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

Merge branch 'master' into ckeditor5/t/1214

Piotrek Koszuliński 7 лет назад
Родитель
Сommit
312f280b3b
55 измененных файлов с 576 добавлено и 265 удалено
  1. 13 0
      packages/ckeditor5-table/CHANGELOG.md
  2. 1 1
      packages/ckeditor5-table/docs/_snippets/features/table.js
  3. 6 6
      packages/ckeditor5-table/lang/translations/ar.po
  4. 6 6
      packages/ckeditor5-table/lang/translations/cs.po
  5. 6 6
      packages/ckeditor5-table/lang/translations/de-ch.po
  6. 6 6
      packages/ckeditor5-table/lang/translations/de.po
  7. 6 6
      packages/ckeditor5-table/lang/translations/en-au.po
  8. 6 6
      packages/ckeditor5-table/lang/translations/en.po
  9. 6 6
      packages/ckeditor5-table/lang/translations/et.po
  10. 6 6
      packages/ckeditor5-table/lang/translations/fa.po
  11. 6 6
      packages/ckeditor5-table/lang/translations/fi.po
  12. 12 12
      packages/ckeditor5-table/lang/translations/fr.po
  13. 4 4
      packages/ckeditor5-table/lang/translations/gl.po
  14. 6 6
      packages/ckeditor5-table/lang/translations/hr.po
  15. 6 6
      packages/ckeditor5-table/lang/translations/hu.po
  16. 6 6
      packages/ckeditor5-table/lang/translations/it.po
  17. 6 6
      packages/ckeditor5-table/lang/translations/ja.po
  18. 6 6
      packages/ckeditor5-table/lang/translations/ku.po
  19. 6 6
      packages/ckeditor5-table/lang/translations/nb.po
  20. 6 6
      packages/ckeditor5-table/lang/translations/ne.po
  21. 6 6
      packages/ckeditor5-table/lang/translations/nl.po
  22. 6 6
      packages/ckeditor5-table/lang/translations/no.po
  23. 6 6
      packages/ckeditor5-table/lang/translations/pl.po
  24. 6 6
      packages/ckeditor5-table/lang/translations/pt-br.po
  25. 6 6
      packages/ckeditor5-table/lang/translations/ru.po
  26. 6 6
      packages/ckeditor5-table/lang/translations/sk.po
  27. 6 6
      packages/ckeditor5-table/lang/translations/sq.po
  28. 6 6
      packages/ckeditor5-table/lang/translations/tr.po
  29. 6 6
      packages/ckeditor5-table/lang/translations/uk.po
  30. 78 0
      packages/ckeditor5-table/lang/translations/vi.po
  31. 6 6
      packages/ckeditor5-table/lang/translations/zh-cn.po
  32. 17 17
      packages/ckeditor5-table/package.json
  33. 1 2
      packages/ckeditor5-table/src/commands/insertcolumncommand.js
  34. 1 2
      packages/ckeditor5-table/src/commands/insertrowcommand.js
  35. 1 2
      packages/ckeditor5-table/src/commands/inserttablecommand.js
  36. 1 2
      packages/ckeditor5-table/src/commands/mergecellcommand.js
  37. 1 2
      packages/ckeditor5-table/src/commands/removecolumncommand.js
  38. 1 2
      packages/ckeditor5-table/src/commands/splitcellcommand.js
  39. 30 26
      packages/ckeditor5-table/src/converters/downcast.js
  40. 5 1
      packages/ckeditor5-table/src/converters/upcasttable.js
  41. 6 6
      packages/ckeditor5-table/src/tableediting.js
  42. 4 1
      packages/ckeditor5-table/src/utils.js
  43. 3 11
      packages/ckeditor5-table/tests/_utils/utils.js
  44. 40 0
      packages/ckeditor5-table/tests/converters/downcast.js
  45. 91 4
      packages/ckeditor5-table/tests/converters/upcasttable.js
  46. 1 4
      packages/ckeditor5-table/tests/manual/table.js
  47. 12 0
      packages/ckeditor5-table/tests/manual/tableblockcontent.html
  48. 4 3
      packages/ckeditor5-table/tests/manual/tableblockcontent.js
  49. 1 0
      packages/ckeditor5-table/tests/manual/tableblockcontent.md
  50. 51 2
      packages/ckeditor5-table/tests/tableediting.js
  51. 37 1
      packages/ckeditor5-table/tests/tabletoolbar.js
  52. 1 1
      packages/ckeditor5-table/theme/icons/table-column.svg
  53. 1 1
      packages/ckeditor5-table/theme/icons/table-merge-cell.svg
  54. 1 1
      packages/ckeditor5-table/theme/icons/table-row.svg
  55. 1 1
      packages/ckeditor5-table/theme/icons/table.svg

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

@@ -1,6 +1,19 @@
 Changelog
 Changelog
 =========
 =========
 
 
+## [11.0.1](https://github.com/ckeditor/ckeditor5-table/compare/v11.0.0...v11.0.1) (2018-12-05)
+
+### Bug fixes
+
+* Skip text nodes between `<tr>` elements during table upcast. Closes [#145](https://github.com/ckeditor/ckeditor5-table/issues/145). ([2ecf448](https://github.com/ckeditor/ckeditor5-table/commit/2ecf448))
+
+### Other changes
+
+* Changed labels and command names for the insert column functionality for better UX and translatability. Closes [#138](https://github.com/ckeditor/ckeditor5-table/issues/138). ([fd2221f](https://github.com/ckeditor/ckeditor5-table/commit/fd2221f))
+* Improved SVG icons size. See [ckeditor/ckeditor5-theme-lark#206](https://github.com/ckeditor/ckeditor5-theme-lark/issues/206). ([23d6803](https://github.com/ckeditor/ckeditor5-table/commit/23d6803))
+* Updated translations. ([47475b2](https://github.com/ckeditor/ckeditor5-table/commit/47475b2)) ([5d39d35](https://github.com/ckeditor/ckeditor5-table/commit/5d39d35)) ([7ce6d5b](https://github.com/ckeditor/ckeditor5-table/commit/7ce6d5b)) ([268f607](https://github.com/ckeditor/ckeditor5-table/commit/268f607))
+
+
 ## [11.0.0](https://github.com/ckeditor/ckeditor5-table/compare/v10.1.0...v11.0.0) (2018-10-08)
 ## [11.0.0](https://github.com/ckeditor/ckeditor5-table/compare/v10.1.0...v11.0.0) (2018-10-08)
 
 
 ### Features
 ### Features

+ 1 - 1
packages/ckeditor5-table/docs/_snippets/features/table.js

@@ -14,7 +14,7 @@ ClassicEditor
 			items: [
 			items: [
 				'insertTable', '|', 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo'
 				'insertTable', '|', 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo'
 			],
 			],
-			viewportTopOffset: 100
+			viewportTopOffset: window.getViewportTopOffsetConfig()
 		},
 		},
 		table: {
 		table: {
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]

+ 6 - 6
packages/ckeditor5-table/lang/translations/ar.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "عمود عنوان"
 msgstr "عمود عنوان"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "ادراج عمود قبل"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "ادراج عمود بعد"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/cs.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Sloupec záhlaví"
 msgstr "Sloupec záhlaví"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Vložit sloupec před"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Vložit sloupec za"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

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

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Kopfspalte"
 msgstr "Kopfspalte"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Spalte links einfügen"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Spalte rechts einfügen"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/de.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Kopfspalte"
 msgstr "Kopfspalte"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Spalte links einfügen"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Spalte rechts einfügen"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

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

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Header column"
 msgstr "Header column"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Insert column before"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Insert column after"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/en.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Header column"
 msgstr "Header column"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Insert column before"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr "Insert column left"
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Insert column after"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr "Insert column right"
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/et.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Päise veerg"
 msgstr "Päise veerg"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Sisesta veerg ettepoole"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Sisesta veerg tahapoole"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/fa.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "ستون سربرگ"
 msgstr "ستون سربرگ"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "درج ستون قبل"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "درج ستون بعد"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/fi.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Otsikkosarake"
 msgstr "Otsikkosarake"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Lisää sarake vasemmalle"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Lisää sarake oikealle"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 12 - 12
packages/ckeditor5-table/lang/translations/fr.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Colonne d'entête"
 msgstr "Colonne d'entête"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Insérer une colonne avant"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr "Insérer une colonne à gauche"
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Insérer une colonne après"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr "Insérer une colonne à droite"
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"
@@ -31,15 +31,15 @@ msgstr "Colonne"
 
 
 msgctxt "Label for the set/unset table header row button."
 msgctxt "Label for the set/unset table header row button."
 msgid "Header row"
 msgid "Header row"
-msgstr "Rangée d'entête"
+msgstr "Ligne d'entête"
 
 
 msgctxt "Label for the insert row below button."
 msgctxt "Label for the insert row below button."
 msgid "Insert row below"
 msgid "Insert row below"
-msgstr "Insérer une rangée en-dessous"
+msgstr "Insérer une ligne en-dessous"
 
 
 msgctxt "Label for the insert row above button."
 msgctxt "Label for the insert row above button."
 msgid "Insert row above"
 msgid "Insert row above"
-msgstr "Insérer une rangée au-dessus"
+msgstr "Insérer une ligne au-dessus"
 
 
 msgctxt "Label for the delete table row button."
 msgctxt "Label for the delete table row button."
 msgid "Delete row"
 msgid "Delete row"
@@ -47,7 +47,7 @@ msgstr "Supprimer la rangée"
 
 
 msgctxt "Label for the table row dropdown button."
 msgctxt "Label for the table row dropdown button."
 msgid "Row"
 msgid "Row"
-msgstr "Rangée"
+msgstr "Ligne"
 
 
 msgctxt "Label for the merge table cell up button."
 msgctxt "Label for the merge table cell up button."
 msgid "Merge cell up"
 msgid "Merge cell up"
@@ -67,11 +67,11 @@ msgstr "Fusionner la cellule à gauche"
 
 
 msgctxt "Label for the split table cell vertically button."
 msgctxt "Label for the split table cell vertically button."
 msgid "Split cell vertically"
 msgid "Split cell vertically"
-msgstr "Séparer la cellule verticalement"
+msgstr "Scinder la cellule verticalement"
 
 
 msgctxt "Label for the split table cell horizontally button."
 msgctxt "Label for the split table cell horizontally button."
 msgid "Split cell horizontally"
 msgid "Split cell horizontally"
-msgstr "Séparer la cellule horizontalement"
+msgstr "Scinder la cellule horizontalement"
 
 
 msgctxt "Label for the merge table cells button."
 msgctxt "Label for the merge table cells button."
 msgid "Merge cells"
 msgid "Merge cells"

+ 4 - 4
packages/ckeditor5-table/lang/translations/gl.po

@@ -13,12 +13,12 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Cabeceira de columna"
 msgstr "Cabeceira de columna"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
 msgstr "Inserir columna á esquerda"
 msgstr "Inserir columna á esquerda"
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
 msgstr "Inserir columna á dereita"
 msgstr "Inserir columna á dereita"
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."

+ 6 - 6
packages/ckeditor5-table/lang/translations/hr.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Kolona zaglavlja"
 msgstr "Kolona zaglavlja"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Ubaci kolonu prije"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Ubaci kolonu nakon"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/hu.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Oszlop fejléc"
 msgstr "Oszlop fejléc"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Oszlop beszúrása elé"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr "Oszlop beszúrása balra"
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Oszlop beszúrása mögé"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr "Oszlop beszúrása jobbra"
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/it.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Intestazione colonna"
 msgstr "Intestazione colonna"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Inserisci colonna prima"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Inserisci colonna dopo"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/ja.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "見出し列"
 msgstr "見出し列"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "左に列を挿入"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "\b右に列を挿入"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/ku.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "ستوونی دەسپێک"
 msgstr "ستوونی دەسپێک"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "لە پێش دانانی ستوون"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "لەدووا دانانی ستوون"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/nb.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Overskriftkolonne"
 msgstr "Overskriftkolonne"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Sett inn kolonne før"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Sett inn kolonne etter"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/ne.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "हेडर स्तम्भ"
 msgstr "हेडर स्तम्भ"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "अगाडि स्तम्भ सम्मिलित गर्नुहोस्"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "पछि स्तम्भ सम्मिलित गर्नुहोस्"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/nl.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Titel kolom"
 msgstr "Titel kolom"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Kolom hiervoor invoegen"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Kolom hierna invoegen"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/no.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Overskriftkolonne"
 msgstr "Overskriftkolonne"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Sett inn kolonne før"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr "Sett inn kolonne til venstre"
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Sett inn kolonne etter"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr "Sett inn kolonne til høyre"
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/pl.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Kolumna nagłówka"
 msgstr "Kolumna nagłówka"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Wstaw kolumnę przed"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr "Wstaw kolumnę z lewej"
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Wstaw kolumnę po"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr "Wstaw kolumnę z prawej"
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

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

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Coluna de cabeçalho"
 msgstr "Coluna de cabeçalho"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Inserir coluna antes"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Inserir coluna depois"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/ru.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Столбец заголовков"
 msgstr "Столбец заголовков"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Вставить столбец левее"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Вставить столбец правее"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/sk.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Stĺpec hlavičky"
 msgstr "Stĺpec hlavičky"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Vložiť stĺpec vľavo"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Vložiť stĺpec vpravo"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/sq.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Kolona e kokës"
 msgstr "Kolona e kokës"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Shto kolonë para"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Shto kolonë pas"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/tr.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Başlık kolonu"
 msgstr "Başlık kolonu"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Öncesine kolon ekle"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr "Sola kolon ekle"
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Sonrasına kolon ekle"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr "Sa kolon ekle"
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

+ 6 - 6
packages/ckeditor5-table/lang/translations/uk.po

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "Заголовок стовпця"
 msgstr "Заголовок стовпця"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "Вставити стовпець перед"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "Вставити стовпець після"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Vietnamese (https://www.transifex.com/ckeditor/teams/11143/vi/)\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Tạo bảng"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+msgstr "Tiêu đề cột"
+
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr "Thêm cột vào bên trái"
+
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr "Thêm cột vào bên phải"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Xoá cột"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Cột"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Tiêu đề hàng"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Thêm hàng ở dưới"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Thêm hàng phía trên"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Xoá hàng"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Hàng"
+
+msgctxt "Label for the merge table cell up button."
+msgid "Merge cell up"
+msgstr ""
+
+msgctxt "Label for the merge table cell right button."
+msgid "Merge cell right"
+msgstr ""
+
+msgctxt "Label for the merge table cell down button."
+msgid "Merge cell down"
+msgstr ""
+
+msgctxt "Label for the merge table cell left button."
+msgid "Merge cell left"
+msgstr ""
+
+msgctxt "Label for the split table cell vertically button."
+msgid "Split cell vertically"
+msgstr ""
+
+msgctxt "Label for the split table cell horizontally button."
+msgid "Split cell horizontally"
+msgstr ""
+
+msgctxt "Label for the merge table cells button."
+msgid "Merge cells"
+msgstr ""

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

@@ -13,13 +13,13 @@ msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
 msgid "Header column"
 msgstr "标题列"
 msgstr "标题列"
 
 
-msgctxt "Label for the insert table column before the current one button."
-msgid "Insert column before"
-msgstr "在前面插入列"
+msgctxt "Label for the insert table column to the left of the current one button."
+msgid "Insert column left"
+msgstr ""
 
 
-msgctxt "Label for the insert table column after the current one button."
-msgid "Insert column after"
-msgstr "在后面插入列"
+msgctxt "Label for the insert table column to the right of the current one button."
+msgid "Insert column right"
+msgstr ""
 
 
 msgctxt "Label for the delete table column button."
 msgctxt "Label for the delete table column button."
 msgid "Delete column"
 msgid "Delete column"

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

@@ -1,6 +1,6 @@
 {
 {
   "name": "@ckeditor/ckeditor5-table",
   "name": "@ckeditor/ckeditor5-table",
-  "version": "11.0.0",
+  "version": "11.0.1",
   "description": "Table feature for CKEditor 5.",
   "description": "Table feature for CKEditor 5.",
   "keywords": [
   "keywords": [
     "ckeditor",
     "ckeditor",
@@ -10,25 +10,25 @@
     "ckeditor5-plugin"
     "ckeditor5-plugin"
   ],
   ],
   "dependencies": {
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^11.0.1",
-    "@ckeditor/ckeditor5-engine": "^11.0.0",
-    "@ckeditor/ckeditor5-ui": "^11.1.0",
-    "@ckeditor/ckeditor5-widget": "^10.3.0"
+    "@ckeditor/ckeditor5-core": "^11.1.0",
+    "@ckeditor/ckeditor5-ui": "^11.2.0",
+    "@ckeditor/ckeditor5-widget": "^10.3.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@ckeditor/ckeditor5-alignment": "^10.0.3",
-    "@ckeditor/ckeditor5-block-quote": "^10.1.0",
-    "@ckeditor/ckeditor5-clipboard": "^10.0.3",
-    "@ckeditor/ckeditor5-editor-classic": "^11.0.1",
-    "@ckeditor/ckeditor5-image": "^11.0.0",
-    "@ckeditor/ckeditor5-list": "^11.0.2",
-    "@ckeditor/ckeditor5-media-embed": "^10.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^10.0.3",
-    "@ckeditor/ckeditor5-typing": "^11.0.1",
-    "@ckeditor/ckeditor5-undo": "^10.0.3",
-    "@ckeditor/ckeditor5-utils": "^11.0.0",
+    "@ckeditor/ckeditor5-alignment": "^10.0.4",
+    "@ckeditor/ckeditor5-block-quote": "^10.1.1",
+    "@ckeditor/ckeditor5-clipboard": "^10.0.4",
+    "@ckeditor/ckeditor5-editor-classic": "^11.0.2",
+    "@ckeditor/ckeditor5-engine": "^12.0.0",
+    "@ckeditor/ckeditor5-image": "^12.0.0",
+    "@ckeditor/ckeditor5-list": "^11.0.3",
+    "@ckeditor/ckeditor5-media-embed": "^10.1.0",
+    "@ckeditor/ckeditor5-paragraph": "^10.0.4",
+    "@ckeditor/ckeditor5-typing": "^11.0.2",
+    "@ckeditor/ckeditor5-undo": "^10.0.4",
+    "@ckeditor/ckeditor5-utils": "^11.1.0",
     "eslint": "^5.5.0",
     "eslint": "^5.5.0",
-    "eslint-config-ckeditor5": "^1.0.7",
+    "eslint-config-ckeditor5": "^1.0.9",
     "husky": "^0.14.3",
     "husky": "^0.14.3",
     "lint-staged": "^7.0.0"
     "lint-staged": "^7.0.0"
   },
   },

+ 1 - 2
packages/ckeditor5-table/src/commands/insertcolumncommand.js

@@ -9,7 +9,6 @@
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import { findAncestor } from './utils';
 import { findAncestor } from './utils';
-import TableUtils from '../tableutils';
 
 
 /**
 /**
  * The insert column command.
  * The insert column command.
@@ -70,7 +69,7 @@ export default class InsertColumnCommand extends Command {
 	execute() {
 	execute() {
 		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 firstPosition = selection.getFirstPosition();
 		const firstPosition = selection.getFirstPosition();
 
 

+ 1 - 2
packages/ckeditor5-table/src/commands/insertrowcommand.js

@@ -9,7 +9,6 @@
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import { findAncestor } from './utils';
 import { findAncestor } from './utils';
-import TableUtils from '../tableutils';
 
 
 /**
 /**
  * The insert row command.
  * The insert row command.
@@ -69,7 +68,7 @@ export default class InsertRowCommand extends Command {
 	execute() {
 	execute() {
 		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 tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
 		const tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
 		const tableRow = tableCell.parent;
 		const tableRow = tableCell.parent;

+ 1 - 2
packages/ckeditor5-table/src/commands/inserttablecommand.js

@@ -9,7 +9,6 @@
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import { findOptimalInsertionPosition } from '@ckeditor/ckeditor5-widget/src/utils';
 import { findOptimalInsertionPosition } from '@ckeditor/ckeditor5-widget/src/utils';
-import TableUtils from '../tableutils';
 
 
 /**
 /**
  * The insert table command.
  * The insert table command.
@@ -49,7 +48,7 @@ export default class InsertTableCommand extends Command {
 	execute( options = {} ) {
 	execute( options = {} ) {
 		const model = this.editor.model;
 		const model = this.editor.model;
 		const selection = model.document.selection;
 		const selection = model.document.selection;
-		const tableUtils = this.editor.plugins.get( TableUtils );
+		const tableUtils = this.editor.plugins.get( 'TableUtils' );
 
 
 		const rows = parseInt( options.rows ) || 2;
 		const rows = parseInt( options.rows ) || 2;
 		const columns = parseInt( options.columns ) || 2;
 		const columns = parseInt( options.columns ) || 2;

+ 1 - 2
packages/ckeditor5-table/src/commands/mergecellcommand.js

@@ -10,7 +10,6 @@
 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 { findAncestor, updateNumericAttribute } from './utils';
-import TableUtils from '../tableutils';
 
 
 /**
 /**
  * The merge cell command.
  * The merge cell command.
@@ -127,7 +126,7 @@ export default class MergeCellCommand extends Command {
 			return;
 			return;
 		}
 		}
 
 
-		const tableUtils = this.editor.plugins.get( TableUtils );
+		const tableUtils = this.editor.plugins.get( 'TableUtils' );
 
 
 		// First get the cell on proper direction.
 		// First get the cell on proper direction.
 		const cellToMerge = this.isHorizontal ?
 		const cellToMerge = this.isHorizontal ?

+ 1 - 2
packages/ckeditor5-table/src/commands/removecolumncommand.js

@@ -10,7 +10,6 @@
 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 TableUtils from '../tableutils';
 import { findAncestor, updateNumericAttribute } from './utils';
 import { findAncestor, updateNumericAttribute } from './utils';
 
 
 /**
 /**
@@ -31,7 +30,7 @@ export default class RemoveColumnCommand extends Command {
 	refresh() {
 	refresh() {
 		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 tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
 		const tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
 
 

+ 1 - 2
packages/ckeditor5-table/src/commands/splitcellcommand.js

@@ -8,7 +8,6 @@
  */
  */
 
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
-import TableUtils from '../tableutils';
 import { findAncestor } from './utils';
 import { findAncestor } from './utils';
 
 
 /**
 /**
@@ -68,7 +67,7 @@ export default class SplitCellCommand extends Command {
 
 
 		const isHorizontally = this.direction === 'horizontally';
 		const isHorizontally = this.direction === 'horizontally';
 
 
-		const tableUtils = this.editor.plugins.get( TableUtils );
+		const tableUtils = this.editor.plugins.get( 'TableUtils' );
 
 
 		if ( isHorizontally ) {
 		if ( isHorizontally ) {
 			tableUtils.splitCellHorizontally( tableCell, 2 );
 			tableUtils.splitCellHorizontally( tableCell, 2 );

+ 30 - 26
packages/ckeditor5-table/src/converters/downcast.js

@@ -51,14 +51,17 @@ export function downcastInsertTable( options = {} ) {
 			headingColumns: table.getAttribute( 'headingColumns' ) || 0
 			headingColumns: table.getAttribute( 'headingColumns' ) || 0
 		};
 		};
 
 
+		// Cache for created table rows.
+		const viewRows = new Map();
+
 		for ( const tableWalkerValue of tableWalker ) {
 		for ( const tableWalkerValue of tableWalker ) {
 			const { row, cell } = tableWalkerValue;
 			const { row, cell } = tableWalkerValue;
 
 
 			const tableSection = getOrCreateTableSection( getSectionName( row, tableAttributes ), tableElement, conversionApi );
 			const tableSection = getOrCreateTableSection( getSectionName( row, tableAttributes ), tableElement, conversionApi );
 			const tableRow = table.getChild( row );
 			const tableRow = table.getChild( row );
 
 
-			// Check if row was converted
-			const trElement = getOrCreateTr( tableRow, row, tableSection, conversionApi );
+			const trElement = viewRows.get( row ) || createTr( tableRow, row, tableSection, conversionApi );
+			viewRows.set( row, trElement );
 
 
 			// Consume table cell - it will be always consumed as we convert whole table at once.
 			// Consume table cell - it will be always consumed as we convert whole table at once.
 			conversionApi.consumable.consume( cell, 'insert' );
 			conversionApi.consumable.consume( cell, 'insert' );
@@ -104,9 +107,14 @@ export function downcastInsertRow( options = {} ) {
 			headingColumns: table.getAttribute( 'headingColumns' ) || 0
 			headingColumns: table.getAttribute( 'headingColumns' ) || 0
 		};
 		};
 
 
+		// Cache for created table rows.
+		const viewRows = new Map();
+
 		for ( const tableWalkerValue of tableWalker ) {
 		for ( const tableWalkerValue of tableWalker ) {
 			const tableSection = getOrCreateTableSection( getSectionName( row, tableAttributes ), tableElement, conversionApi );
 			const tableSection = getOrCreateTableSection( getSectionName( row, tableAttributes ), tableElement, conversionApi );
-			const trElement = getOrCreateTr( tableRow, row, tableSection, conversionApi );
+
+			const trElement = viewRows.get( row ) || createTr( tableRow, row, tableSection, conversionApi );
+			viewRows.set( row, trElement );
 
 
 			// Consume table cell - it will be always consumed as we convert whole row at once.
 			// Consume table cell - it will be always consumed as we convert whole row at once.
 			conversionApi.consumable.consume( tableWalkerValue.cell, 'insert' );
 			conversionApi.consumable.consume( tableWalkerValue.cell, 'insert' );
@@ -313,7 +321,7 @@ export function downcastRemoveRow() {
 //
 //
 // @param {module:engine/model/element~Element} tableCell
 // @param {module:engine/model/element~Element} tableCell
 // @param {String} desiredCellElementName
 // @param {String} desiredCellElementName
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 // @param {Boolean} asWidget
 // @param {Boolean} asWidget
 function renameViewTableCell( tableCell, desiredCellElementName, conversionApi, asWidget ) {
 function renameViewTableCell( tableCell, desiredCellElementName, conversionApi, asWidget ) {
 	const viewWriter = conversionApi.writer;
 	const viewWriter = conversionApi.writer;
@@ -344,7 +352,7 @@ function renameViewTableCell( tableCell, desiredCellElementName, conversionApi,
 //
 //
 // @param {module:table/tablewalker~TableWalkerValue} tableWalkerValue
 // @param {module:table/tablewalker~TableWalkerValue} tableWalkerValue
 // @param {{headingColumns, headingRows}} tableAttributes
 // @param {{headingColumns, headingRows}} tableAttributes
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 // @param {Boolean} asWidget
 // @param {Boolean} asWidget
 function renameViewTableCellIfRequired( tableWalkerValue, tableAttributes, conversionApi, asWidget ) {
 function renameViewTableCellIfRequired( tableWalkerValue, tableAttributes, conversionApi, asWidget ) {
 	const { cell } = tableWalkerValue;
 	const { cell } = tableWalkerValue;
@@ -365,7 +373,7 @@ function renameViewTableCellIfRequired( tableWalkerValue, tableAttributes, conve
 //
 //
 // @param {module:table/tablewalker~TableWalkerValue} tableWalkerValue
 // @param {module:table/tablewalker~TableWalkerValue} tableWalkerValue
 // @param {module:engine/view/position~Position} insertPosition
 // @param {module:engine/view/position~Position} insertPosition
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 function createViewTableCellElement( tableWalkerValue, tableAttributes, insertPosition, conversionApi, options ) {
 function createViewTableCellElement( tableWalkerValue, tableAttributes, insertPosition, conversionApi, options ) {
 	const asWidget = options && options.asWidget;
 	const asWidget = options && options.asWidget;
 	const cellElementName = getCellElementName( tableWalkerValue, tableAttributes );
 	const cellElementName = getCellElementName( tableWalkerValue, tableAttributes );
@@ -404,29 +412,25 @@ function createViewTableCellElement( tableWalkerValue, tableAttributes, insertPo
 	}
 	}
 }
 }
 
 
-// Creates or returns an existing `<tr>` element from the view.
+// Creates `<tr>` view element.
 //
 //
 // @param {module:engine/view/element~Element} tableRow
 // @param {module:engine/view/element~Element} tableRow
 // @param {Number} rowIndex
 // @param {Number} rowIndex
 // @param {module:engine/view/element~Element} tableSection
 // @param {module:engine/view/element~Element} tableSection
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 // @returns {module:engine/view/element~Element}
 // @returns {module:engine/view/element~Element}
-function getOrCreateTr( tableRow, rowIndex, tableSection, conversionApi ) {
-	let trElement = conversionApi.mapper.toViewElement( tableRow );
+function createTr( tableRow, rowIndex, tableSection, conversionApi ) {
+	// Will always consume since we're converting <tableRow> element from a parent <table>.
+	conversionApi.consumable.consume( tableRow, 'insert' );
 
 
-	if ( !trElement ) {
-		// Will always consume since we're converting <tableRow> element from a parent <table>.
-		conversionApi.consumable.consume( tableRow, 'insert' );
+	const trElement = conversionApi.writer.createContainerElement( 'tr' );
+	conversionApi.mapper.bindElements( tableRow, trElement );
 
 
-		trElement = conversionApi.writer.createContainerElement( 'tr' );
-		conversionApi.mapper.bindElements( tableRow, trElement );
+	const headingRows = tableRow.parent.getAttribute( 'headingRows' ) || 0;
+	const offset = headingRows > 0 && rowIndex >= headingRows ? rowIndex - headingRows : rowIndex;
 
 
-		const headingRows = tableRow.parent.getAttribute( 'headingRows' ) || 0;
-		const offset = headingRows > 0 && rowIndex >= headingRows ? rowIndex - headingRows : rowIndex;
-
-		const position = conversionApi.writer.createPositionAt( tableSection, offset );
-		conversionApi.writer.insert( position, trElement );
-	}
+	const position = conversionApi.writer.createPositionAt( tableSection, offset );
+	conversionApi.writer.insert( position, trElement );
 
 
 	return trElement;
 	return trElement;
 }
 }
@@ -467,7 +471,7 @@ function getSectionName( row, tableAttributes ) {
 //
 //
 // @param {String} sectionName
 // @param {String} sectionName
 // @param {module:engine/view/element~Element} viewTable
 // @param {module:engine/view/element~Element} viewTable
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 // @param {Object} cachedTableSection An object that stores cached elements.
 // @param {Object} cachedTableSection An object that stores cached elements.
 // @returns {module:engine/view/containerelement~ContainerElement}
 // @returns {module:engine/view/containerelement~ContainerElement}
 function getOrCreateTableSection( sectionName, viewTable, conversionApi ) {
 function getOrCreateTableSection( sectionName, viewTable, conversionApi ) {
@@ -480,7 +484,7 @@ function getOrCreateTableSection( sectionName, viewTable, conversionApi ) {
 //
 //
 // @param {String} sectionName
 // @param {String} sectionName
 // @param {module:engine/view/element~Element} tableElement
 // @param {module:engine/view/element~Element} tableElement
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 function getExistingTableSectionElement( sectionName, tableElement ) {
 function getExistingTableSectionElement( sectionName, tableElement ) {
 	for ( const tableSection of tableElement.getChildren() ) {
 	for ( const tableSection of tableElement.getChildren() ) {
 		if ( tableSection.name == sectionName ) {
 		if ( tableSection.name == sectionName ) {
@@ -493,7 +497,7 @@ function getExistingTableSectionElement( sectionName, tableElement ) {
 //
 //
 // @param {String} sectionName
 // @param {String} sectionName
 // @param {module:engine/view/element~Element} tableElement
 // @param {module:engine/view/element~Element} tableElement
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 // @returns {module:engine/view/containerelement~ContainerElement}
 // @returns {module:engine/view/containerelement~ContainerElement}
 function createTableSection( sectionName, tableElement, conversionApi ) {
 function createTableSection( sectionName, tableElement, conversionApi ) {
 	const tableChildElement = conversionApi.writer.createContainerElement( sectionName );
 	const tableChildElement = conversionApi.writer.createContainerElement( sectionName );
@@ -509,7 +513,7 @@ function createTableSection( sectionName, tableElement, conversionApi ) {
 //
 //
 // @param {String} sectionName
 // @param {String} sectionName
 // @param {module:engine/view/element~Element} tableElement
 // @param {module:engine/view/element~Element} tableElement
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 function removeTableSectionIfEmpty( sectionName, tableElement, conversionApi ) {
 function removeTableSectionIfEmpty( sectionName, tableElement, conversionApi ) {
 	const tableSection = getExistingTableSectionElement( sectionName, tableElement );
 	const tableSection = getExistingTableSectionElement( sectionName, tableElement );
 
 
@@ -524,7 +528,7 @@ function removeTableSectionIfEmpty( sectionName, tableElement, conversionApi ) {
 //
 //
 // @param {Array.<module:engine/model/element~Element>} rowsToMove
 // @param {Array.<module:engine/model/element~Element>} rowsToMove
 // @param {module:engine/view/element~Element} viewTableSection
 // @param {module:engine/view/element~Element} viewTableSection
-// @param {Object} conversionApi
+// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi
 // @param {Number|'end'|'before'|'after'} offset Offset or one of the flags.
 // @param {Number|'end'|'before'|'after'} offset Offset or one of the flags.
 function moveViewRowsToTableSection( rowsToMove, viewTableSection, conversionApi, offset ) {
 function moveViewRowsToTableSection( rowsToMove, viewTableSection, conversionApi, offset ) {
 	for ( const tableRow of rowsToMove ) {
 	for ( const tableRow of rowsToMove ) {

+ 5 - 1
packages/ckeditor5-table/src/converters/upcasttable.js

@@ -180,7 +180,11 @@ function scanTable( viewTable ) {
 				firstTheadElement = tableChild;
 				firstTheadElement = tableChild;
 			}
 			}
 
 
-			for ( const tr of Array.from( tableChild.getChildren() ) ) {
+			// There might be some extra empty text nodes between the `tr`s.
+			// Make sure further code operates on `tr`s only. (#145)
+			const trs = Array.from( tableChild.getChildren() ).filter( el => el.is( 'element', 'tr' ) );
+
+			for ( const tr of trs ) {
 				// This <tr> is a child of a first <thead> element.
 				// This <tr> is a child of a first <thead> element.
 				if ( tr.parent.name === 'thead' && tr.parent === firstTheadElement ) {
 				if ( tr.parent.name === 'thead' && tr.parent === firstTheadElement ) {
 					tableMeta.headingRows++;
 					tableMeta.headingRows++;

+ 6 - 6
packages/ckeditor5-table/src/tableediting.js

@@ -8,7 +8,6 @@
  */
  */
 
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
-import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
 
 
 import upcastTable, { upcastTableCell } from './converters/upcasttable';
 import upcastTable, { upcastTableCell } from './converters/upcasttable';
 import {
 import {
@@ -57,7 +56,8 @@ export default class TableEditing extends Plugin {
 			allowWhere: '$block',
 			allowWhere: '$block',
 			allowAttributes: [ 'headingRows', 'headingColumns' ],
 			allowAttributes: [ 'headingRows', 'headingColumns' ],
 			isLimit: true,
 			isLimit: true,
-			isObject: true
+			isObject: true,
+			isBlock: true
 		} );
 		} );
 
 
 		schema.register( 'tableRow', {
 		schema.register( 'tableRow', {
@@ -81,13 +81,13 @@ export default class TableEditing extends Plugin {
 			}
 			}
 		} );
 		} );
 
 
-		// Disallow image and media in table cell.
+		// Disallow media in table cell.
 		schema.addChildCheck( ( context, childDefinition ) => {
 		schema.addChildCheck( ( context, childDefinition ) => {
 			if ( !Array.from( context.getNames() ).includes( 'table' ) ) {
 			if ( !Array.from( context.getNames() ).includes( 'table' ) ) {
 				return;
 				return;
 			}
 			}
 
 
-			if ( childDefinition.name == 'image' || childDefinition.name == 'media' ) {
+			if ( childDefinition.name == 'media' ) {
 				return false;
 				return false;
 			}
 			}
 		} );
 		} );
@@ -99,7 +99,7 @@ export default class TableEditing extends Plugin {
 		conversion.for( 'dataDowncast' ).add( downcastInsertTable() );
 		conversion.for( 'dataDowncast' ).add( downcastInsertTable() );
 
 
 		// Table row conversion.
 		// Table row conversion.
-		conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableRow', view: 'tr' } ) );
+		conversion.for( 'upcast' ).elementToElement( { model: 'tableRow', view: 'tr' } );
 
 
 		conversion.for( 'editingDowncast' ).add( downcastInsertRow( { asWidget: true } ) );
 		conversion.for( 'editingDowncast' ).add( downcastInsertRow( { asWidget: true } ) );
 		conversion.for( 'dataDowncast' ).add( downcastInsertRow() );
 		conversion.for( 'dataDowncast' ).add( downcastInsertRow() );
@@ -228,7 +228,7 @@ export default class TableEditing extends Plugin {
 			const isLastRow = currentRowIndex === table.childCount - 1;
 			const isLastRow = currentRowIndex === table.childCount - 1;
 
 
 			if ( isForward && isLastRow && isLastCellInRow ) {
 			if ( isForward && isLastRow && isLastCellInRow ) {
-				editor.plugins.get( TableUtils ).insertRows( table, { at: table.childCount } );
+				editor.plugins.get( 'TableUtils' ).insertRows( table, { at: table.childCount } );
 			}
 			}
 
 
 			let cellToFocus;
 			let cellToFocus;

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

@@ -57,7 +57,10 @@ export function isTableWidgetSelected( selection ) {
  * @returns {Boolean}
  * @returns {Boolean}
  */
  */
 export function isTableContentSelected( selection ) {
 export function isTableContentSelected( selection ) {
+	const selectedElement = selection.getSelectedElement();
+	const isInnerWidgetSelected = selectedElement && isWidget( selectedElement );
+
 	const parentTable = findAncestor( 'table', selection.getFirstPosition() );
 	const parentTable = findAncestor( 'table', selection.getFirstPosition() );
 
 
-	return !!( parentTable && isTableWidget( parentTable.parent ) );
+	return !isInnerWidgetSelected && !!( parentTable && isTableWidget( parentTable.parent ) );
 }
 }

+ 3 - 11
packages/ckeditor5-table/tests/_utils/utils.js

@@ -3,8 +3,6 @@
  * For licensing, see LICENSE.md.
  * For licensing, see LICENSE.md.
  */
  */
 
 
-import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
-
 import {
 import {
 	downcastInsertCell,
 	downcastInsertCell,
 	downcastInsertRow,
 	downcastInsertRow,
@@ -163,7 +161,8 @@ export function defaultSchema( schema, registerParagraph = true ) {
 		allowWhere: '$block',
 		allowWhere: '$block',
 		allowAttributes: [ 'headingRows', 'headingColumns' ],
 		allowAttributes: [ 'headingRows', 'headingColumns' ],
 		isLimit: true,
 		isLimit: true,
-		isObject: true
+		isObject: true,
+		isBlock: true
 	} );
 	} );
 
 
 	schema.register( 'tableRow', {
 	schema.register( 'tableRow', {
@@ -187,13 +186,6 @@ export function defaultSchema( schema, registerParagraph = true ) {
 		}
 		}
 	} );
 	} );
 
 
-	// Disallow image in table.
-	schema.addChildCheck( ( context, childDefinition ) => {
-		if ( childDefinition.name == 'image' && Array.from( context.getNames() ).includes( 'table' ) ) {
-			return false;
-		}
-	} );
-
 	if ( registerParagraph ) {
 	if ( registerParagraph ) {
 		schema.register( 'paragraph', { inheritAllFrom: '$block' } );
 		schema.register( 'paragraph', { inheritAllFrom: '$block' } );
 	}
 	}
@@ -207,7 +199,7 @@ export function defaultConversion( conversion, asWidget = false ) {
 	conversion.for( 'downcast' ).add( downcastInsertTable( { asWidget } ) );
 	conversion.for( 'downcast' ).add( downcastInsertTable( { asWidget } ) );
 
 
 	// Table row conversion.
 	// Table row conversion.
-	conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableRow', view: 'tr' } ) );
+	conversion.for( 'upcast' ).elementToElement( { model: 'tableRow', view: 'tr' } );
 	conversion.for( 'downcast' ).add( downcastInsertRow( { asWidget } ) );
 	conversion.for( 'downcast' ).add( downcastInsertRow( { asWidget } ) );
 	conversion.for( 'downcast' ).add( downcastRemoveRow( { asWidget } ) );
 	conversion.for( 'downcast' ).add( downcastRemoveRow( { asWidget } ) );
 
 

+ 40 - 0
packages/ckeditor5-table/tests/converters/downcast.js

@@ -171,6 +171,46 @@ describe( 'downcast converters', () => {
 			) );
 			) );
 		} );
 		} );
 
 
+		it( 'should re-create table on reinsert', () => {
+			model.schema.register( 'wrapper', {
+				allowWhere: '$block',
+				allowContentOf: '$root'
+			} );
+			editor.conversion.elementToElement( { model: 'wrapper', view: 'div' } );
+
+			setModelData( model, modelTable( [ [ '[]' ] ] ) );
+
+			expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formatTable(
+				'<figure class="table">' +
+					'<table>' +
+						'<tbody>' +
+							'<tr><td></td></tr>' +
+						'</tbody>' +
+					'</table>' +
+				'</figure>'
+			) );
+
+			model.change( writer => {
+				const table = model.document.getRoot().getChild( 0 );
+				const range = writer.createRange( writer.createPositionBefore( table ), writer.createPositionAfter( table ) );
+				const wrapper = writer.createElement( 'wrapper' );
+
+				writer.wrap( range, wrapper );
+			} );
+
+			expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formatTable(
+				'<div>' +
+					'<figure class="table">' +
+						'<table>' +
+							'<tbody>' +
+								'<tr><td></td></tr>' +
+							'</tbody>' +
+						'</table>' +
+					'</figure>' +
+				'</div>'
+			) );
+		} );
+
 		describe( 'headingColumns attribute', () => {
 		describe( 'headingColumns attribute', () => {
 			it( 'should mark heading columns table cells', () => {
 			it( 'should mark heading columns table cells', () => {
 				setModelData( model, modelTable( [
 				setModelData( model, modelTable( [

+ 91 - 4
packages/ckeditor5-table/tests/converters/upcasttable.js

@@ -4,7 +4,6 @@
  */
  */
 
 
 import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
 import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
-import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
 import { getData as getModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData as getModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import ImageEditing from '@ckeditor/ckeditor5-image/src/image/imageediting';
 import ImageEditing from '@ckeditor/ckeditor5-image/src/image/imageediting';
@@ -211,7 +210,7 @@ describe( 'upcastTable()', () => {
 		editor.model.schema.register( 'div', {
 		editor.model.schema.register( 'div', {
 			inheritAllFrom: '$block'
 			inheritAllFrom: '$block'
 		} );
 		} );
-		editor.conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'div', view: 'div' } ) );
+		editor.conversion.for( 'upcast' ).elementToElement( { model: 'div', view: 'div' } );
 
 
 		editor.setData(
 		editor.setData(
 			'<div>foo' +
 			'<div>foo' +
@@ -457,7 +456,7 @@ describe( 'upcastTable()', () => {
 			] ) );
 			] ) );
 		} );
 		} );
 
 
-		it( 'should upcast table with <img> in table cell to empty table cell', () => {
+		it( 'should upcast table with <img> in table cell', () => {
 			editor.setData(
 			editor.setData(
 				'<table>' +
 				'<table>' +
 					'<tbody>' +
 					'<tbody>' +
@@ -469,8 +468,96 @@ describe( 'upcastTable()', () => {
 			);
 			);
 
 
 			expectModel( modelTable( [
 			expectModel( modelTable( [
-				[ '' ]
+				[ '<image src="sample.png"></image>' ]
 			] ) );
 			] ) );
 		} );
 		} );
 	} );
 	} );
+
+	describe( 'handling redundant whitespacing between table elements', () => {
+		it( 'table without thead/tbody/tfoot', () => {
+			editor.setData(
+				'<table> ' +
+					'<tr> <td>1</td></tr>' +
+				'</table>'
+			);
+
+			expectModel(
+				'<table>' +
+					'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+				'</table>'
+			);
+		} );
+
+		it( 'table with thead only', () => {
+			editor.setData(
+				'<table>' +
+					'<thead>' +
+						'<tr><td>1</td></tr> ' +
+						'<tr><td>2</td></tr>' +
+						' <tr><td>3</td></tr>' +
+					'</thead>' +
+				'</table>'
+			);
+
+			expectModel(
+				'<table headingRows="3">' +
+					'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>2</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>3</paragraph></tableCell></tableRow>' +
+				'</table>'
+			);
+		} );
+
+		it( 'table with thead and tbody', () => {
+			editor.setData(
+				'<table>' +
+					'<thead>   ' +
+						'<tr><td>1</td></tr>' +
+						'<tr><td>2</td></tr>\n\n   ' +
+					'</thead>' +
+					'<tbody>' +
+						'<tr><td>3</td></tr> ' +
+						'\n\n    <tr><td>4</td></tr>' +
+						'<tr>    <td>5</td></tr> ' +
+					'</tbody>' +
+				'</table>'
+			);
+
+			expectModel(
+				'<table headingRows="2">' +
+					'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>2</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>3</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>4</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>5</paragraph></tableCell></tableRow>' +
+				'</table>'
+			);
+		} );
+
+		it( 'table with tbody and tfoot', () => {
+			editor.setData(
+				'<table>' +
+					'<tbody>' +
+						'     <tr><td>1</td></tr>' +
+						'<tr><td>2</td></tr>' +
+						'<tr><td>3</td></tr> ' +
+						'<tr><td>4</td></tr>\n\n\n' +
+					'</tbody>\n\n' +
+					'   <tfoot>' +
+						'<tr>  <td>5</td>\n\n\n</tr>   ' +
+					'</tfoot>' +
+				'</table>'
+			);
+
+			expectModel(
+				'<table>' +
+					'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>2</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>3</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>4</paragraph></tableCell></tableRow>' +
+					'<tableRow><tableCell><paragraph>5</paragraph></tableCell></tableRow>' +
+				'</table>'
+			);
+		} );
+	} );
 } );
 } );

+ 1 - 4
packages/ckeditor5-table/tests/manual/table.js

@@ -7,13 +7,10 @@
 
 
 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 Table from '../../src/table';
-import TableToolbar from '../../src/tabletoolbar';
-import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
 
 
 ClassicEditor
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 	.create( document.querySelector( '#editor' ), {
-		plugins: [ ArticlePluginSet, Table, TableToolbar, BlockQuote ],
+		plugins: [ ArticlePluginSet ],
 		toolbar: [
 		toolbar: [
 			'heading', '|', 'insertTable', '|', 'bold', 'italic', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo'
 			'heading', '|', 'insertTable', '|', 'bold', 'italic', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo'
 		],
 		],

+ 12 - 0
packages/ckeditor5-table/tests/manual/tableblockcontent.html

@@ -64,6 +64,18 @@
 			</td>
 			</td>
 			<td><blockquote><p style="text-align: right">A quote with paragraph with right alignment</p></blockquote></td>
 			<td><blockquote><p style="text-align: right">A quote with paragraph with right alignment</p></blockquote></td>
 		</tr>
 		</tr>
+		<tr>
+			<td>image</td>
+			<td>
+				<img alt="sample image" src="sample.jpg">
+			</td>
+			<td>
+				<p>An image aligned to right:</p>
+				<figure class="image image-style-side" contenteditable="false">
+					<img src="sample.jpg" alt="sample image">
+				</figure>
+			</td>
+		</tr>
 		</tbody>
 		</tbody>
 	</table>
 	</table>
 </div>
 </div>

+ 4 - 3
packages/ckeditor5-table/tests/manual/tableblockcontent.js

@@ -7,17 +7,18 @@
 
 
 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 Table from '../../src/table';
-import TableToolbar from '../../src/tabletoolbar';
 import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
 import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
 
 
 ClassicEditor
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 	.create( document.querySelector( '#editor' ), {
-		plugins: [ ArticlePluginSet, Table, TableToolbar, Alignment ],
+		plugins: [ ArticlePluginSet, Alignment ],
 		toolbar: [
 		toolbar: [
 			'heading', '|', 'insertTable', '|', 'bold', 'italic', 'bulletedList', 'numberedList', 'blockQuote',
 			'heading', '|', 'insertTable', '|', 'bold', 'italic', 'bulletedList', 'numberedList', 'blockQuote',
 			'alignment', '|', 'undo', 'redo'
 			'alignment', '|', 'undo', 'redo'
 		],
 		],
+		image: {
+			toolbar: [ 'imageStyle:full', 'imageStyle:side' ]
+		},
 		table: {
 		table: {
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
 			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
 		}
 		}

+ 1 - 0
packages/ckeditor5-table/tests/manual/tableblockcontent.md

@@ -6,6 +6,7 @@
     * List
     * List
     * Heading
     * Heading
     * Block Quote (with inner paragraph)
     * Block Quote (with inner paragraph)
+    * Image
 
 
 2. The third column consist blocks with text alignment.
 2. The third column consist blocks with text alignment.
     * Paragraph - should be rendered was `<p>` when alignment is set (apart from default) for single paragraph.
     * Paragraph - should be rendered was `<p>` when alignment is set (apart from default) for single paragraph.

+ 51 - 2
packages/ckeditor5-table/tests/tableediting.js

@@ -45,6 +45,7 @@ describe( 'TableEditing', () => {
 		// Table:
 		// Table:
 		expect( model.schema.isRegistered( 'table' ) ).to.be.true;
 		expect( model.schema.isRegistered( 'table' ) ).to.be.true;
 		expect( model.schema.isObject( 'table' ) ).to.be.true;
 		expect( model.schema.isObject( 'table' ) ).to.be.true;
+		expect( model.schema.isBlock( 'table' ) ).to.be.true;
 		expect( model.schema.isLimit( 'table' ) ).to.be.true;
 		expect( model.schema.isLimit( 'table' ) ).to.be.true;
 
 
 		expect( model.schema.checkChild( [ '$root' ], 'table' ) ).to.be.true;
 		expect( model.schema.checkChild( [ '$root' ], 'table' ) ).to.be.true;
@@ -74,7 +75,7 @@ describe( 'TableEditing', () => {
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], '$text' ) ).to.be.false;
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], '$text' ) ).to.be.false;
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], '$block' ) ).to.be.true;
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], '$block' ) ).to.be.true;
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], 'table' ) ).to.be.false;
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], 'table' ) ).to.be.false;
-		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], 'image' ) ).to.be.false;
+		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], 'image' ) ).to.be.true;
 	} );
 	} );
 
 
 	it( 'adds insertTable command', () => {
 	it( 'adds insertTable command', () => {
@@ -183,7 +184,7 @@ describe( 'TableEditing', () => {
 				editor.setData( '<table><tbody><tr><td><img src="sample.png"></td></tr></tbody></table>' );
 				editor.setData( '<table><tbody><tr><td><img src="sample.png"></td></tr></tbody></table>' );
 
 
 				expect( getModelData( model, { withoutSelection: true } ) )
 				expect( getModelData( model, { withoutSelection: true } ) )
-					.to.equal( '<table><tableRow><tableCell><paragraph></paragraph></tableCell></tableRow></table>' );
+					.to.equal( '<table><tableRow><tableCell><image src="sample.png"></image></tableCell></tableRow></table>' );
 			} );
 			} );
 
 
 			it( 'should convert table with media', () => {
 			it( 'should convert table with media', () => {
@@ -312,6 +313,40 @@ describe( 'TableEditing', () => {
 				] ) );
 				] ) );
 			} );
 			} );
 
 
+			it( 'should move to next cell with an image', () => {
+				setModelData( model, modelTable( [
+					[ '11[]', '<paragraph>foo</paragraph><image></image>' ]
+				] ) );
+
+				editor.editing.view.document.fire( 'keydown', domEvtDataStub );
+
+				sinon.assert.calledOnce( domEvtDataStub.preventDefault );
+				sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
+				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
+					[ '11', '<paragraph>[foo</paragraph><image></image>]' ]
+				] ) );
+			} );
+
+			it( 'should move to next cell with an blockQuote', () => {
+				model.schema.register( 'blockQuote', {
+					allowWhere: '$block',
+					allowContentOf: '$root'
+				} );
+				editor.conversion.elementToElement( { model: 'blockQuote', view: 'blockquote' } );
+
+				setModelData( model, modelTable( [
+					[ '11[]', '<blockQuote><paragraph>foo</paragraph></blockQuote>' ]
+				] ) );
+
+				editor.editing.view.document.fire( 'keydown', domEvtDataStub );
+
+				sinon.assert.calledOnce( domEvtDataStub.preventDefault );
+				sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
+				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
+					[ '11', '<blockQuote><paragraph>[foo]</paragraph></blockQuote>' ]
+				] ) );
+			} );
+
 			it( 'should listen with lower priority then its children', () => {
 			it( 'should listen with lower priority then its children', () => {
 				// Cancel TAB event.
 				// Cancel TAB event.
 				editor.keystrokes.set( 'Tab', ( data, cancel ) => cancel() );
 				editor.keystrokes.set( 'Tab', ( data, cancel ) => cancel() );
@@ -461,6 +496,20 @@ describe( 'TableEditing', () => {
 					],
 					],
 				] ) );
 				] ) );
 			} );
 			} );
+
+			it( 'should move to previous cell with an image', () => {
+				setModelData( model, modelTable( [
+					[ '<paragraph>foo</paragraph><image></image>', 'bar[]' ]
+				] ) );
+
+				editor.editing.view.document.fire( 'keydown', domEvtDataStub );
+
+				sinon.assert.calledOnce( domEvtDataStub.preventDefault );
+				sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
+				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
+					[ '<paragraph>[foo</paragraph><image></image>]', 'bar' ]
+				] ) );
+			} );
 		} );
 		} );
 	} );
 	} );
 
 

+ 37 - 1
packages/ckeditor5-table/tests/tabletoolbar.js

@@ -16,6 +16,9 @@ import View from '@ckeditor/ckeditor5-ui/src/view';
 import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import WidgetToolbarRepository from '@ckeditor/ckeditor5-widget/src/widgettoolbarrepository';
 import WidgetToolbarRepository from '@ckeditor/ckeditor5-widget/src/widgettoolbarrepository';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
+import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
+import Image from '@ckeditor/ckeditor5-image/src/image';
+import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
 
 
 describe( 'TableToolbar', () => {
 describe( 'TableToolbar', () => {
 	testUtils.createSinonSandbox();
 	testUtils.createSinonSandbox();
@@ -29,7 +32,10 @@ describe( 'TableToolbar', () => {
 
 
 			return ClassicTestEditor
 			return ClassicTestEditor
 				.create( editorElement, {
 				.create( editorElement, {
-					plugins: [ Paragraph, Table, TableToolbar, FakeButton ],
+					plugins: [ Paragraph, Image, ImageStyle, ImageToolbar, Table, TableToolbar, FakeButton ],
+					image: {
+						toolbar: [ 'imageStyle:full', 'imageStyle:side' ]
+					},
 					table: {
 					table: {
 						contentToolbar: [ 'fake_button' ]
 						contentToolbar: [ 'fake_button' ]
 					}
 					}
@@ -154,6 +160,36 @@ describe( 'TableToolbar', () => {
 				expect( balloon.visibleView ).to.equal( toolbar );
 				expect( balloon.visibleView ).to.equal( toolbar );
 			} );
 			} );
 
 
+			it( 'should not show the toolbar on ui#update when the image inside table is selected', () => {
+				setData(
+					model,
+					'<paragraph>[foo]</paragraph>' +
+					'<table><tableRow><tableCell><paragraph>foo</paragraph><image src=""></image></tableCell></tableRow></table>'
+				);
+
+				expect( balloon.visibleView ).to.be.null;
+
+				const imageToolbar = widgetToolbarRepository._toolbars.get( 'image' ).view;
+
+				model.change( writer => {
+					// Select the <tableCell><paragraph></paragraph>[<image></image>]</tableCell>
+					const nodeByPath = doc.getRoot().getNodeByPath( [ 1, 0, 0, 1 ] );
+
+					writer.setSelection( nodeByPath, 'on' );
+				} );
+
+				expect( balloon.visibleView ).to.equal( imageToolbar );
+
+				model.change( writer => {
+					// Select the <tableCell><paragraph>[]</paragraph><image></image></tableCell>
+					writer.setSelection(
+						writer.createPositionAt( doc.getRoot().getNodeByPath( [ 1, 0, 0, 0 ] ), 0 )
+					);
+				} );
+
+				expect( balloon.visibleView ).to.equal( toolbar );
+			} );
+
 			it( 'should not engage when the toolbar is in the balloon yet invisible', () => {
 			it( 'should not engage when the toolbar is in the balloon yet invisible', () => {
 				setData( model, '<table><tableRow><tableCell><paragraph>x[y]z</paragraph></tableCell></tableRow></table>' );
 				setData( model, '<table><tableRow><tableCell><paragraph>x[y]z</paragraph></tableCell></tableRow></table>' );
 
 

+ 1 - 1
packages/ckeditor5-table/theme/icons/table-column.svg

@@ -1 +1 @@
-<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g fill="#333" fill-rule="evenodd"><path d="M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z" opacity=".6"/><path d="M18 7v1H2V7h16zm0 5v1H2v-1h16z" fill-rule="nonzero" opacity=".6"/><path d="M14 1v18a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1zm-2 1H8v4h4V2zm0 6H8v4h4V8zm0 6H8v4h4v-4z"/></g></svg>
+<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z" opacity=".6"/><path d="M18 7v1H2V7h16zm0 5v1H2v-1h16z" opacity=".6"/><path d="M14 1v18a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1zm-2 1H8v4h4V2zm0 6H8v4h4V8zm0 6H8v4h4v-4z"/></g></svg>

+ 1 - 1
packages/ckeditor5-table/theme/icons/table-merge-cell.svg

@@ -1 +1 @@
-<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g fill="#333" fill-rule="evenodd"><path d="M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z" opacity=".6"/><path d="M7 2h1v16H7V2zm5 0h1v7h-1V2zm6 5v1H2V7h16zM8 12v1H2v-1h6z" fill-rule="nonzero" opacity=".6"/><path d="M7 7h12a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1zm1 2v9h10V9H8z"/></g></svg>
+<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z" opacity=".6"/><path d="M7 2h1v16H7V2zm5 0h1v7h-1V2zm6 5v1H2V7h16zM8 12v1H2v-1h6z" opacity=".6"/><path d="M7 7h12a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1zm1 2v9h10V9H8z"/></g></svg>

+ 1 - 1
packages/ckeditor5-table/theme/icons/table-row.svg

@@ -1 +1 @@
-<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g fill="#333" fill-rule="evenodd"><path d="M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z" opacity=".6"/><path d="M7 2h1v16H7V2zm5 0h1v16h-1V2z" fill-rule="nonzero" opacity=".6"/><path d="M1 6h18a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm1 2v4h4V8H2zm6 0v4h4V8H8zm6 0v4h4V8h-4z"/></g></svg>
+<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z" opacity=".6"/><path d="M7 2h1v16H7V2zm5 0h1v16h-1V2z" opacity=".6"/><path d="M1 6h18a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm1 2v4h4V8H2zm6 0v4h4V8H8zm6 0v4h4V8h-4z"/></g></svg>

+ 1 - 1
packages/ckeditor5-table/theme/icons/table.svg

@@ -1 +1 @@
-<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg"><path d="M3 6v3h4V6H3zm0 4v3h4v-3H3zm0 4v3h4v-3H3zm5 3h4v-3H8v3zm5 0h4v-3h-4v3zm4-4v-3h-4v3h4zm0-4V6h-4v3h4zm1.5 8a1.5 1.5 0 0 1-1.5 1.5H3A1.5 1.5 0 0 1 1.5 17V4c.222-.863 1.068-1.5 2-1.5h13c.932 0 1.778.637 2 1.5v13zM12 13v-3H8v3h4zm0-4V6H8v3h4z" fill="#333" fill-rule="evenodd"/></svg>
+<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M3 6v3h4V6H3zm0 4v3h4v-3H3zm0 4v3h4v-3H3zm5 3h4v-3H8v3zm5 0h4v-3h-4v3zm4-4v-3h-4v3h4zm0-4V6h-4v3h4zm1.5 8a1.5 1.5 0 0 1-1.5 1.5H3A1.5 1.5 0 0 1 1.5 17V4c.222-.863 1.068-1.5 2-1.5h13c.932 0 1.778.637 2 1.5v13zM12 13v-3H8v3h4zm0-4V6H8v3h4z"/></svg>