在Firefox扩展中阻止脚本执行?

时间:2015-02-12 17:36:43

标签: firefox-addon

可能正在寻找一个古老问题的答案,但我想阻止脚本执行。在我的用例中,阻止浏览器是可以接受的。

此外,在我的用例中,我尝试从Firefox扩展程序执行此操作,这意味着我的代码是" Chrome代码",在浏览器环境中运行。

这可以通过使用模态窗口,然后以编程方式关闭窗口来轻松完成。所以这表明存在一种阻塞机制。

有没有办法在没有实际创建或打开模态窗口的情况下实现模态阻塞?有哪些方法可以利用用于模态窗口的阻塞机制?

我已就此主题进行了大量搜索,但无济于事。

2 个答案:

答案 0 :(得分:1)

使用nsIProcess可以阻止线程。

您可以创建一个具有sleep或usleep方法或等效方法的可执行文件。然后同步运行该进程(nsIProcess.run)并将blocking参数设置为true。

当然,为了便于携带,您需要创建适合您希望支持的每个平台的可执行文件,并提供歧视代码。

基本代码如下所示。我已经在'nix(Mac OS X)上验证了此代码的工作原理,使用仅包含行sleep .03的bash脚本:

let testex = Components.classes["@mozilla.org/file/local;1"]
                    .createInstance(Components.interfaces.nsIFile);

testex.initWithPath("/Users/allasso/Desktop/pause.sh");

let process = Components.classes["@mozilla.org/process/util;1"]
                    .createInstance(Components.interfaces.nsIProcess);

process.init(testex);
let delay = 30;  // convert this to milliseconds in the executable
process.run(true,[delay],1);  // `run` method runs synchronously, first arg says to block thread

在扩展中,您可能希望使nsIFile文件对象更具可移植性:

Components.utils.import("resource://gre/modules/FileUtils.jsm");
let testex = FileUtils.getFile("ProfD",["extension@moz.org","resources","pause.sh"]);

当然要记住,Javascript基本上是单线程的,所以除非你阻止使用Web Workers生成的线程,否则你将在睡眠期间冻结整个UI(就像你打开一个模态窗口一样)

参考文献:

https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess

https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile

https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O#Getting_special_files

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/basic_usage

答案 1 :(得分:0)

选项1

此处enterModalState中有leaveModalStatensIDOMWindowUtilsMDN :: nsIDOMWindowUtils Reference

然而,他们似乎并不适合我。本主题可以解释原因:nsIDOMWindowUtils.isInModalState() not working他们的主题是isInModalState标记为[noscript]我看到了,但enterModalStateleaveModalState未标记为[noscript]我不知道为什么它不起作用。

对我来说有用的是suppressEventHandling

var utils = Services.wm.getMostRecentWindow('navigator:browser').
            QueryInterface(Components.interfaces.nsIInterfaceRequestor).
            getInterface(Components.interfaces.nsIDOMWindowUtils);

utils.suppressEventHandling(true); //set arg to false to unsupress

选项2

您可以打开一个小窗口,将源窗口作为要进行模态化的窗口,然后打开对话框,将其打开。它的对话框因此它不会显示OS标签栏的新窗口。但是按下alt + f4会关闭那个胜利,但是你可以附加事件监听器(或者可以使用utils.suppressEventHandling,因此键盘不能正常工作)以避免关闭,直到你想要它关闭。这是代码:

    var sDOMWin = Services.wm.getMostRecentWindow(null);
    var sa = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
    var wuri = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
    wuri.data = 'about:blank';
    sa.AppendElement(wuri);
    let features = "chrome,modal,width=1,height=1,left=-100";
    if (PrivateBrowsingUtils.permanentPrivateBrowsing || PrivateBrowsingUtils.isWindowPrivate(sDOMWin)) {
       features += ",private";
    } else {
       features += ",non-private";
    }
    var XULWindow = Services.ww.openWindow(sDOMWin, 'chrome://browser/content/browser.xul', null, features, sa);
/*
    XULWindow.addEventListener('load', function() {
      var DOMWindow = XULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
      DOMWindow.gBrowser.selectedTab.linkedBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
      DOMWindow.gBrowser.swapBrowsersAndCloseOther(DOMWindow.gBrowser.selectedTab, aTab);
      //DOMWindow.gBrowser.selectedTab = newTab;
    }, false);
*/