inliner.js
[app.webkitpdf] / inliner.js
1 /**
2  *
3  * Based on...
4  * CSS Inline Transform v0.1
5  * http://tikku.com/css-inline-transformer-simplified
6  * 
7  * Copyright 2010-2012, Nirvana Tikku
8  * Dual licensed under the MIT or GPL Version 2 licenses.
9  * https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt
10  * 
11  * This tool leverages the jQuery library.
12  * 
13  * Compatibility only tested with FireFox 3.5+, Chrome 5+
14  * 
15  * @author Nirvana Tikku
16  * @dependent jQuery 1.4
17  * @date Wed Mar 31 14:58:04 2010 -0500
18  * @updated Sat Mar 10 16:21:20 2012 -0500
19  * 
20  */
21
22 (function(){
23     
24     //
25     // private methods
26     //
27     /**
28      * @param stylesArray - the array of string 
29      *                  "{name}:{value};" pairs that are to be broken down
30      *
31      */
32     function createCSSRuleObject (stylesArray) {
33         var cssObj = {};
34         for(_s in stylesArray){
35                 var S = stylesArray[_s].split(":");
36                 if(S[0].trim()==""||S[1].trim()=="")continue;
37                 cssObj[S[0].trim()] = S[1].trim();
38         }
39         return cssObj;
40     }
41
42     /**
43      * @param $out - the tmp html content
44      * 
45      */
46     function interpritAppendedStylesheet ($out) { 
47         var stylesheet = $out[0].styleSheets[0]; // first stylesheet
48         for(r in stylesheet.cssRules){
49                 try{
50                         var rule = stylesheet.cssRules[r]; 
51                         if(!isNaN(rule))break; // make sure the rule exists
52                         var $destObj = $out.find(rule.selectorText);
53                         var obj = rule.cssText.replace(rule.selectorText, '');
54                         obj = obj.replace('{','').replace('}',''); // clean up the { and }'s
55                         var styles = obj.split(";"); // separate each 
56                         $destObj.css(createCSSRuleObject(styles)); // do the inline styling
57                 } catch (e) { }
58         }
59     };
60     
61     
62         function isPatternRelevant (newHTML, pattern, relevantPatterns) {
63             if( newHTML.indexOf(pattern) > -1 )
64                 relevantPatterns.push(new RegExp(pattern,"i"));
65         };
66
67     /**
68      * The main method - inflinify
69      *  this utilizes two text areas and a div for final output -  
70      *          (1) css input textarea for the css to apply
71      *          (2) html content for the css to apply TO
72      */
73     function inlinify () {
74         
75         interpritAppendedStylesheet(document); // apply styles to the document just created
76         
77         // remove existing stylesheets..
78         var ar = document.getElementsByTagName('style');
79         for(var i =0;i< ar.length;i++) {
80             ar[i].parentElement.remove(ar[i]);
81         }
82         
83         //var relevantPatterns = [];
84         //      isPatternRelevant(newHTML, "href=\"", relevantPatterns);
85         //      isPatternRelevant(newHTML, "src=\"", relevantPatterns);
86         //      return sanitize( newHTML, relevantPatterns );
87     };
88     
89     function sanitize(html, patterns){
90         var ret = html;
91         for(var i=0; i<patterns.length; i++){
92             ret = san(ret, patterns[i])
93         }  
94         return ret;
95     };
96
97     /**
98      * This method will take HTML and a PATTERN and essentially
99      * sanitize the following chars within the HTML with that 
100      * pattern through a filter: 
101      *      Currently this only applies to &amp;' -> &
102      */
103     function san(html, pattern){
104     
105         var ret = "";
106         var remainingString;
107         var hrefIndex;
108         for(var i=0; i<html.length; i++){
109                 remainingString = html.substring(i);
110                 hrefIndex = remainingString.search(pattern);
111                 if( hrefIndex === 0 ){
112                     // actually sanitize the pattern, i.e. href="[sanitize-candidate]"
113                     // must be encapsulated within quotes, "
114                (function(){
115                    // get the start of what we will sanitize
116                    var startIndex = remainingString.indexOf("\"");
117                    // and the end 
118                    var endIndex = remainingString.indexOf("\"",startIndex+1);
119                    // get the data to sanitize
120                    var newHREF = html.substring(i+startIndex+1, i+endIndex+1);
121                    // here we actually perform the replacement
122                    newHREF = newHREF.replace(/&amp;/g, '&');
123                    // add the pattern + the new data + a closing quote
124                    var regExpStartLen = "/".length;
125                    var regExpFlagsLen = "/i".length;
126                    ret += String(pattern).substring( regExpStartLen, String(pattern).length - regExpFlagsLen)
127                         + newHREF;
128                    i += endIndex;
129                })();
130                continue;
131                 } else { 
132                     // if we have another href, copy everything until that href index
133                     if( hrefIndex > 0 ) {
134                         ret += html.substring(i, hrefIndex);
135                         i = hrefIndex-1;
136                     } else { 
137                         // otherwise just add the remaining chars and stop trying to sanitize
138                         ret += html.substring(i);
139                         break;
140                     }
141                 }
142         }
143         return ret;
144         
145     };
146     
147     //
148     // public methods
149     //
150     doInline = function(input) {
151         return inlinify(input);
152     }
153     
154 })();