2015-04-07 9 views
2

Создание приложения XulRunner для Windows Я обнаружил, что если привязка B расширяет привязку A. И B удаляется, затем вызывается только деструктор B, а не по вызову Деструктор.Почему деструктор расширенного связывания не вызывается при удалении связывания?

Есть ли что-то не в порядке с моим кодом, или это ошибка XulRunner (я не нашел соответствующую ошибку в bugzilla)?

log after binding B is removed

Вот пример, который я тестировал на 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> 

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> 
+1

Это проблема, с которой я и другие столкнулись, это то, о чем говорили: https://ask.mozilla.org/question/297/apply-and-remove-xbl-binding-on-runtime/| https://ask.mozilla.org/question/271/my-xbl-is-not-working-on-findbar/ | https://stackoverflow.com/questions/24403667/dynamic-way-to-unbind-dynamically-binded-xbl | и theres некоторые более больные должны выкопать его – Noitidart

ответ

1

здесь является решение для вашей проблемы:

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> 

bindings.css:

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); 

binding-a { -moz-binding: url("bindings.xml#binding-a"); } 
binding-b { -moz-binding: url("bindings.xml#binding-b"); } 

main.xul:

<?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> 

Я знаю, что это хак на самом деле, но это работает.

+1

Протестировано на FF 36. –

+0

Мне нравится 'this .__ proto __.__ proto __. destruct.call (this)'. Не могли бы вы подтвердить, что эта проблема действительно существует для вас в вашей среде? В вашем обходном пути мне нужно создать метод 'destruct'? Можно ли вызвать '' '' binding-a' напрямую? –

+1

Я могу подтвердить, что '' в расширенной привязке не вызывается автоматически при уничтожении привязки дочернего элемента. Это просто работа - взломать, если хотите. –