1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
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 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | export default class BlockQuoteEditing extends Plugin {
|
20 | |
21 |
|
22 |
|
23 | static get pluginName() {
|
24 | return 'BlockQuoteEditing';
|
25 | }
|
26 | |
27 |
|
28 |
|
29 | static get requires() {
|
30 | return [Enter, Delete];
|
31 | }
|
32 | |
33 |
|
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 |
|
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 |
|
51 | continue;
|
52 | }
|
53 | if (element.is('element', 'blockQuote') && element.isEmpty) {
|
54 |
|
55 | writer.remove(element);
|
56 | return true;
|
57 | }
|
58 | else if (element.is('element', 'blockQuote') && !schema.checkChild(entry.position, element)) {
|
59 |
|
60 | writer.unwrap(element);
|
61 | return true;
|
62 | }
|
63 | else if (element.is('element')) {
|
64 |
|
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 |
|
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 |
|
90 |
|
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 |
|
104 |
|
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 | }
|