@ckeditor/ckeditor5-widget 36.0.0 → 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 +23 -22
- package/src/highlightstack.d.ts +74 -0
- package/src/highlightstack.js +15 -28
- package/src/index.d.ts +9 -0
- package/src/utils.d.ts +198 -0
- package/src/utils.js +90 -107
- package/src/verticalnavigation.d.ts +15 -0
- package/src/verticalnavigation.js +35 -36
- package/src/widget.d.ts +94 -0
- package/src/widget.js +19 -41
- package/src/widgetresize/resizer.d.ts +177 -0
- package/src/widgetresize/resizer.js +15 -77
- package/src/widgetresize/resizerstate.d.ts +125 -0
- package/src/widgetresize/resizerstate.js +36 -95
- package/src/widgetresize/sizeview.d.ts +55 -0
- package/src/widgetresize/sizeview.js +2 -34
- package/src/widgetresize.d.ts +130 -0
- package/src/widgetresize.js +11 -44
- package/src/widgettoolbarrepository.d.ts +98 -0
- package/src/widgettoolbarrepository.js +29 -50
- package/src/widgettypearound/utils.d.ts +38 -0
- package/src/widgettypearound/utils.js +2 -16
- package/src/widgettypearound/widgettypearound.d.ts +232 -0
- package/src/widgettypearound/widgettypearound.js +44 -83
@@ -28,10 +28,17 @@ const PLUGIN_DISABLED_EDITING_ROOT_CLASS = 'ck-widget__type-around_disabled';
|
|
28
28
|
* with two buttons into each widget instance in the editor. Each of the buttons can be clicked by the
|
29
29
|
* user if the widget is next to the "tight spot". Once clicked, a paragraph is created with the selection anchored
|
30
30
|
* in it so that users can type (or insert content, paste, etc.) straight away.
|
31
|
-
*
|
32
|
-
* @extends module:core/plugin~Plugin
|
33
31
|
*/
|
34
32
|
export default class WidgetTypeAround extends Plugin {
|
33
|
+
constructor() {
|
34
|
+
super(...arguments);
|
35
|
+
/**
|
36
|
+
* A reference to the model widget element that has the fake caret active
|
37
|
+
* on either side of it. It is later used to remove CSS classes associated with the fake caret
|
38
|
+
* when the widget no longer needs it.
|
39
|
+
*/
|
40
|
+
this._currentFakeCaretModelElement = null;
|
41
|
+
}
|
35
42
|
/**
|
36
43
|
* @inheritDoc
|
37
44
|
*/
|
@@ -44,21 +51,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
44
51
|
static get requires() {
|
45
52
|
return [Enter, Delete];
|
46
53
|
}
|
47
|
-
/**
|
48
|
-
* @inheritDoc
|
49
|
-
*/
|
50
|
-
constructor(editor) {
|
51
|
-
super(editor);
|
52
|
-
/**
|
53
|
-
* A reference to the model widget element that has the fake caret active
|
54
|
-
* on either side of it. It is later used to remove CSS classes associated with the fake caret
|
55
|
-
* when the widget no longer needs it.
|
56
|
-
*
|
57
|
-
* @private
|
58
|
-
* @member {module:engine/model/element~Element|null}
|
59
|
-
*/
|
60
|
-
this._currentFakeCaretModelElement = null;
|
61
|
-
}
|
62
54
|
/**
|
63
55
|
* @inheritDoc
|
64
56
|
*/
|
@@ -107,9 +99,8 @@ export default class WidgetTypeAround extends Plugin {
|
|
107
99
|
* **Note**: This method is heavily user-oriented and will both focus the editing view and scroll
|
108
100
|
* the viewport to the selection in the inserted paragraph.
|
109
101
|
*
|
110
|
-
* @
|
111
|
-
* @param
|
112
|
-
* @param {'before'|'after'} position The position where the paragraph is inserted. Either `'before'` or `'after'` the widget.
|
102
|
+
* @param widgetModelElement The model widget element next to which a paragraph is inserted.
|
103
|
+
* @param position The position where the paragraph is inserted. Either `'before'` or `'after'` the widget.
|
113
104
|
*/
|
114
105
|
_insertParagraph(widgetModelElement, position) {
|
115
106
|
const editor = this.editor;
|
@@ -126,14 +117,12 @@ export default class WidgetTypeAround extends Plugin {
|
|
126
117
|
* A wrapper for the {@link module:utils/emittermixin~EmitterMixin#listenTo} method that executes the callbacks only
|
127
118
|
* when the plugin {@link #isEnabled is enabled}.
|
128
119
|
*
|
129
|
-
* @
|
130
|
-
* @param
|
131
|
-
* @param
|
132
|
-
* @param
|
133
|
-
* @param
|
134
|
-
*
|
135
|
-
* the priority value the sooner the callback will be fired. Events having the same priority are called in the
|
136
|
-
* order they were added.
|
120
|
+
* @param emitter The object that fires the event.
|
121
|
+
* @param event The name of the event.
|
122
|
+
* @param callback The function to be called on event.
|
123
|
+
* @param options Additional options.
|
124
|
+
* @param options.priority The priority of this event callback. The higher the priority value the sooner
|
125
|
+
* the callback will be fired. Events having the same priority are called in the order they were added.
|
137
126
|
*/
|
138
127
|
_listenToIfEnabled(emitter, event, callback, options) {
|
139
128
|
this.listenTo(emitter, event, (...args) => {
|
@@ -152,8 +141,7 @@ export default class WidgetTypeAround extends Plugin {
|
|
152
141
|
* the insertion can only happen when the widget's fake caret is active (e.g. activated
|
153
142
|
* using the keyboard).
|
154
143
|
*
|
155
|
-
* @
|
156
|
-
* @returns {Boolean} Returns `true` when the paragraph was inserted (the attribute was present) and `false` otherwise.
|
144
|
+
* @returns Returns `true` when the paragraph was inserted (the attribute was present) and `false` otherwise.
|
157
145
|
*/
|
158
146
|
_insertParagraphAccordingToFakeCaretPosition() {
|
159
147
|
const editor = this.editor;
|
@@ -163,7 +151,7 @@ export default class WidgetTypeAround extends Plugin {
|
|
163
151
|
if (!typeAroundFakeCaretPosition) {
|
164
152
|
return false;
|
165
153
|
}
|
166
|
-
// @if CK_DEBUG_TYPING // if ( window.logCKETyping ) {
|
154
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
167
155
|
// @if CK_DEBUG_TYPING // console.info( '%c[WidgetTypeAround]%c Fake caret -> insert paragraph',
|
168
156
|
// @if CK_DEBUG_TYPING // 'font-weight: bold; color: green', ''
|
169
157
|
// @if CK_DEBUG_TYPING // );
|
@@ -178,8 +166,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
178
166
|
*
|
179
167
|
* The UI is delivered as a {@link module:engine/view/uielement~UIElement}
|
180
168
|
* wrapper which renders DOM buttons that users can use to insert paragraphs.
|
181
|
-
*
|
182
|
-
* @private
|
183
169
|
*/
|
184
170
|
_enableTypeAroundUIInjection() {
|
185
171
|
const editor = this.editor;
|
@@ -228,8 +214,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
228
214
|
* does the CSS class clean-up in the view.
|
229
215
|
* 6. Additionally, `change:range` and `FocusTracker#isFocused` listeners also remove the selection
|
230
216
|
* attribute (the former also removes widget CSS classes).
|
231
|
-
*
|
232
|
-
* @private
|
233
217
|
*/
|
234
218
|
_enableTypeAroundFakeCaretActivationUsingKeyboardArrows() {
|
235
219
|
const editor = this.editor;
|
@@ -323,8 +307,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
323
307
|
* in this listener, and stopping and preventing the event that would normally be handled by the widget
|
324
308
|
* plugin that is responsible for the regular keyboard navigation near/across all widgets (that
|
325
309
|
* includes inline widgets, which are ignored by the widget type around plugin).
|
326
|
-
*
|
327
|
-
* @private
|
328
310
|
*/
|
329
311
|
_handleArrowKeyPress(evt, domEventData) {
|
330
312
|
const editor = this.editor;
|
@@ -360,10 +342,9 @@ export default class WidgetTypeAround extends Plugin {
|
|
360
342
|
* the fake caret for that widget, depending on the current value of the `widget-type-around` model
|
361
343
|
* selection attribute and the direction of the pressed arrow key.
|
362
344
|
*
|
363
|
-
* @
|
364
|
-
* @param {Boolean} isForward `true` when the pressed arrow key was responsible for the forward model selection movement
|
345
|
+
* @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement
|
365
346
|
* as in {@link module:utils/keyboard~isForwardArrowKeyCode}.
|
366
|
-
* @returns
|
347
|
+
* @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should
|
367
348
|
* process the event any further. Returns `false` otherwise.
|
368
349
|
*/
|
369
350
|
_handleArrowKeyPressOnSelectedWidget(isForward) {
|
@@ -406,10 +387,9 @@ export default class WidgetTypeAround extends Plugin {
|
|
406
387
|
* Unfortunately, there is no safe way to let the widget plugin do the selection part first and then just set the
|
407
388
|
* selection attribute here in the widget type around plugin. This is why this code must duplicate some from the widget plugin.
|
408
389
|
*
|
409
|
-
* @
|
410
|
-
* @param {Boolean} isForward `true` when the pressed arrow key was responsible for the forward model selection movement
|
390
|
+
* @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement
|
411
391
|
* as in {@link module:utils/keyboard~isForwardArrowKeyCode}.
|
412
|
-
* @returns
|
392
|
+
* @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should
|
413
393
|
* process the event any further. Returns `false` otherwise.
|
414
394
|
*/
|
415
395
|
_handleArrowKeyPressWhenSelectionNextToAWidget(isForward) {
|
@@ -435,10 +415,9 @@ export default class WidgetTypeAround extends Plugin {
|
|
435
415
|
* Handles the keyboard navigation on "keydown" when a widget is currently selected (together with some other content)
|
436
416
|
* and the widget is the first or last element in the selection. It activates or deactivates the fake caret for that widget.
|
437
417
|
*
|
438
|
-
* @
|
439
|
-
* @param {Boolean} isForward `true` when the pressed arrow key was responsible for the forward model selection movement
|
418
|
+
* @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement
|
440
419
|
* as in {@link module:utils/keyboard~isForwardArrowKeyCode}.
|
441
|
-
* @returns
|
420
|
+
* @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should
|
442
421
|
* process the event any further. Returns `false` otherwise.
|
443
422
|
*/
|
444
423
|
_handleArrowKeyPressWhenNonCollapsedSelection(isForward) {
|
@@ -465,8 +444,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
465
444
|
* Registers a `mousedown` listener for the view document which intercepts events
|
466
445
|
* coming from the widget type around UI, which happens when a user clicks one of the buttons
|
467
446
|
* that insert a paragraph next to a widget.
|
468
|
-
*
|
469
|
-
* @private
|
470
447
|
*/
|
471
448
|
_enableInsertingParagraphsOnButtonClick() {
|
472
449
|
const editor = this.editor;
|
@@ -496,8 +473,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
496
473
|
*
|
497
474
|
* In the second case, the new paragraph is inserted based on whether a soft (<kbd>Shift</kbd>+<kbd>Enter</kbd>) keystroke
|
498
475
|
* was pressed or not.
|
499
|
-
*
|
500
|
-
* @private
|
501
476
|
*/
|
502
477
|
_enableInsertingParagraphsOnEnterKeypress() {
|
503
478
|
const editor = this.editor;
|
@@ -542,8 +517,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
542
517
|
* **Note**: At the moment this listener creates 2 undo steps: one for the `insertParagraph` command
|
543
518
|
* and another one for actual typing. It is not a disaster but this may need to be fixed
|
544
519
|
* sooner or later.
|
545
|
-
*
|
546
|
-
* @private
|
547
520
|
*/
|
548
521
|
_enableInsertingParagraphsOnTypingKeystroke() {
|
549
522
|
const editor = this.editor;
|
@@ -582,8 +555,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
582
555
|
* The fake caret should create an illusion of a real browser caret so that when it appears before or after
|
583
556
|
* a widget, pressing <kbd>Delete</kbd> or <kbd>Backspace</kbd> should remove a widget or delete the content
|
584
557
|
* before or after a widget (depending on the content surrounding the widget).
|
585
|
-
*
|
586
|
-
* @private
|
587
558
|
*/
|
588
559
|
_enableDeleteIntegration() {
|
589
560
|
const editor = this.editor;
|
@@ -656,8 +627,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
656
627
|
* content near a widget when the fake caret is first activated using the arrow keys.
|
657
628
|
*
|
658
629
|
* The content is inserted according to the `widget-type-around` selection attribute (see {@link #_handleArrowKeyPress}).
|
659
|
-
*
|
660
|
-
* @private
|
661
630
|
*/
|
662
631
|
_enableInsertContentIntegration() {
|
663
632
|
const editor = this.editor;
|
@@ -688,15 +657,13 @@ export default class WidgetTypeAround extends Plugin {
|
|
688
657
|
* to reflect user's intent of desired insertion position.
|
689
658
|
*
|
690
659
|
* The object is inserted according to the `widget-type-around` selection attribute (see {@link #_handleArrowKeyPress}).
|
691
|
-
*
|
692
|
-
* @private
|
693
660
|
*/
|
694
661
|
_enableInsertObjectIntegration() {
|
695
662
|
const editor = this.editor;
|
696
663
|
const model = this.editor.model;
|
697
664
|
const documentSelection = model.document.selection;
|
698
665
|
this._listenToIfEnabled(editor.model, 'insertObject', (evt, args) => {
|
699
|
-
const [, selectable,
|
666
|
+
const [, selectable, options = {}] = args;
|
700
667
|
if (selectable && !selectable.is('documentSelection')) {
|
701
668
|
return;
|
702
669
|
}
|
@@ -715,8 +682,6 @@ export default class WidgetTypeAround extends Plugin {
|
|
715
682
|
* This is required for cases that trigger {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`}
|
716
683
|
* before calling {@link module:engine/model/model~Model#insertContent `model.insertContent()`} like, for instance,
|
717
684
|
* plain text pasting.
|
718
|
-
*
|
719
|
-
* @private
|
720
685
|
*/
|
721
686
|
_enableDeleteContentIntegration() {
|
722
687
|
const editor = this.editor;
|
@@ -734,11 +699,9 @@ export default class WidgetTypeAround extends Plugin {
|
|
734
699
|
}, { priority: 'high' });
|
735
700
|
}
|
736
701
|
}
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
// @param {Object.<String,String>} buttonTitles
|
741
|
-
// @param {module:engine/view/element~Element} widgetViewElement
|
702
|
+
/**
|
703
|
+
* Injects the type around UI into a view widget instance.
|
704
|
+
*/
|
742
705
|
function injectUIIntoWidget(viewWriter, buttonTitles, widgetViewElement) {
|
743
706
|
const typeAroundWrapper = viewWriter.createUIElement('div', {
|
744
707
|
class: 'ck ck-reset_all ck-widget__type-around'
|
@@ -751,12 +714,11 @@ function injectUIIntoWidget(viewWriter, buttonTitles, widgetViewElement) {
|
|
751
714
|
// Inject the type around wrapper into the widget's wrapper.
|
752
715
|
viewWriter.insert(viewWriter.createPositionAt(widgetViewElement, 'end'), typeAroundWrapper);
|
753
716
|
}
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
// @param {Object.<String,String>} buttonTitles
|
717
|
+
/**
|
718
|
+
* FYI: Not using the IconView class because each instance would need to be destroyed to avoid memory leaks
|
719
|
+
* and it's pretty hard to figure out when a view (widget) is gone for good so it's cheaper to use raw
|
720
|
+
* <svg> here.
|
721
|
+
*/
|
760
722
|
function injectButtons(wrapperDomElement, buttonTitles) {
|
761
723
|
for (const position of POSSIBLE_INSERTION_POSITIONS) {
|
762
724
|
const buttonTemplate = new Template({
|
@@ -777,7 +739,6 @@ function injectButtons(wrapperDomElement, buttonTitles) {
|
|
777
739
|
wrapperDomElement.appendChild(buttonTemplate.render());
|
778
740
|
}
|
779
741
|
}
|
780
|
-
// @param {HTMLElement} wrapperDomElement
|
781
742
|
function injectFakeCaret(wrapperDomElement) {
|
782
743
|
const caretTemplate = new Template({
|
783
744
|
tag: 'div',
|
@@ -790,16 +751,16 @@ function injectFakeCaret(wrapperDomElement) {
|
|
790
751
|
});
|
791
752
|
wrapperDomElement.appendChild(caretTemplate.render());
|
792
753
|
}
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
754
|
+
/**
|
755
|
+
* Returns the ancestor of an element closest to the root which is empty. For instance,
|
756
|
+
* for `<baz>`:
|
757
|
+
*
|
758
|
+
* ```
|
759
|
+
* <foo>abc<bar><baz></baz></bar></foo>
|
760
|
+
* ```
|
761
|
+
*
|
762
|
+
* it returns `<bar>`.
|
763
|
+
*/
|
803
764
|
function getDeepestEmptyElementAncestor(schema, element) {
|
804
765
|
let deepestEmptyAncestor = element;
|
805
766
|
for (const ancestor of element.getAncestors({ parentFirst: true })) {
|