Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Mojito mojito-lite into develop-perf branch #601

Merged
merged 18 commits into from
Oct 9, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/app/addons/ac/config.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ YUI.add('mojito-config-addon', function(Y, NAME) {
this._ctx = command.context;
this._config = command.instance.config;
this._def = command.instance.definition;
this._store = null;
}


Expand Down
6 changes: 3 additions & 3 deletions lib/app/addons/ac/cookie.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ YUI.add('mojito-cookie-addon', function(Y, NAME) {

/**
* Returns the cookie for the given key or all the cookies if the key
* is not specified.
* is not specified.
* @method get
* @param {string} [optional] key The key to look for.
* @return {string} the value of the cookie for the given key.
* @return {object} contains all the cookies if the key is not specified.
* @return {string} the value of the cookie for the given key.
* @return {object} contains all the cookies if the key is not specified.
*/
get: function(key) {
if (key) {
Expand Down
268 changes: 25 additions & 243 deletions lib/app/addons/ac/deploy.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,9 @@
YUI.add('mojito-deploy-addon', function(Y, NAME) {

var fs = require('fs'),
yuiFilter = 'min',
minify;


if (YUI._mojito && YUI._mojito.DEBUG) {
yuiFilter = 'debug';
}


// TODO: [Issue 64] improve this, it's a poor man's minify.
// a. build minification into static handler?
// b. build minification into prod-build script ?
Expand All @@ -45,6 +39,7 @@ YUI.add('mojito-deploy-addon', function(Y, NAME) {
this.instance = command.instance;
this.scripts = {};
this.ac = ac;
this.rs = null;
}


Expand All @@ -60,10 +55,6 @@ YUI.add('mojito-deploy-addon', function(Y, NAME) {
*/
setStore: function(rs) {
this.rs = rs;
if (rs) {
Y.log('Initialized and activated with Resource Store', 'info',
NAME);
}
},

/**
Expand All @@ -88,28 +79,22 @@ YUI.add('mojito-deploy-addon', function(Y, NAME) {
yuiConfigEscaped,
yuiConfigStr,
yuiModules,
loader,
yuiCombo,
yuiJsUrls = [],
yuiCssUrls = [],
yuiJsUrlContains = {},
viewId,
binder,
i,
id,
clientConfig = {},
clientConfigEscaped,
clientConfigStr,
usePrecomputed,
useOnDemand,
initialModuleList,
initialModuleList = {},
initializer, // script for YUI initialization
routeMaker,
type,
module,
path,
pathToRoot,
urls;
pathToRoot;

contextClient = Y.mojito.util.copy(contextServer);
contextClient.runtime = 'client';
Expand All @@ -121,142 +106,39 @@ YUI.add('mojito-deploy-addon', function(Y, NAME) {

yuiConfig = appConfigClient.yui.config;
yuiConfig.lang = contextServer.lang; // same as contextClient.lang
yuiConfig.core = yuiConfig.core || [];
yuiConfig.core = yuiConfig.core.concat(
['get', 'features', 'intl-base', 'yui-log', 'mojito',
'yui-later']
);

// If we have a "base" for YUI use it
if (appConfigClient.yui.base) {
yuiConfig.base = appConfigClient.yui.base;
yuiConfig.combine = false;
}

// If we know where yui "Loader" is tell YUI
if (appConfigClient.yui.loader) {
yuiConfig.loaderPath = appConfigClient.yui.loader;
yuiConfig.combine = !!appConfigClient.yui.combine;
} else {
yuiConfig.base = 'combo?';
yuiConfig.combine = true;
}

clientConfig.store = store.serializeClientStore(contextClient);

usePrecomputed = appConfigServer.yui &&
appConfigServer.yui.dependencyCalculations && (-1 !==
appConfigServer.yui.dependencyCalculations.indexOf(
'precomputed'
));
useOnDemand = appConfigServer.yui &&
appConfigServer.yui.dependencyCalculations && (-1 !==
appConfigServer.yui.dependencyCalculations.indexOf(
'ondemand'
));
if (!usePrecomputed) {
useOnDemand = true;
}

urls = store.getAllURLs();

// Set the YUI URL to use on the client (This has to be done
// before any other scripts are added)
if (appConfigClient.yui.url) {
yuiJsUrls.push(appConfigClient.yui.url);
// Since the user has given their own rollup of YUI library
// modules, we need some way of knowing which YUI library
// modules went into that rollup.
if (Y.Lang.isArray(appConfigClient.yui.urlContains)) {
for (i = 0; i < appConfigClient.yui.urlContains.length;
i += 1) {
yuiJsUrlContains[appConfigClient.yui.urlContains[i]] =
true;
}
}
} else {
// YUI 3.4.1 doesn't have actual rollup files, so we need to
// specify all the parts directly.
yuiModules = ['yui-base'];
yuiJsUrlContains['yui-base'] = true;
yuiModules = ['yui'];
yuiJsUrlContains.yui = true;
if (useOnDemand) {
fwConfig = store.getFrameworkConfig();
yuiModules.push('get');
yuiJsUrlContains.get = true;
yuiModules.push('loader-base');
yuiJsUrlContains['loader-base'] = true;
yuiModules.push('loader-rollup');
yuiJsUrlContains['loader-rollup'] = true;
yuiModules.push('loader-yui3');
yuiJsUrlContains['loader-yui3'] = true;
for (i = 0; i < fwConfig.ondemandBaseYuiModules.length; i += 1) {
module = fwConfig.ondemandBaseYuiModules[i];
yuiModules.push(module);
yuiJsUrlContains[module] = true;
}
}
if (appConfigClient.yui.extraModules) {
for (i = 0; i < appConfigClient.yui.extraModules.length;
i += 1) {
yuiModules.push(appConfigClient.yui.extraModules[i]);
yuiJsUrlContains[
appConfigClient.yui.extraModules[i]
] = true;
}
}
for (viewId in binderMap) {
if (binderMap.hasOwnProperty(viewId)) {
binder = binderMap[viewId];
for (module in binder.needs) {
if (binder.needs.hasOwnProperty(module)) {
path = binder.needs[module];
// Anything we don't know about we'll assume is
// a YUI library module.
if (!urls[path]) {
yuiModules.push(module);
yuiJsUrlContains[module] = true;
}
}
}
}
}
assetHandler.addAsset('js', 'top',
(appConfigClient.yui.url ||
'/combo?yui-base/yui-base.js&loader-base/loader-base.js&loader-app-base.js'));

loader = new Y.mojito.Loader(appConfigClient);
yuiCombo = loader.createYuiLibComboUrl(yuiModules, yuiFilter);
yuiJsUrls = yuiCombo.js;
yuiCssUrls = yuiCombo.css;
}
for (i = 0; i < yuiJsUrls.length; i += 1) {
this.addScript('top', yuiJsUrls[i]);
}
// defaults to true if missing
if (!yuiConfig.hasOwnProperty('fetchCSS') || yuiConfig.fetchCSS) {
for (i = 0; i < yuiCssUrls.length; i += 1) {
assetHandler.addCss(yuiCssUrls[i], 'top');
}
}

// add mojito bootstrap
// With "precomputed" the scripts are listed as binder dependencies
// and thus loaded that way. However, with "ondemand" we'll use
// the YUI loader which we haven't (yet) taught where to find the
// fw & app scripts.
if (useOnDemand) {
// add all framework-level and app-level code
this.addScripts('bottom', store.yui.getConfigShared(
'client',
contextClient
).modules, false);
}
// adding the default module for the Y.use statement in the client
initialModuleList['mojito-client'] = true;

// add binders' dependencies
for (viewId in binderMap) {
if (binderMap.hasOwnProperty(viewId)) {
binder = binderMap[viewId];
for (module in binder.needs) {
if (binder.needs.hasOwnProperty(module)) {
if (!yuiJsUrlContains[module]) {
this.addScript('bottom', binder.needs[module]);
}
}
if (binderMap[viewId].name) {
initialModuleList[binderMap[viewId].name] = true;
}
}
}
Expand All @@ -274,142 +156,42 @@ YUI.add('mojito-deploy-addon', function(Y, NAME) {
clientConfig.pathToRoot = pathToRoot;
}

// TODO -- decide if this is necessary, since
// clientConfig.store.mojits is currently unpopulated
/*
for (type in clientConfig.store.mojits) {
for (i in clientConfig.store.mojits[type].yui.sorted) {
module = clientConfig.store.mojits[type].yui.sorted[i];
path = clientConfig.store.mojits[type].yui.sortedPaths[
module];
this.scripts[path] = 'bottom';
}
}
*/

routeMaker = new Y.mojito.RouteMaker(clientConfig.store.routes);
clientConfig.routes = routeMaker.getComputedRoutes();
clientConfig.routes = this.ac.url.getRouteMaker().getComputedRoutes();
delete clientConfig.store;

initialModuleList = "'*'";
if (useOnDemand) {
initialModuleList = "'mojito-client'";
}

// Unicode escape the various strings in the config data to help
// fight against possible script injection attacks.
yuiConfigEscaped = Y.mojito.util.cleanse(yuiConfig);
yuiConfigStr = JSON.stringify(yuiConfigEscaped);
clientConfigEscaped = Y.mojito.util.cleanse(clientConfig);
clientConfigStr = JSON.stringify(clientConfigEscaped);

initialModuleList = "'" + Y.Object.keys(initialModuleList).join("','") + "'";

initializer = '<script type="text/javascript">\n' +
' YUI_config = ' + yuiConfigStr + ';\n' +
' YUI.Env.core.push("loader-base"); // workaround (ticket 2532571)\n' +

'YUI_config.bootstrap = true;' +
'YUI_config.comboBase = "/combo?";' +
'YUI_config.combine = true;' +

' YUI().use(' + initialModuleList + ', function(Y) {\n' +
' window.YMojito = { client: new Y.mojito.Client(' +
clientConfigStr + ') };\n' +
' });\n' +
'</script>\n';

// Add all the scripts we have collected
assetHandler.addAssets(
this.getScripts(appConfigServer.embedJsFilesInHtmlFrame, urls)
);
// Add the boot script
assetHandler.addAsset('blob', 'bottom', initializer);
},


addScript: function(position, path) {
this.scripts[path] = position;
},


addScripts: function(position, modules) {
var i;
for (i in modules) {
if (modules.hasOwnProperty(i)) {
this.scripts[modules[i].fullpath] = position;
}
}
},


/**
* TODO: [Issue 66] This can be made faster with a single for
* loop and caching.
*
* Note: A single SCRIPT tag containing all the JS on the pages is
* slower than many SCRIPT tags (checked on iPad only).
* @method getScripts
* @private
* @param {bool} embed Should returned scripts be embedded in script
* tags.
* @param {object} urls Mapping of URLs to filesystem paths. The keys
* are the URLs, and the values are the cooresponding filesystem
* paths.
* @return {object} An object containing script descriptors.
*/
getScripts: function(embed, urls) {
var i,
path,
x,
assets = {},
blob = {
type: 'blob',
position: 'bottom',
content: ''
};

// Walk over the scripts and check what we can do
for (i in this.scripts) {
if (this.scripts.hasOwnProperty(i)) {
path = urls[i];
if (embed && path) {
this.scripts[i] = {
type: 'blob',
position: 'bottom',
content: '<script type="text/javascript">' +
minify(fs.readFileSync(path, 'utf8')) +
'</script>'
};
} else {
this.scripts[i] = {
type: 'js',
position: this.scripts[i],
content: i
};
}
}
}


// Convert the scripts to the Assets format
for (x in this.scripts) {
if (this.scripts.hasOwnProperty(x)) {
if (!assets[this.scripts[x].position]) {
assets[this.scripts[x].position] = {};
}
if (!assets[this.scripts[x].position][this.scripts[x].
type]) {
assets[this.scripts[x].position][this.scripts[x].
type] = [];
}
assets[this.scripts[x].position][this.scripts[x].type].push(
this.scripts[x].content
);
}
}

return assets;
}

};

Y.namespace('mojito.addons.ac').deploy = Addon;

}, '0.1.0', {requires: [
'mojito-loader',
'mojito-util',
'mojito-http-addon',
'mojito-route-maker'
'mojito-url-addon'
]});
Loading