Атомное текстовое пятно в перо

Скажем, я хочу иметь AtomicText блот, который похож на блот по умолчанию Link, но является неизменяемым и может быть удален только целиком. Более конкретно:

  • Курсор может находиться между символами AtomicText.
  • Можно выбрать части AtomicText.
  • Удаление хотя бы одного символа AtomicText приводит к удалению всего AtomicText.
  • После создания AtomicText невозможно добавить символы. Ни через события клавиатуры, ни через копирование и вставку.

Моя идея заключалась в том, чтобы сделать AtomicText продолжением Embed пятна. В этом случае весь блок AtomicText удаляется, когда курсор находится справа от последнего символа и нажата клавиша возврата. Но другие операции не работают должным образом. Я предполагаю, что мне нужно переопределить некоторые Blot методы, чтобы добиться правильного поведения, но здесь я немного растерялся.

Другая идея - прослушивать text-change события, определять, находится ли курсор внутри AtomicText пятна, и действовать соответствующим образом. Например, при нажатии клавиши Backspace найдите начальную и конечную позицию текущего AtomicText блота и удалите все символы между этими индексами. Это кажется хрупким подходом.

Любые указатели будут оценены.

Подобные вопросы / пожелания следующие:


person Eugen    schedule 28.11.2016    source источник
comment
Какие еще операции не работают должным образом?   -  person jhchen    schedule 29.11.2016
comment
Например, я все еще могу добавлять символы в пятно AtomicText. Я поэкспериментировал и попытался установить contentEditable = false для узла в определении блота. Это не сработало, но создание искусственного дочернего узла с contentEditable = false приблизилось, но все еще недостаточно. Кажется, что даже если вы наследуете от Embed, но у вашего узла есть текст, этот текст обрабатывается как обычный текстовый блот, поэтому вы все равно можете добавлять к нему символы.   -  person Eugen    schedule 29.11.2016
comment
Вот аналогичный запрос для ProseMirror («Заблокированные узлы»): обсудить.prosemirror.net / t / locked-nodes / 448/1   -  person Eugen    schedule 09.12.2016
comment
Если вы хотите предотвратить ввод, вам нужно, чтобы он был contenteditable = false   -  person jhchen    schedule 10.12.2016
comment
Я помню, как пытался (см. Мой второй комментарий выше). Но это привело к кажущемуся нарушению взаимодействия с позицией курсора и попыткам удалить пятно. Например, я мог бы поместить курсор в середину блота и, нажав клавишу Backspace, просто поместил бы курсор в начало блота. Вот почему я предположил, что мне нужно переопределить другие методы Blot с настраиваемым поведением, но не понимал, как это сделать правильно.   -  person Eugen    schedule 10.12.2016


Ответы (2)


По моему опыту, установка contenteditable false проблематична. Если вы разместите AtomicText пятно в конце документа, вы не сможете добавить к нему. Кроме того, наведение курсора на AtomicText в конце приведет к размытию редактора.

У меня возникла аналогичная проблема с пятном для сноски. Это тег sup, содержащий [\d+], и мы не хотим, чтобы редакторы изменяли сноску, но мы хотим, чтобы они могли плавно перемещать курсор по ним.

Я экспериментировал с двумя другими вариантами в дополнение к слушателю text-change, упомянутому OP. Первый вариант - попытаться расположить курсор (через setSelection) спереди или сзади, используя selection-change прослушиватели событий. Я обнаружил, что это проблематично, потому что можно прокрасться до того, как сработает событие изменения выбора. Я также не сторонник этого подхода, потому что он заставляет курсор перемещаться по сноске. YMMV

Другой вариант - перехватить ввод с клавиатуры. Вы можете добавить слушателя клавиатуры (я использовал KeyboardJS) в модуль, который инициализируется с помощью quill. Если текущий выбор находится «внутри» вашего атомарного текста, вы можете остановить ввод от перехода к quill, используя e.preventDefault(). При таком подходе вам также нужно будет предоставить пользовательские обработчики клавиатуры в вашей конфигурации перьевого ввода для переопределения вкладки, ввода и, возможно, удаления. Вкладки представляют собой большую проблему, потому что есть обработчик вкладок по умолчанию, предоставляемый quill, который имеет приоритет, если вы его не переопределите. В пользовательском обработчике вам нужно будет определить, находится ли context в вашем AtomicText. Объект context будет содержать format карту, содержащую atomictext (ваше имя блота), если он находится в контексте AtomicText.

Обратите внимание, что если пользователь помещает курсор рядом с вашим AtomicText, то с точки зрения перо, которая находится в контексте AtomicText. Наше решение этой проблемы для ввода - вставить неразрывный пробел нулевой ширины, а затем продолжить ввод с клавиатуры. Это «вырывает» курсор из AtomicText блота, позволяя продолжить вставку, как ожидалось. Затем мы удаляем эти символы из полученного HTML перед сохранением текста.

Надеюсь это поможет.

person Damon Snyder    schedule 18.05.2018

В функции создания блота (значение) добавьте следующее:

node.setAttribute('contenteditable', false);
person Andy    schedule 07.02.2017