8
0
Просмотр исходного кода

Merge branch 'master' into i/6341

Aleksander Nowodzinski 5 лет назад
Родитель
Сommit
609963c237
100 измененных файлов с 10506 добавлено и 942 удалено
  1. 1 1
      packages/ckeditor5-table/.travis.yml
  2. 18 0
      packages/ckeditor5-table/CHANGELOG.md
  3. 31 4
      packages/ckeditor5-table/docs/_snippets/features/build-table-source.js
  4. 0 9
      packages/ckeditor5-table/docs/_snippets/features/table-styling-colors.js
  5. 0 9
      packages/ckeditor5-table/docs/_snippets/features/table-styling.js
  6. 0 9
      packages/ckeditor5-table/docs/_snippets/features/table.js
  7. 4 0
      packages/ckeditor5-table/docs/api/table.md
  8. 17 0
      packages/ckeditor5-table/docs/features/table.md
  9. 4 1
      packages/ckeditor5-table/lang/contexts.json
  10. 144 0
      packages/ckeditor5-table/lang/translations/ar.po
  11. 144 0
      packages/ckeditor5-table/lang/translations/az.po
  12. 144 0
      packages/ckeditor5-table/lang/translations/cs.po
  13. 144 0
      packages/ckeditor5-table/lang/translations/da.po
  14. 144 0
      packages/ckeditor5-table/lang/translations/de-ch.po
  15. 144 0
      packages/ckeditor5-table/lang/translations/de.po
  16. 144 0
      packages/ckeditor5-table/lang/translations/en-au.po
  17. 144 0
      packages/ckeditor5-table/lang/translations/en-gb.po
  18. 144 0
      packages/ckeditor5-table/lang/translations/en.po
  19. 144 0
      packages/ckeditor5-table/lang/translations/es.po
  20. 144 0
      packages/ckeditor5-table/lang/translations/et.po
  21. 144 0
      packages/ckeditor5-table/lang/translations/fa.po
  22. 144 0
      packages/ckeditor5-table/lang/translations/fi.po
  23. 144 0
      packages/ckeditor5-table/lang/translations/fr.po
  24. 144 0
      packages/ckeditor5-table/lang/translations/gl.po
  25. 144 0
      packages/ckeditor5-table/lang/translations/hr.po
  26. 144 0
      packages/ckeditor5-table/lang/translations/hu.po
  27. 144 0
      packages/ckeditor5-table/lang/translations/id.po
  28. 144 0
      packages/ckeditor5-table/lang/translations/it.po
  29. 144 0
      packages/ckeditor5-table/lang/translations/ja.po
  30. 144 0
      packages/ckeditor5-table/lang/translations/ku.po
  31. 144 0
      packages/ckeditor5-table/lang/translations/lt.po
  32. 144 0
      packages/ckeditor5-table/lang/translations/lv.po
  33. 144 0
      packages/ckeditor5-table/lang/translations/nb.po
  34. 144 0
      packages/ckeditor5-table/lang/translations/ne.po
  35. 144 0
      packages/ckeditor5-table/lang/translations/nl.po
  36. 144 0
      packages/ckeditor5-table/lang/translations/no.po
  37. 144 0
      packages/ckeditor5-table/lang/translations/pl.po
  38. 144 0
      packages/ckeditor5-table/lang/translations/pt-br.po
  39. 144 0
      packages/ckeditor5-table/lang/translations/ro.po
  40. 144 0
      packages/ckeditor5-table/lang/translations/ru.po
  41. 144 0
      packages/ckeditor5-table/lang/translations/sk.po
  42. 144 0
      packages/ckeditor5-table/lang/translations/sq.po
  43. 144 0
      packages/ckeditor5-table/lang/translations/sr-latn.po
  44. 144 0
      packages/ckeditor5-table/lang/translations/sr.po
  45. 144 0
      packages/ckeditor5-table/lang/translations/sv.po
  46. 144 0
      packages/ckeditor5-table/lang/translations/th.po
  47. 144 0
      packages/ckeditor5-table/lang/translations/tr.po
  48. 144 0
      packages/ckeditor5-table/lang/translations/uk.po
  49. 144 0
      packages/ckeditor5-table/lang/translations/vi.po
  50. 144 0
      packages/ckeditor5-table/lang/translations/zh-cn.po
  51. 144 0
      packages/ckeditor5-table/lang/translations/zh.po
  52. 18 17
      packages/ckeditor5-table/package.json
  53. 5 4
      packages/ckeditor5-table/src/commands/insertcolumncommand.js
  54. 6 3
      packages/ckeditor5-table/src/commands/insertrowcommand.js
  55. 12 9
      packages/ckeditor5-table/src/commands/mergecellcommand.js
  56. 241 0
      packages/ckeditor5-table/src/commands/mergecellscommand.js
  57. 117 41
      packages/ckeditor5-table/src/commands/removecolumncommand.js
  58. 99 53
      packages/ckeditor5-table/src/commands/removerowcommand.js
  59. 65 0
      packages/ckeditor5-table/src/commands/selectcolumncommand.js
  60. 57 0
      packages/ckeditor5-table/src/commands/selectrowcommand.js
  61. 17 34
      packages/ckeditor5-table/src/commands/setheadercolumncommand.js
  62. 14 16
      packages/ckeditor5-table/src/commands/setheaderrowcommand.js
  63. 6 16
      packages/ckeditor5-table/src/commands/splitcellcommand.js
  64. 15 0
      packages/ckeditor5-table/src/commands/utils.js
  65. 6 0
      packages/ckeditor5-table/src/converters/tableproperties.js
  66. 9 3
      packages/ckeditor5-table/src/table.js
  67. 4 1
      packages/ckeditor5-table/src/tablecellproperties.js
  68. 22 13
      packages/ckeditor5-table/src/tablecellproperties/commands/tablecellpropertycommand.js
  69. 15 23
      packages/ckeditor5-table/src/tablecellproperties/tablecellpropertiesediting.js
  70. 50 42
      packages/ckeditor5-table/src/tablecellproperties/ui/tablecellpropertiesview.js
  71. 13 33
      packages/ckeditor5-table/src/tableclipboard.js
  72. 10 5
      packages/ckeditor5-table/src/tableediting.js
  73. 5 2
      packages/ckeditor5-table/src/tableproperties.js
  74. 2 3
      packages/ckeditor5-table/src/tableproperties/tablepropertiesediting.js
  75. 42 35
      packages/ckeditor5-table/src/tableproperties/ui/tablepropertiesview.js
  76. 349 166
      packages/ckeditor5-table/src/tableselection.js
  77. 0 49
      packages/ckeditor5-table/src/tableselection/converters.js
  78. 4 4
      packages/ckeditor5-table/src/tableselection/croptable.js
  79. 7 7
      packages/ckeditor5-table/src/tableselection/mouseeventsobserver.js
  80. 0 160
      packages/ckeditor5-table/src/tableselection/mouseselectionhandler.js
  81. 22 0
      packages/ckeditor5-table/src/tableui.js
  82. 15 2
      packages/ckeditor5-table/src/tableutils.js
  83. 3 1
      packages/ckeditor5-table/src/ui/colorinputview.js
  84. 0 90
      packages/ckeditor5-table/src/ui/formheaderview.js
  85. 66 12
      packages/ckeditor5-table/src/ui/utils.js
  86. 106 0
      packages/ckeditor5-table/src/utils.js
  87. 37 0
      packages/ckeditor5-table/tests/_utils/utils.js
  88. 58 3
      packages/ckeditor5-table/tests/commands/insertcolumncommand.js
  89. 67 2
      packages/ckeditor5-table/tests/commands/insertrowcommand.js
  90. 60 40
      packages/ckeditor5-table/tests/commands/mergecellcommand.js
  91. 480 0
      packages/ckeditor5-table/tests/commands/mergecellscommand.js
  92. 337 1
      packages/ckeditor5-table/tests/commands/removecolumncommand.js
  93. 346 3
      packages/ckeditor5-table/tests/commands/removerowcommand.js
  94. 450 0
      packages/ckeditor5-table/tests/commands/selectcolumncommand.js
  95. 469 0
      packages/ckeditor5-table/tests/commands/selectrowcommand.js
  96. 271 3
      packages/ckeditor5-table/tests/commands/setheadercolumncommand.js
  97. 295 2
      packages/ckeditor5-table/tests/commands/setheaderrowcommand.js
  98. 32 1
      packages/ckeditor5-table/tests/commands/splitcellcommand.js
  99. 52 6
      packages/ckeditor5-table/tests/commands/utils.js
  100. 7 4
      packages/ckeditor5-table/tests/manual/rtl.js

+ 1 - 1
packages/ckeditor5-table/.travis.yml

@@ -9,7 +9,7 @@ services:
 cache:
 cache:
   yarn: true
   yarn: true
 node_js:
 node_js:
-- '8'
+- '10'
 branches:
 branches:
   except:
   except:
   - stable
   - stable

+ 18 - 0
packages/ckeditor5-table/CHANGELOG.md

@@ -1,6 +1,24 @@
 Changelog
 Changelog
 =========
 =========
 
 
+## [18.0.0](https://github.com/ckeditor/ckeditor5-table/compare/v17.0.0...v18.0.0) (2020-03-19)
+
+### Features
+
+* Introduced the `TableSelection` plugin. Closes [ckeditor/ckeditor5#3202](https://github.com/ckeditor/ckeditor5/issues/3202). ([281dba5](https://github.com/ckeditor/ckeditor5-table/commit/281dba5))
+* Introduced RTL support to the table and table cell property forms. Closes [ckeditor/ckeditor5#6107](https://github.com/ckeditor/ckeditor5/issues/6107). ([3a92fc4](https://github.com/ckeditor/ckeditor5-table/commit/3a92fc4))
+
+### Bug fixes
+
+* Merge left and right commands should be always enabled if the execution does not cross the heading column boundary. Closes [ckeditor/ckeditor5#6368](https://github.com/ckeditor/ckeditor5/issues/6368). ([c088814](https://github.com/ckeditor/ckeditor5-table/commit/c088814))
+* Table border styles conversion handler should not throw when it approaches a nested table. Closes [ckeditor/ckeditor5#6177](https://github.com/ckeditor/ckeditor5/issues/6177). ([a754898](https://github.com/ckeditor/ckeditor5-table/commit/a754898))
+
+### Other changes
+
+* The default background color for the table headers should blend with the background of the entire table instead of overriding it. Closes [ckeditor/ckeditor5#6228](https://github.com/ckeditor/ckeditor5/issues/6228). ([b53032d](https://github.com/ckeditor/ckeditor5-table/commit/b53032d))
+* Updated translations. ([70b8af5](https://github.com/ckeditor/ckeditor5-table/commit/70b8af5))
+
+
 ## [17.0.0](https://github.com/ckeditor/ckeditor5-table/compare/v16.0.0...v17.0.0) (2020-02-19)
 ## [17.0.0](https://github.com/ckeditor/ckeditor5-table/compare/v16.0.0...v17.0.0) (2020-02-19)
 
 
 ### Features
 ### Features

+ 31 - 4
packages/ckeditor5-table/docs/_snippets/features/build-table-source.js

@@ -7,13 +7,40 @@
 
 
 import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
 import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
 
 
-import Table from '@ckeditor/ckeditor5-table/src/table';
-import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
+import FontFamily from '@ckeditor/ckeditor5-font/src/fontfamily';
+import FontSize from '@ckeditor/ckeditor5-font/src/fontsize';
+import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
+import IndentBlock from '@ckeditor/ckeditor5-indent/src/indentblock';
 import TableProperties from '@ckeditor/ckeditor5-table/src/tableproperties';
 import TableProperties from '@ckeditor/ckeditor5-table/src/tableproperties';
 import TableCellProperties from '@ckeditor/ckeditor5-table/src/tablecellproperties';
 import TableCellProperties from '@ckeditor/ckeditor5-table/src/tablecellproperties';
 
 
-ClassicEditor.builtinPlugins.push( Table );
-ClassicEditor.builtinPlugins.push( TableToolbar );
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor.builtinPlugins.push( FontFamily, FontSize, Alignment, IndentBlock );
+ClassicEditor.defaultConfig = {
+	cloudServices: CS_CONFIG,
+	toolbar: {
+		items: [
+			'insertTable',
+			'|',
+			'fontFamily', 'fontSize',
+			'|',
+			'bold', 'italic',
+			'|',
+			'alignment:left', 'alignment:center', 'alignment:right', 'alignment:justify',
+			'|',
+			'bulletedList', 'numberedList',
+			'|',
+			'indent', 'outdent',
+			'|',
+			'link', 'blockQuote',
+			'|',
+			'undo', 'redo'
+		],
+		viewportTopOffset: window.getViewportTopOffsetConfig()
+	},
+	indentBlock: { offset: 30, unit: 'px' }
+};
 
 
 window.ClassicEditor = ClassicEditor;
 window.ClassicEditor = ClassicEditor;
 window.CKEditorPlugins = {
 window.CKEditorPlugins = {

+ 0 - 9
packages/ckeditor5-table/docs/_snippets/features/table-styling-colors.js

@@ -5,8 +5,6 @@
 
 
 /* globals ClassicEditor, CKEditorPlugins, console, window, document */
 /* globals ClassicEditor, CKEditorPlugins, console, window, document */
 
 
-import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
-
 const customColorPalette = [
 const customColorPalette = [
 	{
 	{
 		color: 'hsl(4, 90%, 58%)',
 		color: 'hsl(4, 90%, 58%)',
@@ -96,13 +94,6 @@ ClassicEditor
 			CKEditorPlugins.TableProperties,
 			CKEditorPlugins.TableProperties,
 			CKEditorPlugins.TableCellProperties
 			CKEditorPlugins.TableCellProperties
 		],
 		],
-		cloudServices: CS_CONFIG,
-		toolbar: {
-			items: [
-				'insertTable', '|', 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo'
-			],
-			viewportTopOffset: window.getViewportTopOffsetConfig()
-		},
 		table: {
 		table: {
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties' ],
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties' ],
 			tableProperties: {
 			tableProperties: {

+ 0 - 9
packages/ckeditor5-table/docs/_snippets/features/table-styling.js

@@ -5,8 +5,6 @@
 
 
 /* globals ClassicEditor, CKEditorPlugins, console, window, document */
 /* globals ClassicEditor, CKEditorPlugins, console, window, document */
 
 
-import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
-
 const COLOR_PALETTE = [
 const COLOR_PALETTE = [
 	{
 	{
 		color: 'hsl(0, 0%, 0%)',
 		color: 'hsl(0, 0%, 0%)',
@@ -97,13 +95,6 @@ ClassicEditor
 			CKEditorPlugins.TableProperties,
 			CKEditorPlugins.TableProperties,
 			CKEditorPlugins.TableCellProperties
 			CKEditorPlugins.TableCellProperties
 		],
 		],
-		cloudServices: CS_CONFIG,
-		toolbar: {
-			items: [
-				'insertTable', '|', 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo'
-			],
-			viewportTopOffset: window.getViewportTopOffsetConfig()
-		},
 		table: {
 		table: {
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties' ],
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties' ],
 			tableProperties: {
 			tableProperties: {

+ 0 - 9
packages/ckeditor5-table/docs/_snippets/features/table.js

@@ -5,17 +5,8 @@
 
 
 /* globals ClassicEditor, console, window, document */
 /* globals ClassicEditor, console, window, document */
 
 
-import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
-
 ClassicEditor
 ClassicEditor
 	.create( document.querySelector( '#snippet-table' ), {
 	.create( document.querySelector( '#snippet-table' ), {
-		cloudServices: CS_CONFIG,
-		toolbar: {
-			items: [
-				'insertTable', '|', 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo'
-			],
-			viewportTopOffset: window.getViewportTopOffsetConfig()
-		},
 		table: {
 		table: {
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
 		}
 		}

+ 4 - 0
packages/ckeditor5-table/docs/api/table.md

@@ -18,6 +18,10 @@ See the {@link features/table Table feature} guide and the documentation for the
 
 
 * {@link module:table/table~Table}
 * {@link module:table/table~Table}
 * {@link module:table/tabletoolbar~TableToolbar}
 * {@link module:table/tabletoolbar~TableToolbar}
+* {@link module:table/tableproperties~TableProperties}
+* {@link module:table/tablecellproperties~TableCellProperties}
+* {@link module:table/tableselection~TableSelection}
+* {@link module:table/tableclipboard~TableClipboard}
 * {@link module:table/tableutils~TableUtils}
 * {@link module:table/tableutils~TableUtils}
 
 
 ## Installation
 ## Installation

+ 17 - 0
packages/ckeditor5-table/docs/features/table.md

@@ -31,6 +31,15 @@ Put the caret anywhere inside the table and click the **"Table properties"** but
 	By default, table styling tools are not included in the {@link builds/guides/overview ready–to–use editor builds} and must be installed separately. See the [installation](#table-and-cell-styling-tools-2) section to learn how to enable them in your editor.
 	By default, table styling tools are not included in the {@link builds/guides/overview ready–to–use editor builds} and must be installed separately. See the [installation](#table-and-cell-styling-tools-2) section to learn how to enable them in your editor.
 </info-box>
 </info-box>
 
 
+## Table selection
+
+The {@link module:table/tableselection~TableSelection} plugin introduces support for the custom selection system for tables that lets you:
+
+* Select an arbitrary rectangular table fragment &mdash; a few cells from different rows, a column (or a few of them) or a row (or multiple rows).
+* Apply formatting or add a link to all selected cells at once.
+
+The table selection plugin is loaded automatically by the `Table` plugin and can be tested in the [demos above](#demos).
+
 ## Installation
 ## Installation
 
 
 ### Basic table features
 ### Basic table features
@@ -385,6 +394,14 @@ The {@link module:table/tabletoolbar~TableToolbar} plugin introduces two balloon
 			<td><code>'removeTableRow'</code></td>
 			<td><code>'removeTableRow'</code></td>
 			<td>{@link module:table/commands/removerowcommand~RemoveRowCommand}</td>
 			<td>{@link module:table/commands/removerowcommand~RemoveRowCommand}</td>
 		</tr>
 		</tr>
+		<tr>
+			<td><code>'selectTableColumn'</code></td>
+			<td>{@link module:table/commands/selectcolumncommand~SelectColumnCommand}</td>
+		</tr>
+		<tr>
+			<td><code>'selectTableRow'</code></td>
+			<td>{@link module:table/commands/selectrowcommand~SelectRowCommand}</td>
+		</tr>
 		<tr>
 		<tr>
 			<td><code>'setTableColumnHeader'</code></td>
 			<td><code>'setTableColumnHeader'</code></td>
 			<td>{@link module:table/commands/setheadercolumncommand~SetHeaderColumnCommand}</td>
 			<td>{@link module:table/commands/setheadercolumncommand~SetHeaderColumnCommand}</td>

+ 4 - 1
packages/ckeditor5-table/lang/contexts.json

@@ -4,11 +4,13 @@
 	"Insert column left": "Label for the insert table column to the left of the current one button.",
 	"Insert column left": "Label for the insert table column to the left of the current one button.",
 	"Insert column right": "Label for the insert table column to the right of the current one button.",
 	"Insert column right": "Label for the insert table column to the right of the current one button.",
 	"Delete column": "Label for the delete table column button.",
 	"Delete column": "Label for the delete table column button.",
+	"Select column": "Label for the select table entire column button.",
 	"Column": "Label for the table column dropdown button.",
 	"Column": "Label for the table column dropdown button.",
 	"Header row": "Label for the set/unset table header row button.",
 	"Header row": "Label for the set/unset table header row button.",
 	"Insert row below": "Label for the insert row below button.",
 	"Insert row below": "Label for the insert row below button.",
 	"Insert row above": "Label for the insert row above button.",
 	"Insert row above": "Label for the insert row above button.",
 	"Delete row": "Label for the delete table row button.",
 	"Delete row": "Label for the delete table row button.",
+	"Select row": "Label for the select table entire row button.",
 	"Row": "Label for the table row dropdown button.",
 	"Row": "Label for the table row dropdown button.",
 	"Merge cell up": "Label for the merge table cell up button.",
 	"Merge cell up": "Label for the merge table cell up button.",
 	"Merge cell right": "Label for the merge table cell right button.",
 	"Merge cell right": "Label for the merge table cell right button.",
@@ -53,5 +55,6 @@
 	"Center table": "The label used by assistive technologies describing a button that centers the table.",
 	"Center table": "The label used by assistive technologies describing a button that centers the table.",
 	"Align table to the right": "The label used by assistive technologies describing a button that aligns the table to the right.",
 	"Align table to the right": "The label used by assistive technologies describing a button that aligns the table to the right.",
 	"The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".": "The localized error string that can be displayed next to color (background, border) fields that have an invalid value",
 	"The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".": "The localized error string that can be displayed next to color (background, border) fields that have an invalid value",
-	"The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".": "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+	"The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".": "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value.",
+	"Color picker": "The label used by assistive technologies describing a button that opens a color picker, where user can choose a configured color for a certain properties (eg.: background color, color, border-color etc.)."
 }
 }

+ 144 - 0
packages/ckeditor5-table/lang/translations/ar.po

@@ -91,3 +91,147 @@ msgstr "دمج الخلايا"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/az.po

@@ -91,3 +91,147 @@ msgstr "Xanaları birləşdir"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Cədvəl paneli"
 msgstr "Cədvəl paneli"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Cədvəl xüsusiyyətləri"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Sərhəd"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Eni"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Hündürlük"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Rəng"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Fon"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Ölçülər"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Cədvəl hüceyrəsi mətninin uyğunlaşdırılması"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/cs.po

@@ -91,3 +91,147 @@ msgstr "Sloučit buňky"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Panel nástrojů tabulky"
 msgstr "Panel nástrojů tabulky"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/da.po

@@ -91,3 +91,147 @@ msgstr "Flet celler"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Tabel værktøjslinje"
 msgstr "Tabel værktøjslinje"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Tabelegenskaber"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Celleegenskaber"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Ramme"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Stil"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Bredde"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Højde"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Farve"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Baggrund"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Fyld"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensioner"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Tabelcelle tekstjustering"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Justering"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Horisontal tekstjustering værktøjslinje"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Vertikal tekstjustering værktøjslinje"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Tabeljustering værktøjslinje"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Ingen"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Massiv"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Stiplet (prik)"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Stiplet (streg)"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Dobbel"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Not"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Kam"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "Forsænket"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Fra starten"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Justér tekstcelle til venstre"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Justér tekstcelle centreret"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Justér tekstcelle til højre"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Justér tekstcelle"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Justér tekstcelle til top"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Justér tekstcelle til midten"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Justér tekstcelle til bunden"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Justér tabel til venstre"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Centrér tabel"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Justér tabel til højre"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "Farven er ugyldig. Prøv \"#FF0000\" eller \"rgb(255,0,0)\" eller \"red\"."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "Værdien er ugyldig. Prøv \"10px\" eller \"2em\" eller ganske enkelt \"2\"."

+ 144 - 0
packages/ckeditor5-table/lang/translations/de-ch.po

@@ -91,3 +91,147 @@ msgstr "Zellen verbinden"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/de.po

@@ -91,3 +91,147 @@ msgstr "Zellen verbinden"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Tabelle Werkzeugleiste"
 msgstr "Tabelle Werkzeugleiste"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/en-au.po

@@ -91,3 +91,147 @@ msgstr "Merge cells"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Table toolbar"
 msgstr "Table toolbar"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Table properties"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Cell properties"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Border"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Style"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Width"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Height"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Colour"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Background"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Padding"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensions"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Table cell text alignment"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Alignment"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Horizontal text alignment toolbar"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Vertical text alignment toolbar"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Table alignment toolbar"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "None"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Solid"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Dotted"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Dashed"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Double"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Groove"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Ridge"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "Inset"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Outset"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Align cell text to the left"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Align cell text to the center"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Align cell text to the right"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Justify cell text"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Align cell text to the top"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Align cell text to the middle"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Align cell text to the bottom"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Align table to the left"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Centre table"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Align table to the right"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "The colour is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."

+ 144 - 0
packages/ckeditor5-table/lang/translations/en-gb.po

@@ -91,3 +91,147 @@ msgstr "Merge cells"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/en.po

@@ -91,3 +91,147 @@ msgstr "Merge cells"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Table toolbar"
 msgstr "Table toolbar"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Table properties"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Cell properties"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Border"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Style"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Width"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Height"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Color"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Background"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Padding"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensions"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Table cell text alignment"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Alignment"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Horizontal text alignment toolbar"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Vertical text alignment toolbar"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Table alignment toolbar"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "None"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Solid"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Dotted"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Dashed"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Double"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Groove"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Ridge"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "Inset"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Outset"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Align cell text to the left"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Align cell text to the center"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Align cell text to the right"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Justify cell text"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Align cell text to the top"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Align cell text to the middle"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Align cell text to the bottom"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Align table to the left"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Center table"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Align table to the right"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."

+ 144 - 0
packages/ckeditor5-table/lang/translations/es.po

@@ -91,3 +91,147 @@ msgstr "Combinar celdas"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Barra de herramientas de tabla"
 msgstr "Barra de herramientas de tabla"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/et.po

@@ -91,3 +91,147 @@ msgstr "Liida lahtrid"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Tabelite tööriistariba"
 msgstr "Tabelite tööriistariba"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/fa.po

@@ -91,3 +91,147 @@ msgstr "ادغام سلول ها"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "نوارابزار جدول"
 msgstr "نوارابزار جدول"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/fi.po

@@ -91,3 +91,147 @@ msgstr "Yhdistä tai jaa soluja"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/fr.po

@@ -91,3 +91,147 @@ msgstr "Fusionner les cellules"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Barre d'outils des tableaux"
 msgstr "Barre d'outils des tableaux"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Propriétés du tableau"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Propriétés de la cellule"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Bordure"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Style"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Largeur"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Hauteur"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Couleur"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Fond"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Remplissage pour aérer le texte"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensions"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Alignement du texte de la cellule"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Alignement"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Barre d'outils pour modifier l'alignement horizontal du texte"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Barre d'outils pour modifier l'alignement vertical du texte"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Barre d'outils pour modifier l'alignement du tableau"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Aucun"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Continu"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Pointillés"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Tirets"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Double"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Rainuré"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Relief"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "Relief intérieur"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Relief extérieur"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Aligner la cellule à gauche"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Aligner la cellule au centre"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Aligner la cellule à droite"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Justifier le contenu de la cellule"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Aligner le texte en haut"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Aligner le texte au milieu"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Aligner le texte en bas"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Aligner le tableau à gauche"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Centrer le tableau "
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Aligner le tableau à droite"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "La couleur est invalide. Essayez \"#FF0000\" ou \"rgb(255,0,0)\" ou \"red\"."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "La valeur est invalide. Essayez \"10px\" ou \"2em\" ou simplement \"2\"."

+ 144 - 0
packages/ckeditor5-table/lang/translations/gl.po

@@ -91,3 +91,147 @@ msgstr "Combinar celas"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Barra de ferramentas de táboas"
 msgstr "Barra de ferramentas de táboas"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Propiedades da táboa"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Propiedades da cela"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Bordo"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Estilo"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Largo"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Alto"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Cor"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Fondo"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Recheo"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensións"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Aliñamento do texto das celas da táboa"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Aliñamento"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Barra de ferramentas de aliñamento de texto horizontal"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Barra de ferramentas de aliñamento de texto vertical"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Barra de ferramentas de aliñamento da táboa"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Ningún"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Sólido"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Punteado"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Raiado"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Dobre"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Rañura"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Crista"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "Inserción"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Inicio"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Aliñar o texto da cela á esquerda"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Aliñar o texto da cela ao centro"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Aliña o texto da cela á dereita"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Xustificar o texto da cela"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Aliñar o texto da cela á parte superior"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Aliñar o texto da cela ao medio"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Aliñar o texto da cela á base"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Aliñar a táboa á esquerda"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Centrar a táboa"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Aliñar a táboa á dereita"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "A cor non é válida. Probe «#FF0000» ou «rgb(255,0,0)» ou «vermello»."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "O valor non é válido. Probe «10px» ou «2em» ou simplemente «2»."

+ 144 - 0
packages/ckeditor5-table/lang/translations/hr.po

@@ -91,3 +91,147 @@ msgstr "Spoji ćelije"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Traka za tablice"
 msgstr "Traka za tablice"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/hu.po

@@ -91,3 +91,147 @@ msgstr "Cellaegyesítés"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Táblázat eszköztár"
 msgstr "Táblázat eszköztár"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/id.po

@@ -91,3 +91,147 @@ msgstr "Gabungkan sel"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Alat tabel"
 msgstr "Alat tabel"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/it.po

@@ -91,3 +91,147 @@ msgstr "Unisci celle"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Barra degli strumenti della tabella"
 msgstr "Barra degli strumenti della tabella"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Proprietà tabella"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Proprietà cella"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Bordo"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Stile"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Larghezza"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Altezza"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Colore"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Sfondo"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Spaziatura interna"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensioni"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Allineamento del testo nella cella della tabella"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Allineamento"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Barra degli strumenti dell'allineamento orizzontale del testo"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Barra degli strumenti dell'allineamento verticale del testo"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Barra degli strumenti dell'allineamento della tabella"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Solido"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Punteggiato"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Tratteggiato"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Doppio"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Scanalatura"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Rilievo"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "Incassato"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Rialzato"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Allinea il testo della cella a sinistra"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Allinea il testo della cella al centro"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Allinea il testo della cella a destra"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Testo della cella giustificato"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Allinea il testo della cella in alto"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Allinea il testo della cella in mezzo"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Allinea il testo della cella in basso"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Allinea tabella a sinistra"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Allinea tabella al centro"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Allinea tabella a destra"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "Il colore non è valido. Provare \"#FF0000\" o \"rgb(255,0,0)\" o \"red\"."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "Il valore non è valido. Provare \"10px\" o \"2em\" o semplicemente \"2\"."

+ 144 - 0
packages/ckeditor5-table/lang/translations/ja.po

@@ -91,3 +91,147 @@ msgstr "セルを結合"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/ku.po

@@ -91,3 +91,147 @@ msgstr "تێکەڵکردنی خانەکان"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "تووڵامرازی خشتە"
 msgstr "تووڵامرازی خشتە"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/lt.po

@@ -91,3 +91,147 @@ msgstr "Sujungti langelius"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/lv.po

@@ -91,3 +91,147 @@ msgstr "Apvienot šūnas"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Tabulas rīkjosla"
 msgstr "Tabulas rīkjosla"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/nb.po

@@ -91,3 +91,147 @@ msgstr "Slå sammen celler"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/ne.po

@@ -91,3 +91,147 @@ msgstr "कक्ष मर्ज गर्नुहोस्"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/nl.po

@@ -91,3 +91,147 @@ msgstr "Cellen samenvoegen"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Tabel werkbalk"
 msgstr "Tabel werkbalk"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/no.po

@@ -91,3 +91,147 @@ msgstr "Slå sammen celler"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Egenskaper for tabell"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Celleegenskaper "
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Stil "
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Bredde"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Høyde"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Farge"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Bakgrunn "
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensjoner"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Celle tekstjustering "
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Justering"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/pl.po

@@ -91,3 +91,147 @@ msgstr "Scal komórki"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Pasek narzędzi tabel"
 msgstr "Pasek narzędzi tabel"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Właściwości tabeli"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Właściwości komórki"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Obramowanie"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Styl"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Szerokość"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Wysokość"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Kolor"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Tło"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Dopełnienie"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Wymiary"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Wyrównanie tekstu komórki tabeli"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Wyrównanie"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Pasek narzędzi wyrównania tekstu w poziomie"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Pasek narzędzi wyrównania tekstu w pionie"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Pasek narzędzi wyrównania tabeli"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Brak"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Ciągłe"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Kropkowane"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Kreskowane"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Podwójne"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Wklęsłe"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Wypukłe"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "Zapadnięte"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Wysunięte"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Wyrównaj tekst w komórce do lewej"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Wyrównaj tekst w komórce do środka"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Wyrównaj tekst w komórce do prawej"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Wyjustuj tekst komórki"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Wyrównaj tekst w komórce do góry"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Wyrównaj tekst w komórce do środka"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Wyrównaj tekst w komórce do dołu"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Wyrównaj tabelę do lewej"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Wyrównaj tabelę do środka"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Wyrównaj tabelę do prawej"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "Kolor jest niepoprawny. Spróbuj wpisać \"#FF0000\", \"rgb(255,0,0)\" lub \"red\"."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "Wartość jest niepoprawna. Spróbuj  wpisać \"10px\", \"2em\" lub po prostu \"2\"."

+ 144 - 0
packages/ckeditor5-table/lang/translations/pt-br.po

@@ -91,3 +91,147 @@ msgstr "Mesclar células"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Ferramentas de Tabela"
 msgstr "Ferramentas de Tabela"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Propriedades da tabela"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Propriedades da célula"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Borda"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Estilo"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Largura"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Altura"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Cor"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Cor de fundo"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Dimensões"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Alinhamento do texto na célula"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Alinhamento"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Ferramentas de alinhamento horizontal do texto"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Ferramentas de alinhamento vertical do texto"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Ferramentas de alinhamento da tabela"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Sem borda"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Sólida"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Pontilhada"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Tracejada"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Dupla"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Alinhar texto da célula para a esquerda"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Alinhar texto da célula centralizado"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Alinhar texto da célula para a direita"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Justificar texto da célula"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Alinhar texto da célula para o topo"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Alinhar texto da célula para o meio"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Alinhar texto da célula para baixo"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Alinhar tabela para esquerda"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Centralizar tabela"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Alinhar tabela para direita"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "Cor inválida. Tente \"#FF0000\" ou \"rgb(255,0,0)\" ou \"red\""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "Valor inválido. Tente \"10px\" ou \"2em\" ou apenas \"2\""

+ 144 - 0
packages/ckeditor5-table/lang/translations/ro.po

@@ -91,3 +91,147 @@ msgstr "Îmbină celulele"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Bară tabel"
 msgstr "Bară tabel"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/ru.po

@@ -91,3 +91,147 @@ msgstr "Объединить ячейки"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/sk.po

@@ -91,3 +91,147 @@ msgstr "Zlúčiť bunky"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Panel nástrojov tabuľky"
 msgstr "Panel nástrojov tabuľky"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/sq.po

@@ -91,3 +91,147 @@ msgstr "Bashko kutizat"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/sr-latn.po

@@ -91,3 +91,147 @@ msgstr "Spoj ćelije"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Tabela traka sa alatkama"
 msgstr "Tabela traka sa alatkama"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/sr.po

@@ -91,3 +91,147 @@ msgstr "Спој ћелије"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Табела трака са алаткама"
 msgstr "Табела трака са алаткама"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/sv.po

@@ -91,3 +91,147 @@ msgstr ""
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/th.po

@@ -91,3 +91,147 @@ msgstr "ผสานเซลล์"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "เครื่องมือตาราง"
 msgstr "เครื่องมือตาราง"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/tr.po

@@ -91,3 +91,147 @@ msgstr "Hücreleri birleştir"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Tablo araç çubuğu"
 msgstr "Tablo araç çubuğu"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Tablo özellikleri"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Hücre özellikleri"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Kenar"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Stil"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Genişlik"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Yükseklik"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Renk"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Arkaplan"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "İç boşluk"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Ölçüler"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Tablo hücresi metin hizalaması"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Hizalama"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Yatay metin hizalama araç çubuğu"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Dikey metin hizalama araç çubuğu"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Tablo hizalama araç çubuğu"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Yok"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Dolu"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Noktalı"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr "Kesik çizgili"
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr "Çift"
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr "Yiv"
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr "Yükselti"
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr "İçe"
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr "Dışarıya"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr "Hücre içindeki metnini sola hizala"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr "Hücre içindeki metnini ortaya hizalama"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr "Hücre içindeki metnini sağa hizala"
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr "Hücre içindeki metini iki yana yasla"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr "Hücre içindeki metni üste hizala"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr "Hücre içindeki metni ortaya hizala"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr "Hücre içindeki metni alta hizala"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr "Tabloyu sola hizala"
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr "Tabloyu ortala"
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr "Tabloyu sağa hizala"
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "Geçersiz renk. \"#FF0000\" veya \"rgb(255,0,0)\" veya \"red\" deneyin."
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "Geçersiz değer. \"10px\" veya \"2em\" veya sadece \"2\" deneyin."

+ 144 - 0
packages/ckeditor5-table/lang/translations/uk.po

@@ -91,3 +91,147 @@ msgstr "Поєднати комірки"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Панель інструментів таблиці"
 msgstr "Панель інструментів таблиці"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr "Властивості таблиці"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr "Властивості комірок"
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr "Межа"
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr "Стиль"
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr "Ширина"
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr "Висота"
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr "Колір"
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr "Фон"
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr "Заповнення"
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr "Розміри"
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr "Вирівнювання тексту комірки"
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr "Вирівнювання"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr "Панель інструментів вирівнювання горизонтального тексту"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr "Панель інструментів вертикального вирівнювання тексту"
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr "Панель інструментів вирівнювання таблиці"
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr "Не вказано"
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr "Суцільний"
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr "Пунктирною"
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr "Колір недійсний. Спробуйте \"#FF0000\" або \"rgb(255,0,0)\" або \"red\""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr "Значення недійсне. Спробуйте \"10px\" або \"2em\" або просто \"2\""

+ 144 - 0
packages/ckeditor5-table/lang/translations/vi.po

@@ -91,3 +91,147 @@ msgstr "Sát nhập ô"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "Thanh công cụ bảng"
 msgstr "Thanh công cụ bảng"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/zh-cn.po

@@ -91,3 +91,147 @@ msgstr "合并单元格"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr "表格工具栏"
 msgstr "表格工具栏"
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 144 - 0
packages/ckeditor5-table/lang/translations/zh.po

@@ -91,3 +91,147 @@ msgstr "合併儲存格"
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgctxt "The label used by assistive technologies describing a table toolbar attached to a table widget."
 msgid "Table toolbar"
 msgid "Table toolbar"
 msgstr ""
 msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table."
+msgid "Table properties"
+msgstr ""
+
+msgctxt "The label describing the form allowing to specify the properties of a selected table cell."
+msgid "Cell properties"
+msgstr ""
+
+msgctxt "The label describing a group of border–related form fields (border style, color, etc.)."
+msgid "Border"
+msgstr ""
+
+msgctxt "The label for the dropdown that allows configuring the border style of a table or a table cell."
+msgid "Style"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the width of a table or a table cell or the width of a border."
+msgid "Width"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the height of a table or a table cell."
+msgid "Height"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the border color of a table or a table cell."
+msgid "Color"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the background color of a table or a table cell."
+msgid "Background"
+msgstr ""
+
+msgctxt "The label for the input that allows configuring the padding of a table cell."
+msgid "Padding"
+msgstr ""
+
+msgctxt "The label describing a group of form fields that allows setting dimensions of a table or a table cell."
+msgid "Dimensions"
+msgstr ""
+
+msgctxt "The label for the group of toolbars that allows configuring the text alignment in a table cell."
+msgid "Table cell text alignment"
+msgstr ""
+
+msgctxt "The label for the toolbar that allows configuring the alignment of a table."
+msgid "Alignment"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the horizontal text alignment in a table cell."
+msgid "Horizontal text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the vertical text alignment in a table cell."
+msgid "Vertical text alignment toolbar"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a toolbar that allows configuring the alignment of a table."
+msgid "Table alignment toolbar"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when no style is applied to a table or a table cell."
+msgid "None"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the solid border is applied to a table or a table cell."
+msgid "Solid"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dotted border is applied to a table or a table cell."
+msgid "Dotted"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the dashed border is applied to a table or a table cell."
+msgid "Dashed"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the double border is applied to a table or a table cell."
+msgid "Double"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the groove border is applied to a table or a table cell."
+msgid "Groove"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the ridge border is applied to a table or a table cell."
+msgid "Ridge"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the inset border is applied to a table or a table cell."
+msgid "Inset"
+msgstr ""
+
+msgctxt "The label for the border style dropdown when the outset border is applied to a table or a table cell."
+msgid "Outset"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the left."
+msgid "Align cell text to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the center."
+msgid "Align cell text to the center"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the right."
+msgid "Align cell text to the right"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that justifies the table cell text."
+msgid "Justify cell text"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the top."
+msgid "Align cell text to the top"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the middle."
+msgid "Align cell text to the middle"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table cell text to the bottom."
+msgid "Align cell text to the bottom"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the left."
+msgid "Align table to the left"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that centers the table."
+msgid "Center table"
+msgstr ""
+
+msgctxt "The label used by assistive technologies describing a button that aligns the table to the right."
+msgid "Align table to the right"
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to color (background, border) fields that have an invalid value"
+msgid "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\"."
+msgstr ""
+
+msgctxt "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value."
+msgid "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\"."
+msgstr ""

+ 18 - 17
packages/ckeditor5-table/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@ckeditor/ckeditor5-table",
   "name": "@ckeditor/ckeditor5-table",
-  "version": "17.0.0",
+  "version": "18.0.0",
   "description": "Table feature for CKEditor 5.",
   "description": "Table feature for CKEditor 5.",
   "keywords": [
   "keywords": [
     "ckeditor",
     "ckeditor",
@@ -10,25 +10,26 @@
     "ckeditor5-plugin"
     "ckeditor5-plugin"
   ],
   ],
   "dependencies": {
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^17.0.0",
-    "@ckeditor/ckeditor5-ui": "^17.0.0",
-    "@ckeditor/ckeditor5-widget": "^17.0.0",
+    "@ckeditor/ckeditor5-core": "^18.0.0",
+    "@ckeditor/ckeditor5-ui": "^18.0.0",
+    "@ckeditor/ckeditor5-widget": "^18.0.0",
     "lodash-es": "^4.17.10"
     "lodash-es": "^4.17.10"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@ckeditor/ckeditor5-alignment": "^17.0.0",
-    "@ckeditor/ckeditor5-block-quote": "^17.0.0",
-    "@ckeditor/ckeditor5-clipboard": "^17.0.0",
-    "@ckeditor/ckeditor5-editor-classic": "^17.0.0",
-    "@ckeditor/ckeditor5-engine": "^17.0.0",
-    "@ckeditor/ckeditor5-image": "^17.0.0",
-    "@ckeditor/ckeditor5-indent": "^17.0.0",
-    "@ckeditor/ckeditor5-list": "^17.0.0",
-    "@ckeditor/ckeditor5-media-embed": "^17.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^17.0.0",
-    "@ckeditor/ckeditor5-typing": "^17.0.0",
-    "@ckeditor/ckeditor5-undo": "^17.0.0",
-    "@ckeditor/ckeditor5-utils": "^17.0.0",
+    "@ckeditor/ckeditor5-alignment": "^18.0.0",
+    "@ckeditor/ckeditor5-block-quote": "^18.0.0",
+    "@ckeditor/ckeditor5-clipboard": "^18.0.0",
+    "@ckeditor/ckeditor5-editor-classic": "^18.0.0",
+    "@ckeditor/ckeditor5-engine": "^18.0.0",
+    "@ckeditor/ckeditor5-horizontal-line": "^18.0.0",
+    "@ckeditor/ckeditor5-image": "^18.0.0",
+    "@ckeditor/ckeditor5-indent": "^18.0.0",
+    "@ckeditor/ckeditor5-list": "^18.0.0",
+    "@ckeditor/ckeditor5-media-embed": "^18.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^18.0.0",
+    "@ckeditor/ckeditor5-typing": "^18.0.0",
+    "@ckeditor/ckeditor5-undo": "^18.0.0",
+    "@ckeditor/ckeditor5-utils": "^18.0.0",
     "eslint": "^5.5.0",
     "eslint": "^5.5.0",
     "eslint-config-ckeditor5": "^2.0.0",
     "eslint-config-ckeditor5": "^2.0.0",
     "husky": "^1.3.1",
     "husky": "^1.3.1",

+ 5 - 4
packages/ckeditor5-table/src/commands/insertcolumncommand.js

@@ -70,15 +70,16 @@ export default class InsertColumnCommand extends Command {
 		const editor = this.editor;
 		const editor = this.editor;
 		const selection = editor.model.document.selection;
 		const selection = editor.model.document.selection;
 		const tableUtils = editor.plugins.get( 'TableUtils' );
 		const tableUtils = editor.plugins.get( 'TableUtils' );
+		const insertBefore = this.order === 'left';
 
 
-		const firstPosition = selection.getFirstPosition();
+		const referencePosition = insertBefore ? selection.getFirstPosition() : selection.getLastPosition();
+		const referenceRange = insertBefore ? selection.getFirstRange() : selection.getLastRange();
 
 
-		const tableCell = findAncestor( 'tableCell', firstPosition );
+		const tableCell = referenceRange.getContainedElement() || findAncestor( 'tableCell', referencePosition );
 		const table = tableCell.parent.parent;
 		const table = tableCell.parent.parent;
 
 
 		const { column } = tableUtils.getCellLocation( tableCell );
 		const { column } = tableUtils.getCellLocation( tableCell );
-		const insertAt = this.order === 'right' ? column + 1 : column;
 
 
-		tableUtils.insertColumns( table, { columns: 1, at: insertAt } );
+		tableUtils.insertColumns( table, { columns: 1, at: insertBefore ? column : column + 1 } );
 	}
 	}
 }
 }

+ 6 - 3
packages/ckeditor5-table/src/commands/insertrowcommand.js

@@ -69,14 +69,17 @@ export default class InsertRowCommand extends Command {
 		const editor = this.editor;
 		const editor = this.editor;
 		const selection = editor.model.document.selection;
 		const selection = editor.model.document.selection;
 		const tableUtils = editor.plugins.get( 'TableUtils' );
 		const tableUtils = editor.plugins.get( 'TableUtils' );
+		const insertAbove = this.order === 'above';
 
 
-		const tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
+		const referencePosition = insertAbove ? selection.getFirstPosition() : selection.getLastPosition();
+		const referenceRange = insertAbove ? selection.getFirstRange() : selection.getLastRange();
+
+		const tableCell = referenceRange.getContainedElement() || findAncestor( 'tableCell', referencePosition );
 		const tableRow = tableCell.parent;
 		const tableRow = tableCell.parent;
 		const table = tableRow.parent;
 		const table = tableRow.parent;
 
 
 		const row = table.getChildIndex( tableRow );
 		const row = table.getChildIndex( tableRow );
-		const insertAt = this.order === 'below' ? row + 1 : row;
 
 
-		tableUtils.insertRows( table, { rows: 1, at: insertAt } );
+		tableUtils.insertRows( table, { rows: 1, at: this.order === 'below' ? row + 1 : row } );
 	}
 	}
 }
 }

+ 12 - 9
packages/ckeditor5-table/src/commands/mergecellcommand.js

@@ -9,7 +9,11 @@
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import TableWalker from '../tablewalker';
 import TableWalker from '../tablewalker';
-import { findAncestor, updateNumericAttribute } from './utils';
+import {
+	updateNumericAttribute,
+	isHeadingColumnCell
+} from './utils';
+import { getTableCellsContainingSelection } from '../utils';
 
 
 /**
 /**
  * The merge cell command.
  * The merge cell command.
@@ -78,7 +82,7 @@ export default class MergeCellCommand extends Command {
 	execute() {
 	execute() {
 		const model = this.editor.model;
 		const model = this.editor.model;
 		const doc = model.document;
 		const doc = model.document;
-		const tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );
+		const tableCell = getTableCellsContainingSelection( doc.selection )[ 0 ];
 		const cellToMerge = this.value;
 		const cellToMerge = this.value;
 		const direction = this.direction;
 		const direction = this.direction;
 
 
@@ -118,7 +122,7 @@ export default class MergeCellCommand extends Command {
 	_getMergeableCell() {
 	_getMergeableCell() {
 		const model = this.editor.model;
 		const model = this.editor.model;
 		const doc = model.document;
 		const doc = model.document;
-		const tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );
+		const tableCell = getTableCellsContainingSelection( doc.selection )[ 0 ];
 
 
 		if ( !tableCell ) {
 		if ( !tableCell ) {
 			return;
 			return;
@@ -156,7 +160,7 @@ function getHorizontalCell( tableCell, direction, tableUtils ) {
 	const tableRow = tableCell.parent;
 	const tableRow = tableCell.parent;
 	const table = tableRow.parent;
 	const table = tableRow.parent;
 	const horizontalCell = direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;
 	const horizontalCell = direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;
-	const headingColumns = table.getAttribute( 'headingColumns' ) || 0;
+	const hasHeadingColumns = ( table.getAttribute( 'headingColumns' ) || 0 ) > 0;
 
 
 	if ( !horizontalCell ) {
 	if ( !horizontalCell ) {
 		return;
 		return;
@@ -171,13 +175,12 @@ function getHorizontalCell( tableCell, direction, tableUtils ) {
 	const { column: rightCellColumn } = tableUtils.getCellLocation( cellOnRight );
 	const { column: rightCellColumn } = tableUtils.getCellLocation( cellOnRight );
 
 
 	const leftCellSpan = parseInt( cellOnLeft.getAttribute( 'colspan' ) || 1 );
 	const leftCellSpan = parseInt( cellOnLeft.getAttribute( 'colspan' ) || 1 );
-	const rightCellSpan = parseInt( cellOnRight.getAttribute( 'colspan' ) || 1 );
 
 
-	// We cannot merge cells if the result will extend over heading section.
-	const isMergeWithBodyCell = direction == 'right' && ( rightCellColumn + rightCellSpan > headingColumns );
-	const isMergeWithHeadCell = direction == 'left' && ( leftCellColumn + leftCellSpan > headingColumns - 1 );
+	const isCellOnLeftInHeadingColumn = isHeadingColumnCell( tableUtils, cellOnLeft, table );
+	const isCellOnRightInHeadingColumn = isHeadingColumnCell( tableUtils, cellOnRight, table );
 
 
-	if ( headingColumns && ( isMergeWithBodyCell || isMergeWithHeadCell ) ) {
+	// We cannot merge heading columns cells with regular cells.
+	if ( hasHeadingColumns && isCellOnLeftInHeadingColumn != isCellOnRightInHeadingColumn ) {
 		return;
 		return;
 	}
 	}
 
 

+ 241 - 0
packages/ckeditor5-table/src/commands/mergecellscommand.js

@@ -0,0 +1,241 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module table/commands/mergecellscommand
+ */
+
+import Command from '@ckeditor/ckeditor5-core/src/command';
+import TableWalker from '../tablewalker';
+import { findAncestor, updateNumericAttribute } from './utils';
+import TableUtils from '../tableutils';
+import { getRowIndexes, getSelectedTableCells } from '../utils';
+
+/**
+ * The merge cells command.
+ *
+ * The command is registered by the {@link module:table/tableediting~TableEditing} as `'mergeTableCells'` editor command.
+ *
+ * For example, to merge selected table cells:
+ *
+ *		editor.execute( 'mergeTableCells' );
+ *
+ * @extends module:core/command~Command
+ */
+export default class MergeCellsCommand extends Command {
+	/**
+	 * @inheritDoc
+	 */
+	refresh() {
+		this.isEnabled = canMergeCells( this.editor.model.document.selection, this.editor.plugins.get( TableUtils ) );
+	}
+
+	/**
+	 * Executes the command.
+	 *
+	 * @fires execute
+	 */
+	execute() {
+		const model = this.editor.model;
+		const tableUtils = this.editor.plugins.get( TableUtils );
+
+		model.change( writer => {
+			const selectedTableCells = getSelectedTableCells( model.document.selection );
+
+			// All cells will be merge into the first one.
+			const firstTableCell = selectedTableCells.shift();
+
+			// This prevents the "model-selection-range-intersects" error, caused by removing row selected cells.
+			writer.setSelection( firstTableCell, 'on' );
+
+			// Update target cell dimensions.
+			const { mergeWidth, mergeHeight } = getMergeDimensions( firstTableCell, selectedTableCells, tableUtils );
+			updateNumericAttribute( 'colspan', mergeWidth, firstTableCell, writer );
+			updateNumericAttribute( 'rowspan', mergeHeight, firstTableCell, writer );
+
+			for ( const tableCell of selectedTableCells ) {
+				const tableRow = tableCell.parent;
+				mergeTableCells( tableCell, firstTableCell, writer );
+				removeRowIfEmpty( tableRow, writer );
+			}
+
+			writer.setSelection( firstTableCell, 'in' );
+		} );
+	}
+}
+
+// Properly removes the empty row from a table. Updates the `rowspan` attribute of cells that overlap the removed row.
+//
+// @param {module:engine/model/element~Element} row
+// @param {module:engine/model/writer~Writer} writer
+function removeRowIfEmpty( row, writer ) {
+	if ( row.childCount ) {
+		return;
+	}
+
+	const table = row.parent;
+	const removedRowIndex = table.getChildIndex( row );
+
+	for ( const { cell, row, rowspan } of new TableWalker( table, { endRow: removedRowIndex } ) ) {
+		const overlapsRemovedRow = row + rowspan - 1 >= removedRowIndex;
+
+		if ( overlapsRemovedRow ) {
+			updateNumericAttribute( 'rowspan', rowspan - 1, cell, writer );
+		}
+	}
+
+	writer.remove( row );
+}
+
+// Merges two table cells - will ensure that after merging cells with empty paragraphs the result table cell will only have one paragraph.
+// If one of the merged table cells is empty, the merged table cell will have contents of the non-empty table cell.
+// If both are empty, the merged table cell will have only one empty paragraph.
+//
+// @param {module:engine/model/element~Element} cellBeingMerged
+// @param {module:engine/model/element~Element} targetCell
+// @param {module:engine/model/writer~Writer} writer
+function mergeTableCells( cellBeingMerged, targetCell, writer ) {
+	if ( !isEmpty( cellBeingMerged ) ) {
+		if ( isEmpty( targetCell ) ) {
+			writer.remove( writer.createRangeIn( targetCell ) );
+		}
+
+		writer.move( writer.createRangeIn( cellBeingMerged ), writer.createPositionAt( targetCell, 'end' ) );
+	}
+
+	// Remove merged table cell.
+	writer.remove( cellBeingMerged );
+}
+
+// Checks if the passed table cell contains an empty paragraph.
+//
+// @param {module:engine/model/element~Element} tableCell
+// @returns {Boolean}
+function isEmpty( tableCell ) {
+	return tableCell.childCount == 1 && tableCell.getChild( 0 ).is( 'paragraph' ) && tableCell.getChild( 0 ).isEmpty;
+}
+
+// Checks if the selection contains mergeable cells.
+//
+// In a table below:
+//
+//   ┌───┬───┬───┬───┐
+//   │ a │ b │ c │ d │
+//   ├───┴───┼───┤   │
+//   │ e     │ f │   │
+//   ├       ├───┼───┤
+//   │       │ g │ h │
+//   └───────┴───┴───┘
+//
+// Valid selections are these which create a solid rectangle (without gaps), such as:
+//   - a, b (two horizontal cells)
+//   - c, f (two vertical cells)
+//   - a, b, e (cell "e" spans over four cells)
+//   - c, d, f (cell d spans over a cell in the row below)
+//
+// While an invalid selection would be:
+//   - a, c (cell "b" not selected creates a gap)
+//   - f, g, h (cell "d" spans over a cell from row of "f" cell - thus creates a gap)
+//
+// @param {module:engine/model/selection~Selection} selection
+// @param {module:table/tableUtils~TableUtils} tableUtils
+// @returns {boolean}
+function canMergeCells( selection, tableUtils ) {
+	const selectedTableCells = getSelectedTableCells( selection );
+
+	if ( selectedTableCells.length < 2 || !areCellInTheSameTableSection( selectedTableCells ) ) {
+		return false;
+	}
+
+	// A valid selection is a fully occupied rectangle composed of table cells.
+	// Below we will calculate the area of a selected table cells and the area of valid selection.
+	// The area of a valid selection is defined by top-left and bottom-right cells.
+	const rows = new Set();
+	const columns = new Set();
+
+	let areaOfSelectedCells = 0;
+
+	for ( const tableCell of selectedTableCells ) {
+		const { row, column } = tableUtils.getCellLocation( tableCell );
+		const rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );
+		const colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
+
+		// Record row & column indexes of current cell.
+		rows.add( row );
+		columns.add( column );
+
+		// For cells that spans over multiple rows add also the last row that this cell spans over.
+		if ( rowspan > 1 ) {
+			rows.add( row + rowspan - 1 );
+		}
+
+		// For cells that spans over multiple columns add also the last column that this cell spans over.
+		if ( colspan > 1 ) {
+			columns.add( column + colspan - 1 );
+		}
+
+		areaOfSelectedCells += ( rowspan * colspan );
+	}
+
+	// We can only merge table cells that are in adjacent rows...
+	const areaOfValidSelection = getBiggestRectangleArea( rows, columns );
+
+	return areaOfValidSelection == areaOfSelectedCells;
+}
+
+// Calculates the area of a maximum rectangle that can span over provided row & column indexes.
+//
+// @param {Array.<Number>} rows
+// @param {Array.<Number>} columns
+// @returns {Number}
+function getBiggestRectangleArea( rows, columns ) {
+	const rowsIndexes = Array.from( rows.values() );
+	const columnIndexes = Array.from( columns.values() );
+
+	const lastRow = Math.max( ...rowsIndexes );
+	const firstRow = Math.min( ...rowsIndexes );
+	const lastColumn = Math.max( ...columnIndexes );
+	const firstColumn = Math.min( ...columnIndexes );
+
+	return ( lastRow - firstRow + 1 ) * ( lastColumn - firstColumn + 1 );
+}
+
+function areCellInTheSameTableSection( tableCells ) {
+	const table = findAncestor( 'table', tableCells[ 0 ] );
+
+	const rowIndexes = getRowIndexes( tableCells );
+	const headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );
+
+	const firstCellIsInBody = rowIndexes.first > headingRows - 1;
+	const lastCellIsInBody = rowIndexes.last > headingRows - 1;
+
+	return firstCellIsInBody === lastCellIsInBody;
+}
+
+function getMergeDimensions( firstTableCell, selectedTableCells, tableUtils ) {
+	let maxWidthOffset = 0;
+	let maxHeightOffset = 0;
+
+	for ( const tableCell of selectedTableCells ) {
+		const { row, column } = tableUtils.getCellLocation( tableCell );
+
+		maxWidthOffset = getMaxOffset( tableCell, column, maxWidthOffset, 'colspan' );
+		maxHeightOffset = getMaxOffset( tableCell, row, maxHeightOffset, 'rowspan' );
+	}
+
+	// Update table cell span attribute and merge set selection on a merged contents.
+	const { row: firstCellRow, column: firstCellColumn } = tableUtils.getCellLocation( firstTableCell );
+
+	const mergeWidth = maxWidthOffset - firstCellColumn;
+	const mergeHeight = maxHeightOffset - firstCellRow;
+
+	return { mergeWidth, mergeHeight };
+}
+
+function getMaxOffset( tableCell, start, currentMaxOffset, which ) {
+	const dimensionValue = parseInt( tableCell.getAttribute( which ) || 1 );
+
+	return Math.max( currentMaxOffset, start + dimensionValue );
+}

+ 117 - 41
packages/ckeditor5-table/src/commands/removecolumncommand.js

@@ -10,7 +10,8 @@
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 
 
 import TableWalker from '../tablewalker';
 import TableWalker from '../tablewalker';
-import { findAncestor, updateNumericAttribute } from './utils';
+import { updateNumericAttribute } from './utils';
+import { getSelectionAffectedTableCells } from '../utils';
 
 
 /**
 /**
  * The remove column command.
  * The remove column command.
@@ -28,69 +29,144 @@ export default class RemoveColumnCommand extends Command {
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
 	refresh() {
 	refresh() {
-		const editor = this.editor;
-		const selection = editor.model.document.selection;
-		const tableUtils = editor.plugins.get( 'TableUtils' );
-
-		const tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
-
-		this.isEnabled = !!tableCell && tableUtils.getColumns( tableCell.parent.parent ) > 1;
+		const selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );
+		const firstCell = selectedCells[ 0 ];
+
+		if ( firstCell ) {
+			const table = firstCell.parent.parent;
+			const tableColumnCount = this.editor.plugins.get( 'TableUtils' ).getColumns( table );
+
+			const tableMap = [ ...new TableWalker( table ) ];
+			const columnIndexes = tableMap.filter( entry => selectedCells.includes( entry.cell ) ).map( el => el.column ).sort();
+			const minColumnIndex = columnIndexes[ 0 ];
+			const maxColumnIndex = columnIndexes[ columnIndexes.length - 1 ];
+
+			this.isEnabled = maxColumnIndex - minColumnIndex < ( tableColumnCount - 1 );
+		} else {
+			this.isEnabled = false;
+		}
 	}
 	}
 
 
 	/**
 	/**
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
 	execute() {
 	execute() {
-		const model = this.editor.model;
-		const selection = model.document.selection;
+		const [ firstCell, lastCell ] = getBoundaryCells( this.editor.model.document.selection );
+		const table = firstCell.parent.parent;
 
 
-		const firstPosition = selection.getFirstPosition();
+		// Cache the table before removing or updating colspans.
+		const tableMap = [ ...new TableWalker( table ) ];
 
 
-		const tableCell = findAncestor( 'tableCell', firstPosition );
-		const tableRow = tableCell.parent;
-		const table = tableRow.parent;
+		// Store column indexes of removed columns.
+		const removedColumnIndexes = {
+			first: tableMap.find( value => value.cell === firstCell ).column,
+			last: tableMap.find( value => value.cell === lastCell ).column
+		};
 
 
-		const headingColumns = table.getAttribute( 'headingColumns' ) || 0;
+		const cellToFocus = getCellToFocus( tableMap, firstCell, lastCell, removedColumnIndexes );
 
 
-		// Cache the table before removing or updating colspans.
-		const tableMap = [ ...new TableWalker( table ) ];
+		this.editor.model.change( writer => {
+			// A temporary workaround to avoid the "model-selection-range-intersects" error.
+			writer.setSelection( writer.createRangeOn( table ) );
 
 
-		// Get column index of removed column.
-		const cellData = tableMap.find( value => value.cell === tableCell );
-		const removedColumn = cellData.column;
-		const selectionRow = cellData.row;
-		const cellToFocus = getCellToFocus( tableCell );
+			adjustHeadingColumns( table, removedColumnIndexes, writer );
 
 
-		model.change( writer => {
-			// Update heading columns attribute if removing a row from head section.
-			if ( headingColumns && selectionRow <= headingColumns ) {
-				writer.setAttribute( 'headingColumns', headingColumns - 1, table );
+			for (
+				let removedColumnIndex = removedColumnIndexes.last;
+				removedColumnIndex >= removedColumnIndexes.first;
+				removedColumnIndex--
+			) {
+				this._removeColumn( removedColumnIndex, table, writer );
 			}
 			}
 
 
-			for ( const { cell, column, colspan } of tableMap ) {
-				// If colspaned cell overlaps removed column decrease it's span.
-				if ( column <= removedColumn && colspan > 1 && column + colspan > removedColumn ) {
-					updateNumericAttribute( 'colspan', colspan - 1, cell, writer );
-				} else if ( column === removedColumn ) {
-					// The cell in removed column has colspan of 1.
-					writer.remove( cell );
+			writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
+		} );
+	}
+
+	/**
+	 * Removes a column from the given `table`.
+	 *
+	 * @private
+	 * @param {Number} removedColumnIndex Index of the column that should be removed.
+	 * @param {module:engine/model/element~Element} table
+	 * @param {module:engine/model/writer~Writer} writer
+	 */
+	_removeColumn( removedColumnIndex, table, writer ) {
+		for ( const { cell, column, colspan } of new TableWalker( table ) ) {
+			// If colspaned cell overlaps removed column decrease its span.
+			if ( column <= removedColumnIndex && colspan > 1 && column + colspan > removedColumnIndex ) {
+				updateNumericAttribute( 'colspan', colspan - 1, cell, writer );
+			} else if ( column === removedColumnIndex ) {
+				const cellRow = cell.parent;
+
+				// The cell in removed column has colspan of 1.
+				writer.remove( cell );
+
+				// If the cell was the last one in the row, get rid of the entire row.
+				// https://github.com/ckeditor/ckeditor5/issues/6429
+				if ( !cellRow.childCount ) {
+					writer.remove( cellRow );
 				}
 				}
 			}
 			}
+		}
+	}
+}
 
 
-			writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
-		} );
+// Updates heading columns attribute if removing a row from head section.
+function adjustHeadingColumns( table, removedColumnIndexes, writer ) {
+	const headingColumns = table.getAttribute( 'headingColumns' ) || 0;
+
+	if ( headingColumns && removedColumnIndexes.first <= headingColumns ) {
+		const headingsRemoved = Math.min( headingColumns - 1 /* Other numbers are 0-based */, removedColumnIndexes.last ) -
+			removedColumnIndexes.first + 1;
+
+		writer.setAttribute( 'headingColumns', headingColumns - headingsRemoved, table );
 	}
 	}
 }
 }
 
 
-// Returns a proper table cell to focus after removing a column. It should be a next sibling to selection visually stay in place but:
+// Returns a proper table cell to focus after removing a column.
 // - selection is on last table cell it will return previous cell.
 // - selection is on last table cell it will return previous cell.
-// - table cell is spanned over 2+ columns - it will be truncated so the selection should stay in that cell.
-function getCellToFocus( tableCell ) {
-	const colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
+function getCellToFocus( tableMap, firstCell, lastCell, removedColumnIndexes ) {
+	const colspan = parseInt( lastCell.getAttribute( 'colspan' ) || 1 );
 
 
+	// If the table cell is spanned over 2+ columns - it will be truncated so the selection should
+	// stay in that cell.
 	if ( colspan > 1 ) {
 	if ( colspan > 1 ) {
-		return tableCell;
+		return lastCell;
 	}
 	}
+	// Normally, look for the cell in the same row that precedes the first cell to put selection there ("column on the left").
+	// If the deleted column is the first column of the table, there will be no predecessor: use the cell
+	// from the column that follows then (also in the same row).
+	else if ( firstCell.previousSibling || lastCell.nextSibling ) {
+		return lastCell.nextSibling || firstCell.previousSibling;
+	}
+	// It can happen that table cells have no siblings in a row, for instance, when there are row spans
+	// in the table (in the previous row). Then just look for the closest cell that is in a column
+	// that will not be removed to put the selection there.
+	else {
+		// Look for any cell in a column that precedes the first removed column.
+		if ( removedColumnIndexes.first ) {
+			return tableMap.reverse().find( ( { column } ) => {
+				return column < removedColumnIndexes.first;
+			} ).cell;
+		}
+		// If the first removed column is the first column of the table, then
+		// look for any cell that is in a column that follows the last removed column.
+		else {
+			return tableMap.reverse().find( ( { column } ) => {
+				return column > removedColumnIndexes.last;
+			} ).cell;
+		}
+	}
+}
+
+// Returns helper object returning the first and the last cell contained in given selection, based on DOM order.
+function getBoundaryCells( selection ) {
+	const referenceCells = getSelectionAffectedTableCells( selection );
+	const firstCell = referenceCells[ 0 ];
+	const lastCell = referenceCells.pop();
+
+	const returnValue = [ firstCell, lastCell ];
 
 
-	return tableCell.nextSibling ? tableCell.nextSibling : tableCell.previousSibling;
+	return firstCell.isBefore( lastCell ) ? returnValue : returnValue.reverse();
 }
 }

+ 99 - 53
packages/ckeditor5-table/src/commands/removerowcommand.js

@@ -11,6 +11,7 @@ import Command from '@ckeditor/ckeditor5-core/src/command';
 
 
 import TableWalker from '../tablewalker';
 import TableWalker from '../tablewalker';
 import { findAncestor, updateNumericAttribute } from './utils';
 import { findAncestor, updateNumericAttribute } from './utils';
+import { getRowIndexes, getSelectionAffectedTableCells } from '../utils';
 
 
 /**
 /**
  * The remove row command.
  * The remove row command.
@@ -28,12 +29,23 @@ export default class RemoveRowCommand extends Command {
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
 	refresh() {
 	refresh() {
-		const model = this.editor.model;
-		const doc = model.document;
+		const selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );
+		const firstCell = selectedCells[ 0 ];
+
+		if ( firstCell ) {
+			const table = findAncestor( 'table', firstCell );
+			const tableRowCount = this.editor.plugins.get( 'TableUtils' ).getRows( table );
+			const lastRowIndex = tableRowCount - 1;
 
 
-		const tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );
+			const selectedRowIndexes = getRowIndexes( selectedCells );
 
 
-		this.isEnabled = !!tableCell && tableCell.parent.parent.childCount > 1;
+			const areAllRowsSelected = selectedRowIndexes.first === 0 && selectedRowIndexes.last === lastRowIndex;
+
+			// Disallow selecting whole table -> delete whole table should be used instead.
+			this.isEnabled = !areAllRowsSelected;
+		} else {
+			this.isEnabled = false;
+		}
 	}
 	}
 
 
 	/**
 	/**
@@ -41,73 +53,96 @@ export default class RemoveRowCommand extends Command {
 	 */
 	 */
 	execute() {
 	execute() {
 		const model = this.editor.model;
 		const model = this.editor.model;
-		const selection = model.document.selection;
-
-		const firstPosition = selection.getFirstPosition();
-		const tableCell = findAncestor( 'tableCell', firstPosition );
-		const tableRow = tableCell.parent;
-		const table = tableRow.parent;
-
-		const removedRow = table.getChildIndex( tableRow );
-
-		const tableMap = [ ...new TableWalker( table, { endRow: removedRow } ) ];
+		const referenceCells = getSelectionAffectedTableCells( model.document.selection );
+		const removedRowIndexes = getRowIndexes( referenceCells );
 
 
-		const cellData = tableMap.find( value => value.cell === tableCell );
+		const firstCell = referenceCells[ 0 ];
+		const table = findAncestor( 'table', firstCell );
 
 
-		const headingRows = table.getAttribute( 'headingRows' ) || 0;
-
-		const columnToFocus = cellData.column;
+		const columnIndexToFocus = this.editor.plugins.get( 'TableUtils' ).getCellLocation( firstCell ).column;
 
 
 		model.change( writer => {
 		model.change( writer => {
-			if ( headingRows && removedRow <= headingRows ) {
-				updateNumericAttribute( 'headingRows', headingRows - 1, table, writer, 0 );
-			}
-
-			const cellsToMove = new Map();
+			// This prevents the "model-selection-range-intersects" error, caused by removing row selected cells.
+			writer.setSelection( writer.createSelection( table, 'on' ) );
 
 
-			// Get cells from removed row that are spanned over multiple rows.
-			tableMap
-				.filter( ( { row, rowspan } ) => row === removedRow && rowspan > 1 )
-				.forEach( ( { column, cell, rowspan } ) => cellsToMove.set( column, { cell, rowspanToSet: rowspan - 1 } ) );
+			let cellToFocus;
 
 
-			// Reduce rowspan on cells that are above removed row and overlaps removed row.
-			tableMap
-				.filter( ( { row, rowspan } ) => row <= removedRow - 1 && row + rowspan > removedRow )
-				.forEach( ( { cell, rowspan } ) => updateNumericAttribute( 'rowspan', rowspan - 1, cell, writer ) );
+			for ( let i = removedRowIndexes.last; i >= removedRowIndexes.first; i-- ) {
+				const removedRowIndex = i;
+				this._removeRow( removedRowIndex, table, writer );
 
 
-			// Move cells to another row.
-			const targetRow = removedRow + 1;
-			const tableWalker = new TableWalker( table, { includeSpanned: true, startRow: targetRow, endRow: targetRow } );
-
-			let previousCell;
+				cellToFocus = getCellToFocus( table, removedRowIndex, columnIndexToFocus );
+			}
 
 
-			for ( const { row, column, cell } of [ ...tableWalker ] ) {
-				if ( cellsToMove.has( column ) ) {
-					const { cell: cellToMove, rowspanToSet } = cellsToMove.get( column );
-					const targetPosition = previousCell ?
-						writer.createPositionAfter( previousCell ) :
-						writer.createPositionAt( table.getChild( row ), 0 );
+			const model = this.editor.model;
+			const headingRows = table.getAttribute( 'headingRows' ) || 0;
 
 
-					writer.move( writer.createRangeOn( cellToMove ), targetPosition );
-					updateNumericAttribute( 'rowspan', rowspanToSet, cellToMove, writer );
+			if ( headingRows && removedRowIndexes.first < headingRows ) {
+				const newRows = getNewHeadingRowsValue( removedRowIndexes, headingRows );
 
 
-					previousCell = cellToMove;
-				} else {
-					previousCell = cell;
-				}
+				// Must be done after the changes in table structure (removing rows).
+				// Otherwise the downcast converter for headingRows attribute will fail. ckeditor/ckeditor5#6391.
+				model.enqueueChange( writer.batch, writer => {
+					updateNumericAttribute( 'headingRows', newRows, table, writer, 0 );
+				} );
 			}
 			}
 
 
-			writer.remove( tableRow );
-
-			const cellToFocus = getCellToFocus( table, removedRow, columnToFocus );
 			writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
 			writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
 		} );
 		} );
 	}
 	}
+
+	/**
+	 * Removes a row from the given `table`.
+	 *
+	 * @private
+	 * @param {Number} removedRowIndex Index of the row that should be removed.
+	 * @param {module:engine/model/element~Element} table
+	 * @param {module:engine/model/writer~Writer} writer
+	 */
+	_removeRow( removedRowIndex, table, writer ) {
+		const cellsToMove = new Map();
+		const tableRow = table.getChild( removedRowIndex );
+		const tableMap = [ ...new TableWalker( table, { endRow: removedRowIndex } ) ];
+
+		// Get cells from removed row that are spanned over multiple rows.
+		tableMap
+			.filter( ( { row, rowspan } ) => row === removedRowIndex && rowspan > 1 )
+			.forEach( ( { column, cell, rowspan } ) => cellsToMove.set( column, { cell, rowspanToSet: rowspan - 1 } ) );
+
+		// Reduce rowspan on cells that are above removed row and overlaps removed row.
+		tableMap
+			.filter( ( { row, rowspan } ) => row <= removedRowIndex - 1 && row + rowspan > removedRowIndex )
+			.forEach( ( { cell, rowspan } ) => updateNumericAttribute( 'rowspan', rowspan - 1, cell, writer ) );
+
+		// Move cells to another row.
+		const targetRow = removedRowIndex + 1;
+		const tableWalker = new TableWalker( table, { includeSpanned: true, startRow: targetRow, endRow: targetRow } );
+		let previousCell;
+
+		for ( const { row, column, cell } of [ ...tableWalker ] ) {
+			if ( cellsToMove.has( column ) ) {
+				const { cell: cellToMove, rowspanToSet } = cellsToMove.get( column );
+				const targetPosition = previousCell ?
+					writer.createPositionAfter( previousCell ) :
+					writer.createPositionAt( table.getChild( row ), 0 );
+				writer.move( writer.createRangeOn( cellToMove ), targetPosition );
+				updateNumericAttribute( 'rowspan', rowspanToSet, cellToMove, writer );
+				previousCell = cellToMove;
+			}
+			else {
+				previousCell = cell;
+			}
+		}
+
+		writer.remove( tableRow );
+	}
 }
 }
 
 
 // Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.
 // Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.
-function getCellToFocus( table, removedRow, columnToFocus ) {
-	const row = table.getChild( removedRow );
+// * If the row was not the last one, the cell to focus will be in the row that followed it (before removal).
+// * If the row was the last one, the cell to focus will be in the row that preceded it (before removal).
+function getCellToFocus( table, removedRowIndex, columnToFocus ) {
+	const row = table.getChild( removedRowIndex ) || table.getChild( table.childCount - 1 );
 
 
 	// Default to first table cell.
 	// Default to first table cell.
 	let cellToFocus = row.getChild( 0 );
 	let cellToFocus = row.getChild( 0 );
@@ -121,4 +156,15 @@ function getCellToFocus( table, removedRow, columnToFocus ) {
 		cellToFocus = tableCell;
 		cellToFocus = tableCell;
 		column += parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
 		column += parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
 	}
 	}
+
+	return cellToFocus;
+}
+
+// Calculates a new heading rows value for removing rows from heading section.
+function getNewHeadingRowsValue( removedRowIndexes, headingRows ) {
+	if ( removedRowIndexes.last < headingRows ) {
+		return headingRows - ( ( removedRowIndexes.last - removedRowIndexes.first ) + 1 );
+	}
+
+	return removedRowIndexes.first;
 }
 }

+ 65 - 0
packages/ckeditor5-table/src/commands/selectcolumncommand.js

@@ -0,0 +1,65 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module table/commands/selectcolumncommand
+ */
+
+import Command from '@ckeditor/ckeditor5-core/src/command';
+
+import TableWalker from '../tablewalker';
+import { findAncestor } from './utils';
+import { getSelectionAffectedTableCells } from '../utils';
+
+/**
+ * The select column command.
+ *
+ * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableColumn'` editor command.
+ *
+ * To select the columns containing the selected cells, execute the command:
+ *
+ *		editor.execute( 'selectTableColumn' );
+ *
+ * @extends module:core/command~Command
+ */
+export default class SelectColumnCommand extends Command {
+	/**
+	 * @inheritDoc
+	 */
+	refresh() {
+		const selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );
+
+		this.isEnabled = selectedCells.length > 0;
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	execute() {
+		const model = this.editor.model;
+		const referenceCells = getSelectionAffectedTableCells( model.document.selection );
+		const firstCell = referenceCells[ 0 ];
+		const lastCell = referenceCells.pop();
+
+		const tableUtils = this.editor.plugins.get( 'TableUtils' );
+		const startLocation = tableUtils.getCellLocation( firstCell );
+		const endLocation = tableUtils.getCellLocation( lastCell );
+
+		const startColumn = Math.min( startLocation.column, endLocation.column );
+		const endColumn = Math.max( startLocation.column, endLocation.column );
+
+		const rangesToSelect = [];
+
+		for ( const cellInfo of new TableWalker( findAncestor( 'table', firstCell ) ) ) {
+			if ( cellInfo.column >= startColumn && cellInfo.column <= endColumn ) {
+				rangesToSelect.push( model.createRangeOn( cellInfo.cell ) );
+			}
+		}
+
+		model.change( writer => {
+			writer.setSelection( rangesToSelect );
+		} );
+	}
+}

+ 57 - 0
packages/ckeditor5-table/src/commands/selectrowcommand.js

@@ -0,0 +1,57 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module table/commands/selectrowcommand
+ */
+
+import Command from '@ckeditor/ckeditor5-core/src/command';
+
+import { findAncestor } from './utils';
+import { getRowIndexes, getSelectionAffectedTableCells } from '../utils';
+
+/**
+ * The select row command.
+ *
+ * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableRow'` editor command.
+ *
+ * To select the rows containing the selected cells, execute the command:
+ *
+ *		editor.execute( 'selectTableRow' );
+ *
+ * @extends module:core/command~Command
+ */
+export default class SelectRowCommand extends Command {
+	/**
+	 * @inheritDoc
+	 */
+	refresh() {
+		const selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );
+
+		this.isEnabled = selectedCells.length > 0;
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	execute() {
+		const model = this.editor.model;
+		const referenceCells = getSelectionAffectedTableCells( model.document.selection );
+		const rowIndexes = getRowIndexes( referenceCells );
+
+		const table = findAncestor( 'table', referenceCells[ 0 ] );
+		const rangesToSelect = [];
+
+		for ( let rowIndex = rowIndexes.first; rowIndex <= rowIndexes.last; rowIndex++ ) {
+			for ( const cell of table.getChild( rowIndex ).getChildren() ) {
+				rangesToSelect.push( model.createRangeOn( cell ) );
+			}
+		}
+
+		model.change( writer => {
+			writer.setSelection( rangesToSelect );
+		} );
+	}
+}

+ 17 - 34
packages/ckeditor5-table/src/commands/setheadercolumncommand.js

@@ -9,7 +9,11 @@
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 
 
-import { findAncestor, updateNumericAttribute } from './utils';
+import {
+	updateNumericAttribute,
+	isHeadingColumnCell
+} from './utils';
+import { getSelectionAffectedTableCells } from '../utils';
 
 
 /**
 /**
  * The header column command.
  * The header column command.
@@ -32,13 +36,9 @@ export default class SetHeaderColumnCommand extends Command {
 	 */
 	 */
 	refresh() {
 	refresh() {
 		const model = this.editor.model;
 		const model = this.editor.model;
-		const doc = model.document;
-		const selection = doc.selection;
-
-		const position = selection.getFirstPosition();
-		const tableCell = findAncestor( 'tableCell', position );
-
-		const isInTable = !!tableCell;
+		const selectedCells = getSelectionAffectedTableCells( model.document.selection );
+		const tableUtils = this.editor.plugins.get( 'TableUtils' );
+		const isInTable = selectedCells.length > 0;
 
 
 		this.isEnabled = isInTable;
 		this.isEnabled = isInTable;
 
 
@@ -50,7 +50,7 @@ export default class SetHeaderColumnCommand extends Command {
 		 * @readonly
 		 * @readonly
 		 * @member {Boolean} #value
 		 * @member {Boolean} #value
 		 */
 		 */
-		this.value = isInTable && this._isInHeading( tableCell, tableCell.parent.parent );
+		this.value = isInTable && selectedCells.every( cell => isHeadingColumnCell( tableUtils, cell ) );
 	}
 	}
 
 
 	/**
 	/**
@@ -67,43 +67,26 @@ export default class SetHeaderColumnCommand extends Command {
 	 */
 	 */
 	execute( options = {} ) {
 	execute( options = {} ) {
 		const model = this.editor.model;
 		const model = this.editor.model;
-		const doc = model.document;
-		const selection = doc.selection;
 		const tableUtils = this.editor.plugins.get( 'TableUtils' );
 		const tableUtils = this.editor.plugins.get( 'TableUtils' );
 
 
-		const position = selection.getFirstPosition();
-		const tableCell = findAncestor( 'tableCell', position );
-		const tableRow = tableCell.parent;
+		const selectedCells = getSelectionAffectedTableCells( model.document.selection );
+		const firstCell = selectedCells[ 0 ];
+		const lastCell = selectedCells[ selectedCells.length - 1 ];
+		const tableRow = firstCell.parent;
 		const table = tableRow.parent;
 		const table = tableRow.parent;
 
 
-		const { column: selectionColumn } = tableUtils.getCellLocation( tableCell );
+		const [ selectedColumnMin, selectedColumnMax ] =
+			// Returned cells might not necessary be in order, so make sure to sort it.
+			[ tableUtils.getCellLocation( firstCell ).column, tableUtils.getCellLocation( lastCell ).column ].sort();
 
 
 		if ( options.forceValue === this.value ) {
 		if ( options.forceValue === this.value ) {
 			return;
 			return;
 		}
 		}
 
 
-		const headingColumnsToSet = this.value ? selectionColumn : selectionColumn + 1;
+		const headingColumnsToSet = this.value ? selectedColumnMin : selectedColumnMax + 1;
 
 
 		model.change( writer => {
 		model.change( writer => {
 			updateNumericAttribute( 'headingColumns', headingColumnsToSet, table, writer, 0 );
 			updateNumericAttribute( 'headingColumns', headingColumnsToSet, table, writer, 0 );
 		} );
 		} );
 	}
 	}
-
-	/**
-	 * Checks if a table cell is in the heading section.
-	 *
-	 * @param {module:engine/model/element~Element} tableCell
-	 * @param {module:engine/model/element~Element} table
-	 * @returns {Boolean}
-	 * @private
-	 */
-	_isInHeading( tableCell, table ) {
-		const headingColumns = parseInt( table.getAttribute( 'headingColumns' ) || 0 );
-
-		const tableUtils = this.editor.plugins.get( 'TableUtils' );
-
-		const { column } = tableUtils.getCellLocation( tableCell );
-
-		return !!headingColumns && column < headingColumns;
-	}
 }
 }

+ 14 - 16
packages/ckeditor5-table/src/commands/setheaderrowcommand.js

@@ -9,7 +9,8 @@
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 
 
-import { createEmptyTableCell, findAncestor, updateNumericAttribute } from './utils';
+import { createEmptyTableCell, updateNumericAttribute } from './utils';
+import { getSelectionAffectedTableCells } from '../utils';
 import TableWalker from '../tablewalker';
 import TableWalker from '../tablewalker';
 
 
 /**
 /**
@@ -32,12 +33,8 @@ export default class SetHeaderRowCommand extends Command {
 	 */
 	 */
 	refresh() {
 	refresh() {
 		const model = this.editor.model;
 		const model = this.editor.model;
-		const doc = model.document;
-		const selection = doc.selection;
-
-		const position = selection.getFirstPosition();
-		const tableCell = findAncestor( 'tableCell', position );
-		const isInTable = !!tableCell;
+		const selectedCells = getSelectionAffectedTableCells( model.document.selection );
+		const isInTable = selectedCells.length > 0;
 
 
 		this.isEnabled = isInTable;
 		this.isEnabled = isInTable;
 
 
@@ -49,7 +46,7 @@ export default class SetHeaderRowCommand extends Command {
 		 * @readonly
 		 * @readonly
 		 * @member {Boolean} #value
 		 * @member {Boolean} #value
 		 */
 		 */
-		this.value = isInTable && this._isInHeading( tableCell, tableCell.parent.parent );
+		this.value = isInTable && selectedCells.every( cell => this._isInHeading( cell, cell.parent.parent ) );
 	}
 	}
 
 
 	/**
 	/**
@@ -66,22 +63,23 @@ export default class SetHeaderRowCommand extends Command {
 	 */
 	 */
 	execute( options = {} ) {
 	execute( options = {} ) {
 		const model = this.editor.model;
 		const model = this.editor.model;
-		const doc = model.document;
-		const selection = doc.selection;
 
 
-		const position = selection.getFirstPosition();
-		const tableCell = findAncestor( 'tableCell', position );
-		const tableRow = tableCell.parent;
-		const table = tableRow.parent;
+		const selectedCells = getSelectionAffectedTableCells( model.document.selection );
+		const firstCell = selectedCells[ 0 ];
+		const lastCell = selectedCells[ selectedCells.length - 1 ];
+		const table = firstCell.parent.parent;
 
 
 		const currentHeadingRows = table.getAttribute( 'headingRows' ) || 0;
 		const currentHeadingRows = table.getAttribute( 'headingRows' ) || 0;
-		const selectionRow = tableRow.index;
+
+		const [ selectedRowMin, selectedRowMax ] =
+			// Returned cells might not necessary be in order, so make sure to sort it.
+			[ firstCell.parent.index, lastCell.parent.index ].sort();
 
 
 		if ( options.forceValue === this.value ) {
 		if ( options.forceValue === this.value ) {
 			return;
 			return;
 		}
 		}
 
 
-		const headingRowsToSet = this.value ? selectionRow : selectionRow + 1;
+		const headingRowsToSet = this.value ? selectedRowMin : selectedRowMax + 1;
 
 
 		model.change( writer => {
 		model.change( writer => {
 			if ( headingRowsToSet ) {
 			if ( headingRowsToSet ) {

+ 6 - 16
packages/ckeditor5-table/src/commands/splitcellcommand.js

@@ -8,7 +8,7 @@
  */
  */
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
-import { findAncestor } from './utils';
+import { getSelectionAffectedTableCells } from '../utils';
 
 
 /**
 /**
  * The split cell command.
  * The split cell command.
@@ -46,30 +46,20 @@ export default class SplitCellCommand extends Command {
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
 	refresh() {
 	refresh() {
-		const model = this.editor.model;
-		const doc = model.document;
+		const selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );
 
 
-		const tableCell = findAncestor( 'tableCell', doc.selection.getFirstPosition() );
-
-		this.isEnabled = !!tableCell;
+		this.isEnabled = selectedCells.length === 1;
 	}
 	}
 
 
 	/**
 	/**
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
 	execute() {
 	execute() {
-		const model = this.editor.model;
-		const document = model.document;
-		const selection = document.selection;
-
-		const firstPosition = selection.getFirstPosition();
-		const tableCell = findAncestor( 'tableCell', firstPosition );
-
-		const isHorizontally = this.direction === 'horizontally';
-
+		const tableCell = getSelectionAffectedTableCells( this.editor.model.document.selection )[ 0 ];
+		const isHorizontal = this.direction === 'horizontally';
 		const tableUtils = this.editor.plugins.get( 'TableUtils' );
 		const tableUtils = this.editor.plugins.get( 'TableUtils' );
 
 
-		if ( isHorizontally ) {
+		if ( isHorizontal ) {
 			tableUtils.splitCellHorizontally( tableCell, 2 );
 			tableUtils.splitCellHorizontally( tableCell, 2 );
 		} else {
 		} else {
 			tableUtils.splitCellVertically( tableCell, 2 );
 			tableUtils.splitCellVertically( tableCell, 2 );

+ 15 - 0
packages/ckeditor5-table/src/commands/utils.js

@@ -114,3 +114,18 @@ export function addDefaultUnitToNumericValue( value, defaultUnit ) {
 
 
 	return `${ numericValue }${ defaultUnit }`;
 	return `${ numericValue }${ defaultUnit }`;
 }
 }
+
+/**
+ * Checks if a table cell belongs to the heading column section.
+ *
+ * @param {module:table/tableutils~TableUtils} tableUtils
+ * @param {module:engine/model/element~Element} tableCell
+ * @returns {Boolean}
+ */
+export function isHeadingColumnCell( tableUtils, tableCell ) {
+	const table = tableCell.parent.parent;
+	const headingColumns = parseInt( table.getAttribute( 'headingColumns' ) || 0 );
+	const { column } = tableUtils.getCellLocation( tableCell );
+
+	return !!headingColumns && column < headingColumns;
+}

+ 6 - 0
packages/ckeditor5-table/src/converters/tableproperties.js

@@ -60,6 +60,12 @@ export function upcastBorderStyles( conversion, viewElementName ) {
 			return;
 			return;
 		}
 		}
 
 
+		// This can happen when the upcasted table is nested table. As to why it happens, it remains a mystery.
+		// Take a look at https://github.com/ckeditor/ckeditor5/issues/6177.
+		if ( !data.modelRange ) {
+			data = Object.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );
+		}
+
 		const modelElement = [ ...data.modelRange.getItems( { shallow: true } ) ].pop();
 		const modelElement = [ ...data.modelRange.getItems( { shallow: true } ) ].pop();
 
 
 		conversionApi.consumable.consume( data.viewItem, matcherPattern );
 		conversionApi.consumable.consume( data.viewItem, matcherPattern );

+ 9 - 3
packages/ckeditor5-table/src/table.js

@@ -11,6 +11,8 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 
 
 import TableEditing from './tableediting';
 import TableEditing from './tableediting';
 import TableUI from './tableui';
 import TableUI from './tableui';
+import TableSelection from './tableselection';
+import TableClipboard from './tableclipboard';
 import Widget from '@ckeditor/ckeditor5-widget/src/widget';
 import Widget from '@ckeditor/ckeditor5-widget/src/widget';
 
 
 import '../theme/table.css';
 import '../theme/table.css';
@@ -20,8 +22,12 @@ import '../theme/table.css';
  *
  *
  * For a detailed overview, check the {@glink features/table Table feature documentation}.
  * For a detailed overview, check the {@glink features/table Table feature documentation}.
  *
  *
- * This is a "glue" plugin that loads the {@link module:table/tableediting~TableEditing table editing feature}
- * and {@link module:table/tableui~TableUI table UI feature}.
+ * This is a "glue" plugin that loads the following table features:
+ *
+ * * {@link module:table/tableediting~TableEditing editing feature},
+ * * {@link module:table/tableselection~TableSelection selection feature},
+ * * {@link module:table/tableclipboard~TableClipboard clipboard feature},
+ * * {@link module:table/tableui~TableUI UI feature}.
  *
  *
  * @extends module:core/plugin~Plugin
  * @extends module:core/plugin~Plugin
  */
  */
@@ -30,7 +36,7 @@ export default class Table extends Plugin {
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
 	static get requires() {
 	static get requires() {
-		return [ TableEditing, TableUI, Widget ];
+		return [ TableEditing, TableUI, TableSelection, TableClipboard, Widget ];
 	}
 	}
 
 
 	/**
 	/**

+ 4 - 1
packages/ckeditor5-table/src/tablecellproperties.js

@@ -12,7 +12,10 @@ import TableCellPropertiesUI from './tablecellproperties/tablecellpropertiesui';
 import TableCellPropertiesEditing from './tablecellproperties/tablecellpropertiesediting';
 import TableCellPropertiesEditing from './tablecellproperties/tablecellpropertiesediting';
 
 
 /**
 /**
- * The table cell properties feature.
+ * The table cell properties feature. Enables support for setting properties of table cells (size, border, background, etc.).
+ *
+ * Read more in the {@glink features/table#table-and-cell-styling-tools Table and cell styling tools} section.
+ * See also the {@link module:table/tableproperties~TableProperties} plugin.
  *
  *
  * This is a "glue" plugin that loads the
  * This is a "glue" plugin that loads the
  * {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing table cell properties editing feature} and
  * {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing table cell properties editing feature} and

+ 22 - 13
packages/ckeditor5-table/src/tablecellproperties/commands/tablecellpropertycommand.js

@@ -8,8 +8,7 @@
  */
  */
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
-
-import { findAncestor } from '../../commands/utils';
+import { getSelectionAffectedTableCells } from '../../utils';
 
 
 /**
 /**
  * The table cell attribute command.
  * The table cell attribute command.
@@ -36,12 +35,10 @@ export default class TableCellPropertyCommand extends Command {
 	 */
 	 */
 	refresh() {
 	refresh() {
 		const editor = this.editor;
 		const editor = this.editor;
-		const selection = editor.model.document.selection;
-
-		const tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
+		const selectedTableCells = getSelectionAffectedTableCells( editor.model.document.selection );
 
 
-		this.isEnabled = !!tableCell;
-		this.value = this._getAttribute( tableCell );
+		this.isEnabled = !!selectedTableCells.length;
+		this.value = this._getSingleValue( selectedTableCells );
 	}
 	}
 
 
 	/**
 	/**
@@ -55,13 +52,9 @@ export default class TableCellPropertyCommand extends Command {
 	 * for example to allow a single undo step for multiple executions.
 	 * for example to allow a single undo step for multiple executions.
 	 */
 	 */
 	execute( options = {} ) {
 	execute( options = {} ) {
-		const model = this.editor.model;
-		const selection = model.document.selection;
-
 		const { value, batch } = options;
 		const { value, batch } = options;
-
-		const tableCells = Array.from( selection.getSelectedBlocks() )
-			.map( element => findAncestor( 'tableCell', model.createPositionAt( element, 0 ) ) );
+		const model = this.editor.model;
+		const tableCells = getSelectionAffectedTableCells( model.document.selection );
 		const valueToSet = this._getValueToSet( value );
 		const valueToSet = this._getValueToSet( value );
 
 
 		model.enqueueChange( batch || 'default', writer => {
 		model.enqueueChange( batch || 'default', writer => {
@@ -98,4 +91,20 @@ export default class TableCellPropertyCommand extends Command {
 	_getValueToSet( value ) {
 	_getValueToSet( value ) {
 		return value;
 		return value;
 	}
 	}
+
+	/**
+	 * Returns a single value for all selected table cells. If the value is the same for all cells,
+	 * it will be returned (`undefined` otherwise).
+	 *
+	 * @param {Array.<module:engine/model/element~Element>} tableCell
+	 * @returns {*}
+	 * @private
+	 */
+	_getSingleValue( tableCell ) {
+		const firstCellValue = this._getAttribute( tableCell[ 0 ] );
+
+		const everyCellHasAttribute = tableCell.every( tableCell => this._getAttribute( tableCell ) === firstCellValue );
+
+		return everyCellHasAttribute ? firstCellValue : undefined;
+	}
 }
 }

+ 15 - 23
packages/ckeditor5-table/src/tablecellproperties/tablecellpropertiesediting.js

@@ -69,15 +69,15 @@ export default class TableCellPropertiesEditing extends Plugin {
 		const editor = this.editor;
 		const editor = this.editor;
 		const schema = editor.model.schema;
 		const schema = editor.model.schema;
 		const conversion = editor.conversion;
 		const conversion = editor.conversion;
-		const viewDoc = editor.editing.view.document;
+		const locale = editor.locale;
 
 
-		viewDoc.addStyleProcessorRules( addBorderRules );
+		editor.data.addStyleProcessorRules( addBorderRules );
 		enableBorderProperties( schema, conversion );
 		enableBorderProperties( schema, conversion );
 		editor.commands.add( 'tableCellBorderStyle', new TableCellBorderStyleCommand( editor ) );
 		editor.commands.add( 'tableCellBorderStyle', new TableCellBorderStyleCommand( editor ) );
 		editor.commands.add( 'tableCellBorderColor', new TableCellBorderColorCommand( editor ) );
 		editor.commands.add( 'tableCellBorderColor', new TableCellBorderColorCommand( editor ) );
 		editor.commands.add( 'tableCellBorderWidth', new TableCellBorderWidthCommand( editor ) );
 		editor.commands.add( 'tableCellBorderWidth', new TableCellBorderWidthCommand( editor ) );
 
 
-		enableHorizontalAlignmentProperty( schema, conversion );
+		enableHorizontalAlignmentProperty( schema, conversion, locale );
 		editor.commands.add( 'tableCellHorizontalAlignment', new TableCellHorizontalAlignmentCommand( editor ) );
 		editor.commands.add( 'tableCellHorizontalAlignment', new TableCellHorizontalAlignmentCommand( editor ) );
 
 
 		enableProperty( schema, conversion, 'width', 'width' );
 		enableProperty( schema, conversion, 'width', 'width' );
@@ -86,11 +86,11 @@ export default class TableCellPropertiesEditing extends Plugin {
 		enableProperty( schema, conversion, 'height', 'height' );
 		enableProperty( schema, conversion, 'height', 'height' );
 		editor.commands.add( 'tableCellHeight', new TableCellHeightCommand( editor ) );
 		editor.commands.add( 'tableCellHeight', new TableCellHeightCommand( editor ) );
 
 
-		viewDoc.addStyleProcessorRules( addPaddingRules );
+		editor.data.addStyleProcessorRules( addPaddingRules );
 		enableProperty( schema, conversion, 'padding', 'padding' );
 		enableProperty( schema, conversion, 'padding', 'padding' );
 		editor.commands.add( 'tableCellPadding', new TableCellPaddingCommand( editor ) );
 		editor.commands.add( 'tableCellPadding', new TableCellPaddingCommand( editor ) );
 
 
-		viewDoc.addStyleProcessorRules( addBackgroundRules );
+		editor.data.addStyleProcessorRules( addBackgroundRules );
 		enableProperty( schema, conversion, 'backgroundColor', 'background-color' );
 		enableProperty( schema, conversion, 'backgroundColor', 'background-color' );
 		editor.commands.add( 'tableCellBackgroundColor', new TableCellBackgroundColorCommand( editor ) );
 		editor.commands.add( 'tableCellBackgroundColor', new TableCellBackgroundColorCommand( editor ) );
 
 
@@ -118,37 +118,29 @@ function enableBorderProperties( schema, conversion ) {
 //
 //
 // @param {module:engine/model/schema~Schema} schema
 // @param {module:engine/model/schema~Schema} schema
 // @param {module:engine/conversion/conversion~Conversion} conversion
 // @param {module:engine/conversion/conversion~Conversion} conversion
-function enableHorizontalAlignmentProperty( schema, conversion ) {
+// @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.
+function enableHorizontalAlignmentProperty( schema, conversion, locale ) {
 	schema.extend( 'tableCell', {
 	schema.extend( 'tableCell', {
 		allowAttributes: [ 'horizontalAlignment' ]
 		allowAttributes: [ 'horizontalAlignment' ]
 	} );
 	} );
 
 
+	const options = [ locale.contentLanguageDirection == 'rtl' ? 'left' : 'right', 'center', 'justify' ];
+
 	conversion.attributeToAttribute( {
 	conversion.attributeToAttribute( {
 		model: {
 		model: {
 			name: 'tableCell',
 			name: 'tableCell',
 			key: 'horizontalAlignment',
 			key: 'horizontalAlignment',
-			values: [ 'right', 'center', 'justify' ]
+			values: options
 		},
 		},
-		view: {
-			right: {
-				key: 'style',
-				value: {
-					'text-align': 'right'
-				}
-			},
-			center: {
+		view: options.reduce( ( result, option ) => ( {
+			...result,
+			[ option ]: {
 				key: 'style',
 				key: 'style',
 				value: {
 				value: {
-					'text-align': 'center'
-				}
-			},
-			justify: {
-				key: 'style',
-				value: {
-					'text-align': 'justify'
+					'text-align': option
 				}
 				}
 			}
 			}
-		}
+		} ), {} )
 	} );
 	} );
 }
 }
 
 

+ 50 - 42
packages/ckeditor5-table/src/tablecellproperties/ui/tablecellpropertiesview.js

@@ -15,8 +15,8 @@ import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
 import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
 import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
 import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
 import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
 
 
-import LabeledView from '@ckeditor/ckeditor5-ui/src/labeledview/labeledview';
-import { createLabeledDropdown, createLabeledInputText } from '@ckeditor/ckeditor5-ui/src/labeledview/utils';
+import LabeledFieldView from '@ckeditor/ckeditor5-ui/src/labeledfield/labeledfieldview';
+import { createLabeledDropdown, createLabeledInputText } from '@ckeditor/ckeditor5-ui/src/labeledfield/utils';
 import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview';
 import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview';
 import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
 import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
 import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
 import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
@@ -28,7 +28,8 @@ import {
 	getLabeledColorInputCreator
 	getLabeledColorInputCreator
 } from '../../ui/utils';
 } from '../../ui/utils';
 import FormRowView from '../../ui/formrowview';
 import FormRowView from '../../ui/formrowview';
-import FormHeaderView from '../../ui/formheaderview';
+
+import FormHeaderView from '@ckeditor/ckeditor5-ui/src/formheader/formheaderview';
 
 
 import checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';
 import checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';
 import cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';
 import cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';
@@ -465,57 +466,57 @@ export default class TableCellPropertiesView extends View {
 		// -- Style ---------------------------------------------------
 		// -- Style ---------------------------------------------------
 
 
 		const styleLabels = getBorderStyleLabels( t );
 		const styleLabels = getBorderStyleLabels( t );
-		const borderStyleDropdown = new LabeledView( locale, createLabeledDropdown );
+		const borderStyleDropdown = new LabeledFieldView( locale, createLabeledDropdown );
 		borderStyleDropdown.set( {
 		borderStyleDropdown.set( {
 			label: t( 'Style' ),
 			label: t( 'Style' ),
 			class: 'ck-table-form__border-style'
 			class: 'ck-table-form__border-style'
 		} );
 		} );
 
 
-		borderStyleDropdown.view.buttonView.set( {
+		borderStyleDropdown.fieldView.buttonView.set( {
 			isOn: false,
 			isOn: false,
 			withText: true,
 			withText: true,
 			tooltip: t( 'Style' )
 			tooltip: t( 'Style' )
 		} );
 		} );
 
 
-		borderStyleDropdown.view.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {
+		borderStyleDropdown.fieldView.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {
 			return styleLabels[ value ? value : 'none' ];
 			return styleLabels[ value ? value : 'none' ];
 		} );
 		} );
 
 
-		borderStyleDropdown.view.on( 'execute', evt => {
+		borderStyleDropdown.fieldView.on( 'execute', evt => {
 			this.borderStyle = evt.source._borderStyleValue;
 			this.borderStyle = evt.source._borderStyleValue;
 		} );
 		} );
 
 
-		addListToDropdown( borderStyleDropdown.view, getBorderStyleDefinitions( this ) );
+		addListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this ) );
 
 
 		// -- Width ---------------------------------------------------
 		// -- Width ---------------------------------------------------
 
 
-		const borderWidthInput = new LabeledView( locale, createLabeledInputText );
+		const borderWidthInput = new LabeledFieldView( locale, createLabeledInputText );
 
 
 		borderWidthInput.set( {
 		borderWidthInput.set( {
 			label: t( 'Width' ),
 			label: t( 'Width' ),
 			class: 'ck-table-form__border-width'
 			class: 'ck-table-form__border-width'
 		} );
 		} );
 
 
-		borderWidthInput.view.bind( 'value' ).to( this, 'borderWidth' );
+		borderWidthInput.fieldView.bind( 'value' ).to( this, 'borderWidth' );
 		borderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
 		borderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
-		borderWidthInput.view.on( 'input', () => {
-			this.borderWidth = borderWidthInput.view.element.value;
+		borderWidthInput.fieldView.on( 'input', () => {
+			this.borderWidth = borderWidthInput.fieldView.element.value;
 		} );
 		} );
 
 
 		// -- Color ---------------------------------------------------
 		// -- Color ---------------------------------------------------
 
 
-		const borderColorInput = new LabeledView( locale, colorInputCreator );
+		const borderColorInput = new LabeledFieldView( locale, colorInputCreator );
 
 
 		borderColorInput.set( {
 		borderColorInput.set( {
 			label: t( 'Color' ),
 			label: t( 'Color' ),
 			class: 'ck-table-form__border-color'
 			class: 'ck-table-form__border-color'
 		} );
 		} );
 
 
-		borderColorInput.view.bind( 'value' ).to( this, 'borderColor' );
+		borderColorInput.fieldView.bind( 'value' ).to( this, 'borderColor' );
 		borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
 		borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
 
 
-		borderColorInput.view.on( 'input', () => {
-			this.borderColor = borderColorInput.view.value;
+		borderColorInput.fieldView.on( 'input', () => {
+			this.borderColor = borderColorInput.fieldView.value;
 		} );
 		} );
 
 
 		// Reset the border color and width fields when style is "none".
 		// Reset the border color and width fields when style is "none".
@@ -541,7 +542,7 @@ export default class TableCellPropertiesView extends View {
 	 * * {@link #backgroundInput}.
 	 * * {@link #backgroundInput}.
 	 *
 	 *
 	 * @private
 	 * @private
-	 * @returns {module:ui/labeledview/labeledview~LabeledView}
+	 * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
 	 */
 	 */
 	_createBackgroundField() {
 	_createBackgroundField() {
 		const locale = this.locale;
 		const locale = this.locale;
@@ -551,16 +552,16 @@ export default class TableCellPropertiesView extends View {
 			columns: 5
 			columns: 5
 		} );
 		} );
 
 
-		const backgroundInput = new LabeledView( locale, colorInputCreator );
+		const backgroundInput = new LabeledFieldView( locale, colorInputCreator );
 
 
 		backgroundInput.set( {
 		backgroundInput.set( {
 			label: t( 'Background' ),
 			label: t( 'Background' ),
 			class: 'ck-table-cell-properties-form__background'
 			class: 'ck-table-cell-properties-form__background'
 		} );
 		} );
 
 
-		backgroundInput.view.bind( 'value' ).to( this, 'backgroundColor' );
-		backgroundInput.view.on( 'input', () => {
-			this.backgroundColor = backgroundInput.view.value;
+		backgroundInput.fieldView.bind( 'value' ).to( this, 'backgroundColor' );
+		backgroundInput.fieldView.on( 'input', () => {
+			this.backgroundColor = backgroundInput.fieldView.value;
 		} );
 		} );
 
 
 		return backgroundInput;
 		return backgroundInput;
@@ -573,7 +574,7 @@ export default class TableCellPropertiesView extends View {
 	 * * {@link #heightInput}.
 	 * * {@link #heightInput}.
 	 *
 	 *
 	 * @private
 	 * @private
-	 * @returns {module:ui/labeledview/labeledview~LabeledView}
+	 * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
 	 */
 	 */
 	_createDimensionFields() {
 	_createDimensionFields() {
 		const locale = this.locale;
 		const locale = this.locale;
@@ -586,16 +587,16 @@ export default class TableCellPropertiesView extends View {
 
 
 		// -- Width ---------------------------------------------------
 		// -- Width ---------------------------------------------------
 
 
-		const widthInput = new LabeledView( locale, createLabeledInputText );
+		const widthInput = new LabeledFieldView( locale, createLabeledInputText );
 
 
 		widthInput.set( {
 		widthInput.set( {
 			label: t( 'Width' ),
 			label: t( 'Width' ),
 			class: 'ck-table-form__dimensions-row__width'
 			class: 'ck-table-form__dimensions-row__width'
 		} );
 		} );
 
 
-		widthInput.view.bind( 'value' ).to( this, 'width' );
-		widthInput.view.on( 'input', () => {
-			this.width = widthInput.view.element.value;
+		widthInput.fieldView.bind( 'value' ).to( this, 'width' );
+		widthInput.fieldView.on( 'input', () => {
+			this.width = widthInput.fieldView.element.value;
 		} );
 		} );
 
 
 		// -- Operator ---------------------------------------------------
 		// -- Operator ---------------------------------------------------
@@ -615,16 +616,16 @@ export default class TableCellPropertiesView extends View {
 
 
 		// -- Height ---------------------------------------------------
 		// -- Height ---------------------------------------------------
 
 
-		const heightInput = new LabeledView( locale, createLabeledInputText );
+		const heightInput = new LabeledFieldView( locale, createLabeledInputText );
 
 
 		heightInput.set( {
 		heightInput.set( {
 			label: t( 'Height' ),
 			label: t( 'Height' ),
 			class: 'ck-table-form__dimensions-row__height'
 			class: 'ck-table-form__dimensions-row__height'
 		} );
 		} );
 
 
-		heightInput.view.bind( 'value' ).to( this, 'height' );
-		heightInput.view.on( 'input', () => {
-			this.height = heightInput.view.element.value;
+		heightInput.fieldView.bind( 'value' ).to( this, 'height' );
+		heightInput.fieldView.on( 'input', () => {
+			this.height = heightInput.fieldView.element.value;
 		} );
 		} );
 
 
 		return {
 		return {
@@ -641,22 +642,22 @@ export default class TableCellPropertiesView extends View {
 	 * * {@link #paddingInput}.
 	 * * {@link #paddingInput}.
 	 *
 	 *
 	 * @private
 	 * @private
-	 * @returns {module:ui/labeledview/labeledview~LabeledView}
+	 * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
 	 */
 	 */
 	_createPaddingField() {
 	_createPaddingField() {
 		const locale = this.locale;
 		const locale = this.locale;
 		const t = this.t;
 		const t = this.t;
 
 
-		const paddingInput = new LabeledView( locale, createLabeledInputText );
+		const paddingInput = new LabeledFieldView( locale, createLabeledInputText );
 
 
 		paddingInput.set( {
 		paddingInput.set( {
 			label: t( 'Padding' ),
 			label: t( 'Padding' ),
 			class: 'ck-table-cell-properties-form__padding'
 			class: 'ck-table-cell-properties-form__padding'
 		} );
 		} );
 
 
-		paddingInput.view.bind( 'value' ).to( this, 'padding' );
-		paddingInput.view.on( 'input', () => {
-			this.padding = paddingInput.view.element.value;
+		paddingInput.fieldView.bind( 'value' ).to( this, 'padding' );
+		paddingInput.fieldView.on( 'input', () => {
+			this.padding = paddingInput.fieldView.element.value;
 		} );
 		} );
 
 
 		return paddingInput;
 		return paddingInput;
@@ -682,6 +683,7 @@ export default class TableCellPropertiesView extends View {
 		// -- Horizontal ---------------------------------------------------
 		// -- Horizontal ---------------------------------------------------
 
 
 		const horizontalAlignmentToolbar = new ToolbarView( locale );
 		const horizontalAlignmentToolbar = new ToolbarView( locale );
+		const isContentRTL = this.locale.contentLanguageDirection === 'rtl';
 
 
 		horizontalAlignmentToolbar.set( {
 		horizontalAlignmentToolbar.set( {
 			isCompact: true,
 			isCompact: true,
@@ -695,7 +697,7 @@ export default class TableCellPropertiesView extends View {
 			labels: this._horizontalAlignmentLabels,
 			labels: this._horizontalAlignmentLabels,
 			propertyName: 'horizontalAlignment',
 			propertyName: 'horizontalAlignment',
 			nameToValue: name => {
 			nameToValue: name => {
-				return name === 'left' ? '' : name;
+				return name === ( isContentRTL ? 'right' : 'left' ) ? '' : name;
 			}
 			}
 		} );
 		} );
 
 
@@ -781,14 +783,20 @@ export default class TableCellPropertiesView extends View {
 	 * @type {Object.<String,String>}
 	 * @type {Object.<String,String>}
 	 */
 	 */
 	get _horizontalAlignmentLabels() {
 	get _horizontalAlignmentLabels() {
+		const locale = this.locale;
 		const t = this.t;
 		const t = this.t;
 
 
-		return {
-			left: t( 'Align cell text to the left' ),
-			center: t( 'Align cell text to the center' ),
-			right: t( 'Align cell text to the right' ),
-			justify: t( 'Justify cell text' )
-		};
+		const left = t( 'Align cell text to the left' );
+		const center = t( 'Align cell text to the center' );
+		const right = t( 'Align cell text to the right' );
+		const justify = t( 'Justify cell text' );
+
+		// Returns object with a proper order of labels.
+		if ( locale.uiLanguageDirection === 'rtl' ) {
+			return { right, center, left, justify };
+		} else {
+			return { left, center, right, justify };
+		}
 	}
 	}
 
 
 	/**
 	/**

+ 13 - 33
packages/ckeditor5-table/src/tableclipboard.js

@@ -11,9 +11,8 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import TableSelection from './tableselection';
 import TableSelection from './tableselection';
 
 
 /**
 /**
- * The table clipboard integration plugin.
- *
- * It introduces the ability to copy selected table cells.
+ * This plugin adds support for copying/cutting/pasting fragments of tables.
+ * It is loaded automatically by the {@link module:table/table~Table} plugin.
  *
  *
  * @extends module:core/plugin~Plugin
  * @extends module:core/plugin~Plugin
  */
  */
@@ -39,30 +38,25 @@ export default class TableClipboard extends Plugin {
 		const editor = this.editor;
 		const editor = this.editor;
 		const viewDocument = editor.editing.view.document;
 		const viewDocument = editor.editing.view.document;
 
 
-		/**
-		 * A table selection plugin instance.
-		 *
-		 * @private
-		 * @readonly
-		 * @member {module:table/tableselection~TableSelection} module:tableclipboard~TableClipboard#_tableSelection
-		 */
-		this._tableSelection = editor.plugins.get( 'TableSelection' );
-
-		this.listenTo( viewDocument, 'copy', ( evt, data ) => this._onCopy( evt, data ), { priority: 'normal' } );
-		this.listenTo( viewDocument, 'cut', ( evt, data ) => this._onCut( evt, data ), { priority: 'high' } );
+		this.listenTo( viewDocument, 'copy', ( evt, data ) => this._onCopyCut( evt, data ) );
+		this.listenTo( viewDocument, 'cut', ( evt, data ) => this._onCopyCut( evt, data ) );
 	}
 	}
 
 
 	/**
 	/**
-	 * A clipboard "copy" event handler.
+	 * Copies table content to a clipboard on "copy" & "cut" events.
 	 *
 	 *
+	 * @private
 	 * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the handled event.
 	 * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the handled event.
 	 * @param {Object} data Clipboard event data.
 	 * @param {Object} data Clipboard event data.
-	 * @private
 	 */
 	 */
-	_onCopy( evt, data ) {
-		const tableSelection = this._tableSelection;
+	_onCopyCut( evt, data ) {
+		const tableSelection = this.editor.plugins.get( 'TableSelection' );
 
 
-		if ( !tableSelection.hasMultiCellSelection ) {
+		if ( !tableSelection.getSelectedTableCells() ) {
+			return;
+		}
+
+		if ( evt.name == 'cut' && this.editor.isReadOnly ) {
 			return;
 			return;
 		}
 		}
 
 
@@ -80,18 +74,4 @@ export default class TableClipboard extends Plugin {
 			method: evt.name
 			method: evt.name
 		} );
 		} );
 	}
 	}
-
-	/**
-	 * A clipboard "cut" event handler.
-	 *
-	 * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the handled event.
-	 * @param {Object} data Clipboard event data.
-	 * @private
-	 */
-	_onCut( evt, data ) {
-		if ( this._tableSelection.hasMultiCellSelection ) {
-			data.preventDefault();
-			evt.stop();
-		}
-	}
 }
 }

+ 10 - 5
packages/ckeditor5-table/src/tableediting.js

@@ -28,7 +28,10 @@ import RemoveRowCommand from './commands/removerowcommand';
 import RemoveColumnCommand from './commands/removecolumncommand';
 import RemoveColumnCommand from './commands/removecolumncommand';
 import SetHeaderRowCommand from './commands/setheaderrowcommand';
 import SetHeaderRowCommand from './commands/setheaderrowcommand';
 import SetHeaderColumnCommand from './commands/setheadercolumncommand';
 import SetHeaderColumnCommand from './commands/setheadercolumncommand';
-import { findAncestor } from './commands/utils';
+import MergeCellsCommand from './commands/mergecellscommand';
+import SelectRowCommand from './commands/selectrowcommand';
+import SelectColumnCommand from './commands/selectcolumncommand';
+import { getTableCellsContainingSelection } from './utils';
 import TableUtils from '../src/tableutils';
 import TableUtils from '../src/tableutils';
 
 
 import injectTableLayoutPostFixer from './converters/table-layout-post-fixer';
 import injectTableLayoutPostFixer from './converters/table-layout-post-fixer';
@@ -131,6 +134,8 @@ export default class TableEditing extends Plugin {
 		editor.commands.add( 'splitTableCellVertically', new SplitCellCommand( editor, { direction: 'vertically' } ) );
 		editor.commands.add( 'splitTableCellVertically', new SplitCellCommand( editor, { direction: 'vertically' } ) );
 		editor.commands.add( 'splitTableCellHorizontally', new SplitCellCommand( editor, { direction: 'horizontally' } ) );
 		editor.commands.add( 'splitTableCellHorizontally', new SplitCellCommand( editor, { direction: 'horizontally' } ) );
 
 
+		editor.commands.add( 'mergeTableCells', new MergeCellsCommand( editor ) );
+
 		editor.commands.add( 'mergeTableCellRight', new MergeCellCommand( editor, { direction: 'right' } ) );
 		editor.commands.add( 'mergeTableCellRight', new MergeCellCommand( editor, { direction: 'right' } ) );
 		editor.commands.add( 'mergeTableCellLeft', new MergeCellCommand( editor, { direction: 'left' } ) );
 		editor.commands.add( 'mergeTableCellLeft', new MergeCellCommand( editor, { direction: 'left' } ) );
 		editor.commands.add( 'mergeTableCellDown', new MergeCellCommand( editor, { direction: 'down' } ) );
 		editor.commands.add( 'mergeTableCellDown', new MergeCellCommand( editor, { direction: 'down' } ) );
@@ -139,6 +144,9 @@ export default class TableEditing extends Plugin {
 		editor.commands.add( 'setTableColumnHeader', new SetHeaderColumnCommand( editor ) );
 		editor.commands.add( 'setTableColumnHeader', new SetHeaderColumnCommand( editor ) );
 		editor.commands.add( 'setTableRowHeader', new SetHeaderRowCommand( editor ) );
 		editor.commands.add( 'setTableRowHeader', new SetHeaderRowCommand( editor ) );
 
 
+		editor.commands.add( 'selectTableRow', new SelectRowCommand( editor ) );
+		editor.commands.add( 'selectTableColumn', new SelectColumnCommand( editor ) );
+
 		injectTableLayoutPostFixer( model );
 		injectTableLayoutPostFixer( model );
 		injectTableCellRefreshPostFixer( model );
 		injectTableCellRefreshPostFixer( model );
 		injectTableCellParagraphPostFixer( model );
 		injectTableCellParagraphPostFixer( model );
@@ -195,10 +203,7 @@ export default class TableEditing extends Plugin {
 
 
 		return ( domEventData, cancel ) => {
 		return ( domEventData, cancel ) => {
 			const selection = editor.model.document.selection;
 			const selection = editor.model.document.selection;
-
-			const firstPosition = selection.getFirstPosition();
-
-			const tableCell = findAncestor( 'tableCell', firstPosition );
+			const tableCell = getTableCellsContainingSelection( selection )[ 0 ];
 
 
 			if ( !tableCell ) {
 			if ( !tableCell ) {
 				return;
 				return;

+ 5 - 2
packages/ckeditor5-table/src/tableproperties.js

@@ -13,10 +13,13 @@ import TablePropertiesEditing from './tableproperties/tablepropertiesediting';
 import TablePropertiesUI from './tableproperties/tablepropertiesui';
 import TablePropertiesUI from './tableproperties/tablepropertiesui';
 
 
 /**
 /**
- * The table properties feature.
+ * The table properties feature. Enables support for setting properties of tables (size, border, background, etc.).
+ *
+ * Read more in the {@glink features/table#table-and-cell-styling-tools Table and cell styling tools} section.
+ * See also the {@link module:table/tablecellproperties~TableCellProperties} plugin.
  *
  *
  * This is a "glue" plugin that loads the
  * This is a "glue" plugin that loads the
- * {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing table editing feature} and
+ * {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing table properties editing feature} and
  * the {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI table properties UI feature}.
  * the {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI table properties UI feature}.
  *
  *
  * @extends module:core/plugin~Plugin
  * @extends module:core/plugin~Plugin

+ 2 - 3
packages/ckeditor5-table/src/tableproperties/tablepropertiesediting.js

@@ -69,9 +69,8 @@ export default class TablePropertiesEditing extends Plugin {
 		const editor = this.editor;
 		const editor = this.editor;
 		const schema = editor.model.schema;
 		const schema = editor.model.schema;
 		const conversion = editor.conversion;
 		const conversion = editor.conversion;
-		const viewDoc = editor.editing.view.document;
 
 
-		viewDoc.addStyleProcessorRules( addBorderRules );
+		editor.data.addStyleProcessorRules( addBorderRules );
 		enableBorderProperties( schema, conversion );
 		enableBorderProperties( schema, conversion );
 		editor.commands.add( 'tableBorderColor', new TableBorderColorCommand( editor ) );
 		editor.commands.add( 'tableBorderColor', new TableBorderColorCommand( editor ) );
 		editor.commands.add( 'tableBorderStyle', new TableBorderStyleCommand( editor ) );
 		editor.commands.add( 'tableBorderStyle', new TableBorderStyleCommand( editor ) );
@@ -86,7 +85,7 @@ export default class TablePropertiesEditing extends Plugin {
 		enableTableToFigureProperty( schema, conversion, 'height', 'height' );
 		enableTableToFigureProperty( schema, conversion, 'height', 'height' );
 		editor.commands.add( 'tableHeight', new TableHeightCommand( editor ) );
 		editor.commands.add( 'tableHeight', new TableHeightCommand( editor ) );
 
 
-		viewDoc.addStyleProcessorRules( addBackgroundRules );
+		editor.data.addStyleProcessorRules( addBackgroundRules );
 		enableProperty( schema, conversion, 'backgroundColor', 'background-color' );
 		enableProperty( schema, conversion, 'backgroundColor', 'background-color' );
 		editor.commands.add( 'tableBackgroundColor', new TableBackgroundColorCommand( editor ) );
 		editor.commands.add( 'tableBackgroundColor', new TableBackgroundColorCommand( editor ) );
 	}
 	}

+ 42 - 35
packages/ckeditor5-table/src/tableproperties/ui/tablepropertiesview.js

@@ -15,8 +15,8 @@ import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
 import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
 import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
 import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
 import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
 
 
-import LabeledView from '@ckeditor/ckeditor5-ui/src/labeledview/labeledview';
-import { createLabeledDropdown, createLabeledInputText } from '@ckeditor/ckeditor5-ui/src/labeledview/utils';
+import LabeledFieldView from '@ckeditor/ckeditor5-ui/src/labeledfield/labeledfieldview';
+import { createLabeledDropdown, createLabeledInputText } from '@ckeditor/ckeditor5-ui/src/labeledfield/utils';
 import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview';
 import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview';
 import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
 import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
 import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
 import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
@@ -28,7 +28,8 @@ import {
 	getLabeledColorInputCreator
 	getLabeledColorInputCreator
 } from '../../ui/utils';
 } from '../../ui/utils';
 import FormRowView from '../../ui/formrowview';
 import FormRowView from '../../ui/formrowview';
-import FormHeaderView from '../../ui/formheaderview';
+
+import FormHeaderView from '@ckeditor/ckeditor5-ui/src/formheader/formheaderview';
 
 
 import checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';
 import checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';
 import cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';
 import cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';
@@ -412,57 +413,57 @@ export default class TablePropertiesView extends View {
 		// -- Style ---------------------------------------------------
 		// -- Style ---------------------------------------------------
 
 
 		const styleLabels = getBorderStyleLabels( this.t );
 		const styleLabels = getBorderStyleLabels( this.t );
-		const borderStyleDropdown = new LabeledView( locale, createLabeledDropdown );
+		const borderStyleDropdown = new LabeledFieldView( locale, createLabeledDropdown );
 		borderStyleDropdown.set( {
 		borderStyleDropdown.set( {
 			label: t( 'Style' ),
 			label: t( 'Style' ),
 			class: 'ck-table-form__border-style'
 			class: 'ck-table-form__border-style'
 		} );
 		} );
 
 
-		borderStyleDropdown.view.buttonView.set( {
+		borderStyleDropdown.fieldView.buttonView.set( {
 			isOn: false,
 			isOn: false,
 			withText: true,
 			withText: true,
 			tooltip: t( 'Style' )
 			tooltip: t( 'Style' )
 		} );
 		} );
 
 
-		borderStyleDropdown.view.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {
+		borderStyleDropdown.fieldView.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {
 			return styleLabels[ value ? value : 'none' ];
 			return styleLabels[ value ? value : 'none' ];
 		} );
 		} );
 
 
-		borderStyleDropdown.view.on( 'execute', evt => {
+		borderStyleDropdown.fieldView.on( 'execute', evt => {
 			this.borderStyle = evt.source._borderStyleValue;
 			this.borderStyle = evt.source._borderStyleValue;
 		} );
 		} );
 
 
-		addListToDropdown( borderStyleDropdown.view, getBorderStyleDefinitions( this ) );
+		addListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this ) );
 
 
 		// -- Width ---------------------------------------------------
 		// -- Width ---------------------------------------------------
 
 
-		const borderWidthInput = new LabeledView( locale, createLabeledInputText );
+		const borderWidthInput = new LabeledFieldView( locale, createLabeledInputText );
 
 
 		borderWidthInput.set( {
 		borderWidthInput.set( {
 			label: t( 'Width' ),
 			label: t( 'Width' ),
 			class: 'ck-table-form__border-width'
 			class: 'ck-table-form__border-width'
 		} );
 		} );
 
 
-		borderWidthInput.view.bind( 'value' ).to( this, 'borderWidth' );
+		borderWidthInput.fieldView.bind( 'value' ).to( this, 'borderWidth' );
 		borderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
 		borderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
-		borderWidthInput.view.on( 'input', () => {
-			this.borderWidth = borderWidthInput.view.element.value;
+		borderWidthInput.fieldView.on( 'input', () => {
+			this.borderWidth = borderWidthInput.fieldView.element.value;
 		} );
 		} );
 
 
 		// -- Color ---------------------------------------------------
 		// -- Color ---------------------------------------------------
 
 
-		const borderColorInput = new LabeledView( locale, colorInputCreator );
+		const borderColorInput = new LabeledFieldView( locale, colorInputCreator );
 
 
 		borderColorInput.set( {
 		borderColorInput.set( {
 			label: t( 'Color' ),
 			label: t( 'Color' ),
 			class: 'ck-table-form__border-color'
 			class: 'ck-table-form__border-color'
 		} );
 		} );
 
 
-		borderColorInput.view.bind( 'value' ).to( this, 'borderColor' );
+		borderColorInput.fieldView.bind( 'value' ).to( this, 'borderColor' );
 		borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
 		borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
 
 
-		borderColorInput.view.on( 'input', () => {
-			this.borderColor = borderColorInput.view.value;
+		borderColorInput.fieldView.on( 'input', () => {
+			this.borderColor = borderColorInput.fieldView.value;
 		} );
 		} );
 
 
 		// Reset the border color and width fields when style is "none".
 		// Reset the border color and width fields when style is "none".
@@ -488,7 +489,7 @@ export default class TablePropertiesView extends View {
 	 * * {@link #backgroundInput}.
 	 * * {@link #backgroundInput}.
 	 *
 	 *
 	 * @private
 	 * @private
-	 * @returns {module:ui/labeledview/labeledview~LabeledView}
+	 * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
 	 */
 	 */
 	_createBackgroundField() {
 	_createBackgroundField() {
 		const backgroundInputCreator = getLabeledColorInputCreator( {
 		const backgroundInputCreator = getLabeledColorInputCreator( {
@@ -498,16 +499,16 @@ export default class TablePropertiesView extends View {
 		const locale = this.locale;
 		const locale = this.locale;
 		const t = this.t;
 		const t = this.t;
 
 
-		const backgroundInput = new LabeledView( locale, backgroundInputCreator );
+		const backgroundInput = new LabeledFieldView( locale, backgroundInputCreator );
 
 
 		backgroundInput.set( {
 		backgroundInput.set( {
 			label: t( 'Background' ),
 			label: t( 'Background' ),
 			class: 'ck-table-properties-form__background'
 			class: 'ck-table-properties-form__background'
 		} );
 		} );
 
 
-		backgroundInput.view.bind( 'value' ).to( this, 'backgroundColor' );
-		backgroundInput.view.on( 'input', () => {
-			this.backgroundColor = backgroundInput.view.value;
+		backgroundInput.fieldView.bind( 'value' ).to( this, 'backgroundColor' );
+		backgroundInput.fieldView.on( 'input', () => {
+			this.backgroundColor = backgroundInput.fieldView.value;
 		} );
 		} );
 
 
 		return backgroundInput;
 		return backgroundInput;
@@ -520,7 +521,7 @@ export default class TablePropertiesView extends View {
 	 * * {@link #heightInput}.
 	 * * {@link #heightInput}.
 	 *
 	 *
 	 * @private
 	 * @private
-	 * @returns {module:ui/labeledview/labeledview~LabeledView}
+	 * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
 	 */
 	 */
 	_createDimensionFields() {
 	_createDimensionFields() {
 		const locale = this.locale;
 		const locale = this.locale;
@@ -533,16 +534,16 @@ export default class TablePropertiesView extends View {
 
 
 		// -- Width ---------------------------------------------------
 		// -- Width ---------------------------------------------------
 
 
-		const widthInput = new LabeledView( locale, createLabeledInputText );
+		const widthInput = new LabeledFieldView( locale, createLabeledInputText );
 
 
 		widthInput.set( {
 		widthInput.set( {
 			label: t( 'Width' ),
 			label: t( 'Width' ),
 			class: 'ck-table-form__dimensions-row__width'
 			class: 'ck-table-form__dimensions-row__width'
 		} );
 		} );
 
 
-		widthInput.view.bind( 'value' ).to( this, 'width' );
-		widthInput.view.on( 'input', () => {
-			this.width = widthInput.view.element.value;
+		widthInput.fieldView.bind( 'value' ).to( this, 'width' );
+		widthInput.fieldView.on( 'input', () => {
+			this.width = widthInput.fieldView.element.value;
 		} );
 		} );
 
 
 		// -- Operator ---------------------------------------------------
 		// -- Operator ---------------------------------------------------
@@ -562,16 +563,16 @@ export default class TablePropertiesView extends View {
 
 
 		// -- Height ---------------------------------------------------
 		// -- Height ---------------------------------------------------
 
 
-		const heightInput = new LabeledView( locale, createLabeledInputText );
+		const heightInput = new LabeledFieldView( locale, createLabeledInputText );
 
 
 		heightInput.set( {
 		heightInput.set( {
 			label: t( 'Height' ),
 			label: t( 'Height' ),
 			class: 'ck-table-form__dimensions-row__height'
 			class: 'ck-table-form__dimensions-row__height'
 		} );
 		} );
 
 
-		heightInput.view.bind( 'value' ).to( this, 'height' );
-		heightInput.view.on( 'input', () => {
-			this.height = heightInput.view.element.value;
+		heightInput.fieldView.bind( 'value' ).to( this, 'height' );
+		heightInput.fieldView.on( 'input', () => {
+			this.height = heightInput.fieldView.element.value;
 		} );
 		} );
 
 
 		return {
 		return {
@@ -681,13 +682,19 @@ export default class TablePropertiesView extends View {
 	 * @type {Object.<String,String>}
 	 * @type {Object.<String,String>}
 	 */
 	 */
 	get _alignmentLabels() {
 	get _alignmentLabels() {
+		const locale = this.locale;
 		const t = this.t;
 		const t = this.t;
 
 
-		return {
-			left: t( 'Align table to the left' ),
-			center: t( 'Center table' ),
-			right: t( 'Align table to the right' )
-		};
+		const left = t( 'Align table to the left' );
+		const center = t( 'Center table' );
+		const right = t( 'Align table to the right' );
+
+		// Returns object with a proper order of labels.
+		if ( locale.uiLanguageDirection === 'rtl' ) {
+			return { right, center, left };
+		} else {
+			return { left, center, right };
+		}
 	}
 	}
 }
 }
 
 

+ 349 - 166
packages/ckeditor5-table/src/tableselection.js

@@ -11,34 +11,19 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 
 
 import TableWalker from './tablewalker';
 import TableWalker from './tablewalker';
 import TableUtils from './tableutils';
 import TableUtils from './tableutils';
-import { setupTableSelectionHighlighting } from './tableselection/converters';
-import MouseSelectionHandler from './tableselection/mouseselectionhandler';
+import MouseEventsObserver from './tableselection/mouseeventsobserver';
+import {
+	getSelectedTableCells,
+	getTableCellsContainingSelection
+} from './utils';
 import { findAncestor } from './commands/utils';
 import { findAncestor } from './commands/utils';
 import cropTable from './tableselection/croptable';
 import cropTable from './tableselection/croptable';
 
 
 import '../theme/tableselection.css';
 import '../theme/tableselection.css';
 
 
 /**
 /**
- * The table selection plugin.
- *
- * It introduces the ability to select table cells. The table selection is described by two nodes: start and end.
- * Both are the oposite corners of an rectangle that spans over them.
- *
- * Consider a table:
- *
- *		    0   1   2   3
- *		  +---+---+---+---+
- *		0 | a | b | c | d |
- *		  +-------+   +---+
- *		1 | e | f |   | g |
- *		  +---+---+---+---+
- *		2 | h | i     | j |
- *		  +---+---+---+---+
- *
- * Setting the table selection start in table cell "b" and the end in table cell "g" will select table cells: "b", "c", "d", "f", and "g".
- * The cells that span over multiple rows or columns can extend over the selection rectangle. For instance, setting a selection from
- * the table cell "a" to the table cell "i" will create a selection in which the table cell "i" will be (partially) outside
- * the rectangle of selected cells: "a", "b", "e", "f", "h", and "i".
+ * This plugin enables the advanced table cells, rows and columns selection.
+ * It is loaded automatically by the {@link module:table/table~Table} plugin.
  *
  *
  * @extends module:core/plugin~Plugin
  * @extends module:core/plugin~Plugin
  */
  */
@@ -60,223 +45,421 @@ export default class TableSelection extends Plugin {
 	/**
 	/**
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
-	constructor( editor ) {
-		super( editor );
-
-		/**
-		 * A mouse selection handler.
-		 *
-		 * @private
-		 * @readonly
-		 * @member {module:table/tableselection/mouseselectionhandler~MouseSelectionHandler}
-		 */
-		this._mouseHandler = new MouseSelectionHandler( this, this.editor.editing );
-
-		/**
-		 * A reference to the table utilities used across the class.
-		 *
-		 * @private
-		 * @readonly
-		 * @member {module:table/tableutils~TableUtils} #_tableUtils
-		 */
+	init() {
+		const editor = this.editor;
+		const model = editor.model;
+
+		this.listenTo( model, 'deleteContent', ( evt, args ) => this._handleDeleteContent( evt, args ), { priority: 'high' } );
+
+		// Currently the MouseObserver only handles `mouseup` events.
+		// TODO move to the engine?
+		editor.editing.view.addObserver( MouseEventsObserver );
+
+		this._defineSelectionConverter();
+		this._enableShiftClickSelection();
+		this._enableMouseDragSelection();
+		this._enablePluginDisabling(); // sic!
 	}
 	}
 
 
 	/**
 	/**
-	 * A flag indicating that there are selected table cells and the selection includes more than one table cell.
+	 * Returns the currently selected table cells or `null` if it is not a table cells selection.
 	 *
 	 *
-	 * @type {Boolean}
+	 * @returns {Array.<module:engine/model/element~Element>|null}
 	 */
 	 */
-	get hasMultiCellSelection() {
-		return !!this._startElement && !!this._endElement && this._startElement !== this._endElement;
-	}
+	getSelectedTableCells() {
+		const selection = this.editor.model.document.selection;
 
 
-	/**
-	 * @inheritDoc
-	 */
-	init() {
-		const editor = this.editor;
-		const selection = editor.model.document.selection;
+		const selectedCells = getSelectedTableCells( selection );
 
 
-		this._tableUtils = editor.plugins.get( 'TableUtils' );
+		if ( selectedCells.length == 0 ) {
+			return null;
+		}
 
 
-		setupTableSelectionHighlighting( editor, this );
+		// This should never happen, but let's know if it ever happens.
+		// @if CK_DEBUG //	/* istanbul ignore next */
+		// @if CK_DEBUG //	if ( selectedCells.length != selection.rangeCount ) {
+		// @if CK_DEBUG //		console.warn( 'Mixed selection warning. The selection contains table cells and some other ranges.' );
+		// @if CK_DEBUG //	}
 
 
-		selection.on( 'change:range', () => this._clearSelectionOnExternalChange( selection ) );
+		return selectedCells;
 	}
 	}
 
 
 	/**
 	/**
-	 * @inheritDoc
+	 * Returns the selected table fragment as a document fragment.
+	 *
+	 * @returns {module:engine/model/documentfragment~DocumentFragment|null}
 	 */
 	 */
-	destroy() {
-		super.destroy();
-		this._mouseHandler.stopListening();
+	getSelectionAsFragment() {
+		const selectedCells = this.getSelectedTableCells();
+
+		if ( !selectedCells ) {
+			return null;
+		}
+
+		return this.editor.model.change( writer => {
+			const documentFragment = writer.createDocumentFragment();
+			const table = cropTable( selectedCells, this.editor.plugins.get( 'TableUtils' ), writer );
+
+			writer.insert( table, documentFragment, 0 );
+
+			return documentFragment;
+		} );
 	}
 	}
 
 
 	/**
 	/**
-	 * Marks the table cell as a start of a table selection.
+	 * Defines a selection converter which marks the selected cells with a specific class.
 	 *
 	 *
-	 *		editor.plugins.get( 'TableSelection' ).startSelectingFrom( tableCell );
+	 * The real DOM selection is put in the last cell. Since the order of ranges is dependent on whether the
+	 * selection is backward or not, the last cell will usually be close to the "focus" end of the selection
+	 * (a selection has anchor and focus).
 	 *
 	 *
-	 * This method will clear the previous selection. The model selection will not be updated until
-	 * the {@link #setSelectingTo} method is used.
+	 * The real DOM selection is then hidden with CSS.
 	 *
 	 *
-	 * @param {module:engine/model/element~Element} tableCell
+	 * @private
 	 */
 	 */
-	startSelectingFrom( tableCell ) {
-		this.clearSelection();
+	_defineSelectionConverter() {
+		const editor = this.editor;
+		const highlighted = new Set();
+
+		editor.conversion.for( 'editingDowncast' ).add( dispatcher => dispatcher.on( 'selection', ( evt, data, conversionApi ) => {
+			const viewWriter = conversionApi.writer;
+
+			clearHighlightedTableCells( viewWriter );
+
+			const selectedCells = this.getSelectedTableCells();
+
+			if ( !selectedCells ) {
+				return;
+			}
+
+			for ( const tableCell of selectedCells ) {
+				const viewElement = conversionApi.mapper.toViewElement( tableCell );
+
+				viewWriter.addClass( 'ck-editor__editable_selected', viewElement );
+				highlighted.add( viewElement );
+			}
+
+			const lastViewCell = conversionApi.mapper.toViewElement( selectedCells[ selectedCells.length - 1 ] );
+			viewWriter.setSelection( lastViewCell, 0 );
+		}, { priority: 'lowest' } ) );
 
 
-		this._startElement = tableCell;
-		this._endElement = tableCell;
+		function clearHighlightedTableCells( writer ) {
+			for ( const previouslyHighlighted of highlighted ) {
+				writer.removeClass( 'ck-editor__editable_selected', previouslyHighlighted );
+			}
+
+			highlighted.clear();
+		}
 	}
 	}
 
 
 	/**
 	/**
-	 * Updates the current table selection end element. Table selection is defined by a start and an end element.
-	 * This method updates the end element. Must be preceded by {@link #startSelectingFrom}.
+	 * Enables making cells selection by <kbd>Shift</kbd>+click. Creates a selection from the cell which previously held
+	 * the selection to the cell which was clicked. It can be the same cell, in which case it selects a single cell.
 	 *
 	 *
-	 *		editor.plugins.get( 'TableSelection' ).startSelectingFrom( startTableCell );
-	 *
-	 *		editor.plugins.get( 'TableSelection' ).setSelectingTo( endTableCell );
-	 *
-	 * This method will update model selection if start and end cells are different and belongs to the same table.
-	 *
-	 * @param {module:engine/model/element~Element} tableCell
+	 * @private
 	 */
 	 */
-	setSelectingTo( tableCell ) {
-		if ( !this._startElement ) {
-			this._startElement = tableCell;
-		}
+	_enableShiftClickSelection() {
+		const editor = this.editor;
+		let blockSelectionChange = false;
 
 
-		const table = this._startElement.parent.parent;
+		this.listenTo( editor.editing.view.document, 'mousedown', ( evt, domEventData ) => {
+			if ( !this.isEnabled ) {
+				return;
+			}
 
 
-		// Do not add tableCell to selection if it is from other table or is already set as end element.
-		if ( table !== tableCell.parent.parent || this._endElement === tableCell ) {
-			return;
-		}
+			if ( !domEventData.domEvent.shiftKey ) {
+				return;
+			}
+
+			const anchorCell = getTableCellsContainingSelection( editor.model.document.selection )[ 0 ];
+
+			if ( !anchorCell ) {
+				return;
+			}
+
+			const targetCell = this._getModelTableCellFromDomEvent( domEventData );
+
+			if ( targetCell && haveSameTableParent( anchorCell, targetCell ) ) {
+				blockSelectionChange = true;
+				this._setCellSelection( anchorCell, targetCell );
 
 
-		this._endElement = tableCell;
-		this._updateModelSelection();
+				domEventData.preventDefault();
+			}
+		} );
+
+		this.listenTo( editor.editing.view.document, 'mouseup', () => {
+			blockSelectionChange = false;
+		} );
+
+		// We need to ignore a `selectionChange` event that is fired after we render our new table cells selection.
+		// When downcasting table cells selection to the view, we put the view selection in the last selected cell
+		// in a place that may not be natively a "correct" location. This is – we put it directly in the `<td>` element.
+		// All browsers fire the native `selectionchange` event.
+		// However, all browsers except Safari return the selection in the exact place where we put it
+		// (even though it's visually normalized). Safari returns `<td><p>^foo` that makes our selection observer
+		// fire our `selectionChange` event (because the view selection that we set in the first step differs from the DOM selection).
+		// Since `selectionChange` is fired, we automatically update the model selection that moves it that paragraph.
+		// This breaks our dear cells selection.
+		//
+		// Theoretically this issue concerns only Safari that is the only browser that do normalize the selection.
+		// However, to avoid code branching and to have a good coverage for this event blocker, I enabled it for all browsers.
+		//
+		// Note: I'm keeping the `blockSelectionChange` state separately for shift+click and mouse drag (exact same logic)
+		// so I don't have to try to analyze whether they don't overlap in some weird cases. Probably they don't.
+		// But I have other things to do, like writing this comment.
+		this.listenTo( editor.editing.view.document, 'selectionChange', evt => {
+			if ( blockSelectionChange ) {
+				// @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );
+
+				evt.stop();
+			}
+		}, { priority: 'highest' } );
 	}
 	}
 
 
 	/**
 	/**
-	 * Stops the selection process (but do not clear the current selection).
-	 * The selection process is finished but the selection in the model remains.
-	 *
-	 *		editor.plugins.get( 'TableSelection' ).startSelectingFrom( startTableCell );
-	 *		editor.plugins.get( 'TableSelection' ).setSelectingTo( endTableCell );
-	 *		editor.plugins.get( 'TableSelection' ).stopSelection();
+	 * Enables making cells selection by dragging.
 	 *
 	 *
-	 * To clear the selection use {@link #clearSelection}.
+	 * The selection is made only on mousemove. Mouse tracking is started on mousedown.
+	 * However, the cells selection is enabled only after the mouse cursor left the anchor cell.
+	 * Thanks to that normal text selection within one cell works just fine. However, you can still select
+	 * just one cell by leaving the anchor cell and moving back to it.
 	 *
 	 *
-	 * @param {module:engine/model/element~Element} [tableCell]
+	 * @private
 	 */
 	 */
-	stopSelection( tableCell ) {
-		if ( tableCell && tableCell.parent.parent === this._startElement.parent.parent ) {
-			this._endElement = tableCell;
-		}
+	_enableMouseDragSelection() {
+		const editor = this.editor;
+		let anchorCell, targetCell;
+		let beganCellSelection = false;
+		let blockSelectionChange = false;
 
 
-		this._updateModelSelection();
+		this.listenTo( editor.editing.view.document, 'mousedown', ( evt, domEventData ) => {
+			if ( !this.isEnabled ) {
+				return;
+			}
+
+			// Make sure to not conflict with the shift+click listener and any other possible handler.
+			if ( domEventData.domEvent.shiftKey || domEventData.domEvent.ctrlKey || domEventData.domEvent.altKey ) {
+				return;
+			}
+
+			anchorCell = this._getModelTableCellFromDomEvent( domEventData );
+		} );
+
+		this.listenTo( editor.editing.view.document, 'mousemove', ( evt, domEventData ) => {
+			if ( !domEventData.domEvent.buttons ) {
+				return;
+			}
+
+			if ( !anchorCell ) {
+				return;
+			}
+
+			const newTargetCell = this._getModelTableCellFromDomEvent( domEventData );
+
+			if ( newTargetCell && haveSameTableParent( anchorCell, newTargetCell ) ) {
+				targetCell = newTargetCell;
+
+				// Switch to the cell selection mode after the mouse cursor left the anchor cell.
+				// Switch off only on mouseup (makes selecting a single cell possible).
+				if ( !beganCellSelection && targetCell != anchorCell ) {
+					beganCellSelection = true;
+				}
+			}
+
+			// Yep, not making a cell selection yet. See method docs.
+			if ( !beganCellSelection ) {
+				return;
+			}
+
+			blockSelectionChange = true;
+			this._setCellSelection( anchorCell, targetCell );
+
+			domEventData.preventDefault();
+		} );
+
+		this.listenTo( editor.editing.view.document, 'mouseup', () => {
+			beganCellSelection = false;
+			blockSelectionChange = false;
+			anchorCell = null;
+			targetCell = null;
+		} );
+
+		// See the explanation in `_enableShiftClickSelection()`.
+		this.listenTo( editor.editing.view.document, 'selectionChange', evt => {
+			if ( blockSelectionChange ) {
+				// @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );
+
+				evt.stop();
+			}
+		}, { priority: 'highest' } );
 	}
 	}
 
 
 	/**
 	/**
-	 * Stops the current selection process and clears the table selection in the model.
-	 *
-	 *		editor.plugins.get( 'TableSelection' ).startSelectingFrom( startTableCell );
-	 *		editor.plugins.get( 'TableSelection' ).setSelectingTo( endTableCell );
-	 *		editor.plugins.get( 'TableSelection' ).stopSelection();
+	 * Creates a listener that reacts to changes in {@link #isEnabled} and, if the plugin was disabled,
+	 * it collapses the multi-cell selection to a regular selection placed inside a table cell.
 	 *
 	 *
-	 *		editor.plugins.get( 'TableSelection' ).clearSelection();
+	 * This listener helps features that disable the table selection plugin bring the selection
+	 * to a clear state they can work with (for instance, because they don't support multiple cell selection).
 	 */
 	 */
-	clearSelection() {
-		this._startElement = undefined;
-		this._endElement = undefined;
+	_enablePluginDisabling() {
+		const editor = this.editor;
+
+		this.on( 'change:isEnabled', () => {
+			if ( !this.isEnabled ) {
+				const selectedCells = this.getSelectedTableCells();
+
+				if ( !selectedCells ) {
+					return;
+				}
+
+				editor.model.change( writer => {
+					const position = writer.createPositionAt( selectedCells[ 0 ], 0 );
+					const range = editor.model.schema.getNearestSelectionRange( position );
+
+					writer.setSelection( range );
+				} );
+			}
+		} );
 	}
 	}
 
 
 	/**
 	/**
-	 * Returns an iterator for selected table cells.
-	 *
-	 *		tableSelection.startSelectingFrom( startTableCell );
-	 *		tableSelection.stopSelection( endTableCell );
+	 * Overrides the default `model.deleteContent()` behavior over a selected table fragment.
 	 *
 	 *
-	 *		const selectedTableCells = Array.from( tableSelection.getSelectedTableCells() );
-	 *		// The above array will represent a rectangular table selection.
-	 *
-	 * @returns {Iterable.<module:engine/model/element~Element>}
+	 * @private
+	 * @param {module:utils/eventinfo~EventInfo} event
+	 * @param {Array.<*>} args Delete content method arguments.
 	 */
 	 */
-	* getSelectedTableCells() {
-		if ( !this.hasMultiCellSelection ) {
+	_handleDeleteContent( event, args ) {
+		const [ selection, options ] = args;
+		const model = this.editor.model;
+		const isBackward = !options || options.direction == 'backward';
+		const selectedTableCells = getSelectedTableCells( selection );
+
+		if ( !selectedTableCells.length ) {
 			return;
 			return;
 		}
 		}
 
 
-		const startLocation = this._tableUtils.getCellLocation( this._startElement );
-		const endLocation = this._tableUtils.getCellLocation( this._endElement );
+		event.stop();
 
 
-		const startRow = Math.min( startLocation.row, endLocation.row );
-		const endRow = Math.max( startLocation.row, endLocation.row );
+		model.change( writer => {
+			const tableCellToSelect = selectedTableCells[ isBackward ? selectedTableCells.length - 1 : 0 ];
 
 
-		const startColumn = Math.min( startLocation.column, endLocation.column );
-		const endColumn = Math.max( startLocation.column, endLocation.column );
+			model.change( writer => {
+				for ( const tableCell of selectedTableCells ) {
+					model.deleteContent( writer.createSelection( tableCell, 'in' ) );
+				}
+			} );
 
 
-		for ( const cellInfo of new TableWalker( findAncestor( 'table', this._startElement ), { startRow, endRow } ) ) {
-			if ( cellInfo.column >= startColumn && cellInfo.column <= endColumn ) {
-				yield cellInfo.cell;
+			const rangeToSelect = model.schema.getNearestSelectionRange( writer.createPositionAt( tableCellToSelect, 0 ) );
+
+			// Note: we ignore the case where rangeToSelect may be null because deleteContent() will always (unless someone broke it)
+			// create an empty paragraph to accommodate the selection.
+
+			if ( selection.is( 'documentSelection' ) ) {
+				writer.setSelection( rangeToSelect );
+			} else {
+				selection.setTo( rangeToSelect );
 			}
 			}
-		}
+		} );
 	}
 	}
 
 
 	/**
 	/**
-	 * Returns selected table fragment as a document fragment.
+	 * Sets the model selection based on given anchor and target cells (can be the same cell).
+	 * Takes care of setting the backward flag.
 	 *
 	 *
-	 * @returns {module:engine/model/documentfragment~DocumentFragment|undefined}
+	 * @protected
+	 * @param {module:engine/model/element~Element} anchorCell
+	 * @param {module:engine/model/element~Element} targetCell
 	 */
 	 */
-	getSelectionAsFragment() {
-		if ( !this.hasMultiCellSelection ) {
-			return;
-		}
-
-		return this.editor.model.change( writer => {
-			const documentFragment = writer.createDocumentFragment();
-
-			const table = cropTable( this.getSelectedTableCells(), this._tableUtils, writer );
-			writer.insert( table, documentFragment, 0 );
-
-			return documentFragment;
+	_setCellSelection( anchorCell, targetCell ) {
+		const cellsToSelect = this._getCellsToSelect( anchorCell, targetCell );
+
+		this.editor.model.change( writer => {
+			writer.setSelection(
+				cellsToSelect.cells.map( cell => writer.createRangeOn( cell ) ),
+				{ backward: cellsToSelect.backward }
+			);
 		} );
 		} );
 	}
 	}
 
 
 	/**
 	/**
-	 * Synchronizes the model selection with currently selected table cells.
+	 * Returns the model table cell element based on the target element of the passed DOM event.
 	 *
 	 *
 	 * @private
 	 * @private
+	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
+	 * @returns {module:engine/model/element~Element|undefined} Returns the table cell or `undefined`.
 	 */
 	 */
-	_updateModelSelection() {
-		if ( !this.hasMultiCellSelection ) {
-			return;
+	_getModelTableCellFromDomEvent( domEventData ) {
+		// Note: Work with positions (not element mapping) because the target element can be an attribute or other non-mapped element.
+		const viewTargetElement = domEventData.target;
+		const viewPosition = this.editor.editing.view.createPositionAt( viewTargetElement, 0 );
+		const modelPosition = this.editor.editing.mapper.toModelPosition( viewPosition );
+		const modelElement = modelPosition.parent;
+
+		if ( modelElement.is( 'tableCell' ) ) {
+			return modelElement;
 		}
 		}
 
 
-		const editor = this.editor;
-		const model = editor.model;
-
-		const modelRanges = [];
-
-		for ( const tableCell of this.getSelectedTableCells() ) {
-			modelRanges.push( model.createRangeOn( tableCell ) );
-		}
-
-		// Update model's selection
-		model.change( writer => {
-			writer.setSelection( modelRanges );
-		} );
+		return findAncestor( 'tableCell', modelElement );
 	}
 	}
 
 
 	/**
 	/**
-	 * Checks if the selection has changed via an external change and if it is required to clear the internal state of the plugin.
+	 * Returns an array of table cells that should be selected based on the
+	 * given anchor cell and target (focus) cell.
+	 *
+	 * The cells are returned in a reverse direction if the selection is backward.
 	 *
 	 *
-	 * @param {module:engine/model/documentselection~DocumentSelection} selection
 	 * @private
 	 * @private
+	 * @param {module:engine/model/element~Element} anchorCell
+	 * @param {module:engine/model/element~Element} targetCell
+	 * @returns {Array.<module:engine/model/element~Element>}
 	 */
 	 */
-	_clearSelectionOnExternalChange( selection ) {
-		if ( selection.rangeCount <= 1 && this.hasMultiCellSelection ) {
-			this.clearSelection();
+	_getCellsToSelect( anchorCell, targetCell ) {
+		const tableUtils = this.editor.plugins.get( 'TableUtils' );
+		const startLocation = tableUtils.getCellLocation( anchorCell );
+		const endLocation = tableUtils.getCellLocation( targetCell );
+
+		const startRow = Math.min( startLocation.row, endLocation.row );
+		const endRow = Math.max( startLocation.row, endLocation.row );
+
+		const startColumn = Math.min( startLocation.column, endLocation.column );
+		const endColumn = Math.max( startLocation.column, endLocation.column );
+
+		const cells = [];
+
+		for ( const cellInfo of new TableWalker( findAncestor( 'table', anchorCell ), { startRow, endRow } ) ) {
+			if ( cellInfo.column >= startColumn && cellInfo.column <= endColumn ) {
+				cells.push( cellInfo.cell );
+			}
+		}
+
+		// A selection started in the bottom right corner and finished in the upper left corner
+		// should have it ranges returned in the reverse order.
+		// However, this is only half of the story because the selection could be made to the left (then the left cell is a focus)
+		// or to the right (then the right cell is a focus), while being a forward selection in both cases
+		// (because it was made from top to bottom). This isn't handled.
+		// This method would need to be smarter, but the ROI is microscopic, so I skip this.
+		if ( checkIsBackward( startLocation, endLocation ) ) {
+			return { cells: cells.reverse(), backward: true };
 		}
 		}
+
+		return { cells, backward: false };
 	}
 	}
 }
 }
+
+// Naively check whether the selection should be backward or not. See the longer explanation where this function is used.
+function checkIsBackward( startLocation, endLocation ) {
+	if ( startLocation.row > endLocation.row ) {
+		return true;
+	}
+
+	if ( startLocation.row == endLocation.row && startLocation.column > endLocation.column ) {
+		return true;
+	}
+
+	return false;
+}
+
+function haveSameTableParent( cellA, cellB ) {
+	return cellA.parent.parent == cellB.parent.parent;
+}

+ 0 - 49
packages/ckeditor5-table/src/tableselection/converters.js

@@ -1,49 +0,0 @@
-/**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/**
- * @module table/tableselection/converters
- */
-
-/**
- * Adds a visual highlight style to selected table cells.
- *
- * @param {module:core/editor/editor~Editor} editor
- * @param {module:table/tableselection~TableSelection} tableSelection
- */
-export function setupTableSelectionHighlighting( editor, tableSelection ) {
-	const highlighted = new Set();
-
-	editor.conversion.for( 'editingDowncast' ).add( dispatcher => dispatcher.on( 'selection', ( evt, data, conversionApi ) => {
-		const view = editor.editing.view;
-		const viewWriter = conversionApi.writer;
-		const viewSelection = viewWriter.document.selection;
-
-		if ( tableSelection.hasMultiCellSelection ) {
-			clearHighlightedTableCells( highlighted, view );
-
-			for ( const tableCell of tableSelection.getSelectedTableCells() ) {
-				const viewElement = conversionApi.mapper.toViewElement( tableCell );
-
-				viewWriter.addClass( 'ck-editor__editable_selected', viewElement );
-				highlighted.add( viewElement );
-			}
-
-			viewWriter.setSelection( viewSelection.getRanges(), { fake: true, label: 'TABLE' } );
-		} else {
-			clearHighlightedTableCells( highlighted, view );
-		}
-	}, { priority: 'lowest' } ) );
-}
-
-function clearHighlightedTableCells( highlighted, view ) {
-	const previous = [ ...highlighted.values() ];
-
-	view.change( writer => {
-		for ( const previouslyHighlighted of previous ) {
-			writer.removeClass( 'ck-editor__editable_selected', previouslyHighlighted );
-		}
-	} );
-}

+ 4 - 4
packages/ckeditor5-table/src/tableselection/croptable.js

@@ -10,16 +10,16 @@
 import { findAncestor } from '../commands/utils';
 import { findAncestor } from '../commands/utils';
 
 
 /**
 /**
- * Returns cropped table from selected table cells.
+ * Returns a cropped table from the selected table cells.
  *
  *
- * This is to be used with table selection
+ * This function is to be used with the table selection.
  *
  *
  *		tableSelection.startSelectingFrom( startCell )
  *		tableSelection.startSelectingFrom( startCell )
  *		tableSelection.setSelectingFrom( endCell )
  *		tableSelection.setSelectingFrom( endCell )
  *
  *
- *		const croppedTable = cropTable( tableSelection.getSelectedTableCells );
+ *		const croppedTable = cropTable( tableSelection.getSelectedTableCells() );
  *
  *
- * **Note**: This function is used also by {@link module:table/tableselection~TableSelection#getSelectionAsFragment}
+ * **Note**: This function is also used by {@link module:table/tableselection~TableSelection#getSelectionAsFragment}.
  *
  *
  * @param {Iterable.<module:engine/model/element~Element>} selectedTableCellsIterator
  * @param {Iterable.<module:engine/model/element~Element>} selectedTableCellsIterator
  * @param {module:table/tableutils~TableUtils} tableUtils
  * @param {module:table/tableutils~TableUtils} tableUtils

+ 7 - 7
packages/ckeditor5-table/src/tableselection/mouseeventsobserver.js

@@ -10,18 +10,18 @@
 import DomEventObserver from '@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver';
 import DomEventObserver from '@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver';
 
 
 /**
 /**
- * The mouse selection events observer.
+ * The mouse selection event observer.
  *
  *
- * It registers listeners for DOM events:
+ * It registers listeners for the following DOM events:
  *
  *
  * - `'mousemove'`
  * - `'mousemove'`
  * - `'mouseup'`
  * - `'mouseup'`
  * - `'mouseleave'`
  * - `'mouseleave'`
  *
  *
- * Note that this observer is disabled by default. To enable this observer it needs to be added to
+ * Note that this observer is disabled by default. To enable this observer, it needs to be added to
  * {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  * {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  *
  *
- * It is registered by {@link module:table/tableselection/mouseselectionhandler~MouseSelectionHandler}.
+ * The observer is registered by the {@link module:table/tableselection~TableSelection} plugin.
  *
  *
  * @extends module:engine/view/observer/domeventobserver~DomEventObserver
  * @extends module:engine/view/observer/domeventobserver~DomEventObserver
  */
  */
@@ -48,7 +48,7 @@ export default class MouseEventsObserver extends DomEventObserver {
  *
  *
  * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.
  * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.
  *
  *
- * Note that this event is not available by default. To make it available
+ * Note that this event is not available by default. To make it available,
  * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added
  * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added
  * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  *
  *
@@ -62,7 +62,7 @@ export default class MouseEventsObserver extends DomEventObserver {
  *
  *
  * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.
  * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.
  *
  *
- * Note that this event is not available by default. To make it available
+ * Note that this event is not available by default. To make it available,
  * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added
  * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added
  * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  *
  *
@@ -76,7 +76,7 @@ export default class MouseEventsObserver extends DomEventObserver {
  *
  *
  * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.
  * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.
  *
  *
- * Note that this event is not available by default. To make it available
+ * Note that this event is not available by default. To make it available,
  * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added
  * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added
  * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.
  *
  *

+ 0 - 160
packages/ckeditor5-table/src/tableselection/mouseselectionhandler.js

@@ -1,160 +0,0 @@
-/**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/**
- * @module table/tableselection/mouseselectionhandler
- */
-
-import mix from '@ckeditor/ckeditor5-utils/src/mix';
-import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
-
-import { findAncestor } from '../commands/utils';
-import MouseEventsObserver from './mouseeventsobserver';
-
-/**
- * A mouse selection handler class for the table selection.
- *
- * It registers the {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} to observe view document mouse events
- * and invoke proper {@link module:table/tableselection~TableSelection} actions.
- */
-export default class MouseSelectionHandler {
-	/**
-	 * Creates an instance of the `MouseSelectionHandler`.
-	 *
-	 * @param {module:table/tableselection~TableSelection} tableSelection
-	 * @param {module:engine/controller/editingcontroller~EditingController} editing
-	 */
-	constructor( tableSelection, editing ) {
-		/**
-		 * The table selection plugin instance.
-		 *
-		 * @private
-		 * @readonly
-		 * @member {module:table/tableselection~TableSelection}
-		 */
-		this._tableSelection = tableSelection;
-
-		/**
-		 * A flag indicating that the mouse selection is "active". A selection is "active" if it was started and not yet finished.
-		 * A selection can be "active", for instance, if a user moves a mouse over a table while holding a mouse button down.
-		 *
-		 * @readonly
-		 * @member {Boolean}
-		 */
-		this.isSelecting = false;
-
-		/**
-		 * Editing mapper.
-		 *
-		 * @private
-		 * @readonly
-		 * @member {module:engine/conversion/mapper~Mapper}
-		 */
-		this._mapper = editing.mapper;
-
-		const view = editing.view;
-
-		// Currently the MouseObserver only handles `mouseup` events.
-		view.addObserver( MouseEventsObserver );
-
-		this.listenTo( view.document, 'mousedown', ( event, domEventData ) => this._handleMouseDown( domEventData ) );
-		this.listenTo( view.document, 'mousemove', ( event, domEventData ) => this._handleMouseMove( domEventData ) );
-		this.listenTo( view.document, 'mouseup', ( event, domEventData ) => this._handleMouseUp( domEventData ) );
-	}
-
-	/**
-	 * Handles starting a selection when "mousedown" event has table cell as a DOM target.
-	 *
-	 * If there is no table cell in the event target, it will clear the previous selection.
-	 *
-	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
-	 * @private
-	 */
-	_handleMouseDown( domEventData ) {
-		const tableCell = this._getModelTableCellFromDomEvent( domEventData );
-
-		if ( !tableCell ) {
-			this._tableSelection.clearSelection();
-			this._tableSelection.stopSelection();
-
-			return;
-		}
-
-		this.isSelecting = true;
-		this._tableSelection.startSelectingFrom( tableCell );
-	}
-
-	/**
-	 * Handles updating the table selection when the "mousemove" event has a table cell as a DOM target.
-	 *
-	 * Does nothing if there is no table cell in event target or the selection has not been started yet.
-	 *
-	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
-	 * @private
-	 */
-	_handleMouseMove( domEventData ) {
-		if ( !isButtonPressed( domEventData ) ) {
-			this._tableSelection.stopSelection();
-
-			return;
-		}
-
-		const tableCell = this._getModelTableCellFromDomEvent( domEventData );
-
-		if ( !tableCell ) {
-			return;
-		}
-
-		this._tableSelection.setSelectingTo( tableCell );
-	}
-
-	/**
-	 * Handles ending (not clearing) the table selection on the "mouseup" event.
-	 *
-	 * Does nothing if the selection has not been started yet.
-	 *
-	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
-	 * @private
-	 */
-	_handleMouseUp( domEventData ) {
-		if ( !this.isSelecting ) {
-			return;
-		}
-
-		const tableCell = this._getModelTableCellFromDomEvent( domEventData );
-
-		// Selection can be stopped if table cell is undefined.
-		this._tableSelection.stopSelection( tableCell );
-	}
-
-	/**
-	 * Finds a model table cell for a given DOM event.
-	 *
-	 * @private
-	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
-	 * @returns {module:engine/model/element~Element|undefined} Returns model table cell or undefined event target is not
-	 * a mapped table cell.
-	 */
-	_getModelTableCellFromDomEvent( domEventData ) {
-		const viewTargetElement = domEventData.target;
-		const modelElement = this._mapper.toModelElement( viewTargetElement );
-
-		if ( !modelElement ) {
-			return;
-		}
-
-		if ( modelElement.is( 'tableCell' ) ) {
-			return modelElement;
-		}
-
-		return findAncestor( 'tableCell', modelElement );
-	}
-}
-
-mix( MouseSelectionHandler, ObservableMixin );
-
-function isButtonPressed( domEventData ) {
-	return !!domEventData.domEvent.buttons;
-}

+ 22 - 0
packages/ckeditor5-table/src/tableui.js

@@ -113,6 +113,13 @@ export default class TableUI extends Plugin {
 						commandName: 'removeTableColumn',
 						commandName: 'removeTableColumn',
 						label: t( 'Delete column' )
 						label: t( 'Delete column' )
 					}
 					}
+				},
+				{
+					type: 'button',
+					model: {
+						commandName: 'selectTableColumn',
+						label: t( 'Select column' )
+					}
 				}
 				}
 			];
 			];
 
 
@@ -150,6 +157,13 @@ export default class TableUI extends Plugin {
 						commandName: 'removeTableRow',
 						commandName: 'removeTableRow',
 						label: t( 'Delete row' )
 						label: t( 'Delete row' )
 					}
 					}
+				},
+				{
+					type: 'button',
+					model: {
+						commandName: 'selectTableRow',
+						label: t( 'Select row' )
+					}
 				}
 				}
 			];
 			];
 
 
@@ -187,6 +201,14 @@ export default class TableUI extends Plugin {
 					}
 					}
 				},
 				},
 				{ type: 'separator' },
 				{ type: 'separator' },
+				{
+					type: 'button',
+					model: {
+						commandName: 'mergeTableCells',
+						label: t( 'Merge cells' )
+					}
+				},
+				{ type: 'separator' },
 				{
 				{
 					type: 'button',
 					type: 'button',
 					model: {
 					model: {

+ 15 - 2
packages/ckeditor5-table/src/tableutils.js

@@ -108,7 +108,7 @@ export default class TableUtils extends Plugin {
 	 *		    |   | f | g |                      |   |   |   |
 	 *		    |   | f | g |                      |   |   |   |
 	 *		  3 +---+---+---+                      +   +---+---+ 3
 	 *		  3 +---+---+---+                      +   +---+---+ 3
 	 *		                                       |   | d | e |
 	 *		                                       |   | d | e |
-	 *		                                       +---+---+---+ 4
+	 *		                                       +   +---+---+ 4
 	 *		                                       +   + f | g |
 	 *		                                       +   + f | g |
 	 *		                                       +---+---+---+ 5
 	 *		                                       +---+---+---+ 5
 	 *
 	 *
@@ -228,7 +228,7 @@ export default class TableUtils extends Plugin {
 				const rowspan = parseInt( cell.getAttribute( 'rowspan' ) || 1 );
 				const rowspan = parseInt( cell.getAttribute( 'rowspan' ) || 1 );
 				const colspan = parseInt( cell.getAttribute( 'colspan' ) || 1 );
 				const colspan = parseInt( cell.getAttribute( 'colspan' ) || 1 );
 
 
-				if ( cell.index !== insertAt && colspan > 1 ) {
+				if ( cellIndex !== insertAt && colspan > 1 ) {
 					// If column is different than `insertAt`, it is a cell that spans over an inserted column (cell "a" & "i").
 					// If column is different than `insertAt`, it is a cell that spans over an inserted column (cell "a" & "i").
 					// For such cells expand them by a number of columns inserted.
 					// For such cells expand them by a number of columns inserted.
 					writer.setAttribute( 'colspan', colspan + columnsToInsert, cell );
 					writer.setAttribute( 'colspan', colspan + columnsToInsert, cell );
@@ -550,6 +550,19 @@ export default class TableUtils extends Plugin {
 			return columns + columnWidth;
 			return columns + columnWidth;
 		}, 0 );
 		}, 0 );
 	}
 	}
+
+	/**
+	 * Returns the number of rows for a given table.
+	 *
+	 *		editor.plugins.get( 'TableUtils' ).getRows( table );
+	 *
+	 * @param {module:engine/model/element~Element} table The table to analyze.
+	 * @returns {Number}
+	 */
+	getRows( table ) {
+		// Simple row counting, not including rowspan due to #6427.
+		return table.childCount;
+	}
 }
 }
 
 
 // Creates empty rows at the given index in an existing table.
 // Creates empty rows at the given index in an existing table.

+ 3 - 1
packages/ckeditor5-table/src/ui/colorinputview.js

@@ -138,6 +138,7 @@ export default class ColorInputView extends View {
 	 */
 	 */
 	_createDropdownView() {
 	_createDropdownView() {
 		const locale = this.locale;
 		const locale = this.locale;
+		const t = locale.t;
 		const bind = this.bindTemplate;
 		const bind = this.bindTemplate;
 		const colorGrid = this._createColorGrid( locale );
 		const colorGrid = this._createColorGrid( locale );
 		const dropdown = createDropdown( locale );
 		const dropdown = createDropdown( locale );
@@ -174,8 +175,9 @@ export default class ColorInputView extends View {
 		} );
 		} );
 
 
 		dropdown.buttonView.children.add( colorPreview );
 		dropdown.buttonView.children.add( colorPreview );
+		dropdown.buttonView.tooltip = t( 'Color picker' );
 
 
-		dropdown.panelPosition = 'sw';
+		dropdown.panelPosition = locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw';
 		dropdown.panelView.children.add( removeColorButton );
 		dropdown.panelView.children.add( removeColorButton );
 		dropdown.panelView.children.add( colorGrid );
 		dropdown.panelView.children.add( colorGrid );
 		dropdown.bind( 'isEnabled' ).to( this, 'isReadOnly', value => !value );
 		dropdown.bind( 'isEnabled' ).to( this, 'isReadOnly', value => !value );

+ 0 - 90
packages/ckeditor5-table/src/ui/formheaderview.js

@@ -1,90 +0,0 @@
-/**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/**
- * @module table/ui/formheaderview
- */
-
-import View from '@ckeditor/ckeditor5-ui/src/view';
-
-import '../../theme/formheader.css';
-
-/**
- * The class representing a header in a complex form.
- *
- * **Note**: For now this class is private. When more use cases arrive (beyond ckeditor5-table),
- * it will become a component in ckeditor5-ui.
- *
- * @private
- * @extends module:ui/view~View
- */
-export default class FormHeaderView extends View {
-	/**
-	 * Creates an instance of the form header view class.
-	 *
-	 * @param {module:utils/locale~Locale} locale The locale instance.
-	 * @param {Object} [options]
-	 * @param {String} [options.class] When passed, the class will be set on the header element.
-	 * @param {String} [options.label] When passed, the label will be used for the header.
-	 */
-	constructor( locale, options = {} ) {
-		super( locale );
-
-		const bind = this.bindTemplate;
-
-		/**
-		 * A collection of header items.
-		 *
-		 * @readonly
-		 * @member {module:ui/viewcollection~ViewCollection}
-		 */
-		this.children = this.createCollection();
-
-		/**
-		 * An additional CSS class added to the {@link #element}.
-		 *
-		 * @observable
-		 * @member {String} #class
-		 */
-		this.set( 'class', options.class || null );
-
-		/**
-		 * The label of the header.
-		 *
-		 * @readonly
-		 * @member {String} #label
-		 */
-		this.set( 'label', options.label || '' );
-
-		const label = new View( locale );
-
-		label.setTemplate( {
-			tag: 'span',
-			attributes: {
-				class: [
-					'ck',
-					'ck-form__header__label'
-				]
-			},
-			children: [
-				{ text: bind.to( 'label' ) }
-			]
-		} );
-
-		this.children.add( label );
-
-		this.setTemplate( {
-			tag: 'div',
-			attributes: {
-				class: [
-					'ck',
-					'ck-form__header',
-					bind.to( 'class' )
-				]
-			},
-			children: this.children
-		} );
-	}
-}

+ 66 - 12
packages/ckeditor5-table/src/ui/utils.js

@@ -15,6 +15,7 @@ import ColorInputView from './colorinputview';
 import { isColor, isLength, isPercentage } from '@ckeditor/ckeditor5-engine/src/view/styles/utils';
 import { isColor, isLength, isPercentage } from '@ckeditor/ckeditor5-engine/src/view/styles/utils';
 import { getTableWidgetAncestor } from '../utils';
 import { getTableWidgetAncestor } from '../utils';
 import { findAncestor } from '../commands/utils';
 import { findAncestor } from '../commands/utils';
+import Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';
 
 
 const DEFAULT_BALLOON_POSITIONS = BalloonPanelView.defaultPositions;
 const DEFAULT_BALLOON_POSITIONS = BalloonPanelView.defaultPositions;
 const BALLOON_POSITIONS = [
 const BALLOON_POSITIONS = [
@@ -81,12 +82,26 @@ export function getBalloonTablePositionData( editor ) {
  * @returns {module:utils/dom/position~Options}
  * @returns {module:utils/dom/position~Options}
  */
  */
 export function getBalloonCellPositionData( editor ) {
 export function getBalloonCellPositionData( editor ) {
-	const firstPosition = editor.model.document.selection.getFirstPosition();
-	const modelTableCell = findAncestor( 'tableCell', firstPosition );
-	const viewTableCell = editor.editing.mapper.toViewElement( modelTableCell );
+	const mapper = editor.editing.mapper;
+	const domConverter = editor.editing.view.domConverter;
+	const selection = editor.model.document.selection;
+
+	if ( selection.rangeCount > 1 ) {
+		return {
+			target: () => createBoundingRect( selection.getRanges(), modelRange => {
+				const modelTableCell = getTableCellAtPosition( modelRange.start );
+				const viewTableCell = mapper.toViewElement( modelTableCell );
+				return new Rect( domConverter.viewToDom( viewTableCell ) );
+			} ),
+			positions: BALLOON_POSITIONS
+		};
+	}
+
+	const modelTableCell = getTableCellAtPosition( selection.getFirstPosition() );
+	const viewTableCell = mapper.toViewElement( modelTableCell );
 
 
 	return {
 	return {
-		target: editor.editing.view.domConverter.viewToDom( viewTableCell ),
+		target: domConverter.viewToDom( viewTableCell ),
 		positions: BALLOON_POSITIONS
 		positions: BALLOON_POSITIONS
 	};
 	};
 }
 }
@@ -241,7 +256,8 @@ export function fillToolbar( { view, icons, toolbar, labels, propertyName, nameT
 
 
 		button.set( {
 		button.set( {
 			label: labels[ name ],
 			label: labels[ name ],
-			icon: icons[ name ]
+			icon: icons[ name ],
+			tooltip: labels[ name ]
 		} );
 		} );
 
 
 		button.bind( 'isOn' ).to( view, propertyName, value => {
 		button.bind( 'isOn' ).to( view, propertyName, value => {
@@ -397,7 +413,7 @@ export const defaultColors = [
  *
  *
  * For given options, it returns a function that creates an instance of a
  * For given options, it returns a function that creates an instance of a
  * {@link module:table/ui/colorinputview~ColorInputView color input} logically related to
  * {@link module:table/ui/colorinputview~ColorInputView color input} logically related to
- * a {@link module:ui/labeledview/labeledview~LabeledView labeled view} in the DOM.
+ * a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in the DOM.
  *
  *
  * The helper does the following:
  * The helper does the following:
  *
  *
@@ -413,7 +429,7 @@ export const defaultColors = [
  *			columns: 3,
  *			columns: 3,
  *		} );
  *		} );
  *
  *
- *		const labeledInputView = new LabeledView( locale, colorInputCreator );
+ *		const labeledInputView = new LabeledFieldView( locale, colorInputCreator );
  *		console.log( labeledInputView.view ); // A color input instance.
  *		console.log( labeledInputView.view ); // A color input instance.
  *
  *
  * @private
  * @private
@@ -425,8 +441,8 @@ export const defaultColors = [
  * @returns {Function}
  * @returns {Function}
  */
  */
 export function getLabeledColorInputCreator( options ) {
 export function getLabeledColorInputCreator( options ) {
-	return ( labeledView, viewUid, statusUid ) => {
-		const inputView = new ColorInputView( labeledView.locale, {
+	return ( labeledFieldView, viewUid, statusUid ) => {
+		const inputView = new ColorInputView( labeledFieldView.locale, {
 			colorDefinitions: colorConfigToColorGridDefinitions( options.colorConfig ),
 			colorDefinitions: colorConfigToColorGridDefinitions( options.colorConfig ),
 			columns: options.columns
 			columns: options.columns
 		} );
 		} );
@@ -436,13 +452,13 @@ export function getLabeledColorInputCreator( options ) {
 			ariaDescribedById: statusUid
 			ariaDescribedById: statusUid
 		} );
 		} );
 
 
-		inputView.bind( 'isReadOnly' ).to( labeledView, 'isEnabled', value => !value );
-		inputView.bind( 'errorText' ).to( labeledView );
+		inputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );
+		inputView.bind( 'errorText' ).to( labeledFieldView );
 
 
 		inputView.on( 'input', () => {
 		inputView.on( 'input', () => {
 			// UX: Make the error text disappear and disable the error indicator as the user
 			// UX: Make the error text disappear and disable the error indicator as the user
 			// starts fixing the errors.
 			// starts fixing the errors.
-			labeledView.errorText = null;
+			labeledFieldView.errorText = null;
 		} );
 		} );
 
 
 		return inputView;
 		return inputView;
@@ -468,3 +484,41 @@ function colorConfigToColorGridDefinitions( colorConfig ) {
 		}
 		}
 	} ) );
 	} ) );
 }
 }
+
+// Returns the first selected table cell from a multi-cell or in-cell selection.
+//
+// @param {module:engine/model/position~Position} position Document position.
+// @returns {module:engine/model/element~Element}
+function getTableCellAtPosition( position ) {
+	const isTableCellSelected = position.nodeAfter && position.nodeAfter.is( 'tableCell' );
+
+	return isTableCellSelected ? position.nodeAfter : findAncestor( 'tableCell', position );
+}
+
+// Returns bounding rect for list of rects.
+//
+// @param {Array.<module:utils/dom/rect~Rect>|Array.<*>} list List of `Rect`s or any list to map by `mapFn`.
+// @param {Function} mapFn Mapping function for list elements.
+// @returns {module:utils/dom/rect~Rect}
+function createBoundingRect( list, mapFn ) {
+	const rectData = {
+		left: Number.POSITIVE_INFINITY,
+		top: Number.POSITIVE_INFINITY,
+		right: Number.NEGATIVE_INFINITY,
+		bottom: Number.NEGATIVE_INFINITY
+	};
+
+	for ( const item of list ) {
+		const rect = mapFn( item );
+
+		rectData.left = Math.min( rectData.left, rect.left );
+		rectData.top = Math.min( rectData.top, rect.top );
+		rectData.right = Math.max( rectData.right, rect.right );
+		rectData.bottom = Math.max( rectData.bottom, rect.bottom );
+	}
+
+	rectData.width = rectData.right - rectData.left;
+	rectData.height = rectData.bottom - rectData.top;
+
+	return new Rect( rectData );
+}

+ 106 - 0
packages/ckeditor5-table/src/utils.js

@@ -67,3 +67,109 @@ export function getTableWidgetAncestor( selection ) {
 
 
 	return null;
 	return null;
 }
 }
+
+/**
+ * Returns all model table cells that are fully selected (from the outside)
+ * within the provided model selection's ranges.
+ *
+ * To obtain the cells selected from the inside, use
+ * {@link module:table/utils~getTableCellsContainingSelection}.
+ *
+ * @param {module:engine/model/selection~Selection} selection
+ * @returns {Array.<module:engine/model/element~Element>}
+ */
+export function getSelectedTableCells( selection ) {
+	const cells = [];
+
+	for ( const range of sortRanges( selection.getRanges() ) ) {
+		const element = range.getContainedElement();
+
+		if ( element && element.is( 'tableCell' ) ) {
+			cells.push( element );
+		}
+	}
+
+	return cells;
+}
+
+/**
+ * Returns all model table cells that the provided model selection's ranges
+ * {@link module:engine/model/range~Range#start} inside.
+ *
+ * To obtain the cells selected from the outside, use
+ * {@link module:table/utils~getSelectedTableCells}.
+ *
+ * @param {module:engine/model/selection~Selection} selection
+ * @returns {Array.<module:engine/model/element~Element>}
+ */
+export function getTableCellsContainingSelection( selection ) {
+	const cells = [];
+
+	for ( const range of selection.getRanges() ) {
+		const cellWithSelection = findAncestor( 'tableCell', range.start );
+
+		if ( cellWithSelection ) {
+			cells.push( cellWithSelection );
+		}
+	}
+
+	return cells;
+}
+
+/**
+ * Returns all model table cells that are either completely selected
+ * by selection ranges or host selection range
+ * {@link module:engine/model/range~Range#start start positions} inside them.
+ *
+ * Combines {@link module:table/utils~getTableCellsContainingSelection} and
+ * {@link module:table/utils~getSelectedTableCells}.
+ *
+ * @param {module:engine/model/selection~Selection} selection
+ * @returns {Array.<module:engine/model/element~Element>}
+ */
+export function getSelectionAffectedTableCells( selection ) {
+	const selectedCells = getSelectedTableCells( selection );
+
+	if ( selectedCells.length ) {
+		return selectedCells;
+	}
+
+	return getTableCellsContainingSelection( selection );
+}
+
+/**
+ * Returns a helper object with `first` and `last` row index contained in given `tableCells`.
+ *
+ *		const selectedTableCells = getSelectedTableCells( editor.model.document.selection );
+ *
+ *		const { first, last } = getRowIndexes( selectedTableCells );
+ *
+ *		console.log( `Selected rows ${ first } to ${ last }` );
+ *
+ * @package {Array.<module:engine/model/element~Element>}
+ * @returns {Object} Returns an object with `first` and `last` table row indexes.
+ */
+export function getRowIndexes( tableCells ) {
+	const allIndexesSorted = tableCells.map( cell => cell.parent.index ).sort();
+
+	return {
+		first: allIndexesSorted[ 0 ],
+		last: allIndexesSorted[ allIndexesSorted.length - 1 ]
+	};
+}
+
+function sortRanges( rangesIterator ) {
+	return Array.from( rangesIterator ).sort( compareRangeOrder );
+}
+
+function compareRangeOrder( rangeA, rangeB ) {
+	// Since table cell ranges are disjoint, it's enough to check their start positions.
+	const posA = rangeA.start;
+	const posB = rangeB.start;
+
+	if ( posA.isEqual( posB ) ) {
+		return 0;
+	}
+
+	return posA.isBefore( posB ) ? -1 : 1;
+}

+ 37 - 0
packages/ckeditor5-table/tests/_utils/utils.js

@@ -340,6 +340,43 @@ export function assertTableCellStyle( editor, tableCellStyle ) {
  * The above call will check if table has second column selected (assuming no spans).
  * The above call will check if table has second column selected (assuming no spans).
  *
  *
  * **Note**: This function operates on child indexes - not rows/columns.
  * **Note**: This function operates on child indexes - not rows/columns.
+ *
+ * Examples:
+ *
+ * 		+----+----+----+----+
+ * 		| 00 | 01 | 02 | 03 |
+ * 		+----+    +----+----+
+ * 		|[10]|    |[12]|[13]|
+ * 		+----+----+----+----+
+ * 		| 20 | 21 | 22 | 23 |
+ * 		+----+----+----+----+
+ * 		| 30 | 31      | 33 |
+ * 		+----+----+----+----+
+ *
+ * 		assertSelectedCells( model, [
+ *			[ 0, 0, 0, 0 ],
+ * 			[ 1,    1, 1 ],
+ * 			[ 0, 0, 0, 0 ],
+ *			[ 0, 0,    0 ]
+ *		] );
+ *
+ * 		+----+----+----+----+
+ * 		| 00 |[01]| 02 | 03 |
+ * 		+----+    +----+----+
+ * 		| 10 |    | 12 | 13 |
+ * 		+----+----+----+----+
+ * 		| 20 |[21]| 22 | 23 |
+ * 		+----+----+----+----+
+ * 		| 30 |[31]     | 33 |
+ * 		+----+----+----+----+
+ *
+ * 		assertSelectedCells( model, [
+ *			[ 0, 1, 0, 0 ],
+ * 			[ 0,    0, 0 ],
+ * 			[ 0, 1, 0, 0 ],
+ *			[ 0, 1,    0 ]
+ *		] );
+ *
  */
  */
 export function assertSelectedCells( model, tableMap ) {
 export function assertSelectedCells( model, tableMap ) {
 	const tableIndex = 0;
 	const tableIndex = 0;

+ 58 - 3
packages/ckeditor5-table/tests/commands/insertcolumncommand.js

@@ -7,7 +7,8 @@ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltestedit
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 
 import InsertColumnCommand from '../../src/commands/insertcolumncommand';
 import InsertColumnCommand from '../../src/commands/insertcolumncommand';
-import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import TableSelection from '../../src/tableselection';
+import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
 import TableUtils from '../../src/tableutils';
 import TableUtils from '../../src/tableutils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 
@@ -17,7 +18,7 @@ describe( 'InsertColumnCommand', () => {
 	beforeEach( () => {
 	beforeEach( () => {
 		return ModelTestEditor
 		return ModelTestEditor
 			.create( {
 			.create( {
-				plugins: [ TableUtils ]
+				plugins: [ TableUtils, TableSelection ]
 			} )
 			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
@@ -76,7 +77,7 @@ describe( 'InsertColumnCommand', () => {
 				] ) );
 				] ) );
 			} );
 			} );
 
 
-			it( 'should insert columns at table end', () => {
+			it( 'should insert column at table end', () => {
 				setData( model, modelTable( [
 				setData( model, modelTable( [
 					[ '11', '12' ],
 					[ '11', '12' ],
 					[ '21', '22[]' ]
 					[ '21', '22[]' ]
@@ -90,6 +91,33 @@ describe( 'InsertColumnCommand', () => {
 				] ) );
 				] ) );
 			} );
 			} );
 
 
+			it( 'should insert column after a multi column selection', () => {
+				setData( model, modelTable( [
+					[ '11', '12', '13' ],
+					[ '21', '22', '23' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '11', '12', '', '13' ],
+					[ '21', '22', '', '23' ]
+				] ) );
+
+				assertSelectedCells( model, [
+					[ 1, 1, 0, 0 ],
+					[ 1, 1, 0, 0 ]
+				] );
+			} );
+
 			it( 'should update table heading columns attribute when inserting column in headings section', () => {
 			it( 'should update table heading columns attribute when inserting column in headings section', () => {
 				setData( model, modelTable( [
 				setData( model, modelTable( [
 					[ '11[]', '12' ],
 					[ '11[]', '12' ],
@@ -214,6 +242,33 @@ describe( 'InsertColumnCommand', () => {
 				] ) );
 				] ) );
 			} );
 			} );
 
 
+			it( 'should insert column before a multi column selection', () => {
+				setData( model, modelTable( [
+					[ '11', '12', '13' ],
+					[ '21', '22', '23' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '', '11', '12', '13' ],
+					[ '', '21', '22', '23' ]
+				] ) );
+
+				assertSelectedCells( model, [
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ]
+				] );
+			} );
+
 			it( 'should update table heading columns attribute when inserting column in headings section', () => {
 			it( 'should update table heading columns attribute when inserting column in headings section', () => {
 				setData( model, modelTable( [
 				setData( model, modelTable( [
 					[ '11', '12[]' ],
 					[ '11', '12[]' ],

+ 67 - 2
packages/ckeditor5-table/tests/commands/insertrowcommand.js

@@ -7,7 +7,8 @@ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltestedit
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 
 import InsertRowCommand from '../../src/commands/insertrowcommand';
 import InsertRowCommand from '../../src/commands/insertrowcommand';
-import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import TableSelection from '../../src/tableselection';
+import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
 import TableUtils from '../../src/tableutils';
 import TableUtils from '../../src/tableutils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 
@@ -17,7 +18,7 @@ describe( 'InsertRowCommand', () => {
 	beforeEach( () => {
 	beforeEach( () => {
 		return ModelTestEditor
 		return ModelTestEditor
 			.create( {
 			.create( {
-				plugins: [ TableUtils ]
+				plugins: [ TableUtils, TableSelection ]
 			} )
 			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
@@ -181,6 +182,38 @@ describe( 'InsertRowCommand', () => {
 					[ '', '' ]
 					[ '', '' ]
 				] ) );
 				] ) );
 			} );
 			} );
+
+			it( 'should insert a row when multiple rows are selected', () => {
+				setData( model, modelTable( [
+					[ '11', '12' ],
+					[ '21', '22' ],
+					[ '31', '32' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '11', '12' ],
+					[ '21', '22' ],
+					[ '', '' ],
+					[ '31', '32' ]
+				] ) );
+
+				assertSelectedCells( model, [
+					[ 1, 1 ],
+					[ 1, 1 ],
+					[ 0, 0 ],
+					[ 0, 0 ]
+				] );
+			} );
 		} );
 		} );
 	} );
 	} );
 
 
@@ -284,6 +317,38 @@ describe( 'InsertRowCommand', () => {
 					[ '20[]', '21' ]
 					[ '20[]', '21' ]
 				], { headingRows: 2 } ) );
 				], { headingRows: 2 } ) );
 			} );
 			} );
+
+			it( 'should insert a row when multiple rows are selected', () => {
+				setData( model, modelTable( [
+					[ '11', '12' ],
+					[ '21', '22' ],
+					[ '31', '32' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '', '' ],
+					[ '11', '12' ],
+					[ '21', '22' ],
+					[ '31', '32' ]
+				] ) );
+
+				assertSelectedCells( model, [
+					[ 0, 0 ],
+					[ 1, 1 ],
+					[ 1, 1 ],
+					[ 0, 0 ]
+				] );
+			} );
 		} );
 		} );
 	} );
 	} );
 } );
 } );

+ 60 - 40
packages/ckeditor5-table/tests/commands/mergecellcommand.js

@@ -95,44 +95,46 @@ describe( 'MergeCellCommand', () => {
 				expect( command.isEnabled ).to.be.false;
 				expect( command.isEnabled ).to.be.false;
 			} );
 			} );
 
 
-			it( 'should be false if mergeable cell is in other table section then current cell', () => {
-				setData( model, modelTable( [
-					[ '00[]', '01' ]
-				], { headingColumns: 1 } ) );
+			describe( 'when the heading section is in the table', () => {
+				it( 'should be false if mergeable cell is in other table section then current cell', () => {
+					setData( model, modelTable( [
+						[ '00[]', '01' ]
+					], { headingColumns: 1 } ) );
 
 
-				expect( command.isEnabled ).to.be.false;
-			} );
+					expect( command.isEnabled ).to.be.false;
+				} );
 
 
-			it( 'should be false if merged cell would cross heading section (mergeable cell with colspan)', () => {
-				setData( model, modelTable( [
-					[ '00[]', { colspan: 2, contents: '01' }, '02', '03' ]
-				], { headingColumns: 2 } ) );
+				it( 'should be true if merged cell would not cross heading section (mergeable cell with colspan)', () => {
+					setData( model, modelTable( [
+						[ '00[]', { colspan: 2, contents: '01' }, '02', '03' ]
+					], { headingColumns: 3 } ) );
 
 
-				expect( command.isEnabled ).to.be.false;
-			} );
+					expect( command.isEnabled ).to.be.true;
+				} );
 
 
-			it( 'should be true if merged cell would not cross heading section (mergeable cell with colspan)', () => {
-				setData( model, modelTable( [
-					[ '00[]', { colspan: 2, contents: '01' }, '02', '03' ]
-				], { headingColumns: 3 } ) );
+				it( 'should be false if merged cell would cross heading section (current cell with colspan)', () => {
+					setData( model, modelTable( [
+						[ { colspan: 2, contents: '00[]' }, '01', '02', '03' ]
+					], { headingColumns: 2 } ) );
 
 
-				expect( command.isEnabled ).to.be.true;
-			} );
+					expect( command.isEnabled ).to.be.false;
+				} );
 
 
-			it( 'should be false if merged cell would cross heading section (current cell with colspan)', () => {
-				setData( model, modelTable( [
-					[ { colspan: 2, contents: '00[]' }, '01', '02', '03' ]
-				], { headingColumns: 2 } ) );
+				it( 'should be true if merged cell would not cross heading section (current cell with colspan)', () => {
+					setData( model, modelTable( [
+						[ { colspan: 2, contents: '00[]' }, '01', '02', '03' ]
+					], { headingColumns: 3 } ) );
 
 
-				expect( command.isEnabled ).to.be.false;
-			} );
+					expect( command.isEnabled ).to.be.true;
+				} );
 
 
-			it( 'should be true if merged cell would not cross heading section (current cell with colspan)', () => {
-				setData( model, modelTable( [
-					[ { colspan: 2, contents: '00[]' }, '01', '02', '03' ]
-				], { headingColumns: 3 } ) );
+				it( 'should be true if merged cell would not cross the section boundary (regular section)', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02[]', '03' ]
+					], { headingColumns: 1 } ) );
 
 
-				expect( command.isEnabled ).to.be.true;
+					expect( command.isEnabled ).to.be.true;
+				} );
 			} );
 			} );
 		} );
 		} );
 
 
@@ -315,20 +317,38 @@ describe( 'MergeCellCommand', () => {
 				expect( command.isEnabled ).to.be.false;
 				expect( command.isEnabled ).to.be.false;
 			} );
 			} );
 
 
-			it( 'should be false if mergeable cell is in other table section then current cell', () => {
-				setData( model, modelTable( [
-					[ '00', '01[]' ]
-				], { headingColumns: 1 } ) );
+			describe( 'when the heading section is in the table', () => {
+				it( 'should be false if mergeable cell is in other table section then current cell', () => {
+					setData( model, modelTable( [
+						[ '00', '01[]' ]
+					], { headingColumns: 1 } ) );
 
 
-				expect( command.isEnabled ).to.be.false;
-			} );
+					expect( command.isEnabled ).to.be.false;
+				} );
 
 
-			it( 'should be false if merged cell would cross heading section (mergeable cell with colspan)', () => {
-				setData( model, modelTable( [
-					[ { colspan: 2, contents: '00' }, '02[]', '03' ]
-				], { headingColumns: 2 } ) );
+				it( 'should be false if merged cell would cross heading section (mergeable cell with colspan)', () => {
+					setData( model, modelTable( [
+						[ { colspan: 2, contents: '00' }, '02[]', '03' ]
+					], { headingColumns: 2 } ) );
 
 
-				expect( command.isEnabled ).to.be.false;
+					expect( command.isEnabled ).to.be.false;
+				} );
+
+				it( 'should be true if merged cell would not cross the section boundary (in regular section)', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02[]', '03' ]
+					], { headingColumns: 1 } ) );
+
+					expect( command.isEnabled ).to.be.true;
+				} );
+
+				it( 'should be true if merged cell would not cross the section boundary (in heading section)', () => {
+					setData( model, modelTable( [
+						[ '00', '01[]', '02', '03' ]
+					], { headingColumns: 2 } ) );
+
+					expect( command.isEnabled ).to.be.true;
+				} );
 			} );
 			} );
 		} );
 		} );
 
 

+ 480 - 0
packages/ckeditor5-table/tests/commands/mergecellscommand.js

@@ -0,0 +1,480 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
+import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+
+import MergeCellsCommand from '../../src/commands/mergecellscommand';
+import { modelTable } from '../_utils/utils';
+import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
+import TableSelection from '../../src/tableselection';
+import TableEditing from '../../src/tableediting';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+
+describe( 'MergeCellsCommand', () => {
+	let editor, model, command, root, tableSelection;
+
+	beforeEach( async () => {
+		editor = await ModelTestEditor.create( {
+			plugins: [ Paragraph, TableEditing, TableSelection ]
+		} );
+
+		model = editor.model;
+		root = model.document.getRoot( 'main' );
+		tableSelection = editor.plugins.get( TableSelection );
+
+		command = new MergeCellsCommand( editor );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	describe( 'isEnabled', () => {
+		it( 'should be false if collapsed selection in table cell', () => {
+			setData( model, modelTable( [
+				[ '00[]', '01' ]
+			] ) );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be false if only one table cell is selected', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ] ] );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be true if at least two adjacent table cells are selected', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ], [ 0, 0, 1 ] ] );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true if many table cells are selected', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02', '03' ],
+				[ '10', '11', '12', '13' ],
+				[ '20', '21', '22', '23' ],
+				[ '30', '31', '32', '33' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 0, 1 ], [ 0, 0, 2 ],
+				[ 0, 1, 1 ], [ 0, 1, 2 ],
+				[ 0, 2, 1 ], [ 0, 2, 2 ],
+				[ 0, 3, 1 ], [ 0, 3, 2 ]
+			] );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be false if at least one table cell is not selected from an area', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02', '03' ],
+				[ '10', '11', '12', '13' ],
+				[ '20', '21', '22', '23' ],
+				[ '30', '31', '32', '33' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 0, 1 ], [ 0, 0, 2 ],
+				[ 0, 1, 2 ], // one table cell not selected from this row
+				[ 0, 2, 1 ], [ 0, 2, 2 ],
+				[ 0, 3, 1 ], [ 0, 3, 2 ]
+			] );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be false if table cells are not in adjacent rows', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '10', '11' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 1, 0 ],
+				[ 0, 0, 1 ]
+			] );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be false if table cells are not in adjacent columns', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ], [ 0, 0, 2 ] ] );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be false if any table cell with colspan attribute extends over selection area', () => {
+			setData( model, modelTable( [
+				[ '00', { colspan: 2, contents: '01' } ],
+				[ '10', '11', '12' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 0, 0 ], [ 0, 0, 1 ],
+				[ 0, 1, 0 ], [ 0, 1, 1 ]
+			] );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be true if none table cell with colspan attribute extends over selection area', () => {
+			setData( model, modelTable( [
+				[ '00', { colspan: 2, contents: '01' } ],
+				[ '10', '11', '12' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 0, 0 ], [ 0, 0, 1 ],
+				[ 0, 1, 0 ], [ 0, 1, 1 ],
+				[ 0, 1, 2 ]
+			] );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true if first table cell is inside selection area', () => {
+			setData( model, modelTable( [
+				[ { colspan: 2, rowspan: 2, contents: '00' }, '02', '03' ],
+				[ '12', '13' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 0, 0 ], [ 0, 0, 1 ],
+				[ 0, 1, 0 ]
+			] );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be false if any table cell with rowspan attribute extends over selection area', () => {
+			setData( model, modelTable( [
+				[ '00', { rowspan: 2, contents: '01' } ],
+				[ '10' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ], [ 0, 0, 1 ] ] );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be true if none table cell with rowspan attribute extends over selection area', () => {
+			setData( model, modelTable( [
+				[ '00', { rowspan: 2, contents: '01' } ],
+				[ '10' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 0, 0 ], [ 0, 0, 1 ],
+				[ 0, 1, 0 ]
+			] );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be false if not in a cell', () => {
+			setData( model, '<paragraph>11[]</paragraph>' );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
+		it( 'should be false if selection has cells from header and body sections', () => {
+			setData( model, modelTable( [
+				[ '00[]', '01' ],
+				[ '10', '11' ]
+			], { headingRows: 1 } ) );
+
+			tableSelection._setCellSelection(
+				root.getNodeByPath( [ 0, 0, 0 ] ),
+				root.getNodeByPath( [ 0, 1, 0 ] )
+			);
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+	} );
+
+	describe( 'execute()', () => {
+		it( 'should merge simple table cell selection', () => {
+			setData( model, modelTable( [
+				[ '[]00', '01' ]
+			] ) );
+
+			tableSelection._setCellSelection(
+				root.getNodeByPath( [ 0, 0, 0 ] ),
+				root.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { colspan: 2, contents: '<paragraph>[00</paragraph><paragraph>01]</paragraph>' } ]
+			] ) );
+		} );
+
+		it( 'should merge selection with a cell with rowspan in the selection', () => {
+			setData( model, modelTable( [
+				[ '[]00', '01', '02' ],
+				[ '10', { contents: '11', rowspan: 2 }, '12' ],
+				[ '20', '22' ]
+			] ) );
+
+			tableSelection._setCellSelection(
+				root.getNodeByPath( [ 0, 1, 0 ] ),
+				root.getNodeByPath( [ 0, 2, 1 ] )
+			);
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ '00', '01', '02' ],
+				[ {
+					colspan: 3,
+					contents: '<paragraph>[10</paragraph><paragraph>11</paragraph><paragraph>12</paragraph>' +
+						'<paragraph>20</paragraph><paragraph>22]</paragraph>'
+				} ]
+			] ) );
+		} );
+
+		it( 'should merge selection with a cell with rowspan in the selection (reverse selection)', () => {
+			setData( model, modelTable( [
+				[ '[]00', '01', '02' ],
+				[ '10', { contents: '11', rowspan: 2 }, '12' ],
+				[ '20', '22' ]
+			] ) );
+
+			tableSelection._setCellSelection(
+				root.getNodeByPath( [ 0, 2, 1 ] ),
+				root.getNodeByPath( [ 0, 1, 0 ] )
+			);
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ '00', '01', '02' ],
+				[ {
+					colspan: 3,
+					contents: '<paragraph>[10</paragraph><paragraph>11</paragraph><paragraph>12</paragraph>' +
+						'<paragraph>20</paragraph><paragraph>22]</paragraph>'
+				} ]
+			] ) );
+		} );
+
+		it( 'should merge selection inside a table (properly calculate target rowspan/colspan)', () => {
+			setData( model, modelTable( [
+				[ '[]00', '01', '02', '03' ],
+				[ '10', '11', { contents: '12', rowspan: 2 }, '13' ],
+				[ '20', '21', '23' ],
+				[ '30', '31', '32', '33' ]
+			] ) );
+
+			tableSelection._setCellSelection(
+				root.getNodeByPath( [ 0, 2, 1 ] ),
+				root.getNodeByPath( [ 0, 1, 2 ] )
+			);
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ '00', '01', '02', '03' ],
+				[ '10', {
+					colspan: 2,
+					rowspan: 2,
+					contents: '<paragraph>[11</paragraph><paragraph>12</paragraph><paragraph>21]</paragraph>'
+				}, '13' ],
+				[ '20', '23' ],
+				[ '30', '31', '32', '33' ]
+			] ) );
+		} );
+
+		it( 'should merge table cells - extend colspan attribute', () => {
+			setData( model, modelTable( [
+				[ { colspan: 2, contents: '00' }, '02', '03' ],
+				[ '10', '11', '12', '13' ]
+			] ) );
+
+			selectNodes( [
+				[ 0, 0, 0 ], [ 0, 0, 1 ],
+				[ 0, 1, 0 ], [ 0, 1, 1 ], [ 0, 1, 2 ]
+			] );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ {
+					colspan: 3,
+					rowspan: 2,
+					contents: '<paragraph>[00</paragraph>' +
+						'<paragraph>02</paragraph>' +
+						'<paragraph>10</paragraph>' +
+						'<paragraph>11</paragraph>' +
+						'<paragraph>12]</paragraph>'
+				}, '03' ],
+				[ '13' ]
+			] ) );
+		} );
+
+		it( 'should merge to a single paragraph - every cell is empty', () => {
+			setData( model, modelTable( [
+				[ '[]', '' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ], [ 0, 0, 1 ] ] );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { colspan: 2, contents: '<paragraph>[]</paragraph>' } ]
+			] ) );
+		} );
+
+		it( 'should merge to a single paragraph - merged cell is empty', () => {
+			setData( model, modelTable( [
+				[ 'foo', '' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ], [ 0, 0, 1 ] ] );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { colspan: 2, contents: '<paragraph>[foo]</paragraph>' } ]
+			] ) );
+		} );
+
+		it( 'should merge to a single paragraph - cell to which others are merged is empty', () => {
+			setData( model, modelTable( [
+				[ '', 'foo' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ], [ 0, 0, 1 ] ] );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { colspan: 2, contents: '<paragraph>[foo]</paragraph>' } ]
+			] ) );
+		} );
+
+		it( 'should not merge empty blocks other then <paragraph> to a single block', () => {
+			model.schema.register( 'block', {
+				allowWhere: '$block',
+				allowContentOf: '$block',
+				isBlock: true
+			} );
+
+			setData( model, modelTable( [
+				[ '<block>[]</block>', '<block></block>' ]
+			] ) );
+
+			selectNodes( [ [ 0, 0, 0 ], [ 0, 0, 1 ] ] );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { colspan: 2, contents: '<block>[</block><block>]</block>' } ]
+			] ) );
+		} );
+
+		describe( 'removing empty row', () => {
+			it( 'should remove empty row if merging all table cells from that row', () => {
+				setData( model, modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ]
+				] ) );
+
+				selectNodes( [
+					[ 0, 0, 0 ],
+					[ 0, 1, 0 ],
+					[ 0, 2, 0 ]
+				] );
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[
+						'<paragraph>[00</paragraph><paragraph>10</paragraph><paragraph>20]</paragraph>'
+					]
+				] ) );
+			} );
+
+			it( 'should decrease rowspan if cell overlaps removed row', () => {
+				setData( model, modelTable( [
+					[ '00', { rowspan: 2, contents: '01' }, { rowspan: 3, contents: '02' } ],
+					[ '10' ],
+					[ '20', '21' ]
+				] ) );
+
+				selectNodes( [
+					[ 0, 0, 0 ],
+					[ 0, 1, 0 ],
+					[ 0, 2, 0 ]
+				] );
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[
+						{ rowspan: 2, contents: '<paragraph>[00</paragraph><paragraph>10</paragraph><paragraph>20]</paragraph>' },
+						'01',
+						{ rowspan: 2, contents: '02' }
+					],
+					[ '21' ]
+				] ) );
+			} );
+
+			it( 'should not decrease rowspan if cell from previous row does not overlaps removed row', () => {
+				setData( model, modelTable( [
+					[ '00', { rowspan: 2, contents: '01' } ],
+					[ '10' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				selectNodes( [
+					[ 0, 2, 0 ], [ 0, 2, 1 ],
+					[ 0, 3, 0 ], [ 0, 3, 1 ]
+				] );
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', { rowspan: 2, contents: '01' } ],
+					[ '10' ],
+					[
+						{
+							colspan: 2,
+							contents: '<paragraph>[20</paragraph><paragraph>21</paragraph>' +
+								'<paragraph>30</paragraph><paragraph>31]</paragraph>'
+						}
+					]
+				] ) );
+			} );
+		} );
+	} );
+
+	function selectNodes( paths ) {
+		model.change( writer => {
+			const ranges = paths.map( path => writer.createRangeOn( root.getNodeByPath( path ) ) );
+
+			writer.setSelection( ranges );
+		} );
+	}
+} );

+ 337 - 1
packages/ckeditor5-table/tests/commands/removecolumncommand.js

@@ -7,6 +7,7 @@ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltestedit
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 
 import RemoveColumnCommand from '../../src/commands/removecolumncommand';
 import RemoveColumnCommand from '../../src/commands/removecolumncommand';
+import TableSelection from '../../src/tableselection';
 import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
 import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
 import TableUtils from '../../src/tableutils';
 import TableUtils from '../../src/tableutils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
@@ -17,7 +18,7 @@ describe( 'RemoveColumnCommand', () => {
 	beforeEach( () => {
 	beforeEach( () => {
 		return ModelTestEditor
 		return ModelTestEditor
 			.create( {
 			.create( {
-				plugins: [ TableUtils ]
+				plugins: [ TableUtils, TableSelection ]
 			} )
 			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
@@ -43,6 +44,22 @@ describe( 'RemoveColumnCommand', () => {
 			expect( command.isEnabled ).to.be.true;
 			expect( command.isEnabled ).to.be.true;
 		} );
 		} );
 
 
+		it( 'should be true if selection contains multiple cells', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02' ],
+				[ '10', '11', '12' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
 		it( 'should be false if selection is inside table with one column only', () => {
 		it( 'should be false if selection is inside table with one column only', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00' ],
 				[ '00' ],
@@ -53,6 +70,22 @@ describe( 'RemoveColumnCommand', () => {
 			expect( command.isEnabled ).to.be.false;
 			expect( command.isEnabled ).to.be.false;
 		} );
 		} );
 
 
+		it( 'should be false if all columns are selected', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02' ],
+				[ '10', '11', '12' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 2 ] )
+			);
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
 		it( 'should be false if selection is outside a table', () => {
 		it( 'should be false if selection is outside a table', () => {
 			setData( model, '<paragraph>11[]</paragraph>' );
 			setData( model, '<paragraph>11[]</paragraph>' );
 
 
@@ -93,6 +126,229 @@ describe( 'RemoveColumnCommand', () => {
 			] ) );
 			] ) );
 		} );
 		} );
 
 
+		describe( 'with multiple cells selected', () => {
+			it( 'should properly remove the first column', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '01' ],
+					[ '11' ],
+					[ '[]21' ],
+					[ '31' ]
+				] ) );
+			} );
+
+			it( 'should properly remove a middle column', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02' ],
+					[ '10', '11', '12' ],
+					[ '20', '21', '22' ],
+					[ '30', '31', '32' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '02' ],
+					[ '10', '12' ],
+					[ '20', '[]22' ],
+					[ '30', '32' ]
+				] ) );
+			} );
+
+			it( 'should properly remove the last column', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00' ],
+					[ '[]10' ],
+					[ '20' ],
+					[ '30' ]
+				] ) );
+			} );
+
+			it( 'should properly remove two first columns', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02' ],
+					[ '10', '11', '12' ],
+					[ '20', '21', '22' ],
+					[ '30', '31', '32' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '02' ],
+					[ '[]12' ],
+					[ '22' ],
+					[ '32' ]
+				] ) );
+			} );
+
+			it( 'should properly remove two middle columns', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02', '03' ],
+					[ '10', '11', '12', '13' ],
+					[ '20', '21', '22', '23' ],
+					[ '30', '31', '32', '33' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 2 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '03' ],
+					[ '10', '13' ],
+					[ '20', '[]23' ],
+					[ '30', '33' ]
+				] ) );
+			} );
+
+			it( 'should properly remove two middle columns with reversed selection', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02', '03' ],
+					[ '10', '11', '12', '13' ],
+					[ '20', '21', '22', '23' ],
+					[ '30', '31', '32', '33' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 2, 2 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '03' ],
+					[ '10', '13' ],
+					[ '20', '[]23' ],
+					[ '30', '33' ]
+				] ) );
+			} );
+
+			it( 'should properly remove two last columns', () => {
+				// There's no handling for selection in case like that.
+				setData( model, modelTable( [
+					[ '00', '01', '02' ],
+					[ '10', '11', '12' ],
+					[ '20', '21', '22' ],
+					[ '30', '31', '32' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 2 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00' ],
+					[ '[]10' ],
+					[ '20' ],
+					[ '30' ]
+				] ) );
+			} );
+
+			it( 'should properly remove multiple heading columns', () => {
+				// There's no handling for selection in case like that.
+				setData( model, modelTable( [
+					[ '00', '01', '02', '03', '04' ],
+					[ '10', '11', '12', '13', '14' ]
+				], { headingColumns: 3 } ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 3 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '04' ],
+					[ '10', '[]14' ]
+				], { headingColumns: 1 } ) );
+			} );
+
+			it( 'should properly calculate truncated colspans', () => {
+				setData( model, modelTable( [
+					[ { contents: '00', colspan: 3 } ],
+					[ '10', '11', '12' ],
+					[ '20', '21', '22' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00' ],
+					[ '[]12' ],
+					[ '22' ]
+				] ) );
+			} );
+		} );
+
 		it( 'should change heading columns if removing a heading column', () => {
 		it( 'should change heading columns if removing a heading column', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00', '01' ],
 				[ '00', '01' ],
@@ -161,5 +417,85 @@ describe( 'RemoveColumnCommand', () => {
 				[ '20', '21' ]
 				[ '20', '21' ]
 			] ) );
 			] ) );
 		} );
 		} );
+
+		it( 'should work property if the rowspan is in the first column (#1)', () => {
+			setData( model, modelTable( [
+				[ { rowspan: 2, contents: '00' }, '[]01' ],
+				[ '10' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { rowspan: 2, contents: '[]00' } ]
+			] ) );
+		} );
+
+		it( 'should work property if the rowspan is in the first column (#2)', () => {
+			setData( model, modelTable( [
+				[ { rowspan: 2, contents: '00' }, '01' ],
+				[ '[]10' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { rowspan: 2, contents: '[]00' } ]
+			] ) );
+		} );
+
+		it( 'should work property if the rowspan is in the first column (#3)', () => {
+			setData( model, modelTable( [
+				[ { rowspan: 2, contents: '00[]' }, '01' ],
+				[ '10' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ '[]01' ],
+				[ '10' ]
+			] ) );
+		} );
+
+		it( 'should work property if the rowspan is in the last column (#1)', () => {
+			setData( model, modelTable( [
+				[ '[]00', { rowspan: 2, contents: '01' } ],
+				[ '10' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { rowspan: 2, contents: '[]01' } ]
+			] ) );
+		} );
+
+		it( 'should work property if the rowspan is in the last column (#2)', () => {
+			setData( model, modelTable( [
+				[ '00', { rowspan: 2, contents: '01' } ],
+				[ '[]10' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ { rowspan: 2, contents: '[]01' } ]
+			] ) );
+		} );
+
+		it( 'should work property if the rowspan is in the last column (#3)', () => {
+			setData( model, modelTable( [
+				[ '00', { rowspan: 2, contents: '[]01' } ],
+				[ '10' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ '[]00' ],
+				[ '10' ]
+			] ) );
+		} );
 	} );
 	} );
 } );
 } );

+ 346 - 3
packages/ckeditor5-table/tests/commands/removerowcommand.js

@@ -3,18 +3,20 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
-import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
+import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
 
 
 import RemoveRowCommand from '../../src/commands/removerowcommand';
 import RemoveRowCommand from '../../src/commands/removerowcommand';
-import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import TableSelection from '../../src/tableselection';
+import { defaultConversion, defaultSchema, modelTable, viewTable } from '../_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 
 describe( 'RemoveRowCommand', () => {
 describe( 'RemoveRowCommand', () => {
 	let editor, model, command;
 	let editor, model, command;
 
 
 	beforeEach( () => {
 	beforeEach( () => {
-		return ModelTestEditor.create()
+		return VirtualTestEditor.create( { plugins: [ TableSelection ] } )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
 				model = editor.model;
 				model = editor.model;
@@ -39,6 +41,23 @@ describe( 'RemoveRowCommand', () => {
 			expect( command.isEnabled ).to.be.true;
 			expect( command.isEnabled ).to.be.true;
 		} );
 		} );
 
 
+		it( 'should be true if selection contains multiple cells', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
 		it( 'should be false if selection is inside table with one row only', () => {
 		it( 'should be false if selection is inside table with one row only', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00[]', '01' ]
 				[ '00[]', '01' ]
@@ -47,11 +66,45 @@ describe( 'RemoveRowCommand', () => {
 			expect( command.isEnabled ).to.be.false;
 			expect( command.isEnabled ).to.be.false;
 		} );
 		} );
 
 
+		it( 'should be false if all the rows are selected', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '10', '11' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+			);
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+
 		it( 'should be false if selection is outside a table', () => {
 		it( 'should be false if selection is outside a table', () => {
 			setData( model, '<paragraph>11[]</paragraph>' );
 			setData( model, '<paragraph>11[]</paragraph>' );
 
 
 			expect( command.isEnabled ).to.be.false;
 			expect( command.isEnabled ).to.be.false;
 		} );
 		} );
+
+		it( 'should be false when the first column with rowspan is selected', () => {
+			// (#6427)
+			setData( model, modelTable( [
+				[ { rowspan: 2, contents: '00' }, '01' ],
+				[ '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+			);
+
+			expect( command.isEnabled ).to.be.false;
+		} );
 	} );
 	} );
 
 
 	describe( 'execute()', () => {
 	describe( 'execute()', () => {
@@ -70,6 +123,268 @@ describe( 'RemoveRowCommand', () => {
 			] ) );
 			] ) );
 		} );
 		} );
 
 
+		describe( 'with multiple rows selected', () => {
+			it( 'should properly remove middle rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '01' ],
+					[ '[]30', '31' ]
+				] ) );
+			} );
+
+			it( 'should properly remove middle rows in reversed order', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '01' ],
+					[ '[]30', '31' ]
+				] ) );
+			} );
+
+			it( 'should properly remove tailing rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 3, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '01' ],
+					[ '[]10', '11' ]
+				] ) );
+			} );
+
+			it( 'should properly remove beginning rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '[]20', '21' ],
+					[ '30', '31' ]
+				] ) );
+			} );
+
+			it( 'should support removing multiple headings (removed rows in heading section)', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				], { headingRows: 3 } ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '[]20', '21' ],
+					[ '30', '31' ]
+				], { headingRows: 1 } ) );
+			} );
+
+			it( 'should support removing multiple headings (removed rows in heading and body section)', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ],
+					[ '40', '41' ]
+				], { headingRows: 3 } ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 3, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '01' ],
+					[ '[]40', '41' ]
+				], { headingRows: 1 } ) );
+
+				// The view should also be properly downcasted.
+				assertEqualMarkup( getViewData( editor.editing.view, { withoutSelection: true } ), viewTable( [
+					[ '00', '01' ],
+					[ '40', '41' ]
+				], { headingRows: 1 } ) );
+			} );
+
+			it( 'should support removing mixed heading and cell rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ]
+				], { headingRows: 1 } ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '[]20', '21' ]
+				] ) );
+			} );
+
+			it( 'should properly calculate truncated rowspans', () => {
+				setData( model, modelTable( [
+					[ '00', { contents: '01', rowspan: 3 } ],
+					[ '10' ],
+					[ '20' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '[]20', '01' ]
+				] ) );
+			} );
+
+			it( 'should create one undo step (1 batch)', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				], { headingRows: 3 } ) );
+
+				const createdBatches = new Set();
+
+				model.on( 'applyOperation', ( evt, args ) => {
+					const operation = args[ 0 ];
+
+					createdBatches.add( operation.batch );
+				} );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				expect( createdBatches.size ).to.equal( 1 );
+			} );
+		} );
+
+		describe( 'with entire row selected', () => {
+			it( 'should remove a row if all its cells are selected', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '01' ],
+					[ '[]20', '21' ]
+				] ) );
+			} );
+
+			it( 'should properly remove row if reversed selection is made', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '[]10', '11' ]
+				] ) );
+			} );
+		} );
+
 		it( 'should remove a given row from a table start', () => {
 		it( 'should remove a given row from a table start', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '[]00', '01' ],
 				[ '[]00', '01' ],
@@ -85,6 +400,34 @@ describe( 'RemoveRowCommand', () => {
 			] ) );
 			] ) );
 		} );
 		} );
 
 
+		it( 'should remove a given row from a table start when selection is at the end', () => {
+			setData( model, modelTable( [
+				[ '00', '01[]' ],
+				[ '10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ '10', '[]11' ],
+				[ '20', '21' ]
+			] ) );
+		} );
+
+		it( 'should remove last row', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '[]10', '11' ]
+			] ) );
+
+			command.execute();
+
+			assertEqualMarkup( getData( model ), modelTable( [
+				[ '[]00', '01' ]
+			] ) );
+		} );
+
 		it( 'should change heading rows if removing a heading row', () => {
 		it( 'should change heading rows if removing a heading row', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00', '01' ],
 				[ '00', '01' ],

+ 450 - 0
packages/ckeditor5-table/tests/commands/selectcolumncommand.js

@@ -0,0 +1,450 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
+import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+
+import SelectColumnCommand from '../../src/commands/selectcolumncommand';
+import TableSelection from '../../src/tableselection';
+import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+
+describe( 'SelectColumnCommand', () => {
+	let editor, model, modelRoot, command, tableSelection;
+
+	beforeEach( () => {
+		return VirtualTestEditor.create( { plugins: [ TableSelection ] } )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				modelRoot = model.document.getRoot();
+				command = new SelectColumnCommand( editor );
+				tableSelection = editor.plugins.get( TableSelection );
+
+				defaultSchema( model.schema );
+				defaultConversion( editor.conversion );
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	describe( 'isEnabled', () => {
+		it( 'should be true if the selection is inside table cell', () => {
+			setData( model, modelTable( [
+				[ '00[]', '01' ],
+				[ '10', '11' ]
+			] ) );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true if the selection contains multiple cells', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be false if the selection is outside a table', () => {
+			setData( model, '<paragraph>11[]</paragraph>' );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+	} );
+
+	describe( 'execute()', () => {
+		it( 'should select a column of a table cell with a collapsed selection', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02' ],
+				[ '10', '[]11', '12' ],
+				[ '20', '21', '22' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 0, 1, 0 ],
+				[ 0, 1, 0 ],
+				[ 0, 1, 0 ]
+			] );
+		} );
+
+		it( 'should select a column of table cell with a collapsed selection in first table cell', () => {
+			setData( model, modelTable( [
+				[ '[]00', '01' ],
+				[ '10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 1, 0 ],
+				[ 1, 0 ],
+				[ 1, 0 ]
+			] );
+		} );
+
+		it( 'should select a column of table cell with a collapsed selection in last cell in the first column', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '10', '11' ],
+				[ '20[]', '21' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 1, 0 ],
+				[ 1, 0 ],
+				[ 1, 0 ]
+			] );
+		} );
+
+		it( 'should select a column of table cell with collapsed selection in the first cell of the last column', () => {
+			setData( model, modelTable( [
+				[ '00', '01[]' ],
+				[ '10', '11' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 0, 1 ],
+				[ 0, 1 ]
+			] );
+		} );
+
+		describe( 'with col-spanned cells', () => {
+			beforeEach( () => {
+				// +----+----+----+----+
+				// | 00                |
+				// +----+----+----+----+
+				// | 10           | 13 |
+				// +----+----+----+----+
+				// | 20      | 22 | 23 |
+				// +----+----+----+----+
+				// | 30 | 31      | 33 |
+				// +----+----+----+----+
+				// | 40 | 41 | 42 | 43 |
+				// +----+----+----+----+
+				setData( model, modelTable( [
+					[ { colspan: 4, contents: '00' } ],
+					[ { colspan: 3, contents: '10' }, '13' ],
+					[ { colspan: 2, contents: '20' }, '22', '23' ],
+					[ '30', { colspan: 2, contents: '31' }, '33' ],
+					[ '40', '41', '42', '43' ]
+				] ) );
+			} );
+
+			it( 'should select only one column if only one cell is selected', () => {
+				// Selection in cell 10.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 1,       0 ],
+					[ 0,    0, 0 ],
+					[ 0, 0,    0 ],
+					[ 0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 1          ],
+					[ 1,       0 ],
+					[ 1,    0, 0 ],
+					[ 1, 0,    0 ],
+					[ 1, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should not select col-spanned columns that start in other column', () => {
+				// Selection in cell 42.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 4, 2 ] ),
+					modelRoot.getNodeByPath( [ 0, 4, 2 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 0,       0 ],
+					[ 0,    0, 0 ],
+					[ 0, 0,    0 ],
+					[ 0, 0, 1, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 0,       0 ],
+					[ 0,    1, 0 ],
+					[ 0, 0,    0 ],
+					[ 0, 0, 1, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should not select col-spanned columns that start in other column but include those that start in selected column', () => {
+				// Selection in cell 41.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 4, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 4, 1 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 0,       0 ],
+					[ 0,    0, 0 ],
+					[ 0, 0,    0 ],
+					[ 0, 1, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 0,       0 ],
+					[ 0,    0, 0 ],
+					[ 0, 1,    0 ],
+					[ 0, 1, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should select properly for multiple not spanned cells selected', () => {
+				// Selection in cells 40 - 41.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 4, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 4, 1 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 0,       0 ],
+					[ 0,    0, 0 ],
+					[ 0, 0,    0 ],
+					[ 1, 1, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 1          ],
+					[ 1,       0 ],
+					[ 1,    0, 0 ],
+					[ 1, 1,    0 ],
+					[ 1, 1, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should select properly for multiple cells selected including spanned one', () => {
+				// Selection in cells 31 - 33.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 3, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 3, 2 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 0,       0 ],
+					[ 0,    0, 0 ],
+					[ 0, 1,    1 ],
+					[ 0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0          ],
+					[ 0,       1 ],
+					[ 0,    1, 1 ],
+					[ 0, 1,    1 ],
+					[ 0, 1, 1, 1 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+		} );
+
+		describe( 'with multiple columns selected', () => {
+			beforeEach( () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02', '03' ],
+					[ '10', '11', '12', '13' ],
+					[ '20', '21', '22', '23' ]
+				] ) );
+			} );
+
+			it( 'should properly select middle columns', () => {
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 2 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ]
+				] );
+			} );
+
+			it( 'should properly select middle columns in reversed order', () => {
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 2 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ]
+				] );
+			} );
+
+			it( 'should properly select tailing columns', () => {
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 2 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 3 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 0, 1, 1 ],
+					[ 0, 0, 1, 1 ],
+					[ 0, 0, 1, 1 ]
+				] );
+			} );
+
+			it( 'should properly select beginning columns', () => {
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 1, 1, 0, 0 ],
+					[ 1, 1, 0, 0 ],
+					[ 1, 1, 0, 0 ]
+				] );
+			} );
+
+			it( 'should properly select multiple columns from square selection', () => {
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 2 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ]
+				] );
+			} );
+
+			it( 'should support selecting mixed heading and cell columns', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02', '03' ],
+					[ '10', '11', '12', '13' ],
+					[ '20', '21', '22', '23' ]
+				], { headingRows: 1 } ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 1, 1, 0, 0 ],
+					[ 1, 1, 0, 0 ],
+					[ 1, 1, 0, 0 ]
+				] );
+			} );
+		} );
+
+		describe( 'with entire column selected', () => {
+			it( 'should select a column if all its cells are selected', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02' ],
+					[ '10', '11', '12' ],
+					[ '20', '21', '22' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 1 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 1, 0 ],
+					[ 0, 1, 0 ],
+					[ 0, 1, 0 ]
+				] );
+			} );
+
+			it( 'should properly select column if reversed selection is made', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 1, 0 ],
+					[ 1, 0 ]
+				] );
+			} );
+		} );
+	} );
+} );

+ 469 - 0
packages/ckeditor5-table/tests/commands/selectrowcommand.js

@@ -0,0 +1,469 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
+import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+
+import SelectRowCommand from '../../src/commands/selectrowcommand';
+import TableSelection from '../../src/tableselection';
+import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+
+describe( 'SelectRowCommand', () => {
+	let editor, model, modelRoot, command, tableSelection;
+
+	beforeEach( () => {
+		return VirtualTestEditor.create( { plugins: [ TableSelection ] } )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				modelRoot = model.document.getRoot();
+				command = new SelectRowCommand( editor );
+				tableSelection = editor.plugins.get( TableSelection );
+
+				defaultSchema( model.schema );
+				defaultConversion( editor.conversion );
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	describe( 'isEnabled', () => {
+		it( 'should be true if the selection is inside table cell', () => {
+			setData( model, modelTable( [
+				[ '00[]', '01' ],
+				[ '10', '11' ]
+			] ) );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true if the selection contains multiple cells', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be false if the selection is outside a table', () => {
+			setData( model, '<paragraph>11[]</paragraph>' );
+
+			expect( command.isEnabled ).to.be.false;
+		} );
+	} );
+
+	describe( 'execute()', () => {
+		it( 'should select a row of a table cell with a collapsed selection', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '[]10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 0, 0 ],
+				[ 1, 1 ],
+				[ 0, 0 ]
+			] );
+		} );
+
+		it( 'should select a row of table cell with a collapsed selection in first table cell', () => {
+			setData( model, modelTable( [
+				[ '[]00', '01' ],
+				[ '10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 1, 1 ],
+				[ 0, 0 ],
+				[ 0, 0 ]
+			] );
+		} );
+
+		it( 'should select a row of table cell with a collapsed selection in last cell in the first column', () => {
+			setData( model, modelTable( [
+				[ '00', '01[]' ],
+				[ '10', '11' ],
+				[ '20', '21' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 1, 1 ],
+				[ 0, 0 ],
+				[ 0, 0 ]
+			] );
+		} );
+
+		it( 'should select a row of table cell with collapsed selection in the first cell of the last column', () => {
+			setData( model, modelTable( [
+				[ '00', '01' ],
+				[ '[]10', '11' ]
+			] ) );
+
+			command.execute();
+
+			assertSelectedCells( model, [
+				[ 0, 0 ],
+				[ 1, 1 ]
+			] );
+		} );
+
+		describe( 'with row-spanned cells', () => {
+			beforeEach( () => {
+				// +----+----+----+----+----+
+				// | 00 | 01 | 02 | 03 | 04 |
+				// +    +    +    +----+----+
+				// |    |    |    | 13 | 14 |
+				// +    +    +----+    +----+
+				// |    |    | 22 |    | 24 |
+				// +    +----+----+----+----+
+				// |    | 31 | 32 | 33 | 34 |
+				// +----+----+----+----+----+
+				setData( model, modelTable( [
+					[ { rowspan: 4, contents: '00' }, { rowspan: 3, contents: '01' }, { rowspan: 2, contents: '02' }, '03', '04' ],
+					[ { rowspan: 2, contents: '13' }, '14' ],
+					[ '22', '23', '24' ],
+					[ '30', '31', '32', '33', '34' ]
+				] ) );
+			} );
+
+			it( 'should select only one row if only one cell is selected', () => {
+				// Selection in cell 01.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 1, 0, 0, 0 ],
+					[          0, 0 ],
+					[       0,    0 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 1, 1, 1, 1, 1 ],
+					[          0, 0 ],
+					[       0,    0 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should not select row-spanned rows that start in other row', () => {
+				// Selection in cell 24.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 2, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 1 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0, 0 ],
+					[          0, 0 ],
+					[       0,    1 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0, 0 ],
+					[          0, 0 ],
+					[       1,    1 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should not select row-spanned rows that start in other row but include those that start in selected row', () => {
+				// Selection in cell 14.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0, 0 ],
+					[          0, 1 ],
+					[       0,    0 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0, 0 ],
+					[          1, 1 ],
+					[       0,    0 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should select properly for multiple not spanned cells selected', () => {
+				// Selection in cells 04 - 14.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 4 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0, 1 ],
+					[          0, 1 ],
+					[       0,    0 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 1, 1, 1, 1, 1 ],
+					[          1, 1 ],
+					[       0,    0 ],
+					[    0, 0, 0, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+
+			it( 'should select properly for multiple cells selected including spanned one', () => {
+				// Selection in cells 13 - 33.
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 3, 2 ] )
+				);
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0, 0 ],
+					[          1, 0 ],
+					[       0,    0 ],
+					[    0, 0, 1, 0 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+
+				command.execute();
+
+				/* eslint-disable no-multi-spaces */
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0, 0 ],
+					[          1, 1 ],
+					[       1,    1 ],
+					[    1, 1, 1, 1 ]
+				] );
+				/* eslint-enable no-multi-spaces */
+			} );
+		} );
+
+		describe( 'with multiple rows selected', () => {
+			it( 'should properly select middle rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 0 ],
+					[ 1, 1 ],
+					[ 1, 1 ],
+					[ 0, 0 ]
+				] );
+			} );
+
+			it( 'should properly select middle rows in reversed order', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 0 ],
+					[ 1, 1 ],
+					[ 1, 1 ],
+					[ 0, 0 ]
+				] );
+			} );
+
+			it( 'should properly select tailing rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 3, 0 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 0 ],
+					[ 0, 0 ],
+					[ 1, 1 ],
+					[ 1, 1 ]
+				] );
+			} );
+
+			it( 'should properly select beginning rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ],
+					[ '30', '31' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 1, 1 ],
+					[ 1, 1 ],
+					[ 0, 0 ],
+					[ 0, 0 ]
+				] );
+			} );
+
+			it( 'should properly select multiple rows from square selection', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02' ],
+					[ '10', '11', '12' ],
+					[ '20', '21', '22' ],
+					[ '30', '31', '32' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 1 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 0, 0 ],
+					[ 1, 1, 1 ],
+					[ 1, 1, 1 ],
+					[ 0, 0, 0 ]
+				] );
+			} );
+
+			it( 'should support selecting mixed heading and cell rows', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ]
+				], { headingColumns: 1 } ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 1, 1 ],
+					[ 1, 1 ],
+					[ 0, 0 ]
+				] );
+			} );
+		} );
+
+		describe( 'with entire row selected', () => {
+			it( 'should select a row if all its cells are selected', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ],
+					[ '20', '21' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 0, 0 ],
+					[ 1, 1 ],
+					[ 0, 0 ]
+				] );
+			} );
+
+			it( 'should properly select row if reversed selection is made', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ],
+					[ '10', '11' ]
+				] ) );
+
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] )
+				);
+
+				command.execute();
+
+				assertSelectedCells( model, [
+					[ 1, 1 ],
+					[ 0, 0 ]
+				] );
+			} );
+		} );
+	} );
+} );

+ 271 - 3
packages/ckeditor5-table/tests/commands/setheadercolumncommand.js

@@ -7,7 +7,8 @@ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltestedit
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 
 import SetHeaderColumnCommand from '../../src/commands/setheadercolumncommand';
 import SetHeaderColumnCommand from '../../src/commands/setheadercolumncommand';
-import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import TableSelection from '../../src/tableselection';
 import TableUtils from '../../src/tableutils';
 import TableUtils from '../../src/tableutils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 
@@ -17,7 +18,7 @@ describe( 'SetHeaderColumnCommand', () => {
 	beforeEach( () => {
 	beforeEach( () => {
 		return ModelTestEditor
 		return ModelTestEditor
 			.create( {
 			.create( {
-				plugins: [ TableUtils ]
+				plugins: [ TableUtils, TableSelection ]
 			} )
 			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
@@ -43,6 +44,36 @@ describe( 'SetHeaderColumnCommand', () => {
 			setData( model, '<table><tableRow><tableCell><paragraph>foo[]</paragraph></tableCell></tableRow></table>' );
 			setData( model, '<table><tableRow><tableCell><paragraph>foo[]</paragraph></tableCell></tableRow></table>' );
 			expect( command.isEnabled ).to.be.true;
 			expect( command.isEnabled ).to.be.true;
 		} );
 		} );
+
+		it( 'should be true if multiple columns are selected', () => {
+			setData( model, modelTable( [
+				[ '01', '02', '03' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true if multiple header columns are selected', () => {
+			setData( model, modelTable( [
+				[ '01', '02', '03' ]
+			], { headingColumns: 2 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
 	} );
 	} );
 
 
 	describe( 'value', () => {
 	describe( 'value', () => {
@@ -64,6 +95,36 @@ describe( 'SetHeaderColumnCommand', () => {
 			expect( command.value ).to.be.true;
 			expect( command.value ).to.be.true;
 		} );
 		} );
 
 
+		it( 'should be true if multiple header columns are selected', () => {
+			setData( model, modelTable( [
+				[ '01', '02', '03' ]
+			], { headingColumns: 2 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.value ).to.be.true;
+		} );
+
+		it( 'should be true if multiple header columns are selected in reversed order', () => {
+			setData( model, modelTable( [
+				[ '01', '02', '03' ]
+			], { headingColumns: 2 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] )
+			);
+
+			expect( command.value ).to.be.true;
+		} );
+
 		it( 'should be false if selection is in a heading row', () => {
 		it( 'should be false if selection is in a heading row', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '01', '02[]' ],
 				[ '01', '02[]' ],
@@ -72,10 +133,25 @@ describe( 'SetHeaderColumnCommand', () => {
 
 
 			expect( command.value ).to.be.false;
 			expect( command.value ).to.be.false;
 		} );
 		} );
+
+		it( 'should be false if only part of selected columns are headers', () => {
+			setData( model, modelTable( [
+				[ '01', '02', '03', '04' ]
+			], { headingColumns: 2 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 2 ] )
+			);
+
+			expect( command.value ).to.be.false;
+		} );
 	} );
 	} );
 
 
 	describe( 'execute()', () => {
 	describe( 'execute()', () => {
-		it( 'should set heading columns attribute that cover column in which is selection', () => {
+		it( 'should set heading columns attribute that cover column with collapsed selection', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00', '01[]', '02', '03' ]
 				[ '00', '01[]', '02', '03' ]
 			] ) );
 			] ) );
@@ -87,6 +163,29 @@ describe( 'SetHeaderColumnCommand', () => {
 			], { headingColumns: 2 } ) );
 			], { headingColumns: 2 } ) );
 		} );
 		} );
 
 
+		it( 'should set heading columns attribute that cover column with entire cell selected', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02', '03' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			command.execute();
+
+			assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+				[ '00', '01', '02', '03' ]
+			], { headingColumns: 2 } ) );
+
+			assertSelectedCells( model, [
+				[ 0, 1, 0, 0 ]
+			] );
+		} );
+
 		it( 'should set heading columns attribute below current selection column', () => {
 		it( 'should set heading columns attribute below current selection column', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00', '01[]', '02', '03' ]
 				[ '00', '01[]', '02', '03' ]
@@ -99,6 +198,175 @@ describe( 'SetHeaderColumnCommand', () => {
 			], { headingColumns: 1 } ) );
 			], { headingColumns: 1 } ) );
 		} );
 		} );
 
 
+		describe( 'multi-cell selection', () => {
+			describe( 'setting header', () => {
+				it( 'should set it correctly in a middle of single-row, multiple cell selection', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02', '03' ]
+					] ) );
+
+					const tableSelection = editor.plugins.get( TableSelection );
+					const modelRoot = model.document.getRoot();
+					tableSelection._setCellSelection(
+						modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+						modelRoot.getNodeByPath( [ 0, 0, 2 ] )
+					);
+
+					command.execute();
+
+					assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 3
+					} ) );
+
+					assertSelectedCells( model, [
+						[ 0, 1, 1, 0 ]
+					] );
+				} );
+
+				it( 'should set it correctly in a middle of multi-row, multiple cell selection', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02', '03' ],
+						[ '10', '11', '12', '13' ]
+					] ) );
+
+					const tableSelection = editor.plugins.get( TableSelection );
+					const modelRoot = model.document.getRoot();
+					tableSelection._setCellSelection(
+						modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+						modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+					);
+
+					command.execute();
+
+					assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+						[ '00', '01', '02', '03' ],
+						[ '10', '11', '12', '13' ]
+					], {
+						headingColumns: 2
+					} ) );
+
+					assertSelectedCells( model, [
+						[ 0, 1, 0, 0 ],
+						[ 0, 1, 0, 0 ]
+					] );
+				} );
+
+				it( 'should remove header columns in case of multiple cell selection', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02', '03' ]
+					], { headingColumns: 4 } ) );
+
+					const tableSelection = editor.plugins.get( TableSelection );
+					const modelRoot = model.document.getRoot();
+					tableSelection._setCellSelection(
+						modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+						modelRoot.getNodeByPath( [ 0, 0, 2 ] )
+					);
+
+					command.execute();
+
+					assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 1
+					} ) );
+
+					assertSelectedCells( model, [
+						[ 0, 1, 1, 0 ]
+					] );
+				} );
+
+				it( 'should remove header columns in case of multiple cell selection - reversed order', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 4
+					} ) );
+
+					const tableSelection = editor.plugins.get( TableSelection );
+					const modelRoot = model.document.getRoot();
+					tableSelection._setCellSelection(
+						modelRoot.getNodeByPath( [ 0, 0, 2 ] ),
+						modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+					);
+
+					command.execute();
+
+					assertEqualMarkup( getData( model, {
+						withoutSelection: true
+					} ), modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 1
+					} ) );
+
+					assertSelectedCells( model, [
+						[ 0, 1, 1, 0 ]
+					] );
+				} );
+
+				it( 'should respect forceValue=true in case of multiple cell selection', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 3
+					} ) );
+
+					const tableSelection = editor.plugins.get( TableSelection );
+					const modelRoot = model.document.getRoot();
+					tableSelection._setCellSelection(
+						modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+						modelRoot.getNodeByPath( [ 0, 0, 2 ] )
+					);
+
+					command.execute( { forceValue: true } );
+
+					assertEqualMarkup( getData( model, {
+						withoutSelection: true
+					} ), modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 3
+					} ) );
+
+					assertSelectedCells( model, [
+						[ 0, 1, 1, 0 ]
+					] );
+				} );
+
+				it( 'should respect forceValue=false in case of multiple cell selection', () => {
+					setData( model, modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 1
+					} ) );
+
+					const tableSelection = editor.plugins.get( TableSelection );
+					const modelRoot = model.document.getRoot();
+					tableSelection._setCellSelection(
+						modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+						modelRoot.getNodeByPath( [ 0, 0, 2 ] )
+					);
+
+					command.execute( { forceValue: false } );
+
+					assertEqualMarkup( getData( model, {
+						withoutSelection: true
+					} ), modelTable( [
+						[ '00', '01', '02', '03' ]
+					], {
+						headingColumns: 1
+					} ) );
+
+					assertSelectedCells( model, [
+						[ 0, 1, 1, 0 ]
+					] );
+				} );
+			} );
+		} );
+
 		it( 'should toggle of selected column', () => {
 		it( 'should toggle of selected column', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00', '01[]', '02', '03' ]
 				[ '00', '01[]', '02', '03' ]

+ 295 - 2
packages/ckeditor5-table/tests/commands/setheaderrowcommand.js

@@ -6,7 +6,8 @@
 import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
 import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import SetHeaderRowCommand from '../../src/commands/setheaderrowcommand';
 import SetHeaderRowCommand from '../../src/commands/setheaderrowcommand';
-import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import TableSelection from '../../src/tableselection';
 import TableUtils from '../../src/tableutils';
 import TableUtils from '../../src/tableutils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 
@@ -16,7 +17,7 @@ describe( 'SetHeaderRowCommand', () => {
 	beforeEach( () => {
 	beforeEach( () => {
 		return ModelTestEditor
 		return ModelTestEditor
 			.create( {
 			.create( {
-				plugins: [ TableUtils ]
+				plugins: [ TableUtils, TableSelection ]
 			} )
 			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
@@ -42,6 +43,36 @@ describe( 'SetHeaderRowCommand', () => {
 			setData( model, '<table><tableRow><tableCell><paragraph>foo[]</paragraph></tableCell></tableRow></table>' );
 			setData( model, '<table><tableRow><tableCell><paragraph>foo[]</paragraph></tableCell></tableRow></table>' );
 			expect( command.isEnabled ).to.be.true;
 			expect( command.isEnabled ).to.be.true;
 		} );
 		} );
+
+		it( 'should be true if multiple cells are selected', () => {
+			setData( model, modelTable( [
+				[ '01', '02', '03' ]
+			] ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true if multiple cells in a header row are selected', () => {
+			setData( model, modelTable( [
+				[ '01', '02', '03' ]
+			], { headingRows: 1 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.isEnabled ).to.be.true;
+		} );
 	} );
 	} );
 
 
 	describe( 'value', () => {
 	describe( 'value', () => {
@@ -80,6 +111,54 @@ describe( 'SetHeaderRowCommand', () => {
 
 
 			expect( command.value ).to.be.false;
 			expect( command.value ).to.be.false;
 		} );
 		} );
+
+		it( 'should be true if multiple header rows are selected', () => {
+			setData( model, modelTable( [
+				[ '01', '02' ],
+				[ '11', '12' ]
+			], { headingRows: 2 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			expect( command.value ).to.be.true;
+		} );
+
+		it( 'should be true if multiple header columns are selected in reversed order', () => {
+			setData( model, modelTable( [
+				[ '01', '02' ],
+				[ '11', '12' ]
+			], { headingRows: 2 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
+				modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+			);
+
+			expect( command.value ).to.be.true;
+		} );
+
+		it( 'should be false if only part of selected columns are headers', () => {
+			setData( model, modelTable( [
+				[ '01', '02' ],
+				[ '11', '12' ]
+			], { headingRows: 1 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+			);
+
+			expect( command.value ).to.be.false;
+		} );
 	} );
 	} );
 
 
 	describe( 'execute()', () => {
 	describe( 'execute()', () => {
@@ -164,6 +243,220 @@ describe( 'SetHeaderRowCommand', () => {
 			] ) );
 			] ) );
 		} );
 		} );
 
 
+		describe( 'multi-cell selection', () => {
+			it( 'should set it correctly in a middle of multi-row table', () => {
+				setData( model, modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], {
+					headingRows: 3
+				} ) );
+
+				assertSelectedCells( model, [
+					[ 0 ],
+					[ 1 ],
+					[ 1 ],
+					[ 0 ]
+				] );
+			} );
+
+			it( 'should set it correctly in a middle of multi-row table - reversed selection', () => {
+				setData( model, modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], {
+					headingRows: 3
+				} ) );
+
+				assertSelectedCells( model, [
+					[ 0 ],
+					[ 1 ],
+					[ 1 ],
+					[ 0 ]
+				] );
+			} );
+
+			it( 'should set it correctly in a middle of multi-row, multiple cell selection', () => {
+				setData( model, modelTable( [
+					[ '00', '01', '02', '03' ],
+					[ '10', '11', '12', '13' ],
+					[ '20', '21', '22', '23' ],
+					[ '30', '31', '32', '33' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 1 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 2 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '00', '01', '02', '03' ],
+					[ '10', '11', '12', '13' ],
+					[ '20', '21', '22', '23' ],
+					[ '30', '31', '32', '33' ]
+				], {
+					headingRows: 3
+				} ) );
+
+				assertSelectedCells( model, [
+					[ 0, 0, 0, 0 ],
+					[ 0, 1, 1, 0 ],
+					[ 0, 1, 1, 0 ],
+					[ 0, 0, 0, 0 ]
+				] );
+			} );
+
+			it( 'should remove header rows in case of multiple cell selection', () => {
+				setData( model, modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], { headingRows: 4 } ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], {
+					headingRows: 1
+				} ) );
+
+				assertSelectedCells( model, [
+					[ 0 ],
+					[ 1 ],
+					[ 1 ],
+					[ 0 ]
+				] );
+			} );
+
+			it( 'should respect forceValue=true in case of multiple row selection', () => {
+				setData( model, modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], {
+					headingRows: 3
+				} ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+				);
+
+				command.execute( { forceValue: true } );
+
+				assertEqualMarkup( getData( model, {
+					withoutSelection: true
+				} ), modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], {
+					headingRows: 3
+				} ) );
+
+				assertSelectedCells( model, [
+					[ 0 ],
+					[ 1 ],
+					[ 1 ],
+					[ 0 ]
+				] );
+			} );
+
+			it( 'should respect forceValue=false in case of multiple cell selection', () => {
+				setData( model, modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], {
+					headingRows: 1
+				} ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 2, 0 ] )
+				);
+
+				command.execute( { forceValue: false } );
+
+				assertEqualMarkup( getData( model, {
+					withoutSelection: true
+				} ), modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ],
+					[ '30' ]
+				], {
+					headingRows: 1
+				} ) );
+
+				assertSelectedCells( model, [
+					[ 0 ],
+					[ 1 ],
+					[ 1 ],
+					[ 0 ]
+				] );
+			} );
+		} );
+
 		it( 'should respect forceValue parameter #1', () => {
 		it( 'should respect forceValue parameter #1', () => {
 			setData( model, modelTable( [
 			setData( model, modelTable( [
 				[ '00' ],
 				[ '00' ],

+ 32 - 1
packages/ckeditor5-table/tests/commands/splitcellcommand.js

@@ -8,6 +8,7 @@ import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model
 
 
 import SplitCellCommand from '../../src/commands/splitcellcommand';
 import SplitCellCommand from '../../src/commands/splitcellcommand';
 import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
 import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
+import TableSelection from '../../src/tableselection';
 import TableUtils from '../../src/tableutils';
 import TableUtils from '../../src/tableutils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 
@@ -17,7 +18,7 @@ describe( 'SplitCellCommand', () => {
 	beforeEach( () => {
 	beforeEach( () => {
 		return ModelTestEditor
 		return ModelTestEditor
 			.create( {
 			.create( {
-				plugins: [ TableUtils ]
+				plugins: [ TableUtils, TableSelection ]
 			} )
 			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
@@ -47,6 +48,36 @@ describe( 'SplitCellCommand', () => {
 				expect( command.isEnabled ).to.be.true;
 				expect( command.isEnabled ).to.be.true;
 			} );
 			} );
 
 
+			it( 'should be true if in an entire cell is selected', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] )
+				);
+
+				expect( command.isEnabled ).to.be.true;
+			} );
+
+			it( 'should be false if multiple cells are selected', () => {
+				setData( model, modelTable( [
+					[ '00', '01' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 0, 1 ] )
+				);
+
+				expect( command.isEnabled ).to.be.false;
+			} );
+
 			it( 'should be false if not in cell', () => {
 			it( 'should be false if not in cell', () => {
 				setData( model, '<paragraph>11[]</paragraph>' );
 				setData( model, '<paragraph>11[]</paragraph>' );
 
 

+ 52 - 6
packages/ckeditor5-table/tests/commands/utils.js

@@ -4,20 +4,24 @@
  */
  */
 
 
 import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
 import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
+import TableUtils from '../../src/tableutils';
 import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
-
 import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
 import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
-
-import { findAncestor } from '../../src/commands/utils';
+import { findAncestor, isHeadingColumnCell } from '../../src/commands/utils';
 
 
 describe( 'commands utils', () => {
 describe( 'commands utils', () => {
-	let editor, model;
+	let editor, model, modelRoot, tableUtils;
 
 
 	beforeEach( () => {
 	beforeEach( () => {
-		return ModelTestEditor.create()
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
 			.then( newEditor => {
 			.then( newEditor => {
 				editor = newEditor;
 				editor = newEditor;
 				model = editor.model;
 				model = editor.model;
+				modelRoot = model.document.getRoot();
+				tableUtils = editor.plugins.get( TableUtils );
 
 
 				defaultSchema( model.schema );
 				defaultSchema( model.schema );
 				defaultConversion( editor.conversion );
 				defaultConversion( editor.conversion );
@@ -28,7 +32,7 @@ describe( 'commands utils', () => {
 		return editor.destroy();
 		return editor.destroy();
 	} );
 	} );
 
 
-	describe( 'getParentTable()', () => {
+	describe( 'findAncestor()', () => {
 		it( 'should return undefined if not in table', () => {
 		it( 'should return undefined if not in table', () => {
 			setData( model, '<paragraph>foo[]</paragraph>' );
 			setData( model, '<paragraph>foo[]</paragraph>' );
 
 
@@ -44,4 +48,46 @@ describe( 'commands utils', () => {
 			expect( parentTable.is( 'table' ) ).to.be.true;
 			expect( parentTable.is( 'table' ) ).to.be.true;
 		} );
 		} );
 	} );
 	} );
+
+	describe( 'isHeadingColumnCell()', () => {
+		it( 'should return "true" for a heading column cell', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02', '03' ]
+			], { headingColumns: 2 } ) );
+
+			const tableCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
+
+			expect( isHeadingColumnCell( tableUtils, tableCell ) ).to.be.true;
+		} );
+
+		it( 'should return "true" for a heading column cell with colspan', () => {
+			setData( model, modelTable( [
+				[ { colspan: 2, contents: '00' }, '01', '02', '03' ]
+			], { headingColumns: 2 } ) );
+
+			const tableCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
+
+			expect( isHeadingColumnCell( tableUtils, tableCell ) ).to.be.true;
+		} );
+
+		it( 'should return "false" for a regular column cell', () => {
+			setData( model, modelTable( [
+				[ '00', '01', '02', '03' ]
+			], { headingColumns: 2 } ) );
+
+			const tableCell = modelRoot.getNodeByPath( [ 0, 0, 2 ] );
+
+			expect( isHeadingColumnCell( tableUtils, tableCell ) ).to.be.false;
+		} );
+
+		it( 'should return "false" for a regular column cell with colspan', () => {
+			setData( model, modelTable( [
+				[ '00', { colspan: 2, contents: '01' }, '02', '03' ]
+			], { headingColumns: 1 } ) );
+
+			const tableCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
+
+			expect( isHeadingColumnCell( tableUtils, tableCell ) ).to.be.false;
+		} );
+	} );
 } );
 } );

+ 7 - 4
packages/ckeditor5-table/tests/manual/rtl.js

@@ -8,18 +8,21 @@
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
 import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
 
 
+import TableProperties from '../../src/tableproperties';
+import TableCellProperties from '../../src/tablecellproperties';
+
 ClassicEditor
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 	.create( document.querySelector( '#editor' ), {
-		plugins: [ ArticlePluginSet ],
+		plugins: [ ArticlePluginSet, TableProperties, TableCellProperties ],
 		language: {
 		language: {
-			ui: 'en',
-			content: 'ar'
+			ui: 'ar',
+			content: 'en'
 		},
 		},
 		toolbar: [
 		toolbar: [
 			'heading', '|', 'insertTable', '|', 'bold', 'italic', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo'
 			'heading', '|', 'insertTable', '|', 'bold', 'italic', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo'
 		],
 		],
 		table: {
 		table: {
-			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ],
+			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties' ],
 			tableToolbar: [ 'bold', 'italic' ]
 			tableToolbar: [ 'bold', 'italic' ]
 		}
 		}
 	} )
 	} )

Некоторые файлы не были показаны из-за большого количества измененных файлов