Deploy release build.xml

This commit is contained in:
Eduardo Lundgren 2008-06-07 20:02:49 +00:00
parent 9383692025
commit e2d2ed1eb0
16 changed files with 2495 additions and 0 deletions

144
release/build.xml Normal file
View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
jQuery UI Release!
Call task called 'deploy-release' to build a full release.
The release built will be stored on 'dist' dir.
@author Eduardo Lundgren (eduardo.lundgren@gmail.com)
-->
<project name="jquery-ui" default="deploy-release" basedir=".">
<target name="deploy-release" depends="load.properties, concatenate, minify, pack, copy" description="Release builder">
</target>
<target name="load.properties">
<property file="ant.properties" />
<property name="dist.dir" value="dist" />
<property name="build.dir" value="build" />
<property name="ui.dir" value="../" />
<property name="src.dir" value="${ui.dir}/ui/" />
<property name="min.folder" value="${dist.dir}/ui/minified" />
<property name="packed.folder" value="${dist.dir}/ui/packed" />
<property name="concatenated" value="jquery-ui-all" />
<property name="core.files" value="ui.core.js, ui.draggable.js, ui.droppable.js, ui.resizable.js, ui.selectable.js, ui.sortable.js, effects.core.js" />
<property description="YUI Compressor" name="yui-jar" value="${build.dir}/yuicompressor.jar" />
<property description="Rhino JS Engine" name="jar" value="${build.dir}/js.jar" />
</target>
<target name="concatenate" depends="load.properties">
<echo message="Building concatenated" />
<mkdir dir="${dist.dir}/ui/" />
<delete file="${dist.dir}/ui/${concatenated}.js" />
<concat destfile="${dist.dir}/ui/${concatenated}.js">
<filelist dir="${src.dir}/" files="${core.files}" />
<fileset dir="${src.dir}/" includes="ui.*.js, effects.*.js" excludes="${core.files}" />
</concat>
<echo message="Concatenated built." />
</target>
<target name="minify" depends="load.properties, concatenate" description="Remove all comments and whitespace, no compression, great in combination with GZip">
<echo message="Building minified" />
<delete dir="${min.folder}/" />
<mkdir dir="${min.folder}" />
<apply executable="java" parallel="false">
<filelist dir="${dist.dir}/ui/" files="${concatenated}.js" />
<fileset dir="${src.dir}/" includes="ui.*.js, effects.*.js" />
<arg line="-jar" />
<arg path="${yui-jar}" />
<srcfile />
<arg line="-o" />
<mapper type="glob" from="*.js" to="${min.folder}/*.min.js" />
<targetfile />
</apply>
<echo message="Minified built." />
</target>
<target name="pack" depends="load.properties, concatenate, minify" description="Remove all comments and whitespace and compress">
<!--
http://dean.edwards.name/download/#packer
http://homepages.nildram.co.uk/~9jack9/download/packer.wsh.zip
-->
<echo message="Building packed" />
<delete dir="${packed.folder}/" />
<mkdir dir="${packed.folder}" />
<apply executable="cmd" parallel="false">
<filelist dir="${min.folder}" files="${concatenated}.min.js" />
<fileset dir="${min.folder}" includes="ui.*.min.js, effects.*.min.js" />
<arg line="/c CScript /nologo ${build.dir}/js/pack.wsf" />
<srcfile />
<arg line=">>" />
<mapper type="glob" from="*.min.js" to="${packed.folder}/*.packed.js" />
<targetfile />
</apply>
<echo message="Packed built." />
</target>
<!--
TODO - Using Rhino Javascript Engine
<target name="pack" depends="load.properties, concatenate" description="Remove all comments and whitespace and compress">
<echo message="Building packed" />
<delete dir="${packed.folder}/" />
<mkdir dir="${packed.folder}" />
<apply executable="java" parallel="false">
<filelist dir="${min.folder}" files="${concatenated}.min.js" />
<fileset dir="${min.folder}" includes="ui.*.min.js, effects.*.min.js" />
<arg line="-jar" />
<arg path="${jar}" />
<arg value="${build.dir}/build/pack.js" />
<srcfile />
<mapper type="glob" from="*.min.js" to="${packed.folder}/*.packed.js" />
<targetfile />
</apply>
<echo message="Packed built." />
</target>
-->
<target description="Copy needed folders" name="copy" depends="load.properties">
<echo message="Copying files" />
<mkdir dir="${dist.dir}" />
<copy overwrite="true" todir="${dist.dir}/ui/">
<fileset dir="${src.dir}/" includes="ui.*.js, effects.*.js" />
</copy>
<copy overwrite="true" todir="${dist.dir}/ui/i18n/" >
<fileset dir="${src.dir}/i18n/" />
</copy>
<copy overwrite="true" todir="${dist.dir}/">
<fileset dir="${ui.dir}/" includes="*.txt" />
</copy>
<copy overwrite="true" todir="${dist.dir}/demos/" >
<fileset dir="${ui.dir}/demos/" />
</copy>
<copy overwrite="true" todir="${dist.dir}/tests/" >
<fileset dir="${ui.dir}/tests/" />
</copy>
<copy overwrite="true" todir="${dist.dir}/themes/" >
<fileset dir="${ui.dir}/themes/" />
</copy>
<echo message="Files copied." />
</target>
<target depends="load.properties" name="clean">
<delete dir="${dist.dir}" />
</target>
</project>

View File

@ -0,0 +1,11 @@
load("build/js/jsmin.js", "build/js/writeFile.js");
// arguments
var inFile = arguments[0];
var outFile = arguments[1] || inFile.replace(/\.js$/, ".min.js");
var script = readFile(inFile);
var header = script.match(/\/\*(.|\n)*?\*\//)[0];
var minifiedScript = jsmin('', script, 3);
writeFile( outFile, header + minifiedScript );

View File

@ -0,0 +1,19 @@
load("build/js/writeFile.js");
load("build/js/base2.js");
load("build/js/Packer.js");
load("build/js/Words.js");
// arguments
var inFile = arguments[0];
var outFile = arguments[1] || inFile.replace(/\.js$/, ".pack.js");
// options
var base62 = true;
var shrink = true;
var script = readFile(inFile);
var header = script.match(/\/\*(.|\n)*?\*\//)[0];
var packer = new Packer;
var packedScript = packer.pack(script, base62, shrink);
writeFile(outFile, header + "\n" + packedScript);

BIN
release/build/js.jar Normal file

Binary file not shown.

209
release/build/js/Packer.js Normal file
View File

@ -0,0 +1,209 @@
/*
Packer version 3.0 (beta 8) - 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.data.exec(script);
script = Packer.whitespace.exec(script);
script = Packer.clean.exec(script);
return script;
},
pack: function(script, base62, shrink) {
script = this.minify(script + "\n");
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 REGEXP = /^[^'"]\//;
var store = function(string) {
var replacement = "#" + data.length;
if (REGEXP.test(string)) {
replacement = string.charAt(0) + replacement;
string = string.slice(1);
}
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$]+/g;
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 = trim(id);
if (id && id.length > 1) { // > 1 char
id = rescape(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, function(data, replacement, expression) {
data.store(this.javascript.exec(expression), replacement);
return data;
}, new RegGrp, this);
this.clean = this.data.union(this.clean);
this.whitespace = this.data.union(this.whitespace);
},
clean: {
"\\(\\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$3",
"(COMMENT2)\\s*(REGEXP)?": " $3",
"([\\[(\\^=,{}:;&|!*?])\\s*(REGEXP)": "$1$2"
},
javascript: new RegGrp({
COMMENT1: /(\/\/|;;;)[^\n]*/.source,
COMMENT2: /\/\*[^*]*\*+([^\/][^*]*\*+)*\//.source,
CONDITIONAL: /\/\*@|@\*\/|\/\/@[^\n]*\n/.source,
REGEXP: /\/(\\[\/\\]|[^*\/])(\\.|[^\/\n\\])*\/[gim]*/.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
}
});

View File

@ -0,0 +1,106 @@
/*
ParseMaster, version 1.0.2 (2005-08-19)
Copyright 2005, Dean Edwards
License: http://creativecommons.org/licenses/LGPL/2.1/
*/
/* a multi-pattern parser */
// KNOWN BUG: erroneous behavior when using escapeChar with a replacement value that is a function
function ParseMaster() {
// constants
var $EXPRESSION = 0, $REPLACEMENT = 1, $LENGTH = 2;
// used to determine nesting levels
var $GROUPS = /\(/g, $SUB_REPLACE = /\$\d/, $INDEXED = /^\$\d+$/,
$TRIM = /(['"])\1\+(.*)\+\1\1$/, $$ESCAPE = /\\./g, $QUOTE = /'/,
$$DELETED = /\x01[^\x01]*\x01/g;
var self = this;
// public
this.add = function($expression, $replacement) {
if (!$replacement) $replacement = "";
// count the number of sub-expressions
// - add one because each pattern is itself a sub-expression
var $length = (_internalEscape(String($expression)).match($GROUPS) || "").length + 1;
// does the pattern deal with sub-expressions?
if ($SUB_REPLACE.test($replacement)) {
// a simple lookup? (e.g. "$2")
if ($INDEXED.test($replacement)) {
// store the index (used for fast retrieval of matched strings)
$replacement = parseInt($replacement.slice(1)) - 1;
} else { // a complicated lookup (e.g. "Hello $2 $1")
// build a function to do the lookup
var i = $length;
var $quote = $QUOTE.test(_internalEscape($replacement)) ? '"' : "'";
while (i) $replacement = $replacement.split("$" + i--).join($quote + "+a[o+" + i + "]+" + $quote);
$replacement = new Function("a,o", "return" + $quote + $replacement.replace($TRIM, "$1") + $quote);
}
}
// pass the modified arguments
_add($expression || "/^$/", $replacement, $length);
};
// execute the global replacement
this.exec = function($string) {
_escaped.length = 0;
return _unescape(_escape($string, this.escapeChar).replace(
new RegExp(_patterns, this.ignoreCase ? "gi" : "g"), _replacement), this.escapeChar).replace($$DELETED, "");
};
// clear the patterns collection so that this object may be re-used
this.reset = function() {
_patterns.length = 0;
};
// private
var _escaped = []; // escaped characters
var _patterns = []; // patterns stored by index
var _toString = function(){return "(" + String(this[$EXPRESSION]).slice(1, -1) + ")"};
_patterns.toString = function(){return this.join("|")};
// create and add a new pattern to the patterns collection
function _add() {
arguments.toString = _toString;
// store the pattern - as an arguments object (i think this is quicker..?)
_patterns[_patterns.length] = arguments;
}
// this is the global replace function (it's quite complicated)
function _replacement() {
if (!arguments[0]) return "";
var i = 1, j = 0, $pattern;
// loop through the patterns
while ($pattern = _patterns[j++]) {
// do we have a result?
if (arguments[i]) {
var $replacement = $pattern[$REPLACEMENT];
switch (typeof $replacement) {
case "function": return $replacement(arguments, i);
case "number": return arguments[$replacement + i];
}
var $delete = (arguments[i].indexOf(self.escapeChar) == -1) ? "" :
"\x01" + arguments[i] + "\x01";
return $delete + $replacement;
// skip over references to sub-expressions
} else i += $pattern[$LENGTH];
}
};
// encode escaped characters
function _escape($string, $escapeChar) {
return $escapeChar ? $string.replace(new RegExp("\\" + $escapeChar + "(.)", "g"), function($match, $char) {
_escaped[_escaped.length] = $char;
return $escapeChar;
}) : $string;
};
// decode escaped characters
function _unescape($string, $escapeChar) {
var i = 0;
return $escapeChar ? $string.replace(new RegExp("\\" + $escapeChar, "g"), function() {
return $escapeChar + (_escaped[i++] || "");
}) : $string;
};
function _internalEscape($string) {
return $string.replace($$ESCAPE, "");
};
};
ParseMaster.prototype = {
constructor: ParseMaster,
ignoreCase: false,
escapeChar: ""
};

62
release/build/js/Words.js Normal file
View File

@ -0,0 +1,62 @@
var Words = Collection.extend({
constructor: function(script) {
this.base();
forEach (script.match(WORDS), this.add, this);
this.encode();
},
add: function(word) {
if (!this.exists(word)) this.base(word);
word = this.fetch(word);
word.count++;
return word;
},
encode: function() {
// sort by frequency
this.sort(function(word1, word2) {
return word2.count - word1.count;
});
eval("var a=62,e=" + Packer.ENCODE62);
var encode = e;
var encoded = new Collection; // a dictionary of base62 -> base10
var count = this.count();
for (var i = 0; i < count; i++) {
encoded.store(encode(i), i);
}
var empty = function() {return ""};
var index = 0;
forEach (this, function(word) {
if (encoded.exists(word)) {
word.index = encoded.fetch(word);
word.toString = empty;
} else {
while (this.exists(encode(index))) index++;
word.index = index++;
}
word.encoded = encode(word.index);
}, this);
// sort by encoding
this.sort(function(word1, word2) {
return word1.index - word2.index;
});
},
toString: function() {
return this.values().join("|");
}
}, {
Item: {
constructor: function(word) {
this.toString = function() {return word};
},
count: 0,
encoded: "",
index: -1
}
});

978
release/build/js/base2.js Normal file
View File

@ -0,0 +1,978 @@
// timestamp: Tue, 01 May 2007 19:13:00
/*
base2.js - copyright 2007, Dean Edwards
http://www.opensource.org/licenses/mit-license
*/
var base2 = {};
// You know, writing a javascript library is awfully time consuming.
new function(_) { //////////////////// BEGIN: CLOSURE ////////////////////
// =========================================================================
// base2/Base.js
// =========================================================================
// version 1.1
var Base = function() {
// call this method from any other method to invoke that method's ancestor
};
Base.prototype = {
extend: function(source) {
if (arguments.length > 1) { // extending with a name/value pair
var ancestor = this[source];
var value = arguments[1];
if (typeof value == "function" && ancestor && /\bbase\b/.test(value)) {
var method = value;
value = function() { // override
var previous = this.base;
this.base = ancestor;
var returnValue = method.apply(this, arguments);
this.base = previous;
return returnValue;
};
value.method = method;
value.ancestor = ancestor;
}
this[source] = value;
} else if (source) { // extending with an object literal
var extend = Base.prototype.extend;
if (Base._prototyping) {
var key, i = 0, members = ["constructor", "toString", "valueOf"];
while (key = members[i++]) if (source[key] != Object.prototype[key]) {
extend.call(this, key, source[key]);
}
} else if (typeof this != "function") {
// if the object has a customised extend() method then use it
extend = this.extend || extend;
}
// copy each of the source object's properties to this object
for (key in source) if (!Object.prototype[key]) {
extend.call(this, key, source[key]);
}
}
return this;
},
base: Base
};
Base.extend = function(_instance, _static) { // subclass
var extend = Base.prototype.extend;
// build the prototype
Base._prototyping = true;
var proto = new this;
extend.call(proto, _instance);
delete Base._prototyping;
// create the wrapper for the constructor function
var constructor = proto.constructor;
var klass = proto.constructor = function() {
if (!Base._prototyping) {
if (this._constructing || this.constructor == klass) { // instantiation
this._constructing = true;
constructor.apply(this, arguments);
delete this._constructing;
} else { // casting
var object = arguments[0];
if (object != null) {
(object.extend || extend).call(object, proto);
}
return object;
}
}
};
// build the class interface
for (var i in Base) klass[i] = this[i];
klass.ancestor = this;
klass.base = Base.base;
klass.prototype = proto;
klass.toString = this.toString;
extend.call(klass, _static);
// class initialisation
if (typeof klass.init == "function") klass.init();
return klass;
};
// initialise
Base = Base.extend({
constructor: function() {
this.extend(arguments[0]);
}
}, {
ancestor: Object,
base: Base,
implement: function(_interface) {
if (typeof _interface == "function") {
// if it's a function, call it
_interface(this.prototype);
} else {
// add the interface using the extend() method
this.prototype.extend(_interface);
}
return this;
}
});
// =========================================================================
// lang/main.js
// =========================================================================
var Legacy = typeof $Legacy == "undefined" ? {} : $Legacy;
var K = function(k) {return k};
var assert = function(condition, message, Err) {
if (!condition) {
throw new (Err || Error)(message || "Assertion failed.");
}
};
var assertType = function(object, type, message) {
if (type) {
var condition = typeof type == "function" ? instanceOf(object, type) : typeof object == type;
assert(condition, message || "Invalid type.", TypeError);
}
};
var copy = function(object) {
var fn = new Function;
fn.prototype = object;
return new fn;
};
var format = function(string) {
// replace %n with arguments[n]
// e.g. format("%1 %2%3 %2a %1%3", "she", "se", "lls");
// ==> "she sells sea shells"
// only supports nine replacements: %1 - %9
var args = arguments;
return String(string).replace(/%([1-9])/g, function(match, index) {
return index < args.length ? args[index] : match;
});
};
var $instanceOf = Legacy.instanceOf || new Function("o,k", "return o instanceof k");
var instanceOf = function(object, klass) {
assertType(klass, "function", "Invalid 'instanceOf' operand.");
if ($instanceOf(object, klass)) return true;
// handle exceptions where the target object originates from another frame
// this is handy for JSON parsing (amongst other things)
if (object != null) switch (klass) {
case Object:
return true;
case Number:
case Boolean:
case Function:
case String:
return typeof object == typeof klass.prototype.valueOf();
case Array:
// this is the only troublesome one
return !!(object.join && object.splice && !arguments.callee(object, Function));
case Date:
return !!object.getTimezoneOffset;
case RegExp:
return String(object.constructor.prototype) == String(new RegExp);
}
return false;
};
var match = function(string, expression) {
// same as String.match() except that this function will return an empty
// array if there is no match
return String(string).match(expression) || [];
};
var RESCAPE = /([\/()[\]{}|*+-.,^$?\\])/g;
var rescape = function(string) {
// make a string safe for creating a RegExp
return String(string).replace(RESCAPE, "\\$1");
};
var $slice = Array.prototype.slice;
var slice = function(object) {
// slice an array-like object
return $slice.apply(object, $slice.call(arguments, 1));
};
var TRIM = /^\s+|\s+$/g;
var trim = function(string) {
return String(string).replace(TRIM, "");
};
// =========================================================================
// lang/extend.js
// =========================================================================
var base = function(object, args) {
// invoke the base method with all supplied arguments
return object.base.apply(object, args);
};
var extend = function(object) {
assert(object != Object.prototype, "Object.prototype is verboten!");
return Base.prototype.extend.apply(object, slice(arguments, 1));
};
// =========================================================================
// lang/assignID.js
// =========================================================================
var $ID = 1;
var assignID = function(object) {
// assign a unique id
if (!object.base2ID) object.base2ID = "b2_" + $ID++;
return object.base2ID;
};
// =========================================================================
// lang/forEach.js
// =========================================================================
if (typeof StopIteration == "undefined") {
StopIteration = new Error("StopIteration");
}
var forEach = function(object, block, context) {
if (object == null) return;
if (typeof object == "function") {
// functions are a special case
var fn = Function;
} else if (typeof object.forEach == "function" && object.forEach != arguments.callee) {
// the object implements a custom forEach method
object.forEach(block, context);
return;
} else if (typeof object.length == "number") {
// the object is array-like
forEach.Array(object, block, context);
return;
}
forEach.Function(fn || Object, object, block, context);
};
// these are the two core enumeration methods. all other forEach methods
// eventually call one of these two.
forEach.Array = function(array, block, context) {
var i, length = array.length; // preserve
if (typeof array == "string") {
for (i = 0; i < length; i++) {
block.call(context, array.charAt(i), i, array);
}
} else {
for (i = 0; i < length; i++) {
block.call(context, array[i], i, array);
}
}
};
forEach.Function = Legacy.forEach || function(fn, object, block, context) {
// enumerate an object and compare its keys with fn's prototype
for (var key in object) {
if (fn.prototype[key] === undefined) {
block.call(context, object[key], key, object);
}
}
};
// =========================================================================
// base2/Base/forEach.js
// =========================================================================
Base.forEach = function(object, block, context) {
forEach.Function(this, object, block, context);
};
// =========================================================================
// base2/../Function.js
// =========================================================================
// some browsers don't define this
Function.prototype.prototype = {};
// =========================================================================
// base2/../String.js
// =========================================================================
// fix String.replace (Safari/IE5.0)
if ("".replace(/^/, String)) {
extend(String.prototype, "replace", function(expression, replacement) {
if (typeof replacement == "function") { // Safari doesn't like functions
if (instanceOf(expression, RegExp)) {
var regexp = expression;
var global = regexp.global;
if (global == null) global = /(g|gi)$/.test(regexp);
// we have to convert global RexpExps for exec() to work consistently
if (global) regexp = new RegExp(regexp.source); // non-global
} else {
regexp = new RegExp(rescape(expression));
}
var match, string = this, result = "";
while (string && (match = regexp.exec(string))) {
result += string.slice(0, match.index) + replacement.apply(this, match);
string = string.slice(match.index + match[0].length);
if (!global) break;
}
return result + string;
} else {
return base(this, arguments);
}
});
}
// =========================================================================
// base2/Abstract.js
// =========================================================================
var Abstract = Base.extend({
constructor: function() {
throw new TypeError("Class cannot be instantiated.");
}
});
// =========================================================================
// base2/Module.js
// =========================================================================
// based on ruby's Module class and Mozilla's Array generics:
// http://www.ruby-doc.org/core/classes/Module.html
// http://developer.mozilla.org/en/docs/New_in_JavaScript_1.6#Array_and_String_generics
// A Module is used as the basis for creating interfaces that can be
// applied to other classes. *All* properties and methods are static.
// When a module is used as a mixin, methods defined on what would normally be
// the instance interface become instance methods of the target object.
// Modules cannot be instantiated. Static properties and methods are inherited.
var Module = Abstract.extend(null, {
extend: function(_interface, _static) {
// extend a module to create a new module
var module = this.base();
// inherit static methods
forEach (this, function(property, name) {
if (!Module[name] && name != "init") {
extend(module, name, property);
}
});
// implement module (instance AND static) methods
module.implement(_interface);
// implement static properties and methods
extend(module, _static);
// Make the submarine noises Larry!
if (typeof module.init == "function") module.init();
return module;
},
implement: function(_interface) {
// implement an interface on BOTH the instance and static interfaces
var module = this;
if (typeof _interface == "function") {
module.base(_interface);
forEach (_interface, function(property, name) {
if (!Module[name] && name != "init") {
extend(module, name, property);
}
});
} else {
// create the instance interface
Base.forEach (extend({}, _interface), function(property, name) {
// instance methods call the equivalent static method
if (typeof property == "function") {
property = function() {
base; // force inheritance
return module[name].apply(module, [this].concat(slice(arguments)));
};
}
if (!Module[name]) extend(this, name, property);
}, module.prototype);
// add the static interface
extend(module, _interface);
}
return module;
}
});
// =========================================================================
// base2/Enumerable.js
// =========================================================================
var Enumerable = Module.extend({
every: function(object, test, context) {
var result = true;
try {
this.forEach (object, function(value, key) {
result = test.call(context, value, key, object);
if (!result) throw StopIteration;
});
} catch (error) {
if (error != StopIteration) throw error;
}
return !!result; // cast to boolean
},
filter: function(object, test, context) {
return this.reduce(object, function(result, value, key) {
if (test.call(context, value, key, object)) {
result[result.length] = value;
}
return result;
}, new Array2);
},
invoke: function(object, method) {
// apply a method to each item in the enumerated object
var args = slice(arguments, 2);
return this.map(object, (typeof method == "function") ? function(item) {
if (item != null) return method.apply(item, args);
} : function(item) {
if (item != null) return item[method].apply(item, args);
});
},
map: function(object, block, context) {
var result = new Array2;
this.forEach (object, function(value, key) {
result[result.length] = block.call(context, value, key, object);
});
return result;
},
pluck: function(object, key) {
return this.map(object, function(item) {
if (item != null) return item[key];
});
},
reduce: function(object, block, result, context) {
this.forEach (object, function(value, key) {
result = block.call(context, result, value, key, object);
});
return result;
},
some: function(object, test, context) {
return !this.every(object, function(value, key) {
return !test.call(context, value, key, object);
});
}
}, {
forEach: forEach
});
// =========================================================================
// base2/Array2.js
// =========================================================================
// The IArray module implements all Array methods.
// This module is not public but its methods are accessible through the Array2 object (below).
var IArray = Module.extend({
combine: function(keys, values) {
// combine two arrays to make a hash
if (!values) values = keys;
return this.reduce(keys, function(object, key, index) {
object[key] = values[index];
return object;
}, {});
},
copy: function(array) {
return this.concat(array);
},
contains: function(array, item) {
return this.indexOf(array, item) != -1;
},
forEach: forEach.Array,
indexOf: function(array, item, fromIndex) {
var length = array.length;
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, length + fromIndex);
}
for (var i = fromIndex; i < length; i++) {
if (array[i] === item) return i;
}
return -1;
},
insertAt: function(array, item, index) {
this.splice(array, index, 0, item);
return item;
},
insertBefore: function(array, item, before) {
var index = this.indexOf(array, before);
if (index == -1) this.push(array, item);
else this.splice(array, index, 0, item);
return item;
},
lastIndexOf: function(array, item, fromIndex) {
var length = array.length;
if (fromIndex == null) {
fromIndex = length - 1;
} else if (from < 0) {
fromIndex = Math.max(0, length + fromIndex);
}
for (var i = fromIndex; i >= 0; i--) {
if (array[i] === item) return i;
}
return -1;
},
remove: function(array, item) {
var index = this.indexOf(array, item);
if (index != -1) this.removeAt(array, index);
return item;
},
removeAt: function(array, index) {
var item = array[index];
this.splice(array, index, 1);
return item;
}
});
IArray.prototype.forEach = function(block, context) {
forEach.Array(this, block, context);
};
IArray.implement(Enumerable);
forEach ("concat,join,pop,push,reverse,shift,slice,sort,splice,unshift".split(","), function(name) {
IArray[name] = function(array) {
return Array.prototype[name].apply(array, slice(arguments, 1));
};
});
// create a faux constructor that augments the built-in Array object
var Array2 = function() {
return IArray(this.constructor == IArray ? Array.apply(null, arguments) : arguments[0]);
};
// expose IArray.prototype so that it can be extended
Array2.prototype = IArray.prototype;
forEach (IArray, function(method, name, proto) {
if (Array[name]) {
IArray[name] = Array[name];
delete IArray.prototype[name];
}
Array2[name] = IArray[name];
});
// =========================================================================
// base2/Hash.js
// =========================================================================
var HASH = "#" + Number(new Date);
var KEYS = HASH + "keys";
var VALUES = HASH + "values";
var Hash = Base.extend({
constructor: function(values) {
this[KEYS] = new Array2;
this[VALUES] = {};
this.merge(values);
},
copy: function() {
var copy = new this.constructor(this);
Base.forEach (this, function(property, name) {
if (typeof property != "function" && name.charAt(0) != "#") {
copy[name] = property;
}
});
return copy;
},
// ancient browsers throw an error when we use "in" as an operator
// so we must create the function dynamically
exists: Legacy.exists || new Function("k", format("return('%1'+k)in this['%2']", HASH, VALUES)),
fetch: function(key) {
return this[VALUES][HASH + key];
},
forEach: function(block, context) {
forEach (this[KEYS], function(key) {
block.call(context, this.fetch(key), key, this);
}, this);
},
keys: function(index, length) {
var keys = this[KEYS] || new Array2;
switch (arguments.length) {
case 0: return keys.copy();
case 1: return keys[index];
default: return keys.slice(index, length);
}
},
merge: function(values) {
forEach (arguments, function(values) {
forEach (values, function(value, key) {
this.store(key, value);
}, this);
}, this);
return this;
},
remove: function(key) {
var value = this.fetch(key);
this[KEYS].remove(String(key));
delete this[VALUES][HASH + key];
return value;
},
store: function(key, value) {
if (arguments.length == 1) value = key;
// only store the key for a new entry
if (!this.exists(key)) {
this[KEYS].push(String(key));
}
// create the new entry (or overwrite the old entry)
this[VALUES][HASH + key] = value;
return value;
},
toString: function() {
return String(this[KEYS]);
},
union: function(values) {
return this.merge.apply(this.copy(), arguments);
},
values: function(index, length) {
var values = this.map(K);
switch (arguments.length) {
case 0: return values;
case 1: return values[index];
default: return values.slice(index, length);
}
}
});
Hash.implement(Enumerable);
// =========================================================================
// base2/Collection.js
// =========================================================================
// A Hash that is more array-like (accessible by index).
// Collection classes have a special (optional) property: Item
// The Item property points to a constructor function.
// Members of the collection must be an instance of Item.
// e.g.
// var Dates = Collection.extend(); // create a collection class
// Dates.Item = Date; // only JavaScript Date objects allowed as members
// var appointments = new Dates(); // instantiate the class
// appointments.add(appointmentId, new Date); // add a date
// appointments.add(appointmentId, "tomorrow"); // ERROR!
// The static create() method is responsible for all construction of collection items.
// Instance methods that add new items (add, store, insertAt, replaceAt) pass *all* of their arguments
// to the static create() method. If you want to modify the way collection items are
// created then you only need to override this method for custom collections.
var Collection = Hash.extend({
add: function(key, item) {
// Duplicates not allowed using add().
// - but you can still overwrite entries using store()
assert(!this.exists(key), "Duplicate key.");
return this.store.apply(this, arguments);
},
count: function() {
return this[KEYS].length;
},
indexOf: function(key) {
return this[KEYS].indexOf(String(key));
},
insertAt: function(index, key, item) {
assert(!this.exists(key), "Duplicate key.");
this[KEYS].insertAt(index, String(key));
return this.store.apply(this, slice(arguments, 1));
},
item: function(index) {
return this.fetch(this[KEYS][index]);
},
removeAt: function(index) {
return this.remove(this[KEYS][index]);
},
reverse: function() {
this[KEYS].reverse();
return this;
},
sort: function(compare) {
if (compare) {
var self = this;
this[KEYS].sort(function(key1, key2) {
return compare(self.fetch(key1), self.fetch(key2), key1, key2);
});
} else this[KEYS].sort();
return this;
},
store: function(key, item) {
if (arguments.length == 1) item = key;
item = this.constructor.create.apply(this.constructor, arguments);
return this.base(key, item);
},
storeAt: function(index, item) {
//-dean: get rid of this?
assert(index < this.count(), "Index out of bounds.");
arguments[0] = this[KEYS][index];
return this.store.apply(this, arguments);
}
}, {
Item: null, // if specified, all members of the Collection must be instances of Item
create: function(key, item) {
if (this.Item && !instanceOf(item, this.Item)) {
item = new this.Item(key, item);
}
return item;
},
extend: function(_instance, _static) {
var klass = this.base(_instance);
klass.create = this.create;
extend(klass, _static);
if (!klass.Item) {
klass.Item = this.Item;
} else if (typeof klass.Item != "function") {
klass.Item = (this.Item || Base).extend(klass.Item);
}
if (typeof klass.init == "function") klass.init();
return klass;
}
});
// =========================================================================
// base2/RegGrp.js
// =========================================================================
var RegGrp = Collection.extend({
constructor: function(values, flags) {
this.base(values);
if (typeof flags == "string") {
this.global = /g/.test(flags);
this.ignoreCase = /i/.test(flags);
}
},
global: true, // global is the default setting
ignoreCase: false,
exec: function(string, replacement) {
if (arguments.length == 1) {
var keys = this[KEYS];
var values = this[VALUES];
replacement = function(match) {
if (!match) return "";
var offset = 1, i = 0;
// loop through the values
while (match = values[HASH + keys[i++]]) {
// do we have a result?
if (arguments[offset]) {
var replacement = match.replacement;
switch (typeof replacement) {
case "function":
return replacement.apply(null, slice(arguments, offset));
case "number":
return arguments[offset + replacement];
default:
return replacement;
}
// no? then skip over references to sub-expressions
} else offset += match.length + 1;
}
};
}
var flags = (this.global ? "g" : "") + (this.ignoreCase ? "i" : "");
return String(string).replace(new RegExp(this, flags), replacement);
},
test: function(string) {
return this.exec(string) != string;
},
toString: function() {
var length = 0;
return "(" + this.map(function(item) {
// fix back references
var expression = String(item).replace(/\\(\d+)/g, function($, index) {
return "\\" + (1 + Number(index) + length);
});
length += item.length + 1;
return expression;
}).join(")|(") + ")";
}
}, {
IGNORE: "$0",
init: function() {
forEach ("add,exists,fetch,remove,store".split(","), function(name) {
extend(this, name, function(expression) {
if (instanceOf(expression, RegExp)) {
expression = expression.source;
}
return base(this, arguments);
});
}, this.prototype);
}
});
// =========================================================================
// base2/RegGrp/Item.js
// =========================================================================
RegGrp.Item = Base.extend({
constructor: function(expression, replacement) {
var ESCAPE = /\\./g;
var STRING = /(['"])\1\+(.*)\+\1\1$/;
expression = instanceOf(expression, RegExp) ? expression.source : String(expression);
if (typeof replacement == "number") replacement = String(replacement);
else if (replacement == null) replacement = "";
// count the number of sub-expressions
// - add one because each pattern is itself a sub-expression
this.length = match(expression.replace(ESCAPE, "").replace(/\[[^\]]+\]/g, ""), /\(/g).length;
// does the pattern use sub-expressions?
if (typeof replacement == "string" && /\$(\d+)/.test(replacement)) {
// a simple lookup? (e.g. "$2")
if (/^\$\d+$/.test(replacement)) {
// store the index (used for fast retrieval of matched strings)
replacement = parseInt(replacement.slice(1));
} else { // a complicated lookup (e.g. "Hello $2 $1")
// build a function to do the lookup
var i = this.length + 1;
var Q = /'/.test(replacement.replace(ESCAPE, "")) ? '"' : "'";
replacement = replacement.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\$(\d+)/g, Q +
"+(arguments[$1]||" + Q+Q + ")+" + Q);
replacement = new Function("return " + Q + replacement.replace(STRING, "$1") + Q);
}
}
this.replacement = replacement;
this.toString = function() {
return expression || "";
};
},
length: 0,
replacement: ""
});
// =========================================================================
// base2/Namespace.js
// =========================================================================
var Namespace = Base.extend({
constructor: function(_private, _public) {
this.extend(_public);
this.toString = function() {
return format("[base2.%1]", this.name);
};
// initialise
if (typeof this.init == "function") this.init();
if (this.name != "base2") {
this.namespace = format("var %1=base2.%1;", this.name);
}
var namespace = "var base=" + base + ";";
var imports = ("base2,lang," + this.imports).split(",");
_private.imports = Enumerable.reduce(imports, function(namespace, name) {
if (base2[name]) namespace += base2[name].namespace;
return namespace;
}, namespace);
var namespace = format("base2.%1=%1;", this.name);
var exports = this.exports.split(",");
_private.exports = Enumerable.reduce(exports, function(namespace, name) {
if (name) {
this.namespace += format("var %2=%1.%2;", this.name, name);
namespace += format("if(!%1.%2)%1.%2=%2;base2.%2=%1.%2;", this.name, name);
}
return namespace;
}, namespace, this);
if (this.name != "base2") {
base2.namespace += format("var %1=base2.%1;", this.name);
}
},
exports: "",
imports: "",
namespace: "",
name: ""
});
base2 = new Namespace(this, {
name: "base2",
version: "0.8 (alpha)",
exports: "Base,Abstract,Module,Enumerable,Array2,Hash,Collection,RegGrp,Namespace"
});
base2.toString = function() {
return "[base2]";
};
eval(this.exports);
// =========================================================================
// base2/lang/namespace.js
// =========================================================================
var lang = new Namespace(this, {
name: "lang",
version: base2.version,
exports: "K,assert,assertType,assignID,copy,instanceOf,extend,format,forEach,match,rescape,slice,trim",
init: function() {
this.extend = extend;
// add the Enumerable methods to the lang object
forEach (Enumerable.prototype, function(method, name) {
if (!Module[name]) {
this[name] = function() {
return Enumerable[name].apply(Enumerable, arguments);
};
this.exports += "," + name;
}
}, this);
}
});
eval(this.exports);
base2.namespace += lang.namespace;
}; //////////////////// END: CLOSURE /////////////////////////////////////

316
release/build/js/jsmin.js Normal file
View File

@ -0,0 +1,316 @@
/* jsmin.js - 2006-08-31
Author: Franck Marcia
This work is an adaptation of jsminc.c published by Douglas Crockford.
Permission is hereby granted to use the Javascript version under the same
conditions as the jsmin.c on which it is based.
jsmin.c
2006-05-04
Copyright (c) 2002 Douglas Crockford (www.crockford.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Update:
add level:
1: minimal, keep linefeeds if single
2: normal, the standard algorithm
3: agressive, remove any linefeed and doesn't take care of potential
missing semicolons (can be regressive)
store stats
jsmin.oldSize
jsmin.newSize
*/
String.prototype.has = function(c) {
return this.indexOf(c) > -1;
};
function jsmin(comment, input, level) {
if (input === undefined) {
input = comment;
comment = '';
level = 2;
} else if (level === undefined || level < 1 || level > 3) {
level = 2;
}
if (comment.length > 0) {
comment += '\n';
}
var a = '',
b = '',
EOF = -1,
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
DIGITS = '0123456789',
ALNUM = LETTERS + DIGITS + '_$\\',
theLookahead = EOF;
/* isAlphanum -- return true if the character is a letter, digit, underscore,
dollar sign, or non-ASCII character.
*/
function isAlphanum(c) {
return c != EOF && (ALNUM.has(c) || c.charCodeAt(0) > 126);
}
/* get -- return the next character. Watch out for lookahead. If the
character is a control character, translate it to a space or
linefeed.
*/
function get() {
var c = theLookahead;
if (get.i == get.l) {
return EOF;
}
theLookahead = EOF;
if (c == EOF) {
c = input.charAt(get.i);
++get.i;
}
if (c >= ' ' || c == '\n') {
return c;
}
if (c == '\r') {
return '\n';
}
return ' ';
}
get.i = 0;
get.l = input.length;
/* peek -- get the next character without getting it.
*/
function peek() {
theLookahead = get();
return theLookahead;
}
/* next -- get the next character, excluding comments. peek() is used to see
if a '/' is followed by a '/' or '*'.
*/
function next() {
var c = get();
if (c == '/') {
switch (peek()) {
case '/':
for (;;) {
c = get();
if (c <= '\n') {
return c;
}
}
break;
case '*':
get();
for (;;) {
switch (get()) {
case '*':
if (peek() == '/') {
get();
return ' ';
}
break;
case EOF:
throw 'Error: Unterminated comment.';
}
}
break;
default:
return c;
}
}
return c;
}
/* action -- do something! What you do is determined by the argument:
1 Output A. Copy B to A. Get the next B.
2 Copy B to A. Get the next B. (Delete A).
3 Get the next B. (Delete B).
action treats a string as a single character. Wow!
action recognizes a regular expression if it is preceded by ( or , or =.
*/
function action(d) {
var r = [];
if (d == 1) {
r.push(a);
}
if (d < 3) {
a = b;
if (a == '\'' || a == '"') {
for (;;) {
r.push(a);
a = get();
if (a == b) {
break;
}
if (a <= '\n') {
throw 'Error: unterminated string literal: ' + a;
}
if (a == '\\') {
r.push(a);
a = get();
}
}
}
}
b = next();
if (b == '/' && '(,=:[!&|'.has(a)) {
r.push(a);
r.push(b);
for (;;) {
a = get();
if (a == '/') {
break;
} else if (a =='\\') {
r.push(a);
a = get();
} else if (a <= '\n') {
throw 'Error: unterminated Regular Expression literal';
}
r.push(a);
}
b = next();
}
return r.join('');
}
/* m -- Copy the input to the output, deleting the characters which are
insignificant to JavaScript. Comments will be removed. Tabs will be
replaced with spaces. Carriage returns will be replaced with
linefeeds.
Most spaces and linefeeds will be removed.
*/
function m() {
var r = [];
a = '\n';
r.push(action(3));
while (a != EOF) {
switch (a) {
case ' ':
if (isAlphanum(b)) {
r.push(action(1));
} else {
r.push(action(2));
}
break;
case '\n':
switch (b) {
case '{':
case '[':
case '(':
case '+':
case '-':
r.push(action(1));
break;
case ' ':
r.push(action(3));
break;
default:
if (isAlphanum(b)) {
r.push(action(1));
} else {
if (level == 1 && b != '\n') {
r.push(action(1));
} else {
r.push(action(2));
}
}
}
break;
default:
switch (b) {
case ' ':
if (isAlphanum(a)) {
r.push(action(1));
break;
}
r.push(action(3));
break;
case '\n':
if (level == 1 && a != '\n') {
r.push(action(1));
} else {
switch (a) {
case '}':
case ']':
case ')':
case '+':
case '-':
case '"':
case '\'':
if (level == 3) {
r.push(action(3));
} else {
r.push(action(1));
}
break;
default:
if (isAlphanum(a)) {
r.push(action(1));
} else {
r.push(action(3));
}
}
}
break;
default:
r.push(action(1));
break;
}
}
}
return r.join('');
}
jsmin.oldSize = input.length;
var r = m(input);
jsmin.newSize = r.length;
return comment + r;
}

117
release/build/js/json.js Normal file
View File

@ -0,0 +1,117 @@
/*
json.js
2006-04-28
This file adds these methods to JavaScript:
object.toJSONString()
This method produces a JSON text from an object. The
object must not contain any cyclical references.
array.toJSONString()
This method produces a JSON text from an array. The
array must not contain any cyclical references.
string.parseJSON()
This method parses a JSON text to produce an object or
array. It will return false if there is an error.
*/
(function () {
var m = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
s = {
array: function (x) {
var a = ['['], b, f, i, l = x.length, v;
for (i = 0; i < l; i += 1) {
v = x[i];
f = s[typeof v];
if (f) {
v = f(v);
if (typeof v == 'string') {
if (b) {
a[a.length] = ',';
}
a[a.length] = v;
b = true;
}
}
}
a[a.length] = ']';
return a.join('');
},
'boolean': function (x) {
return String(x);
},
'null': function (x) {
return "null";
},
number: function (x) {
return isFinite(x) ? String(x) : 'null';
},
object: function (x) {
if (x) {
if (x instanceof Array) {
return s.array(x);
}
var a = ['{'], b, f, i, v;
for (i in x) {
v = x[i];
f = s[typeof v];
if (f) {
v = f(v);
if (typeof v == 'string') {
if (b) {
a[a.length] = ',';
}
a.push(s.string(i), ':', v);
b = true;
}
}
}
a[a.length] = '}';
return a.join('');
}
return 'null';
},
string: function (x) {
if (/["\\\x00-\x1f]/.test(x)) {
x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
var c = m[b];
if (c) {
return c;
}
c = b.charCodeAt();
return '\\u00' +
Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
});
}
return '"' + x + '"';
}
};
Object.toJSON = function(obj) {
return s.object(obj);
};
})();
String.prototype.parseJSON = function () {
try {
return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
this.replace(/"(\\.|[^"\\])*"/g, ''))) &&
eval('(' + this + ')');
} catch (e) {
return false;
}
};

316
release/build/js/pack.js Normal file
View File

@ -0,0 +1,316 @@
/*
packer, version 2.0.2 (2005-08-19)
Copyright 2004-2005, Dean Edwards
License: http://creativecommons.org/licenses/LGPL/2.1/
*/
function pack(_script, _encoding, _fastDecode, _specialChars) {
// constants
var $IGNORE = "$1";
// validate parameters
_script += "\n";
_encoding = Math.min(parseInt(_encoding), 95);
// apply all parsing routines
function _pack($script) {
var i, $parse;
for (i = 0; ($parse = _parsers[i]); i++) {
$script = $parse($script);
}
return $script;
};
// unpacking function - this is the boot strap function
// data extracted from this packing routine is passed to
// this function when decoded in the target
var _unpack = function($packed, $ascii, $count, $keywords, $encode, $decode) {
while ($count--)
if ($keywords[$count])
$packed = $packed.replace(new RegExp('\\b' + $encode($count) + '\\b', 'g'), $keywords[$count]);
return $packed;
};
// code-snippet inserted into the unpacker to speed up decoding
var _decode = function() {
// does the browser support String.replace where the
// replacement value is a function?
if (!''.replace(/^/, String)) {
// decode all the values we need
while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count);
// global replacement function
$keywords = [function($encoded){return $decode[$encoded]}];
// generic match
$encode = function(){return'\\w+'};
// reset the loop counter - we are now doing a global replace
$count = 1;
}
};
// keep a list of parsing functions, they'll be executed all at once
var _parsers = [];
function _addParser($parser) {
_parsers[_parsers.length] = $parser;
};
// zero encoding - just removal of white space and comments
function _basicCompression($script) {
var $parser = new ParseMaster;
// make safe
$parser.escapeChar = "\\";
// protect strings
$parser.add(/'[^'\n\r]*'/, $IGNORE);
$parser.add(/"[^"\n\r]*"/, $IGNORE);
// remove comments
$parser.add(/\/\/[^\n\r]*[\n\r]/, " ");
$parser.add(/\/\*[^*]*\*+([^\/][^*]*\*+)*\//, " ");
// protect regular expressions
$parser.add(/\s+(\/[^\/\n\r\*][^\/\n\r]*\/g?i?)/, "$2"); // IGNORE
$parser.add(/[^\w\x24\/'"*)\?:]\/[^\/\n\r\*][^\/\n\r]*\/g?i?/, $IGNORE);
// remove: ;;; doSomething();
if (_specialChars) $parser.add(/;;;[^\n\r]+[\n\r]/);
// remove redundant semi-colons
$parser.add(/\(;;\)/, $IGNORE); // protect for (;;) loops
$parser.add(/;+\s*([};])/, "$2");
// apply the above
$script = $parser.exec($script);
// remove white-space
$parser.add(/(\b|\x24)\s+(\b|\x24)/, "$2 $3");
$parser.add(/([+\-])\s+([+\-])/, "$2 $3");
$parser.add(/\s+/, "");
// done
return $parser.exec($script);
};
function _encodeSpecialChars($script) {
var $parser = new ParseMaster;
// replace: $name -> n, $$name -> na
$parser.add(/((\x24+)([a-zA-Z$_]+))(\d*)/, function($match, $offset) {
var $length = $match[$offset + 2].length;
var $start = $length - Math.max($length - $match[$offset + 3].length, 0);
return $match[$offset + 1].substr($start, $length) + $match[$offset + 4];
});
// replace: _name -> _0, double-underscore (__name) is ignored
var $regexp = /\b_[A-Za-z\d]\w*/;
// build the word list
var $keywords = _analyze($script, _globalize($regexp), _encodePrivate);
// quick ref
var $encoded = $keywords.$encoded;
$parser.add($regexp, function($match, $offset) {
return $encoded[$match[$offset]];
});
return $parser.exec($script);
};
function _encodeKeywords($script) {
// escape high-ascii values already in the script (i.e. in strings)
if (_encoding > 62) $script = _escape95($script);
// create the parser
var $parser = new ParseMaster;
var $encode = _getEncoder(_encoding);
// for high-ascii, don't encode single character low-ascii
var $regexp = (_encoding > 62) ? /\w\w+/ : /\w+/;
// build the word list
$keywords = _analyze($script, _globalize($regexp), $encode);
var $encoded = $keywords.$encoded;
// encode
$parser.add($regexp, function($match, $offset) {
return $encoded[$match[$offset]];
});
// if encoded, wrap the script in a decoding function
return $script && _bootStrap($parser.exec($script), $keywords);
};
function _analyze($script, $regexp, $encode) {
// analyse
// retreive all words in the script
var $all = $script.match($regexp);
var $$sorted = []; // list of words sorted by frequency
var $$encoded = {}; // dictionary of word->encoding
var $$protected = {}; // instances of "protected" words
if ($all) {
var $unsorted = []; // same list, not sorted
var $protected = {}; // "protected" words (dictionary of word->"word")
var $values = {}; // dictionary of charCode->encoding (eg. 256->ff)
var $count = {}; // word->count
var i = $all.length, j = 0, $word;
// count the occurrences - used for sorting later
do {
$word = "$" + $all[--i];
if (!$count[$word]) {
$count[$word] = 0;
$unsorted[j] = $word;
// make a dictionary of all of the protected words in this script
// these are words that might be mistaken for encoding
$protected["$" + ($values[j] = $encode(j))] = j++;
}
// increment the word counter
$count[$word]++;
} while (i);
// prepare to sort the word list, first we must protect
// words that are also used as codes. we assign them a code
// equivalent to the word itself.
// e.g. if "do" falls within our encoding range
// then we store keywords["do"] = "do";
// this avoids problems when decoding
i = $unsorted.length;
do {
$word = $unsorted[--i];
if ($protected[$word] != null) {
$$sorted[$protected[$word]] = $word.slice(1);
$$protected[$protected[$word]] = true;
$count[$word] = 0;
}
} while (i);
// sort the words by frequency
$unsorted.sort(function($match1, $match2) {
return $count[$match2] - $count[$match1];
});
j = 0;
// because there are "protected" words in the list
// we must add the sorted words around them
do {
if ($$sorted[i] == null) $$sorted[i] = $unsorted[j++].slice(1);
$$encoded[$$sorted[i]] = $values[i];
} while (++i < $unsorted.length);
}
return {$sorted: $$sorted, $encoded: $$encoded, $protected: $$protected};
};
// build the boot function used for loading and decoding
function _bootStrap($packed, $keywords) {
var $ENCODE = _safeRegExp("$encode\\($count\\)", "g");
// $packed: the packed script
$packed = "'" + _escape($packed) + "'";
// $ascii: base for encoding
var $ascii = Math.min($keywords.$sorted.length, _encoding) || 1;
// $count: number of words contained in the script
var $count = $keywords.$sorted.length;
// $keywords: list of words contained in the script
for (var i in $keywords.$protected) $keywords.$sorted[i] = "";
// convert from a string to an array
$keywords = "'" + $keywords.$sorted.join("|") + "'.split('|')";
// $encode: encoding function (used for decoding the script)
var $encode = _encoding > 62 ? _encode95 : _getEncoder($ascii);
$encode = String($encode).replace(/_encoding/g, "$ascii").replace(/arguments\.callee/g, "$encode");
var $inline = "$count" + ($ascii > 10 ? ".toString($ascii)" : "");
// $decode: code snippet to speed up decoding
if (_fastDecode) {
// create the decoder
var $decode = _getFunctionBody(_decode);
if (_encoding > 62) $decode = $decode.replace(/\\\\w/g, "[\\xa1-\\xff]");
// perform the encoding inline for lower ascii values
else if ($ascii < 36) $decode = $decode.replace($ENCODE, $inline);
// special case: when $count==0 there are no keywords. I want to keep
// the basic shape of the unpacking funcion so i'll frig the code...
if (!$count) $decode = $decode.replace(_safeRegExp("($count)\\s*=\\s*1"), "$1=0");
}
// boot function
var $unpack = String(_unpack);
if (_fastDecode) {
// insert the decoder
$unpack = $unpack.replace(/\{/, "{" + $decode + ";");
}
$unpack = $unpack.replace(/"/g, "'");
if (_encoding > 62) { // high-ascii
// get rid of the word-boundaries for regexp matches
$unpack = $unpack.replace(/'\\\\b'\s*\+|\+\s*'\\\\b'/g, "");
}
if ($ascii > 36 || _encoding > 62 || _fastDecode) {
// insert the encode function
$unpack = $unpack.replace(/\{/, "{$encode=" + $encode + ";");
} else {
// perform the encoding inline
$unpack = $unpack.replace($ENCODE, $inline);
}
// pack the boot function too
$unpack = pack($unpack, 0, false, true);
// arguments
var $params = [$packed, $ascii, $count, $keywords];
if (_fastDecode) {
// insert placeholders for the decoder
$params = $params.concat(0, "{}");
}
// the whole thing
return "eval(" + $unpack + "(" + $params + "))\n";
};
// mmm.. ..which one do i need ??
function _getEncoder($ascii) {
return $ascii > 10 ? $ascii > 36 ? $ascii > 62 ? _encode95 : _encode62 : _encode36 : _encode10;
};
// zero encoding
// characters: 0123456789
var _encode10 = function($charCode) {
return $charCode;
};
// inherent base36 support
// characters: 0123456789abcdefghijklmnopqrstuvwxyz
var _encode36 = function($charCode) {
return $charCode.toString(36);
};
// hitch a ride on base36 and add the upper case alpha characters
// characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
var _encode62 = function($charCode) {
return ($charCode < _encoding ? '' : arguments.callee(parseInt($charCode / _encoding))) +
(($charCode = $charCode % _encoding) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36));
};
// use high-ascii values
var _encode95 = function($charCode) {
return ($charCode < _encoding ? '' : arguments.callee($charCode / _encoding)) +
String.fromCharCode($charCode % _encoding + 161);
};
// special _chars
var _encodePrivate = function($charCode) {
return "_" + $charCode;
};
// protect characters used by the parser
function _escape($script) {
return $script.replace(/([\\'])/g, "\\$1");
};
// protect high-ascii characters already in the script
function _escape95($script) {
return $script.replace(/[\xa1-\xff]/g, function($match) {
return "\\x" + $match.charCodeAt(0).toString(16);
});
};
function _safeRegExp($string, $flags) {
return new RegExp($string.replace(/\$/g, "\\$"), $flags);
};
// extract the body of a function
function _getFunctionBody($function) {
with (String($function)) return slice(indexOf("{") + 1, lastIndexOf("}"));
};
// set the global flag on a RegExp (you have to create a new one)
function _globalize($regexp) {
return new RegExp(String($regexp).slice(1, -1), "g");
};
// build the parsing routine
_addParser(_basicCompression);
if (_specialChars) _addParser(_encodeSpecialChars);
if (_encoding) _addParser(_encodeKeywords);
// go!
return _pack(_script);
};

68
release/build/js/pack.wsf Normal file

File diff suppressed because one or more lines are too long

105
release/build/js/parse.js Normal file
View File

@ -0,0 +1,105 @@
function parse( f ) {
var c = [], bm, m;
var blockMatch = /\/\*\*\s*((.|\n)*?)\s*\*\//g;
var paramMatch = /\@(\S+) *((.|\n)*?)(?=\n\@|!!!)/m;
while ( bm = blockMatch.exec(f) ) {
block = bm[1].replace(/^\s*\* ?/mg,"") + "!!!";
var ret = { params: [], examples: [], tests: [], options: [] };
while ( m = paramMatch.exec( block ) ) {
block = block.replace( paramMatch, "" );
var n = m[1];
var v = m[2]
.replace(/\s*$/g,"")
.replace(/^\s*/g,"")
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
//.replace(/\n/g, "<br/>")
/*.replace(/(\s\s+)/g, function(a){
var ret = "";
for ( var i = 0; i < a.length; i++ )
ret += "&nbsp;";
return ret;
})*/ || 1;
if ( n == 'param' || n == 'option' ) {
var args = v.split(/\s+/);
v = args.slice( 2, args.length );
v = { type: args[0], name: args[1], desc: v.join(' ') };
n = n + "s";
} else if ( n == 'example' ) {
v = { code: v };
n = "examples";
} else if ( n == 'test' ) {
n = "tests";
}
if ( n == 'desc' || n == 'before' || n == 'after' || n == 'result' ) {
ret.examples[ ret.examples.length - 1 ][ n ] = v;
} else {
if ( ret[ n ] ) {
if ( ret[ n ].constructor == Array ) {
ret[ n ].push( v );
} else {
ret[ n ] = [ ret[ n ], v ];
}
} else {
ret[ n ] = v;
}
}
}
ret.desc = block.replace(/\s*!!!$/,"")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
//.replace(/\n\n/g, "<br/><br/>")
//.replace(/\n/g, " ");
var m = /^((.|\n)*?(\.|$))/.exec( ret.desc );
if ( m ) ret['short'] = m[1];
if ( ret.name ) c.push( ret );
}
return c;
}
function categorize( json ) {
var obj = { cat: [], method: [] };
for ( var i = 0; i < json.length; i++ ) {
if ( !json[i].cat ) json[i].cat = "";
var cat = json[i].cat.split("/");
var pos = obj;
for ( var j = 0; j < cat.length; j++ ) {
var c = cat[j];
var curCat = null;
// Locate current category
for ( var n = 0; n < pos.cat.length; n++ )
if ( pos.cat[n].value == c )
curCat = pos.cat[n];
// Create current category
if ( !curCat ) {
curCat = { value: c, cat: [], method: [] };
pos.cat.push( curCat )
}
// If we're at the end, add the method
if ( j == cat.length - 1 )
curCat.method.push( json[i] );
// Otherwise, traverse deeper
else
pos = curCat;
}
}
return obj;
}

View File

@ -0,0 +1,19 @@
importPackage(java.io);
function writeFile( file, stream ) {
var buffer = new PrintWriter( new FileWriter( file ) );
buffer.print( stream );
buffer.close();
}
function read( file ) {
var jq = new File(file);
var reader = new BufferedReader(new FileReader(jq));
var line = null;
var buffer = new java.lang.StringBuffer(jq.length());
while( (line = reader.readLine()) != null) {
buffer.append(line);
buffer.append("\n");
}
return buffer.toString();
}

25
release/build/js/xml.js Normal file
View File

@ -0,0 +1,25 @@
Object.toXML = function( obj, tag ) {
if ( obj.constructor == Array ) {
var ret = "";
for ( var i = 0; i < obj.length; i++ )
ret += Object.toXML( obj[i], tag );
return ret;
} else if ( obj.constructor == Object ) {
var tag = tag || "tmp";
var p = "", child = "";
for ( var i in obj )
if ( ( obj[i].constructor != String && obj[i].constructor != Number ) || /</.test(obj[i] + "") || Object.toXML.force[i] )
child += Object.toXML( obj[i], i );
else
p += " " + i + "='" + (obj[i] + "").replace(/'/g, "&apos;") + "'";
return "<" + tag + p + ( child ? ">\n" + child + "</" + tag + ">\n" : "/>\n" );
} else if ( obj.constructor == String || obj.constructor == Number ) {
return "<" + tag + ">" + obj + "</" + tag + ">\n";
}
return "";
};
Object.toXML.force = {};

Binary file not shown.