jslint_on_rails 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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