Use latest jsonld.js; upgrade to ES6 Promise API.
authorDave Longley <dlongley@digitalbazaar.com>
Fri, 28 Feb 2014 16:34:32 -0500
changeset 2123 722b11e5d8e3
parent 2122 55e2f1b6bb9a
child 2124 0cd24c49aae1
child 2125 824d8e847913
Use latest jsonld.js; upgrade to ES6 Promise API.
playground/Promise.js
playground/index.html
playground/jsonld.js
playground/playground.js
playground/promise-0.1.1.min.js
--- a/playground/Promise.js	Fri Feb 28 09:45:54 2014 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,415 +0,0 @@
-// Copyright (C) 2013:
-//    Alex Russell <slightlyoff@chromium.org>
-//    Yehuda Katz
-//
-// Use of this source code is governed by
-//    http://www.apache.org/licenses/LICENSE-2.0
-
-// FIXME(slightlyoff):
-//    - Document "npm test"
-//    - Change global name from "Promise" to something less conflicty
-(function(global, browserGlobal, underTest) {
-"use strict";
-
-// FIXME(slighltyoff):
-//  * aggregates + tests
-//  * check on fast-forwarding
-
-underTest = !!underTest;
-
-//
-// Async Utilities
-//
-
-// Borrowed from RSVP.js
-var async;
-
-var MutationObserver = browserGlobal.MutationObserver ||
-                       browserGlobal.WebKitMutationObserver;
-var Promise;
-
-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) {
-      tuple[0].call(tuple[1]);
-    });
-  });
-
-  var element = document.createElement('div');
-  observer.observe(element, { attributes: true });
-
-  // Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
-  window.addEventListener('unload', function(){
-    observer.disconnect();
-    observer = null;
-  });
-
-  async = function(callback, binding) {
-    queue.push([callback, binding]);
-    element.setAttribute('drainQueue', 'drainQueue');
-  };
-} else {
-  async = function(callback, binding) {
-    setTimeout(function() {
-      callback.call(binding);
-    }, 1);
-  };
-}
-
-//
-// Object Model Utilities
-//
-
-// defineProperties utilities
-var _readOnlyProperty = function(v) {
-    return {
-      enumerable: true,
-      configurable: false,
-      get: v
-    };
-};
-
-var _method = function(v, e, c, w) {
-    return {
-      enumerable:   !!(e || 0),
-      configurable: !!(c || 1),
-      writable:     !!(w || 1),
-      value:           v || function() {}
-    };
-};
-
-var _pseudoPrivate = function(v) { return _method(v, 0, 1, 0); };
-var _public = function(v) { return _method(v, 1); };
-
-//
-// Promises Utilities
-//
-
-var isThenable = function(any) {
-  try {
-    var f = any.then;
-    if (typeof f == "function") {
-      return true;
-    }
-  } catch (e) { /*squelch*/ }
-  return false;
-};
-
-var AlreadyResolved = function(name) {
-  Error.call(this, name);
-};
-AlreadyResolved.prototype = Object.create(Error.prototype);
-
-var Backlog = function() {
-  var bl = [];
-  bl.pump = function(value) {
-    async(function() {
-      var l = bl.length;
-      var x = 0;
-      while(x < l) {
-        x++;
-        bl.shift()(value);
-      }
-    });
-  };
-  return bl;
-};
-
-//
-// Resolver Constuctor
-//
-
-var Resolver = function(future,
-                        fulfillCallbacks,
-                        rejectCallbacks,
-                        setValue,
-                        setError,
-                        setState) {
-  var isResolved = false;
-
-  var resolver = this;
-  var fulfill = function(value) {
-    // console.log("queueing fulfill with:", value);
-    async(function() {
-      setState("fulfilled");
-      setValue(value);
-      // console.log("fulfilling with:", value);
-      fulfillCallbacks.pump(value);
-    });
-  };
-  var reject = function(reason) {
-    // console.log("queuing reject with:", reason);
-    async(function() {
-      setState("rejected");
-      setError(reason);
-      // console.log("rejecting with:", reason);
-      rejectCallbacks.pump(reason);
-    });
-  };
-  var resolve = function(value) {
-    if (isThenable(value)) {
-      value.then(resolve, reject);
-      return;
-    }
-    fulfill(value);
-  };
-  var ifNotResolved = function(func, name) {
-    return function(value) {
-      if (!isResolved) {
-        isResolved = true;
-        func(value);
-      } else {
-        if (typeof console != "undefined") {
-          console.error("Cannot resolve a Promise multiple times.");
-        }
-      }
-    };
-  };
-
-  // Indirectly resolves the Promise, chaining any passed Promise's resolution
-  this.resolve = ifNotResolved(resolve, "resolve");
-
-  // Directly fulfills the future, no matter what value's type is
-  this.fulfill = ifNotResolved(fulfill, "fulfill");
-
-  // Rejects the future
-  this.reject = ifNotResolved(reject, "reject");
-
-  this.cancel  = function() { resolver.reject(new Error("Cancel")); };
-  this.timeout = function() { resolver.reject(new Error("Timeout")); };
-
-  if (underTest) {
-    Object.defineProperties(this, {
-      _isResolved: _readOnlyProperty(function() { return isResolved; }),
-    });
-  }
-
-  setState("pending");
-};
-
-//
-// Promise Constuctor
-//
-
-var Promise = function(init) {
-  var fulfillCallbacks = new Backlog();
-  var rejectCallbacks = new Backlog();
-  var value;
-  var error;
-  var state = "pending";
-
-  if (underTest) {
-    Object.defineProperties(this, {
-      _value: _readOnlyProperty(function() { return value; }),
-      _error: _readOnlyProperty(function() { return error; }),
-      _state: _readOnlyProperty(function() { return state; }),
-    });
-  }
-
-  Object.defineProperties(this, {
-    _addAcceptCallback: _pseudoPrivate(
-      function(cb) {
-        // console.log("adding fulfill callback:", cb);
-        fulfillCallbacks.push(cb);
-        if (state == "fulfilled") {
-          fulfillCallbacks.pump(value);
-        }
-      }
-    ),
-    _addRejectCallback: _pseudoPrivate(
-      function(cb) {
-        // console.log("adding reject callback:", cb);
-        rejectCallbacks.push(cb);
-        if (state == "rejected") {
-          rejectCallbacks.pump(error);
-        }
-      }
-    ),
-  });
-  var r = new Resolver(this,
-                       fulfillCallbacks, rejectCallbacks,
-                       function(v) { value = v; },
-                       function(e) { error = e; },
-                       function(s) { state = s; })
-  try {
-    if (init) { init(r); }
-  } catch(e) {
-    r.reject(e);
-  }
-};
-
-//
-// Consructor
-//
-
-var isCallback = function(any) {
-  return (typeof any == "function");
-};
-
-// Used in .then()
-var wrap = function(callback, resolver, disposition) {
-  if (!isCallback(callback)) {
-    // If we don't get a callback, we want to forward whatever resolution we get
-    return resolver[disposition].bind(resolver);
-  }
-
-  return function() {
-    try {
-      var r = callback.apply(null, arguments);
-      resolver.resolve(r);
-    } catch(e) {
-      // Exceptions reject the resolver
-      resolver.reject(e);
-    }
-  };
-};
-
-var addCallbacks = function(onfulfill, onreject, scope) {
-  if (isCallback(onfulfill)) {
-    scope._addAcceptCallback(onfulfill);
-  }
-  if (isCallback(onreject)) {
-    scope._addRejectCallback(onreject);
-  }
-  return scope;
-};
-
-//
-// Prototype properties
-//
-
-Promise.prototype = Object.create(null, {
-  "then": _public(function(onfulfill, onreject) {
-    // The logic here is:
-    //    We return a new Promise whose resolution merges with the return from
-    //    onfulfill() or onerror(). If onfulfill() returns a Promise, we forward
-    //    the resolution of that future to the resolution of the returned
-    //    Promise.
-    var f = this;
-    return new Promise(function(r) {
-      addCallbacks(wrap(onfulfill, r, "resolve"),
-                   wrap(onreject, r, "reject"), f);
-    });
-  }),
-  "catch": _public(function(onreject) {
-    var f = this;
-    return new Promise(function(r) {
-      addCallbacks(null, wrap(onreject, r, "reject"), f);
-    });
-  }),
-});
-
-//
-// Statics
-//
-
-Promise.isThenable = isThenable;
-
-var toPromiseList = function(list) {
-  return Array.prototype.slice.call(list).map(Promise.resolve);
-};
-
-Promise.any = function(/*...futuresOrValues*/) {
-  var futures = toPromiseList(arguments);
-  return new Promise(function(r) {
-    if (!futures.length) {
-      r.reject("No futures passed to Promise.any()");
-    } else {
-      var resolved = false;
-      var firstSuccess = function(value) {
-        if (resolved) { return; }
-        resolved = true;
-        r.resolve(value);
-      };
-      var firstFailure = function(reason) {
-        if (resolved) { return; }
-        resolved = true;
-        r.reject(reason);
-      };
-      futures.forEach(function(f, idx) {
-        f.then(firstSuccess, firstFailure);
-      });
-    }
-  });
-};
-
-Promise.every = function(/*...futuresOrValues*/) {
-  var futures = toPromiseList(arguments);
-  return new Promise(function(r) {
-    if (!futures.length) {
-      r.reject("No futures passed to Promise.every()");
-    } else {
-      var values = new Array(futures.length);
-      var count = 0;
-      var accumulate = function(idx, v) {
-        count++;
-        values[idx] = v;
-        if (count == futures.length) {
-          r.resolve(values);
-        }
-      };
-      futures.forEach(function(f, idx) {
-        f.then(accumulate.bind(null, idx), r.reject);
-      });
-    }
-  });
-};
-
-Promise.some = function() {
-  var futures = toPromiseList(arguments);
-  return new Promise(function(r) {
-    if (!futures.length) {
-      r.reject("No futures passed to Promise.some()");
-    } else {
-      var count = 0;
-      var accumulateFailures = function(e) {
-        count++;
-        if (count == futures.length) {
-          r.reject();
-        }
-      };
-      futures.forEach(function(f, idx) {
-        f.then(r.resolve, accumulateFailures);
-      });
-    }
-  });
-};
-
-Promise.fulfill = function(value) {
-  return new Promise(function(r) {
-    r.fulfill(value);
-  });
-};
-
-Promise.resolve = function(value) {
-  return new Promise(function(r) {
-    r.resolve(value);
-  });
-};
-
-Promise.reject = function(reason) {
-  return new Promise(function(r) {
-    r.reject(reason);
-  });
-};
-
-//
-// Export
-//
-
-global.Promise = Promise;
-
-})(this,
-  (typeof window !== 'undefined') ? window : {},
-  this.runningUnderTest||false);
--- a/playground/index.html	Fri Feb 28 09:45:54 2014 -0500
+++ b/playground/index.html	Fri Feb 28 16:34:32 2014 -0500
@@ -217,9 +217,9 @@
 
     <!-- script tags -->
     <script src="jquery-1.9.0.min.js"></script>
-    <script type="text/javascript" src="js_beautify.js"></script>
-    <script type="text/javascript" src="Promise.js"></script>
-    <script type="text/javascript" src="jsonld.js"></script>
+    <script src="js_beautify.js"></script>
+    <script src="promise-0.1.1.min.js"></script>
+    <script src="jsonld.js"></script>
 
     <script>
       (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
--- a/playground/jsonld.js	Fri Feb 28 09:45:54 2014 -0500
+++ b/playground/jsonld.js	Fri Feb 28 16:34:32 2014 -0500
@@ -1043,15 +1043,20 @@
  * @return the promise.
  */
 jsonld.promisify = function(op) {
-  var Promise = _nodejs ? require('./Promise').Promise : global.Promise;
+  try {
+    var Promise = global.Promise || require('./Promise').Promise;
+  }
+  catch(e) {
+    throw new Error('Unable to find a Promise implementation.');
+  }
   var args = Array.prototype.slice.call(arguments, 1);
-  return new Promise(function(resolver) {
+  return new Promise(function(resolve, reject) {
     op.apply(null, args.concat(function(err, value) {
-      if(err) {
-        resolver.reject(err);
+      if(!err) {
+        resolve(value);
       }
       else {
-        resolver.resolve(value);
+        reject(err);
       }
     }));
   });
@@ -1115,10 +1120,9 @@
 // define setImmediate and nextTick
 if(typeof process === 'undefined' || !process.nextTick) {
   if(typeof setImmediate === 'function') {
-    jsonld.setImmediate = setImmediate;
-    jsonld.nextTick = function(callback) {
+    jsonld.setImmediate = jsonld.nextTick = function(callback) {
       return setImmediate(callback);
-    };
+    }
   }
   else {
     jsonld.setImmediate = function(callback) {
--- a/playground/playground.js	Fri Feb 28 09:45:54 2014 -0500
+++ b/playground/playground.js	Fri Feb 28 16:34:32 2014 -0500
@@ -330,65 +330,43 @@
    * @param param the JSON-LD param to use.
    */
   playground.performAction = function(input, param) {
-    return new Promise(function(resolver) {
-      var processor = new jsonld.JsonLdProcessor();
-
-      // set base IRI
-      var options = {base: (document.baseURI || document.URL)};
-
-      if(playground.activeTab === 'tab-compacted') {
-        processor.compact(input, param, options).then(function(compacted) {
-
-          playground.outputs["compacted"]
-            .setValue(playground.humanize(compacted));
-
-          resolver.resolve();
-        }, resolver.reject);
-      }
-      else if(playground.activeTab === 'tab-expanded') {
-        processor.expand(input, options).then(function(expanded) {
-
-          playground.outputs["expanded"]
-            .setValue(playground.humanize(expanded));
-
-          resolver.resolve();
-        }, resolver.reject);
-      }
-      else if(playground.activeTab === 'tab-flattened') {
-        processor.flatten(input, param, options).then(function(flattened) {
+    var processor = new jsonld.JsonLdProcessor();
 
-          playground.outputs["flattened"]
-            .setValue(playground.humanize(flattened));
-
-          resolver.resolve();
-        }, resolver.reject);
-      }
-      else if(playground.activeTab === 'tab-framed') {
-        processor.frame(input, param, options).then(function(framed) {
-
-          playground.outputs["framed"]
-            .setValue(playground.humanize(framed));
-
-          resolver.resolve();
-        }, resolver.reject);
+    // set base IRI
+    var options = {base: (document.baseURI || document.URL)};
+    
+    var promise;
+    if(playground.activeTab === 'tab-compacted') {
+      promise = processor.compact(input, param, options);
+    }
+    else if(playground.activeTab === 'tab-expanded') {
+      promise = processor.expand(input, options);
+    }
+    else if(playground.activeTab === 'tab-flattened') {
+      promise = processor.flatten(input, param, options);
+    }
+    else if(playground.activeTab === 'tab-framed') {
+      promise = processor.frame(input, param, options);
+    }
+    else if(playground.activeTab === 'tab-nquads') {
+      options.format = 'application/nquads';
+      promise = processor.toRDF(input, options);
+    }
+    else if(playground.activeTab === 'tab-normalized') {
+      options.format = 'application/nquads';
+      promise = processor.normalize(input, options);
+    }
+    else {
+      promise = Promise.reject(new Error('Invalid tab selection.'));
+    }
+    
+    return promise.then(function(result) {
+      var outputTab = playground.activeTab.substr('tab-'.length);
+      if(['compacted', 'expanded', 'flattened', 'framed']
+        .indexOf(outputTab) !== -1) {
+        result = playground.humanize(result);
       }
-      else if(playground.activeTab === 'tab-nquads') {
-        options.format = 'application/nquads';
-        processor.toRDF(input, options).then(function(nquads) {
-
-          playground.outputs["nquads"].setValue(nquads);
-
-          resolver.resolve();
-        }, resolver.reject);
-      }
-      else if(playground.activeTab === 'tab-normalized') {
-        options.format = 'application/nquads';
-        processor.normalize(input, options).then(function(normalized) {
-
-          playground.outputs["normalized"].setValue(normalized);
-
-        }, resolver.reject);
-      }
+      playground.outputs[outputTab].setValue(result);
     });
   };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playground/promise-0.1.1.min.js	Fri Feb 28 16:34:32 2014 -0500
@@ -0,0 +1,1 @@
+!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)"exports"===i[l]?k.push(g={}):k.push(b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/cast",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.cast=b}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:(c[a]=b,void 0)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a="Promise"in window&&"cast"in window.Promise&&"resolve"in window.Promise&&"reject"in window.Promise&&"all"in window.Promise&&"race"in window.Promise&&function(){var a;return new window.Promise(function(b){a=b}),f(a)}();a||(window.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h,i){"use strict";function j(a){if(!w(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof j))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],k(a,this)}function k(a,b){function c(a){p(b,a)}function d(a){r(b,a)}try{a(c,d)}catch(e){d(e)}}function l(a,b,c,d){var e,f,g,h,i=w(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;o(b,e)||(i&&g?p(b,e):h?r(b,f):a===F?p(b,e):a===G&&r(b,e))}function m(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+F]=c,e[f+G]=d}function n(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],l(b,c,d,f);a._subscribers=null}function o(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(v(b)&&(d=b.then,w(d)))return d.call(b,function(d){return c?!0:(c=!0,b!==d?p(a,d):q(a,d),void 0)},function(b){return c?!0:(c=!0,r(a,b),void 0)}),!0}catch(e){return c?!0:(r(a,e),!0)}return!1}function p(a,b){a===b?q(a,b):o(a,b)||q(a,b)}function q(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(s,a))}function r(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(t,a))}function s(a){n(a,a._state=F)}function t(a){n(a,a._state=G)}var u=a.config,v=(a.configure,b.objectOrFunction),w=b.isFunction,x=(b.now,c.cast),y=d.all,z=e.race,A=f.resolve,B=g.reject,C=h.asap;u.async=C;var D=void 0,E=0,F=1,G=2;j.prototype={constructor:j,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;u.async(function(){l(c._state,d,e[c._state-1],c._detail)})}else m(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},j.all=y,j.cast=x,j.race=z,j.resolve=A,j.reject=B,i.Promise=j}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}();
\ No newline at end of file