如何从Firefox扩展中覆盖JavaScript函数?

问题描述 投票:4回答:2

我试图拦截所有页面的document.write调用。通过注入类似脚本来设置页面内部的拦截

function overrideDocWrite() {
 alert("Override called");
 document.write = function(w) {
  return function(s) {
   alert("special dom");
   w.call(this, wrapString(s));
  };
 }(document.write);
 alert("Override finished");
}

很容易并且有效,但我希望我的扩展能够从扩展内部为每个文档对象设置拦截。我找不到办法做到这一点。我试着听“加载”事件并在那里设置拦截,但它也失败了。如何从扩展中挂钩对doc.write的调用?

我取得了一些进展:

var myExtension = {
  init: function() {
    var appcontent = document.getElementById("appcontent"); // browser
    if (appcontent)
      appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad,
        true);
  },

  onPageLoad: function(aEvent) {
    var doc = aEvent.originalTarget; // doc is document that triggered "onload" event
    // do something with the loaded page.
    // doc.location is a Location object (see below for a link).
    // You can use it to make your code executed on certain pages only.
    alert("Override called");
    alert(doc);
    alert(doc.write);
    alert(doc.wrappedJSObject);
    alert(doc.wrappedJSObject.write);
    doc.wrappedJSObject.write = function(w) {
      return function(s) {
        alert("special dom");
        w.call(this, "(" + s + ")");
      };
    }(doc.write);
    alert("Override finished");
  }
}

这似乎有效,但DOMContentLoaded是这项工作的错误事件,因为它被解雇了太晚了!是否有较早的事件要听?

javascript firefox-addon document.write
2个回答
3
投票

复活的问题!我得到了答案。这是一个示例代码:

const os    = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);

os.addObserver({
    observe : function(aWindow, aTopic, aData) {
        if (aWindow instanceof Ci.nsIDOMWindow && aTopic == 'content-document-global-created') {
            aWindow.wrappedJSObject.myfunction = function(){
                // Do some stuff . . .
            }
        }
    }
}, 'content-document-global-created', false);

从gecko 2.0开始插入事件document-element的文档也是如此。


0
投票

JavaScript使用原型继承系统,而不是拥有类,对象具有原型。原型是真实对象,用作对其他对象的引用,用于继承方法和属性。

最好的策略是覆盖“文档”原型中的方法写入(对于HTML文档是HTMLDocument)。这应该有效地将所有“文档”实例的方法包装在浏览器中加载的页面中,因为它们都使用相同的原型。

代替

document.write = function() { ... }

尝试这样的事情:

HTMLDocument.prototype.write= function() { ... }

更新:它似乎并不像我最初想象的那么容易,这似乎在第一次尝试时不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.