diff options
Diffstat (limited to 'sources/plugins/htmlwriter/plugin.js')
-rw-r--r-- | sources/plugins/htmlwriter/plugin.js | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/sources/plugins/htmlwriter/plugin.js b/sources/plugins/htmlwriter/plugin.js new file mode 100644 index 00000000..687b2bf0 --- /dev/null +++ b/sources/plugins/htmlwriter/plugin.js | |||
@@ -0,0 +1,359 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | CKEDITOR.plugins.add( 'htmlwriter', { | ||
7 | init: function( editor ) { | ||
8 | var writer = new CKEDITOR.htmlWriter(); | ||
9 | |||
10 | writer.forceSimpleAmpersand = editor.config.forceSimpleAmpersand; | ||
11 | writer.indentationChars = editor.config.dataIndentationChars || '\t'; | ||
12 | |||
13 | // Overwrite default basicWriter initialized in hmtlDataProcessor constructor. | ||
14 | editor.dataProcessor.writer = writer; | ||
15 | } | ||
16 | } ); | ||
17 | |||
18 | /** | ||
19 | * The class used to write HTML data. | ||
20 | * | ||
21 | * var writer = new CKEDITOR.htmlWriter(); | ||
22 | * writer.openTag( 'p' ); | ||
23 | * writer.attribute( 'class', 'MyClass' ); | ||
24 | * writer.openTagClose( 'p' ); | ||
25 | * writer.text( 'Hello' ); | ||
26 | * writer.closeTag( 'p' ); | ||
27 | * alert( writer.getHtml() ); // '<p class="MyClass">Hello</p>' | ||
28 | * | ||
29 | * @class | ||
30 | * @extends CKEDITOR.htmlParser.basicWriter | ||
31 | */ | ||
32 | CKEDITOR.htmlWriter = CKEDITOR.tools.createClass( { | ||
33 | base: CKEDITOR.htmlParser.basicWriter, | ||
34 | |||
35 | /** | ||
36 | * Creates an `htmlWriter` class instance. | ||
37 | * | ||
38 | * @constructor | ||
39 | */ | ||
40 | $: function() { | ||
41 | // Call the base contructor. | ||
42 | this.base(); | ||
43 | |||
44 | /** | ||
45 | * The characters to be used for each indentation step. | ||
46 | * | ||
47 | * // Use tab for indentation. | ||
48 | * editorInstance.dataProcessor.writer.indentationChars = '\t'; | ||
49 | */ | ||
50 | this.indentationChars = '\t'; | ||
51 | |||
52 | /** | ||
53 | * The characters to be used to close "self-closing" elements, like `<br>` or `<img>`. | ||
54 | * | ||
55 | * // Use HTML4 notation for self-closing elements. | ||
56 | * editorInstance.dataProcessor.writer.selfClosingEnd = '>'; | ||
57 | */ | ||
58 | this.selfClosingEnd = ' />'; | ||
59 | |||
60 | /** | ||
61 | * The characters to be used for line breaks. | ||
62 | * | ||
63 | * // Use CRLF for line breaks. | ||
64 | * editorInstance.dataProcessor.writer.lineBreakChars = '\r\n'; | ||
65 | */ | ||
66 | this.lineBreakChars = '\n'; | ||
67 | |||
68 | this.sortAttributes = 1; | ||
69 | |||
70 | this._.indent = 0; | ||
71 | this._.indentation = ''; | ||
72 | // Indicate preformatted block context status. (#5789) | ||
73 | this._.inPre = 0; | ||
74 | this._.rules = {}; | ||
75 | |||
76 | var dtd = CKEDITOR.dtd; | ||
77 | |||
78 | for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) { | ||
79 | this.setRules( e, { | ||
80 | indent: !dtd[ e ][ '#' ], | ||
81 | breakBeforeOpen: 1, | ||
82 | breakBeforeClose: !dtd[ e ][ '#' ], | ||
83 | breakAfterClose: 1, | ||
84 | needsSpace: ( e in dtd.$block ) && !( e in { li: 1, dt: 1, dd: 1 } ) | ||
85 | } ); | ||
86 | } | ||
87 | |||
88 | this.setRules( 'br', { breakAfterOpen: 1 } ); | ||
89 | |||
90 | this.setRules( 'title', { | ||
91 | indent: 0, | ||
92 | breakAfterOpen: 0 | ||
93 | } ); | ||
94 | |||
95 | this.setRules( 'style', { | ||
96 | indent: 0, | ||
97 | breakBeforeClose: 1 | ||
98 | } ); | ||
99 | |||
100 | this.setRules( 'pre', { | ||
101 | breakAfterOpen: 1, // Keep line break after the opening tag | ||
102 | indent: 0 // Disable indentation on <pre>. | ||
103 | } ); | ||
104 | }, | ||
105 | |||
106 | proto: { | ||
107 | /** | ||
108 | * Writes the tag opening part for an opener tag. | ||
109 | * | ||
110 | * // Writes '<p'. | ||
111 | * writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } ); | ||
112 | * | ||
113 | * @param {String} tagName The element name for this tag. | ||
114 | * @param {Object} attributes The attributes defined for this tag. The | ||
115 | * attributes could be used to inspect the tag. | ||
116 | */ | ||
117 | openTag: function( tagName ) { | ||
118 | var rules = this._.rules[ tagName ]; | ||
119 | |||
120 | if ( this._.afterCloser && rules && rules.needsSpace && this._.needsSpace ) | ||
121 | this._.output.push( '\n' ); | ||
122 | |||
123 | if ( this._.indent ) | ||
124 | this.indentation(); | ||
125 | // Do not break if indenting. | ||
126 | else if ( rules && rules.breakBeforeOpen ) { | ||
127 | this.lineBreak(); | ||
128 | this.indentation(); | ||
129 | } | ||
130 | |||
131 | this._.output.push( '<', tagName ); | ||
132 | |||
133 | this._.afterCloser = 0; | ||
134 | }, | ||
135 | |||
136 | /** | ||
137 | * Writes the tag closing part for an opener tag. | ||
138 | * | ||
139 | * // Writes '>'. | ||
140 | * writer.openTagClose( 'p', false ); | ||
141 | * | ||
142 | * // Writes ' />'. | ||
143 | * writer.openTagClose( 'br', true ); | ||
144 | * | ||
145 | * @param {String} tagName The element name for this tag. | ||
146 | * @param {Boolean} isSelfClose Indicates that this is a self-closing tag, | ||
147 | * like `<br>` or `<img>`. | ||
148 | */ | ||
149 | openTagClose: function( tagName, isSelfClose ) { | ||
150 | var rules = this._.rules[ tagName ]; | ||
151 | |||
152 | if ( isSelfClose ) { | ||
153 | this._.output.push( this.selfClosingEnd ); | ||
154 | |||
155 | if ( rules && rules.breakAfterClose ) | ||
156 | this._.needsSpace = rules.needsSpace; | ||
157 | } else { | ||
158 | this._.output.push( '>' ); | ||
159 | |||
160 | if ( rules && rules.indent ) | ||
161 | this._.indentation += this.indentationChars; | ||
162 | } | ||
163 | |||
164 | if ( rules && rules.breakAfterOpen ) | ||
165 | this.lineBreak(); | ||
166 | tagName == 'pre' && ( this._.inPre = 1 ); | ||
167 | }, | ||
168 | |||
169 | /** | ||
170 | * Writes an attribute. This function should be called after opening the | ||
171 | * tag with {@link #openTagClose}. | ||
172 | * | ||
173 | * // Writes ' class="MyClass"'. | ||
174 | * writer.attribute( 'class', 'MyClass' ); | ||
175 | * | ||
176 | * @param {String} attName The attribute name. | ||
177 | * @param {String} attValue The attribute value. | ||
178 | */ | ||
179 | attribute: function( attName, attValue ) { | ||
180 | |||
181 | if ( typeof attValue == 'string' ) { | ||
182 | this.forceSimpleAmpersand && ( attValue = attValue.replace( /&/g, '&' ) ); | ||
183 | // Browsers don't always escape special character in attribute values. (#4683, #4719). | ||
184 | attValue = CKEDITOR.tools.htmlEncodeAttr( attValue ); | ||
185 | } | ||
186 | |||
187 | this._.output.push( ' ', attName, '="', attValue, '"' ); | ||
188 | }, | ||
189 | |||
190 | /** | ||
191 | * Writes a closer tag. | ||
192 | * | ||
193 | * // Writes '</p>'. | ||
194 | * writer.closeTag( 'p' ); | ||
195 | * | ||
196 | * @param {String} tagName The element name for this tag. | ||
197 | */ | ||
198 | closeTag: function( tagName ) { | ||
199 | var rules = this._.rules[ tagName ]; | ||
200 | |||
201 | if ( rules && rules.indent ) | ||
202 | this._.indentation = this._.indentation.substr( this.indentationChars.length ); | ||
203 | |||
204 | if ( this._.indent ) | ||
205 | this.indentation(); | ||
206 | // Do not break if indenting. | ||
207 | else if ( rules && rules.breakBeforeClose ) { | ||
208 | this.lineBreak(); | ||
209 | this.indentation(); | ||
210 | } | ||
211 | |||
212 | this._.output.push( '</', tagName, '>' ); | ||
213 | tagName == 'pre' && ( this._.inPre = 0 ); | ||
214 | |||
215 | if ( rules && rules.breakAfterClose ) { | ||
216 | this.lineBreak(); | ||
217 | this._.needsSpace = rules.needsSpace; | ||
218 | } | ||
219 | |||
220 | this._.afterCloser = 1; | ||
221 | }, | ||
222 | |||
223 | /** | ||
224 | * Writes text. | ||
225 | * | ||
226 | * // Writes 'Hello Word'. | ||
227 | * writer.text( 'Hello Word' ); | ||
228 | * | ||
229 | * @param {String} text The text value | ||
230 | */ | ||
231 | text: function( text ) { | ||
232 | if ( this._.indent ) { | ||
233 | this.indentation(); | ||
234 | !this._.inPre && ( text = CKEDITOR.tools.ltrim( text ) ); | ||
235 | } | ||
236 | |||
237 | this._.output.push( text ); | ||
238 | }, | ||
239 | |||
240 | /** | ||
241 | * Writes a comment. | ||
242 | * | ||
243 | * // Writes "<!-- My comment -->". | ||
244 | * writer.comment( ' My comment ' ); | ||
245 | * | ||
246 | * @param {String} comment The comment text. | ||
247 | */ | ||
248 | comment: function( comment ) { | ||
249 | if ( this._.indent ) | ||
250 | this.indentation(); | ||
251 | |||
252 | this._.output.push( '<!--', comment, '-->' ); | ||
253 | }, | ||
254 | |||
255 | /** | ||
256 | * Writes a line break. It uses the {@link #lineBreakChars} property for it. | ||
257 | * | ||
258 | * // Writes '\n' (e.g.). | ||
259 | * writer.lineBreak(); | ||
260 | */ | ||
261 | lineBreak: function() { | ||
262 | if ( !this._.inPre && this._.output.length > 0 ) | ||
263 | this._.output.push( this.lineBreakChars ); | ||
264 | this._.indent = 1; | ||
265 | }, | ||
266 | |||
267 | /** | ||
268 | * Writes the current indentation character. It uses the {@link #indentationChars} | ||
269 | * property, repeating it for the current indentation steps. | ||
270 | * | ||
271 | * // Writes '\t' (e.g.). | ||
272 | * writer.indentation(); | ||
273 | */ | ||
274 | indentation: function() { | ||
275 | if ( !this._.inPre && this._.indentation ) | ||
276 | this._.output.push( this._.indentation ); | ||
277 | this._.indent = 0; | ||
278 | }, | ||
279 | |||
280 | /** | ||
281 | * Empties the current output buffer. It also brings back the default | ||
282 | * values of the writer flags. | ||
283 | * | ||
284 | * writer.reset(); | ||
285 | */ | ||
286 | reset: function() { | ||
287 | this._.output = []; | ||
288 | this._.indent = 0; | ||
289 | this._.indentation = ''; | ||
290 | this._.afterCloser = 0; | ||
291 | this._.inPre = 0; | ||
292 | }, | ||
293 | |||
294 | /** | ||
295 | * Sets formatting rules for a given element. Possible rules are: | ||
296 | * | ||
297 | * * `indent` – indent the element content. | ||
298 | * * `breakBeforeOpen` – break line before the opener tag for this element. | ||
299 | * * `breakAfterOpen` – break line after the opener tag for this element. | ||
300 | * * `breakBeforeClose` – break line before the closer tag for this element. | ||
301 | * * `breakAfterClose` – break line after the closer tag for this element. | ||
302 | * | ||
303 | * All rules default to `false`. Each function call overrides rules that are | ||
304 | * already present, leaving the undefined ones untouched. | ||
305 | * | ||
306 | * By default, all elements available in the {@link CKEDITOR.dtd#$block}, | ||
307 | * {@link CKEDITOR.dtd#$listItem}, and {@link CKEDITOR.dtd#$tableContent} | ||
308 | * lists have all the above rules set to `true`. Additionaly, the `<br>` | ||
309 | * element has the `breakAfterOpen` rule set to `true`. | ||
310 | * | ||
311 | * // Break line before and after "img" tags. | ||
312 | * writer.setRules( 'img', { | ||
313 | * breakBeforeOpen: true | ||
314 | * breakAfterOpen: true | ||
315 | * } ); | ||
316 | * | ||
317 | * // Reset the rules for the "h1" tag. | ||
318 | * writer.setRules( 'h1', {} ); | ||
319 | * | ||
320 | * @param {String} tagName The name of the element for which the rules are set. | ||
321 | * @param {Object} rules An object containing the element rules. | ||
322 | */ | ||
323 | setRules: function( tagName, rules ) { | ||
324 | var currentRules = this._.rules[ tagName ]; | ||
325 | |||
326 | if ( currentRules ) | ||
327 | CKEDITOR.tools.extend( currentRules, rules, true ); | ||
328 | else | ||
329 | this._.rules[ tagName ] = rules; | ||
330 | } | ||
331 | } | ||
332 | } ); | ||
333 | |||
334 | /** | ||
335 | * Whether to force using `'&'` instead of `'&'` in element attributes | ||
336 | * values. It is not recommended to change this setting for compliance with the | ||
337 | * W3C XHTML 1.0 standards ([C.12, XHTML 1.0](http://www.w3.org/TR/xhtml1/#C_12)). | ||
338 | * | ||
339 | * // Use `'&'` instead of `'&'` | ||
340 | * CKEDITOR.config.forceSimpleAmpersand = true; | ||
341 | * | ||
342 | * @cfg {Boolean} [forceSimpleAmpersand=false] | ||
343 | * @member CKEDITOR.config | ||
344 | */ | ||
345 | |||
346 | /** | ||
347 | * The characters to be used for indenting HTML output produced by the editor. | ||
348 | * Using characters different from `' '` (space) and `'\t'` (tab) is not recommended | ||
349 | * as it will mess the code. | ||
350 | * | ||
351 | * // No indentation. | ||
352 | * CKEDITOR.config.dataIndentationChars = ''; | ||
353 | * | ||
354 | * // Use two spaces for indentation. | ||
355 | * CKEDITOR.config.dataIndentationChars = ' '; | ||
356 | * | ||
357 | * @cfg {String} [dataIndentationChars='\t'] | ||
358 | * @member CKEDITOR.config | ||
359 | */ | ||