@ckeditor/ckeditor5-engine
Advanced tools
Comparing version 34.0.0 to 34.1.0
@@ -5,3 +5,3 @@ Software License Agreement | ||
**CKEditor 5 editing engine** – https://github.com/ckeditor/ckeditor5-engine <br> | ||
Copyright (c) 2003-2022, [CKSource](http://cksource.com) Holding sp. z o.o. All rights reserved. | ||
Copyright (c) 2003-2022, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved. | ||
@@ -18,2 +18,2 @@ Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). | ||
**CKEditor** is a trademark of [CKSource](http://cksource.com) Holding sp. z o.o. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders. | ||
**CKEditor** is a trademark of [CKSource Holding sp. z o.o.](https://cksource.com) All other brand and product names are trademarks, registered trademarks or service marks of their respective holders. |
{ | ||
"name": "@ckeditor/ckeditor5-engine", | ||
"version": "34.0.0", | ||
"version": "34.1.0", | ||
"description": "The editing engine of CKEditor 5 – the best browser-based rich text editor.", | ||
@@ -26,26 +26,26 @@ "keywords": [ | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-utils": "^34.0.0", | ||
"@ckeditor/ckeditor5-utils": "^34.1.0", | ||
"lodash-es": "^4.17.15" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-basic-styles": "^34.0.0", | ||
"@ckeditor/ckeditor5-block-quote": "^34.0.0", | ||
"@ckeditor/ckeditor5-clipboard": "^34.0.0", | ||
"@ckeditor/ckeditor5-cloud-services": "^34.0.0", | ||
"@ckeditor/ckeditor5-core": "^34.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^34.0.0", | ||
"@ckeditor/ckeditor5-enter": "^34.0.0", | ||
"@ckeditor/ckeditor5-essentials": "^34.0.0", | ||
"@ckeditor/ckeditor5-heading": "^34.0.0", | ||
"@ckeditor/ckeditor5-image": "^34.0.0", | ||
"@ckeditor/ckeditor5-link": "^34.0.0", | ||
"@ckeditor/ckeditor5-list": "^34.0.0", | ||
"@ckeditor/ckeditor5-mention": "^34.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^34.0.0", | ||
"@ckeditor/ckeditor5-table": "^34.0.0", | ||
"@ckeditor/ckeditor5-theme-lark": "^34.0.0", | ||
"@ckeditor/ckeditor5-typing": "^34.0.0", | ||
"@ckeditor/ckeditor5-ui": "^34.0.0", | ||
"@ckeditor/ckeditor5-undo": "^34.0.0", | ||
"@ckeditor/ckeditor5-widget": "^34.0.0", | ||
"@ckeditor/ckeditor5-basic-styles": "^34.1.0", | ||
"@ckeditor/ckeditor5-block-quote": "^34.1.0", | ||
"@ckeditor/ckeditor5-clipboard": "^34.1.0", | ||
"@ckeditor/ckeditor5-cloud-services": "^34.1.0", | ||
"@ckeditor/ckeditor5-core": "^34.1.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^34.1.0", | ||
"@ckeditor/ckeditor5-enter": "^34.1.0", | ||
"@ckeditor/ckeditor5-essentials": "^34.1.0", | ||
"@ckeditor/ckeditor5-heading": "^34.1.0", | ||
"@ckeditor/ckeditor5-image": "^34.1.0", | ||
"@ckeditor/ckeditor5-link": "^34.1.0", | ||
"@ckeditor/ckeditor5-list": "^34.1.0", | ||
"@ckeditor/ckeditor5-mention": "^34.1.0", | ||
"@ckeditor/ckeditor5-paragraph": "^34.1.0", | ||
"@ckeditor/ckeditor5-table": "^34.1.0", | ||
"@ckeditor/ckeditor5-theme-lark": "^34.1.0", | ||
"@ckeditor/ckeditor5-typing": "^34.1.0", | ||
"@ckeditor/ckeditor5-ui": "^34.1.0", | ||
"@ckeditor/ckeditor5-undo": "^34.1.0", | ||
"@ckeditor/ckeditor5-widget": "^34.1.0", | ||
"webpack": "^5.58.1", | ||
@@ -52,0 +52,0 @@ "webpack-cli": "^4.9.0" |
@@ -155,5 +155,5 @@ /** | ||
/** | ||
* The list of elements that were created during splitting but should not get removed on conversion end even if they are empty. | ||
* The list of elements that were created during the splitting but should not get removed on conversion end even if they are empty. | ||
* | ||
* After the conversion process the list is cleared. | ||
* The list is cleared after the conversion process. | ||
* | ||
@@ -468,3 +468,3 @@ * @private | ||
/** | ||
* Mark an element that were created during splitting that it should not get removed on conversion end even if it's empty. | ||
* Mark an element that were created during the splitting to not get removed on conversion end even if it is empty. | ||
* | ||
@@ -784,3 +784,3 @@ * @private | ||
/** | ||
* Mark an element that was created during splitting that it should not get removed on conversion end even if it's empty. | ||
* Mark an element that was created during splitting to not get removed on conversion end even if it is empty. | ||
* | ||
@@ -787,0 +787,0 @@ * **Note:** This is an advanced method. For most cases you will not need to keep the split empty element. |
@@ -870,2 +870,9 @@ /** | ||
return ( evt, data, conversionApi ) => { | ||
// Converting an attribute of an element that has not been converted to anything does not make sense | ||
// because there will be nowhere to set that attribute on. At this stage, the element should've already | ||
// been converted (https://github.com/ckeditor/ckeditor5/issues/11000). | ||
if ( !data.modelRange && shallow ) { | ||
return; | ||
} | ||
const match = matcher.match( data.viewItem ); | ||
@@ -881,3 +888,4 @@ | ||
} else { | ||
// Do not test or consume `name` consumable. | ||
// Do not test `name` consumable because it could get consumed already while upcasting some other attribute | ||
// on the same element (for example <span class="big" style="color: red">foo</span>). | ||
delete match.match.name; | ||
@@ -913,2 +921,11 @@ } | ||
if ( attributeWasSet ) { | ||
// Verify if the element itself wasn't consumed yet. It could be consumed already while upcasting some other attribute | ||
// on the same element (for example <span class="big" style="color: red">foo</span>). | ||
// We need to consume it so other features (especially GHS) won't try to convert it. | ||
// Note that it's not tested by the other element-to-attribute converters whether an element was consumed before | ||
// (in case of converters that the element itself is just a context and not the primary information to convert). | ||
if ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) { | ||
match.match.name = true; | ||
} | ||
conversionApi.consumable.consume( data.viewItem, match.match ); | ||
@@ -915,0 +932,0 @@ } |
@@ -41,2 +41,7 @@ /** | ||
export { default as ViewElement } from './view/element'; | ||
export { default as ViewContainerElement } from './view/containerelement'; | ||
export { default as ViewAttributeElement } from './view/attributeelement'; | ||
export { default as ViewEmptyElement } from './view/emptyelement'; | ||
export { default as ViewRawElement } from './view/rawelement'; | ||
export { default as ViewUIElement } from './view/uielement'; | ||
export { default as ViewDocumentFragment } from './view/documentfragment'; | ||
@@ -43,0 +48,0 @@ |
@@ -56,13 +56,2 @@ /** | ||
/** | ||
* The document version. It starts from `0` and every operation increases the version number. It is used to ensure that | ||
* operations are applied on a proper document version. | ||
* | ||
* If the {@link module:engine/model/operation/operation~Operation#baseVersion base version} does not match the document version, | ||
* a {@link module:utils/ckeditorerror~CKEditorError model-document-applyoperation-wrong-version} error is thrown. | ||
* | ||
* @type {Number} | ||
*/ | ||
this.version = 0; | ||
/** | ||
* The document's history. | ||
@@ -73,3 +62,3 @@ * | ||
*/ | ||
this.history = new History( this ); | ||
this.history = new History(); | ||
@@ -120,17 +109,2 @@ /** | ||
// First, if the operation is a document operation check if it's base version is correct. | ||
this.listenTo( model, 'applyOperation', ( evt, args ) => { | ||
const operation = args[ 0 ]; | ||
if ( operation.isDocumentOperation && operation.baseVersion !== this.version ) { | ||
/** | ||
* Only operations with matching versions can be applied. | ||
* | ||
* @error model-document-applyoperation-wrong-version | ||
* @param {module:engine/model/operation/operation~Operation} operation | ||
*/ | ||
throw new CKEditorError( 'model-document-applyoperation-wrong-version', this, { operation } ); | ||
} | ||
}, { priority: 'highest' } ); | ||
// Then, still before an operation is applied on model, buffer the change in differ. | ||
@@ -150,3 +124,2 @@ this.listenTo( model, 'applyOperation', ( evt, args ) => { | ||
if ( operation.isDocumentOperation ) { | ||
this.version++; | ||
this.history.addOperation( operation ); | ||
@@ -187,2 +160,21 @@ } | ||
/** | ||
* The document version. Every applied operation increases the version number. It is used to | ||
* ensure that operations are applied on a proper document version. | ||
* | ||
* This property is equal to {@link module:engine/model/history~History#version `model.Document#history#version`}. | ||
* | ||
* If the {@link module:engine/model/operation/operation~Operation#baseVersion base version} does not match the document version, | ||
* a {@link module:utils/ckeditorerror~CKEditorError model-document-applyoperation-wrong-version} error is thrown. | ||
* | ||
* @type {Number} | ||
*/ | ||
get version() { | ||
return this.history.version; | ||
} | ||
set version( version ) { | ||
this.history.version = version; | ||
} | ||
/** | ||
* The graveyard tree root. A document always has a graveyard root that stores removed nodes. | ||
@@ -189,0 +181,0 @@ * |
@@ -6,2 +6,4 @@ /** | ||
import { CKEditorError } from '@ckeditor/ckeditor5-utils'; | ||
/** | ||
@@ -22,4 +24,5 @@ * @module engine/model/history | ||
* | ||
* @protected | ||
* @member {Array.<module:engine/model/operation/operation~Operation>} module:engine/model/history~History#_operations | ||
* @private | ||
* @readonly | ||
* @type {Array.<module:engine/model/operation/operation~Operation>} | ||
*/ | ||
@@ -44,39 +47,160 @@ this._operations = []; | ||
* @private | ||
* @member {Set.<module:engine/model/operation/operation~Operation>} module:engine/model/history~History#_undoneOperations | ||
* @type {Set.<module:engine/model/operation/operation~Operation>} | ||
*/ | ||
this._undoneOperations = new Set(); | ||
/** | ||
* A map that allows retrieving the operations fast based on the given base version. | ||
* | ||
* @private | ||
* @type Map.<Number,Number> | ||
*/ | ||
this._baseVersionToOperationIndex = new Map(); | ||
/** | ||
* The history version. | ||
* | ||
* @private | ||
* @type {Number} | ||
*/ | ||
this._version = 0; | ||
/** | ||
* The gap pairs kept in the <from,to> format. | ||
* | ||
* Anytime the `history.version` is set to a version larger than `history.version + 1`, | ||
* a new <lastHistoryVersion, newHistoryVersion> entry is added to the map. | ||
* | ||
* @private | ||
* @type Map.<number,number> | ||
*/ | ||
this._gaps = new Map(); | ||
} | ||
/** | ||
* Adds an operation to the history. | ||
* The version of the last operation in the history. | ||
* | ||
* The history version is incremented automatically when a new operation is added to the history. | ||
* Setting the version manually should be done only in rare circumstances when a gap is planned | ||
* between history versions. When doing so, a gap will be created and the history will accept adding | ||
* an operation with base version equal to the new history version. | ||
* | ||
* @type {Number} | ||
*/ | ||
get version() { | ||
return this._version; | ||
} | ||
set version( version ) { | ||
// Store a gap if there are some operations already in the history and the | ||
// new version does not increment the latest one. | ||
if ( this._operations.length && version > this._version + 1 ) { | ||
this._gaps.set( this._version, version ); | ||
} | ||
this._version = version; | ||
} | ||
/** | ||
* The last history operation. | ||
* | ||
* @readonly | ||
* @type {module:engine/model/operation/operation~Operation|undefined} | ||
*/ | ||
get lastOperation() { | ||
return this._operations[ this._operations.length - 1 ]; | ||
} | ||
/** | ||
* Adds an operation to the history and increments the history version. | ||
* | ||
* The operation's base version should be equal to the history version. Otherwise an error is thrown. | ||
* | ||
* @param {module:engine/model/operation/operation~Operation} operation Operation to add. | ||
*/ | ||
addOperation( operation ) { | ||
if ( this._operations.includes( operation ) ) { | ||
return; | ||
if ( operation.baseVersion !== this.version ) { | ||
/** | ||
* Only operations with matching versions can be added to the history. | ||
* | ||
* @error model-document-history-addoperation-incorrect-version | ||
* @param {Object} errorData The operation and the current document history version. | ||
*/ | ||
throw new CKEditorError( 'model-document-history-addoperation-incorrect-version', this, { | ||
operation, | ||
historyVersion: this.version | ||
} ); | ||
} | ||
this._operations.push( operation ); | ||
this._version++; | ||
this._baseVersionToOperationIndex.set( operation.baseVersion, this._operations.length - 1 ); | ||
} | ||
/** | ||
* Returns operations added to the history. | ||
* Returns operations from the given range of operation base versions that were added to the history. | ||
* | ||
* @param {Number} [from=Number.NEGATIVE_INFINITY] Base version from which operations should be returned (inclusive). | ||
* Defaults to `Number.NEGATIVE_INFINITY`, which means that operations from the first one will be returned. | ||
* @param {Number} [to=Number.POSITIVE_INFINITY] Base version up to which operations should be returned (exclusive). | ||
* Defaults to `Number.POSITIVE_INFINITY` which means that operations up to the last one will be returned. | ||
* @returns {Array.<module:engine/model/operation/operation~Operation>} Operations added to the history. | ||
* Note that there may be gaps in operations base versions. | ||
* | ||
* @param {Number} [fromBaseVersion] Base version from which operations should be returned (inclusive). | ||
* @param {Number} [toBaseVersion] Base version up to which operations should be returned (exclusive). | ||
* @returns {Array.<module:engine/model/operation/operation~Operation>} History operations for the given range, in chronological order. | ||
*/ | ||
getOperations( from = Number.NEGATIVE_INFINITY, to = Number.POSITIVE_INFINITY ) { | ||
const operations = []; | ||
getOperations( fromBaseVersion, toBaseVersion = this.version ) { | ||
// When there is no operation in the history, return an empty array. | ||
// After that we can be sure that `firstOperation`, `lastOperation` are not nullish. | ||
if ( !this._operations.length ) { | ||
return []; | ||
} | ||
for ( const operation of this._operations ) { | ||
if ( operation.baseVersion >= from && operation.baseVersion < to ) { | ||
operations.push( operation ); | ||
const firstOperation = this._operations[ 0 ]; | ||
if ( fromBaseVersion === undefined ) { | ||
fromBaseVersion = firstOperation.baseVersion; | ||
} | ||
// Change exclusive `toBaseVersion` to inclusive, so it will refer to the actual index. | ||
// Thanks to that mapping from base versions to operation indexes are possible. | ||
let inclusiveTo = toBaseVersion - 1; | ||
// Check if "from" or "to" point to a gap between versions. | ||
// If yes, then change the incorrect position to the proper side of the gap. | ||
// Thanks to it, it will be possible to get index of the operation. | ||
for ( const [ gapFrom, gapTo ] of this._gaps ) { | ||
if ( fromBaseVersion > gapFrom && fromBaseVersion < gapTo ) { | ||
fromBaseVersion = gapTo; | ||
} | ||
if ( inclusiveTo > gapFrom && inclusiveTo < gapTo ) { | ||
inclusiveTo = gapFrom - 1; | ||
} | ||
} | ||
return operations; | ||
// If the whole range is outside of the operation versions, then return an empty array. | ||
if ( inclusiveTo < firstOperation.baseVersion || fromBaseVersion > this.lastOperation.baseVersion ) { | ||
return []; | ||
} | ||
let fromIndex = this._baseVersionToOperationIndex.get( fromBaseVersion ); | ||
// If the range starts before the first operation, then use the first operation as the range's start. | ||
if ( fromIndex === undefined ) { | ||
fromIndex = 0; | ||
} | ||
let toIndex = this._baseVersionToOperationIndex.get( inclusiveTo ); | ||
// If the range ends after the last operation, then use the last operation as the range's end. | ||
if ( toIndex === undefined ) { | ||
toIndex = this._operations.length - 1; | ||
} | ||
// Return the part of the history operations based on the calculated start index and end index. | ||
return this._operations.slice( | ||
fromIndex, | ||
// The `toIndex` should be included in the returned operations, so add `1`. | ||
toIndex + 1 | ||
); | ||
} | ||
@@ -92,7 +216,9 @@ | ||
getOperation( baseVersion ) { | ||
for ( const operation of this._operations ) { | ||
if ( operation.baseVersion == baseVersion ) { | ||
return operation; | ||
} | ||
const operationIndex = this._baseVersionToOperationIndex.get( baseVersion ); | ||
if ( operationIndex === undefined ) { | ||
return; | ||
} | ||
return this._operations[ operationIndex ]; | ||
} | ||
@@ -142,2 +268,14 @@ | ||
} | ||
/** | ||
* Resets the history of operations. | ||
*/ | ||
reset() { | ||
this._version = 0; | ||
this._undoPairs = new Map(); | ||
this._operations = []; | ||
this._undoneOperations = new Set(); | ||
this._gaps = new Map(); | ||
this._baseVersionToOperationIndex = new Map(); | ||
} | ||
} |
@@ -528,3 +528,3 @@ /** | ||
* | ||
* Note that this option works only for block objects. Inline objects are inserted into text and do not split blocks. | ||
* Note that this option only works for block objects. Inline objects are inserted into text and do not split blocks. | ||
* @param {'on'|'after'} [options.setSelection] An option that, when set, moves the | ||
@@ -1018,3 +1018,3 @@ * {@link module:engine/model/document~Document#selection document selection} after inserting the object. | ||
/** | ||
* Event fired when {@link #insertObject} method is called. | ||
* Event fired when the {@link #insertObject} method is called. | ||
* | ||
@@ -1021,0 +1021,0 @@ * The {@link #insertObject default action of that method} is implemented as a |
@@ -24,3 +24,3 @@ /** | ||
// This function is only exposed to be used by {@link module:widget/utils#findOptimalInsertionRange findOptimalInsertionRange()} | ||
// in `widget` package and inside `engine` package. | ||
// in the `widget` package and inside the `engine` package. | ||
// | ||
@@ -31,6 +31,6 @@ // @private | ||
// @param {module:engine/model/model~Model} model Model instance. | ||
// @param {'auto'|'before'|'after'} [place='auto'] Place where to look for optimal insertion range. | ||
// Default value `auto` will determine itself the best position for insertion. | ||
// Value `before` will try to find a position before selection. | ||
// Value `after` will try to find a position after selection. | ||
// @param {'auto'|'before'|'after'} [place='auto'] The place where to look for optimal insertion range. | ||
// The default `auto` value will determine itself the best position for insertion. | ||
// The `before` value will try to find a position before selection. | ||
// The `after` value will try to find a position after selection. | ||
// @returns {module:engine/model/range~Range} The optimal range. | ||
@@ -37,0 +37,0 @@ export function findOptimalInsertionRange( selection, model, place = 'auto' ) { |
@@ -132,5 +132,5 @@ /** | ||
// @param {module:engine/model/writer~Writer} writer An instance of the model writer. | ||
// @param {module:engine/model/element~Element} contextElement An element to set attributes on. | ||
// @param {'on'|'after'} place Place where selection should be set in relation to `contextElement` element. | ||
// Value `on` will set selection on passed `contextElement`. Value `after` will set selection after `contextElement`. | ||
// @param {module:engine/model/element~Element} contextElement An element to set the attributes on. | ||
// @param {'on'|'after'} place The place where selection should be set in relation to the `contextElement` element. | ||
// Value `on` will set selection on the passed `contextElement`. Value `after` will set selection after `contextElement`. | ||
// @param {Object} attributes Attributes keys and values to set on a paragraph that this function can create when | ||
@@ -165,5 +165,5 @@ // `place` parameter is equal to `after` but there is no element with `$text` node to set selection in. | ||
/** | ||
* Unsupported `options.setSelection` parameter was passed | ||
* The unsupported `options.setSelection` parameter was passed | ||
* to the {@link module:engine/model/utils/insertobject insertObject()} function. | ||
* Check {@link module:engine/model/utils/insertobject insertObject()} API documentation for allowed | ||
* Check the {@link module:engine/model/utils/insertobject insertObject()} API documentation for allowed | ||
* `options.setSelection` parameter values. | ||
@@ -170,0 +170,0 @@ * |
@@ -19,3 +19,3 @@ /** | ||
* Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the | ||
* {@link module:engine/view/view~View} this event is available by default. | ||
* {@link module:engine/view/view~View}, this event is available by default. | ||
* | ||
@@ -64,3 +64,3 @@ * @extends module:engine/view/observer/observer~Observer | ||
* Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the | ||
* {@link module:engine/view/view~View} this event is available by default. | ||
* {@link module:engine/view/view~View}, this event is available by default. | ||
* | ||
@@ -67,0 +67,0 @@ * @event module:engine/view/document~Document#event:tab |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1829761
43459