UNPKG

libdom

Version:

Lean Browser Library for typical DOM operations

2,041 lines (1,602 loc) 114 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('libcore')) : typeof define === 'function' && define.amd ? define(['exports', 'libcore'], factory) : (factory((global.libdom = {}),global.libcore)); }(this, (function (exports,libcore) { 'use strict'; var global$1 = typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; var ROOT = global$1; var browser = libcore.env.browser; var ieVersion = 0; var exported$2 = false; var match; var ieVersion; if (browser) { match = libcore.env.userAgent.match(/msie ([0-9]+\.[0-9]+)/i); exported$2 = { strict: ROOT.document.compatMode === 'CSS1Compat', ieVersion: match && parseInt(match[1], 10) || 0, ie8: ieVersion === 8 }; } ROOT = null; var browser$1 = exported$2; var WINDOW = global$1; var exported$3 = false; if (browser$1) { exported$3 = { w3c: !!WINDOW.addEventListener, ie: !!WINDOW.attachEvent, customEvent: !!WINDOW.CustomEvent }; } WINDOW = null; var domEvent = exported$3; var WINDOW$1 = global$1; var exported$4 = false; var DOCUMENT; var ROOT$1; if (browser$1) { DOCUMENT = WINDOW$1.document; ROOT$1 = DOCUMENT.documentElement; exported$4 = { compare: !!ROOT$1.compareDocumentPosition, contains: !!ROOT$1.contains, defaultView: DOCUMENT.defaultView ? 'defaultView' : DOCUMENT.parentWindow ? 'parentWindow' : null, querySelectorAll: !!DOCUMENT.querySelectorAll, listToArray: ROOT$1.childNodes instanceof Object }; } DOCUMENT = ROOT$1 = null; var dom = exported$4; var WINDOW$2 = global$1; var exported$5 = false; var DOC; var DIV; var STYLE; var name; var color; function detectAlphaColor(style) { var rgba = 'rgba(0,0,0,0.5)'; try { style.color = rgba; color = style.color; if (libcore.string(color)) { color = color.replace(/[ \r\n\t\s]+/g, '').toLowerCase(); } if (rgba === color) { return true; } } catch (e) {} return false; } function detectTransition(style) { var supports = ['OTransition', 'webkitTransition', 'MozTransition', 'transition'], l = supports.length; for (l = supports.length; l--;) { name = supports[l]; if (typeof style[name] !== 'undefined') { return name; } } return false; } if (browser$1) { DOC = WINDOW$2.document; DIV = DOC.createElement('div'); STYLE = DIV.style; exported$5 = { w3cStyle: !!WINDOW$2.getComputedStyle, ieStyle: !!DOC.documentElement.currentStyle, setattribute: !!STYLE.setAttribute, setproperty: !!STYLE.setProperty, opacity: typeof STYLE.opacity !== 'undefined', filterOpacity: typeof STYLE.filter !== 'undefined', alphaColor: detectAlphaColor(STYLE), transition: detectTransition(STYLE) }; } WINDOW$2 = DOC = DIV = STYLE = null; var css = exported$5; var WINDOW$3 = global$1; var exported$6 = false; var ieVersion$1; if (browser$1) { ieVersion$1 = browser$1.ieVersion; exported$6 = { screensize: typeof WINDOW$3.innerWidth !== 'undefined', pagescroll: typeof WINDOW$3.pageXOffset !== 'undefined', rectmethod: !!WINDOW$3.document.documentElement.getBoundingClientRect, zoomfactor: ieVersion$1 > 0 && ieVersion$1 < 8, ie8: ieVersion$1 === 8 }; } WINDOW$3 = null; var dimension = exported$6; var exported$7 = false; var DOCUMENT$1; var ROOTSTYLE; var UNDEFINED; if (browser$1) { DOCUMENT$1 = global$1.document; ROOTSTYLE = DOCUMENT$1.documentElement.style; UNDEFINED = 'undefined'; exported$7 = { range: !!DOCUMENT$1.createRange, textrange: !!DOCUMENT$1.createElement('input').createTextRange, cssUnselectable: typeof ROOTSTYLE.MozUserSelect !== UNDEFINED ? 'MozUserSelect' : typeof ROOTSTYLE.webkitUserSelect !== UNDEFINED ? 'webkitUserSelect' : false }; } DOCUMENT$1 = ROOTSTYLE = null; var selection = exported$7; var exported$1 = false; if (browser$1) { exported$1 = { browser: browser$1, event: domEvent, dom: dom, css: css, dimension: dimension, selection: selection }; } var DETECTED = exported$1; var SEPARATE_RE = /[ \r\n\t]*[ \r\n\t]+[ \r\n\t]*/; var STYLIZE_RE = /^([Mm]oz|[Ww]ebkit|[Mm]s|[oO])[A-Z]/; var HTML_ESCAPE_CHARS_RE = /[^\u0021-\u007e]|[\u003e\u003c\&\"\']/g; var TEXTAREA = null; function htmlescapeCallback(chr) { var code = chr.charCodeAt(0).toString(16); var value; switch (code) { case '26': value = 'amp'; break; case '22': value = 'quot'; break; case '27': value = 'apos'; break; case '3C': case '3c': value = 'lt'; break; case '3E': case '3e': value = 'gt'; break; default: value = '#x' + code; } return '&' + value + ';'; } function initialize() { if (DETECTED) { TEXTAREA = global$1.document.createElement('textarea'); // register destructor libcore.register("libdom.event.global-destroy", onDestroy); } } function onDestroy() { TEXTAREA = null; } initialize(); var ERROR = { 1001: "Invalid String [name] parameter.", 1002: "Invalid Boolean [destroy] parameter.", 1011: "Invalid Function [handler] parameter.", 1021: "Invalid String [subject] parameter.", 1101: "Invalid DOM [element] parameter.", 1102: "Invalid [dom] Object parameter.", 1103: "Invalid DOM [node] parameter.", 1104: "Invalid DOM [document] parameter.", 1105: "Invalid DOM [nodes] parameter.", 1106: "Invalid DOM [from] parameter.", 1107: "Invalid DOM [to] parameter.", 1108: "Invalid DOM [before] parameter.", 1111: "Invalid CSS [selector] parameter.", 1112: "Invalid tree traverse [callback] parameter.", 1113: "Invalid [classNames] parameter.", 1121: "Invalid DOM Element [config] parameter.", 1131: "Invalid [observable] parameter.", 1132: "Invalid Event [type] parameter.", 1133: "Invalid Event [handler] parameter.", 1134: "Invalid Event [properties] parameter.", 1141: "Invalid Style [rule] parameter.", //1142: "Invalid Colorset [type] parameter.", //1143: "Invalid [colorValue] integer parameter.", 1151: "Invalid Animation [callback] parameter.", 1152: "Invalid Animation [displacements] parameter.", 1153: "Invalid Animation [type] parameter.", 1154: "Invalid Animation [duration] parameter.", 1210: "Invalid Dimension [x] parameter.", 1211: "Invalid Dimension [y] parameter.", 1212: "Invalid Dimension [right] parameter.", 1213: "Invalid Dimension [bottom] parameter.", 1214: "Invalid Dimension [width] parameter.", 1215: "Invalid Dimension [height] parameter.", 1216: "Invalid Dimension parameters.", 2001: "Style Attribute manipulation is not supported", 2002: "Computed style is not supported by this browser.", 2003: "CSS Selector query form DOM is not supported.", 2004: "DOM position comparison is not supported.", 2005: "DOM selection not supported.", 2006: "CSS Opacity is not supported by this browser" }; function stylize(subject) { if (!libcore.string(subject)) { throw new Error(ERROR[1021]); } subject = libcore.camelize(subject); return STYLIZE_RE.test(subject) ? subject.charAt(0).toUpperCase() + subject.substring(1, subject.length) : subject; } function addWord(subject, items) { var isString = libcore.string, trimString = libcore.trim; var c, l, item, cl, combined; if (!isString(subject, true)) { throw new Error(ERROR[1021]); } cl = 0; combined = []; subject = trimString(subject); for (c = -1, l = items.length; l--;) { item = items[++c]; if (!isString(item)) { continue; } item = trimString(item); if (item) { combined[cl++] = item; } } return subject ? libcore.unionList(subject.split(SEPARATE_RE), combined).join(' ') : cl ? combined.join(' ') : ''; } function removeWord(subject, items) { var isString = libcore.string, trimString = libcore.trim; var c, l, item, index; if (!isString(subject, true)) { throw new Error(ERROR[1021]); } subject = trimString(subject); if (!subject) { return ''; } subject = libcore.unionList(subject.split(SEPARATE_RE), []); for (c = -1, l = items.length; l--;) { if (!isString(item = items[++c])) { continue; } index = subject.indexOf(trimString(item)); if (index !== -1) { subject.splice(index, 1); } } return subject.join(' '); } function xmlDecode(subject) { var textarea = TEXTAREA; var value = ''; if (!libcore.string(subject)) { throw new Error(ERROR[1021]); } if (textarea) { textarea.innerHTML = subject; value = textarea.value; } textarea = null; return value; } function xmlEncode(subject) { if (!libcore.string(subject)) { throw new Error(ERROR[1021]); } return subject.replace(HTML_ESCAPE_CHARS_RE, htmlescapeCallback); } var MODULE = null; function use(chain) { MODULE = chain; return get(); } function get() { return MODULE; } var EVENTS = null; var PAGE_UNLOADED = false; var MIDDLEWARE = libcore.middleware('libdom.event'); var IE_CUSTOM_EVENTS = {}; var ERROR_OBSERVABLE_NO_SUPPORT = ERROR[1131]; var ERROR_INVALID_TYPE = ERROR[1132]; var ERROR_INVALID_HANDLER = ERROR[1133]; var IE_ON = 'on'; var IE_BUBBLE_EVENT = 'beforeupdate'; var IE_NO_BUBBLE_EVENT = 'propertychange'; var RESOLVE; var LISTEN; var UNLISTEN; var DISPATCH; var EVENT_INFO; var IS_CAPABLE; var SUBJECT; function createUnlistener(event) { var destroyed = false; function destroy() { var head, tail; if (!destroyed) { destroyed = true; UNLISTEN(event[0], event[1], event[4]); head = event.head; tail = event.tail; if (head) { head.tail = tail; } if (tail) { tail.head = head; } if (event === EVENTS) { EVENTS = tail || head; } event[0] = null; event.splice(0, 4); delete event.unlisten; delete event.head; delete event.tail; event = head = tail = null; } } return destroy; } function filter(argLen, observable, type, handler, context) { var last = EVENTS, found = [], len = 0, HAS_OBSERVABLE = 0, HAS_TYPE = 0, HAS_HANDLER = 0, HAS_CONTEXT = 0; switch (true) { case argLen > 3: HAS_CONTEXT = 1; /* fall through */ case argLen > 2: HAS_HANDLER = 1; /* fall through */ case argLen > 1: HAS_TYPE = 1; /* fall through */ case argLen > 0: HAS_OBSERVABLE = 1; } for (; last; last = last.head) { if ((HAS_OBSERVABLE && last[0] !== observable) || (HAS_TYPE && last[1] !== type) || (HAS_HANDLER && last[2] !== handler) || (HAS_CONTEXT && last[3] !== context)) { continue; } found[len++] = last; } return found; } /** * w3c events */ function w3cListen(observable, type, handler, context) { var listener = w3cCreateHandler(handler, context); observable.addEventListener(type, listener, false); return [observable, type, handler, context, listener]; } function w3cUnlisten(observable, type, listener) { observable.removeEventListener(type, listener, false); } function w3cDispatch(observable, type, properties) { var hasOwn = libcore.contains, event = global$1.document.createEvent("Event"); var name; event.initEvent(type, 'bubbles' in properties && properties.bubbles === true, 'cancelable' in properties && properties.cancelable !== false); for (name in properties) { if (hasOwn(properties, name) && !(name in event)) { event[name] = properties[name]; } } observable.dispatchEvent(event); return event; } function w3cObservable(observable) { var isFunction = libcore.method; return observable && typeof observable === 'object' && isFunction(observable.addEventListener) && isFunction(observable.removeEventListener) && isFunction(observable.dispatchEvent) ? observable : false; } function w3cCreateHandler(handler, context) { function onEvent(event) { MIDDLEWARE.run('dispatch', [event.type, event]); return handler.call(context, event); } return onEvent; } /** * ie events */ function ieListen(observable, type, handler, context) { var on = IE_ON; var listener; // listen to bubble if (ieTestCustomEvent(observable, type)) { listener = ieCreateCustomHandler(type, handler, context); observable.attachEvent(on + IE_BUBBLE_EVENT, listener); observable.attachEvent(on + IE_NO_BUBBLE_EVENT, listener); } else { listener = ieCreateHandler(handler, context); observable.attachEvent(on + type, listener); } return [observable, type, handler, context, listener]; } function ieUnlisten(observable, type, listener) { var on = IE_ON; if (listener.customType) { observable.detachEvent(on + IE_BUBBLE_EVENT, listener); observable.detachEvent(on + IE_NO_BUBBLE_EVENT, listener); } else { observable.detachEvent(on + type, listener); } } function ieDispatch(observable, type, properties) { var hasOwn = libcore.contains, event = global$1.document.createEventObject(); var name; for (name in properties) { if (hasOwn(properties, name) && !(name in event)) { event[name] = properties[name]; } } if (ieTestCustomEvent(observable, type)) { event.customType = type; type = properties.bubbles === true ? IE_BUBBLE_EVENT : IE_NO_BUBBLE_EVENT; } name = IE_ON + type; observable.fireEvent(name, event); // set to not cancel if not cancelable if (properties.cancelable === false) { event.returnValue = true; } return event; } function ieObservable(observable) { if (observable) { observable = observable.window ? observable.self : observable; if (observable.attachEvent && observable.detachEvent) { return observable; } } return false; } function ieCreateHandler(handler, context) { function onEvent() { var event = global$1.event; iePolyfillEvent(event); MIDDLEWARE.run('dispatch', [event.type, event]); return handler.call(context, event); } return onEvent; } function ieCreateCustomHandler(type, handler, context) { function onEvent() { var event = global$1.event; iePolyfillEvent(event); if (event.customType === type) { MIDDLEWARE.run('dispatch', [type, event]); event.type = type; return handler.call(context, event); } } onEvent.customType = true; return onEvent; } function iePreventDefault() { /* jshint validthis:true */ this.returnValue = false; } function ieStopPropagation() { /* jshint validthis:true */ this.cancelBubble = true; } function iePolyfillEvent(eventObject) { eventObject.target = eventObject.target || eventObject.srcElement; if (!('preventDefault' in eventObject)) { eventObject.preventDefault = iePreventDefault; } if (!('stopPropagation' in eventObject)) { eventObject.stopPropagation = ieStopPropagation; } } function ieTestCustomEvent(observable, type) { var supported = false, list = IE_CUSTOM_EVENTS; var element, access, ontype; if (observable.nodeType === 9) { observable = observable.documentElement; } if (observable.nodeType === 1) { // dont do another test access = observable.tagName + ':' + type; if (access in list) { return list[access]; } ontype = IE_ON + type; element = observable.cloneNode(false); supported = ontype in element; if (!supported) { element.setAttribute(ontype, 'return;'); supported = typeof element[ontype] === 'function'; } element = null; list[access] = !supported; return !supported; } return false; } /** * purge after page has unloaded */ function onBeforeUnload() { if (!PAGE_UNLOADED) { PAGE_UNLOADED = true; // call middleware MIDDLEWARE.run('global-destroy', []); purge(); } } RESOLVE = LISTEN = UNLISTEN = DISPATCH = null; /** * Initialize */ EVENT_INFO = DETECTED && DETECTED.event; if (EVENT_INFO) { IS_CAPABLE = true; switch (true) { case EVENT_INFO.w3c: LISTEN = w3cListen; UNLISTEN = w3cUnlisten; DISPATCH = w3cDispatch; RESOLVE = w3cObservable; break; case EVENT_INFO.ie: LISTEN = ieListen; UNLISTEN = ieUnlisten; DISPATCH = ieDispatch; RESOLVE = ieObservable; break; default: IS_CAPABLE = false; } // postprocess event handlers if platform is capable of L2 events if (IS_CAPABLE) { SUBJECT = global$1; // register destructors on(SUBJECT, 'beforeunload', onBeforeUnload); on(SUBJECT, 'unload', onBeforeUnload); SUBJECT = null; } } function on(observable, type, handler, context) { var last = EVENTS; var current, args; if (!libcore.string(type)) { throw new Error(ERROR_INVALID_TYPE); } if (!libcore.method(handler)) { throw new Error(ERROR_INVALID_HANDLER); } observable = RESOLVE(observable); if (!observable) { throw new Error(ERROR_OBSERVABLE_NO_SUPPORT); } if (typeof context === 'undefined') { context = null; } args = [observable, type, handler, context]; MIDDLEWARE.run('listen', args); observable = args[0]; type = args[1]; handler = args[2]; context = args[3]; args.splice(0, 4); args = null; current = LISTEN(observable, type, handler, context); current.unlisten = createUnlistener(current); current.head = last; current.tail = null; if (last) { last.tail = current; } EVENTS = current; return current.unlisten; } function un(observable, type, handler, context) { var found, len, args; if (!libcore.string(type)) { throw new Error(ERROR_INVALID_TYPE); } if (!libcore.method(handler)) { throw new Error(ERROR_INVALID_HANDLER); } observable = RESOLVE(observable); if (!observable) { throw new Error(ERROR_OBSERVABLE_NO_SUPPORT); } if (typeof context === 'undefined') { context = null; } args = [observable, type, handler, context]; MIDDLEWARE.run('unlisten', args); observable = args[0]; type = args[1]; handler = args[2]; context = args[3]; args.splice(0, 4); args = null; found = filter(4, observable, type, handler, context); for (len = found.length; len--;) { found[len].unlisten(); } return get(); } function dispatch(observable, type, properties) { if (!libcore.string(type)) { throw new Error(ERROR_INVALID_TYPE); } observable = RESOLVE(observable); if (!observable) { throw new Error(ERROR_OBSERVABLE_NO_SUPPORT); } if (arguments.length > 2 && !libcore.object(properties)) { throw new Error(ERROR[1134]); } return DISPATCH(observable, type, properties || {}); } function purge(observable, type, handler, context) { var alen = arguments.length; var found, len; switch (true) { case alen > 2: if (!libcore.method(handler)) { throw new Error(ERROR_INVALID_HANDLER); } /* falls through */ case alen > 1: if (!libcore.string(type)) { throw new Error(ERROR_INVALID_TYPE); } /* falls through */ case alen > 0: if (!RESOLVE(observable)) { throw new Error(ERROR_OBSERVABLE_NO_SUPPORT); } } if (typeof context === 'undefined') { context = null; } found = filter(alen, observable, type, handler, context); len = found.length; for (; len--;) { found[len].unlisten(); } return get(); } function destructor(handler) { if (!libcore.method(handler)) { throw new Error(ERROR_INVALID_HANDLER); } MIDDLEWARE.register('global-destroy', handler); return get(); } var ORDER_TYPE_PREORDER = 1; var ORDER_TYPE_POSTORDER = 2; var ORDER_TYPE_LEVELORDER = 3; exports.select = notSupportedQuerySelector; var ERROR_INVALID_DOM = ERROR[1101]; var ERROR_INVALID_DOM_NODE = ERROR[1103]; var ERROR_INVALID_DOM_NODES = ERROR[1105]; var ERROR_INVALID_CSS_SELECTOR = ERROR[1111]; var ERROR_INVALID_CALLBACK = ERROR[1112]; var ERROR_INVALID_ELEMENT_CONFIG = ERROR[1121]; var ERROR_INVALID_DESTROY = ERROR[1002]; var ALLOW_DESCENDANT_NODE_TYPES = { // CDATA_SECTION_NODE 4: { 1: 1, 11: 1 }, // COMMENT_NODE 8: { 1: 1, 11: 1 }, // DOCUMENT_FRAGMENT_NODE //11: [], // DOCUMENT_NODE //9: [], // ELEMENT_NODE 1: { 1: 1, 9: 1, 11: 1 }, // PROCESSING_INSTRUCTION_NODE 7: { 1: 1, 11: 1 }, // TEXT_NODE 3: { 1: 1, 11: 1 } }; var NORMALIZED_CONTAINS = notSupportedContains; var DOM_ATTRIBUTE_RE = /(^\_|[^a-zA-Z\_])/; var DOM_ATTRIBUTE_LIST = [ 'nodeType', 'nodeValue', 'ownerDocument', 'tagName', 'attributes', 'parentNode', 'childNodes', 'firstChild', 'lastChild', 'previousSibling', 'nextSibling', 'sourceIndex', 'type' ]; var EVENT_ATTRIBUTE_RE = /^on(\-?[a-zA-Z].+)?$/; var MANIPULATION_HELPERS = libcore.createRegistry(); var DOM_INFO; /** * node contains... */ function notSupportedContains() { throw new Error(ERROR[2004]); } function w3cContains(ancestor, descendant) { return (ancestor.compareDocumentPosition(descendant) & 16) > 0; } function ieContains(ancestor, descendant) { return ancestor.contains(descendant); } /** * DOM Manipulation helper */ function registerDomHelper(name, handler) { if (!libcore.string(name)) { throw new Error(ERROR[1001]); } if (!libcore.method(handler)) { throw new Error(ERROR[1011]); } MANIPULATION_HELPERS.set(name, handler); return get(); } function purgeEventsFrom(element) { purge(element); } function getTagNameFromConfig(config) { if (libcore.object(config)) { config = 'tagName' in config ? config.tagName : 'nodeName' in config ? config.nodeName : 'tag' in config ? config.tag : false; } return libcore.string(config) ? config : false; } function applyAttributeToElement(value, name) { /* jshint validthis:true */ var element = this, helper = MANIPULATION_HELPERS; var listen; // rename attributes switch (name) { case 'class': name = 'className'; break; case 'for': name = 'htmlFor'; break; } if (EVENT_ATTRIBUTE_RE.test(name)) { listen = name.substring(name.charAt(2) === '-' ? 3 : 2, name.length); if (listen === 'on' && libcore.object(value)) { libcore.each(value, applyEventAttribute, element); } else { applyEventAttribute.call(element, value, listen); } } else if (helper.exists(name)) { helper.get(name)(element, value); } else if (DOM_ATTRIBUTE_RE.test(name) || DOM_ATTRIBUTE_LIST.indexOf(name) !== -1) { element.setAttribute(name, value); } else { element[name] = value; } element = null; } function applyEventAttribute(handler, name) { /* jshint validthis:true */ var element = this; if (libcore.method(handler)) { on(element, name, handler); } element = null; } function applyConfigToElement(element, config, usedFragment) { var hasOwn = libcore.contains, isObject= libcore.object, me = applyConfigToElement, resolveTagName = getTagNameFromConfig, applyAttribute = applyAttributeToElement, htmlEncodeChild = false, childNodes = null; var name, value, item, c, l, fragment, doc, created; if (isObject(config)) { childNodes = null; // apply attributes main: for (name in config) { if (hasOwn(config, name)) { value = config[name]; // apply non-attributes if found switch (name) { case 'tagName': case 'nodeName': case 'tag': continue main; case 'text': case 'childText': case 'innerText': htmlEncodeChild = true; /* falls through */ case 'childNodes': case 'innerHTML': case 'html': childNodes = value; continue main; case 'attributes': if (isObject(value)) { libcore.each(value, applyAttribute, element); } continue; } applyAttribute.call(element, value, name); } } // apply childNodes if (libcore.string(childNodes)) { // convert if (htmlEncodeChild) { childNodes = xmlEncode(childNodes); } element.innerHTML = childNodes; } // fragment else if (!htmlEncodeChild) { if (isObject(childNodes)) { childNodes = [childNodes]; } if (libcore.array(childNodes)) { doc = element.ownerDocument; fragment = usedFragment === true ? element : doc.createDocumentFragment(); for (c = -1, l = childNodes.length; l--;) { item = childNodes[++c]; if (isObject(item)) { created = doc.createElement( resolveTagName(item) || 'div'); // configure me(created, item, true); fragment.appendChild(created); } } if (fragment !== element) { element.appendChild(fragment); } doc = fragment = created = null; } } item = null; } } function findChild(element, node, nodeType) { var isNumber = libcore.number; var index, counter, any; if (node === null || (is(node, 1, 3, 4, 7, 8) && node.parentNode === element)) { return node; } else if (isNumber(node) && node > -1) { index = node; counter = -1; any = !isNumber(nodeType); node = element.firstChild; for (; node; node = node.nextSibling) { if (any || nodeType === node.nodeType) { counter++; } if (counter === index) { return node; } } return null; } return false; } function hasParent(child, parent) { for (; child; child = child.parentNode) { if (child === parent) { return true; } } return false; } function resolveCreatedNode(node) { var item, result, len; if (node.nodeType === 11) { item = node.firstChild; result = []; len = 0; for (; item; item = item.nextSibling) { result[len++] = item; } item = null; return result; } return node; } /** * DOM select */ function noArrayQuerySelectorAll(dom, selector) { var list, c, l, result; if (!is(dom, 9, 1)) { throw new Error(ERROR_INVALID_DOM_NODE); } if (!libcore.string(selector)) { throw new Error(ERROR_INVALID_CSS_SELECTOR); } list = dom.querySelectorAll(selector); c = -1; (result = []).length = l = list.length; for (; l--;) { result[++c] = list[c]; } list = null; return result; } function toArrayQuerySelectorAll(dom, selector) { if (!is(dom, 9, 1)) { throw new Error(ERROR_INVALID_DOM_NODE); } if (!libcore.string(selector)) { throw new Error(ERROR_INVALID_CSS_SELECTOR); } return Array.prototype.slice.call(dom.querySelectorAll(selector)); } function notSupportedQuerySelector() { throw new Error(ERROR[2003]); } function orderTraverse(element, callback, context, orderType, includeRoot) { var depth = 0, isPostOrder = 0; var queue, last, node, current; if (typeof context === 'undefined') { context = null; } includeRoot = includeRoot !== false; switch (orderType) { case ORDER_TYPE_LEVELORDER: queue = last = { node: element, next: null }; for (; queue; queue = queue.next) { node = queue.node; queue.node = null; // iterate siblings for (; node; node = node.nextSibling) { current = node.firstChild; if ((includeRoot || 0 !== depth) && callback.call(context, current) === false) { break; } // insert if (current) { depth++; last.next = { node: current, next: null }; last = last.next; } } } break; case ORDER_TYPE_POSTORDER: isPostOrder = 1; /* falls through */ case ORDER_TYPE_PREORDER: main: for (current = element; current;) { // process pre-order if ((includeRoot || 0 !== depth) && !isPostOrder && current.nodeType === 1 && callback.call(context, current) === false) { break; } // go into first child node = current.firstChild; if (node) { depth++; } // go next sibling or parentNode's nextSibling else { // process post-order if ((includeRoot || 0 !== depth) && isPostOrder && current.nodeType === 1 && callback.call(context, current) === false) { break; } node = current.nextSibling; for (; !node && depth-- && current;) { current = current.parentNode; // process post-order if ((includeRoot || 0 !== depth) && isPostOrder && current.nodeType === 1 && callback.call(context, current) === false) { break main; } node = current.nextSibling; } } current = node; } } last = queue = node = current = null; return get(); } /** * Initialize */ DOM_INFO = DETECTED && DETECTED.dom; if (DOM_INFO) { NORMALIZED_CONTAINS = DOM_INFO.compare ? w3cContains : DOM_INFO.contains ? ieContains : notSupportedContains; if (DOM_INFO.querySelectorAll) { exports.select = DOM_INFO.listToArray ? toArrayQuerySelectorAll : noArrayQuerySelectorAll; } } var documentViewAccess = 'defaultView'; /** * is node */ function is(node) { var isNumber = libcore.number; var type, c, len, items, match, matched; if (node && typeof node === 'object') { type = node.nodeType; if (isNumber(type)) { items = arguments; len = Math.max(items.length - 1, 0); matched = !len; for (c = 0; len--;) { match = items[++c]; if (type === match) { return true; } } return matched; } } return false; } function isView(defaultView) { var type = typeof defaultView; return !!defaultView && (type === 'object' || type === 'function') && defaultView.self === defaultView.window && !!defaultView.document; } function contains$1(ancestor, descendant) { var elementErrorString = ERROR[1102], allowList = ALLOW_DESCENDANT_NODE_TYPES, isDom = is; var ancestorType, descendantType; if (!isDom(ancestor) || !isDom(descendant)) { throw new Error(elementErrorString); } // primary checking if in allow list ancestorType = ancestor.nodeType; descendantType = descendant.nodeType; if (!(descendantType in allowList) || !(ancestorType in allowList[descendantType])) { return false; } // normalize ancestory switch (ancestorType) { case 9: ancestor = ancestor.documentElement; if (ancestor === descendant) { return true; } break; // for document fragment, it requires manual checking if it has a // fragment ancestor node. case 11: return hasParent(descendant, ancestor); } return NORMALIZED_CONTAINS(ancestor, descendant); } /** * DOM manipulaton */ function add(element, config, before) { var toInsert = null, invalidConfig = ERROR_INVALID_ELEMENT_CONFIG, isDom = is; var tagName, inserted; if (!isDom(element, 1, 11)) { throw new Error(ERROR_INVALID_DOM); } if (isDom(config, 1, 3, 4, 7, 8, 11)) { toInsert = config; if (config.nodeType !== 11 && contains$1(config, element)) { throw new Error(invalidConfig); } } else if (libcore.object(config)) { tagName = getTagNameFromConfig(config); if (!tagName) { throw new Error(invalidConfig); } toInsert = element.ownerDocument.createElement(tagName); applyConfigToElement(toInsert, config); } else { throw new Error(invalidConfig); } // validate [before] if (arguments.length > 2) { before = findChild(element, before); if (before === false) { throw new Error(ERROR[1108]); } } inserted = resolveCreatedNode(toInsert); element.insertBefore(toInsert, before || null); toInsert = null; return inserted; } function remove(node, destroy) { var parentNode; if (!is(node, 1, 3, 4, 7, 8)) { throw new Error(ERROR_INVALID_DOM_NODE); } // unset child events by default if (arguments.length > 1) { if (typeof destroy !== 'boolean') { throw new Error(ERROR_INVALID_DESTROY); } if (node.nodeType === 1 && destroy) { eachNodePostorder(node, purgeEventsFrom); } } parentNode = node.parentNode; if (parentNode) { parentNode.removeChild(node); } parentNode = null; return node; } function move(nodes, element, before) { var isDom = is, insert = add, fragment = null; var c, l, newChild, inserted; // if (isDom(nodes, 1, 3, 4, 7, 8, 11)) { // fragment = nodes; // } // else if (!array(nodes)) { // } if (libcore.array(nodes)) { fragment = element.ownerDocument.createDocumentFragment(); for (c = -1, l = nodes.length; l--;) { newChild = nodes[++c]; if (!isDom(newChild, 1, 3, 4, 7, 8) || newChild === element) { throw new Error(ERROR_INVALID_DOM_NODES); } fragment.appendChild(newChild); } nodes = fragment; } else if (!isDom(nodes, 1, 3, 4, 7, 8, 11)) { throw new Error(ERROR_INVALID_DOM_NODES); } inserted = arguments.length > 2 ? insert(element, nodes, before) : insert(element, nodes); fragment = newChild = null; return inserted; } function replace(node, config, destroy) { var toInsert = null, invalidConfig = ERROR_INVALID_ELEMENT_CONFIG, isDom = is; var tagName, inserted; if (!isDom(node, 1, 3, 4, 7, 8) || !node.parentNode) { throw new Error(ERROR_INVALID_DOM_NODE); } if (isDom(config, 1, 3, 4, 7, 8, 11)) { toInsert = config; if (config.nodeType !== 11 && contains$1(config, node)) { throw new Error(invalidConfig); } } else if (libcore.object(config)) { tagName = getTagNameFromConfig(config); if (!tagName) { throw new Error(invalidConfig); } toInsert = node.ownerDocument.createElement(tagName); applyConfigToElement(toInsert, config); } else { throw new Error(invalidConfig); } // remove events before replacing it only if mandated if (arguments.length > 2) { if (typeof destroy !== 'boolean') { throw new Error(ERROR_INVALID_DESTROY); } if (node.nodeType === 1 && destroy) { eachNodePostorder(node, purgeEventsFrom); } } inserted = resolveCreatedNode(toInsert); node.parentNode.replaceChild(toInsert, node); toInsert = null; return inserted; } /** * DOM Tree walk */ function eachNodePreorder(element, callback, context, includeRoot) { if (!is(element, 1)) { throw new Error(ERROR_INVALID_DOM); } if (!libcore.method(callback)) { throw new Error(ERROR_INVALID_CALLBACK); } return orderTraverse(element, callback, context, ORDER_TYPE_PREORDER, includeRoot !== false); } function eachNodePostorder(element, callback, context, includeRoot) { if (!is(element, 1)) { throw new Error(ERROR_INVALID_DOM); } if (!libcore.method(callback)) { throw new Error(ERROR_INVALID_CALLBACK); } return orderTraverse(element, callback, context, ORDER_TYPE_POSTORDER, includeRoot !== false); } function eachNodeLevelorder(element, callback, context, includeRoot) { if (!is(element, 1)) { throw new Error(ERROR_INVALID_DOM); } if (!libcore.method(callback)) { throw new Error(ERROR_INVALID_CALLBACK); } return orderTraverse(element, callback, context, ORDER_TYPE_LEVELORDER, includeRoot !== false); } var NUMBER = 1; var HEX = 2; var PERCENT$1 = 3; var HAS_UNIT_RE = /\%$/; function format(value, colorFormat) { switch (colorFormat) { case HEX: return parseInt(value, 16) || 0; case NUMBER: value = 1 * value; return value || 0; case PERCENT$1: value = HAS_UNIT_RE.test(value) ? 1 * value.substring(0, value.length -1) : 1 * value; return Math.round((value || 1) * 100); } return 0; } var format$1 = { NUMBER: NUMBER, HEX: HEX, PERCENT: PERCENT$1, format: format }; var BYTE = 255; var BYTE_PERCENT = 127; var BYTE_HUE = 511; var PERCENT = 100; var HUE = 360; var SATURATION = PERCENT; var LUMINOSITY = PERCENT; // from: https://gist.github.com/mjackson/5311256 function hue2rgb(p, q, t) { t = (t + 1) % 1; switch (true) { case t < 1/6: return p + (q - p) * 6 * t; case t < 1/2: return q; case t < 2/3: return p + (q - p) * (2/3 - t) * 6; } return p; } function itemize(value, index, colorFormat) { var M = Math, F = format$1, isFloat = index > 2 && colorFormat !== F.PERCENT, min = 0, max = index < 3 ? BYTE : PERCENT; value = F.format(value, colorFormat); if (isFloat) { value *= 100; } return M.max(min, M.min(max, value)); } function toArray(integer) { var M = Math, h2r = hue2rgb, size = BYTE, psize = BYTE_PERCENT, h = integer & BYTE_HUE, s = (integer >> 9) & psize, l = (integer >> 16) & psize, a = (integer >> 23) & psize; var q, p; l /= LUMINOSITY; if (s === 0) { return [l, l, l]; } h /= HUE; s /= SATURATION; q = l < 0.5 ? l * (1 + s) : l + s - l * s; p = 2 * l - q; return [M.round(h2r(p, q, h + 1/3) * size), M.round(h2r(p, q, h) * size), M.round(h2r(p, q, h - 1/3) * size), (a).toFixed(2)]; } function toInteger(r, g, b, a) { var M = Math, size = BYTE, psize = BYTE_PERCENT; var max, min, h, s, l, d; r /= size; g /= size; b /= size; max = M.max(r, g, b); min = M.min(r, g, b); l = (max + min) / 2; if (max === min) { h = s = 0; // achromatic } else { d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } if (!libcore.number(a)) { a = PERCENT; } return ((a & psize) << 23) | (((l * LUMINOSITY) & psize) << 16) | (((s * SATURATION) & psize) << 9) | ((h * HUE) & BYTE_HUE); } function toString$1(integer) { var values = toArray(integer), alpha = (values[3] / PERCENT); values[3] = parseFloat(alpha.toFixed(2)); return 'rgba(' + values.join(',') + ')'; } var rgbaColor = Object.freeze({ itemize: itemize, toArray: toArray, toInteger: toInteger, toString: toString$1 }); function toHex(integer) { var M = Math; integer = M.max(0, M.min(integer, 255)); return (integer < 16 ? '0' : '') + integer.toString(16); } function toString(integer) { var convert = toHex, values = toArray(integer).slice(0, 3); values[0] = convert(values[0]); values[1] = convert(values[1]); values[2] = convert(values[2]); return '#' + values.join(''); } var hexColor = Object.freeze({ toHex: toHex, toString: toString, itemize: itemize, toArray: toArray, toInteger: toInteger }); function toString$2(integer) { return 'rgb(' + toArray(integer).slice(0, 3).join(',') + ')'; } function toInteger$1(r, g, b) { return toInteger(r, g, b, 100); } var rgbColor = Object.freeze({ toString: toString$2, toInteger: toInteger$1, itemize: itemize, toArray: toArray }); var BYTE$1 = 255; var BYTE_PERCENT$1 = 127; var BYTE_HUE$1 = 511; var HUE$1 = 360; var PERCENT$2 = 100; function itemize$1(value, index, colorFormat) { var F = format$1, M = Math, percent = PERCENT$2, min = 0, max = index < 1 ? HUE$1 : percent; switch (colorFormat) { case F.HEX: value = (parseInt(value, 16) / BYTE$1) * max; break; case F.NUMBER: value = (1 * value) || 0; if (index > 2) { value *= percent; } break; case F.PERCENT: value = (1 * value.substring(0, value.length - 1)) || 0; break; } return M.max(min, M.min(max, value || 0)); } function toInteger$2(h, s, l, a) { var psize = BYTE_PERCENT$1; if (!libcore.number(a)) { a = PERCENT$2; } return ((a & psize) << 23) | ((l & psize) << 16) | ((s & psize) << 9) | (h & BYTE_HUE$1); } function toArray$1(integer) { var psize = BYTE_PERCENT$1; return [ integer & BYTE_HUE$1, (integer >> 9) & psize, (integer >> 16) & psize, (integer >> 23) & psize]; } function toString$4(integer) { var values = toArray$1(integer); values[1] += '%'; values[2] += '%'; values[3] = (values[3] / PERCENT$2); return 'hsla(' + values.join(',') + ')'; } var hslaColor = Object.freeze({ itemize: itemize$1, toInteger: toInteger$2, toArray: toArray$1, toString: toString$4 }); function toString$3(integer) { var values = toArray$1(integer).slice(0, 3); values[1] += '%'; values[2] += '%'; return 'hsl(' + values.join(',') + ')'; } var hslColor = Object.freeze({ toString: toString$3, itemize: itemize$1, toArray: toArray$1, toInteger: toInteger$2 }); var ERROR_SUBJECT = 'Invalid [subject] parameter.'; var COLOR_RE$1 = /^(\#?|rgba?|hsla?)(\(([^\,]+(\,[^\,]+){2,3})\)|[a-f0-9]{3}|[a-f0-9]{6})$/; var NUMBER_RE$1 = /^[0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*$/; var REMOVE_SPACES = /[ \r\n\t\s]+/g; var TO_COLOR = { rgb: rgbColor, rgba: rgbaColor, hsl: hslColor, hsla: hslaColor, hex: hexColor }; function preParseValue(str) { if (typeof str === 'string') { str = str.replace(REMOVE_SPACES, ''); if (COLOR_RE$1.test(str)) { return str; } } return null; } function parseColorStringType(str) { var list = TO_COLOR, m = str.match(COLOR_RE$1), type = m[1]; var items, isHex, item; if (!libcore.contains(list, type)) { type = 'hex'; } items = m[3]; isHex = !items; // breakdown hex if (isHex) { items = m[2]; // three digit if (items.length < 6) {