123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- import Block from '../blots/block';
- import Container from '../blots/container';
- class TableCell extends Block {
- static create(value) {
- const node = super.create();
- if (value) {
- node.setAttribute('data-row', value);
- } else {
- node.setAttribute('data-row', tableId());
- }
- return node;
- }
- static formats(domNode) {
- if (domNode.hasAttribute('data-row')) {
- return domNode.getAttribute('data-row');
- }
- return undefined;
- }
- cellOffset() {
- if (this.parent) {
- return this.parent.children.indexOf(this);
- }
- return -1;
- }
- format(name, value) {
- if (name === TableCell.blotName && value) {
- this.domNode.setAttribute('data-row', value);
- } else {
- super.format(name, value);
- }
- }
- row() {
- return this.parent;
- }
- rowOffset() {
- if (this.row()) {
- return this.row().rowOffset();
- }
- return -1;
- }
- table() {
- return this.row() && this.row().table();
- }
- }
- TableCell.blotName = 'table';
- TableCell.tagName = 'TD';
- class TableRow extends Container {
- checkMerge() {
- if (super.checkMerge() && this.next.children.head != null) {
- const thisHead = this.children.head.formats();
- const thisTail = this.children.tail.formats();
- const nextHead = this.next.children.head.formats();
- const nextTail = this.next.children.tail.formats();
- return (
- thisHead.table === thisTail.table &&
- thisHead.table === nextHead.table &&
- thisHead.table === nextTail.table
- );
- }
- return false;
- }
- optimize(...args) {
- super.optimize(...args);
- this.children.forEach(child => {
- if (child.next == null) return;
- const childFormats = child.formats();
- const nextFormats = child.next.formats();
- if (childFormats.table !== nextFormats.table) {
- const next = this.splitAfter(child);
- if (next) {
- next.optimize();
- }
- // We might be able to merge with prev now
- if (this.prev) {
- this.prev.optimize();
- }
- }
- });
- }
- rowOffset() {
- if (this.parent) {
- return this.parent.children.indexOf(this);
- }
- return -1;
- }
- table() {
- return this.parent && this.parent.parent;
- }
- }
- TableRow.blotName = 'table-row';
- TableRow.tagName = 'TR';
- class TableBody extends Container {}
- TableBody.blotName = 'table-body';
- TableBody.tagName = 'TBODY';
- class TableContainer extends Container {
- balanceCells() {
- const rows = this.descendants(TableRow);
- const maxColumns = rows.reduce((max, row) => {
- return Math.max(row.children.length, max);
- }, 0);
- rows.forEach(row => {
- new Array(maxColumns - row.children.length).fill(0).forEach(() => {
- let value;
- if (row.children.head != null) {
- value = TableCell.formats(row.children.head.domNode);
- }
- const blot = this.scroll.create(TableCell.blotName, value);
- row.appendChild(blot);
- blot.optimize(); // Add break blot
- });
- });
- }
- cells(column) {
- return this.rows().map(row => row.children.at(column));
- }
- deleteColumn(index) {
- const [body] = this.descendant(TableBody);
- if (body == null || body.children.head == null) return;
- body.children.forEach(row => {
- const cell = row.children.at(index);
- if (cell != null) {
- cell.remove();
- }
- });
- }
- insertColumn(index) {
- const [body] = this.descendant(TableBody);
- if (body == null || body.children.head == null) return;
- body.children.forEach(row => {
- const ref = row.children.at(index);
- const value = TableCell.formats(row.children.head.domNode);
- const cell = this.scroll.create(TableCell.blotName, value);
- row.insertBefore(cell, ref);
- });
- }
- insertRow(index) {
- const [body] = this.descendant(TableBody);
- if (body == null || body.children.head == null) return;
- const id = tableId();
- const row = this.scroll.create(TableRow.blotName);
- body.children.head.children.forEach(() => {
- const cell = this.scroll.create(TableCell.blotName, id);
- row.appendChild(cell);
- });
- const ref = body.children.at(index);
- body.insertBefore(row, ref);
- }
- rows() {
- const body = this.children.head;
- if (body == null) return [];
- return body.children.map(row => row);
- }
- }
- TableContainer.blotName = 'table-container';
- TableContainer.tagName = 'TABLE';
- TableContainer.allowedChildren = [TableBody];
- TableBody.requiredContainer = TableContainer;
- TableBody.allowedChildren = [TableRow];
- TableRow.requiredContainer = TableBody;
- TableRow.allowedChildren = [TableCell];
- TableCell.requiredContainer = TableRow;
- function tableId() {
- const id = Math.random()
- .toString(36)
- .slice(2, 6);
- return `row-${id}`;
- }
- export { TableCell, TableRow, TableBody, TableContainer, tableId };
|