Skip to content

Commit

Permalink
Merge pull-request montagejsgh-814 from 'kriskowal/bundle2'
Browse files Browse the repository at this point in the history
Conflicts:
	package.json
  • Loading branch information
Mike Czepiel committed Jul 20, 2012
2 parents 3e5d755 + 23eacdf commit b2fac54
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 100 deletions.
29 changes: 20 additions & 9 deletions core/promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -665,16 +665,27 @@ var Promise = PrimordialPromise.create({}, { // Descriptor for each of the three
},

end: {
value: function () {
this.then(void 0, function (reason, error) {
// forward to a future turn so that ``when``
// does not catch it and turn it into a rejection.
nextTick(function () {
console.error(error && error.stack || error || reason);
throw error;
});
value: function (callback, errback) {
this.then(function (value) {
if (callback) {
nextTick(function () {
callback(value);
});
}
}, function (reason, error) {
if (errback) {
nextTick(function () {
errback(error || reason);
});
} else {
// forward to a future turn so that ``when``
// does not catch it and turn it into a rejection.
nextTick(function () {
throw error;
});
}
})
// Returns undefined
// Does not return a promise
}
},

Expand Down
164 changes: 111 additions & 53 deletions montage.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,41 @@ if (typeof window !== "undefined") {
};

var location = URL.resolve(config.location, params["package"] || ".");
var applicationHash = params.applicationHash;

if (typeof BUNDLE === "object") {
var bundleDefinitions = {};
var getDefinition = function (name) {
return bundleDefinitions[name] =
bundleDefinitions[name] ||
Promise.Promise.defer();
};
global.bundleLoaded = function (name) {
getDefinition(name).resolve();
};
var preloading = Promise.Promise.defer();
config.preloaded = preloading.promise;
// preload bundles sequentially
var preloaded = Promise.Promise.resolve();
BUNDLE.forEach(function (bundleLocations) {
preloaded = preloaded.then(function () {
return Promise.Promise.all(bundleLocations.map(function (bundleLocation) {
browser.load(bundleLocation);
return getDefinition(bundleLocation).promise;
}));
});
});
// then release the module loader to run normally
preloading.resolve(preloaded.then(function () {
delete BUNDLE;
delete bundleLoaded;
}));
}

Require.loadPackage(montageLocation, config)
Require.loadPackage({
location: montageLocation,
hash: params.montageHash
}, config)
.then(function (montageRequire) {
montageRequire.inject("core/promise", Promise);
montageRequire.inject("core/next-tick", Clock);
Expand Down Expand Up @@ -146,8 +179,12 @@ if (typeof window !== "undefined") {
);
}

return montageRequire.loadPackage(location)
return montageRequire.loadPackage({
location: location,
hash: applicationHash
})
.then(function (applicationRequire) {

global.require = applicationRequire;
global.montageRequire = montageRequire;
platform.initMontage(montageRequire, applicationRequire, params);
Expand Down Expand Up @@ -241,14 +278,22 @@ if (typeof window !== "undefined") {
return function(module) {
if (!module.location)
return;
var match = module.location.match(/(.*\/)?(?=[^\/]+\.html$)/);
var match = module.location.match(/(.*\/)?(?=[^\/]+\.html(?:\.load\.js)?$)/);
if (match) {
module.dependencies = module.dependencies || [];
module.exports = {
directory: match[1],
root: match, // deprecated
content: module.text
};
// XXX deprecated
Object.defineProperty(module.exports, "root", {
get: function () {
if (typeof console === "object") {
console.warn("'root' property is deprecated on template modules. Use 'directory' instead of root[1]");
}
return match;
}
});
return module;
} else {
compile(module);
Expand Down Expand Up @@ -299,6 +344,16 @@ if (typeof window !== "undefined") {

var browser = {

load: function (location) {
var script = document.createElement("script");
script.src = location;
script.onload = function () {
// remove clutter
script.parentNode.removeChild(script);
};
document.getElementsByTagName("head")[0].appendChild(script);
},

getConfig: function() {
return {
location: "" + window.location
Expand Down Expand Up @@ -386,14 +441,7 @@ if (typeof window !== "undefined") {
// otherwise, these scripts will be inlined after already
if (typeof BUNDLE === "undefined") {
pending.forEach(function(name) {
var url = params.montageLocation + name + ".js";
var script = document.createElement("script");
script.src = url;
script.onload = function () {
// remove clutter
script.parentNode.removeChild(script);
};
document.getElementsByTagName("head")[0].appendChild(script);
browser.load(params.montageLocation + name + ".js");
});
}

Expand Down Expand Up @@ -442,53 +490,63 @@ if (typeof window !== "undefined") {
},

initMontage: function (montageRequire, applicationRequire, params) {
var Promise, defaultEventManager, application;

montageRequire.async("core/promise").then(function(exports) {
Promise = exports.Promise;
Promise.all([
montageRequire.async("core/event/event-manager"),
montageRequire.async("core/deserializer")
]).then(function(exportsArray) {
// Load the event-manager
defaultEventManager = exportsArray[0].EventManager.create().initWithWindow(window);

// montageWillLoad is mostly for testing purposes
if (typeof global.montageWillLoad === "function") {
global.montageWillLoad();
}

// Load the application
var dependencies = [
"core/event/event-manager",
"core/deserializer"
];

var appProto = applicationRequire.packageDescription.applicationPrototype,
applicationDescription, appModulePromise;
if (appProto) {
applicationDescription = exportsArray[1].Deserializer.parseForModuleAndName(appProto);
appModulePromise = applicationRequire.async(applicationDescription.module);
} else {
appModulePromise = montageRequire.async("ui/application");
}
if (typeof window !== "undefined") {
dependencies.push("core/event/binding");
}

if (typeof window !== "undefined") {
montageRequire.async("core/event/binding").end();
}
var Promise = montageRequire("core/promise").Promise;

appModulePromise.then(function(exports) {
application = exports[(applicationDescription ? applicationDescription.name : "Application")].create();
window.document.application = application;
defaultEventManager.application = application;
application.eventManager = defaultEventManager;
application._load(applicationRequire, function() {
if (params.module) {
// If a module was specified in the config then we initialize it now
applicationRequire.async(params.module).end();
}
});
}).end();
return Promise.all(dependencies.map(montageRequire.deepLoad))
.then(function () {

dependencies.forEach(montageRequire);

var EventManager = montageRequire("core/event/event-manager").EventManager;
var Deserializer = montageRequire("core/deserializer").Deserializer;
var defaultEventManager, application;

// Load the event-manager
defaultEventManager = EventManager.create().initWithWindow(window);

// montageWillLoad is mostly for testing purposes
if (typeof global.montageWillLoad === "function") {
global.montageWillLoad();
}

// Load the application

}).end();
var appProto = applicationRequire.packageDescription.applicationPrototype,
applicationDescription, appModulePromise;
if (appProto) {
applicationDescription = Deserializer.parseForModuleAndName(appProto);
appModulePromise = applicationRequire.async(applicationDescription.module);
} else {
appModulePromise = montageRequire.async("ui/application");
}

return appModulePromise.then(function(exports) {
application = exports[(applicationDescription ? applicationDescription.name : "Application")].create();
window.document.application = application;
defaultEventManager.application = application;
application.eventManager = defaultEventManager;
application._load(applicationRequire, function() {
if (params.module) {
// If a module was specified in the config then we initialize it now
applicationRequire.async(params.module)
.end();
}
});
})

})
.end();

});
}
};

Expand Down
33 changes: 30 additions & 3 deletions node.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,14 @@ var loadPackagedModule = function (directory, program, command, args) {
};

MontageBoot.loadPackage = function (location, config) {
var config = {};

config.location = URL.resolve(Require.getLocation(), location + '/');
if (location.slice(location.length - 1, location.length) !== "/") {
location += "/";
}

config = config || {};

config.location = URL.resolve(Require.getLocation(), location);

// setup the reel loader
config.makeLoader = function (config) {
Expand Down Expand Up @@ -121,6 +126,7 @@ MontageBoot.TemplateLoader = function (config, load) {
return function(id, module) {
var html = id.match(/(.*\/)?(?=[^\/]+\.html$)/);
var serialization = id.match(/(?=[^\/]+\.json$)/); // XXX this is not necessarily a strong indicator of a serialization alone
var reelModule = id.match(/(.*\/)?([^\/]+)\.reel\/\2/);
if (html) {
return load(id, module)
.then(function () {
Expand All @@ -133,6 +139,17 @@ MontageBoot.TemplateLoader = function (config, load) {
module.dependencies = collectSerializationDependencies(module.text, []);
return module;
});
} else if (reelModule) {
return load(id, module)
.then(function () {
var reelHtml = URL.resolve(module.location, reelModule[2] + ".html");
return Require.isFile(reelHtml)
.then(function (isFile) {
if (isFile) {
module.extraDependencies = [id + ".html"];
}
})
});
} else {
return load(id, module);
}
Expand Down Expand Up @@ -198,10 +215,20 @@ var collectSerializationDependencies = function (text, dependencies) {
var serialization = JSON.parse(text);
Object.keys(serialization).forEach(function (label) {
var description = serialization[label];
if (typeof description.module === "string") {
if (description.lazy) {
return;
}
if (typeof description.module === "string") { // XXX deprecated
dependencies.push(description.module);
}
if (typeof description.prototype === "string") {
dependencies.push(parsePrototypeForModule(description.prototype));
}
});
return dependencies;
};

function parsePrototypeForModule(prototype) {
return prototype.replace(/\[[^\]]+\]$/, "");
}

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"lab/sandbox",
"samples",
"tools",
"examples",
"require/test",
"require/tests",
"etc",
"node.js"
],
Expand Down
25 changes: 21 additions & 4 deletions require/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ var __FILE__String = "__FILE__",

Require.Compiler = function (config) {
return function(module) {
if (module.factory || module.text === void 0)
if (module.exports || module.factory || module.text === void 0)
return module;
if (config.define)
throw new Error("Can't use eval.");
throw new Error("Can't use eval to compile " + JSON.stringify(module.id));

// Here we use a couple tricks to make debugging better in various browsers:
// TODO: determine if these are all necessary / the best options
Expand Down Expand Up @@ -168,8 +168,9 @@ define = function (hash, id, module) {

Require.ScriptLoader = function (config) {
var hash = config.packageDescription.hash;
var preloaded = config.preloaded = config.preloaded || Promise.resolve();
return function (location, module) {
return Promise.call(function () {
return preloaded.then(function () {

// short-cut by predefinition
if (definitions[hash] && definitions[hash][module.id]) {
Expand Down Expand Up @@ -206,8 +207,24 @@ Require.ScriptLoader = function (config) {
};
};

// annotate loadPackageDescription such that preloaded descriptions can be
// retrieved from the definitions data
Require.loadPackageDescription = (function (loadPackageDescription) {
return function (dependency, config) {
if (
definitions[dependency.hash] &&
definitions[dependency.hash]["package.json"]
) {
return definitions[dependency.hash]["package.json"]
.promise.get("exports");
} else {
return loadPackageDescription(dependency, config);
}
};
})(Require.loadPackageDescription);

Require.makeLoader = function (config) {
if (config.define) {
if (config.packageDescription.define) {
Loader = Require.ScriptLoader;
} else {
Loader = Require.XhrLoader;
Expand Down
Loading

0 comments on commit b2fac54

Please sign in to comment.