January 22nd, 2020

JS

Когда я в воскресенье вошёл "в личную зону" компьютера (сделал удобно за ним сидеть и сел так на час-полтора), я раскопал свои эксперименты по JS.

Что там - оконный интерфейс на JS и довольно удобный текстовый редактор в нём (картинка - отсюда). Основная идея интерфейса - пишется код, а не разметка (примерно как SWING на Java или там AWT), разметка спрятана глубоко и не факт, что она есть (почему бы просто не рисовать на Canvas с тем же интерфейсом или вообще на аппаратном экранчике). Основная идея редактора - редактируется структура текста, а не внешний вид, внешний вид делается стилями и часто вообще другим человеком. Средства работы со структурой и (готовыми) стилями прилагаются; также в комплекте удобные фишечки типа автозамены, автоформата и древовидной отмены (привет, nabbla1).

1. эта штука работает спустя почти 12 лет после написания, несмотря на местами нетривиальный код.
2. подобного мало, а в совокупности свойств - я не нашёл
3. чего-то подобного от интерфейса мне хочется (утилитарно) часто, в итоге я отказываюсь от того, чтоб выложить ну например мои эксперименты с картинками или другие штуки, требующие GUI.
4. внутри лютый говнокод (на 50% из-за IE, см. ниже, а другим 50 нет прощения), так что даже показывать "как есть" не хочется;

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

--
Про IE - когда-то давно у него, насколько помню, было два сборщика мусора - для кода JS и для DOMа. Пара ссылок туда-обратно (что более чем просто сделать) и память течёт. Популярность метода - самому создать элемент, самому назначить ему id и самому же по id обращаться, вместо того, чтобы сохранить ссылку и работать с ней - как мне кажется, из-за этого. У меня был другой подход - ссылки из DOM на js лежали в небольшом числе элементов в прогнозируемых местах и при удалении элемента очищались. Тем не менее, сделать объект, например, редактор, который сам знал, где у него что лежит, не получалось, в итоге объектов я не делал и там просто большая куча функций, которые сам знают, где что смотреть - вот это было зря. Правильнее было доступ к элементу обернуть, чтоб там внутри была шняга с getElementBySomeShit или поиск вот тех "прогнозируемых место" в контейнерах и использовать сомнительные прелести прототипного ООП, а теперь бы я исправил эту обёртку и всё.

(no subject)

Во славу Бахуса начинаю писать то, во что хочу превратить кучу функций редактора. Про UI - потом.

Здесь под документом понимается DOM-дерево, возможно как документ, открытый в iframe, а возможно - фрагмент документа.

  • DocumentCursor - указатель на конкретное место в документе.

  • DocumentRange - по факту два курсора - "от" и "до", задающие диапазон. Буду ли реализовывать как класс, включающий два курсора или как частный случай DocumentCursor - не думал пока.

  • DocumentCursorPickle - сохранённое состояние курсора, независимое от документа - документ сохранён, после загружен, а курсор на то же месте. Вот для этого и нужен DocumentCursorPickle. Может выродится в строку, кстати, но пока это массив.

  • DocumentManipulator - класс, меняющий документ; сам по себе никакого документа не содержит и может работать то с одним, то с другим документом - что на вход подали, то и обрабатывается. Подаётся как правило DocumentCursor.

  • DocumentEditor - редактор конкретного документа, сам по себе содержит документ и курсор(ы). Неинтерактивен, но пригоден для автоматизации вида найти/заменить.

  • DocumentManualEditor - то же, но изменение курсора и редактирование может происходить и "извне" кода, пользователем - путём нажатия кнопок, тыкания мышью/пальцем и т.д... Эти действия могут перехватываться и как-то дообрабатываться. Нажатия экранных кнопок, события от меню и прочие ненепосредственные действия - вызывают обычные методы DocumentEditor. В принципе можно явно затребовать все действия выполнимыми неинтерактивно - легче будет обрабатывать историю - и так их сначала перехватывать и блокировать, а потом вызывать, но это не обязательно.

Про DocumentEditor и зачем он нужен - использовать execCommand не хочется совершенно, а часто ещё и не можется - видите в списке по ссылке formatInline? Вот и я не вижу. И визуальные тэги превалируют над структурными. И по-разному работает в разных браузерах и их версиях. А если сначала вызывать, а потом поправлять, то ломается история отмены и курсор ведёт себя... странно. Не надо так делать, а то до shadow DOM дойдёте :-) Ну и вообще никто не сказал, что всё это счастье видно пользователю - загрузить документ, найти/заменить в нём что-то и сохранить - довольно типовая автоматика.

Интересно, что немалая часть реализована давным-давно и работает начиная с 6-го IE (гыыы!)

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