ckeditor5-elements-menu 49.0.0-alpha.4 → 49.0.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.
Files changed (53) hide show
  1. package/README.md +7 -7
  2. package/dist/augmentation.d.ts +7 -7
  3. package/dist/augmentation.d.ts.map +1 -1
  4. package/dist/breadcrumbs/{breadcrumbs.d.ts → elementBreadcrumbs.d.ts} +8 -7
  5. package/dist/breadcrumbs/elementBreadcrumbs.d.ts.map +1 -0
  6. package/dist/breadcrumbs/{breadcrumbs.js → elementBreadcrumbs.js} +8 -7
  7. package/dist/breadcrumbs/elementBreadcrumbs.js.map +1 -0
  8. package/dist/contextMenu/elementContextMenu.d.ts.map +1 -1
  9. package/dist/contextMenu/elementContextMenu.js +7 -17
  10. package/dist/contextMenu/elementContextMenu.js.map +1 -1
  11. package/dist/domTarget.d.ts +8 -0
  12. package/dist/domTarget.d.ts.map +1 -0
  13. package/dist/domTarget.js +20 -0
  14. package/dist/domTarget.js.map +1 -0
  15. package/dist/elementMenu.d.ts +2 -2
  16. package/dist/elementMenu.d.ts.map +1 -1
  17. package/dist/elementMenu.js +4 -26
  18. package/dist/elementMenu.js.map +1 -1
  19. package/dist/elementMenuView.d.ts +5 -0
  20. package/dist/elementMenuView.d.ts.map +1 -1
  21. package/dist/elementMenuView.js +31 -5
  22. package/dist/elementMenuView.js.map +1 -1
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/quickInsert/{quickInsert.d.ts → elementQuickInsert.d.ts} +11 -11
  28. package/dist/quickInsert/elementQuickInsert.d.ts.map +1 -0
  29. package/dist/quickInsert/{quickInsert.js → elementQuickInsert.js} +19 -29
  30. package/dist/quickInsert/elementQuickInsert.js.map +1 -0
  31. package/dist/quickInsert/quickInsertCommand.d.ts +14 -5
  32. package/dist/quickInsert/quickInsertCommand.d.ts.map +1 -1
  33. package/dist/quickInsert/quickInsertCommand.js +28 -17
  34. package/dist/quickInsert/quickInsertCommand.js.map +1 -1
  35. package/dist/quickInsert/quickInsertPositionCommand.d.ts +7 -2
  36. package/dist/quickInsert/quickInsertPositionCommand.d.ts.map +1 -1
  37. package/dist/quickInsert/quickInsertPositionCommand.js +11 -13
  38. package/dist/quickInsert/quickInsertPositionCommand.js.map +1 -1
  39. package/package.json +5 -2
  40. package/src/augmentation.ts +10 -10
  41. package/src/breadcrumbs/{breadcrumbs.ts → elementBreadcrumbs.ts} +10 -9
  42. package/src/contextMenu/elementContextMenu.ts +8 -20
  43. package/src/domTarget.ts +27 -0
  44. package/src/elementMenu.ts +11 -36
  45. package/src/elementMenuView.ts +53 -14
  46. package/src/index.ts +2 -2
  47. package/src/quickInsert/{quickInsert.ts → elementQuickInsert.ts} +24 -38
  48. package/src/quickInsert/quickInsertCommand.ts +36 -25
  49. package/src/quickInsert/quickInsertPositionCommand.ts +13 -17
  50. package/dist/breadcrumbs/breadcrumbs.d.ts.map +0 -1
  51. package/dist/breadcrumbs/breadcrumbs.js.map +0 -1
  52. package/dist/quickInsert/quickInsert.d.ts.map +0 -1
  53. package/dist/quickInsert/quickInsert.js.map +0 -1
@@ -3,9 +3,9 @@ import type { ElementOrPosition } from 'ckeditor5-elements-core';
3
3
  import ElementMenu from '../elementMenu.js';
4
4
  import { type QuickInsertItem } from './quickInsertListView.js';
5
5
  /**
6
- * The configuration of the {@link QuickInsert} plugin.
6
+ * The configuration of the {@link ElementQuickInsert} plugin.
7
7
  */
8
- export interface QuickInsertConfig {
8
+ export interface ElementQuickInsertConfig {
9
9
  /**
10
10
  * Labels of the elements, by model name. Elements without a label are listed by their model name.
11
11
  */
@@ -22,7 +22,7 @@ export interface QuickInsertConfig {
22
22
  }
23
23
  /**
24
24
  * Opens a menu with a search field and the elements allowed at the selection, on Alt+Enter (Option+Enter on macOS; see
25
- * {@link QuickInsertConfig.keystroke}). Choosing an element inserts it with the `quickInsert` command.
25
+ * {@link ElementQuickInsertConfig.keystroke}). Choosing an element inserts it with the `quickInsert` command.
26
26
  *
27
27
  * The menu is shown by the `ElementMenu` plugin. The `quickInsertBefore` and `quickInsertAfter` commands (see
28
28
  * {@link QuickInsertPositionCommand}) open it for the position before or after an element; list them in the
@@ -30,9 +30,9 @@ export interface QuickInsertConfig {
30
30
  *
31
31
  * The menu closes when the document changes while it is open, so it never inserts at an outdated position.
32
32
  */
33
- export default class QuickInsert extends Plugin {
33
+ export default class ElementQuickInsert extends Plugin {
34
34
  static get requires(): readonly [typeof ElementMenu];
35
- static get pluginName(): 'QuickInsert';
35
+ static get pluginName(): 'ElementQuickInsert';
36
36
  constructor(editor: Editor);
37
37
  init(): void;
38
38
  /**
@@ -40,6 +40,11 @@ export default class QuickInsert extends Plugin {
40
40
  * selection), with their labels.
41
41
  */
42
42
  getItems(elementOrPosition?: ElementOrPosition): QuickInsertItem[];
43
+ /**
44
+ * Whether an element can be inserted at the target (a position, the position before an element, or the selection),
45
+ * as {@link getItems} lists them: it stops at the first one, e.g. for whether a command is enabled.
46
+ */
47
+ hasItems(elementOrPosition?: ElementOrPosition): boolean;
43
48
  /**
44
49
  * Opens the menu for inserting at the target (a position, the position before an element, or the selection), next
45
50
  * to the given DOM target. By default, the menu is next to the element, or the selection.
@@ -48,10 +53,5 @@ export default class QuickInsert extends Plugin {
48
53
  * show the menu next to.
49
54
  */
50
55
  open(elementOrPosition?: ElementOrPosition, domTarget?: RectSource): boolean;
51
- /**
52
- * Returns the DOM element of the element, or the DOM range of the selection.
53
- */
54
- private _getDomTarget;
55
- private _getDomElement;
56
56
  }
57
- //# sourceMappingURL=quickInsert.d.ts.map
57
+ //# sourceMappingURL=elementQuickInsert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elementQuickInsert.d.ts","sourceRoot":"","sources":["../../src/quickInsert/elementQuickInsert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAiC,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAG5C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGhE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,MAAM;IACrD,WAAkB,QAAQ,IAAI,SAAS,CAAC,OAAO,WAAW,CAAC,CAE1D;IAED,WAAkB,UAAU,IAAI,oBAAoB,CAEnD;gBAEW,MAAM,EAAE,MAAM;IAMnB,IAAI,IAAI,IAAI;IAqBnB;;;OAGG;IACI,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,eAAe,EAAE;IAWzE;;;OAGG;IACI,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,OAAO;IAM/D;;;;;;OAMG;IACI,IAAI,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,OAAO;CA0BnF"}
@@ -1,4 +1,5 @@
1
1
  import { Plugin } from 'ckeditor5';
2
+ import { getDomTarget } from '../domTarget.js';
2
3
  import ElementMenu from '../elementMenu.js';
3
4
  import QuickInsertCommand from './quickInsertCommand.js';
4
5
  import QuickInsertPositionCommand from './quickInsertPositionCommand.js';
@@ -6,7 +7,7 @@ import {} from './quickInsertListView.js';
6
7
  import QuickInsertView from './quickInsertView.js';
7
8
  /**
8
9
  * Opens a menu with a search field and the elements allowed at the selection, on Alt+Enter (Option+Enter on macOS; see
9
- * {@link QuickInsertConfig.keystroke}). Choosing an element inserts it with the `quickInsert` command.
10
+ * {@link ElementQuickInsertConfig.keystroke}). Choosing an element inserts it with the `quickInsert` command.
10
11
  *
11
12
  * The menu is shown by the `ElementMenu` plugin. The `quickInsertBefore` and `quickInsertAfter` commands (see
12
13
  * {@link QuickInsertPositionCommand}) open it for the position before or after an element; list them in the
@@ -14,23 +15,23 @@ import QuickInsertView from './quickInsertView.js';
14
15
  *
15
16
  * The menu closes when the document changes while it is open, so it never inserts at an outdated position.
16
17
  */
17
- export default class QuickInsert extends Plugin {
18
+ export default class ElementQuickInsert extends Plugin {
18
19
  static get requires() {
19
20
  return [ElementMenu];
20
21
  }
21
22
  static get pluginName() {
22
- return 'QuickInsert';
23
+ return 'ElementQuickInsert';
23
24
  }
24
25
  constructor(editor) {
25
26
  super(editor);
26
- editor.config.define('quickInsert', { labels: {}, exclude: [], keystroke: 'Alt+Enter' });
27
+ editor.config.define('elementQuickInsert', { labels: {}, exclude: [], keystroke: 'Alt+Enter' });
27
28
  }
28
29
  init() {
29
30
  const editor = this.editor;
30
- const keystroke = editor.config.get('quickInsert')?.keystroke;
31
+ const keystroke = editor.config.get('elementQuickInsert')?.keystroke;
31
32
  editor.commands.add('quickInsert', new QuickInsertCommand(editor));
32
- editor.commands.add('quickInsertBefore', new QuickInsertPositionCommand(editor, 'before'));
33
- editor.commands.add('quickInsertAfter', new QuickInsertPositionCommand(editor, 'after'));
33
+ editor.commands.add('quickInsertBefore', new QuickInsertPositionCommand(editor, 'before', this));
34
+ editor.commands.add('quickInsertAfter', new QuickInsertPositionCommand(editor, 'after', this));
34
35
  if (keystroke) {
35
36
  editor.keystrokes.set(keystroke, (data, cancel) => {
36
37
  if (this.open()) {
@@ -47,7 +48,7 @@ export default class QuickInsert extends Plugin {
47
48
  * selection), with their labels.
48
49
  */
49
50
  getItems(elementOrPosition) {
50
- const config = this.editor.config.get('quickInsert');
51
+ const config = this.editor.config.get('elementQuickInsert');
51
52
  const labels = config?.labels ?? {};
52
53
  const command = this.editor.commands.get('quickInsert');
53
54
  return (command?.getAllowedElements(elementOrPosition, config?.exclude) ?? []).map(name => ({
@@ -55,6 +56,14 @@ export default class QuickInsert extends Plugin {
55
56
  label: labels[name] ?? name
56
57
  }));
57
58
  }
59
+ /**
60
+ * Whether an element can be inserted at the target (a position, the position before an element, or the selection),
61
+ * as {@link getItems} lists them: it stops at the first one, e.g. for whether a command is enabled.
62
+ */
63
+ hasItems(elementOrPosition) {
64
+ const command = this.editor.commands.get('quickInsert');
65
+ return !!command?.hasAllowedElements(elementOrPosition, this.editor.config.get('elementQuickInsert')?.exclude);
66
+ }
58
67
  /**
59
68
  * Opens the menu for inserting at the target (a position, the position before an element, or the selection), next
60
69
  * to the given DOM target. By default, the menu is next to the element, or the selection.
@@ -66,7 +75,7 @@ export default class QuickInsert extends Plugin {
66
75
  const editor = this.editor;
67
76
  const command = editor.commands.get('quickInsert');
68
77
  const position = command?.getInsertPosition(elementOrPosition);
69
- const menuTarget = domTarget ?? this._getDomTarget(elementOrPosition);
78
+ const menuTarget = domTarget ?? getDomTarget(editor, elementOrPosition);
70
79
  if (!command || !position || !menuTarget || !command.getState(position).isEnabled) {
71
80
  return false;
72
81
  }
@@ -83,24 +92,5 @@ export default class QuickInsert extends Plugin {
83
92
  });
84
93
  return true;
85
94
  }
86
- /**
87
- * Returns the DOM element of the element, or the DOM range of the selection.
88
- */
89
- _getDomTarget(elementOrPosition) {
90
- const editing = this.editor.editing;
91
- if (elementOrPosition && !elementOrPosition.is('position')) {
92
- return this._getDomElement(elementOrPosition);
93
- }
94
- const viewRange = elementOrPosition
95
- ? editing.view.createRange(editing.mapper.toViewPosition(elementOrPosition))
96
- : editing.view.document.selection.getFirstRange();
97
- return viewRange && editing.view.domConverter.viewRangeToDom(viewRange);
98
- }
99
- _getDomElement(element) {
100
- const editing = this.editor.editing;
101
- const viewElement = editing.mapper.toViewElement(element);
102
- const domElement = viewElement && editing.view.domConverter.mapViewToDom(viewElement);
103
- return domElement instanceof HTMLElement ? domElement : null;
104
- }
105
95
  }
106
- //# sourceMappingURL=quickInsert.js.map
96
+ //# sourceMappingURL=elementQuickInsert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elementQuickInsert.js","sourceRoot":"","sources":["../../src/quickInsert/elementQuickInsert.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,15 @@
1
1
  import { type Editor, type ModelPosition } from 'ckeditor5';
2
2
  import { ElementOrPositionCommand, type ElementOrPosition } from 'ckeditor5-elements-core';
3
3
  /**
4
- * Inserts an element by its model name at a position, or opens the quick insert menu for that position.
4
+ * Inserts an element by its model name at a position: what the quick insert menu does, when an element is chosen. The
5
+ * menu itself is opened by the `ElementQuickInsert` plugin, with its `open()`.
5
6
  *
6
7
  * The target comes first, as in every {@link ElementOrPositionCommand}: a position, an element (meaning the position
7
8
  * before it), or none (the selection).
8
9
  *
9
10
  * ```ts
10
11
  * editor.execute('quickInsert', position, 'heading1'); // Inserts a heading at the position.
11
- * editor.execute('quickInsert'); // Opens the quick insert menu at the selection.
12
+ * editor.execute('quickInsert', undefined, 'softBreak'); // Inserts a line break at the selection.
12
13
  * ```
13
14
  *
14
15
  * Only elements that the schema allows at exactly that position are inserted (see {@link getAllowedElements}):
@@ -24,15 +25,23 @@ export default class QuickInsertCommand extends ElementOrPositionCommand {
24
25
  * were registered. Generic items (such as `$text` or `$block`) and the excluded names are skipped.
25
26
  */
26
27
  getAllowedElements(elementOrPosition?: ElementOrPosition, exclude?: readonly string[]): string[];
28
+ /**
29
+ * Whether an element is allowed at exactly the position (or the selection), as {@link getAllowedElements} returns
30
+ * them: it stops at the first one.
31
+ */
32
+ hasAllowedElements(elementOrPosition?: ElementOrPosition, exclude?: readonly string[]): boolean;
27
33
  /**
28
34
  * Returns the position where elements are inserted for the target: the position, the position before the element,
29
35
  * or the selection.
30
36
  */
31
37
  getInsertPosition(elementOrPosition?: ElementOrPosition): ModelPosition | null;
32
38
  /**
33
- * Inserts the element named `name` at the target, when the schema allows it there. Without a name, opens the quick
34
- * insert menu for the target (requires the `QuickInsert` plugin).
39
+ * Inserts the element named `name` at the target, when the schema allows it there.
40
+ */
41
+ execute(elementOrPosition: ElementOrPosition | undefined, name: string): void;
42
+ /**
43
+ * Yields the names of the elements allowed at exactly the position (or the selection), one by one.
35
44
  */
36
- execute(elementOrPosition?: ElementOrPosition, name?: string): void;
45
+ private _getAllowedElements;
37
46
  }
38
47
  //# sourceMappingURL=quickInsertCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"quickInsertCommand.d.ts","sourceRoot":"","sources":["../../src/quickInsert/quickInsertCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAoB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG7G;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,wBAAwB;gBAC3D,MAAM,EAAE,MAAM;IAO1B;;;OAGG;IACI,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,EAAE;IAc3G;;;OAGG;IACI,iBAAiB,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,aAAa,GAAG,IAAI;IAIrF;;;OAGG;IACa,OAAO,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;CAyBnF"}
1
+ {"version":3,"file":"quickInsertCommand.d.ts","sourceRoot":"","sources":["../../src/quickInsert/quickInsertCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAoB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG7G;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,wBAAwB;gBAC3D,MAAM,EAAE,MAAM;IAO1B;;;OAGG;IACI,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,EAAE;IAI3G;;;OAGG;IACI,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO;IAI1G;;;OAGG;IACI,iBAAiB,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,aAAa,GAAG,IAAI;IAIrF;;OAEG;IACa,OAAO,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAgB7F;;OAEG;IACH,OAAO,CAAE,mBAAmB;CAmB5B"}
@@ -2,14 +2,15 @@ import {} from 'ckeditor5';
2
2
  import { ElementOrPositionCommand, selectNewElement } from 'ckeditor5-elements-core';
3
3
  import { insertIcon } from './icons.js';
4
4
  /**
5
- * Inserts an element by its model name at a position, or opens the quick insert menu for that position.
5
+ * Inserts an element by its model name at a position: what the quick insert menu does, when an element is chosen. The
6
+ * menu itself is opened by the `ElementQuickInsert` plugin, with its `open()`.
6
7
  *
7
8
  * The target comes first, as in every {@link ElementOrPositionCommand}: a position, an element (meaning the position
8
9
  * before it), or none (the selection).
9
10
  *
10
11
  * ```ts
11
12
  * editor.execute('quickInsert', position, 'heading1'); // Inserts a heading at the position.
12
- * editor.execute('quickInsert'); // Opens the quick insert menu at the selection.
13
+ * editor.execute('quickInsert', undefined, 'softBreak'); // Inserts a line break at the selection.
13
14
  * ```
14
15
  *
15
16
  * Only elements that the schema allows at exactly that position are inserted (see {@link getAllowedElements}):
@@ -29,12 +30,14 @@ export default class QuickInsertCommand extends ElementOrPositionCommand {
29
30
  * were registered. Generic items (such as `$text` or `$block`) and the excluded names are skipped.
30
31
  */
31
32
  getAllowedElements(elementOrPosition, exclude = []) {
32
- const target = this._getPosition(elementOrPosition);
33
- if (!target) {
34
- return [];
35
- }
36
- const schema = this.editor.model.schema;
37
- return Object.keys(schema.getDefinitions()).filter(name => !name.startsWith('$') && !exclude.includes(name) && schema.checkChild(target, name));
33
+ return Array.from(this._getAllowedElements(elementOrPosition, exclude));
34
+ }
35
+ /**
36
+ * Whether an element is allowed at exactly the position (or the selection), as {@link getAllowedElements} returns
37
+ * them: it stops at the first one.
38
+ */
39
+ hasAllowedElements(elementOrPosition, exclude = []) {
40
+ return !this._getAllowedElements(elementOrPosition, exclude).next().done;
38
41
  }
39
42
  /**
40
43
  * Returns the position where elements are inserted for the target: the position, the position before the element,
@@ -44,17 +47,9 @@ export default class QuickInsertCommand extends ElementOrPositionCommand {
44
47
  return this._getPosition(elementOrPosition);
45
48
  }
46
49
  /**
47
- * Inserts the element named `name` at the target, when the schema allows it there. Without a name, opens the quick
48
- * insert menu for the target (requires the `QuickInsert` plugin).
50
+ * Inserts the element named `name` at the target, when the schema allows it there.
49
51
  */
50
52
  execute(elementOrPosition, name) {
51
- if (name === undefined) {
52
- const plugins = this.editor.plugins;
53
- if (plugins.has('QuickInsert')) {
54
- plugins.get('QuickInsert').open(elementOrPosition);
55
- }
56
- return;
57
- }
58
53
  const model = this.editor.model;
59
54
  const target = this._getPosition(elementOrPosition);
60
55
  if (!target || !model.canEditAt(target) || !model.schema.checkChild(target, name)) {
@@ -66,5 +61,21 @@ export default class QuickInsertCommand extends ElementOrPositionCommand {
66
61
  selectNewElement(writer, element);
67
62
  });
68
63
  }
64
+ /**
65
+ * Yields the names of the elements allowed at exactly the position (or the selection), one by one.
66
+ */
67
+ *_getAllowedElements(elementOrPosition, exclude) {
68
+ const target = this._getPosition(elementOrPosition);
69
+ if (!target) {
70
+ return;
71
+ }
72
+ const schema = this.editor.model.schema;
73
+ const excluded = new Set(exclude);
74
+ for (const name of Object.keys(schema.getDefinitions())) {
75
+ if (!name.startsWith('$') && !excluded.has(name) && schema.checkChild(target, name)) {
76
+ yield name;
77
+ }
78
+ }
79
+ }
69
80
  }
70
81
  //# sourceMappingURL=quickInsertCommand.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"quickInsertCommand.js","sourceRoot":"","sources":["../../src/quickInsert/quickInsertCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAA0B,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,wBAAwB;IACvE,YAAY,MAAc;QACzB,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACxB,CAAC;IAED;;;OAGG;IACI,kBAAkB,CAAC,iBAAqC,EAAE,UAA6B,EAAE;QAC/F,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACX,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QAExC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,MAAM,CACjD,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAC3F,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,iBAAiB,CAAC,iBAAqC;QAC7D,OAAO,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACa,OAAO,CAAC,iBAAqC,EAAE,IAAa;QAC3E,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;YAEpC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACpD,CAAC;YAED,OAAO;QACR,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YACnF,OAAO;QACR,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACrB,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAE3C,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/B,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACJ,CAAC;CACD"}
1
+ {"version":3,"file":"quickInsertCommand.js","sourceRoot":"","sources":["../../src/quickInsert/quickInsertCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAA0B,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,wBAAwB;IACvE,YAAY,MAAc;QACzB,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACxB,CAAC;IAED;;;OAGG;IACI,kBAAkB,CAAC,iBAAqC,EAAE,UAA6B,EAAE;QAC/F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,CAAC;IACzE,CAAC;IAED;;;OAGG;IACI,kBAAkB,CAAC,iBAAqC,EAAE,UAA6B,EAAE;QAC/F,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC;IAC1E,CAAC;IAED;;;OAGG;IACI,iBAAiB,CAAC,iBAAqC;QAC7D,OAAO,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACa,OAAO,CAAC,iBAAgD,EAAE,IAAY;QACrF,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YACnF,OAAO;QACR,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACrB,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAE3C,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/B,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,CAAC,mBAAmB,CAC3B,iBAAgD,EAChD,OAA0B;QAE1B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO;QACR,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAElC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;gBACrF,MAAM,IAAI,CAAC;YACZ,CAAC;QACF,CAAC;IACF,CAAC;CACD"}
@@ -1,5 +1,6 @@
1
1
  import { type Editor } from 'ckeditor5';
2
2
  import { ElementOrPositionCommand, type ElementOrPosition } from 'ckeditor5-elements-core';
3
+ import type ElementQuickInsert from './elementQuickInsert.js';
3
4
  /**
4
5
  * Where the quick insert menu inserts, relative to the element.
5
6
  */
@@ -10,14 +11,18 @@ export type QuickInsertPlacement = 'before' | 'after';
10
11
  * The element is the given one, the parent of the given position, or the selected element or the parent of the
11
12
  * selection (see {@link ElementOrPositionCommand}). Enabled when something can be inserted at that position.
12
13
  *
13
- * Requires the `QuickInsert` plugin, which registers it as `quickInsertBefore` and `quickInsertAfter`.
14
+ * The `ElementQuickInsert` plugin registers it as `quickInsertBefore` and `quickInsertAfter`, for its menu.
14
15
  */
15
16
  export default class QuickInsertPositionCommand extends ElementOrPositionCommand {
16
17
  /**
17
18
  * Where the quick insert menu inserts, relative to the element.
18
19
  */
19
20
  readonly placement: QuickInsertPlacement;
20
- constructor(editor: Editor, placement: QuickInsertPlacement);
21
+ /**
22
+ * The plugin whose menu the command opens.
23
+ */
24
+ private readonly _quickInsert;
25
+ constructor(editor: Editor, placement: QuickInsertPlacement, quickInsert: ElementQuickInsert);
21
26
  /**
22
27
  * Opens the quick insert menu for the position before or after the element, next to the element.
23
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"quickInsertPositionCommand.d.ts","sourceRoot":"","sources":["../../src/quickInsert/quickInsertPositionCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAsB,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG3F;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,wBAAwB;IAC/E;;OAEG;IACH,SAAgB,SAAS,EAAE,oBAAoB,CAAC;gBAEpC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB;IAQ3D;;OAEG;IACa,OAAO,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,IAAI;cAejD,aAAa,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,OAAO;IAYhF,OAAO,CAAC,kBAAkB;CAU1B"}
1
+ {"version":3,"file":"quickInsertPositionCommand.d.ts","sourceRoot":"","sources":["../../src/quickInsert/quickInsertPositionCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAsB,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE3F,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAC;AAG9D;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,wBAAwB;IAC/E;;OAEG;IACH,SAAgB,SAAS,EAAE,oBAAoB,CAAC;IAEhD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;gBAEtC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,EAAE,WAAW,EAAE,kBAAkB;IAS5F;;OAEG;IACa,OAAO,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,IAAI;cASjD,aAAa,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,OAAO;IAMhF,OAAO,CAAC,kBAAkB;CAU1B"}
@@ -1,5 +1,6 @@
1
1
  import {} from 'ckeditor5';
2
2
  import { ElementOrPositionCommand } from 'ckeditor5-elements-core';
3
+ import { getDomTarget } from '../domTarget.js';
3
4
  import { insertAfterIcon, insertBeforeIcon } from './icons.js';
4
5
  /**
5
6
  * Opens the quick insert menu for the position before or after an element, next to that element.
@@ -7,16 +8,21 @@ import { insertAfterIcon, insertBeforeIcon } from './icons.js';
7
8
  * The element is the given one, the parent of the given position, or the selected element or the parent of the
8
9
  * selection (see {@link ElementOrPositionCommand}). Enabled when something can be inserted at that position.
9
10
  *
10
- * Requires the `QuickInsert` plugin, which registers it as `quickInsertBefore` and `quickInsertAfter`.
11
+ * The `ElementQuickInsert` plugin registers it as `quickInsertBefore` and `quickInsertAfter`, for its menu.
11
12
  */
12
13
  export default class QuickInsertPositionCommand extends ElementOrPositionCommand {
13
14
  /**
14
15
  * Where the quick insert menu inserts, relative to the element.
15
16
  */
16
17
  placement;
17
- constructor(editor, placement) {
18
+ /**
19
+ * The plugin whose menu the command opens.
20
+ */
21
+ _quickInsert;
22
+ constructor(editor, placement, quickInsert) {
18
23
  super(editor);
19
24
  this.placement = placement;
25
+ this._quickInsert = quickInsert;
20
26
  this.title = placement === 'before' ? editor.t('Insert before') : editor.t('Insert after');
21
27
  this.icon = placement === 'before' ? insertBeforeIcon : insertAfterIcon;
22
28
  }
@@ -24,23 +30,15 @@ export default class QuickInsertPositionCommand extends ElementOrPositionCommand
24
30
  * Opens the quick insert menu for the position before or after the element, next to the element.
25
31
  */
26
32
  execute(elementOrPosition) {
27
- const editor = this.editor;
28
33
  const element = this._getElement(elementOrPosition);
29
34
  const position = this._getInsertPosition(elementOrPosition);
30
- if (!element || !position) {
31
- return;
35
+ if (element && position) {
36
+ this._quickInsert.open(position, getDomTarget(this.editor, element) ?? undefined);
32
37
  }
33
- const viewElement = editor.editing.mapper.toViewElement(element);
34
- const domElement = viewElement && editor.editing.view.domConverter.mapViewToDom(viewElement);
35
- editor.plugins.get('QuickInsert').open(position, domElement ?? undefined);
36
38
  }
37
39
  _isEnabledFor(elementOrPosition) {
38
40
  const position = this._getInsertPosition(elementOrPosition);
39
- const plugins = this.editor.plugins;
40
- return (!!position &&
41
- this.editor.model.canEditAt(position) &&
42
- plugins.has('QuickInsert') &&
43
- plugins.get('QuickInsert').getItems(position).length > 0);
41
+ return !!position && this.editor.model.canEditAt(position) && this._quickInsert.hasItems(position);
44
42
  }
45
43
  _getInsertPosition(elementOrPosition) {
46
44
  const element = this._getElement(elementOrPosition);
@@ -1 +1 @@
1
- {"version":3,"file":"quickInsertPositionCommand.js","sourceRoot":"","sources":["../../src/quickInsert/quickInsertPositionCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAA0B,MAAM,yBAAyB,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAO/D;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,wBAAwB;IAC/E;;OAEG;IACa,SAAS,CAAuB;IAEhD,YAAY,MAAc,EAAE,SAA+B;QAC1D,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAC3F,IAAI,CAAC,IAAI,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC;IACzE,CAAC;IAED;;OAEG;IACa,OAAO,CAAC,iBAAqC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QAE5D,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3B,OAAO;QACR,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,WAAW,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAE7F,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,IAAI,SAAS,CAAC,CAAC;IAC3E,CAAC;IAEkB,aAAa,CAAC,iBAAqC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QAEpC,OAAO,CACN,CAAC,CAAC,QAAQ;YACV,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CACxD,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,iBAAqC;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC/G,CAAC;CACD"}
1
+ {"version":3,"file":"quickInsertPositionCommand.js","sourceRoot":"","sources":["../../src/quickInsert/quickInsertPositionCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAA0B,MAAM,yBAAyB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAO/D;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,wBAAwB;IAC/E;;OAEG;IACa,SAAS,CAAuB;IAEhD;;OAEG;IACc,YAAY,CAAqB;IAElD,YAAY,MAAc,EAAE,SAA+B,EAAE,WAA+B;QAC3F,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAC3F,IAAI,CAAC,IAAI,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC;IACzE,CAAC;IAED;;OAEG;IACa,OAAO,CAAC,iBAAqC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QAE5D,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,SAAS,CAAC,CAAC;QACnF,CAAC;IACF,CAAC;IAEkB,aAAa,CAAC,iBAAqC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QAE5D,OAAO,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpG,CAAC;IAEO,kBAAkB,CAAC,iBAAqC;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC/G,CAAC;CACD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ckeditor5-elements-menu",
3
- "version": "49.0.0-alpha.4",
3
+ "version": "49.0.0",
4
4
  "description": "Element menus for CKEditor 5: the menu of an element, built from commands, and the element context menu, breadcrumbs and quick insert that open it.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -41,7 +41,10 @@
41
41
  "*.css"
42
42
  ],
43
43
  "dependencies": {
44
- "ckeditor5-elements-core": "49.0.0-alpha.4"
44
+ "ckeditor5-elements-core": "49.0.0"
45
+ },
46
+ "devDependencies": {
47
+ "ckeditor5-elements-actions": "49.0.0"
45
48
  },
46
49
  "peerDependencies": {
47
50
  "ckeditor5": "^49.0.0"
@@ -1,12 +1,12 @@
1
1
  import type {
2
- Breadcrumbs,
3
- BreadcrumbsConfig,
2
+ ElementBreadcrumbs,
3
+ ElementBreadcrumbsConfig,
4
4
  ElementContextMenu,
5
5
  ElementMenu,
6
6
  ElementMenuConfig,
7
- QuickInsert,
7
+ ElementQuickInsert,
8
8
  QuickInsertCommand,
9
- QuickInsertConfig,
9
+ ElementQuickInsertConfig,
10
10
  QuickInsertPositionCommand
11
11
  } from './index.js';
12
12
 
@@ -14,8 +14,8 @@ declare module 'ckeditor5' {
14
14
  interface PluginsMap {
15
15
  [ElementMenu.pluginName]: ElementMenu;
16
16
  [ElementContextMenu.pluginName]: ElementContextMenu;
17
- [Breadcrumbs.pluginName]: Breadcrumbs;
18
- [QuickInsert.pluginName]: QuickInsert;
17
+ [ElementBreadcrumbs.pluginName]: ElementBreadcrumbs;
18
+ [ElementQuickInsert.pluginName]: ElementQuickInsert;
19
19
  }
20
20
 
21
21
  interface CommandsMap {
@@ -32,13 +32,13 @@ declare module 'ckeditor5' {
32
32
  elementContextMenu?: ElementMenuConfig;
33
33
 
34
34
  /**
35
- * The configuration of the {@link Breadcrumbs} plugin.
35
+ * The configuration of the {@link ElementBreadcrumbs} plugin.
36
36
  */
37
- breadcrumbs?: BreadcrumbsConfig;
37
+ elementBreadcrumbs?: ElementBreadcrumbsConfig;
38
38
 
39
39
  /**
40
- * The configuration of the {@link QuickInsert} plugin.
40
+ * The configuration of the {@link ElementQuickInsert} plugin.
41
41
  */
42
- quickInsert?: QuickInsertConfig;
42
+ elementQuickInsert?: ElementQuickInsertConfig;
43
43
  }
44
44
  }
@@ -24,9 +24,9 @@ const SLOW_CONVERSION_TIME = 10;
24
24
  const THROTTLE_TIME = 250;
25
25
 
26
26
  /**
27
- * The configuration of the {@link Breadcrumbs} plugin.
27
+ * The configuration of the {@link ElementBreadcrumbs} plugin.
28
28
  */
29
- export interface BreadcrumbsConfig {
29
+ export interface ElementBreadcrumbsConfig {
30
30
  /**
31
31
  * Returns the items of the menu that opens when a breadcrumb is clicked, for the element of the breadcrumb: the
32
32
  * same items as in the `elementContextMenu` option (commands, submenus and `'|'` separators), so one callback can
@@ -48,18 +48,19 @@ interface DataView {
48
48
  * Shows the data view structure at the current selection (the elements of the editor data, as in `getData()`), e.g.
49
49
  * `aside.note › p`, `ul › li` or `figure.table › table › tbody › tr › td`.
50
50
  *
51
- * Text attributes such as `<strong>` are skipped. The selected element, e.g. an image, is the innermost item.
51
+ * Inline elements are items, as any element. CKEditor's text attributes, marks on the text such as its `<strong>`, are
52
+ * skipped. The selected element, e.g. an image, is the innermost item.
52
53
  *
53
54
  * Place them in a toolbar as the `breadcrumbs` component, or anywhere else using a view from {@link createView}.
54
55
  *
55
- * Clicking is configured only by the `breadcrumbs.menu` editor config option (see {@link BreadcrumbsConfig}): with it,
56
+ * Clicking is configured only by the `elementBreadcrumbs.menu` editor config option (see {@link ElementBreadcrumbsConfig}): with it,
56
57
  * the items are buttons that open the menu of their element, with `ElementMenu`, as the context menu does; without it,
57
58
  * they are labels.
58
59
  *
59
60
  * The data view is converted again only when elements change, not when typing or moving the cursor. For a large
60
61
  * document, that happens at most every 250 ms.
61
62
  */
62
- export default class Breadcrumbs extends Plugin {
63
+ export default class ElementBreadcrumbs extends Plugin {
63
64
  /**
64
65
  * The elements at the current selection, from the outermost to the innermost one.
65
66
  *
@@ -72,8 +73,8 @@ export default class Breadcrumbs extends Plugin {
72
73
  private _isConversionSlow = false;
73
74
  private _conversionTimeout: ReturnType<typeof setTimeout> | null = null;
74
75
 
75
- public static get pluginName(): 'Breadcrumbs' {
76
- return 'Breadcrumbs' as const;
76
+ public static get pluginName(): 'ElementBreadcrumbs' {
77
+ return 'ElementBreadcrumbs' as const;
77
78
  }
78
79
 
79
80
  public static get requires(): readonly [typeof ElementMenu] {
@@ -109,7 +110,7 @@ export default class Breadcrumbs extends Plugin {
109
110
  * Creates a breadcrumbs view that follows {@link items}.
110
111
  */
111
112
  public createView(locale: Locale = this.editor.locale): BreadcrumbsView {
112
- const isClickable = typeof this.editor.config.get('breadcrumbs')?.menu === 'function';
113
+ const isClickable = typeof this.editor.config.get('elementBreadcrumbs')?.menu === 'function';
113
114
  const view = new BreadcrumbsView(locale, { isClickable });
114
115
 
115
116
  view.setItems(this.items);
@@ -234,7 +235,7 @@ export default class Breadcrumbs extends Plugin {
234
235
  }
235
236
 
236
237
  private _openMenu(item: BreadcrumbItemView): void {
237
- const menuItems = this.editor.config.get('breadcrumbs')?.menu;
238
+ const menuItems = this.editor.config.get('elementBreadcrumbs')?.menu;
238
239
  const element = item.modelElement;
239
240
 
240
241
  if (!menuItems || !item.element || !element || !isInDocument(element)) {
@@ -1,5 +1,6 @@
1
1
  import { Plugin, type ModelElement, type RectSource, type ViewElement } from 'ckeditor5';
2
- import { getElementAtSelection, isInDocument } from 'ckeditor5-elements-core';
2
+ import { getElementAtSelection, getElementsAround, isInDocument } from 'ckeditor5-elements-core';
3
+ import { getDomTarget } from '../domTarget.js';
3
4
  import ElementMenu from '../elementMenu.js';
4
5
  import ContextMenuObserver, { type ViewDocumentContextMenuEvent } from './contextMenuObserver.js';
5
6
 
@@ -80,17 +81,10 @@ export default class ElementContextMenu extends Plugin {
80
81
  * Returns `false` when there is no such element or no items.
81
82
  */
82
83
  public openAtSelection(): boolean {
83
- const editing = this.editor.editing;
84
- const selection = this.editor.model.document.selection;
85
- const selectedElement = selection.getSelectedElement();
86
- const element = getElementAtSelection(selection);
87
- const viewElement = selectedElement && editing.mapper.toViewElement(selectedElement);
88
- const viewRange = editing.view.document.selection.getFirstRange();
89
- const target = viewElement
90
- ? editing.view.domConverter.mapViewToDom(viewElement)
91
- : viewRange && editing.view.domConverter.viewRangeToDom(viewRange);
92
-
93
- if (!element || !isInDocument(element) || !(target instanceof HTMLElement || target instanceof Range)) {
84
+ const element = getElementAtSelection(this.editor.model.document.selection);
85
+ const target = getDomTarget(this.editor);
86
+
87
+ if (!element || !isInDocument(element) || !target) {
94
88
  return false;
95
89
  }
96
90
 
@@ -101,14 +95,8 @@ export default class ElementContextMenu extends Plugin {
101
95
  * Returns the closest model element mapped to the given view element or its ancestors, skipping the root.
102
96
  */
103
97
  public getModelElement(viewElement: ViewElement): ModelElement | null {
104
- const mapper = this.editor.editing.mapper;
105
-
106
- for (let node: ViewElement | null = viewElement; node; node = node.parent?.is('element') ? node.parent : null) {
107
- const element = mapper.toModelElement(node);
108
-
109
- if (element) {
110
- return element.is('rootElement') ? null : element;
111
- }
98
+ for (const { element } of getElementsAround(this.editor.editing.mapper, viewElement)) {
99
+ return element;
112
100
  }
113
101
 
114
102
  return null;
@@ -0,0 +1,27 @@
1
+ import { ModelPosition, type Editor } from 'ckeditor5';
2
+ import type { ElementOrPosition } from 'ckeditor5-elements-core';
3
+
4
+ /**
5
+ * Returns what a menu for the target is shown next to: the DOM element of an element, or the DOM range of a position.
6
+ * Without a target, the ones of the selection: its selected element, or its range. `null` when it is not rendered.
7
+ */
8
+ export function getDomTarget(editor: Editor, target?: ElementOrPosition): HTMLElement | Range | null {
9
+ const { mapper, view } = editor.editing;
10
+
11
+ if (target instanceof ModelPosition) {
12
+ return view.domConverter.viewRangeToDom(view.createRange(mapper.toViewPosition(target)));
13
+ }
14
+
15
+ const element = target ?? editor.model.document.selection.getSelectedElement();
16
+
17
+ if (element) {
18
+ const viewElement = mapper.toViewElement(element);
19
+ const domElement = viewElement && view.domConverter.mapViewToDom(viewElement);
20
+
21
+ return domElement instanceof HTMLElement ? domElement : null;
22
+ }
23
+
24
+ const viewRange = view.document.selection.getFirstRange();
25
+
26
+ return viewRange ? view.domConverter.viewRangeToDom(viewRange) : null;
27
+ }