jslint_on_rails 1.0.0 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +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
|
|