Как разработать текстовый редактор для Интернета
Опубликовано: 2022-03-10Я работаю в компании Readymag, которая создает браузерный инструмент для дизайна, который помогает людям создавать веб-сайты, портфолио и всевозможные онлайн-публикации без программирования. В нашем инструменте доступно множество виджетов, и текстовый виджет является одним из наиболее широко используемых.
Текстовый виджет — это поле ввода текста, в котором пользователь может стилизовать текст, используя ряд элементов управления в редакторе. Каждый элемент управления применяет свойство CSS к тексту. Со стороны пользователя оно выглядит как обычное поле для ввода текста, но за его кажущейся простотой скрывается огромное количество сложных процессов.
В этой статье я объясню проблемы, с которыми столкнулась моя компания, и решения, которые мы использовали для создания текстового виджета в нашем приложении. Я также расскажу о том, как мы это реализовали и чему научились в ходе работы, а также о том, как в целом работает набор текста в Интернете.
Редактирование текста в Интернете
В Интернете существует несколько способов реализации полей ввода текста. Мы могли бы использовать простое текстовое поле, или многострочный элемент textarea
, или атрибут contenteditable
, чтобы сделать ввод доступным для редактирования, или document.designMode = on
. Насколько они разные?
Элементы input
и textarea
идеально подходят для добавления текста на страницу, но они не обеспечивают широкие возможности форматирования текста. Для этого мы можем использовать атрибут contenteditable
, чтобы сделать практически любой элемент редактируемым и включить использование стилей текста.
Если вам нужно отредактировать всю страницу сразу, вы можете использовать document.designMode
. Этот режим позволяет редактировать любой элемент в данном документе, даже iframe
.
Мы выбрали атрибут contenteditable
, который включает в себя все необходимые возможности редактирования текста. С этим атрибутом любой текст на странице становится редактируемым, что очень важно, если мы хотим, чтобы люди могли стилизовать текст с помощью CSS . Например, пользователи могут затем напрямую стилизовать выбранные разделы или весь текст.
Стили текста и свойства шрифта
Мы позволяем пользователям стилизовать текст так, как они хотят, предоставляя доступ ко всем параметрам, которые CSS предоставляет из коробки. Помимо общеизвестных свойств, таких как шрифт, стиль, цвет и оформление, мы даем пользователям возможность использовать особенности шрифта OpenType, такие как лигатуры, стилистические наборы, дроби и так далее. Эти функции работают через свойство CSS font-feature-settings
, которое позволяет пользователям настраивать стили текста.
Примечание . Я настоятельно рекомендую прочитать прекрасную статью Sparanoid, демонстрирующую все возможности OpenType.
Современная типографика сделала большой шаг вперед, позволив использовать вариативные шрифты в Интернете через свойство font-variation-settings
.
Каждый вариативный шрифт имеет переменные свойства, значения которых вы можете изменить. Например, в стандартном шрифте вы можете изменить толщину шрифта, используя строго заданные значения ( 400
, 500
, 600
и т. д.), тогда как в вариативном шрифте вы можете использовать любое значение из доступного диапазона, предоставляя более широкие возможности. для оформления текста.
.style-1 { font-weight: 600; } .style-2 { font-variation-settings: "wght" 777; }
Ниже вы можете увидеть пример того, как выглядит работа с вариативным шрифтом в текстовом виджете.
В дополнение к зарегистрированным значениям ( wght
, wdth
, slnt
и т. д.) производители шрифтов также могут создавать свои собственные уникальные функции шрифта (как в примере выше). Чтобы дать нашим пользователям возможность использовать все возможные функции шрифта, нам нужна эта информация в первую очередь.
Все функции, которые вы хотите использовать, должны быть определены в файле шрифта. Посмотрим на его характеристики. Каждый шрифт может быть представлен в виде таблиц, предоставляющих всю различную информацию, используемую при отображении его символов.
Мы используем две таблицы для сбора этой информации о шрифтах:
- Таблица замены глифов
Таблица замены глифов (GSUB) содержит список данных рендеринга глифов. ОбъектGSUB.featureList
представляет собой перечисление функций шрифта и их свойств. Вы можете просмотреть пример данных в таблице на GitHub. В этой таблице наиболее интересно полеtag
. Это имя функции шрифта, и оно указывает, что эта функция доступна с этим шрифтом. Мы можем безопасно использоватьtag
в свойствеfont-feature-settings
. - Таблица вариантов шрифтов
Таблица вариаций шрифтов (fvar) представляет собой представление переменных свойств, связанных со шрифтом. Пример таблицы также доступен на GitHub. Каждый объект — это свойство шрифта с описанием возможных значений (min
,max
, default) и локализованным именем (если есть). Мы используем эти значения со свойствомfont-variation-settings
.
С помощью этих двух таблиц мы можем покрыть все наши требования: использование переменных свойств шрифта и различных функций шрифта. Полученные данные отображаются в элементах управления текстовыми виджетами в редакторе, где пользователи могут стилизовать текст без использования кода.
Использование клавиатуры
Ввод текста — один из наиболее важных аспектов взаимодействия с пользователем текстового виджета. Помимо включения ярлыков для работы с текстом, нам пришлось столкнуться с некоторыми необычными проблемами. Навигация по тексту с помощью клавиш со стрелками определенно была одной из них.
Пока пользователь редактирует, текстовый виджет также показывает скрытые символы, такие как неразрывные пробелы и разрывы строк. Они реализованы в виде значков SVG, вставленных в текст, что создает проблему: если мы используем contenteditable
, то эти значки не позволяют пользователям перемещать курсор с помощью клавиш со стрелками.
Решение достаточно простое: используйте span
и псевдоэлемент :before
. Таким образом, браузер воспринимает значок как текст, а клавиши со стрелками отлично работают.
span:before { content: ""; height: 1em; position: relative; background-repeat: no-repeat; background-image: url("data:image/svg+xml,..."); background-position: center bottom; background-size: 1em; }
Ярлыки
Есть два сочетания клавиш для вставки текста в текстовый виджет.
Cmd / Ctrl + V вставляет текст из буфера обмена и сохраняет все стили, которые были в исходном документе. Если текст был скопирован из таких приложений, как Pages, Notes, Word или Google Docs, то ваш буфер обмена будет содержать информацию HTML, а не только обычный текст. Этот HTML-код можно разобрать и вставить, сохраняя исходные стили.
Вы можете получить данные HTML следующим образом:
// https://www.w3.org/TR/clipboard-apis/#reading-from-clipboard document.addEventListener('paste', (e) => { const text = e.clipboardData.getData('text/plain'); const html = e.clipboardData.getData('text/html'); handlePaste(); });
Кроме того, у нас есть сочетание клавиш Cmd + Shift + V. Когда вы вставляете текст с помощью этой комбинации клавиш, браузер оставит простые данные в полезной нагрузке, поэтому стиль определяется местом назначения вставки. Эти ярлыки существуют в браузере по умолчанию, но вам нужно не забыть реализовать их в своем проекте.
Выбор текста и фокус
Выбор текста помогает пользователям увидеть, какой фрагмент текста редактируется в данный момент. Давайте рассмотрим простой пример: поле ввода с кнопкой для управления жирностью текста.
В этом примере мы можем выделить фрагмент текста и нажать кнопку Bold
, после чего выделение в тексте останется. Но что, если наш пример сложнее? Скажем, мы добавляем поле ввода в селектор размера текста. В этом случае фокус сместится на новый ввод.
Есть два варианта решения этой проблемы :
- После каждого события ввода мы заставляем фокус возвращаться к текстовому блоку. В этом случае выделение начнет мигать после определенного количества входных событий — мы этого не хотим.
- Мы можем добавить текстовый блок в
iframe
. Как вы, наверное, знаете,iframe
имеет свой собственный глобальный объектwindow
. Таким образом, пока выделение находится внутриiframe
, оно будет сохраняться, даже если фокус будет перемещен снаружи.
В итоге мы получили текстовый виджет, обернутый в iframe
. Таким образом, пока выделение находится внутри iframe
, оно будет сохраняться, даже если фокус будет перемещен снаружи. Взгляните на скриншот ниже. У нас есть два выделения на странице: выделенный фрагмент в текстовом виджете и выбранное значение размера текста в контроле.
Производительность во время ввода текста
Скорость отклика вашего интерфейса редактирования текста важна. Внимательно следите за значением частоты кадров в секунду (FPS), особенно когда речь идет о таких задачах, как редактирование текста на высокой скорости или изменение размера шрифта.
Readymag имеет два окна просмотра: настольное и мобильное . Стили текста могут отображаться по-разному в каждом из них. Пока текст вводится, редактор будет выполнять различные вычисления для синхронизации данных между окнами просмотра. Высокая отзывчивость достигается за счет использования браузерного API: requestAnimationFrame
и requestIdleCallback
:
-
requestAnimationFrame
вызывается каждый раз при обновлении экрана; -
requestIdleCallback
вызывается только тогда, когда браузер бездействует.
Это отличный способ выполнять утомительные операции, не блокируя основной поток.
Доступность
Включение доступности — одна из самых важных практик в веб-разработке сегодня. Если ваш веб-сайт разработан с учетом доступности, он предоставит большему количеству людей доступ к вашему продукту . Это означает размещение не только людей с ограниченными возможностями, но и пользователей на разных платформах: настольных и сенсорных устройствах, программах чтения с экрана, слуховых аппаратах и так далее. Чтобы понять, насколько важным может быть обеспечение доступности проектов, я рекомендую ознакомиться с последней статистикой доступности.
Чтобы начать внедрять методы обеспечения доступности веб-ресурсов, сначала ознакомьтесь с Руководством по обеспечению доступности веб-контента (WCAG), наиболее полным ресурсом по этой теме. И поскольку Readymag является инструментом для публикации, в дополнение к WCAG нам также необходимо следовать Руководству по доступности средств разработки (ATAG).
В настоящее время наша команда находится на этапе интеграции специальных возможностей в редактор. В следующих статьях мы расскажем больше о нашем пути к полной интеграции специальных возможностей в Readymag. Вы также можете проверить любую работу, выполненную с помощью Readymag, используя наш контрольный список специальных возможностей.
Лучшие практики
Наконец, вот несколько советов, которые помогут вам разработать текстовый редактор для Интернета:
- Тщательно продумайте планировку.
Заранее определите, какие возможности вам нужны и как вы будете работать с элементами в текстовом редакторе. - Настройте визуальное тестирование.
При работе с текстом нельзя полностью полагаться на результат теста моментального снимка. Вы можете получить правильный результат в тесте, ожидая заданный CSS для блока, но иногда результат может быть не таким, как вы ожидали. - Проверьте свою работу в разных браузерах.
Хотя большинство браузеров достаточно хорошо поддерживают новые онлайн-функции, часто возникают проблемы с отображением одних и тех же стилей в разных браузерах. - Используйте флаги функций для более безопасной разработки новых функций.
- Измеряйте FPS в браузере при вводе текста.
Не выполняйте ресурсоемкие задачи в одном потоке. - Не бойтесь экспериментировать .
- И последнее, но не менее важное: попробуйте Text Widget в Readymag.
Некоторые полезные ссылки
- «Полная демонстрация CSS для функций OpenType», Sparanoid
- «Введение в вариативные шрифты в Интернете», web.dev
- «Потрясающая типографика», Джоэл Галеран
- «Переменные шрифты», Ник Шерман
- Набор шрифтов
- OpenType.js