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 ) ) ; |
---|
33 | |
---|
34 | // Register our toolbar buttons. |
---|
35 | var tbButton = new FCKToolbarButton( 'MW_Template', 'Template', 'Insert/Edit Template' ) ; |
---|
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', 'Insert/Edit Reference' ) ; |
---|
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', 'Insert/Edit Formula' ) ; |
---|
44 | tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_math.gif' ; |
---|
45 | FCKToolbarItems.RegisterItem( 'MW_Math', tbButton ) ; |
---|
46 | |
---|
47 | tbButton = new FCKToolbarButton( 'MW_Special', 'Special Tag', 'Insert/Edit Special Tag' ) ; |
---|
48 | tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_special.gif' ; |
---|
49 | FCKToolbarItems.RegisterItem( 'MW_Special', tbButton ) ; |
---|
50 | |
---|
51 | // Override some dialogs. |
---|
52 | FCKCommands.RegisterCommand( 'MW_Template', new FCKDialogCommand( 'MW_Template', 'Template Properties', FCKConfig.PluginsPath + 'mediawiki/dialogs/template.html', 400, 330 ) ) ; |
---|
53 | FCKCommands.RegisterCommand( 'MW_Ref', new FCKDialogCommand( 'MW_Ref', 'Reference Properties', FCKConfig.PluginsPath + 'mediawiki/dialogs/ref.html', 400, 250 ) ) ; |
---|
54 | FCKCommands.RegisterCommand( 'MW_Math', new FCKDialogCommand( 'MW_Math', 'Formula', FCKConfig.PluginsPath + 'mediawiki/dialogs/math.html', 400, 300 ) ) ; |
---|
55 | FCKCommands.RegisterCommand( 'MW_Special', new FCKDialogCommand( 'MW_Special', 'Special Tag Properties', FCKConfig.PluginsPath + 'mediawiki/dialogs/special.html', 400, 330 ) ) ; //YC |
---|
56 | FCKCommands.RegisterCommand( 'Link', new FCKDialogCommand( 'Link', FCKLang.DlgLnkWindowTitle, FCKConfig.PluginsPath + 'mediawiki/dialogs/link.html', 400, 250 ) ) ; |
---|
57 | FCKCommands.RegisterCommand( 'Image', new FCKDialogCommand( 'Image', FCKLang.DlgImgTitle, FCKConfig.PluginsPath + 'mediawiki/dialogs/image.html', 450, 300 ) ) ; |
---|
58 | |
---|
59 | FCKToolbarItems.OldGetItem = FCKToolbarItems.GetItem; |
---|
60 | |
---|
61 | FCKToolbarItems.GetItem = function( itemName ) |
---|
62 | { |
---|
63 | var oItem = FCKToolbarItems.LoadedItems[ itemName ] ; |
---|
64 | |
---|
65 | if ( oItem ) |
---|
66 | return oItem ; |
---|
67 | |
---|
68 | switch ( itemName ) |
---|
69 | { |
---|
70 | case 'Bold' : oItem = new FCKToolbarButton( 'Bold' , FCKLang.Bold, null, null, true, true, 20 ) ; break ; |
---|
71 | case 'Italic' : oItem = new FCKToolbarButton( 'Italic' , FCKLang.Italic, null, null, true, true, 21 ) ; break ; |
---|
72 | case 'Underline' : oItem = new FCKToolbarButton( 'Underline' , FCKLang.Underline, null, null, true, true, 22 ) ; break ; |
---|
73 | case 'StrikeThrough': oItem = new FCKToolbarButton( 'StrikeThrough' , FCKLang.StrikeThrough, null, null, true, true, 23 ) ; break ; |
---|
74 | case 'Link' : oItem = new FCKToolbarButton( 'Link' , FCKLang.InsertLinkLbl, FCKLang.InsertLink, null, true, true, 34 ) ; break ; |
---|
75 | |
---|
76 | default: |
---|
77 | return FCKToolbarItems.OldGetItem( itemName ); |
---|
78 | } |
---|
79 | |
---|
80 | FCKToolbarItems.LoadedItems[ itemName ] = oItem ; |
---|
81 | |
---|
82 | return oItem ; |
---|
83 | } |
---|
84 | |
---|
85 | FCKToolbarButton.prototype.Click = function() |
---|
86 | { |
---|
87 | var oToolbarButton = this._ToolbarButton || this ; |
---|
88 | |
---|
89 | // for some buttons, do something else instead... |
---|
90 | var CMode = false ; |
---|
91 | if ( oToolbarButton.SourceView && (FCK_EDITMODE_SOURCE == FCK.EditMode) ) |
---|
92 | { |
---|
93 | switch (oToolbarButton.CommandName) |
---|
94 | { |
---|
95 | case 'Bold' : window.parent.insertTags ('\'\'\'', '\'\'\'', 'Bold text') ; CMode = true ; break ; |
---|
96 | case 'Italic' : window.parent.insertTags ('\'\'', '\'\'', 'Italic text') ; CMode = true ; break ; |
---|
97 | case 'Underline' : window.parent.insertTags ('<u>', '</u>', 'Underlined text') ; CMode = true ; break ; |
---|
98 | case 'StrikeThrough': window.parent.insertTags ('<strike>', '</strike>', 'Strikethrough text') ; CMode = true ; break ; |
---|
99 | case 'Link' : window.parent.insertTags ('[[', ']]', 'Internal link') ; CMode = true ; break ; |
---|
100 | } |
---|
101 | } |
---|
102 | |
---|
103 | if ( !CMode ) |
---|
104 | FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( oToolbarButton.CommandName ).Execute() ; |
---|
105 | } |
---|
106 | |
---|
107 | // MediaWiki Wikitext Data Processor implementation. |
---|
108 | FCK.DataProcessor = |
---|
109 | { |
---|
110 | _inPre : false, |
---|
111 | _inLSpace : false, |
---|
112 | |
---|
113 | /* |
---|
114 | * Returns a string representing the HTML format of "data". The returned |
---|
115 | * value will be loaded in the editor. |
---|
116 | * The HTML must be from <html> to </html>, eventually including |
---|
117 | * the DOCTYPE. |
---|
118 | * @param {String} data The data to be converted in the |
---|
119 | * DataProcessor specific format. |
---|
120 | */ |
---|
121 | ConvertToHtml : function( data ) |
---|
122 | { |
---|
123 | // Call the original code. |
---|
124 | return FCKDataProcessor.prototype.ConvertToHtml.call( this, data ) ; |
---|
125 | }, |
---|
126 | |
---|
127 | /* |
---|
128 | * Converts a DOM (sub-)tree to a string in the data format. |
---|
129 | * @param {Object} rootNode The node that contains the DOM tree to be |
---|
130 | * converted to the data format. |
---|
131 | * @param {Boolean} excludeRoot Indicates that the root node must not |
---|
132 | * be included in the conversion, only its children. |
---|
133 | * @param {Boolean} format Indicates that the data must be formatted |
---|
134 | * for human reading. Not all Data Processors may provide it. |
---|
135 | */ |
---|
136 | ConvertToDataFormat : function( rootNode, excludeRoot, ignoreIfEmptyParagraph, format ) |
---|
137 | { |
---|
138 | // rootNode is <body>. |
---|
139 | |
---|
140 | // Normalize the document for text node processing (except IE - #1586). |
---|
141 | if ( !FCKBrowserInfo.IsIE ) |
---|
142 | rootNode.normalize() ; |
---|
143 | |
---|
144 | var stringBuilder = new Array() ; |
---|
145 | this._AppendNode( rootNode, stringBuilder, '' ) ; |
---|
146 | return stringBuilder.join( '' ).RTrim().replace(/^\n*/, "") ; |
---|
147 | }, |
---|
148 | |
---|
149 | /* |
---|
150 | * Makes any necessary changes to a piece of HTML for insertion in the |
---|
151 | * editor selection position. |
---|
152 | * @param {String} html The HTML to be fixed. |
---|
153 | */ |
---|
154 | FixHtml : function( html ) |
---|
155 | { |
---|
156 | return html ; |
---|
157 | }, |
---|
158 | |
---|
159 | // Collection of element definitions: |
---|
160 | // 0 : Prefix |
---|
161 | // 1 : Suffix |
---|
162 | // 2 : Ignore children |
---|
163 | _BasicElements : { |
---|
164 | body : [ ], |
---|
165 | b : [ "'''", "'''" ], |
---|
166 | strong : [ "'''", "'''" ], |
---|
167 | i : [ "''", "''" ], |
---|
168 | em : [ "''", "''" ], |
---|
169 | p : [ '\n', '\n' ], |
---|
170 | h1 : [ '\n= ', ' =\n' ], |
---|
171 | h2 : [ '\n== ', ' ==\n' ], |
---|
172 | h3 : [ '\n=== ', ' ===\n' ], |
---|
173 | h4 : [ '\n==== ', ' ====\n' ], |
---|
174 | h5 : [ '\n===== ', ' =====\n' ], |
---|
175 | h6 : [ '\n====== ', ' ======\n' ], |
---|
176 | br : [ '<br>', null, true ], |
---|
177 | hr : [ '\n----\n', null, true ] |
---|
178 | } , |
---|
179 | |
---|
180 | // This function is based on FCKXHtml._AppendNode. |
---|
181 | _AppendNode : function( htmlNode, stringBuilder, prefix ) |
---|
182 | { |
---|
183 | if ( !htmlNode ) |
---|
184 | return ; |
---|
185 | |
---|
186 | switch ( htmlNode.nodeType ) |
---|
187 | { |
---|
188 | // Element Node. |
---|
189 | case 1 : |
---|
190 | |
---|
191 | // Here we found an element that is not the real element, but a |
---|
192 | // fake one (like the Flash placeholder image), so we must get the real one. |
---|
193 | if ( htmlNode.getAttribute('_fckfakelement') && !htmlNode.getAttribute( '_fck_mw_math' ) ) |
---|
194 | return this._AppendNode( FCK.GetRealElement( htmlNode ), stringBuilder ) ; |
---|
195 | |
---|
196 | // Mozilla insert custom nodes in the DOM. |
---|
197 | if ( FCKBrowserInfo.IsGecko && htmlNode.hasAttribute('_moz_editor_bogus_node') ) |
---|
198 | return ; |
---|
199 | |
---|
200 | // This is for elements that are instrumental to FCKeditor and |
---|
201 | // must be removed from the final HTML. |
---|
202 | if ( htmlNode.getAttribute('_fcktemp') ) |
---|
203 | return ; |
---|
204 | |
---|
205 | // Get the element name. |
---|
206 | var sNodeName = htmlNode.tagName.toLowerCase() ; |
---|
207 | |
---|
208 | if ( FCKBrowserInfo.IsIE ) |
---|
209 | { |
---|
210 | // IE doens't include the scope name in the nodeName. So, add the namespace. |
---|
211 | if ( htmlNode.scopeName && htmlNode.scopeName != 'HTML' && htmlNode.scopeName != 'FCK' ) |
---|
212 | sNodeName = htmlNode.scopeName.toLowerCase() + ':' + sNodeName ; |
---|
213 | } |
---|
214 | else |
---|
215 | { |
---|
216 | if ( sNodeName.StartsWith( 'fck:' ) ) |
---|
217 | sNodeName = sNodeName.Remove( 0,4 ) ; |
---|
218 | } |
---|
219 | |
---|
220 | // Check if the node name is valid, otherwise ignore this tag. |
---|
221 | // If the nodeName starts with a slash, it is a orphan closing tag. |
---|
222 | // On some strange cases, the nodeName is empty, even if the node exists. |
---|
223 | if ( !FCKRegexLib.ElementName.test( sNodeName ) ) |
---|
224 | return ; |
---|
225 | |
---|
226 | if ( sNodeName == 'br' && ( this._inPre || this._inLSpace ) ) |
---|
227 | { |
---|
228 | stringBuilder.push( "\n" ) ; |
---|
229 | if ( this._inLSpace ) |
---|
230 | stringBuilder.push( " " ) ; |
---|
231 | return ; |
---|
232 | } |
---|
233 | |
---|
234 | // Remove the <br> if it is a bogus node. |
---|
235 | if ( sNodeName == 'br' && htmlNode.getAttribute( 'type', 2 ) == '_moz' ) |
---|
236 | return ; |
---|
237 | |
---|
238 | // The already processed nodes must be marked to avoid then to be duplicated (bad formatted HTML). |
---|
239 | // So here, the "mark" is checked... if the element is Ok, then mark it. |
---|
240 | if ( htmlNode._fckxhtmljob && htmlNode._fckxhtmljob == FCKXHtml.CurrentJobNum ) |
---|
241 | return ; |
---|
242 | |
---|
243 | var basicElement = this._BasicElements[ sNodeName ] ; |
---|
244 | if ( basicElement ) |
---|
245 | { |
---|
246 | var basic0 = basicElement[0]; |
---|
247 | var basic1 = basicElement[1]; |
---|
248 | |
---|
249 | if ( ( basicElement[0] == "''" || basicElement[0] == "'''" ) && stringBuilder.length > 2 ) |
---|
250 | { |
---|
251 | var pr1 = stringBuilder[stringBuilder.length-1]; |
---|
252 | var pr2 = stringBuilder[stringBuilder.length-2]; |
---|
253 | |
---|
254 | if ( pr1 + pr2 == "'''''") { |
---|
255 | if ( basicElement[0] == "''") |
---|
256 | { |
---|
257 | basic0 = '<i>'; |
---|
258 | basic1 = '</i>'; |
---|
259 | } |
---|
260 | if ( basicElement[0] == "'''") |
---|
261 | { |
---|
262 | basic0 = '<b>'; |
---|
263 | basic1 = '</b>'; |
---|
264 | } |
---|
265 | } |
---|
266 | } |
---|
267 | |
---|
268 | if ( basic0 ) |
---|
269 | stringBuilder.push( basic0 ) ; |
---|
270 | |
---|
271 | var len = stringBuilder.length ; |
---|
272 | |
---|
273 | if ( !basicElement[2] ) |
---|
274 | { |
---|
275 | this._AppendChildNodes( htmlNode, stringBuilder, prefix ) ; |
---|
276 | // only empty element inside, remove it to avoid quotes |
---|
277 | if ( ( stringBuilder.length == len || (stringBuilder.length == len + 1 && !stringBuilder[len].length) ) |
---|
278 | && basicElement[0].charAt(0) == "'") |
---|
279 | { |
---|
280 | stringBuilder.pop(); |
---|
281 | stringBuilder.pop(); |
---|
282 | return; |
---|
283 | } |
---|
284 | } |
---|
285 | |
---|
286 | if ( basic1 ) |
---|
287 | stringBuilder.push( basic1 ) ; |
---|
288 | } |
---|
289 | else |
---|
290 | { |
---|
291 | switch ( sNodeName ) |
---|
292 | { |
---|
293 | case 'ol' : |
---|
294 | case 'ul' : |
---|
295 | var isFirstLevel = !htmlNode.parentNode.nodeName.IEquals( 'ul', 'ol', 'li', 'dl', 'dt', 'dd' ) ; |
---|
296 | |
---|
297 | this._AppendChildNodes( htmlNode, stringBuilder, prefix ) ; |
---|
298 | |
---|
299 | if ( isFirstLevel && stringBuilder[ stringBuilder.length - 1 ] != "\n" ) { |
---|
300 | stringBuilder.push( '\n' ) ; |
---|
301 | } |
---|
302 | |
---|
303 | break ; |
---|
304 | |
---|
305 | case 'li' : |
---|
306 | |
---|
307 | if( stringBuilder.length > 1) |
---|
308 | { |
---|
309 | var sLastStr = stringBuilder[ stringBuilder.length - 1 ] ; |
---|
310 | if ( sLastStr != ";" && sLastStr != ":" && sLastStr != "#" && sLastStr != "*") |
---|
311 | stringBuilder.push( '\n' + prefix ) ; |
---|
312 | } |
---|
313 | |
---|
314 | var parent = htmlNode.parentNode ; |
---|
315 | var listType = "#" ; |
---|
316 | |
---|
317 | while ( parent ) |
---|
318 | { |
---|
319 | if ( parent.nodeName.toLowerCase() == 'ul' ) |
---|
320 | { |
---|
321 | listType = "*" ; |
---|
322 | break ; |
---|
323 | } |
---|
324 | else if ( parent.nodeName.toLowerCase() == 'ol' ) |
---|
325 | { |
---|
326 | listType = "#" ; |
---|
327 | break ; |
---|
328 | } |
---|
329 | else if ( parent.nodeName.toLowerCase() != 'li' ) |
---|
330 | break ; |
---|
331 | |
---|
332 | parent = parent.parentNode ; |
---|
333 | } |
---|
334 | |
---|
335 | stringBuilder.push( listType ) ; |
---|
336 | this._AppendChildNodes( htmlNode, stringBuilder, prefix + listType ) ; |
---|
337 | |
---|
338 | break ; |
---|
339 | |
---|
340 | case 'a' : |
---|
341 | |
---|
342 | // Get the actual Link href. |
---|
343 | var href = htmlNode.getAttribute( '_fcksavedurl' ) ; |
---|
344 | var hrefType = htmlNode.getAttribute( '_fck_mw_type' ) || '' ; |
---|
345 | |
---|
346 | if ( href == null ) |
---|
347 | href = htmlNode.getAttribute( 'href' , 2 ) || '' ; |
---|
348 | |
---|
349 | var isWikiUrl = true ; |
---|
350 | |
---|
351 | if ( hrefType == "media" ) |
---|
352 | stringBuilder.push( '[[Media:' ) ; |
---|
353 | else if ( htmlNode.className == "extiw" ) |
---|
354 | { |
---|
355 | stringBuilder.push( '[[' ) ; |
---|
356 | var isWikiUrl = true; |
---|
357 | } |
---|
358 | else |
---|
359 | { |
---|
360 | var isWikiUrl = !( href.StartsWith( 'mailto:' ) || /^\w+:\/\//.test( href ) ) ; |
---|
361 | stringBuilder.push( isWikiUrl ? '[[' : '[' ) ; |
---|
362 | } |
---|
363 | stringBuilder.push( href ) ; |
---|
364 | if ( htmlNode.innerHTML != '[n]' && (!isWikiUrl || href != htmlNode.innerHTML || !href.toLowerCase().StartsWith("category:"))) |
---|
365 | { |
---|
366 | stringBuilder.push( isWikiUrl? '|' : ' ' ) ; |
---|
367 | this._AppendChildNodes( htmlNode, stringBuilder, prefix ) ; |
---|
368 | } |
---|
369 | stringBuilder.push( isWikiUrl ? ']]' : ']' ) ; |
---|
370 | |
---|
371 | break ; |
---|
372 | |
---|
373 | case 'dl' : |
---|
374 | |
---|
375 | this._AppendChildNodes( htmlNode, stringBuilder, prefix ) ; |
---|
376 | var isFirstLevel = !htmlNode.parentNode.nodeName.IEquals( 'ul', 'ol', 'li', 'dl', 'dd', 'dt' ) ; |
---|
377 | if ( isFirstLevel && stringBuilder[ stringBuilder.length - 1 ] != "\n" ) |
---|
378 | stringBuilder.push( '\n') ; |
---|
379 | |
---|
380 | break ; |
---|
381 | |
---|
382 | case 'dt' : |
---|
383 | |
---|
384 | if( stringBuilder.length > 1) |
---|
385 | { |
---|
386 | var sLastStr = stringBuilder[ stringBuilder.length - 1 ] ; |
---|
387 | if ( sLastStr != ";" && sLastStr != ":" && sLastStr != "#" && sLastStr != "*" ) |
---|
388 | stringBuilder.push( '\n' + prefix ) ; |
---|
389 | } |
---|
390 | stringBuilder.push( ';' ) ; |
---|
391 | this._AppendChildNodes( htmlNode, stringBuilder, prefix + ";") ; |
---|
392 | |
---|
393 | break ; |
---|
394 | |
---|
395 | case 'dd' : |
---|
396 | |
---|
397 | if( stringBuilder.length > 1) |
---|
398 | { |
---|
399 | var sLastStr = stringBuilder[ stringBuilder.length - 1 ] ; |
---|
400 | if ( sLastStr != ";" && sLastStr != ":" && sLastStr != "#" && sLastStr != "*" ) |
---|
401 | stringBuilder.push( '\n' + prefix ) ; |
---|
402 | } |
---|
403 | stringBuilder.push( ':' ) ; |
---|
404 | this._AppendChildNodes( htmlNode, stringBuilder, prefix + ":" ) ; |
---|
405 | |
---|
406 | break ; |
---|
407 | |
---|
408 | case 'table' : |
---|
409 | |
---|
410 | var attribs = this._GetAttributesStr( htmlNode ) ; |
---|
411 | |
---|
412 | stringBuilder.push( '\n{|' ) ; |
---|
413 | if ( attribs.length > 0 ) |
---|
414 | stringBuilder.push( attribs ) ; |
---|
415 | stringBuilder.push( '\n' ) ; |
---|
416 | |
---|
417 | if ( htmlNode.caption && htmlNode.caption.innerHTML.length > 0 ) |
---|
418 | { |
---|
419 | stringBuilder.push( '|+ ' ) ; |
---|
420 | this._AppendChildNodes( htmlNode.caption, stringBuilder, prefix ) ; |
---|
421 | stringBuilder.push( '\n' ) ; |
---|
422 | } |
---|
423 | |
---|
424 | for ( var r = 0 ; r < htmlNode.rows.length ; r++ ) |
---|
425 | { |
---|
426 | attribs = this._GetAttributesStr( htmlNode.rows[r] ) ; |
---|
427 | |
---|
428 | stringBuilder.push( '|-' ) ; |
---|
429 | if ( attribs.length > 0 ) |
---|
430 | stringBuilder.push( attribs ) ; |
---|
431 | stringBuilder.push( '\n' ) ; |
---|
432 | |
---|
433 | for ( var c = 0 ; c < htmlNode.rows[r].cells.length ; c++ ) |
---|
434 | { |
---|
435 | attribs = this._GetAttributesStr( htmlNode.rows[r].cells[c] ) ; |
---|
436 | |
---|
437 | if ( htmlNode.rows[r].cells[c].tagName.toLowerCase() == "th" ) |
---|
438 | stringBuilder.push( '!' ) ; |
---|
439 | else |
---|
440 | stringBuilder.push( '|' ) ; |
---|
441 | |
---|
442 | if ( attribs.length > 0 ) |
---|
443 | stringBuilder.push( attribs + ' |' ) ; |
---|
444 | |
---|
445 | stringBuilder.push( ' ' ) ; |
---|
446 | |
---|
447 | this._IsInsideCell = true ; |
---|
448 | this._AppendChildNodes( htmlNode.rows[r].cells[c], stringBuilder, prefix ) ; |
---|
449 | this._IsInsideCell = false ; |
---|
450 | |
---|
451 | stringBuilder.push( '\n' ) ; |
---|
452 | } |
---|
453 | } |
---|
454 | |
---|
455 | stringBuilder.push( '|}\n' ) ; |
---|
456 | |
---|
457 | break ; |
---|
458 | |
---|
459 | case 'img' : |
---|
460 | |
---|
461 | var formula = htmlNode.getAttribute( '_fck_mw_math' ) ; |
---|
462 | |
---|
463 | if ( formula && formula.length > 0 ) |
---|
464 | { |
---|
465 | stringBuilder.push( '<math>' ) ; |
---|
466 | stringBuilder.push( formula ) ; |
---|
467 | stringBuilder.push( '</math>' ) ; |
---|
468 | return ; |
---|
469 | } |
---|
470 | |
---|
471 | var imgName = htmlNode.getAttribute( '_fck_mw_filename' ) ; |
---|
472 | var imgCaption = htmlNode.getAttribute( 'alt' ) || '' ; |
---|
473 | var imgType = htmlNode.getAttribute( '_fck_mw_type' ) || '' ; |
---|
474 | var imgLocation = htmlNode.getAttribute( '_fck_mw_location' ) || '' ; |
---|
475 | var imgWidth = htmlNode.getAttribute( '_fck_mw_width' ) || '' ; |
---|
476 | var imgHeight = htmlNode.getAttribute( '_fck_mw_height' ) || '' ; |
---|
477 | |
---|
478 | stringBuilder.push( '[[Image:' ) |
---|
479 | stringBuilder.push( imgName ) |
---|
480 | |
---|
481 | if ( imgType.length > 0 ) |
---|
482 | stringBuilder.push( '|' + imgType ) ; |
---|
483 | |
---|
484 | if ( imgLocation.length > 0 ) |
---|
485 | stringBuilder.push( '|' + imgLocation ) ; |
---|
486 | |
---|
487 | if ( imgWidth.length > 0 ) |
---|
488 | { |
---|
489 | stringBuilder.push( '|' + imgWidth ) ; |
---|
490 | |
---|
491 | if ( imgHeight.length > 0 ) |
---|
492 | stringBuilder.push( 'x' + imgHeight ) ; |
---|
493 | |
---|
494 | stringBuilder.push( 'px' ) ; |
---|
495 | } |
---|
496 | |
---|
497 | if ( imgCaption.length > 0 ) |
---|
498 | stringBuilder.push( '|' + imgCaption ) ; |
---|
499 | |
---|
500 | stringBuilder.push( ']]' ) |
---|
501 | |
---|
502 | break ; |
---|
503 | |
---|
504 | case 'span' : |
---|
505 | switch ( htmlNode.className ) |
---|
506 | { |
---|
507 | case 'fck_mw_ref' : |
---|
508 | var refName = htmlNode.getAttribute( 'name' ) ; |
---|
509 | |
---|
510 | stringBuilder.push( '<ref' ) ; |
---|
511 | |
---|
512 | if ( refName && refName.length > 0 ) |
---|
513 | stringBuilder.push( ' name="' + refName + '"' ) ; |
---|
514 | |
---|
515 | if ( htmlNode.innerHTML.length == 0 ) |
---|
516 | stringBuilder.push( ' />' ) ; |
---|
517 | else |
---|
518 | { |
---|
519 | stringBuilder.push( '>' ) ; |
---|
520 | stringBuilder.push( htmlNode.innerHTML ) ; |
---|
521 | stringBuilder.push( '</ref>' ) ; |
---|
522 | } |
---|
523 | return ; |
---|
524 | |
---|
525 | case 'fck_mw_references' : |
---|
526 | stringBuilder.push( '<references />' ) ; |
---|
527 | return ; |
---|
528 | |
---|
529 | case 'fck_mw_template' : |
---|
530 | stringBuilder.push( FCKTools.HTMLDecode(htmlNode.innerHTML).replace(/fckLR/g,'\r\n') ) ; |
---|
531 | return ; |
---|
532 | |
---|
533 | case 'fck_mw_magic' : |
---|
534 | stringBuilder.push( htmlNode.innerHTML ) ; |
---|
535 | return ; |
---|
536 | |
---|
537 | case 'fck_mw_nowiki' : |
---|
538 | sNodeName = 'nowiki' ; |
---|
539 | break ; |
---|
540 | |
---|
541 | case 'fck_mw_includeonly' : |
---|
542 | sNodeName = 'includeonly' ; |
---|
543 | break ; |
---|
544 | |
---|
545 | case 'fck_mw_noinclude' : |
---|
546 | sNodeName = 'noinclude' ; |
---|
547 | break ; |
---|
548 | |
---|
549 | case 'fck_mw_gallery' : |
---|
550 | sNodeName = 'gallery' ; |
---|
551 | break ; |
---|
552 | |
---|
553 | case 'fck_mw_onlyinclude' : |
---|
554 | sNodeName = 'onlyinclude' ; |
---|
555 | |
---|
556 | break ; |
---|
557 | } |
---|
558 | |
---|
559 | // Change the node name and fell in the "default" case. |
---|
560 | if ( htmlNode.getAttribute( '_fck_mw_customtag' ) ) |
---|
561 | sNodeName = htmlNode.getAttribute( '_fck_mw_tagname' ) ; |
---|
562 | |
---|
563 | case 'pre' : |
---|
564 | var attribs = this._GetAttributesStr( htmlNode ) ; |
---|
565 | |
---|
566 | if ( htmlNode.className == "_fck_mw_lspace") |
---|
567 | { |
---|
568 | stringBuilder.push( "\n " ) ; |
---|
569 | this._inLSpace = true ; |
---|
570 | this._AppendChildNodes( htmlNode, stringBuilder, prefix ) ; |
---|
571 | this._inLSpace = false ; |
---|
572 | var len = stringBuilder.length ; |
---|
573 | if ( len>1 ) { |
---|
574 | var tail = stringBuilder[len-2] + stringBuilder[len-1]; |
---|
575 | if ( len>2 ) { |
---|
576 | tail = stringBuilder[len-3] + tail ; |
---|
577 | } |
---|
578 | if (tail.EndsWith("\n ")) { |
---|
579 | stringBuilder[len-1] = stringBuilder[len-1].replace(/ $/, ""); |
---|
580 | } |
---|
581 | else if ( !tail.EndsWith("\n") ) { |
---|
582 | stringBuilder.push( "\n" ) ; |
---|
583 | } |
---|
584 | } |
---|
585 | } |
---|
586 | else |
---|
587 | { |
---|
588 | stringBuilder.push( '<' ) ; |
---|
589 | stringBuilder.push( sNodeName ) ; |
---|
590 | |
---|
591 | if ( attribs.length > 0 ) |
---|
592 | stringBuilder.push( attribs ) ; |
---|
593 | |
---|
594 | stringBuilder.push( '>' ) ; |
---|
595 | this._inPre = true ; |
---|
596 | this._AppendChildNodes( htmlNode, stringBuilder, prefix ) ; |
---|
597 | this._inPre = false ; |
---|
598 | |
---|
599 | stringBuilder.push( '<\/' ) ; |
---|
600 | stringBuilder.push( sNodeName ) ; |
---|
601 | stringBuilder.push( '>' ) ; |
---|
602 | } |
---|
603 | |
---|
604 | break ; |
---|
605 | default : |
---|
606 | var attribs = this._GetAttributesStr( htmlNode ) ; |
---|
607 | |
---|
608 | stringBuilder.push( '<' ) ; |
---|
609 | stringBuilder.push( sNodeName ) ; |
---|
610 | |
---|
611 | if ( attribs.length > 0 ) |
---|
612 | stringBuilder.push( attribs ) ; |
---|
613 | |
---|
614 | stringBuilder.push( '>' ) ; |
---|
615 | this._AppendChildNodes( htmlNode, stringBuilder, prefix ) ; |
---|
616 | stringBuilder.push( '<\/' ) ; |
---|
617 | stringBuilder.push( sNodeName ) ; |
---|
618 | stringBuilder.push( '>' ) ; |
---|
619 | break ; |
---|
620 | } |
---|
621 | } |
---|
622 | |
---|
623 | htmlNode._fckxhtmljob = FCKXHtml.CurrentJobNum ; |
---|
624 | return ; |
---|
625 | |
---|
626 | // Text Node. |
---|
627 | case 3 : |
---|
628 | |
---|
629 | var parentIsSpecialTag = htmlNode.parentNode.getAttribute( '_fck_mw_customtag' ) ; |
---|
630 | var textValue = htmlNode.nodeValue; |
---|
631 | |
---|
632 | if ( !parentIsSpecialTag ) |
---|
633 | { |
---|
634 | if ( FCKBrowserInfo.IsIE && this._inLSpace ) { |
---|
635 | textValue = textValue.replace( /\r/g, "\r " ) ; |
---|
636 | if (textValue.EndsWith( "\r " )) { |
---|
637 | textValue = textValue.replace( /\r $/, "\r" ); |
---|
638 | } |
---|
639 | } |
---|
640 | if ( !FCKBrowserInfo.IsIE && this._inLSpace ) { |
---|
641 | textValue = textValue.replace( /\n(?! )/g, "\n " ) ; |
---|
642 | } |
---|
643 | |
---|
644 | if (!this._inLSpace && !this._inPre) { |
---|
645 | textValue = textValue.replace( /[\n\t]/g, ' ' ) ; |
---|
646 | } |
---|
647 | |
---|
648 | textValue = FCKTools.HTMLEncode( textValue ) ; |
---|
649 | textValue = textValue.replace( /\u00A0/g, ' ' ) ; |
---|
650 | |
---|
651 | if ( ( !htmlNode.previousSibling || |
---|
652 | ( stringBuilder.length > 0 && stringBuilder[ stringBuilder.length - 1 ].EndsWith( '\n' ) ) ) && !this._inLSpace && !this._inPre ) |
---|
653 | { |
---|
654 | textValue = textValue.LTrim() ; |
---|
655 | } |
---|
656 | |
---|
657 | if ( !htmlNode.nextSibling && !this._inLSpace && !this._inPre && (!htmlNode.parentNode || !htmlNode.parentNode.nextSibling)) |
---|
658 | textValue = textValue.RTrim() ; |
---|
659 | |
---|
660 | if (!this._inLSpace && !this._inPre) |
---|
661 | textValue = textValue.replace( / {2,}/g, ' ' ) ; |
---|
662 | |
---|
663 | if ( this._inLSpace && textValue.length == 1 && textValue.charCodeAt(0) == 13 ) |
---|
664 | textValue = textValue + " " ; |
---|
665 | |
---|
666 | if ( !this._inLSpace && !this._inPre && textValue == " " ) { |
---|
667 | var len = stringBuilder.length; |
---|
668 | if (len > 1) { |
---|
669 | var tail = stringBuilder[len-2] + stringBuilder[len-1]; |
---|
670 | if ( tail.toString().EndsWith( "\n" ) ) |
---|
671 | textValue = ""; |
---|
672 | } |
---|
673 | } |
---|
674 | |
---|
675 | if ( this._IsInsideCell ) |
---|
676 | textValue = textValue.replace( /\|/g, '|' ) ; |
---|
677 | } |
---|
678 | else |
---|
679 | { |
---|
680 | textValue = FCKTools.HTMLDecode(textValue).replace(/fckLR/g,'\r\n'); |
---|
681 | } |
---|
682 | |
---|
683 | stringBuilder.push( textValue ) ; |
---|
684 | return ; |
---|
685 | |
---|
686 | // Comment |
---|
687 | case 8 : |
---|
688 | // IE catches the <!DOTYPE ... > as a comment, but it has no |
---|
689 | // innerHTML, so we can catch it, and ignore it. |
---|
690 | if ( FCKBrowserInfo.IsIE && !htmlNode.innerHTML ) |
---|
691 | return ; |
---|
692 | |
---|
693 | stringBuilder.push( "<!--" ) ; |
---|
694 | |
---|
695 | try { stringBuilder.push( htmlNode.nodeValue ) ; } |
---|
696 | catch (e) { /* Do nothing... probably this is a wrong format comment. */ } |
---|
697 | |
---|
698 | stringBuilder.push( "-->" ) ; |
---|
699 | return ; |
---|
700 | } |
---|
701 | }, |
---|
702 | |
---|
703 | _AppendChildNodes : function( htmlNode, stringBuilder, listPrefix ) |
---|
704 | { |
---|
705 | var child = htmlNode.firstChild ; |
---|
706 | |
---|
707 | while ( child ) |
---|
708 | { |
---|
709 | this._AppendNode( child, stringBuilder, listPrefix ) ; |
---|
710 | child = child.nextSibling ; |
---|
711 | } |
---|
712 | }, |
---|
713 | |
---|
714 | _GetAttributesStr : function( htmlNode ) |
---|
715 | { |
---|
716 | var attStr = '' ; |
---|
717 | var aAttributes = htmlNode.attributes ; |
---|
718 | |
---|
719 | for ( var n = 0 ; n < aAttributes.length ; n++ ) |
---|
720 | { |
---|
721 | var oAttribute = aAttributes[n] ; |
---|
722 | |
---|
723 | if ( oAttribute.specified ) |
---|
724 | { |
---|
725 | var sAttName = oAttribute.nodeName.toLowerCase() ; |
---|
726 | var sAttValue ; |
---|
727 | |
---|
728 | // Ignore any attribute starting with "_fck". |
---|
729 | if ( sAttName.StartsWith( '_fck' ) ) |
---|
730 | continue ; |
---|
731 | // There is a bug in Mozilla that returns '_moz_xxx' attributes as specified. |
---|
732 | else if ( sAttName.indexOf( '_moz' ) == 0 ) |
---|
733 | continue ; |
---|
734 | // For "class", nodeValue must be used. |
---|
735 | else if ( sAttName == 'class' ) |
---|
736 | { |
---|
737 | // Get the class, removing any fckXXX we can have there. |
---|
738 | sAttValue = oAttribute.nodeValue.replace( /(^|\s*)fck\S+/, '' ).Trim() ; |
---|
739 | |
---|
740 | if ( sAttValue.length == 0 ) |
---|
741 | continue ; |
---|
742 | } |
---|
743 | else if ( sAttName == 'style' && FCKBrowserInfo.IsIE ) { |
---|
744 | sAttValue = htmlNode.style.cssText.toLowerCase() ; |
---|
745 | } |
---|
746 | // XHTML doens't support attribute minimization like "CHECKED". It must be trasformed to cheched="checked". |
---|
747 | else if ( oAttribute.nodeValue === true ) |
---|
748 | sAttValue = sAttName ; |
---|
749 | else |
---|
750 | sAttValue = htmlNode.getAttribute( sAttName, 2 ) ; // We must use getAttribute to get it exactly as it is defined. |
---|
751 | |
---|
752 | // leave templates |
---|
753 | if ( sAttName.StartsWith( '{{' ) && sAttName.EndsWith( '}}' ) ) { |
---|
754 | attStr += ' ' + sAttName ; |
---|
755 | } |
---|
756 | else { |
---|
757 | attStr += ' ' + sAttName + '="' + String(sAttValue).replace( '"', '"' ) + '"' ; |
---|
758 | } |
---|
759 | } |
---|
760 | } |
---|
761 | return attStr ; |
---|
762 | } |
---|
763 | } ; |
---|
764 | |
---|
765 | // Here we change the SwitchEditMode function to make the Ajax call when |
---|
766 | // switching from Wikitext. |
---|
767 | (function() |
---|
768 | { |
---|
769 | var original = FCK.SwitchEditMode ; |
---|
770 | |
---|
771 | FCK.SwitchEditMode = function() |
---|
772 | { |
---|
773 | var args = arguments ; |
---|
774 | |
---|
775 | var loadHTMLFromAjax = function( result ) |
---|
776 | { |
---|
777 | alert("response text = "+result.responseText) |
---|
778 | FCK.EditingArea.Textarea.value = result.responseText ; |
---|
779 | original.apply( FCK, args ) ; |
---|
780 | } |
---|
781 | var edittools_markup = parent.document.getElementById ('editpage-specialchars') ; |
---|
782 | |
---|
783 | if ( FCK.EditMode == FCK_EDITMODE_SOURCE ) |
---|
784 | { |
---|
785 | // Hide the textarea to avoid seeing the code change. |
---|
786 | FCK.EditingArea.Textarea.style.visibility = 'hidden' ; |
---|
787 | |
---|
788 | var loading = document.createElement( 'span' ) ; |
---|
789 | loading.innerHTML = ' Loading Wikitext. Please wait... ' ; |
---|
790 | loading.style.position = 'absolute' ; |
---|
791 | loading.style.left = '5px' ; |
---|
792 | // loading.style.backgroundColor = '#ff0000' ; |
---|
793 | FCK.EditingArea.Textarea.parentNode.appendChild( loading, FCK.EditingArea.Textarea ) ; |
---|
794 | // if we have a standard Edittools div, hide the one containing wikimarkup |
---|
795 | if (edittools_markup) { |
---|
796 | edittools_markup.style.display = 'none' ; |
---|
797 | } |
---|
798 | |
---|
799 | // Use Ajax to transform the Wikitext to HTML. |
---|
800 | window.parent.sajax_request_type = 'POST' ; |
---|
801 | window.parent.sajax_do_call( 'wfSajaxWikiToHTML', [FCK.EditingArea.Textarea.value], loadHTMLFromAjax ) ; |
---|
802 | } |
---|
803 | else { |
---|
804 | original.apply( FCK, args ) ; |
---|
805 | if (edittools_markup) { |
---|
806 | edittools_markup.style.display = '' ; |
---|
807 | } |
---|
808 | } |
---|
809 | } |
---|
810 | })() ; |
---|
811 | |
---|
812 | // MediaWiki document processor. |
---|
813 | FCKDocumentProcessor.AppendNew().ProcessDocument = function( document ) |
---|
814 | { |
---|
815 | // Templates and magic words. |
---|
816 | var aSpans = document.getElementsByTagName( 'SPAN' ) ; |
---|
817 | |
---|
818 | var eSpan ; |
---|
819 | var i = aSpans.length - 1 ; |
---|
820 | while ( i >= 0 && ( eSpan = aSpans[i--] ) ) |
---|
821 | { |
---|
822 | var className = null ; |
---|
823 | switch ( eSpan.className ) |
---|
824 | { |
---|
825 | case 'fck_mw_ref' : |
---|
826 | className = 'FCK__MWRef' ; |
---|
827 | case 'fck_mw_references' : |
---|
828 | if ( className == null ) |
---|
829 | className = 'FCK__MWReferences' ; |
---|
830 | case 'fck_mw_template' : |
---|
831 | if ( className == null ) //YC |
---|
832 | className = 'FCK__MWTemplate' ; //YC |
---|
833 | case 'fck_mw_magic' : |
---|
834 | if ( className == null ) |
---|
835 | className = 'FCK__MWMagicWord' ; |
---|
836 | case 'fck_mw_magic' : |
---|
837 | if ( className == null ) |
---|
838 | className = 'FCK__MWMagicWord' ; |
---|
839 | case 'fck_mw_special' : //YC |
---|
840 | if ( className == null ) |
---|
841 | className = 'FCK__MWSpecial' ; |
---|
842 | case 'fck_mw_nowiki' : |
---|
843 | if ( className == null ) |
---|
844 | className = 'FCK__MWNowiki' ; |
---|
845 | case 'fck_mw_includeonly' : |
---|
846 | if ( className == null ) |
---|
847 | className = 'FCK__MWIncludeonly' ; |
---|
848 | case 'fck_mw_gallery' : |
---|
849 | if ( className == null ) |
---|
850 | className = 'FCK__MWGallery' ; |
---|
851 | case 'fck_mw_noinclude' : |
---|
852 | if ( className == null ) |
---|
853 | className = 'FCK__MWNoinclude' ; |
---|
854 | case 'fck_mw_onlyinclude' : |
---|
855 | if ( className == null ) |
---|
856 | className = 'FCK__MWOnlyinclude' ; |
---|
857 | |
---|
858 | var oImg = FCKDocumentProcessor_CreateFakeImage( className, eSpan.cloneNode(true) ) ; |
---|
859 | oImg.setAttribute( '_' + eSpan.className, 'true', 0 ) ; |
---|
860 | |
---|
861 | eSpan.parentNode.insertBefore( oImg, eSpan ) ; |
---|
862 | eSpan.parentNode.removeChild( eSpan ) ; |
---|
863 | break ; |
---|
864 | } |
---|
865 | } |
---|
866 | |
---|
867 | // InterWiki / InterLanguage links |
---|
868 | var aHrefs = document.getElementsByTagName( 'A' ) ; |
---|
869 | var a ; |
---|
870 | var i = aHrefs.length - 1 ; |
---|
871 | while ( i >= 0 && ( a = aHrefs[i--] ) ) |
---|
872 | { |
---|
873 | if (a.className == 'extiw') |
---|
874 | { |
---|
875 | a.href = ":" + a.title ; |
---|
876 | a.setAttribute( '_fcksavedurl', ":" + a.title ) ; |
---|
877 | } |
---|
878 | } |
---|
879 | } |
---|
880 | |
---|
881 | // Context menu for templates. |
---|
882 | FCK.ContextMenu.RegisterListener({ |
---|
883 | AddItems : function( contextMenu, tag, tagName ) |
---|
884 | { |
---|
885 | if ( tagName == 'IMG' ) |
---|
886 | { |
---|
887 | if ( tag.getAttribute( '_fck_mw_template' ) ) |
---|
888 | { |
---|
889 | contextMenu.AddSeparator() ; |
---|
890 | contextMenu.AddItem( 'MW_Template', 'Template Properties' ) ; |
---|
891 | } |
---|
892 | if ( tag.getAttribute( '_fck_mw_magic' ) ) |
---|
893 | { |
---|
894 | contextMenu.AddSeparator() ; |
---|
895 | contextMenu.AddItem( 'MW_MagicWord', 'Modify Magic Word' ) ; |
---|
896 | } |
---|
897 | if ( tag.getAttribute( '_fck_mw_ref' ) ) |
---|
898 | { |
---|
899 | contextMenu.AddSeparator() ; |
---|
900 | contextMenu.AddItem( 'MW_Ref', 'Reference Properties' ) ; |
---|
901 | } |
---|
902 | if ( tag.getAttribute( '_fck_mw_math' ) ) |
---|
903 | { |
---|
904 | contextMenu.AddSeparator() ; |
---|
905 | contextMenu.AddItem( 'MW_Math', 'Edit Formula' ) ; |
---|
906 | } |
---|
907 | if ( tag.getAttribute( '_fck_mw_special' ) || tag.getAttribute( '_fck_mw_nowiki' ) || tag.getAttribute( '_fck_mw_includeonly' ) || tag.getAttribute( '_fck_mw_noinclude' ) || tag.getAttribute( '_fck_mw_onlyinclude' ) || tag.getAttribute( '_fck_mw_gallery' )) //YC |
---|
908 | { |
---|
909 | contextMenu.AddSeparator() ; |
---|
910 | contextMenu.AddItem( 'MW_Special', 'Special Tag Properties' ) ; |
---|
911 | } |
---|
912 | } |
---|
913 | } |
---|
914 | }) ; |
---|