@ckeditor/ckeditor5-bookmark 0.0.0-nightly-next-20260106.0 → 0.0.0-nightly-20260107.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/build/bookmark.js +5 -0
- package/build/translations/af.js +1 -0
- package/build/translations/ar.js +1 -0
- package/build/translations/ast.js +1 -0
- package/build/translations/az.js +1 -0
- package/build/translations/be.js +1 -0
- package/build/translations/bg.js +1 -0
- package/build/translations/bn.js +1 -0
- package/build/translations/bs.js +1 -0
- package/build/translations/ca.js +1 -0
- package/build/translations/cs.js +1 -0
- package/build/translations/da.js +1 -0
- package/build/translations/de-ch.js +1 -0
- package/build/translations/de.js +1 -0
- package/build/translations/el.js +1 -0
- package/build/translations/en-au.js +1 -0
- package/build/translations/en-gb.js +1 -0
- package/build/translations/eo.js +1 -0
- package/build/translations/es-co.js +1 -0
- package/build/translations/es.js +1 -0
- package/build/translations/et.js +1 -0
- package/build/translations/eu.js +1 -0
- package/build/translations/fa.js +1 -0
- package/build/translations/fi.js +1 -0
- package/build/translations/fr.js +1 -0
- package/build/translations/gl.js +1 -0
- package/build/translations/gu.js +1 -0
- package/build/translations/he.js +1 -0
- package/build/translations/hi.js +1 -0
- package/build/translations/hr.js +1 -0
- package/build/translations/hu.js +1 -0
- package/build/translations/hy.js +1 -0
- package/build/translations/id.js +1 -0
- package/build/translations/it.js +1 -0
- package/build/translations/ja.js +1 -0
- package/build/translations/jv.js +1 -0
- package/build/translations/kk.js +1 -0
- package/build/translations/km.js +1 -0
- package/build/translations/kn.js +1 -0
- package/build/translations/ko.js +1 -0
- package/build/translations/ku.js +1 -0
- package/build/translations/lt.js +1 -0
- package/build/translations/lv.js +1 -0
- package/build/translations/ms.js +1 -0
- package/build/translations/nb.js +1 -0
- package/build/translations/ne.js +1 -0
- package/build/translations/nl.js +1 -0
- package/build/translations/no.js +1 -0
- package/build/translations/oc.js +1 -0
- package/build/translations/pl.js +1 -0
- package/build/translations/pt-br.js +1 -0
- package/build/translations/pt.js +1 -0
- package/build/translations/ro.js +1 -0
- package/build/translations/ru.js +1 -0
- package/build/translations/si.js +1 -0
- package/build/translations/sk.js +1 -0
- package/build/translations/sl.js +1 -0
- package/build/translations/sq.js +1 -0
- package/build/translations/sr-latn.js +1 -0
- package/build/translations/sr.js +1 -0
- package/build/translations/sv.js +1 -0
- package/build/translations/th.js +1 -0
- package/build/translations/ti.js +1 -0
- package/build/translations/tk.js +1 -0
- package/build/translations/tr.js +1 -0
- package/build/translations/tt.js +1 -0
- package/build/translations/ug.js +1 -0
- package/build/translations/uk.js +1 -0
- package/build/translations/ur.js +1 -0
- package/build/translations/uz.js +1 -0
- package/build/translations/vi.js +1 -0
- package/build/translations/zh-cn.js +1 -0
- package/build/translations/zh.js +1 -0
- package/ckeditor5-metadata.json +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +34 -25
- package/{dist → src}/augmentation.d.ts +0 -4
- package/src/augmentation.js +5 -0
- package/{dist → src}/bookmark.d.ts +2 -6
- package/src/bookmark.js +36 -0
- package/{dist → src}/bookmarkconfig.d.ts +0 -4
- package/src/bookmarkconfig.js +5 -0
- package/{dist → src}/bookmarkediting.d.ts +2 -6
- package/src/bookmarkediting.js +238 -0
- package/{dist → src}/bookmarkui.d.ts +3 -7
- package/src/bookmarkui.js +591 -0
- package/{dist → src}/index.d.ts +0 -4
- package/src/index.js +15 -0
- package/{dist → src}/insertbookmarkcommand.d.ts +1 -5
- package/src/insertbookmarkcommand.js +113 -0
- package/{dist → src}/ui/bookmarkformview.d.ts +2 -6
- package/src/ui/bookmarkformview.js +244 -0
- package/{dist → src}/updatebookmarkcommand.d.ts +1 -5
- package/src/updatebookmarkcommand.js +75 -0
- package/{dist → src}/utils.d.ts +0 -4
- package/src/utils.js +21 -0
package/package.json
CHANGED
|
@@ -1,54 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-bookmark",
|
|
3
|
-
"version": "0.0.0-nightly-
|
|
3
|
+
"version": "0.0.0-nightly-20260107.0",
|
|
4
4
|
"description": "Bookmark feature for CKEditor 5.",
|
|
5
|
-
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
|
-
"author": "CKSource (http://cksource.com/)",
|
|
7
|
-
"homepage": "https://ckeditor.com/ckeditor-5",
|
|
8
|
-
"bugs": "https://github.com/ckeditor/ckeditor5/issues",
|
|
9
|
-
"repository": {
|
|
10
|
-
"type": "git",
|
|
11
|
-
"url": "https://github.com/ckeditor/ckeditor5.git",
|
|
12
|
-
"directory": "packages/ckeditor5-bookmark"
|
|
13
|
-
},
|
|
14
5
|
"keywords": [
|
|
15
6
|
"ckeditor",
|
|
16
7
|
"ckeditor5",
|
|
17
8
|
"ckeditor 5",
|
|
18
9
|
"ckeditor5-feature",
|
|
19
|
-
"ckeditor5-plugin"
|
|
10
|
+
"ckeditor5-plugin",
|
|
11
|
+
"ckeditor5-dll"
|
|
20
12
|
],
|
|
21
13
|
"type": "module",
|
|
22
|
-
"main": "
|
|
14
|
+
"main": "src/index.js",
|
|
23
15
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"@ckeditor/ckeditor5-
|
|
26
|
-
"@ckeditor/ckeditor5-icons": "0.0.0-nightly-
|
|
27
|
-
"@ckeditor/ckeditor5-
|
|
28
|
-
"@ckeditor/ckeditor5-
|
|
29
|
-
"@ckeditor/ckeditor5-ui": "0.0.0-nightly-
|
|
30
|
-
"@ckeditor/ckeditor5-
|
|
31
|
-
|
|
16
|
+
"ckeditor5": "0.0.0-nightly-20260107.0",
|
|
17
|
+
"@ckeditor/ckeditor5-core": "0.0.0-nightly-20260107.0",
|
|
18
|
+
"@ckeditor/ckeditor5-icons": "0.0.0-nightly-20260107.0",
|
|
19
|
+
"@ckeditor/ckeditor5-widget": "0.0.0-nightly-20260107.0",
|
|
20
|
+
"@ckeditor/ckeditor5-utils": "0.0.0-nightly-20260107.0",
|
|
21
|
+
"@ckeditor/ckeditor5-ui": "0.0.0-nightly-20260107.0",
|
|
22
|
+
"@ckeditor/ckeditor5-link": "0.0.0-nightly-20260107.0"
|
|
23
|
+
},
|
|
24
|
+
"author": "CKSource (http://cksource.com/)",
|
|
25
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
26
|
+
"homepage": "https://ckeditor.com/ckeditor-5",
|
|
27
|
+
"bugs": "https://github.com/ckeditor/ckeditor5/issues",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/ckeditor/ckeditor5.git",
|
|
31
|
+
"directory": "packages/ckeditor5-bookmark"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
34
|
"dist",
|
|
35
35
|
"lang",
|
|
36
|
+
"src/**/*.js",
|
|
37
|
+
"src/**/*.d.ts",
|
|
36
38
|
"theme",
|
|
39
|
+
"build",
|
|
37
40
|
"ckeditor5-metadata.json",
|
|
38
41
|
"CHANGELOG.md"
|
|
39
42
|
],
|
|
40
|
-
"types": "
|
|
43
|
+
"types": "src/index.d.ts",
|
|
41
44
|
"exports": {
|
|
42
45
|
".": {
|
|
43
|
-
"types": "./
|
|
44
|
-
"import": "./
|
|
45
|
-
"default": "./
|
|
46
|
+
"types": "./src/index.d.ts",
|
|
47
|
+
"import": "./src/index.js",
|
|
48
|
+
"default": "./src/index.js"
|
|
46
49
|
},
|
|
47
50
|
"./dist/*": {
|
|
48
|
-
"types": "./
|
|
51
|
+
"types": "./src/index.d.ts",
|
|
49
52
|
"import": "./dist/*",
|
|
50
53
|
"default": "./dist/*"
|
|
51
54
|
},
|
|
55
|
+
"./src/*": {
|
|
56
|
+
"types": "./src/*.d.ts",
|
|
57
|
+
"import": "./src/*",
|
|
58
|
+
"default": "./src/*"
|
|
59
|
+
},
|
|
60
|
+
"./build/*": "./build/*",
|
|
52
61
|
"./lang/*": "./lang/*",
|
|
53
62
|
"./theme/*": "./theme/*",
|
|
54
63
|
"./ckeditor5-metadata.json": "./ckeditor5-metadata.json",
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
1
|
/**
|
|
6
2
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
1
|
/**
|
|
6
2
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
@@ -9,8 +5,8 @@
|
|
|
9
5
|
/**
|
|
10
6
|
* @module bookmark/bookmark
|
|
11
7
|
*/
|
|
12
|
-
import { Plugin } from '
|
|
13
|
-
import { Widget } from '
|
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
+
import { Widget } from 'ckeditor5/src/widget.js';
|
|
14
10
|
import { BookmarkUI } from './bookmarkui.js';
|
|
15
11
|
import { BookmarkEditing } from './bookmarkediting.js';
|
|
16
12
|
/**
|
package/src/bookmark.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module bookmark/bookmark
|
|
7
|
+
*/
|
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
+
import { Widget } from 'ckeditor5/src/widget.js';
|
|
10
|
+
import { BookmarkUI } from './bookmarkui.js';
|
|
11
|
+
import { BookmarkEditing } from './bookmarkediting.js';
|
|
12
|
+
/**
|
|
13
|
+
* The bookmark feature.
|
|
14
|
+
*
|
|
15
|
+
* For a detailed overview, check the {@glink features/bookmarks Bookmarks} feature guide.
|
|
16
|
+
*/
|
|
17
|
+
export class Bookmark extends Plugin {
|
|
18
|
+
/**
|
|
19
|
+
* @inheritDoc
|
|
20
|
+
*/
|
|
21
|
+
static get pluginName() {
|
|
22
|
+
return 'Bookmark';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* @inheritDoc
|
|
26
|
+
*/
|
|
27
|
+
static get requires() {
|
|
28
|
+
return [BookmarkEditing, BookmarkUI, Widget];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @inheritDoc
|
|
32
|
+
*/
|
|
33
|
+
static get isOfficialPlugin() {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
1
|
/**
|
|
6
2
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
1
|
/**
|
|
6
2
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
@@ -9,8 +5,8 @@
|
|
|
9
5
|
/**
|
|
10
6
|
* @module bookmark/bookmarkediting
|
|
11
7
|
*/
|
|
12
|
-
import { type Editor, Plugin } from '
|
|
13
|
-
import type { ModelElement } from '
|
|
8
|
+
import { type Editor, Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
+
import type { ModelElement } from 'ckeditor5/src/engine.js';
|
|
14
10
|
import '../theme/bookmark.css';
|
|
15
11
|
/**
|
|
16
12
|
* The bookmark editing plugin.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module bookmark/bookmarkediting
|
|
7
|
+
*/
|
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
+
import { toWidget } from 'ckeditor5/src/widget.js';
|
|
10
|
+
import { IconView } from 'ckeditor5/src/ui.js';
|
|
11
|
+
import { IconBookmarkInline } from 'ckeditor5/src/icons.js';
|
|
12
|
+
import { InsertBookmarkCommand } from './insertbookmarkcommand.js';
|
|
13
|
+
import { UpdateBookmarkCommand } from './updatebookmarkcommand.js';
|
|
14
|
+
import '../theme/bookmark.css';
|
|
15
|
+
/**
|
|
16
|
+
* The bookmark editing plugin.
|
|
17
|
+
*/
|
|
18
|
+
export class BookmarkEditing extends Plugin {
|
|
19
|
+
/**
|
|
20
|
+
* A collection of bookmarks elements in the document.
|
|
21
|
+
*/
|
|
22
|
+
_bookmarkElements = new Map();
|
|
23
|
+
/**
|
|
24
|
+
* @inheritDoc
|
|
25
|
+
*/
|
|
26
|
+
static get pluginName() {
|
|
27
|
+
return 'BookmarkEditing';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @inheritDoc
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
static get licenseFeatureCode() {
|
|
34
|
+
return 'BKM';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @inheritDoc
|
|
38
|
+
*/
|
|
39
|
+
static get isOfficialPlugin() {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @inheritDoc
|
|
44
|
+
*/
|
|
45
|
+
static get isPremiumPlugin() {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @inheritDoc
|
|
50
|
+
*/
|
|
51
|
+
constructor(editor) {
|
|
52
|
+
super(editor);
|
|
53
|
+
editor.config.define('bookmark', {
|
|
54
|
+
toolbar: ['bookmarkPreview', '|', 'editBookmark', 'removeBookmark']
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* @inheritDoc
|
|
59
|
+
*/
|
|
60
|
+
init() {
|
|
61
|
+
const { editor } = this;
|
|
62
|
+
this._defineSchema();
|
|
63
|
+
this._defineConverters();
|
|
64
|
+
editor.commands.add('insertBookmark', new InsertBookmarkCommand(editor));
|
|
65
|
+
editor.commands.add('updateBookmark', new UpdateBookmarkCommand(editor));
|
|
66
|
+
this.listenTo(editor.model.document, 'change:data', () => {
|
|
67
|
+
this._trackBookmarkElements();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns the model element for the given bookmark ID if it exists.
|
|
72
|
+
*/
|
|
73
|
+
getElementForBookmarkId(bookmarkId) {
|
|
74
|
+
for (const [element, id] of this._bookmarkElements) {
|
|
75
|
+
if (id == bookmarkId) {
|
|
76
|
+
return element;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns all unique bookmark names existing in the content.
|
|
83
|
+
*/
|
|
84
|
+
getAllBookmarkNames() {
|
|
85
|
+
return new Set(this._bookmarkElements.values());
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Defines the schema for the bookmark feature.
|
|
89
|
+
*/
|
|
90
|
+
_defineSchema() {
|
|
91
|
+
const schema = this.editor.model.schema;
|
|
92
|
+
schema.register('bookmark', {
|
|
93
|
+
inheritAllFrom: '$inlineObject',
|
|
94
|
+
allowAttributes: 'bookmarkId',
|
|
95
|
+
disallowAttributes: ['linkHref', 'htmlA']
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Defines the converters for the bookmark feature.
|
|
100
|
+
*/
|
|
101
|
+
_defineConverters() {
|
|
102
|
+
const { editor } = this;
|
|
103
|
+
const { conversion, t } = editor;
|
|
104
|
+
editor.data.htmlProcessor.domConverter.registerInlineObjectMatcher(element => upcastMatcher(element));
|
|
105
|
+
// Register an inline object matcher so that bookmarks <a>s are correctly recognized as inline elements in editing pipeline.
|
|
106
|
+
// This prevents converting spaces around bookmarks to ` `s.
|
|
107
|
+
editor.editing.view.domConverter.registerInlineObjectMatcher(element => upcastMatcher(element, false));
|
|
108
|
+
conversion.for('dataDowncast').elementToElement({
|
|
109
|
+
model: {
|
|
110
|
+
name: 'bookmark',
|
|
111
|
+
attributes: ['bookmarkId']
|
|
112
|
+
},
|
|
113
|
+
view: (modelElement, { writer }) => {
|
|
114
|
+
const emptyElement = writer.createEmptyElement('a', {
|
|
115
|
+
'id': modelElement.getAttribute('bookmarkId')
|
|
116
|
+
});
|
|
117
|
+
// `getFillerOffset` is not needed to set here, because `emptyElement` has already covered it.
|
|
118
|
+
return emptyElement;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
conversion.for('editingDowncast').elementToElement({
|
|
122
|
+
model: {
|
|
123
|
+
name: 'bookmark',
|
|
124
|
+
attributes: ['bookmarkId']
|
|
125
|
+
},
|
|
126
|
+
view: (modelElement, { writer }) => {
|
|
127
|
+
const id = modelElement.getAttribute('bookmarkId');
|
|
128
|
+
const containerElement = writer.createContainerElement('a', {
|
|
129
|
+
id,
|
|
130
|
+
class: 'ck-bookmark'
|
|
131
|
+
}, [this._createBookmarkUIElement(writer)]);
|
|
132
|
+
writer.setCustomProperty('bookmark', true, containerElement);
|
|
133
|
+
this._bookmarkElements.set(modelElement, id);
|
|
134
|
+
// `getFillerOffset` is not needed to set here, because `toWidget` has already covered it.
|
|
135
|
+
const labelCreator = () => `${id} ${t('bookmark widget')}`;
|
|
136
|
+
return toWidget(containerElement, writer, { label: labelCreator });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
conversion.for('upcast').add(dispatcher => dispatcher.on('element:a', dataViewModelAnchorInsertion(editor)));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Creates a UI element for the `bookmark` representation in editing view.
|
|
143
|
+
*/
|
|
144
|
+
_createBookmarkUIElement(writer) {
|
|
145
|
+
return writer.createUIElement('span', { class: 'ck-bookmark__icon' }, function (domDocument) {
|
|
146
|
+
const domElement = this.toDomElement(domDocument);
|
|
147
|
+
const icon = new IconView();
|
|
148
|
+
icon.set({
|
|
149
|
+
content: IconBookmarkInline,
|
|
150
|
+
isColorInherited: false
|
|
151
|
+
});
|
|
152
|
+
icon.render();
|
|
153
|
+
domElement.appendChild(icon.element);
|
|
154
|
+
return domElement;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Tracking the added or removed bookmark elements.
|
|
159
|
+
*/
|
|
160
|
+
_trackBookmarkElements() {
|
|
161
|
+
this._bookmarkElements.forEach((id, element) => {
|
|
162
|
+
if (element.root.rootName === '$graveyard') {
|
|
163
|
+
this._bookmarkElements.delete(element);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* A helper function to match an `anchor` element which must contain `id` or `name` attribute but without `href` attribute,
|
|
170
|
+
* also when `expectEmpty` is set to `true` but the element is not empty matcher should not match any element.
|
|
171
|
+
*
|
|
172
|
+
* @param element The element to be checked.
|
|
173
|
+
* @param expectEmpty Default set to `true`, when set to `false` matcher expects that `anchor` is not empty;
|
|
174
|
+
* in editing pipeline it's not empty because it contains the `UIElement`.
|
|
175
|
+
*/
|
|
176
|
+
function upcastMatcher(element, expectEmpty = true) {
|
|
177
|
+
const isAnchorElement = element.name === 'a';
|
|
178
|
+
if (!isAnchorElement) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
if (expectEmpty && !element.isEmpty) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
const hasIdAttribute = element.hasAttribute('id');
|
|
185
|
+
const hasNameAttribute = element.hasAttribute('name');
|
|
186
|
+
const hasHrefAttribute = element.hasAttribute('href');
|
|
187
|
+
if (hasIdAttribute && !hasHrefAttribute) {
|
|
188
|
+
return { name: true, attributes: ['id'] };
|
|
189
|
+
}
|
|
190
|
+
if (hasNameAttribute && !hasHrefAttribute) {
|
|
191
|
+
return { name: true, attributes: ['name'] };
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* A view-to-model converter that handles converting pointed or wrapped anchors with `id` and/or `name` attributes.
|
|
197
|
+
*
|
|
198
|
+
* @returns Returns a conversion callback.
|
|
199
|
+
*/
|
|
200
|
+
function dataViewModelAnchorInsertion(editor) {
|
|
201
|
+
return (evt, data, conversionApi) => {
|
|
202
|
+
const viewItem = data.viewItem;
|
|
203
|
+
const match = upcastMatcher(viewItem, false);
|
|
204
|
+
if (!match || !conversionApi.consumable.test(viewItem, match)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const enableNonEmptyAnchorConversion = isEnabledNonEmptyAnchorConversion(editor);
|
|
208
|
+
if (!enableNonEmptyAnchorConversion && !viewItem.isEmpty) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const modelWriter = conversionApi.writer;
|
|
212
|
+
const anchorId = viewItem.getAttribute('id');
|
|
213
|
+
const anchorName = viewItem.getAttribute('name');
|
|
214
|
+
const bookmarkId = anchorId || anchorName;
|
|
215
|
+
const bookmark = modelWriter.createElement('bookmark', { bookmarkId });
|
|
216
|
+
if (!conversionApi.safeInsert(bookmark, data.modelCursor)) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
conversionApi.consumable.consume(viewItem, match);
|
|
220
|
+
if (anchorId === anchorName) {
|
|
221
|
+
conversionApi.consumable.consume(viewItem, { attributes: ['name'] });
|
|
222
|
+
}
|
|
223
|
+
conversionApi.updateConversionResult(bookmark, data);
|
|
224
|
+
// Convert children uses the result of `bookmark` insertion to convert the `anchor` content
|
|
225
|
+
// after the bookmark element (not inside it).
|
|
226
|
+
const { modelCursor, modelRange } = conversionApi.convertChildren(viewItem, data.modelCursor);
|
|
227
|
+
data.modelCursor = modelCursor;
|
|
228
|
+
data.modelRange = modelWriter.createRange(data.modelRange.start, modelRange.end);
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Normalize the bookmark configuration option `enableNonEmptyAnchorConversion`.
|
|
233
|
+
*/
|
|
234
|
+
function isEnabledNonEmptyAnchorConversion(editor) {
|
|
235
|
+
const enableNonEmptyAnchorConversion = editor.config.get('bookmark.enableNonEmptyAnchorConversion');
|
|
236
|
+
// When not defined, option `enableNonEmptyAnchorConversion` by default is set to `true`.
|
|
237
|
+
return enableNonEmptyAnchorConversion !== undefined ? enableNonEmptyAnchorConversion : true;
|
|
238
|
+
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
1
|
/**
|
|
6
2
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
8
4
|
*/
|
|
9
|
-
import { Plugin } from '
|
|
10
|
-
import { ContextualBalloon, type ViewWithCssTransitionDisabler } from '
|
|
11
|
-
import { WidgetToolbarRepository } from '
|
|
5
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
|
6
|
+
import { ContextualBalloon, type ViewWithCssTransitionDisabler } from 'ckeditor5/src/ui.js';
|
|
7
|
+
import { WidgetToolbarRepository } from 'ckeditor5/src/widget.js';
|
|
12
8
|
import { BookmarkFormView } from './ui/bookmarkformview.js';
|
|
13
9
|
import { BookmarkEditing } from './bookmarkediting.js';
|
|
14
10
|
import '../theme/bookmarktoolbar.css';
|