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 +8 -0
- data/README.markdown +2 -0
- data/Rakefile +8 -0
- data/lib/jslint.rb +3 -3
- data/{config → lib/jslint/config}/jslint.yml +2 -1
- data/lib/jslint/lint.rb +19 -8
- data/lib/jslint/rails.rb +3 -1
- data/lib/jslint/tasks.rb +2 -1
- data/lib/jslint/utils.rb +18 -9
- data/{vendor → lib/jslint/vendor}/jslint.js +412 -240
- data/{vendor → lib/jslint/vendor}/rhino.jar +0 -0
- data/{vendor → lib/jslint/vendor}/test.jar +0 -0
- data/spec/lint_spec.rb +142 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/utils_spec.rb +148 -0
- metadata +21 -9
data/Gemfile
ADDED
data/README.markdown
CHANGED
@@ -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
|
|
data/Rakefile
ADDED
data/lib/jslint.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
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
|
-
|
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
|
|
data/lib/jslint/lint.rb
CHANGED
@@ -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}
|
6
|
-
RHINO_JAR_FILE = File.expand_path("#{PATH}
|
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}
|
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'
|
30
|
+
['paths', 'exclude_paths'].each { |field| @config.delete(field) }
|
28
31
|
end
|
29
32
|
|
30
33
|
def run
|
31
34
|
check_java
|
32
|
-
|
33
|
-
|
34
|
-
success =
|
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 =
|
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
|
data/lib/jslint/rails.rb
CHANGED
data/lib/jslint/tasks.rb
CHANGED
data/lib/jslint/utils.rb
CHANGED
@@ -2,7 +2,8 @@ require 'ftools'
|
|
2
2
|
|
3
3
|
module JSLint
|
4
4
|
|
5
|
-
|
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
|
-
|
52
|
+
xprint "Copying default config file to #{File.expand_path(JSLint.config_path)}... "
|
44
53
|
if File.exists?(JSLint.config_path)
|
45
|
-
|
46
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
68
|
+
xputs "OK."
|
60
69
|
else
|
61
|
-
|
70
|
+
xputs "File was modified, so it won't be deleted automatically."
|
62
71
|
end
|
63
72
|
else
|
64
|
-
|
73
|
+
xputs "OK (no config file found)."
|
65
74
|
end
|
66
75
|
end
|
67
76
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// jslint.js
|
2
|
-
//
|
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,
|
152
|
-
COM, Canvas, CustomAnimation, Date, Debug, E,
|
153
|
-
|
154
|
-
LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
|
155
|
-
|
156
|
-
POSITIVE_INFINITY, Point, RangeError, Rectangle,
|
157
|
-
|
158
|
-
Style, SyntaxError, System, Text, TextArea,
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
"background-
|
165
|
-
|
166
|
-
|
167
|
-
"border-bottom
|
168
|
-
"border-
|
169
|
-
"border-
|
170
|
-
"border-
|
171
|
-
"border-style", "border-
|
172
|
-
"border-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
"
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
"
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
"
|
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
|
-
|
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
|
-
|
714
|
-
|
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
|
1020
|
+
if (option.browser) {
|
986
1021
|
combine(predefined, browser);
|
987
1022
|
}
|
988
|
-
if (option.
|
989
|
-
combine(predefined,
|
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
|
-
|
1130
|
-
|
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
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
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.",
|
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.",
|
1526
|
+
errorAt("Unclosed regular expression.",
|
1527
|
+
line, from);
|
1472
1528
|
return;
|
1473
1529
|
case '/':
|
1474
1530
|
if (depth > 0) {
|
1475
|
-
warningAt("Unescaped '{a}'.",
|
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(
|
1555
|
+
warningAt(
|
1556
|
+
"Unexpected control character in regular expression.", line, from + l);
|
1494
1557
|
} else if (c === '<') {
|
1495
|
-
warningAt(
|
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(
|
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}'.",
|
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(
|
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}'.",
|
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,
|
1615
|
+
warningAt("Empty class.", line,
|
1616
|
+
from + l - 1);
|
1548
1617
|
q = true;
|
1549
1618
|
}
|
1550
|
-
|
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}'.",
|
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}'.",
|
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}'.",
|
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(
|
1647
|
+
warningAt(
|
1648
|
+
"Unexpected control character in regular expression.", line, from + l);
|
1576
1649
|
} else if (c === '<') {
|
1577
|
-
warningAt(
|
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}'.",
|
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(
|
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,
|
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,
|
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(
|
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(
|
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(
|
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(
|
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)'] &&
|
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(
|
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(
|
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) &&
|
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
|
-
|
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 (
|
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,
|
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
|
-
|
4457
|
-
|
4458
|
-
if (
|
4459
|
-
|
4460
|
-
|
4461
|
-
|
4462
|
-
|
4463
|
-
|
4464
|
-
}
|
4465
|
-
|
4466
|
-
|
4467
|
-
|
4468
|
-
|
4469
|
-
|
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 === ','
|
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)']
|
4624
|
-
warning("
|
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.
|
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,
|
5354
|
-
|
5355
|
-
|
5356
|
-
|
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 (
|
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 = '
|
5639
|
+
itself.edition = '2010-04-06';
|
5468
5640
|
|
5469
5641
|
return itself;
|
5470
5642
|
|