Firefox addon 为什么在删除扩展绑定时不调用扩展绑定的析构函数?

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

为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"?>
<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删除元素时,这不起作用。