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
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 ) {
/**
* 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 @@ ...@@ -53,9 +53,6 @@
<li> <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> <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>
<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> <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> <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> </li>
...@@ -65,11 +62,11 @@ ...@@ -65,11 +62,11 @@
<li> <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> <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> </li>
</ul>
<ul class="nav nav-pills">
<li> <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> <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> </li>
</ul>
<ul class="nav nav-pills">
<li> <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> <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> </li>
......
This diff is collapsed.
This diff is collapsed.
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