Деловая неделя

Как перенести на веб-сайт красиво (или хотя бы разнообразно) оформленный и структурированный текст: жирный, курсив, зелёный, красный, список, крупный заголовок по центру?..

ЕЖЕНЕДЕЛЬНАЯ РЕКЛАМНАЯ ГАЗЕТА ДЛЯ ПРЕДПРИЯТИЙ «Деловая неделя» (Иркутск)

Визуальные HTML-редакторы (обзор) - (Javascript, DOM)

Просто, быстро, надёжно

Как перенести на веб-сайт красиво оформленный текст? Ну, пусть не «красиво», а просто – разнообразно оформленный и структурированный: жирный, курсив, зелёный, красный, крупный заголовок по центру, абзацный отступ, таблицу, наконец?

Ответ зависит от того, как (где именно) вы создаёте исходный текст, какую роль должен будет он играть на сайте и кто вообще вы – автор дизайна, поставщик новостей или, например, просто гость, добавляющий комментарий. Начнём с последнего. Потому что гостю (в отличие от дизайнера) позволено всё: и зелёный, и красный, и жирный шрифт, и таблицы и даже крупные заголовки. Если, конечно, на сайте (форуме) позволены HTML-тэги.

На доске объявлений «Иркутск» как раз некоторые HTML-тэги позволены (во всяком случае, жирный, курсив и таблицы). Самый простой способ в этом случае – набрать и оформить текст в Word'e или другом текстовом редакторе (OpenOffice на Линуксе), а потом перенести оформленный текст на Доску через буфер обмена (скопировать исходный текст, потом вставить его в форму добавления нового объявления на Доске). Оформление, в основном, сохранится.

Копировать оформленный текст на нашу Доску объявлений можно не только из окна текстового редактора, но и, например, с других HTML-страниц или из сообщений электронной почты. При этом вы можете совершенно не знать правил написания HTML-кода. Что, кстати, является мечтой каждого веб-дизайнера – как оформил, нарисовал страницу где-нибудь в Кореле, так и перенёс её один к одному на сайт, не вникая в особенности HTML-вёрстки.

Мечта дизайнера, в отличие от желаний Гостя, разумеется невыполнима: всё, что дизайнер сделает со шрифтом, должно быть потом корректно и вполне осознанно, разумно, оптимально переведено в HTML. А для этого не существует визуальных HTML-редакторов. Вернее, их существует слишком даже много, но все они врут: переводят дизайн в HTML-код как попало, некачественно, часто используя устаревшие стандарты и прямо-таки чудовищные конструкции. Даже таким продвинутым верстальным продуктам, как QuarkXpress или Scribus доверять нельзя – сгенерированный ими HTML-код нуждается потом в очень тщательной переработке.

Поэтому не надо устанавливать (тем более покупать за деньги!) никаких специальных программ: превратить дизайн rtf-текста (Word, Corel) в HTML-код можно с помощью любой хорошей почтовой программы. Если уж у вас стоит Windows, значит, на ней есть и Outlook Express: просто создайте новое сообщение, выберите в меню Формат пункт HTML и вставьте в текстовое поле через буфер обмена ваш оформленный текст. Там же его можно и доработать – изменить оформление и структуру. Чтобы увидеть (и переработать) потом полученный HTML-код, нужно сохранить письмо как веб-страницу (меню ФайлСохранить какТип файла «Файлы HTML»). Разумеется, если у вас не Windows, а какая-то более современная и надёжная ОС (Linux, Mac OS X), там не будет Outlook Express, но зато полно не менее качественных бесплатных почтовых клиентов (SeaMonkey, FireBird...), которые с успехом можно использовать в качестве визуальных HTML-редакторов.

Существуют и «стопроцентные» специализированные визуальные редакторы – это, например, Composer браузера SeaMonkey: в SeaMonkey, в меню Файл просто выберите пункт Редактировать страницу. Composer SeaMonkey генерирует очень хороший HTML-код (уж ясно лучше, чем Outlook Express), но хороший программист (или дизайнер), конечно же, не станет слепо использовать даже этот код, а, в лучшем случае, может лишь взять его за основу.

Визуальный HTML-редактор он-лайн (прямо на сайте)

Дизайнер или любой другой автор сайта, веб-мастер, php-программист произвольно меняют HTML-код – меняют оформление сайта прямо с помощью написания таких строк, как <span style="font-size:1.2em;">. Редактор новостей (или других обновлений сайта) или Гость, добавляющий объявления или комментарии, могут вообще не знать о существовании какого-то там кода, а пользоваться только визуальными средствами: выделил кусок текста, нажал кнопочку «Ж» – получилось жирно.

Первый вопрос: зачем это делать на сайте? Зачем на сайте визуальный редактор, если туда можно сразу вставить отформатированный в Word'е (или в почтовой программе) текст через буфер обмена? В общем, зачем изобретать велосипед? Всё по той же причине: хороший хозяин (сайта) никогда не доверяет коду, получаемому из других источников. Все присылаемые пользователем HTML-тэги тщательно проверяются и фильтруются специальной программой на сайте; некоторые тэги просто уничтожаются как потенциально опасные (например, <img src="nevinnyi.gif?hacker=ne_spit!">), некоторые сильно изменяются (у них удаляют опасные атрибуты). В итоге получается не совсем то, что пользователь изобразил в Word'е (или даже скопировал с другой HTML-страницы). И пользователю даётся возможность доработать свой текст «напильником» – те же кнопочки «Жирный», «Влево», «По центру», «Заголовок» не в текстовом редакторе, а прямо на сайте.

Как это работает? Как такой визуальный редактор устроен внутри, описано во многих статьях в Интернете. Наберите в Гугле слова «Визуальный редактор HTML designMode» – и читайте. Как правило, самые первые статьи в списке поиска – самые полезные. Мы уже почитали их, и вот наше мнение (на 29.03.09):
краткая и хорошая статья –
(1) Простейший WYSIWYG (визуальный редактор), автор Александр Бурцев;
очень обстоятельная статья –
(2) Пишем правильный online WYSIWYG-редактор, автор, судя по комментариям, Сергей Круглов (на странице нет подписи);
в сети довольно давно существует интересная (правда, очень навороченная) реализация оф-лайнового (целиком на Javascript) WYSIWYG-редактора Владимира Токмакова –
(3) Реформатор.

Технология помещения объявлений на Доску irkutsk.ir2.ru практически полностью построена на материале статьи (1). Но есть и некоторые тонкости (вообще-то если убрать это слово – «практически» – редактор просто не будет работать). Для начала разъяснений мы хотели бы выделить три ключевых слова в описываемых технологиях: DOM, designMode, iframe.

DOM – Document Object Model, Объектная модель HTML-документа, HTML-страницы. Это схема HTML-документа в том виде, в каком его видит браузер. И браузер хранит эту схему – каждой открытой страницы – у себя в памяти, и позволяет обращаться к элементам этой схемы по их именам с помощью языка Javascript. Первый, самый главный элемент этой схемы – Окно браузера (Window), в которое загружается страница.

Чтобы текст в Окне стал доступным для редактирования, надо установить свойству designMode открытого Документа значение "on". Это можно сделать (записать) прямо в HTML-тексте самой страницы; вот что получится: http://irkutsk.ir2.ru/designMode_on.htm. Можно удалять и добавлять буквы текста. Можно было бы добавить и кнопки типа «Жирный», «Курсив», но беда в том, что на открытой для редактирования странице ни одна кнопка и ни одна ссылка не будут работать. Вы не сможете отправить отредактированный текст на сайт или даже просто посмотреть его HTML-код (хотя более опытный пользователь код увидеть сможет).

Поэтому все визуальные редакторы прежде всего помещают редактируемый текст во вложенное окно браузера – элемент DOM IFRAME: http://irkutsk.ir2.ru/idesignMode_on.htm.

Кроссбраузерность (IE, FF, Opera)

Для работы визуального редактора нам необходимо знать, как обратиться к трём элементам схемы DOM в нашем iframe: это, во-первых, сам iframe (мы ведь управляем им из внешнего окна и должны знать, как получить к нему доступ), во-вторых, объект Окно этого iframe, и, в-третьих, объект Документ в этом вложенном окне. С учётом того, что три ведущих браузера (IE, FireFox, Opera) понимают схему DOM каждый по-своему, простенький код обращения к трём объектам, по сути, утраивается.

Тут-то и вылезает недостаток методики доступа к объектам, предложенной в статье (1). Методика основана на проверке свойств браузера – является ли он gecko (движок браузеров Mozilla Firefox, SeaMonkey):

var iHtm = (isGecko) ? document.getElementById("htm") : frames["htm"];

Но проблема в том, что оставшиеся после такой проверки IE и Opera тоже понимают объектную модель документа по-разному, и при такой проверке надо тогда уж к (isGecko) добавлять и (isIE) (как, кстати, делает, например, Phpmyadmin и другие «серьёзные» программы). А потом к этой проверке придётся добавить ещё (isIE7), (isOpera9.5) и т.д.!

Мы выбрали другой путь, подсказанный Реформатором (3) – проверять не браузер, а сразу наличие нужного объекта в схеме DOM:

var iHtm = (frames["htm"]) ? frames["htm"]:document.getElementById("htm");

Ну, а в статье (2) мы подсмотрели очень полезную команду:

iframe.contentWindow.document.execCommand("useCSS", false, true);

Дело в том, что браузеры gecko переводят визуальное оформление в HTML-код, по умолчанию используя CSS; при этом, например, жирный будет выглядеть как <span style="font-weight:bold;">жирный</span>. Но кто ж пустит на свой сайт произвольный CSS (вида «style="")! На Доску объявлений «Иркутск» CSS допускается только в виде classname (<span class="small">). Поэтому для всех этих font-weight пришлось бы заводить отдельные классы и потом их достаточно муторно обрабатывать (если, например, попадётся сразу <span style="font-weight:bold; font-style:italic; text-decoration:underline;">) – можете сами посмотреть в конце файла http://irkutsk.ir2.ru/prices/dn.css – 15 правил для span!). А команда execCommand("useCSS", false, true) заставляет браузер gecko генерировать HTML без использования CSS – простыми <b>, <i>, <u>...

На стороне сервера (фильтрация тэгов)

Существуют визуальные редакторы HTML, которые можно назвать «промышленными», – настолько они тщательно проработаны и огромны. Например, FCKeditor (с открытым исходным кодом). В развёрнутом виде он занимает около четырёх мегабайт (основная часть – Javascript). Судя по предварительному, поверхностному знакомству, он может практически всё (например, в диалоговом режиме генерировать коды ссылок – тщательнее и подробнее, чем MS Office). Но в образце принимающего данные серверного скрипта нет никакой обработки, фильтрации тэгов. Поэтому возникает опять тот же навязчивый вопрос: где такая программа может найти применение? В работе неумелых php-программистов и веб-дизайнеров, не желающих учить HTML-CSS? Звучит как минимум парадоксально. Если для неопытных гостей сайта – это, наверное, более правильно (хотя больше будет похоже на развлечение, отвлекающее от конечной цели – добавить комментарий на форум или объявление на доску).

Мы бы, наверное, поместили эту конструкцию на свою Доску объявлений – просто для интереса, чтоб веселее было, но лень «прикручивать» этого гиганта к файлам сайта, занимающим всего 200Кб. Вот если бы в FCKeditor'е ещё и приём полученного кода на сервере был организован так же тщательно! А так – всё приходится самим...

Текст (с HTML-разметкой), получаемый сервером от пользователя, обычно потом выводится на каких-то страницах сайта в определённом контексте, как часть шаблонной страницы. Поэтому многие HTML-тэги в сгенерированном автоматически коде (например, в почтовом клиенте или при копировании из Word'а) будут просто лишними: это, например, тэги meta, link, title. Некоторые тэги могут быть вставлены в код со злым умыслом (например, script, img). Практически в любом тэге может быть вставлен потенциально опасный атрибут (что-нибудь вроде onmouseover="дайте_мне_ваши_cookie!").

Задача в первом приближении выглядит как «удалить всё опасное и оставить полезное». При работе с текстом подобные операции обычно выполняются с помощью регулярных выражений (они существуют в любом языке: и perl, и php, и Java, и javascript...). Во втором приближении следует решить, как именно мы будем удалять текст, так или иначе привязанный к разным тэгам. На уровне тэгов получается примерно 3 схемы:

1) удалить полностью открывающий и закрывающий тэги и весь текст между ними; это, например, <script>var abc;</script> или <style>p {display:none};</style>;

2) удалить полностью единичный тэг со всеми атрибутами (например, <meta keyword=''>;

3) удалить полностью открывающий и закрывающий тэги но оставить весь текст между ними (например, ссылки <a href=''>мой сайт</a>).

На уровне атрибутов мы решили сохранять colspan и rowspan в тэгах th, td (да в общем, всё равно, в каких тэгах) и атрибут вида class="abc" в любых тэгах.

Третья ступень решения – составить списки тэгов и атрибутов, удовлетворяющих заданным условиям, и поместить эти списки в массивы. Ну, и потом мелочи (составляющие радость жизни php-программиста): написать регулярные выражения для решения каждой группы задач и прогнать каждый массив тэгов через соответствующий регэксп. А потом ещё «доработать напильником» то, что не удалось обработать en mass. В общем, это не та часть кода сайта irkutsk.ir2.ru, которой мы можем похвастать и выложить в общий доступ как нечто законченное. Хватит с вас пока и Javascript'а в файле http://irkutsk.ir2.ru/idesignMode_on.htm. Когда система приёма HTML-кода на сайте irkutsk.ir2.ru достигнет идеала, напишем вторую часть этой статьи.

© 2009, «Деловая неделя», Михаил Гутентог

Читать все комментарии (1)

20. D.M., admin

Mozilla Rich Text Editing Demo – вот наиболее подходящий образец для извлечения оттуда чего-то полезного и помещения к себе на сайт.

Мы так и сделали на своей Доске объявлений – добавили почти все кнопочки, какие захотели. Осталось ещё только Таблицу добавить.

11.04.2009 06:23:21

Добавить комментарий:

*Автор:
E-Mail:
*Текст: