Pop-Up Blocker

Simple but effective opup window blocker

Verzia zo dňa 31.10.2016. Pozri najnovšiu verziu.

// ==UserScript==
// @name        Pop-Up Blocker
// @namespace   HTML
// @include     *
// @version     $Id:$
// @description Simple but effective opup window blocker
// ==/UserScript==

(function () {
	var BLOCK_MODE = {'ALL': 0,  // Block all popups
										'CONFIRM': 2,  // Confirm each popup (not recommended, but useful for testing)
									  'GRANT_PERIOD': 4,  // Block popups that are initiated after the mouse click grant period
                    'SECURE': 8}  // Block popups from insecure (HTTP) sites
	var block_mode = BLOCK_MODE.GRANT_PERIOD | BLOCK_MODE.SECURE;
	var grant_period = 50;  // Milliseconds
	var ts = 0, wopen = window.open, showmodaldlg = window.showModalDialog;

	window.addEventListener('mousedown', function () {
		ts = Date.now();
	}, true);

	window.addEventListener('click', function () {
		ts = Date.now();
	}, true);

	function confirmPopup(msg, args) {
		confirm(msg + ' (' + Array.prototype.slice.apply(arguments).join(', ') + ')');
	}

	window.open = function () {
    var oargs = arguments;
		if (block_mode != BLOCK_MODE.ALL &&
				(block_mode & BLOCK_MODE.CONFIRM
				 ? confirmPopup('Allow popup?', arguments)
				 : (block_mode & BLOCK_MODE.SECURE ? location.protocol == 'https:' : true) && Date.now() < ts + grant_period)) {
      console.info('Allowed window.open', Array.prototype.slice.apply(arguments));
			return wopen.apply(window, arguments);
    }
		else {
			console.warn('Blocked window.open', Array.prototype.slice.apply(arguments));
			notify('Blocked popup window', arguments[0], 0, function() {
        console.info('User clicked window.open', Array.prototype.slice.apply(oargs));
        wopen.apply(window, oargs);
      });
		}
		return {}
	};

	window.showModalDialog = function () {
		if (block_mode != BLOCK_MODE.ALL &&
				(block_mode & BLOCK_MODE.CONFIRM
				 ? confirmPopup('Allow modal dialog?', arguments)
				 : (block_mode & BLOCK_MODE.SECURE ? location.protocol == 'https:' : true) && Date.now() < ts + grant_period)) {
      console.info('Allowed window.showModalDialog', Array.prototype.slice.apply(arguments));
			return showmodaldlg.apply(window, arguments);
    }
		else {
			console.warn('Blocked modal showModalDialog', Array.prototype.slice.apply(arguments));
			notify('Blocked modal dialog', arguments[0]);
		}
		return {}
	};

	// Notifications
	function notificationDetails(title, text, timeout, onclick) {
		return {
			'text': text || '',
			'title': title || '',
			'timeout': timeout || 0,
			'onclick': onclick || function () {
			}
		};
	}

	function notify(title, text, timeout, onclick) {
		//GM_notification(notificationDetails(title, text, timeout, onclick));
    var notification = document.createElement('div');
    resetStyles(notification);
    notification.style.cssText = 'background: InfoBackground !important';
    notification.style.cssText += 'border-bottom: 1px solid WindowFrame !important';
    notification.style.cssText += 'box-sizing: border-box !important';
    notification.style.cssText += 'font: small-caption !important';
    notification.style.cssText += 'padding: .6em .9em !important';
    notification.style.cssText += 'position: fixed !important';
    notification.style.cssText += 'left: 0 !important';
    notification.style.cssText += 'right: 0 !important';
    notification.style.cssText += 'top: 0 !important';
    notification.style.cssText += 'width: 100% !important';
    var closeButton = document.createElement('span');
    resetStyles(closeButton);
    closeButton.style.cssText += 'cursor: pointer !important';
    closeButton.style.cssText += 'display: inline-block !important';
    closeButton.style.cssText += 'float: right !important';
    closeButton.style.cssText += 'font: inherit !important';
    closeButton.style.cssText += 'margin-left: .75em !important';
    closeButton.appendChild(document.createTextNode('╳'));
    closeButton.onclick = function () {
      document.body.removeChild(notification);
    }
    notification.appendChild(closeButton);
    notification.appendChild(document.createTextNode(title));
    var linkText = document.createElement('span');
    resetStyles(linkText);
    linkText.style.cssText += 'color: #00e !important';
    linkText.style.cssText += 'color: -moz-nativehyperlinktext !important';
    linkText.style.cssText += 'cursor: pointer !important';
    linkText.style.cssText += 'font: inherit !important';
    linkText.style.cssText += 'text-decoration: underline !important';
    linkText.appendChild(document.createTextNode(text));
    if (onclick) {
      linkText.onclick = function(e) {
        onclick(e);
        document.body.removeChild(notification);
      }
    }
    notification.appendChild(document.createTextNode(' '));
    notification.appendChild(linkText);
    document.body.appendChild(notification);
    if (timeout) {
      notification.style.cssText += 'transition: opacity .25s !important';
      setTimeout(function () {
        notification.style.cssText += 'opacity: 0 !important';
      }, timeout);
      setTimeout(function () {
        document.body.removeChild(notification);
      }, timeout + .25 * 1000);
    }
	}

  function resetStyles(element) {
    element.style.cssText = 'background: transparent !important';
    element.style.cssText += 'border: none !important';
    element.style.cssText += 'border-radius: 0 !important';
    element.style.cssText += 'bottom: auto !important';
    element.style.cssText += 'box-shadow: none !important';
    element.style.cssText += 'color: WindowText !important';
    element.style.cssText += 'font: medium serif !important';
    element.style.cssText += 'line-height: normal !important';
    element.style.cssText += 'margin: 0 !important';
    element.style.cssText += 'opacity: 1 !important';
    element.style.cssText += 'outline: none !important';
    element.style.cssText += 'padding: 0 !important';
    element.style.cssText += 'position: static !important';
    element.style.cssText += 'text-align: left !important';
    element.style.cssText += 'text-shadow: none !important';
    element.style.cssText += 'left: auto !important';
    element.style.cssText += 'right: auto !important';
    element.style.cssText += 'top: auto !important';
    element.style.cssText += 'white-space: normal !important';
    element.style.cssText += 'width: auto !important';
  }

  function shim_GM_notification() {
    if (typeof GM_notification === "function") return;

    window.GM_notification = function (options) {
			function checkPermission() {
				if (Notification.permission === "granted") {
					showNotification();
				}
				else if (Notification.permission === "denied") {
					console.error("User has denied notifications for this page/site!");
					return;
				}
				else {
					Notification.requestPermission(function (permission) {
						console.info("Requested permission to show notification", permission);
						checkPermission();
					});
				}
			}
			checkPermission();

			function showNotification() {
				if (!options.title) {
					console.error("A title is required for a notification!");
					return;
				}
				if (options.text && !options.body) {
					options.body = options.text;
				}

				var notification = new Notification(options.title, options);

				if (options.onclick) {
					notification.onclick = options.onclick;
				}
				if (options.timeout) {
					setTimeout(function() {
						notification.close();
					}, options.timeout);
				}
			}
    }
	}
	//shim_GM_notification();
})();