static/tinymce/plugins/paste/editor_plugin_src.js
function(content) {
			var ed = this.editor,
				linebr = getParam(ed, "paste_text_linebreaktype"),
				rl = getParam(ed, "paste_text_replacements"),
				is = tinymce.is;

			function process(items) {
				each(items, function(v) {
					if (v.constructor == RegExp)
						content = content.replace(v, "");
					else
						content = content.replace(v[0], v[1]);
				});
			};

			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(content)) {
					process([
						/[\n\r]+/g
					]);
				} else {
					// Otherwise just get rid of carriage returns (only need linefeeds)
					process([
						/\r+/g
					]);
				}

				process([
					[/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi, "\n\n"],		// Block tags get a blank line after them
					[/<br[^>]*>|<\/tr>/gi, "\n"],				// Single linebreak for <br /> tags and table rows
					[/<\/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.
				]);

				var maxLinebreaks = Number(getParam(ed, "paste_max_consecutive_linebreaks"));
				if (maxLinebreaks > -1) {
					var maxLinebreaksRegex = new RegExp("\n{" + (maxLinebreaks + 1) + ",}", "g");
					var linebreakReplacement = "";

					while (linebreakReplacement.length < maxLinebreaks) {
						linebreakReplacement += "\n";
					}

					process([
						[maxLinebreaksRegex, linebreakReplacement] // Limit max consecutive linebreaks
					]);
				}

				content = ed.dom.decode(tinymce.html.Entities.encodeRaw(content));

				// Perform default or custom replacements
				if (is(rl, "array")) {
					process(rl);
				} 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") {
					// Convert all line breaks to <br />
					process([
						[/\n/g, "<br />"]
					]);
				} 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([
						[/\n\n/g, "</p><p>"],
						[/^(.*<\/p>)(<p>)$/, '<p>$1'],
						[/\n/g, "<br />"]
					]);
				}

				ed.execCommand('mceInsertContent', false, content);
			}
		}
function(content) {
			var ed = this.editor,
				linebr = getParam(ed, "paste_text_linebreaktype"),
				rl = getParam(ed, "paste_text_replacements"),
				is = tinymce.is;

			function process(items) {
				each(items, function(v) {
					if (v.constructor == RegExp)
						content = content.replace(v, "");
					else
						content = content.replace(v[0], v[1]);
				});
			};

			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(content)) {
					process([
						/[\n\r]+/g
					]);
				} else {
					// Otherwise just get rid of carriage returns (only need linefeeds)
					process([
						/\r+/g
					]);
				}

				process([
					[/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi, "\n\n"],		// Block tags get a blank line after them
					[/<br[^>]*>|<\/tr>/gi, "\n"],				// Single linebreak for <br /> tags and table rows
					[/<\/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.
				]);

				var maxLinebreaks = Number(getParam(ed, "paste_max_consecutive_linebreaks"));
				if (maxLinebreaks > -1) {
					var maxLinebreaksRegex = new RegExp("\n{" + (maxLinebreaks + 1) + ",}", "g");
					var linebreakReplacement = "";

					while (linebreakReplacement.length < maxLinebreaks) {
						linebreakReplacement += "\n";
					}

					process([
						[maxLinebreaksRegex, linebreakReplacement] // Limit max consecutive linebreaks
					]);
				}

				content = ed.dom.decode(tinymce.html.Entities.encodeRaw(content));

				// Perform default or custom replacements
				if (is(rl, "array")) {
					process(rl);
				} 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") {
					// Convert all line breaks to <br />
					process([
						[/\n/g, "<br />"]
					]);
				} 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([
						[/\n\n/g, "</p><p>"],
						[/^(.*<\/p>)(<p>)$/, '<p>$1'],
						[/\n/g, "<br />"]
					]);
				}

				ed.execCommand('mceInsertContent', false, content);
			}
		}
Instead of the old plain text method which tried to re-create a paste operation, the
new approach adds a plain text mode toggle switch that changes the behavior of paste.
This function is passed the same input that the regular paste plugin produces.
It performs additional scrubbing and produces (and inserts) the plain text.
This approach leverages all of the great existing functionality in the paste
plugin, and requires minimal changes to add the new functionality.
Speednet - June 2009