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