#ckeditor5
#ckeditor5
Вопрос:
Мне нужно добавить ‘id’ attr к элементам заголовка, у которых его нет.
Я пытаюсь это сделать
conversion.for('upcast').elementToElement({
model: (viewElement, modelWriter) => {
const attrs = {};
const id = viewElement.getAttribute('id');
if (id) {
attrs['id'] = id;
}
return modelWriter.createElement('heading1', attrs);
},
view: {
name: 'h1'
},
converterPriority: 'low' 1
});
conversion.for('downcast').add(dispatcher => {
dispatcher.on('insert:heading1', (evt, data, conversionApi) => {
if (!data.item.getAttribute('id')) {
conversionApi.writer.setAttribute('id', generateUID(), data.item)
}
});
});
conversion.for('downcast').attributeToAttribute({
model: {
name: 'heading1',
key: 'id'
},
view: {
name: 'h1',
key: 'id'
}
});
editor.conversion.elementToElement(option);
modelElements.push(option.model);
и это изменило модель с
<$root>
<heading1 id="ykuqo5" >some text</heading1>
</$root>
но у представления все еще нет ‘id’ attr.
Я ожидаю, что HTML-тег в редакторе будет иметь идентификатор, соответствующий модели. Спасибо за помощь, извините за мой английский
Ответ №1:
c. Есть несколько незначительных проблем:
- Процесс преобразования может быть упрощен до двустороннего конвертера
conversion.attributeToAttribute()
. - Вы должны разрешить
id
атрибут для всех заголовков либо расширив их определения, либо добавив проверку атрибута в схему. - Принудительное изменение состояния модели должно быть выполнено путем добавления исправления документа модели.
class HeadingIdAttribute extends Plugin {
init() {
const editor = this.editor;
const model = editor.model;
const conversion = editor.conversion;
// Allow 'id' attribute on heading* elements:
// Either by extending each heading definition:
// editor.model.schema.extend( 'heading1', { allowAttributes: [ 'id' ] } );
// editor.model.schema.extend( 'heading2', { allowAttributes: [ 'id' ] } );
// editor.model.schema.extend( 'heading3', { allowAttributes: [ 'id' ] } );
// or by adding a more general attribute check:
model.schema.addAttributeCheck( ( schemaContext, attribute ) => {
if ( attribute == 'id' amp;amp; isHeading( schemaContext.last.name ) ) {
return true;
}
} );
// Then the conversion might be a two way attribute-to-attribute:
conversion.attributeToAttribute( {
model: 'id',
view: 'id'
} );
// Register a model post-fixer to add missing id attribute
// to the heading* element.
model.document.registerPostFixer( writer => {
let wasChanged = false;
// Get changes
const changes = model.document.differ.getChanges();
for ( const change of changes ) {
// Check heading nodes on insert.
if ( change.type == 'insert' amp;amp; isHeading( change.name ) ) {
const heading = change.position.nodeAfter;
// Set 'id' attribute when it is missing in the model.
if ( !heading.hasAttribute( 'id' ) ) {
writer.setAttribute( 'id', uid(), heading );
// Return true to notify that model was altered.
wasChanged = true;
}
}
}
return wasChanged;
} );
// Helper method for checking if name is any heading element.
// Detects default headings: 'heading1', 'heading2', ... 'heading6'.
function isHeading( name ) {
return name.slice( 0, -1 ) == 'heading';
}
}
}
И добавьте этот плагин в свой редактор (не забудьте добавить также другие плагины):
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Enter, Typing, Undo, Heading, Paragraph, HeadingIdAttribute ],
toolbar: [ 'heading', '|', 'undo', 'redo' ]
} )
.then( editor => {
window.editor = editor;
} )
.catch( err => {
console.error( err.stack );
} );
Это также создаст атрибут id для представления: