c13a5a7b81209c510b76aeeca431e4b6b4772613
[roojs1] / Roo / htmleditor / Tidy.js
1
2 /**
3  * @class Roo.htmleditor.Tidy
4  * Tidy HTML 
5  * @cfg {Roo.HtmlEditorCore} core the editor.
6  * @constructor
7  * Create a new Filter.
8  * @param {Object} config Configuration options
9  */
10
11
12 Roo.htmleditor.Tidy = function(cfg) {
13     Roo.apply(this, cfg);
14     
15     this.core.doc.body.innerHTML = this.tidy(this.core.doc.body, '');
16      
17 }
18
19 Roo.htmleditor.Tidy.toString = function(node)
20 {
21     return Roo.htmleditor.Tidy.prototype.tidy(node, '');
22 }
23
24 Roo.htmleditor.Tidy.prototype = {
25     
26     
27     wrap : function(s) {
28         return s.replace(/\n/g, " ").replace(/(?![^\n]{1,80}$)([^\n]{1,80})\s/g, '$1\n');
29     },
30
31     
32     tidy : function(node, indent) {
33      
34         if  (node.nodeType == 3) {
35             // text.
36             
37             
38             return indent === false ? node.nodeValue : this.wrap(node.nodeValue.trim()).split("\n").join("\n" + indent);
39                 
40             
41         }
42         
43         if  (node.nodeType != 1) {
44             return '';
45         }
46         
47         
48         
49         if (node.tagName == 'BODY') {
50             
51             return this.cn(node, '');
52         }
53              
54              // Prints the node tagName, such as <A>, <IMG>, etc
55         var ret = "<" + node.tagName +  this.attr(node) ;
56         
57         // elements with no children..
58         if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(node.tagName) > -1) {
59                 return ret + '/>';
60         }
61         ret += '>';
62         
63         
64         var cindent = indent === false ? '' : (indent + '  ');
65         // tags where we will not pad the children.. (inline text tags etc..)
66         if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN', 'B', 'I', 'S'].indexOf(node.tagName) > -1) { // or code?
67             cindent = false;
68             
69             
70         }
71         
72         var cn = this.cn(node, cindent );
73         
74         return ret + cn  + '</' + node.tagName + '>';
75         
76     },
77     cn: function(node, indent)
78     {
79         var ret = [];
80         
81         var ar = Array.from(node.childNodes);
82         for (var i = 0 ; i < ar.length ; i++) {
83             
84             
85             
86             if (indent !== false   // indent==false preservies everything
87                 && i > 0
88                 && ar[i].nodeType == 3 
89                 && ar[i].nodeValue.length > 0
90                 && ar[i].nodeValue.match(/^\s+/)
91             ) {
92                 if (ret.length && ret[ret.length-1] == "\n" + indent) {
93                     ret.pop(); // remove line break from last?
94                 }
95                 
96                 ret.push(" "); // add a space if i'm a text item with a space at the front, as tidy will strip spaces.
97             }
98             if (indent !== false
99                 && ar[i].nodeType == 1 // element - and indent is not set... 
100             ) {
101                 ret.push("\n" + indent); 
102             }
103             
104             ret.push(this.tidy(ar[i], indent));
105             // text + trailing indent 
106             if (indent !== false
107                 && ar[i].nodeType == 3
108                 && ar[i].nodeValue.length > 0
109                 && ar[i].nodeValue.match(/\s+$/)
110             ){
111                 ret.push("\n" + indent); 
112             }
113             
114             
115             
116             
117         }
118         // what if all text?
119         
120         
121         return ret.join('');
122     },
123     
124          
125         
126     attr : function(node)
127     {
128         var attr = [];
129         for(i = 0; i < node.attributes.length;i++) {
130             
131             // skip empty values?
132             if (!node.attributes.item(i).value.length) {
133                 continue;
134             }
135             attr.push(  node.attributes.item(i).name + '="' +
136                     Roo.util.Format.htmlEncode(node.attributes.item(i).value) + '"'
137             );
138         }
139         return attr.length ? (' ' + attr.join(' ') ) : '';
140         
141     }
142     
143     
144     
145 }