@ckeditor/ckeditor5-code-block 35.4.0 → 36.0.1

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,105 +1,78 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module code-block/indentcodeblockcommand
8
7
  */
9
-
10
8
  import { Command } from 'ckeditor5/src/core';
11
-
12
- import {
13
- getIndentOutdentPositions,
14
- isModelSelectionInCodeBlock
15
- } from './utils';
16
-
9
+ import { getIndentOutdentPositions, isModelSelectionInCodeBlock } from './utils';
17
10
  /**
18
11
  * The code block indentation increase command plugin.
19
- *
20
- * @extends module:core/command~Command
21
12
  */
22
13
  export default class IndentCodeBlockCommand extends Command {
23
- constructor( editor ) {
24
- super( editor );
25
-
26
- /**
27
- * A sequence of characters added to the line when the command is executed.
28
- *
29
- * @readonly
30
- * @private
31
- * @member {String}
32
- */
33
- this._indentSequence = editor.config.get( 'codeBlock.indentSequence' );
34
- }
35
-
36
- /**
37
- * @inheritDoc
38
- */
39
- refresh() {
40
- this.isEnabled = this._checkEnabled();
41
- }
42
-
43
- /**
44
- * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
45
- * code lines in the selection will be increased.
46
- *
47
- * @fires execute
48
- */
49
- execute() {
50
- const editor = this.editor;
51
- const model = editor.model;
52
-
53
- model.change( writer => {
54
- const positions = getIndentOutdentPositions( model );
55
-
56
- // Indent all positions, for instance assuming the indent sequence is 4x space (" "):
57
- //
58
- // <codeBlock>^foo</codeBlock> -> <codeBlock> foo</codeBlock>
59
- //
60
- // <codeBlock>foo^bar</codeBlock> -> <codeBlock>foo bar</codeBlock>
61
- //
62
- // Also, when there is more than one position:
63
- //
64
- // <codeBlock>
65
- // ^foobar
66
- // <softBreak></softBreak>
67
- // ^bazqux
68
- // </codeBlock>
69
- //
70
- // ->
71
- //
72
- // <codeBlock>
73
- // foobar
74
- // <softBreak></softBreak>
75
- // bazqux
76
- // </codeBlock>
77
- //
78
- for ( const position of positions ) {
79
- const indentSequenceTextElement = writer.createText( this._indentSequence );
80
-
81
- // Previously insertion was done by writer.insertText(). It was changed to insertContent() to enable
82
- // integration of code block with track changes. It's the easiest way of integration because insertContent()
83
- // is already integrated with track changes, but if it ever cause any troubles it can be reverted, however
84
- // some additional work will be required in track changes integration of code block.
85
- model.insertContent( indentSequenceTextElement, position );
86
- }
87
- } );
88
- }
89
-
90
- /**
91
- * Checks whether the command can be enabled in the current context.
92
- *
93
- * @private
94
- * @returns {Boolean} Whether the command should be enabled.
95
- */
96
- _checkEnabled() {
97
- if ( !this._indentSequence ) {
98
- return false;
99
- }
100
-
101
- // Indent (forward) command is always enabled when there's any code block in the selection
102
- // because you can always indent code lines.
103
- return isModelSelectionInCodeBlock( this.editor.model.document.selection );
104
- }
14
+ constructor(editor) {
15
+ super(editor);
16
+ this._indentSequence = editor.config.get('codeBlock.indentSequence');
17
+ }
18
+ /**
19
+ * @inheritDoc
20
+ */
21
+ refresh() {
22
+ this.isEnabled = this._checkEnabled();
23
+ }
24
+ /**
25
+ * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
26
+ * code lines in the selection will be increased.
27
+ *
28
+ * @fires execute
29
+ */
30
+ execute() {
31
+ const editor = this.editor;
32
+ const model = editor.model;
33
+ model.change(writer => {
34
+ const positions = getIndentOutdentPositions(model);
35
+ // Indent all positions, for instance assuming the indent sequence is 4x space (" "):
36
+ //
37
+ // <codeBlock>^foo</codeBlock> -> <codeBlock> foo</codeBlock>
38
+ //
39
+ // <codeBlock>foo^bar</codeBlock> -> <codeBlock>foo bar</codeBlock>
40
+ //
41
+ // Also, when there is more than one position:
42
+ //
43
+ // <codeBlock>
44
+ // ^foobar
45
+ // <softBreak></softBreak>
46
+ // ^bazqux
47
+ // </codeBlock>
48
+ //
49
+ // ->
50
+ //
51
+ // <codeBlock>
52
+ // foobar
53
+ // <softBreak></softBreak>
54
+ // bazqux
55
+ // </codeBlock>
56
+ //
57
+ for (const position of positions) {
58
+ const indentSequenceTextElement = writer.createText(this._indentSequence);
59
+ // Previously insertion was done by writer.insertText(). It was changed to insertContent() to enable
60
+ // integration of code block with track changes. It's the easiest way of integration because insertContent()
61
+ // is already integrated with track changes, but if it ever cause any troubles it can be reverted, however
62
+ // some additional work will be required in track changes integration of code block.
63
+ model.insertContent(indentSequenceTextElement, position);
64
+ }
65
+ });
66
+ }
67
+ /**
68
+ * Checks whether the command can be enabled in the current context.
69
+ */
70
+ _checkEnabled() {
71
+ if (!this._indentSequence) {
72
+ return false;
73
+ }
74
+ // Indent (forward) command is always enabled when there's any code block in the selection
75
+ // because you can always indent code lines.
76
+ return isModelSelectionInCodeBlock(this.editor.model.document.selection);
77
+ }
105
78
  }
package/src/index.js CHANGED
@@ -1,12 +1,10 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module code-block
8
7
  */
9
-
10
8
  export { default as CodeBlock } from './codeblock';
11
9
  export { default as CodeBlockEditing } from './codeblockediting';
12
10
  export { default as CodeBlockUI } from './codeblockui';
@@ -1,119 +1,88 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
- /**
7
- * @module code-block/outdentcodeblockcommand
8
- */
9
-
10
5
  import { Command } from 'ckeditor5/src/core';
11
-
12
- import {
13
- getLeadingWhiteSpaces,
14
- getIndentOutdentPositions,
15
- isModelSelectionInCodeBlock
16
- } from './utils';
17
-
6
+ import { getLeadingWhiteSpaces, getIndentOutdentPositions, isModelSelectionInCodeBlock } from './utils';
18
7
  /**
19
8
  * The code block indentation decrease command plugin.
20
- *
21
- * @extends module:core/command~Command
22
9
  */
23
10
  export default class OutdentCodeBlockCommand extends Command {
24
- constructor( editor ) {
25
- super( editor );
26
-
27
- /**
28
- * A sequence of characters removed from the line when the command is executed.
29
- *
30
- * @readonly
31
- * @private
32
- * @member {String}
33
- */
34
- this._indentSequence = editor.config.get( 'codeBlock.indentSequence' );
35
- }
36
-
37
- /**
38
- * @inheritDoc
39
- */
40
- refresh() {
41
- this.isEnabled = this._checkEnabled();
42
- }
43
-
44
- /**
45
- * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
46
- * code lines in the selection will be decreased.
47
- *
48
- * @fires execute
49
- */
50
- execute() {
51
- const editor = this.editor;
52
- const model = editor.model;
53
-
54
- model.change( () => {
55
- const positions = getIndentOutdentPositions( model );
56
-
57
- // Outdent all positions, for instance assuming the indent sequence is 4x space (" "):
58
- //
59
- // <codeBlock>^foo</codeBlock> -> <codeBlock>foo</codeBlock>
60
- //
61
- // <codeBlock> ^bar</codeBlock> -> <codeBlock>bar</codeBlock>
62
- //
63
- // Also, when there is more than one position:
64
- //
65
- // <codeBlock>
66
- // ^foobar
67
- // <softBreak></softBreak>
68
- // ^bazqux
69
- // </codeBlock>
70
- //
71
- // ->
72
- //
73
- // <codeBlock>
74
- // foobar
75
- // <softBreak></softBreak>
76
- // bazqux
77
- // </codeBlock>
78
- for ( const position of positions ) {
79
- const range = getLastOutdentableSequenceRange( model, position, this._indentSequence );
80
-
81
- if ( range ) {
82
- // Previously deletion was done by writer.remove(). It was changed to deleteContent() to enable
83
- // integration of code block with track changes. It's the easiest way of integration because deleteContent()
84
- // is already integrated with track changes, but if it ever cause any troubles it can be reverted, however
85
- // some additional work will be required in track changes integration of code block.
86
- model.deleteContent( model.createSelection( range ) );
87
- }
88
- }
89
- } );
90
- }
91
-
92
- /**
93
- * Checks whether the command can be enabled in the current context.
94
- *
95
- * @private
96
- * @returns {Boolean} Whether the command should be enabled.
97
- */
98
- _checkEnabled() {
99
- if ( !this._indentSequence ) {
100
- return false;
101
- }
102
-
103
- const model = this.editor.model;
104
-
105
- if ( !isModelSelectionInCodeBlock( model.document.selection ) ) {
106
- return false;
107
- }
108
-
109
- // Outdent command can execute only when there is an indent character sequence
110
- // in some of the lines.
111
- return getIndentOutdentPositions( model ).some( position => {
112
- return getLastOutdentableSequenceRange( model, position, this._indentSequence );
113
- } );
114
- }
11
+ constructor(editor) {
12
+ super(editor);
13
+ this._indentSequence = editor.config.get('codeBlock.indentSequence');
14
+ }
15
+ /**
16
+ * @inheritDoc
17
+ */
18
+ refresh() {
19
+ this.isEnabled = this._checkEnabled();
20
+ }
21
+ /**
22
+ * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
23
+ * code lines in the selection will be decreased.
24
+ *
25
+ * @fires execute
26
+ */
27
+ execute() {
28
+ const editor = this.editor;
29
+ const model = editor.model;
30
+ model.change(() => {
31
+ const positions = getIndentOutdentPositions(model);
32
+ // Outdent all positions, for instance assuming the indent sequence is 4x space (" "):
33
+ //
34
+ // <codeBlock>^foo</codeBlock> -> <codeBlock>foo</codeBlock>
35
+ //
36
+ // <codeBlock> ^bar</codeBlock> -> <codeBlock>bar</codeBlock>
37
+ //
38
+ // Also, when there is more than one position:
39
+ //
40
+ // <codeBlock>
41
+ // ^foobar
42
+ // <softBreak></softBreak>
43
+ // ^bazqux
44
+ // </codeBlock>
45
+ //
46
+ // ->
47
+ //
48
+ // <codeBlock>
49
+ // foobar
50
+ // <softBreak></softBreak>
51
+ // bazqux
52
+ // </codeBlock>
53
+ for (const position of positions) {
54
+ const range = getLastOutdentableSequenceRange(model, position, this._indentSequence);
55
+ if (range) {
56
+ // Previously deletion was done by writer.remove(). It was changed to deleteContent() to enable
57
+ // integration of code block with track changes. It's the easiest way of integration because deleteContent()
58
+ // is already integrated with track changes, but if it ever cause any troubles it can be reverted, however
59
+ // some additional work will be required in track changes integration of code block.
60
+ model.deleteContent(model.createSelection(range));
61
+ }
62
+ }
63
+ });
64
+ }
65
+ /**
66
+ * Checks whether the command can be enabled in the current context.
67
+ *
68
+ * @private
69
+ * @returns {Boolean} Whether the command should be enabled.
70
+ */
71
+ _checkEnabled() {
72
+ if (!this._indentSequence) {
73
+ return false;
74
+ }
75
+ const model = this.editor.model;
76
+ if (!isModelSelectionInCodeBlock(model.document.selection)) {
77
+ return false;
78
+ }
79
+ // Outdent command can execute only when there is an indent character sequence
80
+ // in some of the lines.
81
+ return getIndentOutdentPositions(model).some(position => {
82
+ return getLastOutdentableSequenceRange(model, position, this._indentSequence);
83
+ });
84
+ }
115
85
  }
116
-
117
86
  // For a position coming from `getIndentOutdentPositions()`, it returns the range representing
118
87
  // the last occurrence of the indent sequence among the leading whitespaces of the code line the
119
88
  // position represents.
@@ -130,63 +99,50 @@ export default class OutdentCodeBlockCommand extends Command {
130
99
  // @param {<module:engine/model/position~Position>} position
131
100
  // @param {String} sequence
132
101
  // @returns {<module:engine/model/range~Range>|null}
133
- function getLastOutdentableSequenceRange( model, position, sequence ) {
134
- // Positions start before each text node (code line). Get the node corresponding to the position.
135
- const nodeAtPosition = getCodeLineTextNodeAtPosition( position );
136
-
137
- if ( !nodeAtPosition ) {
138
- return null;
139
- }
140
-
141
- const leadingWhiteSpaces = getLeadingWhiteSpaces( nodeAtPosition );
142
- const lastIndexOfSequence = leadingWhiteSpaces.lastIndexOf( sequence );
143
-
144
- // For instance, assuming the indent sequence is 4x space (" "):
145
- //
146
- // <codeBlock> ^foo</codeBlock> -> null
147
- //
148
- if ( lastIndexOfSequence + sequence.length !== leadingWhiteSpaces.length ) {
149
- return null;
150
- }
151
-
152
- // For instance, assuming the indent sequence is 4x space (" "):
153
- //
154
- // <codeBlock> ^foo</codeBlock> -> null
155
- //
156
- if ( lastIndexOfSequence === -1 ) {
157
- return null;
158
- }
159
-
160
- const { parent, startOffset } = nodeAtPosition;
161
-
162
- // Create a range that contains the **last** indent sequence among the leading whitespaces
163
- // of the line.
164
- //
165
- // For instance, assuming the indent sequence is 4x space (" "):
166
- //
167
- // <codeBlock> ^foo</codeBlock> -> <codeBlock> [ ]foo</codeBlock>
168
- //
169
- return model.createRange(
170
- model.createPositionAt( parent, startOffset + lastIndexOfSequence ),
171
- model.createPositionAt( parent, startOffset + lastIndexOfSequence + sequence.length )
172
- );
102
+ function getLastOutdentableSequenceRange(model, position, sequence) {
103
+ // Positions start before each text node (code line). Get the node corresponding to the position.
104
+ const nodeAtPosition = getCodeLineTextNodeAtPosition(position);
105
+ if (!nodeAtPosition) {
106
+ return null;
107
+ }
108
+ const leadingWhiteSpaces = getLeadingWhiteSpaces(nodeAtPosition);
109
+ const lastIndexOfSequence = leadingWhiteSpaces.lastIndexOf(sequence);
110
+ // For instance, assuming the indent sequence is 4x space (" "):
111
+ //
112
+ // <codeBlock> ^foo</codeBlock> -> null
113
+ //
114
+ if (lastIndexOfSequence + sequence.length !== leadingWhiteSpaces.length) {
115
+ return null;
116
+ }
117
+ // For instance, assuming the indent sequence is 4x space (" "):
118
+ //
119
+ // <codeBlock> ^foo</codeBlock> -> null
120
+ //
121
+ if (lastIndexOfSequence === -1) {
122
+ return null;
123
+ }
124
+ const { parent, startOffset } = nodeAtPosition;
125
+ // Create a range that contains the **last** indent sequence among the leading whitespaces
126
+ // of the line.
127
+ //
128
+ // For instance, assuming the indent sequence is 4x space (" "):
129
+ //
130
+ // <codeBlock> ^foo</codeBlock> -> <codeBlock> [ ]foo</codeBlock>
131
+ //
132
+ return model.createRange(model.createPositionAt(parent, startOffset + lastIndexOfSequence), model.createPositionAt(parent, startOffset + lastIndexOfSequence + sequence.length));
173
133
  }
174
-
175
- function getCodeLineTextNodeAtPosition( position ) {
176
- // Positions start before each text node (code line). Get the node corresponding to the position.
177
- let nodeAtPosition = position.parent.getChild( position.index );
178
-
179
- // <codeBlock>foo^</codeBlock>
180
- // <codeBlock>foo^<softBreak></softBreak>bar</codeBlock>
181
- if ( !nodeAtPosition || nodeAtPosition.is( 'element', 'softBreak' ) ) {
182
- nodeAtPosition = position.nodeBefore;
183
- }
184
-
185
- // <codeBlock>^</codeBlock>
186
- // <codeBlock>foo^<softBreak></softBreak>bar</codeBlock>
187
- if ( !nodeAtPosition || nodeAtPosition.is( 'element', 'softBreak' ) ) {
188
- return null;
189
- }
190
-
191
- return nodeAtPosition;
134
+ function getCodeLineTextNodeAtPosition(position) {
135
+ // Positions start before each text node (code line). Get the node corresponding to the position.
136
+ let nodeAtPosition = position.parent.getChild(position.index);
137
+ // <codeBlock>foo^</codeBlock>
138
+ // <codeBlock>foo^<softBreak></softBreak>bar</codeBlock>
139
+ if (!nodeAtPosition || nodeAtPosition.is('element', 'softBreak')) {
140
+ nodeAtPosition = position.nodeBefore;
141
+ }
142
+ // <codeBlock>^</codeBlock>
143
+ // <codeBlock>foo^<softBreak></softBreak>bar</codeBlock>
144
+ if (!nodeAtPosition || nodeAtPosition.is('element', 'softBreak')) {
145
+ return null;
146
+ }
147
+ return nodeAtPosition;
192
148
  }