ckeditor5-elements-core 49.0.0-alpha.0 → 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.
@@ -1 +1 @@
1
- {"version":3,"file":"elementMenu.d.ts","sourceRoot":"","sources":["../src/elementMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EAGjB,YAAY,EACZ,MAAM,EAEN,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,MAAM,WAAW,CAAC;AAEnB,OAAO,wBAAwB,MAAM,+BAA+B,CAAC;AAGrE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,EAAE,CAAC,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,wBAAwB,GAAG,cAAc,GAAG,GAAG,CAAC;AAE9E;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;AAElH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAE3B;;OAEG;IACH,aAAa,CAAC,EAAE;QAAE,KAAK,IAAI,IAAI,CAAA;KAAE,CAAC;IAElC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,MAAM;IAC9C;;OAEG;IACI,IAAI,EAAE,aAAa,GAAG,IAAI,CAAQ;IAEzC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,OAAO,CAA6B;IAE5C,WAAkB,QAAQ,IAAI,SAAS,CAAC,OAAO,iBAAiB,EAAE,OAAO,YAAY,CAAC,CAGrF;IAED,WAAkB,UAAU,IAAI,aAAa,CAE5C;IAEM,IAAI,IAAI,IAAI;IAQnB;;;;;OAKG;IACI,IAAI,CACV,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,iBAAiB,EACzB,EAAE,KAAqC,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,GAAE,sBAA2B,GAC5F,OAAO;IAmBV;;;OAGG;IACI,IAAI,CACV,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,UAAU,EAClB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,GAAE,sBAA2B,GAChE,IAAI;IAkDP;;OAEG;IACI,IAAI,IAAI,IAAI;IAuBH,OAAO,IAAI,IAAI;IAK/B,OAAO,KAAK,QAAQ,GAEnB;CACD"}
1
+ {"version":3,"file":"elementMenu.d.ts","sourceRoot":"","sources":["../src/elementMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EAGjB,YAAY,EACZ,MAAM,EAEN,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,MAAM,WAAW,CAAC;AAEnB,OAAO,wBAAwB,MAAM,+BAA+B,CAAC;AAGrE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,EAAE,CAAC,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,wBAAwB,GAAG,cAAc,GAAG,GAAG,CAAC;AAE9E;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;AAElH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAE3B;;OAEG;IACH,aAAa,CAAC,EAAE;QAAE,KAAK,IAAI,IAAI,CAAA;KAAE,CAAC;IAElC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,MAAM;IAC9C;;OAEG;IACI,IAAI,EAAE,aAAa,GAAG,IAAI,CAAQ;IAEzC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,OAAO,CAA6B;IAE5C,WAAkB,QAAQ,IAAI,SAAS,CAAC,OAAO,iBAAiB,EAAE,OAAO,YAAY,CAAC,CAGrF;IAED,WAAkB,UAAU,IAAI,aAAa,CAE5C;IAEM,IAAI,IAAI,IAAI;IAQnB;;;;;OAKG;IACI,IAAI,CACV,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,iBAAiB,EACzB,EAAE,KAAqC,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,GAAE,sBAA2B,GAC5F,OAAO;IAmBV;;;OAGG;IACI,IAAI,CACV,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,UAAU,EAClB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,GAAE,sBAA2B,GAChE,IAAI;IAqDP;;OAEG;IACI,IAAI,IAAI,IAAI;IAuBH,OAAO,IAAI,IAAI;IAK/B,OAAO,KAAK,QAAQ,GAEnB;CACD"}
@@ -80,7 +80,10 @@ export default class ElementMenu extends Plugin {
80
80
  view,
81
81
  position: { target },
82
82
  withArrow: false,
83
- singleViewMode: true
83
+ singleViewMode: true,
84
+ // Views that other plugins add to the balloon meanwhile (e.g. an element toolbar, when the selection moves
85
+ // into its element) go to their own stack, so they do not cover the menu.
86
+ stackId: 'elementMenu'
84
87
  });
85
88
  const keystrokes = new KeystrokeHandler();
86
89
  // Esc in a nested menu closes only that menu.
@@ -1 +1 @@
1
- {"version":3,"file":"elementMenu.js","sourceRoot":"","sources":["../src/elementMenu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"elementMenu.js","sourceRoot":"","sources":["../src/elementMenu.ts"],"names":[],"mappings":"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"}
@@ -10,11 +10,17 @@ export interface ElementOrPositionButtonViewOptions {
10
10
  */
11
11
  withText?: boolean;
12
12
  /**
13
- * The position or element the button acts on. Without it, the button follows the command state for the selection
14
- * and executes the command for the selection.
13
+ * The position or element the button acts on, or a function that returns it, e.g. the element of a floating
14
+ * toolbar, which changes as the selection moves. The function is called whenever the button updates or is clicked;
15
+ * when it returns `null`, the button is disabled. Without a target, the button follows the command state for the
16
+ * selection and executes the command for the selection.
15
17
  */
16
- target?: ElementOrPosition;
18
+ target?: ElementOrPositionTarget;
17
19
  }
20
+ /**
21
+ * The target of a button: a position or an element, or a function that returns one (or `null`).
22
+ */
23
+ export type ElementOrPositionTarget = ElementOrPosition | (() => ElementOrPosition | null);
18
24
  /**
19
25
  * A button that reflects an {@link ElementOrPositionCommand} and executes it when clicked.
20
26
  *
@@ -34,7 +40,7 @@ export default class ElementOrPositionButtonView extends ButtonView {
34
40
  /**
35
41
  * The position or element the button acts on, if any.
36
42
  */
37
- readonly target: ElementOrPosition | undefined;
43
+ readonly target: ElementOrPositionTarget | undefined;
38
44
  constructor(locale: Locale | undefined, command: ElementOrPositionCommand, options?: ElementOrPositionButtonViewOptions);
39
45
  }
40
46
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"elementOrPositionButtonView.d.ts","sourceRoot":"","sources":["../src/elementOrPositionButtonView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,KAAK,wBAAwB,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,kCAAkC;IAClD;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,OAAO,2BAA4B,SAAQ,UAAU;IAClE;;OAEG;IACH,SAAgB,OAAO,EAAE,wBAAwB,CAAC;IAElD;;OAEG;IACH,SAAgB,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC;gBAGrD,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,wBAAwB,EACjC,OAAO,GAAE,kCAAuC;CASjD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,wBAAwB,EACjC,EAAE,QAAgB,EAAE,MAAM,EAAE,GAAE,kCAAuC,GACnE,IAAI,CAwCN"}
1
+ {"version":3,"file":"elementOrPositionButtonView.d.ts","sourceRoot":"","sources":["../src/elementOrPositionButtonView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,KAAK,wBAAwB,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,kCAAkC;IAClD;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,uBAAuB,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,CAAC;AAE3F;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,OAAO,2BAA4B,SAAQ,UAAU;IAClE;;OAEG;IACH,SAAgB,OAAO,EAAE,wBAAwB,CAAC;IAElD;;OAEG;IACH,SAAgB,MAAM,EAAE,uBAAuB,GAAG,SAAS,CAAC;gBAG3D,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,wBAAwB,EACjC,OAAO,GAAE,kCAAuC;CASjD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,wBAAwB,EACjC,EAAE,QAAgB,EAAE,MAAM,EAAE,GAAE,kCAAuC,GACnE,IAAI,CAiDN"}
@@ -41,9 +41,11 @@ export function bindButtonToCommand(button, command, { withText = false, target
41
41
  else {
42
42
  button.bind('tooltip').to(command, 'tooltip');
43
43
  }
44
+ const getTarget = typeof target === 'function' ? target : () => target ?? null;
44
45
  if (target) {
45
46
  const updateState = () => {
46
- const { isEnabled, isOn } = command.getState(target);
47
+ const current = getTarget();
48
+ const { isEnabled, isOn } = current ? command.getState(current) : { isEnabled: false, isOn: false };
47
49
  button.isEnabled = isEnabled;
48
50
  button.isOn = isOn;
49
51
  };
@@ -58,7 +60,11 @@ export function bindButtonToCommand(button, command, { withText = false, target
58
60
  button.on('execute', () => {
59
61
  // Focus first: focusing reads the DOM selection, which would override a selection set by the command.
60
62
  editor.editing.view.focus();
61
- const result = target ? command.executeFor(target) : command.execute();
63
+ const current = getTarget();
64
+ if (target && !current) {
65
+ return;
66
+ }
67
+ const result = current ? command.executeFor(current) : command.execute();
62
68
  if (result instanceof Promise) {
63
69
  result.catch((error) => {
64
70
  reportError(command, error);
@@ -1 +1 @@
1
- {"version":3,"file":"elementOrPositionButtonView.js","sourceRoot":"","sources":["../src/elementOrPositionButtonView.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"elementOrPositionButtonView.js","sourceRoot":"","sources":["../src/elementOrPositionButtonView.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -10,9 +10,10 @@ import './singleCopyGuard.js';
10
10
  export { default as ElementMenu, type ElementMenuConfig, type ElementMenuItem, type ElementMenuShowOptions, type ElementSubmenu } from './elementMenu.js';
11
11
  export { default as ElementOrPositionCommand, type ElementOrPosition } from './elementOrPositionCommand.js';
12
12
  export { default as ElementCommand } from './elementCommand.js';
13
- export { default as ElementOrPositionButtonView, type ElementOrPositionButtonViewOptions } from './elementOrPositionButtonView.js';
13
+ export { default as ElementOrPositionButtonView, type ElementOrPositionButtonViewOptions, type ElementOrPositionTarget } from './elementOrPositionButtonView.js';
14
14
  export { default as ElementButtonView } from './elementButtonView.js';
15
15
  export { default as ElementMenuView } from './elementMenuView.js';
16
- export { isInDocument } from './utils.js';
16
+ export { getElementAtSelection, isInDocument, isStandalone, selectNewElement } from './utils.js';
17
+ export { findPlugin, getElementsAround, matchesElement, type ElementMatcher } from './matching.js';
17
18
  import './augmentation.js';
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EACN,OAAO,IAAI,WAAW,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC5G,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EACN,OAAO,IAAI,2BAA2B,EACtC,KAAK,kCAAkC,EACvC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EACN,OAAO,IAAI,WAAW,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC5G,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EACN,OAAO,IAAI,2BAA2B,EACtC,KAAK,kCAAkC,EACvC,KAAK,uBAAuB,EAC5B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAEnG,OAAO,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ export { default as ElementOrPositionButtonView } from './elementOrPositionButto
17
17
  export { default as ElementButtonView } from './elementButtonView.js';
18
18
  export { default as ElementMenuView } from './elementMenuView.js';
19
19
  // Utils.
20
- export { isInDocument } from './utils.js';
20
+ export { getElementAtSelection, isInDocument, isStandalone, selectNewElement } from './utils.js';
21
+ export { findPlugin, getElementsAround, matchesElement } from './matching.js';
21
22
  import './augmentation.js';
22
23
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,sBAAsB,CAAC;AAE9B,WAAW;AACX,OAAO,EACN,OAAO,IAAI,WAAW,EAKtB,MAAM,kBAAkB,CAAC;AAE1B,YAAY;AACZ,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAA0B,MAAM,+BAA+B,CAAC;AAC5G,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEhE,SAAS;AACT,OAAO,EACN,OAAO,IAAI,2BAA2B,EAEtC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAElE,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,sBAAsB,CAAC;AAE9B,WAAW;AACX,OAAO,EACN,OAAO,IAAI,WAAW,EAKtB,MAAM,kBAAkB,CAAC;AAE1B,YAAY;AACZ,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAA0B,MAAM,+BAA+B,CAAC;AAC5G,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEhE,SAAS;AACT,OAAO,EACN,OAAO,IAAI,2BAA2B,EAGtC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAElE,SAAS;AACT,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAuB,MAAM,eAAe,CAAC;AAEnG,OAAO,mBAAmB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Editor, Mapper, ModelElement, ViewElement } from 'ckeditor5';
2
+ /**
3
+ * Matches model elements: the name of a model element (e.g. `'imageBlock'`), or a function that returns whether it is for
4
+ * the given element (e.g. `element => element.hasAttribute('linkHref')`).
5
+ */
6
+ export type ElementMatcher = string | ((element: ModelElement) => boolean);
7
+ /**
8
+ * Returns whether the matcher is for the element.
9
+ */
10
+ export declare function matchesElement(matcher: ElementMatcher, element: ModelElement): boolean;
11
+ /**
12
+ * Returns the model elements of a view element and its ancestors, the innermost first, with their view elements. The view
13
+ * elements that are not converted from model elements, and roots, are skipped.
14
+ */
15
+ export declare function getElementsAround(mapper: Mapper, viewElement: ViewElement): Generator<{
16
+ element: ModelElement;
17
+ viewElement: ViewElement;
18
+ }>;
19
+ /**
20
+ * Returns the plugin of the name when it is loaded and fits the guard, `null` otherwise. The features use it to work with
21
+ * another feature without depending on it: they look the plugin up by name, and check it against the interface they use.
22
+ */
23
+ export declare function findPlugin<T extends object>(editor: Editor, name: string, isPlugin: (plugin: object) => plugin is T): T | null;
24
+ //# sourceMappingURL=matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../src/matching.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE3E;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;AAE3E;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAEtF;AAED;;;GAGG;AACH,wBAAiB,iBAAiB,CACjC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,GACtB,SAAS,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC,CAQhE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAC1C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,IAAI,CAAC,GACvC,CAAC,GAAG,IAAI,CAIV"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Returns whether the matcher is for the element.
3
+ */
4
+ export function matchesElement(matcher, element) {
5
+ return typeof matcher === 'string' ? element.name === matcher : matcher(element);
6
+ }
7
+ /**
8
+ * Returns the model elements of a view element and its ancestors, the innermost first, with their view elements. The view
9
+ * elements that are not converted from model elements, and roots, are skipped.
10
+ */
11
+ export function* getElementsAround(mapper, viewElement) {
12
+ for (let node = viewElement; node; node = node.parent?.is('element') ? node.parent : null) {
13
+ const element = mapper.toModelElement(node);
14
+ if (element && !element.is('rootElement')) {
15
+ yield { element, viewElement: node };
16
+ }
17
+ }
18
+ }
19
+ /**
20
+ * Returns the plugin of the name when it is loaded and fits the guard, `null` otherwise. The features use it to work with
21
+ * another feature without depending on it: they look the plugin up by name, and check it against the interface they use.
22
+ */
23
+ export function findPlugin(editor, name, isPlugin) {
24
+ const plugin = editor.plugins.has(name) ? editor.plugins.get(name) : null;
25
+ return typeof plugin === 'object' && plugin !== null && isPlugin(plugin) ? plugin : null;
26
+ }
27
+ //# sourceMappingURL=matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.js","sourceRoot":"","sources":["../src/matching.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAuB,EAAE,OAAqB;IAC5E,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,MAAM,SAAS,CAAC,CAAC,iBAAiB,CACjC,MAAc,EACd,WAAwB;IAExB,KAAK,IAAI,IAAI,GAAuB,WAAW,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/G,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC;YAC3C,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QACtC,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CACzB,MAAc,EACd,IAAY,EACZ,QAAyC;IAEzC,MAAM,MAAM,GAAY,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEnF,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1F,CAAC"}
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,23 @@
1
- import type { ModelElement, ModelPosition } from 'ckeditor5';
1
+ import type { ModelDocumentSelection, ModelElement, ModelPosition, ModelSchema, ModelSelection, ModelWriter } from 'ckeditor5';
2
2
  /**
3
3
  * Whether the element (or position) is in the document. Unlike `element.isAttached()`, removed elements (moved to
4
4
  * the graveyard root) do not count, and neither do the elements of detached roots.
5
5
  */
6
6
  export declare function isInDocument(elementOrPosition: ModelElement | ModelPosition): boolean;
7
+ /**
8
+ * Returns the element at the selection: the selected element (e.g. an image), or the element with the cursor, i.e. the
9
+ * parent of the start of the selection. Never a root: `null` when the selection is directly in one.
10
+ */
11
+ export declare function getElementAtSelection(selection: ModelSelection | ModelDocumentSelection): ModelElement | null;
12
+ /**
13
+ * Whether the element can be handled as a whole: copied, moved, duplicated or removed. Parts of a structure that cannot
14
+ * stand alone, such as a table cell, a table row or a caption, cannot: in the schema, they are limit elements that are
15
+ * not objects.
16
+ */
17
+ export declare function isStandalone(schema: ModelSchema, element: ModelElement): boolean;
18
+ /**
19
+ * Puts the selection in a newly inserted element, so that the user can go on: an object is selected; an element that
20
+ * holds text gets the cursor inside it; an element that holds blocks gets an empty paragraph with the cursor.
21
+ */
22
+ export declare function selectNewElement(writer: ModelWriter, element: ModelElement): void;
7
23
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,YAAY,CAAC,iBAAiB,EAAE,YAAY,GAAG,aAAa,GAAG,OAAO,CAIrF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,cAAc,EACd,WAAW,EACX,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,iBAAiB,EAAE,YAAY,GAAG,aAAa,GAAG,OAAO,CAIrF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,cAAc,GAAG,sBAAsB,GAAG,YAAY,GAAG,IAAI,CAI7G;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAEhF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAgBjF"}
package/dist/utils.js CHANGED
@@ -6,4 +6,42 @@ export function isInDocument(elementOrPosition) {
6
6
  const root = elementOrPosition.root;
7
7
  return root.is('rootElement') && root.rootName !== '$graveyard' && root.isAttached();
8
8
  }
9
+ /**
10
+ * Returns the element at the selection: the selected element (e.g. an image), or the element with the cursor, i.e. the
11
+ * parent of the start of the selection. Never a root: `null` when the selection is directly in one.
12
+ */
13
+ export function getElementAtSelection(selection) {
14
+ const element = selection.getSelectedElement() ?? selection.getFirstPosition()?.parent;
15
+ return element?.is('element') && !element.is('rootElement') ? element : null;
16
+ }
17
+ /**
18
+ * Whether the element can be handled as a whole: copied, moved, duplicated or removed. Parts of a structure that cannot
19
+ * stand alone, such as a table cell, a table row or a caption, cannot: in the schema, they are limit elements that are
20
+ * not objects.
21
+ */
22
+ export function isStandalone(schema, element) {
23
+ return !schema.isLimit(element) || schema.isObject(element);
24
+ }
25
+ /**
26
+ * Puts the selection in a newly inserted element, so that the user can go on: an object is selected; an element that
27
+ * holds text gets the cursor inside it; an element that holds blocks gets an empty paragraph with the cursor.
28
+ */
29
+ export function selectNewElement(writer, element) {
30
+ const schema = writer.model.schema;
31
+ if (schema.isObject(element)) {
32
+ writer.setSelection(element, 'on');
33
+ }
34
+ else if (schema.checkChild(element, '$text')) {
35
+ writer.setSelection(element, 0);
36
+ }
37
+ else if (schema.checkChild(element, 'paragraph')) {
38
+ const paragraph = writer.createElement('paragraph');
39
+ writer.append(paragraph, element);
40
+ writer.setSelection(paragraph, 0);
41
+ }
42
+ else {
43
+ // Only objects can be selected as a whole. The selection post-fixer moves it to the closest valid place.
44
+ writer.setSelection(element, 'after');
45
+ }
46
+ }
9
47
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,iBAA+C;IAC3E,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC;IAEpC,OAAO,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,iBAA+C;IAC3E,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC;IAEpC,OAAO,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;AACtF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAkD;IACvF,MAAM,OAAO,GAAG,SAAS,CAAC,kBAAkB,EAAE,IAAI,SAAS,CAAC,gBAAgB,EAAE,EAAE,MAAM,CAAC;IAEvF,OAAO,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAmB,EAAE,OAAqB;IACtE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAmB,EAAE,OAAqB;IAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IAEnC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;SAAM,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACjC,CAAC;SAAM,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACpD,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAEpD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACP,yGAAyG;QACzG,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ckeditor5-elements-core",
3
- "version": "49.0.0-alpha.0",
3
+ "version": "49.0.0-alpha.2",
4
4
  "description": "The base of the element commands, buttons and menus for CKEditor 5: ElementOrPositionCommand, ElementCommand, their button views, and ElementMenu.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -38,7 +38,7 @@
38
38
  "README.md"
39
39
  ],
40
40
  "peerDependencies": {
41
- "ckeditor5": ">=49.0.0"
41
+ "ckeditor5": "^49.0.0"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc --build"
@@ -173,7 +173,10 @@ export default class ElementMenu extends Plugin {
173
173
  view,
174
174
  position: { target },
175
175
  withArrow: false,
176
- singleViewMode: true
176
+ singleViewMode: true,
177
+ // Views that other plugins add to the balloon meanwhile (e.g. an element toolbar, when the selection moves
178
+ // into its element) go to their own stack, so they do not cover the menu.
179
+ stackId: 'elementMenu'
177
180
  });
178
181
 
179
182
  const keystrokes = new KeystrokeHandler();
@@ -12,12 +12,19 @@ export interface ElementOrPositionButtonViewOptions {
12
12
  withText?: boolean;
13
13
 
14
14
  /**
15
- * The position or element the button acts on. Without it, the button follows the command state for the selection
16
- * and executes the command for the selection.
15
+ * The position or element the button acts on, or a function that returns it, e.g. the element of a floating
16
+ * toolbar, which changes as the selection moves. The function is called whenever the button updates or is clicked;
17
+ * when it returns `null`, the button is disabled. Without a target, the button follows the command state for the
18
+ * selection and executes the command for the selection.
17
19
  */
18
- target?: ElementOrPosition;
20
+ target?: ElementOrPositionTarget;
19
21
  }
20
22
 
23
+ /**
24
+ * The target of a button: a position or an element, or a function that returns one (or `null`).
25
+ */
26
+ export type ElementOrPositionTarget = ElementOrPosition | (() => ElementOrPosition | null);
27
+
21
28
  /**
22
29
  * A button that reflects an {@link ElementOrPositionCommand} and executes it when clicked.
23
30
  *
@@ -38,7 +45,7 @@ export default class ElementOrPositionButtonView extends ButtonView {
38
45
  /**
39
46
  * The position or element the button acts on, if any.
40
47
  */
41
- public readonly target: ElementOrPosition | undefined;
48
+ public readonly target: ElementOrPositionTarget | undefined;
42
49
 
43
50
  constructor(
44
51
  locale: Locale | undefined,
@@ -74,9 +81,12 @@ export function bindButtonToCommand(
74
81
  button.bind('tooltip').to(command, 'tooltip');
75
82
  }
76
83
 
84
+ const getTarget = typeof target === 'function' ? target : (): ElementOrPosition | null => target ?? null;
85
+
77
86
  if (target) {
78
87
  const updateState = (): void => {
79
- const { isEnabled, isOn } = command.getState(target);
88
+ const current = getTarget();
89
+ const { isEnabled, isOn } = current ? command.getState(current) : { isEnabled: false, isOn: false };
80
90
 
81
91
  button.isEnabled = isEnabled;
82
92
  button.isOn = isOn;
@@ -94,7 +104,13 @@ export function bindButtonToCommand(
94
104
  // Focus first: focusing reads the DOM selection, which would override a selection set by the command.
95
105
  editor.editing.view.focus();
96
106
 
97
- const result = target ? command.executeFor(target) : command.execute();
107
+ const current = getTarget();
108
+
109
+ if (target && !current) {
110
+ return;
111
+ }
112
+
113
+ const result = current ? command.executeFor(current) : command.execute();
98
114
 
99
115
  if (result instanceof Promise) {
100
116
  result.catch((error: unknown) => {
package/src/index.ts CHANGED
@@ -25,12 +25,14 @@ export { default as ElementCommand } from './elementCommand.js';
25
25
  // Views.
26
26
  export {
27
27
  default as ElementOrPositionButtonView,
28
- type ElementOrPositionButtonViewOptions
28
+ type ElementOrPositionButtonViewOptions,
29
+ type ElementOrPositionTarget
29
30
  } from './elementOrPositionButtonView.js';
30
31
  export { default as ElementButtonView } from './elementButtonView.js';
31
32
  export { default as ElementMenuView } from './elementMenuView.js';
32
33
 
33
34
  // Utils.
34
- export { isInDocument } from './utils.js';
35
+ export { getElementAtSelection, isInDocument, isStandalone, selectNewElement } from './utils.js';
36
+ export { findPlugin, getElementsAround, matchesElement, type ElementMatcher } from './matching.js';
35
37
 
36
38
  import './augmentation.js';
@@ -0,0 +1,45 @@
1
+ import type { Editor, Mapper, ModelElement, ViewElement } from 'ckeditor5';
2
+
3
+ /**
4
+ * Matches model elements: the name of a model element (e.g. `'imageBlock'`), or a function that returns whether it is for
5
+ * the given element (e.g. `element => element.hasAttribute('linkHref')`).
6
+ */
7
+ export type ElementMatcher = string | ((element: ModelElement) => boolean);
8
+
9
+ /**
10
+ * Returns whether the matcher is for the element.
11
+ */
12
+ export function matchesElement(matcher: ElementMatcher, element: ModelElement): boolean {
13
+ return typeof matcher === 'string' ? element.name === matcher : matcher(element);
14
+ }
15
+
16
+ /**
17
+ * Returns the model elements of a view element and its ancestors, the innermost first, with their view elements. The view
18
+ * elements that are not converted from model elements, and roots, are skipped.
19
+ */
20
+ export function* getElementsAround(
21
+ mapper: Mapper,
22
+ viewElement: ViewElement
23
+ ): Generator<{ element: ModelElement; viewElement: ViewElement }> {
24
+ for (let node: ViewElement | null = viewElement; node; node = node.parent?.is('element') ? node.parent : null) {
25
+ const element = mapper.toModelElement(node);
26
+
27
+ if (element && !element.is('rootElement')) {
28
+ yield { element, viewElement: node };
29
+ }
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Returns the plugin of the name when it is loaded and fits the guard, `null` otherwise. The features use it to work with
35
+ * another feature without depending on it: they look the plugin up by name, and check it against the interface they use.
36
+ */
37
+ export function findPlugin<T extends object>(
38
+ editor: Editor,
39
+ name: string,
40
+ isPlugin: (plugin: object) => plugin is T
41
+ ): T | null {
42
+ const plugin: unknown = editor.plugins.has(name) ? editor.plugins.get(name) : null;
43
+
44
+ return typeof plugin === 'object' && plugin !== null && isPlugin(plugin) ? plugin : null;
45
+ }
package/src/utils.ts CHANGED
@@ -1,4 +1,11 @@
1
- import type { ModelElement, ModelPosition } from 'ckeditor5';
1
+ import type {
2
+ ModelDocumentSelection,
3
+ ModelElement,
4
+ ModelPosition,
5
+ ModelSchema,
6
+ ModelSelection,
7
+ ModelWriter
8
+ } from 'ckeditor5';
2
9
 
3
10
  /**
4
11
  * Whether the element (or position) is in the document. Unlike `element.isAttached()`, removed elements (moved to
@@ -9,3 +16,44 @@ export function isInDocument(elementOrPosition: ModelElement | ModelPosition): b
9
16
 
10
17
  return root.is('rootElement') && root.rootName !== '$graveyard' && root.isAttached();
11
18
  }
19
+
20
+ /**
21
+ * Returns the element at the selection: the selected element (e.g. an image), or the element with the cursor, i.e. the
22
+ * parent of the start of the selection. Never a root: `null` when the selection is directly in one.
23
+ */
24
+ export function getElementAtSelection(selection: ModelSelection | ModelDocumentSelection): ModelElement | null {
25
+ const element = selection.getSelectedElement() ?? selection.getFirstPosition()?.parent;
26
+
27
+ return element?.is('element') && !element.is('rootElement') ? element : null;
28
+ }
29
+
30
+ /**
31
+ * Whether the element can be handled as a whole: copied, moved, duplicated or removed. Parts of a structure that cannot
32
+ * stand alone, such as a table cell, a table row or a caption, cannot: in the schema, they are limit elements that are
33
+ * not objects.
34
+ */
35
+ export function isStandalone(schema: ModelSchema, element: ModelElement): boolean {
36
+ return !schema.isLimit(element) || schema.isObject(element);
37
+ }
38
+
39
+ /**
40
+ * Puts the selection in a newly inserted element, so that the user can go on: an object is selected; an element that
41
+ * holds text gets the cursor inside it; an element that holds blocks gets an empty paragraph with the cursor.
42
+ */
43
+ export function selectNewElement(writer: ModelWriter, element: ModelElement): void {
44
+ const schema = writer.model.schema;
45
+
46
+ if (schema.isObject(element)) {
47
+ writer.setSelection(element, 'on');
48
+ } else if (schema.checkChild(element, '$text')) {
49
+ writer.setSelection(element, 0);
50
+ } else if (schema.checkChild(element, 'paragraph')) {
51
+ const paragraph = writer.createElement('paragraph');
52
+
53
+ writer.append(paragraph, element);
54
+ writer.setSelection(paragraph, 0);
55
+ } else {
56
+ // Only objects can be selected as a whole. The selection post-fixer moves it to the closest valid place.
57
+ writer.setSelection(element, 'after');
58
+ }
59
+ }