UNPKG

4.53 kBJavaScriptView Raw
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 table/plaintableoutput
7 */
8import { Plugin } from 'ckeditor5/src/core';
9import Table from './table';
10/**
11 * The plain table output feature.
12 */
13export default class PlainTableOutput extends Plugin {
14 /**
15 * @inheritDoc
16 */
17 static get pluginName() {
18 return 'PlainTableOutput';
19 }
20 /**
21 * @inheritDoc
22 */
23 static get requires() {
24 return [Table];
25 }
26 /**
27 * @inheritDoc
28 */
29 init() {
30 const editor = this.editor;
31 // Override default table data downcast converter.
32 editor.conversion.for('dataDowncast').elementToStructure({
33 model: 'table',
34 view: downcastTableElement,
35 converterPriority: 'high'
36 });
37 // Make sure table <caption> is downcasted into <caption> in the data pipeline when necessary.
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 // Handle border-style, border-color, border-width and background-color table attributes.
50 if (editor.plugins.has('TableProperties')) {
51 downcastTableBorderAndBackgroundAttributes(editor);
52 }
53 }
54}
55/**
56 * The plain table downcast converter callback.
57 *
58 * @param table Table model element.
59 * @param conversionApi The conversion API object.
60 * @returns Created element.
61 */
62function downcastTableElement(table, { writer }) {
63 const headingRows = table.getAttribute('headingRows') || 0;
64 // Table head rows slot.
65 const headRowsSlot = writer.createSlot((element) => element.is('element', 'tableRow') && element.index < headingRows);
66 // Table body rows slot.
67 const bodyRowsSlot = writer.createSlot((element) => element.is('element', 'tableRow') && element.index >= headingRows);
68 // Table children slot.
69 const childrenSlot = writer.createSlot((element) => !element.is('element', 'tableRow'));
70 // Table <thead> element with all the heading rows.
71 const theadElement = writer.createContainerElement('thead', null, headRowsSlot);
72 // Table <tbody> element with all the body rows.
73 const tbodyElement = writer.createContainerElement('tbody', null, bodyRowsSlot);
74 // Table contents element containing <thead> and <tbody> when necessary.
75 const tableContentElements = [];
76 if (headingRows) {
77 tableContentElements.push(theadElement);
78 }
79 if (headingRows < table.childCount) {
80 tableContentElements.push(tbodyElement);
81 }
82 // Create table structure.
83 //
84 // <table>
85 // {children-slot-like-caption}
86 // <thead>
87 // {table-head-rows-slot}
88 // </thead>
89 // <tbody>
90 // {table-body-rows-slot}
91 // </tbody>
92 // </table>
93 return writer.createContainerElement('table', null, [childrenSlot, ...tableContentElements]);
94}
95/**
96 * Register table border and background attributes converters.
97 */
98function 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}