Procházet zdrojové kódy

Added table post-fixer that marks table to refresh on headingRows attribute change.

Kuba Niegowski před 5 roky
rodič
revize
70b5134324

+ 53 - 0
packages/ckeditor5-table/src/converters/table-heading-rows-refresh-post-fixer.js

@@ -0,0 +1,53 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module table/converters/table-heading-rows-refresh-post-fixer
+ */
+
+/**
+ * Injects a table post-fixer into the model which marks the table in the differ to have it re-rendered.
+ *
+ * Table heading rows are represented in model just by `headingRows` attribute but in the view it's rendered as separate
+ * sections of the table (`thead`, `tbody`) so any change of that attribute would trigger a lot changes in view.
+ *
+ * When table `headingRows` attribute changes, entire table is re-rendered.
+ *
+ * @param {module:engine/model/model~Model} model
+ */
+export default function injectTableHeadingRowsRefreshPostFixer( model ) {
+	model.document.registerPostFixer( () => tableHeadingRowsRefreshPostFixer( model ) );
+}
+
+function tableHeadingRowsRefreshPostFixer( model ) {
+	const differ = model.document.differ;
+
+	// Stores tables to be refreshed so the table will be refreshed once for multiple changes.
+	const tablesToRefresh = new Set();
+
+	for ( const change of differ.getChanges() ) {
+		if ( change.type != 'attribute' ) {
+			continue;
+		}
+
+		const element = change.range.start.nodeAfter;
+
+		if ( element && element.is( 'table' ) && change.attributeKey == 'headingRows' ) {
+			tablesToRefresh.add( element );
+		}
+	}
+
+	if ( tablesToRefresh.size ) {
+		// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: refreshing heading rows (${ tablesToRefresh.size }).` );
+
+		for ( const table of tablesToRefresh.values() ) {
+			differ.refreshItem( table );
+		}
+
+		return true;
+	}
+
+	return false;
+}

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

@@ -35,6 +35,7 @@ import TableUtils from '../src/tableutils';
 import injectTableLayoutPostFixer from './converters/table-layout-post-fixer';
 import injectTableCellParagraphPostFixer from './converters/table-cell-paragraph-post-fixer';
 import injectTableCellRefreshPostFixer from './converters/table-cell-refresh-post-fixer';
+import injectTableHeadingRowsRefreshPostFixer from './converters/table-heading-rows-refresh-post-fixer';
 
 import '../theme/tableediting.css';
 
@@ -115,9 +116,6 @@ export default class TableEditing extends Plugin {
 		// Table heading columns conversion (change of heading rows requires reconversion of the whole table).
 		conversion.for( 'editingDowncast' ).add( downcastTableHeadingColumnsChange() );
 
-		// Table heading rows change requires reconversion of the whole table.
-		this.listenTo( model, 'applyOperation', headingRowsAttributeChangeHandler( model ) );
-
 		// Define all the commands.
 		editor.commands.add( 'insertTable', new InsertTableCommand( editor ) );
 		editor.commands.add( 'insertTableRowAbove', new InsertRowCommand( editor, { order: 'above' } ) );
@@ -144,6 +142,7 @@ export default class TableEditing extends Plugin {
 		editor.commands.add( 'selectTableRow', new SelectRowCommand( editor ) );
 		editor.commands.add( 'selectTableColumn', new SelectColumnCommand( editor ) );
 
+		injectTableHeadingRowsRefreshPostFixer( model );
 		injectTableLayoutPostFixer( model );
 		injectTableCellRefreshPostFixer( model );
 		injectTableCellParagraphPostFixer( model );
@@ -156,22 +155,3 @@ export default class TableEditing extends Plugin {
 		return [ TableUtils ];
 	}
 }
-
-// Model#applyOperation handler for headingRows attribute changes.
-function headingRowsAttributeChangeHandler( model ) {
-	return ( event, [ operation ] ) => {
-		if ( !operation.isDocumentOperation ) {
-			return;
-		}
-
-		if ( operation.type != 'addAttribute' && operation.type != 'removeAttribute' && operation.type != 'changeAttribute' ) {
-			return;
-		}
-
-		const element = operation.range.getContainedElement();
-
-		if ( element && element.is( 'table' ) && operation.key == 'headingRows' ) {
-			model.document.differ.refreshItem( element );
-		}
-	};
-}