Commit 5f0fe0dd authored by Yehuda Katz's avatar Yehuda Katz

Update RSVP to use the module transpiler

parent 636dcb2a
# A sample Gemfile
source "https://rubygems.org"
gem "js_module_transpiler", github: "wycats/js_module_transpiler", branch: "master"
GIT
remote: git://github.com/wycats/js_module_transpiler.git
revision: c2f2d529c2e45f32f6c71a5beaef23a75e8286e8
branch: master
specs:
js_module_transpiler (0.0.1)
thor
GEM
remote: https://rubygems.org/
specs:
thor (0.16.0)
PLATFORMS
ruby
DEPENDENCIES
js_module_transpiler!
require "bundler/setup"
require "js_module_transpiler"
directory "browser" directory "browser"
file "browser/rsvp.js" => ["browser", "lib/rsvp.js"] do file "browser/rsvp.js" => ["browser", "lib/rsvp.js"] do
library = File.read("lib/rsvp.js") library = File.read("lib/rsvp.js")
open "browser/rsvp.js", "w" do |file| open "browser/rsvp.js", "w" do |file|
file.puts "(function(exports) { #{library} })(window.RSVP = {});" converter = JsModuleTranspiler::Compiler.new(File.read("./lib/rsvp.js"), "rsvp", into: "RSVP")
file.puts converter.to_globals
end end
end end
file "browser/rsvp-amd.js" => ["browser", "lib/rsvp.js"] do file "browser/rsvp-amd.js" => ["browser", "lib/rsvp.js"] do
library = File.read("lib/rsvp.js") library = File.read("lib/rsvp.js")
open "browser/rsvp-amd.js", "w" do |file| open "browser/rsvp-amd.js", "w" do |file|
file.puts "define(function(require, exports, module) { #{library} });" require "js_module_transpiler"
converter = JsModuleTranspiler::Compiler.new(File.read("./lib/rsvp.js"), "rsvp")
file.puts converter.to_amd
end end
end end
...@@ -22,6 +29,16 @@ file "browser/rsvp.min.js" => "browser/rsvp.js" do ...@@ -22,6 +29,16 @@ file "browser/rsvp.min.js" => "browser/rsvp.js" do
end end
end end
file "tests/rsvp.js" => "lib/rsvp.js" do
library = File.read("lib/rsvp.js")
open "tests/rsvp.js", "w" do |file|
require "js_module_transpiler"
converter = JsModuleTranspiler::Compiler.new(File.read("./lib/rsvp.js"), "rsvp")
file.puts converter.to_cjs
end
end
task :dist => ["browser/rsvp.js", "browser/rsvp.min.js", "browser/rsvp-amd.js"] task :dist => ["browser/rsvp.js", "browser/rsvp.min.js", "browser/rsvp-amd.js"]
task :push => :dist do task :push => :dist do
...@@ -40,7 +57,7 @@ task :update_tests => "promise-tests" do ...@@ -40,7 +57,7 @@ task :update_tests => "promise-tests" do
end end
end end
task :test => :update_tests do task :test => [:update_tests, "tests/rsvp.js"] do
cd "promise-tests" do cd "promise-tests" do
sh "node ./lib/cli.js all ../tests/test-adapter.js" sh "node ./lib/cli.js all ../tests/test-adapter.js"
end end
......
define(function(require, exports, module) { "use strict"; define("rsvp",
["exports"],
var browserGlobal = (typeof window !== 'undefined') ? window : {}; function(__exports__) {
"use strict";
var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; var browserGlobal = (typeof window !== 'undefined') ? window : {};
var async;
var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
if (typeof process !== 'undefined') { var async;
async = function(callback, binding) {
process.nextTick(function() { if (typeof process !== 'undefined' &&
callback.call(binding); {}.toString.call(process) === '[object process]') {
}); async = function(callback, binding) {
}; process.nextTick(function() {
} else if (MutationObserver) { callback.call(binding);
var queue = []; });
};
var observer = new MutationObserver(function() { } else if (MutationObserver) {
var toProcess = queue.slice(); var queue = [];
queue = [];
var observer = new MutationObserver(function() {
toProcess.forEach(function(tuple) { var toProcess = queue.slice();
var callback = tuple[0], binding = tuple[1]; queue = [];
callback.call(binding);
}); toProcess.forEach(function(tuple) {
}); var callback = tuple[0], binding = tuple[1];
callback.call(binding);
});
});
var element = document.createElement('div');
observer.observe(element, { attributes: true });
async = function(callback, binding) {
queue.push([callback, binding]);
element.setAttribute('drainQueue', 'drainQueue');
};
} else {
async = function(callback, binding) {
setTimeout(function() {
callback.call(binding);
}, 1);
};
}
var element = document.createElement('div');
observer.observe(element, { attributes: true });
async = function(callback, binding) { var Event = function(type, options) {
queue.push([callback, binding]); this.type = type;
element.setAttribute('drainQueue', 'drainQueue');
};
} else {
async = function(callback, binding) {
setTimeout(function() {
callback.call(binding);
}, 1);
};
}
exports.async = async; for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
var Event = exports.Event = function(type, options) { this[option] = options[option];
this.type = type; }
};
for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
this[option] = options[option]; var indexOf = function(callbacks, callback) {
} for (var i=0, l=callbacks.length; i<l; i++) {
}; if (callbacks[i][0] === callback) { return i; }
}
var indexOf = function(callbacks, callback) { return -1;
for (var i=0, l=callbacks.length; i<l; i++) { };
if (callbacks[i][0] === callback) { return i; }
}
return -1; var callbacksFor = function(object) {
}; var callbacks = object._promiseCallbacks;
var callbacksFor = function(object) { if (!callbacks) {
var callbacks = object._promiseCallbacks; callbacks = object._promiseCallbacks = {};
}
if (!callbacks) { return callbacks;
callbacks = object._promiseCallbacks = {}; };
}
return callbacks; var EventTarget = {
}; mixin: function(object) {
object.on = this.on;
object.off = this.off;
object.trigger = this.trigger;
return object;
},
var EventTarget = exports.EventTarget = { on: function(eventNames, callback, binding) {
mixin: function(object) { var allCallbacks = callbacksFor(this), callbacks, eventName;
object.on = this.on; eventNames = eventNames.split(/\s+/);
object.off = this.off; binding = binding || this;
object.trigger = this.trigger;
return object;
},
on: function(eventName, callback, binding) { while (eventName = eventNames.shift()) {
var allCallbacks = callbacksFor(this), callbacks; callbacks = allCallbacks[eventName];
binding = binding || this;
callbacks = allCallbacks[eventName]; if (!callbacks) {
callbacks = allCallbacks[eventName] = [];
}
if (!callbacks) { if (indexOf(callbacks, callback) === -1) {
callbacks = allCallbacks[eventName] = []; callbacks.push([callback, binding]);
} }
}
},
if (indexOf(callbacks, callback) === -1) { off: function(eventNames, callback) {
callbacks.push([callback, binding]); var allCallbacks = callbacksFor(this), callbacks, eventName, index;
} eventNames = eventNames.split(/\s+/);
},
off: function(eventName, callback) { while (eventName = eventNames.shift()) {
var allCallbacks = callbacksFor(this), callbacks; if (!callback) {
allCallbacks[eventName] = [];
continue;
}
if (!callback) { callbacks = allCallbacks[eventName];
allCallbacks[eventName] = [];
return;
}
callbacks = allCallbacks[eventName]; index = indexOf(callbacks, callback);
var index = indexOf(callbacks, callback); if (index !== -1) { callbacks.splice(index, 1); }
}
},
if (index !== -1) { callbacks.splice(index, 1); } trigger: function(eventName, options) {
}, var allCallbacks = callbacksFor(this),
callbacks, callbackTuple, callback, binding, event;
trigger: function(eventName, options) { if (callbacks = allCallbacks[eventName]) {
var allCallbacks = callbacksFor(this), for (var i=0, l=callbacks.length; i<l; i++) {
callbacks, callbackTuple, callback, binding, event; callbackTuple = callbacks[i];
callback = callbackTuple[0];
binding = callbackTuple[1];
if (callbacks = allCallbacks[eventName]) { if (typeof options !== 'object') {
for (var i=0, l=callbacks.length; i<l; i++) { options = { detail: options };
callbackTuple = callbacks[i]; }
callback = callbackTuple[0];
binding = callbackTuple[1];
if (typeof options !== 'object') { event = new Event(eventName, options);
options = { detail: options }; callback.call(binding, event);
}
} }
}
};
var Promise = function() {
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
};
var noop = function() {};
event = new Event(eventName, options); var invokeCallback = function(type, promise, callback, event) {
callback.call(binding, event); var value, error;
if (callback) {
try {
value = callback(event.detail);
} catch(e) {
error = e;
}
} else {
value = event.detail;
} }
}
}
};
var Promise = exports.Promise = function() { if (value instanceof Promise) {
this.on('promise:resolved', function(event) { value.then(function(value) {
this.trigger('success', { detail: event.detail }); promise.resolve(value);
}, this); }, function(error) {
promise.reject(error);
});
} else if (callback && value) {
promise.resolve(value);
} else if (error) {
promise.reject(error);
} else {
promise[type](value);
}
};
Promise.prototype = {
then: function(done, fail) {
var thenPromise = new Promise();
if (this.isResolved) {
async(function() {
invokeCallback('resolve', thenPromise, done, { detail: this.resolvedValue });
}, this);
}
if (this.isRejected) {
async(function() {
invokeCallback('reject', thenPromise, fail, { detail: this.rejectedValue });
}, this);
}
this.on('promise:failed', function(event) { this.on('promise:resolved', function(event) {
this.trigger('error', { detail: event.detail }); invokeCallback('resolve', thenPromise, done, event);
}, this); });
};
var noop = function() {}; this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
var invokeCallback = function(type, promise, callback, event) { return thenPromise;
var value, error; },
if (callback) { resolve: function(value) {
try { resolve(this, value);
value = callback(event.detail);
} catch(e) { this.resolve = noop;
error = e; this.reject = noop;
},
reject: function(value) {
reject(this, value);
this.resolve = noop;
this.reject = noop;
}
};
function resolve(promise, value) {
async(function() {
promise.trigger('promise:resolved', { detail: value });
promise.isResolved = true;
promise.resolvedValue = value;
});
} }
} else {
value = event.detail; function reject(promise, value) {
} async(function() {
promise.trigger('promise:failed', { detail: value });
if (value instanceof Promise) { promise.isRejected = true;
value.then(function(value) { promise.rejectedValue = value;
promise.resolve(value); });
}, function(error) { }
promise.reject(error);
}); EventTarget.mixin(Promise.prototype);
} else if (callback && value) { __exports__.async = async;
promise.resolve(value); __exports__.Event = Event;
} else if (error) { __exports__.EventTarget = EventTarget;
promise.reject(error); __exports__.Promise = Promise;
} else { });
promise[type](value);
}
};
Promise.prototype = {
then: function(done, fail) {
var thenPromise = new Promise();
this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event);
});
this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
return thenPromise;
},
resolve: function(value) {
exports.async(function() {
this.trigger('promise:resolved', { detail: value });
this.isResolved = value;
}, this);
this.resolve = noop;
this.reject = noop;
},
reject: function(value) {
exports.async(function() {
this.trigger('promise:failed', { detail: value });
this.isRejected = value;
}, this);
this.resolve = noop;
this.reject = noop;
}
};
EventTarget.mixin(Promise.prototype);
});
(function(exports) { "use strict"; (function(exports) {
"use strict";
var browserGlobal = (typeof window !== 'undefined') ? window : {}; var browserGlobal = (typeof window !== 'undefined') ? window : {};
var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var async; var async;
if (typeof process !== 'undefined') { if (typeof process !== 'undefined' &&
async = function(callback, binding) { {}.toString.call(process) === '[object process]') {
process.nextTick(function() { async = function(callback, binding) {
callback.call(binding); process.nextTick(function() {
callback.call(binding);
});
};
} else if (MutationObserver) {
var queue = [];
var observer = new MutationObserver(function() {
var toProcess = queue.slice();
queue = [];
toProcess.forEach(function(tuple) {
var callback = tuple[0], binding = tuple[1];
callback.call(binding);
});
}); });
};
} else if (MutationObserver) {
var queue = [];
var observer = new MutationObserver(function() { var element = document.createElement('div');
var toProcess = queue.slice(); observer.observe(element, { attributes: true });
queue = [];
toProcess.forEach(function(tuple) { async = function(callback, binding) {
var callback = tuple[0], binding = tuple[1]; queue.push([callback, binding]);
callback.call(binding); element.setAttribute('drainQueue', 'drainQueue');
}); };
}); } else {
async = function(callback, binding) {
setTimeout(function() {
callback.call(binding);
}, 1);
};
}
var element = document.createElement('div');
observer.observe(element, { attributes: true });
async = function(callback, binding) { var Event = function(type, options) {
queue.push([callback, binding]); this.type = type;
element.setAttribute('drainQueue', 'drainQueue');
};
} else {
async = function(callback, binding) {
setTimeout(function() {
callback.call(binding);
}, 1);
};
}
exports.async = async; for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
var Event = exports.Event = function(type, options) { this[option] = options[option];
this.type = type; }
};
for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
this[option] = options[option]; var indexOf = function(callbacks, callback) {
} for (var i=0, l=callbacks.length; i<l; i++) {
}; if (callbacks[i][0] === callback) { return i; }
}
var indexOf = function(callbacks, callback) { return -1;
for (var i=0, l=callbacks.length; i<l; i++) { };
if (callbacks[i][0] === callback) { return i; }
}
return -1; var callbacksFor = function(object) {
}; var callbacks = object._promiseCallbacks;
var callbacksFor = function(object) { if (!callbacks) {
var callbacks = object._promiseCallbacks; callbacks = object._promiseCallbacks = {};
}
if (!callbacks) { return callbacks;
callbacks = object._promiseCallbacks = {}; };
}
return callbacks; var EventTarget = {
}; mixin: function(object) {
object.on = this.on;
object.off = this.off;
object.trigger = this.trigger;
return object;
},
var EventTarget = exports.EventTarget = { on: function(eventNames, callback, binding) {
mixin: function(object) { var allCallbacks = callbacksFor(this), callbacks, eventName;
object.on = this.on; eventNames = eventNames.split(/\s+/);
object.off = this.off; binding = binding || this;
object.trigger = this.trigger;
return object;
},
on: function(eventName, callback, binding) { while (eventName = eventNames.shift()) {
var allCallbacks = callbacksFor(this), callbacks; callbacks = allCallbacks[eventName];
binding = binding || this;
callbacks = allCallbacks[eventName]; if (!callbacks) {
callbacks = allCallbacks[eventName] = [];
}
if (!callbacks) { if (indexOf(callbacks, callback) === -1) {
callbacks = allCallbacks[eventName] = []; callbacks.push([callback, binding]);
} }
}
},
if (indexOf(callbacks, callback) === -1) { off: function(eventNames, callback) {
callbacks.push([callback, binding]); var allCallbacks = callbacksFor(this), callbacks, eventName, index;
} eventNames = eventNames.split(/\s+/);
},
off: function(eventName, callback) { while (eventName = eventNames.shift()) {
var allCallbacks = callbacksFor(this), callbacks; if (!callback) {
allCallbacks[eventName] = [];
continue;
}
if (!callback) { callbacks = allCallbacks[eventName];
allCallbacks[eventName] = [];
return;
}
callbacks = allCallbacks[eventName]; index = indexOf(callbacks, callback);
var index = indexOf(callbacks, callback); if (index !== -1) { callbacks.splice(index, 1); }
}
},
if (index !== -1) { callbacks.splice(index, 1); } trigger: function(eventName, options) {
}, var allCallbacks = callbacksFor(this),
callbacks, callbackTuple, callback, binding, event;
trigger: function(eventName, options) { if (callbacks = allCallbacks[eventName]) {
var allCallbacks = callbacksFor(this), for (var i=0, l=callbacks.length; i<l; i++) {
callbacks, callbackTuple, callback, binding, event; callbackTuple = callbacks[i];
callback = callbackTuple[0];
binding = callbackTuple[1];
if (callbacks = allCallbacks[eventName]) { if (typeof options !== 'object') {
for (var i=0, l=callbacks.length; i<l; i++) { options = { detail: options };
callbackTuple = callbacks[i]; }
callback = callbackTuple[0];
binding = callbackTuple[1];
if (typeof options !== 'object') { event = new Event(eventName, options);
options = { detail: options }; callback.call(binding, event);
} }
event = new Event(eventName, options);
callback.call(binding, event);
} }
} }
} };
};
var Promise = exports.Promise = function() {
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
this.on('promise:failed', function(event) { var Promise = function() {
this.trigger('error', { detail: event.detail }); this.on('promise:resolved', function(event) {
}, this); this.trigger('success', { detail: event.detail });
}; }, this);
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
};
var noop = function() {}; var noop = function() {};
var invokeCallback = function(type, promise, callback, event) { var invokeCallback = function(type, promise, callback, event) {
var value, error; var value, error;
if (callback) { if (callback) {
try { try {
value = callback(event.detail); value = callback(event.detail);
} catch(e) { } catch(e) {
error = e; error = e;
}
} else {
value = event.detail;
} }
} else {
value = event.detail;
}
if (value instanceof Promise) { if (value instanceof Promise) {
value.then(function(value) { value.then(function(value) {
promise.resolve(value);
}, function(error) {
promise.reject(error);
});
} else if (callback && value) {
promise.resolve(value); promise.resolve(value);
}, function(error) { } else if (error) {
promise.reject(error); promise.reject(error);
}); } else {
} else if (callback && value) { promise[type](value);
promise.resolve(value); }
} else if (error) { };
promise.reject(error);
} else {
promise[type](value);
}
};
Promise.prototype = { Promise.prototype = {
then: function(done, fail) { then: function(done, fail) {
var thenPromise = new Promise(); var thenPromise = new Promise();
this.on('promise:resolved', function(event) { if (this.isResolved) {
invokeCallback('resolve', thenPromise, done, event); async(function() {
}); invokeCallback('resolve', thenPromise, done, { detail: this.resolvedValue });
}, this);
}
this.on('promise:failed', function(event) { if (this.isRejected) {
invokeCallback('reject', thenPromise, fail, event); async(function() {
}); invokeCallback('reject', thenPromise, fail, { detail: this.rejectedValue });
}, this);
}
return thenPromise; this.on('promise:resolved', function(event) {
}, invokeCallback('resolve', thenPromise, done, event);
});
resolve: function(value) { this.on('promise:failed', function(event) {
exports.async(function() { invokeCallback('reject', thenPromise, fail, event);
this.trigger('promise:resolved', { detail: value }); });
this.isResolved = value;
}, this);
this.resolve = noop; return thenPromise;
this.reject = noop; },
},
reject: function(value) { resolve: function(value) {
exports.async(function() { resolve(this, value);
this.trigger('promise:failed', { detail: value });
this.isRejected = value; this.resolve = noop;
}, this); this.reject = noop;
},
reject: function(value) {
reject(this, value);
this.resolve = noop; this.resolve = noop;
this.reject = noop; this.reject = noop;
}
};
function resolve(promise, value) {
async(function() {
promise.trigger('promise:resolved', { detail: value });
promise.isResolved = true;
promise.resolvedValue = value;
});
}
function reject(promise, value) {
async(function() {
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedValue = value;
});
} }
};
EventTarget.mixin(Promise.prototype); EventTarget.mixin(Promise.prototype);
})(window.RSVP = {}); exports.async = async;
exports.Event = Event;
exports.EventTarget = EventTarget;
exports.Promise = Promise;
})(window.RSVP = {});
(function(a){"use strict";var b=typeof window!="undefined"?window:{},c=b.MutationObserver||b.WebKitMutationObserver,d;if(typeof process!="undefined")d=function(a,b){process.nextTick(function(){a.call(b)})};else if(c){var e=[],f=new c(function(){var a=e.slice();e=[],a.forEach(function(a){var b=a[0],c=a[1];b.call(c)})}),g=document.createElement("div");f.observe(g,{attributes:!0}),d=function(a,b){e.push([a,b]),g.setAttribute("drainQueue","drainQueue")}}else d=function(a,b){setTimeout(function(){a.call(b)},1)};a.async=d;var h=a.Event=function(a,b){this.type=a;for(var c in b){if(!b.hasOwnProperty(c))continue;this[c]=b[c]}},i=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c][0]===b)return c;return-1},j=function(a){var b=a._promiseCallbacks;b||(b=a._promiseCallbacks={});return b},k=a.EventTarget={mixin:function(a){a.on=this.on,a.off=this.off,a.trigger=this.trigger;return a},on:function(a,b,c){var d=j(this),e;c=c||this,e=d[a],e||(e=d[a]=[]),i(e,b)===-1&&e.push([b,c])},off:function(a,b){var c=j(this),d;if(!b)c[a]=[];else{d=c[a];var e=i(d,b);e!==-1&&d.splice(e,1)}},trigger:function(a,b){var c=j(this),d,e,f,g,i;if(d=c[a])for(var k=0,l=d.length;k<l;k++)e=d[k],f=e[0],g=e[1],typeof b!="object"&&(b={detail:b}),i=new h(a,b),f.call(g,i)}},l=a.Promise=function(){this.on("promise:resolved",function(a){this.trigger("success",{detail:a.detail})},this),this.on("promise:failed",function(a){this.trigger("error",{detail:a.detail})},this)},m=function(){},n=function(a,b,c,d){var e,f;if(c)try{e=c(d.detail)}catch(g){f=g}else e=d.detail;e instanceof l?e.then(function(a){b.resolve(a)},function(a){b.reject(a)}):c&&e?b.resolve(e):f?b.reject(f):b[a](e)};l.prototype={then:function(a,b){var c=new l;this.on("promise:resolved",function(b){n("resolve",c,a,b)}),this.on("promise:failed",function(a){n("reject",c,b,a)});return c},resolve:function(b){a.async(function(){this.trigger("promise:resolved",{detail:b}),this.isResolved=b},this),this.resolve=m,this.reject=m},reject:function(b){a.async(function(){this.trigger("promise:failed",{detail:b}),this.isRejected=b},this),this.resolve=m,this.reject=m}},k.mixin(l.prototype)})(window.RSVP={}) (function(a){function p(a,b){d(function(){a.trigger("promise:failed",{detail:b}),a.isRejected=!0,a.rejectedValue=b})}function o(a,b){d(function(){a.trigger("promise:resolved",{detail:b}),a.isResolved=!0,a.resolvedValue=b})}"use strict";var b=typeof window!="undefined"?window:{},c=b.MutationObserver||b.WebKitMutationObserver,d;if(typeof process!="undefined"&&{}.toString.call(process)==="[object process]")d=function(a,b){process.nextTick(function(){a.call(b)})};else if(c){var e=[],f=new c(function(){var a=e.slice();e=[],a.forEach(function(a){var b=a[0],c=a[1];b.call(c)})}),g=document.createElement("div");f.observe(g,{attributes:!0}),d=function(a,b){e.push([a,b]),g.setAttribute("drainQueue","drainQueue")}}else d=function(a,b){setTimeout(function(){a.call(b)},1)};var h=function(a,b){this.type=a;for(var c in b){if(!b.hasOwnProperty(c))continue;this[c]=b[c]}},i=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c][0]===b)return c;return-1},j=function(a){var b=a._promiseCallbacks;b||(b=a._promiseCallbacks={});return b},k={mixin:function(a){a.on=this.on,a.off=this.off,a.trigger=this.trigger;return a},on:function(a,b,c){var d=j(this),e,f;a=a.split(/\s+/),c=c||this;while(f=a.shift())e=d[f],e||(e=d[f]=[]),i(e,b)===-1&&e.push([b,c])},off:function(a,b){var c=j(this),d,e,f;a=a.split(/\s+/);while(e=a.shift()){if(!b){c[e]=[];continue}d=c[e],f=i(d,b),f!==-1&&d.splice(f,1)}},trigger:function(a,b){var c=j(this),d,e,f,g,i;if(d=c[a])for(var k=0,l=d.length;k<l;k++)e=d[k],f=e[0],g=e[1],typeof b!="object"&&(b={detail:b}),i=new h(a,b),f.call(g,i)}},l=function(){this.on("promise:resolved",function(a){this.trigger("success",{detail:a.detail})},this),this.on("promise:failed",function(a){this.trigger("error",{detail:a.detail})},this)},m=function(){},n=function(a,b,c,d){var e,f;if(c)try{e=c(d.detail)}catch(g){f=g}else e=d.detail;e instanceof l?e.then(function(a){b.resolve(a)},function(a){b.reject(a)}):c&&e?b.resolve(e):f?b.reject(f):b[a](e)};l.prototype={then:function(a,b){var c=new l;this.isResolved&&d(function(){n("resolve",c,a,{detail:this.resolvedValue})},this),this.isRejected&&d(function(){n("reject",c,b,{detail:this.rejectedValue})},this),this.on("promise:resolved",function(b){n("resolve",c,a,b)}),this.on("promise:failed",function(a){n("reject",c,b,a)});return c},resolve:function(a){o(this,a),this.resolve=m,this.reject=m},reject:function(a){p(this,a),this.resolve=m,this.reject=m}},k.mixin(l.prototype),a.async=d,a.Event=h,a.EventTarget=k,a.Promise=l})(window.RSVP={})
'use strict';
var browserGlobal = (typeof window !== 'undefined') ? window : {}; var browserGlobal = (typeof window !== 'undefined') ? window : {};
var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
...@@ -40,9 +38,9 @@ if (typeof process !== 'undefined' && ...@@ -40,9 +38,9 @@ if (typeof process !== 'undefined' &&
}; };
} }
exports.async = async; export async;
var Event = exports.Event = function(type, options) { var Event = function(type, options) {
this.type = type; this.type = type;
for (var option in options) { for (var option in options) {
...@@ -52,6 +50,8 @@ var Event = exports.Event = function(type, options) { ...@@ -52,6 +50,8 @@ var Event = exports.Event = function(type, options) {
} }
}; };
export Event;
var indexOf = function(callbacks, callback) { var indexOf = function(callbacks, callback) {
for (var i=0, l=callbacks.length; i<l; i++) { for (var i=0, l=callbacks.length; i<l; i++) {
if (callbacks[i][0] === callback) { return i; } if (callbacks[i][0] === callback) { return i; }
...@@ -70,7 +70,7 @@ var callbacksFor = function(object) { ...@@ -70,7 +70,7 @@ var callbacksFor = function(object) {
return callbacks; return callbacks;
}; };
var EventTarget = exports.EventTarget = { var EventTarget = {
mixin: function(object) { mixin: function(object) {
object.on = this.on; object.on = this.on;
object.off = this.off; object.off = this.off;
...@@ -135,7 +135,9 @@ var EventTarget = exports.EventTarget = { ...@@ -135,7 +135,9 @@ var EventTarget = exports.EventTarget = {
} }
}; };
var Promise = exports.Promise = function() { export EventTarget;
var Promise = function() {
this.on('promise:resolved', function(event) { this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail }); this.trigger('success', { detail: event.detail });
}, this); }, this);
...@@ -145,6 +147,8 @@ var Promise = exports.Promise = function() { ...@@ -145,6 +147,8 @@ var Promise = exports.Promise = function() {
}, this); }, this);
}; };
export Promise;
var noop = function() {}; var noop = function() {};
var invokeCallback = function(type, promise, callback, event) { var invokeCallback = function(type, promise, callback, event) {
...@@ -179,6 +183,18 @@ Promise.prototype = { ...@@ -179,6 +183,18 @@ Promise.prototype = {
then: function(done, fail) { then: function(done, fail) {
var thenPromise = new Promise(); var thenPromise = new Promise();
if (this.isResolved) {
async(function() {
invokeCallback('resolve', thenPromise, done, { detail: this.resolvedValue });
}, this);
}
if (this.isRejected) {
async(function() {
invokeCallback('reject', thenPromise, fail, { detail: this.rejectedValue });
}, this);
}
this.on('promise:resolved', function(event) { this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event); invokeCallback('resolve', thenPromise, done, event);
}); });
...@@ -191,24 +207,34 @@ Promise.prototype = { ...@@ -191,24 +207,34 @@ Promise.prototype = {
}, },
resolve: function(value) { resolve: function(value) {
exports.async(function() { resolve(this, value);
this.trigger('promise:resolved', { detail: value });
this.isResolved = value;
}, this);
this.resolve = noop; this.resolve = noop;
this.reject = noop; this.reject = noop;
}, },
reject: function(value) { reject: function(value) {
exports.async(function() { reject(this, value);
this.trigger('promise:failed', { detail: value });
this.isRejected = value;
}, this);
this.resolve = noop; this.resolve = noop;
this.reject = noop; this.reject = noop;
} }
}; };
function resolve(promise, value) {
async(function() {
promise.trigger('promise:resolved', { detail: value });
promise.isResolved = true;
promise.resolvedValue = value;
});
}
function reject(promise, value) {
async(function() {
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedValue = value;
});
}
EventTarget.mixin(Promise.prototype); EventTarget.mixin(Promise.prototype);
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
switch(name) { switch(name) {
case "assert": return window.assert; case "assert": return window.assert;
case "sinon": return window.sinon; case "sinon": return window.sinon;
case "../lib/rsvp": return RSVP; case "./rsvp": return RSVP;
} }
}; };
</script> </script>
......
"use strict";
var browserGlobal = (typeof window !== 'undefined') ? window : {};
var MutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var async;
if (typeof process !== 'undefined' &&
{}.toString.call(process) === '[object process]') {
async = function(callback, binding) {
process.nextTick(function() {
callback.call(binding);
});
};
} else if (MutationObserver) {
var queue = [];
var observer = new MutationObserver(function() {
var toProcess = queue.slice();
queue = [];
toProcess.forEach(function(tuple) {
var callback = tuple[0], binding = tuple[1];
callback.call(binding);
});
});
var element = document.createElement('div');
observer.observe(element, { attributes: true });
async = function(callback, binding) {
queue.push([callback, binding]);
element.setAttribute('drainQueue', 'drainQueue');
};
} else {
async = function(callback, binding) {
setTimeout(function() {
callback.call(binding);
}, 1);
};
}
var Event = function(type, options) {
this.type = type;
for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
this[option] = options[option];
}
};
var indexOf = function(callbacks, callback) {
for (var i=0, l=callbacks.length; i<l; i++) {
if (callbacks[i][0] === callback) { return i; }
}
return -1;
};
var callbacksFor = function(object) {
var callbacks = object._promiseCallbacks;
if (!callbacks) {
callbacks = object._promiseCallbacks = {};
}
return callbacks;
};
var EventTarget = {
mixin: function(object) {
object.on = this.on;
object.off = this.off;
object.trigger = this.trigger;
return object;
},
on: function(eventNames, callback, binding) {
var allCallbacks = callbacksFor(this), callbacks, eventName;
eventNames = eventNames.split(/\s+/);
binding = binding || this;
while (eventName = eventNames.shift()) {
callbacks = allCallbacks[eventName];
if (!callbacks) {
callbacks = allCallbacks[eventName] = [];
}
if (indexOf(callbacks, callback) === -1) {
callbacks.push([callback, binding]);
}
}
},
off: function(eventNames, callback) {
var allCallbacks = callbacksFor(this), callbacks, eventName, index;
eventNames = eventNames.split(/\s+/);
while (eventName = eventNames.shift()) {
if (!callback) {
allCallbacks[eventName] = [];
continue;
}
callbacks = allCallbacks[eventName];
index = indexOf(callbacks, callback);
if (index !== -1) { callbacks.splice(index, 1); }
}
},
trigger: function(eventName, options) {
var allCallbacks = callbacksFor(this),
callbacks, callbackTuple, callback, binding, event;
if (callbacks = allCallbacks[eventName]) {
for (var i=0, l=callbacks.length; i<l; i++) {
callbackTuple = callbacks[i];
callback = callbackTuple[0];
binding = callbackTuple[1];
if (typeof options !== 'object') {
options = { detail: options };
}
event = new Event(eventName, options);
callback.call(binding, event);
}
}
}
};
var Promise = function() {
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
};
var noop = function() {};
var invokeCallback = function(type, promise, callback, event) {
var value, error;
if (callback) {
try {
value = callback(event.detail);
} catch(e) {
error = e;
}
} else {
value = event.detail;
}
if (value instanceof Promise) {
value.then(function(value) {
promise.resolve(value);
}, function(error) {
promise.reject(error);
});
} else if (callback && value) {
promise.resolve(value);
} else if (error) {
promise.reject(error);
} else {
promise[type](value);
}
};
Promise.prototype = {
then: function(done, fail) {
var thenPromise = new Promise();
if (this.isResolved) {
async(function() {
invokeCallback('resolve', thenPromise, done, { detail: this.resolvedValue });
}, this);
}
if (this.isRejected) {
async(function() {
invokeCallback('reject', thenPromise, fail, { detail: this.rejectedValue });
}, this);
}
this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event);
});
this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
return thenPromise;
},
resolve: function(value) {
resolve(this, value);
this.resolve = noop;
this.reject = noop;
},
reject: function(value) {
reject(this, value);
this.resolve = noop;
this.reject = noop;
}
};
function resolve(promise, value) {
async(function() {
promise.trigger('promise:resolved', { detail: value });
promise.isResolved = true;
promise.resolvedValue = value;
});
}
function reject(promise, value) {
async(function() {
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedValue = value;
});
}
EventTarget.mixin(Promise.prototype);
exports.async = async;
exports.Event = Event;
exports.EventTarget = EventTarget;
exports.Promise = Promise;
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
(function(global) { (function(global) {
'use strict'; 'use strict';
var Promise = require('../lib/rsvp').Promise; var Promise = require('./rsvp').Promise;
var adapter; var adapter;
if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') { if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment