attributedelta.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module engine/model/delta/attributedelta
  7. */
  8. import Delta from './delta';
  9. import DeltaFactory from './deltafactory';
  10. import NoOperation from '../operation/nooperation';
  11. import Range from '../range';
  12. /**
  13. * To provide specific OT behavior and better collisions solving, methods to change attributes
  14. * ({@link module:engine/model/batch~Batch#setAttribute} and {@link module:engine/model/batch~Batch#removeAttribute})
  15. * use `AttributeDelta` class which inherits from the `Delta` class and may overwrite some methods.
  16. *
  17. * @extends module:engine/model/delta/delta~Delta
  18. */
  19. export default class AttributeDelta extends Delta {
  20. /**
  21. * @inheritDoc
  22. */
  23. get type() {
  24. return 'attribute';
  25. }
  26. /**
  27. * The attribute key that is changed by the delta or `null` if the delta has no operations.
  28. *
  29. * @readonly
  30. * @type {String|null}
  31. */
  32. get key() {
  33. return this.operations[ 0 ] ? this.operations[ 0 ].key : null;
  34. }
  35. /**
  36. * The attribute value that is set by the delta or `null` if the delta has no operations.
  37. *
  38. * @readonly
  39. * @type {*|null}
  40. */
  41. get value() {
  42. return this.operations[ 0 ] ? this.operations[ 0 ].newValue : null;
  43. }
  44. /**
  45. * The range on which delta operates or `null` if the delta has no operations.
  46. *
  47. * @readonly
  48. * @type {module:engine/model/range~Range|null}
  49. */
  50. get range() {
  51. // Check if it is cached.
  52. if ( this._range ) {
  53. return this._range;
  54. }
  55. let start = null;
  56. let end = null;
  57. for ( const operation of this.operations ) {
  58. if ( operation instanceof NoOperation ) {
  59. continue;
  60. }
  61. if ( start === null || start.isAfter( operation.range.start ) ) {
  62. start = operation.range.start;
  63. }
  64. if ( end === null || end.isBefore( operation.range.end ) ) {
  65. end = operation.range.end;
  66. }
  67. }
  68. if ( start && end ) {
  69. this._range = new Range( start, end );
  70. return this._range;
  71. }
  72. return null;
  73. }
  74. get _reverseDeltaClass() {
  75. return AttributeDelta;
  76. }
  77. /**
  78. * @inheritDoc
  79. */
  80. toJSON() {
  81. const json = super.toJSON();
  82. delete json._range;
  83. return json;
  84. }
  85. /**
  86. * @inheritDoc
  87. */
  88. static get className() {
  89. return 'engine.model.delta.AttributeDelta';
  90. }
  91. }
  92. DeltaFactory.register( AttributeDelta );