jslint_on_rails 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ disable_system_gems
2
+ clear_sources
3
+ source "http://gemcutter.org"
4
+ source "http://gems.github.com"
5
+ bundle_path 'gems'
6
+
7
+ gem 'rspec'
8
+ gem 'fakefs'
@@ -48,11 +48,13 @@ file to be kept - for example:
48
48
  If you wish to write your own rake task to run JSLint, you can create and execute the JSLint object manually:
49
49
 
50
50
  require 'jslint'
51
+
51
52
  lint = JSLint::Lint.new(
52
53
  :paths => ['public/javascripts/**/*.js'],
53
54
  :exclude_paths => ['public/javascripts/vendor/**/*.js'],
54
55
  :config_path => 'config/jslint.yml'
55
56
  )
57
+
56
58
  lint.run
57
59
 
58
60
 
@@ -0,0 +1,8 @@
1
+ require 'gems/environment'
2
+ require 'spec/rake/spectask'
3
+
4
+ desc 'Run the specs'
5
+ Spec::Rake::SpecTask.new do |t|
6
+ t.libs << 'lib'
7
+ t.spec_opts = ['--colour', '--format', 'specdoc']
8
+ end
@@ -1,3 +1,3 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/jslint/errors')
2
- require File.expand_path(File.dirname(__FILE__) + '/jslint/utils')
3
- require File.expand_path(File.dirname(__FILE__) + '/jslint/lint')
1
+ require 'jslint/errors'
2
+ require 'jslint/utils'
3
+ require 'jslint/lint'
@@ -36,6 +36,7 @@ white: false # true if strict whitespace rules apply (see also 'indent' o
36
36
  cap: false # true if upper case HTML should be allowed
37
37
  css: true # true if CSS workarounds should be tolerated
38
38
  debug: false # true if debugger statements should be allowed (set to false before going into production)
39
+ es5: true # true if ECMAScript 5 syntax should be allowed
39
40
  evil: false # true if eval should be allowed
40
41
  forin: true # true if unfiltered 'for in' statements should be allowed
41
42
  fragment: true # true if HTML fragments should be allowed
@@ -53,7 +54,7 @@ passfail: false # true if the scan should stop on first error (per file)
53
54
  predef: '' # Names of predefined global variables - comma-separated string
54
55
  browser: true # true if the standard browser globals should be predefined
55
56
  rhino: false # true if the Rhino environment globals should be predefined
56
- sidebar: false # true if the Windows Sidebar Gadgets globals should be predefined
57
+ windows: false # true if Windows-specific globals should be predefined
57
58
  widget: false # true if the Yahoo Widgets globals should be predefined
58
59
  devel: true # true if functions like alert, confirm, console, prompt etc. are predefined
59
60
 
@@ -1,13 +1,16 @@
1
+ require 'jslint/errors'
2
+ require 'jslint/utils'
3
+
1
4
  module JSLint
2
5
 
3
6
  PATH = File.dirname(__FILE__)
4
7
 
5
- TEST_JAR_FILE = File.expand_path("#{PATH}/../../vendor/test.jar")
6
- RHINO_JAR_FILE = File.expand_path("#{PATH}/../../vendor/rhino.jar")
8
+ TEST_JAR_FILE = File.expand_path("#{PATH}/vendor/test.jar")
9
+ RHINO_JAR_FILE = File.expand_path("#{PATH}/vendor/rhino.jar")
7
10
  TEST_JAR_CLASS = "Test"
8
11
  RHINO_JAR_CLASS = "org.mozilla.javascript.tools.shell.Main"
9
12
 
10
- JSLINT_FILE = File.expand_path("#{PATH}/../../vendor/jslint.js")
13
+ JSLINT_FILE = File.expand_path("#{PATH}/vendor/jslint.js")
11
14
 
12
15
  class Lint
13
16
 
@@ -24,27 +27,35 @@ module JSLint
24
27
  excluded_files = files_matching_paths(options, :exclude_paths)
25
28
  @file_list = Utils.exclude_files(included_files, excluded_files)
26
29
 
27
- ['paths', 'exclude_paths', 'config_path'].each { |field| @config.delete(field) }
30
+ ['paths', 'exclude_paths'].each { |field| @config.delete(field) }
28
31
  end
29
32
 
30
33
  def run
31
34
  check_java
32
- puts "Running JSLint:\n\n"
33
- command = "java -cp #{RHINO_JAR_FILE} #{RHINO_JAR_CLASS} #{JSLINT_FILE} #{option_string} #{@file_list.join(' ')}"
34
- success = system(command)
35
+ Utils.xputs "Running JSLint:\n\n"
36
+ arguments = "#{JSLINT_FILE} #{option_string} #{@file_list.join(' ')}"
37
+ success = call_java_with_status(RHINO_JAR_FILE, RHINO_JAR_CLASS, arguments)
35
38
  raise LintCheckFailure, "JSLint test failed." unless success
36
39
  end
37
40
 
38
41
 
39
42
  private
40
43
 
44
+ def call_java_with_output(jar, mainClass, arguments = "")
45
+ %x(java -cp #{jar} #{mainClass} #{arguments})
46
+ end
47
+
48
+ def call_java_with_status(jar, mainClass, arguments = "")
49
+ system("java -cp #{jar} #{mainClass} #{arguments}")
50
+ end
51
+
41
52
  def option_string
42
53
  @config.map { |k, v| "#{k}=#{v.inspect}" }.join(',')
43
54
  end
44
55
 
45
56
  def check_java
46
57
  unless @java_ok
47
- java_test = %x(java -cp #{TEST_JAR_FILE} #{TEST_JAR_CLASS})
58
+ java_test = call_java_with_output(TEST_JAR_FILE, TEST_JAR_CLASS)
48
59
  if java_test.strip == "OK"
49
60
  @java_ok = true
50
61
  else
@@ -1,2 +1,4 @@
1
+ require 'jslint/utils'
2
+
1
3
  # for Rails, set config file path to config/jslint.yml in Rails root
2
- JSLint.config_path = File.expand_path(RAILS_ROOT + '/config/jslint.yml')
4
+ JSLint.config_path = File.join(Rails.root, 'config', 'jslint.yml')
@@ -1,4 +1,5 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../jslint')
1
+ require 'jslint/lint'
2
+ require 'jslint/utils'
2
3
 
3
4
  desc "Run JSLint check on selected Javascript files"
4
5
  task :jslint do
@@ -2,7 +2,8 @@ require 'ftools'
2
2
 
3
3
  module JSLint
4
4
 
5
- DEFAULT_CONFIG_FILE = File.expand_path(File.dirname(__FILE__) + "/../../config/jslint.yml")
5
+ VERSION = "1.0.2"
6
+ DEFAULT_CONFIG_FILE = File.expand_path(File.dirname(__FILE__) + "/config/jslint.yml")
6
7
 
7
8
  class << self
8
9
  attr_accessor :config_path
@@ -11,6 +12,14 @@ module JSLint
11
12
  module Utils
12
13
  class << self
13
14
 
15
+ def xprint(txt)
16
+ print txt
17
+ end
18
+
19
+ def xputs(txt)
20
+ puts txt
21
+ end
22
+
14
23
  def load_config_file(file_name)
15
24
  if file_name && File.exists?(file_name) && File.file?(file_name) && File.readable?(file_name)
16
25
  YAML.load_file(file_name)
@@ -40,28 +49,28 @@ module JSLint
40
49
 
41
50
  def copy_config_file
42
51
  raise ArgumentError, "Please set JSLint.config_path" if JSLint.config_path.nil?
43
- print "Copying default config file to #{File.expand_path(JSLint.config_path)}... "
52
+ xprint "Copying default config file to #{File.expand_path(JSLint.config_path)}... "
44
53
  if File.exists?(JSLint.config_path)
45
- puts "\n\nWarning: config file exists, so it won't be overwritten. " +
46
- "You can copy it manually from the jslint_on_rails directory if you want to reset it."
54
+ xputs "\n\nWarning: config file exists, so it won't be overwritten. " +
55
+ "You can copy it manually from the jslint_on_rails directory if you want to reset it."
47
56
  else
48
57
  File.copy(JSLint::DEFAULT_CONFIG_FILE, JSLint.config_path)
49
- puts "OK."
58
+ xputs "OK."
50
59
  end
51
60
  end
52
61
 
53
62
  def remove_config_file
54
63
  raise ArgumentError, "Please set JSLint.config_path" if JSLint.config_path.nil?
55
- print "Removing config file... "
64
+ xprint "Removing config file... "
56
65
  if File.exists?(JSLint.config_path) && File.file?(JSLint.config_path)
57
66
  if File.read(JSLint.config_path) == File.read(JSLint::DEFAULT_CONFIG_FILE)
58
67
  File.delete(JSLint.config_path)
59
- puts "OK."
68
+ xputs "OK."
60
69
  else
61
- puts "File was modified, so it won't be deleted automatically."
70
+ xputs "File was modified, so it won't be deleted automatically."
62
71
  end
63
72
  else
64
- puts "OK (no config file found)."
73
+ xputs "OK (no config file found)."
65
74
  end
66
75
  end
67
76
 
@@ -1,5 +1,5 @@
1
1
  // jslint.js
2
- // 2009-11-22
2
+ // 2010-04-06
3
3
 
4
4
  /*
5
5
  Copyright (c) 2002 Douglas Crockford (www.JSLint.com)
@@ -144,110 +144,112 @@ SOFTWARE.
144
144
  evil: true, nomen: false, onevar: false, regexp: false, strict: true
145
145
  */
146
146
 
147
- /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
148
- "(begin)", "(breakage)", "(context)", "(error)", "(global)",
149
- "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
150
- "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
151
- "<", "<=", "==", "===", ">", ">=", ADSAFE, Array, Boolean,
152
- COM, Canvas, CustomAnimation, Date, Debug, E, Error, EvalError,
153
- FadeAnimation, Flash, FormField, Frame, Function, HotKey, Image, JSON,
154
- LN10, LN2, LOG10E, LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem,
155
- MoveAnimation, NEGATIVE_INFINITY, Number, Object, Option, PI,
156
- POSITIVE_INFINITY, Point, RangeError, Rectangle, ReferenceError, RegExp,
157
- ResizeAnimation, RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String,
158
- Style, SyntaxError, System, Text, TextArea, Timer, TypeError, URIError,
159
- URL, Web, Window, XMLDOM, XMLHttpRequest, "\\", a, abbr, acronym,
160
- addEventListener, address, adsafe, alert, aliceblue, animator,
161
- antiquewhite, appleScript, applet, apply, approved, aqua, aquamarine,
162
- area, arguments, arity, autocomplete, azure, b, background,
163
- "background-attachment", "background-color", "background-image",
164
- "background-position", "background-repeat", base, bdo, beep, beige, big,
165
- bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
166
- blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
167
- "border-bottom-style", "border-bottom-width", "border-collapse",
168
- "border-color", "border-left", "border-left-color", "border-left-style",
169
- "border-left-width", "border-right", "border-right-color",
170
- "border-right-style", "border-right-width", "border-spacing",
171
- "border-style", "border-top", "border-top-color", "border-top-style",
172
- "border-top-width", "border-width", bottom, br, brown, browser,
173
- burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
174
- canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
175
- character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
176
- cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
177
- closed, closure, cm, code, col, colgroup, color, comment, condition,
178
- confirm, console, constructor, content, convertPathToHFS,
179
- convertPathToPlatform, coral, cornflowerblue, cornsilk,
180
- "counter-increment", "counter-reset", create, crimson, css, cursor,
181
- cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
182
- darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
183
- darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
184
- darkviolet, data, dd, debug, decodeURI, decodeURIComponent, deeppink,
185
- deepskyblue, defaultStatus, defineClass, del, deserialize, devel, dfn,
186
- dimension, dimgray, dir, direction, display, div, dl, document,
187
- dodgerblue, dt, edition, else, em, embed, empty, "empty-cells",
188
- encodeURI, encodeURIComponent, entityify, eqeqeq, errors, escape, eval,
189
- event, evidence, evil, ex, exception, exec, exps, fieldset, filesystem,
190
- firebrick, first, float, floor, floralwhite, focus, focusWidget, font,
191
- "font-face", "font-family", "font-size", "font-size-adjust",
192
- "font-stretch", "font-style", "font-variant", "font-weight",
193
- forestgreen, forin, form, fragment, frame, frames, frameset, from,
194
- fromCharCode, fuchsia, fud, funct, function, functions, g, gainsboro,
195
- gc, getComputedStyle, ghostwhite, global, globals, gold, goldenrod,
196
- gray, green, greenyellow, h1, h2, h3, h4, h5, h6, hasOwnProperty, head,
197
- height, help, history, honeydew, hotpink, hr, html, i, iTunes, id,
198
- identifier, iframe, img, immed, implieds, in, include, indent, indexOf,
199
- indianred, indigo, init, input, ins, isAlpha, isApplicationRunning,
200
- isDigit, isFinite, isNaN, ivory, join, jslint, json, kbd, khaki,
201
- konfabulatorVersion, label, labelled, lang, last, lavender,
202
- lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
203
- lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
204
- lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
205
- lightseagreen, lightskyblue, lightslategray, lightsteelblue,
206
- lightyellow, lime, limegreen, line, "line-height", linen, link,
207
- "list-style", "list-style-image", "list-style-position",
208
- "list-style-type", load, loadClass, location, log, m, magenta, map,
209
- margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
210
- "marker-offset", maroon, match, "max-height", "max-width", maxerr, maxlen,
211
- md5, media, mediumaquamarine, mediumblue, mediumorchid, mediumpurple,
212
- mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise,
213
- mediumvioletred, member, menu, message, meta, midnightblue,
214
- "min-height", "min-width", mintcream, mistyrose, mm, moccasin, moveBy,
215
- moveTo, name, navajowhite, navigator, navy, new, newcap, noframes,
216
- nomen, noscript, nud, object, ol, oldlace, olive, olivedrab, on,
217
- onbeforeunload, onblur, onerror, onevar, onfocus, onload, onresize,
218
- onunload, opacity, open, openURL, opener, opera, optgroup, option,
219
- orange, orangered, orchid, outer, outline, "outline-color",
220
- "outline-style", "outline-width", overflow, "overflow-x", "overflow-y",
221
- p, padding, "padding-bottom", "padding-left", "padding-right",
222
- "padding-top", page, "page-break-after", "page-break-before",
223
- palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip,
224
- param, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru,
225
- pink, play, plum, plusplus, pop, popupMenu, position, powderblue, pre,
226
- predef, preferenceGroups, preferences, print, prompt, prototype, pt,
227
- purple, push, px, q, quit, quotes, random, range, raw, reach, readFile,
228
- readUrl, reason, red, regexp, reloadWidget, removeEventListener,
229
- replace, report, reserved, resizeBy, resizeTo, resolvePath,
230
- resumeUpdates, rhino, right, rosybrown, royalblue, runCommand,
231
- runCommandInBg, saddlebrown, safe, salmon, samp, sandybrown, saveAs,
232
- savePreferences, screen, script, scroll, scrollBy, scrollTo, seagreen,
233
- seal, search, seashell, select, serialize, setInterval, setTimeout,
234
- shift, showWidgetPreferences, sidebar, sienna, silver, skyblue,
235
- slateblue, slategray, sleep, slice, small, snow, sort, span, spawn,
236
- speak, split, springgreen, src, status, steelblue, strict, strong,
237
- style, styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
238
- system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
239
- "text-align", "text-decoration", "text-indent", "text-shadow",
240
- "text-transform", textarea, tfoot, th, thead, thistle, title,
241
- toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
242
- turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
243
- unwatch, updateNow, urls, value, valueOf, var, version,
244
- "vertical-align", violet, visibility, watch, wheat, white,
245
- "white-space", whitesmoke, widget, width, "word-spacing", "word-wrap",
246
- yahooCheckLogin, yahooLogin, yahooLogout, yellow, yellowgreen,
247
- "z-index"
147
+ /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
148
+ "(begin)", "(breakage)", "(context)", "(error)", "(global)",
149
+ "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
150
+ "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
151
+ "<", "<=", "==", "===", ">", ">=", ADSAFE, ActiveXObject,
152
+ Array, Boolean, COM, CScript, Canvas, CustomAnimation, Date, Debug, E,
153
+ Enumerator, Error, EvalError, FadeAnimation, Flash, FormField, Frame,
154
+ Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
155
+ MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY, Number,
156
+ Object, Option, PI, POSITIVE_INFINITY, Point, RangeError, Rectangle,
157
+ ReferenceError, RegExp, ResizeAnimation, RotateAnimation, SQRT1_2,
158
+ SQRT2, ScrollBar, String, Style, SyntaxError, System, Text, TextArea,
159
+ Timer, TypeError, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
160
+ XMLHttpRequest, "\\", a, abbr, acronym, addEventListener, address,
161
+ adsafe, alert, aliceblue, animator, antiquewhite, appleScript, applet,
162
+ apply, approved, aqua, aquamarine, area, arguments, arity, article,
163
+ aside, audio, autocomplete, azure, b, background,
164
+ "background-attachment", "background-color", "background-image",
165
+ "background-position", "background-repeat", base, bdo, beep, beige, big,
166
+ bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
167
+ blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
168
+ "border-bottom-style", "border-bottom-width", "border-collapse",
169
+ "border-color", "border-left", "border-left-color", "border-left-style",
170
+ "border-left-width", "border-right", "border-right-color",
171
+ "border-right-style", "border-right-width", "border-spacing",
172
+ "border-style", "border-top", "border-top-color", "border-top-style",
173
+ "border-top-width", "border-width", bottom, br, brown, browser,
174
+ burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
175
+ canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
176
+ character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
177
+ cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
178
+ closed, closure, cm, code, col, colgroup, color, command, comment,
179
+ condition, confirm, console, constructor, content, convertPathToHFS,
180
+ convertPathToPlatform, coral, cornflowerblue, cornsilk,
181
+ "counter-increment", "counter-reset", create, crimson, css, cursor,
182
+ cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
183
+ darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
184
+ darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
185
+ darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,
186
+ deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,
187
+ details, devel, dfn, dialog, dimension, dimgray, dir, direction,
188
+ display, div, dl, document, dodgerblue, dt, edition, else, em, embed,
189
+ empty, "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq,
190
+ errors, es5, escape, eval, event, evidence, evil, ex, exception, exec, exps,
191
+ fieldset, figure, filesystem, firebrick, first, float, floor,
192
+ floralwhite, focus, focusWidget, font, "font-face", "font-family",
193
+ "font-size", "font-size-adjust", "font-stretch", "font-style",
194
+ "font-variant", "font-weight", footer, forestgreen, forin, form,
195
+ fragment, frame, frames, frameset, from, fromCharCode, fuchsia, fud,
196
+ funct, function, functions, g, gainsboro, gc, getComputedStyle,
197
+ ghostwhite, global, globals, gold, goldenrod, gray, green, greenyellow,
198
+ h1, h2, h3, h4, h5, h6, hasOwnProperty, head, header, height, help,
199
+ hgroup, history, honeydew, hotpink, hr, html, i, iTunes, id, identifier,
200
+ iframe, img, immed, implieds, in, include, indent, indexOf, indianred,
201
+ indigo, init, input, ins, isAlpha, isApplicationRunning, isDigit,
202
+ isFinite, isNaN, ivory, join, jslint, json, kbd, keygen, khaki,
203
+ konfabulatorVersion, label, labelled, lang, last, lavender,
204
+ lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
205
+ lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
206
+ lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
207
+ lightseagreen, lightskyblue, lightslategray, lightsteelblue,
208
+ lightyellow, lime, limegreen, line, "line-height", linen, link,
209
+ "list-style", "list-style-image", "list-style-position",
210
+ "list-style-type", load, loadClass, location, log, m, magenta, map,
211
+ margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
212
+ mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr,
213
+ maxlen, md5, media, mediumaquamarine, mediumblue, mediumorchid,
214
+ mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen,
215
+ mediumturquoise, mediumvioletred, member, menu, message, meta, meter,
216
+ midnightblue, "min-height", "min-width", mintcream, mistyrose, mm,
217
+ moccasin, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,
218
+ newcap, noframes, nomen, noscript, nud, object, ol, oldlace, olive,
219
+ olivedrab, on, onbeforeunload, onblur, onerror, onevar, onfocus, onload,
220
+ onresize, onunload, opacity, open, openURL, opener, opera, optgroup,
221
+ option, orange, orangered, orchid, outer, outline, "outline-color",
222
+ "outline-style", "outline-width", output, overflow, "overflow-x",
223
+ "overflow-y", p, padding, "padding-bottom", "padding-left",
224
+ "padding-right", "padding-top", page, "page-break-after",
225
+ "page-break-before", palegoldenrod, palegreen, paleturquoise,
226
+ palevioletred, papayawhip, param, parent, parseFloat, parseInt,
227
+ passfail, pc, peachpuff, peru, pink, play, plum, plusplus, pop,
228
+ popupMenu, position, powderblue, pre, predef, preferenceGroups,
229
+ preferences, print, progress, prompt, prototype, pt, purple, push, px,
230
+ q, quit, quotes, random, range, raw, reach, readFile, readUrl, reason,
231
+ red, regexp, reloadWidget, removeEventListener, replace, report,
232
+ reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right,
233
+ rosybrown, royalblue, rp, rt, ruby, runCommand, runCommandInBg,
234
+ saddlebrown, safe, salmon, samp, sandybrown, saveAs, savePreferences,
235
+ screen, script, scroll, scrollBy, scrollTo, seagreen, seal, search,
236
+ seashell, section, select, serialize, setInterval, setTimeout, shift,
237
+ showWidgetPreferences, sienna, silver, skyblue, slateblue, slategray,
238
+ sleep, slice, small, snow, sort, source, span, spawn, speak, split,
239
+ springgreen, src, stack, status, steelblue, strict, strong, style,
240
+ styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
241
+ system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
242
+ "text-align", "text-decoration", "text-indent", "text-shadow",
243
+ "text-transform", textarea, tfoot, th, thead, thistle, time, title,
244
+ toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
245
+ turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
246
+ unwatch, updateNow, urls, value, valueOf, var, version,
247
+ "vertical-align", video, violet, visibility, watch, wheat, white,
248
+ "white-space", whitesmoke, widget, width, windows, "word-spacing",
249
+ "word-wrap", yahooCheckLogin, yahooLogin, yahooLogout, yellow,
250
+ yellowgreen, "z-index"
248
251
  */
249
252
 
250
-
251
253
  // We build the application inside a function so that we produce only a single
252
254
  // global variable. The function will be invoked, its return value is the JSLINT
253
255
  // application itself.
@@ -294,6 +296,7 @@ var JSLINT = (function () {
294
296
  constructor : true,
295
297
  'eval' : true,
296
298
  prototype : true,
299
+ stack : true,
297
300
  unwatch : true,
298
301
  valueOf : true,
299
302
  watch : true
@@ -311,6 +314,7 @@ var JSLINT = (function () {
311
314
  debug : true, // if debugger statements should be allowed
312
315
  devel : true, // if logging should be allowed (console, alert, etc.)
313
316
  eqeqeq : true, // if === should be required
317
+ es5 : true, // if ES5 syntax should be allowed
314
318
  evil : true, // if eval should be allowed
315
319
  forin : true, // if for in statements must filter
316
320
  fragment : true, // if HTML fragments should be allowed
@@ -326,7 +330,7 @@ var JSLINT = (function () {
326
330
  rhino : true, // if the Rhino environment globals should be predefined
327
331
  undef : true, // if variables should be declared before used
328
332
  safe : true, // if use of some browser features should be restricted
329
- sidebar : true, // if the System object should be predefined
333
+ windows : true, // if MS Windows-specigic globals should be predefined
330
334
  strict : true, // require the "use strict"; pragma
331
335
  sub : true, // if all forms of subscript notation are tolerated
332
336
  white : true, // if strict whitespace rules apply
@@ -587,6 +591,9 @@ var JSLINT = (function () {
587
591
  address: {},
588
592
  applet: {},
589
593
  area: {empty: true, parent: ' map '},
594
+ article: {},
595
+ aside: {},
596
+ audio: {},
590
597
  b: {},
591
598
  base: {empty: true, parent: ' head '},
592
599
  bdo: {},
@@ -602,8 +609,12 @@ var JSLINT = (function () {
602
609
  code: {},
603
610
  col: {empty: true, parent: ' table colgroup '},
604
611
  colgroup: {parent: ' table '},
612
+ command: {parent: ' menu '},
613
+ datalist: {},
605
614
  dd: {parent: ' dl '},
606
615
  del: {},
616
+ details: {},
617
+ dialog: {},
607
618
  dfn: {},
608
619
  dir: {},
609
620
  div: {},
@@ -612,7 +623,9 @@ var JSLINT = (function () {
612
623
  em: {},
613
624
  embed: {},
614
625
  fieldset: {},
626
+ figure: {},
615
627
  font: {},
628
+ footer: {},
616
629
  form: {},
617
630
  frame: {empty: true, parent: ' frameset '},
618
631
  frameset: {parent: ' html frameset '},
@@ -623,6 +636,8 @@ var JSLINT = (function () {
623
636
  h5: {},
624
637
  h6: {},
625
638
  head: {parent: ' html '},
639
+ header: {},
640
+ hgroup: {},
626
641
  html: {parent: '*'},
627
642
  hr: {empty: true},
628
643
  i: {},
@@ -631,28 +646,39 @@ var JSLINT = (function () {
631
646
  input: {empty: true},
632
647
  ins: {},
633
648
  kbd: {},
649
+ keygen: {},
634
650
  label: {},
635
- legend: {parent: ' fieldset '},
651
+ legend: {parent: ' details fieldset figure '},
636
652
  li: {parent: ' dir menu ol ul '},
637
653
  link: {empty: true, parent: ' head '},
638
654
  map: {},
655
+ mark: {},
639
656
  menu: {},
640
657
  meta: {empty: true, parent: ' head noframes noscript '},
658
+ meter: {},
659
+ nav: {},
641
660
  noframes: {parent: ' html body '},
642
661
  noscript: {parent: ' body head noframes '},
643
662
  object: {},
644
663
  ol: {},
645
664
  optgroup: {parent: ' select '},
646
665
  option: {parent: ' optgroup select '},
666
+ output: {},
647
667
  p: {},
648
668
  param: {empty: true, parent: ' applet object '},
649
669
  pre: {},
670
+ progress: {},
650
671
  q: {},
672
+ rp: {},
673
+ rt: {},
674
+ ruby: {},
651
675
  samp: {},
652
676
  script: {empty: true, parent: ' body div frame head iframe p pre span '},
677
+ section: {},
653
678
  select: {},
654
679
  small: {},
655
680
  span: {},
681
+ source: {},
656
682
  strong: {},
657
683
  style: {parent: ' head ', empty: true},
658
684
  sub: {},
@@ -664,12 +690,14 @@ var JSLINT = (function () {
664
690
  tfoot: {parent: ' table '},
665
691
  th: {parent: ' tr '},
666
692
  thead: {parent: ' table '},
693
+ time: {},
667
694
  title: {parent: ' head '},
668
695
  tr: {parent: ' table tbody thead tfoot '},
669
696
  tt: {},
670
697
  u: {},
671
698
  ul: {},
672
- 'var': {}
699
+ 'var': {},
700
+ video: {}
673
701
  },
674
702
 
675
703
  ids, // HTML ids
@@ -710,8 +738,14 @@ var JSLINT = (function () {
710
738
 
711
739
  scope, // The current scope
712
740
 
713
- sidebar = {
714
- System : false
741
+ windows = {
742
+ ActiveXObject: false,
743
+ CScript : false,
744
+ Debug : false,
745
+ Enumerator : false,
746
+ System : false,
747
+ VBArray : false,
748
+ WScript : false
715
749
  },
716
750
 
717
751
  src,
@@ -872,7 +906,8 @@ var JSLINT = (function () {
872
906
  // token
873
907
  tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
874
908
  // html token
875
- hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--|.)/,
909
+ //////// hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--|.)/,
910
+ hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--)/,
876
911
  // characters in strings that need escapement
877
912
  nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
878
913
  nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
@@ -890,7 +925,7 @@ var JSLINT = (function () {
890
925
  sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
891
926
  ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,
892
927
  // attributes characters
893
- qx = /[^a-zA-Z0-9-_\/ ]/,
928
+ qx = /[^a-zA-Z0-9+\-_\/ ]/,
894
929
  // query characters for ids
895
930
  dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
896
931
 
@@ -982,11 +1017,11 @@ var JSLINT = (function () {
982
1017
  if (option.devel) {
983
1018
  combine(predefined, devel);
984
1019
  }
985
- if (option.browser || option.sidebar) {
1020
+ if (option.browser) {
986
1021
  combine(predefined, browser);
987
1022
  }
988
- if (option.sidebar) {
989
- combine(predefined, sidebar);
1023
+ if (option.windows) {
1024
+ combine(predefined, windows);
990
1025
  }
991
1026
  if (option.widget) {
992
1027
  combine(predefined, widget);
@@ -1126,8 +1161,8 @@ var JSLINT = (function () {
1126
1161
  i = t.id;
1127
1162
  if (i !== '(endline)') {
1128
1163
  prereg = i &&
1129
- (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
1130
- i === 'return');
1164
+ (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
1165
+ i === 'return');
1131
1166
  }
1132
1167
  return t;
1133
1168
  }
@@ -1332,17 +1367,32 @@ var JSLINT = (function () {
1332
1367
  }
1333
1368
  }
1334
1369
  }
1370
+ // t = match(rx[xmode] || tx);
1371
+ // if (!t) {
1372
+ // if (xmode === 'html') {
1373
+ // return it('(error)', s.charAt(0));
1374
+ // } else {
1375
+ // t = '';
1376
+ // c = '';
1377
+ // while (s && s < '!') {
1378
+ // s = s.substr(1);
1379
+ // }
1380
+ // if (s) {
1381
+ // errorAt("Unexpected '{a}'.",
1382
+ // line, character, s.substr(0, 1));
1383
+ // }
1384
+ // }
1335
1385
  t = match(rx[xmode] || tx);
1336
1386
  if (!t) {
1337
- if (xmode === 'html') {
1338
- return it('(error)', s.charAt(0));
1339
- } else {
1340
- t = '';
1341
- c = '';
1342
- while (s && s < '!') {
1343
- s = s.substr(1);
1344
- }
1345
- if (s) {
1387
+ t = '';
1388
+ c = '';
1389
+ while (s && s < '!') {
1390
+ s = s.substr(1);
1391
+ }
1392
+ if (s) {
1393
+ if (xmode === 'html') {
1394
+ return it('(error)', s.charAt(0));
1395
+ } else {
1346
1396
  errorAt("Unexpected '{a}'.",
1347
1397
  line, character, s.substr(0, 1));
1348
1398
  }
@@ -1427,7 +1477,8 @@ var JSLINT = (function () {
1427
1477
  errorAt("Unclosed comment.", line, character);
1428
1478
  } else {
1429
1479
  if (option.safe && ax.test(s)) {
1430
- warningAt("ADsafe comment violation.", line, character);
1480
+ warningAt("ADsafe comment violation.",
1481
+ line, character);
1431
1482
  }
1432
1483
  }
1433
1484
  }
@@ -1458,6 +1509,10 @@ var JSLINT = (function () {
1458
1509
  break;
1459
1510
  // /
1460
1511
  case '/':
1512
+ if (token.id === '/=') {
1513
+ errorAt(
1514
+ "A regular expression literal can be confused with '/='.", line, from);
1515
+ }
1461
1516
  if (prereg) {
1462
1517
  depth = 0;
1463
1518
  captures = 0;
@@ -1468,11 +1523,13 @@ var JSLINT = (function () {
1468
1523
  l += 1;
1469
1524
  switch (c) {
1470
1525
  case '':
1471
- errorAt("Unclosed regular expression.", line, from);
1526
+ errorAt("Unclosed regular expression.",
1527
+ line, from);
1472
1528
  return;
1473
1529
  case '/':
1474
1530
  if (depth > 0) {
1475
- warningAt("Unescaped '{a}'.", line, from + l, '/');
1531
+ warningAt("Unescaped '{a}'.",
1532
+ line, from + l, '/');
1476
1533
  }
1477
1534
  c = s.substr(0, l - 1);
1478
1535
  q = {
@@ -1486,13 +1543,20 @@ var JSLINT = (function () {
1486
1543
  }
1487
1544
  character += l;
1488
1545
  s = s.substr(l);
1546
+ q = s.charAt(0);
1547
+ if (q === '/' || q === '*') {
1548
+ errorAt("Confusing regular expression.",
1549
+ line, from);
1550
+ }
1489
1551
  return it('(regexp)', c);
1490
1552
  case '\\':
1491
1553
  c = s.charAt(l);
1492
1554
  if (c < ' ') {
1493
- warningAt("Unexpected control character in regular expression.", line, from + l);
1555
+ warningAt(
1556
+ "Unexpected control character in regular expression.", line, from + l);
1494
1557
  } else if (c === '<') {
1495
- warningAt("Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1558
+ warningAt(
1559
+ "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1496
1560
  }
1497
1561
  l += 1;
1498
1562
  break;
@@ -1508,7 +1572,8 @@ var JSLINT = (function () {
1508
1572
  l += 1;
1509
1573
  break;
1510
1574
  default:
1511
- warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
1575
+ warningAt(
1576
+ "Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
1512
1577
  }
1513
1578
  } else {
1514
1579
  captures += 1;
@@ -1519,7 +1584,8 @@ var JSLINT = (function () {
1519
1584
  break;
1520
1585
  case ')':
1521
1586
  if (depth === 0) {
1522
- warningAt("Unescaped '{a}'.", line, from + l, ')');
1587
+ warningAt("Unescaped '{a}'.",
1588
+ line, from + l, ')');
1523
1589
  } else {
1524
1590
  depth -= 1;
1525
1591
  }
@@ -1531,7 +1597,8 @@ var JSLINT = (function () {
1531
1597
  q += 1;
1532
1598
  }
1533
1599
  if (q > 1) {
1534
- warningAt("Spaces are hard to count. Use {{a}}.", line, from + l, q);
1600
+ warningAt(
1601
+ "Spaces are hard to count. Use {{a}}.", line, from + l, q);
1535
1602
  }
1536
1603
  break;
1537
1604
  case '[':
@@ -1539,55 +1606,64 @@ var JSLINT = (function () {
1539
1606
  if (c === '^') {
1540
1607
  l += 1;
1541
1608
  if (option.regexp) {
1542
- warningAt("Insecure '{a}'.", line, from + l, c);
1609
+ warningAt("Insecure '{a}'.",
1610
+ line, from + l, c);
1543
1611
  }
1544
1612
  }
1545
1613
  q = false;
1546
1614
  if (c === ']') {
1547
- warningAt("Empty class.", line, from + l - 1);
1615
+ warningAt("Empty class.", line,
1616
+ from + l - 1);
1548
1617
  q = true;
1549
1618
  }
1550
- klass: do {
1619
+ klass: do {
1551
1620
  c = s.charAt(l);
1552
1621
  l += 1;
1553
1622
  switch (c) {
1554
1623
  case '[':
1555
1624
  case '^':
1556
- warningAt("Unescaped '{a}'.", line, from + l, c);
1625
+ warningAt("Unescaped '{a}'.",
1626
+ line, from + l, c);
1557
1627
  q = true;
1558
1628
  break;
1559
1629
  case '-':
1560
1630
  if (q) {
1561
1631
  q = false;
1562
1632
  } else {
1563
- warningAt("Unescaped '{a}'.", line, from + l, '-');
1633
+ warningAt("Unescaped '{a}'.",
1634
+ line, from + l, '-');
1564
1635
  q = true;
1565
1636
  }
1566
1637
  break;
1567
1638
  case ']':
1568
1639
  if (!q) {
1569
- warningAt("Unescaped '{a}'.", line, from + l - 1, '-');
1640
+ warningAt("Unescaped '{a}'.",
1641
+ line, from + l - 1, '-');
1570
1642
  }
1571
1643
  break klass;
1572
1644
  case '\\':
1573
1645
  c = s.charAt(l);
1574
1646
  if (c < ' ') {
1575
- warningAt("Unexpected control character in regular expression.", line, from + l);
1647
+ warningAt(
1648
+ "Unexpected control character in regular expression.", line, from + l);
1576
1649
  } else if (c === '<') {
1577
- warningAt("Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1650
+ warningAt(
1651
+ "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1578
1652
  }
1579
1653
  l += 1;
1580
1654
  q = true;
1581
1655
  break;
1582
1656
  case '/':
1583
- warningAt("Unescaped '{a}'.", line, from + l - 1, '/');
1657
+ warningAt("Unescaped '{a}'.",
1658
+ line, from + l - 1, '/');
1584
1659
  q = true;
1585
1660
  break;
1586
1661
  case '<':
1587
1662
  if (xmode === 'script') {
1588
1663
  c = s.charAt(l);
1589
1664
  if (c === '!' || c === '/') {
1590
- warningAt("HTML confusion in regular expression '<{a}'.", line, from + l, c);
1665
+ warningAt(
1666
+ "HTML confusion in regular expression '<{a}'.", line, from + l, c);
1591
1667
  }
1592
1668
  }
1593
1669
  q = true;
@@ -1599,7 +1675,8 @@ var JSLINT = (function () {
1599
1675
  break;
1600
1676
  case '.':
1601
1677
  if (option.regexp) {
1602
- warningAt("Insecure '{a}'.", line, from + l, c);
1678
+ warningAt("Insecure '{a}'.", line,
1679
+ from + l, c);
1603
1680
  }
1604
1681
  break;
1605
1682
  case ']':
@@ -1608,13 +1685,15 @@ var JSLINT = (function () {
1608
1685
  case '}':
1609
1686
  case '+':
1610
1687
  case '*':
1611
- warningAt("Unescaped '{a}'.", line, from + l, c);
1688
+ warningAt("Unescaped '{a}'.", line,
1689
+ from + l, c);
1612
1690
  break;
1613
1691
  case '<':
1614
1692
  if (xmode === 'script') {
1615
1693
  c = s.charAt(l);
1616
1694
  if (c === '!' || c === '/') {
1617
- warningAt("HTML confusion in regular expression '<{a}'.", line, from + l, c);
1695
+ warningAt(
1696
+ "HTML confusion in regular expression '<{a}'.", line, from + l, c);
1618
1697
  }
1619
1698
  }
1620
1699
  }
@@ -1632,7 +1711,8 @@ var JSLINT = (function () {
1632
1711
  l += 1;
1633
1712
  c = s.charAt(l);
1634
1713
  if (c < '0' || c > '9') {
1635
- warningAt("Expected a number and instead saw '{a}'.", line, from + l, c);
1714
+ warningAt(
1715
+ "Expected a number and instead saw '{a}'.", line, from + l, c);
1636
1716
  }
1637
1717
  l += 1;
1638
1718
  low = +c;
@@ -1663,7 +1743,8 @@ var JSLINT = (function () {
1663
1743
  }
1664
1744
  }
1665
1745
  if (s.charAt(l) !== '}') {
1666
- warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
1746
+ warningAt(
1747
+ "Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
1667
1748
  } else {
1668
1749
  l += 1;
1669
1750
  }
@@ -1671,7 +1752,8 @@ var JSLINT = (function () {
1671
1752
  l += 1;
1672
1753
  }
1673
1754
  if (low > high) {
1674
- warningAt("'{a}' should not be greater than '{b}'.", line, from + l, low, high);
1755
+ warningAt(
1756
+ "'{a}' should not be greater than '{b}'.", line, from + l, low, high);
1675
1757
  }
1676
1758
  }
1677
1759
  }
@@ -1765,7 +1847,8 @@ var JSLINT = (function () {
1765
1847
 
1766
1848
  function addlabel(t, type) {
1767
1849
 
1768
- if (option.safe && funct['(global)'] && typeof predefined[t] !== 'boolean') {
1850
+ if (option.safe && funct['(global)'] &&
1851
+ typeof predefined[t] !== 'boolean') {
1769
1852
  warning('ADsafe global: ' + t + '.', token);
1770
1853
  } else if (t === 'hasOwnProperty') {
1771
1854
  warning("'hasOwnProperty' is a really bad name.");
@@ -1941,7 +2024,8 @@ loop: for (;;) {
1941
2024
  if (nexttoken.id === '(end)') {
1942
2025
  warning("Unmatched '{a}'.", t, t.id);
1943
2026
  } else {
1944
- warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
2027
+ warning(
2028
+ "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
1945
2029
  nexttoken, id, t.id, t.line, nexttoken.value);
1946
2030
  }
1947
2031
  } else if (nexttoken.type !== '(identifier)' ||
@@ -2081,7 +2165,8 @@ loop: for (;;) {
2081
2165
  if (option.white && nexttoken.id !== '(end)') {
2082
2166
  i = indent + (bias || 0);
2083
2167
  if (nexttoken.from !== i) {
2084
- warning("Expected '{a}' to have an indentation at {b} instead at {c}.",
2168
+ warning(
2169
+ "Expected '{a}' to have an indentation at {b} instead at {c}.",
2085
2170
  nexttoken, nexttoken.value, i, nexttoken.from);
2086
2171
  }
2087
2172
  }
@@ -2190,7 +2275,8 @@ loop: for (;;) {
2190
2275
 
2191
2276
  function reservevar(s, v) {
2192
2277
  return reserve(s, function () {
2193
- if (this.id === 'this' || this.id === 'arguments') {
2278
+ if (this.id === 'this' || this.id === 'arguments' ||
2279
+ this.id === 'eval') {
2194
2280
  if (strict_mode && funct['(global)']) {
2195
2281
  warning("Strict violation.", this);
2196
2282
  } else if (option.safe) {
@@ -2345,7 +2431,8 @@ loop: for (;;) {
2345
2431
  x.led = function (left) {
2346
2432
  if (option.plusplus) {
2347
2433
  warning("Unexpected use of '{a}'.", this, this.id);
2348
- } else if ((!left.identifier || left.reserved) && left.id !== '.' && left.id !== '[') {
2434
+ } else if ((!left.identifier || left.reserved) &&
2435
+ left.id !== '.' && left.id !== '[') {
2349
2436
  warning("Bad operand.", this);
2350
2437
  }
2351
2438
  this.left = left;
@@ -2356,12 +2443,14 @@ loop: for (;;) {
2356
2443
 
2357
2444
 
2358
2445
  function optionalidentifier() {
2359
- if (nexttoken.reserved) {
2360
- warning("Expected an identifier and instead saw '{a}' (a reserved word).",
2361
- nexttoken, nexttoken.id);
2362
- }
2363
2446
  if (nexttoken.identifier) {
2364
2447
  advance();
2448
+ if (option.safe && banned[token.value]) {
2449
+ warning("ADsafe violation: '{a}'.", token, token.value);
2450
+ } else if (token.reserved && !option.es5) {
2451
+ warning("Expected an identifier and instead saw '{a}' (a reserved word).",
2452
+ token, token.id);
2453
+ }
2365
2454
  return token.value;
2366
2455
  }
2367
2456
  }
@@ -2439,9 +2528,6 @@ loop: for (;;) {
2439
2528
  if (!noindent) {
2440
2529
  indentation();
2441
2530
  }
2442
- if (nexttoken.id === 'new' && !option.newstat) {
2443
- warning("'new' should not be used as a statement.");
2444
- }
2445
2531
  r = parse(0, true);
2446
2532
 
2447
2533
  // Look for the final semicolon.
@@ -2451,6 +2537,8 @@ loop: for (;;) {
2451
2537
  warning(
2452
2538
  "Expected an assignment or function call and instead saw an expression.",
2453
2539
  token);
2540
+ } else if (r.id === '(' && r.left.id === 'new' && !option.newstat) {
2541
+ warning("Do not use 'new' for side effects.");
2454
2542
  }
2455
2543
  if (nexttoken.id !== ';') {
2456
2544
  if (!(nexttoken.id == '}' && option.lastsemic)) {
@@ -2656,9 +2744,10 @@ loop: for (;;) {
2656
2744
  }
2657
2745
 
2658
2746
  function cssColor() {
2659
- var i, number;
2747
+ var i, number, value;
2660
2748
  if (nexttoken.identifier) {
2661
- if (nexttoken.value === 'rgb') {
2749
+ value = nexttoken.value;
2750
+ if (value === 'rgb' || value === 'rgba') {
2662
2751
  advance();
2663
2752
  advance('(');
2664
2753
  for (i = 0; i < 3; i += 1) {
@@ -2686,6 +2775,19 @@ loop: for (;;) {
2686
2775
  }
2687
2776
  }
2688
2777
  }
2778
+ if (value === 'rgba') {
2779
+ advance(',');
2780
+ number = +nexttoken.value;
2781
+ if (nexttoken.type !== '(number)' || number < 0 || number > 1) {
2782
+ warning("Expected a number between 0 and 1 and instead saw '{a}'",
2783
+ nexttoken, number);
2784
+ }
2785
+ advance();
2786
+ if (nexttoken.id === '%') {
2787
+ warning("Unexpected '%'.");
2788
+ advance('%');
2789
+ }
2790
+ }
2689
2791
  advance(')');
2690
2792
  return true;
2691
2793
  } else if (cssColorData[nexttoken.value] === true) {
@@ -3479,7 +3581,9 @@ loop: for (;;) {
3479
3581
  if (ids[u] === true) {
3480
3582
  warning("Duplicate id='{a}'.", nexttoken, v);
3481
3583
  }
3482
- if (option.adsafe) {
3584
+ if (!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)) {
3585
+ warning("Bad id: '{a}'.", nexttoken, v);
3586
+ } else if (option.adsafe) {
3483
3587
  if (adsafe_id) {
3484
3588
  if (v.slice(0, adsafe_id.length) !== adsafe_id) {
3485
3589
  warning("ADsafe violation: An id must have a '{a}' prefix",
@@ -3968,6 +4072,9 @@ loop: for (;;) {
3968
4072
  return this;
3969
4073
  });
3970
4074
 
4075
+
4076
+ // ECMAScript parser
4077
+
3971
4078
  delim('(endline)');
3972
4079
  delim('(begin)');
3973
4080
  delim('(end)').reach = true;
@@ -4420,7 +4527,7 @@ loop: for (;;) {
4420
4527
  this.first.push(parse(10));
4421
4528
  if (nexttoken.id === ',') {
4422
4529
  comma();
4423
- if (nexttoken.id === ']') {
4530
+ if (nexttoken.id === ']' && !option.es5) {
4424
4531
  warning("Extra comma.", token);
4425
4532
  break;
4426
4533
  }
@@ -4435,10 +4542,77 @@ loop: for (;;) {
4435
4542
  advance(']', this);
4436
4543
  return this;
4437
4544
  }, 160);
4545
+
4546
+
4547
+ function property_name() {
4548
+ var i = optionalidentifier(true);
4549
+ if (!i) {
4550
+ if (nexttoken.id === '(string)') {
4551
+ i = nexttoken.value;
4552
+ advance();
4553
+ } else if (nexttoken.id === '(number)') {
4554
+ i = nexttoken.value.toString();
4555
+ advance();
4556
+ }
4557
+ }
4558
+ return i;
4559
+ }
4560
+
4438
4561
 
4562
+ function functionparams() {
4563
+ var i, t = nexttoken, p = [];
4564
+ advance('(');
4565
+ nospace();
4566
+ if (nexttoken.id === ')') {
4567
+ advance(')');
4568
+ nospace(prevtoken, token);
4569
+ return;
4570
+ }
4571
+ for (;;) {
4572
+ i = identifier();
4573
+ p.push(i);
4574
+ addlabel(i, 'parameter');
4575
+ if (nexttoken.id === ',') {
4576
+ comma();
4577
+ } else {
4578
+ advance(')', t);
4579
+ nospace(prevtoken, token);
4580
+ return p;
4581
+ }
4582
+ }
4583
+ }
4584
+
4585
+
4586
+ function doFunction(i) {
4587
+ var f, s = scope;
4588
+ scope = Object.create(s);
4589
+ funct = {
4590
+ '(name)' : i || '"' + anonname + '"',
4591
+ '(line)' : nexttoken.line,
4592
+ '(context)' : funct,
4593
+ '(breakage)': 0,
4594
+ '(loopage)' : 0,
4595
+ '(scope)' : scope
4596
+ };
4597
+ f = funct;
4598
+ token.funct = funct;
4599
+ functions.push(funct);
4600
+ if (i) {
4601
+ addlabel(i, 'function');
4602
+ }
4603
+ funct['(params)'] = functionparams();
4604
+
4605
+ block(false);
4606
+ scope = s;
4607
+ funct['(last)'] = token.line;
4608
+ funct = funct['(context)'];
4609
+ return f;
4610
+ }
4611
+
4612
+
4439
4613
  (function (x) {
4440
4614
  x.nud = function () {
4441
- var b, i, s, seen = {};
4615
+ var b, f, i, j, p, seen = {}, t;
4442
4616
  b = token.line !== nexttoken.line;
4443
4617
  if (b) {
4444
4618
  indent += option.indent;
@@ -4453,33 +4627,59 @@ loop: for (;;) {
4453
4627
  if (b) {
4454
4628
  indentation();
4455
4629
  }
4456
- i = optionalidentifier(true);
4457
- if (!i) {
4458
- if (nexttoken.id === '(string)') {
4459
- i = nexttoken.value;
4460
- if (ix.test(i)) {
4461
- s = syntax[i];
4462
- }
4463
- advance();
4464
- } else if (nexttoken.id === '(number)') {
4465
- i = nexttoken.value.toString();
4466
- advance();
4467
- } else {
4468
- error("Expected '{a}' and instead saw '{b}'.",
4469
- nexttoken, '}', nexttoken.value);
4630
+ if (nexttoken.value === 'get' && peek().id !== ':') {
4631
+ advance('get');
4632
+ if (!option.es5) {
4633
+ error("get/set are ES5 features.");
4634
+ }
4635
+ i = property_name();
4636
+ if (!i) {
4637
+ error("Missing property name.");
4638
+ }
4639
+ t = nexttoken;
4640
+ adjacent(token, nexttoken);
4641
+ f = doFunction(i);
4642
+ if (funct['(loopage)']) {
4643
+ warning("Don't make functions within a loop.", t);
4644
+ }
4645
+ p = f['(params)'];
4646
+ if (p) {
4647
+ warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i);
4648
+ }
4649
+ adjacent(token, nexttoken);
4650
+ advance(',');
4651
+ indentation();
4652
+ advance('set');
4653
+ j = property_name();
4654
+ if (i !== j) {
4655
+ error("Expected {a} and instead saw {b}.", token, i, j);
4470
4656
  }
4657
+ t = nexttoken;
4658
+ adjacent(token, nexttoken);
4659
+ f = doFunction(i);
4660
+ p = f['(params)'];
4661
+ if (!p || p.length !== 1 || p[0] !== 'value') {
4662
+ warning("Expected (value) in set {a} function.", t, i);
4663
+ }
4664
+ } else {
4665
+ i = property_name();
4666
+ if (typeof i !== 'string') {
4667
+ break;
4668
+ }
4669
+ advance(':');
4670
+ nonadjacent(token, nexttoken);
4671
+ parse(10);
4471
4672
  }
4472
4673
  if (seen[i] === true) {
4473
4674
  warning("Duplicate member '{a}'.", nexttoken, i);
4474
4675
  }
4475
4676
  seen[i] = true;
4476
4677
  countMember(i);
4477
- advance(':');
4478
- nonadjacent(token, nexttoken);
4479
- parse(10);
4480
4678
  if (nexttoken.id === ',') {
4481
4679
  comma();
4482
- if (nexttoken.id === ',' || nexttoken.id === '}') {
4680
+ if (nexttoken.id === ',') {
4681
+ warning("Extra comma.", token);
4682
+ } else if (nexttoken.id === '}' && !option.es5) {
4483
4683
  warning("Extra comma.", token);
4484
4684
  }
4485
4685
  } else {
@@ -4528,6 +4728,9 @@ loop: for (;;) {
4528
4728
  nonadjacent(token, nexttoken);
4529
4729
  advance('=');
4530
4730
  nonadjacent(token, nexttoken);
4731
+ if (nexttoken.id === 'undefined') {
4732
+ warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
4733
+ }
4531
4734
  if (peek(0).id === '=' && nexttoken.identifier) {
4532
4735
  error("Variable {a} was not declared correctly.",
4533
4736
  nexttoken, nexttoken.value);
@@ -4547,54 +4750,6 @@ loop: for (;;) {
4547
4750
  stmt('var', varstatement).exps = true;
4548
4751
 
4549
4752
 
4550
- function functionparams() {
4551
- var i, t = nexttoken, p = [];
4552
- advance('(');
4553
- nospace();
4554
- if (nexttoken.id === ')') {
4555
- advance(')');
4556
- nospace(prevtoken, token);
4557
- return;
4558
- }
4559
- for (;;) {
4560
- i = identifier();
4561
- p.push(i);
4562
- addlabel(i, 'parameter');
4563
- if (nexttoken.id === ',') {
4564
- comma();
4565
- } else {
4566
- advance(')', t);
4567
- nospace(prevtoken, token);
4568
- return p;
4569
- }
4570
- }
4571
- }
4572
-
4573
- function doFunction(i) {
4574
- var s = scope;
4575
- scope = Object.create(s);
4576
- funct = {
4577
- '(name)' : i || '"' + anonname + '"',
4578
- '(line)' : nexttoken.line,
4579
- '(context)' : funct,
4580
- '(breakage)': 0,
4581
- '(loopage)' : 0,
4582
- '(scope)' : scope
4583
- };
4584
- token.funct = funct;
4585
- functions.push(funct);
4586
- if (i) {
4587
- addlabel(i, 'function');
4588
- }
4589
- funct['(params)'] = functionparams();
4590
-
4591
- block(false);
4592
- scope = s;
4593
- funct['(last)'] = token.line;
4594
- funct = funct['(context)'];
4595
- }
4596
-
4597
-
4598
4753
  blockstmt('function', function () {
4599
4754
  if (inblock) {
4600
4755
  warning(
@@ -4620,8 +4775,8 @@ loop: for (;;) {
4620
4775
  nonadjacent(token, nexttoken);
4621
4776
  }
4622
4777
  doFunction(i);
4623
- if (funct['(loopage)'] && nexttoken.id !== '(') {
4624
- warning("Be careful when making functions within a loop. Consider putting the function in a closure.");
4778
+ if (funct['(loopage)']) {
4779
+ warning("Don't make functions within a loop.");
4625
4780
  }
4626
4781
  return this;
4627
4782
  });
@@ -4957,6 +5112,8 @@ loop: for (;;) {
4957
5112
  this.first = nexttoken;
4958
5113
  advance();
4959
5114
  }
5115
+ } else if (!funct['(loopage)']) {
5116
+ warning("Unexpected '{a}'.", nexttoken, this.value);
4960
5117
  }
4961
5118
  reachable('continue');
4962
5119
  return this;
@@ -5007,6 +5164,9 @@ loop: for (;;) {
5007
5164
  reserve('public');
5008
5165
  reserve('static');
5009
5166
 
5167
+
5168
+ // Parse JSON
5169
+
5010
5170
  function jsonValue() {
5011
5171
 
5012
5172
  function jsonObject() {
@@ -5127,7 +5287,7 @@ loop: for (;;) {
5127
5287
  o.on = false;
5128
5288
  o.rhino = false;
5129
5289
  o.safe = true;
5130
- o.sidebar = false;
5290
+ o.windows = false;
5131
5291
  o.strict = true;
5132
5292
  o.sub = false;
5133
5293
  o.undef = true;
@@ -5262,6 +5422,7 @@ loop: for (;;) {
5262
5422
  return a;
5263
5423
  }
5264
5424
 
5425
+
5265
5426
  // Data summary.
5266
5427
 
5267
5428
  itself.data = function () {
@@ -5350,10 +5511,19 @@ loop: for (;;) {
5350
5511
 
5351
5512
  var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s;
5352
5513
 
5353
- function detail(h, s) {
5354
- if (s) {
5355
- o.push('<div><i>' + h + '</i> ' +
5356
- s.sort().join(', ') + '</div>');
5514
+ function detail(h, array) {
5515
+ var b, i, singularity;
5516
+ if (array) {
5517
+ o.push('<div><i>' + h + '</i> ');
5518
+ array = array.sort();
5519
+ for (i = 0; i < array.length; i += 1) {
5520
+ if (array[i] !== singularity) {
5521
+ singularity = array[i];
5522
+ o.push((b ? ', ' : '') + singularity);
5523
+ b = true;
5524
+ }
5525
+ }
5526
+ o.push('</div>');
5357
5527
  }
5358
5528
  }
5359
5529
 
@@ -5408,7 +5578,9 @@ loop: for (;;) {
5408
5578
  detail("URLs<br>", data.urls, '<br>');
5409
5579
  }
5410
5580
 
5411
- if (data.json && !err) {
5581
+ if (xmode === 'style') {
5582
+ o.push('<p>CSS.</p>');
5583
+ } else if (data.json && !err) {
5412
5584
  o.push('<p>JSON: good.</p>');
5413
5585
  } else if (data.globals) {
5414
5586
  o.push('<div><i>Global</i> ' +
@@ -5464,7 +5636,7 @@ loop: for (;;) {
5464
5636
  };
5465
5637
  itself.jslint = itself;
5466
5638
 
5467
- itself.edition = '2009-11-22';
5639
+ itself.edition = '2010-04-06';
5468
5640
 
5469
5641
  return itself;
5470
5642