有没有办法自定义firefox插件而不实际触及插件代码?

时间:2011-03-07 18:17:31

标签: javascript firefox-addon

我想扩展一个现有的firefox插件,其功能对我来说非常特殊(因此与此插件的其他用户无关)。 如何在不实际应用对插件代码的更改的情况下覆盖或挂钩javascript方法? 是否有类似特殊的地方可以在插件后添加其他文件?

修改插件本身意味着每次更新插件时我的更改都会丢失。

是否有一般概念来实现这一目标?

编辑以获取更多信息:我试图扩展的插件是用于在domReady上自定义功能和显示网站的信息。我想改变插件的行为以显示更多特殊的东西。 为此,我需要在插件代码之后执行我的代码,但在domReady事件之前,即在这种情况下使用bookmarklet不起作用。

祝你好运, 彼得

2 个答案:

答案 0 :(得分:0)

我会添加你的代码并保留它的备份,以便你可以在更新后添加它。

您还可以创建一个插件,用于在插件运行时监听,可能类似于

function listener() {
  setTimeout(function(){
    if (document.getElementById('someId').style.prop === 'changed?') {
      startYourAddon();
    } else {
      listener(); //then there's a timeout, it would more logically fit around this call
    }
  }, 5);
}
listener();

答案 1 :(得分:0)

没有通用的解决方案。您需要研究加载项的源代码,并检查要扩展的部分以及如何完成。例如,要扩展的加载项可能会定义浏览器窗口覆盖并在其中加载其脚本。它定义了您想要扩展的函数MyExtension.doSomething()。您可以通过定义自己的叠加层并将其应用于叠加层来实现。例如。他们的chrome.manifest包含以下行:

overlay chrome://browser/content/browser.xul chrome://myextension/content/overlay.xul

您将以下内容添加到自己的chrome.manifest

overlay chrome://myextension/content/overlay.xul chrome://myextensionaddon/content/overlay.xul

myextensionaddon是您自己的加载项的chrome命名空间。你的叠加层可以运行类似于这段代码的东西:

(function()
{
  // Store original method so that we can call it later
  var oldMethod = MyExtension.doSomething;

  // Replace the method by our own
  MyExtension.doSomething = function()
  {
    // Code executed before the original method is called goes here
    oldMethod.apply(this, arguments);
    // Code executed after the original method is called goes here
  };
})();

这是有效的,因为所有叠加层的脚本都在相同的上下文中执行,即它们所覆盖的窗口的上下文。将叠加层应用于叠加层可确保在扩展叠加层后加载叠加层。

现在扩展方法并不总是可行的。如果绝对没有其他解决方案,您可以使用技巧来操纵其中一个文件。为此,您可以使用chrome.manifest中的override instruction。例如,您使用自己的文件覆盖加载项的script.js文件:

override chrome://myextension/content/script.js chrome://myextensionaddon/content/script.js

覆盖Chrome网址仅适用于精确网址匹配,这意味着您仍然可以访问chrome://myextension/content/script.js?foo下的原始脚本(由于查询问题,它不再是完全匹配,但查询字符串无效关于你得到的内容)。您的script.js文件可能如下所示:

// Code executed before the original file is loaded goes here

// Load the original script now
Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
          .getService(Components.interfaces.mozIJSSubScriptLoader)
          .loadSubScript("chrome://myextension/content/script.js?foo");

// Code executed after the original file is loaded goes here