mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 09:54:52 +00:00
837 lines
25 KiB
JavaScript
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));
|