Update TinyMCE to 3.5.6

This commit is contained in:
Colin Kuskie 2012-08-30 16:00:42 -07:00
parent 4f74c4cd3e
commit 3cfc42d38f
134 changed files with 11869 additions and 7611 deletions

File diff suppressed because one or more lines are too long

View file

@ -27,7 +27,7 @@
paste_text_sticky : false,
paste_text_sticky_default : false,
paste_text_notifyalways : false,
paste_text_linebreaktype : "p",
paste_text_linebreaktype : "combined",
paste_text_replacements : [
[/\u2026/g, "..."],
[/[\x93\x94\u201c\u201d]/g, '"'],
@ -76,7 +76,7 @@
// This function executes the process handlers and inserts the contents
// force_rich overrides plain text mode set by user, important for pasting with execCommand
function process(o, force_rich) {
var dom = ed.dom, rng, nodes;
var dom = ed.dom, rng;
// Execute pre process handlers
t.onPreProcess.dispatch(t, o);
@ -89,11 +89,9 @@
if (tinymce.isGecko) {
rng = ed.selection.getRng(true);
if (rng.startContainer == rng.endContainer && rng.startContainer.nodeType == 3) {
nodes = dom.select('p,h1,h2,h3,h4,h5,h6,pre', o.node);
// Is only one block node and it doesn't contain word stuff
if (nodes.length == 1 && o.content.indexOf('__MCE_ITEM__') === -1)
dom.remove(nodes.reverse(), true);
if (o.node.childNodes.length === 1 && /^(p|h[1-6]|pre)$/i.test(o.node.firstChild.nodeName) && o.content.indexOf('__MCE_ITEM__') === -1)
dom.remove(o.node.firstChild, true);
}
}
@ -101,11 +99,11 @@
t.onPostProcess.dispatch(t, o);
// Serialize content
o.content = ed.serializer.serialize(o.node, {getInner : 1});
o.content = ed.serializer.serialize(o.node, {getInner : 1, forced_root_block : ''});
// Plain text option active?
if ((!force_rich) && (ed.pasteAsPlainText)) {
t._insertPlainText(ed, dom, o.content);
t._insertPlainText(o.content);
if (!getParam(ed, "paste_text_sticky")) {
ed.pasteAsPlainText = false;
@ -132,7 +130,7 @@
if (getParam(ed, "paste_text_sticky")) {
ed.windowManager.alert(ed.translate('paste.plaintext_mode_sticky'));
} else {
ed.windowManager.alert(ed.translate('paste.plaintext_mode_sticky'));
ed.windowManager.alert(ed.translate('paste.plaintext_mode'));
}
if (!getParam(ed, "paste_text_notifyalways")) {
@ -157,7 +155,7 @@
if (ed.pasteAsPlainText) {
e.preventDefault();
process({content : textContent.replace(/\r?\n/g, '<br />')});
process({content : dom.encode(textContent).replace(/\r?\n/g, '<br />')});
return;
}
}
@ -172,13 +170,14 @@
if (body != ed.getDoc().body)
posY = dom.getPos(ed.selection.getStart(), body).y;
else
posY = body.scrollTop + dom.getViewPort().y;
posY = body.scrollTop + dom.getViewPort(ed.getWin()).y;
// Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles
// If also needs to be in view on IE or the paste would fail
dom.setStyles(n, {
position : 'absolute',
left : -10000,
top : posY,
left : tinymce.isGecko ? -40 : 0, // Need to move it out of site on Gecko since it will othewise display a ghost resize rect for the div
top : posY - 25,
width : 1,
height : 1,
overflow : 'hidden'
@ -268,8 +267,9 @@
h += n.innerHTML;
});
} else {
// Found WebKit weirdness so force the content into plain text mode
h = '<pre>' + dom.encode(textContent).replace(/\r?\n/g, '<br />') + '</pre>';
// Found WebKit weirdness so force the content into paragraphs this seems to happen when you paste plain text from Nodepad etc
// So this logic will replace double enter with paragraphs and single enter with br so it kind of looks the same
h = '<p>' + dom.encode(textContent).replace(/\r?\n\r?\n/g, '</p><p>').replace(/\r?\n/g, '<br />') + '</p>';
}
// Remove the nodes
@ -359,9 +359,18 @@
}
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
if (tinymce.isIE && document.documentMode >= 9)
if (tinymce.isIE && document.documentMode >= 9 && /<(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)/.test(o.content)) {
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
process([[/(?:<br>&nbsp;[\s\r\n]+|<br>)*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:<br>&nbsp;[\s\r\n]+|<br>)*/g, '$1']]);
// IE9 also adds an extra BR element for each soft-linefeed and it also adds a BR for each word wrap break
process([
[/<br><br>/g, '<BR><BR>'], // Replace multiple BR elements with uppercase BR to keep them intact
[/<br>/g, ' '], // Replace single br elements with space since they are word wrap BR:s
[/<BR><BR>/g, '<br>'] // Replace back the double brs but into a single BR
]);
}
// Detect Word content and process it more aggressive
if (/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(h) || o.wordContent) {
o.wordContent = true; // Mark the pasted contents as word specific content
@ -747,28 +756,24 @@
* plugin, and requires minimal changes to add the new functionality.
* Speednet - June 2009
*/
_insertPlainText : function(ed, dom, h) {
var i, len, pos, rpos, node, breakElms, before, after,
w = ed.getWin(),
d = ed.getDoc(),
sel = ed.selection,
is = tinymce.is,
inArray = tinymce.inArray,
_insertPlainText : function(content) {
var ed = this.editor,
linebr = getParam(ed, "paste_text_linebreaktype"),
rl = getParam(ed, "paste_text_replacements");
rl = getParam(ed, "paste_text_replacements"),
is = tinymce.is;
function process(items) {
each(items, function(v) {
if (v.constructor == RegExp)
h = h.replace(v, "");
content = content.replace(v, "");
else
h = h.replace(v[0], v[1]);
content = content.replace(v[0], v[1]);
});
};
if ((typeof(h) === "string") && (h.length > 0)) {
if ((typeof(content) === "string") && (content.length > 0)) {
// If HTML content with line-breaking tags, then remove all cr/lf chars because only tags will break a line
if (/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(h)) {
if (/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(content)) {
process([
/[\n\r]+/g
]);
@ -785,114 +790,47 @@
[/<\/t[dh]>\s*<t[dh][^>]*>/gi, "\t"], // Table cells get tabs betweem them
/<[a-z!\/?][^>]*>/gi, // Delete all remaining tags
[/&nbsp;/gi, " "], // Convert non-break spaces to regular spaces (remember, *plain text*)
[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"], // Cool little RegExp deletes whitespace around linebreak chars.
[/\n{3,}/g, "\n\n"], // Max. 2 consecutive linebreaks
/^\s+|\s+$/g // Trim the front & back
[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"],// Cool little RegExp deletes whitespace around linebreak chars.
[/\n{3,}/g, "\n\n"] // Max. 2 consecutive linebreaks
]);
h = dom.decode(tinymce.html.Entities.encodeRaw(h));
// Delete any highlighted text before pasting
if (!sel.isCollapsed()) {
d.execCommand("Delete", false, null);
}
content = ed.dom.decode(tinymce.html.Entities.encodeRaw(content));
// Perform default or custom replacements
if (is(rl, "array") || (is(rl, "array"))) {
if (is(rl, "array")) {
process(rl);
}
else if (is(rl, "string")) {
} else if (is(rl, "string")) {
process(new RegExp(rl, "gi"));
}
// Treat paragraphs as specified in the config
if (linebr == "none") {
// Convert all line breaks to space
process([
[/\n+/g, " "]
]);
}
else if (linebr == "br") {
} else if (linebr == "br") {
// Convert all line breaks to <br />
process([
[/\n/g, "<br />"]
]);
}
else {
} else if (linebr == "p") {
// Convert all line breaks to <p>...</p>
process([
[/\n+/g, "</p><p>"],
[/^(.*<\/p>)(<p>)$/, '<p>$1']
]);
} else {
// defaults to "combined"
// Convert single line breaks to <br /> and double line breaks to <p>...</p>
process([
/^\s+|\s+$/g,
[/\n\n/g, "</p><p>"],
[/^(.*<\/p>)(<p>)$/, '<p>$1'],
[/\n/g, "<br />"]
]);
}
// This next piece of code handles the situation where we're pasting more than one paragraph of plain
// text, and we are pasting the content into the middle of a block node in the editor. The block
// node gets split at the selection point into "Para A" and "Para B" (for the purposes of explaining).
// The first paragraph of the pasted text is appended to "Para A", and the last paragraph of the
// pasted text is prepended to "Para B". Any other paragraphs of pasted text are placed between
// "Para A" and "Para B". This code solves a host of problems with the original plain text plugin and
// now handles styles correctly. (Pasting plain text into a styled paragraph is supposed to make the
// plain text take the same style as the existing paragraph.)
if ((pos = h.indexOf("</p><p>")) != -1) {
rpos = h.lastIndexOf("</p><p>");
node = sel.getNode();
breakElms = []; // Get list of elements to break
do {
if (node.nodeType == 1) {
// Don't break tables and break at body
if (node.nodeName == "TD" || node.nodeName == "BODY") {
break;
}
breakElms[breakElms.length] = node;
}
} while (node = node.parentNode);
// Are we in the middle of a block node?
if (breakElms.length > 0) {
before = h.substring(0, pos);
after = "";
for (i=0, len=breakElms.length; i<len; i++) {
before += "</" + breakElms[i].nodeName.toLowerCase() + ">";
after += "<" + breakElms[breakElms.length-i-1].nodeName.toLowerCase() + ">";
}
if (pos == rpos) {
h = before + after + h.substring(pos+7);
}
else {
h = before + h.substring(pos+4, rpos+4) + after + h.substring(rpos+7);
}
}
}
// Insert content at the caret, plus add a marker for repositioning the caret
ed.execCommand("mceInsertRawHTML", false, h + '<span id="_plain_text_marker">&nbsp;</span>');
// Reposition the caret to the marker, which was placed immediately after the inserted content.
// Needs to be done asynchronously (in window.setTimeout) or else it doesn't work in all browsers.
// The second part of the code scrolls the content up if the caret is positioned off-screen.
// This is only necessary for WebKit browsers, but it doesn't hurt to use for all.
window.setTimeout(function() {
var marker = dom.get('_plain_text_marker'),
elm, vp, y, elmHeight;
sel.select(marker, false);
d.execCommand("Delete", false, null);
marker = null;
// Get element, position and height
elm = sel.getStart();
vp = dom.getViewPort(w);
y = dom.getPos(elm).y;
elmHeight = elm.clientHeight;
// Is element within viewport if not then scroll it into view
if ((y < vp.y) || (y + elmHeight > vp.y + vp.h)) {
d.body.scrollTop = y < vp.y ? y : y - vp.h + 25;
}
}, 0);
ed.execCommand('mceInsertContent', false, content);
}
},

View file

@ -1 +1 @@
tinyMCE.addI18n('en.paste_dlg',{"word_title":"Use CTRL+V on your keyboard to paste the text into the window.","text_linebreaks":"Keep linebreaks","text_title":"Use CTRL+V on your keyboard to paste the text into the window."});
tinyMCE.addI18n('en.paste_dlg',{"word_title":"Use Ctrl+V on your keyboard to paste the text into the window.","text_linebreaks":"Keep Linebreaks","text_title":"Use Ctrl+V on your keyboard to paste the text into the window."});