UNPKG

nehan

Version:

Html layout engine for paged-media written in Typescript

133 lines 5.18 kB
import { Config, LayoutOutline, FloatRegion, LogicalCursorPos, LogicalSize, FlowFormatContext, HoriLogicalNodeEvaluator, VertLogicalNodeEvaluator, LogicalCssEvaluator, LogicalTextJustifier, } from './public-api'; export class FlowRootFormatContext extends FlowFormatContext { constructor(env, parent) { super(env, parent); this.env = env; this.parent = parent; this.floatNodes = []; this.pageCount = 0; this.anchors = {}; this.outline = new LayoutOutline(); } get flowRoot() { return this; } getSectionAt(pageIndex) { return this.outline.getSectionAt(pageIndex); } get boxPos() { return { offsetPos: { start: 0, before: 0 }, clientPos: { start: this.contextBoxEdge.borderBoxStartSize, before: this.contextBoxEdge.borderBoxBeforeSize } }; } openElement(element) { this.outline.openElement(element, this.pageCount); } closeElement(element) { this.outline.closeElement(element); } createOutline(evaluator) { return this.outline.acceptEvaluator(evaluator); } createElement(tagName, layoutNames, logicalNode) { const node = document.createElement(tagName); const element = logicalNode.env.element; const originalTagName = element.tagName; const id = logicalNode.env.element.id; const anchor = this.getAnchor(id); if (anchor && !anchor.dom) { anchor.dom = node; } switch (originalTagName) { case "a": const href = element.getAttribute("href"); if (href) { node.setAttribute("href", href); } const name = element.getAttribute("name"); if (name) { node.setAttribute("name", name); } break; } node.className = layoutNames.concat(originalTagName).map(layoutName => `nehan-${layoutName}`).concat(element.classList.values().map(klass => `nehan-e-${klass}`)).join(" "); logicalNode.dom = node; return node; } createLogicalNodeEvaluator() { const cssEvaluator = new LogicalCssEvaluator(this.env.writingMode); switch (this.env.writingMode.value) { case "horizontal-tb": return new HoriLogicalNodeEvaluator(this, cssEvaluator, LogicalTextJustifier.instance); case "vertical-rl": case "vertical-lr": return new VertLogicalNodeEvaluator(this, cssEvaluator, LogicalTextJustifier.instance); default: throw new Error(`undefined writing mode: ${this.env.writingMode.value}`); } } setAnchor(name, anchor) { this.anchors[name] = anchor; } getAnchor(name) { return this.anchors[name]; } getHeaderSection(element) { return this.outline.getHeaderSection(element); } clearFloat(clear) { if (!this.floatRegion) { throw new Error("float region is not defined"); } if (clear.isStart()) { return this.floatRegion.clearStart(); } if (clear.isEnd()) { return this.floatRegion.clearEnd(); } if (clear.isBoth()) { return this.floatRegion.clearBoth(); } throw new Error("clear direction is not defined"); } addFloat(block, float, contextMeasure, flowRootPos) { if (float.isNone()) { console.error("float direction is not set! ignored."); return; } if (!this.floatRegion) { const regionSize = new LogicalSize({ measure: this.maxMeasure, extent: this.maxExtent }); this.floatRegion = new FloatRegion(regionSize, flowRootPos.before); } try { if (Config.debugLayout) { console.log("addFloat(%o, %o, ctxM:%d, flowRootPos:%o)", block, float, contextMeasure, flowRootPos); } const floatSize = new LogicalSize({ measure: block.size.measure + block.env.edge.measure, extent: block.size.extent + block.env.edge.extent }); const rect = float.isStart() ? this.floatRegion.pushStart(flowRootPos.before, floatSize, contextMeasure) : this.floatRegion.pushEnd(flowRootPos.before, floatSize, contextMeasure); const start = float.isStart() ? flowRootPos.start : rect.start + block.env.edge.start; block.layoutPos = new LogicalCursorPos({ start, before: rect.before }); this.floatNodes.push(block); if (Config.debugLayout) { console.log("added float. rect:%o, pos:%o", rect, block.layoutPos); console.log("spaceMeasure at %d = %d", block.layoutPos.before, this.floatRegion.getSpaceMeasureAt(block.layoutPos.before)); } } catch (err) { console.error(err); } } } //# sourceMappingURL=flow-root-format-context.js.map