@ckeditor/ckeditor5-widget 39.0.2 → 40.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }