UNPKG

devexpress-richedit

Version:

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

610 lines (609 loc) 29.5 kB
import { LayoutBoxType } from '../../layout/main-structures/layout-boxes/layout-box'; import { LayoutPageFlags } from '../../layout/main-structures/layout-page'; import { SubDocumentInfoType } from '../../model/enums'; import { ModelIterator } from '../../model/model-iterator'; import { RunType } from '../../model/runs/run-type'; import { TableCellPropertiesMask } from '../../model/tables/properties/table-cell-properties'; import { TablePropertiesMask } from '../../model/tables/properties/table-properties'; import { TableRowPropertiesMask } from '../../model/tables/properties/table-row-properties'; import { TableCellMergingState, TableLayoutType, TableLookTypes } from '../../model/tables/secondary-structures/table-base-structures'; import { TableHeightUnitType, TableWidthUnitType } from '../../model/tables/secondary-structures/table-units'; import { IntervalAlgorithms } from '@devexpress/utils/lib/intervals/algorithms'; import { FixedInterval } from '@devexpress/utils/lib/intervals/fixed'; import { ListUtils } from '@devexpress/utils/lib/utils/list'; import { NumberMapUtils } from '@devexpress/utils/lib/utils/map/number'; import { StringMapUtils } from '@devexpress/utils/lib/utils/map/string'; import { StringUtils } from '@devexpress/utils/lib/utils/string'; export class ManagerParams { constructor(name, func = null) { this.name = name; this.func = func; } } class ManagerInfo { constructor(id, obj) { this.id = id; this.obj = obj; } } export class SimpleObjectsManager { constructor() { this.map = {}; this.createdVariables = []; } add(obj, constructorName, params) { if (StringUtils.startsAt(constructorName, "new ")) constructorName = constructorName.substr(4); let indOfOpenBracket = constructorName.indexOf("("); if (indOfOpenBracket == -1) indOfOpenBracket = constructorName.length; let constructorParams = constructorName.substring(indOfOpenBracket); if (!constructorParams.length) constructorParams = "()"; const variablePrefixName = constructorName.charAt(0).toLowerCase() + constructorName.substring(1, indOfOpenBracket); let info = this.map[variablePrefixName]; if (info === undefined) info = this.map[variablePrefixName] = []; let equalObj; if (obj.equals) equalObj = ListUtils.elementBy(info, (curr) => curr.obj.equals(obj)); if (equalObj) return `${variablePrefixName}_${equalObj.id}`; const id = info.length ? ListUtils.last(info).id + 1 : 0; const variableName = `${variablePrefixName}_${id}`; info.push(new ManagerInfo(id, obj)); const t = []; t.push(`const ${variableName}: ${constructorName.substring(0, indOfOpenBracket)} = new ${constructorName.substr(0, indOfOpenBracket)}${constructorParams};`); for (let p of params) t.push(`${variableName}.${p.name} = ${p.func ? p.func() : obj[p.name]};`); this.createdVariables.push(t.join("\r\n")); return variableName; } } export class Options { constructor() { this.defineBorderInfo = false; this.defineTableBorderInfo = false; this.defineTableCellBorderInfo = false; this.defineFullTableProperties = false; this.defineFullTableRowProperties = false; this.defineFullTableCellProperties = false; } enableSeparateBorderInfo() { this.defineBorderInfo = true; return this; } enableSeparateTableBorderInfo() { this.defineTableBorderInfo = true; return this; } enableSeparateTableCellBorderInfo() { this.defineTableCellBorderInfo = true; return this; } enableFullTableProperties() { this.defineFullTableProperties = true; return this; } enableFullTableRowProperties() { this.defineFullTableRowProperties = true; return this; } enableFullTableCellProperties() { this.defineFullTableCellProperties = true; return this; } } export class Creator { get documentModel() { ListUtils.addListOnTail(this.idMap.createdVariables, this.str); return this.idMap.createdVariables.join("\r\n"); } get tables() { return this.subDocument.tables; } get table() { return this.tables[this.tblIndex]; } static create(model, layout = null, options = new Options()) { return new Creator(model, layout, options).documentModel; } constructor(model, layout = null, options = new Options()) { this.layout = layout; this.subDocument = model.mainSubDocument; this.subDocumentVariableName = Creator.getSubDocumentVariableName(this.subDocument); this.model = model; this.options = options; this.idMap = new SimpleObjectsManager(); this.tblIndex = 0; this.str = []; this.fillModel(); this.str.push(`${this.subDocumentVariableName} = model.activeSubDocument;`); this.fillTables(); this.fillFields(); this.fillBookmarks(); NumberMapUtils.forEach(this.model.subDocuments, (sd) => { if (sd.isMain()) return; this.subDocumentVariableName = Creator.getSubDocumentVariableName(sd); this.subDocument = sd; const parentSubDocumentId = sd.isTextBox() ? sd.info.parentSubDocumentId : -1; this.str.push(`const ${this.subDocumentVariableName}: SubDocument = TestDocumentModel.addOtherSubDocument(model, SubDocumentInfoType.${SubDocumentInfoType[sd.info.getType()]}, ${parentSubDocumentId},`); this.str.push("["); this.fillChunks(); this.str.push("],"); this.str.push("["); this.fillParagraphs(); this.str.push("]);"); this.fillTables(); this.fillFields(); this.fillBookmarks(); }); this.str.push(`layout = new TestLayoutCreator([`); for (let p of this.layout.pages) this.fillPage(p); this.str.push(`], model).getLayout();`); } static getSubDocumentVariableName(sd) { if (sd.isMain()) return "subDocument"; const typeAsStr = SubDocumentInfoType[sd.info.getType()]; return `subDocument_${typeAsStr}_${sd.id}`; } escape(str) { return str.replace(/\\/g, "\\\\") .replace(/"/g, "\\\""); } fillFields() { ListUtils.forEach(this.subDocument.fields, (f, ind) => { this.str.push(`Field.addField(${this.subDocumentVariableName}.fields, new Field(${this.subDocumentVariableName}.positionManager, ${ind}, ${f.getFieldStartPosition()}, ${f.getSeparatorPosition()}, ${f.getFieldEndPosition()}, ${f.showCode},`); if (f.getHyperlinkInfo()) this.str.push(`new HyperlinkInfo("${this.escape(f.getHyperlinkInfo().uri)}", "${this.escape(f.getHyperlinkInfo().anchor)}", "${this.escape(f.getHyperlinkInfo().tip)}", ${f.getHyperlinkInfo().visited}))); //${this.escape(this.subDocument.getText(f.getAllFieldInterval()))}`); else { this.str.push(`undefined)); //${this.escape(this.subDocument.getText(f.getAllFieldInterval()))}`); this.mergeLastStrings(2); } }); } fillBookmarks() { if (!this.subDocument.bookmarks.length) return; this.str.push(`${this.subDocumentVariableName}.bookmarks = [];`); for (let b of this.subDocument.bookmarks) this.str.push(`${this.subDocumentVariableName}.bookmarks.push(new Bookmark(${this.subDocumentVariableName}.positionManager, new BoundaryInterval(${b.start}, ${b.end}), "${this.escape(b.name)}")); //${this.escape(this.subDocument.getText(b.interval))}`); } fillModel() { this.str.push("model = TestDocumentModel.create("); this.str.push("["); this.fillChunks(); this.str.push("],"); this.str.push("["); this.fillParagraphs(); this.str.push("],"); this.str.push("["); this.fillSections(); this.str.push("]);"); } tableWidthUnit(w) { return `new TableWidthUnit().init(${w.value}, TableWidthUnitType.${TableWidthUnitType[w.type]})`; } borderInfo(b) { if (this.options.defineBorderInfo) return this.idMap.add(b, "BorderInfo", [ new ManagerParams("colorIndex"), new ManagerParams("frame"), new ManagerParams("offset"), new ManagerParams("shadow"), new ManagerParams("style"), new ManagerParams("width"), ]); else return `new BorderInfo()`; } tableBorders(brds) { if (this.options.defineTableBorderInfo) return this.idMap.add(brds, "TableBorders", [ new ManagerParams("top", () => this.borderInfo(brds.top)), new ManagerParams("right", () => this.borderInfo(brds.right)), new ManagerParams("bottom", () => this.borderInfo(brds.bottom)), new ManagerParams("left", () => this.borderInfo(brds.left)), new ManagerParams("insideHorizontal", () => this.borderInfo(brds.insideHorizontal)), new ManagerParams("insideVertical", () => this.borderInfo(brds.insideVertical)), ]); else return `new TableBorders()`; } asEnum(objEnum, objEnumName, mask, excessNullValue = Number.MAX_VALUE) { const res = []; let isFoundNullValue = false; StringMapUtils.forEach(objEnum, (obj, key) => { const keyNum = parseInt(key); if (!isNaN(keyNum) && (keyNum & mask) == keyNum) { if (excessNullValue != keyNum) res.push(obj); else isFoundNullValue = true; } }); if (isFoundNullValue && !res.length) res.push(objEnum[excessNullValue]); return ListUtils.map(res, (r) => `${objEnumName}.${r}`).join(" | "); } tableCellMargins(cm) { return this.idMap.add(cm, "TableCellMargins", [ new ManagerParams("top", () => this.tableWidthUnit(cm.top)), new ManagerParams("bottom", () => this.tableWidthUnit(cm.bottom)), new ManagerParams("left", () => this.tableWidthUnit(cm.left)), new ManagerParams("right", () => this.tableWidthUnit(cm.right)), ]); } tableProperties(p) { if (this.options.defineFullTableProperties) return this.idMap.add(p, "TableProperties", [ new ManagerParams("avoidDoubleBorders"), new ManagerParams("backgroundColor"), new ManagerParams("borders", () => this.tableBorders(p.borders)), new ManagerParams("bottomFromText"), new ManagerParams("cellMargins", () => this.tableCellMargins(p.cellMargins)), new ManagerParams("cellSpacing", () => this.tableWidthUnit(p.cellSpacing)), new ManagerParams("horizontalAlignMode"), new ManagerParams("horizontalAnchorType"), new ManagerParams("indent", () => this.tableWidthUnit(p.indent)), new ManagerParams("isTableOverlap"), new ManagerParams("layoutType", () => `TableLayoutType.${TableLayoutType[p.layoutType]}`), new ManagerParams("leftFromText"), new ManagerParams("mask", () => this.asEnum(TablePropertiesMask, "TablePropertiesMask", p.mask, TablePropertiesMask.UseNone)), new ManagerParams("rightFromText"), new ManagerParams("tableHorizontalPosition"), new ManagerParams("tableRowAlignment"), new ManagerParams("tableStyleColumnBandSize"), new ManagerParams("tableStyleRowBandSize"), new ManagerParams("tableVerticalPosition"), new ManagerParams("textWrapping"), new ManagerParams("topFromText"), new ManagerParams("verticalAlignMode"), new ManagerParams("verticalAnchorType"), ]); else return this.idMap.add(p, "TableProperties", [ new ManagerParams("cellMargins", () => this.tableCellMargins(p.cellMargins)), new ManagerParams("cellSpacing", () => this.tableWidthUnit(p.cellSpacing)), new ManagerParams("indent", () => this.tableWidthUnit(p.indent)), new ManagerParams("layoutType", () => `TableLayoutType.${TableLayoutType[p.layoutType]}`), new ManagerParams("mask", () => this.asEnum(TablePropertiesMask, "TablePropertiesMask", p.mask, TablePropertiesMask.UseNone)), ]); } tableLookTypes(lt) { return this.asEnum(TableLookTypes, "TableLookTypes", lt, TableLookTypes.None); } tableStyle(_s) { return `new TableStyle("name", "name", false, false, false, false, {}, null, null)`; } tableRowProperties(prop) { if (this.options.defineFullTableRowProperties) return this.idMap.add(prop, "TableRowProperties", [ new ManagerParams("cantSplit"), new ManagerParams("cellSpacing", () => this.tableWidthUnit(prop.cellSpacing)), new ManagerParams("divId"), new ManagerParams("header"), new ManagerParams("hideCellMark"), new ManagerParams("mask", () => this.asEnum(TableRowPropertiesMask, "TableRowPropertiesMask", prop.mask, TableRowPropertiesMask.UseNone)), new ManagerParams("tableRowAlignment"), ]); else return this.idMap.add(prop, "TableRowProperties", [ new ManagerParams("cellSpacing", () => this.tableWidthUnit(prop.cellSpacing)), new ManagerParams("mask", () => this.asEnum(TableRowPropertiesMask, "TableRowPropertiesMask", prop.mask, TableRowPropertiesMask.UseNone)), ]); } tblCellRuns(c) { let nextLevel = this.subDocument.tablesByLevels[this.table.nestedLevel + 1]; if (!nextLevel) nextLevel = []; const cellInterval = c.interval; const internalTables = ListUtils.reducedMap(nextLevel, (t) => IntervalAlgorithms.getIntersectionNonNullLength(t.interval, cellInterval) ? t : null); const isNeedChunkIndex = this.subDocument.chunks.length > 1; const it = new ModelIterator(this.subDocument, false); it.setPosition(cellInterval.start); const runStr = []; do { const pos = it.getAbsolutePosition(); if (pos >= cellInterval.end) break; const curr = new FixedInterval(pos, it.run.getLength()); if (ListUtils.allOf(internalTables, (t) => !IntervalAlgorithms.getIntersectionNonNullLength(t.interval, curr))) runStr.push(isNeedChunkIndex ? `[${it.chunkIndex}, ${it.runIndex}]` : `${it.runIndex}`); } while (it.moveToNextRun()); this.str.push(`[${runStr.join(", ")}],`); } tableCellborders(brds) { if (this.options.defineTableCellBorderInfo) return this.idMap.add(brds, "TableCellBorders", [ new ManagerParams("top", () => this.borderInfo(brds.top)), new ManagerParams("right", () => this.borderInfo(brds.right)), new ManagerParams("bottom", () => this.borderInfo(brds.bottom)), new ManagerParams("left", () => this.borderInfo(brds.left)), new ManagerParams("topLeftDiagonal", () => this.borderInfo(brds.topLeftDiagonal)), new ManagerParams("topRightDiagonal", () => this.borderInfo(brds.topRightDiagonal)), ]); else return `new TableCellBorders()`; } tableCellProperties(prop) { if (this.options.defineFullTableCellProperties) return this.idMap.add(prop, "TableCellProperties", [ new ManagerParams("backgroundColor"), new ManagerParams("borders", () => this.tableCellborders(prop.borders)), new ManagerParams("cellMargins", () => this.tableCellMargins(prop.cellMargins)), new ManagerParams("fitText"), new ManagerParams("foreColor"), new ManagerParams("hideCellMark"), new ManagerParams("mask", () => this.asEnum(TableCellPropertiesMask, "TableCellPropertiesMask", prop.mask, TableCellPropertiesMask.UseNone)), new ManagerParams("noWrap"), new ManagerParams("shading"), new ManagerParams("textDirection"), new ManagerParams("verticalAlignment"), ]); else return this.idMap.add(prop, "TableCellProperties", [ new ManagerParams("cellMargins", () => this.tableCellMargins(prop.cellMargins)), new ManagerParams("mask", () => this.asEnum(TableCellPropertiesMask, "TableCellPropertiesMask", prop.mask, TableCellPropertiesMask.UseNone)), ]); } internalTables(c) { const nextLevel = this.subDocument.tablesByLevels[this.table.nestedLevel + 1]; if (nextLevel) { const cellInterval = c.interval; const tbls = ListUtils.reducedMap(nextLevel, (t) => IntervalAlgorithms.getIntersectionNonNullLength(t.interval, cellInterval) ? t : null); if (tbls.length) { this.str.push(`[`); for (let t of tbls) this.fillTable(t.index); this.str.push(`],`); return true; } } this.str.push(`[],`); return false; } mergeLastStrings(num) { this.str.push(this.str.splice(this.str.length - num, num).join(" ")); } tableCells(cells) { for (let c of cells) { this.str.push(`new MockTableCell(`); this.tblCellRuns(c), this.str.push(`${c.columnSpan},`); this.str.push(`TableCellMergingState.${TableCellMergingState[c.verticalMerging]},`); this.mergeLastStrings(4); const intTbls = this.internalTables(c); if (!intTbls) this.mergeLastStrings(2); this.str.push(`${this.tableWidthUnit(c.preferredWidth)},`); this.str.push(`${this.tableCellProperties(c.properties)}),`); this.mergeLastStrings(intTbls ? 2 : 3); } } fillTableRows() { for (let r of this.table.rows) { this.str.push(`new MockTableRow(${r.gridBefore}, ${r.gridAfter}, [`); this.tableCells(r.cells); this.str.push(`],`); this.str.push(`new TableHeightUnit().init(${r.height.value}, TableHeightUnitType.${TableHeightUnitType[r.height.type]}),`); this.str.push(`${this.tableRowProperties(r.properties)},`); this.str.push(`${this.tableWidthUnit(r.widthBefore)},`); this.str.push(`${this.tableWidthUnit(r.widthAfter)},`); this.str.push(`true),`); this.mergeLastStrings(6); } } fillTable(tInd) { const oldInd = this.tblIndex; this.tblIndex = tInd; this.str.push(`new MockTable([`); this.fillTableRows(); this.str.push(`],`); this.str.push(`${this.tableWidthUnit(this.table.preferredWidth)},`); this.str.push(`${this.tableProperties(this.table.properties)},`); this.str.push(`${this.tableLookTypes(this.table.lookTypes)},`); this.str.push(`${this.tableStyle(this.table.style)}),`); this.tblIndex = oldInd; } fillTables() { if (!this.tables.length) return; this.str.push(`new ImposeTableHelper(${this.subDocumentVariableName}, [`); for (let t of this.subDocument.tablesByLevels[0]) this.fillTable(t.index); this.str.push(`]);`); } fillSections() { for (let _s of this.model.sections) this.str.push("new MockSection(0),"); } fillParagraphs() { for (let _p of this.subDocument.paragraphs) this.str.push("new MockParagraph(0, 0, -1, -1),"); } fillChunks() { for (let c of this.subDocument.chunks) { this.str.push("["); this.fillRuns(c); this.str.push("]"); } } size(s) { return `new Size(${s.width}, ${s.height})`; } point(p) { return `new Point(${p.x}, ${p.y})`; } anchorInfo(obj) { return this.idMap.add(obj, `AnchorInfo`, [ new ManagerParams("allowOverlap"), new ManagerParams("topDistance"), new ManagerParams("bottomDistance"), new ManagerParams("leftDistance"), new ManagerParams("rightDistance"), new ManagerParams("hidden"), new ManagerParams("horizontalPositionAlignment"), new ManagerParams("horizontalPositionType"), new ManagerParams("isBehindDoc"), new ManagerParams("layoutTableCell"), new ManagerParams("locked"), new ManagerParams("offset", () => this.point(obj.offset)), new ManagerParams("percentOffset", () => this.point(obj.percentOffset)), new ManagerParams("verticalPositionAlignment"), new ManagerParams("verticalPositionType"), new ManagerParams("wrapSide"), new ManagerParams("wrapType"), new ManagerParams("zOrder"), ]); } shape(s) { return `new Shape(${s.fillColor}, ${s.outlineColor}, ${s.outlineWidth})`; } textBoxProps(props) { return this.idMap.add(props, `new TextBoxProperties(new Margins(${props.leftMargin}, ${props.rightMargin}, ${props.topMargin}, ${props.bottomMargin}))`, [ new ManagerParams("resizeShapeToFitText"), new ManagerParams("upright"), new ManagerParams("verticalAlignment"), new ManagerParams("wrapText"), ]); } fillRuns(c) { for (let r of c.textRuns) { switch (r.getType()) { case RunType.TextRun: { const run = r; this.str.push(`new MockTextRun(0, 0, "${this.escape(c.getTextInChunk(run.startOffset, run.length))}"),`); break; } case RunType.ParagraphRun: { this.str.push("new MockParagraphRun(0, 0),"); break; } case RunType.SectionRun: { this.str.push("new MockSectionRun(0, 0),"); break; } case RunType.AnchoredPictureRun: { const run = r; const size = `new PictureSize(${run.size.lockAspectRatio}, ${run.size.rotation}, ${this.size(run.size.originalSize)}, ${this.size(run.size.scale)})`; this.str.push(`new MockAnchoredPictureRun(0, 0, ${this.shape(run.shape)}, ${run.cacheInfo.currId}, ${size}, ${this.anchorInfo(run.anchorInfo)}, ${run.cacheInfo.isLoaded}),`); break; } case RunType.AnchoredTextBoxRun: { const run = r; const size = `new AnchorTextBoxSize(${run.size.lockAspectRatio}, ${run.size.rotation}, ${this.size(run.size.absoluteSize)}, ${this.size(run.size.relativeSize)}, ${run.size.relativeWidthType}, ${run.size.relativeHeightType}, ${run.size.useAbsoluteWidth()}, ${run.size.useAbsoluteHeight()})`; this.str.push(`new MockAnchoredTextBoxRun(0, 0, ${this.shape(run.shape)}, ${run.subDocId}, ${size}, ${this.anchorInfo(run.anchorInfo)}, ${this.textBoxProps(run.textBoxProperties)}),`); break; } case RunType.FieldCodeEndRun: { this.str.push("new MockFieldCodeEndRun(0, 0),"); break; } case RunType.FieldCodeStartRun: { this.str.push("new MockFieldCodeStartRun(0, 0),"); break; } case RunType.FieldResultEndRun: { this.str.push("new MockFieldResultEndRun(0, 0),"); break; } case RunType.InlinePictureRun: { const run = r; const size = `new PictureSize(${run.size.lockAspectRatio}, ${run.size.rotation}, ${this.size(run.size.originalSize)}, ${this.size(run.size.scale)})`; this.str.push(`new MockInlinePictureRun(0, 0, ${this.shape(run.shape)}, ${run.cacheInfo.currId}, ${size}, ${run.cacheInfo.isLoaded}),`); break; } case RunType.LayoutDependentRun: { this.str.push("new MockLayoutDependentRun(0, 0),"); break; } case RunType.EndNoteRun: case RunType.FootNoteRun: case RunType.NoteSeparatorRun: case RunType.NoteContinuationSeparatorRun: case RunType.Undefined: case RunType.InlineTextBoxRun: default: throw new Error("NotSupportedRun"); } this.str.push(`// [${c.startLogPosition.value + r.startOffset}, ${c.startLogPosition.value + r.startOffset + r.getLength()}]`); this.mergeLastStrings(2); } } pushRectangleProps(prefix, r) { this.str.push(`${prefix}Width: ${r.width},`); this.str.push(`${prefix}Height: ${r.height},`); this.str.push(`${prefix}X: ${r.x},`); this.str.push(`${prefix}Y: ${r.y},`); this.mergeLastStrings(4); } fillPage(page) { this.str.push(`{`); this.pushRectangleProps("page", page); this.str.push(`pageStartPosition: ${page.getPosition()},`); this.str.push(`pageIsContentValid: ${true},`); this.str.push(`pageIsFirstInSection: ${page.flags.get(LayoutPageFlags.IsFirstPageOfSection)},`); this.str.push(`pageCalculateIntervals: ${true},`); this.mergeLastStrings(4); this.str.push(`pagePageAreas: [`); for (let pa of page.mainSubDocumentPageAreas) this.fillPageArea(pa); NumberMapUtils.forEach(page.otherPageAreas, (pa) => this.fillPageArea(pa)); this.str.push(`]},`); } fillPageArea(pa) { this.str.push(`{`); this.pushRectangleProps("pageArea", pa); this.str.push(`pageAreaSubDocument: ${Creator.getSubDocumentVariableName(pa.subDocument)},`); this.str.push(`pageAreaPageOffset: ${pa.pageOffset},`); this.str.push(`pageAreaColumns: [`); this.mergeLastStrings(3); for (let c of pa.columns) this.fillColumn(c); this.str.push(`]},`); } fillColumn(c) { this.str.push(`{`); this.pushRectangleProps("column", c); this.str.push(`columnParagraphFrames: [],`); this.str.push(`columnPageAreaOffset: ${c.pageAreaOffset},`); this.str.push(`columnRows: [`); this.mergeLastStrings(3); for (let r of c.rows) this.fillRow(r); this.str.push(`]},`); } fillRow(r) { this.str.push(`{`); this.pushRectangleProps("row", r); this.str.push(`rowBaseLine: ${r.baseLine},`); this.str.push(`rowSpacingBefore: ${r.getSpacingBefore()},`); this.str.push(`rowSpacingAfter: ${r.getSpacingAfter()},`); this.str.push(`rowNumberingListBox: ${r.numberingListBox},`); this.str.push(`rowColumnOffset: ${r.columnOffset},`); this.mergeLastStrings(5); this.str.push(`rowBoxes: [`); for (let b of r.boxes) this.fillBox(b); this.str.push(`]},`); } fillBox(b) { let str = `{ width: ${b.width}, height: ${b.height}, type: LayoutBoxType.${LayoutBoxType[b.getType()]}, charProp: null, getAscent: () => ${b.getAscent()}, getDescent: () => ${b.getDescent()}`; switch (b.getType()) { case LayoutBoxType.Text: str += `, text: "${this.escape(b.text)}" },`; break; case LayoutBoxType.Dash: str += `, text: "${this.escape(b.text)}" },`; break; case LayoutBoxType.Picture: str += `, id: ${b.cacheInfo.currId} },`; break; case LayoutBoxType.Space: case LayoutBoxType.TabSpace: case LayoutBoxType.LineBreak: case LayoutBoxType.PageBreak: case LayoutBoxType.ColumnBreak: case LayoutBoxType.ParagraphMark: str += ` },`; break; } this.str.push(str); } }