fragments and .js files.", token);
- }
- if (option.fragment) {
- if (n !== 'div') {
- error("ADsafe violation: Wrap the widget in a div.", token);
- }
- } else {
- error("Use the fragment option.", token);
- }
- }
- option.browser = true;
- assume();
- }
-
- function doAttribute(n, a, v) {
- var u, x;
- if (a === 'id') {
- u = typeof v === 'string' ? v.toUpperCase() : '';
- if (ids[u] === true) {
- warning("Duplicate id='{a}'.", nexttoken, v);
- }
- if (!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)) {
- warning("Bad id: '{a}'.", nexttoken, v);
- } else if (option.adsafe) {
- if (adsafe_id) {
- if (v.slice(0, adsafe_id.length) !== adsafe_id) {
- warning("ADsafe violation: An id must have a '{a}' prefix",
- nexttoken, adsafe_id);
- } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {
- warning("ADSAFE violation: bad id.");
- }
- } else {
- adsafe_id = v;
- if (!/^[A-Z]+_$/.test(v)) {
- warning("ADSAFE violation: bad id.");
- }
- }
- }
- x = v.search(dx);
- if (x >= 0) {
- warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a);
- }
- ids[u] = true;
- } else if (a === 'class' || a === 'type' || a === 'name') {
- x = v.search(qx);
- if (x >= 0) {
- warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a);
- }
- ids[u] = true;
- } else if (a === 'href' || a === 'background' ||
- a === 'content' || a === 'data' ||
- a.indexOf('src') >= 0 || a.indexOf('url') >= 0) {
- if (option.safe && ux.test(v)) {
- error("ADsafe URL violation.");
- }
- urls.push(v);
- } else if (a === 'for') {
- if (option.adsafe) {
- if (adsafe_id) {
- if (v.slice(0, adsafe_id.length) !== adsafe_id) {
- warning("ADsafe violation: An id must have a '{a}' prefix",
- nexttoken, adsafe_id);
- } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {
- warning("ADSAFE violation: bad id.");
- }
- } else {
- warning("ADSAFE violation: bad id.");
- }
- }
- } else if (a === 'name') {
- if (option.adsafe && v.indexOf('_') >= 0) {
- warning("ADsafe name violation.");
- }
- }
- }
-
- function doTag(n, a) {
- var i, t = htmltag[n], x;
- src = false;
- if (!t) {
- error("Unrecognized tag '<{a}>'.",
- nexttoken,
- n === n.toLowerCase() ? n :
- n + ' (capitalization error)');
- }
- if (stack.length > 0) {
- if (n === 'html') {
- error("Too many tags.", token);
- }
- x = t.parent;
- if (x) {
- if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) {
- error("A '<{a}>' must be within '<{b}>'.",
- token, n, x);
- }
- } else if (!option.adsafe && !option.fragment) {
- i = stack.length;
- do {
- if (i <= 0) {
- error("A '<{a}>' must be within '<{b}>'.",
- token, n, 'body');
- }
- i -= 1;
- } while (stack[i].name !== 'body');
- }
- }
- switch (n) {
- case 'div':
- if (option.adsafe && stack.length === 1 && !adsafe_id) {
- warning("ADSAFE violation: missing ID_.");
- }
- break;
- case 'script':
- xmode = 'script';
- advance('>');
- indent = nexttoken.from;
- if (a.lang) {
- warning("lang is deprecated.", token);
- }
- if (option.adsafe && stack.length !== 1) {
- warning("ADsafe script placement violation.", token);
- }
- if (a.src) {
- if (option.adsafe && (!adsafe_may || !approved[a.src])) {
- warning("ADsafe unapproved script source.", token);
- }
- if (a.type) {
- warning("type is unnecessary.", token);
- }
- } else {
- if (adsafe_went) {
- error("ADsafe script violation.", token);
- }
- statements('script');
- }
- xmode = 'html';
- advance('');
- if (!nexttoken.identifier && nexttoken.value !== 'script') {
- warning("Expected '{a}' and instead saw '{b}'.",
- nexttoken, 'script', nexttoken.value);
- }
- advance();
- xmode = 'outer';
- break;
- case 'style':
- xmode = 'style';
- advance('>');
- styles();
- xmode = 'html';
- advance('');
- if (!nexttoken.identifier && nexttoken.value !== 'style') {
- warning("Expected '{a}' and instead saw '{b}'.",
- nexttoken, 'style', nexttoken.value);
- }
- advance();
- xmode = 'outer';
- break;
- case 'input':
- switch (a.type) {
- case 'radio':
- case 'checkbox':
- case 'button':
- case 'reset':
- case 'submit':
- break;
- case 'text':
- case 'file':
- case 'password':
- case 'file':
- case 'hidden':
- case 'image':
- if (option.adsafe && a.autocomplete !== 'off') {
- warning("ADsafe autocomplete violation.");
- }
- break;
- default:
- warning("Bad input type.");
- }
- break;
- case 'applet':
- case 'body':
- case 'embed':
- case 'frame':
- case 'frameset':
- case 'head':
- case 'iframe':
- case 'noembed':
- case 'noframes':
- case 'object':
- case 'param':
- if (option.adsafe) {
- warning("ADsafe violation: Disallowed tag: " + n);
- }
- break;
- }
- }
-
-
- function closetag(n) {
- return '' + n + '>';
- }
-
- function html() {
- var a, attributes, e, n, q, t, v, w = option.white, wmode;
- xmode = 'html';
- xquote = '';
- stack = null;
- for (;;) {
- switch (nexttoken.value) {
- case '<':
- xmode = 'html';
- advance('<');
- attributes = {};
- t = nexttoken;
- if (!t.identifier) {
- warning("Bad identifier {a}.", t, t.value);
- }
- n = t.value;
- if (option.cap) {
- n = n.toLowerCase();
- }
- t.name = n;
- advance();
- if (!stack) {
- stack = [];
- doBegin(n);
- }
- v = htmltag[n];
- if (typeof v !== 'object') {
- error("Unrecognized tag '<{a}>'.", t, n);
- }
- e = v.empty;
- t.type = n;
- for (;;) {
- if (nexttoken.id === '/') {
- advance('/');
- if (nexttoken.id !== '>') {
- warning("Expected '{a}' and instead saw '{b}'.",
- nexttoken, '>', nexttoken.value);
- }
- break;
- }
- if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') {
- break;
- }
- if (!nexttoken.identifier) {
- if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
- error("Missing '>'.", nexttoken);
- }
- warning("Bad identifier.");
- }
- option.white = true;
- nonadjacent(token, nexttoken);
- a = nexttoken.value;
- option.white = w;
- advance();
- if (!option.cap && a !== a.toLowerCase()) {
- warning("Attribute '{a}' not all lower case.", nexttoken, a);
- }
- a = a.toLowerCase();
- xquote = '';
- if (is_own(attributes, a)) {
- warning("Attribute '{a}' repeated.", nexttoken, a);
- }
- if (a.slice(0, 2) === 'on') {
- if (!option.on) {
- warning("Avoid HTML event handlers.");
- }
- xmode = 'scriptstring';
- advance('=');
- q = nexttoken.id;
- if (q !== '"' && q !== "'") {
- error("Missing quote.");
- }
- xquote = q;
- wmode = option.white;
- option.white = false;
- advance(q);
- statements('on');
- option.white = wmode;
- if (nexttoken.id !== q) {
- error("Missing close quote on script attribute.");
- }
- xmode = 'html';
- xquote = '';
- advance(q);
- v = false;
- } else if (a === 'style') {
- xmode = 'scriptstring';
- advance('=');
- q = nexttoken.id;
- if (q !== '"' && q !== "'") {
- error("Missing quote.");
- }
- xmode = 'styleproperty';
- xquote = q;
- advance(q);
- substyle();
- xmode = 'html';
- xquote = '';
- advance(q);
- v = false;
- } else {
- if (nexttoken.id === '=') {
- advance('=');
- v = nexttoken.value;
- if (!nexttoken.identifier &&
- nexttoken.id !== '"' &&
- nexttoken.id !== '\'' &&
- nexttoken.type !== '(string)' &&
- nexttoken.type !== '(number)' &&
- nexttoken.type !== '(color)') {
- warning("Expected an attribute value and instead saw '{a}'.", token, a);
- }
- advance();
- } else {
- v = true;
- }
- }
- attributes[a] = v;
- doAttribute(n, a, v);
- }
- doTag(n, attributes);
- if (!e) {
- stack.push(t);
- }
- xmode = 'outer';
- advance('>');
- break;
- case '':
- xmode = 'html';
- advance('');
- if (!nexttoken.identifier) {
- warning("Bad identifier.");
- }
- n = nexttoken.value;
- if (option.cap) {
- n = n.toLowerCase();
- }
- advance();
- if (!stack) {
- error("Unexpected '{a}'.", nexttoken, closetag(n));
- }
- t = stack.pop();
- if (!t) {
- error("Unexpected '{a}'.", nexttoken, closetag(n));
- }
- if (t.name !== n) {
- error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, closetag(t.name), closetag(n));
- }
- if (nexttoken.id !== '>') {
- error("Missing '{a}'.", nexttoken, '>');
- }
- xmode = 'outer';
- advance('>');
- break;
- case '' || nexttoken.id === '(end)') {
- break;
- }
- if (nexttoken.value.indexOf('--') >= 0) {
- warning("Unexpected --.");
- }
- if (nexttoken.value.indexOf('<') >= 0) {
- warning("Unexpected <.");
- }
- if (nexttoken.value.indexOf('>') >= 0) {
- warning("Unexpected >.");
- }
- }
- xmode = 'outer';
- advance('>');
- break;
- case '(end)':
- return;
- default:
- if (nexttoken.id === '(end)') {
- error("Missing '{a}'.", nexttoken,
- '' + stack[stack.length - 1].value + '>');
- } else {
- advance();
- }
- }
- if (stack && stack.length === 0 && (option.adsafe ||
- !option.fragment || nexttoken.id === '(end)')) {
- break;
- }
- }
- if (nexttoken.id !== '(end)') {
- error("Unexpected material after the end.");
- }
- }
-
-
-// Build the syntax table by declaring the syntactic elements of the language.
-
- type('(number)', idValue);
- type('(string)', idValue);
-
- syntax['(identifier)'] = {
- type: '(identifier)',
- lbp: 0,
- identifier: true,
- nud: function () {
- var v = this.value,
- s = scope[v],
- f;
- if (typeof s === 'function') {
- s = undefined;
- } else if (typeof s === 'boolean') {
- f = funct;
- funct = functions[0];
- addlabel(v, 'var');
- s = funct;
- funct = f;
- }
-
-// The name is in scope and defined in the current function.
-
- if (funct === s) {
-
-// Change 'unused' to 'var', and reject labels.
-
- switch (funct[v]) {
- case 'unused':
- funct[v] = 'var';
- break;
- case 'label':
- warning("'{a}' is a statement label.", token, v);
- break;
- }
-
-// The name is not defined in the function. If we are in the global scope,
-// then we have an undefined variable.
-
- } else if (funct['(global)']) {
- if (option.undef && predefined[v] !== 'boolean') {
- warning("'{a}' is not defined.", token, v);
- }
- note_implied(token);
-
-// If the name is already defined in the current
-// function, but not as outer, then there is a scope error.
-
- } else {
- switch (funct[v]) {
- case 'closure':
- case 'function':
- case 'var':
- case 'unused':
- warning("'{a}' used out of scope.", token, v);
- break;
- case 'label':
- warning("'{a}' is a statement label.", token, v);
- break;
- case 'outer':
- case 'global':
- break;
- default:
-
-// If the name is defined in an outer function, make an outer entry, and if
-// it was unused, make it var.
-
- if (s === true) {
- funct[v] = true;
- } else if (s === null) {
- warning("'{a}' is not allowed.", token, v);
- note_implied(token);
- } else if (typeof s !== 'object') {
- if (option.undef) {
- warning("'{a}' is not defined.", token, v);
- } else {
- funct[v] = true;
- }
- note_implied(token);
- } else {
- switch (s[v]) {
- case 'function':
- case 'var':
- case 'unused':
- s[v] = 'closure';
- funct[v] = s['(global)'] ? 'global' : 'outer';
- break;
- case 'closure':
- case 'parameter':
- funct[v] = s['(global)'] ? 'global' : 'outer';
- break;
- case 'label':
- warning("'{a}' is a statement label.", token, v);
- }
- }
- }
- }
- return this;
- },
- led: function () {
- error("Expected an operator and instead saw '{a}'.",
- nexttoken, nexttoken.value);
- }
- };
-
- type('(regexp)', function () {
- return this;
- });
-
- delim('(endline)');
- delim('(begin)');
- delim('(end)').reach = true;
- delim('').reach = true;
- delim('');
- delim('(error)').reach = true;
- delim('}').reach = true;
- delim(')');
- delim(']');
- delim('"').reach = true;
- delim("'").reach = true;
- delim(';');
- delim(':').reach = true;
- delim(',');
- delim('#');
- delim('@');
- reserve('else');
- reserve('case').reach = true;
- reserve('catch');
- reserve('default').reach = true;
- reserve('finally');
- reservevar('arguments');
- reservevar('eval');
- reservevar('false');
- reservevar('Infinity');
- reservevar('NaN');
- reservevar('null');
- reservevar('this');
- reservevar('true');
- reservevar('undefined');
- assignop('=', 'assign', 20);
- assignop('+=', 'assignadd', 20);
- assignop('-=', 'assignsub', 20);
- assignop('*=', 'assignmult', 20);
- assignop('/=', 'assigndiv', 20).nud = function () {
- error("A regular expression literal can be confused with '/='.");
- };
- assignop('%=', 'assignmod', 20);
- bitwiseassignop('&=', 'assignbitand', 20);
- bitwiseassignop('|=', 'assignbitor', 20);
- bitwiseassignop('^=', 'assignbitxor', 20);
- bitwiseassignop('<<=', 'assignshiftleft', 20);
- bitwiseassignop('>>=', 'assignshiftright', 20);
- bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);
- infix('?', function (left, that) {
- that.left = left;
- that.right = parse(10);
- advance(':');
- that['else'] = parse(10);
- return that;
- }, 30);
-
- infix('||', 'or', 40);
- infix('&&', 'and', 50);
- bitwise('|', 'bitor', 70);
- bitwise('^', 'bitxor', 80);
- bitwise('&', 'bitand', 90);
- relation('==', function (left, right) {
- if (option.eqeqeq) {
- warning("Expected '{a}' and instead saw '{b}'.",
- this, '===', '==');
- } else if (isPoorRelation(left)) {
- warning("Use '{a}' to compare with '{b}'.",
- this, '===', left.value);
- } else if (isPoorRelation(right)) {
- warning("Use '{a}' to compare with '{b}'.",
- this, '===', right.value);
- }
- return this;
- });
- relation('===');
- relation('!=', function (left, right) {
- if (option.eqeqeq) {
- warning("Expected '{a}' and instead saw '{b}'.",
- this, '!==', '!=');
- } else if (isPoorRelation(left)) {
- warning("Use '{a}' to compare with '{b}'.",
- this, '!==', left.value);
- } else if (isPoorRelation(right)) {
- warning("Use '{a}' to compare with '{b}'.",
- this, '!==', right.value);
- }
- return this;
- });
- relation('!==');
- relation('<');
- relation('>');
- relation('<=');
- relation('>=');
- bitwise('<<', 'shiftleft', 120);
- bitwise('>>', 'shiftright', 120);
- bitwise('>>>', 'shiftrightunsigned', 120);
- infix('in', 'in', 120);
- infix('instanceof', 'instanceof', 120);
- infix('+', function (left, that) {
- var right = parse(130);
- if (left && right && left.id === '(string)' && right.id === '(string)') {
- left.value += right.value;
- left.character = right.character;
- if (jx.test(left.value)) {
- warning("JavaScript URL.", left);
- }
- return left;
- }
- that.left = left;
- that.right = right;
- return that;
- }, 130);
- prefix('+', 'num');
- infix('-', 'sub', 130);
- prefix('-', 'neg');
- infix('*', 'mult', 140);
- infix('/', 'div', 140);
- infix('%', 'mod', 140);
-
- suffix('++', 'postinc');
- prefix('++', 'preinc');
- syntax['++'].exps = true;
-
- suffix('--', 'postdec');
- prefix('--', 'predec');
- syntax['--'].exps = true;
- prefix('delete', function () {
- var p = parse(0);
- if (!p || (p.id !== '.' && p.id !== '[')) {
- warning("Expected '{a}' and instead saw '{b}'.",
- nexttoken, '.', nexttoken.value);
- }
- this.first = p;
- return this;
- }).exps = true;
-
-
- prefix('~', function () {
- if (option.bitwise) {
- warning("Unexpected '{a}'.", this, '~');
- }
- parse(150);
- return this;
- });
- prefix('!', function () {
- this.right = parse(150);
- this.arity = 'unary';
- if (bang[this.right.id] === true) {
- warning("Confusing use of '{a}'.", this, '!');
- }
- return this;
- });
- prefix('typeof', 'typeof');
- prefix('new', function () {
- var c = parse(155), i;
- if (c && c.id !== 'function') {
- if (c.identifier) {
- c['new'] = true;
- switch (c.value) {
- case 'Object':
- warning("Use the object literal notation {}.", token);
- break;
- case 'Array':
- if (nexttoken.id !== '(') {
- warning("Use the array literal notation [].", token);
- } else {
- advance('(');
- if (nexttoken.id === ')') {
- warning("Use the array literal notation [].", token);
- } else {
- i = parse(0);
- c.dimension = i;
- if ((i.id === '(number)' && /[.+\-Ee]/.test(i.value)) ||
- (i.id === '-' && !i.right) ||
- i.id === '(string)' || i.id === '[' ||
- i.id === '{' || i.id === 'true' ||
- i.id === 'false' ||
- i.id === 'null' || i.id === 'undefined' ||
- i.id === 'Infinity') {
- warning("Use the array literal notation [].", token);
- }
- if (nexttoken.id !== ')') {
- error("Use the array literal notation [].", token);
- }
- }
- advance(')');
- }
- this.first = c;
- return this;
- case 'Number':
- case 'String':
- case 'Boolean':
- case 'Math':
- case 'JSON':
- warning("Do not use {a} as a constructor.", token, c.value);
- break;
- case 'Function':
- if (!option.evil) {
- warning("The Function constructor is eval.");
- }
- break;
- case 'Date':
- case 'RegExp':
- break;
- default:
- if (c.id !== 'function') {
- i = c.value.substr(0, 1);
- if (option.newcap && (i < 'A' || i > 'Z')) {
- warning(
- "A constructor name should start with an uppercase letter.",
- token);
- }
- }
- }
- } else {
- if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
- warning("Bad constructor.", token);
- }
- }
- } else {
- warning("Weird construction. Delete 'new'.", this);
- }
- adjacent(token, nexttoken);
- if (nexttoken.id !== '(') {
- warning("Missing '()' invoking a constructor.");
- }
- this.first = c;
- return this;
- });
- syntax['new'].exps = true;
-
- infix('.', function (left, that) {
- adjacent(prevtoken, token);
- var m = identifier();
- if (typeof m === 'string') {
- countMember(m);
- }
- that.left = left;
- that.right = m;
- if (!option.evil && left && left.value === 'document' &&
- (m === 'write' || m === 'writeln')) {
- warning("document.write can be a form of eval.", left);
- } else if (option.adsafe) {
- if (left && left.value === 'ADSAFE') {
- if (m === 'id' || m === 'lib') {
- warning("ADsafe violation.", that);
- } else if (m === 'go') {
- if (xmode !== 'script') {
- warning("ADsafe violation.", that);
- } else if (adsafe_went || nexttoken.id !== '(' ||
- peek(0).id !== '(string)' ||
- peek(0).value !== adsafe_id ||
- peek(1).id !== ',') {
- error("ADsafe violation: go.", that);
- }
- adsafe_went = true;
- adsafe_may = false;
- }
- }
- }
- if (!option.evil && (m === 'eval' || m === 'execScript')) {
- warning('eval is evil.');
- } else if (option.safe) {
- for (;;) {
- if (banned[m] === true) {
- warning("ADsafe restricted word '{a}'.", token, m);
- }
- if (typeof predefined[left.value] !== 'boolean' ||
- nexttoken.id === '(') {
- break;
- }
- if (standard_member[m] === true) {
- if (nexttoken.id === '.') {
- warning("ADsafe violation.", that);
- }
- break;
- }
- if (nexttoken.id !== '.') {
- warning("ADsafe violation.", that);
- break;
- }
- advance('.');
- token.left = that;
- token.right = m;
- that = token;
- m = identifier();
- if (typeof m === 'string') {
- countMember(m);
- }
- }
- }
- return that;
- }, 160, true);
-
- infix('(', function (left, that) {
- adjacent(prevtoken, token);
- nospace();
- var n = 0,
- p = [];
- if (left) {
- if (left.type === '(identifier)') {
- if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
- if (left.value !== 'Number' && left.value !== 'String' &&
- left.value !== 'Boolean' &&
- left.value !== 'Date') {
- if (left.value === 'Math') {
- warning("Math is not a function.", left);
- } else if (option.newcap) {
- warning(
-"Missing 'new' prefix when invoking a constructor.", left);
- }
- }
- }
- } else if (left.id === '.') {
- if (option.safe && left.left.value === 'Math' &&
- left.right === 'random') {
- warning("ADsafe violation.", left);
- }
- }
- }
- if (nexttoken.id !== ')') {
- for (;;) {
- p[p.length] = parse(10);
- n += 1;
- if (nexttoken.id !== ',') {
- break;
- }
- comma();
- }
- }
- advance(')');
- if (option.immed && left.id === 'function' && nexttoken.id !== ')') {
- warning("Wrap the entire immediate function invocation in parens.",
- that);
- }
- nospace(prevtoken, token);
- if (typeof left === 'object') {
- if (left.value === 'parseInt' && n === 1) {
- warning("Missing radix parameter.", left);
- }
- if (!option.evil) {
- if (left.value === 'eval' || left.value === 'Function' ||
- left.value === 'execScript') {
- warning("eval is evil.", left);
- } else if (p[0] && p[0].id === '(string)' &&
- (left.value === 'setTimeout' ||
- left.value === 'setInterval')) {
- warning(
- "Implied eval is evil. Pass a function instead of a string.", left);
- }
- }
- if (!left.identifier && left.id !== '.' && left.id !== '[' &&
- left.id !== '(' && left.id !== '&&' && left.id !== '||' &&
- left.id !== '?') {
- warning("Bad invocation.", left);
- }
- }
- that.left = left;
- return that;
- }, 155, true).exps = true;
-
- prefix('(', function () {
- nospace();
- var v = parse(0);
- advance(')', this);
- nospace(prevtoken, token);
- if (option.immed && v.id === 'function') {
- if (nexttoken.id === '(') {
- warning(
-"Move the invocation into the parens that contain the function.", nexttoken);
- } else {
- warning(
-"Do not wrap function literals in parens unless they are to be immediately invoked.",
- this);
- }
- }
- return v;
- });
-
- infix('[', function (left, that) {
- nospace();
- var e = parse(0), s;
- if (e && e.type === '(string)') {
- if (option.safe && banned[e.value] === true) {
- warning("ADsafe restricted word '{a}'.", that, e.value);
- } else if (!option.evil &&
- (e.value === 'eval' || e.value === 'execScript')) {
- warning("eval is evil.", that);
- } else if (option.safe &&
- (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) {
- warning("ADsafe restricted subscript '{a}'.", that, e.value);
- }
- countMember(e.value);
- if (!option.sub && ix.test(e.value)) {
- s = syntax[e.value];
- if (!s || !s.reserved) {
- warning("['{a}'] is better written in dot notation.",
- e, e.value);
- }
- }
- } else if (!e || e.type !== '(number)' || e.value < 0) {
- if (option.safe) {
- warning('ADsafe subscripting.');
- }
- }
- advance(']', that);
- nospace(prevtoken, token);
- that.left = left;
- that.right = e;
- return that;
- }, 160, true);
-
- prefix('[', function () {
- var b = token.line !== nexttoken.line;
- this.first = [];
- if (b) {
- indent += option.indent;
- if (nexttoken.from === indent + option.indent) {
- indent += option.indent;
- }
- }
- while (nexttoken.id !== '(end)') {
- while (nexttoken.id === ',') {
- warning("Extra comma.");
- advance(',');
- }
- if (nexttoken.id === ']') {
- break;
- }
- if (b && token.line !== nexttoken.line) {
- indentation();
- }
- this.first.push(parse(10));
- if (nexttoken.id === ',') {
- comma();
- if (nexttoken.id === ']') {
- warning("Extra comma.", token);
- break;
- }
- } else {
- break;
- }
- }
- if (b) {
- indent -= option.indent;
- indentation();
- }
- advance(']', this);
- return this;
- }, 160);
-
- (function (x) {
- x.nud = function () {
- var b, i, s, seen = {};
- b = token.line !== nexttoken.line;
- if (b) {
- indent += option.indent;
- if (nexttoken.from === indent + option.indent) {
- indent += option.indent;
- }
- }
- for (;;) {
- if (nexttoken.id === '}') {
- break;
- }
- if (b) {
- indentation();
- }
- i = optionalidentifier(true);
- if (!i) {
- if (nexttoken.id === '(string)') {
- i = nexttoken.value;
- if (ix.test(i)) {
- s = syntax[i];
- }
- advance();
- } else if (nexttoken.id === '(number)') {
- i = nexttoken.value.toString();
- advance();
- } else {
- error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, '}', nexttoken.value);
- }
- }
- if (seen[i] === true) {
- warning("Duplicate member '{a}'.", nexttoken, i);
- }
- seen[i] = true;
- countMember(i);
- advance(':');
- nonadjacent(token, nexttoken);
- parse(10);
- if (nexttoken.id === ',') {
- comma();
- if (nexttoken.id === ',' || nexttoken.id === '}') {
- warning("Extra comma.", token);
- }
- } else {
- break;
- }
- }
- if (b) {
- indent -= option.indent;
- indentation();
- }
- advance('}', this);
- return this;
- };
- x.fud = function () {
- error("Expected to see a statement and instead saw a block.", token);
- };
- }(delim('{')));
-
-
- function varstatement(prefix) {
-
-// JavaScript does not have block scope. It only has function scope. So,
-// declaring a variable in a block can have unexpected consequences.
-
- var id, name, value;
-
- if (funct['(onevar)'] && option.onevar) {
- warning("Too many var statements.");
- } else if (!funct['(global)']) {
- funct['(onevar)'] = true;
- }
- this.first = [];
- for (;;) {
- nonadjacent(token, nexttoken);
- id = identifier();
- if (funct['(global)'] && predefined[id] === false) {
- warning("Redefinition of '{a}'.", token, id);
- }
- addlabel(id, 'unused');
- if (prefix) {
- break;
- }
- name = token;
- this.first.push(token);
- if (nexttoken.id === '=') {
- nonadjacent(token, nexttoken);
- advance('=');
- nonadjacent(token, nexttoken);
- if (nexttoken.id === 'undefined') {
- warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
- }
- if (peek(0).id === '=' && nexttoken.identifier) {
- error("Variable {a} was not declared correctly.",
- nexttoken, nexttoken.value);
- }
- value = parse(0);
- name.first = value;
- }
- if (nexttoken.id !== ',') {
- break;
- }
- comma();
- }
- return this;
- }
-
-
- stmt('var', varstatement).exps = true;
-
-
- function functionparams() {
- var i, t = nexttoken, p = [];
- advance('(');
- nospace();
- if (nexttoken.id === ')') {
- advance(')');
- nospace(prevtoken, token);
- return;
- }
- for (;;) {
- i = identifier();
- p.push(i);
- addlabel(i, 'parameter');
- if (nexttoken.id === ',') {
- comma();
- } else {
- advance(')', t);
- nospace(prevtoken, token);
- return p;
- }
- }
- }
-
- function doFunction(i) {
- var s = scope;
- scope = Object.create(s);
- funct = {
- '(name)' : i || '"' + anonname + '"',
- '(line)' : nexttoken.line,
- '(context)' : funct,
- '(breakage)': 0,
- '(loopage)' : 0,
- '(scope)' : scope
- };
- token.funct = funct;
- functions.push(funct);
- if (i) {
- addlabel(i, 'function');
- }
- funct['(params)'] = functionparams();
-
- block(false);
- scope = s;
- funct['(last)'] = token.line;
- funct = funct['(context)'];
- }
-
-
- blockstmt('function', function () {
- if (inblock) {
- warning(
-"Function statements cannot be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token);
-
- }
- var i = identifier();
- adjacent(token, nexttoken);
- addlabel(i, 'unused');
- doFunction(i);
- if (nexttoken.id === '(' && nexttoken.line === token.line) {
- error(
-"Function statements are not invocable. Wrap the whole function invocation in parens.");
- }
- return this;
- });
-
- prefix('function', function () {
- var i = optionalidentifier();
- if (i) {
- adjacent(token, nexttoken);
- } else {
- nonadjacent(token, nexttoken);
- }
- doFunction(i);
- if (funct['(loopage)']) {
- warning("Don't make functions within a loop.");
- }
- return this;
- });
-
- blockstmt('if', function () {
- var t = nexttoken;
- advance('(');
- nonadjacent(this, t);
- nospace();
- parse(20);
- if (nexttoken.id === '=') {
- warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
- parse(20);
- }
- advance(')', t);
- nospace(prevtoken, token);
- block(true);
- if (nexttoken.id === 'else') {
- nonadjacent(token, nexttoken);
- advance('else');
- if (nexttoken.id === 'if' || nexttoken.id === 'switch') {
- statement(true);
- } else {
- block(true);
- }
- }
- return this;
- });
-
- blockstmt('try', function () {
- var b, e, s;
- if (option.adsafe) {
- warning("ADsafe try violation.", this);
- }
- block(false);
- if (nexttoken.id === 'catch') {
- advance('catch');
- nonadjacent(token, nexttoken);
- advance('(');
- s = scope;
- scope = Object.create(s);
- e = nexttoken.value;
- if (nexttoken.type !== '(identifier)') {
- warning("Expected an identifier and instead saw '{a}'.",
- nexttoken, e);
- } else {
- addlabel(e, 'exception');
- }
- advance();
- advance(')');
- block(false);
- b = true;
- scope = s;
- }
- if (nexttoken.id === 'finally') {
- advance('finally');
- block(false);
- return;
- } else if (!b) {
- error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, 'catch', nexttoken.value);
- }
- return this;
- });
-
- blockstmt('while', function () {
- var t = nexttoken;
- funct['(breakage)'] += 1;
- funct['(loopage)'] += 1;
- advance('(');
- nonadjacent(this, t);
- nospace();
- parse(20);
- if (nexttoken.id === '=') {
- warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
- parse(20);
- }
- advance(')', t);
- nospace(prevtoken, token);
- block(true);
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
- return this;
- }).labelled = true;
-
- reserve('with');
-
- blockstmt('switch', function () {
- var t = nexttoken,
- g = false;
- funct['(breakage)'] += 1;
- advance('(');
- nonadjacent(this, t);
- nospace();
- this.condition = parse(20);
- advance(')', t);
- nospace(prevtoken, token);
- nonadjacent(token, nexttoken);
- t = nexttoken;
- advance('{');
- nonadjacent(token, nexttoken);
- indent += option.indent;
- this.cases = [];
- for (;;) {
- switch (nexttoken.id) {
- case 'case':
- switch (funct['(verb)']) {
- case 'break':
- case 'case':
- case 'continue':
- case 'return':
- case 'switch':
- case 'throw':
- break;
- default:
- warning(
- "Expected a 'break' statement before 'case'.",
- token);
- }
- indentation(-option.indent);
- advance('case');
- this.cases.push(parse(20));
- g = true;
- advance(':');
- funct['(verb)'] = 'case';
- break;
- case 'default':
- switch (funct['(verb)']) {
- case 'break':
- case 'continue':
- case 'return':
- case 'throw':
- break;
- default:
- warning(
- "Expected a 'break' statement before 'default'.",
- token);
- }
- indentation(-option.indent);
- advance('default');
- g = true;
- advance(':');
- break;
- case '}':
- indent -= option.indent;
- indentation();
- advance('}', t);
- if (this.cases.length === 1 || this.condition.id === 'true' ||
- this.condition.id === 'false') {
- warning("This 'switch' should be an 'if'.", this);
- }
- funct['(breakage)'] -= 1;
- funct['(verb)'] = undefined;
- return;
- case '(end)':
- error("Missing '{a}'.", nexttoken, '}');
- return;
- default:
- if (g) {
- switch (token.id) {
- case ',':
- error("Each value should have its own case label.");
- return;
- case ':':
- statements();
- break;
- default:
- error("Missing ':' on a case clause.", token);
- }
- } else {
- error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, 'case', nexttoken.value);
- }
- }
- }
- }).labelled = true;
-
- stmt('debugger', function () {
- if (!option.debug) {
- warning("All 'debugger' statements should be removed.");
- }
- return this;
- }).exps = true;
-
- (function () {
- var x = stmt('do', function () {
- funct['(breakage)'] += 1;
- funct['(loopage)'] += 1;
- this.first = block(true);
- advance('while');
- var t = nexttoken;
- nonadjacent(token, t);
- advance('(');
- nospace();
- parse(20);
- if (nexttoken.id === '=') {
- warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
- parse(20);
- }
- advance(')', t);
- nospace(prevtoken, token);
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
- return this;
- });
- x.labelled = true;
- x.exps = true;
- }());
-
- blockstmt('for', function () {
- var f = option.forin, s, t = nexttoken;
- funct['(breakage)'] += 1;
- funct['(loopage)'] += 1;
- advance('(');
- nonadjacent(this, t);
- nospace();
- if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
- if (nexttoken.id === 'var') {
- advance('var');
- varstatement(true);
- } else {
- switch (funct[nexttoken.value]) {
- case 'unused':
- funct[nexttoken.value] = 'var';
- break;
- case 'var':
- break;
- default:
- warning("Bad for in variable '{a}'.",
- nexttoken, nexttoken.value);
- }
- advance();
- }
- advance('in');
- parse(20);
- advance(')', t);
- s = block(true);
- if (!f && (s.length > 1 || typeof s[0] !== 'object' ||
- s[0].value !== 'if')) {
- warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this);
- }
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
- return this;
- } else {
- if (nexttoken.id !== ';') {
- if (nexttoken.id === 'var') {
- advance('var');
- varstatement();
- } else {
- for (;;) {
- parse(0, 'for');
- if (nexttoken.id !== ',') {
- break;
- }
- comma();
- }
- }
- }
- nolinebreak(token);
- advance(';');
- if (nexttoken.id !== ';') {
- parse(20);
- if (nexttoken.id === '=') {
- warning("Expected a conditional expression and instead saw an assignment.");
- advance('=');
- parse(20);
- }
- }
- nolinebreak(token);
- advance(';');
- if (nexttoken.id === ';') {
- error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, ')', ';');
- }
- if (nexttoken.id !== ')') {
- for (;;) {
- parse(0, 'for');
- if (nexttoken.id !== ',') {
- break;
- }
- comma();
- }
- }
- advance(')', t);
- nospace(prevtoken, token);
- block(true);
- funct['(breakage)'] -= 1;
- funct['(loopage)'] -= 1;
- return this;
- }
- }).labelled = true;
-
-
- stmt('break', function () {
- var v = nexttoken.value;
- if (funct['(breakage)'] === 0) {
- warning("Unexpected '{a}'.", nexttoken, this.value);
- }
- nolinebreak(this);
- if (nexttoken.id !== ';') {
- if (token.line === nexttoken.line) {
- if (funct[v] !== 'label') {
- warning("'{a}' is not a statement label.", nexttoken, v);
- } else if (scope[v] !== funct) {
- warning("'{a}' is out of scope.", nexttoken, v);
- }
- this.first = nexttoken;
- advance();
- }
- }
- reachable('break');
- return this;
- }).exps = true;
-
-
- stmt('continue', function () {
- var v = nexttoken.value;
- if (funct['(breakage)'] === 0) {
- warning("Unexpected '{a}'.", nexttoken, this.value);
- }
- nolinebreak(this);
- if (nexttoken.id !== ';') {
- if (token.line === nexttoken.line) {
- if (funct[v] !== 'label') {
- warning("'{a}' is not a statement label.", nexttoken, v);
- } else if (scope[v] !== funct) {
- warning("'{a}' is out of scope.", nexttoken, v);
- }
- this.first = nexttoken;
- advance();
- }
- } else if (!funct['(loopage)']) {
- warning("Unexpected '{a}'.", nexttoken, this.value);
- }
- reachable('continue');
- return this;
- }).exps = true;
-
-
- stmt('return', function () {
- nolinebreak(this);
- if (nexttoken.id === '(regexp)') {
- warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
- }
- if (nexttoken.id !== ';' && !nexttoken.reach) {
- nonadjacent(token, nexttoken);
- this.first = parse(20);
- }
- reachable('return');
- return this;
- }).exps = true;
-
-
- stmt('throw', function () {
- nolinebreak(this);
- nonadjacent(token, nexttoken);
- this.first = parse(20);
- reachable('throw');
- return this;
- }).exps = true;
-
- reserve('void');
-
-// Superfluous reserved words
-
- reserve('class');
- reserve('const');
- reserve('enum');
- reserve('export');
- reserve('extends');
- reserve('import');
- reserve('super');
-
- reserve('let');
- reserve('yield');
- reserve('implements');
- reserve('interface');
- reserve('package');
- reserve('private');
- reserve('protected');
- reserve('public');
- reserve('static');
-
- function jsonValue() {
-
- function jsonObject() {
- var o = {}, t = nexttoken;
- advance('{');
- if (nexttoken.id !== '}') {
- for (;;) {
- if (nexttoken.id === '(end)') {
- error("Missing '}' to match '{' from line {a}.",
- nexttoken, t.line);
- } else if (nexttoken.id === '}') {
- warning("Unexpected comma.", token);
- break;
- } else if (nexttoken.id === ',') {
- error("Unexpected comma.", nexttoken);
- } else if (nexttoken.id !== '(string)') {
- warning("Expected a string and instead saw {a}.",
- nexttoken, nexttoken.value);
- }
- if (o[nexttoken.value] === true) {
- warning("Duplicate key '{a}'.",
- nexttoken, nexttoken.value);
- } else if (nexttoken.value === '__proto__') {
- warning("Stupid key '{a}'.",
- nexttoken, nexttoken.value);
- } else {
- o[nexttoken.value] = true;
- }
- advance();
- advance(':');
- jsonValue();
- if (nexttoken.id !== ',') {
- break;
- }
- advance(',');
- }
- }
- advance('}');
- }
-
- function jsonArray() {
- var t = nexttoken;
- advance('[');
- if (nexttoken.id !== ']') {
- for (;;) {
- if (nexttoken.id === '(end)') {
- error("Missing ']' to match '[' from line {a}.",
- nexttoken, t.line);
- } else if (nexttoken.id === ']') {
- warning("Unexpected comma.", token);
- break;
- } else if (nexttoken.id === ',') {
- error("Unexpected comma.", nexttoken);
- }
- jsonValue();
- if (nexttoken.id !== ',') {
- break;
- }
- advance(',');
- }
- }
- advance(']');
- }
-
- switch (nexttoken.id) {
- case '{':
- jsonObject();
- break;
- case '[':
- jsonArray();
- break;
- case 'true':
- case 'false':
- case 'null':
- case '(number)':
- case '(string)':
- advance();
- break;
- case '-':
- advance('-');
- if (token.character !== nexttoken.from) {
- warning("Unexpected space after '-'.", token);
- }
- adjacent(token, nexttoken);
- advance('(number)');
- break;
- default:
- error("Expected a JSON value.", nexttoken);
- }
- }
-
-
-// The actual JSLINT function itself.
-
- var itself = function (s, o) {
- var a, i;
- JSLINT.errors = [];
- predefined = Object.create(standard);
- if (o) {
- a = o.predef;
- if (a instanceof Array) {
- for (i = 0; i < a.length; i += 1) {
- predefined[a[i]] = true;
- }
- }
- if (o.adsafe) {
- o.safe = true;
- }
- if (o.safe) {
- o.browser = false;
- o.css = false;
- o.debug = false;
- o.devel = false;
- o.eqeqeq = true;
- o.evil = false;
- o.forin = false;
- o.nomen = true;
- o.on = false;
- o.rhino = false;
- o.safe = true;
- o.sidebar = false;
- o.strict = true;
- o.sub = false;
- o.undef = true;
- o.widget = false;
- predefined.Date = null;
- predefined['eval'] = null;
- predefined.Function = null;
- predefined.Object = null;
- predefined.ADSAFE = false;
- predefined.lib = false;
- }
- option = o;
- } else {
- option = {};
- }
- option.indent = option.indent || 4;
- option.maxerr = option.maxerr || 50;
- adsafe_id = '';
- adsafe_may = false;
- adsafe_went = false;
- approved = {};
- if (option.approved) {
- for (i = 0; i < option.approved.length; i += 1) {
- approved[option.approved[i]] = option.approved[i];
- }
- } else {
- approved.test = 'test';
- }
- tab = '';
- for (i = 0; i < option.indent; i += 1) {
- tab += ' ';
- }
- indent = 1;
- global = Object.create(predefined);
- scope = global;
- funct = {
- '(global)': true,
- '(name)': '(global)',
- '(scope)': scope,
- '(breakage)': 0,
- '(loopage)': 0
- };
- functions = [funct];
- ids = {};
- urls = [];
- src = false;
- xmode = false;
- stack = null;
- member = {};
- membersOnly = null;
- implied = {};
- inblock = false;
- lookahead = [];
- jsonmode = false;
- warnings = 0;
- lex.init(s);
- prereg = true;
- strict_mode = false;
-
- prevtoken = token = nexttoken = syntax['(begin)'];
- assume();
-
- try {
- advance();
- if (nexttoken.value.charAt(0) === '<') {
- html();
- if (option.adsafe && !adsafe_went) {
- warning("ADsafe violation: Missing ADSAFE.go.", this);
- }
- } else {
- switch (nexttoken.id) {
- case '{':
- case '[':
- option.laxbreak = true;
- jsonmode = true;
- jsonValue();
- break;
- case '@':
- case '*':
- case '#':
- case '.':
- case ':':
- xmode = 'style';
- advance();
- if (token.id !== '@' || !nexttoken.identifier ||
- nexttoken.value !== 'charset' || token.line !== 1 ||
- token.from !== 1) {
- error('A css file should begin with @charset "UTF-8";');
- }
- advance();
- if (nexttoken.type !== '(string)' &&
- nexttoken.value !== 'UTF-8') {
- error('A css file should begin with @charset "UTF-8";');
- }
- advance();
- advance(';');
- styles();
- break;
-
- default:
- if (option.adsafe && option.fragment) {
- error("Expected '{a}' and instead saw '{b}'.",
- nexttoken, '
', nexttoken.value);
- }
- statements('lib');
- }
- }
- advance('(end)');
- } catch (e) {
- if (e) {
- JSLINT.errors.push({
- reason : e.message,
- line : e.line || nexttoken.line,
- character : e.character || nexttoken.from
- }, null);
- }
- }
- return JSLINT.errors.length === 0;
- };
-
- function is_array(o) {
- return Object.prototype.toString.apply(o) === '[object Array]';
- }
-
- function to_array(o) {
- var a = [], k;
- for (k in o) {
- if (is_own(o, k)) {
- a.push(k);
- }
- }
- return a;
- }
-
-// Data summary.
-
- itself.data = function () {
-
- var data = {functions: []}, fu, globals, implieds = [], f, i, j,
- members = [], n, unused = [], v;
- if (itself.errors.length) {
- data.errors = itself.errors;
- }
-
- if (jsonmode) {
- data.json = true;
- }
-
- for (n in implied) {
- if (is_own(implied, n)) {
- implieds.push({
- name: n,
- line: implied[n]
- });
- }
- }
- if (implieds.length > 0) {
- data.implieds = implieds;
- }
-
- if (urls.length > 0) {
- data.urls = urls;
- }
-
- globals = to_array(scope);
- if (globals.length > 0) {
- data.globals = globals;
- }
-
- for (i = 1; i < functions.length; i += 1) {
- f = functions[i];
- fu = {};
- for (j = 0; j < functionicity.length; j += 1) {
- fu[functionicity[j]] = [];
- }
- for (n in f) {
- if (is_own(f, n) && n.charAt(0) !== '(') {
- v = f[n];
- if (is_array(fu[v])) {
- fu[v].push(n);
- if (v === 'unused') {
- unused.push({
- name: n,
- line: f['(line)'],
- 'function': f['(name)']
- });
- }
- }
- }
- }
- for (j = 0; j < functionicity.length; j += 1) {
- if (fu[functionicity[j]].length === 0) {
- delete fu[functionicity[j]];
- }
- }
- fu.name = f['(name)'];
- fu.param = f['(params)'];
- fu.line = f['(line)'];
- fu.last = f['(last)'];
- data.functions.push(fu);
- }
-
- if (unused.length > 0) {
- data.unused = unused;
- }
-
- members = [];
- for (n in member) {
- if (typeof member[n] === 'number') {
- data.member = member;
- break;
- }
- }
-
- return data;
- };
-
- itself.report = function (option) {
- var data = itself.data();
-
- var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s;
-
- function detail(h, array) {
- var b, i, singularity;
- if (array) {
- o.push('
' + h + ' ');
- array = array.sort();
- for (i = 0; i < array.length; i += 1) {
- if (array[i] !== singularity) {
- singularity = array[i];
- o.push((b ? ', ' : '') + singularity);
- b = true;
- }
- }
- o.push('
');
- }
- }
-
-
- if (data.errors || data.implieds || data.unused) {
- err = true;
- o.push('
Error: ');
- if (data.errors) {
- for (i = 0; i < data.errors.length; i += 1) {
- c = data.errors[i];
- if (c) {
- e = c.evidence || '';
- o.push('
Problem' + (isFinite(c.line) ? ' at line ' +
- c.line + ' character ' + c.character : '') +
- ': ' + c.reason.entityify() +
- '
' +
- (e && (e.length > 80 ? e.slice(0, 77) + '...' :
- e).entityify()) + '
');
- }
- }
- }
-
- if (data.implieds) {
- s = [];
- for (i = 0; i < data.implieds.length; i += 1) {
- s[i] = '
' + data.implieds[i].name + '
' +
- data.implieds[i].line + ' ';
- }
- o.push('
Implied global: ' + s.join(', ') + '
');
- }
-
- if (data.unused) {
- s = [];
- for (i = 0; i < data.unused.length; i += 1) {
- s[i] = '
' + data.unused[i].name + '
' +
- data.unused[i].line + ' ' +
- data.unused[i]['function'] + '
';
- }
- o.push('
Unused variable: ' + s.join(', ') + '
');
- }
- if (data.json) {
- o.push('
JSON: bad.
');
- }
- o.push('
');
- }
-
- if (!option) {
-
- o.push('
');
-
- if (data.urls) {
- detail("URLs
", data.urls, '
');
- }
-
- if (xmode === 'style') {
- o.push('
CSS.
');
- } else if (data.json && !err) {
- o.push('
JSON: good.
');
- } else if (data.globals) {
- o.push('
Global ' +
- data.globals.sort().join(', ') + '
');
- } else {
- o.push('
No new global variables introduced.
');
- }
-
- for (i = 0; i < data.functions.length; i += 1) {
- f = data.functions[i];
-
- o.push('
' + f.line + '-' +
- f.last + ' ' + (f.name || '') + '(' +
- (f.param ? f.param.join(', ') : '') + ')
');
- detail('
Unused ', f.unused);
- detail('Closure', f.closure);
- detail('Variable', f['var']);
- detail('Exception', f.exception);
- detail('Outer', f.outer);
- detail('Global', f.global);
- detail('Label', f.label);
- }
-
- if (data.member) {
- a = to_array(data.member);
- if (a.length) {
- a = a.sort();
- m = '
/*members ';
- l = 10;
- for (i = 0; i < a.length; i += 1) {
- k = a[i];
- n = k.name();
- if (l + n.length > 72) {
- o.push(m + ' ');
- m = ' ';
- l = 1;
- }
- l += n.length + 2;
- if (data.member[k] === 1) {
- n = '' + n + ' ';
- }
- if (i < a.length - 1) {
- n += ', ';
- }
- m += n;
- }
- o.push(m + ' */ ');
- }
- o.push('
');
- }
- }
- return o.join('');
- };
- itself.jslint = itself;
-
- itself.edition = '2010-02-20';
-
- if (typeof exports !== "undefined") {
- exports.JSLINT = itself;
- }
-
- return itself;
-
-}());
diff --git a/build/lib/parse-js.js b/build/lib/parse-js.js
deleted file mode 100644
index 8edecb73..00000000
--- a/build/lib/parse-js.js
+++ /dev/null
@@ -1,1315 +0,0 @@
-/***********************************************************************
-
- A JavaScript tokenizer / parser / beautifier / compressor.
-
- This version is suitable for Node.js. With minimal changes (the
- exports stuff) it should work on any JS platform.
-
- This file contains the tokenizer/parser. It is a port to JavaScript
- of parse-js [1], a JavaScript parser library written in Common Lisp
- by Marijn Haverbeke. Thank you Marijn!
-
- [1] http://marijn.haverbeke.nl/parse-js/
-
- Exported functions:
-
- - tokenizer(code) -- returns a function. Call the returned
- function to fetch the next token.
-
- - parse(code) -- returns an AST of the given JavaScript code.
-
- -------------------------------- (C) ---------------------------------
-
- Author: Mihai Bazon
-
- http://mihai.bazon.net/blog
-
- Distributed under the BSD license:
-
- Copyright 2010 (c) Mihai Bazon
- Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
-
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
- ***********************************************************************/
-
-/* -----[ Tokenizer (constants) ]----- */
-
-var KEYWORDS = array_to_hash([
- "break",
- "case",
- "catch",
- "const",
- "continue",
- "default",
- "delete",
- "do",
- "else",
- "finally",
- "for",
- "function",
- "if",
- "in",
- "instanceof",
- "new",
- "return",
- "switch",
- "throw",
- "try",
- "typeof",
- "var",
- "void",
- "while",
- "with"
-]);
-
-var RESERVED_WORDS = array_to_hash([
- "abstract",
- "boolean",
- "byte",
- "char",
- "class",
- "debugger",
- "double",
- "enum",
- "export",
- "extends",
- "final",
- "float",
- "goto",
- "implements",
- "import",
- "int",
- "interface",
- "long",
- "native",
- "package",
- "private",
- "protected",
- "public",
- "short",
- "static",
- "super",
- "synchronized",
- "throws",
- "transient",
- "volatile"
-]);
-
-var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
- "return",
- "new",
- "delete",
- "throw",
- "else",
- "case"
-]);
-
-var KEYWORDS_ATOM = array_to_hash([
- "false",
- "null",
- "true",
- "undefined"
-]);
-
-var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
-
-var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
-var RE_OCT_NUMBER = /^0[0-7]+$/;
-var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
-
-var OPERATORS = array_to_hash([
- "in",
- "instanceof",
- "typeof",
- "new",
- "void",
- "delete",
- "++",
- "--",
- "+",
- "-",
- "!",
- "~",
- "&",
- "|",
- "^",
- "*",
- "/",
- "%",
- ">>",
- "<<",
- ">>>",
- "<",
- ">",
- "<=",
- ">=",
- "==",
- "===",
- "!=",
- "!==",
- "?",
- "=",
- "+=",
- "-=",
- "/=",
- "*=",
- "%=",
- ">>=",
- "<<=",
- ">>>=",
- "|=",
- "^=",
- "&=",
- "&&",
- "||"
-]);
-
-var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t\u200b"));
-
-var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
-
-var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
-
-var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
-
-/* -----[ Tokenizer ]----- */
-
-// regexps adapted from http://xregexp.com/plugins/#unicode
-var UNICODE = {
- letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),
- non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"),
- space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"),
- connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]")
-};
-
-function is_letter(ch) {
- return UNICODE.letter.test(ch);
-};
-
-function is_digit(ch) {
- ch = ch.charCodeAt(0);
- return ch >= 48 && ch <= 57; //XXX: find out if "UnicodeDigit" means something else than 0..9
-};
-
-function is_alphanumeric_char(ch) {
- return is_digit(ch) || is_letter(ch);
-};
-
-function is_unicode_combining_mark(ch) {
- return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
-};
-
-function is_unicode_connector_punctuation(ch) {
- return UNICODE.connector_punctuation.test(ch);
-};
-
-function is_identifier_start(ch) {
- return ch == "$" || ch == "_" || is_letter(ch);
-};
-
-function is_identifier_char(ch) {
- return is_identifier_start(ch)
- || is_unicode_combining_mark(ch)
- || is_digit(ch)
- || is_unicode_connector_punctuation(ch)
- || ch == "\u200c" // zero-width non-joiner
- || ch == "\u200d" // zero-width joiner (in my ECMA-262 PDF, this is also 200c)
- ;
-};
-
-function parse_js_number(num) {
- if (RE_HEX_NUMBER.test(num)) {
- return parseInt(num.substr(2), 16);
- } else if (RE_OCT_NUMBER.test(num)) {
- return parseInt(num.substr(1), 8);
- } else if (RE_DEC_NUMBER.test(num)) {
- return parseFloat(num);
- }
-};
-
-function JS_Parse_Error(message, line, col, pos) {
- this.message = message;
- this.line = line;
- this.col = col;
- this.pos = pos;
- try {
- ({})();
- } catch(ex) {
- this.stack = ex.stack;
- };
-};
-
-JS_Parse_Error.prototype.toString = function() {
- return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack;
-};
-
-function js_error(message, line, col, pos) {
- throw new JS_Parse_Error(message, line, col, pos);
-};
-
-function is_token(token, type, val) {
- return token.type == type && (val == null || token.value == val);
-};
-
-var EX_EOF = {};
-
-function tokenizer($TEXT) {
-
- var S = {
- text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
- pos : 0,
- tokpos : 0,
- line : 0,
- tokline : 0,
- col : 0,
- tokcol : 0,
- newline_before : false,
- regex_allowed : false,
- comments_before : []
- };
-
- function peek() { return S.text.charAt(S.pos); };
-
- function next(signal_eof) {
- var ch = S.text.charAt(S.pos++);
- if (signal_eof && !ch)
- throw EX_EOF;
- if (ch == "\n") {
- S.newline_before = true;
- ++S.line;
- S.col = 0;
- } else {
- ++S.col;
- }
- return ch;
- };
-
- function eof() {
- return !S.peek();
- };
-
- function find(what, signal_eof) {
- var pos = S.text.indexOf(what, S.pos);
- if (signal_eof && pos == -1) throw EX_EOF;
- return pos;
- };
-
- function start_token() {
- S.tokline = S.line;
- S.tokcol = S.col;
- S.tokpos = S.pos;
- };
-
- function token(type, value, is_comment) {
- S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
- (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
- (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
- var ret = {
- type : type,
- value : value,
- line : S.tokline,
- col : S.tokcol,
- pos : S.tokpos,
- nlb : S.newline_before
- };
- if (!is_comment) {
- ret.comments_before = S.comments_before;
- S.comments_before = [];
- }
- S.newline_before = false;
- return ret;
- };
-
- function skip_whitespace() {
- while (HOP(WHITESPACE_CHARS, peek()))
- next();
- };
-
- function read_while(pred) {
- var ret = "", ch = peek(), i = 0;
- while (ch && pred(ch, i++)) {
- ret += next();
- ch = peek();
- }
- return ret;
- };
-
- function parse_error(err) {
- js_error(err, S.tokline, S.tokcol, S.tokpos);
- };
-
- function read_num(prefix) {
- var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
- var num = read_while(function(ch, i){
- if (ch == "x" || ch == "X") {
- if (has_x) return false;
- return has_x = true;
- }
- if (!has_x && (ch == "E" || ch == "e")) {
- if (has_e) return false;
- return has_e = after_e = true;
- }
- if (ch == "-") {
- if (after_e || (i == 0 && !prefix)) return true;
- return false;
- }
- if (ch == "+") return after_e;
- after_e = false;
- if (ch == ".") {
- if (!has_dot && !has_x)
- return has_dot = true;
- return false;
- }
- return is_alphanumeric_char(ch);
- });
- if (prefix)
- num = prefix + num;
- var valid = parse_js_number(num);
- if (!isNaN(valid)) {
- return token("num", valid);
- } else {
- parse_error("Invalid syntax: " + num);
- }
- };
-
- function read_escaped_char() {
- var ch = next(true);
- switch (ch) {
- case "n" : return "\n";
- case "r" : return "\r";
- case "t" : return "\t";
- case "b" : return "\b";
- case "v" : return "\v";
- case "f" : return "\f";
- case "0" : return "\0";
- case "x" : return String.fromCharCode(hex_bytes(2));
- case "u" : return String.fromCharCode(hex_bytes(4));
- default : return ch;
- }
- };
-
- function hex_bytes(n) {
- var num = 0;
- for (; n > 0; --n) {
- var digit = parseInt(next(true), 16);
- if (isNaN(digit))
- parse_error("Invalid hex-character pattern in string");
- num = (num << 4) | digit;
- }
- return num;
- };
-
- function read_string() {
- return with_eof_error("Unterminated string constant", function(){
- var quote = next(), ret = "";
- for (;;) {
- var ch = next(true);
- if (ch == "\\") ch = read_escaped_char();
- else if (ch == quote) break;
- ret += ch;
- }
- return token("string", ret);
- });
- };
-
- function read_line_comment() {
- next();
- var i = find("\n"), ret;
- if (i == -1) {
- ret = S.text.substr(S.pos);
- S.pos = S.text.length;
- } else {
- ret = S.text.substring(S.pos, i);
- S.pos = i;
- }
- return token("comment1", ret, true);
- };
-
- function read_multiline_comment() {
- next();
- return with_eof_error("Unterminated multiline comment", function(){
- var i = find("*/", true),
- text = S.text.substring(S.pos, i),
- tok = token("comment2", text, true);
- S.pos = i + 2;
- S.line += text.split("\n").length - 1;
- S.newline_before = text.indexOf("\n") >= 0;
-
- // https://github.com/mishoo/UglifyJS/issues/#issue/100
- if (/^@cc_on/i.test(text)) {
- warn("WARNING: at line " + S.line);
- warn("*** Found \"conditional comment\": " + text);
- warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer.");
- }
-
- return tok;
- });
- };
-
- function read_name() {
- var backslash = false, name = "", ch;
- while ((ch = peek()) != null) {
- if (!backslash) {
- if (ch == "\\") backslash = true, next();
- else if (is_identifier_char(ch)) name += next();
- else break;
- }
- else {
- if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
- ch = read_escaped_char();
- if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
- name += ch;
- backslash = false;
- }
- }
- return name;
- };
-
- function read_regexp() {
- return with_eof_error("Unterminated regular expression", function(){
- var prev_backslash = false, regexp = "", ch, in_class = false;
- while ((ch = next(true))) if (prev_backslash) {
- regexp += "\\" + ch;
- prev_backslash = false;
- } else if (ch == "[") {
- in_class = true;
- regexp += ch;
- } else if (ch == "]" && in_class) {
- in_class = false;
- regexp += ch;
- } else if (ch == "/" && !in_class) {
- break;
- } else if (ch == "\\") {
- prev_backslash = true;
- } else {
- regexp += ch;
- }
- var mods = read_name();
- return token("regexp", [ regexp, mods ]);
- });
- };
-
- function read_operator(prefix) {
- function grow(op) {
- if (!peek()) return op;
- var bigger = op + peek();
- if (HOP(OPERATORS, bigger)) {
- next();
- return grow(bigger);
- } else {
- return op;
- }
- };
- return token("operator", grow(prefix || next()));
- };
-
- function handle_slash() {
- next();
- var regex_allowed = S.regex_allowed;
- switch (peek()) {
- case "/":
- S.comments_before.push(read_line_comment());
- S.regex_allowed = regex_allowed;
- return next_token();
- case "*":
- S.comments_before.push(read_multiline_comment());
- S.regex_allowed = regex_allowed;
- return next_token();
- }
- return S.regex_allowed ? read_regexp() : read_operator("/");
- };
-
- function handle_dot() {
- next();
- return is_digit(peek())
- ? read_num(".")
- : token("punc", ".");
- };
-
- function read_word() {
- var word = read_name();
- return !HOP(KEYWORDS, word)
- ? token("name", word)
- : HOP(OPERATORS, word)
- ? token("operator", word)
- : HOP(KEYWORDS_ATOM, word)
- ? token("atom", word)
- : token("keyword", word);
- };
-
- function with_eof_error(eof_error, cont) {
- try {
- return cont();
- } catch(ex) {
- if (ex === EX_EOF) parse_error(eof_error);
- else throw ex;
- }
- };
-
- function next_token(force_regexp) {
- if (force_regexp)
- return read_regexp();
- skip_whitespace();
- start_token();
- var ch = peek();
- if (!ch) return token("eof");
- if (is_digit(ch)) return read_num();
- if (ch == '"' || ch == "'") return read_string();
- if (HOP(PUNC_CHARS, ch)) return token("punc", next());
- if (ch == ".") return handle_dot();
- if (ch == "/") return handle_slash();
- if (HOP(OPERATOR_CHARS, ch)) return read_operator();
- if (ch == "\\" || is_identifier_start(ch)) return read_word();
- parse_error("Unexpected character '" + ch + "'");
- };
-
- next_token.context = function(nc) {
- if (nc) S = nc;
- return S;
- };
-
- return next_token;
-
-};
-
-/* -----[ Parser (constants) ]----- */
-
-var UNARY_PREFIX = array_to_hash([
- "typeof",
- "void",
- "delete",
- "--",
- "++",
- "!",
- "~",
- "-",
- "+"
-]);
-
-var UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
-
-var ASSIGNMENT = (function(a, ret, i){
- while (i < a.length) {
- ret[a[i]] = a[i].substr(0, a[i].length - 1);
- i++;
- }
- return ret;
-})(
- ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="],
- { "=": true },
- 0
-);
-
-var PRECEDENCE = (function(a, ret){
- for (var i = 0, n = 1; i < a.length; ++i, ++n) {
- var b = a[i];
- for (var j = 0; j < b.length; ++j) {
- ret[b[j]] = n;
- }
- }
- return ret;
-})(
- [
- ["||"],
- ["&&"],
- ["|"],
- ["^"],
- ["&"],
- ["==", "===", "!=", "!=="],
- ["<", ">", "<=", ">=", "in", "instanceof"],
- [">>", "<<", ">>>"],
- ["+", "-"],
- ["*", "/", "%"]
- ],
- {}
-);
-
-var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
-
-var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
-
-/* -----[ Parser ]----- */
-
-function NodeWithToken(str, start, end) {
- this.name = str;
- this.start = start;
- this.end = end;
-};
-
-NodeWithToken.prototype.toString = function() { return this.name; };
-
-function parse($TEXT, exigent_mode, embed_tokens) {
-
- var S = {
- input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT,
- token : null,
- prev : null,
- peeked : null,
- in_function : 0,
- in_loop : 0,
- labels : []
- };
-
- S.token = next();
-
- function is(type, value) {
- return is_token(S.token, type, value);
- };
-
- function peek() { return S.peeked || (S.peeked = S.input()); };
-
- function next() {
- S.prev = S.token;
- if (S.peeked) {
- S.token = S.peeked;
- S.peeked = null;
- } else {
- S.token = S.input();
- }
- return S.token;
- };
-
- function prev() {
- return S.prev;
- };
-
- function croak(msg, line, col, pos) {
- var ctx = S.input.context();
- js_error(msg,
- line != null ? line : ctx.tokline,
- col != null ? col : ctx.tokcol,
- pos != null ? pos : ctx.tokpos);
- };
-
- function token_error(token, msg) {
- croak(msg, token.line, token.col);
- };
-
- function unexpected(token) {
- if (token == null)
- token = S.token;
- token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
- };
-
- function expect_token(type, val) {
- if (is(type, val)) {
- return next();
- }
- token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
- };
-
- function expect(punc) { return expect_token("punc", punc); };
-
- function can_insert_semicolon() {
- return !exigent_mode && (
- S.token.nlb || is("eof") || is("punc", "}")
- );
- };
-
- function semicolon() {
- if (is("punc", ";")) next();
- else if (!can_insert_semicolon()) unexpected();
- };
-
- function as() {
- return slice(arguments);
- };
-
- function parenthesised() {
- expect("(");
- var ex = expression();
- expect(")");
- return ex;
- };
-
- function add_tokens(str, start, end) {
- return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
- };
-
- function maybe_embed_tokens(parser) {
- if (embed_tokens) return function() {
- var start = S.token;
- var ast = parser.apply(this, arguments);
- ast[0] = add_tokens(ast[0], start, prev());
- return ast;
- };
- else return parser;
- };
-
- var statement = maybe_embed_tokens(function() {
- if (is("operator", "/")) {
- S.peeked = null;
- S.token = S.input(true); // force regexp
- }
- switch (S.token.type) {
- case "num":
- case "string":
- case "regexp":
- case "operator":
- case "atom":
- return simple_statement();
-
- case "name":
- return is_token(peek(), "punc", ":")
- ? labeled_statement(prog1(S.token.value, next, next))
- : simple_statement();
-
- case "punc":
- switch (S.token.value) {
- case "{":
- return as("block", block_());
- case "[":
- case "(":
- return simple_statement();
- case ";":
- next();
- return as("block");
- default:
- unexpected();
- }
-
- case "keyword":
- switch (prog1(S.token.value, next)) {
- case "break":
- return break_cont("break");
-
- case "continue":
- return break_cont("continue");
-
- case "debugger":
- semicolon();
- return as("debugger");
-
- case "do":
- return (function(body){
- expect_token("keyword", "while");
- return as("do", prog1(parenthesised, semicolon), body);
- })(in_loop(statement));
-
- case "for":
- return for_();
-
- case "function":
- return function_(true);
-
- case "if":
- return if_();
-
- case "return":
- if (S.in_function == 0)
- croak("'return' outside of function");
- return as("return",
- is("punc", ";")
- ? (next(), null)
- : can_insert_semicolon()
- ? null
- : prog1(expression, semicolon));
-
- case "switch":
- return as("switch", parenthesised(), switch_block_());
-
- case "throw":
- return as("throw", prog1(expression, semicolon));
-
- case "try":
- return try_();
-
- case "var":
- return prog1(var_, semicolon);
-
- case "const":
- return prog1(const_, semicolon);
-
- case "while":
- return as("while", parenthesised(), in_loop(statement));
-
- case "with":
- return as("with", parenthesised(), statement());
-
- default:
- unexpected();
- }
- }
- });
-
- function labeled_statement(label) {
- S.labels.push(label);
- var start = S.token, stat = statement();
- if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
- unexpected(start);
- S.labels.pop();
- return as("label", label, stat);
- };
-
- function simple_statement() {
- return as("stat", prog1(expression, semicolon));
- };
-
- function break_cont(type) {
- var name = is("name") ? S.token.value : null;
- if (name != null) {
- next();
- if (!member(name, S.labels))
- croak("Label " + name + " without matching loop or statement");
- }
- else if (S.in_loop == 0)
- croak(type + " not inside a loop or switch");
- semicolon();
- return as(type, name);
- };
-
- function for_() {
- expect("(");
- var init = null;
- if (!is("punc", ";")) {
- init = is("keyword", "var")
- ? (next(), var_(true))
- : expression(true, true);
- if (is("operator", "in"))
- return for_in(init);
- }
- return regular_for(init);
- };
-
- function regular_for(init) {
- expect(";");
- var test = is("punc", ";") ? null : expression();
- expect(";");
- var step = is("punc", ")") ? null : expression();
- expect(")");
- return as("for", init, test, step, in_loop(statement));
- };
-
- function for_in(init) {
- var lhs = init[0] == "var" ? as("name", init[1][0]) : init;
- next();
- var obj = expression();
- expect(")");
- return as("for-in", init, lhs, obj, in_loop(statement));
- };
-
- var function_ = maybe_embed_tokens(function(in_statement) {
- var name = is("name") ? prog1(S.token.value, next) : null;
- if (in_statement && !name)
- unexpected();
- expect("(");
- return as(in_statement ? "defun" : "function",
- name,
- // arguments
- (function(first, a){
- while (!is("punc", ")")) {
- if (first) first = false; else expect(",");
- if (!is("name")) unexpected();
- a.push(S.token.value);
- next();
- }
- next();
- return a;
- })(true, []),
- // body
- (function(){
- ++S.in_function;
- var loop = S.in_loop;
- S.in_loop = 0;
- var a = block_();
- --S.in_function;
- S.in_loop = loop;
- return a;
- })());
- });
-
- function if_() {
- var cond = parenthesised(), body = statement(), belse;
- if (is("keyword", "else")) {
- next();
- belse = statement();
- }
- return as("if", cond, body, belse);
- };
-
- function block_() {
- expect("{");
- var a = [];
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- a.push(statement());
- }
- next();
- return a;
- };
-
- var switch_block_ = curry(in_loop, function(){
- expect("{");
- var a = [], cur = null;
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- if (is("keyword", "case")) {
- next();
- cur = [];
- a.push([ expression(), cur ]);
- expect(":");
- }
- else if (is("keyword", "default")) {
- next();
- expect(":");
- cur = [];
- a.push([ null, cur ]);
- }
- else {
- if (!cur) unexpected();
- cur.push(statement());
- }
- }
- next();
- return a;
- });
-
- function try_() {
- var body = block_(), bcatch, bfinally;
- if (is("keyword", "catch")) {
- next();
- expect("(");
- if (!is("name"))
- croak("Name expected");
- var name = S.token.value;
- next();
- expect(")");
- bcatch = [ name, block_() ];
- }
- if (is("keyword", "finally")) {
- next();
- bfinally = block_();
- }
- if (!bcatch && !bfinally)
- croak("Missing catch/finally blocks");
- return as("try", body, bcatch, bfinally);
- };
-
- function vardefs(no_in) {
- var a = [];
- for (;;) {
- if (!is("name"))
- unexpected();
- var name = S.token.value;
- next();
- if (is("operator", "=")) {
- next();
- a.push([ name, expression(false, no_in) ]);
- } else {
- a.push([ name ]);
- }
- if (!is("punc", ","))
- break;
- next();
- }
- return a;
- };
-
- function var_(no_in) {
- return as("var", vardefs(no_in));
- };
-
- function const_() {
- return as("const", vardefs());
- };
-
- function new_() {
- var newexp = expr_atom(false), args;
- if (is("punc", "(")) {
- next();
- args = expr_list(")");
- } else {
- args = [];
- }
- return subscripts(as("new", newexp, args), true);
- };
-
- var expr_atom = maybe_embed_tokens(function(allow_calls) {
- if (is("operator", "new")) {
- next();
- return new_();
- }
- if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
- return make_unary("unary-prefix",
- prog1(S.token.value, next),
- expr_atom(allow_calls));
- }
- if (is("punc")) {
- switch (S.token.value) {
- case "(":
- next();
- return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
- case "[":
- next();
- return subscripts(array_(), allow_calls);
- case "{":
- next();
- return subscripts(object_(), allow_calls);
- }
- unexpected();
- }
- if (is("keyword", "function")) {
- next();
- return subscripts(function_(false), allow_calls);
- }
- if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
- var atom = S.token.type == "regexp"
- ? as("regexp", S.token.value[0], S.token.value[1])
- : as(S.token.type, S.token.value);
- return subscripts(prog1(atom, next), allow_calls);
- }
- unexpected();
- });
-
- function expr_list(closing, allow_trailing_comma, allow_empty) {
- var first = true, a = [];
- while (!is("punc", closing)) {
- if (first) first = false; else expect(",");
- if (allow_trailing_comma && is("punc", closing)) break;
- if (is("punc", ",") && allow_empty) {
- a.push([ "atom", "undefined" ]);
- } else {
- a.push(expression(false));
- }
- }
- next();
- return a;
- };
-
- function array_() {
- return as("array", expr_list("]", !exigent_mode, true));
- };
-
- function object_() {
- var first = true, a = [];
- while (!is("punc", "}")) {
- if (first) first = false; else expect(",");
- if (!exigent_mode && is("punc", "}"))
- // allow trailing comma
- break;
- var type = S.token.type;
- var name = as_property_name();
- if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
- a.push([ as_name(), function_(false), name ]);
- } else {
- expect(":");
- a.push([ name, expression(false) ]);
- }
- }
- next();
- return as("object", a);
- };
-
- function as_property_name() {
- switch (S.token.type) {
- case "num":
- case "string":
- return prog1(S.token.value, next);
- }
- return as_name();
- };
-
- function as_name() {
- switch (S.token.type) {
- case "name":
- case "operator":
- case "keyword":
- case "atom":
- return prog1(S.token.value, next);
- default:
- unexpected();
- }
- };
-
- function subscripts(expr, allow_calls) {
- if (is("punc", ".")) {
- next();
- return subscripts(as("dot", expr, as_name()), allow_calls);
- }
- if (is("punc", "[")) {
- next();
- return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
- }
- if (allow_calls && is("punc", "(")) {
- next();
- return subscripts(as("call", expr, expr_list(")")), true);
- }
- if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) {
- return prog1(curry(make_unary, "unary-postfix", S.token.value, expr),
- next);
- }
- return expr;
- };
-
- function make_unary(tag, op, expr) {
- if ((op == "++" || op == "--") && !is_assignable(expr))
- croak("Invalid use of " + op + " operator");
- return as(tag, op, expr);
- };
-
- function expr_op(left, min_prec, no_in) {
- var op = is("operator") ? S.token.value : null;
- if (op && op == "in" && no_in) op = null;
- var prec = op != null ? PRECEDENCE[op] : null;
- if (prec != null && prec > min_prec) {
- next();
- var right = expr_op(expr_atom(true), prec, no_in);
- return expr_op(as("binary", op, left, right), min_prec, no_in);
- }
- return left;
- };
-
- function expr_ops(no_in) {
- return expr_op(expr_atom(true), 0, no_in);
- };
-
- function maybe_conditional(no_in) {
- var expr = expr_ops(no_in);
- if (is("operator", "?")) {
- next();
- var yes = expression(false);
- expect(":");
- return as("conditional", expr, yes, expression(false, no_in));
- }
- return expr;
- };
-
- function is_assignable(expr) {
- if (!exigent_mode) return true;
- switch (expr[0]) {
- case "dot":
- case "sub":
- case "new":
- case "call":
- return true;
- case "name":
- return expr[1] != "this";
- }
- };
-
- function maybe_assign(no_in) {
- var left = maybe_conditional(no_in), val = S.token.value;
- if (is("operator") && HOP(ASSIGNMENT, val)) {
- if (is_assignable(left)) {
- next();
- return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in));
- }
- croak("Invalid assignment");
- }
- return left;
- };
-
- var expression = maybe_embed_tokens(function(commas, no_in) {
- if (arguments.length == 0)
- commas = true;
- var expr = maybe_assign(no_in);
- if (commas && is("punc", ",")) {
- next();
- return as("seq", expr, expression(true, no_in));
- }
- return expr;
- });
-
- function in_loop(cont) {
- try {
- ++S.in_loop;
- return cont();
- } finally {
- --S.in_loop;
- }
- };
-
- return as("toplevel", (function(a){
- while (!is("eof"))
- a.push(statement());
- return a;
- })([]));
-
-};
-
-/* -----[ Utilities ]----- */
-
-function curry(f) {
- var args = slice(arguments, 1);
- return function() { return f.apply(this, args.concat(slice(arguments))); };
-};
-
-function prog1(ret) {
- if (ret instanceof Function)
- ret = ret();
- for (var i = 1, n = arguments.length; --n > 0; ++i)
- arguments[i]();
- return ret;
-};
-
-function array_to_hash(a) {
- var ret = {};
- for (var i = 0; i < a.length; ++i)
- ret[a[i]] = true;
- return ret;
-};
-
-function slice(a, start) {
- return Array.prototype.slice.call(a, start == null ? 0 : start);
-};
-
-function characters(str) {
- return str.split("");
-};
-
-function member(name, array) {
- for (var i = array.length; --i >= 0;)
- if (array[i] === name)
- return true;
- return false;
-};
-
-function HOP(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-};
-
-var warn = function() {};
-
-/* -----[ Exports ]----- */
-
-exports.tokenizer = tokenizer;
-exports.parse = parse;
-exports.slice = slice;
-exports.curry = curry;
-exports.member = member;
-exports.array_to_hash = array_to_hash;
-exports.PRECEDENCE = PRECEDENCE;
-exports.KEYWORDS_ATOM = KEYWORDS_ATOM;
-exports.RESERVED_WORDS = RESERVED_WORDS;
-exports.KEYWORDS = KEYWORDS;
-exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
-exports.OPERATORS = OPERATORS;
-exports.is_alphanumeric_char = is_alphanumeric_char;
-exports.set_logger = function(logger) {
- warn = logger;
-};
diff --git a/build/lib/process.js b/build/lib/process.js
deleted file mode 100644
index 3878c8d6..00000000
--- a/build/lib/process.js
+++ /dev/null
@@ -1,1666 +0,0 @@
-/***********************************************************************
-
- A JavaScript tokenizer / parser / beautifier / compressor.
-
- This version is suitable for Node.js. With minimal changes (the
- exports stuff) it should work on any JS platform.
-
- This file implements some AST processors. They work on data built
- by parse-js.
-
- Exported functions:
-
- - ast_mangle(ast, options) -- mangles the variable/function names
- in the AST. Returns an AST.
-
- - ast_squeeze(ast) -- employs various optimizations to make the
- final generated code even smaller. Returns an AST.
-
- - gen_code(ast, options) -- generates JS code from the AST. Pass
- true (or an object, see the code for some options) as second
- argument to get "pretty" (indented) code.
-
- -------------------------------- (C) ---------------------------------
-
- Author: Mihai Bazon
-
- http://mihai.bazon.net/blog
-
- Distributed under the BSD license:
-
- Copyright 2010 (c) Mihai Bazon
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- disclaimer.
-
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
- ***********************************************************************/
-
-var jsp = require("./parse-js"),
- slice = jsp.slice,
- member = jsp.member,
- PRECEDENCE = jsp.PRECEDENCE,
- OPERATORS = jsp.OPERATORS;
-
-/* -----[ helper for AST traversal ]----- */
-
-function ast_walker(ast) {
- function _vardefs(defs) {
- return [ this[0], MAP(defs, function(def){
- var a = [ def[0] ];
- if (def.length > 1)
- a[1] = walk(def[1]);
- return a;
- }) ];
- };
- function _block(statements) {
- var out = [ this[0] ];
- if (statements != null)
- out.push(MAP(statements, walk));
- return out;
- };
- var walkers = {
- "string": function(str) {
- return [ this[0], str ];
- },
- "num": function(num) {
- return [ this[0], num ];
- },
- "name": function(name) {
- return [ this[0], name ];
- },
- "toplevel": function(statements) {
- return [ this[0], MAP(statements, walk) ];
- },
- "block": _block,
- "splice": _block,
- "var": _vardefs,
- "const": _vardefs,
- "try": function(t, c, f) {
- return [
- this[0],
- MAP(t, walk),
- c != null ? [ c[0], MAP(c[1], walk) ] : null,
- f != null ? MAP(f, walk) : null
- ];
- },
- "throw": function(expr) {
- return [ this[0], walk(expr) ];
- },
- "new": function(ctor, args) {
- return [ this[0], walk(ctor), MAP(args, walk) ];
- },
- "switch": function(expr, body) {
- return [ this[0], walk(expr), MAP(body, function(branch){
- return [ branch[0] ? walk(branch[0]) : null,
- MAP(branch[1], walk) ];
- }) ];
- },
- "break": function(label) {
- return [ this[0], label ];
- },
- "continue": function(label) {
- return [ this[0], label ];
- },
- "conditional": function(cond, t, e) {
- return [ this[0], walk(cond), walk(t), walk(e) ];
- },
- "assign": function(op, lvalue, rvalue) {
- return [ this[0], op, walk(lvalue), walk(rvalue) ];
- },
- "dot": function(expr) {
- return [ this[0], walk(expr) ].concat(slice(arguments, 1));
- },
- "call": function(expr, args) {
- return [ this[0], walk(expr), MAP(args, walk) ];
- },
- "function": function(name, args, body) {
- return [ this[0], name, args.slice(), MAP(body, walk) ];
- },
- "defun": function(name, args, body) {
- return [ this[0], name, args.slice(), MAP(body, walk) ];
- },
- "if": function(conditional, t, e) {
- return [ this[0], walk(conditional), walk(t), walk(e) ];
- },
- "for": function(init, cond, step, block) {
- return [ this[0], walk(init), walk(cond), walk(step), walk(block) ];
- },
- "for-in": function(vvar, key, hash, block) {
- return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ];
- },
- "while": function(cond, block) {
- return [ this[0], walk(cond), walk(block) ];
- },
- "do": function(cond, block) {
- return [ this[0], walk(cond), walk(block) ];
- },
- "return": function(expr) {
- return [ this[0], walk(expr) ];
- },
- "binary": function(op, left, right) {
- return [ this[0], op, walk(left), walk(right) ];
- },
- "unary-prefix": function(op, expr) {
- return [ this[0], op, walk(expr) ];
- },
- "unary-postfix": function(op, expr) {
- return [ this[0], op, walk(expr) ];
- },
- "sub": function(expr, subscript) {
- return [ this[0], walk(expr), walk(subscript) ];
- },
- "object": function(props) {
- return [ this[0], MAP(props, function(p){
- return p.length == 2
- ? [ p[0], walk(p[1]) ]
- : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
- }) ];
- },
- "regexp": function(rx, mods) {
- return [ this[0], rx, mods ];
- },
- "array": function(elements) {
- return [ this[0], MAP(elements, walk) ];
- },
- "stat": function(stat) {
- return [ this[0], walk(stat) ];
- },
- "seq": function() {
- return [ this[0] ].concat(MAP(slice(arguments), walk));
- },
- "label": function(name, block) {
- return [ this[0], name, walk(block) ];
- },
- "with": function(expr, block) {
- return [ this[0], walk(expr), walk(block) ];
- },
- "atom": function(name) {
- return [ this[0], name ];
- }
- };
-
- var user = {};
- var stack = [];
- function walk(ast) {
- if (ast == null)
- return null;
- try {
- stack.push(ast);
- var type = ast[0];
- var gen = user[type];
- if (gen) {
- var ret = gen.apply(ast, ast.slice(1));
- if (ret != null)
- return ret;
- }
- gen = walkers[type];
- return gen.apply(ast, ast.slice(1));
- } finally {
- stack.pop();
- }
- };
-
- function with_walkers(walkers, cont){
- var save = {}, i;
- for (i in walkers) if (HOP(walkers, i)) {
- save[i] = user[i];
- user[i] = walkers[i];
- }
- var ret = cont();
- for (i in save) if (HOP(save, i)) {
- if (!save[i]) delete user[i];
- else user[i] = save[i];
- }
- return ret;
- };
-
- return {
- walk: walk,
- with_walkers: with_walkers,
- parent: function() {
- return stack[stack.length - 2]; // last one is current node
- },
- stack: function() {
- return stack;
- }
- };
-};
-
-/* -----[ Scope and mangling ]----- */
-
-function Scope(parent) {
- this.names = {}; // names defined in this scope
- this.mangled = {}; // mangled names (orig.name => mangled)
- this.rev_mangled = {}; // reverse lookup (mangled => orig.name)
- this.cname = -1; // current mangled name
- this.refs = {}; // names referenced from this scope
- this.uses_with = false; // will become TRUE if with() is detected in this or any subscopes
- this.uses_eval = false; // will become TRUE if eval() is detected in this or any subscopes
- this.parent = parent; // parent scope
- this.children = []; // sub-scopes
- if (parent) {
- this.level = parent.level + 1;
- parent.children.push(this);
- } else {
- this.level = 0;
- }
-};
-
-var base54 = (function(){
- var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
- return function(num) {
- var ret = "";
- do {
- ret = DIGITS.charAt(num % 54) + ret;
- num = Math.floor(num / 54);
- } while (num > 0);
- return ret;
- };
-})();
-
-Scope.prototype = {
- has: function(name) {
- for (var s = this; s; s = s.parent)
- if (HOP(s.names, name))
- return s;
- },
- has_mangled: function(mname) {
- for (var s = this; s; s = s.parent)
- if (HOP(s.rev_mangled, mname))
- return s;
- },
- toJSON: function() {
- return {
- names: this.names,
- uses_eval: this.uses_eval,
- uses_with: this.uses_with
- };
- },
-
- next_mangled: function() {
- // we must be careful that the new mangled name:
- //
- // 1. doesn't shadow a mangled name from a parent
- // scope, unless we don't reference the original
- // name from this scope OR from any sub-scopes!
- // This will get slow.
- //
- // 2. doesn't shadow an original name from a parent
- // scope, in the event that the name is not mangled
- // in the parent scope and we reference that name
- // here OR IN ANY SUBSCOPES!
- //
- // 3. doesn't shadow a name that is referenced but not
- // defined (possibly global defined elsewhere).
- for (;;) {
- var m = base54(++this.cname), prior;
-
- // case 1.
- prior = this.has_mangled(m);
- if (prior && this.refs[prior.rev_mangled[m]] === prior)
- continue;
-
- // case 2.
- prior = this.has(m);
- if (prior && prior !== this && this.refs[m] === prior && !prior.has_mangled(m))
- continue;
-
- // case 3.
- if (HOP(this.refs, m) && this.refs[m] == null)
- continue;
-
- // I got "do" once. :-/
- if (!is_identifier(m))
- continue;
-
- return m;
- }
- },
- get_mangled: function(name, newMangle) {
- if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use
- var s = this.has(name);
- if (!s) return name; // not in visible scope, no mangle
- if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope
- if (!newMangle) return name; // not found and no mangling requested
-
- var m = s.next_mangled();
- s.rev_mangled[m] = name;
- return s.mangled[name] = m;
- },
- define: function(name) {
- if (name != null)
- return this.names[name] = name;
- }
-};
-
-function ast_add_scope(ast) {
-
- var current_scope = null;
- var w = ast_walker(), walk = w.walk;
- var having_eval = [];
-
- function with_new_scope(cont) {
- current_scope = new Scope(current_scope);
- var ret = current_scope.body = cont();
- ret.scope = current_scope;
- current_scope = current_scope.parent;
- return ret;
- };
-
- function define(name) {
- return current_scope.define(name);
- };
-
- function reference(name) {
- current_scope.refs[name] = true;
- };
-
- function _lambda(name, args, body) {
- var is_defun = this[0] == "defun";
- return [ this[0], is_defun ? define(name) : name, args, with_new_scope(function(){
- if (!is_defun) define(name);
- MAP(args, define);
- return MAP(body, walk);
- })];
- };
-
- return with_new_scope(function(){
- // process AST
- var ret = w.with_walkers({
- "function": _lambda,
- "defun": _lambda,
- "with": function(expr, block) {
- for (var s = current_scope; s; s = s.parent)
- s.uses_with = true;
- },
- "var": function(defs) {
- MAP(defs, function(d){ define(d[0]) });
- },
- "const": function(defs) {
- MAP(defs, function(d){ define(d[0]) });
- },
- "try": function(t, c, f) {
- if (c != null) return [
- this[0],
- MAP(t, walk),
- [ define(c[0]), MAP(c[1], walk) ],
- f != null ? MAP(f, walk) : null
- ];
- },
- "name": function(name) {
- if (name == "eval")
- having_eval.push(current_scope);
- reference(name);
- }
- }, function(){
- return walk(ast);
- });
-
- // the reason why we need an additional pass here is
- // that names can be used prior to their definition.
-
- // scopes where eval was detected and their parents
- // are marked with uses_eval, unless they define the
- // "eval" name.
- MAP(having_eval, function(scope){
- if (!scope.has("eval")) while (scope) {
- scope.uses_eval = true;
- scope = scope.parent;
- }
- });
-
- // for referenced names it might be useful to know
- // their origin scope. current_scope here is the
- // toplevel one.
- function fixrefs(scope, i) {
- // do children first; order shouldn't matter
- for (i = scope.children.length; --i >= 0;)
- fixrefs(scope.children[i]);
- for (i in scope.refs) if (HOP(scope.refs, i)) {
- // find origin scope and propagate the reference to origin
- for (var origin = scope.has(i), s = scope; s; s = s.parent) {
- s.refs[i] = origin;
- if (s === origin) break;
- }
- }
- };
- fixrefs(current_scope);
-
- return ret;
- });
-
-};
-
-/* -----[ mangle names ]----- */
-
-function ast_mangle(ast, options) {
- var w = ast_walker(), walk = w.walk, scope;
- options = options || {};
-
- function get_mangled(name, newMangle) {
- if (!options.toplevel && !scope.parent) return name; // don't mangle toplevel
- if (options.except && member(name, options.except))
- return name;
- return scope.get_mangled(name, newMangle);
- };
-
- function get_define(name) {
- // we always lookup a defined symbol for the current scope FIRST, so declared
- // vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value
- if (!scope.has(name)) {
- if (HOP(options.defines, name)) {
- return options.defines[name];
- }
- }
- return null;
- };
-
- function _lambda(name, args, body) {
- var is_defun = this[0] == "defun";
- if (is_defun && name) name = get_mangled(name);
- body = with_scope(body.scope, function(){
- if (!is_defun && name) name = get_mangled(name);
- args = MAP(args, function(name){ return get_mangled(name) });
- return MAP(body, walk);
- });
- return [ this[0], name, args, body ];
- };
-
- function with_scope(s, cont) {
- var _scope = scope;
- scope = s;
- for (var i in s.names) if (HOP(s.names, i)) {
- get_mangled(i, true);
- }
- var ret = cont();
- ret.scope = s;
- scope = _scope;
- return ret;
- };
-
- function _vardefs(defs) {
- return [ this[0], MAP(defs, function(d){
- return [ get_mangled(d[0]), walk(d[1]) ];
- }) ];
- };
-
- return w.with_walkers({
- "function": _lambda,
- "defun": function() {
- // move function declarations to the top when
- // they are not in some block.
- var ast = _lambda.apply(this, arguments);
- switch (w.parent()[0]) {
- case "toplevel":
- case "function":
- case "defun":
- return MAP.at_top(ast);
- }
- return ast;
- },
- "var": _vardefs,
- "const": _vardefs,
- "name": function(name) {
- return get_define(name) || [ this[0], get_mangled(name) ];
- },
- "try": function(t, c, f) {
- return [ this[0],
- MAP(t, walk),
- c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null,
- f != null ? MAP(f, walk) : null ];
- },
- "toplevel": function(body) {
- var self = this;
- return with_scope(self.scope, function(){
- return [ self[0], MAP(body, walk) ];
- });
- }
- }, function() {
- return walk(ast_add_scope(ast));
- });
-};
-
-/* -----[
- - compress foo["bar"] into foo.bar,
- - remove block brackets {} where possible
- - join consecutive var declarations
- - various optimizations for IFs:
- - if (cond) foo(); else bar(); ==> cond?foo():bar();
- - if (cond) foo(); ==> cond&&foo();
- - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); // also for throw
- - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
- ]----- */
-
-var warn = function(){};
-
-function best_of(ast1, ast2) {
- return gen_code(ast1).length > gen_code(ast2[0] == "stat" ? ast2[1] : ast2).length ? ast2 : ast1;
-};
-
-function last_stat(b) {
- if (b[0] == "block" && b[1] && b[1].length > 0)
- return b[1][b[1].length - 1];
- return b;
-}
-
-function aborts(t) {
- if (t) {
- t = last_stat(t);
- if (t[0] == "return" || t[0] == "break" || t[0] == "continue" || t[0] == "throw")
- return true;
- }
-};
-
-function boolean_expr(expr) {
- return ( (expr[0] == "unary-prefix"
- && member(expr[1], [ "!", "delete" ])) ||
-
- (expr[0] == "binary"
- && member(expr[1], [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ])) ||
-
- (expr[0] == "binary"
- && member(expr[1], [ "&&", "||" ])
- && boolean_expr(expr[2])
- && boolean_expr(expr[3])) ||
-
- (expr[0] == "conditional"
- && boolean_expr(expr[2])
- && boolean_expr(expr[3])) ||
-
- (expr[0] == "assign"
- && expr[1] === true
- && boolean_expr(expr[3])) ||
-
- (expr[0] == "seq"
- && boolean_expr(expr[expr.length - 1]))
- );
-};
-
-function make_conditional(c, t, e) {
- var make_real_conditional = function() {
- if (c[0] == "unary-prefix" && c[1] == "!") {
- return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
- } else {
- return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ];
- }
- };
- // shortcut the conditional if the expression has a constant value
- return when_constant(c, function(ast, val){
- warn_unreachable(val ? e : t);
- return (val ? t : e);
- }, make_real_conditional);
-};
-
-function empty(b) {
- return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
-};
-
-function is_string(node) {
- return (node[0] == "string" ||
- node[0] == "unary-prefix" && node[1] == "typeof" ||
- node[0] == "binary" && node[1] == "+" &&
- (is_string(node[2]) || is_string(node[3])));
-};
-
-var when_constant = (function(){
-
- var $NOT_CONSTANT = {};
-
- // this can only evaluate constant expressions. If it finds anything
- // not constant, it throws $NOT_CONSTANT.
- function evaluate(expr) {
- switch (expr[0]) {
- case "string":
- case "num":
- return expr[1];
- case "name":
- case "atom":
- switch (expr[1]) {
- case "true": return true;
- case "false": return false;
- }
- break;
- case "unary-prefix":
- switch (expr[1]) {
- case "!": return !evaluate(expr[2]);
- case "typeof": return typeof evaluate(expr[2]);
- case "~": return ~evaluate(expr[2]);
- case "-": return -evaluate(expr[2]);
- case "+": return +evaluate(expr[2]);
- }
- break;
- case "binary":
- var left = expr[2], right = expr[3];
- switch (expr[1]) {
- case "&&" : return evaluate(left) && evaluate(right);
- case "||" : return evaluate(left) || evaluate(right);
- case "|" : return evaluate(left) | evaluate(right);
- case "&" : return evaluate(left) & evaluate(right);
- case "^" : return evaluate(left) ^ evaluate(right);
- case "+" : return evaluate(left) + evaluate(right);
- case "*" : return evaluate(left) * evaluate(right);
- case "/" : return evaluate(left) / evaluate(right);
- case "-" : return evaluate(left) - evaluate(right);
- case "<<" : return evaluate(left) << evaluate(right);
- case ">>" : return evaluate(left) >> evaluate(right);
- case ">>>" : return evaluate(left) >>> evaluate(right);
- case "==" : return evaluate(left) == evaluate(right);
- case "===" : return evaluate(left) === evaluate(right);
- case "!=" : return evaluate(left) != evaluate(right);
- case "!==" : return evaluate(left) !== evaluate(right);
- case "<" : return evaluate(left) < evaluate(right);
- case "<=" : return evaluate(left) <= evaluate(right);
- case ">" : return evaluate(left) > evaluate(right);
- case ">=" : return evaluate(left) >= evaluate(right);
- case "in" : return evaluate(left) in evaluate(right);
- case "instanceof" : return evaluate(left) instanceof evaluate(right);
- }
- }
- throw $NOT_CONSTANT;
- };
-
- return function(expr, yes, no) {
- try {
- var val = evaluate(expr), ast;
- switch (typeof val) {
- case "string": ast = [ "string", val ]; break;
- case "number": ast = [ "num", val ]; break;
- case "boolean": ast = [ "name", String(val) ]; break;
- default: throw new Error("Can't handle constant of type: " + (typeof val));
- }
- return yes.call(expr, ast, val);
- } catch(ex) {
- if (ex === $NOT_CONSTANT) {
- if (expr[0] == "binary"
- && (expr[1] == "===" || expr[1] == "!==")
- && ((is_string(expr[2]) && is_string(expr[3]))
- || (boolean_expr(expr[2]) && boolean_expr(expr[3])))) {
- expr[1] = expr[1].substr(0, 2);
- }
- else if (no && expr[0] == "binary"
- && (expr[1] == "||" || expr[1] == "&&")) {
- // the whole expression is not constant but the lval may be...
- try {
- var lval = evaluate(expr[2]);
- expr = ((expr[1] == "&&" && (lval ? expr[3] : lval)) ||
- (expr[1] == "||" && (lval ? lval : expr[3])) ||
- expr);
- } catch(ex2) {
- // IGNORE... lval is not constant
- }
- }
- return no ? no.call(expr, expr) : null;
- }
- else throw ex;
- }
- };
-
-})();
-
-function warn_unreachable(ast) {
- if (!empty(ast))
- warn("Dropping unreachable code: " + gen_code(ast, true));
-};
-
-function ast_squeeze(ast, options) {
- options = defaults(options, {
- make_seqs : true,
- dead_code : true,
- keep_comps : true,
- no_warnings : false
- });
-
- var w = ast_walker(), walk = w.walk, scope;
-
- function negate(c) {
- var not_c = [ "unary-prefix", "!", c ];
- switch (c[0]) {
- case "unary-prefix":
- return c[1] == "!" && boolean_expr(c[2]) ? c[2] : not_c;
- case "seq":
- c = slice(c);
- c[c.length - 1] = negate(c[c.length - 1]);
- return c;
- case "conditional":
- return best_of(not_c, [ "conditional", c[1], negate(c[2]), negate(c[3]) ]);
- case "binary":
- var op = c[1], left = c[2], right = c[3];
- if (!options.keep_comps) switch (op) {
- case "<=" : return [ "binary", ">", left, right ];
- case "<" : return [ "binary", ">=", left, right ];
- case ">=" : return [ "binary", "<", left, right ];
- case ">" : return [ "binary", "<=", left, right ];
- }
- switch (op) {
- case "==" : return [ "binary", "!=", left, right ];
- case "!=" : return [ "binary", "==", left, right ];
- case "===" : return [ "binary", "!==", left, right ];
- case "!==" : return [ "binary", "===", left, right ];
- case "&&" : return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]);
- case "||" : return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]);
- }
- break;
- }
- return not_c;
- };
-
- function with_scope(s, cont) {
- var _scope = scope;
- scope = s;
- var ret = cont();
- ret.scope = s;
- scope = _scope;
- return ret;
- };
-
- function rmblock(block) {
- if (block != null && block[0] == "block" && block[1]) {
- if (block[1].length == 1)
- block = block[1][0];
- else if (block[1].length == 0)
- block = [ "block" ];
- }
- return block;
- };
-
- function _lambda(name, args, body) {
- var is_defun = this[0] == "defun";
- body = with_scope(body.scope, function(){
- var ret = tighten(MAP(body, walk), "lambda");
- if (!is_defun && name && !HOP(scope.refs, name))
- name = null;
- return ret;
- });
- return [ this[0], name, args, body ];
- };
-
- // we get here for blocks that have been already transformed.
- // this function does a few things:
- // 1. discard useless blocks
- // 2. join consecutive var declarations
- // 3. remove obviously dead code
- // 4. transform consecutive statements using the comma operator
- // 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... }
- function tighten(statements, block_type) {
- statements = statements.reduce(function(a, stat){
- if (stat[0] == "block") {
- if (stat[1]) {
- a.push.apply(a, stat[1]);
- }
- } else {
- a.push(stat);
- }
- return a;
- }, []);
-
- statements = (function(a, prev){
- statements.forEach(function(cur){
- if (prev && ((cur[0] == "var" && prev[0] == "var") ||
- (cur[0] == "const" && prev[0] == "const"))) {
- prev[1] = prev[1].concat(cur[1]);
- } else {
- a.push(cur);
- prev = cur;
- }
- });
- return a;
- })([]);
-
- if (options.dead_code) statements = (function(a, has_quit){
- statements.forEach(function(st){
- if (has_quit) {
- if (member(st[0], [ "function", "defun" , "var", "const" ])) {
- a.push(st);
- }
- else if (!options.no_warnings)
- warn_unreachable(st);
- }
- else {
- a.push(st);
- if (member(st[0], [ "return", "throw", "break", "continue" ]))
- has_quit = true;
- }
- });
- return a;
- })([]);
-
- if (options.make_seqs) statements = (function(a, prev) {
- statements.forEach(function(cur){
- if (prev && prev[0] == "stat" && cur[0] == "stat") {
- prev[1] = [ "seq", prev[1], cur[1] ];
- } else {
- a.push(cur);
- prev = cur;
- }
- });
- return a;
- })([]);
-
- if (block_type == "lambda") statements = (function(i, a, stat){
- while (i < statements.length) {
- stat = statements[i++];
- if (stat[0] == "if" && !stat[3]) {
- if (stat[2][0] == "return" && stat[2][1] == null) {
- a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ]));
- break;
- }
- var last = last_stat(stat[2]);
- if (last[0] == "return" && last[1] == null) {
- a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ]));
- break;
- }
- }
- a.push(stat);
- }
- return a;
- })(0, []);
-
- return statements;
- };
-
- function make_if(c, t, e) {
- return when_constant(c, function(ast, val){
- if (val) {
- warn_unreachable(e);
- return t;
- } else {
- warn_unreachable(t);
- return e;
- }
- }, function() {
- return make_real_if(c, t, e);
- });
- };
-
- function make_real_if(c, t, e) {
- c = walk(c);
- t = walk(t);
- e = walk(e);
-
- if (empty(t)) {
- c = negate(c);
- t = e;
- e = null;
- } else if (empty(e)) {
- e = null;
- } else {
- // if we have both else and then, maybe it makes sense to switch them?
- (function(){
- var a = gen_code(c);
- var n = negate(c);
- var b = gen_code(n);
- if (b.length < a.length) {
- var tmp = t;
- t = e;
- e = tmp;
- c = n;
- }
- })();
- }
- if (empty(e) && empty(t))
- return [ "stat", c ];
- var ret = [ "if", c, t, e ];
- if (t[0] == "if" && empty(t[3]) && empty(e)) {
- ret = best_of(ret, walk([ "if", [ "binary", "&&", c, t[1] ], t[2] ]));
- }
- else if (t[0] == "stat") {
- if (e) {
- if (e[0] == "stat") {
- ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]);
- }
- }
- else {
- ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]);
- }
- }
- else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw") && t[1] && e[1]) {
- ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]);
- }
- else if (e && aborts(t)) {
- ret = [ [ "if", c, t ] ];
- if (e[0] == "block") {
- if (e[1]) ret = ret.concat(e[1]);
- }
- else {
- ret.push(e);
- }
- ret = walk([ "block", ret ]);
- }
- else if (t && aborts(e)) {
- ret = [ [ "if", negate(c), e ] ];
- if (t[0] == "block") {
- if (t[1]) ret = ret.concat(t[1]);
- } else {
- ret.push(t);
- }
- ret = walk([ "block", ret ]);
- }
- return ret;
- };
-
- function _do_while(cond, body) {
- return when_constant(cond, function(cond, val){
- if (!val) {
- warn_unreachable(body);
- return [ "block" ];
- } else {
- return [ "for", null, null, null, walk(body) ];
- }
- });
- };
-
- return w.with_walkers({
- "sub": function(expr, subscript) {
- if (subscript[0] == "string") {
- var name = subscript[1];
- if (is_identifier(name))
- return [ "dot", walk(expr), name ];
- else if (/^[1-9][0-9]*$/.test(name) || name === "0")
- return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ];
- }
- },
- "if": make_if,
- "toplevel": function(body) {
- return [ "toplevel", with_scope(this.scope, function(){
- return tighten(MAP(body, walk));
- }) ];
- },
- "switch": function(expr, body) {
- var last = body.length - 1;
- return [ "switch", walk(expr), MAP(body, function(branch, i){
- var block = tighten(MAP(branch[1], walk));
- if (i == last && block.length > 0) {
- var node = block[block.length - 1];
- if (node[0] == "break" && !node[1])
- block.pop();
- }
- return [ branch[0] ? walk(branch[0]) : null, block ];
- }) ];
- },
- "function": _lambda,
- "defun": _lambda,
- "block": function(body) {
- if (body) return rmblock([ "block", tighten(MAP(body, walk)) ]);
- },
- "binary": function(op, left, right) {
- return when_constant([ "binary", op, walk(left), walk(right) ], function yes(c){
- return best_of(walk(c), this);
- }, function no() {
- return this;
- });
- },
- "conditional": function(c, t, e) {
- return make_conditional(walk(c), walk(t), walk(e));
- },
- "try": function(t, c, f) {
- return [
- "try",
- tighten(MAP(t, walk)),
- c != null ? [ c[0], tighten(MAP(c[1], walk)) ] : null,
- f != null ? tighten(MAP(f, walk)) : null
- ];
- },
- "unary-prefix": function(op, expr) {
- expr = walk(expr);
- var ret = [ "unary-prefix", op, expr ];
- if (op == "!")
- ret = best_of(ret, negate(expr));
- return when_constant(ret, function(ast, val){
- return walk(ast); // it's either true or false, so minifies to !0 or !1
- }, function() { return ret });
- },
- "name": function(name) {
- switch (name) {
- case "true": return [ "unary-prefix", "!", [ "num", 0 ]];
- case "false": return [ "unary-prefix", "!", [ "num", 1 ]];
- }
- },
- "new": function(ctor, args) {
- if (ctor[0] == "name" && ctor[1] == "Array" && !scope.has("Array")) {
- if (args.length != 1) {
- return [ "array", args ];
- } else {
- return [ "call", [ "name", "Array" ], args ];
- }
- }
- },
- "call": function(expr, args) {
- if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
- return [ "array", args ];
- }
- },
- "while": _do_while,
- "do": _do_while
- }, function() {
- return walk(ast_add_scope(ast));
- });
-};
-
-/* -----[ re-generate code from the AST ]----- */
-
-var DOT_CALL_NO_PARENS = jsp.array_to_hash([
- "name",
- "array",
- "object",
- "string",
- "dot",
- "sub",
- "call",
- "regexp"
-]);
-
-function make_string(str, ascii_only) {
- var dq = 0, sq = 0;
- str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029]/g, function(s){
- switch (s) {
- case "\\": return "\\\\";
- case "\b": return "\\b";
- case "\f": return "\\f";
- case "\n": return "\\n";
- case "\r": return "\\r";
- case "\t": return "\\t";
- case "\u2028": return "\\u2028";
- case "\u2029": return "\\u2029";
- case '"': ++dq; return '"';
- case "'": ++sq; return "'";
- }
- return s;
- });
- if (ascii_only) str = to_ascii(str);
- if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
- else return '"' + str.replace(/\x22/g, '\\"') + '"';
-};
-
-function to_ascii(str) {
- return str.replace(/[\u0080-\uffff]/g, function(ch) {
- var code = ch.charCodeAt(0).toString(16);
- while (code.length < 4) code = "0" + code;
- return "\\u" + code;
- });
-};
-
-var SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);
-
-function gen_code(ast, options) {
- options = defaults(options, {
- indent_start : 0,
- indent_level : 4,
- quote_keys : false,
- space_colon : false,
- beautify : false,
- ascii_only : false
- });
- var beautify = !!options.beautify;
- var indentation = 0,
- newline = beautify ? "\n" : "",
- space = beautify ? " " : "";
-
- function encode_string(str) {
- return make_string(str, options.ascii_only);
- };
-
- function make_name(name) {
- name = name.toString();
- if (options.ascii_only)
- name = to_ascii(name);
- return name;
- };
-
- function indent(line) {
- if (line == null)
- line = "";
- if (beautify)
- line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line;
- return line;
- };
-
- function with_indent(cont, incr) {
- if (incr == null) incr = 1;
- indentation += incr;
- try { return cont.apply(null, slice(arguments, 1)); }
- finally { indentation -= incr; }
- };
-
- function add_spaces(a) {
- if (beautify)
- return a.join(" ");
- var b = [];
- for (var i = 0; i < a.length; ++i) {
- var next = a[i + 1];
- b.push(a[i]);
- if (next &&
- ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) ||
- (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
- b.push(" ");
- }
- }
- return b.join("");
- };
-
- function add_commas(a) {
- return a.join("," + space);
- };
-
- function parenthesize(expr) {
- var gen = make(expr);
- for (var i = 1; i < arguments.length; ++i) {
- var el = arguments[i];
- if ((el instanceof Function && el(expr)) || expr[0] == el)
- return "(" + gen + ")";
- }
- return gen;
- };
-
- function best_of(a) {
- if (a.length == 1) {
- return a[0];
- }
- if (a.length == 2) {
- var b = a[1];
- a = a[0];
- return a.length <= b.length ? a : b;
- }
- return best_of([ a[0], best_of(a.slice(1)) ]);
- };
-
- function needs_parens(expr) {
- if (expr[0] == "function" || expr[0] == "object") {
- // dot/call on a literal function requires the
- // function literal itself to be parenthesized
- // only if it's the first "thing" in a
- // statement. This means that the parent is
- // "stat", but it could also be a "seq" and
- // we're the first in this "seq" and the
- // parent is "stat", and so on. Messy stuff,
- // but it worths the trouble.
- var a = slice($stack), self = a.pop(), p = a.pop();
- while (p) {
- if (p[0] == "stat") return true;
- if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
- ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) {
- self = p;
- p = a.pop();
- } else {
- return false;
- }
- }
- }
- return !HOP(DOT_CALL_NO_PARENS, expr[0]);
- };
-
- function make_num(num) {
- var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m;
- if (Math.floor(num) === num) {
- a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
- "0" + num.toString(8)); // same.
- if ((m = /^(.*?)(0+)$/.exec(num))) {
- a.push(m[1] + "e" + m[2].length);
- }
- } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
- a.push(m[2] + "e-" + (m[1].length + m[2].length),
- str.substr(str.indexOf(".")));
- }
- return best_of(a);
- };
-
- var generators = {
- "string": encode_string,
- "num": make_num,
- "name": make_name,
- "toplevel": function(statements) {
- return make_block_statements(statements)
- .join(newline + newline);
- },
- "splice": function(statements) {
- var parent = $stack[$stack.length - 2][0];
- if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
- // we need block brackets in this case
- return make_block.apply(this, arguments);
- } else {
- return MAP(make_block_statements(statements, true),
- function(line, i) {
- // the first line is already indented
- return i > 0 ? indent(line) : line;
- }).join(newline);
- }
- },
- "block": make_block,
- "var": function(defs) {
- return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
- },
- "const": function(defs) {
- return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
- },
- "try": function(tr, ca, fi) {
- var out = [ "try", make_block(tr) ];
- if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
- if (fi) out.push("finally", make_block(fi));
- return add_spaces(out);
- },
- "throw": function(expr) {
- return add_spaces([ "throw", make(expr) ]) + ";";
- },
- "new": function(ctor, args) {
- args = args.length > 0 ? "(" + add_commas(MAP(args, make)) + ")" : "";
- return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
- var w = ast_walker(), has_call = {};
- try {
- w.with_walkers({
- "call": function() { throw has_call },
- "function": function() { return this }
- }, function(){
- w.walk(expr);
- });
- } catch(ex) {
- if (ex === has_call)
- return true;
- throw ex;
- }
- }) + args ]);
- },
- "switch": function(expr, body) {
- return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
- },
- "break": function(label) {
- var out = "break";
- if (label != null)
- out += " " + make_name(label);
- return out + ";";
- },
- "continue": function(label) {
- var out = "continue";
- if (label != null)
- out += " " + make_name(label);
- return out + ";";
- },
- "conditional": function(co, th, el) {
- return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
- parenthesize(th, "seq"), ":",
- parenthesize(el, "seq") ]);
- },
- "assign": function(op, lvalue, rvalue) {
- if (op && op !== true) op += "=";
- else op = "=";
- return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
- },
- "dot": function(expr) {
- var out = make(expr), i = 1;
- if (expr[0] == "num") {
- if (!/\./.test(expr[1]))
- out += ".";
- } else if (needs_parens(expr))
- out = "(" + out + ")";
- while (i < arguments.length)
- out += "." + make_name(arguments[i++]);
- return out;
- },
- "call": function(func, args) {
- var f = make(func);
- if (needs_parens(func))
- f = "(" + f + ")";
- return f + "(" + add_commas(MAP(args, function(expr){
- return parenthesize(expr, "seq");
- })) + ")";
- },
- "function": make_function,
- "defun": make_function,
- "if": function(co, th, el) {
- var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
- if (el) {
- out.push("else", make(el));
- }
- return add_spaces(out);
- },
- "for": function(init, cond, step, block) {
- var out = [ "for" ];
- init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
- cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
- step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
- var args = init + cond + step;
- if (args == "; ; ") args = ";;";
- out.push("(" + args + ")", make(block));
- return add_spaces(out);
- },
- "for-in": function(vvar, key, hash, block) {
- return add_spaces([ "for", "(" +
- (vvar ? make(vvar).replace(/;+$/, "") : make(key)),
- "in",
- make(hash) + ")", make(block) ]);
- },
- "while": function(condition, block) {
- return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
- },
- "do": function(condition, block) {
- return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
- },
- "return": function(expr) {
- var out = [ "return" ];
- if (expr != null) out.push(make(expr));
- return add_spaces(out) + ";";
- },
- "binary": function(operator, lvalue, rvalue) {
- var left = make(lvalue), right = make(rvalue);
- // XXX: I'm pretty sure other cases will bite here.
- // we need to be smarter.
- // adding parens all the time is the safest bet.
- if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
- lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]]) {
- left = "(" + left + ")";
- }
- if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
- rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] &&
- !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) {
- right = "(" + right + ")";
- }
- return add_spaces([ left, operator, right ]);
- },
- "unary-prefix": function(operator, expr) {
- var val = make(expr);
- if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
- val = "(" + val + ")";
- return operator + (jsp.is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
- },
- "unary-postfix": function(operator, expr) {
- var val = make(expr);
- if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
- val = "(" + val + ")";
- return val + operator;
- },
- "sub": function(expr, subscript) {
- var hash = make(expr);
- if (needs_parens(expr))
- hash = "(" + hash + ")";
- return hash + "[" + make(subscript) + "]";
- },
- "object": function(props) {
- if (props.length == 0)
- return "{}";
- return "{" + newline + with_indent(function(){
- return MAP(props, function(p){
- if (p.length == 3) {
- // getter/setter. The name is in p[0], the arg.list in p[1][2], the
- // body in p[1][3] and type ("get" / "set") in p[2].
- return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
- }
- var key = p[0], val = make(p[1]);
- if (options.quote_keys) {
- key = encode_string(key);
- } else if ((typeof key == "number" || !beautify && +key + "" == key)
- && parseFloat(key) >= 0) {
- key = make_num(+key);
- } else if (!is_identifier(key)) {
- key = encode_string(key);
- }
- return indent(add_spaces(beautify && options.space_colon
- ? [ key, ":", val ]
- : [ key + ":", val ]));
- }).join("," + newline);
- }) + newline + indent("}");
- },
- "regexp": function(rx, mods) {
- return "/" + rx + "/" + mods;
- },
- "array": function(elements) {
- if (elements.length == 0) return "[]";
- return add_spaces([ "[", add_commas(MAP(elements, function(el){
- if (!beautify && el[0] == "atom" && el[1] == "undefined") return "";
- return parenthesize(el, "seq");
- })), "]" ]);
- },
- "stat": function(stmt) {
- return make(stmt).replace(/;*\s*$/, ";");
- },
- "seq": function() {
- return add_commas(MAP(slice(arguments), make));
- },
- "label": function(name, block) {
- return add_spaces([ make_name(name), ":", make(block) ]);
- },
- "with": function(expr, block) {
- return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
- },
- "atom": function(name) {
- return make_name(name);
- }
- };
-
- // The squeezer replaces "block"-s that contain only a single
- // statement with the statement itself; technically, the AST
- // is correct, but this can create problems when we output an
- // IF having an ELSE clause where the THEN clause ends in an
- // IF *without* an ELSE block (then the outer ELSE would refer
- // to the inner IF). This function checks for this case and
- // adds the block brackets if needed.
- function make_then(th) {
- if (th[0] == "do") {
- // https://github.com/mishoo/UglifyJS/issues/#issue/57
- // IE croaks with "syntax error" on code like this:
- // if (foo) do ... while(cond); else ...
- // we need block brackets around do/while
- return make([ "block", [ th ]]);
- }
- var b = th;
- while (true) {
- var type = b[0];
- if (type == "if") {
- if (!b[3])
- // no else, we must add the block
- return make([ "block", [ th ]]);
- b = b[3];
- }
- else if (type == "while" || type == "do") b = b[2];
- else if (type == "for" || type == "for-in") b = b[4];
- else break;
- }
- return make(th);
- };
-
- function make_function(name, args, body, keyword) {
- var out = keyword || "function";
- if (name) {
- out += " " + make_name(name);
- }
- out += "(" + add_commas(MAP(args, make_name)) + ")";
- return add_spaces([ out, make_block(body) ]);
- };
-
- function make_block_statements(statements, noindent) {
- for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
- var stat = statements[i];
- var code = make(stat);
- if (code != ";") {
- if (!beautify && i == last) {
- if ((stat[0] == "while" && empty(stat[2])) ||
- (member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) ||
- (stat[0] == "if" && empty(stat[2]) && !stat[3]) ||
- (stat[0] == "if" && stat[3] && empty(stat[3]))) {
- code = code.replace(/;*\s*$/, ";");
- } else {
- code = code.replace(/;+\s*$/, "");
- }
- }
- a.push(code);
- }
- }
- return noindent ? a : MAP(a, indent);
- };
-
- function make_switch_block(body) {
- var n = body.length;
- if (n == 0) return "{}";
- return "{" + newline + MAP(body, function(branch, i){
- var has_body = branch[1].length > 0, code = with_indent(function(){
- return indent(branch[0]
- ? add_spaces([ "case", make(branch[0]) + ":" ])
- : "default:");
- }, 0.5) + (has_body ? newline + with_indent(function(){
- return make_block_statements(branch[1]).join(newline);
- }) : "");
- if (!beautify && has_body && i < n - 1)
- code += ";";
- return code;
- }).join(newline) + newline + indent("}");
- };
-
- function make_block(statements) {
- if (!statements) return ";";
- if (statements.length == 0) return "{}";
- return "{" + newline + with_indent(function(){
- return make_block_statements(statements).join(newline);
- }) + newline + indent("}");
- };
-
- function make_1vardef(def) {
- var name = def[0], val = def[1];
- if (val != null)
- name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]);
- return name;
- };
-
- var $stack = [];
-
- function make(node) {
- var type = node[0];
- var gen = generators[type];
- if (!gen)
- throw new Error("Can't find generator for \"" + type + "\"");
- $stack.push(node);
- var ret = gen.apply(type, node.slice(1));
- $stack.pop();
- return ret;
- };
-
- return make(ast);
-};
-
-function split_lines(code, max_line_length) {
- var splits = [ 0 ];
- jsp.parse(function(){
- var next_token = jsp.tokenizer(code);
- var last_split = 0;
- var prev_token;
- function current_length(tok) {
- return tok.pos - last_split;
- };
- function split_here(tok) {
- last_split = tok.pos;
- splits.push(last_split);
- };
- function custom(){
- var tok = next_token.apply(this, arguments);
- out: {
- if (prev_token) {
- if (prev_token.type == "keyword") break out;
- }
- if (current_length(tok) > max_line_length) {
- switch (tok.type) {
- case "keyword":
- case "atom":
- case "name":
- case "punc":
- split_here(tok);
- break out;
- }
- }
- }
- prev_token = tok;
- return tok;
- };
- custom.context = function() {
- return next_token.context.apply(this, arguments);
- };
- return custom;
- }());
- return splits.map(function(pos, i){
- return code.substring(pos, splits[i + 1] || code.length);
- }).join("\n");
-};
-
-/* -----[ Utilities ]----- */
-
-function repeat_string(str, i) {
- if (i <= 0) return "";
- if (i == 1) return str;
- var d = repeat_string(str, i >> 1);
- d += d;
- if (i & 1) d += str;
- return d;
-};
-
-function defaults(args, defs) {
- var ret = {};
- if (args === true)
- args = {};
- for (var i in defs) if (HOP(defs, i)) {
- ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
- }
- return ret;
-};
-
-function is_identifier(name) {
- return /^[a-z_$][a-z0-9_$]*$/i.test(name)
- && name != "this"
- && !HOP(jsp.KEYWORDS_ATOM, name)
- && !HOP(jsp.RESERVED_WORDS, name)
- && !HOP(jsp.KEYWORDS, name);
-};
-
-function HOP(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-};
-
-// some utilities
-
-var MAP;
-
-(function(){
- MAP = function(a, f, o) {
- var ret = [];
- for (var i = 0; i < a.length; ++i) {
- var val = f.call(o, a[i], i);
- if (val instanceof AtTop) ret.unshift(val.v);
- else ret.push(val);
- }
- return ret;
- };
- MAP.at_top = function(val) { return new AtTop(val) };
- function AtTop(val) { this.v = val };
-})();
-
-/* -----[ Exports ]----- */
-
-exports.ast_walker = ast_walker;
-exports.ast_mangle = ast_mangle;
-exports.ast_squeeze = ast_squeeze;
-exports.gen_code = gen_code;
-exports.ast_add_scope = ast_add_scope;
-exports.set_logger = function(logger) { warn = logger };
-exports.make_string = make_string;
-exports.split_lines = split_lines;
-exports.MAP = MAP;
-
-// keep this last!
-exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
diff --git a/build/lib/squeeze-more.js b/build/lib/squeeze-more.js
deleted file mode 100644
index 12380af8..00000000
--- a/build/lib/squeeze-more.js
+++ /dev/null
@@ -1,22 +0,0 @@
-var jsp = require("./parse-js"),
- pro = require("./process"),
- slice = jsp.slice,
- member = jsp.member,
- PRECEDENCE = jsp.PRECEDENCE,
- OPERATORS = jsp.OPERATORS;
-
-function ast_squeeze_more(ast) {
- var w = pro.ast_walker(), walk = w.walk;
- return w.with_walkers({
- "call": function(expr, args) {
- if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
- // foo.toString() ==> foo+""
- return [ "binary", "+", expr[1], [ "string", "" ]];
- }
- }
- }, function() {
- return walk(ast);
- });
-};
-
-exports.ast_squeeze_more = ast_squeeze_more;
diff --git a/build/post-compile.js b/build/post-compile.js
deleted file mode 100644
index 1bbeaa6f..00000000
--- a/build/post-compile.js
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env node
-
-var print = require("sys").print,
- src = require("fs").readFileSync(process.argv[2], "utf8");
-
-// Previously done in sed but reimplemented here due to portability issues
-print( src.replace( /^(\s*\*\/)(.+)/m, "$1\n$2" ) + ";" );
diff --git a/build/release-notes.js b/build/release-notes.js
deleted file mode 100644
index b112d998..00000000
--- a/build/release-notes.js
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env node
-/*
- * jQuery Release Note Generator
- */
-
-var fs = require("fs"),
- http = require("http"),
- tmpl = require("mustache"),
- extract = /(.*?)<[^"]+"component">\s*(\S+)/g;
-
-var opts = {
- version: "1.6.2 RC 1",
- short_version: "1.6.2rc1",
- final_version: "1.6.2",
- categories: []
-};
-
-http.request({
- host: "bugs.jquery.com",
- port: 80,
- method: "GET",
- path: "/query?status=closed&resolution=fixed&component=!web&order=component&milestone=" + opts.final_version
-}, function (res) {
- var data = [];
-
- res.on( "data", function( chunk ) {
- data.push( chunk );
- });
-
- res.on( "end", function() {
- var match,
- file = data.join(""),
- cur;
-
- while ( (match = extract.exec( file )) ) {
- if ( "#" + match[1] !== match[2] ) {
- var cat = match[3];
-
- if ( !cur || cur.name !== cat ) {
- cur = { name: match[3], niceName: match[3].replace(/^./, function(a){ return a.toUpperCase(); }), bugs: [] };
- opts.categories.push( cur );
- }
-
- cur.bugs.push({ ticket: match[1], title: match[2] });
- }
- }
-
- buildNotes();
- });
-}).end();
-
-function buildNotes() {
- console.log( tmpl.to_html( fs.readFileSync("release-notes.txt", "utf8"), opts ) );
-}
diff --git a/build/release-notes.txt b/build/release-notes.txt
deleted file mode 100644
index 1d0ae746..00000000
--- a/build/release-notes.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-jQuery {{version}} Released
-
-This is a preview release of jQuery. We're releasing it so that everyone can start testing the code in their applications, making sure that there are no major problems.
-
-You can get the code from the jQuery CDN:
-
-
-
-You can help us by dropping that code into your existing application and letting us know that if anything no longer works. Please file a bug and be sure to mention that you're testing against jQuery {{version}}.
-
-We want to encourage everyone from the community to try and get involved in contributing back to jQuery core. We've set up a full page of information dedicated towards becoming more involved with the team. The team is here and ready to help you help us!
-
-jQuery {{version}} Change Log
-
-The current change log of the {{version}} release.
-
-{{#categories}}
-{{niceName}}
-
-
-{{/categories}}
diff --git a/build/release.js b/build/release.js
deleted file mode 100644
index 7a42f998..00000000
--- a/build/release.js
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/env node
-/*
- * jQuery Release Management
- */
-
-var fs = require("fs"),
- child = require("child_process"),
- debug = false;
-
-var scpURL = "jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/",
- cdnURL = "http://code.origin.jquery.com/",
-
- version = /^[\d.]+(?:(?:a|b|rc)\d+|pre)?$/,
- versionFile = "version.txt",
-
- file = "dist/jquery.js",
- minFile = "dist/jquery.min.js",
-
- files = {
- "jquery-VER.js": file,
- "jquery-VER.min.js": minFile
- },
-
- finalFiles = {
- "jquery.js": file,
- "jquery-latest.js": file,
- "jquery.min.js": minFile,
- "jquery-latest.min.js": minFile
- };
-
-exec( "git pull && git status", function( error, stdout, stderr ) {
- if ( /Changes to be committed/i.test( stdout ) ) {
- exit( "Please commit changed files before attemping to push a release." );
-
- } else if ( /Changes not staged for commit/i.test( stdout ) ) {
- exit( "Please stash files before attempting to push a release." );
-
- } else {
- setVersion();
- }
-});
-
-function setVersion() {
- var oldVersion = fs.readFileSync( versionFile, "utf8" );
-
- prompt( "New Version (was " + oldVersion + "): ", function( data ) {
- if ( data && version.test( data ) ) {
- fs.writeFileSync( versionFile, data );
-
- exec( "git commit -a -m 'Tagging the " + data + " release.' && git push && " +
- "git tag " + data + " && git push origin " + data, function() {
- make( data );
- });
-
- } else {
- console.error( "Malformed version number, please try again." );
- setVersion();
- }
- });
-}
-
-function make( newVersion ) {
- exec( "make clean && make", function( error, stdout, stderr ) {
- // TODO: Verify JSLint
-
- Object.keys( files ).forEach(function( oldName ) {
- var value = files[ oldName ], name = oldName.replace( /VER/g, newVersion );
-
- copy( value, name );
-
- delete files[ oldName ];
- files[ name ] = value;
- });
-
- exec( "scp " + Object.keys( files ).join( " " ) + " " + scpURL, function() {
- setNextVersion( newVersion );
- });
- });
-}
-
-function setNextVersion( newVersion ) {
- var isFinal = false;
-
- if ( /(?:a|b|rc)\d+$/.test( newVersion ) ) {
- newVersion = newVersion.replace( /(?:a|b|rc)\d+$/, "pre" );
-
- } else if ( /^\d+\.\d+\.?(\d*)$/.test( newVersion ) ) {
- newVersion = newVersion.replace( /^(\d+\.\d+\.?)(\d*)$/, function( all, pre, num ) {
- return pre + (pre.charAt( pre.length - 1 ) !== "." ? "." : "") + (num ? parseFloat( num ) + 1 : 1) + "pre";
- });
-
- isFinal = true;
- }
-
- prompt( "Next Version [" + newVersion + "]: ", function( data ) {
- if ( !data ) {
- data = newVersion;
- }
-
- if ( version.test( data ) ) {
- fs.writeFileSync( versionFile, data );
-
- exec( "git commit -a -m 'Updating the source version to " + data + "' && git push", function() {
- if ( isFinal ) {
- makeFinal( newVersion );
- }
- });
-
- } else {
- console.error( "Malformed version number, please try again." );
- setNextVersion( newVersion );
- }
- });
-}
-
-function makeFinal( newVersion ) {
- var all = Object.keys( finalFiles );
-
- // Copy all the files
- all.forEach(function( name ) {
- copy( finalFiles[ name ], name );
- });
-
- // Upload files to CDN
- exec( "scp " + all.join( " " ) + " " + scpURL, function() {
- exec( "curl '" + cdnURL + "{" + all.join( "," ) + "}?reload'", function() {
- console.log( "Done." );
- });
- });
-}
-
-function copy( oldFile, newFile ) {
- if ( debug ) {
- console.log( "Copying " + oldFile + " to " + newFile );
-
- } else {
- fs.writeFileSync( newFile, fs.readFileSync( oldFile, "utf8" ) );
- }
-}
-
-function prompt( msg, callback ) {
- process.stdout.write( msg );
-
- process.stdin.resume();
- process.stdin.setEncoding( "utf8" );
-
- process.stdin.once( "data", function( chunk ) {
- process.stdin.pause();
- callback( chunk.replace( /\n*$/g, "" ) );
- });
-}
-
-function exec( cmd, fn ) {
- if ( debug ) {
- console.log( cmd );
- fn();
-
- } else {
- child.exec( cmd, fn );
- }
-}
-
-function exit( msg ) {
- if ( msg ) {
- console.error( "\nError: " + msg );
- }
-
- process.exit( 1 );
-}
diff --git a/build/runtest/env.js b/build/runtest/env.js
new file mode 100644
index 00000000..e15a2263
--- /dev/null
+++ b/build/runtest/env.js
@@ -0,0 +1,695 @@
+/*
+ * Simulated browser environment for Rhino
+ * By John Resig
+ * Copyright 2007 John Resig, under the MIT License
+ */
+
+// The window Object
+var window = this;
+
+(function(){
+
+ // Browser Navigator
+
+ window.navigator = {
+ get userAgent(){
+ return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3";
+ }
+ };
+
+ var curLocation = (new java.io.File("./")).toURL();
+
+ window.__defineSetter__("location", function(url){
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url);
+ xhr.onreadystatechange = function(){
+ curLocation = new java.net.URL( curLocation, url );
+ window.document = xhr.responseXML;
+
+ var event = document.createEvent();
+ event.initEvent("load");
+ window.dispatchEvent( event );
+ };
+ xhr.send();
+ });
+
+ window.__defineGetter__("location", function(url){
+ return {
+ get protocol(){
+ return curLocation.getProtocol() + ":";
+ },
+ get href(){
+ return curLocation.toString();
+ },
+ toString: function(){
+ return this.href;
+ }
+ };
+ });
+
+ // Timers
+
+ var timers = [];
+
+ window.setTimeout = function(fn, time){
+ var num;
+ return num = setInterval(function(){
+ fn();
+ clearInterval(num);
+ }, time);
+ };
+
+ window.setInterval = function(fn, time){
+ var num = timers.length;
+
+ timers[num] = new java.lang.Thread(new java.lang.Runnable({
+ run: function(){
+ while (true){
+ java.lang.Thread.currentThread().sleep(time);
+ fn();
+ }
+ }
+ }));
+
+ timers[num].start();
+
+ return num;
+ };
+
+ window.clearInterval = function(num){
+ if ( timers[num] ) {
+ timers[num].stop();
+ delete timers[num];
+ }
+ };
+
+ // Window Events
+
+ var events = [{}];
+
+ window.addEventListener = function(type, fn){
+ if ( !this.uuid || this == window ) {
+ this.uuid = events.length;
+ events[this.uuid] = {};
+ }
+
+ if ( !events[this.uuid][type] )
+ events[this.uuid][type] = [];
+
+ if ( events[this.uuid][type].indexOf( fn ) < 0 )
+ events[this.uuid][type].push( fn );
+ };
+
+ window.removeEventListener = function(type, fn){
+ if ( !this.uuid || this == window ) {
+ this.uuid = events.length;
+ events[this.uuid] = {};
+ }
+
+ if ( !events[this.uuid][type] )
+ events[this.uuid][type] = [];
+
+ events[this.uuid][type] =
+ events[this.uuid][type].filter(function(f){
+ return f != fn;
+ });
+ };
+
+ window.dispatchEvent = function(event){
+ if ( event.type ) {
+ if ( this.uuid && events[this.uuid][event.type] ) {
+ var self = this;
+
+ events[this.uuid][event.type].forEach(function(fn){
+ fn.call( self, event );
+ });
+ }
+
+ if ( this["on" + event.type] )
+ this["on" + event.type].call( self, event );
+ }
+ };
+
+ // DOM Document
+
+ window.DOMDocument = function(file){
+ this._file = file;
+ this._dom = Packages.javax.xml.parsers.
+ DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder().parse(file);
+
+ if ( !obj_nodes.containsKey( this._dom ) )
+ obj_nodes.put( this._dom, this );
+ };
+
+ DOMDocument.prototype = {
+ createTextNode: function(text){
+ return makeNode( this._dom.createTextNode(
+ text.replace(/&/g, "&").replace(//g, ">")) );
+ },
+ createElement: function(name){
+ return makeNode( this._dom.createElement(name.toLowerCase()) );
+ },
+ getElementsByTagName: function(name){
+ return new DOMNodeList( this._dom.getElementsByTagName(
+ name.toLowerCase()) );
+ },
+ getElementById: function(id){
+ var elems = this._dom.getElementsByTagName("*");
+
+ for ( var i = 0; i < elems.length; i++ ) {
+ var elem = elems.item(i);
+ if ( elem.getAttribute("id") == id )
+ return makeNode(elem);
+ }
+
+ return null;
+ },
+ get body(){
+ return this.getElementsByTagName("body")[0];
+ },
+ get documentElement(){
+ return makeNode( this._dom.getDocumentElement() );
+ },
+ get ownerDocument(){
+ return null;
+ },
+ addEventListener: window.addEventListener,
+ removeEventListener: window.removeEventListener,
+ dispatchEvent: window.dispatchEvent,
+ get nodeName() {
+ return "#document";
+ },
+ importNode: function(node, deep){
+ return makeNode( this._dom.importNode(node._dom, deep) );
+ },
+ toString: function(){
+ return "Document" + (typeof this._file == "string" ?
+ ": " + this._file : "");
+ },
+ get innerHTML(){
+ return this.documentElement.outerHTML;
+ },
+
+ get defaultView(){
+ return {
+ getComputedStyle: function(elem){
+ return {
+ getPropertyValue: function(prop){
+ prop = prop.replace(/\-(\w)/g,function(m,c){
+ return c.toUpperCase();
+ });
+ var val = elem.style[prop];
+
+ if ( prop == "opacity" && val == "" )
+ val = "1";
+
+ return val;
+ }
+ };
+ }
+ };
+ },
+
+ createEvent: function(){
+ return {
+ type: "",
+ initEvent: function(type){
+ this.type = type;
+ }
+ };
+ }
+ };
+
+ function getDocument(node){
+ return obj_nodes.get(node);
+ }
+
+ // DOM NodeList
+
+ window.DOMNodeList = function(list){
+ this._dom = list;
+ this.length = list.getLength();
+
+ for ( var i = 0; i < this.length; i++ ) {
+ var node = list.item(i);
+ this[i] = makeNode( node );
+ }
+ };
+
+ DOMNodeList.prototype = {
+ toString: function(){
+ return "[ " +
+ Array.prototype.join.call( this, ", " ) + " ]";
+ },
+ get outerHTML(){
+ return Array.prototype.map.call(
+ this, function(node){return node.outerHTML;}).join('');
+ }
+ };
+
+ // DOM Node
+
+ window.DOMNode = function(node){
+ this._dom = node;
+ };
+
+ DOMNode.prototype = {
+ get nodeType(){
+ return this._dom.getNodeType();
+ },
+ get nodeValue(){
+ return this._dom.getNodeValue();
+ },
+ get nodeName() {
+ return this._dom.getNodeName();
+ },
+ cloneNode: function(deep){
+ return makeNode( this._dom.cloneNode(deep) );
+ },
+ get ownerDocument(){
+ return getDocument( this._dom.ownerDocument );
+ },
+ get documentElement(){
+ return makeNode( this._dom.documentElement );
+ },
+ get parentNode() {
+ return makeNode( this._dom.getParentNode() );
+ },
+ get nextSibling() {
+ return makeNode( this._dom.getNextSibling() );
+ },
+ get previousSibling() {
+ return makeNode( this._dom.getPreviousSibling() );
+ },
+ toString: function(){
+ return '"' + this.nodeValue + '"';
+ },
+ get outerHTML(){
+ return this.nodeValue;
+ }
+ };
+
+ // DOM Element
+
+ window.DOMElement = function(elem){
+ this._dom = elem;
+ this.style = {
+ get opacity(){ return this._opacity; },
+ set opacity(val){ this._opacity = val + ""; }
+ };
+
+ // Load CSS info
+ var styles = (this.getAttribute("style") || "").split(/\s*;\s*/);
+
+ for ( var i = 0; i < styles.length; i++ ) {
+ var style = styles[i].split(/\s*:\s*/);
+ if ( style.length == 2 )
+ this.style[ style[0] ] = style[1];
+ }
+ };
+
+ DOMElement.prototype = extend( new DOMNode(), {
+ get nodeName(){
+ return this.tagName.toUpperCase();
+ },
+ get tagName(){
+ return this._dom.getTagName();
+ },
+ toString: function(){
+ return "<" + this.tagName + (this.id ? "#" + this.id : "" ) + ">";
+ },
+ get outerHTML(){
+ var ret = "<" + this.tagName, attr = this.attributes;
+
+ for ( var i in attr )
+ ret += " " + i + "='" + attr[i] + "'";
+
+ if ( this.childNodes.length || this.nodeName == "SCRIPT" )
+ ret += ">" + this.childNodes.outerHTML +
+ "" + this.tagName + ">";
+ else
+ ret += "/>";
+
+ return ret;
+ },
+
+ get attributes(){
+ var attr = {}, attrs = this._dom.getAttributes();
+
+ for ( var i = 0; i < attrs.getLength(); i++ )
+ attr[ attrs.item(i).nodeName ] = attrs.item(i).nodeValue;
+
+ return attr;
+ },
+
+ get innerHTML(){
+ return this.childNodes.outerHTML;
+ },
+ set innerHTML(html){
+ html = html.replace(/<\/?([A-Z]+)/g, function(m){
+ return m.toLowerCase();
+ });
+
+ var nodes = this.ownerDocument.importNode(
+ new DOMDocument( new java.io.ByteArrayInputStream(
+ (new java.lang.String("" + html + " "))
+ .getBytes("UTF8"))).documentElement, true).childNodes;
+
+ while (this.firstChild)
+ this.removeChild( this.firstChild );
+
+ for ( var i = 0; i < nodes.length; i++ )
+ this.appendChild( nodes[i] );
+ },
+
+ get textContent(){
+ return nav(this.childNodes);
+
+ function nav(nodes){
+ var str = "";
+ for ( var i = 0; i < nodes.length; i++ )
+ if ( nodes[i].nodeType == 3 )
+ str += nodes[i].nodeValue;
+ else if ( nodes[i].nodeType == 1 )
+ str += nav(nodes[i].childNodes);
+ return str;
+ }
+ },
+ set textContent(text){
+ while (this.firstChild)
+ this.removeChild( this.firstChild );
+ this.appendChild( this.ownerDocument.createTextNode(text));
+ },
+
+ style: {},
+ clientHeight: 0,
+ clientWidth: 0,
+ offsetHeight: 0,
+ offsetWidth: 0,
+
+ get disabled() {
+ var val = this.getAttribute("disabled");
+ return val != "false" && !!val;
+ },
+ set disabled(val) { return this.setAttribute("disabled",val); },
+
+ get checked() {
+ var val = this.getAttribute("checked");
+ return val != "false" && !!val;
+ },
+ set checked(val) { return this.setAttribute("checked",val); },
+
+ get selected() {
+ if ( !this._selectDone ) {
+ this._selectDone = true;
+
+ if ( this.nodeName == "OPTION" && !this.parentNode.getAttribute("multiple") ) {
+ var opt = this.parentNode.getElementsByTagName("option");
+
+ if ( this == opt[0] ) {
+ var select = true;
+
+ for ( var i = 1; i < opt.length; i++ )
+ if ( opt[i].selected ) {
+ select = false;
+ break;
+ }
+
+ if ( select )
+ this.selected = true;
+ }
+ }
+ }
+
+ var val = this.getAttribute("selected");
+ return val != "false" && !!val;
+ },
+ set selected(val) { return this.setAttribute("selected",val); },
+
+ get className() { return this.getAttribute("class") || ""; },
+ set className(val) {
+ return this.setAttribute("class",
+ val.replace(/(^\s*|\s*$)/g,""));
+ },
+
+ get type() { return this.getAttribute("type") || ""; },
+ set type(val) { return this.setAttribute("type",val); },
+
+ get value() { return this.getAttribute("value") || ""; },
+ set value(val) { return this.setAttribute("value",val); },
+
+ get src() { return this.getAttribute("src") || ""; },
+ set src(val) { return this.setAttribute("src",val); },
+
+ get id() { return this.getAttribute("id") || ""; },
+ set id(val) { return this.setAttribute("id",val); },
+
+ getAttribute: function(name){
+ return this._dom.hasAttribute(name) ?
+ new String( this._dom.getAttribute(name) ) :
+ null;
+ },
+ setAttribute: function(name,value){
+ this._dom.setAttribute(name,value);
+ },
+ removeAttribute: function(name){
+ this._dom.removeAttribute(name);
+ },
+
+ get childNodes(){
+ return new DOMNodeList( this._dom.getChildNodes() );
+ },
+ get firstChild(){
+ return makeNode( this._dom.getFirstChild() );
+ },
+ get lastChild(){
+ return makeNode( this._dom.getLastChild() );
+ },
+ appendChild: function(node){
+ this._dom.appendChild( node._dom );
+ },
+ insertBefore: function(node,before){
+ this._dom.insertBefore( node._dom, before ? before._dom : before );
+ },
+ removeChild: function(node){
+ this._dom.removeChild( node._dom );
+ },
+
+ getElementsByTagName: DOMDocument.prototype.getElementsByTagName,
+
+ addEventListener: window.addEventListener,
+ removeEventListener: window.removeEventListener,
+ dispatchEvent: window.dispatchEvent,
+
+ click: function(){
+ var event = document.createEvent();
+ event.initEvent("click");
+ this.dispatchEvent(event);
+ },
+ submit: function(){
+ var event = document.createEvent();
+ event.initEvent("submit");
+ this.dispatchEvent(event);
+ },
+ focus: function(){
+ var event = document.createEvent();
+ event.initEvent("focus");
+ this.dispatchEvent(event);
+ },
+ blur: function(){
+ var event = document.createEvent();
+ event.initEvent("blur");
+ this.dispatchEvent(event);
+ },
+ get elements(){
+ return this.getElementsByTagName("*");
+ },
+ get contentWindow(){
+ return this.nodeName == "IFRAME" ? {
+ document: this.contentDocument
+ } : null;
+ },
+ get contentDocument(){
+ if ( this.nodeName == "IFRAME" ) {
+ if ( !this._doc )
+ this._doc = new DOMDocument(
+ new java.io.ByteArrayInputStream((new java.lang.String(
+ " "))
+ .getBytes("UTF8")));
+ return this._doc;
+ } else
+ return null;
+ }
+ });
+
+ // Helper method for extending one object with another
+
+ function extend(a,b) {
+ for ( var i in b ) {
+ var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+
+ if ( g || s ) {
+ if ( g )
+ a.__defineGetter__(i, g);
+ if ( s )
+ a.__defineSetter__(i, s);
+ } else
+ a[i] = b[i];
+ }
+ return a;
+ }
+
+ // Helper method for generating the right
+ // DOM objects based upon the type
+
+ var obj_nodes = new java.util.HashMap();
+
+ function makeNode(node){
+ if ( node ) {
+ if ( !obj_nodes.containsKey( node ) )
+ obj_nodes.put( node, node.getNodeType() ==
+ Packages.org.w3c.dom.Node.ELEMENT_NODE ?
+ new DOMElement( node ) : new DOMNode( node ) );
+
+ return obj_nodes.get(node);
+ } else
+ return null;
+ }
+
+ // XMLHttpRequest
+ // Originally implemented by Yehuda Katz
+
+ window.XMLHttpRequest = function(){
+ this.headers = {};
+ this.responseHeaders = {};
+ };
+
+ XMLHttpRequest.prototype = {
+ open: function(method, url, async, user, password){
+ this.readyState = 1;
+ if (async)
+ this.async = true;
+ this.method = method || "GET";
+ this.url = url;
+ this.onreadystatechange();
+ },
+ setRequestHeader: function(header, value){
+ this.headers[header] = value;
+ },
+ getResponseHeader: function(header){ },
+ send: function(data){
+ var self = this;
+
+ function makeRequest(){
+ var url = new java.net.URL(curLocation, self.url);
+
+ if ( url.getProtocol() == "file" ) {
+ if ( self.method == "PUT" ) {
+ var out = new java.io.FileWriter(
+ new java.io.File( new java.net.URI( url.toString() ) ) ),
+ text = new java.lang.String( data || "" );
+
+ out.write( text, 0, text.length() );
+ out.flush();
+ out.close();
+ } else if ( self.method == "DELETE" ) {
+ var file = new java.io.File( new java.net.URI( url.toString() ) );
+ file["delete"]();
+ } else {
+ var connection = url.openConnection();
+ connection.connect();
+ handleResponse();
+ }
+ } else {
+ var connection = url.openConnection();
+
+ connection.setRequestMethod( self.method );
+
+ // Add headers to Java connection
+ for (var header in self.headers)
+ connection.addRequestProperty(header, self.headers[header]);
+
+ connection.connect();
+
+ // Stick the response headers into responseHeaders
+ for (var i = 0; ; i++) {
+ var headerName = connection.getHeaderFieldKey(i);
+ var headerValue = connection.getHeaderField(i);
+ if (!headerName && !headerValue) break;
+ if (headerName)
+ self.responseHeaders[headerName] = headerValue;
+ }
+
+ handleResponse();
+ }
+
+ function handleResponse(){
+ self.readyState = 4;
+ self.status = parseInt(connection.responseCode) || undefined;
+ self.statusText = connection.responseMessage || "";
+
+ var stream = new java.io.InputStreamReader(connection.getInputStream()),
+ buffer = new java.io.BufferedReader(stream), line;
+
+ while ((line = buffer.readLine()) != null)
+ self.responseText += line;
+
+ self.responseXML = null;
+
+ if ( self.responseText.match(/^\s*) ) {
+ try {
+ self.responseXML = new DOMDocument(
+ new java.io.ByteArrayInputStream(
+ (new java.lang.String(
+ self.responseText)).getBytes("UTF8")));
+ } catch(e) {}
+ }
+ }
+
+ self.onreadystatechange();
+ }
+
+ if (this.async)
+ (new java.lang.Thread(new java.lang.Runnable({
+ run: makeRequest
+ }))).start();
+ else
+ makeRequest();
+ },
+ abort: function(){},
+ onreadystatechange: function(){},
+ getResponseHeader: function(header){
+ if (this.readyState < 3)
+ throw new Error("INVALID_STATE_ERR");
+ else {
+ var returnedHeaders = [];
+ for (var rHeader in this.responseHeaders) {
+ if (rHeader.match(new Regexp(header, "i")))
+ returnedHeaders.push(this.responseHeaders[rHeader]);
+ }
+
+ if (returnedHeaders.length)
+ return returnedHeaders.join(", ");
+ }
+
+ return null;
+ },
+ getAllResponseHeaders: function(header){
+ if (this.readyState < 3)
+ throw new Error("INVALID_STATE_ERR");
+ else {
+ var returnedHeaders = [];
+
+ for (var header in this.responseHeaders)
+ returnedHeaders.push( header + ": " + this.responseHeaders[header] );
+
+ return returnedHeaders.join("\r\n");
+ }
+ },
+ async: true,
+ readyState: 0,
+ responseText: "",
+ status: 0
+ };
+})();
diff --git a/build/runtest/test.js b/build/runtest/test.js
new file mode 100644
index 00000000..a9721620
--- /dev/null
+++ b/build/runtest/test.js
@@ -0,0 +1,21 @@
+// Init
+load("build/runtest/env.js");
+
+window.location = "test/index.html";
+
+window.onload = function(){
+ // Load the test runner
+ load("dist/jquery.js","build/runtest/testrunner.js");
+
+ // Load the tests
+ load(
+ "test/unit/core.js",
+ "test/unit/selector.js",
+ "test/unit/event.js"
+ //"test/unit/fx.js",
+ //"test/unit/ajax.js"
+ );
+
+ // Display the results
+ results();
+};
diff --git a/build/runtest/testrunner.js b/build/runtest/testrunner.js
new file mode 100644
index 00000000..363cd9bd
--- /dev/null
+++ b/build/runtest/testrunner.js
@@ -0,0 +1,197 @@
+function test(name, fn){
+ expected = -1;
+ numTests = 0;
+ reset();
+
+ fn();
+
+ if ( expected != -1 && expected != numTests )
+ log( false, "Wrong number of tests run. " + numTests + " ran, expected " + expected );
+}
+
+var orig = document.getElementById('main').innerHTML;
+
+/**
+ * Resets the test setup. Useful for tests that modify the DOM.
+ */
+function reset() {
+ document.getElementById('main').innerHTML = orig;
+}
+
+var currentModule = "";
+
+// call on start of module test to prepend name to all tests
+function module(moduleName) {
+ currentModule = moduleName;
+}
+
+var expected = -1;
+
+/**
+ * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
+ */
+function expect(asserts) {
+ expected = asserts;
+}
+
+/**
+ * Asserts true.
+ * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
+ */
+function ok(a, msg) {
+ log( !!a, msg );
+}
+
+/**
+ * Asserts that two arrays are the same
+ */
+function isSet(a, b, msg) {
+ var ret = true;
+ if ( a && b && a.length != undefined && a.length == b.length ) {
+ for ( var i = 0; i < a.length; i++ ) {
+ if ( a[i] != b[i] )
+ ret = false;
+ }
+ } else
+ ret = false;
+ if ( !ret )
+ log( ret, msg + " expected: " + serialArray(b) + " result: " + serialArray(a) );
+ else
+ log( ret, msg );
+}
+
+/**
+ * Asserts that two objects are equivalent
+ */
+function isObj(a, b, msg) {
+ var ret = true;
+
+ if ( a && b ) {
+ for ( var i in a )
+ if ( a[i] != b[i] )
+ ret = false;
+
+ for ( i in b )
+ if ( a[i] != b[i] )
+ ret = false;
+ } else
+ ret = false;
+
+ log( ret, msg );
+}
+
+function serialArray( a ) {
+ var r = [];
+
+ if ( a && a.length )
+ for ( var i = 0; i < a.length; i++ ) {
+ var str = a[i] ? a[i].nodeName : "";
+ if ( str ) {
+ str = str.toLowerCase();
+ if ( a[i].id )
+ str += "#" + a[i].id;
+ } else
+ str = a[i];
+ r.push( str );
+ }
+
+ return "[ " + r.join(", ") + " ]"
+}
+
+/**
+ * Returns an array of elements with the given IDs, eg.
+ * @example q("main", "foo", "bar")
+ * @result [,
, ]
+ */
+function q() {
+ var r = [];
+ for ( var i = 0; i < arguments.length; i++ )
+ r.push( document.getElementById( arguments[i] ) );
+ return r;
+}
+
+/**
+ * Asserts that a select matches the given IDs
+ * @example t("Check for something", "//[a]", ["foo", "baar"]);
+ * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
+ */
+function t(a,b,c) {
+ var f = jQuery(b);
+ var s = "";
+ for ( var i = 0; i < f.length; i++ )
+ s += (s && ",") + '"' + f[i].id + '"';
+ isSet(f, q.apply(q,c), a + " (" + b + ")");
+}
+
+/**
+ * Checks that the first two arguments are equal, with an optional message.
+ * Prints out both expected and actual values on failure.
+ *
+ * Prefered to ok( expected == actual, message )
+ *
+ * @example equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
+ *
+ * @param Object expected
+ * @param Object actual
+ * @param String message (optional)
+ */
+function equals(expected, actual, message) {
+ var result = expected == actual;
+ message = message || (result ? "okay" : "failed");
+ log( result, result ? message + ": " + expected : message + " expected: " + expected + " actual: " + actual );
+}
+
+var numTests = 0, total = 0, pass = 0, fail = 0;
+
+function log(state, msg){
+ print( (state ? "PASS" : "FAIL") + " (" + (++total) + ") " +
+ (currentModule ? "[" + currentModule + "] " : "") + msg );
+
+ numTests++;
+
+ if ( state )
+ pass++;
+ else
+ fail++;
+}
+
+function results(){
+ print( pass + " Passed, " + fail + " Failed" );
+}
+
+function start(){}
+function stop(){}
+
+/**
+ * Trigger an event on an element.
+ *
+ * @example triggerEvent( document.body, "click" );
+ *
+ * @param DOMElement elem
+ * @param String type
+ */
+function triggerEvent( elem, type, event ) {
+/*
+ if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
+ event = document.createEvent("MouseEvents");
+ event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+ 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ elem.dispatchEvent( event );
+ } else if ( jQuery.browser.msie ) {
+ elem.fireEvent("on"+type);
+ }
+*/
+}
+
+/**
+ * Add random number to url to stop IE from caching
+ *
+ * @example url("data/test.html")
+ * @result "data/test.html?10538358428943"
+ *
+ * @example url("data/test.php?foo=bar")
+ * @result "data/test.php?foo=bar&10538358345554"
+ */
+function url(value) {
+ return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
+}
\ No newline at end of file
diff --git a/speed/benchmarker.css b/build/speed/benchmarker.css
old mode 100644
new mode 100755
similarity index 100%
rename from speed/benchmarker.css
rename to build/speed/benchmarker.css
diff --git a/speed/benchmarker.js b/build/speed/benchmarker.js
old mode 100644
new mode 100755
similarity index 79%
rename from speed/benchmarker.js
rename to build/speed/benchmarker.js
index bfcc16ed..73953d11
--- a/speed/benchmarker.js
+++ b/build/speed/benchmarker.js
@@ -1,42 +1,18 @@
jQuery.benchmarker.tests = [
- // Selectors from:
- // http://ejohn.org/blog/selectors-that-people-actually-use/
- /*
- // For Amazon.com
- "#navAmazonLogo", "#navSwmSkedPop",
- ".navbar", ".navGreeting",
- "div", "table",
- "img.navCrossshopTabCap", "span.navGreeting",
- "#navbar table", "#navidWelcomeMsg span",
- "div#navbar", "ul#navAmazonLogo",
- "#navAmazonLogo .navAmazonLogoGatewayPanel", "#navidWelcomeMsg .navGreeting",
- ".navbar .navAmazonLogoGatewayPanel", ".navbar .navGreeting",
- "*",
- "#navAmazonLogo li.navAmazonLogoGatewayPanel", "#navidWelcomeMsg span.navGreeting",
- "a[name=top]", "form[name=site-search]",
- ".navbar li", ".navbar span",
- "[name=top]", "[name=site-search]",
- "ul li", "a img",
- "#navbar #navidWelcomeMsg", "#navbar #navSwmDWPop",
- "#navbar ul li", "#navbar a img"
- */
- // For Yahoo.com
- "#page", "#masthead", "#mastheadhd",
- ".mastheadbd", ".first", ".on",
- "div", "li", "a",
- "div.mastheadbd", "li.first", "li.on",
- "#page div", "#dtba span",
- "div#page", "div#masthead",
- "#page .mastheadbd", "#page .first",
- ".outer_search_container .search_container", ".searchbox_container .inputtext",
- "*",
- "#page div.mastheadbd", "#page li.first",
- "input[name=p]", "a[name=marketplace]",
- ".outer_search_container div", ".searchbox_container span",
- "[name=p]", "[name=marketplace]",
- "ul li", "form input",
- "#page #e2econtent", "#page #e2e"
- ];
+ "*",
+ "body", "body div", "div",
+ "div div div", "div div", ".dialog", "div.dialog", "div .dialog",
+ "#speech5", "div#speech5", "div #speech5", "div > div", "div.scene div.dialog",
+ "div#scene1.scene div.dialog div", "#scene1 #speech1", "body > div.dialog div#speech5",
+ "div:nth-child(even)", "div:nth-child(odd)",
+ "div:nth-child(1)", "div:nth-child(2n)",
+ "div:nth-child(2n+3)", "div:first-child",
+ "div:last-child", "div:only-child",
+ "div:contains(CELIA)",
+ "div ~ div", "div + div",
+ "div[@class]", "div[@class=dialog]", "div[@class!=dialog]",
+ "div[@class^=dialog]", "div[@class$=dialog]", "div[@class*=dialog]"
+ ]
jQuery.fn.benchmark = function() {
this.each(function() {
@@ -62,8 +38,8 @@
jQuery("button.retryTies").bind("click", function() { jQuery("tr:has(td.tie) td.test").benchmark() })
- jQuery("button.selectAll").bind("click", function() { jQuery("input[type=checkbox]").each(function() { this.checked = true }) })
- jQuery("button.deselectAll").bind("click", function() { jQuery("input[type=checkbox]").each(function() { this.checked = false }) })
+ jQuery("button.selectAll").bind("click", function() { jQuery("input[@type=checkbox]").each(function() { this.checked = true }) })
+ jQuery("button.deselectAll").bind("click", function() { jQuery("input[@type=checkbox]").each(function() { this.checked = false }) })
jQuery("#addTest").bind("click", function() {
jQuery("table").append("Add ");
@@ -101,6 +77,9 @@
var times = times || 50;
var el = list[0];
var code = jQuery(el).text().replace(/^-/, "");
+ if(!libraries[0].match(/^jQ/)) {
+ code = code.replace(/@/, "");
+ }
var timeArr = []
for(i = 0; i < times + 2; i++) {
var time = new Date()
diff --git a/build/speed/index.html b/build/speed/index.html
new file mode 100755
index 00000000..b1561892
--- /dev/null
+++ b/build/speed/index.html
@@ -0,0 +1,513 @@
+
+
+
+
+
+ Speed Test
+
+
+
+
+
+
+
+
+Speed Test
+
+
+
Using the following selector expressions ( times each):
+
NOTE: Number shown is an average.
+
+ Select All
+ Deselect All
+
+ Run Tests
+ Retry Ties
+
+
+
+
+ Run?
+ Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select All
+ Deselect All
+ Run Tests
+ Retry Ties
+ +
+
+
+
+
+
As You Like It
+
+ by William Shakespeare
+
+
+
+
ACT I, SCENE III. A room in the palace.
+
+
Enter CELIA and ROSALIND
+
+
+
+
CELIA
+
+
+
Why, cousin! why, Rosalind! Cupid have mercy! not a word?
+
+
+
ROSALIND
+
+
+
Not one to throw at a dog.
+
+
+
CELIA
+
+
No, thy words are too precious to be cast away upon
+
+
curs; throw some of them at me; come, lame me with reasons.
+
+
+
ROSALIND
+
+
CELIA
+
+
But is all this for your father?
+
+
+
+
+
Then there were two cousins laid up; when the one
+
should be lamed with reasons and the other mad
+
without any.
+
+
+
ROSALIND
+
+
No, some of it is for my child's father. O, how
+
+
full of briers is this working-day world!
+
+
+
CELIA
+
+
+
+
They are but burs, cousin, thrown upon thee in
+
holiday foolery: if we walk not in the trodden
+
+
paths our very petticoats will catch them.
+
+
+
ROSALIND
+
+
+
I could shake them off my coat: these burs are in my heart.
+
+
+
CELIA
+
+
+
+
ROSALIND
+
+
+
I would try, if I could cry 'hem' and have him.
+
+
+
CELIA
+
+
+
Come, come, wrestle with thy affections.
+
+
+
+
ROSALIND
+
+
O, they take the part of a better wrestler than myself!
+
+
+
+
CELIA
+
+
+
O, a good wish upon you! you will try in time, in
+
despite of a fall. But, turning these jests out of
+
service, let us talk in good earnest: is it
+
+
possible, on such a sudden, you should fall into so
+
strong a liking with old Sir Rowland's youngest son?
+
+
+
ROSALIND
+
+
The duke my father loved his father dearly.
+
+
+
+
CELIA
+
+
+
Doth it therefore ensue that you should love his son
+
+
dearly? By this kind of chase, I should hate him,
+
for my father hated his father dearly; yet I hate
+
+
not Orlando.
+
+
+
ROSALIND
+
+
+
No, faith, hate him not, for my sake.
+
+
+
CELIA
+
+
+
Why should I not? doth he not deserve well?
+
+
+
+
ROSALIND
+
+
+
Let me love him for that, and do you love him
+
because I do. Look, here comes the duke.
+
+
+
CELIA
+
+
+
With his eyes full of anger.
+
Enter DUKE FREDERICK, with Lords
+
+
+
DUKE FREDERICK
+
+
+
Mistress, dispatch you with your safest haste
+
+
And get you from our court.
+
+
+
ROSALIND
+
+
+
+
DUKE FREDERICK
+
+
You, cousin
+
Within these ten days if that thou be'st found
+
+
So near our public court as twenty miles,
+
Thou diest for it.
+
+
+
+
ROSALIND
+
+
I do beseech your grace,
+
+
Let me the knowledge of my fault bear with me:
+
If with myself I hold intelligence
+
+
Or have acquaintance with mine own desires,
+
If that I do not dream or be not frantic,--
+
As I do trust I am not--then, dear uncle,
+
+
Never so much as in a thought unborn
+
+
Did I offend your highness.
+
+
+
+
DUKE FREDERICK
+
+
Thus do all traitors:
+
If their purgation did consist in words,
+
+
They are as innocent as grace itself:
+
+
Let it suffice thee that I trust thee not.
+
+
+
+
ROSALIND
+
+
Yet your mistrust cannot make me a traitor:
+
+
Tell me whereon the likelihood depends.
+
+
+
+
DUKE FREDERICK
+
+
Thou art thy father's daughter; there's enough.
+
+
+
ROSALIND
+
+
+
So was I when your highness took his dukedom;
+
So was I when your highness banish'd him:
+
Treason is not inherited, my lord;
+
Or, if we did derive it from our friends,
+
+
What's that to me? my father was no traitor:
+
+
Then, good my liege, mistake me not so much
+
To think my poverty is treacherous.
+
+
+
+
CELIA
+
+
+
Dear sovereign, hear me speak.
+
+
+
+
DUKE FREDERICK
+
+
Ay, Celia; we stay'd her for your sake,
+
Else had she with her father ranged along.
+
+
+
+
CELIA
+
+
I did not then entreat to have her stay;
+
It was your pleasure and your own remorse:
+
I was too young that time to value her;
+
+
But now I know her: if she be a traitor,
+
+
Why so am I; we still have slept together,
+
Rose at an instant, learn'd, play'd, eat together,
+
And wheresoever we went, like Juno's swans,
+
+
Still we went coupled and inseparable.
+
+
+
DUKE FREDERICK
+
+
+
She is too subtle for thee; and her smoothness,
+
Her very silence and her patience
+
Speak to the people, and they pity her.
+
Thou art a fool: she robs thee of thy name;
+
+
And thou wilt show more bright and seem more virtuous
+
+
When she is gone. Then open not thy lips:
+
Firm and irrevocable is my doom
+
Which I have pass'd upon her; she is banish'd.
+
+
+
CELIA
+
+
+
Pronounce that sentence then on me, my liege:
+
I cannot live out of her company.
+
+
+
DUKE FREDERICK
+
+
You are a fool. You, niece, provide yourself:
+
+
If you outstay the time, upon mine honour,
+
And in the greatness of my word, you die.
+
Exeunt DUKE FREDERICK and Lords
+
+
+
CELIA
+
+
+
O my poor Rosalind, whither wilt thou go?
+
+
Wilt thou change fathers? I will give thee mine.
+
I charge thee, be not thou more grieved than I am.
+
+
+
ROSALIND
+
+
+
+
CELIA
+
+
Thou hast not, cousin;
+
+
Prithee be cheerful: know'st thou not, the duke
+
+
Hath banish'd me, his daughter?
+
+
+
ROSALIND
+
+
+
CELIA
+
+
No, hath not? Rosalind lacks then the love
+
+
Which teacheth thee that thou and I am one:
+
Shall we be sunder'd? shall we part, sweet girl?
+
+
No: let my father seek another heir.
+
+
Therefore devise with me how we may fly,
+
Whither to go and what to bear with us;
+
And do not seek to take your change upon you,
+
To bear your griefs yourself and leave me out;
+
For, by this heaven, now at our sorrows pale,
+
+
Say what thou canst, I'll go along with thee.
+
+
+
+
ROSALIND
+
+
Why, whither shall we go?
+
+
+
CELIA
+
+
+
To seek my uncle in the forest of Arden.
+
+
+
ROSALIND
+
+
+
Alas, what danger will it be to us,
+
+
Maids as we are, to travel forth so far!
+
Beauty provoketh thieves sooner than gold.
+
+
+
CELIA
+
+
+
I'll put myself in poor and mean attire
+
+
And with a kind of umber smirch my face;
+
The like do you: so shall we pass along
+
+
And never stir assailants.
+
+
+
ROSALIND
+
+
+
Were it not better,
+
Because that I am more than common tall,
+
That I did suit me all points like a man?
+
A gallant curtle-axe upon my thigh,
+
+
A boar-spear in my hand; and--in my heart
+
+
Lie there what hidden woman's fear there will--
+
+
We'll have a swashing and a martial outside,
+
As many other mannish cowards have
+
That do outface it with their semblances.
+
+
+
+
CELIA
+
+
+
What shall I call thee when thou art a man?
+
+
+
ROSALIND
+
+
+
I'll have no worse a name than Jove's own page;
+
And therefore look you call me Ganymede.
+
+
But what will you be call'd?
+
+
+
CELIA
+
+
+
Something that hath a reference to my state
+
No longer Celia, but Aliena.
+
+
+
+
ROSALIND
+
+
+
But, cousin, what if we assay'd to steal
+
The clownish fool out of your father's court?
+
Would he not be a comfort to our travel?
+
+
+
+
CELIA
+
+
+
He'll go along o'er the wide world with me;
+
+
Leave me alone to woo him. Let's away,
+
And get our jewels and our wealth together,
+
+
Devise the fittest time and safest way
+
To hide us from pursuit that will be made
+
+
After my flight. Now go we in content
+
To liberty and not to banishment.
+
Exeunt
+
+
+
+
+
+
+
+
+
diff --git a/build/speed/jquery-1.2.1.js b/build/speed/jquery-1.2.1.js
new file mode 100644
index 00000000..9fb3a8e5
--- /dev/null
+++ b/build/speed/jquery-1.2.1.js
@@ -0,0 +1,2992 @@
+(function(){
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
+ * $Rev: 3353 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( typeof jQuery != "undefined" )
+ var _jQuery = jQuery;
+
+var jQuery = window.jQuery = function(selector, context) {
+ // If the context is a namespace object, return a new object
+ return this instanceof jQuery ?
+ this.init(selector, context) :
+ new jQuery(selector, context);
+};
+
+// Map over the $ in case of overwrite
+if ( typeof $ != "undefined" )
+ var _$ = $;
+
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function(selector, context) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle HTML strings
+ if ( typeof selector == "string" ) {
+ var m = quickExpr.exec(selector);
+ if ( m && (m[1] || !context) ) {
+ // HANDLE: $(html) -> $(array)
+ if ( m[1] )
+ selector = jQuery.clean( [ m[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var tmp = document.getElementById( m[3] );
+ if ( tmp )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( tmp.id != m[3] )
+ return jQuery().find( selector );
+ else {
+ this[0] = tmp;
+ this.length = 1;
+ return this;
+ }
+ else
+ selector = [];
+ }
+
+ // HANDLE: $(expr)
+ } else
+ return new jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction(selector) )
+ return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+ return this.setArray(
+ // HANDLE: $(array)
+ selector.constructor == Array && selector ||
+
+ // HANDLE: $(arraylike)
+ // Watch for when an array-like object is passed as the selector
+ (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+ // HANDLE: $(*)
+ [ selector ] );
+ },
+
+ jquery: "1.2.1",
+
+ size: function() {
+ return this.length;
+ },
+
+ length: 0,
+
+ get: function( num ) {
+ return num == undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[num];
+ },
+
+ pushStack: function( a ) {
+ var ret = jQuery(a);
+ ret.prevObject = this;
+ return ret;
+ },
+
+ setArray: function( a ) {
+ this.length = 0;
+ Array.prototype.push.apply( this, a );
+ return this;
+ },
+
+ each: function( fn, args ) {
+ return jQuery.each( this, fn, args );
+ },
+
+ index: function( obj ) {
+ var pos = -1;
+ this.each(function(i){
+ if ( this == obj ) pos = i;
+ });
+ return pos;
+ },
+
+ attr: function( key, value, type ) {
+ var obj = key;
+
+ // Look for the case where we're accessing a style value
+ if ( key.constructor == String )
+ if ( value == undefined )
+ return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
+ else {
+ obj = {};
+ obj[ key ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(index){
+ // Set all the styles
+ for ( var prop in obj )
+ jQuery.attr(
+ type ? this.style : this,
+ prop, jQuery.prop(this, obj[prop], type, index, prop)
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function(e) {
+ if ( typeof e != "object" && e != null )
+ return this.empty().append( document.createTextNode( e ) );
+
+ var t = "";
+ jQuery.each( e || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ t += this.nodeType != 1 ?
+ this.nodeValue : jQuery.fn.text([ this ]);
+ });
+ });
+ return t;
+ },
+
+ wrapAll: function(html) {
+ if ( this[0] )
+ // The elements to wrap the target around
+ jQuery(html, this[0].ownerDocument)
+ .clone()
+ .insertBefore(this[0])
+ .map(function(){
+ var elem = this;
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+ return elem;
+ })
+ .append(this);
+
+ return this;
+ },
+
+ wrapInner: function(html) {
+ return this.each(function(){
+ jQuery(this).contents().wrapAll(html);
+ });
+ },
+
+ wrap: function(html) {
+ return this.each(function(){
+ jQuery(this).wrapAll(html);
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, 1, function(a){
+ this.appendChild( a );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, -1, function(a){
+ this.insertBefore( a, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, 1, function(a){
+ this.parentNode.insertBefore( a, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, -1, function(a){
+ this.parentNode.insertBefore( a, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery([]);
+ },
+
+ find: function(t) {
+ var data = jQuery.map(this, function(a){ return jQuery.find(t,a); });
+ return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ?
+ jQuery.unique( data ) : data );
+ },
+
+ clone: function(events) {
+ // Do the clone
+ var ret = this.map(function(){
+ return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] != undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if (events === true)
+ this.find("*").andSelf().each(function(i) {
+ var events = jQuery.data(this, "events");
+ for ( var type in events )
+ for ( var handler in events[type] )
+ jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data);
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function(t) {
+ return this.pushStack(
+ jQuery.isFunction( t ) &&
+ jQuery.grep(this, function(el, index){
+ return t.apply(el, [index]);
+ }) ||
+
+ jQuery.multiFilter(t,this) );
+ },
+
+ not: function(t) {
+ return this.pushStack(
+ t.constructor == String &&
+ jQuery.multiFilter(t, this, true) ||
+
+ jQuery.grep(this, function(a) {
+ return ( t.constructor == Array || t.jquery )
+ ? jQuery.inArray( a, t ) < 0
+ : a != t;
+ })
+ );
+ },
+
+ add: function(t) {
+ return this.pushStack( jQuery.merge(
+ this.get(),
+ t.constructor == String ?
+ jQuery(t).get() :
+ t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ?
+ t : [t] )
+ );
+ },
+
+ is: function(expr) {
+ return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
+ },
+
+ hasClass: function(expr) {
+ return this.is("." + expr);
+ },
+
+ val: function( val ) {
+ if ( val == undefined ) {
+ if ( this.length ) {
+ var elem = this[0];
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName(elem, "select") ) {
+ var index = elem.selectedIndex,
+ a = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[i];
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value;
+
+ // We don't need an array for one selects
+ if ( one )
+ return val;
+
+ // Multi-Selects return an array
+ a.push(val);
+ }
+ }
+
+ return a;
+
+ // Everything else, we just grab the value
+ } else
+ return this[0].value.replace(/\r/g, "");
+ }
+ } else
+ return this.each(function(){
+ if ( val.constructor == Array && /radio|checkbox/.test(this.type) )
+ this.checked = (jQuery.inArray(this.value, val) >= 0 ||
+ jQuery.inArray(this.name, val) >= 0);
+ else if ( jQuery.nodeName(this, "select") ) {
+ var tmp = val.constructor == Array ? val : [val];
+
+ jQuery("option", this).each(function(){
+ this.selected = (jQuery.inArray(this.value, tmp) >= 0 ||
+ jQuery.inArray(this.text, tmp) >= 0);
+ });
+
+ if ( !tmp.length )
+ this.selectedIndex = -1;
+ } else
+ this.value = val;
+ });
+ },
+
+ html: function( val ) {
+ return val == undefined ?
+ ( this.length ? this[0].innerHTML : null ) :
+ this.empty().append( val );
+ },
+
+ replaceWith: function( val ) {
+ return this.after( val ).remove();
+ },
+
+ eq: function(i){
+ return this.slice(i, i+1);
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
+
+ map: function(fn) {
+ return this.pushStack(jQuery.map( this, function(elem,i){
+ return fn.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function(args, table, dir, fn) {
+ var clone = this.length > 1, a;
+
+ return this.each(function(){
+ if ( !a ) {
+ a = jQuery.clean(args, this.ownerDocument);
+ if ( dir < 0 )
+ a.reverse();
+ }
+
+ var obj = this;
+
+ if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
+
+ jQuery.each( a, function(){
+ var elem = clone ? this.cloneNode(true) : this;
+ if ( !evalScript(0, elem) )
+ fn.call( obj, elem );
+ });
+ });
+ }
+};
+
+function evalScript(i, elem){
+ var script = jQuery.nodeName(elem, "script");
+
+ if ( script ) {
+ if ( elem.src )
+ jQuery.ajax({ url: elem.src, async: false, dataType: "script" });
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild(elem);
+
+ } else if ( elem.nodeType == 1 )
+ jQuery("script", elem).each(evalScript);
+
+ return script;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( al == 1 ) {
+ target = this;
+ a = 0;
+ }
+
+ var prop;
+
+ for ( ; a < al; a++ )
+ // Only deal with non-null/undefined values
+ if ( (prop = arguments[a]) != null )
+ // Extend the base object
+ for ( var i in prop ) {
+ // Prevent never-ending loop
+ if ( target == prop[i] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && typeof prop[i] == 'object' && target[i] )
+ jQuery.extend( target[i], prop[i] );
+
+ // Don't bring in undefined values
+ else if ( prop[i] != undefined )
+ target[i] = prop[i];
+ }
+
+ // Return the modified object
+ return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {};
+
+jQuery.extend({
+ noConflict: function(deep) {
+ window.$ = _$;
+ if ( deep )
+ window.jQuery = _jQuery;
+ return jQuery;
+ },
+
+ // This may seem like some crazy code, but trust me when I say that this
+ // is the only cross-browser way to do this. --John
+ isFunction: function( fn ) {
+ return !!fn && typeof fn != "string" && !fn.nodeName &&
+ fn.constructor != Array && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a XML document
+ isXMLDoc: function(elem) {
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ // Evaluates Async. in Safari 2 :-(
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+ if ( data ) {
+ if ( window.execScript )
+ window.execScript( data );
+ else if ( jQuery.browser.safari )
+ // safari doesn't provide a synchronous global eval
+ window.setTimeout( data, 0 );
+ else
+ eval.call( window, data );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data != undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ? jQuery.cache[ id ][ name ] : id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+ for ( name in jQuery.cache[ id ] ) break;
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+
+ // args is for internal usage only
+ each: function( obj, fn, args ) {
+ if ( args ) {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.apply( obj[i], args );
+ else
+ for ( var i = 0, ol = obj.length; i < ol; i++ )
+ if ( fn.apply( obj[i], args ) === false ) break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.call( obj[i], i, obj[i] );
+ else
+ for ( var i = 0, ol = obj.length, val = obj[0];
+ i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){}
+ }
+
+ return obj;
+ },
+
+ prop: function(elem, value, type, index, prop){
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, [index] );
+
+ // exclude the following css properties to add px
+ var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+ // Handle passing in a number to a CSS property
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, c ){
+ jQuery.each( (c || "").split(/\s+/), function(i, cur){
+ if ( !jQuery.className.has( elem.className, cur ) )
+ elem.className += ( elem.className ? " " : "" ) + cur;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, c ){
+ elem.className = c != undefined ?
+ jQuery.grep( elem.className.split(/\s+/), function(cur){
+ return !jQuery.className.has( c, cur );
+ }).join(" ") : "";
+ },
+
+ // internal only, use is(".class")
+ has: function( t, c ) {
+ return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ swap: function(e,o,f) {
+ for ( var i in o ) {
+ e.style["old"+i] = e.style[i];
+ e.style[i] = o[i];
+ }
+ f.apply( e, [] );
+ for ( var i in o )
+ e.style[i] = e.style["old"+i];
+ },
+
+ css: function(e,p) {
+ if ( p == "height" || p == "width" ) {
+ var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
+
+ jQuery.each( d, function(){
+ old["padding" + this] = 0;
+ old["border" + this + "Width"] = 0;
+ });
+
+ jQuery.swap( e, old, function() {
+ if ( jQuery(e).is(':visible') ) {
+ oHeight = e.offsetHeight;
+ oWidth = e.offsetWidth;
+ } else {
+ e = jQuery(e.cloneNode(true))
+ .find(":radio").removeAttr("checked").end()
+ .css({
+ visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
+ }).appendTo(e.parentNode)[0];
+
+ var parPos = jQuery.css(e.parentNode,"position") || "static";
+ if ( parPos == "static" )
+ e.parentNode.style.position = "relative";
+
+ oHeight = e.clientHeight;
+ oWidth = e.clientWidth;
+
+ if ( parPos == "static" )
+ e.parentNode.style.position = "static";
+
+ e.parentNode.removeChild(e);
+ }
+ });
+
+ return p == "height" ? oHeight : oWidth;
+ }
+
+ return jQuery.curCSS( e, p );
+ },
+
+ curCSS: function(elem, prop, force) {
+ var ret, stack = [], swap = [];
+
+ // A helper method for determining if an element's values are broken
+ function color(a){
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle(a,null);
+ return !ret || ret.getPropertyValue("color") == "";
+ }
+
+ if (prop == "opacity" && jQuery.browser.msie) {
+ ret = jQuery.attr(elem.style, "opacity");
+ return ret == "" ? "1" : ret;
+ }
+
+ if (prop.match(/float/i))
+ prop = styleFloat;
+
+ if (!force && elem.style[prop])
+ ret = elem.style[prop];
+
+ else if (document.defaultView && document.defaultView.getComputedStyle) {
+
+ if (prop.match(/float/i))
+ prop = "float";
+
+ prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
+ var cur = document.defaultView.getComputedStyle(elem, null);
+
+ if ( cur && !color(elem) )
+ ret = cur.getPropertyValue(prop);
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( a = 0; a < stack.length; a++ )
+ if ( color(stack[a]) ) {
+ swap[a] = stack[a].style.display;
+ stack[a].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = prop == "display" && swap[stack.length-1] != null ?
+ "none" :
+ document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || "";
+
+ // Finally, revert the display styles back
+ for ( a = 0; a < swap.length; a++ )
+ if ( swap[a] != null )
+ stack[a].style.display = swap[a];
+ }
+
+ if ( prop == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if (elem.currentStyle) {
+ var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
+ ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) {
+ var style = elem.style.left;
+ var runtimeStyle = elem.runtimeStyle.left;
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = ret || 0;
+ ret = elem.style.pixelLeft + "px";
+ elem.style.left = style;
+ elem.runtimeStyle.left = runtimeStyle;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function(a, doc) {
+ var r = [];
+ doc = doc || document;
+
+ jQuery.each( a, function(i,arg){
+ if ( !arg ) return;
+
+ if ( arg.constructor == Number )
+ arg = arg.toString();
+
+ // Convert html string into DOM nodes
+ if ( typeof arg == "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+">"+tag+">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = [];
+
+ var wrap =
+ // option or optgroup
+ !s.indexOf("", ""] ||
+
+ !s.indexOf("", ""] ||
+
+ s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [1, ""] ||
+
+ !s.indexOf("", " "] ||
+
+ // matched above
+ (!s.indexOf(" ", " "] ||
+
+ !s.indexOf("", " "] ||
+
+ // IE can't serialize and
-
-
-
-
-
-
-
-
Hello
-
-
-
lorem ipsum
-
dolor sit amet
-
-
-
-
-
-
-
diff --git a/speed/css.html b/speed/css.html
deleted file mode 100644
index 4d6700cf..00000000
--- a/speed/css.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
- Test Event Handling Performance
-
-
-
-
-
-
-
-
- Getting Values: Loading...
- Setting Values: Loading...
-
-
diff --git a/speed/event.html b/speed/event.html
deleted file mode 100644
index 6d463b4d..00000000
--- a/speed/event.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
- Test Event Handling Performance
-
-
-
-
-
-
-
- Move the mouse, please!
-
-
-
diff --git a/speed/filter.html b/speed/filter.html
deleted file mode 100644
index 43ee94e5..00000000
--- a/speed/filter.html
+++ /dev/null
@@ -1,183 +0,0 @@
-
-
-
- Test .filter() Performance
-
-
-
-
-
-
-
-
-
Hello
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/speed/find.html b/speed/find.html
deleted file mode 100644
index d3a2dc12..00000000
--- a/speed/find.html
+++ /dev/null
@@ -1,179 +0,0 @@
-
-
-
- Test .find() Performance
-
-
-
-
-
-
-
-
-
Hello
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/speed/index.html b/speed/index.html
deleted file mode 100644
index 717ca731..00000000
--- a/speed/index.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
- Speed Test
-
-
-
-
-
-
-
-
-Speed Test
-
-
-
Using the following selector expressions ( times each):
-
NOTE: Number shown is an average.
-
- Select All
- Deselect All
-
- Run Tests
- Retry Ties
-
-
-
-
- Run?
- Test
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Select All
- Deselect All
- Run Tests
- Retry Ties
- +
-
-
-
-
-
-
-
-
-
diff --git a/speed/jquery-basis.js b/speed/jquery-basis.js
deleted file mode 100644
index 6fe017c1..00000000
--- a/speed/jquery-basis.js
+++ /dev/null
@@ -1,6238 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.4.2
- * http://jquery.com/
- *
- * Copyright 2010, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2010, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Sat Feb 13 22:33:48 2010 -0500
- */
-(function( window, undefined ) {
-
-// Define a local copy of jQuery
-var jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- return new jQuery.fn.init( selector, context );
- },
-
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$,
-
- // Use the correct document accordingly with window argument (sandbox)
- document = window.document,
-
- // A central reference to the root jQuery(document)
- rootjQuery,
-
- // A simple way to check for HTML strings or ID strings
- // (both of which we optimize for)
- quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
-
- // Is it a simple selector
- isSimple = /^.[^:#\[\.,]*$/,
-
- // Check if a string has a non-whitespace character in it
- rnotwhite = /\S/,
-
- // Used for trimming whitespace
- rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
-
- // Match a standalone tag
- rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
-
- // Keep a UserAgent string for use with jQuery.browser
- userAgent = navigator.userAgent,
-
- // For matching the engine and version of the browser
- browserMatch,
-
- // Has the ready events already been bound?
- readyBound = false,
-
- // The functions to execute on DOM ready
- readyList = [],
-
- // The ready event handler
- DOMContentLoaded,
-
- // Save a reference to some core methods
- toString = Object.prototype.toString,
- hasOwnProperty = Object.prototype.hasOwnProperty,
- push = Array.prototype.push,
- slice = Array.prototype.slice,
- indexOf = Array.prototype.indexOf;
-
-jQuery.fn = jQuery.prototype = {
- init: function( selector, context ) {
- var match, elem, ret, doc;
-
- // Handle $(""), $(null), or $(undefined)
- if ( !selector ) {
- return this;
- }
-
- // Handle $(DOMElement)
- if ( selector.nodeType ) {
- this.context = this[0] = selector;
- this.length = 1;
- return this;
- }
-
- // The body element only exists once, optimize finding it
- if ( selector === "body" && !context ) {
- this.context = document;
- this[0] = document.body;
- this.selector = "body";
- this.length = 1;
- return this;
- }
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- // Are we dealing with HTML string or an ID?
- match = quickExpr.exec( selector );
-
- // Verify a match, and that no context was specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- doc = (context ? context.ownerDocument || context : document);
-
- // If a single string is passed in and it's a single tag
- // just do a createElement and skip the rest
- ret = rsingleTag.exec( selector );
-
- if ( ret ) {
- if ( jQuery.isPlainObject( context ) ) {
- selector = [ document.createElement( ret[1] ) ];
- jQuery.fn.attr.call( selector, context, true );
-
- } else {
- selector = [ doc.createElement( ret[1] ) ];
- }
-
- } else {
- ret = buildFragment( [ match[1] ], [ doc ] );
- selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
- }
-
- return jQuery.merge( this, selector );
-
- // HANDLE: $("#id")
- } else {
- elem = document.getElementById( match[2] );
-
- if ( elem ) {
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id !== match[2] ) {
- return rootjQuery.find( selector );
- }
-
- // Otherwise, we inject the element directly into the jQuery object
- this.length = 1;
- this[0] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $("TAG")
- } else if ( !context && /^\w+$/.test( selector ) ) {
- this.selector = selector;
- this.context = document;
- selector = document.getElementsByTagName( selector );
- return jQuery.merge( this, selector );
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return (context || rootjQuery).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return jQuery( context ).find( selector );
- }
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return rootjQuery.ready( selector );
- }
-
- if (selector.selector !== undefined) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- },
-
- // Start with an empty selector
- selector: "",
-
- // The current version of jQuery being used
- jquery: "1.4.2",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- // The number of elements contained in the matched element set
- size: function() {
- return this.length;
- },
-
- toArray: function() {
- return slice.call( this, 0 );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num == null ?
-
- // Return a 'clean' array
- this.toArray() :
-
- // Return just the object
- ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems, name, selector ) {
- // Build a new jQuery matched element set
- var ret = jQuery();
-
- if ( jQuery.isArray( elems ) ) {
- push.apply( ret, elems );
-
- } else {
- jQuery.merge( ret, elems );
- }
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
-
- ret.context = this.context;
-
- if ( name === "find" ) {
- ret.selector = this.selector + (this.selector ? " " : "") + selector;
- } else if ( name ) {
- ret.selector = this.selector + "." + name + "(" + selector + ")";
- }
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- ready: function( fn ) {
- // Attach the listeners
- jQuery.bindReady();
-
- // If the DOM is already ready
- if ( jQuery.isReady ) {
- // Execute the function immediately
- fn.call( document, jQuery );
-
- // Otherwise, remember the function for later
- } else if ( readyList ) {
- // Add the function to the wait list
- readyList.push( fn );
- }
-
- return this;
- },
-
- eq: function( i ) {
- return i === -1 ?
- this.slice( i ) :
- this.slice( i, +i + 1 );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ),
- "slice", slice.call(arguments).join(",") );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
- return callback.call( elem, i, elem );
- }));
- },
-
- end: function() {
- return this.prevObject || jQuery(null);
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: [].sort,
- splice: [].splice
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-jQuery.extend = jQuery.fn.extend = function() {
- // copy reference to target object
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if ( length === i ) {
- target = this;
- --i;
- }
-
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging object literal values or arrays
- if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
- var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
- : jQuery.isArray(copy) ? [] : {};
-
- // Never move original objects, clone them
- target[ name ] = jQuery.extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
-};
-
-jQuery.extend({
- noConflict: function( deep ) {
- window.$ = _$;
-
- if ( deep ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
- },
-
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // Handle when the DOM is ready
- ready: function() {
- // Make sure that the DOM is not already loaded
- if ( !jQuery.isReady ) {
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( !document.body ) {
- return setTimeout( jQuery.ready, 13 );
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If there are functions bound, to execute
- if ( readyList ) {
- // Execute all of them
- var fn, i = 0;
- while ( (fn = readyList[ i++ ]) ) {
- fn.call( document, jQuery );
- }
-
- // Reset the list of functions
- readyList = null;
- }
-
- // Trigger any bound ready events
- if ( jQuery.fn.triggerHandler ) {
- jQuery( document ).triggerHandler( "ready" );
- }
- }
- },
-
- bindReady: function() {
- if ( readyBound ) {
- return;
- }
-
- readyBound = true;
-
- // Catch cases where $(document).ready() is called after the
- // browser event has already occurred.
- if ( document.readyState === "complete" ) {
- return jQuery.ready();
- }
-
- // Mozilla, Opera and webkit nightlies currently support this event
- if ( document.addEventListener ) {
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", jQuery.ready, false );
-
- // If IE event model is used
- } else if ( document.attachEvent ) {
- // ensure firing before onload,
- // maybe late but safe also for iframes
- document.attachEvent("onreadystatechange", DOMContentLoaded);
-
- // A fallback to window.onload, that will always work
- window.attachEvent( "onload", jQuery.ready );
-
- // If IE and not a frame
- // continually check to see if the document is ready
- var toplevel = false;
-
- try {
- toplevel = window.frameElement == null;
- } catch(e) {}
-
- if ( document.documentElement.doScroll && toplevel ) {
- doScrollCheck();
- }
- }
- },
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return toString.call(obj) === "[object Function]";
- },
-
- isArray: function( obj ) {
- return toString.call(obj) === "[object Array]";
- },
-
- isPlainObject: function( obj ) {
- // Must be an Object.
- // Because of IE, we also have to check the presence of the constructor property.
- // Make sure that DOM nodes and window objects don't pass through, as well
- if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
- return false;
- }
-
- // Not own constructor property must be Object
- if ( obj.constructor
- && !hasOwnProperty.call(obj, "constructor")
- && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
- return false;
- }
-
- // Own properties are enumerated firstly, so to speed up,
- // if last one is own, then all properties are own.
-
- var key;
- for ( key in obj ) {}
-
- return key === undefined || hasOwnProperty.call( obj, key );
- },
-
- isEmptyObject: function( obj ) {
- for ( var name in obj ) {
- return false;
- }
- return true;
- },
-
- error: function( msg ) {
- throw msg;
- },
-
- parseJSON: function( data ) {
- if ( typeof data !== "string" || !data ) {
- return null;
- }
-
- // Make sure leading/trailing whitespace is removed (IE can't handle it)
- data = jQuery.trim( data );
-
- // Make sure the incoming data is actual JSON
- // Logic borrowed from http://json.org/json2.js
- if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
- .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
-
- // Try to use the native JSON parser first
- return window.JSON && window.JSON.parse ?
- window.JSON.parse( data ) :
- (new Function("return " + data))();
-
- } else {
- jQuery.error( "Invalid JSON: " + data );
- }
- },
-
- noop: function() {},
-
- // Evalulates a script in a global context
- globalEval: function( data ) {
- if ( data && rnotwhite.test(data) ) {
- // Inspired by code by Andrea Giammarchi
- // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
- var head = document.head || document.getElementsByTagName("head")[0] || document.documentElement,
- script = document.createElement("script");
-
- if ( jQuery.support.scriptEval ) {
- script.appendChild( document.createTextNode( data ) );
- } else {
- script.text = data;
- }
-
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
- // This arises when a base node is used (#2709).
- head.insertBefore( script, head.firstChild );
- head.removeChild( script );
- }
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
- },
-
- // args is for internal usage only
- each: function( object, callback, args ) {
- var name, i = 0,
- length = object.length,
- isObj = length === undefined || jQuery.isFunction(object);
-
- if ( args ) {
- if ( isObj ) {
- for ( name in object ) {
- if ( callback.apply( object[ name ], args ) === false ) {
- break;
- }
- }
- } else {
- for ( ; i < length; ) {
- if ( callback.apply( object[ i++ ], args ) === false ) {
- break;
- }
- }
- }
-
- // A special, fast, case for the most common use of each
- } else {
- if ( isObj ) {
- for ( name in object ) {
- if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
- break;
- }
- }
- } else {
- for ( var value = object[0];
- i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
- }
- }
-
- return object;
- },
-
- trim: function( text ) {
- return (text || "").replace( rtrim, "" );
- },
-
- // results is for internal usage only
- makeArray: function( array, results ) {
- var ret = results || [];
-
- if ( array != null ) {
- // The window, strings (and functions) also have 'length'
- // The extra typeof function check is to prevent crashes
- // in Safari 2 (See: #3039)
- if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
- push.call( ret, array );
- } else {
- jQuery.merge( ret, array );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, array ) {
- if ( array.indexOf ) {
- return array.indexOf( elem );
- }
-
- for ( var i = 0, length = array.length; i < length; i++ ) {
- if ( array[ i ] === elem ) {
- return i;
- }
- }
-
- return -1;
- },
-
- merge: function( first, second ) {
- var i = first.length, j = 0;
-
- if ( typeof second.length === "number" ) {
- for ( var l = second.length; j < l; j++ ) {
- first[ i++ ] = second[ j ];
- }
-
- } else {
- while ( second[j] !== undefined ) {
- first[ i++ ] = second[ j++ ];
- }
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, inv ) {
- var ret = [];
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- if ( !inv !== !callback( elems[ i ], i ) ) {
- ret.push( elems[ i ] );
- }
- }
-
- return ret;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var ret = [], value;
-
- // Go through the array, translating each of the items to their
- // new value (or values).
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret[ ret.length ] = value;
- }
- }
-
- return ret.concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- proxy: function( fn, proxy, thisObject ) {
- if ( arguments.length === 2 ) {
- if ( typeof proxy === "string" ) {
- thisObject = fn;
- fn = thisObject[ proxy ];
- proxy = undefined;
-
- } else if ( proxy && !jQuery.isFunction( proxy ) ) {
- thisObject = proxy;
- proxy = undefined;
- }
- }
-
- if ( !proxy && fn ) {
- proxy = function() {
- return fn.apply( thisObject || this, arguments );
- };
- }
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- if ( fn ) {
- proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
- }
-
- // So proxy can be declared as an argument
- return proxy;
- },
-
- // Use of jQuery.browser is frowned upon.
- // More details: http://docs.jquery.com/Utilities/jQuery.browser
- uaMatch: function( ua ) {
- ua = ua.toLowerCase();
-
- var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
- /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
- /(msie) ([\w.]+)/.exec( ua ) ||
- !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
- [];
-
- return { browser: match[1] || "", version: match[2] || "0" };
- },
-
- browser: {}
-});
-
-browserMatch = jQuery.uaMatch( userAgent );
-if ( browserMatch.browser ) {
- jQuery.browser[ browserMatch.browser ] = true;
- jQuery.browser.version = browserMatch.version;
-}
-
-// Deprecated, use jQuery.browser.webkit instead
-if ( jQuery.browser.webkit ) {
- jQuery.browser.safari = true;
-}
-
-if ( indexOf ) {
- jQuery.inArray = function( elem, array ) {
- return indexOf.call( array, elem );
- };
-}
-
-// All jQuery objects should point back to these
-rootjQuery = jQuery(document);
-
-// Cleanup functions for the document ready method
-if ( document.addEventListener ) {
- DOMContentLoaded = function() {
- document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
- jQuery.ready();
- };
-
-} else if ( document.attachEvent ) {
- DOMContentLoaded = function() {
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( document.readyState === "complete" ) {
- document.detachEvent( "onreadystatechange", DOMContentLoaded );
- jQuery.ready();
- }
- };
-}
-
-// The DOM ready check for Internet Explorer
-function doScrollCheck() {
- if ( jQuery.isReady ) {
- return;
- }
-
- try {
- // If IE is used, use the trick by Diego Perini
- // http://javascript.nwbox.com/IEContentLoaded/
- document.documentElement.doScroll("left");
- } catch( error ) {
- setTimeout( doScrollCheck, 1 );
- return;
- }
-
- // and execute any waiting functions
- jQuery.ready();
-}
-
-function evalScript( i, elem ) {
- if ( elem.src ) {
- jQuery.ajax({
- url: elem.src,
- async: false,
- dataType: "script"
- });
- } else {
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
- }
-
- if ( elem.parentNode ) {
- elem.parentNode.removeChild( elem );
- }
-}
-
-// Mutifunctional method to get and set values to a collection
-// The value/s can be optionally by executed if its a function
-function access( elems, key, value, exec, fn, pass ) {
- var length = elems.length;
-
- // Setting many attributes
- if ( typeof key === "object" ) {
- for ( var k in key ) {
- access( elems, k, key[k], exec, fn, value );
- }
- return elems;
- }
-
- // Setting one attribute
- if ( value !== undefined ) {
- // Optionally, function values get executed if exec is true
- exec = !pass && exec && jQuery.isFunction(value);
-
- for ( var i = 0; i < length; i++ ) {
- fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
- }
-
- return elems;
- }
-
- // Getting an attribute
- return length ? fn( elems[0], key ) : undefined;
-}
-
-function now() {
- return (new Date).getTime();
-}
-(function() {
-
- jQuery.support = {};
-
- var root = document.documentElement,
- script = document.createElement("script"),
- div = document.createElement("div"),
- id = "script" + now();
-
- div.style.display = "none";
- div.innerHTML = " a ";
-
- var all = div.getElementsByTagName("*"),
- a = div.getElementsByTagName("a")[0];
-
- // Can't get basic test support
- if ( !all || !all.length || !a ) {
- return;
- }
-
- jQuery.support = {
- // IE strips leading whitespace when .innerHTML is used
- leadingWhitespace: div.firstChild.nodeType === 3,
-
- // Make sure that tbody elements aren't automatically inserted
- // IE will insert them into empty tables
- tbody: !div.getElementsByTagName("tbody").length,
-
- // Make sure that link elements get serialized correctly by innerHTML
- // This requires a wrapper element in IE
- htmlSerialize: !!div.getElementsByTagName("link").length,
-
- // Get the style information from getAttribute
- // (IE uses .cssText insted)
- style: /red/.test( a.getAttribute("style") ),
-
- // Make sure that URLs aren't manipulated
- // (IE normalizes it by default)
- hrefNormalized: a.getAttribute("href") === "/a",
-
- // Make sure that element opacity exists
- // (IE uses filter instead)
- // Use a regex to work around a WebKit issue. See #5145
- opacity: /^0.55$/.test( a.style.opacity ),
-
- // Verify style float existence
- // (IE uses styleFloat instead of cssFloat)
- cssFloat: !!a.style.cssFloat,
-
- // Make sure that if no value is specified for a checkbox
- // that it defaults to "on".
- // (WebKit defaults to "" instead)
- checkOn: div.getElementsByTagName("input")[0].value === "on",
-
- // Make sure that a selected-by-default option has a working selected property.
- // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
- optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
-
- parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
-
- // Will be defined later
- deleteExpando: true,
- checkClone: false,
- scriptEval: false,
- noCloneEvent: true,
- boxModel: null
- };
-
- script.type = "text/javascript";
- try {
- script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
- } catch(e) {}
-
- root.insertBefore( script, root.firstChild );
-
- // Make sure that the execution of code works by injecting a script
- // tag with appendChild/createTextNode
- // (IE doesn't support this, fails, and uses .text instead)
- if ( window[ id ] ) {
- jQuery.support.scriptEval = true;
- delete window[ id ];
- }
-
- // Test to see if it's possible to delete an expando from an element
- // Fails in Internet Explorer
- try {
- delete script.test;
-
- } catch(e) {
- jQuery.support.deleteExpando = false;
- }
-
- root.removeChild( script );
-
- if ( div.attachEvent && div.fireEvent ) {
- div.attachEvent("onclick", function click() {
- // Cloning a node shouldn't copy over any
- // bound event handlers (IE does this)
- jQuery.support.noCloneEvent = false;
- div.detachEvent("onclick", click);
- });
- div.cloneNode(true).fireEvent("onclick");
- }
-
- div = document.createElement("div");
- div.innerHTML = " ";
-
- var fragment = document.createDocumentFragment();
- fragment.appendChild( div.firstChild );
-
- // WebKit doesn't clone checked state correctly in fragments
- jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
-
- // Figure out if the W3C box model works as expected
- // document.body must exist before we can do this
- jQuery(function() {
- var div = document.createElement("div");
- div.style.width = div.style.paddingLeft = "1px";
-
- document.body.appendChild( div );
- jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
- document.body.removeChild( div ).style.display = 'none';
-
- div = null;
- });
-
- // Technique from Juriy Zaytsev
- // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
- var eventSupported = function( eventName ) {
- var el = document.createElement("div");
- eventName = "on" + eventName;
-
- var isSupported = (eventName in el);
- if ( !isSupported ) {
- el.setAttribute(eventName, "return;");
- isSupported = typeof el[eventName] === "function";
- }
- el = null;
-
- return isSupported;
- };
-
- jQuery.support.submitBubbles = eventSupported("submit");
- jQuery.support.changeBubbles = eventSupported("change");
-
- // release memory in IE
- root = script = div = all = a = null;
-})();
-
-jQuery.props = {
- "for": "htmlFor",
- "class": "className",
- readonly: "readOnly",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- rowspan: "rowSpan",
- colspan: "colSpan",
- tabindex: "tabIndex",
- usemap: "useMap",
- frameborder: "frameBorder"
-};
-var expando = "jQuery" + now(), uuid = 0, windowData = {};
-
-jQuery.extend({
- cache: {},
-
- expando:expando,
-
- // The following elements throw uncatchable exceptions if you
- // attempt to add expando properties to them.
- noData: {
- "embed": true,
- "object": true,
- "applet": true
- },
-
- data: function( elem, name, data ) {
- if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
- return;
- }
-
- elem = elem == window ?
- windowData :
- elem;
-
- var id = elem[ expando ], cache = jQuery.cache, thisCache;
-
- if ( !id && typeof name === "string" && data === undefined ) {
- return null;
- }
-
- // Compute a unique ID for the element
- if ( !id ) {
- id = ++uuid;
- }
-
- // Avoid generating a new cache unless none exists and we
- // want to manipulate it.
- if ( typeof name === "object" ) {
- elem[ expando ] = id;
- thisCache = cache[ id ] = jQuery.extend(true, {}, name);
-
- } else if ( !cache[ id ] ) {
- elem[ expando ] = id;
- cache[ id ] = {};
- }
-
- thisCache = cache[ id ];
-
- // Prevent overriding the named cache with undefined values
- if ( data !== undefined ) {
- thisCache[ name ] = data;
- }
-
- return typeof name === "string" ? thisCache[ name ] : thisCache;
- },
-
- removeData: function( elem, name ) {
- if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
- return;
- }
-
- elem = elem == window ?
- windowData :
- elem;
-
- var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
-
- // If we want to remove a specific section of the element's data
- if ( name ) {
- if ( thisCache ) {
- // Remove the section of cache data
- delete thisCache[ name ];
-
- // If we've removed all the data, remove the element's cache
- if ( jQuery.isEmptyObject(thisCache) ) {
- jQuery.removeData( elem );
- }
- }
-
- // Otherwise, we want to remove all of the element's data
- } else {
- if ( jQuery.support.deleteExpando ) {
- delete elem[ jQuery.expando ];
-
- } else if ( elem.removeAttribute ) {
- elem.removeAttribute( jQuery.expando );
- }
-
- // Completely remove the data cache
- delete cache[ id ];
- }
- }
-});
-
-jQuery.fn.extend({
- data: function( key, value ) {
- if ( typeof key === "undefined" && this.length ) {
- return jQuery.data( this[0] );
-
- } else if ( typeof key === "object" ) {
- return this.each(function() {
- jQuery.data( this, key );
- });
- }
-
- var parts = key.split(".");
- parts[1] = parts[1] ? "." + parts[1] : "";
-
- if ( value === undefined ) {
- var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
- if ( data === undefined && this.length ) {
- data = jQuery.data( this[0], key );
- }
- return data === undefined && parts[1] ?
- this.data( parts[0] ) :
- data;
- } else {
- return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
- jQuery.data( this, key, value );
- });
- }
- },
-
- removeData: function( key ) {
- return this.each(function() {
- jQuery.removeData( this, key );
- });
- }
-});
-jQuery.extend({
- queue: function( elem, type, data ) {
- if ( !elem ) {
- return;
- }
-
- type = (type || "fx") + "queue";
- var q = jQuery.data( elem, type );
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( !data ) {
- return q || [];
- }
-
- if ( !q || jQuery.isArray(data) ) {
- q = jQuery.data( elem, type, jQuery.makeArray(data) );
-
- } else {
- q.push( data );
- }
-
- return q;
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ), fn = queue.shift();
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- }
-
- if ( fn ) {
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift("inprogress");
- }
-
- fn.call(elem, function() {
- jQuery.dequeue(elem, type);
- });
- }
- }
-});
-
-jQuery.fn.extend({
- queue: function( type, data ) {
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- }
-
- if ( data === undefined ) {
- return jQuery.queue( this[0], type );
- }
- return this.each(function( i, elem ) {
- var queue = jQuery.queue( this, type, data );
-
- if ( type === "fx" && queue[0] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- dequeue: function( type ) {
- return this.each(function() {
- jQuery.dequeue( this, type );
- });
- },
-
- // Based off of the plugin by Clint Helfers, with permission.
- // http://blindsignals.com/index.php/2009/07/jquery-delay/
- delay: function( time, type ) {
- time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
- type = type || "fx";
-
- return this.queue( type, function() {
- var elem = this;
- setTimeout(function() {
- jQuery.dequeue( elem, type );
- }, time );
- });
- },
-
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- }
-});
-var rclass = /[\n\t]/g,
- rspace = /\s+/,
- rreturn = /\r/g,
- rspecialurl = /href|src|style/,
- rtype = /(button|input)/i,
- rfocusable = /(button|input|object|select|textarea)/i,
- rclickable = /^(a|area)$/i,
- rradiocheck = /radio|checkbox/;
-
-jQuery.fn.extend({
- attr: function( name, value ) {
- return access( this, name, value, true, jQuery.attr );
- },
-
- removeAttr: function( name, fn ) {
- return this.each(function(){
- jQuery.attr( this, name, "" );
- if ( this.nodeType === 1 ) {
- this.removeAttribute( name );
- }
- });
- },
-
- addClass: function( value ) {
- if ( jQuery.isFunction(value) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- self.addClass( value.call(this, i, self.attr("class")) );
- });
- }
-
- if ( value && typeof value === "string" ) {
- var classNames = (value || "").split( rspace );
-
- for ( var i = 0, l = this.length; i < l; i++ ) {
- var elem = this[i];
-
- if ( elem.nodeType === 1 ) {
- if ( !elem.className ) {
- elem.className = value;
-
- } else {
- var className = " " + elem.className + " ", setClass = elem.className;
- for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
- if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
- setClass += " " + classNames[c];
- }
- }
- elem.className = jQuery.trim( setClass );
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function( value ) {
- if ( jQuery.isFunction(value) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- self.removeClass( value.call(this, i, self.attr("class")) );
- });
- }
-
- if ( (value && typeof value === "string") || value === undefined ) {
- var classNames = (value || "").split(rspace);
-
- for ( var i = 0, l = this.length; i < l; i++ ) {
- var elem = this[i];
-
- if ( elem.nodeType === 1 && elem.className ) {
- if ( value ) {
- var className = (" " + elem.className + " ").replace(rclass, " ");
- for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
- className = className.replace(" " + classNames[c] + " ", " ");
- }
- elem.className = jQuery.trim( className );
-
- } else {
- elem.className = "";
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function( value, stateVal ) {
- var type = typeof value, isBool = typeof stateVal === "boolean";
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
- });
- }
-
- return this.each(function() {
- if ( type === "string" ) {
- // toggle individual class names
- var className, i = 0, self = jQuery(this),
- state = stateVal,
- classNames = value.split( rspace );
-
- while ( (className = classNames[ i++ ]) ) {
- // check each className given, space seperated list
- state = isBool ? state : !self.hasClass( className );
- self[ state ? "addClass" : "removeClass" ]( className );
- }
-
- } else if ( type === "undefined" || type === "boolean" ) {
- if ( this.className ) {
- // store className if set
- jQuery.data( this, "__className__", this.className );
- }
-
- // toggle whole className
- this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
- }
- });
- },
-
- hasClass: function( selector ) {
- var className = " " + selector + " ";
- for ( var i = 0, l = this.length; i < l; i++ ) {
- if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
- return true;
- }
- }
-
- return false;
- },
-
- val: function( value ) {
- if ( value === undefined ) {
- var elem = this[0];
-
- if ( elem ) {
- if ( jQuery.nodeName( elem, "option" ) ) {
- return (elem.attributes.value || {}).specified ? elem.value : elem.text;
- }
-
- // We need to handle select boxes special
- if ( jQuery.nodeName( elem, "select" ) ) {
- var index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type === "select-one";
-
- // Nothing was selected
- if ( index < 0 ) {
- return null;
- }
-
- // Loop through all the selected options
- for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
- var option = options[ i ];
-
- if ( option.selected ) {
- // Get the specifc value for the option
- value = jQuery(option).val();
-
- // We don't need an array for one selects
- if ( one ) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- }
-
- // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
- if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
- return elem.getAttribute("value") === null ? "on" : elem.value;
- }
-
-
- // Everything else, we just grab the value
- return (elem.value || "").replace(rreturn, "");
-
- }
-
- return undefined;
- }
-
- var isFunction = jQuery.isFunction(value);
-
- return this.each(function(i) {
- var self = jQuery(this), val = value;
-
- if ( this.nodeType !== 1 ) {
- return;
- }
-
- if ( isFunction ) {
- val = value.call(this, i, self.val());
- }
-
- // Typecast each time if the value is a Function and the appended
- // value is therefore different each time.
- if ( typeof val === "number" ) {
- val += "";
- }
-
- if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
- this.checked = jQuery.inArray( self.val(), val ) >= 0;
-
- } else if ( jQuery.nodeName( this, "select" ) ) {
- var values = jQuery.makeArray(val);
-
- jQuery( "option", this ).each(function() {
- this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
- });
-
- if ( !values.length ) {
- this.selectedIndex = -1;
- }
-
- } else {
- this.value = val;
- }
- });
- }
-});
-
-jQuery.extend({
- attrFn: {
- val: true,
- css: true,
- html: true,
- text: true,
- data: true,
- width: true,
- height: true,
- offset: true
- },
-
- attr: function( elem, name, value, pass ) {
- // don't set attributes on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
- return undefined;
- }
-
- if ( pass && name in jQuery.attrFn ) {
- return jQuery(elem)[name](value);
- }
-
- var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
- // Whether we are setting (or getting)
- set = value !== undefined;
-
- // Try to normalize/fix the name
- name = notxml && jQuery.props[ name ] || name;
-
- // Only do all the following if this is a node (faster for style)
- if ( elem.nodeType === 1 ) {
- // These attributes require special treatment
- var special = rspecialurl.test( name );
-
- // Safari mis-reports the default selected property of an option
- // Accessing the parent's selectedIndex property fixes it
- if ( name === "selected" && !jQuery.support.optSelected ) {
- var parent = elem.parentNode;
- if ( parent ) {
- parent.selectedIndex;
-
- // Make sure that it also works with optgroups, see #5701
- if ( parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- }
- }
-
- // If applicable, access the attribute via the DOM 0 way
- if ( name in elem && notxml && !special ) {
- if ( set ) {
- // We can't allow the type property to be changed (since it causes problems in IE)
- if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
- jQuery.error( "type property can't be changed" );
- }
-
- elem[ name ] = value;
- }
-
- // browsers index elements by id/name on forms, give priority to attributes.
- if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
- return elem.getAttributeNode( name ).nodeValue;
- }
-
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
- if ( name === "tabIndex" ) {
- var attributeNode = elem.getAttributeNode( "tabIndex" );
-
- return attributeNode && attributeNode.specified ?
- attributeNode.value :
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- undefined;
- }
-
- return elem[ name ];
- }
-
- if ( !jQuery.support.style && notxml && name === "style" ) {
- if ( set ) {
- elem.style.cssText = "" + value;
- }
-
- return elem.style.cssText;
- }
-
- if ( set ) {
- // convert the value to a string (all browsers do this but IE) see #1070
- elem.setAttribute( name, "" + value );
- }
-
- var attr = !jQuery.support.hrefNormalized && notxml && special ?
- // Some attributes require a special call on IE
- elem.getAttribute( name, 2 ) :
- elem.getAttribute( name );
-
- // Non-existent attributes return null, we normalize to undefined
- return attr === null ? undefined : attr;
- }
-
- // elem is actually elem.style ... set the style
- // Using attr for specific style information is now deprecated. Use style instead.
- return jQuery.style( elem, name, value );
- }
-});
-var rnamespaces = /\.(.*)$/,
- fcleanup = function( nm ) {
- return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
- return "\\" + ch;
- });
- };
-
-/*
- * A number of helper functions used for managing events.
- * Many of the ideas behind this code originated from
- * Dean Edwards' addEvent library.
- */
-jQuery.event = {
-
- // Bind an event to an element
- // Original by Dean Edwards
- add: function( elem, types, handler, data ) {
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- // For whatever reason, IE has trouble passing the window object
- // around, causing it to be cloned in the process
- if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
- elem = window;
- }
-
- var handleObjIn, handleObj;
-
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- }
-
- // Make sure that the function being executed has a unique ID
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure
- var elemData = jQuery.data( elem );
-
- // If no elemData is found then we must be trying to bind to one of the
- // banned noData elements
- if ( !elemData ) {
- return;
- }
-
- var events = elemData.events = elemData.events || {},
- eventHandle = elemData.handle, eventHandle;
-
- if ( !eventHandle ) {
- elemData.handle = eventHandle = function() {
- // Handle the second event of a trigger and when
- // an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
- jQuery.event.handle.apply( eventHandle.elem, arguments ) :
- undefined;
- };
- }
-
- // Add elem as a property of the handle function
- // This is to prevent a memory leak with non-native events in IE.
- eventHandle.elem = elem;
-
- // Handle multiple events separated by a space
- // jQuery(...).bind("mouseover mouseout", fn);
- types = types.split(" ");
-
- var type, i = 0, namespaces;
-
- while ( (type = types[ i++ ]) ) {
- handleObj = handleObjIn ?
- jQuery.extend({}, handleObjIn) :
- { handler: handler, data: data };
-
- // Namespaced event handlers
- if ( type.indexOf(".") > -1 ) {
- namespaces = type.split(".");
- type = namespaces.shift();
- handleObj.namespace = namespaces.slice(0).sort().join(".");
-
- } else {
- namespaces = [];
- handleObj.namespace = "";
- }
-
- handleObj.type = type;
- handleObj.guid = handler.guid;
-
- // Get the current list of functions bound to this event
- var handlers = events[ type ],
- special = jQuery.event.special[ type ] || {};
-
- // Init the event handler queue
- if ( !handlers ) {
- handlers = events[ type ] = [];
-
- // Check for a special event handler
- // Only use addEventListener/attachEvent if the special
- // events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
- // Bind the global event handler to the element
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle, false );
-
- } else if ( elem.attachEvent ) {
- elem.attachEvent( "on" + type, eventHandle );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add the function to the element's handler list
- handlers.push( handleObj );
-
- // Keep track of which events have been used, for global triggering
- jQuery.event.global[ type ] = true;
- }
-
- // Nullify elem to prevent memory leaks in IE
- elem = null;
- },
-
- global: {},
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, pos ) {
- // don't do events on text and comment nodes
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
- elemData = jQuery.data( elem ),
- events = elemData && elemData.events;
-
- if ( !elemData || !events ) {
- return;
- }
-
- // types is actually an event object here
- if ( types && types.type ) {
- handler = types.handler;
- types = types.type;
- }
-
- // Unbind all events for the element
- if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
- types = types || "";
-
- for ( type in events ) {
- jQuery.event.remove( elem, type + types );
- }
-
- return;
- }
-
- // Handle multiple events separated by a space
- // jQuery(...).unbind("mouseover mouseout", fn);
- types = types.split(" ");
-
- while ( (type = types[ i++ ]) ) {
- origType = type;
- handleObj = null;
- all = type.indexOf(".") < 0;
- namespaces = [];
-
- if ( !all ) {
- // Namespaced event handlers
- namespaces = type.split(".");
- type = namespaces.shift();
-
- namespace = new RegExp("(^|\\.)" +
- jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
- }
-
- eventType = events[ type ];
-
- if ( !eventType ) {
- continue;
- }
-
- if ( !handler ) {
- for ( var j = 0; j < eventType.length; j++ ) {
- handleObj = eventType[ j ];
-
- if ( all || namespace.test( handleObj.namespace ) ) {
- jQuery.event.remove( elem, origType, handleObj.handler, j );
- eventType.splice( j--, 1 );
- }
- }
-
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
-
- for ( var j = pos || 0; j < eventType.length; j++ ) {
- handleObj = eventType[ j ];
-
- if ( handler.guid === handleObj.guid ) {
- // remove the given handler for the given type
- if ( all || namespace.test( handleObj.namespace ) ) {
- if ( pos == null ) {
- eventType.splice( j--, 1 );
- }
-
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
-
- if ( pos != null ) {
- break;
- }
- }
- }
-
- // remove generic event handler if no more handlers exist
- if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
- removeEvent( elem, type, elemData.handle );
- }
-
- ret = null;
- delete events[ type ];
- }
- }
-
- // Remove the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- var handle = elemData.handle;
- if ( handle ) {
- handle.elem = null;
- }
-
- delete elemData.events;
- delete elemData.handle;
-
- if ( jQuery.isEmptyObject( elemData ) ) {
- jQuery.removeData( elem );
- }
- }
- },
-
- // bubbling is internal
- trigger: function( event, data, elem /*, bubbling */ ) {
- // Event object or event type
- var type = event.type || event,
- bubbling = arguments[3];
-
- if ( !bubbling ) {
- event = typeof event === "object" ?
- // jQuery.Event object
- event[expando] ? event :
- // Object literal
- jQuery.extend( jQuery.Event(type), event ) :
- // Just the event type (string)
- jQuery.Event(type);
-
- if ( type.indexOf("!") >= 0 ) {
- event.type = type = type.slice(0, -1);
- event.exclusive = true;
- }
-
- // Handle a global trigger
- if ( !elem ) {
- // Don't bubble custom events when global (to avoid too much overhead)
- event.stopPropagation();
-
- // Only trigger if we've ever bound an event for it
- if ( jQuery.event.global[ type ] ) {
- jQuery.each( jQuery.cache, function() {
- if ( this.events && this.events[type] ) {
- jQuery.event.trigger( event, data, this.handle.elem );
- }
- });
- }
- }
-
- // Handle triggering a single element
-
- // don't do events on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
- return undefined;
- }
-
- // Clean up in case it is reused
- event.result = undefined;
- event.target = elem;
-
- // Clone the incoming data, if any
- data = jQuery.makeArray( data );
- data.unshift( event );
- }
-
- event.currentTarget = elem;
-
- // Trigger the event, it is assumed that "handle" is a function
- var handle = jQuery.data( elem, "handle" );
- if ( handle ) {
- handle.apply( elem, data );
- }
-
- var parent = elem.parentNode || elem.ownerDocument;
-
- // Trigger an inline bound script
- try {
- if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
- if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
- event.result = false;
- }
- }
-
- // prevent IE from throwing an error for some elements with some event types, see #3533
- } catch (e) {}
-
- if ( !event.isPropagationStopped() && parent ) {
- jQuery.event.trigger( event, data, parent, true );
-
- } else if ( !event.isDefaultPrevented() ) {
- var target = event.target, old,
- isClick = jQuery.nodeName(target, "a") && type === "click",
- special = jQuery.event.special[ type ] || {};
-
- if ( (!special._default || special._default.call( elem, event ) === false) &&
- !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
-
- try {
- if ( target[ type ] ) {
- // Make sure that we don't accidentally re-trigger the onFOO events
- old = target[ "on" + type ];
-
- if ( old ) {
- target[ "on" + type ] = null;
- }
-
- jQuery.event.triggered = true;
- target[ type ]();
- }
-
- // prevent IE from throwing an error for some elements with some event types, see #3533
- } catch (e) {}
-
- if ( old ) {
- target[ "on" + type ] = old;
- }
-
- jQuery.event.triggered = false;
- }
- }
- },
-
- handle: function( event ) {
- var all, handlers, namespaces, namespace, events;
-
- event = arguments[0] = jQuery.event.fix( event || window.event );
- event.currentTarget = this;
-
- // Namespaced event handlers
- all = event.type.indexOf(".") < 0 && !event.exclusive;
-
- if ( !all ) {
- namespaces = event.type.split(".");
- event.type = namespaces.shift();
- namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
- }
-
- var events = jQuery.data(this, "events"), handlers = events[ event.type ];
-
- if ( events && handlers ) {
- // Clone the handlers to prevent manipulation
- handlers = handlers.slice(0);
-
- for ( var j = 0, l = handlers.length; j < l; j++ ) {
- var handleObj = handlers[ j ];
-
- // Filter the functions by class
- if ( all || namespace.test( handleObj.namespace ) ) {
- // Pass in a reference to the handler function itself
- // So that we can later remove it
- event.handler = handleObj.handler;
- event.data = handleObj.data;
- event.handleObj = handleObj;
-
- var ret = handleObj.handler.apply( this, arguments );
-
- if ( ret !== undefined ) {
- event.result = ret;
- if ( ret === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
-
- if ( event.isImmediatePropagationStopped() ) {
- break;
- }
- }
- }
- }
-
- return event.result;
- },
-
- props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
-
- fix: function( event ) {
- if ( event[ expando ] ) {
- return event;
- }
-
- // store a copy of the original event object
- // and "clone" to set read-only properties
- var originalEvent = event;
- event = jQuery.Event( originalEvent );
-
- for ( var i = this.props.length, prop; i; ) {
- prop = this.props[ --i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Fix target property, if necessary
- if ( !event.target ) {
- event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
- }
-
- // check if target is a textnode (safari)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- // Add relatedTarget, if necessary
- if ( !event.relatedTarget && event.fromElement ) {
- event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
- }
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && event.clientX != null ) {
- var doc = document.documentElement, body = document.body;
- event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
- event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
- }
-
- // Add which for key events
- if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
- event.which = event.charCode || event.keyCode;
- }
-
- // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
- if ( !event.metaKey && event.ctrlKey ) {
- event.metaKey = event.ctrlKey;
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && event.button !== undefined ) {
- event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
- }
-
- return event;
- },
-
- // Deprecated, use jQuery.guid instead
- guid: 1E8,
-
- // Deprecated, use jQuery.proxy instead
- proxy: jQuery.proxy,
-
- special: {
- ready: {
- // Make sure the ready event is setup
- setup: jQuery.bindReady,
- teardown: jQuery.noop
- },
-
- live: {
- add: function( handleObj ) {
- jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
- },
-
- remove: function( handleObj ) {
- var remove = true,
- type = handleObj.origType.replace(rnamespaces, "");
-
- jQuery.each( jQuery.data(this, "events").live || [], function() {
- if ( type === this.origType.replace(rnamespaces, "") ) {
- remove = false;
- return false;
- }
- });
-
- if ( remove ) {
- jQuery.event.remove( this, handleObj.origType, liveHandler );
- }
- }
-
- },
-
- beforeunload: {
- setup: function( data, namespaces, eventHandle ) {
- // We only want to do this special case on windows
- if ( this.setInterval ) {
- this.onbeforeunload = eventHandle;
- }
-
- return false;
- },
- teardown: function( namespaces, eventHandle ) {
- if ( this.onbeforeunload === eventHandle ) {
- this.onbeforeunload = null;
- }
- }
- }
- }
-};
-
-var removeEvent = document.removeEventListener ?
- function( elem, type, handle ) {
- elem.removeEventListener( type, handle, false );
- } :
- function( elem, type, handle ) {
- elem.detachEvent( "on" + type, handle );
- };
-
-jQuery.Event = function( src ) {
- // Allow instantiation without the 'new' keyword
- if ( !this.preventDefault ) {
- return new jQuery.Event( src );
- }
-
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
- // Event type
- } else {
- this.type = src;
- }
-
- // timeStamp is buggy for some events on Firefox(#3843)
- // So we won't rely on the native value
- this.timeStamp = now();
-
- // Mark it as fixed
- this[ expando ] = true;
-};
-
-function returnFalse() {
- return false;
-}
-function returnTrue() {
- return true;
-}
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
- preventDefault: function() {
- this.isDefaultPrevented = returnTrue;
-
- var e = this.originalEvent;
- if ( !e ) {
- return;
- }
-
- // if preventDefault exists run it on the original event
- if ( e.preventDefault ) {
- e.preventDefault();
- }
- // otherwise set the returnValue property of the original event to false (IE)
- e.returnValue = false;
- },
- stopPropagation: function() {
- this.isPropagationStopped = returnTrue;
-
- var e = this.originalEvent;
- if ( !e ) {
- return;
- }
- // if stopPropagation exists run it on the original event
- if ( e.stopPropagation ) {
- e.stopPropagation();
- }
- // otherwise set the cancelBubble property of the original event to true (IE)
- e.cancelBubble = true;
- },
- stopImmediatePropagation: function() {
- this.isImmediatePropagationStopped = returnTrue;
- this.stopPropagation();
- },
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse
-};
-
-// Checks if an event happened on an element within another element
-// Used in jQuery.event.special.mouseenter and mouseleave handlers
-var withinElement = function( event ) {
- // Check if mouse(over|out) are still within the same parent element
- var parent = event.relatedTarget;
-
- // Firefox sometimes assigns relatedTarget a XUL element
- // which we cannot access the parentNode property of
- try {
- // Traverse up the tree
- while ( parent && parent !== this ) {
- parent = parent.parentNode;
- }
-
- if ( parent !== this ) {
- // set the correct event type
- event.type = event.data;
-
- // handle event if we actually just moused on to a non sub-element
- jQuery.event.handle.apply( this, arguments );
- }
-
- // assuming we've left the element since we most likely mousedover a xul element
- } catch(e) { }
-},
-
-// In case of event delegation, we only need to rename the event.type,
-// liveHandler will take care of the rest.
-delegate = function( event ) {
- event.type = event.data;
- jQuery.event.handle.apply( this, arguments );
-};
-
-// Create mouseenter and mouseleave events
-jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout"
-}, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- setup: function( data ) {
- jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
- },
- teardown: function( data ) {
- jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
- }
- };
-});
-
-// submit delegation
-if ( !jQuery.support.submitBubbles ) {
-
- jQuery.event.special.submit = {
- setup: function( data, namespaces ) {
- if ( this.nodeName.toLowerCase() !== "form" ) {
- jQuery.event.add(this, "click.specialSubmit", function( e ) {
- var elem = e.target, type = elem.type;
-
- if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
- return trigger( "submit", this, arguments );
- }
- });
-
- jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
- var elem = e.target, type = elem.type;
-
- if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
- return trigger( "submit", this, arguments );
- }
- });
-
- } else {
- return false;
- }
- },
-
- teardown: function( namespaces ) {
- jQuery.event.remove( this, ".specialSubmit" );
- }
- };
-
-}
-
-// change delegation, happens here so we have bind.
-if ( !jQuery.support.changeBubbles ) {
-
- var formElems = /textarea|input|select/i,
-
- changeFilters,
-
- getVal = function( elem ) {
- var type = elem.type, val = elem.value;
-
- if ( type === "radio" || type === "checkbox" ) {
- val = elem.checked;
-
- } else if ( type === "select-multiple" ) {
- val = elem.selectedIndex > -1 ?
- jQuery.map( elem.options, function( elem ) {
- return elem.selected;
- }).join("-") :
- "";
-
- } else if ( elem.nodeName.toLowerCase() === "select" ) {
- val = elem.selectedIndex;
- }
-
- return val;
- },
-
- testChange = function testChange( e ) {
- var elem = e.target, data, val;
-
- if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
- return;
- }
-
- data = jQuery.data( elem, "_change_data" );
- val = getVal(elem);
-
- // the current data will be also retrieved by beforeactivate
- if ( e.type !== "focusout" || elem.type !== "radio" ) {
- jQuery.data( elem, "_change_data", val );
- }
-
- if ( data === undefined || val === data ) {
- return;
- }
-
- if ( data != null || val ) {
- e.type = "change";
- return jQuery.event.trigger( e, arguments[1], elem );
- }
- };
-
- jQuery.event.special.change = {
- filters: {
- focusout: testChange,
-
- click: function( e ) {
- var elem = e.target, type = elem.type;
-
- if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
- return testChange.call( this, e );
- }
- },
-
- // Change has to be called before submit
- // Keydown will be called before keypress, which is used in submit-event delegation
- keydown: function( e ) {
- var elem = e.target, type = elem.type;
-
- if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
- (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
- type === "select-multiple" ) {
- return testChange.call( this, e );
- }
- },
-
- // Beforeactivate happens also before the previous element is blurred
- // with this event you can't trigger a change event, but you can store
- // information/focus[in] is not needed anymore
- beforeactivate: function( e ) {
- var elem = e.target;
- jQuery.data( elem, "_change_data", getVal(elem) );
- }
- },
-
- setup: function( data, namespaces ) {
- if ( this.type === "file" ) {
- return false;
- }
-
- for ( var type in changeFilters ) {
- jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
- }
-
- return formElems.test( this.nodeName );
- },
-
- teardown: function( namespaces ) {
- jQuery.event.remove( this, ".specialChange" );
-
- return formElems.test( this.nodeName );
- }
- };
-
- changeFilters = jQuery.event.special.change.filters;
-}
-
-function trigger( type, elem, args ) {
- args[0].type = type;
- return jQuery.event.handle.apply( elem, args );
-}
-
-// Create "bubbling" focus and blur events
-if ( document.addEventListener ) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
- jQuery.event.special[ fix ] = {
- setup: function() {
- this.addEventListener( orig, handler, true );
- },
- teardown: function() {
- this.removeEventListener( orig, handler, true );
- }
- };
-
- function handler( e ) {
- e = jQuery.event.fix( e );
- e.type = fix;
- return jQuery.event.handle.call( this, e );
- }
- });
-}
-
-jQuery.each(["bind", "one"], function( i, name ) {
- jQuery.fn[ name ] = function( type, data, fn ) {
- // Handle object literals
- if ( typeof type === "object" ) {
- for ( var key in type ) {
- this[ name ](key, data, type[key], fn);
- }
- return this;
- }
-
- if ( jQuery.isFunction( data ) ) {
- fn = data;
- data = undefined;
- }
-
- var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
- jQuery( this ).unbind( event, handler );
- return fn.apply( this, arguments );
- }) : fn;
-
- if ( type === "unload" && name !== "one" ) {
- this.one( type, data, fn );
-
- } else {
- for ( var i = 0, l = this.length; i < l; i++ ) {
- jQuery.event.add( this[i], type, handler, data );
- }
- }
-
- return this;
- };
-});
-
-jQuery.fn.extend({
- unbind: function( type, fn ) {
- // Handle object literals
- if ( typeof type === "object" && !type.preventDefault ) {
- for ( var key in type ) {
- this.unbind(key, type[key]);
- }
-
- } else {
- for ( var i = 0, l = this.length; i < l; i++ ) {
- jQuery.event.remove( this[i], type, fn );
- }
- }
-
- return this;
- },
-
- delegate: function( selector, types, data, fn ) {
- return this.live( types, data, fn, selector );
- },
-
- undelegate: function( selector, types, fn ) {
- if ( arguments.length === 0 ) {
- return this.unbind( "live" );
-
- } else {
- return this.die( types, null, fn, selector );
- }
- },
-
- trigger: function( type, data ) {
- return this.each(function() {
- jQuery.event.trigger( type, data, this );
- });
- },
-
- triggerHandler: function( type, data ) {
- if ( this[0] ) {
- var event = jQuery.Event( type );
- event.preventDefault();
- event.stopPropagation();
- jQuery.event.trigger( event, data, this[0] );
- return event.result;
- }
- },
-
- toggle: function( fn ) {
- // Save reference to arguments for access in closure
- var args = arguments, i = 1;
-
- // link all the functions, so any of them can unbind this click handler
- while ( i < args.length ) {
- jQuery.proxy( fn, args[ i++ ] );
- }
-
- return this.click( jQuery.proxy( fn, function( event ) {
- // Figure out which function to execute
- var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
- jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
-
- // Make sure that clicks stop
- event.preventDefault();
-
- // and execute the function
- return args[ lastToggle ].apply( this, arguments ) || false;
- }));
- },
-
- hover: function( fnOver, fnOut ) {
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
- }
-});
-
-var liveMap = {
- focus: "focusin",
- blur: "focusout",
- mouseenter: "mouseover",
- mouseleave: "mouseout"
-};
-
-jQuery.each(["live", "die"], function( i, name ) {
- jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
- var type, i = 0, match, namespaces, preType,
- selector = origSelector || this.selector,
- context = origSelector ? this : jQuery( this.context );
-
- if ( jQuery.isFunction( data ) ) {
- fn = data;
- data = undefined;
- }
-
- types = (types || "").split(" ");
-
- while ( (type = types[ i++ ]) != null ) {
- match = rnamespaces.exec( type );
- namespaces = "";
-
- if ( match ) {
- namespaces = match[0];
- type = type.replace( rnamespaces, "" );
- }
-
- if ( type === "hover" ) {
- types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
- continue;
- }
-
- preType = type;
-
- if ( type === "focus" || type === "blur" ) {
- types.push( liveMap[ type ] + namespaces );
- type = type + namespaces;
-
- } else {
- type = (liveMap[ type ] || type) + namespaces;
- }
-
- if ( name === "live" ) {
- // bind live handler
- context.each(function(){
- jQuery.event.add( this, liveConvert( type, selector ),
- { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
- });
-
- } else {
- // unbind live handler
- context.unbind( liveConvert( type, selector ), fn );
- }
- }
-
- return this;
- }
-});
-
-function liveHandler( event ) {
- var stop, elems = [], selectors = [], args = arguments,
- related, match, handleObj, elem, j, i, l, data,
- events = jQuery.data( this, "events" );
-
- // Make sure we avoid non-left-click bubbling in Firefox (#3861)
- if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
- return;
- }
-
- event.liveFired = this;
-
- var live = events.live.slice(0);
-
- for ( j = 0; j < live.length; j++ ) {
- handleObj = live[j];
-
- if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
- selectors.push( handleObj.selector );
-
- } else {
- live.splice( j--, 1 );
- }
- }
-
- match = jQuery( event.target ).closest( selectors, event.currentTarget );
-
- for ( i = 0, l = match.length; i < l; i++ ) {
- for ( j = 0; j < live.length; j++ ) {
- handleObj = live[j];
-
- if ( match[i].selector === handleObj.selector ) {
- elem = match[i].elem;
- related = null;
-
- // Those two events require additional checking
- if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
- related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
- }
-
- if ( !related || related !== elem ) {
- elems.push({ elem: elem, handleObj: handleObj });
- }
- }
- }
- }
-
- for ( i = 0, l = elems.length; i < l; i++ ) {
- match = elems[i];
- event.currentTarget = match.elem;
- event.data = match.handleObj.data;
- event.handleObj = match.handleObj;
-
- if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
- stop = false;
- break;
- }
- }
-
- return stop;
-}
-
-function liveConvert( type, selector ) {
- return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
-}
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
- "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
-
- // Handle event binding
- jQuery.fn[ name ] = function( fn ) {
- return fn ? this.bind( name, fn ) : this.trigger( name );
- };
-
- if ( jQuery.attrFn ) {
- jQuery.attrFn[ name ] = true;
- }
-});
-
-// Prevent memory leaks in IE
-// Window isn't included so as not to unbind existing unload events
-// More info:
-// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
-if ( window.attachEvent && !window.addEventListener ) {
- window.attachEvent("onunload", function() {
- for ( var id in jQuery.cache ) {
- if ( jQuery.cache[ id ].handle ) {
- // Try/Catch is to handle iframes being unloaded, see #4280
- try {
- jQuery.event.remove( jQuery.cache[ id ].handle.elem );
- } catch(e) {}
- }
- }
- });
-}
-/*!
- * Sizzle CSS Selector Engine - v1.0
- * Copyright 2009, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- * More information: http://sizzlejs.com/
- */
-(function(){
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
- done = 0,
- toString = Object.prototype.toString,
- hasDuplicate = false,
- baseHasDuplicate = true;
-
-// Here we check if the JavaScript engine is using some sort of
-// optimization where it does not always call our comparision
-// function. If that is the case, discard the hasDuplicate value.
-// Thus far that includes Google Chrome.
-[0, 0].sort(function(){
- baseHasDuplicate = false;
- return 0;
-});
-
-var Sizzle = function(selector, context, results, seed) {
- results = results || [];
- var origContext = context = context || document;
-
- if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
- return [];
- }
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
- soFar = selector;
-
- // Reset the position of the chunker regexp (start from head)
- while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
- soFar = m[3];
-
- parts.push( m[1] );
-
- if ( m[2] ) {
- extra = m[3];
- break;
- }
- }
-
- if ( parts.length > 1 && origPOS.exec( selector ) ) {
- if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
- set = posProcess( parts[0] + parts[1], context );
- } else {
- set = Expr.relative[ parts[0] ] ?
- [ context ] :
- Sizzle( parts.shift(), context );
-
- while ( parts.length ) {
- selector = parts.shift();
-
- if ( Expr.relative[ selector ] ) {
- selector += parts.shift();
- }
-
- set = posProcess( selector, set );
- }
- }
- } else {
- // Take a shortcut and set the context if the root selector is an ID
- // (but not if it'll be faster if the inner selector is an ID)
- if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
- Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
- var ret = Sizzle.find( parts.shift(), context, contextXML );
- context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
- }
-
- if ( context ) {
- var ret = seed ?
- { expr: parts.pop(), set: makeArray(seed) } :
- Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
- set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
-
- if ( parts.length > 0 ) {
- checkSet = makeArray(set);
- } else {
- prune = false;
- }
-
- while ( parts.length ) {
- var cur = parts.pop(), pop = cur;
-
- if ( !Expr.relative[ cur ] ) {
- cur = "";
- } else {
- pop = parts.pop();
- }
-
- if ( pop == null ) {
- pop = context;
- }
-
- Expr.relative[ cur ]( checkSet, pop, contextXML );
- }
- } else {
- checkSet = parts = [];
- }
- }
-
- if ( !checkSet ) {
- checkSet = set;
- }
-
- if ( !checkSet ) {
- Sizzle.error( cur || selector );
- }
-
- if ( toString.call(checkSet) === "[object Array]" ) {
- if ( !prune ) {
- results.push.apply( results, checkSet );
- } else if ( context && context.nodeType === 1 ) {
- for ( var i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
- results.push( set[i] );
- }
- }
- } else {
- for ( var i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
- results.push( set[i] );
- }
- }
- }
- } else {
- makeArray( checkSet, results );
- }
-
- if ( extra ) {
- Sizzle( extra, origContext, results, seed );
- Sizzle.uniqueSort( results );
- }
-
- return results;
-};
-
-Sizzle.uniqueSort = function(results){
- if ( sortOrder ) {
- hasDuplicate = baseHasDuplicate;
- results.sort(sortOrder);
-
- if ( hasDuplicate ) {
- for ( var i = 1; i < results.length; i++ ) {
- if ( results[i] === results[i-1] ) {
- results.splice(i--, 1);
- }
- }
- }
- }
-
- return results;
-};
-
-Sizzle.matches = function(expr, set){
- return Sizzle(expr, null, null, set);
-};
-
-Sizzle.find = function(expr, context, isXML){
- var set, match;
-
- if ( !expr ) {
- return [];
- }
-
- for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
- var type = Expr.order[i], match;
-
- if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
- var left = match[1];
- match.splice(1,1);
-
- if ( left.substr( left.length - 1 ) !== "\\" ) {
- match[1] = (match[1] || "").replace(/\\/g, "");
- set = Expr.find[ type ]( match, context, isXML );
- if ( set != null ) {
- expr = expr.replace( Expr.match[ type ], "" );
- break;
- }
- }
- }
- }
-
- if ( !set ) {
- set = context.getElementsByTagName("*");
- }
-
- return {set: set, expr: expr};
-};
-
-Sizzle.filter = function(expr, set, inplace, not){
- var old = expr, result = [], curLoop = set, match, anyFound,
- isXMLFilter = set && set[0] && isXML(set[0]);
-
- while ( expr && set.length ) {
- for ( var type in Expr.filter ) {
- if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
- var filter = Expr.filter[ type ], found, item, left = match[1];
- anyFound = false;
-
- match.splice(1,1);
-
- if ( left.substr( left.length - 1 ) === "\\" ) {
- continue;
- }
-
- if ( curLoop === result ) {
- result = [];
- }
-
- if ( Expr.preFilter[ type ] ) {
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
- if ( !match ) {
- anyFound = found = true;
- } else if ( match === true ) {
- continue;
- }
- }
-
- if ( match ) {
- for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
- if ( item ) {
- found = filter( item, match, i, curLoop );
- var pass = not ^ !!found;
-
- if ( inplace && found != null ) {
- if ( pass ) {
- anyFound = true;
- } else {
- curLoop[i] = false;
- }
- } else if ( pass ) {
- result.push( item );
- anyFound = true;
- }
- }
- }
- }
-
- if ( found !== undefined ) {
- if ( !inplace ) {
- curLoop = result;
- }
-
- expr = expr.replace( Expr.match[ type ], "" );
-
- if ( !anyFound ) {
- return [];
- }
-
- break;
- }
- }
- }
-
- // Improper expression
- if ( expr === old ) {
- if ( anyFound == null ) {
- Sizzle.error( expr );
- } else {
- break;
- }
- }
-
- old = expr;
- }
-
- return curLoop;
-};
-
-Sizzle.error = function( msg ) {
- throw "Syntax error, unrecognized expression: " + msg;
-};
-
-var Expr = Sizzle.selectors = {
- order: [ "ID", "NAME", "TAG" ],
- match: {
- ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
- CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
- NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
- TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
- CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
- POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
- PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
- },
- leftMatch: {},
- attrMap: {
- "class": "className",
- "for": "htmlFor"
- },
- attrHandle: {
- href: function(elem){
- return elem.getAttribute("href");
- }
- },
- relative: {
- "+": function(checkSet, part){
- var isPartStr = typeof part === "string",
- isTag = isPartStr && !/\W/.test(part),
- isPartStrNotTag = isPartStr && !isTag;
-
- if ( isTag ) {
- part = part.toLowerCase();
- }
-
- for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
- if ( (elem = checkSet[i]) ) {
- while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
- checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
- elem || false :
- elem === part;
- }
- }
-
- if ( isPartStrNotTag ) {
- Sizzle.filter( part, checkSet, true );
- }
- },
- ">": function(checkSet, part){
- var isPartStr = typeof part === "string";
-
- if ( isPartStr && !/\W/.test(part) ) {
- part = part.toLowerCase();
-
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- var parent = elem.parentNode;
- checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
- }
- }
- } else {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- checkSet[i] = isPartStr ?
- elem.parentNode :
- elem.parentNode === part;
- }
- }
-
- if ( isPartStr ) {
- Sizzle.filter( part, checkSet, true );
- }
- }
- },
- "": function(checkSet, part, isXML){
- var doneName = done++, checkFn = dirCheck;
-
- if ( typeof part === "string" && !/\W/.test(part) ) {
- var nodeCheck = part = part.toLowerCase();
- checkFn = dirNodeCheck;
- }
-
- checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
- },
- "~": function(checkSet, part, isXML){
- var doneName = done++, checkFn = dirCheck;
-
- if ( typeof part === "string" && !/\W/.test(part) ) {
- var nodeCheck = part = part.toLowerCase();
- checkFn = dirNodeCheck;
- }
-
- checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
- }
- },
- find: {
- ID: function(match, context, isXML){
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- return m ? [m] : [];
- }
- },
- NAME: function(match, context){
- if ( typeof context.getElementsByName !== "undefined" ) {
- var ret = [], results = context.getElementsByName(match[1]);
-
- for ( var i = 0, l = results.length; i < l; i++ ) {
- if ( results[i].getAttribute("name") === match[1] ) {
- ret.push( results[i] );
- }
- }
-
- return ret.length === 0 ? null : ret;
- }
- },
- TAG: function(match, context){
- return context.getElementsByTagName(match[1]);
- }
- },
- preFilter: {
- CLASS: function(match, curLoop, inplace, result, not, isXML){
- match = " " + match[1].replace(/\\/g, "") + " ";
-
- if ( isXML ) {
- return match;
- }
-
- for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
- if ( elem ) {
- if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
- if ( !inplace ) {
- result.push( elem );
- }
- } else if ( inplace ) {
- curLoop[i] = false;
- }
- }
- }
-
- return false;
- },
- ID: function(match){
- return match[1].replace(/\\/g, "");
- },
- TAG: function(match, curLoop){
- return match[1].toLowerCase();
- },
- CHILD: function(match){
- if ( match[1] === "nth" ) {
- // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
- var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
- match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
- !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
- // calculate the numbers (first)n+(last) including if they are negative
- match[2] = (test[1] + (test[2] || 1)) - 0;
- match[3] = test[3] - 0;
- }
-
- // TODO: Move to normal caching system
- match[0] = done++;
-
- return match;
- },
- ATTR: function(match, curLoop, inplace, result, not, isXML){
- var name = match[1].replace(/\\/g, "");
-
- if ( !isXML && Expr.attrMap[name] ) {
- match[1] = Expr.attrMap[name];
- }
-
- if ( match[2] === "~=" ) {
- match[4] = " " + match[4] + " ";
- }
-
- return match;
- },
- PSEUDO: function(match, curLoop, inplace, result, not){
- if ( match[1] === "not" ) {
- // If we're dealing with a complex expression, or a simple one
- if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
- match[3] = Sizzle(match[3], null, null, curLoop);
- } else {
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
- if ( !inplace ) {
- result.push.apply( result, ret );
- }
- return false;
- }
- } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
- return true;
- }
-
- return match;
- },
- POS: function(match){
- match.unshift( true );
- return match;
- }
- },
- filters: {
- enabled: function(elem){
- return elem.disabled === false && elem.type !== "hidden";
- },
- disabled: function(elem){
- return elem.disabled === true;
- },
- checked: function(elem){
- return elem.checked === true;
- },
- selected: function(elem){
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- elem.parentNode.selectedIndex;
- return elem.selected === true;
- },
- parent: function(elem){
- return !!elem.firstChild;
- },
- empty: function(elem){
- return !elem.firstChild;
- },
- has: function(elem, i, match){
- return !!Sizzle( match[3], elem ).length;
- },
- header: function(elem){
- return /h\d/i.test( elem.nodeName );
- },
- text: function(elem){
- return "text" === elem.type;
- },
- radio: function(elem){
- return "radio" === elem.type;
- },
- checkbox: function(elem){
- return "checkbox" === elem.type;
- },
- file: function(elem){
- return "file" === elem.type;
- },
- password: function(elem){
- return "password" === elem.type;
- },
- submit: function(elem){
- return "submit" === elem.type;
- },
- image: function(elem){
- return "image" === elem.type;
- },
- reset: function(elem){
- return "reset" === elem.type;
- },
- button: function(elem){
- return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
- },
- input: function(elem){
- return /input|select|textarea|button/i.test(elem.nodeName);
- }
- },
- setFilters: {
- first: function(elem, i){
- return i === 0;
- },
- last: function(elem, i, match, array){
- return i === array.length - 1;
- },
- even: function(elem, i){
- return i % 2 === 0;
- },
- odd: function(elem, i){
- return i % 2 === 1;
- },
- lt: function(elem, i, match){
- return i < match[3] - 0;
- },
- gt: function(elem, i, match){
- return i > match[3] - 0;
- },
- nth: function(elem, i, match){
- return match[3] - 0 === i;
- },
- eq: function(elem, i, match){
- return match[3] - 0 === i;
- }
- },
- filter: {
- PSEUDO: function(elem, match, i, array){
- var name = match[1], filter = Expr.filters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- } else if ( name === "contains" ) {
- return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
- } else if ( name === "not" ) {
- var not = match[3];
-
- for ( var i = 0, l = not.length; i < l; i++ ) {
- if ( not[i] === elem ) {
- return false;
- }
- }
-
- return true;
- } else {
- Sizzle.error( "Syntax error, unrecognized expression: " + name );
- }
- },
- CHILD: function(elem, match){
- var type = match[1], node = elem;
- switch (type) {
- case 'only':
- case 'first':
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
- if ( type === "first" ) {
- return true;
- }
- node = elem;
- case 'last':
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
- return true;
- case 'nth':
- var first = match[2], last = match[3];
-
- if ( first === 1 && last === 0 ) {
- return true;
- }
-
- var doneName = match[0],
- parent = elem.parentNode;
-
- if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
- var count = 0;
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- node.nodeIndex = ++count;
- }
- }
- parent.sizcache = doneName;
- }
-
- var diff = elem.nodeIndex - last;
- if ( first === 0 ) {
- return diff === 0;
- } else {
- return ( diff % first === 0 && diff / first >= 0 );
- }
- }
- },
- ID: function(elem, match){
- return elem.nodeType === 1 && elem.getAttribute("id") === match;
- },
- TAG: function(elem, match){
- return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
- },
- CLASS: function(elem, match){
- return (" " + (elem.className || elem.getAttribute("class")) + " ")
- .indexOf( match ) > -1;
- },
- ATTR: function(elem, match){
- var name = match[1],
- result = Expr.attrHandle[ name ] ?
- Expr.attrHandle[ name ]( elem ) :
- elem[ name ] != null ?
- elem[ name ] :
- elem.getAttribute( name ),
- value = result + "",
- type = match[2],
- check = match[4];
-
- return result == null ?
- type === "!=" :
- type === "=" ?
- value === check :
- type === "*=" ?
- value.indexOf(check) >= 0 :
- type === "~=" ?
- (" " + value + " ").indexOf(check) >= 0 :
- !check ?
- value && result !== false :
- type === "!=" ?
- value !== check :
- type === "^=" ?
- value.indexOf(check) === 0 :
- type === "$=" ?
- value.substr(value.length - check.length) === check :
- type === "|=" ?
- value === check || value.substr(0, check.length + 1) === check + "-" :
- false;
- },
- POS: function(elem, match, i, array){
- var name = match[2], filter = Expr.setFilters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- }
- }
- }
-};
-
-var origPOS = Expr.match.POS;
-
-for ( var type in Expr.match ) {
- Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
- Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
- return "\\" + (num - 0 + 1);
- }));
-}
-
-var makeArray = function(array, results) {
- array = Array.prototype.slice.call( array, 0 );
-
- if ( results ) {
- results.push.apply( results, array );
- return results;
- }
-
- return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-// Also verifies that the returned array holds DOM nodes
-// (which is not the case in the Blackberry browser)
-try {
- Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
-
-// Provide a fallback method if it does not work
-} catch(e){
- makeArray = function(array, results) {
- var ret = results || [];
-
- if ( toString.call(array) === "[object Array]" ) {
- Array.prototype.push.apply( ret, array );
- } else {
- if ( typeof array.length === "number" ) {
- for ( var i = 0, l = array.length; i < l; i++ ) {
- ret.push( array[i] );
- }
- } else {
- for ( var i = 0; array[i]; i++ ) {
- ret.push( array[i] );
- }
- }
- }
-
- return ret;
- };
-}
-
-var sortOrder;
-
-if ( document.documentElement.compareDocumentPosition ) {
- sortOrder = function( a, b ) {
- if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return a.compareDocumentPosition ? -1 : 1;
- }
-
- var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-} else if ( "sourceIndex" in document.documentElement ) {
- sortOrder = function( a, b ) {
- if ( !a.sourceIndex || !b.sourceIndex ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return a.sourceIndex ? -1 : 1;
- }
-
- var ret = a.sourceIndex - b.sourceIndex;
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-} else if ( document.createRange ) {
- sortOrder = function( a, b ) {
- if ( !a.ownerDocument || !b.ownerDocument ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return a.ownerDocument ? -1 : 1;
- }
-
- var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
- aRange.setStart(a, 0);
- aRange.setEnd(a, 0);
- bRange.setStart(b, 0);
- bRange.setEnd(b, 0);
- var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-}
-
-// Utility function for retreiving the text value of an array of DOM nodes
-function getText( elems ) {
- var ret = "", elem;
-
- for ( var i = 0; elems[i]; i++ ) {
- elem = elems[i];
-
- // Get the text from text nodes and CDATA nodes
- if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
- ret += elem.nodeValue;
-
- // Traverse everything else, except comment nodes
- } else if ( elem.nodeType !== 8 ) {
- ret += getText( elem.childNodes );
- }
- }
-
- return ret;
-}
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
- // We're going to inject a fake input element with a specified name
- var form = document.createElement("div"),
- id = "script" + (new Date).getTime();
- form.innerHTML = " ";
-
- // Inject it into the root element, check its status, and remove it quickly
- var root = document.documentElement;
- root.insertBefore( form, root.firstChild );
-
- // The workaround has to do additional checks after a getElementById
- // Which slows things down for other browsers (hence the branching)
- if ( document.getElementById( id ) ) {
- Expr.find.ID = function(match, context, isXML){
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
- }
- };
-
- Expr.filter.ID = function(elem, match){
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
- return elem.nodeType === 1 && node && node.nodeValue === match;
- };
- }
-
- root.removeChild( form );
- root = form = null; // release memory in IE
-})();
-
-(function(){
- // Check to see if the browser returns only elements
- // when doing getElementsByTagName("*")
-
- // Create a fake element
- var div = document.createElement("div");
- div.appendChild( document.createComment("") );
-
- // Make sure no comments are found
- if ( div.getElementsByTagName("*").length > 0 ) {
- Expr.find.TAG = function(match, context){
- var results = context.getElementsByTagName(match[1]);
-
- // Filter out possible comments
- if ( match[1] === "*" ) {
- var tmp = [];
-
- for ( var i = 0; results[i]; i++ ) {
- if ( results[i].nodeType === 1 ) {
- tmp.push( results[i] );
- }
- }
-
- results = tmp;
- }
-
- return results;
- };
- }
-
- // Check to see if an attribute returns normalized href attributes
- div.innerHTML = " ";
- if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
- div.firstChild.getAttribute("href") !== "#" ) {
- Expr.attrHandle.href = function(elem){
- return elem.getAttribute("href", 2);
- };
- }
-
- div = null; // release memory in IE
-})();
-
-if ( document.querySelectorAll ) {
- (function(){
- var oldSizzle = Sizzle, div = document.createElement("div");
- div.innerHTML = "
";
-
- // Safari can't handle uppercase or unicode characters when
- // in quirks mode.
- if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
- return;
- }
-
- Sizzle = function(query, context, extra, seed){
- context = context || document;
-
- // Only use querySelectorAll on non-XML documents
- // (ID selectors don't work in non-HTML documents)
- if ( !seed && context.nodeType === 9 && !isXML(context) ) {
- try {
- return makeArray( context.querySelectorAll(query), extra );
- } catch(e){}
- }
-
- return oldSizzle(query, context, extra, seed);
- };
-
- for ( var prop in oldSizzle ) {
- Sizzle[ prop ] = oldSizzle[ prop ];
- }
-
- div = null; // release memory in IE
- })();
-}
-
-(function(){
- var div = document.createElement("div");
-
- div.innerHTML = "
";
-
- // Opera can't find a second classname (in 9.6)
- // Also, make sure that getElementsByClassName actually exists
- if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
- return;
- }
-
- // Safari caches class attributes, doesn't catch changes (in 3.2)
- div.lastChild.className = "e";
-
- if ( div.getElementsByClassName("e").length === 1 ) {
- return;
- }
-
- Expr.order.splice(1, 0, "CLASS");
- Expr.find.CLASS = function(match, context, isXML) {
- if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
- return context.getElementsByClassName(match[1]);
- }
- };
-
- div = null; // release memory in IE
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- elem = elem[dir];
- var match = false;
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 && !isXML ){
- elem.sizcache = doneName;
- elem.sizset = i;
- }
-
- if ( elem.nodeName.toLowerCase() === cur ) {
- match = elem;
- break;
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- elem = elem[dir];
- var match = false;
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 ) {
- if ( !isXML ) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
- if ( typeof cur !== "string" ) {
- if ( elem === cur ) {
- match = true;
- break;
- }
-
- } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
- match = elem;
- break;
- }
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-var contains = document.compareDocumentPosition ? function(a, b){
- return !!(a.compareDocumentPosition(b) & 16);
-} : function(a, b){
- return a !== b && (a.contains ? a.contains(b) : true);
-};
-
-var isXML = function(elem){
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-var posProcess = function(selector, context){
- var tmpSet = [], later = "", match,
- root = context.nodeType ? [context] : context;
-
- // Position selectors must be done after the filter
- // And so must :not(positional) so we move all PSEUDOs to the end
- while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
- later += match[0];
- selector = selector.replace( Expr.match.PSEUDO, "" );
- }
-
- selector = Expr.relative[selector] ? selector + "*" : selector;
-
- for ( var i = 0, l = root.length; i < l; i++ ) {
- Sizzle( selector, root[i], tmpSet );
- }
-
- return Sizzle.filter( later, tmpSet );
-};
-
-// EXPOSE
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.filters;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = getText;
-jQuery.isXMLDoc = isXML;
-jQuery.contains = contains;
-
-return;
-
-window.Sizzle = Sizzle;
-
-})();
-var runtil = /Until$/,
- rparentsprev = /^(?:parents|prevUntil|prevAll)/,
- // Note: This RegExp should be improved, or likely pulled from Sizzle
- rmultiselector = /,/,
- slice = Array.prototype.slice;
-
-// Implement the identical functionality for filter and not
-var winnow = function( elements, qualifier, keep ) {
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep(elements, function( elem, i ) {
- return !!qualifier.call( elem, i, elem ) === keep;
- });
-
- } else if ( qualifier.nodeType ) {
- return jQuery.grep(elements, function( elem, i ) {
- return (elem === qualifier) === keep;
- });
-
- } else if ( typeof qualifier === "string" ) {
- var filtered = jQuery.grep(elements, function( elem ) {
- return elem.nodeType === 1;
- });
-
- if ( isSimple.test( qualifier ) ) {
- return jQuery.filter(qualifier, filtered, !keep);
- } else {
- qualifier = jQuery.filter( qualifier, filtered );
- }
- }
-
- return jQuery.grep(elements, function( elem, i ) {
- return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
- });
-};
-
-jQuery.fn.extend({
- find: function( selector ) {
- var ret = this.pushStack( "", "find", selector ), length = 0;
-
- for ( var i = 0, l = this.length; i < l; i++ ) {
- length = ret.length;
- jQuery.find( selector, this[i], ret );
-
- if ( i > 0 ) {
- // Make sure that the results are unique
- for ( var n = length; n < ret.length; n++ ) {
- for ( var r = 0; r < length; r++ ) {
- if ( ret[r] === ret[n] ) {
- ret.splice(n--, 1);
- break;
- }
- }
- }
- }
- }
-
- return ret;
- },
-
- has: function( target ) {
- var targets = jQuery( target );
- return this.filter(function() {
- for ( var i = 0, l = targets.length; i < l; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
- return true;
- }
- }
- });
- },
-
- not: function( selector ) {
- return this.pushStack( winnow(this, selector, false), "not", selector);
- },
-
- filter: function( selector ) {
- return this.pushStack( winnow(this, selector, true), "filter", selector );
- },
-
- is: function( selector ) {
- return !!selector && jQuery.filter( selector, this ).length > 0;
- },
-
- closest: function( selectors, context ) {
- if ( jQuery.isArray( selectors ) ) {
- var ret = [], cur = this[0], match, matches = {}, selector;
-
- if ( cur && selectors.length ) {
- for ( var i = 0, l = selectors.length; i < l; i++ ) {
- selector = selectors[i];
-
- if ( !matches[selector] ) {
- matches[selector] = jQuery.expr.match.POS.test( selector ) ?
- jQuery( selector, context || this.context ) :
- selector;
- }
- }
-
- while ( cur && cur.ownerDocument && cur !== context ) {
- for ( selector in matches ) {
- match = matches[selector];
-
- if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
- ret.push({ selector: selector, elem: cur });
- delete matches[selector];
- }
- }
- cur = cur.parentNode;
- }
- }
-
- return ret;
- }
-
- var pos = jQuery.expr.match.POS.test( selectors ) ?
- jQuery( selectors, context || this.context ) : null;
-
- return this.map(function( i, cur ) {
- while ( cur && cur.ownerDocument && cur !== context ) {
- if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
- return cur;
- }
- cur = cur.parentNode;
- }
- return null;
- });
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
- if ( !elem || typeof elem === "string" ) {
- return jQuery.inArray( this[0],
- // If it receives a string, the selector is used
- // If it receives nothing, the siblings are used
- elem ? jQuery( elem ) : this.parent().children() );
- }
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[0] : elem, this );
- },
-
- add: function( selector, context ) {
- var set = typeof selector === "string" ?
- jQuery( selector, context || this.context ) :
- jQuery.makeArray( selector ),
- all = jQuery.merge( this.get(), set );
-
- return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
- all :
- jQuery.unique( all ) );
- },
-
- andSelf: function() {
- return this.add( this.prevObject );
- }
-});
-
-// A painfully simple check to see if an element is disconnected
-// from a document (should be improved, where feasible).
-function isDisconnected( node ) {
- return !node || !node.parentNode || node.parentNode.nodeType === 11;
-}
-
-jQuery.each({
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return jQuery.nth( elem, 2, "nextSibling" );
- },
- prev: function( elem ) {
- return jQuery.nth( elem, 2, "previousSibling" );
- },
- nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return jQuery.sibling( elem.parentNode.firstChild, elem );
- },
- children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
- },
- contents: function( elem ) {
- return jQuery.nodeName( elem, "iframe" ) ?
- elem.contentDocument || elem.contentWindow.document :
- jQuery.makeArray( elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var ret = jQuery.map( this, fn, until );
-
- if ( !runtil.test( name ) ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- ret = jQuery.filter( selector, ret );
- }
-
- ret = this.length > 1 ? jQuery.unique( ret ) : ret;
-
- if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
- ret = ret.reverse();
- }
-
- return this.pushStack( ret, name, slice.call(arguments).join(",") );
- };
-});
-
-jQuery.extend({
- filter: function( expr, elems, not ) {
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return jQuery.find.matches(expr, elems);
- },
-
- dir: function( elem, dir, until ) {
- var matched = [], cur = elem[dir];
- while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
- if ( cur.nodeType === 1 ) {
- matched.push( cur );
- }
- cur = cur[dir];
- }
- return matched;
- },
-
- nth: function( cur, result, dir, elem ) {
- result = result || 1;
- var num = 0;
-
- for ( ; cur; cur = cur[dir] ) {
- if ( cur.nodeType === 1 && ++num === result ) {
- break;
- }
- }
-
- return cur;
- },
-
- sibling: function( n, elem ) {
- var r = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- r.push( n );
- }
- }
-
- return r;
- }
-});
-var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
- rleadingWhitespace = /^\s+/,
- rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
- rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
- rtagName = /<([\w:]+)/,
- rtbody = /" + tag + ">";
- },
- wrapMap = {
- option: [ 1, "", " " ],
- legend: [ 1, "", " " ],
- thead: [ 1, "" ],
- tr: [ 2, "" ],
- td: [ 3, "" ],
- col: [ 2, "" ],
- area: [ 1, "", " " ],
- _default: [ 0, "", "" ]
- };
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-// IE can't serialize and
\ No newline at end of file
diff --git a/src/ajax.js b/src/ajax.js
index 355fd7e4..3e724880 100644
--- a/src/ajax.js
+++ b/src/ajax.js
@@ -1,173 +1,32 @@
-(function( jQuery ) {
-
-var r20 = /%20/g,
- rbracket = /\[\]$/,
- rCRLF = /\r?\n/g,
- rhash = /#.*$/,
- rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
- rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
- // #7653, #8125, #8152: local protocol detection
- rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
- rnoContent = /^(?:GET|HEAD)$/,
- rprotocol = /^\/\//,
- rquery = /\?/,
- rscript = /
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CSP Test Page
-
-