UNPKG

devexpress-richedit

Version:

DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.

121 lines (120 loc) 4.32 kB
import { ListUtils } from '@devexpress/utils/lib/utils/list'; import { SearchUtils } from '@devexpress/utils/lib/utils/search'; import { Table, TablePosition } from '../../../model/tables/main-structures/table'; import { BoxWrapFieldInfo } from '../box-wrap'; export class RecursiveObjectsIterator { constructor(objects) { this.objects = objects; } getNextObjectPosition() { return this.nextObjPosition; } init(pos) { this.indexes = []; const index = SearchUtils.normedInterpolationIndexOf(this.objects, (o) => this.getStartPosition(o), pos); if (index < 0) { this.setNextInfos(0, pos); return; } let obj = this.objects[index]; while (pos >= this.getEndPosition(obj)) { const parent = this.getParent(obj); if (!parent) { this.setNextInfos(index + 1, pos); return; } obj = parent; } this.collectIndexes(this.getIndex(obj), pos); } collectIndexes(index, pos) { const insertPos = this.indexes.length; let ind = this.correctBounds(index, pos); let obj = this.objects[ind]; const leftBoundIndex = this.indexes.length ? ListUtils.last(this.indexes) : -1; while (true) { this.indexes.splice(insertPos, 0, ind); const parent = this.getParent(obj); if (!parent || this.getIndex(parent) == leftBoundIndex) break; ind = this.getIndex(parent); obj = parent; } this.setNextInfos(ListUtils.last(this.indexes) + 1, pos); } update(newPosition) { if (!this.objects.length) return false; const indexesDeleted = this.popLastIndexes(newPosition); if (newPosition >= this.nextObjPosition) { this.nextObjIndex = this.correctBounds(this.nextObjIndex, newPosition); this.collectIndexes(this.nextObjIndex, newPosition); return true; } return indexesDeleted; } setNextInfos(ind, pos) { this.nextObjIndex = ind; const obj = this.objects[ind]; if (!obj || this.getStartPosition(obj) >= pos) this.nextObjPosition = obj ? this.getStartPosition(obj) : Number.MAX_VALUE; else this.setNextInfos(ind + 1, pos); } popLastIndexes(newPosition) { if (!this.indexes.length || newPosition < this.getEndPosition(this.objects[ListUtils.last(this.indexes)])) return false; this.indexes.pop(); this.popLastIndexes(newPosition); return true; } } export class TableIterator extends RecursiveObjectsIterator { getStartPosition(o) { return o.getStartPosition(); } getEndPosition(o) { return o.getEndPosition(); } getParent(obj) { return obj.getParentTable(); } getIndex(obj) { return obj.index; } correctBounds(objIndex, pos) { return Table.correctBoundTable(this.objects, objIndex, pos, (i) => ++i).index; } generateInfo(pos) { if (!this.indexes.length) return null; return ListUtils.map(this.indexes, (ind) => { const table = this.objects[ind]; const rowIndex = SearchUtils.normedInterpolationIndexOf(table.rows, (r) => r.getStartPosition(), pos); const cellIndex = SearchUtils.normedInterpolationIndexOf(table.rows[rowIndex].cells, (c) => c.startParagraphPosition.value, pos); return new TablePosition(table, rowIndex, cellIndex).init(); }); } } export class FieldIterator extends RecursiveObjectsIterator { getStartPosition(o) { return o.getFieldStartPosition(); } getEndPosition(o) { return o.getFieldEndPosition(); } getParent(obj) { return obj.parent; } getIndex(obj) { return obj.index; } correctBounds(objIndex, _pos) { return objIndex; } generateInfo(pos) { if (!this.indexes.length) return null; return ListUtils.map(this.indexes, (ind) => BoxWrapFieldInfo.make(this.objects[ind], pos)); } }