Files
S.P.L.U.R.T-Station-13/tgui/packages/tgui-polyfill/ie8.js
2020-08-15 16:08:10 +08:00

837 lines
25 KiB
JavaScript

/**
* @file
* @copyright 2013 Andrea Giammarchi, WebReflection
* @license MIT
*/
/* eslint-disable */
(function(window){
/*! (C) WebReflection Mit Style License */
if (document.createEvent) return;
var
DUNNOABOUTDOMLOADED = true,
READYEVENTDISPATCHED = false,
ONREADYSTATECHANGE = 'onreadystatechange',
DOMCONTENTLOADED = 'DOMContentLoaded',
SECRET = '__IE8__' + Math.random(),
// Object = window.Object,
defineProperty = Object.defineProperty ||
// just in case ...
function (object, property, descriptor) {
object[property] = descriptor.value;
},
defineProperties = Object.defineProperties ||
// IE8 implemented defineProperty but not the plural...
function (object, descriptors) {
for(var key in descriptors) {
if (hasOwnProperty.call(descriptors, key)) {
try {
defineProperty(object, key, descriptors[key]);
} catch(o_O) {
if (window.console) {
console.log(key + ' failed on object:', object, o_O.message);
}
}
}
}
},
getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
hasOwnProperty = Object.prototype.hasOwnProperty,
// here IE7 will break like a charm
ElementPrototype = window.Element.prototype,
TextPrototype = window.Text.prototype,
// none of above native constructors exist/are exposed
possiblyNativeEvent = /^[a-z]+$/,
// ^ actually could probably be just /^[a-z]+$/
readyStateOK = /loaded|complete/,
types = {},
div = document.createElement('div'),
html = document.documentElement,
removeAttribute = html.removeAttribute,
setAttribute = html.setAttribute,
valueDesc = function (value) {
return {
enumerable: true,
writable: true,
configurable: true,
value: value
};
}
;
function commonEventLoop(currentTarget, e, $handlers, synthetic) {
for(var
handler,
continuePropagation,
handlers = $handlers.slice(),
evt = enrich(e, currentTarget),
i = 0, length = handlers.length; i < length; i++
) {
handler = handlers[i];
if (typeof handler === 'object') {
if (typeof handler.handleEvent === 'function') {
handler.handleEvent(evt);
}
} else {
handler.call(currentTarget, evt);
}
if (evt.stoppedImmediatePropagation) break;
}
continuePropagation = !evt.stoppedPropagation;
/*
if (continuePropagation && !synthetic && !live(currentTarget)) {
evt.cancelBubble = true;
}
*/
return (
synthetic &&
continuePropagation &&
currentTarget.parentNode
) ?
currentTarget.parentNode.dispatchEvent(evt) :
!evt.defaultPrevented
;
}
function commonDescriptor(get, set) {
return {
// if you try with enumerable: true
// IE8 will miserably fail
configurable: true,
get: get,
set: set
};
}
function commonTextContent(protoDest, protoSource, property) {
var descriptor = getOwnPropertyDescriptor(
protoSource || protoDest, property
);
defineProperty(
protoDest,
'textContent',
commonDescriptor(
function () {
return descriptor.get.call(this);
},
function (textContent) {
descriptor.set.call(this, textContent);
}
)
);
}
function enrich(e, currentTarget) {
e.currentTarget = currentTarget;
e.eventPhase = (
// AT_TARGET : BUBBLING_PHASE
e.target === e.currentTarget ? 2 : 3
);
return e;
}
function find(array, value) {
var i = array.length;
while(i-- && array[i] !== value);
return i;
}
function getTextContent() {
if (this.tagName === 'BR') return '\n';
var
textNode = this.firstChild,
arrayContent = []
;
while(textNode) {
if (textNode.nodeType !== 8 && textNode.nodeType !== 7) {
arrayContent.push(textNode.textContent);
}
textNode = textNode.nextSibling;
}
return arrayContent.join('');
}
function live(self) {
return self.nodeType !== 9 && html.contains(self);
}
function onkeyup(e) {
var evt = document.createEvent('Event');
evt.initEvent('input', true, true);
(e.srcElement || e.fromElement || document).dispatchEvent(evt);
}
function onReadyState(e) {
if (!READYEVENTDISPATCHED && readyStateOK.test(
document.readyState
)) {
READYEVENTDISPATCHED = !READYEVENTDISPATCHED;
document.detachEvent(ONREADYSTATECHANGE, onReadyState);
e = document.createEvent('Event');
e.initEvent(DOMCONTENTLOADED, true, true);
document.dispatchEvent(e);
}
}
function getter(attr) {
return function() {
return html[attr] || (document.body && document.body[attr]) || 0;
};
}
function setTextContent(textContent) {
var node;
while ((node = this.lastChild)) {
this.removeChild(node);
}
/*jshint eqnull:true */
if (textContent != null) {
this.appendChild(document.createTextNode(textContent));
}
}
function verify(self, e) {
if (!e) {
e = window.event;
}
if (!e.target) {
e.target = e.srcElement || e.fromElement || document;
}
if (!e.timeStamp) {
e.timeStamp = (new Date()).getTime();
}
return e;
}
// normalized textContent for:
// comment, script, style, text, title
commonTextContent(
window.HTMLCommentElement.prototype,
ElementPrototype,
'nodeValue'
);
commonTextContent(
window.HTMLScriptElement.prototype,
null,
'text'
);
commonTextContent(
TextPrototype,
null,
'nodeValue'
);
commonTextContent(
window.HTMLTitleElement.prototype,
null,
'text'
);
defineProperty(
window.HTMLStyleElement.prototype,
'textContent',
(function(descriptor){
return commonDescriptor(
function () {
return descriptor.get.call(this.styleSheet);
},
function (textContent) {
descriptor.set.call(this.styleSheet, textContent);
}
);
}(getOwnPropertyDescriptor(window.CSSStyleSheet.prototype, 'cssText')))
);
var opacityre = /\b\s*alpha\s*\(\s*opacity\s*=\s*(\d+)\s*\)/;
defineProperty(
window.CSSStyleDeclaration.prototype,
'opacity', {
get: function() {
var m = this.filter.match(opacityre);
return m ? (m[1] / 100).toString() : '';
},
set: function(value) {
this.zoom = 1;
var found = false;
if (value < 1) {
value = ' alpha(opacity=' + Math.round(value * 100) + ')';
}
else {
value = '';
}
this.filter = this.filter.replace(opacityre,
function() { found = true; return value; });
if (!found && value) {
this.filter += value;
}
}
}
);
defineProperties(
ElementPrototype,
{
// bonus
textContent: {
get: getTextContent,
set: setTextContent
},
// http://www.w3.org/TR/ElementTraversal/#interface-elementTraversal
firstElementChild: {
get: function () {
for(var
childNodes = this.childNodes || [],
i = 0, length = childNodes.length;
i < length; i++
) {
if (childNodes[i].nodeType == 1) return childNodes[i];
}
}
},
lastElementChild: {
get: function () {
for(var
childNodes = this.childNodes || [],
i = childNodes.length;
i--;
) {
if (childNodes[i].nodeType == 1) return childNodes[i];
}
}
},
oninput: {
get: function () {
return this._oninput || null;
},
set: function (oninput) {
if (this._oninput) {
this.removeEventListener('input', this._oninput);
this._oninput = oninput;
if (oninput) {
this.addEventListener('input', oninput);
}
}
}
},
previousElementSibling: {
get: function () {
var previousElementSibling = this.previousSibling;
while (previousElementSibling && previousElementSibling.nodeType != 1) {
previousElementSibling = previousElementSibling.previousSibling;
}
return previousElementSibling;
}
},
nextElementSibling: {
get: function () {
var nextElementSibling = this.nextSibling;
while (nextElementSibling && nextElementSibling.nodeType != 1) {
nextElementSibling = nextElementSibling.nextSibling;
}
return nextElementSibling;
}
},
childElementCount: {
get: function () {
for(var
count = 0,
childNodes = this.childNodes || [],
i = childNodes.length; i--; count += childNodes[i].nodeType == 1
);
return count;
}
},
/*
// children would be an override
// IE8 already supports them but with comments too
// not just nodeType 1
children: {
get: function () {
for(var
children = [],
childNodes = this.childNodes || [],
i = 0, length = childNodes.length;
i < length; i++
) {
if (childNodes[i].nodeType == 1) {
children.push(childNodes[i]);
}
}
return children;
}
},
*/
// DOM Level 2 EventTarget methods and events
addEventListener: valueDesc(function (type, handler, capture) {
if (typeof handler !== 'function' && typeof handler !== 'object') return;
var
self = this,
ontype = 'on' + type,
temple = self[SECRET] ||
defineProperty(
self, SECRET, {value: {}}
)[SECRET],
currentType = temple[ontype] || (temple[ontype] = {}),
handlers = currentType.h || (currentType.h = []),
e, attr
;
if (!hasOwnProperty.call(currentType, 'w')) {
currentType.w = function (e) {
// e[SECRET] is a silent notification needed to avoid
// fired events during live test
return e[SECRET] || commonEventLoop(self, verify(self, e), handlers, false);
};
// if not detected yet
if (!hasOwnProperty.call(types, ontype)) {
// and potentially a native event
if(possiblyNativeEvent.test(type)) {
// do this heavy thing
try {
// TODO: should I consider tagName too so that
// INPUT[ontype] could be different ?
e = document.createEventObject();
// do not clone ever a node
// specially a document one ...
// use the secret to ignore them all
e[SECRET] = true;
// document a part if a node has never been
// added to any other node, fireEvent might
// behave very weirdly (read: trigger unspecified errors)
if (self.nodeType != 9) {
/*jshint eqnull:true */
if (self.parentNode == null) {
div.appendChild(self);
}
if ((attr = self.getAttribute(ontype))) {
removeAttribute.call(self, ontype);
}
}
self.fireEvent(ontype, e);
types[ontype] = true;
} catch(meh) {
types[ontype] = false;
while (div.hasChildNodes()) {
div.removeChild(div.firstChild);
}
}
if (attr != null) {
setAttribute.call(self, ontype, attr);
}
} else {
// no need to bother since
// 'x-event' ain't native for sure
types[ontype] = false;
}
}
if ((currentType.n = types[ontype])) {
self.attachEvent(ontype, currentType.w);
}
}
if (find(handlers, handler) < 0) {
handlers[capture ? 'unshift' : 'push'](handler);
}
if (type === 'input') {
self.attachEvent('onkeyup', onkeyup);
}
}),
dispatchEvent: valueDesc(function (e) {
var
self = this,
ontype = 'on' + e.type,
temple = self[SECRET],
currentType = temple && temple[ontype],
valid = !!currentType,
parentNode
;
if (!e.target) e.target = self;
return (valid ? (
currentType.n /* && live(self) */ ?
self.fireEvent(ontype, e) :
commonEventLoop(
self,
e,
currentType.h,
true
)
) : (
(parentNode = self.parentNode) /* && live(self) */ ?
parentNode.dispatchEvent(e) :
true
)), !e.defaultPrevented;
}),
removeEventListener: valueDesc(function (type, handler, capture) {
if (typeof handler !== 'function' && typeof handler !== 'object') return;
var
self = this,
ontype = 'on' + type,
temple = self[SECRET],
currentType = temple && temple[ontype],
handlers = currentType && currentType.h,
i = handlers ? find(handlers, handler) : -1
;
if (-1 < i) handlers.splice(i, 1);
})
}
);
/* this is not needed in IE8
defineProperties(window.HTMLSelectElement.prototype, {
value: {
get: function () {
return this.options[this.selectedIndex].value;
}
}
});
//*/
// EventTarget methods for Text nodes too
defineProperties(TextPrototype, {
addEventListener: valueDesc(ElementPrototype.addEventListener),
dispatchEvent: valueDesc(ElementPrototype.dispatchEvent),
removeEventListener: valueDesc(ElementPrototype.removeEventListener)
});
defineProperties(
window.XMLHttpRequest.prototype,
{
addEventListener: valueDesc(function (type, handler, capture) {
var
self = this,
ontype = 'on' + type,
temple = self[SECRET] ||
defineProperty(
self, SECRET, {value: {}}
)[SECRET],
currentType = temple[ontype] || (temple[ontype] = {}),
handlers = currentType.h || (currentType.h = [])
;
if (find(handlers, handler) < 0) {
if (!self[ontype]) {
self[ontype] = function () {
var e = document.createEvent('Event');
e.initEvent(type, true, true);
self.dispatchEvent(e);
};
}
handlers[capture ? 'unshift' : 'push'](handler);
}
}),
dispatchEvent: valueDesc(function (e) {
var
self = this,
ontype = 'on' + e.type,
temple = self[SECRET],
currentType = temple && temple[ontype],
valid = !!currentType
;
return valid && (
currentType.n /* && live(self) */ ?
self.fireEvent(ontype, e) :
commonEventLoop(
self,
e,
currentType.h,
true
)
);
}),
removeEventListener: valueDesc(ElementPrototype.removeEventListener)
}
);
var buttonGetter = getOwnPropertyDescriptor(Event.prototype, 'button').get;
defineProperties(
window.Event.prototype,
{
bubbles: valueDesc(true),
cancelable: valueDesc(true),
preventDefault: valueDesc(function () {
if (this.cancelable) {
this.returnValue = false;
}
}),
stopPropagation: valueDesc(function () {
this.stoppedPropagation = true;
this.cancelBubble = true;
}),
stopImmediatePropagation: valueDesc(function () {
this.stoppedImmediatePropagation = true;
this.stopPropagation();
}),
initEvent: valueDesc(function(type, bubbles, cancelable){
this.type = type;
this.bubbles = !!bubbles;
this.cancelable = !!cancelable;
if (!this.bubbles) {
this.stopPropagation();
}
}),
pageX: {get: function(){ return this._pageX || (this._pageX = this.clientX + window.scrollX - (html.clientLeft || 0)); }},
pageY: {get: function(){ return this._pageY || (this._pageY = this.clientY + window.scrollY - (html.clientTop || 0)); }},
which: {get: function(){ return this.keyCode ? this.keyCode : (isNaN(this.button) ? undefined : this.button + 1); }},
charCode: {get: function(){ return (this.keyCode && this.type == 'keypress') ? this.keyCode : 0; }},
buttons: {get: function(){ return buttonGetter.call(this); }},
button: {get: function() {
var buttons = this.buttons;
return (buttons & 1 ? 0 : (buttons & 2 ? 2 : (buttons & 4 ? 1 : undefined)));
}},
defaultPrevented: {get: function() {
// if preventDefault() was never called, or returnValue not given a value
// then returnValue is undefined
var returnValue = this.returnValue, undef;
return !(returnValue === undef || returnValue);
}},
relatedTarget: {get: function() {
var type = this.type;
if (type === 'mouseover') {
return this.fromElement;
} else if (type === 'mouseout') {
return this.toElement;
} else {
return null;
}
}}
}
);
defineProperties(
window.HTMLDocument.prototype,
{
defaultView: {
get: function () {
return this.parentWindow;
}
},
textContent: {
get: function () {
return this.nodeType === 11 ? getTextContent.call(this) : null;
},
set: function (textContent) {
if (this.nodeType === 11) {
setTextContent.call(this, textContent);
}
}
},
addEventListener: valueDesc(function(type, handler, capture) {
var self = this;
ElementPrototype.addEventListener.call(self, type, handler, capture);
// NOTE: it won't fire if already loaded, this is NOT a $.ready() shim!
// this behaves just like standard browsers
if (
DUNNOABOUTDOMLOADED &&
type === DOMCONTENTLOADED &&
!readyStateOK.test(
self.readyState
)
) {
DUNNOABOUTDOMLOADED = false;
self.attachEvent(ONREADYSTATECHANGE, onReadyState);
/* global top */
if (window == top) {
(function gonna(e){try{
self.documentElement.doScroll('left');
onReadyState();
}catch(o_O){
setTimeout(gonna, 50);
}}());
}
}
}),
dispatchEvent: valueDesc(ElementPrototype.dispatchEvent),
removeEventListener: valueDesc(ElementPrototype.removeEventListener),
createEvent: valueDesc(function(Class){
var e;
if (Class !== 'Event') throw new Error('unsupported ' + Class);
e = document.createEventObject();
e.timeStamp = (new Date()).getTime();
return e;
})
}
);
defineProperties(
window.Window.prototype,
{
getComputedStyle: valueDesc(function(){
var // partially grabbed from jQuery and Dean's hack
notpixel = /^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,
position = /^(top|right|bottom|left)$/,
re = /\-([a-z])/g,
place = function (match, $1) {
return $1.toUpperCase();
}
;
function ComputedStyle(_) {
this._ = _;
}
ComputedStyle.prototype.getPropertyValue = function (name) {
var
el = this._,
style = el.style,
currentStyle = el.currentStyle,
runtimeStyle = el.runtimeStyle,
result,
left,
rtLeft
;
if (name == 'opacity') {
return style.opacity || '1';
}
name = (name === 'float' ? 'style-float' : name).replace(re, place);
result = currentStyle ? currentStyle[name] : style[name];
if (notpixel.test(result) && !position.test(name)) {
left = style.left;
rtLeft = runtimeStyle && runtimeStyle.left;
if (rtLeft) {
runtimeStyle.left = currentStyle.left;
}
style.left = name === 'fontSize' ? '1em' : result;
result = style.pixelLeft + 'px';
style.left = left;
if (rtLeft) {
runtimeStyle.left = rtLeft;
}
}
/*jshint eqnull:true */
return result == null ?
result : ((result + '') || 'auto');
};
// unsupported
function PseudoComputedStyle() {}
PseudoComputedStyle.prototype.getPropertyValue = function () {
return null;
};
return function (el, pseudo) {
return pseudo ?
new PseudoComputedStyle(el) :
new ComputedStyle(el);
};
}()),
addEventListener: valueDesc(function (type, handler, capture) {
var
self = window,
ontype = 'on' + type,
handlers
;
if (!self[ontype]) {
self[ontype] = function(e) {
return commonEventLoop(self, verify(self, e), handlers, false) && undefined;
};
}
handlers = self[ontype][SECRET] || (
self[ontype][SECRET] = []
);
if (find(handlers, handler) < 0) {
handlers[capture ? 'unshift' : 'push'](handler);
}
}),
dispatchEvent: valueDesc(function (e) {
var method = window['on' + e.type];
return method ? method.call(window, e) !== false && !e.defaultPrevented : true;
}),
removeEventListener: valueDesc(function (type, handler, capture) {
var
ontype = 'on' + type,
handlers = (window[ontype] || Object)[SECRET],
i = handlers ? find(handlers, handler) : -1
;
if (-1 < i) handlers.splice(i, 1);
}),
pageXOffset: {get: getter('scrollLeft')},
pageYOffset: {get: getter('scrollTop')},
scrollX: {get: getter('scrollLeft')},
scrollY: {get: getter('scrollTop')},
innerWidth: {get: getter('clientWidth')},
innerHeight: {get: getter('clientHeight')}
}
);
window.HTMLElement = window.Element;
(function (styleSheets, HTML5Element, i) {
for (i = 0; i < HTML5Element.length; i++) document.createElement(HTML5Element[i]);
if (!styleSheets.length) document.createStyleSheet('');
styleSheets[0].addRule(HTML5Element.join(','), 'display:block;');
}(document.styleSheets, ['header', 'nav', 'section', 'article', 'aside', 'footer']));
(function () {
if (document.createRange) return;
document.createRange = function createRange() {
return new Range();
};
function getContents(start, end) {
var nodes = [start];
while (start !== end) {
nodes.push(start = start.nextSibling);
}
return nodes;
}
function Range() {}
var proto = Range.prototype;
proto.cloneContents = function cloneContents() {
for (var
fragment = this._start.ownerDocument.createDocumentFragment(),
nodes = getContents(this._start, this._end),
i = 0,
length = nodes.length;
i < length; i++
) {
fragment.appendChild(nodes[i].cloneNode(true));
}
return fragment;
};
proto.cloneRange = function cloneRange() {
var range = new Range();
range._start = this._start;
range._end = this._end;
return range;
};
proto.deleteContents = function deleteContents() {
for (var
parentNode = this._start.parentNode,
nodes = getContents(this._start, this._end),
i = 0,
length = nodes.length;
i < length; i++
) {
parentNode.removeChild(nodes[i]);
}
};
proto.extractContents = function extractContents() {
for (var
fragment = this._start.ownerDocument.createDocumentFragment(),
nodes = getContents(this._start, this._end),
i = 0,
length = nodes.length;
i < length; i++
) {
fragment.appendChild(nodes[i]);
}
return fragment;
};
proto.setEndAfter = function setEndAfter(node) {
this._end = node;
};
proto.setEndBefore = function setEndBefore(node) {
this._end = node.previousSibling;
};
proto.setStartAfter = function setStartAfter(node) {
this._start = node.nextSibling;
};
proto.setStartBefore = function setStartBefore(node) {
this._start = node;
};
}());
}(window));