mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Re-added entwine src/ in order to use inspector in dev mode
This commit is contained in:
parent
93ea066f53
commit
5f0329c6f2
138
thirdparty/jquery-entwine/src/domevents/jquery.entwine.domevents.addrem.js
vendored
Executable file
138
thirdparty/jquery-entwine/src/domevents/jquery.entwine.domevents.addrem.js
vendored
Executable file
@ -0,0 +1,138 @@
|
|||||||
|
(function($){
|
||||||
|
|
||||||
|
// Gets all the child elements of a particular elements, stores it in an array
|
||||||
|
function getElements(store, original) {
|
||||||
|
var node, i = store.length, next = original.firstChild;
|
||||||
|
|
||||||
|
while ((node = next)) {
|
||||||
|
if (node.nodeType === 1) store[i++] = node;
|
||||||
|
next = node.firstChild || node.nextSibling;
|
||||||
|
while (!next && (node = node.parentNode) && node !== original) next = node.nextSibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This might be faster? Or slower? @todo: benchmark.
|
||||||
|
function getElementsAlt(store, node) {
|
||||||
|
if (node.getElementsByTagName) {
|
||||||
|
var els = node.getElementsByTagName('*'), len = els.length, i = 0, j = store.length;
|
||||||
|
for(; i < len; i++, j++) {
|
||||||
|
store[j] = els[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node.childNodes) {
|
||||||
|
var els = node.childNodes, len = els.length, i = 0;
|
||||||
|
for(; i < len; i++) {
|
||||||
|
getElements(store, els[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var dontTrigger = false;
|
||||||
|
|
||||||
|
var patchDomManipCallback = function(original) {
|
||||||
|
var patched = function(elem){
|
||||||
|
var added = [];
|
||||||
|
|
||||||
|
if (!dontTrigger) {
|
||||||
|
if (elem.nodeType == 1) added[added.length] = elem;
|
||||||
|
getElements(added, elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rv = original.apply(this, arguments);
|
||||||
|
|
||||||
|
if (!dontTrigger && added.length) {
|
||||||
|
var event = $.Event('EntwineElementsAdded');
|
||||||
|
event.targets = added;
|
||||||
|
$(document).triggerHandler(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
patched.patched = true;
|
||||||
|
|
||||||
|
return patched;
|
||||||
|
}
|
||||||
|
|
||||||
|
var version = $.prototype.jquery.split('.');
|
||||||
|
var callbackIdx = (version[0] > 1 || version[1] >= 10 ? 1 : 2);
|
||||||
|
|
||||||
|
// Monkey patch $.fn.domManip to catch all regular jQuery add element calls
|
||||||
|
var _domManip = $.prototype.domManip;
|
||||||
|
$.prototype.domManip = function() {
|
||||||
|
if (!arguments[callbackIdx].patched) arguments[callbackIdx] = patchDomManipCallback(arguments[callbackIdx]);
|
||||||
|
return _domManip.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Monkey patch $.fn.html to catch when jQuery sets innerHTML directly
|
||||||
|
var _html = $.prototype.html;
|
||||||
|
$.prototype.html = function(value) {
|
||||||
|
if (value === undefined) return _html.apply(this, arguments);
|
||||||
|
|
||||||
|
dontTrigger = true;
|
||||||
|
var res = _html.apply(this, arguments);
|
||||||
|
dontTrigger = false;
|
||||||
|
|
||||||
|
var added = [];
|
||||||
|
|
||||||
|
var i = 0, length = this.length;
|
||||||
|
for (; i < length; i++ ) getElements(added, this[i]);
|
||||||
|
|
||||||
|
var event = $.Event('EntwineElementsAdded');
|
||||||
|
event.targets = added;
|
||||||
|
$(document).triggerHandler(event);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is true, we've changed something to call cleanData so that we can catch the elements, but we don't
|
||||||
|
// want to call the underlying original $.cleanData
|
||||||
|
var supressActualClean = false;
|
||||||
|
|
||||||
|
// Monkey patch $.cleanData to catch element removal
|
||||||
|
var _cleanData = $.cleanData;
|
||||||
|
$.cleanData = function( elems ) {
|
||||||
|
// By default we can assume all elements passed are legitimately being removeed
|
||||||
|
var removed = elems;
|
||||||
|
|
||||||
|
// Except if we're supressing actual clean - we might be being called by jQuery "being careful" about detaching nodes
|
||||||
|
// before attaching them. So we need to check to make sure these nodes currently are in a document
|
||||||
|
if (supressActualClean) {
|
||||||
|
var i = 0, len = elems.length, removed = [], ri = 0;
|
||||||
|
for(; i < len; i++) {
|
||||||
|
var node = elems[i], current = node;
|
||||||
|
while (current = current.parentNode) {
|
||||||
|
if (current.nodeType == 9) { removed[ri++] = node; break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removed.length) {
|
||||||
|
var event = $.Event('EntwineElementsRemoved');
|
||||||
|
event.targets = removed;
|
||||||
|
$(document).triggerHandler(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!supressActualClean) _cleanData.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Monkey patch $.fn.remove to catch when we're just detaching (keepdata == 1) -
|
||||||
|
// this doesn't call cleanData but still needs to trigger event
|
||||||
|
var _remove = $.prototype.remove;
|
||||||
|
$.prototype.remove = function(selector, keepdata) {
|
||||||
|
supressActualClean = keepdata;
|
||||||
|
var rv = _remove.call(this, selector);
|
||||||
|
supressActualClean = false;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And on DOM ready, trigger adding once
|
||||||
|
$(function(){
|
||||||
|
var added = []; getElements(added, document);
|
||||||
|
|
||||||
|
var event = $.Event('EntwineElementsAdded');
|
||||||
|
event.targets = added;
|
||||||
|
$(document).triggerHandler(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})(jQuery);
|
149
thirdparty/jquery-entwine/src/domevents/jquery.entwine.domevents.maybechanged.js
vendored
Executable file
149
thirdparty/jquery-entwine/src/domevents/jquery.entwine.domevents.maybechanged.js
vendored
Executable file
@ -0,0 +1,149 @@
|
|||||||
|
(function($){
|
||||||
|
|
||||||
|
/** Utility function to monkey-patch a jQuery method */
|
||||||
|
var monkey = function( /* method, method, ...., patch */){
|
||||||
|
var methods = $.makeArray(arguments);
|
||||||
|
var patch = methods.pop();
|
||||||
|
|
||||||
|
$.each(methods, function(i, method){
|
||||||
|
var old = $.fn[method];
|
||||||
|
|
||||||
|
$.fn[method] = function() {
|
||||||
|
var self = this, args = $.makeArray(arguments);
|
||||||
|
|
||||||
|
var rv = old.apply(self, args);
|
||||||
|
patch.apply(self, args);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** What to call to run a function 'soon'. Normally setTimeout, but for syncronous mode we override so soon === now */
|
||||||
|
var runSoon = window.setTimeout;
|
||||||
|
|
||||||
|
/** The timer handle for the asyncronous matching call */
|
||||||
|
var ChangeDetails = Base.extend({
|
||||||
|
|
||||||
|
init: function() {
|
||||||
|
this.global = false;
|
||||||
|
this.attrs = {};
|
||||||
|
this.classes = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Fire the change event. Only fires on the document node, so bind to that */
|
||||||
|
triggerEvent: function() {
|
||||||
|
// If we're not the active changes instance any more, don't trigger
|
||||||
|
if (changes != this) return;
|
||||||
|
|
||||||
|
// Cancel any pending timeout (if we're directly called in the mean time)
|
||||||
|
if (this.check_id) clearTimeout(this.check_id);
|
||||||
|
|
||||||
|
// Reset the global changes object to be a new instance (do before trigger, in case trigger fires changes itself)
|
||||||
|
changes = new ChangeDetails();
|
||||||
|
|
||||||
|
// Fire event
|
||||||
|
$(document).triggerHandler("EntwineSubtreeMaybeChanged", [this]);
|
||||||
|
},
|
||||||
|
|
||||||
|
changed: function() {
|
||||||
|
if (!this.check_id) {
|
||||||
|
var self = this;
|
||||||
|
this.check_id = runSoon(function(){ self.check_id = null; self.triggerEvent(); }, 10);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addAll: function() {
|
||||||
|
if (this.global) return this; // If we've already flagged as a global change, just skip
|
||||||
|
|
||||||
|
this.global = true;
|
||||||
|
this.changed();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
addSubtree: function(node) {
|
||||||
|
return this.addAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
/* For now we don't do this. It's expensive, and jquery.entwine.ctors doesn't use this information anyway */
|
||||||
|
addSubtreeFuture: function(node) {
|
||||||
|
if (this.global) return this; // If we've already flagged as a global change, just skip
|
||||||
|
|
||||||
|
this.subtree = this.subtree ? this.subtree.add(node) : $(node);
|
||||||
|
this.changed();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
addAttr: function(attr, node) {
|
||||||
|
if (this.global) return this;
|
||||||
|
|
||||||
|
this.attrs[attr] = (attr in this.attrs) ? this.attrs[attr].add(node) : $(node);
|
||||||
|
this.changed();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
addClass: function(klass, node) {
|
||||||
|
if (this.global) return this;
|
||||||
|
|
||||||
|
this.classes[klass] = (klass in this.classes) ? this.classes[klass].add(node) : $(node);
|
||||||
|
this.changed();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var changes = new ChangeDetails();
|
||||||
|
|
||||||
|
// Element add events trigger maybechanged events
|
||||||
|
|
||||||
|
$(document).bind('EntwineElementsAdded', function(e){ changes.addSubtree(e.targets); });
|
||||||
|
|
||||||
|
// Element remove events trigger maybechanged events, but we have to wait until after the nodes are actually removed
|
||||||
|
// (EntwineElementsRemoved fires _just before_ the elements are removed so the data still exists), especially in syncronous mode
|
||||||
|
|
||||||
|
var removed = null;
|
||||||
|
$(document).bind('EntwineElementsRemoved', function(e){ removed = e.targets; });
|
||||||
|
|
||||||
|
monkey('remove', 'html', 'empty', function(){
|
||||||
|
var subtree = removed; removed = null;
|
||||||
|
if (subtree) changes.addSubtree(subtree);
|
||||||
|
});
|
||||||
|
|
||||||
|
// We also need to know when an attribute, class, etc changes. Patch the relevant jQuery methods here
|
||||||
|
|
||||||
|
monkey('removeAttr', function(attr){
|
||||||
|
changes.addAttr(attr, this);
|
||||||
|
});
|
||||||
|
|
||||||
|
monkey('addClass', 'removeClass', 'toggleClass', function(klass){
|
||||||
|
if (typeof klass == 'string') changes.addClass(klass, this);
|
||||||
|
});
|
||||||
|
|
||||||
|
monkey('attr', function(a, b){
|
||||||
|
if (b !== undefined && typeof a == 'string') changes.addAttr(a, this);
|
||||||
|
else if (typeof a != 'string') { for (var k in a) changes.addAttr(k, this); }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add some usefull accessors to $.entwine
|
||||||
|
|
||||||
|
$.extend($.entwine, {
|
||||||
|
/**
|
||||||
|
* Make onmatch and onunmatch work in synchronous mode - that is, new elements will be detected immediately after
|
||||||
|
* the DOM manipulation that made them match. This is only really useful for during testing, since it's pretty slow
|
||||||
|
* (otherwise we'd make it the default).
|
||||||
|
*/
|
||||||
|
synchronous_mode: function() {
|
||||||
|
if (changes && changes.check_id) clearTimeout(changes.check_id);
|
||||||
|
changes = new ChangeDetails();
|
||||||
|
|
||||||
|
runSoon = function(func, delay){ func.call(this); return null; };
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger onmatch and onunmatch now - usefull for after DOM manipulation by methods other than through jQuery.
|
||||||
|
* Called automatically on document.ready
|
||||||
|
*/
|
||||||
|
triggerMatching: function() {
|
||||||
|
changes.addAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
63
thirdparty/jquery-entwine/src/jquery.entwine.addrem.js
vendored
Executable file
63
thirdparty/jquery-entwine/src/jquery.entwine.addrem.js
vendored
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
$.entwine.Namespace.addMethods({
|
||||||
|
build_addrem_proxy: function(name) {
|
||||||
|
var one = this.one(name, 'func');
|
||||||
|
|
||||||
|
return function() {
|
||||||
|
if (this.length === 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (this.length) {
|
||||||
|
var rv, i = this.length;
|
||||||
|
while (i--) rv = one(this[i], arguments);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return one(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
bind_addrem_proxy: function(selector, name, func) {
|
||||||
|
var rulelist = this.store[name] || (this.store[name] = $.entwine.RuleList());
|
||||||
|
|
||||||
|
var rule = rulelist.addRule(selector, name); rule.func = func;
|
||||||
|
|
||||||
|
if (!this.injectee.hasOwnProperty(name)) {
|
||||||
|
this.injectee[name] = this.build_addrem_proxy(name);
|
||||||
|
this.injectee[name].isentwinemethod = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.entwine.Namespace.addHandler({
|
||||||
|
order: 30,
|
||||||
|
|
||||||
|
bind: function(selector, k, v) {
|
||||||
|
if ($.isFunction(v) && (k == 'onadd' || k == 'onremove')) {
|
||||||
|
this.bind_addrem_proxy(selector, k, v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('EntwineElementsAdded', function(e){
|
||||||
|
// For every namespace
|
||||||
|
for (var k in $.entwine.namespaces) {
|
||||||
|
var namespace = $.entwine.namespaces[k];
|
||||||
|
if (namespace.injectee.onadd) namespace.injectee.onadd.call(e.targets);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('EntwineElementsRemoved', function(e){
|
||||||
|
for (var k in $.entwine.namespaces) {
|
||||||
|
var namespace = $.entwine.namespaces[k];
|
||||||
|
if (namespace.injectee.onremove) namespace.injectee.onremove.call(e.targets);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})(jQuery);
|
242
thirdparty/jquery-entwine/src/jquery.entwine.ctors.js
vendored
Executable file
242
thirdparty/jquery-entwine/src/jquery.entwine.ctors.js
vendored
Executable file
@ -0,0 +1,242 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
/* Add the methods to handle constructor & destructor binding to the Namespace class */
|
||||||
|
$.entwine.Namespace.addMethods({
|
||||||
|
bind_condesc: function(selector, name, func) {
|
||||||
|
var ctors = this.store.ctors || (this.store.ctors = $.entwine.RuleList()) ;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
try { func.call(namespace.$(el)); }
|
||||||
|
catch(e) { $.entwine.warn_exception(name, el, e); }
|
||||||
|
finally { el.i = tmp_i; el.f = tmp_f; }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ctors[name+'proxy'] = proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.entwine.Namespace.addHandler({
|
||||||
|
order: 30,
|
||||||
|
|
||||||
|
bind: function(selector, k, v) {
|
||||||
|
if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) {
|
||||||
|
// When we add new matchers we need to trigger a full global recalc once, regardless of the DOM changes that triggered the event
|
||||||
|
this.matchersDirty = true;
|
||||||
|
|
||||||
|
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('EntwineSubtreeMaybeChanged', function(e, changes){
|
||||||
|
// var start = (new Date).getTime();
|
||||||
|
|
||||||
|
// For every namespace
|
||||||
|
for (var k in $.entwine.namespaces) {
|
||||||
|
var namespace = $.entwine.namespaces[k];
|
||||||
|
|
||||||
|
// That has constructors or destructors
|
||||||
|
var ctors = namespace.store.ctors;
|
||||||
|
if (ctors) {
|
||||||
|
|
||||||
|
// Keep a record of elements that have matched some previous more specific rule.
|
||||||
|
// Not that we _don't_ actually do that until this is needed. If matched is null, it's not been calculated yet.
|
||||||
|
// We also keep track of any elements that have newly been taken or released by a specific rule
|
||||||
|
var matched = null, taken = $([]), released = $([]);
|
||||||
|
|
||||||
|
// Updates matched to contain all the previously matched elements as if we'd been keeping track all along
|
||||||
|
var calcmatched = function(j){
|
||||||
|
if (matched !== null) return;
|
||||||
|
matched = $([]);
|
||||||
|
|
||||||
|
var cache, k = ctors.length;
|
||||||
|
while ((--k) > j) {
|
||||||
|
if (cache = ctors[k].cache) matched = matched.add(cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some declared variables used in the loop
|
||||||
|
var add, rem, res, rule, sel, ctor, dtor, full;
|
||||||
|
|
||||||
|
// Stepping through each selector from most to least specific
|
||||||
|
var j = ctors.length;
|
||||||
|
while (j--) {
|
||||||
|
// Build some quick-access variables
|
||||||
|
rule = ctors[j];
|
||||||
|
sel = rule.selector.selector;
|
||||||
|
ctor = rule.onmatch;
|
||||||
|
dtor = rule.onunmatch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rule.cache might be stale or fresh. It'll be stale if
|
||||||
|
- some more specific selector now has some of rule.cache in it
|
||||||
|
- some change has happened that means new elements match this selector now
|
||||||
|
- some change has happened that means elements no longer match this selector
|
||||||
|
|
||||||
|
The first we can just compare rules.cache with matched, removing anything that's there already.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Reset the "elements that match this selector and no more specific selector with an onmatch rule" to null.
|
||||||
|
// Staying null means this selector is fresh.
|
||||||
|
res = null;
|
||||||
|
|
||||||
|
// If this gets changed to true, it's too hard to do a delta update, so do a full update
|
||||||
|
full = false;
|
||||||
|
|
||||||
|
if (namespace.matchersDirty || changes.global) {
|
||||||
|
// For now, just fall back to old version. We need to do something like changed.Subtree.find('*').andSelf().filter(sel), but that's _way_ slower on modern browsers than the below
|
||||||
|
full = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We don't deal with attributes yet, so any attribute change means we need to do a full recalc
|
||||||
|
for (var k in changes.attrs) { full = true; break; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
If a class changes, but it isn't listed in our selector, we don't care - the change couldn't affect whether or not any element matches
|
||||||
|
|
||||||
|
If it is listed on our selector
|
||||||
|
- If it is on the direct match part, it could have added or removed the node it changed on
|
||||||
|
- If it is on the context part, it could have added or removed any node that were previously included or excluded because of a match or failure to match with the context required on that node
|
||||||
|
- NOTE: It might be on _both_
|
||||||
|
*/
|
||||||
|
|
||||||
|
var method = rule.selector.affectedBy(changes);
|
||||||
|
|
||||||
|
if (method.classes.context) {
|
||||||
|
full = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (var k in method.classes.direct) {
|
||||||
|
calcmatched(j);
|
||||||
|
var recheck = changes.classes[k].not(matched);
|
||||||
|
|
||||||
|
if (res === null) {
|
||||||
|
res = rule.cache ? rule.cache.not(taken).add(released.filter(sel)) : $([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = res.not(recheck).add(recheck.filter(sel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full) {
|
||||||
|
calcmatched(j);
|
||||||
|
res = $(sel).not(matched);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!res) {
|
||||||
|
// We weren't stale because of any changes to the DOM that affected this selector, but more specific
|
||||||
|
// onmatches might have caused stale-ness
|
||||||
|
|
||||||
|
// Do any of the previous released elements match this selector?
|
||||||
|
add = released.length && released.filter(sel);
|
||||||
|
|
||||||
|
if (add && add.length) {
|
||||||
|
// Yes, so we're stale as we need to include them. Filter for any possible taken value at the same time
|
||||||
|
res = rule.cache ? rule.cache.not(taken).add(add) : add;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do we think we own any of the elements now taken by more specific rules?
|
||||||
|
rem = taken.length && rule.cache && rule.cache.filter(taken);
|
||||||
|
|
||||||
|
if (rem && rem.length) {
|
||||||
|
// Yes, so we're stale as we need to exclude them.
|
||||||
|
res = rule.cache.not(rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Res will be null if we know we are fresh (no full needed, selector not affectedBy changes)
|
||||||
|
if (res === null) {
|
||||||
|
// If we are tracking matched, add ourselves
|
||||||
|
if (matched && rule.cache) matched = matched.add(rule.cache);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If this selector has a list of elements it matched against last time
|
||||||
|
if (rule.cache) {
|
||||||
|
// Find the ones that are extra this time
|
||||||
|
add = res.not(rule.cache);
|
||||||
|
rem = rule.cache.not(res);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
add = res; rem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((add && add.length) || (rem && rem.length)) {
|
||||||
|
if (rem && rem.length) {
|
||||||
|
released = released.add(rem);
|
||||||
|
|
||||||
|
if (dtor && !rule.onunmatchRunning) {
|
||||||
|
rule.onunmatchRunning = true;
|
||||||
|
ctors.onunmatchproxy(rem, j, dtor);
|
||||||
|
rule.onunmatchRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the constructor on the newly matched ones
|
||||||
|
if (add && add.length) {
|
||||||
|
taken = taken.add(add);
|
||||||
|
released = released.not(add);
|
||||||
|
|
||||||
|
if (ctor && !rule.onmatchRunning) {
|
||||||
|
rule.onmatchRunning = true;
|
||||||
|
ctors.onmatchproxy(add, j, ctor);
|
||||||
|
rule.onmatchRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are tracking matched, add ourselves
|
||||||
|
if (matched) matched = matched.add(res);
|
||||||
|
|
||||||
|
// And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
|
||||||
|
rule.cache = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace.matchersDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log((new Date).getTime() - start);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})(jQuery);
|
118
thirdparty/jquery-entwine/src/jquery.entwine.eventcapture.js
vendored
Executable file
118
thirdparty/jquery-entwine/src/jquery.entwine.eventcapture.js
vendored
Executable file
@ -0,0 +1,118 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
$.entwine.Namespace.addMethods({
|
||||||
|
bind_capture: function(selector, event, name, capture) {
|
||||||
|
var store = this.captures || (this.captures = {});
|
||||||
|
var rulelists = store[event] || (store[event] = {});
|
||||||
|
var rulelist = rulelists[name] || (rulelists[name] = $.entwine.RuleList());
|
||||||
|
|
||||||
|
rule = rulelist.addRule(selector, event);
|
||||||
|
rule.handler = name;
|
||||||
|
|
||||||
|
this.bind_proxy(selector, name, capture);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var bindings = $.entwine.capture_bindings = {};
|
||||||
|
|
||||||
|
var event_proxy = function(event) {
|
||||||
|
return function(e) {
|
||||||
|
var namespace, capturelists, forevent, capturelist, rule, handler, sel;
|
||||||
|
|
||||||
|
for (var k in $.entwine.namespaces) {
|
||||||
|
namespace = $.entwine.namespaces[k];
|
||||||
|
capturelists = namespace.captures;
|
||||||
|
|
||||||
|
if (capturelists && (forevent = capturelists[event])) {
|
||||||
|
for (var k in forevent) {
|
||||||
|
var capturelist = forevent[k];
|
||||||
|
var triggered = namespace.$([]);
|
||||||
|
|
||||||
|
// Stepping through each selector from most to least specific
|
||||||
|
var j = capturelist.length;
|
||||||
|
while (j--) {
|
||||||
|
rule = capturelist[j];
|
||||||
|
handler = rule.handler;
|
||||||
|
sel = rule.selector.selector;
|
||||||
|
|
||||||
|
var matching = namespace.$(sel).not(triggered);
|
||||||
|
matching[handler].apply(matching, arguments);
|
||||||
|
|
||||||
|
triggered = triggered.add(matching);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var selector_proxy = function(selector, handler, includechildren) {
|
||||||
|
var matcher = $.selector(selector);
|
||||||
|
return function(e){
|
||||||
|
if (matcher.matches(e.target)) return handler.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var document_proxy = function(selector, handler, includechildren) {
|
||||||
|
return function(e){
|
||||||
|
if (e.target === document) return handler.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var window_proxy = function(selector, handler, includechildren) {
|
||||||
|
return function(e){
|
||||||
|
if (e.target === window) return handler.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var property_proxy = function(property, handler, includechildren) {
|
||||||
|
var matcher;
|
||||||
|
|
||||||
|
return function(e){
|
||||||
|
var match = this['get'+property]();
|
||||||
|
|
||||||
|
if (typeof(match) == 'string') {
|
||||||
|
var matcher = (matcher && match == matcher.selector) ? matcher : $.selector(match);
|
||||||
|
if (matcher.matches(e.target)) return handler.apply(this, arguments);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ($.inArray(e.target, match) !== -1) return handler.apply(this, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.entwine.Namespace.addHandler({
|
||||||
|
order: 10,
|
||||||
|
|
||||||
|
bind: function(selector, k, v) {
|
||||||
|
var match;
|
||||||
|
if ($.isPlainObject(v) && (match = k.match(/^from\s*(.*)/))) {
|
||||||
|
var from = match[1];
|
||||||
|
var proxyGen;
|
||||||
|
|
||||||
|
if (from.match(/[^\w]/)) proxyGen = selector_proxy;
|
||||||
|
else if (from == 'Window' || from == 'window') proxyGen = window_proxy;
|
||||||
|
else if (from == 'Document' || from == 'document') proxyGen = document_proxy;
|
||||||
|
else proxyGen = property_proxy;
|
||||||
|
|
||||||
|
for (var onevent in v) {
|
||||||
|
var handler = v[onevent];
|
||||||
|
match = onevent.match(/^on(.*)/);
|
||||||
|
var event = match[1];
|
||||||
|
|
||||||
|
this.bind_capture(selector, event, k + '_' + event, proxyGen(from, handler));
|
||||||
|
|
||||||
|
if (!bindings[event]) {
|
||||||
|
var namespaced = event.replace(/(\s+|$)/g, '.entwine$1');
|
||||||
|
bindings[event] = event_proxy(event);
|
||||||
|
|
||||||
|
$(proxyGen == window_proxy ? window : document).bind(namespaced, bindings[event]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
249
thirdparty/jquery-entwine/src/jquery.entwine.events.js
vendored
Executable file
249
thirdparty/jquery-entwine/src/jquery.entwine.events.js
vendored
Executable file
@ -0,0 +1,249 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
/** Taken from jQuery 1.5.2 for backwards compatibility */
|
||||||
|
if ($.support.changeBubbles == undefined) {
|
||||||
|
$.support.changeBubbles = true;
|
||||||
|
|
||||||
|
var el = document.createElement("div");
|
||||||
|
eventName = "onchange";
|
||||||
|
|
||||||
|
if (el.attachEvent) {
|
||||||
|
var isSupported = (eventName in el);
|
||||||
|
if (!isSupported) {
|
||||||
|
el.setAttribute(eventName, "return;");
|
||||||
|
isSupported = typeof el[eventName] === "function";
|
||||||
|
}
|
||||||
|
|
||||||
|
$.support.changeBubbles = isSupported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if node b is the same as, or is a descendant of, node a */
|
||||||
|
if (document.compareDocumentPosition) {
|
||||||
|
var is_or_contains = function(a, b) {
|
||||||
|
return a && b && (a == b || !!(a.compareDocumentPosition(b) & 16));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var is_or_contains = function(a, b) {
|
||||||
|
return a && b && (a == b || (a.contains ? a.contains(b) : true));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the methods to handle event binding to the Namespace class */
|
||||||
|
$.entwine.Namespace.addMethods({
|
||||||
|
build_event_proxy: function(name) {
|
||||||
|
var one = this.one(name, 'func');
|
||||||
|
|
||||||
|
var prxy = function(e, data) {
|
||||||
|
// For events that do not bubble we manually trigger delegation (see delegate_submit below)
|
||||||
|
// If this event is a manual trigger, the event we actually want to bubble is attached as a property of the passed event
|
||||||
|
e = e.delegatedEvent || e;
|
||||||
|
|
||||||
|
var el = e.target;
|
||||||
|
while (el && el.nodeType == 1 && !e.isPropagationStopped()) {
|
||||||
|
var ret = one(el, arguments);
|
||||||
|
if (ret !== undefined) e.result = ret;
|
||||||
|
if (ret === false) { e.preventDefault(); e.stopPropagation(); }
|
||||||
|
|
||||||
|
el = el.parentNode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return prxy;
|
||||||
|
},
|
||||||
|
|
||||||
|
build_mouseenterleave_proxy: function(name) {
|
||||||
|
var one = this.one(name, 'func');
|
||||||
|
|
||||||
|
var prxy = function(e) {
|
||||||
|
var el = e.target;
|
||||||
|
var rel = e.relatedTarget;
|
||||||
|
|
||||||
|
while (el && el.nodeType == 1 && !e.isPropagationStopped()) {
|
||||||
|
/* We know el contained target. If it also contains relatedTarget then we didn't mouseenter / leave. What's more, every ancestor will also
|
||||||
|
contan el and rel, and so we can just stop bubbling */
|
||||||
|
if (is_or_contains(el, rel)) break;
|
||||||
|
|
||||||
|
var ret = one(el, arguments);
|
||||||
|
if (ret !== undefined) e.result = ret;
|
||||||
|
if (ret === false) { e.preventDefault(); e.stopPropagation(); }
|
||||||
|
|
||||||
|
el = el.parentNode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return prxy;
|
||||||
|
},
|
||||||
|
|
||||||
|
build_change_proxy: function(name) {
|
||||||
|
var one = this.one(name, 'func');
|
||||||
|
|
||||||
|
/*
|
||||||
|
This change bubble emulation code is taken mostly from jQuery 1.6 - unfortunately we can't easily reuse any of
|
||||||
|
it without duplication, so we'll have to re-migrate any bugfixes
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Get the value of an item. Isn't supposed to be interpretable, just stable for some value, and different
|
||||||
|
// once the value changes
|
||||||
|
var getVal = function( elem ) {
|
||||||
|
var type = elem.type, val = elem.value;
|
||||||
|
|
||||||
|
if (type === "radio" || type === "checkbox") {
|
||||||
|
val = elem.checked;
|
||||||
|
}
|
||||||
|
else if (type === "select-multiple") {
|
||||||
|
val = "";
|
||||||
|
if (elem.selectedIndex > -1) {
|
||||||
|
val = jQuery.map(elem.options, function(elem){ return elem.selected; }).join("-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (jQuery.nodeName(elem, "select")) {
|
||||||
|
val = elem.selectedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test if a node name is a form input
|
||||||
|
var rformElems = /^(?:textarea|input|select)$/i;
|
||||||
|
|
||||||
|
// Check if this event is a change, and bubble the change event if it is
|
||||||
|
var testChange = function(e) {
|
||||||
|
var elem = e.target, data, val;
|
||||||
|
|
||||||
|
if (!rformElems.test(elem.nodeName) || elem.readOnly) return;
|
||||||
|
|
||||||
|
data = jQuery.data(elem, "_entwine_change_data");
|
||||||
|
val = getVal(elem);
|
||||||
|
|
||||||
|
// the current data will be also retrieved by beforeactivate
|
||||||
|
if (e.type !== "focusout" || elem.type !== "radio") {
|
||||||
|
jQuery.data(elem, "_entwine_change_data", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data === undefined || val === data) return;
|
||||||
|
|
||||||
|
if (data != null || val) {
|
||||||
|
e.type = "change";
|
||||||
|
|
||||||
|
while (elem && elem.nodeType == 1 && !e.isPropagationStopped()) {
|
||||||
|
var ret = one(elem, arguments);
|
||||||
|
if (ret !== undefined) e.result = ret;
|
||||||
|
if (ret === false) { e.preventDefault(); e.stopPropagation(); }
|
||||||
|
|
||||||
|
elem = elem.parentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The actual proxy - responds to several events, some of which triger a change check, some
|
||||||
|
// of which just store the value for future change checks
|
||||||
|
var prxy = function(e) {
|
||||||
|
var event = e.type, elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case 'focusout':
|
||||||
|
case 'beforedeactivate':
|
||||||
|
testChange.apply(this, arguments);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'click':
|
||||||
|
if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
|
||||||
|
testChange.apply(this, arguments);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Change has to be called before submit
|
||||||
|
// Keydown will be called before keypress, which is used in submit-event delegation
|
||||||
|
case 'keydown':
|
||||||
|
if (
|
||||||
|
(e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
|
||||||
|
(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
|
||||||
|
type === "select-multiple"
|
||||||
|
) {
|
||||||
|
testChange.apply(this, arguments);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Beforeactivate happens also before the previous element is blurred
|
||||||
|
// with this event you can't trigger a change event, but you can store
|
||||||
|
// information
|
||||||
|
case 'focusin':
|
||||||
|
case 'beforeactivate':
|
||||||
|
jQuery.data( elem, "_entwine_change_data", getVal(elem) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prxy;
|
||||||
|
},
|
||||||
|
|
||||||
|
bind_event: function(selector, name, func, event) {
|
||||||
|
var funcs = this.store[name] || (this.store[name] = $.entwine.RuleList()) ;
|
||||||
|
var proxies = funcs.proxies || (funcs.proxies = {});
|
||||||
|
|
||||||
|
var rule = funcs.addRule(selector, name); rule.func = func;
|
||||||
|
|
||||||
|
if (!proxies[name]) {
|
||||||
|
switch (name) {
|
||||||
|
case 'onmouseenter':
|
||||||
|
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||||
|
event = 'mouseover';
|
||||||
|
break;
|
||||||
|
case 'onmouseleave':
|
||||||
|
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||||
|
event = 'mouseout';
|
||||||
|
break;
|
||||||
|
case 'onchange':
|
||||||
|
if (!$.support.changeBubbles) {
|
||||||
|
proxies[name] = this.build_change_proxy(name);
|
||||||
|
event = 'click keydown focusin focusout beforeactivate beforedeactivate';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'onsubmit':
|
||||||
|
event = 'delegatedSubmit';
|
||||||
|
break;
|
||||||
|
case 'onfocus':
|
||||||
|
case 'onblur':
|
||||||
|
$.entwine.warn('Event '+event+' not supported - using focusin / focusout instead', $.entwine.WARN_LEVEL_IMPORTANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If none of the special handlers created a proxy, use the generic proxy
|
||||||
|
if (!proxies[name]) proxies[name] = this.build_event_proxy(name);
|
||||||
|
|
||||||
|
$(document).bind(event.replace(/(\s+|$)/g, '.entwine$1'), proxies[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.entwine.Namespace.addHandler({
|
||||||
|
order: 40,
|
||||||
|
|
||||||
|
bind: function(selector, k, v){
|
||||||
|
var match, event;
|
||||||
|
if ($.isFunction(v) && (match = k.match(/^on(.*)/))) {
|
||||||
|
event = match[1];
|
||||||
|
this.bind_event(selector, k, v, event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Find all forms and bind onsubmit to trigger on the document too.
|
||||||
|
// This is the only event that can't be grabbed via delegation
|
||||||
|
|
||||||
|
var delegate_submit = function(e, data){
|
||||||
|
var delegationEvent = $.Event('delegatedSubmit'); delegationEvent.delegatedEvent = e;
|
||||||
|
return $(document).trigger(delegationEvent, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).bind('EntwineElementsAdded', function(e){
|
||||||
|
var forms = $(e.targets).filter('form');
|
||||||
|
if (!forms.length) return;
|
||||||
|
|
||||||
|
forms.bind('submit.entwine_delegate_submit', delegate_submit);
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
||||||
|
|
240
thirdparty/jquery-entwine/src/jquery.entwine.inspector.js
vendored
Executable file
240
thirdparty/jquery-entwine/src/jquery.entwine.inspector.js
vendored
Executable file
@ -0,0 +1,240 @@
|
|||||||
|
|
||||||
|
jQuery(function($){
|
||||||
|
// Create a new style element
|
||||||
|
var styleEl = document.createElement('style');
|
||||||
|
styleEl.setAttribute('type', 'text/css');
|
||||||
|
(document.head || document.getElementsByTagName('head')[0]).appendChild(styleEl);
|
||||||
|
|
||||||
|
var inspectorCSS = [
|
||||||
|
'#entwine-inspector { position: fixed; z-index: 1000001; left: 0; right: 0; height: 400px; background: white; -webkit-box-shadow: 0 5px 40px 0 black; -moz-box-shadow: 0 5px 40px 0 black; }',
|
||||||
|
'#entwine-inspector li { list-style: none; margin: 2px 0; padding: 2px 0; }',
|
||||||
|
'#entwine-inspector li:hover { background: #eee; }',
|
||||||
|
'#entwine-inspector li.selected { background: #ddd; }',
|
||||||
|
|
||||||
|
'#ei-columns { overflow: hidden; display: -webkit-box; display: -moz-box; width: 100%; height: 380px; }',
|
||||||
|
|
||||||
|
'.ei-column { height: 380px; width: 1px; -webkit-box-flex: 1; -moz-box-flex: 1; }',
|
||||||
|
'#entwine-inspector .ei-column h1 { display: block; margin: 0; padding: 5px 2px; height: 20px; text-align: center; background: #444; color: #eee; font-size: 14px; font-weight: bold; }',
|
||||||
|
'#entwine-inspector .ei-column ul { overflow-y: scroll; height: 350px; }',
|
||||||
|
|
||||||
|
'#ei-options { overflow: hidden; height: 20px; background: #444; color: #eee; }',
|
||||||
|
'#ei-options label { padding-right: 5px; border-right: 1px solid #eee; }',
|
||||||
|
|
||||||
|
'.ei-entwined:hover, .ei-selected { background: rgba(128,0,0,0.2); }',
|
||||||
|
'.ei-hovernode { position: absolute; z-index: 1000000; background: rgba(0,0,0,0.3); border: 1px solid white; outline: 1px solid white; }',
|
||||||
|
|
||||||
|
'#ei-selectors li { color: #aaa; display: none; }',
|
||||||
|
'#ei-selectors li.matching, #entwine-inspector.show-unmatched #ei-selectors li { display: block; }',
|
||||||
|
'#ei-selectors li.matching { color: black; }'
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
// Set the style element to style up the inspector panel
|
||||||
|
if(styleEl.styleSheet){
|
||||||
|
styleEl.styleSheet.cssText = inspectorCSS;
|
||||||
|
}else{
|
||||||
|
styleEl.appendChild(document.createTextNode(inspectorCSS));
|
||||||
|
}
|
||||||
|
|
||||||
|
var inspectorPanel = $('<div id="entwine-inspector" class="show-unmatched"></div>').appendTo('body');
|
||||||
|
var columnHolder = $('<div id="ei-columns"></div>').appendTo(inspectorPanel);
|
||||||
|
var optionsHolder = $('<div id="ei-options"></div>').appendTo(inspectorPanel);
|
||||||
|
|
||||||
|
inspectorPanel.css({
|
||||||
|
top: -400,
|
||||||
|
visibility: 'hidden'
|
||||||
|
});
|
||||||
|
|
||||||
|
$('body').bind('keypress', function(e){
|
||||||
|
if (e.ctrlKey && e.which == 96) {
|
||||||
|
if (inspectorPanel.css('visibility') != 'visible') {
|
||||||
|
inspectorPanel.css({top: 0, visibility: 'visible'});
|
||||||
|
$('body').css({marginTop: 400});
|
||||||
|
initialise();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inspectorPanel.css({top: -400, visibility: 'hidden'});
|
||||||
|
$('body').css({marginTop: 0});
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var showUnmatching = $('<input id="ei-option-showunmatching" type="checkbox" checked="checked" />').appendTo(optionsHolder);
|
||||||
|
var showUnmatchingLabel = $('<label>Show selectors that dont match</label>').appendTo(optionsHolder);
|
||||||
|
|
||||||
|
showUnmatching.bind('click', function(){
|
||||||
|
inspectorPanel.toggleClass('show-unmatched', $(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
var hovernode;
|
||||||
|
|
||||||
|
var reset = function() {
|
||||||
|
$('.ei-entwined').unbind('.entwine-inspector').removeClass('ei-entwined');
|
||||||
|
if (hovernode) hovernode.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
var initialise = function(){
|
||||||
|
reset();
|
||||||
|
|
||||||
|
$.each($.entwine.namespaces, function(name, namespace){
|
||||||
|
$.each(namespace.store, function(name, list){
|
||||||
|
$.each(list, function(i, rule){
|
||||||
|
var match = $(rule.selector.selector);
|
||||||
|
match.addClass('ei-entwined').bind('click.entwine-inspector', displaydetails);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var dumpElement = function(el) {
|
||||||
|
var frag = document.createDocumentFragment();
|
||||||
|
var div = document.createElement('div'); frag.appendChild(div);
|
||||||
|
|
||||||
|
var clone = el.cloneNode(false); $(clone).removeClass('ei-entwined').removeAttr('style');
|
||||||
|
|
||||||
|
var i = clone.attributes.length;
|
||||||
|
while (i--) {
|
||||||
|
var attr = clone.attributes.item(i);
|
||||||
|
if (attr.name != 'class' && attr.name != 'id' && attr.value.length > 20) attr.value = attr.value.substr(0, 18)+'..'+attr.value.substr(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.appendChild(clone);
|
||||||
|
return div.innerHTML;
|
||||||
|
};
|
||||||
|
|
||||||
|
var displaydetails = function(e){
|
||||||
|
e.preventDefault(); e.stopPropagation();
|
||||||
|
|
||||||
|
columnHolder.empty();
|
||||||
|
|
||||||
|
var columns = {};
|
||||||
|
$.each(['elements', 'namespaces', 'methods', 'selectors'], function(i, col){
|
||||||
|
columns[col] = $('<div id="ei-'+col+'" class="ei-column"><h1>'+col+'</h1></div>').appendTo(columnHolder);
|
||||||
|
})
|
||||||
|
|
||||||
|
var lists = {};
|
||||||
|
|
||||||
|
var ctr = 0;
|
||||||
|
|
||||||
|
lists.elements = $('<ul></ul>').appendTo(columns.elements);
|
||||||
|
|
||||||
|
var displayelement = function(){
|
||||||
|
var target = $(this);
|
||||||
|
|
||||||
|
var li = $('<li></li>');
|
||||||
|
li.text(dumpElement(this)).attr('data-id', ++ctr).data('el', target).prependTo(lists.elements);
|
||||||
|
|
||||||
|
var namespaces = $('<ul data-element="'+ctr+'"></ul>').appendTo(columns.namespaces);
|
||||||
|
|
||||||
|
$.each($.entwine.namespaces, function(name, namespace){
|
||||||
|
var methods = $('<ul data-namespace="'+ctr+'-'+name+'"></ul>');
|
||||||
|
|
||||||
|
$.each(namespace.store, function(method, list){
|
||||||
|
|
||||||
|
if (method == 'ctors') {
|
||||||
|
var matchselectors = $('<ul data-method="'+ctr+'-'+name+'-onmatch"></ul>');
|
||||||
|
var unmatchselectors = $('<ul data-method="'+ctr+'-'+name+'-onunmatch"></ul>');
|
||||||
|
|
||||||
|
$.each(list, function(i, rule){
|
||||||
|
var matchitem = $('<li>'+rule.selector.selector+'</li>').prependTo(matchselectors);
|
||||||
|
var unmatchitem = rule.onunmatch ? $('<li>'+rule.selector.selector+'</li>').prependTo(unmatchselectors) : null;
|
||||||
|
|
||||||
|
if (target.is(rule.selector.selector)) {
|
||||||
|
matchitem.addClass('matching'); unmatchitem && unmatchitem.addClass('matching');
|
||||||
|
|
||||||
|
if (!methods.parent().length) {
|
||||||
|
$('<li data-namespace="'+ctr+'-'+name+'">'+name+'</li>').prependTo(namespaces);
|
||||||
|
methods.appendTo(columns.methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchselectors.parent().length) {
|
||||||
|
$('<li data-method="'+ctr+'-'+name+'-onmatch">onmatch</li>').prependTo(methods);
|
||||||
|
matchselectors.appendTo(columns.selectors);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.onunmatch && !unmatchselectors.parent().length) {
|
||||||
|
$('<li data-method="'+ctr+'-'+name+'-onunmatch">onunmatch</li>').prependTo(methods);
|
||||||
|
unmatchselectors.appendTo(columns.selectors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var selectors = $('<ul data-method="'+ctr+'-'+name+'-'+method+'"></ul>');
|
||||||
|
|
||||||
|
$.each(list, function(i, rule){
|
||||||
|
var ruleitem = $('<li>'+rule.selector.selector+'</li>').prependTo(selectors);
|
||||||
|
|
||||||
|
if (target.is(rule.selector.selector)){
|
||||||
|
ruleitem.addClass('matching');
|
||||||
|
|
||||||
|
if (!methods.parent().length) {
|
||||||
|
$('<li data-namespace="'+ctr+'-'+name+'">'+name+'</li>').prependTo(namespaces);
|
||||||
|
methods.appendTo(columns.methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectors.parent().length) {
|
||||||
|
$('<li data-method="'+ctr+'-'+name+'-'+method+'">'+method+'</li>').prependTo(methods);
|
||||||
|
selectors.appendTo(columns.selectors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$.each($(e.target).parents().andSelf().filter('.ei-entwined'), displayelement);
|
||||||
|
$('#ei-elements > ul:first > li:first').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
var activatelist = function(list) {
|
||||||
|
list = $(list);
|
||||||
|
|
||||||
|
list.siblings('ul').css('display', 'none');
|
||||||
|
|
||||||
|
list.css('display', 'block');
|
||||||
|
list.children().first().click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#entwine-inspector').live('mouseleave', function(){
|
||||||
|
if (hovernode) hovernode.hide();
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#entwine-inspector').live('mouseenter', function(){
|
||||||
|
if (hovernode) hovernode.show();
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#ei-elements > ul > li').live('click', function(e){
|
||||||
|
var target = $(e.target), id = target.attr('data-id');
|
||||||
|
target.addClass('selected').siblings().removeClass('selected');
|
||||||
|
|
||||||
|
if (!hovernode) {
|
||||||
|
hovernode = $('<div class="ei-hovernode"></div>').appendTo('body');
|
||||||
|
}
|
||||||
|
|
||||||
|
var hover = target.data('el');
|
||||||
|
hovernode.css({width: hover.outerWidth()-2, height: hover.outerHeight()-2, top: hover.offset().top, left: hover.offset().left});
|
||||||
|
|
||||||
|
$('.ei-selected').removeClass('ei-selected');
|
||||||
|
|
||||||
|
activatelist('#ei-namespaces ul[data-element="'+id+'"]');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#ei-namespaces > ul > li').live('click', function(e){
|
||||||
|
var target = $(e.target), namespace = target.attr('data-namespace');
|
||||||
|
target.addClass('selected').siblings().removeClass('selected');
|
||||||
|
|
||||||
|
activatelist('#ei-methods ul[data-namespace="'+namespace+'"]');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#ei-methods > ul > li').live('click', function(e){
|
||||||
|
var target = $(e.target), method = target.attr('data-method');
|
||||||
|
target.addClass('selected').siblings().removeClass('selected');
|
||||||
|
|
||||||
|
activatelist('#ei-selectors ul[data-method="'+method+'"]');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
354
thirdparty/jquery-entwine/src/jquery.entwine.js
vendored
Executable file
354
thirdparty/jquery-entwine/src/jquery.entwine.js
vendored
Executable file
@ -0,0 +1,354 @@
|
|||||||
|
try {
|
||||||
|
console.log;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
window.console = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
/* Create a subclass of the jQuery object. This was introduced in jQuery 1.5, but removed again in 1.9 */
|
||||||
|
var sub = function() {
|
||||||
|
function jQuerySub( selector, context ) {
|
||||||
|
return new jQuerySub.fn.init( selector, context );
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery.extend( true, jQuerySub, $ );
|
||||||
|
jQuerySub.superclass = $;
|
||||||
|
jQuerySub.fn = jQuerySub.prototype = $();
|
||||||
|
jQuerySub.fn.constructor = jQuerySub;
|
||||||
|
jQuerySub.fn.init = function init( selector, context ) {
|
||||||
|
if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
|
||||||
|
context = jQuerySub( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
|
||||||
|
};
|
||||||
|
jQuerySub.fn.init.prototype = jQuerySub.fn;
|
||||||
|
var rootjQuerySub = jQuerySub(document);
|
||||||
|
return jQuerySub;
|
||||||
|
};
|
||||||
|
|
||||||
|
var namespaces = {};
|
||||||
|
|
||||||
|
$.entwine = function() {
|
||||||
|
$.fn.entwine.apply(null, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A couple of utility functions for accessing the store outside of this closure, and for making things
|
||||||
|
* operate in a little more easy-to-test manner
|
||||||
|
*/
|
||||||
|
$.extend($.entwine, {
|
||||||
|
/**
|
||||||
|
* Get all the namespaces. Useful for introspection? Internal interface of Namespace not guaranteed consistant
|
||||||
|
*/
|
||||||
|
namespaces: namespaces,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all entwine rules
|
||||||
|
*/
|
||||||
|
clear_all_rules: function() {
|
||||||
|
// Remove proxy functions
|
||||||
|
for (var k in $.fn) { if ($.fn[k].isentwinemethod) delete $.fn[k]; }
|
||||||
|
// Remove bound events - TODO: Make this pluggable, so this code can be moved to jquery.entwine.events.js
|
||||||
|
$(document).unbind('.entwine');
|
||||||
|
$(window).unbind('.entwine');
|
||||||
|
// Remove namespaces, and start over again
|
||||||
|
for (var k in namespaces) delete namespaces[k];
|
||||||
|
for (var k in $.entwine.capture_bindings) delete $.entwine.capture_bindings[k];
|
||||||
|
},
|
||||||
|
|
||||||
|
WARN_LEVEL_NONE: 0,
|
||||||
|
WARN_LEVEL_IMPORTANT: 1,
|
||||||
|
WARN_LEVEL_BESTPRACTISE: 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning level. Set to a higher level to get warnings dumped to console.
|
||||||
|
*/
|
||||||
|
warningLevel: 0,
|
||||||
|
|
||||||
|
/** Utility to optionally display warning messages depending on level */
|
||||||
|
warn: function(message, level) {
|
||||||
|
if (level <= $.entwine.warningLevel && console && console.warn) {
|
||||||
|
console.warn(message);
|
||||||
|
if (console.trace) console.trace();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
warn_exception: function(where, /* optional: */ on, e) {
|
||||||
|
if ($.entwine.WARN_LEVEL_IMPORTANT <= $.entwine.warningLevel && console && console.warn) {
|
||||||
|
if (arguments.length == 2) { e = on; on = null; }
|
||||||
|
|
||||||
|
if (on) console.warn('Uncaught exception',e,'in',where,'on',on);
|
||||||
|
else console.warn('Uncaught exception',e,'in',where);
|
||||||
|
|
||||||
|
if (e.stack) console.warn("Stack Trace:\n" + e.stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/** Stores a count of definitions, so that we can sort identical selectors by definition order */
|
||||||
|
var rulecount = 0;
|
||||||
|
|
||||||
|
var Rule = Base.extend({
|
||||||
|
init: function(selector, name) {
|
||||||
|
this.selector = selector;
|
||||||
|
this.specifity = selector.specifity();
|
||||||
|
this.important = 0;
|
||||||
|
this.name = name;
|
||||||
|
this.rulecount = rulecount++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Rule.compare = function(a, b) {
|
||||||
|
var as = a.specifity, bs = b.specifity;
|
||||||
|
|
||||||
|
return (a.important - b.important) ||
|
||||||
|
(as[0] - bs[0]) ||
|
||||||
|
(as[1] - bs[1]) ||
|
||||||
|
(as[2] - bs[2]) ||
|
||||||
|
(a.rulecount - b.rulecount) ;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.entwine.RuleList = function() {
|
||||||
|
var list = [];
|
||||||
|
|
||||||
|
list.addRule = function(selector, name){
|
||||||
|
var rule = Rule(selector, name);
|
||||||
|
|
||||||
|
list[list.length] = rule;
|
||||||
|
list.sort(Rule.compare);
|
||||||
|
|
||||||
|
return rule;
|
||||||
|
};
|
||||||
|
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
var handlers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Namespace holds all the information needed for adding entwine methods to a namespace (including the _null_ namespace)
|
||||||
|
*/
|
||||||
|
$.entwine.Namespace = Base.extend({
|
||||||
|
init: function(name){
|
||||||
|
if (name && !name.match(/^[A-Za-z0-9.]+$/)) $.entwine.warn('Entwine namespace '+name+' is not formatted as period seperated identifiers', $.entwine.WARN_LEVEL_BESTPRACTISE);
|
||||||
|
name = name || '__base';
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
this.store = {};
|
||||||
|
|
||||||
|
namespaces[name] = this;
|
||||||
|
|
||||||
|
if (name == "__base") {
|
||||||
|
this.injectee = $.fn;
|
||||||
|
this.$ = $;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into
|
||||||
|
this.$ = $.sub ? $.sub() : sub();
|
||||||
|
// Work around bug in sub() - subclass must share cache with root or data won't get cleared by cleanData
|
||||||
|
this.$.cache = $.cache;
|
||||||
|
|
||||||
|
this.injectee = this.$.prototype;
|
||||||
|
|
||||||
|
// We override entwine to inject the name of this namespace when defining blocks inside this namespace
|
||||||
|
var entwine_wrapper = this.injectee.entwine = function(spacename) {
|
||||||
|
var args = arguments;
|
||||||
|
|
||||||
|
if (!spacename || typeof spacename != 'string') { args = $.makeArray(args); args.unshift(name); }
|
||||||
|
else if (spacename.charAt(0) != '.') args[0] = name+'.'+spacename;
|
||||||
|
|
||||||
|
return $.fn.entwine.apply(this, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$.entwine = function() {
|
||||||
|
entwine_wrapper.apply(null, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < handlers.length; i++) {
|
||||||
|
var handler = handlers[i], builder;
|
||||||
|
|
||||||
|
// Inject jQuery object method overrides
|
||||||
|
if (builder = handler.namespaceMethodOverrides) {
|
||||||
|
var overrides = builder(this);
|
||||||
|
for (var k in overrides) this.injectee[k] = overrides[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject $.entwine function overrides
|
||||||
|
if (builder = handler.namespaceStaticOverrides) {
|
||||||
|
var overrides = builder(this);
|
||||||
|
for (var k in overrides) this.$.entwine[k] = overrides[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a function that does selector matching against the function list for a function name
|
||||||
|
* Used by proxy for all calls, and by ctorProxy to handle _super calls
|
||||||
|
* @param {String} name - name of the function as passed in the construction object
|
||||||
|
* @param {String} funcprop - the property on the Rule object that gives the actual function to call
|
||||||
|
* @param {function} basefunc - the non-entwine function to use as the catch-all function at the bottom of the stack
|
||||||
|
*/
|
||||||
|
one: function(name, funcprop, basefunc) {
|
||||||
|
var namespace = this;
|
||||||
|
var funcs = this.store[name];
|
||||||
|
|
||||||
|
var one = function(el, args, i){
|
||||||
|
if (i === undefined) i = funcs.length;
|
||||||
|
while (i--) {
|
||||||
|
if (funcs[i].selector.matches(el)) {
|
||||||
|
var ret, tmp_i = el.i, tmp_f = el.f;
|
||||||
|
el.i = i; el.f = one;
|
||||||
|
try { ret = funcs[i][funcprop].apply(namespace.$(el), args); }
|
||||||
|
finally { el.i = tmp_i; el.f = tmp_f; }
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we didn't find a entwine-defined function, but there is a non-entwine function to use as a base, try that
|
||||||
|
if (basefunc) return basefunc.apply(namespace.$(el), args);
|
||||||
|
};
|
||||||
|
|
||||||
|
return one;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A proxy is a function attached to a callable object (either the base jQuery.fn or a subspace object) which handles
|
||||||
|
* finding and calling the correct function for each member of the current jQuery context
|
||||||
|
* @param {String} name - name of the function as passed in the construction object
|
||||||
|
* @param {function} basefunc - the non-entwine function to use as the catch-all function at the bottom of the stack
|
||||||
|
*/
|
||||||
|
build_proxy: function(name, basefunc) {
|
||||||
|
var one = this.one(name, 'func', basefunc);
|
||||||
|
|
||||||
|
var prxy = function() {
|
||||||
|
var rv, ctx = $(this);
|
||||||
|
|
||||||
|
var i = ctx.length;
|
||||||
|
while (i--) rv = one(ctx[i], arguments);
|
||||||
|
return rv;
|
||||||
|
};
|
||||||
|
|
||||||
|
return prxy;
|
||||||
|
},
|
||||||
|
|
||||||
|
bind_proxy: function(selector, name, func) {
|
||||||
|
var rulelist = this.store[name] || (this.store[name] = $.entwine.RuleList());
|
||||||
|
|
||||||
|
var rule = rulelist.addRule(selector, name); rule.func = func;
|
||||||
|
|
||||||
|
if (!this.injectee.hasOwnProperty(name) || !this.injectee[name].isentwinemethod) {
|
||||||
|
this.injectee[name] = this.build_proxy(name, this.injectee.hasOwnProperty(name) ? this.injectee[name] : null);
|
||||||
|
this.injectee[name].isentwinemethod = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.injectee[name].isentwinemethod) {
|
||||||
|
$.entwine.warn('Warning: Entwine function '+name+' clashes with regular jQuery function - entwine function will not be callable directly on jQuery object', $.entwine.WARN_LEVEL_IMPORTANT);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
add: function(selector, data) {
|
||||||
|
// For every item in the hash, try ever method handler, until one returns true
|
||||||
|
for (var k in data) {
|
||||||
|
var v = data[k];
|
||||||
|
|
||||||
|
for (var i = 0; i < handlers.length; i++) {
|
||||||
|
if (handlers[i].bind && handlers[i].bind.call(this, selector, k, v)) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
has: function(ctx, name) {
|
||||||
|
var rulelist = this.store[name];
|
||||||
|
if (!rulelist) return false;
|
||||||
|
|
||||||
|
/* We go forward this time, since low specifity is likely to knock out a bunch of elements quickly */
|
||||||
|
for (var i = 0 ; i < rulelist.length; i++) {
|
||||||
|
ctx = ctx.not(rulelist[i].selector);
|
||||||
|
if (!ctx.length) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler is some javascript code that adds support for some time of key / value pair passed in the hash to the Namespace add method.
|
||||||
|
* The default handlers provided (and included by default) are event, ctor and properties
|
||||||
|
*/
|
||||||
|
$.entwine.Namespace.addHandler = function(handler) {
|
||||||
|
for (var i = 0; i < handlers.length && handlers[i].order < handler.order; i++) { /* Pass */ }
|
||||||
|
handlers.splice(i, 0, handler);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.entwine.Namespace.addHandler({
|
||||||
|
order: 50,
|
||||||
|
|
||||||
|
bind: function(selector, k, v){
|
||||||
|
if ($.isFunction(v)) {
|
||||||
|
this.bind_proxy(selector, k, v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend($.fn, {
|
||||||
|
/**
|
||||||
|
* Main entwine function. Used for new definitions, calling into a namespace (or forcing the base namespace) and entering a using block
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
entwine: function(spacename) {
|
||||||
|
var i = 0;
|
||||||
|
/* Don't actually work out selector until we try and define something on it - we might be opening a namespace on an function-traveresed object
|
||||||
|
which have non-standard selectors like .parents(.foo).slice(0,1) */
|
||||||
|
var selector = null;
|
||||||
|
|
||||||
|
/* By default we operator on the base namespace */
|
||||||
|
var namespace = namespaces.__base || $.entwine.Namespace();
|
||||||
|
|
||||||
|
/* If the first argument is a string, then it's the name of a namespace. Look it up */
|
||||||
|
if (typeof spacename == 'string') {
|
||||||
|
if (spacename.charAt('0') == '.') spacename = spacename.substr(1);
|
||||||
|
if (spacename) namespace = namespaces[spacename] || $.entwine.Namespace(spacename);
|
||||||
|
i=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All remaining arguments should either be using blocks or definition hashs */
|
||||||
|
while (i < arguments.length) {
|
||||||
|
var res = arguments[i++];
|
||||||
|
|
||||||
|
// If it's a function, call it - either it's a using block or it's a namespaced entwine definition
|
||||||
|
if ($.isFunction(res)) {
|
||||||
|
if (res.length != 1) $.entwine.warn('Function block inside entwine definition does not take $ argument properly', $.entwine.WARN_LEVEL_IMPORTANT);
|
||||||
|
res = res.call(namespace.$(this), namespace.$);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have a entwine definition hash, inject it into namespace
|
||||||
|
if (res) {
|
||||||
|
if (selector === null) selector = this.selector ? $.selector(this.selector) : false;
|
||||||
|
|
||||||
|
if (selector) namespace.add(selector, res);
|
||||||
|
else $.entwine.warn('Entwine block given to entwine call without selector. Make sure you call $(selector).entwine when defining blocks', $.entwine.WARN_LEVEL_IMPORTANT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, return the jQuery object 'this' refers to, wrapped in the new namespace */
|
||||||
|
return namespace.$(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the next most specific version of the current entwine method
|
||||||
|
*/
|
||||||
|
_super: function(){
|
||||||
|
var rv, i = this.length;
|
||||||
|
while (i--) {
|
||||||
|
var el = this[0];
|
||||||
|
rv = el.f(el, arguments, el.i);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
21
thirdparty/jquery-entwine/src/jquery.entwine.legacy.js
vendored
Executable file
21
thirdparty/jquery-entwine/src/jquery.entwine.legacy.js
vendored
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
// Adds back concrete methods for backwards compatibility
|
||||||
|
$.concrete = $.entwine;
|
||||||
|
$.fn.concrete = $.fn.entwine;
|
||||||
|
$.fn.concreteData = $.fn.entwineData;
|
||||||
|
|
||||||
|
// Use addHandler to hack in the namespace.$.concrete equivilent to the namespace.$.entwine namespace-injection
|
||||||
|
$.entwine.Namespace.addHandler({
|
||||||
|
order: 100,
|
||||||
|
bind: function(selector, k, v) { return false; },
|
||||||
|
|
||||||
|
namespaceMethodOverrides: function(namespace){
|
||||||
|
namespace.$.concrete = namespace.$.entwine;
|
||||||
|
namespace.injectee.concrete = namespace.injectee.entwine;
|
||||||
|
namespace.injectee.concreteData = namespace.injectee.entwineData;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
85
thirdparty/jquery-entwine/src/jquery.entwine.properties.js
vendored
Executable file
85
thirdparty/jquery-entwine/src/jquery.entwine.properties.js
vendored
Executable file
@ -0,0 +1,85 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
var entwine_prepend = '__entwine!';
|
||||||
|
|
||||||
|
var getEntwineData = function(el, namespace, property) {
|
||||||
|
return el.data(entwine_prepend + namespace + '!' + property);
|
||||||
|
};
|
||||||
|
|
||||||
|
var setEntwineData = function(el, namespace, property, value) {
|
||||||
|
return el.data(entwine_prepend + namespace + '!' + property, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
var getEntwineDataAsHash = function(el, namespace) {
|
||||||
|
var hash = {};
|
||||||
|
var id = jQuery.data(el[0]);
|
||||||
|
|
||||||
|
var matchstr = entwine_prepend + namespace + '!';
|
||||||
|
var matchlen = matchstr.length;
|
||||||
|
|
||||||
|
var cache = jQuery.cache[id];
|
||||||
|
for (var k in cache) {
|
||||||
|
if (k.substr(0,matchlen) == matchstr) hash[k.substr(matchlen)] = cache[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
var setEntwineDataFromHash = function(el, namespace, hash) {
|
||||||
|
for (var k in hash) setEntwineData(namespace, k, hash[k]);
|
||||||
|
};
|
||||||
|
|
||||||
|
var entwineData = function(el, namespace, args) {
|
||||||
|
switch (args.length) {
|
||||||
|
case 0:
|
||||||
|
return getEntwineDataAsHash(el, namespace);
|
||||||
|
case 1:
|
||||||
|
if (typeof args[0] == 'string') return getEntwineData(el, namespace, args[0]);
|
||||||
|
else return setEntwineDataFromHash(el, namespace, args[0]);
|
||||||
|
default:
|
||||||
|
return setEntwineData(el, namespace, args[0], args[1]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.extend($.fn, {
|
||||||
|
entwineData: function() {
|
||||||
|
return entwineData(this, '__base', arguments);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.entwine.Namespace.addHandler({
|
||||||
|
order: 60,
|
||||||
|
|
||||||
|
bind: function(selector, k, v) {
|
||||||
|
if (k.charAt(0) != k.charAt(0).toUpperCase()) $.entwine.warn('Entwine property '+k+' does not start with a capital letter', $.entwine.WARN_LEVEL_BESTPRACTISE);
|
||||||
|
|
||||||
|
// Create the getters and setters
|
||||||
|
|
||||||
|
var getterName = 'get'+k;
|
||||||
|
var setterName = 'set'+k;
|
||||||
|
|
||||||
|
this.bind_proxy(selector, getterName, function() { var r = this.entwineData(k); return r === undefined ? v : r; });
|
||||||
|
this.bind_proxy(selector, setterName, function(v){ return this.entwineData(k, v); });
|
||||||
|
|
||||||
|
// Get the get and set proxies we just created
|
||||||
|
|
||||||
|
var getter = this.injectee[getterName];
|
||||||
|
var setter = this.injectee[setterName];
|
||||||
|
|
||||||
|
// And bind in the jQuery-style accessor
|
||||||
|
|
||||||
|
this.bind_proxy(selector, k, function(v){ return (arguments.length == 1 ? setter : getter).call(this, v) ; });
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
namespaceMethodOverrides: function(namespace){
|
||||||
|
return {
|
||||||
|
entwineData: function() {
|
||||||
|
return entwineData(this, namespace.name, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
52
thirdparty/jquery-entwine/src/jquery.focusinout.js
vendored
Executable file
52
thirdparty/jquery-entwine/src/jquery.focusinout.js
vendored
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
(function($){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live)
|
||||||
|
* Copyright (c) 2007 Jörn Zaefferer
|
||||||
|
*/
|
||||||
|
if ($.support.focusinBubbles === undefined) {
|
||||||
|
$.support.focusinBubbles = !!($.browser.msie);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$.support.focusinBubbles && !$.event.special.focusin) {
|
||||||
|
// Emulate focusin and focusout by binding focus and blur in capturing mode
|
||||||
|
$.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){
|
||||||
|
$.event.special[fix] = {
|
||||||
|
setup: function(){
|
||||||
|
if (!this.addEventListener) return false;
|
||||||
|
this.addEventListener(original, $.event.special[fix].handler, true);
|
||||||
|
},
|
||||||
|
teardown: function(){
|
||||||
|
if (!this.removeEventListener) return false;
|
||||||
|
this.removeEventListener(original, $.event.special[fix].handler, true);
|
||||||
|
},
|
||||||
|
handler: function(e){
|
||||||
|
arguments[0] = $.event.fix(e);
|
||||||
|
arguments[0].type = fix;
|
||||||
|
return $.event.handle.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
//IE has some trouble with focusout with select and keyboard navigation
|
||||||
|
var activeFocus = null;
|
||||||
|
|
||||||
|
$(document)
|
||||||
|
.bind('focusin', function(e){
|
||||||
|
var target = e.realTarget || e.target;
|
||||||
|
if (activeFocus && activeFocus !== target) {
|
||||||
|
e.type = 'focusout';
|
||||||
|
$(activeFocus).trigger(e);
|
||||||
|
e.type = 'focusin';
|
||||||
|
e.target = target;
|
||||||
|
}
|
||||||
|
activeFocus = target;
|
||||||
|
})
|
||||||
|
.bind('focusout', function(e){
|
||||||
|
activeFocus = null;
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
})(jQuery);
|
58
thirdparty/jquery-entwine/src/jquery.selector.affectedby.js
vendored
Executable file
58
thirdparty/jquery-entwine/src/jquery.selector.affectedby.js
vendored
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Make attributes & IDs work
|
||||||
|
|
||||||
|
var DIRECT = /DIRECT/g;
|
||||||
|
var CONTEXT = /CONTEXT/g;
|
||||||
|
var EITHER = /DIRECT|CONTEXT/g;
|
||||||
|
|
||||||
|
$.selector.SelectorBase.addMethod('affectedBy', function(props) {
|
||||||
|
this.affectedBy = new Function('props', ([
|
||||||
|
'var direct_classes, context_classes, direct_attrs, context_attrs, t;',
|
||||||
|
this.ABC_compile().replace(DIRECT, 'direct').replace(CONTEXT, 'context'),
|
||||||
|
'return {classes: {context: context_classes, direct: direct_classes}, attrs: {context: context_attrs, direct: direct_attrs}};'
|
||||||
|
]).join("\n"));
|
||||||
|
|
||||||
|
// DEBUG: Print out the compiled funciton
|
||||||
|
// console.log(this.selector, ''+this.affectedBy);
|
||||||
|
|
||||||
|
return this.affectedBy(props);
|
||||||
|
});
|
||||||
|
|
||||||
|
$.selector.SimpleSelector.addMethod('ABC_compile', function() {
|
||||||
|
var parts = [];
|
||||||
|
|
||||||
|
$.each(this.classes, function(i, cls){
|
||||||
|
parts[parts.length] = "if (t = props.classes['"+cls+"']) (DIRECT_classes || (DIRECT_classes = {}))['"+cls+"'] = t;";
|
||||||
|
});
|
||||||
|
|
||||||
|
$.each(this.nots, function(i, not){
|
||||||
|
parts[parts.length] = not.ABC_compile();
|
||||||
|
});
|
||||||
|
|
||||||
|
return parts.join("\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
$.selector.Selector.addMethod('ABC_compile', function(arg){
|
||||||
|
var parts = [];
|
||||||
|
var i = this.parts.length-1;
|
||||||
|
|
||||||
|
parts[parts.length] = this.parts[i].ABC_compile();
|
||||||
|
while ((i = i - 2) >= 0) parts[parts.length] = this.parts[i].ABC_compile().replace(EITHER, 'CONTEXT');
|
||||||
|
|
||||||
|
return parts.join("\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
$.selector.SelectorsGroup.addMethod('ABC_compile', function(){
|
||||||
|
var parts = [];
|
||||||
|
|
||||||
|
$.each(this.parts, function(i,part){
|
||||||
|
parts[parts.length] = part.ABC_compile();
|
||||||
|
});
|
||||||
|
|
||||||
|
return parts.join("\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})(jQuery);
|
Loading…
Reference in New Issue
Block a user