Страницы: 1
Приветствую всех читающих.
Дебажил свой экстеншин и заметил в нем аномальное поведение xbl.
По мануалу - при установке связки должен вызваться constructor, а при удалении - destructor.
На практике - конструктор срабатывает, деструктор нет. Если связку не убирать с элемента, то при закрытии браузера деструктор срабатывает. Если связаный элемент удалить (типа removeChild), то связка с него не отваливается и деструктор не вызывается (т.е. элемент пропадает, браузер закрываешь, деструктор не вызывается).
Собственно хотел поинтересоваться - это баг ? Можно как-то сделать чтобы деструктор вызывался автоматический ?
Отсутствует
Так, гуглом установлено что это баг - https://bugzilla.mozilla.org/show_bug.cgi?id=230086 очень древний.
Можно попробовать вынести деструктор в метод и вызывать самостоятельно, но это очень неудобно и не всегда уследишь + как быть с расширяемыми XBL ? (т.е. один - расширение второго) ?
Отсутствует
Мысль пришла по поводу слежения - если попробовать слушать DOMNodeRemoved и в нем фильтровать свои элементы с xbl, дергать у них свой метод destroy или что-то подобное ? Такое вообще реально ?
Отсутствует
Мысль пришла по поводу слежения - если попробовать слушать DOMNodeRemoved и в нем фильтровать свои элементы с xbl, дергать у них свой метод destroy или что-то подобное ? Такое вообще реально ?
Почему бы и нет ?
Время настанет, время придет...
И лис кОнкурiентов на части порвет !!!
Отсутствует
Просто подумалось что медленно будет работать. Вот примерно что получилось:
Функция, рекурсивно обрабатывающая стандартные деструкторы:
function xbl_destructor_bugfix(event) { if (event.originalTarget.nodeName == 'opwidget') { // ok, we needs call desructor recursion // but have some problems... $) var binded_to = document.defaultView.getComputedStyle(event.originalTarget, null).getPropertyValue('-moz-binding'); var get_url = binded_to.match(/url\((\'|\")?(.*?)\1?\)/mi); if (get_url != null) { // current binding founded var bind_params = get_url[2].match(/([^\#]+)#(.*)/mi); if (bind_params != null) { var bind_to_url = bind_params[1]; var bind_to_section = bind_params[2]; var ajax = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Components.interfaces.nsIXMLHttpRequest); ajax.open('GET', bind_to_url, false); ajax.send(null); if ((ajax.responseXML != null) && (ajax.responseXML.documentElement.nodeName != 'parsererror')) { // XBL xml successful loaded var xbl_destructor_recursion_removal = function(xbl_xml, section) { var xpe = new XPathEvaluator(); var nr = function (prefix) { var ns = { html : 'http://www.w3.org/1999/xhtml', xul : 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', xbl : 'http://www.mozilla.org/xbl' }; return ns[prefix] || null; }; var result = xpe.evaluate('/xbl:bindings/xbl:binding[@id=\'' + section + '\']', xbl_xml, nr, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (result.singleNodeValue) { // section founded var section_node = result.singleNodeValue; var extension_of = (section_node.hasAttribute('extends') ? section_node.getAttribute('extends') : ''); result = xpe.evaluate('xbl:implementation/xbl:destructor', section_node, nr, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (result.singleNodeValue) { event.originalTarget.destroy = function(){ eval(result.singleNodeValue.textContent); }; event.originalTarget.destroy.call(event.originalTarget); } // extexsions from other files not supported, you can modify this code for other files 8-) if ((extension_of) && (extension_of.indexOf('#') == 0)) xbl_destructor_recursion_removal(xbl_xml, extension_of.substring(1)); } }; // try to remove xbl_destructor_recursion_removal(ajax.responseXML.documentElement, bind_to_section); } } } } }
К документу прицепляется так:
Сразу говорю что этот вариант с ограничениями:
1. для ускорения фильрации своих xbl вставил
if (event.originalTarget.nodeName == 'opwidget')
- тут можно вписать свое или вообще это условие убрать (должно начать тормозить).
2. расширения xbl из разных файлов не поддерживаются (у меня все водном файле - под это и писал).
3. у ваших объектов не должно быть метода destroy (можно переименовать в любое другое на свой вкус).
работает
Отредактировано Codeblight (17-05-2009 00:59:11)
Отсутствует
Страницы: 1