Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
move( range, itemOrPosition, offset ) {
this._assertWriterUsedCorrectly();
if ( !( range instanceof Range ) ) {
/**
* Invalid range to move.
*
* @error writer-move-invalid-range
*/
throw new CKEditorError( 'writer-move-invalid-range: Invalid range to move.', this );
}
if ( !range.isFlat ) {
/**
* Range to move is not flat.
*
* @error writer-move-range-not-flat
*/
throw new CKEditorError( 'writer-move-range-not-flat: Range to move is not flat.', this );
}
const position = Position._createAt( itemOrPosition, offset );
// Do not move anything if the move target is same as moved range start.
if ( position.isEqual( range.start ) ) {
return;
if ( !( range instanceof Range ) ) {
/**
* Invalid range to move.
*
* @error writer-move-invalid-range
*/
throw new CKEditorError( 'writer-move-invalid-range: Invalid range to move.', this );
}
if ( !range.isFlat ) {
/**
* Range to move is not flat.
*
* @error writer-move-range-not-flat
*/
throw new CKEditorError( 'writer-move-range-not-flat: Range to move is not flat.', this );
}
const position = Position._createAt( itemOrPosition, offset );
// Do not move anything if the move target is same as moved range start.
if ( position.isEqual( range.start ) ) {
return;
}
// If part of the marker is removed, create additional marker operation for undo purposes.
this._addOperationForAffectedMarkers( 'move', range );
if ( !isSameTree( range.root, position.root ) ) {
/**
* Range is going to be moved within not the same document. Please use
* {@link module:engine/model/writer~Writer#insert insert} instead.
return;
}
const hasUsingOperationDefined = typeof options.usingOperation == 'boolean';
const affectsDataDefined = typeof options.affectsData == 'boolean';
// Use previously defined marker's affectsData if the property is not provided.
const affectsData = affectsDataDefined ? options.affectsData : currentMarker.affectsData;
if ( !hasUsingOperationDefined && !options.range && !affectsDataDefined ) {
/**
* One of the options is required - provide range, usingOperations or affectsData.
*
* @error writer-updateMarker-wrong-options
*/
throw new CKEditorError(
'writer-updateMarker-wrong-options: One of the options is required - provide range, usingOperations or affectsData.',
this
);
}
const currentRange = currentMarker.getRange();
const updatedRange = options.range ? options.range : currentRange;
if ( hasUsingOperationDefined && options.usingOperation !== currentMarker.managedUsingOperations ) {
// The marker type is changed so it's necessary to create proper operations.
if ( options.usingOperation ) {
// If marker changes to a managed one treat this as synchronizing existing marker.
// Create `MarkerOperation` with `oldRange` set to `null`, so reverse operation will remove the marker.
applyMarkerOperation( this, markerName, null, updatedRange, affectsData );
} else {
// If marker changes to a marker that do not use operations then we need to create additional operation
register( itemName, rules ) {
if ( this._sourceRules[ itemName ] ) {
// TODO docs
throw new CKEditorError( 'schema-cannot-register-item-twice: A single item cannot be registered twice in the schema.' );
}
this._sourceRules[ itemName ] = [
Object.assign( {}, rules )
];
this._clearCache();
}
_createConversionHelpers( { name, dispatchers, isDowncast } ) {
if ( this._helpers.has( name ) ) {
/**
* Trying to register a group name that has already been registered.
*
* @error conversion-group-exists
*/
throw new CKEditorError( 'conversion-group-exists: Trying to register a group name that has already been registered.', this );
}
const helpers = isDowncast ? new DowncastHelpers( dispatchers ) : new UpcastHelpers( dispatchers );
this._helpers.set( name, helpers );
}
}
static createFromSelection() {
/**
* Cannot create a new `LiveSelection` instance.
*
* `LiveSelection#createFromSelection()` is not available. There can be only one
* `LiveSelection` per document instance, so creating new `LiveSelection`s this way
* would be unsafe.
*
* @error liveselection-cannot-create
*/
throw new CKEditorError( 'liveselection-cannot-create: Cannot create a new LiveSelection instance.' );
}
static createFromParentAndOffset( parent, offset ) {
if ( !parent.is( 'element' ) && !parent.is( 'documentFragment' ) ) {
/**
* Position parent have to be a model element or model document fragment.
*
* @error model-position-parent-incorrect
*/
throw new CKEditorError( 'model-position-parent-incorrect: Position parent have to be a element or document fragment.' );
}
const path = parent.getPath();
path.push( offset );
return new this( parent.root, path );
}
for( groupName ) {
if ( !this._helpers.has( groupName ) ) {
/**
* Trying to add a converter to an unknown dispatchers group.
*
* @error conversion-for-unknown-group
*/
throw new CKEditorError( 'conversion-for-unknown-group: Trying to add a converter to an unknown dispatchers group.', this );
}
return this._helpers.get( groupName );
}
updateSourceElement() {
if ( !this.sourceElement ) {
/**
* Cannot update the source element of a detached editor.
*
* The {@link ~ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not
* pass an element to `Editor.create()`.
*
* @error editor-missing-sourceelement
*/
throw new CKEditorError(
'editor-missing-sourceelement: Cannot update the source element of a detached editor.',
this
);
}
setDataInElement( this.sourceElement, this.data.get() );
}
};
} else if ( sourceOffset + this.howMany > sourceElement.maxOffset ) {
/**
* The nodes which should be moved do not exist.
*
* @error move-operation-nodes-do-not-exist
*/
throw new CKEditorError(
'move-operation-nodes-do-not-exist: The nodes which should be moved do not exist.', this
);
} else if ( sourceElement === targetElement && sourceOffset < targetOffset && targetOffset < sourceOffset + this.howMany ) {
/**
* Trying to move a range of nodes into the middle of that range.
*
* @error move-operation-range-into-itself
*/
throw new CKEditorError(
'move-operation-range-into-itself: Trying to move a range of nodes to the inside of that range.', this
);
} else if ( this.sourcePosition.root == this.targetPosition.root ) {
if ( compareArrays( this.sourcePosition.getParentPath(), this.targetPosition.getParentPath() ) == 'prefix' ) {
const i = this.sourcePosition.path.length - 1;
if ( this.targetPosition.path[ i ] >= sourceOffset && this.targetPosition.path[ i ] < sourceOffset + this.howMany ) {
/**
* Trying to move a range of nodes into one of nodes from that range.
*
* @error move-operation-node-into-itself
*/
throw new CKEditorError(
'move-operation-node-into-itself: Trying to move a range of nodes into one of nodes from that range.', this
);
}