(function (exports) { 'use strict'; // ChildNode.remove (function () { "use strict"; if(!("remove" in Element.prototype)){ Element.prototype.remove = function(){ if(this.parentNode) { this.parentNode.removeChild(this); } }; } })(); // Number.isNaN Number.isNaN = Number.isNaN || function(val){ return val !== val; }; // String.prototype.repeat String.prototype.repeat = String.prototype.repeat || function(num) { return Array(num + 1).join(this); }; // Adapted from https://gist.github.com/paulirish/1579671 which derived from // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating // requestAnimationFrame polyfill by Erik Möller. // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon // MIT license if (!Date.now) Date.now = function() { return new Date().getTime(); }; (function() { 'use strict'; var vendors = ['webkit', 'moz']; for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { var vp = vendors[i]; window.requestAnimationFrame = window[vp+'RequestAnimationFrame']; window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame'] || window[vp+'CancelRequestAnimationFrame']); } if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy || !window.requestAnimationFrame || !window.cancelAnimationFrame) { var lastTime = 0; window.requestAnimationFrame = function(callback) { var now = Date.now(); var nextTime = Math.max(lastTime + 16, now); return setTimeout(function() { callback(lastTime = nextTime); }, nextTime - now); }; window.cancelAnimationFrame = clearTimeout; } }()); function isNodeList(el) { // Only NodeList has the "item()" function return typeof el.item !== "undefined"; } function append(els, data) { var els_new = (isNodeList(els)) ? els : [els], i; if (typeof data.nodeType !== "undefined" && data.nodeType === 1) { for (i = els_new.length; i--;) { els_new[i].appendChild(data); } } else if (typeof data === "string") { for (i = els_new.length; i--;) { els_new[i].insertAdjacentHTML("beforeend", data); } } else if (isNodeList(data)) { var fragment = document.createDocumentFragment(); for (i = data.length; i--;) { fragment.insertBefore(data[i], fragment.firstChild); } for (var j = els_new.length; j--;) { els_new[j].appendChild(fragment); } } } function createElement(obj) { if (!obj || !obj.tagName) { throw { message : "Invalid argument" }; } var el = document.createElement(obj.tagName); obj.id && (el.id = obj.id); obj.className && (el.className = obj.className); obj.html && (el.innerHTML = obj.html); if (typeof obj.attributes !== "undefined") { var attr = obj.attributes, prop; for (prop in attr) { if (attr.hasOwnProperty(prop)) { el.setAttribute(prop, attr[prop]); } } } if (typeof obj.children !== "undefined") { var i = 0, len = obj.children.length; while (i < len) { el.appendChild(createElement(obj.children[i])); i++; } } return el; } // var el = gn.createElement({ // tagName: "div", // id: "foo", // className: "foo", // children: [{ // tagName: "div", // html: "Hello, creatElement", // attributes: { // "am-button": "primary" // } // }] // }); function ready(fn) { // Sanity check if ( typeof fn !== "function" ) { return; } // If document is already loaded, run method if ( document.readyState === "complete" ) { return fn(); } // Otherwise, wait until document is loaded document.addEventListener( "DOMContentLoaded", fn, false ); } function extend() { var obj, name, copy, target = arguments[0] || {}, i = 1, length = arguments.length; for (; i < length; i++) { if ((obj = arguments[i]) !== null) { for (name in obj) { copy = obj[name]; if (target === copy) { continue; } else if (copy !== undefined) { target[name] = copy; } } } } return target; } /** DOMTokenList polyfill */ (function(){ "use strict"; /*<*/ var UNDEF, WIN = window, DOC = document, OBJ = Object, NULL = null, TRUE = true, FALSE = false, /*>*/ /** Munge the hell out of our string literals. Saves a tonne of space after compression. */ SPACE = " ", ELEMENT = "Element", CREATE_ELEMENT = "create"+ELEMENT, DOM_TOKEN_LIST = "DOMTokenList", DEFINE_GETTER = "__defineGetter__", DEFINE_PROPERTY = "defineProperty", CLASS_ = "class", LIST = "List", CLASS_LIST = CLASS_+LIST, REL = "rel", REL_LIST = REL+LIST, DIV = "div", LENGTH = "length", CONTAINS = "contains", APPLY = "apply", HTML_ = "HTML", METHODS = ("item "+CONTAINS+" add remove toggle toString toLocaleString").split(SPACE), ADD = METHODS[2], REMOVE = METHODS[3], TOGGLE = METHODS[4], PROTOTYPE = "prototype", /** Ascertain browser support for Object.defineProperty */ dpSupport = DEFINE_PROPERTY in OBJ || DEFINE_GETTER in OBJ[ PROTOTYPE ] || NULL, /** Wrapper for Object.defineProperty that falls back to using the legacy __defineGetter__ method if available. */ defineGetter = function(object, name, fn, configurable){ if(OBJ[ DEFINE_PROPERTY ]) OBJ[ DEFINE_PROPERTY ](object, name, { configurable: FALSE === dpSupport ? TRUE : !!configurable, get: fn }); else object[ DEFINE_GETTER ](name, fn); }, /** DOMTokenList interface replacement */ DOMTokenList = function(el, prop){ var THIS = this, /** Private variables */ tokens = [], tokenMap = {}, length = 0, maxLength = 0, reindex = function(){ /** Define getter functions for array-like access to the tokenList's contents. */ if(length >= maxLength) for(; maxLength < length; ++maxLength) (function(i){ defineGetter(THIS, i, function(){ preop(); return tokens[i]; }, FALSE); })(maxLength); }, /** Helper function called at the start of each class method. Internal use only. */ preop = function(){ var error, i, args = arguments, rSpace = /\s+/; /** Validate the token/s passed to an instance method, if any. */ if(args[ LENGTH ]) for(i = 0; i < args[ LENGTH ]; ++i) if(rSpace.test(args[i])){ error = new SyntaxError('String "' + args[i] + '" ' + CONTAINS + ' an invalid character'); error.code = 5; error.name = "InvalidCharacterError"; throw error; } /** Split the new value apart by whitespace*/ tokens = ("" + el[prop]).replace(/^\s+|\s+$/g, "").split(rSpace); /** Avoid treating blank strings as single-item token lists */ if("" === tokens[0]) tokens = []; /** Repopulate the internal token lists */ tokenMap = {}; for(i = 0; i < tokens[ LENGTH ]; ++i) tokenMap[tokens[i]] = TRUE; length = tokens[ LENGTH ]; reindex(); }; /** Populate our internal token list if the targeted attribute of the subject element isn't empty. */ preop(); /** Return the number of tokens in the underlying string. Read-only. */ defineGetter(THIS, LENGTH, function(){ preop(); return length; }); /** Override the default toString/toLocaleString methods to return a space-delimited list of tokens when typecast. */ THIS[ METHODS[6] /** toLocaleString */ ] = THIS[ METHODS[5] /** toString */ ] = function(){ preop(); return tokens.join(SPACE); }; /** Return an item in the list by its index (or undefined if the number is greater than or equal to the length of the list) */ THIS.item = function(idx){ preop(); return tokens[idx]; }; /** Return TRUE if the underlying string contains `token`; otherwise, FALSE. */ THIS[ CONTAINS ] = function(token){ preop(); return !!tokenMap[token]; }; /** Add one or more tokens to the underlying string. */ THIS[ADD] = function(){ preop[APPLY](THIS, args = arguments); for(var args, token, i = 0, l = args[ LENGTH ]; i < l; ++i){ token = args[i]; if(!tokenMap[token]){ tokens.push(token); tokenMap[token] = TRUE; } } /** Update the targeted attribute of the attached element if the token list's changed. */ if(length !== tokens[ LENGTH ]){ length = tokens[ LENGTH ] >>> 0; el[prop] = tokens.join(SPACE); reindex(); } }; /** Remove one or more tokens from the underlying string. */ THIS[ REMOVE ] = function(){ preop[APPLY](THIS, args = arguments); /** Build a hash of token names to compare against when recollecting our token list. */ for(var args, ignore = {}, i = 0, t = []; i < args[ LENGTH ]; ++i){ ignore[args[i]] = TRUE; delete tokenMap[args[i]]; } /** Run through our tokens list and reassign only those that aren't defined in the hash declared above. */ for(i = 0; i < tokens[ LENGTH ]; ++i) if(!ignore[tokens[i]]) t.push(tokens[i]); tokens = t; length = t[ LENGTH ] >>> 0; /** Update the targeted attribute of the attached element. */ el[prop] = tokens.join(SPACE); reindex(); }; /** Add or remove a token depending on whether it's already contained within the token list. */ THIS[TOGGLE] = function(token, force){ preop[APPLY](THIS, [token]); /** Token state's being forced. */ if(UNDEF !== force){ if(force) { THIS[ADD](token); return TRUE; } else { THIS[REMOVE](token); return FALSE; } } /** Token already exists in tokenList. Remove it, and return FALSE. */ if(tokenMap[token]){ THIS[ REMOVE ](token); return FALSE; } /** Otherwise, add the token and return TRUE. */ THIS[ADD](token); return TRUE; }; /** Mark our newly-assigned methods as non-enumerable. */ (function(o, defineProperty){ if(defineProperty) for(var i = 0; i < 7; ++i) defineProperty(o, METHODS[i], {enumerable: FALSE}); }(THIS, OBJ[ DEFINE_PROPERTY ])); return THIS; }, /** Polyfills a property with a DOMTokenList */ addProp = function(o, name, attr){ defineGetter(o[PROTOTYPE], name, function(){ var tokenList, THIS = this, /** Prevent this from firing twice for some reason. What the hell, IE. */ gibberishProperty = DEFINE_GETTER + DEFINE_PROPERTY + name; if(THIS[gibberishProperty]) return tokenList; THIS[gibberishProperty] = TRUE; /** * IE8 can't define properties on native JavaScript objects, so we'll use a dumb hack instead. * * What this is doing is creating a dummy element ("reflection") inside a detached phantom node ("mirror") * that serves as the target of Object.defineProperty instead. While we could simply use the subject HTML * element instead, this would conflict with element types which use indexed properties (such as forms and * select lists). */ if(FALSE === dpSupport){ var visage, mirror = addProp.mirror = addProp.mirror || DOC[ CREATE_ELEMENT ](DIV), reflections = mirror.childNodes, /** Iterator variables */ l = reflections[ LENGTH ], i = 0; for(; i < l; ++i) if(reflections[i]._R === THIS){ visage = reflections[i]; break; } /** Couldn't find an element's reflection inside the mirror. Materialise one. */ visage || (visage = mirror.appendChild(DOC[ CREATE_ELEMENT ](DIV))); tokenList = DOMTokenList.call(visage, THIS, attr); } else tokenList = new DOMTokenList(THIS, attr); defineGetter(THIS, name, function(){ return tokenList; }); delete THIS[gibberishProperty]; return tokenList; }, TRUE); }, /** Variables used for patching native methods that're partially implemented (IE doesn't support adding/removing multiple tokens, for instance). */ testList, nativeAdd, nativeRemove; /** No discernible DOMTokenList support whatsoever. Time to remedy that. */ if(!WIN[ DOM_TOKEN_LIST ]){ /** Ensure the browser allows Object.defineProperty to be used on native JavaScript objects. */ if(dpSupport) try{ defineGetter({}, "support"); } catch(e){ dpSupport = FALSE; } DOMTokenList.polyfill = TRUE; WIN[ DOM_TOKEN_LIST ] = DOMTokenList; addProp( WIN[ ELEMENT ], CLASS_LIST, CLASS_ + "Name"); /* Element.classList */ addProp( WIN[ HTML_+ "Link" + ELEMENT ], REL_LIST, REL); /* HTMLLinkElement.relList */ addProp( WIN[ HTML_+ "Anchor" + ELEMENT ], REL_LIST, REL); /* HTMLAnchorElement.relList */ addProp( WIN[ HTML_+ "Area" + ELEMENT ], REL_LIST, REL); /* HTMLAreaElement.relList */ } /** * Possible support, but let's check for bugs. * * Where arbitrary values are needed for performing a test, previous variables * are recycled to save space in the minified file. */ else{ testList = DOC[ CREATE_ELEMENT ](DIV)[CLASS_LIST]; /** We'll replace a "string constant" to hold a reference to DOMTokenList.prototype (filesize optimisation, yaddah-yaddah...) */ PROTOTYPE = WIN[DOM_TOKEN_LIST][PROTOTYPE]; /** Check if we can pass multiple arguments to add/remove. To save space, we'll just recycle a previous array of strings. */ testList[ADD][APPLY](testList, METHODS); if(2 > testList[LENGTH]){ nativeAdd = PROTOTYPE[ADD]; nativeRemove = PROTOTYPE[REMOVE]; PROTOTYPE[ADD] = function(){ for(var i = 0, args = arguments; i < args[LENGTH]; ++i) nativeAdd.call(this, args[i]); }; PROTOTYPE[REMOVE] = function(){ for(var i = 0, args = arguments; i < args[LENGTH]; ++i) nativeRemove.call(this, args[i]); }; } /** Check if the "force" option of .toggle is supported. */ if(testList[TOGGLE](LIST, FALSE)) PROTOTYPE[TOGGLE] = function(token, force){ var THIS = this; THIS[(force = UNDEF === force ? !THIS[CONTAINS](token) : force) ? ADD : REMOVE](token); return !!force; }; } }()); function getClosest(elem, selector) { if (!selector || typeof selector !== 'string') { return; } var firstChar = selector.charAt(0); // Get closest match for ( ; elem && elem !== document; elem = elem.parentNode ) { // If selector is a class if ( firstChar === "." ) { if ( elem.classList.contains( selector.substr(1) ) ) { return elem; } } // If selector is an ID if ( firstChar === "#" ) { if ( elem.id === selector.substr(1) ) { return elem; } } // If selector is a data attribute if ( firstChar === "[" ) { if ( elem.hasAttribute( selector.substr(1, selector.length - 2) ) ) { return elem; } } // If selector is a tag if ( elem.tagName.toLowerCase() === selector ) { return elem; } } return false; } // var elem = document.querySelector("#some-element"); // var closest = getClosest(elem, ".some-class"); // var closestLink = getClosest(elem, "a"); // var closestExcludingElement = getClosest(elem.parentNode, ".some-class"); (function(window, document, undefined){ "use strict"; // create a test element var testElem = document.createElement('test'), docElement = document.documentElement, defaultView = document.defaultView, getComputedStyle = defaultView && defaultView.getComputedStyle, computedValueBug, runit = /^(-?[\d+\.\-]+)([a-z]+|%)$/i, convert = {}, conversions = [1/25.4, 1/2.54, 1/72, 1/6], units = ['mm', 'cm', 'pt', 'pc', 'in', 'mozmm'], i = 6; // units.length // add the test element to the dom docElement.appendChild(testElem); // test for the WebKit getComputedStyle bug // @see http://bugs.jquery.com/ticket/10639 if (getComputedStyle) { // add a percentage margin and measure it testElem.style.marginTop = '1%'; computedValueBug = getComputedStyle(testElem).marginTop === '1%'; } // pre-calculate absolute unit conversions while(i--) { convert[units[i] + "toPx"] = conversions[i] ? conversions[i] * convert.inToPx : toPx(testElem, '1' + units[i]); } // remove the test element from the DOM and delete it docElement.removeChild(testElem); testElem = undefined; // convert a value to pixels function toPx(elem, value, prop, force) { // use width as the default property, or specify your own prop = prop || 'width'; var style, inlineValue, ret, unit = (value.match(runit)||[])[2], conversion = unit === 'px' ? 1 : convert[unit + 'toPx'], rem = /r?em/i; if (conversion || rem.test(unit) && !force) { // calculate known conversions immediately // find the correct element for absolute units or rem or fontSize + em or em elem = conversion ? elem : unit === 'rem' ? docElement : prop === 'fontSize' ? elem.parentNode || elem : elem; // use the pre-calculated conversion or fontSize of the element for rem and em conversion = conversion || parseFloat(curCSS(elem, 'fontSize')); // multiply the value by the conversion ret = parseFloat(value) * conversion; } else { // begin "the awesome hack by Dean Edwards" // @see http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 // remember the current style style = elem.style; inlineValue = style[prop]; // set the style on the target element try { style[prop] = value; } catch(e) { // IE 8 and below throw an exception when setting unsupported units return 0; } // read the computed value // if style is nothing we probably set an unsupported unit ret = !style[prop] ? 0 : parseFloat(curCSS(elem, prop)); // reset the style back to what it was or blank it out style[prop] = inlineValue !== undefined ? inlineValue : null; } // return a number return ret; } // return the computed value of a CSS property function curCSS(elem, prop) { var value, pixel, unit, rvpos = /^top|bottom/, outerProp = ["paddingTop", "paddingBottom", "borderTop", "borderBottom"], innerHeight, parent, i = 4; // outerProp.length if (getComputedStyle) { // FireFox, Chrome/Safari, Opera and IE9+ value = getComputedStyle(elem)[prop]; } else if (pixel = elem.style['pixel' + prop.charAt(0).toUpperCase() + prop.slice(1)]) { // IE and Opera support pixel shortcuts for top, bottom, left, right, height, width // WebKit supports pixel shortcuts only when an absolute unit is used value = pixel + 'px'; } else if (prop === 'fontSize') { // correct IE issues with font-size // @see http://bugs.jquery.com/ticket/760 value = toPx(elem, '1em', 'left', 1) + 'px'; } else { // IE 8 and below return the specified style value = elem.currentStyle[prop]; } // check the unit unit = (value.match(runit)||[])[2]; if (unit === '%' && computedValueBug) { // WebKit won't convert percentages for top, bottom, left, right, margin and text-indent if (rvpos.test(prop)) { // Top and bottom require measuring the innerHeight of the parent. innerHeight = (parent = elem.parentNode || elem).offsetHeight; while (i--) { innerHeight -= parseFloat(curCSS(parent, outerProp[i])); } value = parseFloat(value) / 100 * innerHeight + 'px'; } else { // This fixes margin, left, right and text-indent // @see https://bugs.webkit.org/show_bug.cgi?id=29084 // @see http://bugs.jquery.com/ticket/10639 value = toPx(elem, value); } } else if ((value === 'auto' || (unit && unit !== 'px')) && getComputedStyle) { // WebKit and Opera will return auto in some cases // Firefox will pass back an unaltered value when it can't be set, like top on a static element value = 0; } else if (unit && unit !== 'px' && !getComputedStyle) { // IE 8 and below won't convert units for us // try to convert using a prop that will return pixels // this will be accurate for everything (except font-size and some percentages) value = toPx(elem, value) + 'px'; } return value; } // expose the conversion function to the window object window.Length = { toPx: toPx }; }(window, window.document)); function getHeight(el) { var pattern = /\d/, // check if value contains digital number height = el.clientHeight, style = el.currentStyle || getComputedStyle(el), paddingTop = (pattern.exec(style.paddingTop) === null) ? "0px" : style.paddingTop, paddingBottom = (pattern.exec(style.paddingBottom) === null) ? "0px" : style.paddingBottom; height -= (parseInt(Length.toPx(el, paddingTop)) + parseInt(Length.toPx(el, paddingBottom))); return height; } // 1. outer size: content + padding + border + margin // // 2. offset size: content + padding + border // // el.offsetWidth // el.offsetHeight // 3. client size: content + padding // el.clientWidth // el.clientHeight // 4. size: content function getOffsetLeft(el) { return el.getBoundingClientRect().left + document.documentElement.scrollLeft; } function getOffsetTop(el) { return el.getBoundingClientRect().top + document.documentElement.scrollTop; } function getOuterHeight(el) { var pattern = /\d/, // check if value contains digital number height = el.offsetHeight, style = el.currentStyle || getComputedStyle(el), marginTop = (pattern.exec(style.marginTop) === null) ? "0px" : style.marginTop, marginBottom = (pattern.exec(style.marginBottom) === null) ? "0px" : style.marginBottom; height += parseInt(Length.toPx(el, marginTop)) + parseInt(Length.toPx(el, marginBottom)); return height; } // 1. outer size: content + padding + border + margin // // 2. offset size: content + padding + border // // el.offsetWidth // el.offsetHeight // 3. client size: content + padding // el.clientWidth // el.clientHeight function getOuterWidth(el) { var pattern = /\d/, // check if value contains digital number width = el.offsetWidth, style = el.currentStyle || getComputedStyle(el), marginLeft = (pattern.exec(style.marginLeft) === null) ? "0px" : style.marginLeft, marginRight = (pattern.exec(style.marginRight) === null) ? "0px" : style.marginRight; width += parseInt(Length.toPx(el, marginLeft)) + parseInt(Length.toPx(el, marginRight)); return width; } // 1. outer size: content + padding + border + margin // // 2. offset size: content + padding + border // // el.offsetWidth // el.offsetHeight // 3. client size: content + padding // el.clientWidth // el.clientHeight function getParents(elem, selector) { var parents = []; if ( selector ) { var firstChar = selector.charAt(0); } // Get matches for ( ; elem && elem !== document; elem = elem.parentNode ) { if ( selector ) { // If selector is a class if ( firstChar === "." ) { if ( elem.classList.contains( selector.substr(1) ) ) { parents.push( elem ); } } // If selector is an ID if ( firstChar === "#" ) { if ( elem.id === selector.substr(1) ) { parents.push( elem ); } } // If selector is a data attribute if ( firstChar === "[" ) { if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) { parents.push( elem ); } } // If selector is a tag if ( elem.tagName.toLowerCase() === selector ) { parents.push( elem ); } } else { parents.push( elem ); } } // Return parents if any exist if ( parents.length === 0 ) { return null; } else { return parents; } } // var elem = document.querySelector("#some-element"); // var parents = getParents(elem, ".some-class"); // var allParents = getParents(elem.parentNode); function getParentsUntil(elem, parent, selector) { var parents = []; if ( parent ) { var parentType = parent.charAt(0); } if ( selector ) { var selectorType = selector.charAt(0); } // Get matches for ( ; elem && elem !== document; elem = elem.parentNode ) { // Check if parent has been reached if ( parent ) { // If parent is a class if ( parentType === "." ) { if ( elem.classList.contains( parent.substr(1) ) ) { break; } } // If parent is an ID if ( parentType === "#" ) { if ( elem.id === parent.substr(1) ) { break; } } // If parent is a data attribute if ( parentType === "[" ) { if ( elem.hasAttribute( parent.substr(1, parent.length - 1) ) ) { break; } } // If parent is a tag if ( elem.tagName.toLowerCase() === parent ) { break; } } if ( selector ) { // If selector is a class if ( selectorType === "." ) { if ( elem.classList.contains( selector.substr(1) ) ) { parents.push( elem ); } } // If selector is an ID if ( selectorType === "#" ) { if ( elem.id === selector.substr(1) ) { parents.push( elem ); } } // If selector is a data attribute if ( selectorType === "[" ) { if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) { parents.push( elem ); } } // If selector is a tag if ( elem.tagName.toLowerCase() === selector ) { parents.push( elem ); } } else { parents.push( elem ); } } // Return parents if any exist if ( parents.length === 0 ) { return null; } else { return parents; } } // Examples // var elem = document.querySelector("#some-element"); // var parentsUntil = getParentsUntil(elem, ".some-class"); // var parentsUntilByFilter = getParentsUntil(elem, ".some-class", "[data-something]"); // var allParentsUntil = getParentsUntil(elem); // var allParentsExcludingElem = getParentsUntil(elem.parentNode); function getSiblings(elem) { var siblings = []; var sibling = elem.parentNode.firstChild; for ( ; sibling; sibling = sibling.nextSibling ) { if ( sibling.nodeType === 1 && sibling !== elem ) { siblings.push( sibling ); } } return siblings; } // var elem = document.querySelector('#some-element'); // var siblings = getSiblings(elem); function getSupportedProp(proparray){ var root = document.documentElement; for (var i=0; i 0 && rect.right > 0 && rect.top < document.documentElement.clientHeight && rect.left < document.documentElement.clientWidth ); } // forEach if (!Array.prototype.forEach) { Array.prototype.forEach = function(block, thisObject) { var len = this.length >>> 0; for (var i = 0; i < len; i++) { if (i in this) { block.call(thisObject, this[i], i, this); } } }; } // addEventListener // removeEventListener // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener?redirectlocale=en-US&redirectslug=DOM%2FEventTarget.addEventListener#Compatibility (function() { if (!Element.prototype.addEventListener) { var eventListeners=[]; var addEventListener=function(type,listener /*, useCapture (will be ignored) */) { var self=this; var wrapper=function(e) { e.target=e.srcElement; e.currentTarget=self; if (typeof listener.handleEvent != "undefined") { listener.handleEvent(e); } else { listener.call(self,e); } }; if (type=="DOMContentLoaded") { var wrapper2=function(e) { if (document.readyState=="complete") { wrapper(e); } }; document.attachEvent("onreadystatechange",wrapper2); eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper2}); if (document.readyState=="complete") { var e=new Event(); e.srcElement=window; wrapper2(e); } } else { this.attachEvent("on"+type,wrapper); eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper}); } }; var removeEventListener=function(type,listener /*, useCapture (will be ignored) */) { var counter=0; while (counter 0) ? obj.cloneNode(true) : obj, el = elsNew[i]; // Cache the current parent and sibling. var parent = el.parentNode, sibling = el.nextSibling; // Wrap the element (is automatically removed from its current parent). wrapper.appendChild(el); // If the element had a sibling, insert the wrapper before // the sibling to maintain the HTML structure; otherwise, just // append it to the parent. if (sibling) { parent.insertBefore(wrapper, sibling); } else { parent.appendChild(wrapper); } } } function wrapAll(els, wrapper) { // Cache the current parent and sibling of the first element. var el = els.length ? els[0] : els, parent = el.parentNode, sibling = el.nextSibling; // Wrap all elements (if applicable). Each element is // automatically removed from its current parent and from the elms // array. for (var i = 0; i < els.length; i++) { wrapper.appendChild(els[i]); } // If the first element had a sibling, insert the wrapper before the // sibling to maintain the HTML structure; otherwise, just append it // to the parent. if (sibling !== els[1]) { parent.insertBefore(wrapper, sibling); } else { parent.appendChild(wrapper); } } exports.isNodeList = isNodeList; exports.append = append; exports.createElement = createElement; exports.ready = ready; exports.extend = extend; exports.getClosest = getClosest; exports.getHeight = getHeight; exports.getOffsetLeft = getOffsetLeft; exports.getOffsetTop = getOffsetTop; exports.getOuterHeight = getOuterHeight; exports.getOuterWidth = getOuterWidth; exports.getParents = getParents; exports.getParentsUntil = getParentsUntil; exports.getSiblings = getSiblings; exports.getSupportedProp = getSupportedProp; exports.getWidth = getWidth; exports.indexOf = indexOf; exports.isInViewport = isInViewport; exports.optimizedResize = optimizedResize; exports.prepend = prepend; exports.unwrap = unwrap; exports.wrap = wrap; exports.wrapAll = wrapAll; }((this.gn = this.gn || {})));