Skip to content

Commit

Permalink
Add Object.create shim so that es6-shim/Promise is ES3 compatible. Ad…
Browse files Browse the repository at this point in the history
…d simple shim test.
  • Loading branch information
briancavalier committed Mar 14, 2014
1 parent f3057ee commit 4bc18fc
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 47 deletions.
57 changes: 35 additions & 22 deletions es6-shim/Promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,19 @@ define(function(require) {
(function(define) { 'use strict';
define(function() {

var forEach = Array.prototype.forEach;

return function makePromise(environment) {

var foreverPendingPromise;
var promiseCycleError;
var tasks = environment.scheduler;

var objectCreate = Object.create ||
function(proto) {
function Child() {}
Child.prototype = proto;
return new Child();
};

/**
* Create a promise whose fate is determined by resolver
* @constructor
Expand Down Expand Up @@ -342,8 +347,8 @@ define(function() {
for (i = 0; i < len; ++i) {
if (i in promises) {
x = promises[i];
if (typeof x === 'object' || typeof x === 'function') {
resolveOne(resolver, results, getHandler(x), i);
if (maybeThenable(x)) {
resolveOne(resolver, results, getHandlerChecked(x), i);
} else {
results[i] = x;
--pending;
Expand Down Expand Up @@ -391,9 +396,9 @@ define(function() {
}

var h = new DeferredHandler();
forEach.call(promises, function(p) {
getHandler(p).when(noop, noop, void 0, h, h.resolve, h.reject);
});
for(var i=0; i<promises.length; ++i) {
getHandler(promises[i]).when(noop, noop, void 0, h, h.resolve, h.reject);
}

return new InternalPromise(h);
}
Expand All @@ -412,7 +417,7 @@ define(function() {
this._handler = handler;
}

InternalPromise.prototype = Object.create(Promise.prototype);
InternalPromise.prototype = objectCreate(Promise.prototype);

/**
* Get an appropriate handler for x
Expand All @@ -423,17 +428,17 @@ define(function() {
*/
function getHandler(x, h) {
if(x instanceof Promise) {
return getHandlerChecked(x, h);
return getHandlerPromise(x, h);
}

if(Object(x) === x) {
return getHandlerUntrusted(x);
}

return new FulfilledHandler(x);
return maybeThenable(x) ? getHandlerUntrusted(x) : new FulfilledHandler(x);
}

function getHandlerChecked(x, h) {
return x instanceof Promise
? getHandlerPromise(x, h) : getHandlerUntrusted(x);
}

function getHandlerPromise(x, h) {
var h2 = x._handler.join();
return h === h2 ? promiseCycleError : h2;
}
Expand Down Expand Up @@ -479,7 +484,7 @@ define(function() {
this.handler = handler;
}

DelegateHandler.prototype = Object.create(Handler.prototype);
DelegateHandler.prototype = objectCreate(Handler.prototype);

DelegateHandler.prototype.join = function() {
return this.handler.join();
Expand Down Expand Up @@ -508,7 +513,7 @@ define(function() {
}
}

DeferredHandler.prototype = Object.create(Handler.prototype);
DeferredHandler.prototype = objectCreate(Handler.prototype);

DeferredHandler.prototype.inspect = function() {
return this.resolved ? this.handler.join().inspect() : toPendingState();
Expand Down Expand Up @@ -581,7 +586,7 @@ define(function() {
}
}

AsyncHandler.prototype = Object.create(DelegateHandler.prototype);
AsyncHandler.prototype = objectCreate(DelegateHandler.prototype);

AsyncHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) {
tasks.enqueue(new RunHandlerTask(resolve, notify, t, receiver, f, r, u, this.join()));
Expand All @@ -599,7 +604,7 @@ define(function() {
this.receiver = receiver;
}

BoundHandler.prototype = Object.create(DelegateHandler.prototype);
BoundHandler.prototype = objectCreate(DelegateHandler.prototype);

BoundHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) {
// Because handlers are allowed to be shared among promises,
Expand All @@ -626,7 +631,7 @@ define(function() {
this.thenable = thenable;
}

ThenableHandler.prototype = Object.create(DeferredHandler.prototype);
ThenableHandler.prototype = objectCreate(DeferredHandler.prototype);

ThenableHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) {
if(!this.assimilated) {
Expand Down Expand Up @@ -663,7 +668,7 @@ define(function() {
this.value = x;
}

FulfilledHandler.prototype = Object.create(Handler.prototype);
FulfilledHandler.prototype = objectCreate(Handler.prototype);

FulfilledHandler.prototype.inspect = function() {
return toFulfilledState(this.value);
Expand Down Expand Up @@ -694,7 +699,7 @@ define(function() {
}
}

RejectedHandler.prototype = Object.create(Handler.prototype);
RejectedHandler.prototype = objectCreate(Handler.prototype);

RejectedHandler.prototype.inspect = function() {
return toRejectedState(this.value);
Expand Down Expand Up @@ -797,6 +802,14 @@ define(function() {
notify.call(t, x);
};

/**
* @param {*} x
* @returns {boolean} false iff x is guaranteed not to be a thenable
*/
function maybeThenable(x) {
return (typeof x === 'object' || typeof x === 'function') && x !== null;
}

/**
* Return f.call(thisArg, x), or if it throws return a rejected promise for
* the thrown exception
Expand Down
33 changes: 33 additions & 0 deletions lib/es6-shim/Promise-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(function(buster, global, define) {

var assert = buster.assert;
var OrigPromise = global.Promise;

define('when/es6-shim/Promise-test', function (require) {

var Promise = require('when/es6-shim/Promise');

buster.testCase('when/es6-shim/PromiseMonitor', {

tearDown: function() {
global.Promise = OrigPromise;
},

'should publish global Promise': function() {
assert.same(Promise, global.Promise);
}

});

});
}(
this.buster || require('buster'),
typeof global !== 'undefined' ? global : this,
typeof define === 'function' && define.amd ? define : function (id, factory) {
var packageName = id.split(/[\/\-\.]/)[0], pathToRoot = id.replace(/[^\/]+/g, '..');
pathToRoot = pathToRoot.length > 2 ? pathToRoot.substr(3) : pathToRoot;
factory(function (moduleId) {
return require(moduleId.indexOf(packageName) === 0 ? pathToRoot + moduleId.substr(packageName.length) : moduleId);
});
}
));
31 changes: 18 additions & 13 deletions lib/makePromise.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
(function(define) { 'use strict';
define(function() {

var forEach = Array.prototype.forEach;

return function makePromise(environment) {

var foreverPendingPromise;
var promiseCycleError;
var tasks = environment.scheduler;

var objectCreate = Object.create ||
function(proto) {
function Child() {}
Child.prototype = proto;
return new Child();
};

/**
* Create a promise whose fate is determined by resolver
* @constructor
Expand Down Expand Up @@ -217,9 +222,9 @@ define(function() {
}

var h = new DeferredHandler();
forEach.call(promises, function(p) {
getHandler(p).when(noop, noop, void 0, h, h.resolve, h.reject);
});
for(var i=0; i<promises.length; ++i) {
getHandler(promises[i]).when(noop, noop, void 0, h, h.resolve, h.reject);
}

return new InternalPromise(h);
}
Expand All @@ -238,7 +243,7 @@ define(function() {
this._handler = handler;
}

InternalPromise.prototype = Object.create(Promise.prototype);
InternalPromise.prototype = objectCreate(Promise.prototype);

/**
* Get an appropriate handler for x
Expand Down Expand Up @@ -305,7 +310,7 @@ define(function() {
this.handler = handler;
}

DelegateHandler.prototype = Object.create(Handler.prototype);
DelegateHandler.prototype = objectCreate(Handler.prototype);

DelegateHandler.prototype.join = function() {
return this.handler.join();
Expand Down Expand Up @@ -334,7 +339,7 @@ define(function() {
}
}

DeferredHandler.prototype = Object.create(Handler.prototype);
DeferredHandler.prototype = objectCreate(Handler.prototype);

DeferredHandler.prototype.inspect = function() {
return this.resolved ? this.handler.join().inspect() : toPendingState();
Expand Down Expand Up @@ -407,7 +412,7 @@ define(function() {
}
}

AsyncHandler.prototype = Object.create(DelegateHandler.prototype);
AsyncHandler.prototype = objectCreate(DelegateHandler.prototype);

AsyncHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) {
tasks.enqueue(new RunHandlerTask(resolve, notify, t, receiver, f, r, u, this.join()));
Expand All @@ -425,7 +430,7 @@ define(function() {
this.receiver = receiver;
}

BoundHandler.prototype = Object.create(DelegateHandler.prototype);
BoundHandler.prototype = objectCreate(DelegateHandler.prototype);

BoundHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) {
// Because handlers are allowed to be shared among promises,
Expand All @@ -452,7 +457,7 @@ define(function() {
this.thenable = thenable;
}

ThenableHandler.prototype = Object.create(DeferredHandler.prototype);
ThenableHandler.prototype = objectCreate(DeferredHandler.prototype);

ThenableHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) {
if(!this.assimilated) {
Expand Down Expand Up @@ -489,7 +494,7 @@ define(function() {
this.value = x;
}

FulfilledHandler.prototype = Object.create(Handler.prototype);
FulfilledHandler.prototype = objectCreate(Handler.prototype);

FulfilledHandler.prototype.inspect = function() {
return toFulfilledState(this.value);
Expand Down Expand Up @@ -520,7 +525,7 @@ define(function() {
}
}

RejectedHandler.prototype = Object.create(Handler.prototype);
RejectedHandler.prototype = objectCreate(Handler.prototype);

RejectedHandler.prototype.inspect = function() {
return toRejectedState(this.value);
Expand Down
7 changes: 0 additions & 7 deletions test/monitor/PromiseMonitor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ define('when/monitor/PromiseMonitor-test', function (require) {

buster.testCase('when/monitor/PromiseMonitor', {

tearDown: function() {
if (typeof console !== 'undefined'
&& console.promiseMonitor instanceof PromiseMonitor) {
console.promiseMonitor = void 0;
}
},

'reject should trigger report': function(done) {
if (typeof console === 'undefined') {
done();
Expand Down
6 changes: 1 addition & 5 deletions unfold/list.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
/** @license MIT License (c) copyright B Cavalier & J Hann */

/**
* unfold
* @author: [email protected]
*/
(function(define) {
define(function(require) {

var unfold = require('../unfold');
var unfold = require('../when').unfold;

/**
* @deprecated
Expand Down

0 comments on commit 4bc18fc

Please sign in to comment.