deletecommand.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. import Command from '../command/command.js';
  7. import Selection from '../engine/model/selection.js';
  8. import ChangeBuffer from './changebuffer.js';
  9. import count from '../utils/count.js';
  10. /**
  11. * Delete command. Used by the {@link delete.Delete delete feature} to handle <kbd>Delete</kbd> and
  12. * <kbd>Backspace</kbd> keys.
  13. *
  14. * @member delete
  15. * @extends ckeditor5.command.Command
  16. */
  17. export default class DeleteCommand extends Command {
  18. /**
  19. * Creates instance of the command;
  20. *
  21. * @param {ckeditor5.Editor} editor
  22. * @param {'FORWARD'|'BACKWARD'} direction The directionality of the delete (in what direction it should
  23. * consume the content when selection is collapsed).
  24. */
  25. constructor( editor, direction ) {
  26. super( editor );
  27. /**
  28. * The directionality of the delete (in what direction it should
  29. * consume the content when selection is collapsed).
  30. *
  31. * @readonly
  32. * @member {'FORWARD'|'BACKWARD'} delete.DeleteCommand#direction
  33. */
  34. this.direction = direction;
  35. /**
  36. * Delete's change buffer used to group subsequent changes into batches.
  37. *
  38. * @readonly
  39. * @private
  40. * @member {typing.ChangeBuffer} delete.DeleteCommand#buffer
  41. */
  42. this._buffer = new ChangeBuffer( editor.document, editor.config.get( 'undo.step' ) );
  43. }
  44. /**
  45. * Executes the command: depending on whether the selection is collapsed or not, deletes its contents
  46. * or piece of content in the {@link delete.DeleteCommand#direction defined direction}.
  47. *
  48. * @param {Object} [options] The command options.
  49. * @param {'CHARACTER'} [options.unit='CHARACTER'] See {@link engine.model.composer.modifySelection}'s options.
  50. */
  51. _doExecute( options = {} ) {
  52. const doc = this.editor.document;
  53. doc.enqueueChanges( () => {
  54. const selection = Selection.createFromSelection( doc.selection );
  55. // Try to extend the selection in the specified direction.
  56. if ( selection.isCollapsed ) {
  57. doc.composer.modifySelection( selection, { direction: this.direction, unit: options.unit } );
  58. }
  59. // If selection is still collapsed, then there's nothing to delete.
  60. if ( selection.isCollapsed ) {
  61. return;
  62. }
  63. let changeCount = 0;
  64. selection.getFirstRange().getMinimalFlatRanges().forEach( ( range ) => {
  65. changeCount += count(
  66. range.getWalker( { singleCharacters: true, ignoreElementEnd: true, shallow: true } )
  67. );
  68. } );
  69. doc.composer.deleteContents( this._buffer.batch, selection, { merge: true } );
  70. this._buffer.input( changeCount );
  71. doc.selection.setRanges( selection.getRanges(), selection.isBackward );
  72. } );
  73. }
  74. }