【问题标题】:How to pack a Firefox extension from scratch如何从头开始打包 Firefox 扩展
【发布时间】:2015-06-25 11:24:05
【问题描述】:

我是 Firefox 扩展程序的新手,我希望您帮我打包一个我构建的扩展程序并将其发送给一些朋友进行测试。

我的扩展程序即将“阻止”某些 URL。这意味着如果有人尝试加入“facebook.com”,我的扩展程序应该将他重定向到“www.google.com”

代码如下。

const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import('resource://gre/modules/Services.jsm');
var urls_block = [ 
    //If URLs contain any of these elements they will be blocked or redirected,
    //  your choice based on code in observer line 17
    'www.facebook.com',
     'www.apple.com'
];
var redir_obj = {
    'www.facebook.com': 'http://www.google.com/',
    'www.apple.com': 'http://www.samsung.com'
}
var observers = {
    'http-on-modify-request': {
        observe: function (aSubject, aTopic, aData) {
            console.info('http-on-modify-request: aSubject = ' 
                          + aSubject + ' | aTopic = ' + aTopic + ' | aData = ' + aData);
            var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
            var requestUrl = httpChannel.URI.spec.toLowerCase();
            for (var i=0; i<urls_block.length; i++) {
                if (requestUrl.indexOf(urls_block[i]) > -1) {
                    //httpChannel.cancel(Cr.NS_BINDING_ABORTED); //this aborts the load
                    //Can redirect with this next line, if don't want to redirect and
                    //  just block, then comment this line and uncomment the line above:
                    httpChannel.redirectTo(Services.io.newURI(redir_obj[urls_block[i]],
                                               null, null));
                    break;
                }
            }
        },
        reg: function () {
            Services.obs.addObserver(observers['http-on-modify-request'],
                                           'http-on-modify-request', false);
        },
        unreg: function () {
            Services.obs.removeObserver(observers['http-on-modify-request'], 
                                           'http-on-modify-request');
        }
    }
};
function install() {}
function uninstall() {}
function startup() {
    for (var o in observers) {
        observers[o].reg();
    }
}

function shutdown(aData, aReason) {
    if (aReason == APP_SHUTDOWN) return;

    for (var o in observers) {
        observers[o].unreg();
    }
}

非常感谢@Noitidart 的大力帮助。

所以我想为 Firefox 扩展打包此代码。 有人可以告诉我怎么做或任何例子吗?

非常感谢您抽出宝贵时间帮助我。

【问题讨论】:

  • 作为一个简短的说明,你所拥有的看起来像一个 bootstrap.js 文件。按照 Makyen 的说法,但将您的代码用于 bootstrap.js。
  • 我的荣幸。这里有一些压缩和安装引导插件的东西:addons.mozilla.org/en-US/firefox/addon/xpicompiler 这里有一些简单的例子:gist.github.com/Noitidart/9025999 这个要点的自述文件解释了很多
  • @Noitidart 再次伟大!是否可以通过网站使其在线更新?或者我应该对此提出另一个问题?
  • @SteliosM。很酷的人,我很确定你可以做到,但我不知道怎么做。我更喜欢将其上传到 addons.mozilla.org 并将可见性设置为私有以便其他人找不到它,然后将其作为下载链接分享到您的插件
  • @Noitidart 非常感谢一切! :)

标签: firefox firefox-addon firefox-addon-sdk firefox-developer-tools


【解决方案1】:

您至少需要创建一个install.rdf 文件和一个chrome.manifest 文件。通过这些链接,您将需要做出一些选择(例如,如何称呼您的扩展程序、&lt;em:id&gt; 等)。

此外,您似乎正在制作一个bootstrap/restartless 插件,并且应该调用包含您在问题中包含的代码的文件:bootstrap.js

.xpi file format (Extension Packaging):

用作 Mozilla(Firefox、Thunderbird 等)扩展容器的 .xpi 文件只是将文件扩展名更改为 .xpi 的 zip 压缩档案。文件从 zip 压缩存档的根目录开始(即有一个包含文件的第一级目录)。文件必须未压缩,或使用“Deflate”算法压缩。使用其他压缩算法将导致您的 .xpi 文件无法加载,并且会弹出一个显示插件已损坏的弹出窗口。

存档的内容可能只有几个文件到任意数量的文件。至少,您有一个install.rdf 和一个chrome.manifest 文件。几乎总会有至少一个附加文件(如果附加文件不多的话)。

我非常简单的Bootstrap/Restartless 扩展,Print Button is Print(将打印按钮更改为打印而不是打印预览)具有以下结构:

Archive contains:
  bootstrap.js
  chrome/
  chrome/content/
  chrome/content/options.xul
  chrome/skin/
  chrome/skin/printer-typeC128.png
  chrome/skin/printer-typeC32.png
  chrome/skin/printer-typeC48.png
  chrome/skin/printer-typeC64.png
  chrome.manifest
  install.rdf
  license.txt
Total 12 entries (42360 bytes)
  • 有所需的install.rdfchrome.manifest 文件。
  • Bootstrap/Restartless 扩展需要文件bootstrap.js。它包含在安装、删除、启用、禁用扩展程序时或在 Firefox 启动或关闭时运行的代码。这个扩展非常简单,所有的 JavaScript 代码都包含在 bootstrap.js 中。
  • 有一个文件chrome/content/options.xul,它是options dialog 的XUL 定义。
  • license.txt 只是说明该扩展是在Mozilla Public License, v2.0 下发布的。
  • .png 文件是此扩展在各种分辨率下的图标。

打印按钮的 install.rdf 文件是 Print is(PrintButtonIsPrint 的所有实例都应更改为您在 chrome.manifest中定义的扩展名> 文件;如果您愿意,您可以从 instal.rdf 文件中删除所有这些,因为您没有选项对话框或定义的图标(尚未)。):

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
    <Description about="urn:mozilla:install-manifest">
    <em:id>PrintButtonIsPrint@makyen.foo</em:id> <!-- MUST be unique to your extension. -->
    <em:version>1.0.1</em:version>
    <em:type>2</em:type>
    <em:name>Print Button is Print</em:name> <!-- Should be unique to your extension. -->
    <em:bootstrap>true</em:bootstrap> <!-- Indicate that the extension is restartless -->
    <em:unpack>false</em:unpack>
    <em:description>Makes the Print Button print the page instead of presenting a print preview. Adds the option of using shift-left-click and/or ctrl-left-click for Print Preview (both enabled by default).</em:description>
    <em:creator>Makyen</em:creator>
    <!-- No about.
    <em:aboutURL>chrome://PrintButtonIsPrint/content/about.xul</em:aboutURL>
    -->
    <em:optionsURL>chrome://PrintButtonIsPrint/content/options.xul</em:optionsURL>
    <em:iconURL>chrome://PrintButtonIsPrint/skin/printer-typeC48.png</em:iconURL> 
    <em:icon64URL>chrome://PrintButtonIsPrint/skin/printer-typeC64.png</em:icon64URL> 
<!--Firefox-->
    <em:targetApplication>
        <Description>
            <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
            <em:minVersion>29.0</em:minVersion>
            <em:maxVersion>37.*</em:maxVersion>
        </Description>
    </em:targetApplication>
    </Description>
</RDF>

chrome.manifest 是(PrintButtonIsPrint 的两个实例都应更改为您的扩展程序):

content      PrintButtonIsPrint                                         chrome/content/
skin         PrintButtonIsPrint               classic/1.0               chrome/skin/

为了创建.xpi 文件,我使用了一个批处理文件,它使用了 DOS 和 Unix/Linux(实际上是 Cygwin)命令的组合:

mkxpi.bat

rm -f PrintButtonIsPrint@makyen.foo.xpi
zip -1 -r PrintButtonIsPrint@makyen.foo.xpi * -x@xpi.ignore
pause

这将删除 .xpi 文件的所有旧版本。然后它创建一个新的.xpi 文件,使用-1,最小压缩(访问速度比节省空间更重要)并包含所有文件和子目录**,但忽略xpi 中的所有文件。忽略文本文件-x@xpi.ignore。使用忽略文件是因为我在目录中有其他东西(例如.git 目录、.bak 从编辑器自动创建的文件等)。创建 .xpi 文件后,脚本将执行 pause,以便我可以验证包含哪些文件、没有错误等,而不仅仅是让窗口消失并假设一切正常。

我的 xpi.ignore 文件有点长,因为它积累了来自各种项目的垃圾并且很少被清理:

*.com
*.class
*.dll
*.exe
*.o
*.so
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
*.log
*.sql
*.sqlite
*.svg
*/.DS_Store
*/.DS_Store?
*/._*
._*
*/.Spotlight-V100
.Spotlight-V100
*/.Trashes
.Trashes
*/ehthumbs.db
*/Thumbs.db
*.ORIG
*.bak
*OLD*
OLD/*
*/OLD/*
*.OLD
*.OLD[0-9]
*/OLD/*
*/OLD[0-9]/*
*.unknown
*.unknown[0-9]
*.updated
*.updated[0-9]
*/Copy *
*/OLD
*/OLD*
*/OLD[0-9]
*/OLD[0-9][0-9]
*/test/*
*/not in xpi/*
*/tmp
*.tmp
*/foo
*.foo
*checkpoint
.git
*/.git
.gitignore
*/.gitignore
xpi.ignore
mkclean.bat
mkclean.bat.DONTRUN
mkxpi.bat
*.xpi
*/devtools-toolbox-window.ico
*/devtools-webconsole.ico
*/JSConsoleWindow.ico
*/main-window.ico
*/places.ico
*/viewSource.ico

Installing extensions:

至于installing extensions(即.xpi 文件),只需将其拖放到运行您希望安装的配置文件的Firefox 窗口中即可。对于development/testing,您可以使用Firefox extension proxy file 将扩展名放在本地驱动器上的目录中(在配置文件的extensions 目录中创建一个名为扩展名&lt;em:id&gt; 的文件,其中包含一行包含扩展文件的目录的完整路径)。根据您的目标(一个配置文件、所有配置文件、所有用户、哪个操作系统等),还有其他选择如何install extensions

这个答案大部分是从my answer here复制过来的。

【讨论】:

  • 我应该把什么作为描述ID?因为你有很多
  • @SteliosM。上例中的&lt;em:targetApplication&gt;&lt;Description&gt;&lt;em:id&gt; 是Firefox 的ID,并且是固定的。如果您希望您的扩展程序加载到 Firefox 中,那就是您使用的那个。如果您想加载到不同的或附加的应用程序(例如 Thunderbird),则使用不同的或附加的&lt;em:targetApplication&gt;。您可以找到 GUID 列表和有效的应用程序版本,on MDN
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多