1075 lines
27 KiB
JavaScript
1075 lines
27 KiB
JavaScript
|
|
|
||
|
|
// IE 11 CustomEvent polyfill
|
||
|
|
|
||
|
|
(function () {
|
||
|
|
if ( typeof window.CustomEvent === "function" ) return false; //If not IE
|
||
|
|
|
||
|
|
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 = window.Event.prototype;
|
||
|
|
|
||
|
|
window.CustomEvent = CustomEvent;
|
||
|
|
})();
|
||
|
|
|
||
|
|
// IE 11 EventTarget polyfill
|
||
|
|
(function () {
|
||
|
|
if (typeof window.EventTarget === "function") return false; // If EventTarget exists
|
||
|
|
|
||
|
|
function EventTarget() {
|
||
|
|
this._listeners = {};
|
||
|
|
}
|
||
|
|
|
||
|
|
EventTarget.prototype.addEventListener = function(type, callback) {
|
||
|
|
if (!(type in this._listeners)) {
|
||
|
|
this._listeners[type] = [];
|
||
|
|
}
|
||
|
|
this._listeners[type].push(callback);
|
||
|
|
};
|
||
|
|
|
||
|
|
EventTarget.prototype.removeEventListener = function(type, callback) {
|
||
|
|
if (!(type in this._listeners)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
var stack = this._listeners[type];
|
||
|
|
for (var i = 0, l = stack.length; i < l; i++) {
|
||
|
|
if (stack[i] === callback) {
|
||
|
|
stack.splice(i, 1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
EventTarget.prototype.dispatchEvent = function(event) {
|
||
|
|
if (!(event.type in this._listeners)) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
var stack = this._listeners[event.type].slice();
|
||
|
|
|
||
|
|
for (var i = 0, l = stack.length; i < l; i++) {
|
||
|
|
stack[i].call(this, event);
|
||
|
|
}
|
||
|
|
return !event.defaultPrevented;
|
||
|
|
};
|
||
|
|
|
||
|
|
window.EventTarget = EventTarget;
|
||
|
|
})();
|
||
|
|
|
||
|
|
// IE 11 Array.isArray polyfill (just in case)
|
||
|
|
if (!Array.isArray) {
|
||
|
|
Array.isArray = function(arg) {
|
||
|
|
return Object.prototype.toString.call(arg) === '[object Array]';
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*! Native Promise Only
|
||
|
|
v0.8.1 (c) Kyle Simpson
|
||
|
|
MIT License: http://getify.mit-license.org
|
||
|
|
*/
|
||
|
|
|
||
|
|
(function UMD(name,context,definition){
|
||
|
|
// special form of UMD for polyfilling across environments
|
||
|
|
context[name] = context[name] || definition();
|
||
|
|
if (typeof module != "undefined" && module.exports) { module.exports = context[name]; }
|
||
|
|
else if (typeof define == "function" && define.amd) { define(function $AMD$(){ return context[name]; }); }
|
||
|
|
})("Promise",typeof global != "undefined" ? global : this,function DEF(){
|
||
|
|
/*jshint validthis:true */
|
||
|
|
"use strict";
|
||
|
|
|
||
|
|
var builtInProp, cycle, scheduling_queue,
|
||
|
|
ToString = Object.prototype.toString,
|
||
|
|
timer = (typeof setImmediate != "undefined") ?
|
||
|
|
function timer(fn) { return setImmediate(fn); } :
|
||
|
|
setTimeout
|
||
|
|
;
|
||
|
|
|
||
|
|
// dammit, IE8.
|
||
|
|
try {
|
||
|
|
Object.defineProperty({},"x",{});
|
||
|
|
builtInProp = function builtInProp(obj,name,val,config) {
|
||
|
|
return Object.defineProperty(obj,name,{
|
||
|
|
value: val,
|
||
|
|
writable: true,
|
||
|
|
configurable: config !== false
|
||
|
|
});
|
||
|
|
};
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
builtInProp = function builtInProp(obj,name,val) {
|
||
|
|
obj[name] = val;
|
||
|
|
return obj;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// Note: using a queue instead of array for efficiency
|
||
|
|
scheduling_queue = (function Queue() {
|
||
|
|
var first, last, item;
|
||
|
|
|
||
|
|
function Item(fn,self) {
|
||
|
|
this.fn = fn;
|
||
|
|
this.self = self;
|
||
|
|
this.next = void 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
add: function add(fn,self) {
|
||
|
|
item = new Item(fn,self);
|
||
|
|
if (last) {
|
||
|
|
last.next = item;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
first = item;
|
||
|
|
}
|
||
|
|
last = item;
|
||
|
|
item = void 0;
|
||
|
|
},
|
||
|
|
drain: function drain() {
|
||
|
|
var f = first;
|
||
|
|
first = last = cycle = void 0;
|
||
|
|
|
||
|
|
while (f) {
|
||
|
|
f.fn.call(f.self);
|
||
|
|
f = f.next;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
})();
|
||
|
|
|
||
|
|
function schedule(fn,self) {
|
||
|
|
scheduling_queue.add(fn,self);
|
||
|
|
if (!cycle) {
|
||
|
|
cycle = timer(scheduling_queue.drain);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// promise duck typing
|
||
|
|
function isThenable(o) {
|
||
|
|
var _then, o_type = typeof o;
|
||
|
|
|
||
|
|
if (o != null &&
|
||
|
|
(
|
||
|
|
o_type == "object" || o_type == "function"
|
||
|
|
)
|
||
|
|
) {
|
||
|
|
_then = o.then;
|
||
|
|
}
|
||
|
|
return typeof _then == "function" ? _then : false;
|
||
|
|
}
|
||
|
|
|
||
|
|
function notify() {
|
||
|
|
for (var i=0; i<this.chain.length; i++) {
|
||
|
|
notifyIsolated(
|
||
|
|
this,
|
||
|
|
(this.state === 1) ? this.chain[i].success : this.chain[i].failure,
|
||
|
|
this.chain[i]
|
||
|
|
);
|
||
|
|
}
|
||
|
|
this.chain.length = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// NOTE: This is a separate function to isolate
|
||
|
|
// the `try..catch` so that other code can be
|
||
|
|
// optimized better
|
||
|
|
function notifyIsolated(self,cb,chain) {
|
||
|
|
var ret, _then;
|
||
|
|
try {
|
||
|
|
if (cb === false) {
|
||
|
|
chain.reject(self.msg);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (cb === true) {
|
||
|
|
ret = self.msg;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ret = cb.call(void 0,self.msg);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ret === chain.promise) {
|
||
|
|
chain.reject(TypeError("Promise-chain cycle"));
|
||
|
|
}
|
||
|
|
else if (_then = isThenable(ret)) {
|
||
|
|
_then.call(ret,chain.resolve,chain.reject);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
chain.resolve(ret);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
chain.reject(err);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function resolve(msg) {
|
||
|
|
var _then, self = this;
|
||
|
|
|
||
|
|
// already triggered?
|
||
|
|
if (self.triggered) { return; }
|
||
|
|
|
||
|
|
self.triggered = true;
|
||
|
|
|
||
|
|
// unwrap
|
||
|
|
if (self.def) {
|
||
|
|
self = self.def;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
if (_then = isThenable(msg)) {
|
||
|
|
schedule(function(){
|
||
|
|
var def_wrapper = new MakeDefWrapper(self);
|
||
|
|
try {
|
||
|
|
_then.call(msg,
|
||
|
|
function $resolve$(){ resolve.apply(def_wrapper,arguments); },
|
||
|
|
function $reject$(){ reject.apply(def_wrapper,arguments); }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
reject.call(def_wrapper,err);
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
self.msg = msg;
|
||
|
|
self.state = 1;
|
||
|
|
if (self.chain.length > 0) {
|
||
|
|
schedule(notify,self);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
reject.call(new MakeDefWrapper(self),err);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function reject(msg) {
|
||
|
|
var self = this;
|
||
|
|
|
||
|
|
// already triggered?
|
||
|
|
if (self.triggered) { return; }
|
||
|
|
|
||
|
|
self.triggered = true;
|
||
|
|
|
||
|
|
// unwrap
|
||
|
|
if (self.def) {
|
||
|
|
self = self.def;
|
||
|
|
}
|
||
|
|
|
||
|
|
self.msg = msg;
|
||
|
|
self.state = 2;
|
||
|
|
if (self.chain.length > 0) {
|
||
|
|
schedule(notify,self);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function iteratePromises(Constructor,arr,resolver,rejecter) {
|
||
|
|
for (var idx=0; idx<arr.length; idx++) {
|
||
|
|
(function IIFE(idx){
|
||
|
|
Constructor.resolve(arr[idx])
|
||
|
|
.then(
|
||
|
|
function $resolver$(msg){
|
||
|
|
resolver(idx,msg);
|
||
|
|
},
|
||
|
|
rejecter
|
||
|
|
);
|
||
|
|
})(idx);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function MakeDefWrapper(self) {
|
||
|
|
this.def = self;
|
||
|
|
this.triggered = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
function MakeDef(self) {
|
||
|
|
this.promise = self;
|
||
|
|
this.state = 0;
|
||
|
|
this.triggered = false;
|
||
|
|
this.chain = [];
|
||
|
|
this.msg = void 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
function Promise(executor) {
|
||
|
|
if (typeof executor != "function") {
|
||
|
|
throw TypeError("Not a function");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this.__NPO__ !== 0) {
|
||
|
|
throw TypeError("Not a promise");
|
||
|
|
}
|
||
|
|
|
||
|
|
// instance shadowing the inherited "brand"
|
||
|
|
// to signal an already "initialized" promise
|
||
|
|
this.__NPO__ = 1;
|
||
|
|
|
||
|
|
var def = new MakeDef(this);
|
||
|
|
|
||
|
|
this["then"] = function then(success,failure) {
|
||
|
|
var o = {
|
||
|
|
success: typeof success == "function" ? success : true,
|
||
|
|
failure: typeof failure == "function" ? failure : false
|
||
|
|
};
|
||
|
|
// Note: `then(..)` itself can be borrowed to be used against
|
||
|
|
// a different promise constructor for making the chained promise,
|
||
|
|
// by substituting a different `this` binding.
|
||
|
|
o.promise = new this.constructor(function extractChain(resolve,reject) {
|
||
|
|
if (typeof resolve != "function" || typeof reject != "function") {
|
||
|
|
throw TypeError("Not a function");
|
||
|
|
}
|
||
|
|
|
||
|
|
o.resolve = resolve;
|
||
|
|
o.reject = reject;
|
||
|
|
});
|
||
|
|
def.chain.push(o);
|
||
|
|
|
||
|
|
if (def.state !== 0) {
|
||
|
|
schedule(notify,def);
|
||
|
|
}
|
||
|
|
|
||
|
|
return o.promise;
|
||
|
|
};
|
||
|
|
this["catch"] = function $catch$(failure) {
|
||
|
|
return this.then(void 0,failure);
|
||
|
|
};
|
||
|
|
|
||
|
|
try {
|
||
|
|
executor.call(
|
||
|
|
void 0,
|
||
|
|
function publicResolve(msg){
|
||
|
|
resolve.call(def,msg);
|
||
|
|
},
|
||
|
|
function publicReject(msg) {
|
||
|
|
reject.call(def,msg);
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
reject.call(def,err);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var PromisePrototype = builtInProp({},"constructor",Promise,
|
||
|
|
/*configurable=*/false
|
||
|
|
);
|
||
|
|
|
||
|
|
// Note: Android 4 cannot use `Object.defineProperty(..)` here
|
||
|
|
Promise.prototype = PromisePrototype;
|
||
|
|
|
||
|
|
// built-in "brand" to signal an "uninitialized" promise
|
||
|
|
builtInProp(PromisePrototype,"__NPO__",0,
|
||
|
|
/*configurable=*/false
|
||
|
|
);
|
||
|
|
|
||
|
|
builtInProp(Promise,"resolve",function Promise$resolve(msg) {
|
||
|
|
var Constructor = this;
|
||
|
|
|
||
|
|
// spec mandated checks
|
||
|
|
// note: best "isPromise" check that's practical for now
|
||
|
|
if (msg && typeof msg == "object" && msg.__NPO__ === 1) {
|
||
|
|
return msg;
|
||
|
|
}
|
||
|
|
|
||
|
|
return new Constructor(function executor(resolve,reject){
|
||
|
|
if (typeof resolve != "function" || typeof reject != "function") {
|
||
|
|
throw TypeError("Not a function");
|
||
|
|
}
|
||
|
|
|
||
|
|
resolve(msg);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
builtInProp(Promise,"reject",function Promise$reject(msg) {
|
||
|
|
return new this(function executor(resolve,reject){
|
||
|
|
if (typeof resolve != "function" || typeof reject != "function") {
|
||
|
|
throw TypeError("Not a function");
|
||
|
|
}
|
||
|
|
|
||
|
|
reject(msg);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
builtInProp(Promise,"all",function Promise$all(arr) {
|
||
|
|
var Constructor = this;
|
||
|
|
|
||
|
|
// spec mandated checks
|
||
|
|
if (ToString.call(arr) != "[object Array]") {
|
||
|
|
return Constructor.reject(TypeError("Not an array"));
|
||
|
|
}
|
||
|
|
if (arr.length === 0) {
|
||
|
|
return Constructor.resolve([]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return new Constructor(function executor(resolve,reject){
|
||
|
|
if (typeof resolve != "function" || typeof reject != "function") {
|
||
|
|
throw TypeError("Not a function");
|
||
|
|
}
|
||
|
|
|
||
|
|
var len = arr.length, msgs = Array(len), count = 0;
|
||
|
|
|
||
|
|
iteratePromises(Constructor,arr,function resolver(idx,msg) {
|
||
|
|
msgs[idx] = msg;
|
||
|
|
if (++count === len) {
|
||
|
|
resolve(msgs);
|
||
|
|
}
|
||
|
|
},reject);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
builtInProp(Promise,"race",function Promise$race(arr) {
|
||
|
|
var Constructor = this;
|
||
|
|
|
||
|
|
// spec mandated checks
|
||
|
|
if (ToString.call(arr) != "[object Array]") {
|
||
|
|
return Constructor.reject(TypeError("Not an array"));
|
||
|
|
}
|
||
|
|
|
||
|
|
return new Constructor(function executor(resolve,reject){
|
||
|
|
if (typeof resolve != "function" || typeof reject != "function") {
|
||
|
|
throw TypeError("Not a function");
|
||
|
|
}
|
||
|
|
|
||
|
|
iteratePromises(Constructor,arr,function resolver(idx,msg){
|
||
|
|
resolve(msg);
|
||
|
|
},reject);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
return Promise;
|
||
|
|
});
|
||
|
|
|
||
|
|
|
||
|
|
/*!
|
||
|
|
* Symbol-ES6 v0.1.2
|
||
|
|
* ES6 Symbol polyfill in pure ES5.
|
||
|
|
*
|
||
|
|
* @license Copyright (c) 2017-2018 Rousan Ali, MIT License
|
||
|
|
*
|
||
|
|
* Codebase: https://github.com/rousan/symbol-es6
|
||
|
|
* Date: 28th Jan, 2018
|
||
|
|
*/
|
||
|
|
|
||
|
|
(function (global, factory) {
|
||
|
|
|
||
|
|
"use strict";
|
||
|
|
|
||
|
|
if (typeof module === "object" && typeof module.exports === "object") {
|
||
|
|
// For the environment like NodeJS, CommonJS etc where module or
|
||
|
|
// module.exports objects are available
|
||
|
|
module.exports = factory(global);
|
||
|
|
} else {
|
||
|
|
// For browser context, where global object is window
|
||
|
|
factory(global);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* window is for browser environment and global is for NodeJS environment */
|
||
|
|
})(typeof window !== "undefined" ? window : global, function (global) {
|
||
|
|
|
||
|
|
"use strict";
|
||
|
|
|
||
|
|
var defineProperty = Object.defineProperty;
|
||
|
|
|
||
|
|
var defineProperties = Object.defineProperties;
|
||
|
|
|
||
|
|
var symbolHiddenCounter = 0;
|
||
|
|
|
||
|
|
var globalSymbolRegistry = [];
|
||
|
|
|
||
|
|
var slice = Array.prototype.slice;
|
||
|
|
|
||
|
|
var ES6 = typeof global.ES6 === "object" ? global.ES6 : (global.ES6 = {});
|
||
|
|
|
||
|
|
var isArray = Array.isArray;
|
||
|
|
|
||
|
|
var objectToString = Object.prototype.toString;
|
||
|
|
|
||
|
|
var push = Array.prototype.push;
|
||
|
|
|
||
|
|
var emptyFunction = function () {};
|
||
|
|
|
||
|
|
var simpleFunction = function (arg) {
|
||
|
|
return arg;
|
||
|
|
};
|
||
|
|
|
||
|
|
var isCallable = function (fn) {
|
||
|
|
return typeof fn === 'function';
|
||
|
|
};
|
||
|
|
|
||
|
|
var isConstructor = function (fn) {
|
||
|
|
return isCallable(fn);
|
||
|
|
};
|
||
|
|
|
||
|
|
var Iterator = function () {};
|
||
|
|
|
||
|
|
var ArrayIterator = function ArrayIterator(array, flag) {
|
||
|
|
this._array = array;
|
||
|
|
this._flag = flag;
|
||
|
|
this._nextIndex = 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
var StringIterator = function StringIterator(string, flag) {
|
||
|
|
this._string = string;
|
||
|
|
this._flag = flag;
|
||
|
|
this._nextIndex = 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
var isES6Running = function() {
|
||
|
|
return false; /* Now 'false' for testing purpose */
|
||
|
|
};
|
||
|
|
|
||
|
|
var isObject = function (value) {
|
||
|
|
return value !== null && (typeof value === "object" || typeof value === "function");
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6FunctionPrototypeHasInstanceSymbol = function (instance) {
|
||
|
|
if (typeof this !== "function")
|
||
|
|
return false;
|
||
|
|
return instance instanceof this;
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6InstanceOfOperator = function (object, constructor) {
|
||
|
|
if (!isObject(constructor))
|
||
|
|
throw new TypeError("Right-hand side of 'instanceof' is not an object");
|
||
|
|
|
||
|
|
var hasInstanceSymbolProp = constructor[Symbol.hasInstance];
|
||
|
|
if (typeof hasInstanceSymbolProp === "undefined") {
|
||
|
|
return object instanceof constructor;
|
||
|
|
} else if(typeof hasInstanceSymbolProp !== "function") {
|
||
|
|
throw new TypeError(typeof hasInstanceSymbolProp + " is not a function");
|
||
|
|
} else {
|
||
|
|
return hasInstanceSymbolProp.call(constructor, object);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Generates name for a symbol instance and this name will be used as
|
||
|
|
// property key for property symbols internally.
|
||
|
|
var generateSymbolName = function (id) {
|
||
|
|
return "@@_____" + id + "_____";
|
||
|
|
};
|
||
|
|
|
||
|
|
// Generates id for next Symbol instance
|
||
|
|
var getNextSymbolId = function () {
|
||
|
|
return symbolHiddenCounter++;
|
||
|
|
};
|
||
|
|
|
||
|
|
var setupSymbolInternals = function (symbol, desc) {
|
||
|
|
defineProperties(symbol, {
|
||
|
|
_description: {
|
||
|
|
value: desc
|
||
|
|
},
|
||
|
|
_isSymbol: {
|
||
|
|
value: true
|
||
|
|
},
|
||
|
|
_id: {
|
||
|
|
value: getNextSymbolId()
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return symbol;
|
||
|
|
};
|
||
|
|
|
||
|
|
var checkSymbolInternals = function (symbol) {
|
||
|
|
return symbol._isSymbol === true && typeof symbol._id === "number" && typeof symbol._description === "string";
|
||
|
|
};
|
||
|
|
|
||
|
|
var isSymbol = function (symbol) {
|
||
|
|
return symbol instanceof Symbol && checkSymbolInternals(symbol);
|
||
|
|
};
|
||
|
|
|
||
|
|
var symbolFor = function (key) {
|
||
|
|
key = String(key);
|
||
|
|
var registryLength = globalSymbolRegistry.length,
|
||
|
|
record,
|
||
|
|
i = 0;
|
||
|
|
|
||
|
|
for(; i<registryLength; ++i) {
|
||
|
|
record = globalSymbolRegistry[i];
|
||
|
|
if (record.key === key)
|
||
|
|
return record.symbol;
|
||
|
|
}
|
||
|
|
|
||
|
|
record = {
|
||
|
|
key: key,
|
||
|
|
symbol: Symbol(key)
|
||
|
|
};
|
||
|
|
globalSymbolRegistry.push(record);
|
||
|
|
return record.symbol;
|
||
|
|
};
|
||
|
|
|
||
|
|
var symbolKeyFor = function (symbol) {
|
||
|
|
if (!ES6.isSymbol(symbol))
|
||
|
|
throw new TypeError(String(symbol) + " is not a symbol");
|
||
|
|
var registryLength = globalSymbolRegistry.length,
|
||
|
|
record,
|
||
|
|
i = 0;
|
||
|
|
|
||
|
|
for(; i<registryLength; ++i) {
|
||
|
|
record = globalSymbolRegistry[i];
|
||
|
|
if (record.symbol === symbol)
|
||
|
|
return record.key;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/* It affects array1 and appends array2 at the end of array1 */
|
||
|
|
var appendArray = function (array1, array2) {
|
||
|
|
// Returns immediately if these are not array or not array-like objects
|
||
|
|
if (!(typeof array1.length === "number" && array1.length >= 0 && typeof array2.length === "number" && array2.length >= 0))
|
||
|
|
return;
|
||
|
|
var length1 = Math.floor(array1.length),
|
||
|
|
length2 = Math.floor(array2.length),
|
||
|
|
i = 0;
|
||
|
|
|
||
|
|
array1.length = length1 + length2;
|
||
|
|
for (; i<length2; ++i)
|
||
|
|
if (array2.hasOwnProperty(i))
|
||
|
|
array1[length1 + i] = array2[i];
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6ObjectPrototypeToString = function toString() {
|
||
|
|
if (this === undefined || this === null)
|
||
|
|
return objectToString.call(this);
|
||
|
|
// Add support for @@toStringTag symbol
|
||
|
|
if (typeof this[Symbol.toStringTag] === "string")
|
||
|
|
return "[object " + this[Symbol.toStringTag] + "]";
|
||
|
|
else
|
||
|
|
return objectToString.call(this);
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6ArrayPrototypeConcat = function concat() {
|
||
|
|
if (this === undefined || this === null)
|
||
|
|
throw new TypeError("Array.prototype.concat called on null or undefined");
|
||
|
|
|
||
|
|
// Boxing 'this' value to wrapper object
|
||
|
|
var self = Object(this),
|
||
|
|
targets = slice.call(arguments),
|
||
|
|
outputs = []; // Later it may affected by Symbol
|
||
|
|
|
||
|
|
targets.unshift(self);
|
||
|
|
|
||
|
|
targets.forEach(function (target) {
|
||
|
|
// If target is primitive then just push
|
||
|
|
if (!isObject(target))
|
||
|
|
outputs.push(target);
|
||
|
|
// Here Symbol.isConcatSpreadable support is added
|
||
|
|
else if (typeof target[Symbol.isConcatSpreadable] !== "undefined") {
|
||
|
|
if (target[Symbol.isConcatSpreadable]) {
|
||
|
|
appendArray(outputs, target);
|
||
|
|
} else {
|
||
|
|
outputs.push(target);
|
||
|
|
}
|
||
|
|
} else if (isArray(target)) {
|
||
|
|
appendArray(outputs, target);
|
||
|
|
} else {
|
||
|
|
outputs.push(target);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return outputs;
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6ForOfLoop = function (iterable, callback, thisArg) {
|
||
|
|
callback = typeof callback !== "function" ? emptyFunction : callback;
|
||
|
|
if (typeof iterable[Symbol.iterator] !== "function")
|
||
|
|
throw new TypeError("Iterable[Symbol.iterator] is not a function");
|
||
|
|
var iterator = iterable[Symbol.iterator](),
|
||
|
|
iterationResult;
|
||
|
|
if (typeof iterator.next !== "function")
|
||
|
|
throw new TypeError(".iterator.next is not a function");
|
||
|
|
while (true) {
|
||
|
|
iterationResult = iterator.next();
|
||
|
|
if (!isObject(iterationResult))
|
||
|
|
throw new TypeError("Iterator result " + iterationResult + " is not an object");
|
||
|
|
if (iterationResult.done)
|
||
|
|
break;
|
||
|
|
callback.call(thisArg, iterationResult.value);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Provides simple inheritance functionality
|
||
|
|
var simpleInheritance = function (child, parent) {
|
||
|
|
if (typeof child !== "function" || typeof parent !== "function")
|
||
|
|
throw new TypeError("Child and Parent must be function type");
|
||
|
|
|
||
|
|
child.prototype = Object.create(parent.prototype);
|
||
|
|
child.prototype.constructor = child;
|
||
|
|
};
|
||
|
|
|
||
|
|
// Behaves as Symbol function in ES6, take description and returns an unique object,
|
||
|
|
// but in ES6 this function returns 'symbol' primitive typed value.
|
||
|
|
// Its type is 'object' not 'symbol'.
|
||
|
|
// There is no wrapping in this case i.e. Object(sym) = sym.
|
||
|
|
var Symbol = function Symbol(desc) {
|
||
|
|
desc = typeof desc === "undefined" ? "" : String(desc);
|
||
|
|
|
||
|
|
if(this instanceof Symbol)
|
||
|
|
throw new TypeError("Symbol is not a constructor");
|
||
|
|
|
||
|
|
return setupSymbolInternals(Object.create(Symbol.prototype), desc);
|
||
|
|
};
|
||
|
|
|
||
|
|
defineProperties(Symbol, {
|
||
|
|
|
||
|
|
"for": {
|
||
|
|
value: symbolFor,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
},
|
||
|
|
|
||
|
|
"keyFor": {
|
||
|
|
value: symbolKeyFor,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
},
|
||
|
|
|
||
|
|
"hasInstance": {
|
||
|
|
value: Symbol("Symbol.hasInstance")
|
||
|
|
},
|
||
|
|
|
||
|
|
"isConcatSpreadable": {
|
||
|
|
value: Symbol("Symbol.isConcatSpreadable")
|
||
|
|
},
|
||
|
|
|
||
|
|
"iterator": {
|
||
|
|
value: Symbol("Symbol.iterator")
|
||
|
|
},
|
||
|
|
|
||
|
|
"toStringTag": {
|
||
|
|
value: Symbol("Symbol.toStringTag")
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// In ES6, this function returns like 'Symbol(<desc>)', but in this case
|
||
|
|
// this function returns the symbol's internal name to work properly.
|
||
|
|
Symbol.prototype.toString = function () {
|
||
|
|
return generateSymbolName(this._id);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Returns itself but in ES6 It returns 'symbol' typed value.
|
||
|
|
Symbol.prototype.valueOf = function () {
|
||
|
|
return this;
|
||
|
|
};
|
||
|
|
|
||
|
|
// Make Iterator like iterable
|
||
|
|
defineProperty(Iterator.prototype, Symbol.iterator.toString(), {
|
||
|
|
value: function () {return this;},
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
simpleInheritance(ArrayIterator, Iterator);
|
||
|
|
|
||
|
|
simpleInheritance(StringIterator, Iterator);
|
||
|
|
|
||
|
|
defineProperty(ArrayIterator.prototype, Symbol.toStringTag.toString(), {
|
||
|
|
value: "Array Iterator",
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(StringIterator.prototype, Symbol.toStringTag.toString(), {
|
||
|
|
value: "String Iterator",
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
// This iterator works on any Array or TypedArray or array-like objects
|
||
|
|
ArrayIterator.prototype.next = function next() {
|
||
|
|
if (!(this instanceof ArrayIterator))
|
||
|
|
throw new TypeError("Method Array Iterator.prototype.next called on incompatible receiver " + String(this));
|
||
|
|
|
||
|
|
var self = this,
|
||
|
|
nextValue;
|
||
|
|
|
||
|
|
if (self._nextIndex === -1) {
|
||
|
|
return {
|
||
|
|
done: true,
|
||
|
|
value: undefined
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!(typeof self._array.length === "number" && self._array.length >= 0)) {
|
||
|
|
self._nextIndex = -1;
|
||
|
|
return {
|
||
|
|
done: true,
|
||
|
|
value: undefined
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// _flag = 1 for [index, value]
|
||
|
|
// _flag = 2 for [value]
|
||
|
|
// _flag = 3 for [index]
|
||
|
|
if (self._nextIndex < Math.floor(self._array.length)) {
|
||
|
|
if (self._flag === 1)
|
||
|
|
nextValue = [self._nextIndex, self._array[self._nextIndex]];
|
||
|
|
else if (self._flag === 2)
|
||
|
|
nextValue = self._array[self._nextIndex];
|
||
|
|
else if (self._flag === 3)
|
||
|
|
nextValue = self._nextIndex;
|
||
|
|
self._nextIndex++;
|
||
|
|
return {
|
||
|
|
done: false,
|
||
|
|
value: nextValue
|
||
|
|
};
|
||
|
|
} else {
|
||
|
|
self._nextIndex = -1;
|
||
|
|
return {
|
||
|
|
done: true,
|
||
|
|
value: undefined
|
||
|
|
};
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
StringIterator.prototype.next = function next() {
|
||
|
|
if (!(this instanceof StringIterator))
|
||
|
|
throw new TypeError("Method String Iterator.prototype.next called on incompatible receiver " + String(this));
|
||
|
|
|
||
|
|
var self = this,
|
||
|
|
stringObject = new String(this._string),
|
||
|
|
nextValue;
|
||
|
|
|
||
|
|
if (self._nextIndex === -1) {
|
||
|
|
return {
|
||
|
|
done: true,
|
||
|
|
value: undefined
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
if (self._nextIndex < stringObject.length) {
|
||
|
|
nextValue = stringObject[self._nextIndex];
|
||
|
|
self._nextIndex++;
|
||
|
|
return {
|
||
|
|
done: false,
|
||
|
|
value: nextValue
|
||
|
|
};
|
||
|
|
} else {
|
||
|
|
self._nextIndex = -1;
|
||
|
|
return {
|
||
|
|
done: true,
|
||
|
|
value: undefined
|
||
|
|
};
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6ArrayPrototypeIteratorSymbol = function values() {
|
||
|
|
if (this === undefined || this === null)
|
||
|
|
throw new TypeError("Cannot convert undefined or null to object");
|
||
|
|
|
||
|
|
var self = Object(this);
|
||
|
|
return new ArrayIterator(self, 2);
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6StringPrototypeIteratorSymbol = function values() {
|
||
|
|
if (this === undefined || this === null)
|
||
|
|
throw new TypeError("String.prototype[Symbol.iterator] called on null or undefined");
|
||
|
|
return new StringIterator(String(this), 0);
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6ArrayPrototypeEntries = function entries() {
|
||
|
|
if (this === undefined || this === null)
|
||
|
|
throw new TypeError("Cannot convert undefined or null to object");
|
||
|
|
|
||
|
|
var self = Object(this);
|
||
|
|
return new ArrayIterator(self, 1);
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6ArrayPrototypeKeys = function keys() {
|
||
|
|
if (this === undefined || this === null)
|
||
|
|
throw new TypeError("Cannot convert undefined or null to object");
|
||
|
|
var self = Object(this);
|
||
|
|
return new ArrayIterator(self, 3);
|
||
|
|
};
|
||
|
|
|
||
|
|
var SpreadOperatorImpl = function (target, thisArg) {
|
||
|
|
this._target = target;
|
||
|
|
this._values = [];
|
||
|
|
this._thisArg = thisArg;
|
||
|
|
};
|
||
|
|
// All the arguments must be iterable
|
||
|
|
SpreadOperatorImpl.prototype.spread = function () {
|
||
|
|
var self = this;
|
||
|
|
slice.call(arguments).forEach(function (iterable) {
|
||
|
|
ES6.forOf(iterable, function (value) {
|
||
|
|
self._values.push(value);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
return self;
|
||
|
|
};
|
||
|
|
|
||
|
|
SpreadOperatorImpl.prototype.add = function () {
|
||
|
|
var self = this;
|
||
|
|
slice.call(arguments).forEach(function (value) {
|
||
|
|
self._values.push(value);
|
||
|
|
});
|
||
|
|
return self;
|
||
|
|
};
|
||
|
|
|
||
|
|
SpreadOperatorImpl.prototype.call = function (thisArg) {
|
||
|
|
if (typeof this._target !== "function")
|
||
|
|
throw new TypeError("Target is not a function");
|
||
|
|
thisArg = arguments.length <= 0 ? this._thisArg : thisArg;
|
||
|
|
return this._target.apply(thisArg, this._values);
|
||
|
|
};
|
||
|
|
|
||
|
|
SpreadOperatorImpl.prototype.new = function () {
|
||
|
|
if (typeof this._target !== "function")
|
||
|
|
throw new TypeError("Target is not a constructor");
|
||
|
|
|
||
|
|
var temp,
|
||
|
|
returnValue;
|
||
|
|
temp = Object.create(this._target.prototype);
|
||
|
|
returnValue = this._target.apply(temp, this._values);
|
||
|
|
return isObject(returnValue) ? returnValue : temp;
|
||
|
|
};
|
||
|
|
|
||
|
|
// Affects the target array
|
||
|
|
SpreadOperatorImpl.prototype.array = function () {
|
||
|
|
if (!isArray(this._target))
|
||
|
|
throw new TypeError("Target is not a array");
|
||
|
|
push.apply(this._target, this._values);
|
||
|
|
return this._target;
|
||
|
|
};
|
||
|
|
|
||
|
|
// Target must be Array or function
|
||
|
|
var es6SpreadOperator = function spreadOperator(target, thisArg) {
|
||
|
|
if (!(typeof target === "function" || isArray(target)))
|
||
|
|
throw new TypeError("Spread operator only supports on array and function objects at this moment");
|
||
|
|
return new SpreadOperatorImpl(target, thisArg);
|
||
|
|
};
|
||
|
|
|
||
|
|
var es6ArrayFrom = function from(arrayLike, mapFn, thisArg) {
|
||
|
|
var constructor,
|
||
|
|
i = 0,
|
||
|
|
length,
|
||
|
|
outputs;
|
||
|
|
// Use the generic constructor
|
||
|
|
constructor = !isConstructor(this) ? Array : this;
|
||
|
|
if (arrayLike === undefined || arrayLike === null)
|
||
|
|
throw new TypeError("Cannot convert undefined or null to object");
|
||
|
|
|
||
|
|
arrayLike = Object(arrayLike);
|
||
|
|
if (mapFn === undefined)
|
||
|
|
mapFn = simpleFunction;
|
||
|
|
else if (!isCallable(mapFn))
|
||
|
|
throw new TypeError(mapFn + " is not a function");
|
||
|
|
|
||
|
|
if (typeof arrayLike[Symbol.iterator] === "undefined") {
|
||
|
|
if (!(typeof arrayLike.length === "number" && arrayLike.length >= 0)) {
|
||
|
|
outputs = new constructor(0);
|
||
|
|
outputs.length = 0;
|
||
|
|
return outputs;
|
||
|
|
}
|
||
|
|
length = Math.floor(arrayLike.length);
|
||
|
|
outputs = new constructor(length);
|
||
|
|
outputs.length = length;
|
||
|
|
for(; i < length; ++i)
|
||
|
|
outputs[i] = mapFn.call(thisArg, arrayLike[i]);
|
||
|
|
} else {
|
||
|
|
outputs = new constructor();
|
||
|
|
outputs.length = 0;
|
||
|
|
ES6.forOf(arrayLike, function (value) {
|
||
|
|
outputs.length++;
|
||
|
|
outputs[outputs.length - 1] = mapFn.call(thisArg, value);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return outputs;
|
||
|
|
};
|
||
|
|
|
||
|
|
// Export ES6 APIs and add all the patches to support Symbol in ES5
|
||
|
|
// If the running environment already supports ES6 then no patches will be applied,
|
||
|
|
if (isES6Running())
|
||
|
|
return ES6;
|
||
|
|
else {
|
||
|
|
|
||
|
|
// Some ES6 APIs can't be implemented in pure ES5, so this 'ES6' object provides
|
||
|
|
// some equivalent functionality of these features.
|
||
|
|
defineProperties(ES6, {
|
||
|
|
|
||
|
|
// Checks if a JS value is a symbol
|
||
|
|
// It can be used as equivalent api in ES6: typeof symbol === 'symbol'
|
||
|
|
isSymbol: {
|
||
|
|
value: isSymbol,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
},
|
||
|
|
|
||
|
|
// Native ES5 'instanceof' operator does not support @@hasInstance symbol,
|
||
|
|
// this method provides same functionality of ES6 'instanceof' operator.
|
||
|
|
instanceOf: {
|
||
|
|
value: es6InstanceOfOperator,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
},
|
||
|
|
|
||
|
|
// This method behaves exactly same as ES6 for...of loop.
|
||
|
|
forOf: {
|
||
|
|
value: es6ForOfLoop,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
},
|
||
|
|
|
||
|
|
// This method gives same functionality of the spread operator of ES6
|
||
|
|
// It works on only functions and arrays.
|
||
|
|
// Limitation: You can't create array like this [...iterable, , , , 33] by this method,
|
||
|
|
// to achieve this you have to do like this [...iterable, undefined, undefined, undefined, 33]
|
||
|
|
spreadOperator: {
|
||
|
|
value: es6SpreadOperator,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(global, "Symbol", {
|
||
|
|
value: Symbol,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(Function.prototype, Symbol.hasInstance.toString(), {
|
||
|
|
value: es6FunctionPrototypeHasInstanceSymbol
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(Array.prototype, "concat", {
|
||
|
|
value: es6ArrayPrototypeConcat,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(Object.prototype, "toString", {
|
||
|
|
value: es6ObjectPrototypeToString,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(Array.prototype, Symbol.iterator.toString(), {
|
||
|
|
value: es6ArrayPrototypeIteratorSymbol,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(Array, "from", {
|
||
|
|
value: es6ArrayFrom,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(Array.prototype, "entries", {
|
||
|
|
value: es6ArrayPrototypeEntries,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(Array.prototype, "keys", {
|
||
|
|
value: es6ArrayPrototypeKeys,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
|
||
|
|
defineProperty(String.prototype, Symbol.iterator.toString(), {
|
||
|
|
value: es6StringPrototypeIteratorSymbol,
|
||
|
|
writable: true,
|
||
|
|
configurable: true
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
return ES6;
|
||
|
|
});
|