Permalink
Fetching contributors…
Cannot retrieve contributors at this time
1895 lines (1670 sloc) 59.1 KB
// Composited file - DO NOT EDIT
(function(global) {
'use strict';
if (!('window' in global && 'document' in global))
return;
//----------------------------------------------------------------------
//
// HTML
// https://html.spec.whatwg.org
//
//----------------------------------------------------------------------
// document.head attribute
// Needed for: IE8-
if (!('head' in document))
document.head = document.getElementsByTagName('head')[0];
// Ensure correct parsing of newish elements ("shiv")
// Needed for: IE8-
[
'abbr', 'article', 'aside', 'audio', 'bdi', 'canvas', 'data', 'datalist',
'details', 'dialog', 'figcaption', 'figure', 'footer', 'header', 'hgroup',
'main', 'mark', 'meter', 'nav', 'output', 'picture', 'progress', 'section',
'summary', 'template', 'time', 'video'].forEach(function(tag) {
document.createElement(tag);
});
// HTMLElement.dataset
// Needed for: IE10-
if (!('dataset' in document.createElement('span')) &&
'Element' in global && Element.prototype && Object.defineProperty) {
Object.defineProperty(Element.prototype, 'dataset', { get: function() {
var result = Object.create(null);
for (var i = 0; i < this.attributes.length; ++i) {
var attr = this.attributes[i];
if (attr.specified && attr.name.substring(0, 5) === 'data-') {
(function(element, name) {
var prop = name.replace(/-([a-z])/g, function(m, p) {
return p.toUpperCase();
});
result[prop] = element.getAttribute('data-' + name); // Read-only, for IE8-
Object.defineProperty(result, prop, {
get: function() {
return element.getAttribute('data-' + name);
},
set: function(value) {
element.setAttribute('data-' + name, value);
}});
}(this, attr.name.substring(5)));
}
}
return result;
}});
}
// Base64 utility methods
// Needed for: IE9-
(function() {
if ('atob' in global && 'btoa' in global)
return;
var B64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function atob(input) {
input = String(input);
var position = 0,
output = [],
buffer = 0, bits = 0, n;
input = input.replace(/\s/g, '');
if ((input.length % 4) === 0) { input = input.replace(/=+$/, ''); }
if ((input.length % 4) === 1) { throw Error("InvalidCharacterError"); }
if (/[^+/0-9A-Za-z]/.test(input)) { throw Error("InvalidCharacterError"); }
while (position < input.length) {
n = B64_ALPHABET.indexOf(input.charAt(position));
buffer = (buffer << 6) | n;
bits += 6;
if (bits === 24) {
output.push(String.fromCharCode((buffer >> 16) & 0xFF));
output.push(String.fromCharCode((buffer >> 8) & 0xFF));
output.push(String.fromCharCode(buffer & 0xFF));
bits = 0;
buffer = 0;
}
position += 1;
}
if (bits === 12) {
buffer = buffer >> 4;
output.push(String.fromCharCode(buffer & 0xFF));
} else if (bits === 18) {
buffer = buffer >> 2;
output.push(String.fromCharCode((buffer >> 8) & 0xFF));
output.push(String.fromCharCode(buffer & 0xFF));
}
return output.join('');
};
function btoa(input) {
input = String(input);
var position = 0,
out = [],
o1, o2, o3,
e1, e2, e3, e4;
if (/[^\x00-\xFF]/.test(input)) { throw Error("InvalidCharacterError"); }
while (position < input.length) {
o1 = input.charCodeAt(position++);
o2 = input.charCodeAt(position++);
o3 = input.charCodeAt(position++);
// 111111 112222 222233 333333
e1 = o1 >> 2;
e2 = ((o1 & 0x3) << 4) | (o2 >> 4);
e3 = ((o2 & 0xf) << 2) | (o3 >> 6);
e4 = o3 & 0x3f;
if (position === input.length + 2) {
e3 = 64;
e4 = 64;
}
else if (position === input.length + 1) {
e4 = 64;
}
out.push(B64_ALPHABET.charAt(e1),
B64_ALPHABET.charAt(e2),
B64_ALPHABET.charAt(e3),
B64_ALPHABET.charAt(e4));
}
return out.join('');
};
global.atob = atob;
global.btoa = btoa;
}());
// requestAnimationFrame - needed for IE9-
(function() {
if ('requestAnimationFrame' in global)
return;
var TARGET_FPS = 60,
requests = Object.create(null),
raf_handle = 0,
timeout_handle = -1;
function isVisible(element) {
return element.offsetWidth > 0 && element.offsetHeight > 0;
}
function onFrameTimer() {
var cur_requests = requests;
requests = Object.create(null);
timeout_handle = -1;
Object.keys(cur_requests).forEach(function(id) {
var request = cur_requests[id];
if (!request.element || isVisible(request.element))
request.callback(Date.now());
});
}
function requestAnimationFrame(callback, element) {
var cb_handle = ++raf_handle;
requests[cb_handle] = {callback: callback, element: element};
if (timeout_handle === -1)
timeout_handle = global.setTimeout(onFrameTimer, 1000 / TARGET_FPS);
return cb_handle;
}
function cancelAnimationFrame(handle) {
delete requests[handle];
if (Object.keys(requests).length === 0) {
global.clearTimeout(timeout_handle);
timeout_handle = -1;
}
}
global.requestAnimationFrame = requestAnimationFrame;
global.cancelAnimationFrame = cancelAnimationFrame;
}());
}(self));
(function(global) {
'use strict';
if (!('window' in global && 'document' in global))
return;
//----------------------------------------------------------------------
//
// DOM
// https://dom.spec.whatwg.org/
//
//----------------------------------------------------------------------
// Document.querySelectorAll method
// http://ajaxian.com/archives/creating-a-queryselector-for-ie-that-runs-at-native-speed
// Needed for: IE7-
if (!document.querySelectorAll) {
document.querySelectorAll = function(selectors) {
var style = document.createElement('style'), elements = [], element;
document.documentElement.firstChild.appendChild(style);
document._qsa = [];
style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
window.scrollBy(0, 0);
style.parentNode.removeChild(style);
while (document._qsa.length) {
element = document._qsa.shift();
element.style.removeAttribute('x-qsa');
elements.push(element);
}
document._qsa = null;
return elements;
};
}
// Document.querySelector method
// Needed for: IE7-
if (!document.querySelector) {
document.querySelector = function(selectors) {
var elements = document.querySelectorAll(selectors);
return (elements.length) ? elements[0] : null;
};
}
// Document.getElementsByClassName method
// Needed for: IE8-
if (!document.getElementsByClassName) {
document.getElementsByClassName = function(classNames) {
classNames = String(classNames).replace(/^|\s+/g, '.');
return document.querySelectorAll(classNames);
};
}
// Node interface constants
// Needed for: IE8-
global.Node = global.Node || function() { throw TypeError("Illegal constructor"); };
[
['ELEMENT_NODE', 1],
['ATTRIBUTE_NODE', 2],
['TEXT_NODE', 3],
['CDATA_SECTION_NODE', 4],
['ENTITY_REFERENCE_NODE', 5],
['ENTITY_NODE', 6],
['PROCESSING_INSTRUCTION_NODE', 7],
['COMMENT_NODE', 8],
['DOCUMENT_NODE', 9],
['DOCUMENT_TYPE_NODE', 10],
['DOCUMENT_FRAGMENT_NODE', 11],
['NOTATION_NODE', 12]
].forEach(function(p) { if (!(p[0] in global.Node)) global.Node[p[0]] = p[1]; });
// DOMException constants
// Needed for: IE8-
global.DOMException = global.DOMException || function() { throw TypeError("Illegal constructor"); };
[
['INDEX_SIZE_ERR', 1],
['DOMSTRING_SIZE_ERR', 2],
['HIERARCHY_REQUEST_ERR', 3],
['WRONG_DOCUMENT_ERR', 4],
['INVALID_CHARACTER_ERR', 5],
['NO_DATA_ALLOWED_ERR', 6],
['NO_MODIFICATION_ALLOWED_ERR', 7],
['NOT_FOUND_ERR', 8],
['NOT_SUPPORTED_ERR', 9],
['INUSE_ATTRIBUTE_ERR', 10],
['INVALID_STATE_ERR', 11],
['SYNTAX_ERR', 12],
['INVALID_MODIFICATION_ERR', 13],
['NAMESPACE_ERR', 14],
['INVALID_ACCESS_ERR', 15]
].forEach(function(p) { if (!(p[0] in global.DOMException)) global.DOMException[p[0]] = p[1]; });
// Event and EventTargets interfaces
// Needed for: IE8
(function(){
if (!('Element' in global) || Element.prototype.addEventListener || !Object.defineProperty)
return;
// interface Event
// PhaseType (const unsigned short)
Event.CAPTURING_PHASE = 1;
Event.AT_TARGET = 2;
Event.BUBBLING_PHASE = 3;
Object.defineProperties(Event.prototype, {
CAPTURING_PHASE: { get: function() { return 1; } },
AT_TARGET: { get: function() { return 2; } },
BUBBLING_PHASE: { get: function() { return 3; } },
target: {
get: function() {
return this.srcElement;
}},
currentTarget: {
get: function() {
return this._currentTarget;
}},
eventPhase: {
get: function() {
return (this.srcElement === this.currentTarget) ? Event.AT_TARGET : Event.BUBBLING_PHASE;
}},
bubbles: {
get: function() {
switch (this.type) {
// Mouse
case 'click':
case 'dblclick':
case 'mousedown':
case 'mouseup':
case 'mouseover':
case 'mousemove':
case 'mouseout':
case 'mousewheel':
// Keyboard
case 'keydown':
case 'keypress':
case 'keyup':
// Frame/Object
case 'resize':
case 'scroll':
// Form
case 'select':
case 'change':
case 'submit':
case 'reset':
return true;
}
return false;
}},
cancelable: {
get: function() {
switch (this.type) {
// Mouse
case 'click':
case 'dblclick':
case 'mousedown':
case 'mouseup':
case 'mouseover':
case 'mouseout':
case 'mousewheel':
// Keyboard
case 'keydown':
case 'keypress':
case 'keyup':
// Form
case 'submit':
return true;
}
return false;
}},
timeStamp: {
get: function() {
return this._timeStamp;
}},
stopPropagation: {
value: function() {
this.cancelBubble = true;
}},
preventDefault: {
value: function() {
this.returnValue = false;
}},
defaultPrevented: {
get: function() {
return this.returnValue === false;
}}
});
// interface EventTarget
function addEventListener(type, listener, useCapture) {
if (typeof listener !== 'function') return;
if (type === 'DOMContentLoaded') type = 'load';
var target = this;
var f = function(e) {
e._timeStamp = Date.now();
e._currentTarget = target;
listener.call(this, e);
e._currentTarget = null;
};
this['_' + type + listener] = f;
this.attachEvent('on' + type, f);
}
function removeEventListener(type, listener, useCapture) {
if (typeof listener !== 'function') return;
if (type === 'DOMContentLoaded') type = 'load';
var f = this['_' + type + listener];
if (f) {
this.detachEvent('on' + type, f);
this['_' + type + listener] = null;
}
}
[Window, HTMLDocument, Element].forEach(function(o) {
o.prototype.addEventListener = addEventListener;
o.prototype.removeEventListener = removeEventListener;
});
}());
// CustomEvent
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
// Needed for: IE
(function () {
if ('CustomEvent' in global && typeof global.CustomEvent === "function")
return;
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = global.Event.prototype;
global.CustomEvent = CustomEvent;
})();
// Shim for DOM Events for IE7-
// http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
// Use addEvent(object, event, handler) instead of object.addEventListener(event, handler)
window.addEvent = function(obj, type, fn) {
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj.attachEvent) {
obj["e" + type + fn] = fn;
obj[type + fn] = function() {
var e = window.event;
e.currentTarget = obj;
e.preventDefault = function() { e.returnValue = false; };
e.stopPropagation = function() { e.cancelBubble = true; };
e.target = e.srcElement;
e.timeStamp = Date.now();
obj["e" + type + fn].call(this, e);
};
obj.attachEvent("on" + type, obj[type + fn]);
}
};
window.removeEvent = function(obj, type, fn) {
if (obj.removeEventListener) {
obj.removeEventListener(type, fn, false);
} else if (obj.detachEvent) {
obj.detachEvent("on" + type, obj[type + fn]);
obj[type + fn] = null;
obj["e" + type + fn] = null;
}
};
// DOMTokenList interface and Element.classList / Element.relList
// Needed for: IE9-
// Use getClassList(elem) instead of elem.classList() if IE7- support is needed
// Use getRelList(elem) instead of elem.relList() if IE7- support is needed
(function() {
function DOMTokenListShim(o, p) {
function split(s) { return s.length ? s.split(/\s+/g) : []; }
// NOTE: This does not exactly match the spec.
function removeTokenFromString(token, string) {
var tokens = split(string),
index = tokens.indexOf(token);
if (index !== -1) {
tokens.splice(index, 1);
}
return tokens.join(' ');
}
Object.defineProperties(
this,
{
length: {
get: function() { return split(o[p]).length; }
},
item: {
value: function(idx) {
var tokens = split(o[p]);
return 0 <= idx && idx < tokens.length ? tokens[idx] : null;
}
},
contains: {
value: function(token) {
token = String(token);
if (token.length === 0) { throw SyntaxError(); }
if (/\s/.test(token)) { throw Error("InvalidCharacterError"); }
var tokens = split(o[p]);
return tokens.indexOf(token) !== -1;
}
},
add: {
value: function(/*tokens...*/) {
var tokens = Array.prototype.slice.call(arguments).map(String);
if (tokens.some(function(token) { return token.length === 0; })) {
throw SyntaxError();
}
if (tokens.some(function(token) { return (/\s/).test(token); })) {
throw Error("InvalidCharacterError");
}
try {
var underlying_string = o[p];
var token_list = split(underlying_string);
tokens = tokens.filter(function(token) { return token_list.indexOf(token) === -1; });
if (tokens.length === 0) {
return;
}
if (underlying_string.length !== 0 && !(/\s$/).test(underlying_string)) {
underlying_string += ' ';
}
underlying_string += tokens.join(' ');
o[p] = underlying_string;
} finally {
var length = split(o[p]).length;
if (this.length !== length) { this.length = length; }
}
}
},
remove: {
value: function(/*tokens...*/) {
var tokens = Array.prototype.slice.call(arguments).map(String);
if (tokens.some(function(token) { return token.length === 0; })) {
throw SyntaxError();
}
if (tokens.some(function(token) { return (/\s/).test(token); })) {
throw Error("InvalidCharacterError");
}
try {
var underlying_string = o[p];
tokens.forEach(function(token) {
underlying_string = removeTokenFromString(token, underlying_string);
});
o[p] = underlying_string;
} finally {
var length = split(o[p]).length;
if (this.length !== length) { this.length = length; }
}
}
},
toggle: {
value: function(token/*, force*/) {
var force = arguments[1];
try {
token = String(token);
if (token.length === 0) { throw SyntaxError(); }
if (/\s/.test(token)) { throw Error("InvalidCharacterError"); }
var tokens = split(o[p]),
index = tokens.indexOf(token);
if (index !== -1 && (!force || force === (void 0))) {
o[p] = removeTokenFromString(token, o[p]);
return false;
}
if (index !== -1 && force) {
return true;
}
var underlying_string = o[p];
if (underlying_string.length !== 0 && !/\s$/.test(underlying_string)) {
underlying_string += ' ';
}
underlying_string += token;
o[p] = underlying_string;
return true;
} finally {
var length = split(o[p]).length;
if (this.length !== length) { this.length = length; }
}
}
},
toString: {
value: function() {
return o[p];
}
}
});
if (!('length' in this)) {
// In case getters are not supported
this.length = split(o[p]).length;
} else {
// If they are, shim in index getters (up to 100)
for (var i = 0; i < 100; ++i) {
Object.defineProperty(this, String(i), {
get: (function(n) { return function() { return this.item(n); }; }(i))
});
}
}
}
function addToElementPrototype(p, f) {
if ('Element' in global && Element.prototype && Object.defineProperty) {
Object.defineProperty(Element.prototype, p, { get: f });
}
}
// HTML - https://html.spec.whatwg.org
// Element.classList
if ('classList' in document.createElement('span')) {
window.getClassList = function(elem) { return elem.classList; };
} else {
window.getClassList = function(elem) { return new DOMTokenListShim(elem, 'className'); };
addToElementPrototype('classList', function() { return new DOMTokenListShim(this, 'className'); } );
}
// HTML - https://html.spec.whatwg.org
// HTMLAnchorElement.relList
// HTMLLinkElement.relList
if ('relList' in document.createElement('link')) {
window.getRelList = function(elem) { return elem.relList; };
} else {
window.getRelList = function(elem) { return new DOMTokenListShim(elem, 'rel'); };
addToElementPrototype('relList', function() { return new DOMTokenListShim(this, 'rel'); } );
}
// Add second argument to native DOMTokenList.toggle() if necessary
(function() {
if (!('DOMTokenList' in global)) return;
var e = document.createElement('span');
if (!('classList' in e)) return;
e.classList.toggle('x', false);
if (!e.classList.contains('x')) return;
global.DOMTokenList.prototype.toggle = function toggle(token/*, force*/) {
var force = arguments[1];
if (force === undefined) {
var add = !this.contains(token);
this[add ? 'add' : 'remove'](token);
return add;
}
force = !!force;
this[force ? 'add' : 'remove'](token);
return force;
};
}());
// DOM - Interface NonDocumentTypeChildNode
// Interface NonDocumentTypeChildNode
// previousElementSibling / nextElementSibling - for IE8
if (!('previousElementSibling' in document.documentElement)) {
addToElementPrototype('previousElementSibling', function() {
var n = this.previousSibling;
while (n && n.nodeType !== Node.ELEMENT_NODE)
n = n.previousSibling;
return n;
});
}
if (!('nextElementSibling' in document.documentElement)) {
addToElementPrototype('nextElementSibling', function() {
var n = this.nextSibling;
while (n && n.nodeType !== Node.ELEMENT_NODE)
n = n.nextSibling;
return n;
});
}
}());
// Element.matches
// https://developer.mozilla.org/en/docs/Web/API/Element/matches
// Needed for: IE, Firefox 3.6, early Webkit and Opera 15.0
// Use msMatchesSelector(selector) for IE
// Use oMatchesSelector(selector) for Opera 15.0
// Use mozMatchesSelector(selector) for Firefox 3.6
// Use webkitMatchesSelector(selector) for early Webkit
// Use polyfill if no matches() support, but querySelectorAll() support
if ('Element' in global && !Element.prototype.matches) {
if (Element.prototype.msMatchesSelector) {
Element.prototype.matches = Element.prototype.msMatchesSelector;
} else if (Element.prototype.oMatchesSelector) {
Element.prototype.matches = Element.prototype.oMatchesSelector;
} else if (Element.prototype.mozMatchesSelector) {
Element.prototype.matches = Element.prototype.mozMatchesSelector;
} else if (Element.prototype.webkitMatchesSelector) {
Element.prototype.matches = Element.prototype.webkitMatchesSelector;
} else if (document.querySelectorAll) {
Element.prototype.matches = function matches(selector) {
var matches = (this.document || this.ownerDocument).querySelectorAll(selector),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
}
// Element.closest
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
if (window.Element && !Element.prototype.closest) {
Element.prototype.closest = function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i,
el = this;
do {
i = matches.length;
while (--i >= 0 && matches.item(i) !== el) {};
} while ((i < 0) && (el = el.parentElement));
return el;
};
}
function mixin(o, ps) {
if (!o) return;
Object.keys(ps).forEach(function(p) {
if ((p in o) || (p in o.prototype)) return;
try {
Object.defineProperty(
o.prototype,
p,
Object.getOwnPropertyDescriptor(ps, p)
);
} catch (ex) {
// Throws in IE8; just copy it
o[p] = ps[p];
}
});
}
// Mixin ParentNode
// https://dom.spec.whatwg.org/#interface-parentnode
function convertNodesIntoANode(nodes) {
var node = null;
nodes = nodes.map(function(node) {
return !(node instanceof Node) ? document.createTextNode(node) : node;
});
if (nodes.length === 1) {
node = nodes[0];
} else {
node = document.createDocumentFragment();
nodes.forEach(function(n) { node.appendChild(n); });
}
return node;
}
var ParentNode = {
prepend: function(/*...nodes*/) {
var nodes = [].slice.call(arguments);
nodes = convertNodesIntoANode(nodes);
this.insertBefore(nodes, this.firstChild);
},
append: function(/*...nodes*/) {
var nodes = [].slice.call(arguments);
nodes = convertNodesIntoANode(nodes);
this.appendChild(nodes);
}
};
mixin(global.Document || global.HTMLDocument, ParentNode); // HTMLDocument for IE8
mixin(global.DocumentFragment, ParentNode);
mixin(global.Element, ParentNode);
// Mixin ChildNode
// https://dom.spec.whatwg.org/#interface-childnode
var ChildNode = {
before: function(/*...nodes*/) {
var nodes = [].slice.call(arguments);
var parent = this.parentNode;
if (!parent) return;
var viablePreviousSibling = this.previousSibling;
while (nodes.indexOf(viablePreviousSibling) !== -1)
viablePreviousSibling = viablePreviousSibling.previousSibling;
var node = convertNodesIntoANode(nodes);
parent.insertBefore(node, viablePreviousSibling ?
viablePreviousSibling.nextSibling : parent.firstChild);
},
after: function(/*...nodes*/) {
var nodes = [].slice.call(arguments);
var parent = this.parentNode;
if (!parent) return;
var viableNextSibling = this.nextSibling;
while (nodes.indexOf(viableNextSibling) !== -1)
viableNextSibling = viableNextSibling.nextSibling;
var node = convertNodesIntoANode(nodes);
parent.insertBefore(node, viableNextSibling);
},
replaceWith: function(/*...nodes*/) {
var nodes = [].slice.call(arguments);
var parent = this.parentNode;
if (!parent) return;
var viableNextSibling = this.nextSibling;
while (nodes.indexOf(viableNextSibling) !== -1)
viableNextSibling = viableNextSibling.nextSibling;
var node = convertNodesIntoANode(nodes);
if (this.parentNode === parent)
parent.replaceChild(node, this);
else
parent.insertBefore(node, viableNextSibling);
},
remove: function() {
if (!this.parentNode) return;
this.parentNode.removeChild(this);
}
};
mixin(global.DocumentType, ChildNode);
mixin(global.Element, ChildNode);
mixin(global.CharacterData, ChildNode);
}(self));
(function(global) {
'use strict';
if (!('window' in global && 'document' in global))
return;
//----------------------------------------------------------------------
//
// XMLHttpRequest
// https://xhr.spec.whatwg.org
//
//----------------------------------------------------------------------
// XMLHttpRequest interface
// Needed for: IE7-
global.XMLHttpRequest = global.XMLHttpRequest || function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (_) { }
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (_) { }
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (_) { }
throw Error("This browser does not support XMLHttpRequest.");
};
// XMLHttpRequest interface constants
// Needed for IE8-
[
['UNSENT', 0],
['OPENED', 1],
['HEADERS_RECEIVED', 2],
['LOADING', 3],
['DONE', 4],
].forEach(function(p) { if (!(p[0] in global.XMLHttpRequest)) global.XMLHttpRequest[p[0]] = p[1]; });
// FormData interface
// Needed for: IE9-
(function() {
if ('FormData' in global)
return;
function FormData(form) {
this._data = [];
if (!form) return;
for (var i = 0; i < form.elements.length; ++i) {
var element = form.elements[i];
if (element.name !== '')
this.append(element.name, element.value);
}
}
FormData.prototype = {
append: function(name, value /*, filename */) {
if ('Blob' in global && value instanceof global.Blob)
throw TypeError("Blob not supported");
name = String(name);
this._data.push([name, value]);
},
toString: function() {
return this._data.map(function(pair) {
return encodeURIComponent(pair[0]) + '=' + encodeURIComponent(pair[1]);
}).join('&');
}
};
global.FormData = FormData;
var send = global.XMLHttpRequest.prototype.send;
global.XMLHttpRequest.prototype.send = function(body) {
if (body instanceof FormData) {
this.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
arguments[0] = body.toString();
}
return send.apply(this, arguments);
};
}());
}(self));
(function(global) {
'use strict';
if (!('window' in global && 'document' in global))
return;
//----------------------------------------------------------------------
//
// CSSOM View Module
// https://dev.w3.org/csswg/cssom-view/
//
//----------------------------------------------------------------------
// Fix for IE8-'s Element.getBoundingClientRect()
if ('TextRectangle' in global && !('width' in global.TextRectangle.prototype)) {
Object.defineProperties(global.TextRectangle.prototype, {
width: { get: function() { return this.right - this.left; } },
height: { get: function() { return this.bottom - this.top; } }
});
}
}(self));
// URL Polyfill
// Draft specification: https://url.spec.whatwg.org
// Notes:
// - Primarily useful for parsing URLs and modifying query parameters
// - Should work in IE8+ and everything more modern, with es5.js polyfills
(function (global) {
'use strict';
function isSequence(o) {
if (!o) return false;
if ('Symbol' in global && 'iterator' in global.Symbol &&
typeof o[Symbol.iterator] === 'function') return true;
if (Array.isArray(o)) return true;
return false;
}
function toArray(iter) {
return ('from' in Array) ? Array.from(iter) : Array.prototype.slice.call(iter);
}
(function() {
// Browsers may have:
// * No global URL object
// * URL with static methods only - may have a dummy constructor
// * URL with members except searchParams
// * Full URL API support
var origURL = global.URL;
var nativeURL;
try {
if (origURL) {
nativeURL = new global.URL('http://example.com');
if ('searchParams' in nativeURL)
return;
if (!('href' in nativeURL))
nativeURL = undefined;
}
} catch (_) {}
// NOTE: Doesn't do the encoding/decoding dance
function urlencoded_serialize(pairs) {
var output = '', first = true;
pairs.forEach(function (pair) {
var name = encodeURIComponent(pair.name);
var value = encodeURIComponent(pair.value);
if (!first) output += '&';
output += name + '=' + value;
first = false;
});
return output.replace(/%20/g, '+');
}
// NOTE: Doesn't do the encoding/decoding dance
function urlencoded_parse(input, isindex) {
var sequences = input.split('&');
if (isindex && sequences[0].indexOf('=') === -1)
sequences[0] = '=' + sequences[0];
var pairs = [];
sequences.forEach(function (bytes) {
if (bytes.length === 0) return;
var index = bytes.indexOf('=');
if (index !== -1) {
var name = bytes.substring(0, index);
var value = bytes.substring(index + 1);
} else {
name = bytes;
value = '';
}
name = name.replace(/\+/g, ' ');
value = value.replace(/\+/g, ' ');
pairs.push({ name: name, value: value });
});
var output = [];
pairs.forEach(function (pair) {
output.push({
name: decodeURIComponent(pair.name),
value: decodeURIComponent(pair.value)
});
});
return output;
}
function URLUtils(url) {
if (nativeURL)
return new origURL(url);
var anchor = document.createElement('a');
anchor.href = url;
return anchor;
}
function URLSearchParams(init) {
var $this = this;
this._list = [];
if (init === undefined || init === null) {
// no-op
} else if (init instanceof URLSearchParams) {
// In ES6 init would be a sequence, but special case for ES5.
this._list = urlencoded_parse(String(init));
} else if (typeof init === 'object' && isSequence(init)) {
toArray(init).forEach(function(e) {
if (!isSequence(e)) throw TypeError();
var nv = toArray(e);
if (nv.length !== 2) throw TypeError();
$this._list.push({name: String(nv[0]), value: String(nv[1])});
});
} else if (typeof init === 'object' && init) {
Object.keys(init).forEach(function(key) {
$this._list.push({name: String(key), value: String(init[key])});
});
} else {
init = String(init);
if (init.substring(0, 1) === '?')
init = init.substring(1);
this._list = urlencoded_parse(init);
}
this._url_object = null;
this._setList = function (list) { if (!updating) $this._list = list; };
var updating = false;
this._update_steps = function() {
if (updating) return;
updating = true;
if (!$this._url_object) return;
// Partial workaround for IE issue with 'about:'
if ($this._url_object.protocol === 'about:' &&
$this._url_object.pathname.indexOf('?') !== -1) {
$this._url_object.pathname = $this._url_object.pathname.split('?')[0];
}
$this._url_object.search = urlencoded_serialize($this._list);
updating = false;
};
}
Object.defineProperties(URLSearchParams.prototype, {
append: {
value: function (name, value) {
this._list.push({ name: name, value: value });
this._update_steps();
}, writable: true, enumerable: true, configurable: true
},
'delete': {
value: function (name) {
for (var i = 0; i < this._list.length;) {
if (this._list[i].name === name)
this._list.splice(i, 1);
else
++i;
}
this._update_steps();
}, writable: true, enumerable: true, configurable: true
},
get: {
value: function (name) {
for (var i = 0; i < this._list.length; ++i) {
if (this._list[i].name === name)
return this._list[i].value;
}
return null;
}, writable: true, enumerable: true, configurable: true
},
getAll: {
value: function (name) {
var result = [];
for (var i = 0; i < this._list.length; ++i) {
if (this._list[i].name === name)
result.push(this._list[i].value);
}
return result;
}, writable: true, enumerable: true, configurable: true
},
has: {
value: function (name) {
for (var i = 0; i < this._list.length; ++i) {
if (this._list[i].name === name)
return true;
}
return false;
}, writable: true, enumerable: true, configurable: true
},
set: {
value: function (name, value) {
var found = false;
for (var i = 0; i < this._list.length;) {
if (this._list[i].name === name) {
if (!found) {
this._list[i].value = value;
found = true;
++i;
} else {
this._list.splice(i, 1);
}
} else {
++i;
}
}
if (!found)
this._list.push({ name: name, value: value });
this._update_steps();
}, writable: true, enumerable: true, configurable: true
},
entries: {
value: function() { return new Iterator(this._list, 'key+value'); },
writable: true, enumerable: true, configurable: true
},
keys: {
value: function() { return new Iterator(this._list, 'key'); },
writable: true, enumerable: true, configurable: true
},
values: {
value: function() { return new Iterator(this._list, 'value'); },
writable: true, enumerable: true, configurable: true
},
forEach: {
value: function(callback) {
var thisArg = (arguments.length > 1) ? arguments[1] : undefined;
this._list.forEach(function(pair, index) {
callback.call(thisArg, pair.value, pair.name);
});
}, writable: true, enumerable: true, configurable: true
},
toString: {
value: function () {
return urlencoded_serialize(this._list);
}, writable: true, enumerable: false, configurable: true
}
});
function Iterator(source, kind) {
var index = 0;
this['next'] = function() {
if (index >= source.length)
return {done: true, value: undefined};
var pair = source[index++];
return {done: false, value:
kind === 'key' ? pair.name :
kind === 'value' ? pair.value :
[pair.name, pair.value]};
};
}
if ('Symbol' in global && 'iterator' in global.Symbol) {
Object.defineProperty(URLSearchParams.prototype, global.Symbol.iterator, {
value: URLSearchParams.prototype.entries,
writable: true, enumerable: true, configurable: true});
Object.defineProperty(Iterator.prototype, global.Symbol.iterator, {
value: function() { return this; },
writable: true, enumerable: true, configurable: true});
}
function URL(url, base) {
if (!(this instanceof global.URL))
throw new TypeError("Failed to construct 'URL': Please use the 'new' operator.");
if (base) {
url = (function () {
if (nativeURL) return new origURL(url, base).href;
var iframe;
try {
var doc;
// Use another document/base tag/anchor for relative URL resolution, if possible
if (Object.prototype.toString.call(window.operamini) === "[object OperaMini]") {
iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.documentElement.appendChild(iframe);
doc = iframe.contentWindow.document;
} else if (document.implementation && document.implementation.createHTMLDocument) {
doc = document.implementation.createHTMLDocument('');
} else if (document.implementation && document.implementation.createDocument) {
doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
doc.documentElement.appendChild(doc.createElement('head'));
doc.documentElement.appendChild(doc.createElement('body'));
} else if (window.ActiveXObject) {
doc = new window.ActiveXObject('htmlfile');
doc.write('<head><\/head><body><\/body>');
doc.close();
}
if (!doc) throw Error('base not supported');
var baseTag = doc.createElement('base');
baseTag.href = base;
doc.getElementsByTagName('head')[0].appendChild(baseTag);
var anchor = doc.createElement('a');
anchor.href = url;
return anchor.href;
} finally {
if (iframe)
iframe.parentNode.removeChild(iframe);
}
}());
}
// An inner object implementing URLUtils (either a native URL
// object or an HTMLAnchorElement instance) is used to perform the
// URL algorithms. With full ES5 getter/setter support, return a
// regular object For IE8's limited getter/setter support, a
// different HTMLAnchorElement is returned with properties
// overridden
var instance = URLUtils(url || '');
// Detect for ES5 getter/setter support
// (an Object.defineProperties polyfill that doesn't support getters/setters may throw)
var ES5_GET_SET = (function() {
if (!('defineProperties' in Object)) return false;
try {
var obj = {};
Object.defineProperties(obj, { prop: { 'get': function () { return true; } } });
return obj.prop;
} catch (_) {
return false;
}
})();
var self = ES5_GET_SET ? this : document.createElement('a');
var query_object = new URLSearchParams(
instance.search ? instance.search.substring(1) : null);
query_object._url_object = self;
Object.defineProperties(self, {
href: {
get: function () { return instance.href; },
set: function (v) { instance.href = v; tidy_instance(); update_steps(); },
enumerable: true, configurable: true
},
origin: {
get: function () {
if ('origin' in instance) return instance.origin;
return this.protocol + '//' + this.host;
},
enumerable: true, configurable: true
},
protocol: {
get: function () { return instance.protocol; },
set: function (v) { instance.protocol = v; },
enumerable: true, configurable: true
},
username: {
get: function () { return instance.username; },
set: function (v) { instance.username = v; },
enumerable: true, configurable: true
},
password: {
get: function () { return instance.password; },
set: function (v) { instance.password = v; },
enumerable: true, configurable: true
},
host: {
get: function () {
// IE returns default port in |host|
var re = {'http:': /:80$/, 'https:': /:443$/, 'ftp:': /:21$/}[instance.protocol];
return re ? instance.host.replace(re, '') : instance.host;
},
set: function (v) { instance.host = v; },
enumerable: true, configurable: true
},
hostname: {
get: function () { return instance.hostname; },
set: function (v) { instance.hostname = v; },
enumerable: true, configurable: true
},
port: {
get: function () { return instance.port; },
set: function (v) { instance.port = v; },
enumerable: true, configurable: true
},
pathname: {
get: function () {
// IE does not include leading '/' in |pathname|
if (instance.pathname.charAt(0) !== '/') return '/' + instance.pathname;
return instance.pathname;
},
set: function (v) { instance.pathname = v; },
enumerable: true, configurable: true
},
search: {
get: function () { return instance.search; },
set: function (v) {
if (instance.search === v) return;
instance.search = v; tidy_instance(); update_steps();
},
enumerable: true, configurable: true
},
searchParams: {
get: function () { return query_object; },
enumerable: true, configurable: true
},
hash: {
get: function () { return instance.hash; },
set: function (v) { instance.hash = v; tidy_instance(); },
enumerable: true, configurable: true
},
toString: {
value: function() { return instance.toString(); },
enumerable: false, configurable: true
},
valueOf: {
value: function() { return instance.valueOf(); },
enumerable: false, configurable: true
}
});
function tidy_instance() {
var href = instance.href.replace(/#$|\?$|\?(?=#)/g, '');
if (instance.href !== href)
instance.href = href;
}
function update_steps() {
query_object._setList(instance.search ? urlencoded_parse(instance.search.substring(1)) : []);
query_object._update_steps();
};
return self;
}
if (origURL) {
for (var i in origURL) {
if (origURL.hasOwnProperty(i) && typeof origURL[i] === 'function')
URL[i] = origURL[i];
}
}
global.URL = URL;
global.URLSearchParams = URLSearchParams;
}());
// Patch native URLSearchParams constructor to handle sequences/records
// if necessary.
(function() {
if (new global.URLSearchParams([['a', 1]]).get('a') === '1' &&
new global.URLSearchParams({a: 1}).get('a') === '1')
return;
var orig = global.URLSearchParams;
global.URLSearchParams = function(init) {
if (init && typeof init === 'object' && isSequence(init)) {
var o = new orig();
toArray(init).forEach(function(e) {
if (!isSequence(e)) throw TypeError();
var nv = toArray(e);
if (nv.length !== 2) throw TypeError();
o.append(nv[0], nv[1]);
});
return o;
} else if (init && typeof init === 'object') {
o = new orig();
Object.keys(init).forEach(function(key) {
o.set(key, init[key]);
});
return o;
} else {
return new orig(init);
}
};
}());
}(self));
// Work-In-Progress 'prollyfill' for Fetch API
// Standard: https://fetch.spec.whatwg.org/#fetch-api
//
// As usual, the intent is to produce a forward-compatible
// subset so that code can be written using future standard
// functionality; not every case is considered or supported.
// Requires ES2015: Promise, Symbol.iterator (or polyfill)
// Requires: URL (or polyfill)
// Example:
// fetch('README.md')
// .then(function(response) { return response.text(); })
// .then(function(text) { alert(text); });
(function(global) {
'use strict';
// Web IDL concepts
// https://heycam.github.io/webidl/#idl-ByteString
function ByteString(value) {
value = String(value);
if (value.match(/[^\x00-\xFF]/)) throw TypeError('Not a valid ByteString');
return value;
}
// https://heycam.github.io/webidl/#idl-USVString
function USVString(value) {
value = String(value);
return value.replace(
/([\u0000-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF])/g,
function (c) {
if (/^[\uD800-\uDFFF]$/.test(c)) return '\uFFFD';
return c;
});
}
function ushort(x) { return x & 0xFFFF; }
// 2 Terminology
function byteLowerCase(s) {
return String(s).replace(/[A-Z]/g, function(c) { return c.toLowerCase(); });
}
function byteUpperCase(s) {
return String(s).replace(/[a-z]/g, function(c) { return c.toUpperCase(); });
}
function byteCaseInsensitiveMatch(a, b) {
return byteLowerCase(a) === byteLowerCase(b);
}
// 2.1 HTTP
// 2.1.1 Methods
function isForbiddenMethod(m) {
m = byteUpperCase(m);
return m === 'CONNECT' || m === 'TRACE' || m === 'TRACK';
}
function normalizeMethod(m) {
var u = byteUpperCase(m);
if (u === 'DELETE' || u === 'GET' || u === 'HEAD' || u === 'OPTIONS' ||
u === 'POST' || u === 'PUT') return u;
return m;
}
function isName(s) {
return /^[!#$%&'*+\-.09A-Z^_`a-z|~]+$/.test(s);
}
function isValue(s) {
// TODO: Implement me
return true;
}
function isForbiddenHeaderName(n) {
n = String(n).toLowerCase();
var forbidden = {
'accept-charset': true,
'accept-encoding': true,
'access-control-request-headers': true,
'access-control-request-method': true,
'connection': true,
'content-length': true,
'cookie': true,
'cookie2': true,
'date': true,
'dnt': true,
'expect': true,
'host': true,
'keep-alive': true,
'origin': true,
'referer': true,
'te': true,
'trailer': true,
'transfer-encoding': true,
'upgrade': true,
'user-agent': true,
'via': true
};
return forbidden[n] || n.substring(0, 6) === 'proxy-' || n.substring(0, 4) === 'sec-';
}
function isForbiddenResponseHeaderName(n) {
n = String(n).toLowerCase();
var forbidden = {
'set-cookie': true,
'set-cookie2': true
};
return forbidden[n];
}
function isSimpleHeader(name, value) {
name = String(name).toLowerCase();
return name === 'accept' || name === 'accept-language' || name === 'content-language' ||
(name === 'content-type' &&
['application/x-www-form-encoded', 'multipart/form-data', 'text/plain'].indexOf(value) !== -1);
}
//
// 5.1 Headers class
//
// typedef (Headers or sequence<sequence<ByteString>> or OpenEndedDictionary<ByteString>) HeadersInit;
// Constructor(optional HeadersInit init)
function Headers(init) {
this._guard = 'none';
this._headerList = [];
if (init) fill(this, init);
}
function fill(headers, init) {
if (init instanceof Headers) {
init._headerList.forEach(function(header) {
headers.append(header[0], header[1]);
});
} else if (Array.isArray(init)) {
init.forEach(function(header) {
if (!Array.isArray(header) || header.length !== 2) throw TypeError();
headers.append(header[0], header[1]);
});
} else {
init = Object(init);
Object.keys(init).forEach(function(key) {
headers.append(key, init[key]);
});
}
}
// interface Headers
Headers.prototype = {
// void append(ByteString name, ByteString value);
append: function append(name, value) {
name = ByteString(name);
if (!isName(name) || !isValue(value)) throw TypeError();
if (this._guard === 'immutable') throw TypeError();
else if (this._guard === 'request' && isForbiddenHeaderName(name)) return;
else if (this._guard === 'request-no-CORS' && !isSimpleHeader(name, value)) return;
else if (this._guard === 'response' && isForbiddenResponseHeaderName(name)) return;
name = name.toLowerCase();
this._headerList.push([name, value]);
},
// void delete(ByteString name);
'delete': function delete_(name) {
name = ByteString(name);
if (!isName(name)) throw TypeError();
if (this._guard === 'immutable') throw TypeError();
else if (this._guard === 'request' && isForbiddenHeaderName(name)) return;
else if (this._guard === 'request-no-CORS' && !isSimpleHeader(name, 'invalid')) return;
else if (this._guard === 'response' && isForbiddenResponseHeaderName(name)) return;
name = name.toLowerCase();
var index = 0;
while (index < this._headerList.length) {
if (this._headerList[index][0] === name)
this._headerList.splice(index, 1);
else
++index;
}
},
// ByteString? get(ByteString name);
get: function get(name) {
name = ByteString(name);
if (!isName(name)) throw TypeError();
name = name.toLowerCase();
for (var index = 0; index < this._headerList.length; ++index) {
if (this._headerList[index][0] === name)
return this._headerList[index][1];
}
return null;
},
// sequence<ByteString> getAll(ByteString name);
getAll: function getAll(name) {
name = ByteString(name);
if (!isName(name)) throw TypeError();
name = name.toLowerCase();
var sequence = [];
for (var index = 0; index < this._headerList.length; ++index) {
if (this._headerList[index][0] === name)
sequence.push(this._headerList[index][1]);
}
return sequence;
},
// boolean has(ByteString name);
has: function has(name) {
name = ByteString(name);
if (!isName(name)) throw TypeError();
name = name.toLowerCase();
for (var index = 0; index < this._headerList.length; ++index) {
if (this._headerList[index][0] === name)
return true;
}
return false;
},
// void set(ByteString name, ByteString value);
set: function set(name, value) {
name = ByteString(name);
if (!isName(name) || !isValue(value)) throw TypeError();
if (this._guard === 'immutable') throw TypeError();
else if (this._guard === 'request' && isForbiddenHeaderName(name)) return;
else if (this._guard === 'request-no-CORS' && !isSimpleHeader(name, value)) return;
else if (this._guard === 'response' && isForbiddenResponseHeaderName(name)) return;
name = name.toLowerCase();
for (var index = 0; index < this._headerList.length; ++index) {
if (this._headerList[index][0] === name) {
this._headerList[index++][1] = value;
while (index < this._headerList.length) {
if (this._headerList[index][0] === name)
this._headerList.splice(index, 1);
else
++index;
}
return;
}
}
this._headerList.push([name, value]);
}
};
Headers.prototype[Symbol.iterator] = function() {
return new HeadersIterator(this);
};
function HeadersIterator(headers) {
this._headers = headers;
this._index = 0;
}
HeadersIterator.prototype = {};
HeadersIterator.prototype.next = function() {
if (this._index >= this._headers._headerList.length)
return { value: undefined, done: true };
return { value: this._headers._headerList[this._index++], done: false };
};
HeadersIterator.prototype[Symbol.iterator] = function() { return this; };
//
// 5.2 Body mixin
//
function Body(_stream) {
// TODO: Handle initialization from other types
this._stream = _stream;
this.bodyUsed = false;
}
// interface FetchBodyStream
Body.prototype = {
// Promise<ArrayBuffer> arrayBuffer();
arrayBuffer: function() {
if (this.bodyUsed) return Promise.reject(TypeError());
this.bodyUsed = true;
if (this._stream instanceof ArrayBuffer) return Promise.resolve(this._stream);
var value = this._stream;
return new Promise(function(resolve, reject) {
var octets = unescape(encodeURIComponent(value)).split('').map(function(c) {
return c.charCodeAt(0);
});
resolve(new Uint8Array(octets).buffer);
});
},
// Promise<Blob> blob();
blob: function() {
if (this.bodyUsed) return Promise.reject(TypeError());
this.bodyUsed = true;
if (this._stream instanceof Blob) return Promise.resolve(this._stream);
return Promise.resolve(new Blob([this._stream]));
},
// Promise<FormData> formData();
formData: function() {
if (this.bodyUsed) return Promise.reject(TypeError());
this.bodyUsed = true;
if (this._stream instanceof FormData) return Promise.resolve(this._stream);
return Promise.reject(Error('Not yet implemented'));
},
// Promise<JSON> json();
json: function() {
if (this.bodyUsed) return Promise.reject(TypeError());
this.bodyUsed = true;
var that = this;
return new Promise(function(resolve, reject) {
resolve(JSON.parse(that._stream));
});
},
// Promise<USVString> text();
text: function() {
if (this.bodyUsed) return Promise.reject(TypeError());
this.bodyUsed = true;
return Promise.resolve(String(this._stream));
}
};
//
// 5.3 Request class
//
// typedef (Request or USVString) RequestInfo;
// Constructor(RequestInfo input, optional RequestInit init)
function Request(input, init) {
if (arguments.length < 1) throw TypeError('Not enough arguments');
Body.call(this, null);
// readonly attribute ByteString method;
this.method = 'GET';
// readonly attribute USVString url;
this.url = '';
// readonly attribute Headers headers;
this.headers = new Headers();
this.headers._guard = 'request';
// readonly attribute DOMString referrer;
this.referrer = null; // TODO: Implement.
// readonly attribute RequestMode mode;
this.mode = null; // TODO: Implement.
// readonly attribute RequestCredentials credentials;
this.credentials = 'omit';
if (input instanceof Request) {
if (input.bodyUsed) throw TypeError();
input.bodyUsed = true;
this.method = input.method;
this.url = input.url;
this.headers = new Headers(input.headers);
this.headers._guard = input.headers._guard;
this.credentials = input.credentials;
this._stream = input._stream;
} else {
input = USVString(input);
this.url = String(new URL(input, self.location));
}
init = Object(init);
if ('method' in init) {
var method = ByteString(init.method);
if (isForbiddenMethod(method)) throw TypeError();
this.method = normalizeMethod(method);
}
if ('headers' in init) {
this.headers = new Headers();
fill(this.headers, init.headers);
}
if ('body' in init)
this._stream = init.body;
if ('credentials' in init &&
(['omit', 'same-origin', 'include'].indexOf(init.credentials) !== -1))
this.credentials = init.credentials;
}
// interface Request
Request.prototype = Body.prototype;
//
// 5.4 Response class
//
// Constructor(optional FetchBodyInit body, optional ResponseInit init)
function Response(body, init) {
if (arguments.length < 1)
body = '';
this.headers = new Headers();
this.headers._guard = 'response';
// Internal
if (body instanceof XMLHttpRequest && '_url' in body) {
var xhr = body;
this.type = 'basic'; // TODO: ResponseType
this.url = USVString(xhr._url);
this.status = xhr.status;
this.ok = 200 <= this.status && this.status <= 299;
this.statusText = xhr.statusText;
xhr.getAllResponseHeaders()
.split(/\r?\n/)
.filter(function(header) { return header.length; })
.forEach(function(header) {
var i = header.indexOf(':');
this.headers.append(header.substring(0, i), header.substring(i + 2));
}, this);
Body.call(this, xhr.responseText);
return;
}
Body.call(this, body);
init = Object(init) || {};
// readonly attribute USVString url;
this.url = '';
// readonly attribute unsigned short status;
var status = 'status' in init ? ushort(init.status) : 200;
if (status < 200 || status > 599) throw RangeError();
this.status = status;
// readonly attribute boolean ok;
this.ok = 200 <= this.status && this.status <= 299;
// readonly attribute ByteString statusText;
var statusText = 'statusText' in init ? String(init.statusText) : 'OK';
if (/[^\x00-\xFF]/.test(statusText)) throw TypeError();
this.statusText = statusText;
// readonly attribute Headers headers;
if ('headers' in init) fill(this.headers, init);
// TODO: Implement these
// readonly attribute ResponseType type;
this.type = 'basic'; // TODO: ResponseType
}
// interface Response
Response.prototype = Body.prototype;
Response.redirect = function() {
// TODO: Implement?
throw Error('Not supported');
};
//
// 5.5 Structured cloning of Headers, FetchBodyStream, Request, Response
//
//
// 5.6 Fetch method
//
// Promise<Response> fetch(RequestInfo input, optional RequestInit init);
function fetch(input, init) {
return new Promise(function(resolve, reject) {
var r = new Request(input, init);
var xhr = new XMLHttpRequest(), async = true;
xhr._url = r.url;
try { xhr.open(r.method, r.url, async); } catch (e) { throw TypeError(e.message); }
for (var iter = r.headers[Symbol.iterator](), step = iter.next();
!step.done; step = iter.next())
xhr.setRequestHeader(step.value[0], step.value[1]);
if (r.credentials === 'include')
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
if (xhr.readyState !== XMLHttpRequest.DONE) return;
if (xhr.status === 0)
reject(new TypeError('Network error'));
else
resolve(new Response(xhr));
};
xhr.send(r._stream);
});
}
// Exported
if (!('fetch' in global)) {
global.Headers = Headers;
global.Request = Request;
global.Response = Response;
global.fetch = fetch;
}
}(self));