@@ -3,7 +3,6 @@ import { DragAndDropHelper } from '../../../pluginUtils/DragAndDrop/DragAndDropH
33import { getCMTableFromTable } from '../utils/getTableFromContentModel' ;
44import type { TableEditFeature } from './TableEditFeature' ;
55import {
6- isElementOfType ,
76 normalizeRect ,
87 MIN_ALLOWED_TABLE_CELL_WIDTH ,
98 mutateBlock ,
@@ -125,6 +124,7 @@ export interface CellResizerContext {
125124export interface CellResizerInitValue {
126125 cmTable : ReadonlyContentModelTable | undefined ;
127126 anchorColumn : number | undefined ;
127+ nextColumn : number ;
128128 anchorRow : number | undefined ;
129129 anchorRowHeight : number ;
130130 allWidths : number [ ] ;
@@ -139,45 +139,67 @@ export function onDragStart(context: CellResizerContext, event: MouseEvent): Cel
139139 const rect = normalizeRect ( td . getBoundingClientRect ( ) ) ;
140140
141141 // Get cell coordinates
142- const columnIndex = td . cellIndex ;
143- const row =
144- td . parentElement && isElementOfType ( td . parentElement , 'tr' ) ? td . parentElement : undefined ;
145- const rowIndex = row ?. rowIndex ;
146-
147- if ( rowIndex == undefined ) {
148- return {
149- cmTable : undefined ,
150- anchorColumn : undefined ,
151- anchorRow : undefined ,
152- anchorRowHeight : - 1 ,
153- allWidths : [ ] ,
154- } ; // Just a fallback
155- }
142+ let rowIndex : number | undefined ;
143+ let columnIndex : number | undefined ;
144+ let nextColumnIndex = - 1 ;
156145
157146 const { editor, table } = context ;
158147
159148 // Get Table block in content model
160149 const cmTable = getCMTableFromTable ( editor , table ) ;
161150
162151 if ( rect && cmTable ) {
152+ for ( let r = 0 ; r < cmTable ?. rows . length ; r ++ ) {
153+ for ( let c = 0 ; c < cmTable . rows [ r ] . cells . length ; c ++ ) {
154+ const cell = cmTable . rows [ r ] . cells [ c ] ;
155+
156+ if ( cell . cachedElement == td ) {
157+ // Target cell found, record its position
158+ rowIndex = r ;
159+ columnIndex = c ;
160+ } else if ( rowIndex != undefined && columnIndex != undefined ) {
161+ // rowIndex and columnIndex are already found, we can find nextColumnIndex now
162+ if ( ! cell . cachedElement ) {
163+ // No cached element means this cell is merged, so this could potentially be the right side of column
164+ // We are trying to find the last merged cell so we can modify its width later
165+ columnIndex = c ;
166+ } else {
167+ // Since we already found the target cell, the first cell with cachedElement after that must be the next column
168+ nextColumnIndex = c ;
169+ break ;
170+ }
171+ }
172+ }
173+
174+ // As long as rowIndex is found, we can break here, no matter if nextColumnIndex is found or not
175+ // because for the last column case, nextColumnIndex will be -1
176+ if ( rowIndex != undefined ) {
177+ break ;
178+ }
179+ }
180+
163181 onStart ( ) ;
164182
165- return {
166- cmTable,
167- anchorColumn : columnIndex ,
168- anchorRow : rowIndex ,
169- anchorRowHeight : cmTable . rows [ rowIndex ] . height ,
170- allWidths : [ ...cmTable . widths ] ,
171- } ;
172- } else {
173- return {
174- cmTable,
175- anchorColumn : undefined ,
176- anchorRow : undefined ,
177- anchorRowHeight : - 1 ,
178- allWidths : [ ] ,
179- } ; // Just a fallback
183+ if ( rowIndex !== undefined ) {
184+ return {
185+ cmTable,
186+ anchorColumn : columnIndex ,
187+ nextColumn : nextColumnIndex ,
188+ anchorRow : rowIndex ,
189+ anchorRowHeight : cmTable . rows [ rowIndex ] . height ,
190+ allWidths : [ ...cmTable . widths ] ,
191+ } ;
192+ }
180193 }
194+
195+ return {
196+ cmTable,
197+ anchorColumn : undefined ,
198+ anchorRow : undefined ,
199+ anchorRowHeight : - 1 ,
200+ allWidths : [ ] ,
201+ nextColumn : - 1 ,
202+ } ; // Just a fallback
181203}
182204
183205/**
@@ -191,7 +213,6 @@ export function onDraggingHorizontal(
191213 deltaX : number ,
192214 deltaY : number
193215) {
194- const { table } = context ;
195216 const { cmTable, anchorRow, anchorRowHeight } = initValue ;
196217
197218 // Assign new widths and heights to the CM table
@@ -203,11 +224,15 @@ export function onDraggingHorizontal(
203224 const newHeight = Math . max ( cmTable . rows [ anchorRow ] . height , MIN_ALLOWED_TABLE_CELL_HEIGHT ) ;
204225
205226 // Writeback CM Table size changes to DOM Table
206- const tableRow = table . rows [ anchorRow ] ;
207- for ( let col = 0 ; col < tableRow . cells . length ; col ++ ) {
208- const td = tableRow . cells [ col ] ;
209- td . style . height = newHeight + 'px' ;
210- td . style . boxSizing = 'border-box' ;
227+ const tableRow = cmTable . rows [ anchorRow ] . cells ;
228+
229+ for ( let col = 0 ; col < tableRow . length ; col ++ ) {
230+ const td = tableRow [ col ] . cachedElement ;
231+
232+ if ( td ) {
233+ td . style . height = newHeight + 'px' ;
234+ td . style . boxSizing = 'border-box' ;
235+ }
211236 }
212237
213238 return true ;
@@ -227,17 +252,15 @@ export function onDraggingVertical(
227252 deltaX : number
228253) {
229254 const { table, isRTL } = context ;
230- const { cmTable, anchorColumn, allWidths } = initValue ;
255+ const { cmTable, anchorColumn, nextColumn , allWidths } = initValue ;
231256
232257 // Assign new widths and heights to the CM table
233258 if ( cmTable && anchorColumn != undefined ) {
234259 const mutableTable = mutateBlock ( cmTable ) ;
235260
236- // Modify the CM Table size
237- const lastColumn = anchorColumn == cmTable . widths . length - 1 ;
238261 const change = deltaX * ( isRTL ? - 1 : 1 ) ;
239262 // This is the last column
240- if ( lastColumn ) {
263+ if ( nextColumn == - 1 ) {
241264 // Only the last column changes
242265 // Normalize the new width value
243266 const newWidth = Math . max (
@@ -248,25 +271,42 @@ export function onDraggingVertical(
248271 } else {
249272 // Any other two columns
250273 const anchorChange = allWidths [ anchorColumn ] + change ;
251- const nextAnchorChange = allWidths [ anchorColumn + 1 ] - change ;
274+ const nextAnchorChange = allWidths [ nextColumn ] - change ;
252275 if (
253276 anchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH ||
254277 nextAnchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH
255278 ) {
256279 return false ;
257280 }
281+
258282 mutableTable . widths [ anchorColumn ] = anchorChange ;
259- mutableTable . widths [ anchorColumn + 1 ] = nextAnchorChange ;
283+ mutableTable . widths [ nextColumn ] = nextAnchorChange ;
260284 }
261285
262- // Writeback CM Table size changes to DOM Table
263- for ( let row = 0 ; row < table . rows . length ; row ++ ) {
264- const tableRow = table . rows [ row ] ;
265- for ( let col = 0 ; col < tableRow . cells . length ; col ++ ) {
266- const td = tableRow . cells [ col ] ;
267-
268- td . style . width = cmTable . widths [ col ] + 'px' ;
269- td . style . boxSizing = 'border-box' ;
286+ // Write back CM Table size changes to DOM Table
287+ for ( let row = 0 ; row < cmTable . rows . length ; row ++ ) {
288+ const tableRow = cmTable . rows [ row ] . cells ;
289+ let lastTd : HTMLTableCellElement | null = null ;
290+ let lastWidth = 0 ;
291+
292+ for ( let col = 0 ; col < tableRow . length ; col ++ ) {
293+ const td = tableRow [ col ] . cachedElement ;
294+
295+ if ( td ) {
296+ td . style . boxSizing = 'border-box' ;
297+ lastTd = td ;
298+ lastWidth = cmTable . widths [ col ] ;
299+ } else if ( lastTd && tableRow [ col ] . spanLeft ) {
300+ lastWidth += cmTable . widths [ col ] ;
301+ } else if ( tableRow [ col ] . spanAbove ) {
302+ // For span above case, we don't need to adjust width, just clear lastTd and lastWidth
303+ lastTd = null ;
304+ lastWidth = 0 ;
305+ }
306+
307+ if ( lastTd ) {
308+ lastTd . style . width = lastWidth + 'px' ;
309+ }
270310 }
271311 }
272312
0 commit comments