41

This is one of the common issue with RTEs on web. Could you please guide me through how to:

  1. Paste as the PLAIN TEXT
  2. Retain the HTML but remove the WORD/HTML styling

I want to do it directly on paste (paste_preprocess callback), without opening the dialogs provided by Paste plugins.

Any thoughts/experiences ?

Thanks,

Imran

Thariama
  • 50,002
  • 13
  • 138
  • 166
Saim
  • 2,471
  • 5
  • 30
  • 43
  • I think this should clean the text up a bit, but I would appreciate more suggestions/solutions: http://www.1stclassmedia.co.uk/developers/clean-ms-word-formatting.php – Saim Nov 08 '10 at 09:11

6 Answers6

44

This is what i do to get paste plain text.

1. paste_preprocess setting (in tinymce init)

paste_preprocess : function(pl, o) {
  //example: keep bold,italic,underline and paragraphs
  //o.content = strip_tags( o.content,'<b><u><i><p>' );

  // remove all tags => plain text
  o.content = strip_tags( o.content,'' );
},

2. function strip_tags (on the main document)

// Strips HTML and PHP tags from a string 
// returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
// example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
// returns 2: '<p>Kevin van Zonneveld</p>'
// example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
// returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
// example 4: strip_tags('1 < 5 5 > 1');
// returns 4: '1 < 5 5 > 1'
function strip_tags (str, allowed_tags)
{

    var key = '', allowed = false;
    var matches = [];    var allowed_array = [];
    var allowed_tag = '';
    var i = 0;
    var k = '';
    var html = ''; 
    var replacer = function (search, replace, str) {
        return str.split(search).join(replace);
    };
    // Build allowes tags associative array
    if (allowed_tags) {
        allowed_array = allowed_tags.match(/([a-zA-Z0-9]+)/gi);
    }
    str += '';

    // Match tags
    matches = str.match(/(<\/?[\S][^>]*>)/gi);
    // Go through all HTML tags
    for (key in matches) {
        if (isNaN(key)) {
                // IE7 Hack
            continue;
        }

        // Save HTML tag
        html = matches[key].toString();
        // Is tag not in allowed list? Remove from str!
        allowed = false;

        // Go through all allowed tags
        for (k in allowed_array) {            // Init
            allowed_tag = allowed_array[k];
            i = -1;

            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}
            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}
            if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag)   ;}

            // Determine
            if (i == 0) {                allowed = true;
                break;
            }
        }
        if (!allowed) {
            str = replacer(html, "", str); // Custom replace. No regexing
        }
    }
    return str;
}
Thariama
  • 50,002
  • 13
  • 138
  • 166
  • Wow! Thanks Thariama. From where can I get the "replacer" definition? – Saim Nov 08 '10 at 13:40
  • you just enter the tags you want to keep in the strip_tags call – Thariama Nov 08 '10 at 14:38
  • 2
    This is the only solution I have found that removes __all__ tags. The past plugin only has options to remove styling. –  Jun 07 '12 at 16:26
  • @Thariama What to do if you want multiple tags as the second parameter of strip_tags()? – petko_stankoski Nov 14 '12 at 11:39
  • @Scree: it's in the code above: strip_tags( o.content,'

    ' );

    – Thariama Nov 14 '12 at 15:39
  • @Thariama, mayI request you to have a look at a tinyMCE question here http://stackoverflow.com/questions/15386834/jquery-tinymce-2-1-3-get-content-from-the-second-instanceplease ? – Istiaque Ahmed Mar 14 '13 at 12:17
  • its working v nice. but when i paste the text the window scroll to top or jump to start of document? what can it be? – Bilal Rabi May 12 '14 at 20:58
  • the jumping won't have to do with the code in my answer. It might be that on your webpage the tinymce ditor looses focus and resets it when it inserts the pasted content – Thariama May 13 '14 at 09:11
33

Actually, you can now just do this:

plugins: 'paste',
...
paste_auto_cleanup_on_paste : true,
paste_remove_styles: true,
paste_remove_styles_if_webkit: true,
paste_strip_class_attributes: true,

Credit goes to: http://www.miuaiga.com/index.cfm/2010/1/7/New-TinyMCE-lets-you-paste-as-plain-text-automatically

trinth
  • 5,919
  • 9
  • 40
  • 45
12

There is now a new option that replaces all of the above:

tinymce.init({
   paste_as_text: true
});

See http://www.tinymce.com/wiki.php/Configuration:paste_as_text

or in django-tinymce, in the settings.py:

TINYMCE_DEFAULT_CONFIG = {
   'paste_as_text': True,
}
Mario
  • 2,619
  • 1
  • 24
  • 22
10

Was looking all over for this.. For TinyMCE, you can use the builtin paste as text behavior. Just set up the tinymce init with the below values.

Source: jerome.chevreau, http://www.tinymce.com/forum/viewtopic.php?id=6788

//add paste plugin
plugins : 'paste',
//Keeps Paste Text feature active until user deselects the Paste as Text button
paste_text_sticky : true,
//select pasteAsPlainText on startup
setup : function(ed) {
    ed.onInit.add(function(ed) {
        ed.pasteAsPlainText = true;
    });
}
ben
  • 101
  • 1
  • 2
3

I used this:

    oninit: function (ed) {
        ed.pasteAsPlainText = true;
    }

along with

paste_text_sticky: true
Chris
  • 12,192
  • 5
  • 21
  • 23
0

I have used @Thariama solutions but I got one issue.

In paste_preprocess function:

paste_preprocess : function(pl, o) {
  o.content = StripTags( o.content,'' );
  console.log(o.content);
},

Tinymce returns string as:

Original String:

"<h1>History.js Test Suite</h1>
        <p>HTML5 Browsers must pass the HTML4+HTML5 tests, HTML4 Browsers must pass the HTML4 tests and should fail the HTML5 tests.</p>"

Returned string:

&lt;h1&gt;History.js Test Suite&lt;/h1&gt;<br /> <br />&lt;p&gt;HTML5 Browsers must pass the HTML4+HTML5 tests, HTML4 Browsers must pass the HTML4 tests and should fail the HTML5 tests.&lt;/p&gt;

The best I found that will for both string.

var $str1 = '&lt;h1&gt;History.js Test Suite&lt;/h1&gt;<br /> <br />&lt;p&gt;HTML5 Browsers must pass the HTML4+HTML5 tests, HTML4 Browsers must pass the HTML4 tests and should fail the HTML5 tests.&lt;/p&gt;';


function StripTags(string) {

  var decoded_string = $("<div/>").html(string).text();
  return $("<div/>").html(decoded_string).text();

}

console.log(StripTags($str1));

Output:

History.js Test Suite HTML5 Browsers must pass the HTML4+HTML5 tests, HTML4 Browsers must pass the HTML4 tests and should fail the HTML5 tests.

Reference link

Gufran Hasan
  • 8,910
  • 7
  • 38
  • 51