You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					84 lines
				
				2.5 KiB
			
		
		
			
		
	
	
					84 lines
				
				2.5 KiB
			| 
											3 years ago
										 | import { Node } from 'prosemirror-model'; | ||
|  | import { NodeView } from 'prosemirror-view'; | ||
|  | 
 | ||
|  | /** | ||
|  |  * @public | ||
|  |  */ | ||
|  | export class TableView implements NodeView { | ||
|  |   public dom: HTMLDivElement; | ||
|  |   public table: HTMLTableElement; | ||
|  |   public colgroup: HTMLTableColElement; | ||
|  |   public contentDOM: HTMLTableSectionElement; | ||
|  | 
 | ||
|  |   constructor(public node: Node, public cellMinWidth: number) { | ||
|  |     this.dom = document.createElement('div'); | ||
|  |     this.dom.className = 'tableWrapper'; | ||
|  |     this.table = this.dom.appendChild(document.createElement('table')); | ||
|  |     this.colgroup = this.table.appendChild(document.createElement('colgroup')); | ||
|  |     updateColumnsOnResize(node, this.colgroup, this.table, cellMinWidth); | ||
|  |     this.contentDOM = this.table.appendChild(document.createElement('tbody')); | ||
|  |   } | ||
|  | 
 | ||
|  |   update(node: Node): boolean { | ||
|  |     if (node.type != this.node.type) return false; | ||
|  |     this.node = node; | ||
|  |     updateColumnsOnResize(node, this.colgroup, this.table, this.cellMinWidth); | ||
|  |     return true; | ||
|  |   } | ||
|  | 
 | ||
|  |   ignoreMutation(record: MutationRecord): boolean { | ||
|  |     return ( | ||
|  |       record.type == 'attributes' && | ||
|  |       (record.target == this.table || this.colgroup.contains(record.target)) | ||
|  |     ); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * @public | ||
|  |  */ | ||
|  | export function updateColumnsOnResize( | ||
|  |   node: Node, | ||
|  |   colgroup: HTMLTableColElement, | ||
|  |   table: HTMLTableElement, | ||
|  |   cellMinWidth: number, | ||
|  |   overrideCol?: number, | ||
|  |   overrideValue?: number, | ||
|  | ): void { | ||
|  |   let totalWidth = 0, | ||
|  |     fixedWidth = true; | ||
|  |   let nextDOM = colgroup.firstChild as HTMLElement; | ||
|  |   const row = node.firstChild; | ||
|  |   for (let i = 0, col = 0; i < row.childCount; i++) { | ||
|  |     const { colspan, colwidth } = row.child(i).attrs; | ||
|  |     for (let j = 0; j < colspan; j++, col++) { | ||
|  |       const hasWidth = | ||
|  |         overrideCol == col ? overrideValue : colwidth && colwidth[j]; | ||
|  |       const cssWidth = hasWidth ? hasWidth + 'px' : ''; | ||
|  |       totalWidth += hasWidth || cellMinWidth; | ||
|  |       if (!hasWidth) fixedWidth = false; | ||
|  |       if (!nextDOM) { | ||
|  |         colgroup.appendChild(document.createElement('col')).style.width = | ||
|  |           cssWidth; | ||
|  |       } else { | ||
|  |         if (nextDOM.style.width != cssWidth) nextDOM.style.width = cssWidth; | ||
|  |         nextDOM = nextDOM.nextSibling as HTMLElement; | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   while (nextDOM) { | ||
|  |     const after = nextDOM.nextSibling; | ||
|  |     nextDOM.parentNode.removeChild(nextDOM); | ||
|  |     nextDOM = after as HTMLElement; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (fixedWidth) { | ||
|  |     table.style.width = totalWidth + 'px'; | ||
|  |     table.style.minWidth = ''; | ||
|  |   } else { | ||
|  |     table.style.width = ''; | ||
|  |     table.style.minWidth = totalWidth + 'px'; | ||
|  |   } | ||
|  | } |