Николай Ланец
9 сент. 2019 г., 23:31

ContentEditor

Всем привет!

Давно я не описывал описывал базовые компоненты фронт-редактора, но сегодня появился отличный экземпляр, про который можно было бы написать несколько отдельных статей, но постараюсь все основные моменты описать в одной статье. Как наверняка понятно из заголовка, я его назвал ContentEditor, хотя на самом деле это чуть более расширенный базовый компонент HTML Tag, о котором я писал еще в первой заметке про цикл статей по @prisma-cms/front-editor.

Процитирую здесь часть той заметки
Итак, начинаем мы сегодня с компонента HTML Tag. На мой взгляд это самый интересный компонент, потому как ближе всех остальных к нативному HTML. Я не знаю насколько мой подход костыльный, но я попытался сделать так, чтобы обычный HTML конвертировался в JSON, а JSON конвертировался в HTML. При редактировании текста используется браузерное свойство тега contenteditable. (c) я
Меня постоянно обвиняют в том, что у меня нет дизайнерского вкуса и все мои работы выглядят слишком программерскими (то есть с оформлением полная беда), но вот этак цитата по оформлению вроде ничего так выглядит, да? :) Это все потому что я ее честно стырил)) вот отсюда. Сам бы я конечно не придумал бы такое оформление. Ну а вообще, мог взять любую из вот этих: https://uicookies.com/css-blockquotes/ (да и много откуда в принципе). И все это благодаря новому компоненту ContentEditor.

Повторю цитату из той статьи: "Я не знаю насколько мой подход костыльный, но я попытался сделать так, чтобы обычный HTML конвертировался в JSON, а JSON конвертировался в HTML.". По моим ощущениям, это все еще имеет явные признаки костыльности, но все-таки выбранный подход себя оправдал и начинает раскрывать свой потенциал, пир чем гораздо больше, чем даже я сам ожидал. Фишка нового редактора в том, что редактировать содержимое можно как средствами самого редактора, так и любыми другими доступными средствами, хоть даже в браузерном devTools. Вот гляньте небольшое видео.


Это дает очень большие возможности в оформлении в тех случаях, когда не хватает элементов управления в самом редакторе, или редактор где-то не ту разметку генерирует.

Кстати, TinyMCE и CKEditor тоже так умеют. Если вы используете эти редакторы, попробуйте сами поэкспериментировать. Но все же итоговый результат у меня и этих редакторов разные. Эти редакторы в итоге отдают конечный HTML (что вполне логично). У меня же HTML конвертируется в JSON-описание и непосредственно рендеринг проходит через реакт-компоненты, а не просто выводится полученный HTML. Это дает возможность на уровне отрисовки каждого элемента, к примеру, фильтровать их и модифицировать, а так же позволяет в такой разметке редактировать и выводить и другие, более сложные react-компоненты. И хотя последняя функция не до конца еще реализована, все-таки принципиальная возможность такая есть.

Немного технических деталей.

Как я и писал в вышеупомянутой статье, редактирование обеспечивается за счет html-атрибута contenteditable. Если какому-либо элементу на странице задать этот атрибут, его содержимое будет доступно для редактирования пользователем прям в браузере (кроме вложенных элементов, для которых задан атрибут contenteditable="false"). При этом изменения содержимого можно отслеживать событием oninput. Именно oninput был использован в первоначальной версии HTML Tag, но в новой версии оно было заменено на DOMSubtreeModified, а спустя буквально пару часов на Web API MutationObserver. С чем это связано и что дало? Проблема была в том, что ни oninput, ни DOMSubtreeModified не реагировали на изменения атрибутов элементов, например, при изменении стилей в devTools. А вот MutationObserver позволил это сделать. При чем, как оказалось, MutationObserver - очень мощная и удобная штука! При его инициализации можно перечислить какие именно изменения отслеживать (полный список здесь), то есть можно отслеживать изменения текста, прямых потомков, полностью дочернее дерево или атрибуты текущей ноды. А главное, в колбэке мы получаем сразу массив ивентов, то есть если за раз прилетели новые элементы и атрибуты, то мы получим в массиве каждое такое изменение в отдельности. А можно еще отслеживать предыдущие состояния. В общем, очень крутая штука!

На том закончу. Напоследок тем, кого интересуют WYSIWYG-редакторы, советую к прочтению очень подробную и полезную статью: https://habr.com/ru/company/oleg-bunin/blog/350252/

Николай, привет!

Интересный подход к редактированию через devTools: для меня открытие, хотя и можно было самому догадаться))))

А по отслеживанию изменений: то есть можно вообще все изменения страницы забить в БД: кто изменил, чего и когда?
Дима, привет!

<< А по отслеживанию изменений: то есть можно вообще все изменения страницы забить в БД: кто изменил, чего и когда?

Если заморочиться, то можно вообще каждое изменение журналировать (в том числе изменение текста). Но скорее всего это будет избыточно. А вот просто сохранять старую страницу в базу, при сохранении новой версии - это вполне можно. Но надо учитывать, что у объекта страницы могут быть связанные данные (например, файлы фотогалереи), это уже придется дополнительно заморачиваться.
Да, каждое изменение пожалуй избыточно будет:) Да и смысла особого нет.
А вот журнал изменений в виде таблицы дата, кто менял, json страницы уже представляется полезным на той же пивкарте.


Это не сложно сделать.

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