jshint_on_rails 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- /*
1
+ /*!
2
2
  * JSHint, by JSHint Community.
3
3
  *
4
4
  * Licensed under the same slightly modified MIT license that JSLint is.
@@ -40,7 +40,7 @@
40
40
  The first parameter is either a string or an array of strings. If it is a
41
41
  string, it will be split on '\n' or '\r'. If it is an array of strings, it
42
42
  is assumed that each string represents one line. The source can be a
43
- JavaScript text, or HTML text, or a JSON text, or a CSS text.
43
+ JavaScript text or a JSON text.
44
44
 
45
45
  The second parameter is an optional object of options which control the
46
46
  operation of JSHINT. Most of the options are booleans: They are all
@@ -151,120 +151,79 @@
151
151
  */
152
152
 
153
153
  /*jshint
154
- evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true
154
+ evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true,
155
+ undef: true, maxlen: 100
155
156
  */
156
157
 
157
- /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
158
- "(begin)", "(breakage)", "(context)", "(error)", "(global)",
159
- "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
160
- "(params)", "(scope)", "(statement)", "(verb)", "*", "+", "++", "-",
161
- "--", "\/", "<", "<=", "==", "===", ">", ">=", $, ADSAFE, __filename, __dirname,
162
- ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Boolean, Buffer, COM,
163
- CScript, Canvas, CustomAnimation, DataView, Date, Debug, E, Enumerator,
164
- Error, EvalError, FadeAnimation, Flash, Float32Array, Float64Array,
165
- FormField, Frame, Function, HotKey, Image, Int16Array, Int32Array, Int8Array,
166
- JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem, MoveAnimation,
167
- NEGATIVE_INFINITY, Number, Object, Option, PI, POSITIVE_INFINITY, Point,
168
- RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation,
169
- RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String, Style, SyntaxError,
170
- System, Text, TextArea, Timer, TypeError, URIError, URL, VBArray,
171
- WScript, Web, Window, XMLDOM, XMLHttpRequest, "\\", a, abbr, acronym,
172
- activeborder, activecaption, addEventListener, address, adsafe, alert,
173
- aliceblue, all, animator, antiquewhite, appleScript, applet, apply,
174
- approved, appworkspace, applicationCache, aqua, aquamarine, area, arguments,
175
- arity, article, asi, aside, audio, autocomplete, azure, b, background,
176
- "background-attachment", "background-color", "background-image",
177
- "background-position", "background-repeat", base, bdo, beep, beige, big,
178
- bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
179
- blueviolet, blur, body, boolOptions, border, "border-bottom", "border-bottom-color",
180
- "border-bottom-style", "border-bottom-width", "border-collapse",
181
- "border-color", "border-left", "border-left-color", "border-left-style",
182
- "border-left-width", "border-right", "border-right-color",
183
- "border-right-style", "border-right-width", "border-spacing",
184
- "border-style", "border-top", "border-top-color", "border-top-style",
185
- "border-top-width", "border-width", bottom, boss, br, braille, brown, browser,
186
- burlywood, button, buttonface, buttonhighlight, buttonshadow,
187
- buttontext, bytesToUIString, c, cadetblue, call, callee, caller, canvas,
188
- cap, caption, "caption-side", captiontext, cases, center, charAt,
189
- charCodeAt, character, chartreuse, chocolate, chooseColor, chooseFile,
190
- chooseFolder, cite, clear, clearInterval, clearTimeout, clip, close,
191
- closeWidget, closed, closure, cm, code, col, colgroup, color, command,
192
- comment, condition, confirm, console, constructor, content,
193
- convertPathToHFS, convertPathToPlatform, coral, cornflowerblue,
194
- cornsilk, couch, "counter-increment", "counter-reset", create, crimson,
195
- css, curly, cursor, cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray,
196
- darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid,
197
- darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
198
- darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,
199
- deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,
200
- details, devel, dfn, dialog, dimgray, dir, direction, display, div, dl,
201
- document, dodgerblue, dt, edition, else, em, embed, embossed, emit, empty,
202
- "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq, errors,
203
- es5, escape, eval, event, evidence, evil, ex, exception, exec, exps, exports,
204
- fieldset, figure, filesystem, FileReader, firebrick, first, float, floor,
205
- floralwhite, focus, focusWidget, font, "font-family", "font-size",
206
- "font-size-adjust", "font-stretch", "font-style", "font-variant",
207
- "font-weight", footer, forestgreen, forin, form, fragment, frame,
208
- frames, frameset, from, fromCharCode, fuchsia, fud, funct, function,
209
- functions, g, gainsboro, gc, getComputedStyle, getRow, ghostwhite, GLOBAL, global,
210
- globals, gold, goldenrod, gray, graytext, green, greenyellow, h1, h2,
211
- h3, h4, h5, h6, handheld, hasOwnProperty, head, header, height, help,
212
- hgroup, highlight, highlighttext, history, honeydew, hotpink, hr,
213
- "hta:application", html, i, iTunes, id, identifier, iframe, img, immed,
214
- implieds, in, inactiveborder, inactivecaption, inactivecaptiontext,
215
- include, indent, indexOf, indianred, indigo, infobackground, infotext,
216
- init, input, ins, isAlpha, isApplicationRunning, isArray, isDigit,
217
- isFinite, isNaN, ivory, join, jshint, JSHINT, json, jquery, jQuery, kbd,
218
- keygen, keys, khaki, konfabulatorVersion, label, labelled, lang, last,
219
- lavender, lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
220
- lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
221
- lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
222
- lightseagreen, lightskyblue, lightslategray, lightsteelblue,
223
- lightyellow, lime, limegreen, line, "line-height", linen, link,
224
- "list-style", "list-style-image", "list-style-position",
225
- "list-style-type", load, loadClass, localStorage, location, log, loopfunc, m, magenta,
226
- map, margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
227
- mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr,
228
- maxlen, md5, mediumaquamarine, mediumblue, mediumorchid, mediumpurple,
229
- mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise,
230
- mediumvioletred, member, menu, menutext, message, meta, meter,
231
- midnightblue, "min-height", "min-width", mintcream, mistyrose, mm,
232
- moccasin, module, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,
233
- newcap, noarg, node, noempty, noframes, nomen, nonew, noscript, nud, object, ol,
234
- oldlace, olive, olivedrab, on, onbeforeunload, onblur, onerror, onevar,
235
- onfocus, onload, onresize, onunload, opacity, open, openDatabase, openURL, opener,
236
- opera, optgroup, option, orange, orangered, orchid, outer, outline, "outline-color",
237
- "outline-style", "outline-width", output, overflow, "overflow-x",
238
- "overflow-y", p, padding, "padding-bottom", "padding-left",
239
- "padding-right", "padding-top", "page-break-after", "page-break-before",
240
- palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip,
241
- param, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru,
242
- pink, play, plum, plusplus, pop, popupMenu, position, powderblue, pre,
243
- predef, preferenceGroups, preferences, print, process, progress, projection,
244
- prompt, prototype, pt, purple, push, px, q, quit, quotes, random, range,
245
- raw, reach, readFile, readUrl, reason, red, regexp, reloadWidget,
246
- removeEventListener, replace, report, require, reserved, resizeBy, resizeTo,
247
- resolvePath, resumeUpdates, respond, rhino, right, rosybrown, royalblue,
248
- rp, rt, ruby, runCommand, runCommandInBg, saddlebrown, safe, salmon, samp,
249
- sandybrown, saveAs, savePreferences, screen, script, scroll, scrollBy,
250
- scrollTo, scrollbar, seagreen, seal, search, seashell, section, send, select,
251
- serialize, setInterval, setTimeout, shift, showWidgetPreferences,
252
- sienna, silver, skyblue, slateblue, slategray, sleep, slice, small,
253
- snow, sort, source, span, spawn, speak, speech, split, springgreen, src,
254
- stack, status, start, steelblue, strict, strong, style, styleproperty, sub,
255
- substr, sum, sup, supplant, suppressUpdates, sync, system, table,
256
- "table-layout", tan, tbody, td, teal, tellWidget, test, "text-align",
257
- "text-decoration", "text-indent", "text-shadow", "text-transform",
258
- textarea, tfoot, th, thead, thistle, threeddarkshadow, threedface,
259
- threedhighlight, threedlightshadow, threedshadow, time, title,
260
- toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
261
- tty, turquoise, tv, type, Uint16Array, Uint32Array, Uint8Array, u, ul, undef,
262
- unescape, "unicode-bidi", unused, unwatch, updateNow, urls, value, valueOf,
263
- var, version, "vertical-align", video, violet, visibility, watch,
264
- WebSocket, wheat, white, "white-space", whitesmoke, widget, width,
265
- window, windowframe, windows, windowtext, Worker, "word-spacing", "word-wrap",
266
- yahooCheckLogin, yahooLogin, yahooLogout, yellow, yellowgreen, "z-index"
267
- */
158
+ /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)",
159
+ "(breakage)", "(context)", "(error)", "(global)", "(identifier)", "(last)",
160
+ "(line)", "(loopage)", "(name)", "(onevar)", "(params)", "(scope)",
161
+ "(statement)", "(verb)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==",
162
+ "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax,
163
+ __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio,
164
+ Autocompleter, Assets, Boolean, Builder, Buffer, Browser, COM, CScript, Canvas,
165
+ CustomAnimation, Class, Control, Chain, Color, Cookie, Core, DataView, Date,
166
+ Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMReady, Drag,
167
+ E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event,
168
+ Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form,
169
+ FormField, Frame, FormData, Function, Fx, GetObject, Group, Hash, HotKey,
170
+ HTMLElement, HTMLAnchorElement, HTMLBaseElement, HTMLBlockquoteElement,
171
+ HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDirectoryElement,
172
+ HTMLDivElement, HTMLDListElement, HTMLFieldSetElement,
173
+ HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement,
174
+ HTMLHeadElement, HTMLHeadingElement, HTMLHRElement, HTMLHtmlElement,
175
+ HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLIsIndexElement,
176
+ HTMLLabelElement, HTMLLayerElement, HTMLLegendElement, HTMLLIElement,
177
+ HTMLLinkElement, HTMLMapElement, HTMLMenuElement, HTMLMetaElement,
178
+ HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement,
179
+ HTMLOptionElement, HTMLParagraphElement, HTMLParamElement, HTMLPreElement,
180
+ HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLStyleElement,
181
+ HtmlTable, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement,
182
+ HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement,
183
+ HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement, HTMLVideoElement
184
+ Iframe, IframeShim, Image, Int16Array, Int32Array, Int8Array,
185
+ Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E,
186
+ MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem, MoveAnimation, MooTools, Native,
187
+ NEGATIVE_INFINITY, Number, Object, ObjectRange, Option, Options, OverText, PI,
188
+ POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype, RangeError,
189
+ Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation,
190
+ SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion,
191
+ ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller,
192
+ Slick, Slider, Selector, SharedWorker, String, Style, SyntaxError, Sortable, Sortables,
193
+ SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template,
194
+ Timer, Tips, Type, TypeError, Toggle, Try, unescape, URI, URIError, URL, VBArray, WSH,
195
+ WScript, Web, Window, XMLDOM, XMLHttpRequest, XPathEvaluator, XPathException,
196
+ XPathExpression, XPathNamespace, XPathNSResolver, XPathResult, "\\", a,
197
+ addEventListener, address, alert, apply, applicationCache, arguments, arity,
198
+ asi, b, bitwise, block, blur, boolOptions, boss, browser, c, call, callee,
199
+ caller, cases, charAt, charCodeAt, character, clearInterval, clearTimeout,
200
+ close, closed, closure, comment, condition, confirm, console, constructor,
201
+ content, couch, create, css, curly, d, data, datalist, dd, debug, decodeURI,
202
+ decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document,
203
+ dojo, dijit, dojox, define, edition, else, emit, encodeURI, encodeURIComponent,
204
+ entityify, eqeqeq, eqnull, errors, es5, escape, eval, event, evidence, evil,
205
+ ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus,
206
+ forin, fragment, frames, from, fromCharCode, fud, funct, function, functions,
207
+ g, gc, getComputedStyle, getRow, GLOBAL, global, globals, globalstrict,
208
+ hasOwnProperty, help, history, i, id, identifier, immed, implieds, include,
209
+ indent, indexOf, init, ins, instanceOf, isAlpha, isApplicationRunning, isArray,
210
+ isDigit, isFinite, isNaN, iterator, join, jshint,
211
+ JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastsemic, laxbreak,
212
+ latedef, lbp, led, left, length, line, load, loadClass, localStorage, location,
213
+ log, loopfunc, m, match, maxerr, maxlen, member,message, meta, module, moveBy,
214
+ moveTo, mootools, name, navigator, new, newcap, noarg, node, noempty, nomen,
215
+ nonew, nonstandard, nud, onbeforeunload, onblur, onerror, onevar, onecase, onfocus,
216
+ onload, onresize, onunload, open, openDatabase, openURL, opener, opera, outer, param,
217
+ parent, parseFloat, parseInt, passfail, plusplus, predef, print, process, prompt,
218
+ proto, prototype, prototypejs, push, quit, range, raw, reach, reason, regexp,
219
+ readFile, readUrl, regexdash, removeEventListener, replace, report, require,
220
+ reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right,
221
+ runCommand, scroll, screen, scripturl, scrollBy, scrollTo, scrollbar, search, seal,
222
+ send, serialize, sessionStorage, setInterval, setTimeout, shift, slice, sort,spawn,
223
+ split, stack, status, start, strict, sub, substr, supernew, shadow, supplant, sum,
224
+ sync, test, toLowerCase, toString, toUpperCase, toint32, token, top, trailing, type,
225
+ typeOf, Uint16Array, Uint32Array, Uint8Array, undef, unused, urls, validthis, value, valueOf,
226
+ var, version, WebSocket, white, window, Worker, wsh*/
268
227
 
269
228
  /*global exports: false */
270
229
 
@@ -275,11 +234,7 @@
275
234
  var JSHINT = (function () {
276
235
  "use strict";
277
236
 
278
- var adsafe_id, // The widget's ADsafe id.
279
- adsafe_may, // The widget may load approved scripts.
280
- adsafe_went, // ADSAFE.go has been called.
281
- anonname, // The guessed name for anonymous functions.
282
- approved, // ADsafe approved urls.
237
+ var anonname, // The guessed name for anonymous functions.
283
238
 
284
239
  // These are operators that should not be used with the ! operator.
285
240
 
@@ -299,137 +254,202 @@ var JSHINT = (function () {
299
254
  '%' : true
300
255
  },
301
256
 
302
- // These are property names that should not be permitted in the safe subset.
303
-
304
- banned = { // the member names that ADsafe prohibits.
305
- 'arguments' : true,
306
- callee : true,
307
- caller : true,
308
- constructor : true,
309
- 'eval' : true,
310
- prototype : true,
311
- stack : true,
312
- unwatch : true,
313
- valueOf : true,
314
- watch : true
315
- },
316
-
317
-
318
- // These are the JSHint boolean options.
319
-
257
+ // These are the JSHint boolean options.
320
258
  boolOptions = {
321
- adsafe : true, // if ADsafe should be enforced
322
- asi : true, // if automatic semicolon insertion should be tolerated
323
- bitwise : true, // if bitwise operators should not be allowed
324
- boss : true, // if advanced usage of assignments and == should be allowed
325
- browser : true, // if the standard browser globals should be predefined
326
- cap : true, // if upper case HTML should be allowed
327
- couch : true, // if CouchDB globals should be predefined
328
- css : true, // if CSS workarounds should be tolerated
329
- curly : true, // if curly braces around blocks should be required (even in if/for/while)
330
- debug : true, // if debugger statements should be allowed
331
- devel : true, // if logging should be allowed (console, alert, etc.)
332
- eqeqeq : true, // if === should be required
333
- es5 : true, // if ES5 syntax should be allowed
334
- evil : true, // if eval should be allowed
335
- forin : true, // if for in statements must filter
336
- fragment : true, // if HTML fragments should be allowed
337
- immed : true, // if immediate invocations must be wrapped in parens
338
- jquery : true, // if jQuery globals should be predefined
339
- laxbreak : true, // if line breaks should not be checked
340
- loopfunc : true, // if functions should be allowed to be defined within loops
341
- newcap : true, // if constructor names must be capitalized
342
- noarg : true, // if arguments.caller and arguments.callee should be disallowed
343
- node : true, // if the Node.js environment globals should be predefined
344
- noempty : true, // if empty blocks should be disallowed
345
- nonew : true, // if using `new` for side-effects should be disallowed
346
- nomen : true, // if names should be checked
347
- on : true, // if HTML event handlers should be allowed
348
- onevar : true, // if only one var statement per function should be allowed
349
- passfail : true, // if the scan should stop on first error
350
- plusplus : true, // if increment/decrement should not be allowed
351
- regexp : true, // if the . should not be allowed in regexp literals
352
- rhino : true, // if the Rhino environment globals should be predefined
353
- undef : true, // if variables should be declared before used
354
- safe : true, // if use of some browser features should be restricted
355
- windows : true, // if MS Windows-specific globals should be predefined
356
- strict : true, // require the "use strict"; pragma
357
- sub : true, // if all forms of subscript notation are tolerated
358
- white : true, // if strict whitespace rules apply
359
- widget : true, // if the Yahoo Widgets globals should be predefined
360
-
361
- // jshint_on_rails options
362
- lastsemic : true, // if lack of semicolon at the end of block should be ignored
363
- newstat : true, // if 'new used as a statement' warning should be ignored
364
- statinexp : true // ignores 'expected statement, got expression' errors if exp. contains a statement
259
+ asi : true, // if automatic semicolon insertion should be tolerated
260
+ bitwise : true, // if bitwise operators should not be allowed
261
+ boss : true, // if advanced usage of assignments should be allowed
262
+ browser : true, // if the standard browser globals should be predefined
263
+ couch : true, // if CouchDB globals should be predefined
264
+ curly : true, // if curly braces around all blocks should be required
265
+ debug : true, // if debugger statements should be allowed
266
+ devel : true, // if logging globals should be predefined (console,
267
+ // alert, etc.)
268
+ dojo : true, // if Dojo Toolkit globals should be predefined
269
+ eqeqeq : true, // if === should be required
270
+ eqnull : true, // if == null comparisons should be tolerated
271
+ es5 : true, // if ES5 syntax should be allowed
272
+ evil : true, // if eval should be allowed
273
+ expr : true, // if ExpressionStatement should be allowed as Programs
274
+ forin : true, // if for in statements must filter
275
+ globalstrict: true, // if global "use strict"; should be allowed (also
276
+ // enables 'strict')
277
+ immed : true, // if immediate invocations must be wrapped in parens
278
+ iterator : true, // if the `__iterator__` property should be disallowed
279
+ jquery : true, // if jQuery globals should be predefined
280
+ lastsemic : true, // if semicolons may be ommitted for the trailing
281
+ // statements inside of a one-line blocks.
282
+ latedef : true, // if the use before definition should not be tolerated
283
+ laxbreak : true, // if line breaks should not be checked
284
+ loopfunc : true, // if functions should be allowed to be defined within
285
+ // loops
286
+ mootools : true, // if MooTools globals should be predefined
287
+ newcap : true, // if constructor names must be capitalized
288
+ noarg : true, // if arguments.caller and arguments.callee should be
289
+ // disallowed
290
+ node : true, // if the Node.js environment globals should be
291
+ // predefined
292
+ noempty : true, // if empty blocks should be disallowed
293
+ nonew : true, // if using `new` for side-effects should be disallowed
294
+ nonstandard : true, // if non-standard (but widely adopted) globals should
295
+ // be predefined
296
+ nomen : true, // if names should be checked
297
+ onevar : true, // if only one var statement per function should be
298
+ // allowed
299
+ onecase : true, // if one case switch statements should be allowed
300
+ passfail : true, // if the scan should stop on first error
301
+ plusplus : true, // if increment/decrement should not be allowed
302
+ proto : true, // if the `__proto__` property should be disallowed
303
+ prototypejs : true, // if Prototype and Scriptaculous globals should be
304
+ // predefined
305
+ regexdash : true, // if unescaped last dash (-) inside brackets should be
306
+ // tolerated
307
+ regexp : true, // if the . should not be allowed in regexp literals
308
+ rhino : true, // if the Rhino environment globals should be predefined
309
+ undef : true, // if variables should be declared before used
310
+ scripturl : true, // if script-targeted URLs should be tolerated
311
+ shadow : true, // if variable shadowing should be tolerated
312
+ strict : true, // require the "use strict"; pragma
313
+ sub : true, // if all forms of subscript notation are tolerated
314
+ supernew : true, // if `new function () { ... };` and `new Object;`
315
+ // should be tolerated
316
+ trailing : true, // if trailing whitespace rules apply
317
+ validthis : true, // if 'this' inside a non-constructor function is valid.
318
+ // This is a function scoped option only.
319
+ white : true, // if strict whitespace rules apply
320
+ wsh : true // if the Windows Scripting Host environment globals
321
+ // should be predefined
365
322
  },
366
323
 
367
- // browser contains a set of global names which are commonly provided by a
368
- // web browser environment.
369
-
324
+ // browser contains a set of global names which are commonly provided by a
325
+ // web browser environment.
370
326
  browser = {
371
- ArrayBuffer : false,
372
- ArrayBufferView : false,
373
- addEventListener: false,
374
- applicationCache: false,
375
- blur : false,
376
- clearInterval : false,
377
- clearTimeout : false,
378
- close : false,
379
- closed : false,
380
- DataView : false,
381
- defaultStatus : false,
382
- document : false,
383
- event : false,
384
- FileReader : false,
385
- Float32Array : false,
386
- Float64Array : false,
387
- focus : false,
388
- frames : false,
389
- getComputedStyle: false,
390
- history : false,
391
- Int16Array : false,
392
- Int32Array : false,
393
- Int8Array : false,
394
- Image : false,
395
- length : false,
396
- localStorage : false,
397
- location : false,
398
- moveBy : false,
399
- moveTo : false,
400
- name : false,
401
- navigator : false,
402
- onbeforeunload : true,
403
- onblur : true,
404
- onerror : true,
405
- onfocus : true,
406
- onload : true,
407
- onresize : true,
408
- onunload : true,
409
- open : false,
410
- openDatabase : false,
411
- opener : false,
412
- Option : false,
413
- parent : false,
414
- print : false,
415
- removeEventListener: false,
416
- resizeBy : false,
417
- resizeTo : false,
418
- screen : false,
419
- scroll : false,
420
- scrollBy : false,
421
- scrollTo : false,
422
- setInterval : false,
423
- setTimeout : false,
424
- status : false,
425
- top : false,
426
- Uint16Array : false,
427
- Uint32Array : false,
428
- Uint8Array : false,
429
- WebSocket : false,
430
- window : false,
431
- Worker : false,
432
- XMLHttpRequest : false
327
+ ArrayBuffer : false,
328
+ ArrayBufferView : false,
329
+ Audio : false,
330
+ addEventListener : false,
331
+ applicationCache : false,
332
+ blur : false,
333
+ clearInterval : false,
334
+ clearTimeout : false,
335
+ close : false,
336
+ closed : false,
337
+ DataView : false,
338
+ defaultStatus : false,
339
+ document : false,
340
+ event : false,
341
+ FileReader : false,
342
+ Float32Array : false,
343
+ Float64Array : false,
344
+ FormData : false,
345
+ focus : false,
346
+ frames : false,
347
+ getComputedStyle : false,
348
+ HTMLElement : false,
349
+ HTMLAnchorElement : false,
350
+ HTMLBaseElement : false,
351
+ HTMLBlockquoteElement : false,
352
+ HTMLBodyElement : false,
353
+ HTMLBRElement : false,
354
+ HTMLButtonElement : false,
355
+ HTMLCanvasElement : false,
356
+ HTMLDirectoryElement : false,
357
+ HTMLDivElement : false,
358
+ HTMLDListElement : false,
359
+ HTMLFieldSetElement : false,
360
+ HTMLFontElement : false,
361
+ HTMLFormElement : false,
362
+ HTMLFrameElement : false,
363
+ HTMLFrameSetElement : false,
364
+ HTMLHeadElement : false,
365
+ HTMLHeadingElement : false,
366
+ HTMLHRElement : false,
367
+ HTMLHtmlElement : false,
368
+ HTMLIFrameElement : false,
369
+ HTMLImageElement : false,
370
+ HTMLInputElement : false,
371
+ HTMLIsIndexElement : false,
372
+ HTMLLabelElement : false,
373
+ HTMLLayerElement : false,
374
+ HTMLLegendElement : false,
375
+ HTMLLIElement : false,
376
+ HTMLLinkElement : false,
377
+ HTMLMapElement : false,
378
+ HTMLMenuElement : false,
379
+ HTMLMetaElement : false,
380
+ HTMLModElement : false,
381
+ HTMLObjectElement : false,
382
+ HTMLOListElement : false,
383
+ HTMLOptGroupElement : false,
384
+ HTMLOptionElement : false,
385
+ HTMLParagraphElement : false,
386
+ HTMLParamElement : false,
387
+ HTMLPreElement : false,
388
+ HTMLQuoteElement : false,
389
+ HTMLScriptElement : false,
390
+ HTMLSelectElement : false,
391
+ HTMLStyleElement : false,
392
+ HTMLTableCaptionElement : false,
393
+ HTMLTableCellElement : false,
394
+ HTMLTableColElement : false,
395
+ HTMLTableElement : false,
396
+ HTMLTableRowElement : false,
397
+ HTMLTableSectionElement : false,
398
+ HTMLTextAreaElement : false,
399
+ HTMLTitleElement : false,
400
+ HTMLUListElement : false,
401
+ HTMLVideoElement : false,
402
+ history : false,
403
+ Int16Array : false,
404
+ Int32Array : false,
405
+ Int8Array : false,
406
+ Image : false,
407
+ length : false,
408
+ localStorage : false,
409
+ location : false,
410
+ moveBy : false,
411
+ moveTo : false,
412
+ name : false,
413
+ navigator : false,
414
+ onbeforeunload : true,
415
+ onblur : true,
416
+ onerror : true,
417
+ onfocus : true,
418
+ onload : true,
419
+ onresize : true,
420
+ onunload : true,
421
+ open : false,
422
+ openDatabase : false,
423
+ opener : false,
424
+ Option : false,
425
+ parent : false,
426
+ print : false,
427
+ removeEventListener : false,
428
+ resizeBy : false,
429
+ resizeTo : false,
430
+ screen : false,
431
+ scroll : false,
432
+ scrollBy : false,
433
+ scrollTo : false,
434
+ sessionStorage : false,
435
+ setInterval : false,
436
+ setTimeout : false,
437
+ SharedWorker : false,
438
+ status : false,
439
+ top : false,
440
+ Uint16Array : false,
441
+ Uint32Array : false,
442
+ Uint8Array : false,
443
+ WebSocket : false,
444
+ window : false,
445
+ Worker : false,
446
+ XMLHttpRequest : false,
447
+ XPathEvaluator : false,
448
+ XPathException : false,
449
+ XPathExpression : false,
450
+ XPathNamespace : false,
451
+ XPathNSResolver : false,
452
+ XPathResult : false
433
453
  },
434
454
 
435
455
  couch = {
@@ -445,205 +465,21 @@ var JSHINT = (function () {
445
465
  module : false
446
466
  },
447
467
 
448
- cssAttributeData,
449
- cssAny,
450
-
451
- cssColorData = {
452
- "aliceblue" : true,
453
- "antiquewhite" : true,
454
- "aqua" : true,
455
- "aquamarine" : true,
456
- "azure" : true,
457
- "beige" : true,
458
- "bisque" : true,
459
- "black" : true,
460
- "blanchedalmond" : true,
461
- "blue" : true,
462
- "blueviolet" : true,
463
- "brown" : true,
464
- "burlywood" : true,
465
- "cadetblue" : true,
466
- "chartreuse" : true,
467
- "chocolate" : true,
468
- "coral" : true,
469
- "cornflowerblue" : true,
470
- "cornsilk" : true,
471
- "crimson" : true,
472
- "cyan" : true,
473
- "darkblue" : true,
474
- "darkcyan" : true,
475
- "darkgoldenrod" : true,
476
- "darkgray" : true,
477
- "darkgreen" : true,
478
- "darkkhaki" : true,
479
- "darkmagenta" : true,
480
- "darkolivegreen" : true,
481
- "darkorange" : true,
482
- "darkorchid" : true,
483
- "darkred" : true,
484
- "darksalmon" : true,
485
- "darkseagreen" : true,
486
- "darkslateblue" : true,
487
- "darkslategray" : true,
488
- "darkturquoise" : true,
489
- "darkviolet" : true,
490
- "deeppink" : true,
491
- "deepskyblue" : true,
492
- "dimgray" : true,
493
- "dodgerblue" : true,
494
- "firebrick" : true,
495
- "floralwhite" : true,
496
- "forestgreen" : true,
497
- "fuchsia" : true,
498
- "gainsboro" : true,
499
- "ghostwhite" : true,
500
- "gold" : true,
501
- "goldenrod" : true,
502
- "gray" : true,
503
- "green" : true,
504
- "greenyellow" : true,
505
- "honeydew" : true,
506
- "hotpink" : true,
507
- "indianred" : true,
508
- "indigo" : true,
509
- "ivory" : true,
510
- "khaki" : true,
511
- "lavender" : true,
512
- "lavenderblush" : true,
513
- "lawngreen" : true,
514
- "lemonchiffon" : true,
515
- "lightblue" : true,
516
- "lightcoral" : true,
517
- "lightcyan" : true,
518
- "lightgoldenrodyellow" : true,
519
- "lightgreen" : true,
520
- "lightpink" : true,
521
- "lightsalmon" : true,
522
- "lightseagreen" : true,
523
- "lightskyblue" : true,
524
- "lightslategray" : true,
525
- "lightsteelblue" : true,
526
- "lightyellow" : true,
527
- "lime" : true,
528
- "limegreen" : true,
529
- "linen" : true,
530
- "magenta" : true,
531
- "maroon" : true,
532
- "mediumaquamarine" : true,
533
- "mediumblue" : true,
534
- "mediumorchid" : true,
535
- "mediumpurple" : true,
536
- "mediumseagreen" : true,
537
- "mediumslateblue" : true,
538
- "mediumspringgreen" : true,
539
- "mediumturquoise" : true,
540
- "mediumvioletred" : true,
541
- "midnightblue" : true,
542
- "mintcream" : true,
543
- "mistyrose" : true,
544
- "moccasin" : true,
545
- "navajowhite" : true,
546
- "navy" : true,
547
- "oldlace" : true,
548
- "olive" : true,
549
- "olivedrab" : true,
550
- "orange" : true,
551
- "orangered" : true,
552
- "orchid" : true,
553
- "palegoldenrod" : true,
554
- "palegreen" : true,
555
- "paleturquoise" : true,
556
- "palevioletred" : true,
557
- "papayawhip" : true,
558
- "peachpuff" : true,
559
- "peru" : true,
560
- "pink" : true,
561
- "plum" : true,
562
- "powderblue" : true,
563
- "purple" : true,
564
- "red" : true,
565
- "rosybrown" : true,
566
- "royalblue" : true,
567
- "saddlebrown" : true,
568
- "salmon" : true,
569
- "sandybrown" : true,
570
- "seagreen" : true,
571
- "seashell" : true,
572
- "sienna" : true,
573
- "silver" : true,
574
- "skyblue" : true,
575
- "slateblue" : true,
576
- "slategray" : true,
577
- "snow" : true,
578
- "springgreen" : true,
579
- "steelblue" : true,
580
- "tan" : true,
581
- "teal" : true,
582
- "thistle" : true,
583
- "tomato" : true,
584
- "turquoise" : true,
585
- "violet" : true,
586
- "wheat" : true,
587
- "white" : true,
588
- "whitesmoke" : true,
589
- "yellow" : true,
590
- "yellowgreen" : true,
591
-
592
- "activeborder" : true,
593
- "activecaption" : true,
594
- "appworkspace" : true,
595
- "background" : true,
596
- "buttonface" : true,
597
- "buttonhighlight" : true,
598
- "buttonshadow" : true,
599
- "buttontext" : true,
600
- "captiontext" : true,
601
- "graytext" : true,
602
- "highlight" : true,
603
- "highlighttext" : true,
604
- "inactiveborder" : true,
605
- "inactivecaption" : true,
606
- "inactivecaptiontext" : true,
607
- "infobackground" : true,
608
- "infotext" : true,
609
- "menu" : true,
610
- "menutext" : true,
611
- "scrollbar" : true,
612
- "threeddarkshadow" : true,
613
- "threedface" : true,
614
- "threedhighlight" : true,
615
- "threedlightshadow" : true,
616
- "threedshadow" : true,
617
- "window" : true,
618
- "windowframe" : true,
619
- "windowtext" : true
620
- },
621
-
622
- cssBorderStyle,
623
- cssBreak,
624
-
625
- cssLengthData = {
626
- '%': true,
627
- 'cm': true,
628
- 'em': true,
629
- 'ex': true,
630
- 'in': true,
631
- 'mm': true,
632
- 'pc': true,
633
- 'pt': true,
634
- 'px': true
468
+ devel = {
469
+ alert : false,
470
+ confirm : false,
471
+ console : false,
472
+ Debug : false,
473
+ opera : false,
474
+ prompt : false
635
475
  },
636
476
 
637
- cssMedia,
638
- cssOverflow,
639
-
640
- devel = {
641
- alert : false,
642
- confirm : false,
643
- console : false,
644
- Debug : false,
645
- opera : false,
646
- prompt : false
477
+ dojo = {
478
+ dojo : false,
479
+ dijit : false,
480
+ dojox : false,
481
+ define : false,
482
+ "require" : false
647
483
  },
648
484
 
649
485
  escapes = {
@@ -667,125 +503,6 @@ var JSHINT = (function () {
667
503
  functions, // All of the functions
668
504
 
669
505
  global, // The global scope
670
- htmltag = {
671
- a: {},
672
- abbr: {},
673
- acronym: {},
674
- address: {},
675
- applet: {},
676
- area: {empty: true, parent: ' map '},
677
- article: {},
678
- aside: {},
679
- audio: {},
680
- b: {},
681
- base: {empty: true, parent: ' head '},
682
- bdo: {},
683
- big: {},
684
- blockquote: {},
685
- body: {parent: ' html noframes '},
686
- br: {empty: true},
687
- button: {},
688
- canvas: {parent: ' body p div th td '},
689
- caption: {parent: ' table '},
690
- center: {},
691
- cite: {},
692
- code: {},
693
- col: {empty: true, parent: ' table colgroup '},
694
- colgroup: {parent: ' table '},
695
- command: {parent: ' menu '},
696
- datalist: {},
697
- dd: {parent: ' dl '},
698
- del: {},
699
- details: {},
700
- dialog: {},
701
- dfn: {},
702
- dir: {},
703
- div: {},
704
- dl: {},
705
- dt: {parent: ' dl '},
706
- em: {},
707
- embed: {},
708
- fieldset: {},
709
- figure: {},
710
- font: {},
711
- footer: {},
712
- form: {},
713
- frame: {empty: true, parent: ' frameset '},
714
- frameset: {parent: ' html frameset '},
715
- h1: {},
716
- h2: {},
717
- h3: {},
718
- h4: {},
719
- h5: {},
720
- h6: {},
721
- head: {parent: ' html '},
722
- header: {},
723
- hgroup: {},
724
- hr: {empty: true},
725
- 'hta:application':
726
- {empty: true, parent: ' head '},
727
- html: {parent: '*'},
728
- i: {},
729
- iframe: {},
730
- img: {empty: true},
731
- input: {empty: true},
732
- ins: {},
733
- kbd: {},
734
- keygen: {},
735
- label: {},
736
- legend: {parent: ' details fieldset figure '},
737
- li: {parent: ' dir menu ol ul '},
738
- link: {empty: true, parent: ' head '},
739
- map: {},
740
- mark: {},
741
- menu: {},
742
- meta: {empty: true, parent: ' head noframes noscript '},
743
- meter: {},
744
- nav: {},
745
- noframes: {parent: ' html body '},
746
- noscript: {parent: ' body head noframes '},
747
- object: {},
748
- ol: {},
749
- optgroup: {parent: ' select '},
750
- option: {parent: ' optgroup select '},
751
- output: {},
752
- p: {},
753
- param: {empty: true, parent: ' applet object '},
754
- pre: {},
755
- progress: {},
756
- q: {},
757
- rp: {},
758
- rt: {},
759
- ruby: {},
760
- samp: {},
761
- script: {empty: true, parent: ' body div frame head iframe p pre span '},
762
- section: {},
763
- select: {},
764
- small: {},
765
- span: {},
766
- source: {},
767
- strong: {},
768
- style: {parent: ' head ', empty: true},
769
- sub: {},
770
- sup: {},
771
- table: {},
772
- tbody: {parent: ' table '},
773
- td: {parent: ' tr '},
774
- textarea: {},
775
- tfoot: {parent: ' table '},
776
- th: {parent: ' tr '},
777
- thead: {parent: ' table '},
778
- time: {},
779
- title: {parent: ' head '},
780
- tr: {parent: ' table tbody thead tfoot '},
781
- tt: {},
782
- u: {},
783
- ul: {},
784
- 'var': {},
785
- video: {}
786
- },
787
-
788
- ids, // HTML ids
789
506
  implied, // Implied globals
790
507
  inblock,
791
508
  indent,
@@ -800,12 +517,62 @@ var JSHINT = (function () {
800
517
  lookahead,
801
518
  member,
802
519
  membersOnly,
520
+
521
+ mootools = {
522
+ '$' : false,
523
+ '$$' : false,
524
+ Assets : false,
525
+ Browser : false,
526
+ Chain : false,
527
+ Class : false,
528
+ Color : false,
529
+ Cookie : false,
530
+ Core : false,
531
+ Document : false,
532
+ DomReady : false,
533
+ DOMReady : false,
534
+ Drag : false,
535
+ Element : false,
536
+ Elements : false,
537
+ Event : false,
538
+ Events : false,
539
+ Fx : false,
540
+ Group : false,
541
+ Hash : false,
542
+ HtmlTable : false,
543
+ Iframe : false,
544
+ IframeShim : false,
545
+ InputValidator : false,
546
+ instanceOf : false,
547
+ Keyboard : false,
548
+ Locale : false,
549
+ Mask : false,
550
+ MooTools : false,
551
+ Native : false,
552
+ Options : false,
553
+ OverText : false,
554
+ Request : false,
555
+ Scroller : false,
556
+ Slick : false,
557
+ Slider : false,
558
+ Sortables : false,
559
+ Spinner : false,
560
+ Swiff : false,
561
+ Tips : false,
562
+ Type : false,
563
+ typeOf : false,
564
+ URI : false,
565
+ Window : false
566
+ },
567
+
803
568
  nexttoken,
804
569
 
805
570
  node = {
806
571
  __filename : false,
807
572
  __dirname : false,
808
573
  Buffer : false,
574
+ console : false,
575
+ exports : false,
809
576
  GLOBAL : false,
810
577
  global : false,
811
578
  module : false,
@@ -819,6 +586,47 @@ var JSHINT = (function () {
819
586
  prereg,
820
587
  prevtoken,
821
588
 
589
+ prototypejs = {
590
+ '$' : false,
591
+ '$$' : false,
592
+ '$A' : false,
593
+ '$F' : false,
594
+ '$H' : false,
595
+ '$R' : false,
596
+ '$break' : false,
597
+ '$continue' : false,
598
+ '$w' : false,
599
+ Abstract : false,
600
+ Ajax : false,
601
+ Class : false,
602
+ Enumerable : false,
603
+ Element : false,
604
+ Event : false,
605
+ Field : false,
606
+ Form : false,
607
+ Hash : false,
608
+ Insertion : false,
609
+ ObjectRange : false,
610
+ PeriodicalExecuter: false,
611
+ Position : false,
612
+ Prototype : false,
613
+ Selector : false,
614
+ Template : false,
615
+ Toggle : false,
616
+ Try : false,
617
+ Autocompleter : false,
618
+ Builder : false,
619
+ Control : false,
620
+ Draggable : false,
621
+ Draggables : false,
622
+ Droppables : false,
623
+ Effect : false,
624
+ Sortable : false,
625
+ SortableObserver : false,
626
+ Sound : false,
627
+ Scriptaculous : false
628
+ },
629
+
822
630
  rhino = {
823
631
  defineClass : false,
824
632
  deserialize : false,
@@ -843,9 +651,8 @@ var JSHINT = (function () {
843
651
  src,
844
652
  stack,
845
653
 
846
- // standard contains the global names that are provided by the
847
- // ECMAScript standard.
848
-
654
+ // standard contains the global names that are provided by the
655
+ // ECMAScript standard.
849
656
  standard = {
850
657
  Array : false,
851
658
  Boolean : false,
@@ -876,6 +683,12 @@ var JSHINT = (function () {
876
683
  URIError : false
877
684
  },
878
685
 
686
+ // widely adopted global names that are not part of ECMAScript standard
687
+ nonstandard = {
688
+ escape : false,
689
+ unescape : false
690
+ },
691
+
879
692
  standard_member = {
880
693
  E : true,
881
694
  LN2 : true,
@@ -898,149 +711,49 @@ var JSHINT = (function () {
898
711
  urls,
899
712
  warnings,
900
713
 
901
- // widget contains the global names which are provided to a Yahoo
902
- // (fna Konfabulator) widget.
903
-
904
- widget = {
905
- alert : true,
906
- animator : true,
907
- appleScript : true,
908
- beep : true,
909
- bytesToUIString : true,
910
- Canvas : true,
911
- chooseColor : true,
912
- chooseFile : true,
913
- chooseFolder : true,
914
- closeWidget : true,
915
- COM : true,
916
- convertPathToHFS : true,
917
- convertPathToPlatform : true,
918
- CustomAnimation : true,
919
- escape : true,
920
- FadeAnimation : true,
921
- filesystem : true,
922
- Flash : true,
923
- focusWidget : true,
924
- form : true,
925
- FormField : true,
926
- Frame : true,
927
- HotKey : true,
928
- Image : true,
929
- include : true,
930
- isApplicationRunning : true,
931
- iTunes : true,
932
- konfabulatorVersion : true,
933
- log : true,
934
- md5 : true,
935
- MenuItem : true,
936
- MoveAnimation : true,
937
- openURL : true,
938
- play : true,
939
- Point : true,
940
- popupMenu : true,
941
- preferenceGroups : true,
942
- preferences : true,
943
- print : true,
944
- prompt : true,
945
- random : true,
946
- Rectangle : true,
947
- reloadWidget : true,
948
- ResizeAnimation : true,
949
- resolvePath : true,
950
- resumeUpdates : true,
951
- RotateAnimation : true,
952
- runCommand : true,
953
- runCommandInBg : true,
954
- saveAs : true,
955
- savePreferences : true,
956
- screen : true,
957
- ScrollBar : true,
958
- showWidgetPreferences : true,
959
- sleep : true,
960
- speak : true,
961
- Style : true,
962
- suppressUpdates : true,
963
- system : true,
964
- tellWidget : true,
965
- Text : true,
966
- TextArea : true,
967
- Timer : true,
968
- unescape : true,
969
- updateNow : true,
970
- URL : true,
971
- Web : true,
972
- widget : true,
973
- Window : true,
974
- XMLDOM : true,
975
- XMLHttpRequest : true,
976
- yahooCheckLogin : true,
977
- yahooLogin : true,
978
- yahooLogout : true
979
- },
714
+ wsh = {
715
+ ActiveXObject : true,
716
+ Enumerator : true,
717
+ GetObject : true,
718
+ ScriptEngine : true,
719
+ ScriptEngineBuildVersion : true,
720
+ ScriptEngineMajorVersion : true,
721
+ ScriptEngineMinorVersion : true,
722
+ VBArray : true,
723
+ WSH : true,
724
+ WScript : true
725
+ };
980
726
 
981
- windows = {
982
- ActiveXObject: false,
983
- CScript : false,
984
- Debug : false,
985
- Enumerator : false,
986
- System : false,
987
- VBArray : false,
988
- WScript : false
989
- },
727
+ // Regular expressions. Some of these are stupidly long.
728
+ var ax, cx, tx, nx, nxg, lx, ix, jx, ft;
729
+ (function () {
730
+ /*jshint maxlen:300 */
990
731
 
991
- // xmode is used to adapt to the exceptions in html parsing.
992
- // It can have these states:
993
- // false .js script file
994
- // html
995
- // outer
996
- // script
997
- // style
998
- // scriptstring
999
- // styleproperty
1000
-
1001
- xmode,
1002
- xquote,
1003
-
1004
- // Regular expressions. Some of these are stupidly long.
1005
-
1006
- // unsafe comment or string
1007
- ax = /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i,
1008
- // unsafe characters that are silently deleted by one or more browsers
1009
- cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
1010
- // token
1011
- tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
1012
- // html token
1013
- hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,
1014
- // characters in strings that need escapement
1015
- nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
1016
- nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
1017
- // outer html token
1018
- ox = /[>&]|<[\/!]?|--/,
1019
- // star slash
1020
- lx = /\*\/|\/\*/,
1021
- // identifier
1022
- ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
1023
- // javascript url
1024
- jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
1025
- // url badness
1026
- ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,
1027
- // style
1028
- sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
1029
- ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,
1030
- // attributes characters
1031
- qx = /[^a-zA-Z0-9+\-_\/ ]/,
1032
- // query characters for ids
1033
- dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
1034
- // catches /* falls through */ comments
1035
- ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/,
1036
-
1037
- rx = {
1038
- outer: hx,
1039
- html: hx,
1040
- style: sx,
1041
- styleproperty: ssx
1042
- };
732
+ // unsafe comment or string
733
+ ax = /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
734
+
735
+ // unsafe characters that are silently deleted by one or more browsers
736
+ cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
737
+
738
+ // token
739
+ 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]+)?)/;
740
+
741
+ // characters in strings that need escapement
742
+ nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
743
+ nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
744
+
745
+ // star slash
746
+ lx = /\*\/|\/\*/;
747
+
748
+ // identifier
749
+ ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
750
+
751
+ // javascript url
752
+ jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
1043
753
 
754
+ // catches /* falls through */ comments
755
+ ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/;
756
+ }());
1044
757
 
1045
758
  function F() {} // Used by Object.create
1046
759
 
@@ -1148,44 +861,53 @@ var JSHINT = (function () {
1148
861
  }
1149
862
 
1150
863
  function assume() {
1151
- if (option.safe)
1152
- return;
1153
-
1154
864
  if (option.couch)
1155
865
  combine(predefined, couch);
1156
866
 
1157
867
  if (option.rhino)
1158
868
  combine(predefined, rhino);
1159
869
 
870
+ if (option.prototypejs)
871
+ combine(predefined, prototypejs);
872
+
1160
873
  if (option.node)
1161
874
  combine(predefined, node);
1162
875
 
1163
876
  if (option.devel)
1164
877
  combine(predefined, devel);
1165
878
 
879
+ if (option.dojo)
880
+ combine(predefined, dojo);
881
+
1166
882
  if (option.browser)
1167
883
  combine(predefined, browser);
1168
884
 
885
+ if (option.nonstandard)
886
+ combine(predefined, nonstandard);
887
+
1169
888
  if (option.jquery)
1170
889
  combine(predefined, jquery);
1171
890
 
1172
- if (option.windows)
1173
- combine(predefined, windows);
891
+ if (option.mootools)
892
+ combine(predefined, mootools);
893
+
894
+ if (option.wsh)
895
+ combine(predefined, wsh);
1174
896
 
1175
- if (option.widget)
1176
- combine(predefined, widget);
897
+ if (option.globalstrict && option.strict !== false)
898
+ option.strict = true;
1177
899
  }
1178
900
 
1179
901
 
1180
- // Produce an error warning.
902
+ // Produce an error warning.
903
+ function quit(message, line, chr) {
904
+ var percentage = Math.floor((line / lines.length) * 100);
1181
905
 
1182
- function quit(m, l, ch) {
1183
906
  throw {
1184
907
  name: 'JSHintError',
1185
- line: l,
1186
- character: ch,
1187
- message: m + " (" + Math.floor((l / lines.length) * 100) +
1188
- "% scanned)."
908
+ line: line,
909
+ character: chr,
910
+ message: message + " (" + percentage + "% scanned)."
1189
911
  };
1190
912
  }
1191
913
 
@@ -1229,7 +951,6 @@ var JSHINT = (function () {
1229
951
 
1230
952
  function error(m, t, a, b, c, d) {
1231
953
  var w = warning(m, t, a, b, c, d);
1232
- quit("Stopping, unable to continue.", w.line, w.character);
1233
954
  }
1234
955
 
1235
956
  function errorAt(m, l, ch, a, b, c, d) {
@@ -1249,25 +970,34 @@ var JSHINT = (function () {
1249
970
  // Private lex methods
1250
971
 
1251
972
  function nextLine() {
1252
- var at;
1253
- if (line >= lines.length) {
973
+ var at,
974
+ tw; // trailing whitespace check
975
+
976
+ if (line >= lines.length)
1254
977
  return false;
1255
- }
978
+
1256
979
  character = 1;
1257
980
  s = lines[line];
1258
981
  line += 1;
1259
982
  at = s.search(/ \t/);
1260
- if (at >= 0) {
983
+
984
+ if (at >= 0)
1261
985
  warningAt("Mixed spaces and tabs.", line, at + 1);
1262
- }
986
+
1263
987
  s = s.replace(/\t/g, tab);
1264
988
  at = s.search(cx);
1265
- if (at >= 0) {
989
+
990
+ if (at >= 0)
1266
991
  warningAt("Unsafe character.", line, at);
1267
- }
1268
- if (option.maxlen && option.maxlen < s.length) {
992
+
993
+ if (option.maxlen && option.maxlen < s.length)
1269
994
  warningAt("Line too long.", line, s.length);
1270
- }
995
+
996
+ // Check for trailing whitespaces
997
+ tw = s.search(/\s+$/);
998
+ if (option.trailing && ~tw && !~s.search(/^\s+$/))
999
+ warningAt("Trailing whitespace.", line, tw);
1000
+
1271
1001
  return true;
1272
1002
  }
1273
1003
 
@@ -1285,20 +1015,24 @@ var JSHINT = (function () {
1285
1015
  }
1286
1016
  t = Object.create(t);
1287
1017
  if (type === '(string)' || type === '(range)') {
1288
- if (jx.test(value)) {
1018
+ if (!option.scripturl && jx.test(value)) {
1289
1019
  warningAt("Script URL.", line, from);
1290
1020
  }
1291
1021
  }
1292
1022
  if (type === '(identifier)') {
1293
1023
  t.identifier = true;
1294
- if (value === '__iterator__' || value === '__proto__') {
1295
- errorAt("Reserved name '{a}'.",
1024
+ if (value === '__proto__' && !option.proto) {
1025
+ warningAt("The '{a}' property is deprecated.",
1296
1026
  line, from, value);
1297
- } else if (option.nomen &&
1298
- (value.charAt(0) === '_' ||
1027
+ } else if (value === '__iterator__' && !option.iterator) {
1028
+ warningAt("'{a}' is only available in JavaScript 1.7.",
1029
+ line, from, value);
1030
+ } else if (option.nomen && (value.charAt(0) === '_' ||
1299
1031
  value.charAt(value.length - 1) === '_')) {
1300
- warningAt("Unexpected {a} in '{b}'.", line, from,
1301
- "dangling '_'", value);
1032
+ if (!option.node || token.id == '.' ||
1033
+ (value != '__dirname' && value != '__filename')) {
1034
+ warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", value);
1035
+ }
1302
1036
  }
1303
1037
  }
1304
1038
  t.value = value;
@@ -1314,8 +1048,7 @@ var JSHINT = (function () {
1314
1048
  return t;
1315
1049
  }
1316
1050
 
1317
- // Public lex methods
1318
-
1051
+ // Public lex methods
1319
1052
  return {
1320
1053
  init: function (source) {
1321
1054
  if (typeof source === 'string') {
@@ -1327,10 +1060,10 @@ var JSHINT = (function () {
1327
1060
  lines = source;
1328
1061
  }
1329
1062
 
1330
- // If the first line is a shebang (#!), remove it and move on.
1063
+ // If the first line is a shebang (#!), make it a blank and move on.
1331
1064
  // Shebangs are used by Node scripts.
1332
1065
  if (lines[0] && lines[0].substr(0, 2) == '#!')
1333
- lines.shift();
1066
+ lines[0] = '';
1334
1067
 
1335
1068
  line = 0;
1336
1069
  nextLine();
@@ -1356,7 +1089,6 @@ var JSHINT = (function () {
1356
1089
  s = s.slice(1);
1357
1090
  character += 1;
1358
1091
  return it('(range)', value);
1359
- case xquote:
1360
1092
  case '\\':
1361
1093
  warningAt("Unexpected '{a}'.", line, character, c);
1362
1094
  }
@@ -1365,8 +1097,8 @@ var JSHINT = (function () {
1365
1097
 
1366
1098
  },
1367
1099
 
1368
- // token -- this is called by advance to get the next token.
1369
1100
 
1101
+ // token -- this is called by advance to get the next token
1370
1102
  token: function () {
1371
1103
  var b, c, captures, d, depth, high, i, l, low, q, t;
1372
1104
 
@@ -1391,10 +1123,6 @@ var JSHINT = (function () {
1391
1123
  line, character);
1392
1124
  }
1393
1125
 
1394
- if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
1395
- return it('(punctuator)', x);
1396
- }
1397
-
1398
1126
  function esc(n) {
1399
1127
  var i = parseInt(s.substr(j + 1, n), 16);
1400
1128
  j += n;
@@ -1409,7 +1137,7 @@ var JSHINT = (function () {
1409
1137
  for (;;) {
1410
1138
  while (j >= s.length) {
1411
1139
  j = 0;
1412
- if (xmode !== 'html' || !nextLine()) {
1140
+ if (!nextLine()) {
1413
1141
  errorAt("Unclosed string.", line, from);
1414
1142
  }
1415
1143
  }
@@ -1425,82 +1153,52 @@ var JSHINT = (function () {
1425
1153
  }
1426
1154
  warningAt("Control character in string: {a}.",
1427
1155
  line, character + j, s.slice(0, j));
1428
- } else if (c === xquote) {
1429
- warningAt("Bad HTML string", line, character + j);
1430
- } else if (c === '<') {
1431
- if (option.safe && xmode === 'html') {
1432
- warningAt("ADsafe string violation.",
1433
- line, character + j);
1434
- } else if (s.charAt(j + 1) === '/' && (xmode || option.safe)) {
1435
- warningAt("Expected '<\\/' and instead saw '</'.", line, character);
1436
- } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {
1437
- warningAt("Unexpected '<!' in a string.", line, character);
1438
- }
1439
1156
  } else if (c === '\\') {
1440
- if (xmode === 'html') {
1441
- if (option.safe) {
1442
- warningAt("ADsafe string violation.",
1443
- line, character + j);
1157
+ j += 1;
1158
+ character += 1;
1159
+ c = s.charAt(j);
1160
+ switch (c) {
1161
+ case '\\':
1162
+ case '"':
1163
+ case '/':
1164
+ break;
1165
+ case '\'':
1166
+ if (jsonmode) {
1167
+ warningAt("Avoid \\'.", line, character);
1444
1168
  }
1445
- } else if (xmode === 'styleproperty') {
1446
- j += 1;
1447
- character += 1;
1448
- c = s.charAt(j);
1449
- if (c !== x) {
1450
- warningAt("Escapement in style string.",
1451
- line, character + j);
1169
+ break;
1170
+ case 'b':
1171
+ c = '\b';
1172
+ break;
1173
+ case 'f':
1174
+ c = '\f';
1175
+ break;
1176
+ case 'n':
1177
+ c = '\n';
1178
+ break;
1179
+ case 'r':
1180
+ c = '\r';
1181
+ break;
1182
+ case 't':
1183
+ c = '\t';
1184
+ break;
1185
+ case 'u':
1186
+ esc(4);
1187
+ break;
1188
+ case 'v':
1189
+ if (jsonmode) {
1190
+ warningAt("Avoid \\v.", line, character);
1452
1191
  }
1453
- } else {
1454
- j += 1;
1455
- character += 1;
1456
- c = s.charAt(j);
1457
- switch (c) {
1458
- case xquote:
1459
- warningAt("Bad HTML string", line,
1460
- character + j);
1461
- break;
1462
- case '\\':
1463
- case '"':
1464
- case '/':
1465
- break;
1466
- case '\'':
1467
- if (jsonmode) {
1468
- warningAt("Avoid \\'.", line, character);
1469
- }
1470
- break;
1471
- case 'b':
1472
- c = '\b';
1473
- break;
1474
- case 'f':
1475
- c = '\f';
1476
- break;
1477
- case 'n':
1478
- c = '\n';
1479
- break;
1480
- case 'r':
1481
- c = '\r';
1482
- break;
1483
- case 't':
1484
- c = '\t';
1485
- break;
1486
- case 'u':
1487
- esc(4);
1488
- break;
1489
- case 'v':
1490
- if (jsonmode) {
1491
- warningAt("Avoid \\v.", line, character);
1492
- }
1493
- c = '\v';
1494
- break;
1495
- case 'x':
1496
- if (jsonmode) {
1497
- warningAt("Avoid \\x-.", line, character);
1498
- }
1499
- esc(2);
1500
- break;
1501
- default:
1502
- warningAt("Bad escapement.", line, character);
1192
+ c = '\v';
1193
+ break;
1194
+ case 'x':
1195
+ if (jsonmode) {
1196
+ warningAt("Avoid \\x-.", line, character);
1503
1197
  }
1198
+ esc(2);
1199
+ break;
1200
+ default:
1201
+ warningAt("Bad escapement.", line, character);
1504
1202
  }
1505
1203
  }
1506
1204
  r += c;
@@ -1513,21 +1211,7 @@ var JSHINT = (function () {
1513
1211
  if (!s) {
1514
1212
  return it(nextLine() ? '(endline)' : '(end)', '');
1515
1213
  }
1516
- while (xmode === 'outer') {
1517
- i = s.search(ox);
1518
- if (i === 0) {
1519
- break;
1520
- } else if (i > 0) {
1521
- character += 1;
1522
- s = s.slice(i);
1523
- break;
1524
- } else {
1525
- if (!nextLine()) {
1526
- return it('(end)', '');
1527
- }
1528
- }
1529
- }
1530
- t = match(rx[xmode] || tx);
1214
+ t = match(tx);
1531
1215
  if (!t) {
1532
1216
  t = '';
1533
1217
  c = '';
@@ -1535,12 +1219,7 @@ var JSHINT = (function () {
1535
1219
  s = s.substr(1);
1536
1220
  }
1537
1221
  if (s) {
1538
- if (xmode === 'html') {
1539
- return it('(error)', s.charAt(0));
1540
- } else {
1541
- errorAt("Unexpected '{a}'.",
1542
- line, character, s.substr(0, 1));
1543
- }
1222
+ errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1));
1544
1223
  }
1545
1224
  } else {
1546
1225
 
@@ -1553,20 +1232,18 @@ var JSHINT = (function () {
1553
1232
  // number
1554
1233
 
1555
1234
  if (c.isDigit()) {
1556
- if (xmode !== 'style' && !isFinite(Number(t))) {
1235
+ if (!isFinite(Number(t))) {
1557
1236
  warningAt("Bad number '{a}'.",
1558
1237
  line, character, t);
1559
1238
  }
1560
- if (xmode !== 'style' &&
1561
- xmode !== 'styleproperty' &&
1562
- s.substr(0, 1).isAlpha()) {
1239
+ if (s.substr(0, 1).isAlpha()) {
1563
1240
  warningAt("Missing space after '{a}'.",
1564
1241
  line, character, t);
1565
1242
  }
1566
1243
  if (c === '0') {
1567
1244
  d = t.substr(1, 1);
1568
1245
  if (d.isDigit()) {
1569
- if (token.id !== '.' && xmode !== 'styleproperty') {
1246
+ if (token.id !== '.') {
1570
1247
  warningAt("Don't use extra leading zeros '{a}'.",
1571
1248
  line, character, t);
1572
1249
  }
@@ -1592,12 +1269,8 @@ var JSHINT = (function () {
1592
1269
  // // comment
1593
1270
 
1594
1271
  case '//':
1595
- if (src || (xmode && xmode !== 'script')) {
1272
+ if (src) {
1596
1273
  warningAt("Unexpected comment.", line, character);
1597
- } else if (xmode === 'script' && /<\s*\//i.test(s)) {
1598
- warningAt("Unexpected <\/ in comment.", line, character);
1599
- } else if ((option.safe || xmode === 'script') && ax.test(s)) {
1600
- warningAt("Dangerous comment.", line, character);
1601
1274
  }
1602
1275
  s = '';
1603
1276
  token.comment = true;
@@ -1606,12 +1279,9 @@ var JSHINT = (function () {
1606
1279
  // /* comment
1607
1280
 
1608
1281
  case '/*':
1609
- if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) {
1282
+ if (src) {
1610
1283
  warningAt("Unexpected comment.", line, character);
1611
1284
  }
1612
- if (option.safe && ax.test(s)) {
1613
- warningAt("ADsafe comment violation.", line, character);
1614
- }
1615
1285
  for (;;) {
1616
1286
  i = s.search(lx);
1617
1287
  if (i >= 0) {
@@ -1619,11 +1289,6 @@ var JSHINT = (function () {
1619
1289
  }
1620
1290
  if (!nextLine()) {
1621
1291
  errorAt("Unclosed comment.", line, character);
1622
- } else {
1623
- if (option.safe && ax.test(s)) {
1624
- warningAt("ADsafe comment violation.",
1625
- line, character);
1626
- }
1627
1292
  }
1628
1293
  }
1629
1294
  character += i + 2;
@@ -1639,6 +1304,7 @@ var JSHINT = (function () {
1639
1304
  case '/*members':
1640
1305
  case '/*member':
1641
1306
  case '/*jshint':
1307
+ case '/*jslint':
1642
1308
  case '/*global':
1643
1309
  case '*/':
1644
1310
  return {
@@ -1783,7 +1449,7 @@ klass: do {
1783
1449
  }
1784
1450
  break;
1785
1451
  case ']':
1786
- if (!q) {
1452
+ if (!q && !option.regexdash) {
1787
1453
  warningAt("Unescaped '{a}'.",
1788
1454
  line, from + l - 1, '-');
1789
1455
  }
@@ -1806,13 +1472,6 @@ klass: do {
1806
1472
  q = true;
1807
1473
  break;
1808
1474
  case '<':
1809
- if (xmode === 'script') {
1810
- c = s.charAt(l);
1811
- if (c === '!' || c === '/') {
1812
- warningAt(
1813
- "HTML confusion in regular expression '<{a}'.", line, from + l, c);
1814
- }
1815
- }
1816
1475
  q = true;
1817
1476
  break;
1818
1477
  default:
@@ -1834,15 +1493,6 @@ klass: do {
1834
1493
  case '*':
1835
1494
  warningAt("Unescaped '{a}'.", line,
1836
1495
  from + l, c);
1837
- break;
1838
- case '<':
1839
- if (xmode === 'script') {
1840
- c = s.charAt(l);
1841
- if (c === '!' || c === '/') {
1842
- warningAt(
1843
- "HTML confusion in regular expression '<{a}'.", line, from + l, c);
1844
- }
1845
- }
1846
1496
  }
1847
1497
  if (b) {
1848
1498
  switch (s.charAt(l)) {
@@ -1914,75 +1564,9 @@ klass: do {
1914
1564
 
1915
1565
  // punctuator
1916
1566
 
1917
- case '<!--':
1918
- l = line;
1919
- c = character;
1920
- for (;;) {
1921
- i = s.indexOf('--');
1922
- if (i >= 0) {
1923
- break;
1924
- }
1925
- i = s.indexOf('<!');
1926
- if (i >= 0) {
1927
- errorAt("Nested HTML comment.",
1928
- line, character + i);
1929
- }
1930
- if (!nextLine()) {
1931
- errorAt("Unclosed HTML comment.", l, c);
1932
- }
1933
- }
1934
- l = s.indexOf('<!');
1935
- if (l >= 0 && l < i) {
1936
- errorAt("Nested HTML comment.",
1937
- line, character + l);
1938
- }
1939
- character += i;
1940
- if (s.charAt(i + 2) !== '>') {
1941
- errorAt("Expected -->.", line, character);
1942
- }
1943
- character += 3;
1944
- s = s.slice(i + 3);
1945
- break;
1946
1567
  case '#':
1947
- if (xmode === 'html' || xmode === 'styleproperty') {
1948
- for (;;) {
1949
- c = s.charAt(0);
1950
- if ((c < '0' || c > '9') &&
1951
- (c < 'a' || c > 'f') &&
1952
- (c < 'A' || c > 'F')) {
1953
- break;
1954
- }
1955
- character += 1;
1956
- s = s.substr(1);
1957
- t += c;
1958
- }
1959
- if (t.length !== 4 && t.length !== 7) {
1960
- warningAt("Bad hex color '{a}'.", line,
1961
- from + l, t);
1962
- }
1963
- return it('(color)', t);
1964
- }
1965
1568
  return it('(punctuator)', t);
1966
1569
  default:
1967
- if (xmode === 'outer' && c === '&') {
1968
- character += 1;
1969
- s = s.substr(1);
1970
- for (;;) {
1971
- c = s.charAt(0);
1972
- character += 1;
1973
- s = s.substr(1);
1974
- if (c === ';') {
1975
- break;
1976
- }
1977
- if (!((c >= '0' && c <= '9') ||
1978
- (c >= 'a' && c <= 'z') ||
1979
- c === '#')) {
1980
- errorAt("Bad entity", line, from + l,
1981
- character);
1982
- }
1983
- }
1984
- break;
1985
- }
1986
1570
  return it('(punctuator)', t);
1987
1571
  }
1988
1572
  }
@@ -1994,26 +1578,28 @@ klass: do {
1994
1578
 
1995
1579
  function addlabel(t, type) {
1996
1580
 
1997
- if (option.safe && funct['(global)'] &&
1998
- typeof predefined[t] !== 'boolean') {
1999
- warning('ADsafe global: ' + t + '.', token);
2000
- } else if (t === 'hasOwnProperty') {
1581
+ if (t === 'hasOwnProperty') {
2001
1582
  warning("'hasOwnProperty' is a really bad name.");
2002
1583
  }
2003
1584
 
2004
1585
  // Define t in the current function in the current scope.
2005
1586
 
2006
1587
  if (is_own(funct, t) && !funct['(global)']) {
2007
- warning(funct[t] === true ?
2008
- "'{a}' was used before it was defined." :
2009
- "'{a}' is already defined.",
2010
- nexttoken, t);
1588
+ if (funct[t] === true) {
1589
+ if (option.latedef)
1590
+ warning("'{a}' was used before it was defined.", nexttoken, t);
1591
+ } else {
1592
+ if (!option.shadow)
1593
+ warning("'{a}' is already defined.", nexttoken, t);
1594
+ }
2011
1595
  }
1596
+
2012
1597
  funct[t] = type;
2013
1598
  if (funct['(global)']) {
2014
1599
  global[t] = funct;
2015
1600
  if (is_own(implied, t)) {
2016
- warning("'{a}' was used before it was defined.", nexttoken, t);
1601
+ if (option.latedef)
1602
+ warning("'{a}' was used before it was defined.", nexttoken, t);
2017
1603
  delete implied[t];
2018
1604
  }
2019
1605
  } else {
@@ -2037,16 +1623,11 @@ klass: do {
2037
1623
  obj = membersOnly;
2038
1624
  break;
2039
1625
  case '/*jshint':
2040
- if (option.safe) {
2041
- warning("ADsafe restriction.");
2042
- }
1626
+ case '/*jslint':
2043
1627
  obj = option;
2044
1628
  filter = boolOptions;
2045
1629
  break;
2046
1630
  case '/*global':
2047
- if (option.safe) {
2048
- warning("ADsafe restriction.");
2049
- }
2050
1631
  obj = predefined;
2051
1632
  break;
2052
1633
  default:
@@ -2074,7 +1655,7 @@ loop: for (;;) {
2074
1655
  error("Expected '{a}' and instead saw '{b}'.",
2075
1656
  t, '*/', ':');
2076
1657
  }
2077
- if (t.value === 'indent' && o === '/*jshint') {
1658
+ if (t.value === 'indent' && (o === '/*jshint' || o === '/*jslint')) {
2078
1659
  b = +v.value;
2079
1660
  if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
2080
1661
  Math.floor(b) !== b) {
@@ -2083,7 +1664,7 @@ loop: for (;;) {
2083
1664
  }
2084
1665
  obj.white = true;
2085
1666
  obj.indent = b;
2086
- } else if (t.value === 'maxerr' && o === '/*jshint') {
1667
+ } else if (t.value === 'maxerr' && (o === '/*jshint' || o === '/*jslint')) {
2087
1668
  b = +v.value;
2088
1669
  if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
2089
1670
  Math.floor(b) !== b) {
@@ -2091,7 +1672,7 @@ loop: for (;;) {
2091
1672
  v, v.value);
2092
1673
  }
2093
1674
  obj.maxerr = b;
2094
- } else if (t.value === 'maxlen' && o === '/*jshint') {
1675
+ } else if (t.value === 'maxlen' && (o === '/*jshint' || o === '/*jslint')) {
2095
1676
  b = +v.value;
2096
1677
  if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
2097
1678
  Math.floor(b) !== b) {
@@ -2099,6 +1680,15 @@ loop: for (;;) {
2099
1680
  v, v.value);
2100
1681
  }
2101
1682
  obj.maxlen = b;
1683
+ } else if (t.value == 'validthis') {
1684
+ if (funct['(global)']) {
1685
+ error("Option 'validthis' can't be used in a global scope.");
1686
+ } else {
1687
+ if (v.value === 'true' || v.value === 'false')
1688
+ obj[t.value] = v.value === 'true';
1689
+ else
1690
+ error("Bad option value.", v);
1691
+ }
2102
1692
  } else if (v.value === 'true') {
2103
1693
  obj[t.value] = true;
2104
1694
  } else if (v.value === 'false') {
@@ -2108,7 +1698,7 @@ loop: for (;;) {
2108
1698
  }
2109
1699
  t = lex.token();
2110
1700
  } else {
2111
- if (o === '/*jshint') {
1701
+ if (o === '/*jshint' || o === '/*jslint') {
2112
1702
  error("Missing option value.", t);
2113
1703
  }
2114
1704
  obj[t.value] = false;
@@ -2148,8 +1738,7 @@ loop: for (;;) {
2148
1738
  switch (token.id) {
2149
1739
  case '(number)':
2150
1740
  if (nexttoken.id === '.') {
2151
- warning(
2152
- "A dot following a number can be confused with a decimal point.", token);
1741
+ warning("A dot following a number can be confused with a decimal point.", token);
2153
1742
  }
2154
1743
  break;
2155
1744
  case '-':
@@ -2163,6 +1752,7 @@ loop: for (;;) {
2163
1752
  }
2164
1753
  break;
2165
1754
  }
1755
+
2166
1756
  if (token.type === '(string)' || token.identifier) {
2167
1757
  anonname = token.value;
2168
1758
  }
@@ -2172,8 +1762,7 @@ loop: for (;;) {
2172
1762
  if (nexttoken.id === '(end)') {
2173
1763
  warning("Unmatched '{a}'.", t, t.id);
2174
1764
  } else {
2175
- warning(
2176
- "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
1765
+ warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
2177
1766
  nexttoken, id, t.id, t.line, nexttoken.value);
2178
1767
  }
2179
1768
  } else if (nexttoken.type !== '(identifier)' ||
@@ -2182,6 +1771,7 @@ loop: for (;;) {
2182
1771
  nexttoken, id, nexttoken.value);
2183
1772
  }
2184
1773
  }
1774
+
2185
1775
  prevtoken = token;
2186
1776
  token = nexttoken;
2187
1777
  for (;;) {
@@ -2215,15 +1805,12 @@ loop: for (;;) {
2215
1805
  // They are elements of the parsing method called Top Down Operator Precedence.
2216
1806
 
2217
1807
  function expression(rbp, initial) {
2218
- var left;
2219
- if (nexttoken.id === '(end)') {
1808
+ var left, isArray = false;
1809
+
1810
+ if (nexttoken.id === '(end)')
2220
1811
  error("Unexpected early end of program.", token);
2221
- }
1812
+
2222
1813
  advance();
2223
- if (option.safe && typeof predefined[token.value] === 'boolean' &&
2224
- (nexttoken.id !== '(' && nexttoken.id !== '.')) {
2225
- warning('ADsafe violation.', token);
2226
- }
2227
1814
  if (initial) {
2228
1815
  anonname = 'anonymous';
2229
1816
  funct['(verb)'] = token.value;
@@ -2235,8 +1822,7 @@ loop: for (;;) {
2235
1822
  left = token.nud();
2236
1823
  } else {
2237
1824
  if (nexttoken.type === '(number)' && token.id === '.') {
2238
- warning(
2239
- "A leading decimal point can be confused with a dot: '.{a}'.",
1825
+ warning("A leading decimal point can be confused with a dot: '.{a}'.",
2240
1826
  token, nexttoken.value);
2241
1827
  advance();
2242
1828
  return token;
@@ -2246,7 +1832,10 @@ loop: for (;;) {
2246
1832
  }
2247
1833
  }
2248
1834
  while (rbp < nexttoken.lbp) {
1835
+ isArray = token.value == 'Array';
2249
1836
  advance();
1837
+ if (isArray && token.id == '(' && nexttoken.id == ')')
1838
+ warning("Use the array literal notation [].", token);
2250
1839
  if (token.led) {
2251
1840
  left = token.led(left);
2252
1841
  } else {
@@ -2264,7 +1853,7 @@ loop: for (;;) {
2264
1853
  function adjacent(left, right) {
2265
1854
  left = left || token;
2266
1855
  right = right || nexttoken;
2267
- if (option.white || xmode === 'styleproperty' || xmode === 'style') {
1856
+ if (option.white) {
2268
1857
  if (left.character !== right.from && left.line === right.line) {
2269
1858
  warning("Unexpected space after '{a}'.", right, left.value);
2270
1859
  }
@@ -2487,7 +2076,7 @@ loop: for (;;) {
2487
2076
  return node &&
2488
2077
  ((node.type === '(number)' && +node.value === 0) ||
2489
2078
  (node.type === '(string)' && node.value === '') ||
2490
- (node.type === 'null' && !option.boss) ||
2079
+ (node.type === 'null' && !option.eqnull) ||
2491
2080
  node.type === 'true' ||
2492
2081
  node.type === 'false' ||
2493
2082
  node.type === 'undefined');
@@ -2505,15 +2094,6 @@ loop: for (;;) {
2505
2094
  } else if (left['function']) {
2506
2095
  warning("'{a}' is a function.", left, left.value);
2507
2096
  }
2508
- if (option.safe) {
2509
- l = left;
2510
- do {
2511
- if (typeof predefined[l.value] === 'boolean') {
2512
- warning('ADsafe violation.', l);
2513
- }
2514
- l = l.left;
2515
- } while (l);
2516
- }
2517
2097
  if (left) {
2518
2098
  if (left.id === '.' || left.id === '[') {
2519
2099
  if (!left.left || left.left.value === 'arguments') {
@@ -2601,9 +2181,7 @@ loop: for (;;) {
2601
2181
  function optionalidentifier(fnparam) {
2602
2182
  if (nexttoken.identifier) {
2603
2183
  advance();
2604
- if (option.safe && banned[token.value]) {
2605
- warning("ADsafe violation: '{a}'.", token, token.value);
2606
- } else if (token.reserved && !option.es5) {
2184
+ if (token.reserved && !option.es5) {
2607
2185
  // `undefined` as a function param is a common pattern to protect
2608
2186
  // against the case when somebody does `undefined = true` and
2609
2187
  // help with minification. More info: https://gist.github.com/315916
@@ -2693,17 +2271,29 @@ loop: for (;;) {
2693
2271
  }
2694
2272
  r = expression(0, true);
2695
2273
 
2696
- // Look for the final semicolon.
2697
-
2274
+ // Look for the final semicolon.
2698
2275
  if (!t.block) {
2699
- if (!r || !r.exps) {
2700
- warning("Expected an assignment or function call and instead saw an expression.", token);
2276
+ if (!option.expr && (!r || !r.exps)) {
2277
+ warning("Expected an assignment or function call and instead saw an expression.",
2278
+ token);
2701
2279
  } else if (option.nonew && r.id === '(' && r.left.id === 'new') {
2702
2280
  warning("Do not use 'new' for side effects.");
2703
2281
  }
2282
+
2704
2283
  if (nexttoken.id !== ';') {
2705
2284
  if (!option.asi) {
2706
- warningAt("Missing semicolon.", token.line, token.from + token.value.length);
2285
+ // If this is the last statement in a block that ends on
2286
+ // the same line *and* option lastsemic is on, ignore the warning.
2287
+ // Otherwise, complain about missing semicolon.
2288
+ if (!option.lastsemic || nexttoken.id != '}' ||
2289
+ nexttoken.line != token.line) {
2290
+ warningAt("Missing semicolon.", token.line, token.from +
2291
+ token.value.length);
2292
+ }
2293
+ }
2294
+ if (!option.asi && !(option.lastsemic && nexttoken.id == '}' &&
2295
+ nexttoken.line == token.line)) {
2296
+
2707
2297
  }
2708
2298
  } else {
2709
2299
  adjacent(token, nexttoken);
@@ -2739,66 +2329,7 @@ loop: for (;;) {
2739
2329
 
2740
2330
  function statements(begin) {
2741
2331
  var a = [], f, p;
2742
- if (option.adsafe) {
2743
- switch (begin) {
2744
- case 'script':
2745
-
2746
- // JSHint is also the static analizer for ADsafe. See www.ADsafe.org.
2747
-
2748
- if (!adsafe_may) {
2749
- if (nexttoken.value !== 'ADSAFE' ||
2750
- peek(0).id !== '.' ||
2751
- (peek(1).value !== 'id' &&
2752
- peek(1).value !== 'go')) {
2753
- error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.',
2754
- nexttoken);
2755
- }
2756
- }
2757
- if (nexttoken.value === 'ADSAFE' &&
2758
- peek(0).id === '.' &&
2759
- peek(1).value === 'id') {
2760
- if (adsafe_may) {
2761
- error('ADsafe violation.', nexttoken);
2762
- }
2763
- advance('ADSAFE');
2764
- advance('.');
2765
- advance('id');
2766
- advance('(');
2767
- if (nexttoken.value !== adsafe_id) {
2768
- error('ADsafe violation: id does not match.', nexttoken);
2769
- }
2770
- advance('(string)');
2771
- advance(')');
2772
- advance(';');
2773
- adsafe_may = true;
2774
- }
2775
- break;
2776
- case 'lib':
2777
- if (nexttoken.value === 'ADSAFE') {
2778
- advance('ADSAFE');
2779
- advance('.');
2780
- advance('lib');
2781
- advance('(');
2782
- advance('(string)');
2783
- comma();
2784
- f = expression(0);
2785
- if (f.id !== 'function') {
2786
- error('The second argument to lib must be a function.', f);
2787
- }
2788
- p = f.funct['(params)'];
2789
- p = p && p.join(', ');
2790
- if (p && p !== 'lib') {
2791
- error("Expected '{a}' and instead saw '{b}'.",
2792
- f, '(lib)', '(' + p + ')');
2793
- }
2794
- advance(')');
2795
- advance(';');
2796
- return a;
2797
- } else {
2798
- error("ADsafe lib violation.");
2799
- }
2800
- }
2801
- }
2332
+
2802
2333
  while (!nexttoken.reach && nexttoken.id !== '(end)') {
2803
2334
  if (nexttoken.id === ';') {
2804
2335
  warning("Unnecessary semicolon.");
@@ -2896,1370 +2427,70 @@ loop: for (;;) {
2896
2427
  }
2897
2428
  }
2898
2429
 
2430
+ // Build the syntax table by declaring the syntactic elements of the language.
2899
2431
 
2900
- // CSS parsing.
2901
-
2902
- function cssName() {
2903
- if (nexttoken.identifier) {
2904
- advance();
2905
- return true;
2906
- }
2907
- }
2908
-
2909
-
2910
- function cssNumber() {
2911
- if (nexttoken.id === '-') {
2912
- advance('-');
2913
- adjacent();
2914
- nolinebreak();
2915
- }
2916
- if (nexttoken.type === '(number)') {
2917
- advance('(number)');
2918
- return true;
2919
- }
2920
- }
2432
+ type('(number)', function () {
2433
+ return this;
2434
+ });
2921
2435
 
2436
+ type('(string)', function () {
2437
+ return this;
2438
+ });
2922
2439
 
2923
- function cssString() {
2924
- if (nexttoken.type === '(string)') {
2925
- advance();
2926
- return true;
2927
- }
2928
- }
2440
+ syntax['(identifier)'] = {
2441
+ type: '(identifier)',
2442
+ lbp: 0,
2443
+ identifier: true,
2444
+ nud: function () {
2445
+ var v = this.value,
2446
+ s = scope[v],
2447
+ f;
2929
2448
 
2449
+ if (typeof s === 'function') {
2450
+ // Protection against accidental inheritance.
2451
+ s = undefined;
2452
+ } else if (typeof s === 'boolean') {
2453
+ f = funct;
2454
+ funct = functions[0];
2455
+ addlabel(v, 'var');
2456
+ s = funct;
2457
+ funct = f;
2458
+ }
2930
2459
 
2931
- function cssColor() {
2932
- var i, number, value;
2933
- if (nexttoken.identifier) {
2934
- value = nexttoken.value;
2935
- if (value === 'rgb' || value === 'rgba') {
2936
- advance();
2937
- advance('(');
2938
- for (i = 0; i < 3; i += 1) {
2939
- if (i) {
2940
- advance(',');
2941
- }
2942
- number = nexttoken.value;
2943
- if (nexttoken.type !== '(number)' || number < 0) {
2944
- warning("Expected a positive number and instead saw '{a}'",
2945
- nexttoken, number);
2946
- advance();
2947
- } else {
2948
- advance();
2949
- if (nexttoken.id === '%') {
2950
- advance('%');
2951
- if (number > 100) {
2952
- warning("Expected a percentage and instead saw '{a}'",
2953
- token, number);
2954
- }
2955
- } else {
2956
- if (number > 255) {
2957
- warning("Expected a small number and instead saw '{a}'",
2958
- token, number);
2959
- }
2960
- }
2961
- }
2460
+ // The name is in scope and defined in the current function.
2461
+ if (funct === s) {
2462
+ // Change 'unused' to 'var', and reject labels.
2463
+ switch (funct[v]) {
2464
+ case 'unused':
2465
+ funct[v] = 'var';
2466
+ break;
2467
+ case 'unction':
2468
+ funct[v] = 'function';
2469
+ this['function'] = true;
2470
+ break;
2471
+ case 'function':
2472
+ this['function'] = true;
2473
+ break;
2474
+ case 'label':
2475
+ warning("'{a}' is a statement label.", token, v);
2476
+ break;
2962
2477
  }
2963
- if (value === 'rgba') {
2964
- advance(',');
2965
- number = +nexttoken.value;
2966
- if (nexttoken.type !== '(number)' || number < 0 || number > 1) {
2967
- warning("Expected a number between 0 and 1 and instead saw '{a}'",
2968
- nexttoken, number);
2969
- }
2970
- advance();
2971
- if (nexttoken.id === '%') {
2972
- warning("Unexpected '%'.");
2973
- advance('%');
2974
- }
2478
+ } else if (funct['(global)']) {
2479
+ // The name is not defined in the function. If we are in the global
2480
+ // scope, then we have an undefined variable.
2481
+ //
2482
+ // Operators typeof and delete do not raise runtime errors even if
2483
+ // the base object of a reference is null so no need to display warning
2484
+ // if we're inside of typeof or delete.
2485
+ if (anonname != 'typeof' && anonname != 'delete' &&
2486
+ option.undef && typeof predefined[v] !== 'boolean') {
2487
+ warning("'{a}' is not defined.", token, v);
2975
2488
  }
2976
- advance(')');
2977
- return true;
2978
- } else if (cssColorData[nexttoken.value] === true) {
2979
- advance();
2980
- return true;
2981
- }
2982
- } else if (nexttoken.type === '(color)') {
2983
- advance();
2984
- return true;
2985
- }
2986
- return false;
2987
- }
2988
-
2489
+ note_implied(token);
2490
+ } else {
2491
+ // If the name is already defined in the current
2492
+ // function, but not as outer, then there is a scope error.
2989
2493
 
2990
- function cssLength() {
2991
- if (nexttoken.id === '-') {
2992
- advance('-');
2993
- adjacent();
2994
- nolinebreak();
2995
- }
2996
- if (nexttoken.type === '(number)') {
2997
- advance();
2998
- if (nexttoken.type !== '(string)' &&
2999
- cssLengthData[nexttoken.value] === true) {
3000
- adjacent();
3001
- advance();
3002
- } else if (+token.value !== 0) {
3003
- warning("Expected a linear unit and instead saw '{a}'.",
3004
- nexttoken, nexttoken.value);
3005
- }
3006
- return true;
3007
- }
3008
- return false;
3009
- }
3010
-
3011
-
3012
- function cssLineHeight() {
3013
- if (nexttoken.id === '-') {
3014
- advance('-');
3015
- adjacent();
3016
- }
3017
- if (nexttoken.type === '(number)') {
3018
- advance();
3019
- if (nexttoken.type !== '(string)' &&
3020
- cssLengthData[nexttoken.value] === true) {
3021
- adjacent();
3022
- advance();
3023
- }
3024
- return true;
3025
- }
3026
- return false;
3027
- }
3028
-
3029
-
3030
- function cssWidth() {
3031
- if (nexttoken.identifier) {
3032
- switch (nexttoken.value) {
3033
- case 'thin':
3034
- case 'medium':
3035
- case 'thick':
3036
- advance();
3037
- return true;
3038
- }
3039
- } else {
3040
- return cssLength();
3041
- }
3042
- }
3043
-
3044
-
3045
- function cssMargin() {
3046
- if (nexttoken.identifier) {
3047
- if (nexttoken.value === 'auto') {
3048
- advance();
3049
- return true;
3050
- }
3051
- } else {
3052
- return cssLength();
3053
- }
3054
- }
3055
-
3056
- function cssAttr() {
3057
- if (nexttoken.identifier && nexttoken.value === 'attr') {
3058
- advance();
3059
- advance('(');
3060
- if (!nexttoken.identifier) {
3061
- warning("Expected a name and instead saw '{a}'.",
3062
- nexttoken, nexttoken.value);
3063
- }
3064
- advance();
3065
- advance(')');
3066
- return true;
3067
- }
3068
- return false;
3069
- }
3070
-
3071
-
3072
- function cssCommaList() {
3073
- while (nexttoken.id !== ';') {
3074
- if (!cssName() && !cssString()) {
3075
- warning("Expected a name and instead saw '{a}'.",
3076
- nexttoken, nexttoken.value);
3077
- }
3078
- if (nexttoken.id !== ',') {
3079
- return true;
3080
- }
3081
- comma();
3082
- }
3083
- }
3084
-
3085
-
3086
- function cssCounter() {
3087
- if (nexttoken.identifier && nexttoken.value === 'counter') {
3088
- advance();
3089
- advance('(');
3090
- advance();
3091
- if (nexttoken.id === ',') {
3092
- comma();
3093
- if (nexttoken.type !== '(string)') {
3094
- warning("Expected a string and instead saw '{a}'.",
3095
- nexttoken, nexttoken.value);
3096
- }
3097
- advance();
3098
- }
3099
- advance(')');
3100
- return true;
3101
- }
3102
- if (nexttoken.identifier && nexttoken.value === 'counters') {
3103
- advance();
3104
- advance('(');
3105
- if (!nexttoken.identifier) {
3106
- warning("Expected a name and instead saw '{a}'.",
3107
- nexttoken, nexttoken.value);
3108
- }
3109
- advance();
3110
- if (nexttoken.id === ',') {
3111
- comma();
3112
- if (nexttoken.type !== '(string)') {
3113
- warning("Expected a string and instead saw '{a}'.",
3114
- nexttoken, nexttoken.value);
3115
- }
3116
- advance();
3117
- }
3118
- if (nexttoken.id === ',') {
3119
- comma();
3120
- if (nexttoken.type !== '(string)') {
3121
- warning("Expected a string and instead saw '{a}'.",
3122
- nexttoken, nexttoken.value);
3123
- }
3124
- advance();
3125
- }
3126
- advance(')');
3127
- return true;
3128
- }
3129
- return false;
3130
- }
3131
-
3132
-
3133
- function cssShape() {
3134
- var i;
3135
- if (nexttoken.identifier && nexttoken.value === 'rect') {
3136
- advance();
3137
- advance('(');
3138
- for (i = 0; i < 4; i += 1) {
3139
- if (!cssLength()) {
3140
- warning("Expected a number and instead saw '{a}'.",
3141
- nexttoken, nexttoken.value);
3142
- break;
3143
- }
3144
- }
3145
- advance(')');
3146
- return true;
3147
- }
3148
- return false;
3149
- }
3150
-
3151
-
3152
- function cssUrl() {
3153
- var c, url;
3154
- if (nexttoken.identifier && nexttoken.value === 'url') {
3155
- nexttoken = lex.range('(', ')');
3156
- url = nexttoken.value;
3157
- c = url.charAt(0);
3158
- if (c === '"' || c === '\'') {
3159
- if (url.slice(-1) !== c) {
3160
- warning("Bad url string.");
3161
- } else {
3162
- url = url.slice(1, -1);
3163
- if (url.indexOf(c) >= 0) {
3164
- warning("Bad url string.");
3165
- }
3166
- }
3167
- }
3168
- if (!url) {
3169
- warning("Missing url.");
3170
- }
3171
- advance();
3172
- if (option.safe && ux.test(url)) {
3173
- error("ADsafe URL violation.");
3174
- }
3175
- urls.push(url);
3176
- return true;
3177
- }
3178
- return false;
3179
- }
3180
-
3181
-
3182
- cssAny = [cssUrl, function () {
3183
- for (;;) {
3184
- if (nexttoken.identifier) {
3185
- switch (nexttoken.value.toLowerCase()) {
3186
- case 'url':
3187
- cssUrl();
3188
- break;
3189
- case 'expression':
3190
- warning("Unexpected expression '{a}'.",
3191
- nexttoken, nexttoken.value);
3192
- advance();
3193
- break;
3194
- default:
3195
- advance();
3196
- }
3197
- } else {
3198
- if (nexttoken.id === ';' || nexttoken.id === '!' ||
3199
- nexttoken.id === '(end)' || nexttoken.id === '}') {
3200
- return true;
3201
- }
3202
- advance();
3203
- }
3204
- }
3205
- }];
3206
-
3207
-
3208
- cssBorderStyle = [
3209
- 'none', 'dashed', 'dotted', 'double', 'groove',
3210
- 'hidden', 'inset', 'outset', 'ridge', 'solid'
3211
- ];
3212
-
3213
- cssBreak = [
3214
- 'auto', 'always', 'avoid', 'left', 'right'
3215
- ];
3216
-
3217
- cssMedia = {
3218
- 'all': true,
3219
- 'braille': true,
3220
- 'embossed': true,
3221
- 'handheld': true,
3222
- 'print': true,
3223
- 'projection': true,
3224
- 'screen': true,
3225
- 'speech': true,
3226
- 'tty': true,
3227
- 'tv': true
3228
- };
3229
-
3230
- cssOverflow = [
3231
- 'auto', 'hidden', 'scroll', 'visible'
3232
- ];
3233
-
3234
- cssAttributeData = {
3235
- background: [
3236
- true, 'background-attachment', 'background-color',
3237
- 'background-image', 'background-position', 'background-repeat'
3238
- ],
3239
- 'background-attachment': ['scroll', 'fixed'],
3240
- 'background-color': ['transparent', cssColor],
3241
- 'background-image': ['none', cssUrl],
3242
- 'background-position': [
3243
- 2, [cssLength, 'top', 'bottom', 'left', 'right', 'center']
3244
- ],
3245
- 'background-repeat': [
3246
- 'repeat', 'repeat-x', 'repeat-y', 'no-repeat'
3247
- ],
3248
- 'border': [true, 'border-color', 'border-style', 'border-width'],
3249
- 'border-bottom': [
3250
- true, 'border-bottom-color', 'border-bottom-style',
3251
- 'border-bottom-width'
3252
- ],
3253
- 'border-bottom-color': cssColor,
3254
- 'border-bottom-style': cssBorderStyle,
3255
- 'border-bottom-width': cssWidth,
3256
- 'border-collapse': ['collapse', 'separate'],
3257
- 'border-color': ['transparent', 4, cssColor],
3258
- 'border-left': [
3259
- true, 'border-left-color', 'border-left-style', 'border-left-width'
3260
- ],
3261
- 'border-left-color': cssColor,
3262
- 'border-left-style': cssBorderStyle,
3263
- 'border-left-width': cssWidth,
3264
- 'border-right': [
3265
- true, 'border-right-color', 'border-right-style',
3266
- 'border-right-width'
3267
- ],
3268
- 'border-right-color': cssColor,
3269
- 'border-right-style': cssBorderStyle,
3270
- 'border-right-width': cssWidth,
3271
- 'border-spacing': [2, cssLength],
3272
- 'border-style': [4, cssBorderStyle],
3273
- 'border-top': [
3274
- true, 'border-top-color', 'border-top-style', 'border-top-width'
3275
- ],
3276
- 'border-top-color': cssColor,
3277
- 'border-top-style': cssBorderStyle,
3278
- 'border-top-width': cssWidth,
3279
- 'border-width': [4, cssWidth],
3280
- bottom: [cssLength, 'auto'],
3281
- 'caption-side' : ['bottom', 'left', 'right', 'top'],
3282
- clear: ['both', 'left', 'none', 'right'],
3283
- clip: [cssShape, 'auto'],
3284
- color: cssColor,
3285
- content: [
3286
- 'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote',
3287
- cssString, cssUrl, cssCounter, cssAttr
3288
- ],
3289
- 'counter-increment': [
3290
- cssName, 'none'
3291
- ],
3292
- 'counter-reset': [
3293
- cssName, 'none'
3294
- ],
3295
- cursor: [
3296
- cssUrl, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move',
3297
- 'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize',
3298
- 'se-resize', 'sw-resize', 'w-resize', 'text', 'wait'
3299
- ],
3300
- direction: ['ltr', 'rtl'],
3301
- display: [
3302
- 'block', 'compact', 'inline', 'inline-block', 'inline-table',
3303
- 'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption',
3304
- 'table-cell', 'table-column', 'table-column-group',
3305
- 'table-footer-group', 'table-header-group', 'table-row',
3306
- 'table-row-group'
3307
- ],
3308
- 'empty-cells': ['show', 'hide'],
3309
- 'float': ['left', 'none', 'right'],
3310
- font: [
3311
- 'caption', 'icon', 'menu', 'message-box', 'small-caption',
3312
- 'status-bar', true, 'font-size', 'font-style', 'font-weight',
3313
- 'font-family'
3314
- ],
3315
- 'font-family': cssCommaList,
3316
- 'font-size': [
3317
- 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large',
3318
- 'xx-large', 'larger', 'smaller', cssLength
3319
- ],
3320
- 'font-size-adjust': ['none', cssNumber],
3321
- 'font-stretch': [
3322
- 'normal', 'wider', 'narrower', 'ultra-condensed',
3323
- 'extra-condensed', 'condensed', 'semi-condensed',
3324
- 'semi-expanded', 'expanded', 'extra-expanded'
3325
- ],
3326
- 'font-style': [
3327
- 'normal', 'italic', 'oblique'
3328
- ],
3329
- 'font-variant': [
3330
- 'normal', 'small-caps'
3331
- ],
3332
- 'font-weight': [
3333
- 'normal', 'bold', 'bolder', 'lighter', cssNumber
3334
- ],
3335
- height: [cssLength, 'auto'],
3336
- left: [cssLength, 'auto'],
3337
- 'letter-spacing': ['normal', cssLength],
3338
- 'line-height': ['normal', cssLineHeight],
3339
- 'list-style': [
3340
- true, 'list-style-image', 'list-style-position', 'list-style-type'
3341
- ],
3342
- 'list-style-image': ['none', cssUrl],
3343
- 'list-style-position': ['inside', 'outside'],
3344
- 'list-style-type': [
3345
- 'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero',
3346
- 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha',
3347
- 'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana',
3348
- 'hiragana-iroha', 'katakana-oroha', 'none'
3349
- ],
3350
- margin: [4, cssMargin],
3351
- 'margin-bottom': cssMargin,
3352
- 'margin-left': cssMargin,
3353
- 'margin-right': cssMargin,
3354
- 'margin-top': cssMargin,
3355
- 'marker-offset': [cssLength, 'auto'],
3356
- 'max-height': [cssLength, 'none'],
3357
- 'max-width': [cssLength, 'none'],
3358
- 'min-height': cssLength,
3359
- 'min-width': cssLength,
3360
- opacity: cssNumber,
3361
- outline: [true, 'outline-color', 'outline-style', 'outline-width'],
3362
- 'outline-color': ['invert', cssColor],
3363
- 'outline-style': [
3364
- 'dashed', 'dotted', 'double', 'groove', 'inset', 'none',
3365
- 'outset', 'ridge', 'solid'
3366
- ],
3367
- 'outline-width': cssWidth,
3368
- overflow: cssOverflow,
3369
- 'overflow-x': cssOverflow,
3370
- 'overflow-y': cssOverflow,
3371
- padding: [4, cssLength],
3372
- 'padding-bottom': cssLength,
3373
- 'padding-left': cssLength,
3374
- 'padding-right': cssLength,
3375
- 'padding-top': cssLength,
3376
- 'page-break-after': cssBreak,
3377
- 'page-break-before': cssBreak,
3378
- position: ['absolute', 'fixed', 'relative', 'static'],
3379
- quotes: [8, cssString],
3380
- right: [cssLength, 'auto'],
3381
- 'table-layout': ['auto', 'fixed'],
3382
- 'text-align': ['center', 'justify', 'left', 'right'],
3383
- 'text-decoration': [
3384
- 'none', 'underline', 'overline', 'line-through', 'blink'
3385
- ],
3386
- 'text-indent': cssLength,
3387
- 'text-shadow': ['none', 4, [cssColor, cssLength]],
3388
- 'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'],
3389
- top: [cssLength, 'auto'],
3390
- 'unicode-bidi': ['normal', 'embed', 'bidi-override'],
3391
- 'vertical-align': [
3392
- 'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle',
3393
- 'text-bottom', cssLength
3394
- ],
3395
- visibility: ['visible', 'hidden', 'collapse'],
3396
- 'white-space': [
3397
- 'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit'
3398
- ],
3399
- width: [cssLength, 'auto'],
3400
- 'word-spacing': ['normal', cssLength],
3401
- 'word-wrap': ['break-word', 'normal'],
3402
- 'z-index': ['auto', cssNumber]
3403
- };
3404
-
3405
- function styleAttribute() {
3406
- var v;
3407
- while (nexttoken.id === '*' || nexttoken.id === '#' ||
3408
- nexttoken.value === '_') {
3409
- if (!option.css) {
3410
- warning("Unexpected '{a}'.", nexttoken, nexttoken.value);
3411
- }
3412
- advance();
3413
- }
3414
- if (nexttoken.id === '-') {
3415
- if (!option.css) {
3416
- warning("Unexpected '{a}'.", nexttoken, nexttoken.value);
3417
- }
3418
- advance('-');
3419
- if (!nexttoken.identifier) {
3420
- warning(
3421
- "Expected a non-standard style attribute and instead saw '{a}'.",
3422
- nexttoken, nexttoken.value);
3423
- }
3424
- advance();
3425
- return cssAny;
3426
- } else {
3427
- if (!nexttoken.identifier) {
3428
- warning("Excepted a style attribute, and instead saw '{a}'.",
3429
- nexttoken, nexttoken.value);
3430
- } else {
3431
- if (is_own(cssAttributeData, nexttoken.value)) {
3432
- v = cssAttributeData[nexttoken.value];
3433
- } else {
3434
- v = cssAny;
3435
- if (!option.css) {
3436
- warning("Unrecognized style attribute '{a}'.",
3437
- nexttoken, nexttoken.value);
3438
- }
3439
- }
3440
- }
3441
- advance();
3442
- return v;
3443
- }
3444
- }
3445
-
3446
-
3447
- function styleValue(v) {
3448
- var i = 0,
3449
- n,
3450
- once,
3451
- match,
3452
- round,
3453
- start = 0,
3454
- vi;
3455
- switch (typeof v) {
3456
- case 'function':
3457
- return v();
3458
- case 'string':
3459
- if (nexttoken.identifier && nexttoken.value === v) {
3460
- advance();
3461
- return true;
3462
- }
3463
- return false;
3464
- }
3465
- for (;;) {
3466
- if (i >= v.length) {
3467
- return false;
3468
- }
3469
- vi = v[i];
3470
- i += 1;
3471
- if (vi === true) {
3472
- break;
3473
- } else if (typeof vi === 'number') {
3474
- n = vi;
3475
- vi = v[i];
3476
- i += 1;
3477
- } else {
3478
- n = 1;
3479
- }
3480
- match = false;
3481
- while (n > 0) {
3482
- if (styleValue(vi)) {
3483
- match = true;
3484
- n -= 1;
3485
- } else {
3486
- break;
3487
- }
3488
- }
3489
- if (match) {
3490
- return true;
3491
- }
3492
- }
3493
- start = i;
3494
- once = [];
3495
- for (;;) {
3496
- round = false;
3497
- for (i = start; i < v.length; i += 1) {
3498
- if (!once[i]) {
3499
- if (styleValue(cssAttributeData[v[i]])) {
3500
- match = true;
3501
- round = true;
3502
- once[i] = true;
3503
- break;
3504
- }
3505
- }
3506
- }
3507
- if (!round) {
3508
- return match;
3509
- }
3510
- }
3511
- }
3512
-
3513
- function styleChild() {
3514
- if (nexttoken.id === '(number)') {
3515
- advance();
3516
- if (nexttoken.value === 'n' && nexttoken.identifier) {
3517
- adjacent();
3518
- advance();
3519
- if (nexttoken.id === '+') {
3520
- adjacent();
3521
- advance('+');
3522
- adjacent();
3523
- advance('(number)');
3524
- }
3525
- }
3526
- return;
3527
- } else {
3528
- switch (nexttoken.value) {
3529
- case 'odd':
3530
- case 'even':
3531
- if (nexttoken.identifier) {
3532
- advance();
3533
- return;
3534
- }
3535
- }
3536
- }
3537
- warning("Unexpected token '{a}'.", nexttoken, nexttoken.value);
3538
- }
3539
-
3540
- function substyle() {
3541
- var v;
3542
- for (;;) {
3543
- if (nexttoken.id === '}' || nexttoken.id === '(end)' ||
3544
- xquote && nexttoken.id === xquote) {
3545
- return;
3546
- }
3547
- while (nexttoken.id === ';') {
3548
- warning("Misplaced ';'.");
3549
- advance(';');
3550
- }
3551
- v = styleAttribute();
3552
- advance(':');
3553
- if (nexttoken.identifier && nexttoken.value === 'inherit') {
3554
- advance();
3555
- } else {
3556
- if (!styleValue(v)) {
3557
- warning("Unexpected token '{a}'.", nexttoken,
3558
- nexttoken.value);
3559
- advance();
3560
- }
3561
- }
3562
- if (nexttoken.id === '!') {
3563
- advance('!');
3564
- adjacent();
3565
- if (nexttoken.identifier && nexttoken.value === 'important') {
3566
- advance();
3567
- } else {
3568
- warning("Expected '{a}' and instead saw '{b}'.",
3569
- nexttoken, 'important', nexttoken.value);
3570
- }
3571
- }
3572
- if (nexttoken.id === '}' || nexttoken.id === xquote) {
3573
- warning("Missing '{a}'.", nexttoken, ';');
3574
- } else {
3575
- advance(';');
3576
- }
3577
- }
3578
- }
3579
-
3580
- function styleSelector() {
3581
- if (nexttoken.identifier) {
3582
- if (!is_own(htmltag, option.cap ?
3583
- nexttoken.value.toLowerCase() : nexttoken.value)) {
3584
- warning("Expected a tagName, and instead saw {a}.",
3585
- nexttoken, nexttoken.value);
3586
- }
3587
- advance();
3588
- } else {
3589
- switch (nexttoken.id) {
3590
- case '>':
3591
- case '+':
3592
- advance();
3593
- styleSelector();
3594
- break;
3595
- case ':':
3596
- advance(':');
3597
- switch (nexttoken.value) {
3598
- case 'active':
3599
- case 'after':
3600
- case 'before':
3601
- case 'checked':
3602
- case 'disabled':
3603
- case 'empty':
3604
- case 'enabled':
3605
- case 'first-child':
3606
- case 'first-letter':
3607
- case 'first-line':
3608
- case 'first-of-type':
3609
- case 'focus':
3610
- case 'hover':
3611
- case 'last-child':
3612
- case 'last-of-type':
3613
- case 'link':
3614
- case 'only-of-type':
3615
- case 'root':
3616
- case 'target':
3617
- case 'visited':
3618
- advance();
3619
- break;
3620
- case 'lang':
3621
- advance();
3622
- advance('(');
3623
- if (!nexttoken.identifier) {
3624
- warning("Expected a lang code, and instead saw :{a}.",
3625
- nexttoken, nexttoken.value);
3626
- }
3627
- advance(')');
3628
- break;
3629
- case 'nth-child':
3630
- case 'nth-last-child':
3631
- case 'nth-last-of-type':
3632
- case 'nth-of-type':
3633
- advance();
3634
- advance('(');
3635
- styleChild();
3636
- advance(')');
3637
- break;
3638
- case 'not':
3639
- advance();
3640
- advance('(');
3641
- if (nexttoken.id === ':' && peek(0).value === 'not') {
3642
- warning("Nested not.");
3643
- }
3644
- styleSelector();
3645
- advance(')');
3646
- break;
3647
- default:
3648
- warning("Expected a pseudo, and instead saw :{a}.",
3649
- nexttoken, nexttoken.value);
3650
- }
3651
- break;
3652
- case '#':
3653
- advance('#');
3654
- if (!nexttoken.identifier) {
3655
- warning("Expected an id, and instead saw #{a}.",
3656
- nexttoken, nexttoken.value);
3657
- }
3658
- advance();
3659
- break;
3660
- case '*':
3661
- advance('*');
3662
- break;
3663
- case '.':
3664
- advance('.');
3665
- if (!nexttoken.identifier) {
3666
- warning("Expected a class, and instead saw #.{a}.",
3667
- nexttoken, nexttoken.value);
3668
- }
3669
- advance();
3670
- break;
3671
- case '[':
3672
- advance('[');
3673
- if (!nexttoken.identifier) {
3674
- warning("Expected an attribute, and instead saw [{a}].",
3675
- nexttoken, nexttoken.value);
3676
- }
3677
- advance();
3678
- if (nexttoken.id === '=' || nexttoken.value === '~=' ||
3679
- nexttoken.value === '$=' ||
3680
- nexttoken.value === '|=' ||
3681
- nexttoken.id === '*=' ||
3682
- nexttoken.id === '^=') {
3683
- advance();
3684
- if (nexttoken.type !== '(string)') {
3685
- warning("Expected a string, and instead saw {a}.",
3686
- nexttoken, nexttoken.value);
3687
- }
3688
- advance();
3689
- }
3690
- advance(']');
3691
- break;
3692
- default:
3693
- error("Expected a CSS selector, and instead saw {a}.",
3694
- nexttoken, nexttoken.value);
3695
- }
3696
- }
3697
- }
3698
-
3699
- function stylePattern() {
3700
- if (nexttoken.id === '{') {
3701
- warning("Expected a style pattern, and instead saw '{a}'.", nexttoken,
3702
- nexttoken.id);
3703
- }
3704
- for (;;) {
3705
- styleSelector();
3706
- if (nexttoken.id === '</' || nexttoken.id === '{' ||
3707
- nexttoken.id === '(end)') {
3708
- return '';
3709
- }
3710
- if (nexttoken.id === ',') {
3711
- comma();
3712
- }
3713
- }
3714
- }
3715
-
3716
- function stylelist() {
3717
- while (nexttoken.id !== '</' && nexttoken.id !== '(end)') {
3718
- stylePattern();
3719
- xmode = 'styleproperty';
3720
- if (nexttoken.id === ';') {
3721
- advance(';');
3722
- } else {
3723
- advance('{');
3724
- substyle();
3725
- xmode = 'style';
3726
- advance('}');
3727
- }
3728
- }
3729
- }
3730
-
3731
- function styles() {
3732
- var i;
3733
- while (nexttoken.id === '@') {
3734
- i = peek();
3735
- advance('@');
3736
- if (nexttoken.identifier) {
3737
- switch (nexttoken.value) {
3738
- case 'import':
3739
- advance();
3740
- if (!cssUrl()) {
3741
- warning("Expected '{a}' and instead saw '{b}'.",
3742
- nexttoken, 'url', nexttoken.value);
3743
- advance();
3744
- }
3745
- advance(';');
3746
- break;
3747
- case 'media':
3748
- advance();
3749
- for (;;) {
3750
- if (!nexttoken.identifier || cssMedia[nexttoken.value] === true) {
3751
- error("Expected a CSS media type, and instead saw '{a}'.", nexttoken, nexttoken.id);
3752
- }
3753
- advance();
3754
- if (nexttoken.id !== ',') {
3755
- break;
3756
- }
3757
- advance(',');
3758
- }
3759
- advance('{');
3760
- stylelist();
3761
- advance('}');
3762
- break;
3763
- default:
3764
- warning("Expected an at-rule, and instead saw @{a}.",
3765
- nexttoken, nexttoken.value);
3766
- }
3767
- } else {
3768
- warning("Expected an at-rule, and instead saw '{a}'.",
3769
- nexttoken, nexttoken.value);
3770
- }
3771
- }
3772
- stylelist();
3773
- }
3774
-
3775
-
3776
- // HTML parsing.
3777
-
3778
- function doBegin(n) {
3779
- if (n !== 'html' && !option.fragment) {
3780
- if (n === 'div' && option.adsafe) {
3781
- error("ADSAFE: Use the fragment option.");
3782
- } else {
3783
- error("Expected '{a}' and instead saw '{b}'.",
3784
- token, 'html', n);
3785
- }
3786
- }
3787
- if (option.adsafe) {
3788
- if (n === 'html') {
3789
- error(
3790
- "Currently, ADsafe does not operate on whole HTML documents. It operates on <div> fragments and .js files.", token);
3791
- }
3792
- if (option.fragment) {
3793
- if (n !== 'div') {
3794
- error("ADsafe violation: Wrap the widget in a div.", token);
3795
- }
3796
- } else {
3797
- error("Use the fragment option.", token);
3798
- }
3799
- }
3800
- option.browser = true;
3801
- assume();
3802
- }
3803
-
3804
- function doAttribute(n, a, v) {
3805
- var u, x;
3806
- if (a === 'id') {
3807
- u = typeof v === 'string' ? v.toUpperCase() : '';
3808
- if (ids[u] === true) {
3809
- warning("Duplicate id='{a}'.", nexttoken, v);
3810
- }
3811
- if (!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)) {
3812
- warning("Bad id: '{a}'.", nexttoken, v);
3813
- } else if (option.adsafe) {
3814
- if (adsafe_id) {
3815
- if (v.slice(0, adsafe_id.length) !== adsafe_id) {
3816
- warning("ADsafe violation: An id must have a '{a}' prefix",
3817
- nexttoken, adsafe_id);
3818
- } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {
3819
- warning("ADSAFE violation: bad id.");
3820
- }
3821
- } else {
3822
- adsafe_id = v;
3823
- if (!/^[A-Z]+_$/.test(v)) {
3824
- warning("ADSAFE violation: bad id.");
3825
- }
3826
- }
3827
- }
3828
- x = v.search(dx);
3829
- if (x >= 0) {
3830
- warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a);
3831
- }
3832
- ids[u] = true;
3833
- } else if (a === 'class' || a === 'type' || a === 'name') {
3834
- x = v.search(qx);
3835
- if (x >= 0) {
3836
- warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a);
3837
- }
3838
- ids[u] = true;
3839
- } else if (a === 'href' || a === 'background' ||
3840
- a === 'content' || a === 'data' ||
3841
- a.indexOf('src') >= 0 || a.indexOf('url') >= 0) {
3842
- if (option.safe && ux.test(v)) {
3843
- error("ADsafe URL violation.");
3844
- }
3845
- urls.push(v);
3846
- } else if (a === 'for') {
3847
- if (option.adsafe) {
3848
- if (adsafe_id) {
3849
- if (v.slice(0, adsafe_id.length) !== adsafe_id) {
3850
- warning("ADsafe violation: An id must have a '{a}' prefix",
3851
- nexttoken, adsafe_id);
3852
- } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {
3853
- warning("ADSAFE violation: bad id.");
3854
- }
3855
- } else {
3856
- warning("ADSAFE violation: bad id.");
3857
- }
3858
- }
3859
- } else if (a === 'name') {
3860
- if (option.adsafe && v.indexOf('_') >= 0) {
3861
- warning("ADsafe name violation.");
3862
- }
3863
- }
3864
- }
3865
-
3866
- function doTag(n, a) {
3867
- var i, t = htmltag[n], x;
3868
- src = false;
3869
- if (!t) {
3870
- error("Unrecognized tag '<{a}>'.",
3871
- nexttoken,
3872
- n === n.toLowerCase() ? n :
3873
- n + ' (capitalization error)');
3874
- }
3875
- if (stack.length > 0) {
3876
- if (n === 'html') {
3877
- error("Too many <html> tags.", token);
3878
- }
3879
- x = t.parent;
3880
- if (x) {
3881
- if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) {
3882
- error("A '<{a}>' must be within '<{b}>'.",
3883
- token, n, x);
3884
- }
3885
- } else if (!option.adsafe && !option.fragment) {
3886
- i = stack.length;
3887
- do {
3888
- if (i <= 0) {
3889
- error("A '<{a}>' must be within '<{b}>'.",
3890
- token, n, 'body');
3891
- }
3892
- i -= 1;
3893
- } while (stack[i].name !== 'body');
3894
- }
3895
- }
3896
- switch (n) {
3897
- case 'div':
3898
- if (option.adsafe && stack.length === 1 && !adsafe_id) {
3899
- warning("ADSAFE violation: missing ID_.");
3900
- }
3901
- break;
3902
- case 'script':
3903
- xmode = 'script';
3904
- advance('>');
3905
- indent = nexttoken.from;
3906
- if (a.lang) {
3907
- warning("lang is deprecated.", token);
3908
- }
3909
- if (option.adsafe && stack.length !== 1) {
3910
- warning("ADsafe script placement violation.", token);
3911
- }
3912
- if (a.src) {
3913
- if (option.adsafe && (!adsafe_may || !approved[a.src])) {
3914
- warning("ADsafe unapproved script source.", token);
3915
- }
3916
- if (a.type) {
3917
- warning("type is unnecessary.", token);
3918
- }
3919
- } else {
3920
- if (adsafe_went) {
3921
- error("ADsafe script violation.", token);
3922
- }
3923
- use_strict();
3924
- statements('script');
3925
- }
3926
- xmode = 'html';
3927
- advance('</');
3928
- if (!nexttoken.identifier && nexttoken.value !== 'script') {
3929
- warning("Expected '{a}' and instead saw '{b}'.",
3930
- nexttoken, 'script', nexttoken.value);
3931
- }
3932
- advance();
3933
- xmode = 'outer';
3934
- break;
3935
- case 'style':
3936
- xmode = 'style';
3937
- advance('>');
3938
- styles();
3939
- xmode = 'html';
3940
- advance('</');
3941
- if (!nexttoken.identifier && nexttoken.value !== 'style') {
3942
- warning("Expected '{a}' and instead saw '{b}'.",
3943
- nexttoken, 'style', nexttoken.value);
3944
- }
3945
- advance();
3946
- xmode = 'outer';
3947
- break;
3948
- case 'input':
3949
- switch (a.type) {
3950
- case 'radio':
3951
- case 'checkbox':
3952
- case 'button':
3953
- case 'reset':
3954
- case 'submit':
3955
- break;
3956
- case 'text':
3957
- case 'file':
3958
- case 'password':
3959
- case 'file':
3960
- case 'hidden':
3961
- case 'image':
3962
- if (option.adsafe && a.autocomplete !== 'off') {
3963
- warning("ADsafe autocomplete violation.");
3964
- }
3965
- break;
3966
- default:
3967
- warning("Bad input type.");
3968
- }
3969
- break;
3970
- case 'applet':
3971
- case 'body':
3972
- case 'embed':
3973
- case 'frame':
3974
- case 'frameset':
3975
- case 'head':
3976
- case 'iframe':
3977
- case 'noembed':
3978
- case 'noframes':
3979
- case 'object':
3980
- case 'param':
3981
- if (option.adsafe) {
3982
- warning("ADsafe violation: Disallowed tag: " + n);
3983
- }
3984
- break;
3985
- }
3986
- }
3987
-
3988
-
3989
- function closetag(n) {
3990
- return '</' + n + '>';
3991
- }
3992
-
3993
- function html() {
3994
- var a, attributes, e, n, q, t, v, w = option.white, wmode;
3995
- xmode = 'html';
3996
- xquote = '';
3997
- stack = null;
3998
- for (;;) {
3999
- switch (nexttoken.value) {
4000
- case '<':
4001
- xmode = 'html';
4002
- advance('<');
4003
- attributes = {};
4004
- t = nexttoken;
4005
- if (!t.identifier) {
4006
- warning("Bad identifier {a}.", t, t.value);
4007
- }
4008
- n = t.value;
4009
- if (option.cap) {
4010
- n = n.toLowerCase();
4011
- }
4012
- t.name = n;
4013
- advance();
4014
- if (!stack) {
4015
- stack = [];
4016
- doBegin(n);
4017
- }
4018
- v = htmltag[n];
4019
- if (typeof v !== 'object') {
4020
- error("Unrecognized tag '<{a}>'.", t, n);
4021
- }
4022
- e = v.empty;
4023
- t.type = n;
4024
- for (;;) {
4025
- if (nexttoken.id === '/') {
4026
- advance('/');
4027
- if (nexttoken.id !== '>') {
4028
- warning("Expected '{a}' and instead saw '{b}'.",
4029
- nexttoken, '>', nexttoken.value);
4030
- }
4031
- break;
4032
- }
4033
- if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') {
4034
- break;
4035
- }
4036
- if (!nexttoken.identifier) {
4037
- if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
4038
- error("Missing '>'.", nexttoken);
4039
- }
4040
- warning("Bad identifier.");
4041
- }
4042
- option.white = true;
4043
- nonadjacent(token, nexttoken);
4044
- a = nexttoken.value;
4045
- option.white = w;
4046
- advance();
4047
- if (!option.cap && a !== a.toLowerCase()) {
4048
- warning("Attribute '{a}' not all lower case.", nexttoken, a);
4049
- }
4050
- a = a.toLowerCase();
4051
- xquote = '';
4052
- if (is_own(attributes, a)) {
4053
- warning("Attribute '{a}' repeated.", nexttoken, a);
4054
- }
4055
- if (a.slice(0, 2) === 'on') {
4056
- if (!option.on) {
4057
- warning("Avoid HTML event handlers.");
4058
- }
4059
- xmode = 'scriptstring';
4060
- advance('=');
4061
- q = nexttoken.id;
4062
- if (q !== '"' && q !== "'") {
4063
- error("Missing quote.");
4064
- }
4065
- xquote = q;
4066
- wmode = option.white;
4067
- option.white = false;
4068
- advance(q);
4069
- use_strict();
4070
- statements('on');
4071
- option.white = wmode;
4072
- if (nexttoken.id !== q) {
4073
- error("Missing close quote on script attribute.");
4074
- }
4075
- xmode = 'html';
4076
- xquote = '';
4077
- advance(q);
4078
- v = false;
4079
- } else if (a === 'style') {
4080
- xmode = 'scriptstring';
4081
- advance('=');
4082
- q = nexttoken.id;
4083
- if (q !== '"' && q !== "'") {
4084
- error("Missing quote.");
4085
- }
4086
- xmode = 'styleproperty';
4087
- xquote = q;
4088
- advance(q);
4089
- substyle();
4090
- xmode = 'html';
4091
- xquote = '';
4092
- advance(q);
4093
- v = false;
4094
- } else {
4095
- if (nexttoken.id === '=') {
4096
- advance('=');
4097
- v = nexttoken.value;
4098
- if (!nexttoken.identifier &&
4099
- nexttoken.id !== '"' &&
4100
- nexttoken.id !== '\'' &&
4101
- nexttoken.type !== '(string)' &&
4102
- nexttoken.type !== '(number)' &&
4103
- nexttoken.type !== '(color)') {
4104
- warning("Expected an attribute value and instead saw '{a}'.", token, a);
4105
- }
4106
- advance();
4107
- } else {
4108
- v = true;
4109
- }
4110
- }
4111
- attributes[a] = v;
4112
- doAttribute(n, a, v);
4113
- }
4114
- doTag(n, attributes);
4115
- if (!e) {
4116
- stack.push(t);
4117
- }
4118
- xmode = 'outer';
4119
- advance('>');
4120
- break;
4121
- case '</':
4122
- xmode = 'html';
4123
- advance('</');
4124
- if (!nexttoken.identifier) {
4125
- warning("Bad identifier.");
4126
- }
4127
- n = nexttoken.value;
4128
- if (option.cap) {
4129
- n = n.toLowerCase();
4130
- }
4131
- advance();
4132
- if (!stack) {
4133
- error("Unexpected '{a}'.", nexttoken, closetag(n));
4134
- }
4135
- t = stack.pop();
4136
- if (!t) {
4137
- error("Unexpected '{a}'.", nexttoken, closetag(n));
4138
- }
4139
- if (t.name !== n) {
4140
- error("Expected '{a}' and instead saw '{b}'.",
4141
- nexttoken, closetag(t.name), closetag(n));
4142
- }
4143
- if (nexttoken.id !== '>') {
4144
- error("Missing '{a}'.", nexttoken, '>');
4145
- }
4146
- xmode = 'outer';
4147
- advance('>');
4148
- break;
4149
- case '<!':
4150
- if (option.safe) {
4151
- warning("ADsafe HTML violation.");
4152
- }
4153
- xmode = 'html';
4154
- for (;;) {
4155
- advance();
4156
- if (nexttoken.id === '>' || nexttoken.id === '(end)') {
4157
- break;
4158
- }
4159
- if (nexttoken.value.indexOf('--') >= 0) {
4160
- error("Unexpected --.");
4161
- }
4162
- if (nexttoken.value.indexOf('<') >= 0) {
4163
- error("Unexpected <.");
4164
- }
4165
- if (nexttoken.value.indexOf('>') >= 0) {
4166
- error("Unexpected >.");
4167
- }
4168
- }
4169
- xmode = 'outer';
4170
- advance('>');
4171
- break;
4172
- case '(end)':
4173
- return;
4174
- default:
4175
- if (nexttoken.id === '(end)') {
4176
- error("Missing '{a}'.", nexttoken,
4177
- '</' + stack[stack.length - 1].value + '>');
4178
- } else {
4179
- advance();
4180
- }
4181
- }
4182
- if (stack && stack.length === 0 && (option.adsafe ||
4183
- !option.fragment || nexttoken.id === '(end)')) {
4184
- break;
4185
- }
4186
- }
4187
- if (nexttoken.id !== '(end)') {
4188
- error("Unexpected material after the end.");
4189
- }
4190
- }
4191
-
4192
-
4193
- // Build the syntax table by declaring the syntactic elements of the language.
4194
-
4195
- type('(number)', function () {
4196
- return this;
4197
- });
4198
- type('(string)', function () {
4199
- return this;
4200
- });
4201
-
4202
- syntax['(identifier)'] = {
4203
- type: '(identifier)',
4204
- lbp: 0,
4205
- identifier: true,
4206
- nud: function () {
4207
- var v = this.value,
4208
- s = scope[v],
4209
- f;
4210
- if (typeof s === 'function') {
4211
-
4212
- // Protection against accidental inheritance.
4213
-
4214
- s = undefined;
4215
- } else if (typeof s === 'boolean') {
4216
- f = funct;
4217
- funct = functions[0];
4218
- addlabel(v, 'var');
4219
- s = funct;
4220
- funct = f;
4221
- }
4222
-
4223
- // The name is in scope and defined in the current function.
4224
-
4225
- if (funct === s) {
4226
-
4227
- // Change 'unused' to 'var', and reject labels.
4228
-
4229
- switch (funct[v]) {
4230
- case 'unused':
4231
- funct[v] = 'var';
4232
- break;
4233
- case 'unction':
4234
- funct[v] = 'function';
4235
- this['function'] = true;
4236
- break;
4237
- case 'function':
4238
- this['function'] = true;
4239
- break;
4240
- case 'label':
4241
- warning("'{a}' is a statement label.", token, v);
4242
- break;
4243
- }
4244
-
4245
- // The name is not defined in the function. If we are in the global scope,
4246
- // then we have an undefined variable.
4247
- //
4248
- // Operators typeof and delete do not raise runtime errors even if the base
4249
- // object of a reference is null so no need to display warning if we're
4250
- // inside of typeof or delete.
4251
-
4252
- } else if (funct['(global)']) {
4253
- if (anonname != 'typeof' && anonname != 'delete' &&
4254
- option.undef && typeof predefined[v] !== 'boolean') {
4255
- warning("'{a}' is not defined.", token, v);
4256
- }
4257
- note_implied(token);
4258
-
4259
- // If the name is already defined in the current
4260
- // function, but not as outer, then there is a scope error.
4261
-
4262
- } else {
4263
2494
  switch (funct[v]) {
4264
2495
  case 'closure':
4265
2496
  case 'function':
@@ -4274,20 +2505,17 @@ loop: for (;;) {
4274
2505
  case 'global':
4275
2506
  break;
4276
2507
  default:
4277
-
4278
- // If the name is defined in an outer function, make an outer entry, and if
4279
- // it was unused, make it var.
4280
-
2508
+ // If the name is defined in an outer function, make an outer entry,
2509
+ // and if it was unused, make it var.
4281
2510
  if (s === true) {
4282
2511
  funct[v] = true;
4283
2512
  } else if (s === null) {
4284
2513
  warning("'{a}' is not allowed.", token, v);
4285
2514
  note_implied(token);
4286
2515
  } else if (typeof s !== 'object') {
4287
-
4288
- // Operators typeof and delete do not raise runtime errors even if the base object of
4289
- // a reference is null so no need to display warning if we're inside of typeof or delete.
4290
-
2516
+ // Operators typeof and delete do not raise runtime errors even
2517
+ // if the base object of a reference is null so no need to
2518
+ // display warning if we're inside of typeof or delete.
4291
2519
  if (anonname != 'typeof' && anonname != 'delete' && option.undef) {
4292
2520
  warning("'{a}' is not defined.", token, v);
4293
2521
  } else {
@@ -4358,25 +2586,17 @@ loop: for (;;) {
4358
2586
  reservevar('arguments', function (x) {
4359
2587
  if (strict_mode && funct['(global)']) {
4360
2588
  warning("Strict violation.", x);
4361
- } else if (option.safe) {
4362
- warning("ADsafe violation.", x);
4363
- }
4364
- });
4365
- reservevar('eval', function (x) {
4366
- if (option.safe) {
4367
- warning("ADsafe violation.", x);
4368
2589
  }
4369
2590
  });
2591
+ reservevar('eval');
4370
2592
  reservevar('false');
4371
2593
  reservevar('Infinity');
4372
2594
  reservevar('NaN');
4373
2595
  reservevar('null');
4374
2596
  reservevar('this', function (x) {
4375
- if (strict_mode && ((funct['(statement)'] &&
2597
+ if (strict_mode && !option.validthis && ((funct['(statement)'] &&
4376
2598
  funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) {
4377
- warning("Strict violation.", x);
4378
- } else if (option.safe) {
4379
- warning("ADsafe violation.", x);
2599
+ warning("Possible strict violation.", x);
4380
2600
  }
4381
2601
  });
4382
2602
  reservevar('true');
@@ -4409,21 +2629,23 @@ loop: for (;;) {
4409
2629
  bitwise('^', 'bitxor', 80);
4410
2630
  bitwise('&', 'bitand', 90);
4411
2631
  relation('==', function (left, right) {
4412
- if (option.eqeqeq) {
4413
- warning("Expected '{a}' and instead saw '{b}'.",
4414
- this, '===', '==');
4415
- } else if (isPoorRelation(left)) {
4416
- warning("Use '{a}' to compare with '{b}'.",
4417
- this, '===', left.value);
4418
- } else if (isPoorRelation(right)) {
4419
- warning("Use '{a}' to compare with '{b}'.",
4420
- this, '===', right.value);
4421
- }
2632
+ var eqnull = option.eqnull && (left.value == 'null' || right.value == 'null');
2633
+
2634
+ if (!eqnull && option.eqeqeq)
2635
+ warning("Expected '{a}' and instead saw '{b}'.", this, '===', '==');
2636
+ else if (isPoorRelation(left))
2637
+ warning("Use '{a}' to compare with '{b}'.", this, '===', left.value);
2638
+ else if (isPoorRelation(right))
2639
+ warning("Use '{a}' to compare with '{b}'.", this, '===', right.value);
2640
+
4422
2641
  return this;
4423
2642
  });
4424
2643
  relation('===');
4425
2644
  relation('!=', function (left, right) {
4426
- if (option.eqeqeq) {
2645
+ var eqnull = option.eqnull &&
2646
+ (left.value == 'null' || right.value == 'null');
2647
+
2648
+ if (!eqnull && option.eqeqeq) {
4427
2649
  warning("Expected '{a}' and instead saw '{b}'.",
4428
2650
  this, '!==', '!=');
4429
2651
  } else if (isPoorRelation(left)) {
@@ -4450,7 +2672,7 @@ loop: for (;;) {
4450
2672
  if (left && right && left.id === '(string)' && right.id === '(string)') {
4451
2673
  left.value += right.value;
4452
2674
  left.character = right.character;
4453
- if (jx.test(left.value)) {
2675
+ if (!option.scripturl && jx.test(left.value)) {
4454
2676
  warning("JavaScript URL.", left);
4455
2677
  }
4456
2678
  return left;
@@ -4506,7 +2728,6 @@ loop: for (;;) {
4506
2728
  return this;
4507
2729
  }).exps = true;
4508
2730
 
4509
-
4510
2731
  prefix('~', function () {
4511
2732
  if (option.bitwise) {
4512
2733
  warning("Unexpected '{a}'.", this, '~');
@@ -4514,6 +2735,7 @@ loop: for (;;) {
4514
2735
  expression(150);
4515
2736
  return this;
4516
2737
  });
2738
+
4517
2739
  prefix('!', function () {
4518
2740
  this.right = expression(150);
4519
2741
  this.arity = 'unary';
@@ -4532,21 +2754,6 @@ loop: for (;;) {
4532
2754
  case 'Object':
4533
2755
  warning("Use the object literal notation {}.", token);
4534
2756
  break;
4535
- case 'Array':
4536
- if (nexttoken.id !== '(') {
4537
- warning("Use the array literal notation [].", token);
4538
- } else {
4539
- advance('(');
4540
- if (nexttoken.id === ')') {
4541
- warning("Use the array literal notation [].", token);
4542
- } else {
4543
- expression(0);
4544
- }
4545
-
4546
- advance(')');
4547
- }
4548
- this.first = c;
4549
- return this;
4550
2757
  case 'Number':
4551
2758
  case 'String':
4552
2759
  case 'Boolean':
@@ -4566,9 +2773,8 @@ loop: for (;;) {
4566
2773
  if (c.id !== 'function') {
4567
2774
  i = c.value.substr(0, 1);
4568
2775
  if (option.newcap && (i < 'A' || i > 'Z')) {
4569
- warning(
4570
- "A constructor name should start with an uppercase letter.",
4571
- token);
2776
+ warning("A constructor name should start with "+
2777
+ "an uppercase letter.", token);
4572
2778
  }
4573
2779
  }
4574
2780
  }
@@ -4578,10 +2784,11 @@ loop: for (;;) {
4578
2784
  }
4579
2785
  }
4580
2786
  } else {
4581
- warning("Weird construction. Delete 'new'.", this);
2787
+ if (!option.supernew)
2788
+ warning("Weird construction. Delete 'new'.", this);
4582
2789
  }
4583
2790
  adjacent(token, nexttoken);
4584
- if (nexttoken.id !== '(') {
2791
+ if (nexttoken.id !== '(' && !option.supernew) {
4585
2792
  warning("Missing '()' invoking a constructor.");
4586
2793
  }
4587
2794
  this.first = c;
@@ -4589,6 +2796,8 @@ loop: for (;;) {
4589
2796
  });
4590
2797
  syntax['new'].exps = true;
4591
2798
 
2799
+ prefix('void').exps = true;
2800
+
4592
2801
  infix('.', function (left, that) {
4593
2802
  adjacent(prevtoken, token);
4594
2803
  nobreak();
@@ -4598,60 +2807,17 @@ loop: for (;;) {
4598
2807
  }
4599
2808
  that.left = left;
4600
2809
  that.right = m;
4601
- if (option.noarg && left && left.value === 'arguments' &&
4602
- (m === 'callee' || m === 'caller')) {
4603
- warning("Avoid arguments.{a}.", left, m);
2810
+ if (left && left.value === 'arguments' && (m === 'callee' || m === 'caller')) {
2811
+ if (option.noarg)
2812
+ warning("Avoid arguments.{a}.", left, m);
2813
+ else if (strict_mode)
2814
+ error('Strict violation.');
4604
2815
  } else if (!option.evil && left && left.value === 'document' &&
4605
2816
  (m === 'write' || m === 'writeln')) {
4606
2817
  warning("document.write can be a form of eval.", left);
4607
- } else if (option.adsafe) {
4608
- if (left && left.value === 'ADSAFE') {
4609
- if (m === 'id' || m === 'lib') {
4610
- warning("ADsafe violation.", that);
4611
- } else if (m === 'go') {
4612
- if (xmode !== 'script') {
4613
- warning("ADsafe violation.", that);
4614
- } else if (adsafe_went || nexttoken.id !== '(' ||
4615
- peek(0).id !== '(string)' ||
4616
- peek(0).value !== adsafe_id ||
4617
- peek(1).id !== ',') {
4618
- error("ADsafe violation: go.", that);
4619
- }
4620
- adsafe_went = true;
4621
- adsafe_may = false;
4622
- }
4623
- }
4624
2818
  }
4625
2819
  if (!option.evil && (m === 'eval' || m === 'execScript')) {
4626
2820
  warning('eval is evil.');
4627
- } else if (option.safe) {
4628
- for (;;) {
4629
- if (banned[m] === true) {
4630
- warning("ADsafe restricted word '{a}'.", token, m);
4631
- }
4632
- if (typeof predefined[left.value] !== 'boolean' ||
4633
- nexttoken.id === '(') {
4634
- break;
4635
- }
4636
- if (standard_member[m] === true) {
4637
- if (nexttoken.id === '.') {
4638
- warning("ADsafe violation.", that);
4639
- }
4640
- break;
4641
- }
4642
- if (nexttoken.id !== '.') {
4643
- warning("ADsafe violation.", that);
4644
- break;
4645
- }
4646
- advance('.');
4647
- token.left = that;
4648
- token.right = m;
4649
- that = token;
4650
- m = identifier();
4651
- if (typeof m === 'string') {
4652
- countMember(m);
4653
- }
4654
- }
4655
2821
  }
4656
2822
  return that;
4657
2823
  }, 160, true);
@@ -4682,11 +2848,6 @@ loop: for (;;) {
4682
2848
  }
4683
2849
  }
4684
2850
  }
4685
- } else if (left.id === '.') {
4686
- if (option.safe && left.left.value === 'Math' &&
4687
- left.right === 'random') {
4688
- warning("ADsafe violation.", left);
4689
- }
4690
2851
  }
4691
2852
  }
4692
2853
  if (nexttoken.id !== ')') {
@@ -4752,14 +2913,8 @@ loop: for (;;) {
4752
2913
  nospace();
4753
2914
  var e = expression(0), s;
4754
2915
  if (e && e.type === '(string)') {
4755
- if (option.safe && banned[e.value] === true) {
4756
- warning("ADsafe restricted word '{a}'.", that, e.value);
4757
- } else if (!option.evil &&
4758
- (e.value === 'eval' || e.value === 'execScript')) {
2916
+ if (!option.evil && (e.value === 'eval' || e.value === 'execScript')) {
4759
2917
  warning("eval is evil.", that);
4760
- } else if (option.safe &&
4761
- (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) {
4762
- warning("ADsafe restricted subscript '{a}'.", that, e.value);
4763
2918
  }
4764
2919
  countMember(e.value);
4765
2920
  if (!option.sub && ix.test(e.value)) {
@@ -4769,10 +2924,6 @@ loop: for (;;) {
4769
2924
  e, e.value);
4770
2925
  }
4771
2926
  }
4772
- } else if (!e || e.type !== '(number)' || e.value < 0) {
4773
- if (option.safe) {
4774
- warning('ADsafe subscripting.');
4775
- }
4776
2927
  }
4777
2928
  advance(']', that);
4778
2929
  nospace(prevtoken, token);
@@ -4826,12 +2977,6 @@ loop: for (;;) {
4826
2977
  if (!id) {
4827
2978
  if (nexttoken.id === '(string)') {
4828
2979
  id = nexttoken.value;
4829
- if (option.adsafe &&
4830
- (id.charAt(0) === '_' ||
4831
- id.charAt(id.length - 1) === '_')) {
4832
- warning("Unexpected {a} in '{b}'.", token,
4833
- "dangling '_'", id);
4834
- }
4835
2980
  advance();
4836
2981
  } else if (nexttoken.id === '(number)') {
4837
2982
  id = nexttoken.value.toString();
@@ -4867,8 +3012,13 @@ loop: for (;;) {
4867
3012
 
4868
3013
 
4869
3014
  function doFunction(i, statement) {
4870
- var f, s = scope;
4871
- scope = Object.create(s);
3015
+ var f,
3016
+ oldOption = option,
3017
+ oldScope = scope;
3018
+
3019
+ option = Object.create(option);
3020
+ scope = Object.create(scope);
3021
+
4872
3022
  funct = {
4873
3023
  '(name)' : i || '"' + anonname + '"',
4874
3024
  '(line)' : nexttoken.line,
@@ -4887,7 +3037,8 @@ loop: for (;;) {
4887
3037
  funct['(params)'] = functionparams();
4888
3038
 
4889
3039
  block(false);
4890
- scope = s;
3040
+ scope = oldScope;
3041
+ option = oldOption;
4891
3042
  funct['(last)'] = token.line;
4892
3043
  funct = funct['(context)'];
4893
3044
  return f;
@@ -4897,6 +3048,7 @@ loop: for (;;) {
4897
3048
  (function (x) {
4898
3049
  x.nud = function () {
4899
3050
  var b, f, i, j, p, seen = {}, t;
3051
+
4900
3052
  b = token.line !== nexttoken.line;
4901
3053
  if (b) {
4902
3054
  indent += option.indent;
@@ -4922,7 +3074,7 @@ loop: for (;;) {
4922
3074
  }
4923
3075
  t = nexttoken;
4924
3076
  adjacent(token, nexttoken);
4925
- f = doFunction(i);
3077
+ f = doFunction();
4926
3078
  if (!option.loopfunc && funct['(loopage)']) {
4927
3079
  warning("Don't make functions within a loop.", t);
4928
3080
  }
@@ -4940,7 +3092,7 @@ loop: for (;;) {
4940
3092
  }
4941
3093
  t = nexttoken;
4942
3094
  adjacent(token, nexttoken);
4943
- f = doFunction(i);
3095
+ f = doFunction();
4944
3096
  p = f['(params)'];
4945
3097
  if (!p || p.length !== 1 || p[0] !== 'value') {
4946
3098
  warning("Expected (value) in set {a} function.", t, i);
@@ -4982,12 +3134,9 @@ loop: for (;;) {
4982
3134
  };
4983
3135
  }(delim('{')));
4984
3136
 
4985
-
4986
- var varstatement = function varstatement(prefix) {
4987
-
4988
- // JavaScript does not have block scope. It only has function scope. So,
4989
- // declaring a variable in a block can have unexpected consequences.
4990
-
3137
+ var varstatement = stmt('var', function (prefix) {
3138
+ // JavaScript does not have block scope. It only has function scope. So,
3139
+ // declaring a variable in a block can have unexpected consequences.
4991
3140
  var id, name, value;
4992
3141
 
4993
3142
  if (funct['(onevar)'] && option.onevar) {
@@ -5028,16 +3177,14 @@ loop: for (;;) {
5028
3177
  comma();
5029
3178
  }
5030
3179
  return this;
5031
- };
5032
-
5033
-
5034
- stmt('var', varstatement).exps = true;
5035
-
3180
+ });
3181
+ varstatement.exps = true;
5036
3182
 
5037
3183
  blockstmt('function', function () {
5038
3184
  if (inblock) {
5039
- warning(
5040
- "Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token);
3185
+ warning("Function declarations should not be placed in blocks. " +
3186
+ "Use a function expression or move the statement to the top of " +
3187
+ "the outer function.", token);
5041
3188
 
5042
3189
  }
5043
3190
  var i = identifier();
@@ -5094,9 +3241,7 @@ loop: for (;;) {
5094
3241
 
5095
3242
  blockstmt('try', function () {
5096
3243
  var b, e, s;
5097
- if (option.adsafe) {
5098
- warning("ADsafe try violation.", this);
5099
- }
3244
+
5100
3245
  block(false);
5101
3246
  if (nexttoken.id === 'catch') {
5102
3247
  advance('catch');
@@ -5221,7 +3366,8 @@ loop: for (;;) {
5221
3366
  advance('}', t);
5222
3367
  if (this.cases.length === 1 || this.condition.id === 'true' ||
5223
3368
  this.condition.id === 'false') {
5224
- warning("This 'switch' should be an 'if'.", this);
3369
+ if (!option.onecase)
3370
+ warning("This 'switch' should be an 'if'.", this);
5225
3371
  }
5226
3372
  funct['(breakage)'] -= 1;
5227
3373
  funct['(verb)'] = undefined;
@@ -5284,7 +3430,7 @@ loop: for (;;) {
5284
3430
  }());
5285
3431
 
5286
3432
  blockstmt('for', function () {
5287
- var f = option.forin, s, t = nexttoken;
3433
+ var s, t = nexttoken;
5288
3434
  funct['(breakage)'] += 1;
5289
3435
  funct['(loopage)'] += 1;
5290
3436
  advance('(');
@@ -5293,7 +3439,7 @@ loop: for (;;) {
5293
3439
  if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
5294
3440
  if (nexttoken.id === 'var') {
5295
3441
  advance('var');
5296
- varstatement(true);
3442
+ varstatement.fud.call(varstatement, true);
5297
3443
  } else {
5298
3444
  switch (funct[nexttoken.value]) {
5299
3445
  case 'unused':
@@ -5311,9 +3457,10 @@ loop: for (;;) {
5311
3457
  expression(20);
5312
3458
  advance(')', t);
5313
3459
  s = block(true, true);
5314
- if (!f && (s.length > 1 || typeof s[0] !== 'object' ||
3460
+ if (option.forin && (s.length > 1 || typeof s[0] !== 'object' ||
5315
3461
  s[0].value !== 'if')) {
5316
- warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this);
3462
+ warning("The body of a for in should be wrapped in an if statement to filter " +
3463
+ "unwanted properties from the prototype.", this);
5317
3464
  }
5318
3465
  funct['(breakage)'] -= 1;
5319
3466
  funct['(loopage)'] -= 1;
@@ -5322,7 +3469,7 @@ loop: for (;;) {
5322
3469
  if (nexttoken.id !== ';') {
5323
3470
  if (nexttoken.id === 'var') {
5324
3471
  advance('var');
5325
- varstatement();
3472
+ varstatement.fud.call(varstatement);
5326
3473
  } else {
5327
3474
  for (;;) {
5328
3475
  expression(0, 'for');
@@ -5371,10 +3518,13 @@ loop: for (;;) {
5371
3518
 
5372
3519
  stmt('break', function () {
5373
3520
  var v = nexttoken.value;
5374
- if (funct['(breakage)'] === 0) {
3521
+
3522
+ if (funct['(breakage)'] === 0)
5375
3523
  warning("Unexpected '{a}'.", nexttoken, this.value);
5376
- }
5377
- nolinebreak(this);
3524
+
3525
+ if (!option.asi)
3526
+ nolinebreak(this);
3527
+
5378
3528
  if (nexttoken.id !== ';') {
5379
3529
  if (token.line === nexttoken.line) {
5380
3530
  if (funct[v] !== 'label') {
@@ -5393,10 +3543,13 @@ loop: for (;;) {
5393
3543
 
5394
3544
  stmt('continue', function () {
5395
3545
  var v = nexttoken.value;
5396
- if (funct['(breakage)'] === 0) {
3546
+
3547
+ if (funct['(breakage)'] === 0)
5397
3548
  warning("Unexpected '{a}'.", nexttoken, this.value);
5398
- }
5399
- nolinebreak(this);
3549
+
3550
+ if (!option.asi)
3551
+ nolinebreak(this);
3552
+
5400
3553
  if (nexttoken.id !== ';') {
5401
3554
  if (token.line === nexttoken.line) {
5402
3555
  if (funct[v] !== 'label') {
@@ -5416,14 +3569,19 @@ loop: for (;;) {
5416
3569
 
5417
3570
 
5418
3571
  stmt('return', function () {
5419
- nolinebreak(this);
5420
- if (nexttoken.id === '(regexp)') {
3572
+ if (!option.asi)
3573
+ nolinebreak(this);
3574
+
3575
+ if (nexttoken.id === '(regexp)')
5421
3576
  warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
3577
+
3578
+ if (this.line === nexttoken.line || !option.asi) {
3579
+ if (nexttoken.id !== ';' && !nexttoken.reach) {
3580
+ nonadjacent(token, nexttoken);
3581
+ this.first = expression(20);
3582
+ }
5422
3583
  }
5423
- if (nexttoken.id !== ';' && !nexttoken.reach) {
5424
- nonadjacent(token, nexttoken);
5425
- this.first = expression(20);
5426
- }
3584
+
5427
3585
  reachable('return');
5428
3586
  return this;
5429
3587
  }).exps = true;
@@ -5437,8 +3595,6 @@ loop: for (;;) {
5437
3595
  return this;
5438
3596
  }).exps = true;
5439
3597
 
5440
- reserve('void');
5441
-
5442
3598
  // Superfluous reserved words
5443
3599
 
5444
3600
  reserve('class');
@@ -5484,8 +3640,10 @@ loop: for (;;) {
5484
3640
  if (o[nexttoken.value] === true) {
5485
3641
  warning("Duplicate key '{a}'.",
5486
3642
  nexttoken, nexttoken.value);
5487
- } else if (nexttoken.value === '__proto__') {
5488
- warning("Stupid key '{a}'.",
3643
+ } else if ((nexttoken.value === '__proto__' &&
3644
+ !option.proto) || (nexttoken.value === '__iterator__' &&
3645
+ !option.iterator)) {
3646
+ warning("The '{a}' key may produce unexpected results.",
5489
3647
  nexttoken, nexttoken.value);
5490
3648
  } else {
5491
3649
  o[nexttoken.value] = true;
@@ -5571,57 +3729,17 @@ loop: for (;;) {
5571
3729
  } else if (typeof a === 'object') {
5572
3730
  k = Object.keys(a);
5573
3731
  for (i = 0; i < k.length; i += 1) {
5574
- predefined[k[i]] = !!a[k];
3732
+ predefined[k[i]] = !!a[k[i]];
5575
3733
  }
5576
3734
  }
5577
3735
  }
5578
- if (o.adsafe) {
5579
- o.safe = true;
5580
- }
5581
- if (o.safe) {
5582
- o.browser =
5583
- o.css =
5584
- o.debug =
5585
- o.devel =
5586
- o.evil =
5587
- o.forin =
5588
- o.loopfunc =
5589
- o.on =
5590
- o.rhino =
5591
- o.windows =
5592
- o.sub =
5593
- o.widget = false;
5594
-
5595
- o.eqeqeq =
5596
- o.nomen =
5597
- o.safe =
5598
- o.undef = true;
5599
-
5600
- predefined.Date =
5601
- predefined['eval'] =
5602
- predefined.Function =
5603
- predefined.Object = null;
5604
-
5605
- predefined.ADSAFE =
5606
- predefined.lib = false;
5607
- }
5608
3736
  option = o;
5609
3737
  } else {
5610
3738
  option = {};
5611
3739
  }
5612
3740
  option.indent = option.indent || 4;
5613
3741
  option.maxerr = option.maxerr || 50;
5614
- adsafe_id = '';
5615
- adsafe_may = false;
5616
- adsafe_went = false;
5617
- approved = {};
5618
- if (option.approved) {
5619
- for (i = 0; i < option.approved.length; i += 1) {
5620
- approved[option.approved[i]] = option.approved[i];
5621
- }
5622
- } else {
5623
- approved.test = 'test';
5624
- }
3742
+
5625
3743
  tab = '';
5626
3744
  for (i = 0; i < option.indent; i += 1) {
5627
3745
  tab += ' ';
@@ -5637,10 +3755,8 @@ loop: for (;;) {
5637
3755
  '(loopage)': 0
5638
3756
  };
5639
3757
  functions = [funct];
5640
- ids = {};
5641
3758
  urls = [];
5642
3759
  src = false;
5643
- xmode = false;
5644
3760
  stack = null;
5645
3761
  member = {};
5646
3762
  membersOnly = null;
@@ -5658,52 +3774,21 @@ loop: for (;;) {
5658
3774
 
5659
3775
  try {
5660
3776
  advance();
5661
- if (nexttoken.value.charAt(0) === '<') {
5662
- html();
5663
- if (option.adsafe && !adsafe_went) {
5664
- warning("ADsafe violation: Missing ADSAFE.go.", this);
5665
- }
5666
- } else {
5667
- switch (nexttoken.id) {
5668
- case '{':
5669
- case '[':
5670
- option.laxbreak = true;
5671
- jsonmode = true;
5672
- jsonValue();
5673
- break;
5674
- case '@':
5675
- case '*':
5676
- case '#':
5677
- case '.':
5678
- case ':':
5679
- xmode = 'style';
5680
- advance();
5681
- if (token.id !== '@' || !nexttoken.identifier ||
5682
- nexttoken.value !== 'charset' || token.line !== 1 ||
5683
- token.from !== 1) {
5684
- error("A css file should begin with @charset 'UTF-8';");
5685
- }
5686
- advance();
5687
- if (nexttoken.type !== '(string)' &&
5688
- nexttoken.value !== 'UTF-8') {
5689
- error("A css file should begin with @charset 'UTF-8';");
5690
- }
5691
- advance();
5692
- advance(';');
5693
- styles();
5694
- break;
5695
-
5696
- default:
5697
- if (option.adsafe && option.fragment) {
5698
- error("Expected '{a}' and instead saw '{b}'.",
5699
- nexttoken, '<div>', nexttoken.value);
5700
- }
5701
- if (nexttoken.value === 'use strict') {
3777
+ switch (nexttoken.id) {
3778
+ case '{':
3779
+ case '[':
3780
+ option.laxbreak = true;
3781
+ jsonmode = true;
3782
+ jsonValue();
3783
+ break;
3784
+ default:
3785
+ if (nexttoken.value === 'use strict') {
3786
+ if (!option.globalstrict)
5702
3787
  warning("Use the function form of \"use strict\".");
5703
- use_strict();
5704
- }
5705
- statements('lib');
3788
+ use_strict();
5706
3789
  }
3790
+
3791
+ statements('lib');
5707
3792
  }
5708
3793
  advance('(end)');
5709
3794
  } catch (e) {
@@ -5718,9 +3803,7 @@ loop: for (;;) {
5718
3803
  return JSHINT.errors.length === 0;
5719
3804
  };
5720
3805
 
5721
-
5722
- // Data summary.
5723
-
3806
+ // Data summary.
5724
3807
  itself.data = function () {
5725
3808
 
5726
3809
  var data = {functions: []}, fu, globals, implieds = [], f, i, j,
@@ -5877,9 +3960,7 @@ loop: for (;;) {
5877
3960
  detail("URLs<br>", data.urls, '<br>');
5878
3961
  }
5879
3962
 
5880
- if (xmode === 'style') {
5881
- o.push('<p>CSS.</p>');
5882
- } else if (data.json && !err) {
3963
+ if (data.json && !err) {
5883
3964
  o.push('<p>JSON: good.</p>');
5884
3965
  } else if (data.globals) {
5885
3966
  o.push('<div><i>Global</i> ' +
@@ -5933,12 +4014,11 @@ loop: for (;;) {
5933
4014
  }
5934
4015
  return o.join('');
5935
4016
  };
5936
- itself.jshint = itself;
5937
4017
 
5938
- itself.edition = '2011-03-01';
4018
+ itself.jshint = itself;
4019
+ itself.edition = '2011-04-16';
5939
4020
 
5940
4021
  return itself;
5941
-
5942
4022
  }());
5943
4023
 
5944
4024
  // Make JSHINT a Node module, if possible.