mentionediting.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /**
  2. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module mention/mentionediting
  7. */
  8. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  9. import MentionCommand from './mentioncommand';
  10. /**
  11. * The mention editing feature.
  12. *
  13. * @extends module:core/plugin~Plugin
  14. */
  15. export default class MentionEditing extends Plugin {
  16. /**
  17. * @inheritDoc
  18. */
  19. static get pluginName() {
  20. return 'MentionEditing';
  21. }
  22. /**
  23. * @inheritDoc
  24. */
  25. init() {
  26. const editor = this.editor;
  27. // Allow mention attribute on text nodes.
  28. editor.model.schema.extend( '$text', { allowAttributes: 'mention' } );
  29. editor.conversion.for( 'upcast' ).elementToAttribute( {
  30. view: {
  31. name: 'span',
  32. key: 'data-mention',
  33. classes: 'mention'
  34. },
  35. model: {
  36. key: 'mention',
  37. value: viewItem => {
  38. return viewItem.getAttribute( 'data-mention' );
  39. }
  40. }
  41. } );
  42. editor.conversion.for( 'downcast' ).attributeToElement( {
  43. model: 'mention',
  44. view: ( modelAttributeValue, viewWriter ) => {
  45. return viewWriter.createAttributeElement( 'span', {
  46. class: 'mention',
  47. 'data-mention': modelAttributeValue
  48. } );
  49. }
  50. } );
  51. // Remove mention attribute if text was edited.
  52. editor.model.document.registerPostFixer( writer => {
  53. const changes = editor.model.document.differ.getChanges();
  54. let wasChanged = false;
  55. for ( const change of changes ) {
  56. if ( change.type == 'insert' || change.type == 'remove' ) {
  57. const textNode = change.position.textNode;
  58. if ( change.name == '$text' && textNode && textNode.hasAttribute( 'mention' ) ) {
  59. writer.removeAttribute( 'mention', textNode );
  60. wasChanged = true;
  61. }
  62. }
  63. if ( change.type == 'remove' ) {
  64. const nodeBefore = change.position.nodeBefore;
  65. if ( nodeBefore && nodeBefore.hasAttribute( 'mention' ) ) {
  66. const text = nodeBefore.data;
  67. if ( text != nodeBefore.getAttribute( 'mention' ) ) {
  68. writer.removeAttribute( 'mention', nodeBefore );
  69. wasChanged = true;
  70. }
  71. }
  72. }
  73. }
  74. return wasChanged;
  75. } );
  76. editor.model.document.registerPostFixer( writer => {
  77. const selection = editor.model.document.selection;
  78. const focus = selection.focus;
  79. if ( selection.hasAttribute( 'mention' ) && selection.isCollapsed && focus.nodeBefore && focus.nodeBefore.is( 'text' ) ) {
  80. writer.removeSelectionAttribute( 'mention' );
  81. return true;
  82. }
  83. } );
  84. editor.commands.add( 'mention', new MentionCommand( editor ) );
  85. }
  86. }