@ckeditor/ckeditor5-engine 33.0.0 → 34.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.
@@ -185,10 +185,6 @@ export default class DowncastWriter {
185
185
  * // Set `id` of a marker element so it is not joined or merged with "normal" elements.
186
186
  * writer.createAttributeElement( 'span', { class: 'my-marker' }, { id: 'marker:my' } );
187
187
  *
188
- * **Note:** By default an `AttributeElement` is split by a
189
- * {@link module:engine/view/containerelement~ContainerElement `ContainerElement`} but this behavior can be modified
190
- * with `isAllowedInsideAttributeElement` option set while {@link #createContainerElement creating the element}.
191
- *
192
188
  * @param {String} name Name of the element.
193
189
  * @param {Object} [attributes] Element's attributes.
194
190
  * @param {Object} [options] Element's options.
@@ -237,7 +233,7 @@ export default class DowncastWriter {
237
233
  * ] );
238
234
  *
239
235
  * // Create element with specific options.
240
- * writer.createContainerElement( 'span', { class: 'placeholder' }, { isAllowedInsideAttributeElement: true } );
236
+ * writer.createContainerElement( 'span', { class: 'placeholder' }, { renderUnsafeAttributes: [ 'foo' ] } );
241
237
  *
242
238
  * @param {String} name Name of the element.
243
239
  * @param {Object} [attributes] Elements attributes.
@@ -245,9 +241,6 @@ export default class DowncastWriter {
245
241
  * A node or a list of nodes to be inserted into the created element. If no children were specified, element's `options`
246
242
  * can be passed in this argument.
247
243
  * @param {Object} [options] Element's options.
248
- * @param {Boolean} [options.isAllowedInsideAttributeElement=false] Whether an element is
249
- * {@link module:engine/view/element~Element#isAllowedInsideAttributeElement allowed inside an AttributeElement} and can be wrapped
250
- * with {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
251
244
  * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
252
245
  * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
253
246
  * @returns {module:engine/view/containerelement~ContainerElement} Created element.
@@ -263,10 +256,6 @@ export default class DowncastWriter {
263
256
 
264
257
  const containerElement = new ContainerElement( this.document, name, attributes, children );
265
258
 
266
- if ( options.isAllowedInsideAttributeElement !== undefined ) {
267
- containerElement._isAllowedInsideAttributeElement = options.isAllowedInsideAttributeElement;
268
- }
269
-
270
259
  if ( options.renderUnsafeAttributes ) {
271
260
  containerElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
272
261
  }
@@ -310,9 +299,6 @@ export default class DowncastWriter {
310
299
  * @param {String} name Name of the element.
311
300
  * @param {Object} [attributes] Elements attributes.
312
301
  * @param {Object} [options] Element's options.
313
- * @param {Boolean} [options.isAllowedInsideAttributeElement=true] Whether an element is
314
- * {@link module:engine/view/element~Element#isAllowedInsideAttributeElement allowed inside an AttributeElement} and can be wrapped
315
- * with {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
316
302
  * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
317
303
  * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
318
304
  * @returns {module:engine/view/emptyelement~EmptyElement} Created element.
@@ -320,10 +306,6 @@ export default class DowncastWriter {
320
306
  createEmptyElement( name, attributes, options = {} ) {
321
307
  const emptyElement = new EmptyElement( this.document, name, attributes );
322
308
 
323
- if ( options.isAllowedInsideAttributeElement !== undefined ) {
324
- emptyElement._isAllowedInsideAttributeElement = options.isAllowedInsideAttributeElement;
325
- }
326
-
327
309
  if ( options.renderUnsafeAttributes ) {
328
310
  emptyElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
329
311
  }
@@ -354,23 +336,15 @@ export default class DowncastWriter {
354
336
  * @param {String} name The name of the element.
355
337
  * @param {Object} [attributes] Element attributes.
356
338
  * @param {Function} [renderFunction] A custom render function.
357
- * @param {Object} [options] Element's options.
358
- * @param {Boolean} [options.isAllowedInsideAttributeElement=true] Whether an element is
359
- * {@link module:engine/view/element~Element#isAllowedInsideAttributeElement allowed inside an AttributeElement} and can be wrapped
360
- * with {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
361
339
  * @returns {module:engine/view/uielement~UIElement} The created element.
362
340
  */
363
- createUIElement( name, attributes, renderFunction, options = {} ) {
341
+ createUIElement( name, attributes, renderFunction ) {
364
342
  const uiElement = new UIElement( this.document, name, attributes );
365
343
 
366
344
  if ( renderFunction ) {
367
345
  uiElement.render = renderFunction;
368
346
  }
369
347
 
370
- if ( options.isAllowedInsideAttributeElement !== undefined ) {
371
- uiElement._isAllowedInsideAttributeElement = options.isAllowedInsideAttributeElement;
372
- }
373
-
374
348
  return uiElement;
375
349
  }
376
350
 
@@ -397,9 +371,6 @@ export default class DowncastWriter {
397
371
  * @param {Object} [attributes] Element attributes.
398
372
  * @param {Function} [renderFunction] A custom render function.
399
373
  * @param {Object} [options] Element's options.
400
- * @param {Boolean} [options.isAllowedInsideAttributeElement=true] Whether an element is
401
- * {@link module:engine/view/element~Element#isAllowedInsideAttributeElement allowed inside an AttributeElement} and can be wrapped
402
- * with {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
403
374
  * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
404
375
  * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
405
376
  * @returns {module:engine/view/rawelement~RawElement} The created element.
@@ -409,10 +380,6 @@ export default class DowncastWriter {
409
380
 
410
381
  rawElement.render = renderFunction || ( () => {} );
411
382
 
412
- if ( options.isAllowedInsideAttributeElement !== undefined ) {
413
- rawElement._isAllowedInsideAttributeElement = options.isAllowedInsideAttributeElement;
414
- }
415
-
416
383
  if ( options.renderUnsafeAttributes ) {
417
384
  rawElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
418
385
  }
@@ -790,7 +757,7 @@ export default class DowncastWriter {
790
757
 
791
758
  // Break attributes on nodes that do exist in the model tree so they can have attributes, other elements
792
759
  // can't have an attribute in model and won't get wrapped with an AttributeElement while down-casted.
793
- const breakAttributes = !( node.is( 'uiElement' ) && node.isAllowedInsideAttributeElement );
760
+ const breakAttributes = !node.is( 'uiElement' );
794
761
 
795
762
  if ( !lastGroup || lastGroup.breakAttributes != breakAttributes ) {
796
763
  groups.push( {
@@ -979,16 +946,6 @@ export default class DowncastWriter {
979
946
  * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-nonselection-collapsed-range` when passed range
980
947
  * is collapsed and different than view selection.
981
948
  *
982
- * **Note:** Attribute elements by default can wrap {@link module:engine/view/text~Text},
983
- * {@link module:engine/view/emptyelement~EmptyElement}, {@link module:engine/view/uielement~UIElement},
984
- * {@link module:engine/view/rawelement~RawElement} and other attribute elements with higher priority. Other elements while placed
985
- * inside an attribute element will split it (or nest it in case of an `AttributeElement`). This behavior can be modified by changing
986
- * the `isAllowedInsideAttributeElement` option while using
987
- * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement},
988
- * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement},
989
- * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement} or
990
- * {@link module:engine/view/downcastwriter~DowncastWriter#createRawElement}.
991
- *
992
949
  * @param {module:engine/view/range~Range} range Range to wrap.
993
950
  * @param {module:engine/view/attributeelement~AttributeElement} attribute Attribute element to use as wrapper.
994
951
  * @returns {module:engine/view/range~Range} range Range after wrapping, spanning over wrapping attribute element.
@@ -1399,7 +1356,6 @@ export default class DowncastWriter {
1399
1356
  const child = parent.getChild( i );
1400
1357
  const isText = child.is( '$text' );
1401
1358
  const isAttribute = child.is( 'attributeElement' );
1402
- const isAllowedInsideAttributeElement = child.isAllowedInsideAttributeElement;
1403
1359
 
1404
1360
  //
1405
1361
  // (In all examples, assume that `wrapElement` is `<span class="foo">` element.)
@@ -1418,7 +1374,7 @@ export default class DowncastWriter {
1418
1374
  //
1419
1375
  // <p>abc</p> --> <p><span class="foo">abc</span></p>
1420
1376
  // <p><strong>abc</strong></p> --> <p><span class="foo"><strong>abc</strong></span></p>
1421
- else if ( isText || isAllowedInsideAttributeElement || ( isAttribute && shouldABeOutsideB( wrapElement, child ) ) ) {
1377
+ else if ( isText || !isAttribute || shouldABeOutsideB( wrapElement, child ) ) {
1422
1378
  // Clone attribute.
1423
1379
  const newAttribute = wrapElement._clone();
1424
1380
 
@@ -1436,7 +1392,7 @@ export default class DowncastWriter {
1436
1392
  //
1437
1393
  // <p><a href="foo.html">abc</a></p> --> <p><a href="foo.html"><span class="foo">abc</span></a></p>
1438
1394
  //
1439
- else if ( isAttribute ) {
1395
+ else /* if ( isAttribute ) */ {
1440
1396
  this._wrapChildren( child, 0, child.childCount, wrapElement );
1441
1397
  }
1442
1398
 
@@ -130,15 +130,6 @@ export default class Element extends Node {
130
130
  */
131
131
  this._customProperties = new Map();
132
132
 
133
- /**
134
- * Whether an element is allowed inside an AttributeElement and can be wrapped with
135
- * {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
136
- *
137
- * @protected
138
- * @member {Boolean}
139
- */
140
- this._isAllowedInsideAttributeElement = false;
141
-
142
133
  /**
143
134
  * A list of attribute names that should be rendered in the editing pipeline even though filtering mechanisms
144
135
  * implemented in the {@link module:engine/view/domconverter~DomConverter} (for instance,
@@ -175,17 +166,6 @@ export default class Element extends Node {
175
166
  return this._children.length === 0;
176
167
  }
177
168
 
178
- /**
179
- * Whether the element is allowed inside an AttributeElement and can be wrapped with
180
- * {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
181
- *
182
- * @readonly
183
- * @type {Boolean}
184
- */
185
- get isAllowedInsideAttributeElement() {
186
- return this._isAllowedInsideAttributeElement;
187
- }
188
-
189
169
  /**
190
170
  * Checks whether this object is of the given.
191
171
  *
@@ -350,11 +330,6 @@ export default class Element extends Node {
350
330
  return false;
351
331
  }
352
332
 
353
- // Check isAllowedInsideAttributeElement property.
354
- if ( this.isAllowedInsideAttributeElement != otherElement.isAllowedInsideAttributeElement ) {
355
- return false;
356
- }
357
-
358
333
  // Check number of attributes, classes and styles.
359
334
  if ( this._attrs.size !== otherElement._attrs.size || this._classes.size !== otherElement._classes.size ||
360
335
  this._styles.size !== otherElement._styles.size ) {
@@ -633,8 +608,6 @@ export default class Element extends Node {
633
608
  // is changed by e.g. toWidget() function from ckeditor5-widget. Perhaps this should be one of custom props.
634
609
  cloned.getFillerOffset = this.getFillerOffset;
635
610
 
636
- cloned._isAllowedInsideAttributeElement = this.isAllowedInsideAttributeElement;
637
-
638
611
  return cloned;
639
612
  }
640
613
 
@@ -37,9 +37,6 @@ export default class EmptyElement extends Element {
37
37
  constructor( document, name, attrs, children ) {
38
38
  super( document, name, attrs, children );
39
39
 
40
- // Override the default of the base class.
41
- this._isAllowedInsideAttributeElement = true;
42
-
43
40
  /**
44
41
  * Returns `null` because filler is not needed for EmptyElements.
45
42
  *
@@ -739,7 +739,7 @@ function matchStyles( patterns, element ) {
739
739
  * styles: /^border.*$/
740
740
  * }
741
741
  *
742
- * Refer to the {@glink builds/guides/migration/migration-to-29##migration-to-ckeditor-5-v2910 Migration to v29.1.0} guide
742
+ * Refer to the {@glink updating/migration-to-29##migration-to-ckeditor-5-v2910 Migration to v29.1.0} guide
743
743
  * and {@link module:engine/view/matcher~MatcherPattern} documentation.
744
744
  *
745
745
  * @param {Object} pattern Pattern with missing properties.
@@ -769,7 +769,7 @@ function matchStyles( patterns, element ) {
769
769
  * classes: 'foobar'
770
770
  * }
771
771
  *
772
- * Refer to the {@glink builds/guides/migration/migration-to-29##migration-to-ckeditor-5-v2910 Migration to v29.1.0} guide
772
+ * Refer to the {@glink updating/migration-to-29##migration-to-ckeditor-5-v2910 Migration to v29.1.0} guide
773
773
  * and the {@link module:engine/view/matcher~MatcherPattern} documentation.
774
774
  *
775
775
  * @param {Object} pattern Pattern with missing properties.
@@ -1,4 +1,3 @@
1
-
2
1
  /**
3
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
4
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
6
6
  /**
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ /**
7
+ * @module engine/view/observer/tabobserver
8
+ */
9
+
10
+ import Observer from './observer';
11
+ import BubblingEventInfo from './bubblingeventinfo';
12
+
13
+ import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
14
+
15
+ /**
16
+ * Tab observer introduces the {@link module:engine/view/document~Document#event:tab `Document#tab`} event.
17
+ *
18
+ * Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the
19
+ * {@link module:engine/view/view~View} this event is available by default.
20
+ *
21
+ * @extends module:engine/view/observer/observer~Observer
22
+ */
23
+ export default class TabObserver extends Observer {
24
+ /**
25
+ * @inheritDoc
26
+ */
27
+ constructor( view ) {
28
+ super( view );
29
+
30
+ const doc = this.document;
31
+
32
+ doc.on( 'keydown', ( evt, data ) => {
33
+ if (
34
+ !this.isEnabled ||
35
+ data.keyCode != keyCodes.tab ||
36
+ data.ctrlKey
37
+ ) {
38
+ return;
39
+ }
40
+
41
+ const event = new BubblingEventInfo( doc, 'tab', doc.selection.getFirstRange() );
42
+
43
+ doc.fire( event, data );
44
+
45
+ if ( event.stop.called ) {
46
+ evt.stop();
47
+ }
48
+ } );
49
+ }
50
+
51
+ /**
52
+ * @inheritDoc
53
+ */
54
+ observe() {}
55
+ }
56
+
57
+ /**
58
+ * Event fired when the user presses a tab key.
59
+ *
60
+ * Introduced by {@link module:engine/view/observer/tabobserver~TabObserver}.
61
+ *
62
+ * Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the
63
+ * {@link module:engine/view/view~View} this event is available by default.
64
+ *
65
+ * @event module:engine/view/document~Document#event:tab
66
+ *
67
+ * @param {module:engine/view/observer/domeventdata~DomEventData} data
68
+ */
@@ -276,7 +276,7 @@ function getChildPlaceholderHostSubstitute( parent ) {
276
276
  if ( parent.childCount ) {
277
277
  const firstChild = parent.getChild( 0 );
278
278
 
279
- if ( firstChild.is( 'element' ) && !firstChild.is( 'uiElement' ) ) {
279
+ if ( firstChild.is( 'element' ) && !firstChild.is( 'uiElement' ) && !firstChild.is( 'attributeElement' ) ) {
280
280
  return firstChild;
281
281
  }
282
282
  }
@@ -47,9 +47,6 @@ export default class RawElement extends Element {
47
47
  constructor( document, name, attrs, children ) {
48
48
  super( document, name, attrs, children );
49
49
 
50
- // Override the default of the base class.
51
- this._isAllowedInsideAttributeElement = true;
52
-
53
50
  /**
54
51
  * Returns `null` because filler is not needed for raw elements.
55
52
  *
@@ -50,9 +50,6 @@ export default class UIElement extends Element {
50
50
  constructor( document, name, attributes, children ) {
51
51
  super( document, name, attributes, children );
52
52
 
53
- // Override the default of the base class.
54
- this._isAllowedInsideAttributeElement = true;
55
-
56
53
  /**
57
54
  * Returns `null` because filler is not needed for UIElements.
58
55
  *
package/src/view/view.js CHANGED
@@ -23,6 +23,7 @@ import FocusObserver from './observer/focusobserver';
23
23
  import CompositionObserver from './observer/compositionobserver';
24
24
  import InputObserver from './observer/inputobserver';
25
25
  import ArrowKeysObserver from './observer/arrowkeysobserver';
26
+ import TabObserver from './observer/tabobserver';
26
27
 
27
28
  import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
28
29
  import mix from '@ckeditor/ckeditor5-utils/src/mix';
@@ -54,6 +55,8 @@ import env from '@ckeditor/ckeditor5-utils/src/env';
54
55
  * * {@link module:engine/view/observer/keyobserver~KeyObserver},
55
56
  * * {@link module:engine/view/observer/fakeselectionobserver~FakeSelectionObserver}.
56
57
  * * {@link module:engine/view/observer/compositionobserver~CompositionObserver}.
58
+ * * {@link module:engine/view/observer/arrowkeysobserver~ArrowKeysObserver}.
59
+ * * {@link module:engine/view/observer/tabobserver~TabObserver}.
57
60
  *
58
61
  * This class also {@link module:engine/view/view~View#attachDomRoot binds the DOM and the view elements}.
59
62
  *
@@ -186,6 +189,7 @@ export default class View {
186
189
  this.addObserver( FakeSelectionObserver );
187
190
  this.addObserver( CompositionObserver );
188
191
  this.addObserver( ArrowKeysObserver );
192
+ this.addObserver( TabObserver );
189
193
 
190
194
  if ( env.isAndroid ) {
191
195
  this.addObserver( InputObserver );