From 35374d168604cd08bf85846b0f337084994f7692 Mon Sep 17 00:00:00 2001 From: soulgalore Date: Fri, 21 Feb 2014 21:25:46 +0100 Subject: [PATCH] show redirectsPerPage & maxRequestPerDomain on summary #384 #385 --- bin/sitespeed.io | 4 +-- dependencies/yslow-3.1.8-sitespeed.js | 2 +- .../velocity/logic/site.summary.xml.logic.vm | 34 ++++++++++++++++++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/bin/sitespeed.io b/bin/sitespeed.io index b88aa4649..5a0209516 100755 --- a/bin/sitespeed.io +++ b/bin/sitespeed.io @@ -329,7 +329,7 @@ if [ "$SUMMARY_BOXES" != "" ] SUMMARY_BOXES="-Dcom.soulgalore.velocity.key.boxes=$SUMMARY_BOXES" else # Default columns - SUMMARY_BOXES="-Dcom.soulgalore.velocity.key.boxes=ruleScore,criticalPathScore,jsSyncInHead,jsPerPage,cssPerPage,cssImagesPerPage,imagesPerPage,requests,requestsWithoutExpires,requestsWithoutGZipPerPage,docWeight,jsWeightPerPage,cssWeightPerPage,imageWeightPerPage,pageWeight,browserScaledImages,spofPerPage,domainsPerPage,domElements,assetsCacheTime,timeSinceLastModification" + SUMMARY_BOXES="-Dcom.soulgalore.velocity.key.boxes=ruleScore,criticalPathScore,jsSyncInHead,jsPerPage,cssPerPage,cssImagesPerPage,imagesPerPage,requests,requestsWithoutExpires,requestsWithoutGZipPerPage,docWeight,jsWeightPerPage,cssWeightPerPage,imageWeightPerPage,pageWeight,browserScaledImages,spofPerPage,domainsPerPage,domElements,assetsCacheTime,timeSinceLastModification,maxRequestsPerDomainPerPage,redirectsPerPage" if [ "$COLLECT_BROWSER_TIMINGS" = "true" ] then SUMMARY_BOXES="$SUMMARY_BOXES",serverResponseTime,backEndTime,pageDownloadTime,frontEndTime,domContentLoadedTime,pageLoadTime @@ -830,7 +830,7 @@ OPTIONS: -t The proxy type, default is http [optional] -a The full User Agent string, default is Chrome for MacOSX. You can also set the value as iphone or ipad (will automagically change the viewport) [optional] -v The view port, the page viewport size WidthxHeight, like 400x300, default is 1280x800 [optional] - -y The compiled YSlow file, default is dependencies/yslow-3.1.5-sitespeed.js [optional] + -y The compiled YSlow file, default is dependencies/yslow-3.1.8-sitespeed.js [optional] -l Which ruleset to use, default is the latest sitespeed.io version for desktop [optional] -g The columns showed on detailed page summary table, see http://www.sitespeed.io/documentation/#config-columns for more info [optional] -b The boxes showed on site summary page, see http://www.sitespeed.io/documentation/#config-boxes for more info [optional] diff --git a/dependencies/yslow-3.1.8-sitespeed.js b/dependencies/yslow-3.1.8-sitespeed.js index f15e533fc..e6c7b6147 100644 --- a/dependencies/yslow-3.1.8-sitespeed.js +++ b/dependencies/yslow-3.1.8-sitespeed.js @@ -1 +1 @@ -var resourceWait=1000,maxRenderWait=10000,count=0,renderTimeout;var i,arg,page,urlCount,viewport,webpage=require("webpage"),args=phantom.args,len=args.length,urls=[],yslowArgs={info:"all",format:"json",ruleset:"ydefault",beacon:false,ua:false,viewport:false,headers:false,console:0,threshold:80,cdns:"",basicauth:"",cookie:undefined},unaryArgs={help:false,version:false,dict:false,verbose:false},argsAlias={i:"info",f:"format",r:"ruleset",h:"help",V:"version",d:"dict",u:"ua",vp:"viewport",c:"console",b:"beacon",v:"verbose",t:"threshold",ch:"headers",ba:"basicauth",C:"cookie"};for(i=0;i specify the information to display/log (basic|grade|stats|comps|all) [all]"," -f, --format specify the output results format (json|xml|plain|tap|junit) [json]"," -r, --ruleset specify the YSlow performance ruleset to be used (ydefault|yslow1|yblog) [ydefault]"," -b, --beacon specify an URL to log the results"," -d, --dict include dictionary of results fields"," -v, --verbose output beacon response information"," -t, --threshold for test formats, the threshold to test scores ([0-100]|[A-F]|{JSON}) [80]",' e.g.: -t B or -t 75 or -t \'{"overall": "B", "ycdn": "F", "yexpires": 85}\'',' -u, --ua "" specify the user agent string sent to server when the page requests resources'," -vp, --viewport specify page viewport size WxY, where W = width and H = height [400x300]",' -ch, --headers specify custom request headers, e.g.: -ch \'{"Cookie": "foo=bar"}\''," -c, --console output page console messages (0: none, 1: message, 2: message + line + source) [0]",' -C, --cookie specify an cookie for phantomjs ex) \'{"name":"cookie_name","value":"cookie_value","domain":"localhost"}\'',' --cdns "" specify comma separated list of additional CDNs',' -ba, --basicauth "" username & password used for basic auth',""," Examples:",""," phantomjs "+phantom.scriptName+" http://yslow.org"," phantomjs "+phantom.scriptName+" -i grade -f xml www.yahoo.com www.cnn.com www.nytimes.com"," phantomjs "+phantom.scriptName+' --info all --format plain --ua "MSIE 9.0" http://yslow.org'," phantomjs "+phantom.scriptName+" -i basic --rulseset yslow1 -d http://yslow.org"," phantomjs "+phantom.scriptName+" -i grade -b http://www.showslow.com/beacon/yslow/ -v yslow.org"," phantomjs --load-plugins=yes "+phantom.scriptName+" -vp 800x600 http://www.yahoo.com"," phantomjs "+phantom.scriptName+" -i grade -f tap -t 85 http://yslow.org",""].join("\n"));phantom.exit()}yslowArgs.dict=unaryArgs.dict;yslowArgs.verbose=unaryArgs.verbose;try{cookie=JSON.parse(yslowArgs.cookie,function(k,v){return v})}catch(e){console.log("Error - "+e);cookie=undefined}if(cookie!=undefined){phantom.addCookie(cookie)}urls.forEach(function(url){function finishPhantomJS(exitStatus){urlCount-=1;if(urlCount===0){phantom.exit(exitStatus)}}function doRender(){var yslow,ysphantomjs,controller,evalFunc,loadTime,url,resp,output,exitStatus=0,startTime=page.startTime,resources=page.resources;loadTime=new Date()-startTime;for(url in resources){if(resources.hasOwnProperty(url)){resp=resources[url].response;if(resp){resp.time=new Date(resp.time)-startTime}}}yslow=function(){if(typeof YSLOW==="undefined"){YSLOW={}}YSLOW.DEBUG=true;YSLOW.registerRule=function(rule){YSLOW.controller.addRule(rule)};YSLOW.registerRuleset=function(ruleset){YSLOW.controller.addRuleset(ruleset)};YSLOW.registerRenderer=function(renderer){YSLOW.controller.addRenderer(renderer)};YSLOW.registerTool=function(tool){YSLOW.Tools.addCustomTool(tool)};YSLOW.addEventListener=function(event_name,callback,that){YSLOW.util.event.addListener(event_name,callback,that)};YSLOW.removeEventListener=function(event_name,callback){return YSLOW.util.event.removeListener(event_name,callback)};YSLOW.Error=function(name,message){this.name=name;this.message=message};YSLOW.Error.prototype={toString:function(){return this.name+"\n"+this.message}};YSLOW.version="3.1.8";YSLOW.ComponentSet=function(node,onloadTimestamp){this.root_node=node;this.components=[];this.outstanding_net_request=0;this.component_info=[];this.onloadTimestamp=onloadTimestamp;this.nextID=1;this.notified_fetch_done=false};YSLOW.ComponentSet.prototype={clear:function(){this.components=[];this.component_info=[];this.cleared=true;if(this.outstanding_net_request>0){YSLOW.util.dump("YSLOW.ComponentSet.Clearing component set before all net requests finish.")}},addComponent:function(url,type,base_href,o){var comp,found,isDoc;if(!url){if(!this.empty_url){this.empty_url=[]}this.empty_url[type]=(this.empty_url[type]||0)+1}if(url&&type){if(!YSLOW.ComponentSet.isValidProtocol(url)||!YSLOW.ComponentSet.isValidURL(url)){return comp}url=YSLOW.util.makeAbsoluteUrl(url,base_href);url=YSLOW.util.escapeHtml(url);found=typeof this.component_info[url]!=="undefined";isDoc=type==="doc";if(!found||isDoc){this.component_info[url]={state:"NONE",count:found?this.component_info[url].count:0};comp=new YSLOW.Component(url,type,this,o);if(comp){comp.id=this.nextID+=1;this.components[this.components.length]=comp;if(!this.doc_comp&&isDoc){this.doc_comp=comp}if(this.component_info[url].state==="NONE"){this.component_info[url].state="REQUESTED";this.outstanding_net_request+=1}}else{this.component_info[url].state="ERROR";YSLOW.util.event.fire("componentFetchError")}}this.component_info[url].count+=1}return comp},addComponentNoDuplicate:function(url,type,base_href){if(url&&type){url=YSLOW.util.escapeHtml(url);url=YSLOW.util.makeAbsoluteUrl(url,base_href);if(this.component_info[url]===undefined){return this.addComponent(url,type,base_href)}}},getComponentsByType:function(type,includeAfterOnload,includeBeacons){var i,j,len,lenJ,t,comp,info,components=this.components,compInfo=this.component_info,comps=[],types={};if(typeof includeAfterOnload==="undefined"){includeAfterOnload=!(YSLOW.util.Preference.getPref("excludeAfterOnload",true))}if(typeof includeBeacons==="undefined"){includeBeacons=!(YSLOW.util.Preference.getPref("excludeBeaconsFromLint",true))}if(typeof type==="string"){types[type]=1}else{for(i=0,len=type.length;i0){protocol=s.substr(0,index);for(i=0;i0){that.expires=new Date(that.headers.expires)}}if(that.type==="image"&&!ignoreImgReq){if(typeof Image!==UNDEF){obj=new Image()}else{obj=document.createElement("img")}if(that.body.length){img_src="data:"+that.headers["content-type"]+";base64,"+YSLOW.util.base64Encode(that.body);dataUri=1}else{img_src=that.url}obj.onerror=function(){obj.onerror=NULL;if(dataUri){obj.src=that.url}};obj.onload=function(){obj.onload=NULL;if(obj&&obj.width&&obj.height){if(that.object_prop){that.object_prop.actual_width=obj.width;that.object_prop.actual_height=obj.height}else{that.object_prop={width:obj.width,height:obj.height,actual_width:obj.width,actual_height:obj.height}}if(obj.width<2&&obj.height<2){that.is_beacon=true}}};obj.src=img_src}};YSLOW.Component.prototype.hasOldModifiedDate=function(){var now=Number(new Date()),modified_date=this.headers["last-modified"];if(typeof modified_date!=="undefined"){return((now-Number(new Date(modified_date)))>(24*60*60*1000))}return false};YSLOW.Component.prototype.hasFarFutureExpiresOrMaxAge=function(){var expires_in_seconds,now=Number(new Date()),minSeconds=YSLOW.util.Preference.getPref("minFutureExpiresSeconds",2*24*60*60),minMilliSeconds=minSeconds*1000;if(typeof this.expires==="object"){expires_in_seconds=Number(this.expires);if((expires_in_seconds-now)>minMilliSeconds){return true}}return false};YSLOW.Component.prototype.getEtag=function(){return this.headers.etag||""};YSLOW.Component.prototype.getMaxAge=function(){var index,maxage,expires,cache_control=this.headers["cache-control"];if(cache_control){index=cache_control.indexOf("max-age");if(index>-1){maxage=parseInt(cache_control.substring(index+8),10);if(maxage>0){expires=YSLOW.util.maxAgeToDate(maxage)}}}return expires};YSLOW.Component.prototype.getSetCookieSize=function(){var aCookies,k,size=0;if(this.headers&&this.headers["set-cookie"]){aCookies=this.headers["set-cookie"].split("\n");if(aCookies.length>0){for(k=0;k0){aCookies=this.cookie.split("\n");if(aCookies.length>0){for(k=0;kcomp.parent.onloadTimestamp;comp.populateProperties(false,true);comp.get_info_state="DONE";comp.parent.onComponentGetInfoStateChange({comp:comp,state:"DONE"})};if(o.request&&o.response){parse(o.request,o.response)}};YSLOW.controller={rules:{},rulesets:{},onloadTimestamp:null,renderers:{},default_ruleset_id:"ydefault",run_pending:0,init:function(){var arr_rulesets,i,obj,value;YSLOW.util.event.addListener("onload",function(e){this.onloadTimestamp=e.time;YSLOW.util.setTimer(function(){YSLOW.controller.run_pending_event()})},this);YSLOW.util.event.addListener("onUnload",function(e){this.run_pending=0;this.onloadTimestamp=null},this);arr_rulesets=YSLOW.util.Preference.getPrefList("customRuleset.",undefined);if(arr_rulesets&&arr_rulesets.length>0){for(i=0;i0){obj=JSON.parse(value,null);obj.custom=true;this.addRuleset(obj)}}}this.default_ruleset_id=YSLOW.util.Preference.getPref("defaultRuleset","ydefault");this.loadRulePreference()},run:function(win,yscontext,autorun){var cset,line,doc=win.document;if(!doc||!doc.location||doc.location.href.indexOf("about:")===0||"undefined"===typeof doc.location.hostname){if(!autorun){line="Please enter a valid website address before running YSlow.";YSLOW.ysview.openDialog(YSLOW.ysview.panel_doc,389,150,line,"","Ok")}return}if(!yscontext.PAGE.loaded){this.run_pending={win:win,yscontext:yscontext};return}YSLOW.util.event.fire("peelStart",undefined);cset=YSLOW.peeler.peel(doc,this.onloadTimestamp);yscontext.component_set=cset;YSLOW.util.event.fire("peelComplete",{component_set:cset});cset.notifyPeelDone()},run_pending_event:function(){if(this.run_pending){this.run(this.run_pending.win,this.run_pending.yscontext,false);this.run_pending=0}},lint:function(doc,yscontext,ruleset_id){var rule,rules,i,conf,result,weight,score,ruleset=[],results=[],total_score=0,total_weight=0,that=this,rs=that.rulesets,defaultRuleSetId=that.default_ruleset_id;if(ruleset_id){ruleset=rs[ruleset_id]}else{if(defaultRuleSetId&&rs[defaultRuleSetId]){ruleset=rs[defaultRuleSetId]}else{for(i in rs){if(rs.hasOwnProperty(i)&&rs[i]){ruleset=rs[i];break}}}}rules=ruleset.rules;for(i in rules){if(rules.hasOwnProperty(i)&&rules[i]&&this.rules.hasOwnProperty(i)){try{rule=this.rules[i];conf=YSLOW.util.merge(rule.config,rules[i]);result=rule.lint(doc,yscontext.component_set,conf);weight=(ruleset.weights?ruleset.weights[i]:undefined);if(weight!==undefined){weight=parseInt(weight,10)}if(weight===undefined||weight<0||weight>100){if(rs.ydefault.weights[i]){weight=rs.ydefault.weights[i]}else{weight=5}}result.weight=weight;if(result.score!==undefined){if(typeof result.score!=="number"){score=parseInt(result.score,10);if(!isNaN(score)){result.score=score}}if(typeof result.score==="number"){total_weight+=result.weight;if(!YSLOW.util.Preference.getPref("allowNegativeScore",false)){if(result.score<0){result.score=0}if(typeof result.score!=="number"){result.score=-1}}if(result.score!==0){total_score+=result.score*(typeof result.weight!=="undefined"?result.weight:1)}}}result.name=rule.name;result.category=rule.category;result.rule_id=i;results[results.length]=result}catch(err){YSLOW.util.dump("YSLOW.controller.lint: "+i,err);YSLOW.util.event.fire("lintError",{rule:i,message:err})}}}yscontext.PAGE.overallScore=total_score/(total_weight>0?total_weight:1);yscontext.result_set=new YSLOW.ResultSet(results,yscontext.PAGE.overallScore,ruleset);yscontext.result_set.url=yscontext.component_set.doc_comp.url;YSLOW.util.event.fire("lintResultReady",{yslowContext:yscontext});return yscontext.result_set},runTool:function(tool_id,yscontext,param){var result,html,doc,h,css,uri,req2,l,s,message,body,tool=YSLOW.Tools.getTool(tool_id);try{if(typeof tool==="object"){result=tool.run(yscontext.document,yscontext.component_set,param);if(tool.print_output){html="";if(typeof result==="object"){html=result.html}else{if(typeof result==="string"){html=result}}doc=YSLOW.util.getNewDoc();body=doc.body||doc.documentElement;body.innerHTML=html;h=doc.getElementsByTagName("head")[0];if(typeof result.css==="undefined"){uri="chrome://yslow/content/yslow/tool.css";req2=new XMLHttpRequest();req2.open("GET",uri,false);req2.send(null);css=req2.responseText}else{css=result.css}if(typeof css==="string"){l=doc.createElement("style");l.setAttribute("type","text/css");l.appendChild(doc.createTextNode(css));h.appendChild(l)}if(typeof result.js!=="undefined"){s=doc.createElement("script");s.setAttribute("type","text/javascript");s.appendChild(doc.createTextNode(result.js));h.appendChild(s)}if(typeof result.plot_component!=="undefined"&&result.plot_component===true){YSLOW.renderer.plotComponents(doc,yscontext)}}}else{message=tool_id+" is not a tool.";YSLOW.util.dump(message);YSLOW.util.event.fire("toolError",{tool_id:tool_id,message:message})}}catch(err){YSLOW.util.dump("YSLOW.controller.runTool: "+tool_id,err);YSLOW.util.event.fire("toolError",{tool_id:tool_id,message:err})}},render:function(id,view,params){var renderer=this.renderers[id],content="";if(renderer.supports[view]!==undefined&&renderer.supports[view]===1){switch(view){case"components":content=renderer.componentsView(params.comps,params.total_size);break;case"reportcard":content=renderer.reportcardView(params.result_set);break;case"stats":content=renderer.statsView(params.stats);break;case"tools":content=renderer.toolsView(params.tools);break;case"rulesetEdit":content=renderer.rulesetEditView(params.rulesets);break}}return content},getRenderer:function(id){return this.renderers[id]},addRule:function(rule){var i,doc_obj,required=["id","name","config","info","lint"];if(YSLOW.doc.rules&&YSLOW.doc.rules[rule.id]){doc_obj=YSLOW.doc.rules[rule.id];if(doc_obj.name){rule.name=doc_obj.name}if(doc_obj.info){rule.info=doc_obj.info}}for(i=0;i0&&rule){rule.config.howfar=minSeconds}}};YSLOW.util={merge:function(a,b){var i,o={};for(i in a){if(a.hasOwnProperty(i)){o[i]=a[i]}}for(i in b){if(b.hasOwnProperty(i)){o[i]=b[i]}}return o},dump:function(){var args;if(!YSLOW.DEBUG){return}args=Array.prototype.slice.apply(arguments);args=args&&args.length===1?args[0]:args;try{if(typeof Firebug!=="undefined"&&Firebug.Console&&Firebug.Console.log){Firebug.Console.log(args)}else{if(typeof Components!=="undefined"&&Components.classes&&Components.interfaces){Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService).logStringMessage(JSON.stringify(args,null,2))}}}catch(e1){try{console.log(args)}catch(e2){}}},filter:function(hash,callback,rekey){var i,result=rekey?[]:{};for(i in hash){if(hash.hasOwnProperty(i)&&callback(i,hash[i])){result[rekey?result.length:i]=hash[i]}}return result},expires_month:{Jan:1,Feb:2,Mar:3,Apr:4,May:5,Jun:6,Jul:7,Aug:8,Sep:9,Oct:10,Nov:11,Dec:12},prettyExpiresDate:function(expires){var month;if(Object.prototype.toString.call(expires)==="[object Date]"&&expires.toString()!=="Invalid Date"&&!isNaN(expires)){month=expires.getMonth()+1;return expires.getFullYear()+"/"+month+"/"+expires.getDate()}else{if(!expires){return"no expires"}}return"invalid date object"},maxAgeToDate:function(seconds){var d=new Date();d=d.getTime()+parseInt(seconds,10)*1000;return new Date(d)},plural:function(template,number){var i,res=template,repl={are:["are","is"],s:["s",""],"do":["do","does"],num:[number,number]};for(i in repl){if(repl.hasOwnProperty(i)){res=res.replace(new RegExp("%"+i+"%","gm"),(number===1)?repl[i][1]:repl[i][0])}}return res},countExpressions:function(content){var num_expr=0,index;index=content.indexOf("expression(");while(index!==-1){num_expr+=1;index=content.indexOf("expression(",index+1)}return num_expr},countAlphaImageLoaderFilter:function(content){var index,colon,filter_hack,value,num_filter=0,num_hack_filter=0,result={};index=content.indexOf("filter:");while(index!==-1){filter_hack=false;if(index>0&&content.charAt(index-1)==="_"){filter_hack=true}colon=content.indexOf(";",index+7);if(colon!==-1){value=content.substring(index+7,colon);if(value.indexOf("AlphaImageLoader")!==-1){if(filter_hack){num_hack_filter+=1}else{num_filter+=1}}}index=content.indexOf("filter:",index+1)}if(num_hack_filter>0){result.hackFilter=num_hack_filter}if(num_filter>0){result.filter=num_filter}return result},getHostname:function(url){var hostname=url.split("/")[2];return(hostname&&hostname.split(":")[0])||""},getUniqueDomains:function(comps,exclude_ips){var i,len,parts,domains={},retval=[];for(i=0,len=comps.length;i0.2){return false}return true},isETagGood:function(etag){var reIIS=/^[0-9a-f]+:([1-9a-f]|[0-9a-f]{2,})$/,reApache=/^[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+$/;if(!etag){return true}etag=etag.replace(/^["']|["'][\s\S]*$/g,"");return !(reApache.test(etag)||reIIS.test(etag))},getComponentType:function(content_type){var c_type="unknown";if(content_type&&typeof content_type==="string"){if(content_type==="text/html"||content_type==="text/plain"){c_type="doc"}else{if(content_type==="text/css"){c_type="css"}else{if(/javascript/.test(content_type)){c_type="js"}else{if(/flash/.test(content_type)){c_type="flash"}else{if(/image/.test(content_type)){c_type="image"}else{if(/font/.test(content_type)){c_type="font"}}}}}}}return c_type},base64Encode:function(data){var i,a,b,c,new_data="",padding=0,arr=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"];for(i=0;i>2];new_data+=arr[((a&3)<<4)|((b&240)>>4)];if(padding>0){new_data+="="}else{new_data+=arr[((b&15)<<2)|((c&192)>>6)]}if(padding>1){new_data+="="}else{new_data+=arr[(c&63)]}}return new_data},getXHR:function(){var i=0,xhr=null,ids=["MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];if(typeof XMLHttpRequest==="function"){return new XMLHttpRequest()}for(i=0;i/g,">")},escapeQuotes:function(str,which){if(which==="single"){return str.replace(/\'/g,"\\'")}if(which==="double"){return str.replace(/\"/g,'\\"')}return str.replace(/\'/g,"\\'").replace(/\"/g,'\\"')},formatHeaderName:(function(){var specialCases={"content-md5":"Content-MD5",dnt:"DNT",etag:"ETag",p3p:"P3P",te:"TE","www-authenticate":"WWW-Authenticate","x-att-deviceid":"X-ATT-DeviceId","x-cdn":"X-CDN","x-ua-compatible":"X-UA-Compatible","x-xss-protection":"X-XSS-Protection"};return function(headerName){var lowerCasedHeaderName=headerName.toLowerCase();if(specialCases.hasOwnProperty(lowerCasedHeaderName)){return specialCases[lowerCasedHeaderName]}else{return lowerCasedHeaderName.replace(/(^|-)([a-z])/g,function($0,optionalLeadingDash,ch){return optionalLeadingDash+ch.toUpperCase()})}}}()),mod:function(divisee,base){return Math.round(divisee-(Math.floor(divisee/base)*base))},briefUrl:function(url,maxchars){var iDoubleSlash,iQMark,iFirstSlash,iLastSlash;maxchars=maxchars||100;if(url===undefined){return""}iDoubleSlash=url.indexOf("//");if(-1!==iDoubleSlash){iQMark=url.indexOf("?");if(-1!==iQMark){url=url.substring(0,iQMark)+"?..."}if(url.length>maxchars){iFirstSlash=url.indexOf("/",iDoubleSlash+2);iLastSlash=url.lastIndexOf("/");if(-1!==iFirstSlash&&-1!==iLastSlash&&iFirstSlash!==iLastSlash){url=url.substring(0,iFirstSlash+1)+"..."+url.substring(iLastSlash)}else{url=url.substring(0,maxchars+1)+"..."}}}return url},prettyAnchor:function(text,url,sClass,bBriefUrl,maxChars,numLines,rel){var escaped_dq_url,sTitle="",sResults="",iLines=0;if(typeof url==="undefined"){url=text}if(typeof sClass==="undefined"){sClass=""}else{sClass=' class="'+sClass+'"'}if(typeof maxChars==="undefined"){maxChars=100}if(typeof numLines==="undefined"){numLines=1}rel=(rel)?' rel="'+rel+'"':"";url=YSLOW.util.escapeHtml(url);text=YSLOW.util.escapeHtml(text);escaped_dq_url=YSLOW.util.escapeQuotes(url,"double");if(bBriefUrl){text=YSLOW.util.briefUrl(text,maxChars);sTitle=' title="'+escaped_dq_url+'"'}while(0"+text.substring(0,maxChars);text=text.substring(maxChars);iLines+=1;if(iLines>=numLines){if(0";break}else{sResults+=" "}}return sResults},kbSize:function(size){var remainder=size%(size>100?100:10);size-=remainder;return parseFloat(size/1000)+(0===(size%1000)?".0":"")+"K"},prettyTypes:{image:"Image",doc:"HTML/Text",cssimage:"CSS Image",css:"Stylesheet File",js:"JavaScript File",flash:"Flash Object",iframe:"IFrame",xhr:"XMLHttpRequest",redirect:"Redirect",favicon:"Favicon",unknown:"Unknown"},prettyType:function(sType){return YSLOW.util.prettyTypes[sType]},prettyScore:function(score){var letter="F";if(!parseInt(score,10)&&score!==0){return score}if(score===-1){return"N/A"}if(score>=90){letter="A"}else{if(score>=80){letter="B"}else{if(score>=70){letter="C"}else{if(score>=60){letter="D"}else{if(score>=50){letter="E"}}}}}return letter},getResults:function(yscontext,info){var i,l,results,url,type,comps,comp,encoded_url,obj,cr,cs,etag,name,len,include_grade,include_comps,include_stats,result,len2,spaceid,header,sourceHeaders,targetHeaders,reButton=/ "):"")}}return{score:score,message:message,components:offenders}}});YSLOW.registerRule({id:"yexpires",url:"http://developer.yahoo.com/performance/rules.html#expires",category:["server"],config:{points:11,howfar:172800,types:["css","js","image","cssimage","flash","favicon"]},lint:function(doc,cset,config){var ts,i,expiration,score,len,far=parseInt(config.howfar,10)*1000,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;its+far){continue}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% static component%s%",offenders.length)+" without a far-future expiration date.":"",components:offenders}}});YSLOW.registerRule({id:"ycompress",url:"http://developer.yahoo.com/performance/rules.html#gzip",category:["server"],config:{min_filesize:500,types:["doc","iframe","xhr","js","css"],points:11},lint:function(doc,cset,config){var i,len,score,comp,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% plain text component%s%",offenders.length)+" that should be sent compressed":"",components:offenders}}});YSLOW.registerRule({id:"ycsstop",url:"http://developer.yahoo.com/performance/rules.html#css_top",category:["css"],config:{points:10},lint:function(doc,cset,config){var i,len,score,comp,comps=cset.getComponentsByType("css"),offenders=[];for(i=0,len=comps.length;i0){score-=1+offenders.length*parseInt(config.points,10)}return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% stylesheet%s%",offenders.length)+" found in the body of the document":"",components:offenders}}});YSLOW.registerRule({id:"yjsbottom",url:"http://developer.yahoo.com/performance/rules.html#js_bottom",category:["javascript"],config:{points:5},lint:function(doc,cset,config){var i,len,comp,score,offenders=[],comps=cset.getComponentsByType("js");for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% JavaScript script%s%",offenders.length)+" found in the head of the document":"",components:offenders}}});YSLOW.registerRule({id:"yexpressions",url:"http://developer.yahoo.com/performance/rules.html#css_expressions",category:["css"],config:{points:2},lint:function(doc,cset,config){var i,len,expr_count,comp,instyles=(cset.inline&&cset.inline.styles)||[],comps=cset.getComponentsByType("css"),offenders=[],score=100,total=0;for(i=0,len=comps.length;i0){comp.yexpressions=YSLOW.util.plural("%num% expression%s%",expr_count);total+=expr_count;offenders.push(comp)}}for(i=0,len=instyles.length;i0){offenders.push("inline <style> tag #"+(i+1)+" ("+YSLOW.util.plural("%num% expression%s%",expr_count)+")");total+=expr_count}}if(total>0){score=90-total*config.points}return{score:score,message:total>0?"There is a total of "+YSLOW.util.plural("%num% expression%s%",total):"",components:offenders}}});YSLOW.registerRule({id:"yexternal",url:"http://developer.yahoo.com/performance/rules.html#external",category:["javascript","css"],config:{},lint:function(doc,cset,config){var message,inline=cset.inline,styles=(inline&&inline.styles)||[],scripts=(inline&&inline.scripts)||[],offenders=[];if(styles.length){message=YSLOW.util.plural("There is a total of %num% inline css",styles.length);offenders.push(message)}if(scripts.length){message=YSLOW.util.plural("There is a total of %num% inline script%s%",scripts.length);offenders.push(message)}return{score:"n/a",message:"Only consider this if your property is a common user home page.",components:offenders}}});YSLOW.registerRule({id:"ydns",url:"http://developer.yahoo.com/performance/rules.html#dns_lookups",category:["content"],config:{max_domains:4,points:5},lint:function(doc,cset,config){var i,len,domain,util=YSLOW.util,kbSize=util.kbSize,plural=util.plural,score=100,domains=util.summaryByDomain(cset.components,["size","size_compressed"],true);if(domains.length>config.max_domains){score-=(domains.length-config.max_domains)*config.points}if(domains.length){for(i=0,len=domains.length;i0?" ("+kbSize(domain.sum_size_compressed)+" GZip)":"")}}return{score:score,message:(domains.length>config.max_domains)?plural("The components are split over more than %num% domain%s%",config.max_domains):"",components:domains}}});YSLOW.registerRule({id:"yminify",url:"http://developer.yahoo.com/performance/rules.html#minify",category:["javascript","css"],config:{points:10,types:["js","css"]},lint:function(doc,cset,config){var i,len,score,minified,comp,inline=cset.inline,styles=(inline&&inline.styles)||[],scripts=(inline&&inline.scripts)||[],comps=cset.getComponentsByType(config.types),offenders=[];for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% component%s% that can be minified",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yredirects",url:"http://developer.yahoo.com/performance/rules.html#redirects",category:["content"],config:{points:10},lint:function(doc,cset,config){var i,len,comp,score,offenders=[],briefUrl=YSLOW.util.briefUrl,comps=cset.getComponentsByType("redirect");for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% redirect%s%",comps.length):"",components:offenders}}});YSLOW.registerRule({id:"ydupes",url:"http://developer.yahoo.com/performance/rules.html#js_dupes",category:["javascript","css"],config:{points:5,types:["js","css"]},lint:function(doc,cset,config){var i,url,score,len,hash={},offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i1){offenders.push(comps[hash[i].compindex])}}score=100-offenders.length*parseInt(config.points,10);return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% duplicate component%s%",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yetags",url:"http://developer.yahoo.com/performance/rules.html#etags",category:["server"],config:{points:11,types:["flash","js","css","cssimage","image","favicon"]},lint:function(doc,cset,config){var i,len,score,comp,etag,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% component%s% with misconfigured ETags",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yxhr",url:"http://developer.yahoo.com/performance/rules.html#cacheajax",category:["content"],config:{points:5,min_cache_time:3600},lint:function(doc,cset,config){var i,expiration,ts,score,cache_control,min=parseInt(config.min_cache_time,10)*1000,offenders=[],comps=cset.getComponentsByType("xhr");for(i=0;its+min){continue}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% XHR component%s% that %are% not cacheable",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yxhrmethod",url:"http://developer.yahoo.com/performance/rules.html#ajax_get",category:["server"],config:{points:5},lint:function(doc,cset,config){var i,score,offenders=[],comps=cset.getComponentsByType("xhr");for(i=0;i0)?YSLOW.util.plural("There %are% %num% XHR component%s% that %do% not use GET HTTP method",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ymindom",url:"http://developer.yahoo.com/performance/rules.html#min_dom",category:["content"],config:{range:250,points:10,maxdom:900},lint:function(doc,cset,config){var numdom=cset.domElementsCount,score=100;if(numdom>config.maxdom){score=99-Math.ceil((numdom-parseInt(config.maxdom,10))/parseInt(config.range,10))*parseInt(config.points,10)}return{score:score,message:(numdom>config.maxdom)?YSLOW.util.plural("There %are% %num% DOM element%s% on the page",numdom):"",components:[]}}});YSLOW.registerRule({id:"yno404",url:"http://developer.yahoo.com/performance/rules.html#no404",category:["content"],config:{points:5,types:["css","js","image","cssimage","flash","xhr","favicon"]},lint:function(doc,cset,config){var i,len,comp,score,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% request%s% that %are% 404 Not Found",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ymincookie",url:"http://developer.yahoo.com/performance/rules.html#cookie_size",category:["cookie"],config:{points:10,max_cookie_size:1000},lint:function(doc,cset,config){var n,cookies=cset.cookies,cookieSize=(cookies&&cookies.length)||0,message="",score=100;if(cookieSize>config.max_cookie_size){n=Math.floor(cookieSize/config.max_cookie_size);score-=1+n*parseInt(config.points,10);message=YSLOW.util.plural("There %are% %num% byte%s% of cookies on this page",cookieSize)}return{score:score,message:message,components:[]}}});YSLOW.registerRule({id:"ycookiefree",url:"http://developer.yahoo.com/performance/rules.html#cookie_free",category:["cookie"],config:{points:5,types:["js","css","image","cssimage","flash","favicon"]},lint:function(doc,cset,config){var i,len,score,comp,cookie,offenders=[],getHostname=YSLOW.util.getHostname,docDomain=getHostname(cset.doc_comp.url),comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% component%s% that %are% not cookie-free",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ynofilter",url:"http://developer.yahoo.com/performance/rules.html#no_filters",category:["css"],config:{points:5,halfpoints:2},lint:function(doc,cset,config){var i,len,score,comp,type,count,filter_count,instyles=(cset.inline&&cset.inline.styles)||[],comps=cset.getComponentsByType("css"),offenders=[],filter_total=0,hack_filter_total=0;for(i=0,len=comps.length;i0){comps[i].yfilters=YSLOW.util.plural("%num% filter%s%",count);offenders.push(comps[i])}}for(i=0,len=instyles.length;i0){offenders.push("inline <style> tag #"+(i+1)+" ("+YSLOW.util.plural("%num% filter%s%",count)+")")}}score=100-(filter_total*config.points+hack_filter_total*config.halfpoints);return{score:score,message:(filter_total+hack_filter_total)>0?"There is a total of "+YSLOW.util.plural("%num% filter%s%",filter_total+hack_filter_total):"",components:offenders}}});YSLOW.registerRule({id:"yimgnoscale",url:"http://developer.yahoo.com/performance/rules.html#no_scale",category:["images"],config:{points:5},lint:function(doc,cset,config){var i,prop,score,offenders=[],comps=cset.getComponentsByType("image");for(i=0;i0)?YSLOW.util.plural("There %are% %num% image%s% that %are% scaled down",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yfavicon",url:"http://developer.yahoo.com/performance/rules.html#favicon",category:["images"],config:{points:5,size:2000,min_cache_time:3600},lint:function(doc,cset,config){var ts,expiration,comp,score,cacheable,messages=[],min=parseInt(config.min_cache_time,10)*1000,comps=cset.getComponentsByType("favicon");if(comps.length){comp=comps[0];if(parseInt(comp.status,10)===404){messages.push("Favicon was not found")}if(comp.size>config.size){messages.push(YSLOW.util.plural("Favicon is more than %num% bytes",config.size))}expiration=comp.expires;if(typeof expiration==="object"&&typeof expiration.getTime==="function"){ts=new Date().getTime();cacheable=expiration.getTime()>=ts+min}if(!cacheable){messages.push("Favicon is not cacheable")}}score=100-messages.length*parseInt(config.points,10);return{score:score,message:(messages.length>0)?messages.join("\n"):"",components:[]}}});YSLOW.registerRule({id:"yemptysrc",url:"http://developer.yahoo.com/performance/rules.html#emptysrc",category:["server"],config:{points:100},lint:function(doc,cset,config){var type,score,count,emptyUrl=cset.empty_url,offenders=[],messages=[],msg="",points=parseInt(config.points,10);score=100;if(emptyUrl){for(type in emptyUrl){if(emptyUrl.hasOwnProperty(type)){count=emptyUrl[type];score-=count*points;messages.push(count+" "+type)}}msg=messages.join(", ")+YSLOW.util.plural(" component%s% with empty link were found.",messages.length)}return{score:score,message:msg,components:offenders}}});YSLOW.registerRuleset({id:"ydefault",name:"YSlow(V2)",rules:{ynumreq:{},ycdn:{},yemptysrc:{},yexpires:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},yexternal:{},ydns:{},yminify:{},yredirects:{},ydupes:{},yetags:{},yxhr:{},yxhrmethod:{},ymindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},yimgnoscale:{},yfavicon:{}},weights:{ynumreq:8,ycdn:6,yemptysrc:30,yexpires:10,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,yexternal:4,ydns:3,yminify:4,yredirects:4,ydupes:4,yetags:2,yxhr:4,yxhrmethod:3,ymindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,yimgnoscale:3,yfavicon:2}});YSLOW.registerRuleset({id:"yslow1",name:"Classic(V1)",rules:{ynumreq:{},ycdn:{},yexpires:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},yexternal:{},ydns:{},yminify:{types:["js"],check_inline:false},yredirects:{},ydupes:{types:["js"]},yetags:{}},weights:{ynumreq:8,ycdn:6,yexpires:10,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,yexternal:4,ydns:3,yminify:4,yredirects:4,ydupes:4,yetags:2}});YSLOW.registerRuleset({id:"yblog",name:"Small Site or Blog",rules:{ynumreq:{},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},yredirects:{},ydupes:{},ymindom:{},yno404:{},ynofilter:{},yimgnoscale:{},yfavicon:{}},weights:{ynumreq:8,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,yredirects:4,ydupes:4,ymindom:3,yno404:4,ynofilter:4,yimgnoscale:3,yfavicon:2}});var SITESPEEDHELP={};SITESPEEDHELP.getTLD=function(host){var tld=host;var noSecondaries=/\.(gov|ac|mil|net|org|co)\.\w\w$/i;if(host.match(noSecondaries)){var threePart=/[\w]+\.[\w]+\.[\w]+$/i;tld=host.match(threePart).toString()}else{var twoPart=/[\w]+\.[\w]+$/i;tld=host.match(twoPart).toString()}return tld};SITESPEEDHELP.getTextLength=function(element){var avoidTextInScriptAndStyle=("script style").split(" ");var textLength=0;function getLength(element){if(element.childNodes&&element.childNodes.length>0){for(var i=0;i=(edge||0)}SITESPEEDHELP.versionCompare=function(userVersion,edgeVersion){if(userVersion===undefined){return true}userVersion=userVersion.split(".");var major=digitCompare(userVersion[0],edgeVersion[0]),minor=digitCompare(userVersion[1],edgeVersion[1]),build=digitCompare(userVersion[2],edgeVersion[2]);return(!major||major&&!minor||major&&minor&&!build)};SITESPEEDHELP.isSameDomainTLD=function(docDomainTLD,cssUrl,fontFaceUrl){if((/^http/).test(fontFaceUrl)){if(docDomainTLD===SITESPEEDHELP.getTLD(YSLOW.util.getHostname(fontFaceUrl))){return true}else{return false}}else{if(docDomainTLD===SITESPEEDHELP.getTLD(YSLOW.util.getHostname(cssUrl))){return true}else{return false}}return false};YSLOW.registerRule({id:"cssprint",name:"Do not load print stylesheets, use @media type print instead",info:"Loading a specific stylesheet for printing slows down the page, even though it is not used",category:["css"],config:{points:20},url:"http://sitespeed.io/rules/#cssprint",lint:function(doc,cset,config){var i,media,score,url,offenders=[],hash={},comps=cset.getComponentsByType("css"),links=doc.getElementsByTagName("link");for(i=0,len=links.length;i0)?YSLOW.util.plural("There %are% %num% print css files included on the page, that should be @media query instead",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ttfb",name:"Time to first byte",info:"It is important to have low time to the first byte to be able to render the page fast",category:["server"],config:{points:10,limitInMs:300,hurtEveryMs:100},url:"http://sitespeed.io/rules/#ttfb",lint:function(doc,cset,config){var i,limit=parseInt(config.limitInMs,10),hurtEveryMs=parseInt(config.hurtEveryMs,10),score,ttfb,comps=cset.getComponentsByType("doc");for(i=0,len=comps.length;ilimit){score=100-(Math.ceil((ttfb-limit)/hurtEveryMs)*parseInt(config.points,10))}}if(score<0){score=0}return{score:score,message:(score<100)?"The TTFB is too slow:"+ttfb+" ms. The limit is "+limit+" ms and for every "+hurtEveryMs+" ms points are removed":"",components:[""+ttfb]}}});YSLOW.registerRule({id:"cssinheaddomain",name:"Load CSS in head from document domain",info:"Make sure css in head is loaded from same domain as document, in order to have a better user experience and minimize dns lookups",category:["css"],config:{points:10},url:"http://sitespeed.io/rules/#cssinheaddomain",lint:function(doc,cset,config){var css=doc.getElementsByTagName("link"),comps=cset.getComponentsByType("css"),comp,docdomain,src,offenders={},offendercomponents=[],uniquedns=[],score=100;docdomain=YSLOW.util.getHostname(cset.doc_comp.url);for(i=0,len=css.length;its){continue}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);message=(offenders.length>0)?YSLOW.util.plural("There %are% %num% static component%s%",offenders.length)+" without a future expiration date.":"";return{score:score,message:message,components:offenders}}});YSLOW.registerRule({id:"longexpirehead",name:"Have expires headers equals or longer than one year",info:"All static components of a page should have at least one year expire header. However, analythics scripts will not give you bad points.",url:"http://sitespeed.io/rules/#longexpires",category:["server"],config:{points:5,types:["css","js","image","cssimage","flash","favicon"],skip:["https://secure.gaug.es/track.js","https://ssl.google-analytics.com/ga.js","http://www.google-analytics.com/ga.js"]},lint:function(doc,cset,config){var ts,i,expiration,score,len,message,offenders=[],skipped=[],far=31535000*1000,comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;its+far){continue}else{if(config.skip.indexOf(comps[i].url)>1){skipped.push(comps[i].url);continue}}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);message=(offenders.length>0)?YSLOW.util.plural("There %are% %num% static component%s%",offenders.length)+" without a expire header equal or longer than one year.":"";message+=(skipped.length>0)?YSLOW.util.plural(" There %are% %num% static component%s% that are skipped from the score calculation",skipped.length)+":"+skipped:"";return{score:score,message:message,components:offenders}}});YSLOW.registerRule({id:"inlinecsswhenfewrequest",name:"Do not load css files when the page has few request",info:"When a page has few requests, it is better to inline the css, to make the page to start render as early as possible",category:["css"],config:{points:20,limit:15,types:["css","js","image","cssimage","flash","favicon"]},url:"http://sitespeed.io/rules/#inlinecsswhenfewrequest",lint:function(doc,cset,config){var comps=cset.getComponentsByType(config.types),css=cset.getComponentsByType("css"),message="",score=100,offenders=[];if(comps.length0){for(i=0,len=css.length;i1){for(i=0,len=comps.length;iconfig.max_css){score-=(css.length-config.max_css)*config.points_css;message="This page has "+YSLOW.util.plural("%num% external stylesheet%s%",css.length)+". Try combining them into fewer requests.";for(var i=0;iconfig.max_cssimages){score-=(cssimages.length-config.max_cssimages)*config.points_cssimages;message="This page has "+YSLOW.util.plural("%num% external css image%s%",cssimages.length)+". Try combining them into fewer request.";for(var i=0;iconfig.max_js){message="There "+YSLOW.util.plural("%are% %num% script%s%",offender_comps.length)+" loaded synchronously that could be combined into fewer requests.";score-=(offender_comps.length-config.max_js)*parseInt(config.points_js,10)}return{score:score,message:message,components:offender_comps}}});YSLOW.registerRule({id:"noduplicates",name:"Remove duplicate JS and CSS",info:"It is bad practice include the same js or css twice",category:["js","css"],config:{},url:"http://developer.yahoo.com/performance/rules.html#js_dupes",lint:function(doc,cset,config){var i,url,score,len,comp,hash={},offenders=[],comps=cset.getComponentsByType(["js","css"]),scripts=doc.getElementsByTagName("script"),css=doc.getElementsByTagName("link");for(i=0,len=scripts.length;i1){offenders.push(comps[i])}}score=100-offenders.length*11;return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% js/css file%s% included more than once on the page",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"mindom",name:"Reduce the number of DOM elements",info:"The number of dom elements are in correlation to if the page is fast or not",url:"http://developer.yahoo.com/performance/rules.html#min_dom",category:["content"],config:{range:250,points:10,maxdom:900},lint:function(doc,cset,config){var numdom=cset.domElementsCount,score=100;if(numdom>config.maxdom){score=99-Math.ceil((numdom-parseInt(config.maxdom,10))/parseInt(config.range,10))*parseInt(config.points,10)}return{score:score,message:(numdom>config.maxdom)?YSLOW.util.plural("There %are% %num% DOM element%s% on the page",numdom):"",components:[""+numdom]}}});YSLOW.registerRule({id:"thirdpartyversions",name:"Always use latest versions of third party javascripts",info:"Unisng the latest versions, will make sure you have the fastest and hopefully leanest javascripts.",url:"http://sitespeed.io/rules/#thirdpartyversions",category:["js"],config:{points:10},lint:function(doc,cset,config){var message="",score,offenders=0;if(typeof jQuery=="function"){if(SITESPEEDHELP.versionCompare(jQuery.fn.jquery,[2,0,0])){message="You are using an old version of JQuery: "+jQuery.fn.jquery+" Newer version is faster & better. Upgrade to the newest version from http://jquery.com/";offenders+=1}}score=100-offenders*parseInt(config.points,10);return{score:score,message:message,components:[]}}});YSLOW.registerRule({id:"avoidscalingimages",name:"Never scale images in HTML",info:"Always use the correct size for images to avoid that a browser download an image that is larger than necessary.",url:"http://sitespeed.io/rules/#avoidscalingimages",category:["images"],config:{reallyBadLimit:100},lint:function(doc,cset,config){var message="",score,offenders=[],hash={},punish=0,comps=cset.getComponentsByType("image"),images=doc.getElementsByTagName("img");for(var i=0;i0){message=message+" "+img.src+" [browserWidth:"+img.clientWidth+" realImageWidth: "+img.naturalWidth+"]";hash[img.src]=1;if((img.clientWidth+config.reallyBadLimit)0)?YSLOW.util.plural("You have %num% image%s% that %are% scaled in the HTML:"+message,offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"redirects",name:"Never do redirects",info:"Avoid doing redirects, it will kill you web page on mobile.",url:"http://sitespeed.io/rules/#redirects",category:["content"],config:{points:10},lint:function(doc,cset,config){var score;score=100-cset.redirects.length*parseInt(config.points,10);return{score:score,message:(cset.redirects.length>0)?YSLOW.util.plural("There %are% %num% redirect%s%.",cset.redirects.length)+" "+cset.redirects:"",components:[]}}});YSLOW.registerRuleset({id:"sitespeed.io-desktop",name:"Sitespeed.io desktop rules",rules:{criticalpath:{},spof:{fontFaceInCssSpof:false,inlineFontFaceSpof:false},cssnumreq:{},cssimagesnumreq:{},jsnumreq:{},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},redirects:{},noduplicates:{},yetags:{},yxhr:{},yxhrmethod:{},mindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},avoidscalingimages:{},yfavicon:{},thirdpartyasyncjs:{},cssprint:{},cssinheaddomain:{},syncjsinhead:{},avoidfont:{},totalrequests:{},expiresmod:{},longexpirehead:{},nodnslookupswhenfewrequests:{},inlinecsswhenfewrequest:{},textcontent:{},thirdpartyversions:{},ycdn:{}},weights:{criticalpath:15,spof:5,cssnumreq:8,cssimagesnumreq:8,jsnumreq:8,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,redirects:4,noduplicates:4,yetags:2,yxhr:4,yxhrmethod:3,mindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,avoidscalingimages:5,yfavicon:2,thirdpartyasyncjs:10,cssprint:3,cssinheaddomain:8,syncjsinhead:20,avoidfont:1,totalrequests:10,expiresmod:10,longexpirehead:5,nodnslookupswhenfewrequests:8,inlinecsswhenfewrequest:7,textcontent:1,thirdpartyversions:5,ycdn:6}});YSLOW.registerRuleset({id:"sitespeed.io-mobile",name:"Sitespeed.io mobile rules",rules:{criticalpath:{},spof:{fontFaceInCssSpof:false,inlineFontFaceSpof:false},cssnumreq:{},cssimagesnumreq:{},jsnumreq:{},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},redirects:{},noduplicates:{},yetags:{},yxhr:{},yxhrmethod:{},mindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},avoidscalingimages:{},yfavicon:{},thirdpartyasyncjs:{},cssprint:{},cssinheaddomain:{},syncjsinhead:{},avoidfont:{},totalrequests:{},expiresmod:{},longexpirehead:{},nodnslookupswhenfewrequests:{},inlinecsswhenfewrequest:{},textcontent:{},thirdpartyversions:{},ycdn:{}},weights:{criticalpath:20,spof:5,cssnumreq:8,cssimagesnumreq:8,jsnumreq:8,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,redirects:15,noduplicates:4,yetags:2,yxhr:4,yxhrmethod:3,mindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,avoidscalingimages:10,yfavicon:2,thirdpartyasyncjs:10,cssprint:3,cssinheaddomain:8,syncjsinhead:20,avoidfont:5,totalrequests:14,expiresmod:10,longexpirehead:5,nodnslookupswhenfewrequests:15,inlinecsswhenfewrequest:10,textcontent:1,thirdpartyversions:5,ycdn:6}});YSLOW.registerRuleset({id:"sitespeed.io-desktop-http2.0",name:"Sitespeed.io desktop rules for HTTP 2.0",rules:{criticalpath:{},spof:{fontFaceInCssSpof:false,inlineFontFaceSpof:false},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},redirects:{},noduplicates:{},yetags:{},yxhr:{},yxhrmethod:{},mindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},avoidscalingimages:{},yfavicon:{},thirdpartyasyncjs:{},cssprint:{},cssinheaddomain:{},syncjsinhead:{},avoidfont:{},expiresmod:{},longexpirehead:{},textcontent:{},thirdpartyversions:{},ycdn:{}},weights:{criticalpath:15,spof:5,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,redirects:4,noduplicates:4,yetags:2,yxhr:4,yxhrmethod:3,mindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,avoidscalingimages:5,yfavicon:2,thirdpartyasyncjs:10,cssprint:3,cssinheaddomain:8,syncjsinhead:20,avoidfont:1,expiresmod:10,longexpirehead:5,textcontent:1,thirdpartyversions:5,ycdn:6}});YSLOW.ResultSet=function(results,overall_score,ruleset_applied){this.ruleset_applied=ruleset_applied;this.overall_score=overall_score;this.results=results};YSLOW.ResultSet.prototype={getResults:function(){return this.results},getRulesetApplied:function(){return this.ruleset_applied},getOverallScore:function(){return this.overall_score}};YSLOW.view=function(panel,yscontext){var toolbar,elem,dialogHtml,modaldlg,copyright;this.panel_doc=panel.document;this.buttonViews={};this.curButtonId="";this.panelNode=panel.panelNode;this.loadCSS(this.panel_doc);toolbar=this.panel_doc.createElement("div");toolbar.id="toolbarDiv";toolbar.innerHTML=this.getToolbarSource();toolbar.style.display="block";elem=this.panel_doc.createElement("div");elem.style.display="block";dialogHtml='

text

';modaldlg=this.panel_doc.createElement("div");modaldlg.id="dialogDiv";modaldlg.innerHTML=dialogHtml;modaldlg.style.display="none";this.modaldlg=modaldlg;this.tooltip=new YSLOW.view.Tooltip(this.panel_doc,panel.panelNode);copyright=this.panel_doc.createElement("div");copyright.id="copyrightDiv";copyright.innerHTML=YSLOW.doc.copyright;this.copyright=copyright;if(panel.panelNode){panel.panelNode.id="yslowDiv";panel.panelNode.appendChild(modaldlg);panel.panelNode.appendChild(toolbar);panel.panelNode.appendChild(elem);panel.panelNode.appendChild(copyright)}this.viewNode=elem;this.viewNode.id="viewDiv";this.viewNode.className="yui-skin-sam";this.yscontext=yscontext;YSLOW.util.addEventListener(this.panelNode,"click",function(e){var help,helplink,x,y,parent;var doc=FBL.getContentView(panel.document);var toolbar=doc.ysview.getElementByTagNameAndId(panel.panelNode,"div","toolbarDiv");if(toolbar){helplink=doc.ysview.getElementByTagNameAndId(toolbar,"li","helpLink");if(helplink){x=helplink.offsetLeft;y=helplink.offsetTop;parent=helplink.offsetParent;while(parent){x+=parent.offsetLeft;y+=parent.offsetTop;parent=parent.offsetParent}if(e.clientX>=x&&e.clientY>=y&&e.clientX"+rule.name+"

"+rule.info,e.target)}}}});YSLOW.util.addEventListener(this.panelNode,"mouseout",function(e){var doc=FBL.getContentView(panel.document);doc.ysview.tooltip.hide()});YSLOW.util.addEventListener(this.panel_doc.defaultView||this.panel_doc.parentWindow,"resize",function(e){var doc=FBL.getContentView(panel.document);var overlay=doc.ysview.modaldlg;if(overlay&&overlay.style.display==="block"){overlay.style.display="none"}})};YSLOW.view.prototype={setDocument:function(doc){this.panel_doc=doc},loadCSS:function(){},addButtonView:function(sButtonId,sHtml){var btnView=this.getButtonView(sButtonId);if(!btnView){btnView=this.panel_doc.createElement("div");btnView.style.display="none";this.viewNode.appendChild(btnView);this.buttonViews[sButtonId]=btnView}btnView.innerHTML=sHtml;this.showButtonView(sButtonId)},clearAllButtonView:function(){var views=this.buttonViews,node=this.viewNode,remove=function(v){if(views.hasOwnProperty(v)){node.removeChild(views[v]);delete views[v]}};remove("ysPerfButton");remove("ysCompsButton");remove("ysStatsButton")},showButtonView:function(sButtonId){var sId,btnView=this.getButtonView(sButtonId);if(!btnView){YSLOW.util.dump("ERROR: YSLOW.view.showButtonView: Couldn't find ButtonView '"+sButtonId+"'.");return}for(sId in this.buttonViews){if(this.buttonViews.hasOwnProperty(sId)&&sId!==sButtonId){this.buttonViews[sId].style.display="none"}}if(sButtonId==="ysPerfButton"){if(this.copyright){this.copyright.style.display="none"}}else{if(this.curButtonId==="ysPerfButton"){if(this.copyright){this.copyright.style.display="block"}}}btnView.style.display="block";this.curButtonId=sButtonId},getButtonView:function(sButtonId){return(this.buttonViews.hasOwnProperty(sButtonId)?this.buttonViews[sButtonId]:undefined)},setButtonView:function(sButtonId,sHtml){var btnView=this.getButtonView(sButtonId);if(!btnView){YSLOW.util.dump("ERROR: YSLOW.view.setButtonView: Couldn't find ButtonView '"+sButtonId+"'.");return}btnView.innerHTML=sHtml;this.showButtonView(sButtonId)},setSplashView:function(hideAutoRun,showAntiIframe,hideToolsInfo){var sHtml,title="Grade your web pages with YSlow",header="YSlow gives you:",text="
  • Grade based on the performance (you can define your own rules)
  • Summary of the Components in the page
  • Chart with statistics
  • Tools including Smush.It and JSLint
  • ",more_info_text="Learn more about YSlow and YDN";if(YSLOW.doc.splash){if(YSLOW.doc.splash.title){title=YSLOW.doc.splash.title}if(YSLOW.doc.splash.content){if(YSLOW.doc.splash.content.header){header=YSLOW.doc.splash.content.header}if(YSLOW.doc.splash.content.text){text=YSLOW.doc.splash.content.text}}if(YSLOW.doc.splash.more_info){more_info_text=YSLOW.doc.splash.more_info}}if(typeof hideToolsInfo!=="undefined"){YSLOW.hideToolsInfo=hideToolsInfo}else{hideToolsInfo=YSLOW.hideToolsInfo}if(hideToolsInfo){text=text.replace(/
  • Tools[^<]+<\/li>/,"")}sHtml='

    '+title+'

    '+header+'

      '+text+"
    ";if(typeof hideAutoRun!=="undefined"){YSLOW.hideAutoRun=hideAutoRun}else{hideAutoRun=YSLOW.hideAutoRun}if(!hideAutoRun){sHtml+=''}sHtml+='
    ";this.addButtonView("panel_about",sHtml)},genProgressView:function(){var sBody='

    Finding components in the page:

    Getting component information:

    start...
    ';this.setButtonView("panel_about",sBody)},updateProgressView:function(progress_type,progress_info){var outerbar,progbar,progtext,percent,view,maxwidth,width,left,message="";if(this.curButtonId==="panel_about"){view=this.getButtonView(this.curButtonId);if(progress_type==="peel"){outerbar=this.getElementByTagNameAndId(view,"div","peelprogress");progbar=this.getElementByTagNameAndId(view,"div","progbar");progtext=this.getElementByTagNameAndId(view,"div","progtext");message=progress_info.message;percent=(progress_info.current_step*100)/progress_info.total_step}else{if(progress_type==="fetch"){outerbar=this.getElementByTagNameAndId(view,"div","fetchprogress");progbar=this.getElementByTagNameAndId(view,"div","progbar2");progtext=this.getElementByTagNameAndId(view,"div","progtext2");message=progress_info.last_component_url;percent=(progress_info.current*100)/progress_info.total}else{if(progress_type==="message"){progtext=this.getElementByTagNameAndId(view,"div","progtext2");if(progtext){progtext.innerHTML=progress_info}return}else{return}}}}if(outerbar&&progbar&&progtext){maxwidth=outerbar.clientWidth;if(percent<0){percent=0}if(percent>100){percent=100}percent=100-percent;width=(maxwidth*percent)/100;if(width>maxwidth){width=maxwidth}left=maxwidth-parseInt(width,10);progbar.style.width=parseInt(width,10)+"px";progbar.style.left=parseInt(left,10)+"px";progtext.innerHTML=message}},updateStatusBar:function(doc){var size,grade,result,info,url,yslow=YSLOW,util=yslow.util,view=yslow.view,pref=util.Preference,yscontext=this.yscontext;if(!yscontext.PAGE.statusbar){yscontext.PAGE.statusbar=true;if(!yscontext.PAGE.overallScore){yslow.controller.lint(doc,yscontext)}if(!yscontext.PAGE.totalSize){yscontext.collectStats()}size=util.kbSize(yscontext.PAGE.totalSize);grade=util.prettyScore(yscontext.PAGE.overallScore);view.setStatusBar(grade,"yslow_status_grade");view.setStatusBar(size,"yslow_status_size");if(pref.getPref("optinBeacon",false)){info=pref.getPref("beaconInfo","basic"),url=pref.getPref("beaconUrl","http://rtblab.pclick.yahoo.com/images/ysb.gif");result=util.getResults(yscontext,info);util.sendBeacon(result,info,url)}}},getRulesetListSource:function(rulesets){var id,custom,sHtml="",defaultRulesetId=YSLOW.controller.getDefaultRulesetId();for(id in rulesets){if(rulesets[id]){sHtml+='"}}return sHtml},updateRulesetList:function(){var i,div,new_select,selects=this.panel_doc.getElementsByTagName("select"),rulesets=YSLOW.controller.getRegisteredRuleset(),sText=this.getRulesetListSource(rulesets),onchangeFunc=function(event){var doc=FBL.getContentView(this.ownerDocument);doc.ysview.onChangeRuleset(event)};for(i=0;iRulesets ";sHtml+='';sHtml+='";sHtml+='";sHtml+="";return sHtml},show:function(sView){var format="html",stext="";sView=sView||this.yscontext.defaultview;if(this.yscontext.component_set===null){YSLOW.controller.run(window.top.content,this.yscontext,false);this.yscontext.defaultview=sView}else{if(this.getButtonView(sView)){this.showButtonView(sView)}else{if("ysCompsButton"===sView){stext+=this.yscontext.genComponents(format);this.addButtonView("ysCompsButton",stext)}else{if("ysStatsButton"===sView){stext+=this.yscontext.genStats(format);this.addButtonView("ysStatsButton",stext);YSLOW.renderer.plotComponents(this.getButtonView("ysStatsButton"),this.yscontext)}else{if("ysToolButton"===sView){stext+=this.yscontext.genToolsView(format);this.addButtonView("ysToolButton",stext)}else{stext+=this.yscontext.genPerformance(format);this.addButtonView("ysPerfButton",stext)}}}}this.panelNode.scrollTop=0;this.panelNode.scrollLeft=0;this.updateStatusBar(this.yscontext.document);this.updateToolbarSelection()}},updateToolbarSelection:function(){var elem,ul_elem,child;switch(this.curButtonId){case"ysCompsButton":case"ysPerfButton":case"ysStatsButton":case"ysToolButton":elem=this.getElementByTagNameAndId(this.panelNode,"li",this.curButtonId);if(elem){if(elem.className.indexOf("selected")!==-1){return}else{elem.className+=" selected";if(elem.previousSibling){elem.previousSibling.className+=" off"}}}break;default:break}ul_elem=this.getElementByTagNameAndId(this.panelNode,"ul","toolbarLinks");child=ul_elem.firstChild;while(child){if(child.id!==this.curButtonId&&child.className.indexOf("selected")!==-1){this.unselect(child);if(child.previousSibling){YSLOW.view.removeClassName(child.previousSibling,"off")}}child=child.nextSibling}},showPerformance:function(){this.show("ysPerfButton")},showStats:function(){this.show("ysStatsButton")},showComponents:function(){this.show("ysCompsButton")},showTools:function(){this.show("ysToolButton")},showRuleSettings:function(){var stext=this.yscontext.genRulesetEditView("html");this.addButtonView("ysRuleEditButton",stext);this.panelNode.scrollTop=0;this.panelNode.scrollLeft=0;this.updateToolbarSelection()},runTest:function(){YSLOW.controller.run(window.top.content,this.yscontext,false)},setAutorun:function(set){YSLOW.util.Preference.setPref("extensions.yslow.autorun",set)},setAntiIframe:function(set){YSLOW.antiIframe=set},addCDN:function(cdn){var i,id,that=this,doc=document,ctx=that.yscontext,pref=YSLOW.util.Preference,cdns=pref.getPref("cdnHostnames",""),panel=that.panel_doc,el=panel.getElementById("tab-label-list"),lis=el.getElementsByTagName("li"),len=lis.length;if(cdns){cdns=cdns.replace(/\s+/g,"").split(",");cdns.push(cdn);cdns=cdns.join()}else{cdns=cdn}pref.setPref("extensions.yslow.cdnHostnames",cdns);for(i=0;i-1){id=el.id;break}}YSLOW.controller.lint(ctx.document,ctx);that.addButtonView("ysPerfButton",ctx.genPerformance("html"));YSLOW.view.restoreStatusBar(ctx);that.updateToolbarSelection();el=panel.getElementById(id);that.onclickTabLabel({currentTarget:el},true)},onChangeRuleset:function(event){var doc,line1,left_button_label,left_button_func,select=YSLOW.util.getCurrentTarget(event),option=select.options[select.selectedIndex];YSLOW.controller.setDefaultRuleset(option.value);doc=select.ownerDocument;line1="Do you want to run the selected ruleset now?";left_button_label="Run Test";left_button_func=function(e){var stext;doc.ysview.closeDialog(doc);if(doc.yslowContext.component_set===null){YSLOW.controller.run(doc.yslowContext.document.defaultView||doc.yslowContext.document.parentWindow,doc.yslowContext,false)}else{YSLOW.controller.lint(doc.yslowContext.document,doc.yslowContext)}stext=doc.yslowContext.genPerformance("html");doc.ysview.addButtonView("ysPerfButton",stext);doc.ysview.panelNode.scrollTop=0;doc.ysview.panelNode.scrollLeft=0;YSLOW.view.restoreStatusBar(doc.yslowContext);doc.ysview.updateToolbarSelection()};this.openDialog(doc,389,150,line1,undefined,left_button_label,left_button_func)},onclickTabLabel:function(event,move_tab){var child,hide_tab_id,show_tab_id,hide,show,show_tab,id_substring,li_elem=YSLOW.util.getCurrentTarget(event),ul_elem=li_elem.parentNode,div_elem=ul_elem.nextSibling;if(li_elem.className.indexOf("selected")!==-1||li_elem.id.indexOf("label")===-1){return false}if(ul_elem){child=ul_elem.firstChild;while(child){if(this.unselect(child)){hide_tab_id=child.id.substring(5);break}child=child.nextSibling}li_elem.className+=" selected";show_tab_id=li_elem.id.substring(5);child=div_elem.firstChild;while(child){id_substring=child.id.substring(3);if(!hide&&hide_tab_id&&id_substring===hide_tab_id){if(child.className.indexOf("yui-hidden")===-1){child.className+=" yui-hidden"}hide=true}if(!show&&show_tab_id&&id_substring===show_tab_id){YSLOW.view.removeClassName(child,"yui-hidden");show=true;show_tab=child}if((hide||!hide_tab_id)&&(show||!show_tab_id)){break}child=child.nextSibling}if(move_tab===true&&show===true&&show_tab){this.positionResultTab(show_tab,div_elem,li_elem)}}return false},positionResultTab:function(tab,container,label){var y,parent,delta,padding=5,doc=this.panel_doc,win=doc.defaultView||doc.parentWindow,pageHeight=win.offsetHeight?win.offsetHeight:win.innerHeight,height=label.offsetTop+tab.offsetHeight;container.style.height=height+"px";tab.style.position="absolute";tab.style.left=label.offsetLeft+label.offsetWidth+"px";tab.style.top=label.offsetTop+"px";y=tab.offsetTop;parent=tab.offsetParent;while(parent!==null){y+=parent.offsetTop;parent=parent.offsetParent}if(ythis.panelNode.scrollTop+pageHeight){if(yy-this.panelNode.scrollTop){delta=y-this.panelNode.scrollTop}this.panelNode.scrollTop+=delta}}},onclickResult:function(event){YSLOW.util.preventDefault(event);return this.onclickTabLabel(event,true)},unselect:function(elem){return YSLOW.view.removeClassName(elem,"selected")},filterResult:function(doc,category){var ul_elem,showAll,child,firstTab,tab,firstChild,div_elem,view=this.getButtonView("ysPerfButton");if(category==="all"){showAll=true}if(view){ul_elem=this.getElementByTagNameAndId(view,"ul","tab-label-list")}if(ul_elem){child=ul_elem.firstChild;div_elem=ul_elem.nextSibling;tab=div_elem.firstChild;while(child){YSLOW.view.removeClassName(child,"first");if(showAll||child.className.indexOf(category)!==-1){child.style.display="block";if(firstTab===undefined){firstTab=tab;firstChild=child;YSLOW.view.removeClassName(tab,"yui-hidden");child.className+=" first";if(child.className.indexOf("selected")===-1){child.className+=" selected"}child=child.nextSibling;tab=tab.nextSibling;continue}}else{child.style.display="none"}if(tab.className.indexOf("yui-hidden")===-1){tab.className+=" yui-hidden"}this.unselect(child);child=child.nextSibling;tab=tab.nextSibling}if(firstTab){this.positionResultTab(firstTab,div_elem,firstChild)}}},updateFilterSelection:function(event){var li,elem=YSLOW.util.getCurrentTarget(event);YSLOW.util.preventDefault(event);if(elem.className.indexOf("selected")!==-1){return}elem.className+=" selected";li=elem.parentNode.firstChild;while(li){if(li!==elem&&this.unselect(li)){break}li=li.nextSibling}this.filterResult(elem.ownerDocument,elem.id)},onclickToolbarMenu:function(event){var child,a_elem=YSLOW.util.getCurrentTarget(event),li_elem=a_elem.parentNode,ul_elem=li_elem.parentNode;if(li_elem.className.indexOf("selected")!==-1){return}li_elem.className+=" selected";if(li_elem.previousSibling){li_elem.previousSibling.className+=" off"}if(ul_elem){child=ul_elem.firstChild;while(child){if(child!==li_elem&&this.unselect(child)){if(child.previousSibling){YSLOW.view.removeClassName(child.previousSibling,"off")}break}child=child.nextSibling}}},expandCollapseComponentType:function(doc,type){var table,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysCompsButton");if(view){table=this.getElementByTagNameAndId(view,"table","components-table");renderer.expandCollapseComponentType(doc,table,type)}},expandAll:function(doc){var table,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysCompsButton");if(view){table=this.getElementByTagNameAndId(view,"table","components-table");renderer.expandAllComponentType(doc,table)}},regenComponentsTable:function(doc,column_name,sortDesc){var table,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysCompsButton");if(view){table=this.getElementByTagNameAndId(view,"table","components-table");renderer.regenComponentsTable(doc,table,column_name,sortDesc,this.yscontext.component_set)}},showComponentHeaders:function(headersDivId){var elem,td,view=this.getButtonView("ysCompsButton");if(view){elem=this.getElementByTagNameAndId(view,"tr",headersDivId);if(elem){td=elem.firstChild;if(elem.style.display==="none"){elem.style.display="table-row"}else{elem.style.display="none"}}}},openLink:function(url){YSLOW.util.openLink(url)},openPopup:function(url,name,width,height,features){window.open(url,name||"_blank","width="+(width||626)+",height="+(height||436)+","+(features||"toolbar=0,status=1,location=1,resizable=1"))},runTool:function(tool_id,param){YSLOW.controller.runTool(tool_id,this.yscontext,param)},onclickRuleset:function(event){var ruleset_id,end,view,form,li_elem=YSLOW.util.getCurrentTarget(event),index=li_elem.className.indexOf("ruleset-");YSLOW.util.preventDefault(event);if(index!==-1){end=li_elem.className.indexOf(" ",index+8);if(end!==-1){ruleset_id=li_elem.className.substring(index+8,end)}else{ruleset_id=li_elem.className.substring(index+8)}view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form","edit-form");YSLOW.renderer.initRulesetEditForm(li_elem.ownerDocument,form,YSLOW.controller.getRuleset(ruleset_id))}}return this.onclickTabLabel(event,false)},openSaveAsDialog:function(doc,form_id){var line1='',left_button_label="Save",left_button_func=function(e){var textbox,line,view,form,input,doc=YSLOW.util.getCurrentTarget(e).ownerDocument;if(doc.ysview.modaldlg){textbox=doc.ysview.getElementByTagNameAndId(doc.ysview.modaldlg,"input","saveas-name")}if(textbox){if(YSLOW.controller.checkRulesetName(textbox.value)===true){line=line1+'
    '+textbox.value+" ruleset already exists.
    ";doc.ysview.closeDialog(doc);doc.ysview.openDialog(doc,389,150,line,"",left_button_label,left_button_func)}else{view=doc.ysview.getButtonView("ysRuleEditButton");if(view){form=doc.ysview.getElementByTagNameAndId(view,"form",form_id);input=doc.createElement("input");input.type="hidden";input.name="saveas-name";input.value=textbox.value;form.appendChild(input);form.submit()}doc.ysview.closeDialog(doc)}}};this.openDialog(doc,389,150,line1,undefined,left_button_label,left_button_func)},openPrintableDialog:function(doc){var line="Please run YSlow first before using Printable View.",line1="Check which information you want to view or print
    ",line2='
    ',left_button_label="Ok",left_button_func=function(e){var i,doc=YSLOW.util.getCurrentTarget(e).ownerDocument,doc=FBL.getContentView(doc);aInputs=doc.getElementsByName("print-type"),print_type={};for(i=0;i0){for(i=0;i0){if(elems[i].className==="dialog-box"){dialog=elems[i]}else{if(elems[i].className==="dialog-text"){text=elems[i]}else{if(elems[i].className==="dialog-more-text"){more_text=elems[i]}}}}}if(overlay&&dialog&&text&&more_text){text.innerHTML=(text1?text1:"");more_text.innerHTML=(text2?text2:"");inputs=overlay.getElementsByTagName("input");for(j=0;j0)?left:225)+"px";dialog.style.top=((top&&top>0)?top:80)+"px";overlay.style.left=this.panelNode.scrollLeft+"px";overlay.style.top=this.panelNode.scrollTop+"px";overlay.style.display="block";if(inputs.length>0){inputs[0].focus()}}},closeDialog:function(doc){var dialog=this.modaldlg;dialog.style.display="none"},saveRuleset:function(doc,form_id){var form,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);renderer.saveRuleset(doc,form)}},deleteRuleset:function(doc,form_id){var form,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);renderer.deleteRuleset(doc,form)}},shareRuleset:function(doc,form_id){var form,ruleset_id,ruleset,result,line1,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);ruleset_id=renderer.getEditFormRulesetId(form);ruleset=YSLOW.controller.getRuleset(ruleset_id);if(ruleset){result=YSLOW.Exporter.exportRuleset(ruleset);if(result){line1="";this.openDialog(doc,389,150,line1,"","Ok")}}}},createRuleset:function(button,form_id){var view,form,li_elem=button.parentNode,ul_elem=li_elem.parentNode,child=ul_elem.firstChild;while(child){this.unselect(child);child=child.nextSibling}view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);YSLOW.renderer.initRulesetEditForm(this.panel_doc,form)}},showHideHelp:function(){var help,toolbar=this.getElementByTagNameAndId(this.panelNode,"div","toolbarDiv");if(toolbar){help=this.getElementByTagNameAndId(toolbar,"div","helpDiv")}if(help){if(help.style.visibility==="visible"){help.style.visibility="hidden"}else{help.style.visibility="visible"}}},smushIt:function(doc,url){YSLOW.util.smushIt(url,function(resp){var line1,line2,smushurl,dest_url,txt="";if(resp.error){txt+="
    "+resp.error+"
    "}else{smushurl=YSLOW.util.getSmushUrl();dest_url=YSLOW.util.makeAbsoluteUrl(resp.dest,smushurl);txt+="
    Original size: "+resp.src_size+" bytes
    Result size: "+resp.dest_size+" bytes
    % Savings: "+resp.percent+"%
    "}line1='
    Image: '+YSLOW.util.briefUrl(url,250)+"
    ";line2=txt;doc.ysview.openDialog(doc,389,150,line1,line2,"Ok")})},checkAllRules:function(doc,form_id,check){var i,view,form,aElements;if(typeof check!=="boolean"){return}view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);aElements=form.elements;for(i=0;ipageWidth||tooltipHeight>pageHeight){this.tooltip.style.display="none";return}parent=target.offsetParent;while(parent!==null){x+=parent.offsetLeft;y+=parent.offsetTop;parent=parent.offsetParent}x+=target.offsetLeft;y+=target.offsetTop;if(xdoc.ysview.panelNode.scrollTop+pageHeight)){this.tooltip.style.display="none";return}midpt_x=x+target.offsetWidth/2;midpt_y=y+target.offsetHeight/2;if(x+target.offsetWidth+padding+tooltipWidth=doc.ysview.panelNode.scrollTop)&&(y-padding+tooltipHeight+padding<=doc.ysview.panelNode.scrollTop+pageHeight)){y=y-padding;sClass="right top"}else{y+=target.offsetHeight-tooltipHeight;sClass="right bottom"}}else{if(y-tooltipHeight-padding>=doc.ysview.panelNode.scrollTop){y-=tooltipHeight+padding;sClass="top"}else{y+=target.offsetHeight+padding;sClass="bottom"}new_x=Math.floor(midpt_x-tooltipWidth/2);if((new_x>=doc.ysview.panelNode.scrollLeft)&&(new_x+tooltipWidth<=doc.ysview.panelNode.scrollLeft+pageWidth)){x=new_x}else{if(new_x0&&name&&name.length>0){names=element.className.split(" ");for(i=0;i0){canvas_data[sType]=hSize[sType]}totalSize+=hSize[sType]}}return{total_size:totalSize,num_requests:nHttpRequests,count_obj:hCount,size_obj:hSize,canvas_data:canvas_data}},collectStats:function(){var stats=this.computeStats();if(stats!==undefined){this.PAGE.totalSize=stats.total_size;this.PAGE.totalRequests=stats.num_requests;this.PAGE.totalObjCount=stats.count_obj;this.PAGE.totalObjSize=stats.size_obj;this.PAGE.canvas_data.empty=stats.canvas_data}stats=this.computeStats(true);if(stats){this.PAGE.totalSizePrimed=stats.total_size;this.PAGE.totalRequestsPrimed=stats.num_requests;this.PAGE.totalObjCountPrimed=stats.count_obj;this.PAGE.totalObjSizePrimed=stats.size_obj;this.PAGE.canvas_data.primed=stats.canvas_data}},genPerformance:function(output_format,doc){if(this.result_set===null){if(!doc){doc=this.document}YSLOW.controller.lint(doc,this)}return YSLOW.controller.render(output_format,"reportcard",{result_set:this.result_set})},genStats:function(output_format){var stats={};if(!this.PAGE.totalSize){this.collectStats()}stats.PAGE=this.PAGE;return YSLOW.controller.render(output_format,"stats",{stats:stats})},genComponents:function(output_format){if(!this.PAGE.totalSize){this.collectStats()}return YSLOW.controller.render(output_format,"components",{comps:this.component_set.components,total_size:this.PAGE.totalSize})},genToolsView:function(output_format){var tools=YSLOW.Tools.getAllTools();return YSLOW.controller.render(output_format,"tools",{tools:tools})},genRulesetEditView:function(output_format){return YSLOW.controller.render(output_format,"rulesetEdit",{rulesets:YSLOW.controller.getRegisteredRuleset()})}};YSLOW.renderer={sortBy:"type",sortDesc:false,bPrintable:false,colors:{doc:"#8963df",redirect:"#FC8C8C",iframe:"#FFDFDF",xhr:"#89631f",flash:"#8D4F5B",js:"#9fd0e8",css:"#aba5eb",cssimage:"#677ab8",image:"#d375cd",favicon:"#a26c00",unknown:"#888888"},reset:function(){this.sortBy="type";this.sortDesc=false},genStats:function(stats,bCacheFull){var hCount,hSize,nHttpRequests,aTypes,cache_type,i,sType,sText,tableHtml="",totalSize=0;if(!stats.PAGE){return""}if(bCacheFull){hCount=stats.PAGE.totalObjCountPrimed;hSize=stats.PAGE.totalObjSizePrimed;nHttpRequests=stats.PAGE.totalRequestsPrimed;totalSize=stats.PAGE.totalSizePrimed}else{hCount=stats.PAGE.totalObjCount;hSize=stats.PAGE.totalObjSize;nHttpRequests=stats.PAGE.totalRequests;totalSize=stats.PAGE.totalSize}aTypes=YSLOW.peeler.types;cache_type=(bCacheFull)?"primed":"empty";for(i=0;i
     
    '+hCount[sType]+''+YSLOW.util.prettyType(sType)+''+YSLOW.util.kbSize(hSize[sType])+""}}sText='
    HTTP Requests - '+nHttpRequests+'
    Total Weight - '+YSLOW.util.kbSize(totalSize)+'
    '+tableHtml+"
    ";return sText},plotComponents:function(stats_view,yscontext){if(typeof stats_view!=="object"){return}this.plotOne(stats_view,yscontext.PAGE.canvas_data.empty,yscontext.PAGE.totalSize,"comp-canvas-empty");this.plotOne(stats_view,yscontext.PAGE.canvas_data.primed,yscontext.PAGE.totalSizePrimed,"comp-canvas-primed")},plotOne:function(stats_view,data,total,canvas_id){var canvas,i,ctx,canvas_size,radius,center,sofar,piece,thisvalue,aElements=stats_view.getElementsByTagName("canvas");for(i=0;i'+YSLOW.util.escapeHtml(comp.headers[field])+""}}if(comp.req_headers){sText+='Request Headers';for(field in comp.req_headers){if(comp.req_headers.hasOwnProperty(field)&&comp.req_headers[field]){sText+=''+YSLOW.util.escapeHtml(YSLOW.util.formatHeaderName(field))+'

    '+YSLOW.util.escapeHtml(comp.req_headers[field])+"

    "}}}sText+="";return sText},genComponentRow:function(fields,comp,row_class,hidden){var headersDivId,sHtml,i,sClass,value,sent,recv;if(typeof row_class!=="string"){row_class=""}if(comp.status>=400&&comp.status<500){row_class+=" compError"}if(comp.after_onload===true){row_class+=" afteronload"}headersDivId="compHeaders"+comp.id;sHtml='";for(i in fields){if(fields.hasOwnProperty(i)){sClass=i;value="";if(i==="type"){value+=comp[i];if(comp.is_beacon){value+=" †"}if(comp.after_onload){value+=" *"}}else{if(i==="size"){value+=YSLOW.util.kbSize(comp.size)}else{if(i==="url"){if(comp.status>=400&&comp.status<500){sHtml+=''+comp[i]+" (status: "+comp.status+")";continue}else{value+=YSLOW.util.prettyAnchor(comp[i],comp[i],undefined,!YSLOW.renderer.bPrintable,100,1,comp.type)}}else{if(i==="gzip"&&(comp.compressed==="gzip"||comp.compressed==="deflate")){value+=(comp.size_compressed!==undefined?YSLOW.util.kbSize(comp.size_compressed):"uncertain")}else{if(i==="set-cookie"){sent=comp.getSetCookieSize();value+=sent>0?sent:""}else{if(i==="cookie"){recv=comp.getReceivedCookieSize();value+=recv>0?recv:""}else{if(i==="etag"){value+=comp.getEtag()}else{if(i==="expires"){value+=YSLOW.util.prettyExpiresDate(comp.expires)}else{if(i==="headers"){if(YSLOW.renderer.bPrintable){continue}if(comp.raw_headers&&comp.raw_headers.length>0){value+="'}}else{if(i==="action"){if(YSLOW.renderer.bPrintable){continue}if(comp.type==="cssimage"||comp.type==="image"){if(comp.response_type===undefined||comp.response_type==="image"){value+="smush.it"}}}else{if(comp[i]!==undefined){value+=comp[i]}}}}}}}}}}}sHtml+=''+value+""}}sHtml+="";if(comp.raw_headers&&comp.raw_headers.length>0){sHtml+=''+this.getComponentHeadersTable(comp)+""}return sHtml},componentSortCallback:function(comp1,comp2){var i,types,max,a="",b="",sortBy=YSLOW.renderer.sortBy,desc=YSLOW.renderer.sortDesc;switch(sortBy){case"type":a=comp1.type;b=comp2.type;break;case"size":a=comp1.size?Number(comp1.size):0;b=comp2.size?Number(comp2.size):0;break;case"gzip":a=comp1.size_compressed?Number(comp1.size_compressed):0;b=comp2.size_compressed?Number(comp2.size_compressed):0;break;case"set-cookie":a=comp1.getSetCookieSize();b=comp2.getSetCookieSize();break;case"cookie":a=comp1.getReceivedCookieSize();b=comp2.getReceivedCookieSize();break;case"headers":break;case"url":a=comp1.url;b=comp2.url;break;case"respTime":a=comp1.respTime?Number(comp1.respTime):0;b=comp2.respTime?Number(comp2.respTime):0;break;case"etag":a=comp1.getEtag();b=comp2.getEtag();break;case"action":if(comp1.type==="cssimage"||comp1.type==="image"){a="smush.it"}if(comp2.type==="cssimage"||comp2.type==="image"){b="smush.it"}break;case"expires":a=comp1.expires||0;b=comp2.expires||0;break}if(a===b){if(comp1.id>comp2.id){return(desc)?-1:1}if(comp1.idb){return(desc)?-1:1}if(a',col2Text='
    ',col3Text='
    ';for(id in rules){if(rules.hasOwnProperty(id)&&rules[id]){rule=rules[id];sText='
    ";if(ruleset.rules[id]!==undefined){numRules+=1}if(ruleset.weights!==undefined&&ruleset.weights[id]!==undefined){weightsText+=''}column_id=(j%3);switch(column_id){case 0:col1Text+=sText;break;case 1:col2Text+=sText;break;case 2:col3Text+=sText;break}j+=1}}col1Text+="
    ";col2Text+="
    ";col3Text+="";return'

    '+ruleset.name+' Ruleset (includes '+parseInt(numRules,10)+" of "+parseInt(j,10)+' rules)

    '+col1Text+""+col2Text+""+col3Text+'
    '+weightsText+"
    "},genRulesetEditForm:function(ruleset){var contentHtml="";contentHtml+='
    '+YSLOW.renderer.genRulesCheckbox(ruleset)+'
    ';return contentHtml},initRulesetEditForm:function(doc,form,ruleset){var divs,i,j,id,buttons,rulesetId,rulesetName,title,weightsDiv,rules,numRulesSpan,spans,checkbox,aElements=form.elements,weightsText="",checkboxes=[],numRules=0,totalRules=0;for(i=0;i'}numRules+=1}}numRulesSpan.innerHTML="(includes "+parseInt(numRules,10)+" of "+parseInt(totalRules,10)+" rules)";rulesetId.innerHTML='';rulesetName.innerHTML='';title.innerHTML=ruleset.name}else{rulesetId.innerHTML="";rulesetName.innerHTML="";title.innerHTML="New";numRulesSpan.innerHTML=""}weightsDiv.innerHTML=weightsText}};YSLOW.registerRenderer({id:"html",supports:{components:1,reportcard:1,stats:1,tools:1,rulesetEdit:1},genComponentsTable:function(comps,sortBy,sortDesc){var f,j,type,comp,headers={type:"TYPE",size:"SIZE
    (KB)",gzip:"GZIP
    (KB)","set-cookie":"COOKIE RECEIVED
    (bytes)",cookie:"COOKIE SENT
    (bytes)",headers:"HEADERS",url:"URL",expires:"EXPIRES
    (Y/M/D)",respTime:"RESPONSE
    TIME (ms)",etag:"ETAG",action:"ACTION"},collapsed=false,tableHtml="",rowHtml="",numComponentsByType=0,sizeByType=0;if(sortBy!==undefined&&headers[sortBy]===undefined){return""}if(YSLOW.renderer.bPrintable){sortBy=YSLOW.renderer.sortBy;sortDesc=YSLOW.renderer.sortDesc}else{if(sortBy===undefined||sortBy==="type"){sortBy="type";collapsed=true}}comps=YSLOW.renderer.sortComponents(comps,sortBy,sortDesc);tableHtml+='';for(f in headers){if(headers.hasOwnProperty(f)&&headers[f]){if(YSLOW.renderer.bPrintable&&(f==="action"||f==="components"||f==="headers")){continue}tableHtml+="'+(sortBy===f?(sortDesc?"↓":"↑"):"")+" "+headers[f]+""}}}tableHtml+="";for(j=0;j";tableHtml+=rowHtml;rowHtml="";numComponentsByType=0;sizeByType=0;type=comp.type}}rowHtml+=YSLOW.renderer.genComponentRow(headers,comp,(numComponentsByType%2===0?"even":"odd"),collapsed);numComponentsByType+=1;sizeByType+=comp.size}else{tableHtml+=YSLOW.renderer.genComponentRow(headers,comp,(j%2===0?"even":"odd"),false)}}if(rowHtml.length>0){tableHtml+='";tableHtml+=rowHtml}tableHtml+="
    '+type+" ("+numComponentsByType+')'+YSLOW.util.kbSize(sizeByType)+"
    '+type+" ("+numComponentsByType+')'+YSLOW.util.kbSize(sizeByType)+"
    ";return tableHtml},componentsView:function(comps,totalSize){var sText,tableHtml=this.genComponentsTable(comps,YSLOW.renderer.sortBy,false),beacon_legend="in type column indicates the component is loaded after window onload event.",after_onload_legend="denotes 1x1 pixels image that may be image beacon",title="Components";if(YSLOW.doc){if(YSLOW.doc.components_legend){if(YSLOW.doc.components_legend.beacon){beacon_legend=YSLOW.doc.components_legend.beacon}if(YSLOW.doc.components_legend.after_onload){after_onload_legend=YSLOW.doc.components_legend.after_onload}}if(YSLOW.doc.view_names&&YSLOW.doc.view_names.components){title=YSLOW.doc.view_names.components}}sText='
    '+title+'The page has a total of '+comps.length+' components and a total weight of '+YSLOW.util.kbSize(totalSize)+' bytes
    '+tableHtml+'
    * '+beacon_legend+"
    † "+after_onload_legend+"
    ";return sText},reportcardPrintableView:function(results,overall_grade,ruleset){var i,j,result,grade,grade_class,html='
    ";for(i=0;i"}}html+="
    Overall Grade: '+overall_grade+" (Ruleset applied: "+ruleset.name+")
    '+grade+'

    '+result.name+'

    '+result.message+"
    ";if(result.components&&result.components.length>0){html+='
      ';for(j=0;j"+result.components[j]+""}else{if(result.components[j].url!==undefined){html+="
    • "+YSLOW.util.briefUrl(result.components[j].url,60)+"
    • "}}}html+="

    "}html+="

    ";return html},getFilterCode:function(categories,results,grade,url){var html,id,i,len,link,result,score,total=results.length,array=[];for(id in categories){if(categories.hasOwnProperty(id)&&categories[id]){array.push(id)}}array.sort();html='
    • ALL ('+total+')
    • FILTER BY:
    • ';for(i=0,len=array.length;i'+array[i].toUpperCase()+" ("+categories[array[i]]+")"}link="http://yslow.org/scoremeter/?url="+encodeURIComponent(url)+"&grade="+grade;for(i=0;i=0&&score<100){link+="&"+result.rule_id.toLowerCase()+"="+score}}link=encodeURIComponent(encodeURIComponent(link));url=encodeURIComponent(encodeURIComponent(url.slice(0,60)+(url.length>60?"...":"")));html+='";html+='";html+="
    ";return html},reportcardView:function(resultset){var overall_grade,i,j,k,result,grade,index,sClass,grade_class,score,messages,comp,string,rule,html='
    ',appliedRuleset=resultset.getRulesetApplied(),results=resultset.getResults(),url=resultset.url,title="Grade",tab_label_html="",tab_html="",categories={};if(YSLOW.doc){if(YSLOW.doc.view_names&&YSLOW.doc.view_names.grade){title=YSLOW.doc.view_names.grade}}overall_grade=YSLOW.util.prettyScore(resultset.getOverallScore());if(YSLOW.renderer.bPrintable){return this.reportcardPrintableView(results,overall_grade,appliedRuleset)}html+='
    '+title+'
    '+overall_grade+'
    Overall performance score '+Math.round(resultset.getOverallScore())+'Ruleset applied: '+appliedRuleset.name+'URL: '+YSLOW.util.briefUrl(url,100)+"
    ";for(i=0;i0){sClass+=" "}sClass+=result.category[k];if(categories[result.category[k]]===undefined){categories[result.category[k]]=0}categories[result.category[k]]+=1}}if(sClass.length>0){tab_label_html+=' class="'+sClass+'"'}tab_label_html+=' onclick="javascript:document.ysview.onclickResult(event)">
    '+grade+''+result.name+"
  • ";tab_html+='
    ")}tab_html+='">

    Grade '+grade+" on "+result.name+"

    "+result.message+"
    ";if(result.components&&result.components.length>0){tab_html+='

      ';for(j=0;j"+comp+""}else{if(comp.url!==undefined){tab_html+="
    • ";string=result.rule_id.toLowerCase();if(result.rule_id.match("expires")){tab_html+="("+YSLOW.util.prettyExpiresDate(comp.expires)+") "}tab_html+=YSLOW.util.prettyAnchor(comp.url,comp.url,undefined,true,120,undefined,comp.type)+"
    • "}}}tab_html+="

    "}tab_html+="

    ";rule=YSLOW.controller.getRule(result.rule_id);if(rule){tab_html+='

    '+(rule.info||"** To be added **")+"

    ";if(rule.url!==undefined){tab_html+='

    »Read More

    "}}tab_html+="
    "}}html+='
    '+this.getFilterCode(categories,results,overall_grade,url)+'
      '+tab_label_html+'
    '+tab_html+'
    '+YSLOW.doc.copyright+"
    ";return html},statsView:function(stats){var sText="",title="Stats";if(YSLOW.doc){if(YSLOW.doc.view_names&&YSLOW.doc.view_names.stats){title=YSLOW.doc.view_names.stats}}sText+='
    '+title+'The page has a total of '+stats.PAGE.totalRequests+' HTTP requests and a total weight of '+YSLOW.util.kbSize(stats.PAGE.totalSize)+" bytes with empty cache
    ";sText+='
    WEIGHT GRAPHS
    ';sText+='
    Empty Cache
    '+YSLOW.renderer.genStats(stats,false)+"
    ";sText+='
    Primed Cache
    '+YSLOW.renderer.genStats(stats,true)+"
    ";sText+="
    ";return sText},toolsView:function(tools){var i,sText,tool,tableHtml="",title="Tools",desc="Click the Launch Tool link next to the tool you want to run to start the tool.";if(YSLOW.doc){if(YSLOW.doc.tools_desc){desc=YSLOW.doc.tools_desc}if(YSLOW.doc.view_names&&YSLOW.doc.view_names.tools){title=YSLOW.doc.view_names.tools}}for(i=0;i"}tableHtml+="
    "+tool.name+"-"+(tool.short_desc||"Short text here explaining what are the main benefits of running this App")+"
    ";sText='
    '+title+""+desc+'
    '+tableHtml+"
    ";return sText},rulesetEditView:function(rulesets){var id,ruleset,tab_id,sText,settingsHtml='
    ',navHtml,contentHtml,index=0,custom=false,selectedRuleset,defaultRulesetId,title="Rule Settings",desc="Choose which ruleset better fit your specific needs. You can Save As an existing rule, based on an existing ruleset.";if(YSLOW.doc){if(YSLOW.doc.rulesettings_desc){desc=YSLOW.doc.rulesettings_desc}if(YSLOW.doc.view_names&&YSLOW.doc.view_names.rulesetedit){title=YSLOW.doc.view_names.rulesetedit}}defaultRulesetId=YSLOW.controller.getDefaultRulesetId();navHtml='
    • STANDARD SETS
    • ';for(id in rulesets){if(rulesets.hasOwnProperty(id)&&rulesets[id]){ruleset=rulesets[id];tab_id="tab"+index;if(!custom&&ruleset.custom===true){navHtml+='
    • CUSTOM SETS
    • ';custom=true}navHtml+='
    • '+ruleset.name+"
    • ";index+=1}}navHtml+='
    ';contentHtml='
    '+YSLOW.renderer.genRulesetEditForm(selectedRuleset)+"
    ";settingsHtml+=navHtml+contentHtml;sText='
    '+title+""+desc+"
    "+settingsHtml+"
    ";return sText},rulesetEditUpdateTab:function(doc,form,ruleset,updateAction,updateSelection){var ul_elem,content,li_elem,index,id,tab_id,event,custom_set_title,label_id,idx,prev_li_elem,header,event2,container=form.parentNode.parentNode.parentNode;if(container&&container.id==="settingsDiv"&&ruleset.custom===true){ul_elem=container.firstChild;content=ul_elem.nextSibling;if(updateAction<1){li_elem=ul_elem.firstChild;while(li_elem){index=li_elem.className.indexOf("ruleset-");if(index!==-1){id=li_elem.className.substring(index+8);index=id.indexOf(" ");if(index!==-1){id=id.substring(0,index)}if(ruleset.id===id){index=li_elem.id.indexOf("label");if(index!==-1){tab_id=li_elem.id.substring(index+5);if(li_elem.className.indexOf("selected")!==-1){event={};event.currentTarget=prev_li_elem;doc.ysview.onclickRuleset(event)}if(li_elem.previousSibling&&li_elem.previousSibling.id==="custom-set-title"&&li_elem.nextSibling&&li_elem.nextSibling.id==="create-ruleset"){custom_set_title=li_elem.previousSibling}ul_elem.removeChild(li_elem);if(custom_set_title){ul_elem.removeChild(custom_set_title)}}break}else{prev_li_elem=li_elem}}li_elem=li_elem.nextSibling}}else{li_elem=ul_elem.lastChild;while(li_elem){idx=li_elem.id.indexOf("label");if(idx!==-1){label_id=li_elem.id.substring(idx+5);break}li_elem=li_elem.previousSibling}label_id=Number(label_id)+1;li_elem=doc.createElement("li");li_elem.className="ruleset-"+ruleset.id;li_elem.id="label"+label_id;li_elem.onclick=function(event){doc.ysview.onclickRuleset(event)};li_elem.innerHTML=''+ruleset.name+"";ul_elem.insertBefore(li_elem,ul_elem.lastChild);header=ul_elem.firstChild;while(header){if(header.id&&header.id==="custom-set-title"){custom_set_title=header;break}header=header.nextSibling}if(!custom_set_title){custom_set_title=doc.createElement("li");custom_set_title.className="new-section header";custom_set_title.id="custom-set-title";custom_set_title.innerHTML="CUSTOM SETS";ul_elem.insertBefore(custom_set_title,li_elem)}if(updateSelection){event2={};event2.currentTarget=li_elem;doc.ysview.onclickRuleset(event2)}}}},hasClassName:function(class_name,name){var i,arr_class=class_name.split(" ");if(arr_class){for(i=0;i";sText+=""+comps[i].type+"";sText+=""+comps[i].size+"";if(comps[i].compressed===false){sText+=""}else{sText+=""+(comps[i].size_compressed!==undefined?parseInt(comps[i].size_compressed,10):"uncertain")+""}cookieSize=comps[i].getSetCookieSize();if(cookieSize>0){sText+=""+parseInt(cookieSize,10)+""}cookieSize=comps[i].getReceivedCookieSize();if(cookieSize>0){sText+=""+parseInt(cookieSize,10)+""}sText+=""+encodeURI(comps[i].url)+"";sText+=""+comps[i].expires+"";sText+=""+comps[i].respTime+"";sText+=""+comps[i].getEtag()+"";sText+=""}sText+="";return sText},reportcardView:function(resultset){var i,j,result,overall_score=resultset.getOverallScore(),overall_grade=YSLOW.util.prettyScore(overall_score),appliedRuleset=resultset.getRulesetApplied(),results=resultset.getResults(),sText='';sText+='';for(i=0;i';sText+=""+result.message+"";if(results.components&&results.components.length>0){sText+="";for(j=0;j"+result.components[j]+""}else{if(result.components[j].url!==undefined){sText+=""+result.components[j].url+""}}}sText+=""}sText+=""}sText+="";return sText},statsView:function(stats){var i,sType,sText,primed_cache_items='',empty_cache_items='',aTypes=YSLOW.peeler.types;for(i=0;i'}if((stats.PAGE.totalObjCount[sType])!==undefined){empty_cache_items+=''}}primed_cache_items+="";empty_cache_items+="";sText=''+primed_cache_items+empty_cache_items+"";return sText}});YSLOW.peeler={types:["doc","js","css","iframe","flash","cssimage","image","favicon","xhr","redirect","font"],NODETYPE:{ELEMENT:1,DOCUMENT:9},CSSRULE:{IMPORT_RULE:3,FONT_FACE_RULE:5},peel:function(node,onloadTimestamp){},findDocuments:function(node){var frames,doc,docUrl,type,i,len,el,frameDocs,parentDoc,allDocs={};YSLOW.util.event.fire("peelProgress",{total_step:7,current_step:1,message:"Finding documents"});if(!node){return}if(!YSLOW.util.Preference.getPref("extensions.yslow.getFramesComponents",true)){allDocs[node.URL]={document:node,type:"doc"};return allDocs}type="doc";if(node.nodeType===this.NODETYPE.DOCUMENT){doc=node;docUrl=node.URL}else{if(node.nodeType===this.NODETYPE.ELEMENT&&node.nodeName.toLowerCase()==="frame"){doc=node.contentDocument;docUrl=node.src}else{if(node.nodeType===this.NODETYPE.ELEMENT&&node.nodeName.toLowerCase()==="iframe"){doc=node.contentDocument;docUrl=node.src;type="iframe";try{parentDoc=node.contentWindow;parentDoc=parentDoc&&parentDoc.parent;parentDoc=parentDoc&&parentDoc.document;parentDoc=parentDoc||node.ownerDocument;if(parentDoc&&parentDoc.URL===docUrl){docUrl=!node.getAttribute("src")?"":"about:blank"}}catch(err){YSLOW.util.dump(err)}}else{return allDocs}}}allDocs[docUrl]={document:doc,type:type};try{frames=doc.getElementsByTagName("iframe");for(i=0,len=frames.length;i0){for(j=0;j0){for(j=0;j specify the information to display/log (basic|grade|stats|comps|all) [all]"," -f, --format specify the output results format (json|xml|plain|tap|junit) [json]"," -r, --ruleset specify the YSlow performance ruleset to be used (ydefault|yslow1|yblog) [ydefault]"," -b, --beacon specify an URL to log the results"," -d, --dict include dictionary of results fields"," -v, --verbose output beacon response information"," -t, --threshold for test formats, the threshold to test scores ([0-100]|[A-F]|{JSON}) [80]",' e.g.: -t B or -t 75 or -t \'{"overall": "B", "ycdn": "F", "yexpires": 85}\'',' -u, --ua "" specify the user agent string sent to server when the page requests resources'," -vp, --viewport specify page viewport size WxY, where W = width and H = height [400x300]",' -ch, --headers specify custom request headers, e.g.: -ch \'{"Cookie": "foo=bar"}\''," -c, --console output page console messages (0: none, 1: message, 2: message + line + source) [0]",' -C, --cookie specify an cookie for phantomjs ex) \'{"name":"cookie_name","value":"cookie_value","domain":"localhost"}\'',' --cdns "" specify comma separated list of additional CDNs',' -ba, --basicauth "" username & password used for basic auth',""," Examples:",""," phantomjs "+phantom.scriptName+" http://yslow.org"," phantomjs "+phantom.scriptName+" -i grade -f xml www.yahoo.com www.cnn.com www.nytimes.com"," phantomjs "+phantom.scriptName+' --info all --format plain --ua "MSIE 9.0" http://yslow.org'," phantomjs "+phantom.scriptName+" -i basic --rulseset yslow1 -d http://yslow.org"," phantomjs "+phantom.scriptName+" -i grade -b http://www.showslow.com/beacon/yslow/ -v yslow.org"," phantomjs --load-plugins=yes "+phantom.scriptName+" -vp 800x600 http://www.yahoo.com"," phantomjs "+phantom.scriptName+" -i grade -f tap -t 85 http://yslow.org",""].join("\n"));phantom.exit()}yslowArgs.dict=unaryArgs.dict;yslowArgs.verbose=unaryArgs.verbose;try{cookie=JSON.parse(yslowArgs.cookie,function(k,v){return v})}catch(e){cookie=undefined}if(cookie!=undefined){phantom.addCookie(cookie)}urls.forEach(function(url){function finishPhantomJS(exitStatus){urlCount-=1;if(urlCount===0){phantom.exit(exitStatus)}}function doRender(){var yslow,ysphantomjs,controller,evalFunc,loadTime,url,resp,output,exitStatus=0,startTime=page.startTime,resources=page.resources;loadTime=new Date()-startTime;for(url in resources){if(resources.hasOwnProperty(url)){resp=resources[url].response;if(resp){resp.time=new Date(resp.time)-startTime}}}yslow=function(){if(typeof YSLOW==="undefined"){YSLOW={}}YSLOW.DEBUG=true;YSLOW.registerRule=function(rule){YSLOW.controller.addRule(rule)};YSLOW.registerRuleset=function(ruleset){YSLOW.controller.addRuleset(ruleset)};YSLOW.registerRenderer=function(renderer){YSLOW.controller.addRenderer(renderer)};YSLOW.registerTool=function(tool){YSLOW.Tools.addCustomTool(tool)};YSLOW.addEventListener=function(event_name,callback,that){YSLOW.util.event.addListener(event_name,callback,that)};YSLOW.removeEventListener=function(event_name,callback){return YSLOW.util.event.removeListener(event_name,callback)};YSLOW.Error=function(name,message){this.name=name;this.message=message};YSLOW.Error.prototype={toString:function(){return this.name+"\n"+this.message}};YSLOW.version="3.1.8";YSLOW.ComponentSet=function(node,onloadTimestamp){this.root_node=node;this.components=[];this.outstanding_net_request=0;this.component_info=[];this.onloadTimestamp=onloadTimestamp;this.nextID=1;this.notified_fetch_done=false};YSLOW.ComponentSet.prototype={clear:function(){this.components=[];this.component_info=[];this.cleared=true;if(this.outstanding_net_request>0){YSLOW.util.dump("YSLOW.ComponentSet.Clearing component set before all net requests finish.")}},addComponent:function(url,type,base_href,o){var comp,found,isDoc;if(!url){if(!this.empty_url){this.empty_url=[]}this.empty_url[type]=(this.empty_url[type]||0)+1}if(url&&type){if(!YSLOW.ComponentSet.isValidProtocol(url)||!YSLOW.ComponentSet.isValidURL(url)){return comp}url=YSLOW.util.makeAbsoluteUrl(url,base_href);url=YSLOW.util.escapeHtml(url);found=typeof this.component_info[url]!=="undefined";isDoc=type==="doc";if(!found||isDoc){this.component_info[url]={state:"NONE",count:found?this.component_info[url].count:0};comp=new YSLOW.Component(url,type,this,o);if(comp){comp.id=this.nextID+=1;this.components[this.components.length]=comp;if(!this.doc_comp&&isDoc){this.doc_comp=comp}if(this.component_info[url].state==="NONE"){this.component_info[url].state="REQUESTED";this.outstanding_net_request+=1}}else{this.component_info[url].state="ERROR";YSLOW.util.event.fire("componentFetchError")}}this.component_info[url].count+=1}return comp},addComponentNoDuplicate:function(url,type,base_href){if(url&&type){url=YSLOW.util.escapeHtml(url);url=YSLOW.util.makeAbsoluteUrl(url,base_href);if(this.component_info[url]===undefined){return this.addComponent(url,type,base_href)}}},getComponentsByType:function(type,includeAfterOnload,includeBeacons){var i,j,len,lenJ,t,comp,info,components=this.components,compInfo=this.component_info,comps=[],types={};if(typeof includeAfterOnload==="undefined"){includeAfterOnload=!(YSLOW.util.Preference.getPref("excludeAfterOnload",true))}if(typeof includeBeacons==="undefined"){includeBeacons=!(YSLOW.util.Preference.getPref("excludeBeaconsFromLint",true))}if(typeof type==="string"){types[type]=1}else{for(i=0,len=type.length;i0){protocol=s.substr(0,index);for(i=0;i0){that.expires=new Date(that.headers.expires)}}if(that.type==="image"&&!ignoreImgReq){if(typeof Image!==UNDEF){obj=new Image()}else{obj=document.createElement("img")}if(that.body.length){img_src="data:"+that.headers["content-type"]+";base64,"+YSLOW.util.base64Encode(that.body);dataUri=1}else{img_src=that.url}obj.onerror=function(){obj.onerror=NULL;if(dataUri){obj.src=that.url}};obj.onload=function(){obj.onload=NULL;if(obj&&obj.width&&obj.height){if(that.object_prop){that.object_prop.actual_width=obj.width;that.object_prop.actual_height=obj.height}else{that.object_prop={width:obj.width,height:obj.height,actual_width:obj.width,actual_height:obj.height}}if(obj.width<2&&obj.height<2){that.is_beacon=true}}};obj.src=img_src}};YSLOW.Component.prototype.hasOldModifiedDate=function(){var now=Number(new Date()),modified_date=this.headers["last-modified"];if(typeof modified_date!=="undefined"){return((now-Number(new Date(modified_date)))>(24*60*60*1000))}return false};YSLOW.Component.prototype.hasFarFutureExpiresOrMaxAge=function(){var expires_in_seconds,now=Number(new Date()),minSeconds=YSLOW.util.Preference.getPref("minFutureExpiresSeconds",2*24*60*60),minMilliSeconds=minSeconds*1000;if(typeof this.expires==="object"){expires_in_seconds=Number(this.expires);if((expires_in_seconds-now)>minMilliSeconds){return true}}return false};YSLOW.Component.prototype.getEtag=function(){return this.headers.etag||""};YSLOW.Component.prototype.getMaxAge=function(){var index,maxage,expires,cache_control=this.headers["cache-control"];if(cache_control){index=cache_control.indexOf("max-age");if(index>-1){maxage=parseInt(cache_control.substring(index+8),10);if(maxage>0){expires=YSLOW.util.maxAgeToDate(maxage)}}}return expires};YSLOW.Component.prototype.getSetCookieSize=function(){var aCookies,k,size=0;if(this.headers&&this.headers["set-cookie"]){aCookies=this.headers["set-cookie"].split("\n");if(aCookies.length>0){for(k=0;k0){aCookies=this.cookie.split("\n");if(aCookies.length>0){for(k=0;kcomp.parent.onloadTimestamp;comp.populateProperties(false,true);comp.get_info_state="DONE";comp.parent.onComponentGetInfoStateChange({comp:comp,state:"DONE"})};if(o.request&&o.response){parse(o.request,o.response)}};YSLOW.controller={rules:{},rulesets:{},onloadTimestamp:null,renderers:{},default_ruleset_id:"ydefault",run_pending:0,init:function(){var arr_rulesets,i,obj,value;YSLOW.util.event.addListener("onload",function(e){this.onloadTimestamp=e.time;YSLOW.util.setTimer(function(){YSLOW.controller.run_pending_event()})},this);YSLOW.util.event.addListener("onUnload",function(e){this.run_pending=0;this.onloadTimestamp=null},this);arr_rulesets=YSLOW.util.Preference.getPrefList("customRuleset.",undefined);if(arr_rulesets&&arr_rulesets.length>0){for(i=0;i0){obj=JSON.parse(value,null);obj.custom=true;this.addRuleset(obj)}}}this.default_ruleset_id=YSLOW.util.Preference.getPref("defaultRuleset","ydefault");this.loadRulePreference()},run:function(win,yscontext,autorun){var cset,line,doc=win.document;if(!doc||!doc.location||doc.location.href.indexOf("about:")===0||"undefined"===typeof doc.location.hostname){if(!autorun){line="Please enter a valid website address before running YSlow.";YSLOW.ysview.openDialog(YSLOW.ysview.panel_doc,389,150,line,"","Ok")}return}if(!yscontext.PAGE.loaded){this.run_pending={win:win,yscontext:yscontext};return}YSLOW.util.event.fire("peelStart",undefined);cset=YSLOW.peeler.peel(doc,this.onloadTimestamp);yscontext.component_set=cset;YSLOW.util.event.fire("peelComplete",{component_set:cset});cset.notifyPeelDone()},run_pending_event:function(){if(this.run_pending){this.run(this.run_pending.win,this.run_pending.yscontext,false);this.run_pending=0}},lint:function(doc,yscontext,ruleset_id){var rule,rules,i,conf,result,weight,score,ruleset=[],results=[],total_score=0,total_weight=0,that=this,rs=that.rulesets,defaultRuleSetId=that.default_ruleset_id;if(ruleset_id){ruleset=rs[ruleset_id]}else{if(defaultRuleSetId&&rs[defaultRuleSetId]){ruleset=rs[defaultRuleSetId]}else{for(i in rs){if(rs.hasOwnProperty(i)&&rs[i]){ruleset=rs[i];break}}}}rules=ruleset.rules;for(i in rules){if(rules.hasOwnProperty(i)&&rules[i]&&this.rules.hasOwnProperty(i)){try{rule=this.rules[i];conf=YSLOW.util.merge(rule.config,rules[i]);result=rule.lint(doc,yscontext.component_set,conf);weight=(ruleset.weights?ruleset.weights[i]:undefined);if(weight!==undefined){weight=parseInt(weight,10)}if(weight===undefined||weight<0||weight>100){if(rs.ydefault.weights[i]){weight=rs.ydefault.weights[i]}else{weight=5}}result.weight=weight;if(result.score!==undefined){if(typeof result.score!=="number"){score=parseInt(result.score,10);if(!isNaN(score)){result.score=score}}if(typeof result.score==="number"){total_weight+=result.weight;if(!YSLOW.util.Preference.getPref("allowNegativeScore",false)){if(result.score<0){result.score=0}if(typeof result.score!=="number"){result.score=-1}}if(result.score!==0){total_score+=result.score*(typeof result.weight!=="undefined"?result.weight:1)}}}result.name=rule.name;result.category=rule.category;result.rule_id=i;results[results.length]=result}catch(err){YSLOW.util.dump("YSLOW.controller.lint: "+i,err);YSLOW.util.event.fire("lintError",{rule:i,message:err})}}}yscontext.PAGE.overallScore=total_score/(total_weight>0?total_weight:1);yscontext.result_set=new YSLOW.ResultSet(results,yscontext.PAGE.overallScore,ruleset);yscontext.result_set.url=yscontext.component_set.doc_comp.url;YSLOW.util.event.fire("lintResultReady",{yslowContext:yscontext});return yscontext.result_set},runTool:function(tool_id,yscontext,param){var result,html,doc,h,css,uri,req2,l,s,message,body,tool=YSLOW.Tools.getTool(tool_id);try{if(typeof tool==="object"){result=tool.run(yscontext.document,yscontext.component_set,param);if(tool.print_output){html="";if(typeof result==="object"){html=result.html}else{if(typeof result==="string"){html=result}}doc=YSLOW.util.getNewDoc();body=doc.body||doc.documentElement;body.innerHTML=html;h=doc.getElementsByTagName("head")[0];if(typeof result.css==="undefined"){uri="chrome://yslow/content/yslow/tool.css";req2=new XMLHttpRequest();req2.open("GET",uri,false);req2.send(null);css=req2.responseText}else{css=result.css}if(typeof css==="string"){l=doc.createElement("style");l.setAttribute("type","text/css");l.appendChild(doc.createTextNode(css));h.appendChild(l)}if(typeof result.js!=="undefined"){s=doc.createElement("script");s.setAttribute("type","text/javascript");s.appendChild(doc.createTextNode(result.js));h.appendChild(s)}if(typeof result.plot_component!=="undefined"&&result.plot_component===true){YSLOW.renderer.plotComponents(doc,yscontext)}}}else{message=tool_id+" is not a tool.";YSLOW.util.dump(message);YSLOW.util.event.fire("toolError",{tool_id:tool_id,message:message})}}catch(err){YSLOW.util.dump("YSLOW.controller.runTool: "+tool_id,err);YSLOW.util.event.fire("toolError",{tool_id:tool_id,message:err})}},render:function(id,view,params){var renderer=this.renderers[id],content="";if(renderer.supports[view]!==undefined&&renderer.supports[view]===1){switch(view){case"components":content=renderer.componentsView(params.comps,params.total_size);break;case"reportcard":content=renderer.reportcardView(params.result_set);break;case"stats":content=renderer.statsView(params.stats);break;case"tools":content=renderer.toolsView(params.tools);break;case"rulesetEdit":content=renderer.rulesetEditView(params.rulesets);break}}return content},getRenderer:function(id){return this.renderers[id]},addRule:function(rule){var i,doc_obj,required=["id","name","config","info","lint"];if(YSLOW.doc.rules&&YSLOW.doc.rules[rule.id]){doc_obj=YSLOW.doc.rules[rule.id];if(doc_obj.name){rule.name=doc_obj.name}if(doc_obj.info){rule.info=doc_obj.info}}for(i=0;i0&&rule){rule.config.howfar=minSeconds}}};YSLOW.util={merge:function(a,b){var i,o={};for(i in a){if(a.hasOwnProperty(i)){o[i]=a[i]}}for(i in b){if(b.hasOwnProperty(i)){o[i]=b[i]}}return o},dump:function(){var args;if(!YSLOW.DEBUG){return}args=Array.prototype.slice.apply(arguments);args=args&&args.length===1?args[0]:args;try{if(typeof Firebug!=="undefined"&&Firebug.Console&&Firebug.Console.log){Firebug.Console.log(args)}else{if(typeof Components!=="undefined"&&Components.classes&&Components.interfaces){Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService).logStringMessage(JSON.stringify(args,null,2))}}}catch(e1){try{console.log(args)}catch(e2){}}},filter:function(hash,callback,rekey){var i,result=rekey?[]:{};for(i in hash){if(hash.hasOwnProperty(i)&&callback(i,hash[i])){result[rekey?result.length:i]=hash[i]}}return result},expires_month:{Jan:1,Feb:2,Mar:3,Apr:4,May:5,Jun:6,Jul:7,Aug:8,Sep:9,Oct:10,Nov:11,Dec:12},prettyExpiresDate:function(expires){var month;if(Object.prototype.toString.call(expires)==="[object Date]"&&expires.toString()!=="Invalid Date"&&!isNaN(expires)){month=expires.getMonth()+1;return expires.getFullYear()+"/"+month+"/"+expires.getDate()}else{if(!expires){return"no expires"}}return"invalid date object"},maxAgeToDate:function(seconds){var d=new Date();d=d.getTime()+parseInt(seconds,10)*1000;return new Date(d)},plural:function(template,number){var i,res=template,repl={are:["are","is"],s:["s",""],"do":["do","does"],num:[number,number]};for(i in repl){if(repl.hasOwnProperty(i)){res=res.replace(new RegExp("%"+i+"%","gm"),(number===1)?repl[i][1]:repl[i][0])}}return res},countExpressions:function(content){var num_expr=0,index;index=content.indexOf("expression(");while(index!==-1){num_expr+=1;index=content.indexOf("expression(",index+1)}return num_expr},countAlphaImageLoaderFilter:function(content){var index,colon,filter_hack,value,num_filter=0,num_hack_filter=0,result={};index=content.indexOf("filter:");while(index!==-1){filter_hack=false;if(index>0&&content.charAt(index-1)==="_"){filter_hack=true}colon=content.indexOf(";",index+7);if(colon!==-1){value=content.substring(index+7,colon);if(value.indexOf("AlphaImageLoader")!==-1){if(filter_hack){num_hack_filter+=1}else{num_filter+=1}}}index=content.indexOf("filter:",index+1)}if(num_hack_filter>0){result.hackFilter=num_hack_filter}if(num_filter>0){result.filter=num_filter}return result},getHostname:function(url){var hostname=url.split("/")[2];return(hostname&&hostname.split(":")[0])||""},getUniqueDomains:function(comps,exclude_ips){var i,len,parts,domains={},retval=[];for(i=0,len=comps.length;i0.2){return false}return true},isETagGood:function(etag){var reIIS=/^[0-9a-f]+:([1-9a-f]|[0-9a-f]{2,})$/,reApache=/^[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+$/;if(!etag){return true}etag=etag.replace(/^["']|["'][\s\S]*$/g,"");return !(reApache.test(etag)||reIIS.test(etag))},getComponentType:function(content_type){var c_type="unknown";if(content_type&&typeof content_type==="string"){if(content_type==="text/html"||content_type==="text/plain"){c_type="doc"}else{if(content_type==="text/css"){c_type="css"}else{if(/javascript/.test(content_type)){c_type="js"}else{if(/flash/.test(content_type)){c_type="flash"}else{if(/image/.test(content_type)){c_type="image"}else{if(/font/.test(content_type)){c_type="font"}}}}}}}return c_type},base64Encode:function(data){var i,a,b,c,new_data="",padding=0,arr=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"];for(i=0;i>2];new_data+=arr[((a&3)<<4)|((b&240)>>4)];if(padding>0){new_data+="="}else{new_data+=arr[((b&15)<<2)|((c&192)>>6)]}if(padding>1){new_data+="="}else{new_data+=arr[(c&63)]}}return new_data},getXHR:function(){var i=0,xhr=null,ids=["MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];if(typeof XMLHttpRequest==="function"){return new XMLHttpRequest()}for(i=0;i/g,">")},escapeQuotes:function(str,which){if(which==="single"){return str.replace(/\'/g,"\\'")}if(which==="double"){return str.replace(/\"/g,'\\"')}return str.replace(/\'/g,"\\'").replace(/\"/g,'\\"')},formatHeaderName:(function(){var specialCases={"content-md5":"Content-MD5",dnt:"DNT",etag:"ETag",p3p:"P3P",te:"TE","www-authenticate":"WWW-Authenticate","x-att-deviceid":"X-ATT-DeviceId","x-cdn":"X-CDN","x-ua-compatible":"X-UA-Compatible","x-xss-protection":"X-XSS-Protection"};return function(headerName){var lowerCasedHeaderName=headerName.toLowerCase();if(specialCases.hasOwnProperty(lowerCasedHeaderName)){return specialCases[lowerCasedHeaderName]}else{return lowerCasedHeaderName.replace(/(^|-)([a-z])/g,function($0,optionalLeadingDash,ch){return optionalLeadingDash+ch.toUpperCase()})}}}()),mod:function(divisee,base){return Math.round(divisee-(Math.floor(divisee/base)*base))},briefUrl:function(url,maxchars){var iDoubleSlash,iQMark,iFirstSlash,iLastSlash;maxchars=maxchars||100;if(url===undefined){return""}iDoubleSlash=url.indexOf("//");if(-1!==iDoubleSlash){iQMark=url.indexOf("?");if(-1!==iQMark){url=url.substring(0,iQMark)+"?..."}if(url.length>maxchars){iFirstSlash=url.indexOf("/",iDoubleSlash+2);iLastSlash=url.lastIndexOf("/");if(-1!==iFirstSlash&&-1!==iLastSlash&&iFirstSlash!==iLastSlash){url=url.substring(0,iFirstSlash+1)+"..."+url.substring(iLastSlash)}else{url=url.substring(0,maxchars+1)+"..."}}}return url},prettyAnchor:function(text,url,sClass,bBriefUrl,maxChars,numLines,rel){var escaped_dq_url,sTitle="",sResults="",iLines=0;if(typeof url==="undefined"){url=text}if(typeof sClass==="undefined"){sClass=""}else{sClass=' class="'+sClass+'"'}if(typeof maxChars==="undefined"){maxChars=100}if(typeof numLines==="undefined"){numLines=1}rel=(rel)?' rel="'+rel+'"':"";url=YSLOW.util.escapeHtml(url);text=YSLOW.util.escapeHtml(text);escaped_dq_url=YSLOW.util.escapeQuotes(url,"double");if(bBriefUrl){text=YSLOW.util.briefUrl(text,maxChars);sTitle=' title="'+escaped_dq_url+'"'}while(0"+text.substring(0,maxChars);text=text.substring(maxChars);iLines+=1;if(iLines>=numLines){if(0";break}else{sResults+=" "}}return sResults},kbSize:function(size){var remainder=size%(size>100?100:10);size-=remainder;return parseFloat(size/1000)+(0===(size%1000)?".0":"")+"K"},prettyTypes:{image:"Image",doc:"HTML/Text",cssimage:"CSS Image",css:"Stylesheet File",js:"JavaScript File",flash:"Flash Object",iframe:"IFrame",xhr:"XMLHttpRequest",redirect:"Redirect",favicon:"Favicon",unknown:"Unknown"},prettyType:function(sType){return YSLOW.util.prettyTypes[sType]},prettyScore:function(score){var letter="F";if(!parseInt(score,10)&&score!==0){return score}if(score===-1){return"N/A"}if(score>=90){letter="A"}else{if(score>=80){letter="B"}else{if(score>=70){letter="C"}else{if(score>=60){letter="D"}else{if(score>=50){letter="E"}}}}}return letter},getResults:function(yscontext,info){var i,l,results,url,type,comps,comp,encoded_url,obj,cr,cs,etag,name,len,include_grade,include_comps,include_stats,result,len2,spaceid,header,sourceHeaders,targetHeaders,reButton=/ "):"")}}return{score:score,message:message,components:offenders}}});YSLOW.registerRule({id:"yexpires",url:"http://developer.yahoo.com/performance/rules.html#expires",category:["server"],config:{points:11,howfar:172800,types:["css","js","image","cssimage","flash","favicon"]},lint:function(doc,cset,config){var ts,i,expiration,score,len,far=parseInt(config.howfar,10)*1000,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;its+far){continue}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% static component%s%",offenders.length)+" without a far-future expiration date.":"",components:offenders}}});YSLOW.registerRule({id:"ycompress",url:"http://developer.yahoo.com/performance/rules.html#gzip",category:["server"],config:{min_filesize:500,types:["doc","iframe","xhr","js","css"],points:11},lint:function(doc,cset,config){var i,len,score,comp,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% plain text component%s%",offenders.length)+" that should be sent compressed":"",components:offenders}}});YSLOW.registerRule({id:"ycsstop",url:"http://developer.yahoo.com/performance/rules.html#css_top",category:["css"],config:{points:10},lint:function(doc,cset,config){var i,len,score,comp,comps=cset.getComponentsByType("css"),offenders=[];for(i=0,len=comps.length;i0){score-=1+offenders.length*parseInt(config.points,10)}return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% stylesheet%s%",offenders.length)+" found in the body of the document":"",components:offenders}}});YSLOW.registerRule({id:"yjsbottom",url:"http://developer.yahoo.com/performance/rules.html#js_bottom",category:["javascript"],config:{points:5},lint:function(doc,cset,config){var i,len,comp,score,offenders=[],comps=cset.getComponentsByType("js");for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% JavaScript script%s%",offenders.length)+" found in the head of the document":"",components:offenders}}});YSLOW.registerRule({id:"yexpressions",url:"http://developer.yahoo.com/performance/rules.html#css_expressions",category:["css"],config:{points:2},lint:function(doc,cset,config){var i,len,expr_count,comp,instyles=(cset.inline&&cset.inline.styles)||[],comps=cset.getComponentsByType("css"),offenders=[],score=100,total=0;for(i=0,len=comps.length;i0){comp.yexpressions=YSLOW.util.plural("%num% expression%s%",expr_count);total+=expr_count;offenders.push(comp)}}for(i=0,len=instyles.length;i0){offenders.push("inline <style> tag #"+(i+1)+" ("+YSLOW.util.plural("%num% expression%s%",expr_count)+")");total+=expr_count}}if(total>0){score=90-total*config.points}return{score:score,message:total>0?"There is a total of "+YSLOW.util.plural("%num% expression%s%",total):"",components:offenders}}});YSLOW.registerRule({id:"yexternal",url:"http://developer.yahoo.com/performance/rules.html#external",category:["javascript","css"],config:{},lint:function(doc,cset,config){var message,inline=cset.inline,styles=(inline&&inline.styles)||[],scripts=(inline&&inline.scripts)||[],offenders=[];if(styles.length){message=YSLOW.util.plural("There is a total of %num% inline css",styles.length);offenders.push(message)}if(scripts.length){message=YSLOW.util.plural("There is a total of %num% inline script%s%",scripts.length);offenders.push(message)}return{score:"n/a",message:"Only consider this if your property is a common user home page.",components:offenders}}});YSLOW.registerRule({id:"ydns",url:"http://developer.yahoo.com/performance/rules.html#dns_lookups",category:["content"],config:{max_domains:4,points:5},lint:function(doc,cset,config){var i,len,domain,util=YSLOW.util,kbSize=util.kbSize,plural=util.plural,score=100,domains=util.summaryByDomain(cset.components,["size","size_compressed"],true);if(domains.length>config.max_domains){score-=(domains.length-config.max_domains)*config.points}if(domains.length){for(i=0,len=domains.length;i0?" ("+kbSize(domain.sum_size_compressed)+" GZip)":"")}}return{score:score,message:(domains.length>config.max_domains)?plural("The components are split over more than %num% domain%s%",config.max_domains):"",components:domains}}});YSLOW.registerRule({id:"yminify",url:"http://developer.yahoo.com/performance/rules.html#minify",category:["javascript","css"],config:{points:10,types:["js","css"]},lint:function(doc,cset,config){var i,len,score,minified,comp,inline=cset.inline,styles=(inline&&inline.styles)||[],scripts=(inline&&inline.scripts)||[],comps=cset.getComponentsByType(config.types),offenders=[];for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% component%s% that can be minified",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yredirects",url:"http://developer.yahoo.com/performance/rules.html#redirects",category:["content"],config:{points:10},lint:function(doc,cset,config){var i,len,comp,score,offenders=[],briefUrl=YSLOW.util.briefUrl,comps=cset.getComponentsByType("redirect");for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% redirect%s%",comps.length):"",components:offenders}}});YSLOW.registerRule({id:"ydupes",url:"http://developer.yahoo.com/performance/rules.html#js_dupes",category:["javascript","css"],config:{points:5,types:["js","css"]},lint:function(doc,cset,config){var i,url,score,len,hash={},offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i1){offenders.push(comps[hash[i].compindex])}}score=100-offenders.length*parseInt(config.points,10);return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% duplicate component%s%",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yetags",url:"http://developer.yahoo.com/performance/rules.html#etags",category:["server"],config:{points:11,types:["flash","js","css","cssimage","image","favicon"]},lint:function(doc,cset,config){var i,len,score,comp,etag,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% component%s% with misconfigured ETags",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yxhr",url:"http://developer.yahoo.com/performance/rules.html#cacheajax",category:["content"],config:{points:5,min_cache_time:3600},lint:function(doc,cset,config){var i,expiration,ts,score,cache_control,min=parseInt(config.min_cache_time,10)*1000,offenders=[],comps=cset.getComponentsByType("xhr");for(i=0;its+min){continue}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% XHR component%s% that %are% not cacheable",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yxhrmethod",url:"http://developer.yahoo.com/performance/rules.html#ajax_get",category:["server"],config:{points:5},lint:function(doc,cset,config){var i,score,offenders=[],comps=cset.getComponentsByType("xhr");for(i=0;i0)?YSLOW.util.plural("There %are% %num% XHR component%s% that %do% not use GET HTTP method",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ymindom",url:"http://developer.yahoo.com/performance/rules.html#min_dom",category:["content"],config:{range:250,points:10,maxdom:900},lint:function(doc,cset,config){var numdom=cset.domElementsCount,score=100;if(numdom>config.maxdom){score=99-Math.ceil((numdom-parseInt(config.maxdom,10))/parseInt(config.range,10))*parseInt(config.points,10)}return{score:score,message:(numdom>config.maxdom)?YSLOW.util.plural("There %are% %num% DOM element%s% on the page",numdom):"",components:[]}}});YSLOW.registerRule({id:"yno404",url:"http://developer.yahoo.com/performance/rules.html#no404",category:["content"],config:{points:5,types:["css","js","image","cssimage","flash","xhr","favicon"]},lint:function(doc,cset,config){var i,len,comp,score,offenders=[],comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% request%s% that %are% 404 Not Found",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ymincookie",url:"http://developer.yahoo.com/performance/rules.html#cookie_size",category:["cookie"],config:{points:10,max_cookie_size:1000},lint:function(doc,cset,config){var n,cookies=cset.cookies,cookieSize=(cookies&&cookies.length)||0,message="",score=100;if(cookieSize>config.max_cookie_size){n=Math.floor(cookieSize/config.max_cookie_size);score-=1+n*parseInt(config.points,10);message=YSLOW.util.plural("There %are% %num% byte%s% of cookies on this page",cookieSize)}return{score:score,message:message,components:[]}}});YSLOW.registerRule({id:"ycookiefree",url:"http://developer.yahoo.com/performance/rules.html#cookie_free",category:["cookie"],config:{points:5,types:["js","css","image","cssimage","flash","favicon"]},lint:function(doc,cset,config){var i,len,score,comp,cookie,offenders=[],getHostname=YSLOW.util.getHostname,docDomain=getHostname(cset.doc_comp.url),comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;i0)?YSLOW.util.plural("There %are% %num% component%s% that %are% not cookie-free",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ynofilter",url:"http://developer.yahoo.com/performance/rules.html#no_filters",category:["css"],config:{points:5,halfpoints:2},lint:function(doc,cset,config){var i,len,score,comp,type,count,filter_count,instyles=(cset.inline&&cset.inline.styles)||[],comps=cset.getComponentsByType("css"),offenders=[],filter_total=0,hack_filter_total=0;for(i=0,len=comps.length;i0){comps[i].yfilters=YSLOW.util.plural("%num% filter%s%",count);offenders.push(comps[i])}}for(i=0,len=instyles.length;i0){offenders.push("inline <style> tag #"+(i+1)+" ("+YSLOW.util.plural("%num% filter%s%",count)+")")}}score=100-(filter_total*config.points+hack_filter_total*config.halfpoints);return{score:score,message:(filter_total+hack_filter_total)>0?"There is a total of "+YSLOW.util.plural("%num% filter%s%",filter_total+hack_filter_total):"",components:offenders}}});YSLOW.registerRule({id:"yimgnoscale",url:"http://developer.yahoo.com/performance/rules.html#no_scale",category:["images"],config:{points:5},lint:function(doc,cset,config){var i,prop,score,offenders=[],comps=cset.getComponentsByType("image");for(i=0;i0)?YSLOW.util.plural("There %are% %num% image%s% that %are% scaled down",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"yfavicon",url:"http://developer.yahoo.com/performance/rules.html#favicon",category:["images"],config:{points:5,size:2000,min_cache_time:3600},lint:function(doc,cset,config){var ts,expiration,comp,score,cacheable,messages=[],min=parseInt(config.min_cache_time,10)*1000,comps=cset.getComponentsByType("favicon");if(comps.length){comp=comps[0];if(parseInt(comp.status,10)===404){messages.push("Favicon was not found")}if(comp.size>config.size){messages.push(YSLOW.util.plural("Favicon is more than %num% bytes",config.size))}expiration=comp.expires;if(typeof expiration==="object"&&typeof expiration.getTime==="function"){ts=new Date().getTime();cacheable=expiration.getTime()>=ts+min}if(!cacheable){messages.push("Favicon is not cacheable")}}score=100-messages.length*parseInt(config.points,10);return{score:score,message:(messages.length>0)?messages.join("\n"):"",components:[]}}});YSLOW.registerRule({id:"yemptysrc",url:"http://developer.yahoo.com/performance/rules.html#emptysrc",category:["server"],config:{points:100},lint:function(doc,cset,config){var type,score,count,emptyUrl=cset.empty_url,offenders=[],messages=[],msg="",points=parseInt(config.points,10);score=100;if(emptyUrl){for(type in emptyUrl){if(emptyUrl.hasOwnProperty(type)){count=emptyUrl[type];score-=count*points;messages.push(count+" "+type)}}msg=messages.join(", ")+YSLOW.util.plural(" component%s% with empty link were found.",messages.length)}return{score:score,message:msg,components:offenders}}});YSLOW.registerRuleset({id:"ydefault",name:"YSlow(V2)",rules:{ynumreq:{},ycdn:{},yemptysrc:{},yexpires:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},yexternal:{},ydns:{},yminify:{},yredirects:{},ydupes:{},yetags:{},yxhr:{},yxhrmethod:{},ymindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},yimgnoscale:{},yfavicon:{}},weights:{ynumreq:8,ycdn:6,yemptysrc:30,yexpires:10,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,yexternal:4,ydns:3,yminify:4,yredirects:4,ydupes:4,yetags:2,yxhr:4,yxhrmethod:3,ymindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,yimgnoscale:3,yfavicon:2}});YSLOW.registerRuleset({id:"yslow1",name:"Classic(V1)",rules:{ynumreq:{},ycdn:{},yexpires:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},yexternal:{},ydns:{},yminify:{types:["js"],check_inline:false},yredirects:{},ydupes:{types:["js"]},yetags:{}},weights:{ynumreq:8,ycdn:6,yexpires:10,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,yexternal:4,ydns:3,yminify:4,yredirects:4,ydupes:4,yetags:2}});YSLOW.registerRuleset({id:"yblog",name:"Small Site or Blog",rules:{ynumreq:{},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},yredirects:{},ydupes:{},ymindom:{},yno404:{},ynofilter:{},yimgnoscale:{},yfavicon:{}},weights:{ynumreq:8,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,yredirects:4,ydupes:4,ymindom:3,yno404:4,ynofilter:4,yimgnoscale:3,yfavicon:2}});var SITESPEEDHELP={};SITESPEEDHELP.getTLD=function(host){var tld=host;var noSecondaries=/\.(gov|ac|mil|net|org|co)\.\w\w$/i;if(host.match(noSecondaries)){var threePart=/[\w]+\.[\w]+\.[\w]+$/i;tld=host.match(threePart).toString()}else{var twoPart=/[\w]+\.[\w]+$/i;tld=host.match(twoPart).toString()}return tld};SITESPEEDHELP.getTextLength=function(element){var avoidTextInScriptAndStyle=("script style").split(" ");var textLength=0;function getLength(element){if(element.childNodes&&element.childNodes.length>0){for(var i=0;i=(edge||0)}SITESPEEDHELP.versionCompare=function(userVersion,edgeVersion){if(userVersion===undefined){return true}userVersion=userVersion.split(".");var major=digitCompare(userVersion[0],edgeVersion[0]),minor=digitCompare(userVersion[1],edgeVersion[1]),build=digitCompare(userVersion[2],edgeVersion[2]);return(!major||major&&!minor||major&&minor&&!build)};SITESPEEDHELP.isSameDomainTLD=function(docDomainTLD,cssUrl,fontFaceUrl){if((/^http/).test(fontFaceUrl)){if(docDomainTLD===SITESPEEDHELP.getTLD(YSLOW.util.getHostname(fontFaceUrl))){return true}else{return false}}else{if(docDomainTLD===SITESPEEDHELP.getTLD(YSLOW.util.getHostname(cssUrl))){return true}else{return false}}return false};YSLOW.registerRule({id:"cssprint",name:"Do not load print stylesheets, use @media type print instead",info:"Loading a specific stylesheet for printing slows down the page, even though it is not used",category:["css"],config:{points:20},url:"http://sitespeed.io/rules/#cssprint",lint:function(doc,cset,config){var i,media,score,url,offenders=[],hash={},comps=cset.getComponentsByType("css"),links=doc.getElementsByTagName("link");for(i=0,len=links.length;i0)?YSLOW.util.plural("There %are% %num% print css files included on the page, that should be @media query instead",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"ttfb",name:"Time to first byte",info:"It is important to have low time to the first byte to be able to render the page fast",category:["server"],config:{points:10,limitInMs:300,hurtEveryMs:100},url:"http://sitespeed.io/rules/#ttfb",lint:function(doc,cset,config){var i,limit=parseInt(config.limitInMs,10),hurtEveryMs=parseInt(config.hurtEveryMs,10),score,ttfb,comps=cset.getComponentsByType("doc");for(i=0,len=comps.length;ilimit){score=100-(Math.ceil((ttfb-limit)/hurtEveryMs)*parseInt(config.points,10))}}if(score<0){score=0}return{score:score,message:(score<100)?"The TTFB is too slow:"+ttfb+" ms. The limit is "+limit+" ms and for every "+hurtEveryMs+" ms points are removed":"",components:[""+ttfb]}}});YSLOW.registerRule({id:"cssinheaddomain",name:"Load CSS in head from document domain",info:"Make sure css in head is loaded from same domain as document, in order to have a better user experience and minimize dns lookups",category:["css"],config:{points:10},url:"http://sitespeed.io/rules/#cssinheaddomain",lint:function(doc,cset,config){var css=doc.getElementsByTagName("link"),comps=cset.getComponentsByType("css"),comp,docdomain,src,offenders={},offendercomponents=[],uniquedns=[],score=100;docdomain=YSLOW.util.getHostname(cset.doc_comp.url);for(i=0,len=css.length;its){continue}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);message=(offenders.length>0)?YSLOW.util.plural("There %are% %num% static component%s%",offenders.length)+" without a future expiration date.":"";return{score:score,message:message,components:offenders}}});YSLOW.registerRule({id:"longexpirehead",name:"Have expires headers equals or longer than one year",info:"All static components of a page should have at least one year expire header. However, analythics scripts will not give you bad points.",url:"http://sitespeed.io/rules/#longexpires",category:["server"],config:{points:5,types:["css","js","image","cssimage","flash","favicon"],skip:["https://secure.gaug.es/track.js","https://ssl.google-analytics.com/ga.js","http://www.google-analytics.com/ga.js"]},lint:function(doc,cset,config){var ts,i,expiration,score,len,message,offenders=[],skipped=[],far=31535000*1000,comps=cset.getComponentsByType(config.types);for(i=0,len=comps.length;its+far){continue}else{if(config.skip.indexOf(comps[i].url)>1){skipped.push(comps[i].url);continue}}}offenders.push(comps[i])}score=100-offenders.length*parseInt(config.points,10);message=(offenders.length>0)?YSLOW.util.plural("There %are% %num% static component%s%",offenders.length)+" without a expire header equal or longer than one year.":"";message+=(skipped.length>0)?YSLOW.util.plural(" There %are% %num% static component%s% that are skipped from the score calculation",skipped.length)+":"+skipped:"";return{score:score,message:message,components:offenders}}});YSLOW.registerRule({id:"inlinecsswhenfewrequest",name:"Do not load css files when the page has few request",info:"When a page has few requests, it is better to inline the css, to make the page to start render as early as possible",category:["css"],config:{points:20,limit:15,types:["css","js","image","cssimage","flash","favicon"]},url:"http://sitespeed.io/rules/#inlinecsswhenfewrequest",lint:function(doc,cset,config){var comps=cset.getComponentsByType(config.types),css=cset.getComponentsByType("css"),message="",score=100,offenders=[];if(comps.length0){for(i=0,len=css.length;i1){for(i=0,len=comps.length;iconfig.max_css){score-=(css.length-config.max_css)*config.points_css;message="This page has "+YSLOW.util.plural("%num% external stylesheet%s%",css.length)+". Try combining them into fewer requests.";for(var i=0;iconfig.max_cssimages){score-=(cssimages.length-config.max_cssimages)*config.points_cssimages;message="This page has "+YSLOW.util.plural("%num% external css image%s%",cssimages.length)+". Try combining them into fewer request.";for(var i=0;iconfig.max_js){message="There "+YSLOW.util.plural("%are% %num% script%s%",offender_comps.length)+" loaded synchronously that could be combined into fewer requests.";score-=(offender_comps.length-config.max_js)*parseInt(config.points_js,10)}return{score:score,message:message,components:offender_comps}}});YSLOW.registerRule({id:"noduplicates",name:"Remove duplicate JS and CSS",info:"It is bad practice include the same js or css twice",category:["js","css"],config:{},url:"http://developer.yahoo.com/performance/rules.html#js_dupes",lint:function(doc,cset,config){var i,url,score,len,comp,hash={},offenders=[],comps=cset.getComponentsByType(["js","css"]),scripts=doc.getElementsByTagName("script"),css=doc.getElementsByTagName("link");for(i=0,len=scripts.length;i1){offenders.push(comps[i])}}score=100-offenders.length*11;return{score:score,message:(offenders.length>0)?YSLOW.util.plural("There %are% %num% js/css file%s% included more than once on the page",offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"mindom",name:"Reduce the number of DOM elements",info:"The number of dom elements are in correlation to if the page is fast or not",url:"http://developer.yahoo.com/performance/rules.html#min_dom",category:["content"],config:{range:250,points:10,maxdom:900},lint:function(doc,cset,config){var numdom=cset.domElementsCount,score=100;if(numdom>config.maxdom){score=99-Math.ceil((numdom-parseInt(config.maxdom,10))/parseInt(config.range,10))*parseInt(config.points,10)}return{score:score,message:(numdom>config.maxdom)?YSLOW.util.plural("There %are% %num% DOM element%s% on the page",numdom):"",components:[""+numdom]}}});YSLOW.registerRule({id:"thirdpartyversions",name:"Always use latest versions of third party javascripts",info:"Unisng the latest versions, will make sure you have the fastest and hopefully leanest javascripts.",url:"http://sitespeed.io/rules/#thirdpartyversions",category:["js"],config:{points:10},lint:function(doc,cset,config){var message="",score,offenders=0;if(typeof jQuery=="function"){if(SITESPEEDHELP.versionCompare(jQuery.fn.jquery,[2,0,0])){message="You are using an old version of JQuery: "+jQuery.fn.jquery+" Newer version is faster & better. Upgrade to the newest version from http://jquery.com/";offenders+=1}}score=100-offenders*parseInt(config.points,10);return{score:score,message:message,components:[]}}});YSLOW.registerRule({id:"avoidscalingimages",name:"Never scale images in HTML",info:"Always use the correct size for images to avoid that a browser download an image that is larger than necessary.",url:"http://sitespeed.io/rules/#avoidscalingimages",category:["images"],config:{reallyBadLimit:100},lint:function(doc,cset,config){var message="",score,offenders=[],hash={},punish=0,comps=cset.getComponentsByType("image"),images=doc.getElementsByTagName("img");for(var i=0;i0){message=message+" "+img.src+" [browserWidth:"+img.clientWidth+" realImageWidth: "+img.naturalWidth+"]";hash[img.src]=1;if((img.clientWidth+config.reallyBadLimit)0)?YSLOW.util.plural("You have %num% image%s% that %are% scaled in the HTML:"+message,offenders.length):"",components:offenders}}});YSLOW.registerRule({id:"redirects",name:"Never do redirects",info:"Avoid doing redirects, it will kill you web page on mobile.",url:"http://sitespeed.io/rules/#redirects",category:["content"],config:{points:10},lint:function(doc,cset,config){var score,redirects=[];score=100-cset.redirects.length*parseInt(config.points,10);redirects.push(cset.redirects.length.toFixed(0));return{score:score,message:(cset.redirects.length>0)?YSLOW.util.plural("There %are% %num% redirect%s%.",cset.redirects.length)+" "+cset.redirects:"",components:redirects}}});YSLOW.registerRuleset({id:"sitespeed.io-desktop",name:"Sitespeed.io desktop rules",rules:{criticalpath:{},spof:{fontFaceInCssSpof:false,inlineFontFaceSpof:false},cssnumreq:{},cssimagesnumreq:{},jsnumreq:{},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},redirects:{},noduplicates:{},yetags:{},yxhr:{},yxhrmethod:{},mindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},avoidscalingimages:{},yfavicon:{},thirdpartyasyncjs:{},cssprint:{},cssinheaddomain:{},syncjsinhead:{},avoidfont:{},totalrequests:{},expiresmod:{},longexpirehead:{},nodnslookupswhenfewrequests:{},inlinecsswhenfewrequest:{},textcontent:{},thirdpartyversions:{},ycdn:{}},weights:{criticalpath:15,spof:5,cssnumreq:8,cssimagesnumreq:8,jsnumreq:8,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,redirects:4,noduplicates:4,yetags:2,yxhr:4,yxhrmethod:3,mindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,avoidscalingimages:5,yfavicon:2,thirdpartyasyncjs:10,cssprint:3,cssinheaddomain:8,syncjsinhead:20,avoidfont:1,totalrequests:10,expiresmod:10,longexpirehead:5,nodnslookupswhenfewrequests:8,inlinecsswhenfewrequest:7,textcontent:1,thirdpartyversions:5,ycdn:6}});YSLOW.registerRuleset({id:"sitespeed.io-mobile",name:"Sitespeed.io mobile rules",rules:{criticalpath:{},spof:{fontFaceInCssSpof:false,inlineFontFaceSpof:false},cssnumreq:{},cssimagesnumreq:{},jsnumreq:{},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},redirects:{},noduplicates:{},yetags:{},yxhr:{},yxhrmethod:{},mindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},avoidscalingimages:{},yfavicon:{},thirdpartyasyncjs:{},cssprint:{},cssinheaddomain:{},syncjsinhead:{},avoidfont:{},totalrequests:{},expiresmod:{},longexpirehead:{},nodnslookupswhenfewrequests:{},inlinecsswhenfewrequest:{},textcontent:{},thirdpartyversions:{},ycdn:{}},weights:{criticalpath:20,spof:5,cssnumreq:8,cssimagesnumreq:8,jsnumreq:8,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,redirects:15,noduplicates:4,yetags:2,yxhr:4,yxhrmethod:3,mindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,avoidscalingimages:10,yfavicon:2,thirdpartyasyncjs:10,cssprint:3,cssinheaddomain:8,syncjsinhead:20,avoidfont:5,totalrequests:14,expiresmod:10,longexpirehead:5,nodnslookupswhenfewrequests:15,inlinecsswhenfewrequest:10,textcontent:1,thirdpartyversions:5,ycdn:6}});YSLOW.registerRuleset({id:"sitespeed.io-desktop-http2.0",name:"Sitespeed.io desktop rules for HTTP 2.0",rules:{criticalpath:{},spof:{fontFaceInCssSpof:false,inlineFontFaceSpof:false},yemptysrc:{},ycompress:{},ycsstop:{},yjsbottom:{},yexpressions:{},ydns:{},yminify:{},redirects:{},noduplicates:{},yetags:{},yxhr:{},yxhrmethod:{},mindom:{},yno404:{},ymincookie:{},ycookiefree:{},ynofilter:{},avoidscalingimages:{},yfavicon:{},thirdpartyasyncjs:{},cssprint:{},cssinheaddomain:{},syncjsinhead:{},avoidfont:{},expiresmod:{},longexpirehead:{},textcontent:{},thirdpartyversions:{},ycdn:{}},weights:{criticalpath:15,spof:5,yemptysrc:30,ycompress:8,ycsstop:4,yjsbottom:4,yexpressions:3,ydns:3,yminify:4,redirects:4,noduplicates:4,yetags:2,yxhr:4,yxhrmethod:3,mindom:3,yno404:4,ymincookie:3,ycookiefree:3,ynofilter:4,avoidscalingimages:5,yfavicon:2,thirdpartyasyncjs:10,cssprint:3,cssinheaddomain:8,syncjsinhead:20,avoidfont:1,expiresmod:10,longexpirehead:5,textcontent:1,thirdpartyversions:5,ycdn:6}});YSLOW.ResultSet=function(results,overall_score,ruleset_applied){this.ruleset_applied=ruleset_applied;this.overall_score=overall_score;this.results=results};YSLOW.ResultSet.prototype={getResults:function(){return this.results},getRulesetApplied:function(){return this.ruleset_applied},getOverallScore:function(){return this.overall_score}};YSLOW.view=function(panel,yscontext){var toolbar,elem,dialogHtml,modaldlg,copyright;this.panel_doc=panel.document;this.buttonViews={};this.curButtonId="";this.panelNode=panel.panelNode;this.loadCSS(this.panel_doc);toolbar=this.panel_doc.createElement("div");toolbar.id="toolbarDiv";toolbar.innerHTML=this.getToolbarSource();toolbar.style.display="block";elem=this.panel_doc.createElement("div");elem.style.display="block";dialogHtml='

    text

    ';modaldlg=this.panel_doc.createElement("div");modaldlg.id="dialogDiv";modaldlg.innerHTML=dialogHtml;modaldlg.style.display="none";this.modaldlg=modaldlg;this.tooltip=new YSLOW.view.Tooltip(this.panel_doc,panel.panelNode);copyright=this.panel_doc.createElement("div");copyright.id="copyrightDiv";copyright.innerHTML=YSLOW.doc.copyright;this.copyright=copyright;if(panel.panelNode){panel.panelNode.id="yslowDiv";panel.panelNode.appendChild(modaldlg);panel.panelNode.appendChild(toolbar);panel.panelNode.appendChild(elem);panel.panelNode.appendChild(copyright)}this.viewNode=elem;this.viewNode.id="viewDiv";this.viewNode.className="yui-skin-sam";this.yscontext=yscontext;YSLOW.util.addEventListener(this.panelNode,"click",function(e){var help,helplink,x,y,parent;var doc=FBL.getContentView(panel.document);var toolbar=doc.ysview.getElementByTagNameAndId(panel.panelNode,"div","toolbarDiv");if(toolbar){helplink=doc.ysview.getElementByTagNameAndId(toolbar,"li","helpLink");if(helplink){x=helplink.offsetLeft;y=helplink.offsetTop;parent=helplink.offsetParent;while(parent){x+=parent.offsetLeft;y+=parent.offsetTop;parent=parent.offsetParent}if(e.clientX>=x&&e.clientY>=y&&e.clientX"+rule.name+"

    "+rule.info,e.target)}}}});YSLOW.util.addEventListener(this.panelNode,"mouseout",function(e){var doc=FBL.getContentView(panel.document);doc.ysview.tooltip.hide()});YSLOW.util.addEventListener(this.panel_doc.defaultView||this.panel_doc.parentWindow,"resize",function(e){var doc=FBL.getContentView(panel.document);var overlay=doc.ysview.modaldlg;if(overlay&&overlay.style.display==="block"){overlay.style.display="none"}})};YSLOW.view.prototype={setDocument:function(doc){this.panel_doc=doc},loadCSS:function(){},addButtonView:function(sButtonId,sHtml){var btnView=this.getButtonView(sButtonId);if(!btnView){btnView=this.panel_doc.createElement("div");btnView.style.display="none";this.viewNode.appendChild(btnView);this.buttonViews[sButtonId]=btnView}btnView.innerHTML=sHtml;this.showButtonView(sButtonId)},clearAllButtonView:function(){var views=this.buttonViews,node=this.viewNode,remove=function(v){if(views.hasOwnProperty(v)){node.removeChild(views[v]);delete views[v]}};remove("ysPerfButton");remove("ysCompsButton");remove("ysStatsButton")},showButtonView:function(sButtonId){var sId,btnView=this.getButtonView(sButtonId);if(!btnView){YSLOW.util.dump("ERROR: YSLOW.view.showButtonView: Couldn't find ButtonView '"+sButtonId+"'.");return}for(sId in this.buttonViews){if(this.buttonViews.hasOwnProperty(sId)&&sId!==sButtonId){this.buttonViews[sId].style.display="none"}}if(sButtonId==="ysPerfButton"){if(this.copyright){this.copyright.style.display="none"}}else{if(this.curButtonId==="ysPerfButton"){if(this.copyright){this.copyright.style.display="block"}}}btnView.style.display="block";this.curButtonId=sButtonId},getButtonView:function(sButtonId){return(this.buttonViews.hasOwnProperty(sButtonId)?this.buttonViews[sButtonId]:undefined)},setButtonView:function(sButtonId,sHtml){var btnView=this.getButtonView(sButtonId);if(!btnView){YSLOW.util.dump("ERROR: YSLOW.view.setButtonView: Couldn't find ButtonView '"+sButtonId+"'.");return}btnView.innerHTML=sHtml;this.showButtonView(sButtonId)},setSplashView:function(hideAutoRun,showAntiIframe,hideToolsInfo){var sHtml,title="Grade your web pages with YSlow",header="YSlow gives you:",text="
  • Grade based on the performance (you can define your own rules)
  • Summary of the Components in the page
  • Chart with statistics
  • Tools including Smush.It and JSLint
  • ",more_info_text="Learn more about YSlow and YDN";if(YSLOW.doc.splash){if(YSLOW.doc.splash.title){title=YSLOW.doc.splash.title}if(YSLOW.doc.splash.content){if(YSLOW.doc.splash.content.header){header=YSLOW.doc.splash.content.header}if(YSLOW.doc.splash.content.text){text=YSLOW.doc.splash.content.text}}if(YSLOW.doc.splash.more_info){more_info_text=YSLOW.doc.splash.more_info}}if(typeof hideToolsInfo!=="undefined"){YSLOW.hideToolsInfo=hideToolsInfo}else{hideToolsInfo=YSLOW.hideToolsInfo}if(hideToolsInfo){text=text.replace(/
  • Tools[^<]+<\/li>/,"")}sHtml='

    '+title+'

    '+header+'

      '+text+"
    ";if(typeof hideAutoRun!=="undefined"){YSLOW.hideAutoRun=hideAutoRun}else{hideAutoRun=YSLOW.hideAutoRun}if(!hideAutoRun){sHtml+=''}sHtml+='
    ";this.addButtonView("panel_about",sHtml)},genProgressView:function(){var sBody='

    Finding components in the page:

    Getting component information:

    start...
    ';this.setButtonView("panel_about",sBody)},updateProgressView:function(progress_type,progress_info){var outerbar,progbar,progtext,percent,view,maxwidth,width,left,message="";if(this.curButtonId==="panel_about"){view=this.getButtonView(this.curButtonId);if(progress_type==="peel"){outerbar=this.getElementByTagNameAndId(view,"div","peelprogress");progbar=this.getElementByTagNameAndId(view,"div","progbar");progtext=this.getElementByTagNameAndId(view,"div","progtext");message=progress_info.message;percent=(progress_info.current_step*100)/progress_info.total_step}else{if(progress_type==="fetch"){outerbar=this.getElementByTagNameAndId(view,"div","fetchprogress");progbar=this.getElementByTagNameAndId(view,"div","progbar2");progtext=this.getElementByTagNameAndId(view,"div","progtext2");message=progress_info.last_component_url;percent=(progress_info.current*100)/progress_info.total}else{if(progress_type==="message"){progtext=this.getElementByTagNameAndId(view,"div","progtext2");if(progtext){progtext.innerHTML=progress_info}return}else{return}}}}if(outerbar&&progbar&&progtext){maxwidth=outerbar.clientWidth;if(percent<0){percent=0}if(percent>100){percent=100}percent=100-percent;width=(maxwidth*percent)/100;if(width>maxwidth){width=maxwidth}left=maxwidth-parseInt(width,10);progbar.style.width=parseInt(width,10)+"px";progbar.style.left=parseInt(left,10)+"px";progtext.innerHTML=message}},updateStatusBar:function(doc){var size,grade,result,info,url,yslow=YSLOW,util=yslow.util,view=yslow.view,pref=util.Preference,yscontext=this.yscontext;if(!yscontext.PAGE.statusbar){yscontext.PAGE.statusbar=true;if(!yscontext.PAGE.overallScore){yslow.controller.lint(doc,yscontext)}if(!yscontext.PAGE.totalSize){yscontext.collectStats()}size=util.kbSize(yscontext.PAGE.totalSize);grade=util.prettyScore(yscontext.PAGE.overallScore);view.setStatusBar(grade,"yslow_status_grade");view.setStatusBar(size,"yslow_status_size");if(pref.getPref("optinBeacon",false)){info=pref.getPref("beaconInfo","basic"),url=pref.getPref("beaconUrl","http://rtblab.pclick.yahoo.com/images/ysb.gif");result=util.getResults(yscontext,info);util.sendBeacon(result,info,url)}}},getRulesetListSource:function(rulesets){var id,custom,sHtml="",defaultRulesetId=YSLOW.controller.getDefaultRulesetId();for(id in rulesets){if(rulesets[id]){sHtml+='"}}return sHtml},updateRulesetList:function(){var i,div,new_select,selects=this.panel_doc.getElementsByTagName("select"),rulesets=YSLOW.controller.getRegisteredRuleset(),sText=this.getRulesetListSource(rulesets),onchangeFunc=function(event){var doc=FBL.getContentView(this.ownerDocument);doc.ysview.onChangeRuleset(event)};for(i=0;iRulesets ";sHtml+='
  • ';sHtml+='";sHtml+='";sHtml+="";return sHtml},show:function(sView){var format="html",stext="";sView=sView||this.yscontext.defaultview;if(this.yscontext.component_set===null){YSLOW.controller.run(window.top.content,this.yscontext,false);this.yscontext.defaultview=sView}else{if(this.getButtonView(sView)){this.showButtonView(sView)}else{if("ysCompsButton"===sView){stext+=this.yscontext.genComponents(format);this.addButtonView("ysCompsButton",stext)}else{if("ysStatsButton"===sView){stext+=this.yscontext.genStats(format);this.addButtonView("ysStatsButton",stext);YSLOW.renderer.plotComponents(this.getButtonView("ysStatsButton"),this.yscontext)}else{if("ysToolButton"===sView){stext+=this.yscontext.genToolsView(format);this.addButtonView("ysToolButton",stext)}else{stext+=this.yscontext.genPerformance(format);this.addButtonView("ysPerfButton",stext)}}}}this.panelNode.scrollTop=0;this.panelNode.scrollLeft=0;this.updateStatusBar(this.yscontext.document);this.updateToolbarSelection()}},updateToolbarSelection:function(){var elem,ul_elem,child;switch(this.curButtonId){case"ysCompsButton":case"ysPerfButton":case"ysStatsButton":case"ysToolButton":elem=this.getElementByTagNameAndId(this.panelNode,"li",this.curButtonId);if(elem){if(elem.className.indexOf("selected")!==-1){return}else{elem.className+=" selected";if(elem.previousSibling){elem.previousSibling.className+=" off"}}}break;default:break}ul_elem=this.getElementByTagNameAndId(this.panelNode,"ul","toolbarLinks");child=ul_elem.firstChild;while(child){if(child.id!==this.curButtonId&&child.className.indexOf("selected")!==-1){this.unselect(child);if(child.previousSibling){YSLOW.view.removeClassName(child.previousSibling,"off")}}child=child.nextSibling}},showPerformance:function(){this.show("ysPerfButton")},showStats:function(){this.show("ysStatsButton")},showComponents:function(){this.show("ysCompsButton")},showTools:function(){this.show("ysToolButton")},showRuleSettings:function(){var stext=this.yscontext.genRulesetEditView("html");this.addButtonView("ysRuleEditButton",stext);this.panelNode.scrollTop=0;this.panelNode.scrollLeft=0;this.updateToolbarSelection()},runTest:function(){YSLOW.controller.run(window.top.content,this.yscontext,false)},setAutorun:function(set){YSLOW.util.Preference.setPref("extensions.yslow.autorun",set)},setAntiIframe:function(set){YSLOW.antiIframe=set},addCDN:function(cdn){var i,id,that=this,doc=document,ctx=that.yscontext,pref=YSLOW.util.Preference,cdns=pref.getPref("cdnHostnames",""),panel=that.panel_doc,el=panel.getElementById("tab-label-list"),lis=el.getElementsByTagName("li"),len=lis.length;if(cdns){cdns=cdns.replace(/\s+/g,"").split(",");cdns.push(cdn);cdns=cdns.join()}else{cdns=cdn}pref.setPref("extensions.yslow.cdnHostnames",cdns);for(i=0;i-1){id=el.id;break}}YSLOW.controller.lint(ctx.document,ctx);that.addButtonView("ysPerfButton",ctx.genPerformance("html"));YSLOW.view.restoreStatusBar(ctx);that.updateToolbarSelection();el=panel.getElementById(id);that.onclickTabLabel({currentTarget:el},true)},onChangeRuleset:function(event){var doc,line1,left_button_label,left_button_func,select=YSLOW.util.getCurrentTarget(event),option=select.options[select.selectedIndex];YSLOW.controller.setDefaultRuleset(option.value);doc=select.ownerDocument;line1="Do you want to run the selected ruleset now?";left_button_label="Run Test";left_button_func=function(e){var stext;doc.ysview.closeDialog(doc);if(doc.yslowContext.component_set===null){YSLOW.controller.run(doc.yslowContext.document.defaultView||doc.yslowContext.document.parentWindow,doc.yslowContext,false)}else{YSLOW.controller.lint(doc.yslowContext.document,doc.yslowContext)}stext=doc.yslowContext.genPerformance("html");doc.ysview.addButtonView("ysPerfButton",stext);doc.ysview.panelNode.scrollTop=0;doc.ysview.panelNode.scrollLeft=0;YSLOW.view.restoreStatusBar(doc.yslowContext);doc.ysview.updateToolbarSelection()};this.openDialog(doc,389,150,line1,undefined,left_button_label,left_button_func)},onclickTabLabel:function(event,move_tab){var child,hide_tab_id,show_tab_id,hide,show,show_tab,id_substring,li_elem=YSLOW.util.getCurrentTarget(event),ul_elem=li_elem.parentNode,div_elem=ul_elem.nextSibling;if(li_elem.className.indexOf("selected")!==-1||li_elem.id.indexOf("label")===-1){return false}if(ul_elem){child=ul_elem.firstChild;while(child){if(this.unselect(child)){hide_tab_id=child.id.substring(5);break}child=child.nextSibling}li_elem.className+=" selected";show_tab_id=li_elem.id.substring(5);child=div_elem.firstChild;while(child){id_substring=child.id.substring(3);if(!hide&&hide_tab_id&&id_substring===hide_tab_id){if(child.className.indexOf("yui-hidden")===-1){child.className+=" yui-hidden"}hide=true}if(!show&&show_tab_id&&id_substring===show_tab_id){YSLOW.view.removeClassName(child,"yui-hidden");show=true;show_tab=child}if((hide||!hide_tab_id)&&(show||!show_tab_id)){break}child=child.nextSibling}if(move_tab===true&&show===true&&show_tab){this.positionResultTab(show_tab,div_elem,li_elem)}}return false},positionResultTab:function(tab,container,label){var y,parent,delta,padding=5,doc=this.panel_doc,win=doc.defaultView||doc.parentWindow,pageHeight=win.offsetHeight?win.offsetHeight:win.innerHeight,height=label.offsetTop+tab.offsetHeight;container.style.height=height+"px";tab.style.position="absolute";tab.style.left=label.offsetLeft+label.offsetWidth+"px";tab.style.top=label.offsetTop+"px";y=tab.offsetTop;parent=tab.offsetParent;while(parent!==null){y+=parent.offsetTop;parent=parent.offsetParent}if(ythis.panelNode.scrollTop+pageHeight){if(yy-this.panelNode.scrollTop){delta=y-this.panelNode.scrollTop}this.panelNode.scrollTop+=delta}}},onclickResult:function(event){YSLOW.util.preventDefault(event);return this.onclickTabLabel(event,true)},unselect:function(elem){return YSLOW.view.removeClassName(elem,"selected")},filterResult:function(doc,category){var ul_elem,showAll,child,firstTab,tab,firstChild,div_elem,view=this.getButtonView("ysPerfButton");if(category==="all"){showAll=true}if(view){ul_elem=this.getElementByTagNameAndId(view,"ul","tab-label-list")}if(ul_elem){child=ul_elem.firstChild;div_elem=ul_elem.nextSibling;tab=div_elem.firstChild;while(child){YSLOW.view.removeClassName(child,"first");if(showAll||child.className.indexOf(category)!==-1){child.style.display="block";if(firstTab===undefined){firstTab=tab;firstChild=child;YSLOW.view.removeClassName(tab,"yui-hidden");child.className+=" first";if(child.className.indexOf("selected")===-1){child.className+=" selected"}child=child.nextSibling;tab=tab.nextSibling;continue}}else{child.style.display="none"}if(tab.className.indexOf("yui-hidden")===-1){tab.className+=" yui-hidden"}this.unselect(child);child=child.nextSibling;tab=tab.nextSibling}if(firstTab){this.positionResultTab(firstTab,div_elem,firstChild)}}},updateFilterSelection:function(event){var li,elem=YSLOW.util.getCurrentTarget(event);YSLOW.util.preventDefault(event);if(elem.className.indexOf("selected")!==-1){return}elem.className+=" selected";li=elem.parentNode.firstChild;while(li){if(li!==elem&&this.unselect(li)){break}li=li.nextSibling}this.filterResult(elem.ownerDocument,elem.id)},onclickToolbarMenu:function(event){var child,a_elem=YSLOW.util.getCurrentTarget(event),li_elem=a_elem.parentNode,ul_elem=li_elem.parentNode;if(li_elem.className.indexOf("selected")!==-1){return}li_elem.className+=" selected";if(li_elem.previousSibling){li_elem.previousSibling.className+=" off"}if(ul_elem){child=ul_elem.firstChild;while(child){if(child!==li_elem&&this.unselect(child)){if(child.previousSibling){YSLOW.view.removeClassName(child.previousSibling,"off")}break}child=child.nextSibling}}},expandCollapseComponentType:function(doc,type){var table,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysCompsButton");if(view){table=this.getElementByTagNameAndId(view,"table","components-table");renderer.expandCollapseComponentType(doc,table,type)}},expandAll:function(doc){var table,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysCompsButton");if(view){table=this.getElementByTagNameAndId(view,"table","components-table");renderer.expandAllComponentType(doc,table)}},regenComponentsTable:function(doc,column_name,sortDesc){var table,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysCompsButton");if(view){table=this.getElementByTagNameAndId(view,"table","components-table");renderer.regenComponentsTable(doc,table,column_name,sortDesc,this.yscontext.component_set)}},showComponentHeaders:function(headersDivId){var elem,td,view=this.getButtonView("ysCompsButton");if(view){elem=this.getElementByTagNameAndId(view,"tr",headersDivId);if(elem){td=elem.firstChild;if(elem.style.display==="none"){elem.style.display="table-row"}else{elem.style.display="none"}}}},openLink:function(url){YSLOW.util.openLink(url)},openPopup:function(url,name,width,height,features){window.open(url,name||"_blank","width="+(width||626)+",height="+(height||436)+","+(features||"toolbar=0,status=1,location=1,resizable=1"))},runTool:function(tool_id,param){YSLOW.controller.runTool(tool_id,this.yscontext,param)},onclickRuleset:function(event){var ruleset_id,end,view,form,li_elem=YSLOW.util.getCurrentTarget(event),index=li_elem.className.indexOf("ruleset-");YSLOW.util.preventDefault(event);if(index!==-1){end=li_elem.className.indexOf(" ",index+8);if(end!==-1){ruleset_id=li_elem.className.substring(index+8,end)}else{ruleset_id=li_elem.className.substring(index+8)}view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form","edit-form");YSLOW.renderer.initRulesetEditForm(li_elem.ownerDocument,form,YSLOW.controller.getRuleset(ruleset_id))}}return this.onclickTabLabel(event,false)},openSaveAsDialog:function(doc,form_id){var line1='',left_button_label="Save",left_button_func=function(e){var textbox,line,view,form,input,doc=YSLOW.util.getCurrentTarget(e).ownerDocument;if(doc.ysview.modaldlg){textbox=doc.ysview.getElementByTagNameAndId(doc.ysview.modaldlg,"input","saveas-name")}if(textbox){if(YSLOW.controller.checkRulesetName(textbox.value)===true){line=line1+'
    '+textbox.value+" ruleset already exists.
    ";doc.ysview.closeDialog(doc);doc.ysview.openDialog(doc,389,150,line,"",left_button_label,left_button_func)}else{view=doc.ysview.getButtonView("ysRuleEditButton");if(view){form=doc.ysview.getElementByTagNameAndId(view,"form",form_id);input=doc.createElement("input");input.type="hidden";input.name="saveas-name";input.value=textbox.value;form.appendChild(input);form.submit()}doc.ysview.closeDialog(doc)}}};this.openDialog(doc,389,150,line1,undefined,left_button_label,left_button_func)},openPrintableDialog:function(doc){var line="Please run YSlow first before using Printable View.",line1="Check which information you want to view or print
    ",line2='
    ',left_button_label="Ok",left_button_func=function(e){var i,doc=YSLOW.util.getCurrentTarget(e).ownerDocument,doc=FBL.getContentView(doc);aInputs=doc.getElementsByName("print-type"),print_type={};for(i=0;i0){for(i=0;i0){if(elems[i].className==="dialog-box"){dialog=elems[i]}else{if(elems[i].className==="dialog-text"){text=elems[i]}else{if(elems[i].className==="dialog-more-text"){more_text=elems[i]}}}}}if(overlay&&dialog&&text&&more_text){text.innerHTML=(text1?text1:"");more_text.innerHTML=(text2?text2:"");inputs=overlay.getElementsByTagName("input");for(j=0;j0)?left:225)+"px";dialog.style.top=((top&&top>0)?top:80)+"px";overlay.style.left=this.panelNode.scrollLeft+"px";overlay.style.top=this.panelNode.scrollTop+"px";overlay.style.display="block";if(inputs.length>0){inputs[0].focus()}}},closeDialog:function(doc){var dialog=this.modaldlg;dialog.style.display="none"},saveRuleset:function(doc,form_id){var form,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);renderer.saveRuleset(doc,form)}},deleteRuleset:function(doc,form_id){var form,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);renderer.deleteRuleset(doc,form)}},shareRuleset:function(doc,form_id){var form,ruleset_id,ruleset,result,line1,renderer=YSLOW.controller.getRenderer("html"),view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);ruleset_id=renderer.getEditFormRulesetId(form);ruleset=YSLOW.controller.getRuleset(ruleset_id);if(ruleset){result=YSLOW.Exporter.exportRuleset(ruleset);if(result){line1="";this.openDialog(doc,389,150,line1,"","Ok")}}}},createRuleset:function(button,form_id){var view,form,li_elem=button.parentNode,ul_elem=li_elem.parentNode,child=ul_elem.firstChild;while(child){this.unselect(child);child=child.nextSibling}view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);YSLOW.renderer.initRulesetEditForm(this.panel_doc,form)}},showHideHelp:function(){var help,toolbar=this.getElementByTagNameAndId(this.panelNode,"div","toolbarDiv");if(toolbar){help=this.getElementByTagNameAndId(toolbar,"div","helpDiv")}if(help){if(help.style.visibility==="visible"){help.style.visibility="hidden"}else{help.style.visibility="visible"}}},smushIt:function(doc,url){YSLOW.util.smushIt(url,function(resp){var line1,line2,smushurl,dest_url,txt="";if(resp.error){txt+="
    "+resp.error+"
    "}else{smushurl=YSLOW.util.getSmushUrl();dest_url=YSLOW.util.makeAbsoluteUrl(resp.dest,smushurl);txt+="
    Original size: "+resp.src_size+" bytes
    Result size: "+resp.dest_size+" bytes
    % Savings: "+resp.percent+"%
    "}line1='
    Image: '+YSLOW.util.briefUrl(url,250)+"
    ";line2=txt;doc.ysview.openDialog(doc,389,150,line1,line2,"Ok")})},checkAllRules:function(doc,form_id,check){var i,view,form,aElements;if(typeof check!=="boolean"){return}view=this.getButtonView("ysRuleEditButton");if(view){form=this.getElementByTagNameAndId(view,"form",form_id);aElements=form.elements;for(i=0;ipageWidth||tooltipHeight>pageHeight){this.tooltip.style.display="none";return}parent=target.offsetParent;while(parent!==null){x+=parent.offsetLeft;y+=parent.offsetTop;parent=parent.offsetParent}x+=target.offsetLeft;y+=target.offsetTop;if(xdoc.ysview.panelNode.scrollTop+pageHeight)){this.tooltip.style.display="none";return}midpt_x=x+target.offsetWidth/2;midpt_y=y+target.offsetHeight/2;if(x+target.offsetWidth+padding+tooltipWidth=doc.ysview.panelNode.scrollTop)&&(y-padding+tooltipHeight+padding<=doc.ysview.panelNode.scrollTop+pageHeight)){y=y-padding;sClass="right top"}else{y+=target.offsetHeight-tooltipHeight;sClass="right bottom"}}else{if(y-tooltipHeight-padding>=doc.ysview.panelNode.scrollTop){y-=tooltipHeight+padding;sClass="top"}else{y+=target.offsetHeight+padding;sClass="bottom"}new_x=Math.floor(midpt_x-tooltipWidth/2);if((new_x>=doc.ysview.panelNode.scrollLeft)&&(new_x+tooltipWidth<=doc.ysview.panelNode.scrollLeft+pageWidth)){x=new_x}else{if(new_x0&&name&&name.length>0){names=element.className.split(" ");for(i=0;i0){canvas_data[sType]=hSize[sType]}totalSize+=hSize[sType]}}return{total_size:totalSize,num_requests:nHttpRequests,count_obj:hCount,size_obj:hSize,canvas_data:canvas_data}},collectStats:function(){var stats=this.computeStats();if(stats!==undefined){this.PAGE.totalSize=stats.total_size;this.PAGE.totalRequests=stats.num_requests;this.PAGE.totalObjCount=stats.count_obj;this.PAGE.totalObjSize=stats.size_obj;this.PAGE.canvas_data.empty=stats.canvas_data}stats=this.computeStats(true);if(stats){this.PAGE.totalSizePrimed=stats.total_size;this.PAGE.totalRequestsPrimed=stats.num_requests;this.PAGE.totalObjCountPrimed=stats.count_obj;this.PAGE.totalObjSizePrimed=stats.size_obj;this.PAGE.canvas_data.primed=stats.canvas_data}},genPerformance:function(output_format,doc){if(this.result_set===null){if(!doc){doc=this.document}YSLOW.controller.lint(doc,this)}return YSLOW.controller.render(output_format,"reportcard",{result_set:this.result_set})},genStats:function(output_format){var stats={};if(!this.PAGE.totalSize){this.collectStats()}stats.PAGE=this.PAGE;return YSLOW.controller.render(output_format,"stats",{stats:stats})},genComponents:function(output_format){if(!this.PAGE.totalSize){this.collectStats()}return YSLOW.controller.render(output_format,"components",{comps:this.component_set.components,total_size:this.PAGE.totalSize})},genToolsView:function(output_format){var tools=YSLOW.Tools.getAllTools();return YSLOW.controller.render(output_format,"tools",{tools:tools})},genRulesetEditView:function(output_format){return YSLOW.controller.render(output_format,"rulesetEdit",{rulesets:YSLOW.controller.getRegisteredRuleset()})}};YSLOW.renderer={sortBy:"type",sortDesc:false,bPrintable:false,colors:{doc:"#8963df",redirect:"#FC8C8C",iframe:"#FFDFDF",xhr:"#89631f",flash:"#8D4F5B",js:"#9fd0e8",css:"#aba5eb",cssimage:"#677ab8",image:"#d375cd",favicon:"#a26c00",unknown:"#888888"},reset:function(){this.sortBy="type";this.sortDesc=false},genStats:function(stats,bCacheFull){var hCount,hSize,nHttpRequests,aTypes,cache_type,i,sType,sText,tableHtml="",totalSize=0;if(!stats.PAGE){return""}if(bCacheFull){hCount=stats.PAGE.totalObjCountPrimed;hSize=stats.PAGE.totalObjSizePrimed;nHttpRequests=stats.PAGE.totalRequestsPrimed;totalSize=stats.PAGE.totalSizePrimed}else{hCount=stats.PAGE.totalObjCount;hSize=stats.PAGE.totalObjSize;nHttpRequests=stats.PAGE.totalRequests;totalSize=stats.PAGE.totalSize}aTypes=YSLOW.peeler.types;cache_type=(bCacheFull)?"primed":"empty";for(i=0;i
     
    '+hCount[sType]+''+YSLOW.util.prettyType(sType)+''+YSLOW.util.kbSize(hSize[sType])+""}}sText='
    HTTP Requests - '+nHttpRequests+'
    Total Weight - '+YSLOW.util.kbSize(totalSize)+'
    '+tableHtml+"
    ";return sText},plotComponents:function(stats_view,yscontext){if(typeof stats_view!=="object"){return}this.plotOne(stats_view,yscontext.PAGE.canvas_data.empty,yscontext.PAGE.totalSize,"comp-canvas-empty");this.plotOne(stats_view,yscontext.PAGE.canvas_data.primed,yscontext.PAGE.totalSizePrimed,"comp-canvas-primed")},plotOne:function(stats_view,data,total,canvas_id){var canvas,i,ctx,canvas_size,radius,center,sofar,piece,thisvalue,aElements=stats_view.getElementsByTagName("canvas");for(i=0;i'+YSLOW.util.escapeHtml(comp.headers[field])+""}}if(comp.req_headers){sText+='Request Headers';for(field in comp.req_headers){if(comp.req_headers.hasOwnProperty(field)&&comp.req_headers[field]){sText+=''+YSLOW.util.escapeHtml(YSLOW.util.formatHeaderName(field))+'

    '+YSLOW.util.escapeHtml(comp.req_headers[field])+"

    "}}}sText+="";return sText},genComponentRow:function(fields,comp,row_class,hidden){var headersDivId,sHtml,i,sClass,value,sent,recv;if(typeof row_class!=="string"){row_class=""}if(comp.status>=400&&comp.status<500){row_class+=" compError"}if(comp.after_onload===true){row_class+=" afteronload"}headersDivId="compHeaders"+comp.id;sHtml='";for(i in fields){if(fields.hasOwnProperty(i)){sClass=i;value="";if(i==="type"){value+=comp[i];if(comp.is_beacon){value+=" †"}if(comp.after_onload){value+=" *"}}else{if(i==="size"){value+=YSLOW.util.kbSize(comp.size)}else{if(i==="url"){if(comp.status>=400&&comp.status<500){sHtml+=''+comp[i]+" (status: "+comp.status+")";continue}else{value+=YSLOW.util.prettyAnchor(comp[i],comp[i],undefined,!YSLOW.renderer.bPrintable,100,1,comp.type)}}else{if(i==="gzip"&&(comp.compressed==="gzip"||comp.compressed==="deflate")){value+=(comp.size_compressed!==undefined?YSLOW.util.kbSize(comp.size_compressed):"uncertain")}else{if(i==="set-cookie"){sent=comp.getSetCookieSize();value+=sent>0?sent:""}else{if(i==="cookie"){recv=comp.getReceivedCookieSize();value+=recv>0?recv:""}else{if(i==="etag"){value+=comp.getEtag()}else{if(i==="expires"){value+=YSLOW.util.prettyExpiresDate(comp.expires)}else{if(i==="headers"){if(YSLOW.renderer.bPrintable){continue}if(comp.raw_headers&&comp.raw_headers.length>0){value+="'}}else{if(i==="action"){if(YSLOW.renderer.bPrintable){continue}if(comp.type==="cssimage"||comp.type==="image"){if(comp.response_type===undefined||comp.response_type==="image"){value+="smush.it"}}}else{if(comp[i]!==undefined){value+=comp[i]}}}}}}}}}}}sHtml+=''+value+""}}sHtml+="";if(comp.raw_headers&&comp.raw_headers.length>0){sHtml+=''+this.getComponentHeadersTable(comp)+""}return sHtml},componentSortCallback:function(comp1,comp2){var i,types,max,a="",b="",sortBy=YSLOW.renderer.sortBy,desc=YSLOW.renderer.sortDesc;switch(sortBy){case"type":a=comp1.type;b=comp2.type;break;case"size":a=comp1.size?Number(comp1.size):0;b=comp2.size?Number(comp2.size):0;break;case"gzip":a=comp1.size_compressed?Number(comp1.size_compressed):0;b=comp2.size_compressed?Number(comp2.size_compressed):0;break;case"set-cookie":a=comp1.getSetCookieSize();b=comp2.getSetCookieSize();break;case"cookie":a=comp1.getReceivedCookieSize();b=comp2.getReceivedCookieSize();break;case"headers":break;case"url":a=comp1.url;b=comp2.url;break;case"respTime":a=comp1.respTime?Number(comp1.respTime):0;b=comp2.respTime?Number(comp2.respTime):0;break;case"etag":a=comp1.getEtag();b=comp2.getEtag();break;case"action":if(comp1.type==="cssimage"||comp1.type==="image"){a="smush.it"}if(comp2.type==="cssimage"||comp2.type==="image"){b="smush.it"}break;case"expires":a=comp1.expires||0;b=comp2.expires||0;break}if(a===b){if(comp1.id>comp2.id){return(desc)?-1:1}if(comp1.idb){return(desc)?-1:1}if(a',col2Text='
    ',col3Text='
    ';for(id in rules){if(rules.hasOwnProperty(id)&&rules[id]){rule=rules[id];sText='
    ";if(ruleset.rules[id]!==undefined){numRules+=1}if(ruleset.weights!==undefined&&ruleset.weights[id]!==undefined){weightsText+=''}column_id=(j%3);switch(column_id){case 0:col1Text+=sText;break;case 1:col2Text+=sText;break;case 2:col3Text+=sText;break}j+=1}}col1Text+="
    ";col2Text+="
    ";col3Text+="";return'

    '+ruleset.name+' Ruleset (includes '+parseInt(numRules,10)+" of "+parseInt(j,10)+' rules)

    '+col1Text+""+col2Text+""+col3Text+'
    '+weightsText+"
    "},genRulesetEditForm:function(ruleset){var contentHtml="";contentHtml+='
    '+YSLOW.renderer.genRulesCheckbox(ruleset)+'
    ';return contentHtml},initRulesetEditForm:function(doc,form,ruleset){var divs,i,j,id,buttons,rulesetId,rulesetName,title,weightsDiv,rules,numRulesSpan,spans,checkbox,aElements=form.elements,weightsText="",checkboxes=[],numRules=0,totalRules=0;for(i=0;i'}numRules+=1}}numRulesSpan.innerHTML="(includes "+parseInt(numRules,10)+" of "+parseInt(totalRules,10)+" rules)";rulesetId.innerHTML='';rulesetName.innerHTML='';title.innerHTML=ruleset.name}else{rulesetId.innerHTML="";rulesetName.innerHTML="";title.innerHTML="New";numRulesSpan.innerHTML=""}weightsDiv.innerHTML=weightsText}};YSLOW.registerRenderer({id:"html",supports:{components:1,reportcard:1,stats:1,tools:1,rulesetEdit:1},genComponentsTable:function(comps,sortBy,sortDesc){var f,j,type,comp,headers={type:"TYPE",size:"SIZE
    (KB)",gzip:"GZIP
    (KB)","set-cookie":"COOKIE RECEIVED
    (bytes)",cookie:"COOKIE SENT
    (bytes)",headers:"HEADERS",url:"URL",expires:"EXPIRES
    (Y/M/D)",respTime:"RESPONSE
    TIME (ms)",etag:"ETAG",action:"ACTION"},collapsed=false,tableHtml="",rowHtml="",numComponentsByType=0,sizeByType=0;if(sortBy!==undefined&&headers[sortBy]===undefined){return""}if(YSLOW.renderer.bPrintable){sortBy=YSLOW.renderer.sortBy;sortDesc=YSLOW.renderer.sortDesc}else{if(sortBy===undefined||sortBy==="type"){sortBy="type";collapsed=true}}comps=YSLOW.renderer.sortComponents(comps,sortBy,sortDesc);tableHtml+='';for(f in headers){if(headers.hasOwnProperty(f)&&headers[f]){if(YSLOW.renderer.bPrintable&&(f==="action"||f==="components"||f==="headers")){continue}tableHtml+="'+(sortBy===f?(sortDesc?"↓":"↑"):"")+" "+headers[f]+""}}}tableHtml+="";for(j=0;j";tableHtml+=rowHtml;rowHtml="";numComponentsByType=0;sizeByType=0;type=comp.type}}rowHtml+=YSLOW.renderer.genComponentRow(headers,comp,(numComponentsByType%2===0?"even":"odd"),collapsed);numComponentsByType+=1;sizeByType+=comp.size}else{tableHtml+=YSLOW.renderer.genComponentRow(headers,comp,(j%2===0?"even":"odd"),false)}}if(rowHtml.length>0){tableHtml+='";tableHtml+=rowHtml}tableHtml+="
    '+type+" ("+numComponentsByType+')'+YSLOW.util.kbSize(sizeByType)+"
    '+type+" ("+numComponentsByType+')'+YSLOW.util.kbSize(sizeByType)+"
    ";return tableHtml},componentsView:function(comps,totalSize){var sText,tableHtml=this.genComponentsTable(comps,YSLOW.renderer.sortBy,false),beacon_legend="in type column indicates the component is loaded after window onload event.",after_onload_legend="denotes 1x1 pixels image that may be image beacon",title="Components";if(YSLOW.doc){if(YSLOW.doc.components_legend){if(YSLOW.doc.components_legend.beacon){beacon_legend=YSLOW.doc.components_legend.beacon}if(YSLOW.doc.components_legend.after_onload){after_onload_legend=YSLOW.doc.components_legend.after_onload}}if(YSLOW.doc.view_names&&YSLOW.doc.view_names.components){title=YSLOW.doc.view_names.components}}sText='
    '+title+'The page has a total of '+comps.length+' components and a total weight of '+YSLOW.util.kbSize(totalSize)+' bytes
    '+tableHtml+'
    * '+beacon_legend+"
    † "+after_onload_legend+"
    ";return sText},reportcardPrintableView:function(results,overall_grade,ruleset){var i,j,result,grade,grade_class,html='
    ";for(i=0;i"}}html+="
    Overall Grade: '+overall_grade+" (Ruleset applied: "+ruleset.name+")
    '+grade+'

    '+result.name+'

    '+result.message+"
    ";if(result.components&&result.components.length>0){html+='
      ';for(j=0;j"+result.components[j]+""}else{if(result.components[j].url!==undefined){html+="
    • "+YSLOW.util.briefUrl(result.components[j].url,60)+"
    • "}}}html+="

    "}html+="

    ";return html},getFilterCode:function(categories,results,grade,url){var html,id,i,len,link,result,score,total=results.length,array=[];for(id in categories){if(categories.hasOwnProperty(id)&&categories[id]){array.push(id)}}array.sort();html='
    • ALL ('+total+')
    • FILTER BY:
    • ';for(i=0,len=array.length;i'+array[i].toUpperCase()+" ("+categories[array[i]]+")"}link="http://yslow.org/scoremeter/?url="+encodeURIComponent(url)+"&grade="+grade;for(i=0;i=0&&score<100){link+="&"+result.rule_id.toLowerCase()+"="+score}}link=encodeURIComponent(encodeURIComponent(link));url=encodeURIComponent(encodeURIComponent(url.slice(0,60)+(url.length>60?"...":"")));html+='";html+='";html+="
    ";return html},reportcardView:function(resultset){var overall_grade,i,j,k,result,grade,index,sClass,grade_class,score,messages,comp,string,rule,html='
    ',appliedRuleset=resultset.getRulesetApplied(),results=resultset.getResults(),url=resultset.url,title="Grade",tab_label_html="",tab_html="",categories={};if(YSLOW.doc){if(YSLOW.doc.view_names&&YSLOW.doc.view_names.grade){title=YSLOW.doc.view_names.grade}}overall_grade=YSLOW.util.prettyScore(resultset.getOverallScore());if(YSLOW.renderer.bPrintable){return this.reportcardPrintableView(results,overall_grade,appliedRuleset)}html+='
    '+title+'
    '+overall_grade+'
    Overall performance score '+Math.round(resultset.getOverallScore())+'Ruleset applied: '+appliedRuleset.name+'URL: '+YSLOW.util.briefUrl(url,100)+"
    ";for(i=0;i0){sClass+=" "}sClass+=result.category[k];if(categories[result.category[k]]===undefined){categories[result.category[k]]=0}categories[result.category[k]]+=1}}if(sClass.length>0){tab_label_html+=' class="'+sClass+'"'}tab_label_html+=' onclick="javascript:document.ysview.onclickResult(event)">
    '+grade+''+result.name+"
    ";tab_html+='
    ")}tab_html+='">

    Grade '+grade+" on "+result.name+"

    "+result.message+"
    ";if(result.components&&result.components.length>0){tab_html+='

      ';for(j=0;j"+comp+""}else{if(comp.url!==undefined){tab_html+="
    • ";string=result.rule_id.toLowerCase();if(result.rule_id.match("expires")){tab_html+="("+YSLOW.util.prettyExpiresDate(comp.expires)+") "}tab_html+=YSLOW.util.prettyAnchor(comp.url,comp.url,undefined,true,120,undefined,comp.type)+"
    • "}}}tab_html+="

    "}tab_html+="

    ";rule=YSLOW.controller.getRule(result.rule_id);if(rule){tab_html+='

    '+(rule.info||"** To be added **")+"

    ";if(rule.url!==undefined){tab_html+='

    »Read More

    "}}tab_html+="
    "}}html+='
    '+this.getFilterCode(categories,results,overall_grade,url)+'
      '+tab_label_html+'
    '+tab_html+'
    '+YSLOW.doc.copyright+"
    ";return html},statsView:function(stats){var sText="",title="Stats";if(YSLOW.doc){if(YSLOW.doc.view_names&&YSLOW.doc.view_names.stats){title=YSLOW.doc.view_names.stats}}sText+='
    '+title+'The page has a total of '+stats.PAGE.totalRequests+' HTTP requests and a total weight of '+YSLOW.util.kbSize(stats.PAGE.totalSize)+" bytes with empty cache
    ";sText+='
    WEIGHT GRAPHS
    ';sText+='
    Empty Cache
    '+YSLOW.renderer.genStats(stats,false)+"
    ";sText+='
    Primed Cache
    '+YSLOW.renderer.genStats(stats,true)+"
    ";sText+="
    ";return sText},toolsView:function(tools){var i,sText,tool,tableHtml="",title="Tools",desc="Click the Launch Tool link next to the tool you want to run to start the tool.";if(YSLOW.doc){if(YSLOW.doc.tools_desc){desc=YSLOW.doc.tools_desc}if(YSLOW.doc.view_names&&YSLOW.doc.view_names.tools){title=YSLOW.doc.view_names.tools}}for(i=0;i"}tableHtml+="
    "+tool.name+"-"+(tool.short_desc||"Short text here explaining what are the main benefits of running this App")+"
    ";sText='
    '+title+""+desc+'
    '+tableHtml+"
    ";return sText},rulesetEditView:function(rulesets){var id,ruleset,tab_id,sText,settingsHtml='
    ',navHtml,contentHtml,index=0,custom=false,selectedRuleset,defaultRulesetId,title="Rule Settings",desc="Choose which ruleset better fit your specific needs. You can Save As an existing rule, based on an existing ruleset.";if(YSLOW.doc){if(YSLOW.doc.rulesettings_desc){desc=YSLOW.doc.rulesettings_desc}if(YSLOW.doc.view_names&&YSLOW.doc.view_names.rulesetedit){title=YSLOW.doc.view_names.rulesetedit}}defaultRulesetId=YSLOW.controller.getDefaultRulesetId();navHtml='
    • STANDARD SETS
    • ';for(id in rulesets){if(rulesets.hasOwnProperty(id)&&rulesets[id]){ruleset=rulesets[id];tab_id="tab"+index;if(!custom&&ruleset.custom===true){navHtml+='
    • CUSTOM SETS
    • ';custom=true}navHtml+='
    • '+ruleset.name+"
    • ";index+=1}}navHtml+='
    ';contentHtml='
    '+YSLOW.renderer.genRulesetEditForm(selectedRuleset)+"
    ";settingsHtml+=navHtml+contentHtml;sText='
    '+title+""+desc+"
    "+settingsHtml+"
    ";return sText},rulesetEditUpdateTab:function(doc,form,ruleset,updateAction,updateSelection){var ul_elem,content,li_elem,index,id,tab_id,event,custom_set_title,label_id,idx,prev_li_elem,header,event2,container=form.parentNode.parentNode.parentNode;if(container&&container.id==="settingsDiv"&&ruleset.custom===true){ul_elem=container.firstChild;content=ul_elem.nextSibling;if(updateAction<1){li_elem=ul_elem.firstChild;while(li_elem){index=li_elem.className.indexOf("ruleset-");if(index!==-1){id=li_elem.className.substring(index+8);index=id.indexOf(" ");if(index!==-1){id=id.substring(0,index)}if(ruleset.id===id){index=li_elem.id.indexOf("label");if(index!==-1){tab_id=li_elem.id.substring(index+5);if(li_elem.className.indexOf("selected")!==-1){event={};event.currentTarget=prev_li_elem;doc.ysview.onclickRuleset(event)}if(li_elem.previousSibling&&li_elem.previousSibling.id==="custom-set-title"&&li_elem.nextSibling&&li_elem.nextSibling.id==="create-ruleset"){custom_set_title=li_elem.previousSibling}ul_elem.removeChild(li_elem);if(custom_set_title){ul_elem.removeChild(custom_set_title)}}break}else{prev_li_elem=li_elem}}li_elem=li_elem.nextSibling}}else{li_elem=ul_elem.lastChild;while(li_elem){idx=li_elem.id.indexOf("label");if(idx!==-1){label_id=li_elem.id.substring(idx+5);break}li_elem=li_elem.previousSibling}label_id=Number(label_id)+1;li_elem=doc.createElement("li");li_elem.className="ruleset-"+ruleset.id;li_elem.id="label"+label_id;li_elem.onclick=function(event){doc.ysview.onclickRuleset(event)};li_elem.innerHTML=''+ruleset.name+"";ul_elem.insertBefore(li_elem,ul_elem.lastChild);header=ul_elem.firstChild;while(header){if(header.id&&header.id==="custom-set-title"){custom_set_title=header;break}header=header.nextSibling}if(!custom_set_title){custom_set_title=doc.createElement("li");custom_set_title.className="new-section header";custom_set_title.id="custom-set-title";custom_set_title.innerHTML="CUSTOM SETS";ul_elem.insertBefore(custom_set_title,li_elem)}if(updateSelection){event2={};event2.currentTarget=li_elem;doc.ysview.onclickRuleset(event2)}}}},hasClassName:function(class_name,name){var i,arr_class=class_name.split(" ");if(arr_class){for(i=0;i";sText+=""+comps[i].type+"";sText+=""+comps[i].size+"";if(comps[i].compressed===false){sText+=""}else{sText+=""+(comps[i].size_compressed!==undefined?parseInt(comps[i].size_compressed,10):"uncertain")+""}cookieSize=comps[i].getSetCookieSize();if(cookieSize>0){sText+=""+parseInt(cookieSize,10)+""}cookieSize=comps[i].getReceivedCookieSize();if(cookieSize>0){sText+=""+parseInt(cookieSize,10)+""}sText+=""+encodeURI(comps[i].url)+"";sText+=""+comps[i].expires+"";sText+=""+comps[i].respTime+"";sText+=""+comps[i].getEtag()+"";sText+=""}sText+="";return sText},reportcardView:function(resultset){var i,j,result,overall_score=resultset.getOverallScore(),overall_grade=YSLOW.util.prettyScore(overall_score),appliedRuleset=resultset.getRulesetApplied(),results=resultset.getResults(),sText='';sText+='';for(i=0;i';sText+=""+result.message+"";if(results.components&&results.components.length>0){sText+="";for(j=0;j"+result.components[j]+""}else{if(result.components[j].url!==undefined){sText+=""+result.components[j].url+""}}}sText+=""}sText+=""}sText+="";return sText},statsView:function(stats){var i,sType,sText,primed_cache_items='',empty_cache_items='',aTypes=YSLOW.peeler.types;for(i=0;i'}if((stats.PAGE.totalObjCount[sType])!==undefined){empty_cache_items+=''}}primed_cache_items+="";empty_cache_items+="";sText=''+primed_cache_items+empty_cache_items+"";return sText}});YSLOW.peeler={types:["doc","js","css","iframe","flash","cssimage","image","favicon","xhr","redirect","font"],NODETYPE:{ELEMENT:1,DOCUMENT:9},CSSRULE:{IMPORT_RULE:3,FONT_FACE_RULE:5},peel:function(node,onloadTimestamp){},findDocuments:function(node){var frames,doc,docUrl,type,i,len,el,frameDocs,parentDoc,allDocs={};YSLOW.util.event.fire("peelProgress",{total_step:7,current_step:1,message:"Finding documents"});if(!node){return}if(!YSLOW.util.Preference.getPref("extensions.yslow.getFramesComponents",true)){allDocs[node.URL]={document:node,type:"doc"};return allDocs}type="doc";if(node.nodeType===this.NODETYPE.DOCUMENT){doc=node;docUrl=node.URL}else{if(node.nodeType===this.NODETYPE.ELEMENT&&node.nodeName.toLowerCase()==="frame"){doc=node.contentDocument;docUrl=node.src}else{if(node.nodeType===this.NODETYPE.ELEMENT&&node.nodeName.toLowerCase()==="iframe"){doc=node.contentDocument;docUrl=node.src;type="iframe";try{parentDoc=node.contentWindow;parentDoc=parentDoc&&parentDoc.parent;parentDoc=parentDoc&&parentDoc.document;parentDoc=parentDoc||node.ownerDocument;if(parentDoc&&parentDoc.URL===docUrl){docUrl=!node.getAttribute("src")?"":"about:blank"}}catch(err){YSLOW.util.dump(err)}}else{return allDocs}}}allDocs[docUrl]={document:doc,type:type};try{frames=doc.getElementsByTagName("iframe");for(i=0,len=frames.length;i0){for(j=0;j0){for(j=0;j $mostDomains) + #set ($mostDomains=$entry.getValue() ) + #end + #end + + $statsMaxRequestsPerDomain.addValue($mostDomains) #if($hosts.size()>0) $statsDomains.addValue($hosts.size()) #end + #if($totalImagePageSize>0) $statsTotalImageWeight.addValue($totalImagePageSize) #end