HTML5 WYSIWYG рд╕рдВрдкрд╛рджрдХ (рд╕рдВрддреЛрд╖рдкреНрд░рдж) рдореЗрдВ MS Word рд╕реЗ рдкрд╛рда рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддреЗ рд╕рдордп HTML рдХреЛрдб рдХреЛ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ

рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ!

рдореЗрд░реЗ WYSIWYG рд╕рдВрдкрд╛рджрдХ рдХреЛ рд▓рд┐рдЦрддреЗ рд╕рдордп, Word рд╕реЗ рдкрд╛рда рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдереАред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рддреАрди рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ:

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ jquery рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕рдХрд╛ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИред рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:

$('#editor'). msword_html_filter(); 

рдкреНрд▓рдЧрдЗрди рдХреЛ рдХреАрдк рдИрд╡реЗрдВрдЯ рдкрд░ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╕рдВрдкрд╛рджрдХ рдХреЗ рдЕрдВрджрд░ рд╕реНрд░реЛрдд рдХреЛрдб рд╡рд░реНрдб рд╕реЗ рдЪрд┐рдкрдХрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рдХреНрд▓реАрдирдЕрдк рдлрд╝рдВрдХреНрд╢рди рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рд╕рдм рдХреБрдЫ рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдореА HTML рдореЗрдВ рдорд╛рд░рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - inextricable рд░рд┐рдХреНрдд рд╕реНрдерд╛рди, рд╢реИрд▓реА рдФрд░ рд╕рдВрд░реЗрдЦрд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ, рдЕрд╡рдзрд┐ рдЯреИрдЧ, рд╕рднреА Mso рд╡рд░реНрдЧ, рдЦрд╛рд▓реА рдЕрдиреБрдЪреНрдЫреЗрджред

рдХрдЯреМрддреА рдХреЗ рддрд╣рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдгред

рдХреЛрдбрдбреЗрди рдкрд░ UPD рдбреЗрдореЛ



рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдирд┐рдпрдорд┐рдд рдЯрд┐рдиреАрдПрдорд╕реАрдИ рджреНрд╡рд╛рд░рд╛ рдЬрд╛рд╕реВрд╕реА рдХреА рдЧрдИ рд╣реИред

рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╡рд░реНрдб рд╕реЗ рдПрдХ рд▓рд╛рдЗрди рдореЗрдВ рдбрд╛рд▓рд╛ рдЧрдпрд╛ HTML рдХреЛрдб рдХреНрдпрд╛ рд╣реИ:

 if (/class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i.test( content )) { ... } 


рдХреЛрдб рдХреЛ рд╕рд╛рдл рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп (jquery рд╕рдВрдкрд╛рджрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ):

 function word_filter(editor){ var content = editor.html(); // Word comments like conditional comments etc content = content.replace(/<!--[\s\S]+?-->/gi, ''); // Remove comments, scripts (eg, msoShowComment), XML tag, VML content, // MS Office namespaced tags, and a few other tags content = content.replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, ''); // Convert <s> into <strike> for line-though content = content.replace(/<(\/?)s>/gi, "<$1strike>"); // Replace nbsp entites to char since it's easier to handle //content = content.replace(/ /gi, "\u00a0"); content = content.replace(/ /gi, ' '); // Convert <span style="mso-spacerun:yes">___</span> to string of alternating // breaking/non-breaking spaces of same length content = content.replace(/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi, function(str, spaces) { return (spaces.length > 0) ? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : ''; }); editor.html(content); // Parse out list indent level for lists $('p', editor).each(function(){ var str = $(this).attr('style'); var matches = /mso-list:\w+ \w+([0-9]+)/.exec(str); if (matches) { $(this).data('_listLevel', parseInt(matches[1], 10)); } }); // Parse Lists var last_level=0; var pnt = null; $('p', editor).each(function(){ var cur_level = $(this).data('_listLevel'); if(cur_level != undefined){ var txt = $(this).text(); var list_tag = '<ul></ul>'; if (/^\s*\w+\./.test(txt)) { var matches = /([0-9])\./.exec(txt); if (matches) { var start = parseInt(matches[1], 10); list_tag = start>1 ? '<ol start="' + start + '"></ol>' : '<ol></ol>'; }else{ list_tag = '<ol></ol>'; } } if(cur_level>last_level){ if(last_level==0){ $(this).before(list_tag); pnt = $(this).prev(); }else{ pnt = $(list_tag).appendTo(pnt); } } if(cur_level<last_level){ for(var i=0; i<last_level-cur_level; i++){ pnt = pnt.parent(); } } $('span:first', this).remove(); pnt.append('<li>' + $(this).html() + '</li>') $(this).remove(); last_level = cur_level; }else{ last_level = 0; } }) $('[style]', editor).removeAttr('style'); $('[align]', editor).removeAttr('align'); $('span', editor).replaceWith(function() {return $(this).contents();}); $('span:empty', editor).remove(); $("[class^='Mso']", editor).removeAttr('class'); $('p:empty', editor).remove(); } 


рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рддрд╣рдд рдкреНрд▓рдЧрдЗрди рдХрд╛ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб, jquery.msword_html_filter.js рдкрд░ рд╕рд╣реЗрдЬреЗрдВ

рдкреНрд▓рдЧрдЗрди рд╕реНрд░реЛрдд
 (function($) { $.fn.msword_html_filter = function(options) { var settings = $.extend( {}, options); function word_filter(editor){ var content = editor.html(); // Word comments like conditional comments etc content = content.replace(/<!--[\s\S]+?-->/gi, ''); // Remove comments, scripts (eg, msoShowComment), XML tag, VML content, // MS Office namespaced tags, and a few other tags content = content.replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, ''); // Convert <s> into <strike> for line-though content = content.replace(/<(\/?)s>/gi, "<$1strike>"); // Replace nbsp entites to char since it's easier to handle //content = content.replace(/ /gi, "\u00a0"); content = content.replace(/ /gi, ' '); // Convert <span style="mso-spacerun:yes">___</span> to string of alternating // breaking/non-breaking spaces of same length content = content.replace(/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi, function(str, spaces) { return (spaces.length > 0) ? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : ''; }); editor.html(content); // Parse out list indent level for lists $('p', editor).each(function(){ var str = $(this).attr('style'); var matches = /mso-list:\w+ \w+([0-9]+)/.exec(str); if (matches) { $(this).data('_listLevel', parseInt(matches[1], 10)); } }); // Parse Lists var last_level=0; var pnt = null; $('p', editor).each(function(){ var cur_level = $(this).data('_listLevel'); if(cur_level != undefined){ var txt = $(this).text(); var list_tag = '<ul></ul>'; if (/^\s*\w+\./.test(txt)) { var matches = /([0-9])\./.exec(txt); if (matches) { var start = parseInt(matches[1], 10); list_tag = start>1 ? '<ol start="' + start + '"></ol>' : '<ol></ol>'; }else{ list_tag = '<ol></ol>'; } } if(cur_level>last_level){ if(last_level==0){ $(this).before(list_tag); pnt = $(this).prev(); }else{ pnt = $(list_tag).appendTo(pnt); } } if(cur_level<last_level){ for(var i=0; i<last_level-cur_level; i++){ pnt = pnt.parent(); } } $('span:first', this).remove(); pnt.append('<li>' + $(this).html() + '</li>') $(this).remove(); last_level = cur_level; }else{ last_level = 0; } }) $('[style]', editor).removeAttr('style'); $('[align]', editor).removeAttr('align'); $('span', editor).replaceWith(function() {return $(this).contents();}); $('span:empty', editor).remove(); $("[class^='Mso']", editor).removeAttr('class'); $('p:empty', editor).remove(); } return this.each(function() { $(this).on('keyup', function(){ var content = $(this).html(); if (/class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i.test( content )) { word_filter( $(this) ); } }); }); }; })( jQuery ) 


рдкреНрд░рджрд░реНрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреЗрд╡рд▓ рдирд╡реАрдирддрдо рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

Source: https://habr.com/ru/post/In194848/


All Articles