Advertisement
Guest User

pageresources2

a guest
Jan 17th, 2011
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var GR = GR || {};
  2. GR.ignoreProtocols = ['data:', 'chrome:', 'javascript:', 'about:', 'resource:', 'jar:'];
  3.  
  4. GR.Ajax = {
  5.             requests: [],
  6.             transport: null,
  7.             states: ["Uninitialized", "Loading", "Loaded", "Interactive", "Complete"],
  8.             initialize: function () {
  9.                 this.transport = this.getXHRObject()
  10.             },
  11.             getXHRObject: function () {
  12.                 var xhrObj = false;
  13.                 try {
  14.                     xhrObj = new XMLHttpRequest()
  15.                 } catch (e) {
  16.                     var progid = ["MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
  17.                     for (var i = 0;
  18.                     i < progid.length; ++i) {
  19.                         try {
  20.                             xhrObj = new ActiveXObject(progid[i])
  21.                         } catch (e) {
  22.                             continue
  23.                         }
  24.                         break
  25.                     }
  26.                 } finally {
  27.                     return xhrObj
  28.                 }
  29.             },
  30.             request: function (options) {
  31.                 var o = options || {};
  32.                 o.type = o.type && o.type.toLowerCase() || "get";
  33.                 o.async = o.async || true;
  34.                 o.dataType = o.dataType || "text";
  35.                 o.contentType = o.contentType || "application/x-www-form-urlencoded";
  36.                 this.requests.push(o);
  37.                 var s = this.getState();
  38.                 if (s == "Uninitialized" || s == "Complete" || s == "Loaded") {
  39.                     this.sendRequest()
  40.                 }
  41.             },
  42.             serialize: function (data) {
  43.                 var r = [""],
  44.                     rl = 0;
  45.                 if (data) {
  46.                     if (typeof data == "string") {
  47.                         r[rl++] = data
  48.                     } else {
  49.                         if (data.innerHTML && data.elements) {
  50.                             for (var i = 0, el, l = (el = data.elements).length;
  51.                             i < l;
  52.                             i++) {
  53.                                 if (el[i].name) {
  54.                                     r[rl++] = encodeURIComponent(el[i].name);
  55.                                     r[rl++] = "=";
  56.                                     r[rl++] = encodeURIComponent(el[i].value);
  57.                                     r[rl++] = "&"
  58.                                 }
  59.                             }
  60.                         } else {
  61.                             for (var param in data) {
  62.                                 r[rl++] = encodeURIComponent(param);
  63.                                 r[rl++] = "=";
  64.                                 r[rl++] = encodeURIComponent(data[param]);
  65.                                 r[rl++] = "&"
  66.                             }
  67.                         }
  68.                     }
  69.                 }
  70.                 return r.join("").replace(/&$/, "")
  71.             },
  72.             sendRequest: function () {
  73.                 var t = GR.Ajax.transport,
  74.                     r = GR.Ajax.requests.shift(),
  75.                     data;
  76.                 t.open(r.type, r.url, r.async);
  77.                 t.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  78.                 if (data = GR.Ajax.serialize(r.data)) {
  79.                     t.setRequestHeader("Content-Type", r.contentType)
  80.                 }
  81.                 t.onreadystatechange = function () {
  82.                     GR.Ajax.onStateChange(r)
  83.                 };
  84.                 t.send(data)
  85.             },
  86.             onStateChange: function (options) {
  87.                 var fn, o = options,
  88.                     t = this.transport;
  89.                 var state = this.getState(t);
  90.                 if (fn = o["on" + state]) {
  91.                     fn(this.getResponse(o), o)
  92.                 }
  93.                 if (state == "Complete") {
  94.                     var success = t.status == 200,
  95.                         response = this.getResponse(o);
  96.                     if (fn = o.onUpdate) {
  97.                         fn(response, o)
  98.                     }
  99.                     if (fn = o["on" + (success ? "Success" : "Failure")]) {
  100.                         fn(response, o)
  101.                     }
  102.                     //t.onreadystatechange = GR.emptyFn;
  103.                     if (this.requests.length > 0) {
  104.                         setTimeout(this.sendRequest, 10)
  105.                     }
  106.                 }
  107.             },
  108.             getResponse: function (options) {
  109.                 var t = this.transport,
  110.                     type = options.dataType;
  111.                 if (t.status != 200) {
  112.                     return t.statusText
  113.                 } else {
  114.                     if (type == "text") {
  115.                         return t.responseText
  116.                     } else {
  117.                         if (type == "html") {
  118.                             return t.responseText
  119.                         } else {
  120.                             if (type == "xml") {
  121.                                 return t.responseXML
  122.                             } else {
  123.                                 if (type == "json") {
  124.                                     return eval("(" + t.responseText + ")")
  125.                                 }
  126.                             }
  127.                         }
  128.                     }
  129.                 }
  130.             },
  131.             getState: function () {
  132.                 return this.states[this.transport.readyState]
  133.             }
  134.         };
  135.  
  136.  
  137. GR.findHtml = function(win, docs) {
  138.     docs = docs || [];
  139.  
  140.     if ( win ) {
  141.         var frames = win.frames;
  142.         try {
  143.             if ( win.document ) {
  144.                 if ( GR.isValidProtocol(win.document.location.href) ) {
  145.                     GR.addResource("html", win.document.location.href);
  146.                     docs[docs.length] = win.document;
  147.                 }
  148.             }
  149.  
  150.             // recurse into this iframe and find sub-iframes (if any)
  151.             for ( var i = 0, len = frames.length; i < len; i++ ) {
  152.                 GR.findHtml(frames[i], docs);
  153.             }
  154.         }
  155.         catch(err) {
  156.             GR.dprint("findHtml: Caught error accessing window document. Error: " + err.description);
  157.         }
  158.     }
  159.  
  160.     return docs;
  161. };
  162.  
  163.  
  164. GR.findScripts = function(doc) {
  165.     var aElems = doc.getElementsByTagName("script");
  166.     for ( var i = 0, len = aElems.length; i < len; i++ ) {
  167.         var elem = aElems[i];
  168.         if ( "string" === typeof(elem["src"]) && elem["src"].length && GR.isValidProtocol(elem["src"]) ) {
  169.             if ( -1 === elem["src"].indexOf("mobileperf/") ) {
  170.                 GR.addResource("js", elem["src"], elem);
  171.             }
  172.         }
  173.     }
  174. };
  175.  
  176.  
  177. GR.findStylesheets = function(doc) {
  178.     var aElems = doc.styleSheets;
  179.     for ( var i = 0, len = aElems.length; i < len; i++ ) {
  180.         var elem = aElems[i];
  181.         if ( "string" === typeof(elem["href"]) && elem["href"].length && GR.isValidProtocol(elem["href"]) ) {
  182.             if ( elem["href"] != doc.location ) {
  183.                 // In FF *all* the stylesheets have an HREF field. It's set to the document.location.
  184.                 GR.addResource("css", elem["href"], elem);
  185.                
  186.                
  187.             }
  188.             // If it IS an imported styled sheet we'll add the component inside this function.
  189.             GR.findImportedStyleSheets(elem);
  190.         }
  191.  
  192.         // IE
  193.         if ( "object" === typeof(elem["imports"]) ) {
  194.             var aImports = elem["imports"];
  195.             for ( var j = 0, lenImports = aImports.length; j < lenImports; j++ ) {
  196.                 var elemImport = aImports[j];
  197.                 if ( "string" === typeof(elemImport["href"]) && elemImport["href"].length && GR.isValidProtocol(elemImport["href"]) ) {
  198.                     GR.addResource("css", elemImport["href"], elem);
  199.                 }
  200.             }
  201.         }
  202.     }
  203. };
  204.  
  205.  
  206. GR.findImportedStyleSheets = function(styleSheet) {
  207.     try {
  208.         if ( "object" === typeof(styleSheet["cssRules"]) ) {
  209.             for (var irule in styleSheet["cssRules"]) {
  210.                 if ( "length" === irule ) {
  211.                     continue;
  212.                 }
  213.                 var rule = styleSheet["cssRules"][irule];
  214.                 if ( "object" == typeof(rule["styleSheet"]) &&
  215.                      "string" == typeof(rule["styleSheet"]["href"]) &&
  216.                      rule["styleSheet"]["href"].length &&
  217.                      GR.isValidProtocol(rule["styleSheet"]["href"]) ) {
  218.                     var impStyleSheet = rule["styleSheet"];
  219.                     // It IS an imported stylesheet!
  220.                     GR.addResource("css", impStyleSheet["href"]);
  221.                     // Recursively check if this stylesheet itself imports any other stylesheets.
  222.                     GR.findImportedStyleSheets(impStyleSheet);
  223.                 }
  224.                 else {
  225.                     break;
  226.                 }
  227.             }
  228.         }
  229.     }
  230.     catch(err) {
  231.         GR.dprint("findImportedStyleSheets: Caught error finding imported stylesheets. Error: " + err.description);
  232.     }
  233. };
  234.  
  235.  
  236. GR.findImages = function(doc) {
  237.     var aElems = doc.images;
  238.     var hFound = {};
  239.     for ( var i = 0, len = aElems.length; i < len; i++ ) {
  240.         var elem = aElems[i];
  241.         if ( "string" === typeof(elem["src"]) && elem["src"].length && GR.isValidProtocol(elem["src"]) ) {
  242.             var src = elem["src"];
  243.             if ( "undefined" === typeof(hFound[src]) ) {
  244.                 hFound[src] = 1;
  245.                 GR.addResource("image", src, elem);
  246.             }
  247.         }
  248.     }
  249. };
  250.  
  251.  
  252. GR.findBgImages = function(doc) {
  253.     var elems = doc.getElementsByTagName('*');
  254.     var nElems = elems.length;
  255.     GR.hBgImages = {};
  256.  
  257.     for ( var i = 0; i < nElems; i++ ) {
  258.         var elem = elems[i];
  259.         var imageUrl = GR.getStyleAndUrl(elem, 'backgroundImage', true, doc);
  260.         if ( imageUrl ) {
  261.             if ( 0 == imageUrl.toLowerCase().indexOf("data:") ) {
  262.                 continue;
  263.             }
  264.  
  265.             imageUrl = imageUrl.replace("\\", ""); // Firefox 3.5 added a backslash to a URL that contained a comma (",")
  266.             if ( ! GR.hBgImages[imageUrl] ) {
  267.                 GR.hBgImages[imageUrl] = 1;
  268.                 GR.addResource("cssimage", imageUrl, elem);
  269.             }
  270.         }
  271.     }
  272. };
  273.  
  274.  
  275. GR.findFlash = function(doc) {
  276.     var aElements = doc.applets;
  277.     for ( var i = 0, len = aElements.length; i < len; i++ ) {
  278.         var elem = aElements[i];
  279.         if ( "string" == typeof(elem["Movie"]) && elem["Movie"].length ) {
  280.             GR.addResource("flash", elem["Movie"]);
  281.         }
  282.     }
  283.  
  284.     var aElements = doc.getElementsByTagName("embed");
  285.     for ( var i = 0, len = aElements.length; i < len; i++) {
  286.         var elem = aElements[i];
  287.         if ( "string" == typeof(elem["src"]) && elem.src.length && GR.isValidProtocol(elem.src) ) {
  288.             GR.addResource("flash", elem.src);
  289.         }
  290.     }
  291. };
  292.  
  293.  
  294. GR.isValidProtocol = function(url) {
  295.     url = url.toLowerCase();
  296.     for ( var max = GR.ignoreProtocols.length, i = 0; i < max; i++ ) {
  297.         if ( url.indexOf(GR.ignoreProtocols[i]) === 0 ) {
  298.             return false;
  299.         }
  300.     }
  301.  
  302.     return true;
  303. };
  304.  
  305.  
  306. GR.addResource = function(type, url, elem) {
  307.     GR.dprint("found resource of type " + type + ": " + url.substring(0, 128));
  308.    
  309.     var aResources = GR.resources[type];
  310.     if ( "undefined" === typeof(aResources) ) {
  311.         GR.resources[type] = [];
  312.         aResources = GR.resources[type];
  313.     }
  314.  
  315.     aResources[aResources.length] = { 'url': url, 'elem': elem };
  316. };
  317.  
  318.  
  319. GR.dprint = function(msg) {
  320.     if ( "undefined" != typeof(console) && "undefined" != typeof(console.log) ) {
  321.         console.log(msg);
  322.     }
  323. };
  324.  
  325.  
  326. GR.init = function() {
  327.     GR.resources = {};
  328.     GR.bIE = ( -1 != navigator.userAgent.indexOf('MSIE') );
  329.     GR.Ajax.initialize();
  330. };
  331.  
  332.  
  333. GR.removeDiv = function() {
  334.     var div = document.getElementById('grdiv');
  335.     div.parentNode.removeChild(div);
  336. };
  337.  
  338.  
  339. GR.report = function(doc) {
  340.     var div = doc.createElement('div');
  341.     div.id = "grdiv";
  342.     div.style.cssText = "border: 2px solid #000; background: white; padding: 0 0 4px 8px; margin: 8px; position: absolute; top: 50px; right: 50px; font-size: 10px; font-family: 'Lucida Grande','Lucida Sans Unicode',Lucida,Arial,Helvetica,sans-serif; z-index: 9999; color: #000; text-align: left; line-height: 1.3em;";
  343.     var sHtml = "<div style='float: right; text-align: right;'><a style='font-weight: bold; color: #FFF; text-decoration: none; border: 1px solid #C00; padding: 0 2px 0 2px; background: #C00;' href='#' onclick='GR.removeDiv(); return false;'>X</a></div><div style='font-weight: bold; font-size: 1.1em; margin-bottom: 8px;'>Page Resources bookmarklet</div>";
  344.  
  345.     // List the resources in these categories:
  346.     var aTypes = ["html", "js", "css", "image", "cssimage", "flash"];
  347.     for ( var i = 0, len = aTypes.length; i < len; i++ ) {
  348.         sHtml += GR.reportType(aTypes[i]);
  349.     }
  350.     sHtml += "<div style='margin: 16px 2em 0 0;'><a style='border: 0; text-decoration: underline; color: #0645AD;' href=\"http://stevesouders.com/mobileperf/pageresources.php\" target='_blank'>Page Resources home</a></div>";
  351.     div.innerHTML = sHtml;
  352.     doc.body.appendChild(div);
  353.     div.style.width = div.offsetWidth + "px"; // fix the width so it doesn't resize if the user collapses the twisties
  354. };
  355.  
  356.  
  357. GR.reportType = function(type) {
  358.     var aResources = GR.resources[type];
  359.     if ( ! aResources ) {
  360.         return "";
  361.     }
  362.  
  363.     var len = aResources.length;
  364.     var id = "pr_" + type;
  365.     var sHtml = "<div>" +
  366.         "<a style='border: 0; text-decoration: underline; color: #0645AD;' href='#' onclick='GR.toggle(this, \"" + id + "\"); return false;'><img border=0 src='http://stevesouders.com/mobileperf/twistyOpen.png'></a> " +
  367.         len + " " + GR.prettyType(type) + " resource" + ( 1 < len ? "s" : "" ) + ":</div><div id='" + id + "' style='margin-left: 10px; margin-bottom: 10px;'>";
  368.     for ( var i = 0; i < len; i++ ) {
  369.         var elem = aResources[i];
  370.         sHtml += "<div style='margin-right: 8px;'><a style='border: 0; text-decoration: underline; color: #0645AD;' href='" + elem['url'] + "'>" + GR.shortenUrl(elem['url']) + "</a><div id='"+escape(GR.shortenUrl(elem['url']))+"'>" +
  371.             GR.reportTypeDetails(type, elem['elem'], elem['url']) +
  372.             "</div></div>";
  373.     }
  374.     sHtml += "</div>";
  375.  
  376.     return sHtml;
  377. };
  378.  
  379.  
  380. // return a string of additional details
  381. GR.reportTypeDetails = function(type, elem, url) {
  382.    
  383.     var renderProcessGenerator = function renderProcessGenerator(url) {
  384.         var renderProcess = function renderProcess(src) {
  385.             GR.dprint("size of " + url + " " + src.length);
  386.             id = escape(GR.shortenUrl(url));
  387.             document.getElementById(id).innerHTML = src.length;
  388.  
  389.         }
  390.         return renderProcess;
  391.     }
  392.    
  393.  
  394.     sHtml = "";
  395.     if ( "image" === type ) {
  396.         if ( "undefined" != typeof(elem.naturalWidth) ) {
  397.             sHtml += "(" + elem.naturalWidth + "x" + elem.naturalHeight;
  398.         }
  399.         else {
  400.             sHtml += "(" + elem.width + "x" + elem.height;
  401.         }
  402.  
  403.         if ( "undefined" != typeof(elem.fileSize) ) {
  404.             sHtml += ", " + parseInt(elem.fileSize / 1024) + "K";
  405.         }
  406.         sHtml += ")";
  407.     }
  408.     else if ( "js" === type){
  409.        
  410.         GR.Ajax.request({ url: url,
  411.                           onSuccess: renderProcessGenerator(url),
  412.                           onFailure: alert
  413.                        })
  414.     }
  415.     else if ( "css" === type){
  416.         //GR.dprint("???? " + elem.href);
  417.         GR.Ajax.request({ url: url,
  418.                           onSuccess: renderProcessGenerator(url),
  419.                           onFailure: alert
  420.                        })
  421.     }
  422.    
  423.    
  424.  
  425.     return sHtml;
  426. };
  427.  
  428.  
  429. GR.toggle = function(a, targetId) {
  430.     var elem = document.getElementById(targetId);
  431.     if ( a && elem ) {
  432.         bShow = ( "none" == elem.style.display );
  433.         elem.style.display = ( bShow ? "block" : "none" );
  434.         a.getElementsByTagName('img')[0].src = ( bShow ? "http://stevesouders.com/mobileperf/twistyOpen.png" : "http://stevesouders.com/mobileperf/twistyClosed.png" );
  435.     }
  436. };
  437.  
  438.  
  439. GR.getStyleAndUrl = function(elem, prop, bGetUrl, doc) {
  440.     var val = "";
  441.  
  442.     if ( elem.currentStyle ) {
  443.         val = elem.currentStyle[prop];
  444.     }
  445.  
  446.     if ( elem.ownerDocument && elem.ownerDocument.defaultView && doc.defaultView.getComputedStyle ) {
  447.         var style = elem.ownerDocument.defaultView.getComputedStyle(elem, "");
  448.         if ( style ) {
  449.             val = style[prop];
  450.         }
  451.     }
  452.  
  453.     if ( "backgroundPosition" === prop && GR.bIE ) {
  454.         var posX = GR.getStyleAndUrl(elem, 'backgroundPositionX', false, doc);
  455.         posX = ( "left" == posX ? "0%" : ( "center" == posX ? "50%" : ( "right" == posX ? "100%" : posX ) ) );
  456.         var posY = GR.getStyleAndUrl(elem, 'backgroundPositionY', false, doc);
  457.         posY = ( "top" == posY ? "0%" : ( "center" == posY ? "50%" : ( "bottom" == posY ? "100%" : posY ) ) );
  458.         val = posX + " " + posY;
  459.     }
  460.  
  461.     if ( !bGetUrl ) {
  462.         return val;
  463.     }
  464.  
  465.     if ( "string" != typeof(val) || 0 !== val.indexOf('url(') ) {
  466.         return false;
  467.     }
  468.  
  469.     val = val.replace(/url\(/, "");
  470.     val = val.substr(0, val.length - 1);
  471.     if ( 0 === val.indexOf('"') ) {
  472.         val = val.substr(1, val.length - 2);
  473.     }
  474.  
  475.     return val;
  476. };
  477.  
  478.  
  479. GR.shortenUrl = function(url) {
  480.     if ( 60 < url.length ) {
  481.         // strip the querystring
  482.         var hostname = "", dirs = "", filename = "", ext = "", querystring = "";
  483.         if ( url.match( /^(http.*\/\/.*?\/)(.*)$/ ) ) {
  484.             // break it apart
  485.             hostname = RegExp.$1;  // HAS trailing slash
  486.             url = RegExp.$2;
  487.  
  488.             if ( url.match( /^(.*)(\?.*)$/ ) ) {
  489.                 url = RegExp.$1;
  490.                 querystring = RegExp.$2;  // HAS leading "?"
  491.             }
  492.  
  493.             if ( url.match( /^(.*\/)(.*)$/ ) ) {
  494.                 dirs = RegExp.$1;  // HAS trailing slash
  495.                 url = RegExp.$2;
  496.             }
  497.                
  498.             if ( url.match( /^(.*)(\..*?)$/ ) && 5 > RegExp.$2.length ) {
  499.                 filename = RegExp.$1; // NO trailing "."
  500.                 ext = RegExp.$2;      // HAS leading "."
  501.             }
  502.             var hlen = hostname.length, dlen = dirs.length, flen = filename.length, elen = ext.length, qlen = querystring.length;
  503.  
  504.             // build it back up
  505.             if ( 60 > hlen + dlen + flen + elen ) {
  506.                 // trim querystring
  507.                 url = hostname + dirs + filename + ext;
  508.                 return url + ( qlen ? querystring.substring(0, 57 - url.length) + "..." : "" );
  509.             }
  510.  
  511.             if ( 64 > hlen + flen + elen ) {
  512.                 // trim dirs
  513.                 return hostname + dirs.substring(0, (60-(hlen + flen + elen))) + ".../" + filename + ext;
  514.             }
  515.  
  516.             if ( 60 > hlen ) {
  517.                 // trim filename
  518.                 return hostname + ( dirs ? ".../" : "" ) + filename.substring(0, (60-(hlen + elen))) + "..." + ext;
  519.             }
  520.  
  521.             return hostname.substring(0, 53) + ".../...";
  522.         }
  523.     }
  524.  
  525.     return url;
  526. };
  527.  
  528.  
  529. GR.prettyType = function(type) {
  530.     switch(type) {
  531.         case "html": return "HTML";
  532.         case "js": return "Script";
  533.         case "css": return "Stylesheet";
  534.         case "image": return "Image";
  535.         case "cssimage": return "CSS Background Image";
  536.         case "flash": return "Flash";
  537.     }
  538.  
  539.     return "unrecognized type";
  540. };
  541.  
  542.  
  543. GR.findResources = function(doc) {
  544.     GR.findScripts(doc);
  545.     GR.findStylesheets(doc);
  546.     GR.findImages(doc);
  547.     GR.findBgImages(doc);
  548.     GR.findFlash(doc);
  549. };
  550.  
  551.  
  552. GR.start = function() {
  553.     GR.init();
  554.    
  555.  
  556.     var subDocs = GR.findHtml(window);
  557.     for ( var i = 0, len = subDocs.length; i < len; i++ ) {
  558.         GR.findResources(subDocs[i]);
  559.     }
  560.  
  561.     GR.report(window.document);
  562. };
  563.  
  564.  
  565. GR.start();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement