@ckeditor/ckeditor5-block-quote 48.2.0-alpha.7 → 48.3.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2,377 +2,367 @@
2
2
  * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
- import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
6
- import { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';
7
- import { Delete } from '@ckeditor/ckeditor5-typing/dist/index.js';
8
- import { first } from '@ckeditor/ckeditor5-utils/dist/index.js';
9
- import { IconQuote } from '@ckeditor/ckeditor5-icons/dist/index.js';
10
- import { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
5
+ import { Command, Plugin } from "@ckeditor/ckeditor5-core";
6
+ import { Enter } from "@ckeditor/ckeditor5-enter";
7
+ import { Delete } from "@ckeditor/ckeditor5-typing";
8
+ import { first } from "@ckeditor/ckeditor5-utils";
9
+ import { IconQuote } from "@ckeditor/ckeditor5-icons";
10
+ import { ButtonView, MenuBarMenuListItemButtonView } from "@ckeditor/ckeditor5-ui";
11
11
 
12
12
  /**
13
- * The block quote command plugin.
14
- *
15
- * @extends module:core/command~Command
16
- */ class BlockQuoteCommand extends Command {
17
- /**
18
- * @inheritDoc
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
- */ execute(options = {}) {
33
- const model = this.editor.model;
34
- const schema = model.schema;
35
- const selection = model.document.selection;
36
- const blocks = Array.from(selection.getSelectedBlocks());
37
- const value = options.forceValue === undefined ? !this.value : options.forceValue;
38
- model.change((writer)=>{
39
- if (!value) {
40
- this._removeQuote(writer, blocks.filter(findQuote));
41
- } else {
42
- const blocksToQuote = blocks.filter((block)=>{
43
- // Already quoted blocks needs to be considered while quoting too
44
- // in order to reuse their <bQ> elements.
45
- return findQuote(block) || checkCanBeQuoted(schema, block);
46
- });
47
- this._applyQuote(writer, blocksToQuote);
48
- }
49
- });
50
- }
51
- /**
52
- * Checks the command's {@link #value}.
53
- */ _getValue() {
54
- const selection = this.editor.model.document.selection;
55
- const firstBlock = first(selection.getSelectedBlocks());
56
- // In the current implementation, the block quote must be an immediate parent of a block element.
57
- return !!(firstBlock && findQuote(firstBlock));
58
- }
59
- /**
60
- * Checks whether the command can be enabled in the current context.
61
- *
62
- * @returns Whether the command should be enabled.
63
- */ _checkEnabled() {
64
- if (this.value) {
65
- return true;
66
- }
67
- const selection = this.editor.model.document.selection;
68
- const schema = this.editor.model.schema;
69
- const firstBlock = first(selection.getSelectedBlocks());
70
- if (!firstBlock) {
71
- return false;
72
- }
73
- return checkCanBeQuoted(schema, firstBlock);
74
- }
75
- /**
76
- * Removes the quote from given blocks.
77
- *
78
- * If blocks which are supposed to be "unquoted" are in the middle of a quote,
79
- * start it or end it, then the quote will be split (if needed) and the blocks
80
- * will be moved out of it, so other quoted blocks remained quoted.
81
- */ _removeQuote(writer, blocks) {
82
- // Unquote all groups of block. Iterate in the reverse order to not break following ranges.
83
- getRangesOfBlockGroups(writer, blocks).reverse().forEach((groupRange)=>{
84
- if (groupRange.start.isAtStart && groupRange.end.isAtEnd) {
85
- writer.unwrap(groupRange.start.parent);
86
- return;
87
- }
88
- // The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).
89
- if (groupRange.start.isAtStart) {
90
- const positionBefore = writer.createPositionBefore(groupRange.start.parent);
91
- writer.move(groupRange, positionBefore);
92
- return;
93
- }
94
- // The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block
95
- // so we move the items there.
96
- if (!groupRange.end.isAtEnd) {
97
- writer.split(groupRange.end);
98
- }
99
- // Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.
100
- const positionAfter = writer.createPositionAfter(groupRange.end.parent);
101
- writer.move(groupRange, positionAfter);
102
- });
103
- }
104
- /**
105
- * Applies the quote to given blocks.
106
- */ _applyQuote(writer, blocks) {
107
- const quotesToMerge = [];
108
- // Quote all groups of block. Iterate in the reverse order to not break following ranges.
109
- getRangesOfBlockGroups(writer, blocks).reverse().forEach((groupRange)=>{
110
- let quote = findQuote(groupRange.start);
111
- if (!quote) {
112
- quote = writer.createElement('blockQuote');
113
- writer.wrap(groupRange, quote);
114
- }
115
- quotesToMerge.push(quote);
116
- });
117
- // Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through
118
- // the <bQ> elements in the source order (due to how merge works – it moves the right element's content
119
- // to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements
120
- // we want to keep the reference to the first (furthest left) one.
121
- quotesToMerge.reverse().reduce((currentQuote, nextQuote)=>{
122
- if (currentQuote.nextSibling == nextQuote) {
123
- writer.merge(writer.createPositionAfter(currentQuote));
124
- return currentQuote;
125
- }
126
- return nextQuote;
127
- });
128
- }
129
- }
13
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
14
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
15
+ */
16
+ /**
17
+ * @module block-quote/blockquotecommand
18
+ */
19
+ /**
20
+ * The block quote command plugin.
21
+ *
22
+ * @extends module:core/command~Command
23
+ */
24
+ var BlockQuoteCommand = class extends Command {
25
+ /**
26
+ * @inheritDoc
27
+ */
28
+ refresh() {
29
+ this.value = this._getValue();
30
+ this.isEnabled = this._checkEnabled();
31
+ }
32
+ /**
33
+ * Executes the command. When the command {@link #value is on}, all top-most block quotes within
34
+ * the selection will be removed. If it is off, all selected blocks will be wrapped with
35
+ * a block quote.
36
+ *
37
+ * @fires execute
38
+ * @param options Command options.
39
+ * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote,
40
+ * otherwise the command will remove the block quote. If not set, the command will act basing on its current value.
41
+ */
42
+ execute(options = {}) {
43
+ const model = this.editor.model;
44
+ const schema = model.schema;
45
+ const selection = model.document.selection;
46
+ const blocks = Array.from(selection.getSelectedBlocks());
47
+ const value = options.forceValue === void 0 ? !this.value : options.forceValue;
48
+ model.change((writer) => {
49
+ if (!value) this._removeQuote(writer, blocks.filter(findQuote));
50
+ else {
51
+ const blocksToQuote = blocks.filter((block) => {
52
+ return findQuote(block) || checkCanBeQuoted(schema, block);
53
+ });
54
+ this._applyQuote(writer, blocksToQuote);
55
+ }
56
+ });
57
+ }
58
+ /**
59
+ * Checks the command's {@link #value}.
60
+ */
61
+ _getValue() {
62
+ const selection = this.editor.model.document.selection;
63
+ const firstBlock = first(selection.getSelectedBlocks());
64
+ return !!(firstBlock && findQuote(firstBlock));
65
+ }
66
+ /**
67
+ * Checks whether the command can be enabled in the current context.
68
+ *
69
+ * @returns Whether the command should be enabled.
70
+ */
71
+ _checkEnabled() {
72
+ if (this.value) return true;
73
+ const selection = this.editor.model.document.selection;
74
+ const schema = this.editor.model.schema;
75
+ const firstBlock = first(selection.getSelectedBlocks());
76
+ if (!firstBlock) return false;
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
+ getRangesOfBlockGroups(writer, blocks).reverse().forEach((groupRange) => {
88
+ if (groupRange.start.isAtStart && groupRange.end.isAtEnd) {
89
+ writer.unwrap(groupRange.start.parent);
90
+ return;
91
+ }
92
+ if (groupRange.start.isAtStart) {
93
+ const positionBefore = writer.createPositionBefore(groupRange.start.parent);
94
+ writer.move(groupRange, positionBefore);
95
+ return;
96
+ }
97
+ if (!groupRange.end.isAtEnd) writer.split(groupRange.end);
98
+ const positionAfter = writer.createPositionAfter(groupRange.end.parent);
99
+ writer.move(groupRange, positionAfter);
100
+ });
101
+ }
102
+ /**
103
+ * Applies the quote to given blocks.
104
+ */
105
+ _applyQuote(writer, blocks) {
106
+ const quotesToMerge = [];
107
+ getRangesOfBlockGroups(writer, blocks).reverse().forEach((groupRange) => {
108
+ let quote = findQuote(groupRange.start);
109
+ if (!quote) {
110
+ quote = writer.createElement("blockQuote");
111
+ writer.wrap(groupRange, quote);
112
+ }
113
+ quotesToMerge.push(quote);
114
+ });
115
+ quotesToMerge.reverse().reduce((currentQuote, nextQuote) => {
116
+ if (currentQuote.nextSibling == nextQuote) {
117
+ writer.merge(writer.createPositionAfter(currentQuote));
118
+ return currentQuote;
119
+ }
120
+ return nextQuote;
121
+ });
122
+ }
123
+ };
130
124
  function findQuote(elementOrPosition) {
131
- return elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null;
125
+ return elementOrPosition.parent.name == "blockQuote" ? elementOrPosition.parent : null;
132
126
  }
133
127
  /**
134
- * Returns a minimal array of ranges containing groups of subsequent blocks.
135
- *
136
- * content: abcdefgh
137
- * blocks: [ a, b, d, f, g, h ]
138
- * output ranges: [ab]c[d]e[fgh]
139
- */ function getRangesOfBlockGroups(writer, blocks) {
140
- let startPosition;
141
- let i = 0;
142
- const ranges = [];
143
- while(i < blocks.length){
144
- const block = blocks[i];
145
- const nextBlock = blocks[i + 1];
146
- if (!startPosition) {
147
- startPosition = writer.createPositionBefore(block);
148
- }
149
- if (!nextBlock || block.nextSibling != nextBlock) {
150
- ranges.push(writer.createRange(startPosition, writer.createPositionAfter(block)));
151
- startPosition = null;
152
- }
153
- i++;
154
- }
155
- return ranges;
128
+ * Returns a minimal array of ranges containing groups of subsequent blocks.
129
+ *
130
+ * content: abcdefgh
131
+ * blocks: [ a, b, d, f, g, h ]
132
+ * output ranges: [ab]c[d]e[fgh]
133
+ */
134
+ function getRangesOfBlockGroups(writer, blocks) {
135
+ let startPosition;
136
+ let i = 0;
137
+ const ranges = [];
138
+ while (i < blocks.length) {
139
+ const block = blocks[i];
140
+ const nextBlock = blocks[i + 1];
141
+ if (!startPosition) startPosition = writer.createPositionBefore(block);
142
+ if (!nextBlock || block.nextSibling != nextBlock) {
143
+ ranges.push(writer.createRange(startPosition, writer.createPositionAfter(block)));
144
+ startPosition = null;
145
+ }
146
+ i++;
147
+ }
148
+ return ranges;
156
149
  }
157
150
  /**
158
- * Checks whether <bQ> can wrap the block.
159
- */ function checkCanBeQuoted(schema, block) {
160
- // TMP will be replaced with schema.checkWrap().
161
- const parentContext = schema.createContext(block.parent);
162
- // Is block-quote allowed in parent of block.
163
- if (!schema.checkChild(parentContext, 'blockQuote')) {
164
- return false;
165
- }
166
- // Is block allowed inside block-quote.
167
- if (!schema.checkChild(parentContext.push('blockQuote'), block)) {
168
- return false;
169
- }
170
- return true;
151
+ * Checks whether <bQ> can wrap the block.
152
+ */
153
+ function checkCanBeQuoted(schema, block) {
154
+ const parentContext = schema.createContext(block.parent);
155
+ if (!schema.checkChild(parentContext, "blockQuote")) return false;
156
+ if (!schema.checkChild(parentContext.push("blockQuote"), block)) return false;
157
+ return true;
171
158
  }
172
159
 
173
160
  /**
174
- * The block quote editing.
175
- *
176
- * Introduces the `'blockQuote'` command and the `'blockQuote'` model element.
177
- *
178
- * @extends module:core/plugin~Plugin
179
- */ class BlockQuoteEditing extends Plugin {
180
- /**
181
- * @inheritDoc
182
- */ static get pluginName() {
183
- return 'BlockQuoteEditing';
184
- }
185
- /**
186
- * @inheritDoc
187
- */ static get isOfficialPlugin() {
188
- return true;
189
- }
190
- /**
191
- * @inheritDoc
192
- */ static get requires() {
193
- return [
194
- Enter,
195
- Delete
196
- ];
197
- }
198
- /**
199
- * @inheritDoc
200
- */ init() {
201
- const editor = this.editor;
202
- const schema = editor.model.schema;
203
- editor.commands.add('blockQuote', new BlockQuoteCommand(editor));
204
- schema.register('blockQuote', {
205
- inheritAllFrom: '$container'
206
- });
207
- editor.conversion.elementToElement({
208
- model: 'blockQuote',
209
- view: 'blockquote'
210
- });
211
- // Postfixer which cleans incorrect model states connected with block quotes.
212
- editor.model.document.registerPostFixer((writer)=>{
213
- const changes = editor.model.document.differ.getChanges();
214
- for (const entry of changes){
215
- if (entry.type == 'insert') {
216
- const element = entry.position.nodeAfter;
217
- if (!element) {
218
- continue;
219
- }
220
- if (element.is('element', 'blockQuote') && element.isEmpty) {
221
- // Added an empty blockQuote - remove it.
222
- writer.remove(element);
223
- return true;
224
- } else if (element.is('element', 'blockQuote') && !schema.checkChild(entry.position, element)) {
225
- // Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost.
226
- writer.unwrap(element);
227
- return true;
228
- } else if (element.is('element')) {
229
- // Just added an element. Check that all children meet the scheme rules.
230
- const range = writer.createRangeIn(element);
231
- for (const child of range.getItems()){
232
- if (child.is('element', 'blockQuote') && !schema.checkChild(writer.createPositionBefore(child), child)) {
233
- writer.unwrap(child);
234
- return true;
235
- }
236
- }
237
- }
238
- } else if (entry.type == 'remove') {
239
- const parent = entry.position.parent;
240
- if (parent.is('element', 'blockQuote') && parent.isEmpty) {
241
- // Something got removed and now blockQuote is empty. Remove the blockQuote as well.
242
- writer.remove(parent);
243
- return true;
244
- }
245
- }
246
- }
247
- return false;
248
- });
249
- const viewDocument = this.editor.editing.view.document;
250
- const selection = editor.model.document.selection;
251
- const blockQuoteCommand = editor.commands.get('blockQuote');
252
- // Overwrite default Enter key behavior.
253
- // If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.
254
- this.listenTo(viewDocument, 'enter', (evt, data)=>{
255
- if (!selection.isCollapsed || !blockQuoteCommand.value) {
256
- return;
257
- }
258
- const positionParent = selection.getLastPosition().parent;
259
- if (positionParent.isEmpty) {
260
- editor.execute('blockQuote');
261
- editor.editing.view.scrollToTheSelection();
262
- data.preventDefault();
263
- evt.stop();
264
- }
265
- }, {
266
- context: 'blockquote'
267
- });
268
- // Overwrite default Backspace key behavior.
269
- // If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote.
270
- this.listenTo(viewDocument, 'delete', (evt, data)=>{
271
- if (data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand.value) {
272
- return;
273
- }
274
- const positionParent = selection.getLastPosition().parent;
275
- if (positionParent.isEmpty && !positionParent.previousSibling) {
276
- editor.execute('blockQuote');
277
- editor.editing.view.scrollToTheSelection();
278
- data.preventDefault();
279
- evt.stop();
280
- }
281
- }, {
282
- context: 'blockquote'
283
- });
284
- }
285
- }
161
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
162
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
163
+ */
164
+ /**
165
+ * @module block-quote/blockquoteediting
166
+ */
167
+ /**
168
+ * The block quote editing.
169
+ *
170
+ * Introduces the `'blockQuote'` command and the `'blockQuote'` model element.
171
+ *
172
+ * @extends module:core/plugin~Plugin
173
+ */
174
+ var BlockQuoteEditing = class extends Plugin {
175
+ /**
176
+ * @inheritDoc
177
+ */
178
+ static get pluginName() {
179
+ return "BlockQuoteEditing";
180
+ }
181
+ /**
182
+ * @inheritDoc
183
+ */
184
+ static get isOfficialPlugin() {
185
+ return true;
186
+ }
187
+ /**
188
+ * @inheritDoc
189
+ */
190
+ static get requires() {
191
+ return [Enter, Delete];
192
+ }
193
+ /**
194
+ * @inheritDoc
195
+ */
196
+ init() {
197
+ const editor = this.editor;
198
+ const schema = editor.model.schema;
199
+ editor.commands.add("blockQuote", new BlockQuoteCommand(editor));
200
+ schema.register("blockQuote", { inheritAllFrom: "$container" });
201
+ editor.conversion.elementToElement({
202
+ model: "blockQuote",
203
+ view: "blockquote"
204
+ });
205
+ editor.model.document.registerPostFixer((writer) => {
206
+ const changes = editor.model.document.differ.getChanges();
207
+ for (const entry of changes) if (entry.type == "insert") {
208
+ const element = entry.position.nodeAfter;
209
+ if (!element) continue;
210
+ if (element.is("element", "blockQuote") && element.isEmpty) {
211
+ writer.remove(element);
212
+ return true;
213
+ } else if (element.is("element", "blockQuote") && !schema.checkChild(entry.position, element)) {
214
+ writer.unwrap(element);
215
+ return true;
216
+ } else if (element.is("element")) {
217
+ const range = writer.createRangeIn(element);
218
+ for (const child of range.getItems()) if (child.is("element", "blockQuote") && !schema.checkChild(writer.createPositionBefore(child), child)) {
219
+ writer.unwrap(child);
220
+ return true;
221
+ }
222
+ }
223
+ } else if (entry.type == "remove") {
224
+ const parent = entry.position.parent;
225
+ if (parent.is("element", "blockQuote") && parent.isEmpty) {
226
+ writer.remove(parent);
227
+ return true;
228
+ }
229
+ }
230
+ return false;
231
+ });
232
+ const viewDocument = this.editor.editing.view.document;
233
+ const selection = editor.model.document.selection;
234
+ const blockQuoteCommand = editor.commands.get("blockQuote");
235
+ this.listenTo(viewDocument, "enter", (evt, data) => {
236
+ if (!selection.isCollapsed || !blockQuoteCommand.value) return;
237
+ if (selection.getLastPosition().parent.isEmpty) {
238
+ editor.execute("blockQuote");
239
+ editor.editing.view.scrollToTheSelection();
240
+ data.preventDefault();
241
+ evt.stop();
242
+ }
243
+ }, { context: "blockquote" });
244
+ this.listenTo(viewDocument, "delete", (evt, data) => {
245
+ if (data.direction != "backward" || !selection.isCollapsed || !blockQuoteCommand.value) return;
246
+ const positionParent = selection.getLastPosition().parent;
247
+ if (positionParent.isEmpty && !positionParent.previousSibling) {
248
+ editor.execute("blockQuote");
249
+ editor.editing.view.scrollToTheSelection();
250
+ data.preventDefault();
251
+ evt.stop();
252
+ }
253
+ }, { context: "blockquote" });
254
+ }
255
+ };
286
256
 
287
257
  /**
288
- * The block quote UI plugin.
289
- *
290
- * It introduces the `'blockQuote'` button.
291
- *
292
- * @extends module:core/plugin~Plugin
293
- */ class BlockQuoteUI extends Plugin {
294
- /**
295
- * @inheritDoc
296
- */ static get pluginName() {
297
- return 'BlockQuoteUI';
298
- }
299
- /**
300
- * @inheritDoc
301
- */ static get isOfficialPlugin() {
302
- return true;
303
- }
304
- /**
305
- * @inheritDoc
306
- */ init() {
307
- const editor = this.editor;
308
- editor.ui.componentFactory.add('blockQuote', ()=>{
309
- const buttonView = this._createButton(ButtonView);
310
- buttonView.set({
311
- tooltip: true
312
- });
313
- return buttonView;
314
- });
315
- editor.ui.componentFactory.add('menuBar:blockQuote', ()=>{
316
- const buttonView = this._createButton(MenuBarMenuListItemButtonView);
317
- buttonView.set({
318
- role: 'menuitemcheckbox'
319
- });
320
- return buttonView;
321
- });
322
- }
323
- /**
324
- * Creates a button for block quote command to use either in toolbar or in menu bar.
325
- */ _createButton(ButtonClass) {
326
- const editor = this.editor;
327
- const locale = editor.locale;
328
- const command = editor.commands.get('blockQuote');
329
- const view = new ButtonClass(editor.locale);
330
- const t = locale.t;
331
- view.set({
332
- label: t('Block quote'),
333
- icon: IconQuote,
334
- isToggleable: true
335
- });
336
- view.bind('isEnabled').to(command, 'isEnabled');
337
- view.bind('isOn').to(command, 'value');
338
- // Execute the command.
339
- this.listenTo(view, 'execute', ()=>{
340
- editor.execute('blockQuote');
341
- editor.editing.view.focus();
342
- });
343
- return view;
344
- }
345
- }
258
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
259
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
260
+ */
261
+ /**
262
+ * @module block-quote/blockquoteui
263
+ */
264
+ /**
265
+ * The block quote UI plugin.
266
+ *
267
+ * It introduces the `'blockQuote'` button.
268
+ *
269
+ * @extends module:core/plugin~Plugin
270
+ */
271
+ var BlockQuoteUI = class extends Plugin {
272
+ /**
273
+ * @inheritDoc
274
+ */
275
+ static get pluginName() {
276
+ return "BlockQuoteUI";
277
+ }
278
+ /**
279
+ * @inheritDoc
280
+ */
281
+ static get isOfficialPlugin() {
282
+ return true;
283
+ }
284
+ /**
285
+ * @inheritDoc
286
+ */
287
+ init() {
288
+ const editor = this.editor;
289
+ editor.ui.componentFactory.add("blockQuote", () => {
290
+ const buttonView = this._createButton(ButtonView);
291
+ buttonView.set({ tooltip: true });
292
+ return buttonView;
293
+ });
294
+ editor.ui.componentFactory.add("menuBar:blockQuote", () => {
295
+ const buttonView = this._createButton(MenuBarMenuListItemButtonView);
296
+ buttonView.set({ role: "menuitemcheckbox" });
297
+ return buttonView;
298
+ });
299
+ }
300
+ /**
301
+ * Creates a button for block quote command to use either in toolbar or in menu bar.
302
+ */
303
+ _createButton(ButtonClass) {
304
+ const editor = this.editor;
305
+ const locale = editor.locale;
306
+ const command = editor.commands.get("blockQuote");
307
+ const view = new ButtonClass(editor.locale);
308
+ const t = locale.t;
309
+ view.set({
310
+ label: t("Block quote"),
311
+ icon: IconQuote,
312
+ isToggleable: true
313
+ });
314
+ view.bind("isEnabled").to(command, "isEnabled");
315
+ view.bind("isOn").to(command, "value");
316
+ this.listenTo(view, "execute", () => {
317
+ editor.execute("blockQuote");
318
+ editor.editing.view.focus();
319
+ });
320
+ return view;
321
+ }
322
+ };
346
323
 
347
324
  /**
348
- * The block quote plugin.
349
- *
350
- * For more information about this feature check the {@glink api/block-quote package page}.
351
- *
352
- * This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}
353
- * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.
354
- *
355
- * @extends module:core/plugin~Plugin
356
- */ class BlockQuote extends Plugin {
357
- /**
358
- * @inheritDoc
359
- */ static get requires() {
360
- return [
361
- BlockQuoteEditing,
362
- BlockQuoteUI
363
- ];
364
- }
365
- /**
366
- * @inheritDoc
367
- */ static get pluginName() {
368
- return 'BlockQuote';
369
- }
370
- /**
371
- * @inheritDoc
372
- */ static get isOfficialPlugin() {
373
- return true;
374
- }
375
- }
325
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
326
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
327
+ */
328
+ /**
329
+ * @module block-quote/blockquote
330
+ */
331
+ /**
332
+ * The block quote plugin.
333
+ *
334
+ * For more information about this feature check the {@glink api/block-quote package page}.
335
+ *
336
+ * This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}
337
+ * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.
338
+ *
339
+ * @extends module:core/plugin~Plugin
340
+ */
341
+ var BlockQuote = class extends Plugin {
342
+ /**
343
+ * @inheritDoc
344
+ */
345
+ static get requires() {
346
+ return [BlockQuoteEditing, BlockQuoteUI];
347
+ }
348
+ /**
349
+ * @inheritDoc
350
+ */
351
+ static get pluginName() {
352
+ return "BlockQuote";
353
+ }
354
+ /**
355
+ * @inheritDoc
356
+ */
357
+ static get isOfficialPlugin() {
358
+ return true;
359
+ }
360
+ };
361
+
362
+ /**
363
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
364
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
365
+ */
376
366
 
377
367
  export { BlockQuote, BlockQuoteCommand, BlockQuoteEditing, BlockQuoteUI };
378
- //# sourceMappingURL=index.js.map
368
+ //# sourceMappingURL=index.js.map