Roo/htmleditor/TidySerializer.js
[roojs1] / Roo / htmleditor / TidySerializer.js
1
2 /***
3  * This is based loosely on tinymce 
4  * @class Roo.htmleditor.TidySerializer
5  * https://github.com/thorn0/tinymce.html/blob/master/tinymce.html.js
6  * @constructor
7  * @method Serializer
8  * @param {Object} settings Name/value settings object.
9  * @param {tinymce.html.Schema} schema Schema instance to use.
10  */
11
12
13 Roo.htmleditor.TidySerializer = function(settings)
14 {
15     Roo.apply(this.settings);
16     
17     this.writer = new Roo.htmleditor.TidyWriter(settings);
18     
19     //settings.validate = !('validate' in settings) || settings.validate;
20     //      self.schema = schema = schema || new Schema();
21
22 };
23 Roo.apply(Roo.htmleditor.TidySerializer.prototype, {
24     
25     /**
26      * @param {boolean} inner do the inner of the node.
27      */
28     inner : false,
29     
30     /**
31     * Serializes the specified node into a string.
32     *
33     * @example
34     * new tinymce.html.Serializer().serialize(new tinymce.html.DomParser().parse('<p>text</p>'));
35     * @method serialize
36     * @param {DomElement} node Node instance to serialize.
37     * @return {String} String with HTML based on DOM tree.
38     */
39     serialize : function(node) {
40         
41         // = settings.validate;
42         var writer = this.writer;
43         var walk  = this.walk;
44         this.handlers = {
45             // #text
46             3: function(node) {
47                 writer.text(node.value, node.raw);
48             },
49             // #comment
50             8: function(node) {
51                 writer.comment(node.value);
52             },
53             // Processing instruction
54             7: function(node) {
55                 writer.pi(node.name, node.value);
56             },
57             // Doctype
58             10: function(node) {
59                 writer.doctype(node.value);
60             },
61             // CDATA
62             4: function(node) {
63                 writer.cdata(node.value);
64             },
65             // Document fragment
66             11: function(node) {
67                 node = node.firstChild;
68                 if (!node) {
69                     return;
70                 }
71                 while(node) {
72                     walk(node);
73                     node = node.nextSibling
74                 }
75             }
76         };
77         writer.reset();
78         1 != node.nodeType || this.inner ? handlers[11](node) : walk(node);
79         return writer.getContent();
80     },
81
82     walk: function(node) {
83         var name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule, handler = handlers[node.type];
84         if (handler) {
85             handler(node);
86         } else {
87             name = node.name;
88             isEmpty = node.shortEnded;
89             attrs = node.attributes;
90             // Sort attributes
91             if (validate && attrs && attrs.length > 1) {
92                 sortedAttrs = [];
93                 sortedAttrs.map = {};
94                 elementRule = schema.getElementRule(node.name);
95                 if (elementRule) {
96                     for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {
97                         attrName = elementRule.attributesOrder[i];
98                         if (attrName in attrs.map) {
99                             attrValue = attrs.map[attrName];
100                             sortedAttrs.map[attrName] = attrValue;
101                             sortedAttrs.push({
102                                 name: attrName,
103                                 value: attrValue
104                             });
105                         }
106                     }
107                     for (i = 0, l = attrs.length; i < l; i++) {
108                         attrName = attrs[i].name;
109                         if (!(attrName in sortedAttrs.map)) {
110                             attrValue = attrs.map[attrName];
111                             sortedAttrs.map[attrName] = attrValue;
112                             sortedAttrs.push({
113                                 name: attrName,
114                                 value: attrValue
115                             });
116                         }
117                     }
118                     attrs = sortedAttrs;
119                 }
120             }
121             writer.start(node.name, attrs, isEmpty);
122             if (!isEmpty) {
123                 if (node = node.firstChild) {
124                     do {
125                         walk(node);
126                     } while (node = node.next);
127                 }
128                 writer.end(name);
129             }
130         }
131     }
132     // Serialize element and treat all non elements as fragments
133    
134 };
135 };
136