Салимóненко Дмитрий Александрович

Разное


Мой визуальный редактор HTML

В свое время, как только начал более-менее серьезно заниматься сайтами и т.д., стал искать себе подходящий редактор HTML. Чтобы, по возможности, быстрее делать вебстраницы. Как я уже писал тут где-то у себя, перебрал достаточно много разных редакторов. В итоге, остановился на Notepad++ (для мелких и легких работ) и PHPStorm. Ну, и, конечно, плагин к Word – doctoHtml, если изначально текст страницы создаю в Word.

Однако, все-таки оба этих редактора предназначены больше для профессиональной работы с программным кодом (т.е. для программирования), а не с контентом вебстраницы. Контент в них, конечно, тоже можно делать (что я и делал; да и не только я), но, как бы сказать, хотелось бы что-то поудобнее. Несмотря на то, что тот же PHPStorm имеет возможность создавать макросы, шаблоны вставок кода и шаблоны вебстраниц в целом и ряд другой полезной функциональности. Не там хватает именно визуальности. Ну, т.е. это чтобы пару раз кнопкой мыши щелкнуть – и было готово, без лишних размышлений и воспоминаний, какое сочетание клавиш надо нажать, какую аббревиатуру ввести и т.д. Чтобы я перед вставкой шаблона html-кода видел его глазами – примерно как он будет выглядеть. Иными словами, все-таки постоянно думал о редакторе WYSIWYG (переводится примерно так: что вижу, то и делаю - What You See Is What You Get). Согласно Википедии,

которую я иногда, все же, читаю, хотя в свое время, вроде бы. отказался от нее это - свойство прикладных программ или веб-интерфейсов, в которых содержание отображается в процессе редактирования и выглядит максимально близко похожим на конечную продукцию, которая может быть печатным документом, веб-страницей или презентацией. В настоящее время для подобных программ также широко используется понятие «визуальный редактор».

А я люблю оформлять страницы не просто в виде текста/рисунков/таблиц – а с учетом пояснений, выделенных мест и т.д. Да, это вполне можно делать вручную (т.е. путем набора html-тегов) в том же PHPStorm, но оправданно это лишь для простых выделений или чего-то подобного. А когда нужно реализовать более сложный (пусть и готовый) шаблон – это уже приходится его, как минимум, найти. Например, на этом сайте пара широко применяемых мною шаблонов присутствует на Технической странице.

После этого следует скопировать, вставить его в нужное место html-кода, затем заполнить контентом (т.е. словами или чем-то еще). Добро, если страница – небольшая. А при довольно большом ее размере – каждый раз при вставке шаблона кода приходится искать место, куда же его следует вставить. Потом надо посмотреть в браузере – как оно отображается на странице. Потом снова надо в PHPStorm, снова делать вставки, исправления и т.д. Если нужно вставить шаблон – нужно помнить его название/аббревиатуру; ну, или открывать список шаблонов, где они показаны, увы, в виде html-кода, а не визуально.

Т.е. это все вполне можно делать, но как-то хлопотно.

Иными словами, это вполне делается и довольно быстро (при надлежащей сноровке), но хочется еще быстрее и удобнее. А это уже – WYSIWYG. Причем, работающий через браузер. Ибо именно в браузере страница отображается так, как она будет видна пользователям.

В свое время такой редактор я делать начинал. Потом понял, что иду, скажем так, не по тому пути. И забросил разработку на сколько-то лет. А недавно вспомнил и кое-что поменял. И что-то в итоге получилось.

Надо сказать, что в общем случае WYSIWYG редактор HTML невозможен. Как минимум, потому, что:

  1. Часть контента страницы может формироваться путем работы скриптов (javascript).
  2. Часть контента может подгружаться или изменяться в процессе взаимодействия со страницей.
  3. Кроме того, существуют еще требования адаптивного дизайна. Без которых нынче не обходится, наверное, ни один сайт.

Реализовывать все это автоматически возможно, разве что, при помощи искусственного интеллекта. Ну, или вручную – что обычно многие и делают.

Да, еще путем применения разных библиотек, но это, на мой взгляд, гиблый путь, если начать им злоупотреблять. Потому что в итоге разработчик оказывается более-менее привязанным к той или иной библиотеке. А потом, когда обнаружится ее ограниченность или ошибки – может встать вопрос о кардинальном переходе на другую библиотеку. А это – довольно напряженно и трудно.

Поэтому я сразу обозначил для себя, скажем так, технические условия.

Любопытно, но мне приходится даже для СЕБЯ устанавливать некоторые правила/ограничения, чтобы двигаться в разработке дальше.

1. Ограничил область деятельности:

WYSIWYG-редактированию подлежит только определенная область на странице (например, основной контент). Все остальное можно исправлять только обычным образом – через PHPStorm или что-то подобное.

Чтобы обозначить такую область в html-коде страницы, я решил сделать соответствующие комментарии в нем. Т.е. все то, что находится между ними, может быть отредактировано в данном визуальном редакторе и затем будет сохранено на сервере. Для этого сайта такие, к примеру, комментарии:

<!--  __Begin_main_content__ -->

… (контент) …

<!--  __Finish-main-content__ -->

В состав контента может входить обычный текст, рисунки, таблицы, видео и т.д. Внутри этого контента могут находиться соответствующие шаблоны html-кода.

Каждый из которых, конечно, является адаптивным, т.е. правильно отображается при любых разрешениях экрана.

2. Суть технологии работы редактора – достаточно простая:

на странице делаются изменения (осуществляется ее редактирование), после чего контент, содержащийся между указанными комментариями, пересылается на сервер и там вставляется в соответствующее место в файле, в котором содержится html-код страницы. Точнее, старый контент, ранее присутствовавший между данными комментариями в этом файле, заменяется на новый контент, пришедший от клиента (браузера).

Если, что сейчас более принято, сайт реализован на базах данных, то запись будет производиться, соответственно, в базу данных. Правда, это я не реализовывал, ограничился работой с файлами.

3. Само редактирование делается средствами браузера + javascript.

Для этого на редактируемую страницу после ее очередного обновления добавляется определенный скрипт, который, собственно, и управляет всей работой. На страницу добавляется специальная рабочая панель, ну, и т.д.

4. Режим редактирования

Это если на сайте включен(!) режим редактирования. Если он выключен, то страница отображается в обычном режиме, без панели.

Т.е. страница отображается в режиме максимально приближенному к режиму «как есть». И редактировать ее можно прямо в процессе просмотра, визуально.

5. В редактируемой области не должно быть контента, который формируется или изменяется при помощи javascript перед редактированием.

Т.е. там может быть только «сырой» контент. Такой, который, возможно, в процессе работы МОЖЕТ быть подвергнут изменению средствами javascript в обычном режиме, но не в режиме редактирования. Это означает, что соответствующие скрипты НЕ ДОЛЖНЫ функционировать в процессе редактирования контента страницы.

Это же относится к скриптам со сторонних сайтов, типа Яндекс.Метрики, Google-analytics и т.п. Собственно, подобные скрипты существенно замедляют загрузку страниц сайта и при редактировании только мешаются, поэтому на это время их лучше отключить.

6. Редактирование производится только локально

А потом готовую страницу можно уже отправить на сервер. Это чисто для безопасности. Да и в любом случае, мне необходима копия сайта у себя на компьютере. А то мало ли.

Так что несколько вот таких условий.

Вообще, подобная функциональность присутствует в конструкторах сайтов

Которых ныне – очень-очень много. Причем, там можно редактировать не только основной контент, а и всю вебстраницу. Но, во-первых, любой конструктор подразумевает работу с тем или иным шаблоном страницы все равно. Некоторые конструкторы имеют множество разных шаблонов, некоторые – поменьше, но они таки применяются. Совсем без шаблона в конструкторе, как минимум, не получится делать адаптивные страницы.

Во-вторых, после конструкторов, вроде как, получается не очень чистый html-код. А сайты с грязным, неряшливым кодом, по идее, уже давно канули в лету. Сейчас считается, как минимум, признаком нехорошего тона, если на сайте грубый, «непричесанный» код. Впрочем, наверное, разные конструкторы есть, не знаю.

В-третьих, если потребуется именно конкретный шаблон страницы (например, такой, как у меня тут на сайте), то конструктор едва ли поможет. Впрочем, не удивлюсь, что есть ныне и такие конструкторы сайтов, которые позволяют встраивать в них какие-либо авторские шаблоны и их использовать для формирования вебстраниц.

В-четвертых, мало-мальски серьезный конструктор является платным. Бесплатные возможности – их, как правило, хватает лишь для новичков, на начальной стадии работы с сайтом.

В-пятых, конструктор, нередко, как бы привязывает к себе сайт. Т.е. если потом захочется перейти на другой конструктор (а то и вовсе продолжать существовать без него), то это будет крайне проблематичным.

В-шестых (это актуально для меня лично, по крайней мере) многие конструкторы уже, к сожалению, не поддерживают работу используемых мною браузеров (24-й, 36-й Firefox).

Как я это сделал

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

Ну, а вот что касается клиентской части (на JS) – там, конечно, пришлось «слегка» поработать. Ведь нужно что было сделать. Скажем, выделил я на странице слово (или предложение, или пару абзацев) и хочу к ним применить требуемый стиль (да, совсем в редакторе Word, скажем). Так это надо учитывать, где там начало контейнера, где конец; сохранять это в диапазон; сделать так, чтобы выделение сохранялось при кликах мыши по определенным местам на странице; ну, и т.д.

Свои проблемы создавали баги в функциях execCommand() (работающие тогда, когда у редактируемого блока установлен атрибут contenteditable=”true”). А также, устаревшая работа этих функций. Например, при выделении жирным шрифтом применение этой функции формирует теги <b>…</b>. А ведь уже лет 10 эти теги являются устаревшими (deprecated). Вместо них нужно <span style="font-weight: bold>.../span>.

Понятно, что такое преобразование пришлось производить вручную, уже после работы функции execCommand(). Да еще если выделенный диапазон включает в себя блочные теги, то пар тегов <b>…</b> образуется несколько. С одной стороны, это – удобно, но с другой – приходится вручную (уже циклом) заменять их на указанные <span style="font-weight: bold>.../span>.

Кстати, функции execCommand() ныне являются, вроде как, устаревшими. Пока они, конечно, работают и в новых браузерах тоже, но… в будущем могут перестать работать. Возможно, как раз по той причине, что они хотя и работают в целом приемлемо, но все же дают иногда досадные ошибки. Хотя, эти ошибки не критические и их вполне можно учитывать, делать для них, своего рода, патчи.

Любопытно, что в некоторых случаях НЕКОТОРЫЕ пары тегов <b>…</b> НЕ заменялись на … . Да, вот не заменялись, да и все, что тут скажешь. Пришлось делать повторную замену – для контроля…

То же касается, например, тегов <i>…</i> - выделение курсивом.

Если начинать выделение с НАЧАЛА абзаца – то именем контейнера (свойство commonAncestorContainer) является #text… а если НЕ с начала абзаца (например, со второго его символа) – то р, т.е. тег абзаца… Почему, я так и не понял, как ни пытался. Поэтому пришлось предусмотреть, своего рода, «костыль» для корректной обработки данной ситуации.

Ну, и т.д., и т.д. Просто масса всего такого, разных тонкостей.

Собственно, оно и неудивительно. Как только начинаешь что-то делать чуть больше, чем просто «типичная» функциональность – количество разных сложностей и тонкостей резко возрастает.

Попутно, добавил получение списка последних 10 измененных файлов (ибо, скорее всего, именно их может потребоваться редактировать). Ну, и связал с этим очистку html-кода после плагина docToHtml (это у меня уже и раньше было).

Вот примерно как происходит процесс работы

Если так, очень тезисно. Вот исходный вид страницы обслуживания:



Обновив карту сайта, выводится список последних 10 наиболее недавно измененных файлов. Кликнув по имени одного из них, получаем его html-код (только редактируемой области):


Код, по идее, был очищен ранее, так что более очистки не требуется.

Окраска кода – от слова не очень, т.к. я ее делал по-быстрому, сам, без использования библиотек.

Кликнув по кнопке «HTML», можно выделить его. Останется лишь скопировать его и вставить куда-то, при необходимости.

А если кликнуть по ссылке слева сверху – откроется эта страница в режиме редактирования (т.к. он – включен).


Пока, конечно, функциональность довольно скудная. Можно выделять текст жирным или курсивом; можно задавать ссылки. Для этого нужно дважды кликнуть по соответствующей фразе, ну, и задать основные параметры ссылки:


Также можно убрать уже имеющуюся ссылку.

Ну, и, наконец – собственно, работа с шаблонами. Кликая соответствующую кнопку, попадаем на страницу шаблонов, где можно выбрать необходимый. Пока у меня там всего два шаблона, остальные еще не добавил. Кликнув по понравившемуся шаблону, получаем примерно следующее:


В середине отображается шаблон с примером текста (окаймован синим фоном, для наглядности) точно так, как он будет выглядеть на вебстранице. Если нажать кнопку «Посмотреть теги», то серым цветом будут показаны ВСЕ теги, которые применены для создания этого шаблона (вместе со всеми атрибутами).

Справа приведена только разметка этого шаблона, без примера текста. Двойной клик по шаблону выделит ее. И после копирования она может быть вставлена в любое место html-кода в том или ином редакторе, например, в PHPStorm. Однако, чтобы вставить шаблон на редактируемую страницу в визуальном режиме, можно поступить двумя путями:

  1. Либо сделать ТРОЙНОЙ клик по шаблону и затем скопировать в буфер обмена. Далее можно закрыть панель с шаблонами и, перейдя к редактируемой области, сделать вставку из буфера (Ctrl + V). Шаблон вставится визуально (а не в виде html-кода, как при копировании после ДВОЙНОГО клика).
  2. Либо просто нажать кнопку «Вставить» (этот слева наверху, где изображен портфель с листом бумаги – типичный значок для операции вставки). При этом панель шаблонов закроется, а шаблон, по которому кликнули, автоматически вставится в то место редактируемой области, где стоит (стоял) курсор. Кстати, если курсор стоял посередине абзаца, этот абзац будет поделен на два абзаца и шаблон будет вставлен между ними. Это, конечно, стандартная функциональность функции execCommand().

Далее можно вводить в шаблон текст и т.д.

Ну, а продолжать редактирование, как обычно. После чего – нажать кнопку «Сохранить изменения». Если все нормально, ошибок не было, то содержимое редактируемой области будет записана в файл, содержащий html-код редактируемой вебстраницы.

Если будут ошибки – они появятся либо в стандартных сообщениях (alert() ), либо в панели редактирования слева.

Да, еще реализовал подсветку тегов (всех или при наведении мыши – выборочно). Если навести мышь на участок редактируемой области, затем кликнуть по появившемуся окну, то появятся теги соответствующего элемента:

Здесь можно подправить конкретный тег – например, убрать или добавить класс, стиль, другой атрибут. Это если неохота лишний раз переключаться в окно с редактором (типа PHPStorm) и искать там соответствующее место для исправления. Все-таки, непосредственно в браузере, когда все видишь, как оно должно выглядеть, делать это проще.

Правда, эта функциональность у меня пока еще не до конца доработана, да и ошибки встречаются.

Еще хочу добавить шаблоны для рисунков, видео. Может, что-то еще.

Примечание

Правда, уже при формировании этой статьи наткнулся на новые проблемы. Например, строчка
&lt;!-- &nbsp;__Begin_main_content__ --&gt;
Оказывается, в процессе редактирования страницы (причем, не в этом месте) вполне себе самостоятельно преобразуется именно в комментарий, т.е. в
<!--  __Begin_main_content__ -->

И еще кое-что. Надо будет исправлять.

С уважением, Салимоненко Д.А.