ckeditor5-elements-breadcrumbs 0.0.0-stage → 49.0.0-alpha.2
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/LICENSE +21 -0
- package/README.md +31 -2
- package/dist/augmentation.d.ts +13 -0
- package/dist/augmentation.d.ts.map +1 -0
- package/dist/augmentation.js +2 -0
- package/dist/augmentation.js.map +1 -0
- package/dist/breadcrumbItemView.d.ts +47 -0
- package/dist/breadcrumbItemView.d.ts.map +1 -0
- package/dist/breadcrumbItemView.js +30 -0
- package/dist/breadcrumbItemView.js.map +1 -0
- package/dist/breadcrumbLabelView.d.ts +29 -0
- package/dist/breadcrumbLabelView.d.ts.map +1 -0
- package/dist/breadcrumbLabelView.js +39 -0
- package/dist/breadcrumbLabelView.js.map +1 -0
- package/dist/breadcrumbs.d.ts +103 -0
- package/dist/breadcrumbs.d.ts.map +1 -0
- package/dist/breadcrumbs.js +238 -0
- package/dist/breadcrumbs.js.map +1 -0
- package/dist/breadcrumbsView.d.ts +68 -0
- package/dist/breadcrumbsView.d.ts.map +1 -0
- package/dist/breadcrumbsView.js +134 -0
- package/dist/breadcrumbsView.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -3
- package/src/augmentation.ts +14 -0
- package/src/breadcrumbItemView.ts +74 -0
- package/src/breadcrumbLabelView.ts +55 -0
- package/src/breadcrumbs.ts +375 -0
- package/src/breadcrumbsView.ts +176 -0
- package/src/index.ts +29 -0
- package/theme/breadcrumbs.css +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ivan Kildyushov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ckeditor5-elements-breadcrumbs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Breadcrumbs for CKEditor 5 Elements: `Breadcrumbs` shows the element path at the cursor, made of the elements of the
|
|
4
|
+
editor data (e.g. `ul › li`, `figure.table › table › tbody › tr › td`), as labels, or as buttons that open the element
|
|
5
|
+
menu.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
This package is part of `ckeditor5-elements`. Install the whole package to use it:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install ckeditor5 ckeditor5-elements
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Breadcrumbs } from 'ckeditor5-elements';
|
|
19
|
+
import 'ckeditor5-elements/index.css';
|
|
20
|
+
|
|
21
|
+
// In the editor config:
|
|
22
|
+
plugins: [..., Breadcrumbs],
|
|
23
|
+
toolbar: ['bold', 'italic', '|', 'breadcrumbs'],
|
|
24
|
+
// Optional: the breadcrumbs become buttons that open this menu (needs the `ElementMenu` plugin).
|
|
25
|
+
breadcrumbs: { menu: (element, editor) => [editor.commands.get('copyElement')] }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
See the [Breadcrumbs guide](https://ivankild.github.io/ckeditor5-elements/guide/breadcrumbs) of the documentation.
|
|
29
|
+
|
|
30
|
+
## License
|
|
31
|
+
|
|
32
|
+
MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Breadcrumbs, BreadcrumbsConfig } from './index.js';
|
|
2
|
+
declare module 'ckeditor5' {
|
|
3
|
+
interface PluginsMap {
|
|
4
|
+
[Breadcrumbs.pluginName]: Breadcrumbs;
|
|
5
|
+
}
|
|
6
|
+
interface EditorConfig {
|
|
7
|
+
/**
|
|
8
|
+
* The configuration of the {@link Breadcrumbs} plugin.
|
|
9
|
+
*/
|
|
10
|
+
breadcrumbs?: BreadcrumbsConfig;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=augmentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"augmentation.d.ts","sourceRoot":"","sources":["../src/augmentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,QAAQ,WAAW,CAAC;IAC1B,UAAU,UAAU;QACnB,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC;KACtC;IAED,UAAU,YAAY;QACrB;;WAEG;QACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;KAChC;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"augmentation.js","sourceRoot":"","sources":["../src/augmentation.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ButtonView, type Locale, type ModelElement, type ViewElement } from 'ckeditor5';
|
|
2
|
+
/**
|
|
3
|
+
* A single breadcrumb that can be clicked: a button labelled with one element of the data view, e.g. `section.title`.
|
|
4
|
+
* It opens the menu of its element (`aria-haspopup`), and is `aria-expanded` while the menu is open.
|
|
5
|
+
*/
|
|
6
|
+
export default class BreadcrumbItemView extends ButtonView {
|
|
7
|
+
/**
|
|
8
|
+
* The data view element this item stands for.
|
|
9
|
+
*/
|
|
10
|
+
readonly viewElement: ViewElement;
|
|
11
|
+
/**
|
|
12
|
+
* The model element the menu of this item is for.
|
|
13
|
+
*/
|
|
14
|
+
readonly modelElement: ModelElement | null;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the menu of this item is open.
|
|
17
|
+
*
|
|
18
|
+
* @observable
|
|
19
|
+
*/
|
|
20
|
+
isExpanded: boolean;
|
|
21
|
+
constructor(locale: Locale | undefined, { label, viewElement, modelElement }: BreadcrumbItem, { isCurrent }?: BreadcrumbItemViewOptions);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The options of {@link BreadcrumbItemView} and {@link BreadcrumbLabelView}.
|
|
25
|
+
*/
|
|
26
|
+
export interface BreadcrumbItemViewOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Whether the item is the innermost element (where the cursor is). It is marked with `aria-current="location"`.
|
|
29
|
+
*/
|
|
30
|
+
isCurrent?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A breadcrumb: an element of the data view, its label, and the model element it belongs to.
|
|
34
|
+
*/
|
|
35
|
+
export interface BreadcrumbItem {
|
|
36
|
+
label: string;
|
|
37
|
+
/**
|
|
38
|
+
* The data view element (as in the editor data, e.g. `getData()`).
|
|
39
|
+
*/
|
|
40
|
+
viewElement: ViewElement;
|
|
41
|
+
/**
|
|
42
|
+
* The model element of the view element: the mapped one, or for a part of a structure (e.g. a `tbody`), the closest
|
|
43
|
+
* mapped ancestor (the table). `null` for list items (`ul`, `li`), which come from block attributes.
|
|
44
|
+
*/
|
|
45
|
+
modelElement: ModelElement | null;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=breadcrumbItemView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumbItemView.d.ts","sourceRoot":"","sources":["../src/breadcrumbItemView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAEzF;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,UAAU;IACzD;;OAEG;IACH,SAAgB,WAAW,EAAE,WAAW,CAAC;IAEzC;;OAEG;IACH,SAAgB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAElD;;;;OAIG;IACY,UAAU,EAAE,OAAO,CAAC;gBAGlC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,cAAc,EACpD,EAAE,SAAiB,EAAE,GAAE,yBAA8B;CAkBtD;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IAEzB;;;OAGG;IACH,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;CAClC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ButtonView } from 'ckeditor5';
|
|
2
|
+
/**
|
|
3
|
+
* A single breadcrumb that can be clicked: a button labelled with one element of the data view, e.g. `section.title`.
|
|
4
|
+
* It opens the menu of its element (`aria-haspopup`), and is `aria-expanded` while the menu is open.
|
|
5
|
+
*/
|
|
6
|
+
export default class BreadcrumbItemView extends ButtonView {
|
|
7
|
+
/**
|
|
8
|
+
* The data view element this item stands for.
|
|
9
|
+
*/
|
|
10
|
+
viewElement;
|
|
11
|
+
/**
|
|
12
|
+
* The model element the menu of this item is for.
|
|
13
|
+
*/
|
|
14
|
+
modelElement;
|
|
15
|
+
constructor(locale, { label, viewElement, modelElement }, { isCurrent = false } = {}) {
|
|
16
|
+
super(locale);
|
|
17
|
+
this.viewElement = viewElement;
|
|
18
|
+
this.modelElement = modelElement;
|
|
19
|
+
this.set({ label, withText: true, isExpanded: false });
|
|
20
|
+
this.extendTemplate({
|
|
21
|
+
attributes: {
|
|
22
|
+
class: 'ck-elements-breadcrumbs__item',
|
|
23
|
+
'aria-haspopup': 'menu',
|
|
24
|
+
'aria-expanded': this.bindTemplate.to('isExpanded', value => String(value)),
|
|
25
|
+
...(isCurrent ? { 'aria-current': 'location' } : {})
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=breadcrumbItemView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumbItemView.js","sourceRoot":"","sources":["../src/breadcrumbItemView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAoD,MAAM,WAAW,CAAC;AAEzF;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,UAAU;IACzD;;OAEG;IACa,WAAW,CAAc;IAEzC;;OAEG;IACa,YAAY,CAAsB;IASlD,YACC,MAA0B,EAC1B,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAkB,EACpD,EAAE,SAAS,GAAG,KAAK,KAAgC,EAAE;QAErD,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QAEjC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAEvD,IAAI,CAAC,cAAc,CAAC;YACnB,UAAU,EAAE;gBACX,KAAK,EAAE,+BAA+B;gBACtC,eAAe,EAAE,MAAM;gBACvB,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC3E,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD;SACD,CAAC,CAAC;IACJ,CAAC;CACD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { View, type Locale, type ModelElement, type ViewElement } from 'ckeditor5';
|
|
2
|
+
import { type BreadcrumbItem, type BreadcrumbItemViewOptions } from './breadcrumbItemView.js';
|
|
3
|
+
/**
|
|
4
|
+
* A single breadcrumb that cannot be clicked: the label of one element of the data view, e.g. `section.title`.
|
|
5
|
+
*
|
|
6
|
+
* It can be focused (but is not in the Tab order), so keyboard users can reach it in a toolbar.
|
|
7
|
+
*/
|
|
8
|
+
export default class BreadcrumbLabelView extends View {
|
|
9
|
+
/**
|
|
10
|
+
* The data view element this item stands for.
|
|
11
|
+
*/
|
|
12
|
+
readonly viewElement: ViewElement;
|
|
13
|
+
/**
|
|
14
|
+
* The model element of the view element, if any.
|
|
15
|
+
*/
|
|
16
|
+
readonly modelElement: ModelElement | null;
|
|
17
|
+
/**
|
|
18
|
+
* The label of the element.
|
|
19
|
+
*
|
|
20
|
+
* @observable
|
|
21
|
+
*/
|
|
22
|
+
label: string;
|
|
23
|
+
constructor(locale: Locale | undefined, { label, viewElement, modelElement }: BreadcrumbItem, { isCurrent }?: BreadcrumbItemViewOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Focuses the label.
|
|
26
|
+
*/
|
|
27
|
+
focus(): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=breadcrumbLabelView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumbLabelView.d.ts","sourceRoot":"","sources":["../src/breadcrumbLabelView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACnF,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAE9F;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,IAAI;IACpD;;OAEG;IACH,SAAgB,WAAW,EAAE,WAAW,CAAC;IAEzC;;OAEG;IACH,SAAgB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAElD;;;;OAIG;IACY,KAAK,EAAE,MAAM,CAAC;gBAG5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,cAAc,EACpD,EAAE,SAAiB,EAAE,GAAE,yBAA8B;IAmBtD;;OAEG;IACI,KAAK,IAAI,IAAI;CAGpB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { View } from 'ckeditor5';
|
|
2
|
+
import {} from './breadcrumbItemView.js';
|
|
3
|
+
/**
|
|
4
|
+
* A single breadcrumb that cannot be clicked: the label of one element of the data view, e.g. `section.title`.
|
|
5
|
+
*
|
|
6
|
+
* It can be focused (but is not in the Tab order), so keyboard users can reach it in a toolbar.
|
|
7
|
+
*/
|
|
8
|
+
export default class BreadcrumbLabelView extends View {
|
|
9
|
+
/**
|
|
10
|
+
* The data view element this item stands for.
|
|
11
|
+
*/
|
|
12
|
+
viewElement;
|
|
13
|
+
/**
|
|
14
|
+
* The model element of the view element, if any.
|
|
15
|
+
*/
|
|
16
|
+
modelElement;
|
|
17
|
+
constructor(locale, { label, viewElement, modelElement }, { isCurrent = false } = {}) {
|
|
18
|
+
super(locale);
|
|
19
|
+
this.viewElement = viewElement;
|
|
20
|
+
this.modelElement = modelElement;
|
|
21
|
+
this.set('label', label);
|
|
22
|
+
this.setTemplate({
|
|
23
|
+
tag: 'span',
|
|
24
|
+
attributes: {
|
|
25
|
+
class: ['ck', 'ck-elements-breadcrumbs__item', 'ck-elements-breadcrumbs__label'],
|
|
26
|
+
tabindex: '-1',
|
|
27
|
+
...(isCurrent ? { 'aria-current': 'location' } : {})
|
|
28
|
+
},
|
|
29
|
+
children: [{ text: this.bindTemplate.to('label') }]
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Focuses the label.
|
|
34
|
+
*/
|
|
35
|
+
focus() {
|
|
36
|
+
this.element?.focus();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=breadcrumbLabelView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumbLabelView.js","sourceRoot":"","sources":["../src/breadcrumbLabelView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAoD,MAAM,WAAW,CAAC;AACnF,OAAO,EAAuD,MAAM,yBAAyB,CAAC;AAE9F;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,IAAI;IACpD;;OAEG;IACa,WAAW,CAAc;IAEzC;;OAEG;IACa,YAAY,CAAsB;IASlD,YACC,MAA0B,EAC1B,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAkB,EACpD,EAAE,SAAS,GAAG,KAAK,KAAgC,EAAE;QAErD,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAEzB,IAAI,CAAC,WAAW,CAAC;YAChB,GAAG,EAAE,MAAM;YACX,UAAU,EAAE;gBACX,KAAK,EAAE,CAAC,IAAI,EAAE,+BAA+B,EAAE,gCAAgC,CAAC;gBAChF,QAAQ,EAAE,IAAI;gBACd,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD;YACD,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;SACnD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,KAAK;QACX,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;CACD"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Plugin, type Editor, type Locale, type ModelElement, type RectSource } from 'ckeditor5';
|
|
2
|
+
import { type BreadcrumbItem } from './breadcrumbItemView.js';
|
|
3
|
+
import BreadcrumbsView from './breadcrumbsView.js';
|
|
4
|
+
/**
|
|
5
|
+
* The configuration of the {@link Breadcrumbs} plugin.
|
|
6
|
+
*/
|
|
7
|
+
export interface BreadcrumbsConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Returns the items of the menu that opens when a breadcrumb is clicked, for the element of the breadcrumb: the
|
|
10
|
+
* same items as in the `elementContextMenu` option (commands, submenus and `'|'` separators; see `ElementMenuConfig`),
|
|
11
|
+
* so one callback can serve both. Without this option, or without a loaded `ElementMenu` plugin, breadcrumbs cannot
|
|
12
|
+
* be clicked.
|
|
13
|
+
*/
|
|
14
|
+
menu?: BreadcrumbsMenuItems;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Shows the data view structure at the current selection (the elements of the editor data, as in `getData()`), e.g.
|
|
18
|
+
* `aside.note › p`, `ul › li` or `figure.table › table › tbody › tr › td`.
|
|
19
|
+
*
|
|
20
|
+
* Text attributes such as `<strong>` are skipped. The selected element, e.g. an image, is the innermost item.
|
|
21
|
+
*
|
|
22
|
+
* Place them in a toolbar as the `breadcrumbs` component, or anywhere else using a view from {@link createView}.
|
|
23
|
+
*
|
|
24
|
+
* Clicking is configured only by the `breadcrumbs.menu` editor config option (see {@link BreadcrumbsConfig}): with it,
|
|
25
|
+
* the items are buttons that open a menu of their element; without it, they are labels. The menu is shown by the
|
|
26
|
+
* `ElementMenu` plugin (loaded by `ElementContextMenu` and `QuickInsert`), which is used through the
|
|
27
|
+
* {@link BreadcrumbsMenu} interface: the breadcrumbs do not depend on the other features.
|
|
28
|
+
*
|
|
29
|
+
* The data view is converted again only when elements change, not when typing or moving the cursor. For a large
|
|
30
|
+
* document, that happens at most every 250 ms.
|
|
31
|
+
*/
|
|
32
|
+
export default class Breadcrumbs extends Plugin {
|
|
33
|
+
/**
|
|
34
|
+
* The elements at the current selection, from the outermost to the innermost one.
|
|
35
|
+
*
|
|
36
|
+
* @observable
|
|
37
|
+
*/
|
|
38
|
+
items: readonly BreadcrumbItem[];
|
|
39
|
+
private _dataView;
|
|
40
|
+
private _isDataViewOutdated;
|
|
41
|
+
private _isConversionSlow;
|
|
42
|
+
private _conversionTimeout;
|
|
43
|
+
static get pluginName(): 'Breadcrumbs';
|
|
44
|
+
constructor(editor: Editor);
|
|
45
|
+
init(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a breadcrumbs view that follows {@link items}.
|
|
48
|
+
*/
|
|
49
|
+
createView(locale?: Locale): BreadcrumbsView;
|
|
50
|
+
/**
|
|
51
|
+
* Updates {@link items} from the current selection, converting the data view first when elements changed.
|
|
52
|
+
*/
|
|
53
|
+
refresh(): void;
|
|
54
|
+
destroy(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Refreshes the items after a change. When converting is slow, the data view is converted later, and the items
|
|
57
|
+
* follow the outdated data view until then.
|
|
58
|
+
*/
|
|
59
|
+
private _update;
|
|
60
|
+
/**
|
|
61
|
+
* Converts the root to the data view, and maps its model elements to their view elements.
|
|
62
|
+
*/
|
|
63
|
+
private _convert;
|
|
64
|
+
private _cancelConversion;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the data view elements at the selection: the view element of the selected element, or of the innermost
|
|
67
|
+
* element with the selection, and its ancestors.
|
|
68
|
+
*/
|
|
69
|
+
private _getItems;
|
|
70
|
+
private _openMenu;
|
|
71
|
+
/**
|
|
72
|
+
* Returns the plugin that shows menus: `ElementMenu`, when it is loaded.
|
|
73
|
+
*/
|
|
74
|
+
private _getMenu;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The part of the `ElementMenu` plugin the breadcrumbs use. The breadcrumbs do not depend on the other features: the
|
|
78
|
+
* plugin is looked up by name and checked against this interface.
|
|
79
|
+
*/
|
|
80
|
+
export interface BreadcrumbsMenu {
|
|
81
|
+
open(element: ModelElement, target: RectSource, items: BreadcrumbsMenuItems, options: BreadcrumbsMenuOptions): boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The options the breadcrumbs pass to {@link BreadcrumbsMenu#open}.
|
|
85
|
+
*/
|
|
86
|
+
export interface BreadcrumbsMenuOptions {
|
|
87
|
+
/**
|
|
88
|
+
* What gets the focus when the menu is closed with Esc: the breadcrumb that opened it.
|
|
89
|
+
*/
|
|
90
|
+
returnFocusTo: {
|
|
91
|
+
focus(): void;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Called when the menu closes.
|
|
95
|
+
*/
|
|
96
|
+
onHide: () => void;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Returns the items of the menu of an element. The breadcrumbs pass them to the menu plugin as they are; for
|
|
100
|
+
* `ElementMenu`, they are commands, submenus and `'|'` separators.
|
|
101
|
+
*/
|
|
102
|
+
export type BreadcrumbsMenuItems = (element: ModelElement, editor: Editor) => readonly unknown[];
|
|
103
|
+
//# sourceMappingURL=breadcrumbs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumbs.d.ts","sourceRoot":"","sources":["../src/breadcrumbs.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,MAAM,EAEN,KAAK,MAAM,EACX,KAAK,MAAM,EAGX,KAAK,YAAY,EAEjB,KAAK,UAAU,EAIf,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,KAAK,cAAc,EAAsC,MAAM,yBAAyB,CAAC;AAClG,OAAO,eAAqD,MAAM,sBAAsB,CAAC;AASzF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;CAC5B;AAWD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,MAAM;IAC9C;;;;OAIG;IACY,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IAEhD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,mBAAmB,CAAQ;IACnC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,kBAAkB,CAA8C;IAExE,WAAkB,UAAU,IAAI,aAAa,CAE5C;gBAEW,MAAM,EAAE,MAAM;IAMnB,IAAI,IAAI,IAAI;IAmBnB;;OAEG;IACI,UAAU,CAAC,MAAM,GAAE,MAA2B,GAAG,eAAe;IAgBvE;;OAEG;IACI,OAAO,IAAI,IAAI;IAcN,OAAO,IAAI,IAAI;IAK/B;;;OAGG;IACH,OAAO,CAAC,OAAO;IAqBf;;OAEG;IACH,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAwBjB,OAAO,CAAC,SAAS;IA0BjB;;OAEG;IACH,OAAO,CAAC,QAAQ;CAGhB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,CACH,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,aAAa,EAAE;QAAE,KAAK,IAAI,IAAI,CAAA;KAAE,CAAC;IAEjC;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { Plugin } from 'ckeditor5';
|
|
2
|
+
import { findPlugin } from 'ckeditor5-elements-core';
|
|
3
|
+
import {} from './breadcrumbItemView.js';
|
|
4
|
+
import BreadcrumbsView, {} from './breadcrumbsView.js';
|
|
5
|
+
/**
|
|
6
|
+
* Converting the data view of a large document takes a while. When the last conversion took longer than this (in
|
|
7
|
+
* milliseconds), the next one waits for {@link THROTTLE_TIME}, so editing elements quickly does not convert every time.
|
|
8
|
+
*/
|
|
9
|
+
const SLOW_CONVERSION_TIME = 10;
|
|
10
|
+
const THROTTLE_TIME = 250;
|
|
11
|
+
/**
|
|
12
|
+
* Shows the data view structure at the current selection (the elements of the editor data, as in `getData()`), e.g.
|
|
13
|
+
* `aside.note › p`, `ul › li` or `figure.table › table › tbody › tr › td`.
|
|
14
|
+
*
|
|
15
|
+
* Text attributes such as `<strong>` are skipped. The selected element, e.g. an image, is the innermost item.
|
|
16
|
+
*
|
|
17
|
+
* Place them in a toolbar as the `breadcrumbs` component, or anywhere else using a view from {@link createView}.
|
|
18
|
+
*
|
|
19
|
+
* Clicking is configured only by the `breadcrumbs.menu` editor config option (see {@link BreadcrumbsConfig}): with it,
|
|
20
|
+
* the items are buttons that open a menu of their element; without it, they are labels. The menu is shown by the
|
|
21
|
+
* `ElementMenu` plugin (loaded by `ElementContextMenu` and `QuickInsert`), which is used through the
|
|
22
|
+
* {@link BreadcrumbsMenu} interface: the breadcrumbs do not depend on the other features.
|
|
23
|
+
*
|
|
24
|
+
* The data view is converted again only when elements change, not when typing or moving the cursor. For a large
|
|
25
|
+
* document, that happens at most every 250 ms.
|
|
26
|
+
*/
|
|
27
|
+
export default class Breadcrumbs extends Plugin {
|
|
28
|
+
_dataView = null;
|
|
29
|
+
_isDataViewOutdated = true;
|
|
30
|
+
_isConversionSlow = false;
|
|
31
|
+
_conversionTimeout = null;
|
|
32
|
+
static get pluginName() {
|
|
33
|
+
return 'Breadcrumbs';
|
|
34
|
+
}
|
|
35
|
+
constructor(editor) {
|
|
36
|
+
super(editor);
|
|
37
|
+
this.set('items', []);
|
|
38
|
+
}
|
|
39
|
+
init() {
|
|
40
|
+
const editor = this.editor;
|
|
41
|
+
editor.ui.componentFactory.add('breadcrumbs', locale => this.createView(locale));
|
|
42
|
+
this.listenTo(editor.ui, 'ready', () => {
|
|
43
|
+
this.refresh();
|
|
44
|
+
});
|
|
45
|
+
// Both selection and data changes.
|
|
46
|
+
this.listenTo(editor.model.document, 'change', () => {
|
|
47
|
+
if (hasElementChanges(editor.model.document.differ.getChanges())) {
|
|
48
|
+
this._isDataViewOutdated = true;
|
|
49
|
+
}
|
|
50
|
+
this._update();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Creates a breadcrumbs view that follows {@link items}.
|
|
55
|
+
*/
|
|
56
|
+
createView(locale = this.editor.locale) {
|
|
57
|
+
const isClickable = typeof this.editor.config.get('breadcrumbs')?.menu === 'function' && !!this._getMenu();
|
|
58
|
+
const view = new BreadcrumbsView(locale, { isClickable });
|
|
59
|
+
view.setItems(this.items);
|
|
60
|
+
view.listenTo(this, 'change:items', () => {
|
|
61
|
+
view.setItems(this.items);
|
|
62
|
+
});
|
|
63
|
+
view.on('execute', (evt, item) => {
|
|
64
|
+
this._openMenu(item);
|
|
65
|
+
});
|
|
66
|
+
return view;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Updates {@link items} from the current selection, converting the data view first when elements changed.
|
|
70
|
+
*/
|
|
71
|
+
refresh() {
|
|
72
|
+
const root = this.editor.model.document.selection.getFirstPosition()?.root;
|
|
73
|
+
if (root?.is('rootElement') && (this._isDataViewOutdated || root !== this._dataView?.root)) {
|
|
74
|
+
this._convert(root);
|
|
75
|
+
}
|
|
76
|
+
const items = this._getItems();
|
|
77
|
+
if (!areEqual(items, this.items)) {
|
|
78
|
+
this.items = items;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
destroy() {
|
|
82
|
+
this._cancelConversion();
|
|
83
|
+
super.destroy();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Refreshes the items after a change. When converting is slow, the data view is converted later, and the items
|
|
87
|
+
* follow the outdated data view until then.
|
|
88
|
+
*/
|
|
89
|
+
_update() {
|
|
90
|
+
const root = this.editor.model.document.selection.getFirstPosition()?.root;
|
|
91
|
+
if (this._isDataViewOutdated && this._isConversionSlow && root === this._dataView?.root) {
|
|
92
|
+
this._conversionTimeout ??= setTimeout(() => {
|
|
93
|
+
this._conversionTimeout = null;
|
|
94
|
+
this.refresh();
|
|
95
|
+
}, THROTTLE_TIME);
|
|
96
|
+
}
|
|
97
|
+
if (this._conversionTimeout) {
|
|
98
|
+
const items = this._getItems();
|
|
99
|
+
if (!areEqual(items, this.items)) {
|
|
100
|
+
this.items = items;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this.refresh();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Converts the root to the data view, and maps its model elements to their view elements.
|
|
109
|
+
*/
|
|
110
|
+
_convert(root) {
|
|
111
|
+
const data = this.editor.data;
|
|
112
|
+
const start = performance.now();
|
|
113
|
+
const viewElements = new WeakMap();
|
|
114
|
+
const modelElements = new WeakMap();
|
|
115
|
+
// The mapper of the data pipeline is cleared by the next conversion (e.g. `getData()`), so keep the mapping.
|
|
116
|
+
data.toView(root);
|
|
117
|
+
for (const { item } of this.editor.model.createRangeIn(root)) {
|
|
118
|
+
const viewElement = item.is('element') ? data.mapper.toViewElement(item) : undefined;
|
|
119
|
+
if (item.is('element') && viewElement) {
|
|
120
|
+
viewElements.set(item, viewElement);
|
|
121
|
+
modelElements.set(viewElement, item);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
this._dataView = { root, viewElements, modelElements };
|
|
125
|
+
this._isDataViewOutdated = false;
|
|
126
|
+
this._isConversionSlow = performance.now() - start > SLOW_CONVERSION_TIME;
|
|
127
|
+
this._cancelConversion();
|
|
128
|
+
}
|
|
129
|
+
_cancelConversion() {
|
|
130
|
+
if (this._conversionTimeout) {
|
|
131
|
+
clearTimeout(this._conversionTimeout);
|
|
132
|
+
this._conversionTimeout = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns the data view elements at the selection: the view element of the selected element, or of the innermost
|
|
137
|
+
* element with the selection, and its ancestors.
|
|
138
|
+
*/
|
|
139
|
+
_getItems() {
|
|
140
|
+
const dataView = this._dataView;
|
|
141
|
+
const selection = this.editor.model.document.selection;
|
|
142
|
+
const position = selection.getFirstPosition();
|
|
143
|
+
if (!dataView || position?.root !== dataView.root) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
// Elements created since the last conversion are not mapped yet; their closest mapped ancestor is used meanwhile.
|
|
147
|
+
let viewElement;
|
|
148
|
+
for (let element = selection.getSelectedElement() ?? position.parent; element?.is('element') && !element.is('rootElement') && !viewElement; element = element.parent) {
|
|
149
|
+
viewElement = dataView.viewElements.get(element);
|
|
150
|
+
}
|
|
151
|
+
return viewElement ? getPath(viewElement).map(node => createItem(node, dataView)) : [];
|
|
152
|
+
}
|
|
153
|
+
_openMenu(item) {
|
|
154
|
+
const menuItems = this.editor.config.get('breadcrumbs')?.menu;
|
|
155
|
+
const menu = this._getMenu();
|
|
156
|
+
const element = item.modelElement;
|
|
157
|
+
if (!menuItems || !menu || !item.element || !element || !isInDocument(element)) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
item.isExpanded = menu.open(element, item.element, menuItems, {
|
|
161
|
+
// The breadcrumbs may have been replaced while the menu was open.
|
|
162
|
+
returnFocusTo: {
|
|
163
|
+
focus: () => {
|
|
164
|
+
if (item.element?.isConnected) {
|
|
165
|
+
item.focus();
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
this.editor.editing.view.focus();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
onHide: () => {
|
|
173
|
+
item.isExpanded = false;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Returns the plugin that shows menus: `ElementMenu`, when it is loaded.
|
|
179
|
+
*/
|
|
180
|
+
_getMenu() {
|
|
181
|
+
return findPlugin(this.editor, 'ElementMenu', isBreadcrumbsMenu);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function isBreadcrumbsMenu(plugin) {
|
|
185
|
+
return 'open' in plugin && typeof plugin.open === 'function';
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Whether the changes add, remove or change elements. Typing (text changes) does not change the data view structure.
|
|
189
|
+
*/
|
|
190
|
+
function hasElementChanges(changes) {
|
|
191
|
+
return changes.some(change => change.type === 'attribute'
|
|
192
|
+
? Array.from(change.range.getItems({ shallow: true })).some(item => item.is('element'))
|
|
193
|
+
: change.name !== '$text');
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Returns the view element and its ancestors, outermost first, without:
|
|
197
|
+
*
|
|
198
|
+
* * text attributes (attribute elements without a block inside, such as `<strong>` or `<a>`); list items (`<ul>`,
|
|
199
|
+
* `<li>`) are attribute elements too, but wrap blocks,
|
|
200
|
+
* * elements that are not rendered in the data, such as the paragraph in a list item or a table cell that has only
|
|
201
|
+
* one paragraph.
|
|
202
|
+
*/
|
|
203
|
+
function getPath(viewElement) {
|
|
204
|
+
const path = [];
|
|
205
|
+
let hasBlock = false;
|
|
206
|
+
for (let node = viewElement; node?.is('element'); node = node.parent) {
|
|
207
|
+
const isTextAttribute = node.is('attributeElement') && !hasBlock;
|
|
208
|
+
if (!isTextAttribute && !node.getCustomProperty('dataPipeline:transparentRendering')) {
|
|
209
|
+
path.unshift(node);
|
|
210
|
+
}
|
|
211
|
+
hasBlock ||= node.is('containerElement');
|
|
212
|
+
}
|
|
213
|
+
return path;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Creates the item of a view element. Its model element is the mapped one, or the closest mapped ancestor of a part of
|
|
217
|
+
* a structure (e.g. a `tbody` is a part of a table). List items have none: they come from the attributes of the blocks
|
|
218
|
+
* in them, not from an element.
|
|
219
|
+
*/
|
|
220
|
+
function createItem(viewElement, dataView) {
|
|
221
|
+
let modelElement = null;
|
|
222
|
+
for (let node = viewElement; node?.is('element') && !modelElement && !node.is('attributeElement'); node = node.parent) {
|
|
223
|
+
modelElement = dataView.modelElements.get(node) ?? null;
|
|
224
|
+
}
|
|
225
|
+
return { label: [viewElement.name, ...viewElement.getClassNames()].join('.'), viewElement, modelElement };
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Whether the element is in the document, i.e. not removed.
|
|
229
|
+
*/
|
|
230
|
+
function isInDocument(element) {
|
|
231
|
+
const root = element.root;
|
|
232
|
+
return root.is('rootElement') && root.rootName !== '$graveyard' && root.isAttached();
|
|
233
|
+
}
|
|
234
|
+
function areEqual(a, b) {
|
|
235
|
+
return (a.length === b.length &&
|
|
236
|
+
a.every((item, index) => item.label === b[index]?.label && item.modelElement === b[index].modelElement));
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=breadcrumbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumbs.js","sourceRoot":"","sources":["../src/breadcrumbs.ts"],"names":[],"mappings":"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"}
|