From 593be752240273530ddac7237421386610d98714 Mon Sep 17 00:00:00 2001 From: Caridy Patino Date: Thu, 31 Jul 2014 14:53:38 -0400 Subject: [PATCH] allowing network activity for client implementation. renaming the dist files to system-polyfill --- Gruntfile.js | 4 +- client.js | 229 ++++++++++++++++++++++-------------- dist/loader.js | 116 ------------------ dist/loader.min.js | 1 - dist/system-polyfill.js | 163 +++++++++++++++++++++++++ dist/system-polyfill.min.js | 1 + package.json | 2 +- 7 files changed, 305 insertions(+), 211 deletions(-) delete mode 100644 dist/loader.js delete mode 100644 dist/loader.min.js create mode 100644 dist/system-polyfill.js create mode 100644 dist/system-polyfill.min.js diff --git a/Gruntfile.js b/Gruntfile.js index bb0ee7d..26ab934 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -11,7 +11,7 @@ module.exports = function (grunt) { dist: { files: [ { - 'dist/loader.js': ['client.js'] + 'dist/system-polyfill.js': ['client.js'] } ] } @@ -20,7 +20,7 @@ module.exports = function (grunt) { dist: { files: [ { - 'dist/loader.min.js': ['dist/loader.js'] + 'dist/system-polyfill.min.js': ['dist/system-polyfill.js'] } ] } diff --git a/client.js b/client.js index 090b5ad..3d24c2f 100644 --- a/client.js +++ b/client.js @@ -1,116 +1,163 @@ -(function (exports) { +(function(exports) { "use strict"; +var headEl = document.getElementsByTagName('head')[0], + ie = /MSIE/.test(navigator.userAgent); + function normalizeName(child, parentBase) { - if (child.charAt(0) === "/") { - child = child.slice(1); - } - if (child.charAt(0) !== ".") { - return child; - } - var parts = child.split("/"); - while (parts[0] === "." || parts[0] === "..") { - if (parts.shift() === "..") { - parentBase.pop(); + if (child.charAt(0) === "/") { + child = child.slice(1); + } + if (child.charAt(0) !== ".") { + return child; + } + var parts = child.split("/"); + while (parts[0] === "." || parts[0] === "..") { + if (parts.shift() === "..") { + parentBase.pop(); + } } - } - return parentBase.concat(parts).join("/"); + return parentBase.concat(parts).join("/"); } var seen = Object.create(null); var internalRegistry = Object.create(null); var externalRegistry = Object.create(null); -function ensuredExecute (name) { - var mod = internalRegistry[name]; - if (mod && !seen[name]) { - seen[name] = true; - // one time operation to execute the module body - mod.execute(); - } - return mod && mod.proxy; +function ensuredExecute(name) { + var mod = internalRegistry[name]; + if (mod && !seen[name]) { + seen[name] = true; + // one time operation to execute the module body + mod.execute(); + } + return mod && mod.proxy; +} + +function set(name, values) { + externalRegistry[name] = values; } -function set (name, values) { - externalRegistry[name] = values; + +function get(name) { + return externalRegistry[name] || ensuredExecute(name); } -function get (name) { - return externalRegistry[name] || ensuredExecute(name); + +function has(name) { + return !!externalRegistry[name] || !!internalRegistry[name]; } -function has (name) { - return !!externalRegistry[name] || !!internalRegistry[name]; + +function createScriptNode(src, callback) { + var node = document.createElement('script'); + // use async=false for ordered async? + // parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order + if (node.async) { + node.async = false; + } + if (ie) { + node.onreadystatechange = function() { + if (/loaded|complete/.test(this.readyState)) { + this.onreadystatechange = null; + callback(); + } + }; + } else { + node.onload = node.onerror = callback; + } + node.setAttribute('src', src); + headEl.appendChild(node); } +function load(name) { + return new Promise(function(resolve, reject) { + createScriptNode((System.baseURL || '/') + name + '.js', function(err) { + var mod = internalRegistry[name]; + if (!mod) { + reject(new Error("Error loading module " + name)); + return; + } + Promise.all(mod.deps.map(function (dep) { + if (externalRegistry[dep] || internalRegistry[dep]) { + return Promise.resolve(); + } + return load(dep); + })).then(resolve, reject); + }); + }); +} // exporting the System object exports.System = { - set: set, - get: get, - has: has, - import: function(name) { - return new Promise(function (resolve, reject) { - var mod = get(normalizeName(name, [])); - return mod ? resolve(mod) : reject(new Error("Could not find module " + name)); - }); - }, - register: function (name, deps, wrapper) { - var proxy = Object.create(null), - values = Object.create(null), - mod, meta; - // creating a new entry in the internal registry - internalRegistry[name] = mod = { - // live bindings - proxy: proxy, - // exported values - values: values, - // normalized deps - deps: deps.map(function(dep) { - return normalizeName(dep, name.split("/").slice(0, -1)); - }), - // other modules that depends on this so we can push updates into those modules - dependants: [], - // method used to push updates of deps into the module body - update: function(moduleName, moduleObj) { - meta.setters[mod.deps.indexOf(moduleName)](moduleObj); - }, - execute: function () { - mod.deps.map(function(dep) { - var imports = externalRegistry[dep]; - if (imports) { - mod.update(dep, imports); - } else { - imports = get(dep) && internalRegistry[dep].values; // optimization to pass plain values instead of bindings - if (imports) { - internalRegistry[dep].dependants.push(name); - mod.update(dep, imports); - } - } + set: set, + get: get, + has: has, + import: function(name) { + return new Promise(function(resolve, reject) { + var normalizedName = normalizeName(name, []); + var mod = get(normalizedName); + return mod ? resolve(mod) : load(name).then(function () { + return get(normalizedName); + }); }); - meta.execute(); - } - }; - // collecting execute() and setters[] - meta = wrapper(function(identifier, value) { - values[identifier] = value; - mod.lock = true; // locking down the updates on the module to avoid infinite loop - mod.dependants.forEach(function(moduleName) { - if (internalRegistry[moduleName] && !internalRegistry[moduleName].lock) { - internalRegistry[moduleName].update(name, values); - } - }); - mod.lock = false; - if (!Object.getOwnPropertyDescriptor(proxy, identifier)) { - Object.defineProperty(proxy, identifier, { - enumerable: true, - get: function() { - return values[identifier]; - } + }, + register: function(name, deps, wrapper) { + var proxy = Object.create(null), + values = Object.create(null), + mod, meta; + // creating a new entry in the internal registry + internalRegistry[name] = mod = { + // live bindings + proxy: proxy, + // exported values + values: values, + // normalized deps + deps: deps.map(function(dep) { + return normalizeName(dep, name.split("/").slice(0, -1)); + }), + // other modules that depends on this so we can push updates into those modules + dependants: [], + // method used to push updates of deps into the module body + update: function(moduleName, moduleObj) { + meta.setters[mod.deps.indexOf(moduleName)](moduleObj); + }, + execute: function() { + mod.deps.map(function(dep) { + var imports = externalRegistry[dep]; + if (imports) { + mod.update(dep, imports); + } else { + imports = get(dep) && internalRegistry[dep].values; // optimization to pass plain values instead of bindings + if (imports) { + internalRegistry[dep].dependants.push(name); + mod.update(dep, imports); + } + } + }); + meta.execute(); + } + }; + // collecting execute() and setters[] + meta = wrapper(function(identifier, value) { + values[identifier] = value; + mod.lock = true; // locking down the updates on the module to avoid infinite loop + mod.dependants.forEach(function(moduleName) { + if (internalRegistry[moduleName] && !internalRegistry[moduleName].lock) { + internalRegistry[moduleName].update(name, values); + } + }); + mod.lock = false; + if (!Object.getOwnPropertyDescriptor(proxy, identifier)) { + Object.defineProperty(proxy, identifier, { + enumerable: true, + get: function() { + return values[identifier]; + } + }); + } + return value; }); - } - return value; - }); - } + } }; })(window); diff --git a/dist/loader.js b/dist/loader.js deleted file mode 100644 index 090b5ad..0000000 --- a/dist/loader.js +++ /dev/null @@ -1,116 +0,0 @@ -(function (exports) { - -"use strict"; - -function normalizeName(child, parentBase) { - if (child.charAt(0) === "/") { - child = child.slice(1); - } - if (child.charAt(0) !== ".") { - return child; - } - var parts = child.split("/"); - while (parts[0] === "." || parts[0] === "..") { - if (parts.shift() === "..") { - parentBase.pop(); - } - } - return parentBase.concat(parts).join("/"); -} - -var seen = Object.create(null); -var internalRegistry = Object.create(null); -var externalRegistry = Object.create(null); - -function ensuredExecute (name) { - var mod = internalRegistry[name]; - if (mod && !seen[name]) { - seen[name] = true; - // one time operation to execute the module body - mod.execute(); - } - return mod && mod.proxy; -} -function set (name, values) { - externalRegistry[name] = values; -} -function get (name) { - return externalRegistry[name] || ensuredExecute(name); -} -function has (name) { - return !!externalRegistry[name] || !!internalRegistry[name]; -} - - - -// exporting the System object -exports.System = { - set: set, - get: get, - has: has, - import: function(name) { - return new Promise(function (resolve, reject) { - var mod = get(normalizeName(name, [])); - return mod ? resolve(mod) : reject(new Error("Could not find module " + name)); - }); - }, - register: function (name, deps, wrapper) { - var proxy = Object.create(null), - values = Object.create(null), - mod, meta; - // creating a new entry in the internal registry - internalRegistry[name] = mod = { - // live bindings - proxy: proxy, - // exported values - values: values, - // normalized deps - deps: deps.map(function(dep) { - return normalizeName(dep, name.split("/").slice(0, -1)); - }), - // other modules that depends on this so we can push updates into those modules - dependants: [], - // method used to push updates of deps into the module body - update: function(moduleName, moduleObj) { - meta.setters[mod.deps.indexOf(moduleName)](moduleObj); - }, - execute: function () { - mod.deps.map(function(dep) { - var imports = externalRegistry[dep]; - if (imports) { - mod.update(dep, imports); - } else { - imports = get(dep) && internalRegistry[dep].values; // optimization to pass plain values instead of bindings - if (imports) { - internalRegistry[dep].dependants.push(name); - mod.update(dep, imports); - } - } - }); - meta.execute(); - } - }; - // collecting execute() and setters[] - meta = wrapper(function(identifier, value) { - values[identifier] = value; - mod.lock = true; // locking down the updates on the module to avoid infinite loop - mod.dependants.forEach(function(moduleName) { - if (internalRegistry[moduleName] && !internalRegistry[moduleName].lock) { - internalRegistry[moduleName].update(name, values); - } - }); - mod.lock = false; - if (!Object.getOwnPropertyDescriptor(proxy, identifier)) { - Object.defineProperty(proxy, identifier, { - enumerable: true, - get: function() { - return values[identifier]; - } - }); - } - return value; - }); - } -}; - -})(window); diff --git a/dist/loader.min.js b/dist/loader.min.js deleted file mode 100644 index f33a17a..0000000 --- a/dist/loader.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){"use strict";function b(a,b){if("/"===a.charAt(0)&&(a=a.slice(1)),"."!==a.charAt(0))return a;for(var c=a.split("/");"."===c[0]||".."===c[0];)".."===c.shift()&&b.pop();return b.concat(c).join("/")}function c(a){var b=h[a];return b&&!g[a]&&(g[a]=!0,b.execute()),b&&b.proxy}function d(a,b){i[a]=b}function e(a){return i[a]||c(a)}function f(a){return!!i[a]||!!h[a]}var g=Object.create(null),h=Object.create(null),i=Object.create(null);a.System={set:d,get:e,has:f,"import":function(a){return new Promise(function(c,d){var f=e(b(a,[]));return f?c(f):d(new Error("Could not find module "+a))})},register:function(a,c,d){var f,g,j=Object.create(null),k=Object.create(null);h[a]=f={proxy:j,values:k,deps:c.map(function(c){return b(c,a.split("/").slice(0,-1))}),dependants:[],update:function(a,b){g.setters[f.deps.indexOf(a)](b)},execute:function(){f.deps.map(function(b){var c=i[b];c?f.update(b,c):(c=e(b)&&h[b].values,c&&(h[b].dependants.push(a),f.update(b,c)))}),g.execute()}},g=d(function(b,c){return k[b]=c,f.lock=!0,f.dependants.forEach(function(b){h[b]&&!h[b].lock&&h[b].update(a,k)}),f.lock=!1,Object.getOwnPropertyDescriptor(j,b)||Object.defineProperty(j,b,{enumerable:!0,get:function(){return k[b]}}),c})}}}(window); \ No newline at end of file diff --git a/dist/system-polyfill.js b/dist/system-polyfill.js new file mode 100644 index 0000000..3d24c2f --- /dev/null +++ b/dist/system-polyfill.js @@ -0,0 +1,163 @@ +(function(exports) { + +"use strict"; + +var headEl = document.getElementsByTagName('head')[0], + ie = /MSIE/.test(navigator.userAgent); + +function normalizeName(child, parentBase) { + if (child.charAt(0) === "/") { + child = child.slice(1); + } + if (child.charAt(0) !== ".") { + return child; + } + var parts = child.split("/"); + while (parts[0] === "." || parts[0] === "..") { + if (parts.shift() === "..") { + parentBase.pop(); + } + } + return parentBase.concat(parts).join("/"); +} + +var seen = Object.create(null); +var internalRegistry = Object.create(null); +var externalRegistry = Object.create(null); + +function ensuredExecute(name) { + var mod = internalRegistry[name]; + if (mod && !seen[name]) { + seen[name] = true; + // one time operation to execute the module body + mod.execute(); + } + return mod && mod.proxy; +} + +function set(name, values) { + externalRegistry[name] = values; +} + +function get(name) { + return externalRegistry[name] || ensuredExecute(name); +} + +function has(name) { + return !!externalRegistry[name] || !!internalRegistry[name]; +} + +function createScriptNode(src, callback) { + var node = document.createElement('script'); + // use async=false for ordered async? + // parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order + if (node.async) { + node.async = false; + } + if (ie) { + node.onreadystatechange = function() { + if (/loaded|complete/.test(this.readyState)) { + this.onreadystatechange = null; + callback(); + } + }; + } else { + node.onload = node.onerror = callback; + } + node.setAttribute('src', src); + headEl.appendChild(node); +} + +function load(name) { + return new Promise(function(resolve, reject) { + createScriptNode((System.baseURL || '/') + name + '.js', function(err) { + var mod = internalRegistry[name]; + if (!mod) { + reject(new Error("Error loading module " + name)); + return; + } + Promise.all(mod.deps.map(function (dep) { + if (externalRegistry[dep] || internalRegistry[dep]) { + return Promise.resolve(); + } + return load(dep); + })).then(resolve, reject); + }); + }); +} + + +// exporting the System object +exports.System = { + set: set, + get: get, + has: has, + import: function(name) { + return new Promise(function(resolve, reject) { + var normalizedName = normalizeName(name, []); + var mod = get(normalizedName); + return mod ? resolve(mod) : load(name).then(function () { + return get(normalizedName); + }); + }); + }, + register: function(name, deps, wrapper) { + var proxy = Object.create(null), + values = Object.create(null), + mod, meta; + // creating a new entry in the internal registry + internalRegistry[name] = mod = { + // live bindings + proxy: proxy, + // exported values + values: values, + // normalized deps + deps: deps.map(function(dep) { + return normalizeName(dep, name.split("/").slice(0, -1)); + }), + // other modules that depends on this so we can push updates into those modules + dependants: [], + // method used to push updates of deps into the module body + update: function(moduleName, moduleObj) { + meta.setters[mod.deps.indexOf(moduleName)](moduleObj); + }, + execute: function() { + mod.deps.map(function(dep) { + var imports = externalRegistry[dep]; + if (imports) { + mod.update(dep, imports); + } else { + imports = get(dep) && internalRegistry[dep].values; // optimization to pass plain values instead of bindings + if (imports) { + internalRegistry[dep].dependants.push(name); + mod.update(dep, imports); + } + } + }); + meta.execute(); + } + }; + // collecting execute() and setters[] + meta = wrapper(function(identifier, value) { + values[identifier] = value; + mod.lock = true; // locking down the updates on the module to avoid infinite loop + mod.dependants.forEach(function(moduleName) { + if (internalRegistry[moduleName] && !internalRegistry[moduleName].lock) { + internalRegistry[moduleName].update(name, values); + } + }); + mod.lock = false; + if (!Object.getOwnPropertyDescriptor(proxy, identifier)) { + Object.defineProperty(proxy, identifier, { + enumerable: true, + get: function() { + return values[identifier]; + } + }); + } + return value; + }); + } +}; + +})(window); diff --git a/dist/system-polyfill.min.js b/dist/system-polyfill.min.js new file mode 100644 index 0000000..d1e1f2c --- /dev/null +++ b/dist/system-polyfill.min.js @@ -0,0 +1 @@ +!function(a){"use strict";function b(a,b){if("/"===a.charAt(0)&&(a=a.slice(1)),"."!==a.charAt(0))return a;for(var c=a.split("/");"."===c[0]||".."===c[0];)".."===c.shift()&&b.pop();return b.concat(c).join("/")}function c(a){var b=l[a];return b&&!k[a]&&(k[a]=!0,b.execute()),b&&b.proxy}function d(a,b){m[a]=b}function e(a){return m[a]||c(a)}function f(a){return!!m[a]||!!l[a]}function g(a,b){var c=document.createElement("script");c.async&&(c.async=!1),j?c.onreadystatechange=function(){/loaded|complete/.test(this.readyState)&&(this.onreadystatechange=null,b())}:c.onload=c.onerror=b,c.setAttribute("src",a),i.appendChild(c)}function h(a){return new Promise(function(b,c){g((System.baseURL||"/")+a+".js",function(){var d=l[a];return d?void Promise.all(d.deps.map(function(a){return m[a]||l[a]?Promise.resolve():h(a)})).then(b,c):void c(new Error("Error loading module "+a))})})}var i=document.getElementsByTagName("head")[0],j=/MSIE/.test(navigator.userAgent),k=Object.create(null),l=Object.create(null),m=Object.create(null);a.System={set:d,get:e,has:f,"import":function(a){return new Promise(function(c){var d=b(a,[]),f=e(d);return f?c(f):h(a).then(function(){return e(d)})})},register:function(a,c,d){var f,g,h=Object.create(null),i=Object.create(null);l[a]=f={proxy:h,values:i,deps:c.map(function(c){return b(c,a.split("/").slice(0,-1))}),dependants:[],update:function(a,b){g.setters[f.deps.indexOf(a)](b)},execute:function(){f.deps.map(function(b){var c=m[b];c?f.update(b,c):(c=e(b)&&l[b].values,c&&(l[b].dependants.push(a),f.update(b,c)))}),g.execute()}},g=d(function(b,c){return i[b]=c,f.lock=!0,f.dependants.forEach(function(b){l[b]&&!l[b].lock&&l[b].update(a,i)}),f.lock=!1,Object.getOwnPropertyDescriptor(h,b)||Object.defineProperty(h,b,{enumerable:!0,get:function(){return i[b]}}),c})}}}(window); \ No newline at end of file diff --git a/package.json b/package.json index d7213a3..6ae4c72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "es6-micro-loader", - "version": "0.0.1", + "version": "0.0.2", "description": "Simplistic ES6 Module Loader for modules transpiled into System.register() format", "author": "Caridy Patino ", "homepage": "https://github.com/caridy/es6-micro-loader",