Firefox addon 为什么在删除扩展绑定时不调用扩展绑定的析构函数?
为Windows创建XulRunner应用程序时,我发现如果绑定B会扩展绑定a。如果删除B,则只调用B的析构函数,而不调用a的析构函数 我的代码是否有问题,或者这是一个XulRunner错误(我在bugzilla中没有找到匹配的错误) 下面是我在XulRunner 23和35上测试的一个示例: main.xul:Firefox addon 为什么在删除扩展绑定时不调用扩展绑定的析构函数?,firefox-addon,xul,gecko,xulrunner,Firefox Addon,Xul,Gecko,Xulrunner,为Windows创建XulRunner应用程序时,我发现如果绑定B会扩展绑定a。如果删除B,则只调用B的析构函数,而不调用a的析构函数 我的代码是否有问题,或者这是一个XulRunner错误(我在bugzilla中没有找到匹配的错误) 下面是我在XulRunner 23和35上测试的一个示例: main.xul: <?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<!--<binding-a id="A" style="-moz-binding: url('binding.xml#binding-a')"/>-->
<binding-b id="B" style="-moz-binding: url('binding.xml#binding-b')"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="bindings.css" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<binding-a id="A"/>
<binding-b id="B"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
移走
删除B
呼叫A.f()
呼叫B.f()
binding.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="binding-a">
<content>
<xul:label anonid="label" value="Binding A"/>
</content>
<implementation>
<constructor><![CDATA[
var label = document.getAnonymousElementByAttribute(this, "anonid", "label");
label.value = label.value + " A.constructor";
window.print("A.constructor");
]]></constructor>
<destructor><![CDATA[
window.print("A.destructor");
]]></destructor>
<method name="f">
<body><![CDATA[
window.print("A.f");
]]></body>
</method>
</implementation>
</binding>
<binding id="binding-b" extends="#binding-a">
<content>
<xul:label anonid="label" value="Binding B"/>
</content>
<implementation>
<constructor><![CDATA[
window.print("B.constructor");
]]></constructor>
<destructor><![CDATA[
window.print("B.destructor");
]]></destructor>
</implementation>
</binding>
</bindings>
以下是您问题的解决方案: bindings.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="binding-a">
<content>
<xul:label anonid="label" value="Binding A"/>
</content>
<implementation>
<constructor><![CDATA[
var label = document.getAnonymousElementByAttribute(this, "anonid", "label");
label.value = label.value + " A.constructor";
window.print("A.constructor");
]]></constructor>
<destructor><![CDATA[
this.destruct();
]]></destructor>
<method name="f">
<body><![CDATA[
window.print("A.f");
]]></body>
</method>
<method name="destruct">
<body><![CDATA[
window.print("A.destructor");
]]></body>
</method>
</implementation>
</binding>
<binding id="binding-b" extends="#binding-a">
<content>
<xul:label anonid="label" value="Binding B"/>
</content>
<implementation>
<constructor><![CDATA[
window.print("B.constructor");
]]></constructor>
<destructor><![CDATA[
this.destruct();
]]></destructor>
<method name="destruct">
<body><![CDATA[
this.__proto__.__proto__.destruct.call(this);
window.print("B.destructor");
]]></body>
</method>
</implementation>
</binding>
</bindings>
main.xul:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<!--<binding-a id="A" style="-moz-binding: url('binding.xml#binding-a')"/>-->
<binding-b id="B" style="-moz-binding: url('binding.xml#binding-b')"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="bindings.css" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<binding-a id="A"/>
<binding-b id="B"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
移走
删除B
呼叫A.f()
呼叫B.f()
我知道这实际上是一个黑客程序,但它是有效的。这是我和其他人也遇到的问题,这些都是讨论过的问题:| | | | | | | | | | | | |还有一些我必须把它挖出来,就像
这个。uu(uu proto)uu.destruct u.destruct调用(这个)
。您能否确认您的环境中确实存在此问题?在您的解决方案中,我是否必须创建destruct
方法?我可以直接调用
的
绑定-a吗?我可以确认,当子绑定被销毁时,扩展绑定中的
不会自动调用。这只是一个解决办法——如果你愿意的话,这是一个黑客攻击。析构函数的问题很老了,而且看起来永远都不会被解决——还有一个注意事项——事实上,当文档被完全销毁时(例如,文档或窗口被关闭)binding-a
的析构函数在binding-b
的析构函数之后被正确调用,但当您通过JavaScript删除元素时,这不起作用。