XUL overlay,stringbundleset,getString的问题不是函数,但createBundle方法有效

时间:2016-05-20 19:04:50

标签: firefox-addon xul

所以我正在处理一个旧的XUL覆盖加载项并遇到这个问题,并将其简化为最小的附加组件。想知道是否有人可以向我解释我是否做错了什么,如果我误解了什么,或者如何让它按预期工作。完整的代码如下。在FF 29.0b1和49.0a1中进行测试,结果相同。

在主XUL文件中,我定义了一个stringbundleset和一个stringbundle,两者都有(非常可能)唯一ID。在JavaScript文件中,我想简单地通过元素ID获取bundle(而不是set),并使用getString(或getFormattedString)方法。在主JavaScript文件中,我有一个事件监听器调用一个load函数,它可以调用其他函数,包括一个init函数,我把字符串抓取代码。所有字符串变量都使用var(在init函数之外)全局定义。问题是,我得到getString is not a function。此外,console.log()在功能中无处可行,因此我甚至无法检查应该保留返回的字符串包的变量的值。

在我的附加组件中,我在Options和About XUL文件中使用完全相同的模式,并且它可以工作,正如MDN文档所说的那样。所以我从示例代码中排除了这个。

如果尝试构建和测试,请注意在示例JavaScript代码中,我有破坏的块尝试使用XUL stringbundle并失败,并且使用createBundle()的工作纯javascript-only技术被注释掉。可以使用//* code /**/注释模式轻松修改,只需删除第一个/并在另一个块上添加/并重建xpi。

以下是工作代码应创建的示例屏幕截图。附加组件依赖于旧的状态栏。我使用了"The Addon Bar (Restored)"加载项。注意状态栏上的“TSBS”。右键单击“TSBS”,弹出一个菜单,顶部显示Options。这些标签是从.dtd文件中提取的。 Menu是一个子菜单,其中包含tsbs.js脚本设置的标签,从.properties文件中提取值。该示例显示了它们是从仅JS方法中提取的。我试图从XUL / DOM方法开始工作。

我意识到XUL附加组件很快就会死掉。我意识到我不应该完全依赖状态栏。我意识到我应该只使用JS-only方法,因为它似乎更可靠。但我问这个是因为我注意到了它,并希望从中吸取教训。知道如何纠正或改进代码模式,或者这是一个已知的问题或常见的陷阱?

example screenshot

Directory tree:

test_string_bundle_set-1.0.0-fx
  +-- chrome
  |     +-- content
  |     |     +-- tsbs.js
  |     |     +-- tsbs.xul
  |     +-- locale
  |     |     +-- en-US
  |     |           +-- contents.rdf
  |     |           +-- tsbs.dtd
  |     |           +-- tsbs.properties
  +-- chrome.manifest
  +-- install.rdf

chrome.manifest:

overlay chrome://browser/content/browser.xul chrome://{00735700-7357-7357-7357-073570073570}/content/tsbs.xul

content {00735700-7357-7357-7357-073570073570} chrome/content/

locale {00735700-7357-7357-7357-073570073570} en-US chrome/locale/en-US/

install.rdf:

<?xml version="1.0" encoding="UTF-8"?>
<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>{00735700-7357-7357-7357-073570073570}</em:id>
        <em:version>1.0.0</em:version>
        <em:type>2</em:type>

        <em:name>Test String Bundle Sets</em:name>
        <em:description>Test String Bundle Sets</em:description>
        <em:creator>Quite A. Character</em:creator>

        <!--Firefox-->
        <em:targetApplication>
            <Description>
                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                <em:minVersion>29.0</em:minVersion>
                <em:maxVersion>49.*</em:maxVersion>
            </Description>
        </em:targetApplication>
    </Description>  
</RDF>

chrome/content/tsbs.js:

var tsbs_strings;

var tsbs_string_4;
var tsbs_string_5;
var tsbs_string_6;

function tsbs_load( ) {
    tsbs_init( );
    return true;
}

function tsbs_close( ) {
    return true;
}

window.addEventListener( 'load', tsbs_load, false );
window.addEventListener( 'close', tsbs_close, false );

function tsbs_init( ) {
    //* XUL/DOM method
    tsbs_strings    = document.getElementById( 'tsbs-strings' );

    console.log( 'TSBS->tsbs_init()->tsbs_strings: ' + typeof tsbs_strings );

    tsbs_string_4   = tsbs_strings.getString( 'tsbs.properties.string.4' );
    tsbs_string_5   = tsbs_strings.getString( 'tsbs.properties.string.5' );
    tsbs_string_6   = tsbs_strings.getString( 'tsbs.properties.string.6' );
    /**/
    /* JS-only method
    tsbs_strings    = Services.strings.createBundle( 'chrome://{00735700-7357-7357-7357-073570073570}/locale/tsbs.properties' );

    console.log( 'TSBS->tsbs_init()->tsbs_strings: ' + typeof tsbs_strings );

    tsbs_string_4   = tsbs_strings.GetStringFromName( 'tsbs.properties.string.4' );
    tsbs_string_5   = tsbs_strings.GetStringFromName( 'tsbs.properties.string.5' );
    tsbs_string_6   = tsbs_strings.GetStringFromName( 'tsbs.properties.string.6' );
    /**/

    document.getElementById( 'tsbs-item-4' ).label = tsbs_string_4;
    document.getElementById( 'tsbs-item-5' ).label = tsbs_string_5;
    document.getElementById( 'tsbs-item-6' ).label = tsbs_string_6;
}

chrome/content/tsbs.xul:

<?xml version="1.0" encoding="UTF-8"?>

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<!DOCTYPE overlay SYSTEM "chrome://{00735700-7357-7357-7357-073570073570}/locale/tsbs.dtd">

<overlay id="tsbs-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

    <script type="application/javascript" src="chrome://{00735700-7357-7357-7357-073570073570}/content/tsbs.js"/>

    <stringbundleset id="tsbs-stringset">
        <stringbundle id="tsbs-strings" src="chrome://{00735700-7357-7357-7357-073570073570}/locale/tsbs.properties"/>
    </stringbundleset>

    <statusbar id="status-bar">
        <statusbarpanel
            id="tsbs-display"
            label="&tsbs.dtd.statusbarpanel.display;"
            pack="end"
            context="tsbs-contextmenu"
        />
    </statusbar>

    <window id="main-window">
        <vbox id="tsbs-notifier">
            <popupset id="mainPopupSet">
                <menupopup id="tsbs-contextmenu" position="before_end">
                    <menuitem id="tsbs-options" label="&tsbs.dtd.options;"/>
                    <menuitem label="&tsbs.dtd.string.1;"/>
                    <menuitem label="&tsbs.dtd.string.2;"/>
                    <menuitem label="&tsbs.dtd.string.3;"/>
                    <menu id="tsbs-menu" label="&tsbs.dtd.menu;">
                        <menupopup id="tsbs-submenu">
                            <menuitem id="tsbs-item-4"/>
                            <menuitem id="tsbs-item-5"/>
                            <menuitem id="tsbs-item-6"/>
                        </menupopup>
                    </menu>
                </menupopup>
            </popupset>
        </vbox>
    </window>

</overlay>

chrome/locale/en-US/contents.rdf:

<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
    <Seq about="urn:mozilla:locale:root">
        <li resource="urn:mozilla:locale:en-US"/>
    </Seq>
    <Description about="urn:mozilla:locale:en-US">
        <chrome:packages>
            <Seq about="urn:mozilla:locale:en-US:packages">
                <li resource="urn:mozilla:locale:en-US:{00735700-7357-7357-7357-073570073570}"/>
            </Seq>
        </chrome:packages>
    </Description>
</RDF>

chrome/locale/en-US/tsbs.dtd:

<!ENTITY tsbs.dtd.statusbarpanel.display    "TSBS"      >
<!ENTITY tsbs.dtd.options                   "Options"   >
<!ENTITY tsbs.dtd.menu                      "Menu"      >
<!ENTITY tsbs.dtd.string.1                  "One"       >
<!ENTITY tsbs.dtd.string.2                  "Two"       >
<!ENTITY tsbs.dtd.string.3                  "Three"     >

chrome/locale/en-US/tsbs.properties:

extensions.{00735700-7357-7357-7357-073570073570}.description=Test String Bundle Sets
tsbs.properties.string.4=four
tsbs.properties.string.5=five
tsbs.properties.string.6=six

1 个答案:

答案 0 :(得分:0)

我相信这是你的问题:

<stringbundleset id="tsbs-stringset">

如果<overlay>的直接子项具有ID,则在XUL叠加层中,它应该与基础文档中的元素匹配。 If it does, its contents is inserted under the matching element. If it doesn't this part of an overlay is ignored.

browser.xul can be matched using中现有的stringbundleset:

<stringbundleset id="stringbundleset">

此外,我不相信有'关闭'事件(使用'卸载'),并且自Firefox 2以来你不需要contents.rdf。关于console.log()无法正常工作 - 您检查了Browser Console,而不是Web控制台,对吧?