@ckeditor/ckeditor5-utils 47.4.0 → 47.5.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +42 -47
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/dom/rect.js +27 -45
- package/src/dom/scroll.d.ts +7 -1
- package/src/dom/scroll.js +10 -2
- package/src/version.d.ts +1 -1
- package/src/version.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-utils",
|
|
3
|
-
"version": "47.
|
|
3
|
+
"version": "47.5.0-alpha.0",
|
|
4
4
|
"description": "Miscellaneous utilities used by CKEditor 5.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ckeditor",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"type": "module",
|
|
13
13
|
"main": "src/index.js",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@ckeditor/ckeditor5-ui": "47.
|
|
15
|
+
"@ckeditor/ckeditor5-ui": "47.5.0-alpha.0",
|
|
16
16
|
"es-toolkit": "1.39.5"
|
|
17
17
|
},
|
|
18
18
|
"author": "CKSource (http://cksource.com/)",
|
|
@@ -51,4 +51,4 @@
|
|
|
51
51
|
},
|
|
52
52
|
"./package.json": "./package.json"
|
|
53
53
|
}
|
|
54
|
-
}
|
|
54
|
+
}
|
package/src/dom/rect.js
CHANGED
|
@@ -11,7 +11,8 @@ import { getBorderWidths } from './getborderwidths.js';
|
|
|
11
11
|
import { isText } from './istext.js';
|
|
12
12
|
import { getPositionedAncestor } from './getpositionedancestor.js';
|
|
13
13
|
import { global } from './global.js';
|
|
14
|
-
const
|
|
14
|
+
const RECT_PROPERTIES = ['top', 'right', 'bottom', 'left', 'width', 'height'];
|
|
15
|
+
const POSITIONING_VALUES = new Set(['relative', 'absolute', 'fixed', 'sticky']);
|
|
15
16
|
/**
|
|
16
17
|
* A helper class representing a `ClientRect` object, e.g. value returned by
|
|
17
18
|
* the native `object.getBoundingClientRect()` method. Provides a set of methods
|
|
@@ -236,50 +237,21 @@ export class Rect {
|
|
|
236
237
|
}
|
|
237
238
|
let child = source;
|
|
238
239
|
let parent = source.parentNode || source.commonAncestorContainer;
|
|
239
|
-
let
|
|
240
|
+
let lastPositionedChildElement;
|
|
240
241
|
// Check the ancestors all the way up to the <body>.
|
|
241
242
|
while (parent && !isBody(parent)) {
|
|
242
|
-
const
|
|
243
|
-
if (
|
|
244
|
-
|
|
243
|
+
const isNonClippingParent = getElementOverflow(parent) === 'visible';
|
|
244
|
+
if (isPositioned(child)) {
|
|
245
|
+
lastPositionedChildElement = child;
|
|
245
246
|
}
|
|
246
|
-
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
// condition: isParentOverflowVisible
|
|
252
|
-
// +---------------------------+
|
|
253
|
-
// | #parent |
|
|
254
|
-
// | (overflow: visible) |
|
|
255
|
-
// | +-----------+---------------+
|
|
256
|
-
// | | child |
|
|
257
|
-
// | +-----------+---------------+
|
|
258
|
-
// +---------------------------+
|
|
247
|
+
// 1. If a parent has overflow: visible, it can be safely skipped in consideration for any parent-child configuration.
|
|
248
|
+
// 2. If a parent has any other overflow (it clips), for the actual clipping to happen the following must be true:
|
|
249
|
+
// * the last positioned child must have `position: absolute`,
|
|
250
|
+
// * the parent must have a position other than `position: static`.
|
|
259
251
|
//
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
// | (position: relative;) |
|
|
264
|
-
// | (overflow: visible;) |
|
|
265
|
-
// | +-----------+---------------+
|
|
266
|
-
// | | child |
|
|
267
|
-
// | | (position: absolute;) |
|
|
268
|
-
// | +-----------+---------------+
|
|
269
|
-
// +---------------------------+
|
|
270
|
-
//
|
|
271
|
-
// condition: absolutelyPositionedChildElement && parentElementPosition !== 'relative'
|
|
272
|
-
// +---------------------------+
|
|
273
|
-
// | parent |
|
|
274
|
-
// | (position: static;) |
|
|
275
|
-
// | +-----------+---------------+
|
|
276
|
-
// | | child |
|
|
277
|
-
// | | (position: absolute;) |
|
|
278
|
-
// | +-----------+---------------+
|
|
279
|
-
// +---------------------------+
|
|
280
|
-
if (isParentOverflowVisible ||
|
|
281
|
-
absolutelyPositionedChildElement && ((parentElementPosition === 'relative' && isParentOverflowVisible) ||
|
|
282
|
-
parentElementPosition !== 'relative')) {
|
|
252
|
+
// https://github.com/ckeditor/ckeditor5/issues/14107.
|
|
253
|
+
if (isNonClippingParent ||
|
|
254
|
+
(lastPositionedChildElement && getElementPosition(lastPositionedChildElement) === 'absolute' && !isPositioned(parent))) {
|
|
283
255
|
child = parent;
|
|
284
256
|
parent = parent.parentNode;
|
|
285
257
|
continue;
|
|
@@ -310,7 +282,7 @@ export class Rect {
|
|
|
310
282
|
* @returns `true` when Rects are equal. `false` otherwise.
|
|
311
283
|
*/
|
|
312
284
|
isEqual(anotherRect) {
|
|
313
|
-
for (const prop of
|
|
285
|
+
for (const prop of RECT_PROPERTIES) {
|
|
314
286
|
if (this[prop] !== anotherRect[prop]) {
|
|
315
287
|
return false;
|
|
316
288
|
}
|
|
@@ -392,7 +364,11 @@ export class Rect {
|
|
|
392
364
|
const clientRects = Array.from(range.getClientRects());
|
|
393
365
|
if (clientRects.length) {
|
|
394
366
|
for (const rect of clientRects) {
|
|
395
|
-
|
|
367
|
+
const r = new Rect(rect);
|
|
368
|
+
// Point the rect source to the DOM range instead of of the DOM client rect to allow proper clipping,
|
|
369
|
+
// in `Rect#getVisible()` method.
|
|
370
|
+
r._source = range;
|
|
371
|
+
rects.push(r);
|
|
396
372
|
}
|
|
397
373
|
}
|
|
398
374
|
// If there's no client rects for the Range, use parent container's bounding rect
|
|
@@ -446,7 +422,7 @@ export class Rect {
|
|
|
446
422
|
* Acquires all the rect properties from the passed source.
|
|
447
423
|
*/
|
|
448
424
|
function copyRectProperties(rect, source) {
|
|
449
|
-
for (const p of
|
|
425
|
+
for (const p of RECT_PROPERTIES) {
|
|
450
426
|
rect[p] = source[p];
|
|
451
427
|
}
|
|
452
428
|
}
|
|
@@ -471,7 +447,7 @@ function isDomElement(value) {
|
|
|
471
447
|
* Returns the value of the `position` style of an `HTMLElement`.
|
|
472
448
|
*/
|
|
473
449
|
function getElementPosition(element) {
|
|
474
|
-
return element
|
|
450
|
+
return element.ownerDocument.defaultView.getComputedStyle(element).position;
|
|
475
451
|
}
|
|
476
452
|
/**
|
|
477
453
|
* Returns the value of the `overflow` style of an `HTMLElement` or a `Range`.
|
|
@@ -479,6 +455,12 @@ function getElementPosition(element) {
|
|
|
479
455
|
function getElementOverflow(element) {
|
|
480
456
|
return element instanceof HTMLElement ? element.ownerDocument.defaultView.getComputedStyle(element).overflow : 'visible';
|
|
481
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* Checks if the given node is positioned in any other way than `position: static`.
|
|
460
|
+
*/
|
|
461
|
+
function isPositioned(node) {
|
|
462
|
+
return node instanceof HTMLElement && POSITIONING_VALUES.has(getElementPosition(node));
|
|
463
|
+
}
|
|
482
464
|
/**
|
|
483
465
|
* For a given absolute Rect coordinates object and a positioned element ancestor, it updates its
|
|
484
466
|
* coordinates that make up for the position and the scroll of the ancestor.
|
package/src/dom/scroll.d.ts
CHANGED
|
@@ -68,5 +68,11 @@ export declare function scrollViewportToShowTarget<T extends boolean, U extends
|
|
|
68
68
|
* to be maintained while scrolling.
|
|
69
69
|
* @param limiterElement The outermost ancestor that should be scrolled. If specified, it can prevent
|
|
70
70
|
* scrolling the whole page.
|
|
71
|
+
* @param alignToTop When set `true`, the function will make sure the `target` is scrolled up
|
|
72
|
+
* to the top boundary of the scrollable ancestors if scrolled up. When not set (default), the `target`
|
|
73
|
+
* will be revealed by scrolling as little as possible. This option will not affect target elements that must be
|
|
74
|
+
* scrolled down because they will appear at the top of the boundary anyway.
|
|
75
|
+
* @param forceScroll When set `true`, the `target` will be aligned to the top of scrollable ancestors
|
|
76
|
+
* whether it is already visible or not. This option will only work when `alignToTop` is `true`
|
|
71
77
|
*/
|
|
72
|
-
export declare function scrollAncestorsToShowTarget(target: HTMLElement | Range, ancestorOffset?: number, limiterElement?: HTMLElement): void;
|
|
78
|
+
export declare function scrollAncestorsToShowTarget(target: HTMLElement | Range, ancestorOffset?: number, limiterElement?: HTMLElement, alignToTop?: boolean, forceScroll?: true): void;
|
package/src/dom/scroll.js
CHANGED
|
@@ -141,14 +141,22 @@ export function scrollViewportToShowTarget({ target, viewportOffset = 0, ancesto
|
|
|
141
141
|
* to be maintained while scrolling.
|
|
142
142
|
* @param limiterElement The outermost ancestor that should be scrolled. If specified, it can prevent
|
|
143
143
|
* scrolling the whole page.
|
|
144
|
+
* @param alignToTop When set `true`, the function will make sure the `target` is scrolled up
|
|
145
|
+
* to the top boundary of the scrollable ancestors if scrolled up. When not set (default), the `target`
|
|
146
|
+
* will be revealed by scrolling as little as possible. This option will not affect target elements that must be
|
|
147
|
+
* scrolled down because they will appear at the top of the boundary anyway.
|
|
148
|
+
* @param forceScroll When set `true`, the `target` will be aligned to the top of scrollable ancestors
|
|
149
|
+
* whether it is already visible or not. This option will only work when `alignToTop` is `true`
|
|
144
150
|
*/
|
|
145
|
-
export function scrollAncestorsToShowTarget(target, ancestorOffset, limiterElement) {
|
|
151
|
+
export function scrollAncestorsToShowTarget(target, ancestorOffset, limiterElement, alignToTop, forceScroll) {
|
|
146
152
|
const targetParent = getParentElement(target);
|
|
147
153
|
scrollAncestorsToShowRect({
|
|
148
154
|
parent: targetParent,
|
|
149
155
|
getRect: () => new Rect(target),
|
|
150
156
|
ancestorOffset,
|
|
151
|
-
limiterElement
|
|
157
|
+
limiterElement,
|
|
158
|
+
alignToTop,
|
|
159
|
+
forceScroll
|
|
152
160
|
});
|
|
153
161
|
}
|
|
154
162
|
/**
|
package/src/version.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
4
|
*/
|
|
5
|
-
export declare const version = "47.
|
|
5
|
+
export declare const version = "47.5.0-alpha.0";
|
|
6
6
|
export declare const releaseDate: Date;
|
|
7
7
|
declare global {
|
|
8
8
|
var CKEDITOR_VERSION: string;
|
package/src/version.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* @module utils/version
|
|
7
7
|
*/
|
|
8
8
|
import { CKEditorError } from './ckeditorerror.js';
|
|
9
|
-
export const version = '47.
|
|
9
|
+
export const version = '47.5.0-alpha.0';
|
|
10
10
|
// The second argument is not a month. It is `monthIndex` and starts from `0`.
|
|
11
|
-
export const releaseDate = new Date(2026,
|
|
11
|
+
export const releaseDate = new Date(2026, 1, 4);
|
|
12
12
|
/* istanbul ignore next -- @preserve */
|
|
13
13
|
if (globalThis.CKEDITOR_VERSION) {
|
|
14
14
|
/**
|