@ckeditor/ckeditor5-widget 39.0.2 → 40.1.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/LICENSE.md CHANGED
@@ -2,7 +2,7 @@ Software License Agreement
2
2
  ==========================
3
3
 
4
4
  **CKEditor&nbsp;5 widget API** – https://github.com/ckeditor/ckeditor5-image <br>
5
- Copyright (c) 2003-2023, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved.
5
+ Copyright (c) 20032023, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved.
6
6
 
7
7
  Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
8
8
 
@@ -13,9 +13,9 @@ Where not otherwise indicated, all CKEditor content is authored by CKSource engi
13
13
 
14
14
  The following libraries are included in CKEditor under the [MIT license](https://opensource.org/licenses/MIT):
15
15
 
16
- * lodash - Copyright (c) JS Foundation and other contributors https://js.foundation/. Based on Underscore.js, copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors http://underscorejs.org/.
16
+ * Lodash - Copyright (c) JS Foundation and other contributors https://js.foundation/. Based on Underscore.js, copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors http://underscorejs.org/.
17
17
 
18
18
  Trademarks
19
19
  ----------
20
20
 
21
- **CKEditor** is a trademark of [CKSource Holding sp. z o.o.](https://cksource.com) All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.
21
+ **CKEditor** is a trademark of [CKSource Holding sp. z o.o.](https://cksource.com) All other brand and product names are trademarks, registered trademarks, or service marks of their respective holders.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-widget",
3
- "version": "39.0.2",
3
+ "version": "40.1.0",
4
4
  "description": "Widget API for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -11,12 +11,12 @@
11
11
  ],
12
12
  "main": "src/index.js",
13
13
  "dependencies": {
14
- "@ckeditor/ckeditor5-core": "39.0.2",
15
- "@ckeditor/ckeditor5-engine": "39.0.2",
16
- "@ckeditor/ckeditor5-enter": "39.0.2",
17
- "@ckeditor/ckeditor5-ui": "39.0.2",
18
- "@ckeditor/ckeditor5-utils": "39.0.2",
19
- "@ckeditor/ckeditor5-typing": "39.0.2",
14
+ "@ckeditor/ckeditor5-core": "40.1.0",
15
+ "@ckeditor/ckeditor5-engine": "40.1.0",
16
+ "@ckeditor/ckeditor5-enter": "40.1.0",
17
+ "@ckeditor/ckeditor5-ui": "40.1.0",
18
+ "@ckeditor/ckeditor5-utils": "40.1.0",
19
+ "@ckeditor/ckeditor5-typing": "40.1.0",
20
20
  "lodash-es": "4.17.21"
21
21
  },
22
22
  "author": "CKSource (http://cksource.com/)",
package/src/widget.d.ts CHANGED
@@ -44,6 +44,10 @@ export default class Widget extends Plugin {
44
44
  * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.
45
45
  */
46
46
  private _onMousedown;
47
+ /**
48
+ * Selects entire block content, e.g. on triple click it selects entire paragraph.
49
+ */
50
+ private _selectBlockContent;
47
51
  /**
48
52
  * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes
49
53
  * the model selection when:
package/src/widget.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * @module widget/widget
7
7
  */
8
8
  import { Plugin } from '@ckeditor/ckeditor5-core';
9
- import { MouseObserver } from '@ckeditor/ckeditor5-engine';
9
+ import { MouseObserver, TreeWalker } from '@ckeditor/ckeditor5-engine';
10
10
  import { Delete } from '@ckeditor/ckeditor5-typing';
11
11
  import { env, getLocalizedArrowKeyCodeDirection } from '@ckeditor/ckeditor5-utils';
12
12
  import WidgetTypeAround from './widgettypearound/widgettypearound';
@@ -154,23 +154,17 @@ export default class Widget extends Plugin {
154
154
  const view = editor.editing.view;
155
155
  const viewDocument = view.document;
156
156
  let element = domEventData.target;
157
- // Do nothing for single or double click inside nested editable.
158
- if (isInsideNestedEditable(element)) {
159
- // But at least triple click inside nested editable causes broken selection in Safari.
160
- // For such event, we select the entire nested editable element.
161
- // See: https://github.com/ckeditor/ckeditor5/issues/1463.
162
- if ((env.isSafari || env.isGecko) && domEventData.domEvent.detail >= 3) {
163
- const mapper = editor.editing.mapper;
164
- const viewElement = element.is('attributeElement') ?
165
- element.findAncestor(element => !element.is('attributeElement')) : element;
166
- const modelElement = mapper.toModelElement(viewElement);
157
+ // If triple click should select entire paragraph.
158
+ if (domEventData.domEvent.detail >= 3) {
159
+ if (this._selectBlockContent(element)) {
167
160
  domEventData.preventDefault();
168
- this.editor.model.change(writer => {
169
- writer.setSelection(modelElement, 'in');
170
- });
171
161
  }
172
162
  return;
173
163
  }
164
+ // Do nothing for single or double click inside nested editable.
165
+ if (isInsideNestedEditable(element)) {
166
+ return;
167
+ }
174
168
  // If target is not a widget element - check if one of the ancestors is.
175
169
  if (!isWidget(element)) {
176
170
  element = element.findAncestor(isWidget);
@@ -191,6 +185,31 @@ export default class Widget extends Plugin {
191
185
  const modelElement = editor.editing.mapper.toModelElement(element);
192
186
  this._setSelectionOverElement(modelElement);
193
187
  }
188
+ /**
189
+ * Selects entire block content, e.g. on triple click it selects entire paragraph.
190
+ */
191
+ _selectBlockContent(element) {
192
+ const editor = this.editor;
193
+ const model = editor.model;
194
+ const mapper = editor.editing.mapper;
195
+ const schema = model.schema;
196
+ const viewElement = mapper.findMappedViewAncestor(this.editor.editing.view.createPositionAt(element, 0));
197
+ const modelElement = findTextBlockAncestor(mapper.toModelElement(viewElement), model.schema);
198
+ if (!modelElement) {
199
+ return false;
200
+ }
201
+ model.change(writer => {
202
+ const nextTextBlock = !schema.isLimit(modelElement) ?
203
+ findNextTextBlock(writer.createPositionAfter(modelElement), schema) :
204
+ null;
205
+ const start = writer.createPositionAt(modelElement, 0);
206
+ const end = nextTextBlock ?
207
+ writer.createPositionAt(nextTextBlock, 0) :
208
+ writer.createPositionAt(modelElement, 'end');
209
+ writer.setSelection(writer.createRange(start, end));
210
+ });
211
+ return true;
212
+ }
194
213
  /**
195
214
  * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes
196
215
  * the model selection when:
@@ -378,3 +397,33 @@ function isChild(element, parent) {
378
397
  }
379
398
  return Array.from(element.getAncestors()).includes(parent);
380
399
  }
400
+ /**
401
+ * Returns nearest text block ancestor.
402
+ */
403
+ function findTextBlockAncestor(modelElement, schema) {
404
+ for (const element of modelElement.getAncestors({ includeSelf: true, parentFirst: true })) {
405
+ if (schema.checkChild(element, '$text')) {
406
+ return element;
407
+ }
408
+ // Do not go beyond nested editable.
409
+ if (schema.isLimit(element) && !schema.isObject(element)) {
410
+ break;
411
+ }
412
+ }
413
+ return null;
414
+ }
415
+ /**
416
+ * Returns next text block where could put selection.
417
+ */
418
+ function findNextTextBlock(position, schema) {
419
+ const treeWalker = new TreeWalker({ startPosition: position });
420
+ for (const { item } of treeWalker) {
421
+ if (schema.isLimit(item) || !item.is('element')) {
422
+ return null;
423
+ }
424
+ if (schema.checkChild(item, '$text')) {
425
+ return item;
426
+ }
427
+ }
428
+ return null;
429
+ }