Prompt On New Tab

Display a confirmation dialog when the site wants to open a new tab. This won't work if the user opens a link in a new tab using web browser's "Open in a new tab", "Open in background tab", or similar which are web browser internal features or browser extension features.

目前為 2018-03-01 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Prompt On New Tab
// @namespace    https://gf.qytechs.cn/en/users/85671-jcunews
// @version      1.1.16
// @license      GNU AGPLv3
// @description  Display a confirmation dialog when the site wants to open a new tab. This won't work if the user opens a link in a new tab using web browser's "Open in a new tab", "Open in background tab", or similar which are web browser internal features or browser extension features.
// @author       jcunews
// @match        *://*/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

/*
  Information about rejectList and allowList can be found on below URL.

  https://gf.qytechs.cn/en/scripts/38392-prompt-on-new-tab
*/

var rejectList = [
  ["*", "*://*.doubleclick.net/*"],
  ["*", /^https?:\/\/[^.]+\.adservices?\.com\//i],
  ["*://site.com/*", /^.*?:\/\/site\.com\/(offer|popup)/i]
];

var allowList = [
  ["*://www.bing.com/*", "*"],
  ["*://www.google.*/*", "*://*.google.*/*"]
];

[rejectList, allowList].forEach(function(list) {
  list.forEach(function(pair) {
    pair.forEach(function(str, i) {
      if (("string" === typeof str) || (str instanceof String)) {
        pair[i] = new RegExp("^" + str.replace(/([(){}\[\]\\^$.+?|])/g, "\\$1").replace(/([*])/g, ".*?") + "$", "i");
      }
    });
  });
});

function checkUrl(target, curUrl) {
  function checkUrlPair(pair) {
    if (pair[0].test(curUrl) && pair[1].test(target)) return true;
  }

  curUrl = location.href;
  if (rejectList.some(checkUrlPair)) {
    return -1;
  } else if (allowList.some(checkUrlPair)) {
    return 1;
  } else return 0;
}

function getFrameNames(fs, r) {
  function doEle(ele, n, i, z) {
    try {
      n = ele.tagName;
    } catch(z) {
      n = "";
    }
    if (fs.indexOf(n) >= 0) {
      try {
        r.push(ele.name);
      } catch(z) {}
    } else if (n) {
      for (i = ele.childElementCount-1; i >= 0; i--) {
        try {
          n = ele.children[i].tagName;
        } catch(z) {
          n = "";
        }
        if (fs.indexOf(n) >= 0) {
          try {
            r.push(ele.children[i].name);
          } catch(z) {}
        } else if (n) {
          doEle(ele.children[i]);
        }
      }
    }
  }
  fs = ["IFRAME", "FRAME"];
  r = [];
  doEle(document.body);
  return r;
}

(function(open_, submit_, wael, ele) {
  function dummy(){}

  function isExistingFrameName(name) {
    return (!name || ["_parent", "_self", "_top"].indexOf(name) >= 0) || (getFrameNames().indexOf(name) >= 0);
  }

  open_ = window.open;
  window.open = function(url, name) {
    var loc = {};
    if (isExistingFrameName(name)) {
      return open_.apply(this, arguments);
    } else switch (checkUrl(url)) {
      case 1:
        return open_.apply(this, arguments);
      case 0:
        if (confirm("This site wants to open a new tab.\nDo you want to allow it?\n\nURL:\n" + url)) {
          return open_.apply(this, arguments);
        }
    }
    return {
      document: {
        close: dummy,
        location: loc,
        open: dummy,
        write: dummy
      },
      location: loc
    };
  };

  function reject(ev) {
    if (!ev || !ev.preventDefault) return;
    ev.preventDefault();
    ev.stopPropagation();
    ev.stopImmediatePropagation();
  }

  function actionCheckUrl(url, msg, ev) {
    switch (checkUrl(url)) {
      case 0:
        if (!confirm(msg + "\nDo you want to allow it?\n\nURL:\n" + url)) {
          reject(ev);
          return false;
        } else break;
      case -1:
        reject(ev);
        return false;
    }
    return true;
  }

  function onFormSubmit(ev) {
    if ((/^https?:/).test(this.action) && !isExistingFrameName(this.target) &&
       !actionCheckUrl(this.action, "This site wants to submit a form in a new tab.")) return;
    return submit_.apply(this, arguments);
  }
  submit_ = HTMLFormElement.prototype.submit;
  HTMLFormElement.prototype.submit = onFormSubmit;

  function windowSubmit(ev){
    if (!ev.defaultPrevented && (/^https?:/).test(ev.target.action) && !isExistingFrameName(ev.target.target)) {
      return actionCheckUrl(ev.target.action, "This site wants to submit a form in a new tab.", ev);
    }
  }
  addEventListener("submit", windowSubmit);

  function onAnchorClick(ev) {
    if ((/^(?:f|ht)tps?:/).test(this.href) && !isExistingFrameName(this.target)) {
      return actionCheckUrl(this.href, "This site wants to open a new tab.", ev);
    }
    return;
  }

  function windowClick(ev, a){
    if (ev.button || !(a = ev.target) || ev.defaultPrevented) return;
    if (a.tagName === "A") {
      return onAnchorClick.call(a, ev);
    } else {
      while (a = a.parentNode) {
        if (a.tagName === "A") return onAnchorClick.call(a, ev);
      }
    }
  }
  addEventListener("click", windowClick);

  wael = window.addEventListener;
  window.addEventListener = function(type, fn) {
    var res = wael.apply(this, arguments);
    if (type === "click") {
      removeEventListener("click", windowClick);
      wael("click", windowClick);
    } else if (type === "submit") {
      removeEventListener("click", windowSubmit);
      wael("submit", windowSubmit);
    }
    return res;
  };
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址