Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
101 lines
No EOL
3 KiB
JavaScript
101 lines
No EOL
3 KiB
JavaScript
;
|
|
(function () {
|
|
'use strict';
|
|
var ns = '_attach';
|
|
var proto = Element.prototype;
|
|
var matches = proto.matchesSelector || proto.webkitMatchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector;
|
|
function attach(root, type, selector, fn, ctx) {
|
|
if (arguments.length === 2) {
|
|
return attach.many.apply(null, arguments);
|
|
}
|
|
if (typeof selector === 'function') {
|
|
ctx = fn;
|
|
fn = selector;
|
|
selector = null;
|
|
}
|
|
selector = selector || 'null';
|
|
var store = getStore(root);
|
|
var master = store.master[type];
|
|
var delegates = store.delegates[type] = store.delegates[type] || {};
|
|
delegates[selector] = fn;
|
|
if (master) {
|
|
return;
|
|
}
|
|
master = store.master[type] = callback;
|
|
root.addEventListener(type, master);
|
|
function callback(e) {
|
|
var el = e.target;
|
|
var selector;
|
|
var matched;
|
|
var out;
|
|
var fn;
|
|
while (el) {
|
|
for (selector in delegates) {
|
|
fn = delegates[selector];
|
|
matched = el === root && selector === 'null' || matches.call(el, selector);
|
|
if (matched) {
|
|
out = fn.call(ctx || el, e, el);
|
|
if (out === false) {
|
|
return e.stopPropagation();
|
|
}
|
|
}
|
|
}
|
|
if (el == root)
|
|
break;
|
|
el = el.parentNode;
|
|
}
|
|
}
|
|
}
|
|
attach.on = attach;
|
|
attach.off = function (root, type, selector) {
|
|
var store = getStore(root);
|
|
var master = store.master[type];
|
|
var delegates = store.delegates[type];
|
|
if (type && selector) {
|
|
delete delegates[selector];
|
|
} else if (type) {
|
|
delete store.delegates[type];
|
|
} else {
|
|
for (type in store.master) {
|
|
attach.off(root, type);
|
|
}
|
|
}
|
|
if (isEmpty(store.delegates[type])) {
|
|
root.removeEventListener(type, master);
|
|
delete store.master[type];
|
|
}
|
|
};
|
|
attach.many = function (root, config, ctx) {
|
|
var parts;
|
|
var key;
|
|
for (key in config) {
|
|
parts = key.split(' ');
|
|
attach.on(root, parts[0], parts[1], config[key], ctx);
|
|
}
|
|
};
|
|
function getStore(el) {
|
|
return el[ns] || createStore(el);
|
|
}
|
|
function createStore(el) {
|
|
el[ns] = {
|
|
master: {},
|
|
delegates: {}
|
|
};
|
|
return el[ns];
|
|
}
|
|
function isEmpty(ob) {
|
|
for (var key in ob) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
if (typeof exports === 'object') {
|
|
module.exports = attach;
|
|
} else if (typeof define === 'function' && define.amd) {
|
|
define([], function () {
|
|
return attach;
|
|
});
|
|
} else {
|
|
window.attach = attach;
|
|
}
|
|
}()); |