Roo/htmleditor/TidyWriter.js
[roojs1] / Roo / htmleditor / TidyWriter.js
1 /***
2  * This is based loosely on tinymce 
3  * @class Roo.htmleditor.TidyWriter
4  * https://github.com/thorn0/tinymce.html/blob/master/tinymce.html.js
5  */
6
7 Roo.htmleditor.TidyWriter = function(settings)
8 {
9     
10     // indent, indentBefore, indentAfter, encode, htmlOutput, html = [];
11     Roo.apply(this, settings);
12     this.html = [];
13     
14     this.indentBefore =this.makeMap(settings.indent_before || '');
15     this.indentAfter = this.makeMap(settings.indent_after || '');
16     this.encode = Roo.htmleditor.TidyEntities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);
17     this.htmlOutput = 'html' == settings.element_format;
18 }
19 Roo.htmleditor.TidyWriter.prototype = {
20
21
22
23     makeMap : function (items, delim, map) {
24                 var i;
25                 items = items || [];
26                 delim = delim || ',';
27                 if (typeof items == "string") {
28                         items = items.split(delim);
29                 }
30                 map = map || {};
31                 i = items.length;
32                 while (i--) {
33                         map[items[i]] = {};
34                 }
35                 return map;
36         },
37
38
39     indent : 0,
40     indentBefore : false,
41     indentAfter : false,
42     encode : false,
43     htmlOutput : false,
44     
45             /**
46     * Writes the a start element such as <p id="a">.
47     *
48     * @method start
49     * @param {String} name Name of the element.
50     * @param {Array} attrs Optional attribute array or undefined if it hasn't any.
51     * @param {Boolean} empty Optional empty state if the tag should end like <br />.
52     */
53     start: function(name, attrs, empty) {
54        var i, l, attr, value;
55        if (this.indent && this.indentBefore[name] && this.html.length > 0) {
56            this.value = this.html[this.html.length - 1];
57            value.length > 0 && '\n' !== value && this.html.push('\n');
58        }
59        this.html.push('<', name);
60        if (attrs) {
61            for (i = 0, l = attrs.length; i < l; i++) {
62                attr = attrs[i];
63                this.html.push(' ', attr.name, '="', this.encode(attr.value, true), '"');
64            }
65        }
66        this.html[this.html.length] = !empty || this.htmlOutput ? '>' : ' />';
67        if (empty && this.indent && this.indentAfter[name] && this.html.length > 0) {
68            value = this.html[this.html.length - 1];
69            value.length > 0 && '\n' !== value && this.html.push('\n');
70        }
71     },
72     /**
73      * Writes the a end element such as </p>.
74      *
75      * @method end
76      * @param {String} name Name of the element.
77      */
78     end: function(name) {
79         var value;
80          
81         this.html.push('</', name, '>');
82         if (this.indent && this.indentAfter[name] && this.html.length > 0) {
83             value = this.html[this.html.length - 1];
84             value.length > 0 && '\n' !== value && this.html.push('\n');
85         }
86     },
87     /**
88      * Writes a text node.
89      *
90      * @method text
91      * @param {String} text String to write out.
92      * @param {Boolean} raw Optional raw state if true the contents wont get encoded.
93      */
94     text: function(text, raw) {
95         text.length > 0 && (this.html[this.html.length] = raw ? text : encode(text));
96     },
97     /**
98      * Writes a cdata node such as <![CDATA[data]]>.
99      *
100      * @method cdata
101      * @param {String} text String to write out inside the cdata.
102      */
103     cdata: function(text) {
104         this.html.push('<![CDATA[', text, ']]>');
105     },
106     /**
107     * Writes a comment node such as <!-- Comment -->.
108     *
109     * @method cdata
110     * @param {String} text String to write out inside the comment.
111     */
112    comment: function(text) {
113        this.html.push('<!--', text, '-->');
114    },
115     /**
116      * Writes a PI node such as <?xml attr="value" ?>.
117      *
118      * @method pi
119      * @param {String} name Name of the pi.
120      * @param {String} text String to write out inside the pi.
121      */
122     pi: function(name, text) {
123         text ? this.html.push('<?', name, ' ', this.encode(text), '?>') : this.html.push('<?', name, '?>');
124         this.indent && this.html.push('\n');
125     },
126     /**
127      * Writes a doctype node such as <!DOCTYPE data>.
128      *
129      * @method doctype
130      * @param {String} text String to write out inside the doctype.
131      */
132     doctype: function(text) {
133         this.html.push('<!DOCTYPE', text, '>', this.indent ? '\n' : '');
134     },
135     /**
136      * Resets the internal buffer if one wants to reuse the writer.
137      *
138      * @method reset
139      */
140     reset: function() {
141         this.html.length = 0;
142     },
143     /**
144      * Returns the contents that got serialized.
145      *
146      * @method getContent
147      * @return {String} HTML contents that got written down.
148      */
149     getContent: function() {
150         return this.html.join('').replace(/\n$/, '');
151     }
152
153 };