【问题标题】:using eval.call() in firefox XPCOM component在 firefox XPCOM 组件中使用 eval.call()
【发布时间】:2010-07-20 22:17:16
【问题描述】:

我正在制作一个扩展,在加载每个页面时都会为该页面创建一个我的 xpcom 组件实例。

我是这样做的:

var appcontent = document.getElementById("appcontent");   // browser
if(appcontent) {
   appcontent.addEventListener("load", onPageLoad, true);
}
var onPageLoad = function(aEvent) {
   var doc = aEvent.originalTarget; //this is the reference to the opened page
   pages.push(createInstanceOfMyXPCOM(doc));
}

我的问题是,在 XPCOM 组件中,如何在该文档的全局上下文中使用 eval()。如果您只是在 html 中的常规 javascript 中执行此操作,您可以这样做:

window.eval.call(window, somecode);

问题是我的 xpcom 组件中没有窗口变量(或者我有),我只有对文档的引用。我也可以在创建时将窗口传递给我的 XPCOM 组件,但是如果我打开了几个页面,我看不出它是如何工作的..

【问题讨论】:

  • 我以为我可以在本地拥有 var window = doc.defaultView。但是由于某种原因 doc.defaultView.eval 是未定义的,即使我可以这样做,例如:doc.defaultView.content.document.defaultView.content.document.location.href。我错过了一些东西=)

标签: javascript firefox xpcom


【解决方案1】:

从 XPCOM,您应该能够使用以下方法获得对主窗口的引用:

var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                       .getInterface(Components.interfaces.nsIWebNavigation)
                       .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                       .rootTreeItem
                       .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                       .getInterface(Components.interfaces.nsIDOMWindow);

然后就可以通过以下方式获取当前选中的tab文档:

document = mainWindow.gBrowser.contentDocument;

您可以在这里找到更多信息:

https://developer.mozilla.org/en/Code_snippets/Tabbed_browser

https://developer.mozilla.org/en/Working_with_windows_in_chrome_code

更新:

试试这个,你应该可以得到最近窗口的引用:

var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow("navigator:browser");

如果您有多个选项卡,您可以使用这样的东西(来自 Mozilla Dev Site 的代码)来遍历所有选项卡并访问每个文档:

var num = gBrowser.browsers.length;
for (var i = 0; i < num; i++) {
  var b = gBrowser.getBrowserAtIndex(i);
  try {
    dump(b.currentURI.spec); // dump URLs of all open tabs to console
  } catch(e) {
    Components.utils.reportError(e);
  }

}

【讨论】:

  • 我不认为我可以使用代码的第一个 sn-p,因为在 XPCOM 世界中 window 变量是未定义的,尽管我可能错了。加上 mainWindow 将帮助我执行 window.eval.call(window, somecode);因为我可能同时打开了 3 个选项卡,在每个选项卡中我都想像 window.eval.call(window, somecode) 一样执行 smth。我昨天找到了 evalInSandbox(code, context),但我仍然没有t弄清楚如何将上下文传递给那个..
  • 我明白了...刚刚添加了一些想法,希望对您有所帮助。我将很快与 XPCOM 合作,所以这是一个非常有趣的问题......一旦找到解决方案,请确保在此处编写更新!
  • 对不起,我从来没有用解决方案更新这个:-\我最终没有使用 eval,因为这通常是可以避免的;)
猜你喜欢
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多