Commit a7c45c4f authored by Sindre Sorhus's avatar Sindre Sorhus

Move JavascriptMVC to labs

parent 037052bc
steal(function( steal ) {
// recursively goes through steals and their dependencies.
var addDependencies = function( steel, files, app ) {
//add self to files
if (!files[steel.path] ) {
var source = readFile(steel.path);
if ( steel.type && steal.build.types[steel.type] ) {
source = steal.build.types[steel.type]({
text: source,
id: steal.cleanId(steel.path)
});
print(" converting " + steel.path + " ");
} else {
print(" compressing " + steel.path + " ");
}
source = steal.build.builders.scripts.clean(source);
source = "" + steal.build.compressor(source, true);
//need to convert to other types.
files[steel.path] = {
path: steel.path,
apps: [],
dependencies: {},
size: source.length,
packaged: false,
source: source
}
}
var data = files[steel.path];
data.apps.push(app);
for ( var d = 0; d < steel.dependencies.length; d++ ) {
var dependency = steel.dependencies[d];
if ( dependency.dependencies ) { //this dependency was actually loaded
data.dependencies[dependency.path] = addDependencies(dependency, files, app);
}
}
return data;
},
/**
* Adds an order to a directed acyclic graph
* @param {Object} appFiles
*/
orderFiles = function( appFiles ) {
var order = 0
function visit(f) {
if ( f.order === undefined ) {
for ( var name in f.dependencies ) {
visit(f.dependencies[name])
}
f.order = (order++);
}
}
for ( var d = 0; d < appFiles.length; d++ ) {
visit(appFiles[d])
}
},
getMostShared = function( files ) {
var shared = []; // count
for ( var fileName in files ) {
var file = files[fileName];
if ( file.packaged ) {
continue;
}
if (!shared[file.apps.length] ) {
shared[file.apps.length] = {};
}
var level = shared[file.apps.length]; //how many apps it is shared in (5?)
var appsName = file.apps.sort().join();
if (!level[appsName] ) {
level[appsName] = {
totalSize: 0,
files: [],
apps: file.apps
};
}
//add file, the count is how many files are shared among this many apps
level[appsName].files.push(file);
level[appsName].totalSize += file.size;
}
if (!shared.length ) {
return null;
}
//get the most
var mostShared = shared.pop(),
mostSize = 0,
most;
for ( var apps in mostShared ) {
if ( mostShared[apps].totalSize > mostSize ) {
most = mostShared[apps];
mostSize = most.totalSize;
}
}
//mark files
for ( var i = 0; i < most.files.length; i++ ) {
var f = most.files[i];
f.packaged = true;
}
return most;
}
steal.build.apps = function( list, options ) {
options = steal.opts(options || {}, {
//compress everything, regardless of what you find
depth: 1,
//folder to build to, defaults to the folder the page is in
to: 1
});
// set the compressor globally
steal.build.compressor = steal.build.builders.scripts.compressors[options.compressor || "localClosure"]();
//a list of files hashed by their path
var files = {},
//keeps track of the packages an app needs
apps = {},
//a list of the apps (top most dependencies)
appFiles = [];
//set defaults
options.depth = options.depth || 2;
options.to = options.to || "packages/"
//go through, open each app, and make dependency graph
for ( var i = 0; i < list.length; i++ ) {
var startFile = list[i] + "/" + steal.File(list[i]).basename() + ".js"
var opener = steal.build.open('steal/rhino/blank.html', {
startFile: startFile
})
appFiles.push(addDependencies(opener.steal._start, files, list[i]));
apps[list[i]] = [];
}
//add an order so we can sort them nicely
orderFiles(appFiles);
// will be set to the biggest group
var pack,
//the package number
packageCount = 0;
//while there are files left to be packaged, get the most shared and largest package
while ((pack = getMostShared(files))) {
print('\njoining shared by ' + pack.apps.join(", "))
//the source of the package
var src = [],
//order the files, most base file first
ordered = pack.files.sort(function( f1, f2 ) {
return f1.order - f2.order;
});
// paths to files this package represents
var paths = [];
//go through files, put in src, and track
for ( var i = 0; i < ordered.length; i++ ) {
var f = ordered[i];
src.push("/* " + f.path + " */\n" + f.source);
print(" " + f.order + ":" + f.path);
paths.push(f.path)
}
//the final source, includes a steal of all the files in this source
var source = "steal('//" + paths.join("'\n,'//") + "');\nsteal.end();\n" + src.join(";steal.end();\n"),
//the path to save
saveFile = pack.apps.length == 1 ? pack.apps[0] + "/production.js" : "packages/" + packageCount + ".js";
//if we are the top most, replace production file with the following
if ( pack.apps.length == 1 ) {
var packages = apps[pack.apps[0]];
source = "steal.packs('" + packages.join("','") + "', function(){\n" + source + "\n});"
}
//save the file
print("saving " + saveFile);
steal.File(saveFile).save(source);
//add this package to the app's packages list
for ( var pa = 0; pa < pack.apps.length; pa++ ) {
apps[pack.apps[pa]].push(packageCount);
}
packageCount++;
}
}
})
\ No newline at end of file
// load("steal/build/apps/test.js")
_args = ['cookbook', 'mxui/combobox', 'mxui/modal'];
load("steal/buildjs");
\ No newline at end of file
//used to build a page's script
/*global steal : false, Envjs : false, jQuery : false*/
steal(function( steal ) {
var window = (function() {
return this;
}).call(null, 0);
/**
*
* @parent stealjs
*
* Builds an html page's JavaScript and CSS files by compressing and concatenating them into
* a single or several files.
*
* Steal can also build multiple applications at the same time and separate
* shared dependencies into standalone cache-able scripts.
*
* ## How it works
*
* <code>Steal.build</code> opens a page in Envjs to extract all scripts and styles
* from the page. It compresses the resources into production.js and production.css
* files.
*
* Steal.build works with or without using steal.js, so it could work with other script loaders.
*
* ## Building with steal.js.
*
* Building with steal is easy, just point the <code>steal/buildjs</code> script at your page and
* give it the name of your application folder:
*
* @codestart no-highlight
* js steal/buildjs path/to/page.html -to myapp
* @codeend
*
* If you generated a steal app or plugin, there's a handy script already ready for you:
*
* @codestart no-highlight
* js myapp/scripts/build.js
* @codeend
*
* ## Building without steal.js
*
* You can compress and package any page's JavaScript by adding <code>compress="true"</code>
* attributes to your script tag like the following:
*
* @codestart html
* &lt;script src="file1.js" type="text/javascript" compress="true">&lt;/script>
* &lt;script src="file2.js" type="text/javascript" compress="true">&lt;/script>
* @codeend
*
* and then running either:
*
* @codestart no-highlight
* js steal/buildjs path/to/page.html -to [OUTPUT_FOLDER]
* @codeend
*
* or:
*
* @codestart no-highlight
* js steal/buildjs http://hostname/path/page.html -to [OUTPUT_FOLDER]
* @codeend
*
* This will compress file1.js and file2.js into a file package named production.js an put it in OUTPUT_FOLDER.
*
* ## Common Problems
*
* If you are getting errors building a production build, it's almost certainly because Envjs is
* close, but not quite a fully featured browser. So, you have to avoid doing things in your page that
* Envjs doesn't like before onload. The most common problems are:
*
* <h5>Malformed HTML or unescaped characters</h5>
* <p>Steal does not have as tolerant of an HTML parser as Firefox. Make sure your page's tags look good.
* Also, make sure you escape characters like &amp; to &amp;amp;
* </p>
* <h5>DOM manipulations before onload</h5>
* <p>EnvJS supports most DOM manipulations. But, it's not a graphical browser so it completely punts
* on styles and dimensional DOM features. It's easy to protect against this, just wait until
* document ready or onload to do these things.
* </p>
* <h5>Unending timeouts or intervals before onload</h5>
* <p>Envjs won't quit running until all timeouts or intervals have completed. If you have a reoccuring
* 'process', consider starting it on document ready or onload.</p>
* <h2>Building With Shared Dependencies</h2>
* <p>
* If you are using steal in a setting with multiple pages loading similar
* functionality, it's typically a good idea to build the shared functionality in
* its own script. This way when a user switches pages, they don't have to load
* that functionality again.
* </p>
* <p>
* To do this, use the buildjs script with the names of your apps:
* </p>
* @codestart
* ./js steal/buildjs myco/search myco/searchresults music
* @codeend
* <h2>steal.build function</h2>
* Takes a url, extracts
* @param {String} url an html page to compress
* @param {Object} options An object literal with the following optional values:
* <table class='options'>
* <tr>
* <th>Name</th><th>Description</th>
* </tr>
* <tr><td>to</td>
* <td>The folder to put the production.js and production.css files.</td></tr>
* <tr><td>all</td>
* <td>Concat and compress all scripts and styles. By default, this is set to false, meaning
* scripts and styles have to opt into being compress with the <code>compress='true'</code> attribute.</td></tr>
* <tr><td>compressor</td>
* <td>The compressor to use: shrinksafe, localClosure, closureService or yui</td></tr>
* </table>
* Note that you must install shrinksafe and YUI compressor manually, because they are not included in the JavaScriptMVC distribution.
*/
steal.build = function( url, options ) {
//convert options (which might be an array) into an object
options = steal.opts(options || {}, {
//compress everything, regardless of what you find
all: 1,
//folder to build to, defaults to the folder the page is in
to: 1,
//compressor to use, e.g. shrinksafe, localClosure, closureService or yui
compressor: 1
});
// to is the folder packages will be put in
options.to = options.to || (url.match(/https?:\/\//) ? "" : url.substr(0, url.lastIndexOf('/')));
// make sure to ends with /
if ( options.to.match(/\\$/) === null && options.to !== '' ) {
options.to += "/";
}
steal.print("Building to " + options.to);
var opener = steal.build.open(url);
// iterates through the types of builders. For now
// there are just scripts and styles builders
for ( var builder in steal.build.builders ) {
steal.build.builders[builder](opener, options);
}
};
// a place for the builders
steal.build.builders = {}; //builders
// a helper function that gets the src of a script and returns
// the content for that script
var loadScriptText = function( src ) {
var text = "",
base = "" + window.location,
url = src.match(/([^\?#]*)/)[1];
if ( url.match(/^\/\//) ) {
url = steal.root.join(url.substr(2)); //can steal be removed?
}
url = Envjs.uri(url, base);
if ( url.match(/^file\:/) ) {
url = url.replace("file:/", "");
text = readFile("/" + url);
}
if ( url.match(/^https?\:/) ) {
text = readUrl(url);
}
return text;
},
checkText = function(text, id){
if(!text){
print("\n!! There is nothing at "+id+"!!")
}
};
// types conversion
// the idea is for each type to return JavaScript (or css) that
// should be in its place
steal.build.types = {
'text/javascript': function( script ) {
if ( script.src ) {
return loadScriptText(script.src, script);
}
else {
return script.text;
}
},
'text/css': function( script ) {
if ( script.href ) {
return loadScriptText(script.href, script);
}
else {
return script.text;
}
},
'text/ejs': function( script ) {
var text = script.text || loadScriptText(script.src),
id = script.id || script.getAttribute("id");
checkText(text, script.src || id);
return jQuery.View.registerScript("ejs", id, text);
},
'text/micro': function( script ) {
var text = script.text || loadScriptText(script.src),
id = script.id || script.getAttribute("id");
checkText(text, script.src || id);
return jQuery.View.registerScript("micro", id, text);
},
'text/jaml': function( script ) {
var text = script.text || loadScriptText(script.src),
id = script.id || script.getAttribute("id");
checkText(text, script.src || id);
return jQuery.View.registerScript("jaml", id, text);
},
'text/tmpl': function( script ) {
var text = script.text || loadScriptText(script.src),
id = script.id || script.getAttribute("id");
checkText(text, script.src || id);
return jQuery.View.registerScript("tmpl", id, text);
},
loadScriptText: loadScriptText
};
/**
* @function open
* Opens a page by:
* temporarily deleting the rhino steal
* opening the page with Envjs
* setting back rhino steal, saving envjs's steal as steal._steal;
* @param {String} url the html page to open
* @return {Object} an object with properties that makes extracting
* the content for a certain tag slightly easier.
*
*/
steal.build.open = function( url, stealData ) {
var scripts = [],
// save and remove the old steal
oldSteal = window.steal || steal,
newSteal;
delete window.steal;
if ( stealData ) {
window.steal = stealData;
}
// get envjs
load('steal/rhino/env.js'); //reload every time
var success = true;
// open the url
Envjs(url, {
scriptTypes: {
"text/javascript": true,
"text/envjs": true,
"": true
},
fireLoad: false,
logLevel: 2,
afterScriptLoad: {
".*": function( script ) {
scripts.push(script);
}
},
onLoadUnknownTypeScript: function( script ) {
scripts.push(script);
},
afterInlineScriptLoad: function( script ) {
scripts.push(script);
},
onScriptLoadError: function(script) {
success = false;
},
dontPrintUserAgent: true,
killTimersAfterLoad: true
});
if (!success) {
java.lang.System.exit(-1);
}
// set back steal
newSteal = window.steal;
window.steal = oldSteal;
window.steal._steal = newSteal;
// check if newSteal added any build types (used to convert less to css for example).
if(newSteal && newSteal.build && newSteal.build.types){
for ( var buildType in newSteal.build.types ) {
oldSteal.build.types[buildType] = newSteal.build.types[buildType];
}
}
// return the helper
return {
/**
* @hide
* Gets all elements of a type, extracts their converted content, and calls a callback function with
* each element and its converted content.
* @param {Object} [type] the tag to get
* @param {Object} func a function to call back with the element and its content
*/
each: function( type, func ) {
if ( typeof type == 'function' ) {
func = type;
type = 'script';
}
var scripts = document.getElementsByTagName(type);
for ( var i = 0; i < scripts.length; i++ ) {
func(scripts[i], this.getScriptContent(scripts[i]), i);
}
},
getScriptContent: function( script ) {
return steal.build.types[script.type] && steal.build.types[script.type](script, loadScriptText);
},
// the
steal: newSteal,
url: url
};
};
});
steal("//steal/build/pluginify/tokens").
plugins('steal/build').then(function(){
steal.build.parse = function(str){
//print("Breaking up strs")
var tokens = str.tokens('=<>!+-*&|/%^', '=<>&|'),
tokenNum = 0;
var moveNext = function(){
var next = tokens[tokenNum++];
if(next){
//print("Next TOken = "+next.value);
}
return next;
}
return {
moveNext : moveNext,
next : function(){
return tokens[tokenNum];
},
until: function(){
var token,
matchCounts = [];
for(var i =0; i < arguments.length;i++){
matchCounts[i] =0;
if(typeof arguments[i] == "string"){
arguments[i] = [arguments[i]]
}
}
while (token = moveNext() ) {
for(var i =0; i< arguments.length; i++){
if( token.type !== "string" &&
token.value === arguments[i][matchCounts[i]]){
matchCounts[i] = matchCounts[i]+1;
if(matchCounts[i] === arguments[i].length){
return token;
}
}else{
matchCounts[i] = 0;
}
}
}
}
}
};
})
\ No newline at end of file
// usage:
// js steal\scripts\pluginify.js funcunit/functional -destination funcunit/dist/funcunit.js
// js steal\scripts\pluginify.js jquery/controller
// js steal\scripts\pluginify.js jquery/event/drag -exclude jquery/lang/vector/vector.js jquery/event/livehack/livehack.js
// load("steal/rhino/steal.js");
steal.plugins('steal/parse','steal/build/scripts').then(
function(s) {
/**
* Builds a 'steal-less' version of your application. To use this, files that use steal must
* have their code within a callback function.
*
* js steal\pluginify jquery\controller -nojquery
*
* @param {Object} plugin
* @param {Object} opts
*/
s.build.pluginify = function( plugin, opts ) {
print(""+plugin+" >");
var jq = true,
othervar,
opts = steal.opts(opts, {
"destination": 1,
"exclude": -1,
"nojquery": 0,
"global" : 0,
"compress" : 0
}),
destination = opts.destination || plugin+"/"+plugin.replace(/\//g,".") + ".js";
opts.exclude = !opts.exclude ? [] : (steal.isArray(opts.exclude) ? opts.exclude : [opts.exclude]);
if ( opts.nojquery ) {
jq = false;
//othervar = opts.nojquery;
opts.exclude.push('jquery.js');
}
opts.exclude.push("steal/dev/")
rhinoLoader = {
callback: function( s ) {
s.pluginify = true;
s.plugins(plugin);
}
};
steal.win().build_in_progress = true;
var pageSteal = steal.build.open("steal/rhino/empty.html").steal,
out = [],
str, i, inExclude = function( path ) {
for ( var i = 0; i < opts.exclude.length; i++ ) {
if ( path.indexOf(opts.exclude[i]) > -1 ) {
return true;
}
}
return false;
},
steals = pageSteal.total;
for ( i = 0; i < steals.length; i++ ) {
if(!inExclude(steals[i].path)){
var content = steal.build.pluginify.content(steals[i], opts.global ? opts.global : "jQuery" );
if(content){
print(" > "+steals[i].path)
out.push(steal.build.builders.scripts.clean(content));
}
}else{
print(" Ignoring "+steals[i].path)
}
}
var output = out.join(";\n");
if(opts.compress) {
var compressorName = (typeof(opts.compress) == "string") ? opts.compress : "localClosure";
var compressor = steal.build.builders.scripts.compressors[compressorName]()
output = compressor(output);
}
print("--> " + destination);
new steal.File(destination).save(output);
//print("pluginified " + plugin)
};
//keeps track of which 'then' we are in with steal
var funcCount = {};
//gets content from a steal
s.build.pluginify.content = function(steal, param){
if(steal.func){
// if it's a function, go to the file it's in ... pull out the content
var index = funcCount[steal.path] || 0,
contents = readFile(steal.path);
//print("FOOO "+steal.path);
funcCount[steal.path]++;
return "("+s.build.pluginify.getFunction(contents, index)+")("+param+")";
}else{
var content = readFile(steal.path);
if( /steal[.\(]/.test(content) ){
return;
}
//make sure steal isn't in here
return content;
}
};
s.build.pluginify.getFunction = function(content, ith){
var p = steal.parse(content),
token,
funcs = [];
while (token = p.moveNext() ) {
//print(token.value)
if(token.type !== "string"){
switch(token.value){
case "steal" :
stealPull(p, content, function(func){
funcs.push(func)
});
break;
}
}
}
return funcs[ith||0];
};
//gets a function from steal
var stealPull = function(p, content, cb){
var token = p.next(),
startToken,
endToken;
if(!token || (token.value != "." && token.value != "(")){
// we said steal .. but we don't care
return;
}else{
p.moveNext();
}
if(token.value == "."){
p.until("(")
}
token = p.until("function",")");
if(token.value == "function"){
startToken = p.until("{");
endToken = p.partner("{");
cb(content.substring(token.from, endToken.to))
//print("CONTENT\n"+ );
p.moveNext();
}else{
}
stealPull(p,content, cb );
};
});
function(abc){
(function(){});
"abc(){};";
/* steal */
// steal
boom
}
\ No newline at end of file
// load('steal/compress/test/run.js')
/**
* Tests compressing a very basic page and one that is using steal
*/
load('steal/rhino/steal.js')
steal.plugins('steal/test','steal/build/pluginify').then( function( s ) {
STEALPRINT = false;
s.test.module("steal/build/pluginify")
s.test.test("getFunctions", function(t){
var js = readFile('steal/build/pluginify/test/test_steals.js');
var firstFunc = steal.build.pluginify.getFunction(js, 0);
t.equals(firstFunc, readFile('steal/build/pluginify/test/firstFunc.js'));
var secondFunc = steal.build.pluginify.getFunction(js, 1);
t.equals(secondFunc, readFile('steal/build/pluginify/test/secondFunc.js'))
})
s.test.test("getFunctions2", function(t){
var js = readFile('jquery/view/micro/micro.js');
var firstFunc = steal.build.pluginify.getFunction(js, 0);
//print(firstFunc);
})
});
\ No newline at end of file
/**
* steal something
*/
steal.foo().bar(function(abc){
(function(){});
"abc(){};";
/* steal */
// steal
boom
}).plugins("boom").then(function($,foo){
//yes
})
abc.def
asdfas
steal.then(function(){
/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g
})
\ No newline at end of file
// tokens.js
// 2009-05-17
// (c) 2006 Douglas Crockford
// Produce an array of simple token objects from a string.
// A simple token object contains these members:
// type: 'name', 'string', 'number', 'operator'
// value: string or number value of the token
// from: index of first character of the token
// to: index of the last character + 1
// Comments of the // type are ignored.
// Operators are by default single characters. Multicharacter
// operators can be made by supplying a string of prefix and
// suffix characters.
// characters. For example,
// '<>+-&', '=>&:'
// will match any of these:
// <= >> >>> <> >= +: -: &: &&: &&
String.prototype.tokens = function (prefix, suffix) {
var c; // The current character.
var from; // The index of the start of the token.
var i = 0; // The index of the current character.
var length = this.length;
var n; // The number value.
var q; // The quote character.
var str; // The string value.
var result = []; // An array to hold the results.
var prereg = true;
var make = function (type, value) {
// Make a token object.
//prereg = i &&
// (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
// i === 'return')
//print(type+":"+value+"-")
prereg = (type == 'operator' || type === 'name') &&
(value === 'return' || ('(,=:[!&|?{};'.indexOf(value.charAt(value.length - 1)) >= 0 ) )
//print(type+" : "+value+" - "+prereg)
return {
type: type,
value: value,
from: from,
to: i
};
};
var has = function(thIs, before){
var j = i+1;
for (;;) {
c = this.charAt(j);
if(c === thIs){
return true;
}
//print("|"+c+"|"+(c=="\n" || c=="\r"));
if (before.test(c) || c === '') {
return false;
}
j += 1;
}
}
// Begin tokenization. If the source string is empty, return nothing.
if (!this) {
return;
}
// If prefix and suffix strings are not provided, supply defaults.
if (typeof prefix !== 'string') {
prefix = '<>+-&';
}
if (typeof suffix !== 'string') {
suffix = '=>&:';
}
// Loop through this text, one character at a time.
c = this.charAt(i);
while (c) {
from = i;
//print(c);
// Ignore whitespace.
if (c <= ' ') {
i += 1;
c = this.charAt(i);
// name.
} else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
str = c;
i += 1;
for (;;) {
c = this.charAt(i);
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || c === '_') {
str += c;
i += 1;
} else {
break;
}
}
//print(str);
result.push(make('name', str));
// number.
// A number cannot start with a decimal point. It must start with a digit,
// possibly '0'.
} else if (c >= '0' && c <= '9') {
str = c;
i += 1;
// Look for more digits.
for (;;) {
c = this.charAt(i);
if (c < '0' || c > '9') {
break;
}
i += 1;
str += c;
}
// Look for a decimal fraction part.
if (c === '.') {
i += 1;
str += c;
for (;;) {
c = this.charAt(i);
if (c < '0' || c > '9') {
break;
}
i += 1;
str += c;
}
}
// Look for an exponent part.
if (c === 'e' || c === 'E') {
i += 1;
str += c;
c = this.charAt(i);
if (c === '-' || c === '+') {
i += 1;
str += c;
c = this.charAt(i);
}
if (c < '0' || c > '9') {
make('number', str).error("Bad exponent");
}
do {
i += 1;
str += c;
c = this.charAt(i);
} while (c >= '0' && c <= '9');
}
// Make sure the next character is not a letter.
if (c >= 'a' && c <= 'z') {
str += c;
i += 1;
print(this.substr(i-20,20))
print(this.substr(i,20))
make('number', str).error("Bad number");
}
// Convert the string value to a number. If it is finite, then it is a good
// token.
n = +str;
if (isFinite(n)) {
result.push(make('number', n));
} else {
make('number', str).error("Bad number");
}
// string
} else if (c === '\'' || c === '"') {
str = '';
q = c;
i += 1;
//print("----")
for (;;) {
c = this.charAt(i);
//print(this[i])
if (c < ' ') {
print(this.substr(i-20,20))
print(this.substr(i,20))
make('string', str).error(c === '\n' || c === '\r' || c === '' ?
"Unterminated string." :
"Control character in string.", make('', str));
}
// Look for the closing quote.
if (c === q) {
break;
}
// Look for escapement.
if (c === '\\') {
i += 1;
if (i >= length) {
make('string', str).error("Unterminated string");
}
c = this.charAt(i);
switch (c) {
case 'b':
c = '\b';
break;
case 'f':
c = '\f';
break;
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'u':
if (i >= length) {
make('string', str).error("Unterminated string");
}
c = parseInt(this.substr(i + 1, 4), 16);
if (!isFinite(c) || c < 0) {
make('string', str).error("Unterminated string");
}
c = String.fromCharCode(c);
i += 4;
break;
}
}
str += c;
i += 1;
}
i += 1;
//print("str = "+str)
result.push(make('string', str));
c = this.charAt(i);
// comment.
} else if (c === '/' && this.charAt(i + 1) === '*') {
var str = c;
i += 1;
for (;;) {
c = this.charAt(i);
str += c;
if (c === '*' && this.charAt(i+1) == "/") {
i += 1;
i += 1;
str+= "/";
result.push(make('comment', str));
break;
}
i += 1;
}
} else if (c === '/' && this.charAt(i + 1) === '/') {
i += 1;
for (;;) {
c = this.charAt(i);
if (c === '\n' || c === '\r' || c === '') {
break;
}
i += 1;
}
// regexp
} else if (c === '/' && has.call(this, "/", /[\n\r]/) && prereg) { // what about /2
//print('matcing regexp')
i += 1;
var str = c;
for (;;) {
c = this.charAt(i);
if(c === "\\"){ //skip over \
str += c;
i += 1;
//print("adding "+c)
c = this.charAt(i);
str += c;
//print("adding "+c)
i += 1;
c = this.charAt(i);
continue;
}
if (c === '/' ) {
str += c;
i += 1;
c = this.charAt(i);
while(/\w/.test(c)){ //get stuff after /a/m
str += c;
i += 1;
c = this.charAt(i);
}
result.push(make('regexp', str));
//print("regexp = "+str)
break;
}
str += c;
i += 1;
}
// combining
} else if (prefix.indexOf(c) >= 0) {
str = c;
i += 1;
while (i < length) {
c = this.charAt(i);
if (suffix.indexOf(c) < 0) {
break;
}
str += c;
i += 1;
}
result.push(make('operator', str));
// single-character operator
} else {
i += 1;
result.push(make('operator', c));
c = this.charAt(i);
}
}
return result;
};
steal(function( steal ) {
/**
* Builds JavaScripts
*
* @param {Object} opener the result of a steal.build.open
* @param {Object} options options passed to the build script
*
* * __to__ - which folder the production.css files should be put in
* * __quite__ - tell the compressor to be less abnoxious about sending errors
* * __all__ - compress all scripts
*/
var scripts = (steal.build.builders.scripts = function( opener, options ) {
steal.print("\nBUILDING SCRIPTS --------------- ");
// get the compressor
var compressor = scripts.compressors[options.compressor || "localClosure"](),
// packages that can be compressed somewhere
packages = {},
// the current package
currentPackage = [];
// compress all scripts by default
if ( options.all ) {
packages['production.js'] = currentPackage;
}
// for each script we find
opener.each("script", function( script, text, i ) {
// if we should ignore it, ignore it
if ( script.getAttribute('ignore') == "true" ) {
if ( script.src ) {
steal.print(' ignoring ' + script.src);
}
return;
}
// if it has a src, let people know we are compressing it
if ( script.src ) {
steal.print(" " + script.src.replace(/\?.*$/, "").replace(/^(\.\.\/)+/, ""));
}
// get the package, this will be production.js
var pack = script.getAttribute('package');
if ( pack ) {
//if we don't have it, create it and set it to the current package
if (!packages[pack] ) {
packages[pack] = [];
}
currentPackage = packages[pack];
}
// clean out any remove-start style comments
text = scripts.clean(text);
// if we should compress the script, compress it
if ( script.getAttribute('compress') == "true" || options.all ) {
text = compressor(text, true);
}
// put the result in the package
currentPackage.push(text);
});
steal.print("");
// go through all the packages
for ( var p in packages ) {
if ( packages[p].length ) {
//join them
var compressed = packages[p].join(";\n");
//save them
new steal.File(options.to + p).save(compressed);
steal.print("SCRIPT BUNDLE > " + options.to + p);
}
}
});
// removes dev comments from text
scripts.clean = function( text ) {
return String(java.lang.String(text).replaceAll("(?s)\/\/@steal-remove-start(.*?)\/\/@steal-remove-end", "").replaceAll("steal[\n\s\r]*\.[\n\s\r]*dev[\n\s\r]*\.[\n\s\r]*(\\w+)[\n\s\r]*\\([^\\)]*\\)", ""));
};
//various compressors
scripts.compressors = {
// needs shrinksafe.jar at steal/build/javascripts/shrinksafe.jar
shrinksafe: function() {
steal.print("steal.compress - Using ShrinkSafe");
// importPackages/Class doesn't really work
var URLClassLoader = Packages.java.net.URLClassLoader,
URL = java.net.URL,
File = java.io.File,
ss = new File("steal/build/javascripts/shrinksafe.jar"),
ssurl = ss.toURL(),
urls = java.lang.reflect.Array.newInstance(URL, 1);
urls[0] = new URL(ssurl);
var clazzLoader = new URLClassLoader(urls),
mthds = clazzLoader.loadClass("org.dojotoolkit.shrinksafe.Compressor").getDeclaredMethods(),
rawCompress = null;
//iterate through methods to find the one we are looking for
for ( var i = 0; i < mthds.length; i++ ) {
var meth = mthds[i];
if ( meth.toString().match(/compressScript\(java.lang.String,int,int,boolean\)/) ) {
rawCompress = meth;
}
}
return function( src ) {
var zero = new java.lang.Integer(0),
one = new java.lang.Integer(1),
tru = new java.lang.Boolean(false),
script = new java.lang.String(src);
return rawCompress.invoke(null, script, zero, one, tru);
};
},
closureService: function() {
steal.print("steal.compress - Using Google Closure Service");
return function( src ) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://closure-compiler.appspot.com/compile", false);
xhr.setRequestHeader["Content-Type"] = "application/x-www-form-urlencoded";
var params = "js_code=" + encodeURIComponent(src) + "&compilation_level=WHITESPACE_ONLY" + "&output_format=text&output_info=compiled_code";
xhr.send(params);
return "" + xhr.responseText;
};
},
localClosure: function() {
//was unable to use SS import method, so create a temp file
steal.print("steal.compress - Using Google Closure app");
return function( src, quiet ) {
var rnd = Math.floor(Math.random() * 1000000 + 1),
filename = "tmp" + rnd + ".js",
tmpFile = new steal.File(filename);
tmpFile.save(src);
var outBaos = new java.io.ByteArrayOutputStream(),
output = new java.io.PrintStream(outBaos);
if ( quiet ) {
runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--js", filename, {
output: output
});
} else {
runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--js", filename, {
output: output
});
}
tmpFile.remove();
return outBaos.toString();
};
},
yui: function() {
// needs yuicompressor.jar at steal/build/scripts/yuicompressor.jar
steal.print("steal.compress - Using YUI compressor");
return function( src ) {
var rnd = Math.floor(Math.random() * 1000000 + 1),
filename = "tmp" + rnd + ".js",
tmpFile = new steal.File(filename);
tmpFile.save(src);
var outBaos = new java.io.ByteArrayOutputStream(),
output = new java.io.PrintStream(outBaos);
runCommand(
"java",
"-jar",
"steal/build/scripts/yuicompressor.jar",
"--charset",
"utf-8",
filename,
{ output: output }
);
tmpFile.remove();
return outBaos.toString();
};
}
};
});
steal(function( steal ) {
/**
* cssmin.js
* Author: Stoyan Stefanov - http://phpied.com/
* This is a JavaScript port of the CSS minification tool
* distributed with YUICompressor, itself a port
* of the cssmin utility by Isaac Schlueter - http://foohack.com/
* Permission is hereby granted to use the JavaScript version under the same
* conditions as the YUICompressor (original YUICompressor note below).
*/
/*
* YUI Compressor
* Author: Julien Lecomte - http://www.julienlecomte.net/
* Copyright (c) 2009 Yahoo! Inc. All rights reserved.
* The copyrights embodied in the content of this file are licensed
* by Yahoo! Inc. under the BSD (revised) open source license.
*/
var YAHOO = YAHOO || {};
YAHOO.compressor = YAHOO.compressor || {};
YAHOO.compressor.cssmin = function (css, linebreakpos) {
var startIndex = 0,
endIndex = 0,
i = 0, max = 0,
preservedTokens = [],
comments = [],
token = '',
totallen = css.length,
placeholder = '';
// collect all comment blocks...
while ((startIndex = css.indexOf("/*", startIndex)) >= 0) {
endIndex = css.indexOf("*/", startIndex + 2);
if (endIndex < 0) {
endIndex = totallen;
}
token = css.slice(startIndex + 2, endIndex);
comments.push(token);
css = css.slice(0, startIndex + 2) + "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + (comments.length - 1) + "___" + css.slice(endIndex);
startIndex += 2;
}
// preserve strings so their content doesn't get accidentally minified
css = css.replace(/("([^\\"]|\\.|\\)*")|('([^\\']|\\.|\\)*')/g, function (match) {
var i, max, quote = match.substring(0, 1);
match = match.slice(1, -1);
// maybe the string contains a comment-like substring?
// one, maybe more? put'em back then
if (match.indexOf("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_") >= 0) {
for (i = 0, max = comments.length; i < max; i = i + 1) {
match = match.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", comments[i]);
}
}
// minify alpha opacity in filter strings
match = match.replace(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity=");
preservedTokens.push(match);
return quote + "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___" + quote;
});
// strings are safe, now wrestle the comments
for (i = 0, max = comments.length; i < max; i = i + 1) {
token = comments[i];
placeholder = "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___";
// ! in the first position of the comment means preserve
// so push to the preserved tokens keeping the !
if (token.charAt(0) === "!") {
preservedTokens.push(token);
css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
continue;
}
// \ in the last position looks like hack for Mac/IE5
// shorten that to /*\*/ and the next one to /**/
if (token.charAt(token.length - 1) === "\\") {
preservedTokens.push("\\");
css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
i = i + 1; // attn: advancing the loop
preservedTokens.push("");
css = css.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
continue;
}
// keep empty comments after child selectors (IE7 hack)
// e.g. html >/**/ body
if (token.length === 0) {
startIndex = css.indexOf(placeholder);
if (startIndex > 2) {
if (css.charAt(startIndex - 3) === '>') {
preservedTokens.push("");
css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
}
}
}
// in all other cases kill the comment
css = css.replace("/*" + placeholder + "*/", "");
}
// Normalize all whitespace strings to single spaces. Easier to work with that way.
css = css.replace(/\s+/g, " ");
// Remove the spaces before the things that should not have spaces before them.
// But, be careful not to turn "p :link {...}" into "p:link{...}"
// Swap out any pseudo-class colons with the token, and then swap back.
css = css.replace(/(^|\})(([^\{:])+:)+([^\{]*\{)/g, function (m) {
return m.replace(":", "___YUICSSMIN_PSEUDOCLASSCOLON___");
});
css = css.replace(/\s+([!{};:>+\(\)\],])/g, '$1');
css = css.replace(/___YUICSSMIN_PSEUDOCLASSCOLON___/g, ":");
// retain space for special IE6 cases
css = css.replace(/:first-(line|letter)(\{|,)/g, ":first-$1 $2");
// no space after the end of a preserved comment
css = css.replace(/\*\/ /g, '*/');
// If there is a @charset, then only allow one, and push to the top of the file.
css = css.replace(/^(.*)(@charset "[^"]*";)/gi, '$2$1');
css = css.replace(/^(\s*@charset [^;]+;\s*)+/gi, '$1');
// Put the space back in some cases, to support stuff like
// @media screen and (-webkit-min-device-pixel-ratio:0){
css = css.replace(/\band\(/gi, "and (");
// Remove the spaces after the things that should not have spaces after them.
css = css.replace(/([!{}:;>+\(\[,])\s+/g, '$1');
// remove unnecessary semicolons
css = css.replace(/;+\}/g, "}");
// Replace 0(px,em,%) with 0.
css = css.replace(/([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)/gi, "$1$2");
// Replace 0 0 0 0; with 0.
css = css.replace(/:0 0 0 0(;|\})/g, ":0$1");
css = css.replace(/:0 0 0(;|\})/g, ":0$1");
css = css.replace(/:0 0(;|\})/g, ":0$1");
// Replace background-position:0; with background-position:0 0;
// same for transform-origin
css = css.replace(/(background-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|\})/gi, function(all, prop, tail) {
return prop.toLowerCase() + ":0 0" + tail;
});
// Replace 0.6 to .6, but only when preceded by : or a white-space
css = css.replace(/(:|\s)0+\.(\d+)/g, "$1.$2");
// Shorten colors from rgb(51,102,153) to #336699
// This makes it more likely that it'll get further compressed in the next step.
css = css.replace(/rgb\s*\(\s*([0-9,\s]+)\s*\)/gi, function () {
var i, rgbcolors = arguments[1].split(',');
for (i = 0; i < rgbcolors.length; i = i + 1) {
rgbcolors[i] = parseInt(rgbcolors[i], 10).toString(16);
if (rgbcolors[i].length === 1) {
rgbcolors[i] = '0' + rgbcolors[i];
}
}
return '#' + rgbcolors.join('');
});
// Shorten colors from #AABBCC to #ABC. Note that we want to make sure
// the color is not preceded by either ", " or =. Indeed, the property
// filter: chroma(color="#FFFFFF");
// would become
// filter: chroma(color="#FFF");
// which makes the filter break in IE.
css = css.replace(/([^"'=\s])(\s*)#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])/gi, function () {
var group = arguments;
if (
group[3].toLowerCase() === group[4].toLowerCase() &&
group[5].toLowerCase() === group[6].toLowerCase() &&
group[7].toLowerCase() === group[8].toLowerCase()
) {
return (group[1] + group[2] + '#' + group[3] + group[5] + group[7]).toLowerCase();
} else {
return group[0].toLowerCase();
}
});
// border: none -> border:0
css = css.replace(/(border|border-top|border-right|border-bottom|border-right|outline|background):none(;|\})/gi, function(all, prop, tail) {
return prop.toLowerCase() + ":0" + tail;
});
// shorter opacity IE filter
css = css.replace(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity=");
// Remove empty rules.
css = css.replace(/[^\};\{\/]+\{\}/g, "");
if (linebreakpos >= 0) {
// Some source control tools don't like it when files containing lines longer
// than, say 8000 characters, are checked in. The linebreak option is used in
// that case to split long lines after a specific column.
startIndex = 0;
i = 0;
while (i < css.length) {
i = i + 1;
if (css[i - 1] === '}' && i - startIndex > linebreakpos) {
css = css.slice(0, i) + '\n' + css.slice(i);
startIndex = i;
}
}
}
// Replace multiple semi-colons in a row by a single one
// See SF bug #1980989
css = css.replace(/;;+/g, ";");
// restore preserved comments and strings
for (i = 0, max = preservedTokens.length; i < max; i = i + 1) {
css = css.replace("___YUICSSMIN_PRESERVED_TOKEN_" + i + "___", preservedTokens[i]);
}
// Trim the final string (for any leading or trailing white spaces)
css = css.replace(/^\s+|\s+$/g, "");
return css;
};
steal.build.builders.styles.min = function( css ) {
//remove comments & minify
return YAHOO.compressor.cssmin(css);
}
});
steal(function( steal ) {
/**
* Builds and compresses CSS files.
* @param {Object} opener a steal opener that can give the final version of scripts
* @param {Object} options options configuring the css building
*
* - __to__ where the css should be built.
*/
var styles = (steal.build.builders.styles = function( opener, options ) {
steal.print("\nBUILDING STYLES --------------- ");
//where we are putting stuff
var folder = options.to.substr(0, options.to.length - 1),
//where the page is
pageFolder = steal.File(opener.url).dir(),
currentPackage = [];
opener.each('link', function( link, text, i ) {
steal.print(link.type)
//let people know we are adding it
if ( link.href && steal.build.types[link.type] ) {
steal.print(link.href)
var loc = steal.File(pageFolder).join(link.href),
converted = convert(text, loc, folder);
currentPackage.push(converted);
}
});
steal.print("")
if ( currentPackage.length ) {
steal.print("STYLE BUNDLE > " + folder + "/production.css")
//now that we have all the css minify and save it
var raw_css = currentPackage.join(""),
minified_css = styles.min(raw_css);
steal.print("Nice! "+calcSavings(raw_css.length,minified_css.length));
steal.File(folder + "/production.css").save(minified_css);
} else {
steal.print("no styles\n")
}
});
//used to convert css referencs in one file so they will make sense from prodLocation
var convert = function( css, cssLocation, prodLocation ) {
//how do we go from prod to css
var cssLoc = new steal.File(cssLocation).dir(),
newCSss = css.replace(/url\(['"]?([^'"\)]*)['"]?\)/g, function( whole, part ) {
//check if url is relative
if (!isRelative(part) ) {
return whole
}
//it's a relative path from cssLocation, need to convert to
// prodLocation
var imagePath = steal.File(part).joinFrom(cssLoc),
fin = steal.File(imagePath).toReferenceFromSameDomain(prodLocation);
//print(" -> "+imagePath);
steal.print(" " + part + " > " + fin);
return "url(" + fin + ")";
});
return newCSss;
},
isRelative = function( part ) {
// http://, https://, /
return !/^(http:\/\/|https:\/\/|\/)/.test(part)
},
calcSavings = function(raw_len, minified_len) {
var diff_len = raw_len - minified_len, x = Math.pow(10,1);
return 'Compressed: '+(Math.round((diff_len/raw_len*100)*x)/x)+'% Before: '+
string2size(raw_len)+' After: '+string2size(minified_len);
},
string2size = function(bytes) {
var s = ['bytes','kb','mb','gb','tb','pb'];
var e = Math.floor(Math.log(bytes)/Math.log(1024));
return (bytes/Math.pow(1024,Math.floor(e))).toFixed(1)+' '+s[e];
};
},'//steal/build/styles/cssmin');
\ No newline at end of file
<html>
<head>
</head>
<body>
<h1>Bordered</h1>
<script type='text/javascript'
src='../../../../steal.js?steal/build/styles/test/app'></script>
</body>
</html>
\ No newline at end of file
.background1a { background-image: url(justin.png) }
.background1b { background-image: url(../upload.png) }
.background1c { background-image: url('justin.png') }
.background1d { background-image: url('../upload.png') }
.background2 { background-image: url(upload.PNG) }
.back {
width: 200px; height: 200px;
}
.background2b{
background-image : url(/foo/bar.PNG)
}
/**
* here is a multi line comment
*/
.foo { color: blue}
<html>
<head>
<link type="text/css" href="css/css1.css" rel="stylesheet" />
<link type="text/css" href="css2.css" rel="stylesheet" />
<!-- <link type="text/css" href="production.css" rel="stylesheet" />
-->
</head>
<body>
<h3>Picture of Justin</h3>
<div class='background1a back'></div>
<h3>Picture of Upload</h3>
<div class='background1b back'></div>
<h3>Picture of Upload</h3>
<div class='background2 back'></div>
<p>You can verify this by replacing the style sheet's above
with production.css</p>
</body>
</html>
\ No newline at end of file
.background1a{background-image:url(css/justin.png)}.background1b{background-image:url(upload.png)}.background1c{background-image:url(css/justin.png)}.background1d{background-image:url(upload.png)}.background2{background-image:url(upload.PNG)}.back{width:200px;height:200px}.background2b{background-image:url(/foo/bar.PNG)}
\ No newline at end of file
.background1a{background-image:url(css/justin.png)}.background1b{background-image:url(upload.png)}.background1c{background-image:url(css/justin.png)}.background1d{background-image:url(upload.png)}
.background2{background-image:url(upload.PNG)}.back{width:200px;height:200px}.background2b{background-image:url(/foo/bar.PNG)}
\ No newline at end of file
// load('steal/build/styles/test/styles_test.js')
/**
* Tests compressing a very basic page and one that is using steal
*/
load('steal/rhino/steal.js')
steal('//steal/test/test', function( s ) {
//STEALPRINT = false;
s.test.module("steal/build/styles")
STEALPRINT = false;
s.test.test("css", function(){
load('steal/rhino/steal.js');
steal.plugins(
'steal/build','steal/build/styles',
function(){
steal.build('steal/build/styles/test/page.html',
{to: 'steal/build/styles/test'});
});
var prod = readFile('steal/build/styles/test/production.css').replace(/\r|\n|\s/g,""),
expected = readFile('steal/build/styles/test/productionCompare.css').replace(/\r|\n|\s/g,"");
s.test.equals(
prod,
expected,
"css out right");
s.test.clear();
})
s.test.test("min multiline comment", function(){
load('steal/rhino/steal.js');
steal.plugins('steal/build','steal/build/styles',function(){
var input = readFile('steal/build/styles/test/multiline.css'),
out = steal.build.builders.styles.min(input);
s.test.equals(out, ".foo{color:blue}", "multline comments wrong")
});
s.test.clear();
});
s.test.test("load the same css twice, but only once in prod", function(){
load('steal/rhino/steal.js');
steal.plugins('steal/build',
'steal/build/styles',
function(){
steal.build('steal/build/styles/test/app/app.html',
{to: 'steal/build/styles/test/app'});
});
var prod = readFile('steal/build/styles/test/app/production.css').replace(/\r|\n/g,"");
s.test.equals(prod,"h1{border:solid 1px black}", "only one css");
s.test.clear();
})
});
\ No newline at end of file
<html>
<head></head>
<body>
<script type='text/javascript' src='basicsource.js' package='basicproduction.js' compress='true'></script>
</body>
</html>
\ No newline at end of file
BasicSource = 5;
(function( hereIsAVeryLongName ) {
hereIsAVeryLongName++;
BasicSource = hereIsAVeryLongName;
})(BasicSource)
\ No newline at end of file
<html>
<head></head>
<body>
<script type='text/javascript' src='foreign.js' package='foreignproduction.js' compress='true'></script>
</body>
</html>
\ No newline at end of file
a = "Miércoles";
b = "Atenção";
\ No newline at end of file
<html>
<head>
</head>
<body>
<script type='text/javascript' src='../../steal.js?steal/build/test/https.js'></script>
</body>
</html>
\ No newline at end of file
steal('https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js');
\ No newline at end of file
removeRemoveSteal = function( text ) {
return String(java.lang.String(text).replaceAll("(?s)\/\/@steal-remove-start(.*?)\/\/@steal-remove-end", "").replaceAll("steal[\n\s\r]*\.[\n\s\r]*dev[\n\s\r]*\.[\n\s\r]*(\w+)[\n\s\r]*\([^\)]*\)", ""))
}
//@steal-remove-start
print(removeRemoveSteal(readFile("steal/compress/test/removecode.js")))
//@steal-remove-end
steal = {
dev: {
log: function() {},
isHappyName: function() {}
}
}
steal.dev.log()
var foo = bar;
\ No newline at end of file
// load('steal/compress/test/run.js')
/**
* Tests compressing a very basic page and one that is using steal
*/
load('steal/rhino/steal.js')
steal('//steal/test/test', function( s ) {
STEALPRINT = false;
s.test.module("steal/build")
s.test.test("basicpage", function(){
//lets see if we can clear everything
s.test.clear();
load('steal/rhino/steal.js')
steal("//steal/build/build")
steal("//steal/build/scripts/scripts")
steal.build("steal/build/test/basicpage.html", {
to: 'steal/build/test'
})
s.test.clear();
load("steal/build/test/basicproduction.js")
s.test.equals(BasicSource, 6, "Basic source not right number")
s.test.clear();
s.test.remove('steal/build/test/basicproduction.js')
})
s.test.test("using stealjs", function(){
load('steal/rhino/steal.js')
steal("//steal/build/build")
steal("//steal/build/scripts/scripts")
steal.build("steal/build/test/stealpage.html", {
to: 'steal/build/test'
})
s.test.clear();
s.test.open('steal/build/test/stealprodpage.html')
s.test.equals(BasicSource, 7, "Basic source not right number")
s.test.clear();
s.test.remove('steal/build/test/production.js')
});
s.test.test("foreign characters", function(){
load('steal/rhino/steal.js')
steal("//steal/build/build")
steal("//steal/build/scripts/scripts")
steal.build("steal/build/test/foreign.html", {
to: 'steal/build/test'
})
s.test.clear();
//check that srcs are equal
f1 = readFile('foreign.js').replace(/\r/,"");
f2 = readFile('foreignproduction.js');
s.test.equals(f1, f2, "Foreign Characters")
s.test.clear();
s.test.remove('steal/build/test/foreignproduction.js')
});
});
\ No newline at end of file
<html>
<head></head>
<body>
<script type='text/javascript'
src='../../steal.js?steal[app]=steal/build/test&steal[env]=development'
compress='false'>
</script>
</body>
</html>
<html>
<head></head>
<body>
<script type='text/javascript'
src='../../steal.js?steal[app]=steal/build/test&steal[env]=production'
compress='false'>
</script>
</body>
</html>
steal('basicsource').then(function() {
BasicSource++;
})
\ No newline at end of file
......@@ -53,9 +53,6 @@
<li>
<a href="dependency-examples/emberjs_require/index.html" data-source="http://emberjs.com" data-content="Ember is a JavaScript framework for creating ambitious web applications that eliminates boilerplate and provides a standard application architecture. This is an example of using it with AMD modules">Ember.js + RequireJS</a>
</li>
<li>
<a href="architecture-examples/javascriptmvc/todo/todo/index.html" data-source="http://javascriptmvc.com/" data-content="JavaScriptMVC is an open-source framework containing the best ideas in jQuery development. It guides you to successfully completed projects by promoting best practices, maintainability, and convention over configuration.">JavaScriptMVC</a>
</li>
<li>
<a href="architecture-examples/spine/index.html" data-source="http://spinejs.com/" data-content="Spine is a lightweight framework for building JavaScript web applications. Spine gives you an MVC structure and then gets out of your way, allowing you to concentrate on the fun stuff, building awesome web applications.">Spine.js</a>
</li>
......@@ -65,11 +62,11 @@
<li>
<a href="architecture-examples/dojo/index.html" data-source="http://dojotoolkit.org/" data-content="Dojo saves you time and scales with your development process, using web standards as its platform. It’s the toolkit experienced developers turn to for building high quality desktop and mobile web applications.">Dojo</a>
</li>
</ul>
<ul class="nav nav-pills">
<li>
<a href="architecture-examples/closure/index.html" data-source="http://code.google.com/closure/library/" data-content="The Closure Library is a broad, well-tested, modular, and cross-browser JavaScript library. You can pull just what you need from a large set of reusable UI widgets and controls, and from lower-level utilities for DOM manipulation, server communication, animation, data structures, unit testing, rich-text editing, and more.">Closure</a>
</li>
</ul>
<ul class="nav nav-pills">
<li>
<a href="architecture-examples/yuilibrary/index.html" data-source="http://yuilibrary.com/" data-content="YUI's lightweight core and modular architecture make it scalable, fast, and robust. Built by frontend engineers at Yahoo!, YUI powers the most popular websites in the world.">YUILibrary</a>
</li>
......
......@@ -101,6 +101,9 @@
</li>
</ul>
<ul class="nav nav-pills">
<li>
<a href="architecture-examples/javascriptmvc/todo/todo/index.html" data-source="http://javascriptmvc.com/" data-content="JavaScriptMVC is an open-source framework containing the best ideas in jQuery development. It guides you to successfully completed projects by promoting best practices, maintainability, and convention over configuration.">JavaScriptMVC</a>
</li>
<li>
<a href="http://todomvc.meteor.com" data-source="http://meteor.com" data-content="Meteor is an ultra-simple environment for building modern websites.A Meteor application is a mix of JavaScript that runs inside a client web browser, JavaScript that runs on the Meteor server inside a Node.js container, and all the supporting HTML fragments, CSS rules, and static assets. Meteor automates the packaging and transmission of these different components. And, it is quite flexible about how you choose to structure those components in your file tree.">Meteor *</a>
</li>
......
......@@ -14,7 +14,6 @@ To help solve this problem, TodoMVC was created - a project which offers the sam
- [Backbone.js](http://documentcloud.github.com/backbone)
- [Ember.js](http://emberjs.com)
- [JavaScriptMVC](http://javascriptmvc.com)
- [Spine.js](http://spinejs.com)
- [KnockoutJS](http://knockoutjs.com) (MVVM)
- [Knockback.js](http://kmalakoff.github.com/knockback)
......@@ -44,6 +43,7 @@ We also have a number of in-progress applications in our [Labs](http://addyosman
- [Maria.js](https://github.com/petermichaux/maria)
- [Batman.js](http://batmanjs.org)
- [Meteor](http://meteor.com)
- [JavaScriptMVC](http://javascriptmvc.com)
- [Google Web Toolkit](https://developers.google.com/web-toolkit/)
- [Stapes.js](http://hay.github.com/stapes)
- [TroopJS](https://github.com/troopjs)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment