1 /** |
1 /** |
2 * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ |
2 * $Id: editor_plugin_src.js 432 2007-11-23 16:07:16Z spocke $ |
3 * |
3 * |
4 * @author Moxiecode |
4 * @author Moxiecode |
5 * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. |
5 * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. |
6 */ |
6 */ |
7 |
7 |
8 /* Import plugin specific language pack */ |
8 (function() { |
9 tinyMCE.importPluginLanguagePack('paste'); |
9 var Event = tinymce.dom.Event; |
10 |
10 |
11 var TinyMCE_PastePlugin = { |
11 tinymce.create('tinymce.plugins.PastePlugin', { |
12 getInfo : function() { |
12 init : function(ed, url) { |
13 return { |
13 var t = this; |
14 longname : 'Paste text/word', |
14 |
15 author : 'Moxiecode Systems AB', |
15 t.editor = ed; |
16 authorurl : 'http://tinymce.moxiecode.com', |
16 |
17 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste', |
17 // Register commands |
18 version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion |
18 ed.addCommand('mcePasteText', function(ui, v) { |
19 }; |
19 if (ui) { |
20 }, |
20 ed.windowManager.open({ |
21 |
21 file : url + '/pastetext.htm', |
22 initInstance : function(inst) { |
22 width : 450, |
23 if (tinyMCE.isMSIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false)) |
23 height : 400, |
24 tinyMCE.addEvent(inst.getBody(), "paste", TinyMCE_PastePlugin._handlePasteEvent); |
24 inline : 1 |
25 }, |
25 }, { |
26 |
26 plugin_url : url |
27 handleEvent : function(e) { |
27 }); |
28 // Force paste dialog if non IE browser |
28 } else |
29 if (!tinyMCE.isRealIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false) && e.ctrlKey && e.keyCode == 86 && e.type == "keydown") { |
29 t._insertText(v.html, v.linebreaks); |
30 window.setTimeout('tinyMCE.selectedInstance.execCommand("mcePasteText",true)', 1); |
30 }); |
31 return tinyMCE.cancelEvent(e); |
31 |
|
32 ed.addCommand('mcePasteWord', function(ui, v) { |
|
33 if (ui) { |
|
34 ed.windowManager.open({ |
|
35 file : url + '/pasteword.htm', |
|
36 width : 450, |
|
37 height : 400, |
|
38 inline : 1 |
|
39 }, { |
|
40 plugin_url : url |
|
41 }); |
|
42 } else |
|
43 t._insertWordContent(v); |
|
44 }); |
|
45 |
|
46 ed.addCommand('mceSelectAll', function() { |
|
47 ed.execCommand('selectall'); |
|
48 }); |
|
49 |
|
50 // Register buttons |
|
51 ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText', ui : true}); |
|
52 ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord', ui : true}); |
|
53 ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'mceSelectAll'}); |
|
54 |
|
55 if (ed.getParam("paste_auto_cleanup_on_paste", false)) { |
|
56 ed.onPaste.add(function(ed, e) { |
|
57 return t._handlePasteEvent(e) |
|
58 }); |
|
59 } |
|
60 |
|
61 if (!tinymce.isIE && ed.getParam("paste_auto_cleanup_on_paste", false)) { |
|
62 // Force paste dialog if non IE browser |
|
63 ed.onKeyDown.add(function(ed, e) { |
|
64 if (e.ctrlKey && e.keyCode == 86) { |
|
65 window.setTimeout(function() { |
|
66 ed.execCommand("mcePasteText", true); |
|
67 }, 1); |
|
68 |
|
69 Event.cancel(e); |
|
70 } |
|
71 }); |
|
72 } |
|
73 }, |
|
74 |
|
75 getInfo : function() { |
|
76 return { |
|
77 longname : 'Paste text/word', |
|
78 author : 'Moxiecode Systems AB', |
|
79 authorurl : 'http://tinymce.moxiecode.com', |
|
80 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste', |
|
81 version : tinymce.majorVersion + "." + tinymce.minorVersion |
|
82 }; |
|
83 }, |
|
84 |
|
85 // Private methods |
|
86 |
|
87 _handlePasteEvent : function(e) { |
|
88 var html = this._clipboardHTML(), ed = this.editor, sel = ed.selection, r; |
|
89 |
|
90 // Removes italic, strong etc, the if was needed due to bug #1437114 |
|
91 if (ed && (r = sel.getRng()) && r.text.length > 0) |
|
92 ed.execCommand('delete'); |
|
93 |
|
94 if (html && html.length > 0) |
|
95 ed.execCommand('mcePasteWord', false, html); |
|
96 |
|
97 return Event.cancel(e); |
|
98 }, |
|
99 |
|
100 _insertText : function(content, bLinebreaks) { |
|
101 if (content && content.length > 0) { |
|
102 if (bLinebreaks) { |
|
103 // Special paragraph treatment |
|
104 if (this.editor.getParam("paste_create_paragraphs", true)) { |
|
105 var rl = this.editor.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); |
|
106 for (var i=0; i<rl.length; i+=2) |
|
107 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); |
|
108 |
|
109 content = content.replace(/\r\n\r\n/g, '</p><p>'); |
|
110 content = content.replace(/\r\r/g, '</p><p>'); |
|
111 content = content.replace(/\n\n/g, '</p><p>'); |
|
112 |
|
113 // Has paragraphs |
|
114 if ((pos = content.indexOf('</p><p>')) != -1) { |
|
115 this.editor.execCommand("Delete"); |
|
116 |
|
117 var node = this.editor.selection.getNode(); |
|
118 |
|
119 // Get list of elements to break |
|
120 var breakElms = []; |
|
121 |
|
122 do { |
|
123 if (node.nodeType == 1) { |
|
124 // Don't break tables and break at body |
|
125 if (node.nodeName == "TD" || node.nodeName == "BODY") |
|
126 break; |
|
127 |
|
128 breakElms[breakElms.length] = node; |
|
129 } |
|
130 } while(node = node.parentNode); |
|
131 |
|
132 var before = "", after = "</p>"; |
|
133 before += content.substring(0, pos); |
|
134 |
|
135 for (var i=0; i<breakElms.length; i++) { |
|
136 before += "</" + breakElms[i].nodeName + ">"; |
|
137 after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; |
|
138 } |
|
139 |
|
140 before += "<p>"; |
|
141 content = before + content.substring(pos+7) + after; |
|
142 } |
|
143 } |
|
144 |
|
145 if (this.editor.getParam("paste_create_linebreaks", true)) { |
|
146 content = content.replace(/\r\n/g, '<br />'); |
|
147 content = content.replace(/\r/g, '<br />'); |
|
148 content = content.replace(/\n/g, '<br />'); |
|
149 } |
|
150 } |
|
151 |
|
152 this.editor.execCommand("mceInsertRawHTML", false, content); |
|
153 } |
|
154 }, |
|
155 |
|
156 _insertWordContent : function(content) { |
|
157 if (content && content.length > 0) { |
|
158 // Cleanup Word content |
|
159 var bull = String.fromCharCode(8226); |
|
160 var middot = String.fromCharCode(183); |
|
161 var cb; |
|
162 |
|
163 if ((cb = this.editor.getParam("paste_insert_word_content_callback", "")) != "") |
|
164 content = eval(cb + "('before', content)"); |
|
165 |
|
166 var rl = this.editor.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); |
|
167 for (var i=0; i<rl.length; i+=2) |
|
168 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); |
|
169 |
|
170 if (this.editor.getParam("paste_convert_headers_to_strong", false)) { |
|
171 content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>'); |
|
172 } |
|
173 |
|
174 content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--"); |
|
175 content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>"); |
|
176 content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list |
|
177 content = content.replace(/<o:p><\/o:p>/gi, ""); |
|
178 content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks |
|
179 content = content.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), ""); // Word comments |
|
180 |
|
181 if (this.editor.getParam("paste_remove_spans", true)) |
|
182 content = content.replace(/<\/?span[^>]*>/gi, ""); |
|
183 |
|
184 if (this.editor.getParam("paste_remove_styles", true)) |
|
185 content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3"); |
|
186 |
|
187 content = content.replace(/<\/?font[^>]*>/gi, ""); |
|
188 |
|
189 // Strips class attributes. |
|
190 switch (this.editor.getParam("paste_strip_class_attributes", "all")) { |
|
191 case "all": |
|
192 content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); |
|
193 break; |
|
194 |
|
195 case "mso": |
|
196 content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3"); |
|
197 break; |
|
198 } |
|
199 |
|
200 content = content.replace(new RegExp('href="?' + this._reEscape("" + document.location) + '', 'gi'), 'href="' + this.editor.documentBaseURI.getURI()); |
|
201 content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3"); |
|
202 content = content.replace(/<\\?\?xml[^>]*>/gi, ""); |
|
203 content = content.replace(/<\/?\w+:[^>]*>/gi, ""); |
|
204 content = content.replace(/-- page break --\s*<p> <\/p>/gi, ""); // Remove pagebreaks |
|
205 content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks |
|
206 |
|
207 // content = content.replace(/\/? */gi, ""); |
|
208 // content = content.replace(/<p> <\/p>/gi, ''); |
|
209 |
|
210 if (!this.editor.getParam('force_p_newlines')) { |
|
211 content = content.replace('', '' ,'gi'); |
|
212 content = content.replace('</p>', '<br /><br />' ,'gi'); |
|
213 } |
|
214 |
|
215 if (!tinymce.isIE && !this.editor.getParam('force_p_newlines')) { |
|
216 content = content.replace(/<\/?p[^>]*>/gi, ""); |
|
217 } |
|
218 |
|
219 content = content.replace(/<\/?div[^>]*>/gi, ""); |
|
220 |
|
221 // Convert all middlot lists to UL lists |
|
222 if (this.editor.getParam("paste_convert_middot_lists", true)) { |
|
223 var div = document.createElement("div"); |
|
224 div.innerHTML = content; |
|
225 |
|
226 // Convert all middot paragraphs to li elements |
|
227 var className = this.editor.getParam("paste_unindented_list_class", "unIndentedList"); |
|
228 |
|
229 while (this._convertMiddots(div, "--list--")) ; // bull |
|
230 while (this._convertMiddots(div, middot, className)) ; // Middot |
|
231 while (this._convertMiddots(div, bull)) ; // bull |
|
232 |
|
233 content = div.innerHTML; |
|
234 } |
|
235 |
|
236 // Replace all headers with strong and fix some other issues |
|
237 if (this.editor.getParam("paste_convert_headers_to_strong", false)) { |
|
238 content = content.replace(/<h[1-6]> <\/h[1-6]>/gi, '<p> </p>'); |
|
239 content = content.replace(/<h[1-6]>/gi, '<p><b>'); |
|
240 content = content.replace(/<\/h[1-6]>/gi, '</b></p>'); |
|
241 content = content.replace(/<b> <\/b>/gi, '<b> </b>'); |
|
242 content = content.replace(/^( )*/gi, ''); |
|
243 } |
|
244 |
|
245 content = content.replace(/--list--/gi, ""); // Remove --list-- |
|
246 |
|
247 if ((cb = this.editor.getParam("paste_insert_word_content_callback", "")) != "") |
|
248 content = eval(cb + "('after', content)"); |
|
249 |
|
250 // Insert cleaned content |
|
251 this.editor.execCommand("mceInsertContent", false, content); |
|
252 |
|
253 if (this.editor.getParam('paste_force_cleanup_wordpaste', true)) { |
|
254 var ed = this.editor; |
|
255 |
|
256 window.setTimeout(function() { |
|
257 ed.execCommand("mceCleanup"); |
|
258 }, 1); // Do normal cleanup detached from this thread |
|
259 } |
|
260 } |
|
261 }, |
|
262 |
|
263 _reEscape : function(s) { |
|
264 var l = "?.\\*[](){}+^$:"; |
|
265 var o = ""; |
|
266 |
|
267 for (var i=0; i<s.length; i++) { |
|
268 var c = s.charAt(i); |
|
269 |
|
270 if (l.indexOf(c) != -1) |
|
271 o += '\\' + c; |
|
272 else |
|
273 o += c; |
|
274 } |
|
275 |
|
276 return o; |
|
277 }, |
|
278 |
|
279 _convertMiddots : function(div, search, class_name) { |
|
280 var mdot = String.fromCharCode(183); |
|
281 var bull = String.fromCharCode(8226); |
|
282 |
|
283 var nodes = div.getElementsByTagName("p"); |
|
284 var prevul; |
|
285 for (var i=0; i<nodes.length; i++) { |
|
286 var p = nodes[i]; |
|
287 |
|
288 // Is middot |
|
289 if (p.innerHTML.indexOf(search) == 0) { |
|
290 var ul = document.createElement("ul"); |
|
291 |
|
292 if (class_name) |
|
293 ul.className = class_name; |
|
294 |
|
295 // Add the first one |
|
296 var li = document.createElement("li"); |
|
297 li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); |
|
298 ul.appendChild(li); |
|
299 |
|
300 // Add the rest |
|
301 var np = p.nextSibling; |
|
302 while (np) { |
|
303 // If the node is whitespace, then |
|
304 // ignore it and continue on. |
|
305 if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) { |
|
306 np = np.nextSibling; |
|
307 continue; |
|
308 } |
|
309 |
|
310 if (search == mdot) { |
|
311 if (np.nodeType == 1 && new RegExp('^o(\\s+| )').test(np.innerHTML)) { |
|
312 // Second level of nesting |
|
313 if (!prevul) { |
|
314 prevul = ul; |
|
315 ul = document.createElement("ul"); |
|
316 prevul.appendChild(ul); |
|
317 } |
|
318 np.innerHTML = np.innerHTML.replace(/^o/, ''); |
|
319 } else { |
|
320 // Pop the stack if we're going back up to the first level |
|
321 if (prevul) { |
|
322 ul = prevul; |
|
323 prevul = null; |
|
324 } |
|
325 // Not element or middot paragraph |
|
326 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) |
|
327 break; |
|
328 } |
|
329 } else { |
|
330 // Not element or middot paragraph |
|
331 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) |
|
332 break; |
|
333 } |
|
334 |
|
335 var cp = np.nextSibling; |
|
336 var li = document.createElement("li"); |
|
337 li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); |
|
338 np.parentNode.removeChild(np); |
|
339 ul.appendChild(li); |
|
340 np = cp; |
|
341 } |
|
342 |
|
343 p.parentNode.replaceChild(ul, p); |
|
344 |
|
345 return true; |
|
346 } |
|
347 } |
|
348 |
|
349 return false; |
|
350 }, |
|
351 |
|
352 _clipboardHTML : function() { |
|
353 var div = document.getElementById('_TinyMCE_clipboardHTML'); |
|
354 |
|
355 if (!div) { |
|
356 var div = document.createElement('DIV'); |
|
357 div.id = '_TinyMCE_clipboardHTML'; |
|
358 |
|
359 with (div.style) { |
|
360 visibility = 'hidden'; |
|
361 overflow = 'hidden'; |
|
362 position = 'absolute'; |
|
363 width = 1; |
|
364 height = 1; |
|
365 } |
|
366 |
|
367 document.body.appendChild(div); |
|
368 } |
|
369 |
|
370 div.innerHTML = ''; |
|
371 var rng = document.body.createTextRange(); |
|
372 rng.moveToElementText(div); |
|
373 rng.execCommand('Paste'); |
|
374 var html = div.innerHTML; |
|
375 div.innerHTML = ''; |
|
376 return html; |
32 } |
377 } |
33 |
378 }); |
34 return true; |
379 |
35 }, |
380 // Register plugin |
36 |
381 tinymce.PluginManager.add('paste', tinymce.plugins.PastePlugin); |
37 getControlHTML : function(cn) { |
382 })(); |
38 switch (cn) { |
|
39 case "pastetext": |
|
40 return tinyMCE.getButtonHTML(cn, 'lang_paste_text_desc', '{$pluginurl}/images/pastetext.gif', 'mcePasteText', true); |
|
41 |
|
42 case "pasteword": |
|
43 return tinyMCE.getButtonHTML(cn, 'lang_paste_word_desc', '{$pluginurl}/images/pasteword.gif', 'mcePasteWord', true); |
|
44 |
|
45 case "selectall": |
|
46 return tinyMCE.getButtonHTML(cn, 'lang_selectall_desc', '{$pluginurl}/images/selectall.gif', 'mceSelectAll', true); |
|
47 } |
|
48 |
|
49 return ''; |
|
50 }, |
|
51 |
|
52 execCommand : function(editor_id, element, command, user_interface, value) { |
|
53 switch (command) { |
|
54 case "mcePasteText": |
|
55 if (user_interface) { |
|
56 if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && !tinyMCE.getParam('paste_use_dialog', false)) |
|
57 TinyMCE_PastePlugin._insertText(clipboardData.getData("Text"), true); |
|
58 else { |
|
59 var template = new Array(); |
|
60 template['file'] = '../../plugins/paste/pastetext.htm'; // Relative to theme |
|
61 template['width'] = 450; |
|
62 template['height'] = 400; |
|
63 var plain_text = ""; |
|
64 tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", inline : "yes", mceDo : 'insert'}); |
|
65 } |
|
66 } else |
|
67 TinyMCE_PastePlugin._insertText(value['html'], value['linebreaks']); |
|
68 |
|
69 return true; |
|
70 |
|
71 case "mcePasteWord": |
|
72 if (user_interface) { |
|
73 if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && !tinyMCE.getParam('paste_use_dialog', false)) { |
|
74 TinyMCE_PastePlugin._insertWordContent(TinyMCE_PastePlugin._clipboardHTML()); |
|
75 } else { |
|
76 var template = new Array(); |
|
77 template['file'] = '../../plugins/paste/pasteword.htm'; // Relative to theme |
|
78 template['width'] = 450; |
|
79 template['height'] = 400; |
|
80 var plain_text = ""; |
|
81 tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", inline : "yes", mceDo : 'insert'}); |
|
82 } |
|
83 } else |
|
84 TinyMCE_PastePlugin._insertWordContent(value); |
|
85 |
|
86 return true; |
|
87 |
|
88 case "mceSelectAll": |
|
89 tinyMCE.execInstanceCommand(editor_id, 'selectall'); |
|
90 return true; |
|
91 |
|
92 } |
|
93 |
|
94 // Pass to next handler in chain |
|
95 return false; |
|
96 }, |
|
97 |
|
98 // Private plugin internal methods |
|
99 |
|
100 _handlePasteEvent : function(e) { |
|
101 switch (e.type) { |
|
102 case "paste": |
|
103 var html = TinyMCE_PastePlugin._clipboardHTML(); |
|
104 var r, inst = tinyMCE.selectedInstance; |
|
105 |
|
106 // Removes italic, strong etc, the if was needed due to bug #1437114 |
|
107 if (inst && (r = inst.getRng()) && r.text.length > 0) |
|
108 tinyMCE.execCommand('delete'); |
|
109 |
|
110 if (html && html.length > 0) |
|
111 tinyMCE.execCommand('mcePasteWord', false, html); |
|
112 |
|
113 tinyMCE.cancelEvent(e); |
|
114 return false; |
|
115 } |
|
116 |
|
117 return true; |
|
118 }, |
|
119 |
|
120 _insertText : function(content, bLinebreaks) { |
|
121 if (content && content.length > 0) { |
|
122 if (bLinebreaks) { |
|
123 // Special paragraph treatment |
|
124 if (tinyMCE.getParam("paste_create_paragraphs", true)) { |
|
125 var rl = tinyMCE.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); |
|
126 for (var i=0; i<rl.length; i+=2) |
|
127 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); |
|
128 |
|
129 content = tinyMCE.regexpReplace(content, "\r\n\r\n", "</p><p>", "gi"); |
|
130 content = tinyMCE.regexpReplace(content, "\r\r", "</p><p>", "gi"); |
|
131 content = tinyMCE.regexpReplace(content, "\n\n", "</p><p>", "gi"); |
|
132 |
|
133 // Has paragraphs |
|
134 if ((pos = content.indexOf('</p><p>')) != -1) { |
|
135 tinyMCE.execCommand("Delete"); |
|
136 |
|
137 var node = tinyMCE.selectedInstance.getFocusElement(); |
|
138 |
|
139 // Get list of elements to break |
|
140 var breakElms = new Array(); |
|
141 |
|
142 do { |
|
143 if (node.nodeType == 1) { |
|
144 // Don't break tables and break at body |
|
145 if (node.nodeName == "TD" || node.nodeName == "BODY") |
|
146 break; |
|
147 |
|
148 breakElms[breakElms.length] = node; |
|
149 } |
|
150 } while(node = node.parentNode); |
|
151 |
|
152 var before = "", after = "</p>"; |
|
153 before += content.substring(0, pos); |
|
154 |
|
155 for (var i=0; i<breakElms.length; i++) { |
|
156 before += "</" + breakElms[i].nodeName + ">"; |
|
157 after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; |
|
158 } |
|
159 |
|
160 before += "<p>"; |
|
161 content = before + content.substring(pos+7) + after; |
|
162 } |
|
163 } |
|
164 |
|
165 if (tinyMCE.getParam("paste_create_linebreaks", true)) { |
|
166 content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi"); |
|
167 content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi"); |
|
168 content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi"); |
|
169 } |
|
170 } |
|
171 |
|
172 tinyMCE.execCommand("mceInsertRawHTML", false, content); |
|
173 } |
|
174 }, |
|
175 |
|
176 _insertWordContent : function(content) { |
|
177 if (content && content.length > 0) { |
|
178 // Cleanup Word content |
|
179 var bull = String.fromCharCode(8226); |
|
180 var middot = String.fromCharCode(183); |
|
181 var cb; |
|
182 |
|
183 if ((cb = tinyMCE.getParam("paste_insert_word_content_callback", "")) != "") |
|
184 content = eval(cb + "('before', content)"); |
|
185 |
|
186 var rl = tinyMCE.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); |
|
187 for (var i=0; i<rl.length; i+=2) |
|
188 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); |
|
189 |
|
190 if (tinyMCE.getParam("paste_convert_headers_to_strong", false)) { |
|
191 content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>'); |
|
192 } |
|
193 |
|
194 content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--"); |
|
195 content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>"); |
|
196 content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list |
|
197 content = content.replace(/<o:p><\/o:p>/gi, ""); |
|
198 content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks |
|
199 content = content.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), ""); // Word comments |
|
200 |
|
201 if (tinyMCE.getParam("paste_remove_spans", true)) |
|
202 content = content.replace(/<\/?span[^>]*>/gi, ""); |
|
203 |
|
204 if (tinyMCE.getParam("paste_remove_styles", true)) |
|
205 content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3"); |
|
206 |
|
207 content = content.replace(/<\/?font[^>]*>/gi, ""); |
|
208 |
|
209 // Strips class attributes. |
|
210 switch (tinyMCE.getParam("paste_strip_class_attributes", "all")) { |
|
211 case "all": |
|
212 content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); |
|
213 break; |
|
214 |
|
215 case "mso": |
|
216 content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3"); |
|
217 break; |
|
218 } |
|
219 |
|
220 content = content.replace(new RegExp('href="?' + TinyMCE_PastePlugin._reEscape("" + document.location) + '', 'gi'), 'href="' + tinyMCE.settings['document_base_url']); |
|
221 content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3"); |
|
222 content = content.replace(/<\\?\?xml[^>]*>/gi, ""); |
|
223 content = content.replace(/<\/?\w+:[^>]*>/gi, ""); |
|
224 content = content.replace(/-- page break --\s*<p> <\/p>/gi, ""); // Remove pagebreaks |
|
225 content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks |
|
226 |
|
227 // content = content.replace(/\/? */gi, ""); |
|
228 // content = content.replace(/<p> <\/p>/gi, ''); |
|
229 |
|
230 if (!tinyMCE.settings['force_p_newlines']) { |
|
231 content = content.replace('', '' ,'gi'); |
|
232 content = content.replace('</p>', '<br /><br />' ,'gi'); |
|
233 } |
|
234 |
|
235 if (!tinyMCE.isMSIE && !tinyMCE.settings['force_p_newlines']) { |
|
236 content = content.replace(/<\/?p[^>]*>/gi, ""); |
|
237 } |
|
238 |
|
239 content = content.replace(/<\/?div[^>]*>/gi, ""); |
|
240 |
|
241 // Convert all middlot lists to UL lists |
|
242 if (tinyMCE.getParam("paste_convert_middot_lists", true)) { |
|
243 var div = document.createElement("div"); |
|
244 div.innerHTML = content; |
|
245 |
|
246 // Convert all middot paragraphs to li elements |
|
247 var className = tinyMCE.getParam("paste_unindented_list_class", "unIndentedList"); |
|
248 |
|
249 while (TinyMCE_PastePlugin._convertMiddots(div, "--list--")) ; // bull |
|
250 while (TinyMCE_PastePlugin._convertMiddots(div, middot, className)) ; // Middot |
|
251 while (TinyMCE_PastePlugin._convertMiddots(div, bull)) ; // bull |
|
252 |
|
253 content = div.innerHTML; |
|
254 } |
|
255 |
|
256 // Replace all headers with strong and fix some other issues |
|
257 if (tinyMCE.getParam("paste_convert_headers_to_strong", false)) { |
|
258 content = content.replace(/<h[1-6]> <\/h[1-6]>/gi, '<p> </p>'); |
|
259 content = content.replace(/<h[1-6]>/gi, '<p><b>'); |
|
260 content = content.replace(/<\/h[1-6]>/gi, '</b></p>'); |
|
261 content = content.replace(/<b> <\/b>/gi, '<b> </b>'); |
|
262 content = content.replace(/^( )*/gi, ''); |
|
263 } |
|
264 |
|
265 content = content.replace(/--list--/gi, ""); // Remove --list-- |
|
266 |
|
267 if ((cb = tinyMCE.getParam("paste_insert_word_content_callback", "")) != "") |
|
268 content = eval(cb + "('after', content)"); |
|
269 |
|
270 // Insert cleaned content |
|
271 tinyMCE.execCommand("mceInsertContent", false, content); |
|
272 |
|
273 if (tinyMCE.getParam('paste_force_cleanup_wordpaste', true)) |
|
274 window.setTimeout('tinyMCE.execCommand("mceCleanup");', 1); // Do normal cleanup detached from this thread |
|
275 } |
|
276 }, |
|
277 |
|
278 _reEscape : function(s) { |
|
279 var l = "?.\\*[](){}+^$:"; |
|
280 var o = ""; |
|
281 |
|
282 for (var i=0; i<s.length; i++) { |
|
283 var c = s.charAt(i); |
|
284 |
|
285 if (l.indexOf(c) != -1) |
|
286 o += '\\' + c; |
|
287 else |
|
288 o += c; |
|
289 } |
|
290 |
|
291 return o; |
|
292 }, |
|
293 |
|
294 _convertMiddots : function(div, search, class_name) { |
|
295 var mdot = String.fromCharCode(183); |
|
296 var bull = String.fromCharCode(8226); |
|
297 |
|
298 var nodes = div.getElementsByTagName("p"); |
|
299 var prevul; |
|
300 for (var i=0; i<nodes.length; i++) { |
|
301 var p = nodes[i]; |
|
302 |
|
303 // Is middot |
|
304 if (p.innerHTML.indexOf(search) == 0) { |
|
305 var ul = document.createElement("ul"); |
|
306 |
|
307 if (class_name) |
|
308 ul.className = class_name; |
|
309 |
|
310 // Add the first one |
|
311 var li = document.createElement("li"); |
|
312 li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); |
|
313 ul.appendChild(li); |
|
314 |
|
315 // Add the rest |
|
316 var np = p.nextSibling; |
|
317 while (np) { |
|
318 // If the node is whitespace, then |
|
319 // ignore it and continue on. |
|
320 if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) { |
|
321 np = np.nextSibling; |
|
322 continue; |
|
323 } |
|
324 |
|
325 if (search == mdot) { |
|
326 if (np.nodeType == 1 && new RegExp('^o(\\s+| )').test(np.innerHTML)) { |
|
327 // Second level of nesting |
|
328 if (!prevul) { |
|
329 prevul = ul; |
|
330 ul = document.createElement("ul"); |
|
331 prevul.appendChild(ul); |
|
332 } |
|
333 np.innerHTML = np.innerHTML.replace(/^o/, ''); |
|
334 } else { |
|
335 // Pop the stack if we're going back up to the first level |
|
336 if (prevul) { |
|
337 ul = prevul; |
|
338 prevul = null; |
|
339 } |
|
340 // Not element or middot paragraph |
|
341 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) |
|
342 break; |
|
343 } |
|
344 } else { |
|
345 // Not element or middot paragraph |
|
346 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) |
|
347 break; |
|
348 } |
|
349 |
|
350 var cp = np.nextSibling; |
|
351 var li = document.createElement("li"); |
|
352 li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); |
|
353 np.parentNode.removeChild(np); |
|
354 ul.appendChild(li); |
|
355 np = cp; |
|
356 } |
|
357 |
|
358 p.parentNode.replaceChild(ul, p); |
|
359 |
|
360 return true; |
|
361 } |
|
362 } |
|
363 |
|
364 return false; |
|
365 }, |
|
366 |
|
367 _clipboardHTML : function() { |
|
368 var div = document.getElementById('_TinyMCE_clipboardHTML'); |
|
369 |
|
370 if (!div) { |
|
371 var div = document.createElement('DIV'); |
|
372 div.id = '_TinyMCE_clipboardHTML'; |
|
373 |
|
374 with (div.style) { |
|
375 visibility = 'hidden'; |
|
376 overflow = 'hidden'; |
|
377 position = 'absolute'; |
|
378 width = 1; |
|
379 height = 1; |
|
380 } |
|
381 |
|
382 document.body.appendChild(div); |
|
383 } |
|
384 |
|
385 div.innerHTML = ''; |
|
386 var rng = document.body.createTextRange(); |
|
387 rng.moveToElementText(div); |
|
388 rng.execCommand('Paste'); |
|
389 var html = div.innerHTML; |
|
390 div.innerHTML = ''; |
|
391 return html; |
|
392 } |
|
393 }; |
|
394 |
|
395 tinyMCE.addPlugin("paste", TinyMCE_PastePlugin); |
|