
Много лет меня преследовал этот зуд — попытки найти «идеальный» текстовый редактор для совместной работы. Но не просто любой текстовый редактор, который поддерживает совместную работу, о нет, моя задача — найти (ну, по крайней мере, искать) открытые текстовые редакторы с групповой работой в режиме реального времени (т. е. не только обычный текст, но и структурированный контент). Таким образом, основное внимание в этой статье уделяется довольно нишевой категории инструментов с открытым исходным кодом и технологиям, на которых они работают. Если ваши интересы шире, можете обратиться к этому постоянно обновляемому списку редакторов.
Итак. Я много раз прыгал с обрыва и нырял в практически бесконечное море программ для совместной работы в реальном времени. Полёт вниз, этот бодрящий нырок на дно бассейна, мне уже хорошо знаком. Обычно он начинается с некоторого первоначального волнения и удивления (скачок) новых низкоуровневых технологий и исследовательских работ, затем следует чувство перегруженности и желания всплыть (эй, тут довольно глубоко) и исследовать прикладную часть, а затем период, когда мои мысли лучше всего описать фразой: «Я действительно настолько глуп для этого?» (вполне вероятно), потому что обычно документация, демо и код не совсем совпадают или имеют смысл, компонент совместной работы на сервере не запускается и встречаются пограничные ситуации, когда более двух пользователей вводят одно и то же слово, и… на этом всё заканчивается (всплыл, хватая ртом воздух).
После этого трудно снова поднять тему, следующий этап — это своего рода зима размышлений, в дрёме, пережидая суровую погоду, когда я обычно позволяю полуготовому коду работать месяцами… или годами. Пока мы не встретимся снова, бесконфликтный реплицированный тип данных!

Рис. 1. Прыжок
Дело в том, что в 2017 году я был так взволнован перспективами одного алгоритма (разновидность CRDT), описанного в исследовательской статье, что потратил несколько дней и реализовал его на JavaScript, только чтобы узнать, что в самой научной статье есть пограничная ситуация, для которой не приведено решения (хорошо… но может всё-таки?). Я в то время обратился к автору, но не получил ответа, и обнаружил, что эта конкретная пограничная ситуация рассмотрена в аналогичном алгоритме другой командой, но чёрт, из-за этих тонкостей в реализации, возможно, я мог бы перенести его на Lisp… ТАК, СТОП! Что здесь происходит? Я, конечно, не хочу внедрять новый алгоритм из исследовательской работы и исправлять его проблемы! Что я делаю, как я сюда попал? Давайте перемотаем обратно!
То, что мне (и, вероятно, вам тоже, дорогой читатель) действительно нужно — это редактор plug-and-play, готовый продукт. Который решает проблему совместной работы в реальном времени. Который позволяет нескольким подключённым пользователям за тысячи миль друг от друга редактировать структурированный документ, нажимая клавиши на клавиатурах, и видеть изменения друг друга на своих экранах. Вот и всё. Однако редакторы — это сложно... и я никак не мог найти такого инструмента.
До сих пор.
Наступил 2019 год (зуд вернулся с силой), и на этот раз не только появился волшебный редактор, но на самом деле даже два претендента на выполнение долгожданной спецификации. Первоначально я хотел полетать с вами над полем и перечислить почти все текстовые редакторы для совместной работы, но, похоже, это не добавит большой ценности. Вместо этого давайте сосредоточимся на двух редакторах, которые могут стать «тем самым».
Но редакторов два, и нужно сделать выбор — было бы неплохо объективно рассмотреть, какой из них действительно лучше подходит. Предлагаю глубоко научную систему классификации со следующими категориями (используя киви в качестве стандартной единицы добра):
- Открытая лицензия: добавляет 1 киви
(это также критерий исключения)
- Поддержка изображений: добавляет 1 киви
- Поддержка таблиц: добавляет 1 киви
- Поддержка списков: добавляет 1 киви
- Поддержка математики: добавляет 1 киви
- Поддержка сотрудничества в реальном времени: добавляет 1 киви
- Доступные серверные компоненты: 1 киви
- Поддержка удалённого курсора и выделения: 1 киви
(то есть вы можете видеть курсоры других пользователей)
- Работа в офлайне: 1 киви
(это довольно сложно определить)
- Опыт работы в продакшне: 1 киви
- Поддержка мобильных устройств: 1 киви
С такой системой подсчёта очков редактор может получить максимум 11 киви-единиц добра. Давайте приступим!
CKEditor 5

Рисунок 2. Интерфейс CKEditor 5 (один из возможных вариантов), источник
Начнём с CKEditor 5, последней версии из большой линейки качественных редакторов. Он прекрасен. Я знаю, знаю, что это не критерий, и он в реальности не имеет значения (и мы можем даже не согласиться), но я просто должен был сказать о его красоте. Итак, этот редактор берёт много киви: он лицензирован под GPL (некоторое обсуждение ограничений здесь), (+1), поддерживает изображения, таблицы, списки (+3), математика поддерживается плагином (+1) и он также поддерживает совместную работу в реальном времени с удалённым курсором и выделениями (+2). Создатели CKEditor написали удивительный подробный пост в блоге о том, как они его разработали с помощью операционных преобразований.
Тем не менее, я не смог найти необходимую реализацию сервера для совместной работы в реальном времени, а вся документация указывает на обязательную необходимость их облачного сервиса и (платного) компонента даже в проектах, совместимых с GPL.
Уровень офлайновой поддержки трудно определить, но похоже, что она не совсем полная (например, редактор выдерживает ненадолго прерванное подключение, но не несколько дней работы в автономном режиме). Наверное, половина киви? То же самое касается мобильной поддержки, там также ведётся работа по полной поддержке (+0,5). И последний момент, CKEditor, безусловно, используется в продакшне, но я не смог найти список продуктов на его основе (+0,5).
Хороший редактор, но отсутствие доступного сервера совместной работы с открытым исходным кодом действительно удручает.
Полная оценка: 8,5/11









Atlaskit Editor

Рис. 3. Atlaskit Editor от Atlassian
Около года назад Atlassian запустила систему Atlaskit Design с открытым исходным кодом, и с ней пришло много вкусностей, в том числе полноценный готовый к использованию редактор на основе ProseMirror. Я уже чувствую, что это может быть тот редактор, который мы искали! Он выпущен под лицензией Apache 2.0, по мнению многих, очень разрешительной лицензией open source (+1 киви). Он не только поддерживает изображения, таблицы и списки, но поддерживает их исключительно хорошо (+3 киви)! Реализация таблиц, чего очень не хватает большинству редакторов, тут выполнена прекрасно:

Рис. 4. Управление таблицами в Atlaskit Editor
К сожалению, математика не поддерживается, но сам редактор основан на ProseMirror, так что не должно стать проблемой добавить к нему существующее решение (+0,5). Он определённо поддерживает совместную работу в реальном времени с удалёнными курсорами и выделениями (+2), это из лучших примеров UI такой поддержки, какие я когда-либо видел (например, удалённые курсоры затемняются, если перекрываются с вашими собственными, и другие прекрасные детали реализации). Кроме того, из моего тестирования поддержка работы в офлайне кажется очень прочной (+1) — вероятно, это связано с подходом «центральной компетенции», который использует для совместной работы ProseMirror. Ничего себе, мы уже добрались до 7,5 киви, а ещё много пунктов! Вперёд!
К сожалению, именно здесь мы немного сталкиваемся с суровой реальностью. Как и в CKEditor, здесь нет доступной серверной реализации для совместной работы в реальном времени. Лентяи. Крупный облом. Интересно, можно ли это исправить?..
Во всяком случае, если продолжать спускаться по критериям, то всё остальное достойно киви: он абсолютно точно используется в продакшне (миллионы пользователей), и у него есть мобильная поддержка (+2). Как раз когда я собирался объявить победителя (в общей сложности 9,5 киви) и опубликовать этот пост, появилось что-то ещё. Оказывается, логотипы и значки, используемые в редакторе, и многие другие компоненты Atlaskit лицензированы под очень ограничительной лицензией ADG, в которой говорится, что вы не можете использовать их за пределами вселенной Atlassian. Однако те же иконки широко используются и плотно интегрированы в редактор. Крупный облом номер два, и я забираю у них киви. Мы вернулись к 8,5, и если вы ведёте подсчёт, то видите, что результат теперь одинаковый. И он окончательный.
Вот если бы что-то сделать с этими иконками...
Я подумал, что после всех последних достижений в области онлайновых текстовых редакторов будет очень печально остаться с двумя великолепными редакторами с удивительными функциями, которые всё равно нельзя использовать в проектах с открытым исходным кодом — либо из-за проблем лицензирования, отсутствия доступных строительных блоков, либо и то, и другое.
Поэтому сначала я разработал серверную часть (на основе PostgreSQL, фреймворке PubSweet и смеси REST/WebSockets), код доступен здесь. Он довольно простой, но выполняет свою работу и обеспечивает сохраняемость документов и канал связи в реальном времени. Удивительно, но благодаря огромному сообществу ProseMirror я смог выяснить, как всё должно работать, не имея точной спецификации интерфейса (+1 киви).
А затем я заменил иконки, используемые редактором, значками из набора Feather. В частности, пришлось заменить три пакета. Поскольку лицензия ADG, среди прочего, запрещает любые производные работы, то эти пакеты нужно было переделывать с нуля. Вероятно, из-за этого потерялись некоторые функции, в основном, с точки зрения доступности для людей с ограниченными возможностями, но зато создана хорошая открытая база для дальнейшего развития. Например, в некоторых случаях для значков отсутствуют лучшие альтернативы, так что если вы хотите внести свой вклад в этот проект, вот вам первая проблема (+1 киви)!
Всё это означает, что теперь мы всего в половине киви от идеального результата (но мы, вероятно, сможем справиться с математикой). Свершилось то, во что я не верил, когда начинал это путешествие. Это также означает, что у нас есть явный победитель в этой битве, и в конечном итоге Atlaskit Editor победил благодаря разнообразному, открытому и полезному сообществу ProseMirror. Ознакомьтесь с документацией проекта для получения инструкций, с чего начинать. Я считаю, что если вы начинаете новый проект и рассматриваете возможность сотрудничества в реальном времени, это отличное место для начала, даже со всеми оговорками.
Рис. 5. Демонстрация возможностей редактирования в режиме реального времени в Atlaskit Editor
Итоговый (исправленный) результат: 10,5/11











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

Рис. 6. Редактор Wax (текстовый процессор на основе ProseMirror)
Первый — это Wax (назван в честь древних восковых табличек) от Coko Foundation. Этот текстовый процессор сначала сделали на библиотеке Substance (репозиторий), а теперь перестроили под ProseMirror (репозиторий). Он исключительно упакован функциональностью. Это не совсем те функции, ��а которые мы даём киви, но тем не менее это отличные функции. Wax изначально построен для вёрстки книг, он поддерживает заметки (нумерованные аннотации, распространённые в книгах), историю изменений, поиск и замену, орнаменты и другие. Может, за это давать апельсины









Texture

Рис. 7. Texture, редактор на основе Substance
Наконец, у нас есть Texture, очень специфический, профессиональный (но с открытым исходным кодом) редактор для создания научного контента в формате JATS (стандарт XML для журнальных статей). Если тут поупражняться в подсчёте фруктов, у нас почти наверняка закончатся пальцы: открытая лицензия, таблицы, изображения, глубокая поддержка математики, ссылки и перекрёстные ссылки, списки, поддержка метаданных, список продолжается!



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