@ckeditor/ckeditor5-block-quote 38.1.1 → 38.2.0-alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +3 -2
- package/src/augmentation.d.ts +15 -15
- package/src/augmentation.js +5 -5
- package/src/blockquote.d.ts +30 -30
- package/src/blockquote.js +34 -34
- package/src/blockquotecommand.d.ts +61 -61
- package/src/blockquotecommand.js +172 -172
- package/src/blockquoteediting.d.ts +31 -31
- package/src/blockquoteediting.js +118 -118
- package/src/blockquoteui.d.ts +26 -26
- package/src/blockquoteui.js +50 -50
- package/src/index.d.ts +12 -12
- package/src/index.js +11 -11
- package/build/block-quote.js.map +0 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ckeditor/ckeditor5-block-quote",
|
3
|
-
"version": "38.
|
3
|
+
"version": "38.2.0-alpha.1",
|
4
4
|
"description": "Block quote feature for CKEditor 5.",
|
5
5
|
"keywords": [
|
6
6
|
"ckeditor",
|
@@ -11,8 +11,9 @@
|
|
11
11
|
"ckeditor5-dll"
|
12
12
|
],
|
13
13
|
"main": "src/index.js",
|
14
|
+
"type": "module",
|
14
15
|
"dependencies": {
|
15
|
-
"ckeditor5": "38.
|
16
|
+
"ckeditor5": "38.2.0-alpha.1"
|
16
17
|
},
|
17
18
|
"engines": {
|
18
19
|
"node": ">=16.0.0",
|
package/src/augmentation.d.ts
CHANGED
@@ -1,15 +1,15 @@
|
|
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 type { BlockQuote, BlockQuoteCommand, BlockQuoteEditing, BlockQuoteUI } from './index';
|
6
|
-
declare module '@ckeditor/ckeditor5-core' {
|
7
|
-
interface PluginsMap {
|
8
|
-
[BlockQuote.pluginName]: BlockQuote;
|
9
|
-
[BlockQuoteEditing.pluginName]: BlockQuoteEditing;
|
10
|
-
[BlockQuoteUI.pluginName]: BlockQuoteUI;
|
11
|
-
}
|
12
|
-
interface CommandsMap {
|
13
|
-
blockQuote: BlockQuoteCommand;
|
14
|
-
}
|
15
|
-
}
|
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 type { BlockQuote, BlockQuoteCommand, BlockQuoteEditing, BlockQuoteUI } from './index.js';
|
6
|
+
declare module '@ckeditor/ckeditor5-core' {
|
7
|
+
interface PluginsMap {
|
8
|
+
[BlockQuote.pluginName]: BlockQuote;
|
9
|
+
[BlockQuoteEditing.pluginName]: BlockQuoteEditing;
|
10
|
+
[BlockQuoteUI.pluginName]: BlockQuoteUI;
|
11
|
+
}
|
12
|
+
interface CommandsMap {
|
13
|
+
blockQuote: BlockQuoteCommand;
|
14
|
+
}
|
15
|
+
}
|
package/src/augmentation.js
CHANGED
@@ -1,5 +1,5 @@
|
|
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
|
-
export {};
|
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
|
+
export {};
|
package/src/blockquote.d.ts
CHANGED
@@ -1,30 +1,30 @@
|
|
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 block-quote/blockquote
|
7
|
-
*/
|
8
|
-
import { Plugin } from 'ckeditor5/src/core';
|
9
|
-
import BlockQuoteEditing from './blockquoteediting';
|
10
|
-
import BlockQuoteUI from './blockquoteui';
|
11
|
-
/**
|
12
|
-
* The block quote plugin.
|
13
|
-
*
|
14
|
-
* For more information about this feature check the {@glink api/block-quote package page}.
|
15
|
-
*
|
16
|
-
* This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}
|
17
|
-
* and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.
|
18
|
-
*
|
19
|
-
* @extends module:core/plugin~Plugin
|
20
|
-
*/
|
21
|
-
export default class BlockQuote extends Plugin {
|
22
|
-
/**
|
23
|
-
* @inheritDoc
|
24
|
-
*/
|
25
|
-
static get requires(): readonly [typeof BlockQuoteEditing, typeof BlockQuoteUI];
|
26
|
-
/**
|
27
|
-
* @inheritDoc
|
28
|
-
*/
|
29
|
-
static get pluginName(): "BlockQuote";
|
30
|
-
}
|
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 block-quote/blockquote
|
7
|
+
*/
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
9
|
+
import BlockQuoteEditing from './blockquoteediting.js';
|
10
|
+
import BlockQuoteUI from './blockquoteui.js';
|
11
|
+
/**
|
12
|
+
* The block quote plugin.
|
13
|
+
*
|
14
|
+
* For more information about this feature check the {@glink api/block-quote package page}.
|
15
|
+
*
|
16
|
+
* This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}
|
17
|
+
* and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.
|
18
|
+
*
|
19
|
+
* @extends module:core/plugin~Plugin
|
20
|
+
*/
|
21
|
+
export default class BlockQuote extends Plugin {
|
22
|
+
/**
|
23
|
+
* @inheritDoc
|
24
|
+
*/
|
25
|
+
static get requires(): readonly [typeof BlockQuoteEditing, typeof BlockQuoteUI];
|
26
|
+
/**
|
27
|
+
* @inheritDoc
|
28
|
+
*/
|
29
|
+
static get pluginName(): "BlockQuote";
|
30
|
+
}
|
package/src/blockquote.js
CHANGED
@@ -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 block-quote/blockquote
|
7
|
-
*/
|
8
|
-
import { Plugin } from 'ckeditor5/src/core';
|
9
|
-
import BlockQuoteEditing from './blockquoteediting';
|
10
|
-
import BlockQuoteUI from './blockquoteui';
|
11
|
-
/**
|
12
|
-
* The block quote plugin.
|
13
|
-
*
|
14
|
-
* For more information about this feature check the {@glink api/block-quote package page}.
|
15
|
-
*
|
16
|
-
* This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}
|
17
|
-
* and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.
|
18
|
-
*
|
19
|
-
* @extends module:core/plugin~Plugin
|
20
|
-
*/
|
21
|
-
export default class BlockQuote extends Plugin {
|
22
|
-
/**
|
23
|
-
* @inheritDoc
|
24
|
-
*/
|
25
|
-
static get requires() {
|
26
|
-
return [BlockQuoteEditing, BlockQuoteUI];
|
27
|
-
}
|
28
|
-
/**
|
29
|
-
* @inheritDoc
|
30
|
-
*/
|
31
|
-
static get pluginName() {
|
32
|
-
return 'BlockQuote';
|
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 block-quote/blockquote
|
7
|
+
*/
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
9
|
+
import BlockQuoteEditing from './blockquoteediting.js';
|
10
|
+
import BlockQuoteUI from './blockquoteui.js';
|
11
|
+
/**
|
12
|
+
* The block quote plugin.
|
13
|
+
*
|
14
|
+
* For more information about this feature check the {@glink api/block-quote package page}.
|
15
|
+
*
|
16
|
+
* This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}
|
17
|
+
* and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.
|
18
|
+
*
|
19
|
+
* @extends module:core/plugin~Plugin
|
20
|
+
*/
|
21
|
+
export default class BlockQuote extends Plugin {
|
22
|
+
/**
|
23
|
+
* @inheritDoc
|
24
|
+
*/
|
25
|
+
static get requires() {
|
26
|
+
return [BlockQuoteEditing, BlockQuoteUI];
|
27
|
+
}
|
28
|
+
/**
|
29
|
+
* @inheritDoc
|
30
|
+
*/
|
31
|
+
static get pluginName() {
|
32
|
+
return 'BlockQuote';
|
33
|
+
}
|
34
|
+
}
|
@@ -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 block-quote/blockquotecommand
|
7
|
-
*/
|
8
|
-
import { Command } from 'ckeditor5/src/core';
|
9
|
-
/**
|
10
|
-
* The block quote command plugin.
|
11
|
-
*
|
12
|
-
* @extends module:core/command~Command
|
13
|
-
*/
|
14
|
-
export default class BlockQuoteCommand extends Command {
|
15
|
-
/**
|
16
|
-
* Whether the selection starts in a block quote.
|
17
|
-
*
|
18
|
-
* @observable
|
19
|
-
* @readonly
|
20
|
-
*/
|
21
|
-
value: boolean;
|
22
|
-
/**
|
23
|
-
* @inheritDoc
|
24
|
-
*/
|
25
|
-
refresh(): void;
|
26
|
-
/**
|
27
|
-
* Executes the command. When the command {@link #value is on}, all top-most block quotes within
|
28
|
-
* the selection will be removed. If it is off, all selected blocks will be wrapped with
|
29
|
-
* a block quote.
|
30
|
-
*
|
31
|
-
* @fires execute
|
32
|
-
* @param options Command options.
|
33
|
-
* @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote,
|
34
|
-
* otherwise the command will remove the block quote. If not set, the command will act basing on its current value.
|
35
|
-
*/
|
36
|
-
execute(options?: {
|
37
|
-
forceValue?: boolean;
|
38
|
-
}): void;
|
39
|
-
/**
|
40
|
-
* Checks the command's {@link #value}.
|
41
|
-
*/
|
42
|
-
private _getValue;
|
43
|
-
/**
|
44
|
-
* Checks whether the command can be enabled in the current context.
|
45
|
-
*
|
46
|
-
* @returns Whether the command should be enabled.
|
47
|
-
*/
|
48
|
-
private _checkEnabled;
|
49
|
-
/**
|
50
|
-
* Removes the quote from given blocks.
|
51
|
-
*
|
52
|
-
* If blocks which are supposed to be "unquoted" are in the middle of a quote,
|
53
|
-
* start it or end it, then the quote will be split (if needed) and the blocks
|
54
|
-
* will be moved out of it, so other quoted blocks remained quoted.
|
55
|
-
*/
|
56
|
-
private _removeQuote;
|
57
|
-
/**
|
58
|
-
* Applies the quote to given blocks.
|
59
|
-
*/
|
60
|
-
private _applyQuote;
|
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 block-quote/blockquotecommand
|
7
|
+
*/
|
8
|
+
import { Command } from 'ckeditor5/src/core.js';
|
9
|
+
/**
|
10
|
+
* The block quote command plugin.
|
11
|
+
*
|
12
|
+
* @extends module:core/command~Command
|
13
|
+
*/
|
14
|
+
export default class BlockQuoteCommand extends Command {
|
15
|
+
/**
|
16
|
+
* Whether the selection starts in a block quote.
|
17
|
+
*
|
18
|
+
* @observable
|
19
|
+
* @readonly
|
20
|
+
*/
|
21
|
+
value: boolean;
|
22
|
+
/**
|
23
|
+
* @inheritDoc
|
24
|
+
*/
|
25
|
+
refresh(): void;
|
26
|
+
/**
|
27
|
+
* Executes the command. When the command {@link #value is on}, all top-most block quotes within
|
28
|
+
* the selection will be removed. If it is off, all selected blocks will be wrapped with
|
29
|
+
* a block quote.
|
30
|
+
*
|
31
|
+
* @fires execute
|
32
|
+
* @param options Command options.
|
33
|
+
* @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote,
|
34
|
+
* otherwise the command will remove the block quote. If not set, the command will act basing on its current value.
|
35
|
+
*/
|
36
|
+
execute(options?: {
|
37
|
+
forceValue?: boolean;
|
38
|
+
}): void;
|
39
|
+
/**
|
40
|
+
* Checks the command's {@link #value}.
|
41
|
+
*/
|
42
|
+
private _getValue;
|
43
|
+
/**
|
44
|
+
* Checks whether the command can be enabled in the current context.
|
45
|
+
*
|
46
|
+
* @returns Whether the command should be enabled.
|
47
|
+
*/
|
48
|
+
private _checkEnabled;
|
49
|
+
/**
|
50
|
+
* Removes the quote from given blocks.
|
51
|
+
*
|
52
|
+
* If blocks which are supposed to be "unquoted" are in the middle of a quote,
|
53
|
+
* start it or end it, then the quote will be split (if needed) and the blocks
|
54
|
+
* will be moved out of it, so other quoted blocks remained quoted.
|
55
|
+
*/
|
56
|
+
private _removeQuote;
|
57
|
+
/**
|
58
|
+
* Applies the quote to given blocks.
|
59
|
+
*/
|
60
|
+
private _applyQuote;
|
61
|
+
}
|
package/src/blockquotecommand.js
CHANGED
@@ -1,172 +1,172 @@
|
|
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 block-quote/blockquotecommand
|
7
|
-
*/
|
8
|
-
import { Command } from 'ckeditor5/src/core';
|
9
|
-
import { first } from 'ckeditor5/src/utils';
|
10
|
-
/**
|
11
|
-
* The block quote command plugin.
|
12
|
-
*
|
13
|
-
* @extends module:core/command~Command
|
14
|
-
*/
|
15
|
-
export default class BlockQuoteCommand extends Command {
|
16
|
-
/**
|
17
|
-
* @inheritDoc
|
18
|
-
*/
|
19
|
-
refresh() {
|
20
|
-
this.value = this._getValue();
|
21
|
-
this.isEnabled = this._checkEnabled();
|
22
|
-
}
|
23
|
-
/**
|
24
|
-
* Executes the command. When the command {@link #value is on}, all top-most block quotes within
|
25
|
-
* the selection will be removed. If it is off, all selected blocks will be wrapped with
|
26
|
-
* a block quote.
|
27
|
-
*
|
28
|
-
* @fires execute
|
29
|
-
* @param options Command options.
|
30
|
-
* @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote,
|
31
|
-
* otherwise the command will remove the block quote. If not set, the command will act basing on its current value.
|
32
|
-
*/
|
33
|
-
execute(options = {}) {
|
34
|
-
const model = this.editor.model;
|
35
|
-
const schema = model.schema;
|
36
|
-
const selection = model.document.selection;
|
37
|
-
const blocks = Array.from(selection.getSelectedBlocks());
|
38
|
-
const value = (options.forceValue === undefined) ? !this.value : options.forceValue;
|
39
|
-
model.change(writer => {
|
40
|
-
if (!value) {
|
41
|
-
this._removeQuote(writer, blocks.filter(findQuote));
|
42
|
-
}
|
43
|
-
else {
|
44
|
-
const blocksToQuote = blocks.filter(block => {
|
45
|
-
// Already quoted blocks needs to be considered while quoting too
|
46
|
-
// in order to reuse their <bQ> elements.
|
47
|
-
return findQuote(block) || checkCanBeQuoted(schema, block);
|
48
|
-
});
|
49
|
-
this._applyQuote(writer, blocksToQuote);
|
50
|
-
}
|
51
|
-
});
|
52
|
-
}
|
53
|
-
/**
|
54
|
-
* Checks the command's {@link #value}.
|
55
|
-
*/
|
56
|
-
_getValue() {
|
57
|
-
const selection = this.editor.model.document.selection;
|
58
|
-
const firstBlock = first(selection.getSelectedBlocks());
|
59
|
-
// In the current implementation, the block quote must be an immediate parent of a block element.
|
60
|
-
return !!(firstBlock && findQuote(firstBlock));
|
61
|
-
}
|
62
|
-
/**
|
63
|
-
* Checks whether the command can be enabled in the current context.
|
64
|
-
*
|
65
|
-
* @returns Whether the command should be enabled.
|
66
|
-
*/
|
67
|
-
_checkEnabled() {
|
68
|
-
if (this.value) {
|
69
|
-
return true;
|
70
|
-
}
|
71
|
-
const selection = this.editor.model.document.selection;
|
72
|
-
const schema = this.editor.model.schema;
|
73
|
-
const firstBlock = first(selection.getSelectedBlocks());
|
74
|
-
if (!firstBlock) {
|
75
|
-
return false;
|
76
|
-
}
|
77
|
-
return checkCanBeQuoted(schema, firstBlock);
|
78
|
-
}
|
79
|
-
/**
|
80
|
-
* Removes the quote from given blocks.
|
81
|
-
*
|
82
|
-
* If blocks which are supposed to be "unquoted" are in the middle of a quote,
|
83
|
-
* start it or end it, then the quote will be split (if needed) and the blocks
|
84
|
-
* will be moved out of it, so other quoted blocks remained quoted.
|
85
|
-
*/
|
86
|
-
_removeQuote(writer, blocks) {
|
87
|
-
// Unquote all groups of block. Iterate in the reverse order to not break following ranges.
|
88
|
-
getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => {
|
89
|
-
if (groupRange.start.isAtStart && groupRange.end.isAtEnd) {
|
90
|
-
writer.unwrap(groupRange.start.parent);
|
91
|
-
return;
|
92
|
-
}
|
93
|
-
// The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).
|
94
|
-
if (groupRange.start.isAtStart) {
|
95
|
-
const positionBefore = writer.createPositionBefore(groupRange.start.parent);
|
96
|
-
writer.move(groupRange, positionBefore);
|
97
|
-
return;
|
98
|
-
}
|
99
|
-
// The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block
|
100
|
-
// so we move the items there.
|
101
|
-
if (!groupRange.end.isAtEnd) {
|
102
|
-
writer.split(groupRange.end);
|
103
|
-
}
|
104
|
-
// Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.
|
105
|
-
const positionAfter = writer.createPositionAfter(groupRange.end.parent);
|
106
|
-
writer.move(groupRange, positionAfter);
|
107
|
-
});
|
108
|
-
}
|
109
|
-
/**
|
110
|
-
* Applies the quote to given blocks.
|
111
|
-
*/
|
112
|
-
_applyQuote(writer, blocks) {
|
113
|
-
const quotesToMerge = [];
|
114
|
-
// Quote all groups of block. Iterate in the reverse order to not break following ranges.
|
115
|
-
getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => {
|
116
|
-
let quote = findQuote(groupRange.start);
|
117
|
-
if (!quote) {
|
118
|
-
quote = writer.createElement('blockQuote');
|
119
|
-
writer.wrap(groupRange, quote);
|
120
|
-
}
|
121
|
-
quotesToMerge.push(quote);
|
122
|
-
});
|
123
|
-
// Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through
|
124
|
-
// the <bQ> elements in the source order (due to how merge works – it moves the right element's content
|
125
|
-
// to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements
|
126
|
-
// we want to keep the reference to the first (furthest left) one.
|
127
|
-
quotesToMerge.reverse().reduce((currentQuote, nextQuote) => {
|
128
|
-
if (currentQuote.nextSibling == nextQuote) {
|
129
|
-
writer.merge(writer.createPositionAfter(currentQuote));
|
130
|
-
return currentQuote;
|
131
|
-
}
|
132
|
-
return nextQuote;
|
133
|
-
});
|
134
|
-
}
|
135
|
-
}
|
136
|
-
function findQuote(elementOrPosition) {
|
137
|
-
return elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null;
|
138
|
-
}
|
139
|
-
/**
|
140
|
-
* Returns a minimal array of ranges containing groups of subsequent blocks.
|
141
|
-
*
|
142
|
-
* content: abcdefgh
|
143
|
-
* blocks: [ a, b, d, f, g, h ]
|
144
|
-
* output ranges: [ab]c[d]e[fgh]
|
145
|
-
*/
|
146
|
-
function getRangesOfBlockGroups(writer, blocks) {
|
147
|
-
let startPosition;
|
148
|
-
let i = 0;
|
149
|
-
const ranges = [];
|
150
|
-
while (i < blocks.length) {
|
151
|
-
const block = blocks[i];
|
152
|
-
const nextBlock = blocks[i + 1];
|
153
|
-
if (!startPosition) {
|
154
|
-
startPosition = writer.createPositionBefore(block);
|
155
|
-
}
|
156
|
-
if (!nextBlock || block.nextSibling != nextBlock) {
|
157
|
-
ranges.push(writer.createRange(startPosition, writer.createPositionAfter(block)));
|
158
|
-
startPosition = null;
|
159
|
-
}
|
160
|
-
i++;
|
161
|
-
}
|
162
|
-
return ranges;
|
163
|
-
}
|
164
|
-
/**
|
165
|
-
* Checks whether <bQ> can wrap the block.
|
166
|
-
*/
|
167
|
-
function checkCanBeQuoted(schema, block) {
|
168
|
-
// TMP will be replaced with schema.checkWrap().
|
169
|
-
const isBQAllowed = schema.checkChild(block.parent, 'blockQuote');
|
170
|
-
const isBlockAllowedInBQ = schema.checkChild(['$root', 'blockQuote'], block);
|
171
|
-
return isBQAllowed && isBlockAllowedInBQ;
|
172
|
-
}
|
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 block-quote/blockquotecommand
|
7
|
+
*/
|
8
|
+
import { Command } from 'ckeditor5/src/core.js';
|
9
|
+
import { first } from 'ckeditor5/src/utils.js';
|
10
|
+
/**
|
11
|
+
* The block quote command plugin.
|
12
|
+
*
|
13
|
+
* @extends module:core/command~Command
|
14
|
+
*/
|
15
|
+
export default class BlockQuoteCommand extends Command {
|
16
|
+
/**
|
17
|
+
* @inheritDoc
|
18
|
+
*/
|
19
|
+
refresh() {
|
20
|
+
this.value = this._getValue();
|
21
|
+
this.isEnabled = this._checkEnabled();
|
22
|
+
}
|
23
|
+
/**
|
24
|
+
* Executes the command. When the command {@link #value is on}, all top-most block quotes within
|
25
|
+
* the selection will be removed. If it is off, all selected blocks will be wrapped with
|
26
|
+
* a block quote.
|
27
|
+
*
|
28
|
+
* @fires execute
|
29
|
+
* @param options Command options.
|
30
|
+
* @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote,
|
31
|
+
* otherwise the command will remove the block quote. If not set, the command will act basing on its current value.
|
32
|
+
*/
|
33
|
+
execute(options = {}) {
|
34
|
+
const model = this.editor.model;
|
35
|
+
const schema = model.schema;
|
36
|
+
const selection = model.document.selection;
|
37
|
+
const blocks = Array.from(selection.getSelectedBlocks());
|
38
|
+
const value = (options.forceValue === undefined) ? !this.value : options.forceValue;
|
39
|
+
model.change(writer => {
|
40
|
+
if (!value) {
|
41
|
+
this._removeQuote(writer, blocks.filter(findQuote));
|
42
|
+
}
|
43
|
+
else {
|
44
|
+
const blocksToQuote = blocks.filter(block => {
|
45
|
+
// Already quoted blocks needs to be considered while quoting too
|
46
|
+
// in order to reuse their <bQ> elements.
|
47
|
+
return findQuote(block) || checkCanBeQuoted(schema, block);
|
48
|
+
});
|
49
|
+
this._applyQuote(writer, blocksToQuote);
|
50
|
+
}
|
51
|
+
});
|
52
|
+
}
|
53
|
+
/**
|
54
|
+
* Checks the command's {@link #value}.
|
55
|
+
*/
|
56
|
+
_getValue() {
|
57
|
+
const selection = this.editor.model.document.selection;
|
58
|
+
const firstBlock = first(selection.getSelectedBlocks());
|
59
|
+
// In the current implementation, the block quote must be an immediate parent of a block element.
|
60
|
+
return !!(firstBlock && findQuote(firstBlock));
|
61
|
+
}
|
62
|
+
/**
|
63
|
+
* Checks whether the command can be enabled in the current context.
|
64
|
+
*
|
65
|
+
* @returns Whether the command should be enabled.
|
66
|
+
*/
|
67
|
+
_checkEnabled() {
|
68
|
+
if (this.value) {
|
69
|
+
return true;
|
70
|
+
}
|
71
|
+
const selection = this.editor.model.document.selection;
|
72
|
+
const schema = this.editor.model.schema;
|
73
|
+
const firstBlock = first(selection.getSelectedBlocks());
|
74
|
+
if (!firstBlock) {
|
75
|
+
return false;
|
76
|
+
}
|
77
|
+
return checkCanBeQuoted(schema, firstBlock);
|
78
|
+
}
|
79
|
+
/**
|
80
|
+
* Removes the quote from given blocks.
|
81
|
+
*
|
82
|
+
* If blocks which are supposed to be "unquoted" are in the middle of a quote,
|
83
|
+
* start it or end it, then the quote will be split (if needed) and the blocks
|
84
|
+
* will be moved out of it, so other quoted blocks remained quoted.
|
85
|
+
*/
|
86
|
+
_removeQuote(writer, blocks) {
|
87
|
+
// Unquote all groups of block. Iterate in the reverse order to not break following ranges.
|
88
|
+
getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => {
|
89
|
+
if (groupRange.start.isAtStart && groupRange.end.isAtEnd) {
|
90
|
+
writer.unwrap(groupRange.start.parent);
|
91
|
+
return;
|
92
|
+
}
|
93
|
+
// The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).
|
94
|
+
if (groupRange.start.isAtStart) {
|
95
|
+
const positionBefore = writer.createPositionBefore(groupRange.start.parent);
|
96
|
+
writer.move(groupRange, positionBefore);
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
// The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block
|
100
|
+
// so we move the items there.
|
101
|
+
if (!groupRange.end.isAtEnd) {
|
102
|
+
writer.split(groupRange.end);
|
103
|
+
}
|
104
|
+
// Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.
|
105
|
+
const positionAfter = writer.createPositionAfter(groupRange.end.parent);
|
106
|
+
writer.move(groupRange, positionAfter);
|
107
|
+
});
|
108
|
+
}
|
109
|
+
/**
|
110
|
+
* Applies the quote to given blocks.
|
111
|
+
*/
|
112
|
+
_applyQuote(writer, blocks) {
|
113
|
+
const quotesToMerge = [];
|
114
|
+
// Quote all groups of block. Iterate in the reverse order to not break following ranges.
|
115
|
+
getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => {
|
116
|
+
let quote = findQuote(groupRange.start);
|
117
|
+
if (!quote) {
|
118
|
+
quote = writer.createElement('blockQuote');
|
119
|
+
writer.wrap(groupRange, quote);
|
120
|
+
}
|
121
|
+
quotesToMerge.push(quote);
|
122
|
+
});
|
123
|
+
// Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through
|
124
|
+
// the <bQ> elements in the source order (due to how merge works – it moves the right element's content
|
125
|
+
// to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements
|
126
|
+
// we want to keep the reference to the first (furthest left) one.
|
127
|
+
quotesToMerge.reverse().reduce((currentQuote, nextQuote) => {
|
128
|
+
if (currentQuote.nextSibling == nextQuote) {
|
129
|
+
writer.merge(writer.createPositionAfter(currentQuote));
|
130
|
+
return currentQuote;
|
131
|
+
}
|
132
|
+
return nextQuote;
|
133
|
+
});
|
134
|
+
}
|
135
|
+
}
|
136
|
+
function findQuote(elementOrPosition) {
|
137
|
+
return elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null;
|
138
|
+
}
|
139
|
+
/**
|
140
|
+
* Returns a minimal array of ranges containing groups of subsequent blocks.
|
141
|
+
*
|
142
|
+
* content: abcdefgh
|
143
|
+
* blocks: [ a, b, d, f, g, h ]
|
144
|
+
* output ranges: [ab]c[d]e[fgh]
|
145
|
+
*/
|
146
|
+
function getRangesOfBlockGroups(writer, blocks) {
|
147
|
+
let startPosition;
|
148
|
+
let i = 0;
|
149
|
+
const ranges = [];
|
150
|
+
while (i < blocks.length) {
|
151
|
+
const block = blocks[i];
|
152
|
+
const nextBlock = blocks[i + 1];
|
153
|
+
if (!startPosition) {
|
154
|
+
startPosition = writer.createPositionBefore(block);
|
155
|
+
}
|
156
|
+
if (!nextBlock || block.nextSibling != nextBlock) {
|
157
|
+
ranges.push(writer.createRange(startPosition, writer.createPositionAfter(block)));
|
158
|
+
startPosition = null;
|
159
|
+
}
|
160
|
+
i++;
|
161
|
+
}
|
162
|
+
return ranges;
|
163
|
+
}
|
164
|
+
/**
|
165
|
+
* Checks whether <bQ> can wrap the block.
|
166
|
+
*/
|
167
|
+
function checkCanBeQuoted(schema, block) {
|
168
|
+
// TMP will be replaced with schema.checkWrap().
|
169
|
+
const isBQAllowed = schema.checkChild(block.parent, 'blockQuote');
|
170
|
+
const isBlockAllowedInBQ = schema.checkChild(['$root', 'blockQuote'], block);
|
171
|
+
return isBQAllowed && isBlockAllowedInBQ;
|
172
|
+
}
|
@@ -1,31 +1,31 @@
|
|
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 block-quote/blockquoteediting
|
7
|
-
*/
|
8
|
-
import { Plugin } from 'ckeditor5/src/core';
|
9
|
-
import { Enter } from 'ckeditor5/src/enter';
|
10
|
-
import { Delete } from 'ckeditor5/src/typing';
|
11
|
-
/**
|
12
|
-
* The block quote editing.
|
13
|
-
*
|
14
|
-
* Introduces the `'blockQuote'` command and the `'blockQuote'` model element.
|
15
|
-
*
|
16
|
-
* @extends module:core/plugin~Plugin
|
17
|
-
*/
|
18
|
-
export default class BlockQuoteEditing extends Plugin {
|
19
|
-
/**
|
20
|
-
* @inheritDoc
|
21
|
-
*/
|
22
|
-
static get pluginName(): "BlockQuoteEditing";
|
23
|
-
/**
|
24
|
-
* @inheritDoc
|
25
|
-
*/
|
26
|
-
static get requires(): readonly [typeof Enter, typeof Delete];
|
27
|
-
/**
|
28
|
-
* @inheritDoc
|
29
|
-
*/
|
30
|
-
init(): void;
|
31
|
-
}
|
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 block-quote/blockquoteediting
|
7
|
+
*/
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
9
|
+
import { Enter } from 'ckeditor5/src/enter.js';
|
10
|
+
import { Delete } from 'ckeditor5/src/typing.js';
|
11
|
+
/**
|
12
|
+
* The block quote editing.
|
13
|
+
*
|
14
|
+
* Introduces the `'blockQuote'` command and the `'blockQuote'` model element.
|
15
|
+
*
|
16
|
+
* @extends module:core/plugin~Plugin
|
17
|
+
*/
|
18
|
+
export default class BlockQuoteEditing extends Plugin {
|
19
|
+
/**
|
20
|
+
* @inheritDoc
|
21
|
+
*/
|
22
|
+
static get pluginName(): "BlockQuoteEditing";
|
23
|
+
/**
|
24
|
+
* @inheritDoc
|
25
|
+
*/
|
26
|
+
static get requires(): readonly [typeof Enter, typeof Delete];
|
27
|
+
/**
|
28
|
+
* @inheritDoc
|
29
|
+
*/
|
30
|
+
init(): void;
|
31
|
+
}
|
package/src/blockquoteediting.js
CHANGED
@@ -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 block-quote/blockquoteediting
|
7
|
-
*/
|
8
|
-
import { Plugin } from 'ckeditor5/src/core';
|
9
|
-
import { Enter } from 'ckeditor5/src/enter';
|
10
|
-
import { Delete } from 'ckeditor5/src/typing';
|
11
|
-
import BlockQuoteCommand from './blockquotecommand';
|
12
|
-
/**
|
13
|
-
* The block quote editing.
|
14
|
-
*
|
15
|
-
* Introduces the `'blockQuote'` command and the `'blockQuote'` model element.
|
16
|
-
*
|
17
|
-
* @extends module:core/plugin~Plugin
|
18
|
-
*/
|
19
|
-
export default class BlockQuoteEditing extends Plugin {
|
20
|
-
/**
|
21
|
-
* @inheritDoc
|
22
|
-
*/
|
23
|
-
static get pluginName() {
|
24
|
-
return 'BlockQuoteEditing';
|
25
|
-
}
|
26
|
-
/**
|
27
|
-
* @inheritDoc
|
28
|
-
*/
|
29
|
-
static get requires() {
|
30
|
-
return [Enter, Delete];
|
31
|
-
}
|
32
|
-
/**
|
33
|
-
* @inheritDoc
|
34
|
-
*/
|
35
|
-
init() {
|
36
|
-
const editor = this.editor;
|
37
|
-
const schema = editor.model.schema;
|
38
|
-
editor.commands.add('blockQuote', new BlockQuoteCommand(editor));
|
39
|
-
schema.register('blockQuote', {
|
40
|
-
inheritAllFrom: '$container'
|
41
|
-
});
|
42
|
-
editor.conversion.elementToElement({ model: 'blockQuote', view: 'blockquote' });
|
43
|
-
// Postfixer which cleans incorrect model states connected with block quotes.
|
44
|
-
editor.model.document.registerPostFixer(writer => {
|
45
|
-
const changes = editor.model.document.differ.getChanges();
|
46
|
-
for (const entry of changes) {
|
47
|
-
if (entry.type == 'insert') {
|
48
|
-
const element = entry.position.nodeAfter;
|
49
|
-
if (!element) {
|
50
|
-
// We are inside a text node.
|
51
|
-
continue;
|
52
|
-
}
|
53
|
-
if (element.is('element', 'blockQuote') && element.isEmpty) {
|
54
|
-
// Added an empty blockQuote - remove it.
|
55
|
-
writer.remove(element);
|
56
|
-
return true;
|
57
|
-
}
|
58
|
-
else if (element.is('element', 'blockQuote') && !schema.checkChild(entry.position, element)) {
|
59
|
-
// Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost.
|
60
|
-
writer.unwrap(element);
|
61
|
-
return true;
|
62
|
-
}
|
63
|
-
else if (element.is('element')) {
|
64
|
-
// Just added an element. Check that all children meet the scheme rules.
|
65
|
-
const range = writer.createRangeIn(element);
|
66
|
-
for (const child of range.getItems()) {
|
67
|
-
if (child.is('element', 'blockQuote') &&
|
68
|
-
!schema.checkChild(writer.createPositionBefore(child), child)) {
|
69
|
-
writer.unwrap(child);
|
70
|
-
return true;
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
74
|
-
}
|
75
|
-
else if (entry.type == 'remove') {
|
76
|
-
const parent = entry.position.parent;
|
77
|
-
if (parent.is('element', 'blockQuote') && parent.isEmpty) {
|
78
|
-
// Something got removed and now blockQuote is empty. Remove the blockQuote as well.
|
79
|
-
writer.remove(parent);
|
80
|
-
return true;
|
81
|
-
}
|
82
|
-
}
|
83
|
-
}
|
84
|
-
return false;
|
85
|
-
});
|
86
|
-
const viewDocument = this.editor.editing.view.document;
|
87
|
-
const selection = editor.model.document.selection;
|
88
|
-
const blockQuoteCommand = editor.commands.get('blockQuote');
|
89
|
-
// Overwrite default Enter key behavior.
|
90
|
-
// If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.
|
91
|
-
this.listenTo(viewDocument, 'enter', (evt, data) => {
|
92
|
-
if (!selection.isCollapsed || !blockQuoteCommand.value) {
|
93
|
-
return;
|
94
|
-
}
|
95
|
-
const positionParent = selection.getLastPosition().parent;
|
96
|
-
if (positionParent.isEmpty) {
|
97
|
-
editor.execute('blockQuote');
|
98
|
-
editor.editing.view.scrollToTheSelection();
|
99
|
-
data.preventDefault();
|
100
|
-
evt.stop();
|
101
|
-
}
|
102
|
-
}, { context: 'blockquote' });
|
103
|
-
// Overwrite default Backspace key behavior.
|
104
|
-
// If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote.
|
105
|
-
this.listenTo(viewDocument, 'delete', (evt, data) => {
|
106
|
-
if (data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand.value) {
|
107
|
-
return;
|
108
|
-
}
|
109
|
-
const positionParent = selection.getLastPosition().parent;
|
110
|
-
if (positionParent.isEmpty && !positionParent.previousSibling) {
|
111
|
-
editor.execute('blockQuote');
|
112
|
-
editor.editing.view.scrollToTheSelection();
|
113
|
-
data.preventDefault();
|
114
|
-
evt.stop();
|
115
|
-
}
|
116
|
-
}, { context: 'blockquote' });
|
117
|
-
}
|
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 block-quote/blockquoteediting
|
7
|
+
*/
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
9
|
+
import { Enter } from 'ckeditor5/src/enter.js';
|
10
|
+
import { Delete } from 'ckeditor5/src/typing.js';
|
11
|
+
import BlockQuoteCommand from './blockquotecommand.js';
|
12
|
+
/**
|
13
|
+
* The block quote editing.
|
14
|
+
*
|
15
|
+
* Introduces the `'blockQuote'` command and the `'blockQuote'` model element.
|
16
|
+
*
|
17
|
+
* @extends module:core/plugin~Plugin
|
18
|
+
*/
|
19
|
+
export default class BlockQuoteEditing extends Plugin {
|
20
|
+
/**
|
21
|
+
* @inheritDoc
|
22
|
+
*/
|
23
|
+
static get pluginName() {
|
24
|
+
return 'BlockQuoteEditing';
|
25
|
+
}
|
26
|
+
/**
|
27
|
+
* @inheritDoc
|
28
|
+
*/
|
29
|
+
static get requires() {
|
30
|
+
return [Enter, Delete];
|
31
|
+
}
|
32
|
+
/**
|
33
|
+
* @inheritDoc
|
34
|
+
*/
|
35
|
+
init() {
|
36
|
+
const editor = this.editor;
|
37
|
+
const schema = editor.model.schema;
|
38
|
+
editor.commands.add('blockQuote', new BlockQuoteCommand(editor));
|
39
|
+
schema.register('blockQuote', {
|
40
|
+
inheritAllFrom: '$container'
|
41
|
+
});
|
42
|
+
editor.conversion.elementToElement({ model: 'blockQuote', view: 'blockquote' });
|
43
|
+
// Postfixer which cleans incorrect model states connected with block quotes.
|
44
|
+
editor.model.document.registerPostFixer(writer => {
|
45
|
+
const changes = editor.model.document.differ.getChanges();
|
46
|
+
for (const entry of changes) {
|
47
|
+
if (entry.type == 'insert') {
|
48
|
+
const element = entry.position.nodeAfter;
|
49
|
+
if (!element) {
|
50
|
+
// We are inside a text node.
|
51
|
+
continue;
|
52
|
+
}
|
53
|
+
if (element.is('element', 'blockQuote') && element.isEmpty) {
|
54
|
+
// Added an empty blockQuote - remove it.
|
55
|
+
writer.remove(element);
|
56
|
+
return true;
|
57
|
+
}
|
58
|
+
else if (element.is('element', 'blockQuote') && !schema.checkChild(entry.position, element)) {
|
59
|
+
// Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost.
|
60
|
+
writer.unwrap(element);
|
61
|
+
return true;
|
62
|
+
}
|
63
|
+
else if (element.is('element')) {
|
64
|
+
// Just added an element. Check that all children meet the scheme rules.
|
65
|
+
const range = writer.createRangeIn(element);
|
66
|
+
for (const child of range.getItems()) {
|
67
|
+
if (child.is('element', 'blockQuote') &&
|
68
|
+
!schema.checkChild(writer.createPositionBefore(child), child)) {
|
69
|
+
writer.unwrap(child);
|
70
|
+
return true;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
else if (entry.type == 'remove') {
|
76
|
+
const parent = entry.position.parent;
|
77
|
+
if (parent.is('element', 'blockQuote') && parent.isEmpty) {
|
78
|
+
// Something got removed and now blockQuote is empty. Remove the blockQuote as well.
|
79
|
+
writer.remove(parent);
|
80
|
+
return true;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
return false;
|
85
|
+
});
|
86
|
+
const viewDocument = this.editor.editing.view.document;
|
87
|
+
const selection = editor.model.document.selection;
|
88
|
+
const blockQuoteCommand = editor.commands.get('blockQuote');
|
89
|
+
// Overwrite default Enter key behavior.
|
90
|
+
// If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.
|
91
|
+
this.listenTo(viewDocument, 'enter', (evt, data) => {
|
92
|
+
if (!selection.isCollapsed || !blockQuoteCommand.value) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
const positionParent = selection.getLastPosition().parent;
|
96
|
+
if (positionParent.isEmpty) {
|
97
|
+
editor.execute('blockQuote');
|
98
|
+
editor.editing.view.scrollToTheSelection();
|
99
|
+
data.preventDefault();
|
100
|
+
evt.stop();
|
101
|
+
}
|
102
|
+
}, { context: 'blockquote' });
|
103
|
+
// Overwrite default Backspace key behavior.
|
104
|
+
// If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote.
|
105
|
+
this.listenTo(viewDocument, 'delete', (evt, data) => {
|
106
|
+
if (data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand.value) {
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
const positionParent = selection.getLastPosition().parent;
|
110
|
+
if (positionParent.isEmpty && !positionParent.previousSibling) {
|
111
|
+
editor.execute('blockQuote');
|
112
|
+
editor.editing.view.scrollToTheSelection();
|
113
|
+
data.preventDefault();
|
114
|
+
evt.stop();
|
115
|
+
}
|
116
|
+
}, { context: 'blockquote' });
|
117
|
+
}
|
118
|
+
}
|
package/src/blockquoteui.d.ts
CHANGED
@@ -1,26 +1,26 @@
|
|
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 block-quote/blockquoteui
|
7
|
-
*/
|
8
|
-
import { Plugin } from 'ckeditor5/src/core';
|
9
|
-
import '../theme/blockquote.css';
|
10
|
-
/**
|
11
|
-
* The block quote UI plugin.
|
12
|
-
*
|
13
|
-
* It introduces the `'blockQuote'` button.
|
14
|
-
*
|
15
|
-
* @extends module:core/plugin~Plugin
|
16
|
-
*/
|
17
|
-
export default class BlockQuoteUI extends Plugin {
|
18
|
-
/**
|
19
|
-
* @inheritDoc
|
20
|
-
*/
|
21
|
-
static get pluginName(): "BlockQuoteUI";
|
22
|
-
/**
|
23
|
-
* @inheritDoc
|
24
|
-
*/
|
25
|
-
init(): void;
|
26
|
-
}
|
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 block-quote/blockquoteui
|
7
|
+
*/
|
8
|
+
import { Plugin } from 'ckeditor5/src/core.js';
|
9
|
+
import '../theme/blockquote.css';
|
10
|
+
/**
|
11
|
+
* The block quote UI plugin.
|
12
|
+
*
|
13
|
+
* It introduces the `'blockQuote'` button.
|
14
|
+
*
|
15
|
+
* @extends module:core/plugin~Plugin
|
16
|
+
*/
|
17
|
+
export default class BlockQuoteUI extends Plugin {
|
18
|
+
/**
|
19
|
+
* @inheritDoc
|
20
|
+
*/
|
21
|
+
static get pluginName(): "BlockQuoteUI";
|
22
|
+
/**
|
23
|
+
* @inheritDoc
|
24
|
+
*/
|
25
|
+
init(): void;
|
26
|
+
}
|
package/src/blockquoteui.js
CHANGED
@@ -1,50 +1,50 @@
|
|
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 block-quote/blockquoteui
|
7
|
-
*/
|
8
|
-
import { Plugin, icons } from 'ckeditor5/src/core';
|
9
|
-
import { ButtonView } from 'ckeditor5/src/ui';
|
10
|
-
import '../theme/blockquote.css';
|
11
|
-
/**
|
12
|
-
* The block quote UI plugin.
|
13
|
-
*
|
14
|
-
* It introduces the `'blockQuote'` button.
|
15
|
-
*
|
16
|
-
* @extends module:core/plugin~Plugin
|
17
|
-
*/
|
18
|
-
export default class BlockQuoteUI extends Plugin {
|
19
|
-
/**
|
20
|
-
* @inheritDoc
|
21
|
-
*/
|
22
|
-
static get pluginName() {
|
23
|
-
return 'BlockQuoteUI';
|
24
|
-
}
|
25
|
-
/**
|
26
|
-
* @inheritDoc
|
27
|
-
*/
|
28
|
-
init() {
|
29
|
-
const editor = this.editor;
|
30
|
-
const t = editor.t;
|
31
|
-
editor.ui.componentFactory.add('blockQuote', locale => {
|
32
|
-
const command = editor.commands.get('blockQuote');
|
33
|
-
const buttonView = new ButtonView(locale);
|
34
|
-
buttonView.set({
|
35
|
-
label: t('Block quote'),
|
36
|
-
icon: icons.quote,
|
37
|
-
tooltip: true,
|
38
|
-
isToggleable: true
|
39
|
-
});
|
40
|
-
// Bind button model to command.
|
41
|
-
buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');
|
42
|
-
// Execute command.
|
43
|
-
this.listenTo(buttonView, 'execute', () => {
|
44
|
-
editor.execute('blockQuote');
|
45
|
-
editor.editing.view.focus();
|
46
|
-
});
|
47
|
-
return buttonView;
|
48
|
-
});
|
49
|
-
}
|
50
|
-
}
|
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 block-quote/blockquoteui
|
7
|
+
*/
|
8
|
+
import { Plugin, icons } from 'ckeditor5/src/core.js';
|
9
|
+
import { ButtonView } from 'ckeditor5/src/ui.js';
|
10
|
+
import '../theme/blockquote.css';
|
11
|
+
/**
|
12
|
+
* The block quote UI plugin.
|
13
|
+
*
|
14
|
+
* It introduces the `'blockQuote'` button.
|
15
|
+
*
|
16
|
+
* @extends module:core/plugin~Plugin
|
17
|
+
*/
|
18
|
+
export default class BlockQuoteUI extends Plugin {
|
19
|
+
/**
|
20
|
+
* @inheritDoc
|
21
|
+
*/
|
22
|
+
static get pluginName() {
|
23
|
+
return 'BlockQuoteUI';
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* @inheritDoc
|
27
|
+
*/
|
28
|
+
init() {
|
29
|
+
const editor = this.editor;
|
30
|
+
const t = editor.t;
|
31
|
+
editor.ui.componentFactory.add('blockQuote', locale => {
|
32
|
+
const command = editor.commands.get('blockQuote');
|
33
|
+
const buttonView = new ButtonView(locale);
|
34
|
+
buttonView.set({
|
35
|
+
label: t('Block quote'),
|
36
|
+
icon: icons.quote,
|
37
|
+
tooltip: true,
|
38
|
+
isToggleable: true
|
39
|
+
});
|
40
|
+
// Bind button model to command.
|
41
|
+
buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');
|
42
|
+
// Execute command.
|
43
|
+
this.listenTo(buttonView, 'execute', () => {
|
44
|
+
editor.execute('blockQuote');
|
45
|
+
editor.editing.view.focus();
|
46
|
+
});
|
47
|
+
return buttonView;
|
48
|
+
});
|
49
|
+
}
|
50
|
+
}
|
package/src/index.d.ts
CHANGED
@@ -1,12 +1,12 @@
|
|
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 block-quote
|
7
|
-
*/
|
8
|
-
export { default as BlockQuote } from './blockquote';
|
9
|
-
export { default as BlockQuoteEditing } from './blockquoteediting';
|
10
|
-
export { default as BlockQuoteUI } from './blockquoteui';
|
11
|
-
export type { default as BlockQuoteCommand } from './blockquotecommand';
|
12
|
-
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 block-quote
|
7
|
+
*/
|
8
|
+
export { default as BlockQuote } from './blockquote.js';
|
9
|
+
export { default as BlockQuoteEditing } from './blockquoteediting.js';
|
10
|
+
export { default as BlockQuoteUI } from './blockquoteui.js';
|
11
|
+
export type { default as BlockQuoteCommand } from './blockquotecommand.js';
|
12
|
+
import './augmentation.js';
|
package/src/index.js
CHANGED
@@ -1,11 +1,11 @@
|
|
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 block-quote
|
7
|
-
*/
|
8
|
-
export { default as BlockQuote } from './blockquote';
|
9
|
-
export { default as BlockQuoteEditing } from './blockquoteediting';
|
10
|
-
export { default as BlockQuoteUI } from './blockquoteui';
|
11
|
-
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 block-quote
|
7
|
+
*/
|
8
|
+
export { default as BlockQuote } from './blockquote.js';
|
9
|
+
export { default as BlockQuoteEditing } from './blockquoteediting.js';
|
10
|
+
export { default as BlockQuoteUI } from './blockquoteui.js';
|
11
|
+
import './augmentation.js';
|
package/build/block-quote.js.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["webpack://CKEditor5.blockQuote/./theme/blockquote.css","webpack://CKEditor5.blockQuote/../node_modules/css-loader/dist/runtime/api.js","webpack://CKEditor5.blockQuote/../node_modules/css-loader/dist/runtime/cssWithMappingToString.js","webpack://CKEditor5.blockQuote/./theme/blockquote.css?f62a","webpack://CKEditor5.blockQuote/../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack://CKEditor5.blockQuote/./src/blockquote.js","webpack://CKEditor5.blockQuote/./src/blockquotecommand.js","webpack://CKEditor5.blockQuote/./src/blockquoteediting.js","webpack://CKEditor5.blockQuote/./src/blockquoteui.js","webpack://CKEditor5.blockQuote/delegated \"./src/core.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.blockQuote/delegated \"./src/enter.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.blockQuote/delegated \"./src/typing.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.blockQuote/delegated \"./src/ui.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.blockQuote/delegated \"./src/utils.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.blockQuote/external var \"CKEditor5.dll\"","webpack://CKEditor5.blockQuote/webpack/bootstrap","webpack://CKEditor5.blockQuote/webpack/runtime/compat get default export","webpack://CKEditor5.blockQuote/webpack/runtime/define property getters","webpack://CKEditor5.blockQuote/webpack/runtime/hasOwnProperty shorthand","webpack://CKEditor5.blockQuote/webpack/runtime/make namespace object","webpack://CKEditor5.blockQuote/webpack/runtime/nonce","webpack://CKEditor5.blockQuote/./src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,iEAAiE,2BAA2B,kBAAkB,cAAc,eAAe,gBAAgB,mBAAmB,oBAAoB,gCAAgC,cAAc,4BAA4B,OAAO,+ZAA+Z,sCAAsC,gGAAgG,wBAAwB,qBAAqB,oBAAoB,uBAAuB,2CAA2C,GAAG,yCAAyC,mBAAmB,4CAA4C,GAAG,qBAAqB;AAC9jC;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;ACP1B;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;;AAEA;AACA,4CAA4C,qBAAqB;AACjE;;AAEA;AACA,KAAK;AACL,KAAK;AACL;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,sBAAsB,iBAAiB;AACvC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,qBAAqB,qBAAqB;AAC1C;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;ACjEa;;AAEb,kCAAkC;;AAElC,8BAA8B;;AAE9B,kDAAkD,gBAAgB,gEAAgE,wDAAwD,6DAA6D,sDAAsD;;AAE7S,uCAAuC,uDAAuD,uCAAuC,SAAS,OAAO,oBAAoB;;AAEzK,yCAAyC,8FAA8F,wBAAwB,eAAe,eAAe,gBAAgB,YAAY,MAAM,wBAAwB,+BAA+B,aAAa,qBAAqB,uCAAuC,cAAc,WAAW,YAAY,UAAU,MAAM,mDAAmD,UAAU,sBAAsB;;AAEve,gCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,uDAAuD,cAAc;AACrE;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACnC+F;AAC/F,YAA+K;;AAE/K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,2JAAO;;;;AAIxB,iEAAe,kKAAc,MAAM;;;;;;;;;;;ACZtB;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,wDAAwD;;AAExD;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;;AAEA,kBAAkB,wBAAwB;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,kBAAkB,iBAAiB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,gBAAgB,KAAwC,GAAG,sBAAiB,GAAG,CAAI;;AAEnF;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,qEAAqE,qBAAqB,cAAc;;AAExG;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA,yDAAyD;AACzD,IAAI;;AAEJ;;;AAGA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA,2BAA2B;AAC3B;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAoB,4BAA4B;AAChD;AACA;AACA;AACA;;AAEA;;AAEA,qBAAqB,6BAA6B;AAClD;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC5QA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAEQ;AACV;;AAE1C;AACA;AACA;AACA,sDAAsD,oCAAoC;AAC1F;AACA,4CAA4C;AAC5C,QAAQ,0EAA0E;AAClF;AACA;AACA;AACe,yBAAyB,sDAAM;AAC9C;AACA;AACA;AACA;AACA,WAAW,0DAAiB,EAAE,qDAAY;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACtCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;;AAE5C;AACA;AACA;AACA;AACA;AACe,gCAAgC,uDAAO;AACtD;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4CAA4C,mBAAmB;AAC/D;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA,uBAAuB;AACvB;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA,qBAAqB,0DAAK;;AAE1B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qBAAqB,0DAAK;;AAE1B;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C,YAAY,6CAA6C;AACzD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C,YAAY,6CAA6C;AACzD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,6CAA6C;AACxD,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;ACvOA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACA;AACE;;AAEM;;AAEpD;AACA;AACA;AACA;AACA;AACA;AACA;AACe,gCAAgC,sDAAM;AACrD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,sDAAK,EAAE,wDAAM;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,yCAAyC,0DAAiB;;AAE1D;AACA;AACA,IAAI;;AAEJ,wCAAwC,0CAA0C;;AAElF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,OAAO;AACP;AACA;;AAEA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG,IAAI,wBAAwB;;AAE/B;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG,IAAI,wBAAwB;AAC/B;AACA;;;;;;;;;;;;;;;;;;;ACjJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEmD;AACL;;AAEb;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA;AACe,2BAA2B,sDAAM;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,0BAA0B,wDAAU;;AAEpC;AACA;AACA,UAAU,2DAAW;AACrB;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,IAAI;AACJ;AACA;;;;;;;;;;;AC3DA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCtBA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;WCNA;;;;;;;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEqD;AACc;AACV","file":"block-quote.js","sourcesContent":["// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck-content blockquote{border-left:5px solid #ccc;font-style:italic;margin-left:0;margin-right:0;overflow:hidden;padding-left:1.5em;padding-right:1.5em}.ck-content[dir=rtl] blockquote{border-left:0;border-right:5px solid #ccc}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/blockquote.css\"],\"names\":[],\"mappings\":\"AAKA,uBAWC,0BAAsC,CADtC,iBAAkB,CAFlB,aAAc,CACd,cAAe,CAPf,eAAgB,CAIhB,kBAAmB,CADnB,mBAOD,CAEA,gCACC,aAAc,CACd,2BACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck-content blockquote {\\n\\t/* See #12 */\\n\\toverflow: hidden;\\n\\n\\t/* https://github.com/ckeditor/ckeditor5-block-quote/issues/15 */\\n\\tpadding-right: 1.5em;\\n\\tpadding-left: 1.5em;\\n\\n\\tmargin-left: 0;\\n\\tmargin-right: 0;\\n\\tfont-style: italic;\\n\\tborder-left: solid 5px hsl(0, 0%, 80%);\\n}\\n\\n.ck-content[dir=\\\"rtl\\\"] blockquote {\\n\\tborder-left: 0;\\n\\tborder-right: solid 5px hsl(0, 0%, 80%);\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (cssWithMappingToString) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join(\"\");\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === \"string\") {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, \"\"]];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};","\"use strict\";\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr && (typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]); if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nmodule.exports = function cssWithMappingToString(item) {\n var _item = _slicedToArray(item, 4),\n content = _item[1],\n cssMapping = _item[3];\n\n if (!cssMapping) {\n return content;\n }\n\n if (typeof btoa === \"function\") {\n // eslint-disable-next-line no-undef\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n var sourceURLs = cssMapping.sources.map(function (source) {\n return \"/*# sourceURL=\".concat(cssMapping.sourceRoot || \"\").concat(source, \" */\");\n });\n return [content].concat(sourceURLs).concat([sourceMapping]).join(\"\\n\");\n }\n\n return [content].join(\"\\n\");\n};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./blockquote.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","\"use strict\";\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n var attributes = options.attributes || {};\n\n if (typeof attributes.nonce === 'undefined') {\n var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;\n\n if (nonce) {\n attributes.nonce = nonce;\n }\n }\n\n Object.keys(attributes).forEach(function (key) {\n style.setAttribute(key, attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n } else {\n style.removeAttribute('media');\n }\n\n if (sourceMap && typeof btoa !== 'undefined') {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n // tags it will allow on a page\n\n if (!options.singleton && typeof options.singleton !== 'boolean') {\n options.singleton = isOldIE();\n }\n\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n if (Object.prototype.toString.call(newList) !== '[object Array]') {\n return;\n }\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDom[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDom[_index].references === 0) {\n stylesInDom[_index].updater();\n\n stylesInDom.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquote\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport BlockQuoteEditing from './blockquoteediting';\nimport BlockQuoteUI from './blockquoteui';\n\n/**\n * The block quote plugin.\n *\n * For more information about this feature check the {@glink api/block-quote package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}\n * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuote extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ BlockQuoteEditing, BlockQuoteUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'BlockQuote';\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquotecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\n\n/**\n * The block quote command plugin.\n *\n * @extends module:core/command~Command\n */\nexport default class BlockQuoteCommand extends Command {\n\t/**\n\t * Whether the selection starts in a block quote.\n\t *\n\t * @observable\n\t * @readonly\n\t * @member {Boolean} #value\n\t */\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command. When the command {@link #value is on}, all top-most block quotes within\n\t * the selection will be removed. If it is off, all selected blocks will be wrapped with\n\t * a block quote.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Command options.\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will apply a block quote,\n\t * otherwise the command will remove the block quote. If not set, the command will act basing on its current value.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( !value ) {\n\t\t\t\tthis._removeQuote( writer, blocks.filter( findQuote ) );\n\t\t\t} else {\n\t\t\t\tconst blocksToQuote = blocks.filter( block => {\n\t\t\t\t\t// Already quoted blocks needs to be considered while quoting too\n\t\t\t\t\t// in order to reuse their <bQ> elements.\n\t\t\t\t\treturn findQuote( block ) || checkCanBeQuoted( schema, block );\n\t\t\t\t} );\n\n\t\t\t\tthis._applyQuote( writer, blocksToQuote );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\tconst selection = this.editor.model.document.selection;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\t// In the current implementation, the block quote must be an immediate parent of a block element.\n\t\treturn !!( firstBlock && findQuote( firstBlock ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn checkCanBeQuoted( schema, firstBlock );\n\t}\n\n\t/**\n\t * Removes the quote from given blocks.\n\t *\n\t * If blocks which are supposed to be \"unquoted\" are in the middle of a quote,\n\t * start it or end it, then the quote will be split (if needed) and the blocks\n\t * will be moved out of it, so other quoted blocks remained quoted.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer\n\t * @param {Array.<module:engine/model/element~Element>} blocks\n\t */\n\t_removeQuote( writer, blocks ) {\n\t\t// Unquote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => {\n\t\t\tif ( groupRange.start.isAtStart && groupRange.end.isAtEnd ) {\n\t\t\t\twriter.unwrap( groupRange.start.parent );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).\n\t\t\tif ( groupRange.start.isAtStart ) {\n\t\t\t\tconst positionBefore = writer.createPositionBefore( groupRange.start.parent );\n\n\t\t\t\twriter.move( groupRange, positionBefore );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block\n\t\t\t// so we move the items there.\n\t\t\tif ( !groupRange.end.isAtEnd ) {\n\t\t\t\twriter.split( groupRange.end );\n\t\t\t}\n\n\t\t\t// Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.\n\n\t\t\tconst positionAfter = writer.createPositionAfter( groupRange.end.parent );\n\n\t\t\twriter.move( groupRange, positionAfter );\n\t\t} );\n\t}\n\n\t/**\n\t * Applies the quote to given blocks.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer\n\t * @param {Array.<module:engine/model/element~Element>} blocks\n\t */\n\t_applyQuote( writer, blocks ) {\n\t\tconst quotesToMerge = [];\n\n\t\t// Quote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => {\n\t\t\tlet quote = findQuote( groupRange.start );\n\n\t\t\tif ( !quote ) {\n\t\t\t\tquote = writer.createElement( 'blockQuote' );\n\n\t\t\t\twriter.wrap( groupRange, quote );\n\t\t\t}\n\n\t\t\tquotesToMerge.push( quote );\n\t\t} );\n\n\t\t// Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through\n\t\t// the <bQ> elements in the source order (due to how merge works – it moves the right element's content\n\t\t// to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements\n\t\t// we want to keep the reference to the first (furthest left) one.\n\t\tquotesToMerge.reverse().reduce( ( currentQuote, nextQuote ) => {\n\t\t\tif ( currentQuote.nextSibling == nextQuote ) {\n\t\t\t\twriter.merge( writer.createPositionAfter( currentQuote ) );\n\n\t\t\t\treturn currentQuote;\n\t\t\t}\n\n\t\t\treturn nextQuote;\n\t\t} );\n\t}\n}\n\nfunction findQuote( elementOrPosition ) {\n\treturn elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null;\n}\n\n// Returns a minimal array of ranges containing groups of subsequent blocks.\n//\n// content: abcdefgh\n// blocks: [ a, b, d, f, g, h ]\n// output ranges: [ab]c[d]e[fgh]\n//\n// @param {Array.<module:engine/model/element~Element>} blocks\n// @returns {Array.<module:engine/model/range~Range>}\nfunction getRangesOfBlockGroups( writer, blocks ) {\n\tlet startPosition;\n\tlet i = 0;\n\tconst ranges = [];\n\n\twhile ( i < blocks.length ) {\n\t\tconst block = blocks[ i ];\n\t\tconst nextBlock = blocks[ i + 1 ];\n\n\t\tif ( !startPosition ) {\n\t\t\tstartPosition = writer.createPositionBefore( block );\n\t\t}\n\n\t\tif ( !nextBlock || block.nextSibling != nextBlock ) {\n\t\t\tranges.push( writer.createRange( startPosition, writer.createPositionAfter( block ) ) );\n\t\t\tstartPosition = null;\n\t\t}\n\n\t\ti++;\n\t}\n\n\treturn ranges;\n}\n\n// Checks whether <bQ> can wrap the block.\nfunction checkCanBeQuoted( schema, block ) {\n\t// TMP will be replaced with schema.checkWrap().\n\tconst isBQAllowed = schema.checkChild( block.parent, 'blockQuote' );\n\tconst isBlockAllowedInBQ = schema.checkChild( [ '$root', 'blockQuote' ], block );\n\n\treturn isBQAllowed && isBlockAllowedInBQ;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquoteediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Enter } from 'ckeditor5/src/enter';\nimport { Delete } from 'ckeditor5/src/typing';\n\nimport BlockQuoteCommand from './blockquotecommand';\n\n/**\n * The block quote editing.\n *\n * Introduces the `'blockQuote'` command and the `'blockQuote'` model element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuoteEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'BlockQuoteEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Enter, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\teditor.commands.add( 'blockQuote', new BlockQuoteCommand( editor ) );\n\n\t\tschema.register( 'blockQuote', {\n\t\t\tinheritAllFrom: '$container'\n\t\t} );\n\n\t\teditor.conversion.elementToElement( { model: 'blockQuote', view: 'blockquote' } );\n\n\t\t// Postfixer which cleans incorrect model states connected with block quotes.\n\t\teditor.model.document.registerPostFixer( writer => {\n\t\t\tconst changes = editor.model.document.differ.getChanges();\n\n\t\t\tfor ( const entry of changes ) {\n\t\t\t\tif ( entry.type == 'insert' ) {\n\t\t\t\t\tconst element = entry.position.nodeAfter;\n\n\t\t\t\t\tif ( !element ) {\n\t\t\t\t\t\t// We are inside a text node.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( element.is( 'element', 'blockQuote' ) && element.isEmpty ) {\n\t\t\t\t\t\t// Added an empty blockQuote - remove it.\n\t\t\t\t\t\twriter.remove( element );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else if ( element.is( 'element', 'blockQuote' ) && !schema.checkChild( entry.position, element ) ) {\n\t\t\t\t\t\t// Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost.\n\t\t\t\t\t\twriter.unwrap( element );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else if ( element.is( 'element' ) ) {\n\t\t\t\t\t\t// Just added an element. Check that all children meet the scheme rules.\n\t\t\t\t\t\tconst range = writer.createRangeIn( element );\n\n\t\t\t\t\t\tfor ( const child of range.getItems() ) {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tchild.is( 'element', 'blockQuote' ) &&\n\t\t\t\t\t\t\t\t!schema.checkChild( writer.createPositionBefore( child ), child )\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\twriter.unwrap( child );\n\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if ( entry.type == 'remove' ) {\n\t\t\t\t\tconst parent = entry.position.parent;\n\n\t\t\t\t\tif ( parent.is( 'element', 'blockQuote' ) && parent.isEmpty ) {\n\t\t\t\t\t\t// Something got removed and now blockQuote is empty. Remove the blockQuote as well.\n\t\t\t\t\t\twriter.remove( parent );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t} );\n\n\t\tconst viewDocument = this.editor.editing.view.document;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst blockQuoteCommand = editor.commands.get( 'blockQuote' );\n\n\t\t// Overwrite default Enter key behavior.\n\t\t// If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.\n\t\tthis.listenTo( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tif ( !selection.isCollapsed || !blockQuoteCommand.value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = selection.getLastPosition().parent;\n\n\t\t\tif ( positionParent.isEmpty ) {\n\t\t\t\teditor.execute( 'blockQuote' );\n\t\t\t\teditor.editing.view.scrollToTheSelection();\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'blockquote' } );\n\n\t\t// Overwrite default Backspace key behavior.\n\t\t// If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote.\n\t\tthis.listenTo( viewDocument, 'delete', ( evt, data ) => {\n\t\t\tif ( data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand.value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = selection.getLastPosition().parent;\n\n\t\t\tif ( positionParent.isEmpty && !positionParent.previousSibling ) {\n\t\t\t\teditor.execute( 'blockQuote' );\n\t\t\t\teditor.editing.view.scrollToTheSelection();\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'blockquote' } );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquoteui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core';\nimport { ButtonView } from 'ckeditor5/src/ui';\n\nimport '../theme/blockquote.css';\n\n/**\n * The block quote UI plugin.\n *\n * It introduces the `'blockQuote'` button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuoteUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'BlockQuoteUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'blockQuote', locale => {\n\t\t\tconst command = editor.commands.get( 'blockQuote' );\n\t\t\tconst buttonView = new ButtonView( locale );\n\n\t\t\tbuttonView.set( {\n\t\t\t\tlabel: t( 'Block quote' ),\n\t\t\t\ticon: icons.quote,\n\t\t\t\ttooltip: true,\n\t\t\t\tisToggleable: true\n\t\t\t} );\n\n\t\t\t// Bind button model to command.\n\t\t\tbuttonView.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );\n\n\t\t\t// Execute command.\n\t\t\tthis.listenTo( buttonView, 'execute', () => {\n\t\t\t\teditor.execute( 'blockQuote' );\n\t\t\t\teditor.editing.view.focus();\n\t\t\t} );\n\n\t\t\treturn buttonView;\n\t\t} );\n\t}\n}\n","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/core.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/enter.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/typing.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/ui.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/utils.js\");","module.exports = CKEditor5.dll;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nc = undefined;","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote\n */\n\nexport { default as BlockQuote } from './blockquote';\nexport { default as BlockQuoteEditing } from './blockquoteediting';\nexport { default as BlockQuoteUI } from './blockquoteui';\n"],"sourceRoot":""}
|