rootattributeoperation.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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 Operation from './operation.js';
  7. import CKEditorError from '../../../utils/ckeditorerror.js';
  8. /**
  9. * Operation to change root element's attribute. Using this class you can add, remove or change value of the attribute.
  10. *
  11. * This operation is needed, because root elements can't be changed through {@link engine.treeModel.operation.AttributeOperation}.
  12. * It is because {@link engine.treeModel.operation.AttributeOperation} requires a range to change and root element can't
  13. * be a part of range because every {@link engine.treeModel.Position} has to be inside a root. {@link engine.treeModel.Position}
  14. * can't be created before a root element.
  15. *
  16. * @memberOf engine.treeModel.operation
  17. * @extends engine.treeModel.operation.Operation
  18. */
  19. export default class RootAttributeOperation extends Operation {
  20. /**
  21. * Creates an operation that changes, removes or adds attributes on root element.
  22. *
  23. * @see engine.treeModel.operation.AttributeOperation
  24. * @param {engine.treeModel.RootElement} root Root element to change.
  25. * @param {String} key Key of an attribute to change or remove.
  26. * @param {*} oldValue Old value of the attribute with given key or `null` if adding a new attribute.
  27. * @param {*} newValue New value to set for the attribute. If `null`, then the operation just removes the attribute.
  28. * @param {Number} baseVersion {@link engine.treeModel.Document#version} on which the operation can be applied.
  29. */
  30. constructor( root, key, oldValue, newValue, baseVersion ) {
  31. super( baseVersion );
  32. /**
  33. * Root element to change.
  34. *
  35. * @readonly
  36. * @member {engine.treeModel.RootElement} engine.treeModel.operation.RootAttributeOperation#root
  37. */
  38. this.root = root;
  39. /**
  40. * Key of an attribute to change or remove.
  41. *
  42. * @readonly
  43. * @member {String} engine.treeModel.operation.RootAttributeOperation#key
  44. */
  45. this.key = key;
  46. /**
  47. * Old value of the attribute with given key or `null` if adding a new attribute.
  48. *
  49. * @readonly
  50. * @member {*} engine.treeModel.operation.RootAttributeOperation#oldValue
  51. */
  52. this.oldValue = oldValue;
  53. /**
  54. * New value to set for the attribute. If `null`, then the operation just removes the attribute.
  55. *
  56. * @readonly
  57. * @member {*} engine.treeModel.operation.RootAttributeOperation#newValue
  58. */
  59. this.newValue = newValue;
  60. }
  61. get type() {
  62. if ( this.oldValue === null ) {
  63. return 'addRootAttribute';
  64. } else if ( this.newValue === null ) {
  65. return 'removeRootAttribute';
  66. } else {
  67. return 'changeRootAttribute';
  68. }
  69. }
  70. /**
  71. * @returns {engine.treeModel.operation.RootAttributeOperation}
  72. */
  73. clone() {
  74. return new RootAttributeOperation( this.root, this.key, this.oldValue, this.newValue, this.baseVersion );
  75. }
  76. /**
  77. * @returns {engine.treeModel.operation.RootAttributeOperation}
  78. */
  79. getReversed() {
  80. return new RootAttributeOperation( this.root, this.key, this.newValue, this.oldValue, this.baseVersion + 1 );
  81. }
  82. _execute() {
  83. if ( this.oldValue !== null && this.root.getAttribute( this.key ) !== this.oldValue ) {
  84. /**
  85. * The attribute which should be removed does not exists for the given node.
  86. *
  87. * @error operation-rootattribute-no-attr-to-remove
  88. * @param {engine.treeModel.RootElement} root
  89. * @param {String} key
  90. * @param {*} value
  91. */
  92. throw new CKEditorError(
  93. 'operation-rootattribute-no-attr-to-remove: The attribute which should be removed does not exists for given node.',
  94. { root: this.root, key: this.key }
  95. );
  96. }
  97. if ( this.oldValue === null && this.newValue !== null && this.root.hasAttribute( this.key ) ) {
  98. /**
  99. * The attribute with given key already exists for the given node.
  100. *
  101. * @error operation-rootattribute-attr-exists
  102. * @param {engine.treeModel.RootElement} root
  103. * @param {String} key
  104. */
  105. throw new CKEditorError(
  106. 'operation-rootattribute-attr-exists: The attribute with given key already exists.',
  107. { root: this.root, key: this.key }
  108. );
  109. }
  110. if ( this.newValue !== null ) {
  111. this.root.setAttribute( this.key, this.newValue );
  112. } else {
  113. this.root.removeAttribute( this.key );
  114. }
  115. return { root: this.root, key: this.key, oldValue: this.oldValue, newValue: this.newValue };
  116. }
  117. }