nehan
Version:
Html layout engine for paged-media written in Typescript
140 lines • 4.91 kB
JavaScript
import { LayoutSection, LayoutOutlineParser, } from "./public-api";
export class LayoutOutline {
constructor() {
this.headers = {};
this.rootSection = new LayoutSection();
this.curSection = this.rootSection;
}
getSectionAt(pageIndex) {
const children = this.rootSection.children;
let prev = this.rootSection;
for (let i = 0; i < children.length; i++) {
const child = children[i];
const section = child.getClosestSectionByPageIndex(pageIndex, prev);
if (section.pageIndex === pageIndex) {
return section;
}
if (section.pageIndex > pageIndex) {
return prev;
}
prev = section;
}
return prev;
}
acceptEvaluator(visitor) {
return visitor.visitSectionRoot(this.rootSection);
}
createElement(callbacks) {
return LayoutOutlineParser.parseSection(this.rootSection, callbacks);
}
openElement(element, pageIndex) {
if (LayoutSection.isSectioningRootElement(element)) {
return this.openSectionRoot(element, pageIndex);
}
if (LayoutSection.isSectioningElement(element)) {
return this.openSection(pageIndex);
}
if (LayoutSection.isHeaderElement(element)) {
return this.openHeader(element, pageIndex);
}
return undefined;
}
closeElement(element) {
if (element && LayoutSection.isSectioningElement(element) === false) {
return this.curSection;
}
return this.closeSection();
}
getHeaderSection(element) {
return this.headers[element.getPath(true)];
}
openSectionRoot(element, pageIndex) {
if (!this.rootElement) {
return this.curSection;
}
this.rootElement = element;
return this.openSection(pageIndex);
}
openSection(pageIndex) {
if (this.curSection.closed) {
this.curSection = this.createNextSection(pageIndex);
}
else {
this.curSection = this.createSubSection(pageIndex);
}
return this.curSection;
}
closeSection() {
const before = this.curTitle;
if (this.curSection.parent) {
this.curSection = this.curSection.parent;
}
return this.curSection;
}
openHeader(element, pageIndex) {
this.curSection = this.addHeader(element, pageIndex);
return this.curSection;
}
get curTitle() {
let closeState = this.curSection.closed ? "(closed)" : "(open)";
return this.curSection.title + closeState;
}
createContextSection(pageIndex, header) {
let section = new LayoutSection(header);
section.pageIndex = header ? -1 : pageIndex;
if (header) {
this.headers[header.getPath(true)] = section;
}
return section;
}
createStandAloneSubSection(pageIndex, header) {
const section = this.createContextSection(pageIndex, header);
section.closed = true;
this.curSection.addChild(section);
return section;
}
createSubSection(pageIndex, header) {
const section = this.createContextSection(pageIndex, header);
this.curSection.addChild(section);
return section;
}
createNextSection(pageIndex, header) {
const section = this.createContextSection(pageIndex, header);
const rootSection = this.closeSection();
rootSection.addChild(section);
return section;
}
closeHigherSection(section, maxLevel) {
if (!section.parent || !section.parent.parent || section.level <= maxLevel) {
return section;
}
section.closed = true;
return this.closeHigherSection(section.parent, maxLevel);
}
createHigherSection(pageIndex, header, max_level) {
if (this.curSection.parent) {
this.curSection = this.closeHigherSection(this.curSection.parent, max_level);
}
return this.createNextSection(pageIndex, header);
}
addHeader(header, pageIndex) {
if (!this.curSection.header) {
if (!this.curSection.parent) {
return this.createSubSection(pageIndex, header);
}
this.curSection.setHeader(header);
return this.curSection;
}
const curLevel = this.curSection.level;
const newLevel = LayoutSection.getHeaderLevel(header);
if (newLevel > curLevel) {
return this.createStandAloneSubSection(pageIndex, header);
}
if (newLevel === curLevel) {
return this.createNextSection(pageIndex, header);
}
this.curSection.closed = true;
return this.createHigherSection(pageIndex, header, newLevel);
}
}
//# sourceMappingURL=layout-outline.js.map