@ckeditor/ckeditor5-widget 28.0.0 → 30.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.
- package/README.md +2 -2
- package/lang/translations/ro.po +2 -2
- package/package.json +23 -22
- package/src/utils.js +22 -95
- package/src/verticalnavigation.js +21 -5
- package/src/widget.js +97 -13
- package/src/widgetresize/resizer.js +21 -79
- package/src/widgetresize/sizeview.js +114 -0
- package/src/widgetresize.js +18 -9
- package/src/widgettoolbarrepository.js +3 -6
- package/src/widgettypearound/widgettypearound.js +40 -0
- package/theme/widget.css +13 -2
- package/CHANGELOG.md +0 -260
package/README.md
CHANGED
@@ -2,8 +2,8 @@ CKEditor 5 widget API
|
|
2
2
|
========================================
|
3
3
|
|
4
4
|
[](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget)
|
5
|
-
[](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
6
|
+
[](https://travis-ci.com/ckeditor/ckeditor5)
|
7
7
|
|
8
8
|
This package implements the widget API for CKEditor 5.
|
9
9
|
|
package/lang/translations/ro.po
CHANGED
@@ -22,8 +22,8 @@ msgstr "Bară widget"
|
|
22
22
|
|
23
23
|
msgctxt "The title displayed when a mouse is over a button that inserts a paragraph before a block."
|
24
24
|
msgid "Insert paragraph before block"
|
25
|
-
msgstr ""
|
25
|
+
msgstr "Inserează un paragraf înaintea blocului"
|
26
26
|
|
27
27
|
msgctxt "The title displayed when a mouse is over a button that inserts a paragraph after a block."
|
28
28
|
msgid "Insert paragraph after block"
|
29
|
-
msgstr ""
|
29
|
+
msgstr "Inserează un paragraf după bloc"
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ckeditor/ckeditor5-widget",
|
3
|
-
"version": "
|
3
|
+
"version": "30.0.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": "^
|
15
|
-
"@ckeditor/ckeditor5-engine": "^
|
16
|
-
"@ckeditor/ckeditor5-enter": "^
|
17
|
-
"@ckeditor/ckeditor5-ui": "^
|
18
|
-
"@ckeditor/ckeditor5-utils": "^
|
19
|
-
"@ckeditor/ckeditor5-typing": "^
|
14
|
+
"@ckeditor/ckeditor5-core": "^30.0.0",
|
15
|
+
"@ckeditor/ckeditor5-engine": "^30.0.0",
|
16
|
+
"@ckeditor/ckeditor5-enter": "^30.0.0",
|
17
|
+
"@ckeditor/ckeditor5-ui": "^30.0.0",
|
18
|
+
"@ckeditor/ckeditor5-utils": "^30.0.0",
|
19
|
+
"@ckeditor/ckeditor5-typing": "^30.0.0",
|
20
20
|
"lodash-es": "^4.17.15"
|
21
21
|
},
|
22
22
|
"devDependencies": {
|
23
|
-
"@ckeditor/ckeditor5-basic-styles": "^
|
24
|
-
"@ckeditor/ckeditor5-block-quote": "^
|
25
|
-
"@ckeditor/ckeditor5-clipboard": "^
|
26
|
-
"@ckeditor/ckeditor5-editor-balloon": "^
|
27
|
-
"@ckeditor/ckeditor5-editor-classic": "^
|
28
|
-
"@ckeditor/ckeditor5-essentials": "^
|
29
|
-
"@ckeditor/ckeditor5-heading": "^
|
30
|
-
"@ckeditor/ckeditor5-horizontal-line": "^
|
31
|
-
"@ckeditor/ckeditor5-image": "^
|
32
|
-
"@ckeditor/ckeditor5-link": "^
|
33
|
-
"@ckeditor/ckeditor5-media-embed": "^
|
34
|
-
"@ckeditor/ckeditor5-paragraph": "^
|
35
|
-
"@ckeditor/ckeditor5-table": "^
|
36
|
-
"@ckeditor/ckeditor5-undo": "^
|
23
|
+
"@ckeditor/ckeditor5-basic-styles": "^30.0.0",
|
24
|
+
"@ckeditor/ckeditor5-block-quote": "^30.0.0",
|
25
|
+
"@ckeditor/ckeditor5-clipboard": "^30.0.0",
|
26
|
+
"@ckeditor/ckeditor5-editor-balloon": "^30.0.0",
|
27
|
+
"@ckeditor/ckeditor5-editor-classic": "^30.0.0",
|
28
|
+
"@ckeditor/ckeditor5-essentials": "^30.0.0",
|
29
|
+
"@ckeditor/ckeditor5-heading": "^30.0.0",
|
30
|
+
"@ckeditor/ckeditor5-horizontal-line": "^30.0.0",
|
31
|
+
"@ckeditor/ckeditor5-image": "^30.0.0",
|
32
|
+
"@ckeditor/ckeditor5-link": "^30.0.0",
|
33
|
+
"@ckeditor/ckeditor5-media-embed": "^30.0.0",
|
34
|
+
"@ckeditor/ckeditor5-paragraph": "^30.0.0",
|
35
|
+
"@ckeditor/ckeditor5-table": "^30.0.0",
|
36
|
+
"@ckeditor/ckeditor5-undo": "^30.0.0"
|
37
37
|
},
|
38
38
|
"engines": {
|
39
39
|
"node": ">=12.0.0",
|
@@ -51,6 +51,7 @@
|
|
51
51
|
"files": [
|
52
52
|
"lang",
|
53
53
|
"src",
|
54
|
-
"theme"
|
54
|
+
"theme",
|
55
|
+
"ckeditor5-metadata.json"
|
55
56
|
]
|
56
57
|
}
|
package/src/utils.js
CHANGED
@@ -7,10 +7,6 @@
|
|
7
7
|
* @module widget/utils
|
8
8
|
*/
|
9
9
|
|
10
|
-
import BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';
|
11
|
-
|
12
|
-
import global from '@ckeditor/ckeditor5-utils/src/dom/global';
|
13
|
-
import Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';
|
14
10
|
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
15
11
|
import toArray from '@ckeditor/ckeditor5-utils/src/toarray';
|
16
12
|
|
@@ -124,7 +120,7 @@ export function toWidget( element, writer, options = {} ) {
|
|
124
120
|
addSelectionHandle( element, writer );
|
125
121
|
}
|
126
122
|
|
127
|
-
setHighlightHandling( element, writer
|
123
|
+
setHighlightHandling( element, writer );
|
128
124
|
|
129
125
|
return element;
|
130
126
|
}
|
@@ -171,10 +167,10 @@ function removeHighlight( element, descriptor, writer ) {
|
|
171
167
|
*
|
172
168
|
* @param {module:engine/view/element~Element} element
|
173
169
|
* @param {module:engine/view/downcastwriter~DowncastWriter} writer
|
174
|
-
* @param {Function} add
|
175
|
-
* @param {Function} remove
|
170
|
+
* @param {Function} [add]
|
171
|
+
* @param {Function} [remove]
|
176
172
|
*/
|
177
|
-
export function setHighlightHandling( element, writer, add, remove ) {
|
173
|
+
export function setHighlightHandling( element, writer, add = addHighlight, remove = removeHighlight ) {
|
178
174
|
const stack = new HighlightStack();
|
179
175
|
|
180
176
|
stack.on( 'change:top', ( evt, data ) => {
|
@@ -227,6 +223,7 @@ export function getLabel( element ) {
|
|
227
223
|
* otherwise sets it to `false`,
|
228
224
|
* * adds the `ck-editor__editable` and `ck-editor__nested-editable` CSS classes,
|
229
225
|
* * adds the `ck-editor__nested-editable_focused` CSS class when the editable is focused and removes it when it is blurred.
|
226
|
+
* * implements the {@link ~setHighlightHandling view highlight on widget's editable}.
|
230
227
|
*
|
231
228
|
* Similarly to {@link ~toWidget `toWidget()`} this function should be used in `editingDowncast` only and it is usually
|
232
229
|
* used together with {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.
|
@@ -278,26 +275,28 @@ export function toWidgetEditable( editable, writer ) {
|
|
278
275
|
}
|
279
276
|
} );
|
280
277
|
|
278
|
+
setHighlightHandling( editable, writer );
|
279
|
+
|
281
280
|
return editable;
|
282
281
|
}
|
283
282
|
|
284
283
|
/**
|
285
|
-
* Returns a model
|
284
|
+
* Returns a model range which is optimal (in terms of UX) for inserting a widget block.
|
286
285
|
*
|
287
|
-
* For instance, if a selection is in the middle of a paragraph, the
|
286
|
+
* For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph
|
288
287
|
* will be returned so that it is not split. If the selection is at the end of a paragraph,
|
289
|
-
* the
|
288
|
+
* the collapsed range after this paragraph will be returned.
|
290
289
|
*
|
291
|
-
* Note: If the selection is placed in an empty block, that block will be returned. If that
|
292
|
-
* is then passed to {@link module:engine/model/model~Model#insertContent},
|
293
|
-
* the
|
290
|
+
* Note: If the selection is placed in an empty block, the range in that block will be returned. If that range
|
291
|
+
* is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced
|
292
|
+
* by the inserted widget block.
|
294
293
|
*
|
295
294
|
* @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
|
296
295
|
* The selection based on which the insertion position should be calculated.
|
297
296
|
* @param {module:engine/model/model~Model} model Model instance.
|
298
|
-
* @returns {module:engine/model/
|
297
|
+
* @returns {module:engine/model/range~Range} The optimal range.
|
299
298
|
*/
|
300
|
-
export function
|
299
|
+
export function findOptimalInsertionRange( selection, model ) {
|
301
300
|
const selectedElement = selection.getSelectedElement();
|
302
301
|
|
303
302
|
if ( selectedElement ) {
|
@@ -306,11 +305,11 @@ export function findOptimalInsertionPosition( selection, model ) {
|
|
306
305
|
// If the WidgetTypeAround "fake caret" is displayed, use its position for the insertion
|
307
306
|
// to provide the most predictable UX (https://github.com/ckeditor/ckeditor5/issues/7438).
|
308
307
|
if ( typeAroundFakeCaretPosition ) {
|
309
|
-
return model.createPositionAt( selectedElement, typeAroundFakeCaretPosition );
|
308
|
+
return model.createRange( model.createPositionAt( selectedElement, typeAroundFakeCaretPosition ) );
|
310
309
|
}
|
311
310
|
|
312
|
-
if ( model.schema.
|
313
|
-
return model.
|
311
|
+
if ( model.schema.isObject( selectedElement ) && !model.schema.isInline( selectedElement ) ) {
|
312
|
+
return model.createRangeOn( selectedElement );
|
314
313
|
}
|
315
314
|
}
|
316
315
|
|
@@ -320,34 +319,21 @@ export function findOptimalInsertionPosition( selection, model ) {
|
|
320
319
|
// If inserting into an empty block – return position in that block. It will get
|
321
320
|
// replaced with the image by insertContent(). #42.
|
322
321
|
if ( firstBlock.isEmpty ) {
|
323
|
-
return model.createPositionAt( firstBlock, 0 );
|
322
|
+
return model.createRange( model.createPositionAt( firstBlock, 0 ) );
|
324
323
|
}
|
325
324
|
|
326
325
|
const positionAfter = model.createPositionAfter( firstBlock );
|
327
326
|
|
328
327
|
// If selection is at the end of the block - return position after the block.
|
329
328
|
if ( selection.focus.isTouching( positionAfter ) ) {
|
330
|
-
return positionAfter;
|
329
|
+
return model.createRange( positionAfter );
|
331
330
|
}
|
332
331
|
|
333
332
|
// Otherwise return position before the block.
|
334
|
-
return model.createPositionBefore( firstBlock );
|
333
|
+
return model.createRange( model.createPositionBefore( firstBlock ) );
|
335
334
|
}
|
336
335
|
|
337
|
-
return selection.focus;
|
338
|
-
}
|
339
|
-
|
340
|
-
/**
|
341
|
-
* Checks if the selection is on an object.
|
342
|
-
*
|
343
|
-
* @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
|
344
|
-
* @param {module:engine/model/schema~Schema} schema
|
345
|
-
* @returns {Boolean}
|
346
|
-
*/
|
347
|
-
export function checkSelectionOnObject( selection, schema ) {
|
348
|
-
const selectedElement = selection.getSelectedElement();
|
349
|
-
|
350
|
-
return !!selectedElement && schema.isObject( selectedElement );
|
336
|
+
return model.createRange( selection.focus );
|
351
337
|
}
|
352
338
|
|
353
339
|
/**
|
@@ -409,65 +395,6 @@ export function viewToModelPositionOutsideModelElement( model, viewElementMatche
|
|
409
395
|
};
|
410
396
|
}
|
411
397
|
|
412
|
-
/**
|
413
|
-
* A positioning function passed to the {@link module:utils/dom/position~getOptimalPosition} helper as a last resort
|
414
|
-
* when attaching {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView balloon UI} to widgets.
|
415
|
-
* It comes in handy when a widget is longer than the visual viewport of the web browser and/or upper/lower boundaries
|
416
|
-
* of a widget are off screen because of the web page scroll.
|
417
|
-
*
|
418
|
-
* ┌─┄┄┄┄┄┄┄┄┄Widget┄┄┄┄┄┄┄┄┄┐
|
419
|
-
* ┊ ┊
|
420
|
-
* ┌────────────Viewport───────────┐ ┌──╁─────────Viewport────────╁──┐
|
421
|
-
* │ ┏━━━━━━━━━━Widget━━━━━━━━━┓ │ │ ┃ ^ ┃ │
|
422
|
-
* │ ┃ ^ ┃ │ │ ┃ ╭───────/ \───────╮ ┃ │
|
423
|
-
* │ ┃ ╭───────/ \───────╮ ┃ │ │ ┃ │ Balloon │ ┃ │
|
424
|
-
* │ ┃ │ Balloon │ ┃ │ │ ┃ ╰─────────────────╯ ┃ │
|
425
|
-
* │ ┃ ╰─────────────────╯ ┃ │ │ ┃ ┃ │
|
426
|
-
* │ ┃ ┃ │ │ ┃ ┃ │
|
427
|
-
* │ ┃ ┃ │ │ ┃ ┃ │
|
428
|
-
* │ ┃ ┃ │ │ ┃ ┃ │
|
429
|
-
* │ ┃ ┃ │ │ ┃ ┃ │
|
430
|
-
* │ ┃ ┃ │ │ ┃ ┃ │
|
431
|
-
* │ ┃ ┃ │ │ ┃ ┃ │
|
432
|
-
* └──╀─────────────────────────╀──┘ └──╀─────────────────────────╀──┘
|
433
|
-
* ┊ ┊ ┊ ┊
|
434
|
-
* ┊ ┊ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
|
435
|
-
* ┊ ┊
|
436
|
-
* └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
|
437
|
-
*
|
438
|
-
* **Note**: Works best if used together with
|
439
|
-
* {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions default `BalloonPanelView` positions}
|
440
|
-
* like `northArrowSouth` and `southArrowNorth`; the transition between these two and this position is smooth.
|
441
|
-
*
|
442
|
-
* @param {module:utils/dom/rect~Rect} widgetRect A rect of the widget.
|
443
|
-
* @param {module:utils/dom/rect~Rect} balloonRect A rect of the balloon.
|
444
|
-
* @returns {module:utils/dom/position~Position|null}
|
445
|
-
*/
|
446
|
-
export function centeredBalloonPositionForLongWidgets( widgetRect, balloonRect ) {
|
447
|
-
const viewportRect = new Rect( global.window );
|
448
|
-
const viewportWidgetInsersectionRect = viewportRect.getIntersection( widgetRect );
|
449
|
-
|
450
|
-
const balloonTotalHeight = balloonRect.height + BalloonPanelView.arrowVerticalOffset;
|
451
|
-
|
452
|
-
// If there is enough space above or below the widget then this position should not be used.
|
453
|
-
if ( widgetRect.top - balloonTotalHeight > viewportRect.top || widgetRect.bottom + balloonTotalHeight < viewportRect.bottom ) {
|
454
|
-
return null;
|
455
|
-
}
|
456
|
-
|
457
|
-
// Because this is a last resort positioning, to keep things simple we're not playing with positions of the arrow
|
458
|
-
// like, for instance, "south west" or whatever. Just try to keep the balloon in the middle of the visible area of
|
459
|
-
// the widget for as long as it is possible. If the widgets becomes invisible (because cropped by the viewport),
|
460
|
-
// just... place the balloon in the middle of it (because why not?).
|
461
|
-
const targetRect = viewportWidgetInsersectionRect || widgetRect;
|
462
|
-
const left = targetRect.left + targetRect.width / 2 - balloonRect.width / 2;
|
463
|
-
|
464
|
-
return {
|
465
|
-
top: Math.max( widgetRect.top, 0 ) + BalloonPanelView.arrowVerticalOffset,
|
466
|
-
left,
|
467
|
-
name: 'arrow_n'
|
468
|
-
};
|
469
|
-
}
|
470
|
-
|
471
398
|
// Default filler offset function applied to all widget elements.
|
472
399
|
//
|
473
400
|
// @returns {null}
|
@@ -40,15 +40,29 @@ export default function verticalNavigationHandler( editing ) {
|
|
40
40
|
// Find a range between selection and closest limit element.
|
41
41
|
const range = findTextRangeFromSelection( editing, selection, isForward );
|
42
42
|
|
43
|
-
|
43
|
+
// There is no selection position inside the limit element.
|
44
|
+
if ( !range ) {
|
44
45
|
return;
|
45
46
|
}
|
46
47
|
|
48
|
+
// If already at the edge of a limit element.
|
49
|
+
if ( range.isCollapsed ) {
|
50
|
+
// A collapsed selection at limit edge - nothing more to do.
|
51
|
+
if ( selection.isCollapsed ) {
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
|
55
|
+
// A non collapsed selection is at the limit edge while expanding the selection - let others do their stuff.
|
56
|
+
else if ( expandSelection ) {
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
47
61
|
// If the range is a single line (there is no word wrapping) then move the selection to the position closest to the limit element.
|
48
62
|
//
|
49
63
|
// We can't move the selection directly to the isObject element (eg. table cell) because of dual position at the end/beginning
|
50
64
|
// of wrapped line (it's at the same time at the end of one line and at the start of the next line).
|
51
|
-
if ( isSingleLineRange( editing, range, isForward ) ) {
|
65
|
+
if ( range.isCollapsed || isSingleLineRange( editing, range, isForward ) ) {
|
52
66
|
model.change( writer => {
|
53
67
|
const newPosition = isForward ? range.end : range.start;
|
54
68
|
|
@@ -94,7 +108,7 @@ function findTextRangeFromSelection( editing, selection, isForward ) {
|
|
94
108
|
const range = model.createRange( startPosition, endPosition );
|
95
109
|
const lastRangePosition = getNearestTextPosition( model.schema, range, 'backward' );
|
96
110
|
|
97
|
-
if ( lastRangePosition
|
111
|
+
if ( lastRangePosition ) {
|
98
112
|
return model.createRange( startPosition, lastRangePosition );
|
99
113
|
}
|
100
114
|
|
@@ -111,7 +125,7 @@ function findTextRangeFromSelection( editing, selection, isForward ) {
|
|
111
125
|
const range = model.createRange( startPosition, endPosition );
|
112
126
|
const firstRangePosition = getNearestTextPosition( model.schema, range, 'forward' );
|
113
127
|
|
114
|
-
if ( firstRangePosition
|
128
|
+
if ( firstRangePosition ) {
|
115
129
|
return model.createRange( firstRangePosition, endPosition );
|
116
130
|
}
|
117
131
|
|
@@ -152,7 +166,7 @@ function getNearestNonInlineLimit( model, startPosition, direction ) {
|
|
152
166
|
// @param {module:engine/model/schema~Schema} schema The schema.
|
153
167
|
// @param {module:engine/model/range~Range} range The range to find the position in.
|
154
168
|
// @param {'forward'|'backward'} direction Search direction.
|
155
|
-
// @returns {module:engine/model/position~Position} The nearest selection
|
169
|
+
// @returns {module:engine/model/position~Position|null} The nearest selection position.
|
156
170
|
//
|
157
171
|
function getNearestTextPosition( schema, range, direction ) {
|
158
172
|
const position = direction == 'backward' ? range.end : range.start;
|
@@ -166,6 +180,8 @@ function getNearestTextPosition( schema, range, direction ) {
|
|
166
180
|
return nextPosition;
|
167
181
|
}
|
168
182
|
}
|
183
|
+
|
184
|
+
return null;
|
169
185
|
}
|
170
186
|
|
171
187
|
// Checks if the DOM range corresponding to the provided model range renders as a single line by analyzing DOMRects
|
package/src/widget.js
CHANGED
@@ -11,12 +11,13 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
|
11
11
|
import MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';
|
12
12
|
import WidgetTypeAround from './widgettypearound/widgettypearound';
|
13
13
|
import Delete from '@ckeditor/ckeditor5-typing/src/delete';
|
14
|
-
import { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils';
|
15
|
-
import { isForwardArrowKeyCode } from '@ckeditor/ckeditor5-utils/src/keyboard';
|
16
14
|
import env from '@ckeditor/ckeditor5-utils/src/env';
|
15
|
+
import { getLocalizedArrowKeyCodeDirection } from '@ckeditor/ckeditor5-utils/src/keyboard';
|
17
16
|
|
18
|
-
import '../theme/widget.css';
|
19
17
|
import verticalNavigationHandler from './verticalnavigation';
|
18
|
+
import { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils';
|
19
|
+
|
20
|
+
import '../theme/widget.css';
|
20
21
|
|
21
22
|
/**
|
22
23
|
* The widget plugin. It enables base support for widgets.
|
@@ -52,7 +53,8 @@ export default class Widget extends Plugin {
|
|
52
53
|
* @inheritDoc
|
53
54
|
*/
|
54
55
|
init() {
|
55
|
-
const
|
56
|
+
const editor = this.editor;
|
57
|
+
const view = editor.editing.view;
|
56
58
|
const viewDocument = view.document;
|
57
59
|
|
58
60
|
/**
|
@@ -64,17 +66,69 @@ export default class Widget extends Plugin {
|
|
64
66
|
this._previouslySelected = new Set();
|
65
67
|
|
66
68
|
// Model to view selection converter.
|
67
|
-
// Converts selection placed over widget element to fake selection
|
69
|
+
// Converts selection placed over widget element to fake selection.
|
70
|
+
//
|
71
|
+
// By default, the selection is downcasted by the engine to surround the attribute element, even though its only
|
72
|
+
// child is an inline widget. A similar thing also happens when a collapsed marker is rendered as a UI element
|
73
|
+
// next to an inline widget: the view selection contains both the widget and the marker.
|
74
|
+
//
|
75
|
+
// This prevents creating a correct fake selection when this inline widget is selected. Normalize the selection
|
76
|
+
// in these cases based on the model:
|
77
|
+
//
|
78
|
+
// [<attributeElement><inlineWidget /></attributeElement>] -> <attributeElement>[<inlineWidget />]</attributeElement>
|
79
|
+
// [<uiElement></uiElement><inlineWidget />] -> <uiElement></uiElement>[<inlineWidget />]
|
80
|
+
//
|
81
|
+
// Thanks to this:
|
82
|
+
//
|
83
|
+
// * fake selection can be set correctly,
|
84
|
+
// * any logic depending on (View)Selection#getSelectedElement() also works OK.
|
85
|
+
//
|
86
|
+
// See https://github.com/ckeditor/ckeditor5/issues/9524.
|
87
|
+
this.editor.editing.downcastDispatcher.on( 'selection', ( evt, data, conversionApi ) => {
|
88
|
+
const viewWriter = conversionApi.writer;
|
89
|
+
const modelSelection = data.selection;
|
90
|
+
|
91
|
+
// The collapsed selection can't contain any widget.
|
92
|
+
if ( modelSelection.isCollapsed ) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
|
96
|
+
const selectedModelElement = modelSelection.getSelectedElement();
|
97
|
+
|
98
|
+
if ( !selectedModelElement ) {
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
|
102
|
+
const selectedViewElement = editor.editing.mapper.toViewElement( selectedModelElement );
|
103
|
+
|
104
|
+
if ( !isWidget( selectedViewElement ) ) {
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
|
108
|
+
if ( !conversionApi.consumable.consume( modelSelection, 'selection' ) ) {
|
109
|
+
return;
|
110
|
+
}
|
111
|
+
|
112
|
+
viewWriter.setSelection( viewWriter.createRangeOn( selectedViewElement ), {
|
113
|
+
fake: true,
|
114
|
+
label: getLabel( selectedViewElement )
|
115
|
+
} );
|
116
|
+
} );
|
117
|
+
|
118
|
+
// Mark all widgets inside the selection with the css class.
|
119
|
+
// This handler is registered at the 'low' priority so it's triggered after the real selection conversion.
|
68
120
|
this.editor.editing.downcastDispatcher.on( 'selection', ( evt, data, conversionApi ) => {
|
69
121
|
// Remove selected class from previously selected widgets.
|
70
122
|
this._clearPreviouslySelectedWidgets( conversionApi.writer );
|
71
123
|
|
72
124
|
const viewWriter = conversionApi.writer;
|
73
125
|
const viewSelection = viewWriter.document.selection;
|
74
|
-
|
126
|
+
|
75
127
|
let lastMarked = null;
|
76
128
|
|
77
129
|
for ( const range of viewSelection.getRanges() ) {
|
130
|
+
// Note: There could be multiple selected widgets in a range but no fake selection.
|
131
|
+
// All of them must be marked as selected, for instance [<widget></widget><widget></widget>]
|
78
132
|
for ( const value of range ) {
|
79
133
|
const node = value.item;
|
80
134
|
|
@@ -84,11 +138,6 @@ export default class Widget extends Plugin {
|
|
84
138
|
|
85
139
|
this._previouslySelected.add( node );
|
86
140
|
lastMarked = node;
|
87
|
-
|
88
|
-
// Check if widget is a single element selected.
|
89
|
-
if ( node == selectedElement ) {
|
90
|
-
viewWriter.setSelection( viewSelection.getRanges(), { fake: true, label: getLabel( selectedElement ) } );
|
91
|
-
}
|
92
141
|
}
|
93
142
|
}
|
94
143
|
}
|
@@ -208,7 +257,9 @@ export default class Widget extends Plugin {
|
|
208
257
|
const schema = model.schema;
|
209
258
|
const modelSelection = model.document.selection;
|
210
259
|
const objectElement = modelSelection.getSelectedElement();
|
211
|
-
const
|
260
|
+
const direction = getLocalizedArrowKeyCodeDirection( keyCode, this.editor.locale.contentLanguageDirection );
|
261
|
+
const isForward = direction == 'down' || direction == 'right';
|
262
|
+
const isVerticalNavigation = direction == 'up' || direction == 'down';
|
212
263
|
|
213
264
|
// If object element is selected.
|
214
265
|
if ( objectElement && schema.isObject( objectElement ) ) {
|
@@ -227,15 +278,42 @@ export default class Widget extends Plugin {
|
|
227
278
|
return;
|
228
279
|
}
|
229
280
|
|
230
|
-
//
|
281
|
+
// Handle collapsing of the selection when there is any widget on the edge of selection.
|
282
|
+
// This is needed because browsers have problems with collapsing such selection.
|
283
|
+
if ( !modelSelection.isCollapsed && !domEventData.shiftKey ) {
|
284
|
+
const firstPosition = modelSelection.getFirstPosition();
|
285
|
+
const lastPosition = modelSelection.getLastPosition();
|
286
|
+
|
287
|
+
const firstSelectedNode = firstPosition.nodeAfter;
|
288
|
+
const lastSelectedNode = lastPosition.nodeBefore;
|
289
|
+
|
290
|
+
if ( firstSelectedNode && schema.isObject( firstSelectedNode ) || lastSelectedNode && schema.isObject( lastSelectedNode ) ) {
|
291
|
+
model.change( writer => {
|
292
|
+
writer.setSelection( isForward ? lastPosition : firstPosition );
|
293
|
+
} );
|
294
|
+
|
295
|
+
domEventData.preventDefault();
|
296
|
+
eventInfo.stop();
|
297
|
+
}
|
298
|
+
|
299
|
+
return;
|
300
|
+
}
|
301
|
+
|
231
302
|
// Return if not collapsed.
|
232
303
|
if ( !modelSelection.isCollapsed ) {
|
233
304
|
return;
|
234
305
|
}
|
235
306
|
|
307
|
+
// If selection is next to object element.
|
308
|
+
|
236
309
|
const objectElementNextToSelection = this._getObjectElementNextToSelection( isForward );
|
237
310
|
|
238
311
|
if ( objectElementNextToSelection && schema.isObject( objectElementNextToSelection ) ) {
|
312
|
+
// Do not select an inline widget while handling up/down arrow.
|
313
|
+
if ( schema.isInline( objectElementNextToSelection ) && isVerticalNavigation ) {
|
314
|
+
return;
|
315
|
+
}
|
316
|
+
|
239
317
|
this._setSelectionOverElement( objectElementNextToSelection );
|
240
318
|
|
241
319
|
domEventData.preventDefault();
|
@@ -338,6 +416,12 @@ export default class Widget extends Plugin {
|
|
338
416
|
// to its current state after undo.
|
339
417
|
const probe = model.createSelection( modelSelection );
|
340
418
|
model.modifySelection( probe, { direction: forward ? 'forward' : 'backward' } );
|
419
|
+
|
420
|
+
// The selection didn't change so there is nothing there.
|
421
|
+
if ( probe.isEqual( modelSelection ) ) {
|
422
|
+
return null;
|
423
|
+
}
|
424
|
+
|
341
425
|
const objectElement = forward ? probe.focus.nodeBefore : probe.focus.nodeAfter;
|
342
426
|
|
343
427
|
if ( !!objectElement && schema.isObject( objectElement ) ) {
|
@@ -7,7 +7,6 @@
|
|
7
7
|
* @module widget/widgetresize/resizer
|
8
8
|
*/
|
9
9
|
|
10
|
-
import View from '@ckeditor/ckeditor5-ui/src/view';
|
11
10
|
import Template from '@ckeditor/ckeditor5-ui/src/template';
|
12
11
|
import Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';
|
13
12
|
import compareArrays from '@ckeditor/ckeditor5-utils/src/comparearrays';
|
@@ -16,6 +15,7 @@ import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
|
|
16
15
|
import mix from '@ckeditor/ckeditor5-utils/src/mix';
|
17
16
|
|
18
17
|
import ResizeState from './resizerstate';
|
18
|
+
import SizeView from './sizeview';
|
19
19
|
|
20
20
|
/**
|
21
21
|
* Represents a resizer for a single resizable object.
|
@@ -41,7 +41,7 @@ export default class Resizer {
|
|
41
41
|
*
|
42
42
|
* @protected
|
43
43
|
* @readonly
|
44
|
-
* @member {module:widget/widgetresize/
|
44
|
+
* @member {module:widget/widgetresize/sizeview~SizeView} #_sizeView
|
45
45
|
*/
|
46
46
|
|
47
47
|
/**
|
@@ -52,17 +52,6 @@ export default class Resizer {
|
|
52
52
|
*/
|
53
53
|
this._options = options;
|
54
54
|
|
55
|
-
/**
|
56
|
-
* Container of the entire resize UI.
|
57
|
-
*
|
58
|
-
* Note that this property is initialized only after the element bound with the resizer is drawn
|
59
|
-
* so it will be a `null` when uninitialized.
|
60
|
-
*
|
61
|
-
* @private
|
62
|
-
* @type {HTMLElement|null}
|
63
|
-
*/
|
64
|
-
this._domResizerWrapper = null;
|
65
|
-
|
66
55
|
/**
|
67
56
|
* A wrapper that is controlled by the resizer. This is usually a widget element.
|
68
57
|
*
|
@@ -123,8 +112,6 @@ export default class Resizer {
|
|
123
112
|
that._appendHandles( domElement );
|
124
113
|
that._appendSizeUI( domElement );
|
125
114
|
|
126
|
-
that._domResizerWrapper = domElement;
|
127
|
-
|
128
115
|
that.on( 'change:isEnabled', ( evt, propName, newValue ) => {
|
129
116
|
domElement.style.display = newValue ? '' : 'none';
|
130
117
|
} );
|
@@ -153,7 +140,7 @@ export default class Resizer {
|
|
153
140
|
begin( domResizeHandle ) {
|
154
141
|
this.state = new ResizeState( this._options );
|
155
142
|
|
156
|
-
this.
|
143
|
+
this._sizeView._bindToState( this._options, this.state );
|
157
144
|
|
158
145
|
this._initialViewWidth = this._options.viewElement.getStyle( 'width' );
|
159
146
|
|
@@ -307,8 +294,7 @@ export default class Resizer {
|
|
307
294
|
* @protected
|
308
295
|
*/
|
309
296
|
_cleanup() {
|
310
|
-
this.
|
311
|
-
this._sizeUI.isVisible = false;
|
297
|
+
this._sizeView._dismiss();
|
312
298
|
|
313
299
|
const editingView = this._options.editor.editing.view;
|
314
300
|
|
@@ -420,6 +406,19 @@ export default class Resizer {
|
|
420
406
|
return this._options.getHandleHost( widgetWrapper );
|
421
407
|
}
|
422
408
|
|
409
|
+
/**
|
410
|
+
* DOM container of the entire resize UI.
|
411
|
+
*
|
412
|
+
* Note that this property will have a value only after the element bound with the resizer is rendered
|
413
|
+
* (otherwise `null`).
|
414
|
+
*
|
415
|
+
* @private
|
416
|
+
* @member {HTMLElement|null}
|
417
|
+
*/
|
418
|
+
get _domResizerWrapper() {
|
419
|
+
return this._options.editor.editing.view.domConverter.mapViewToDom( this._viewResizerWrapper );
|
420
|
+
}
|
421
|
+
|
423
422
|
/**
|
424
423
|
* Renders the resize handles in the DOM.
|
425
424
|
*
|
@@ -440,20 +439,18 @@ export default class Resizer {
|
|
440
439
|
}
|
441
440
|
|
442
441
|
/**
|
443
|
-
* Sets up the {@link #
|
442
|
+
* Sets up the {@link #_sizeView} property and adds it to the passed `domElement`.
|
444
443
|
*
|
445
444
|
* @private
|
446
445
|
* @param {HTMLElement} domElement
|
447
446
|
*/
|
448
447
|
_appendSizeUI( domElement ) {
|
449
|
-
|
448
|
+
this._sizeView = new SizeView();
|
450
449
|
|
451
450
|
// Make sure icon#element is rendered before passing to appendChild().
|
452
|
-
|
453
|
-
|
454
|
-
this._sizeUI = sizeUI;
|
451
|
+
this._sizeView.render();
|
455
452
|
|
456
|
-
domElement.appendChild(
|
453
|
+
domElement.appendChild( this._sizeView.element );
|
457
454
|
}
|
458
455
|
|
459
456
|
/**
|
@@ -475,61 +472,6 @@ export default class Resizer {
|
|
475
472
|
|
476
473
|
mix( Resizer, ObservableMixin );
|
477
474
|
|
478
|
-
/**
|
479
|
-
* A view displaying the proposed new element size during the resizing.
|
480
|
-
*
|
481
|
-
* @extends {module:ui/view~View}
|
482
|
-
*/
|
483
|
-
class SizeView extends View {
|
484
|
-
constructor() {
|
485
|
-
super();
|
486
|
-
|
487
|
-
const bind = this.bindTemplate;
|
488
|
-
|
489
|
-
this.setTemplate( {
|
490
|
-
tag: 'div',
|
491
|
-
attributes: {
|
492
|
-
class: [
|
493
|
-
'ck',
|
494
|
-
'ck-size-view',
|
495
|
-
bind.to( 'activeHandlePosition', value => value ? `ck-orientation-${ value }` : '' )
|
496
|
-
],
|
497
|
-
style: {
|
498
|
-
display: bind.if( 'isVisible', 'none', visible => !visible )
|
499
|
-
}
|
500
|
-
},
|
501
|
-
children: [ {
|
502
|
-
text: bind.to( 'label' )
|
503
|
-
} ]
|
504
|
-
} );
|
505
|
-
}
|
506
|
-
|
507
|
-
bindToState( options, resizerState ) {
|
508
|
-
this.bind( 'isVisible' ).to( resizerState, 'proposedWidth', resizerState, 'proposedHeight', ( width, height ) =>
|
509
|
-
width !== null && height !== null );
|
510
|
-
|
511
|
-
this.bind( 'label' ).to(
|
512
|
-
resizerState, 'proposedHandleHostWidth',
|
513
|
-
resizerState, 'proposedHandleHostHeight',
|
514
|
-
resizerState, 'proposedWidthPercents',
|
515
|
-
( width, height, widthPercents ) => {
|
516
|
-
if ( options.unit === 'px' ) {
|
517
|
-
return `${ width }×${ height }`;
|
518
|
-
} else {
|
519
|
-
return `${ widthPercents }%`;
|
520
|
-
}
|
521
|
-
}
|
522
|
-
);
|
523
|
-
|
524
|
-
this.bind( 'activeHandlePosition' ).to( resizerState );
|
525
|
-
}
|
526
|
-
|
527
|
-
dismiss() {
|
528
|
-
this.unbind();
|
529
|
-
this.isVisible = false;
|
530
|
-
}
|
531
|
-
}
|
532
|
-
|
533
475
|
// @private
|
534
476
|
// @param {String} resizerPosition Expected resizer position like `"top-left"`, `"bottom-right"`.
|
535
477
|
// @returns {String} A prefixed HTML class name for the resizer element
|
@@ -0,0 +1,114 @@
|
|
1
|
+
/**
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
|
+
*/
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @module widget/widgetresize/sizeview
|
8
|
+
*/
|
9
|
+
|
10
|
+
import View from '@ckeditor/ckeditor5-ui/src/view';
|
11
|
+
|
12
|
+
/**
|
13
|
+
* A view displaying the proposed new element size during the resizing.
|
14
|
+
*
|
15
|
+
* @protected
|
16
|
+
* @extends {module:ui/view~View}
|
17
|
+
*/
|
18
|
+
export default class SizeView extends View {
|
19
|
+
constructor() {
|
20
|
+
super();
|
21
|
+
|
22
|
+
/**
|
23
|
+
* The visibility of the view defined based on the existence of the host proposed dimensions.
|
24
|
+
*
|
25
|
+
* @private
|
26
|
+
* @observable
|
27
|
+
* @readonly
|
28
|
+
* @member {Boolean} #_isVisible
|
29
|
+
*/
|
30
|
+
|
31
|
+
/**
|
32
|
+
* The text that will be displayed in the `SizeView` child.
|
33
|
+
* It can be formatted as the pixel values (e.g. 10x20) or the percentage value (e.g. 10%).
|
34
|
+
*
|
35
|
+
* @private
|
36
|
+
* @observable
|
37
|
+
* @readonly
|
38
|
+
* @member {Boolean} #_label
|
39
|
+
*/
|
40
|
+
|
41
|
+
/**
|
42
|
+
* The position of the view defined based on the host size and active handle position.
|
43
|
+
*
|
44
|
+
* @private
|
45
|
+
* @observable
|
46
|
+
* @readonly
|
47
|
+
* @member {String} #_viewPosition
|
48
|
+
*/
|
49
|
+
|
50
|
+
const bind = this.bindTemplate;
|
51
|
+
|
52
|
+
this.setTemplate( {
|
53
|
+
tag: 'div',
|
54
|
+
attributes: {
|
55
|
+
class: [
|
56
|
+
'ck',
|
57
|
+
'ck-size-view',
|
58
|
+
bind.to( '_viewPosition', value => value ? `ck-orientation-${ value }` : '' )
|
59
|
+
],
|
60
|
+
style: {
|
61
|
+
display: bind.if( '_isVisible', 'none', visible => !visible )
|
62
|
+
}
|
63
|
+
},
|
64
|
+
children: [ {
|
65
|
+
text: bind.to( '_label' )
|
66
|
+
} ]
|
67
|
+
} );
|
68
|
+
}
|
69
|
+
|
70
|
+
/**
|
71
|
+
* A method used for binding the `SizeView` instance properties to the `ResizeState` instance observable properties.
|
72
|
+
*
|
73
|
+
* @protected
|
74
|
+
* @param {module:widget/widgetresize~ResizerOptions} options
|
75
|
+
* An object defining the resizer options, used for setting the proper size label.
|
76
|
+
* @param {module:widget/widgetresize/resizerstate~ResizeState} resizeState
|
77
|
+
* The `ResizeState` class instance, used for keeping the `SizeView` state up to date.
|
78
|
+
*/
|
79
|
+
_bindToState( options, resizeState ) {
|
80
|
+
this.bind( '_isVisible' ).to( resizeState, 'proposedWidth', resizeState, 'proposedHeight', ( width, height ) =>
|
81
|
+
width !== null && height !== null );
|
82
|
+
|
83
|
+
this.bind( '_label' ).to(
|
84
|
+
resizeState, 'proposedHandleHostWidth',
|
85
|
+
resizeState, 'proposedHandleHostHeight',
|
86
|
+
resizeState, 'proposedWidthPercents',
|
87
|
+
( width, height, widthPercents ) => {
|
88
|
+
if ( options.unit === 'px' ) {
|
89
|
+
return `${ width }×${ height }`;
|
90
|
+
} else {
|
91
|
+
return `${ widthPercents }%`;
|
92
|
+
}
|
93
|
+
}
|
94
|
+
);
|
95
|
+
|
96
|
+
this.bind( '_viewPosition' ).to(
|
97
|
+
resizeState, 'activeHandlePosition',
|
98
|
+
resizeState, 'proposedHandleHostWidth',
|
99
|
+
resizeState, 'proposedHandleHostHeight',
|
100
|
+
// If the widget is too small to contain the size label, display the label above.
|
101
|
+
( position, width, height ) => width < 50 || height < 50 ? 'above-center' : position
|
102
|
+
);
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* A method used for cleaning up. It removes the bindings and hides the view.
|
107
|
+
*
|
108
|
+
* @protected
|
109
|
+
*/
|
110
|
+
_dismiss() {
|
111
|
+
this.unbind();
|
112
|
+
this._isVisible = false;
|
113
|
+
}
|
114
|
+
}
|
package/src/widgetresize.js
CHANGED
@@ -38,6 +38,9 @@ export default class WidgetResize extends Plugin {
|
|
38
38
|
* @inheritDoc
|
39
39
|
*/
|
40
40
|
init() {
|
41
|
+
const editing = this.editor.editing;
|
42
|
+
const domDocument = global.window.document;
|
43
|
+
|
41
44
|
/**
|
42
45
|
* The currently visible resizer.
|
43
46
|
*
|
@@ -60,22 +63,16 @@ export default class WidgetResize extends Plugin {
|
|
60
63
|
/**
|
61
64
|
* A map of resizers created using this plugin instance.
|
62
65
|
*
|
63
|
-
* @
|
66
|
+
* @protected
|
64
67
|
* @type {Map.<module:engine/view/containerelement~ContainerElement, module:widget/widgetresize/resizer~Resizer>}
|
65
68
|
*/
|
66
69
|
this._resizers = new Map();
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
this.editor.model.schema.setAttributeProperties( 'width', {
|
71
|
-
isFormatting: true
|
72
|
-
} );
|
73
|
-
|
74
|
-
this.editor.editing.view.addObserver( MouseObserver );
|
71
|
+
editing.view.addObserver( MouseObserver );
|
75
72
|
|
76
73
|
this._observer = Object.create( DomEmitterMixin );
|
77
74
|
|
78
|
-
this.listenTo(
|
75
|
+
this.listenTo( editing.view.document, 'mousedown', this._mouseDownListener.bind( this ), { priority: 'high' } );
|
79
76
|
|
80
77
|
this._observer.listenTo( domDocument, 'mousemove', this._mouseMoveListener.bind( this ) );
|
81
78
|
this._observer.listenTo( domDocument, 'mouseup', this._mouseUpListener.bind( this ) );
|
@@ -95,6 +92,18 @@ export default class WidgetResize extends Plugin {
|
|
95
92
|
// Redrawing on any change of the UI of the editor (including content changes).
|
96
93
|
this.editor.ui.on( 'update', this._redrawFocusedResizerThrottled );
|
97
94
|
|
95
|
+
// Remove view widget-resizer mappings for widgets that have been removed from the document.
|
96
|
+
// https://github.com/ckeditor/ckeditor5/issues/10156
|
97
|
+
// https://github.com/ckeditor/ckeditor5/issues/10266
|
98
|
+
this.editor.model.document.on( 'change', () => {
|
99
|
+
for ( const [ viewElement, resizer ] of this._resizers ) {
|
100
|
+
if ( !viewElement.isAttached() ) {
|
101
|
+
this._resizers.delete( viewElement );
|
102
|
+
resizer.destroy();
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}, { priority: 'lowest' } );
|
106
|
+
|
98
107
|
// Resizers need to be redrawn upon window resize, because new window might shrink resize host.
|
99
108
|
this._observer.listenTo( global.window, 'resize', this._redrawFocusedResizerThrottled );
|
100
109
|
|
@@ -11,10 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
|
11
11
|
import ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';
|
12
12
|
import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
|
13
13
|
import BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';
|
14
|
-
import {
|
15
|
-
isWidget,
|
16
|
-
centeredBalloonPositionForLongWidgets
|
17
|
-
} from './utils';
|
14
|
+
import { isWidget } from './utils';
|
18
15
|
import CKEditorError, { logWarning } from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
19
16
|
|
20
17
|
/**
|
@@ -36,7 +33,7 @@ import CKEditorError, { logWarning } from '@ckeditor/ckeditor5-utils/src/ckedito
|
|
36
33
|
*
|
37
34
|
* widgetToolbarRepository.register( 'image', {
|
38
35
|
* items: editor.config.get( 'image.toolbar' ),
|
39
|
-
* getRelatedElement:
|
36
|
+
* getRelatedElement: getClosestSelectedImageWidget
|
40
37
|
* } );
|
41
38
|
* }
|
42
39
|
* }
|
@@ -289,7 +286,7 @@ function getBalloonPositionData( editor, relatedElement ) {
|
|
289
286
|
defaultPositions.southArrowNorth,
|
290
287
|
defaultPositions.southArrowNorthWest,
|
291
288
|
defaultPositions.southArrowNorthEast,
|
292
|
-
|
289
|
+
defaultPositions.viewportStickyNorth
|
293
290
|
]
|
294
291
|
};
|
295
292
|
}
|
@@ -398,6 +398,10 @@ export default class WidgetTypeAround extends Plugin {
|
|
398
398
|
else if ( modelSelection.isCollapsed ) {
|
399
399
|
shouldStopAndPreventDefault = this._handleArrowKeyPressWhenSelectionNextToAWidget( isForward );
|
400
400
|
}
|
401
|
+
// Handle collapsing a non-collapsed selection that is wider than on a single widget.
|
402
|
+
else if ( !domEventData.shiftKey ) {
|
403
|
+
shouldStopAndPreventDefault = this._handleArrowKeyPressWhenNonCollapsedSelection( isForward );
|
404
|
+
}
|
401
405
|
|
402
406
|
if ( shouldStopAndPreventDefault ) {
|
403
407
|
domEventData.preventDefault();
|
@@ -492,6 +496,42 @@ export default class WidgetTypeAround extends Plugin {
|
|
492
496
|
return false;
|
493
497
|
}
|
494
498
|
|
499
|
+
/**
|
500
|
+
* Handles the keyboard navigation on "keydown" when a widget is currently selected (together with some other content)
|
501
|
+
* and the widget is the first or last element in the selection. It activates or deactivates the fake caret for that widget.
|
502
|
+
*
|
503
|
+
* @private
|
504
|
+
* @param {Boolean} isForward `true` when the pressed arrow key was responsible for the forward model selection movement
|
505
|
+
* as in {@link module:utils/keyboard~isForwardArrowKeyCode}.
|
506
|
+
* @returns {Boolean} Returns `true` when the keypress was handled and no other keydown listener of the editor should
|
507
|
+
* process the event any further. Returns `false` otherwise.
|
508
|
+
*/
|
509
|
+
_handleArrowKeyPressWhenNonCollapsedSelection( isForward ) {
|
510
|
+
const editor = this.editor;
|
511
|
+
const model = editor.model;
|
512
|
+
const schema = model.schema;
|
513
|
+
const mapper = editor.editing.mapper;
|
514
|
+
const modelSelection = model.document.selection;
|
515
|
+
|
516
|
+
const selectedModelNode = isForward ?
|
517
|
+
modelSelection.getLastPosition().nodeBefore :
|
518
|
+
modelSelection.getFirstPosition().nodeAfter;
|
519
|
+
|
520
|
+
const selectedViewNode = mapper.toViewElement( selectedModelNode );
|
521
|
+
|
522
|
+
// There is a widget at the collapse position so collapse the selection to the fake caret on it.
|
523
|
+
if ( isTypeAroundWidget( selectedViewNode, selectedModelNode, schema ) ) {
|
524
|
+
model.change( writer => {
|
525
|
+
writer.setSelection( selectedModelNode, 'on' );
|
526
|
+
writer.setSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE, isForward ? 'after' : 'before' );
|
527
|
+
} );
|
528
|
+
|
529
|
+
return true;
|
530
|
+
}
|
531
|
+
|
532
|
+
return false;
|
533
|
+
}
|
534
|
+
|
495
535
|
/**
|
496
536
|
* Registers a `mousedown` listener for the view document which intercepts events
|
497
537
|
* coming from the widget type around UI, which happens when a user clicks one of the buttons
|
package/theme/widget.css
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
|
11
11
|
--ck-resizer-border-radius: var(--ck-border-radius);
|
12
12
|
--ck-resizer-tooltip-offset: 10px;
|
13
|
+
--ck-resizer-tooltip-height: calc(var(--ck-spacing-small) * 2 + 10px);
|
13
14
|
}
|
14
15
|
|
15
16
|
.ck .ck-widget {
|
@@ -49,12 +50,15 @@
|
|
49
50
|
border-radius: var(--ck-resizer-border-radius);
|
50
51
|
font-size: var(--ck-font-size-tiny);
|
51
52
|
display: block;
|
52
|
-
padding: var(--ck-spacing-small);
|
53
|
+
padding: 0 var(--ck-spacing-small);
|
54
|
+
height: var(--ck-resizer-tooltip-height);
|
55
|
+
line-height: var(--ck-resizer-tooltip-height);
|
53
56
|
|
54
57
|
&.ck-orientation-top-left,
|
55
58
|
&.ck-orientation-top-right,
|
56
59
|
&.ck-orientation-bottom-right,
|
57
|
-
&.ck-orientation-bottom-left
|
60
|
+
&.ck-orientation-bottom-left,
|
61
|
+
&.ck-orientation-above-center {
|
58
62
|
position: absolute;
|
59
63
|
}
|
60
64
|
|
@@ -77,4 +81,11 @@
|
|
77
81
|
bottom: var(--ck-resizer-tooltip-offset);
|
78
82
|
left: var(--ck-resizer-tooltip-offset);
|
79
83
|
}
|
84
|
+
|
85
|
+
/* Class applied if the widget is too small to contain the size label */
|
86
|
+
&.ck-orientation-above-center {
|
87
|
+
top: calc(var(--ck-resizer-tooltip-height) * -1);
|
88
|
+
left: 50%;
|
89
|
+
transform: translate(-50%);
|
90
|
+
}
|
80
91
|
}
|
package/CHANGELOG.md
DELETED
@@ -1,260 +0,0 @@
|
|
1
|
-
Changelog
|
2
|
-
=========
|
3
|
-
|
4
|
-
All changes in the package are documented in the main repository. See: https://github.com/ckeditor/ckeditor5/blob/master/CHANGELOG.md.
|
5
|
-
|
6
|
-
Changes for the past releases are available below.
|
7
|
-
|
8
|
-
## [19.0.0](https://github.com/ckeditor/ckeditor5-widget/compare/v18.0.0...v19.0.0) (2020-04-29)
|
9
|
-
|
10
|
-
### MINOR BREAKING CHANGES
|
11
|
-
|
12
|
-
* Make sure the latest version of the [`Essentials`](https://ckeditor.com/docs/ckeditor5/latest/api/essentials.html) plugin or the [`SelectAll`](https://ckeditor.com/docs/ckeditor5/latest/api/module_select-all_selectall-SelectAll.html) plugin is installed in your integration. Either is required for proper keystroke handling in editor widgets.
|
13
|
-
|
14
|
-
### Bug fixes
|
15
|
-
|
16
|
-
* Image resize now cleans up temporary view `width` style changes. Closes [ckeditor/ckeditor5#6060](https://github.com/ckeditor/ckeditor5/issues/6060). ([92226f9](https://github.com/ckeditor/ckeditor5-widget/commit/92226f9))
|
17
|
-
|
18
|
-
### Other changes
|
19
|
-
|
20
|
-
* Moved the <kbd>Ctrl</kbd>+<kbd>A</kbd> keystroke handling in widgets to the [`SelectAll`](https://ckeditor.com/docs/ckeditor5/latest/api/module_select-all_selectall-SelectAll.html) plugin (see [ckeditor/ckeditor5#6536](https://github.com/ckeditor/ckeditor5/issues/6536)). ([57eb263](https://github.com/ckeditor/ckeditor5-widget/commit/57eb263))
|
21
|
-
* Updated translations. ([79d1a21](https://github.com/ckeditor/ckeditor5-widget/commit/79d1a21))
|
22
|
-
|
23
|
-
|
24
|
-
## [18.0.0](https://github.com/ckeditor/ckeditor5-widget/compare/v17.0.0...v18.0.0) (2020-03-19)
|
25
|
-
|
26
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
27
|
-
|
28
|
-
|
29
|
-
## [17.0.0](https://github.com/ckeditor/ckeditor5-widget/compare/v16.0.0...v17.0.0) (2020-02-19)
|
30
|
-
|
31
|
-
### MINOR BREAKING CHANGES
|
32
|
-
|
33
|
-
* Resizer options object now also takes an editor instance.
|
34
|
-
|
35
|
-
### Features
|
36
|
-
|
37
|
-
* Introduced API to temporarily disable the `WidgetToolbarRepository` plugin (prevent the toolbar from showing up). Closes [ckeditor/ckeditor5#5964](https://github.com/ckeditor/ckeditor5/issues/5964). ([b9cf062](https://github.com/ckeditor/ckeditor5-widget/commit/b9cf062))
|
38
|
-
|
39
|
-
### Bug fixes
|
40
|
-
|
41
|
-
* Fixed image resize behavior upon short clicking a handle without dragging. Image will no longer became full width, nor will it briefly flash an unexpected size. Closes [ckeditor/ckeditor5#5189](https://github.com/ckeditor/ckeditor5/issues/5189). Closes [ckeditor/ckeditor5#5195](https://github.com/ckeditor/ckeditor5/issues/5195). ([d6a5c93](https://github.com/ckeditor/ckeditor5-widget/commit/d6a5c93))
|
42
|
-
|
43
|
-
### Other changes
|
44
|
-
|
45
|
-
* Align code to changes in `Plugin` API. ([81bb636](https://github.com/ckeditor/ckeditor5-widget/commit/81bb636))
|
46
|
-
* Updated translations. ([75b8c83](https://github.com/ckeditor/ckeditor5-widget/commit/75b8c83))
|
47
|
-
|
48
|
-
|
49
|
-
## [16.0.0](https://github.com/ckeditor/ckeditor5-widget/compare/v15.0.0...v16.0.0) (2019-12-04)
|
50
|
-
|
51
|
-
### Other changes
|
52
|
-
|
53
|
-
* Updated translations. ([b3bf5f0](https://github.com/ckeditor/ckeditor5-widget/commit/b3bf5f0))
|
54
|
-
|
55
|
-
|
56
|
-
## [15.0.0](https://github.com/ckeditor/ckeditor5-widget/compare/v11.1.0...v15.0.0) (2019-10-23)
|
57
|
-
|
58
|
-
### MAJOR BREAKING CHANGES
|
59
|
-
|
60
|
-
* The `drag-handler.svg` icon is now `drag-handle.svg`. If you use it in your integration, please update the path.
|
61
|
-
* The `hasSelectionHandler` option of the [`toWidget()`](https://ckeditor.com/docs/ckeditor5/latest/api/module_widget_utils.html#static-function-toWidget) utility has been renamed to `hasSelectionHandle`. Consider this change if you create your own widgets using this helper.
|
62
|
-
* `.ck-widget__selection-handler` and `.ck-widget_with-selection-handler` CSS classes set on widgets have been renamed to `.ck-widget__selection-handle` and `.ck-widget_with-selection-handle`. This change may affect styling in your integration.
|
63
|
-
|
64
|
-
### Bug fixes
|
65
|
-
|
66
|
-
* Initial resize of a side image with no width predefined now gives correct percentage values. ([6c2c52e](https://github.com/ckeditor/ckeditor5-widget/commit/6c2c52e))
|
67
|
-
* Keyboard navigation should work around widgets in RTL content. Closes [#97](https://github.com/ckeditor/ckeditor5-widget/issues/97). ([dfbf88d](https://github.com/ckeditor/ckeditor5-widget/commit/dfbf88d))
|
68
|
-
|
69
|
-
### Other changes
|
70
|
-
|
71
|
-
* Improved the resizer performance. Closes [ckeditor/ckeditor5#5191](https://github.com/ckeditor/ckeditor5/issues/5191). ([1d1de77](https://github.com/ckeditor/ckeditor5-widget/commit/1d1de77))
|
72
|
-
* Renamed "handler" to "handle" in the entire package. Closes [#99](https://github.com/ckeditor/ckeditor5-widget/issues/99). ([1d35884](https://github.com/ckeditor/ckeditor5-widget/commit/1d35884))
|
73
|
-
* Updated translations. ([b9cb673](https://github.com/ckeditor/ckeditor5-widget/commit/b9cb673)) ([daea4f5](https://github.com/ckeditor/ckeditor5-widget/commit/daea4f5))
|
74
|
-
|
75
|
-
|
76
|
-
## [11.1.0](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.4...v11.1.0) (2019-08-26)
|
77
|
-
|
78
|
-
### Features
|
79
|
-
|
80
|
-
* Introduced image widget resizer. See [ckeditor/ckeditor5-image#241](https://github.com/ckeditor/ckeditor5-image/issues/241). ([c84cd73](https://github.com/ckeditor/ckeditor5-widget/commit/c84cd73))
|
81
|
-
|
82
|
-
### Bug fixes
|
83
|
-
|
84
|
-
* Improved balloon positioning when there is more than one stack in the rotator. ([763c9ba](https://github.com/ckeditor/ckeditor5-widget/commit/763c9ba))
|
85
|
-
* Reposition visible toolbar when it is in a not visible stack of rotator. Closes [ckeditor/ckeditor5#1957](https://github.com/ckeditor/ckeditor5/issues/1957). ([a438c8b](https://github.com/ckeditor/ckeditor5-widget/commit/a438c8b))
|
86
|
-
|
87
|
-
### Other changes
|
88
|
-
|
89
|
-
* The issue tracker for this package was moved to https://github.com/ckeditor/ckeditor5/issues. See [ckeditor/ckeditor5#1988](https://github.com/ckeditor/ckeditor5/issues/1988). ([cfd41c1](https://github.com/ckeditor/ckeditor5-widget/commit/cfd41c1))
|
90
|
-
* The widget toolbar should have a proper `aria-label` attribute (see [ckeditor/ckeditor5#1404](https://github.com/ckeditor/ckeditor5/issues/1404)). ([aec5888](https://github.com/ckeditor/ckeditor5-widget/commit/aec5888))
|
91
|
-
|
92
|
-
|
93
|
-
## [11.0.4](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.3...v11.0.4) (2019-07-10)
|
94
|
-
|
95
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
96
|
-
|
97
|
-
|
98
|
-
## [11.0.3](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.2...v11.0.3) (2019-07-04)
|
99
|
-
|
100
|
-
### Bug fixes
|
101
|
-
|
102
|
-
* A proper `DomConverter` method should be used to map a view to DOM when getting balloon position data. Closes [#87](https://github.com/ckeditor/ckeditor5-widget/issues/87). ([160333a](https://github.com/ckeditor/ckeditor5-widget/commit/160333a))
|
103
|
-
|
104
|
-
|
105
|
-
## [11.0.2](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.1...v11.0.2) (2019-06-05)
|
106
|
-
|
107
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
108
|
-
|
109
|
-
|
110
|
-
## [11.0.1](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.0...v11.0.1) (2019-04-10)
|
111
|
-
|
112
|
-
### Bug fixes
|
113
|
-
|
114
|
-
* Triple clicking inside a nested editable should not select the entire widget in Safari. Closes [ckeditor/ckeditor5#1463](https://github.com/ckeditor/ckeditor5/issues/1463). ([b7c4765](https://github.com/ckeditor/ckeditor5-widget/commit/b7c4765))
|
115
|
-
|
116
|
-
|
117
|
-
## [11.0.0](https://github.com/ckeditor/ckeditor5-widget/compare/v10.3.1...v11.0.0) (2019-02-28)
|
118
|
-
|
119
|
-
### Bug fixes
|
120
|
-
|
121
|
-
* Editor crashes after <kbd>Enter</kbd> key on an image that is inside a blockquote. Closes [ckeditor/ckeditor5#1555](https://github.com/ckeditor/ckeditor5/issues/1555). ([8a8842b](https://github.com/ckeditor/ckeditor5-widget/commit/8a8842b))
|
122
|
-
* Ensured only the widget toolbar attached to the view element which is deepest in the view tree will show up. Code and documentation refactoring in the `WidgetToolbarRepository`. Closes [#60](https://github.com/ckeditor/ckeditor5-widget/issues/60). ([7e11a24](https://github.com/ckeditor/ckeditor5-widget/commit/7e11a24))
|
123
|
-
* Make widget in editable clickable. Closes [ckeditor/ckeditor5-table#98](https://github.com/ckeditor/ckeditor5-table/issues/98). ([8226829](https://github.com/ckeditor/ckeditor5-widget/commit/8226829))
|
124
|
-
* Pressing <kbd>Enter</kbd> should split parent element when the inline widget is inside a `$block`. Closes [ckeditor/ckeditor5#1529](https://github.com/ckeditor/ckeditor5/issues/1529). ([847d2ab](https://github.com/ckeditor/ckeditor5-widget/commit/847d2ab))
|
125
|
-
* Fixed memory leaks during editor initialization and destruction (see [ckeditor/ckeditor5#1341](https://github.com/ckeditor/ckeditor5/issues/1341)). ([2e8f20d](https://github.com/ckeditor/ckeditor5-widget/commit/2e8f20d))
|
126
|
-
|
127
|
-
### Other changes
|
128
|
-
|
129
|
-
* Introduce support and utils for creating inline widgets. Closes [[ckeditor/ckeditor5#1096](https://github.com/ckeditor/ckeditor5/issues/1096)](https://github.com/ckeditor/ckeditor5/issues/1096). ([38fa159](https://github.com/ckeditor/ckeditor5-widget/commit/38fa159))
|
130
|
-
* Renamed the `.ck-widget_selectable` class to `.ck-widget_with-selection-handler` for better semantics. Closes [#66](https://github.com/ckeditor/ckeditor5-widget/issues/66). ([178ad5f](https://github.com/ckeditor/ckeditor5-widget/commit/178ad5f))
|
131
|
-
|
132
|
-
### BREAKING CHANGES
|
133
|
-
|
134
|
-
* Upgraded minimal versions of Node to `8.0.0` and npm to `5.7.1`. See: [ckeditor/ckeditor5#1507](https://github.com/ckeditor/ckeditor5/issues/1507). ([612ea3c](https://github.com/ckeditor/ckeditor5-cloud-services/commit/612ea3c))
|
135
|
-
* The `.ck-widget_selectable` class has been renamed to `.ck-widget_with-selection-handler` for better semantics.
|
136
|
-
* The `visibleWhen()` function, a property of an object passed into `WidgetToolbarRepository.register()`, has been renamed to `getRelatedElement()` and must return an editing `View` element the toolbar should be attached to (instead of `Boolean`).
|
137
|
-
|
138
|
-
|
139
|
-
## [10.3.1](https://github.com/ckeditor/ckeditor5-widget/compare/v10.3.0...v10.3.1) (2018-12-05)
|
140
|
-
|
141
|
-
### Bug fixes
|
142
|
-
|
143
|
-
* Selection converter will mark only the topmost widget in case of selecting a widget with another widget nested inside it. Closes [#57](https://github.com/ckeditor/ckeditor5-widget/issues/57). ([a78efec](https://github.com/ckeditor/ckeditor5-widget/commit/a78efec))
|
144
|
-
|
145
|
-
### Other changes
|
146
|
-
|
147
|
-
* Improved SVG icons size. See [ckeditor/ckeditor5-theme-lark#206](https://github.com/ckeditor/ckeditor5-theme-lark/issues/206). ([5b7a457](https://github.com/ckeditor/ckeditor5-widget/commit/5b7a457))
|
148
|
-
|
149
|
-
|
150
|
-
## [10.3.0](https://github.com/ckeditor/ckeditor5-widget/compare/v10.2.0...v10.3.0) (2018-10-08)
|
151
|
-
|
152
|
-
### Features
|
153
|
-
|
154
|
-
* Introduced the `findOptimalInsertionPostion()` utility function. ([9c0d4ce](https://github.com/ckeditor/ckeditor5-widget/commit/9c0d4ce))
|
155
|
-
* Introduced the widget toolbar repository. Closes [ckeditor/ckeditor5-ui#442](https://github.com/ckeditor/ckeditor5-ui/issues/442). ([bc45176](https://github.com/ckeditor/ckeditor5-widget/commit/bc45176))
|
156
|
-
|
157
|
-
|
158
|
-
## [10.2.0](https://github.com/ckeditor/ckeditor5-widget/compare/v10.1.0...v10.2.0) (2018-07-18)
|
159
|
-
|
160
|
-
### Features
|
161
|
-
|
162
|
-
* Implemented the widget selection handle. Closes [#40](https://github.com/ckeditor/ckeditor5-widget/issues/40). ([bbf9298](https://github.com/ckeditor/ckeditor5-widget/commit/bbf9298))
|
163
|
-
|
164
|
-
### Other changes
|
165
|
-
|
166
|
-
* Do not set the `contenteditable` property for widgets and their nested editables on Edge due to an awful instability which it causes in this browser. Closes [ckeditor/ckeditor5#1079](https://github.com/ckeditor/ckeditor5/issues/1079). Closes [ckeditor/ckeditor5#1067](https://github.com/ckeditor/ckeditor5/issues/1067). ([ee530b1](https://github.com/ckeditor/ckeditor5-widget/commit/ee530b1))
|
167
|
-
|
168
|
-
|
169
|
-
## [10.1.0](https://github.com/ckeditor/ckeditor5-widget/compare/v10.0.0...v10.1.0) (2018-06-21)
|
170
|
-
|
171
|
-
### Features
|
172
|
-
|
173
|
-
* Creating a paragraph next to the selected widget is possible using the (<kbd>Shift</kbd>+)<kbd>Enter</kbd> key (see [ckeditor/ckeditor5#407](https://github.com/ckeditor/ckeditor5/issues/407)). ([d68b7d0](https://github.com/ckeditor/ckeditor5-widget/commit/d68b7d0))
|
174
|
-
|
175
|
-
|
176
|
-
## [10.0.0](https://github.com/ckeditor/ckeditor5-widget/compare/v1.0.0-beta.4...v10.0.0) (2018-04-25)
|
177
|
-
|
178
|
-
### Other changes
|
179
|
-
|
180
|
-
* Changed the license to GPL2+ only. See [ckeditor/ckeditor5#991](https://github.com/ckeditor/ckeditor5/issues/991). ([88ef879](https://github.com/ckeditor/ckeditor5-widget/commit/88ef879))
|
181
|
-
|
182
|
-
### BREAKING CHANGES
|
183
|
-
|
184
|
-
* The license under which CKEditor 5 is released has been changed from a triple GPL, LGPL and MPL license to a GPL2+ only. See [ckeditor/ckeditor5#991](https://github.com/ckeditor/ckeditor5/issues/991) for more information.
|
185
|
-
|
186
|
-
|
187
|
-
## [1.0.0-beta.4](https://github.com/ckeditor/ckeditor5-widget/compare/v1.0.0-beta.2...v1.0.0-beta.4) (2018-04-19)
|
188
|
-
|
189
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
190
|
-
|
191
|
-
|
192
|
-
## [1.0.0-beta.2](https://github.com/ckeditor/ckeditor5-widget/compare/v1.0.0-beta.1...v1.0.0-beta.2) (2018-04-10)
|
193
|
-
|
194
|
-
### Bug fixes
|
195
|
-
|
196
|
-
* Replaced nested editable's `.ck-editable` class with `.ck-editor__editable` + `.ck-editor__nested-editable` to stop Grammarly throwing errors. Closes [ckeditor/ckeditor5#578](https://github.com/ckeditor/ckeditor5/issues/578). ([051b326](https://github.com/ckeditor/ckeditor5-widget/commit/051b326))
|
197
|
-
|
198
|
-
### Other changes
|
199
|
-
|
200
|
-
* Increased the specificity of CSS rules. Introduced the .ck class for editor UI components (see: [ckeditor/ckeditor5#494](https://github.com/ckeditor/ckeditor5/issues/494)). ([abc7def](https://github.com/ckeditor/ckeditor5-widget/commit/abc7def))
|
201
|
-
|
202
|
-
### BREAKING CHANGES
|
203
|
-
|
204
|
-
* The `.ck-editable` class is no longer available. Use the `.ck-editor__nested-editable` class instead.
|
205
|
-
|
206
|
-
|
207
|
-
## [1.0.0-beta.1](https://github.com/ckeditor/ckeditor5-widget/compare/v1.0.0-alpha.2...v1.0.0-beta.1) (2018-03-15)
|
208
|
-
|
209
|
-
### Other changes
|
210
|
-
|
211
|
-
* Aligned feature class naming to the new scheme. ([23991a4](https://github.com/ckeditor/ckeditor5-widget/commit/23991a4))
|
212
|
-
* Migrated package styles to PostCSS. Moved visual styles to `@ckeditor/ckeditor5-theme-lark` (see [ckeditor/ckeditor5-ui#144](https://github.com/ckeditor/ckeditor5-ui/issues/144)). ([857d6d4](https://github.com/ckeditor/ckeditor5-widget/commit/857d6d4))
|
213
|
-
* Switched to handling deletion around widgets by using the `delete` event instead of listening directly on key events. Closes [#29](https://github.com/ckeditor/ckeditor5-widget/issues/29). ([ee6cc95](https://github.com/ckeditor/ckeditor5-widget/commit/ee6cc95))
|
214
|
-
|
215
|
-
|
216
|
-
## [1.0.0-alpha.2](https://github.com/ckeditor/ckeditor5-widget/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (2017-11-14)
|
217
|
-
|
218
|
-
### Bug fixes
|
219
|
-
|
220
|
-
* The <kbd>Ctrl</kbd>+<kbd>A</kbd> keystroke will be now correctly handled when a widget is selected. Closes [#23](https://github.com/ckeditor/ckeditor5-widget/issues/23). ([3e8f91f](https://github.com/ckeditor/ckeditor5-widget/commit/3e8f91f))
|
221
|
-
* View element's `setAttribute()` method should be used with string values of the `contenteditable` attribute. Closes [#26](https://github.com/ckeditor/ckeditor5-widget/issues/26). ([d2a6cf5](https://github.com/ckeditor/ckeditor5-widget/commit/d2a6cf5))
|
222
|
-
|
223
|
-
### Other changes
|
224
|
-
|
225
|
-
* Widgets highlight remove handler will now use only descriptor id, instead of the full descriptor. ([1dfdc83](https://github.com/ckeditor/ckeditor5-widget/commit/1dfdc83))
|
226
|
-
|
227
|
-
|
228
|
-
## [1.0.0-alpha.1](https://github.com/ckeditor/ckeditor5-widget/compare/v0.2.0...v1.0.0-alpha.1) (2017-10-03)
|
229
|
-
|
230
|
-
### Bug fixes
|
231
|
-
|
232
|
-
* <kbd>Backspace</kbd> and <kbd>Delete</kbd> should not delete a widget when the editor is in the read-only mode. Closes [#6](https://github.com/ckeditor/ckeditor5-widget/issues/6). ([5f64125](https://github.com/ckeditor/ckeditor5-widget/commit/5f64125))
|
233
|
-
* Nested element structures next to widgets will be correctly removed when pressing <kbd>Backspace</kbd> or <kbd>Delete</kbd>. Closes [#19](https://github.com/ckeditor/ckeditor5-widget/issues/19). ([27ee848](https://github.com/ckeditor/ckeditor5-widget/commit/27ee848))
|
234
|
-
|
235
|
-
|
236
|
-
## [0.2.0](https://github.com/ckeditor/ckeditor5-widget/compare/v0.1.1...v0.2.0) (2017-09-03)
|
237
|
-
|
238
|
-
### Bug fixes
|
239
|
-
|
240
|
-
* Added initial contenteditable state for editable widget. Closes [#9](https://github.com/ckeditor/ckeditor5-widget/issues/9). ([c6321ff](https://github.com/ckeditor/ckeditor5-widget/commit/c6321ff))
|
241
|
-
|
242
|
-
### Features
|
243
|
-
|
244
|
-
* <kbd>Ctrl</kbd>+<kbd>A</kbd> in a nested editable should select nested editable's content. Closes [#13](https://github.com/ckeditor/ckeditor5-widget/issues/13). ([35a8aff](https://github.com/ckeditor/ckeditor5-widget/commit/35a8aff))
|
245
|
-
|
246
|
-
### Other changes
|
247
|
-
|
248
|
-
* Adjusted widget to the editor read-only mode. Closes [#7](https://github.com/ckeditor/ckeditor5-widget/issues/7). ([2726873](https://github.com/ckeditor/ckeditor5-widget/commit/2726873))
|
249
|
-
* Introduced highlights support for widgets. Closes [#11](https://github.com/ckeditor/ckeditor5-widget/issues/11). ([0bd3d66](https://github.com/ckeditor/ckeditor5-widget/commit/0bd3d66))
|
250
|
-
|
251
|
-
|
252
|
-
## [0.1.1](https://github.com/ckeditor/ckeditor5-widget/compare/v0.1.0...v0.1.1) (2017-05-07)
|
253
|
-
|
254
|
-
Internal changes only (updated dependencies, documentation, etc.).
|
255
|
-
|
256
|
-
## 0.1.0 (2017-04-05)
|
257
|
-
|
258
|
-
### Features
|
259
|
-
|
260
|
-
* Initial implementation (the code was moved from the `ckeditor5-image` package). Closes [#1](https://github.com/ckeditor/ckeditor5-widget/issues/1). ([564dd97](https://github.com/ckeditor/ckeditor5-widget/commit/564dd97))
|