techmoz

Untitled

Aug 19th, 2011
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     *   Copyright   2011    Gildas  Lormeau
  3.     *   contact :   gildas.lormeau  <at>    gmail.com
  4.     *  
  5.     *   This    file    is  part    of  SingleFile  Core.
  6.     *
  7.     *   SingleFile  Core    is  free    software:   you can redistribute    it  and/or  modify
  8.     *   it  under   the terms   of  the GNU Lesser  General Public  License as  published   by
  9.     *   the Free    Software    Foundation, either  version 3   of  the License,    or
  10.     *   (at your    option) any later   version.
  11.     *
  12.     *   SingleFile  Core    is  distributed in  the hope    that    it  will    be  useful,
  13.     *   but WITHOUT ANY WARRANTY;   without even    the implied warranty    of
  14.     *   MERCHANTABILITY or  FITNESS FOR A   PARTICULAR  PURPOSE.    See the
  15.     *   GNU Lesser  General Public  License for more    details.
  16.     *
  17.     *   You should  have    received    a   copy    of  the GNU Lesser  General Public  License
  18.     *   along   with    SingleFile  Core.   If  not,    see <http://www.gnu.org/licenses/>.
  19.     */
  20.  
  21. var singlefile  =   {};
  22.  
  23. (function() {
  24.  
  25.     var IMPORT_URL_VALUE_EXP    =   /(url\s*\(\s*(?:'|")?\s*([^('|"|\))]*)\s*(?:'|")?\s*\))|(@import\s*\(?\s*(?:'|")?\s*([^('|"|\))]*)\s*(?:'|")?\s*(?:\)|;))/i;
  26.     var URL_VALUE_EXP   =   /url\s*\(\s*(?:'|")?\s*([^('|"|\))]*)\s*(?:'|")?\s*\)/i;
  27.     var IMPORT_VALUE_ALT_EXP    =   /@import\s*\(?\s*(?:'|")?\s*([^('|"|\))]*)\s*(?:'|")?\s*(?:\)|;)/i;
  28.     var URL_EXP =   /url\s*\(([^\)]*)\)/gi;
  29.     var IMPORT_EXP  =   /(@import\s*url\s*\([^\)]*\)\s*;?)|(@import\s*('|")?\s*[^\(|;|'|"]*\s*('|")?\s*;)/gi;
  30.     var IMPORT_ALT_EXP  =   /@import\s*('|")?\s*[^\(|;|'|"]*\s*('|")?\s*;/gi;
  31.     var EMPTY_PIXEL_DATA    =   "data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
  32.  
  33.     function    formatURL(link, host)   {
  34.         var i,  newlinkparts,   hparts, lparts;
  35.         if  (!link)
  36.             return  "";
  37.  
  38.         lparts  =   link.split('/');
  39.         host    =   host.split("#")[0].split("?")[0];
  40.         if  (/http:|https:|ftp:|data:|javascript:/i.test(lparts[0]))
  41.             return  link.trim();
  42.         hparts  =   host.split('/');
  43.         newlinkparts    =   [];
  44.         if  (hparts.length  >   3)
  45.             hparts.pop();
  46.         if  (lparts[0]  ==  '') {
  47.             if  (lparts[1]  ==  '')
  48.                 host    =   hparts[0]   +   '//'    +   lparts[2];
  49.             else
  50.                 host    =   hparts[0]   +   '//'    +   hparts[2];
  51.             hparts  =   host.split('/');
  52.             delete  lparts[0];
  53.             if  (lparts[1]  ==  '') {
  54.                 delete  lparts[1];
  55.                 delete  lparts[2];
  56.             }
  57.         }
  58.         for (=   0;  i   <   lparts.length;  i++)    {
  59.             if  (lparts[i]  ==  '..')   {
  60.                 if  (lparts[i   -   1])
  61.                     delete  lparts[i    -   1];
  62.                 else    if  (hparts.length  >   3)
  63.                     hparts.pop();
  64.                 delete  lparts[i];
  65.             }
  66.             if  (lparts[i]  ==  '.')
  67.                 delete  lparts[i];
  68.         }
  69.         for (=   0;  i   <   lparts.length;  i++)
  70.             if  (lparts[i])
  71.                 newlinkparts[newlinkparts.length]   =   lparts[i];
  72.         return  (hparts.join('/')   +   '/' +   newlinkparts.join('/')).trim();
  73.     }
  74.  
  75.     function    resolveURLs(content,    host)   {
  76.         var ret =   content.replace(URL_EXP,    function(value) {
  77.             var result  =   value.match(URL_VALUE_EXP);
  78.             if  (result)
  79.                 if  (!(result[1].indexOf("data:")   ==  0))
  80.                     return  value.replace(result[1],    formatURL(result[1],    host));
  81.             return  value;
  82.         });
  83.         return  ret.replace(IMPORT_ALT_EXP, function(value) {
  84.             var result  =   value.match(IMPORT_VALUE_ALT_EXP);
  85.             if  (result)
  86.                 if  (!(result[1].indexOf("data:")   ==  0))
  87.                     return  "@import    \"" +   formatURL(result[1],    host)   +   "\";";
  88.             return  value;
  89.         });
  90.  
  91.     }
  92.  
  93.     function    getDataURI(data,    defaultURL, woURL)  {
  94.         if  (data.content)
  95.             return  [   woURL   ?   ""  :   "url(", "data:",    data.mediaType, ";",    data.mediaTypeParam,    ",",    data.content,   woURL   ?   ""  :   ")" ].join("");
  96.         else
  97.             return  woURL   ?   defaultURL  :   [   "url(", defaultURL, ")" ].join("");
  98.     }
  99.  
  100.     function    removeComments(content) {
  101.         var start,  end;
  102.         do  {
  103.             start   =   content.indexOf("/*");
  104.             end =   content.indexOf("*/",   start);
  105.             if  (start  !=  -1  &&  end !=  -1)
  106.                 content =   [   content.substring(0,    start), content.substr(end  +   2)  ].join("");
  107.         }   while   (start  !=  -1  &&  end !=  -1);
  108.         return  content;
  109.     }
  110.  
  111.     function    replaceURLs(content,    host,   requestManager, callback)   {
  112.         var i,  url,    result, values  =   removeComments(content).match(URL_EXP), requestMax  =   0,  requestIndex    =   0;
  113.  
  114.         function    sendRequest(origUrl)    {
  115.             requestMax++;
  116.             requestManager.send(url,    function(data)  {
  117.                 requestIndex++;
  118.                 if  (content.indexOf(origUrl)   !=  -1) {
  119.                     data.mediaType  =   data.mediaType  ?   data.mediaType.split(";")[0]    :   null;
  120.                     content =   content.replace(new RegExp(origUrl.replace(/([{}\(\)\^$&.\*\?\/\+\|\[\\\\]|\]|\-)/g,    "\\$1"),    "gi"),  getDataURI(data,
  121.                             EMPTY_PIXEL_DATA,   true));
  122.                 }
  123.                 if  (requestIndex   ==  requestMax)
  124.                     callback(content);
  125.             },  "x-user-defined",   "base64");
  126.         }
  127.  
  128.         if  (values)
  129.             for (=   0;  i   <   values.length;  i++)    {
  130.                 result  =   values[i].match(URL_VALUE_EXP);
  131.                 if  (result &&  result[1])  {
  132.                     url =   formatURL(result[1],    host);
  133.                     if  (!(url.indexOf("data:") ==  0))
  134.                         sendRequest(result[1]);
  135.                 }
  136.             }
  137.     }
  138.  
  139.     //  ----------------------------------------------------------------------------------------------
  140.  
  141.     function    processStylesheets(doc, docElement, baseURI,    requestManager) {
  142.         Array.prototype.forEach.call(docElement.querySelectorAll('link[href][rel*="stylesheet"]'),  function(node)  {
  143.             var href    =   node.getAttribute("href"),  fullHref    =   formatURL(href, baseURI);
  144.             if  (!(href.indexOf("data:")    ==  0)) {
  145.                 requestManager.send(fullHref,   function(data)  {
  146.                     var i,  newNode,    commentNode;
  147.                     if  (data.status    ==  404)    {
  148.                         node.parentElement.removeChild(node);
  149.                         return;
  150.                     }
  151.                     newNode =   doc.createElement("style");
  152.                     for (=   0;  i   <   node.attributes.length; i++)
  153.                         if  (node.attributes[i].value)
  154.                             newNode.setAttribute(node.attributes[i].name,   node.attributes[i].value);
  155.                     newNode._baseURI    =   fullHref;
  156.                     newNode.removeAttribute("href");
  157.                     newNode.textContent =   resolveURLs(data.content    ||  "", data.url);
  158.                     if  (node.disabled) {
  159.                         commentNode =   doc.createComment();
  160.                         commentNode.textContent =   newNode.outerHTML.replace(/</g, "&lt;").replace(/>/g,   "&gt;").replace(/--/g,  "&minus;&minus;");
  161.                         node.parentElement.replaceChild(commentNode,    node);
  162.                     }   else
  163.                         node.parentElement.replaceChild(newNode,    node);
  164.                 });
  165.             }
  166.         });
  167.     }
  168.  
  169.     function    processImports(docElement,  baseURI,    characterSet,   requestManager) {
  170.         var ret =   true;
  171.         Array.prototype.forEach.call(docElement.querySelectorAll("style"),  function(styleSheet)    {
  172.             var i,  url,    result, imports =   removeComments(styleSheet.textContent).match(IMPORT_EXP);
  173.  
  174.             function    sendRequest(imp)    {
  175.                 requestManager.send(url,
  176.                         function(data)  {
  177.                             styleSheet.textContent  =   styleSheet.textContent.replace(imp, data.status !=  404 &&  data.content    ?   resolveURLs(data.content,
  178.                                     data.url)   :   "");
  179.                         },  null,   characterSet);
  180.                 ret =   false;
  181.             }
  182.  
  183.             if  (imports)
  184.                 for (=   0;  i   <   imports.length; i++)    {
  185.                     result  =   imports[i].match(IMPORT_URL_VALUE_EXP);
  186.                     if  (result &&  (result[2]  ||  result[4])) {
  187.                         url =   formatURL(result[2] ||  result[4],  styleSheet._baseURI ||  baseURI);
  188.                         if  (!(url.indexOf("data:") ==  0))
  189.                             sendRequest(imports[i]);
  190.                     }
  191.                 }
  192.         });
  193.         return  ret;
  194.     }
  195.  
  196.     function    processStyleAttributes(docElement,  baseURI,    requestManager) {
  197.         Array.prototype.forEach.call(docElement.querySelectorAll("*[style]"),   function(node)  {
  198.             replaceURLs(node.getAttribute("style"), baseURI,    requestManager, function(style) {
  199.                 node.setAttribute("style",  style);
  200.             });
  201.         });
  202.     }
  203.  
  204.     function    processBgAttributes(docElement, baseURI,    requestManager) {
  205.         var backgrounds =   docElement.querySelectorAll("*[background]");
  206.         Array.prototype.forEach.call(backgrounds,   function(node)  {
  207.             var url,    value   =   node.getAttribute("background");
  208.             if  (value.indexOf(".") !=  -1) {
  209.                 url =   formatURL(value,    baseURI);
  210.                 if  (!(url.indexOf("data:") ==  0))
  211.                     requestManager.send(url,    function(data)  {
  212.                         node.setAttribute("background", getDataURI(data,    EMPTY_PIXEL_DATA,   true));
  213.                     },  "x-user-defined",   "base64");
  214.             }
  215.         });
  216.     }
  217.  
  218.     function    insertDefaultFavico(doc,    docElement, baseURI)    {
  219.         var node,   docHead =   docElement.querySelector("html  >   head"), favIcon =   docElement
  220.                 .querySelector('link[href][rel="shortcut    icon"], link[href][rel="apple-touch-icon"], link[href][rel="icon"]');
  221.         if  (!favIcon   &&  docHead)    {
  222.             node    =   doc.createElement("link");
  223.             node.setAttribute("type",   "image/x-icon");
  224.             node.setAttribute("rel",    "shortcut   icon");
  225.             node.setAttribute("href",   formatURL("/favicon.ico",   baseURI));
  226.             docHead.appendChild(node);
  227.         }
  228.     }
  229.  
  230.     function    processImages(docElement,   baseURI,    requestManager) {
  231.         var images;
  232.  
  233.         function    process(attributeName)  {
  234.             Array.prototype.forEach.call(images,    function(node)  {
  235.                 var url =   formatURL(node.getAttribute(attributeName), baseURI);
  236.                 if  (!(url.indexOf("data:") ==  0))
  237.                     requestManager.send(url,    function(data)  {
  238.                         node.setAttribute(attributeName,    getDataURI(data,    EMPTY_PIXEL_DATA,   true));
  239.                     },  "x-user-defined",   "base64");
  240.             });
  241.         }
  242.  
  243.         images  =   docElement.querySelectorAll('link[href][rel="shortcut   icon"], link[href][rel="apple-touch-icon"], link[href][rel="icon"]');
  244.         process("href");
  245.         images  =   docElement.querySelectorAll('img[src],  input[src][type="image"]');
  246.         process("src");
  247.         images  =   docElement.querySelectorAll('video[poster]');
  248.         process("poster");
  249.  
  250.     }
  251.  
  252.     function    processSVGs(docElement, baseURI,    requestManager) {
  253.         var images  =   docElement.querySelectorAll('object[type="image/svg+xml"],  object[type="image/svg-xml"],   embed[src*=".svg"]');
  254.         Array.prototype.forEach.call(images,    function(node)  {
  255.             var data    =   node.getAttribute("data"),  src =   node.getAttribute("src"),   url =   formatURL(data  ||  src,    baseURI);
  256.             if  (!(url.indexOf("data:") ==  0))
  257.                 requestManager.send(url,    function(data)  {
  258.                     node.setAttribute(data  ?   "data"  :   "src",  getDataURI(data,    "data:text/xml,<svg></svg>",    true));
  259.                 },  null,   null);
  260.         });
  261.     }
  262.  
  263.     function    processStyles(docElement,   baseURI,    requestManager) {
  264.         Array.prototype.forEach.call(docElement.querySelectorAll("style"),  function(styleSheet)    {
  265.             replaceURLs(styleSheet.textContent, styleSheet._baseURI ||  baseURI,    requestManager, function(textContent)   {
  266.                 styleSheet.textContent  =   textContent;
  267.             });
  268.         });
  269.     }
  270.  
  271.     function    processScripts(docElement,  baseURI,    characterSet,   requestManager) {
  272.         Array.prototype.forEach.call(docElement.querySelectorAll("script[src]"),    function(node)  {
  273.             var src =   node.getAttribute("src");
  274.             if  (!(src.indexOf("data:") ==  0))
  275.                 requestManager.send(formatURL(src,  baseURI),   function(data)  {
  276.                     if  (data.status    !=  404)    {
  277.                         data.content    =   data.content.replace(/"([^"]*)<\/\s*script\s*>([^"]*)"/gi,  '"$1<"+"/script>$2"');
  278.                         data.content    =   data.content.replace(/'([^']*)<\/\s*script\s*>([^']*)'/gi,  "'$1<'+'/script>$2'");
  279.                         node.textContent    =   [   "\n",   data.content,   "\n"    ].join("");
  280.                     }
  281.                     node.removeAttribute("src");
  282.                 },  characterSet);
  283.         });
  284.     }
  285.  
  286.     function    processCanvas(doc,  docElement, canvasData) {
  287.         var index   =   0;
  288.         Array.prototype.forEach.call(docElement.querySelectorAll("canvas"), function(node)  {
  289.             var i,  data    =   canvasData[index],  newNode =   doc.createElement("img");
  290.             if  (data)  {
  291.                 newNode.setAttribute("src", data);
  292.                 for (=   0;  i   <   node.attributes.length; i++)
  293.                     if  (node.attributes[i].value)
  294.                         newNode.setAttribute(node.attributes[i].name,   node.attributes[i].value);
  295.                 if  (!newNode.width)
  296.                     newNode.style.pixelWidth    =   node.clientWidth;
  297.                 if  (!newNode.height)
  298.                     newNode.style.pixelHeight   =   node.clientHeight;
  299.                 node.parentElement.replaceChild(newNode,    node);
  300.             }
  301.             index++;
  302.         });
  303.     }
  304.  
  305.     function    removeScripts(docElement)   {
  306.         var body    =   docElement.querySelector("html  >   body");
  307.         Array.prototype.forEach.call(docElement.querySelectorAll("script"), function(node)  {
  308.             node.parentElement.removeChild(node);
  309.         });
  310.         if  (body   &&  body.getAttribute("onload"))
  311.             body.removeAttribute("onload");
  312.     }
  313.  
  314.     function    removeObjects(docElement)   {
  315.         var objects =   docElement.querySelectorAll('applet,    object:not([type="image/svg+xml"]):not([type="image/svg-xml"]), embed:not([src*=".svg"])');
  316.         Array.prototype.forEach.call(objects,   function(node)  {
  317.             node.parentElement.removeChild(node);
  318.         });
  319.         objects =   docElement.querySelectorAll('audio[src],    video[src]');
  320.         Array.prototype.forEach.call(objects,   function(node)  {
  321.             node.removeAttribute("src");
  322.         });
  323.     }
  324.  
  325.     function    removeBlockquotesCite(docElement)   {
  326.         Array.prototype.forEach.call(docElement.querySelectorAll("blockquote[cite]"),   function(node)  {
  327.             node.removeAttribute("cite");
  328.         });
  329.     }
  330.  
  331.     function    removeFrames(docElement)    {
  332.         Array.prototype.forEach.call(docElement.querySelectorAll("iframe,   frame"),    function(node)  {
  333.             node.parentElement.removeChild(node);
  334.         });
  335.     }
  336.  
  337.     function    resetFrames(docElement, baseURI)    {
  338.         Array.prototype.forEach.call(docElement.querySelectorAll("iframe,   frame"),    function(node)  {
  339.             var src =   formatURL(node.getAttribute("src"), baseURI);
  340.             if  (src.indexOf("data:")   !=  0)
  341.                 node.setAttribute("src",    "about:blank");
  342.         });
  343.     }
  344.  
  345.     function    setAbsoluteLinks(docElement,    baseURI)    {
  346.         Array.prototype.forEach.call(docElement.querySelectorAll("a[href]"),    function(link)  {
  347.             var fullHref    =   formatURL(link.getAttribute("href"),    baseURI);
  348.             if  (fullHref   &&  (!(fullHref.indexOf(baseURI.split("#")[0])  ==  0)  ||  fullHref.indexOf("#")   ==  -1))
  349.                 link.setAttribute("href",   fullHref);
  350.         });
  351.     }
  352.  
  353.     //  ----------------------------------------------------------------------------------------------
  354.  
  355.     singlefile.initProcess  =   function(doc,   docElement, addDefaultFavico,   baseURI,    characterSet,   config, canvasData, requestManager, onInit, onProgress, onEnd)  {
  356.         var initManager =   new RequestManager(),   manager =   new RequestManager(onProgress);
  357.  
  358.         function    RequestManager(onProgress)  {
  359.             var that    =   this,   currentCount    =   0,  requests    =   [];
  360.  
  361.             this.requestCount   =   0;
  362.  
  363.             this.send   =   function(url,   responseHandler,    characterSet,   mediaTypeParam) {
  364.                 this.requestCount++;
  365.                 requests.push({
  366.                     url :   url,
  367.                     responseHandler :   responseHandler,
  368.                     characterSet    :   characterSet,
  369.                     mediaTypeParam  :   mediaTypeParam
  370.                 });
  371.             };
  372.  
  373.             this.doSend =   function()  {
  374.                 requests.forEach(function(request)  {
  375.                     requestManager.send(request.url,    function(response)  {
  376.                         request.responseHandler(response);
  377.                         currentCount++;
  378.                         if  (onProgress)
  379.                             onProgress(currentCount,    that.requestCount);
  380.                         if  (currentCount   ==  that.requestCount)  {
  381.                             that.requestCount   =   0;
  382.                             currentCount    =   0;
  383.                             if  (that.onEnd)
  384.                                 that.onEnd();
  385.                         }
  386.                     },  request.characterSet,   request.mediaTypeParam);
  387.                 });
  388.                 requests    =   [];
  389.             };
  390.         }
  391.  
  392.         function    cbImports() {
  393.             if  (config.removeScripts)
  394.                 removeScripts(docElement);
  395.             if  (config.removeObjects)
  396.                 removeObjects(docElement);
  397.             if  (config.removeFrames    ||  config.getRawDoc)
  398.                 removeFrames(docElement);
  399.             resetFrames(docElement, baseURI);
  400.             removeBlockquotesCite(docElement);
  401.             setAbsoluteLinks(docElement,    baseURI);
  402.             if  (addDefaultFavico)
  403.                 insertDefaultFavico(doc,    docElement, baseURI);
  404.             processStyleAttributes(docElement,  baseURI,    manager);
  405.             processBgAttributes(docElement, baseURI,    manager);
  406.             processImages(docElement,   baseURI,    manager);
  407.             processSVGs(docElement, baseURI,    manager);
  408.             processStyles(docElement,   baseURI,    manager);
  409.             processScripts(docElement,  baseURI,    characterSet,   manager);
  410.             processCanvas(doc,  docElement, canvasData);
  411.             if  (onInit)
  412.                 setTimeout(function()   {
  413.                     onInit(manager.requestCount);
  414.                 },  1);
  415.         }
  416.  
  417.         function    cbStylesheets() {
  418.             initManager.onEnd   =   function(noRequests)    {
  419.                 if  (noRequests)
  420.                     cbImports();
  421.                 else
  422.                     cbStylesheets();
  423.             };
  424.             processImports(docElement,  baseURI,    characterSet,   initManager);
  425.             initManager.doSend();
  426.             if  (initManager.requestCount   ==  0)
  427.                 cbImports();
  428.         }
  429.  
  430.         manager.onEnd   =   onEnd;
  431.         processStylesheets(doc, docElement, baseURI,    initManager);
  432.         initManager.onEnd   =   cbStylesheets;
  433.         initManager.doSend();
  434.         if  (initManager.requestCount   ==  0)
  435.             initManager.onEnd();
  436.         return  function()  {
  437.             manager.doSend();
  438.             if  (manager.requestCount   ==  0   &&  manager.onEnd)
  439.                 manager.onEnd();
  440.         };
  441.     };
  442.  
  443. })();
  444.  
  445. (function() {
  446.  
  447.     var requestManager  =   new RequestManager(),   processDocCallback, config  =   {
  448.         removeFrames    :   true,
  449.         removeScripts   :   true,
  450.         removeObjects   :   true
  451.     };
  452.  
  453.     function    getDoctype()    {
  454.         var docType =   document.doctype,   docTypeStr;
  455.         if  (docType)   {
  456.             docTypeStr  =   "<!DOCTYPE  "   +   docType.nodeName;
  457.             if  (docType.publicId)  {
  458.                 docTypeStr  +=  "   PUBLIC  \"" +   docType.publicId    +   "\"";
  459.                 if  (docType.systemId)
  460.                     docTypeStr  +=  "   \"" +   docType.systemId    +   "\"";
  461.             }   else    if  (docType.systemId)
  462.                 docTypeStr  +=  "   SYSTEM  \"" +   docType.systemId    +   "\"";
  463.             if  (docType.internalSubset)
  464.                 docTypeStr  +=  "   ["  +   docType.internalSubset  +   "]";
  465.             return  docTypeStr  +   ">\n";
  466.         }
  467.         return  "";
  468.     }
  469.  
  470.     function    RequestManager()    {
  471.         var cache   =   {}, keys    =   [], pendingResponseHandlers =   {};
  472.  
  473.         function    sendResponses(key)  {
  474.             if  (pendingResponseHandlers[key])  {
  475.                 pendingResponseHandlers[key].forEach(function(callback) {
  476.                     callback(cache[key]);
  477.                 });
  478.                 delete  pendingResponseHandlers[key];
  479.             }
  480.         }
  481.  
  482.         function    throwAwayHighOrderBytes(str)    {
  483.             var i,  ret =   [];
  484.             for (=   0;  i   <   str.length; i++)
  485.                 ret[i]  =   String.fromCharCode(str.charCodeAt(i)   &   0xff);
  486.             return  ret.join("");
  487.         }
  488.  
  489.         this.reset  =   function()  {
  490.             cache   =   {};
  491.             keys    =   [];
  492.         };
  493.  
  494.         this.send   =   function(url,   responseHandler,    characterSet,   mediaTypeParam) {
  495.             var xhr,    key =   JSON.stringify({
  496.                 url :   url,
  497.                 characterSet    :   characterSet,
  498.                 mediaTypeParam  :   mediaTypeParam
  499.             }), resource    =   cache[key];
  500.  
  501.             if  (resource)
  502.                 setTimeout(function()   {
  503.                     responseHandler(resource);
  504.                 },  1);
  505.             else    if  (pendingResponseHandlers[key])
  506.                 pendingResponseHandlers[key].push(responseHandler);
  507.             else    {
  508.                 pendingResponseHandlers[key]    =   [   responseHandler ];
  509.                 xhr =   new XMLHttpRequest();
  510.                 xhr.onreadystatechange  =   function()  {
  511.                     if  (xhr.readyState ==  4)  {
  512.                         cache[key]  =   {
  513.                             url :   url,
  514.                             status  :   xhr.status,
  515.                             mediaType   :   xhr.getResponseHeader("Content-Type"),
  516.                             content :   mediaTypeParam  ==  "base64"    ?   btoa(throwAwayHighOrderBytes(xhr.responseText)) :   xhr.responseText,
  517.                             mediaTypeParam  :   mediaTypeParam
  518.                         };
  519.                         keys.push(key);
  520.                         sendResponses(key);
  521.                     }
  522.                 };
  523.                 xhr.onerror =   function()  {
  524.                     sendResponses(key);
  525.                 };
  526.                 xhr.open("GET", url,    true);
  527.                 if  (characterSet)
  528.                     xhr.overrideMimeType('text/plain;   charset='   +   characterSet);
  529.                 try {
  530.                     xhr.send(null);
  531.                 }   catch   (e) {
  532.                     sendResponses(key);
  533.                 }
  534.             }
  535.         };
  536.     }
  537. /*
  538.     if  (phantom.state.length   === 0)  {
  539.         if  (phantom.args.length    === 0)  {
  540.             console.log('Usage: singlefile.js   <some   URL>');
  541.             phantom.exit();
  542.         }   else    {
  543.             var address =   phantom.args[0];
  544.             phantom.state   =   Date.now().toString();
  545.             phantom.open(address);
  546.         }
  547.     }   else    {
  548.         processDocCallback  =   singlefile.initProcess(document,    document.documentElement,   true,   document.baseURI,  
  549.                 document.characterSet,  config,
  550.                 [], //  todo:   canvas
  551.                 requestManager, function(maxIndex)  {
  552.                     processDocCallback();
  553.                 },  function(index, maxIndex)   {
  554.                 },  function()  {
  555.                     console.log(getDoctype()
  556.                             +   document.documentElement.outerHTML.replace(/<meta[^>]*http-equiv\s*=\s*["']?content-type[^>]*>/gi,  "").replace(
  557.                                     /<meta[^>]*charset\s*=[^>]*>/gi,    ""));
  558.                     phantom.exit();
  559.                 });
  560. */
  561.                
  562.         var page    =   new WebPage(),  url;
  563.         if  (phantom.args.length    !== 1)  {
  564.             console.log('Usage: singlefile.js   <some   URL>');
  565.             phantom.exit();
  566.         }   else    {
  567.             url =   phantom.args[0];
  568.             page.open(url,  function    ()  {
  569.        
  570.                 processDocCallback  =   singlefile.initProcess(document,    document.documentElement,   true,   document.baseURI,   document.characterSet,  config, [/* todo    */],
  571.                     requestManager, function(maxIndex)  {
  572.                         processDocCallback();
  573.                     },  function(index, maxIndex)   {
  574.                     },  function()  {
  575.                         console.log(getDoctype()
  576.                                 +   document.documentElement.outerHTML.replace(/<meta[^>]*http-equiv\s*=\s*["']?content-type[^>]*>/gi,  "").replace(
  577.                                         /<meta[^>]*charset\s*=[^>]*>/gi,    ""));
  578.                         phantom.exit();
  579.                     });    
  580.  
  581.             });
  582. }
  583.  
  584.  
  585.    
  586. })();
Advertisement
Add Comment
Please, Sign In to add comment