renameoperation.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module engine/model/operation/renameoperation
  7. */
  8. import Operation from './operation';
  9. import Element from '../element';
  10. import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
  11. import Position from '../position';
  12. /**
  13. * Operation to change element's name.
  14. *
  15. * Using this class you can change element's name.
  16. *
  17. * @extends module:engine/model/operation/operation~Operation
  18. */
  19. export default class RenameOperation extends Operation {
  20. /**
  21. * Creates an operation that changes element's name.
  22. *
  23. * @param {module:engine/model/position~Position} position Position before an element to change.
  24. * @param {String} oldName Current name of the element.
  25. * @param {String} newName New name for the element.
  26. * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation
  27. * can be applied or `null` if the operation operates on detached (non-document) tree.
  28. */
  29. constructor( position, oldName, newName, baseVersion ) {
  30. super( baseVersion );
  31. /**
  32. * Position before an element to change.
  33. *
  34. * @member {module:engine/model/position~Position} module:engine/model/operation/renameoperation~RenameOperation#position
  35. */
  36. this.position = position;
  37. // This position sticks to the next node because it is a position before the node that we want to change.
  38. this.position.stickiness = 'toNext';
  39. /**
  40. * Current name of the element.
  41. *
  42. * @member {String} module:engine/model/operation/renameoperation~RenameOperation#oldName
  43. */
  44. this.oldName = oldName;
  45. /**
  46. * New name for the element.
  47. *
  48. * @member {String} module:engine/model/operation/renameoperation~RenameOperation#newName
  49. */
  50. this.newName = newName;
  51. }
  52. /**
  53. * @inheritDoc
  54. */
  55. get type() {
  56. return 'rename';
  57. }
  58. /**
  59. * Creates and returns an operation that has the same parameters as this operation.
  60. *
  61. * @returns {module:engine/model/operation/renameoperation~RenameOperation} Clone of this operation.
  62. */
  63. clone() {
  64. return new RenameOperation( this.position.clone(), this.oldName, this.newName, this.baseVersion );
  65. }
  66. /**
  67. * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.
  68. *
  69. * @returns {module:engine/model/operation/renameoperation~RenameOperation}
  70. */
  71. getReversed() {
  72. return new RenameOperation( this.position.clone(), this.newName, this.oldName, this.baseVersion + 1 );
  73. }
  74. /**
  75. * @inheritDoc
  76. */
  77. _validate() {
  78. const element = this.position.nodeAfter;
  79. if ( !( element instanceof Element ) ) {
  80. /**
  81. * Given position is invalid or node after it is not instance of Element.
  82. *
  83. * @error rename-operation-wrong-position
  84. */
  85. throw new CKEditorError(
  86. 'rename-operation-wrong-position',
  87. this
  88. );
  89. } else if ( element.name !== this.oldName ) {
  90. /**
  91. * Element to change has different name than operation's old name.
  92. *
  93. * @error rename-operation-wrong-name
  94. */
  95. throw new CKEditorError(
  96. 'rename-operation-wrong-name',
  97. this
  98. );
  99. }
  100. }
  101. /**
  102. * @inheritDoc
  103. */
  104. _execute() {
  105. const element = this.position.nodeAfter;
  106. element.name = this.newName;
  107. }
  108. /**
  109. * @inheritDoc
  110. */
  111. toJSON() {
  112. const json = super.toJSON();
  113. json.position = this.position.toJSON();
  114. return json;
  115. }
  116. /**
  117. * @inheritDoc
  118. */
  119. static get className() {
  120. return 'RenameOperation';
  121. }
  122. /**
  123. * Creates `RenameOperation` object from deserialized object, i.e. from parsed JSON string.
  124. *
  125. * @param {Object} json Deserialized JSON object.
  126. * @param {module:engine/model/document~Document} document Document on which this operation will be applied.
  127. * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}
  128. */
  129. static fromJSON( json, document ) {
  130. return new RenameOperation( Position.fromJSON( json.position, document ), json.oldName, json.newName, json.baseVersion );
  131. }
  132. // @if CK_DEBUG_ENGINE // toString() {
  133. // @if CK_DEBUG_ENGINE // return `RenameOperation( ${ this.baseVersion } ): ` +
  134. // @if CK_DEBUG_ENGINE // `${ this.position }: "${ this.oldName }" -> "${ this.newName }"`;
  135. // @if CK_DEBUG_ENGINE // }
  136. }