| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
- 'use strict';
- import Delta from './delta.js';
- import DeltaFactory from './deltafactory.js';
- import SplitDelta from './splitdelta.js';
- import { register } from '../batch.js';
- import Position from '../position.js';
- import Element from '../element.js';
- import RemoveOperation from '../operation/removeoperation.js';
- import MoveOperation from '../operation/moveoperation.js';
- import CKEditorError from '../../../utils/ckeditorerror.js';
- /**
- * @classdesc
- * To provide specific OT behavior and better collisions solving, {@link engine.model.Batch#merge} method
- * uses the `MergeDelta` class which inherits from the `Delta` class and may overwrite some methods.
- *
- * @memberOf engine.model.delta
- */
- export default class MergeDelta extends Delta {
- /**
- * Position between to merged nodes or `null` if the delta has no operations.
- *
- * @type {engine.model.Position|null}
- */
- get position() {
- return this._removeOperation ? this._removeOperation.sourcePosition : null;
- }
- getReversed() {
- let delta = super.getReversed();
- if ( delta.operations.length > 0 ) {
- delta.operations[ 1 ].isSticky = false;
- }
- return delta;
- }
- /**
- * Operation in this delta that removes the node after merge position (which will be empty at that point) or
- * `null` if the delta has no operations. Note, that after {@link engine.model.delta.transform transformation}
- * this might be an instance of {@link engine.model.operation.MoveOperation} instead of
- * {@link engine.model.operation.RemoveOperation}.
- *
- * @protected
- * @type {engine.model.operation.MoveOperation|null}
- */
- get _removeOperation() {
- return this.operations[ 1 ] || null;
- }
- get _reverseDeltaClass() {
- return SplitDelta;
- }
- /**
- * @inheritDoc
- */
- static get className() {
- return 'engine.model.delta.MergeDelta';
- }
- }
- /**
- * Merges two siblings at the given position.
- *
- * Node before and after the position have to be an element. Otherwise `batch-merge-no-element-before` or
- * `batch-merge-no-element-after` error will be thrown.
- *
- * @chainable
- * @method engine.model.Batch#merge
- * @param {engine.model.Position} position Position of merge.
- */
- register( 'merge', function( position ) {
- const delta = new MergeDelta();
- this.addDelta( delta );
- const nodeBefore = position.nodeBefore;
- const nodeAfter = position.nodeAfter;
- if ( !( nodeBefore instanceof Element ) ) {
- /**
- * Node before merge position must be an element.
- *
- * @error batch-merge-no-element-before
- */
- throw new CKEditorError(
- 'batch-merge-no-element-before: Node before merge position must be an element.' );
- }
- if ( !( nodeAfter instanceof Element ) ) {
- /**
- * Node after merge position must be an element.
- *
- * @error batch-merge-no-element-after
- */
- throw new CKEditorError(
- 'batch-merge-no-element-after: Node after merge position must be an element.' );
- }
- const positionAfter = Position.createFromParentAndOffset( nodeAfter, 0 );
- const positionBefore = Position.createFromParentAndOffset( nodeBefore, nodeBefore.getChildCount() );
- const move = new MoveOperation( positionAfter, nodeAfter.getChildCount(), positionBefore, this.doc.version );
- move.isSticky = true;
- delta.addOperation( move );
- this.doc.applyOperation( move );
- const remove = new RemoveOperation( position, 1, this.doc.version );
- delta.addOperation( remove );
- this.doc.applyOperation( remove );
- return this;
- } );
- DeltaFactory.register( MergeDelta );
|