Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Визуальный редактор - удаление word форматирования
 
 автор: devil943   (21.08.2009 в 02:50)   письмо автору
 
 

Пишу визуальный редактор, встав вопрос об удалении вордовского мусора из текста. Делать это надо средствами js. Вот что я накатал и думал что этого будет довольно...:

pasteCache = pasteCache.replace(/<strong(\s+|>)/g, "<b>"); // Замена всех элементов strong на на b        
pasteCache = pasteCache.replace(/<\/strong(\s+|>)/g, "</b>"); 
pasteCache = pasteCache.replace(/<em(\s+|>)/g, "<i>"); // Замена всех элементов em на на i    
pasteCache = pasteCache.replace(/<\/em(\s+|>)/g, "</i>");
pasteCache = pasteCache.replace(/<[^>]*>/g, function(match)    {
    match = match.replace(/ ([^=]+)="[^"]*"/g, function(match2, attributeName)    {
        if (attributeName == "alt" ||
 attributeName == "href" ||
 attributeName == "src" ||
 attributeName == "title" ||
 attributeName == "width" ||
 attributeName == "height" ||
 attributeName == "cellpadding" ||
 attributeName == "cellspacing"){
                return match2;
        }
        return "";
    });
    return match;
});
pasteCache = pasteCache.replace(/<\?xml[^>]*>/g, "");
pasteCache = pasteCache.replace(/<[^ >]+:[^>]*>/g, "");
pasteCache = pasteCache.replace(/<\/[^ >]+:[^>]*>/g, "");


Но прекрасно работает в Chrome.
Но возник вопрос с оперой и ФФ.
Первая вставляет текст вообще без форматирования. Как бороться?
Второй оставляет кучу г*вна после оботки ( в том числе мета теги, стили и тд).

Что делать?
Использовать сторонние редакторы не предлагать :)

  Ответить  
 
 автор: devil943   (21.08.2009 в 03:06)   письмо автору
 
   для: devil943   (21.08.2009 в 02:50)
 

В IE не пашет, но, по всей видимости, по причине того, что теги там вставляются в верхнем регистре, т.е надо все теги делать например в нижнем.

UPD: Также после чистки остаются пустые спайны (т.е они не пустые, внутри текст, но без атрибутов => не нужны).
Почему-то код:
pasteCache = pasteCache.replace(/<span>/g, ""); 
pasteCache = pasteCache.replace(/<\/span>/g, "");

не пашет... о_О

  Ответить  
 
 автор: PAT   (22.08.2009 в 00:26)   письмо автору
 
   для: devil943   (21.08.2009 в 03:06)
 

1. У вас ошибка - символы < и > используются в регулярных выражениях как специальные,
потому вам их надо экранировать обратным флешем.

2. Кроме того, ваше регулярное выражение можно улучшить, добавив модификатор i - чтобы
удалялись <SPAN>'ы, написанные любым регистром (и <SPAN>, и <span>, и <sPaN>).

3. Ну и, наконец, для удаления начальных и конечных тегов <SPAN> вполне достаточно
одного регулярного выражения вместо ваших двух. Для этого нужно использовать
квантификатор ?, означающий "ноль совпадений или одно совпадение".

Окончательно вместо двух ваших строк можно записать одну:
pasteCache = pasteCache.replace (/\<\/?span\>/ig, ""); 

Перечисленное в пп.1-2 вам надо применить и при замене тегов <STRONG> и <EM>.

  Ответить  
 
 автор: devil943   (22.08.2009 в 04:35)   письмо автору
 
   для: PAT   (22.08.2009 в 00:26)
 

Спасибо, работает, элегантно, без карманов)
А как быть с оперой, фоксом и ie?

Вот код скрипта, который отвечает за чистку кода:
cleanPaste : function(textarea_id) {
        var iframe = dID("wysiwyg_"+textarea_id);
        if(confirm("Убрать из вставленного текста лишние элементы?")) {
            var pasteCache = iframe.contentWindow.document.getElementsByTagName("body")[0].innerHTML;
            
            /* Заменяем теги */
            pasteCache = pasteCache.replace(/<strong(\s+|>)/ig, "<b>"); // Замена всех элементов strong на на b        
            pasteCache = pasteCache.replace(/<\/strong(\s+|>)/ig, "</b>"); 
            pasteCache = pasteCache.replace(/<em(\s+|>)/ig, "<i>"); // Замена всех элементов em на на i    
            pasteCache = pasteCache.replace(/<\/em(\s+|>)/ig, "</i>");
            pasteCache = pasteCache.replace (/\<\/?span\>/ig, ""); // Удалем спайны
            pasteCache = pasteCache.replace(/<[^>]*>/ig, function(match)    {
                match = match.replace(/ ([^=]+)="[^"]*"/g, function(match2, attributeName)    {
                    alert(attributeName);
                    if (attributeName == "alt" ||
 attributeName == "href" ||
 attributeName == "src" ||
 attributeName == "title" ||
 attributeName == "width" ||
 attributeName == "height" ||
 attributeName == "cellpadding" ||
 attributeName == "cellspacing"){
                        return match2;
                    }
                    return "";
                });

                return match;
            });
            pasteCache = pasteCache.replace(/<\?xml[^>]*>/ig, "");
            pasteCache = pasteCache.replace(/<[^ >]+:[^>]*>/ig, "");
            pasteCache = pasteCache.replace(/<\/[^ >]+:[^>]*>/ig, "");
            iframe.contentWindow.document.getElementsByTagName("body")[0].innerHTML = pasteCache;
        }
    }

Он вызывается событиями, которые я вставляю в iframe:
if(!this.isIE) iframeDoc.addEventListener("keydown", function(e){wysiwyg.detectPaste(e,textarea_id); return true;}, false); // Событие по нажатию кнопки (для чистки вставленого)
        else iframeDoc.attachEvent("onkeydown", function(e){wysiwyg.detectPaste(e,textarea_id); return true;}, false);


isIE задается так:
this.isIE = /*@cc_on!@*/false;

Управление передается скрипту, который запускает cleanPaste через таймаут 100мс (чтобы текст успел вставиться) если был нажат контрол и клавиша 86 (v).

Во всех браузерах событие выполняется и до cleanPaste дело доходит, но, как я уже писал, в опере текста вставляется вообще без форматирования, в ие код чистится частично (удаляются стили и классы у элементов B и тд, но остаются у p и font. В ФФ вставляется вообще куча кода, который, опять же, частично чистится, но не до конца. В хроме все (и в сафари, наверное, тоже) все ок.
Что я недоглядел, почему в ИЕ не полностью чистися код, баг ли моего конкретно висивига - отсутствие форматироание в тексте в опере и как бороться с фоксом.

Заранее спасибо!

  Ответить  
 
 автор: PAT   (22.08.2009 в 06:12)   письмо автору
 
   для: devil943   (22.08.2009 в 04:35)
 

Что-то не очень у вас с логикой и внимательностью :-)

1. Даёте код функции под именем cleanPaste
И тут же показываете вызов функции под именем detectPaste (???)
Нет, я, конечно же, понял, что cleanPaste как-то вызывается из detectPaste...
но мог бы и не догадаться :-)

2. Мою самую последнюю рекомендацию (распространить пункты 1 и 2 при замене
<STRONG> и <EM>) вы восприняли почему-то ЧАСТИЧНО.
Пункт 2 (по поводу модификатора i) вы учли.
А вот насчет того, что символы < и > надо экранировать обратным слешем, вы ЗАБЫЛИ.

Порекомендую сначала отработать только ОЧИСТКУ, в потом уж заняться подключением
функций и прочими проблемами.
Поэтому пока ограничусь замечаниями по замене <STRONG> и <EM>.
Заменяете вы с ОШИБКОЙ.
В тех случаях, когда надо менять "чистый" тег (безо всяких атрибутов), то записанное
у вас работает ПРАВИЛЬНО.
А вот когда в тегах имеется какой-либо атрибут, то у вас на выходе - ерунда.
Из <strong style="color: red">
у вас получается    <b>style="color: red">
а должно получиться <b style="color: red">
Заметили разницу?

Вполне достаточным поэтому будет заменять только <STRONG на <B и <EM на <I - без
учёта последующих возможного пробела или символа >.
Для тега <EM надо будет учесть, что это может быть частью тега <EMBED>, поэтому надо
"заглянуть вперёд" и сказать браузеру, что замену проводить только если далее
не будет символа b (в коде я это "заглядывание" выделил жирно).

В общем, четыре ваших строчки после комментария /* Заменяем теги */ замените на две:
pasteCache = pasteCache.replace (/\<strong/ig, '<b').replace (/\<\/strong\>/ig, '</b>');
pasteCache = pasteCache.replace (/\<em(?!b)/ig, '<i').replace (/\<\/em\>/ig, '</i>');

Ну и объясните на пальцах (простыми словами) что именно вы хотите делать следующей
вашей строкой (коя после удаления <SPAN>'ов и со встроенной функцией)?

  Ответить  
 
 автор: devil943   (22.08.2009 в 14:00)   письмо автору
 
   для: PAT   (22.08.2009 в 06:12)
 

Следующая регулярка находит все атрибуты ([^=]+)="[^"]*" , кладет сам атрибут в переменную attributeName. Далее идет условие, если это не атрибут из условия , то заменяем на пустую строку, иначе - на сам атрибут.
Т.е регулярка вычищает атрибуты style, class и другие, которые во множестве вставляет ворд.

  Ответить  
 
 автор: mihdan   (21.08.2009 в 14:06)   письмо автору
 
   для: devil943   (21.08.2009 в 02:50)
 

Смотрите http://novikov.ua/cleaner/

  Ответить  
 
 автор: devil943   (21.08.2009 в 18:44)   письмо автору
 
   для: mihdan   (21.08.2009 в 14:06)
 

Хм... чесно говоря я не понял на каком языке это написано... в IE 8, даже в режиме совместимости, у меня это не работает, в остальных браузерах тоже.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования