drag
Version:
a very small drag library for javascript
757 lines (689 loc) • 23 kB
JavaScript
/*!
* Ender: open module JavaScript framework
* copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat)
* https://github.com/ender-js/ender
* License MIT
* Build: ender -j domready bean qwery
*/
!function (context) {
function aug(o, o2) {
for (var k in o2) {
k != 'noConflict' && (o[k] = o2[k]);
}
}
function _$(s, r) {
this.elements = typeof s !== 'string' && !s.nodeType && typeof s.length !== 'undefined' ? s : $._select(s, r);
this.length = this.elements.length;
for (var i = 0; i < this.length; i++) {
this[i] = this.elements[i];
}
}
function $(s, r) {
return new _$(s, r);
}
aug($, {
ender: function (o, proto) {
aug(proto ? _$.prototype : $, o);
},
_select: function () {
return [];
}
});
var old = context.$;
$.noConflict = function () {
context.$ = old;
return this;
};
(typeof module !== 'undefined') && module.exports ?
(module.exports = $) :
(context.$ = $);
}(this);
!function () { var module = { exports: {} }; !function (doc) {
var loaded = 0, fns = [], ol, f = false,
testEl = doc.createElement('a'),
domContentLoaded = 'DOMContentLoaded',
addEventListener = 'addEventListener',
onreadystatechange = 'onreadystatechange';
/^loade|c/.test(doc.readyState) && (loaded = 1);
function flush() {
loaded = 1;
for (var i = 0, l = fns.length; i < l; i++) {
fns[i]();
}
}
doc[addEventListener] && doc[addEventListener](domContentLoaded, function fn() {
doc.removeEventListener(domContentLoaded, fn, f);
flush();
}, f);
testEl.doScroll && doc.attachEvent(onreadystatechange, (ol = function ol() {
if (/^c/.test(doc.readyState)) {
doc.detachEvent(onreadystatechange, ol);
flush();
}
}));
var domReady = testEl.doScroll ?
function (fn) {
self != top ?
!loaded ?
fns.push(fn) :
fn() :
!function () {
try {
testEl.doScroll('left');
} catch (e) {
return setTimeout(function() {
domReady(fn);
}, 50);
}
fn();
}();
} :
function (fn) {
loaded ? fn() : fns.push(fn);
};
(typeof module !== 'undefined') && module.exports ?
(module.exports = {domReady: domReady}) :
(window.domReady = domReady);
}(document); $.ender(module.exports); }();
/*!
* bean.js - copyright @dedfat
* https://github.com/fat/bean
* Follow our software http://twitter.com/dedfat
* MIT License
* special thanks to:
* dean edwards: http://dean.edwards.name/
* dperini: https://github.com/dperini/nwevents
* the entire mootools team: github.com/mootools/mootools-core
*/
!function (context) {
var __uid = 1, registry = {}, collected = {},
overOut = /over|out/,
namespace = /[^\.]*(?=\..*)\.|.*/,
stripName = /\..*/,
addEvent = 'addEventListener',
attachEvent = 'attachEvent',
removeEvent = 'removeEventListener',
detachEvent = 'detachEvent',
doc = context.document || {},
root = doc.documentElement || {},
W3C_MODEL = root[addEvent],
eventSupport = W3C_MODEL ? addEvent : attachEvent,
isDescendant = function (parent, child) {
var node = child.parentNode;
while (node != null) {
if (node == parent) {
return true;
}
node = node.parentNode;
}
},
retrieveUid = function (obj, uid) {
return (obj.__uid = uid || obj.__uid || __uid++);
},
retrieveEvents = function (element) {
var uid = retrieveUid(element);
return (registry[uid] = registry[uid] || {});
},
listener = W3C_MODEL ? function (element, type, fn, add) {
element[add ? addEvent : removeEvent](type, fn, false);
} : function (element, type, fn, add, custom) {
custom && add && (element['_on' + custom] = element['_on' + custom] || 0);
element[add ? attachEvent : detachEvent]('on' + type, fn);
},
nativeHandler = function (element, fn, args) {
return function (event) {
event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || context).event);
return fn.apply(element, [event].concat(args));
};
},
customHandler = function (element, fn, type, condition, args) {
return function (event) {
if (condition ? condition.call(this, event) : event && event.propertyName == '_on' + type || !event) {
fn.apply(element, [event].concat(args));
}
};
},
addListener = function (element, orgType, fn, args) {
var type = orgType.replace(stripName, ''),
events = retrieveEvents(element),
handlers = events[type] || (events[type] = {}),
uid = retrieveUid(fn, orgType.replace(namespace, ''));
if (handlers[uid]) {
return element;
}
var custom = customEvents[type];
if (custom) {
fn = custom.condition ? customHandler(element, fn, type, custom.condition) : fn;
type = custom.base || type;
}
var isNative = W3C_MODEL || nativeEvents.indexOf(type) > -1;
fn = isNative ? nativeHandler(element, fn, args) : customHandler(element, fn, type, false, args);
if (type == 'unload') {
var org = fn;
fn = function () {
removeListener(element, type, fn) && org();
};
}
element[eventSupport] && listener(element, isNative ? type : 'propertychange', fn, true, !isNative && type);
handlers[uid] = fn;
fn.__uid = uid;
return type == 'unload' ? element : (collected[retrieveUid(element)] = element);
},
removeListener = function (element, orgType, handler) {
var uid, names, uids, i, events = retrieveEvents(element), type = orgType.replace(stripName, '');
if (!events || !events[type]) {
return element;
}
names = orgType.replace(namespace, '');
uids = names ? names.split('.') : [handler.__uid];
for (i = uids.length; i--;) {
uid = uids[i];
handler = events[type][uid];
delete events[type][uid];
if (element[eventSupport]) {
type = customEvents[type] ? customEvents[type].base : type;
var isNative = element[addEvent] || nativeEvents.indexOf(type) > -1;
listener(element, isNative ? type : 'propertychange', handler, false, !isNative && type);
}
}
return element;
},
del = function (selector, fn, $) {
return function (e) {
var array = typeof selector == 'string' ? $(selector, this) : selector;
for (var target = e.target; target && target != this; target = target.parentNode) {
for (var i = array.length; i--;) {
if (array[i] == target) {
return fn.apply(target, arguments);
}
}
}
};
},
add = function (element, events, fn, delfn, $) {
if (typeof events == 'object' && !fn) {
for (var type in events) {
events.hasOwnProperty(type) && add(element, type, events[type]);
}
} else {
var isDel = typeof fn == 'string', types = (isDel ? fn : events).split(' ');
fn = isDel ? del(events, delfn, $) : fn;
for (var i = types.length; i--;) {
addListener(element, types[i], fn, Array.prototype.slice.call(arguments, isDel ? 4 : 3));
}
}
return element;
},
remove = function (element, orgEvents, fn) {
var k, type, events,
isString = typeof(orgEvents) == 'string',
names = isString && orgEvents.replace(namespace, ''),
rm = removeListener,
attached = retrieveEvents(element);
if (isString && /\s/.test(orgEvents)) {
orgEvents = orgEvents.split(' ');
var i = orgEvents.length - 1;
while (remove(element, orgEvents[i]) && i--) {}
return element;
}
events = isString ? orgEvents.replace(stripName, '') : orgEvents;
if (!attached || (isString && !attached[events])) {
return element;
}
if (typeof fn == 'function') {
rm(element, events, fn);
} else if (names) {
rm(element, orgEvents);
} else {
rm = events ? rm : remove;
type = isString && events;
events = events ? (fn || attached[events] || events) : attached;
for (k in events) {
events.hasOwnProperty(k) && rm(element, type || k, events[k]);
}
}
return element;
},
fire = function (element, type) {
var evt, k, i, types = type.split(' ');
for (i = types.length; i--;) {
type = types[i].replace(stripName, '');
var isNative = nativeEvents.indexOf(type) > -1,
isNamespace = types[i].replace(namespace, ''),
handlers = retrieveEvents(element)[type];
if (isNamespace) {
isNamespace = isNamespace.split('.');
for (k = isNamespace.length; k--;) {
handlers[isNamespace[k]] && handlers[isNamespace[k]]();
}
} else if (element[eventSupport]) {
fireListener(isNative, type, element);
} else {
for (k in handlers) {
handlers.hasOwnProperty(k) && handlers[k]();
}
}
}
return element;
},
fireListener = W3C_MODEL ? function (isNative, type, element) {
evt = document.createEvent(isNative ? "HTMLEvents" : "UIEvents");
evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, context, 1);
element.dispatchEvent(evt);
} : function (isNative, type, element) {
isNative ? element.fireEvent('on' + type, document.createEventObject()) : element['_on' + type]++;
},
clone = function (element, from, type) {
var events = retrieveEvents(from), obj, k;
obj = type ? events[type] : events;
for (k in obj) {
obj.hasOwnProperty(k) && (type ? add : clone)(element, type || from, type ? obj[k] : k);
}
return element;
},
fixEvent = function (e) {
var result = {};
if (!e) {
return result;
}
var type = e.type, target = e.target || e.srcElement;
result.preventDefault = fixEvent.preventDefault(e);
result.stopPropagation = fixEvent.stopPropagation(e);
result.target = target && target.nodeType == 3 ? target.parentNode : target;
if (type.indexOf('key') != -1) {
result.keyCode = e.which || e.keyCode;
} else if ((/click|mouse|menu/i).test(type)) {
result.rightClick = e.which == 3 || e.button == 2;
result.pos = { x: 0, y: 0 };
if (e.pageX || e.pageY) {
result.clientX = e.pageX;
result.clientY = e.pageY;
} else if (e.clientX || e.clientY) {
result.clientX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
result.clientY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
overOut.test(type) && (result.relatedTarget = e.relatedTarget || e[(type == 'mouseover' ? 'from' : 'to') + 'Element']);
}
for (var k in e) {
if (!(k in result)) {
result[k] = e[k];
}
}
return result;
};
fixEvent.preventDefault = function (e) {
return function () {
if (e.preventDefault) {
e.preventDefault();
}
else {
e.returnValue = false;
}
};
};
fixEvent.stopPropagation = function (e) {
return function () {
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
};
};
var nativeEvents = 'click,dblclick,mouseup,mousedown,contextmenu,' + //mouse buttons
'mousewheel,DOMMouseScroll,' + //mouse wheel
'mouseover,mouseout,mousemove,selectstart,selectend,' + //mouse movement
'keydown,keypress,keyup,' + //keyboard
'orientationchange,' + // mobile
'touchstart,touchmove,touchend,touchcancel,' + // touch
'gesturestart,gesturechange,gestureend,' + // gesture
'focus,blur,change,reset,select,submit,' + //form elements
'load,unload,beforeunload,resize,move,DOMContentLoaded,readystatechange,' + //window
'error,abort,scroll'.split(','); //misc
function check(event) {
var related = event.relatedTarget;
if (!related) {
return related == null;
}
return (related != this && related.prefix != 'xul' && !/document/.test(this.toString()) && !isDescendant(this, related));
}
var customEvents = {
mouseenter: { base: 'mouseover', condition: check },
mouseleave: { base: 'mouseout', condition: check },
mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' }
};
var bean = { add: add, remove: remove, clone: clone, fire: fire };
var clean = function (el) {
var uid = remove(el).__uid;
if (uid) {
delete collected[uid];
delete registry[uid];
}
};
if (context[attachEvent]) {
add(context, 'unload', function () {
for (var k in collected) {
collected.hasOwnProperty(k) && clean(collected[k]);
}
context.CollectGarbage && CollectGarbage();
});
}
var oldBean = context.bean;
bean.noConflict = function () {
context.bean = oldBean;
return this;
};
(typeof module !== 'undefined' && module.exports) ?
(module.exports = bean) :
(context.bean = bean);
}(this);!function () {
var b = bean.noConflict(),
integrate = function (method, type, method2) {
var _args = type ? [type] : [];
return function () {
for (var args, i = 0, l = this.elements.length; i < l; i++) {
args = [this.elements[i]].concat(_args, Array.prototype.slice.call(arguments, 0));
args.length == 4 && args.push($);
!arguments.length && method == 'add' && type && (method = 'fire');
b[method].apply(this, args);
}
return this;
};
};
var add = integrate('add'),
remove = integrate('remove'),
fire = integrate('fire');
var methods = {
on: add,
addListener: add,
bind: add,
listen: add,
delegate: add,
unbind: remove,
unlisten: remove,
removeListener: remove,
undelegate: remove,
emit: fire,
trigger: fire,
cloneEvents: integrate('clone'),
hover: function (enter, leave) {
for (var i = 0, l = this.elements.length; i < l; i++) {
b.add.call(this, this.elements[i], 'mouseenter', enter);
b.add.call(this, this.elements[i], 'mouseleave', leave);
}
return this;
}
};
var shortcuts = [
'blur', 'change', 'click', 'dbltclick', 'error', 'focus', 'focusin',
'focusout', 'keydown', 'keypress', 'keyup', 'load', 'mousedown',
'mouseenter', 'mouseleave', 'mouseout', 'mouseover', 'mouseup',
'resize', 'scroll', 'select', 'submit', 'unload'
];
for (var i = shortcuts.length; i--;) {
var shortcut = shortcuts[i];
methods[shortcut] = integrate('add', shortcut);
}
$.ender(methods, true);
}();
/*!
* qwery.js - copyright @dedfat
* https://github.com/ded/qwery
* Follow our software http://twitter.com/dedfat
* MIT License
*/
!function (context, doc) {
var c, i, j, k, l, m, o, p, r, v,
el, node, len, found, classes, item, items, token, collection,
id = /#([\w\-]+)/,
clas = /\.[\w\-]+/g,
idOnly = /^#([\w\-]+$)/,
classOnly = /^\.([\w\-]+)$/,
tagOnly = /^([\w\-]+)$/,
tagAndOrClass = /^([\w]+)?\.([\w\-]+)$/,
html = doc.documentElement,
tokenizr = /\s(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\])/,
simple = /^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,
attr = /\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,
chunker = new RegExp(simple.source + '(' + attr.source + ')?');
function array(ar) {
r = [];
for (i = 0, len = ar.length; i < len; i++) {
r[i] = ar[i];
}
return r;
}
var cache = function () {
this.c = {};
};
cache.prototype = {
g: function (k) {
return this.c[k] || undefined;
},
s: function (k, v) {
this.c[k] = v;
return v;
}
};
var classCache = new cache(),
cleanCache = new cache(),
attrCache = new cache(),
tokenCache = new cache();
function q(query) {
return query.match(chunker);
}
function interpret(whole, tag, idsAndClasses, wholeAttribute, attribute, qualifier, value) {
var m, c, k;
if (tag && this.tagName.toLowerCase() !== tag) {
return false;
}
if (idsAndClasses && (m = idsAndClasses.match(id)) && m[1] !== this.id) {
return false;
}
if (idsAndClasses && (classes = idsAndClasses.match(clas))) {
for (i = classes.length; i--;) {
c = classes[i].slice(1);
if (!(classCache.g(c) || classCache.s(c, new RegExp('(^|\\s+)' + c + '(\\s+|$)'))).test(this.className)) {
return false;
}
}
}
if (wholeAttribute && !value) {
o = this.attributes;
for (k in o) {
if (Object.prototype.hasOwnProperty.call(o, k) && (o[k].name || k) == attribute) {
return this;
}
}
}
if (wholeAttribute && !checkAttr(qualifier, this.getAttribute(attribute) || '', value)) {
return false;
}
return this;
}
function loopAll(tokens) {
var r = [], token = tokens.pop(), intr = q(token), tag = intr[1] || '*', i, l, els,
root = tokens.length && (m = tokens[0].match(idOnly)) ? doc.getElementById(m[1]) : doc;
if (!root) {
return r;
}
els = root.getElementsByTagName(tag);
for (i = 0, l = els.length; i < l; i++) {
el = els[i];
if (item = interpret.apply(el, intr)) {
r.push(item);
}
}
return r;
}
function clean(s) {
return cleanCache.g(s) || cleanCache.s(s, s.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1'));
}
function checkAttr(qualify, actual, val) {
switch (qualify) {
case '=':
return actual == val;
case '^=':
return actual.match(attrCache.g('^=' + val) || attrCache.s('^=' + val, new RegExp('^' + clean(val))));
case '$=':
return actual.match(attrCache.g('$=' + val) || attrCache.s('$=' + val, new RegExp(clean(val) + '$')));
case '*=':
return actual.match(attrCache.g(val) || attrCache.s(val, new RegExp(clean(val))));
case '~=':
return actual.match(attrCache.g('~=' + val) || attrCache.s('~=' + val, new RegExp('(?:^|\\s+)' + clean(val) + '(?:\\s+|$)')));
case '|=':
return actual.match(attrCache.g('|=' + val) || attrCache.s('|=' + val, new RegExp('^' + clean(val) + '(-|$)')));
}
return false;
}
function _qwery(selector) {
var r = [], ret = [], i, l,
tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr));
tokens = tokens.slice(0);
if (!tokens.length) {
return r;
}
r = loopAll(tokens);
if (!tokens.length) {
return r;
}
// loop through all descendent tokens
for (j = 0, l = r.length, k = 0; j < l; j++) {
node = r[j];
p = node;
// loop through each token
for (i = tokens.length; i--;) {
z: // loop through parent nodes
while (p !== html && (p = p.parentNode)) {
if (found = interpret.apply(p, q(tokens[i]))) {
break z;
}
}
}
found && (ret[k++] = node);
}
return ret;
}
var isAncestor = 'compareDocumentPosition' in html ?
function (element, container) {
return (container.compareDocumentPosition(element) & 16) == 16;
} : 'contains' in html ?
function (element, container) {
return container !== element && container.contains(element);
} :
function (element, container) {
while (element = element.parentNode) {
if (element === container) {
return 1;
}
}
return 0;
};
function boilerPlate(selector, _root, fn) {
var root = (typeof _root == 'string') ? fn(_root)[0] : (_root || doc);
if (isNode(selector)) {
return !_root || (isNode(root) && isAncestor(selector, root)) ? [selector] : [];
}
if (selector && typeof selector === 'object' && selector.length && isFinite(selector.length)) {
return array(selector);
}
if (m = selector.match(idOnly)) {
return (el = doc.getElementById(m[1])) ? [el] : [];
}
if (m = selector.match(tagOnly)) {
return array(root.getElementsByTagName(m[1]));
}
return false;
}
function isNode(el) {
return (el === window || el && el.nodeType && el.nodeType.toString().match(/[19]/));
}
function qsa(selector, _root) {
var root = (typeof _root == 'string') ? qsa(_root)[0] : (_root || doc);
if (!root) {
return [];
}
if (m = boilerPlate(selector, _root, qsa)) {
return m;
}
if (doc.getElementsByClassName && (m = selector.match(classOnly))) {
return array((root).getElementsByClassName(m[1]));
}
return array((root).querySelectorAll(selector));
}
function uniq(ar) {
var a = [], i, j;
label:
for (i = 0; i < ar.length; i++) {
for (j = 0; j < a.length; j++) {
if (a[j] == ar[i]) {
continue label;
}
}
a[a.length] = ar[i];
}
return a;
}
var qwery = function () {
// return fast. boosh.
if (doc.querySelector && doc.querySelectorAll) {
return qsa;
}
return function (selector, _root) {
var root = (typeof _root == 'string') ? qwery(_root)[0] : (_root || doc);
if (!root) {
return [];
}
var i, l, result = [], collections = [], element;
if (m = boilerPlate(selector, _root, qwery)) {
return m;
}
if (m = selector.match(tagAndOrClass)) {
items = root.getElementsByTagName(m[1] || '*');
r = classCache.g(m[2]) || classCache.s(m[2], new RegExp('(^|\\s+)' + m[2] + '(\\s+|$)'));
for (i = 0, l = items.length, j = 0; i < l; i++) {
r.test(items[i].className) && (result[j++] = items[i]);
}
return result;
}
for (i = 0, items = selector.split(','), l = items.length; i < l; i++) {
collections[i] = _qwery(items[i]);
}
for (i = 0, l = collections.length; i < l && (collection = collections[i]); i++) {
var ret = collection;
if (root !== doc) {
ret = [];
for (j = 0, m = collection.length; j < m && (element = collection[j]); j++) {
// make sure element is a descendent of root
isAncestor(element, root) && ret.push(element);
}
}
result = result.concat(ret);
}
return uniq(result);
};
}();
qwery.uniq = uniq;
var oldQwery = context.qwery;
qwery.noConflict = function () {
context.qwery = oldQwery;
return this;
};
context.qwery = qwery;
}(this, document);
!function () {
var q = qwery.noConflict();
$._select = q;
$.ender({
find: function (s) {
var r = [], i, l, j, k, els;
for (i = 0, l = this.length; i < l; i++) {
els = q(s, this[i]);
for (j = 0, k = els.length; j < k; j++) {
r.push(els[j]);
}
}
return $(q.uniq(r));
}
}, true);
}();