1
|
1 |
/**
|
|
2 |
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
|
|
3 |
*
|
|
4 |
* @author Moxiecode
|
|
5 |
* @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
|
|
6 |
*/
|
|
7 |
|
|
8 |
/* Import plugin specific language pack */
|
|
9 |
tinyMCE.importPluginLanguagePack('paste');
|
|
10 |
|
|
11 |
var TinyMCE_PastePlugin = {
|
|
12 |
getInfo : function() {
|
|
13 |
return {
|
|
14 |
longname : 'Paste text/word',
|
|
15 |
author : 'Moxiecode Systems AB',
|
|
16 |
authorurl : 'http://tinymce.moxiecode.com',
|
|
17 |
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste',
|
|
18 |
version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
|
|
19 |
};
|
|
20 |
},
|
|
21 |
|
|
22 |
initInstance : function(inst) {
|
|
23 |
if (tinyMCE.isMSIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false))
|
|
24 |
tinyMCE.addEvent(inst.getBody(), "paste", TinyMCE_PastePlugin._handlePasteEvent);
|
|
25 |
},
|
|
26 |
|
|
27 |
handleEvent : function(e) {
|
|
28 |
// Force paste dialog if non IE browser
|
|
29 |
if (!tinyMCE.isRealIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false) && e.ctrlKey && e.keyCode == 86 && e.type == "keydown") {
|
|
30 |
window.setTimeout('tinyMCE.selectedInstance.execCommand("mcePasteText",true)', 1);
|
|
31 |
return tinyMCE.cancelEvent(e);
|
|
32 |
}
|
|
33 |
|
|
34 |
return true;
|
|
35 |
},
|
|
36 |
|
|
37 |
getControlHTML : function(cn) {
|
|
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);
|