1 | /* |
---|
2 | * FCKeditor - The text editor for Internet - http://www.fckeditor.net |
---|
3 | * Copyright (C) 2003-2007 Frederico Caldeira Knabben |
---|
4 | * |
---|
5 | * == BEGIN LICENSE == |
---|
6 | * |
---|
7 | * Licensed under the terms of any of the following licenses at your |
---|
8 | * choice: |
---|
9 | * |
---|
10 | * - GNU General Public License Version 2 or later (the "GPL") |
---|
11 | * http://www.gnu.org/licenses/gpl.html |
---|
12 | * |
---|
13 | * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") |
---|
14 | * http://www.gnu.org/licenses/lgpl.html |
---|
15 | * |
---|
16 | * - Mozilla Public License Version 1.1 or later (the "MPL") |
---|
17 | * http://www.mozilla.org/MPL/MPL-1.1.html |
---|
18 | * |
---|
19 | * == END LICENSE == |
---|
20 | * |
---|
21 | * Main MediaWiki integration plugin. |
---|
22 | * |
---|
23 | * Wikitext syntax reference: |
---|
24 | * http://meta.wikimedia.org/wiki/Help:Wikitext_examples |
---|
25 | * http://meta.wikimedia.org/wiki/Help:Advanced_editing |
---|
26 | * |
---|
27 | * MediaWiki Sandbox: |
---|
28 | * http://meta.wikimedia.org/wiki/Meta:Sandbox |
---|
29 | */ |
---|
30 | |
---|
31 | // Rename the "Source" buttom to "Wikitext". |
---|
32 | FCKToolbarItems.RegisterItem( 'Source', new FCKToolbarButton( 'Source', 'Wikitext', null, FCK_TOOLBARITEM_ICONTEXT, true, true, 1 ) ) ; // JB |
---|
33 | |
---|
34 | // Register our toolbar buttons. |
---|
35 | var tbButton = new FCKToolbarButton( 'MW_Template', 'Template', FCKLang.wikiBtnTemplate ) ; // JB |
---|
36 | tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_template.gif' ; |
---|
37 | FCKToolbarItems.RegisterItem( 'MW_Template', tbButton ) ; |
---|
38 | |
---|
39 | tbButton = new FCKToolbarButton( 'MW_Ref', 'Reference', FCKLang.wikiBtnReference ) ; // JB |
---|
40 | tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_ref.gif' ; |
---|
41 | FCKToolbarItems.RegisterItem( 'MW_Ref', tbButton ) ; |
---|
42 | |
---|
43 | tbButton = new FCKToolbarButton( 'MW_Math', 'Formula', FCKLang.wikiBtnFormula ) ; // JB |
---|
44 | tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_math.gif' ; |
---|
45 | FCKToolbarItems.RegisterItem( 'MW_Math', tbButton ) ; |
---|
46 | |
---|
47 | // Override some dialogs. |
---|
48 | FCKCommands.RegisterCommand( 'MW_Template', new FCKDialogCommand( 'MW_Template', FCKLang.wikiCmdTemplate, FCKConfig.PluginsPath + 'mediawiki/dialogs/template.html', 400, 330 ) ) ; // JB |
---|
49 | FCKCommands.RegisterCommand( 'MW_Ref', new FCKDialogCommand( 'MW_Ref', FCKLang.wikiCmdReference, FCKConfig.PluginsPath + 'mediawiki/dialogs/ref.html', 400, 250 ) ) ; // JB |
---|
50 | FCKCommands.RegisterCommand( 'MW_Math', new FCKDialogCommand( 'MW_Math', FCKLang.wikiCmdFormula, FCKConfig.PluginsPath + 'mediawiki/dialogs/math.html', 400, 300 ) ) ; // JB |
---|
51 | FCKCommands.RegisterCommand( 'Link', new FCKDialogCommand( 'Link', FCKLang.DlgLnkWindowTitle, FCKConfig.PluginsPath + 'mediawiki/dialogs/link.html', 400, 250 ) ) ; |
---|
52 | FCKCommands.RegisterCommand( 'Image', new FCKDialogCommand( 'Image', FCKLang.DlgImgTitle, FCKConfig.PluginsPath + 'mediawiki/dialogs/image.html', 450, 300 ) ) ; |
---|
53 | |
---|
54 | // MediaWiki Wikitext Data Processor implementation. |
---|
55 | FCK.DataProcessor = |
---|
56 | { |
---|
57 | _inPre : false, |
---|
58 | _inLSpace : false, |
---|
59 | |
---|
60 | /* |
---|
61 | * Returns a string representing the HTML format of "data". The returned |
---|
62 | * value will be loaded in the editor. |
---|
63 | * The HTML must be from <html> to </html>, eventually including |
---|
64 | * the DOCTYPE. |
---|
65 | * @param {String} data The data to be converted in the |
---|
66 | * DataProcessor specific format. |
---|
67 | */ |
---|
68 | ConvertToHtml : function( data ) |
---|
69 | { |
---|
70 | // Call the original code. |
---|
71 | return FCKDataProcessor.prototype.ConvertToHtml.call( this, data ) ; |
---|
72 | }, |
---|
73 | |
---|
74 | /* |
---|
75 | * Converts a DOM (sub-)tree to a string in the data format. |
---|
76 | * @param {Object} rootNode The node that contains the DOM tree to be |
---|
77 | * converted to the data format. |
---|
78 | * @param {Boolean} excludeRoot Indicates that the root node must not |
---|
79 | * be included in the conversion, only its children. |
---|
80 | * @param {Boolean} format Indicates that the data must be formatted |
---|
81 | * for human reading. Not all Data Processors may provide it. |
---|
82 | */ |
---|
83 | ConvertToDataFormat : function( rootNode, excludeRoot, ignoreIfEmptyParagraph, format ) |
---|
84 | { |
---|
85 | // rootNode is <body>. |
---|
86 | |
---|
87 | // Normalize the document for text node processing. |
---|
88 | rootNode.normalize() ; |
---|
89 | |
---|
90 | var stringBuilder = new Array() ; |
---|
91 | this._AppendNode( rootNode, stringBuilder ) ; |
---|
92 | return stringBuilder.join( '' ).Trim() ; |
---|
93 | }, |
---|
94 | |
---|
95 | /* |
---|
96 | * Makes any necessary changes to a piece of HTML for insertion in the |
---|
97 | * editor selection position. |
---|
98 | * @param {String} html The HTML to be fixed. |
---|
99 | */ |
---|
100 | FixHtml : function( html ) |
---|
101 | { |
---|
102 | return html ; |
---|
103 | }, |
---|
104 | |
---|
105 | // Collection of element definitions: |
---|
106 | // 0 : Prefix |
---|
107 | // 1 : Suffix |
---|
108 | // 2 : Ignore children |
---|
109 | _BasicElements : { |
---|
110 | body : [ ], |
---|
111 | b : [ "'''", "'''" ], |
---|
112 | strong : [ "'''", "'''" ], |
---|
113 | i : [ "''", "''" ], |
---|
114 | em : [ "''", "''" ], |
---|
115 | p : [ '\n', '\n' ], |
---|
116 | h1 : [ '\n= ', ' =\n' ], |
---|
117 | h2 : [ '\n== ', ' ==\n' ], |
---|
118 | h3 : [ '\n=== ', ' ===\n' ], |
---|
119 | h4 : [ '\n==== ', ' ====\n' ], |
---|
120 | h5 : [ '\n===== ', ' =====\n' ], |
---|
121 | h6 : [ '\n====== ', ' ======\n' ], |
---|
122 | br : [ '<br>', null, true ], |
---|
123 | hr : [ '\n----\n', null, true ] |
---|
124 | } , |
---|
125 | |
---|
126 | // This function is based on FCKXHtml._AppendNode. |
---|
127 | _AppendNode : function( htmlNode, stringBuilder ) |
---|
128 | { |
---|
129 | if ( !htmlNode ) |
---|
130 | return ; |
---|
131 | |
---|
132 | switch ( htmlNode.nodeType ) |
---|
133 | { |
---|
134 | // Element Node. |
---|
135 | case 1 : |
---|
136 | |
---|
137 | // Here we found an element that is not the real element, but a |
---|
138 | // fake one (like the Flash placeholder image), so we must get the real one. |
---|
139 | if ( htmlNode.getAttribute('_fckfakelement') && !htmlNode.getAttribute( '_fck_mw_math' ) ) |
---|
140 | return this._AppendNode( FCK.GetRealElement( htmlNode ), stringBuilder ) ; |
---|
141 | |
---|
142 | // Mozilla insert custom nodes in the DOM. |
---|
143 | if ( FCKBrowserInfo.IsGecko && htmlNode.hasAttribute('_moz_editor_bogus_node') ) |
---|
144 | return ; |
---|
145 | |
---|
146 | // This is for elements that are instrumental to FCKeditor and |
---|
147 | // must be removed from the final HTML. |
---|
148 | if ( htmlNode.getAttribute('_fcktemp') ) |
---|
149 | return ; |
---|
150 | |
---|
151 | // Get the element name. |
---|
152 | var sNodeName = htmlNode.tagName.toLowerCase() ; |
---|
153 | |
---|
154 | if ( FCKBrowserInfo.IsIE ) |
---|
155 | { |
---|
156 | // IE doens't include the scope name in the nodeName. So, add the namespace. |
---|
157 | if ( htmlNode.scopeName && htmlNode.scopeName != 'HTML' && htmlNode.scopeName != 'FCK' ) |
---|
158 | sNodeName = htmlNode.scopeName.toLowerCase() + ':' + sNodeName ; |
---|
159 | } |
---|
160 | else |
---|
161 | { |
---|
162 | if ( sNodeName.StartsWith( 'fck:' ) ) |
---|
163 | sNodeName = sNodeName.Remove( 0,4 ) ; |
---|
164 | } |
---|
165 | |
---|
166 | // Check if the node name is valid, otherwise ignore this tag. |
---|
167 | // If the nodeName starts with a slash, it is a orphan closing tag. |
---|
168 | // On some strange cases, the nodeName is empty, even if the node exists. |
---|
169 | if ( !FCKRegexLib.ElementName.test( sNodeName ) ) |
---|
170 | return ; |
---|
171 | |
---|
172 | if ( sNodeName == 'br' && ( this._inPre || this._inLSpace ) ) |
---|
173 | { |
---|
174 | stringBuilder.push( "\n" ) ; |
---|
175 | if ( this._inLSpace ) |
---|
176 | stringBuilder.push( " " ) ; |
---|
177 | return ; |
---|
178 | } |
---|
179 | |
---|
180 | // Remove the <br> if it is a bogus node. |
---|
181 | if ( sNodeName == 'br' && htmlNode.getAttribute( 'type', 2 ) == '_moz' ) |
---|
182 | return ; |
---|
183 | |
---|
184 | // The already processed nodes must be marked to avoid then to be duplicated (bad formatted HTML). |
---|
185 | // So here, the "mark" is checked... if the element is Ok, then mark it. |
---|
186 | if ( htmlNode._fckxhtmljob && htmlNode._fckxhtmljob == FCKXHtml.CurrentJobNum ) |
---|
187 | return ; |
---|
188 | |
---|
189 | var basicElement = this._BasicElements[ sNodeName ] ; |
---|
190 | if ( basicElement ) |
---|
191 | { |
---|
192 | if ( basicElement[0] ) |
---|
193 | stringBuilder.push( basicElement[0] ) ; |
---|
194 | |
---|
195 | if ( !basicElement[2] ) |
---|
196 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
197 | |
---|
198 | if ( basicElement[1] ) |
---|
199 | stringBuilder.push( basicElement[1] ) ; |
---|
200 | } |
---|
201 | else |
---|
202 | { |
---|
203 | switch ( sNodeName ) |
---|
204 | { |
---|
205 | case 'ol' : |
---|
206 | case 'ul' : |
---|
207 | var isFirstLevel = !htmlNode.parentNode.nodeName.IEquals( 'ul', 'ol', 'li' ) ; |
---|
208 | |
---|
209 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
210 | |
---|
211 | if ( isFirstLevel ) |
---|
212 | stringBuilder.push( '\n' ) ; |
---|
213 | |
---|
214 | break ; |
---|
215 | |
---|
216 | case 'li' : |
---|
217 | |
---|
218 | stringBuilder.push( '\n' ) ; |
---|
219 | |
---|
220 | var listPrefix = '' ; |
---|
221 | var parent = htmlNode.parentNode ; |
---|
222 | |
---|
223 | while ( parent ) |
---|
224 | { |
---|
225 | if ( parent.nodeName.toLowerCase() == 'ul' ) |
---|
226 | listPrefix = '*' + listPrefix ; |
---|
227 | else if ( parent.nodeName.toLowerCase() == 'ol' ) |
---|
228 | listPrefix = '#' + listPrefix ; |
---|
229 | else if ( parent.nodeName.toLowerCase() != 'li' ) |
---|
230 | break ; |
---|
231 | |
---|
232 | parent = parent.parentNode ; |
---|
233 | } |
---|
234 | |
---|
235 | stringBuilder.push( listPrefix ) ; |
---|
236 | stringBuilder.push( ' ' ) ; |
---|
237 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
238 | |
---|
239 | break ; |
---|
240 | |
---|
241 | case 'a' : |
---|
242 | |
---|
243 | // Get the actual Link href. |
---|
244 | var href = htmlNode.getAttribute( '_fcksavedurl' ) ; |
---|
245 | var hrefType = htmlNode.getAttribute( '_fck_mw_type' ) || '' ; |
---|
246 | |
---|
247 | if ( href == null ) |
---|
248 | href = htmlNode.getAttribute( 'href' , 2 ) || '' ; |
---|
249 | |
---|
250 | if ( hrefType == "media" ) |
---|
251 | { |
---|
252 | var isWikiUrl = true ; |
---|
253 | stringBuilder.push( '[[Media:' ) ; |
---|
254 | } |
---|
255 | else |
---|
256 | { |
---|
257 | var isWikiUrl = !( href.StartsWith( 'mailto:' ) || /^\w+:\/\//.test( href ) ) ; |
---|
258 | stringBuilder.push( isWikiUrl ? '[[' : '[' ) ; |
---|
259 | } |
---|
260 | stringBuilder.push( href ) ; |
---|
261 | if ( href != htmlNode.innerHTML && htmlNode.innerHTML != '[n]' ) |
---|
262 | { |
---|
263 | stringBuilder.push( isWikiUrl? '|' : ' ' ) ; |
---|
264 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
265 | } |
---|
266 | stringBuilder.push( isWikiUrl ? ']]' : ']' ) ; |
---|
267 | |
---|
268 | break ; |
---|
269 | |
---|
270 | case 'dl' : |
---|
271 | stringBuilder.push( '\n' ) ; |
---|
272 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
273 | if (stringBuilder.length > 0 && !stringBuilder[ stringBuilder.length - 1 ].EndsWith( '\n' )) |
---|
274 | stringBuilder.push( '\n' ) ; |
---|
275 | break ; |
---|
276 | |
---|
277 | case 'dt' : |
---|
278 | stringBuilder.push( ';' ) ; |
---|
279 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
280 | break ; |
---|
281 | |
---|
282 | case 'dd' : |
---|
283 | stringBuilder.push( ':' ) ; |
---|
284 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
285 | stringBuilder.push( '\n' ) ; |
---|
286 | break ; |
---|
287 | |
---|
288 | case 'table' : |
---|
289 | |
---|
290 | var attribs = this._GetAttributesStr( htmlNode ) ; |
---|
291 | |
---|
292 | stringBuilder.push( '\n{|' ) ; |
---|
293 | if ( attribs.length > 0 ) |
---|
294 | stringBuilder.push( attribs ) ; |
---|
295 | stringBuilder.push( '\n' ) ; |
---|
296 | |
---|
297 | if ( htmlNode.caption && htmlNode.caption.innerHTML.length > 0 ) |
---|
298 | { |
---|
299 | stringBuilder.push( '|+ ' ) ; |
---|
300 | this._AppendChildNodes( htmlNode.caption, stringBuilder ) ; |
---|
301 | stringBuilder.push( '\n' ) ; |
---|
302 | } |
---|
303 | |
---|
304 | for ( var r = 0 ; r < htmlNode.rows.length ; r++ ) |
---|
305 | { |
---|
306 | attribs = this._GetAttributesStr( htmlNode.rows[r] ) ; |
---|
307 | |
---|
308 | stringBuilder.push( '|-' ) ; |
---|
309 | if ( attribs.length > 0 ) |
---|
310 | stringBuilder.push( attribs ) ; |
---|
311 | stringBuilder.push( '\n' ) ; |
---|
312 | |
---|
313 | for ( var c = 0 ; c < htmlNode.rows[r].cells.length ; c++ ) |
---|
314 | { |
---|
315 | attribs = this._GetAttributesStr( htmlNode.rows[r].cells[c] ) ; |
---|
316 | |
---|
317 | stringBuilder.push( '|' ) ; |
---|
318 | |
---|
319 | if ( attribs.length > 0 ) |
---|
320 | stringBuilder.push( attribs + ' |' ) ; |
---|
321 | |
---|
322 | stringBuilder.push( ' ' ) ; |
---|
323 | |
---|
324 | this._IsInsideCell = true ; |
---|
325 | this._AppendChildNodes( htmlNode.rows[r].cells[c], stringBuilder ) ; |
---|
326 | this._IsInsideCell = false ; |
---|
327 | |
---|
328 | stringBuilder.push( '\n' ) ; |
---|
329 | } |
---|
330 | } |
---|
331 | |
---|
332 | stringBuilder.push( '|}\n' ) ; |
---|
333 | |
---|
334 | break ; |
---|
335 | |
---|
336 | case 'img' : |
---|
337 | |
---|
338 | var formula = htmlNode.getAttribute( '_fck_mw_math' ) ; |
---|
339 | |
---|
340 | if ( formula && formula.length > 0 ) |
---|
341 | { |
---|
342 | stringBuilder.push( '<math>' ) ; |
---|
343 | stringBuilder.push( formula ) ; |
---|
344 | stringBuilder.push( '</math>' ) ; |
---|
345 | return ; |
---|
346 | } |
---|
347 | |
---|
348 | var imgName = htmlNode.getAttribute( '_fck_mw_filename' ) ; |
---|
349 | var imgCaption = htmlNode.getAttribute( 'alt' ) || '' ; |
---|
350 | var imgType = htmlNode.getAttribute( '_fck_mw_type' ) || '' ; |
---|
351 | var imgLocation = htmlNode.getAttribute( '_fck_mw_location' ) || '' ; |
---|
352 | var imgWidth = htmlNode.getAttribute( '_fck_mw_width' ) || '' ; |
---|
353 | var imgHeight = htmlNode.getAttribute( '_fck_mw_height' ) || '' ; |
---|
354 | |
---|
355 | stringBuilder.push( '[[Image:' ) |
---|
356 | stringBuilder.push( imgName ) |
---|
357 | |
---|
358 | if ( imgType.length > 0 ) |
---|
359 | stringBuilder.push( '|' + imgType ) ; |
---|
360 | |
---|
361 | if ( imgLocation.length > 0 ) |
---|
362 | stringBuilder.push( '|' + imgLocation ) ; |
---|
363 | |
---|
364 | if ( imgWidth.length > 0 ) |
---|
365 | { |
---|
366 | stringBuilder.push( '|' + imgWidth ) ; |
---|
367 | |
---|
368 | if ( imgHeight.length > 0 ) |
---|
369 | stringBuilder.push( 'x' + imgHeight ) ; |
---|
370 | |
---|
371 | stringBuilder.push( 'px' ) ; |
---|
372 | } |
---|
373 | |
---|
374 | if ( imgCaption.length > 0 ) |
---|
375 | stringBuilder.push( '|' + imgCaption ) ; |
---|
376 | |
---|
377 | stringBuilder.push( ']]' ) |
---|
378 | |
---|
379 | break ; |
---|
380 | |
---|
381 | case 'span' : |
---|
382 | switch ( htmlNode.className ) |
---|
383 | { |
---|
384 | case 'fck_mw_ref' : |
---|
385 | var refName = htmlNode.getAttribute( 'name' ) ; |
---|
386 | |
---|
387 | stringBuilder.push( '<ref' ) ; |
---|
388 | |
---|
389 | if ( refName && refName.length > 0 ) |
---|
390 | stringBuilder.push( ' name="' + refName + '"' ) ; |
---|
391 | |
---|
392 | if ( htmlNode.innerHTML.length == 0 ) |
---|
393 | stringBuilder.push( ' />' ) ; |
---|
394 | else |
---|
395 | { |
---|
396 | stringBuilder.push( '>' ) ; |
---|
397 | stringBuilder.push( htmlNode.innerHTML ) ; |
---|
398 | stringBuilder.push( '</ref>' ) ; |
---|
399 | } |
---|
400 | return ; |
---|
401 | |
---|
402 | case 'fck_mw_references' : |
---|
403 | stringBuilder.push( '<references />' ) ; |
---|
404 | return ; |
---|
405 | |
---|
406 | case 'fck_mw_template' : |
---|
407 | stringBuilder.push( FCKTools.HTMLDecode(htmlNode.innerHTML) ) ; |
---|
408 | return ; |
---|
409 | |
---|
410 | case 'fck_mw_magic' : |
---|
411 | stringBuilder.push( htmlNode.innerHTML ) ; |
---|
412 | return ; |
---|
413 | |
---|
414 | case 'fck_mw_nowiki' : |
---|
415 | sNodeName = 'nowiki' ; |
---|
416 | break ; |
---|
417 | |
---|
418 | case 'fck_mw_includeonly' : |
---|
419 | sNodeName = 'includeonly' ; |
---|
420 | break ; |
---|
421 | |
---|
422 | case 'fck_mw_noinclude' : |
---|
423 | sNodeName = 'noinclude' ; |
---|
424 | break ; |
---|
425 | |
---|
426 | case 'fck_mw_onlyinclude' : |
---|
427 | sNodeName = 'onlyinclude' ; |
---|
428 | break ; |
---|
429 | } |
---|
430 | |
---|
431 | // Change the node name and fell in the "default" case. |
---|
432 | if ( htmlNode.getAttribute( '_fck_mw_customtag' ) ) |
---|
433 | sNodeName = htmlNode.getAttribute( '_fck_mw_tagname' ) ; |
---|
434 | |
---|
435 | case 'pre' : |
---|
436 | var attribs = this._GetAttributesStr( htmlNode ) ; |
---|
437 | |
---|
438 | if ( htmlNode.className == "_fck_mw_lspace") |
---|
439 | { |
---|
440 | stringBuilder.push( "\n " ) ; |
---|
441 | this._inLSpace = true ; |
---|
442 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
443 | this._inLSpace = false ; |
---|
444 | if ( stringBuilder[stringBuilder.length-2] == "\n" && stringBuilder[stringBuilder.length-1] == " " ) |
---|
445 | stringBuilder.pop() ; |
---|
446 | else |
---|
447 | stringBuilder.push( "\n" ) ; |
---|
448 | } |
---|
449 | else |
---|
450 | { |
---|
451 | stringBuilder.push( '<' ) ; |
---|
452 | stringBuilder.push( sNodeName ) ; |
---|
453 | |
---|
454 | if ( attribs.length > 0 ) |
---|
455 | stringBuilder.push( attribs ) ; |
---|
456 | |
---|
457 | stringBuilder.push( '>' ) ; |
---|
458 | this._inPre = true ; |
---|
459 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
460 | this._inPre = false ; |
---|
461 | stringBuilder.push( '<\/' ) ; |
---|
462 | stringBuilder.push( sNodeName ) ; |
---|
463 | stringBuilder.push( '>' ) ; |
---|
464 | } |
---|
465 | |
---|
466 | break ; |
---|
467 | default : |
---|
468 | var attribs = this._GetAttributesStr( htmlNode ) ; |
---|
469 | |
---|
470 | stringBuilder.push( '<' ) ; |
---|
471 | stringBuilder.push( sNodeName ) ; |
---|
472 | |
---|
473 | if ( attribs.length > 0 ) |
---|
474 | stringBuilder.push( attribs ) ; |
---|
475 | |
---|
476 | stringBuilder.push( '>' ) ; |
---|
477 | this._AppendChildNodes( htmlNode, stringBuilder ) ; |
---|
478 | stringBuilder.push( '<\/' ) ; |
---|
479 | stringBuilder.push( sNodeName ) ; |
---|
480 | stringBuilder.push( '>' ) ; |
---|
481 | break ; |
---|
482 | } |
---|
483 | } |
---|
484 | |
---|
485 | htmlNode._fckxhtmljob = FCKXHtml.CurrentJobNum ; |
---|
486 | return ; |
---|
487 | |
---|
488 | // Text Node. |
---|
489 | case 3 : |
---|
490 | |
---|
491 | var parentIsSpecialTag = htmlNode.parentNode.getAttribute( '_fck_mw_customtag' ) ; |
---|
492 | var textValue = htmlNode.nodeValue; |
---|
493 | |
---|
494 | if ( !parentIsSpecialTag ) |
---|
495 | { |
---|
496 | textValue = textValue.replace( /[\n\t]/g, ' ' ) ; |
---|
497 | textValue = FCKTools.HTMLEncode( textValue ) ; |
---|
498 | textValue = textValue.replace( /\u00A0/g, ' ' ) ; |
---|
499 | |
---|
500 | if ( !htmlNode.previousSibling || |
---|
501 | ( stringBuilder.length > 0 && stringBuilder[ stringBuilder.length - 1 ].EndsWith( '\n' ) ) && !this._inLSpace ) |
---|
502 | { |
---|
503 | textValue = textValue.LTrim() ; |
---|
504 | } |
---|
505 | |
---|
506 | if ( !htmlNode.nextSibling && !this._inLSpace ) |
---|
507 | textValue = textValue.RTrim() ; |
---|
508 | |
---|
509 | textValue = textValue.replace( / {2,}/g, ' ' ) ; |
---|
510 | |
---|
511 | if ( this._inLSpace && textValue.length == 1 && textValue.charCodeAt(0) == 13 ) |
---|
512 | textValue = textValue + " " ; |
---|
513 | |
---|
514 | if ( this._IsInsideCell ) |
---|
515 | textValue = textValue.replace( /\|/g, '|' ) ; |
---|
516 | |
---|
517 | } |
---|
518 | else |
---|
519 | { |
---|
520 | textValue = FCKTools.HTMLDecode( textValue ) ; |
---|
521 | } |
---|
522 | |
---|
523 | stringBuilder.push( textValue ) ; |
---|
524 | return ; |
---|
525 | |
---|
526 | // Comment |
---|
527 | case 8 : |
---|
528 | // IE catches the <!DOTYPE ... > as a comment, but it has no |
---|
529 | // innerHTML, so we can catch it, and ignore it. |
---|
530 | if ( FCKBrowserInfo.IsIE && !htmlNode.innerHTML ) |
---|
531 | return ; |
---|
532 | |
---|
533 | stringBuilder.push( "<!--" ) ; |
---|
534 | |
---|
535 | try { stringBuilder.push( htmlNode.nodeValue ) ; } |
---|
536 | catch (e) { /* Do nothing... probably this is a wrong format comment. */ } |
---|
537 | |
---|
538 | stringBuilder.push( " -->" ) ; |
---|
539 | return ; |
---|
540 | } |
---|
541 | }, |
---|
542 | |
---|
543 | _AppendChildNodes : function( htmlNode, stringBuilder, isBlockElement ) |
---|
544 | { |
---|
545 | var child = htmlNode.firstChild ; |
---|
546 | |
---|
547 | while ( child ) |
---|
548 | { |
---|
549 | this._AppendNode( child, stringBuilder ) ; |
---|
550 | child = child.nextSibling ; |
---|
551 | } |
---|
552 | }, |
---|
553 | |
---|
554 | _GetAttributesStr : function( htmlNode ) |
---|
555 | { |
---|
556 | var attStr = '' ; |
---|
557 | var aAttributes = htmlNode.attributes ; |
---|
558 | |
---|
559 | for ( var n = 0 ; n < aAttributes.length ; n++ ) |
---|
560 | { |
---|
561 | var oAttribute = aAttributes[n] ; |
---|
562 | |
---|
563 | if ( oAttribute.specified ) |
---|
564 | { |
---|
565 | var sAttName = oAttribute.nodeName.toLowerCase() ; |
---|
566 | var sAttValue ; |
---|
567 | |
---|
568 | // Ignore any attribute starting with "_fck". |
---|
569 | if ( sAttName.StartsWith( '_fck' ) ) |
---|
570 | continue ; |
---|
571 | // There is a bug in Mozilla that returns '_moz_xxx' attributes as specified. |
---|
572 | else if ( sAttName.indexOf( '_moz' ) == 0 ) |
---|
573 | continue ; |
---|
574 | // For "class", nodeValue must be used. |
---|
575 | else if ( sAttName == 'class' ) |
---|
576 | { |
---|
577 | // Get the class, removing any fckXXX we can have there. |
---|
578 | sAttValue = oAttribute.nodeValue.replace( /(^|\s*)fck\S+/, '' ).Trim() ; |
---|
579 | |
---|
580 | if ( sAttValue.length == 0 ) |
---|
581 | continue ; |
---|
582 | } |
---|
583 | // XHTML doens't support attribute minimization like "CHECKED". It must be trasformed to cheched="checked". |
---|
584 | else if ( oAttribute.nodeValue === true ) |
---|
585 | sAttValue = sAttName ; |
---|
586 | else |
---|
587 | sAttValue = htmlNode.getAttribute( sAttName, 2 ) ; // We must use getAttribute to get it exactly as it is defined. |
---|
588 | |
---|
589 | attStr += ' ' + sAttName + '="' + sAttValue.replace( '"', '"' ) + '"' ; |
---|
590 | } |
---|
591 | } |
---|
592 | return attStr ; |
---|
593 | } |
---|
594 | } ; |
---|
595 | |
---|
596 | // Here we change the SwitchEditMode function to make the Ajax call when |
---|
597 | // switching from Wikitext. |
---|
598 | (function() |
---|
599 | { |
---|
600 | var original = FCK.SwitchEditMode ; |
---|
601 | |
---|
602 | FCK.SwitchEditMode = function() |
---|
603 | { |
---|
604 | var args = arguments ; |
---|
605 | |
---|
606 | var loadHTMLFromAjax = function( result ) |
---|
607 | { |
---|
608 | FCK.EditingArea.Textarea.value = result.responseText ; |
---|
609 | original.apply( FCK, args ) ; |
---|
610 | } |
---|
611 | |
---|
612 | if ( FCK.EditMode == FCK_EDITMODE_SOURCE ) |
---|
613 | { |
---|
614 | // Hide the textarea to avoid seeing the code change. |
---|
615 | FCK.EditingArea.Textarea.style.visibility = 'hidden' ; |
---|
616 | |
---|
617 | var loading = document.createElement( 'span' ) ; |
---|
618 | loading.innerHTML = FCKLang.wikiLoadingWikitext ; // JB |
---|
619 | loading.style.position = 'absolute' ; |
---|
620 | loading.style.left = '5px' ; |
---|
621 | // loading.style.backgroundColor = '#ff0000' ; |
---|
622 | FCK.EditingArea.Textarea.parentNode.appendChild( loading, FCK.EditingArea.Textarea ) ; |
---|
623 | |
---|
624 | // Use Ajax to transform the Wikitext to HTML. |
---|
625 | window.parent.sajax_request_type = 'POST' ; |
---|
626 | window.parent.sajax_do_call( 'wfSajaxWikiToHTML', [FCK.EditingArea.Textarea.value], loadHTMLFromAjax ) ; |
---|
627 | } |
---|
628 | else |
---|
629 | original.apply( FCK, args ) ; |
---|
630 | } |
---|
631 | })() ; |
---|
632 | |
---|
633 | // MediaWiki document processor. |
---|
634 | FCKDocumentProcessor.AppendNew().ProcessDocument = function( document ) |
---|
635 | { |
---|
636 | // Templates and magic words. |
---|
637 | var aSpans = document.getElementsByTagName( 'SPAN' ) ; |
---|
638 | |
---|
639 | var eSpan ; |
---|
640 | var i = aSpans.length - 1 ; |
---|
641 | while ( i >= 0 && ( eSpan = aSpans[i--] ) ) |
---|
642 | { |
---|
643 | var className = null ; |
---|
644 | switch ( eSpan.className ) |
---|
645 | { |
---|
646 | case 'fck_mw_ref' : |
---|
647 | className = 'FCK__MWRef' ; |
---|
648 | case 'fck_mw_references' : |
---|
649 | if ( className == null ) |
---|
650 | className = 'FCK__MWReferences' ; |
---|
651 | case 'fck_mw_template' : |
---|
652 | case 'fck_mw_magic' : |
---|
653 | if ( className == null ) |
---|
654 | className = 'FCK__MWTemplate' ; |
---|
655 | |
---|
656 | var oImg = FCKDocumentProcessor_CreateFakeImage( className, eSpan.cloneNode(true) ) ; |
---|
657 | oImg.setAttribute( '_' + eSpan.className, 'true', 0 ) ; |
---|
658 | |
---|
659 | eSpan.parentNode.insertBefore( oImg, eSpan ) ; |
---|
660 | eSpan.parentNode.removeChild( eSpan ) ; |
---|
661 | break ; |
---|
662 | } |
---|
663 | } |
---|
664 | } |
---|
665 | |
---|
666 | // Context menu for templates. |
---|
667 | FCK.ContextMenu.RegisterListener({ |
---|
668 | AddItems : function( contextMenu, tag, tagName ) |
---|
669 | { |
---|
670 | if ( tagName == 'IMG' ) |
---|
671 | { |
---|
672 | if ( tag.getAttribute( '_fck_mw_template' ) ) |
---|
673 | { |
---|
674 | contextMenu.AddSeparator() ; |
---|
675 | contextMenu.AddItem( 'MW_Template', FCKLang.wikiMnuTemplate ) ; // JB |
---|
676 | } |
---|
677 | if ( tag.getAttribute( '_fck_mw_magic' ) ) |
---|
678 | { |
---|
679 | contextMenu.AddSeparator() ; |
---|
680 | contextMenu.AddItem( 'MW_MagicWord', FCKLang.wikiMnuMagicWord ) ; // JB |
---|
681 | } |
---|
682 | if ( tag.getAttribute( '_fck_mw_ref' ) ) |
---|
683 | { |
---|
684 | contextMenu.AddSeparator() ; |
---|
685 | contextMenu.AddItem( 'MW_Ref', FCKLang.wikiMnuReference ) ; // JB |
---|
686 | } |
---|
687 | if ( tag.getAttribute( '_fck_mw_math' ) ) |
---|
688 | { |
---|
689 | contextMenu.AddSeparator() ; |
---|
690 | contextMenu.AddItem( 'MW_Math', FCKLang.wikiMnuFormula ) ; // JB |
---|
691 | } |
---|
692 | } |
---|
693 | } |
---|
694 | }) ; |
---|