ckeditor5 начальный номер элемента списка - PullRequest
0 голосов
/ 29 ноября 2018

Попытка создать плагин для установки начального атрибута для ol в ckEditor5.

Насколько я могу судить, модель содержит коллекцию listItems.

Атрибут start должен быть установлен на ol, однако, на родительском элементе списка, а не на самом элементе списка. Есть ли способ получить доступ к ol из модели?

Я могу получить текущий li с помощью

first(editor.model.document.selection.getSelectedBlocks())

. Есть ли способ установить атрибут для элемента ol?

EDIT -код для получения атрибута на LI:

editor.model.schema.extend('listItem', { allowAttributes: 'listStart' });

editor.conversion.attributeToAttribute({ 
  model: 'listStart', 
  view: 'start'
});

включает в модели: <listItem type="numbered" listStart="4">, что будет переводить на это в представлении:

<ol>
  <li start="4">words</li>
</ol>

что я пытаюсь

<ol start="4">
  <li>words</li>
</ol>

Когда я изучаю источник, он выглядит так, как будто здесь автоматически создается ol (или ul):

function generateLiInUl( modelItem, conversionApi ) {

    const mapper = conversionApi.mapper;
    const viewWriter = conversionApi.writer;
    const listType = modelItem.getAttribute( 'listType' ) == 'numbered' ? 'ol' : 'ul';
    const viewItem = createViewListItemElement( viewWriter );
  // ** OL or UL created here -->
    const viewList = viewWriter.createContainerElement( listType, null );
        viewWriter.insert( ViewPosition.createAt( viewList ), viewItem );

    mapper.bindElements( modelItem, viewItem );

    return viewItem;
}

ссылка наисточник

Есть ли событие, которое я мог наблюдать?Или в определении преобразования есть способ нацелить атрибут на родительский элемент?

UPDATE 2

Если мы собираемся модифицировать источник, мы можем перехватить downcastдобавив это к функции generateLiInUl (спасибо MTilsted):

    const listStart = modelItem.getAttribute('listStart');
    if (listStart) {
        viewWriter.setAttribute('start', listStart, viewList);
    }

и для облегчения upcast добавьте это к функции viewModelConverter

    const listStart = data.viewItem.parent.getAttribute('start');
    if (listStart) {
        writer.setAttribute( 'listStart', listStart, listItem );
    }

Это немного уродливо в этоммы модифицируем источник, который является лаваш для обслуживания, и в upcast мы добавляем атрибут listStart к каждому элементу listItem в модели ... но это начало.

Я кратко рассмотрел добавление диспетчеров.. например:

data.upcastDispatcher.on( 'element:li', myCustomUpcastFunction );

, но не смог понять, как получить ссылку на элемент listItem, который был добавлен в модель в функции viewModelConverter, упомянутой выше.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Ответ, который работал для меня, был очень прост, и я чувствую себя немного глупо, не видя его раньше: используйте атрибут LI value вместо атрибута OL start.

<ol>
  <li value="4">words</li>
</ol>

вместо:

<ol start="4">
  <li>words</li>
</ol>

Это сохраняет атрибут в listItem и позволяет избежать всех сложностей (я полностью пропустил существование атрибута значения LI в моей первоначальной попытке):

editor.model.schema.extend('listItem', { allowAttributes: 'value' });

editor.conversion.attributeToAttribute({ 
  model: 'value', 
  view: 'value'
});

Команда дляприменить значение:

execute(arg) {

  let val = arg.value;
  const model = this.editor.model;
  const block = first(model.document.selection.getSelectedBlocks());

  model.change(writer => {
    if (+val) {
      writer.setAttribute('value', val, block);
    } else {
      writer.removeAttribute('value', block);
    }
  });

}

и для предотвращения копирования значения в следующий LI при вводе:

editor.commands.get('enter').on('afterExecute', () => {
  const block = first(editor.model.document.selection.getSelectedBlocks());
  if ( block.name == 'listItem' && block.hasAttribute('value')) {
    editor.model.change( writer => {
      writer.removeAttribute('value', block);
    });
  }
});
0 голосов
/ 30 ноября 2018

Обновлено: хорошо, как работают списки генерации нечетные.Что может иметь какое-то отношение к способу объединения списков и изменения типа.Должен признать, что я не совсем понимаю, как работает эта часть.

Я не смог найти способ уменьшить атрибут по мере необходимости, поэтому, если кто-то из Cksource не придет, единственное решение, которое я смогу найти, - этоисправьте код списка.И я не уверен, насколько хорошо это работает с upcast.(Только слегка проверено).

Но в файле node_modules/@ckeditor/ckeditor5-list/src/converters.js

Просто попробуйте добавить эту строку:

viewWriter.setAttribute('start',model.getAttribute('listStart'),viewList);

к методу

function generateLiInUl( modelItem, conversionApi ) {

В моей версии ckeditor (самая новая) его следует добавить в строку 810.

Оригинальный ответ (полезно, но не для списков).

О да.Вы правы насчет модели.Но суть дизайна в ckeditor 5 заключается в том, что вам не нужно изменять существующий плагин для добавления атрибутов.Вы можете зарегистрировать дополнительный атрибут в схеме, а затем добавить соответствующий DowncastElementToElement в свой собственный плагин.

Вот мой код, который я использую для добавления дополнительных атрибутов в класс изображений.Это должно быть тривиально, чтобы вместо этого работать на listItems.(Вырезать / вставить из разных мест в моем коде, так что я, возможно, что-то забыл, но попробуйте. И если вы не можете заставить его работать, я сделаю полностью рабочий пример понедельник:)

        model.schema.extend('image', {
            allowAttributes: ['displaywidth','ignorecolumns','fullpagepicture']
        } );

    editor.conversion.for('upcast')
                .add(upcastAttributeToAttribute( { model: 'isvisible', view: 'isvisible' }))
                .add(upcastAttributeToAttribute( { model: 'displaywidth', view: 'displaywidth' }))
                .add(upcastAttributeToAttribute( { model: 'fullpagepicture', view: 'fullpagepicture' }))

editor.conversion.for('downcast')
        .add(downcastAttributeToAttribute( { model: 'isvisible', view: 'isvisible' }))
        .add(downcastAttributeToAttribute( { model: 'displaywidth', view: 'displaywidth' }))
        .add(downcastAttributeToAttribute( { model: 'fullpagepicture', view: 'fullpagepicture' }))
...