@ckeditor/ckeditor5-widget 28.0.0 → 30.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-widget.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget)
|
5
|
-
[![
|
6
|
-
[![
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/github/ckeditor/ckeditor5/badge.svg?branch=master)](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
6
|
+
[![Build Status](https://travis-ci.com/ckeditor/ckeditor5.svg?branch=master)](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))
|