Skip to content

Commit

Permalink
allowing network activity for client implementation. renaming the dis…
Browse files Browse the repository at this point in the history
…t files to system-polyfill
  • Loading branch information
caridy committed Jul 31, 2014
1 parent 50f305a commit 593be75
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 211 deletions.
4 changes: 2 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = function (grunt) {
dist: {
files: [
{
'dist/loader.js': ['client.js']
'dist/system-polyfill.js': ['client.js']
}
]
}
Expand All @@ -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']
}
]
}
Expand Down
229 changes: 138 additions & 91 deletions client.js
Original file line number Diff line number Diff line change
@@ -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);
116 changes: 0 additions & 116 deletions dist/loader.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/loader.min.js

This file was deleted.

Loading

0 comments on commit 593be75

Please sign in to comment.