mirror of
https://github.com/jlengrand/webcomponentsjs.git
synced 2026-03-10 08:51:22 +00:00
Merge pull request #654 from webcomponents/ie-compat
Enhance compatibility with IE
This commit is contained in:
186
src/WebComponents/Promise.js
Normal file
186
src/WebComponents/Promise.js
Normal file
@@ -0,0 +1,186 @@
|
||||
(function() {
|
||||
|
||||
if (!window.Promise) {
|
||||
|
||||
function MakePromise (asap) {
|
||||
function Promise(fn) {
|
||||
if (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError();
|
||||
this._state = null;
|
||||
this._value = null;
|
||||
this._deferreds = []
|
||||
|
||||
doResolve(fn, resolve.bind(this), reject.bind(this));
|
||||
}
|
||||
|
||||
function handle(deferred) {
|
||||
var me = this;
|
||||
if (this._state === null) {
|
||||
this._deferreds.push(deferred);
|
||||
return
|
||||
}
|
||||
asap(function() {
|
||||
var cb = me._state ? deferred.onFulfilled : deferred.onRejected
|
||||
if (typeof cb !== 'function') {
|
||||
(me._state ? deferred.resolve : deferred.reject)(me._value);
|
||||
return;
|
||||
}
|
||||
var ret;
|
||||
try {
|
||||
ret = cb(me._value);
|
||||
}
|
||||
catch (e) {
|
||||
deferred.reject(e);
|
||||
return;
|
||||
}
|
||||
deferred.resolve(ret);
|
||||
})
|
||||
}
|
||||
|
||||
function resolve(newValue) {
|
||||
try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
|
||||
if (newValue === this) throw new TypeError();
|
||||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
|
||||
var then = newValue.then;
|
||||
if (typeof then === 'function') {
|
||||
doResolve(then.bind(newValue), resolve.bind(this), reject.bind(this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._state = true;
|
||||
this._value = newValue;
|
||||
finale.call(this);
|
||||
} catch (e) { reject.call(this, e); }
|
||||
}
|
||||
|
||||
function reject(newValue) {
|
||||
this._state = false;
|
||||
this._value = newValue;
|
||||
finale.call(this);
|
||||
}
|
||||
|
||||
function finale() {
|
||||
for (var i = 0, len = this._deferreds.length; i < len; i++) {
|
||||
handle.call(this, this._deferreds[i]);
|
||||
}
|
||||
this._deferreds = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a potentially misbehaving resolver function and make sure
|
||||
* onFulfilled and onRejected are only called once.
|
||||
*
|
||||
* Makes no guarantees about asynchrony.
|
||||
*/
|
||||
function doResolve(fn, onFulfilled, onRejected) {
|
||||
var done = false;
|
||||
try {
|
||||
fn(function (value) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
onFulfilled(value);
|
||||
}, function (reason) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
onRejected(reason);
|
||||
})
|
||||
} catch (ex) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
onRejected(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Promise.prototype['catch'] = function (onRejected) {
|
||||
return this.then(null, onRejected);
|
||||
};
|
||||
|
||||
Promise.prototype.then = function(onFulfilled, onRejected) {
|
||||
var me = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
handle.call(me, {
|
||||
onFulfilled: onFulfilled,
|
||||
onRejected: onRejected,
|
||||
resolve: resolve,
|
||||
reject: reject
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
Promise.resolve = function (value) {
|
||||
if (value && typeof value === 'object' && value.constructor === Promise) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
resolve(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.reject = function (value) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(value);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return Promise;
|
||||
}
|
||||
|
||||
|
||||
function makeAsync() {
|
||||
var twiddle = document.createTextNode('');
|
||||
var content = 0;
|
||||
return function(callback) {
|
||||
// To preserve timing with Promise microtasks
|
||||
// we create a new observer for every callback.
|
||||
var observer = new MutationObserver(function(mxns) {
|
||||
observer.disconnect();
|
||||
callback();
|
||||
});
|
||||
observer.observe(twiddle, {characterData: true});
|
||||
twiddle.textContent = content++;
|
||||
}
|
||||
}
|
||||
|
||||
window.Promise = MakePromise(makeAsync());
|
||||
|
||||
window.Promise.all = function () {
|
||||
var args = Array.prototype.slice.call(arguments.length === 1 && Array.isArray(arguments[0]) ? arguments[0] : arguments);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (args.length === 0) return resolve([]);
|
||||
var remaining = args.length;
|
||||
function res(i, val) {
|
||||
try {
|
||||
if (val && (typeof val === 'object' || typeof val === 'function')) {
|
||||
var then = val.then;
|
||||
if (typeof then === 'function') {
|
||||
then.call(val, function (val) { res(i, val) }, reject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
args[i] = val;
|
||||
if (--remaining === 0) {
|
||||
resolve(args);
|
||||
}
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
res(i, args[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.Promise.race = function (values) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
for(var i = 0, len = values.length; i < len; i++) {
|
||||
values[i].then(resolve, reject);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -5,7 +5,11 @@
|
||||
"../MutationObserver/MutationObserver.js",
|
||||
"../Template/Template.js",
|
||||
"../HTMLImports/build.json",
|
||||
"../CustomElements/build.json",
|
||||
"Promise.js",
|
||||
"../../custom-elements/custom-elements.min.js",
|
||||
"../../shadydom/shadydom.min.js",
|
||||
"../../shadycss/shadycss.min.js",
|
||||
"lang.js",
|
||||
"dom.js",
|
||||
"unresolved.js"
|
||||
]
|
||||
|
||||
@@ -99,7 +99,33 @@
|
||||
e.initEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable));
|
||||
return e;
|
||||
};
|
||||
if (origEvent) {
|
||||
for (var i in origEvent) {
|
||||
window.Event[i] = origEvent[i];
|
||||
}
|
||||
}
|
||||
window.Event.prototype = origEvent.prototype;
|
||||
}
|
||||
|
||||
if (!window.MouseEvent || isIE && (typeof window.MouseEvent !== 'function')) {
|
||||
var origMouseEvent = window.MouseEvent;
|
||||
window.MouseEvent = function(inType, params) {
|
||||
params = params || {};
|
||||
var e = document.createEvent('MouseEvent');
|
||||
e.initMouseEvent(inType,
|
||||
Boolean(params.bubbles), Boolean(params.cancelable),
|
||||
params.view || window, params.detail,
|
||||
params.screenX, params.screenY, params.clientX, params.clientY,
|
||||
params.ctrlKey, params.altKey, params.shiftKey, params.metaKey,
|
||||
params.button, params.relatedTarget);
|
||||
return e;
|
||||
};
|
||||
if (origMouseEvent) {
|
||||
for (var i in origMouseEvent) {
|
||||
window.MouseEvent[i] = origMouseEvent[i];
|
||||
}
|
||||
}
|
||||
window.MouseEvent.prototype = origMouseEvent.prototype;
|
||||
}
|
||||
|
||||
})(window.WebComponents);
|
||||
|
||||
@@ -10,18 +10,47 @@
|
||||
|
||||
(function(scope) {
|
||||
|
||||
// Old versions of iOS do not have bind.
|
||||
'use strict';
|
||||
|
||||
if (!Function.prototype.bind) {
|
||||
Function.prototype.bind = function(scope) {
|
||||
var self = this;
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return function() {
|
||||
var args2 = args.slice();
|
||||
args2.push.apply(args2, arguments);
|
||||
return self.apply(scope, args2);
|
||||
// Old versions of iOS do not have bind.
|
||||
if (!Function.prototype.bind) {
|
||||
Function.prototype.bind = function(scope) {
|
||||
var self = this;
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return function() {
|
||||
var args2 = args.slice();
|
||||
args2.push.apply(args2, arguments);
|
||||
return self.apply(scope, args2);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 stuff
|
||||
if (!Array.from) {
|
||||
Array.from = function (object) {
|
||||
return [].slice.call(object);
|
||||
};
|
||||
}
|
||||
|
||||
if (!Object.assign) {
|
||||
function assign(target, source) {
|
||||
var n$ = Object.getOwnPropertyNames(source);
|
||||
for (var i=0, p; i < n$.length; i++) {
|
||||
p = n$[i];
|
||||
target[p] = source[p];
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign = function(target, sources) {
|
||||
var args = [].slice.call(arguments, 1);
|
||||
for (var i=0, s; i < args.length; i++) {
|
||||
s = args[i];
|
||||
if (s) {
|
||||
assign(target, s);
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
})(window.WebComponents);
|
||||
|
||||
@@ -54,12 +54,14 @@
|
||||
'WeakMap/WeakMap.js',
|
||||
'Template/Template.js',
|
||||
'HTMLImports/HTMLImports.js',
|
||||
'WebComponents/Promise.js',
|
||||
'WebComponents/pre-polyfill.js',
|
||||
'../../custom-elements/custom-elements.min.js',
|
||||
'../../shadydom/shadydom.min.js',
|
||||
'../../shadycss/shadycss.min.js',
|
||||
'WebComponents/post-polyfill.js',
|
||||
// these scripts are loaded here due to polyfill timing issues
|
||||
'WebComponents/lang.js',
|
||||
'WebComponents/dom.js',
|
||||
'WebComponents/unresolved.js'
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user