Skip to content

Commit f7ec559

Browse files
committed
Merge branch 'master' into ck/18710
2 parents d707164 + e4bed9d commit f7ec559

File tree

43 files changed

+674
-442
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+674
-442
lines changed

LICENSE.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,33 @@ Where not otherwise indicated, all CKEditor content is authored by CKSource engi
2121
The following libraries are included in CKEditor under the [MIT license](https://opensource.org/licenses/MIT):
2222

2323
* @types/color-convert - Copyright (c) DefinitelyTyped.
24-
* @types/marked - Copyright (c) DefinitelyTyped.
25-
* @types/turndown - Copyright (c) DefinitelyTyped.
2624
* blurhash - Copyright (c) Wolt Enterprises.
2725
* color-convert - Copyright (c) 2011–2016 Heather Arthur <[email protected]>, copyright (c) 2016–2021 Josh Junon <[email protected]>.
2826
* color-parse - Copyright (c) 2015 Dmitry Ivanov.
2927
* emojibase-data - Copyright (c) 2017-2019 Miles Johnson.
3028
* es-toolkit - Copyright (c) 2024 Viva Republica, Inc.
3129
* fuzzysort - Copyright (c) 2018 Stephen Kamenar.
3230
* is-emoji-supported - Copyright (c) 2016-2020 Koala Interactive, Inc.
33-
* marked - Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/), Copyright (c) 2011–2018, Christopher Jeffrey (https://github.com/chjj/).
34-
* turndown - Copyright (c) 2017 Dom Christie.
35-
* turndown-plugin-gfm - Copyright (c) 2017 Dom Christie.
3631
* vanilla-colorful - Copyright (c) 2020 Serhii Kulykov <[email protected]>.
3732
* Regular Expression for URL validation - Copyright (c) 2010-2018 Diego Perini.
33+
* @types/hast - Copyright (c) Microsoft Corporation.
34+
* hast-util-to-html - Copyright (c) Titus Wormer <[email protected]>
35+
* hast-util-to-mdast - Copyright (c) Titus Wormer <[email protected]> and Copyright (c) Seth Vincent <[email protected]>
36+
* hastscript - Copyright (c) Titus Wormer <[email protected]>
37+
* rehype-remark - Copyright (c) Titus Wormer <[email protected]>
38+
* remark-breaks - Copyright (c) 2017 Titus Wormer <[email protected]>
39+
* remark-gfm - Copyright (c) Titus Wormer <[email protected]>
40+
* remark-parse - Copyright (c) 2014 Titus Wormer <[email protected]>
41+
* remark-rehype - Copyright (c) Titus Wormer <[email protected]>
42+
* remark-stringify - Copyright (c) 2014 Titus Wormer <[email protected]>
43+
* unified - Copyright (c) 2015 Titus Wormer <[email protected]>
44+
* unist-util-visit - Copyright (c) 2015 Titus Wormer <[email protected]>
45+
46+
The following libraries are included in CKEditor under the [ISC license](https://opensource.org/license/isc-license-txt):
47+
48+
* hast-util-from-dom - Copyright (c) Keith McKnight <[email protected]>
49+
* rehype-dom-parse - Copyright (c) 2018 Keith McKnight <[email protected]>
50+
* rehype-dom-stringify - Copyright (c) 2018 Keith McKnight <[email protected]>
3851

3952
Trademarks
4053
----------

docs/updating/update-to-46.md

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,61 @@ Released on xxx, 2025. ([See full release notes](https://github.com/ckeditor/cke
2020

2121
Below are the most important changes that require your attention when upgrading to CKEditor&nbsp;5 v46.0.0.
2222

23-
### New internal export names
23+
## Release highlights
2424

25-
As part of the transition to the New Installation Methods (NIM), we have standardized how public API elements are exposed in CKEditor&nbsp;5 and related packages. It now uses a unified export policy via index.ts, with clearer, standardized public API names introducing some breaking changes. Find all the changes and the new exports introduced with NIM in this {@link updating/nim-migration/migrating-exports dedicated migration guide}.
25+
CKEditor 5 v46.0.0 brings several major improvements and changes that enhance both the developer and end-user experience. This release includes significant API refinements, new features, and improvements to existing functionality.
26+
27+
### Line Height (⭐)
28+
29+
The new line height<!-- link --> feature allows you to adjust the vertical spacing between lines of text, improving readability and visual harmony in your documents. This premium feature lets you set consistent line spacing across paragraphs and text blocks to enhance document accessibility and maintain visual hierarchy in your content.
30+
31+
### Remove Format improvements
32+
33+
Unneeded styles on block elements, such as tables and images, and General HTML Support nodes and attributes are finally eliminated when you hit the {@link features/remove-format remove format} button. The feature now cleans what it should, leaving the document structure untouched.
34+
35+
### List markers styling
36+
37+
Working with {@link features/lists#list-styles styled lists} becomes more intuitive as list markers (bullets and numbers) now automatically inherit text styling properties. When you apply formatting to list text, the markers will match:
38+
39+
* Font size adjustments,
40+
* Text color changes,
41+
* Font weight modifications (bold, italic).
42+
43+
This improvement makes it easier to create visually consistent and professional-looking lists without additional configuration. This improvement also supports {@link features/multi-level-lists multi-level lists}.
44+
45+
**Important!** This behavior is enabled by default, which means you may experience content change when you load the content to the editor’s new version (for the better in our opinion). But if this is not something you expect, you can opt out<!-- link -->.
46+
47+
### Markdown processor dependency refresh
48+
49+
The {@loink features/markdown Markdown} feature dependencies have been modernized with a switch to the `unified` ecosystem, replacing the previous `marked` / `turndown` implementation. This change brings more consistent and symmetrical HTML ↔ Markdown conversion. By adopting `remark` and `rehype` from the same family of tools, we have created a more reliable and maintainable implementation that will better serve your document processing needs.
50+
51+
### Manual token refreshing
52+
53+
We have added a configuration property: `config.cloudServices.autoRefresh` to disable the automatic token refresh mechanism. When it is set to `false`, the token must be refreshed manually.
54+
55+
This property opens up the ability to implement custom token handling if a certain use case requires this.
56+
57+
### Unified exports & renames
58+
59+
This release is also about tidying up the rough edges that showed up after the big New Installation Method release (v42.0.0+). In cases where many helpers or methods from the framework’s APIs were used, some developers upgrading from v41-x to v42-x were greeted by the `does not provide an export named …` error. We addressed issues immediately as they were reported, but we knew it required a deeper are more comprehensive approach long-term.
60+
61+
We spent the last several months discussing how to prepare the CKEditor 5 API layer for the years to come. This release is the result of the rules we are introducing from now on:
62+
63+
* Every public API must be exported via the package’s `index.ts`.
64+
* Every internal API must be marked as such explicitly with `@internal`.
65+
* Exported names should follow a descriptive and unique naming pattern aligned with their purpose and context.
66+
* There should be no `export default` or `export * from` statements in source files.
67+
68+
This resulted in:
69+
70+
* Adding re-exports if they were missing.
71+
* Changing the names of items to be more descriptive and avoid collisions.
72+
* If there were internal methods that were already exported but not tagged, we decided to keep them exported but with the addition of the `_` prefix. This way we keep them available, but we would love to know how you are using them.
73+
* Also, we decided to use this occasion to clean up the code from `@deprecated` code that was stale for several years.
74+
75+
At the same time, we have developed an internal tooling to make sure guardrails are set for the future.
76+
77+
If your build throws errors after the update, search and replace the old names with the new ones from the update guide. **We have not changed the behavior of these APIs, just the names**.
2678

2779
<info-box info>
2880
Manually updating all these numerous imports could be time-consuming and error-prone. We recommend using the [tables with the changed import/export names](https://raw.githubusercontent.com/ckeditor/ckeditor5/refs/heads/master/docs/updating/nim-migration/migrating-exports.md) as context for tools such as Copilot, ChatGPT, or other LLM-based services that can automatically update all imports in your project.
@@ -47,7 +99,6 @@ To improve the out-of-the-box experience and accessibility, we are introducing o
4799
font-size: var(--ck-content-font-size);
48100
color: var(--ck-content-font-color);
49101
line-height: var(--ck-content-line-height);
50-
word-break: var(--ck-content-word-break);
51102
}
52103
```
53104

@@ -95,7 +146,7 @@ Example:
95146
}
96147
```
97148

98-
### Table-related CSS variables renamed for better clarity
149+
#### Table-related CSS variables renamed for better clarity
99150

100151
Some table-related CSS variables had improper naming with `-selector-` in their names, which was confusing and inconsistent. These variables have been renamed to use `-table-` for better clarity and consistency.
101152

@@ -119,6 +170,19 @@ Example:
119170
}
120171
```
121172

173+
### Comment threads improvements
174+
175+
We have introduced improvements to the `addCommandThread` command, which now supports creating comment threads on specified ranges. Additionally, it allows for creating a comment thread with an initial comment with the provided comment content.
176+
177+
#### Minor breaking change
178+
179+
The `AddCommandThreadCommand#isEnabled` property is no longer `false` when the current document selection is empty, as the command now allows for creating comment threads on custom ranges. If you previously used this property (for example, to provide a custom UI element), you should now use the observable `AddCommentThreadCommand#hasContent` property instead.
180+
181+
### Comments and suggestions annotations
182+
183+
We have introduced dedicated methods for an easier way to get specific annotations related to a comment or a suggestion and vice versa.
184+
185+
122186
### Major breaking changes in this release
123187

124188
### Minor breaking changes in this release

packages/ckeditor5-code-block/src/codeblockediting.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
type UpcastElementEvent,
2121
type UpcastTextEvent,
2222
type ModelElement,
23-
type SelectionChangeRangeEvent
23+
type ModelSelectionChangeRangeEvent
2424
} from 'ckeditor5/src/engine.js';
2525
import { ClipboardPipeline, type ClipboardContentInsertionEvent } from 'ckeditor5/src/clipboard.js';
2626

@@ -318,7 +318,7 @@ export class CodeBlockEditing extends Plugin {
318318

319319
let lastFocusedCodeBlock: ModelElement | null = null;
320320

321-
model.document.selection.on<SelectionChangeRangeEvent>( 'change:range', () => {
321+
model.document.selection.on<ModelSelectionChangeRangeEvent>( 'change:range', () => {
322322
const focusParent = model.document.selection.focus!.parent;
323323

324324
if ( !ui || lastFocusedCodeBlock === focusParent || !focusParent.is( 'element' ) ) {

packages/ckeditor5-engine/src/controller/editingcontroller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { type ModelTextProxy } from '../model/textproxy.js';
4040
import type { ModelDocumentChangeEvent } from '../model/document.js';
4141
import type { Marker } from '../model/markercollection.js';
4242
import type { StylesProcessor } from '../view/stylesmap.js';
43-
import type { ViewDocumentSelectionChangeEvent } from '../view/observer/selectionobserver.js';
43+
import type { ViewDocumentObserverSelectionChangeEvent } from '../view/observer/selectionobserver.js';
4444

4545
// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' );
4646

@@ -116,7 +116,7 @@ export class EditingController extends /* #__PURE__ */ ObservableMixin() {
116116
}, { priority: 'low' } );
117117

118118
// Convert selection from the view to the model when it changes in the view.
119-
this.listenTo<ViewDocumentSelectionChangeEvent>( this.view.document, 'selectionChange',
119+
this.listenTo<ViewDocumentObserverSelectionChangeEvent>( this.view.document, 'selectionChange',
120120
convertSelectionChange( this.model, this.mapper )
121121
);
122122

packages/ckeditor5-engine/src/index.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ export {
6969
type DowncastAddHighlightCallback,
7070
type DowncastHighlightDescriptorCreatorFunction,
7171
type DowncastRemoveHighlightCallback,
72-
type DowncastMarkerDataCreatorFunction
72+
type DowncastMarkerDataCreatorFunction,
73+
type DowncastAttributeCreatorFunction
7374
} from './conversion/downcasthelpers.js';
7475

7576
export type {
@@ -213,7 +214,6 @@ export type {
213214
ModelModifySelectionEvent,
214215
ModelCanEditAtEvent
215216
} from './model/model.js';
216-
export type { ModelSelectionChangeRangeEvent as SelectionChangeRangeEvent } from './model/selection.js';
217217

218218
// View.
219219
export { ViewDataTransfer, type ViewDropEffect, type ViewEffectAllowed } from './view/datatransfer.js';
@@ -247,7 +247,7 @@ export { ViewRawElement } from './view/rawelement.js';
247247
export { ViewUIElement } from './view/uielement.js';
248248
export { ViewDocumentFragment } from './view/documentfragment.js';
249249
export type { ViewElementDefinition, ViewElementObjectDefinition } from './view/elementdefinition.js';
250-
export { ViewDocumentSelection } from './view/documentselection.js';
250+
export { ViewDocumentSelection, type ViewDocumentSelectionChangeEvent } from './view/documentselection.js';
251251
export type { ViewItem } from './view/item.js';
252252
export { ViewNode, type ViewNodeChangeEvent } from './view/node.js';
253253
export {
@@ -298,7 +298,7 @@ export {
298298

299299
export {
300300
SelectionObserver,
301-
type ViewDocumentSelectionEventData
301+
type ViewDocumentObserverSelectionEventData
302302
} from './view/observer/selectionobserver.js';
303303

304304
export { CompositionObserver, type ViewDocumentCompositionEventData } from './view/observer/compositionobserver.js';
@@ -366,7 +366,10 @@ export type {
366366
} from './view/observer/touchobserver.js';
367367
export type { ViewDocumentTabEvent } from './view/observer/tabobserver.js';
368368
export type { ViewDocumentClickEvent } from './view/observer/clickobserver.js';
369-
export type { ViewDocumentSelectionChangeEvent, ViewDocumentSelectionChangeDoneEvent } from './view/observer/selectionobserver.js';
369+
export type {
370+
ViewDocumentObserverSelectionChangeEvent,
371+
ViewDocumentObserverSelectionChangeDoneEvent
372+
} from './view/observer/selectionobserver.js';
370373

371374
// View / Styles.
372375
export {

packages/ckeditor5-engine/src/view/observer/fakeselectionobserver.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import type { ViewDocumentArrowKeyEvent } from './arrowkeysobserver.js';
1212
import { ViewSelection } from '../selection.js';
1313
import { type EditingView } from '../view.js';
1414
import type {
15-
ViewDocumentSelectionChangeEvent,
16-
ViewDocumentSelectionChangeDoneEvent,
17-
ViewDocumentSelectionEventData
15+
ViewDocumentObserverSelectionChangeEvent,
16+
ViewDocumentObserverSelectionChangeDoneEvent,
17+
ViewDocumentObserverSelectionEventData
1818
} from './selectionobserver.js';
1919
import { keyCodes } from '@ckeditor/ckeditor5-utils';
2020
import { debounce, type DebouncedFunction } from 'es-toolkit/compat';
@@ -30,7 +30,7 @@ export class FakeSelectionObserver extends Observer {
3030
/**
3131
* Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.
3232
*/
33-
private readonly _fireSelectionChangeDoneDebounced: DebouncedFunction<( data: ViewDocumentSelectionEventData ) => void>;
33+
private readonly _fireSelectionChangeDoneDebounced: DebouncedFunction<( data: ViewDocumentObserverSelectionEventData ) => void>;
3434

3535
/**
3636
* Creates new FakeSelectionObserver instance.
@@ -39,7 +39,7 @@ export class FakeSelectionObserver extends Observer {
3939
super( view );
4040

4141
this._fireSelectionChangeDoneDebounced = debounce( data => {
42-
this.document.fire<ViewDocumentSelectionChangeDoneEvent>( 'selectionChangeDone', data );
42+
this.document.fire<ViewDocumentObserverSelectionChangeDoneEvent>( 'selectionChangeDone', data );
4343
}, 200 );
4444
}
4545

@@ -110,7 +110,7 @@ export class FakeSelectionObserver extends Observer {
110110
};
111111

112112
// Fire dummy selection change event.
113-
this.document.fire<ViewDocumentSelectionChangeEvent>( 'selectionChange', data );
113+
this.document.fire<ViewDocumentObserverSelectionChangeEvent>( 'selectionChange', data );
114114

115115
// Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.
116116
// This function is debounced what means that `selectionChangeDone` event will be fired only when

packages/ckeditor5-engine/src/view/observer/selectionobserver.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class SelectionObserver extends Observer {
6767
/**
6868
* Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.
6969
*/
70-
private readonly _fireSelectionChangeDoneDebounced: DebouncedFunction<( data: ViewDocumentSelectionEventData ) => void>;
70+
private readonly _fireSelectionChangeDoneDebounced: DebouncedFunction<( data: ViewDocumentObserverSelectionEventData ) => void>;
7171

7272
/**
7373
* When called, starts clearing the {@link #_loopbackCounter} counter in time intervals. When the number of selection
@@ -103,7 +103,7 @@ export class SelectionObserver extends Observer {
103103
this.domConverter = view.domConverter;
104104

105105
this._fireSelectionChangeDoneDebounced = debounce( data => {
106-
this.document.fire<ViewDocumentSelectionChangeDoneEvent>( 'selectionChangeDone', data );
106+
this.document.fire<ViewDocumentObserverSelectionChangeDoneEvent>( 'selectionChangeDone', data );
107107
}, 200 );
108108

109109
this._clearInfiniteLoopInterval = setInterval( () => this._clearInfiniteLoop(), 1000 );
@@ -339,7 +339,7 @@ export class SelectionObserver extends Observer {
339339
// Just re-render it, no need to fire any events, etc.
340340
this.view.forceRender();
341341
} else {
342-
const data: ViewDocumentSelectionEventData = {
342+
const data: ViewDocumentObserverSelectionEventData = {
343343
oldSelection: this.selection,
344344
newSelection: newViewSelection,
345345
domSelection
@@ -353,7 +353,7 @@ export class SelectionObserver extends Observer {
353353
// @if CK_DEBUG_TYPING // }
354354

355355
// Prepare data for new selection and fire appropriate events.
356-
this.document.fire<ViewDocumentSelectionChangeEvent>( 'selectionChange', data );
356+
this.document.fire<ViewDocumentObserverSelectionChangeEvent>( 'selectionChange', data );
357357

358358
// Call `#_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.
359359
// This function is debounced what means that `selectionChangeDone` event will be fired only when
@@ -372,9 +372,9 @@ export class SelectionObserver extends Observer {
372372
}
373373

374374
/**
375-
* The value of {@link ~ViewDocumentSelectionChangeEvent} and {@link ~ViewDocumentSelectionChangeDoneEvent} events.
375+
* The value of {@link ~ViewDocumentObserverSelectionChangeEvent} and {@link ~ViewDocumentObserverSelectionChangeDoneEvent} events.
376376
*/
377-
export type ViewDocumentSelectionEventData = {
377+
export type ViewDocumentObserverSelectionEventData = {
378378

379379
/**
380380
* Old View selection which is {@link module:engine/view/document~ViewDocument#selection}.
@@ -404,9 +404,9 @@ export type ViewDocumentSelectionEventData = {
404404
* @see module:engine/view/observer/selectionobserver~SelectionObserver
405405
* @eventName module:engine/view/document~ViewDocument#selectionChange
406406
*/
407-
export type ViewDocumentSelectionChangeEvent = {
407+
export type ViewDocumentObserverSelectionChangeEvent = {
408408
name: 'selectionChange';
409-
args: [ ViewDocumentSelectionEventData ];
409+
args: [ ViewDocumentObserverSelectionEventData ];
410410
};
411411

412412
/**
@@ -420,7 +420,7 @@ export type ViewDocumentSelectionChangeEvent = {
420420
* @see module:engine/view/observer/selectionobserver~SelectionObserver
421421
* @eventName module:engine/view/document~ViewDocument#selectionChangeDone
422422
*/
423-
export type ViewDocumentSelectionChangeDoneEvent = {
423+
export type ViewDocumentObserverSelectionChangeDoneEvent = {
424424
name: 'selectionChangeDone';
425-
args: [ ViewDocumentSelectionEventData ];
425+
args: [ ViewDocumentObserverSelectionEventData ];
426426
};

packages/ckeditor5-engine/src/view/view.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,15 @@ import {
4242
env,
4343
ObservableMixin,
4444
scrollViewportToShowTarget,
45-
type ObservableChangeEvent
45+
type ObservableChangeEvent,
46+
type IfTrue
4647
} from '@ckeditor/ckeditor5-utils';
4748
import { injectUiElementHandling } from './uielement.js';
4849
import { injectQuirksHandling } from './filler.js';
4950

5051
import { cloneDeep } from 'es-toolkit/compat';
5152

52-
type IfTrue<T> = T extends true ? true : never;
53+
// type IfTrue<T> = T extends true ? true : never;
5354
type DomRange = globalThis.Range;
5455

5556
/**

0 commit comments

Comments
 (0)