1 // (C)2002 Douglas Crockford
4 "use strict";JSLINT=function(){var adsafe_id
,adsafe_may
,adsafe_went
,anonname
,approved
,banned
={apply:true,'arguments':true,call:true,callee:true,caller:true,constructor:true,'eval':true,prototype:true,unwatch:true,valueOf:true,watch:true},boolOptions
={adsafe:true,bitwise:true,browser:true,cap:true,debug:true,eqeqeq:true,evil:true,forin:true,fragment:true,glovar:true,laxbreak:true,nomen:true,on:true,passfail:true,plusplus:true,regexp:true,rhino:true,undef:true,safe:true,sidebar:true,sub:true,white:true,widget:true},browser
={alert:true,blur:true,clearInterval:true,clearTimeout:true,close:true,closed:true,confirm:true,console:true,Debug:true,defaultStatus:true,document:true,event:true,focus:true,frames:true,getComputedStyle:true,history:true,Image:true,length:true,location:true,moveBy:true,moveTo:true,name:true,navigator:true,onblur:true,onerror:true,onfocus:true,onload:true,onresize:true,onunload:true,open:true,opener:true,opera:true,Option:true,parent:true,print:true,prompt:true,resizeBy:true,resizeTo:true,screen:true,scroll:true,scrollBy:true,scrollTo:true,self:true,setInterval:true,setTimeout:true,status:true,top:true,window:true,XMLHttpRequest:true},escapes
={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','/':'\\/','\\':'\\\\'},funct
,functions
,href
={background:true,content:true,data:true,dynsrc:true,href:true,lowsrc:true,src:true},global
,ids
,implied
,inblock
,indent
,jsonmode
,lines
,lookahead
,member
,membersOnly
,nexttoken
,noreach
,option
,predefined
,prereg
,prevtoken
,rhino
={defineClass:true,deserialize:true,gc:true,help:true,load:true,loadClass:true,print:true,quit:true,readFile:true,readUrl:true,runCommand:true,seal:true,serialize:true,spawn:true,sync:true,toint32:true,version:true},scope
,sidebar
={System:true},src
,stack
,standard
={Array:true,Boolean:true,Date:true,decodeURI:true,decodeURIComponent:true,encodeURI:true,encodeURIComponent:true,Error:true,'eval':true,EvalError:true,Function:true,isFinite:true,isNaN:true,JSON:true,Math:true,Number:true,Object:true,parseInt:true,parseFloat:true,RangeError:true,ReferenceError:true,RegExp:true,String:true,SyntaxError:true,TypeError:true,URIError:true},standard_member
={E:true,LN2:true,LN10:true,LOG2E:true,LOG10E:true,PI:true,SQRT1_2:true,SQRT2:true,MAX_VALUE:true,MIN_VALUE:true,NEGATIVE_INFINITY:true,POSITIVE_INFINITY:true},syntax
={},tab
,token
,urls
,warnings
,widget
={alert:true,appleScript:true,animator:true,appleScript:true,beep:true,bytesToUIString:true,Canvas:true,chooseColor:true,chooseFile:true,chooseFolder:true,closeWidget:true,COM:true,convertPathToHFS:true,convertPathToPlatform:true,CustomAnimation:true,escape:true,FadeAnimation:true,filesystem:true,focusWidget:true,form:true,FormField:true,Frame:true,HotKey:true,Image:true,include:true,isApplicationRunning:true,iTunes:true,konfabulatorVersion:true,log:true,MenuItem:true,MoveAnimation:true,openURL:true,play:true,Point:true,popupMenu:true,preferenceGroups:true,preferences:true,print:true,prompt:true,random:true,reloadWidget:true,resolvePath:true,resumeUpdates:true,RotateAnimation:true,runCommand:true,runCommandInBg:true,saveAs:true,savePreferences:true,screen:true,ScrollBar:true,showWidgetPreferences:true,sleep:true,speak:true,suppressUpdates:true,system:true,tellWidget:true,Text:true,TextArea:true,Timer:true,unescape:true,updateNow:true,URL:true,widget:true,Window:true,XMLDOM:true,XMLHttpRequest:true,yahooCheckLogin:true,yahooLogin:true,yahooLogout:true},xmode
,xtype
,ax
=/@cc
|<\/?script|\]\]|<!|</i,cx
=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,tx
=/^\s*([(){}\[.,:;'"~]|\](\]>)?|\?>?|==?=?|\/(\*(global|extern|jslint|member|members)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%[=>]?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=%\?]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,lx
=/\*\/|\/\*/,ix
=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,jx
=/^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,ux
=/&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i;function F(){}
5 if(typeof Object
.create
!=='function'){Object
.create=function(o
){F
.prototype=o
;return new F();};}
6 Object
.prototype.union=function(o
){var n
;for(n
in o
){if(o
.hasOwnProperty(n
)){this[n
]=o
[n
];}}};String
.prototype.entityify=function(){return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g
,'>');};String
.prototype.isAlpha=function(){return(this>='a'&&this<='z\uffff')||(this>='A'&&this<='Z\uffff');};String
.prototype.isDigit=function(){return(this>='0'&&this<='9');};String
.prototype.supplant=function(o
){return this.replace(/\{([^{}]*)\}/g,function(a
,b
){var r
=o
[b
];return typeof r
==='string'||typeof r
==='number'?r:a
;});};String
.prototype.name=function(){if(ix
.test(this)){return this;}
7 if(/[&<"\/\\\x00-\x1f]/.test(this)){return'"'+this.replace(/[&<"\/\\\x00-\x1f]/g,function(a
){var c
=escapes
[a
];if(c
){return c
;}
8 c
=a
.charCodeAt();return'\\u00'+
9 Math
.floor(c
/16).toString(16)+
10 (c
%16).toString(16);})+'"';}
11 return'"'+this+'"';};function assume(){if(!option
.safe
){if(option
.rhino
){predefined
.union(rhino
);}
12 if(option
.browser
||option
.sidebar
){predefined
.union(browser
);}
13 if(option
.sidebar
){predefined
.union(sidebar
);}
14 if(option
.widget
){predefined
.union(widget
);}}}
15 function quit(m
,l
,ch
){throw{name:'JSLintError',line:l
,character:ch
,message:m
+" ("+Math
.floor((l
/lines
.length
)*100)+"% scanned)."};}
16 function warning(m
,t
,a
,b
,c
,d
){var ch
,l
,w
;t
=t
||nexttoken
;if(t
.id
==='(end)'){t
=token
;}
17 l
=t
.line
||0;ch
=t
.from||0;w
={id:'(error)',raw:m
,evidence:lines
[l
]||'',line:l
,character:ch
,a:a
,b:b
,c:c
,d:d
};w
.reason
=m
.supplant(w
);JSLINT
.errors
.push(w
);if(option
.passfail
){quit('Stopping. ',l
,ch
);}
18 warnings
+=1;if(warnings
===50){quit("Too many errors.",l
,ch
);}
20 function warningAt(m
,l
,ch
,a
,b
,c
,d
){return warning(m
,{line:l
,from:ch
},a
,b
,c
,d
);}
21 function error(m
,t
,a
,b
,c
,d
){var w
=warning(m
,t
,a
,b
,c
,d
);quit("Stopping, unable to continue.",w
.line
,w
.character
);}
22 function errorAt(m
,l
,ch
,a
,b
,c
,d
){return error(m
,{line:l
,from:ch
},a
,b
,c
,d
);}
23 var lex=function(){var character
,from,line
,s
;function nextLine(){var at
;line
+=1;if(line
>=lines
.length
){return false;}
24 character
=0;s
=lines
[line
].replace(/\t/g,tab
);at
=s
.search(cx
);if(at
>=0){warningAt("Unsafe character.",line
,at
);}
26 function it(type
,value
){var i
,t
;if(type
==='(punctuator)'||(type
==='(identifier)'&&syntax
.hasOwnProperty(value
))){t
=syntax
[value
];if(!t
.id
){t
=syntax
[type
];}}else{t
=syntax
[type
];}
27 t
=Object
.create(t
);if(type
==='(string)'){if(jx
.test(value
)){warningAt("Script URL.",line
,from);}}else if(type
==='(identifier)'){if(option
.nomen
&&(value
.charAt(0)==='_'||value
.charAt(value
.length
-1)==='_')){warningAt("Unexpected '_' in '{a}'.",line
,from,value
);}}
28 t
.value
=value
;t
.line
=line
;t
.character
=character
;t
.from=from;i
=t
.id
;if(i
!=='(endline)'){prereg
=i
&&(('(,=:[!&|?{};'.indexOf(i
.charAt(i
.length
-1))>=0)||i
==='return');}
30 return{init:function(source
){if(typeof source
==='string'){lines
=source
.replace(/\r\n/g,'\n').replace(/\r/g,'\n').split('\n');}else{lines
=source
;}
31 line
=-1;nextLine();from=0;},token:function(){var b
,c
,captures
,d
,depth
,high
,i
,l
,low
,q
,t
;function match(x
){var r
=x
.exec(s
),r1
;if(r
){l
=r
[0].length
;r1
=r
[1];c
=r1
.charAt(0);s
=s
.substr(l
);character
+=l
;from=character
-r1
.length
;return r1
;}}
32 function string(x
){var c
,j
,r
='';if(jsonmode
&&x
!=='"'){warningAt("Strings must use doublequote.",line
,character
);}
33 if(xmode
===x
||xmode
==='string'){if(xmode
&&xmode
!=='CDATA'&&ax
.test(x
)){warning("ADsafe string violation.",line
,character
);}
34 return it('(punctuator)',x
);}
35 function esc(n
){var i
=parseInt(s
.substr(j
+1,n
),16);j
+=n
;if(i
>=32&&i
<=127&&i
!==34&&i
!==92&&i
!==39){warningAt("Unnecessary escapement.",line
,character
);}
36 character
+=n
;c
=String
.fromCharCode(i
);}
37 j
=0;for(;;){while(j
>=s
.length
){j
=0;if(xmode
!=='xml'||!nextLine()){errorAt("Unclosed string.",line
,from);}}
38 c
=s
.charAt(j
);if(c
===x
){character
+=1;s
=s
.substr(j
+1);return it('(string)',r
,x
);}
39 if(c
<' '){if(c
==='\n'||c
==='\r'){break;}
40 warningAt("Control character in string: {a}.",line
,character
+j
,s
.slice(0,j
));}else if(c
==='<'){if(option
.safe
&&xmode
==='xml'){warningAt("ADsafe string violation.",line
,character
+j
);}else if(s
.charAt(j
+1)==='/'&&((xmode
&&xmode
!=='CDATA')||option
.safe
)){warningAt("Expected '<\\/' and instead saw '</'.",line
,character
);}else if(s
.charAt(j
+1)==='!'&&((xmode
&&xmode
!=='CDATA')||option
.safe
)){warningAt("Unexpected '<!' in a string.",line
,character
);}}else if(c
==='\\'){if(option
.safe
&&xmode
==='xml'){warningAt("ADsafe string violation.",line
,character
+j
);}
41 j
+=1;character
+=1;c
=s
.charAt(j
);switch(c
){case'\\':case'\'':case'"':case'/':break;case'b':c
='\b';break;case'f':c
='\f';break;case'n':c
='\n';break;case'r':c
='\r';break;case't':c
='\t';break;case'u':esc(4);break;case'v':c
='\v';break;case'x':if(jsonmode
){warningAt("Avoid \\x-.",line
,character
);}
42 esc(2);break;default:warningAt("Bad escapement.",line
,character
);}}
43 r
+=c
;character
+=1;j
+=1;}}
44 for(;;){if(!s
){return it(nextLine()?'(endline)':'(end)','');}
45 t
=match(tx
);if(!t
){t
='';c
='';while(s
&&s
<'!'){s
=s
.substr(1);}
46 if(s
){errorAt("Unexpected '{a}'.",line
,character
,s
.substr(0,1));}}
47 if(c
.isAlpha()||c
==='_'||c
==='$'){return it('(identifier)',t
);}
48 if(c
.isDigit()){if(!isFinite(Number(t
))){warningAt("Bad number '{a}'.",line
,character
,t
);}
49 if(s
.substr(0,1).isAlpha()){warningAt("Missing space after '{a}'.",line
,character
,t
);}
50 if(c
==='0'){d
=t
.substr(1,1);if(d
.isDigit()){if(token
.id
!=='.'){warningAt("Don't use extra leading zeros '{a}'.",line
,character
,t
);}}else if(jsonmode
&&(d
==='x'||d
==='X')){warningAt("Avoid 0x-. '{a}'.",line
,character
,t
);}}
51 if(t
.substr(t
.length
-1)==='.'){warningAt("A trailing decimal point can be confused with a dot '{a}'.",line
,character
,t
);}
52 return it('(number)',t
);}
53 switch(t
){case'"':case"'":return string(t
);case'//':if(src
||(xmode
&&!(xmode
==='script'||xmode
==='CDATA'))){warningAt("Unexpected comment.",line
,character
);}else if(xmode
==='script'&&/\<\/script\>/i.test(s
)){warningAt("Unexpected <\/script> in comment.",line
,character
);}else if((option
.safe
||xmode
==='script')&&ax
.test(s
)){warningAt("ADsafe comment violation.",line
,character
);}
54 s
='';token
.comment
=true;break;case'/*':if(src
||(xmode
&&!(xmode
==='script'||xmode
==='CDATA'))){warningAt("Unexpected comment.",line
,character
);}
55 if(option
.safe
&&ax
.test(s
)){warningAt("ADsafe comment violation.",line
,character
);}
56 for(;;){i
=s
.search(lx
);if(i
>=0){break;}
57 if(!nextLine()){errorAt("Unclosed comment.",line
,character
);}else{if(option
.safe
&&ax
.test(s
)){warningAt("ADsafe comment violation.",line
,character
);}}}
58 character
+=i
+2;if(s
.substr(i
,1)==='/'){errorAt("Nested comment.",line
,character
);}
59 s
=s
.substr(i
+2);token
.comment
=true;break;case'/*global':case'/*extern':case'/*members':case'/*member':case'/*jslint':case'*/':return{value:t
,type:'special',line:line
,character:character
,from:from};case'':break;case'/':if(prereg
){depth
=0;captures
=0;l
=0;for(;;){b
=true;c
=s
.charAt(l
);l
+=1;switch(c
){case'':errorAt("Unclosed regular expression.",line
,from);return;case'/':if(depth
>0){warningAt("Unescaped '{a}'.",line
,from+l
,'/');}
60 c
=s
.substr(0,l
-1);q
={g:true,i:true,m:true};while(q
[s
.charAt(l
)]===true){q
[s
.charAt(l
)]=false;l
+=1;}
61 character
+=l
;s
=s
.substr(l
);return it('(regex)',c
);case'\\':c
=s
.charAt(0);if(c
<' '){warningAt("Unexpected control character in regular expression.",line
,from+l
);}else if(c
==='<'){warningAt("Unexpected escaped character '{a}' in regular expression.",line
,from+l
,c
);}
62 l
+=1;break;case'(':depth
+=1;b
=false;if(s
.charAt(l
)==='?'){l
+=1;switch(s
.charAt(l
)){case':':case'=':case'!':l
+=1;break;default:warningAt("Expected '{a}' and instead saw '{b}'.",line
,from+l
,':',s
.charAt(l
));}}else{captures
+=1;}
63 break;case')':if(depth
===0){warningAt("Unescaped '{a}'.",line
,from+l
,')');}else{depth
-=1;}
64 break;case' ':q
=1;while(s
.charAt(l
)===' '){l
+=1;q
+=1;}
65 if(q
>1){warningAt("Spaces are hard to count. Use {{a}}.",line
,from+l
,q
);}
66 break;case'[':if(s
.charAt(l
)==='^'){l
+=1;}
67 q
=false;klass:do{c
=s
.charAt(l
);l
+=1;switch(c
){case'[':case'^':warningAt("Unescaped '{a}'.",line
,from+l
,c
);q
=true;break;case'-':if(q
){q
=false;}else{warningAt("Unescaped '{a}'.",line
,from+l
,'-');q
=true;}
68 break;case']':if(!q
){warningAt("Unescaped '{a}'.",line
,from+l
-1,'-');}
69 break klass
;case'\\':c
=s
.charAt(0);if(c
<' '){warningAt("Unexpected control character in regular expression.",line
,from+l
);}else if(c
==='<'){warningAt("Unexpected escaped character '{a}' in regular expression.",line
,from+l
,c
);}
70 l
+=1;q
=true;break;case'/':warningAt("Unescaped '{a}'.",line
,from+l
-1,'/');q
=true;break;case'<':if(xmode
==='script'){c
=s
.charAt(l
);if(c
==='!'||c
==='/'){warningAt("HTML confusion in regular expression '<{a}'.",line
,from+l
,c
);}}
71 q
=true;default:q
=true;}}while(c
);break;case'.':if(option
.regexp
){warningAt("Unexpected '{a}'.",line
,from+l
,c
);}
72 break;case']':case'?':case'{':case'}':case'+':case'*':warningAt("Unescaped '{a}'.",line
,from+l
,c
);break;case'<':if(xmode
==='script'){c
=s
.charAt(l
);if(c
==='!'||c
==='/'){warningAt("HTML confusion in regular expression '<{a}'.",line
,from+l
,c
);}}}
73 if(b
){switch(s
.charAt(l
)){case'?':case'+':case'*':l
+=1;if(s
.charAt(l
)==='?'){l
+=1;}
74 break;case'{':l
+=1;c
=s
.charAt(l
);if(c
<'0'||c
>'9'){warningAt("Expected a number and instead saw '{a}'.",line
,from+l
,c
);}
75 l
+=1;low
=+c
;for(;;){c
=s
.charAt(l
);if(c
<'0'||c
>'9'){break;}
76 l
+=1;low
=+c
+(low
*10);}
77 high
=low
;if(c
===','){l
+=1;high
=Infinity
;c
=s
.charAt(l
);if(c
>='0'&&c
<='9'){l
+=1;high
=+c
;for(;;){c
=s
.charAt(l
);if(c
<'0'||c
>'9'){break;}
78 l
+=1;high
=+c
+(high
*10);}}}
79 if(s
.charAt(l
)!=='}'){warningAt("Expected '{a}' and instead saw '{b}'.",line
,from+l
,'}',c
);}else{l
+=1;}
80 if(s
.charAt(l
)==='?'){l
+=1;}
81 if(low
>high
){warningAt("'{a}' should not be greater than '{b}'.",line
,from+l
,low
,high
);}}}}
82 c
=s
.substr(0,l
-1);character
+=l
;s
=s
.substr(l
);return it('(regex)',c
);}
83 return it('(punctuator)',t
);default:return it('(punctuator)',t
);}}},skip:function(p
){var i
,t
=p
;if(nexttoken
.id
){if(!t
){t
='';if(nexttoken
.id
.substr(0,1)==='<'){lookahead
.push(nexttoken
);return true;}}else if(nexttoken
.id
.indexOf(t
)>=0){return true;}}
84 token
=nexttoken
;nexttoken
=syntax
['(end)'];for(;;){i
=s
.indexOf(t
||'<');if(i
>=0){character
+=i
+t
.length
;s
=s
.substr(i
+t
.length
);return true;}
85 if(!nextLine()){break;}}
86 return false;}};}();function addlabel(t
,type
){if(t
==='hasOwnProperty'){error("'hasOwnProperty' is a really bad name.");}
87 if(option
.safe
&&funct
['(global)']){warning('ADsafe global: '+t
+'.',token
);}
88 if(funct
.hasOwnProperty(t
)){warning(funct
[t
]===true?"'{a}' was used before it was defined.":"'{a}' is already defined.",nexttoken
,t
);}
89 funct
[t
]=type
;if(type
==='label'){scope
[t
]=funct
;}else if(funct
['(global)']){global
[t
]=funct
;if(implied
.hasOwnProperty(t
)){warning("'{a}' was used before it was defined.",nexttoken
,t
);delete implied
[t
];}}else{funct
['(scope)'][t
]=funct
;}}
90 function doOption(){var b
,obj
,filter
,o
=nexttoken
.value
,t
,v
;switch(o
){case'*/':error("Unbegun comment.");break;case'/*global':case'/*extern':if(option
.safe
){warning("ADsafe restriction.");}
91 obj
=predefined
;break;case'/*members':case'/*member':o
='/*members';if(!membersOnly
){membersOnly
={};}
92 obj
=membersOnly
;break;case'/*jslint':if(option
.safe
){warning("ADsafe restriction.");}
93 obj
=option
;filter
=boolOptions
;}
94 for(;;){t
=lex
.token();if(t
.id
===','){t
=lex
.token();}
95 while(t
.id
==='(endline)'){t
=lex
.token();}
96 if(t
.type
==='special'&&t
.value
==='*/'){break;}
97 if(t
.type
!=='(string)'&&t
.type
!=='(identifier)'&&o
!=='/*members'){error("Bad option.",t
);}
98 if(filter
){if(filter
[t
.value
]!==true){error("Bad option.",t
);}
99 v
=lex
.token();if(v
.id
!==':'){error("Expected '{a}' and instead saw '{b}'.",t
,':',t
.value
);}
100 v
=lex
.token();if(v
.value
==='true'){b
=true;}else if(v
.value
==='false'){b
=false;}else{error("Expected '{a}' and instead saw '{b}'.",t
,'true',t
.value
);}}else{b
=true;}
102 if(filter
){assume();}}
103 function peek(p
){var i
=p
||0,j
=0,t
;while(j
<=i
){t
=lookahead
[j
];if(!t
){t
=lookahead
[j
]=lex
.token();}
106 var badbreak
={')':true,']':true,'++':true,'--':true};function advance(id
,t
){var l
;switch(token
.id
){case'(number)':if(nexttoken
.id
==='.'){warning("A dot following a number can be confused with a decimal point.",token
);}
107 break;case'-':if(nexttoken
.id
==='-'||nexttoken
.id
==='--'){warning("Confusing minusses.");}
108 break;case'+':if(nexttoken
.id
==='+'||nexttoken
.id
==='++'){warning("Confusing plusses.");}
110 if(token
.type
==='(string)'||token
.identifier
){anonname
=token
.value
;}
111 if(id
&&nexttoken
.id
!==id
){if(t
){if(nexttoken
.id
==='(end)'){warning("Unmatched '{a}'.",t
,t
.id
);}else{warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",nexttoken
,id
,t
.id
,t
.line
+1,nexttoken
.value
);}}else if(nexttoken
.type
!=='(identifier)'||nexttoken
.value
!==id
){warning("Expected '{a}' and instead saw '{b}'.",nexttoken
,id
,nexttoken
.value
);}}
112 prevtoken
=token
;token
=nexttoken
;for(;;){nexttoken
=lookahead
.shift()||lex
.token();if(nexttoken
.type
==='special'){doOption();}else{if(nexttoken
.id
==='<!['){if(option
.safe
){error("ADsafe violation.",nexttoken
);}
113 if(xtype
==='html'){error("Unexpected '{a}'.",nexttoken
,'<![');}
114 if(xmode
==='script'){nexttoken
=lex
.token();if(nexttoken
.value
!=='CDATA'){error("Missing '{a}'.",nexttoken
,'CDATA');}
115 nexttoken
=lex
.token();if(nexttoken
.id
!=='['){error("Missing '{a}'.",nexttoken
,'[');}
116 xmode
='CDATA';}else if(xmode
==='xml'){lex
.skip(']]>');}else{error("Unexpected '{a}'.",nexttoken
,'<![');}}else if(nexttoken
.id
===']]>'){if(xmode
==='CDATA'){xmode
='script';}else{error("Unexpected '{a}'.",nexttoken
,']]>');}}else if(nexttoken
.id
!=='(endline)'){break;}
117 if(xmode
==='"'||xmode
==="'"){error("Missing '{a}'.",token
,xmode
);}
118 l
=!xmode
&&!option
.laxbreak
&&(token
.type
==='(string)'||token
.type
==='(number)'||token
.type
==='(identifier)'||badbreak
[token
.id
]);}}
119 if(l
){switch(nexttoken
.id
){case'{':case'}':case']':case'.':break;case')':switch(token
.id
){case')':case'}':case']':break;default:warning("Line breaking error '{a}'.",token
,')');}
120 break;default:warning("Line breaking error '{a}'.",token
,token
.value
);}}
121 if(xtype
==='widget'&&xmode
==='script'&&nexttoken
.id
){l
=nexttoken
.id
.charAt(0);if(l
==='<'||l
==='&'){nexttoken
.nud
=nexttoken
.led
=null;nexttoken
.lbp
=0;nexttoken
.reach
=true;}}}
122 function parse(rbp
,initial
){var left
,o
;if(nexttoken
.id
==='(end)'){error("Unexpected early end of program.",token
);}
123 advance();if(option
.safe
&&predefined
[token
.value
]===true&&(nexttoken
.id
!=='('&&nexttoken
.id
!=='.')){warning('ADsafe violation.',token
);}
124 if(initial
){anonname
='anonymous';funct
['(verb)']=token
.value
;}
125 if(initial
===true&&token
.fud
){left
=token
.fud();}else{if(token
.nud
){o
=token
.exps
;left
=token
.nud();}else{if(nexttoken
.type
==='(number)'&&token
.id
==='.'){warning("A leading decimal point can be confused with a dot: '.{a}'.",token
,nexttoken
.value
);advance();return token
;}else{error("Expected an identifier and instead saw '{a}'.",token
,token
.id
);}}
126 while(rbp
<nexttoken
.lbp
){o
=nexttoken
.exps
;advance();if(token
.led
){left
=token
.led(left
);}else{error("Expected an operator and instead saw '{a}'.",token
,token
.id
);}}
127 if(initial
&&!o
){warning("Expected an assignment or function call and instead saw an expression.",token
);}}
128 if(!option
.evil
&&left
&&left
.value
==='eval'){warning("eval is evil.",left
);}
130 function adjacent(left
,right
){left
=left
||token
;right
=right
||nexttoken
;if(option
.white
){if(left
.character
!==right
.from&&left
.line
===right
.line
){warning("Unexpected space after '{a}'.",nexttoken
,left
.value
);}}}
131 function nospace(left
,right
){left
=left
||token
;right
=right
||nexttoken
;if(option
.white
&&!left
.comment
){if(left
.line
===right
.line
){adjacent(left
,right
);}}}
132 function nonadjacent(left
,right
){left
=left
||token
;right
=right
||nexttoken
;if(option
.white
){if(left
.character
===right
.from){warning("Missing space after '{a}'.",nexttoken
,left
.value
);}}}
133 function indentation(bias
){var i
;if(option
.white
&&nexttoken
.id
!=='(end)'){i
=indent
+(bias
||0);if(nexttoken
.from!==i
){warning("Expected '{a}' to have an indentation of {b} instead of {c}.",nexttoken
,nexttoken
.value
,i
,nexttoken
.from);}}}
134 function nolinebreak(t
){if(t
.line
!==nexttoken
.line
){warning("Line breaking error '{a}'.",t
,t
.id
);}}
135 function symbol(s
,p
){var x
=syntax
[s
];if(!x
||typeof x
!=='object'){syntax
[s
]=x
={id:s
,lbp:p
,value:s
};}
137 function delim(s
){return symbol(s
,0);}
138 function stmt(s
,f
){var x
=delim(s
);x
.identifier
=x
.reserved
=true;x
.fud
=f
;return x
;}
139 function blockstmt(s
,f
){var x
=stmt(s
,f
);x
.block
=true;return x
;}
140 function reserveName(x
){var c
=x
.id
.charAt(0);if((c
>='a'&&c
<='z')||(c
>='A'&&c
<='Z')){x
.identifier
=x
.reserved
=true;}
142 function prefix(s
,f
){var x
=symbol(s
,150);reserveName(x
);x
.nud
=(typeof f
==='function')?f:function(){if(option
.plusplus
&&(this.id
==='++'||this.id
==='--')){warning("Unexpected use of '{a}'.",this,this.id
);}
143 parse(150);return this;};return x
;}
144 function type(s
,f
){var x
=delim(s
);x
.type
=s
;x
.nud
=f
;return x
;}
145 function reserve(s
,f
){var x
=type(s
,f
);x
.identifier
=x
.reserved
=true;return x
;}
146 function reservevar(s
){return reserve(s
,function(){if(this.id
==='this'){if(option
.safe
){warning("ADsafe violation.",this);}}
148 function infix(s
,f
,p
){var x
=symbol(s
,p
);reserveName(x
);x
.led
=(typeof f
==='function')?f:function(left
){nonadjacent(prevtoken
,token
);nonadjacent(token
,nexttoken
);this.left
=left
;this.right
=parse(p
);return this;};return x
;}
149 function relation(s
,f
){var x
=symbol(s
,100);x
.led=function(left
){nonadjacent(prevtoken
,token
);nonadjacent(token
,nexttoken
);var right
=parse(100);if((left
&&left
.id
==='NaN')||(right
&&right
.id
==='NaN')){warning("Use the isNaN function to compare with NaN.",this);}else if(f
){f
.apply(this,[left
,right
]);}
150 this.left
=left
;this.right
=right
;return this;};return x
;}
151 function isPoorRelation(node
){var n
=+node
.value
;return(node
.type
==='(number)'&&!n
)||(node
.type
==='(string)'&&!node
.value
)||node
.type
==='true'||node
.type
==='false'||node
.type
==='undefined'||node
.type
==='null';}
152 function assignop(s
,f
){symbol(s
,20).exps
=true;return infix(s
,function(left
){var l
;this.left
=left
;nonadjacent(prevtoken
,token
);nonadjacent(token
,nexttoken
);if(option
.safe
){l
=left
;do{if(predefined
[l
.value
]===true){warning('ADsafe violation.',l
);}
154 if(left
){if(left
.id
==='.'||left
.id
==='['){if(left
.left
.value
==='arguments'){warning('Bad assignment.',this);}
155 this.right
=parse(19);return this;}else if(left
.identifier
&&!left
.reserved
){this.right
=parse(19);return this;}
156 if(left
===syntax
['function']){warning("Expected an identifier in an assignment and instead saw a function invocation.",token
);}}
157 error("Bad assignment.",this);},20);}
158 function bitwise(s
,f
,p
){var x
=symbol(s
,p
);reserveName(x
);x
.led
=(typeof f
==='function')?f:function(left
){if(option
.bitwise
){warning("Unexpected use of '{a}'.",this,this.id
);}
159 nonadjacent(prevtoken
,token
);nonadjacent(token
,nexttoken
);this.left
=left
;this.right
=parse(p
);return this;};return x
;}
160 function bitwiseassignop(s
){symbol(s
,20).exps
=true;return infix(s
,function(left
){if(option
.bitwise
){warning("Unexpected use of '{a}'.",this,this.id
);}
161 nonadjacent(prevtoken
,token
);nonadjacent(token
,nexttoken
);if(left
){if(left
.id
==='.'||left
.id
==='['||(left
.identifier
&&!left
.reserved
)){parse(19);return left
;}
162 if(left
===syntax
['function']){warning("Expected an identifier in an assignment, and instead saw a function invocation.",token
);}}
163 error("Bad assignment.",this);},20);}
164 function suffix(s
,f
){var x
=symbol(s
,150);x
.led=function(left
){if(option
.plusplus
){warning("Unexpected use of '{a}'.",this,this.id
);}
165 this.left
=left
;return this;};return x
;}
166 function optionalidentifier(){if(nexttoken
.reserved
){warning("Expected an identifier and instead saw '{a}' (a reserved word).",nexttoken
,nexttoken
.id
);}
167 if(nexttoken
.identifier
){advance();return token
.value
;}}
168 function identifier(){var i
=optionalidentifier();if(i
){return i
;}
169 if(token
.id
==='function'&&nexttoken
.id
==='('){warning("Missing name in function statement.");}else{error("Expected an identifier and instead saw '{a}'.",nexttoken
,nexttoken
.value
);}}
170 function reachable(s
){var i
=0,t
;if(nexttoken
.id
!==';'||noreach
){return;}
171 for(;;){t
=peek(i
);if(t
.reach
){return;}
172 if(t
.id
!=='(endline)'){if(t
.id
==='function'){warning("Inner functions should be listed at the top of the outer function.",t
);break;}
173 warning("Unreachable '{a}' after '{b}'.",t
,t
.value
,s
);break;}
175 function statement(noindent
){var i
=indent
,r
,s
=scope
,t
=nexttoken
;if(t
.id
===';'){warning("Unnecessary semicolon.",t
);advance(';');return;}
176 if(t
.identifier
&&!t
.reserved
&&peek().id
===':'){advance();advance(':');scope
=Object
.create(s
);addlabel(t
.value
,'label');if(!nexttoken
.labelled
){warning("Label '{a}' on {b} statement.",nexttoken
,t
.value
,nexttoken
.value
);}
177 if(jx
.test(t
.value
+':')){warning("Label '{a}' looks like a javascript url.",t
,t
.value
);}
178 nexttoken
.label
=t
.value
;t
=nexttoken
;}
179 if(!noindent
){indentation();}
180 r
=parse(0,true);if(!t
.block
){if(nexttoken
.id
!==';'){warningAt("Missing semicolon.",token
.line
,token
.from+token
.value
.length
);}else{adjacent(token
,nexttoken
);advance(';');nonadjacent(token
,nexttoken
);}}
181 indent
=i
;scope
=s
;return r
;}
182 function statements(begin
){var a
=[];if(begin
){if(option
.safe
&&nexttoken
.type
!=='(string)'){warning('ADsafe violation: Missing "use strict" statement.',nexttoken
);}
183 if(nexttoken
.type
==='(string)'&&nexttoken
.value
.slice(0,10)==='use strict'){advance();advance(';');}}
184 if(option
.adsafe
){switch(begin
){case'script':if(!adsafe_may
){if(nexttoken
.value
!=='ADSAFE'||peek(0).id
!=='.'||(peek(1).value
!=='id'&&peek(1).value
!=='go')){error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.',nexttoken
);}}
185 if(nexttoken
.value
==='ADSAFE'&&peek(0).id
==='.'&&peek(1).value
==='id'){if(adsafe_may
){error('ADsafe violation.',nexttoken
);}
186 advance('ADSAFE');advance('.');advance('id');advance('(');if(nexttoken
.value
!==adsafe_id
){error('ADsafe violation: id does not match.',nexttoken
);}
187 advance('(string)');advance(')');advance(';');adsafe_may
=true;}
188 break;case'lib':if(nexttoken
.value
==='ADSAFE'){advance('ADSAFE');advance('.');advance('lib');advance('(');advance('(string)');advance(',');parse(0);advance(')');advance(';');return a
;}else{error("ADsafe lib violation.");}}}
189 while(!nexttoken
.reach
&&nexttoken
.id
!=='(end)'){if(nexttoken
.id
===';'){warning("Unnecessary semicolon.");advance(';');}else{a
.push(statement());}}
191 function block(f
){var a
,b
=inblock
,s
=scope
;inblock
=f
;if(f
){scope
=Object
.create(scope
);}
192 nonadjacent(token
,nexttoken
);var t
=nexttoken
;if(nexttoken
.id
==='{'){advance('{');if(nexttoken
.id
!=='}'||token
.line
!==nexttoken
.line
){indent
+=option
.indent
;if(!f
&&nexttoken
.from===indent
+option
.indent
){indent
+=option
.indent
;}
193 a
=statements();indent
-=option
.indent
;indentation();}
194 advance('}',t
);}else{warning("Expected '{a}' and instead saw '{b}'.",nexttoken
,'{',nexttoken
.value
);noreach
=true;a
=[statement()];noreach
=false;}
195 funct
['(verb)']=null;scope
=s
;inblock
=b
;return a
;}
196 function idValue(){return this;}
197 function countMember(m
){if(membersOnly
&&membersOnly
[m
]!==true){warning("Unexpected /*member '{a}'.",nexttoken
,m
);}
198 if(typeof member
[m
]==='number'){member
[m
]+=1;}else{member
[m
]=1;}}
199 function note_implied(token
){var name
=token
.value
,line
=token
.line
+1,a
=implied
[name
];if(!a
){a
=[line
];implied
[name
]=a
;}else if(a
[a
.length
-1]!==line
){a
.push(line
);}}
200 var xmltype
={html:{doBegin:function(n
){xtype
='html';option
.browser
=true;assume();},doTagName:function(n
,p
){var i
,t
=xmltype
.html
.tag
[n
],x
;src
=false;if(!t
){error("Unrecognized tag '<{a}>'.",nexttoken
,n
===n
.toLowerCase()?n:n
+' (capitalization error)');}
201 x
=t
.parent
;if(option
.adsafe
){switch(n
){case'script':if(stack
.length
!==1){warning("ADsafe violation: Misplaced script");}
202 break;case'a':case'applet':case'body':case'embed':case'frame':case'frameset':case'head':case'iframe':case'img':case'object':case'param':warning("ADsafe violation: Disallowed tag: "+n
);}}
203 if(!option
.fragment
||stack
.length
!==1){if(x
){if(x
.indexOf(' '+p
+' ')<0){error("A '<{a}>' must be within '<{b}>'.",token
,n
,x
);}}else{i
=stack
.length
;do{if(i
<=0){error("A '<{a}>' must be within '<{b}>'.",token
,n
,'body');}
204 i
-=1;}while(stack
[i
].name
!=='body');}}
205 return t
.empty
;},doAttribute:function(n
,a
){if(!a
){warning("Missing attribute name.",token
);}
206 a
=a
.toLowerCase();if(a
==='id'||a
==='name'||a
==='for'){return a
;}
207 if(n
==='script'){if(a
==='src'){src
=true;return'href';}else if(a
==='language'){warning("The 'language' attribute is deprecated.",token
);return false;}}else if(n
==='style'){if(a
==='type'&&option
.safe
){warning("Don't bother with 'type'.",token
);}}
208 if(href
[a
]===true){return'href';}
209 if(a
==='value'||a
==='style'){return'dangerous';}
210 if(a
.slice(0,2)==='on'){if(!option
.on
){warning("Avoid HTML event handlers.");}
211 return'script';}else{return'value';}},doIt:function(n
){return n
==='script'?'script':n
!=='html'&&xmltype
.html
.tag
[n
].special
&&'special';},tag:{a:{},abbr:{},acronym:{},address:{},applet:{},area:{empty:true,parent:' map '},b:{},base:{empty:true,parent:' head '},bdo:{},big:{},blockquote:{},body:{parent:' html noframes '},br:{empty:true},button:{},canvas:{parent:' body p div th td '},caption:{parent:' table '},center:{},cite:{},code:{},col:{empty:true,parent:' table colgroup '},colgroup:{parent:' table '},dd:{parent:' dl '},del:{},dfn:{},dir:{},div:{},dl:{},dt:{parent:' dl '},em:{},embed:{},fieldset:{},font:{},form:{},frame:{empty:true,parent:' frameset '},frameset:{parent:' html frameset '},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{parent:' html '},html:{},hr:{empty:true},i:{},iframe:{},img:{empty:true},input:{empty:true},ins:{},kbd:{},label:{},legend:{parent:' fieldset '},li:{parent:' dir menu ol ul '},link:{empty:true,parent:' head '},map:{},menu:{},meta:{empty:true,parent:' head noframes noscript '},noframes:{parent:' html body '},noscript:{parent:' body head noframes '},object:{},ol:{},optgroup:{parent:' select '},option:{parent:' optgroup select '},p:{},param:{empty:true,parent:' applet object '},pre:{},q:{},samp:{},script:{parent:' body div frame head iframe p pre span '},select:{},small:{},span:{},strong:{},style:{parent:' head ',special:true},sub:{},sup:{},table:{},tbody:{parent:' table '},td:{parent:' tr '},textarea:{},tfoot:{parent:' table '},th:{parent:' tr '},thead:{parent:' table '},title:{parent:' head '},tr:{parent:' table tbody thead tfoot '},tt:{},u:{},ul:{},'var':{}}},widget:{doBegin:function(n
){xtype
='widget';option
.widget
=true;option
.cap
=true;assume();},doTagName:function(n
,p
){var t
=xmltype
.widget
.tag
[n
];if(!t
){error("Unrecognized tag '<{a}>'.",nexttoken
,n
);}
212 var x
=t
.parent
;if(x
.indexOf(' '+p
+' ')<0){error("A '<{a}>' must be within '<{b}>'.",token
,n
,x
);}},doAttribute:function(n
,a
){var t
=xmltype
.widget
.tag
[a
];if(!t
){error("Unrecognized attribute '<{a} {b}>'.",nexttoken
,n
,a
);}
213 var x
=t
.parent
;if(x
.indexOf(' '+n
+' ')<0){error("Attribute '{a}' does not belong in '<{b}>'.",nexttoken
,a
,n
);}
214 return t
.script
?'script':a
==='name'&&n
!=='setting'?'define':'string';},doIt:function(n
){var x
=xmltype
.widget
.tag
[n
];return x
&&x
.script
&&'script';},tag:{"about-box":{parent:' widget '},"about-image":{parent:' about-box '},"about-text":{parent:' about-box '},"about-version":{parent:' about-box '},action:{parent:' widget ',script:true},alignment:{parent:' canvas frame image scrollbar text textarea window '},anchorstyle:{parent:' text '},author:{parent:' widget '},autohide:{parent:' scrollbar '},create:{parent:' canvas frame image scrollbar text window '},bgcolor:{parent:' text textarea '},bgcolour:{parent:' text textarea '},bgopacity:{parent:' text textarea '},canvas:{parent:' frame window '},charset:{parent:' script '},checked:{parent:' image menuitem '},cliprect:{parent:' image '},color:{parent:' about-text about-version shadow text textarea '},colorize:{parent:' image '},colour:{parent:' about-text about-version shadow text textarea '},columns:{parent:' textarea '},company:{parent:' widget '},contextmenuitems:{parent:' canvas frame image scrollbar text textarea window '},copyright:{parent:' widget '},data:{parent:' about-text about-version text textarea '},debug:{parent:' widget '},defaultvalue:{parent:' preference '},defaulttracking:{parent:' widget '},description:{parent:' preference '},directory:{parent:' preference '},editable:{parent:' textarea '},enabled:{parent:' menuitem '},extension:{parent:' preference '},file:{parent:' action preference '},fillmode:{parent:' image '},font:{parent:' about-text about-version text textarea '},fontstyle:{parent:' textarea '},frame:{parent:' frame window '},group:{parent:' preference '},halign:{parent:' canvas frame image scrollbar text textarea '},handlelinks:{parent:' textarea '},height:{parent:' canvas frame image scrollbar text textarea window '},hidden:{parent:' preference '},hlinesize:{parent:' frame '},hoffset:{parent:' about-text about-version canvas frame image scrollbar shadow text textarea window '},hotkey:{parent:' widget '},hregistrationpoint:{parent:' canvas frame image scrollbar text '},hscrollbar:{parent:' frame '},hsladjustment:{parent:' image '},hsltinting:{parent:' image '},icon:{parent:' preferencegroup '},id:{parent:' canvas frame hotkey image preference text textarea timer scrollbar widget window '},image:{parent:' about-box frame window widget '},interval:{parent:' action timer '},key:{parent:' hotkey '},kind:{parent:' preference '},level:{parent:' window '},lines:{parent:' textarea '},loadingsrc:{parent:' image '},locked:{parent:' window '},max:{parent:' scrollbar '},maxlength:{parent:' preference '},menuitem:{parent:' contextmenuitems '},min:{parent:' scrollbar '},minimumversion:{parent:' widget '},minlength:{parent:' preference '},missingsrc:{parent:' image '},modifier:{parent:' hotkey '},name:{parent:' canvas frame hotkey image preference preferencegroup scrollbar setting text textarea timer widget window '},notsaved:{parent:' preference '},onclick:{parent:' canvas frame image scrollbar text textarea ',script:true},oncontextmenu:{parent:' canvas frame image scrollbar text textarea window ',script:true},ondragdrop:{parent:' canvas frame image scrollbar text textarea ',script:true},ondragenter:{parent:' canvas frame image scrollbar text textarea ',script:true},ondragexit:{parent:' canvas frame image scrollbar text textarea ',script:true},onfirstdisplay:{parent:' window ',script:true},ongainfocus:{parent:' textarea window ',script:true},onkeydown:{parent:' hotkey text textarea window ',script:true},onkeypress:{parent:' textarea window ',script:true},onkeyup:{parent:' hotkey text textarea window ',script:true},onimageloaded:{parent:' image ',script:true},onlosefocus:{parent:' textarea window ',script:true},onmousedown:{parent:' canvas frame image scrollbar text textarea window ',script:true},onmousedrag:{parent:' canvas frame image scrollbar text textarea window ',script:true},onmouseenter:{parent:' canvas frame image scrollbar text textarea window ',script:true},onmouseexit:{parent:' canvas frame image scrollbar text textarea window ',script:true},onmousemove:{parent:' canvas frame image scrollbar text textarea window ',script:true},onmouseup:{parent:' canvas frame image scrollbar text textarea window ',script:true},onmousewheel:{parent:' frame ',script:true},onmulticlick:{parent:' canvas frame image scrollbar text textarea window ',script:true},onselect:{parent:' menuitem ',script:true},ontextinput:{parent:' window ',script:true},ontimerfired:{parent:' timer ',script:true},onvaluechanged:{parent:' scrollbar ',script:true},opacity:{parent:' canvas frame image scrollbar shadow text textarea window '},option:{parent:' preference widget '},optionvalue:{parent:' preference '},order:{parent:' preferencegroup '},orientation:{parent:' scrollbar '},pagesize:{parent:' scrollbar '},preference:{parent:' widget '},preferencegroup:{parent:' widget '},remoteasync:{parent:' image '},requiredplatform:{parent:' widget '},root:{parent:' window '},rotation:{parent:' canvas frame image scrollbar text '},script:{parent:' widget ',script:true},scrollbar:{parent:' frame text textarea window '},scrolling:{parent:' text '},scrollx:{parent:' frame '},scrolly:{parent:' frame '},secure:{parent:' preference textarea '},setting:{parent:' settings '},settings:{parent:' widget '},shadow:{parent:' about-text about-version text window '},size:{parent:' about-text about-version text textarea '},spellcheck:{parent:' textarea '},src:{parent:' image script '},srcheight:{parent:' image '},srcwidth:{parent:' image '},style:{parent:' about-text about-version canvas frame image preference scrollbar text textarea window '},subviews:{parent:' frame '},superview:{parent:' canvas frame image scrollbar text textarea '},text:{parent:' frame text textarea window '},textarea:{parent:' frame window '},timer:{parent:' widget '},thumbcolor:{parent:' scrollbar textarea '},ticking:{parent:' timer '},ticks:{parent:' preference '},ticklabel:{parent:' preference '},tileorigin:{parent:' image '},title:{parent:' menuitem preference preferencegroup window '},tooltip:{parent:' frame image text textarea '},tracking:{parent:' canvas image '},trigger:{parent:' action '},truncation:{parent:' text '},type:{parent:' preference '},url:{parent:' about-box about-text about-version '},usefileicon:{parent:' image '},valign:{parent:' canvas frame image scrollbar text textarea '},value:{parent:' preference scrollbar setting '},version:{parent:' widget '},visible:{parent:' canvas frame image scrollbar text textarea window '},vlinesize:{parent:' frame '},voffset:{parent:' about-text about-version canvas frame image scrollbar shadow text textarea window '},vregistrationpoint:{parent:' canvas frame image scrollbar text '},vscrollbar:{parent:' frame '},width:{parent:' canvas frame image scrollbar text textarea window '},window:{parent:' canvas frame image scrollbar text textarea widget '},wrap:{parent:' text '},zorder:{parent:' canvas frame image scrollbar text textarea window '}}}};function xmlword(tag
){var w
=nexttoken
.value
;if(!nexttoken
.identifier
){if(nexttoken
.id
==='<'){if(tag
){error("Expected '{a}' and instead saw '{b}'.",token
,'<','<');}else{error("Missing '{a}'.",token
,'>');}}else if(nexttoken
.id
==='(end)'){error("Bad structure.");}else{warning("Missing quote.",token
);}}
215 advance();while(nexttoken
.id
==='-'||nexttoken
.id
===':'){w
+=nexttoken
.id
;advance();if(!nexttoken
.identifier
){error("Bad name '{a}'.",nexttoken
,w
+nexttoken
.value
);}
216 w
+=nexttoken
.value
;advance();}
217 if(option
.cap
){w
=w
.toLowerCase();}
219 function closetag(n
){return'</'+n
+'>';}
220 function xml(){var a
,e
,n
,q
,t
,url
,wmode
;xmode
='xml';stack
=null;for(;;){switch(nexttoken
.value
){case'<':if(!stack
){stack
=[];}
221 advance('<');t
=nexttoken
;n
=xmlword(true);t
.name
=n
;if(!xtype
){if(option
.adsafe
&&(!option
.fragment
||n
!=='div')){error("ADsafe violation: Wrap the widget in a div.",token
);}
222 if(xmltype
[n
]){xmltype
[n
].doBegin();n
=xtype
;e
=false;}else{if(option
.fragment
){xmltype
.html
.doBegin();}else{error("Unrecognized tag '<{a}>'.",nexttoken
,n
);}}}else{if(stack
.length
===0){error("What the hell is this?");}
223 e
=xmltype
[xtype
].doTagName(n
,stack
[stack
.length
-1].name
);}
224 t
.type
=n
;for(;;){if(nexttoken
.id
==='/'){advance('/');if(nexttoken
.id
!=='>'){warning("Expected '{a}' and instead saw '{b}'.",nexttoken
,'>',nexttoken
.value
);}
226 if(nexttoken
.id
&&nexttoken
.id
.substr(0,1)==='>'){break;}
227 a
=xmlword();switch(xmltype
[xtype
].doAttribute(n
,a
)){case'script':xmode
='string';advance('=');q
=nexttoken
.id
;if(q
!=='"'&&q
!=="'"){error("Missing quote.");}
228 xmode
=q
;wmode
=option
.white
;option
.white
=false;advance(q
);statements('on');option
.white
=wmode
;if(nexttoken
.id
!==q
){error("Missing close quote on script attribute.");}
229 xmode
='xml';advance(q
);break;case'value':advance('=');if(!nexttoken
.identifier
&&nexttoken
.type
!=='(string)'&&nexttoken
.type
!=='(number)'){error("Bad value '{a}'.",nexttoken
,nexttoken
.value
);}
230 advance();break;case'id':advance('=');if(nexttoken
.type
!=='(string)'||!nexttoken
.value
){warning("Bad id '{a}'.",nexttoken
,nexttoken
.value
);}
231 t
.id
=nexttoken
.value
;if(ids
[t
.id
.toUpperCase()]===true){warning("Duplicate id='{a}'.",nexttoken
,nexttoken
.value
);}else if(option
.adsafe
){if(adsafe_id
){if(stack
.length
===0){warning("ADsafe violation: A widget can have only one id.",nexttoken
);}else if(t
.id
.slice(0,adsafe_id
.length
)!==adsafe_id
){warning("ADsafe violation: An id must have a '{a}' prefix",nexttoken
,adsafe_id
);}else if(!/^[A-Z]+_[A-Z0-9_]*$/.test(adsafe_id
)){warning("ADSAFE violation: bad id.",t
);}}else{adsafe_id
=t
.id
;if(!/^[A-Z]+_$/.test(adsafe_id
)){warning("ADSAFE violation: bad id.",t
);}}}
232 ids
[t
.id
]=true;advance();break;case'for':advance('=');if(adsafe_id
&&(nexttoken
.value
.length
<=adsafe_id
.length
||nexttoken
.value
.slice(0,adsafe_id
.length
)!==adsafe_id
)){warning("ADsafe violation: A for must have a '{a}' prefix",nexttoken
,adsafe_id
);}
233 advance();break;case'name':advance('=');if(nexttoken
.type
!=='(string)'||!nexttoken
.value
||nexttoken
.value
===adsafe_id
){warning("Bad name attribute.",nexttoken
);}
234 advance();break;case'string':advance('=');if(nexttoken
.type
!=='(string)'){error("Bad value '{a}'.",nexttoken
,nexttoken
.value
);}
235 advance();break;case'href':advance('=');if(nexttoken
.type
!=='(string)'){error("Bad value '{a}'.",nexttoken
,nexttoken
.value
);}
236 if(option
.safe
&&ux
.test(nexttoken
.value
)){error("ADsafe URL violation.");}
237 url
=nexttoken
.value
;urls
.push(url
);advance();break;case'dangerous':advance('=');if(nexttoken
.type
!=='(string)'){error("Bad value '{a}'.",nexttoken
,nexttoken
.value
);}
238 if(option
.safe
&&ux
.test(nexttoken
.value
)){error("ADsafe URL violation.");}
239 advance();break;case'define':advance('=');if(nexttoken
.type
!=='(string)'){error("Bad value '{a}'.",nexttoken
,nexttoken
.value
);}
240 addlabel(nexttoken
.value
,'var');advance();break;default:if(nexttoken
.id
==='='){advance('=');if(!nexttoken
.identifier
&&nexttoken
.type
!=='(string)'&&nexttoken
.type
!=='(number)'){error("Bad value '{a}'.",nexttoken
,nexttoken
.value
);}
242 switch(xmltype
[xtype
].doIt(n
)){case'script':xmode
='script';advance('>');indent
=nexttoken
.from;if(src
){if(option
.adsafe
&&(!adsafe_may
||!approved
[url
])){error("ADsafe script violation.",token
);}}else{if(adsafe_went
){error("ADsafe script violation.",token
);}
243 statements('script');}
244 if(nexttoken
.id
!=='</'&&nexttoken
.id
!=='(end)'){warning("Expected '{a}' and instead saw '{b}'.",nexttoken
,'<\/script>',nexttoken
.value
);}
245 xmode
='xml';break;case'special':e
=true;n
=closetag(t
.name
);if(!lex
.skip(n
)){error("Missing '{a}'.",t
,n
);}
246 break;default:lex
.skip('>');}
247 if(option
.adsafe
&&stack
.length
===0&&!adsafe_id
){warning("ADSAFE violation: missing id.",t
);}
248 if(!e
){stack
.push(t
);}
249 break;case'</':advance('</');n
=xmlword(true);if(!stack
){error("Unexpected '{a}'.",nexttoken
,closetag(n
));}
250 t
=stack
.pop();if(!t
){error("Unexpected '{a}'.",nexttoken
,closetag(n
));}
251 if(t
.name
!==n
){error("Expected '{a}' and instead saw '{b}'.",nexttoken
,closetag(t
.name
),closetag(n
));}
252 if(nexttoken
.id
!=='>'){error("Missing '{a}'.",nexttoken
,'>');}
253 if(stack
.length
>0){lex
.skip('>');}else{advance('>');}
254 break;case'<!':if(option
.safe
){error("ADsafe HTML violation.");}
255 for(;;){advance();if(nexttoken
.id
==='>'){break;}
256 if(nexttoken
.id
==='<'||nexttoken
.id
==='(end)'){error("Missing '{a}'.",token
,'>');}}
257 lex
.skip('>');break;case'<!--':if(option
.safe
){error("ADsafe HTML violation.");}
258 lex
.skip('-->');break;case'<%':if(option
.safe
){error("ADsafe HTML violation.");}
259 lex
.skip('%>');break;case'<?':if(option
.safe
){error("ADsafe HTML violation.");}
260 for(;;){advance();if(nexttoken
.id
==='?>'){break;}
261 if(nexttoken
.id
==='<?'||nexttoken
.id
==='<'||nexttoken
.id
==='>'||nexttoken
.id
==='(end)'){error("Missing '{a}'.",token
,'?>');}}
262 lex
.skip('?>');break;case'<=':case'<<':case'<<=':error("Missing '{a}'.",nexttoken
,'<');break;case'(end)':return;}
263 if(stack
&&stack
.length
===0){return;}
264 if(!lex
.skip('')){if(!stack
){error("Bad XML.");}
265 t
=stack
.pop();if(t
.value
){error("Missing '{a}'.",t
,closetag(t
.name
));}else{return;}}
267 type('(number)',idValue
);type('(string)',idValue
);syntax
['(identifier)']={type:'(identifier)',lbp:0,identifier:true,nud:function(){var v
=this.value
,s
=scope
[v
];if(s
&&(s
===funct
||s
===funct
['(global)'])){if(!funct
['(global)']){switch(funct
[v
]){case'unused':funct
[v
]='var';break;case'label':warning("'{a}' is a statement label.",token
,v
);break;}}}else if(funct
['(global)']){if(option
.undef
){warning("'{a}' is undefined.",token
,v
);}
268 note_implied(token
);}else{switch(funct
[v
]){case'closure':case'function':case'var':case'unused':warning("'{a}' used out of scope.",token
,v
);break;case'label':warning("'{a}' is a statement label.",token
,v
);break;case'outer':case true:break;default:if(s
===true){funct
[v
]=true;}else if(typeof s
!=='object'){if(option
.undef
){warning("'{a}' is undefined.",token
,v
);}else{funct
[v
]=true;}
269 note_implied(token
);}else{switch(s
[v
]){case'function':case'var':case'unused':s
[v
]='closure';funct
[v
]='outer';break;case'closure':case'parameter':funct
[v
]='outer';break;case'label':warning("'{a}' is a statement label.",token
,v
);}}}}
270 return this;},led:function(){error("Expected an operator and instead saw '{a}'.",nexttoken
,nexttoken
.value
);}};type('(regex)',function(){return this;});delim('(endline)');delim('(begin)');delim('(end)').reach
=true;delim('</').reach
=true;delim('<![').reach
=true;delim('<%');delim('<?');delim('<!');delim('<!--');delim('%>');delim('?>');delim('(error)').reach
=true;delim('}').reach
=true;delim(')');delim(']');delim(']]>').reach
=true;delim('"').reach
=true;delim("'").reach
=true;delim(';');delim(':').reach
=true;delim(',');reserve('else');reserve('case').reach
=true;reserve('catch');reserve('default').reach
=true;reserve('finally');reservevar('arguments');reservevar('eval');reservevar('false');reservevar('Infinity');reservevar('NaN');reservevar('null');reservevar('this');reservevar('true');reservevar('undefined');assignop('=','assign',20);assignop('+=','assignadd',20);assignop('-=','assignsub',20);assignop('*=','assignmult',20);assignop('/=','assigndiv',20).nud=function(){error("A regular expression literal can be confused with '/='.");};assignop('%=','assignmod',20);bitwiseassignop('&=','assignbitand',20);bitwiseassignop('|=','assignbitor',20);bitwiseassignop('^=','assignbitxor',20);bitwiseassignop('<<=','assignshiftleft',20);bitwiseassignop('>>=','assignshiftright',20);bitwiseassignop('>>>=','assignshiftrightunsigned',20);infix('?',function(left
){parse(10);advance(':');parse(10);},30);infix('||','or',40);infix('&&','and',50);bitwise('|','bitor',70);bitwise('^','bitxor',80);bitwise('&','bitand',90);relation('==',function(left
,right
){if(option
.eqeqeq
){warning("Expected '{a}' and instead saw '{b}'.",this,'===','==');}else if(isPoorRelation(left
)){warning("Use '{a}' to compare with '{b}'.",this,'===',left
.value
);}else if(isPoorRelation(right
)){warning("Use '{a}' to compare with '{b}'.",this,'===',right
.value
);}
271 return this;});relation('===');relation('!=',function(left
,right
){if(option
.eqeqeq
){warning("Expected '{a}' and instead saw '{b}'.",this,'!==','!=');}else if(isPoorRelation(left
)){warning("Use '{a}' to compare with '{b}'.",this,'!==',left
.value
);}else if(isPoorRelation(right
)){warning("Use '{a}' to compare with '{b}'.",this,'!==',right
.value
);}
272 return this;});relation('!==');relation('<');relation('>');relation('<=');relation('>=');bitwise('<<','shiftleft',120);bitwise('>>','shiftright',120);bitwise('>>>','shiftrightunsigned',120);infix('in','in',120);infix('instanceof','instanceof',120);infix('+',function(left
){nonadjacent(prevtoken
,token
);nonadjacent(token
,nexttoken
);var right
=parse(130);if(left
&&right
&&left
.id
==='(string)'&&right
.id
==='(string)'){left
.value
+=right
.value
;left
.character
=right
.character
;if(jx
.test(left
.value
)){warning("JavaScript URL.",left
);}
274 this.left
=left
;this.right
=right
;return this;},130);prefix('+','num');infix('-','sub',130);prefix('-','neg');infix('*','mult',140);infix('/','div',140);infix('%','mod',140);suffix('++','postinc');prefix('++','preinc');syntax
['++'].exps
=true;suffix('--','postdec');prefix('--','predec');syntax
['--'].exps
=true;prefix('delete',function(){var p
=parse(0);if(p
.id
!=='.'&&p
.id
!=='['){warning("Expected '{a}' and instead saw '{b}'.",nexttoken
,'.',nexttoken
.value
);}}).exps
=true;prefix('~',function(){if(option
.bitwise
){warning("Unexpected '{a}'.",this,'~');}
275 parse(150);return this;});prefix('!','not');prefix('typeof','typeof');prefix('new',function(){var c
=parse(155),i
;if(c
&&c
.id
!=='function'){if(c
.identifier
){c
['new']=true;switch(c
.value
){case'Object':warning("Use the object literal notation {}.",token
);break;case'Array':warning("Use the array literal notation [].",token
);break;case'Number':case'String':case'Boolean':case'Math':warning("Do not use the {a} function as a constructor.",token
,c
.value
);break;case'Function':if(!option
.evil
){warning("The Function constructor is eval.");}
276 break;case'Date':case'RegExp':break;default:if(c
.id
!=='function'){i
=c
.value
.substr(0,1);if(i
<'A'||i
>'Z'){warning("A constructor name should start with an uppercase letter.",token
);}}}}else{if(c
.id
!=='.'&&c
.id
!=='['&&c
.id
!=='('){warning("Bad constructor.",token
);}}}else{warning("Weird construction. Delete 'new'.",this);}
277 adjacent(token
,nexttoken
);if(nexttoken
.id
!=='('){warning("Missing '()' invoking a constructor.");}
278 this.first
=c
;return this;});syntax
['new'].exps
=true;infix('.',function(left
){adjacent(prevtoken
,token
);var t
=this,m
=identifier();if(typeof m
==='string'){countMember(m
);}
279 t
.left
=left
;t
.right
=m
;if(!option
.evil
&&left
&&left
.value
==='document'&&(m
==='write'||m
==='writeln')){warning("document.write can be a form of eval.",left
);}
280 if(option
.adsafe
){if(left
&&left
.value
==='ADSAFE'){if(m
==='id'||m
==='lib'){warning("ADsafe violation.",this);}else if(m
==='go'){if(xmode
!=='script'){warning("ADsafe violation.",this);}else if(adsafe_went
||nexttoken
.id
!=='('||peek(0).id
!=='(string)'||peek(0).value
!==adsafe_id
||peek(1).id
!==','){error("ADsafe violation: go.",this);}
281 adsafe_went
=true;adsafe_may
=false;}}
282 for(;;){if(banned
[m
]===true){warning("ADsafe restricted word '{a}'.",token
,m
);}
283 if(predefined
[left
.value
]!==true||nexttoken
.id
==='('){break;}
284 if(standard_member
[m
]===true){if(nexttoken
.id
==='.'){warning("ADsafe violation.",this);}
286 if(nexttoken
.id
!=='.'){warning("ADsafe violation.",this);break;}
287 advance('.');token
.left
=t
;token
.right
=m
;t
=token
;m
=identifier();if(typeof m
==='string'){countMember(m
);}}}
288 return t
;},160);infix('(',function(left
){adjacent(prevtoken
,token
);nospace();var n
=0;var p
=[];if(left
){if(left
.type
==='(identifier)'){if(left
.value
.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)){if(left
.value
!=='Number'&&left
.value
!=='String'&&left
.value
!=='Boolean'&&left
.value
!=='Date'){if(left
.value
==='Math'){warning("Math is not a function.",left
);}else{warning("Missing 'new' prefix when invoking a constructor.",left
);}}}}else if(left
.id
==='.'){if(option
.safe
&&left
.left
.value
==='Math'&&left
.right
==='random'){warning("ADsafe violation.",left
);}}}
289 if(nexttoken
.id
!==')'){for(;;){p
[p
.length
]=parse(10);n
+=1;if(nexttoken
.id
!==','){break;}
290 advance(',');nonadjacent(token
,nexttoken
);}}
291 advance(')');nospace(prevtoken
,token
);if(typeof left
==='object'){if(left
.value
==='parseInt'&&n
===1){warning("Missing radix parameter.",left
);}
292 if(!option
.evil
){if(left
.value
==='eval'||left
.value
==='Function'||left
.value
==='execScript'){warning("eval is evil.",left
);}else if(p
[0]&&p
[0].id
==='(string)'&&(left
.value
==='setTimeout'||left
.value
==='setInterval')){warning("Implied eval is evil. Pass a function instead of a string.",left
);}}
293 if(!left
.identifier
&&left
.id
!=='.'&&left
.id
!=='['&&left
.id
!=='('&&left
.id
!=='&&'&&left
.id
!=='||'&&left
.id
!=='?'){warning("Bad invocation.",left
);}}
294 this.left
=left
;return this;},155).exps
=true;prefix('(',function(){nospace();var v
=parse(0);advance(')',this);nospace(prevtoken
,token
);if(v
&&(v
.id
==='function'||v
.id
==='new'||v
.id
==='.'||v
.id
==='['||v
.id
==='(')){warning("Parens are not needed here.",this);}
295 return v
;}).fud=function(){nospace();var v
=parse(0);advance(')',this);if(v
){if(v
.id
==='function'){advance('(');return token
.led(v
);}}
296 nospace(prevtoken
,token
);return v
;};infix('[',function(left
){nospace();var e
=parse(0),s
;if(e
&&e
.type
==='(string)'){if(option
.safe
&&banned
[e
.value
]===true){warning("ADsafe restricted word '{a}'.",this,e
.value
);}
297 countMember(e
.value
);if(!option
.sub
&&ix
.test(e
.value
)){s
=syntax
[e
.value
];if(!s
||!s
.reserved
){warning("['{a}'] is better written in dot notation.",e
,e
.value
);}}}else if(!e
||e
.type
!=='(number)'){if(option
.safe
){warning('ADsafe subscripting.');}}
298 advance(']',this);nospace(prevtoken
,token
);this.left
=left
;this.right
=e
;return this;},160);prefix('[',function(){if(nexttoken
.id
===']'){advance(']');return;}
299 var b
=token
.line
!==nexttoken
.line
;if(b
){indent
+=option
.indent
;if(nexttoken
.from===indent
+option
.indent
){indent
+=option
.indent
;}}
300 for(;;){if(b
&&token
.line
!==nexttoken
.line
){indentation();}
301 parse(10);if(nexttoken
.id
===','){adjacent(token
,nexttoken
);advance(',');if(nexttoken
.id
===','){warning("Extra comma.",token
);}else if(nexttoken
.id
===']'){warning("Extra comma.",token
);break;}
302 nonadjacent(token
,nexttoken
);}else{if(b
){indent
-=option
.indent
;indentation();}
304 advance(']',this);return;},160);(function(x
){x
.nud=function(){var i
,s
;if(nexttoken
.id
==='}'){advance('}');return;}
305 var b
=token
.line
!==nexttoken
.line
;if(b
){indent
+=option
.indent
;if(nexttoken
.from===indent
+option
.indent
){indent
+=option
.indent
;}}
306 for(;;){if(b
){indentation();}
307 i
=optionalidentifier(true);if(!i
){if(nexttoken
.id
==='(string)'){i
=nexttoken
.value
;if(ix
.test(i
)){s
=syntax
[i
];}
308 advance();}else if(nexttoken
.id
==='(number)'){i
=nexttoken
.value
.toString();advance();}else{error("Expected '{a}' and instead saw '{b}'.",nexttoken
,'}',nexttoken
.value
);}}
309 countMember(i
);advance(':');nonadjacent(token
,nexttoken
);parse(10);if(nexttoken
.id
===','){adjacent(token
,nexttoken
);advance(',');if(nexttoken
.id
===','||nexttoken
.id
==='}'){warning("Extra comma.",token
);}
310 nonadjacent(token
,nexttoken
);}else{if(b
){indent
-=option
.indent
;indentation();}
311 advance('}',this);return;}}};x
.fud=function(){error("Expected to see a statement and instead saw a block.",token
);};})(delim('{'));function varstatement(prefix
){if(funct
['(global)']&&option
.glovar
){warning("Use '/*global "+nexttoken
.value
+"*/' instead of 'var'.",token
);}
312 for(;;){nonadjacent(token
,nexttoken
);addlabel(identifier(),'unused');if(prefix
){return;}
313 if(nexttoken
.id
==='='){nonadjacent(token
,nexttoken
);advance('=');nonadjacent(token
,nexttoken
);if(peek(0).id
==='='){error("Variable {a} was not declared correctly.",nexttoken
,nexttoken
.value
);}
315 if(nexttoken
.id
!==','){return;}
316 adjacent(token
,nexttoken
);advance(',');nonadjacent(token
,nexttoken
);}}
317 stmt('var',varstatement
);stmt('new',function(){error("'new' should not be used as a statement.");});function functionparams(){var i
,t
=nexttoken
,p
=[];advance('(');nospace();if(nexttoken
.id
===')'){advance(')');nospace(prevtoken
,token
);return;}
318 for(;;){i
=identifier();p
.push(i
);addlabel(i
,'parameter');if(nexttoken
.id
===','){advance(',');nonadjacent(token
,nexttoken
);}else{advance(')',t
);nospace(prevtoken
,token
);return p
.join(', ');}}}
319 function doFunction(i
){var s
=scope
;scope
=Object
.create(s
);funct
={'(name)':i
||'"'+anonname
+'"','(line)':nexttoken
.line
+1,'(context)':funct
,'(breakage)':0,'(loopage)':0,'(scope)':scope
};functions
.push(funct
);if(i
){addlabel(i
,'function');}
320 funct
['(params)']=functionparams();block(false);scope
=s
;funct
=funct
['(context)'];}
321 blockstmt('function',function(){if(inblock
){warning("Function statements cannot be placed in blocks. Use a function expression or move the statement to the top of the outer function.",token
);}
322 var i
=identifier();adjacent(token
,nexttoken
);addlabel(i
,'unused');doFunction(i
);if(nexttoken
.id
==='('&&nexttoken
.line
===token
.line
){error("Function statements are not invocable. Wrap the function expression in parens.");}});prefix('function',function(){var i
=optionalidentifier();if(i
){adjacent(token
,nexttoken
);}else{nonadjacent(token
,nexttoken
);}
323 doFunction(i
);if(funct
['(loopage)']&&nexttoken
.id
!=='('){warning("Be careful when making functions within a loop. Consider putting the function in a closure.");}
324 return this;});blockstmt('if',function(){var t
=nexttoken
;advance('(');nonadjacent(this,t
);nospace();parse(20);if(nexttoken
.id
==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}
325 advance(')',t
);nospace(prevtoken
,token
);block(true);if(nexttoken
.id
==='else'){nonadjacent(token
,nexttoken
);advance('else');if(nexttoken
.id
==='if'||nexttoken
.id
==='switch'){statement(true);}else{block(true);}}
326 return this;});blockstmt('try',function(){var b
,e
,s
;block(false);if(nexttoken
.id
==='catch'){advance('catch');nonadjacent(token
,nexttoken
);advance('(');s
=scope
;scope
=Object
.create(s
);e
=nexttoken
.value
;if(nexttoken
.type
!=='(identifier)'){warning("Expected an identifier and instead saw '{a}'.",nexttoken
,e
);}else{addlabel(e
,'unused');}
327 advance();advance(')');block(false);b
=true;scope
=s
;}
328 if(nexttoken
.id
==='finally'){advance('finally');block(false);return;}else if(!b
){error("Expected '{a}' and instead saw '{b}'.",nexttoken
,'catch',nexttoken
.value
);}});blockstmt('while',function(){var t
=nexttoken
;funct
['(breakage)']+=1;funct
['(loopage)']+=1;advance('(');nonadjacent(this,t
);nospace();parse(20);if(nexttoken
.id
==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}
329 advance(')',t
);nospace(prevtoken
,token
);block(true);funct
['(breakage)']-=1;funct
['(loopage)']-=1;}).labelled
=true;reserve('with');blockstmt('switch',function(){var t
=nexttoken
;var g
=false;funct
['(breakage)']+=1;advance('(');nonadjacent(this,t
);nospace();this.condition
=parse(20);advance(')',t
);nospace(prevtoken
,token
);nonadjacent(token
,nexttoken
);t
=nexttoken
;advance('{');nonadjacent(token
,nexttoken
);indent
+=option
.indent
;this.cases
=[];for(;;){switch(nexttoken
.id
){case'case':switch(funct
['(verb)']){case'break':case'case':case'continue':case'return':case'switch':case'throw':break;default:warning("Expected a 'break' statement before 'case'.",token
);}
330 indentation(-option
.indent
);advance('case');this.cases
.push(parse(20));g
=true;advance(':');funct
['(verb)']='case';break;case'default':switch(funct
['(verb)']){case'break':case'continue':case'return':case'throw':break;default:warning("Expected a 'break' statement before 'default'.",token
);}
331 indentation(-option
.indent
);advance('default');g
=true;advance(':');break;case'}':indent
-=option
.indent
;indentation();advance('}',t
);if(this.cases
.length
===1||this.condition
.id
==='true'||this.condition
.id
==='false'){warning("This 'switch' should be an 'if'.",this);}
332 funct
['(breakage)']-=1;funct
['(verb)']=undefined;return;case'(end)':error("Missing '{a}'.",nexttoken
,'}');return;default:if(g
){switch(token
.id
){case',':error("Each value should have its own case label.");return;case':':statements();break;default:error("Missing ':' on a case clause.",token
);}}else{error("Expected '{a}' and instead saw '{b}'.",nexttoken
,'case',nexttoken
.value
);}}}}).labelled
=true;stmt('debugger',function(){if(!option
.debug
){warning("All 'debugger' statements should be removed.");}});stmt('do',function(){funct
['(breakage)']+=1;funct
['(loopage)']+=1;block(true);advance('while');var t
=nexttoken
;nonadjacent(token
,t
);advance('(');nospace();parse(20);if(nexttoken
.id
==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}
333 advance(')',t
);nospace(prevtoken
,token
);funct
['(breakage)']-=1;funct
['(loopage)']-=1;}).labelled
=true;blockstmt('for',function(){var s
,t
=nexttoken
;funct
['(breakage)']+=1;funct
['(loopage)']+=1;advance('(');nonadjacent(this,t
);nospace();if(peek(nexttoken
.id
==='var'?1:0).id
==='in'){if(nexttoken
.id
==='var'){advance('var');varstatement(true);}else{advance();}
334 advance('in');parse(20);advance(')',t
);s
=block(true);if(!option
.forin
&&(s
.length
>1||typeof s
[0]!=='object'||s
[0].value
!=='if')){warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.",this);}
335 funct
['(breakage)']-=1;funct
['(loopage)']-=1;return this;}else{if(nexttoken
.id
!==';'){if(nexttoken
.id
==='var'){advance('var');varstatement();}else{for(;;){parse(0,'for');if(nexttoken
.id
!==','){break;}
337 advance(';');if(nexttoken
.id
!==';'){parse(20);if(nexttoken
.id
==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}}
338 advance(';');if(nexttoken
.id
===';'){error("Expected '{a}' and instead saw '{b}'.",nexttoken
,')',';');}
339 if(nexttoken
.id
!==')'){for(;;){parse(0,'for');if(nexttoken
.id
!==','){break;}
341 advance(')',t
);nospace(prevtoken
,token
);block(true);funct
['(breakage)']-=1;funct
['(loopage)']-=1;}}).labelled
=true;stmt('break',function(){var v
=nexttoken
.value
;if(funct
['(breakage)']===0){warning("Unexpected '{a}'.",nexttoken
,this.value
);}
342 nolinebreak(this);if(nexttoken
.id
!==';'){if(funct
[v
]!=='label'){warning("'{a}' is not a statement label.",nexttoken
,v
);}else if(scope
[v
]!==funct
){warning("'{a}' is out of scope.",nexttoken
,v
);}
344 reachable('break');});stmt('continue',function(){var v
=nexttoken
.value
;nolinebreak(this);if(nexttoken
.id
!==';'){if(funct
[v
]!=='label'){warning("'{a}' is not a statement label.",nexttoken
,v
);}else if(scope
[v
]!==funct
){warning("'{a}' is out of scope.",nexttoken
,v
);}
346 reachable('continue');});stmt('return',function(){nolinebreak(this);if(nexttoken
.id
!==';'&&!nexttoken
.reach
){nonadjacent(token
,nexttoken
);parse(20);}
347 reachable('return');});stmt('throw',function(){nolinebreak(this);nonadjacent(token
,nexttoken
);parse(20);reachable('throw');});reserve('void');reserve('class');reserve('const');reserve('enum');reserve('export');reserve('extends');reserve('goto');reserve('import');reserve('super');function jsonValue(){function jsonObject(){var t
=nexttoken
;advance('{');if(nexttoken
.id
!=='}'){for(;;){if(nexttoken
.id
==='(end)'){error("Missing '}' to match '{' from line {a}.",nexttoken
,t
.line
+1);}else if(nexttoken
.id
==='}'){warning("Unexpected comma.",token
);break;}else if(nexttoken
.id
===','){error("Unexpected comma.",nexttoken
);}else if(nexttoken
.id
!=='(string)'){warning("Expected a string and instead saw {a}.",nexttoken
,nexttoken
.value
);}
348 advance();advance(':');jsonValue();if(nexttoken
.id
!==','){break;}
351 function jsonArray(){var t
=nexttoken
;advance('[');if(nexttoken
.id
!==']'){for(;;){if(nexttoken
.id
==='(end)'){error("Missing ']' to match '[' from line {a}.",nexttoken
,t
.line
+1);}else if(nexttoken
.id
===']'){warning("Unexpected comma.",token
);break;}else if(nexttoken
.id
===','){error("Unexpected comma.",nexttoken
);}
352 jsonValue();if(nexttoken
.id
!==','){break;}
355 switch(nexttoken
.id
){case'{':jsonObject();break;case'[':jsonArray();break;case'true':case'false':case'null':case'(number)':case'(string)':advance();break;case'-':advance('-');if(token
.character
!==nexttoken
.from){warning("Unexpected space after '-'.",token
);}
356 adjacent(token
,nexttoken
);advance('(number)');break;default:error("Expected a JSON value.",nexttoken
);}}
357 var itself=function(s
,o
){var a
,i
;JSLINT
.errors
=[];predefined
=Object
.create(standard
);if(o
){a
=o
.predef
;if(a
instanceof Array
){for(i
=0;i
<a
.length
;i
+=1){predefined
[a
[i
]]=true;}}
358 if(o
.adsafe
){o
.safe
=true;}
359 if(o
.safe
){o
.browser
=false;o
.debug
=false;o
.eqeqeq
=true;o
.evil
=false;o
.forin
=false;o
.glovar
=true;o
.nomen
=true;o
.on
=false;o
.rhino
=false;o
.safe
=true;o
.sidebar
=false;o
.sub
=false;o
.undef
=true;o
.widget
=false;predefined
.Date
=false;predefined
['eval']=false;predefined
.Function
=false;predefined
.Object
=false;predefined
.ADSAFE
=true;}
360 option
=o
;}else{option
={};}
361 option
.indent
=option
.indent
||4;adsafe_id
='';adsafe_may
=false;adsafe_went
=false;approved
={};if(option
.approved
){for(i
=0;i
<option
.approved
.length
;i
+=1){approved
[option
.approved
[i
]]=option
.approved
[i
];}}
362 approved
.test
='test';tab
='';for(i
=0;i
<option
.indent
;i
+=1){tab
+=' ';}
363 indent
=0;global
=Object
.create(predefined
);scope
=global
;funct
={'(global)':true,'(name)':'(global)','(scope)':scope
,'(breakage)':0,'(loopage)':0};functions
=[];ids
={};urls
=[];src
=false;xmode
=false;xtype
='';stack
=null;member
={};membersOnly
=null;implied
={};inblock
=false;lookahead
=[];jsonmode
=false;warnings
=0;lex
.init(s
);prereg
=true;prevtoken
=token
=nexttoken
=syntax
['(begin)'];assume();try{advance();if(nexttoken
.value
.charAt(0)==='<'){xml();if(option
.adsafe
&&!adsafe_went
){warning("ADsafe violation: Missing ADSAFE.go.",this);}}else if(nexttoken
.id
==='{'||nexttoken
.id
==='['){option
.laxbreak
=true;jsonmode
=true;jsonValue();}else{if(option
.adsafe
&&option
.fragment
){warning("ADsafe violation.",this);}
365 advance('(end)');}catch(e
){if(e
){JSLINT
.errors
.push({reason:e
.message
,line:e
.line
||nexttoken
.line
,character:e
.character
||nexttoken
.from},null);}}
366 return JSLINT
.errors
.length
===0;};function to_array(o
){var a
=[],k
;for(k
in o
){if(o
.hasOwnProperty(k
)){a
.push(k
);}}
368 itself
.report=function(option
,sep
){var a
=[],c
,e
,f
,i
,k
,l
,m
='',n
,o
=[],s
,v
,cl
,va
,un
,ou
,gl
,la
;function detail(h
,s
,sep
){if(s
.length
){o
.push('<div><i>'+h
+'</i> '+
369 s
.sort().join(sep
||', ')+'</div>');}}
370 s
=to_array(implied
);k
=JSLINT
.errors
.length
;if(k
||s
.length
>0){o
.push('<div id=errors><i>Error:</i>');if(s
.length
>0){s
.sort();for(i
=0;i
<s
.length
;i
+=1){s
[i
]='<code>'+s
[i
]+'</code> <i>'+
371 implied
[s
[i
]].join(' ')+'</i>';}
372 o
.push('<p><i>Implied global:</i> '+s
.join(', ')+'</p>');c
=true;}
373 for(i
=0;i
<k
;i
+=1){c
=JSLINT
.errors
[i
];if(c
){e
=c
.evidence
||'';o
.push('<p>Problem'+(isFinite(c
.line
)?' at line '+(c
.line
+1)+' character '+(c
.character
+1):'')+': '+c
.reason
.entityify()+'</p><p class=evidence>'+
374 (e
&&(e
.length
>80?e
.slice(0,77)+'...':e
).entityify())+'</p>');}}
375 o
.push('</div>');if(!c
){return o
.join('');}}
376 if(!option
){o
.push('<br><div id=functions>');if(urls
.length
>0){detail("URLs<br>",urls
,'<br>');}
377 s
=to_array(scope
);if(s
.length
===0){if(jsonmode
){if(k
===0){o
.push('<p>JSON: good.</p>');}else{o
.push('<p>JSON: bad.</p>');}}else{o
.push('<div><i>No new global variables introduced.</i></div>');}}else{o
.push('<div><i>Global</i> '+s
.sort().join(', ')+'</div>');}
378 for(i
=0;i
<functions
.length
;i
+=1){f
=functions
[i
];cl
=[];va
=[];un
=[];ou
=[];gl
=[];la
=[];for(k
in f
){if(f
.hasOwnProperty(k
)){v
=f
[k
];switch(v
){case'closure':cl
.push(k
);break;case'var':va
.push(k
);break;case'unused':un
.push(k
);break;case'label':la
.push(k
);break;case'outer':ou
.push(k
);break;case true:if(k
!=='(context)'){gl
.push(k
);}
380 o
.push('<br><div class=function><i>'+f
['(line)']+'</i> '+
381 (f
['(name)']||'')+'('+
382 (f
['(params)']||'')+')</div>');detail('Closure',cl
);detail('Variable',va
);detail('Unused',un
);detail('Label',la
);detail('Outer',ou
);detail('Global',gl
);}
383 a
=[];for(k
in member
){if(typeof member
[k
]==='number'){a
.push(k
);}}
384 if(a
.length
){a
=a
.sort();m
='<br><pre>/*members ';l
=10;for(i
=0;i
<a
.length
;i
+=1){k
=a
[i
];n
=k
.name();if(l
+n
.length
>72){o
.push(m
+'<br>');m
=' ';l
=1;}
385 l
+=n
.length
+2;if(member
[k
]===1){n
='<i>'+n
+'</i>';}
386 if(i
<a
.length
-1){n
+=', ';}
388 o
.push(m
+'<br>*/</pre>');}
390 return o
.join('');};return itself
;}();(function(a
){if(!a
[0]){print("Usage: jslint.js file.js");quit(1);}
391 var input
=readFile(a
[0]);if(!input
){print("jslint: Couldn't open file '"+a
[0]+"'.");quit(1);}
392 if(!JSLINT(input
,{rhino:true,passfail:false})){for(var i
=0;i
<JSLINT
.errors
.length
;i
+=1){var e
=JSLINT
.errors
[i
];if(e
){print('Lint at line '+(e
.line
+1)+' character '+
393 (e
.character
+1)+': '+e
.reason
);print((e
.evidence
||'').replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"));print('');}}}else{print("jslint: No problems found in "+a
[0]);quit();}})(arguments
);