TinyMCE i wklejanie tekstu z edytora tekstowego
Osobiście nie przepadam za wszelkiej maści edytorami wizualnymi (WYSIWYG). Uważam, że więcej z nimi problemów niż korzyści. No ale wiadomo, klienta zdanie web developera za bardzo nie interesuje i chce po prostu dodawać treść tak samo łatwo jak w Wordzie. Co w takiej sytuacji zrobić?
W ostatnim czasie pozytywnie zaskoczył mnie TinyMCE 4. Można go praktycznie w dowolny sposób dostosować – od wyboru funkcji na pasku narzędzi po stworzenie styli dostosowanych do potrzeb klienta. Dodatkowo możemy wewnątrz edytora dostosować CSS tak, by treść wyglądała praktycznie tak jak na docelowej podstronie. Inną bardzo przydatną rzeczą jest możliwość usunięcia wszelkich „śmieci” z tekstu wklejanego prosto z edytora tekstu.
Przykład użycia edytora wraz z formatowaniem wklejanego tekstu:
tinymce.init({ selector: "textarea", content_css: "tinymce_content.css", plugins: [ "advlist autolink autosave link image lists charmap print preview hr anchor pagebreak spellchecker", "searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking", "table contextmenu directionality emoticons template textcolor paste fullpage textcolor" ], toolbar1: "newdocument fullpage | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | styleselect", toolbar2: "cut copy paste | searchreplace | bullist numlist | outdent indent blockquote | undo redo | link unlink anchor image media code | inserttime preview | forecolor backcolor", toolbar3: "table | hr removeformat | subscript superscript | charmap emoticons | print fullscreen | ltr rtl | spellchecker | visualchars visualblocks nonbreaking template pagebreak restoredraft", menubar: false, toolbar_items_size: 'small', style_formats: [ {title: 'Wyróżnienie', block: 'h4', classes: 'header1'}, {title: 'Nagłówek', block: 'h5', classes: 'header3'}, {title: 'Tekst standard', block: 'p', classes: 'akapit'}, ], theme_advanced_buttons3_add: "pastetext,pasteword,selectall", paste_auto_cleanup_on_paste: true, paste_preprocess: function(pl, o) { //example: keep bold,italic,underline and paragraphs o.content = strip_tags(o.content, '<b><u><i><p><ul><ol><li><h1><h3>'); // remove all tags => plain text //o.content = strip_tags( o.content,'' ); }, language: "pl", }); // Author: Kevin van Zonne 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; }
Za pomocą strip_tags() wycinam wszystkie znaczniki poza akapitem, listą i podstawową edycją tekstu. Dodatkowo w style_formats definiuję tylko style, które są potrzebne i mam znacząco ograniczoną możliwość rozsypania strony przez klienta :)