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

Merge branch 'master' into t/ckeditor5/1265

Kamil Piechaczek 7 лет назад
Родитель
Сommit
0763045a1f
25 измененных файлов с 1444 добавлено и 152 удалено
  1. 3 0
      packages/ckeditor5-table/.travis.yml
  2. 35 0
      packages/ckeditor5-table/CHANGELOG.md
  3. 78 0
      packages/ckeditor5-table/lang/translations/ar.po
  4. 78 0
      packages/ckeditor5-table/lang/translations/fa.po
  5. 78 0
      packages/ckeditor5-table/lang/translations/fr.po
  6. 78 0
      packages/ckeditor5-table/lang/translations/gl.po
  7. 78 0
      packages/ckeditor5-table/lang/translations/ja.po
  8. 78 0
      packages/ckeditor5-table/lang/translations/ku.po
  9. 78 0
      packages/ckeditor5-table/lang/translations/ne.po
  10. 78 0
      packages/ckeditor5-table/lang/translations/no.po
  11. 78 0
      packages/ckeditor5-table/lang/translations/pl.po
  12. 8 8
      packages/ckeditor5-table/lang/translations/pt-br.po
  13. 78 0
      packages/ckeditor5-table/lang/translations/ru.po
  14. 78 0
      packages/ckeditor5-table/lang/translations/sk.po
  15. 78 0
      packages/ckeditor5-table/lang/translations/sq.po
  16. 16 16
      packages/ckeditor5-table/package.json
  17. 112 0
      packages/ckeditor5-table/src/converters/table-cell-content-post-fixer.js
  18. 27 28
      packages/ckeditor5-table/src/converters/table-layout-post-fixer.js
  19. 75 68
      packages/ckeditor5-table/src/converters/tablecell-post-fixer.js
  20. 4 2
      packages/ckeditor5-table/src/tableediting.js
  21. 1 1
      packages/ckeditor5-table/src/tabletoolbar.js
  22. 3 1
      packages/ckeditor5-table/tests/_utils/utils.js
  23. 126 0
      packages/ckeditor5-table/tests/converters/table-cell-content-post-fixer.js
  24. 1 1
      packages/ckeditor5-table/tests/converters/table-layout-post-fixer.js
  25. 97 27
      packages/ckeditor5-table/tests/converters/tablecell-post-fixer.js

+ 3 - 0
packages/ckeditor5-table/.travis.yml

@@ -12,6 +12,9 @@ node_js:
 - '8'
 cache:
 - node_modules
+branches:
+   except:
+   - stable
 before_install:
 - export DISPLAY=:99.0
 - sh -e /etc/init.d/xvfb start

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

@@ -1,6 +1,41 @@
 Changelog
 =========
 
+## [11.0.0](https://github.com/ckeditor/ckeditor5-table/compare/v10.1.0...v11.0.0) (2018-10-08)
+
+### Features
+
+* Implemented the table post–fixer which bulletproofs the feature in various complex use–cases (e.g. pasting and real-time collaborative editing). Closes [#13](https://github.com/ckeditor/ckeditor5-table/issues/13). ([01f9a3b](https://github.com/ckeditor/ckeditor5-table/commit/01f9a3b))
+* Introduced the toolbar for the table widget (previously it was available only for single cells). Changed the toolbar configuration option from `table.toolbar` to `table.contentToolbar`. Closes [#113](https://github.com/ckeditor/ckeditor5-table/issues/113). Closes [#106](https://github.com/ckeditor/ckeditor5-table/issues/106). ([9f9486d](https://github.com/ckeditor/ckeditor5-table/commit/9f9486d))
+
+  Other: `config.table.toolbar` is marked as depracted. Use `config.table.contentToolbar` instead.
+* Introduced a support for block content inside tables. Closes [#56](https://github.com/ckeditor/ckeditor5-table/issues/56). ([cdf718e](https://github.com/ckeditor/ckeditor5-table/commit/cdf718e))
+
+### Bug fixes
+
+* A table cell should always have a `<paragraph>` in the model. Closes [#125](https://github.com/ckeditor/ckeditor5-table/issues/125). ([1eb5d6d](https://github.com/ckeditor/ckeditor5-table/commit/1eb5d6d))
+* Downcast converter for table attributes should work with not converted child elements. Closes [#92](https://github.com/ckeditor/ckeditor5-table/issues/92). ([a3ea18d](https://github.com/ckeditor/ckeditor5-table/commit/a3ea18d))
+* Merging down rowspanned cell from the head with a cell in the body is now disabled. Closes [#86](https://github.com/ckeditor/ckeditor5-table/issues/86). ([cb77e38](https://github.com/ckeditor/ckeditor5-table/commit/cb77e38))
+* The upcast conversion will now properly parse inline content in table cell into single paragraph. Closes [ckeditor/ckeditor5#1246](https://github.com/ckeditor/ckeditor5/issues/1246). ([ea1e16d](https://github.com/ckeditor/ckeditor5-table/commit/ea1e16d))
+* Toggling headers should always include the column or row the selection is anchored to. Closes [#34](https://github.com/ckeditor/ckeditor5-table/issues/34). ([bce6766](https://github.com/ckeditor/ckeditor5-table/commit/bce6766))
+
+### Other changes
+
+* Aligned `TableToolbar` to the widget toolbar repository. Closes [#107](https://github.com/ckeditor/ckeditor5-table/issues/107). ([e276e66](https://github.com/ckeditor/ckeditor5-table/commit/e276e66))
+* Media should not be allowed inside table cells for now. Closes [#124](https://github.com/ckeditor/ckeditor5-table/issues/124). ([2f2fe4a](https://github.com/ckeditor/ckeditor5-table/commit/2f2fe4a))
+* Table feature should insert table the same way as other widget features do. Closes [#27](https://github.com/ckeditor/ckeditor5-table/issues/27). ([77d96a4](https://github.com/ckeditor/ckeditor5-table/commit/77d96a4))
+* The table cell view post-fixer should use changed elements from the view to make fixes. Closes [#130](https://github.com/ckeditor/ckeditor5-table/issues/130). ([efc53c9](https://github.com/ckeditor/ckeditor5-table/commit/efc53c9))
+* Updated the table icon which used to feel bulky with a lighter design. Closes [#117](https://github.com/ckeditor/ckeditor5-table/issues/117). ([cd6f5ff](https://github.com/ckeditor/ckeditor5-table/commit/cd6f5ff))
+* Updated translations. ([de47767](https://github.com/ckeditor/ckeditor5-table/commit/de47767))
+
+### BREAKING CHANGES
+
+* The `config.table.toolbar` was renamed to `config.table.contentToolbar`.
+* The `injectTablePostFixer()` function from  `table/converters/table-post-fixer` is now `injectTableLayoutPostFixer()`and is moved to `table/converters/table-layout-post-fixer` module.
+* The `TableUtils#createTable()` method now accepts model `Writer` instance instead of `Position`. The method no longer inserts created table to the model - use returned value instead.
+* Removed `table/commands/utils~getParentTable()` method. Use `table/commands/utils~findAncestor()` instead.
+
+
 ## [10.1.0](https://github.com/ckeditor/ckeditor5-table/compare/v10.0.0...v10.1.0) (2018-07-18)
 
 ### Features

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Arabic (https://www.transifex.com/ckeditor/teams/11143/ar/)\n"
+"Language: ar\n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "إدراج جدول"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "ادراج عمود بعد"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "حذف العمود"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "عمود"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "صف عنوان"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "ادراج صف بعد"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "ادراج صف قبل"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "حذف الصف"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "صف"
+
+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 "دمج الخلايا"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Persian (https://www.transifex.com/ckeditor/teams/11143/fa/)\n"
+"Language: fa\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "درج جدول"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "درج ستون بعد"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "حذف ستون"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "ستون"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "سطر سربرگ"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "درج سطر در پایین"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "درج سطر در بالا"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "حذف سطر"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "سطر"
+
+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 "ادغام سلول ها"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: French (https://www.transifex.com/ckeditor/teams/11143/fr/)\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Insérer un tableau"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "Insérer une colonne après"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Supprimer la colonne"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Colonne"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Rangée d'entête"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Insérer une rangée en-dessous"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Insérer une rangée au-dessus"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Supprimer la rangée"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Rangée"
+
+msgctxt "Label for the merge table cell up button."
+msgid "Merge cell up"
+msgstr "Fusionner la cellule au-dessus"
+
+msgctxt "Label for the merge table cell right button."
+msgid "Merge cell right"
+msgstr "Fusionner la cellule à droite"
+
+msgctxt "Label for the merge table cell down button."
+msgid "Merge cell down"
+msgstr "Fusionner la cellule en-dessous"
+
+msgctxt "Label for the merge table cell left button."
+msgid "Merge cell left"
+msgstr "Fusionner la cellule à gauche"
+
+msgctxt "Label for the split table cell vertically button."
+msgid "Split cell vertically"
+msgstr "Séparer la cellule verticalement"
+
+msgctxt "Label for the split table cell horizontally button."
+msgid "Split cell horizontally"
+msgstr "Séparer la cellule horizontalement"
+
+msgctxt "Label for the merge table cells button."
+msgid "Merge cells"
+msgstr "Fusionner les cellules"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Galician (https://www.transifex.com/ckeditor/teams/11143/gl/)\n"
+"Language: gl\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Inserir táboa"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+msgstr "Cabeceira de columna"
+
+msgctxt "Label for the insert table column before the current one button."
+msgid "Insert column before"
+msgstr "Inserir columna á esquerda"
+
+msgctxt "Label for the insert table column after the current one button."
+msgid "Insert column after"
+msgstr "Inserir columna á dereita"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Eliminar columna"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Columna"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Cabeceira de fila"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Inserir fila embaixo"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Inserir fila enriba"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Eliminar fila"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Fila"
+
+msgctxt "Label for the merge table cell up button."
+msgid "Merge cell up"
+msgstr "Combinar cela cara arriba"
+
+msgctxt "Label for the merge table cell right button."
+msgid "Merge cell right"
+msgstr "Combinar cela cara a dereita"
+
+msgctxt "Label for the merge table cell down button."
+msgid "Merge cell down"
+msgstr "Combinar cela cara  abaixo"
+
+msgctxt "Label for the merge table cell left button."
+msgid "Merge cell left"
+msgstr "Combinar cela cara a esquerda"
+
+msgctxt "Label for the split table cell vertically button."
+msgid "Split cell vertically"
+msgstr "Dividir cela en vertical"
+
+msgctxt "Label for the split table cell horizontally button."
+msgid "Split cell horizontally"
+msgstr "Dividir cela en horizontal"
+
+msgctxt "Label for the merge table cells button."
+msgid "Merge cells"
+msgstr "Combinar celas"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Japanese (https://www.transifex.com/ckeditor/teams/11143/ja/)\n"
+"Language: ja\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "表の挿入"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "\b右に列を挿入"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "列を削除"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "列"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "見出し行"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "下に行を挿入"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "上に行を挿入"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "行を削除"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "行"
+
+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 "セルを結合"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Kurdish (https://www.transifex.com/ckeditor/teams/11143/ku/)\n"
+"Language: ku\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "خشتە دابنێ"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "لەدووا دانانی ستوون"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "سڕینەوەی ستوون"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "ستوون"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "ڕیزی دەسپێک"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "دانانی ڕیز لە ژێرەوە"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "دانانی ڕیز لە سەرەوە"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "سڕینەوەی ڕیز"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "ڕیز"
+
+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 "تێکەڵکردنی خانەکان"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Nepali (Nepal) (https://www.transifex.com/ckeditor/teams/11143/ne_NP/)\n"
+"Language: ne_NP\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "तालिका सम्मिलित गर्नुहोस्"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "पछि स्तम्भ सम्मिलित गर्नुहोस्"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "स्तम्भ मेटाउनुहोस्"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "स्तम्भ"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "हेडर पङ्क्ति"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "तल पंक्ति सम्मिलित गर्नुहोस्"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "माथि पंक्ति सम्मिलित गर्नुहोस्"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "पङ्क्ति मेटाउनुहोस्"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "पङ्क्ति"
+
+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 "कक्ष मर्ज गर्नुहोस्"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Norwegian (https://www.transifex.com/ckeditor/teams/11143/no/)\n"
+"Language: no\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Sett inn tabell"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "Sett inn kolonne etter"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Slett kolonne"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Kolonne"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Overskriftrad"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Sett inn rad under"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Sett inn rad over"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Slett rad"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Rad"
+
+msgctxt "Label for the merge table cell up button."
+msgid "Merge cell up"
+msgstr "Slå sammen celle over"
+
+msgctxt "Label for the merge table cell right button."
+msgid "Merge cell right"
+msgstr "Slå sammen celle til høyre"
+
+msgctxt "Label for the merge table cell down button."
+msgid "Merge cell down"
+msgstr "Slå sammen celle under"
+
+msgctxt "Label for the merge table cell left button."
+msgid "Merge cell left"
+msgstr "Slå sammen celle til venstre"
+
+msgctxt "Label for the split table cell vertically button."
+msgid "Split cell vertically"
+msgstr "Del opp celle vertikalt"
+
+msgctxt "Label for the split table cell horizontally button."
+msgid "Split cell horizontally"
+msgstr "Del opp celle horisontalt"
+
+msgctxt "Label for the merge table cells button."
+msgid "Merge cells"
+msgstr "Slå sammen celler"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Polish (https://www.transifex.com/ckeditor/teams/11143/pl/)\n"
+"Language: pl\n"
+"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Wstaw tabelę"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "Wstaw kolumnę po"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Usuń kolumnę"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Kolumna"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Wiersz nagłówka"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Wstaw wiersz poniżej"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Wstaw wiersz ponad"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Usuń wiersz"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Wiersz"
+
+msgctxt "Label for the merge table cell up button."
+msgid "Merge cell up"
+msgstr "Scal komórkę w górę"
+
+msgctxt "Label for the merge table cell right button."
+msgid "Merge cell right"
+msgstr "Scal komórkę w prawo"
+
+msgctxt "Label for the merge table cell down button."
+msgid "Merge cell down"
+msgstr "Scal komórkę w dół"
+
+msgctxt "Label for the merge table cell left button."
+msgid "Merge cell left"
+msgstr "Scal komórkę w lewo"
+
+msgctxt "Label for the split table cell vertically button."
+msgid "Split cell vertically"
+msgstr "Podziel komórkę pionowo"
+
+msgctxt "Label for the split table cell horizontally button."
+msgid "Split cell horizontally"
+msgstr "Podziel komórkę poziomo"
+
+msgctxt "Label for the merge table cells button."
+msgid "Merge cells"
+msgstr "Scal komórki"

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

@@ -11,7 +11,7 @@ msgstr "Inserir tabela"
 
 msgctxt "Label for the set/unset table header column button."
 msgid "Header column"
-msgstr ""
+msgstr "Coluna de cabeçalho"
 
 msgctxt "Label for the insert table column before the current one button."
 msgid "Insert column before"
@@ -31,7 +31,7 @@ msgstr "Coluna"
 
 msgctxt "Label for the set/unset table header row button."
 msgid "Header row"
-msgstr ""
+msgstr "Linha de cabeçalho"
 
 msgctxt "Label for the insert row below button."
 msgid "Insert row below"
@@ -51,27 +51,27 @@ msgstr "Linha"
 
 msgctxt "Label for the merge table cell up button."
 msgid "Merge cell up"
-msgstr ""
+msgstr "Mesclar acima"
 
 msgctxt "Label for the merge table cell right button."
 msgid "Merge cell right"
-msgstr ""
+msgstr "Mesclar à direita"
 
 msgctxt "Label for the merge table cell down button."
 msgid "Merge cell down"
-msgstr ""
+msgstr "Mesclar abaixo"
 
 msgctxt "Label for the merge table cell left button."
 msgid "Merge cell left"
-msgstr ""
+msgstr "Mesclar à esquerda"
 
 msgctxt "Label for the split table cell vertically button."
 msgid "Split cell vertically"
-msgstr ""
+msgstr "Dividir verticalmente"
 
 msgctxt "Label for the split table cell horizontally button."
 msgid "Split cell horizontally"
-msgstr ""
+msgstr "Dividir horizontalmente"
 
 msgctxt "Label for the merge table cells button."
 msgid "Merge cells"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Russian (https://www.transifex.com/ckeditor/teams/11143/ru/)\n"
+"Language: ru\n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Вставить таблицу"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "Вставить столбец правее"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Удалить столбец"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Столбец"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Строка заголовков"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Вставить строку выше"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Вставить строку ниже"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Удалить строку"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Строка"
+
+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 "Объединить ячейки"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Slovak (https://www.transifex.com/ckeditor/teams/11143/sk/)\n"
+"Language: sk\n"
+"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Vložiť tabuľku"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "Vložiť stĺpec vpravo"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Odstrániť stĺpec"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Stĺpec"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Riadok hlavičky"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Vložiť riadok pod"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Vložiť riadok nad"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Odstrániť riadok"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Riadok"
+
+msgctxt "Label for the merge table cell up button."
+msgid "Merge cell up"
+msgstr "Zlúčiť bunku hore"
+
+msgctxt "Label for the merge table cell right button."
+msgid "Merge cell right"
+msgstr "Zlúčiť bunku vpravo"
+
+msgctxt "Label for the merge table cell down button."
+msgid "Merge cell down"
+msgstr "Zlúčiť bunku dole"
+
+msgctxt "Label for the merge table cell left button."
+msgid "Merge cell left"
+msgstr "Zlúčiť bunku vľavo"
+
+msgctxt "Label for the split table cell vertically button."
+msgid "Split cell vertically"
+msgstr "Rozdeliť bunku zvislo"
+
+msgctxt "Label for the split table cell horizontally button."
+msgid "Split cell horizontally"
+msgstr "Rozdeliť bunku vodorovne"
+
+msgctxt "Label for the merge table cells button."
+msgid "Merge cells"
+msgstr "Zlúčiť bunky"

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

@@ -0,0 +1,78 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Albanian (https://www.transifex.com/ckeditor/teams/11143/sq/)\n"
+"Language: sq\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the insert table toolbar button."
+msgid "Insert table"
+msgstr "Shto tabelë"
+
+msgctxt "Label for the set/unset table header column button."
+msgid "Header column"
+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 after the current one button."
+msgid "Insert column after"
+msgstr "Shto kolonë pas"
+
+msgctxt "Label for the delete table column button."
+msgid "Delete column"
+msgstr "Gris kolonën"
+
+msgctxt "Label for the table column dropdown button."
+msgid "Column"
+msgstr "Kolona"
+
+msgctxt "Label for the set/unset table header row button."
+msgid "Header row"
+msgstr "Rreshti i kokës"
+
+msgctxt "Label for the insert row below button."
+msgid "Insert row below"
+msgstr "Shto rresht poshtë"
+
+msgctxt "Label for the insert row above button."
+msgid "Insert row above"
+msgstr "Shto rresht sipër"
+
+msgctxt "Label for the delete table row button."
+msgid "Delete row"
+msgstr "Grish rreshtin"
+
+msgctxt "Label for the table row dropdown button."
+msgid "Row"
+msgstr "Rreshti"
+
+msgctxt "Label for the merge table cell up button."
+msgid "Merge cell up"
+msgstr "Bashko kutizat sipër"
+
+msgctxt "Label for the merge table cell right button."
+msgid "Merge cell right"
+msgstr "Bashko kutizat djathtas"
+
+msgctxt "Label for the merge table cell down button."
+msgid "Merge cell down"
+msgstr "Bashko kutizat poshtë"
+
+msgctxt "Label for the merge table cell left button."
+msgid "Merge cell left"
+msgstr "Bashko kutizat majtas"
+
+msgctxt "Label for the split table cell vertically button."
+msgid "Split cell vertically"
+msgstr "Ndajë kutizat vertikalisht"
+
+msgctxt "Label for the split table cell horizontally button."
+msgid "Split cell horizontally"
+msgstr "Ndaj kutizat horizontalisht"
+
+msgctxt "Label for the merge table cells button."
+msgid "Merge cells"
+msgstr "Bashko kutizat"

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

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-table",
-  "version": "10.1.0",
+  "version": "11.0.0",
   "description": "Table feature for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -10,23 +10,23 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^11.0.0",
-    "@ckeditor/ckeditor5-engine": "^10.2.0",
-    "@ckeditor/ckeditor5-ui": "^11.0.0",
-    "@ckeditor/ckeditor5-widget": "^10.2.0"
+    "@ckeditor/ckeditor5-core": "^11.0.1",
+    "@ckeditor/ckeditor5-engine": "^11.0.0",
+    "@ckeditor/ckeditor5-ui": "^11.1.0",
+    "@ckeditor/ckeditor5-widget": "^10.3.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-alignment": "^10.0.2",
-    "@ckeditor/ckeditor5-block-quote": "^10.0.2",
-    "@ckeditor/ckeditor5-clipboard": "^10.0.2",
-    "@ckeditor/ckeditor5-editor-classic": "^11.0.0",
-    "@ckeditor/ckeditor5-image": "^10.2.0",
-    "@ckeditor/ckeditor5-list": "^11.0.1",
-    "@ckeditor/ckeditor5-media-embed": "^0.0.1",
-    "@ckeditor/ckeditor5-paragraph": "^10.0.2",
-    "@ckeditor/ckeditor5-typing": "^11.0.0",
-    "@ckeditor/ckeditor5-undo": "^10.0.2",
-    "@ckeditor/ckeditor5-utils": "^10.2.0",
+    "@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",
     "eslint": "^5.5.0",
     "eslint-config-ckeditor5": "^1.0.7",
     "husky": "^0.14.3",

+ 112 - 0
packages/ckeditor5-table/src/converters/table-cell-content-post-fixer.js

@@ -0,0 +1,112 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module table/converters/table-cell-content-post-fixer
+ */
+
+/**
+ * Injects a table cell post-fixer into the model.
+ *
+ * The role of the table post-fixer is to ensure that the table cells have the correct content
+ * after a {@link module:engine/model/model~Model#change `change()`} block was executed.
+ *
+ * A table cells must contains at least one block as a child. The empty table cell will have empty `<paragraph>` as a child.
+ *
+ *        <table>
+ *            <tableRow>
+ *                <tableCell></tableCell>
+ *            </tableRow>
+ *        </table>
+ *
+ * Will be fixed to:
+ *
+ *        <table>
+ *            <tableRow>
+ *                <tableCell><paragraph></paragraph></tableCell>
+ *            </tableRow>
+ *        </table>
+ *
+ * @param {module:engine/model/model~Model} model
+ */
+export default function injectTableCellContentPostFixer( model ) {
+	model.document.registerPostFixer( writer => tableCellContentsPostFixer( writer, model ) );
+}
+
+// The table cell contents post-fixer.
+//
+// @param {module:engine/model/writer~Writer} writer
+// @param {module:engine/model/model~Model} model
+function tableCellContentsPostFixer( writer, model ) {
+	const changes = model.document.differ.getChanges();
+
+	let wasFixed = false;
+
+	for ( const entry of changes ) {
+		// Enforce paragraph in tableCell even after other feature remove its contents.
+		if ( entry.type == 'remove' && entry.position.parent.is( 'tableCell' ) ) {
+			wasFixed = fixTableCellContent( entry.position.parent, writer ) || wasFixed;
+		}
+
+		// Analyze table cells on insertion.
+		if ( entry.type == 'insert' ) {
+			if ( entry.name == 'table' ) {
+				wasFixed = fixTable( entry.position.nodeAfter, writer ) || wasFixed;
+			}
+
+			if ( entry.name == 'tableRow' ) {
+				wasFixed = fixTableRow( entry.position.nodeAfter, writer ) || wasFixed;
+			}
+
+			if ( entry.name == 'tableCell' ) {
+				wasFixed = fixTableCellContent( entry.position.nodeAfter, writer ) || wasFixed;
+			}
+		}
+	}
+
+	return wasFixed;
+}
+
+// Fixes all table cells in a table.
+//
+// @param {module:engine/model/element~Element} table
+// @param {module:engine/model/writer~Writer} writer
+function fixTable( table, writer ) {
+	let wasFixed = false;
+
+	for ( const row of table.getChildren() ) {
+		wasFixed = fixTableRow( row, writer ) || wasFixed;
+	}
+
+	return wasFixed;
+}
+
+// Fixes all table cells in a table row.
+//
+// @param {module:engine/model/element~Element} tableRow
+// @param {module:engine/model/writer~Writer} writer
+function fixTableRow( tableRow, writer ) {
+	let wasFixed = false;
+
+	for ( const tableCell of tableRow.getChildren() ) {
+		wasFixed = fixTableCellContent( tableCell, writer ) || wasFixed;
+	}
+
+	return wasFixed;
+}
+
+// Fixes all table cell content by adding paragraph to a table cell without any child.
+//
+// @param {module:engine/model/element~Element} table
+// @param {module:engine/model/writer~Writer} writer
+function fixTableCellContent( tableCell, writer ) {
+	if ( tableCell.childCount == 0 ) {
+		writer.insertElement( 'paragraph', tableCell );
+
+		return true;
+	}
+
+	return false;
+}

+ 27 - 28
packages/ckeditor5-table/src/converters/table-post-fixer.js → packages/ckeditor5-table/src/converters/table-layout-post-fixer.js

@@ -4,7 +4,7 @@
  */
 
 /**
- * @module table/converters/table-post-fixer
+ * @module table/converters/table-layout-post-fixer
  */
 
 import Position from '@ckeditor/ckeditor5-engine/src/model/position';
@@ -12,15 +12,16 @@ import { createEmptyTableCell, findAncestor, updateNumericAttribute } from './..
 import TableWalker from './../tablewalker';
 
 /**
- * Injects a table post-fixer into the model.
+ * Injects a table layout post-fixer into the model.
  *
- * The role of the table post-fixer is to ensure that the table rows have the correct structure
+ * The role of the table layout post-fixer is to ensure that the table rows have the correct structure
  * after a {@link module:engine/model/model~Model#change `change()`} block was executed.
  *
  * The correct structure means that:
  *
  * * All table rows have the same size.
  * * None of a table cells that extend vertically beyond their section (either header or body).
+ * * A table cell has always at least one element as child.
  *
  * If the table structure is not correct, the post-fixer will automatically correct it in two steps:
  *
@@ -35,12 +36,12 @@ import TableWalker from './../tablewalker';
  *
  *		<table headingRows="1">
  *			<tableRow>
- *				<tableCell rowspan="2">FOO</tableCell>
- *				<tableCell colspan="2">BAR</tableCell>
+ *				<tableCell rowspan="2"><paragraph>FOO</paragraph></tableCell>
+ *				<tableCell colspan="2"><paragraph>BAR</paragraph></tableCell>
  *			</tableRow>
  *			<tableRow>
- *				<tableCell>BAZ</tableCell>
- *				<tableCell>XYZ</tableCell>
+ *				<tableCell><paragraph>BAZ</paragraph></tableCell>
+ *				<tableCell><paragraph>XYZ</paragraph></tableCell>
  *			</tableRow>
  *		</table>
  *
@@ -55,8 +56,8 @@ import TableWalker from './../tablewalker';
  *			</thead>
  *			<tbody>
  *				<tr>
- *					<td>BAZ<td>
- *					<td>XYZ<td>
+ *					<td>BAZ</td>
+ *					<td>XYZ</td>
  *				</tr>
  *			</tbody>
  *		</table>
@@ -90,8 +91,8 @@ import TableWalker from './../tablewalker';
  *			</thead>
  *			<tbody>
  *				<tr>
- *					<td>BAZ<td>
- *					<td>XYZ<td>
+ *					<td>BAZ</td>
+ *					<td>XYZ</td>
  *				</tr>
  *			</tbody>
  *		</table>
@@ -113,8 +114,8 @@ import TableWalker from './../tablewalker';
  *					<td>12</td>
  *				</tr>
  *				<tr>
- *					<td>21<td>
- *					<td>22<td>
+ *					<td>21</td>
+ *					<td>22</td>
  *				</tr>
  *			</tbody>
  *		</table>
@@ -156,8 +157,8 @@ import TableWalker from './../tablewalker';
  *					<td>(empty, inserted by A)</td>
  *				</tr>
  *				<tr>
- *					<td>21<td>
- *					<td>22<td>
+ *					<td>21</td>
+ *					<td>22</td>
  *					<td>(empty, inserted by A)</td>
  *				</tr>
  *				<tr>
@@ -197,32 +198,31 @@ import TableWalker from './../tablewalker';
  *				<tr>
  *					<td>11</td>
  *					<td>12</td>
- *					<td>(empty, inserted by a post-fixer after undo)<td>
+ *					<td>(empty, inserted by a post-fixer after undo)</td>
  *				</tr>
  *				<tr>
- *					<td>21<td>
- *					<td>22<td>
- *					<td>(empty, inserted by a post-fixer after undo)<td>
+ *					<td>21</td>
+ *					<td>22</td>
+ *					<td>(empty, inserted by a post-fixer after undo)</td>
  *				</tr>
  *				<tr>
- *					<td>(empty, inserted by B)<td>
- *					<td>(empty, inserted by B)<td>
- *					<td>(empty, inserted by a post-fixer)<td>
+ *					<td>(empty, inserted by B)</td>
+ *					<td>(empty, inserted by B)</td>
+ *					<td>(empty, inserted by a post-fixer)</td>
  *				</tr>
  *			</tbody>
  *		</table>
- *
  * @param {module:engine/model/model~Model} model
  */
-export default function injectTablePostFixer( model ) {
-	model.document.registerPostFixer( writer => tablePostFixer( writer, model ) );
+export default function injectTableLayoutPostFixer( model ) {
+	model.document.registerPostFixer( writer => tableLayoutPostFixer( writer, model ) );
 }
 
-// The table post-fixer.
+// The table layout post-fixer.
 //
 // @param {module:engine/model/writer~Writer} writer
 // @param {module:engine/model/model~Model} model
-function tablePostFixer( writer, model ) {
+function tableLayoutPostFixer( writer, model ) {
 	const changes = model.document.differ.getChanges();
 
 	let wasFixed = false;
@@ -233,7 +233,6 @@ function tablePostFixer( writer, model ) {
 	for ( const entry of changes ) {
 		let table;
 
-		// Fix table on table insert.
 		if ( entry.name == 'table' && entry.type == 'insert' ) {
 			table = entry.position.nodeAfter;
 		}

+ 75 - 68
packages/ckeditor5-table/src/converters/tablecell-post-fixer.js

@@ -71,7 +71,7 @@
  * @param {module:engine/controller/editingcontroller~EditingController} editing
  */
 export default function injectTableCellPostFixer( model, editing ) {
-	editing.view.document.registerPostFixer( writer => tableCellPostFixer( writer, model, editing.mapper ) );
+	editing.view.document.registerPostFixer( writer => tableCellPostFixer( writer, model, editing.mapper, editing.view ) );
 }
 
 // The table cell post-fixer.
@@ -79,94 +79,101 @@ export default function injectTableCellPostFixer( model, editing ) {
 // @param {module:engine/view/writer~Writer} writer
 // @param {module:engine/model/model~Model} model
 // @param {module:engine/conversion/mapper~Mapper} mapper
-function tableCellPostFixer( writer, model, mapper ) {
-	const changes = model.document.differ.getChanges();
+function tableCellPostFixer( writer, model, mapper, view ) {
 	let wasFixed = false;
 
-	// While this is view post fixer only nodes that changed are worth investigating.
-	for ( const entry of changes ) {
-		// Attribute change - check if it is single paragraph inside table cell that has attributes changed.
-		if ( entry.type == 'attribute' && entry.range.start.parent.name == 'tableCell' ) {
-			const tableCell = entry.range.start.parent;
-
-			if ( tableCell.childCount === 1 ) {
-				const singleChild = tableCell.getChild( 0 );
-				const renameTo = Array.from( singleChild.getAttributes() ).length ? 'p' : 'span';
-
-				wasFixed = renameParagraphIfDifferent( singleChild, renameTo, writer, model, mapper ) || wasFixed;
-			}
-		} else {
-			// Check all nodes inside table cell on insert/remove operations (also other blocks).
-			const parent = entry.position && entry.position.parent;
-
-			if ( parent && parent.is( 'tableCell' ) ) {
-				const renameTo = parent.childCount > 1 ? 'p' : 'span';
-
-				for ( const child of parent.getChildren() ) {
-					wasFixed = renameParagraphIfDifferent( child, renameTo, writer, model, mapper ) || wasFixed;
-				}
-			}
-		}
+	const elementsToCheck = getElementsToCheck( view );
+
+	for ( const element of elementsToCheck ) {
+		wasFixed = ensureProperElementName( element, mapper, writer ) || wasFixed;
+	}
+
+	// Selection in the view might not be updated to renamed elements. Happens mostly when other feature inserts paragraph to the table cell
+	// (ie. when deleting table cell contents) and sets selection to it while table-post fixer changes view <p> to <span> element.
+	// The view.selection would have outdated nodes.
+	if ( wasFixed ) {
+		updateRangesInViewSelection( model.document.selection, mapper, writer );
 	}
 
 	return wasFixed;
 }
 
-// Renames associated view element to a desired one. It will only rename if:
-// - model element is a paragraph
-// - view element is converted (mapped)
-// - view element has different name then requested.
+// Returns view elements changed in current view.change() block.
 //
-// @param {module:engine/model/element~Element} modelElement
-// @param {String} desiredElementName
-// @param {module:engine/view/writer~Writer} writer
-// @param {module:engine/model/model~Model} model
-// @param {module:engine/conversion/mapper~Mapper} mapper
-function renameParagraphIfDifferent( modelElement, desiredElementName, writer, model, mapper ) {
-	// Only rename paragraph elements.
-	if ( !modelElement.is( 'paragraph' ) ) {
-		return false;
-	}
+// **Note**: Currently it uses private property of the view: _renderer to get changed view elements to check.
+//
+// @param {module:engine/view/view~View} view
+function getElementsToCheck( view ) {
+	const elementsWithChangedAttributes = Array.from( view._renderer.markedAttributes )
+		.filter( el => !!el.parent )
+		.filter( isSpanOrP )
+		.filter( el => isTdOrTh( el.parent ) );
+
+	const changedChildren = Array.from( view._renderer.markedChildren )
+		.filter( el => !!el.parent )
+		.filter( isTdOrTh )
+		.reduce( ( prev, element ) => {
+			const childrenToCheck = Array.from( element.getChildren() ).filter( isSpanOrP );
+
+			return [ ...prev, ...childrenToCheck ];
+		}, [] );
+
+	return [ ...elementsWithChangedAttributes, ...changedChildren ];
+}
 
-	const viewElement = mapper.toViewElement( modelElement );
+// This method checks if view element for model's <paragraph> was properly converter.
+// Paragraph should be either
+// - span: for single paragraph with no attributes.
+// - p   : in other cases.
+function ensureProperElementName( currentViewElement, mapper, writer ) {
+	const modelParagraph = mapper.toModelElement( currentViewElement );
+	const expectedViewElementName = getExpectedElementName( modelParagraph.parent, modelParagraph );
 
-	// Only rename converted elements which aren't desired ones.
-	if ( !viewElement || viewElement.name === desiredElementName ) {
-		return false;
-	}
+	if ( currentViewElement.name !== expectedViewElementName ) {
+		// Unbind current view element as it should be cleared from mapper.
+		mapper.unbindViewElement( currentViewElement );
 
-	// After renaming element in the view by a post-fixer the selection would have references to the previous element.
-	const selection = model.document.selection;
-	const shouldFixSelection = checkSelectionForRenamedElement( selection, modelElement );
+		const renamedViewElement = writer.rename( expectedViewElementName, currentViewElement );
 
-	// Unbind current view element as it should be cleared from mapper.
-	mapper.unbindViewElement( viewElement );
-	const renamedViewElement = writer.rename( desiredElementName, viewElement );
-	// Bind paragraph inside table cell to the renamed view element.
-	mapper.bindElements( modelElement, renamedViewElement );
+		// Bind paragraph inside table cell to the renamed view element.
+		mapper.bindElements( modelParagraph, renamedViewElement );
 
-	if ( shouldFixSelection ) {
-		// Re-create view selection based on model selection.
-		updateRangesInViewSelection( selection, mapper, writer );
+		return true;
 	}
 
-	return true;
+	return false;
 }
 
-// Checks if model selection contains renamed element.
+// Expected view element name depends on model elements:
+// - <paragraph> with any attribute set should be rendered as <p>
+// - all <paragraphs> in <tableCell> that has more then one children should be rendered as <p>
+// - an only <paragraph> child with no attributes should be rendered as <span>
 //
-// @param {module:engine/model/selection~Selection} selection
-// @param {module:engine/model/element~Element} modelElement
-// @returns {boolean}
-function checkSelectionForRenamedElement( selection, modelElement ) {
-	return !![ ...selection.getSelectedBlocks() ].find( block => block === modelElement );
+// @param {module:engine/model/element~Element} tableCell
+// @param {module:engine/model/element~Element} paragraph
+// @returns {String}
+function getExpectedElementName( tableCell, paragraph ) {
+	const isOnlyChild = tableCell.childCount > 1;
+	const hasAttributes = !![ ...paragraph.getAttributes() ].length;
+
+	return ( isOnlyChild || hasAttributes ) ? 'p' : 'span';
 }
 
-// Re-create view selection from model selection.
+// Method to filter out <span> and <p> elements.
 //
-// @param {module:engine/model/selection~Selection} selection
-// @param {module:engine/view/writer~Writer} writer
-// @param {module:engine/conversion/mapper~Mapper} mapper
+// @param {module:engine/view/element~Element} element
+function isSpanOrP( element ) {
+	return element.is( 'p' ) || element.is( 'span' );
+}
+
+// Method to filter out <td> and <th> elements.
+//
+// @param {module:engine/view/element~Element} element
+function isTdOrTh( element ) {
+	return element.is( 'td' ) || element.is( 'th' );
+}
+
+// Resets view selections based on model selection.
 function updateRangesInViewSelection( selection, mapper, writer ) {
 	const fixedRanges = Array.from( selection.getRanges() )
 		.map( range => mapper.toViewRange( range ) );

+ 4 - 2
packages/ckeditor5-table/src/tableediting.js

@@ -33,7 +33,8 @@ import SetHeaderColumnCommand from './commands/setheadercolumncommand';
 import { findAncestor } from './commands/utils';
 import TableUtils from '../src/tableutils';
 
-import injectTablePostFixer from './converters/table-post-fixer';
+import injectTableLayoutPostFixer from './converters/table-layout-post-fixer';
+import injectTableCellContentsPostFixer from './converters/table-cell-content-post-fixer';
 import injectTableCellPostFixer from './converters/tablecell-post-fixer';
 
 import '../theme/tableediting.css';
@@ -145,7 +146,8 @@ export default class TableEditing extends Plugin {
 		editor.commands.add( 'setTableColumnHeader', new SetHeaderColumnCommand( editor ) );
 		editor.commands.add( 'setTableRowHeader', new SetHeaderRowCommand( editor ) );
 
-		injectTablePostFixer( model );
+		injectTableLayoutPostFixer( model );
+		injectTableCellContentsPostFixer( model );
 
 		// Handle tab key navigation.
 		this.editor.keystrokes.set( 'Tab', ( ...args ) => this._handleTabOnSelectedTable( ...args ), { priority: 'low' } );

+ 1 - 1
packages/ckeditor5-table/src/tabletoolbar.js

@@ -79,7 +79,7 @@ export default class TableToolbar extends Plugin {
 /**
  * Items to be placed in the table content toolbar.
  *
- * **Note:** This is a deprecated configuration option! Use {@link module:table/table~TableConfig#contentToolbar} instead.
+ * **Note:** This configuration option is deprecated! Use {@link module:table/table~TableConfig#contentToolbar} instead.
  *
  * Read more about configuring toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.
  *

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

@@ -15,6 +15,8 @@ import {
 } from '../../src/converters/downcast';
 import upcastTable, { upcastTableCell } from '../../src/converters/upcasttable';
 
+const WIDGET_TABLE_CELL_CLASS = 'ck-editor__editable ck-editor__nested-editable';
+
 /**
  * Returns a model representation of a table shorthand notation:
  *
@@ -264,7 +266,7 @@ function makeRows( tableData, options ) {
 				const attributes = isObject ? tableCellData : {};
 
 				if ( asWidget ) {
-					attributes.class = 'ck-editor__editable ck-editor__nested-editable';
+					attributes.class = WIDGET_TABLE_CELL_CLASS + ( attributes.class ? ` ${ attributes.class }` : '' );
 					attributes.contenteditable = 'true';
 				}
 

+ 126 - 0
packages/ckeditor5-table/tests/converters/table-cell-content-post-fixer.js

@@ -0,0 +1,126 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import Range from '@ckeditor/ckeditor5-engine/src/model/range';
+import Position from '@ckeditor/ckeditor5-engine/src/model/position';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
+import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+
+import TableEditing from '../../src/tableediting';
+import { formatTable } from './../_utils/utils';
+import UndoEditing from '@ckeditor/ckeditor5-undo/src/undoediting';
+
+describe( 'Table cell content post-fixer', () => {
+	let editor, model, root;
+
+	beforeEach( () => {
+		return VirtualTestEditor
+			.create( {
+				plugins: [ TableEditing, Paragraph, UndoEditing ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				root = model.document.getRoot();
+			} );
+	} );
+
+	afterEach( () => {
+		editor.destroy();
+	} );
+
+	it( 'should add a paragraph to an empty table cell (on table insert)', () => {
+		setModelData( model,
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		);
+
+		expect( formatTable( getModelData( model, { withoutSelection: true } ) ) ).to.equal( formatTable(
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		) );
+	} );
+
+	it( 'should add a paragraph to an empty table cell (on row insert)', () => {
+		setModelData( model,
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		);
+
+		// Insert table row with one table cell
+		model.change( writer => {
+			writer.insertElement( 'tableRow', Position.createAfter( root.getNodeByPath( [ 0, 0 ] ) ) );
+			writer.insertElement( 'tableCell', Position.createAt( root.getNodeByPath( [ 0, 1 ] ) ) );
+		} );
+
+		expect( formatTable( getModelData( model, { withoutSelection: true } ) ) ).to.equal( formatTable(
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+				'</tableRow>' +
+				'<tableRow>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		) );
+	} );
+
+	it( 'should add a paragraph to an empty table cell (on table cell insert)', () => {
+		setModelData( model,
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		);
+
+		// Insert table row with one table cell
+		model.change( writer => {
+			writer.insertElement( 'tableCell', Position.createAt( root.getNodeByPath( [ 0, 0 ], 'end' ) ) );
+		} );
+
+		expect( formatTable( getModelData( model, { withoutSelection: true } ) ) ).to.equal( formatTable(
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		) );
+	} );
+
+	it( 'should add a paragraph to an empty table cell (after remove)', () => {
+		setModelData( model,
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell><paragraph>foo</paragraph></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		);
+
+		// Remove paragraph from table cell.
+		model.change( writer => {
+			writer.remove( Range.createIn( root.getNodeByPath( [ 0, 0, 0 ] ) ) );
+		} );
+
+		expect( formatTable( getModelData( model, { withoutSelection: true } ) ) ).to.equal( formatTable(
+			'<table>' +
+				'<tableRow>' +
+					'<tableCell><paragraph></paragraph></tableCell>' +
+				'</tableRow>' +
+			'</table>'
+		) );
+	} );
+} );

+ 1 - 1
packages/ckeditor5-table/tests/converters/table-post-fixer.js → packages/ckeditor5-table/tests/converters/table-layout-post-fixer.js

@@ -12,7 +12,7 @@ import TableEditing from '../../src/tableediting';
 import { formatTable, formattedModelTable, modelTable } from './../_utils/utils';
 import UndoEditing from '@ckeditor/ckeditor5-undo/src/undoediting';
 
-describe( 'Table post-fixer', () => {
+describe( 'Table layout post-fixer', () => {
 	let editor, model, root;
 
 	beforeEach( () => {

+ 97 - 27
packages/ckeditor5-table/tests/converters/tablecell-post-fixer.js

@@ -3,32 +3,38 @@
  * For licensing, see LICENSE.md.
  */
 
-import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
+/* globals document */
+
 import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
-import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
-import { defaultConversion, defaultSchema, formatTable, formattedViewTable, modelTable } from '../_utils/utils';
+import { defaultConversion, defaultSchema, formatTable, formattedViewTable, viewTable } from '../_utils/utils';
 import injectTableCellPostFixer from '../../src/converters/tablecell-post-fixer';
+import Range from '@ckeditor/ckeditor5-engine/src/model/range';
 
 import env from '@ckeditor/ckeditor5-utils/src/env';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
+import Position from '@ckeditor/ckeditor5-engine/src/model/position';
+import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
 
 describe( 'TableCell post-fixer', () => {
-	let editor, model, doc, root, viewDocument;
+	let editor, model, doc, root, view;
 
 	testUtils.createSinonSandbox();
 
 	beforeEach( () => {
+		const element = document.createElement( 'div' );
+		document.body.appendChild( element );
+
 		// Most tests assume non-edge environment but we do not set `contenteditable=false` on Edge so stub `env.isEdge`.
 		testUtils.sinon.stub( env, 'isEdge' ).get( () => false );
 
-		return VirtualTestEditor.create()
+		return ClassicTestEditor.create( element )
 			.then( newEditor => {
 				editor = newEditor;
 				model = editor.model;
 				doc = model.document;
 				root = doc.getRoot( 'main' );
-				viewDocument = editor.editing.view;
+				view = editor.editing.view;
 
 				defaultSchema( model.schema );
 				defaultConversion( editor.conversion, true );
@@ -46,7 +52,7 @@ describe( 'TableCell post-fixer', () => {
 	} );
 
 	it( 'should rename <span> to <p> when adding more <paragraph> elements to the same table cell', () => {
-		setModelData( model, modelTable( [ [ '00[]' ] ] ) );
+		editor.setData( viewTable( [ [ '<p>00</p>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -60,13 +66,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.setSelection( nodeByPath.nextSibling, 0 );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<p>00</p><p></p>' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should rename <span> to <p> on adding other block element to the same table cell', () => {
-		setModelData( model, modelTable( [ [ '00[]' ] ] ) );
+		editor.setData( viewTable( [ [ '<p>00</p>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -80,13 +86,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.setSelection( nodeByPath.nextSibling, 0 );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<p>00</p><div></div>' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should properly rename the same element on consecutive changes', () => {
-		setModelData( model, modelTable( [ [ '00[]' ] ] ) );
+		editor.setData( viewTable( [ [ '<p>00</p>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -98,7 +104,7 @@ describe( 'TableCell post-fixer', () => {
 			writer.setSelection( nodeByPath.nextSibling, 0 );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<p>00</p><p></p>' ]
 		], { asWidget: true } ) );
 
@@ -106,13 +112,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.remove( table.getNodeByPath( [ 0, 0, 1 ] ) );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '00' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should rename <span> to <p> when setting attribute on <paragraph>', () => {
-		setModelData( model, modelTable( [ [ '<paragraph>00[]</paragraph>' ] ] ) );
+		editor.setData( '<table><tr><td><p>00</p></td></tr></table>' );
 
 		const table = root.getChild( 0 );
 
@@ -120,13 +126,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.setAttribute( 'foo', 'bar', table.getNodeByPath( [ 0, 0, 0 ] ) );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<p foo="bar">00</p>' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should rename <p> to <span> when removing all but one paragraph inside table cell', () => {
-		setModelData( model, modelTable( [ [ '<paragraph>00[]</paragraph><paragraph>foo</paragraph>' ] ] ) );
+		editor.setData( viewTable( [ [ '<p>00</p><p>foo</p>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -134,13 +140,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.remove( table.getNodeByPath( [ 0, 0, 1 ] ) );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '00' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should rename <p> to <span> when removing attribute from <paragraph>', () => {
-		setModelData( model, modelTable( [ [ '<paragraph foo="bar">00[]</paragraph>' ] ] ) );
+		editor.setData( '<table><tr><td><p foo="bar">00</p></td></tr></table>' );
 
 		const table = root.getChild( 0 );
 
@@ -148,13 +154,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.removeAttribute( 'foo', table.getNodeByPath( [ 0, 0, 0 ] ) );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<span>00</span>' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should keep <p> in the view when <paragraph> attribute value is changed', () => {
-		setModelData( model, modelTable( [ [ '<paragraph foo="bar">00[]</paragraph>' ] ] ) );
+		editor.setData( viewTable( [ [ '<p foo="bar">00</p>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -162,13 +168,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.setAttribute( 'foo', 'baz', table.getNodeByPath( [ 0, 0, 0 ] ) );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<p foo="baz">00</p>' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should keep <p> in the view when <paragraph> attribute value is changed (table cell with multiple blocks)', () => {
-		setModelData( model, modelTable( [ [ '<paragraph foo="bar">00[]</paragraph><paragraph>00</paragraph>' ] ] ) );
+		editor.setData( viewTable( [ [ '<p foo="bar">00</p><p>00</p>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -176,13 +182,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.setAttribute( 'foo', 'baz', table.getNodeByPath( [ 0, 0, 0 ] ) );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<p foo="baz">00</p><p>00</p>' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should do nothing on rename <paragraph> to other block', () => {
-		setModelData( model, modelTable( [ [ '00' ] ] ) );
+		editor.setData( viewTable( [ [ '<p>00</p>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -190,13 +196,13 @@ describe( 'TableCell post-fixer', () => {
 			writer.rename( table.getNodeByPath( [ 0, 0, 0 ] ), 'block' );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<div>00</div>' ]
 		], { asWidget: true } ) );
 	} );
 
 	it( 'should do nothing when setting attribute on block item other then <paragraph>', () => {
-		setModelData( model, modelTable( [ [ '<block>foo</block>' ] ] ) );
+		editor.setData( viewTable( [ [ '<div>foo</div>' ] ] ) );
 
 		const table = root.getChild( 0 );
 
@@ -204,8 +210,72 @@ describe( 'TableCell post-fixer', () => {
 			writer.setAttribute( 'foo', 'bar', table.getNodeByPath( [ 0, 0, 0 ] ) );
 		} );
 
-		expect( formatTable( getViewData( viewDocument, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
 			[ '<div foo="bar">foo</div>' ]
 		], { asWidget: true } ) );
 	} );
+
+	it( 'should not crash when view.change() block was called in model.change()', () => {
+		editor.setData( viewTable( [ [ '<p>foobar</p>' ] ] ) );
+
+		const table = root.getChild( 0 );
+
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) )
+			.to.equal( formattedViewTable( [ [ 'foobar' ] ], { asWidget: true } ) );
+
+		expect( () => {
+			model.change( writer => {
+				const tableCell = table.getNodeByPath( [ 0, 0 ] );
+
+				writer.insertElement( 'paragraph', null, Position.createAt( tableCell, 'end' ) );
+				writer.setSelection( Range.createIn( tableCell ) );
+
+				// Do some change in the view while inside model change.
+				editor.editing.view.change( writer => {
+					writer.addClass( 'foo', editor.editing.mapper.toViewElement( tableCell ) );
+				} );
+			} );
+		} ).to.not.throw();
+
+		expect( formatTable( getViewData( view ) ) ).to.equal( formattedViewTable( [
+			[ { class: 'foo', contents: '<p>{foobar</p><p>]</p>' } ]
+		], { asWidget: true } ) );
+	} );
+
+	it( 'should keep <p> in the view when <paragraph> attribute value is changed (table cell with multiple blocks)', () => {
+		editor.setData( viewTable( [ [ '<p>00</p><p>00</p>' ] ] ) );
+
+		const table = root.getChild( 0 );
+
+		model.change( writer => {
+			writer.remove( Range.createOn( table.getNodeByPath( [ 0, 0, 1 ] ) ) );
+		} );
+
+		expect( formatTable( getViewData( view, { withoutSelection: true } ) ) ).to.equal( formattedViewTable( [
+			[ '<span>00</span>' ]
+		], { asWidget: true } ) );
+	} );
+
+	it( 'should update view selection after deleting content', () => {
+		editor.setData( viewTable( [ [ '<p>foo</p><p>bar</p>' ] ] ) );
+
+		const tableCell = root.getNodeByPath( [ 0, 0, 0 ] );
+
+		// Replace table cell contents with paragraph - as model.deleteContent() does.
+		model.change( writer => {
+			writer.remove( Range.createIn( tableCell ) );
+
+			const paragraph = writer.createElement( 'paragraph' );
+
+			writer.insert( paragraph, Position.createAt( tableCell ) );
+
+			// Set selection to newly created paragraph.
+			writer.setSelection( paragraph, 0 );
+		} );
+
+		const viewRange = view.document.selection.getFirstRange();
+
+		// Trying to map view selection to DOM range shouldn't throw after post-fixer will fix inserted <p> to <span>.
+		expect( () => view.domConverter.viewRangeToDom( viewRange ) ).to.not.throw();
+	} );
 } );