Skip to content

Instantly share code, notes, and snippets.

@mlewand
Last active November 2, 2020 17:46
Show Gist options
  • Save mlewand/51a76b8b3172e39083107996d627c696 to your computer and use it in GitHub Desktop.
Save mlewand/51a76b8b3172e39083107996d627c696 to your computer and use it in GitHub Desktop.
/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/* global document, console, window */
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import EnterPlugin from '@ckeditor/ckeditor5-enter/src/enter';
import TypingPlugin from '@ckeditor/ckeditor5-typing/src/typing';
import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import HeadingPlugin from '@ckeditor/ckeditor5-heading/src/heading';
import ImagePlugin from '../../src/image';
import UndoPlugin from '@ckeditor/ckeditor5-undo/src/undo';
import ClipboardPlugin from '@ckeditor/ckeditor5-clipboard/src/clipboard';
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import Command from '@ckeditor/ckeditor5-core/src/command';
export default class TagSpan extends Plugin {
static get requires() {
return [ TicketIdEditing ];
}
}
const TICKET_ID_ATTRIBUTE_NAME = 'ticket-id';
class TicketIdEditing extends Plugin {
init() {
const editor = this.editor;
editor.model.schema.extend( '$text', {
allowAttributes: TICKET_ID_ATTRIBUTE_NAME
} );
editor.model.schema.setAttributeProperties( TICKET_ID_ATTRIBUTE_NAME, {
isFormatting: false,
copyOnEnter: false
} );
editor.conversion.for( 'downcast' ).attributeToElement( {
model: TICKET_ID_ATTRIBUTE_NAME,
view: ( attributeValue, conversionApi ) => {
if ( !attributeValue || !attributeValue[ 'ticket-id' ] ) {
return;
}
return conversionApi.writer.createAttributeElement( 'span', {
href: 'addTicketSpan',
'ticket-id': attributeValue[ 'ticket-id' ],
'another-id': attributeValue[ 'another-id' ]
} );
}
} );
editor.conversion.for( 'upcast' ).elementToAttribute( {
view: {
name: 'span',
'ticket-id': /.+/, // assume the first attribute name is id
'another-id': /.+/ // and the second attribute is called another-id
},
model: {
key: TICKET_ID_ATTRIBUTE_NAME,
value: viewElement => {
// Now in model, the TICKET_ID_ATTRIBUTE_NAME will contain an object.
return {
'ticket-id': viewElement.getAttribute( 'ticket-id' ),
'another-id': viewElement.getAttribute( 'another-id' )
};
}
}
} );
editor.commands.add( 'setTicketId', new TicketIdCommand( editor ) );
}
}
class TicketIdCommand extends Command {
execute( ticketId ) {
const model = this.editor.model;
const selection = model.document.selection;
const ranges = model.schema.getValidRanges( selection.getRanges(), TICKET_ID_ATTRIBUTE_NAME );
model.change( writer => {
for ( const range of ranges ) {
if ( ticketId ) {
writer.setAttribute( TICKET_ID_ATTRIBUTE_NAME, ticketId, range );
} else {
writer.removeAttribute( TICKET_ID_ATTRIBUTE_NAME, range );
}
}
} );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment