Как вставить изображение с подписью в пользовательский элемент в CKEditor 5? - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь вставить элемент изображения внутри пользовательского тега. Но изображение настроено неправильно. Я настроил плагин загрузки изображений ckeditor.

Исходный плагин загрузки имел следующие строки:

const imageElement = writer.createElement('image', { uploadId: loader.id });
const insertAtSelection = findOptimalInsertionPosition(doc.selection);
editor.model.insertContent(imageElement, insertAtSelection);

Это добавленное изображение в дереве dom, как это:

<h2>TITLE</h2>
<figure class="image ck-widget ck-widget_selected" contenteditable="false">
    <img src="EXAMPLE/URL" title="" style="">
    <figcaption class="ck-editor__editable ck-editor__nested-editable ck-placeholder" contenteditable="true" data-placeholder=""><br data-cke-filler="true"></figcaption>
</figure>

Я изменил плагин. Когда я загружаю изображение, эти строки кода работают:

const imageElement = writer.createElement('image', { uploadId: loader.id });
writer.appendElement('content', { 'guid': guid }, parent);
content = parent.getChild(parent.childCount - 1);
writer.append(imageElement, content);
writer.setSelection(content.getChild(content.childCount - 1), 0);

Мой код вставляет изображение в дерево следующим образом:

<h2>TITLE</h2>
<content>
    <figure class="image ck-widget" contenteditable="false">
        <img>
    </figure>
</content>

Как установить атрибуты изображения и подпись? Я подозревал, что insertContent. Я пытался запустить insertContent, но я не мог знать, что следует отправить на insertContent в качестве параметра позиции. Если я использую findOptimalInsertionPosition(doc.selection), изображение добавляется за пределы <content>.

1 Ответ

0 голосов
/ 13 ноября 2018

Определение схемы

Прежде всего, вам нужно убедиться, что <image> разрешено в элементе вашей пользовательской модели. Если вы зарегистрировали это так:

editor.model.schema.register( 'custom', {
    allowContentOf: '$root',
    allowWhere: '$block'
} );

Тогда ты в порядке. Поскольку <$root> позволяет <image> внутри, ваш <custom> позволит <image>.

Подробнее о написании правил схемы можно прочитать в руководстве Глубокое погружение схемы .

Структура модели

Теперь вы спросили, как установить заголовок изображения. Чтобы понять это, вам нужно спросить, какова структура изображений в модели. Ответ будет - он сильно отличается от того, что вы имеете в виду:

<image src="...">
    <caption>Caption text</caption>
</image>

Это структура, которую вы хотите создать, чтобы вставить изображение с подписью.

Вставка изображения в заданном месте

Лучший способ вставить произвольный контент - это editor.model.insertContent(), потому что он заботится о двух вещах:

  • установка выбора документа в желаемое (по крайней мере, из случаев, подобных вставке) место после вставки,
  • убедившись, что содержимое, которое он вставляет, вставлено в место, разрешенное схемой (поэтому нам нужно сначала настроить схему).

Методы записи модели не делают ничего из этого, поэтому, если вы точно не знаете, куда следует вставить изображение и как вы хотите установить выделение, не используйте их.

Итак, как использовать insertContent()?

editor.model.change( writer => {
    const image = writer.createElement( 'image', { src: '...' } );
    const caption = writer.createElement( 'caption' );

    writer.appendText( 'Caption text', caption );
    writer.append( caption, image );


    // Option 1: If you have the <custom> element by reference:
    const positionInCustom = Position.createAt( customElement, 0 );

    editor.model.insertContent( image, positionInCustom );

    // In this case, we still have to set the selection because we haven't
    // passed document selection to `insertContent()` but a specific position.
    writer.setSelection( image, 'on' );


    // Option 2: Assuming that the document selection is somewhere
    // in your <custom> element you might do this (image will be inserted
    // at the document selection position):

    editor.model.insertContent( image );
} );

См. Документацию editor.model.insertContent() для получения дополнительной информации о различных способах ее использования.

...