1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | import { Plugin } from 'ckeditor5/src/core';
|
9 | import Table from './table';
|
10 |
|
11 |
|
12 |
|
13 | export default class PlainTableOutput extends Plugin {
|
14 | |
15 |
|
16 |
|
17 | static get pluginName() {
|
18 | return 'PlainTableOutput';
|
19 | }
|
20 | |
21 |
|
22 |
|
23 | static get requires() {
|
24 | return [Table];
|
25 | }
|
26 | |
27 |
|
28 |
|
29 | init() {
|
30 | const editor = this.editor;
|
31 |
|
32 | editor.conversion.for('dataDowncast').elementToStructure({
|
33 | model: 'table',
|
34 | view: downcastTableElement,
|
35 | converterPriority: 'high'
|
36 | });
|
37 |
|
38 | if (editor.plugins.has('TableCaption')) {
|
39 | editor.conversion.for('dataDowncast').elementToElement({
|
40 | model: 'caption',
|
41 | view: (modelElement, { writer }) => {
|
42 | if (modelElement.parent.name === 'table') {
|
43 | return writer.createContainerElement('caption');
|
44 | }
|
45 | },
|
46 | converterPriority: 'high'
|
47 | });
|
48 | }
|
49 |
|
50 | if (editor.plugins.has('TableProperties')) {
|
51 | downcastTableBorderAndBackgroundAttributes(editor);
|
52 | }
|
53 | }
|
54 | }
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | function downcastTableElement(table, { writer }) {
|
63 | const headingRows = table.getAttribute('headingRows') || 0;
|
64 |
|
65 | const headRowsSlot = writer.createSlot((element) => element.is('element', 'tableRow') && element.index < headingRows);
|
66 |
|
67 | const bodyRowsSlot = writer.createSlot((element) => element.is('element', 'tableRow') && element.index >= headingRows);
|
68 |
|
69 | const childrenSlot = writer.createSlot((element) => !element.is('element', 'tableRow'));
|
70 |
|
71 | const theadElement = writer.createContainerElement('thead', null, headRowsSlot);
|
72 |
|
73 | const tbodyElement = writer.createContainerElement('tbody', null, bodyRowsSlot);
|
74 |
|
75 | const tableContentElements = [];
|
76 | if (headingRows) {
|
77 | tableContentElements.push(theadElement);
|
78 | }
|
79 | if (headingRows < table.childCount) {
|
80 | tableContentElements.push(tbodyElement);
|
81 | }
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | return writer.createContainerElement('table', null, [childrenSlot, ...tableContentElements]);
|
94 | }
|
95 |
|
96 |
|
97 |
|
98 | function downcastTableBorderAndBackgroundAttributes(editor) {
|
99 | const modelAttributes = {
|
100 | 'border-width': 'tableBorderWidth',
|
101 | 'border-color': 'tableBorderColor',
|
102 | 'border-style': 'tableBorderStyle',
|
103 | 'background-color': 'tableBackgroundColor'
|
104 | };
|
105 | for (const [styleName, modelAttribute] of Object.entries(modelAttributes)) {
|
106 | editor.conversion.for('dataDowncast').add(dispatcher => {
|
107 | return dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi) => {
|
108 | const { item, attributeNewValue } = data;
|
109 | const { mapper, writer } = conversionApi;
|
110 | if (!conversionApi.consumable.consume(item, evt.name)) {
|
111 | return;
|
112 | }
|
113 | const table = mapper.toViewElement(item);
|
114 | if (attributeNewValue) {
|
115 | writer.setStyle(styleName, attributeNewValue, table);
|
116 | }
|
117 | else {
|
118 | writer.removeStyle(styleName, table);
|
119 | }
|
120 | }, { priority: 'high' });
|
121 | });
|
122 | }
|
123 | }
|