UNPKG

drag

Version:

a very small drag library for javascript

757 lines (689 loc) 23 kB
/*! * 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); }();