Updated build to packer3
This commit is contained in:
parent
5fae496933
commit
0539495e86
5 changed files with 1255 additions and 3 deletions
205
build/js/Packer.js
Normal file
205
build/js/Packer.js
Normal file
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
Packer version 3.0 (beta 5) - copyright 2004-2007, Dean Edwards
|
||||
http://www.opensource.org/licenses/mit-license
|
||||
*/
|
||||
|
||||
eval(base2.namespace);
|
||||
|
||||
var IGNORE = RegGrp.IGNORE;
|
||||
var REMOVE = "";
|
||||
var SPACE = " ";
|
||||
var WORDS = /\w+/g;
|
||||
|
||||
var Packer = Base.extend({
|
||||
minify: function(script) {
|
||||
script = script.replace(Packer.CONTINUE, "");
|
||||
script = Packer.clean.exec(script);
|
||||
script = Packer.whitespace.exec(script);
|
||||
script = Packer.clean.exec(script); // seem to grab a few more bytes on the second pass
|
||||
return script;
|
||||
},
|
||||
|
||||
pack: function(script, base62, shrink) {
|
||||
script = this.minify(script);
|
||||
if (shrink) script = this._shrinkVariables(script);
|
||||
if (base62) script = this._base62Encode(script);
|
||||
return script;
|
||||
},
|
||||
|
||||
_base62Encode: function(script) {
|
||||
var words = new Words(script);
|
||||
var encode = function(word) {
|
||||
return words.fetch(word).encoded;
|
||||
};
|
||||
|
||||
/* build the packed script */
|
||||
|
||||
var p = this._escape(script.replace(WORDS, encode));
|
||||
var a = Math.min(Math.max(words.count(), 2), 62);
|
||||
var c = words.count();
|
||||
var k = words;
|
||||
var e = Packer["ENCODE" + (a > 10 ? a > 36 ? 62 : 36 : 10)];
|
||||
var r = a > 10 ? "e(c)" : "c";
|
||||
|
||||
// the whole thing
|
||||
return format(Packer.UNPACK, p,a,c,k,e,r);
|
||||
},
|
||||
|
||||
_escape: function(script) {
|
||||
// single quotes wrap the final string so escape them
|
||||
// also escape new lines required by conditional comments
|
||||
return script.replace(/([\\'])/g, "\\$1").replace(/[\r\n]+/g, "\\n");
|
||||
},
|
||||
|
||||
_shrinkVariables: function(script) {
|
||||
// Windows Scripting Host cannot do regexp.test() on global regexps.
|
||||
var global = function(regexp) {
|
||||
// This function creates a global version of the passed regexp.
|
||||
return new RegExp(regexp.source, "g");
|
||||
};
|
||||
|
||||
var data = []; // encoded strings and regular expressions
|
||||
var store = function(string) {
|
||||
var replacement = "#" + data.length;
|
||||
data.push(string);
|
||||
return replacement;
|
||||
};
|
||||
|
||||
// Base52 encoding (a-Z)
|
||||
var encode52 = function(c) {
|
||||
return (c < 52 ? '' : arguments.callee(parseInt(c / 52))) +
|
||||
((c = c % 52) > 25 ? String.fromCharCode(c + 39) : String.fromCharCode(c + 97));
|
||||
};
|
||||
|
||||
// identify blocks, particularly identify function blocks (which define scope)
|
||||
var BLOCK = /(function\s*[\w$]*\s*\(\s*([^\)]*)\s*\)\s*)?(\{([^{}]*)\})/;
|
||||
var VAR_ = /var\s+/g;
|
||||
var VAR_NAME = /var\s+[\w$]{2,}/g; // > 1 char
|
||||
var COMMA = /\s*,\s*/;
|
||||
var blocks = []; // store program blocks (anything between braces {})
|
||||
// encoder for program blocks
|
||||
var encode = function(block, func, args) {
|
||||
if (func) { // the block is a function block
|
||||
|
||||
// decode the function block (THIS IS THE IMPORTANT BIT)
|
||||
// We are retrieving all sub-blocks and will re-parse them in light
|
||||
// of newly shrunk variables
|
||||
block = decode(block);
|
||||
|
||||
// create the list of variable and argument names
|
||||
var vars = match(block, VAR_NAME).join(",").replace(VAR_, "");
|
||||
var ids = Array2.combine(args.split(COMMA).concat(vars.split(COMMA)));
|
||||
|
||||
// process each identifier
|
||||
var count = 0, shortId;
|
||||
forEach (ids, function(id) {
|
||||
id = rescape(trim(id));
|
||||
if (id) {
|
||||
// find the next free short name (check everything in the current scope)
|
||||
do shortId = encode52(count++);
|
||||
while (new RegExp("[^\\w$.]" + shortId + "[^\\w$:]").test(block));
|
||||
// replace the long name with the short name
|
||||
var reg = new RegExp("([^\\w$.])" + id + "([^\\w$:])");
|
||||
while (reg.test(block)) block = block.replace(global(reg), "$1" + shortId + "$2");
|
||||
var reg = new RegExp("([^{,])" + id + ":", "g");
|
||||
block = block.replace(reg, "$1" + shortId + ":");
|
||||
}
|
||||
});
|
||||
}
|
||||
var replacement = "~" + blocks.length;
|
||||
blocks.push(block);
|
||||
return replacement;
|
||||
};
|
||||
|
||||
// decoder for program blocks
|
||||
var ENCODED = /~(\d+)/;
|
||||
var decode = function(script) {
|
||||
while (ENCODED.test(script)) {
|
||||
script = script.replace(global(ENCODED), function(match, index) {
|
||||
return blocks[index];
|
||||
});
|
||||
}
|
||||
return script;
|
||||
};
|
||||
|
||||
// encode strings and regular expressions
|
||||
script = Packer.data.exec(script, store);
|
||||
|
||||
// remove closures (this is for base2 namespaces only)
|
||||
script = script.replace(/new function\(_\)\s*\{/g, "{;#;");
|
||||
|
||||
// encode blocks, as we encode we replace variable and argument names
|
||||
while (BLOCK.test(script)) {
|
||||
script = script.replace(global(BLOCK), encode);
|
||||
}
|
||||
|
||||
// put the blocks back
|
||||
script = decode(script);
|
||||
|
||||
// put back the closure (for base2 namespaces only)
|
||||
script = script.replace(/\{;#;/g, "new function(_){");
|
||||
|
||||
// put strings and regular expressions back
|
||||
script = script.replace(/#(\d+)/g, function(match, index) {
|
||||
return data[index];
|
||||
});
|
||||
|
||||
return script;
|
||||
}
|
||||
}, {
|
||||
CONTINUE: /\\\r?\n/g,
|
||||
|
||||
ENCODE10: "String",
|
||||
ENCODE36: "function(c){return c.toString(a)}",
|
||||
ENCODE62: "function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))}",
|
||||
|
||||
UNPACK: "eval(function(p,a,c,k,e,r){e=%5;if(!''.replace(/^/,String)){while(c--)r[%6]=k[c]" +
|
||||
"||%6;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p." +
|
||||
"replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('%1',%2,%3,'%4'.split('|'),0,{}))",
|
||||
|
||||
init: function() {
|
||||
this.data = reduce(this.data, new RegGrp, function(data, replacement, expression) {
|
||||
data.store(this.javascript.exec(expression), replacement);
|
||||
return data;
|
||||
}, this);
|
||||
this.clean = this.data.union(this.clean);
|
||||
this.whitespace = this.data.union(this.whitespace);
|
||||
},
|
||||
|
||||
clean: {
|
||||
";;;[^\\n]*": REMOVE, // triple semi-colons treated like line comments
|
||||
"\\(\\s*;\\s*;\\s*\\)": "(;;)", // for (;;) loops
|
||||
"throw[^};]+[};]": IGNORE, // a safari 1.3 bug
|
||||
";+\\s*([};])": "$1"
|
||||
},
|
||||
|
||||
data: {
|
||||
// strings
|
||||
"STRING1": IGNORE,
|
||||
'STRING2': IGNORE,
|
||||
"CONDITIONAL": IGNORE, // conditional comments
|
||||
"(COMMENT1)\\n\\s*(REGEXP)?": "\n$2",
|
||||
"(COMMENT2)\\s*(REGEXP)?": " $3",
|
||||
"COMMENT1$": REMOVE,
|
||||
"([\\[(\\^=,{}:;&|!*?])\\s*(REGEXP)": "$1$2"
|
||||
},
|
||||
|
||||
javascript: new RegGrp({
|
||||
COMMENT1: /\/\/[^\n]*/.source,
|
||||
COMMENT2: /\/\*[^*]*\*+([^\/][^*]*\*+)*\//.source,
|
||||
CONDITIONAL: /\/\*@|@\*\/|\/\/@[^\n]*\n/.source,
|
||||
REGEXP: /\/(\\\/|[^*\/])(\\.|[^\/\n\\])*\//.source,
|
||||
STRING1: /'(\\.|[^'\\])*'/.source,
|
||||
STRING2: /"(\\.|[^"\\])*"/.source
|
||||
}),
|
||||
|
||||
whitespace: {
|
||||
"(\\d)\\s+(\\.\\s*[a-z\\$_\\[(])": "$1 $2", // http://dean.edwards.name/weblog/2007/04/packer3/#comment84066
|
||||
"([+-])\\s+([+-])": "$1 $2", // c = a++ +b;
|
||||
"\\b\\s+\\$\\s+\\b": " $ ", // var $ in
|
||||
"\\$\\s+\\b": "$ ", // object$ in
|
||||
"\\b\\s+\\$": " $", // return $object
|
||||
"\\b\\s+\\b": SPACE,
|
||||
"\\s+": REMOVE
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue