@ckeditor/ckeditor5-engine
Advanced tools
Comparing version 37.0.1 to 37.1.0
{ | ||
"name": "@ckeditor/ckeditor5-engine", | ||
"version": "37.0.1", | ||
"version": "37.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": "^37.0.1", | ||
"@ckeditor/ckeditor5-utils": "^37.1.0", | ||
"lodash-es": "^4.17.15" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-basic-styles": "^37.0.1", | ||
"@ckeditor/ckeditor5-block-quote": "^37.0.1", | ||
"@ckeditor/ckeditor5-clipboard": "^37.0.1", | ||
"@ckeditor/ckeditor5-cloud-services": "^37.0.1", | ||
"@ckeditor/ckeditor5-core": "^37.0.1", | ||
"@ckeditor/ckeditor5-editor-classic": "^37.0.1", | ||
"@ckeditor/ckeditor5-enter": "^37.0.1", | ||
"@ckeditor/ckeditor5-essentials": "^37.0.1", | ||
"@ckeditor/ckeditor5-heading": "^37.0.1", | ||
"@ckeditor/ckeditor5-image": "^37.0.1", | ||
"@ckeditor/ckeditor5-link": "^37.0.1", | ||
"@ckeditor/ckeditor5-list": "^37.0.1", | ||
"@ckeditor/ckeditor5-mention": "^37.0.1", | ||
"@ckeditor/ckeditor5-paragraph": "^37.0.1", | ||
"@ckeditor/ckeditor5-table": "^37.0.1", | ||
"@ckeditor/ckeditor5-theme-lark": "^37.0.1", | ||
"@ckeditor/ckeditor5-typing": "^37.0.1", | ||
"@ckeditor/ckeditor5-ui": "^37.0.1", | ||
"@ckeditor/ckeditor5-undo": "^37.0.1", | ||
"@ckeditor/ckeditor5-widget": "^37.0.1", | ||
"@ckeditor/ckeditor5-basic-styles": "^37.1.0", | ||
"@ckeditor/ckeditor5-block-quote": "^37.1.0", | ||
"@ckeditor/ckeditor5-clipboard": "^37.1.0", | ||
"@ckeditor/ckeditor5-cloud-services": "^37.1.0", | ||
"@ckeditor/ckeditor5-core": "^37.1.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^37.1.0", | ||
"@ckeditor/ckeditor5-enter": "^37.1.0", | ||
"@ckeditor/ckeditor5-essentials": "^37.1.0", | ||
"@ckeditor/ckeditor5-heading": "^37.1.0", | ||
"@ckeditor/ckeditor5-image": "^37.1.0", | ||
"@ckeditor/ckeditor5-link": "^37.1.0", | ||
"@ckeditor/ckeditor5-list": "^37.1.0", | ||
"@ckeditor/ckeditor5-mention": "^37.1.0", | ||
"@ckeditor/ckeditor5-paragraph": "^37.1.0", | ||
"@ckeditor/ckeditor5-table": "^37.1.0", | ||
"@ckeditor/ckeditor5-theme-lark": "^37.1.0", | ||
"@ckeditor/ckeditor5-typing": "^37.1.0", | ||
"@ckeditor/ckeditor5-ui": "^37.1.0", | ||
"@ckeditor/ckeditor5-undo": "^37.1.0", | ||
"@ckeditor/ckeditor5-widget": "^37.1.0", | ||
"typescript": "^4.8.4", | ||
@@ -52,0 +52,0 @@ "webpack": "^5.58.1", |
@@ -8,3 +8,3 @@ /** | ||
*/ | ||
import { CKEditorError, ObservableMixin } from '@ckeditor/ckeditor5-utils'; | ||
import { CKEditorError, ObservableMixin, env } from '@ckeditor/ckeditor5-utils'; | ||
import RootEditableElement from '../view/rooteditableelement'; | ||
@@ -16,2 +16,3 @@ import View from '../view/view'; | ||
import { convertSelectionChange } from '../conversion/upcasthelpers'; | ||
import { tryFixingRange } from '../model/utils/selection-post-fixer'; | ||
// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' ); | ||
@@ -64,2 +65,4 @@ /** | ||
this.listenTo(this.view.document, 'selectionChange', convertSelectionChange(this.model, this.mapper)); | ||
// Fix `beforeinput` target ranges so that they map to the valid model ranges. | ||
this.listenTo(this.view.document, 'beforeinput', fixTargetRanges(this.mapper, this.model.schema, this.view), { priority: 'high' }); | ||
// Attach default model converters. | ||
@@ -169,1 +172,24 @@ this.downcastDispatcher.on('insert:$text', insertText(), { priority: 'lowest' }); | ||
} | ||
/** | ||
* Checks whether the target ranges provided by the `beforeInput` event can be properly mapped to model ranges and fixes them if needed. | ||
* | ||
* This is using the same logic as the selection post-fixer. | ||
*/ | ||
function fixTargetRanges(mapper, schema, view) { | ||
return (evt, data) => { | ||
// The Renderer is disabled while composing on non-android browsers, so we can't be sure that target ranges | ||
// could be properly mapped to view and model because the DOM and view tree drifted apart. | ||
if (view.document.isComposing && !env.isAndroid) { | ||
return; | ||
} | ||
for (let i = 0; i < data.targetRanges.length; i++) { | ||
const viewRange = data.targetRanges[i]; | ||
const modelRange = mapper.toModelRange(viewRange); | ||
const correctedRange = tryFixingRange(modelRange, schema); | ||
if (!correctedRange || correctedRange.isEqual(modelRange)) { | ||
continue; | ||
} | ||
data.targetRanges[i] = mapper.toViewRange(correctedRange); | ||
} | ||
}; | ||
} |
@@ -140,3 +140,3 @@ /** | ||
/** | ||
* `Marker` is a continuous parts of model (like a range), is named and represent some kind of information about marked | ||
* `Marker` is a continuous part of model (like a range), is named and represent some kind of information about marked | ||
* part of model document. In contrary to {@link module:engine/model/node~Node nodes}, which are building blocks of | ||
@@ -143,0 +143,0 @@ * model document tree, markers are not stored directly in document tree but in |
@@ -217,3 +217,3 @@ /** | ||
/** | ||
* `Marker` is a continuous parts of model (like a range), is named and represent some kind of information about marked | ||
* `Marker` is a continuous part of model (like a range), is named and represent some kind of information about marked | ||
* part of model document. In contrary to {@link module:engine/model/node~Node nodes}, which are building blocks of | ||
@@ -220,0 +220,0 @@ * model document tree, markers are not stored directly in document tree but in |
@@ -171,3 +171,3 @@ /** | ||
// @if CK_DEBUG // throw err; | ||
/* istanbul ignore next */ | ||
/* istanbul ignore next -- @preserve */ | ||
CKEditorError.rethrowUnexpectedError(err, this); | ||
@@ -195,3 +195,3 @@ } | ||
// @if CK_DEBUG // throw err; | ||
/* istanbul ignore next */ | ||
/* istanbul ignore next -- @preserve */ | ||
CKEditorError.rethrowUnexpectedError(err, this); | ||
@@ -198,0 +198,0 @@ } |
@@ -365,9 +365,19 @@ /** | ||
* | ||
* **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective | ||
* this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details. | ||
* **Special case**: Selection ignores first and/or last blocks if nothing (from user perspective) is selected in them. | ||
* | ||
* ```xml | ||
* // Selection ends and the beginning of the last block. | ||
* <paragraph>[a</paragraph> | ||
* <paragraph>b</paragraph> | ||
* <paragraph>]c</paragraph> // this block will not be returned | ||
* <paragraph>]c</paragraph> // This block will not be returned | ||
* | ||
* // Selection begins at the end of the first block. | ||
* <paragraph>a[</paragraph> // This block will not be returned | ||
* <paragraph>b</paragraph> | ||
* <paragraph>c]</paragraph> | ||
* | ||
* // Selection begings at the end of the first block and ends at the beginning of the last block. | ||
* <paragraph>a[</paragraph> // This block will not be returned | ||
* <paragraph>b</paragraph> | ||
* <paragraph>]c</paragraph> // This block will not be returned | ||
* ``` | ||
@@ -374,0 +384,0 @@ */ |
@@ -560,9 +560,19 @@ /** | ||
* | ||
* **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective | ||
* this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details. | ||
* **Special case**: Selection ignores first and/or last blocks if nothing (from user perspective) is selected in them. | ||
* | ||
* ```xml | ||
* // Selection ends and the beginning of the last block. | ||
* <paragraph>[a</paragraph> | ||
* <paragraph>b</paragraph> | ||
* <paragraph>]c</paragraph> // this block will not be returned | ||
* <paragraph>]c</paragraph> // This block will not be returned | ||
* | ||
* // Selection begins at the end of the first block. | ||
* <paragraph>a[</paragraph> // This block will not be returned | ||
* <paragraph>b</paragraph> | ||
* <paragraph>c]</paragraph> | ||
* | ||
* // Selection begings at the end of the first block and ends at the beginning of the last block. | ||
* <paragraph>a[</paragraph> // This block will not be returned | ||
* <paragraph>b</paragraph> | ||
* <paragraph>]c</paragraph> // This block will not be returned | ||
* ``` | ||
@@ -575,3 +585,3 @@ */ | ||
const startBlock = getParentBlock(range.start, visited); | ||
if (startBlock && isTopBlockInRange(startBlock, range)) { | ||
if (isStartBlockSelected(startBlock, range)) { | ||
yield startBlock; | ||
@@ -586,4 +596,3 @@ } | ||
const endBlock = getParentBlock(range.end, visited); | ||
// #984. Don't return the end block if the range ends right at its beginning. | ||
if (endBlock && !range.end.isTouching(Position._createAt(endBlock, 0)) && isTopBlockInRange(endBlock, range)) { | ||
if (isEndBlockSelected(endBlock, range)) { | ||
yield endBlock; | ||
@@ -716,2 +725,58 @@ } | ||
/** | ||
* If a selection starts at the end of a block, that block is not returned as from user perspective this block wasn't selected. | ||
* See [#11585](https://github.com/ckeditor/ckeditor5/issues/11585) for more details. | ||
* | ||
* ```xml | ||
* <paragraph>a[</paragraph> // This block will not be returned | ||
* <paragraph>b</paragraph> | ||
* <paragraph>c]</paragraph> | ||
* ``` | ||
* | ||
* Collapsed selection is not affected by it: | ||
* | ||
* ```xml | ||
* <paragraph>a[]</paragraph> // This block will be returned | ||
* ``` | ||
*/ | ||
function isStartBlockSelected(startBlock, range) { | ||
if (!startBlock) { | ||
return false; | ||
} | ||
if (range.isCollapsed || startBlock.isEmpty) { | ||
return true; | ||
} | ||
if (range.start.isTouching(Position._createAt(startBlock, startBlock.maxOffset))) { | ||
return false; | ||
} | ||
return isTopBlockInRange(startBlock, range); | ||
} | ||
/** | ||
* If a selection ends at the beginning of a block, that block is not returned as from user perspective this block wasn't selected. | ||
* See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details. | ||
* | ||
* ```xml | ||
* <paragraph>[a</paragraph> | ||
* <paragraph>b</paragraph> | ||
* <paragraph>]c</paragraph> // this block will not be returned | ||
* ``` | ||
* | ||
* Collapsed selection is not affected by it: | ||
* | ||
* ```xml | ||
* <paragraph>[]a</paragraph> // this block will be returned | ||
* ``` | ||
*/ | ||
function isEndBlockSelected(endBlock, range) { | ||
if (!endBlock) { | ||
return false; | ||
} | ||
if (range.isCollapsed || endBlock.isEmpty) { | ||
return true; | ||
} | ||
if (range.end.isTouching(Position._createAt(endBlock, 0))) { | ||
return false; | ||
} | ||
return isTopBlockInRange(endBlock, range); | ||
} | ||
/** | ||
* Returns first ancestor block of a node. | ||
@@ -718,0 +783,0 @@ */ |
@@ -6,3 +6,3 @@ /** | ||
export default class TypeCheckable { | ||
/* istanbul ignore next */ | ||
/* istanbul ignore next -- @preserve */ | ||
is() { | ||
@@ -9,0 +9,0 @@ // There are a lot of overloads above. |
@@ -165,3 +165,3 @@ /** | ||
} | ||
/* istanbul ignore else */ | ||
/* istanbul ignore else -- @preserve */ | ||
if (newRange) { | ||
@@ -257,3 +257,3 @@ if (selection instanceof DocumentSelection) { | ||
this._lastNode = node; | ||
/* istanbul ignore if */ | ||
/* istanbul ignore if -- @preserve */ | ||
if (this.position.parent != node || !this.position.isAtEnd) { | ||
@@ -391,3 +391,3 @@ // Algorithm's correctness check. We should never end up here but it's good to know that we did. | ||
_appendToFragment(node) { | ||
/* istanbul ignore if */ | ||
/* istanbul ignore if -- @preserve */ | ||
if (!this.schema.checkChild(this.position, node)) { | ||
@@ -523,3 +523,3 @@ // Algorithm's correctness check. We should never end up here but it's good to know that we did. | ||
mergePosRight.stickiness = 'toNext'; | ||
/* istanbul ignore if */ | ||
/* istanbul ignore if -- @preserve */ | ||
if (!this.position.isEqual(mergePosRight)) { | ||
@@ -526,0 +526,0 @@ // Algorithm's correctness check. We should never end up here but it's good to know that we did. |
@@ -7,2 +7,3 @@ /** | ||
import type Model from '../model'; | ||
import type Schema from '../schema'; | ||
/** | ||
@@ -61,2 +62,10 @@ * Injects selection post-fixer to the model. | ||
/** | ||
* Tries fixing a range if it's incorrect. | ||
* | ||
* **Note:** This helper is used by the selection post-fixer and to fix the `beforeinput` target ranges. | ||
* | ||
* @returns Returns fixed range or null if range is valid. | ||
*/ | ||
export declare function tryFixingRange(range: Range, schema: Schema): Range | null; | ||
/** | ||
* Returns a minimal non-intersecting array of ranges without duplicates. | ||
@@ -63,0 +72,0 @@ * |
@@ -100,5 +100,7 @@ /** | ||
* | ||
* **Note:** This helper is used by the selection post-fixer and to fix the `beforeinput` target ranges. | ||
* | ||
* @returns Returns fixed range or null if range is valid. | ||
*/ | ||
function tryFixingRange(range, schema) { | ||
export function tryFixingRange(range, schema) { | ||
if (range.isCollapsed) { | ||
@@ -105,0 +107,0 @@ return tryFixingCollapsedRange(range, schema); |
@@ -426,3 +426,3 @@ /** | ||
// We don't need `getter` here because patterns for classes are always normalized to `[ className, true ]`. | ||
return matchPatterns(patterns, element.getClassNames(), /* istanbul ignore next */ () => { }); | ||
return matchPatterns(patterns, element.getClassNames(), /* istanbul ignore next -- @preserve */ () => { }); | ||
} | ||
@@ -429,0 +429,0 @@ /** |
@@ -80,3 +80,3 @@ /** | ||
// @if CK_DEBUG // throw err; | ||
/* istanbul ignore next */ | ||
/* istanbul ignore next -- @preserve */ | ||
CKEditorError.rethrowUnexpectedError(err, this); | ||
@@ -83,0 +83,0 @@ } |
@@ -119,3 +119,3 @@ /** | ||
} | ||
/* istanbul ignore next */ | ||
/* istanbul ignore next -- @preserve */ | ||
_reportInfiniteLoop() { | ||
@@ -122,0 +122,0 @@ // @if CK_DEBUG // throw new Error( |
@@ -212,7 +212,4 @@ /** | ||
return 'after'; | ||
/* istanbul ignore next */ | ||
case 'same': | ||
// Already covered by `this.isEqual` above. Added so TypeScript can infer `result` as number in `default` case. | ||
return 'same'; | ||
default: | ||
// Cast to number to avoid having 'same' as a type of `result`. | ||
return thisPath[result] < otherPath[result] ? 'before' : 'after'; | ||
@@ -219,0 +216,0 @@ } |
@@ -9,3 +9,3 @@ /** | ||
export default class TypeCheckable { | ||
/* istanbul ignore next */ | ||
/* istanbul ignore next -- @preserve */ | ||
is() { | ||
@@ -12,0 +12,0 @@ // There are a lot of overloads above. |
@@ -400,3 +400,3 @@ /** | ||
// @if CK_DEBUG // throw err; | ||
/* istanbul ignore next */ | ||
/* istanbul ignore next -- @preserve */ | ||
CKEditorError.rethrowUnexpectedError(err, this); | ||
@@ -403,0 +403,0 @@ } |
Sorry, the diff of this file is too big to display
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
2813326
62414