@ckeditor/ckeditor5-table 27.1.0 → 29.2.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/LICENSE.md +1 -1
- package/README.md +3 -3
- package/build/table.js +1 -1
- package/build/translations/ar.js +1 -0
- package/build/translations/az.js +1 -0
- package/build/translations/bg.js +1 -0
- package/build/translations/cs.js +1 -0
- package/build/translations/da.js +1 -0
- package/build/translations/de-ch.js +1 -0
- package/build/translations/de.js +1 -0
- package/build/translations/en-au.js +1 -0
- package/build/translations/en-gb.js +1 -0
- package/build/translations/es.js +1 -0
- package/build/translations/et.js +1 -0
- package/build/translations/fa.js +1 -0
- package/build/translations/fi.js +1 -0
- package/build/translations/fr.js +1 -0
- package/build/translations/gl.js +1 -0
- package/build/translations/hi.js +1 -0
- package/build/translations/hr.js +1 -0
- package/build/translations/hu.js +1 -0
- package/build/translations/id.js +1 -0
- package/build/translations/it.js +1 -0
- package/build/translations/ja.js +1 -0
- package/build/translations/ko.js +1 -0
- package/build/translations/ku.js +1 -0
- package/build/translations/lt.js +1 -0
- package/build/translations/lv.js +1 -0
- package/build/translations/nb.js +1 -0
- package/build/translations/ne.js +1 -0
- package/build/translations/nl.js +1 -0
- package/build/translations/no.js +1 -0
- package/build/translations/pl.js +1 -0
- package/build/translations/pt-br.js +1 -0
- package/build/translations/ro.js +1 -0
- package/build/translations/ru.js +1 -0
- package/build/translations/sk.js +1 -0
- package/build/translations/sq.js +1 -0
- package/build/translations/sr-latn.js +1 -0
- package/build/translations/sr.js +1 -0
- package/build/translations/sv.js +1 -0
- package/build/translations/th.js +1 -0
- package/build/translations/tk.js +1 -0
- package/build/translations/tr.js +1 -0
- package/build/translations/ug.js +1 -0
- package/build/translations/uk.js +1 -0
- package/build/translations/vi.js +1 -0
- package/build/translations/zh-cn.js +1 -0
- package/build/translations/zh.js +1 -0
- package/ckeditor5-metadata.json +174 -0
- package/lang/contexts.json +4 -1
- package/lang/translations/ar.po +12 -0
- package/lang/translations/az.po +12 -0
- package/lang/translations/bg.po +12 -0
- package/lang/translations/cs.po +12 -0
- package/lang/translations/da.po +12 -0
- package/lang/translations/de-ch.po +12 -0
- package/lang/translations/de.po +12 -0
- package/lang/translations/en-au.po +12 -0
- package/lang/translations/en-gb.po +12 -0
- package/lang/translations/en.po +12 -0
- package/lang/translations/es.po +12 -0
- package/lang/translations/et.po +12 -0
- package/lang/translations/fa.po +12 -0
- package/lang/translations/fi.po +12 -0
- package/lang/translations/fr.po +12 -0
- package/lang/translations/gl.po +12 -0
- package/lang/translations/hi.po +12 -0
- package/lang/translations/hr.po +12 -0
- package/lang/translations/hu.po +23 -11
- package/lang/translations/id.po +23 -11
- package/lang/translations/it.po +12 -0
- package/lang/translations/ja.po +12 -0
- package/lang/translations/ko.po +12 -0
- package/lang/translations/ku.po +12 -0
- package/lang/translations/lt.po +12 -0
- package/lang/translations/lv.po +12 -0
- package/lang/translations/nb.po +12 -0
- package/lang/translations/ne.po +12 -0
- package/lang/translations/nl.po +12 -0
- package/lang/translations/no.po +12 -0
- package/lang/translations/pl.po +12 -0
- package/lang/translations/pt-br.po +12 -0
- package/lang/translations/ro.po +51 -39
- package/lang/translations/ru.po +12 -0
- package/lang/translations/sk.po +12 -0
- package/lang/translations/sq.po +12 -0
- package/lang/translations/sr-latn.po +12 -0
- package/lang/translations/sr.po +12 -0
- package/lang/translations/sv.po +12 -0
- package/lang/translations/th.po +12 -0
- package/lang/translations/tk.po +12 -0
- package/lang/translations/tr.po +12 -0
- package/lang/translations/ug.po +12 -0
- package/lang/translations/uk.po +12 -0
- package/lang/translations/vi.po +12 -0
- package/lang/translations/zh-cn.po +12 -0
- package/lang/translations/zh.po +12 -0
- package/package.json +25 -23
- package/src/commands/insertcolumncommand.js +2 -3
- package/src/commands/insertrowcommand.js +2 -3
- package/src/commands/inserttablecommand.js +22 -7
- package/src/commands/mergecellcommand.js +5 -3
- package/src/commands/removerowcommand.js +8 -5
- package/src/converters/downcast.js +4 -5
- package/src/converters/table-caption-post-fixer.js +69 -0
- package/src/converters/table-cell-paragraph-post-fixer.js +3 -1
- package/src/converters/table-layout-post-fixer.js +13 -8
- package/src/converters/tableproperties.js +82 -23
- package/src/converters/upcasttable.js +63 -0
- package/src/index.js +18 -33
- package/src/table.js +17 -0
- package/src/tablecaption/tablecaptionediting.js +153 -0
- package/src/tablecaption/tablecaptionui.js +71 -0
- package/src/tablecaption/toggletablecaptioncommand.js +120 -0
- package/src/tablecaption/utils.js +93 -0
- package/src/tablecaption.js +35 -0
- package/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.js +3 -2
- package/src/tablecellproperties/commands/tablecellbordercolorcommand.js +10 -3
- package/src/tablecellproperties/commands/tablecellborderstylecommand.js +10 -3
- package/src/tablecellproperties/commands/tablecellborderwidthcommand.js +17 -4
- package/src/tablecellproperties/commands/tablecellheightcommand.js +10 -3
- package/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.js +3 -2
- package/src/tablecellproperties/commands/tablecellpaddingcommand.js +17 -4
- package/src/tablecellproperties/commands/tablecellpropertycommand.js +28 -2
- package/src/tablecellproperties/commands/tablecellverticalalignmentcommand.js +3 -2
- package/src/tablecellproperties/commands/tablecellwidthcommand.js +10 -3
- package/src/tablecellproperties/tablecellpropertiesediting.js +164 -65
- package/src/tablecellproperties/tablecellpropertiesui.js +76 -16
- package/src/tablecellproperties/ui/tablecellpropertiesview.js +39 -13
- package/src/tablecellproperties.js +42 -2
- package/src/tableediting.js +76 -6
- package/src/tablekeyboard.js +3 -2
- package/src/tableproperties/commands/tablealignmentcommand.js +3 -2
- package/src/tableproperties/commands/tablebackgroundcolorcommand.js +3 -2
- package/src/tableproperties/commands/tablebordercolorcommand.js +10 -3
- package/src/tableproperties/commands/tableborderstylecommand.js +10 -3
- package/src/tableproperties/commands/tableborderwidthcommand.js +17 -4
- package/src/tableproperties/commands/tableheightcommand.js +10 -3
- package/src/tableproperties/commands/tablepropertycommand.js +28 -2
- package/src/tableproperties/commands/tablewidthcommand.js +10 -3
- package/src/tableproperties/tablepropertiesediting.js +104 -47
- package/src/tableproperties/tablepropertiesui.js +68 -15
- package/src/tableproperties/ui/tablepropertiesview.js +26 -11
- package/src/tableproperties.js +38 -2
- package/src/tableui.js +10 -1
- package/src/tableutils.js +41 -5
- package/src/tablewalker.js +36 -1
- package/src/ui/colorinputview.js +11 -7
- package/src/utils/structure.js +4 -3
- package/src/utils/table-properties.js +41 -0
- package/src/utils/ui/table-properties.js +29 -7
- package/src/utils/ui/widget.js +7 -15
- package/theme/table.css +17 -1
- package/theme/tablecaption.css +53 -0
- package/build/table.js.map +0 -1
|
@@ -8,6 +8,51 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { createEmptyTableCell } from '../utils/common';
|
|
11
|
+
import { first } from 'ckeditor5/src/utils';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Returns a function that converts the table view representation:
|
|
15
|
+
*
|
|
16
|
+
* <figure class="table"><table>...</table></figure>
|
|
17
|
+
*
|
|
18
|
+
* to the model representation:
|
|
19
|
+
*
|
|
20
|
+
* <table></table>
|
|
21
|
+
*
|
|
22
|
+
* @returns {Function}
|
|
23
|
+
*/
|
|
24
|
+
export function upcastTableFigure() {
|
|
25
|
+
return dispatcher => {
|
|
26
|
+
dispatcher.on( 'element:figure', ( evt, data, conversionApi ) => {
|
|
27
|
+
// Do not convert if this is not a "table figure".
|
|
28
|
+
if ( !conversionApi.consumable.test( data.viewItem, { name: true, classes: 'table' } ) ) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Find an table element inside the figure element.
|
|
33
|
+
const viewTable = getViewTableFromFigure( data.viewItem );
|
|
34
|
+
|
|
35
|
+
// Do not convert if table element is absent or was already converted.
|
|
36
|
+
if ( !viewTable || !conversionApi.consumable.test( viewTable, { name: true } ) ) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Convert view table to model table.
|
|
41
|
+
const conversionResult = conversionApi.convertItem( viewTable, data.modelCursor );
|
|
42
|
+
|
|
43
|
+
// Get table element from conversion result.
|
|
44
|
+
const modelTable = first( conversionResult.modelRange.getItems() );
|
|
45
|
+
|
|
46
|
+
// When table wasn't successfully converted then finish conversion.
|
|
47
|
+
if ( !modelTable ) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
conversionApi.convertChildren( data.viewItem, conversionApi.writer.createPositionAt( modelTable, 'end' ) );
|
|
52
|
+
conversionApi.updateConversionResult( modelTable, data );
|
|
53
|
+
} );
|
|
54
|
+
};
|
|
55
|
+
}
|
|
11
56
|
|
|
12
57
|
/**
|
|
13
58
|
* View table element to model table element conversion helper.
|
|
@@ -50,6 +95,9 @@ export default function upcastTable() {
|
|
|
50
95
|
// Upcast table rows in proper order (heading rows first).
|
|
51
96
|
rows.forEach( row => conversionApi.convertItem( row, conversionApi.writer.createPositionAt( table, 'end' ) ) );
|
|
52
97
|
|
|
98
|
+
// Convert everything else.
|
|
99
|
+
conversionApi.convertChildren( viewTable, conversionApi.writer.createPositionAt( table, 'end' ) );
|
|
100
|
+
|
|
53
101
|
// Create one row and one table cell for empty table.
|
|
54
102
|
if ( table.isEmpty ) {
|
|
55
103
|
const row = conversionApi.writer.createElement( 'tableRow' );
|
|
@@ -109,12 +157,26 @@ export function ensureParagraphInTableCell( elementName ) {
|
|
|
109
157
|
};
|
|
110
158
|
}
|
|
111
159
|
|
|
160
|
+
// Get view `<table>` element from the view widget (`<figure>`).
|
|
161
|
+
//
|
|
162
|
+
// @private
|
|
163
|
+
// @param {module:engine/view/element~Element} figureView
|
|
164
|
+
// @returns {module:engine/view/element~Element}
|
|
165
|
+
function getViewTableFromFigure( figureView ) {
|
|
166
|
+
for ( const figureChild of figureView.getChildren() ) {
|
|
167
|
+
if ( figureChild.is( 'element', 'table' ) ) {
|
|
168
|
+
return figureChild;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
112
173
|
// Scans table rows and extracts required metadata from the table:
|
|
113
174
|
//
|
|
114
175
|
// headingRows - The number of rows that go as table headers.
|
|
115
176
|
// headingColumns - The maximum number of row headings.
|
|
116
177
|
// rows - Sorted `<tr>` elements as they should go into the model - ie. if `<thead>` is inserted after `<tbody>` in the view.
|
|
117
178
|
//
|
|
179
|
+
// @private
|
|
118
180
|
// @param {module:engine/view/element~Element} viewTable
|
|
119
181
|
// @returns {{headingRows, headingColumns, rows}}
|
|
120
182
|
function scanTable( viewTable ) {
|
|
@@ -186,6 +248,7 @@ function scanTable( viewTable ) {
|
|
|
186
248
|
// - For body rows:
|
|
187
249
|
// - Calculates the number of column headings.
|
|
188
250
|
//
|
|
251
|
+
// @private
|
|
189
252
|
// @param {module:engine/view/element~Element} tr
|
|
190
253
|
// @returns {Number}
|
|
191
254
|
function scanRowForHeadingColumns( tr ) {
|
package/src/index.js
CHANGED
|
@@ -7,36 +7,21 @@
|
|
|
7
7
|
* @module table
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export default
|
|
27
|
-
|
|
28
|
-
TableEditing,
|
|
29
|
-
TableUI,
|
|
30
|
-
TableToolbar,
|
|
31
|
-
TableCellProperties,
|
|
32
|
-
TableCellPropertiesEditing,
|
|
33
|
-
TableCellPropertiesUI,
|
|
34
|
-
TableProperties,
|
|
35
|
-
TablePropertiesEditing,
|
|
36
|
-
TablePropertiesUI,
|
|
37
|
-
TableMouse,
|
|
38
|
-
TableClipboard,
|
|
39
|
-
TableKeyboard,
|
|
40
|
-
TableSelection,
|
|
41
|
-
TableUtils
|
|
42
|
-
};
|
|
10
|
+
export { default as Table } from './table';
|
|
11
|
+
export { default as TableEditing } from './tableediting';
|
|
12
|
+
export { default as TableUI } from './tableui';
|
|
13
|
+
export { default as TableToolbar } from './tabletoolbar';
|
|
14
|
+
export { default as TableCellProperties } from './tablecellproperties';
|
|
15
|
+
export { default as TableCellPropertiesEditing } from './tablecellproperties/tablecellpropertiesediting';
|
|
16
|
+
export { default as TableCellPropertiesUI } from './tablecellproperties/tablecellpropertiesui';
|
|
17
|
+
export { default as TableProperties } from './tableproperties';
|
|
18
|
+
export { default as TablePropertiesEditing } from './tableproperties/tablepropertiesediting';
|
|
19
|
+
export { default as TablePropertiesUI } from './tableproperties/tablepropertiesui';
|
|
20
|
+
export { default as TableCaption } from './tablecaption';
|
|
21
|
+
export { default as TableCaptionEditing } from './tablecaption/tablecaptionediting';
|
|
22
|
+
export { default as TableCaptionUI } from './tablecaption/tablecaptionui';
|
|
23
|
+
export { default as TableClipboard } from './tableclipboard';
|
|
24
|
+
export { default as TableMouse } from './tablemouse';
|
|
25
|
+
export { default as TableKeyboard } from './tablekeyboard';
|
|
26
|
+
export { default as TableSelection } from './tableselection';
|
|
27
|
+
export { default as TableUtils } from './tableutils';
|
package/src/table.js
CHANGED
|
@@ -74,6 +74,23 @@ export default class Table extends Plugin {
|
|
|
74
74
|
* @member {module:table/table~TableConfig} module:core/editor/editorconfig~EditorConfig#table
|
|
75
75
|
*/
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Number of rows and columns to render by default as table heading when inserting new tables.
|
|
79
|
+
*
|
|
80
|
+
* You can configure it like this:
|
|
81
|
+
*
|
|
82
|
+
* const tableConfig = {
|
|
83
|
+
* defaultHeadings: {
|
|
84
|
+
* rows: 1,
|
|
85
|
+
* columns: 1
|
|
86
|
+
* }
|
|
87
|
+
* };
|
|
88
|
+
*
|
|
89
|
+
* Both rows and columns properties are optional defaulting to 0 (no heading).
|
|
90
|
+
*
|
|
91
|
+
* @member {Object} module:table/table~TableConfig#defaultHeadings
|
|
92
|
+
*/
|
|
93
|
+
|
|
77
94
|
/**
|
|
78
95
|
* An array of color definitions (either strings or objects).
|
|
79
96
|
*
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module table/tablecaption/tablecaptionediting
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Plugin } from 'ckeditor5/src/core';
|
|
11
|
+
import { Element, enablePlaceholder } from 'ckeditor5/src/engine';
|
|
12
|
+
import { toWidgetEditable } from 'ckeditor5/src/widget';
|
|
13
|
+
|
|
14
|
+
import injectTableCaptionPostFixer from '../converters/table-caption-post-fixer';
|
|
15
|
+
import ToggleTableCaptionCommand from './toggletablecaptioncommand';
|
|
16
|
+
import { isTable, matchTableCaptionViewElement } from './utils';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The table caption editing plugin.
|
|
20
|
+
*
|
|
21
|
+
* @extends module:core/plugin~Plugin
|
|
22
|
+
*/
|
|
23
|
+
export default class TableCaptionEditing extends Plugin {
|
|
24
|
+
/**
|
|
25
|
+
* @inheritDoc
|
|
26
|
+
*/
|
|
27
|
+
static get pluginName() {
|
|
28
|
+
return 'TableCaptionEditing';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @inheritDoc
|
|
33
|
+
*/
|
|
34
|
+
constructor( editor ) {
|
|
35
|
+
super( editor );
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A map that keeps saved JSONified table captions and table model elements they are
|
|
39
|
+
* associated with.
|
|
40
|
+
*
|
|
41
|
+
* To learn more about this system, see {@link #_saveCaption}.
|
|
42
|
+
*
|
|
43
|
+
* @member {WeakMap.<module:engine/model/element~Element,Object>}
|
|
44
|
+
*/
|
|
45
|
+
this._savedCaptionsMap = new WeakMap();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @inheritDoc
|
|
50
|
+
*/
|
|
51
|
+
init() {
|
|
52
|
+
const editor = this.editor;
|
|
53
|
+
const schema = editor.model.schema;
|
|
54
|
+
const view = editor.editing.view;
|
|
55
|
+
const t = editor.t;
|
|
56
|
+
|
|
57
|
+
if ( !schema.isRegistered( 'caption' ) ) {
|
|
58
|
+
schema.register( 'caption', {
|
|
59
|
+
allowIn: 'table',
|
|
60
|
+
allowContentOf: '$block',
|
|
61
|
+
isLimit: true
|
|
62
|
+
} );
|
|
63
|
+
} else {
|
|
64
|
+
schema.extend( 'caption', {
|
|
65
|
+
allowIn: 'table'
|
|
66
|
+
} );
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
editor.commands.add( 'toggleTableCaption', new ToggleTableCaptionCommand( this.editor ) );
|
|
70
|
+
|
|
71
|
+
// View -> model converter for the data pipeline.
|
|
72
|
+
editor.conversion.for( 'upcast' ).elementToElement( {
|
|
73
|
+
view: matchTableCaptionViewElement,
|
|
74
|
+
model: 'caption'
|
|
75
|
+
} );
|
|
76
|
+
|
|
77
|
+
// Model -> view converter for the data pipeline.
|
|
78
|
+
editor.conversion.for( 'dataDowncast' ).elementToElement( {
|
|
79
|
+
model: 'caption',
|
|
80
|
+
view: ( modelElement, { writer } ) => {
|
|
81
|
+
if ( !isTable( modelElement.parent ) ) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return writer.createContainerElement( 'figcaption' );
|
|
86
|
+
}
|
|
87
|
+
} );
|
|
88
|
+
|
|
89
|
+
// Model -> view converter for the editing pipeline.
|
|
90
|
+
editor.conversion.for( 'editingDowncast' ).elementToElement( {
|
|
91
|
+
model: 'caption',
|
|
92
|
+
view: ( modelElement, { writer } ) => {
|
|
93
|
+
if ( !isTable( modelElement.parent ) ) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const figcaptionElement = writer.createEditableElement( 'figcaption' );
|
|
98
|
+
writer.setCustomProperty( 'tableCaption', true, figcaptionElement );
|
|
99
|
+
|
|
100
|
+
enablePlaceholder( {
|
|
101
|
+
view,
|
|
102
|
+
element: figcaptionElement,
|
|
103
|
+
text: t( 'Enter table caption' ),
|
|
104
|
+
keepOnFocus: true
|
|
105
|
+
} );
|
|
106
|
+
|
|
107
|
+
return toWidgetEditable( figcaptionElement, writer );
|
|
108
|
+
}
|
|
109
|
+
} );
|
|
110
|
+
|
|
111
|
+
injectTableCaptionPostFixer( editor.model );
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Returns the saved {@link module:engine/model/element~Element#toJSON JSONified} caption
|
|
116
|
+
* of a table model element.
|
|
117
|
+
*
|
|
118
|
+
* See {@link #_saveCaption}.
|
|
119
|
+
*
|
|
120
|
+
* @protected
|
|
121
|
+
* @param {module:engine/model/element~Element} tableModelElement The model element the
|
|
122
|
+
* caption should be returned for.
|
|
123
|
+
* @returns {module:engine/model/element~Element|null} The model caption element or `null` if there is none.
|
|
124
|
+
*/
|
|
125
|
+
_getSavedCaption( tableModelElement ) {
|
|
126
|
+
const jsonObject = this._savedCaptionsMap.get( tableModelElement );
|
|
127
|
+
|
|
128
|
+
return jsonObject ? Element.fromJSON( jsonObject ) : null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Saves a {@link module:engine/model/element~Element#toJSON JSONified} caption for
|
|
133
|
+
* a table element to allow restoring it in the future.
|
|
134
|
+
*
|
|
135
|
+
* A caption is saved every time it gets hidden. The
|
|
136
|
+
* user should be able to restore it on demand.
|
|
137
|
+
*
|
|
138
|
+
* **Note**: The caption cannot be stored in the table model element attribute because,
|
|
139
|
+
* for instance, when the model state propagates to collaborators, the attribute would get
|
|
140
|
+
* lost (mainly because it does not convert to anything when the caption is hidden) and
|
|
141
|
+
* the states of collaborators' models would de-synchronize causing numerous issues.
|
|
142
|
+
*
|
|
143
|
+
* See {@link #_getSavedCaption}.
|
|
144
|
+
*
|
|
145
|
+
* @protected
|
|
146
|
+
* @param {module:engine/model/element~Element} tableModelElement The model element the
|
|
147
|
+
* caption is saved for.
|
|
148
|
+
* @param {module:engine/model/element~Element} caption The caption model element to be saved.
|
|
149
|
+
*/
|
|
150
|
+
_saveCaption( tableModelElement, caption ) {
|
|
151
|
+
this._savedCaptionsMap.set( tableModelElement, caption.toJSON() );
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module table/tablecaption/tablecaptionui
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Plugin, icons } from 'ckeditor5/src/core';
|
|
11
|
+
import { ButtonView } from 'ckeditor5/src/ui';
|
|
12
|
+
|
|
13
|
+
import { getCaptionFromModelSelection } from './utils';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The table caption UI plugin. It introduces the `'toggleTableCaption'` UI button.
|
|
17
|
+
*
|
|
18
|
+
* @extends module:core/plugin~Plugin
|
|
19
|
+
*/
|
|
20
|
+
export default class TableCaptionUI extends Plugin {
|
|
21
|
+
/**
|
|
22
|
+
* @inheritDoc
|
|
23
|
+
*/
|
|
24
|
+
static get pluginName() {
|
|
25
|
+
return 'TableCaptionUI';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @inheritDoc
|
|
30
|
+
*/
|
|
31
|
+
init() {
|
|
32
|
+
const editor = this.editor;
|
|
33
|
+
const editingView = editor.editing.view;
|
|
34
|
+
const t = editor.t;
|
|
35
|
+
|
|
36
|
+
editor.ui.componentFactory.add( 'toggleTableCaption', locale => {
|
|
37
|
+
const command = editor.commands.get( 'toggleTableCaption' );
|
|
38
|
+
const view = new ButtonView( locale );
|
|
39
|
+
|
|
40
|
+
view.set( {
|
|
41
|
+
icon: icons.caption,
|
|
42
|
+
tooltip: true,
|
|
43
|
+
isToggleable: true
|
|
44
|
+
} );
|
|
45
|
+
|
|
46
|
+
view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
|
|
47
|
+
view.bind( 'label' ).to( command, 'value', value => value ? t( 'Toggle caption off' ) : t( 'Toggle caption on' ) );
|
|
48
|
+
|
|
49
|
+
this.listenTo( view, 'execute', () => {
|
|
50
|
+
editor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );
|
|
51
|
+
|
|
52
|
+
// Scroll to the selection and highlight the caption if the caption showed up.
|
|
53
|
+
if ( command.value ) {
|
|
54
|
+
const modelCaptionElement = getCaptionFromModelSelection( editor.model.document.selection );
|
|
55
|
+
const figcaptionElement = editor.editing.mapper.toViewElement( modelCaptionElement );
|
|
56
|
+
|
|
57
|
+
if ( !figcaptionElement ) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
editingView.scrollToTheSelection();
|
|
62
|
+
editingView.change( writer => {
|
|
63
|
+
writer.addClass( 'table__caption_highlighted', figcaptionElement );
|
|
64
|
+
} );
|
|
65
|
+
}
|
|
66
|
+
} );
|
|
67
|
+
|
|
68
|
+
return view;
|
|
69
|
+
} );
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module table/tablecaption/toggletablecaptioncommand
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Command } from 'ckeditor5/src/core';
|
|
11
|
+
|
|
12
|
+
import { getCaptionFromTableModelElement, getSelectionAffectedTable } from './utils';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The toggle table caption command.
|
|
16
|
+
*
|
|
17
|
+
* This command is registered by {@link module:table/tablecaption/tablecaptionediting~TableCaptionEditing} as the
|
|
18
|
+
* `'toggleTableCaption'` editor command.
|
|
19
|
+
*
|
|
20
|
+
* Executing this command:
|
|
21
|
+
*
|
|
22
|
+
* * either adds or removes the table caption of a selected table (depending on whether the caption is present or not),
|
|
23
|
+
* * removes the table caption if the selection is anchored in one.
|
|
24
|
+
*
|
|
25
|
+
* // Toggle the presence of the caption.
|
|
26
|
+
* editor.execute( 'toggleTableCaption' );
|
|
27
|
+
*
|
|
28
|
+
* **Note**: You can move the selection to the caption right away as it shows up upon executing this command by using
|
|
29
|
+
* the `focusCaptionOnShow` option:
|
|
30
|
+
*
|
|
31
|
+
* editor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );
|
|
32
|
+
*
|
|
33
|
+
* @extends module:core/command~Command
|
|
34
|
+
*/
|
|
35
|
+
export default class ToggleTableCaptionCommand extends Command {
|
|
36
|
+
/**
|
|
37
|
+
* @inheritDoc
|
|
38
|
+
*/
|
|
39
|
+
refresh() {
|
|
40
|
+
const editor = this.editor;
|
|
41
|
+
const tableElement = getSelectionAffectedTable( editor.model.document.selection );
|
|
42
|
+
|
|
43
|
+
this.isEnabled = !!tableElement;
|
|
44
|
+
|
|
45
|
+
if ( !this.isEnabled ) {
|
|
46
|
+
this.value = false;
|
|
47
|
+
} else {
|
|
48
|
+
this.value = !!getCaptionFromTableModelElement( tableElement );
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Executes the command.
|
|
54
|
+
*
|
|
55
|
+
* editor.execute( 'toggleTableCaption' );
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} [options] Options for the executed command.
|
|
58
|
+
* @param {String} [options.focusCaptionOnShow] When true and the caption shows up, the selection will be moved into it straight away.
|
|
59
|
+
* @fires execute
|
|
60
|
+
*/
|
|
61
|
+
execute( options = {} ) {
|
|
62
|
+
const { focusCaptionOnShow } = options;
|
|
63
|
+
|
|
64
|
+
this.editor.model.change( writer => {
|
|
65
|
+
if ( this.value ) {
|
|
66
|
+
this._hideTableCaption( writer );
|
|
67
|
+
} else {
|
|
68
|
+
this._showTableCaption( writer, focusCaptionOnShow );
|
|
69
|
+
}
|
|
70
|
+
} );
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Shows the table caption. Also:
|
|
75
|
+
*
|
|
76
|
+
* * it attempts to restore the caption content from the `TableCaptionEditing` caption registry,
|
|
77
|
+
* * it moves the selection to the caption right away, it the `focusCaptionOnShow` option was set.
|
|
78
|
+
*
|
|
79
|
+
* @private
|
|
80
|
+
* @param {module:engine/model/writer~Writer} writer
|
|
81
|
+
* @param {Boolean} focusCaptionOnShow Default focus behavior when showing the caption.
|
|
82
|
+
*/
|
|
83
|
+
_showTableCaption( writer, focusCaptionOnShow ) {
|
|
84
|
+
const model = this.editor.model;
|
|
85
|
+
const tableElement = getSelectionAffectedTable( model.document.selection );
|
|
86
|
+
const tableCaptionEditing = this.editor.plugins.get( 'TableCaptionEditing' );
|
|
87
|
+
const savedCaptionElement = tableCaptionEditing._getSavedCaption( tableElement );
|
|
88
|
+
|
|
89
|
+
// Try restoring the caption from the TableCaptionEditing plugin storage.
|
|
90
|
+
const newCaptionElement = savedCaptionElement || writer.createElement( 'caption' );
|
|
91
|
+
|
|
92
|
+
writer.append( newCaptionElement, tableElement );
|
|
93
|
+
|
|
94
|
+
if ( focusCaptionOnShow ) {
|
|
95
|
+
writer.setSelection( newCaptionElement, 'in' );
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Hides the caption of a selected table (or an table caption the selection is anchored to).
|
|
101
|
+
*
|
|
102
|
+
* The content of the caption is stored in the `TableCaptionEditing` caption registry to make this
|
|
103
|
+
* a reversible action.
|
|
104
|
+
*
|
|
105
|
+
* @private
|
|
106
|
+
* @param {module:engine/model/writer~Writer} writer
|
|
107
|
+
*/
|
|
108
|
+
_hideTableCaption( writer ) {
|
|
109
|
+
const model = this.editor.model;
|
|
110
|
+
const tableElement = getSelectionAffectedTable( model.document.selection );
|
|
111
|
+
const tableCaptionEditing = this.editor.plugins.get( 'TableCaptionEditing' );
|
|
112
|
+
const captionElement = getCaptionFromTableModelElement( tableElement );
|
|
113
|
+
|
|
114
|
+
// Store the caption content so it can be restored quickly if the user changes their mind.
|
|
115
|
+
tableCaptionEditing._saveCaption( tableElement, captionElement );
|
|
116
|
+
|
|
117
|
+
writer.setSelection( writer.createRangeIn( tableElement.getChild( 0 ).getChild( 0 ) ) );
|
|
118
|
+
writer.remove( captionElement );
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module table/tablecaption/utils
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Checks if the provided model element is a `table`.
|
|
12
|
+
*
|
|
13
|
+
* @param {module:engine/model/element~Element} modelElement Element to check if it is a table.
|
|
14
|
+
* @returns {Boolean}
|
|
15
|
+
*/
|
|
16
|
+
export function isTable( modelElement ) {
|
|
17
|
+
return !!modelElement && modelElement.is( 'element', 'table' );
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns the caption model element from a given table element. Returns `null` if no caption is found.
|
|
22
|
+
*
|
|
23
|
+
* @param {module:engine/model/element~Element} tableModelElement Table element in which we will try to find a caption element.
|
|
24
|
+
* @returns {module:engine/model/element~Element|null}
|
|
25
|
+
*/
|
|
26
|
+
export function getCaptionFromTableModelElement( tableModelElement ) {
|
|
27
|
+
for ( const node of tableModelElement.getChildren() ) {
|
|
28
|
+
if ( node.is( 'element', 'caption' ) ) {
|
|
29
|
+
return node;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns the caption model element for a model selection. Returns `null` if the selection has no caption element ancestor.
|
|
38
|
+
*
|
|
39
|
+
* @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
|
|
40
|
+
* The selection checked for caption presence.
|
|
41
|
+
* @returns {module:engine/model/element~Element|null}
|
|
42
|
+
*/
|
|
43
|
+
export function getCaptionFromModelSelection( selection ) {
|
|
44
|
+
const tableElement = getSelectionAffectedTable( selection );
|
|
45
|
+
|
|
46
|
+
if ( !tableElement ) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return getCaptionFromTableModelElement( tableElement );
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a caption.
|
|
55
|
+
*
|
|
56
|
+
* There are two possible forms of the valid caption:
|
|
57
|
+
* - A `<figcaption>` element inside a `<figure class="table">` element.
|
|
58
|
+
* - A `<caption>` inside a <table>.
|
|
59
|
+
*
|
|
60
|
+
* @param {module:engine/view/element~Element} element
|
|
61
|
+
* @returns {Object|null} Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element
|
|
62
|
+
* cannot be matched.
|
|
63
|
+
*/
|
|
64
|
+
export function matchTableCaptionViewElement( element ) {
|
|
65
|
+
const parent = element.parent;
|
|
66
|
+
|
|
67
|
+
if ( element.name == 'figcaption' && parent && parent.name == 'figure' && parent.hasClass( 'table' ) ) {
|
|
68
|
+
return { name: true };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if ( element.name == 'caption' && parent && parent.name == 'table' ) {
|
|
72
|
+
return { name: true };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Depending on the position of the selection we either return the table under cursor or look for the table higher in the hierarchy.
|
|
80
|
+
*
|
|
81
|
+
* @param {module:engine/model/position~Position} position
|
|
82
|
+
* @returns {module:engine/model/element~Element}
|
|
83
|
+
*/
|
|
84
|
+
export function getSelectionAffectedTable( selection ) {
|
|
85
|
+
const selectedElement = selection.getSelectedElement();
|
|
86
|
+
|
|
87
|
+
// Is the command triggered from the `tableToolbar`?
|
|
88
|
+
if ( selectedElement && selectedElement.is( 'element', 'table' ) ) {
|
|
89
|
+
return selectedElement;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return selection.getFirstPosition().findAncestor( 'table' );
|
|
93
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module table/tablecaption
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Plugin } from 'ckeditor5/src/core';
|
|
11
|
+
import TableCaptionEditing from './tablecaption/tablecaptionediting';
|
|
12
|
+
import TableCaptionUI from './tablecaption/tablecaptionui';
|
|
13
|
+
|
|
14
|
+
import '../theme/tablecaption.css';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The table caption plugin.
|
|
18
|
+
*
|
|
19
|
+
* @extends module:core/plugin~Plugin
|
|
20
|
+
*/
|
|
21
|
+
export default class TableCaption extends Plugin {
|
|
22
|
+
/**
|
|
23
|
+
* @inheritDoc
|
|
24
|
+
*/
|
|
25
|
+
static get pluginName() {
|
|
26
|
+
return 'TableCaption';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @inheritDoc
|
|
31
|
+
*/
|
|
32
|
+
static get requires() {
|
|
33
|
+
return [ TableCaptionEditing, TableCaptionUI ];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -28,8 +28,9 @@ export default class TableCellBackgroundColorCommand extends TableCellPropertyCo
|
|
|
28
28
|
* Creates a new `TableCellBackgroundColorCommand` instance.
|
|
29
29
|
*
|
|
30
30
|
* @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.
|
|
31
|
+
* @param {String} defaultValue The default value of the attribute.
|
|
31
32
|
*/
|
|
32
|
-
constructor( editor ) {
|
|
33
|
-
super( editor, 'backgroundColor' );
|
|
33
|
+
constructor( editor, defaultValue ) {
|
|
34
|
+
super( editor, 'backgroundColor', defaultValue );
|
|
34
35
|
}
|
|
35
36
|
}
|
|
@@ -29,9 +29,10 @@ export default class TableCellBorderColorCommand extends TableCellPropertyComman
|
|
|
29
29
|
* Creates a new `TableCellBorderColorCommand` instance.
|
|
30
30
|
*
|
|
31
31
|
* @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.
|
|
32
|
+
* @param {String} defaultValue The default value of the attribute.
|
|
32
33
|
*/
|
|
33
|
-
constructor( editor ) {
|
|
34
|
-
super( editor, 'borderColor' );
|
|
34
|
+
constructor( editor, defaultValue ) {
|
|
35
|
+
super( editor, 'borderColor', defaultValue );
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
/**
|
|
@@ -42,6 +43,12 @@ export default class TableCellBorderColorCommand extends TableCellPropertyComman
|
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
const value = getSingleValue( tableCell.getAttribute( this.attributeName ) );
|
|
47
|
+
|
|
48
|
+
if ( value === this._defaultValue ) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return value;
|
|
46
53
|
}
|
|
47
54
|
}
|