// ==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();
})();