2009-11-21 02:33:06 +00:00
|
|
|
(function($) {
|
|
|
|
|
|
|
|
/* Add the methods to handle constructor & destructor binding to the Namespace class */
|
2010-04-13 05:45:29 +00:00
|
|
|
$.entwine.Namespace.addMethods({
|
2009-11-21 02:33:06 +00:00
|
|
|
bind_condesc: function(selector, name, func) {
|
2010-04-13 05:45:29 +00:00
|
|
|
var ctors = this.store.ctors || (this.store.ctors = $.entwine.RuleList()) ;
|
2009-11-21 02:33:06 +00:00
|
|
|
|
|
|
|
var rule;
|
|
|
|
for (var i = 0 ; i < ctors.length; i++) {
|
|
|
|
if (ctors[i].selector.selector == selector.selector) {
|
|
|
|
rule = ctors[i]; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!rule) {
|
|
|
|
rule = ctors.addRule(selector, 'ctors');
|
|
|
|
}
|
|
|
|
|
|
|
|
rule[name] = func;
|
|
|
|
|
|
|
|
if (!ctors[name+'proxy']) {
|
|
|
|
var one = this.one('ctors', name);
|
|
|
|
var namespace = this;
|
|
|
|
|
|
|
|
var proxy = function(els, i, func) {
|
|
|
|
var j = els.length;
|
|
|
|
while (j--) {
|
|
|
|
var el = els[j];
|
|
|
|
|
|
|
|
var tmp_i = el.i, tmp_f = el.f;
|
|
|
|
el.i = i; el.f = one;
|
2010-04-13 05:45:29 +00:00
|
|
|
|
|
|
|
try { func.call(namespace.$(el)); }
|
|
|
|
catch(e) { $.entwine.warn_exception(name, el, e); }
|
|
|
|
finally { el.i = tmp_i; el.f = tmp_f; }
|
2009-11-21 02:33:06 +00:00
|
|
|
}
|
2010-04-13 05:45:29 +00:00
|
|
|
};
|
2009-11-21 02:33:06 +00:00
|
|
|
|
|
|
|
ctors[name+'proxy'] = proxy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2010-04-13 05:45:29 +00:00
|
|
|
$.entwine.Namespace.addHandler({
|
2009-11-21 02:33:06 +00:00
|
|
|
order: 30,
|
|
|
|
|
|
|
|
bind: function(selector, k, v) {
|
|
|
|
if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) {
|
|
|
|
this.bind_condesc(selector, k, v);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate
|
|
|
|
*
|
|
|
|
* Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that
|
|
|
|
* a series of DOM manipulations will only trigger this once.
|
|
|
|
*
|
|
|
|
* The downside of this is that things like:
|
|
|
|
* $('#foo').addClass('tabs'); $('#foo').tabFunctionBar();
|
|
|
|
* won't work.
|
|
|
|
*/
|
|
|
|
$(document).bind('DOMMaybeChanged', function(){
|
|
|
|
// For every namespace
|
2010-04-13 05:45:29 +00:00
|
|
|
for (var k in $.entwine.namespaces) {
|
2009-11-21 02:33:06 +00:00
|
|
|
// That has constructors or destructors
|
2010-04-13 05:45:29 +00:00
|
|
|
var ctors = $.entwine.namespaces[k].store.ctors;
|
2009-11-21 02:33:06 +00:00
|
|
|
if (ctors) {
|
|
|
|
|
|
|
|
// Keep a record of elements that have matched already
|
2010-04-13 05:45:29 +00:00
|
|
|
var matched = $([]), add, rem, res, rule, sel, ctor, dtor;
|
2009-11-21 02:33:06 +00:00
|
|
|
// Stepping through each selector from most to least specific
|
|
|
|
var j = ctors.length;
|
|
|
|
while (j--) {
|
2010-04-13 05:45:29 +00:00
|
|
|
// Build some quick-access variables
|
|
|
|
rule = ctors[j];
|
|
|
|
sel = rule.selector.selector;
|
|
|
|
ctor = rule.onmatch;
|
|
|
|
dtor = rule.onunmatch;
|
|
|
|
|
2009-11-21 02:33:06 +00:00
|
|
|
// Get the list of elements that match this selector, that haven't yet matched a more specific selector
|
|
|
|
res = add = $(sel).not(matched);
|
|
|
|
|
2010-04-13 05:45:29 +00:00
|
|
|
// If this selector has a list of elements it matched against last time
|
|
|
|
if (rule.cache) {
|
2009-11-21 02:33:06 +00:00
|
|
|
// Find the ones that are extra this time
|
2010-04-13 05:45:29 +00:00
|
|
|
add = res.not(rule.cache);
|
|
|
|
if (dtor) {
|
|
|
|
// Find the ones that are gone this time
|
|
|
|
rem = rule.cache.not(res);
|
|
|
|
// And call the destructor on them
|
|
|
|
if (rem.length) ctors.onunmatchproxy(rem, j, dtor);
|
|
|
|
}
|
2009-11-21 02:33:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Call the constructor on the newly matched ones
|
|
|
|
if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
|
|
|
|
|
|
|
|
// Add these matched ones to the list tracking all elements matched so far
|
|
|
|
matched = matched.add(res);
|
|
|
|
// And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
|
|
|
|
ctors[j].cache = res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-04-13 05:45:29 +00:00
|
|
|
});
|
2009-11-21 02:33:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
})(jQuery);
|