From 7cf684f6245010030c6cdc9838ceebd80af85d10 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Fri, 14 Apr 2017 22:35:02 +0300 Subject: [PATCH] KJS: remove unnecessary files from testData --- js/js.translator/testData/jshint.js | 4523 -------- js/js.translator/testData/jslint.js | 6400 ------------ .../testData/libImplementations/jQuery.js | 9300 ----------------- .../testData/libImplementations/jshashset.js | 32 - .../libImplementations/jshashset_src.js | 107 - .../libImplementations/jshashtable-2.1.js | 32 - .../libImplementations/jshashtable-2.1_src.js | 370 - .../testData/libImplementations/prototype.js | 404 - .../testData/objectIntrinsics/dummy.txt | 0 9 files changed, 21168 deletions(-) delete mode 100644 js/js.translator/testData/jshint.js delete mode 100644 js/js.translator/testData/jslint.js delete mode 100644 js/js.translator/testData/libImplementations/jQuery.js delete mode 100644 js/js.translator/testData/libImplementations/jshashset.js delete mode 100644 js/js.translator/testData/libImplementations/jshashset_src.js delete mode 100644 js/js.translator/testData/libImplementations/jshashtable-2.1.js delete mode 100644 js/js.translator/testData/libImplementations/jshashtable-2.1_src.js delete mode 100644 js/js.translator/testData/libImplementations/prototype.js delete mode 100644 js/js.translator/testData/objectIntrinsics/dummy.txt diff --git a/js/js.translator/testData/jshint.js b/js/js.translator/testData/jshint.js deleted file mode 100644 index 62b08159662..00000000000 --- a/js/js.translator/testData/jshint.js +++ /dev/null @@ -1,4523 +0,0 @@ -/*! - * JSHint, by JSHint Community. - * - * Licensed under the same slightly modified MIT license that JSLint is. - * It stops evil-doers everywhere. - * - * JSHint is a derivative work of JSLint: - * - * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * The Software shall be used for Good, not Evil. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * JSHint was forked from 2010-12-16 edition of JSLint. - * - */ - -/* - JSHINT is a global function. It takes two parameters. - - var myResult = JSHINT(source, option); - - The first parameter is either a string or an array of strings. If it is a - string, it will be split on '\n' or '\r'. If it is an array of strings, it - is assumed that each string represents one line. The source can be a - JavaScript text or a JSON text. - - The second parameter is an optional object of options which control the - operation of JSHINT. Most of the options are booleans: They are all - optional and have a default value of false. One of the options, predef, - can be an array of names, which will be used to declare global variables, - or an object whose keys are used as global names, with a boolean value - that determines if they are assignable. - - If it checks out, JSHINT returns true. Otherwise, it returns false. - - If false, you can inspect JSHINT.errors to find out the problems. - JSHINT.errors is an array of objects containing these members: - - { - line : The line (relative to 0) at which the lint was found - character : The character (relative to 0) at which the lint was found - reason : The problem - evidence : The text line in which the problem occurred - raw : The raw message before the details were inserted - a : The first detail - b : The second detail - c : The third detail - d : The fourth detail - } - - If a fatal error was found, a null will be the last element of the - JSHINT.errors array. - - You can request a Function Report, which shows all of the functions - and the parameters and vars that they use. This can be used to find - implied global variables and other problems. The report is in HTML and - can be inserted in an HTML . - - var myReport = JSHINT.report(limited); - - If limited is true, then the report will be limited to only errors. - - You can request a data structure which contains JSHint's results. - - var myData = JSHINT.data(); - - It returns a structure with this form: - - { - errors: [ - { - line: NUMBER, - character: NUMBER, - reason: STRING, - evidence: STRING - } - ], - functions: [ - name: STRING, - line: NUMBER, - last: NUMBER, - param: [ - STRING - ], - closure: [ - STRING - ], - var: [ - STRING - ], - exception: [ - STRING - ], - outer: [ - STRING - ], - unused: [ - STRING - ], - global: [ - STRING - ], - label: [ - STRING - ] - ], - globals: [ - STRING - ], - member: { - STRING: NUMBER - }, - unused: [ - { - name: STRING, - line: NUMBER - } - ], - implieds: [ - { - name: STRING, - line: NUMBER - } - ], - urls: [ - STRING - ], - json: BOOLEAN - } - - Empty arrays will not be included. - -*/ - -/*jshint - evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true, - undef: true, maxlen: 100, indent:4 -*/ - -/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)", - "(breakage)", "(context)", "(error)", "(global)", "(identifier)", "(last)", - "(line)", "(loopage)", "(name)", "(onevar)", "(params)", "(scope)", - "(statement)", "(verb)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==", - "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax, - __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio, - Autocompleter, Assets, Boolean, Builder, Buffer, Browser, COM, CScript, Canvas, - CustomAnimation, Class, Control, Chain, Color, Cookie, Core, DataView, Date, - Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMReady, DOMParser, Drag, - E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event, - Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form, - FormField, Frame, FormData, Function, Fx, GetObject, Group, Hash, HotKey, - HTMLElement, HTMLAnchorElement, HTMLBaseElement, HTMLBlockquoteElement, - HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDirectoryElement, - HTMLDivElement, HTMLDListElement, HTMLFieldSetElement, - HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement, - HTMLHeadElement, HTMLHeadingElement, HTMLHRElement, HTMLHtmlElement, - HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLIsIndexElement, - HTMLLabelElement, HTMLLayerElement, HTMLLegendElement, HTMLLIElement, - HTMLLinkElement, HTMLMapElement, HTMLMenuElement, HTMLMetaElement, - HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement, - HTMLOptionElement, HTMLParagraphElement, HTMLParamElement, HTMLPreElement, - HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLStyleElement, - HtmlTable, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement, - HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement, - HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement, HTMLVideoElement, - Iframe, IframeShim, Image, Int16Array, Int32Array, Int8Array, - Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E, - MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem, MessageChannel, MessageEvent, MessagePort, - MoveAnimation, MooTools, Native, NEGATIVE_INFINITY, Number, Object, ObjectRange, Option, - Options, OverText, PI, POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype, - RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation, - SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion, - ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller, - Slick, Slider, Selector, SharedWorker, String, Style, SyntaxError, Sortable, Sortables, - SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template, - Timer, Tips, Type, TypeError, Toggle, Try, "use strict", unescape, URI, URIError, URL, - VBArray, WSH, WScript, XDomainRequest, Web, Window, XMLDOM, XMLHttpRequest, XMLSerializer, - XPathEvaluator, XPathException, XPathExpression, XPathNamespace, XPathNSResolver, XPathResult, - "\\", a, addEventListener, address, alert, apply, applicationCache, arguments, arity, asi, atob, - b, basic, basicToken, bitwise, block, blur, boolOptions, boss, browser, btoa, c, call, callee, - caller, cases, charAt, charCodeAt, character, clearInterval, clearTimeout, - close, closed, closure, comment, condition, confirm, console, constructor, - content, couch, create, css, curly, d, data, datalist, dd, debug, decodeURI, - decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document, - dojo, dijit, dojox, define, else, emit, encodeURI, encodeURIComponent, - entityify, eqeq, eqeqeq, eqnull, errors, es5, escape, esnext, eval, event, evidence, evil, - ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus, - forin, fragment, frames, from, fromCharCode, fud, funcscope, funct, function, functions, - g, gc, getComputedStyle, getRow, getter, getterToken, GLOBAL, global, globals, globalstrict, - hasOwnProperty, help, history, i, id, identifier, immed, implieds, importPackage, include, - indent, indexOf, init, ins, instanceOf, isAlpha, isApplicationRunning, isArray, - isDigit, isFinite, isNaN, iterator, java, join, jshint, - JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastsemic, laxbreak, laxcomma, - latedef, lbp, led, left, length, line, load, loadClass, localStorage, location, - log, loopfunc, m, match, maxerr, maxlen, member,message, meta, module, moveBy, - moveTo, mootools, multistr, name, navigator, new, newcap, noarg, node, noempty, nomen, - nonew, nonstandard, nud, onbeforeunload, onblur, onerror, onevar, onecase, onfocus, - onload, onresize, onunload, open, openDatabase, openURL, opener, opera, options, outer, param, - parent, parseFloat, parseInt, passfail, plusplus, predef, print, process, prompt, - proto, prototype, prototypejs, provides, push, quit, range, raw, reach, reason, regexp, - readFile, readUrl, regexdash, removeEventListener, replace, report, require, - reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right, - runCommand, scroll, screen, scripturl, scrollBy, scrollTo, scrollbar, search, seal, - send, serialize, sessionStorage, setInterval, setTimeout, setter, setterToken, shift, slice, - smarttabs, sort, spawn, split, stack, status, start, strict, sub, substr, supernew, shadow, - supplant, sum, sync, test, toLowerCase, toString, toUpperCase, toint32, token, top, trailing, - type, typeOf, Uint16Array, Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis, - value, valueOf, var, vars, version, WebSocket, withstmt, white, window, windows, Worker, wsh*/ - -/*global exports: false */ - -// We build the application inside a function so that we produce only a single -// global variable. That function will be invoked immediately, and its return -// value is the JSHINT function itself. - -var JSHINT = (function () { - "use strict"; - - var anonname, // The guessed name for anonymous functions. - -// These are operators that should not be used with the ! operator. - - bang = { - '<' : true, - '<=' : true, - '==' : true, - '===': true, - '!==': true, - '!=' : true, - '>' : true, - '>=' : true, - '+' : true, - '-' : true, - '*' : true, - '/' : true, - '%' : true - }, - - // These are the JSHint boolean options. - boolOptions = { - asi : true, // if automatic semicolon insertion should be tolerated - bitwise : true, // if bitwise operators should not be allowed - boss : true, // if advanced usage of assignments should be allowed - browser : true, // if the standard browser globals should be predefined - couch : true, // if CouchDB globals should be predefined - curly : true, // if curly braces around all blocks should be required - debug : true, // if debugger statements should be allowed - devel : true, // if logging globals should be predefined (console, - // alert, etc.) - dojo : true, // if Dojo Toolkit globals should be predefined - eqeqeq : true, // if === should be required - eqnull : true, // if == null comparisons should be tolerated - es5 : true, // if ES5 syntax should be allowed - esnext : true, // if es.next specific syntax should be allowed - evil : true, // if eval should be allowed - expr : true, // if ExpressionStatement should be allowed as Programs - forin : true, // if for in statements must filter - funcscope : true, // if only function scope should be used for scope tests - globalstrict: true, // if global "use strict"; should be allowed (also - // enables 'strict') - immed : true, // if immediate invocations must be wrapped in parens - iterator : true, // if the `__iterator__` property should be allowed - jquery : true, // if jQuery globals should be predefined - lastsemic : true, // if semicolons may be ommitted for the trailing - // statements inside of a one-line blocks. - latedef : true, // if the use before definition should not be tolerated - laxbreak : true, // if line breaks should not be checked - laxcomma : true, // if line breaks should not be checked around commas - loopfunc : true, // if functions should be allowed to be defined within - // loops - mootools : true, // if MooTools globals should be predefined - multistr : true, // allow multiline strings - newcap : true, // if constructor names must be capitalized - noarg : true, // if arguments.caller and arguments.callee should be - // disallowed - node : true, // if the Node.js environment globals should be - // predefined - noempty : true, // if empty blocks should be disallowed - nonew : true, // if using `new` for side-effects should be disallowed - nonstandard : true, // if non-standard (but widely adopted) globals should - // be predefined - nomen : true, // if names should be checked - onevar : true, // if only one var statement per function should be - // allowed - onecase : true, // if one case switch statements should be allowed - passfail : true, // if the scan should stop on first error - plusplus : true, // if increment/decrement should not be allowed - proto : true, // if the `__proto__` property should be allowed - prototypejs : true, // if Prototype and Scriptaculous globals should be - // predefined - regexdash : true, // if unescaped first/last dash (-) inside brackets - // should be tolerated - regexp : true, // if the . should not be allowed in regexp literals - rhino : true, // if the Rhino environment globals should be predefined - undef : true, // if variables should be declared before used - scripturl : true, // if script-targeted URLs should be tolerated - shadow : true, // if variable shadowing should be tolerated - smarttabs : true, // if smarttabs should be tolerated - // (http://www.emacswiki.org/emacs/SmartTabs) - strict : true, // require the "use strict"; pragma - sub : true, // if all forms of subscript notation are tolerated - supernew : true, // if `new function () { ... };` and `new Object;` - // should be tolerated - trailing : true, // if trailing whitespace rules apply - validthis : true, // if 'this' inside a non-constructor function is valid. - // This is a function scoped option only. - withstmt : true, // if with statements should be allowed - white : true, // if strict whitespace rules apply - wsh : true // if the Windows Scripting Host environment globals - // should be predefined - }, - - // These are the JSHint options that can take any value - // (we use this object to detect invalid options) - valOptions = { - maxlen: false, - indent: false, - maxerr: false, - predef: false - }, - - // These are JSHint boolean options which are shared with JSLint - // where the definition in JSHint is opposite JSLint - invertedOptions = { - bitwise : true, - forin : true, - newcap : true, - nomen : true, - plusplus : true, - regexp : true, - undef : true, - white : true, - - // Inverted and renamed, use JSHint name here - eqeqeq : true, - onevar : true - }, - - // These are JSHint boolean options which are shared with JSLint - // where the name has been changed but the effect is unchanged - renamedOptions = { - eqeq : "eqeqeq", - vars : "onevar", - windows : "wsh" - }, - - - // browser contains a set of global names which are commonly provided by a - // web browser environment. - browser = { - ArrayBuffer : false, - ArrayBufferView : false, - Audio : false, - addEventListener : false, - applicationCache : false, - atob : false, - blur : false, - btoa : false, - clearInterval : false, - clearTimeout : false, - close : false, - closed : false, - DataView : false, - DOMParser : false, - defaultStatus : false, - document : false, - event : false, - FileReader : false, - Float32Array : false, - Float64Array : false, - FormData : false, - focus : false, - frames : false, - getComputedStyle : false, - HTMLElement : false, - HTMLAnchorElement : false, - HTMLBaseElement : false, - HTMLBlockquoteElement : false, - HTMLBodyElement : false, - HTMLBRElement : false, - HTMLButtonElement : false, - HTMLCanvasElement : false, - HTMLDirectoryElement : false, - HTMLDivElement : false, - HTMLDListElement : false, - HTMLFieldSetElement : false, - HTMLFontElement : false, - HTMLFormElement : false, - HTMLFrameElement : false, - HTMLFrameSetElement : false, - HTMLHeadElement : false, - HTMLHeadingElement : false, - HTMLHRElement : false, - HTMLHtmlElement : false, - HTMLIFrameElement : false, - HTMLImageElement : false, - HTMLInputElement : false, - HTMLIsIndexElement : false, - HTMLLabelElement : false, - HTMLLayerElement : false, - HTMLLegendElement : false, - HTMLLIElement : false, - HTMLLinkElement : false, - HTMLMapElement : false, - HTMLMenuElement : false, - HTMLMetaElement : false, - HTMLModElement : false, - HTMLObjectElement : false, - HTMLOListElement : false, - HTMLOptGroupElement : false, - HTMLOptionElement : false, - HTMLParagraphElement : false, - HTMLParamElement : false, - HTMLPreElement : false, - HTMLQuoteElement : false, - HTMLScriptElement : false, - HTMLSelectElement : false, - HTMLStyleElement : false, - HTMLTableCaptionElement : false, - HTMLTableCellElement : false, - HTMLTableColElement : false, - HTMLTableElement : false, - HTMLTableRowElement : false, - HTMLTableSectionElement : false, - HTMLTextAreaElement : false, - HTMLTitleElement : false, - HTMLUListElement : false, - HTMLVideoElement : false, - history : false, - Int16Array : false, - Int32Array : false, - Int8Array : false, - Image : false, - length : false, - localStorage : false, - location : false, - MessageChannel : false, - MessageEvent : false, - MessagePort : false, - moveBy : false, - moveTo : false, - name : false, - navigator : false, - onbeforeunload : true, - onblur : true, - onerror : true, - onfocus : true, - onload : true, - onresize : true, - onunload : true, - open : false, - openDatabase : false, - opener : false, - Option : false, - parent : false, - print : false, - removeEventListener : false, - resizeBy : false, - resizeTo : false, - screen : false, - scroll : false, - scrollBy : false, - scrollTo : false, - sessionStorage : false, - setInterval : false, - setTimeout : false, - SharedWorker : false, - status : false, - top : false, - Uint16Array : false, - Uint32Array : false, - Uint8Array : false, - WebSocket : false, - window : false, - Worker : false, - XMLHttpRequest : false, - XMLSerializer : false, - XPathEvaluator : false, - XPathException : false, - XPathExpression : false, - XPathNamespace : false, - XPathNSResolver : false, - XPathResult : false - }, - - couch = { - "require" : false, - respond : false, - getRow : false, - emit : false, - send : false, - start : false, - sum : false, - log : false, - exports : false, - module : false, - provides : false - }, - - devel = { - alert : false, - confirm : false, - console : false, - Debug : false, - opera : false, - prompt : false - }, - - dojo = { - dojo : false, - dijit : false, - dojox : false, - define : false, - "require" : false - }, - - escapes = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '/' : '\\/', - '\\': '\\\\' - }, - - funct, // The current function - - functionicity = [ - 'closure', 'exception', 'global', 'label', - 'outer', 'unused', 'var' - ], - - functions, // All of the functions - - global, // The global scope - implied, // Implied globals - inblock, - indent, - jsonmode, - - jquery = { - '$' : false, - jQuery : false - }, - - lines, - lookahead, - member, - membersOnly, - - mootools = { - '$' : false, - '$$' : false, - Assets : false, - Browser : false, - Chain : false, - Class : false, - Color : false, - Cookie : false, - Core : false, - Document : false, - DomReady : false, - DOMReady : false, - Drag : false, - Element : false, - Elements : false, - Event : false, - Events : false, - Fx : false, - Group : false, - Hash : false, - HtmlTable : false, - Iframe : false, - IframeShim : false, - InputValidator : false, - instanceOf : false, - Keyboard : false, - Locale : false, - Mask : false, - MooTools : false, - Native : false, - Options : false, - OverText : false, - Request : false, - Scroller : false, - Slick : false, - Slider : false, - Sortables : false, - Spinner : false, - Swiff : false, - Tips : false, - Type : false, - typeOf : false, - URI : false, - Window : false - }, - - nexttoken, - - node = { - __filename : false, - __dirname : false, - Buffer : false, - console : false, - exports : false, - GLOBAL : false, - global : false, - module : false, - process : false, - require : false, - setTimeout : false, - clearTimeout : false, - setInterval : false, - clearInterval : false - }, - - noreach, - option, - predefined, // Global variables defined by option - prereg, - prevtoken, - - prototypejs = { - '$' : false, - '$$' : false, - '$A' : false, - '$F' : false, - '$H' : false, - '$R' : false, - '$break' : false, - '$continue' : false, - '$w' : false, - Abstract : false, - Ajax : false, - Class : false, - Enumerable : false, - Element : false, - Event : false, - Field : false, - Form : false, - Hash : false, - Insertion : false, - ObjectRange : false, - PeriodicalExecuter: false, - Position : false, - Prototype : false, - Selector : false, - Template : false, - Toggle : false, - Try : false, - Autocompleter : false, - Builder : false, - Control : false, - Draggable : false, - Draggables : false, - Droppables : false, - Effect : false, - Sortable : false, - SortableObserver : false, - Sound : false, - Scriptaculous : false - }, - - rhino = { - defineClass : false, - deserialize : false, - gc : false, - help : false, - importPackage: false, - "java" : false, - load : false, - loadClass : false, - print : false, - quit : false, - readFile : false, - readUrl : false, - runCommand : false, - seal : false, - serialize : false, - spawn : false, - sync : false, - toint32 : false, - version : false - }, - - scope, // The current scope - stack, - - // standard contains the global names that are provided by the - // ECMAScript standard. - standard = { - Array : false, - Boolean : false, - Date : false, - decodeURI : false, - decodeURIComponent : false, - encodeURI : false, - encodeURIComponent : false, - Error : false, - 'eval' : false, - EvalError : false, - Function : false, - hasOwnProperty : false, - isFinite : false, - isNaN : false, - JSON : false, - Math : false, - Number : false, - Object : false, - parseInt : false, - parseFloat : false, - RangeError : false, - ReferenceError : false, - RegExp : false, - String : false, - SyntaxError : false, - TypeError : false, - URIError : false - }, - - // widely adopted global names that are not part of ECMAScript standard - nonstandard = { - escape : false, - unescape : false - }, - - standard_member = { - E : true, - LN2 : true, - LN10 : true, - LOG2E : true, - LOG10E : true, - MAX_VALUE : true, - MIN_VALUE : true, - NEGATIVE_INFINITY : true, - PI : true, - POSITIVE_INFINITY : true, - SQRT1_2 : true, - SQRT2 : true - }, - - directive, - syntax = {}, - tab, - token, - urls, - useESNextSyntax, - warnings, - - wsh = { - ActiveXObject : true, - Enumerator : true, - GetObject : true, - ScriptEngine : true, - ScriptEngineBuildVersion : true, - ScriptEngineMajorVersion : true, - ScriptEngineMinorVersion : true, - VBArray : true, - WSH : true, - WScript : true, - XDomainRequest : true - }; - - // Regular expressions. Some of these are stupidly long. - var ax, cx, tx, nx, nxg, lx, ix, jx, ft; - (function () { - /*jshint maxlen:300 */ - - // unsafe comment or string - ax = /@cc|<\/?|script|\]\s*\]|<\s*!|</i; - - // unsafe characters that are silently deleted by one or more browsers - cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - - // token - tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/; - - // characters in strings that need escapement - nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - - // star slash - lx = /\*\/|\/\*/; - - // identifier - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; - - // javascript url - jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; - - // catches /* falls through */ comments - ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/; - }()); - - function F() {} // Used by Object.create - - function is_own(object, name) { - -// The object.hasOwnProperty method fails when the property under consideration -// is named 'hasOwnProperty'. So we have to use this more convoluted form. - - return Object.prototype.hasOwnProperty.call(object, name); - } - - function checkOption(name, t) { - if (valOptions[name] === undefined && boolOptions[name] === undefined) { - warning("Bad option: '" + name + "'.", t); - } - } - -// Provide critical ES5 functions to ES3. - - if (typeof Array.isArray !== 'function') { - Array.isArray = function (o) { - return Object.prototype.toString.apply(o) === '[object Array]'; - }; - } - - if (typeof Object.create !== 'function') { - Object.create = function (o) { - F.prototype = o; - return new F(); - }; - } - - if (typeof Object.keys !== 'function') { - Object.keys = function (o) { - var a = [], k; - for (k in o) { - if (is_own(o, k)) { - a.push(k); - } - } - return a; - }; - } - -// Non standard methods - - if (typeof String.prototype.entityify !== 'function') { - String.prototype.entityify = function () { - return this - .replace(/&/g, '&') - .replace(//g, '>'); - }; - } - - if (typeof String.prototype.isAlpha !== 'function') { - String.prototype.isAlpha = function () { - return (this >= 'a' && this <= 'z\uffff') || - (this >= 'A' && this <= 'Z\uffff'); - }; - } - - if (typeof String.prototype.isDigit !== 'function') { - String.prototype.isDigit = function () { - return (this >= '0' && this <= '9'); - }; - } - - if (typeof String.prototype.supplant !== 'function') { - String.prototype.supplant = function (o) { - return this.replace(/\{([^{}]*)\}/g, function (a, b) { - var r = o[b]; - return typeof r === 'string' || typeof r === 'number' ? r : a; - }); - }; - } - - if (typeof String.prototype.name !== 'function') { - String.prototype.name = function () { - -// If the string looks like an identifier, then we can return it as is. -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can simply slap some quotes around it. -// Otherwise we must also replace the offending characters with safe -// sequences. - - if (ix.test(this)) { - return this; - } - if (nx.test(this)) { - return '"' + this.replace(nxg, function (a) { - var c = escapes[a]; - if (c) { - return c; - } - return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); - }) + '"'; - } - return '"' + this + '"'; - }; - } - - - function combine(t, o) { - var n; - for (n in o) { - if (is_own(o, n)) { - t[n] = o[n]; - } - } - } - - function assume() { - if (option.couch) { - combine(predefined, couch); - } - - if (option.rhino) { - combine(predefined, rhino); - } - - if (option.prototypejs) { - combine(predefined, prototypejs); - } - - if (option.node) { - combine(predefined, node); - option.globalstrict = true; - } - - if (option.devel) { - combine(predefined, devel); - } - - if (option.dojo) { - combine(predefined, dojo); - } - - if (option.browser) { - combine(predefined, browser); - } - - if (option.nonstandard) { - combine(predefined, nonstandard); - } - - if (option.jquery) { - combine(predefined, jquery); - } - - if (option.mootools) { - combine(predefined, mootools); - } - - if (option.wsh) { - combine(predefined, wsh); - } - - if (option.esnext) { - useESNextSyntax(); - } - - if (option.globalstrict && option.strict !== false) { - option.strict = true; - } - } - - - // Produce an error warning. - function quit(message, line, chr) { - var percentage = Math.floor((line / lines.length) * 100); - - throw { - name: 'JSHintError', - line: line, - character: chr, - message: message + " (" + percentage + "% scanned).", - raw: message - }; - } - - function isundef(scope, m, t, a) { - return JSHINT.undefs.push([scope, m, t, a]); - } - - function warning(m, t, a, b, c, d) { - var ch, l, w; - t = t || nexttoken; - if (t.id === '(end)') { // `~ - t = token; - } - l = t.line || 0; - ch = t.from || 0; - w = { - id: '(error)', - raw: m, - evidence: lines[l - 1] || '', - line: l, - character: ch, - a: a, - b: b, - c: c, - d: d - }; - w.reason = m.supplant(w); - JSHINT.errors.push(w); - if (option.passfail) { - quit('Stopping. ', l, ch); - } - warnings += 1; - if (warnings >= option.maxerr) { - quit("Too many errors.", l, ch); - } - return w; - } - - function warningAt(m, l, ch, a, b, c, d) { - return warning(m, { - line: l, - from: ch - }, a, b, c, d); - } - - function error(m, t, a, b, c, d) { - var w = warning(m, t, a, b, c, d); - } - - function errorAt(m, l, ch, a, b, c, d) { - return error(m, { - line: l, - from: ch - }, a, b, c, d); - } - - - -// lexical analysis and token construction - - var lex = (function lex() { - var character, from, line, s; - -// Private lex methods - - function nextLine() { - var at, - tw; // trailing whitespace check - - if (line >= lines.length) - return false; - - character = 1; - s = lines[line]; - line += 1; - - // If smarttabs option is used check for spaces followed by tabs only. - // Otherwise check for any occurence of mixed tabs and spaces. - if (option.smarttabs) - at = s.search(/ \t/); - else - at = s.search(/ \t|\t /); - - if (at >= 0) - warningAt("Mixed spaces and tabs.", line, at + 1); - - s = s.replace(/\t/g, tab); - at = s.search(cx); - - if (at >= 0) - warningAt("Unsafe character.", line, at); - - if (option.maxlen && option.maxlen < s.length) - warningAt("Line too long.", line, s.length); - - // Check for trailing whitespaces - tw = option.trailing && s.match(/^(.*?)\s+$/); - if (tw && !/^\s+$/.test(s)) { - warningAt("Trailing whitespace.", line, tw[1].length + 1); - } - return true; - } - -// Produce a token object. The token inherits from a syntax symbol. - - function it(type, value) { - var i, t; - if (type === '(color)' || type === '(range)') { - t = {type: type}; - } else if (type === '(punctuator)' || - (type === '(identifier)' && is_own(syntax, value))) { - t = syntax[value] || syntax['(error)']; - } else { - t = syntax[type]; - } - t = Object.create(t); - if (type === '(string)' || type === '(range)') { - if (!option.scripturl && jx.test(value)) { - warningAt("Script URL.", line, from); - } - } - if (type === '(identifier)') { - t.identifier = true; - if (value === '__proto__' && !option.proto) { - warningAt("The '{a}' property is deprecated.", - line, from, value); - } else if (value === '__iterator__' && !option.iterator) { - warningAt("'{a}' is only available in JavaScript 1.7.", - line, from, value); - } else if (option.nomen && (value.charAt(0) === '_' || - value.charAt(value.length - 1) === '_')) { - if (!option.node || token.id === '.' || - (value !== '__dirname' && value !== '__filename')) { - warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", value); - } - } - } - t.value = value; - t.line = line; - t.character = character; - t.from = from; - i = t.id; - if (i !== '(endline)') { - prereg = i && - (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) || - i === 'return' || - i === 'case'); - } - return t; - } - - // Public lex methods - return { - init: function (source) { - if (typeof source === 'string') { - lines = source - .replace(/\r\n/g, '\n') - .replace(/\r/g, '\n') - .split('\n'); - } else { - lines = source; - } - - // If the first line is a shebang (#!), make it a blank and move on. - // Shebangs are used by Node scripts. - if (lines[0] && lines[0].substr(0, 2) === '#!') - lines[0] = ''; - - line = 0; - nextLine(); - from = 1; - }, - - range: function (begin, end) { - var c, value = ''; - from = character; - if (s.charAt(0) !== begin) { - errorAt("Expected '{a}' and instead saw '{b}'.", - line, character, begin, s.charAt(0)); - } - for (;;) { - s = s.slice(1); - character += 1; - c = s.charAt(0); - switch (c) { - case '': - errorAt("Missing '{a}'.", line, character, c); - break; - case end: - s = s.slice(1); - character += 1; - return it('(range)', value); - case '\\': - warningAt("Unexpected '{a}'.", line, character, c); - } - value += c; - } - - }, - - - // token -- this is called by advance to get the next token - token: function () { - var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange, n; - - function match(x) { - var r = x.exec(s), r1; - if (r) { - l = r[0].length; - r1 = r[1]; - c = r1.charAt(0); - s = s.substr(l); - from = character + l - r1.length; - character += l; - return r1; - } - } - - function string(x) { - var c, j, r = '', allowNewLine = false; - - if (jsonmode && x !== '"') { - warningAt("Strings must use doublequote.", - line, character); - } - - function esc(n) { - var i = parseInt(s.substr(j + 1, n), 16); - j += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warningAt("Unnecessary escapement.", line, character); - } - character += n; - c = String.fromCharCode(i); - } - j = 0; -unclosedString: for (;;) { - while (j >= s.length) { - j = 0; - - var cl = line, cf = from; - if (!nextLine()) { - errorAt("Unclosed string.", cl, cf); - break unclosedString; - } - - if (allowNewLine) { - allowNewLine = false; - } else { - warningAt("Unclosed string.", cl, cf); - } - } - c = s.charAt(j); - if (c === x) { - character += 1; - s = s.substr(j + 1); - return it('(string)', r, x); - } - if (c < ' ') { - if (c === '\n' || c === '\r') { - break; - } - warningAt("Control character in string: {a}.", - line, character + j, s.slice(0, j)); - } else if (c === '\\') { - j += 1; - character += 1; - c = s.charAt(j); - n = s.charAt(j + 1); - switch (c) { - case '\\': - case '"': - case '/': - break; - case '\'': - if (jsonmode) { - warningAt("Avoid \\'.", line, character); - } - break; - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case '0': - c = '\0'; - // Octal literals fail in strict mode - // check if the number is between 00 and 07 - // where 'n' is the token next to 'c' - if (n >= 0 && n <= 7 && directive["use strict"]) { - warningAt( - "Octal literals are not allowed in strict mode.", - line, character); - } - break; - case 'u': - esc(4); - break; - case 'v': - if (jsonmode) { - warningAt("Avoid \\v.", line, character); - } - c = '\v'; - break; - case 'x': - if (jsonmode) { - warningAt("Avoid \\x-.", line, character); - } - esc(2); - break; - case '': - // last character is escape character - // always allow new line if escaped, but show - // warning if option is not set - allowNewLine = true; - if (option.multistr) { - if (jsonmode) { - warningAt("Avoid EOL escapement.", line, character); - } - c = ''; - character -= 1; - break; - } - warningAt("Bad escapement of EOL. Use option multistr if needed.", - line, character); - break; - default: - warningAt("Bad escapement.", line, character); - } - } - r += c; - character += 1; - j += 1; - } - } - - for (;;) { - if (!s) { - return it(nextLine() ? '(endline)' : '(end)', ''); - } - t = match(tx); - if (!t) { - t = ''; - c = ''; - while (s && s < '!') { - s = s.substr(1); - } - if (s) { - errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1)); - s = ''; - } - } else { - - // identifier - - if (c.isAlpha() || c === '_' || c === '$') { - return it('(identifier)', t); - } - - // number - - if (c.isDigit()) { - if (!isFinite(Number(t))) { - warningAt("Bad number '{a}'.", - line, character, t); - } - if (s.substr(0, 1).isAlpha()) { - warningAt("Missing space after '{a}'.", - line, character, t); - } - if (c === '0') { - d = t.substr(1, 1); - if (d.isDigit()) { - if (token.id !== '.') { - warningAt("Don't use extra leading zeros '{a}'.", - line, character, t); - } - } else if (jsonmode && (d === 'x' || d === 'X')) { - warningAt("Avoid 0x-. '{a}'.", - line, character, t); - } - } - if (t.substr(t.length - 1) === '.') { - warningAt( -"A trailing decimal point can be confused with a dot '{a}'.", line, character, t); - } - return it('(number)', t); - } - switch (t) { - - // string - - case '"': - case "'": - return string(t); - - // // comment - - case '//': - s = ''; - token.comment = true; - break; - - // /* comment - - case '/*': - for (;;) { - i = s.search(lx); - if (i >= 0) { - break; - } - if (!nextLine()) { - errorAt("Unclosed comment.", line, character); - } - } - character += i + 2; - if (s.substr(i, 1) === '/') { - errorAt("Nested comment.", line, character); - } - s = s.substr(i + 2); - token.comment = true; - break; - - // /*members /*jshint /*global - - case '/*members': - case '/*member': - case '/*jshint': - case '/*jslint': - case '/*global': - case '*/': - return { - value: t, - type: 'special', - line: line, - character: character, - from: from - }; - - case '': - break; - // / - case '/': - if (token.id === '/=') { - errorAt("A regular expression literal can be confused with '/='.", - line, from); - } - if (prereg) { - depth = 0; - captures = 0; - l = 0; - for (;;) { - b = true; - c = s.charAt(l); - l += 1; - switch (c) { - case '': - errorAt("Unclosed regular expression.", line, from); - return quit('Stopping.', line, from); - case '/': - if (depth > 0) { - warningAt("{a} unterminated regular expression " + - "group(s).", line, from + l, depth); - } - c = s.substr(0, l - 1); - q = { - g: true, - i: true, - m: true - }; - while (q[s.charAt(l)] === true) { - q[s.charAt(l)] = false; - l += 1; - } - character += l; - s = s.substr(l); - q = s.charAt(0); - if (q === '/' || q === '*') { - errorAt("Confusing regular expression.", - line, from); - } - return it('(regexp)', c); - case '\\': - c = s.charAt(l); - if (c < ' ') { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === '<') { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - break; - case '(': - depth += 1; - b = false; - if (s.charAt(l) === '?') { - l += 1; - switch (s.charAt(l)) { - case ':': - case '=': - case '!': - l += 1; - break; - default: - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l)); - } - } else { - captures += 1; - } - break; - case '|': - b = false; - break; - case ')': - if (depth === 0) { - warningAt("Unescaped '{a}'.", - line, from + l, ')'); - } else { - depth -= 1; - } - break; - case ' ': - q = 1; - while (s.charAt(l) === ' ') { - l += 1; - q += 1; - } - if (q > 1) { - warningAt( -"Spaces are hard to count. Use {{a}}.", line, from + l, q); - } - break; - case '[': - c = s.charAt(l); - if (c === '^') { - l += 1; - if (option.regexp) { - warningAt("Insecure '{a}'.", - line, from + l, c); - } else if (s.charAt(l) === ']') { - errorAt("Unescaped '{a}'.", - line, from + l, '^'); - } - } - if (c === ']') { - warningAt("Empty class.", line, - from + l - 1); - } - isLiteral = false; - isInRange = false; -klass: do { - c = s.charAt(l); - l += 1; - switch (c) { - case '[': - case '^': - warningAt("Unescaped '{a}'.", - line, from + l, c); - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case '-': - if (isLiteral && !isInRange) { - isLiteral = false; - isInRange = true; - } else if (isInRange) { - isInRange = false; - } else if (s.charAt(l) === ']') { - isInRange = true; - } else { - if (option.regexdash !== (l === 2 || (l === 3 && - s.charAt(1) === '^'))) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, '-'); - } - isLiteral = true; - } - break; - case ']': - if (isInRange && !option.regexdash) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, '-'); - } - break klass; - case '\\': - c = s.charAt(l); - if (c < ' ') { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === '<') { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - - // \w, \s and \d are never part of a character range - if (/[wsd]/i.test(c)) { - if (isInRange) { - warningAt("Unescaped '{a}'.", - line, from + l, '-'); - isInRange = false; - } - isLiteral = false; - } else if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case '/': - warningAt("Unescaped '{a}'.", - line, from + l - 1, '/'); - - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case '<': - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - default: - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - } - } while (c); - break; - case '.': - if (option.regexp) { - warningAt("Insecure '{a}'.", line, - from + l, c); - } - break; - case ']': - case '?': - case '{': - case '}': - case '+': - case '*': - warningAt("Unescaped '{a}'.", line, - from + l, c); - } - if (b) { - switch (s.charAt(l)) { - case '?': - case '+': - case '*': - l += 1; - if (s.charAt(l) === '?') { - l += 1; - } - break; - case '{': - l += 1; - c = s.charAt(l); - if (c < '0' || c > '9') { - warningAt( -"Expected a number and instead saw '{a}'.", line, from + l, c); - } - l += 1; - low = +c; - for (;;) { - c = s.charAt(l); - if (c < '0' || c > '9') { - break; - } - l += 1; - low = +c + (low * 10); - } - high = low; - if (c === ',') { - l += 1; - high = Infinity; - c = s.charAt(l); - if (c >= '0' && c <= '9') { - l += 1; - high = +c; - for (;;) { - c = s.charAt(l); - if (c < '0' || c > '9') { - break; - } - l += 1; - high = +c + (high * 10); - } - } - } - if (s.charAt(l) !== '}') { - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c); - } else { - l += 1; - } - if (s.charAt(l) === '?') { - l += 1; - } - if (low > high) { - warningAt( -"'{a}' should not be greater than '{b}'.", line, from + l, low, high); - } - } - } - } - c = s.substr(0, l - 1); - character += l; - s = s.substr(l); - return it('(regexp)', c); - } - return it('(punctuator)', t); - - // punctuator - - case '#': - return it('(punctuator)', t); - default: - return it('(punctuator)', t); - } - } - } - } - }; - }()); - - - function addlabel(t, type) { - - if (t === 'hasOwnProperty') { - warning("'hasOwnProperty' is a really bad name."); - } - -// Define t in the current function in the current scope. - if (is_own(funct, t) && !funct['(global)']) { - if (funct[t] === true) { - if (option.latedef) - warning("'{a}' was used before it was defined.", nexttoken, t); - } else { - if (!option.shadow && type !== "exception") - warning("'{a}' is already defined.", nexttoken, t); - } - } - - funct[t] = type; - if (funct['(global)']) { - global[t] = funct; - if (is_own(implied, t)) { - if (option.latedef) - warning("'{a}' was used before it was defined.", nexttoken, t); - delete implied[t]; - } - } else { - scope[t] = funct; - } - } - - - function doOption() { - var b, obj, filter, o = nexttoken.value, t, tn, v; - - switch (o) { - case '*/': - error("Unbegun comment."); - break; - case '/*members': - case '/*member': - o = '/*members'; - if (!membersOnly) { - membersOnly = {}; - } - obj = membersOnly; - break; - case '/*jshint': - case '/*jslint': - obj = option; - filter = boolOptions; - break; - case '/*global': - obj = predefined; - break; - default: - error("What?"); - } - - t = lex.token(); -loop: for (;;) { - for (;;) { - if (t.type === 'special' && t.value === '*/') { - break loop; - } - if (t.id !== '(endline)' && t.id !== ',') { - break; - } - t = lex.token(); - } - if (t.type !== '(string)' && t.type !== '(identifier)' && - o !== '/*members') { - error("Bad option.", t); - } - - v = lex.token(); - if (v.id === ':') { - v = lex.token(); - - if (obj === membersOnly) { - error("Expected '{a}' and instead saw '{b}'.", - t, '*/', ':'); - } - - if (o === '/*jshint') { - checkOption(t.value, t); - } - - if (t.value === 'indent' && (o === '/*jshint' || o === '/*jslint')) { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.white = true; - obj.indent = b; - } else if (t.value === 'maxerr' && (o === '/*jshint' || o === '/*jslint')) { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxerr = b; - } else if (t.value === 'maxlen' && (o === '/*jshint' || o === '/*jslint')) { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxlen = b; - } else if (t.value === 'validthis') { - if (funct['(global)']) { - error("Option 'validthis' can't be used in a global scope."); - } else { - if (v.value === 'true' || v.value === 'false') - obj[t.value] = v.value === 'true'; - else - error("Bad option value.", v); - } - } else if (v.value === 'true' || v.value === 'false') { - if (o === '/*jslint') { - tn = renamedOptions[t.value] || t.value; - obj[tn] = v.value === 'true'; - if (invertedOptions[tn] !== undefined) { - obj[tn] = !obj[tn]; - } - } else { - obj[t.value] = v.value === 'true'; - } - } else { - error("Bad option value.", v); - } - t = lex.token(); - } else { - if (o === '/*jshint' || o === '/*jslint') { - error("Missing option value.", t); - } - obj[t.value] = false; - t = v; - } - } - if (filter) { - assume(); - } - } - - -// We need a peek function. If it has an argument, it peeks that much farther -// ahead. It is used to distinguish -// for ( var i in ... -// from -// for ( var i = ... - - function peek(p) { - var i = p || 0, j = 0, t; - - while (j <= i) { - t = lookahead[j]; - if (!t) { - t = lookahead[j] = lex.token(); - } - j += 1; - } - return t; - } - - - -// Produce the next token. It looks for programming errors. - - function advance(id, t) { - switch (token.id) { - case '(number)': - if (nexttoken.id === '.') { - warning("A dot following a number can be confused with a decimal point.", token); - } - break; - case '-': - if (nexttoken.id === '-' || nexttoken.id === '--') { - warning("Confusing minusses."); - } - break; - case '+': - if (nexttoken.id === '+' || nexttoken.id === '++') { - warning("Confusing plusses."); - } - break; - } - - if (token.type === '(string)' || token.identifier) { - anonname = token.value; - } - - if (id && nexttoken.id !== id) { - if (t) { - if (nexttoken.id === '(end)') { - warning("Unmatched '{a}'.", t, t.id); - } else { - warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - nexttoken, id, t.id, t.line, nexttoken.value); - } - } else if (nexttoken.type !== '(identifier)' || - nexttoken.value !== id) { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, id, nexttoken.value); - } - } - - prevtoken = token; - token = nexttoken; - for (;;) { - nexttoken = lookahead.shift() || lex.token(); - if (nexttoken.id === '(end)' || nexttoken.id === '(error)') { - return; - } - if (nexttoken.type === 'special') { - doOption(); - } else { - if (nexttoken.id !== '(endline)') { - break; - } - } - } - } - - -// This is the heart of JSHINT, the Pratt parser. In addition to parsing, it -// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is -// like .nud except that it is only used on the first token of a statement. -// Having .fud makes it much easier to define statement-oriented languages like -// JavaScript. I retained Pratt's nomenclature. - -// .nud Null denotation -// .fud First null denotation -// .led Left denotation -// lbp Left binding power -// rbp Right binding power - -// They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - var left, isArray = false, isObject = false; - - if (nexttoken.id === '(end)') - error("Unexpected early end of program.", token); - - advance(); - if (initial) { - anonname = 'anonymous'; - funct['(verb)'] = token.value; - } - if (initial === true && token.fud) { - left = token.fud(); - } else { - if (token.nud) { - left = token.nud(); - } else { - if (nexttoken.type === '(number)' && token.id === '.') { - warning("A leading decimal point can be confused with a dot: '.{a}'.", - token, nexttoken.value); - advance(); - return token; - } else { - error("Expected an identifier and instead saw '{a}'.", - token, token.id); - } - } - while (rbp < nexttoken.lbp) { - isArray = token.value === 'Array'; - isObject = token.value === 'Object'; - - // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object() - // Line breaks in IfStatement heads exist to satisfy the checkJSHint - // "Line too long." error. - if (left && (left.value || (left.first && left.first.value))) { - // If the left.value is not "new", or the left.first.value is a "." - // then safely assume that this is not "new Array()" and possibly - // not "new Object()"... - if (left.value !== 'new' || - (left.first && left.first.value && left.first.value === '.')) { - isArray = false; - // ...In the case of Object, if the left.value and token.value - // are not equal, then safely assume that this not "new Object()" - if (left.value !== token.value) { - isObject = false; - } - } - } - - advance(); - if (isArray && token.id === '(' && nexttoken.id === ')') - warning("Use the array literal notation [].", token); - if (isObject && token.id === '(' && nexttoken.id === ')') - warning("Use the object literal notation {}.", token); - if (token.led) { - left = token.led(left); - } else { - error("Expected an operator and instead saw '{a}'.", - token, token.id); - } - } - } - return left; - } - - -// Functions for conformance of style. - - function adjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white) { - if (left.character !== right.from && left.line === right.line) { - left.from += (left.character - left.from); - warning("Unexpected space after '{a}'.", left, left.value); - } - } - } - - function nobreak(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && (left.character !== right.from || left.line !== right.line)) { - warning("Unexpected space before '{a}'.", right, right.value); - } - } - - function nospace(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && !left.comment) { - if (left.line === right.line) { - adjacent(left, right); - } - } - } - - function nonadjacent(left, right) { - if (option.white) { - left = left || token; - right = right || nexttoken; - if (left.line === right.line && left.character === right.from) { - left.from += (left.character - left.from); - warning("Missing space after '{a}'.", - left, left.value); - } - } - } - - function nobreaknonadjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (!option.laxbreak && left.line !== right.line) { - warning("Bad line breaking before '{a}'.", right, right.id); - } else if (option.white) { - left = left || token; - right = right || nexttoken; - if (left.character === right.from) { - left.from += (left.character - left.from); - warning("Missing space after '{a}'.", - left, left.value); - } - } - } - - function indentation(bias) { - var i; - if (option.white && nexttoken.id !== '(end)') { - i = indent + (bias || 0); - if (nexttoken.from !== i) { - warning( -"Expected '{a}' to have an indentation at {b} instead at {c}.", - nexttoken, nexttoken.value, i, nexttoken.from); - } - } - } - - function nolinebreak(t) { - t = t || token; - if (t.line !== nexttoken.line) { - warning("Line breaking error '{a}'.", t, t.value); - } - } - - - function comma() { - if (token.line !== nexttoken.line) { - if (!option.laxcomma) { - if (comma.first) { - warning("Comma warnings can be turned off with 'laxcomma'"); - comma.first = false; - } - warning("Bad line breaking before '{a}'.", token, nexttoken.id); - } - } else if (!token.comment && token.character !== nexttoken.from && option.white) { - token.from += (token.character - token.from); - warning("Unexpected space after '{a}'.", token, token.value); - } - advance(','); - nonadjacent(token, nexttoken); - } - - -// Functional constructors for making the symbols that will be inherited by -// tokens. - - function symbol(s, p) { - var x = syntax[s]; - if (!x || typeof x !== 'object') { - syntax[s] = x = { - id: s, - lbp: p, - value: s - }; - } - return x; - } - - - function delim(s) { - return symbol(s, 0); - } - - - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - - function blockstmt(s, f) { - var x = stmt(s, f); - x.block = true; - return x; - } - - - function reserveName(x) { - var c = x.id.charAt(0); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - x.identifier = x.reserved = true; - } - return x; - } - - - function prefix(s, f) { - var x = symbol(s, 150); - reserveName(x); - x.nud = (typeof f === 'function') ? f : function () { - this.right = expression(150); - this.arity = 'unary'; - if (this.id === '++' || this.id === '--') { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!this.right.identifier || this.right.reserved) && - this.right.id !== '.' && this.right.id !== '[') { - warning("Bad operand.", this); - } - } - return this; - }; - return x; - } - - - function type(s, f) { - var x = delim(s); - x.type = s; - x.nud = f; - return x; - } - - - function reserve(s, f) { - var x = type(s, f); - x.identifier = x.reserved = true; - return x; - } - - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === 'function') { - v(this); - } - return this; - }); - } - - - function infix(s, f, p, w) { - var x = symbol(s, p); - reserveName(x); - x.led = function (left) { - if (!w) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - } - if (s === "in" && left.id === "!") { - warning("Confusing use of '{a}'.", left, '!'); - } - if (typeof f === 'function') { - return f(left, this); - } else { - this.left = left; - this.right = expression(p); - return this; - } - }; - return x; - } - - - function relation(s, f) { - var x = symbol(s, 100); - x.led = function (left) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - var right = expression(100); - if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) { - warning("Use the isNaN function to compare with NaN.", this); - } else if (f) { - f.apply(this, [left, right]); - } - if (left.id === '!') { - warning("Confusing use of '{a}'.", left, '!'); - } - if (right.id === '!') { - warning("Confusing use of '{a}'.", right, '!'); - } - this.left = left; - this.right = right; - return this; - }; - return x; - } - - - function isPoorRelation(node) { - return node && - ((node.type === '(number)' && +node.value === 0) || - (node.type === '(string)' && node.value === '') || - (node.type === 'null' && !option.eqnull) || - node.type === 'true' || - node.type === 'false' || - node.type === 'undefined'); - } - - - function assignop(s, f) { - symbol(s, 20).exps = true; - return infix(s, function (left, that) { - var l; - that.left = left; - if (predefined[left.value] === false && - scope[left.value]['(global)'] === true) { - warning("Read only.", left); - } else if (left['function']) { - warning("'{a}' is a function.", left, left.value); - } - if (left) { - if (option.esnext && funct[left.value] === 'const') { - warning("Attempting to override '{a}' which is a constant", left, left.value); - } - if (left.id === '.' || left.id === '[') { - if (!left.left || left.left.value === 'arguments') { - warning('Bad assignment.', that); - } - that.right = expression(19); - return that; - } else if (left.identifier && !left.reserved) { - if (funct[left.value] === 'exception') { - warning("Do not assign to the exception parameter.", left); - } - that.right = expression(19); - return that; - } - if (left === syntax['function']) { - warning( -"Expected an identifier in an assignment and instead saw a function invocation.", - token); - } - } - error("Bad assignment.", that); - }, 20); - } - - - function bitwise(s, f, p) { - var x = symbol(s, p); - reserveName(x); - x.led = (typeof f === 'function') ? f : function (left) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", this, this.id); - } - this.left = left; - this.right = expression(p); - return this; - }; - return x; - } - - - function bitwiseassignop(s) { - symbol(s, 20).exps = true; - return infix(s, function (left, that) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", that, that.id); - } - nonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - if (left) { - if (left.id === '.' || left.id === '[' || - (left.identifier && !left.reserved)) { - expression(19); - return that; - } - if (left === syntax['function']) { - warning( -"Expected an identifier in an assignment, and instead saw a function invocation.", - token); - } - return that; - } - error("Bad assignment.", that); - }, 20); - } - - - function suffix(s, f) { - var x = symbol(s, 150); - x.led = function (left) { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!left.identifier || left.reserved) && - left.id !== '.' && left.id !== '[') { - warning("Bad operand.", this); - } - this.left = left; - return this; - }; - return x; - } - - - // fnparam means that this identifier is being defined as a function - // argument (see identifier()) - function optionalidentifier(fnparam) { - if (nexttoken.identifier) { - advance(); - if (token.reserved && !option.es5) { - // `undefined` as a function param is a common pattern to protect - // against the case when somebody does `undefined = true` and - // help with minification. More info: https://gist.github.com/315916 - if (!fnparam || token.value !== 'undefined') { - warning("Expected an identifier and instead saw '{a}' (a reserved word).", - token, token.id); - } - } - return token.value; - } - } - - // fnparam means that this identifier is being defined as a function - // argument - function identifier(fnparam) { - var i = optionalidentifier(fnparam); - if (i) { - return i; - } - if (token.id === 'function' && nexttoken.id === '(') { - warning("Missing name in function declaration."); - } else { - error("Expected an identifier and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - } - - - function reachable(s) { - var i = 0, t; - if (nexttoken.id !== ';' || noreach) { - return; - } - for (;;) { - t = peek(i); - if (t.reach) { - return; - } - if (t.id !== '(endline)') { - if (t.id === 'function') { - if (!option.latedef) { - break; - } - warning( -"Inner functions should be listed at the top of the outer function.", t); - break; - } - warning("Unreachable '{a}' after '{b}'.", t, t.value, s); - break; - } - i += 1; - } - } - - - function statement(noindent) { - var i = indent, r, s = scope, t = nexttoken; - - if (t.id === ";") { - advance(";"); - return; - } - -// Is this a labelled statement? - - if (t.identifier && !t.reserved && peek().id === ':') { - advance(); - advance(':'); - scope = Object.create(s); - addlabel(t.value, 'label'); - if (!nexttoken.labelled) { - warning("Label '{a}' on {b} statement.", - nexttoken, t.value, nexttoken.value); - } - if (jx.test(t.value + ':')) { - warning("Label '{a}' looks like a javascript url.", - t, t.value); - } - nexttoken.label = t.value; - t = nexttoken; - } - -// Parse the statement. - - if (!noindent) { - indentation(); - } - r = expression(0, true); - - // Look for the final semicolon. - if (!t.block) { - if (!option.expr && (!r || !r.exps)) { - warning("Expected an assignment or function call and instead saw an expression.", - token); - } else if (option.nonew && r.id === '(' && r.left.id === 'new') { - warning("Do not use 'new' for side effects."); - } - - if (nexttoken.id === ',') { - return comma(); - } - - if (nexttoken.id !== ';') { - if (!option.asi) { - // If this is the last statement in a block that ends on - // the same line *and* option lastsemic is on, ignore the warning. - // Otherwise, complain about missing semicolon. - if (!option.lastsemic || nexttoken.id !== '}' || - nexttoken.line !== token.line) { - warningAt("Missing semicolon.", token.line, token.character); - } - } - } else { - adjacent(token, nexttoken); - advance(';'); - nonadjacent(token, nexttoken); - } - } - -// Restore the indentation. - - indent = i; - scope = s; - return r; - } - - - function statements(startLine) { - var a = [], f, p; - - while (!nexttoken.reach && nexttoken.id !== '(end)') { - if (nexttoken.id === ';') { - p = peek(); - if (!p || p.id !== "(") { - warning("Unnecessary semicolon."); - } - advance(';'); - } else { - a.push(statement(startLine === nexttoken.line)); - } - } - return a; - } - - - /* - * read all directives - * recognizes a simple form of asi, but always - * warns, if it is used - */ - function directives() { - var i, p, pn; - - for (;;) { - if (nexttoken.id === "(string)") { - p = peek(0); - if (p.id === "(endline)") { - i = 1; - do { - pn = peek(i); - i = i + 1; - } while (pn.id === "(endline)"); - - if (pn.id !== ";") { - if (pn.id !== "(string)" && pn.id !== "(number)" && - pn.id !== "(regexp)" && pn.identifier !== true && - pn.id !== "}") { - break; - } - warning("Missing semicolon.", nexttoken); - } else { - p = pn; - } - } else if (p.id === "}") { - // directive with no other statements, warn about missing semicolon - warning("Missing semicolon.", p); - } else if (p.id !== ";") { - break; - } - - indentation(); - advance(); - if (directive[token.value]) { - warning("Unnecessary directive \"{a}\".", token, token.value); - } - - if (token.value === "use strict") { - option.newcap = true; - option.undef = true; - } - - // there's no directive negation, so always set to true - directive[token.value] = true; - - if (p.id === ";") { - advance(";"); - } - continue; - } - break; - } - } - - - /* - * Parses a single block. A block is a sequence of statements wrapped in - * braces. - * - * ordinary - true for everything but function bodies and try blocks. - * stmt - true if block can be a single statement (e.g. in if/for/while). - * isfunc - true if block is a function body - */ - function block(ordinary, stmt, isfunc) { - var a, - b = inblock, - old_indent = indent, - m, - s = scope, - t, - line, - d; - - inblock = ordinary; - if (!ordinary || !option.funcscope) scope = Object.create(scope); - nonadjacent(token, nexttoken); - t = nexttoken; - - if (nexttoken.id === '{') { - advance('{'); - line = token.line; - if (nexttoken.id !== '}') { - indent += option.indent; - while (!ordinary && nexttoken.from > indent) { - indent += option.indent; - } - - if (isfunc) { - m = {}; - for (d in directive) { - if (is_own(directive, d)) { - m[d] = directive[d]; - } - } - directives(); - - if (option.strict && funct['(context)']['(global)']) { - if (!m["use strict"] && !directive["use strict"]) { - warning("Missing \"use strict\" statement."); - } - } - } - - a = statements(line); - - if (isfunc) { - directive = m; - } - - indent -= option.indent; - if (line !== nexttoken.line) { - indentation(); - } - } else if (line !== nexttoken.line) { - indentation(); - } - advance('}', t); - indent = old_indent; - } else if (!ordinary) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, '{', nexttoken.value); - } else { - if (!stmt || option.curly) - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, '{', nexttoken.value); - - noreach = true; - indent += option.indent; - // test indentation only if statement is in new line - a = [statement(nexttoken.line === token.line)]; - indent -= option.indent; - noreach = false; - } - funct['(verb)'] = null; - if (!ordinary || !option.funcscope) scope = s; - inblock = b; - if (ordinary && option.noempty && (!a || a.length === 0)) { - warning("Empty block."); - } - return a; - } - - - function countMember(m) { - if (membersOnly && typeof membersOnly[m] !== 'boolean') { - warning("Unexpected /*member '{a}'.", token, m); - } - if (typeof member[m] === 'number') { - member[m] += 1; - } else { - member[m] = 1; - } - } - - - function note_implied(token) { - var name = token.value, line = token.line, a = implied[name]; - if (typeof a === 'function') { - a = false; - } - - if (!a) { - a = [line]; - implied[name] = a; - } else if (a[a.length - 1] !== line) { - a.push(line); - } - } - - - // Build the syntax table by declaring the syntactic elements of the language. - - type('(number)', function () { - return this; - }); - - type('(string)', function () { - return this; - }); - - syntax['(identifier)'] = { - type: '(identifier)', - lbp: 0, - identifier: true, - nud: function () { - var v = this.value, - s = scope[v], - f; - - if (typeof s === 'function') { - // Protection against accidental inheritance. - 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 'unction': - funct[v] = 'function'; - this['function'] = true; - break; - case 'function': - this['function'] = true; - break; - case 'label': - warning("'{a}' is a statement label.", token, v); - break; - } - } else if (funct['(global)']) { - // The name is not defined in the function. If we are in the global - // scope, then we have an undefined variable. - // - // Operators typeof and delete do not raise runtime errors even if - // the base object of a reference is null so no need to display warning - // if we're inside of typeof or delete. - - if (option.undef && typeof predefined[v] !== 'boolean') { - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === 'typeof' || anonname === 'delete') || - (nexttoken && (nexttoken.value === '.' || nexttoken.value === '['))) { - - isundef(funct, "'{a}' is not defined.", token, v); - } - } - note_implied(token); - } else { - // If the name is already defined in the current - // function, but not as outer, then there is a scope error. - - 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') { - // Operators typeof and delete do not raise runtime errors even - // if the base object of a reference is null so no need to - // display warning if we're inside of typeof or delete. - if (option.undef) { - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === 'typeof' || anonname === 'delete') || - (nexttoken && - (nexttoken.value === '.' || nexttoken.value === '['))) { - - isundef(funct, "'{a}' is not defined.", token, v); - } - } - funct[v] = true; - note_implied(token); - } else { - switch (s[v]) { - case 'function': - case 'unction': - this['function'] = true; - s[v] = 'closure'; - funct[v] = s['(global)'] ? 'global' : 'outer'; - break; - 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; - }); - - -// ECMAScript parser - - delim('(endline)'); - delim('(begin)'); - delim('(end)').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', function (x) { - if (directive['use strict'] && funct['(global)']) { - warning("Strict violation.", x); - } - }); - reservevar('eval'); - reservevar('false'); - reservevar('Infinity'); - reservevar('NaN'); - reservevar('null'); - reservevar('this', function (x) { - if (directive['use strict'] && !option.validthis && ((funct['(statement)'] && - funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) { - warning("Possible strict violation.", x); - } - }); - 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 = expression(10); - advance(':'); - that['else'] = expression(10); - return that; - }, 30); - - infix('||', 'or', 40); - infix('&&', 'and', 50); - bitwise('|', 'bitor', 70); - bitwise('^', 'bitxor', 80); - bitwise('&', 'bitand', 90); - relation('==', function (left, right) { - var eqnull = option.eqnull && (left.value === 'null' || right.value === 'null'); - - if (!eqnull && 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) { - var eqnull = option.eqnull && - (left.value === 'null' || right.value === 'null'); - - if (!eqnull && 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 = expression(130); - if (left && right && left.id === '(string)' && right.id === '(string)') { - left.value += right.value; - left.character = right.character; - if (!option.scripturl && jx.test(left.value)) { - warning("JavaScript URL.", left); - } - return left; - } - that.left = left; - that.right = right; - return that; - }, 130); - prefix('+', 'num'); - prefix('+++', function () { - warning("Confusing pluses."); - this.right = expression(150); - this.arity = 'unary'; - return this; - }); - infix('+++', function (left) { - warning("Confusing pluses."); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix('-', 'sub', 130); - prefix('-', 'neg'); - prefix('---', function () { - warning("Confusing minuses."); - this.right = expression(150); - this.arity = 'unary'; - return this; - }); - infix('---', function (left) { - warning("Confusing minuses."); - this.left = left; - this.right = expression(130); - return this; - }, 130); - 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 = expression(0); - if (!p || (p.id !== '.' && p.id !== '[')) { - warning("Variables should not be deleted."); - } - this.first = p; - return this; - }).exps = true; - - prefix('~', function () { - if (option.bitwise) { - warning("Unexpected '{a}'.", this, '~'); - } - expression(150); - return this; - }); - - prefix('!', function () { - this.right = expression(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 = expression(155), i; - if (c && c.id !== 'function') { - if (c.identifier) { - c['new'] = true; - switch (c.value) { - 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 { - if (!option.supernew) - warning("Weird construction. Delete 'new'.", this); - } - adjacent(token, nexttoken); - if (nexttoken.id !== '(' && !option.supernew) { - warning("Missing '()' invoking a constructor."); - } - this.first = c; - return this; - }); - syntax['new'].exps = true; - - prefix('void').exps = true; - - infix('.', function (left, that) { - adjacent(prevtoken, token); - nobreak(); - var m = identifier(); - if (typeof m === 'string') { - countMember(m); - } - that.left = left; - that.right = m; - if (left && left.value === 'arguments' && (m === 'callee' || m === 'caller')) { - if (option.noarg) - warning("Avoid arguments.{a}.", left, m); - else if (directive['use strict']) - error('Strict violation.'); - } else if (!option.evil && left && left.value === 'document' && - (m === 'write' || m === 'writeln')) { - warning("document.write can be a form of eval.", left); - } - if (!option.evil && (m === 'eval' || m === 'execScript')) { - warning('eval is evil.'); - } - return that; - }, 160, true); - - infix('(', function (left, that) { - if (prevtoken.id !== '}' && prevtoken.id !== ')') { - nobreak(prevtoken, token); - } - nospace(); - if (option.immed && !left.immed && left.id === 'function') { - warning("Wrap an immediate function invocation in parentheses " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself."); - } - 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); - } - } - } - } - } - if (nexttoken.id !== ')') { - for (;;) { - p[p.length] = expression(10); - n += 1; - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - advance(')'); - 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(); - if (nexttoken.id === 'function') { - nexttoken.immed = true; - } - var v = expression(0); - advance(')', this); - nospace(prevtoken, token); - if (option.immed && v.id === 'function') { - if (nexttoken.id === '(' || - (nexttoken.id === '.' && (peek().value === 'call' || peek().value === 'apply'))) { - 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) { - nobreak(prevtoken, token); - nospace(); - var e = expression(0), s; - if (e && e.type === '(string)') { - if (!option.evil && (e.value === 'eval' || e.value === 'execScript')) { - warning("eval is evil.", that); - } - 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); - } - } - } - 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(expression(10)); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.id === ']' && !option.es5) { - warning("Extra comma.", token); - break; - } - } else { - break; - } - } - if (b) { - indent -= option.indent; - indentation(); - } - advance(']', this); - return this; - }, 160); - - - function property_name() { - var id = optionalidentifier(true); - if (!id) { - if (nexttoken.id === '(string)') { - id = nexttoken.value; - advance(); - } else if (nexttoken.id === '(number)') { - id = nexttoken.value.toString(); - advance(); - } - } - return id; - } - - - function functionparams() { - var i, t = nexttoken, p = []; - advance('('); - nospace(); - if (nexttoken.id === ')') { - advance(')'); - return; - } - for (;;) { - i = identifier(true); - p.push(i); - addlabel(i, 'parameter'); - if (nexttoken.id === ',') { - comma(); - } else { - advance(')', t); - nospace(prevtoken, token); - return p; - } - } - } - - - function doFunction(i, statement) { - var f, - oldOption = option, - oldScope = scope; - - option = Object.create(option); - scope = Object.create(scope); - - funct = { - '(name)' : i || '"' + anonname + '"', - '(line)' : nexttoken.line, - '(context)' : funct, - '(breakage)' : 0, - '(loopage)' : 0, - '(scope)' : scope, - '(statement)': statement - }; - f = funct; - token.funct = funct; - functions.push(funct); - if (i) { - addlabel(i, 'function'); - } - funct['(params)'] = functionparams(); - - block(false, false, true); - scope = oldScope; - option = oldOption; - funct['(last)'] = token.line; - funct = funct['(context)']; - return f; - } - - - (function (x) { - x.nud = function () { - var b, f, i, j, p, t; - var props = {}; // All properties, including accessors - - function saveProperty(name, token) { - if (props[name] && is_own(props, name)) - warning("Duplicate member '{a}'.", nexttoken, i); - else - props[name] = {}; - - props[name].basic = true; - props[name].basicToken = token; - } - - function saveSetter(name, token) { - if (props[name] && is_own(props, name)) { - if (props[name].basic || props[name].setter) - warning("Duplicate member '{a}'.", nexttoken, i); - } else { - props[name] = {}; - } - - props[name].setter = true; - props[name].setterToken = token; - } - - function saveGetter(name) { - if (props[name] && is_own(props, name)) { - if (props[name].basic || props[name].getter) - warning("Duplicate member '{a}'.", nexttoken, i); - } else { - props[name] = {}; - } - - props[name].getter = true; - props[name].getterToken = token; - } - - 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(); - } - if (nexttoken.value === 'get' && peek().id !== ':') { - advance('get'); - if (!option.es5) { - error("get/set are ES5 features."); - } - i = property_name(); - if (!i) { - error("Missing property name."); - } - saveGetter(i); - t = nexttoken; - adjacent(token, nexttoken); - f = doFunction(); - p = f['(params)']; - if (p) { - warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i); - } - adjacent(token, nexttoken); - } else if (nexttoken.value === 'set' && peek().id !== ':') { - advance('set'); - if (!option.es5) { - error("get/set are ES5 features."); - } - i = property_name(); - if (!i) { - error("Missing property name."); - } - saveSetter(i, nexttoken); - t = nexttoken; - adjacent(token, nexttoken); - f = doFunction(); - p = f['(params)']; - if (!p || p.length !== 1) { - warning("Expected a single parameter in set {a} function.", t, i); - } - } else { - i = property_name(); - saveProperty(i, nexttoken); - if (typeof i !== 'string') { - break; - } - advance(':'); - nonadjacent(token, nexttoken); - expression(10); - } - - countMember(i); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.id === ',') { - warning("Extra comma.", token); - } else if (nexttoken.id === '}' && !option.es5) { - warning("Extra comma.", token); - } - } else { - break; - } - } - if (b) { - indent -= option.indent; - indentation(); - } - advance('}', this); - - // Check for lonely setters if in the ES5 mode. - if (option.es5) { - for (var name in props) { - if (is_own(props, name) && props[name].setter && !props[name].getter) { - warning("Setter is defined without getter.", props[name].setterToken); - } - } - } - return this; - }; - x.fud = function () { - error("Expected to see a statement and instead saw a block.", token); - }; - }(delim('{'))); - -// This Function is called when esnext option is set to true -// it adds the `const` statement to JSHINT - - useESNextSyntax = function () { - var conststatement = stmt('const', function (prefix) { - var id, name, value; - - this.first = []; - for (;;) { - nonadjacent(token, nexttoken); - id = identifier(); - if (funct[id] === "const") { - warning("const '" + id + "' has already been declared"); - } - if (funct['(global)'] && predefined[id] === false) { - warning("Redefinition of '{a}'.", token, id); - } - addlabel(id, 'const'); - if (prefix) { - break; - } - name = token; - this.first.push(token); - - if (nexttoken.id !== "=") { - warning("const " + - "'{a}' is initialized to 'undefined'.", token, id); - } - - 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("Constant {a} was not declared correctly.", - nexttoken, nexttoken.value); - } - value = expression(0); - name.first = value; - } - - if (nexttoken.id !== ',') { - break; - } - comma(); - } - return this; - }); - conststatement.exps = true; - }; - - var varstatement = stmt('var', function (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 (option.esnext && funct[id] === "const") { - warning("const '" + id + "' has already been declared"); - } - 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 = expression(0); - name.first = value; - } - if (nexttoken.id !== ',') { - break; - } - comma(); - } - return this; - }); - varstatement.exps = true; - - blockstmt('function', function () { - if (inblock) { - warning("Function declarations should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", token); - - } - var i = identifier(); - if (option.esnext && funct[i] === "const") { - warning("const '" + i + "' has already been declared"); - } - adjacent(token, nexttoken); - addlabel(i, 'unction'); - doFunction(i, true); - if (nexttoken.id === '(' && nexttoken.line === token.line) { - error( -"Function declarations 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 (!option.loopfunc && funct['(loopage)']) { - warning("Don't make functions within a loop."); - } - return this; - }); - - blockstmt('if', function () { - var t = nexttoken; - advance('('); - nonadjacent(this, t); - nospace(); - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - advance(')', t); - nospace(prevtoken, token); - block(true, true); - if (nexttoken.id === 'else') { - nonadjacent(token, nexttoken); - advance('else'); - if (nexttoken.id === 'if' || nexttoken.id === 'switch') { - statement(true); - } else { - block(true, true); - } - } - return this; - }); - - blockstmt('try', function () { - var b, e, s; - - 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(); - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - advance(')', t); - nospace(prevtoken, token); - block(true, true); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }).labelled = true; - - blockstmt('with', function () { - var t = nexttoken; - if (directive['use strict']) { - error("'with' is not allowed in strict mode.", token); - } else if (!option.withstmt) { - warning("Don't use 'with'.", token); - } - - advance('('); - nonadjacent(this, t); - nospace(); - expression(0); - advance(')', t); - nospace(prevtoken, token); - block(true, true); - - return this; - }); - - blockstmt('switch', function () { - var t = nexttoken, - g = false; - funct['(breakage)'] += 1; - advance('('); - nonadjacent(this, t); - nospace(); - this.condition = expression(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: - // You can tell JSHint that you don't use break intentionally by - // adding a comment /* falls through */ on a line just before - // the next `case`. - if (!ft.test(lines[nexttoken.line - 2])) { - warning( - "Expected a 'break' statement before 'case'.", - token); - } - } - indentation(-option.indent); - advance('case'); - this.cases.push(expression(20)); - g = true; - advance(':'); - funct['(verb)'] = 'case'; - break; - case 'default': - switch (funct['(verb)']) { - case 'break': - case 'continue': - case 'return': - case 'throw': - break; - default: - if (!ft.test(lines[nexttoken.line - 2])) { - 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') { - if (!option.onecase) - 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 ':': - g = false; - statements(); - break; - default: - error("Missing ':' on a case clause.", token); - return; - } - } else { - if (token.id === ':') { - advance(':'); - error("Unexpected '{a}'.", token, ':'); - statements(); - } else { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, 'case', nexttoken.value); - return; - } - } - } - } - }).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(); - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - advance(')', t); - nospace(prevtoken, token); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - x.labelled = true; - x.exps = true; - }()); - - blockstmt('for', function () { - var 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.fud.call(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'); - expression(20); - advance(')', t); - s = block(true, true); - if (option.forin && s && (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.fud.call(varstatement); - } else { - for (;;) { - expression(0, 'for'); - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - } - nolinebreak(token); - advance(';'); - if (nexttoken.id !== ';') { - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - } - nolinebreak(token); - advance(';'); - if (nexttoken.id === ';') { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, ')', ';'); - } - if (nexttoken.id !== ')') { - for (;;) { - expression(0, 'for'); - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - advance(')', t); - nospace(prevtoken, token); - block(true, 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); - - if (!option.asi) - 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); - - if (!option.asi) - 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 () { - if (this.line === nexttoken.line) { - if (nexttoken.id === '(regexp)') - warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator."); - - if (nexttoken.id !== ';' && !nexttoken.reach) { - nonadjacent(token, nexttoken); - if (peek().value === "=" && !option.boss) { - warningAt("Did you mean to return a conditional instead of an assignment?", - token.line, token.character + 1); - } - this.first = expression(0); - } - } else if (!option.asi) { - nolinebreak(this); // always warn (Line breaking error) - } - reachable('return'); - return this; - }).exps = true; - - - stmt('throw', function () { - nolinebreak(this); - nonadjacent(token, nexttoken); - this.first = expression(20); - reachable('throw'); - return this; - }).exps = true; - -// 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'); - - -// Parse JSON - - 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__' && - !option.proto) || (nexttoken.value === '__iterator__' && - !option.iterator)) { - warning("The '{a}' key may produce unexpected results.", - 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 JSHINT function itself. - - var itself = function (s, o, g) { - var a, i, k, x, - optionKeys, - newOptionObj = {}; - - JSHINT.errors = []; - JSHINT.undefs = []; - predefined = Object.create(standard); - combine(predefined, g || {}); - if (o) { - a = o.predef; - if (a) { - if (Array.isArray(a)) { - for (i = 0; i < a.length; i += 1) { - predefined[a[i]] = true; - } - } else if (typeof a === 'object') { - k = Object.keys(a); - for (i = 0; i < k.length; i += 1) { - predefined[k[i]] = !!a[k[i]]; - } - } - } - optionKeys = Object.keys(o); - for (x = 0; x < optionKeys.length; x++) { - newOptionObj[optionKeys[x]] = o[optionKeys[x]]; - } - } - - option = newOptionObj; - - option.indent = option.indent || 4; - option.maxerr = option.maxerr || 50; - - 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]; - urls = []; - stack = null; - member = {}; - membersOnly = null; - implied = {}; - inblock = false; - lookahead = []; - jsonmode = false; - warnings = 0; - lex.init(s); - prereg = true; - directive = {}; - - prevtoken = token = nexttoken = syntax['(begin)']; - - // Check options - for (var name in o) { - if (is_own(o, name)) { - checkOption(name, token); - } - } - - assume(); - - // combine the passed globals after we've assumed all our options - combine(predefined, g || {}); - - //reset values - comma.first = true; - - try { - advance(); - switch (nexttoken.id) { - case '{': - case '[': - option.laxbreak = true; - jsonmode = true; - jsonValue(); - break; - default: - directives(); - if (directive["use strict"] && !option.globalstrict) { - warning("Use the function form of \"use strict\".", prevtoken); - } - - statements(); - } - advance('(end)'); - - var markDefined = function (name, context) { - do { - if (typeof context[name] === 'string') { - // JSHINT marks unused variables as 'unused' and - // unused function declaration as 'unction'. This - // code changes such instances back 'var' and - // 'closure' so that the code in JSHINT.data() - // doesn't think they're unused. - - if (context[name] === 'unused') - context[name] = 'var'; - else if (context[name] === 'unction') - context[name] = 'closure'; - - return true; - } - - context = context['(context)']; - } while (context); - - return false; - }; - - var clearImplied = function (name, line) { - if (!implied[name]) - return; - - var newImplied = []; - for (var i = 0; i < implied[name].length; i += 1) { - if (implied[name][i] !== line) - newImplied.push(implied[name][i]); - } - - if (newImplied.length === 0) - delete implied[name]; - else - implied[name] = newImplied; - }; - - // Check queued 'x is not defined' instances to see if they're still undefined. - for (i = 0; i < JSHINT.undefs.length; i += 1) { - k = JSHINT.undefs[i].slice(0); - - if (markDefined(k[2].value, k[0])) { - clearImplied(k[2].value, k[2].line); - } else { - warning.apply(warning, k.slice(1)); - } - } - } catch (e) { - if (e) { - var nt = nexttoken || {}; - JSHINT.errors.push({ - raw : e.raw, - reason : e.message, - line : e.line || nt.line, - character : e.character || nt.from - }, null); - } - } - - return JSHINT.errors.length === 0; - }; - - // Data summary. - itself.data = function () { - - var data = { functions: [], options: option }, 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 = Object.keys(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 (v === 'unction') { - v = 'unused'; - } - if (Array.isArray(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 (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 = Object.keys(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.jshint = itself; - - return itself; -}()); - -// Make JSHINT a Node module, if possible. -if (typeof exports === 'object' && exports) - exports.JSHINT = JSHINT; diff --git a/js/js.translator/testData/jslint.js b/js/js.translator/testData/jslint.js deleted file mode 100644 index db95cfc73bf..00000000000 --- a/js/js.translator/testData/jslint.js +++ /dev/null @@ -1,6400 +0,0 @@ -// jslint.js -// 2012-05-09 - -// Copyright (c) 2002 Douglas Crockford (www.JSLint.com) - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// The Software shall be used for Good, not Evil. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// WARNING: JSLint will hurt your feelings. - -// JSLINT is a global function. It takes two parameters. - -// var myResult = JSLINT(source, option); - -// The first parameter is either a string or an array of strings. If it is a -// string, it will be split on '\n' or '\r'. If it is an array of strings, it -// is assumed that each string represents one line. The source can be a -// JavaScript text, or HTML text, or a JSON text, or a CSS text. - -// The second parameter is an optional object of options that control the -// operation of JSLINT. Most of the options are booleans: They are all -// optional and have a default value of false. One of the options, predef, -// can be an array of names, which will be used to declare global variables, -// or an object whose keys are used as global names, with a boolean value -// that determines if they are assignable. - -// If it checks out, JSLINT returns true. Otherwise, it returns false. - -// If false, you can inspect JSLINT.errors to find out the problems. -// JSLINT.errors is an array of objects containing these properties: - -// { -// line : The line (relative to 0) at which the lint was found -// character : The character (relative to 0) at which the lint was found -// reason : The problem -// evidence : The text line in which the problem occurred -// raw : The raw message before the details were inserted -// a : The first detail -// b : The second detail -// c : The third detail -// d : The fourth detail -// } - -// If a stopping error was found, a null will be the last element of the -// JSLINT.errors array. A stopping error means that JSLint was not confident -// enough to continue. It does not necessarily mean that the error was -// especially heinous. - -// You can request a data structure that contains JSLint's results. - -// var myData = JSLINT.data(); - -// It returns a structure with this form: - -// { -// errors: [ -// { -// line: NUMBER, -// character: NUMBER, -// reason: STRING, -// evidence: STRING -// } -// ], -// functions: [ -// { -// name: STRING, -// line: NUMBER, -// last: NUMBER, -// params: [ -// { -// string: STRING -// } -// ], -// closure: [ -// STRING -// ], -// var: [ -// STRING -// ], -// exception: [ -// STRING -// ], -// outer: [ -// STRING -// ], -// unused: [ -// STRING -// ], -// undef: [ -// STRING -// ], -// global: [ -// STRING -// ], -// label: [ -// STRING -// ] -// } -// ], -// globals: [ -// STRING -// ], -// member: { -// STRING: NUMBER -// }, -// urls: [ -// STRING -// ], -// json: BOOLEAN -// } - -// Empty arrays will not be included. - -// You can request a Function Report, which shows all of the functions -// and the parameters and vars that they use. This can be used to find -// implied global variables and other problems. The report is in HTML and -// can be inserted in an HTML . It should be given the result of the -// JSLINT.data function. - -// var myReport = JSLINT.report(data); - -// You can request an HTML error report. - -// var myErrorReport = JSLINT.error_report(data); - -// You can request a properties report, which produces a list of the program's -// properties in the form of a /*properties*/ declaration. - -// var myPropertyReport = properties_report(JSLINT.property); - -// You can obtain the parse tree that JSLint constructed while parsing. The -// latest tree is kept in JSLINT.tree. A nice stringication can be produced -// with - -// JSON.stringify(JSLINT.tree, [ -// 'string', 'arity', 'name', 'first', -// 'second', 'third', 'block', 'else' -// ], 4)); - -// JSLint provides three directives. They look like slashstar comments, and -// allow for setting options, declaring global variables, and establishing a -// set of allowed property names. - -// These directives respect function scope. - -// The jslint directive is a special comment that can set one or more options. -// The current option set is - -// anon true, if the space may be omitted in anonymous function declarations -// bitwise true, if bitwise operators should be allowed -// browser true, if the standard browser globals should be predefined -// cap true, if upper case HTML should be allowed -// 'continue' true, if the continuation statement should be tolerated -// css true, if CSS workarounds should be tolerated -// debug true, if debugger statements should be allowed -// devel true, if logging should be allowed (console, alert, etc.) -// eqeq true, if == should be allowed -// es5 true, if ES5 syntax should be allowed -// evil true, if eval should be allowed -// forin true, if for in statements need not filter -// fragment true, if HTML fragments should be allowed -// indent the indentation factor -// maxerr the maximum number of errors to allow -// maxlen the maximum length of a source line -// newcap true, if constructor names capitalization is ignored -// node true, if Node.js globals should be predefined -// nomen true, if names may have dangling _ -// on true, if HTML event handlers should be allowed -// passfail true, if the scan should stop on first error -// plusplus true, if increment/decrement should be allowed -// properties true, if all property names must be declared with /*properties*/ -// regexp true, if the . should be allowed in regexp literals -// rhino true, if the Rhino environment globals should be predefined -// undef true, if variables can be declared out of order -// unparam true, if unused parameters should be tolerated -// sloppy true, if the 'use strict'; pragma is optional -// stupid true, if really stupid practices are tolerated -// sub true, if all forms of subscript notation are tolerated -// vars true, if multiple var statements per function should be allowed -// white true, if sloppy whitespace is tolerated -// windows true, if MS Windows-specific globals should be predefined - -// For example: - -/*jslint - evil: true, nomen: true, regexp: true -*/ - -// The properties directive declares an exclusive list of property names. -// Any properties named in the program that are not in the list will -// produce a warning. - -// For example: - -/*properties - '\b', '\t', '\n', '\f', '\r', '!', '!=', '!==', '"', '%', '\'', - '(arguments)', '(begin)', '(breakage)', '(context)', '(error)', - '(identifier)', '(line)', '(loopage)', '(name)', '(params)', '(scope)', - '(token)', '(vars)', '(verb)', '*', '+', '-', '/', '<', '<=', '==', '===', - '>', '>=', ADSAFE, Array, Date, Function, Object, '\\', a, a_label, - a_not_allowed, a_not_defined, a_scope, abbr, acronym, address, adsafe, - adsafe_a, adsafe_autocomplete, adsafe_bad_id, adsafe_div, adsafe_fragment, - adsafe_go, adsafe_html, adsafe_id, adsafe_id_go, adsafe_lib, - adsafe_lib_second, adsafe_missing_id, adsafe_name_a, adsafe_placement, - adsafe_prefix_a, adsafe_script, adsafe_source, adsafe_subscript_a, - adsafe_tag, all, already_defined, and, anon, applet, apply, approved, area, - arity, article, aside, assign, assign_exception, - assignment_function_expression, at, attribute_case_a, audio, autocomplete, - avoid_a, b, background, 'background-attachment', 'background-color', - 'background-image', 'background-position', 'background-repeat', - bad_assignment, bad_color_a, bad_constructor, bad_entity, bad_html, bad_id_a, - bad_in_a, bad_invocation, bad_name_a, bad_new, bad_number, bad_operand, - bad_style, bad_type, bad_url_a, bad_wrap, base, bdo, big, bitwise, block, - blockquote, body, border, 'border-bottom', 'border-bottom-color', - 'border-bottom-left-radius', 'border-bottom-right-radius', - 'border-bottom-style', 'border-bottom-width', 'border-collapse', - 'border-color', 'border-left', 'border-left-color', 'border-left-style', - 'border-left-width', 'border-radius', 'border-right', 'border-right-color', - 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', - 'border-top', 'border-top-color', 'border-top-left-radius', - 'border-top-right-radius', 'border-top-style', 'border-top-width', - 'border-width', bottom, 'box-shadow', br, braille, browser, button, c, call, - canvas, cap, caption, 'caption-side', center, charAt, charCodeAt, character, - cite, clear, clip, closure, cm, code, col, colgroup, color, combine_var, - command, conditional_assignment, confusing_a, confusing_regexp, - constructor_name_a, content, continue, control_a, 'counter-increment', - 'counter-reset', create, css, cursor, d, dangerous_comment, dangling_a, data, - datalist, dd, debug, del, deleted, details, devel, dfn, dialog, dir, - direction, display, disrupt, div, dl, dt, duplicate_a, edge, edition, else, - em, embed, embossed, empty, 'empty-cells', empty_block, empty_case, - empty_class, entityify, eqeq, error_report, errors, es5, eval, evidence, - evil, ex, exception, exec, expected_a, expected_a_at_b_c, expected_a_b, - expected_a_b_from_c_d, expected_at_a, expected_attribute_a, - expected_attribute_value_a, expected_class_a, expected_fraction_a, - expected_id_a, expected_identifier_a, expected_identifier_a_reserved, - expected_lang_a, expected_linear_a, expected_media_a, expected_name_a, - expected_nonstandard_style_attribute, expected_number_a, expected_operator_a, - expected_percent_a, expected_positive_a, expected_pseudo_a, - expected_selector_a, expected_small_a, expected_space_a_b, expected_string_a, - expected_style_attribute, expected_style_pattern, expected_tagname_a, - expected_type_a, f, fieldset, figure, filter, first, flag, float, floor, - font, 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', - 'font-style', 'font-variant', 'font-weight', footer, forEach, for_if, forin, - form, fragment, frame, frameset, from, fromCharCode, fud, funct, function, - function_block, function_eval, function_loop, function_statement, - function_strict, functions, global, globals, h1, h2, h3, h4, h5, h6, - handheld, hasOwnProperty, head, header, height, hgroup, hr, - 'hta:application', html, html_confusion_a, html_handlers, i, id, identifier, - identifier_function, iframe, img, immed, implied_evil, in, indent, indexOf, - infix_in, init, input, ins, insecure_a, isAlpha, isArray, isDigit, isNaN, - join, jslint, json, kbd, keygen, keys, label, labeled, lang, lbp, - leading_decimal_a, led, left, legend, length, 'letter-spacing', li, lib, - line, 'line-height', link, 'list-style', 'list-style-image', - 'list-style-position', 'list-style-type', map, margin, 'margin-bottom', - 'margin-left', 'margin-right', 'margin-top', mark, 'marker-offset', match, - 'max-height', 'max-width', maxerr, maxlen, menu, message, meta, meter, - 'min-height', 'min-width', missing_a, missing_a_after_b, missing_option, - missing_property, missing_space_a_b, missing_url, missing_use_strict, mixed, - mm, mode, move_invocation, move_var, n, name, name_function, nav, - nested_comment, newcap, node, noframes, nomen, noscript, not, - not_a_constructor, not_a_defined, not_a_function, not_a_label, not_a_scope, - not_greater, nud, number, object, octal_a, ol, on, opacity, open, optgroup, - option, outer, outline, 'outline-color', 'outline-style', 'outline-width', - output, overflow, 'overflow-x', 'overflow-y', p, padding, 'padding-bottom', - 'padding-left', 'padding-right', 'padding-top', 'page-break-after', - 'page-break-before', param, parameter_a_get_b, parameter_arguments_a, - parameter_set_a, params, paren, parent, passfail, pc, plusplus, pop, - position, postscript, pre, predef, print, progress, projection, properties, - properties_report, property, prototype, pt, push, px, q, quote, quotes, r, - radix, range, raw, read_only, reason, redefinition_a, regexp, replace, - report, reserved, reserved_a, rhino, right, rp, rt, ruby, safe, samp, - scanned_a_b, screen, script, search, second, section, select, shift, - slash_equal, slice, sloppy, small, sort, source, span, speech, split, src, - statement_block, stopping, strange_loop, strict, string, strong, stupid, - style, styleproperty, sub, subscript, substr, sup, supplant, sync_a, t, - table, 'table-layout', tag_a_in_b, tbody, td, test, 'text-align', - 'text-decoration', 'text-indent', 'text-shadow', 'text-transform', textarea, - tfoot, th, thead, third, thru, time, title, toLowerCase, toString, - toUpperCase, token, too_long, too_many, top, tr, trailing_decimal_a, tree, - tt, tty, tv, type, u, ul, unclosed, unclosed_comment, unclosed_regexp, undef, - undefined, unescaped_a, unexpected_a, unexpected_char_a_b, - unexpected_comment, unexpected_else, unexpected_label_a, - unexpected_property_a, unexpected_space_a_b, 'unicode-bidi', - unnecessary_initialize, unnecessary_use, unparam, unreachable_a_b, - unrecognized_style_attribute_a, unrecognized_tag_a, unsafe, unused, url, - urls, use_array, use_braces, use_charAt, use_object, use_or, use_param, - used_before_a, var, var_a_not, vars, 'vertical-align', video, visibility, - was, weird_assignment, weird_condition, weird_new, weird_program, - weird_relation, weird_ternary, white, 'white-space', width, windows, - 'word-spacing', 'word-wrap', wrap, wrap_immediate, wrap_regexp, - write_is_wrong, writeable, 'z-index' -*/ - -// The global directive is used to declare global variables that can -// be accessed by the program. If a declaration is true, then the variable -// is writeable. Otherwise, it is read-only. - -// We build the application inside a function so that we produce only a single -// global variable. That function will be invoked immediately, and its return -// value is the JSLINT function itself. That function is also an object that -// can contain data and other functions. - -var JSLINT = (function () { - 'use strict'; - - function array_to_object(array, value) { - -// Make an object from an array of keys and a common value. - - var i, length = array.length, object = {}; - for (i = 0; i < length; i += 1) { - object[array[i]] = value; - } - return object; - } - - - var adsafe_id, // The widget's ADsafe id. - adsafe_may, // The widget may load approved scripts. - adsafe_top, // At the top of the widget script. - adsafe_went, // ADSAFE.go has been called. - allowed_option = { - anon : true, - bitwise : true, - browser : true, - cap : true, - 'continue': true, - css : true, - debug : true, - devel : true, - eqeq : true, - es5 : true, - evil : true, - forin : true, - fragment : true, - indent : 10, - maxerr : 1000, - maxlen : 256, - newcap : true, - node : true, - nomen : true, - on : true, - passfail : true, - plusplus : true, - properties: true, - regexp : true, - rhino : true, - undef : true, - unparam : true, - sloppy : true, - stupid : true, - sub : true, - vars : true, - white : true, - windows : true - }, - anonname, // The guessed name for anonymous functions. - approved, // ADsafe approved urls. - -// These are operators that should not be used with the ! operator. - - bang = { - '<' : true, - '<=' : true, - '==' : true, - '===': true, - '!==': true, - '!=' : true, - '>' : true, - '>=' : true, - '+' : true, - '-' : true, - '*' : true, - '/' : true, - '%' : true - }, - -// These are property names that should not be permitted in the safe subset. - - banned = array_to_object([ - 'arguments', 'callee', 'caller', 'constructor', 'eval', 'prototype', - 'stack', 'unwatch', 'valueOf', 'watch' - ], true), - begin, // The root token - -// browser contains a set of global names that are commonly provided by a -// web browser environment. - - browser = array_to_object([ - 'clearInterval', 'clearTimeout', 'document', 'event', 'FormData', - 'frames', 'history', 'Image', 'localStorage', 'location', 'name', - 'navigator', 'Option', 'parent', 'screen', 'sessionStorage', - 'setInterval', 'setTimeout', 'Storage', 'window', 'XMLHttpRequest' - ], false), - -// bundle contains the text messages. - - bundle = { - a_label: "'{a}' is a statement label.", - a_not_allowed: "'{a}' is not allowed.", - a_not_defined: "'{a}' is not defined.", - a_scope: "'{a}' used out of scope.", - adsafe_a: "ADsafe violation: '{a}'.", - adsafe_autocomplete: "ADsafe autocomplete violation.", - adsafe_bad_id: "ADSAFE violation: bad id.", - adsafe_div: "ADsafe violation: Wrap the widget in a div.", - adsafe_fragment: "ADSAFE: Use the fragment option.", - adsafe_go: "ADsafe violation: Misformed ADSAFE.go.", - adsafe_html: "Currently, ADsafe does not operate on whole HTML " + - "documents. It operates on
fragments and .js files.", - adsafe_id: "ADsafe violation: id does not match.", - adsafe_id_go: "ADsafe violation: Missing ADSAFE.id or ADSAFE.go.", - adsafe_lib: "ADsafe lib violation.", - adsafe_lib_second: "ADsafe: The second argument to lib must be a function.", - adsafe_missing_id: "ADSAFE violation: missing ID_.", - adsafe_name_a: "ADsafe name violation: '{a}'.", - adsafe_placement: "ADsafe script placement violation.", - adsafe_prefix_a: "ADsafe violation: An id must have a '{a}' prefix", - adsafe_script: "ADsafe script violation.", - adsafe_source: "ADsafe unapproved script source.", - adsafe_subscript_a: "ADsafe subscript '{a}'.", - adsafe_tag: "ADsafe violation: Disallowed tag '{a}'.", - already_defined: "'{a}' is already defined.", - and: "The '&&' subexpression should be wrapped in parens.", - assign_exception: "Do not assign to the exception parameter.", - assignment_function_expression: "Expected an assignment or " + - "function call and instead saw an expression.", - attribute_case_a: "Attribute '{a}' not all lower case.", - avoid_a: "Avoid '{a}'.", - bad_assignment: "Bad assignment.", - bad_color_a: "Bad hex color '{a}'.", - bad_constructor: "Bad constructor.", - bad_entity: "Bad entity.", - bad_html: "Bad HTML string", - bad_id_a: "Bad id: '{a}'.", - bad_in_a: "Bad for in variable '{a}'.", - bad_invocation: "Bad invocation.", - bad_name_a: "Bad name: '{a}'.", - bad_new: "Do not use 'new' for side effects.", - bad_number: "Bad number '{a}'.", - bad_operand: "Bad operand.", - bad_style: "Bad style.", - bad_type: "Bad type.", - bad_url_a: "Bad url '{a}'.", - bad_wrap: "Do not wrap function literals in parens unless they " + - "are to be immediately invoked.", - combine_var: "Combine this with the previous 'var' statement.", - conditional_assignment: "Expected a conditional expression and " + - "instead saw an assignment.", - confusing_a: "Confusing use of '{a}'.", - confusing_regexp: "Confusing regular expression.", - constructor_name_a: "A constructor name '{a}' should start with " + - "an uppercase letter.", - control_a: "Unexpected control character '{a}'.", - css: "A css file should begin with @charset 'UTF-8';", - dangling_a: "Unexpected dangling '_' in '{a}'.", - dangerous_comment: "Dangerous comment.", - deleted: "Only properties should be deleted.", - duplicate_a: "Duplicate '{a}'.", - empty_block: "Empty block.", - empty_case: "Empty case.", - empty_class: "Empty class.", - es5: "This is an ES5 feature.", - evil: "eval is evil.", - expected_a: "Expected '{a}'.", - expected_a_b: "Expected '{a}' and instead saw '{b}'.", - expected_a_b_from_c_d: "Expected '{a}' to match '{b}' from line " + - "{c} and instead saw '{d}'.", - expected_at_a: "Expected an at-rule, and instead saw @{a}.", - expected_a_at_b_c: "Expected '{a}' at column {b}, not column {c}.", - expected_attribute_a: "Expected an attribute, and instead saw [{a}].", - expected_attribute_value_a: "Expected an attribute value and " + - "instead saw '{a}'.", - expected_class_a: "Expected a class, and instead saw .{a}.", - expected_fraction_a: "Expected a number between 0 and 1 and " + - "instead saw '{a}'", - expected_id_a: "Expected an id, and instead saw #{a}.", - expected_identifier_a: "Expected an identifier and instead saw '{a}'.", - expected_identifier_a_reserved: "Expected an identifier and " + - "instead saw '{a}' (a reserved word).", - expected_linear_a: "Expected a linear unit and instead saw '{a}'.", - expected_lang_a: "Expected a lang code, and instead saw :{a}.", - expected_media_a: "Expected a CSS media type, and instead saw '{a}'.", - expected_name_a: "Expected a name and instead saw '{a}'.", - expected_nonstandard_style_attribute: "Expected a non-standard " + - "style attribute and instead saw '{a}'.", - expected_number_a: "Expected a number and instead saw '{a}'.", - expected_operator_a: "Expected an operator and instead saw '{a}'.", - expected_percent_a: "Expected a percentage and instead saw '{a}'", - expected_positive_a: "Expected a positive number and instead saw '{a}'", - expected_pseudo_a: "Expected a pseudo, and instead saw :{a}.", - expected_selector_a: "Expected a CSS selector, and instead saw {a}.", - expected_small_a: "Expected a small positive integer and instead saw '{a}'", - expected_space_a_b: "Expected exactly one space between '{a}' and '{b}'.", - expected_string_a: "Expected a string and instead saw {a}.", - expected_style_attribute: "Excepted a style attribute, and instead saw '{a}'.", - expected_style_pattern: "Expected a style pattern, and instead saw '{a}'.", - expected_tagname_a: "Expected a tagName, and instead saw {a}.", - expected_type_a: "Expected a type, and instead saw {a}.", - for_if: "The body of a for in should be wrapped in an if " + - "statement to filter unwanted properties from the prototype.", - function_block: "Function statements should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", - function_eval: "The Function constructor is eval.", - function_loop: "Don't make functions within a loop.", - function_statement: "Function statements are not invocable. " + - "Wrap the whole function invocation in parens.", - function_strict: "Use the function form of 'use strict'.", - html_confusion_a: "HTML confusion in regular expression '<{a}'.", - html_handlers: "Avoid HTML event handlers.", - identifier_function: "Expected an identifier in an assignment " + - "and instead saw a function invocation.", - implied_evil: "Implied eval is evil. Pass a function instead of a string.", - infix_in: "Unexpected 'in'. Compare with undefined, or use the " + - "hasOwnProperty method instead.", - insecure_a: "Insecure '{a}'.", - isNaN: "Use the isNaN function to compare with NaN.", - lang: "lang is deprecated.", - leading_decimal_a: "A leading decimal point can be confused with a dot: '.{a}'.", - missing_a: "Missing '{a}'.", - missing_a_after_b: "Missing '{a}' after '{b}'.", - missing_option: "Missing option value.", - missing_property: "Missing property name.", - missing_space_a_b: "Missing space between '{a}' and '{b}'.", - missing_url: "Missing url.", - missing_use_strict: "Missing 'use strict' statement.", - mixed: "Mixed spaces and tabs.", - move_invocation: "Move the invocation into the parens that " + - "contain the function.", - move_var: "Move 'var' declarations to the top of the function.", - name_function: "Missing name in function statement.", - nested_comment: "Nested comment.", - not: "Nested not.", - not_a_constructor: "Do not use {a} as a constructor.", - not_a_defined: "'{a}' has not been fully defined yet.", - not_a_function: "'{a}' is not a function.", - not_a_label: "'{a}' is not a label.", - not_a_scope: "'{a}' is out of scope.", - not_greater: "'{a}' should not be greater than '{b}'.", - octal_a: "Don't use octal: '{a}'. Use '\\u....' instead.", - parameter_arguments_a: "Do not mutate parameter '{a}' when using 'arguments'.", - parameter_a_get_b: "Unexpected parameter '{a}' in get {b} function.", - parameter_set_a: "Expected parameter (value) in set {a} function.", - radix: "Missing radix parameter.", - read_only: "Read only.", - redefinition_a: "Redefinition of '{a}'.", - reserved_a: "Reserved name '{a}'.", - scanned_a_b: "{a} ({b}% scanned).", - slash_equal: "A regular expression literal can be confused with '/='.", - statement_block: "Expected to see a statement and instead saw a block.", - stopping: "Stopping. ", - strange_loop: "Strange loop.", - strict: "Strict violation.", - subscript: "['{a}'] is better written in dot notation.", - sync_a: "Unexpected sync method: '{a}'.", - tag_a_in_b: "A '<{a}>' must be within '<{b}>'.", - too_long: "Line too long.", - too_many: "Too many errors.", - trailing_decimal_a: "A trailing decimal point can be confused " + - "with a dot: '.{a}'.", - type: "type is unnecessary.", - unclosed: "Unclosed string.", - unclosed_comment: "Unclosed comment.", - unclosed_regexp: "Unclosed regular expression.", - unescaped_a: "Unescaped '{a}'.", - unexpected_a: "Unexpected '{a}'.", - unexpected_char_a_b: "Unexpected character '{a}' in {b}.", - unexpected_comment: "Unexpected comment.", - unexpected_else: "Unexpected 'else' after 'return'.", - unexpected_label_a: "Unexpected label '{a}'.", - unexpected_property_a: "Unexpected /*property*/ '{a}'.", - unexpected_space_a_b: "Unexpected space between '{a}' and '{b}'.", - unnecessary_initialize: "It is not necessary to initialize '{a}' " + - "to 'undefined'.", - unnecessary_use: "Unnecessary 'use strict'.", - unreachable_a_b: "Unreachable '{a}' after '{b}'.", - unrecognized_style_attribute_a: "Unrecognized style attribute '{a}'.", - unrecognized_tag_a: "Unrecognized tag '<{a}>'.", - unsafe: "Unsafe character.", - url: "JavaScript URL.", - use_array: "Use the array literal notation [].", - use_braces: "Spaces are hard to count. Use {{a}}.", - use_charAt: "Use the charAt method.", - use_object: "Use the object literal notation {}.", - use_or: "Use the || operator.", - use_param: "Use a named parameter.", - used_before_a: "'{a}' was used before it was defined.", - var_a_not: "Variable {a} was not declared correctly.", - weird_assignment: "Weird assignment.", - weird_condition: "Weird condition.", - weird_new: "Weird construction. Delete 'new'.", - weird_program: "Weird program.", - weird_relation: "Weird relation.", - weird_ternary: "Weird ternary.", - wrap_immediate: "Wrap an immediate function invocation in parentheses " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself.", - wrap_regexp: "Wrap the /regexp/ literal in parens to " + - "disambiguate the slash operator.", - write_is_wrong: "document.write can be a form of eval." - }, - comments_off, - css_attribute_data, - css_any, - - css_colorData = array_to_object([ - "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", - "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", - "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", - "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", - "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", - "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", - "darkred", "darksalmon", "darkseagreen", "darkslateblue", - "darkslategray", "darkturquoise", "darkviolet", "deeppink", - "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", - "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", - "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", - "indianred", "indigo", "ivory", "khaki", "lavender", - "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", - "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgreen", - "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", - "lightslategray", "lightsteelblue", "lightyellow", "lime", - "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", - "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", - "mediumslateblue", "mediumspringgreen", "mediumturquoise", - "mediumvioletred", "midnightblue", "mintcream", "mistyrose", - "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", - "orange", "orangered", "orchid", "palegoldenrod", "palegreen", - "paleturquoise", "palevioletred", "papayawhip", "peachpuff", - "peru", "pink", "plum", "powderblue", "purple", "red", "rosybrown", - "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", - "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", - "snow", "springgreen", "steelblue", "tan", "teal", "thistle", - "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", - "yellow", "yellowgreen", - - "activeborder", "activecaption", "appworkspace", "background", - "buttonface", "buttonhighlight", "buttonshadow", "buttontext", - "captiontext", "graytext", "highlight", "highlighttext", - "inactiveborder", "inactivecaption", "inactivecaptiontext", - "infobackground", "infotext", "menu", "menutext", "scrollbar", - "threeddarkshadow", "threedface", "threedhighlight", - "threedlightshadow", "threedshadow", "window", "windowframe", - "windowtext" - ], true), - - css_border_style, - css_break, - - css_lengthData = { - '%': true, - 'cm': true, - 'em': true, - 'ex': true, - 'in': true, - 'mm': true, - 'pc': true, - 'pt': true, - 'px': true - }, - - css_media, - css_overflow, - - descapes = { - 'b': '\b', - 't': '\t', - 'n': '\n', - 'f': '\f', - 'r': '\r', - '"': '"', - '/': '/', - '\\': '\\', - '!': '!' - }, - - devel = array_to_object([ - 'alert', 'confirm', 'console', 'Debug', 'opera', 'prompt', 'WSH' - ], false), - directive, - escapes = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\'': '\\\'', - '"' : '\\"', - '/' : '\\/', - '\\': '\\\\' - }, - - funct, // The current function, including the labels used in - // the function, as well as (breakage), - // (context), (loopage), (name), (params), (token), - // (vars), (verb) - - functionicity = [ - 'closure', 'exception', 'global', 'label', 'outer', 'undef', - 'unused', 'var' - ], - - functions, // All of the functions - global_funct, // The global body - global_scope, // The global scope - html_tag = { - a: {}, - abbr: {}, - acronym: {}, - address: {}, - applet: {}, - area: {empty: true, parent: ' map '}, - article: {}, - aside: {}, - audio: {}, - b: {}, - base: {empty: true, parent: ' head '}, - bdo: {}, - big: {}, - blockquote: {}, - body: {parent: ' html noframes '}, - br: {empty: true}, - button: {}, - canvas: {parent: ' body p div th td '}, - caption: {parent: ' table '}, - center: {}, - cite: {}, - code: {}, - col: {empty: true, parent: ' table colgroup '}, - colgroup: {parent: ' table '}, - command: {parent: ' menu '}, - datalist: {}, - dd: {parent: ' dl '}, - del: {}, - details: {}, - dialog: {}, - dfn: {}, - dir: {}, - div: {}, - dl: {}, - dt: {parent: ' dl '}, - em: {}, - embed: {}, - fieldset: {}, - figure: {}, - font: {}, - footer: {}, - form: {}, - frame: {empty: true, parent: ' frameset '}, - frameset: {parent: ' html frameset '}, - h1: {}, - h2: {}, - h3: {}, - h4: {}, - h5: {}, - h6: {}, - head: {parent: ' html '}, - header: {}, - hgroup: {}, - hr: {empty: true}, - 'hta:application': - {empty: true, parent: ' head '}, - html: {parent: '*'}, - i: {}, - iframe: {}, - img: {empty: true}, - input: {empty: true}, - ins: {}, - kbd: {}, - keygen: {}, - label: {}, - legend: {parent: ' details fieldset figure '}, - li: {parent: ' dir menu ol ul '}, - link: {empty: true, parent: ' head '}, - map: {}, - mark: {}, - menu: {}, - meta: {empty: true, parent: ' head noframes noscript '}, - meter: {}, - nav: {}, - noframes: {parent: ' html body '}, - noscript: {parent: ' body head noframes '}, - object: {}, - ol: {}, - optgroup: {parent: ' select '}, - option: {parent: ' optgroup select '}, - output: {}, - p: {}, - param: {empty: true, parent: ' applet object '}, - pre: {}, - progress: {}, - q: {}, - rp: {}, - rt: {}, - ruby: {}, - samp: {}, - script: {empty: true, parent: ' body div frame head iframe p pre span '}, - section: {}, - select: {}, - small: {}, - span: {}, - source: {}, - strong: {}, - style: {parent: ' head ', empty: true}, - sub: {}, - sup: {}, - table: {}, - tbody: {parent: ' table '}, - td: {parent: ' tr '}, - textarea: {}, - tfoot: {parent: ' table '}, - th: {parent: ' tr '}, - thead: {parent: ' table '}, - time: {}, - title: {parent: ' head '}, - tr: {parent: ' table tbody thead tfoot '}, - tt: {}, - u: {}, - ul: {}, - 'var': {}, - video: {} - }, - - ids, // HTML ids - in_block, - indent, - itself, // JSLint itself - json_mode, - lex, // the tokenizer - lines, - lookahead, - node = array_to_object([ - 'Buffer', 'clearInterval', 'clearTimeout', 'console', 'exports', - 'global', 'module', 'process', 'querystring', 'require', - 'setInterval', 'setTimeout', '__dirname', '__filename' - ], false), - node_js, - numbery = array_to_object(['indexOf', 'lastIndexOf', 'search'], true), - next_token, - option, - predefined, // Global variables defined by option - prereg, - prev_token, - property, - regexp_flag = array_to_object(['g', 'i', 'm'], true), - return_this = function return_this() { - return this; - }, - rhino = array_to_object([ - 'defineClass', 'deserialize', 'gc', 'help', 'load', 'loadClass', - 'print', 'quit', 'readFile', 'readUrl', 'runCommand', 'seal', - 'serialize', 'spawn', 'sync', 'toint32', 'version' - ], false), - - scope, // An object containing an object for each variable in scope - semicolon_coda = array_to_object([';', '"', '\'', ')'], true), - src, - stack, - -// standard contains the global names that are provided by the -// ECMAScript standard. - - standard = array_to_object([ - 'Array', 'Boolean', 'Date', 'decodeURI', 'decodeURIComponent', - 'encodeURI', 'encodeURIComponent', 'Error', 'eval', 'EvalError', - 'Function', 'isFinite', 'isNaN', 'JSON', 'Math', 'Number', - 'Object', 'parseInt', 'parseFloat', 'RangeError', 'ReferenceError', - 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError' - ], false), - - strict_mode, - syntax = {}, - tab, - token, - urls, - var_mode, - warnings, - - windows = array_to_object([ - 'ActiveXObject', 'CScript', 'Debug', 'Enumerator', 'System', - 'VBArray', 'WScript', 'WSH' - ], false), - -// xmode is used to adapt to the exceptions in html parsing. -// It can have these states: -// '' .js script file -// 'html' -// 'outer' -// 'script' -// 'style' -// 'scriptstring' -// 'styleproperty' - - xmode, - xquote, - -// Regular expressions. Some of these are stupidly long. - -// unsafe comment or string - ax = /@cc|<\/?|script|\]\s*\]|<\s*!|</i, -// carriage return, carriage return linefeed, or linefeed - crlfx = /\r\n?|\n/, -// unsafe characters that are silently deleted by one or more browsers - cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, -// query characters for ids - dx = /[\[\]\/\\"'*<>.&:(){}+=#]/, -// html token - hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/, -// identifier - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, -// javascript url - jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i, -// star slash - lx = /\*\/|\/\*/, -// characters in strings that need escapement - nx = /[\u0000-\u001f'\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, -// outer html token - ox = /[>&]|<[\/!]?|--/, -// attributes characters - qx = /[^a-zA-Z0-9+\-_\/. ]/, -// style - sx = /^\s*([{}:#%.=,>+\[\]@()"';]|[*$\^~]=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/, - ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/, -// token - tx = /^\s*([(){}\[\]\?.,:;'"~#@`]|={1,3}|\/(\*(jslint|properties|property|members?|globals?)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|[\^%]=?|&[&=]?|\|[|=]?|>{1,3}=?|<(?:[\/=!]|\!(\[|--)?|<=?)?|\!={0,2}|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+(?:[xX][0-9a-fA-F]+|\.[0-9]*)?(?:[eE][+\-]?[0-9]+)?)/, -// url badness - ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto|script/i, - - rx = { - outer: hx, - html: hx, - style: sx, - styleproperty: ssx - }; - - - function F() {} // Used by Object.create - -// Provide critical ES5 functions to ES3. - - if (typeof Array.prototype.filter !== 'function') { - Array.prototype.filter = function (f) { - var i, length = this.length, result = [], value; - for (i = 0; i < length; i += 1) { - try { - value = this[i]; - if (f(value)) { - result.push(value); - } - } catch (ignore) { - } - } - return result; - }; - } - - if (typeof Array.prototype.forEach !== 'function') { - Array.prototype.forEach = function (f) { - var i, length = this.length; - for (i = 0; i < length; i += 1) { - try { - f(this[i]); - } catch (ignore) { - } - } - }; - } - - if (typeof Array.isArray !== 'function') { - Array.isArray = function (o) { - return Object.prototype.toString.apply(o) === '[object Array]'; - }; - } - - if (!Object.prototype.hasOwnProperty.call(Object, 'create')) { - Object.create = function (o) { - F.prototype = o; - return new F(); - }; - } - - if (typeof Object.keys !== 'function') { - Object.keys = function (o) { - var array = [], key; - for (key in o) { - if (Object.prototype.hasOwnProperty.call(o, key)) { - array.push(key); - } - } - return array; - }; - } - - if (typeof String.prototype.entityify !== 'function') { - String.prototype.entityify = function () { - return this - .replace(/&/g, '&') - .replace(//g, '>'); - }; - } - - if (typeof String.prototype.isAlpha !== 'function') { - String.prototype.isAlpha = function () { - return (this >= 'a' && this <= 'z\uffff') || - (this >= 'A' && this <= 'Z\uffff'); - }; - } - - if (typeof String.prototype.isDigit !== 'function') { - String.prototype.isDigit = function () { - return (this >= '0' && this <= '9'); - }; - } - - if (typeof String.prototype.supplant !== 'function') { - String.prototype.supplant = function (o) { - return this.replace(/\{([^{}]*)\}/g, function (a, b) { - var replacement = o[b]; - return typeof replacement === 'string' || - typeof replacement === 'number' ? replacement : a; - }); - }; - } - - - function sanitize(a) { - -// Escapify a troublesome character. - - return escapes[a] || - '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); - } - - - function add_to_predefined(group) { - Object.keys(group).forEach(function (name) { - predefined[name] = group[name]; - }); - } - - - function assume() { - if (!option.safe) { - if (option.rhino) { - add_to_predefined(rhino); - option.rhino = false; - } - if (option.devel) { - add_to_predefined(devel); - option.devel = false; - } - if (option.browser) { - add_to_predefined(browser); - option.browser = false; - } - if (option.windows) { - add_to_predefined(windows); - option.windows = false; - } - if (option.node) { - add_to_predefined(node); - option.node = false; - node_js = true; - } - } - } - - -// Produce an error warning. - - function artifact(tok) { - if (!tok) { - tok = next_token; - } - return tok.number || tok.string; - } - - function quit(message, line, character) { - throw { - name: 'JSLintError', - line: line, - character: character, - message: bundle.scanned_a_b.supplant({ - a: message, - b: Math.floor((line / lines.length) * 100) - }) - }; - } - - function warn(message, offender, a, b, c, d) { - var character, line, warning; - offender = offender || next_token; // ~~ - line = offender.line || 0; - character = offender.from || 0; - warning = { - id: '(error)', - raw: bundle[message] || message, - evidence: lines[line - 1] || '', - line: line, - character: character, - a: a || (offender.id === '(number)' - ? String(offender.number) - : offender.string), - b: b, - c: c, - d: d - }; - warning.reason = warning.raw.supplant(warning); - JSLINT.errors.push(warning); - if (option.passfail) { - quit(bundle.stopping, line, character); - } - warnings += 1; - if (warnings >= option.maxerr) { - quit(bundle.too_many, line, character); - } - return warning; - } - - function warn_at(message, line, character, a, b, c, d) { - return warn(message, { - line: line, - from: character - }, a, b, c, d); - } - - function stop(message, offender, a, b, c, d) { - var warning = warn(message, offender, a, b, c, d); - quit(bundle.stopping, warning.line, warning.character); - } - - function stop_at(message, line, character, a, b, c, d) { - return stop(message, { - line: line, - from: character - }, a, b, c, d); - } - - function expected_at(at) { - if (!option.white && next_token.from !== at) { - warn('expected_a_at_b_c', next_token, '', at, - next_token.from); - } - } - - function aint(it, name, expected) { - if (it[name] !== expected) { - warn('expected_a_b', it, expected, it[name]); - return true; - } - return false; - } - - -// lexical analysis and token construction - - lex = (function lex() { - var character, c, from, length, line, pos, source_row; - -// Private lex methods - - function next_line() { - var at; - if (line >= lines.length) { - return false; - } - character = 1; - source_row = lines[line]; - line += 1; - at = source_row.search(/ \t/); - if (at >= 0) { - warn_at('mixed', line, at + 1); - } - source_row = source_row.replace(/\t/g, tab); - at = source_row.search(cx); - if (at >= 0) { - warn_at('unsafe', line, at); - } - if (option.maxlen && option.maxlen < source_row.length) { - warn_at('too_long', line, source_row.length); - } - return true; - } - -// Produce a token object. The token inherits from a syntax symbol. - - function it(type, value) { - var id, the_token; - if (type === '(string)' || type === '(range)') { - if (jx.test(value)) { - warn_at('url', line, from); - } - } - the_token = Object.create(syntax[( - type === '(punctuator)' || (type === '(identifier)' && - Object.prototype.hasOwnProperty.call(syntax, value)) - ? value - : type - )] || syntax['(error)']); - if (type === '(identifier)') { - the_token.identifier = true; - if (value === '__iterator__' || value === '__proto__') { - stop_at('reserved_a', line, from, value); - } else if (!option.nomen && - (value.charAt(0) === '_' || - value.charAt(value.length - 1) === '_')) { - warn_at('dangling_a', line, from, value); - } - } - if (type === '(number)') { - the_token.number = +value; - } else if (value !== undefined) { - the_token.string = String(value); - } - the_token.line = line; - the_token.from = from; - the_token.thru = character; - id = the_token.id; - prereg = id && ( - ('(,=:[!&|?{};'.indexOf(id.charAt(id.length - 1)) >= 0) || - id === 'return' || id === 'case' - ); - return the_token; - } - - function match(x) { - var exec = x.exec(source_row), first; - if (exec) { - length = exec[0].length; - first = exec[1]; - c = first.charAt(0); - source_row = source_row.slice(length); - from = character + length - first.length; - character += length; - return first; - } - } - - function string(x) { - var c, pos = 0, r = '', result; - - function hex(n) { - var i = parseInt(source_row.substr(pos + 1, n), 16); - pos += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warn_at('unexpected_a', line, character, '\\'); - } - character += n; - c = String.fromCharCode(i); - } - - if (json_mode && x !== '"') { - warn_at('expected_a', line, character, '"'); - } - - if (xquote === x || (xmode === 'scriptstring' && !xquote)) { - return it('(punctuator)', x); - } - - for (;;) { - while (pos >= source_row.length) { - pos = 0; - if (xmode !== 'html' || !next_line()) { - stop_at('unclosed', line, from); - } - } - c = source_row.charAt(pos); - if (c === x) { - character += 1; - source_row = source_row.slice(pos + 1); - result = it('(string)', r); - result.quote = x; - return result; - } - if (c < ' ') { - if (c === '\n' || c === '\r') { - break; - } - warn_at('control_a', line, character + pos, - source_row.slice(0, pos)); - } else if (c === xquote) { - warn_at('bad_html', line, character + pos); - } else if (c === '<') { - if (option.safe && xmode === 'html') { - warn_at('adsafe_a', line, character + pos, c); - } else if (source_row.charAt(pos + 1) === '/' && (xmode || option.safe)) { - warn_at('expected_a_b', line, character, - '<\\/', '= '0' && c <= '7' ? 'octal_a' : 'unexpected_a', - line, character, '\\' + c); - } else { - c = descapes[c]; - } - } - } - } - r += c; - character += 1; - pos += 1; - } - } - - function number(snippet) { - var digit; - if (xmode !== 'style' && xmode !== 'styleproperty' && - source_row.charAt(0).isAlpha()) { - warn_at('expected_space_a_b', - line, character, c, source_row.charAt(0)); - } - if (c === '0') { - digit = snippet.charAt(1); - if (digit.isDigit()) { - if (token.id !== '.' && xmode !== 'styleproperty') { - warn_at('unexpected_a', line, character, snippet); - } - } else if (json_mode && (digit === 'x' || digit === 'X')) { - warn_at('unexpected_a', line, character, '0x'); - } - } - if (snippet.slice(snippet.length - 1) === '.') { - warn_at('trailing_decimal_a', line, character, snippet); - } - if (xmode !== 'style') { - digit = +snippet; - if (!isFinite(digit)) { - warn_at('bad_number', line, character, snippet); - } - snippet = digit; - } - return it('(number)', snippet); - } - - function comment(snippet) { - if (comments_off || src || (xmode && xmode !== 'script' && - xmode !== 'style' && xmode !== 'styleproperty')) { - warn_at('unexpected_comment', line, character); - } else if (xmode === 'script' && /<\//i.test(source_row)) { - warn_at('unexpected_a', line, character, '<\/'); - } else if (option.safe && ax.test(snippet)) { - warn_at('dangerous_comment', line, character); - } - } - - function regexp() { - var b, - bit, - captures = 0, - depth = 0, - flag = '', - high, - letter, - length = 0, - low, - potential, - quote, - result; - for (;;) { - b = true; - c = source_row.charAt(length); - length += 1; - switch (c) { - case '': - stop_at('unclosed_regexp', line, from); - return; - case '/': - if (depth > 0) { - warn_at('unescaped_a', line, from + length, '/'); - } - c = source_row.slice(0, length - 1); - potential = Object.create(regexp_flag); - for (;;) { - letter = source_row.charAt(length); - if (potential[letter] !== true) { - break; - } - potential[letter] = false; - length += 1; - flag += letter; - } - if (source_row.charAt(length).isAlpha()) { - stop_at('unexpected_a', line, from, source_row.charAt(length)); - } - character += length; - source_row = source_row.slice(length); - quote = source_row.charAt(0); - if (quote === '/' || quote === '*') { - stop_at('confusing_regexp', line, from); - } - result = it('(regexp)', c); - result.flag = flag; - return result; - case '\\': - c = source_row.charAt(length); - if (c < ' ') { - warn_at('control_a', line, from + length, String(c)); - } else if (c === '<') { - warn_at(bundle.unexpected_a, line, from + length, '\\'); - } - length += 1; - break; - case '(': - depth += 1; - b = false; - if (source_row.charAt(length) === '?') { - length += 1; - switch (source_row.charAt(length)) { - case ':': - case '=': - case '!': - length += 1; - break; - default: - warn_at(bundle.expected_a_b, line, from + length, - ':', source_row.charAt(length)); - } - } else { - captures += 1; - } - break; - case '|': - b = false; - break; - case ')': - if (depth === 0) { - warn_at('unescaped_a', line, from + length, ')'); - } else { - depth -= 1; - } - break; - case ' ': - pos = 1; - while (source_row.charAt(length) === ' ') { - length += 1; - pos += 1; - } - if (pos > 1) { - warn_at('use_braces', line, from + length, pos); - } - break; - case '[': - c = source_row.charAt(length); - if (c === '^') { - length += 1; - if (!option.regexp) { - warn_at('insecure_a', line, from + length, c); - } else if (source_row.charAt(length) === ']') { - stop_at('unescaped_a', line, from + length, '^'); - } - } - bit = false; - if (c === ']') { - warn_at('empty_class', line, from + length - 1); - bit = true; - } -klass: do { - c = source_row.charAt(length); - length += 1; - switch (c) { - case '[': - case '^': - warn_at('unescaped_a', line, from + length, c); - bit = true; - break; - case '-': - if (bit) { - bit = false; - } else { - warn_at('unescaped_a', line, from + length, '-'); - bit = true; - } - break; - case ']': - if (!bit) { - warn_at('unescaped_a', line, from + length - 1, '-'); - } - break klass; - case '\\': - c = source_row.charAt(length); - if (c < ' ') { - warn_at(bundle.control_a, line, from + length, String(c)); - } else if (c === '<') { - warn_at(bundle.unexpected_a, line, from + length, '\\'); - } - length += 1; - bit = true; - break; - case '/': - warn_at('unescaped_a', line, from + length - 1, '/'); - bit = true; - break; - case '<': - if (xmode === 'script') { - c = source_row.charAt(length); - if (c === '!' || c === '/') { - warn_at(bundle.html_confusion_a, line, - from + length, c); - } - } - bit = true; - break; - default: - bit = true; - } - } while (c); - break; - case '.': - if (!option.regexp) { - warn_at('insecure_a', line, from + length, c); - } - break; - case ']': - case '?': - case '{': - case '}': - case '+': - case '*': - warn_at('unescaped_a', line, from + length, c); - break; - case '<': - if (xmode === 'script') { - c = source_row.charAt(length); - if (c === '!' || c === '/') { - warn_at(bundle.html_confusion_a, line, from + length, c); - } - } - break; - } - if (b) { - switch (source_row.charAt(length)) { - case '?': - case '+': - case '*': - length += 1; - if (source_row.charAt(length) === '?') { - length += 1; - } - break; - case '{': - length += 1; - c = source_row.charAt(length); - if (c < '0' || c > '9') { - warn_at(bundle.expected_number_a, line, - from + length, c); - } - length += 1; - low = +c; - for (;;) { - c = source_row.charAt(length); - if (c < '0' || c > '9') { - break; - } - length += 1; - low = +c + (low * 10); - } - high = low; - if (c === ',') { - length += 1; - high = Infinity; - c = source_row.charAt(length); - if (c >= '0' && c <= '9') { - length += 1; - high = +c; - for (;;) { - c = source_row.charAt(length); - if (c < '0' || c > '9') { - break; - } - length += 1; - high = +c + (high * 10); - } - } - } - if (source_row.charAt(length) !== '}') { - warn_at(bundle.expected_a_b, line, from + length, - '}', c); - } else { - length += 1; - } - if (source_row.charAt(length) === '?') { - length += 1; - } - if (low > high) { - warn_at(bundle.not_greater, line, from + length, - low, high); - } - break; - } - } - } - c = source_row.slice(0, length - 1); - character += length; - source_row = source_row.slice(length); - return it('(regexp)', c); - } - -// Public lex methods - - return { - init: function (source) { - if (typeof source === 'string') { - lines = source.split(crlfx); - } else { - lines = source; - } - line = 0; - next_line(); - from = 1; - }, - - range: function (begin, end) { - var c, value = ''; - from = character; - if (source_row.charAt(0) !== begin) { - stop_at('expected_a_b', line, character, begin, - source_row.charAt(0)); - } - for (;;) { - source_row = source_row.slice(1); - character += 1; - c = source_row.charAt(0); - switch (c) { - case '': - stop_at('missing_a', line, character, c); - break; - case end: - source_row = source_row.slice(1); - character += 1; - return it('(range)', value); - case xquote: - case '\\': - warn_at('unexpected_a', line, character, c); - break; - } - value += c; - } - }, - -// token -- this is called by advance to get the next token. - - token: function () { - var c, i, snippet; - - for (;;) { - while (!source_row) { - if (!next_line()) { - return it('(end)'); - } - } - while (xmode === 'outer') { - i = source_row.search(ox); - if (i === 0) { - break; - } else if (i > 0) { - character += 1; - source_row = source_row.slice(i); - break; - } else { - if (!next_line()) { - return it('(end)', ''); - } - } - } - snippet = match(rx[xmode] || tx); - if (!snippet) { - if (source_row) { - if (source_row.charAt(0) === ' ') { - if (!option.white) { - warn_at('unexpected_a', line, character, - '(space)'); - } - character += 1; - source_row = ''; - } else { - stop_at('unexpected_a', line, character, - source_row.charAt(0)); - } - } - } else { - -// identifier - - c = snippet.charAt(0); - if (c.isAlpha() || c === '_' || c === '$') { - return it('(identifier)', snippet); - } - -// number - - if (c.isDigit()) { - return number(snippet); - } - switch (snippet) { - -// string - - case '"': - case "'": - return string(snippet); - -// // comment - - case '//': - comment(source_row); - source_row = ''; - break; - -// /* comment - - case '/*': - for (;;) { - i = source_row.search(lx); - if (i >= 0) { - break; - } - comment(source_row); - if (!next_line()) { - stop_at('unclosed_comment', line, character); - } - } - comment(source_row.slice(0, i)); - character += i + 2; - if (source_row.charAt(i) === '/') { - stop_at('nested_comment', line, character); - } - source_row = source_row.slice(i + 2); - break; - - case '': - break; -// / - case '/': - if (token.id === '/=') { - stop_at( - bundle.slash_equal, - line, - from - ); - } - return prereg - ? regexp() - : it('(punctuator)', snippet); - -// punctuator - - case ''); - } - character += 3; - source_row = source_row.slice(i + 3); - break; - case '#': - if (xmode === 'html' || xmode === 'styleproperty') { - for (;;) { - c = source_row.charAt(0); - if ((c < '0' || c > '9') && - (c < 'a' || c > 'f') && - (c < 'A' || c > 'F')) { - break; - } - character += 1; - source_row = source_row.slice(1); - snippet += c; - } - if (snippet.length !== 4 && snippet.length !== 7) { - warn_at('bad_color_a', line, - from + length, snippet); - } - return it('(color)', snippet); - } - return it('(punctuator)', snippet); - - default: - if (xmode === 'outer' && c === '&') { - character += 1; - source_row = source_row.slice(1); - for (;;) { - c = source_row.charAt(0); - character += 1; - source_row = source_row.slice(1); - if (c === ';') { - break; - } - if (!((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'z') || - c === '#')) { - stop_at('bad_entity', line, from + length, - character); - } - } - break; - } - return it('(punctuator)', snippet); - } - } - } - } - }; - }()); - - - function add_label(token, kind, name) { - -// Define the symbol in the current function in the current scope. - - name = name || token.string; - -// Global variables cannot be created in the safe subset. If a global variable -// already exists, do nothing. If it is predefined, define it. - - if (funct === global_funct) { - if (option.safe) { - warn('adsafe_a', token, name); - } - if (typeof global_funct[name] !== 'string') { - token.writeable = typeof predefined[name] === 'boolean' - ? predefined[name] - : true; - token.funct = funct; - global_scope[name] = token; - } - if (kind === 'becoming') { - kind = 'var'; - } - -// Ordinary variables. - - } else { - -// Warn if the variable already exists. - - if (typeof funct[name] === 'string') { - if (funct[name] === 'undef') { - if (!option.undef) { - warn('used_before_a', token, name); - } - kind = 'var'; - } else { - warn('already_defined', token, name); - } - } else { - -// Add the symbol to the current function. - - token.funct = funct; - token.writeable = true; - scope[name] = token; - } - } - funct[name] = kind; - } - - - function peek(distance) { - -// Peek ahead to a future token. The distance is how far ahead to look. The -// default is the next token. - - var found, slot = 0; - - distance = distance || 0; - while (slot <= distance) { - found = lookahead[slot]; - if (!found) { - found = lookahead[slot] = lex.token(); - } - slot += 1; - } - return found; - } - - - function advance(id, match) { - -// Produce the next token, also looking for programming errors. - - if (indent) { - -// If indentation checking was requested, then inspect all of the line breakings. -// The var statement is tricky because the names might be aligned or not. We -// look at the first line break after the var to determine the programmer's -// intention. - - if (var_mode && next_token.line !== token.line) { - if ((var_mode !== indent || !next_token.edge) && - next_token.from === indent.at - - (next_token.edge ? option.indent : 0)) { - var dent = indent; - for (;;) { - dent.at -= option.indent; - if (dent === var_mode) { - break; - } - dent = dent.was; - } - dent.open = false; - } - var_mode = null; - } - if (next_token.id === '?' && indent.mode === ':' && - token.line !== next_token.line) { - indent.at -= option.indent; - } - if (indent.open) { - -// If the token is an edge. - - if (next_token.edge) { - if (next_token.edge === 'label') { - expected_at(1); - } else if (next_token.edge === 'case' || indent.mode === 'statement') { - expected_at(indent.at - option.indent); - } else if (indent.mode !== 'array' || next_token.line !== token.line) { - expected_at(indent.at); - } - -// If the token is not an edge, but is the first token on the line. - - } else if (next_token.line !== token.line) { - if (next_token.from < indent.at + (indent.mode === - 'expression' ? 0 : option.indent)) { - expected_at(indent.at + option.indent); - } - indent.wrap = true; - } - } else if (next_token.line !== token.line) { - if (next_token.edge) { - expected_at(indent.at); - } else { - indent.wrap = true; - if (indent.mode === 'statement' || indent.mode === 'var') { - expected_at(indent.at + option.indent); - } else if (next_token.from < indent.at + (indent.mode === - 'expression' ? 0 : option.indent)) { - expected_at(indent.at + option.indent); - } - } - } - } - - switch (token.id) { - case '(number)': - if (next_token.id === '.') { - warn('trailing_decimal_a'); - } - break; - case '-': - if (next_token.id === '-' || next_token.id === '--') { - warn('confusing_a'); - } - break; - case '+': - if (next_token.id === '+' || next_token.id === '++') { - warn('confusing_a'); - } - break; - } - if (token.id === '(string)' || token.identifier) { - anonname = token.string; - } - - if (id && next_token.id !== id) { - if (match) { - warn('expected_a_b_from_c_d', next_token, id, - match.id, match.line, artifact()); - } else if (!next_token.identifier || next_token.string !== id) { - warn('expected_a_b', next_token, id, artifact()); - } - } - prev_token = token; - token = next_token; - next_token = lookahead.shift() || lex.token(); - } - - - function advance_identifier(string) { - if (next_token.identifier && next_token.string === string) { - advance(); - } else { - warn('expected_a_b', next_token, string, artifact()); - } - } - - - function do_safe() { - if (option.adsafe) { - option.safe = true; - } - if (option.safe) { - option.browser = - option['continue'] = - option.css = - option.debug = - option.devel = - option.evil = - option.forin = - option.newcap = - option.nomen = - option.on = - option.rhino = - option.sloppy = - option.sub = - option.undef = - option.windows = false; - - - delete predefined.Array; - delete predefined.Date; - delete predefined.Function; - delete predefined.Object; - delete predefined['eval']; - - add_to_predefined({ - ADSAFE: false, - lib: false - }); - } - } - - - function do_globals() { - var name, writeable; - for (;;) { - if (next_token.id !== '(string)' && !next_token.identifier) { - return; - } - name = next_token.string; - advance(); - writeable = false; - if (next_token.id === ':') { - advance(':'); - switch (next_token.id) { - case 'true': - writeable = predefined[name] !== false; - advance('true'); - break; - case 'false': - advance('false'); - break; - default: - stop('unexpected_a'); - } - } - predefined[name] = writeable; - if (next_token.id !== ',') { - return; - } - advance(','); - } - } - - - function do_jslint() { - var name, value; - while (next_token.id === '(string)' || next_token.identifier) { - name = next_token.string; - if (!allowed_option[name]) { - stop('unexpected_a'); - } - advance(); - if (next_token.id !== ':') { - stop('expected_a_b', next_token, ':', artifact()); - } - advance(':'); - if (typeof allowed_option[name] === 'number') { - value = next_token.number; - if (value > allowed_option[name] || value <= 0 || - Math.floor(value) !== value) { - stop('expected_small_a'); - } - option[name] = value; - } else { - if (next_token.id === 'true') { - option[name] = true; - } else if (next_token.id === 'false') { - option[name] = false; - } else { - stop('unexpected_a'); - } - } - advance(); - if (next_token.id === ',') { - advance(','); - } - } - assume(); - } - - - function do_properties() { - var name; - option.properties = true; - for (;;) { - if (next_token.id !== '(string)' && !next_token.identifier) { - return; - } - name = next_token.string; - advance(); - if (next_token.id === ':') { - for (;;) { - advance(); - if (next_token.id !== '(string)' && !next_token.identifier) { - break; - } - } - } - property[name] = 0; - if (next_token.id !== ',') { - return; - } - advance(','); - } - } - - - directive = function directive() { - var command = this.id, - old_comments_off = comments_off, - old_indent = indent; - comments_off = true; - indent = null; - if (next_token.line === token.line && next_token.from === token.thru) { - warn('missing_space_a_b', next_token, artifact(token), artifact()); - } - if (lookahead.length > 0) { - warn('unexpected_a', this); - } - switch (command) { - case '/*properties': - case '/*property': - case '/*members': - case '/*member': - do_properties(); - break; - case '/*jslint': - if (option.safe) { - warn('adsafe_a', this); - } - do_jslint(); - break; - case '/*globals': - case '/*global': - if (option.safe) { - warn('adsafe_a', this); - } - do_globals(); - break; - default: - stop('unexpected_a', this); - } - comments_off = old_comments_off; - advance('*/'); - indent = old_indent; - }; - - -// Indentation intention - - function edge(mode) { - next_token.edge = indent ? indent.open && (mode || 'edge') : ''; - } - - - function step_in(mode) { - var open; - if (typeof mode === 'number') { - indent = { - at: +mode, - open: true, - was: indent - }; - } else if (!indent) { - indent = { - at: 1, - mode: 'statement', - open: true - }; - } else if (mode === 'statement') { - indent = { - at: indent.at, - open: true, - was: indent - }; - } else { - open = mode === 'var' || next_token.line !== token.line; - indent = { - at: (open || mode === 'control' - ? indent.at + option.indent - : indent.at) + (indent.wrap ? option.indent : 0), - mode: mode, - open: open, - was: indent - }; - if (mode === 'var' && open) { - var_mode = indent; - } - } - } - - function step_out(id, symbol) { - if (id) { - if (indent && indent.open) { - indent.at -= option.indent; - edge(); - } - advance(id, symbol); - } - if (indent) { - indent = indent.was; - } - } - -// Functions for conformance of whitespace. - - function one_space(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && !option.white && - (token.line !== right.line || - token.thru + 1 !== right.from)) { - warn('expected_space_a_b', right, artifact(token), artifact(right)); - } - } - - function one_space_only(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && (left.line !== right.line || - (!option.white && left.thru + 1 !== right.from))) { - warn('expected_space_a_b', right, artifact(left), artifact(right)); - } - } - - function no_space(left, right) { - left = left || token; - right = right || next_token; - if ((!option.white || xmode === 'styleproperty' || xmode === 'style') && - left.thru !== right.from && left.line === right.line) { - warn('unexpected_space_a_b', right, artifact(left), artifact(right)); - } - } - - function no_space_only(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && (left.line !== right.line || - (!option.white && left.thru !== right.from))) { - warn('unexpected_space_a_b', right, artifact(left), artifact(right)); - } - } - - function spaces(left, right) { - if (!option.white) { - left = left || token; - right = right || next_token; - if (left.thru === right.from && left.line === right.line) { - warn('missing_space_a_b', right, artifact(left), artifact(right)); - } - } - } - - function comma() { - if (next_token.id !== ',') { - warn_at('expected_a_b', token.line, token.thru, ',', artifact()); - } else { - if (!option.white) { - no_space_only(); - } - advance(','); - spaces(); - } - } - - - function semicolon() { - if (next_token.id !== ';') { - warn_at('expected_a_b', token.line, token.thru, ';', artifact()); - } else { - if (!option.white) { - no_space_only(); - } - advance(';'); - if (semicolon_coda[next_token.id] !== true) { - spaces(); - } - } - } - - function use_strict() { - if (next_token.string === 'use strict') { - if (strict_mode) { - warn('unnecessary_use'); - } - edge(); - advance(); - semicolon(); - strict_mode = true; - option.undef = false; - return true; - } - return false; - } - - - function are_similar(a, b) { - if (a === b) { - return true; - } - if (Array.isArray(a)) { - if (Array.isArray(b) && a.length === b.length) { - var i; - for (i = 0; i < a.length; i += 1) { - if (!are_similar(a[i], b[i])) { - return false; - } - } - return true; - } - return false; - } - if (Array.isArray(b)) { - return false; - } - if (a.id === '(number)' && b.id === '(number)') { - return a.number === b.number; - } - if (a.arity === b.arity && a.string === b.string) { - switch (a.arity) { - case 'prefix': - case 'suffix': - case undefined: - return a.id === b.id && are_similar(a.first, b.first); - case 'infix': - return are_similar(a.first, b.first) && - are_similar(a.second, b.second); - case 'ternary': - return are_similar(a.first, b.first) && - are_similar(a.second, b.second) && - are_similar(a.third, b.third); - case 'function': - case 'regexp': - return false; - default: - return true; - } - } else { - if (a.id === '.' && b.id === '[' && b.arity === 'infix') { - return a.second.string === b.second.string && b.second.id === '(string)'; - } - if (a.id === '[' && a.arity === 'infix' && b.id === '.') { - return a.second.string === b.second.string && a.second.id === '(string)'; - } - } - return false; - } - - -// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it -// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is -// like .nud except that it is only used on the first token of a statement. -// Having .fud makes it much easier to define statement-oriented languages like -// JavaScript. I retained Pratt's nomenclature. - -// .nud Null denotation -// .fud First null denotation -// .led Left denotation -// lbp Left binding power -// rbp Right binding power - -// They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - -// rbp is the right binding power. -// initial indicates that this is the first expression of a statement. - - var left; - if (next_token.id === '(end)') { - stop('unexpected_a', token, next_token.id); - } - advance(); - if (option.safe && scope[token.string] && - scope[token.string] === global_scope[token.string] && - (next_token.id !== '(' && next_token.id !== '.')) { - warn('adsafe_a', token); - } - if (initial) { - anonname = 'anonymous'; - funct['(verb)'] = token.string; - } - if (initial === true && token.fud) { - left = token.fud(); - } else { - if (token.nud) { - left = token.nud(); - } else { - if (next_token.id === '(number)' && token.id === '.') { - warn('leading_decimal_a', token, artifact()); - advance(); - return token; - } - stop('expected_identifier_a', token, token.id); - } - while (rbp < next_token.lbp) { - advance(); - if (token.led) { - left = token.led(left); - } else { - stop('expected_operator_a', token, token.id); - } - } - } - return left; - } - - -// Functional constructors for making the symbols that will be inherited by -// tokens. - - function symbol(s, p) { - var x = syntax[s]; - if (!x || typeof x !== 'object') { - syntax[s] = x = { - id: s, - lbp: p || 0, - string: s - }; - } - return x; - } - - function postscript(x) { - x.postscript = true; - return x; - } - - function ultimate(s) { - var x = symbol(s, 0); - x.from = 1; - x.thru = 1; - x.line = 0; - x.edge = 'edge'; - s.string = s; - return postscript(x); - } - - - function stmt(s, f) { - var x = symbol(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - function labeled_stmt(s, f) { - var x = stmt(s, f); - x.labeled = true; - } - - function disrupt_stmt(s, f) { - var x = stmt(s, f); - x.disrupt = true; - } - - - function reserve_name(x) { - var c = x.id.charAt(0); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - x.identifier = x.reserved = true; - } - return x; - } - - - function prefix(s, f) { - var x = symbol(s, 150); - reserve_name(x); - x.nud = typeof f === 'function' - ? f - : function () { - if (s === 'typeof') { - one_space(); - } else { - no_space_only(); - } - this.first = expression(150); - this.arity = 'prefix'; - if (this.id === '++' || this.id === '--') { - if (!option.plusplus) { - warn('unexpected_a', this); - } else if ((!this.first.identifier || this.first.reserved) && - this.first.id !== '.' && this.first.id !== '[') { - warn('bad_operand', this); - } - } - return this; - }; - return x; - } - - - function type(s, t, nud) { - var x = symbol(s); - x.arity = t; - if (nud) { - x.nud = nud; - } - return x; - } - - - function reserve(s, f) { - var x = symbol(s); - x.identifier = x.reserved = true; - if (typeof f === 'function') { - x.nud = f; - } - return x; - } - - - function constant(name) { - var x = reserve(name); - x.string = name; - x.nud = return_this; - return x; - } - - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === 'function') { - v(this); - } - return this; - }); - } - - - function infix(s, p, f, w) { - var x = symbol(s, p); - reserve_name(x); - x.led = function (left) { - this.arity = 'infix'; - if (!w) { - spaces(prev_token, token); - spaces(); - } - if (!option.bitwise && this.bitwise) { - warn('unexpected_a', this); - } - if (typeof f === 'function') { - return f(left, this); - } - this.first = left; - this.second = expression(p); - return this; - }; - return x; - } - - function expected_relation(node, message) { - if (node.assign) { - warn(message || bundle.conditional_assignment, node); - } - return node; - } - - function expected_condition(node, message) { - switch (node.id) { - case '[': - case '-': - if (node.arity !== 'infix') { - warn(message || bundle.weird_condition, node); - } - break; - case 'false': - case 'function': - case 'Infinity': - case 'NaN': - case 'null': - case 'true': - case 'undefined': - case 'void': - case '(number)': - case '(regexp)': - case '(string)': - case '{': - warn(message || bundle.weird_condition, node); - break; - case '(': - if (node.first.id === '.' && numbery[node.first.second.string] === true) { - warn(message || bundle.weird_condition, node); - } - break; - } - return node; - } - - function check_relation(node) { - switch (node.arity) { - case 'prefix': - switch (node.id) { - case '{': - case '[': - warn('unexpected_a', node); - break; - case '!': - warn('confusing_a', node); - break; - } - break; - case 'function': - case 'regexp': - warn('unexpected_a', node); - break; - default: - if (node.id === 'NaN') { - warn('isNaN', node); - } - } - return node; - } - - - function relation(s, eqeq) { - return infix(s, 100, function (left, that) { - check_relation(left); - if (eqeq && !option.eqeq) { - warn('expected_a_b', that, eqeq, that.id); - } - var right = expression(100); - if (are_similar(left, right) || - ((left.id === '(string)' || left.id === '(number)') && - (right.id === '(string)' || right.id === '(number)'))) { - warn('weird_relation', that); - } - that.first = left; - that.second = check_relation(right); - return that; - }); - } - - - function assignop(s, op) { - var x = infix(s, 20, function (left, that) { - var l; - that.first = left; - if (left.identifier) { - if (scope[left.string]) { - if (scope[left.string].writeable === false) { - warn('read_only', left); - } - } else { - stop('read_only'); - } - if (funct['(params)']) { - funct['(params)'].forEach(function (value) { - if (value.string === left.string) { - value.assign = true; - } - }); - } - } else if (option.safe) { - l = left; - do { - if (typeof predefined[l.string] === 'boolean') { - warn('adsafe_a', l); - } - l = l.first; - } while (l); - } - if (left === syntax['function']) { - warn('identifier_function', token); - } - if (left.id === '.' || left.id === '[') { - if (!left.first || left.first.string === 'arguments') { - warn('bad_assignment', that); - } - } else if (left.identifier) { - if (!left.reserved && funct[left.string] === 'exception') { - warn('assign_exception', left); - } - } else { - warn('bad_assignment', that); - } - that.second = expression(19); - if (that.id === '=' && are_similar(that.first, that.second)) { - warn('weird_assignment', that); - } - return that; - }); - x.assign = true; - if (op) { - if (syntax[op].bitwise) { - x.bitwise = true; - } - } - return x; - } - - - function bitwise(s, p) { - var x = infix(s, p, 'number'); - x.bitwise = true; - return x; - } - - - function suffix(s) { - var x = symbol(s, 150); - x.led = function (left) { - no_space_only(prev_token, token); - if (!option.plusplus) { - warn('unexpected_a', this); - } else if ((!left.identifier || left.reserved) && - left.id !== '.' && left.id !== '[') { - warn('bad_operand', this); - } - this.first = left; - this.arity = 'suffix'; - return this; - }; - return x; - } - - - function optional_identifier() { - if (next_token.identifier) { - advance(); - if (option.safe && banned[token.string]) { - warn('adsafe_a', token); - } else if (token.reserved && !option.es5) { - warn('expected_identifier_a_reserved', token); - } - return token.string; - } - } - - - function identifier() { - var i = optional_identifier(); - if (!i) { - stop(token.id === 'function' && next_token.id === '(' - ? 'name_function' - : 'expected_identifier_a'); - } - return i; - } - - - function statement() { - - var label, old_scope = scope, the_statement; - -// We don't like the empty statement. - - if (next_token.id === ';') { - warn('unexpected_a'); - semicolon(); - return; - } - -// Is this a labeled statement? - - if (next_token.identifier && !next_token.reserved && peek().id === ':') { - edge('label'); - label = next_token; - advance(); - advance(':'); - scope = Object.create(old_scope); - add_label(label, 'label'); - if (next_token.labeled !== true || funct === global_funct) { - stop('unexpected_label_a', label); - } else if (jx.test(label.string + ':')) { - warn('url', label); - } - next_token.label = label; - } - -// Parse the statement. - - if (token.id !== 'else') { - edge(); - } - step_in('statement'); - the_statement = expression(0, true); - if (the_statement) { - -// Look for the final semicolon. - - if (the_statement.arity === 'statement') { - if (the_statement.id === 'switch' || - (the_statement.block && the_statement.id !== 'do')) { - spaces(); - } else { - semicolon(); - } - } else { - -// If this is an expression statement, determine if it is acceptable. -// We do not like -// new Blah(); -// statments. If it is to be used at all, new should only be used to make -// objects, not side effects. The expression statements we do like do -// assignment or invocation or delete. - - if (the_statement.id === '(') { - if (the_statement.first.id === 'new') { - warn('bad_new'); - } - } else if (!the_statement.assign && - the_statement.id !== 'delete' && - the_statement.id !== '++' && - the_statement.id !== '--') { - warn('assignment_function_expression', token); - } - semicolon(); - } - } - step_out(); - scope = old_scope; - return the_statement; - } - - - function statements() { - var array = [], disruptor, the_statement; - -// A disrupt statement may not be followed by any other statement. -// If the last statement is disrupt, then the sequence is disrupt. - - while (next_token.postscript !== true) { - if (next_token.id === ';') { - warn('unexpected_a', next_token); - semicolon(); - } else { - if (next_token.string === 'use strict') { - if ((!node_js && xmode !== 'script') || funct !== global_funct || array.length > 0) { - warn('function_strict'); - } - use_strict(); - } - if (disruptor) { - warn('unreachable_a_b', next_token, next_token.string, - disruptor.string); - disruptor = null; - } - the_statement = statement(); - if (the_statement) { - array.push(the_statement); - if (the_statement.disrupt) { - disruptor = the_statement; - array.disrupt = true; - } - } - } - } - return array; - } - - - function block(ordinary) { - -// array block is array sequence of statements wrapped in braces. -// ordinary is false for function bodies and try blocks. -// ordinary is true for if statements, while, etc. - - var array, - curly = next_token, - old_in_block = in_block, - old_scope = scope, - old_strict_mode = strict_mode; - - in_block = ordinary; - scope = Object.create(scope); - spaces(); - if (next_token.id === '{') { - advance('{'); - step_in(); - if (!ordinary && !use_strict() && !old_strict_mode && - !option.sloppy && funct['(context)'] === global_funct) { - warn('missing_use_strict'); - } - array = statements(); - strict_mode = old_strict_mode; - step_out('}', curly); - } else if (!ordinary) { - stop('expected_a_b', next_token, '{', artifact()); - } else { - warn('expected_a_b', next_token, '{', artifact()); - array = [statement()]; - array.disrupt = array[0].disrupt; - } - funct['(verb)'] = null; - scope = old_scope; - in_block = old_in_block; - if (ordinary && array.length === 0) { - warn('empty_block'); - } - return array; - } - - - function tally_property(name) { - if (option.properties && typeof property[name] !== 'number') { - warn('unexpected_property_a', token, name); - } - if (typeof property[name] === 'number') { - property[name] += 1; - } else { - property[name] = 1; - } - } - - -// ECMAScript parser - - syntax['(identifier)'] = { - id: '(identifier)', - lbp: 0, - identifier: true, - nud: function () { - var name = this.string, - variable = scope[name], - site, - writeable; - -// If the variable is not in scope, then we may have an undeclared variable. -// Check the predefined list. If it was predefined, create the global -// variable. - - if (typeof variable !== 'object') { - writeable = predefined[name]; - if (typeof writeable === 'boolean') { - global_scope[name] = variable = { - string: name, - writeable: writeable, - funct: global_funct - }; - global_funct[name] = 'var'; - -// But if the variable is not in scope, and is not predefined, and if we are not -// in the global scope, then we have an undefined variable error. - - } else { - if (!option.undef) { - warn('used_before_a', token); - } - scope[name] = variable = { - string: name, - writeable: true, - funct: funct - }; - funct[name] = 'undef'; - } - - } - site = variable.funct; - -// The name is in scope and defined in the current function. - - if (funct === site) { - -// Change 'unused' to 'var', and reject labels. - - switch (funct[name]) { - case 'becoming': - warn('unexpected_a', token); - funct[name] = 'var'; - break; - case 'unused': - funct[name] = 'var'; - break; - case 'unparam': - funct[name] = 'parameter'; - break; - case 'unction': - funct[name] = 'function'; - break; - case 'label': - warn('a_label', token, name); - break; - } - -// If the name is already defined in the current -// function, but not as outer, then there is a scope error. - - } else { - switch (funct[name]) { - case 'closure': - case 'function': - case 'var': - case 'unused': - warn('a_scope', token, name); - break; - case 'label': - warn('a_label', token, name); - 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. - - switch (site[name]) { - case 'becoming': - case 'closure': - case 'function': - case 'parameter': - case 'unction': - case 'unused': - case 'var': - site[name] = 'closure'; - funct[name] = site === global_funct - ? 'global' - : 'outer'; - break; - case 'unparam': - site[name] = 'parameter'; - funct[name] = 'outer'; - break; - case 'undef': - funct[name] = 'undef'; - break; - case 'label': - warn('a_label', token, name); - break; - } - } - } - return this; - }, - led: function () { - stop('expected_operator_a'); - } - }; - -// Build the syntax table by declaring the syntactic elements. - - type('(array)', 'array'); - type('(color)', 'color'); - type('(function)', 'function'); - type('(number)', 'number', return_this); - type('(object)', 'object'); - type('(string)', 'string', return_this); - type('(boolean)', 'boolean', return_this); - type('(range)', 'range'); - type('(regexp)', 'regexp', return_this); - - ultimate('(begin)'); - ultimate('(end)'); - ultimate('(error)'); - postscript(symbol(''); - postscript(symbol('}')); - symbol(')'); - symbol(']'); - postscript(symbol('"')); - postscript(symbol('\'')); - symbol(';'); - symbol(':'); - symbol(','); - symbol('#'); - symbol('@'); - symbol('*/'); - postscript(reserve('case')); - reserve('catch'); - postscript(reserve('default')); - reserve('else'); - reserve('finally'); - - reservevar('arguments', function (x) { - if (strict_mode && funct === global_funct) { - warn('strict', x); - } else if (option.safe) { - warn('adsafe_a', x); - } - funct['(arguments)'] = true; - }); - reservevar('eval', function (x) { - if (option.safe) { - warn('adsafe_a', x); - } - }); - constant('false', 'boolean'); - constant('Infinity', 'number'); - constant('NaN', 'number'); - constant('null', ''); - reservevar('this', function (x) { - if (option.safe) { - warn('adsafe_a', x); - } else if (strict_mode && funct['(token)'] && - (funct['(token)'].arity === 'statement' && - funct['(name)'].charAt(0) > 'Z')) { - warn('strict', x); - } - }); - constant('true', 'boolean'); - constant('undefined', ''); - - infix('?', 30, function (left, that) { - step_in('?'); - that.first = expected_condition(expected_relation(left)); - that.second = expression(0); - spaces(); - step_out(); - var colon = next_token; - advance(':'); - step_in(':'); - spaces(); - that.third = expression(10); - that.arity = 'ternary'; - if (are_similar(that.second, that.third)) { - warn('weird_ternary', colon); - } else if (are_similar(that.first, that.second)) { - warn('use_or', that); - } - step_out(); - return that; - }); - - infix('||', 40, function (left, that) { - function paren_check(that) { - if (that.id === '&&' && !that.paren) { - warn('and', that); - } - return that; - } - - that.first = paren_check(expected_condition(expected_relation(left))); - that.second = paren_check(expected_relation(expression(40))); - if (are_similar(that.first, that.second)) { - warn('weird_condition', that); - } - return that; - }); - - infix('&&', 50, function (left, that) { - that.first = expected_condition(expected_relation(left)); - that.second = expected_relation(expression(50)); - if (are_similar(that.first, that.second)) { - warn('weird_condition', that); - } - return that; - }); - - prefix('void', function () { - this.first = expression(0); - this.arity = 'prefix'; - if (option.es5) { - warn('expected_a_b', this, 'undefined', 'void'); - } else if (this.first.number !== 0) { - warn('expected_a_b', this.first, '0', artifact(this.first)); - } - return this; - }); - - bitwise('|', 70); - bitwise('^', 80); - bitwise('&', 90); - - relation('==', '==='); - relation('==='); - relation('!=', '!=='); - relation('!=='); - relation('<'); - relation('>'); - relation('<='); - relation('>='); - - bitwise('<<', 120); - bitwise('>>', 120); - bitwise('>>>', 120); - - infix('in', 120, function (left, that) { - warn('infix_in', that); - that.left = left; - that.right = expression(130); - return that; - }); - infix('instanceof', 120); - infix('+', 130, function (left, that) { - if (left.id === '(number)') { - if (left.number === 0) { - warn('unexpected_a', left, '0'); - } - } else if (left.id === '(string)') { - if (left.string === '') { - warn('expected_a_b', left, 'String', '\'\''); - } - } - var right = expression(130); - if (right.id === '(number)') { - if (right.number === 0) { - warn('unexpected_a', right, '0'); - } - } else if (right.id === '(string)') { - if (right.string === '') { - warn('expected_a_b', right, 'String', '\'\''); - } - } - if (left.id === right.id) { - if (left.id === '(string)' || left.id === '(number)') { - if (left.id === '(string)') { - left.string += right.string; - if (jx.test(left.string)) { - warn('url', left); - } - } else { - left.number += right.number; - } - left.thru = right.thru; - return left; - } - } - that.first = left; - that.second = right; - return that; - }); - prefix('+', 'num'); - prefix('+++', function () { - warn('confusing_a', token); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('+++', 130, function (left) { - warn('confusing_a', token); - this.first = left; - this.second = expression(130); - return this; - }); - infix('-', 130, function (left, that) { - if ((left.id === '(number)' && left.number === 0) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(130); - if ((right.id === '(number)' && right.number === 0) || right.id === '(string)') { - warn('unexpected_a', right); - } - if (left.id === right.id && left.id === '(number)') { - left.number -= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; - }); - prefix('-'); - prefix('---', function () { - warn('confusing_a', token); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('---', 130, function (left) { - warn('confusing_a', token); - this.first = left; - this.second = expression(130); - return this; - }); - infix('*', 140, function (left, that) { - if ((left.id === '(number)' && (left.number === 0 || left.number === 1)) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(140); - if ((right.id === '(number)' && (right.number === 0 || right.number === 1)) || right.id === '(string)') { - warn('unexpected_a', right); - } - if (left.id === right.id && left.id === '(number)') { - left.number *= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; - }); - infix('/', 140, function (left, that) { - if ((left.id === '(number)' && left.number === 0) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(140); - if ((right.id === '(number)' && (right.number === 0 || right.number === 1)) || right.id === '(string)') { - warn('unexpected_a', right); - } - if (left.id === right.id && left.id === '(number)') { - left.number /= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; - }); - infix('%', 140, function (left, that) { - if ((left.id === '(number)' && (left.number === 0 || left.number === 1)) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(140); - if ((right.id === '(number)' && right.number === 0) || right.id === '(string)') { - warn('unexpected_a', right); - } - if (left.id === right.id && left.id === '(number)') { - left.number %= right.number; - left.thru = right.thru; - return left; - } - that.first = left; - that.second = right; - return that; - }); - - suffix('++'); - prefix('++'); - - suffix('--'); - prefix('--'); - prefix('delete', function () { - one_space(); - var p = expression(0); - if (!p || (p.id !== '.' && p.id !== '[')) { - warn('deleted'); - } - this.first = p; - return this; - }); - - - prefix('~', function () { - no_space_only(); - if (!option.bitwise) { - warn('unexpected_a', this); - } - expression(150); - return this; - }); - prefix('!', function () { - no_space_only(); - this.first = expected_condition(expression(150)); - this.arity = 'prefix'; - if (bang[this.first.id] === true || this.first.assign) { - warn('confusing_a', this); - } - return this; - }); - prefix('typeof', null); - prefix('new', function () { - one_space(); - var c = expression(160), n, p, v; - this.first = c; - if (c.id !== 'function') { - if (c.identifier) { - switch (c.string) { - case 'Object': - warn('use_object', token); - break; - case 'Array': - if (next_token.id === '(') { - p = next_token; - p.first = this; - advance('('); - if (next_token.id !== ')') { - n = expression(0); - p.second = [n]; - if (n.id !== '(number)' || next_token.id === ',') { - warn('use_array', p); - } - while (next_token.id === ',') { - advance(','); - p.second.push(expression(0)); - } - } else { - warn('use_array', token); - } - advance(')', p); - return p; - } - warn('use_array', token); - break; - case 'Number': - case 'String': - case 'Boolean': - case 'Math': - case 'JSON': - warn('not_a_constructor', c); - break; - case 'Function': - if (!option.evil) { - warn('function_eval'); - } - break; - case 'Date': - case 'RegExp': - case 'this': - break; - default: - if (c.id !== 'function') { - v = c.string.charAt(0); - if (!option.newcap && (v < 'A' || v > 'Z')) { - warn('constructor_name_a', token); - } - } - } - } else { - if (c.id !== '.' && c.id !== '[' && c.id !== '(') { - warn('bad_constructor', token); - } - } - } else { - warn('weird_new', this); - } - if (next_token.id !== '(') { - warn('missing_a', next_token, '()'); - } - return this; - }); - - infix('(', 160, function (left, that) { - var p; - if (indent && indent.mode === 'expression') { - no_space(prev_token, token); - } else { - no_space_only(prev_token, token); - } - if (!left.immed && left.id === 'function') { - warn('wrap_immediate'); - } - p = []; - if (left.identifier) { - if (left.string.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if (left.string !== 'Number' && left.string !== 'String' && - left.string !== 'Boolean' && left.string !== 'Date') { - if (left.string === 'Math' || left.string === 'JSON') { - warn('not_a_function', left); - } else if (left.string === 'Object') { - warn('use_object', token); - } else if (left.string === 'Array' || !option.newcap) { - warn('missing_a', left, 'new'); - } - } - } - } else if (left.id === '.') { - if (option.safe && left.first.string === 'Math' && - left.second === 'random') { - warn('adsafe_a', left); - } else if (left.second.string === 'split' && - left.first.id === '(string)') { - warn('use_array', left.second); - } - } - step_in(); - if (next_token.id !== ')') { - no_space(); - for (;;) { - edge(); - p.push(expression(10)); - if (next_token.id !== ',') { - break; - } - comma(); - } - } - no_space(); - step_out(')', that); - if (typeof left === 'object') { - if (left.string === 'parseInt' && p.length === 1) { - warn('radix', left); - } - if (!option.evil) { - if (left.string === 'eval' || left.string === 'Function' || - left.string === 'execScript') { - warn('evil', left); - } else if (p[0] && p[0].id === '(string)' && - (left.string === 'setTimeout' || - left.string === 'setInterval')) { - warn('implied_evil', left); - } - } - if (!left.identifier && left.id !== '.' && left.id !== '[' && - left.id !== '(' && left.id !== '&&' && left.id !== '||' && - left.id !== '?') { - warn('bad_invocation', left); - } - } - that.first = left; - that.second = p; - return that; - }, true); - - prefix('(', function () { - step_in('expression'); - no_space(); - edge(); - if (next_token.id === 'function') { - next_token.immed = true; - } - var value = expression(0); - value.paren = true; - no_space(); - step_out(')', this); - if (value.id === 'function') { - switch (next_token.id) { - case '(': - warn('move_invocation'); - break; - case '.': - case '[': - warn('unexpected_a'); - break; - default: - warn('bad_wrap', this); - } - } - return value; - }); - - infix('.', 170, function (left, that) { - no_space(prev_token, token); - no_space(); - var name = identifier(); - if (typeof name === 'string') { - tally_property(name); - } - that.first = left; - that.second = token; - if (left && left.string === 'arguments' && - (name === 'callee' || name === 'caller')) { - warn('avoid_a', left, 'arguments.' + name); - } else if (!option.evil && left && left.string === 'document' && - (name === 'write' || name === 'writeln')) { - warn('write_is_wrong', left); - } else if (!option.stupid && name.indexOf('Sync') > 0) { - warn('sync_a', token); - } else if (option.adsafe) { - if (!adsafe_top && left.string === 'ADSAFE') { - if (name === 'id' || name === 'lib') { - warn('adsafe_a', that); - } else if (name === 'go') { - if (xmode !== 'script') { - warn('adsafe_a', that); - } else if (adsafe_went || next_token.id !== '(' || - peek(0).id !== '(string)' || - peek(0).string !== adsafe_id || - peek(1).id !== ',') { - stop('adsafe_a', that, 'go'); - } - adsafe_went = true; - adsafe_may = false; - } - } - adsafe_top = false; - } - if (!option.evil && (name === 'eval' || name === 'execScript')) { - warn('evil'); - } else if (option.safe) { - for (;;) { - if (banned[name] === true) { - warn('adsafe_a', token, name); - } - if (typeof predefined[left.string] !== 'boolean' || //// check for writeable - next_token.id === '(') { - break; - } - if (next_token.id !== '.') { - warn('adsafe_a', that); - break; - } - advance('.'); - token.first = that; - token.second = name; - that = token; - name = identifier(); - if (typeof name === 'string') { - tally_property(name); - } - } - } - return that; - }, true); - - infix('[', 170, function (left, that) { - var e, s; - no_space_only(prev_token, token); - no_space(); - step_in(); - edge(); - e = expression(0); - switch (e.id) { - case '(number)': - if (e.id === '(number)' && left.id === 'arguments') { - warn('use_param', left); - } - break; - case '(string)': - if (option.safe && (banned[e.string] || - e.string.charAt(0) === '_' || e.string.slice(-1) === '_')) { - warn('adsafe_subscript_a', e); - } else if (!option.evil && - (e.string === 'eval' || e.string === 'execScript')) { - warn('evil', e); - } else if (!option.sub && ix.test(e.string)) { - s = syntax[e.string]; - if (!s || !s.reserved) { - warn('subscript', e); - } - } - tally_property(e.string); - break; - default: - if (option.safe) { - if ((e.id !== '+' || e.arity !== 'prefix') && - e.id !== '-' && e.id !== '*') { - warn('adsafe_subscript_a', e); - } - } - } - step_out(']', that); - no_space(prev_token, token); - that.first = left; - that.second = e; - return that; - }, true); - - prefix('[', function () { - this.arity = 'prefix'; - this.first = []; - step_in('array'); - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - warn('unexpected_a', next_token); - advance(','); - } - if (next_token.id === ']') { - break; - } - indent.wrap = false; - edge(); - this.first.push(expression(10)); - if (next_token.id === ',') { - comma(); - if (next_token.id === ']' && !option.es5) { - warn('unexpected_a', token); - break; - } - } else { - break; - } - } - step_out(']', this); - return this; - }, 170); - - - function property_name() { - var id = optional_identifier(true); - if (!id) { - if (next_token.id === '(string)') { - id = next_token.string; - if (option.safe) { - if (banned[id]) { - warn('adsafe_a'); - } else if (id.charAt(0) === '_' || - id.charAt(id.length - 1) === '_') { - warn('dangling_a'); - } - } - advance(); - } else if (next_token.id === '(number)') { - id = next_token.number.toString(); - advance(); - } - } - return id; - } - - - function function_params() { - var id, paren = next_token, params = []; - advance('('); - step_in(); - no_space(); - if (next_token.id === ')') { - no_space(); - step_out(')', paren); - return params; - } - for (;;) { - edge(); - id = identifier(); - params.push(token); - add_label(token, option.unparam ? 'parameter' : 'unparam'); - if (next_token.id === ',') { - comma(); - } else { - no_space(); - step_out(')', paren); - return params; - } - } - } - - - - function do_function(func, name) { - var old_funct = funct, - old_option = option, - old_scope = scope; - funct = { - '(name)' : name || '\'' + (anonname || '').replace(nx, sanitize) + '\'', - '(line)' : next_token.line, - '(context)' : old_funct, - '(breakage)' : 0, - '(loopage)' : 0, - '(scope)' : scope, - '(token)' : func - }; - option = Object.create(old_option); - scope = Object.create(old_scope); - functions.push(funct); - func.name = name; - if (name) { - add_label(func, 'function', name); - } - func.writeable = false; - func.first = funct['(params)'] = function_params(); - one_space(); - func.block = block(false); - if (funct['(arguments)']) { - func.first.forEach(function (value) { - if (value.assign) { - warn('parameter_arguments_a', value, value.string); - } - }); - } - funct = old_funct; - option = old_option; - scope = old_scope; - } - - - assignop('='); - assignop('+=', '+'); - assignop('-=', '-'); - assignop('*=', '*'); - assignop('/=', '/').nud = function () { - stop('slash_equal'); - }; - assignop('%=', '%'); - assignop('&=', '&'); - assignop('|=', '|'); - assignop('^=', '^'); - assignop('<<=', '<<'); - assignop('>>=', '>>'); - assignop('>>>=', '>>>'); - - - prefix('{', function () { - var get, i, j, name, p, set, seen = {}; - this.arity = 'prefix'; - this.first = []; - step_in(); - while (next_token.id !== '}') { - indent.wrap = false; - -// JSLint recognizes the ES5 extension for get/set in object literals, -// but requires that they be used in pairs. - - edge(); - if (next_token.string === 'get' && peek().id !== ':') { - if (!option.es5) { - warn('es5'); - } - get = next_token; - advance('get'); - one_space_only(); - name = next_token; - i = property_name(); - if (!i) { - stop('missing_property'); - } - get.string = ''; - do_function(get); - if (funct['(loopage)']) { - warn('function_loop', get); - } - p = get.first; - if (p && p.length) { - warn('parameter_a_get_b', p[0], p[0].string, i); - } - comma(); - set = next_token; - spaces(); - edge(); - advance('set'); - set.string = ''; - one_space_only(); - j = property_name(); - if (i !== j) { - stop('expected_a_b', token, i, j || next_token.string); - } - do_function(set); - if (set.block.length === 0) { - warn('missing_a', token, 'throw'); - } - p = set.first; - if (!p || p.length !== 1) { - stop('parameter_set_a', set, 'value'); - } else if (p[0].string !== 'value') { - stop('expected_a_b', p[0], 'value', p[0].string); - } - name.first = [get, set]; - } else { - name = next_token; - i = property_name(); - if (typeof i !== 'string') { - stop('missing_property'); - } - advance(':'); - spaces(); - name.first = expression(10); - } - this.first.push(name); - if (seen[i] === true) { - warn('duplicate_a', next_token, i); - } - seen[i] = true; - tally_property(i); - if (next_token.id !== ',') { - break; - } - for (;;) { - comma(); - if (next_token.id !== ',') { - break; - } - warn('unexpected_a', next_token); - } - if (next_token.id === '}' && !option.es5) { - warn('unexpected_a', token); - } - } - step_out('}', this); - return this; - }); - - stmt('{', function () { - warn('statement_block'); - this.arity = 'statement'; - this.block = statements(); - this.disrupt = this.block.disrupt; - advance('}', this); - return this; - }); - - stmt('/*global', directive); - stmt('/*globals', directive); - stmt('/*jslint', directive); - stmt('/*member', directive); - stmt('/*members', directive); - stmt('/*property', directive); - stmt('/*properties', directive); - - stmt('var', function () { - -// JavaScript does not have block scope. It only has function scope. So, -// declaring a variable in a block can have unexpected consequences. - -// var.first will contain an array, the array containing name tokens -// and assignment tokens. - - var assign, id, name; - - if (funct['(vars)'] && !option.vars) { - warn('combine_var'); - } else if (funct !== global_funct) { - funct['(vars)'] = true; - } - this.arity = 'statement'; - this.first = []; - step_in('var'); - for (;;) { - name = next_token; - id = identifier(); - add_label(name, 'becoming'); - - if (next_token.id === '=') { - assign = next_token; - assign.first = name; - spaces(); - advance('='); - spaces(); - if (next_token.id === 'undefined') { - warn('unnecessary_initialize', token, id); - } - if (peek(0).id === '=' && next_token.identifier) { - stop('var_a_not'); - } - assign.second = expression(0); - assign.arity = 'infix'; - this.first.push(assign); - } else { - this.first.push(name); - } - if (funct[id] === 'becoming') { - funct[id] = 'unused'; - } - if (next_token.id !== ',') { - break; - } - comma(); - indent.wrap = false; - if (var_mode && next_token.line === token.line && - this.first.length === 1) { - var_mode = null; - indent.open = false; - indent.at -= option.indent; - } - spaces(); - edge(); - } - var_mode = null; - step_out(); - return this; - }); - - stmt('function', function () { - one_space(); - if (in_block) { - warn('function_block', token); - } - var name = next_token, id = identifier(); - add_label(name, 'unction'); - no_space(); - this.arity = 'statement'; - do_function(this, id); - if (next_token.id === '(' && next_token.line === token.line) { - stop('function_statement'); - } - return this; - }); - - prefix('function', function () { - if (!option.anon) { - one_space(); - } - var id = optional_identifier(); - if (id) { - no_space(); - } else { - id = ''; - } - do_function(this, id); - if (funct['(loopage)']) { - warn('function_loop'); - } - switch (next_token.id) { - case ';': - case '(': - case ')': - case ',': - case ']': - case '}': - case ':': - break; - case '.': - if (peek().string !== 'bind' || peek(1).id !== '(') { - warn('unexpected_a'); - } - break; - default: - stop('unexpected_a'); - } - this.arity = 'function'; - return this; - }); - - stmt('if', function () { - var paren = next_token; - one_space(); - advance('('); - step_in('control'); - no_space(); - edge(); - this.arity = 'statement'; - this.first = expected_condition(expected_relation(expression(0))); - no_space(); - step_out(')', paren); - one_space(); - this.block = block(true); - if (next_token.id === 'else') { - one_space(); - advance('else'); - one_space(); - this['else'] = next_token.id === 'if' || next_token.id === 'switch' - ? statement(true) - : block(true); - if (this['else'].disrupt && this.block.disrupt) { - this.disrupt = true; - } - } - return this; - }); - - stmt('try', function () { - -// try.first The catch variable -// try.second The catch clause -// try.third The finally clause -// try.block The try block - - var exception_variable, old_scope, paren; - if (option.adsafe) { - warn('adsafe_a', this); - } - one_space(); - this.arity = 'statement'; - this.block = block(false); - if (next_token.id === 'catch') { - one_space(); - advance('catch'); - one_space(); - paren = next_token; - advance('('); - step_in('control'); - no_space(); - edge(); - old_scope = scope; - scope = Object.create(old_scope); - exception_variable = next_token.string; - this.first = exception_variable; - if (!next_token.identifier) { - warn('expected_identifier_a', next_token); - } else { - add_label(next_token, 'exception'); - } - advance(); - no_space(); - step_out(')', paren); - one_space(); - this.second = block(false); - scope = old_scope; - } - if (next_token.id === 'finally') { - one_space(); - advance('finally'); - one_space(); - this.third = block(false); - } else if (!this.second) { - stop('expected_a_b', next_token, 'catch', artifact()); - } - return this; - }); - - labeled_stmt('while', function () { - one_space(); - var paren = next_token; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - step_in('control'); - no_space(); - edge(); - this.arity = 'statement'; - this.first = expected_relation(expression(0)); - if (this.first.id !== 'true') { - expected_condition(this.first, bundle.unexpected_a); - } - no_space(); - step_out(')', paren); - one_space(); - this.block = block(true); - if (this.block.disrupt) { - warn('strange_loop', prev_token); - } - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - reserve('with'); - - labeled_stmt('switch', function () { - -// switch.first the switch expression -// switch.second the array of cases. A case is 'case' or 'default' token: -// case.first the array of case expressions -// case.second the array of statements -// If all of the arrays of statements are disrupt, then the switch is disrupt. - - var cases = [], - old_in_block = in_block, - particular, - the_case = next_token, - unbroken = true; - - function find_duplicate_case(value) { - if (are_similar(particular, value)) { - warn('duplicate_a', value); - } - } - - funct['(breakage)'] += 1; - one_space(); - advance('('); - no_space(); - step_in(); - this.arity = 'statement'; - this.first = expected_condition(expected_relation(expression(0))); - no_space(); - step_out(')', the_case); - one_space(); - advance('{'); - step_in(); - in_block = true; - this.second = []; - while (next_token.id === 'case') { - the_case = next_token; - cases.forEach(find_duplicate_case); - the_case.first = []; - the_case.arity = 'case'; - spaces(); - edge('case'); - advance('case'); - for (;;) { - one_space(); - particular = expression(0); - cases.forEach(find_duplicate_case); - cases.push(particular); - the_case.first.push(particular); - if (particular.id === 'NaN') { - warn('unexpected_a', particular); - } - no_space_only(); - advance(':'); - if (next_token.id !== 'case') { - break; - } - spaces(); - edge('case'); - advance('case'); - } - spaces(); - the_case.second = statements(); - if (the_case.second && the_case.second.length > 0) { - particular = the_case.second[the_case.second.length - 1]; - if (particular.disrupt) { - if (particular.id === 'break') { - unbroken = false; - } - } else { - warn('missing_a_after_b', next_token, 'break', 'case'); - } - } else { - warn('empty_case'); - } - this.second.push(the_case); - } - if (this.second.length === 0) { - warn('missing_a', next_token, 'case'); - } - if (next_token.id === 'default') { - spaces(); - the_case = next_token; - the_case.arity = 'case'; - edge('case'); - advance('default'); - no_space_only(); - advance(':'); - spaces(); - the_case.second = statements(); - if (the_case.second && the_case.second.length > 0) { - particular = the_case.second[the_case.second.length - 1]; - if (unbroken && particular.disrupt && particular.id !== 'break') { - this.disrupt = true; - } - } - this.second.push(the_case); - } - funct['(breakage)'] -= 1; - spaces(); - step_out('}', this); - in_block = old_in_block; - return this; - }); - - stmt('debugger', function () { - if (!option.debug) { - warn('unexpected_a', this); - } - this.arity = 'statement'; - return this; - }); - - labeled_stmt('do', function () { - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - one_space(); - this.arity = 'statement'; - this.block = block(true); - if (this.block.disrupt) { - warn('strange_loop', prev_token); - } - one_space(); - advance('while'); - var paren = next_token; - one_space(); - advance('('); - step_in(); - no_space(); - edge(); - this.first = expected_condition(expected_relation(expression(0)), bundle.unexpected_a); - no_space(); - step_out(')', paren); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - labeled_stmt('for', function () { - - var blok, filter, ok = false, paren = next_token, value; - this.arity = 'statement'; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - if (next_token.id === ';') { - no_space(); - advance(';'); - no_space(); - advance(';'); - no_space(); - advance(')'); - blok = block(true); - } else { - step_in('control'); - spaces(this, paren); - no_space(); - if (next_token.id === 'var') { - stop('move_var'); - } - edge(); - if (peek(0).id === 'in') { - this.forin = true; - value = next_token; - switch (funct[value.string]) { - case 'unused': - funct[value.string] = 'var'; - break; - case 'closure': - case 'var': - break; - default: - warn('bad_in_a', value); - } - advance(); - advance('in'); - this.first = value; - this.second = expression(20); - step_out(')', paren); - blok = block(true); - if (!option.forin) { - if (blok.length === 1 && typeof blok[0] === 'object' && - blok[0].string === 'if' && !blok[0]['else']) { - filter = blok[0].first; - while (filter.id === '&&') { - filter = filter.first; - } - switch (filter.id) { - case '===': - case '!==': - ok = filter.first.id === '[' - ? filter.first.first.string === this.second.string && - filter.first.second.string === this.first.string - : filter.first.id === 'typeof' && - filter.first.first.id === '[' && - filter.first.first.first.string === this.second.string && - filter.first.first.second.string === this.first.string; - break; - case '(': - ok = filter.first.id === '.' && (( - filter.first.first.string === this.second.string && - filter.first.second.string === 'hasOwnProperty' && - filter.second[0].string === this.first.string - ) || ( - filter.first.first.string === 'ADSAFE' && - filter.first.second.string === 'has' && - filter.second[0].string === this.second.string && - filter.second[1].string === this.first.string - ) || ( - filter.first.first.id === '.' && - filter.first.first.first.id === '.' && - filter.first.first.first.first.string === 'Object' && - filter.first.first.first.second.string === 'prototype' && - filter.first.first.second.string === 'hasOwnProperty' && - filter.first.second.string === 'call' && - filter.second[0].string === this.second.string && - filter.second[1].string === this.first.string - )); - break; - } - } - if (!ok) { - warn('for_if', this); - } - } - } else { - edge(); - this.first = []; - for (;;) { - this.first.push(expression(0, 'for')); - if (next_token.id !== ',') { - break; - } - comma(); - } - semicolon(); - edge(); - this.second = expected_relation(expression(0)); - if (this.second.id !== 'true') { - expected_condition(this.second, bundle.unexpected_a); - } - semicolon(token); - if (next_token.id === ';') { - stop('expected_a_b', next_token, ')', ';'); - } - this.third = []; - edge(); - for (;;) { - this.third.push(expression(0, 'for')); - if (next_token.id !== ',') { - break; - } - comma(); - } - no_space(); - step_out(')', paren); - one_space(); - blok = block(true); - } - } - if (blok.disrupt) { - warn('strange_loop', prev_token); - } - this.block = blok; - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - disrupt_stmt('break', function () { - var label = next_token.string; - this.arity = 'statement'; - if (funct['(breakage)'] === 0) { - warn('unexpected_a', this); - } - if (next_token.identifier && token.line === next_token.line) { - one_space_only(); - if (funct[label] !== 'label') { - warn('not_a_label', next_token); - } else if (scope[label].funct !== funct) { - warn('not_a_scope', next_token); - } - this.first = next_token; - advance(); - } - return this; - }); - - disrupt_stmt('continue', function () { - if (!option['continue']) { - warn('unexpected_a', this); - } - var label = next_token.string; - this.arity = 'statement'; - if (funct['(breakage)'] === 0) { - warn('unexpected_a', this); - } - if (next_token.identifier && token.line === next_token.line) { - one_space_only(); - if (funct[label] !== 'label') { - warn('not_a_label', next_token); - } else if (scope[label].funct !== funct) { - warn('not_a_scope', next_token); - } - this.first = next_token; - advance(); - } - return this; - }); - - disrupt_stmt('return', function () { - if (funct === global_funct && xmode !== 'scriptstring') { - warn('unexpected_a', this); - } - this.arity = 'statement'; - if (next_token.id !== ';' && next_token.line === token.line) { - one_space_only(); - if (next_token.id === '/' || next_token.id === '(regexp)') { - warn('wrap_regexp'); - } - this.first = expression(20); - } - if (peek(0).id === '}' && peek(1).id === 'else') { - warn('unexpected_else', this); - } - return this; - }); - - disrupt_stmt('throw', function () { - this.arity = 'statement'; - one_space_only(); - this.first = expression(20); - return this; - }); - - -// Superfluous reserved words - - reserve('class'); - reserve('const'); - reserve('enum'); - reserve('export'); - reserve('extends'); - reserve('import'); - reserve('super'); - -// Harmony reserved words - - reserve('implements'); - reserve('interface'); - reserve('let'); - reserve('package'); - reserve('private'); - reserve('protected'); - reserve('public'); - reserve('static'); - reserve('yield'); - - -// Parse JSON - - function json_value() { - - function json_object() { - var brace = next_token, object = {}; - advance('{'); - if (next_token.id !== '}') { - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - warn('unexpected_a', next_token); - advance(','); - } - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - if (object[next_token.string] === true) { - warn('duplicate_a'); - } else if (next_token.string === '__proto__') { - warn('dangling_a'); - } else { - object[next_token.string] = true; - } - advance(); - advance(':'); - json_value(); - if (next_token.id !== ',') { - break; - } - advance(','); - if (next_token.id === '}') { - warn('unexpected_a', token); - break; - } - } - } - advance('}', brace); - } - - function json_array() { - var bracket = next_token; - advance('['); - if (next_token.id !== ']') { - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - warn('unexpected_a', next_token); - advance(','); - } - json_value(); - if (next_token.id !== ',') { - break; - } - advance(','); - if (next_token.id === ']') { - warn('unexpected_a', token); - break; - } - } - } - advance(']', bracket); - } - - switch (next_token.id) { - case '{': - json_object(); - break; - case '[': - json_array(); - break; - case 'true': - case 'false': - case 'null': - case '(number)': - case '(string)': - advance(); - break; - case '-': - advance('-'); - no_space_only(); - advance('(number)'); - break; - default: - stop('unexpected_a'); - } - } - - -// CSS parsing. - - function css_name() { - if (next_token.identifier) { - advance(); - return true; - } - } - - - function css_number() { - if (next_token.id === '-') { - advance('-'); - no_space_only(); - } - if (next_token.id === '(number)') { - advance('(number)'); - return true; - } - } - - - function css_string() { - if (next_token.id === '(string)') { - advance(); - return true; - } - } - - function css_color() { - var i, number, paren, value; - if (next_token.identifier) { - value = next_token.string; - if (value === 'rgb' || value === 'rgba') { - advance(); - paren = next_token; - advance('('); - for (i = 0; i < 3; i += 1) { - if (i) { - comma(); - } - number = next_token.number; - if (next_token.id !== '(number)' || number < 0) { - warn('expected_positive_a', next_token); - advance(); - } else { - advance(); - if (next_token.id === '%') { - advance('%'); - if (number > 100) { - warn('expected_percent_a', token, number); - } - } else { - if (number > 255) { - warn('expected_small_a', token, number); - } - } - } - } - if (value === 'rgba') { - comma(); - number = next_token.number; - if (next_token.id !== '(number)' || number < 0 || number > 1) { - warn('expected_fraction_a', next_token); - } - advance(); - if (next_token.id === '%') { - warn('unexpected_a'); - advance('%'); - } - } - advance(')', paren); - return true; - } - if (css_colorData[next_token.string] === true) { - advance(); - return true; - } - } else if (next_token.id === '(color)') { - advance(); - return true; - } - return false; - } - - - function css_length() { - if (next_token.id === '-') { - advance('-'); - no_space_only(); - } - if (next_token.id === '(number)') { - advance(); - if (next_token.id !== '(string)' && - css_lengthData[next_token.string] === true) { - no_space_only(); - advance(); - } else if (+token.number !== 0) { - warn('expected_linear_a'); - } - return true; - } - return false; - } - - - function css_line_height() { - if (next_token.id === '-') { - advance('-'); - no_space_only(); - } - if (next_token.id === '(number)') { - advance(); - if (next_token.id !== '(string)' && - css_lengthData[next_token.string] === true) { - no_space_only(); - advance(); - } - return true; - } - return false; - } - - - function css_width() { - if (next_token.identifier) { - switch (next_token.string) { - case 'thin': - case 'medium': - case 'thick': - advance(); - return true; - } - } else { - return css_length(); - } - } - - - function css_margin() { - if (next_token.identifier) { - if (next_token.string === 'auto') { - advance(); - return true; - } - } else { - return css_length(); - } - } - - function css_attr() { - if (next_token.identifier && next_token.string === 'attr') { - advance(); - advance('('); - if (!next_token.identifier) { - warn('expected_name_a'); - } - advance(); - advance(')'); - return true; - } - return false; - } - - - function css_comma_list() { - while (next_token.id !== ';') { - if (!css_name() && !css_string()) { - warn('expected_name_a'); - } - if (next_token.id !== ',') { - return true; - } - comma(); - } - } - - - function css_counter() { - if (next_token.identifier && next_token.string === 'counter') { - advance(); - advance('('); - advance(); - if (next_token.id === ',') { - comma(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - advance(')'); - return true; - } - if (next_token.identifier && next_token.string === 'counters') { - advance(); - advance('('); - if (!next_token.identifier) { - warn('expected_name_a'); - } - advance(); - if (next_token.id === ',') { - comma(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - if (next_token.id === ',') { - comma(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - advance(')'); - return true; - } - return false; - } - - - function css_radius() { - return css_length() && (next_token.id !== '(number)' || css_length()); - } - - - function css_shadow() { - for (;;) { - if (next_token.string === 'inset') { - advance(); - } - for (;;) { - if (!css_length()) { - break; - } - } - css_color(); - if (next_token.id !== ',') { - break; - } - advance(','); - } - return true; - } - - - function css_shape() { - var i; - if (next_token.identifier && next_token.string === 'rect') { - advance(); - advance('('); - for (i = 0; i < 4; i += 1) { - if (!css_length()) { - warn('expected_number_a'); - break; - } - } - advance(')'); - return true; - } - return false; - } - - - function css_url() { - var c, url; - if (next_token.identifier && next_token.string === 'url') { - next_token = lex.range('(', ')'); - url = next_token.string; - c = url.charAt(0); - if (c === '"' || c === '\'') { - if (url.slice(-1) !== c) { - warn('bad_url_a'); - } else { - url = url.slice(1, -1); - if (url.indexOf(c) >= 0) { - warn('bad_url_a'); - } - } - } - if (!url) { - warn('missing_url'); - } - if (ux.test(url)) { - stop('bad_url_a'); - } - urls.push(url); - advance(); - return true; - } - return false; - } - - - css_any = [css_url, function () { - for (;;) { - if (next_token.identifier) { - switch (next_token.string.toLowerCase()) { - case 'url': - css_url(); - break; - case 'expression': - warn('unexpected_a'); - advance(); - break; - default: - advance(); - } - } else { - if (next_token.id === ';' || next_token.id === '!' || - next_token.id === '(end)' || next_token.id === '}') { - return true; - } - advance(); - } - } - }]; - - - function font_face() { - advance_identifier('font-family'); - advance(':'); - if (!css_name() && !css_string()) { - stop('expected_name_a'); - } - semicolon(); - advance_identifier('src'); - advance(':'); - while (true) { - if (next_token.string === 'local') { - advance_identifier('local'); - advance('('); - if (ux.test(next_token.string)) { - stop('bad_url_a'); - } - - if (!css_name() && !css_string()) { - stop('expected_name_a'); - } - advance(')'); - } else if (!css_url()) { - stop('expected_a_b', next_token, 'url', artifact()); - } - if (next_token.id !== ',') { - break; - } - comma(); - } - semicolon(); - } - - - css_border_style = [ - 'none', 'dashed', 'dotted', 'double', 'groove', - 'hidden', 'inset', 'outset', 'ridge', 'solid' - ]; - - css_break = [ - 'auto', 'always', 'avoid', 'left', 'right' - ]; - - css_media = { - 'all': true, - 'braille': true, - 'embossed': true, - 'handheld': true, - 'print': true, - 'projection': true, - 'screen': true, - 'speech': true, - 'tty': true, - 'tv': true - }; - - css_overflow = [ - 'auto', 'hidden', 'scroll', 'visible' - ]; - - css_attribute_data = { - background: [ - true, 'background-attachment', 'background-color', - 'background-image', 'background-position', 'background-repeat' - ], - 'background-attachment': ['scroll', 'fixed'], - 'background-color': ['transparent', css_color], - 'background-image': ['none', css_url], - 'background-position': [ - 2, [css_length, 'top', 'bottom', 'left', 'right', 'center'] - ], - 'background-repeat': [ - 'repeat', 'repeat-x', 'repeat-y', 'no-repeat' - ], - 'border': [true, 'border-color', 'border-style', 'border-width'], - 'border-bottom': [ - true, 'border-bottom-color', 'border-bottom-style', - 'border-bottom-width' - ], - 'border-bottom-color': css_color, - 'border-bottom-left-radius': css_radius, - 'border-bottom-right-radius': css_radius, - 'border-bottom-style': css_border_style, - 'border-bottom-width': css_width, - 'border-collapse': ['collapse', 'separate'], - 'border-color': ['transparent', 4, css_color], - 'border-left': [ - true, 'border-left-color', 'border-left-style', 'border-left-width' - ], - 'border-left-color': css_color, - 'border-left-style': css_border_style, - 'border-left-width': css_width, - 'border-radius': function () { - function count(separator) { - var n = 1; - if (separator) { - advance(separator); - } - if (!css_length()) { - return false; - } - while (next_token.id === '(number)') { - if (!css_length()) { - return false; - } - n += 1; - } - if (n > 4) { - warn('bad_style'); - } - return true; - } - - return count() && (next_token.id !== '/' || count('/')); - }, - 'border-right': [ - true, 'border-right-color', 'border-right-style', - 'border-right-width' - ], - 'border-right-color': css_color, - 'border-right-style': css_border_style, - 'border-right-width': css_width, - 'border-spacing': [2, css_length], - 'border-style': [4, css_border_style], - 'border-top': [ - true, 'border-top-color', 'border-top-style', 'border-top-width' - ], - 'border-top-color': css_color, - 'border-top-left-radius': css_radius, - 'border-top-right-radius': css_radius, - 'border-top-style': css_border_style, - 'border-top-width': css_width, - 'border-width': [4, css_width], - bottom: [css_length, 'auto'], - 'box-shadow': ['none', css_shadow], - 'caption-side' : ['bottom', 'left', 'right', 'top'], - clear: ['both', 'left', 'none', 'right'], - clip: [css_shape, 'auto'], - color: css_color, - content: [ - 'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote', - css_string, css_url, css_counter, css_attr - ], - 'counter-increment': [ - css_name, 'none' - ], - 'counter-reset': [ - css_name, 'none' - ], - cursor: [ - css_url, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move', - 'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize', - 'se-resize', 'sw-resize', 'w-resize', 'text', 'wait' - ], - direction: ['ltr', 'rtl'], - display: [ - 'block', 'compact', 'inline', 'inline-block', 'inline-table', - 'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption', - 'table-cell', 'table-column', 'table-column-group', - 'table-footer-group', 'table-header-group', 'table-row', - 'table-row-group' - ], - 'empty-cells': ['show', 'hide'], - 'float': ['left', 'none', 'right'], - font: [ - 'caption', 'icon', 'menu', 'message-box', 'small-caption', - 'status-bar', true, 'font-size', 'font-style', 'font-weight', - 'font-family' - ], - 'font-family': css_comma_list, - 'font-size': [ - 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', - 'xx-large', 'larger', 'smaller', css_length - ], - 'font-size-adjust': ['none', css_number], - 'font-stretch': [ - 'normal', 'wider', 'narrower', 'ultra-condensed', - 'extra-condensed', 'condensed', 'semi-condensed', - 'semi-expanded', 'expanded', 'extra-expanded' - ], - 'font-style': [ - 'normal', 'italic', 'oblique' - ], - 'font-variant': [ - 'normal', 'small-caps' - ], - 'font-weight': [ - 'normal', 'bold', 'bolder', 'lighter', css_number - ], - height: [css_length, 'auto'], - left: [css_length, 'auto'], - 'letter-spacing': ['normal', css_length], - 'line-height': ['normal', css_line_height], - 'list-style': [ - true, 'list-style-image', 'list-style-position', 'list-style-type' - ], - 'list-style-image': ['none', css_url], - 'list-style-position': ['inside', 'outside'], - 'list-style-type': [ - 'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero', - 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', - 'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana', - 'hiragana-iroha', 'katakana-oroha', 'none' - ], - margin: [4, css_margin], - 'margin-bottom': css_margin, - 'margin-left': css_margin, - 'margin-right': css_margin, - 'margin-top': css_margin, - 'marker-offset': [css_length, 'auto'], - 'max-height': [css_length, 'none'], - 'max-width': [css_length, 'none'], - 'min-height': css_length, - 'min-width': css_length, - opacity: css_number, - outline: [true, 'outline-color', 'outline-style', 'outline-width'], - 'outline-color': ['invert', css_color], - 'outline-style': [ - 'dashed', 'dotted', 'double', 'groove', 'inset', 'none', - 'outset', 'ridge', 'solid' - ], - 'outline-width': css_width, - overflow: css_overflow, - 'overflow-x': css_overflow, - 'overflow-y': css_overflow, - padding: [4, css_length], - 'padding-bottom': css_length, - 'padding-left': css_length, - 'padding-right': css_length, - 'padding-top': css_length, - 'page-break-after': css_break, - 'page-break-before': css_break, - position: ['absolute', 'fixed', 'relative', 'static'], - quotes: [8, css_string], - right: [css_length, 'auto'], - 'table-layout': ['auto', 'fixed'], - 'text-align': ['center', 'justify', 'left', 'right'], - 'text-decoration': [ - 'none', 'underline', 'overline', 'line-through', 'blink' - ], - 'text-indent': css_length, - 'text-shadow': ['none', 4, [css_color, css_length]], - 'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'], - top: [css_length, 'auto'], - 'unicode-bidi': ['normal', 'embed', 'bidi-override'], - 'vertical-align': [ - 'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle', - 'text-bottom', css_length - ], - visibility: ['visible', 'hidden', 'collapse'], - 'white-space': [ - 'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit' - ], - width: [css_length, 'auto'], - 'word-spacing': ['normal', css_length], - 'word-wrap': ['break-word', 'normal'], - 'z-index': ['auto', css_number] - }; - - function style_attribute() { - var v; - while (next_token.id === '*' || next_token.id === '#' || - next_token.string === '_') { - if (!option.css) { - warn('unexpected_a'); - } - advance(); - } - if (next_token.id === '-') { - if (!option.css) { - warn('unexpected_a'); - } - advance('-'); - if (!next_token.identifier) { - warn('expected_nonstandard_style_attribute'); - } - advance(); - return css_any; - } - if (!next_token.identifier) { - warn('expected_style_attribute'); - } else { - if (Object.prototype.hasOwnProperty.call(css_attribute_data, - next_token.string)) { - v = css_attribute_data[next_token.string]; - } else { - v = css_any; - if (!option.css) { - warn('unrecognized_style_attribute_a'); - } - } - } - advance(); - return v; - } - - - function style_value(v) { - var i = 0, - n, - once, - match, - round, - start = 0, - vi; - switch (typeof v) { - case 'function': - return v(); - case 'string': - if (next_token.identifier && next_token.string === v) { - advance(); - return true; - } - return false; - } - for (;;) { - if (i >= v.length) { - return false; - } - vi = v[i]; - i += 1; - if (typeof vi === 'boolean') { - break; - } else if (typeof vi === 'number') { - n = vi; - vi = v[i]; - i += 1; - } else { - n = 1; - } - match = false; - while (n > 0) { - if (style_value(vi)) { - match = true; - n -= 1; - } else { - break; - } - } - if (match) { - return true; - } - } - start = i; - once = []; - for (;;) { - round = false; - for (i = start; i < v.length; i += 1) { - if (!once[i]) { - if (style_value(css_attribute_data[v[i]])) { - match = true; - round = true; - once[i] = true; - break; - } - } - } - if (!round) { - return match; - } - } - } - - function style_child() { - if (next_token.id === '(number)') { - advance(); - if (next_token.string === 'n' && next_token.identifier) { - no_space_only(); - advance(); - if (next_token.id === '+') { - no_space_only(); - advance('+'); - no_space_only(); - advance('(number)'); - } - } - return; - } - if (next_token.identifier && - (next_token.string === 'odd' || next_token.string === 'even')) { - advance(); - return; - } - warn('unexpected_a'); - } - - function substyle() { - var v; - for (;;) { - if (next_token.id === '}' || next_token.id === '(end)' || - (xquote && next_token.id === xquote)) { - return; - } - v = style_attribute(); - advance(':'); - if (next_token.identifier && next_token.string === 'inherit') { - advance(); - } else { - if (!style_value(v)) { - warn('unexpected_a'); - advance(); - } - } - if (next_token.id === '!') { - advance('!'); - no_space_only(); - if (next_token.identifier && next_token.string === 'important') { - advance(); - } else { - warn('expected_a_b', - next_token, 'important', artifact()); - } - } - if (next_token.id === '}' || next_token.id === xquote) { - warn('expected_a_b', next_token, ';', artifact()); - } else { - semicolon(); - } - } - } - - function style_selector() { - if (next_token.identifier) { - if (!Object.prototype.hasOwnProperty.call(html_tag, option.cap - ? next_token.string.toLowerCase() - : next_token.string)) { - warn('expected_tagname_a'); - } - advance(); - } else { - switch (next_token.id) { - case '>': - case '+': - advance(); - style_selector(); - break; - case ':': - advance(':'); - switch (next_token.string) { - case 'active': - case 'after': - case 'before': - case 'checked': - case 'disabled': - case 'empty': - case 'enabled': - case 'first-child': - case 'first-letter': - case 'first-line': - case 'first-of-type': - case 'focus': - case 'hover': - case 'last-child': - case 'last-of-type': - case 'link': - case 'only-of-type': - case 'root': - case 'target': - case 'visited': - advance_identifier(next_token.string); - break; - case 'lang': - advance_identifier('lang'); - advance('('); - if (!next_token.identifier) { - warn('expected_lang_a'); - } - advance(')'); - break; - case 'nth-child': - case 'nth-last-child': - case 'nth-last-of-type': - case 'nth-of-type': - advance_identifier(next_token.string); - advance('('); - style_child(); - advance(')'); - break; - case 'not': - advance_identifier('not'); - advance('('); - if (next_token.id === ':' && peek(0).string === 'not') { - warn('not'); - } - style_selector(); - advance(')'); - break; - default: - warn('expected_pseudo_a'); - } - break; - case '#': - advance('#'); - if (!next_token.identifier) { - warn('expected_id_a'); - } - advance(); - break; - case '*': - advance('*'); - break; - case '.': - advance('.'); - if (!next_token.identifier) { - warn('expected_class_a'); - } - advance(); - break; - case '[': - advance('['); - if (!next_token.identifier) { - warn('expected_attribute_a'); - } - advance(); - if (next_token.id === '=' || next_token.string === '~=' || - next_token.string === '$=' || - next_token.string === '|=' || - next_token.id === '*=' || - next_token.id === '^=') { - advance(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - advance(']'); - break; - default: - stop('expected_selector_a'); - } - } - } - - function style_pattern() { - if (next_token.id === '{') { - warn('expected_style_pattern'); - } - for (;;) { - style_selector(); - if (next_token.id === '= 0) { - warn('unexpected_char_a_b', token, v.charAt(x), a); - } - ids[u] = true; - } else if (a === 'class' || a === 'type' || a === 'name') { - x = v.search(qx); - if (x >= 0) { - warn('unexpected_char_a_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)) { - stop('bad_url_a', next_token, v); - } - urls.push(v); - } else if (a === 'for') { - if (option.adsafe) { - if (adsafe_id) { - if (v.slice(0, adsafe_id.length) !== adsafe_id) { - warn('adsafe_prefix_a', next_token, adsafe_id); - } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { - warn('adsafe_bad_id'); - } - } else { - warn('adsafe_bad_id'); - } - } - } else if (a === 'name') { - if (option.adsafe && v.indexOf('_') >= 0) { - warn('adsafe_name_a', next_token, v); - } - } - } - - function do_tag(name, attribute) { - var i, tag = html_tag[name], script, x; - src = false; - if (!tag) { - stop( - bundle.unrecognized_tag_a, - next_token, - name === name.toLowerCase() - ? name - : name + ' (capitalization error)' - ); - } - if (stack.length > 0) { - if (name === 'html') { - stop('unexpected_a', token, name); - } - x = tag.parent; - if (x) { - if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) { - stop('tag_a_in_b', token, name, x); - } - } else if (!option.adsafe && !option.fragment) { - i = stack.length; - do { - if (i <= 0) { - stop('tag_a_in_b', token, name, 'body'); - } - i -= 1; - } while (stack[i].name !== 'body'); - } - } - switch (name) { - case 'div': - if (option.adsafe && stack.length === 1 && !adsafe_id) { - warn('adsafe_missing_id'); - } - break; - case 'script': - xmode = 'script'; - advance('>'); - if (attribute.lang) { - warn('lang', token); - } - if (option.adsafe && stack.length !== 1) { - warn('adsafe_placement', token); - } - if (attribute.src) { - if (option.adsafe && (!adsafe_may || !approved[attribute.src])) { - warn('adsafe_source', token); - } - } else { - step_in(next_token.from); - edge(); - use_strict(); - adsafe_top = true; - script = statements(); - -// JSLint is also the static analyzer for ADsafe. See www.ADsafe.org. - - if (option.adsafe) { - if (adsafe_went) { - stop('adsafe_script', token); - } - if (script.length !== 1 || - aint(script[0], 'id', '(') || - aint(script[0].first, 'id', '.') || - aint(script[0].first.first, 'string', 'ADSAFE') || - aint(script[0].second[0], 'string', adsafe_id)) { - stop('adsafe_id_go'); - } - switch (script[0].first.second.string) { - case 'id': - if (adsafe_may || adsafe_went || - script[0].second.length !== 1) { - stop('adsafe_id', next_token); - } - adsafe_may = true; - break; - case 'go': - if (adsafe_went) { - stop('adsafe_go'); - } - if (script[0].second.length !== 2 || - aint(script[0].second[1], 'id', 'function') || - !script[0].second[1].first || - aint(script[0].second[1].first[0], 'string', 'dom') || - script[0].second[1].first.length > 2 || - (script[0].second[1].first.length === 2 && - aint(script[0].second[1].first[1], 'string', 'lib'))) { - stop('adsafe_go', next_token); - } - adsafe_went = true; - break; - default: - stop('adsafe_id_go'); - } - } - indent = null; - } - xmode = 'html'; - advance(''); - styles(); - xmode = 'html'; - advance(''; - } - - function html() { - var attribute, attributes, is_empty, name, old_white = option.white, - quote, tag_name, tag, wmode; - xmode = 'html'; - xquote = ''; - stack = null; - for (;;) { - switch (next_token.string) { - case '<': - xmode = 'html'; - advance('<'); - attributes = {}; - tag_name = next_token; - name = tag_name.string; - advance_identifier(name); - if (option.cap) { - name = name.toLowerCase(); - } - tag_name.name = name; - if (!stack) { - stack = []; - do_begin(name); - } - tag = html_tag[name]; - if (typeof tag !== 'object') { - stop('unrecognized_tag_a', tag_name, name); - } - is_empty = tag.empty; - tag_name.type = name; - for (;;) { - if (next_token.id === '/') { - advance('/'); - if (next_token.id !== '>') { - warn('expected_a_b', next_token, '>', artifact()); - } - break; - } - if (next_token.id && next_token.id.charAt(0) === '>') { - break; - } - if (!next_token.identifier) { - if (next_token.id === '(end)' || next_token.id === '(error)') { - warn('expected_a_b', next_token, '>', artifact()); - } - warn('bad_name_a'); - } - option.white = false; - spaces(); - attribute = next_token.string; - option.white = old_white; - advance(); - if (!option.cap && attribute !== attribute.toLowerCase()) { - warn('attribute_case_a', token); - } - attribute = attribute.toLowerCase(); - xquote = ''; - if (Object.prototype.hasOwnProperty.call(attributes, attribute)) { - warn('duplicate_a', token, attribute); - } - if (attribute.slice(0, 2) === 'on') { - if (!option.on) { - warn('html_handlers'); - } - xmode = 'scriptstring'; - advance('='); - quote = next_token.id; - if (quote !== '"' && quote !== '\'') { - stop('expected_a_b', next_token, '"', artifact()); - } - xquote = quote; - wmode = option.white; - option.white = true; - advance(quote); - use_strict(); - statements(); - option.white = wmode; - if (next_token.id !== quote) { - stop('expected_a_b', next_token, quote, artifact()); - } - xmode = 'html'; - xquote = ''; - advance(quote); - tag = false; - } else if (attribute === 'style') { - xmode = 'scriptstring'; - advance('='); - quote = next_token.id; - if (quote !== '"' && quote !== '\'') { - stop('expected_a_b', next_token, '"', artifact()); - } - xmode = 'styleproperty'; - xquote = quote; - advance(quote); - substyle(); - xmode = 'html'; - xquote = ''; - advance(quote); - tag = false; - } else { - if (next_token.id === '=') { - advance('='); - tag = next_token.string; - if (!next_token.identifier && - next_token.id !== '"' && - next_token.id !== '\'' && - next_token.id !== '(string)' && - next_token.id !== '(number)' && - next_token.id !== '(color)') { - warn('expected_attribute_value_a', token, attribute); - } - advance(); - } else { - tag = true; - } - } - attributes[attribute] = tag; - do_attribute(attribute, tag); - } - do_tag(name, attributes); - if (!is_empty) { - stack.push(tag_name); - } - xmode = 'outer'; - advance('>'); - break; - case '') { - stop('expected_a_b', next_token, '>', artifact()); - } - xmode = 'outer'; - advance('>'); - break; - case '' || next_token.id === '(end)') { - break; - } - if (next_token.string.indexOf('--') >= 0) { - stop('unexpected_a', next_token, '--'); - } - if (next_token.string.indexOf('<') >= 0) { - stop('unexpected_a', next_token, '<'); - } - if (next_token.string.indexOf('>') >= 0) { - stop('unexpected_a', next_token, '>'); - } - } - xmode = 'outer'; - advance('>'); - break; - case '(end)': - if (stack.length !== 0) { - warn('missing_a', next_token, ''); - } - return; - default: - if (next_token.id === '(end)') { - stop('missing_a', next_token, - ''); - } else { - advance(); - } - } - if (stack && stack.length === 0 && (option.adsafe || - !option.fragment || next_token.id === '(end)')) { - break; - } - } - if (next_token.id !== '(end)') { - stop('unexpected_a'); - } - } - - -// The actual JSLINT function itself. - - itself = function JSLint(the_source, the_option) { - - var i, predef, tree; - JSLINT.errors = []; - JSLINT.tree = ''; - JSLINT.properties = ''; - begin = prev_token = token = next_token = - Object.create(syntax['(begin)']); - predefined = {}; - add_to_predefined(standard); - property = {}; - if (the_option) { - option = Object.create(the_option); - predef = option.predef; - if (predef) { - if (Array.isArray(predef)) { - for (i = 0; i < predef.length; i += 1) { - predefined[predef[i]] = true; - } - } else if (typeof predef === 'object') { - add_to_predefined(predef); - } - } - do_safe(); - } else { - option = {}; - } - option.indent = +option.indent || 4; - option.maxerr = +option.maxerr || 50; - adsafe_id = ''; - adsafe_may = adsafe_top = 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 += ' '; - } - global_scope = scope = {}; - global_funct = funct = { - '(scope)': scope, - '(breakage)': 0, - '(loopage)': 0 - }; - functions = [funct]; - - comments_off = false; - ids = {}; - in_block = false; - indent = null; - json_mode = false; - lookahead = []; - node_js = false; - prereg = true; - src = false; - stack = null; - strict_mode = false; - urls = []; - var_mode = null; - warnings = 0; - xmode = ''; - lex.init(the_source); - - assume(); - - try { - advance(); - if (next_token.id === '(number)') { - stop('unexpected_a'); - } else if (next_token.string.charAt(0) === '<') { - html(); - if (option.adsafe && !adsafe_went) { - warn('adsafe_go', this); - } - } else { - switch (next_token.id) { - case '{': - case '[': - json_mode = true; - json_value(); - break; - case '@': - case '*': - case '#': - case '.': - case ':': - xmode = 'style'; - advance(); - if (token.id !== '@' || !next_token.identifier || - next_token.string !== 'charset' || token.line !== 1 || - token.from !== 1) { - stop('css'); - } - advance(); - if (next_token.id !== '(string)' && - next_token.string !== 'UTF-8') { - stop('css'); - } - advance(); - semicolon(); - styles(); - break; - - default: - if (option.adsafe && option.fragment) { - stop('expected_a_b', - next_token, '
', artifact()); - } - -// If the first token is a semicolon, ignore it. This is sometimes used when -// files are intended to be appended to files that may be sloppy. A sloppy -// file may be depending on semicolon insertion on its last line. - - step_in(1); - if (next_token.id === ';' && !node_js) { - semicolon(); - } - adsafe_top = true; - tree = statements(); - begin.first = tree; - itself.tree = begin; - if (option.adsafe && (tree.length !== 1 || - aint(tree[0], 'id', '(') || - aint(tree[0].first, 'id', '.') || - aint(tree[0].first.first, 'string', 'ADSAFE') || - aint(tree[0].first.second, 'string', 'lib') || - tree[0].second.length !== 2 || - tree[0].second[0].id !== '(string)' || - aint(tree[0].second[1], 'id', 'function'))) { - stop('adsafe_lib'); - } - if (tree.disrupt) { - warn('weird_program', prev_token); - } - } - } - indent = null; - advance('(end)'); - itself.property = property; - } catch (e) { - if (e) { // ~~ - JSLINT.errors.push({ - reason : e.message, - line : e.line || next_token.line, - character : e.character || next_token.from - }, null); - } - } - return JSLINT.errors.length === 0; - }; - - -// Data summary. - - itself.data = function () { - var data = {functions: []}, - function_data, - globals, - i, - j, - kind, - name, - the_function, - undef = [], - unused = []; - if (itself.errors.length) { - data.errors = itself.errors; - } - - if (json_mode) { - data.json = true; - } - - if (urls.length > 0) { - data.urls = urls; - } - - globals = Object.keys(global_scope).filter(function (value) { - return value.charAt(0) !== '(' && typeof standard[value] !== 'boolean'; - }); - if (globals.length > 0) { - data.globals = globals; - } - - for (i = 1; i < functions.length; i += 1) { - the_function = functions[i]; - function_data = {}; - for (j = 0; j < functionicity.length; j += 1) { - function_data[functionicity[j]] = []; - } - for (name in the_function) { - if (Object.prototype.hasOwnProperty.call(the_function, name)) { - if (name.charAt(0) !== '(') { - kind = the_function[name]; - if (kind === 'unction' || kind === 'unparam') { - kind = 'unused'; - } - if (Array.isArray(function_data[kind])) { - function_data[kind].push(name); - if (kind === 'unused') { - unused.push({ - name: name, - line: the_function['(line)'], - 'function': the_function['(name)'] - }); - } else if (kind === 'undef') { - undef.push({ - name: name, - line: the_function['(line)'], - 'function': the_function['(name)'] - }); - } - } - } - } - } - for (j = 0; j < functionicity.length; j += 1) { - if (function_data[functionicity[j]].length === 0) { - delete function_data[functionicity[j]]; - } - } - function_data.name = the_function['(name)']; - function_data.params = the_function['(params)']; - function_data.line = the_function['(line)']; - data.functions.push(function_data); - } - - if (unused.length > 0) { - data.unused = unused; - } - if (undef.length > 0) { - data['undefined'] = undef; - } - return data; - }; - - itself.error_report = function (data) { - var evidence, i, output = [], snippets, warning; - if (data.errors) { - for (i = 0; i < data.errors.length; i += 1) { - warning = data.errors[i]; - if (warning) { - evidence = warning.evidence || ''; - output.push(''); - if (isFinite(warning.line)) { - output.push('
line ' + - String(warning.line) + - ' character ' + String(warning.character) + - '
'); - } - output.push(warning.reason.entityify() + '
'); - if (evidence) { - output.push('
' + evidence.entityify() + '
'); - } - } - } - } - if (data.unused || data['undefined']) { - output.push('
'); - if (data['undefined']) { - output.push('
undefined
'); - snippets = []; - for (i = 0; i < data['undefined'].length; i += 1) { - snippets[i] = '' + data['undefined'][i].name + - ' 
' + - data['undefined'][i]['function'] + ' ' + - String(data['undefined'][i].line) + '
'; - } - output.push(snippets.join(', ')); - output.push('
'); - } - if (data.unused) { - output.push('
unused
'); - snippets = []; - for (i = 0; i < data.unused.length; i += 1) { - snippets[i] = '' + data.unused[i].name + ' 
' + - data.unused[i]['function'] + ' ' + - String(data.unused[i].line) + '
'; - } - output.push(snippets.join(', ')); - output.push('
'); - } - output.push('
'); - } - if (data.json) { - output.push('

JSON: bad.

'); - } - return output.join(''); - }; - - - itself.report = function (data) { - var dl, err, i, j, names, output = [], the_function; - - function detail(h, value) { - var comma_needed, singularity; - if (Array.isArray(value)) { - output.push('
' + h + '
'); - value.sort().forEach(function (item) { - if (item !== singularity) { - singularity = item; - output.push((comma_needed ? ', ' : '') + singularity); - comma_needed = true; - } - }); - output.push('
'); - } else if (value) { - output.push('
' + h + '
', value, '
'); - } - } - - output.push('
'); - if (data.urls) { - detail("url", data.urls); - dl = true; - } - if (data.globals) { - detail('global', data.globals); - dl = true; - } else if (xmode === 'style') { - output.push('

CSS.

'); - } else if (data.json && !err) { - output.push('

JSON: good.

'); - } else { - output.push('
No new global variables introduced.
'); - } - if (dl) { - output.push('
'); - } else { - output[0] = ''; - } - - for (i = 0; i < data.functions.length; i += 1) { - the_function = data.functions[i]; - names = []; - if (the_function.params) { - for (j = 0; j < the_function.params.length; j += 1) { - names[j] = the_function.params[j].string; - } - } - output.push('
line ' + - String(the_function.line) + '
' + - the_function.name.entityify() + - '(' + names.join(', ') + ')'); - detail('undefined', the_function['undefined']); - detail('unused', the_function.unused); - detail('closure', the_function.closure); - detail('variable', the_function['var']); - detail('exception', the_function.exception); - detail('outer', the_function.outer); - detail('global', the_function.global); - detail('label', the_function.label); - output.push('
'); - } - return output.join(''); - }; - - itself.properties_report = function (property) { - if (!property) { - return ''; - } - var i, - key, - keys = Object.keys(property).sort(), - length, - output = ['/*properties'], - mem = ' ', - name, - not_first = false; - for (i = 0; i < keys.length; i += 1) { - key = keys[i]; - if (property[key] > 0) { - if (not_first) { - mem += ', '; - } - name = ix.test(key) - ? key - : '\'' + key.replace(nx, sanitize) + '\''; - length += name.length + 2; - if (mem.length + name.length > 80) { - output.push(mem); - mem = ' '; - } - mem += name; - not_first = true; - } - } - output.push(mem, '*/\n'); - return output.join('\n'); - }; - - itself.jslint = itself; - - itself.edition = '2012-05-09'; - - return itself; -}()); diff --git a/js/js.translator/testData/libImplementations/jQuery.js b/js/js.translator/testData/libImplementations/jQuery.js deleted file mode 100644 index 3c9ea9e5649..00000000000 --- a/js/js.translator/testData/libImplementations/jQuery.js +++ /dev/null @@ -1,9300 +0,0 @@ -/*! - * jQuery JavaScript Library v1.7 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Thu Nov 3 16:18:21 2011 -0400 - */ -(function( window, undefined ) { - -// Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; -var jQuery = (function() { - -// 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, rootjQuery ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, - - // Check for digits - rdigit = /\d/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - - // Matches dashed string for camelizing - rdashAlpha = /-([a-z]|[0-9])/ig, - rmsPrefix = /^-ms-/, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return ( letter + "" ).toUpperCase(); - }, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // The deferred used on DOM ready - readyList, - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, - - // [[Class]] -> type pairs - class2type = {}; - -jQuery.fn = jQuery.prototype = { - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - 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 && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = selector; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - 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] ) { - context = context instanceof jQuery ? context[0] : context; - 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 = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // 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: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( 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.7", - - // 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[ this.length + num ] : 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 = this.constructor(); - - 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(); - - // Add the callback - readyList.add( 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 || this.constructor(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() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // 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 plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // 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 ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } - - if ( deep && window.jQuery === jQuery ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.fireWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).unbind( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyList ) { - return; - } - - readyList = jQuery.Callbacks( "once memory" ); - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - return setTimeout( jQuery.ready, 1 ); - } - - // 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 jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - // A crude way of determining if an object is a window - isWindow: function( obj ) { - return obj && typeof obj === "object" && "setInterval" in obj; - }, - - isNumeric: function( obj ) { - return obj != null && rdigit.test( obj ) && !isNaN( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - 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 || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - 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 || hasOwn.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 ); - - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { - - return ( new Function( "return " + data ) )(); - - } - jQuery.error( "Invalid JSON: " + data ); - }, - - // Cross-browser xml parsing - parseXML: function( data ) { - var xml, tmp; - try { - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - } catch( e ) { - xml = undefined; - } - if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; - }, - - noop: function() {}, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - 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 ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } - } - } - - return object; - }, - - // Use native String.trim function wherever possible - trim: trim ? - function( text ) { - return text == null ? - "" : - trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); - }, - - // 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) - // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); - - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array, i ) { - var len; - - if ( array ) { - if ( indexOf ) { - return indexOf.call( array, elem, i ); - } - - len = array.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in array && 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 = [], retVal; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, key, ret = [], - i = 0, - length = elems.length, - // jquery objects are treated as arrays - isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; - - // Go through the array, translating each of the items to their - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Go through every key on the object, - } else { - for ( key in elems ) { - value = callback( elems[ key ], key, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - } - - // Flatten any nested arrays - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - if ( typeof context === "string" ) { - var tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - var args = slice.call( arguments, 2 ), - proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - - return proxy; - }, - - // Mutifunctional method to get and set values to a collection - // The value/s can optionally be executed if it's a function - access: function( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - jQuery.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; - }, - - now: function() { - return ( new Date() ).getTime(); - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); - } - - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); - }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; - }, - - browser: {} -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -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; -} - -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} - -// 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(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -// Expose jQuery as an AMD module, but only for AMD loaders that -// understand the issues with loading multiple versions of jQuery -// in a page that all might call define(). The loader will indicate -// they have special allowances for multiple jQuery versions by -// specifying define.amd.jQuery = true. Register as a named module, -// since jQuery can be concatenated with other files that may use define, -// but not use a proper concatenation script that understands anonymous -// AMD modules. A named AMD is safest and most robust way to register. -// Lowercase jquery is used because AMD module names are derived from -// file names, and jQuery is normally delivered in a lowercase file name. -if ( typeof define === "function" && define.amd && define.amd.jQuery ) { - define( "jquery", [], function () { return jQuery; } ); -} - -return jQuery; - -})(); - - -// String to Object flags format cache -var flagsCache = {}; - -// Convert String-formatted flags into Object-formatted ones and store in cache -function createFlags( flags ) { - var object = flagsCache[ flags ] = {}, - i, length; - flags = flags.split( /\s+/ ); - for ( i = 0, length = flags.length; i < length; i++ ) { - object[ flags[i] ] = true; - } - return object; -} - -/* - * Create a callback list using the following parameters: - * - * flags: an optional list of space-separated flags that will change how - * the callback list behaves - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible flags: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( flags ) { - - // Convert flags from String-formatted to Object-formatted - // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; - - var // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = [], - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Add one or several callbacks to the list - add = function( args ) { - var i, - length, - elem, - type, - actual; - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - // Inspect recursively - add( elem ); - } else if ( type === "function" ) { - // Add if not in unique mode and callback is not in - if ( !flags.unique || !self.has( elem ) ) { - list.push( elem ); - } - } - } - }, - // Fire callbacks - fire = function( context, args ) { - args = args || []; - memory = !flags.memory || [ context, args ]; - firing = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { - memory = true; // Mark as halted - break; - } - } - firing = false; - if ( list ) { - if ( !flags.once ) { - if ( stack && stack.length ) { - memory = stack.shift(); - self.fireWith( memory[ 0 ], memory[ 1 ] ); - } - } else if ( memory === true ) { - self.disable(); - } else { - list = []; - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - var length = list.length; - add( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away, unless previous - // firing was halted (stopOnFalse) - } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - var args = arguments, - argIndex = 0, - argLength = args.length; - for ( ; argIndex < argLength ; argIndex++ ) { - for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ] ) { - // Handle firingIndex and firingLength - if ( firing ) { - if ( i <= firingLength ) { - firingLength--; - if ( i <= firingIndex ) { - firingIndex--; - } - } - } - // Remove the element - list.splice( i--, 1 ); - // If we have some unicity property then - // we only need to do this once - if ( flags.unique ) { - break; - } - } - } - } - } - return this; - }, - // Control if a given callback is in the list - has: function( fn ) { - if ( list ) { - var i = 0, - length = list.length; - for ( ; i < length; i++ ) { - if ( fn === list[ i ] ) { - return true; - } - } - } - return false; - }, - // Remove all callbacks from the list - empty: function() { - list = []; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory || memory === true ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( stack ) { - if ( firing ) { - if ( !flags.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( flags.once && memory ) ) { - fire( context, args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!memory; - } - }; - - return self; -}; - - - - -var // Static reference to slice - sliceDeferred = [].slice; - -jQuery.extend({ - - Deferred: function( func ) { - var doneList = jQuery.Callbacks( "once memory" ), - failList = jQuery.Callbacks( "once memory" ), - progressList = jQuery.Callbacks( "memory" ), - state = "pending", - lists = { - resolve: doneList, - reject: failList, - notify: progressList - }, - promise = { - done: doneList.add, - fail: failList.add, - progress: progressList.add, - - state: function() { - return state; - }, - - // Deprecated - isResolved: doneList.fired, - isRejected: failList.fired, - - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, - always: function() { - return deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); - }, - pipe: function( fnDone, fnFail, fnProgress ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ], - progress: [ fnProgress, "notify" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - obj = promise; - } else { - for ( var key in promise ) { - obj[ key ] = promise[ key ]; - } - } - return obj; - } - }, - deferred = promise.promise({}), - key; - - for ( key in lists ) { - deferred[ key ] = lists[ key ].fire; - deferred[ key + "With" ] = lists[ key ].fireWith; - } - - // Handle state - deferred.done( function() { - state = "resolved"; - }, failList.disable, progressList.lock ).fail( function() { - state = "rejected"; - }, doneList.disable, progressList.lock ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = sliceDeferred.call( arguments, 0 ), - i = 0, - length = args.length, - pValues = new Array( length ), - count = length, - pCount = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(), - promise = deferred.promise(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( deferred, args ); - } - }; - } - function progressFunc( i ) { - return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - deferred.notifyWith( promise, pValues ); - }; - } - if ( length > 1 ) { - for ( ; i < length; i++ ) { - if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return promise; - } -}); - - - - -jQuery.support = (function() { - - var div = document.createElement( "div" ), - documentElement = document.documentElement, - all, - a, - select, - opt, - input, - marginDiv, - support, - fragment, - body, - testElementParent, - testElement, - testElementStyle, - tds, - events, - eventName, - i, - isSupported; - - // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = "
a"; - - - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return {}; - } - - // First batch of supports tests - select = document.createElement( "select" ); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; - - 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 instead) - style: /top/.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 unknown elements (like HTML5 elems) are handled appropriately - unknownElems: !!div.getElementsByTagName( "nav" ).length, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: ( input.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: opt.selected, - - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - getSetAttribute: div.className !== "t", - - // Tests for enctype support on a form(#6743) - enctype: !!document.createElement("form").enctype, - - // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, - deleteExpando: true, - noCloneEvent: true, - inlineBlockNeedsLayout: false, - shrinkWrapBlocks: false, - reliableMarginRight: true - }; - - // Make sure checked status is properly cloned - input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) - select.disabled = true; - support.optDisabled = !opt.disabled; - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - support.noCloneEvent = false; - }); - div.cloneNode( true ).fireEvent( "onclick" ); - } - - // Check if a radio maintains its value - // after being appended to the DOM - input = document.createElement("input"); - input.value = "t"; - input.setAttribute("type", "radio"); - support.radioValue = input.value === "t"; - - input.setAttribute("checked", "checked"); - div.appendChild( input ); - fragment = document.createDocumentFragment(); - fragment.appendChild( div.lastChild ); - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - div.innerHTML = ""; - - // Figure out if the W3C box model works as expected - div.style.width = div.style.paddingLeft = "1px"; - - // We don't want to do body-related feature tests on frameset - // documents, which lack a body. So we use - // document.getElementsByTagName("body")[0], which is undefined in - // frameset documents, while document.body isn’t. (7398) - body = document.getElementsByTagName("body")[ 0 ]; - // We use our own, invisible, body unless the body is already present - // in which case we use a div (#9239) - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0, - background: "none" - }; - if ( body ) { - jQuery.extend( testElementStyle, { - position: "absolute", - left: "-999px", - top: "-999px" - }); - } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; - } - testElement.appendChild( div ); - testElementParent = body || documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - support.boxModel = div.offsetWidth === 2; - - if ( "zoom" in div.style ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); - - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); - } - - div.innerHTML = "
t
"; - tds = div.getElementsByTagName( "td" ); - - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Check if empty table cells still have offsetWidth/Height - // (IE < 8 fail this test) - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - div.innerHTML = ""; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( document.defaultView && document.defaultView.getComputedStyle ) { - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - - // Technique from Juriy Zaytsev - // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( div.attachEvent ) { - for( i in { - submit: 1, - change: 1, - focusin: 1 - } ) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; - } - } - - // Run fixed position tests at doc ready to avoid a crash - // related to the invisible body in IE8 - jQuery(function() { - var container, outer, inner, table, td, offsetSupport, - conMarginTop = 1, - ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;", - vb = "visibility:hidden;border:0;", - style = "style='" + ptlm + "border:5px solid #000;padding:0;'", - html = "
" + - "" + - "
"; - - // Reconstruct a container - body = document.getElementsByTagName("body")[0]; - if ( !body ) { - // Return for frameset docs that don't have a body - // These tests cannot be done - return; - } - - container = document.createElement("div"); - container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; - body.insertBefore( container, body.firstChild ); - - // Construct a test element - testElement = document.createElement("div"); - testElement.style.cssText = ptlm + vb; - - testElement.innerHTML = html; - container.appendChild( testElement ); - outer = testElement.firstChild; - inner = outer.firstChild; - td = outer.nextSibling.firstChild.firstChild; - - offsetSupport = { - doesNotAddBorder: ( inner.offsetTop !== 5 ), - doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) - }; - - inner.style.position = "fixed"; - inner.style.top = "20px"; - - // safari subtracts parent border width here which is 5px - offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); - inner.style.position = inner.style.top = ""; - - outer.style.overflow = "hidden"; - outer.style.position = "relative"; - - offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); - offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); - - body.removeChild( container ); - testElement = container = null; - - jQuery.extend( support, offsetSupport ); - }); - - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); - - // Null connected elements to avoid leaks in IE - testElement = fragment = select = opt = body = marginDiv = div = input = null; - - return support; -})(); - -// Keep track of boxModel -jQuery.boxModel = jQuery.support.boxModel; - - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/, - rmultiDash = /([A-Z])/g; - -jQuery.extend({ - cache: {}, - - // Please use with caution - uuid: 0, - - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var privateCache, thisCache, ret, - internalKey = jQuery.expando, - getByName = typeof name === "string", - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando, - isEvents = name === "events"; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - elem[ jQuery.expando ] = id = ++jQuery.uuid; - } else { - id = jQuery.expando; - } - } - - if ( !cache[ id ] ) { - cache[ id ] = {}; - - // Avoids exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - privateCache = thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Users should not attempt to inspect the internal events object using jQuery.data, - // it is undocumented and subject to change. But does anyone listen? No. - if ( isEvents && !thisCache[ name ] ) { - return privateCache.events; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( getByName ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; - }, - - removeData: function( elem, name, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, l, - - // Reference to internal data cache key - internalKey = jQuery.expando, - - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ jQuery.expando ] : jQuery.expando; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support space separated names - if ( jQuery.isArray( name ) ) { - name = name; - } else if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split( " " ); - } - } - - for ( i = 0, l = name.length; i < l; i++ ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { - return; - } - } - - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - // Ensure that `cache` is not a window object #10080 - if ( jQuery.support.deleteExpando || !cache.setInterval ) { - delete cache[ id ]; - } else { - cache[ id ] = null; - } - - // We destroyed the cache and need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ jQuery.expando ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( jQuery.expando ); - } else { - elem[ jQuery.expando ] = null; - } - } - }, - - // For internal use only. - _data: function( elem, name, data ) { - return jQuery.data( elem, name, data, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; - - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var parts, attr, name, - data = null; - - if ( typeof key === "undefined" ) { - if ( this.length ) { - data = jQuery.data( this[0] ); - - if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { - attr = this[0].attributes; - for ( var i = 0, l = attr.length; i < l; i++ ) { - name = attr[i].name; - - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.substring(5) ); - - dataAttr( this[0], name, data[ name ] ); - } - } - jQuery._data( this[0], "parsedAttrs", true ); - } - } - - return data; - - } else if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - // Try to fetch any internally stored data first - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - data = dataAttr( this[0], key, data ); - } - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - - } else { - return this.each(function() { - var $this = jQuery( this ), - args = [ parts[0], value ]; - - $this.triggerHandler( "setData" + parts[1] + "!", args ); - jQuery.data( this, key, value ); - $this.triggerHandler( "changeData" + parts[1] + "!", args ); - }); - } - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - jQuery.isNumeric( data ) ? parseFloat( data ) : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - for ( var name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - - - - -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery._data( elem, deferDataKey ); - if ( defer && - ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && - ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery._data( elem, queueDataKey ) && - !jQuery._data( elem, markDataKey ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.fire(); - } - }, 0 ); - } -} - -jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = ( type || "fx" ) + "mark"; - jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); - if ( count ) { - jQuery._data( elem, key, count ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - - queue: function( elem, type, data ) { - var q; - if ( elem ) { - type = ( type || "fx" ) + "queue"; - q = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - 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(), - hooks = {}; - - // 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" ); - } - - jQuery._data( elem, type + ".run", hooks ); - fn.call( elem, function() { - jQuery.dequeue( elem, type ); - }, hooks ); - } - - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue " + type + ".run", true ); - handleQueueMarkDefer( elem, type, "queue" ); - } - } -}); - -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() { - 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( next, hooks ) { - var timeout = setTimeout( next, time ); - hooks.stop = function() { - clearTimeout( timeout ); - }; - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, object ) { - if ( typeof type !== "string" ) { - object = type; - type = undefined; - } - type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } - while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { - count++; - tmp.add( resolve ); - } - } - resolve(); - return defer.promise(); - } -}); - - - - -var rclass = /[\n\t\r]/g, - rspace = /\s+/, - rreturn = /\r/g, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - nodeHook, boolHook, fixSpecified; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.attr ); - }, - - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.prop ); - }, - - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} - }); - }, - - addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); - }); - } - - if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { - elem.className = value; - - } else { - setClass = " " + elem.className + " "; - - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { - setClass += classNames[ c ] + " "; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - classNames = ( value || "" ).split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( 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 ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, 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 + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var hooks, ret, isFunction, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return undefined; - } - - isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var self = jQuery(this), val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, self.val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - }, - select: { - get: function( elem ) { - var value, i, max, option, - 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 - i = one ? index : 0; - max = one ? index + 1 : options.length; - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific 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 ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - }, - - set: function( elem, value ) { - var values = jQuery.makeArray( value ); - - jQuery(elem).find("option").each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return undefined; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery( elem )[ name ]( value ); - } - - // Fallback to prop when attributes are not supported - if ( !("getAttribute" in elem) ) { - return jQuery.prop( elem, name, value ); - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - // All attributes are lowercase - // Grab necessary hook if one is defined - if ( notxml ) { - name = name.toLowerCase(); - hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return undefined; - - } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, "" + value ); - return value; - } - - } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - - ret = elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, value ) { - var propName, attrNames, name, l, - i = 0; - - if ( elem.nodeType === 1 ) { - attrNames = ( value || "" ).split( rspace ); - l = attrNames.length; - - for ( ; i < l; i++ ) { - name = attrNames[ i ].toLowerCase(); - propName = jQuery.propFix[ name ] || name; - - // See #9699 for explanation of this approach (setting first, then removal) - jQuery.attr( elem, name, "" ); - elem.removeAttribute( getSetAttribute ? name : propName ); - - // Set corresponding property to false for boolean attributes - if ( rboolean.test( name ) && propName in elem ) { - elem[ propName ] = false; - } - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to it's default in case type is set after value - // This is for element creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - }, - // Use the value property for back compat - // Use the nodeHook for button elements in IE6/7 (#1954) - value: { - get: function( elem, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.get( elem, name ); - } - return name in elem ? - elem.value : - null; - }, - set: function( elem, value, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.set( elem, value, name ); - } - // Does not return so that setAttribute is also used - elem.value = value; - } - } - }, - - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - - prop: function( elem, name, value ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return undefined; - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - return ( elem[ name ] = value ); - } - - } else { - if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - return elem[ name ]; - } - } - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - // 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/ - var attributeNode = elem.getAttributeNode("tabindex"); - - return attributeNode && attributeNode.specified ? - parseInt( attributeNode.value, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - } - } -}); - -// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) -jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; - -// Hook for boolean attributes -boolHook = { - get: function( elem, name ) { - // Align boolean attributes with corresponding properties - // Fall back to attribute presence where some booleans are not supported - var attrNode, - property = jQuery.prop( elem, name ); - return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? - name.toLowerCase() : - undefined; - }, - set: function( elem, value, name ) { - var propName; - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - // value is true since we know at this point it's type boolean and not false - // Set boolean attributes to the same name and set the DOM property - propName = jQuery.propFix[ name ] || name; - if ( propName in elem ) { - // Only set the IDL specifically if it already exists on the element - elem[ propName ] = true; - } - - elem.setAttribute( name, name.toLowerCase() ); - } - return name; - } -}; - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !getSetAttribute ) { - - fixSpecified = { - name: true, - id: true - }; - - // Use this for any attribute in IE6/7 - // This fixes almost every IE6/7 issue - nodeHook = jQuery.valHooks.button = { - get: function( elem, name ) { - var ret; - ret = elem.getAttributeNode( name ); - return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? - ret.nodeValue : - undefined; - }, - set: function( elem, value, name ) { - // Set the existing or create a new attribute node - var ret = elem.getAttributeNode( name ); - if ( !ret ) { - ret = document.createAttribute( name ); - elem.setAttributeNode( ret ); - } - return ( ret.nodeValue = value + "" ); - } - }; - - // Apply the nodeHook to tabindex - jQuery.attrHooks.tabindex.set = nodeHook.set; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }); - }); - - // Set contenteditable to false on removals(#10429) - // Setting to empty string throws an error as an invalid value - jQuery.attrHooks.contenteditable = { - get: nodeHook.get, - set: function( elem, value, name ) { - if ( value === "" ) { - value = "false"; - } - nodeHook.set( elem, value, name ); - } - }; -} - - -// Some attributes require a special call on IE -if ( !jQuery.support.hrefNormalized ) { - jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - get: function( elem ) { - var ret = elem.getAttribute( name, 2 ); - return ret === null ? undefined : ret; - } - }); - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; - }, - set: function( elem, value ) { - return ( elem.style.cssText = "" + value ); - } - }; -} - -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { - get: function( elem ) { - var parent = elem.parentNode; - - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - return null; - } - }); -} - -// IE6/7 call enctype encoding -if ( !jQuery.support.enctype ) { - jQuery.propFix.enctype = "encoding"; -} - -// Radios and checkboxes getter/setter -if ( !jQuery.support.checkOn ) { - jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - get: function( elem ) { - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - } - }; - }); -} -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); - } - } - }); -}); - - - - -var rnamespaces = /\.(.*)$/, - rformElems = /^(?:textarea|input|select)$/i, - rperiod = /\./g, - rspaces = / /g, - rescape = /[^\w\s.|`]/g, - rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, - rhoverHack = /\bhover(\.\S+)?/, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|contextmenu)|click/, - rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - quickParse = function( selector ) { - var quick = rquickIs.exec( selector ); - if ( quick ) { - // 0 1 2 3 - // [ _, tag, id, class ] - quick[1] = ( quick[1] || "" ).toLowerCase(); - quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); - } - return quick; - }, - quickIs = function( elem, m ) { - return ( - (!m[1] || elem.nodeName.toLowerCase() === m[1]) && - (!m[2] || elem.id === m[2]) && - (!m[3] || m[3].test( elem.className )) - ); - }, - hoverHack = function( events ) { - return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); - }; - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - add: function( elem, types, handler, data, selector ) { - - var elemData, eventHandle, events, - t, tns, type, namespaces, handleObj, - handleObjIn, quick, handlers, special; - - // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - events = elemData.events; - if ( !events ) { - elemData.events = events = {}; - } - eventHandle = elemData.handle; - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = hoverHack(types).split( " " ); - for ( t = 0; t < types.length; t++ ) { - - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = ( tns[2] || "" ).split( "." ).sort(); - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: tns[1], - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - namespace: namespaces.join(".") - }, handleObjIn ); - - // Delegated event; pre-analyze selector so it's processed quickly on event dispatch - if ( selector ) { - handleObj.quick = quickParse( selector ); - if ( !handleObj.quick && jQuery.expr.match.POS.test( selector ) ) { - handleObj.isPositional = true; - } - } - - // Init the event handler queue if we're the first - handlers = events[ type ]; - if ( !handlers ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // 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 to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - 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, selector ) { - - var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - t, tns, type, namespaces, origCount, - j, events, special, handle, eventType, handleObj; - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = hoverHack( types || "" ).split(" "); - for ( t = 0; t < types.length; t++ ) { - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = tns[2]; - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - namespaces = namespaces? "." + namespaces : ""; - for ( j in events ) { - jQuery.event.remove( elem, j + namespaces, handler, selector ); - } - return; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector? special.delegateType : special.bindType ) || type; - eventType = events[ type ] || []; - origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - - // Only need to loop for special events or selective removal - if ( handler || namespaces || selector || special.remove ) { - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( !handler || handler.guid === handleObj.guid ) { - if ( !namespaces || namespaces.test( handleObj.namespace ) ) { - if ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) { - eventType.splice( j--, 1 ); - - if ( handleObj.selector ) { - eventType.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - } - } - } else { - // Removing all events - eventType.length = 0; - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( eventType.length === 0 && origCount !== eventType.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery.removeData( elem, [ "events", "handle" ], true ); - } - }, - - // Events that are safe to short-circuit if no handlers are attached. - // Native DOM events should not be added, they may have inline handlers. - customEvent: { - "getData": true, - "setData": true, - "changeData": true - }, - - trigger: function( event, data, elem, onlyHandlers ) { - // Don't do events on text and comment nodes - if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { - return; - } - - // Event object or event type - var type = event.type || event, - namespaces = [], - cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; - - if ( type.indexOf( "!" ) >= 0 ) { - // Exclusive events trigger only for the exact event (no namespaces) - type = type.slice(0, -1); - exclusive = true; - } - - if ( type.indexOf( "." ) >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - - if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { - // No jQuery handlers for this event type, and it can't have inline handlers - return; - } - - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); - - event.type = type; - event.isTrigger = true; - event.exclusive = exclusive; - event.namespace = namespaces.join( "." ); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; - - // triggerHandler() and global events don't bubble or run the default action - if ( onlyHandlers || !elem ) { - event.preventDefault(); - } - - // Handle a global trigger - if ( !elem ) { - - // TODO: Stop taunting the data cache; remove global events and always attach to document - cache = jQuery.cache; - for ( i in cache ) { - if ( cache[ i ].events && cache[ i ].events[ type ] ) { - jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); - } - } - return; - } - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - eventPath = [[ elem, special.bindType || type ]]; - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - old = null; - for ( cur = elem.parentNode; cur; cur = cur.parentNode ) { - eventPath.push([ cur, bubbleType ]); - old = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old && old === elem.ownerDocument ) { - eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); - } - } - - // Fire handlers on the event path - for ( i = 0; i < eventPath.length; i++ ) { - - cur = eventPath[i][0]; - event.type = eventPath[i][1]; - - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) ) { - handle.apply( cur, data ); - } - - if ( event.isPropagationStopped() ) { - break; - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && - !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - // IE<9 dies on focus/blur to hidden element (#1486) - if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; - - if ( old ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( old ) { - elem[ ontype ] = old; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event || window.event ); - - var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), - delegateCount = handlers.delegateCount, - args = [].slice.call( arguments, 0 ), - run_all = !event.exclusive && !event.namespace, - specialHandle = ( jQuery.event.special[ event.type ] || {} ).handle, - handlerQueue = [], - i, j, cur, ret, selMatch, matched, matches, handleObj, sel, hit, related; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Determine handlers that should run if there are delegated events - // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { - - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - selMatch = {}; - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - hit = selMatch[ sel ]; - - if ( handleObj.isPositional ) { - // Since .is() does not work for positionals; see http://jsfiddle.net/eJ4yd/3/ - hit = ( hit || (selMatch[ sel ] = jQuery( sel )) ).index( cur ) >= 0; - } else if ( hit === undefined ) { - hit = selMatch[ sel ] = ( handleObj.quick ? quickIs( cur, handleObj.quick ) : jQuery( cur ).is( sel ) ); - } - if ( hit ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); - } - } - } - - // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); - } - - // Run delegates first; they may want to stop propagation beneath us - for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { - matched = handlerQueue[ i ]; - event.currentTarget = matched.elem; - - for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { - handleObj = matched.matches[ j ]; - - // Triggered event must either 1) be non-exclusive and have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { - - event.data = handleObj.data; - event.handleObj = handleObj; - - ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - return event.result; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** - props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement wheelDelta".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, - originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = jQuery.Event( originalEvent ); - - for ( i = copy.length; i; ) { - prop = copy[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Target should not be a text node (#504, Safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) - if ( event.metaKey === undefined ) { - event.metaKey = event.ctrlKey; - } - - return fixHook.filter? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady - }, - - focus: { - delegateType: "focusin", - noBubble: true - }, - blur: { - delegateType: "focusout", - noBubble: true - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, - - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -// Some plugins are using, but it's undocumented/deprecated and will be removed. -// The 1.7 special event interface should provide all the hooks needed now. -jQuery.event.handle = jQuery.event.dispatch; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.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) - } else { - 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 -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = jQuery.event.special[ fix ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var target = this, - related = event.relatedTarget, - handleObj = event.handleObj, - selector = handleObj.selector, - oldType, ret; - - // For a real mouseover/out, always call the handler; for - // mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || handleObj.origType === event.type || (related !== target && !jQuery.contains( target, related )) ) { - oldType = event.type; - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = oldType; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !form._submit_attached ) { - jQuery.event.add( form, "submit._submit", function( event ) { - // Form was submitted, bubble the event up the tree - if ( this.parentNode ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - }); - form._submit_attached = true; - } - }); - // return undefined since we don't need an event listener - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !jQuery.support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed ) { - this._just_changed = false; - jQuery.event.simulate( "change", this, event, true ); - } - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - elem._change_attached = true; - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return rformElems.test( this.nodeName ); - } - }; -} - -// Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0, - handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } - }, - teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on.call( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - var handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( var type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - bind: function( types, data, fn ) { - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - return this.off( types, null, fn ); - }, - - live: function( types, data, fn ) { - jQuery( this.context ).on( types, this.selector, data, fn ); - return this; - }, - die: function( types, fn ) { - jQuery( this.context ).off( types, this.selector || "**", fn ); - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, - guid = fn.guid || jQuery.guid++, - i = 0, - toggler = 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; - }; - - // link all the functions, so any of them can unbind this click handler - toggler.guid = guid; - while ( i < args.length ) { - args[ i++ ].guid = guid; - } - - return this.click( toggler ); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -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 contextmenu").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - if ( fn == null ) { - fn = data; - data = null; - } - - return arguments.length > 0 ? - this.bind( name, data, fn ) : - this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } - - if ( rkeyEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; - } - - if ( rmouseEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; - } -}); - - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - expando = "sizcache" + (Math.random() + '').replace('.', ''), - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rReturn = /\r\n/g, - rNonWord = /\W/; - -// 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 || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context, seed ); - - } 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, seed ); - } - } - - } 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]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - 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 ) { - 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 ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( 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.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set, i, len, match, type, left; - - if ( !expr ) { - return []; - } - - for ( i = 0, len = Expr.order.length; i < len; i++ ) { - type = Expr.order[i]; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - left = match[1]; - match.splice( 1, 1 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - type, found, item, filter, left, - i, pass, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - filter = Expr.filter[ type ]; - 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 ( i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - 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; -}; - -/** - * Utility function for retreiving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -var getText = Sizzle.getText = function( elem ) { - var i, node, - nodeType = elem.nodeType, - ret = ""; - - if ( nodeType ) { - if ( nodeType === 1 ) { - // Use textContent || innerText for elements - if ( typeof elem.textContent === 'string' ) { - return elem.textContent; - } else if ( typeof elem.innerText === 'string' ) { - // Replace IE's carriage returns - return elem.innerText.replace( rReturn, '' ); - } else { - // Traverse it's children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - } else { - - // If no nodeType, this is expected to be an array - for ( i = 0; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - if ( node.nodeType !== 8 ) { - ret += getText( node ); - } - } - } - return ret; -}; - -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|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - 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" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.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 elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - 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 nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - 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]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [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 ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - 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\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // 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; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace( rBackslash, "" ); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - 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 - if ( elem.parentNode ) { - 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 ) { - var attr = elem.getAttribute( "type" ), type = elem.type; - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case - return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); - }, - - radio: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; - }, - - checkbox: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; - }, - - file: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; - }, - - password: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; - }, - - submit: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "submit" === elem.type; - }, - - image: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; - }, - - reset: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "reset" === elem.type; - }, - - button: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && "button" === elem.type || name === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - }, - - focus: function( elem ) { - return elem === elem.ownerDocument.activeElement; - } - }, - 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 j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var first, last, - doneName, parent, cache, - count, diff, - 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": - first = match[2]; - last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - doneName = match[0]; - parent = elem.parentNode; - - if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { - count = 0; - - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - - parent[ expando ] = doneName; - } - - 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 && 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 = Sizzle.attr ? - Sizzle.attr( elem, name ) : - 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 && Sizzle.attr ? - result != null : - 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, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -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, fescape) ); -} - -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 i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - - // Fallback to using sourceIndex (in IE) if it's available on both nodes - } else if ( a.sourceIndex && b.sourceIndex ) { - return a.sourceIndex - b.sourceIndex; - } - - var al, bl, - ap = [], - bp = [], - aup = a.parentNode, - bup = b.parentNode, - cur = aup; - - // If the nodes are siblings (or identical) we can do a quick check - if ( aup === bup ) { - return siblingCheck( a, b ); - - // If no parents were found then the nodes are disconnected - } else if ( !aup ) { - return -1; - - } else if ( !bup ) { - return 1; - } - - // Otherwise they're somewhere else in the tree so we need - // to build up a full list of the parentNodes for comparison - while ( cur ) { - ap.unshift( cur ); - cur = cur.parentNode; - } - - cur = bup; - - while ( cur ) { - bp.unshift( cur ); - cur = cur.parentNode; - } - - al = ap.length; - bl = bp.length; - - // Start walking down the tree looking for a discrepancy - for ( var i = 0; i < al && i < bl; i++ ) { - if ( ap[i] !== bp[i] ) { - return siblingCheck( ap[i], bp[i] ); - } - } - - // We ended someplace up the tree so do a sibling check - return i === al ? - siblingCheck( a, bp[i], -1 ) : - siblingCheck( ap[i], b, 1 ); - }; - - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} - -// 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(), - root = document.documentElement; - - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - 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 ); - - // release memory in IE - root = form = null; -})(); - -(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 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - 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 && !Sizzle.isXML(context) ) { - // See if we find a selector to speed up - var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); - - if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { - // Speed-up: Sizzle("TAG") - if ( match[1] ) { - return makeArray( context.getElementsByTagName( query ), extra ); - - // Speed-up: Sizzle(".CLASS") - } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { - return makeArray( context.getElementsByClassName( match[2] ), extra ); - } - } - - if ( context.nodeType === 9 ) { - // Speed-up: Sizzle("body") - // The body element only exists once, optimize finding it - if ( query === "body" && context.body ) { - return makeArray( [ context.body ], extra ); - - // Speed-up: Sizzle("#ID") - } else if ( match && match[3] ) { - var elem = context.getElementById( match[3] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(qsaError) {} - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; - - if ( matches ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9 fails this) - var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - var ret = matches.call( node, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || !disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9, so check for that - node.document && node.document.nodeType !== 11 ) { - return ret; - } - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(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]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem[ expando ] = 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 ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem[ expando ] = 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; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -Sizzle.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, seed ) { - var match, - tmpSet = [], - later = "", - 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, seed ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -// Override sizzle attribute retrieval -Sizzle.attr = jQuery.attr; -Sizzle.selectors.attrMap = {}; -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})(); - - -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.POS, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - find: function( selector ) { - var self = this, - i, l; - - if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }); - } - - var ret = this.pushStack( "", "find", selector ), - length, n, r; - - for ( 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 ( n = length; n < ret.length; n++ ) { - for ( 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 && ( - typeof selector === "string" ? - // If this is a positional selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - POS.test( selector ) ? - jQuery( selector, this.context ).index( this[0] ) >= 0 : - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); - }, - - closest: function( selectors, context ) { - var ret = [], i, l, cur = this[0]; - - // Array (deprecated as of jQuery 1.7) - if ( jQuery.isArray( selectors ) ) { - var level = 1; - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( i = 0; i < selectors.length; i++ ) { - - if ( jQuery( cur ).is( selectors[ i ] ) ) { - ret.push({ selector: selectors[ i ], elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - - return ret; - } - - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( i = 0, l = this.length; i < l; i++ ) { - cur = this[i]; - - while ( cur ) { - if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { - ret.push( cur ); - break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { - break; - } - } - } - } - - ret = ret.length > 1 ? jQuery.unique( ret ) : ret; - - return this.pushStack( ret, "closest", selectors ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // 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 ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : 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 ), - // The variable 'args' was introduced in - // https://github.com/jquery/jquery/commit/52a0238 - // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. - // http://code.google.com/p/v8/issues/detail?id=1050 - args = slice.call(arguments); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, args.join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 ? - jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : - 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; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, keep ) { - - // Can't pass null or undefined to indexOf in Firefox 4 - // Set to 0 to skip string check - qualifier = qualifier || 0; - - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - var retVal = !!qualifier.call( elem, i, elem ); - return retVal === 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; - }); -} - - - - -function createSafeFragment( document ) { - var list = nodeNames.split( " " ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr article aside audio canvas datalist details figcaption figure footer " + - "header hgroup mark meter nav output progress section summary time video", - rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /", "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }, - safeFragment = createSafeFragment( document ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and