devexpress-richedit
Version:
DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.
159 lines (158 loc) • 8.47 kB
JavaScript
import { FixedInterval } from '@devexpress/utils/lib/intervals/fixed';
import { EnumUtils } from '@devexpress/utils/lib/utils/enum';
import { ListUtils } from '@devexpress/utils/lib/utils/list';
import { CellGridInfoManager } from '../../layout-formatter/table/grid-engine/cell-grid-info-manager';
import { TablePosition, TablePositionIndexes } from '../../model/tables/main-structures/table';
import { TableCellMergingState } from '../../model/tables/secondary-structures/table-base-structures';
import { TableCellUtils } from '../../model/tables/table-utils';
export class __DEBUG_TABLE {
static tables(subDocument) {
const tables = subDocument.tables;
if (!tables.length)
return;
ListUtils.forEach(subDocument.tablesByLevels, (levelTables, levelInd) => {
if (levelTables.length) {
let prevTblInd = levelTables[0].index - 1;
ListUtils.forEach(levelTables, (tbl) => {
if (tbl.nestedLevel != levelInd)
throw new Error(`DEBUG_TABLES_CHECKS incorrect position of table(his index = ${tbl.index}), level = ${levelInd}`);
if (tbl.index <= prevTblInd)
throw new Error(`DEBUG_TABLES_CHECKS incorrect order of tables on level ${levelInd}`);
prevTblInd = tbl.index;
});
}
});
if (!ListUtils.allOf(tables, (t, i) => t.index > tables[i - 1].index, 1))
throw new Error(`DEBUG_TABLES_CHECKS incorrect order of subDocument[${subDocument.id}].tables`);
for (let t of tables)
__DEBUG_TABLE.table(t);
}
static table(table) {
const colCount = TableCellUtils.getColumnCount(table);
if (!table.rows.length)
throw new Error(`DEBUG_TABLE_CHECKS no rowsOnTable`);
ListUtils.forEach(table.rows, (r, rInd) => {
if (r.logicColumnCount != colCount)
throw new Error(`DEBUG_TABLE_CHECKS incorrectColCount on row[${rInd}]. Must be = ${colCount}`);
if (!r.cells.length)
throw new Error(`DEBUG_TABLE_CHECKS no cellsOnRow on row[${rInd}]`);
});
new TableData(table, colCount).check();
}
static VISUALIZE_SELECTED_CELLS(tableInfo) {
if (tableInfo.extendedData.numRows == 0)
return "noCells";
const table = tableInfo.table;
const result = ListUtils.initByCallback(table.rows.length, () => ListUtils.initByValue(TableCellUtils.getColumnCount(table), "*"));
const cgim = new CellGridInfoManager(table);
tableInfo.extendedData.foreach(() => { }, (cellInfo, rowInfo) => {
const cellGridInfo = cgim.tableCellInfos[rowInfo.rowIndex][cellInfo.cellIndex];
ListUtils.forEachOnInterval(cellGridInfo.rowIndexesInterval, (rowIndex) => {
ListUtils.forEachOnInterval(new FixedInterval(cellGridInfo.getGridCellIndex(), cellInfo.cell.columnSpan), (colIndex) => {
result[rowIndex][colIndex] = "X";
});
});
});
return ListUtils.map(result, (r) => r.join("")).join("\n");
}
}
var DebugTableCellState;
(function (DebugTableCellState) {
DebugTableCellState[DebugTableCellState["NotVisited"] = 0] = "NotVisited";
DebugTableCellState[DebugTableCellState["None"] = 1] = "None";
DebugTableCellState[DebugTableCellState["Continious"] = 2] = "Continious";
DebugTableCellState[DebugTableCellState["Restart"] = 3] = "Restart";
DebugTableCellState[DebugTableCellState["BeforeAfter"] = 4] = "BeforeAfter";
})(DebugTableCellState || (DebugTableCellState = {}));
class Data {
constructor(startCellSpan, cellLen, state) {
this.startCellSpan = startCellSpan;
this.state = state;
this.cellLen = cellLen;
}
toString() {
return `${Data.toStrMap[this.state]}[${this.startCellSpan}|${this.startCellSpan + this.cellLen})`;
}
}
Data.toStrMap = {
[DebugTableCellState.None]: "N",
[DebugTableCellState.Restart]: "R",
[DebugTableCellState.Continious]: "C",
[DebugTableCellState.NotVisited]: "NoVis",
[DebugTableCellState.BeforeAfter]: "BA",
};
class TableData {
constructor(table, colCount) {
this.colCount = colCount;
this.table = table;
}
check() {
this.fill();
this.checkData();
__DEBUG_TABLE.lastString = this.toString();
}
fill() {
this.tblData = ListUtils.initByCallback(this.table.rows.length, () => ListUtils.initByValue(this.colCount, new Data(-1, -1, DebugTableCellState.NotVisited)));
const tblPos = new TablePosition(this.table, -1, -1);
while (tblPos.moveToNextRow()) {
ListUtils.forEachOnInterval(new FixedInterval(0, tblPos.row.gridBefore), (colIndex) => this.add(new TablePositionIndexes(tblPos.rowIndex, colIndex), null, -1, -1));
let cellSpan = tblPos.row.gridBefore;
while (tblPos.moveToNextCell()) {
ListUtils.forEachOnInterval(new FixedInterval(cellSpan, tblPos.cell.columnSpan), (colIndex) => this.add(new TablePositionIndexes(tblPos.rowIndex, colIndex), tblPos.cell, cellSpan, tblPos.cell.columnSpan));
cellSpan += tblPos.cell.columnSpan;
}
ListUtils.forEachOnInterval(new FixedInterval(cellSpan, tblPos.row.gridAfter), (colIndex) => this.add(new TablePositionIndexes(tblPos.rowIndex, colIndex), null, -1, -1));
}
}
add(ind, cell, startCellSpan, cellSpanLength) {
const oldVal = this.tblData[ind.rowIndex][ind.cellIndex];
if (oldVal.state != DebugTableCellState.NotVisited)
throw new Error(`DEBUG_TABLE_CHECKS Table model is incorrect`);
this.tblData[ind.rowIndex][ind.cellIndex] = new Data(startCellSpan, cellSpanLength, this.getState(cell));
}
checkData() {
ListUtils.forEach(this.tblData, (rowData, rowInd) => {
ListUtils.forEach(rowData, (data, colInd) => {
switch (data.state) {
case DebugTableCellState.NotVisited:
throw new Error(`DEBUG_TABLE_CHECKS some of logic cells is free`);
case DebugTableCellState.Continious: {
if (rowInd == 0)
throw new Error(`DEBUG_TABLE_CHECKS obvious error [${rowInd}][${colInd}]`);
const neighborRowData = this.tblData[rowInd - 1][colInd];
if (neighborRowData.cellLen != data.cellLen || neighborRowData.startCellSpan != data.startCellSpan ||
!EnumUtils.isAnyOf(neighborRowData.state, DebugTableCellState.Continious, DebugTableCellState.Restart)) {
console.log(this.toString());
throw new Error(`DEBUG_TABLE_CHECKS error`);
}
break;
}
case DebugTableCellState.Restart: {
if (rowInd == this.table.rows.length - 1)
throw new Error(`DEBUG_TABLE_CHECKS obvious error [${rowInd}][${colInd}]`);
const neighborRowData = this.tblData[rowInd + 1][colInd];
if (neighborRowData.cellLen != data.cellLen || neighborRowData.startCellSpan != data.startCellSpan ||
neighborRowData.state != DebugTableCellState.Continious) {
console.log(this.toString());
throw new Error(`DEBUG_TABLE_CHECKS error`);
}
break;
}
case DebugTableCellState.None:
}
});
});
}
toString() {
return ListUtils.map(this.tblData, (d) => ListUtils.map(d, (val) => val.toString()).join("\t")).join("\n");
}
getState(cell) {
if (!cell)
return DebugTableCellState.BeforeAfter;
switch (cell.verticalMerging) {
case TableCellMergingState.None: return DebugTableCellState.None;
case TableCellMergingState.Restart: return DebugTableCellState.Restart;
case TableCellMergingState.Continue: return DebugTableCellState.Continious;
}
}
}