From c08add1575c2899641188561fc0970d9b8f94302 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 5 Mar 2010 20:13:03 +0100 Subject: Remove unnecessary junk --- jslint.js | 524 --- offline-submit/collect-inputs.js | 45 - offline-submit/form-serialization.js | 129 - offline-submit/http-requests.txt | 28 - offline-submit/john-resig-offline-app-stub.js | 43 - offline-submit/jquery.malsup.com.htm | 583 ---- offline-submit/lazarus.js | 4418 ------------------------- offline-submit/post-data.txt | 79 - 8 files changed, 5849 deletions(-) delete mode 100755 jslint.js delete mode 100644 offline-submit/collect-inputs.js delete mode 100644 offline-submit/form-serialization.js delete mode 100644 offline-submit/http-requests.txt delete mode 100644 offline-submit/john-resig-offline-app-stub.js delete mode 100644 offline-submit/jquery.malsup.com.htm delete mode 100644 offline-submit/lazarus.js delete mode 100644 offline-submit/post-data.txt diff --git a/jslint.js b/jslint.js deleted file mode 100755 index a9f9667..0000000 --- a/jslint.js +++ /dev/null @@ -1,524 +0,0 @@ -#!/usr/bin/rhino -// (C)2002 Douglas Crockford -// www.JSLint.com -// Rhino Edition -"use strict";var JSLINT=(function(){var adsafe_id,adsafe_may,adsafe_went,anonname,approved,atrule={media:true,'font-face':true,page:true},bang={'<':true,'<=':true,'==':true,'===':true,'!==':true,'!=':true,'>':true,'>=':true,'+':true,'-':true,'*':true,'/':true,'%':true},banned={'arguments':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,css:true,debug:true,eqeqeq:true,evil:true,forin:true,fragment:true,immed:true,laxbreak:true,newcap:true,nomen:true,on:true,onevar:true,passfail:true,plusplus:true,regexp:true,rhino:true,undef:true,safe:true,sidebar:true,strict:true,sub:true,white:true,widget:true},browser={addEventListener:false,alert:false,blur:false,clearInterval:false,clearTimeout:false,close:false,closed:false,confirm:false,console:false,Debug:false,defaultStatus:false,document:false,event:false,focus:false,frames:false,getComputedStyle:false,history:false,Image:false,length:false,location:false,moveBy:false,moveTo:false,name:false,navigator:false,onbeforeunload:true,onblur:true,onerror:true,onfocus:true,onload:true,onresize:true,onunload:true,open:false,opener:false,opera:false,Option:false,parent:false,print:false,prompt:false,removeEventListener:false,resizeBy:false,resizeTo:false,screen:false,scroll:false,scrollBy:false,scrollTo:false,setInterval:false,setTimeout:false,status:false,top:false,XMLHttpRequest:false},cssAttributeData,cssAny,cssColorData={"aliceblue":true,"antiquewhite":true,"aqua":true,"aquamarine":true,"azure":true,"beige":true,"bisque":true,"black":true,"blanchedalmond":true,"blue":true,"blueviolet":true,"brown":true,"burlywood":true,"cadetblue":true,"chartreuse":true,"chocolate":true,"coral":true,"cornflowerblue":true,"cornsilk":true,"crimson":true,"cyan":true,"darkblue":true,"darkcyan":true,"darkgoldenrod":true,"darkgray":true,"darkgreen":true,"darkkhaki":true,"darkmagenta":true,"darkolivegreen":true,"darkorange":true,"darkorchid":true,"darkred":true,"darksalmon":true,"darkseagreen":true,"darkslateblue":true,"darkslategray":true,"darkturquoise":true,"darkviolet":true,"deeppink":true,"deepskyblue":true,"dimgray":true,"dodgerblue":true,"firebrick":true,"floralwhite":true,"forestgreen":true,"fuchsia":true,"gainsboro":true,"ghostwhite":true,"gold":true,"goldenrod":true,"gray":true,"green":true,"greenyellow":true,"honeydew":true,"hotpink":true,"indianred":true,"indigo":true,"ivory":true,"khaki":true,"lavender":true,"lavenderblush":true,"lawngreen":true,"lemonchiffon":true,"lightblue":true,"lightcoral":true,"lightcyan":true,"lightgoldenrodyellow":true,"lightgreen":true,"lightpink":true,"lightsalmon":true,"lightseagreen":true,"lightskyblue":true,"lightslategray":true,"lightsteelblue":true,"lightyellow":true,"lime":true,"limegreen":true,"linen":true,"magenta":true,"maroon":true,"mediumaquamarine":true,"mediumblue":true,"mediumorchid":true,"mediumpurple":true,"mediumseagreen":true,"mediumslateblue":true,"mediumspringgreen":true,"mediumturquoise":true,"mediumvioletred":true,"midnightblue":true,"mintcream":true,"mistyrose":true,"moccasin":true,"navajowhite":true,"navy":true,"oldlace":true,"olive":true,"olivedrab":true,"orange":true,"orangered":true,"orchid":true,"palegoldenrod":true,"palegreen":true,"paleturquoise":true,"palevioletred":true,"papayawhip":true,"peachpuff":true,"peru":true,"pink":true,"plum":true,"powderblue":true,"purple":true,"red":true,"rosybrown":true,"royalblue":true,"saddlebrown":true,"salmon":true,"sandybrown":true,"seagreen":true,"seashell":true,"sienna":true,"silver":true,"skyblue":true,"slateblue":true,"slategray":true,"snow":true,"springgreen":true,"steelblue":true,"tan":true,"teal":true,"thistle":true,"tomato":true,"turquoise":true,"violet":true,"wheat":true,"white":true,"whitesmoke":true,"yellow":true,"yellowgreen":true},cssBorderStyle,cssBreak,cssLengthData={'%':true,'cm':true,'em':true,'ex':true,'in':true,'mm':true,'pc':true,'pt':true,'px':true},cssOverflow,escapes={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','/':'\\/','\\':'\\\\'},funct,functionicity=['closure','exception','global','label','outer','unused','var'],functions,global,htmltag={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:{parent:'*'},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:{empty:true,parent:' body div frame head iframe p pre span '},select:{},small:{},span:{},strong:{},style:{parent:' head ',empty: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':{}},ids,implied,inblock,indent,jsonmode,lines,lookahead,member,membersOnly,nexttoken,noreach,option,predefined,prereg,prevtoken,rhino={defineClass:false,deserialize:false,gc:false,help:false,load:false,loadClass:false,print:false,quit:false,readFile:false,readUrl:false,runCommand:false,seal:false,serialize:false,spawn:false,sync:false,toint32:false,version:false},scope,sidebar={System:false},src,stack,standard={Array:false,Boolean:false,Date:false,decodeURI:false,decodeURIComponent:false,encodeURI:false,encodeURIComponent:false,Error:false,'eval':false,EvalError:false,Function:false,hasOwnProperty:false,isFinite:false,isNaN:false,JSON:false,Math:false,Number:false,Object:false,parseInt:false,parseFloat:false,RangeError:false,ReferenceError:false,RegExp:false,String:false,SyntaxError:false,TypeError:false,URIError:false},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},strict_mode,syntax={},tab,token,urls,warnings,widget={alert: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,Flash:true,focusWidget:true,form:true,FormField:true,Frame:true,HotKey:true,Image:true,include:true,isApplicationRunning:true,iTunes:true,konfabulatorVersion:true,log:true,md5:true,MenuItem:true,MoveAnimation:true,openURL:true,play:true,Point:true,popupMenu:true,preferenceGroups:true,preferences:true,print:true,prompt:true,random:true,Rectangle:true,reloadWidget:true,ResizeAnimation: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,Style:true,suppressUpdates:true,system:true,tellWidget:true,Text:true,TextArea:true,Timer:true,unescape:true,updateNow:true,URL:true,Web:true,widget:true,Window:true,XMLDOM:true,XMLHttpRequest:true,yahooCheckLogin:true,yahooLogin:true,yahooLogout:true},xmode,xquote,ax=/@cc|<\/?|script|\]*s\]|<\s*!|</i,cx=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,tx=/^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,hx=/^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--|.)/,nx=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,nxg=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,ox=/[>&]|<[\/!]?|--/,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,sx=/^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,ssx=/^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,qx=/[^a-zA-Z0-9-_\/ ]/,dx=/[\[\]\/\\"'*<>.&:(){}+=#]/,rx={outer:hx,html:hx,style:sx,styleproperty:ssx};function F(){} -if(typeof Object.create!=='function'){Object.create=function(o){F.prototype=o;return new F();};} -function is_own(object,name){return Object.prototype.hasOwnProperty.call(object,name);} -function combine(t,o){var n;for(n in o){if(is_own(o,n)){t[n]=o[n];}}} -String.prototype.entityify=function(){return this.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;} -if(nx.test(this)){return'"'+this.replace(nxg,function(a){var c=escapes[a];if(c){return c;} -return'\\u'+('0000'+a.charCodeAt().toString(16)).slice(-4);})+'"';} -return'"'+this+'"';};function assume(){if(!option.safe){if(option.rhino){combine(predefined,rhino);} -if(option.browser||option.sidebar){combine(predefined,browser);} -if(option.sidebar){combine(predefined,sidebar);} -if(option.widget){combine(predefined,widget);}}} -function quit(m,l,ch){throw{name:'JSLintError',line:l,character:ch,message:m+" ("+Math.floor((l/lines.length)*100)+"% scanned)."};} -function warning(m,t,a,b,c,d){var ch,l,w;t=t||nexttoken;if(t.id==='(end)'){t=token;} -l=t.line||0;ch=t.from||0;w={id:'(error)',raw:m,evidence:lines[l-1]||'',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);} -warnings+=1;if(warnings>=option.maxerr){quit("Too many errors.",l,ch);} -return w;} -function warningAt(m,l,ch,a,b,c,d){return warning(m,{line:l,from:ch},a,b,c,d);} -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);} -function errorAt(m,l,ch,a,b,c,d){return error(m,{line:l,from:ch},a,b,c,d);} -var lex=(function lex(){var character,from,line,s;function nextLine(){var at;if(line>=lines.length){return false;} -character=1;s=lines[line];line+=1;at=s.search(/ \t/);if(at>=0){warningAt("Mixed spaces and tabs.",line,at+1);} -s=s.replace(/\t/g,tab);at=s.search(cx);if(at>=0){warningAt("Unsafe character.",line,at);} -if(option.maxlen&&option.maxlen=0)||i==='return');} -return t;} -return{init:function(source){if(typeof source==='string'){lines=source.replace(/\r\n/g,'\n').replace(/\r/g,'\n').split('\n');}else{lines=source;} -line=0;nextLine();from=1;},range:function(begin,end){var c,value='';from=character;if(s.charAt(0)!==begin){errorAt("Expected '{a}' and instead saw '{b}'.",line,character,begin,s.charAt(0));} -for(;;){s=s.slice(1);character+=1;c=s.charAt(0);switch(c){case'':errorAt("Missing '{a}'.",line,character,c);break;case end:s=s.slice(1);character+=1;return it('(range)',value);case xquote:case'\\':warningAt("Unexpected '{a}'.",line,character,c);} -value+=c;}},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);from=character+l-r1.length;character+=l;return r1;}} -function string(x){var c,j,r='';if(jsonmode&&x!=='"'){warningAt("Strings must use doublequote.",line,character);} -if(xquote===x||(xmode==='scriptstring'&&!xquote)){return it('(punctuator)',x);} -function esc(n){var i=parseInt(s.substr(j+1,n),16);j+=n;if(i>=32&&i<=126&&i!==34&&i!==92&&i!==39){warningAt("Unnecessary escapement.",line,character);} -character+=n;c=String.fromCharCode(i);} -j=0;for(;;){while(j>=s.length){j=0;if(xmode!=='html'||!nextLine()){errorAt("Unclosed string.",line,from);}} -c=s.charAt(j);if(c===x){character+=1;s=s.substr(j+1);return it('(string)',r,x);} -if(c<' '){if(c==='\n'||c==='\r'){break;} -warningAt("Control character in string: {a}.",line,character+j,s.slice(0,j));}else if(c===xquote){warningAt("Bad HTML string",line,character+j);}else if(c==='<'){if(option.safe&&xmode==='html'){warningAt("ADsafe string violation.",line,character+j);}else if(s.charAt(j+1)==='/'&&(xmode||option.safe)){warningAt("Expected '<\\/' and instead saw '0){character+=1;s=s.slice(i);break;}else{if(!nextLine()){return it('(end)','');}}} -t=match(rx[xmode]||tx);if(!t){if(xmode==='html'){return it('(error)',s.charAt(0));}else{t='';c='';while(s&&s<'!'){s=s.substr(1);} -if(s){errorAt("Unexpected '{a}'.",line,character,s.substr(0,1));}}}else{if(c.isAlpha()||c==='_'||c==='$'){return it('(identifier)',t);} -if(c.isDigit()){if(xmode!=='style'&&!isFinite(Number(t))){warningAt("Bad number '{a}'.",line,character,t);} -if(xmode!=='style'&&xmode!=='styleproperty'&&s.substr(0,1).isAlpha()){warningAt("Missing space after '{a}'.",line,character,t);} -if(c==='0'){d=t.substr(1,1);if(d.isDigit()){if(token.id!=='.'&&xmode!=='styleproperty'){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);}} -if(t.substr(t.length-1)==='.'){warningAt("A trailing decimal point can be confused with a dot '{a}'.",line,character,t);} -return it('(number)',t);} -switch(t){case'"':case"'":return string(t);case'//':if(src||(xmode&&xmode!=='script')){warningAt("Unexpected comment.",line,character);}else if(xmode==='script'&&/<\s*\//i.test(s)){warningAt("Unexpected <\/ in comment.",line,character);}else if((option.safe||xmode==='script')&&ax.test(s)){warningAt("Dangerous comment.",line,character);} -s='';token.comment=true;break;case'/*':if(src||(xmode&&xmode!=='script'&&xmode!=='style'&&xmode!=='styleproperty')){warningAt("Unexpected comment.",line,character);} -if(option.safe&&ax.test(s)){warningAt("ADsafe comment violation.",line,character);} -for(;;){i=s.search(lx);if(i>=0){break;} -if(!nextLine()){errorAt("Unclosed comment.",line,character);}else{if(option.safe&&ax.test(s)){warningAt("ADsafe comment violation.",line,character);}}} -character+=i+2;if(s.substr(i,1)==='/'){errorAt("Nested comment.",line,character);} -s=s.substr(i+2);token.comment=true;break;case'/*members':case'/*member':case'/*jslint':case'/*global':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,'/');} -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;} -character+=l;s=s.substr(l);return it('(regexp)',c);case'\\':c=s.charAt(l);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);} -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;} -break;case'|':b=false;break;case')':if(depth===0){warningAt("Unescaped '{a}'.",line,from+l,')');}else{depth-=1;} -break;case' ':q=1;while(s.charAt(l)===' '){l+=1;q+=1;} -if(q>1){warningAt("Spaces are hard to count. Use {{a}}.",line,from+l,q);} -break;case'[':c=s.charAt(l);if(c==='^'){l+=1;if(option.regexp){warningAt("Insecure '{a}'.",line,from+l,c);}} -q=false;if(c===']'){warningAt("Empty class.",line,from+l-1);q=true;} -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;} -break;case']':if(!q){warningAt("Unescaped '{a}'.",line,from+l-1,'-');} -break klass;case'\\':c=s.charAt(l);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);} -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);}} -q=true;break;default:q=true;}}while(c);break;case'.':if(option.regexp){warningAt("Insecure '{a}'.",line,from+l,c);} -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);}}} -if(b){switch(s.charAt(l)){case'?':case'+':case'*':l+=1;if(s.charAt(l)==='?'){l+=1;} -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);} -l+=1;low=+c;for(;;){c=s.charAt(l);if(c<'0'||c>'9'){break;} -l+=1;low=+c+(low*10);} -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;} -l+=1;high=+c+(high*10);}}} -if(s.charAt(l)!=='}'){warningAt("Expected '{a}' and instead saw '{b}'.",line,from+l,'}',c);}else{l+=1;} -if(s.charAt(l)==='?'){l+=1;} -if(low>high){warningAt("'{a}' should not be greater than '{b}'.",line,from+l,low,high);}}}} -c=s.substr(0,l-1);character+=l;s=s.substr(l);return it('(regexp)',c);} -return it('(punctuator)',t);case'.",line,character);} -character+=3;s=s.slice(i+3);break;case'#':if(xmode==='html'||xmode==='styleproperty'){for(;;){c=s.charAt(0);if((c<'0'||c>'9')&&(c<'a'||c>'f')&&(c<'A'||c>'F')){break;} -character+=1;s=s.substr(1);t+=c;} -if(t.length!==4&&t.length!==7){warningAt("Bad hex color '{a}'.",line,from+l,t);} -return it('(color)',t);} -return it('(punctuator)',t);default:if(xmode==='outer'&&c==='&'){character+=1;s=s.substr(1);for(;;){c=s.charAt(0);character+=1;s=s.substr(1);if(c===';'){break;} -if(!((c>='0'&&c<='9')||(c>='a'&&c<='z')||c==='#')){errorAt("Bad entity",line,from+l,character);}} -break;} -return it('(punctuator)',t);}}}}};}());function addlabel(t,type){if(option.safe&&funct['(global)']&&typeof predefined[t]!=='boolean'){warning('ADsafe global: '+t+'.',token);}else if(t==='hasOwnProperty'){warning("'hasOwnProperty' is a really bad name.");} -if(is_own(funct,t)&&!funct['(global)']){warning(funct[t]===true?"'{a}' was used before it was defined.":"'{a}' is already defined.",nexttoken,t);} -funct[t]=type;if(funct['(global)']){global[t]=funct;if(is_own(implied,t)){warning("'{a}' was used before it was defined.",nexttoken,t);delete implied[t];}}else{scope[t]=funct;}} -function doOption(){var b,obj,filter,o=nexttoken.value,t,v;switch(o){case'*/':error("Unbegun comment.");break;case'/*members':case'/*member':o='/*members';if(!membersOnly){membersOnly={};} -obj=membersOnly;break;case'/*jslint':if(option.safe){warning("ADsafe restriction.");} -obj=option;filter=boolOptions;break;case'/*global':if(option.safe){warning("ADsafe restriction.");} -obj=predefined;break;default:} -t=lex.token();loop:for(;;){for(;;){if(t.type==='special'&&t.value==='*/'){break loop;} -if(t.id!=='(endline)'&&t.id!==','){break;} -t=lex.token();} -if(t.type!=='(string)'&&t.type!=='(identifier)'&&o!=='/*members'){error("Bad option.",t);} -v=lex.token();if(v.id===':'){v=lex.token();if(obj===membersOnly){error("Expected '{a}' and instead saw '{b}'.",t,'*/',':');} -if(t.value==='indent'&&o==='/*jslint'){b=+v.value;if(typeof b!=='number'||!isFinite(b)||b<=0||Math.floor(b)!==b){error("Expected a small integer and instead saw '{a}'.",v,v.value);} -obj.white=true;obj.indent=b;}else if(t.value==='maxerr'&&o==='/*jslint'){b=+v.value;if(typeof b!=='number'||!isFinite(b)||b<=0||Math.floor(b)!==b){error("Expected a small integer and instead saw '{a}'.",v,v.value);} -obj.maxerr=b;}else if(v.value==='true'){obj[t.value]=true;}else if(v.value==='false'){obj[t.value]=false;}else{error("Bad option value.",v);} -t=lex.token();}else{if(o==='/*jslint'){error("Missing option value.",t);} -obj[t.value]=false;t=v;}} -if(filter){assume();}} -function peek(p){var i=p||0,j=0,t;while(j<=i){t=lookahead[j];if(!t){t=lookahead[j]=lex.token();} -j+=1;} -return t;} -function advance(id,t){switch(token.id){case'(number)':if(nexttoken.id==='.'){warning("A dot following a number can be confused with a decimal point.",token);} -break;case'-':if(nexttoken.id==='-'||nexttoken.id==='--'){warning("Confusing minusses.");} -break;case'+':if(nexttoken.id==='+'||nexttoken.id==='++'){warning("Confusing plusses.");} -break;} -if(token.type==='(string)'||token.identifier){anonname=token.value;} -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,nexttoken.value);}}else if(nexttoken.type!=='(identifier)'||nexttoken.value!==id){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,id,nexttoken.value);}} -prevtoken=token;token=nexttoken;for(;;){nexttoken=lookahead.shift()||lex.token();if(nexttoken.id==='(end)'||nexttoken.id==='(error)'){return;} -if(nexttoken.type==='special'){doOption();}else{if(nexttoken.id!=='(endline)'){break;}}}} -function parse(rbp,initial){var left;if(nexttoken.id==='(end)'){error("Unexpected early end of program.",token);} -advance();if(option.safe&&typeof predefined[token.value]==='boolean'&&(nexttoken.id!=='('&&nexttoken.id!=='.')){warning('ADsafe violation.',token);} -if(initial){anonname='anonymous';funct['(verb)']=token.value;} -if(initial===true&&token.fud){left=token.fud();}else{if(token.nud){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);}} -while(rbp='a'&&c<='z')||(c>='A'&&c<='Z')){x.identifier=x.reserved=true;} -return x;} -function prefix(s,f){var x=symbol(s,150);reserveName(x);x.nud=(typeof f==='function')?f:function(){this.right=parse(150);this.arity='unary';if(this.id==='++'||this.id==='--'){if(option.plusplus){warning("Unexpected use of '{a}'.",this,this.id);}else if((!this.right.identifier||this.right.reserved)&&this.right.id!=='.'&&this.right.id!=='['){warning("Bad operand.",this);}} -return this;};return x;} -function type(s,f){var x=delim(s);x.type=s;x.nud=f;return x;} -function reserve(s,f){var x=type(s,f);x.identifier=x.reserved=true;return x;} -function reservevar(s,v){return reserve(s,function(){if(this.id==='this'||this.id==='arguments'){if(strict_mode&&funct['(global)']){warning("Strict violation.",this);}else if(option.safe){warning("ADsafe violation.",this);}} -return this;});} -function infix(s,f,p,w){var x=symbol(s,p);reserveName(x);x.led=function(left){if(!w){nobreaknonadjacent(prevtoken,token);nonadjacent(token,nexttoken);} -if(typeof f==='function'){return f(left,this);}else{this.left=left;this.right=parse(p);return this;}};return x;} -function relation(s,f){var x=symbol(s,100);x.led=function(left){nobreaknonadjacent(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]);} -if(left.id==='!'){warning("Confusing use of '{a}'.",left,'!');} -if(right.id==='!'){warning("Confusing use of '{a}'.",left,'!');} -this.left=left;this.right=right;return this;};return x;} -function isPoorRelation(node){return node&&((node.type==='(number)'&&+node.value===0)||(node.type==='(string)'&&node.value===' ')||node.type==='true'||node.type==='false'||node.type==='undefined'||node.type==='null');} -function assignop(s,f){symbol(s,20).exps=true;return infix(s,function(left,that){var l;that.left=left;if(predefined[left.value]===false&&scope[left.value]['(global)']===true){warning('Read only.',left);} -if(option.safe){l=left;do{if(typeof predefined[l.value]==='boolean'){warning('ADsafe violation.',l);} -l=l.left;}while(l);} -if(left){if(left.id==='.'||left.id==='['){if(!left.left||left.left.value==='arguments'){warning('Bad assignment.',that);} -that.right=parse(19);return that;}else if(left.identifier&&!left.reserved){if(funct[left.value]==='exception'){warning("Do not assign to the exception parameter.",left);} -that.right=parse(19);return that;} -if(left===syntax['function']){warning("Expected an identifier in an assignment and instead saw a function invocation.",token);}} -error("Bad assignment.",that);},20);} -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);} -this.left=left;this.right=parse(p);return this;};return x;} -function bitwiseassignop(s){symbol(s,20).exps=true;return infix(s,function(left,that){if(option.bitwise){warning("Unexpected use of '{a}'.",that,that.id);} -nonadjacent(prevtoken,token);nonadjacent(token,nexttoken);if(left){if(left.id==='.'||left.id==='['||(left.identifier&&!left.reserved)){parse(19);return that;} -if(left===syntax['function']){warning("Expected an identifier in an assignment, and instead saw a function invocation.",token);} -return that;} -error("Bad assignment.",that);},20);} -function suffix(s,f){var x=symbol(s,150);x.led=function(left){if(option.plusplus){warning("Unexpected use of '{a}'.",this,this.id);}else if((!left.identifier||left.reserved)&&left.id!=='.'&&left.id!=='['){warning("Bad operand.",this);} -this.left=left;return this;};return x;} -function optionalidentifier(){if(nexttoken.reserved){warning("Expected an identifier and instead saw '{a}' (a reserved word).",nexttoken,nexttoken.id);} -if(nexttoken.identifier){advance();return token.value;}} -function identifier(){var i=optionalidentifier();if(i){return i;} -if(token.id==='function'&&nexttoken.id==='('){warning("Missing name in function statement.");}else{error("Expected an identifier and instead saw '{a}'.",nexttoken,nexttoken.value);}} -function reachable(s){var i=0,t;if(nexttoken.id!==';'||noreach){return;} -for(;;){t=peek(i);if(t.reach){return;} -if(t.id!=='(endline)'){if(t.id==='function'){warning("Inner functions should be listed at the top of the outer function.",t);break;} -warning("Unreachable '{a}' after '{b}'.",t,t.value,s);break;} -i+=1;}} -function statement(noindent){var i=indent,r,s=scope,t=nexttoken;if(t.id===';'){warning("Unnecessary semicolon.",t);advance(';');return;} -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);} -if(jx.test(t.value+':')){warning("Label '{a}' looks like a javascript url.",t,t.value);} -nexttoken.label=t.value;t=nexttoken;} -if(!noindent){indentation();} -if(nexttoken.id==='new'){warning("'new' should not be used as a statement.");} -r=parse(0,true);if(!t.block){if(!r||!r.exps){warning("Expected an assignment or function call and instead saw an expression.",token);} -if(nexttoken.id!==';'){warningAt("Missing semicolon.",token.line,token.from+token.value.length);}else{adjacent(token,nexttoken);advance(';');nonadjacent(token,nexttoken);}} -indent=i;scope=s;return r;} -function use_strict(){if(nexttoken.value==='use strict'){advance();advance(';');strict_mode=true;return true;}else{return false;}} -function statements(begin){var a=[],f,p;if(begin&&!use_strict()&&option.strict){warning('Missing "use strict" statement.',nexttoken);} -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);}} -if(nexttoken.value==='ADSAFE'&&peek(0).id==='.'&&peek(1).value==='id'){if(adsafe_may){error('ADsafe violation.',nexttoken);} -advance('ADSAFE');advance('.');advance('id');advance('(');if(nexttoken.value!==adsafe_id){error('ADsafe violation: id does not match.',nexttoken);} -advance('(string)');advance(')');advance(';');adsafe_may=true;} -break;case'lib':if(nexttoken.value==='ADSAFE'){advance('ADSAFE');advance('.');advance('lib');advance('(');advance('(string)');comma();f=parse(0);if(f.id!=='function'){error('The second argument to lib must be a function.',f);} -p=f.funct['(params)'];p=p&&p.join(', ');if(p&&p!=='lib'){error("Expected '{a}' and instead saw '{b}'.",f,'(lib)','('+p+')');} -advance(')');advance(';');return a;}else{error("ADsafe lib violation.");}}} -while(!nexttoken.reach&&nexttoken.id!=='(end)'){if(nexttoken.id===';'){warning("Unnecessary semicolon.");advance(';');}else{a.push(statement());}} -return a;} -function block(f){var a,b=inblock,old_indent=indent,s=scope,t;inblock=f;scope=Object.create(scope);nonadjacent(token,nexttoken);t=nexttoken;if(nexttoken.id==='{'){advance('{');if(nexttoken.id!=='}'||token.line!==nexttoken.line){indent+=option.indent;while(!f&&nexttoken.from>indent){indent+=option.indent;} -if(!f){use_strict();} -a=statements();indent-=option.indent;indentation();} -advance('}',t);indent=old_indent;}else{warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'{',nexttoken.value);noreach=true;a=[statement()];noreach=false;} -funct['(verb)']=null;scope=s;inblock=b;return a;} -function idValue(){return this;} -function countMember(m){if(membersOnly&&typeof membersOnly[m]!=='boolean'){warning("Unexpected /*member '{a}'.",token,m);} -if(typeof member[m]==='number'){member[m]+=1;}else{member[m]=1;}} -function note_implied(token){var name=token.value,line=token.line,a=implied[name];if(typeof a==='function'){a=false;} -if(!a){a=[line];implied[name]=a;}else if(a[a.length-1]!==line){a.push(line);}} -function cssName(){if(nexttoken.identifier){advance();return true;}} -function cssNumber(){if(nexttoken.id==='-'){advance('-');adjacent();nolinebreak();} -if(nexttoken.type==='(number)'){advance('(number)');return true;}} -function cssString(){if(nexttoken.type==='(string)'){advance();return true;}} -function cssColor(){var i,number;if(nexttoken.identifier){if(nexttoken.value==='rgb'){advance();advance('(');for(i=0;i<3;i+=1){if(i){advance(',');} -number=nexttoken.value;if(nexttoken.type!=='(number)'||number<0){warning("Expected a positive number and instead saw '{a}'",nexttoken,number);advance();}else{advance();if(nexttoken.id==='%'){advance('%');if(number>100){warning("Expected a percentage and instead saw '{a}'",token,number);}}else{if(number>255){warning("Expected a small number and instead saw '{a}'",token,number);}}}} -advance(')');return true;}else if(cssColorData[nexttoken.value]===true){advance();return true;}}else if(nexttoken.type==='(color)'){advance();return true;} -return false;} -function cssLength(){if(nexttoken.id==='-'){advance('-');adjacent();nolinebreak();} -if(nexttoken.type==='(number)'){advance();if(nexttoken.type!=='(string)'&&cssLengthData[nexttoken.value]===true){adjacent();advance();}else if(+token.value!==0){warning("Expected a linear unit and instead saw '{a}'.",nexttoken,nexttoken.value);} -return true;} -return false;} -function cssLineHeight(){if(nexttoken.id==='-'){advance('-');adjacent();} -if(nexttoken.type==='(number)'){advance();if(nexttoken.type!=='(string)'&&cssLengthData[nexttoken.value]===true){adjacent();advance();} -return true;} -return false;} -function cssWidth(){if(nexttoken.identifier){switch(nexttoken.value){case'thin':case'medium':case'thick':advance();return true;}}else{return cssLength();}} -function cssMargin(){if(nexttoken.identifier){if(nexttoken.value==='auto'){advance();return true;}}else{return cssLength();}} -function cssAttr(){if(nexttoken.identifier&&nexttoken.value==='attr'){advance();advance('(');if(!nexttoken.identifier){warning("Expected a name and instead saw '{a}'.",nexttoken,nexttoken.value);} -advance();advance(')');return true;} -return false;} -function cssCommaList(){while(nexttoken.id!==';'){if(!cssName()&&!cssString()){warning("Expected a name and instead saw '{a}'.",nexttoken,nexttoken.value);} -if(nexttoken.id!==','){return true;} -comma();}} -function cssCounter(){if(nexttoken.identifier&&nexttoken.value==='counter'){advance();advance('(');if(!nexttoken.identifier){} -advance();if(nexttoken.id===','){comma();if(nexttoken.type!=='(string)'){warning("Expected a string and instead saw '{a}'.",nexttoken,nexttoken.value);} -advance();} -advance(')');return true;} -if(nexttoken.identifier&&nexttoken.value==='counters'){advance();advance('(');if(!nexttoken.identifier){warning("Expected a name and instead saw '{a}'.",nexttoken,nexttoken.value);} -advance();if(nexttoken.id===','){comma();if(nexttoken.type!=='(string)'){warning("Expected a string and instead saw '{a}'.",nexttoken,nexttoken.value);} -advance();} -if(nexttoken.id===','){comma();if(nexttoken.type!=='(string)'){warning("Expected a string and instead saw '{a}'.",nexttoken,nexttoken.value);} -advance();} -advance(')');return true;} -return false;} -function cssShape(){var i;if(nexttoken.identifier&&nexttoken.value==='rect'){advance();advance('(');for(i=0;i<4;i+=1){if(!cssLength()){warning("Expected a number and instead saw '{a}'.",nexttoken,nexttoken.value);break;}} -advance(')');return true;} -return false;} -function cssUrl(){var c,url;if(nexttoken.identifier&&nexttoken.value==='url'){nexttoken=lex.range('(',')');url=nexttoken.value;c=url.charAt(0);if(c==='"'||c==='\''){if(url.slice(-1)!==c){warning("Bad url string.");}else{url=url.slice(1,-1);if(url.indexOf(c)>=0){warning("Bad url string.");}}} -if(!url){warning("Missing url.");} -advance();if(option.safe&&ux.test(url)){error("ADsafe URL violation.");} -urls.push(url);return true;} -return false;} -cssAny=[cssUrl,function(){for(;;){if(nexttoken.identifier){switch(nexttoken.value.toLowerCase()){case'url':cssUrl();break;case'expression':warning("Unexpected expression '{a}'.",nexttoken,nexttoken.value);advance();break;default:advance();}}else{if(nexttoken.id===';'||nexttoken.id==='!'||nexttoken.id==='(end)'||nexttoken.id==='}'){return true;} -advance();}}}];cssBorderStyle=['none','hidden','dotted','dashed','solid','double','ridge','inset','outset'];cssBreak=['auto','always','avoid','left','right'];cssOverflow=['auto','hidden','scroll','visible'];cssAttributeData={background:[true,'background-attachment','background-color','background-image','background-position','background-repeat'],'background-attachment':['scroll','fixed'],'background-color':['transparent',cssColor],'background-image':['none',cssUrl],'background-position':[2,[cssLength,'top','bottom','left','right','center']],'background-repeat':['repeat','repeat-x','repeat-y','no-repeat'],'border':[true,'border-color','border-style','border-width'],'border-bottom':[true,'border-bottom-color','border-bottom-style','border-bottom-width'],'border-bottom-color':cssColor,'border-bottom-style':cssBorderStyle,'border-bottom-width':cssWidth,'border-collapse':['collapse','separate'],'border-color':['transparent',4,cssColor],'border-left':[true,'border-left-color','border-left-style','border-left-width'],'border-left-color':cssColor,'border-left-style':cssBorderStyle,'border-left-width':cssWidth,'border-right':[true,'border-right-color','border-right-style','border-right-width'],'border-right-color':cssColor,'border-right-style':cssBorderStyle,'border-right-width':cssWidth,'border-spacing':[2,cssLength],'border-style':[4,cssBorderStyle],'border-top':[true,'border-top-color','border-top-style','border-top-width'],'border-top-color':cssColor,'border-top-style':cssBorderStyle,'border-top-width':cssWidth,'border-width':[4,cssWidth],bottom:[cssLength,'auto'],'caption-side':['bottom','left','right','top'],clear:['both','left','none','right'],clip:[cssShape,'auto'],color:cssColor,content:['open-quote','close-quote','no-open-quote','no-close-quote',cssString,cssUrl,cssCounter,cssAttr],'counter-increment':[cssName,'none'],'counter-reset':[cssName,'none'],cursor:[cssUrl,'auto','crosshair','default','e-resize','help','move','n-resize','ne-resize','nw-resize','pointer','s-resize','se-resize','sw-resize','w-resize','text','wait'],direction:['ltr','rtl'],display:['block','compact','inline','inline-block','inline-table','list-item','marker','none','run-in','table','table-caption','table-cell','table-column','table-column-group','table-footer-group','table-header-group','table-row','table-row-group'],'empty-cells':['show','hide'],'float':['left','none','right'],font:['caption','icon','menu','message-box','small-caption','status-bar',true,'font-size','font-style','font-weight','font-family'],'font-family':cssCommaList,'font-size':['xx-small','x-small','small','medium','large','x-large','xx-large','larger','smaller',cssLength],'font-size-adjust':['none',cssNumber],'font-stretch':['normal','wider','narrower','ultra-condensed','extra-condensed','condensed','semi-condensed','semi-expanded','expanded','extra-expanded'],'font-style':['normal','italic','oblique'],'font-variant':['normal','small-caps'],'font-weight':['normal','bold','bolder','lighter',cssNumber],height:[cssLength,'auto'],left:[cssLength,'auto'],'letter-spacing':['normal',cssLength],'line-height':['normal',cssLineHeight],'list-style':[true,'list-style-image','list-style-position','list-style-type'],'list-style-image':['none',cssUrl],'list-style-position':['inside','outside'],'list-style-type':['circle','disc','square','decimal','decimal-leading-zero','lower-roman','upper-roman','lower-greek','lower-alpha','lower-latin','upper-alpha','upper-latin','hebrew','katakana','hiragana-iroha','katakana-oroha','none'],margin:[4,cssMargin],'margin-bottom':cssMargin,'margin-left':cssMargin,'margin-right':cssMargin,'margin-top':cssMargin,'marker-offset':[cssLength,'auto'],'max-height':[cssLength,'none'],'max-width':[cssLength,'none'],'min-height':cssLength,'min-width':cssLength,opacity:cssNumber,outline:[true,'outline-color','outline-style','outline-width'],'outline-color':['invert',cssColor],'outline-style':['dashed','dotted','double','groove','inset','none','outset','ridge','solid'],'outline-width':cssWidth,overflow:cssOverflow,'overflow-x':cssOverflow,'overflow-y':cssOverflow,padding:[4,cssLength],'padding-bottom':cssLength,'padding-left':cssLength,'padding-right':cssLength,'padding-top':cssLength,'page-break-after':cssBreak,'page-break-before':cssBreak,position:['absolute','fixed','relative','static'],quotes:[8,cssString],right:[cssLength,'auto'],'table-layout':['auto','fixed'],'text-align':['center','justify','left','right'],'text-decoration':['none','underline','overline','line-through','blink'],'text-indent':cssLength,'text-shadow':['none',4,[cssColor,cssLength]],'text-transform':['capitalize','uppercase','lowercase','none'],top:[cssLength,'auto'],'unicode-bidi':['normal','embed','bidi-override'],'vertical-align':['baseline','bottom','sub','super','top','text-top','middle','text-bottom',cssLength],visibility:['visible','hidden','collapse'],'white-space':['normal','nowrap','pre','pre-line','pre-wrap','inherit'],width:[cssLength,'auto'],'word-spacing':['normal',cssLength],'word-wrap':['break-word','normal'],'z-index':['auto',cssNumber]};function styleAttribute(){var v;while(nexttoken.id==='*'||nexttoken.id==='#'||nexttoken.value==='_'){if(!option.css){warning("Unexpected '{a}'.",nexttoken,nexttoken.value);} -advance();} -if(nexttoken.id==='-'){if(!option.css){warning("Unexpected '{a}'.",nexttoken,nexttoken.value);} -advance('-');if(!nexttoken.identifier){warning("Expected a non-standard style attribute and instead saw '{a}'.",nexttoken,nexttoken.value);} -advance();return cssAny;}else{if(!nexttoken.identifier){warning("Excepted a style attribute, and instead saw '{a}'.",nexttoken,nexttoken.value);}else{if(is_own(cssAttributeData,nexttoken.value)){v=cssAttributeData[nexttoken.value];}else{v=cssAny;if(!option.css){warning("Unrecognized style attribute '{a}'.",nexttoken,nexttoken.value);}}} -advance();return v;}} -function styleValue(v){var i=0,n,once,match,round,start=0,vi;switch(typeof v){case'function':return v();case'string':if(nexttoken.identifier&&nexttoken.value===v){advance();return true;} -return false;} -for(;;){if(i>=v.length){return false;} -vi=v[i];i+=1;if(vi===true){break;}else if(typeof vi==='number'){n=vi;vi=v[i];i+=1;}else{n=1;} -match=false;while(n>0){if(styleValue(vi)){match=true;n-=1;}else{break;}} -if(match){return true;}} -start=i;once=[];for(;;){round=false;for(i=start;i':case'+':advance();styleSelector();break;case':':advance(':');switch(nexttoken.value){case'active':case'after':case'before':case'checked':case'disabled':case'empty':case'enabled':case'first-child':case'first-letter':case'first-line':case'first-of-type':case'focus':case'hover':case'last-of-type':case'link':case'only-of-type':case'root':case'target':case'visited':advance();break;case'lang':advance();advance('(');if(!nexttoken.identifier){warning("Expected a lang code, and instead saw :{a}.",nexttoken,nexttoken.value);} -advance(')');break;case'nth-child':case'nth-last-child':case'nth-last-of-type':case'nth-of-type':advance();advance('(');styleChild();advance(')');break;case'not':advance();advance('(');if(nexttoken.id===':'&&peek(0).value==='not'){warning("Nested not.");} -styleSelector();advance(')');break;default:warning("Expected a pseudo, and instead saw :{a}.",nexttoken,nexttoken.value);} -break;case'#':advance('#');if(!nexttoken.identifier){warning("Expected an id, and instead saw #{a}.",nexttoken,nexttoken.value);} -advance();break;case'*':advance('*');break;case'.':advance('.');if(!nexttoken.identifier){warning("Expected a class, and instead saw #.{a}.",nexttoken,nexttoken.value);} -advance();break;case'[':advance('[');if(!nexttoken.identifier){warning("Expected an attribute, and instead saw [{a}].",nexttoken,nexttoken.value);} -advance();if(nexttoken.id==='='||nexttoken.value==='~='||nexttoken.value==='$='||nexttoken.value==='|='||nexttoken.id==='*='||nexttoken.id==='^='){advance();if(nexttoken.type!=='(string)'){warning("Expected a string, and instead saw {a}.",nexttoken,nexttoken.value);} -advance();} -advance(']');break;default:error("Expected a CSS selector, and instead saw {a}.",nexttoken,nexttoken.value);}}} -function stylePattern(){var name;if(nexttoken.id==='{'){warning("Expected a style pattern, and instead saw '{a}'.",nexttoken,nexttoken.id);}else if(nexttoken.id==='@'){advance('@');name=nexttoken.value;if(nexttoken.identifier&&atrule[name]===true){advance();return name;} -warning("Expected an at-rule, and instead saw @{a}.",nexttoken,name);} -for(;;){styleSelector();if(nexttoken.id===' fragments and .js files.",token);} -if(option.fragment){if(n!=='div'){error("ADsafe violation: Wrap the widget in a div.",token);}}else{error("Use the fragment option.",token);}} -option.browser=true;assume();} -function doAttribute(n,a,v){var u,x;if(a==='id'){u=typeof v==='string'?v.toUpperCase():'';if(ids[u]===true){warning("Duplicate id='{a}'.",nexttoken,v);} -if(option.adsafe){if(adsafe_id){if(v.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-Z]+$/.test(v)){warning("ADSAFE violation: bad id.");}}else{adsafe_id=v;if(!/^[A-Z]+_$/.test(v)){warning("ADSAFE violation: bad id.");}}} -x=v.search(dx);if(x>=0){warning("Unexpected character '{a}' in {b}.",token,v.charAt(x),a);} -ids[u]=true;}else if(a==='class'||a==='type'||a==='name'){x=v.search(qx);if(x>=0){warning("Unexpected character '{a}' in {b}.",token,v.charAt(x),a);} -ids[u]=true;}else if(a==='href'||a==='background'||a==='content'||a==='data'||a.indexOf('src')>=0||a.indexOf('url')>=0){if(option.safe&&ux.test(v)){error("ADsafe URL violation.");} -urls.push(v);}else if(a==='for'){if(option.adsafe){if(adsafe_id){if(v.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-Z]+$/.test(v)){warning("ADSAFE violation: bad id.");}}else{warning("ADSAFE violation: bad id.");}}}else if(a==='name'){if(option.adsafe&&v.indexOf('_')>=0){warning("ADsafe name violation.");}}} -function doTag(n,a){var i,t=htmltag[n],x;src=false;if(!t){error("Unrecognized tag '<{a}>'.",nexttoken,n===n.toLowerCase()?n:n+' (capitalization error)');} -if(stack.length>0){if(n==='html'){error("Too many tags.",token);} -x=t.parent;if(x){if(x.indexOf(' '+stack[stack.length-1].name+' ')<0){error("A '<{a}>' must be within '<{b}>'.",token,n,x);}}else if(!option.adsafe&&!option.fragment){i=stack.length;do{if(i<=0){error("A '<{a}>' must be within '<{b}>'.",token,n,'body');} -i-=1;}while(stack[i].name!=='body');}} -switch(n){case'div':if(option.adsafe&&stack.length===1&&!adsafe_id){warning("ADSAFE violation: missing ID_.");} -break;case'script':xmode='script';advance('>');indent=nexttoken.from;if(a.lang){warning("lang is deprecated.",token);} -if(option.adsafe&&stack.length!==1){warning("ADsafe script placement violation.",token);} -if(a.src){if(option.adsafe&&(!adsafe_may||!approved[a.src])){warning("ADsafe unapproved script source.",token);} -if(a.type){warning("type is unnecessary.",token);}}else{if(adsafe_went){error("ADsafe script violation.",token);} -statements('script');} -xmode='html';advance('');styles();xmode='html';advance('';} -function html(){var a,attributes,e,n,q,t,v,w=option.white,wmode;xmode='html';xquote='';stack=null;for(;;){switch(nexttoken.value){case'<':xmode='html';advance('<');attributes={};t=nexttoken;if(!t.identifier){warning("Bad identifier {a}.",t,t.value);} -n=t.value;if(option.cap){n=n.toLowerCase();} -t.name=n;advance();if(!stack){stack=[];doBegin(n);} -v=htmltag[n];if(typeof v!=='object'){error("Unrecognized tag '<{a}>'.",t,n);} -e=v.empty;t.type=n;for(;;){if(nexttoken.id==='/'){advance('/');if(nexttoken.id!=='>'){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'>',nexttoken.value);} -break;} -if(nexttoken.id&&nexttoken.id.substr(0,1)==='>'){break;} -if(!nexttoken.identifier){if(nexttoken.id==='(end)'||nexttoken.id==='(error)'){error("Missing '>'.",nexttoken);} -warning("Bad identifier.");} -option.white=true;nonadjacent(token,nexttoken);a=nexttoken.value;option.white=w;advance();if(!option.cap&&a!==a.toLowerCase()){warning("Attribute '{a}' not all lower case.",nexttoken,a);} -a=a.toLowerCase();xquote='';if(is_own(attributes,a)){warning("Attribute '{a}' repeated.",nexttoken,a);} -if(a.slice(0,2)==='on'){if(!option.on){warning("Avoid HTML event handlers.");} -xmode='scriptstring';advance('=');q=nexttoken.id;if(q!=='"'&&q!=="'"){error("Missing quote.");} -xquote=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.");} -xmode='html';xquote='';advance(q);v=false;}else if(a==='style'){xmode='scriptstring';advance('=');q=nexttoken.id;if(q!=='"'&&q!=="'"){error("Missing quote.");} -xmode='styleproperty';xquote=q;advance(q);substyle();xmode='html';xquote='';advance(q);v=false;}else{if(nexttoken.id==='='){advance('=');v=nexttoken.value;if(!nexttoken.identifier&&nexttoken.id!=='"'&&nexttoken.id!=='\''&&nexttoken.type!=='(string)'&&nexttoken.type!=='(number)'&&nexttoken.type!=='(color)'){warning("Expected an attribute value and instead saw '{a}'.",token,a);} -advance();}else{v=true;}} -attributes[a]=v;doAttribute(n,a,v);} -doTag(n,attributes);if(!e){stack.push(t);} -xmode='outer';advance('>');break;case''){error("Missing '{a}'.",nexttoken,'>');} -xmode='outer';advance('>');break;case''||nexttoken.id==='(end)'){break;} -if(nexttoken.value.indexOf('--')>=0){warning("Unexpected --.");} -if(nexttoken.value.indexOf('<')>=0){warning("Unexpected <.");} -if(nexttoken.value.indexOf('>')>=0){warning("Unexpected >.");}} -xmode='outer';advance('>');break;case'(end)':return;default:if(nexttoken.id==='(end)'){error("Missing '{a}'.",nexttoken,'');}else{advance();}} -if(stack&&stack.length===0&&(option.adsafe||!option.fragment||nexttoken.id==='(end)')){break;}} -if(nexttoken.id!=='(end)'){error("Unexpected material after the end.");}} -type('(number)',idValue);type('(string)',idValue);syntax['(identifier)']={type:'(identifier)',lbp:0,identifier:true,nud:function(){var v=this.value,s=scope[v],f;if(typeof s==='function'){s=undefined;}else if(typeof s==='boolean'){f=funct;funct=functions[0];addlabel(v,'var');s=funct;funct=f;} -if(funct===s){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&&predefined[v]!=='boolean'){warning("'{a}' is not defined.",token,v);} -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'global':break;default:if(s===true){funct[v]=true;}else if(s===null){warning("'{a}' is not allowed.",token,v);note_implied(token);}else if(typeof s!=='object'){if(option.undef){warning("'{a}' is not defined.",token,v);}else{funct[v]=true;} -note_implied(token);}else{switch(s[v]){case'function':case'var':case'unused':s[v]='closure';funct[v]=s['(global)']?'global':'outer';break;case'closure':case'parameter':funct[v]=s['(global)']?'global':'outer';break;case'label':warning("'{a}' is a statement label.",token,v);}}}} -return this;},led:function(){error("Expected an operator and instead saw '{a}'.",nexttoken,nexttoken.value);}};type('(regexp)',function(){return this;});delim('(endline)');delim('(begin)');delim('(end)').reach=true;delim('');delim('(error)').reach=true;delim('}').reach=true;delim(')');delim(']');delim('"').reach=true;delim("'").reach=true;delim(';');delim(':').reach=true;delim(',');delim('#');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,that){that.left=left;that.right=parse(10);advance(':');that['else']=parse(10);return that;},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);} -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);} -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,that){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);} -return left;} -that.left=left;that.right=right;return that;},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||(p.id!=='.'&&p.id!=='[')){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'.',nexttoken.value);} -this.first=p;return this;}).exps=true;prefix('~',function(){if(option.bitwise){warning("Unexpected '{a}'.",this,'~');} -parse(150);return this;});prefix('!',function(){this.right=parse(150);this.arity='unary';if(bang[this.right.id]===true){warning("Confusing use of '{a}'.",this,'!');} -return this;});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':if(nexttoken.id!=='('){warning("Use the array literal notation [].",token);}else{advance('(');if(nexttoken.id===')'){warning("Use the array literal notation [].",token);}else{i=parse(0);c.dimension=i;if((i.id==='(number)'&&/[.+\-Ee]/.test(i.value))||(i.id==='-'&&!i.right)||i.id==='(string)'||i.id==='['||i.id==='{'||i.id==='true'||i.id==='false'||i.id==='null'||i.id==='undefined'||i.id==='Infinity'){warning("Use the array literal notation [].",token);} -if(nexttoken.id!==')'){error("Use the array literal notation [].",token);}} -advance(')');} -this.first=c;return this;case'Number':case'String':case'Boolean':case'Math':case'JSON':warning("Do not use {a} as a constructor.",token,c.value);break;case'Function':if(!option.evil){warning("The Function constructor is eval.");} -break;case'Date':case'RegExp':break;default:if(c.id!=='function'){i=c.value.substr(0,1);if(option.newcap&&(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);} -adjacent(token,nexttoken);if(nexttoken.id!=='('){warning("Missing '()' invoking a constructor.");} -this.first=c;return this;});syntax['new'].exps=true;infix('.',function(left,that){adjacent(prevtoken,token);var m=identifier();if(typeof m==='string'){countMember(m);} -that.left=left;that.right=m;if(!option.evil&&left&&left.value==='document'&&(m==='write'||m==='writeln')){warning("document.write can be a form of eval.",left);}else if(option.adsafe){if(left&&left.value==='ADSAFE'){if(m==='id'||m==='lib'){warning("ADsafe violation.",that);}else if(m==='go'){if(xmode!=='script'){warning("ADsafe violation.",that);}else if(adsafe_went||nexttoken.id!=='('||peek(0).id!=='(string)'||peek(0).value!==adsafe_id||peek(1).id!==','){error("ADsafe violation: go.",that);} -adsafe_went=true;adsafe_may=false;}}} -if(!option.evil&&(m==='eval'||m==='execScript')){warning('eval is evil.');}else if(option.safe){for(;;){if(banned[m]===true){warning("ADsafe restricted word '{a}'.",token,m);} -if(typeof predefined[left.value]!=='boolean'||nexttoken.id==='('){break;} -if(standard_member[m]===true){if(nexttoken.id==='.'){warning("ADsafe violation.",that);} -break;} -if(nexttoken.id!=='.'){warning("ADsafe violation.",that);break;} -advance('.');token.left=that;token.right=m;that=token;m=identifier();if(typeof m==='string'){countMember(m);}}} -return that;},160,true);infix('(',function(left,that){adjacent(prevtoken,token);nospace();var n=0,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 if(option.newcap){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);}}} -if(nexttoken.id!==')'){for(;;){p[p.length]=parse(10);n+=1;if(nexttoken.id!==','){break;} -comma();}} -advance(')');if(option.immed&&left.id==='function'&&nexttoken.id!==')'){warning("Wrap the entire immediate function invocation in parens.",that);} -nospace(prevtoken,token);if(typeof left==='object'){if(left.value==='parseInt'&&n===1){warning("Missing radix parameter.",left);} -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);}} -if(!left.identifier&&left.id!=='.'&&left.id!=='['&&left.id!=='('&&left.id!=='&&'&&left.id!=='||'&&left.id!=='?'){warning("Bad invocation.",left);}} -that.left=left;return that;},155,true).exps=true;prefix('(',function(){nospace();var v=parse(0);advance(')',this);nospace(prevtoken,token);if(option.immed&&v.id==='function'){if(nexttoken.id==='('){warning("Move the invocation into the parens that contain the function.",nexttoken);}else{warning("Do not wrap function literals in parens unless they are to be immediately invoked.",this);}} -return v;});infix('[',function(left,that){nospace();var e=parse(0),s;if(e&&e.type==='(string)'){if(option.safe&&banned[e.value]===true){warning("ADsafe restricted word '{a}'.",that,e.value);}else if(!option.evil&&(e.value==='eval'||e.value==='execScript')){warning("eval is evil.",that);}else if(option.safe&&(e.value.charAt(0)==='_'||e.value.charAt(0)==='-')){warning("ADsafe restricted subscript '{a}'.",that,e.value);} -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)'||e.value<0){if(option.safe){warning('ADsafe subscripting.');}} -advance(']',that);nospace(prevtoken,token);that.left=left;that.right=e;return that;},160,true);prefix('[',function(){var b=token.line!==nexttoken.line;this.first=[];if(b){indent+=option.indent;if(nexttoken.from===indent+option.indent){indent+=option.indent;}} -while(nexttoken.id!=='(end)'){while(nexttoken.id===','){warning("Extra comma.");advance(',');} -if(nexttoken.id===']'){break;} -if(b&&token.line!==nexttoken.line){indentation();} -this.first.push(parse(10));if(nexttoken.id===','){comma();if(nexttoken.id===']'){warning("Extra comma.",token);break;}}else{break;}} -if(b){indent-=option.indent;indentation();} -advance(']',this);return this;},160);(function(x){x.nud=function(){var b,i,s,seen={};b=token.line!==nexttoken.line;if(b){indent+=option.indent;if(nexttoken.from===indent+option.indent){indent+=option.indent;}} -for(;;){if(nexttoken.id==='}'){break;} -if(b){indentation();} -i=optionalidentifier(true);if(!i){if(nexttoken.id==='(string)'){i=nexttoken.value;if(ix.test(i)){s=syntax[i];} -advance();}else if(nexttoken.id==='(number)'){i=nexttoken.value.toString();advance();}else{error("Expected '{a}' and instead saw '{b}'.",nexttoken,'}',nexttoken.value);}} -if(seen[i]===true){warning("Duplicate member '{a}'.",nexttoken,i);} -seen[i]=true;countMember(i);advance(':');nonadjacent(token,nexttoken);parse(10);if(nexttoken.id===','){comma();if(nexttoken.id===','||nexttoken.id==='}'){warning("Extra comma.",token);}}else{break;}} -if(b){indent-=option.indent;indentation();} -advance('}',this);return this;};x.fud=function(){error("Expected to see a statement and instead saw a block.",token);};}(delim('{')));function varstatement(prefix){var id,name,value;if(funct['(onevar)']&&option.onevar){warning("Too many var statements.");}else if(!funct['(global)']){funct['(onevar)']=true;} -this.first=[];for(;;){nonadjacent(token,nexttoken);id=identifier();if(funct['(global)']&&predefined[id]===false){warning("Redefinition of '{a}'.",token,id);} -addlabel(id,'unused');if(prefix){break;} -name=token;this.first.push(token);if(nexttoken.id==='='){nonadjacent(token,nexttoken);advance('=');nonadjacent(token,nexttoken);if(peek(0).id==='='&&nexttoken.identifier){error("Variable {a} was not declared correctly.",nexttoken,nexttoken.value);} -value=parse(0);name.first=value;} -if(nexttoken.id!==','){break;} -comma();} -return this;} -stmt('var',varstatement).exps=true;function functionparams(){var i,t=nexttoken,p=[];advance('(');nospace();if(nexttoken.id===')'){advance(')');nospace(prevtoken,token);return;} -for(;;){i=identifier();p.push(i);addlabel(i,'parameter');if(nexttoken.id===','){comma();}else{advance(')',t);nospace(prevtoken,token);return p;}}} -function doFunction(i){var s=scope;scope=Object.create(s);funct={'(name)':i||'"'+anonname+'"','(line)':nexttoken.line,'(context)':funct,'(breakage)':0,'(loopage)':0,'(scope)':scope};token.funct=funct;functions.push(funct);if(i){addlabel(i,'function');} -funct['(params)']=functionparams();block(false);scope=s;funct['(last)']=token.line;funct=funct['(context)'];} -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);} -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 whole function invocation in parens.");} -return this;});prefix('function',function(){var i=optionalidentifier();if(i){adjacent(token,nexttoken);}else{nonadjacent(token,nexttoken);} -doFunction(i);if(funct['(loopage)']&&nexttoken.id!=='('){warning("Be careful when making functions within a loop. Consider putting the function in a closure.");} -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);} -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);}} -return this;});blockstmt('try',function(){var b,e,s;if(option.adsafe){warning("ADsafe try violation.",this);} -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,'exception');} -advance();advance(')');block(false);b=true;scope=s;} -if(nexttoken.id==='finally'){advance('finally');block(false);return;}else if(!b){error("Expected '{a}' and instead saw '{b}'.",nexttoken,'catch',nexttoken.value);} -return this;});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);} -advance(')',t);nospace(prevtoken,token);block(true);funct['(breakage)']-=1;funct['(loopage)']-=1;return this;}).labelled=true;reserve('with');blockstmt('switch',function(){var t=nexttoken,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);} -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);} -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);} -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.");} -return this;}).exps=true;(function(){var x=stmt('do',function(){funct['(breakage)']+=1;funct['(loopage)']+=1;this.first=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);} -advance(')',t);nospace(prevtoken,token);funct['(breakage)']-=1;funct['(loopage)']-=1;return this;});x.labelled=true;x.exps=true;}());blockstmt('for',function(){var f=option.forin,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{switch(funct[nexttoken.value]){case'unused':funct[nexttoken.value]='var';break;case'var':break;default:warning("Bad for in variable '{a}'.",nexttoken,nexttoken.value);} -advance();} -advance('in');parse(20);advance(')',t);s=block(true);if(!f&&(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);} -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;} -comma();}}} -nolinebreak(token);advance(';');if(nexttoken.id!==';'){parse(20);if(nexttoken.id==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}} -nolinebreak(token);advance(';');if(nexttoken.id===';'){error("Expected '{a}' and instead saw '{b}'.",nexttoken,')',';');} -if(nexttoken.id!==')'){for(;;){parse(0,'for');if(nexttoken.id!==','){break;} -comma();}} -advance(')',t);nospace(prevtoken,token);block(true);funct['(breakage)']-=1;funct['(loopage)']-=1;return this;}}).labelled=true;stmt('break',function(){var v=nexttoken.value;if(funct['(breakage)']===0){warning("Unexpected '{a}'.",nexttoken,this.value);} -nolinebreak(this);if(nexttoken.id!==';'){if(token.line===nexttoken.line){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);} -this.first=nexttoken;advance();}} -reachable('break');return this;}).exps=true;stmt('continue',function(){var v=nexttoken.value;if(funct['(breakage)']===0){warning("Unexpected '{a}'.",nexttoken,this.value);} -nolinebreak(this);if(nexttoken.id!==';'){if(token.line===nexttoken.line){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);} -this.first=nexttoken;advance();}} -reachable('continue');return this;}).exps=true;stmt('return',function(){nolinebreak(this);if(nexttoken.id==='(regexp)'){warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");} -if(nexttoken.id!==';'&&!nexttoken.reach){nonadjacent(token,nexttoken);this.first=parse(20);} -reachable('return');return this;}).exps=true;stmt('throw',function(){nolinebreak(this);nonadjacent(token,nexttoken);this.first=parse(20);reachable('throw');return this;}).exps=true;reserve('void');reserve('class');reserve('const');reserve('enum');reserve('export');reserve('extends');reserve('import');reserve('super');reserve('let');reserve('yield');reserve('implements');reserve('interface');reserve('package');reserve('private');reserve('protected');reserve('public');reserve('static');function jsonValue(){function jsonObject(){var o={},t=nexttoken;advance('{');if(nexttoken.id!=='}'){for(;;){if(nexttoken.id==='(end)'){error("Missing '}' to match '{' from line {a}.",nexttoken,t.line);}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);} -if(o[nexttoken.value]===true){warning("Duplicate key '{a}'.",nexttoken,nexttoken.value);}else if(nexttoken.value==='__proto__'){warning("Stupid key '{a}'.",nexttoken,nexttoken.value);}else{o[nexttoken.value]=true;} -advance();advance(':');jsonValue();if(nexttoken.id!==','){break;} -advance(',');}} -advance('}');} -function jsonArray(){var t=nexttoken;advance('[');if(nexttoken.id!==']'){for(;;){if(nexttoken.id==='(end)'){error("Missing ']' to match '[' from line {a}.",nexttoken,t.line);}else if(nexttoken.id===']'){warning("Unexpected comma.",token);break;}else if(nexttoken.id===','){error("Unexpected comma.",nexttoken);} -jsonValue();if(nexttoken.id!==','){break;} -advance(',');}} -advance(']');} -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);} -adjacent(token,nexttoken);advance('(number)');break;default:error("Expected a JSON value.",nexttoken);}} -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',nexttoken.value);} -statements('lib');}} -advance('(end)');}catch(e){if(e){JSLINT.errors.push({reason:e.message,line:e.line||nexttoken.line,character:e.character||nexttoken.from},null);}} -return JSLINT.errors.length===0;};function is_array(o){return Object.prototype.toString.apply(o)==='[object Array]';} -function to_array(o){var a=[],k;for(k in o){if(is_own(o,k)){a.push(k);}} -return a;} -itself.data=function(){var data={functions:[]},fu,globals,implieds=[],f,i,j,members=[],n,unused=[],v;if(itself.errors.length){data.errors=itself.errors;} -if(jsonmode){data.json=true;} -for(n in implied){if(is_own(implied,n)){implieds.push({name:n,line:implied[n]});}} -if(implieds.length>0){data.implieds=implieds;} -if(urls.length>0){data.urls=urls;} -globals=to_array(scope);if(globals.length>0){data.globals=globals;} -for(i=1;i0){data.unused=unused;} -members=[];for(n in member){if(typeof member[n]==='number'){data.member=member;break;}} -return data;};itself.report=function(option){var data=itself.data();var a=[],c,e,err,f,i,k,l,m='',n,o=[],s;function detail(h,s){if(s){o.push('
'+h+' '+ -s.sort().join(', ')+'
');}} -if(data.errors||data.implieds||data.unused){err=true;o.push('
Error:');if(data.errors){for(i=0;iProblem'+(isFinite(c.line)?' at line '+ -c.line+' character '+c.character:'')+': '+c.reason.entityify()+'

'+ -(e&&(e.length>80?e.slice(0,77)+'...':e).entityify())+'

');}}} -if(data.implieds){s=[];for(i=0;i'+data.implieds[i].name+' '+ -data.implieds[i].line+'';} -o.push('

Implied global: '+s.join(', ')+'

');} -if(data.unused){s=[];for(i=0;i'+data.unused[i].name+' '+ -data.unused[i].line+' '+ -data.unused[i]['function']+'';} -o.push('

Unused variable: '+s.join(', ')+'

');} -if(data.json){o.push('

JSON: bad.

');} -o.push('
');} -if(!option){o.push('
');if(data.urls){detail("URLs
",data.urls,'
');} -if(data.json&&!err){o.push('

JSON: good.

');}else if(data.globals){o.push('
Global '+ -data.globals.sort().join(', ')+'
');}else{o.push('
No new global variables introduced.
');} -for(i=0;i
'+f.line+'-'+ -f.last+' '+(f.name||'')+'('+ -(f.param?f.param.join(', '):'')+')
');detail('Unused',f.unused);detail('Closure',f.closure);detail('Variable',f['var']);detail('Exception',f.exception);detail('Outer',f.outer);detail('Global',f.global);detail('Label',f.label);} -if(data.member){a=to_array(data.member);if(a.length){a=a.sort();m='
/*members ';l=10;for(i=0;i72){o.push(m+'
');m=' ';l=1;} -l+=n.length+2;if(data.member[k]===1){n=''+n+'';} -if(i*/
');} -o.push('
');}} -return o.join('');};itself.jslint=itself;itself.edition='2009-10-04';return itself;}());(function(a){var e,i,input;if(!a[0]){print("Usage: jslint.js file.js");quit(1);} -input=readFile(a[0]);if(!input){print("jslint: Couldn't open file '"+a[0]+"'.");quit(1);} -if(!JSLINT(input,{bitwise:true,eqeqeq:true,immed:true,newcap:true,nomen:true,onevar:true,plusplus:true,regexp:true,rhino:true,undef:true,white:true})){for(i=0;i"); -} - -} - -// INTERESTING: http://www.quirksmode.org/js/forms.html - -// Example onsubmit handler - -function checkscript() { - if (some value is/is not something) { - // something is wrong - alert('alert user of problem'); - return false; - } - else if (another value is/is not something) { - // something else is wrong - alert('alert user of problem'); - return false; - } - - // If the script makes it to here, everything is OK, - // so you can submit the form - - return true; -} - -// with XPCNativeWrappers you cannot use document.formname.inputname.value -var form = document.forms.namedItem("gs"); -var input = form.elements.namedItem("q"); -var q = input.value; diff --git a/offline-submit/form-serialization.js b/offline-submit/form-serialization.js deleted file mode 100644 index d7c4d07..0000000 --- a/offline-submit/form-serialization.js +++ /dev/null @@ -1,129 +0,0 @@ -/* ------------------------------------------------------------------ */ - -/** - * @param f : Form|HTMLFormElement - * @return string - */ -function serializeForm(f) -{ - var gotSubmit = false; - - /** - * @param o - */ - function serializeControl(o) - { - /* HTML 4.01: Controls that are disabled cannot be successful. */ - if (!o.disabled) - { - /* - * If a form contains more than one submit button, - * only the activated submit button is successful. - * (here: the first one) - */ - var isSubmit = /(^|\s)(submit|image)(\s|$)/i.test(o.type); - if (!gotSubmit || !isSubmit) - { - if (isSubmit) gotSubmit = true; - - /* - * For menus, the control name is provided by a SELECT element - * and values are provided by OPTION elements. Only selected - * options may be successful. When no options are selected, - * the control is not successful and neither the name nor any - * values are submitted to the server when the form is submitted. - */ - var m = /(^|\s)(select(-one)?|undefined)(\s|$)/i.exec(o.type); - if (m) - { - /* select-one */ - if (m[3]) - { - if (o.selectedIndex > -1) - { - items.add(o.name, o.options[o.selectedIndex].value); - } - } - - /* select */ - else if (m[2]) - { - for (var i = 0, opts = o.options, len = opts && opts.length; - i < len; i++) - { - var opt = opts[i]; - if (opt.selected) - { - items.add(o.name, opt.value); - } - } - } - } - - /* - * All "on" checkboxes may be successful. - * For radio buttons that share the same value of the - * name attribute, only the "on" radio button may be successful. - */ - else if (!/(^|\s)file|reset(\s|$)/i.test(o.type) - && !(/(^|\s)object(\s|$)/i.test(o.tagName) && o.declare) - && !/(^|\s)(checkbox|radio)(\s|$)/i.test(o.type) - || o.checked) - { - items.add(o.name, o.value); - } - } - } - } - - var es = getFeature(f, "elements"); - if (es) - { - var items = []; - - items.add = function(sName, sValue) { - var s = esc(sName) + "=" + esc(sValue); - this.push(s); - }; - - if (!isMethod(items, "push")) - { - items.push = function() { - for (var i = 0, len = arguments.length; i < len; i++) - { - items[items.length] = arguments[i]; - } - }; - } - - for (var i = 0, len = es.length; i < len; i++) - { - var e = es[i]; - - /* - * Elements with the same name create a NodeList object, - * however options of select objects are also indexable in Gecko. - */ - if (typeof e[0] != "undefined" && typeof e.options == "undefined") - { - for (var j = 0, len2 = e.length; j < len2; j++) - { - serializeControl(e[j]); - } - } - else - { - serializeControl(e); - } - } - - return items.join("&"); - } - - return ""; -} - -/* ------------------------------------------------------------------ */ - -// esc(), getFeature() and isMethod() are user-defined, of course, but you -// probably get the idea.. diff --git a/offline-submit/http-requests.txt b/offline-submit/http-requests.txt deleted file mode 100644 index 7800182..0000000 --- a/offline-submit/http-requests.txt +++ /dev/null @@ -1,28 +0,0 @@ -00:03:23.973 4.726 2246 4222 POST 200 text/html https://bugzilla.redhat.com/process_bug.cgi -00:03:28.208 0.149 577 (2635) GET (Cache) text/css https://bugzilla.redhat.com/skins/standard/global.css -00:03:28.215 0.169 583 (1100) GET (Cache) text/css https://bugzilla.redhat.com/skins/standard/yui/calendar.css -00:03:28.221 0.173 579 (442) GET (Cache) text/css https://bugzilla.redhat.com/skins/standard/show_bug.css -00:03:28.237 0.192 583 (1728) GET (Cache) text/css https://bugzilla.redhat.com/skins/contrib/RedHat/global.css -00:03:28.243 0.197 589 (103) GET (Cache) text/css https://bugzilla.redhat.com/skins/contrib/RedHat/yui/calendar.css -00:03:28.250 0.209 585 (100) GET (Cache) text/css https://bugzilla.redhat.com/skins/contrib/RedHat/show_bug.css -00:03:28.257 0.227 575 (100) GET (Cache) text/css https://bugzilla.redhat.com/skins/custom/global.css -00:03:28.264 0.236 581 (103) GET (Cache) text/css https://bugzilla.redhat.com/skins/custom/yui/calendar.css -00:03:28.273 0.234 577 (100) GET (Cache) text/css https://bugzilla.redhat.com/skins/custom/show_bug.css -00:03:28.280 0.293 550 (493) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/cookies.js -00:03:28.508 0.220 581 (1568) GET (Cache) text/css https://bugzilla.redhat.com/skins/contrib/Dusk/global.css -00:03:28.513 1.086 587 477 GET 404 text/html https://bugzilla.redhat.com/skins/contrib/Dusk/yui/calendar.css -00:03:28.520 1.091 583 473 GET 404 text/html https://bugzilla.redhat.com/skins/contrib/Dusk/show_bug.css -00:03:28.574 0.222 547 (2033) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/util.js -00:03:28.582 0.234 548 (3746) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/field.js -00:03:28.589 0.252 562 (9752) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/yui/yahoo-dom-event.js -00:03:28.598 0.272 555 (12147) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/yui/calendar.js -00:03:28.606 0.283 554 (4985) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/productform.js -00:03:28.633 0.276 550 (5467) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/rpc-min.js -00:03:28.641 0.284 551 (1047) GET (Cache) application/x-javascript https://bugzilla.redhat.com/js/show_bug.js -00:03:29.557 0.077 427 (14643) GET (Cache) text/plain http://mcepl.fedorapeople.org/scripts/BugZappers_data.json -00:03:29.564 0.071 422 (11352) GET (Cache) text/plain http://mcepl.fedorapeople.org/scripts/drm_pciids.json -00:03:32.916 0.168 566 11698 GET 200 application/vnd.google.safebrowsing-chunk http://safebrowsing-cache.google.com/safebrowsing/rd/goog-malware-shavar_s_25761-25920.25761-25796.25797-25920: -00:03:34.383 0.275 561 20882 GET 200 application/vnd.google.safebrowsing-chunk http://safebrowsing-cache.google.com/safebrowsing/rd/goog-malware-shavar_a_16771-16780.16771,16773-16780.: -00:03:34.691 0.080 566 7154 GET 200 application/vnd.google.safebrowsing-chunk http://safebrowsing-cache.google.com/safebrowsing/rd/goog-malware-shavar_a_16781-16800.16781-16791.16792-16800: -00:03:34.810 0.084 564 3875 GET 200 application/vnd.google.safebrowsing-chunk http://safebrowsing-cache.google.com/safebrowsing/rd/goog-phish-shavar_s_52481-52640.52481-52528.52529-52640: -00:03:35.195 0.111 564 15346 GET 200 application/vnd.google.safebrowsing-chunk http://safebrowsing-cache.google.com/safebrowsing/rd/goog-phish-shavar_a_78641-78720.78641-78718.78719-78720: diff --git a/offline-submit/john-resig-offline-app-stub.js b/offline-submit/john-resig-offline-app-stub.js deleted file mode 100644 index b9d6160..0000000 --- a/offline-submit/john-resig-offline-app-stub.js +++ /dev/null @@ -1,43 +0,0 @@ -// stub for the offline application in pseudocode -// from http://ejohn.org/blog/offline-events/ - -function saveData( item ){ - if ( navigator.onLine ) { - saveToServer( item ); - } else { - toSave.push( item ); - } -} - -function loadData( item ){ - if ( navigator.onLine ) { - return loadFromServer( item ); - } else { - var result = loadFromQueue( item ); - if ( !result ) { - displayError(); - toLoad.push( item ); - } - return result; - } -} - -setInterval(function(){ - if ( navigator.onLine ) { - var item = predictNextItemToBeLoaded(); - loadData( item ); - } -}, 5000); - -window.ononline = function(){ - toSave.forEach( saveData ); - toLoad.forEach( loadData ); -}; - -window.onload = function(){ - document.getElementById("myform").onsubmit = function(){ - saveData( this ); - return false; - }; -}; - diff --git a/offline-submit/jquery.malsup.com.htm b/offline-submit/jquery.malsup.com.htm deleted file mode 100644 index b0008d7..0000000 --- a/offline-submit/jquery.malsup.com.htm +++ /dev/null @@ -1,583 +0,0 @@ - - - -JavaScript Form Serialization Comparison - - - - - - - - - - - - - - - - - - - - - - - -

JavaScript Form Serialization Comparison:   jQuery • dojo • Prototype • YUI • MochiKit

-
- This page tests two things about JavaScript form serialization: quality and speed. -
    - -
  • Quality is dertermined by analyzing the serialized output according to the W3C Recommendation.
  • -
  • Speed is measured using Firebug to time (or profile in FireFox) numerous iterations of the serialization process.[1]
  • -
-
If you believe the tests or comments on this page are inaccurate - or unfair - please let me know. It is not my intent to misrepresent any of these libraries. - Feedback can be sent to: forms at malsup dot com. -
-
»» Special thanks to Marius Feraru for adding support for native browser output and the EOL test!
-
-
- Timer Profiler - Iterations: - -

- - - - - - - -

-
-
-
Output (errors in red) - - - - - - - - - - -
NATIVE
jQuery
jQuery Form
dojo
YUI
MochiKit
Prototype
-
-
- -

- The following form contains each of the possible elements that can be submitted (with the exception of <input type="file">). - Which elements, and how they should be submitted, is specified here: - http://www.w3.org/TR/html401/interact/forms.html#h-17.13 -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Most enabled input elements and textareas are handled correctly by each of the libraries.
<textarea name="T3" rows="2" cols="15">?
Z</textarea>
<input type="hidden" name="H1" value="x" />
<input type="hidden" name="H2" />
<input type="password" name="PWD" />
<input type="text" name="T1" />
<input type="text" name="T2" value="YES" readonly="readonly" />
<input type="checkbox" name="C1" value="1" />
<input type="checkbox" name="C2" />
<input type="radio" name="R1" value="1" />
<input type="radio" name="R1" value="2" />
<input type="text" name="My Name" value="me" />
The reset input should never be serialized. Prototype and MochiKit get this wrong.
<input type="reset" name="reset" value="NO" />
Normal Single select elements are handled correctly by each of the libraries.
<select name="S1"> (100 options) - -
Normal multiple select elements are handled correctly by each of the libraries.
<select name="S2" multiple="multiple" size="3"> (100 options) -
The following select element has a selected option with no value attribute. The option text value should be submitted. - S3=YES is correct. S3= is incorrect. dojo gets this wrong in IE.
<select name="S3"><option selected="selected">YES</option></select>
The following select element has a selected option with a value attribute set to "". S4= is correct. S4=NO is incorrect. -
<select name="S4"><option value="" selected="selected">NO</option></select>
The following select element has its selectedIndex property set to -1 before serialization. - It should not be submitted. dojo and MochiKit get this wrong.
<select name="S5"><option value="NO">NO</option></select>
Submit elements should only appear in the query string when they are the element used to submit the form. Only jQuery and dojo get this right. - YUI always includes the first submit element. Prototype sends all the input submit elements (but not button submit elements). - MochiKit sends them all.
<input type="submit" name="sub1" value="NO" />
<input type="submit" name="sub2" value="NO" />
<input type="image" name="sub3" src="submit.gif" value="NO" />
<button type="submit" name="sub4" value="NO">NO</button>
Disabled elements should never be submitted. MochiKit and mootools get this wrong.
<input type="text" name="D1" value="NO" disabled="disabled" />
<input type="checkbox" name="D2" value="NO" checked="checked" disabled="disabled" />
<input type="radio" name="D3" value="NO" checked="checked" disabled="disabled" />
<select name="D4"><option selected="selected" value="NO" disabled="disabled">NO</option>
Inputs with a type attribute of something other than
- PASSWORD | CHECKBOX | RADIO | SUBMIT | RESET | FILE | HIDDEN | IMAGE | BUTTON
- should be treated as TEXT inputs. -
<input type="bogus" name="TYPE-TEST" value="YES" />
<input type="search" name="SEARCH" value="YES" />
-
-

-

Notes

- This test page does not expose serialization problems that occur during an actual form submit. These include: -

- -

    -
  • YUI, Prototype and MochiKit do not support input elements of type="image".
  • -
  • dojo does not capture the click coordinates of input elements of type="image". However, it does correctly recognize it as the submitting element.
  • -
  • dojo does not properly support semantic serialization when the form contains an input of type="image". When such an element is used to submit - the form, it will always appear last in the query string regardless of its semantic position. (This is likely a very - low-percentage use case.)
  • - -
  • mootools is not compatible with Prototype and is not included on this test page. A test page that includes mootools can be found here. - In summary, mootools does not support semantic serialization and it incorrectly submits disabled fields. -
  • -
-

-

Encoding

- Each of the libraries tested use JavaScript's encodeURIComponent[2] function to encode form data. - Technically, this does not conform to the HTML spec which - states the following - about the application/x-www-form-urlencoded content type (emphasis added): -
- - This is the default content type. Forms submitted with this content type must be encoded as follows:
-
    -
  1. Control names and values are escaped. Space characters are replaced by `+', and then reserved - characters are escaped as described in [RFC1738], - section 2.2: Non-alphanumeric characters are - replaced by `%HH', a percent sign and two hexadecimal digits representing the ASCII code of the character. - Line breaks are represented as "CR LF" pairs (i.e., `%0D%0A').
  2. -
  3. The control names/values are listed in the order they appear in the document. The name is separated - from the value by `=' and name/value pairs are separated from each other by '&'.
  4. - -
-
- While this does not seem to cause any problems, it is interesting and noteworthy. -

-

Links

- - -
- - diff --git a/offline-submit/lazarus.js b/offline-submit/lazarus.js deleted file mode 100644 index 9db59b0..0000000 --- a/offline-submit/lazarus.js +++ /dev/null @@ -1,4418 +0,0 @@ - -//declare namespace -this.Lazarus = this.Lazarus || {} - -Lazarus.STATE_UNINITALIZED = 0; -Lazarus.STATE_DISABLED = 1; -Lazarus.STATE_PASSWORD_REQUIRED = 2; -Lazarus.STATE_ENABLED = 3; -Lazarus.STATE_DISABLED_FOR_DOMAIN = 4; -Lazarus.STATE_PRIVATE_BROWSING = 5; -Lazarus.STATE_GENERATING_KEYS = 6; - - -Lazarus.LOGIN_HOSTNAME = 'chrome://lazarus'; -Lazarus.LOGIN_REALM = 'Private Key Password'; -Lazarus.LOGIN_USERNAME = 'lazarus-private-key'; - -Lazarus.IFRAME_NAME = ''; -Lazarus.MIN_TEXT_NEEDED_TO_SHOW_NOTIFICATION = 1024; //characters - -//flag to indicate if this browser is ready yet. -Lazarus.initalized = false; - -//timers -Lazarus.cleanupSavedFormsTimer = 0; -Lazarus.autoSaveFormTimer = 0; - -//pointer to last autosave form. -Lazarus.currAutoSaveForm = null; - -//pointer to the last editor (txetbox or iframe) that a user put input into. -Lazarus.currentEditor = null; - -//flag to say if context menu is currently being shown -Lazarus.isContextMenuShowing = false; - -/* known input types -case "text": -case "textarea": -case "file": -case "radio": -case "checkbox": -case "select": -case "password": -case "hidden": -case "submit": -case "reset": -case "button": -case "image": -*/ - - - -//array of editor infos that the user has typed into this session -Lazarus.editorInfos = []; - - -/** -* window has loaded -*/ -Lazarus.init = function(){ - - Lazarus.Global = Components.utils.import("resource://lazarus/global.js").Global; - Lazarus.Crypto = Components.utils.import("resource://lazarus/crypto.js").Crypto; - - Lazarus.initalized = true; - Lazarus.initDevEnviroment(); - - //set loading icon - Lazarus.refreshIcon(); - Lazarus.repositionNotification(); - - //Update UI elements - Lazarus.$("lazarus-statusbaricon-tooltip-title").setAttribute("value", Lazarus.getString("lazarus.statusbarpanel.image.tooltip", Lazarus.getVersionStr() +" ["+ Lazarus.build +"]")); - Lazarus.refreshMenuIcons(); - Lazarus.Pref.addObserver('extensions.lazarus.showContextMenuIcons', Lazarus.refreshMenuIcons); - - if (Lazarus.getPref('extensions.lazarus.showDonateNotification')){ - Lazarus.checkForDonateThanks(); - } - - - //check crypto component (breaks a lot with various Linux builds) - if (Lazarus.checkCrypto()){ - //open the database - if (Lazarus.initDB()){ - if (Lazarus.initEncryptionKeys()){ - if (Lazarus.loadPublicKey()){ - Lazarus.enable(); - } - - Lazarus.refreshIcon(); - - Lazarus.saveAutoSaveText(); - - //remove expired forms - Lazarus.cleanupSavedForms(); - - //hmmm, interesting. Cleaning the database makes little difference to the database size (33MB -> 32MB), - // unless a lot of deletions have been made - // - if (Lazarus.getPref('extensions.lazarus.cleanDatabaseAtStartup')){ - Lazarus.cleanDB(); - } - } - //else we are generating new encryption keys, do nothing - } - else { - //errors *should* have been thrown in the error console. - //inform the user something went wrong :( - Lazarus.error("Failed to load database"); - Lazarus.disable(); - } - } - else { - Lazarus.error("Failed to load crypto component"); - Lazarus.disable(); - } - Lazarus.refreshIcon(); -} - -/** -* turn off the donate notifications if this user has donated. -*/ -Lazarus.checkForDonateThanks = function(){ - - var onload = function(uri){ - if (uri && uri.spec && uri.spec.indexOf('//lazarus.interclue.com/donate-thanks.html') > -1){ - Lazarus.setPref('extensions.lazarus.showDonateNotification', false); - Lazarus.Event.remove("location-change", onload); - } - } - Lazarus.Event.add("location-change", onload); -} - -/** -* check to make sure the crypto component has loaded correctly -*/ -Lazarus.checkCrypto = function(){ - try { - var crypto = Components.classes["@labs.mozilla.com/Weave/Crypto;1"].createInstance(Components.interfaces.IWeaveCrypto); - return true; - } - catch(e){ - return false; - } -} - -/** -* reposition the notification bar so that it's always the last element -*/ -Lazarus.repositionNotification = function(){ - //#124: Zotero compatiilty problem - var notif = document.getElementById('lazarus-notification'); - notif.parentNode.appendChild(notif); -} - - - -/** -* enables Lazarus for this browser -*/ -Lazarus.enable = function(){ - - Lazarus.saveAutoSavedForms(); - - //add preference observers - Lazarus.Pref.addObserver("extensions.lazarus.expireSavedForms", Lazarus.startCleanupTimer); - Lazarus.Pref.addObserver("extensions.lazarus.expireSavedFormsInterval", Lazarus.startCleanupTimer); - Lazarus.Pref.addObserver("extensions.lazarus.showInStatusbar", Lazarus.refreshIcon); - - //we need to capture any onsubmit event from forms within a webpage - gBrowser.addEventListener("submit", Lazarus.onFormSubmit, false); - gBrowser.addEventListener("submit", Lazarus.saveLastSubmittedForm, false); - gBrowser.addEventListener("DOMContentLoaded", Lazarus.autofillEvent, true); - gBrowser.addEventListener("DOMContentLoaded", Lazarus.initRecoverForm, true); - gBrowser.addEventListener("reset", Lazarus.onFormReset, false); - gBrowser.addEventListener("change", Lazarus.onFormChange, false); - //we also need to save forms if people are typing into them. - gBrowser.addEventListener("keyup", Lazarus.onKeyUp, false); - - //kjd: removing lazarus icon for now - //gBrowser.addEventListener("keydown", Lazarus.onKeyDown, false); - - - //clear the saved forms if user wants to when "clear private data" is hit. - Lazarus.$("Tools:Sanitize").addEventListener("command", Lazarus.fireClearPrivateDataIfNoPrompt, false); - - //add handlers to the context menu - Lazarus.$("contentAreaContextMenu").addEventListener("popupshowing", Lazarus.onContextMenuShowing, false); - Lazarus.$("contentAreaContextMenu").addEventListener("popuphidden", Lazarus.onContextMenuHide, false); - - //need events when a user changes the current document - Lazarus.Event.add("location-change", Lazarus.onLocationChange); - - Lazarus.Event.add("extension-uninstall", Lazarus.onUninstall); - Lazarus.Event.add("extension-uninstall-request", Lazarus.onUninstallRequest); - Lazarus.Event.add("application-startup", Lazarus.onStartUp); - Lazarus.Event.add("application-startup", Lazarus.removeOldForms); - Lazarus.Event.add("application-shutdown", Lazarus.fireClearPrivateDataOnShutdown); - Lazarus.Event.add("application-shutdown", Lazarus.onShutdown); - Lazarus.Event.add("clear-private-data", Lazarus.onClearPrivateData); - - Lazarus.startCleanupTimer(); - - //show the statusbar image (if user wants it) - Lazarus.refreshIcon(); -} - - -Lazarus.onKeyDown = function(evt){ - var ele = evt.target; - - //ignore if we have already attached an onblur handler to this element - if (!ele.lazarusIconAdded){ - switch(Lazarus.getElementType(ele)){ - case "text": - case "password": - case "textarea": - //are we saving this element? - var form = Lazarus.findFormFromElement(ele); - var editor = Lazarus.findEditorFromElement(ele); - if ((form && Lazarus.shouldSaveForm(form)) || (editor && Lazarus.shouldSaveEditorInfo(form))){ - //highlight element - Lazarus.addBackgroundIcon(ele); - } - else { - //ignore furthur keypresses on this element? - } - - default: - //ignore this element - } - } -} - - -Lazarus.addBackgroundIcon = function(ele){ - - if (!ele.lazarusIconAdded){ - ele.lazarusIconAdded = true; - - var doc = ele.ownerDocument; - if (!doc.lazarusIcon){ - var div = doc.createElement('div'); - div.style.width = "11px"; - div.style.height = "14px"; - div.style.position = "absolute"; - div.style.background = "url("+ Lazarus.icon +") no-repeat center center"; - div.title = Lazarus.getString('Lazarus.savingText'); - doc.body.appendChild(div); - doc.lazarusIcon = div; - } - //now position the image over the end of the textbox - var rect = ele.getBoundingClientRect(); - doc.lazarusIcon.style.top = rect.top +"px"; - doc.lazarusIcon.style.left = (rect.right - parseInt(doc.lazarusIcon.style.width)) +"px"; - doc.lazarusIcon.style.display = "block"; - - var onBlur = function(){ - //hide the icon - doc.lazarusIcon.style.display = "none"; - ele.lazarusIconAdded = false; - } - - //when adding the icon, we should hide it on blur - ele.addEventListener("blur", onBlur, false); - } -} - - -/** -* restart the browser -*/ -Lazarus.restart = function(){ - var nsIAppStartup = Components.interfaces.nsIAppStartup; - Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup).quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit); -} - -/** -* turns Lazarus off for this browser -*/ -Lazarus.disable = function(){ - - //add preference observers - Lazarus.Pref.addObserver("extensions.lazarus.expireSavedForms", Lazarus.startCleanupTimer); - Lazarus.Pref.addObserver("extensions.lazarus.expireSavedFormsInterval", Lazarus.startCleanupTimer); - Lazarus.Pref.addObserver("extensions.lazarus.showInStatusbar", Lazarus.refreshIcon); - - //we need to capture any onsubmit event from forms within a webpage - gBrowser.removeEventListener("submit", Lazarus.onFormSubmit, false); - gBrowser.removeEventListener("submit", Lazarus.saveLastSubmittedForm, false); - gBrowser.removeEventListener("DOMContentLoaded", Lazarus.autofillEvent, true); - gBrowser.removeEventListener("DOMContentLoaded", Lazarus.initRecoverForm, true); - gBrowser.removeEventListener("reset", Lazarus.onFormReset, false); - gBrowser.removeEventListener("change", Lazarus.onFormChange, false); - //we also need to save forms if people are typing into them. - gBrowser.removeEventListener("keyup", Lazarus.onKeyUp, false); - - //need events when a user changes the current document - Lazarus.Event.remove("location-change", Lazarus.onLocationChange); - - //clear the saved forms if user wants to when "clear private data" is hit. - Lazarus.$("Tools:Sanitize").removeEventListener("command", Lazarus.fireClearPrivateDataIfNoPrompt, false); - - Lazarus.stopCleanupTimer(); - - //and close the database - Lazarus.db.close(); - - //update the statusbar image - Lazarus.refreshIcon(); -} - -/** -* return TRUE if we can encrypt a string (ie the Crypto component is working, and the public key exists) -*/ -Lazarus.canEncrypt = function(){ - return Lazarus.Crypto.publicKey ? true : false; -} - -Lazarus.canDecrypt = function(){ - return Lazarus.Crypto.privateKey ? true : false; -} - - - -/** -* initalizes the lazarus recover-form page -*/ -Lazarus.initRecoverForm = function(evt){ - var doc = evt.originalTarget; - if (Lazarus.isDocRecoveryForm(doc)){ - doc.title = Lazarus.getString("recoverform.title"); - - //Lazarus.$('heading', doc).innerHTML = Lazarus.getString("recoverform.title"); - Lazarus.$('description', doc).innerHTML = Lazarus.getString("recoverform.description"); - Lazarus.$('notes', doc).innerHTML= Lazarus.getString("recoverform.notes"); - - Lazarus.$('form-url-label', doc).innerHTML= Lazarus.getString("recoverform.form.url"); - Lazarus.$('form-action-label', doc).innerHTML= Lazarus.getString("recoverform.form.action"); - Lazarus.$('notes', doc).innerHTML= Lazarus.getString("recoverform.notes"); - - var m = doc.URL.match(/[\?&]id=(\d+)/) - var id = m ? parseInt(m[1]) : -1; - if (id > -1){ - var row = Lazarus.db.getRow("SELECT * FROM forms WHERE id = ?1", id); - if (row){ - if (Lazarus.canDecrypt()){ - var formInfo = Lazarus.JSON.decode(Lazarus.decrypt(row["forminfo"])); - - Lazarus.$('form-url', doc).innerHTML = formInfo.origURL ? Lazarus.generateLinkFromURL(formInfo.origURL) : ''; - Lazarus.$('form-action', doc).innerHTML = formInfo.action ? Lazarus.generateLinkFromURL(formInfo.action) : ''; - - var form = Lazarus.buildForm(formInfo, doc); - form.setAttribute("lazarus-form-id", row["formid"]); - Lazarus.$('form-box', doc).appendChild(form); - Lazarus.restoreForm(form, formInfo); - } - else { - //need to explain to user why we cannot fill in the form - Lazarus.showNotificationBox("password-required"); - } - } - else { - Lazarus.$('form-box', doc).innerHTML = Lazarus.getString("error.form.not.found"); - Lazarus.$('form-box', doc).className = "warning"; - } - } - else { - Lazarus.$('form-box', doc).innerHTML = Lazarus.getString("error.form.not.found"); - Lazarus.$('form-box', doc).className = "warning"; - } - } -} - -/** -* return TRUE if the given document is the lazarus Recover Form page. -*/ -Lazarus.isDocRecoveryForm = function(doc){ - return (doc && doc.URL && doc.URL.indexOf("chrome://lazarus/content/recover-form.html") == 0); -} - -/** -* generate an HTML link given a url. -* if url is too long, then truncate url to maxChars -*/ -Lazarus.generateLinkFromURL = function(url, maxChars){ - - maxChars = maxChars || 50; - - if (/^(file|http|https):/.test(url)){ - var text = url; - if (text.length > maxChars){ - text = text.substring(0, maxChars -3) +"..."; - } - - return ''+ Lazarus.htmlEncode(text) +''; - } - else { - return Lazarus.htmlEncode(url); - } -} - -/** -* encode a string for display in an html page -*/ -Lazarus.htmlEncode = function(str){ - str = str.replace(/&/g, "&"); - str = str.replace(//g, ">"); - str = str.replace(/"/g, """); - return str; -} - -/** -* builds an HTML form from a formInfo object -*/ -Lazarus.buildForm = function(formInfo, doc){ - var form = doc.createElement("form"); - form.setAttribute("method", formInfo.method || "get"); - form.setAttribute("enctype", formInfo.enctype || ""); - //support for AJAX textareas - form.isTextarea = formInfo.isTextarea; - - for(var name in formInfo.fields){ - for (var i=0; i= 1 && fieldInfo.value && typeof fieldInfo.value.valueAttr != "undefined"){ - ele = doc.createElement("input"); - ele.setAttribute("type", fieldInfo.type); - ele.setAttribute("value", fieldInfo.value.valueAttr); - eleLabel = name +"["+ fieldInfo.value.valueAttr +"]"; - } - break; - - case "password": - case "hidden": - case "file": - case "text": - ele = doc.createElement("input"); - ele.setAttribute("type", fieldInfo.type); - break; - - case "textarea": - ele = doc.createElement("textarea"); - break; - - case "select": - if (formInfo.version && formInfo.version >= 1 && Lazarus.isArray(fieldInfo.value) && fieldInfo.value.length){ - ele = doc.createElement("select"); - - for (var i=0; i 1){ - ele.setAttribute("size", fieldInfo.value.length); - ele.setAttribute("multiple", "true"); - } - } - break; - - //no saved - case "submit": - case "reset": - case "button": - case "image": - break; - - case "iframe": - //ignore iframes for now? - break; - - default: - Lazarus.error("Unknown element type ["+ fieldInfo.type +"]"); - } - - if (ele){ - if (fieldInfo.type == "hidden"){ - form.appendChild(ele); - } - else { - var box = doc.createElement("div"); - box.setAttribute("class", "form-field-box"); - - var label = doc.createElement("label"); - var text = doc.createTextNode(eleLabel || name); - label.appendChild(text); - box.appendChild(label); - - ele.setAttribute("name", fieldInfo.name); - ele.setAttribute("class", "form-field "+ fieldInfo.type); - box.appendChild(ele); - form.appendChild(box); - } - } - } - } - - return form; -} - -/** -* save the last submitted form id for use in auto restore template -*/ -Lazarus.saveLastSubmittedForm = function(evt){ - var form = Lazarus.findFormFromElement(evt.target); - if (form){ - Lazarus.lastSubmittedFormId = Lazarus.getFormId(form); - } -} - -/** -* call autofill if this is a valid html document. -*/ -Lazarus.autofillEvent = function(evt){ - if (evt.originalTarget instanceof HTMLDocument){ - Lazarus.autofillDoc(evt.originalTarget); - } -} - - -/** -* convert a string of HTML into human readable text -*/ -Lazarus.htmlToText = function(html){ - - //replace headings () and paragraph ends with 2 line breaks - var text = html.replace(/\s*<\/((h\d)|p)\s*>\s*/ig," \n\n"); - - //replace divs blocks with single line breaks - text = text.replace(/\s*<(\/div)\b[^>]*>\s*/ig,"\n"); - - //replace list items with line breaks and dots - text = text.replace(/\s*<(li)\b[^>]*>\s*/ig,"\n * "); - - //replace line breaks - text = text.replace(/<(br)\b[^>]*>/ig,"\n"); - - //strip all other tags - text = text.replace(/<(\/|\w)[^>]*>/g,' '); - - //convert html spaces into normal spaces - text = text.replace(/ /g, ' '); - - //compress whitespace - text = text.replace(/[ \t\f\v]+/g, ' '); - - //never have more than 2 line breaks in a row. - text = text.replace(/\n\s*?\n(\s*?\n)*/g, "\n\n"); - - //and finally trim. - text = text.replace(/^\s+/, '').replace(/\s+$/, ''); - - return text; -} - - -/** -* return TRUE if forms on the given document should be saved -*/ -Lazarus.isValidDoc = function(doc){ - return (doc && doc.URL && /^(file|http|https):/.test(doc.URL)); -} - -/** -* autofills forms found in the given document with there respective templates if they exist -*/ -Lazarus.autofillDoc = function(doc){ - - if (Lazarus.isValidDoc(doc) && doc.forms && doc.forms.length){ - var rsAutoFillTemplates = Lazarus.db.rs("SELECT id, formid FROM forms WHERE autofill = 1 AND savetype = "+ Lazarus.FORM_TYPE_TEMPLATE +" ORDER BY created DESC"); - if (rsAutoFillTemplates.length > 0){ - var templates = {}; - //convert the template id's to a hash table - //TODO: there should only ever be one autofill template for a given form - //raise a warning if this is not the case - for (var i=0; i= 4){ - Lazarus.$('lazarus-statusbar-menuitem-test').hidden = false; - } -} - -/** -* handle text within the address bar changing -*/ -Lazarus.onLocationChange = function(evt){ - //only close the notification if current page was not the result of submitting a form. - if (!Lazarus.lastSubmittedFormId){ - Lazarus.closeNotificationBox(true); - } - Lazarus.refreshIcon(); -} - -/** -* fire the "clear private data" event -*/ -Lazarus.fireClearPrivateDataIfNoPrompt = function(){ - if (!Lazarus.getPref("privacy.sanitize.promptOnSanitize", true)){ - Lazarus.Event.fire("clear-private-data"); - } -} - - -/** -* return the current state of lazarus -*/ -Lazarus.getState = function(){ - if (!Lazarus.initalized){ - return Lazarus.STATE_UNINITALIZED; - } - else if (Lazarus.Crypto.generatingKeys || Lazarus.cleaningDatabase){ - return Lazarus.STATE_GENERATING_KEYS; - } - else if (!Lazarus.canEncrypt()){ - return Lazarus.STATE_DISABLED; - } - else if (Lazarus.isDisabledByPrivateBrowsing()){ - return Lazarus.STATE_PRIVATE_BROWSING; - } - else if (Lazarus.isPageDisabled()){ - return Lazarus.STATE_DISABLED_FOR_DOMAIN; - } - else if (!Lazarus.canDecrypt()){ - return Lazarus.STATE_PASSWORD_REQUIRED; - } - //all good? - else { - return Lazarus.STATE_ENABLED; - } -} - -/** -* fix for multiline xul:description elements -*/ -Lazarus.setDescriptionText = function(ele, text){ - for (var i=ele.childNodes.length-1; i>=0; i--){ - ele.removeChild(ele.childNodes[i]); - } - ele.appendChild(ele.ownerDocument.createTextNode(text)); -} - -/** -* updates the statusbar icon -*/ -Lazarus.refreshIcon = function(){ - - Lazarus.$("lazarus-statusbarpanel").hidden = !Lazarus.getExtPref("showInStatusbar"); - - var iconURL = ""; - var tooltipId = ""; - - switch (Lazarus.getState()){ - case Lazarus.STATE_ENABLED: - iconURL = "chrome://lazarus/skin/lazarus.png"; - tooltipId = "lazarus-statusbaricon-tooltip-enabled" - break; - - case Lazarus.STATE_GENERATING_KEYS: - iconURL = 'chrome://lazarus/skin/lazarus-loading.gif'; - tooltipId = 'lazarus-statusbaricon-tooltip-generatingkeys'; - break; - - case Lazarus.STATE_PASSWORD_REQUIRED: - iconURL = "chrome://lazarus/skin/lazarus-login.png"; - tooltipId = "lazarus-statusbaricon-tooltip-passwordrequired"; - break; - - case Lazarus.STATE_DISABLED_FOR_DOMAIN: - iconURL = "chrome://lazarus/skin/lazarus-disabled.png"; - tooltipId = "lazarus-statusbaricon-tooltip-disabledfordomain"; - break; - - case Lazarus.STATE_PRIVATE_BROWSING: - iconURL = "chrome://lazarus/skin/lazarus-disabled.png"; - tooltipId = "lazarus-statusbaricon-tooltip-private-browsing"; - break; - - case Lazarus.STATE_UNINITALIZED: - case Lazarus.STATE_DISABLED: - default: - iconURL = "chrome://lazarus/skin/lazarus-disabled.png"; - tooltipId = "lazarus-statusbaricon-tooltip-disabled"; - } - - //this appears to screw over firefox, missing images and such, if called during startup? - //NOTE: firfox must be completely closed for this effect, using "restart" will NOT recreate it. - //Lazarus.setDescriptionText(Lazarus.$("lazarus-statusbaricon-tooltip-description"), tooltip); - - Lazarus.$("lazarus-statusbarpanel-image").setAttribute("src", iconURL); - Lazarus.$("lazarus-statusbarpanel-image").setAttribute("tooltip", tooltipId); -} - -/** -* displays the lazarus welcome message -*/ -Lazarus.showWelcome = function(){ - //dont show the welcome message immediately, need to wait a sec so the - //browser is open, and we can center the dialog relative to it. - //~ setTimeout(function(){ - //~ Lazarus.openOptionsDialog("welcome-pane"); - //~ }, 100); - - //hmmm, session recovery is happening after this event, - //which is replacing our tab with the recovered sessions tabs - setTimeout(function(){ - Lazarus.openLazarusWebsite("oninstall.html?ver="+ Lazarus.getVersionStr()); - }, 3000); -} - -/** -* opens the lazarus onupdate page for this version of lazarus -*/ -Lazarus.showUpdatePage = function(){ - //hmmm, session recovery is happening after this event, - //which is replacing our tab with the recovered sessions tabs - setTimeout(function(){ - Lazarus.openLazarusWebsite("onupdate.html?ver="+ Lazarus.getVersionStr()); - }, 3000); -} - - -/** -* handle when the first browser window is opened. -*/ -Lazarus.onStartUp = function(){ - -} - -/** -* onUninstall -*/ -Lazarus.onUninstall = function(ext){ - - if (ext.id == Lazarus.guid){ - - //var msg = ''; - if (Lazarus.getExtPref("uninstall.removeSavedForms", false)){ - //remove database - //unable to disconnect the database, so the best we can do is empty it. - Lazarus.emptyDB(); - - } - if (Lazarus.getExtPref("uninstall.removeUserSettings", false)){ - //cleanup prefs - Lazarus.killPref("extensions.lazarus"); - Lazarus.Pref.savePrefFile(); - } - } -} - -/** -* -*/ -Lazarus.onUninstallRequest = function(ext){ - if (ext.id == Lazarus.guid){ - //ask the user if we should remove their preferences/saved forms - //we need this dialog to appear from the addons dialog (if it exists) - //~ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator); - //~ var win = wm.getMostRecentWindow("Extension:Manager"); - - //~ //if theres no extension manager window (eg all-in-one-sidebar) - //~ //use this window to open the dialog - //~ if (!win){ - //~ win = window; - //~ } - //disabling dialog, uninstall process is stuffed up - //win.openDialog("chrome://lazarus/content/uninstall.xul", "LazarusUninstallOptions", "chrome,dialog,modal,resizable=yes,titlebar=yes"); - } -} - - -/** -* return TRUE if the given editor still exists in the browser -*/ -Lazarus.editorExists = function(info){ - try { - //KLUDGE: - //if a page is refreshed then the page remains, even if you then navigate away from it. - //it appears to still exist, even though the user cannot see it. - if (Lazarus.isIframe(info.editor) && (!info.editor.contentWindow || !info.editor.contentWindow.document)){ - return false; - } - else { - return (info.editor.ownerDocument.defaultView && (info.url == info.editor.ownerDocument.defaultView.top.location.href)); - } - } - catch(e){ - return false; - } -} - - -Lazarus.saveEditorInfo = function(info, saveType){ - - - if (Lazarus.shouldSaveEditorInfo(info)){ - - var textHash = Lazarus.md5(info.text); - - if (saveType == Lazarus.FORM_TYPE_AUTOSAVE){ - var record = Lazarus.db.getRow("SELECT id, text_hash FROM textdata WHERE domain_hash = ?1 AND savetype = ?2 LIMIT 1", info.domainHash, Lazarus.FORM_TYPE_AUTOSAVE); - //if form hasn't changed - if (record && record.text_hash == textHash){ - //do nothing... - } - //if it has changed, or doesn't exist yet, save the changes - else { - Lazarus.debug("Saving textdata - autosave", info); - if (record){ - Lazarus.db.exe("DELETE FROM textdata WHERE id = ?1", record.id); - //and get rid of any fulltext index as well - Lazarus.db.exe("DELETE FROM textdata_fulltext WHERE docid = ?1", record.id); - } - var encText = Lazarus.encrypt(info.text); - var encSummary = Lazarus.encrypt(info.summary); - - var id = Lazarus.db.insert("INSERT INTO textdata (text_encrypted, summary_encrypted, created, domain_hash, url_encrypted, text_hash, text_length, savetype) \ - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)", - encText, encSummary, info.created, info.domainHash, info.urlEncrypted, textHash, info.text.length, Lazarus.FORM_TYPE_AUTOSAVE); - - //and update the full text index, - if (!Lazarus.getPref('extensions.lazarus.disableSearch')){ - //we're going to add domain info into this as well - var hashedText = Lazarus.hashText(info.text); - hashedText += ' '+ Lazarus.hashText(info.domain.replace(/\./g, ' ')); - Lazarus.db.exe("INSERT INTO textdata_fulltext (docid, hashed_text) VALUES (?1, ?2)", id, hashedText); - } - } - } - else { - - //if the info object already exists, with exactly the same text, then just update the timestamp - var id = Lazarus.db.getInt("SELECT id FROM textdata WHERE domain_hash = ?1 AND text_hash = ?2 LIMIT 1", info.domainHash, textHash); - if (id){ - Lazarus.debug("Updating textdata - perm", info); - Lazarus.db.exe("UPDATE textdata SET created = ?1, savetype = ?2 WHERE id = ?3", info.created, Lazarus.FORM_TYPE_NORMAL, id); - } - //otherwise, insert a new info object - else { - Lazarus.debug("Saving textdata - perm", info); - var encText = Lazarus.encrypt(info.text); - var encSummary = Lazarus.encrypt(info.summary); - - var id = Lazarus.db.insert("INSERT INTO textdata (text_encrypted, summary_encrypted, created, domain_hash, url_encrypted, text_hash, text_length, savetype) \ - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)", - encText, encSummary, info.created, info.domainHash, info.urlEncrypted, textHash, info.text.length, Lazarus.FORM_TYPE_NORMAL); - - if (!Lazarus.getPref('extensions.lazarus.disableSearch')){ - var hashedText = Lazarus.hashText(info.text); - hashedText += ' '+ Lazarus.hashText(info.domain.replace(/\./g, ' ')); - Lazarus.db.exe("INSERT INTO textdata_fulltext (docid, hashed_text) VALUES (?1, ?2)", id, hashedText); - } - } - } - } -} - - -/** -* genereate a random seed for use in the hashing function -*/ -Lazarus.generateRandomHashSeed = function(){ - var rnd = Math.random().toString() +':'+ Lazarus.timestamp(true).toString(); - return Lazarus.FNV1a(rnd); -} - - -/** -* hashes individual words in a bunch of text -*/ -Lazarus.hashText = function(text){ - - //we'll need to grab the seed from the database. - var seed = Lazarus.db.getStr("SELECT value FROM settings WHERE name = 'hash-seed'"); - - if (!seed){ - seed = Lazarus.generateRandomHashSeed(); - Lazarus.db.exe("INSERT INTO settings (name, value) VALUES ('hash-seed', ?1)", seed); - //and delete the full text index, because none of the others will work any more - Lazarus.db.exe("DELETE FROM textdata_fulltext"); - } - - //var p = new Profiler("hashedText: "+ text.length); - var map = {}; - //p.mark("setup"); - - //remove all non-text characters (strip HTML?) - text = Lazarus.trim(text.toLowerCase().replace(/[^\s\w\-_]+/g, ' ')); - //p.mark("remove non-text: "+ text.length); - - var words = text.split(/\s+/g); - //p.mark("split into words : "+ words.length); - //we should also remove useless words (like "the", "and", "as" etc...) - var len = words.length; - var hashedWords = []; - for (var i=0; i=0; i--){ - var info = Lazarus.editorInfos[i]; - //the page may have been submitted, or closed without submitting - //if the editor is suddenly empty, we should assume it has been submitted (possibly via AJAX) - if (!Lazarus.editorExists(info) || Lazarus.getEditorInfo(info.editor).isEmpty){ - removed.push(info); - Lazarus.editorInfos.splice(i, 1); - } - } - - //and save any that have been removed - for (var i=0; i]*>)|( )/g, '').match(/^\s*$/) ? true : false; - } - else { - throw Error("Unknown editor type: "+ type); - } -} - -/** -* return the text/html from an editable iframe or textarea -*/ -Lazarus.extractText = function(ele){ - var text = ''; - if (Lazarus.isTextarea(ele)){ - text = (typeof ele.value == "string") ? ele.value : ''; - } - else if (Lazarus.isIframe(ele)){ - text = (typeof ele.contentWindow.document.body.innerHTML) ? ele.contentWindow.document.body.innerHTML : ''; - } - return Lazarus.trim(text); -} - - -/** -* generate a safe summary for display within a XUL:menuitem or XUL:tooltip -*/ -Lazarus.generateSummary = function(text){ - //strip html - text = Lazarus.htmlToText(text); - return (text.length > 255) ? (text.substr(0, 252) +"...") : text; -} - -Lazarus.restartEditorAutoSaveTimer = function(){ - Lazarus.stopEditorAutoSaveTimer(); - Lazarus.editorAutoSaveFormTimer = setInterval(Lazarus.autoSaveEditors, Lazarus.getExtPref("autoSaveInterval", 2000)); -} -Lazarus.stopEditorAutoSaveTimer = function(){ - if (Lazarus.editorAutoSaveFormTimer){ - clearInterval(Lazarus.editorAutoSaveFormTimer); - } -} - - -/** -* start the autosave timer -*/ -Lazarus.restartAutoSaveTimer = function(form){ - Lazarus.stopAutoSaveTimer(); - //we'll save the form here, so we can retrieve it when the timer fires - Lazarus.currAutoSaveForm = form; - Lazarus.autoSaveFormTimer = setTimeout(Lazarus.autoSaveForm, Lazarus.getExtPref("autoSaveInterval", 2000)); -} - -/** -* stops the autosave timer. -*/ -Lazarus.stopAutoSaveTimer = function(){ - if (Lazarus.autoSaveFormTimer){ - clearTimeout(Lazarus.autoSaveFormTimer); - } -} - -/** -* run cleanup for this window -*/ -Lazarus.cleanup = function(){ - gBrowser.removeEventListener("keyup", Lazarus.onKeyUp, false); - gBrowser.removeEventListener("submit", Lazarus.onFormSubmit, false); - gBrowser.removeEventListener("reset", Lazarus.onFormReset, false); - gBrowser.removeEventListener("change", Lazarus.onFormChange, false); - Lazarus.$("Tools:Sanitize").removeEventListener("command", Lazarus.fireCLearPrivateDataIfNoDialog, false); - Lazarus.stopCleanupTimer(); -} - -/** -* handle last browser window shutting down -*/ -Lazarus.onShutdown = function(){ - -} - -/** -* -*/ -Lazarus.onContextMenuHide = function(){ - Lazarus.isContextMenuShowing = false; -} - - -/** -* show or hide the menu item depending on what item caused the context menu to appear. -*/ -Lazarus.onContextMenuShowing = function(evt){ - - //we need to set a flag to prevent new autosaves whilst the context menu is shown - Lazarus.isContextMenuShowing = true; - - //this event is fired whenever a submenu is shown, as well as when the main context menu it shown - //bugfix: only re-calculate the popup menu when it's first opened. - //trying to alter the initial menu when a submenu is opened can cause the browser to hang. - - //hmmm this is causing a noticable hang when the form contains a lot (30k) of info - //as a workaround, we will not calculate any submenu until the submenu is opened. - var evtTargetId = evt.target.id; - - //quick check - if (evtTargetId != "contentAreaContextMenu" && evtTargetId != "lazarus-restoreform-submenu-menupopup" && evtTargetId != "lazarus-restoretext-submenu-menupopup"){ - return; - } - - - //did the user click on a form? - var form = Lazarus.findFormFromElement(gContextMenu.target); - var editor = Lazarus.findEditorFromElement(gContextMenu.target); - - if (evtTargetId == "contentAreaContextMenu"){ - - //assume we should not show any menuitems - var showMainMenu = false; - var showSubMenu = false; - var showLogin = false; - var showSaveForm = false; - var showPageDisabled = false; - var showPrivateBrowsing = false; - - var showRestoreText = false; - var showRestoreTextDisabled = false; - - - if (!form && !editor){ - //dont show anything - } - else if (Lazarus.isDisabledByPrivateBrowsing()){ - showPrivateBrowsing = true; - } - else if (Lazarus.isPageDisabled(form.ownerDocument.URL)){ - showPageDisabled = true; - } - else if (!Lazarus.canDecrypt()){ - showLogin = true; - } - else { - if (form){ - - showSaveForm = true; - var savedForms = Lazarus.getFormInfo(form, "id, formid, created, savetype, forminfohash, formtext, formname"); - - //just show the one menu item, but dont show it if the form is identical to this one. - if (savedForms.length == 1){ - showMainMenu = true; - var info = Lazarus.formInfo(form); - - var infoHash = Lazarus.generateHash(info.fields); - - if (infoHash == savedForms[0]["forminfohash"]){ - Lazarus.$('lazarus-restoreform-contextmenuitem').setAttribute('src', "chrome://lazarus/skin/lazarus-disable.png"); - Lazarus.$('lazarus-restoreform-contextmenuitem').setAttribute('disabled', "true"); - Lazarus.$('lazarus-restoreform-contextmenuitem').setAttribute('tooltiptext', Lazarus.getString("form.is.equal")); - } - else { - var savedForm = savedForms[0]; - Lazarus.$('lazarus-restoreform-contextmenuitem').setAttribute('src', "chrome://lazarus/skin/lazarus.png"); - Lazarus.$('lazarus-restoreform-contextmenuitem').setAttribute('lazarus-forms-id', savedForm["id"]); - Lazarus.$('lazarus-restoreform-contextmenuitem').setAttribute('tooltiptext', Lazarus.generateSavedFormTooltip(savedForm)); - Lazarus.$('lazarus-restoreform-contextmenuitem').setAttribute('disabled', ""); - } - } - //show submenu - else if (savedForms.length > 1){ - showSubMenu = true; - } - } - - if (editor){ - showRestoreTextDisabled = true; - //do we have any text saved for this domain/basedomain? - var domain = Lazarus.getDomainFromElement(editor); - if (domain){ - var domainHash = Lazarus.md5(domain); - if (Lazarus.db.getInt("SELECT count(id) FROM textdata WHERE domain_hash = ?1 LIMIT 1", domainHash)){ - showRestoreText = true; - showRestoreTextDisabled = false; - } - } - } - } - - //only show our menu item if over a form. - Lazarus.$('lazarus-restoretextdisabled-contextmenuitem').hidden = !showRestoreTextDisabled; - Lazarus.$('lazarus-restoretext-submenu').hidden = !showRestoreText; - Lazarus.$('lazarus-restoreform-contextmenuitem').hidden = !showMainMenu; - Lazarus.$('lazarus-restoreform-submenu').hidden = !showSubMenu; - Lazarus.$('lazarus-enterpassword-contextmenuitem').hidden = !showLogin; - Lazarus.$('lazarus-domaindisabled-contextmenuitem').hidden = !showPageDisabled; - Lazarus.$('lazarus-privatebrowsing-contextmenuitem').hidden = !showPrivateBrowsing; - Lazarus.$('lazarus-saveform-contextmenuitem').hidden = !(showSaveForm && Lazarus.getExtPref("includeExperimental", false)); - } - else if (evtTargetId == "lazarus-restoreform-submenu-menupopup" && form){ - Lazarus.buildSubMenu(form); - } - else if (evtTargetId == "lazarus-restoretext-submenu-menupopup" && editor){ - Lazarus.buildRestoreTextSubMenu(editor); - } -} - - - -Lazarus.getDomainFromElement = function(ele){ - try { - return ele.ownerDocument.defaultView.top.location.host; - } - catch(e){ - return null; - } -} - -/** -* builds the list of items that can be restored for this editor element -*/ -Lazarus.buildRestoreTextSubMenu = function(editor){ - // - var menu = Lazarus.$("lazarus-restoretext-submenu-menupopup"); - //remove all the current submenu items - while(menu.lastChild){ - menu.removeChild(menu.lastChild); - } - - var domainHash = Lazarus.md5(Lazarus.getDomainFromElement(editor)); - - //and build the new ones - var items = Lazarus.db.rs("SELECT id, text_hash, summary_encrypted, created FROM textdata WHERE domain_hash = ?1 ORDER BY created DESC LIMIT ?2", domainHash, Lazarus.getPref('extensions.lazarus.maxTextItemsInSubmenu', 20)); - - var text = Lazarus.extractText(editor); - var textHash = Lazarus.md5(text); - - for (var i=0; i Lazarus.MIN_TEXT_NEEDED_TO_SHOW_NOTIFICATION) && Lazarus.getPref("extensions.lazarus.showDonateNotification") && Lazarus.getPref("extensions.lazarus.restoreFormCount", 0) > 3){ - var msgId = Math.floor(Math.random() * 4); - Lazarus.showNotificationBox("form-restored", Lazarus.getFormRestoredNotificationText(text.length, msgId), "msgid-"+ msgId); - } - } - else { - alert(Lazarus.getString("error.form.db.corrupt")); - } - } - else { - Lazarus.error("Unable to find textdata: "+ id); - alert(Lazarus.getString("error.form.not.found")); - } - } - else { - //should never get here - alert(Lazarus.getString("error.form.object.not.found")); - } -} - - -/** -* generates an md5 hash of a javascript object -*/ -Lazarus.generateHash = function(obj){ - return Lazarus.md5(Lazarus.JSON.encode(obj)); -} - -/** -* return the current unix timestamp -*/ -Lazarus.timestamp = function(asFloat){ - var s = new Date().getTime() / 1000; - return asFloat ? s : Math.floor(s); -} - -/** -* return text usable by a menuitem (XUL Label) -*/ -Lazarus.getMenuItemText = function(text){ - - //strip any html found in the text - text = Lazarus.trim(Lazarus.cleanText(text)); - - //labels only handle a single line of text - text = text.split(/\n/, 2)[0]; - //and we dont want it to be too long - if (text.length > 48){ - text = text.substr(0, 48) +"..."; - } - return Lazarus.trim(text); -} - - -/** -* ask the user for their Lazarus password -*/ -Lazarus.showEnterPasswordDialog = function(){ - - var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService); - - //keep asking until they hit cancel - while(true){ - var password = {value: ""}; - var check = {value: false}; - //if a user has a master password set, then allow the lazarus password to be saved in the SSD - var checkText = Lazarus.isMasterPasswordSet() ? Lazarus.getString('password.dialog.checkbox.label') : null; - // - if (prompts.promptPassword(null, Lazarus.getString("password.dialog.title"), Lazarus.getString("password.dialog.label"), password, checkText, check)){ - if (Lazarus.loadPrivateKey(password.value)){ - if (check.value){ - Lazarus.savePassword(password.value); - } - return true; - } - } - else { - break; - } - } - - return false; -} - - -Lazarus.savePassword = function(password){ - //remove the existing password first. - Lazarus.removePassword(); - var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Components.interfaces.nsILoginInfo, "init"); - var loginInfo = new nsLoginInfo(Lazarus.LOGIN_HOSTNAME, null, Lazarus.LOGIN_REALM, Lazarus.LOGIN_USERNAME, password, '', ''); - var nsLoginManager = Components.classes["@mozilla.org/login-manager;1"].getService(Components.interfaces.nsILoginManager); - nsLoginManager.addLogin(loginInfo); -} - - -Lazarus.removePassword = function(){ - - // Get Login Manager - var nsLoginManager = Components.classes["@mozilla.org/login-manager;1"].getService(Components.interfaces.nsILoginManager); - // Find users for this extension - var logins = nsLoginManager.findLogins({}, Lazarus.LOGIN_HOSTNAME, null, Lazarus.LOGIN_REALM); - for (var i = 0; i < logins.length; i++) { - if (logins[i].username == Lazarus.LOGIN_USERNAME){ - nsLoginManager.removeLogin(logins[i]); - } - } -} - -/** -* load the password from the loginManager -*/ -Lazarus.loadPassword = function(){ - - if (Lazarus.isMasterPasswordSet() && !Lazarus.isMasterPasswordRequired()){ - // Get Login Manager - var nsLoginManager = Components.classes["@mozilla.org/login-manager;1"].getService(Components.interfaces.nsILoginManager); - - // Find users for the given parameters - var logins = nsLoginManager.findLogins({}, Lazarus.LOGIN_HOSTNAME, null, Lazarus.LOGIN_REALM); - - // Find user from returned array of nsILoginInfo objects - for (var i = 0; i < logins.length; i++) { - if (logins[i].username == Lazarus.LOGIN_USERNAME){ - return logins[i].password; - } - } - } - //we default to an empty password - return ''; -} - -Lazarus.logout = function(){ - Lazarus.unloadPrivateKey(); - Lazarus.refreshIcon(); -} - -/** -* generate a label for saved form menuitem -*/ -Lazarus.generateSavedFormLabel = function(savedForm, time){ - var label = ''; - - //template should ALWAYS use their template name as a label - if (savedForm["savetype"] == Lazarus.FORM_TYPE_TEMPLATE){ - label = savedForm["formname"]; - } - //use summary - else if (Lazarus.getExtPref("showFormTextInSubMenu") && Lazarus.canDecrypt()){ - label = Lazarus.getMenuItemText(Lazarus.decrypt(savedForm["formtext"])) || ("["+ Lazarus.getString("untitled") +"]"); - } - //use timestamps if we are unable to decrypt the forms - else { - time = time || Lazarus.timestamp(); - label = Lazarus.getTimeString(time - savedForm["created"]); - } - - //mark autosaved forms so users can easily tell the difference. - switch(savedForm["savetype"]){ - case Lazarus.FORM_TYPE_AUTOSAVE: - case Lazarus.FORM_TYPE_STALE_AUTOSAVE: - label += " "+ Lazarus.getString("menuitem.label.append.autosave"); - break; - - case Lazarus.FORM_TYPE_TEMPLATE: - label += " "+ Lazarus.getString("menuitem.label.append.template"); - break; - - default: - label += " "+ Lazarus.getString("menuitem.label.append.normal"); - break; - } - - return label; -} - -/** -* generate a tooltip for saved form menuitem -*/ -Lazarus.generateSavedFormTooltip = function(savedForm, /**/time){ - - time = time || Lazarus.timestamp(); - - var tooltip = ''; - - //show time sting as tooltip - if (Lazarus.getExtPref("showFormTextInSubMenu")){ - - tooltip = Lazarus.getTimeString(time - savedForm["created"]); - } - //show date and time of save - else { - var date = new Date(savedForm["created"] * 1000); - tooltip = Lazarus.formatDate(date); - } - - //mark autosaved forms so users can easily tell the difference. - switch(savedForm["savetype"]){ - case Lazarus.FORM_TYPE_AUTOSAVE: - case Lazarus.FORM_TYPE_STALE_AUTOSAVE: - tooltip += " "+ Lazarus.getString("menuitem.tooltip.append.autosave"); - break; - - case Lazarus.FORM_TYPE_TEMPLATE: - tooltip += " "+ Lazarus.getString("menuitem.tooltip.append.template"); - break; - - default: - tooltip += " "+ Lazarus.getString("menuitem.tooltip.append.normal"); - break; - //do nothing - } - - return tooltip; -} - -/** -* builds the list of available restore point into the submenu -*/ -Lazarus.buildSubMenu = function(form){ - - - var menu = Lazarus.$("lazarus-restoreform-submenu-menupopup"); - //remove all the current submenu items - for (var i=menu.childNodes.length-1; i>=0; i--){ - var node = menu.childNodes[i]; - if (node.getAttribute("lazarus-dynamic-submenu")){ - menu.removeChild(node); - } - } - - var time = Lazarus.timestamp(); - var separator = Lazarus.$("lazarus-submenu-separator"); - //now build the new ones - var lastSaveType = -1; - var savedForms = Lazarus.getFormInfo(form, "id, formid, created, savetype, forminfohash, formtext, formname, forminfo"); - var info = Lazarus.formInfo(form); - var infoHash = Lazarus.generateHash(info.fields); - - for (var i=0; i 0) ? (Lazarus.timestamp() - expires) : 0; - - fields = fields || "*"; - //we need to get ALL the templates for this form first - var forms = []; - forms = forms.concat(Lazarus.db.rs("SELECT "+ fields +" FROM forms WHERE formid = ?1 AND created >= ?2 AND savetype = "+ Lazarus.FORM_TYPE_TEMPLATE +" ORDER BY savetype DESC, created DESC", formId, cutoffTime)); - //and then the autosaves - var maxAutoSaves = Lazarus.getExtPref("maxAutosavesPerForm", 3); - forms = forms.concat(Lazarus.db.rs("SELECT "+ fields +" FROM forms WHERE formid = ?1 AND created >= ?2 AND savetype IN ("+ Lazarus.FORM_TYPE_AUTOSAVE +","+ Lazarus.FORM_TYPE_STALE_AUTOSAVE +") ORDER BY created DESC LIMIT ?3", formId, cutoffTime, maxAutoSaves)); - //and then add normal saved forms - var maxForms = Lazarus.getExtPref("maxSavesPerForm", 10); - forms = forms.concat(Lazarus.db.rs("SELECT "+ fields +" FROM forms WHERE formid = ?1 AND created >= ?2 AND savetype = "+ Lazarus.FORM_TYPE_NORMAL +" ORDER BY created DESC LIMIT ?3", formId, cutoffTime, maxForms)); - return forms; -} - - -/** -* return a fieldInfo object filled with information about the given field -*/ -Lazarus.fieldInfo = function(ele){ - - var getPassword = Lazarus.getExtPref("savePasswordFields"); - var getHidden = Lazarus.getExtPref("saveHiddenFields"); - - var info = {}; - info.name = ele.getAttribute("name"); - info.type = Lazarus.getElementType(ele); - info.value = Lazarus.getElementValue(ele); - if (info.type == "password" && !getPassword){ - info.value = null; - } - if (info.type == "hidden" && !getHidden){ - info.value = null; - } - - switch (info.type){ - case "text": - case "textarea": - case "file": - case "password": - case "iframe": - if (info.value && Lazarus.trim(info.value)){ - info.text = Lazarus.trim(info.value); - } - break; - - default: - } - - return info; -} - -/** -* clean HTML tags and entities from an html string -*/ -Lazarus.cleanText = function(text){ - return text.replace(/<[^>]*>/g, ' ').replace(/&\w+;?/g, ' ').replace(/ +/g, ' '); -} - -/** -* return a formInfo object filled with details about a form -*/ -Lazarus.formInfo = function(form){ - - var info = {}; - info.version = Lazarus.FORM_INFO_VERSION; - info.formid = Lazarus.getFormId(form); - info.action = Lazarus.getUrlPage(form.action || form.ownerDocument.URL); - info.origURL = form.ownerDocument.URL; - info.domain = Lazarus.getDomainFromElement(form); - info.method = (form.method && form.method.toLowerCase()) == "post" ? "post" : "get"; - info.enctype = form.enctype ? form.enctype.toLowerCase() : ''; - info.fields = {}; - info.formtext = []; - info.textLen = 0; - for (var i=0; i 0){ - info.fields[Lazarus.IFRAME_NAME] = []; - info.isIframe = true; for (var i=0; i= 1){ - alert(Lazarus.getString("error.restore.partial")); - } - return (iRestored / iNamedElements); - } - else { - return true; - } -} - -/** -* handle the onselectmenuitem event -*/ -Lazarus.onRestoreFormMenuItem = function(menuitem){ - - if (!Lazarus.canDecrypt()){ - Lazarus.debug("Unable to restore form, password required"); - Lazarus.showNotificationBox("password-required"); - return; - } - - var id = parseInt(menuitem.getAttribute("lazarus-forms-id")); - - Lazarus.debug("Attempting to restore form "+ id); - var form = Lazarus.findFormFromElement(gContextMenu.target, "form"); - if (form){ - var row = Lazarus.db.getRow("SELECT * FROM forms WHERE id = ?1", id); - if (row){ - var formInfo; - try { - formInfo = Lazarus.JSON.decode(Lazarus.decrypt(row["forminfo"])); - } - catch(e){ - Lazarus.error(e); - } - - if (formInfo){ - //if we fully restore a form, then show the "donate" popup - if (Lazarus.restoreForm(form, formInfo) === true){ - Lazarus.incPref("extensions.lazarus.restoreFormCount"); - if ((formInfo.textLen > Lazarus.MIN_TEXT_NEEDED_TO_SHOW_NOTIFICATION) && Lazarus.getPref("extensions.lazarus.showDonateNotification") && Lazarus.getPref("extensions.lazarus.restoreFormCount", 0) > 3){ - var msgId = Math.floor(Math.random() * 4); - Lazarus.showNotificationBox("form-restored", Lazarus.getFormRestoredNotificationText(formInfo.textLen, msgId), "msgid-"+ msgId); - } - } - } - else { - alert(Lazarus.getString("error.form.db.corrupt")); - } - } - else { - alert(Lazarus.getString("error.form.not.found")); - } - } - else { - alert(Lazarus.getString("error.form.object.not.found")); - } -} - -/** -* return TRUE if form is a form we should save -*/ -Lazarus.shouldSaveForm = function(form){ - //only save forms on file/http/https sites - var doc = form.ownerDocument; - if (doc && doc instanceof HTMLDocument && doc.URL && /^(file|http|https):/.test(doc.URL) && !Lazarus.isPageDisabled(doc.URL) && !Lazarus.isDisabledByPrivateBrowsing()){ - return (Lazarus.isSearchForm(form)) ? Lazarus.getPref("extensions.lazarus.saveSearchForms") : true; - } - else { - return false; - } -} - -/** -* return TRUE if we should be saving this info -*/ -Lazarus.shouldSaveEditorInfo = function(info){ - if (Lazarus.isPageDisabled(info.url)){ - return false; - } - else if (Lazarus.isDisabledByPrivateBrowsing()){ - return false; - } - else { - return true; - } -} - - - -Lazarus.disabledDomains = null; - -Lazarus.isPageDisabled = function(url){ - if (!url && content.document && content.document.URL){ - url = content.document.URL; - } - if (url){ - var domainId = Lazarus.urlToDomainId(url); - if (domainId){ - var domains = Lazarus.getDisabledDomains(); - return (typeof domains[domainId] !== "undefined") ? domains[domainId] : false; - } - } - return false; -} - -/** -* return TRUE if lazarus can save forms from this site -* return FALSE for non-valid sites (eg about:config, chrome://... etc..) -*/ -Lazarus.isValidSite = function(url){ - //default to the current documents url - if (!url && content.document && content.document.URL){ - url = content.document.URL; - } - return (url && Lazarus.urlToDomainId(url)) ? true : false; -} - -Lazarus.getDisabledDomains = function(){ - var domainlist = Lazarus.getPref('extensions.lazarus.domainBlacklist', ''); - - if (!Lazarus.disabledDomains || Lazarus.disabledDomains['__origList__'] != domainlist){ - //rebuild the list - Lazarus.disabledDomains = { - '__origList__': domainlist - } - var domains = domainlist.split(/\s*,\s*/g); - for (var i=0; i -1 && uri.port != 80) ? uri.port : '') +'//'+ Lazarus.getBaseDomain(uri.host) +'/') : ''; -} - - -/** -* return TRUE if form appears to be a search form -*/ -Lazarus.isSearchForm = function(form){ - //search forms are forms that have exactly one textbox, and may contain a number of other non-text fields - var MAX_TEXT_FIELDS = 1; - var MAX_NON_TEXT_FIELDS = 5; - - var iTextFields = 0; - var iNonTextFields = 0; - - for (var i=0; i (TEXT_DIFFERENCE * 2)){ - var str = oldForm.formtext.substr(0, oldForm.formtext.length - TEXT_DIFFERENCE); - //if new form is a continuation of old form (ie the first (X - TEXT_DIFFERENCE) characters are still the same), - //then overwrite current autosave, - //otherwise create a new autosave. - return (newForm.formtext.indexOf(str) == -1); - } - //form contains little text, overwrite the current autosave - else { - return false; - } -} - -/** -* automatically save the form the user is working on. -*/ -Lazarus.autoSaveForm = function(){ - //does the form still exist? - if (Lazarus.currAutoSaveForm && !Lazarus.isContextMenuShowing){ - Lazarus.saveForm(Lazarus.currAutoSaveForm, Lazarus.FORM_TYPE_AUTOSAVE); - } -} - -/** -* start the cleanup timer -*/ -Lazarus.startCleanupTimer = function(){ - - Lazarus.stopCleanupTimer(); - - if (Lazarus.getExpiryTime()){ - Lazarus.cleanupSavedFormsTimer = setInterval(Lazarus.cleanupSavedForms, 1000 * 60); - } -} - -/** -* stop the cleanup timer -*/ -Lazarus.stopCleanupTimer = function(){ - if (Lazarus.cleanupSavedFormsTimer){ - clearInterval(Lazarus.cleanupSavedFormsTimer); - } -} - -/** -* remove old forms from the database -*/ -Lazarus.cleanupSavedForms = function(){ - - //dont cleanup any forms if a user might be trying to retore them - if (Lazarus.isContextMenuShowing){return} - - var expires = Lazarus.getExpiryTime(); - - if (expires > 0){ - //add a couple of minutes to the expiry time, so we don't accidentally - //remove a form whilst we are current restoring it. - var cutoffTime = Lazarus.timestamp() - (expires + 120); - var ids = Lazarus.db.getColumn("SELECT id FROM forms WHERE created < ?1 AND savetype != "+ Lazarus.FORM_TYPE_TEMPLATE, cutoffTime); - Lazarus.removeForms(ids); - - var ids = Lazarus.db.getColumn("SELECT id FROM textdata WHERE created < ?1", cutoffTime); - if (ids.length > 0){ - Lazarus.db.exe("DELETE FROM textdata WHERE id IN ("+ ids.join(",") +")"); - Lazarus.db.exe("DELETE FROM textdata_fulltext WHERE docid IN ("+ ids.join(",") +")"); - } - } - else { - Lazarus.stopCleanupTimer(); - } -} - -/** -* return an identifier for a url -*/ -Lazarus.getUrlPage = function(url){ - var uri = Lazarus.urlToURI(url); - if (uri){ - return uri.scheme +"://"+ uri.hostPort + uri.path.replace(/[\?#].*$/, ''); - } - //for testing on file systems - else if ((Lazarus.getExtPref("debugMode") >= 3) && form.action.match(/^file:\/\//i)){ - return "file://just/testing"; - } - else { - return null; - } -} - -/** -* return the user editable fields within a form. -*/ -Lazarus.getEditableFields = function(form){ - var fields = []; - var saveHidden = Lazarus.getExtPref("saveHiddenFields"); - var savePassword = Lazarus.getExtPref("savePasswordFields"); - - for (var i=0; i= 3) && action.match(/^file:\/\//i)){ - formId = "file://just/testing"; - } - - //and point to the same place - if (formId){ - - //support for ajax textareas - if (form.isTextarea){ - formId += "