insertoperation.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import Operation from './operation.js';
  6. import Position from '../position.js';
  7. import NodeList from '../nodelist.js';
  8. import RemoveOperation from './removeoperation.js';
  9. import writer from './../writer.js';
  10. import { normalizeNodes } from './../writer.js';
  11. import Text from '../text.js';
  12. import Element from '../element.js';
  13. /**
  14. * Operation to insert one or more nodes at given position in the model.
  15. *
  16. * @memberOf engine.model.operation
  17. * @extends engine.model.operation.Operation
  18. */
  19. export default class InsertOperation extends Operation {
  20. /**
  21. * Creates an insert operation.
  22. *
  23. * @param {engine.model.Position} position Position of insertion.
  24. * @param {engine.model.NodeSet} nodes The list of nodes to be inserted.
  25. * @param {Number} baseVersion {@link engine.model.Document#version} on which operation can be applied.
  26. */
  27. constructor( position, nodes, baseVersion ) {
  28. super( baseVersion );
  29. /**
  30. * Position of insertion.
  31. *
  32. * @readonly
  33. * @member {engine.model.Position} engine.model.operation.InsertOperation#position
  34. */
  35. this.position = Position.createFromPosition( position );
  36. /**
  37. * List of nodes to insert.
  38. *
  39. * @readonly
  40. * @member {engine.model.NodeList} engine.model.operation.InsertOperation#nodeList
  41. */
  42. this.nodes = new NodeList( normalizeNodes( nodes ) );
  43. }
  44. /**
  45. * @inheritDoc
  46. */
  47. get type() {
  48. return 'insert';
  49. }
  50. /**
  51. * @inheritDoc
  52. * @returns {engine.model.operation.InsertOperation}
  53. */
  54. clone() {
  55. return new InsertOperation( this.position, this.nodes, this.baseVersion );
  56. }
  57. /**
  58. * @inheritDoc
  59. * @returns {engine.model.operation.RemoveOperation}
  60. */
  61. getReversed() {
  62. return new RemoveOperation( this.position, this.nodes.getMaxOffset(), this.baseVersion + 1 );
  63. }
  64. /**
  65. * @inheritDoc
  66. */
  67. _execute() {
  68. // What happens here is that we want original nodes be passed to writer because we want original nodes
  69. // to be inserted to the model. But in InsertOperation, we want to keep those nodes as they were added
  70. // to the operation, not modified. For example, text nodes can get merged or cropped while Elements can
  71. // get children. It is important that InsertOperation has the copy of original nodes in intact state.
  72. const originalNodes = this.nodes;
  73. this.nodes = new NodeList( [ ...originalNodes ].map( ( node ) => node.clone( true ) ) );
  74. const range = writer.insert( this.position, originalNodes );
  75. return { range };
  76. }
  77. /**
  78. * @inheritDoc
  79. */
  80. static get className() {
  81. return 'engine.model.operation.InsertOperation';
  82. }
  83. /**
  84. * Creates `InsertOperation` object from deserilized object, i.e. from parsed JSON string.
  85. *
  86. * @param {Object} json Deserialized JSON object.
  87. * @param {engine.model.Document} document Document on which this operation will be applied.
  88. * @returns {engine.model.operation.InsertOperation}
  89. */
  90. static fromJSON( json, document ) {
  91. let children = [];
  92. for ( let child of json.nodes ) {
  93. if ( child.name ) {
  94. // If child has name property, it is an Element.
  95. children.push( Element.fromJSON( child ) );
  96. } else {
  97. // Otherwise, it is a Text node.
  98. children.push( Text.fromJSON( child ) );
  99. }
  100. }
  101. return new InsertOperation( Position.fromJSON( json.position, document ), children, json.baseVersion );
  102. }
  103. }