@ckeditor/ckeditor5-widget 36.0.1 → 37.0.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-widget",
3
- "version": "36.0.1",
3
+ "version": "37.0.0-alpha.0",
4
4
  "description": "Widget API for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -11,29 +11,29 @@
11
11
  ],
12
12
  "main": "src/index.js",
13
13
  "dependencies": {
14
- "@ckeditor/ckeditor5-core": "^36.0.1",
15
- "@ckeditor/ckeditor5-engine": "^36.0.1",
16
- "@ckeditor/ckeditor5-enter": "^36.0.1",
17
- "@ckeditor/ckeditor5-ui": "^36.0.1",
18
- "@ckeditor/ckeditor5-utils": "^36.0.1",
19
- "@ckeditor/ckeditor5-typing": "^36.0.1",
14
+ "@ckeditor/ckeditor5-core": "^37.0.0-alpha.0",
15
+ "@ckeditor/ckeditor5-engine": "^37.0.0-alpha.0",
16
+ "@ckeditor/ckeditor5-enter": "^37.0.0-alpha.0",
17
+ "@ckeditor/ckeditor5-ui": "^37.0.0-alpha.0",
18
+ "@ckeditor/ckeditor5-utils": "^37.0.0-alpha.0",
19
+ "@ckeditor/ckeditor5-typing": "^37.0.0-alpha.0",
20
20
  "lodash-es": "^4.17.15"
21
21
  },
22
22
  "devDependencies": {
23
- "@ckeditor/ckeditor5-basic-styles": "^36.0.1",
24
- "@ckeditor/ckeditor5-block-quote": "^36.0.1",
25
- "@ckeditor/ckeditor5-clipboard": "^36.0.1",
26
- "@ckeditor/ckeditor5-editor-balloon": "^36.0.1",
27
- "@ckeditor/ckeditor5-editor-classic": "^36.0.1",
28
- "@ckeditor/ckeditor5-essentials": "^36.0.1",
29
- "@ckeditor/ckeditor5-heading": "^36.0.1",
30
- "@ckeditor/ckeditor5-horizontal-line": "^36.0.1",
31
- "@ckeditor/ckeditor5-image": "^36.0.1",
32
- "@ckeditor/ckeditor5-link": "^36.0.1",
33
- "@ckeditor/ckeditor5-media-embed": "^36.0.1",
34
- "@ckeditor/ckeditor5-paragraph": "^36.0.1",
35
- "@ckeditor/ckeditor5-table": "^36.0.1",
36
- "@ckeditor/ckeditor5-undo": "^36.0.1",
23
+ "@ckeditor/ckeditor5-basic-styles": "^37.0.0-alpha.0",
24
+ "@ckeditor/ckeditor5-block-quote": "^37.0.0-alpha.0",
25
+ "@ckeditor/ckeditor5-clipboard": "^37.0.0-alpha.0",
26
+ "@ckeditor/ckeditor5-editor-balloon": "^37.0.0-alpha.0",
27
+ "@ckeditor/ckeditor5-editor-classic": "^37.0.0-alpha.0",
28
+ "@ckeditor/ckeditor5-essentials": "^37.0.0-alpha.0",
29
+ "@ckeditor/ckeditor5-heading": "^37.0.0-alpha.0",
30
+ "@ckeditor/ckeditor5-horizontal-line": "^37.0.0-alpha.0",
31
+ "@ckeditor/ckeditor5-image": "^37.0.0-alpha.0",
32
+ "@ckeditor/ckeditor5-link": "^37.0.0-alpha.0",
33
+ "@ckeditor/ckeditor5-media-embed": "^37.0.0-alpha.0",
34
+ "@ckeditor/ckeditor5-paragraph": "^37.0.0-alpha.0",
35
+ "@ckeditor/ckeditor5-table": "^37.0.0-alpha.0",
36
+ "@ckeditor/ckeditor5-undo": "^37.0.0-alpha.0",
37
37
  "typescript": "^4.8.4",
38
38
  "webpack": "^5.58.1",
39
39
  "webpack-cli": "^4.9.0"
@@ -62,5 +62,6 @@
62
62
  "scripts": {
63
63
  "build": "tsc -p ./tsconfig.release.json",
64
64
  "postversion": "npm run build"
65
- }
65
+ },
66
+ "types": "src/index.d.ts"
66
67
  }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ import type { DowncastWriter, HighlightDescriptor } from '@ckeditor/ckeditor5-engine';
6
+ declare const HighlightStack_base: {
7
+ new (): import("@ckeditor/ckeditor5-utils").Emitter;
8
+ prototype: import("@ckeditor/ckeditor5-utils").Emitter;
9
+ };
10
+ /**
11
+ * Class used to handle the correct order of highlights on elements.
12
+ *
13
+ * When different highlights are applied to same element the correct order should be preserved:
14
+ *
15
+ * * highlight with highest priority should be applied,
16
+ * * if two highlights have same priority - sort by CSS class provided in
17
+ * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor}.
18
+ *
19
+ * This way, highlight will be applied with the same rules it is applied on texts.
20
+ */
21
+ export default class HighlightStack extends HighlightStack_base {
22
+ private readonly _stack;
23
+ /**
24
+ * Adds highlight descriptor to the stack.
25
+ *
26
+ * @fires change:top
27
+ */
28
+ add(descriptor: HighlightDescriptor, writer: DowncastWriter): void;
29
+ /**
30
+ * Removes highlight descriptor from the stack.
31
+ *
32
+ * @fires change:top
33
+ * @param id Id of the descriptor to remove.
34
+ */
35
+ remove(id: string, writer: DowncastWriter): void;
36
+ /**
37
+ * Inserts a given descriptor in correct place in the stack. It also takes care about updating information
38
+ * when descriptor with same id is already present.
39
+ */
40
+ private _insertDescriptor;
41
+ /**
42
+ * Removes descriptor with given id from the stack.
43
+ *
44
+ * @param id Descriptor's id.
45
+ */
46
+ private _removeDescriptor;
47
+ }
48
+ /**
49
+ * Fired when top element on {@link module:widget/highlightstack~HighlightStack} has been changed
50
+ *
51
+ * @eventName change:top
52
+ */
53
+ export type HighlightStackChangeEvent = {
54
+ name: 'change' | 'change:top';
55
+ args: [HighlightStackChangeEventData];
56
+ };
57
+ /**
58
+ * Additional information about the change.
59
+ */
60
+ export type HighlightStackChangeEventData = {
61
+ /**
62
+ * Old highlight descriptor. It will be `undefined` when first descriptor is added to the stack.
63
+ */
64
+ oldDescriptor: HighlightDescriptor;
65
+ /**
66
+ * New highlight descriptor. It will be `undefined` when last descriptor is removed from the stack.
67
+ */
68
+ newDescriptor: HighlightDescriptor;
69
+ /**
70
+ * View writer that can be used to modify element.
71
+ */
72
+ writer: DowncastWriter;
73
+ };
74
+ export {};
@@ -18,19 +18,14 @@ import { EmitterMixin } from '@ckeditor/ckeditor5-utils';
18
18
  * This way, highlight will be applied with the same rules it is applied on texts.
19
19
  */
20
20
  export default class HighlightStack extends EmitterMixin() {
21
- /**
22
- * Creates class instance.
23
- */
24
21
  constructor() {
25
- super();
22
+ super(...arguments);
26
23
  this._stack = [];
27
24
  }
28
25
  /**
29
26
  * Adds highlight descriptor to the stack.
30
27
  *
31
28
  * @fires change:top
32
- * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor
33
- * @param {module:engine/view/downcastwriter~DowncastWriter} writer
34
29
  */
35
30
  add(descriptor, writer) {
36
31
  const stack = this._stack;
@@ -51,8 +46,7 @@ export default class HighlightStack extends EmitterMixin() {
51
46
  * Removes highlight descriptor from the stack.
52
47
  *
53
48
  * @fires change:top
54
- * @param {String} id Id of the descriptor to remove.
55
- * @param {module:engine/view/downcastwriter~DowncastWriter} writer
49
+ * @param id Id of the descriptor to remove.
56
50
  */
57
51
  remove(id, writer) {
58
52
  const stack = this._stack;
@@ -71,9 +65,6 @@ export default class HighlightStack extends EmitterMixin() {
71
65
  /**
72
66
  * Inserts a given descriptor in correct place in the stack. It also takes care about updating information
73
67
  * when descriptor with same id is already present.
74
- *
75
- * @private
76
- * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor
77
68
  */
78
69
  _insertDescriptor(descriptor) {
79
70
  const stack = this._stack;
@@ -97,8 +88,7 @@ export default class HighlightStack extends EmitterMixin() {
97
88
  /**
98
89
  * Removes descriptor with given id from the stack.
99
90
  *
100
- * @private
101
- * @param {String} id Descriptor's id.
91
+ * @param id Descriptor's id.
102
92
  */
103
93
  _removeDescriptor(id) {
104
94
  const stack = this._stack;
@@ -109,19 +99,17 @@ export default class HighlightStack extends EmitterMixin() {
109
99
  }
110
100
  }
111
101
  }
112
- // Compares two descriptors by checking their priority and class list.
113
- //
114
- // @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} a
115
- // @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} b
116
- // @returns {Boolean} Returns true if both descriptors are defined and have same priority and classes.
102
+ /**
103
+ * Compares two descriptors by checking their priority and class list.
104
+ *
105
+ * @returns Returns true if both descriptors are defined and have same priority and classes.
106
+ */
117
107
  function compareDescriptors(a, b) {
118
108
  return a && b && a.priority == b.priority && classesToString(a.classes) == classesToString(b.classes);
119
109
  }
120
- // Checks whenever first descriptor should be placed in the stack before second one.
121
- //
122
- // @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} a
123
- // @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} b
124
- // @returns {Boolean}
110
+ /**
111
+ * Checks whenever first descriptor should be placed in the stack before second one.
112
+ */
125
113
  function shouldABeBeforeB(a, b) {
126
114
  if (a.priority > b.priority) {
127
115
  return true;
@@ -132,11 +120,10 @@ function shouldABeBeforeB(a, b) {
132
120
  // When priorities are equal and names are different - use classes to compare.
133
121
  return classesToString(a.classes) > classesToString(b.classes);
134
122
  }
135
- // Converts CSS classes passed with {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} to
136
- // sorted string.
137
- //
138
- // @param {String|Array<String>} descriptor
139
- // @returns {String}
123
+ /**
124
+ * Converts CSS classes passed with {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} to
125
+ * sorted string.
126
+ */
140
127
  function classesToString(classes) {
141
128
  return Array.isArray(classes) ? classes.sort().join(',') : classes;
142
129
  }
package/src/index.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ export { default as Widget } from './widget';
6
+ export { default as WidgetToolbarRepository } from './widgettoolbarrepository';
7
+ export { default as WidgetResize } from './widgetresize';
8
+ export { default as WidgetTypeAround } from './widgettypearound/widgettypearound';
9
+ export * from './utils';
package/src/utils.d.ts ADDED
@@ -0,0 +1,198 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module widget/utils
7
+ */
8
+ import { type GetCallback } from '@ckeditor/ckeditor5-utils';
9
+ import { type HighlightDescriptor, type MapperViewToModelPositionEvent, type DocumentSelection, type DowncastWriter, type Model, type Range, type Selection, type ViewEditableElement, type ViewElement, type ViewTypeCheckable } from '@ckeditor/ckeditor5-engine';
10
+ /**
11
+ * CSS class added to each widget element.
12
+ */
13
+ export declare const WIDGET_CLASS_NAME = "ck-widget";
14
+ /**
15
+ * CSS class added to currently selected widget element.
16
+ */
17
+ export declare const WIDGET_SELECTED_CLASS_NAME = "ck-widget_selected";
18
+ /**
19
+ * Returns `true` if given {@link module:engine/view/node~Node} is an {@link module:engine/view/element~Element} and a widget.
20
+ */
21
+ export declare function isWidget(node: ViewTypeCheckable): boolean;
22
+ /**
23
+ * Converts the given {@link module:engine/view/element~Element} to a widget in the following way:
24
+ *
25
+ * * sets the `contenteditable` attribute to `"false"`,
26
+ * * adds the `ck-widget` CSS class,
27
+ * * adds a custom {@link module:engine/view/element~Element#getFillerOffset `getFillerOffset()`} method returning `null`,
28
+ * * adds a custom property allowing to recognize widget elements by using {@link ~isWidget `isWidget()`},
29
+ * * implements the {@link ~setHighlightHandling view highlight on widgets}.
30
+ *
31
+ * This function needs to be used in conjunction with
32
+ * {@link module:engine/conversion/downcasthelpers~DowncastHelpers downcast conversion helpers}
33
+ * like {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.
34
+ * Moreover, typically you will want to use `toWidget()` only for `editingDowncast`, while keeping the `dataDowncast` clean.
35
+ *
36
+ * For example, in order to convert a `<widget>` model element to `<div class="widget">` in the view, you can define
37
+ * such converters:
38
+ *
39
+ * ```ts
40
+ * editor.conversion.for( 'editingDowncast' )
41
+ * .elementToElement( {
42
+ * model: 'widget',
43
+ * view: ( modelItem, { writer } ) => {
44
+ * const div = writer.createContainerElement( 'div', { class: 'widget' } );
45
+ *
46
+ * return toWidget( div, writer, { label: 'some widget' } );
47
+ * }
48
+ * } );
49
+ *
50
+ * editor.conversion.for( 'dataDowncast' )
51
+ * .elementToElement( {
52
+ * model: 'widget',
53
+ * view: ( modelItem, { writer } ) => {
54
+ * return writer.createContainerElement( 'div', { class: 'widget' } );
55
+ * }
56
+ * } );
57
+ * ```
58
+ *
59
+ * See the full source code of the widget (with a nested editable) schema definition and converters in
60
+ * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).
61
+ *
62
+ * @param options Additional options.
63
+ * @param options.label Element's label provided to the {@link ~setLabel} function. It can be passed as
64
+ * a plain string or a function returning a string. It represents the widget for assistive technologies (like screen readers).
65
+ * @param options.hasSelectionHandle If `true`, the widget will have a selection handle added.
66
+ * @returns Returns the same element.
67
+ */
68
+ export declare function toWidget(element: ViewElement, writer: DowncastWriter, options?: {
69
+ label?: string | (() => string);
70
+ hasSelectionHandle?: boolean;
71
+ }): ViewElement;
72
+ /**
73
+ * Sets highlight handling methods. Uses {@link module:widget/highlightstack~HighlightStack} to
74
+ * properly determine which highlight descriptor should be used at given time.
75
+ */
76
+ export declare function setHighlightHandling(element: ViewElement, writer: DowncastWriter, add?: (element: ViewElement, descriptor: HighlightDescriptor, writer: DowncastWriter) => void, remove?: (element: ViewElement, descriptor: HighlightDescriptor, writer: DowncastWriter) => void): void;
77
+ /**
78
+ * Sets label for given element.
79
+ * It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by
80
+ * {@link ~getLabel `getLabel()`}.
81
+ */
82
+ export declare function setLabel(element: ViewElement, labelOrCreator: string | (() => string)): void;
83
+ /**
84
+ * Returns the label of the provided element.
85
+ */
86
+ export declare function getLabel(element: ViewElement): string;
87
+ /**
88
+ * Adds functionality to the provided {@link module:engine/view/editableelement~EditableElement} to act as a widget's editable:
89
+ *
90
+ * * sets the `contenteditable` attribute to `true` when {@link module:engine/view/editableelement~EditableElement#isReadOnly} is `false`,
91
+ * otherwise sets it to `false`,
92
+ * * adds the `ck-editor__editable` and `ck-editor__nested-editable` CSS classes,
93
+ * * adds the `ck-editor__nested-editable_focused` CSS class when the editable is focused and removes it when it is blurred.
94
+ * * implements the {@link ~setHighlightHandling view highlight on widget's editable}.
95
+ *
96
+ * Similarly to {@link ~toWidget `toWidget()`} this function should be used in `editingDowncast` only and it is usually
97
+ * used together with {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.
98
+ *
99
+ * For example, in order to convert a `<nested>` model element to `<div class="nested">` in the view, you can define
100
+ * such converters:
101
+ *
102
+ * ```ts
103
+ * editor.conversion.for( 'editingDowncast' )
104
+ * .elementToElement( {
105
+ * model: 'nested',
106
+ * view: ( modelItem, { writer } ) => {
107
+ * const div = writer.createEditableElement( 'div', { class: 'nested' } );
108
+ *
109
+ * return toWidgetEditable( nested, writer, { label: 'label for editable' } );
110
+ * }
111
+ * } );
112
+ *
113
+ * editor.conversion.for( 'dataDowncast' )
114
+ * .elementToElement( {
115
+ * model: 'nested',
116
+ * view: ( modelItem, { writer } ) => {
117
+ * return writer.createContainerElement( 'div', { class: 'nested' } );
118
+ * }
119
+ * } );
120
+ * ```
121
+ *
122
+ * See the full source code of the widget (with nested editable) schema definition and converters in
123
+ * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).
124
+ *
125
+ * @param options Additional options.
126
+ * @param options.label Editable's label used by assistive technologies (e.g. screen readers).
127
+ * @returns Returns the same element that was provided in the `editable` parameter
128
+ */
129
+ export declare function toWidgetEditable(editable: ViewEditableElement, writer: DowncastWriter, options?: {
130
+ label?: string;
131
+ }): ViewEditableElement;
132
+ /**
133
+ * Returns a model range which is optimal (in terms of UX) for inserting a widget block.
134
+ *
135
+ * For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph
136
+ * will be returned so that it is not split. If the selection is at the end of a paragraph,
137
+ * the collapsed range after this paragraph will be returned.
138
+ *
139
+ * Note: If the selection is placed in an empty block, the range in that block will be returned. If that range
140
+ * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced
141
+ * by the inserted widget block.
142
+ *
143
+ * @param selection The selection based on which the insertion position should be calculated.
144
+ * @param model Model instance.
145
+ * @returns The optimal range.
146
+ */
147
+ export declare function findOptimalInsertionRange(selection: Selection | DocumentSelection, model: Model): Range;
148
+ /**
149
+ * A util to be used in order to map view positions to correct model positions when implementing a widget
150
+ * which renders non-empty view element for an empty model element.
151
+ *
152
+ * For example:
153
+ *
154
+ * ```
155
+ * // Model:
156
+ * <placeholder type="name"></placeholder>
157
+ *
158
+ * // View:
159
+ * <span class="placeholder">name</span>
160
+ * ```
161
+ *
162
+ * In such case, view positions inside `<span>` cannot be correctly mapped to the model (because the model element is empty).
163
+ * To handle mapping positions inside `<span class="placeholder">` to the model use this util as follows:
164
+ *
165
+ * ```ts
166
+ * editor.editing.mapper.on(
167
+ * 'viewToModelPosition',
168
+ * viewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )
169
+ * );
170
+ * ```
171
+ *
172
+ * The callback will try to map the view offset of selection to an expected model position.
173
+ *
174
+ * 1. When the position is at the end (or in the middle) of the inline widget:
175
+ *
176
+ * ```
177
+ * // View:
178
+ * <p>foo <span class="placeholder">name|</span> bar</p>
179
+ *
180
+ * // Model:
181
+ * <paragraph>foo <placeholder type="name"></placeholder>| bar</paragraph>
182
+ * ```
183
+ *
184
+ * 2. When the position is at the beginning of the inline widget:
185
+ *
186
+ * ```
187
+ * // View:
188
+ * <p>foo <span class="placeholder">|name</span> bar</p>
189
+ *
190
+ * // Model:
191
+ * <paragraph>foo |<placeholder type="name"></placeholder> bar</paragraph>
192
+ * ```
193
+ *
194
+ * @param model Model instance on which the callback operates.
195
+ * @param viewElementMatcher Function that is passed a view element and should return `true` if the custom mapping
196
+ * should be applied to the given view element.
197
+ */
198
+ export declare function viewToModelPositionOutsideModelElement(model: Model, viewElementMatcher: (element: ViewElement) => boolean): GetCallback<MapperViewToModelPositionEvent>;