]> git.immae.eu Git - perso/Immae/Projets/packagist/piedsjaloux-ckeditor-component.git/blob - sources/plugins/htmlwriter/plugin.js
Initial commit
[perso/Immae/Projets/packagist/piedsjaloux-ckeditor-component.git] / sources / plugins / htmlwriter / plugin.js
1 /**
2 * @license Copyright (c) 2003-2016, 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( /&amp;/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` &ndash; indent the element content.
298 * * `breakBeforeOpen` &ndash; break line before the opener tag for this element.
299 * * `breakAfterOpen` &ndash; break line after the opener tag for this element.
300 * * `breakBeforeClose` &ndash; break line before the closer tag for this element.
301 * * `breakAfterClose` &ndash; 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 `'&amp;'` 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 `'&amp;'`
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 */