@ckeditor/ckeditor5-enter 40.0.0 → 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.
@@ -1,61 +1,61 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, 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
- * @module enter/enterobserver
7
- */
8
- import { Observer, DomEventData, BubblingEventInfo } from '@ckeditor/ckeditor5-engine';
9
- import { env } from '@ckeditor/ckeditor5-utils';
10
- const ENTER_EVENT_TYPES = {
11
- insertParagraph: { isSoft: false },
12
- insertLineBreak: { isSoft: true }
13
- };
14
- /**
15
- * Enter observer introduces the {@link module:engine/view/document~Document#event:enter `Document#enter`} event.
16
- */
17
- export default class EnterObserver extends Observer {
18
- /**
19
- * @inheritDoc
20
- */
21
- constructor(view) {
22
- super(view);
23
- const doc = this.document;
24
- let shiftPressed = false;
25
- doc.on('keydown', (evt, data) => {
26
- shiftPressed = data.shiftKey;
27
- });
28
- doc.on('beforeinput', (evt, data) => {
29
- if (!this.isEnabled) {
30
- return;
31
- }
32
- let inputType = data.inputType;
33
- // See https://github.com/ckeditor/ckeditor5/issues/13321.
34
- if (env.isSafari && shiftPressed && inputType == 'insertParagraph') {
35
- inputType = 'insertLineBreak';
36
- }
37
- const domEvent = data.domEvent;
38
- const enterEventSpec = ENTER_EVENT_TYPES[inputType];
39
- if (!enterEventSpec) {
40
- return;
41
- }
42
- const event = new BubblingEventInfo(doc, 'enter', data.targetRanges[0]);
43
- doc.fire(event, new DomEventData(view, domEvent, {
44
- isSoft: enterEventSpec.isSoft
45
- }));
46
- // Stop `beforeinput` event if `enter` event was stopped.
47
- // https://github.com/ckeditor/ckeditor5/issues/753
48
- if (event.stop.called) {
49
- evt.stop();
50
- }
51
- });
52
- }
53
- /**
54
- * @inheritDoc
55
- */
56
- observe() { }
57
- /**
58
- * @inheritDoc
59
- */
60
- stopObserving() { }
61
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, 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
+ * @module enter/enterobserver
7
+ */
8
+ import { Observer, DomEventData, BubblingEventInfo } from '@ckeditor/ckeditor5-engine';
9
+ import { env } from '@ckeditor/ckeditor5-utils';
10
+ const ENTER_EVENT_TYPES = {
11
+ insertParagraph: { isSoft: false },
12
+ insertLineBreak: { isSoft: true }
13
+ };
14
+ /**
15
+ * Enter observer introduces the {@link module:engine/view/document~Document#event:enter `Document#enter`} event.
16
+ */
17
+ export default class EnterObserver extends Observer {
18
+ /**
19
+ * @inheritDoc
20
+ */
21
+ constructor(view) {
22
+ super(view);
23
+ const doc = this.document;
24
+ let shiftPressed = false;
25
+ doc.on('keydown', (evt, data) => {
26
+ shiftPressed = data.shiftKey;
27
+ });
28
+ doc.on('beforeinput', (evt, data) => {
29
+ if (!this.isEnabled) {
30
+ return;
31
+ }
32
+ let inputType = data.inputType;
33
+ // See https://github.com/ckeditor/ckeditor5/issues/13321.
34
+ if (env.isSafari && shiftPressed && inputType == 'insertParagraph') {
35
+ inputType = 'insertLineBreak';
36
+ }
37
+ const domEvent = data.domEvent;
38
+ const enterEventSpec = ENTER_EVENT_TYPES[inputType];
39
+ if (!enterEventSpec) {
40
+ return;
41
+ }
42
+ const event = new BubblingEventInfo(doc, 'enter', data.targetRanges[0]);
43
+ doc.fire(event, new DomEventData(view, domEvent, {
44
+ isSoft: enterEventSpec.isSoft
45
+ }));
46
+ // Stop `beforeinput` event if `enter` event was stopped.
47
+ // https://github.com/ckeditor/ckeditor5/issues/753
48
+ if (event.stop.called) {
49
+ evt.stop();
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * @inheritDoc
55
+ */
56
+ observe() { }
57
+ /**
58
+ * @inheritDoc
59
+ */
60
+ stopObserving() { }
61
+ }
package/src/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, 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
- * @module enter
7
- */
8
- export { default as Enter } from './enter';
9
- export { default as ShiftEnter } from './shiftenter';
10
- export type { ViewDocumentEnterEvent } from './enterobserver';
11
- export type { default as EnterCommand, EnterCommandAfterExecuteEvent } from './entercommand';
12
- export type { default as ShiftEnterCommand } from './shiftentercommand';
13
- import './augmentation';
1
+ /**
2
+ * @license Copyright (c) 2003-2023, 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
+ * @module enter
7
+ */
8
+ export { default as Enter } from './enter';
9
+ export { default as ShiftEnter } from './shiftenter';
10
+ export type { ViewDocumentEnterEvent } from './enterobserver';
11
+ export type { default as EnterCommand, EnterCommandAfterExecuteEvent } from './entercommand';
12
+ export type { default as ShiftEnterCommand } from './shiftentercommand';
13
+ import './augmentation';
package/src/index.js CHANGED
@@ -1,10 +1,10 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, 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
- * @module enter
7
- */
8
- export { default as Enter } from './enter';
9
- export { default as ShiftEnter } from './shiftenter';
10
- import './augmentation';
1
+ /**
2
+ * @license Copyright (c) 2003-2023, 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
+ * @module enter
7
+ */
8
+ export { default as Enter } from './enter';
9
+ export { default as ShiftEnter } from './shiftenter';
10
+ import './augmentation';
@@ -1,19 +1,19 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, 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
- import { Plugin } from '@ckeditor/ckeditor5-core';
6
- /**
7
- * This plugin handles the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke (soft line break) in the editor.
8
- *
9
- * See also the {@link module:enter/enter~Enter} plugin.
10
- *
11
- * For more information about this feature see the {@glink api/enter package page}.
12
- */
13
- export default class ShiftEnter extends Plugin {
14
- /**
15
- * @inheritDoc
16
- */
17
- static get pluginName(): "ShiftEnter";
18
- init(): void;
19
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, 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
+ import { Plugin } from '@ckeditor/ckeditor5-core';
6
+ /**
7
+ * This plugin handles the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke (soft line break) in the editor.
8
+ *
9
+ * See also the {@link module:enter/enter~Enter} plugin.
10
+ *
11
+ * For more information about this feature see the {@glink api/enter package page}.
12
+ */
13
+ export default class ShiftEnter extends Plugin {
14
+ /**
15
+ * @inheritDoc
16
+ */
17
+ static get pluginName(): "ShiftEnter";
18
+ init(): void;
19
+ }
package/src/shiftenter.js CHANGED
@@ -1,63 +1,63 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, 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
- * @module enter/shiftenter
7
- */
8
- import ShiftEnterCommand from './shiftentercommand';
9
- import EnterObserver from './enterobserver';
10
- import { Plugin } from '@ckeditor/ckeditor5-core';
11
- /**
12
- * This plugin handles the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke (soft line break) in the editor.
13
- *
14
- * See also the {@link module:enter/enter~Enter} plugin.
15
- *
16
- * For more information about this feature see the {@glink api/enter package page}.
17
- */
18
- export default class ShiftEnter extends Plugin {
19
- /**
20
- * @inheritDoc
21
- */
22
- static get pluginName() {
23
- return 'ShiftEnter';
24
- }
25
- init() {
26
- const editor = this.editor;
27
- const schema = editor.model.schema;
28
- const conversion = editor.conversion;
29
- const view = editor.editing.view;
30
- const viewDocument = view.document;
31
- // Configure the schema.
32
- schema.register('softBreak', {
33
- allowWhere: '$text',
34
- isInline: true
35
- });
36
- // Configure converters.
37
- conversion.for('upcast')
38
- .elementToElement({
39
- model: 'softBreak',
40
- view: 'br'
41
- });
42
- conversion.for('downcast')
43
- .elementToElement({
44
- model: 'softBreak',
45
- view: (modelElement, { writer }) => writer.createEmptyElement('br')
46
- });
47
- view.addObserver(EnterObserver);
48
- editor.commands.add('shiftEnter', new ShiftEnterCommand(editor));
49
- this.listenTo(viewDocument, 'enter', (evt, data) => {
50
- // When not in composition, we handle the action, so prevent the default one.
51
- // When in composition, it's the browser who modify the DOM (renderer is disabled).
52
- if (!viewDocument.isComposing) {
53
- data.preventDefault();
54
- }
55
- // The hard enter key is handled by the Enter plugin.
56
- if (!data.isSoft) {
57
- return;
58
- }
59
- editor.execute('shiftEnter');
60
- view.scrollToTheSelection();
61
- }, { priority: 'low' });
62
- }
63
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, 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
+ * @module enter/shiftenter
7
+ */
8
+ import ShiftEnterCommand from './shiftentercommand';
9
+ import EnterObserver from './enterobserver';
10
+ import { Plugin } from '@ckeditor/ckeditor5-core';
11
+ /**
12
+ * This plugin handles the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke (soft line break) in the editor.
13
+ *
14
+ * See also the {@link module:enter/enter~Enter} plugin.
15
+ *
16
+ * For more information about this feature see the {@glink api/enter package page}.
17
+ */
18
+ export default class ShiftEnter extends Plugin {
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ static get pluginName() {
23
+ return 'ShiftEnter';
24
+ }
25
+ init() {
26
+ const editor = this.editor;
27
+ const schema = editor.model.schema;
28
+ const conversion = editor.conversion;
29
+ const view = editor.editing.view;
30
+ const viewDocument = view.document;
31
+ // Configure the schema.
32
+ schema.register('softBreak', {
33
+ allowWhere: '$text',
34
+ isInline: true
35
+ });
36
+ // Configure converters.
37
+ conversion.for('upcast')
38
+ .elementToElement({
39
+ model: 'softBreak',
40
+ view: 'br'
41
+ });
42
+ conversion.for('downcast')
43
+ .elementToElement({
44
+ model: 'softBreak',
45
+ view: (modelElement, { writer }) => writer.createEmptyElement('br')
46
+ });
47
+ view.addObserver(EnterObserver);
48
+ editor.commands.add('shiftEnter', new ShiftEnterCommand(editor));
49
+ this.listenTo(viewDocument, 'enter', (evt, data) => {
50
+ // When not in composition, we handle the action, so prevent the default one.
51
+ // When in composition, it's the browser who modify the DOM (renderer is disabled).
52
+ if (!viewDocument.isComposing) {
53
+ data.preventDefault();
54
+ }
55
+ // The hard enter key is handled by the Enter plugin.
56
+ if (!data.isSoft) {
57
+ return;
58
+ }
59
+ editor.execute('shiftEnter');
60
+ view.scrollToTheSelection();
61
+ }, { priority: 'low' });
62
+ }
63
+ }
@@ -1,34 +1,34 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, 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
- * @module enter/shiftentercommand
7
- */
8
- import { Command } from '@ckeditor/ckeditor5-core';
9
- import type { Writer } from '@ckeditor/ckeditor5-engine';
10
- /**
11
- * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle
12
- * the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke.
13
- */
14
- export default class ShiftEnterCommand extends Command {
15
- /**
16
- * @inheritDoc
17
- */
18
- execute(): void;
19
- /**
20
- * @inheritDoc
21
- */
22
- refresh(): void;
23
- }
24
- /**
25
- * Fired after the the {@link module:enter/shiftentercommand~ShiftEnterCommand} is finished executing.
26
- *
27
- * @eventName ~ShiftEnterCommand#afterExecute
28
- */
29
- export type ShiftEnterCommandAfterExecuteEvent = {
30
- name: 'afterExecute';
31
- args: [{
32
- writer: Writer;
33
- }];
34
- };
1
+ /**
2
+ * @license Copyright (c) 2003-2023, 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
+ * @module enter/shiftentercommand
7
+ */
8
+ import { Command } from '@ckeditor/ckeditor5-core';
9
+ import type { Writer } from '@ckeditor/ckeditor5-engine';
10
+ /**
11
+ * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle
12
+ * the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke.
13
+ */
14
+ export default class ShiftEnterCommand extends Command {
15
+ /**
16
+ * @inheritDoc
17
+ */
18
+ execute(): void;
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ refresh(): void;
23
+ }
24
+ /**
25
+ * Fired after the the {@link module:enter/shiftentercommand~ShiftEnterCommand} is finished executing.
26
+ *
27
+ * @eventName ~ShiftEnterCommand#afterExecute
28
+ */
29
+ export type ShiftEnterCommandAfterExecuteEvent = {
30
+ name: 'afterExecute';
31
+ args: [{
32
+ writer: Writer;
33
+ }];
34
+ };
@@ -1,118 +1,118 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, 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
- * @module enter/shiftentercommand
7
- */
8
- import { Command } from '@ckeditor/ckeditor5-core';
9
- import { getCopyOnEnterAttributes } from './utils';
10
- /**
11
- * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle
12
- * the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke.
13
- */
14
- export default class ShiftEnterCommand extends Command {
15
- /**
16
- * @inheritDoc
17
- */
18
- execute() {
19
- const model = this.editor.model;
20
- const doc = model.document;
21
- model.change(writer => {
22
- softBreakAction(model, writer, doc.selection);
23
- this.fire('afterExecute', { writer });
24
- });
25
- }
26
- /**
27
- * @inheritDoc
28
- */
29
- refresh() {
30
- const model = this.editor.model;
31
- const doc = model.document;
32
- this.isEnabled = isEnabled(model.schema, doc.selection);
33
- }
34
- }
35
- /**
36
- * Checks whether the ShiftEnter command should be enabled in the specified selection.
37
- */
38
- function isEnabled(schema, selection) {
39
- // At this moment it is okay to support single range selections only.
40
- // But in the future we may need to change that.
41
- if (selection.rangeCount > 1) {
42
- return false;
43
- }
44
- const anchorPos = selection.anchor;
45
- // Check whether the break element can be inserted in the current selection anchor.
46
- if (!anchorPos || !schema.checkChild(anchorPos, 'softBreak')) {
47
- return false;
48
- }
49
- const range = selection.getFirstRange();
50
- const startElement = range.start.parent;
51
- const endElement = range.end.parent;
52
- // Do not modify the content if selection is cross-limit elements.
53
- if ((isInsideLimitElement(startElement, schema) || isInsideLimitElement(endElement, schema)) && startElement !== endElement) {
54
- return false;
55
- }
56
- return true;
57
- }
58
- /**
59
- * Creates a break in the way that the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke is expected to work.
60
- */
61
- function softBreakAction(model, writer, selection) {
62
- const isSelectionEmpty = selection.isCollapsed;
63
- const range = selection.getFirstRange();
64
- const startElement = range.start.parent;
65
- const endElement = range.end.parent;
66
- const isContainedWithinOneElement = (startElement == endElement);
67
- if (isSelectionEmpty) {
68
- const attributesToCopy = getCopyOnEnterAttributes(model.schema, selection.getAttributes());
69
- insertBreak(model, writer, range.end);
70
- writer.removeSelectionAttribute(selection.getAttributeKeys());
71
- writer.setSelectionAttribute(attributesToCopy);
72
- }
73
- else {
74
- const leaveUnmerged = !(range.start.isAtStart && range.end.isAtEnd);
75
- model.deleteContent(selection, { leaveUnmerged });
76
- // Selection within one element:
77
- //
78
- // <h>x[xx]x</h> -> <h>x^x</h> -> <h>x<br>^x</h>
79
- if (isContainedWithinOneElement) {
80
- insertBreak(model, writer, selection.focus);
81
- }
82
- // Selection over multiple elements.
83
- //
84
- // <h>x[x</h><p>y]y<p> -> <h>x^</h><p>y</p> -> <h>x</h><p>^y</p>
85
- //
86
- // We chose not to insert a line break in this case because:
87
- //
88
- // * it's not a very common scenario,
89
- // * it actually surprised me when I saw the "expected behavior" in real life.
90
- //
91
- // It's ok if the user will need to be more specific where they want the <br> to be inserted.
92
- else {
93
- // Move the selection to the 2nd element (last step of the example above).
94
- if (leaveUnmerged) {
95
- writer.setSelection(endElement, 0);
96
- }
97
- }
98
- }
99
- }
100
- function insertBreak(model, writer, position) {
101
- const breakLineElement = writer.createElement('softBreak');
102
- model.insertContent(breakLineElement, position);
103
- writer.setSelection(breakLineElement, 'after');
104
- }
105
- /**
106
- * Checks whether the specified `element` is a child of the limit element.
107
- *
108
- * Checking whether the `<p>` element is inside a limit element:
109
- * - `<$root><p>Text.</p></$root> => false`
110
- * - `<$root><limitElement><p>Text</p></limitElement></$root> => true`
111
- */
112
- function isInsideLimitElement(element, schema) {
113
- // `$root` is a limit element but in this case is an invalid element.
114
- if (element.is('rootElement')) {
115
- return false;
116
- }
117
- return schema.isLimit(element) || isInsideLimitElement(element.parent, schema);
118
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, 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
+ * @module enter/shiftentercommand
7
+ */
8
+ import { Command } from '@ckeditor/ckeditor5-core';
9
+ import { getCopyOnEnterAttributes } from './utils';
10
+ /**
11
+ * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle
12
+ * the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke.
13
+ */
14
+ export default class ShiftEnterCommand extends Command {
15
+ /**
16
+ * @inheritDoc
17
+ */
18
+ execute() {
19
+ const model = this.editor.model;
20
+ const doc = model.document;
21
+ model.change(writer => {
22
+ softBreakAction(model, writer, doc.selection);
23
+ this.fire('afterExecute', { writer });
24
+ });
25
+ }
26
+ /**
27
+ * @inheritDoc
28
+ */
29
+ refresh() {
30
+ const model = this.editor.model;
31
+ const doc = model.document;
32
+ this.isEnabled = isEnabled(model.schema, doc.selection);
33
+ }
34
+ }
35
+ /**
36
+ * Checks whether the ShiftEnter command should be enabled in the specified selection.
37
+ */
38
+ function isEnabled(schema, selection) {
39
+ // At this moment it is okay to support single range selections only.
40
+ // But in the future we may need to change that.
41
+ if (selection.rangeCount > 1) {
42
+ return false;
43
+ }
44
+ const anchorPos = selection.anchor;
45
+ // Check whether the break element can be inserted in the current selection anchor.
46
+ if (!anchorPos || !schema.checkChild(anchorPos, 'softBreak')) {
47
+ return false;
48
+ }
49
+ const range = selection.getFirstRange();
50
+ const startElement = range.start.parent;
51
+ const endElement = range.end.parent;
52
+ // Do not modify the content if selection is cross-limit elements.
53
+ if ((isInsideLimitElement(startElement, schema) || isInsideLimitElement(endElement, schema)) && startElement !== endElement) {
54
+ return false;
55
+ }
56
+ return true;
57
+ }
58
+ /**
59
+ * Creates a break in the way that the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke is expected to work.
60
+ */
61
+ function softBreakAction(model, writer, selection) {
62
+ const isSelectionEmpty = selection.isCollapsed;
63
+ const range = selection.getFirstRange();
64
+ const startElement = range.start.parent;
65
+ const endElement = range.end.parent;
66
+ const isContainedWithinOneElement = (startElement == endElement);
67
+ if (isSelectionEmpty) {
68
+ const attributesToCopy = getCopyOnEnterAttributes(model.schema, selection.getAttributes());
69
+ insertBreak(model, writer, range.end);
70
+ writer.removeSelectionAttribute(selection.getAttributeKeys());
71
+ writer.setSelectionAttribute(attributesToCopy);
72
+ }
73
+ else {
74
+ const leaveUnmerged = !(range.start.isAtStart && range.end.isAtEnd);
75
+ model.deleteContent(selection, { leaveUnmerged });
76
+ // Selection within one element:
77
+ //
78
+ // <h>x[xx]x</h> -> <h>x^x</h> -> <h>x<br>^x</h>
79
+ if (isContainedWithinOneElement) {
80
+ insertBreak(model, writer, selection.focus);
81
+ }
82
+ // Selection over multiple elements.
83
+ //
84
+ // <h>x[x</h><p>y]y<p> -> <h>x^</h><p>y</p> -> <h>x</h><p>^y</p>
85
+ //
86
+ // We chose not to insert a line break in this case because:
87
+ //
88
+ // * it's not a very common scenario,
89
+ // * it actually surprised me when I saw the "expected behavior" in real life.
90
+ //
91
+ // It's ok if the user will need to be more specific where they want the <br> to be inserted.
92
+ else {
93
+ // Move the selection to the 2nd element (last step of the example above).
94
+ if (leaveUnmerged) {
95
+ writer.setSelection(endElement, 0);
96
+ }
97
+ }
98
+ }
99
+ }
100
+ function insertBreak(model, writer, position) {
101
+ const breakLineElement = writer.createElement('softBreak');
102
+ model.insertContent(breakLineElement, position);
103
+ writer.setSelection(breakLineElement, 'after');
104
+ }
105
+ /**
106
+ * Checks whether the specified `element` is a child of the limit element.
107
+ *
108
+ * Checking whether the `<p>` element is inside a limit element:
109
+ * - `<$root><p>Text.</p></$root> => false`
110
+ * - `<$root><limitElement><p>Text</p></limitElement></$root> => true`
111
+ */
112
+ function isInsideLimitElement(element, schema) {
113
+ // `$root` is a limit element but in this case is an invalid element.
114
+ if (element.is('rootElement')) {
115
+ return false;
116
+ }
117
+ return schema.isLimit(element) || isInsideLimitElement(element.parent, schema);
118
+ }