mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-15 20:52:41 +00:00
913 lines
28 KiB
JavaScript
913 lines
28 KiB
JavaScript
/**
|
|
* @file
|
|
* @copyright 2013 Andrea Giammarchi, WebReflection
|
|
* @license MIT
|
|
*/
|
|
|
|
/* eslint-disable */
|
|
(function (window) {
|
|
'use strict';
|
|
/* jshint loopfunc: true, noempty: false*/
|
|
// http://www.w3.org/TR/dom/#element
|
|
|
|
function createDocumentFragment() {
|
|
return document.createDocumentFragment();
|
|
}
|
|
|
|
function createElement(nodeName) {
|
|
return document.createElement(nodeName);
|
|
}
|
|
|
|
function enoughArguments(length, name) {
|
|
if (!length) throw new Error('Failed to construct ' + name + ': 1 argument required, but only 0 present.');
|
|
}
|
|
|
|
function mutationMacro(nodes) {
|
|
if (nodes.length === 1) {
|
|
return textNodeIfPrimitive(nodes[0]);
|
|
}
|
|
for (var fragment = createDocumentFragment(), list = slice.call(nodes), i = 0; i < nodes.length; i++) {
|
|
fragment.appendChild(textNodeIfPrimitive(list[i]));
|
|
}
|
|
return fragment;
|
|
}
|
|
|
|
function textNodeIfPrimitive(node) {
|
|
return typeof node === 'object' ? node : document.createTextNode(node);
|
|
}
|
|
|
|
for (
|
|
var head,
|
|
property,
|
|
TemporaryPrototype,
|
|
TemporaryTokenList,
|
|
wrapVerifyToken,
|
|
document = window.document,
|
|
hOP = Object.prototype.hasOwnProperty,
|
|
defineProperty =
|
|
Object.defineProperty ||
|
|
function (object, property, descriptor) {
|
|
if (hOP.call(descriptor, 'value')) {
|
|
object[property] = descriptor.value;
|
|
} else {
|
|
if (hOP.call(descriptor, 'get')) object.__defineGetter__(property, descriptor.get);
|
|
if (hOP.call(descriptor, 'set')) object.__defineSetter__(property, descriptor.set);
|
|
}
|
|
return object;
|
|
},
|
|
indexOf =
|
|
[].indexOf ||
|
|
function indexOf(value) {
|
|
var length = this.length;
|
|
while (length--) {
|
|
if (this[length] === value) {
|
|
break;
|
|
}
|
|
}
|
|
return length;
|
|
},
|
|
// http://www.w3.org/TR/domcore/#domtokenlist
|
|
verifyToken = function (token) {
|
|
if (!token) {
|
|
throw 'SyntaxError';
|
|
} else if (spaces.test(token)) {
|
|
throw 'InvalidCharacterError';
|
|
}
|
|
return token;
|
|
},
|
|
DOMTokenList = function (node) {
|
|
var noClassName = typeof node.className === 'undefined',
|
|
className = noClassName ? node.getAttribute('class') || '' : node.className,
|
|
isSVG = noClassName || typeof className === 'object',
|
|
value = (isSVG ? (noClassName ? className : className.baseVal) : className).replace(trim, '');
|
|
if (value.length) {
|
|
properties.push.apply(this, value.split(spaces));
|
|
}
|
|
this._isSVG = isSVG;
|
|
this._ = node;
|
|
},
|
|
classListDescriptor = {
|
|
get: function get() {
|
|
return new DOMTokenList(this);
|
|
},
|
|
set: function () {},
|
|
},
|
|
trim = /^\s+|\s+$/g,
|
|
spaces = /\s+/,
|
|
SPACE = '\x20',
|
|
CLASS_LIST = 'classList',
|
|
toggle = function toggle(token, force) {
|
|
if (this.contains(token)) {
|
|
if (!force) {
|
|
// force is not true (either false or omitted)
|
|
this.remove(token);
|
|
}
|
|
} else if (force === undefined || force) {
|
|
force = true;
|
|
this.add(token);
|
|
}
|
|
return !!force;
|
|
},
|
|
DocumentFragmentPrototype = window.DocumentFragment && DocumentFragment.prototype,
|
|
Node = window.Node,
|
|
NodePrototype = (Node || Element).prototype,
|
|
CharacterData = window.CharacterData || Node,
|
|
CharacterDataPrototype = CharacterData && CharacterData.prototype,
|
|
DocumentType = window.DocumentType,
|
|
DocumentTypePrototype = DocumentType && DocumentType.prototype,
|
|
ElementPrototype = (window.Element || Node || window.HTMLElement).prototype,
|
|
HTMLSelectElement = window.HTMLSelectElement || createElement('select').constructor,
|
|
selectRemove = HTMLSelectElement.prototype.remove,
|
|
SVGElement = window.SVGElement,
|
|
properties = [
|
|
'matches',
|
|
ElementPrototype.matchesSelector ||
|
|
ElementPrototype.webkitMatchesSelector ||
|
|
ElementPrototype.khtmlMatchesSelector ||
|
|
ElementPrototype.mozMatchesSelector ||
|
|
ElementPrototype.msMatchesSelector ||
|
|
ElementPrototype.oMatchesSelector ||
|
|
function matches(selector) {
|
|
var parentNode = this.parentNode;
|
|
return !!parentNode && -1 < indexOf.call(parentNode.querySelectorAll(selector), this);
|
|
},
|
|
'closest',
|
|
function closest(selector) {
|
|
var parentNode = this,
|
|
matches;
|
|
while (
|
|
// document has no .matches
|
|
(matches = parentNode && parentNode.matches) &&
|
|
!parentNode.matches(selector)
|
|
) {
|
|
parentNode = parentNode.parentNode;
|
|
}
|
|
return matches ? parentNode : null;
|
|
},
|
|
'prepend',
|
|
function prepend() {
|
|
var firstChild = this.firstChild,
|
|
node = mutationMacro(arguments);
|
|
if (firstChild) {
|
|
this.insertBefore(node, firstChild);
|
|
} else {
|
|
this.appendChild(node);
|
|
}
|
|
},
|
|
'append',
|
|
function append() {
|
|
this.appendChild(mutationMacro(arguments));
|
|
},
|
|
'before',
|
|
function before() {
|
|
var parentNode = this.parentNode;
|
|
if (parentNode) {
|
|
parentNode.insertBefore(mutationMacro(arguments), this);
|
|
}
|
|
},
|
|
'after',
|
|
function after() {
|
|
var parentNode = this.parentNode,
|
|
nextSibling = this.nextSibling,
|
|
node = mutationMacro(arguments);
|
|
if (parentNode) {
|
|
if (nextSibling) {
|
|
parentNode.insertBefore(node, nextSibling);
|
|
} else {
|
|
parentNode.appendChild(node);
|
|
}
|
|
}
|
|
},
|
|
// https://dom.spec.whatwg.org/#dom-element-toggleattribute
|
|
'toggleAttribute',
|
|
function toggleAttribute(name, force) {
|
|
var had = this.hasAttribute(name);
|
|
if (1 < arguments.length) {
|
|
if (had && !force) this.removeAttribute(name);
|
|
else if (force && !had) this.setAttribute(name, '');
|
|
} else if (had) this.removeAttribute(name);
|
|
else this.setAttribute(name, '');
|
|
return this.hasAttribute(name);
|
|
},
|
|
// WARNING - DEPRECATED - use .replaceWith() instead
|
|
'replace',
|
|
function replace() {
|
|
this.replaceWith.apply(this, arguments);
|
|
},
|
|
'replaceWith',
|
|
function replaceWith() {
|
|
var parentNode = this.parentNode;
|
|
if (parentNode) {
|
|
parentNode.replaceChild(mutationMacro(arguments), this);
|
|
}
|
|
},
|
|
'remove',
|
|
function remove() {
|
|
var parentNode = this.parentNode;
|
|
if (parentNode) {
|
|
parentNode.removeChild(this);
|
|
}
|
|
},
|
|
],
|
|
slice = properties.slice,
|
|
i = properties.length;
|
|
i;
|
|
i -= 2
|
|
) {
|
|
property = properties[i - 2];
|
|
if (!(property in ElementPrototype)) {
|
|
ElementPrototype[property] = properties[i - 1];
|
|
}
|
|
// avoid unnecessary re-patch when the script is included
|
|
// gazillion times without any reason whatsoever
|
|
// https://github.com/WebReflection/dom4/pull/48
|
|
if (property === 'remove' && !selectRemove._dom4) {
|
|
// see https://github.com/WebReflection/dom4/issues/19
|
|
(HTMLSelectElement.prototype[property] = function () {
|
|
return 0 < arguments.length ? selectRemove.apply(this, arguments) : ElementPrototype.remove.call(this);
|
|
})._dom4 = true;
|
|
}
|
|
// see https://github.com/WebReflection/dom4/issues/18
|
|
if (/^(?:before|after|replace|replaceWith|remove)$/.test(property)) {
|
|
if (CharacterData && !(property in CharacterDataPrototype)) {
|
|
CharacterDataPrototype[property] = properties[i - 1];
|
|
}
|
|
if (DocumentType && !(property in DocumentTypePrototype)) {
|
|
DocumentTypePrototype[property] = properties[i - 1];
|
|
}
|
|
}
|
|
// see https://github.com/WebReflection/dom4/pull/26
|
|
if (/^(?:append|prepend)$/.test(property)) {
|
|
if (DocumentFragmentPrototype) {
|
|
if (!(property in DocumentFragmentPrototype)) {
|
|
DocumentFragmentPrototype[property] = properties[i - 1];
|
|
}
|
|
} else {
|
|
try {
|
|
createDocumentFragment().constructor.prototype[property] = properties[i - 1];
|
|
} catch (o_O) {}
|
|
}
|
|
}
|
|
}
|
|
|
|
// most likely an IE9 only issue
|
|
// see https://github.com/WebReflection/dom4/issues/6
|
|
if (!createElement('a').matches('a')) {
|
|
ElementPrototype[property] = (function (matches) {
|
|
return function (selector) {
|
|
return matches.call(this.parentNode ? this : createDocumentFragment().appendChild(this), selector);
|
|
};
|
|
})(ElementPrototype[property]);
|
|
}
|
|
|
|
// used to fix both old webkit and SVG
|
|
DOMTokenList.prototype = {
|
|
length: 0,
|
|
add: function add() {
|
|
for (var j = 0, token; j < arguments.length; j++) {
|
|
token = arguments[j];
|
|
if (!this.contains(token)) {
|
|
properties.push.call(this, property);
|
|
}
|
|
}
|
|
if (this._isSVG) {
|
|
this._.setAttribute('class', '' + this);
|
|
} else {
|
|
this._.className = '' + this;
|
|
}
|
|
},
|
|
contains: (function (indexOf) {
|
|
return function contains(token) {
|
|
i = indexOf.call(this, (property = verifyToken(token)));
|
|
return -1 < i;
|
|
};
|
|
})(
|
|
[].indexOf ||
|
|
function (token) {
|
|
i = this.length;
|
|
while (i-- && this[i] !== token) {}
|
|
return i;
|
|
}
|
|
),
|
|
item: function item(i) {
|
|
return this[i] || null;
|
|
},
|
|
remove: function remove() {
|
|
for (var j = 0, token; j < arguments.length; j++) {
|
|
token = arguments[j];
|
|
if (this.contains(token)) {
|
|
properties.splice.call(this, i, 1);
|
|
}
|
|
}
|
|
if (this._isSVG) {
|
|
this._.setAttribute('class', '' + this);
|
|
} else {
|
|
this._.className = '' + this;
|
|
}
|
|
},
|
|
toggle: toggle,
|
|
toString: function toString() {
|
|
return properties.join.call(this, SPACE);
|
|
},
|
|
};
|
|
|
|
if (SVGElement && !(CLASS_LIST in SVGElement.prototype)) {
|
|
defineProperty(SVGElement.prototype, CLASS_LIST, classListDescriptor);
|
|
}
|
|
|
|
// http://www.w3.org/TR/dom/#domtokenlist
|
|
// iOS 5.1 has completely screwed this property
|
|
// classList in ElementPrototype is false
|
|
// but it's actually there as getter
|
|
if (!(CLASS_LIST in document.documentElement)) {
|
|
defineProperty(ElementPrototype, CLASS_LIST, classListDescriptor);
|
|
} else {
|
|
// iOS 5.1 and Nokia ASHA do not support multiple add or remove
|
|
// trying to detect and fix that in here
|
|
TemporaryTokenList = createElement('div')[CLASS_LIST];
|
|
TemporaryTokenList.add('a', 'b', 'a');
|
|
if ('a\x20b' != TemporaryTokenList) {
|
|
// no other way to reach original methods in iOS 5.1
|
|
TemporaryPrototype = TemporaryTokenList.constructor.prototype;
|
|
if (!('add' in TemporaryPrototype)) {
|
|
// ASHA double fails in here
|
|
TemporaryPrototype = window.TemporaryTokenList.prototype;
|
|
}
|
|
wrapVerifyToken = function (original) {
|
|
return function () {
|
|
var i = 0;
|
|
while (i < arguments.length) {
|
|
original.call(this, arguments[i++]);
|
|
}
|
|
};
|
|
};
|
|
TemporaryPrototype.add = wrapVerifyToken(TemporaryPrototype.add);
|
|
TemporaryPrototype.remove = wrapVerifyToken(TemporaryPrototype.remove);
|
|
// toggle is broken too ^_^ ... let's fix it
|
|
TemporaryPrototype.toggle = toggle;
|
|
}
|
|
}
|
|
|
|
if (!('contains' in NodePrototype)) {
|
|
defineProperty(NodePrototype, 'contains', {
|
|
value: function (el) {
|
|
while (el && el !== this) el = el.parentNode;
|
|
return this === el;
|
|
},
|
|
});
|
|
}
|
|
|
|
if (!('head' in document)) {
|
|
defineProperty(document, 'head', {
|
|
get: function () {
|
|
return head || (head = document.getElementsByTagName('head')[0]);
|
|
},
|
|
});
|
|
}
|
|
|
|
// requestAnimationFrame partial polyfill
|
|
(function () {
|
|
for (
|
|
var raf,
|
|
rAF = window.requestAnimationFrame,
|
|
cAF = window.cancelAnimationFrame,
|
|
prefixes = ['o', 'ms', 'moz', 'webkit'],
|
|
i = prefixes.length;
|
|
!cAF && i--;
|
|
|
|
) {
|
|
rAF = rAF || window[prefixes[i] + 'RequestAnimationFrame'];
|
|
cAF = window[prefixes[i] + 'CancelAnimationFrame'] || window[prefixes[i] + 'CancelRequestAnimationFrame'];
|
|
}
|
|
if (!cAF) {
|
|
// some FF apparently implemented rAF but no cAF
|
|
if (rAF) {
|
|
raf = rAF;
|
|
rAF = function (callback) {
|
|
var goOn = true;
|
|
raf(function () {
|
|
if (goOn) callback.apply(this, arguments);
|
|
});
|
|
return function () {
|
|
goOn = false;
|
|
};
|
|
};
|
|
cAF = function (id) {
|
|
id();
|
|
};
|
|
} else {
|
|
rAF = function (callback) {
|
|
return setTimeout(callback, 15, 15);
|
|
};
|
|
cAF = function (id) {
|
|
clearTimeout(id);
|
|
};
|
|
}
|
|
}
|
|
window.requestAnimationFrame = rAF;
|
|
window.cancelAnimationFrame = cAF;
|
|
})();
|
|
|
|
// http://www.w3.org/TR/dom/#customevent
|
|
try {
|
|
new window.CustomEvent('?');
|
|
} catch (o_O) {
|
|
window.CustomEvent = (function (eventName, defaultInitDict) {
|
|
// the infamous substitute
|
|
function CustomEvent(type, eventInitDict) {
|
|
/*jshint eqnull:true */
|
|
var event = document.createEvent(eventName);
|
|
if (typeof type != 'string') {
|
|
throw new Error('An event name must be provided');
|
|
}
|
|
if (eventName == 'Event') {
|
|
event.initCustomEvent = initCustomEvent;
|
|
}
|
|
if (eventInitDict == null) {
|
|
eventInitDict = defaultInitDict;
|
|
}
|
|
event.initCustomEvent(type, eventInitDict.bubbles, eventInitDict.cancelable, eventInitDict.detail);
|
|
return event;
|
|
}
|
|
|
|
// attached at runtime
|
|
function initCustomEvent(type, bubbles, cancelable, detail) {
|
|
/*jshint validthis:true*/
|
|
this.initEvent(type, bubbles, cancelable);
|
|
this.detail = detail;
|
|
}
|
|
|
|
// that's it
|
|
return CustomEvent;
|
|
})(
|
|
// is this IE9 or IE10 ?
|
|
// where CustomEvent is there
|
|
// but not usable as construtor ?
|
|
window.CustomEvent
|
|
? // use the CustomEvent interface in such case
|
|
'CustomEvent'
|
|
: 'Event',
|
|
// otherwise the common compatible one
|
|
{
|
|
bubbles: false,
|
|
cancelable: false,
|
|
detail: null,
|
|
}
|
|
);
|
|
}
|
|
|
|
// window.Event as constructor
|
|
try {
|
|
new Event('_');
|
|
} catch (o_O) {
|
|
/* jshint -W022 */
|
|
o_O = (function ($Event) {
|
|
function Event(type, init) {
|
|
enoughArguments(arguments.length, 'Event');
|
|
var out = document.createEvent('Event');
|
|
if (!init) init = {};
|
|
out.initEvent(type, !!init.bubbles, !!init.cancelable);
|
|
return out;
|
|
}
|
|
Event.prototype = $Event.prototype;
|
|
return Event;
|
|
})(window.Event || function Event() {});
|
|
defineProperty(window, 'Event', { value: o_O });
|
|
// Android 4 gotcha
|
|
if (Event !== o_O) Event = o_O;
|
|
}
|
|
|
|
// window.KeyboardEvent as constructor
|
|
try {
|
|
new KeyboardEvent('_', {});
|
|
} catch (o_O) {
|
|
/* jshint -W022 */
|
|
o_O = (function ($KeyboardEvent) {
|
|
// code inspired by https://gist.github.com/termi/4654819
|
|
var initType = 0,
|
|
defaults = {
|
|
char: '',
|
|
key: '',
|
|
location: 0,
|
|
ctrlKey: false,
|
|
shiftKey: false,
|
|
altKey: false,
|
|
metaKey: false,
|
|
altGraphKey: false,
|
|
repeat: false,
|
|
locale: navigator.language,
|
|
detail: 0,
|
|
bubbles: false,
|
|
cancelable: false,
|
|
keyCode: 0,
|
|
charCode: 0,
|
|
which: 0,
|
|
},
|
|
eventType;
|
|
try {
|
|
var e = document.createEvent('KeyboardEvent');
|
|
e.initKeyboardEvent('keyup', false, false, window, '+', 3, true, false, true, false, false);
|
|
initType =
|
|
((e.keyIdentifier || e.key) == '+' &&
|
|
(e.keyLocation || e.location) == 3 &&
|
|
(e.ctrlKey ? (e.altKey ? 1 : 3) : e.shiftKey ? 2 : 4)) ||
|
|
9;
|
|
} catch (o_O) {}
|
|
eventType = 0 < initType ? 'KeyboardEvent' : 'Event';
|
|
|
|
function getModifier(init) {
|
|
for (
|
|
var out = [],
|
|
keys = [
|
|
'ctrlKey',
|
|
'Control',
|
|
'shiftKey',
|
|
'Shift',
|
|
'altKey',
|
|
'Alt',
|
|
'metaKey',
|
|
'Meta',
|
|
'altGraphKey',
|
|
'AltGraph',
|
|
],
|
|
i = 0;
|
|
i < keys.length;
|
|
i += 2
|
|
) {
|
|
if (init[keys[i]]) out.push(keys[i + 1]);
|
|
}
|
|
return out.join(' ');
|
|
}
|
|
|
|
function withDefaults(target, source) {
|
|
for (var key in source) {
|
|
if (source.hasOwnProperty(key) && !source.hasOwnProperty.call(target, key)) target[key] = source[key];
|
|
}
|
|
return target;
|
|
}
|
|
|
|
function withInitValues(key, out, init) {
|
|
try {
|
|
out[key] = init[key];
|
|
} catch (o_O) {}
|
|
}
|
|
|
|
function KeyboardEvent(type, init) {
|
|
enoughArguments(arguments.length, 'KeyboardEvent');
|
|
init = withDefaults(init || {}, defaults);
|
|
var out = document.createEvent(eventType),
|
|
ctrlKey = init.ctrlKey,
|
|
shiftKey = init.shiftKey,
|
|
altKey = init.altKey,
|
|
metaKey = init.metaKey,
|
|
altGraphKey = init.altGraphKey,
|
|
modifiers = initType > 3 ? getModifier(init) : null,
|
|
key = String(init.key),
|
|
chr = String(init.char),
|
|
location = init.location,
|
|
keyCode = init.keyCode || ((init.keyCode = key) && key.charCodeAt(0)) || 0,
|
|
charCode = init.charCode || ((init.charCode = chr) && chr.charCodeAt(0)) || 0,
|
|
bubbles = init.bubbles,
|
|
cancelable = init.cancelable,
|
|
repeat = init.repeat,
|
|
locale = init.locale,
|
|
view = init.view || window,
|
|
args;
|
|
if (!init.which) init.which = init.keyCode;
|
|
if ('initKeyEvent' in out) {
|
|
out.initKeyEvent(type, bubbles, cancelable, view, ctrlKey, altKey, shiftKey, metaKey, keyCode, charCode);
|
|
} else if (0 < initType && 'initKeyboardEvent' in out) {
|
|
args = [type, bubbles, cancelable, view];
|
|
switch (initType) {
|
|
case 1:
|
|
args.push(key, location, ctrlKey, shiftKey, altKey, metaKey, altGraphKey);
|
|
break;
|
|
case 2:
|
|
args.push(ctrlKey, altKey, shiftKey, metaKey, keyCode, charCode);
|
|
break;
|
|
case 3:
|
|
args.push(key, location, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
|
|
break;
|
|
case 4:
|
|
args.push(key, location, modifiers, repeat, locale);
|
|
break;
|
|
default:
|
|
args.push(char, key, location, modifiers, repeat, locale);
|
|
}
|
|
out.initKeyboardEvent.apply(out, args);
|
|
} else {
|
|
out.initEvent(type, bubbles, cancelable);
|
|
}
|
|
for (key in out) {
|
|
if (defaults.hasOwnProperty(key) && out[key] !== init[key]) {
|
|
withInitValues(key, out, init);
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
KeyboardEvent.prototype = $KeyboardEvent.prototype;
|
|
return KeyboardEvent;
|
|
})(window.KeyboardEvent || function KeyboardEvent() {});
|
|
defineProperty(window, 'KeyboardEvent', { value: o_O });
|
|
// Android 4 gotcha
|
|
if (KeyboardEvent !== o_O) KeyboardEvent = o_O;
|
|
}
|
|
|
|
// window.MouseEvent as constructor
|
|
try {
|
|
new MouseEvent('_', {});
|
|
} catch (o_O) {
|
|
/* jshint -W022 */
|
|
o_O = (function ($MouseEvent) {
|
|
function MouseEvent(type, init) {
|
|
enoughArguments(arguments.length, 'MouseEvent');
|
|
var out = document.createEvent('MouseEvent');
|
|
if (!init) init = {};
|
|
out.initMouseEvent(
|
|
type,
|
|
!!init.bubbles,
|
|
!!init.cancelable,
|
|
init.view || window,
|
|
init.detail || 1,
|
|
init.screenX || 0,
|
|
init.screenY || 0,
|
|
init.clientX || 0,
|
|
init.clientY || 0,
|
|
!!init.ctrlKey,
|
|
!!init.altKey,
|
|
!!init.shiftKey,
|
|
!!init.metaKey,
|
|
init.button || 0,
|
|
init.relatedTarget || null
|
|
);
|
|
return out;
|
|
}
|
|
MouseEvent.prototype = $MouseEvent.prototype;
|
|
return MouseEvent;
|
|
})(window.MouseEvent || function MouseEvent() {});
|
|
defineProperty(window, 'MouseEvent', { value: o_O });
|
|
// Android 4 gotcha
|
|
if (MouseEvent !== o_O) MouseEvent = o_O;
|
|
}
|
|
|
|
if (!document.querySelectorAll('*').forEach) {
|
|
(function () {
|
|
function patch(what) {
|
|
var querySelectorAll = what.querySelectorAll;
|
|
what.querySelectorAll = function qSA(css) {
|
|
var result = querySelectorAll.call(this, css);
|
|
result.forEach = Array.prototype.forEach;
|
|
return result;
|
|
};
|
|
}
|
|
patch(document);
|
|
patch(Element.prototype);
|
|
})();
|
|
}
|
|
|
|
try {
|
|
// https://drafts.csswg.org/selectors-4/#the-scope-pseudo
|
|
document.querySelector(':scope *');
|
|
} catch (o_O) {
|
|
(function () {
|
|
var dataScope = 'data-scope-' + ((Math.random() * 1e9) >>> 0);
|
|
var proto = Element.prototype;
|
|
var querySelector = proto.querySelector;
|
|
var querySelectorAll = proto.querySelectorAll;
|
|
proto.querySelector = function qS(css) {
|
|
return find(this, querySelector, css);
|
|
};
|
|
proto.querySelectorAll = function qSA(css) {
|
|
return find(this, querySelectorAll, css);
|
|
};
|
|
function find(node, method, css) {
|
|
node.setAttribute(dataScope, null);
|
|
var result = method.call(
|
|
node,
|
|
String(css).replace(/(^|,\s*)(:scope([ >]|$))/g, function ($0, $1, $2, $3) {
|
|
return $1 + '[' + dataScope + ']' + ($3 || ' ');
|
|
})
|
|
);
|
|
node.removeAttribute(dataScope);
|
|
return result;
|
|
}
|
|
})();
|
|
}
|
|
})(window);
|
|
(function (global) {
|
|
'use strict';
|
|
|
|
// a WeakMap fallback for DOM nodes only used as key
|
|
var DOMMap =
|
|
global.WeakMap ||
|
|
(function () {
|
|
var counter = 0,
|
|
dispatched = false,
|
|
drop = false,
|
|
value;
|
|
|
|
function dispatch(key, ce, shouldDrop) {
|
|
drop = shouldDrop;
|
|
dispatched = false;
|
|
value = undefined;
|
|
key.dispatchEvent(ce);
|
|
}
|
|
|
|
function Handler(value) {
|
|
this.value = value;
|
|
}
|
|
|
|
Handler.prototype.handleEvent = function handleEvent(e) {
|
|
dispatched = true;
|
|
if (drop) {
|
|
e.currentTarget.removeEventListener(e.type, this, false);
|
|
} else {
|
|
value = this.value;
|
|
}
|
|
};
|
|
|
|
function DOMMap() {
|
|
counter++; // make id clashing highly improbable
|
|
this.__ce__ = new Event('@DOMMap:' + counter + Math.random());
|
|
}
|
|
|
|
DOMMap.prototype = {
|
|
'constructor': DOMMap,
|
|
'delete': function del(key) {
|
|
return dispatch(key, this.__ce__, true), dispatched;
|
|
},
|
|
'get': function get(key) {
|
|
dispatch(key, this.__ce__, false);
|
|
var v = value;
|
|
value = undefined;
|
|
return v;
|
|
},
|
|
'has': function has(key) {
|
|
return dispatch(key, this.__ce__, false), dispatched;
|
|
},
|
|
'set': function set(key, value) {
|
|
dispatch(key, this.__ce__, true);
|
|
key.addEventListener(this.__ce__.type, new Handler(value), false);
|
|
return this;
|
|
},
|
|
};
|
|
|
|
return DOMMap;
|
|
})();
|
|
|
|
function Dict() {}
|
|
Dict.prototype = (Object.create || Object)(null);
|
|
|
|
// https://dom.spec.whatwg.org/#interface-eventtarget
|
|
|
|
function createEventListener(type, callback, options) {
|
|
function eventListener(e) {
|
|
if (eventListener.once) {
|
|
e.currentTarget.removeEventListener(e.type, callback, eventListener);
|
|
eventListener.removed = true;
|
|
}
|
|
if (eventListener.passive) {
|
|
e.preventDefault = createEventListener.preventDefault;
|
|
}
|
|
if (typeof eventListener.callback === 'function') {
|
|
/* jshint validthis: true */
|
|
eventListener.callback.call(this, e);
|
|
} else if (eventListener.callback) {
|
|
eventListener.callback.handleEvent(e);
|
|
}
|
|
if (eventListener.passive) {
|
|
delete e.preventDefault;
|
|
}
|
|
}
|
|
eventListener.type = type;
|
|
eventListener.callback = callback;
|
|
eventListener.capture = !!options.capture;
|
|
eventListener.passive = !!options.passive;
|
|
eventListener.once = !!options.once;
|
|
// currently pointless but specs say to use it, so ...
|
|
eventListener.removed = false;
|
|
return eventListener;
|
|
}
|
|
|
|
createEventListener.preventDefault = function preventDefault() {};
|
|
|
|
var Event = global.CustomEvent,
|
|
dE = global.dispatchEvent,
|
|
aEL = global.addEventListener,
|
|
rEL = global.removeEventListener,
|
|
counter = 0,
|
|
increment = function () {
|
|
counter++;
|
|
},
|
|
indexOf =
|
|
[].indexOf ||
|
|
function indexOf(value) {
|
|
var length = this.length;
|
|
while (length--) {
|
|
if (this[length] === value) {
|
|
break;
|
|
}
|
|
}
|
|
return length;
|
|
},
|
|
getListenerKey = function (options) {
|
|
return ''.concat(options.capture ? '1' : '0', options.passive ? '1' : '0', options.once ? '1' : '0');
|
|
},
|
|
augment;
|
|
|
|
try {
|
|
aEL('_', increment, { once: true });
|
|
dE(new Event('_'));
|
|
dE(new Event('_'));
|
|
rEL('_', increment, { once: true });
|
|
} catch (o_O) {}
|
|
|
|
if (counter !== 1) {
|
|
(function () {
|
|
var dm = new DOMMap();
|
|
function createAEL(aEL) {
|
|
return function addEventListener(type, handler, options) {
|
|
if (options && typeof options !== 'boolean') {
|
|
var info = dm.get(this),
|
|
key = getListenerKey(options),
|
|
i,
|
|
tmp,
|
|
wrap;
|
|
if (!info) dm.set(this, (info = new Dict()));
|
|
if (!(type in info))
|
|
info[type] = {
|
|
handler: [],
|
|
wrap: [],
|
|
};
|
|
tmp = info[type];
|
|
i = indexOf.call(tmp.handler, handler);
|
|
if (i < 0) {
|
|
i = tmp.handler.push(handler) - 1;
|
|
tmp.wrap[i] = wrap = new Dict();
|
|
} else {
|
|
wrap = tmp.wrap[i];
|
|
}
|
|
if (!(key in wrap)) {
|
|
wrap[key] = createEventListener(type, handler, options);
|
|
aEL.call(this, type, wrap[key], wrap[key].capture);
|
|
}
|
|
} else {
|
|
aEL.call(this, type, handler, options);
|
|
}
|
|
};
|
|
}
|
|
function createREL(rEL) {
|
|
return function removeEventListener(type, handler, options) {
|
|
if (options && typeof options !== 'boolean') {
|
|
var info = dm.get(this),
|
|
key,
|
|
i,
|
|
tmp,
|
|
wrap;
|
|
if (info && type in info) {
|
|
tmp = info[type];
|
|
i = indexOf.call(tmp.handler, handler);
|
|
if (-1 < i) {
|
|
key = getListenerKey(options);
|
|
wrap = tmp.wrap[i];
|
|
if (key in wrap) {
|
|
rEL.call(this, type, wrap[key], wrap[key].capture);
|
|
delete wrap[key];
|
|
// return if there are other wraps
|
|
for (key in wrap) return;
|
|
// otherwise remove all the things
|
|
tmp.handler.splice(i, 1);
|
|
tmp.wrap.splice(i, 1);
|
|
// if there are no other handlers
|
|
if (tmp.handler.length === 0)
|
|
// drop the info[type] entirely
|
|
delete info[type];
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
rEL.call(this, type, handler, options);
|
|
}
|
|
};
|
|
}
|
|
|
|
augment = function (Constructor) {
|
|
if (!Constructor) return;
|
|
var proto = Constructor.prototype;
|
|
proto.addEventListener = createAEL(proto.addEventListener);
|
|
proto.removeEventListener = createREL(proto.removeEventListener);
|
|
};
|
|
|
|
if (global.EventTarget) {
|
|
augment(EventTarget);
|
|
} else {
|
|
augment(global.Text);
|
|
augment(global.Element || global.HTMLElement);
|
|
augment(global.HTMLDocument);
|
|
augment(global.Window || { prototype: global });
|
|
augment(global.XMLHttpRequest);
|
|
}
|
|
})();
|
|
}
|
|
})(window);
|