UNPKG

2.2 MBSource Map (JSON)View Raw
1{"version":3,"file":"vivliostyle.js","sources":["../../src/vivliostyle/constants.ts","../../src/vivliostyle/logging.ts","../../src/vivliostyle/plugin.ts","../../src/vivliostyle/profile.ts","../../src/vivliostyle/base.ts","../../src/vivliostyle/cfi.ts","../../src/vivliostyle/exprs.ts","../../src/vivliostyle/css.ts","../../src/vivliostyle/geometry-util.ts","../../src/vivliostyle/css-prop.ts","../../src/vivliostyle/counters.ts","../../src/vivliostyle/css-tokenizer.ts","../../src/vivliostyle/task.ts","../../src/vivliostyle/task-util.ts","../../src/vivliostyle/net.ts","../../src/vivliostyle/css-parser.ts","../../src/vivliostyle/matchers.ts","../../src/vivliostyle/css-cascade.ts","../../src/vivliostyle/css-logical-util.ts","../../src/vivliostyle/sizing.ts","../../../../node_modules/fast-diff/diff.js","../../src/vivliostyle/types.ts","../../src/vivliostyle/diff.ts","../../src/vivliostyle/vtree.ts","../../src/vivliostyle/page-floats.ts","../../src/vivliostyle/footnotes.ts","../../src/vivliostyle/break.ts","../../src/vivliostyle/layout-helper.ts","../../src/vivliostyle/break-position.ts","../../src/vivliostyle/display.ts","../../src/vivliostyle/layout-processor.ts","../../src/vivliostyle/layout-retryers.ts","../../src/vivliostyle/layout-util.ts","../../src/vivliostyle/shared.ts","../../src/vivliostyle/pseudo-element.ts","../../src/vivliostyle/layout.ts","../../src/vivliostyle/repetitive-element.ts","../../src/vivliostyle/table.ts","../../src/vivliostyle/math-util.ts","../../src/vivliostyle/columns.ts","../../src/vivliostyle/css-styler.ts","../../src/vivliostyle/css-validator.ts","../../src/vivliostyle/font.ts","../../src/vivliostyle/page-master.ts","../../src/vivliostyle/css-page.ts","../../src/vivliostyle/urls.ts","../../src/vivliostyle/vgen.ts","../../src/vivliostyle/xml-doc.ts","../../src/vivliostyle/ops.ts","../../src/vivliostyle/sha1.ts","../../src/vivliostyle/toc.ts","../../src/vivliostyle/epub.ts","../../src/vivliostyle/adaptive-viewer.ts","../../src/vivliostyle/core-viewer.ts","../../src/vivliostyle/print.ts"],"sourcesContent":["/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Constants\n */\n\n/**\n * Debug flag.\n */\nexport let isDebug: boolean = false;\nexport function setDebug(value: boolean): void {\n isDebug = value;\n}\n\n/**\n * Page progression direction.\n * @enum {string}\n */\nexport enum PageProgression {\n LTR = \"ltr\",\n RTL = \"rtl\",\n}\n\n/**\n * Return PageProgression corresponding to the specified string\n */\nexport function pageProgressionOf(str: string): PageProgression {\n switch (str) {\n case \"ltr\":\n return PageProgression.LTR;\n case \"rtl\":\n return PageProgression.RTL;\n default:\n throw new Error(`unknown PageProgression: ${str}`);\n }\n}\n\n/**\n * Page side (left/right).\n * @enum {string}\n */\nexport enum PageSide {\n LEFT = \"left\",\n RIGHT = \"right\",\n}\n\n/**\n * Viewer ready state.\n * @enum {string}\n */\nexport enum ReadyState {\n LOADING = \"loading\",\n INTERACTIVE = \"interactive\",\n COMPLETE = \"complete\",\n}\n\n/**\n * Pubilc members of the bundled library.\n */\nexport const constants = {\n PageProgression,\n PageSide,\n ReadyState,\n};\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Logging - Logging utility\n */\n\n/**\n * Log level.\n * @enum {number}\n */\nexport enum LogLevel {\n DEBUG = 1,\n INFO,\n WARN,\n ERROR,\n}\n\nexport type ErrorInfo = {\n error: Error;\n messages: any[];\n};\n\n/**\n * Class logging error, warning, information or debug messages.\n */\nexport class Logger {\n private listeners: { [key in LogLevel]?: ((p1: ErrorInfo) => void)[] } = {};\n\n constructor(private opt_console?: Console) {}\n\n private consoleDebug(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.debug) {\n this.opt_console.debug(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.debug(...msg); // eslint-disable-line no-console\n }\n }\n\n private consoleInfo(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.info) {\n this.opt_console.info(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.info(...msg); // eslint-disable-line no-console\n }\n }\n\n private consoleWarn(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.warn) {\n this.opt_console.warn(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.warn(...msg); // eslint-disable-line no-console\n }\n }\n\n private consoleError(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.error) {\n this.opt_console.error(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.error(...msg); // eslint-disable-line no-console\n }\n }\n\n private triggerListeners(level: LogLevel, args: ErrorInfo) {\n const listeners = this.listeners[level];\n if (listeners) {\n listeners.forEach((listener) => {\n listener(args);\n });\n }\n }\n\n /**\n * Add a listener function invoked when a log event with the specified level\n * occurs.\n */\n addListener(level: LogLevel, listener: (p1: ErrorInfo) => void) {\n let listeners = this.listeners[level];\n if (!listeners) {\n listeners = this.listeners[level] = [];\n }\n listeners.push(listener);\n }\n\n debug(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleDebug(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.DEBUG, args);\n }\n\n info(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleInfo(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.INFO, args);\n }\n\n warn(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleWarn(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.WARN, args);\n }\n\n error(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleError(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.ERROR, args);\n }\n}\n\n/**\n * @param args\n */\nfunction argumentsToErrorInfo(args: IArguments): ErrorInfo {\n const a = Array.from(args);\n let e: Error = null;\n if (a[0] instanceof Error) {\n e = a.shift();\n }\n return { error: e, messages: a };\n}\n\nfunction buildMessageAndStackTrace(args: ErrorInfo): string[] {\n const e = args.error;\n const stack = e && (e[\"frameTrace\"] || e[\"stack\"]);\n let messages = [].concat(args[\"messages\"]);\n if (e) {\n if (messages.length > 0) {\n messages = messages.concat([\"\\n\"]);\n }\n messages = messages.concat([e[\"toString\"]()]);\n if (stack) {\n messages = messages.concat([\"\\n\"]).concat(stack);\n }\n }\n return messages;\n}\n\nexport const logger = new Logger();\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Plugin - Plugin mechanism\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as Logging from \"./logging\";\nimport * as Task from \"./task\";\nimport { Layout, Vtree } from \"./types\";\n\n/**\n * Type of implemented hooks.\n * @enum {string}\n */\nexport enum HOOKS {\n /**\n * Called when a single property declaration is parsed.\n *\n * The hook is called with an object with the following properties:\n * {string} name: Property name\n * {!Css.Val} value: Property value\n * {boolean} important: Whether '!important' flag is present or not\n * Functions called by this hook are expected to return a value with the same\n * type as the above. The declaration is then replaced by the returned value.\n *\n * Note that a shorthand declaration is not directly passed to this hook.\n * After the shorthand declaration is interpreted and broken into\n * non-shorthand declarations, the hook is called for each of the\n * non-shorthand declarations.\n */\n SIMPLE_PROPERTY = \"SIMPLE_PROPERTY\",\n\n /**\n * Called when a single document (i.e. a single spine item) has been fetched,\n * before parsing.\n *\n * The hook is called with the Document object.\n */\n PREPROCESS_SINGLE_DOCUMENT = \"PREPROCESS_SINGLE_DOCUMENT\",\n\n /**\n * Called before creating a text node for modifying a text content.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n * {string} sourceTextContent\n *\n * Functions called by this hook are expected to return a\n * Task.Result.<string>. The text content is then replaced by the\n * returned value.\n */\n PREPROCESS_TEXT_CONTENT = \"PREPROCESS_TEXT_CONTENT\",\n\n /**\n * Called before creating a element for modifying a element style.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n * {!Object} style\n */\n PREPROCESS_ELEMENT_STYLE = \"PREPROCESS_ELEMENT_STYLE\",\n\n /**\n * Called before geting CssCascade.polyfilledInheritedProps.\n *\n * The hook return a array of polyfilled inherited property name.\n */\n POLYFILLED_INHERITED_PROPS = \"POLYFILLED_INHERITED_PROPS\",\n\n /**\n * Called when a Viewer is configured.\n *\n * The hook is called with an object with the following properties:\n * {Base.JSON} command\n */\n CONFIGURATION = \"CONFIGURATION\",\n\n /**\n * Called when resolving a text node breaker\n * which detects an acceptable breakpoint and break text node at this point.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n *\n * Functions called by this hook are expected to\n * return an instnce of {Layout.TextNodeBreaker} or null.\n */\n RESOLVE_TEXT_NODE_BREAKER = \"RESOLVE_TEXT_NODE_BREAKER\",\n\n /**\n * Called when resolving a formatting context.\n *\n * The hook is called with the following parameters:\n * nodeContext: a NodeContext object\n * firstTime: a boolean flag representing whether this node is encountered\n * for the first time or not display: an Css.Ident value representing\n * 'display' value of the node position: an Css.Ident value representing\n * 'position' value of the node float: an Css.Ident value representing\n * 'float' value of the node isRoot: a boolean flag representing whether this\n * node is a root (of a flow) or not Functions called by this hook are\n * expected to return a formatting context for the NodeContext.\n */\n RESOLVE_FORMATTING_CONTEXT = \"RESOLVE_FORMATTING_CONTEXT\",\n\n /**\n * Called when resolving a layout processor (LayoutProcessor) for\n * a formatting context.\n *\n * The hook is called with a formatting context\n * (Vtree.FormattingContext). Functions called by this hook are expected\n * to return a layout processor corresponding to the formatting context.\n */\n RESOLVE_LAYOUT_PROCESSOR = \"RESOLVE_LAYOUT_PROCESSOR\",\n\n /**\n * Called after laid out a block contents.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n * {Array.<Vtree.NodeContext>} checkPoints\n * {Layout.Column} column\n */\n POST_LAYOUT_BLOCK = \"POST_LAYOUT_BLOCK\",\n}\n\nexport type PreProcessSingleDocumentHook = (p1: Document) => any;\n\nexport type PreProcessTextContentHook = (\n p1: Vtree.NodeContext,\n p2: string,\n) => Task.Result<string>;\n\nexport type PreProcessElementStyleHook = (\n p1: Vtree.NodeContext,\n p2: object,\n) => void;\n\nexport type PolyfilledInheritedPropsHook = () => string[];\n\nexport type ConfigurationHook = (\n p1: Base.JSON,\n) => {\n needResize: boolean | null | undefined;\n needRefresh: boolean | null | undefined;\n};\n\nexport type ResolveTextNodeBreakerHook = (\n p1: Vtree.NodeContext,\n) => Layout.TextNodeBreaker;\n\nexport type ResolveFormattingContextHook = (\n p1: Vtree.NodeContext,\n p2: boolean,\n p3: Css.Ident,\n p4: Css.Ident,\n p5: Css.Ident,\n p6: boolean,\n) => Vtree.FormattingContext;\n\nexport type ResolveLayoutProcessorHook = (\n p1: Vtree.FormattingContext,\n) => LayoutProcessor.LayoutProcessor;\n\nexport type PostLayoutBlockHook = (\n p1: Vtree.NodeContext,\n p2: Vtree.NodeContext[],\n p3: Layout.Column,\n) => void;\n\nconst hooks = {};\n\n/**\n * Register a function to a hook with the specified name.\n * The registered function is called at appropriate timings by the core code.\n * Arguments passed to the function depend on the hook.\n * When multiple functions are registered, they are called by the order in which\n * they are registered.\n * @param name Name of the hook.\n * @param fn Function to be registered to the hook.\n */\nexport function registerHook(name: string, fn: (...p1) => any): void {\n if (!HOOKS[name]) {\n Logging.logger.warn(new Error(`Skipping unknown plugin hook '${name}'.`));\n } else {\n let hooksForName = hooks[name];\n if (!hooksForName) {\n hooksForName = hooks[name] = [];\n }\n hooksForName.push(fn);\n }\n}\n\n/**\n * Remove a function already registered to the specified name.\n * Note that even if the same function are registered multiple times, this\n * method removes only the first one.\n * @param name Name of the hook.\n * @param fn Function to be removed from the hook.\n */\nexport function removeHook(name: string, fn: (...p1) => any): void {\n if (!HOOKS[name]) {\n Logging.logger.warn(new Error(`Ignoring unknown plugin hook '${name}'.`));\n } else {\n const hooksForName = hooks[name];\n if (hooksForName) {\n const index = hooksForName.indexOf(fn);\n if (index >= 0) {\n hooksForName.splice(index, 1);\n }\n }\n }\n}\n\n/**\n * Get all hooks registered to the specified name.\n * This method is for internal use (from the core code).\n */\nexport function getHooksForName(name: string): ((...p1) => any)[] {\n const hooksForName = hooks[name];\n return hooksForName || [];\n}\n\n/**\n * Pubilc members of the bundled library.\n */\nexport const plugin = {\n registerHook,\n removeHook,\n};\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Profile - Utility for profiling\n */\nimport * as Logging from \"./logging\";\n\n/**\n * Performance profiler measuring execution time of the script.\n */\nexport class Profiler {\n timestamps: { [key: string]: { [key: string]: number } } = {};\n private registerTiming: (p1: string, p2: string, p3?: number) => any;\n registerStartTiming: (name: string, timestamp?: number) => any;\n registerEndTiming: (name: string, timestamp?: number) => any;\n\n constructor(public readonly performanceInstance: Performance) {\n this.registerTiming = noop;\n\n // hack to export (non-prototype) methods\n this[\"registerStartTiming\"] = this.registerStartTiming = noop;\n this[\"registerEndTiming\"] = this.registerEndTiming = noop;\n }\n\n /**\n * Registers start timing of some event, even if profile is disabled.\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\n forceRegisterStartTiming(name: string, timestamp?: number) {\n registerTiming.call(this, name, \"start\", timestamp);\n }\n\n /**\n * Registers end timing of some event, even if profile is disabled.\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\n forceRegisterEndTiming(name: string, timestamp?: number) {\n registerTiming.call(this, name, \"end\", timestamp);\n }\n\n /**\n * Log registered timings (start/end/duration).\n * All values are printed in ms unit.\n */\n printTimings() {\n const timestamps = this.timestamps;\n let st = \"\";\n Object.keys(timestamps).forEach((name) => {\n const stamps = timestamps[name];\n const l = stamps.length;\n for (let i = 0; i < l; i++) {\n const t = stamps[i];\n st += name;\n if (l > 1) {\n st += `(${i})`;\n }\n st += ` => start: ${t[\"start\"]}, end: ${t[\"end\"]}, duration: ${t[\n \"end\"\n ] - t[\"start\"]}\\n`;\n }\n });\n Logging.logger.info(st);\n }\n\n /**\n * Disable profiling.\n */\n disable() {\n this.registerTiming = noop;\n\n // hack to export (non-prototype) methods\n this[\"registerStartTiming\"] = this.registerStartTiming = noop;\n this[\"registerEndTiming\"] = this.registerEndTiming = noop;\n }\n\n /**\n * Enable profiling.\n */\n enable() {\n this.registerTiming = registerTiming;\n\n // hack to export (non-prototype) methods\n this[\n \"registerStartTiming\"\n ] = this.registerStartTiming = registerStartTiming;\n this[\"registerEndTiming\"] = this.registerEndTiming = registerEndTiming;\n }\n\n /**\n * Returns if profiling is enabled or not.\n */\n isEnabled(): boolean {\n return this.registerStartTiming === registerStartTiming;\n }\n}\n\nfunction noop(): void {}\n\n/**\n * Registers start/end timing of some event.\n * @this {Profile.Profiler}\n * @param name Name of event\n * @param startEnd Either of \"start\" or \"end\"\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\nfunction registerTiming(\n name: string,\n startEnd: string,\n timestamp?: number,\n): void {\n if (!timestamp) {\n timestamp = this.performanceInstance.now();\n }\n let timestamps = this.timestamps[name];\n if (!timestamps) {\n timestamps = this.timestamps[name] = [];\n }\n let t;\n const l = timestamps.length;\n for (let i = l - 1; i >= 0; i--) {\n t = timestamps[i];\n if (t && !t[startEnd]) {\n break;\n }\n t = null;\n }\n if (!t) {\n t = {};\n timestamps.push(t);\n }\n t[startEnd] = timestamp;\n}\n\n/**\n * Registers start timing of some event.\n * @this {Profile.Profiler}\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\nfunction registerStartTiming(name: string, timestamp?: number): void {\n this.registerTiming(name, \"start\", timestamp);\n}\n\n/**\n * Registers end timing of some event.\n * @this {Profile.Profiler}\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\nfunction registerEndTiming(name: string, timestamp?: number): void {\n this.registerTiming(name, \"end\", timestamp);\n}\nconst fallbackPerformanceInstance = { now: Date.now } as Performance;\nconst performanceInstance = window && window.performance;\nexport const profiler = new Profiler(\n performanceInstance || fallbackPerformanceInstance,\n);\nprofiler.forceRegisterStartTiming(\"load_vivliostyle\");\n\n/**\n * Pubilc members of the bundled library.\n */\nexport const profile = {\n profiler: {\n registerStartTiming: profiler.registerStartTiming,\n registerEndTiming: profiler.registerEndTiming,\n printTimings: profiler.printTimings,\n disable: profiler.disable,\n enable: profiler.enable,\n },\n};\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Base - Common utilities.\n */\nimport * as Logging from \"./logging\";\nimport * as Asserts from \"./asserts\";\n\nexport let emptyObj = {};\n\nexport type JSON = any;\n\nexport function jsonToString(json: JSON): string {\n return JSON.stringify(json);\n}\n\nexport function stringToJSON(str: string): JSON {\n return JSON.parse(str);\n}\n\nexport function stripFragment(url: string): string {\n const r = url.match(/^([^#]*)/);\n if (r) {\n return r[1];\n }\n return url;\n}\n\nexport function stripFragmentAndQuery(url: string): string {\n const r = url.match(/^([^#?]*)/);\n if (r) {\n return r[1];\n }\n return url;\n}\n\n/**\n * Base URL relative to which URLs of resources are resolved.\n */\nexport let baseURL = window.location.href;\nexport function setBaseURL(value: string): void {\n baseURL = value;\n}\n\n/**\n * Base URL relative to which URLs of resources such as validation.txt and\n * user-agent.css are resolved.\n */\nexport let resourceBaseURL = window.location.href;\nexport function setResourceBaseURL(value: string): void {\n resourceBaseURL = value;\n}\n\n/**\n * @param relURL relative URL\n * @param baseURL base (absolute) URL\n * @return resolved (absolute) URL\n */\nexport function resolveURL(relURL: string, baseURL: string): string {\n if (baseURL.startsWith(\"data:\")) {\n return relURL || baseURL;\n }\n if (!baseURL || relURL.match(/^\\w{2,}:/)) {\n if (relURL.toLowerCase().match(\"^javascript:\")) {\n return \"#\";\n }\n if (relURL.match(/^\\w{2,}:\\/\\/[^\\/]+$/)) {\n relURL = `${relURL}/`;\n }\n return relURL;\n }\n if (baseURL.match(/^\\w{2,}:\\/\\/[^\\/]+$/)) {\n baseURL = `${baseURL}/`;\n }\n let r: string[];\n if (relURL.match(/^\\/\\//)) {\n r = baseURL.match(/^(\\w{2,}:)\\/\\//);\n if (r) {\n return r[1] + relURL;\n }\n return relURL;\n }\n if (relURL.match(/^\\//)) {\n r = baseURL.match(/^(\\w{2,}:\\/\\/[^\\/]+)\\//);\n if (r) {\n return r[1] + relURL;\n }\n return relURL;\n }\n if (relURL.match(/^\\.(\\/|$)/)) {\n relURL = relURL.substr(2); // './foo' => 'foo'\n }\n baseURL = stripFragmentAndQuery(baseURL);\n if (relURL.match(/^#/)) {\n return baseURL + relURL;\n }\n let i = baseURL.lastIndexOf(\"/\");\n if (i < 0) {\n return relURL;\n }\n if (i < baseURL.length - 1) {\n const j = baseURL.lastIndexOf(\".\");\n if (j < i) {\n // Assume the last part without '.' to be a directory name.\n if (relURL == \"\") {\n return baseURL;\n }\n baseURL += \"/\";\n i = baseURL.length - 1;\n }\n }\n let url = baseURL.substr(0, i + 1) + relURL;\n let urlOption = \"\";\n r = url.match(/^([^?#]*)([?#].*)$/);\n if (r) {\n url = r[1];\n urlOption = r[2];\n }\n\n while (true) {\n i = url.indexOf(\"/../\");\n if (i <= 0) {\n break;\n }\n const j = url.lastIndexOf(\"/\", i - 1);\n if (j <= 0) {\n break;\n }\n url = url.substr(0, j) + url.substr(i + 3);\n }\n return url.replace(/\\/(\\.\\/)+/g, \"/\") + urlOption;\n}\n\n/**\n * @return converted URL\n */\nexport function convertSpecialURL(url: string): string {\n let r: RegExpMatchArray;\n if (\n (r = /^(https?:)\\/\\/github\\.com\\/([^/]+\\/[^/]+)\\/(blob\\/|tree\\/|raw\\/)?(.*)$/.exec(\n url,\n ))\n ) {\n // Convert GitHub URL to GitHub raw URL\n url = `${r[1]}//raw.githubusercontent.com/${r[2]}/${r[3] ? \"\" : \"master/\"}${\n r[4]\n }`;\n } else if (\n (r = /^(https?:)\\/\\/www\\.aozora\\.gr\\.jp\\/(cards\\/[^/]+\\/files\\/[^/.]+\\.html)$/.exec(\n url,\n ))\n ) {\n // Convert Aozorabunko (X)HTML URL to GitHub raw URL\n url = `${r[1]}//raw.githubusercontent.com/aozorabunko/aozorabunko/master/${r[2]}`;\n } else if (\n (r = /^(https?:)\\/\\/gist\\.github\\.com\\/([^/]+\\/\\w+)(\\/|$)(raw(\\/|$))?(.*)$/.exec(\n url,\n ))\n ) {\n // Convert Gist URL to Gist raw URL\n url = `${r[1]}//gist.githubusercontent.com/${r[2]}/raw/${r[6]}`;\n } else if (\n (r = /^(https?:)\\/\\/(?:[^/.]+\\.)?jsbin\\.com\\/(?!(?:blog|help)\\b)(\\w+)((\\/\\d+)?).*$/.exec(\n url,\n ))\n ) {\n // Convert JS Bin URL to JS Bin output URL\n url = `${r[1]}//output.jsbin.com/${r[2]}${r[3]}/`;\n }\n return url;\n}\n\nexport interface DocumentURLTransformer {\n transformFragment(fragment: string, baseURL: string): string;\n\n transformURL(url: string, baseURL: string): string;\n\n restoreURL(encoded: string): string[];\n}\n\n/**\n * Various namespaces.\n * @enum {string}\n */\nexport enum NS {\n FB2 = \"http://www.gribuser.ru/xml/fictionbook/2.0\",\n epub = \"http://www.idpf.org/2007/ops\",\n EV = \"http://www.w3.org/2001/xml-events\",\n MATHML = \"http://www.w3.org/1998/Math/MathML\",\n XML = \"http://www.w3.org/XML/1998/namespace\",\n XHTML = \"http://www.w3.org/1999/xhtml\",\n XLINK = \"http://www.w3.org/1999/xlink\",\n SHADOW = \"http://www.pyroxy.com/ns/shadow\",\n SVG = \"http://www.w3.org/2000/svg\",\n DC = \"http://purl.org/dc/elements/1.1/\",\n NCX = \"http://www.daisy.org/z3986/2005/ncx/\",\n SSE = \"http://example.com/sse\", // temporary dummy namespace\n}\n\n/**\n * @param name parameter name\n * @param opt_url URL; window.location.href is used if not provided\n * @return parameter value\n */\nexport function getURLParam(name: string, opt_url?: string): string | null {\n const rg = new RegExp(`#(.*&)?${escapeRegExp(name)}=([^#&]*)`);\n const url = opt_url || window.location.href;\n const r = url.match(rg);\n if (r) {\n return r[2];\n }\n return null;\n}\n\n/**\n * @param name parameter name\n * @param value parameter value\n * @return new url\n */\nexport function setURLParam(url: string, name: string, value: string): string {\n const rg = new RegExp(`#(.*&)?${escapeRegExp(name)}=([^#&]*)`);\n const r = url.match(rg);\n if (r) {\n const length = r[2].length;\n const index = r.index + r[0].length - length;\n return url.substr(0, index) + value + url.substr(index + length);\n }\n if (!url.match(/#/)) {\n return `${url}#${name}=${value}`;\n } else {\n return `${url}&${name}=${value}`;\n }\n}\n\n/**\n * @return ?string\n */\nexport function asString(v: any): any {\n if (v == null) {\n return v;\n }\n return v.toString();\n}\n\nexport interface Comparable {\n /**\n * @return -1 when this less then other, 0 when this equals other\n */\n compare(other: Comparable): number;\n}\n\n/**\n * A priority queue.\n */\nexport class PriorityQueue {\n queue: Comparable[] = [null];\n\n length(): number {\n return this.queue.length - 1;\n }\n\n add(item: Comparable): void {\n let index = this.queue.length;\n while (index > 1) {\n const parentIndex = Math.floor(index / 2);\n const parent = this.queue[parentIndex];\n if (parent.compare(item) > 0) {\n this.queue[index] = item;\n return;\n }\n this.queue[index] = parent;\n index = parentIndex;\n }\n this.queue[1] = item;\n }\n\n /**\n * @return highest priority Comparable.\n */\n peek(): Comparable {\n return this.queue[1];\n }\n\n /**\n * Remove the highest-priority item from the queue.\n * @return removed item.\n */\n remove(): Comparable {\n const result = this.queue[1] as Comparable;\n const curr = this.queue.pop() as Comparable;\n const size = this.queue.length;\n if (size > 1) {\n let index = 1;\n while (true) {\n let childIndex = index * 2;\n if (childIndex >= size) {\n break;\n }\n if (this.queue[childIndex].compare(curr) > 0) {\n if (\n childIndex + 1 < size &&\n this.queue[childIndex + 1].compare(\n this.queue[childIndex] as Comparable,\n ) > 0\n ) {\n childIndex++;\n }\n } else if (\n childIndex + 1 < size &&\n this.queue[childIndex + 1].compare(curr) > 0\n ) {\n childIndex++;\n } else {\n break;\n }\n this.queue[index] = this.queue[childIndex];\n index = childIndex;\n }\n this.queue[index] = curr;\n }\n return result;\n }\n}\n\n/**\n * @param prefix Prefix (containing leading and trailing hyphens)\n * @param cssPropName CSS property name\n * @return JavaScript property name\n */\nexport function cssToJSProp(prefix: string, cssPropName: string): string {\n if (prefix) {\n cssPropName = `-${cssPropName}`;\n prefix = prefix.replace(/-/g, \"\");\n if (prefix === \"moz\") {\n prefix = \"Moz\";\n }\n }\n return (\n prefix +\n cssPropName.replace(/-[a-z]/g, (txt) => txt.substr(1).toUpperCase())\n );\n}\n\nexport const knownPrefixes = [\"\", \"-webkit-\", \"-moz-\", \"-ms-\", \"-o-\", \"-epub-\"];\n\nexport const propNameMap = {};\n\nexport function checkIfPropertySupported(\n prefix: string,\n prop: string,\n): boolean {\n // Special case\n if (prop === \"writing-mode\") {\n const probe = document.createElement(\"span\");\n if (prefix === \"-ms-\") {\n probe.style.setProperty(prefix + prop, \"tb-rl\");\n return probe.style[\"writing-mode\"] === \"tb-rl\";\n } else {\n probe.style.setProperty(prefix + prop, \"vertical-rl\");\n return probe.style[prefix + prop] === \"vertical-rl\";\n }\n } else {\n const style = document.documentElement.style;\n return typeof style[cssToJSProp(prefix, prop)] === \"string\";\n }\n}\n\nexport function getPrefixedPropertyNames(prop: string): string[] | null {\n let prefixed = propNameMap[prop];\n if (prefixed || prefixed === null) {\n // null means the browser does not support the property\n return prefixed;\n }\n switch (prop) {\n case \"text-combine-upright\":\n // Special case for Safari\n if (\n checkIfPropertySupported(\"-webkit-\", \"text-combine\") &&\n !checkIfPropertySupported(\"\", \"text-combine-upright\")\n ) {\n propNameMap[prop] = [\"-webkit-text-combine\"];\n return [\"-webkit-text-combine\"];\n }\n break;\n case \"writing-mode\":\n // Special case: prefer '-ms-writing-mode' to 'writing-mode'\n if (checkIfPropertySupported(\"-ms-\", \"writing-mode\")) {\n propNameMap[prop] = [\"-ms-writing-mode\"];\n return [\"-ms-writing-mode\"];\n }\n break;\n case \"filter\":\n // Special case: prefer '-webkit-filter' to 'filter'\n if (checkIfPropertySupported(\"-webkit-\", \"filter\")) {\n propNameMap[prop] = [\"-webkit-filter\"];\n return [\"-webkit-filter\"];\n }\n break;\n case \"clip-path\":\n // Special case for chrome.\n if (checkIfPropertySupported(\"-webkit-\", \"clip-path\")) {\n return (propNameMap[prop] = [\"-webkit-clip-path\", \"clip-path\"]);\n }\n break;\n case \"margin-inline-start\":\n if (checkIfPropertySupported(\"-webkit-\", \"margin-start\")) {\n propNameMap[prop] = [\"-webkit-margin-start\"];\n return [\"-webkit-margin-start\"];\n }\n break;\n case \"margin-inline-end\":\n if (checkIfPropertySupported(\"-webkit-\", \"margin-end\")) {\n propNameMap[prop] = [\"-webkit-margin-end\"];\n return [\"-webkit-margin-end\"];\n }\n break;\n case \"padding-inline-start\":\n if (checkIfPropertySupported(\"-webkit-\", \"padding-start\")) {\n propNameMap[prop] = [\"-webkit-padding-start\"];\n return [\"-webkit-padding-start\"];\n }\n break;\n case \"padding-inline-end\":\n if (checkIfPropertySupported(\"-webkit-\", \"padding-end\")) {\n propNameMap[prop] = [\"-webkit-padding-end\"];\n return [\"-webkit-padding-end\"];\n }\n break;\n }\n for (const prefix of knownPrefixes) {\n if (checkIfPropertySupported(prefix, prop)) {\n prefixed = prefix + prop;\n propNameMap[prop] = [prefixed];\n return [prefixed];\n }\n }\n\n // Not supported by the browser\n Logging.logger.warn(\"Property not supported by the browser: \", prop);\n propNameMap[prop] = null;\n return null;\n}\n\nexport function setCSSProperty(\n elem: Element,\n prop: string,\n value: string,\n): void {\n try {\n const prefixedPropertyNames = getPrefixedPropertyNames(prop);\n if (!prefixedPropertyNames) {\n return;\n }\n prefixedPropertyNames.forEach((prefixed) => {\n if (prefixed === \"-ms-writing-mode\") {\n switch (value) {\n case \"horizontal-tb\":\n value = \"lr-tb\";\n break;\n case \"vertical-rl\":\n value = \"tb-rl\";\n break;\n case \"vertical-lr\":\n value = \"tb-lr\";\n break;\n }\n } else if (prefixed === \"-webkit-text-combine\") {\n switch (value) {\n case \"all\":\n value = \"horizontal\";\n break;\n }\n }\n if (elem && (elem as HTMLElement).style) {\n (elem as HTMLElement).style.setProperty(prefixed, value);\n }\n });\n } catch (err) {\n Logging.logger.warn(err);\n }\n}\n\nexport function getCSSProperty(\n elem: Element,\n prop: string,\n opt_value?: string,\n): string {\n try {\n const propertyNames = propNameMap[prop];\n return (elem as HTMLElement).style.getPropertyValue(\n propertyNames ? propertyNames[0] : prop,\n );\n } catch (err) {}\n return opt_value || \"\";\n}\n\nexport function getLangAttribute(element: Element): string {\n let lang = element.getAttributeNS(NS.XML, \"lang\");\n if (!lang && element.namespaceURI == NS.XHTML) {\n lang = element.getAttribute(\"lang\");\n }\n return lang;\n}\n\nexport class StringBuffer {\n list: string[] = [];\n\n append(str: string): StringBuffer {\n this.list.push(str);\n return this;\n }\n\n clear(): void {\n this.list = [];\n }\n\n /**\n * @override\n */\n toString(): string {\n const str = this.list.join(\"\");\n this.list = [str];\n return str;\n }\n}\n\nexport function escapeChar(str: string): string {\n // not called for surrogate pairs, no need to worry about them\n return `\\\\${str.charCodeAt(0).toString(16)} `;\n}\n\nexport function escapeCSSIdent(name: string): string {\n return name.replace(/[^-_a-zA-Z0-9\\u0080-\\uFFFF]/g, escapeChar);\n}\n\nexport function escapeCSSStr(str: string): string {\n return str.replace(/[\\u0000-\\u001F\"\\\\]/g, escapeChar);\n}\n\nexport function lightURLEncode(str: string): string {\n return str.replace(/[\\s+&?=#\\u007F-\\uFFFF]+/g, encodeURIComponent);\n}\n\nexport function isLetter(ch: string): boolean {\n return !!ch.match(\n /^[a-zA-Z\\u009E\\u009F\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u024F\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527]$/,\n );\n}\n\nexport function escapeCharToHex(str: string, prefix?: string): string {\n prefix = typeof prefix === \"string\" ? prefix : \"\\\\u\";\n return prefix + (65536 | str.charCodeAt(0)).toString(16).substr(1);\n}\n\nexport function escapeNameStrToHex(str: string, prefix?: string): string {\n function escapeChar(s) {\n return escapeCharToHex(s, prefix);\n }\n return str.replace(/[^-a-zA-Z0-9_]/g, escapeChar);\n}\n\nexport function escapeRegExp(str: string): string {\n return escapeNameStrToHex(str);\n}\n\nexport function unescapeCharFromHex(str: string, prefix?: string): string {\n prefix = typeof prefix === \"string\" ? prefix : \"\\\\u\";\n if (str.indexOf(prefix) === 0) {\n return String.fromCharCode(parseInt(str.substring(prefix.length), 16));\n } else {\n return str;\n }\n}\n\nexport function unescapeStrFromHex(str: string, prefix?: string): string {\n prefix = typeof prefix === \"string\" ? prefix : \"\\\\u\";\n\n function unescapeChar(s) {\n return unescapeCharFromHex(s, prefix);\n }\n const regexp = new RegExp(`${escapeRegExp(prefix)}[0-9a-fA-F]{4}`, \"g\");\n return str.replace(regexp, unescapeChar);\n}\n\n/**\n * Function good is defined for ints from 0 to high-1. It is such that for\n * each i between 1 and high-1 !good(i-1) || good(i) is true. In other words,\n * it goes like false ... false true ... true.\n * Find i such that (i == 0 || !good(i-1)) && (i == h || good(i))\n * In other words, good(i) is the \"first\" good = true.\n */\nexport function binarySearch(\n high: number,\n good: (p1: number) => boolean,\n): number {\n let l = 0;\n let h = high;\n while (true) {\n Asserts.assert(l <= h);\n Asserts.assert(l == 0 || !good(l - 1));\n Asserts.assert(h == high || good(h));\n if (l == h) {\n return l;\n }\n const m = (l + h) >> 1;\n if (good(m)) {\n h = m;\n } else {\n l = m + 1;\n }\n }\n}\n\n/**\n * Function to sort numbers low to high\n */\nexport function numberCompare(a: number, b: number): number {\n return a - b;\n}\n\nexport const base64Chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nexport function appendBase64(sb: StringBuffer, data: string): void {\n const length = data.length;\n const length3 = Math.floor(length / 3) * 3;\n for (let i = 0; i < length3; i += 3) {\n const c1 = data.charCodeAt(i) & 255;\n const c2 = data.charCodeAt(i + 1) & 255;\n const c3 = data.charCodeAt(i + 2) & 255;\n sb.append(base64Chars.charAt(c1 >> 2));\n sb.append(base64Chars.charAt(((c1 << 4) | (c2 >> 4)) & 63));\n sb.append(base64Chars.charAt(((c2 << 2) | (c3 >> 6)) & 63));\n sb.append(base64Chars.charAt(c3 & 63));\n }\n switch (length - length3) {\n case 1: {\n const p1 = data.charCodeAt(length3) & 255;\n sb.append(base64Chars.charAt(p1 >> 2));\n sb.append(base64Chars.charAt((p1 << 4) & 63));\n sb.append(\"==\");\n break;\n }\n case 2: {\n const q1 = data.charCodeAt(length3) & 255;\n const q2 = data.charCodeAt(length3 + 1) & 255;\n sb.append(base64Chars.charAt(q1 >> 2));\n sb.append(base64Chars.charAt(((q1 << 4) | (q2 >> 4)) & 63));\n sb.append(base64Chars.charAt((q2 << 2) & 63));\n sb.append(\"=\");\n break;\n }\n }\n}\n\n/**\n * Index array using key function. First encountered item wins on collision.\n * Elements with empty and null keys are dropped.\n */\nexport function indexArray<T>(\n arr: T[],\n key: (p1: T) => string | null,\n): { [key: string]: T } {\n const map: { [key: string]: T } = {};\n for (const v of arr) {\n const k: string | null = key(v);\n if (k && !map[k]) {\n map[k] = v;\n }\n }\n return map;\n}\n\n/**\n * Convert array of strings to an object with the values in the array set to\n * true.\n */\nexport function arrayToSet(arr: string[]): { [key: string]: boolean } {\n const set = {};\n for (let i = 0; i < arr.length; i++) {\n set[arr[i]] = true;\n }\n return set;\n}\n\n/**\n * Index array using key function. Repeated indices are all combined into\n * arrays. Elements with empty and null keys are dropped. Ordering of the\n * elements in arrays is preserved.\n */\nexport function multiIndexArray<T>(\n arr: T[],\n key: (p1: T) => string | null,\n): { [key: string]: T[] } {\n const map: { [key: string]: T[] } = {};\n for (const v of arr) {\n const k = key(v);\n if (k) {\n if (map[k]) {\n map[k].push(v);\n } else {\n map[k] = [v];\n }\n }\n }\n return map;\n}\n\n/**\n * Apply function to each value of the object\n * @param fn second parameter is the key\n */\nexport function mapObj<P, R>(\n obj: { [key: string]: P },\n fn: (p1: P, p2: string) => R,\n): { [key: string]: R } {\n const res: { [key: string]: R } = {};\n for (const n in obj) {\n res[n] = fn(obj[n], n);\n }\n return res;\n}\n\nexport function mapSize(obj: object): number {\n let n = 0;\n for (const key in obj) {\n n++;\n }\n return n;\n}\n\nexport type Event = {\n type: string;\n target?;\n currentTarget?;\n preventDefault?;\n newPage?;\n anchorElement?;\n href?;\n content?;\n};\n\nexport type EventListener = (p1: Event) => void;\n\n/**\n * Extemely simple-minded EventTarget implementation. Consider using\n * goog.events.EventTarget if you are using Closure library.\n */\nexport class SimpleEventTarget {\n listeners: { [key: string]: EventListener[] } = {};\n\n dispatchEvent(evt: Event): void {\n const list = this.listeners[evt.type];\n if (list) {\n evt.target = this;\n evt.currentTarget = this;\n for (let i = 0; i < list.length; i++) {\n list[i](evt);\n }\n }\n }\n\n addEventListener(\n type: string,\n listener: EventListener,\n capture?: boolean,\n ): void {\n if (capture) {\n return;\n }\n const list = this.listeners[type];\n if (list) {\n list.push(listener);\n } else {\n this.listeners[type] = [listener];\n }\n }\n\n removeEventListener(\n type: string,\n listener: EventListener,\n capture?: boolean,\n ): void {\n if (capture) {\n return;\n }\n const list = this.listeners[type];\n if (list) {\n const index = list.indexOf(listener);\n if (index >= 0) {\n list.splice(index, 1);\n }\n }\n }\n}\nexport type EventTarget = SimpleEventTarget;\n\nexport let hasLShapeFloatBug: boolean | null = null;\n\n/**\n * Check if there is a bug with L-shape floats overlapping text.\n */\nexport function checkLShapeFloatBug(body: HTMLElement): boolean {\n if (hasLShapeFloatBug == null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"100px\";\n container.style.height = \"100px\";\n container.style.overflow = \"hidden\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n body.appendChild(container);\n const f1 = doc.createElement(\"div\") as HTMLElement;\n f1.style.width = \"0px\";\n f1.style.height = \"14px\";\n f1.style.cssFloat = \"left\";\n container.appendChild(f1);\n const f2 = doc.createElement(\"div\") as HTMLElement;\n f2.style.width = \"50px\";\n f2.style.height = \"50px\";\n f2.style.cssFloat = \"left\";\n f2.style.clear = \"left\";\n container.appendChild(f2);\n const t = doc.createTextNode(\"a a a a a a a a a a a a a a a a\");\n container.appendChild(t);\n const range = doc.createRange();\n range.setStart(t, 0);\n range.setEnd(t, 1);\n const leftEdge = range.getBoundingClientRect().left;\n hasLShapeFloatBug = leftEdge < 40;\n body.removeChild(container);\n }\n return hasLShapeFloatBug;\n}\n\nexport let hasVerticalBBoxBug: boolean | null = null;\n\n/**\n * Check if there is a bug with the bounding boxes of vertical text characters.\n * Though method used to be used check Chrome bug, it seems that the bug has\n * been already fixed:\n * https://bugs.chromium.org/p/chromium/issues/detail?id=297808\n * We now use this method to check Firefox bug:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1159309\n */\nexport function checkVerticalBBoxBug(body: HTMLElement): boolean {\n if (hasVerticalBBoxBug == null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"100px\";\n container.style.height = \"100px\";\n container.style.overflow = \"hidden\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n setCSSProperty(container, \"writing-mode\", \"vertical-rl\");\n body.appendChild(container);\n const t = doc.createTextNode(\"a a a a a a a a a a a a a a a a\");\n container.appendChild(t);\n const range = doc.createRange();\n range.setStart(t, 0);\n range.setEnd(t, 1);\n const box = range.getBoundingClientRect();\n hasVerticalBBoxBug = box.right - box.left < 10;\n body.removeChild(container);\n }\n return hasVerticalBBoxBug;\n}\n\nexport let hasInlineBlockJustificationBug: boolean | null = null;\n\nexport function checkInlineBlockJustificationBug(body: HTMLElement): boolean {\n if (hasInlineBlockJustificationBug === null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"30px\";\n container.style.height = \"100px\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n container.style.textAlign = \"justify\";\n body.appendChild(container);\n const t = doc.createTextNode(\"a | \");\n container.appendChild(t);\n const inlineBlock = doc.createElement(\"span\");\n inlineBlock.style.display = \"inline-block\";\n inlineBlock.style.width = \"30px\";\n container.appendChild(inlineBlock);\n const range = doc.createRange();\n range.setStart(t, 0);\n range.setEnd(t, 3);\n const box = range.getBoundingClientRect();\n hasInlineBlockJustificationBug = box.right < 27;\n body.removeChild(container);\n }\n return hasInlineBlockJustificationBug;\n}\n\nexport let hasSoftWrapOpportunityAfterHyphenBug: boolean | null = null;\n\nexport function checkSoftWrapOpportunityAfterHyphenBug(\n body: HTMLElement,\n): boolean {\n if (hasSoftWrapOpportunityAfterHyphenBug === null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"40px\";\n container.style.height = \"100px\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n container.style.textAlign = \"justify\";\n body.appendChild(container);\n const t = doc.createTextNode(\"a a-\");\n container.appendChild(t);\n const inlineBlock = doc.createElement(\"span\");\n inlineBlock.style.display = \"inline-block\";\n inlineBlock.style.width = \"40px\";\n container.appendChild(inlineBlock);\n const range = doc.createRange();\n range.setStart(t, 2);\n range.setEnd(t, 4);\n const box = range.getBoundingClientRect();\n hasSoftWrapOpportunityAfterHyphenBug = box.right < 37;\n body.removeChild(container);\n }\n return hasSoftWrapOpportunityAfterHyphenBug;\n}\n\nexport let hasSoftWrapOpportunityByWbrBug: boolean | null = null;\n\nexport function checkSoftWrapOpportunityByWbrBug(body: HTMLElement): boolean {\n if (hasSoftWrapOpportunityByWbrBug === null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"40px\";\n container.style.height = \"100px\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n container.style.textAlign = \"justify\";\n body.appendChild(container);\n const t = doc.createTextNode(\"a a-\");\n container.appendChild(t);\n container.appendChild(doc.createElement(\"wbr\"));\n const inlineBlock = doc.createElement(\"span\");\n inlineBlock.style.display = \"inline-block\";\n inlineBlock.style.width = \"40px\";\n container.appendChild(inlineBlock);\n const range = doc.createRange();\n range.setStart(t, 2);\n range.setEnd(t, 4);\n const box = range.getBoundingClientRect();\n hasSoftWrapOpportunityByWbrBug = box.right < 37;\n body.removeChild(container);\n }\n return hasSoftWrapOpportunityByWbrBug;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Cfi - Support for EPUB Canonical Fragment Identifiers.\n */\nimport * as Base from \"./base\";\n\nexport type Position = {\n node: Node;\n offset: number;\n after: boolean;\n sideBias: string | null;\n ref: Fragment;\n};\n\nexport function getId(node: Node): string | null {\n if (node.nodeType == 1) {\n const idtxt = (node as Element).getAttribute(\"id\");\n if (idtxt && idtxt.match(/^[-a-zA-Z_0-9.\\u007F-\\uFFFF]+$/)) {\n return idtxt;\n }\n }\n return null;\n}\n\nexport function escapeChar(ch: string): string {\n return `^${ch}`;\n}\n\nexport function escape(str: string): string {\n return str.replace(/[\\[\\]\\(\\),=;^]/g, escapeChar);\n}\n\nexport function unescapeChar(str: string): string {\n return str.substr(1);\n}\n\nexport function unescape(str: string): string {\n if (!str) {\n return str;\n }\n return str.replace(/\\^[\\[\\]\\(\\),=;^]/g, unescapeChar);\n}\n\nexport function parseExtVal(extstr: string): string | string[] {\n const result = [];\n do {\n const r = extstr.match(/^(\\^,|[^,])*/);\n const p = unescape(r[0]);\n extstr = extstr.substr(r[0].length + 1);\n if (!extstr && !result.length) {\n return p;\n }\n result.push(p);\n } while (extstr);\n return result;\n}\n\nexport function parseExt(extstr: string): { [key: string]: string | string[] } {\n const ext = {};\n while (extstr) {\n const r = extstr.match(/^;([^;=]+)=(([^;]|\\^;)*)/);\n if (!r) {\n return ext;\n }\n ext[r[1]] = parseExtVal(r[2]);\n extstr = extstr.substr(r[0].length);\n }\n return ext;\n}\n\nexport interface Step {\n appendTo(sb: Base.StringBuffer): void;\n\n applyTo(pos: Position): boolean;\n}\n\nexport class RefStep implements Step {\n appendTo(sb: Base.StringBuffer) {\n sb.append(\"!\");\n }\n\n /**\n * @override\n */\n applyTo(pos: Position): boolean {\n return false;\n }\n}\n\nexport class ChildStep implements Step {\n constructor(\n public readonly index: number,\n public readonly id: string | null,\n public readonly sideBias: string | null,\n ) {}\n\n /**\n * @override\n */\n appendTo(sb: Base.StringBuffer): void {\n sb.append(\"/\");\n sb.append(this.index.toString());\n if (this.id || this.sideBias) {\n sb.append(\"[\");\n if (this.id) {\n sb.append(this.id);\n }\n if (this.sideBias) {\n sb.append(\";s=\");\n sb.append(this.sideBias);\n }\n sb.append(\"]\");\n }\n }\n\n /**\n * @override\n */\n applyTo(pos: Position): boolean {\n if (pos.node.nodeType != 1) {\n throw new Error(\"E_CFI_NOT_ELEMENT\");\n }\n const elem = pos.node as Element;\n const childElements = elem.children;\n const childElementCount = childElements.length;\n let child: Node;\n const childIndex = Math.floor(this.index / 2) - 1;\n if (childIndex < 0 || childElementCount == 0) {\n child = elem.firstChild;\n pos.node = child || elem;\n } else {\n child = childElements[Math.min(childIndex, childElementCount - 1)];\n if (this.index & 1) {\n const next = child.nextSibling;\n if (!next || next.nodeType == 1) {\n pos.after = true;\n } else {\n child = next;\n }\n }\n pos.node = child;\n }\n if (this.id && (pos.after || this.id != getId(pos.node))) {\n throw new Error(\"E_CFI_ID_MISMATCH\");\n }\n pos.sideBias = this.sideBias;\n return true;\n }\n}\n\nexport class OffsetStep implements Step {\n constructor(\n public readonly offset: number,\n public readonly textBefore: string | null,\n public readonly textAfter: string | null,\n public readonly sideBias: string | null,\n ) {}\n\n applyTo(pos: Position): boolean {\n if (this.offset > 0 && !pos.after) {\n let offset = this.offset;\n let node = pos.node;\n while (true) {\n const nodeType = node.nodeType;\n if (nodeType == 1) {\n break;\n }\n const next = node.nextSibling;\n if (3 <= nodeType && nodeType <= 5) {\n const textLength = node.textContent.length;\n if (offset <= textLength) {\n break;\n }\n if (!next) {\n offset = textLength;\n break;\n }\n offset -= textLength;\n }\n if (!next) {\n offset = 0;\n break;\n }\n node = next;\n }\n pos.node = node;\n pos.offset = offset;\n }\n pos.sideBias = this.sideBias;\n return true;\n }\n\n /**\n * @override\n */\n appendTo(sb: Base.StringBuffer): void {\n sb.append(\":\");\n sb.append(this.offset.toString());\n if (this.textBefore || this.textAfter || this.sideBias) {\n sb.append(\"[\");\n if (this.textBefore || this.textAfter) {\n if (this.textBefore) {\n sb.append(escape(this.textBefore));\n }\n sb.append(\",\");\n if (this.textAfter) {\n sb.append(escape(this.textAfter));\n }\n }\n if (this.sideBias) {\n sb.append(\";s=\");\n sb.append(this.sideBias);\n }\n sb.append(\"]\");\n }\n }\n}\n\nexport class Fragment {\n steps: Step[] = null;\n\n fromString(fragstr: string): void {\n let r = fragstr.match(/^#?epubcfi\\((.*)\\)$/);\n if (!r) {\n throw new Error(\"E_CFI_NOT_CFI\");\n }\n const str = r[1];\n let i = 0;\n const steps = [];\n while (true) {\n let ext: {\n [key: string]: string | string[];\n };\n switch (str.charAt(i)) {\n case \"/\": {\n i++;\n r = str\n .substr(i)\n .match(\n /^(0|[1-9][0-9]*)(\\[([-a-zA-Z_0-9.\\u007F-\\uFFFF]+)(;([^\\]]|\\^\\])*)?\\])?/,\n );\n if (!r) {\n throw new Error(\"E_CFI_NUMBER_EXPECTED\");\n }\n i += r[0].length;\n const index = parseInt(r[1], 10);\n const id = r[3];\n ext = parseExt(r[4]);\n steps.push(new ChildStep(index, id, Base.asString(ext[\"s\"])));\n break;\n }\n case \":\": {\n i++;\n r = str\n .substr(i)\n .match(\n /^(0|[1-9][0-9]*)(\\[((([^\\];,]|\\^[\\];,])*)(,(([^\\];,]|\\^[\\];,])*))?)(;([^]]|\\^\\])*)?\\])?/,\n );\n if (!r) {\n throw new Error(\"E_CFI_NUMBER_EXPECTED\");\n }\n i += r[0].length;\n const offset = parseInt(r[1], 10);\n let textBefore = r[4];\n if (textBefore) {\n textBefore = unescape(textBefore);\n }\n let textAfter = r[7];\n if (textAfter) {\n textAfter = unescape(textAfter);\n }\n ext = parseExt(r[10]);\n steps.push(\n new OffsetStep(\n offset,\n textBefore,\n textAfter,\n Base.asString(ext[\"s\"]),\n ),\n );\n break;\n }\n case \"!\":\n i++;\n steps.push(new RefStep());\n break;\n case \"~\":\n case \"@\":\n\n // Time/space terminus; only useful for highlights/selections which are\n // not yet supported, skip for now. fall through\n case \"\":\n this.steps = steps;\n return;\n default:\n throw new Error(\"E_CFI_PARSE_ERROR\");\n }\n }\n }\n\n navigate(doc: Document): Position {\n const pos = {\n node: doc.documentElement,\n offset: 0,\n after: false,\n sideBias: null,\n ref: null,\n };\n for (let i = 0; i < this.steps.length; i++) {\n if (!this.steps[i].applyTo(pos)) {\n pos.ref = new Fragment();\n pos.ref.steps = this.steps.slice(i + 1);\n break;\n }\n }\n return pos;\n }\n\n trim(text: string, after: boolean): string {\n return text\n .replace(/\\s+/g, \" \")\n .match(\n after\n ? /^[ -\\uD7FF\\uE000-\\uFFFF]{0,8}/\n : /[ -\\uD7FF\\uE000-\\uFFFF]{0,8}$/,\n )[0]\n .replace(/^\\s/, \"\")\n .replace(/\\s$/, \"\");\n }\n\n /**\n * Initialize from a node and an offset.\n */\n prependPathFromNode(\n node: Node,\n offset: number,\n after: boolean,\n sideBias: string | null,\n ) {\n const steps = [];\n let parent = node.parentNode;\n let textBefore = \"\";\n let textAfter = \"\";\n while (node) {\n switch (node.nodeType) {\n case 3: // Text nodes\n case 4:\n case 5: {\n const text = node.textContent;\n const textLength = text.length;\n if (after) {\n offset += textLength;\n if (!textBefore) {\n textBefore = text;\n }\n } else {\n if (offset > textLength) {\n offset = textLength;\n }\n after = true;\n textBefore = text.substr(0, offset);\n textAfter = text.substr(offset);\n }\n node = node.previousSibling;\n continue;\n }\n case 8: // Comment Node\n node = node.previousSibling;\n continue;\n }\n break;\n }\n if (offset > 0 || textBefore || textAfter) {\n textBefore = this.trim(textBefore, false);\n textAfter = this.trim(textAfter, true);\n steps.push(new OffsetStep(offset, textBefore, textAfter, sideBias));\n sideBias = null;\n }\n while (parent) {\n if (!parent || parent.nodeType == 9) {\n break;\n }\n const id = after ? null : getId(node);\n let index = after ? 1 : 0;\n while (node) {\n if (node.nodeType == 1) {\n index += 2;\n }\n node = node.previousSibling;\n }\n steps.push(new ChildStep(index, id, sideBias));\n sideBias = null;\n node = parent;\n parent = parent.parentNode;\n after = false;\n }\n steps.reverse();\n if (this.steps) {\n steps.push(new RefStep());\n this.steps = steps.concat(this.steps);\n } else {\n this.steps = steps;\n }\n }\n\n toString(): string {\n if (!this.steps) {\n return \"\";\n }\n const sb = new Base.StringBuffer();\n sb.append(\"epubcfi(\");\n for (let i = 0; i < this.steps.length; i++) {\n this.steps[i].appendTo(sb);\n }\n sb.append(\")\");\n return sb.toString();\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Exprs - `-epubx-expr` Adaptive Layout expressions.\n */\nimport * as Base from \"./base\";\n\nexport type Preferences = {\n fontFamily: string;\n lineHeight: number;\n margin: number;\n hyphenate: boolean;\n columnWidth: number;\n horizontal: boolean;\n nightMode: boolean;\n spreadView: boolean;\n pageBorder: number;\n enabledMediaTypes: { [key: string]: boolean };\n defaultPaperSize?: { [key: string]: number };\n};\n\nexport function defaultPreferences(): Preferences {\n return {\n fontFamily: \"serif\",\n lineHeight: 1.25,\n margin: 8,\n hyphenate: false,\n columnWidth: 25,\n horizontal: false,\n nightMode: false,\n spreadView: false,\n pageBorder: 1,\n enabledMediaTypes: { vivliostyle: true, print: true },\n defaultPaperSize: undefined,\n };\n}\n\nexport function clonePreferences(pref: Preferences): Preferences {\n return {\n fontFamily: pref.fontFamily,\n lineHeight: pref.lineHeight,\n margin: pref.margin,\n hyphenate: pref.hyphenate,\n columnWidth: pref.columnWidth,\n horizontal: pref.horizontal,\n nightMode: pref.nightMode,\n spreadView: pref.spreadView,\n pageBorder: pref.pageBorder,\n enabledMediaTypes: Object.assign({}, pref.enabledMediaTypes),\n defaultPaperSize: pref.defaultPaperSize\n ? Object.assign({}, pref.defaultPaperSize)\n : undefined,\n };\n}\n\nexport const defaultPreferencesInstance = defaultPreferences();\n\ninterface Pending {}\ntype Special = Pending;\n\n/**\n * Special marker value that indicates that the expression result is being\n * calculated.\n */\nexport const Special = {\n PENDING: {} as Pending,\n};\n\nexport type Result = string | number | boolean | undefined;\n\nexport type PendingResult = Special | Result;\n\nexport function letterbox(\n viewW: number,\n viewH: number,\n objW: number,\n objH: number,\n): string {\n const scale = Math.min((viewW - 0) / objW, (viewH - 0) / objH);\n return `matrix(${scale},0,0,${scale},0,0)`;\n}\n\n/**\n * @return string that can be parsed as CSS string with value str\n */\nexport function cssString(str: string): string {\n return `\"${Base.escapeCSSStr(`${str}`)}\"`;\n}\n\n/**\n * @return string that can be parsed as CSS name\n */\nexport function cssIdent(name: string): string {\n return Base.escapeCSSIdent(`${name}`);\n}\n\nexport function makeQualifiedName(\n objName: string | null,\n memberName: string,\n): string {\n if (objName) {\n return `${Base.escapeCSSIdent(objName)}.${Base.escapeCSSIdent(memberName)}`;\n }\n return Base.escapeCSSIdent(memberName);\n}\n\nexport let nextKeyIndex: number = 0;\n\n/**\n * Lexical scope of the expression.\n */\nexport class LexicalScope {\n scopeKey: string;\n children: LexicalScope[] = [];\n zero: Const;\n one: Const;\n _true: Const;\n _false: Const;\n values: { [key: string]: Val } = {};\n funcs: { [key: string]: Val } = {};\n builtIns: { [key: string]: (...p1: Result[]) => Result } = {};\n\n constructor(\n public parent: LexicalScope,\n public resolver?: (p1: string, p2: boolean) => Val,\n ) {\n this.scopeKey = `S${nextKeyIndex++}`;\n this.zero = new Const(this, 0);\n this.one = new Const(this, 1);\n this._true = new Const(this, true);\n this._false = new Const(this, false);\n if (parent) {\n parent.children.push(this);\n }\n if (!parent) {\n // root scope\n const builtIns = this.builtIns;\n builtIns[\"floor\"] = Math.floor;\n builtIns[\"ceil\"] = Math.ceil;\n builtIns[\"round\"] = Math.round;\n builtIns[\"sqrt\"] = Math.sqrt;\n builtIns[\"min\"] = Math.min;\n builtIns[\"max\"] = Math.max;\n builtIns[\"letterbox\"] = letterbox;\n builtIns[\"css-string\"] = cssString;\n builtIns[\"css-name\"] = cssIdent;\n builtIns[\"typeof\"] = (x) => typeof x;\n this.defineBuiltInName(\"page-width\", function() {\n return this.pageWidth();\n });\n this.defineBuiltInName(\"page-height\", function() {\n return this.pageHeight();\n });\n this.defineBuiltInName(\"pref-font-family\", function() {\n return this.pref.fontFamily;\n });\n this.defineBuiltInName(\"pref-night-mode\", function() {\n return this.pref.nightMode;\n });\n this.defineBuiltInName(\"pref-hyphenate\", function() {\n return this.pref.hyphenate;\n });\n this.defineBuiltInName(\"pref-margin\", function() {\n return this.pref.margin;\n });\n this.defineBuiltInName(\"pref-line-height\", function() {\n return this.pref.lineHeight;\n });\n this.defineBuiltInName(\"pref-column-width\", function() {\n return this.pref.columnWidth * this.fontSize;\n });\n this.defineBuiltInName(\"pref-horizontal\", function() {\n return this.pref.horizontal;\n });\n this.defineBuiltInName(\"pref-spread-view\", function() {\n return this.pref.spreadView;\n });\n\n // For env(pub-title) and env(doc-title)\n this.defineBuiltInName(\"pub-title\", function() {\n return cssString(this.pubTitle ? this.pubTitle : \"\");\n });\n this.defineBuiltInName(\"doc-title\", function() {\n return cssString(this.docTitle ? this.docTitle : \"\");\n });\n }\n }\n\n defineBuiltInName(name: string, fn: () => Result) {\n this.values[name] = new Native(this, fn, name);\n }\n\n defineName(qualifiedName: string, val: Val): void {\n this.values[qualifiedName] = val;\n }\n\n defineFunc(qualifiedName: string, val: Val): void {\n this.funcs[qualifiedName] = val;\n }\n\n defineBuiltIn(qualifiedName: string, fn: (...p1: Result[]) => Result): void {\n this.builtIns[qualifiedName] = fn;\n }\n}\n\nexport function isAbsoluteLengthUnit(unit: string): boolean {\n switch (unit.toLowerCase()) {\n case \"px\":\n case \"in\":\n case \"pt\":\n case \"pc\":\n case \"cm\":\n case \"mm\":\n case \"q\":\n return true;\n default:\n return false;\n }\n}\n\nexport function isViewportRelativeLengthUnit(unit: string): boolean {\n switch (unit.toLowerCase()) {\n case \"vw\":\n case \"vh\":\n case \"vi\":\n case \"vb\":\n case \"vmin\":\n case \"vmax\":\n case \"pvw\":\n case \"pvh\":\n case \"pvi\":\n case \"pvb\":\n case \"pvmin\":\n case \"pvmax\":\n return true;\n default:\n return false;\n }\n}\n\nexport function isFontRelativeLengthUnit(unit: string): boolean {\n switch (unit.toLowerCase()) {\n case \"em\":\n case \"ex\":\n case \"rem\":\n return true;\n default:\n return false;\n }\n}\n\nexport const defaultUnitSizes: { [key: string]: number } = {\n px: 1,\n in: 96,\n pt: 4 / 3,\n pc: 96 / 6,\n cm: 96 / 2.54,\n mm: 96 / 25.4,\n q: 96 / 2.54 / 40,\n em: 16,\n rem: 16,\n ex: 8,\n // <resolution>\n dppx: 1,\n dpi: 1 / 96,\n dpcm: 2.54 / 96,\n};\n\n/**\n * Returns if a unit should be converted to px before applied to the raw DOM.\n */\nexport function needUnitConversion(unit: string): boolean {\n switch (unit) {\n case \"q\":\n case \"rem\":\n return true;\n default:\n return false;\n }\n}\n\nexport type ScopeContext = {\n [key: string]: Result;\n};\n\n/**\n * Run-time instance of a scope and its children.\n */\nexport class Context {\n protected actualPageWidth: number | null = null;\n pageWidth: () => number;\n protected actualPageHeight: number | null = null;\n pageHeight: () => number;\n initialFontSize: number;\n rootFontSize: number | null = null;\n fontSize: () => number;\n pref: Preferences;\n scopes: { [key: string]: ScopeContext } = {};\n pageAreaWidth: number | null = null;\n pageAreaHeight: number | null = null;\n pageVertical: boolean | null = null;\n pubTitle: string | null = null;\n docTitle: string | null = null;\n\n constructor(\n public readonly rootScope: LexicalScope,\n public readonly viewportWidth: number,\n public readonly viewportHeight: number,\n fontSize: number,\n ) {\n this.pageWidth = function() {\n if (this.actualPageWidth) {\n return this.actualPageWidth;\n } else {\n return this.pref.spreadView\n ? Math.floor(viewportWidth / 2) - this.pref.pageBorder\n : viewportWidth;\n }\n };\n this.pageHeight = function() {\n if (this.actualPageHeight) {\n return this.actualPageHeight;\n } else {\n return viewportHeight;\n }\n };\n this.initialFontSize = fontSize;\n this.fontSize = function() {\n if (this.rootFontSize) {\n return this.rootFontSize;\n } else {\n return fontSize;\n }\n };\n this.pref = defaultPreferencesInstance;\n }\n\n private getScopeContext(scope: LexicalScope): ScopeContext {\n let s = this.scopes[scope.scopeKey];\n if (!s) {\n s = {};\n this.scopes[scope.scopeKey] = s;\n }\n return s;\n }\n\n clearScope(scope: LexicalScope): void {\n this.scopes[scope.scopeKey] = {};\n for (let k = 0; k < scope.children.length; k++) {\n this.clearScope(scope.children[k]);\n }\n }\n\n queryUnitSize(unit: string, isRoot: boolean): number {\n if (isViewportRelativeLengthUnit(unit)) {\n const pvw = this.pageWidth() / 100;\n const pvh = this.pageHeight() / 100;\n const vw = this.pageAreaWidth != null ? this.pageAreaWidth / 100 : pvw;\n const vh = this.pageAreaHeight != null ? this.pageAreaHeight / 100 : pvh;\n\n switch (unit) {\n case \"vw\":\n return vw;\n case \"vh\":\n return vh;\n case \"vi\":\n return this.pageVertical ? vh : vw;\n case \"vb\":\n return this.pageVertical ? vw : vh;\n case \"vmin\":\n return vw < vh ? vw : vh;\n case \"vmax\":\n return vw > vh ? vw : vh;\n case \"pvw\":\n return pvw;\n case \"pvh\":\n return pvh;\n case \"pvi\":\n return this.pageVertical ? pvh : pvw;\n case \"pvb\":\n return this.pageVertical ? pvw : pvh;\n case \"pvmin\":\n return pvw < pvh ? pvw : pvh;\n case \"pvmax\":\n return pvw > pvh ? pvw : pvh;\n }\n }\n if (unit == \"em\" || unit == \"rem\") {\n return isRoot ? this.initialFontSize : this.fontSize();\n }\n if (unit == \"ex\") {\n return (\n (defaultUnitSizes[\"ex\"] *\n (isRoot ? this.initialFontSize : this.fontSize())) /\n defaultUnitSizes[\"em\"]\n );\n }\n return defaultUnitSizes[unit];\n }\n\n evalName(scope: LexicalScope, qualifiedName: string): Val {\n do {\n let val = scope.values[qualifiedName];\n if (val) {\n return val;\n }\n if (scope.resolver) {\n val = scope.resolver.call(this, qualifiedName, false);\n if (val) {\n return val;\n }\n }\n scope = scope.parent;\n } while (scope);\n throw new Error(`Name '${qualifiedName}' is undefined`);\n }\n\n /**\n * @param noBuiltInEval don't evaluate built-ins (for dependency calculations)\n */\n evalCall(\n scope: LexicalScope,\n qualifiedName: string,\n params: Val[],\n noBuiltInEval: boolean,\n ): Val {\n do {\n let body = scope.funcs[qualifiedName];\n if (body) {\n return body; // will be expanded by callee\n }\n if (scope.resolver) {\n body = scope.resolver.call(this, qualifiedName, true);\n if (body) {\n return body;\n }\n }\n const fn = scope.builtIns[qualifiedName];\n if (fn) {\n if (noBuiltInEval) {\n return scope.zero;\n }\n const args = Array(params.length);\n for (let i = 0; i < params.length; i++) {\n args[i] = params[i].evaluate(this);\n }\n return new Const(scope, fn.apply(this, args));\n }\n scope = scope.parent;\n } while (scope);\n throw new Error(`Function '${qualifiedName}' is undefined`);\n }\n\n evalMediaName(name: string, not: boolean): boolean {\n const enabled = name === \"all\" || !!this.pref.enabledMediaTypes[name];\n return not ? !enabled : enabled;\n }\n\n evalMediaTest(feature: string, value: Val): boolean {\n let prefix = \"\";\n const r = feature.match(/^(min|max)-(.*)$/);\n if (r) {\n prefix = r[1];\n feature = r[2];\n }\n let req: Result | null = null;\n let actual: number | null = null;\n switch (feature) {\n case \"width\":\n case \"height\":\n case \"device-width\":\n case \"device-height\":\n case \"color\":\n if (value) {\n req = value.evaluate(this);\n }\n break;\n }\n switch (feature) {\n case \"width\":\n actual = this.pageWidth();\n break;\n case \"height\":\n actual = this.pageHeight();\n break;\n case \"device-width\":\n actual = window.screen.availWidth;\n break;\n case \"device-height\":\n actual = window.screen.availHeight;\n break;\n case \"color\":\n actual = window.screen.pixelDepth;\n break;\n }\n if (actual != null && req != null) {\n switch (prefix) {\n case \"min\":\n return actual >= req;\n case \"max\":\n return actual <= req;\n default:\n return actual == req;\n }\n } else if (actual != null && value == null) {\n return actual !== 0;\n }\n return false;\n }\n\n queryVal(scope: LexicalScope, key: string): Result | undefined {\n const s = this.scopes[scope.scopeKey];\n return s ? s[key] : undefined;\n }\n\n storeVal(scope: LexicalScope, key: string, val: Result): void {\n this.getScopeContext(scope)[key] = val;\n }\n}\n\n//---------- name resolution --------------\nexport type DependencyCache = {\n [key: string]: boolean | Special;\n};\n\nexport class Val {\n key: string;\n\n constructor(public scope: LexicalScope) {\n this.scope = scope;\n this.key = `_${nextKeyIndex++}`;\n }\n\n /**\n * @override\n */\n toString(): string {\n const buf = new Base.StringBuffer();\n this.appendTo(buf, 0);\n return buf.toString();\n }\n\n appendTo(buf: Base.StringBuffer, priority: number): void {\n throw new Error(\"F_ABSTRACT\");\n }\n\n protected evaluateCore(context: Context): Result {\n throw new Error(\"F_ABSTRACT\");\n }\n\n expand(context: Context, params: Val[]): Val {\n return this;\n }\n\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return other === this;\n }\n\n dependOuter(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n const cached = dependencyCache[this.key];\n if (cached != null) {\n if (cached === Special.PENDING) {\n return false;\n }\n return cached as boolean;\n } else {\n dependencyCache[this.key] = Special.PENDING;\n const result = this.dependCore(other, context, dependencyCache);\n dependencyCache[this.key] = result;\n return result;\n }\n }\n\n depend(other: Val, context: Context): boolean {\n return this.dependOuter(other, context, {});\n }\n\n evaluate(context: Context): Result {\n let result = context.queryVal(this.scope, this.key);\n if (typeof result != \"undefined\") {\n return result;\n }\n result = this.evaluateCore(context);\n context.storeVal(this.scope, this.key, result);\n return result;\n }\n\n isMediaName(): boolean {\n return false;\n }\n}\n\nexport class Prefix extends Val {\n constructor(scope: LexicalScope, public val: Val) {\n super(scope);\n }\n\n protected getOp(): string {\n throw new Error(\"F_ABSTRACT\");\n }\n\n evalPrefix(val: Result): Result {\n throw new Error(\"F_ABSTRACT\");\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n const val = this.val.evaluate(context);\n return this.evalPrefix(val);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this || this.val.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n if (10 < priority) {\n buf.append(\"(\");\n }\n buf.append(this.getOp());\n this.val.appendTo(buf, 10);\n if (10 < priority) {\n buf.append(\")\");\n }\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const val = this.val.expand(context, params);\n if (val === this.val) {\n return this;\n }\n const r = new (this.constructor as any)(this.scope, val);\n return r;\n }\n}\n\nexport class Infix extends Val {\n constructor(scope: LexicalScope, public lhs: Val, public rhs: Val) {\n super(scope);\n }\n\n getPriority(): number {\n throw new Error(\"F_ABSTRACT\");\n }\n\n getOp(): string {\n throw new Error(\"F_ABSTRACT\");\n }\n\n evalInfix(lhs: Result, rhs: Result): Result {\n throw new Error(\"F_ABSTRACT\");\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n const lhs = this.lhs.evaluate(context);\n const rhs = this.rhs.evaluate(context);\n return this.evalInfix(lhs, rhs);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this ||\n this.lhs.dependOuter(other, context, dependencyCache) ||\n this.rhs.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n const thisPriority = this.getPriority();\n if (thisPriority <= priority) {\n buf.append(\"(\");\n }\n this.lhs.appendTo(buf, thisPriority);\n buf.append(this.getOp());\n this.rhs.appendTo(buf, thisPriority);\n if (thisPriority <= priority) {\n buf.append(\")\");\n }\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const lhs = this.lhs.expand(context, params);\n const rhs = this.rhs.expand(context, params);\n if (lhs === this.lhs && rhs === this.rhs) {\n return this;\n }\n const r = new (this.constructor as any)(this.scope, lhs, rhs);\n return r;\n }\n}\n\nexport class Logical extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class Comparison extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 2;\n }\n}\n\nexport class Additive extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 3;\n }\n}\n\nexport class Multiplicative extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class Not extends Prefix {\n constructor(scope: LexicalScope, val: Val) {\n super(scope, val);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"!\";\n }\n\n /**\n * @override\n */\n evalPrefix(val: Result): Result {\n return !val;\n }\n}\n\nexport class Negate extends Prefix {\n constructor(scope: LexicalScope, val: Val) {\n super(scope, val);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"-\";\n }\n\n /**\n * @override\n */\n evalPrefix(val: Result): Result {\n return -val;\n }\n}\n\nexport class And extends Logical {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"&&\";\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.lhs.evaluate(context) && this.rhs.evaluate(context);\n }\n}\n\nexport class AndMedia extends And {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \" and \";\n }\n}\n\nexport class Or extends Logical {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"||\";\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.lhs.evaluate(context) || this.rhs.evaluate(context);\n }\n}\n\nexport class OrMedia extends Or {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \", \";\n }\n}\n\nexport class Lt extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"<\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs < rhs;\n }\n}\n\nexport class Le extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"<=\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs <= rhs;\n }\n}\n\nexport class Gt extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \">\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs > rhs;\n }\n}\n\nexport class Ge extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \">=\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs >= rhs;\n }\n}\n\nexport class Eq extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"==\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs == rhs;\n }\n}\n\nexport class Ne extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"!=\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs != rhs;\n }\n}\n\nexport class Add extends Additive {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"+\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) + rhs;\n }\n}\n\nexport class Subtract extends Additive {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \" - \";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) - (rhs as any);\n }\n}\n\nexport class Multiply extends Multiplicative {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"*\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) * (rhs as any);\n }\n}\n\nexport class Divide extends Multiplicative {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"/\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) / (rhs as any);\n }\n}\n\nexport class Modulo extends Multiplicative {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"%\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) % (rhs as any);\n }\n}\n\n/**\n * Numerical value with a unit.\n */\nexport class Numeric extends Val {\n unit: string;\n\n constructor(scope: LexicalScope, public num: number, unit: string) {\n super(scope);\n this.unit = unit.toLowerCase();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.num.toString());\n buf.append(Base.escapeCSSIdent(this.unit));\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.num * context.queryUnitSize(this.unit, false);\n }\n}\n\n/**\n * Named value.\n * @param qualifiedName CSS-escaped name sequence separated by dots.\n */\nexport class Named extends Val {\n constructor(scope: LexicalScope, public qualifiedName: string) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.qualifiedName);\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return context.evalName(this.scope, this.qualifiedName).evaluate(context);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this ||\n context\n .evalName(this.scope, this.qualifiedName)\n .dependOuter(other, context, dependencyCache)\n );\n }\n}\n\n/**\n * Named value.\n */\nexport class MediaName extends Val {\n // FIXME: This property is added to reduce TypeScript error on `dependCore`\n // but it is never initialized. Is it really correct code?\n value: Val;\n\n constructor(scope: LexicalScope, public not: boolean, public name: string) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n if (this.not) {\n buf.append(\"not \");\n }\n buf.append(Base.escapeCSSIdent(this.name));\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return context.evalMediaName(this.name, this.not);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this || this.value.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n isMediaName(): boolean {\n return true;\n }\n}\n\n/**\n * A value that is calculated by calling a JavaScript function. Note that the\n * result is cached and this function will be called only once between any\n * clears for its scope in the context.\n * @param fn function to call.\n * @param str a way to represent this value in toString() call.\n */\nexport class Native extends Val {\n constructor(\n scope: LexicalScope,\n public fn: () => Result,\n public str: string,\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.str);\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.fn.call(context);\n }\n}\n\nexport function appendValArray(buf: Base.StringBuffer, arr: Val[]): void {\n buf.append(\"(\");\n for (let i = 0; i < arr.length; i++) {\n if (i) {\n buf.append(\",\");\n }\n arr[i].appendTo(buf, 0);\n }\n buf.append(\")\");\n}\n\nexport function expandValArray(\n context: Context,\n arr: Val[],\n params: Val[],\n): Val[] {\n let expanded: Val[] = arr;\n for (let i = 0; i < arr.length; i++) {\n const p = arr[i].expand(context, params);\n if (arr !== expanded) {\n expanded[i] = p;\n } else if (p !== arr[i]) {\n expanded = Array(arr.length);\n for (let j = 0; j < i; j++) {\n expanded[j] = arr[j];\n }\n expanded[i] = p;\n }\n }\n return expanded;\n}\n\nexport function evalValArray(context: Context, arr: Val[]): Result[] {\n const result: Result[] = Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n result[i] = arr[i].evaluate(context);\n }\n return result;\n}\n\nexport class Call extends Val {\n constructor(\n scope: LexicalScope,\n public qualifiedName: string,\n public params: Val[],\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.qualifiedName);\n appendValArray(buf, this.params);\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n const body = context.evalCall(\n this.scope,\n this.qualifiedName,\n this.params,\n false,\n );\n return body.expand(context, this.params).evaluate(context);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n if (other === this) {\n return true;\n }\n for (let i = 0; i < this.params.length; i++) {\n if (this.params[i].dependOuter(other, context, dependencyCache)) {\n return true;\n }\n }\n const body = context.evalCall(\n this.scope,\n this.qualifiedName,\n this.params,\n true,\n );\n\n // No expansion here!\n return body.dependOuter(other, context, dependencyCache);\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const expandedParams = expandValArray(context, this.params, params);\n if (expandedParams === this.params) {\n return this;\n }\n return new Call(this.scope, this.qualifiedName, expandedParams);\n }\n}\n\nexport class Cond extends Val {\n constructor(\n scope: LexicalScope,\n public cond: Val,\n public ifTrue: Val,\n public ifFalse: Val,\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n if (priority > 0) {\n buf.append(\"(\");\n }\n this.cond.appendTo(buf, 0);\n buf.append(\"?\");\n this.ifTrue.appendTo(buf, 0);\n buf.append(\":\");\n this.ifFalse.appendTo(buf, 0);\n if (priority > 0) {\n buf.append(\")\");\n }\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n if (this.cond.evaluate(context)) {\n return this.ifTrue.evaluate(context);\n } else {\n return this.ifFalse.evaluate(context);\n }\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this ||\n this.cond.dependOuter(other, context, dependencyCache) ||\n this.ifTrue.dependOuter(other, context, dependencyCache) ||\n this.ifFalse.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const cond = this.cond.expand(context, params);\n const ifTrue = this.ifTrue.expand(context, params);\n const ifFalse = this.ifFalse.expand(context, params);\n if (\n cond === this.cond &&\n ifTrue === this.ifTrue &&\n ifFalse === this.ifFalse\n ) {\n return this;\n }\n const r = new Cond(this.scope, cond, ifTrue, ifFalse);\n return r;\n }\n}\n\nexport class Const extends Val {\n constructor(scope: LexicalScope, public val: Result) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n switch (typeof this.val) {\n case \"number\":\n case \"boolean\":\n buf.append(this.val.toString());\n break;\n case \"string\":\n buf.append('\"');\n buf.append(Base.escapeCSSStr(this.val));\n buf.append('\"');\n break;\n default:\n throw new Error(\"F_UNEXPECTED_STATE\");\n }\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.val;\n }\n}\n\nexport class MediaTest extends Val {\n constructor(scope: LexicalScope, public name: MediaName, public value: Val) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(\"(\");\n buf.append(Base.escapeCSSStr(this.name.name));\n buf.append(\":\");\n this.value.appendTo(buf, 0);\n buf.append(\")\");\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return context.evalMediaTest(this.name.name, this.value);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this || this.value.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const value = this.value.expand(context, params);\n if (value === this.value) {\n return this;\n }\n const r = new MediaTest(this.scope, this.name, value);\n return r;\n }\n}\n\nexport class Param extends Val {\n constructor(scope: LexicalScope, public index: number) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(\"$\");\n buf.append(this.index.toString());\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const v = params[this.index];\n if (!v) {\n throw new Error(`Parameter missing: ${this.index}`);\n }\n return v as Val;\n }\n}\n\nexport function and(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (\n v1 === scope._false ||\n v1 === scope.zero ||\n v2 == scope._false ||\n v2 == scope.zero\n ) {\n return scope._false;\n }\n if (v1 === scope._true || v1 === scope.one) {\n return v2;\n }\n if (v2 === scope._true || v2 === scope.one) {\n return v1;\n }\n return new And(scope, v1, v2);\n}\n\nexport function add(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero) {\n return v2;\n }\n if (v2 === scope.zero) {\n return v1;\n }\n return new Add(scope, v1, v2);\n}\n\nexport function sub(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero) {\n return new Negate(scope, v2);\n }\n if (v2 === scope.zero) {\n return v1;\n }\n return new Subtract(scope, v1, v2);\n}\n\nexport function mul(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero || v2 === scope.zero) {\n return scope.zero;\n }\n if (v1 === scope.one) {\n return v2;\n }\n if (v2 === scope.one) {\n return v1;\n }\n return new Multiply(scope, v1, v2);\n}\n\nexport function div(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero) {\n return scope.zero;\n }\n if (v2 === scope.one) {\n return v1;\n }\n return new Divide(scope, v1, v2);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Css - CSS Values and utilities to handle them.\n */\nimport * as Base from \"./base\";\nimport * as Exprs from \"./exprs\";\n\nexport class Visitor {\n /**\n * @return void\n */\n visitValues(values: Val[]): any {\n for (let i = 0; i < values.length; i++) {\n values[i].visit(this);\n }\n }\n\n visitEmpty(empty: Val): Val {\n throw new Error(\"E_CSS_EMPTY_NOT_ALLOWED\");\n }\n\n visitSlash(slash: Val): Val {\n throw new Error(\"E_CSS_SLASH_NOT_ALLOWED\");\n }\n\n visitStr(str: Str): Val {\n throw new Error(\"E_CSS_STR_NOT_ALLOWED\");\n }\n\n visitIdent(ident: Ident): Val {\n throw new Error(\"E_CSS_IDENT_NOT_ALLOWED\");\n }\n\n visitNumeric(numeric: Numeric): Val {\n throw new Error(\"E_CSS_NUMERIC_NOT_ALLOWED\");\n }\n\n visitNum(num: Num): Val {\n throw new Error(\"E_CSS_NUM_NOT_ALLOWED\");\n }\n\n visitInt(num: Int): Val {\n return this.visitNum(num);\n }\n\n visitColor(color: Color): Val {\n throw new Error(\"E_CSS_COLOR_NOT_ALLOWED\");\n }\n\n visitURL(url: URL): Val {\n throw new Error(\"E_CSS_URL_NOT_ALLOWED\");\n }\n\n visitSpaceList(list: SpaceList): Val {\n throw new Error(\"E_CSS_LIST_NOT_ALLOWED\");\n }\n\n visitCommaList(list: CommaList): Val {\n throw new Error(\"E_CSS_COMMA_NOT_ALLOWED\");\n }\n\n visitFunc(func: Func): Val {\n throw new Error(\"E_CSS_FUNC_NOT_ALLOWED\");\n }\n\n visitExpr(expr: Expr): Val {\n throw new Error(\"E_CSS_EXPR_NOT_ALLOWED\");\n }\n}\n\nexport class FilterVisitor extends Visitor {\n constructor() {\n super();\n }\n\n visitValues(values: Val[]): Val[] {\n let arr: Val[] = null;\n for (let i = 0; i < values.length; i++) {\n const before = values[i];\n const after = before.visit(this);\n if (arr) {\n arr[i] = after;\n } else if (before !== after) {\n arr = new Array(values.length);\n for (let k = 0; k < i; k++) {\n arr[k] = values[k];\n }\n arr[i] = after;\n }\n }\n return arr || values;\n }\n\n /**\n * @override\n */\n visitStr(str: Str): Val {\n return str;\n }\n\n /**\n * @override\n */\n visitIdent(ident: Ident): Val {\n return ident;\n }\n\n /**\n * @override\n */\n visitSlash(slash: Val): Val {\n return slash;\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Numeric): Val {\n return numeric;\n }\n\n /**\n * @override\n */\n visitNum(num: Num): Val {\n return num;\n }\n\n /**\n * @override\n */\n visitInt(num: Int): Val {\n return num;\n }\n\n /**\n * @override\n */\n visitColor(color: Color): Val {\n return color;\n }\n\n /**\n * @override\n */\n visitURL(url: URL): Val {\n return url;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: SpaceList): Val {\n const values = this.visitValues(list.values);\n if (values === list.values) {\n return list;\n }\n return new SpaceList(values);\n }\n\n /**\n * @override\n */\n visitCommaList(list: CommaList): Val {\n const values = this.visitValues(list.values);\n if (values === list.values) {\n return list;\n }\n return new CommaList(values);\n }\n\n /**\n * @override\n */\n visitFunc(func: Func): Val {\n const values = this.visitValues(func.values);\n if (values === func.values) {\n return func;\n }\n return new Func(func.name, values);\n }\n\n /**\n * @override\n */\n visitExpr(expr: Expr): Val {\n return expr;\n }\n}\n\nexport class Val {\n /**\n * @override\n */\n toString(): string {\n const buf = new Base.StringBuffer();\n this.appendTo(buf, true);\n return buf.toString();\n }\n\n stringValue(): string {\n const buf = new Base.StringBuffer();\n this.appendTo(buf, false);\n return buf.toString();\n }\n\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n throw new Error(\"F_ABSTRACT\");\n }\n\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"[error]\");\n }\n\n isExpr(): boolean {\n return false;\n }\n\n isNumeric(): boolean {\n return false;\n }\n\n isNum(): boolean {\n return false;\n }\n\n isIdent(): boolean {\n return false;\n }\n\n isSpaceList(): boolean {\n return false;\n }\n\n visit(visitor: any): any {\n throw new Error(\"F_ABSTRACT\");\n }\n}\n\nexport class Empty extends Val {\n private static empty: Empty;\n\n public static get instance(): Empty {\n if (!this.empty) {\n this.empty = new Empty();\n }\n return this.empty;\n }\n\n private constructor() {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, \"\");\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {}\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitEmpty(this);\n }\n}\n\nexport const empty: Empty = Empty.instance;\n\nexport class Slash extends Val {\n private static slash: Slash;\n\n public static get instance(): Slash {\n if (!this.slash) {\n this.slash = new Slash();\n }\n return this.slash;\n }\n\n private constructor() {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, \"/\");\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"/\");\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitSlash(this);\n }\n}\n\nexport const slash: Slash = Slash.instance;\n\nexport class Str extends Val {\n constructor(public str: string) {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, this.str);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n if (toString) {\n buf.append('\"');\n buf.append(Base.escapeCSSStr(this.str));\n buf.append('\"');\n } else {\n buf.append(this.str);\n }\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitStr(this);\n }\n}\n\nconst nameTable = {};\n\nexport class Ident extends Val {\n constructor(public name: string) {\n super();\n if (nameTable[name]) {\n throw new Error(\"E_INVALID_CALL\");\n }\n nameTable[name] = this;\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, this.name);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n if (toString) {\n buf.append(Base.escapeCSSIdent(this.name));\n } else {\n buf.append(this.name);\n }\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitIdent(this);\n }\n\n /**\n * @override\n */\n isIdent(): boolean {\n return true;\n }\n}\n\nexport function getName(name: string): Ident {\n let r = nameTable[name];\n if (!r) {\n r = new Ident(name);\n }\n return r;\n}\n\nexport class Numeric extends Val {\n unit: string;\n\n constructor(public num: number, unit: string) {\n super();\n this.unit = unit.toLowerCase(); // units are case-insensitive in CSS\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n if (this.num == 0) {\n return scope.zero;\n }\n if (ref && this.unit == \"%\") {\n if (this.num == 100) {\n return ref;\n }\n return new Exprs.Multiply(\n scope,\n ref,\n new Exprs.Const(scope, this.num / 100),\n );\n }\n return new Exprs.Numeric(scope, this.num, this.unit);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(this.num.toString());\n buf.append(this.unit);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitNumeric(this);\n }\n\n /**\n * @override\n */\n isNumeric(): boolean {\n return true;\n }\n}\n\nexport class Num extends Val {\n constructor(public num: number) {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n if (this.num == 0) {\n return scope.zero;\n }\n if (this.num == 1) {\n return scope.one;\n }\n return new Exprs.Const(scope, this.num);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(this.num.toString());\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitNum(this);\n }\n\n /**\n * @override\n */\n isNum(): boolean {\n return true;\n }\n}\n\nexport class Int extends Num {\n constructor(num: number) {\n super(num);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitInt(this);\n }\n}\n\nexport class Color extends Val {\n constructor(public rgb: number) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"#\");\n const str = this.rgb.toString(16);\n buf.append(\"000000\".substr(str.length));\n buf.append(str);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitColor(this);\n }\n}\n\nexport class URL extends Val {\n constructor(public url: string) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append('url(\"');\n buf.append(Base.escapeCSSStr(this.url));\n buf.append('\")');\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitURL(this);\n }\n}\n\nexport function appendList(\n buf: Base.StringBuffer,\n values: Val[],\n separator: string,\n toString: boolean,\n): void {\n const length = values.length;\n values[0].appendTo(buf, toString);\n for (let i = 1; i < length; i++) {\n buf.append(separator);\n values[i].appendTo(buf, toString);\n }\n}\n\nexport class SpaceList extends Val {\n constructor(public values: Val[]) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n appendList(buf, this.values, \" \", toString);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitSpaceList(this);\n }\n\n /**\n * @override\n */\n isSpaceList(): boolean {\n return true;\n }\n}\n\nexport class CommaList extends Val {\n constructor(public values: Val[]) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n appendList(buf, this.values, \",\", toString);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitCommaList(this);\n }\n}\n\nexport class Func extends Val {\n constructor(public name: string, public values: Val[]) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(Base.escapeCSSIdent(this.name));\n buf.append(\"(\");\n appendList(buf, this.values, \",\", toString);\n buf.append(\")\");\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitFunc(this);\n }\n}\n\nexport class Expr extends Val {\n constructor(public expr: Exprs.Val) {\n super();\n }\n\n /**\n * @override\n */\n toExpr(): Exprs.Val {\n return this.expr;\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"-epubx-expr(\");\n this.expr.appendTo(buf, 0);\n buf.append(\")\");\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitExpr(this);\n }\n\n /**\n * @override\n */\n isExpr(): boolean {\n return true;\n }\n}\n\nexport function toNumber(val: Val, context: Exprs.Context): number {\n if (val) {\n if (val.isNumeric()) {\n const numeric = val as Numeric;\n return context.queryUnitSize(numeric.unit, false) * numeric.num;\n }\n if (val.isNum()) {\n return (val as Num).num;\n }\n }\n return 0;\n}\n\n/**\n * Convert numeric value to px\n */\nexport function convertNumericToPx(val: Val, context: Exprs.Context): Numeric {\n return new Numeric(toNumber(val, context), \"px\");\n}\n\nexport const ident: { [key: string]: Ident } = {\n absolute: getName(\"absolute\"),\n all: getName(\"all\"),\n always: getName(\"always\"),\n auto: getName(\"auto\"),\n avoid: getName(\"avoid\"),\n balance: getName(\"balance\"),\n balance_all: getName(\"balance-all\"),\n block: getName(\"block\"),\n block_end: getName(\"block-end\"),\n block_start: getName(\"block-start\"),\n both: getName(\"both\"),\n bottom: getName(\"bottom\"),\n border_box: getName(\"border-box\"),\n break_all: getName(\"break-all\"),\n break_word: getName(\"break-word\"),\n crop: getName(\"crop\"),\n cross: getName(\"cross\"),\n column: getName(\"column\"),\n exclusive: getName(\"exclusive\"),\n _false: getName(\"false\"),\n fixed: getName(\"fixed\"),\n flex: getName(\"flex\"),\n footnote: getName(\"footnote\"),\n footer: getName(\"footer\"),\n header: getName(\"header\"),\n hidden: getName(\"hidden\"),\n horizontal_tb: getName(\"horizontal-tb\"),\n inherit: getName(\"inherit\"),\n inline: getName(\"inline\"),\n inline_block: getName(\"inline-block\"),\n inline_end: getName(\"inline-end\"),\n inline_start: getName(\"inline-start\"),\n landscape: getName(\"landscape\"),\n left: getName(\"left\"),\n line: getName(\"line\"),\n list_item: getName(\"list-item\"),\n ltr: getName(\"ltr\"),\n manual: getName(\"manual\"),\n none: getName(\"none\"),\n normal: getName(\"normal\"),\n oeb_page_foot: getName(\"oeb-page-foot\"),\n oeb_page_head: getName(\"oeb-page-head\"),\n page: getName(\"page\"),\n relative: getName(\"relative\"),\n right: getName(\"right\"),\n same: getName(\"same\"),\n scale: getName(\"scale\"),\n snap_block: getName(\"snap-block\"),\n spread: getName(\"spread\"),\n _static: getName(\"static\"),\n rtl: getName(\"rtl\"),\n table: getName(\"table\"),\n table_caption: getName(\"table-caption\"),\n table_cell: getName(\"table-cell\"),\n table_footer_group: getName(\"table-footer-group\"),\n table_header_group: getName(\"table-header-group\"),\n table_row: getName(\"table-row\"),\n top: getName(\"top\"),\n transparent: getName(\"transparent\"),\n vertical_lr: getName(\"vertical-lr\"),\n vertical_rl: getName(\"vertical-rl\"),\n visible: getName(\"visible\"),\n _true: getName(\"true\"),\n};\n\nexport const hundredPercent: Numeric = new Numeric(100, \"%\");\n\nexport const fullWidth: Numeric = new Numeric(100, \"pvw\");\n\nexport const fullHeight: Numeric = new Numeric(100, \"pvh\");\n\nexport const numericZero: Numeric = new Numeric(0, \"px\");\n\nexport const processingOrder = {\n \"font-size\": 1,\n color: 2,\n};\n\n/**\n * Function to sort property names in the order they should be processed\n */\nexport function processingOrderFn(name1: string, name2: string): number {\n const n1 = processingOrder[name1] || Number.MAX_VALUE;\n const n2 = processingOrder[name2] || Number.MAX_VALUE;\n return n1 - n2;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview GeometryUtil - Geometric utilities.\n */\nimport * as Logging from \"./logging\";\n\nexport class Rect {\n constructor(\n public x1: number,\n public y1: number,\n public x2: number,\n public y2: number,\n ) {}\n}\n\nexport class Point {\n constructor(public x: number, public y: number) {}\n}\n\nexport class Insets {\n constructor(\n public left: number,\n public top: number,\n public right: number,\n public bottom: number,\n ) {}\n}\n\nexport class Segment {\n constructor(\n public low: Point,\n public high: Point,\n public winding: number,\n public shapeId: number,\n ) {}\n}\n\n/**\n * A single band for exclusion result. Left float is from the left box edge\n * to x1. Right float is from x2 to the right box edge.\n */\nexport class Band {\n /** Left float. */\n left: Element | null = null;\n\n /** Right float. */\n right: Element | null = null;\n\n constructor(\n public y1: number,\n public y2: number,\n public x1: number,\n public x2: number,\n ) {}\n}\n\nexport function segmentCompare(s1: Segment, s2: Segment): number {\n return s1.low.y - s2.low.y || s1.low.x - s2.low.x;\n}\n\nexport class Shape {\n constructor(public points: Point[]) {}\n\n /**\n * Converts this shape to a sequence of Segments and adds segments to the\n * given array.\n * @param arr array to add segments.\n * @param id shapeId to write into segments.\n */\n addSegments(arr: Segment[], id: number): void {\n const points = this.points;\n const length = points.length;\n let prev = points[length - 1];\n for (let i = 0; i < length; i++) {\n const curr = points[i];\n let s: Segment;\n if (prev.y < curr.y) {\n s = new Segment(prev, curr, 1, id);\n } else {\n s = new Segment(curr, prev, -1, id);\n }\n arr.push(s);\n prev = curr;\n }\n }\n\n withOffset(offsetX: number, offsetY: number): Shape {\n const points = [];\n for (const p of this.points) {\n points.push(new Point(p.x + offsetX, p.y + offsetY));\n }\n return new Shape(points);\n }\n}\n\nexport function shapeForEllipse(\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n): Shape {\n const count = 20;\n const points: Point[] = [];\n for (let i = 0; i < count; i++) {\n const a = (i * 2 * Math.PI) / count;\n points.push(new Point(cx + rx * Math.sin(a), cy + ry * Math.cos(a)));\n }\n return new Shape(points);\n}\n\nexport function shapeForRect(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): Shape {\n return new Shape([\n new Point(x1, y1),\n new Point(x2, y1),\n new Point(x2, y2),\n new Point(x1, y2),\n ]);\n}\n\nexport function shapeForRectObj(r: Rect): Shape {\n return new Shape([\n new Point(r.x1, r.y1),\n new Point(r.x2, r.y1),\n new Point(r.x2, r.y2),\n new Point(r.x1, r.y2),\n ]);\n}\n\nexport class BandIntersection {\n constructor(\n public x: number,\n public winding: number,\n public shapeId: number,\n public lowOrHigh: number,\n ) {}\n}\n\nexport function intersectY(s: Segment, y: number): number {\n const x =\n s.low.x + ((s.high.x - s.low.x) * (y - s.low.y)) / (s.high.y - s.low.y);\n if (isNaN(x)) {\n throw new Error(\"Bad intersection\");\n }\n return x;\n}\n\nexport function addBandIntersections(\n intersections: BandIntersection[],\n s: Segment,\n y1: number,\n y2: number,\n): void {\n let x1: number;\n let w1: number;\n let x2: number;\n let w2: number;\n if (s.high.y < y1) {\n Logging.logger.warn(\"Error: inconsistent segment (1)\");\n }\n if (s.low.y <= y1) {\n // outside\n x1 = intersectY(s, y1);\n w1 = s.winding;\n } else {\n x1 = s.low.x;\n w1 = 0;\n }\n if (s.high.y >= y2) {\n // outside\n x2 = intersectY(s, y2);\n w2 = s.winding;\n } else {\n x2 = s.high.x;\n w2 = 0;\n }\n if (x1 < x2) {\n intersections.push(new BandIntersection(x1, w1, s.shapeId, -1));\n intersections.push(new BandIntersection(x2, w2, s.shapeId, 1));\n } else {\n intersections.push(new BandIntersection(x2, w2, s.shapeId, -1));\n intersections.push(new BandIntersection(x1, w1, s.shapeId, 1));\n }\n}\n\nexport function mergeIntersections(\n intersections: BandIntersection[],\n includeCount: number,\n excludeCount: number,\n): number[] {\n const shapeCount = includeCount + excludeCount;\n const windings1: number[] = Array(shapeCount);\n const windings2: number[] = Array(shapeCount);\n let i: number;\n for (i = 0; i <= shapeCount; i++) {\n windings1[i] = 0;\n windings2[i] = 0;\n }\n const xranges: number[] = [];\n let inside: boolean = false;\n const intersectionCount = intersections.length;\n for (let k = 0; k < intersectionCount; k++) {\n const intersection = intersections[k];\n windings1[intersection.shapeId] += intersection.winding;\n windings2[intersection.shapeId] += intersection.lowOrHigh;\n let stillInside = false;\n for (i = 0; i < includeCount; i++) {\n if (windings1[i] && !windings2[i]) {\n stillInside = true;\n break;\n }\n }\n if (stillInside) {\n for (i = includeCount; i <= shapeCount; i++) {\n if (windings1[i] || windings2[i]) {\n stillInside = false;\n break;\n }\n }\n }\n if (inside != stillInside) {\n xranges.push(intersection.x);\n inside = stillInside;\n }\n }\n return xranges;\n}\n\n/**\n * Round v up to make it a multiple of unit. If unit is zero, return v.\n */\nexport function ceil(v: number, unit: number): number {\n return unit ? Math.ceil(v / unit) * unit : v;\n}\n\n/**\n * Round v down to make it a multiple of unit. If unit is zero, return v.\n */\nexport function floor(v: number, unit: number): number {\n return unit ? Math.floor(v / unit) * unit : v;\n}\n\nexport function rotatePoint(point: Point): Point {\n return new Point(point.y, -point.x);\n}\n\n/**\n * Vertical box to pseudo-horizontal coords.\n */\nexport function rotateBox(box: Rect): Rect {\n return new Rect(box.y1, -box.x2, box.y2, -box.x1);\n}\n\n/**\n * Pseudo-horizontal coords to vertical.\n */\nexport function unrotateBox(box: Rect): Rect {\n return new Rect(-box.y2, box.x1, -box.y1, box.x2);\n}\n\nexport function rotateShape(shape: Shape): Shape {\n return new Shape(shape.points.map((point) => rotatePoint(point)));\n}\n\nexport function shapesToBands(\n box: Rect,\n include: Shape[],\n exclude: Shape[],\n granularity: number,\n snapHeight: number,\n vertical: boolean,\n): Band[] {\n if (vertical) {\n box = rotateBox(box);\n include = include.map((shape) => rotateShape(shape));\n exclude = exclude.map((shape) => rotateShape(shape));\n }\n const includeCount = include.length;\n const excludeCount = exclude ? exclude.length : 0;\n const result: Band[] = [];\n const segments: Segment[] = [];\n let i: number;\n let k: number;\n let segment: Segment;\n for (i = 0; i < includeCount; i++) {\n include[i].addSegments(segments, i);\n }\n for (i = 0; i < excludeCount; i++) {\n exclude[i].addSegments(segments, i + includeCount);\n }\n const segmentCount = segments.length;\n segments.sort(segmentCompare);\n let lowestIncludeIndex = 0;\n while (segments[lowestIncludeIndex].shapeId >= includeCount) {\n lowestIncludeIndex++;\n }\n let y = segments[lowestIncludeIndex].low.y;\n if (y > box.y1) {\n result.push(new Band(box.y1, y, box.x2, box.x2));\n }\n let segmentIndex = 0;\n const activeSegments: Segment[] = [];\n while (\n segmentIndex < segmentCount &&\n (segment = segments[segmentIndex]).low.y < y\n ) {\n if (segment.high.y > y) {\n activeSegments.push(segment);\n }\n segmentIndex++;\n }\n\n // process the segments from low to high y values\n while (segmentIndex < segmentCount || activeSegments.length > 0) {\n // calculate the height of the band to work with\n let y2 = box.y2; // band bottom\n // min possible y2\n const y2min = Math.min(\n ceil(Math.ceil(y + granularity), snapHeight),\n box.y2,\n );\n for (k = 0; k < activeSegments.length && y2 > y2min; k++) {\n segment = activeSegments[k];\n if (segment.low.x == segment.high.x) {\n // vertical\n if (segment.high.y < y2) {\n y2 = Math.max(floor(segment.high.y, snapHeight), y2min);\n }\n } else if (segment.low.x != segment.high.x) {\n // TODO: should we compare y???\n // slanted (not horizontal)\n y2 = y2min;\n }\n }\n if (y2 > box.y2) {\n y2 = box.y2;\n }\n\n // include new segments, decreasing y2 if needed\n while (\n segmentIndex < segmentCount &&\n (segment = segments[segmentIndex]).low.y < y2\n ) {\n if (segment.high.y < y) {\n segmentIndex++;\n continue;\n }\n if (segment.low.y < y2min) {\n if (segment.low.y == segment.high.y && segment.low.y == y) {\n // Horizontal segment that goes right at y is not active,\n // but consume it anyway\n } else {\n activeSegments.push(segment);\n y2 = y2min;\n }\n segmentIndex++;\n } else {\n // Do not consume it, consider bottom edge \"outside\"\n const yn = floor(segment.low.y, snapHeight);\n if (yn < y2) {\n y2 = yn;\n }\n break;\n }\n }\n\n // now look at the band with top at y and bottom at y2\n // activeSegments should list all segments that intersect that band\n\n // find all intersections with the band\n const bandIntersections: BandIntersection[] = [];\n for (k = 0; k < activeSegments.length; k++) {\n addBandIntersections(bandIntersections, activeSegments[k], y, y2);\n }\n bandIntersections.sort(\n (bi1, bi2) => bi1.x - bi2.x || bi1.lowOrHigh - bi2.lowOrHigh,\n );\n const xranges = mergeIntersections(\n bandIntersections,\n includeCount,\n excludeCount,\n );\n if (xranges.length == 0) {\n result.push(new Band(y, y2, box.x2, box.x2));\n } else {\n // get the widest\n let width = 0;\n let x = box.x1;\n for (k = 0; k < xranges.length; k += 2) {\n const rx = Math.max(box.x1, xranges[k]);\n const rw = Math.min(box.x2, xranges[k + 1]) - rx;\n if (rw > width) {\n width = rw;\n x = rx;\n }\n }\n if (width == 0) {\n // no space left\n result.push(new Band(y, y2, box.x2, box.x2));\n } else {\n result.push(\n new Band(y, y2, Math.max(x, box.x1), Math.min(x + width, box.x2)),\n );\n }\n }\n if (y2 == box.y2) {\n break;\n }\n y = y2;\n for (k = activeSegments.length - 1; k >= 0; k--) {\n if (activeSegments[k].high.y <= y2) {\n activeSegments.splice(k, 1);\n }\n }\n }\n normalize(box, result);\n return result;\n}\n\nexport function normalize(box: Rect, bands: Band[]): void {\n let k = bands.length - 1;\n\n // Merge bands with the same x1, x2 and remove unneeded bands at the end.\n // Create fictious last band to merge unneeded bands at the end\n let currBand = new Band(box.y2, box.y2, box.x1, box.x2);\n while (k >= 0) {\n const prevBand = currBand; // result[k+1]\n currBand = bands[k];\n if (\n currBand.y2 - currBand.y1 < 1 || // Remove bands with height less than 1px\n (currBand.x1 == prevBand.x1 && currBand.x2 == prevBand.x2)\n ) {\n prevBand.y1 = currBand.y1; // merge\n bands.splice(k, 1);\n currBand = prevBand;\n }\n k--;\n }\n}\n\n/**\n * Find the index of the bottommost band so that y < band.y2\n */\nexport function findBand(bands: Band[], y: number): number {\n let low = 0;\n let high = bands.length;\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n if (y >= bands[mid].y2) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n}\n\n/**\n * Find the uppermost rectangle contained in the specified rect which occupies\n * full width of the rect without overlapping with any band in the specified\n * bands.\n * @returns Returns null if such rectangle does not exist.\n */\nexport function findUppermostFullyOpenRect(\n bands: Band[],\n rect: Rect,\n): Rect | null {\n if (!bands.length) {\n return rect;\n }\n let topEdge = rect.y1;\n let band: Band;\n let i: number;\n for (i = 0; i < bands.length; i++) {\n band = bands[i];\n if (\n band.y2 > rect.y1 &&\n band.x1 - 0.1 <= rect.x1 &&\n band.x2 + 0.1 >= rect.x2\n ) {\n break;\n } else {\n topEdge = Math.max(topEdge, band.y2);\n }\n }\n let bottomEdge = topEdge;\n for (; i < bands.length; i++) {\n band = bands[i];\n if (\n band.y1 >= rect.y2 ||\n band.x1 - 0.1 > rect.x1 ||\n band.x2 + 0.1 < rect.x2\n ) {\n break;\n } else {\n bottomEdge = band.y2;\n }\n }\n if (i === bands.length) {\n bottomEdge = rect.y2;\n } else {\n bottomEdge = Math.min(bottomEdge, rect.y2);\n }\n if (bottomEdge <= topEdge) {\n return null;\n } else {\n return new Rect(rect.x1, topEdge, rect.x2, bottomEdge);\n }\n}\n\n/**\n * Find the bottommost rectangle contained in the specified rect which occupies\n * full width of the rect without overlapping with any band in the specified\n * bands.\n * @returns Returns null if such rectangle does not exist.\n */\nexport function findBottommostFullyOpenRect(\n bands: Band[],\n rect: Rect,\n): Rect | null {\n if (!bands.length) {\n return rect;\n }\n let bottomEdge = rect.y2;\n let band: Band;\n let i: number;\n for (i = bands.length - 1; i >= 0; i--) {\n band = bands[i];\n if (i === bands.length - 1 && band.y2 < rect.y2) {\n break;\n } else if (\n band.y1 < rect.y2 &&\n band.x1 - 0.1 <= rect.x1 &&\n band.x2 + 0.1 >= rect.x2\n ) {\n break;\n } else {\n bottomEdge = Math.min(bottomEdge, band.y1);\n }\n }\n let topEdge = Math.min(bottomEdge, band.y2);\n for (; i >= 0; i--) {\n band = bands[i];\n if (\n band.y2 <= rect.y1 ||\n band.x1 - 0.1 > rect.x1 ||\n band.x2 + 0.1 < rect.x2\n ) {\n break;\n } else {\n topEdge = band.y1;\n }\n }\n topEdge = Math.max(topEdge, rect.y1);\n if (bottomEdge <= topEdge) {\n return null;\n } else {\n return new Rect(rect.x1, topEdge, rect.x2, bottomEdge);\n }\n}\n\n/**\n * @param side either \"left\" or \"right\"\n */\nexport function positionFloat(\n box: Rect,\n bands: Band[],\n floatBox: Rect,\n side: string,\n): boolean {\n let y = floatBox.y1;\n const floatWidth = floatBox.x2 - floatBox.x1;\n const floatHeight = floatBox.y2 - floatBox.y1;\n let index = findBand(bands, y);\n while (true) {\n // Check if it fits\n const floatBottom = y + floatHeight;\n if (floatBottom > box.y2) {\n return false;\n }\n\n // does not fit vertically\n let x1 = box.x1;\n let x2 = box.x2;\n for (let i = index; i < bands.length && bands[i].y1 < floatBottom; i++) {\n const band = bands[i];\n if (band.x1 > x1) {\n x1 = band.x1;\n }\n if (band.x2 < x2) {\n x2 = band.x2;\n }\n }\n if (x1 + floatWidth <= x2 || index >= bands.length) {\n if (side == \"left\") {\n floatBox.x1 = x1;\n floatBox.x2 = x1 + floatWidth;\n } else {\n floatBox.x1 = x2 - floatWidth;\n floatBox.x2 = x2;\n }\n floatBox.y2 += y - floatBox.y1;\n floatBox.y1 = y;\n return true;\n }\n y = bands[index].y2;\n index++;\n }\n}\n\nexport function addFloatToBands(\n box: Rect,\n bands: Band[],\n floatBox: Rect,\n floatBands: Band[],\n side: string,\n): void {\n if (!floatBands) {\n floatBands = [new Band(floatBox.y1, floatBox.y2, floatBox.x1, floatBox.x2)];\n }\n while (floatBands.length > 0 && floatBands[0].y2 <= box.y1) {\n floatBands.shift();\n }\n if (floatBands.length == 0) {\n return;\n }\n if (floatBands[0].y1 < box.y1) {\n floatBands[0].y1 = box.y1;\n }\n let band: Band;\n const lastY = bands.length == 0 ? box.y1 : bands[bands.length - 1].y2;\n if (lastY < box.y2) {\n // add the tail band that we typically don't keep, it will be cleared by\n // normalize()\n bands.push(new Band(lastY, box.y2, box.x1, box.x2));\n }\n let index = findBand(bands, floatBands[0].y1);\n for (const floatBand of floatBands) {\n if (index == bands.length) {\n break;\n }\n if (bands[index].y1 < floatBand.y1) {\n // split it\n band = bands[index];\n index++;\n bands.splice(index, 0, new Band(floatBand.y1, band.y2, band.x1, band.x2));\n band.y2 = floatBand.y1;\n }\n while (index < bands.length) {\n band = bands[index++];\n if (band.y2 > floatBand.y2) {\n // split it\n bands.splice(\n index,\n 0,\n new Band(floatBand.y2, band.y2, band.x1, band.x2),\n );\n band.y2 = floatBand.y2;\n }\n if (floatBand.x1 != floatBand.x2) {\n // non-empty floatBand\n if (side == \"left\") {\n band.x1 = Math.min(floatBand.x2, box.x2);\n } else {\n band.x2 = Math.max(floatBand.x1, box.x1);\n }\n }\n if (band.y2 == floatBand.y2) {\n break;\n }\n }\n }\n normalize(box, bands);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssProp - Support utilities to extract information\n * from various (parsed) CSS values.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as Exprs from \"./exprs\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Logging from \"./logging\";\n\n//---------------------- value parsers ----------------------------------\nexport class SetVisitor extends Css.Visitor {\n propSet: { [key: string]: boolean } = {};\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n this.propSet[ident.name] = true;\n return ident;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return list;\n }\n}\n\nexport function toSet(val: Css.Val): { [key: string]: boolean } {\n if (val) {\n const visitor = new SetVisitor();\n try {\n val.visit(visitor);\n return visitor.propSet;\n } catch (err) {\n Logging.logger.warn(err, \"toSet:\");\n }\n }\n return {};\n}\n\nexport class IntVisitor extends Css.Visitor {\n constructor(public value: number) {\n super();\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n this.value = num.num;\n return num;\n }\n}\n\nexport function toInt(val: Css.Val, def: number): number {\n if (val) {\n const visitor = new IntVisitor(def);\n try {\n val.visit(visitor);\n return visitor.value;\n } catch (err) {\n Logging.logger.warn(err, \"toInt: \");\n }\n }\n return def;\n}\n\nexport class ShapeVisitor extends Css.Visitor {\n collect: boolean = false;\n coords: Css.Numeric[] = [];\n name: string | null = null;\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n if (this.collect) {\n this.coords.push(numeric);\n }\n return null;\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n if (this.collect && num.num == 0) {\n this.coords.push(new Css.Numeric(0, \"px\"));\n }\n return null;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n if (!this.collect) {\n this.collect = true;\n this.visitValues(func.values);\n this.collect = false;\n this.name = func.name.toLowerCase();\n }\n return null;\n }\n\n getShape(\n x: number,\n y: number,\n width: number,\n height: number,\n context: Exprs.Context,\n ): GeometryUtil.Shape {\n if (this.coords.length > 0) {\n const numbers: number[] = [];\n this.coords.forEach((coord, i) => {\n if (coord.unit == \"%\") {\n let ref = i % 2 == 0 ? width : height;\n if (i == 3 && this.name == \"circle\") {\n ref = Math.sqrt((width * width + height * height) / 2);\n }\n numbers.push((coord.num * ref) / 100);\n } else {\n numbers.push(coord.num * context.queryUnitSize(coord.unit, false));\n }\n });\n switch (this.name) {\n case \"polygon\":\n if (numbers.length % 2 == 0) {\n const points: GeometryUtil.Point[] = [];\n for (let k = 0; k < numbers.length; k += 2) {\n points.push(\n new GeometryUtil.Point(x + numbers[k], y + numbers[k + 1]),\n );\n }\n return new GeometryUtil.Shape(points);\n }\n break;\n case \"rectangle\":\n if (numbers.length == 4) {\n return GeometryUtil.shapeForRect(\n x + numbers[0],\n y + numbers[1],\n x + numbers[0] + numbers[2],\n y + numbers[1] + numbers[3],\n );\n }\n break;\n case \"ellipse\":\n if (numbers.length == 4) {\n return GeometryUtil.shapeForEllipse(\n x + numbers[0],\n y + numbers[1],\n numbers[2],\n numbers[3],\n );\n }\n break;\n case \"circle\":\n if (numbers.length == 3) {\n return GeometryUtil.shapeForEllipse(\n x + numbers[0],\n y + numbers[1],\n numbers[2],\n numbers[2],\n );\n }\n break;\n }\n }\n return null;\n }\n}\n\nexport function toShape(\n val: Css.Val,\n x: number,\n y: number,\n width: number,\n height: number,\n context: Exprs.Context,\n): GeometryUtil.Shape {\n if (val) {\n const visitor = new ShapeVisitor();\n try {\n val.visit(visitor);\n return visitor.getShape(x, y, width, height, context);\n } catch (err) {\n Logging.logger.warn(err, \"toShape:\");\n }\n }\n return GeometryUtil.shapeForRect(x, y, x + width, y + height);\n}\n\nexport class CountersVisitor extends Css.Visitor {\n counters: { [key: string]: number } = {};\n name: string | null = null;\n\n constructor(public readonly reset: boolean) {\n super();\n }\n\n /** @override */\n visitIdent(ident: Css.Ident): Css.Val {\n this.name = ident.toString();\n if (this.reset) {\n this.counters[this.name] = 0;\n } else {\n this.counters[this.name] = (this.counters[this.name] || 0) + 1;\n }\n return ident;\n }\n\n /** @override */\n visitInt(num: Css.Int): Css.Val {\n if (this.name) {\n this.counters[this.name] += num.num - (this.reset ? 0 : 1);\n }\n return num;\n }\n\n /** @override */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return list;\n }\n}\n\nexport function toCounters(\n val: Css.Val,\n reset: boolean,\n): { [key: string]: number } {\n const visitor = new CountersVisitor(reset);\n try {\n val.visit(visitor);\n } catch (err) {\n Logging.logger.warn(err, \"toCounters:\");\n }\n return visitor.counters;\n}\n\nexport class UrlTransformVisitor extends Css.FilterVisitor {\n constructor(\n public baseUrl: string,\n public transformer: Base.DocumentURLTransformer,\n ) {\n super();\n }\n\n /** @override */\n visitURL(url: Css.URL): Css.Val {\n return new Css.URL(this.transformer.transformURL(url.url, this.baseUrl));\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Counters\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssStyler from \"./css-styler\";\nimport * as Exprs from \"./exprs\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport { Layout } from \"./types\";\n\n/**\n * Clone counter values.\n */\nfunction cloneCounterValues(\n counters: CssCascade.CounterValues,\n): CssCascade.CounterValues {\n const result = {};\n Object.keys(counters).forEach((name) => {\n result[name] = Array.from(counters[name]);\n });\n return result;\n}\n\n/**\n * Class representing a reference by target-counter(s).\n * @param targetId ID of the referenced element (transformed by\n * DocumentURLTransformer to handle a reference across multiple source\n * documents)\n * @param resolved If the reference is already resolved or not\n */\nexport class TargetCounterReference {\n pageCounters: CssCascade.CounterValues = null;\n spineIndex: number = -1;\n pageIndex: number = -1;\n\n constructor(public readonly targetId: string, public resolved: boolean) {}\n\n equals(other: TargetCounterReference): boolean {\n if (this === other) {\n return true;\n }\n if (!other) {\n return false;\n }\n return (\n this.targetId === other.targetId &&\n this.resolved === other.resolved &&\n this.spineIndex === other.spineIndex &&\n this.pageIndex === other.pageIndex\n );\n }\n\n /**\n * Returns if the reference is resolved or not.\n */\n isResolved(): boolean {\n return this.resolved;\n }\n\n /**\n * Marks that this reference is resolved.\n */\n resolve() {\n this.resolved = true;\n }\n\n /**\n * Marks that this reference is unresolved.\n */\n unresolve() {\n this.resolved = false;\n }\n}\n\nclass CounterListener implements CssCascade.CounterListener {\n constructor(\n public readonly counterStore: CounterStore,\n public readonly baseURL: string,\n ) {}\n\n /**\n * @override\n */\n countersOfId(id: string, counters: CssCascade.CounterValues) {\n id = this.counterStore.documentURLTransformer.transformFragment(\n id,\n this.baseURL,\n );\n this.counterStore.countersById[id] = counters;\n }\n\n getExprContentListener(): Vtree.ExprContentListener {\n return this.counterStore.getExprContentListener();\n }\n}\n\nclass CounterResolver implements CssCascade.CounterResolver {\n styler: CssStyler.Styler | null = null;\n\n constructor(\n public readonly counterStore: CounterStore,\n public readonly baseURL: string,\n public readonly rootScope: Exprs.LexicalScope,\n public readonly pageScope: Exprs.LexicalScope,\n ) {}\n\n setStyler(styler: CssStyler.Styler) {\n this.styler = styler;\n }\n\n private getFragment(url: string): string | null {\n const r = url.match(/^[^#]*#(.*)$/);\n return r ? r[1] : null;\n }\n\n private getTransformedId(url: string): string {\n let transformedId = this.counterStore.documentURLTransformer.transformURL(\n Base.resolveURL(url, this.baseURL),\n this.baseURL,\n );\n if (transformedId.charAt(0) === \"#\") {\n transformedId = transformedId.substring(1);\n }\n return transformedId;\n }\n\n /**\n * @override\n */\n getPageCounterVal(\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val {\n const self = this;\n\n function getCounterNumber() {\n const values = self.counterStore.currentPageCounters[name];\n return values && values.length ? values[values.length - 1] : null;\n }\n const expr = new Exprs.Native(\n this.pageScope,\n () => format(getCounterNumber()),\n `page-counter-${name}`,\n );\n\n function arrayFormat(arr) {\n return format(arr[0]);\n }\n this.counterStore.registerPageCounterExpr(name, arrayFormat, expr);\n return expr;\n }\n\n /**\n * @override\n */\n getPageCountersVal(\n name: string,\n format: (p1: number[]) => string,\n ): Exprs.Val {\n const self = this;\n\n function getCounterNumbers() {\n return self.counterStore.currentPageCounters[name] || [];\n }\n const expr = new Exprs.Native(\n this.pageScope,\n () => format(getCounterNumbers()),\n `page-counters-${name}`,\n );\n this.counterStore.registerPageCounterExpr(name, format, expr);\n return expr;\n }\n\n /**\n * Returns (non page-based) counter values for an element with the specified\n * ID. Returns null if the style of the elements has not been calculated yet\n * (i.e. the element does not exit or it is in a source document which is not\n * loaded yet).\n * @param id Original ID value\n * @param transformedId ID transformed by DocumentURLTransformer to handle a\n * reference across multiple source documents\n * @param lookForElement If true, look ahead for an element with the ID in the\n * current source document when such an element has not appeared yet. Do\n * not set to true during Styler.styleUntil is being called, since in that\n * case Styler.styleUntil can be called again and may lead to internal\n * inconsistency.\n */\n private getTargetCounters(\n id: string | null,\n transformedId: string,\n lookForElement: boolean,\n ): CssCascade.CounterValues | null {\n let targetCounters = this.counterStore.countersById[transformedId];\n if (!targetCounters && lookForElement && id) {\n this.styler.styleUntilIdIsReached(id);\n targetCounters = this.counterStore.countersById[transformedId];\n }\n return targetCounters || null;\n }\n\n /**\n * Returns page-based counter values for an element with the specified ID.\n * Returns null if the element has not been laid out yet.\n * @param transformedId ID transformed by DocumentURLTransformer to handle a\n * reference across multiple source documents\n */\n private getTargetPageCounters(\n transformedId: string,\n ): CssCascade.CounterValues | null {\n if (this.counterStore.currentPage.elementsById[transformedId]) {\n return this.counterStore.currentPageCounters;\n } else {\n return this.counterStore.pageCountersById[transformedId] || null;\n }\n }\n\n /**\n * @override\n */\n getTargetCounterVal(\n url: string,\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val {\n const id = this.getFragment(url);\n const transformedId = this.getTransformedId(url);\n\n // Since this method is executed during Styler.styleUntil is being called,\n // set false to lookForElement argument.\n let counters = this.getTargetCounters(id, transformedId, false);\n if (counters && counters[name]) {\n // Since an element-based counter is defined, any page-based counter is\n // obscured even if it exists.\n const countersOfName = counters[name];\n return new Exprs.Const(\n this.rootScope,\n format(countersOfName[countersOfName.length - 1] || null),\n );\n }\n const self = this;\n return new Exprs.Native(\n this.pageScope,\n () => {\n // Since This block is evaluated during layout, lookForElement\n // argument can be set to true.\n counters = self.getTargetCounters(id, transformedId, true);\n\n if (counters) {\n if (counters[name]) {\n // Since an element-based counter is defined, any page-based\n // counter is obscured even if it exists.\n const countersOfName = counters[name];\n return format(countersOfName[countersOfName.length - 1] || null);\n } else {\n const pageCounters = self.getTargetPageCounters(transformedId);\n if (pageCounters) {\n // The target element has already been laid out.\n self.counterStore.resolveReference(transformedId);\n if (pageCounters[name]) {\n const pageCountersOfName = pageCounters[name];\n return format(\n pageCountersOfName[pageCountersOfName.length - 1] || null,\n );\n } else {\n // No corresponding counter with the name.\n return format(0);\n }\n } else {\n // The target element has not been laid out yet.\n self.counterStore.saveReferenceOfCurrentPage(\n transformedId,\n false,\n );\n return \"??\"; // TODO more reasonable placeholder?\n }\n }\n } else {\n // The style of target element has not been calculated yet.\n // (The element is in another source document that is not parsed\n // yet)\n self.counterStore.saveReferenceOfCurrentPage(transformedId, false);\n return \"??\"; // TODO more reasonable placeholder?\n }\n },\n `target-counter-${name}-of-${url}`,\n );\n }\n\n /**\n * @override\n */\n getTargetCountersVal(\n url: string,\n name: string,\n format: (p1: number[]) => string,\n ): Exprs.Val {\n const id = this.getFragment(url);\n const transformedId = this.getTransformedId(url);\n const self = this;\n return new Exprs.Native(\n this.pageScope,\n () => {\n const pageCounters = self.getTargetPageCounters(transformedId);\n\n if (!pageCounters) {\n // The target element has not been laid out yet.\n self.counterStore.saveReferenceOfCurrentPage(transformedId, false);\n return \"??\"; // TODO more reasonable placeholder?\n } else {\n self.counterStore.resolveReference(transformedId);\n const pageCountersOfName = pageCounters[name] || [];\n const elementCounters = self.getTargetCounters(\n id,\n transformedId,\n true,\n );\n const elementCountersOfName = elementCounters[name] || [];\n return format(pageCountersOfName.concat(elementCountersOfName));\n }\n },\n `target-counters-${name}-of-${url}`,\n );\n }\n}\n\nexport class CounterStore {\n countersById: { [key: string]: CssCascade.CounterValues } = {};\n pageCountersById: { [key: string]: CssCascade.CounterValues } = {};\n currentPageCounters: CssCascade.CounterValues = {};\n previousPageCounters: CssCascade.CounterValues = {};\n currentPageCountersStack: CssCascade.CounterValues[] = [];\n pageIndicesById: {\n [key: string]: { spineIndex: number; pageIndex: number };\n } = {};\n currentPage: Vtree.Page = null;\n newReferencesOfCurrentPage: TargetCounterReference[] = [];\n referencesToSolve: TargetCounterReference[] = [];\n referencesToSolveStack: TargetCounterReference[][] = [];\n unresolvedReferences: { [key: string]: TargetCounterReference[] } = {};\n resolvedReferences: { [key: string]: TargetCounterReference[] } = {};\n private pagesCounterExprs: {\n expr: Exprs.Val;\n format: (p1: number[]) => string;\n }[] = [];\n\n constructor(\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n ) {\n this.currentPageCounters[\"page\"] = [0];\n }\n\n createCounterListener(baseURL: string): CssCascade.CounterListener {\n return new CounterListener(this, baseURL);\n }\n\n createCounterResolver(\n baseURL: string,\n rootScope: Exprs.LexicalScope,\n pageScope: Exprs.LexicalScope,\n ): CssCascade.CounterResolver {\n return new CounterResolver(this, baseURL, rootScope, pageScope);\n }\n\n setCurrentPage(page: Vtree.Page) {\n this.currentPage = page;\n }\n\n private definePageCounter(counterName: string, value: number) {\n if (this.currentPageCounters[counterName]) {\n this.currentPageCounters[counterName].push(value);\n } else {\n this.currentPageCounters[counterName] = [value];\n }\n }\n\n /**\n * Forcefully set the `page` page-based counter to the specified value.\n */\n forceSetPageCounter(pageNumber: number) {\n const counters = this.currentPageCounters[\"page\"];\n if (!counters || !counters.length) {\n this.currentPageCounters[\"page\"] = [pageNumber];\n } else {\n counters[counters.length - 1] = pageNumber;\n }\n }\n\n /**\n * Update the page-based counters with 'counter-reset' and 'counter-increment'\n * properties within the page context. Call before starting layout of the\n * page.\n */\n updatePageCounters(\n cascadedPageStyle: CssCascade.ElementStyle,\n context: Exprs.Context,\n ) {\n // Save page counters to previousPageCounters before updating\n this.previousPageCounters = cloneCounterValues(this.currentPageCounters);\n let resetMap: { [key: string]: number };\n const reset = cascadedPageStyle[\"counter-reset\"];\n if (reset) {\n const resetVal = reset.evaluate(context);\n if (resetVal) {\n resetMap = CssProp.toCounters(resetVal, true);\n }\n }\n if (resetMap) {\n for (const resetCounterName in resetMap) {\n this.definePageCounter(resetCounterName, resetMap[resetCounterName]);\n }\n }\n let incrementMap: { [key: string]: number };\n const increment = cascadedPageStyle[\"counter-increment\"];\n if (increment) {\n const incrementVal = increment.evaluate(context);\n if (incrementVal) {\n incrementMap = CssProp.toCounters(incrementVal, false);\n }\n }\n\n // If 'counter-increment' for the builtin 'page' counter is absent, add it\n // with value 1.\n if (incrementMap) {\n if (!(\"page\" in incrementMap)) {\n incrementMap[\"page\"] = 1;\n }\n } else {\n incrementMap = {};\n incrementMap[\"page\"] = 1;\n }\n for (const incrementCounterName in incrementMap) {\n if (!this.currentPageCounters[incrementCounterName]) {\n this.definePageCounter(incrementCounterName, 0);\n }\n const counterValues = this.currentPageCounters[incrementCounterName];\n counterValues[counterValues.length - 1] +=\n incrementMap[incrementCounterName];\n }\n }\n\n /**\n * Save current page-based counters values and set them to the values passed\n * in. The saved counter values can be restored by popPageCounters method.\n */\n pushPageCounters(counters: CssCascade.CounterValues) {\n this.currentPageCountersStack.push(this.currentPageCounters);\n this.currentPageCounters = cloneCounterValues(counters);\n }\n\n /**\n * Restore previously saved page-based counter values.\n */\n popPageCounters() {\n this.currentPageCounters = this.currentPageCountersStack.pop();\n }\n\n /**\n * Resolve a reference with the specified ID.\n */\n resolveReference(id: string) {\n const unresolvedRefs = this.unresolvedReferences[id];\n let resolvedRefs = this.resolvedReferences[id];\n if (!resolvedRefs) {\n resolvedRefs = this.resolvedReferences[id] = [];\n }\n let pushed = false;\n for (let i = 0; i < this.referencesToSolve.length; ) {\n const ref = this.referencesToSolve[i];\n if (ref.targetId === id) {\n ref.resolve();\n this.referencesToSolve.splice(i, 1);\n if (unresolvedRefs) {\n const j = unresolvedRefs.indexOf(ref);\n if (j >= 0) {\n unresolvedRefs.splice(j, 1);\n }\n }\n resolvedRefs.push(ref);\n pushed = true;\n } else {\n i++;\n }\n }\n if (!pushed) {\n this.saveReferenceOfCurrentPage(id, true);\n }\n }\n\n /**\n * Save a reference appeared in the current page.\n * @param resolved If the reference is already resolved or not.\n */\n saveReferenceOfCurrentPage(id: string, resolved: boolean) {\n if (!this.newReferencesOfCurrentPage.some((ref) => ref.targetId === id)) {\n const ref = new TargetCounterReference(id, resolved);\n this.newReferencesOfCurrentPage.push(ref);\n }\n }\n\n /**\n * Finish the current page; elements with ID are collected and saved with\n * current page-based counter values internally.\n * @param spineIndex Index of the currently laid out spine item\n * @param pageIndex Index of the currently laid out page in its spine item\n */\n finishPage(spineIndex: number, pageIndex: number) {\n const ids = Object.keys(this.currentPage.elementsById);\n if (ids.length > 0) {\n const currentPageCounters = cloneCounterValues(this.currentPageCounters);\n ids.forEach((id) => {\n this.pageCountersById[id] = currentPageCounters;\n const oldPageIndex = this.pageIndicesById[id];\n if (oldPageIndex && oldPageIndex.pageIndex < pageIndex) {\n const resolvedRefs = this.resolvedReferences[id];\n if (resolvedRefs) {\n let unresolvedRefs = this.unresolvedReferences[id];\n if (!unresolvedRefs) {\n unresolvedRefs = this.unresolvedReferences[id] = [];\n }\n let ref: TargetCounterReference;\n while ((ref = resolvedRefs.shift())) {\n ref.unresolve();\n unresolvedRefs.push(ref);\n }\n }\n }\n this.pageIndicesById[id] = { spineIndex, pageIndex };\n });\n }\n const prevPageCounters = this.previousPageCounters;\n let ref: TargetCounterReference;\n while ((ref = this.newReferencesOfCurrentPage.shift())) {\n ref.pageCounters = prevPageCounters;\n ref.spineIndex = spineIndex;\n ref.pageIndex = pageIndex;\n let arr: TargetCounterReference[];\n if (ref.isResolved()) {\n arr = this.resolvedReferences[ref.targetId];\n if (!arr) {\n arr = this.resolvedReferences[ref.targetId] = [];\n }\n } else {\n arr = this.unresolvedReferences[ref.targetId];\n if (!arr) {\n arr = this.unresolvedReferences[ref.targetId] = [];\n }\n }\n if (arr.every((r) => !ref.equals(r))) {\n arr.push(ref);\n }\n }\n this.currentPage = null;\n }\n\n /**\n * Returns unresolved references pointing to the specified page.\n */\n getUnresolvedRefsToPage(\n page: Vtree.Page,\n ): {\n spineIndex: number;\n pageIndex: number;\n pageCounters: CssCascade.CounterValues;\n refs: TargetCounterReference[];\n }[] {\n let refs: TargetCounterReference[] = [];\n const ids = Object.keys(page.elementsById);\n ids.forEach((id) => {\n const idRefs = this.unresolvedReferences[id];\n if (idRefs) {\n refs = refs.concat(idRefs);\n }\n });\n refs.sort(\n (r1, r2) => r1.spineIndex - r2.spineIndex || r1.pageIndex - r2.pageIndex,\n );\n const result: {\n spineIndex: number;\n pageIndex: number;\n pageCounters: CssCascade.CounterValues;\n refs: TargetCounterReference[];\n }[] = [];\n let o: {\n spineIndex: number;\n pageIndex: number;\n pageCounters: CssCascade.CounterValues;\n refs: TargetCounterReference[];\n } = null;\n refs.forEach((ref) => {\n if (\n !o ||\n o.spineIndex !== ref.spineIndex ||\n o.pageIndex !== ref.pageIndex\n ) {\n o = {\n spineIndex: ref.spineIndex,\n pageIndex: ref.pageIndex,\n pageCounters: ref.pageCounters,\n refs: [ref],\n };\n result.push(o);\n } else {\n o.refs.push(ref);\n }\n });\n return result;\n }\n\n /**\n * Save current references to solve and set them to the values passed in.\n * The saved references can be restored by popReferencesToSolve method.\n */\n pushReferencesToSolve(refs: TargetCounterReference[]) {\n this.referencesToSolveStack.push(this.referencesToSolve);\n this.referencesToSolve = refs;\n }\n\n /**\n * Restore previously saved references to solve.\n */\n popReferencesToSolve() {\n this.referencesToSolve = this.referencesToSolveStack.pop();\n }\n\n registerPageCounterExpr(\n name: string,\n format: (p1: number[]) => string,\n expr: Exprs.Val,\n ) {\n if (name === \"pages\") {\n this.pagesCounterExprs.push({ expr, format });\n }\n }\n\n getExprContentListener(): Vtree.ExprContentListener {\n return this.exprContentListener.bind(this);\n }\n\n private exprContentListener(expr, val, document) {\n const found = this.pagesCounterExprs.findIndex((o) => o.expr === expr) >= 0;\n if (found) {\n const node = document.createElement(\"span\");\n node.textContent = val;\n node.setAttribute(PAGES_COUNTER_ATTR, expr.key);\n return node;\n } else {\n return null;\n }\n }\n\n finishLastPage(viewport: Vgen.Viewport) {\n const nodes = viewport.root.querySelectorAll(`[${PAGES_COUNTER_ATTR}]`);\n const pages = this.currentPageCounters[\"page\"][0];\n Array.from(nodes).forEach((node) => {\n const key = node.getAttribute(PAGES_COUNTER_ATTR);\n const i = this.pagesCounterExprs.findIndex((o) => o.expr.key === key);\n Asserts.assert(i >= 0);\n node.textContent = this.pagesCounterExprs[i].format([pages]);\n });\n }\n\n createLayoutConstraint(pageIndex: number): Layout.LayoutConstraint {\n return new LayoutConstraint(this, pageIndex);\n }\n}\n\nexport const PAGES_COUNTER_ATTR = \"data-vivliostyle-pages-counter\";\n\nclass LayoutConstraint implements Layout.LayoutConstraint {\n constructor(\n public readonly counterStore: CounterStore,\n public readonly pageIndex: number,\n ) {}\n\n /**\n * @override\n */\n allowLayout(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext || nodeContext.after) {\n return true;\n }\n const viewNode = nodeContext.viewNode;\n if (!viewNode || viewNode.nodeType !== 1) {\n return true;\n }\n const id =\n (viewNode as Element).getAttribute(\"id\") ||\n (viewNode as Element).getAttribute(\"name\");\n if (!id) {\n return true;\n }\n if (\n !this.counterStore.resolvedReferences[id] &&\n !this.counterStore.unresolvedReferences[id]\n ) {\n return true;\n }\n const pageIndex = this.counterStore.pageIndicesById[id];\n if (!pageIndex) {\n return true;\n }\n return this.pageIndex >= pageIndex.pageIndex;\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssTokenizer - CSS Tokenizer.\n */\n\nexport interface TokenizerHandler {\n error(mnemonics: string, token: Token): void;\n}\n\nexport function escapeParseSingle(str: string): string {\n str = str.substr(1);\n if (str.match(/^[^0-9a-fA-F\\n\\r]$/)) {\n return str;\n }\n const code = parseInt(str, 16);\n if (isNaN(code)) {\n return \"\";\n }\n if (code <= 65535) {\n return String.fromCharCode(code);\n }\n if (code <= 1114111) {\n // non-BMP characters: convert to a surrogate pair\n return String.fromCharCode(\n 55296 | ((code >> 10) & 1023),\n 56320 | (code & 1023),\n );\n }\n\n // not a valid Unicode value\n return \"\\ufffd\";\n}\n\nexport function escapeParse(str: string): string {\n return str.replace(\n /\\\\([0-9a-fA-F]{0,6}(\\r\\n|[ \\n\\r\\t\\f])?|[^0-9a-fA-F\\n\\r])/g,\n escapeParseSingle,\n );\n}\n\n/**\n * @enum {number}\n */\nexport enum TokenType {\n EOF,\n IDENT,\n STR,\n NUMERIC,\n NUM,\n INT,\n FUNC,\n HASH,\n URL,\n CLASS,\n O_PAR,\n C_PAR,\n O_BRC,\n C_BRC,\n O_BRK,\n C_BRK,\n COMMA,\n SEMICOL,\n COLON,\n SLASH,\n AT,\n PERCENT,\n QMARK,\n PLUS,\n MINUS,\n BAR_BAR,\n AMP_AMP,\n\n // those can have \"=\" at the end\n BANG = 31,\n DOLLAR,\n HAT,\n BAR,\n TILDE,\n STAR,\n GT,\n LT,\n EQ,\n\n // tokens above plus \"=\" at the end, order must be the same\n BANG_EQ = 41,\n DOLLAR_EQ,\n HAT_EQ,\n BAR_EQ,\n TILDE_EQ,\n STAR_EQ,\n GT_EQ,\n LT_EQ,\n EQ_EQ,\n COL_COL,\n INVALID,\n LAST = 51,\n}\n\nexport class Token {\n type: TokenType;\n precededBySpace: boolean = false;\n num: number = 0;\n text: string = \"\";\n position: number = 0;\n\n constructor() {\n this.type = TokenType.EOF;\n }\n}\n\n/**\n * @enum {number}\n */\nexport enum Action {\n SPACE = 1,\n INT,\n IDENT,\n BANG,\n HASH = 6,\n DOLLAR,\n PERCENT,\n AMP,\n O_PAR,\n C_PAR,\n STAR,\n PLUS,\n COMMA,\n MINUS,\n DOT,\n SLASH,\n COLON,\n SEMICOL,\n LT,\n EQ,\n GT,\n QMARK,\n AT,\n O_BRK,\n C_BRK,\n O_BRC,\n C_BRC,\n BSLASH,\n HAT,\n BAR,\n TILDE,\n STR1,\n STR2,\n END,\n EQTAIL,\n ENDINT,\n ENDNUM,\n CONT,\n UNIT,\n PCUNIT,\n NUMBER,\n ENDIDNT,\n IDNTESC,\n ENDIDES,\n\n // end of identifier with escapes\n ENDSTR,\n ENDESTR,\n\n // end of string with escapes\n STR1ESC,\n STR2ESC,\n BAR_BAR,\n AMP_AMP,\n FUNC,\n FUNCES,\n COMMENT,\n COMMST,\n ENDNOTK,\n MINMIN,\n TOINT,\n TONUM,\n TOIDENT,\n TOIDES,\n KILL1,\n KILL2,\n URL,\n URL1,\n URL2,\n ENDURL,\n TERMURL,\n FINURL,\n LT_BG,\n LT_BG_M,\n INVALID,\n CHKPOSS,\n CHKPOSN,\n URLESC,\n IDESCH,\n COL_COL,\n TOCLASS,\n CHKSP,\n EOF,\n}\n\nexport function makeActions(def: Action, spec: Action[]): Action[] {\n const a: number[] = Array(128);\n let i: number;\n for (i = 0; i < 128; i++) {\n a[i] = def;\n }\n a[NaN] = def == Action.END ? Action.END : Action.INVALID;\n for (i = 0; i < spec.length; i += 2) {\n a[spec[i]] = spec[i + 1];\n }\n return a;\n}\n\n/**\n * Start of the token.\n */\nexport const actionsNormal: Action[] = [\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x00-0x07\n Action.INVALID,\n Action.SPACE,\n Action.SPACE,\n Action.INVALID,\n Action.SPACE,\n Action.SPACE,\n Action.INVALID,\n Action.INVALID, // 0x08-0x0F\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x10-0x17\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x18-0x1F\n Action.SPACE,\n Action.BANG,\n Action.STR2,\n Action.HASH,\n Action.DOLLAR,\n Action.PERCENT,\n Action.AMP,\n Action.STR1, // 0x20-0x27\n Action.O_PAR,\n Action.C_PAR,\n Action.STAR,\n Action.PLUS,\n Action.COMMA,\n Action.MINUS,\n Action.DOT,\n Action.SLASH, // 0x28-0x2F\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT, // 0x30-0x37\n Action.INT,\n Action.INT,\n Action.COLON,\n Action.SEMICOL,\n Action.LT,\n Action.EQ,\n Action.GT,\n Action.QMARK, // 0x38-0x3F\n Action.AT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x40-0x47\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x48-0x4F\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x50-0x57\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.O_BRK,\n Action.BSLASH,\n Action.C_BRK,\n Action.HAT,\n Action.IDENT, // 0x58-0x5F\n Action.INVALID,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x60-0x67\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x68-0x6F\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x70-0x77\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.O_BRC,\n Action.BAR,\n Action.C_BRC,\n Action.TILDE,\n Action.INVALID, // 0x78-0x7F\n];\n\nactionsNormal[NaN] = Action.EOF;\n\n/**\n * Inside identifier.\n */\nexport const actionsIdent: Action[] = [\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x00-0x07\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x08-0x0F\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x10-0x17\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x18-0x1F\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x20-0x27\n Action.FUNC,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.CONT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x38-0x3F\n Action.ENDIDNT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x40-0x47\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x48-0x4F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x50-0x57\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDNT,\n Action.IDNTESC,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.CONT, // 0x58-0x5F\n Action.ENDIDNT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x60-0x67\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x68-0x6F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x70-0x77\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x78-0x7F\n];\n\nactionsIdent[NaN] = Action.ENDIDNT;\n\n/**\n * After dot (either .class or .123)\n */\nexport const actionsNumOrClass: Action[] = [\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x00-0x07\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x08-0x0F\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x10-0x17\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x18-0x1F\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x20-0x27\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.TOCLASS,\n Action.TONUM,\n Action.INVALID, // 0x28-0x2F\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM, // 0x30-0x37\n Action.TONUM,\n Action.TONUM,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x38-0x3F\n Action.INVALID,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x40-0x47\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x48-0x4F\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x50-0x57\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.INVALID,\n Action.TOIDES,\n Action.INVALID,\n Action.INVALID,\n Action.TOCLASS, // 0x58-0x5F\n Action.INVALID,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x60-0x67\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x68-0x6F\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x70-0x77\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x78-0x7F\n];\n\nactionsIdent[NaN] = Action.ENDIDNT;\n\n/**\n * after '-'\n */\nexport const actionsMinus: Action[] = [\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x00-0x07\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x08-0x0F\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x10-0x17\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x18-0x1F\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x20-0x27\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.MINMIN,\n Action.TONUM,\n Action.END, // 0x28-0x2F\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT, // 0x30-0x37\n Action.TOINT,\n Action.TOINT,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x38-0x3F\n Action.END,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x40-0x47\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x48-0x4F\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x50-0x57\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.END,\n Action.TOIDES,\n Action.END,\n Action.END,\n Action.TOIDENT, // 0x58-0x5F\n Action.END,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x60-0x67\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x68-0x6F\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x70-0x77\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x78-0x7F\n];\n\nactionsMinus[NaN] = Action.END;\n\n/**\n * Inside identifier with escape sequence\n */\nexport const actionsIdentEsc: Action[] = [\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x00-0x07\n Action.ENDIDES,\n Action.CHKPOSS,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x08-0x0F\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x10-0x17\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x18-0x1F\n Action.CHKPOSS,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x20-0x27\n Action.FUNCES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x38-0x3F\n Action.ENDIDES,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x40-0x47\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x48-0x4F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x50-0x57\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDES,\n Action.IDNTESC,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.CONT, // 0x58-0x5F\n Action.ENDIDES,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x60-0x67\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x68-0x6F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x70-0x77\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x78-0x7F\n];\n\nactionsIdentEsc[NaN] = Action.ENDIDES;\n\n/**\n * Inside integer\n */\nexport const actionsInt: Action[] = [\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x00-0x07\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x08-0x0F\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x10-0x17\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x18-0x1F\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.PCUNIT,\n Action.ENDINT,\n Action.ENDINT, // 0x20-0x27\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.NUMBER,\n Action.ENDINT, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x38-0x3F\n Action.ENDINT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x40-0x47\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x48-0x4F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x50-0x57\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.UNIT, // 0x58-0x5F\n Action.ENDINT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x60-0x67\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x68-0x6F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x70-0x77\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x78-0x7F\n];\n\nactionsInt[NaN] = Action.ENDINT;\n\n/**\n * inside real, after dot\n */\nexport const actionsNumber: Action[] = [\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x00-0x07\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x08-0x0F\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x10-0x17\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x18-0x1F\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.PCUNIT,\n Action.ENDNUM,\n Action.ENDNUM, // 0x20-0x27\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x38-0x3F\n Action.ENDNUM,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x40-0x47\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x48-0x4F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x50-0x57\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.UNIT, // 0x58-0x5F\n Action.ENDNUM,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x60-0x67\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x68-0x6F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x70-0x77\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x78-0x7F\n];\n\nactionsNumber[NaN] = Action.ENDNUM;\n\nexport const actionsCheckEq: Action[] = makeActions(Action.END, [\n 61 /*=*/,\n Action.EQTAIL,\n]);\n\nexport const actionsColon: Action[] = makeActions(Action.END, [\n 58 /*:*/,\n Action.COL_COL,\n]);\n\nexport const actionsBar: Action[] = makeActions(Action.END, [\n 61 /*=*/,\n Action.EQTAIL,\n 124 /*|*/,\n Action.BAR_BAR,\n]);\n\nexport const actionsAmp: Action[] = makeActions(Action.END, [\n 38 /*&*/,\n Action.AMP_AMP,\n]);\n\nexport const actionsSlash: Action[] = makeActions(Action.END, [\n 42 /* * */,\n Action.COMMENT,\n]);\n\nexport const actionsComment: Action[] = makeActions(Action.CONT, [\n 42 /* * */,\n Action.COMMST,\n]);\n\nexport const actionsCommentStar: Action[] = makeActions(Action.COMMENT, [\n 42 /* * */,\n Action.COMMST,\n 47 /* / */,\n Action.ENDNOTK,\n]);\n\nexport const actionsMinusMinus: Action[] = makeActions(Action.KILL1, [\n 62 /* > */,\n Action.ENDNOTK,\n]);\n\nexport const actionsLt: Action[] = makeActions(Action.END, [\n 61 /*=*/,\n Action.EQTAIL,\n 33 /*!*/,\n Action.LT_BG,\n]);\n\nexport const actionsLtBang: Action[] = makeActions(Action.KILL1, [\n 45 /*-*/,\n Action.LT_BG_M,\n]);\n\nexport const actionsLtBangMinus: Action[] = makeActions(Action.KILL2, [\n 45 /*-*/,\n Action.ENDNOTK,\n]);\n\nexport const actionsIdentEscChr: Action[] = makeActions(Action.IDESCH, [\n 9 /*tab*/,\n Action.INVALID,\n 10 /*LF*/,\n Action.INVALID,\n 13 /*CR*/,\n Action.INVALID,\n 32 /*sp*/,\n Action.INVALID,\n]);\n\nexport const actionsStr1: Action[] = makeActions(Action.CONT, [\n 39 /*'*/,\n Action.ENDSTR,\n 10 /*LF*/,\n Action.INVALID,\n 13 /*CR*/,\n Action.INVALID,\n 92 /*\\*/,\n Action.STR1ESC,\n]);\n\nexport const actionsStr2: Action[] = makeActions(Action.CONT, [\n 34 /*\"*/,\n Action.ENDSTR,\n 10 /*LF*/,\n Action.INVALID,\n 13 /*CR*/,\n Action.INVALID,\n 92 /*\\*/,\n Action.STR2ESC,\n]);\n\nexport const actionsStr1Esc: Action[] = makeActions(Action.CONT, [\n 39 /*'*/,\n Action.ENDESTR,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.STR1ESC,\n]);\n\nexport const actionsStr2Esc: Action[] = makeActions(Action.CONT, [\n 34 /*\"*/,\n Action.ENDESTR,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.STR2ESC,\n]);\n\nexport const actionsURL: Action[] = makeActions(Action.URL, [\n 9 /*tab*/,\n Action.CONT,\n 32 /*sp*/,\n Action.CONT,\n 34 /*\"*/,\n Action.URL2,\n 39 /*'*/,\n Action.URL1,\n 41 /*)*/,\n Action.INVALID,\n 10 /*LF*/,\n Action.CONT,\n 13 /*CR*/,\n Action.CONT,\n]);\n\nexport const actionsURLInside: Action[] = makeActions(Action.CONT, [\n 41 /*)*/,\n Action.ENDURL,\n 9 /*TAB*/,\n Action.CHKSP,\n 10 /*LF*/,\n Action.CHKSP,\n 13 /*CR*/,\n Action.CHKSP,\n 32 /*sp*/,\n Action.CHKSP,\n 92 /*\\*/,\n Action.URLESC,\n 40 /*(*/,\n Action.INVALID,\n 91 /*[*/,\n Action.INVALID,\n 93 /*]*/,\n Action.INVALID,\n 123 /*{*/,\n Action.INVALID,\n 125 /*}*/,\n Action.INVALID,\n NaN,\n Action.ENDURL,\n]);\n\nexport const actionsURLInside1: Action[] = makeActions(Action.CONT, [\n 39 /*'*/,\n Action.TERMURL,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.URLESC,\n NaN,\n Action.ENDURL,\n]);\n\nexport const actionsURLInside2: Action[] = makeActions(Action.CONT, [\n 34 /*\"*/,\n Action.TERMURL,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.URLESC,\n NaN,\n Action.ENDURL,\n]);\n\nexport const actionsURLTail: Action[] = makeActions(Action.INVALID, [\n 9 /*tab*/,\n Action.CONT,\n 10 /*LF*/,\n Action.CONT,\n 13 /*CR*/,\n Action.CONT,\n 32 /*sp*/,\n Action.CONT,\n 41 /*)*/,\n Action.FINURL,\n]);\n\nexport const INITIAL_INDEX_MASK = 15;\n\nexport class Tokenizer {\n indexMask: number;\n buffer: Token[];\n head: number = -1; // saved, occupied if >= 0\n tail: number = 0; // available, ready to write\n curr: number = 0; // ready to read\n position: number = 0;\n\n constructor(public input: string, public readonly handler: TokenizerHandler) {\n this.indexMask = INITIAL_INDEX_MASK;\n this.buffer = Array(this.indexMask + 1);\n for (let i = 0; i <= this.indexMask; i++) {\n this.buffer[i] = new Token();\n }\n }\n\n token(): Token {\n if (this.tail == this.curr) {\n this.fillBuffer();\n }\n return this.buffer[this.curr];\n }\n\n nthToken(n: number): Token {\n if (((this.tail - this.curr) & this.indexMask) <= n) {\n this.fillBuffer();\n }\n return this.buffer[(this.curr + n) & this.indexMask];\n }\n\n consume(): void {\n this.curr = (this.curr + 1) & this.indexMask;\n }\n\n mark(): void {\n if (this.head >= 0) {\n throw new Error(\"F_CSSTOK_BAD_CALL mark\");\n }\n this.head = this.curr;\n }\n\n reset(): void {\n if (this.head < 0) {\n throw new Error(\"F_CSSTOK_BAD_CALL reset\");\n }\n this.curr = this.head;\n this.head = -1;\n }\n\n unmark(): void {\n this.head = -1;\n }\n\n hasMark(): boolean {\n return this.head >= 0;\n }\n\n private reallocate(): void {\n const newIndexMask = 2 * (this.indexMask + 1) - 1;\n const newBuffer: Token[] = Array(newIndexMask + 1);\n let oldIndex = this.head;\n let newIndex = 0;\n while (oldIndex != this.tail) {\n newBuffer[newIndex] = this.buffer[oldIndex];\n if (oldIndex == this.curr) {\n this.curr = newIndex;\n }\n oldIndex = (oldIndex + 1) & this.indexMask;\n newIndex++;\n }\n this.head = 0;\n this.tail = newIndex;\n this.indexMask = newIndexMask;\n this.buffer = newBuffer;\n while (newIndex <= newIndexMask) {\n newBuffer[newIndex++] = new Token();\n }\n }\n\n private error(position, token, mnemonics) {\n if (this.handler) {\n this.handler.error(mnemonics, token);\n }\n }\n\n private fillBuffer(): void {\n let tail = this.tail;\n let head = this.head >= 0 ? this.head : this.curr;\n let indexMask = this.indexMask;\n if (tail >= head) {\n head += indexMask;\n } else {\n head--;\n }\n if (head == tail) {\n // only expect to get here when mark is in effect\n if (this.head < 0) {\n throw new Error(\"F_CSSTOK_INTERNAL\");\n }\n this.reallocate();\n tail = this.tail;\n indexMask = this.indexMask;\n head = indexMask; // this.head is zero\n }\n let actions = actionsNormal;\n const input = this.input;\n let position = this.position;\n const buffer = this.buffer;\n let tokenType: TokenType = TokenType.EOF;\n let tokenPosition: number = 0;\n let tokenText: string = \"\";\n let tokenNum: number = 0;\n let seenSpace = false;\n let token: Token = buffer[tail];\n let backslashPos = -9; // far enough before the start of the string\n while (true) {\n const charCode = input.charCodeAt(position);\n switch (actions[charCode] || actions[65] /*A*/) {\n case Action.INVALID:\n tokenType = TokenType.INVALID;\n if (isNaN(charCode)) {\n tokenText = \"E_CSS_UNEXPECTED_EOF\";\n } else {\n tokenText = \"E_CSS_UNEXPECTED_CHAR\";\n }\n actions = actionsNormal;\n position++;\n break;\n case Action.SPACE:\n position++;\n seenSpace = true;\n continue;\n case Action.INT:\n tokenPosition = position++;\n actions = actionsInt;\n continue;\n case Action.IDENT:\n tokenType = TokenType.IDENT;\n tokenPosition = position++;\n actions = actionsIdent;\n continue;\n case Action.BANG:\n tokenPosition = position++;\n tokenType = TokenType.BANG;\n actions = actionsCheckEq;\n continue;\n case Action.STR1:\n tokenType = TokenType.STR;\n tokenPosition = ++position; // after quote\n actions = actionsStr1;\n continue;\n case Action.STR2:\n tokenType = TokenType.STR;\n tokenPosition = ++position; // after quote\n actions = actionsStr2;\n continue;\n case Action.HASH:\n tokenPosition = ++position; // after hash\n tokenType = TokenType.HASH;\n actions = actionsIdent;\n continue;\n case Action.DOLLAR:\n tokenPosition = position++;\n tokenType = TokenType.DOLLAR;\n actions = actionsCheckEq;\n continue;\n case Action.PERCENT:\n tokenPosition = position++;\n tokenType = TokenType.PERCENT;\n break;\n case Action.AMP:\n tokenPosition = position++;\n tokenType = TokenType.DOLLAR;\n actions = actionsAmp;\n continue;\n case Action.O_PAR:\n tokenPosition = position++;\n tokenType = TokenType.O_PAR;\n break;\n case Action.C_PAR:\n tokenPosition = position++;\n tokenType = TokenType.C_PAR;\n break;\n case Action.STAR:\n tokenPosition = position++;\n tokenType = TokenType.STAR;\n actions = actionsCheckEq;\n continue;\n case Action.PLUS:\n tokenPosition = position++;\n tokenType = TokenType.PLUS;\n break;\n case Action.COMMA:\n tokenPosition = position++;\n tokenType = TokenType.COMMA;\n break;\n case Action.MINUS:\n tokenType = TokenType.MINUS;\n tokenPosition = position++;\n actions = actionsMinus;\n continue;\n case Action.DOT:\n tokenPosition = position++;\n actions = actionsNumOrClass;\n continue;\n case Action.TOCLASS:\n tokenPosition = position++;\n tokenType = TokenType.CLASS;\n actions = actionsIdent;\n continue;\n case Action.SLASH:\n tokenPosition = position++;\n tokenType = TokenType.SLASH;\n actions = actionsSlash;\n continue;\n case Action.COLON:\n tokenPosition = position++;\n tokenType = TokenType.COLON;\n actions = actionsColon;\n continue;\n case Action.COL_COL:\n position++;\n tokenType = TokenType.COL_COL;\n break;\n case Action.SEMICOL:\n tokenPosition = position++;\n tokenType = TokenType.SEMICOL;\n break;\n case Action.LT:\n tokenPosition = position++;\n tokenType = TokenType.LT;\n actions = actionsLt;\n continue;\n case Action.EQ:\n tokenPosition = position++;\n tokenType = TokenType.EQ;\n actions = actionsCheckEq;\n continue;\n case Action.GT:\n tokenPosition = position++;\n tokenType = TokenType.GT;\n actions = actionsCheckEq;\n continue;\n case Action.QMARK:\n tokenPosition = position++;\n tokenType = TokenType.QMARK;\n break;\n case Action.AT:\n tokenPosition = ++position; // after \"at\" sign\n tokenType = TokenType.AT;\n actions = actionsIdent;\n continue;\n case Action.O_BRK:\n tokenPosition = position++;\n tokenType = TokenType.O_BRK;\n break;\n case Action.C_BRK:\n tokenPosition = position++;\n tokenType = TokenType.C_BRK;\n break;\n case Action.O_BRC:\n tokenPosition = position++;\n tokenType = TokenType.O_BRC;\n break;\n case Action.C_BRC:\n tokenPosition = position++;\n tokenType = TokenType.C_BRC;\n break;\n case Action.BSLASH:\n tokenPosition = position++;\n backslashPos = tokenPosition;\n tokenType = TokenType.IDENT;\n actions = actionsIdentEscChr;\n continue;\n case Action.HAT:\n tokenPosition = position++;\n tokenType = TokenType.HAT;\n actions = actionsCheckEq;\n continue;\n case Action.BAR:\n tokenPosition = position++;\n tokenType = TokenType.BAR;\n actions = actionsBar;\n continue;\n case Action.TILDE:\n tokenPosition = position++;\n tokenType = TokenType.TILDE;\n actions = actionsCheckEq;\n continue;\n case Action.END:\n // don't consume current char\n break;\n case Action.EQTAIL:\n position++;\n tokenType = (tokenType +\n TokenType.BANG_EQ -\n TokenType.BANG) as TokenType;\n break;\n case Action.ENDINT:\n // don't consume current char\n tokenType = TokenType.INT;\n tokenNum = parseInt(input.substring(tokenPosition, position), 10);\n break;\n case Action.ENDNUM:\n // don't consume current char\n tokenType = TokenType.NUM;\n tokenNum = parseFloat(input.substring(tokenPosition, position));\n break;\n case Action.CONT:\n // just consume current char\n position++;\n continue;\n case Action.UNIT:\n tokenType = TokenType.NUMERIC;\n tokenNum = parseFloat(input.substring(tokenPosition, position));\n tokenPosition = position++;\n actions = actionsIdent;\n continue;\n case Action.PCUNIT:\n tokenType = TokenType.NUMERIC;\n tokenNum = parseFloat(input.substring(tokenPosition, position));\n tokenText = \"%\";\n tokenPosition = position++; // for consistency with alphabetic units\n break;\n case Action.NUMBER:\n position++;\n actions = actionsNumber;\n continue;\n case Action.ENDIDNT:\n // don't consume current char\n // tokenType should be set already\n tokenText = input.substring(tokenPosition, position);\n break;\n case Action.IDNTESC:\n backslashPos = position++;\n actions = actionsIdentEscChr;\n continue;\n case Action.ENDIDES:\n // end of identifier with escapes\n // don't consume current char\n // tokenType should be set already\n tokenText = escapeParse(input.substring(tokenPosition, position));\n break;\n case Action.ENDSTR:\n tokenText = input.substring(tokenPosition, position); // consume closing quote\n position++;\n break;\n case Action.ENDESTR:\n tokenText = escapeParse(input.substring(tokenPosition, position)); // consume closing quote\n position++;\n break;\n case Action.STR1ESC:\n backslashPos = position;\n position += 2; // consume character after backslash in any case\n actions = actionsStr1Esc;\n continue;\n case Action.STR2ESC:\n backslashPos = position;\n position += 2; // consume character after backslash in any case\n actions = actionsStr2Esc;\n continue;\n case Action.BAR_BAR:\n position++;\n tokenType = TokenType.BAR_BAR;\n break;\n case Action.AMP_AMP:\n position++;\n tokenType = TokenType.AMP_AMP;\n break;\n case Action.FUNC:\n // tokenType can be TokenType.IDENT,\n // TokenType.CLASS, TokenType.AT,\n // TokenType.HASH, TokenType.NUMERIC\n tokenText = input.substring(tokenPosition, position);\n if (tokenType == TokenType.IDENT) {\n position++; // consume\n if (tokenText.toLowerCase() == \"url\") {\n actions = actionsURL;\n continue;\n }\n tokenType = TokenType.FUNC;\n }\n break;\n case Action.FUNCES:\n // tokenType can be TokenType.IDENT,\n // TokenType.CLASS, TokenType.AT,\n // TokenType.HASH, T_NUMERIC\n tokenText = escapeParse(input.substring(tokenPosition, position));\n if (tokenType == TokenType.IDENT) {\n position++; // consume\n if (tokenText.toLowerCase() == \"url\") {\n actions = actionsURL;\n continue;\n }\n tokenType = TokenType.FUNC;\n }\n break;\n case Action.COMMENT:\n actions = actionsComment;\n position++;\n continue;\n case Action.COMMST:\n actions = actionsCommentStar;\n position++;\n continue;\n case Action.ENDNOTK:\n actions = actionsNormal;\n position++;\n continue;\n case Action.MINMIN:\n actions = actionsMinusMinus;\n position++;\n continue;\n case Action.TOINT:\n tokenType = TokenType.INT;\n actions = actionsInt;\n position++;\n continue;\n case Action.TONUM:\n tokenType = TokenType.NUM;\n actions = actionsNumber;\n position++;\n continue;\n case Action.TOIDENT:\n tokenType = TokenType.IDENT;\n actions = actionsIdent;\n position++;\n continue;\n case Action.TOIDES:\n tokenType = TokenType.IDENT;\n actions = actionsIdentEscChr;\n backslashPos = position++;\n continue;\n case Action.KILL1:\n position--;\n break;\n case Action.KILL2:\n position -= 2;\n break;\n case Action.URL:\n tokenPosition = position++;\n actions = actionsURLInside;\n continue;\n case Action.URL1:\n tokenPosition = ++position; // skip quote\n actions = actionsURLInside1;\n continue;\n case Action.URL2:\n tokenPosition = ++position; // skip quote\n actions = actionsURLInside2;\n continue;\n case Action.ENDURL:\n tokenType = TokenType.URL;\n tokenText = escapeParse(input.substring(tokenPosition, position));\n position++; // skip ')'\n break;\n case Action.FINURL:\n position++; // skip ')'\n break;\n case Action.LT_BG:\n actions = actionsLtBang;\n position++;\n continue;\n case Action.LT_BG_M:\n actions = actionsLtBangMinus;\n position++;\n continue;\n case Action.CHKSP:\n // newline in non-quoted URL - check if end of url\n if (position - backslashPos < 8) {\n // close enough: may be valid\n if (\n input\n .substring(backslashPos + 1, position + 1)\n .match(/^[0-9a-fA-F]{0,6}(\\r\\n|[\\n\\r])|[ \\t]$/)\n ) {\n // valid, keep going\n position++;\n continue;\n }\n }\n\n // end of url\n // fall through\n case Action.TERMURL:\n tokenType = TokenType.URL;\n tokenText = escapeParse(input.substring(tokenPosition, position));\n position++; // skip quote (or newline)\n actions = actionsURLTail;\n continue;\n case Action.CHKPOSN:\n // newline in string or quoted URL - check validity\n position++;\n if (position - backslashPos < 9) {\n // close enough: may be valid\n if (\n input\n .substring(backslashPos + 1, position)\n .match(/^[0-9a-fA-F]{0,6}(\\r\\n|[\\n\\r])$/)\n ) {\n // valid, keep going\n continue;\n }\n }\n\n // invalid token\n tokenType = TokenType.INVALID;\n tokenText = \"E_CSS_UNEXPECTED_NEWLINE\";\n actions = actionsNormal;\n break;\n case Action.CHKPOSS:\n // space in identifier - check validity\n if (position - backslashPos < 9) {\n // close enough: may be valid\n if (\n input\n .substring(backslashPos + 1, position + 1)\n .match(/^[0-9a-fA-F]{0,6}[ \\t]$/)\n ) {\n // valid, keep going\n position++;\n continue;\n }\n }\n\n // end of identifier\n // don't consume current char\n // tokenType should be set already\n tokenText = escapeParse(input.substring(tokenPosition, position));\n break;\n case Action.URLESC:\n backslashPos = position++;\n continue;\n case Action.IDESCH:\n position++;\n actions = actionsIdentEsc;\n continue;\n default:\n // EOF\n if (actions !== actionsNormal) {\n tokenType = TokenType.INVALID;\n tokenText = \"E_CSS_UNEXPECTED_STATE\";\n break;\n }\n tokenPosition = position;\n tokenType = TokenType.EOF;\n }\n token.type = tokenType;\n token.precededBySpace = seenSpace;\n token.num = tokenNum;\n token.text = tokenText;\n token.position = tokenPosition;\n tail++;\n if (tail >= head) {\n break;\n }\n actions = actionsNormal;\n seenSpace = false;\n token = buffer[tail & indexMask];\n }\n this.position = position;\n this.tail = tail & indexMask;\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Task - Support for asynchronous execution and cooperative\n * multitasking.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\n\n/**\n * External timer. Only needed for testing.\n */\nexport interface Timer {\n /**\n * @return current time in milliseconds.\n */\n currentTime(): number;\n\n /**\n * Calls function after a given timeout.\n * @param fn function to call.\n * @param delay timeout in milliseconds.\n * @return unique number that can be used to clear the timeout.\n */\n setTimeout(fn: () => void, delay: number): number;\n\n /**\n * Calls function after a given timeout.\n * @param token timeout token.\n * @return.\n */\n clearTimeout(token: number): void;\n}\n\n/**\n * Result of an asynchronous function that may be available immediately or\n * some time later. Similar to Deferred.\n * @template T\n */\nexport interface Result<T> {\n /**\n * Call the given function when asynchronous function is finished. Callback\n * is executed in the task's context.\n */\n then(callback: (p1: T) => void): void;\n\n /**\n * Call the given asynchronous function when some asynchronous function is\n * finished. Callback is executed in the task's context.\n * @template T1\n */\n thenAsync<T1>(callback: (p1: T) => Result<T1>): Result<T1>;\n\n /**\n * Produce a Result that resolves to the given value when this Result is\n * resolved.\n * @template T1\n */\n thenReturn<T1>(result: T1): Result<T1>;\n\n /**\n * Finish given frame with the result value when result becomes ready.\n */\n thenFinish(frame: Frame<T>): void;\n\n /**\n * Check if this Result is still pending.\n */\n isPending(): boolean;\n\n /**\n * If this Result is resolved, return the value that it holds.\n */\n get(): T | null;\n}\n\nexport let privateCurrentTask: Task | null = null;\n\nexport let primaryScheduler: Scheduler | null = null;\n\n/**\n * Returns current task.\n */\nexport function currentTask(): Task | null {\n return privateCurrentTask;\n}\n\n/**\n * Create and return a new frame with the given name.\n */\nexport function newFrame<T>(name: string): Frame<T> {\n if (!privateCurrentTask) {\n throw new Error(\"E_TASK_NO_CONTEXT\");\n }\n if (!privateCurrentTask.name) {\n privateCurrentTask.name = name;\n }\n const task = privateCurrentTask;\n const frame = new Frame<T>(task, task.top, name);\n task.top = frame;\n frame.state = FrameState.ACTIVE;\n return frame;\n}\n\nexport function newEventSource(): EventSource {\n return new EventSource();\n}\n\nexport function newScheduler(opt_timer?: Timer): Scheduler {\n return new Scheduler(opt_timer || new TimerImpl());\n}\n\n/**\n * @template T\n */\nexport function newResult<T>(opt_value: T): Result<T> {\n return new SyncResultImpl<T>(opt_value);\n}\n\n/**\n * Creates a new frame and runs code in its context, catching synchronous and\n * asynchronous errors. If an error occurs, onErr is run (in the context of\n * the same frame). As usual, onErr is supposed either produce a result or raise\n * an exception.\n */\nexport function handle<T>(\n name: any,\n code: (p1: Frame<T>) => void,\n onErr: (p1: Frame<T>, p2: Error) => void,\n): Result<T> {\n const frame = newFrame<T>(name);\n frame.handler = onErr;\n try {\n code(frame);\n } catch (err) {\n // synchronous exception\n frame.task.raise(err, frame);\n }\n return frame.result();\n}\n\nexport function start<T>(func: () => Result<T>, opt_name?: string): Task {\n const scheduler = privateCurrentTask\n ? privateCurrentTask.getScheduler()\n : primaryScheduler || newScheduler();\n return scheduler.run(func, opt_name);\n}\n\n/**\n * Frame state.\n * @enum {number}\n */\nexport enum FrameState {\n INIT, // before newFrame call\n ACTIVE, // before finish call\n FINISHED, // before callback complete\n DEAD, // when callback is complete\n}\nexport class TimerImpl implements Timer {\n /**\n * @override\n */\n currentTime(): number {\n return new Date().valueOf();\n }\n\n /**\n * @override\n */\n setTimeout(fn: () => void, delay: number) {\n // HACK: casting to unknown type to prevent TypeScript error\n // [TS2352] Conversion of type 'Timer' to type 'number' may be a mistake because neither type sufficiently overlaps with the other.\n const timer: unknown = setTimeout(fn, delay);\n return timer as number;\n }\n\n /**\n * @override\n */\n clearTimeout(token: number): void {\n clearTimeout(token);\n }\n}\n\n/**\n * A class to create tasks.\n */\nexport class Scheduler {\n timeout: number = 1;\n slice: number = 25;\n sliceOverTime: number = 0;\n queue: Base.PriorityQueue;\n wakeupTime: number | null = null;\n timeoutToken: number | null = null;\n inTimeSlice: boolean = false;\n order: number = 0;\n\n constructor(public timer: Timer) {\n this.queue = new Base.PriorityQueue();\n if (!primaryScheduler) {\n primaryScheduler = this;\n }\n }\n\n /**\n * Sets time slice length.\n * @param slice length in milliseconds.\n */\n setSlice(slice: number) {\n this.slice = slice;\n }\n\n /**\n * Sets timeout between time slices.\n * @param timeout in milliseconds.\n */\n setTimeout(timeout: number) {\n this.timeout = timeout;\n }\n\n /**\n * Checks if the current time slice is over.\n */\n isTimeSliceOver(): boolean {\n const now = this.timer.currentTime();\n return now >= this.sliceOverTime;\n }\n\n private arm(): void {\n if (this.inTimeSlice) {\n return;\n }\n const nextInQueue = this.queue.peek() as Continuation<any>;\n const newTime = nextInQueue.scheduledTime;\n const now = this.timer.currentTime();\n if (this.timeoutToken != null) {\n if (now + this.timeout > this.wakeupTime) {\n return; // no use re-arming\n }\n this.timer.clearTimeout(this.timeoutToken);\n }\n let timeout = newTime - now;\n if (timeout <= this.timeout) {\n timeout = this.timeout;\n }\n this.wakeupTime = now + timeout;\n const self = this;\n this.timeoutToken = this.timer.setTimeout(() => {\n self.timeoutToken = null;\n self.doTimeSlice();\n }, timeout);\n }\n\n schedule(continuation: Continuation<any>, opt_delay?: number): void {\n const c = continuation as Continuation<any>;\n const now = this.timer.currentTime();\n c.order = this.order++;\n c.scheduledTime = now + (opt_delay || 0);\n this.queue.add(c);\n this.arm();\n }\n\n private doTimeSlice(): void {\n if (this.timeoutToken != null) {\n this.timer.clearTimeout(this.timeoutToken);\n this.timeoutToken = null;\n }\n this.inTimeSlice = true;\n try {\n let now = this.timer.currentTime();\n this.sliceOverTime = now + this.slice;\n while (this.queue.length()) {\n const continuation = this.queue.peek() as Continuation<any>;\n if (continuation.scheduledTime > now) {\n break; // too early\n }\n this.queue.remove();\n if (!continuation.canceled) {\n continuation.resumeInternal();\n }\n now = this.timer.currentTime();\n if (now >= this.sliceOverTime) {\n break;\n }\n }\n } catch (err) {\n Logging.logger.error(err);\n }\n this.inTimeSlice = false;\n if (this.queue.length()) {\n this.arm();\n }\n }\n\n run(func: () => Result<any>, opt_name?: string): Task {\n const task = new Task(this, opt_name || \"\");\n task.top = new Frame<any>(task, null, \"bootstrap\");\n task.top.state = FrameState.ACTIVE;\n task.top.then(() => {\n const done = () => {\n task.running = false;\n for (const callback of task.callbacks) {\n try {\n callback();\n } catch (err) {\n Logging.logger.error(err);\n }\n }\n };\n try {\n func().then((result) => {\n task.result = result;\n done();\n });\n } catch (err) {\n task.raise(err);\n done();\n }\n });\n const savedTask = privateCurrentTask;\n privateCurrentTask = task;\n this.schedule(task.top.suspend(\"bootstrap\"));\n privateCurrentTask = savedTask;\n return task;\n }\n}\n\n/**\n * Task suspension point.\n * @template T\n */\nexport class Continuation<T> implements Base.Comparable {\n scheduledTime: number = 0;\n order: number = 0;\n result: T = null;\n canceled: boolean = false;\n\n constructor(public task: Task) {}\n\n /**\n * @override\n */\n compare(otherComp: Base.Comparable): number {\n // earlier wins\n const other = otherComp as Continuation<any>;\n return other.scheduledTime - this.scheduledTime || other.order - this.order;\n }\n\n /**\n * Continuation's task\n */\n getTask(): Task {\n return this.task;\n }\n\n /**\n * Schedule task continuation after the given (optional) delay.\n * @param opt_delay optional delay in milliseconds.\n */\n schedule(result: T, opt_delay?: number) {\n this.result = result;\n this.task.scheduler.schedule(this, opt_delay);\n }\n\n resumeInternal(): boolean {\n const task = this.task;\n this.task = null;\n if (task && task.continuation == this) {\n task.continuation = null;\n const savedTask = privateCurrentTask;\n privateCurrentTask = task;\n task.top.finish(this.result);\n privateCurrentTask = savedTask;\n return true;\n }\n return false;\n }\n\n /**\n * Cancel continuation\n */\n cancel() {\n this.canceled = true;\n }\n}\n\n/**\n * An asynchronous, time-sliced task.\n */\nexport class Task {\n callbacks: (() => void)[] = [];\n exception: Error | null = null;\n running: boolean = true;\n result: any = null;\n waitTarget: string | null = null;\n top: Frame<any> | null = null;\n continuation: Continuation<any> | null = null;\n\n constructor(public scheduler: Scheduler, public name: string) {}\n\n /**\n * @return task name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * @param err exception to throw in the task's context.\n */\n interrupt(err: Error): void {\n this.raise(err || new Error(\"E_TASK_INTERRUPT\"));\n if (this !== privateCurrentTask && this.continuation) {\n // blocked on something\n this.continuation.cancel();\n const continuation = new Continuation(this);\n this.waitTarget = \"interrupt\";\n this.continuation = continuation;\n this.scheduler.schedule(continuation);\n }\n }\n\n /**\n * @return this task's scheduler.\n */\n getScheduler(): Scheduler {\n return this.scheduler;\n }\n\n /**\n * @return true if task is still running.\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Register a callback to be called when the task is done. Callback is not\n * executed in any task context. Multiple callbacks can be registered and\n * they will be called in the registration order.\n */\n whenDone(callback: () => void): void {\n this.callbacks.push(callback);\n }\n\n /**\n * Wait for task to finish (from another task).\n */\n join(): Result<any> {\n const frame = newFrame<any>(\"Task.join\");\n if (!this.running) {\n frame.finish(this.result);\n } else {\n const continuation = frame.suspend(this);\n const self = this;\n this.whenDone(() => {\n continuation.schedule(self.result);\n });\n }\n return frame.result();\n }\n\n /**\n * Unwind the stack. We have two stacks: async (maintained by frame\n * parent link) and sync (regular JavaScript stack).\n */\n unwind() {\n // We have a sequence of frames on the stack.\n while (this.top && !this.top.handler) {\n this.top = this.top.parent;\n }\n if (this.top && this.top.handler && this.exception) {\n // found a handler\n const err = this.exception;\n this.exception = null;\n this.top.handler(this.top, err);\n } else {\n if (this.exception) {\n Logging.logger.error(\n this.exception,\n \"Unhandled exception in task\",\n this.name,\n );\n }\n }\n }\n\n raise(err: Error, opt_frame?: Frame<any>): void {\n this.fillStack(err);\n if (opt_frame) {\n let f = this.top;\n while (f && f != opt_frame) {\n f = f.parent;\n }\n if (f == opt_frame) {\n this.top = f;\n }\n }\n this.exception = err;\n this.unwind();\n }\n\n /**\n * Fill the stack trace in the exception\n * @param err exception\n */\n fillStack(err: Error) {\n let out = err[\"frameTrace\"];\n if (!out) {\n out = err[\"stack\"] ? `${err[\"stack\"]}\\n\\t---- async ---\\n` : \"\";\n for (let f = this.top; f; f = f.parent) {\n out += \"\\t\";\n out += f.getName();\n out += \"\\n\";\n }\n err[\"frameTrace\"] = out;\n }\n }\n}\n\n/**\n * @template T\n */\nexport class SyncResultImpl<T> implements Result<T> {\n constructor(public value: T) {}\n\n /**\n * @override\n */\n then(callback: (T: any) => void) {\n callback(this.value);\n }\n\n /**\n * @override\n */\n thenAsync<T1>(callback: (p1: T) => Result<T1>) {\n return callback(this.value);\n }\n\n /**\n * @override\n */\n thenReturn<T1>(result: T1) {\n return new SyncResultImpl(result);\n }\n\n /**\n * @override\n */\n thenFinish(frame: Frame<T>): void {\n frame.finish(this.value);\n }\n\n /**\n * @override\n */\n isPending(): boolean {\n return false;\n }\n\n /**\n * @override\n */\n get(): T | null {\n return this.value;\n }\n}\n\n/**\n * @template T\n */\nexport class ResultImpl<T> implements Result<T> {\n constructor(public readonly frame: Frame<T>) {}\n\n /**\n * @override\n */\n then(callback: (p1: T) => void): void {\n this.frame.then(callback);\n }\n\n /**\n * @override\n */\n thenAsync<T1>(callback: (p1: T) => Result<T1>): Result<T1> {\n if (this.isPending()) {\n // thenAsync is special, do the trick with the context\n const frame = new Frame<T | T1>(\n this.frame.task,\n this.frame.parent,\n \"AsyncResult.thenAsync\",\n );\n frame.state = FrameState.ACTIVE;\n this.frame.parent = frame as Frame<T>;\n this.frame.then((res1) => {\n callback(res1).then((res2) => {\n frame.finish(res2);\n });\n });\n return frame.result() as Result<T1>;\n } else {\n return callback(this.frame.res);\n }\n }\n\n /**\n * @override\n */\n thenReturn<T1>(result: T1) {\n if (this.isPending()) {\n return this.thenAsync(() => new SyncResultImpl(result));\n } else {\n return new SyncResultImpl(result);\n }\n }\n\n /**\n * @override\n */\n thenFinish(frame: Frame<T>): void {\n if (this.isPending()) {\n this.then((res) => {\n frame.finish(res);\n });\n } else {\n frame.finish(this.frame.res);\n }\n }\n\n /**\n * @override\n */\n isPending(): boolean {\n return this.frame.state == FrameState.ACTIVE;\n }\n\n /**\n * @override\n */\n get(): T | null {\n if (this.isPending()) {\n throw new Error(\"Result is pending\");\n }\n return this.frame.res;\n }\n}\n\n/**\n * Asynchronous execution frame. Corresponds to an asynchronous function\n * invocation.\n * @template T\n */\nexport class Frame<T> {\n res: T = null;\n state: FrameState;\n callback: ((p1: any) => void) | null = null;\n handler: ((p1: Frame<any>, p2: Error) => void) | null = null;\n\n constructor(public task: Task, public parent: Frame<T>, public name: string) {\n this.state = FrameState.INIT;\n }\n\n private checkEnvironment(): void {\n if (!privateCurrentTask) {\n throw new Error(\"F_TASK_NO_CONTEXT\");\n }\n if (this !== privateCurrentTask.top) {\n throw new Error(\"F_TASK_NOT_TOP_FRAME\");\n }\n }\n\n /**\n * @return to be returned as this asynchronous function return value.\n */\n result(): Result<T> {\n return new ResultImpl<T>(this);\n }\n\n finish(res: T) {\n this.checkEnvironment();\n if (privateCurrentTask && !privateCurrentTask.exception) {\n this.res = res;\n }\n this.state = FrameState.FINISHED;\n const frame = this.parent;\n if (privateCurrentTask) {\n privateCurrentTask.top = frame;\n }\n if (this.callback) {\n try {\n this.callback(res);\n } catch (err) {\n this.task.raise(err, frame);\n }\n\n // callback was called\n this.state = FrameState.DEAD;\n }\n }\n\n getTask(): Task {\n return this.task;\n }\n\n /**\n * @return frame name.\n */\n getName(): string {\n return this.name;\n }\n\n getScheduler(): Scheduler {\n return this.task.scheduler;\n }\n\n then(callback: (p1: T) => void): void {\n // legal to call when currentTask is null\n switch (this.state) {\n case FrameState.ACTIVE:\n if (this.callback) {\n throw new Error(\"F_TASK_FRAME_ALREADY_HAS_CALLBACK\");\n } else {\n this.callback = callback;\n }\n break;\n case FrameState.FINISHED: {\n const task = this.task;\n const frame = this.parent;\n try {\n callback(this.res);\n this.state = FrameState.DEAD;\n } catch (err) {\n this.state = FrameState.DEAD;\n task.raise(err, frame);\n }\n break;\n }\n case FrameState.DEAD:\n throw new Error(\"F_TASK_DEAD_FRAME\");\n default:\n throw new Error(`F_TASK_UNEXPECTED_FRAME_STATE ${this.state}`);\n }\n }\n\n /**\n * If this task was executed longer than task's slice parameter.\n * @return holds true\n */\n timeSlice(): Result<boolean> {\n const frame = newFrame<boolean>(\"Frame.timeSlice\");\n const scheduler = frame.getScheduler();\n if (scheduler.isTimeSliceOver()) {\n Logging.logger.debug(\"-- time slice --\");\n frame.suspend().schedule(true);\n } else {\n frame.finish(true);\n }\n return frame.result();\n }\n\n /**\n * Yield to other tasks for the specified time.\n * @param delay in milliseconds.\n * @return holds true\n */\n sleep(delay: number): Result<boolean> {\n const frame = newFrame<boolean>(\"Frame.sleep\");\n frame.suspend().schedule(true, delay);\n return frame.result();\n }\n\n /**\n * Repeatedly execute the given function asynchronously until it returns\n * false.\n * @return holds true.\n */\n loop(func: () => Result<boolean>): Result<boolean> {\n const frame = newFrame<boolean>(\"Frame.loop\");\n const step = (more) => {\n try {\n while (more) {\n const result = func();\n if (result.isPending()) {\n result.then(step);\n return;\n } else {\n result.then((m) => {\n more = m;\n });\n }\n }\n frame.finish(true);\n } catch (err) {\n frame.task.raise(err, frame);\n }\n };\n step(true);\n return frame.result();\n }\n\n /**\n * Similar to loop(), but provides a Frame for loop body function.\n * @return holds true.\n */\n loopWithFrame(func: (p1: LoopBodyFrame) => void): Result<boolean> {\n const task = privateCurrentTask;\n if (!task) {\n throw new Error(\"E_TASK_NO_CONTEXT\");\n }\n return this.loop(() => {\n let result: Result<boolean>;\n do {\n const frame = new LoopBodyFrame(task as Task, task.top);\n task.top = frame;\n frame.state = FrameState.ACTIVE;\n func(frame);\n result = frame.result();\n } while (!result.isPending() && result.get());\n return result;\n });\n }\n\n suspend(opt_waitTarget?: any): Continuation<T> {\n this.checkEnvironment();\n if (this.task.continuation) {\n throw new Error(\"E_TASK_ALREADY_SUSPENDED\");\n }\n const continuation: Continuation<T> = new Continuation(this.task);\n this.task.continuation = continuation;\n privateCurrentTask = null;\n this.task.waitTarget = opt_waitTarget || null;\n return continuation;\n }\n}\n\nexport class LoopBodyFrame extends Frame<boolean> {\n constructor(task: Task, parent: Frame<boolean>) {\n super(task, parent, \"loop\");\n }\n\n continueLoop(): void {\n this.finish(true);\n }\n\n breakLoop(): void {\n this.finish(false);\n }\n}\n\nexport class EventItem {\n next: EventItem = null;\n\n constructor(public event: Base.Event) {}\n}\n\n/**\n * An class to listen to evens and present them as a readable asynchronous\n * stream to tasks.\n */\nexport class EventSource {\n continuation: Continuation<boolean> = null;\n listeners: {\n target: Base.EventTarget;\n type: string;\n listener: Base.EventListener;\n }[] = [];\n head: EventItem;\n tail: EventItem;\n\n constructor() {\n this.head = new EventItem(null);\n this.tail = this.head;\n }\n\n /**\n * Attaches as an event listener to an EventTarget.\n */\n attach(\n target: Base.EventTarget,\n type: string,\n opt_preventDefault?: boolean,\n ): void {\n const self = this;\n const listener = (event) => {\n if (opt_preventDefault) {\n event.preventDefault();\n }\n if (self.tail.event) {\n self.tail.next = new EventItem(event);\n self.tail = self.tail.next;\n } else {\n self.tail.event = event;\n const continuation = self.continuation;\n if (continuation) {\n self.continuation = null;\n continuation.schedule(true);\n }\n }\n };\n target.addEventListener(type, listener, false);\n this.listeners.push({ target, type, listener });\n }\n\n detach(target: Base.EventTarget, type: string): void {\n let i = 0;\n let item: {\n target: Base.SimpleEventTarget;\n type: string;\n listener: Base.EventListener;\n } = null;\n while (i < this.listeners.length) {\n item = this.listeners[i];\n if (item.type == type && item.target === target) {\n this.listeners.splice(i, 1);\n item.target.removeEventListener(item.type, item.listener, false);\n return;\n }\n i++;\n }\n throw new Error(\"E_TASK_EVENT_SOURCE_NOT_ATTACHED\");\n }\n\n /**\n * Read next dispatched event, blocking the current task if needed.\n */\n nextEvent(): Result<Base.Event> {\n const frame: Frame<Base.Event> = newFrame(\"EventSource.nextEvent\");\n const self = this;\n const readEvent = () => {\n if (self.head.event) {\n const event = self.head.event;\n if (self.head.next) {\n self.head = self.head.next;\n } else {\n self.head.event = null;\n }\n frame.finish(event);\n } else if (self.continuation) {\n throw new Error(\"E_TASK_EVENT_SOURCE_OTHER_TASK_WAITING\");\n } else {\n const frameInternal: Frame<boolean> = newFrame(\n \"EventSource.nextEventInternal\",\n );\n self.continuation = frameInternal.suspend(self);\n frameInternal.result().then(readEvent);\n }\n };\n readEvent();\n return frame.result();\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview TaskUtil - Utilities asynchronous execution and cooperative\n * multitasking.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\nimport * as Task from \"./task\";\n\n/**\n * A class that can fetch or compute a resource that may be needed by multiple\n * tasks. The first time a resource is requested, it is fetched and then given\n * to everyone requesting it.\n * @template T\n * @param fetch function that fetches/computes\n * a resource; it will be run in a separate task.\n */\nexport class Fetcher<T> {\n name: string;\n arrived: boolean = false;\n resource: T = null;\n task: Task.Task = null;\n piggybacks: ((p1: any) => void)[] | null = [];\n\n constructor(public readonly fetch: () => Task.Result<T>, opt_name?: string) {\n this.name = opt_name;\n }\n\n /**\n * Start fetching/computing a resource, don't block current task.\n */\n start(): void {\n if (!this.task) {\n const self = this;\n this.task = Task.currentTask()\n .getScheduler()\n .run(() => {\n const frame = Task.newFrame(\"Fetcher.run\");\n self.fetch().then((resource) => {\n const piggibacks = self.piggybacks;\n self.arrived = true;\n self.resource = resource;\n self.task = null;\n self.piggybacks = [];\n if (piggibacks) {\n for (let i = 0; i < piggibacks.length; i++) {\n try {\n piggibacks[i](resource);\n } catch (err) {\n Logging.logger.error(err, \"Error:\");\n }\n }\n }\n frame.finish(resource);\n });\n return frame.result();\n }, this.name);\n }\n }\n\n piggyback(fn: (p1: T) => void): void {\n if (this.arrived) {\n fn(this.resource);\n } else {\n this.piggybacks.push(fn);\n }\n }\n\n /**\n * Fetches the resource, waits for it to arrive if it is already being\n * fetched.\n */\n get(): Task.Result<T> {\n if (this.arrived) {\n return Task.newResult(this.resource);\n }\n this.start();\n return this.task.join() as Task.Result<T>;\n }\n\n hasArrived(): boolean {\n return this.arrived;\n }\n}\n\n/**\n * Wait for all Fetcher objects in the array to arrive\n */\nexport const waitForFetchers = <T>(\n fetchers: Fetcher<T>[],\n): Task.Result<boolean> => {\n if (fetchers.length == 0) {\n return Task.newResult(true);\n }\n if (fetchers.length == 1) {\n return fetchers[0].get().thenReturn(true);\n }\n const frame = Task.newFrame<boolean>(\"waitForFetches\");\n let i = 0;\n frame\n .loop(() => {\n while (i < fetchers.length) {\n const fetcher = fetchers[i++];\n if (!fetcher.hasArrived()) {\n return fetcher.get().thenReturn(true);\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n frame.finish(true);\n });\n return frame.result();\n};\n\n/**\n * @return holding event type (load/error/abort)\n */\nexport function loadElement(elem: Element, src: string): Fetcher<string> {\n let width: string | null = null;\n let height: string | null = null;\n if (elem.localName == \"img\") {\n width = elem.getAttribute(\"width\");\n height = elem.getAttribute(\"height\");\n }\n const fetcher = new Fetcher(() => {\n const frame: Task.Frame<string> = Task.newFrame(\"loadImage\");\n const continuation = frame.suspend(elem);\n let done = false;\n const handler = (evt: Event) => {\n if (done) {\n return;\n } else {\n done = true;\n }\n if (elem.localName == \"img\") {\n // IE puts these bogus attributes, even if they were not present\n if (!width) {\n elem.removeAttribute(\"width\");\n }\n if (!height) {\n elem.removeAttribute(\"height\");\n }\n }\n continuation.schedule(evt ? evt.type : \"timeout\");\n };\n elem.addEventListener(\"load\", handler, false);\n elem.addEventListener(\"error\", handler, false);\n elem.addEventListener(\"abort\", handler, false);\n if (elem.namespaceURI == Base.NS.SVG) {\n elem.setAttributeNS(Base.NS.XLINK, \"xlink:href\", src);\n\n // SVG handlers are not reliable\n setTimeout(handler, 300);\n } else {\n (elem as any).src = src;\n }\n return frame.result();\n }, `loadElement ${src}`);\n fetcher.start();\n return fetcher;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Net - Fetch resource from a URL.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport { Net, XmlDoc } from \"./types\";\nimport UserAgentXml from \"./assets/user-agent.xml\";\n\n/**\n * @enum {string}\n */\nexport enum XMLHttpRequestResponseType {\n DEFAULT = \"\",\n ARRAYBUFFER = \"arraybuffer\",\n BLOB = \"blob\",\n DOCUMENT = \"document\",\n JSON = \"json\",\n TEXT = \"text\",\n}\n\nexport type Response = Net.Response;\n\nexport function ajax(\n url: string,\n opt_type?: XMLHttpRequestResponseType,\n opt_method?: string,\n opt_data?: string,\n opt_contentType?: string,\n): Task.Result<Response> {\n const frame: Task.Frame<Response> = Task.newFrame(\"ajax\");\n const request = new XMLHttpRequest();\n const continuation = frame.suspend(request);\n const response: Response = {\n status: 0,\n statusText: \"\",\n url,\n contentType: null,\n responseText: null,\n responseXML: null,\n responseBlob: null,\n };\n request.open(opt_method || \"GET\", url, true);\n if (opt_type) {\n request.responseType = opt_type;\n }\n request.onreadystatechange = () => {\n if (request.readyState === 4) {\n response.status = request.status;\n response.statusText =\n request.statusText || (request.status == 404 && \"Not Found\") || \"\";\n if (response.status == 200 || response.status == 0) {\n if (\n (!opt_type || opt_type === XMLHttpRequestResponseType.DOCUMENT) &&\n request.responseXML &&\n request.responseXML.documentElement.localName != \"parsererror\"\n ) {\n response.responseXML = request.responseXML;\n response.contentType = (request.responseXML as any).contentType;\n } else if (\n (!opt_type || opt_type === XMLHttpRequestResponseType.DOCUMENT) &&\n request.response instanceof HTMLDocument\n ) {\n response.responseXML = request.response;\n response.contentType = (request.response as any).contentType;\n } else {\n const text = request.response;\n if (\n (!opt_type || opt_type === XMLHttpRequestResponseType.TEXT) &&\n typeof text == \"string\"\n ) {\n response.responseText = text;\n } else if (!text) {\n Logging.logger.warn(\"Unexpected empty success response for\", url);\n } else {\n if (typeof text == \"string\") {\n response.responseBlob = makeBlob([text]);\n } else {\n response.responseBlob = text as Blob;\n }\n }\n const contentTypeHeader = request.getResponseHeader(\"Content-Type\");\n if (contentTypeHeader) {\n response.contentType = contentTypeHeader.replace(/(.*);.*$/, \"$1\");\n }\n }\n }\n continuation.schedule(response);\n }\n };\n try {\n if (opt_data) {\n request.setRequestHeader(\n \"Content-Type\",\n opt_contentType || \"text/plain; charset=UTF-8\",\n );\n request.send(opt_data);\n } else {\n if (/^file:|^https?:\\/\\/[^/]+\\.githubusercontent\\.com|\\.opf$/.test(url)) {\n // File or GitHub raw URL or .opf\n if (\n /\\/aozorabunko\\/[^/]+\\/cards\\/[^/]+\\/files\\/[^/.]+\\.html$/.test(url)\n ) {\n // Aozorabunko's (X)HTML support\n request.overrideMimeType(\"text/html; charset=Shift_JIS\");\n } else if (/\\.(html|htm)$/.test(url)) {\n request.overrideMimeType(\"text/html; charset=UTF-8\");\n } else if (/\\.(xhtml|xht|xml|opf)$/.test(url)) {\n request.overrideMimeType(\"application/xml; charset=UTF-8\");\n } else if (/\\.(txt|css)$/.test(url)) {\n request.overrideMimeType(\"text/plain; charset=UTF-8\");\n } else {\n // fallback to HTML\n request.overrideMimeType(\"text/html; charset=UTF-8\");\n }\n } else if (/^data:,(<|%3C|%3c)/.test(url)) {\n request.overrideMimeType(\"text/html; charset=UTF-8\");\n } else if (/^data:,/.test(url)) {\n request.overrideMimeType(\"text/plain; charset=UTF-8\");\n }\n request.send(null);\n }\n } catch (e) {\n Logging.logger.warn(e, `Error fetching ${url}`);\n continuation.schedule(response);\n }\n return frame.result();\n}\n\n/**\n * @return Blob\n */\nexport function makeBlob(\n parts: (string | Blob | ArrayBuffer | ArrayBufferView)[],\n opt_type?: string,\n): any {\n const type = opt_type || \"application/octet-stream\";\n const builderCtr = window[\"WebKitBlobBuilder\"] || window[\"MSBlobBuilder\"]; // deprecated\n if (builderCtr) {\n const builder = new builderCtr();\n for (let i = 0; i < parts.length; i++) {\n builder.append(parts[i]);\n }\n return builder.getBlob(type);\n }\n return new Blob(parts, { type });\n}\n\n/**\n * @return Task.Result.<ArrayBuffer>\n */\nexport function readBlob(blob: Blob): any {\n const frame: Task.Frame<ArrayBuffer> = Task.newFrame(\"readBlob\");\n const fileReader = new FileReader();\n const continuation = frame.suspend(fileReader);\n fileReader.addEventListener(\n \"load\",\n () => {\n continuation.schedule(fileReader.result as ArrayBuffer);\n },\n false,\n );\n fileReader.readAsArrayBuffer(blob);\n return frame.result();\n}\n\nexport function revokeObjectURL(url: string): void {\n (window[\"URL\"] || window[\"webkitURL\"]).revokeObjectURL(url);\n}\n\n/**\n * @return url\n */\nexport function createObjectURL(blob: Blob): string {\n return (window[\"URL\"] || window[\"webkitURL\"]).createObjectURL(blob);\n}\n\n/**\n * @template Resource\n */\nexport class ResourceStore<Resource> implements Net.ResourceStore<Resource> {\n resources: { [key: string]: Resource } = {};\n fetchers: { [key: string]: TaskUtil.Fetcher<Resource> } = {};\n\n constructor(\n public readonly parser: (\n p1: Response,\n p2: ResourceStore<Resource>,\n ) => Task.Result<Resource>,\n public readonly type: XMLHttpRequestResponseType,\n ) {}\n\n /**\n * @return resource for the given URL\n */\n load(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Resource> {\n url = Base.stripFragment(url);\n const resource = this.resources[url];\n if (typeof resource != \"undefined\") {\n return Task.newResult(resource);\n }\n return this.fetch(url, opt_required, opt_message).get();\n }\n\n private fetchInner(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Resource> {\n const self = this;\n const frame: Task.Frame<Resource> = Task.newFrame(\"fetch\");\n\n // Hack for TOCView.showTOC()\n const isTocBox = url.endsWith(\"?viv-toc-box\");\n if (isTocBox) {\n url = url.replace(\"?viv-toc-box\", \"\");\n }\n const userAgentXmlUrl = Base.resolveURL(\n \"user-agent.xml\",\n Base.resourceBaseURL,\n );\n const isUserAgentXml = !isTocBox && url === userAgentXmlUrl;\n if (isUserAgentXml) {\n // Change \"user-agent.xml\" URL to data URL\n url = `data:application/xml,${encodeURIComponent(UserAgentXml)}`;\n }\n\n ajax(url, self.type).then((response) => {\n if (response.status >= 400) {\n if (opt_required) {\n throw new Error(\n (opt_message || `Failed to fetch required resource: ${url}`) +\n ` (${response.status}${\n response.statusText ? \" \" + response.statusText : \"\"\n })`,\n );\n }\n }\n if (isTocBox) {\n // Hack for TOCView.showTOC()\n url += \"?viv-toc-box\";\n response.url += \"?viv-toc-box\";\n } else if (isUserAgentXml) {\n // Restore \"user-agent.xml\" URL\n response.url = url = userAgentXmlUrl;\n }\n self.parser(response, self).then((resource) => {\n delete self.fetchers[url];\n self.resources[url] = resource;\n frame.finish(resource);\n });\n });\n return frame.result();\n }\n\n /**\n * @return fetcher for the resource for the given URL\n */\n fetch(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): TaskUtil.Fetcher<Resource> {\n url = Base.stripFragment(url);\n const resource = this.resources[url];\n if (resource) {\n return null;\n }\n let fetcher = this.fetchers[url];\n if (!fetcher) {\n const self = this;\n fetcher = new TaskUtil.Fetcher(\n () => self.fetchInner(url, opt_required, opt_message),\n `Fetch ${url}`,\n );\n self.fetchers[url] = fetcher;\n fetcher.start();\n }\n return fetcher;\n }\n\n get(url: string): XmlDoc.XMLDocHolder {\n const resource: unknown = this.resources[Base.stripFragment(url)];\n return resource as XmlDoc.XMLDocHolder;\n }\n\n delete(url: string) {\n delete this.resources[Base.stripFragment(url)];\n }\n}\n\nexport type JSONStore = ResourceStore<Base.JSON>;\n\nexport function parseJSONResource(\n response: Response,\n store: JSONStore,\n): Task.Result<Base.JSON> {\n const text = response.responseText;\n return Task.newResult(text ? Base.stringToJSON(text) : null);\n}\n\nexport function newJSONStore(): JSONStore {\n return new ResourceStore(parseJSONResource, XMLHttpRequestResponseType.TEXT);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssParser - CSS Parser.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Exprs from \"./exprs\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as Task from \"./task\";\n\n/**\n * User agent stylesheet base specificity.\n */\nexport const SPECIFICITY_USER_AGENT: number = 0;\n\n/**\n * User stylesheet base specificity.\n */\nexport const SPECIFICITY_USER: number = 16777216;\n\n/**\n * Author stylesheet (\"normal\" stylesheet) base specificity.\n */\nexport const SPECIFICITY_AUTHOR: number = 33554432;\n\n/**\n * Style attribute base specificity.\n */\nexport const SPECIFICITY_STYLE: number = 50331648;\n\n/**\n * Style attribute base specificity when !important is used.\n */\nexport const SPECIFICITY_STYLE_IMPORTANT: number = 67108864;\n\n/**\n * Author stylesheet base specificity when !important is used.\n */\nexport const SPECIFICITY_AUTHOR_IMPORTANT: number = 83886080;\n\n/**\n * User stylesheet base specificity when !important is used.\n */\nexport const SPECIFICITY_USER_IMPORTANT: number = 100663296;\n\n/**\n * @enum {string}\n */\nexport enum StylesheetFlavor {\n USER_AGENT = \"UA\",\n USER = \"User\",\n AUTHOR = \"Author\",\n}\n\n/**\n * CSS Color value from hash text (without '#' character).\n */\nexport function colorFromHash(text: string): Css.Color {\n let num = parseInt(text, 16);\n if (isNaN(num)) {\n throw new Error(\"E_CSS_COLOR\");\n }\n if (text.length == 6) {\n return new Css.Color(num);\n }\n if (text.length == 3) {\n num =\n (num & 15) |\n ((num & 15) << 4) |\n ((num & 240) << 4) |\n ((num & 240) << 8) |\n ((num & 3840) << 8) |\n ((num & 3840) << 12);\n return new Css.Color(num);\n }\n throw new Error(\"E_CSS_COLOR\");\n}\n\nexport class ParserHandler implements CssTokenizer.TokenizerHandler {\n flavor: StylesheetFlavor;\n\n constructor(public scope: Exprs.LexicalScope) {\n this.flavor = StylesheetFlavor.AUTHOR;\n }\n\n getCurrentToken(): CssTokenizer.Token {\n return null;\n }\n\n getScope(): Exprs.LexicalScope {\n return this.scope;\n }\n\n error(mnemonics: string, token: CssTokenizer.Token): void {}\n\n startStylesheet(flavor: StylesheetFlavor): void {\n this.flavor = flavor;\n }\n\n tagSelector(ns: string | null, name: string | null): void {}\n\n classSelector(name: string): void {}\n\n pseudoclassSelector(name: string, params: (number | string)[]): void {}\n\n pseudoelementSelector(name: string, params: (number | string)[]): void {}\n\n idSelector(id: string): void {}\n\n attributeSelector(\n ns: string,\n name: string,\n op: CssTokenizer.TokenType,\n value: string | null,\n ): void {}\n\n descendantSelector(): void {}\n\n childSelector(): void {}\n\n adjacentSiblingSelector(): void {}\n\n followingSiblingSelector(): void {}\n\n nextSelector(): void {}\n\n startSelectorRule(): void {}\n\n startFontFaceRule(): void {}\n\n startFootnoteRule(pseudoelem: string | null): void {}\n\n startViewportRule(): void {}\n\n startDefineRule(): void {}\n\n startRegionRule(): void {}\n\n startPageRule(): void {}\n\n startPageMarginBoxRule(name: string): void {}\n\n startWhenRule(expr: Css.Expr): void {}\n\n startMediaRule(expr: Css.Expr): void {\n this.startWhenRule(expr);\n }\n\n startFlowRule(flowName: string): void {}\n\n startPageTemplateRule(): void {}\n\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {}\n\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {}\n\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {}\n\n startRuleBody(): void {}\n\n property(name: string, value: Css.Val, important: boolean): void {}\n\n endRule(): void {}\n\n /**\n * @param funcName The name of the function taking a selector list as an\n * argument\n */\n startFuncWithSelector(funcName: string): void {}\n\n endFuncWithSelector(): void {}\n\n getImportantSpecificity(): number {\n switch (this.flavor) {\n case StylesheetFlavor.USER_AGENT:\n return SPECIFICITY_USER_AGENT;\n case StylesheetFlavor.USER:\n return SPECIFICITY_USER_IMPORTANT;\n default:\n return SPECIFICITY_AUTHOR_IMPORTANT;\n }\n }\n\n getBaseSpecificity(): number {\n switch (this.flavor) {\n case StylesheetFlavor.USER_AGENT:\n return SPECIFICITY_USER_AGENT;\n case StylesheetFlavor.USER:\n return SPECIFICITY_USER;\n default:\n return SPECIFICITY_AUTHOR;\n }\n }\n}\n\nexport class DispatchParserHandler extends ParserHandler {\n stack: ParserHandler[] = [];\n tokenizer: CssTokenizer.Tokenizer = null;\n slave: ParserHandler = null;\n\n constructor() {\n super(null);\n }\n\n pushHandler(slave: ParserHandler): void {\n this.stack.push(this.slave);\n this.slave = slave;\n }\n\n popHandler(): void {\n this.slave = this.stack.pop();\n }\n\n /**\n * @override\n */\n getCurrentToken(): CssTokenizer.Token {\n if (this.tokenizer) {\n return this.tokenizer.token();\n }\n return null;\n }\n\n /**\n * @override\n */\n getScope(): Exprs.LexicalScope {\n return this.slave.getScope();\n }\n\n /**\n * Forwards call to slave.\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n this.slave.error(mnemonics, token);\n }\n\n /**\n * Called by a slave.\n */\n errorMsg(mnemonics: string, token: CssTokenizer.Token): void {\n Logging.logger.warn(mnemonics);\n }\n\n /**\n * @override\n */\n startStylesheet(flavor: StylesheetFlavor): void {\n super.startStylesheet(flavor);\n if (this.stack.length > 0) {\n // This can occur as a result of an error\n this.slave = this.stack[0];\n this.stack = [];\n }\n this.slave.startStylesheet(flavor);\n }\n\n /**\n * @override\n */\n tagSelector(ns: string | null, name: string | null): void {\n this.slave.tagSelector(ns, name);\n }\n\n /**\n * @override\n */\n classSelector(name: string): void {\n this.slave.classSelector(name);\n }\n\n /**\n * @override\n */\n pseudoclassSelector(name: string, params: (number | string)[]): void {\n this.slave.pseudoclassSelector(name, params);\n }\n\n /**\n * @override\n */\n pseudoelementSelector(name: string, params: (number | string)[]): void {\n this.slave.pseudoelementSelector(name, params);\n }\n\n /**\n * @override\n */\n idSelector(id: string): void {\n this.slave.idSelector(id);\n }\n\n /**\n * @override\n */\n attributeSelector(\n ns: string,\n name: string,\n op: CssTokenizer.TokenType,\n value: string | null,\n ): void {\n this.slave.attributeSelector(ns, name, op, value);\n }\n\n /**\n * @override\n */\n descendantSelector(): void {\n this.slave.descendantSelector();\n }\n\n /**\n * @override\n */\n childSelector(): void {\n this.slave.childSelector();\n }\n\n /**\n * @override\n */\n adjacentSiblingSelector(): void {\n this.slave.adjacentSiblingSelector();\n }\n\n /**\n * @override\n */\n followingSiblingSelector(): void {\n this.slave.followingSiblingSelector();\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.slave.nextSelector();\n }\n\n /**\n * @override\n */\n startSelectorRule(): void {\n this.slave.startSelectorRule();\n }\n\n /**\n * @override\n */\n startFontFaceRule(): void {\n this.slave.startFontFaceRule();\n }\n\n /**\n * @override\n */\n startFootnoteRule(pseudoelem: string | null): void {\n this.slave.startFootnoteRule(pseudoelem);\n }\n\n /**\n * @override\n */\n startViewportRule(): void {\n this.slave.startViewportRule();\n }\n\n /**\n * @override\n */\n startDefineRule(): void {\n this.slave.startDefineRule();\n }\n\n /**\n * @override\n */\n startRegionRule(): void {\n this.slave.startRegionRule();\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n this.slave.startPageRule();\n }\n\n /**\n * @override\n */\n startPageMarginBoxRule(name: string): void {\n this.slave.startPageMarginBoxRule(name);\n }\n\n /**\n * @override\n */\n startWhenRule(expr: Css.Expr): void {\n this.slave.startWhenRule(expr);\n }\n\n /**\n * @override\n */\n startFlowRule(flowName: string): void {\n this.slave.startFlowRule(flowName);\n }\n\n /**\n * @override\n */\n startPageTemplateRule(): void {\n this.slave.startPageTemplateRule();\n }\n\n /**\n * @override\n */\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.slave.startPageMasterRule(name, pseudoName, classes);\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.slave.startPartitionRule(name, pseudoName, classes);\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.slave.startPartitionGroupRule(name, pseudoName, classes);\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.slave.startRuleBody();\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.slave.property(name, value, important);\n }\n\n /**\n * @override\n */\n endRule(): void {\n this.slave.endRule();\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n this.slave.startFuncWithSelector(funcName);\n }\n\n /**\n * @override\n */\n endFuncWithSelector(): void {\n this.slave.endFuncWithSelector();\n }\n}\n\nexport class SkippingParserHandler extends ParserHandler {\n depth: number = 0;\n flavor: StylesheetFlavor;\n\n constructor(\n scope: Exprs.LexicalScope,\n public owner: DispatchParserHandler,\n public readonly topLevel,\n ) {\n super(scope);\n if (owner) {\n this.flavor = owner.flavor;\n }\n }\n\n /**\n * @override\n */\n getCurrentToken(): CssTokenizer.Token {\n return this.owner.getCurrentToken();\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n this.owner.errorMsg(mnemonics, token);\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.depth++;\n }\n\n /**\n * @override\n */\n endRule(): void {\n if (--this.depth == 0 && !this.topLevel) {\n this.owner.popHandler();\n }\n }\n}\n\nexport class SlaveParserHandler extends SkippingParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: DispatchParserHandler,\n topLevel: boolean,\n ) {\n super(scope, owner, topLevel);\n }\n\n report(message: string): void {\n this.error(message, this.getCurrentToken());\n }\n\n reportAndSkip(message: string): void {\n this.report(message);\n this.owner.pushHandler(\n new SkippingParserHandler(this.scope, this.owner, false),\n );\n }\n\n /**\n * @override\n */\n startSelectorRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_SELECTOR\");\n }\n\n /**\n * @override\n */\n startFontFaceRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_FONT_FACE\");\n }\n\n /**\n * @override\n */\n startFootnoteRule(pseudoelem: string | null): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_FOOTNOTE\");\n }\n\n /**\n * @override\n */\n startViewportRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_VIEWPORT\");\n }\n\n /**\n * @override\n */\n startDefineRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_DEFINE\");\n }\n\n /**\n * @override\n */\n startRegionRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_REGION\");\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PAGE\");\n }\n\n /**\n * @override\n */\n startWhenRule(expr: Css.Expr): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_WHEN\");\n }\n\n /**\n * @override\n */\n startFlowRule(flowName: string): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_FLOW\");\n }\n\n /**\n * @override\n */\n startPageTemplateRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PAGE_TEMPLATE\");\n }\n\n /**\n * @override\n */\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PAGE_MASTER\");\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PARTITION\");\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PARTITION_GROUP\");\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_SELECTOR_FUNC\");\n }\n\n /**\n * @override\n */\n endFuncWithSelector(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_END_SELECTOR_FUNC\");\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.error(\"E_CSS_UNEXPECTED_PROPERTY\", this.getCurrentToken());\n }\n}\n\nexport const actionsBase: Action[] = [];\n\nexport const actionsStyleAttribute: Action[] = [];\n\nexport const actionsSelector: Action[] = [];\n\nexport const actionsSelectorInFunc: Action[] = [];\n\nexport const actionsSelectorCont: Action[] = [];\n\nexport const actionsSelectorStart: Action[] = [];\n\nexport const actionsPropVal: Action[] = [];\n\nexport const actionsExprVal: Action[] = [];\n\nexport const actionsExprOp: Action[] = [];\n\nexport const actionsError: Action[] = [];\n\nexport const actionsErrorDecl: Action[] = [];\n\nexport const actionsErrorSelector: Action[] = [];\n\nexport const priority: number[] = [];\n\n/**\n * @enum {number}\n */\nexport enum Action {\n SELECTOR_NAME_1 = 1,\n SELECTOR_NAME,\n SELECTOR_ANY_1,\n SELECTOR_ANY,\n SELECTOR_ID_1,\n SELECTOR_ID,\n SELECTOR_CLASS_1,\n SELECTOR_CLASS,\n SELECTOR_ATTR_1,\n SELECTOR_ATTR,\n SELECTOR_CHILD,\n SELECTOR_SIBLING,\n SELECTOR_BODY,\n SELECTOR_PSEUDOCLASS,\n VAL_IDENT,\n VAL_HASH,\n VAL_NUM,\n VAL_INT,\n VAL_NUMERIC,\n VAL_STR,\n VAL_URL,\n VAL_COMMA,\n VAL_SLASH,\n VAL_FUNC,\n VAL_C_PAR,\n VAL_END,\n RULE_END,\n IDENT,\n SELECTOR_START,\n AT,\n EXPR_IDENT,\n EXPR_NUM,\n EXPR_NUMERIC,\n EXPR_STR,\n EXPR_PARAM,\n EXPR_PREFIX,\n EXPR_INFIX,\n EXPR_FUNC,\n EXPR_C_PAR,\n EXPR_O_PAR,\n SELECTOR_NEXT,\n SELECTOR_PSEUDOELEM,\n EXPR_O_BRC,\n VAL_FINISH,\n EXPR_INFIX_NAME,\n PROP,\n VAL_BANG,\n VAL_BRC,\n EXPR_SEMICOL,\n ERROR_PUSH,\n ERROR_POP,\n ERROR_POP_DECL,\n ERROR_SEMICOL,\n VAL_PLUS,\n SELECTOR_PSEUDOCLASS_1,\n SELECTOR_FOLLOWING_SIBLING,\n DONE = 200,\n}\n\nexport const OP_MEDIA_AND: number = CssTokenizer.TokenType.LAST + 1;\n\n(() => {\n actionsBase[CssTokenizer.TokenType.IDENT] = Action.IDENT;\n actionsBase[CssTokenizer.TokenType.STAR] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.HASH] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.COLON] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.AT] = Action.AT;\n actionsBase[CssTokenizer.TokenType.C_BRC] = Action.RULE_END;\n actionsBase[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsStyleAttribute[CssTokenizer.TokenType.IDENT] = Action.PROP;\n actionsStyleAttribute[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsSelectorStart[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME;\n actionsSelectorStart[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY;\n actionsSelectorStart[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID;\n actionsSelectorStart[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS;\n actionsSelectorStart[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR;\n actionsSelectorStart[CssTokenizer.TokenType.COLON] =\n Action.SELECTOR_PSEUDOCLASS;\n\n actionsSelector[CssTokenizer.TokenType.GT] = Action.SELECTOR_CHILD;\n actionsSelector[CssTokenizer.TokenType.PLUS] = Action.SELECTOR_SIBLING;\n actionsSelector[CssTokenizer.TokenType.TILDE] =\n Action.SELECTOR_FOLLOWING_SIBLING;\n actionsSelector[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME_1;\n actionsSelector[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY_1;\n actionsSelector[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID_1;\n actionsSelector[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS_1;\n actionsSelector[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR_1;\n actionsSelector[CssTokenizer.TokenType.O_BRC] = Action.SELECTOR_BODY;\n actionsSelector[CssTokenizer.TokenType.COLON] = Action.SELECTOR_PSEUDOCLASS_1;\n actionsSelector[CssTokenizer.TokenType.COL_COL] = Action.SELECTOR_PSEUDOELEM;\n actionsSelector[CssTokenizer.TokenType.COMMA] = Action.SELECTOR_NEXT;\n actionsSelectorInFunc[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.C_PAR] = Action.DONE;\n actionsSelectorInFunc[CssTokenizer.TokenType.COLON] =\n Action.SELECTOR_PSEUDOCLASS_1;\n actionsSelectorCont[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME;\n actionsSelectorCont[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY;\n actionsSelectorCont[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID;\n actionsSelectorCont[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS;\n actionsSelectorCont[CssTokenizer.TokenType.COLON] =\n Action.SELECTOR_PSEUDOCLASS;\n actionsSelectorCont[CssTokenizer.TokenType.COL_COL] =\n Action.SELECTOR_PSEUDOELEM;\n actionsSelectorCont[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR;\n actionsSelectorCont[CssTokenizer.TokenType.O_BRC] = Action.SELECTOR_BODY;\n actionsPropVal[CssTokenizer.TokenType.IDENT] = Action.VAL_IDENT;\n actionsPropVal[CssTokenizer.TokenType.HASH] = Action.VAL_HASH;\n actionsPropVal[CssTokenizer.TokenType.NUM] = Action.VAL_NUM;\n actionsPropVal[CssTokenizer.TokenType.INT] = Action.VAL_INT;\n actionsPropVal[CssTokenizer.TokenType.NUMERIC] = Action.VAL_NUMERIC;\n actionsPropVal[CssTokenizer.TokenType.STR] = Action.VAL_STR;\n actionsPropVal[CssTokenizer.TokenType.URL] = Action.VAL_URL;\n actionsPropVal[CssTokenizer.TokenType.COMMA] = Action.VAL_COMMA;\n actionsPropVal[CssTokenizer.TokenType.SLASH] = Action.VAL_SLASH;\n actionsPropVal[CssTokenizer.TokenType.FUNC] = Action.VAL_FUNC;\n actionsPropVal[CssTokenizer.TokenType.C_PAR] = Action.VAL_C_PAR;\n actionsPropVal[CssTokenizer.TokenType.SEMICOL] = Action.VAL_END;\n actionsPropVal[CssTokenizer.TokenType.C_BRC] = Action.VAL_BRC;\n actionsPropVal[CssTokenizer.TokenType.BANG] = Action.VAL_BANG;\n actionsPropVal[CssTokenizer.TokenType.PLUS] = Action.VAL_PLUS;\n actionsPropVal[CssTokenizer.TokenType.EOF] = Action.VAL_FINISH;\n actionsExprVal[CssTokenizer.TokenType.IDENT] = Action.EXPR_IDENT;\n actionsExprVal[CssTokenizer.TokenType.NUM] = Action.EXPR_NUM;\n actionsExprVal[CssTokenizer.TokenType.INT] = Action.EXPR_NUM;\n actionsExprVal[CssTokenizer.TokenType.NUMERIC] = Action.EXPR_NUMERIC;\n actionsExprVal[CssTokenizer.TokenType.STR] = Action.EXPR_STR;\n actionsExprVal[CssTokenizer.TokenType.O_PAR] = Action.EXPR_O_PAR;\n actionsExprVal[CssTokenizer.TokenType.FUNC] = Action.EXPR_FUNC;\n actionsExprVal[CssTokenizer.TokenType.BANG] = Action.EXPR_PREFIX;\n actionsExprVal[CssTokenizer.TokenType.MINUS] = Action.EXPR_PREFIX;\n actionsExprVal[CssTokenizer.TokenType.DOLLAR] = Action.EXPR_PARAM;\n actionsExprOp[CssTokenizer.TokenType.IDENT] = Action.EXPR_INFIX_NAME;\n actionsExprOp[CssTokenizer.TokenType.COMMA] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.GT] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.LT] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.GT_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.LT_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.EQ_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.BANG_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.AMP_AMP] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.BAR_BAR] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.PLUS] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.MINUS] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.SLASH] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.PERCENT] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.STAR] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.COLON] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.QMARK] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.C_PAR] = Action.EXPR_C_PAR;\n actionsExprOp[CssTokenizer.TokenType.O_BRC] = Action.EXPR_O_BRC;\n actionsExprOp[CssTokenizer.TokenType.SEMICOL] = Action.EXPR_SEMICOL;\n actionsError[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsError[CssTokenizer.TokenType.O_BRC] = Action.ERROR_PUSH;\n actionsError[CssTokenizer.TokenType.C_BRC] = Action.ERROR_POP;\n actionsError[CssTokenizer.TokenType.O_BRK] = Action.ERROR_PUSH;\n actionsError[CssTokenizer.TokenType.C_BRK] = Action.ERROR_POP;\n actionsError[CssTokenizer.TokenType.O_PAR] = Action.ERROR_PUSH;\n actionsError[CssTokenizer.TokenType.C_PAR] = Action.ERROR_POP;\n actionsError[CssTokenizer.TokenType.SEMICOL] = Action.ERROR_SEMICOL;\n actionsErrorDecl[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsErrorDecl[CssTokenizer.TokenType.O_BRC] = Action.ERROR_PUSH;\n actionsErrorDecl[CssTokenizer.TokenType.C_BRC] = Action.ERROR_POP_DECL;\n actionsErrorDecl[CssTokenizer.TokenType.O_BRK] = Action.ERROR_PUSH;\n actionsErrorDecl[CssTokenizer.TokenType.C_BRK] = Action.ERROR_POP;\n actionsErrorDecl[CssTokenizer.TokenType.O_PAR] = Action.ERROR_PUSH;\n actionsErrorDecl[CssTokenizer.TokenType.C_PAR] = Action.ERROR_POP;\n actionsErrorDecl[CssTokenizer.TokenType.SEMICOL] = Action.ERROR_SEMICOL;\n actionsErrorSelector[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsErrorSelector[CssTokenizer.TokenType.O_BRC] = Action.ERROR_PUSH;\n actionsErrorSelector[CssTokenizer.TokenType.C_BRC] = Action.ERROR_POP;\n actionsErrorSelector[CssTokenizer.TokenType.O_BRK] = Action.ERROR_PUSH;\n actionsErrorSelector[CssTokenizer.TokenType.C_BRK] = Action.ERROR_POP;\n actionsErrorSelector[CssTokenizer.TokenType.O_PAR] = Action.ERROR_PUSH;\n actionsErrorSelector[CssTokenizer.TokenType.C_PAR] = Action.ERROR_POP;\n priority[CssTokenizer.TokenType.C_PAR] = 0;\n priority[CssTokenizer.TokenType.COMMA] = 0;\n priority[CssTokenizer.TokenType.QMARK] = 1;\n priority[CssTokenizer.TokenType.COLON] = 1;\n priority[CssTokenizer.TokenType.AMP_AMP] = 2;\n priority[CssTokenizer.TokenType.BAR_BAR] = 2;\n priority[CssTokenizer.TokenType.LT] = 3;\n priority[CssTokenizer.TokenType.GT] = 3;\n priority[CssTokenizer.TokenType.LT_EQ] = 3;\n priority[CssTokenizer.TokenType.GT_EQ] = 3;\n priority[CssTokenizer.TokenType.EQ] = 3;\n priority[CssTokenizer.TokenType.EQ_EQ] = 3;\n priority[CssTokenizer.TokenType.BANG_EQ] = 3;\n priority[CssTokenizer.TokenType.PLUS] = 4;\n priority[CssTokenizer.TokenType.MINUS] = 4;\n priority[CssTokenizer.TokenType.STAR] = 5;\n priority[CssTokenizer.TokenType.SLASH] = 5;\n priority[CssTokenizer.TokenType.PERCENT] = 5;\n priority[CssTokenizer.TokenType.EOF] = 6;\n priority[OP_MEDIA_AND] = 2;\n})();\n\n/**\n * @enum {number}\n */\nexport enum ExprContext {\n PROP,\n WHEN,\n MEDIA,\n IMPORT,\n}\n\nexport class Parser {\n valStack: any[] = [];\n namespacePrefixToURI: { [key: string]: string } = {};\n defaultNamespaceURI: string | null = null;\n propName: string | null = null;\n propImportant: boolean = false;\n exprContext: ExprContext;\n result: Css.Val = null;\n importReady: boolean = false;\n importURL: string | null = null;\n importCondition: Css.Expr = null;\n errorBrackets: number[] = [];\n ruleStack: string[] = [];\n regionRule: boolean = false;\n pageRule: boolean = false;\n\n constructor(\n public actions: Action[],\n public tokenizer: CssTokenizer.Tokenizer,\n public readonly handler: ParserHandler,\n public baseURL: string,\n ) {\n this.exprContext = ExprContext.MEDIA;\n }\n\n extractVals(sep: string, index: number): Css.Val[] {\n const arr: Css.Val[] = [];\n const valStack = this.valStack;\n while (true) {\n arr.push(valStack[index++] as Css.Val);\n if (index == valStack.length) {\n break;\n }\n if (valStack[index++] != sep) {\n throw new Error(\"Unexpected state\");\n }\n }\n return arr;\n }\n\n valStackReduce(sep: string, token: CssTokenizer.Token): Css.Val {\n const valStack = this.valStack;\n let index = valStack.length;\n let v;\n do {\n v = valStack[--index];\n } while (typeof v != \"undefined\" && typeof v != \"string\");\n let count = valStack.length - (index + 1);\n if (count > 1) {\n valStack.splice(\n index + 1,\n count,\n new Css.SpaceList(valStack.slice(index + 1, valStack.length)),\n );\n }\n if (sep == \",\") {\n return null;\n }\n index++;\n do {\n v = valStack[--index];\n } while (typeof v != \"undefined\" && (typeof v != \"string\" || v == \",\"));\n count = valStack.length - (index + 1);\n if (v == \"(\") {\n if (sep != \")\") {\n this.handler.error(\"E_CSS_MISMATCHED_C_PAR\", token);\n this.actions = actionsErrorDecl;\n return null;\n }\n const func = new Css.Func(\n valStack[index - 1] as string,\n this.extractVals(\",\", index + 1),\n );\n valStack.splice(index - 1, count + 2, func);\n return null;\n }\n if (sep != \";\" || index >= 0) {\n this.handler.error(\"E_CSS_UNEXPECTED_VAL_END\", token);\n this.actions = actionsErrorDecl;\n return null;\n }\n if (count > 1) {\n return new Css.CommaList(this.extractVals(\",\", index + 1));\n }\n return valStack[0] as Css.Val;\n }\n\n exprError(mnemonics: string, token: CssTokenizer.Token) {\n this.actions = this.propName ? actionsErrorDecl : actionsError;\n this.handler.error(mnemonics, token);\n }\n\n exprStackReduce(op: number, token: CssTokenizer.Token): boolean {\n const valStack = this.valStack;\n const handler = this.handler;\n let val = valStack.pop() as Exprs.Val;\n let val2: Exprs.Val;\n while (true) {\n let tok = valStack.pop();\n if (op == CssTokenizer.TokenType.C_PAR) {\n const args: Exprs.Val[] = [val];\n while (tok == CssTokenizer.TokenType.COMMA) {\n args.unshift(valStack.pop());\n tok = valStack.pop();\n }\n if (typeof tok == \"string\") {\n if (tok == \"{\") {\n // reached CSS portion of the stack\n while (args.length >= 2) {\n const e1 = args.shift();\n const e2 = args.shift();\n const er = new Exprs.OrMedia(handler.getScope(), e1, e2);\n args.unshift(er);\n }\n valStack.push(new Css.Expr(args[0]));\n return true;\n } else if (tok == \"(\") {\n // call\n const name2 = valStack.pop() as string;\n const name1 = valStack.pop() as string | null;\n val = new Exprs.Call(\n handler.getScope(),\n Exprs.makeQualifiedName(name1, name2),\n args,\n );\n op = CssTokenizer.TokenType.EOF;\n continue;\n }\n }\n if (tok == CssTokenizer.TokenType.O_PAR) {\n if (val.isMediaName()) {\n val = new Exprs.MediaTest(\n handler.getScope(),\n val as Exprs.MediaName,\n null,\n );\n }\n op = CssTokenizer.TokenType.EOF;\n continue;\n }\n } else {\n if (typeof tok == \"string\") {\n // reached CSS portion of the stack or a call\n valStack.push(tok);\n break;\n }\n }\n if ((tok as number) < 0) {\n // prefix\n if (tok == -CssTokenizer.TokenType.BANG) {\n val = new Exprs.Not(handler.getScope(), val);\n } else if (tok == -CssTokenizer.TokenType.MINUS) {\n val = new Exprs.Negate(handler.getScope(), val);\n } else {\n this.exprError(\"F_UNEXPECTED_STATE\", token);\n return false;\n }\n } else {\n // infix\n if (priority[op] > priority[tok as number]) {\n valStack.push(tok);\n break;\n }\n val2 = valStack.pop() as Exprs.Val;\n switch (tok) {\n case CssTokenizer.TokenType.AMP_AMP:\n val = new Exprs.And(handler.getScope(), val2, val);\n break;\n case OP_MEDIA_AND:\n val = new Exprs.AndMedia(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.BAR_BAR:\n val = new Exprs.Or(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.LT:\n val = new Exprs.Lt(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.GT:\n val = new Exprs.Gt(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.LT_EQ:\n val = new Exprs.Le(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.GT_EQ:\n val = new Exprs.Ge(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.EQ:\n case CssTokenizer.TokenType.EQ_EQ:\n val = new Exprs.Eq(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.BANG_EQ:\n val = new Exprs.Ne(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.PLUS:\n val = new Exprs.Add(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.MINUS:\n val = new Exprs.Subtract(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.STAR:\n val = new Exprs.Multiply(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.SLASH:\n val = new Exprs.Divide(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.PERCENT:\n val = new Exprs.Modulo(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.COLON:\n if (valStack.length > 1) {\n switch (valStack[valStack.length - 1]) {\n case CssTokenizer.TokenType.QMARK:\n valStack.pop();\n val = new Exprs.Cond(\n handler.getScope(),\n valStack.pop() as Exprs.Val,\n val2,\n val,\n );\n break;\n case CssTokenizer.TokenType.O_PAR:\n if (val2.isMediaName()) {\n val = new Exprs.MediaTest(\n handler.getScope(),\n val2 as Exprs.MediaName,\n val,\n );\n } else {\n this.exprError(\"E_CSS_MEDIA_TEST\", token);\n return false;\n }\n break;\n }\n } else {\n this.exprError(\"E_CSS_EXPR_COND\", token);\n return false;\n }\n break;\n case CssTokenizer.TokenType.QMARK:\n if (op != CssTokenizer.TokenType.COLON) {\n this.exprError(\"E_CSS_EXPR_COND\", token);\n return false;\n }\n\n // fall through\n case CssTokenizer.TokenType.O_PAR:\n // don't reduce\n valStack.push(val2);\n valStack.push(tok);\n valStack.push(val);\n return false;\n default:\n this.exprError(\"F_UNEXPECTED_STATE\", token);\n return false;\n }\n }\n }\n valStack.push(val);\n return false;\n }\n\n readPseudoParams(): (number | string)[] {\n const arr = [];\n while (true) {\n const token = this.tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n arr.push(token.text);\n break;\n case CssTokenizer.TokenType.PLUS:\n arr.push(\"+\");\n break;\n case CssTokenizer.TokenType.NUM:\n case CssTokenizer.TokenType.INT:\n arr.push(token.num);\n break;\n default:\n return arr;\n }\n this.tokenizer.consume();\n }\n }\n\n /**\n * Read `an+b` argument of pseudoclasses. Roughly based on the algorithm at\n * https://drafts.csswg.org/css-syntax/#the-anb-type\n */\n private readNthPseudoParams(): number[] | null {\n let hasLeadingPlus = false;\n let token = this.tokenizer.token();\n if (token.type === CssTokenizer.TokenType.PLUS) {\n // '+'\n hasLeadingPlus = true;\n this.tokenizer.consume();\n token = this.tokenizer.token();\n } else if (\n token.type === CssTokenizer.TokenType.IDENT &&\n (token.text === \"even\" || token.text === \"odd\")\n ) {\n // 'even' or 'odd'\n this.tokenizer.consume();\n return [2, token.text === \"odd\" ? 1 : 0];\n }\n switch (token.type) {\n case CssTokenizer.TokenType.NUMERIC:\n if (hasLeadingPlus && token.num < 0) {\n // reject '+-an'\n return null;\n }\n\n // FALLTHROUGH\n case CssTokenizer.TokenType.IDENT:\n if (hasLeadingPlus && token.text.charAt(0) === \"-\") {\n // reject '+-n'\n return null;\n }\n if (token.text === \"n\" || token.text === \"-n\") {\n // 'an', 'an +b', 'an -b', 'n', 'n +b', 'n -b', '-n', '-n +b' '-n -b'\n if (hasLeadingPlus && token.precededBySpace) {\n // reject '+ an'\n return null;\n }\n let a = token.text === \"-n\" ? -1 : 1;\n if (token.type === CssTokenizer.TokenType.NUMERIC) {\n a = token.num;\n }\n let b = 0;\n this.tokenizer.consume();\n token = this.tokenizer.token();\n const hasMinusSign = token.type === CssTokenizer.TokenType.MINUS;\n const hasSign =\n token.type === CssTokenizer.TokenType.PLUS || hasMinusSign;\n if (hasSign) {\n // 'an +b', 'an - b'\n this.tokenizer.consume();\n token = this.tokenizer.token();\n }\n if (token.type === CssTokenizer.TokenType.INT) {\n b = token.num;\n\n if (1 / b === 1 / -0) {\n // negative zero: 'an -0'\n b = 0;\n if (hasSign) {\n return null; // reject 'an + -0', 'an - -0'\n }\n } else if (b < 0) {\n // negative: 'an -b'\n if (hasSign) {\n return null; // reject 'an + -b', 'an - -b'\n }\n } else if (b >= 0) {\n // positive or positive zero: 'an +b'\n if (!hasSign) {\n return null;\n }\n }\n this.tokenizer.consume();\n } else if (hasSign) {\n // reject 'an + (non-integer)'\n return null;\n }\n return [a, hasMinusSign && b > 0 ? -b : b];\n } else if (token.text === \"n-\" || token.text === \"-n-\") {\n // 'an- b', '-n- b'\n if (hasLeadingPlus && token.precededBySpace) {\n // reject '+ an- b'\n return null;\n }\n let a = token.text === \"-n-\" ? -1 : 1;\n if (token.type === CssTokenizer.TokenType.NUMERIC) {\n a = token.num;\n }\n this.tokenizer.consume();\n token = this.tokenizer.token();\n if (token.type === CssTokenizer.TokenType.INT) {\n if (token.num < 0 || 1 / token.num === 1 / -0) {\n // reject 'an- -b', 'an- -0'\n return null;\n } else {\n this.tokenizer.consume();\n return [a, token.num];\n }\n }\n } else {\n let r = token.text.match(/^n(-[0-9]+)$/);\n if (r) {\n // 'n-b', 'an-b'\n if (hasLeadingPlus && token.precededBySpace) {\n // reject '+ an-b'\n return null;\n }\n this.tokenizer.consume();\n return [\n token.type === CssTokenizer.TokenType.NUMERIC ? token.num : 1,\n parseInt(r[1], 10),\n ];\n }\n r = token.text.match(/^-n(-[0-9]+)$/);\n\n // '-n-b'\n if (r) {\n this.tokenizer.consume();\n return [-1, parseInt(r[1], 10)];\n }\n }\n return null;\n case CssTokenizer.TokenType.INT:\n if (hasLeadingPlus && (token.precededBySpace || token.num < 0)) {\n return null;\n }\n this.tokenizer.consume();\n return [0, token.num];\n }\n return null;\n }\n\n makeCondition(classes: string | null, condition: Exprs.Val): Css.Expr {\n const scope = this.handler.getScope();\n if (!scope) {\n return null;\n }\n condition = condition || scope._true;\n if (classes) {\n const classList = classes.split(/\\s+/);\n for (const className of classList) {\n switch (className) {\n case \"vertical\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Not(scope, new Exprs.Named(scope, \"pref-horizontal\")),\n );\n break;\n case \"horizontal\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Named(scope, \"pref-horizontal\"),\n );\n break;\n case \"day\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Not(scope, new Exprs.Named(scope, \"pref-night-mode\")),\n );\n break;\n case \"night\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Named(scope, \"pref-night-mode\"),\n );\n break;\n default:\n condition = scope._false;\n }\n }\n }\n if (condition === scope._true) {\n return null;\n }\n return new Css.Expr(condition);\n }\n\n isInsidePropertyOnlyRule(): boolean {\n switch (this.ruleStack[this.ruleStack.length - 1]) {\n case \"[selector]\":\n case \"font-face\":\n case \"-epubx-flow\":\n case \"-epubx-viewport\":\n case \"-epubx-define\":\n case \"-adapt-footnote-area\":\n return true;\n }\n return false;\n }\n\n runParser(\n count: number,\n parsingValue,\n parsingStyleAttr: boolean,\n parsingMediaQuery,\n parsingFunctionParam,\n ): boolean {\n const handler = this.handler;\n const tokenizer = this.tokenizer;\n const valStack = this.valStack;\n let token: CssTokenizer.Token;\n let token1: CssTokenizer.Token;\n let ns: string | null;\n let text: string | null;\n let num: number;\n let val: Css.Val;\n let params: (number | string)[];\n if (parsingMediaQuery) {\n this.exprContext = ExprContext.MEDIA;\n this.valStack.push(\"{\");\n }\n parserLoop: for (; count > 0; --count) {\n token = tokenizer.token();\n switch (this.actions[token.type]) {\n case Action.IDENT:\n // figure out if this is a property assignment or selector\n if (tokenizer.nthToken(1).type != CssTokenizer.TokenType.COLON) {\n // cannot be property assignment\n if (this.isInsidePropertyOnlyRule()) {\n handler.error(\"E_CSS_COLON_EXPECTED\", tokenizer.nthToken(1));\n this.actions = actionsErrorDecl;\n } else {\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n }\n continue;\n }\n token1 = tokenizer.nthToken(2);\n if (\n token1.precededBySpace ||\n (token1.type != CssTokenizer.TokenType.IDENT &&\n token1.type != CssTokenizer.TokenType.FUNC)\n ) {\n // cannot be a selector\n } else {\n // can be either a selector or a property assignment\n tokenizer.mark();\n }\n this.propName = token.text;\n this.propImportant = false;\n tokenizer.consume();\n tokenizer.consume();\n this.actions = actionsPropVal;\n valStack.splice(0, valStack.length);\n continue;\n case Action.PROP:\n // figure out if this is a property assignment or selector\n if (tokenizer.nthToken(1).type != CssTokenizer.TokenType.COLON) {\n // cannot be property assignment\n this.actions = actionsErrorDecl;\n handler.error(\"E_CSS_COLON_EXPECTED\", tokenizer.nthToken(1));\n continue;\n }\n this.propName = token.text;\n this.propImportant = false;\n tokenizer.consume();\n tokenizer.consume();\n this.actions = actionsPropVal;\n valStack.splice(0, valStack.length);\n continue;\n case Action.SELECTOR_START:\n // don't consume, process again\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n continue;\n case Action.SELECTOR_NAME_1:\n if (!token.precededBySpace) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_SPACE_EXPECTED\", token);\n continue;\n }\n handler.descendantSelector();\n\n // fall through\n case Action.SELECTOR_NAME:\n if (tokenizer.nthToken(1).type == CssTokenizer.TokenType.BAR) {\n tokenizer.consume();\n tokenizer.consume();\n ns = this.namespacePrefixToURI[token.text];\n if (ns != null) {\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.tagSelector(ns, token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n case CssTokenizer.TokenType.STAR:\n handler.tagSelector(ns, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n default:\n this.actions = actionsError;\n handler.error(\"E_CSS_NAMESPACE\", token);\n }\n } else {\n this.actions = actionsError;\n handler.error(\"E_CSS_UNDECLARED_PREFIX\", token);\n }\n } else {\n handler.tagSelector(this.defaultNamespaceURI, token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n }\n continue;\n case Action.SELECTOR_ANY_1:\n if (!token.precededBySpace) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_SPACE_EXPECTED\", token);\n continue;\n }\n handler.descendantSelector();\n\n // fall through\n case Action.SELECTOR_ANY:\n if (tokenizer.nthToken(1).type == CssTokenizer.TokenType.BAR) {\n tokenizer.consume();\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.tagSelector(null, token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n case CssTokenizer.TokenType.STAR:\n handler.tagSelector(null, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n default:\n this.actions = actionsError;\n handler.error(\"E_CSS_NAMESPACE\", token);\n }\n } else {\n handler.tagSelector(this.defaultNamespaceURI, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n }\n continue;\n case Action.SELECTOR_ID_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_ID:\n handler.idSelector(token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case Action.SELECTOR_CLASS_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_CLASS:\n handler.classSelector(token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case Action.SELECTOR_PSEUDOCLASS_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_PSEUDOCLASS:\n tokenizer.consume();\n token = tokenizer.token();\n pseudoclassType: switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.pseudoclassSelector(token.text, null);\n tokenizer.consume();\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n continue;\n case CssTokenizer.TokenType.FUNC:\n text = token.text;\n tokenizer.consume();\n switch (text) {\n case \"not\":\n this.actions = actionsSelectorStart;\n handler.startFuncWithSelector(\"not\");\n if (\n this.runParser(\n Number.POSITIVE_INFINITY,\n false,\n false,\n false,\n true,\n )\n ) {\n this.actions = actionsSelector;\n } else {\n this.actions = actionsErrorSelector;\n }\n break parserLoop;\n case \"lang\":\n case \"href-epub-type\":\n token = tokenizer.token();\n if (token.type === CssTokenizer.TokenType.IDENT) {\n params = [token.text];\n tokenizer.consume();\n break;\n } else {\n break pseudoclassType;\n }\n case \"nth-child\":\n case \"nth-of-type\":\n case \"nth-last-child\":\n case \"nth-last-of-type\":\n params = this.readNthPseudoParams();\n if (!params) {\n break pseudoclassType;\n } else {\n break;\n }\n default:\n // TODO\n params = this.readPseudoParams();\n }\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.C_PAR) {\n handler.pseudoclassSelector(text as string, params);\n tokenizer.consume();\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n continue;\n }\n break;\n }\n handler.error(\"E_CSS_PSEUDOCLASS_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case Action.SELECTOR_PSEUDOELEM:\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.pseudoelementSelector(token.text, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case CssTokenizer.TokenType.FUNC:\n text = token.text;\n tokenizer.consume();\n if (text == \"nth-fragment\") {\n params = this.readNthPseudoParams();\n if (params === null) {\n break;\n }\n } else {\n params = this.readPseudoParams();\n }\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.C_PAR) {\n handler.pseudoelementSelector(text as string, params);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n }\n break;\n }\n handler.error(\"E_CSS_PSEUDOELEM_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case Action.SELECTOR_ATTR_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_ATTR:\n tokenizer.consume();\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.IDENT) {\n text = token.text;\n tokenizer.consume();\n } else if (token.type == CssTokenizer.TokenType.STAR) {\n text = null;\n tokenizer.consume();\n } else if (token.type == CssTokenizer.TokenType.BAR) {\n text = \"\";\n } else {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR\", token);\n tokenizer.consume();\n continue;\n }\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.BAR) {\n ns = text ? this.namespacePrefixToURI[text] : text;\n if (ns == null) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_UNDECLARED_PREFIX\", token);\n tokenizer.consume();\n continue;\n }\n tokenizer.consume();\n token = tokenizer.token();\n if (token.type != CssTokenizer.TokenType.IDENT) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR_NAME_EXPECTED\", token);\n continue;\n }\n text = token.text;\n tokenizer.consume();\n token = tokenizer.token();\n } else {\n ns = \"\";\n }\n switch (token.type) {\n case CssTokenizer.TokenType.EQ:\n case CssTokenizer.TokenType.TILDE_EQ:\n case CssTokenizer.TokenType.BAR_EQ:\n case CssTokenizer.TokenType.HAT_EQ:\n case CssTokenizer.TokenType.DOLLAR_EQ:\n case CssTokenizer.TokenType.STAR_EQ:\n case CssTokenizer.TokenType.COL_COL:\n num = token.type;\n tokenizer.consume();\n token = tokenizer.token();\n break;\n case CssTokenizer.TokenType.C_BRK:\n handler.attributeSelector(\n ns as string,\n text as string,\n CssTokenizer.TokenType.EOF,\n null,\n );\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n default:\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR_OP_EXPECTED\", token);\n continue;\n }\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n case CssTokenizer.TokenType.STR:\n handler.attributeSelector(\n ns as string,\n text as string,\n num,\n token.text,\n );\n tokenizer.consume();\n token = tokenizer.token();\n break;\n default:\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR_VAL_EXPECTED\", token);\n continue;\n }\n if (token.type != CssTokenizer.TokenType.C_BRK) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR\", token);\n continue;\n }\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case Action.SELECTOR_CHILD:\n handler.childSelector();\n this.actions = actionsSelectorCont;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_SIBLING:\n handler.adjacentSiblingSelector();\n this.actions = actionsSelectorCont;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_FOLLOWING_SIBLING:\n handler.followingSiblingSelector();\n this.actions = actionsSelectorCont;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_BODY:\n if (this.regionRule) {\n this.ruleStack.push(\"-epubx-region\");\n this.regionRule = false;\n } else if (this.pageRule) {\n this.ruleStack.push(\"page\");\n this.pageRule = false;\n } else {\n this.ruleStack.push(\"[selector]\");\n }\n handler.startRuleBody();\n this.actions = actionsBase;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_NEXT:\n handler.nextSelector();\n this.actions = actionsSelectorStart;\n tokenizer.consume();\n continue;\n case Action.VAL_IDENT:\n valStack.push(Css.getName(token.text));\n tokenizer.consume();\n continue;\n case Action.VAL_HASH:\n num = parseInt(token.text, 16);\n try {\n valStack.push(colorFromHash(token.text));\n } catch (err) {\n handler.error(\"E_CSS_COLOR\", token);\n this.actions = actionsError;\n }\n tokenizer.consume();\n continue;\n case Action.VAL_NUM:\n valStack.push(new Css.Num(token.num));\n tokenizer.consume();\n continue;\n case Action.VAL_INT:\n valStack.push(new Css.Int(token.num));\n tokenizer.consume();\n continue;\n case Action.VAL_NUMERIC:\n if (Exprs.isViewportRelativeLengthUnit(token.text)) {\n // Treat numeric value with viewport unit as numeric in expr.\n valStack.push(\n new Css.Expr(\n new Exprs.Numeric(handler.getScope(), token.num, token.text),\n ),\n );\n } else {\n valStack.push(new Css.Numeric(token.num, token.text));\n }\n tokenizer.consume();\n continue;\n case Action.VAL_STR:\n valStack.push(new Css.Str(token.text));\n tokenizer.consume();\n continue;\n case Action.VAL_URL:\n valStack.push(new Css.URL(Base.resolveURL(token.text, this.baseURL)));\n tokenizer.consume();\n continue;\n case Action.VAL_COMMA:\n this.valStackReduce(\",\", token);\n valStack.push(\",\");\n tokenizer.consume();\n continue;\n case Action.VAL_SLASH:\n valStack.push(Css.slash);\n tokenizer.consume();\n continue;\n case Action.VAL_FUNC:\n text = token.text.toLowerCase();\n if (text == \"-epubx-expr\" || text == \"calc\" || text == \"env\") {\n // special case\n this.actions = actionsExprVal;\n this.exprContext = ExprContext.PROP;\n valStack.push(\"{\");\n } else {\n valStack.push(text);\n valStack.push(\"(\");\n }\n tokenizer.consume();\n continue;\n case Action.VAL_C_PAR:\n this.valStackReduce(\")\", token);\n tokenizer.consume();\n continue;\n case Action.VAL_BANG:\n tokenizer.consume();\n token = tokenizer.token();\n token1 = tokenizer.nthToken(1);\n if (\n token.type == CssTokenizer.TokenType.IDENT &&\n token.text.toLowerCase() == \"important\" &&\n (token1.type == CssTokenizer.TokenType.SEMICOL ||\n token1.type == CssTokenizer.TokenType.EOF ||\n token1.type == CssTokenizer.TokenType.C_BRC)\n ) {\n tokenizer.consume();\n this.propImportant = true;\n continue;\n }\n this.exprError(\"E_CSS_SYNTAX\", token);\n continue;\n case Action.VAL_PLUS:\n token1 = tokenizer.nthToken(1);\n switch (token1.type) {\n case CssTokenizer.TokenType.NUM:\n case CssTokenizer.TokenType.NUMERIC:\n case CssTokenizer.TokenType.INT:\n if (!token1.precededBySpace) {\n // Plus before number, ignore\n tokenizer.consume();\n continue;\n }\n }\n if (this.actions === actionsPropVal && tokenizer.hasMark()) {\n tokenizer.reset();\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n continue;\n } else {\n this.exprError(\"E_CSS_UNEXPECTED_PLUS\", token);\n continue;\n }\n case Action.VAL_END:\n tokenizer.consume();\n\n // fall through\n case Action.VAL_BRC:\n tokenizer.unmark();\n val = this.valStackReduce(\";\", token);\n if (val && this.propName) {\n handler.property(this.propName as string, val, this.propImportant);\n }\n this.actions = parsingStyleAttr ? actionsStyleAttribute : actionsBase;\n continue;\n case Action.VAL_FINISH:\n tokenizer.consume();\n tokenizer.unmark();\n val = this.valStackReduce(\";\", token);\n if (parsingValue) {\n this.result = val;\n return true;\n }\n if (this.propName && val) {\n handler.property(this.propName as string, val, this.propImportant);\n }\n if (parsingStyleAttr) {\n return true;\n }\n this.exprError(\"E_CSS_SYNTAX\", token);\n continue;\n case Action.EXPR_IDENT:\n token1 = tokenizer.nthToken(1);\n if (token1.type == CssTokenizer.TokenType.CLASS) {\n if (\n tokenizer.nthToken(2).type == CssTokenizer.TokenType.O_PAR &&\n !tokenizer.nthToken(2).precededBySpace\n ) {\n valStack.push(token.text, token1.text, \"(\");\n tokenizer.consume();\n } else {\n valStack.push(\n new Exprs.Named(\n handler.getScope(),\n Exprs.makeQualifiedName(token.text, token1.text),\n ),\n );\n this.actions = actionsExprOp;\n }\n tokenizer.consume();\n } else {\n if (\n this.exprContext == ExprContext.MEDIA ||\n this.exprContext == ExprContext.IMPORT\n ) {\n if (token.text.toLowerCase() == \"not\") {\n tokenizer.consume();\n valStack.push(\n new Exprs.MediaName(handler.getScope(), true, token1.text),\n );\n } else {\n if (token.text.toLowerCase() == \"only\") {\n tokenizer.consume();\n token = token1;\n }\n valStack.push(\n new Exprs.MediaName(handler.getScope(), false, token.text),\n );\n }\n } else {\n valStack.push(new Exprs.Named(handler.getScope(), token.text));\n }\n this.actions = actionsExprOp;\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_FUNC:\n valStack.push(null, token.text, \"(\");\n tokenizer.consume();\n continue;\n case Action.EXPR_NUM:\n valStack.push(new Exprs.Const(handler.getScope(), token.num));\n tokenizer.consume();\n this.actions = actionsExprOp;\n continue;\n case Action.EXPR_NUMERIC:\n text = token.text;\n if (text == \"%\") {\n if (this.propName && this.propName.match(/height|^(top|bottom)$/)) {\n text = \"vh\";\n } else {\n text = \"vw\";\n }\n }\n valStack.push(new Exprs.Numeric(handler.getScope(), token.num, text));\n tokenizer.consume();\n this.actions = actionsExprOp;\n continue;\n case Action.EXPR_STR:\n valStack.push(new Exprs.Const(handler.getScope(), token.text));\n tokenizer.consume();\n this.actions = actionsExprOp;\n continue;\n case Action.EXPR_PARAM:\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type != CssTokenizer.TokenType.INT ||\n token.precededBySpace\n ) {\n this.exprError(\"E_CSS_SYNTAX\", token);\n } else {\n valStack.push(new Exprs.Param(handler.getScope(), token.num));\n tokenizer.consume();\n this.actions = actionsExprOp;\n }\n continue;\n case Action.EXPR_PREFIX:\n valStack.push(-token.type);\n tokenizer.consume();\n continue;\n case Action.EXPR_INFIX:\n this.actions = actionsExprVal;\n this.exprStackReduce(token.type, token);\n valStack.push(token.type);\n tokenizer.consume();\n continue;\n case Action.EXPR_INFIX_NAME:\n if (token.text.toLowerCase() == \"and\") {\n this.actions = actionsExprVal;\n this.exprStackReduce(OP_MEDIA_AND, token);\n valStack.push(OP_MEDIA_AND);\n tokenizer.consume();\n } else {\n this.exprError(\"E_CSS_SYNTAX\", token);\n }\n continue;\n case Action.EXPR_C_PAR:\n if (this.exprStackReduce(token.type, token)) {\n if (this.propName) {\n this.actions = actionsPropVal;\n } else {\n this.exprError(\"E_CSS_UNBALANCED_PAR\", token);\n }\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_O_BRC:\n if (this.exprStackReduce(CssTokenizer.TokenType.C_PAR, token)) {\n if (this.propName || this.exprContext == ExprContext.IMPORT) {\n this.exprError(\"E_CSS_UNEXPECTED_BRC\", token);\n } else {\n if (this.exprContext == ExprContext.WHEN) {\n handler.startWhenRule(valStack.pop() as Css.Expr);\n } else {\n handler.startMediaRule(valStack.pop() as Css.Expr);\n }\n this.ruleStack.push(\"media\");\n handler.startRuleBody();\n this.actions = actionsBase;\n }\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_SEMICOL:\n if (this.exprStackReduce(CssTokenizer.TokenType.C_PAR, token)) {\n if (this.propName || this.exprContext != ExprContext.IMPORT) {\n this.exprError(\"E_CSS_UNEXPECTED_SEMICOL\", token);\n } else {\n this.importCondition = valStack.pop() as Css.Expr;\n this.importReady = true;\n this.actions = actionsBase;\n tokenizer.consume();\n return false;\n }\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_O_PAR:\n valStack.push(token.type);\n tokenizer.consume();\n continue;\n case Action.RULE_END:\n this.actions = actionsBase;\n tokenizer.consume();\n handler.endRule();\n if (this.ruleStack.length) {\n this.ruleStack.pop();\n }\n continue;\n case Action.AT:\n text = token.text.toLowerCase();\n switch (text) {\n case \"import\":\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.STR ||\n token.type == CssTokenizer.TokenType.URL\n ) {\n this.importURL = token.text;\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.SEMICOL ||\n token.type == CssTokenizer.TokenType.EOF\n ) {\n this.importReady = true;\n tokenizer.consume();\n return false;\n } else {\n this.propName = null; // signals @ rule\n this.exprContext = ExprContext.IMPORT;\n this.actions = actionsExprVal;\n valStack.push(\"{\");\n continue;\n }\n }\n handler.error(\"E_CSS_IMPORT_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case \"namespace\":\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n text = token.text; // Prefix\n tokenizer.consume();\n token = tokenizer.token();\n if (\n (token.type == CssTokenizer.TokenType.STR ||\n token.type == CssTokenizer.TokenType.URL) &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.SEMICOL\n ) {\n this.namespacePrefixToURI[text] = token.text;\n tokenizer.consume();\n tokenizer.consume();\n continue;\n }\n break;\n case CssTokenizer.TokenType.STR:\n case CssTokenizer.TokenType.URL:\n if (\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.SEMICOL\n ) {\n this.defaultNamespaceURI = token.text;\n tokenizer.consume();\n tokenizer.consume();\n continue;\n }\n break;\n }\n handler.error(\"E_CSS_NAMESPACE_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case \"charset\":\n // Useless in EPUB (only UTF-8 or UTF-16 is allowed anyway and\n // we are at the mercy of the browser charset handling anyway).\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.STR &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.SEMICOL\n ) {\n text = token.text.toLowerCase();\n if (text != \"utf-8\" && text != \"utf-16\") {\n handler.error(`E_CSS_UNEXPECTED_CHARSET ${text}`, token);\n }\n tokenizer.consume();\n tokenizer.consume();\n continue;\n }\n handler.error(\"E_CSS_CHARSET_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case \"font-face\":\n case \"-epubx-page-template\":\n case \"-epubx-define\":\n case \"-epubx-viewport\":\n if (tokenizer.nthToken(1).type == CssTokenizer.TokenType.O_BRC) {\n tokenizer.consume();\n tokenizer.consume();\n switch (text) {\n case \"font-face\":\n handler.startFontFaceRule();\n break;\n case \"-epubx-page-template\":\n handler.startPageTemplateRule();\n break;\n case \"-epubx-define\":\n handler.startDefineRule();\n break;\n case \"-epubx-viewport\":\n handler.startViewportRule();\n break;\n }\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n case \"-adapt-footnote-area\":\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.O_BRC:\n tokenizer.consume();\n handler.startFootnoteRule(null);\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n case CssTokenizer.TokenType.COL_COL:\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.IDENT &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.O_BRC\n ) {\n text = token.text;\n tokenizer.consume();\n tokenizer.consume();\n handler.startFootnoteRule(text);\n this.ruleStack.push(\"-adapt-footnote-area\");\n handler.startRuleBody();\n continue;\n }\n break;\n }\n break;\n case \"-epubx-region\":\n tokenizer.consume();\n handler.startRegionRule();\n this.regionRule = true;\n this.actions = actionsSelectorStart;\n continue;\n case \"page\":\n tokenizer.consume();\n handler.startPageRule();\n this.pageRule = true;\n this.actions = actionsSelectorCont;\n continue;\n case \"top-left-corner\":\n case \"top-left\":\n case \"top-center\":\n case \"top-right\":\n case \"top-right-corner\":\n case \"right-top\":\n case \"right-middle\":\n case \"right-bottom\":\n case \"bottom-right-corner\":\n case \"bottom-right\":\n case \"bottom-center\":\n case \"bottom-left\":\n case \"bottom-left-corner\":\n case \"left-bottom\":\n case \"left-middle\":\n case \"left-top\":\n tokenizer.consume();\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.O_BRC) {\n tokenizer.consume();\n handler.startPageMarginBoxRule(text);\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n case \"-epubx-when\":\n tokenizer.consume();\n this.propName = null; // signals @ rule\n this.exprContext = ExprContext.WHEN;\n this.actions = actionsExprVal;\n valStack.push(\"{\");\n continue;\n case \"media\":\n tokenizer.consume();\n this.propName = null; // signals @ rule\n this.exprContext = ExprContext.MEDIA;\n this.actions = actionsExprVal;\n valStack.push(\"{\");\n continue;\n case \"-epubx-flow\":\n if (\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.IDENT &&\n tokenizer.nthToken(2).type == CssTokenizer.TokenType.O_BRC\n ) {\n handler.startFlowRule(tokenizer.nthToken(1).text);\n tokenizer.consume();\n tokenizer.consume();\n tokenizer.consume();\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n case \"-epubx-page-master\":\n case \"-epubx-partition\":\n case \"-epubx-partition-group\": {\n tokenizer.consume();\n token = tokenizer.token();\n let ruleName: string | null = null;\n let rulePseudoName: string | null = null;\n const classes: string[] = [];\n if (token.type == CssTokenizer.TokenType.IDENT) {\n ruleName = token.text;\n tokenizer.consume();\n token = tokenizer.token();\n }\n if (\n token.type == CssTokenizer.TokenType.COLON &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.IDENT\n ) {\n rulePseudoName = tokenizer.nthToken(1).text;\n tokenizer.consume();\n tokenizer.consume();\n token = tokenizer.token();\n }\n while (\n token.type == CssTokenizer.TokenType.FUNC &&\n token.text.toLowerCase() == \"class\" &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.IDENT &&\n tokenizer.nthToken(2).type == CssTokenizer.TokenType.C_PAR\n ) {\n classes.push(tokenizer.nthToken(1).text);\n tokenizer.consume();\n tokenizer.consume();\n tokenizer.consume();\n token = tokenizer.token();\n }\n if (token.type == CssTokenizer.TokenType.O_BRC) {\n tokenizer.consume();\n switch (text) {\n case \"-epubx-page-master\":\n handler.startPageMasterRule(\n ruleName,\n rulePseudoName,\n classes,\n );\n break;\n case \"-epubx-partition\":\n handler.startPartitionRule(\n ruleName,\n rulePseudoName,\n classes,\n );\n break;\n case \"-epubx-partition-group\":\n handler.startPartitionGroupRule(\n ruleName,\n rulePseudoName,\n classes,\n );\n break;\n }\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n }\n case \"\":\n // No text after @\n handler.error(`E_CSS_UNEXPECTED_AT${text}`, token);\n\n // Error recovery using selector rules.\n this.actions = actionsErrorSelector;\n continue;\n default:\n handler.error(`E_CSS_AT_UNKNOWN ${text}`, token);\n this.actions = actionsError;\n continue;\n }\n handler.error(`E_CSS_AT_SYNTAX ${text}`, token);\n this.actions = actionsError;\n continue;\n case Action.ERROR_PUSH:\n // Open bracket while skipping error syntax\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n this.errorBrackets.push(token.type + 1);\n\n // Expected closing bracket\n tokenizer.consume();\n continue;\n case Action.ERROR_POP_DECL:\n // Close bracket while skipping error syntax in declaration\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n if (this.errorBrackets.length == 0) {\n this.actions = actionsBase;\n\n // Don't consume closing brace\n continue;\n }\n\n // fall through\n case Action.ERROR_POP:\n // Close bracket while skipping error syntax\n if (\n this.errorBrackets.length > 0 &&\n this.errorBrackets[this.errorBrackets.length - 1] == token.type\n ) {\n this.errorBrackets.pop();\n }\n if (\n this.errorBrackets.length == 0 &&\n token.type == CssTokenizer.TokenType.C_BRC\n ) {\n this.actions = actionsBase;\n }\n tokenizer.consume();\n continue;\n case Action.ERROR_SEMICOL:\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n if (this.errorBrackets.length == 0) {\n this.actions = actionsBase;\n }\n tokenizer.consume();\n continue;\n case Action.DONE:\n if (parsingFunctionParam) {\n tokenizer.consume();\n handler.endFuncWithSelector();\n }\n return true;\n default:\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n if (parsingMediaQuery) {\n if (this.exprStackReduce(CssTokenizer.TokenType.C_PAR, token)) {\n this.result = valStack.pop() as Css.Val;\n return true;\n }\n return false;\n }\n if (parsingFunctionParam) {\n if (token.type == CssTokenizer.TokenType.INVALID) {\n handler.error(token.text, token);\n } else {\n handler.error(\"E_CSS_SYNTAX\", token);\n }\n return false;\n }\n if (this.actions === actionsPropVal && tokenizer.hasMark()) {\n tokenizer.reset();\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n continue;\n }\n if (\n this.actions !== actionsError &&\n this.actions !== actionsErrorSelector &&\n this.actions !== actionsErrorDecl\n ) {\n if (token.type == CssTokenizer.TokenType.INVALID) {\n handler.error(token.text, token);\n } else {\n handler.error(\"E_CSS_SYNTAX\", token);\n }\n if (this.isInsidePropertyOnlyRule()) {\n this.actions = actionsErrorDecl;\n } else {\n this.actions = actionsErrorSelector;\n }\n continue; // Let error-recovery to re-process the offending token\n }\n tokenizer.consume();\n continue;\n }\n }\n return false; // Not done yet.\n }\n}\n\nexport class ErrorHandler extends ParserHandler {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super(null);\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n throw new Error(mnemonics);\n }\n\n /**\n * @override\n */\n getScope(): Exprs.LexicalScope {\n return this.scope;\n }\n}\n\nexport function parseStylesheet(\n tokenizer: CssTokenizer.Tokenizer,\n handler: ParserHandler,\n baseURL: string,\n classes: string | null,\n media: string | null,\n): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\"parseStylesheet\");\n const parser = new Parser(actionsBase, tokenizer, handler, baseURL);\n let condition: Css.Expr = null;\n if (media) {\n condition = parseMediaQuery(\n new CssTokenizer.Tokenizer(media, handler),\n handler,\n baseURL,\n );\n }\n condition = parser.makeCondition(classes, condition && condition.toExpr());\n if (condition) {\n handler.startMediaRule(condition);\n handler.startRuleBody();\n }\n frame\n .loop(() => {\n while (!parser.runParser(100, false, false, false, false)) {\n if (parser.importReady) {\n const resolvedURL = Base.resolveURL(\n parser.importURL as string,\n baseURL,\n );\n if (parser.importCondition) {\n handler.startMediaRule(parser.importCondition);\n handler.startRuleBody();\n }\n const innerFrame: Task.Frame<boolean> = Task.newFrame(\n \"parseStylesheet.import\",\n );\n parseStylesheetFromURL(resolvedURL, handler, null, null).then(() => {\n if (parser.importCondition) {\n handler.endRule();\n }\n parser.importReady = false;\n parser.importURL = null;\n parser.importCondition = null;\n innerFrame.finish(true);\n });\n return innerFrame.result();\n }\n const r = frame.timeSlice();\n if (r.isPending) {\n return r;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n if (condition) {\n handler.endRule();\n }\n frame.finish(true);\n });\n return frame.result();\n}\n\nexport function parseStylesheetFromText(\n text: string,\n handler: ParserHandler,\n baseURL: string,\n classes: string | null,\n media: string | null,\n): Task.Result<boolean> {\n return Task.handle(\n \"parseStylesheetFromText\",\n (frame) => {\n const tok = new CssTokenizer.Tokenizer(text, handler);\n parseStylesheet(tok, handler, baseURL, classes, media).thenFinish(frame);\n },\n (frame, err) => {\n Logging.logger.warn(err, `Failed to parse stylesheet text: ${text}`);\n frame.finish(false);\n },\n );\n}\n\nexport function parseStylesheetFromURL(\n url: string,\n handler: ParserHandler,\n classes: string | null,\n media: string | null,\n): Task.Result<boolean> {\n return Task.handle(\n \"parseStylesheetFromURL\",\n (frame) => {\n Net.ajax(url).then((xhr) => {\n if (!xhr.responseText) {\n frame.finish(true);\n } else {\n parseStylesheetFromText(\n xhr.responseText,\n handler,\n url,\n classes,\n media,\n ).then((result) => {\n if (!result) {\n Logging.logger.warn(`Failed to parse stylesheet from ${url}`);\n }\n frame.finish(true);\n });\n }\n });\n },\n (frame, err) => {\n Logging.logger.warn(err, \"Exception while fetching and parsing:\", url);\n frame.finish(true);\n },\n );\n}\n\nexport function parseValue(\n scope: Exprs.LexicalScope,\n tokenizer: CssTokenizer.Tokenizer,\n baseURL: string,\n): Css.Val {\n const parser = new Parser(\n actionsPropVal,\n tokenizer,\n new ErrorHandler(scope),\n baseURL,\n );\n parser.runParser(Number.POSITIVE_INFINITY, true, false, false, false);\n return parser.result;\n}\n\nexport function parseStyleAttribute(\n tokenizer: CssTokenizer.Tokenizer,\n handler: ParserHandler,\n baseURL: string,\n): void {\n const parser = new Parser(actionsStyleAttribute, tokenizer, handler, baseURL);\n parser.runParser(Number.POSITIVE_INFINITY, false, true, false, false);\n}\n\nexport function parseMediaQuery(\n tokenizer: CssTokenizer.Tokenizer,\n handler: ParserHandler,\n baseURL: string,\n): Css.Expr {\n const parser = new Parser(actionsExprVal, tokenizer, handler, baseURL);\n parser.runParser(Number.POSITIVE_INFINITY, false, false, true, false);\n return parser.result as Css.Expr;\n}\n\nexport const numProp: { [key: string]: boolean } = {\n \"z-index\": true,\n \"column-count\": true,\n \"flow-linger\": true,\n opacity: true,\n page: true,\n \"flow-priority\": true,\n utilization: true,\n};\n\nexport function takesOnlyNum(propName: string): boolean {\n return !!numProp[propName];\n}\n\n/**\n * @return val\n */\nexport function evaluateExprToCSS(\n context: Exprs.Context,\n val: Exprs.Val,\n propName: string,\n): Css.Val {\n const result = val.evaluate(context);\n switch (typeof result) {\n case \"number\":\n if (!takesOnlyNum(propName)) {\n return new Css.Numeric(result as number, \"px\");\n } else if (result == Math.round(result as number)) {\n return new Css.Int(result as number);\n } else {\n return new Css.Num(result as number);\n }\n case \"string\":\n if (!result) {\n return Css.empty;\n }\n\n // TODO: where baseURL should come from???\n return parseValue(\n val.scope,\n new CssTokenizer.Tokenizer(result as string, null),\n \"\",\n );\n case \"boolean\":\n return result ? Css.ident._true : Css.ident._false;\n case \"undefined\":\n return Css.empty;\n }\n throw new Error(\"E_UNEXPECTED\");\n}\n\n/**\n * @return val\n */\nexport function evaluateCSSToCSS(\n context: Exprs.Context,\n val: Css.Val,\n propName: string,\n): Css.Val {\n if (val.isExpr()) {\n return evaluateExprToCSS(context, (val as Css.Expr).expr, propName);\n }\n return val;\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Matchers - Definitions of Matcher.\n */\nimport * as Asserts from \"./asserts\";\n\n/**\n * Checkes whether given order can be represented as an+b with a non-negative\n * interger n\n */\nexport function matchANPlusB(order: number, a: number, b: number): boolean {\n order -= b;\n if (a === 0) {\n return order === 0;\n } else {\n return order % a === 0 && order / a >= 0;\n }\n}\n\nexport interface Matcher {\n matches(): boolean;\n}\n\nexport class AnyMatcher implements Matcher {\n constructor(public readonly matchers: Matcher[]) {}\n\n /** @override */\n matches(): boolean {\n return this.matchers.some((matcher) => matcher.matches());\n }\n}\n\nexport class AllMatcher implements Matcher {\n constructor(public readonly matchers: Matcher[]) {}\n\n /** @override */\n matches(): boolean {\n return this.matchers.every((matcher) => matcher.matches());\n }\n}\n\nexport class NthFragmentMatcher implements Matcher {\n static fragmentIndices = {};\n\n static registerFragmentIndex(\n elementOffset: number,\n fragmentIndex: number,\n priority: number,\n ) {\n const indices = NthFragmentMatcher.fragmentIndices;\n if (\n !indices[elementOffset] ||\n indices[elementOffset].priority <= priority\n ) {\n indices[elementOffset] = { fragmentIndex, priority };\n }\n }\n\n static clearFragmentIndices() {\n NthFragmentMatcher.fragmentIndices = {};\n }\n\n constructor(\n public readonly elementOffset: number,\n public readonly a: number,\n public readonly b: number,\n ) {}\n\n /** @override */\n matches(): boolean {\n const entry = NthFragmentMatcher.fragmentIndices[this.elementOffset];\n return (\n entry != null &&\n entry.fragmentIndex != null &&\n matchANPlusB(entry.fragmentIndex, this.a, this.b)\n );\n }\n}\n\nexport class MatcherBuilder {\n static buildViewConditionMatcher(\n elementOffset: number,\n viewCondition: string,\n ): Matcher {\n const strs = viewCondition.split(\"_\");\n if (strs[0] == \"NFS\") {\n return new NthFragmentMatcher(\n elementOffset,\n parseInt(strs[1], 10),\n parseInt(strs[2], 10),\n );\n } else {\n Asserts.fail(`unknown view condition. condition=${viewCondition}`);\n return null;\n }\n }\n\n static buildAllMatcher(matchers: Matcher[]): Matcher {\n return new AllMatcher(matchers);\n }\n\n static buildAnyMatcher(matchers: Matcher[]): Matcher {\n return new AnyMatcher(matchers);\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssCascade - CSS Cascade.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Logging from \"./logging\";\nimport * as Matchers from \"./matchers\";\nimport * as Plugin from \"./plugin\";\nimport * as Vtree from \"./vtree\";\nimport { CssCascade } from \"./types\";\n\nexport interface ElementStyle extends CssCascade.ElementStyle {}\n\nexport const inheritedProps = {\n azimuth: true,\n \"border-collapse\": true,\n \"border-spacing\": true,\n \"caption-side\": true,\n \"clip-rule\": true,\n color: true,\n \"color-interpolation\": true,\n \"color-rendering\": true,\n cursor: true,\n direction: true,\n elevation: true,\n \"empty-cells\": true,\n fill: true,\n \"fill-opacity\": true,\n \"fill-rule\": true,\n \"font-kerning\": true,\n \"font-size\": true,\n \"font-size-adjust\": true,\n \"font-family\": true,\n \"font-feature-settings\": true,\n \"font-style\": true,\n \"font-stretch\": true,\n \"font-variant\": true,\n \"font-weight\": true,\n \"glyph-orientation-vertical\": true,\n hyphens: true,\n \"hyphenate-character\": true,\n \"hyphenate-limit-chars\": true,\n \"hyphenate-limit-last\": true,\n \"image-rendering\": true,\n \"image-resolution\": true,\n \"letter-spacing\": true,\n \"line-break\": true,\n \"line-height\": true,\n \"list-style-image\": true,\n \"list-style-position\": true,\n \"list-style-type\": true,\n marker: true,\n \"marker-end\": true,\n \"marker-mid\": true,\n \"marker-start\": true,\n orphans: true,\n \"overflow-wrap\": true,\n \"paint-order\": true,\n \"pointer-events\": true,\n \"pitch-range\": true,\n quotes: true,\n richness: true,\n \"ruby-align\": true,\n \"ruby-position\": true,\n \"speak-header\": true,\n \"speak-numeral\": true,\n \"speak-punctuation\": true,\n \"speech-rate\": true,\n \"shape-rendering\": true,\n stress: true,\n stroke: true,\n \"stroke-dasharray\": true,\n \"stroke-dashoffset\": true,\n \"stroke-linecap\": true,\n \"stroke-linejoin\": true,\n \"stroke-miterlimit\": true,\n \"stroke-opacity\": true,\n \"stroke-width\": true,\n \"tab-size\": true,\n \"text-align\": true,\n \"text-align-last\": true,\n \"text-anchor\": true,\n \"text-decoration-skip\": true,\n \"text-emphasis-color\": true,\n \"text-emphasis-position\": true,\n \"text-emphasis-style\": true,\n \"text-combine-upright\": true,\n \"text-indent\": true,\n \"text-justify\": true,\n \"text-rendering\": true,\n \"text-size-adjust\": true,\n \"text-transform\": true,\n \"text-underline-position\": true,\n visibility: true,\n \"voice-family\": true,\n volume: true,\n \"white-space\": true,\n widows: true,\n \"word-break\": true,\n \"word-spacing\": true,\n \"word-wrap\": true,\n \"writing-mode\": true,\n};\n\nexport const polyfilledInheritedProps = [\n \"box-decoration-break\",\n // TODO: box-decoration-block should not be inherited.\n // https://github.com/vivliostyle/vivliostyle.js/issues/259\n \"image-resolution\",\n \"orphans\",\n \"widows\",\n];\n\nexport function getPolyfilledInheritedProps(): string[] {\n const hooks: Plugin.PolyfilledInheritedPropsHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.POLYFILLED_INHERITED_PROPS,\n );\n return hooks.reduce(\n (props, f) => props.concat(f()),\n [].concat(polyfilledInheritedProps),\n );\n}\n\nexport const supportedNamespaces = {\n \"http://www.idpf.org/2007/ops\": true,\n \"http://www.w3.org/1999/xhtml\": true,\n \"http://www.w3.org/2000/svg\": true,\n};\n\nexport const coupledPatterns = [\n \"margin-%\",\n \"padding-%\",\n \"border-%-width\",\n \"border-%-style\",\n \"border-%-color\",\n \"%\",\n];\n\nexport const coupledExtentPatterns = [\"max-%\", \"min-%\", \"%\"];\n\nexport const geomNames: { [key: string]: boolean } = (() => {\n const sides = [\"left\", \"right\", \"top\", \"bottom\"];\n const names = {\n width: true,\n height: true,\n \"max-width\": true,\n \"max-height\": true,\n \"min-width\": true,\n \"min-height\": true,\n };\n for (let i = 0; i < coupledPatterns.length; i++) {\n for (let k = 0; k < sides.length; k++) {\n const name = coupledPatterns[i].replace(\"%\", sides[k]);\n names[name] = true;\n }\n }\n return names;\n})();\n\nexport function buildCouplingMap(\n sideMap: { [key: string]: string },\n extentMap: { [key: string]: string },\n): { [key: string]: string } {\n const map = {};\n for (const pattern of coupledPatterns) {\n for (const side in sideMap) {\n const name1 = pattern.replace(\"%\", side);\n const name2 = pattern.replace(\"%\", sideMap[side]);\n map[name1] = name2;\n map[name2] = name1;\n }\n }\n for (const extentPattern of coupledExtentPatterns) {\n for (const extent in extentMap) {\n const name1 = extentPattern.replace(\"%\", extent);\n const name2 = extentPattern.replace(\"%\", extentMap[extent]);\n map[name1] = name2;\n map[name2] = name1;\n }\n }\n return map;\n}\n\nexport const couplingMapVert = buildCouplingMap(\n {\n \"block-start\": \"right\",\n \"block-end\": \"left\",\n \"inline-start\": \"top\",\n \"inline-end\": \"bottom\",\n },\n { \"block-size\": \"width\", \"inline-size\": \"height\" },\n);\n\nexport const couplingMapHor = buildCouplingMap(\n {\n \"block-start\": \"top\",\n \"block-end\": \"bottom\",\n \"inline-start\": \"left\",\n \"inline-end\": \"right\",\n },\n { \"block-size\": \"height\", \"inline-size\": \"width\" },\n);\n\nexport const couplingMapVertRtl = buildCouplingMap(\n {\n \"block-start\": \"right\",\n \"block-end\": \"left\",\n \"inline-start\": \"bottom\",\n \"inline-end\": \"top\",\n },\n { \"block-size\": \"width\", \"inline-size\": \"height\" },\n);\n\nexport const couplingMapHorRtl = buildCouplingMap(\n {\n \"block-start\": \"top\",\n \"block-end\": \"bottom\",\n \"inline-start\": \"right\",\n \"inline-end\": \"left\",\n },\n { \"block-size\": \"height\", \"inline-size\": \"width\" },\n);\n\nexport class CascadeValue {\n constructor(\n public readonly value: Css.Val,\n public readonly priority: number,\n ) {}\n\n getBaseValue(): CascadeValue {\n return this;\n }\n\n filterValue(visitor: Css.Visitor): CascadeValue {\n const value = this.value.visit(visitor);\n if (value === this.value) {\n return this;\n }\n return new CascadeValue(value, this.priority);\n }\n\n increaseSpecificity(specificity: number): CascadeValue {\n if (specificity == 0) {\n return this;\n }\n return new CascadeValue(this.value, this.priority + specificity);\n }\n\n evaluate(context: Exprs.Context, propName: string): Css.Val {\n return CssParser.evaluateCSSToCSS(context, this.value, propName);\n }\n\n isEnabled(context: Exprs.Context): boolean {\n return true;\n }\n}\n\n/**\n * Internal subclass of CascadeValue. Should never be seen outside of the\n * cascade engine.\n */\nexport class ConditionalCascadeValue extends CascadeValue {\n constructor(\n value: Css.Val,\n priority: number,\n public readonly condition: Exprs.Val,\n ) {\n super(value, priority);\n }\n\n /**\n * @override\n */\n getBaseValue(): CascadeValue {\n return new CascadeValue(this.value, this.priority);\n }\n\n /**\n * @override\n */\n filterValue(visitor: Css.Visitor): CascadeValue {\n const value = this.value.visit(visitor);\n if (value === this.value) {\n return this;\n }\n return new ConditionalCascadeValue(value, this.priority, this.condition);\n }\n\n /**\n * @override\n */\n increaseSpecificity(specificity: number): CascadeValue {\n if (specificity == 0) {\n return this;\n }\n return new ConditionalCascadeValue(\n this.value,\n this.priority + specificity,\n this.condition,\n );\n }\n\n isEnabled(context: Exprs.Context): boolean {\n return !!this.condition.evaluate(context);\n }\n}\n\n/**\n * @param tv current value (cannot be conditional)\n * @param av cascaded value (can be conditional)\n */\nexport function cascadeValues(\n context: Exprs.Context,\n tv: CascadeValue,\n av: CascadeValue,\n): CascadeValue {\n if ((tv == null || av.priority > tv.priority) && av.isEnabled(context)) {\n return av.getBaseValue();\n }\n return tv;\n}\n\nexport type ElementStyleMap = {\n [key: string]: ElementStyle;\n};\n\nexport const SPECIALS = {\n \"region-id\": true,\n \"fragment-selector-id\": true,\n};\n\nexport function isSpecialName(name: string): boolean {\n return !!SPECIALS[name];\n}\n\nexport function isMapName(name: string): boolean {\n return name.charAt(0) == \"_\";\n}\n\nexport function isPropName(name: string): boolean {\n return name.charAt(0) != \"_\" && !SPECIALS[name];\n}\n\nexport function isInherited(name: string): boolean {\n return !!inheritedProps[name];\n}\n\nexport function getProp(style: ElementStyle, name: string): CascadeValue {\n return style[name] as CascadeValue;\n}\n\n/**\n * @return void\n */\nexport function setProp(\n style: ElementStyle,\n name: string,\n value: CascadeValue,\n): any {\n if (!value) {\n delete style[name];\n } else {\n style[name] = value;\n }\n}\n\nexport function getStyleMap(\n style: ElementStyle,\n name: string,\n): ElementStyleMap {\n return style[name] as ElementStyleMap;\n}\n\nexport function getMutableStyleMap(\n style: ElementStyle,\n name: string,\n): ElementStyleMap {\n let r = style[name] as ElementStyleMap;\n if (!r) {\n r = {};\n style[name] = r;\n }\n return r;\n}\n\nexport const getViewConditionalStyleMap = (\n style: ElementStyle,\n): { matcher: Matchers.Matcher; styles: ElementStyleMap }[] => {\n let r = style[\"_viewConditionalStyles\"] as {\n matcher: Matchers.Matcher;\n styles: ElementStyleMap;\n }[];\n if (!r) {\n r = [];\n style[\"_viewConditionalStyles\"] = r;\n }\n return r;\n};\n\nexport function getSpecial(style: ElementStyle, name: string): CascadeValue[] {\n return style[name] as CascadeValue[];\n}\n\nexport function getMutableSpecial(\n style: ElementStyle,\n name: string,\n): CascadeValue[] {\n let r = style[name] as CascadeValue[];\n if (!r) {\n r = [];\n style[name] = r;\n }\n return r;\n}\n\nexport function mergeIn(\n context: Exprs.Context,\n target: ElementStyle,\n style: ElementStyle,\n specificity: number,\n pseudoelement: string | null,\n regionId: string | null,\n viewConditionMatcher: Matchers.Matcher | null,\n): void {\n const hierarchy = [\n { id: pseudoelement, styleKey: \"_pseudos\" },\n { id: regionId, styleKey: \"_regions\" },\n ];\n hierarchy.forEach((item) => {\n if (item.id) {\n const styleMap = getMutableStyleMap(target, item.styleKey);\n target = styleMap[item.id];\n if (!target) {\n target = {} as ElementStyle;\n styleMap[item.id] = target;\n }\n }\n });\n if (viewConditionMatcher) {\n const styleMap = getViewConditionalStyleMap(target);\n target = {} as ElementStyle;\n styleMap.push({\n styles: target as ElementStyleMap,\n matcher: viewConditionMatcher,\n });\n }\n for (const prop in style) {\n if (isMapName(prop)) {\n continue;\n }\n if (isSpecialName(prop)) {\n // special properties: list of all assigned values\n const as = getSpecial(style, prop);\n const ts = getMutableSpecial(target, prop);\n Array.prototype.push.apply(ts, as);\n } else {\n // regular properties: higher priority wins\n const av = getProp(style, prop).increaseSpecificity(specificity);\n const tv = getProp(target, prop);\n setProp(target, prop, cascadeValues(context, tv, av));\n }\n }\n}\n\nexport function mergeAll(\n context: Exprs.Context,\n styles: ElementStyle[],\n): ElementStyle {\n const target = {} as ElementStyle;\n for (let k = 0; k < styles.length; k++) {\n mergeIn(context, target, styles[k], 0, null, null, null);\n }\n return target;\n}\n\nexport function chainActions(\n chain: ChainedAction[],\n action: CascadeAction,\n): CascadeAction {\n if (chain.length > 0) {\n chain.sort((a, b) => b.getPriority() - a.getPriority());\n let chained: ChainedAction | null = null;\n for (let i = chain.length - 1; i >= 0; i--) {\n chained = chain[i];\n chained.chained = action;\n action = chained;\n }\n return chained;\n }\n return action;\n}\n\nexport class InheritanceVisitor extends Css.FilterVisitor {\n propName: string = \"\";\n\n constructor(\n public readonly props: ElementStyle,\n public readonly context: Exprs.Context,\n ) {\n super();\n }\n\n setPropName(name: string): void {\n this.propName = name;\n }\n\n private getFontSize() {\n const cascval = getProp(this.props, \"font-size\");\n const n = cascval.value as Css.Numeric;\n if (!Exprs.isAbsoluteLengthUnit(n.unit)) {\n throw new Error(\"Unexpected state\");\n }\n return n.num * Exprs.defaultUnitSizes[n.unit];\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n Asserts.assert(this.context);\n if (this.propName === \"font-size\") {\n return convertFontSizeToPx(numeric, this.getFontSize(), this.context);\n } else if (\n numeric.unit == \"em\" ||\n numeric.unit == \"ex\" ||\n numeric.unit == \"rem\"\n ) {\n return convertFontRelativeLengthToPx(\n numeric,\n this.getFontSize(),\n this.context,\n );\n } else if (numeric.unit == \"%\") {\n if (this.propName === \"line-height\") {\n return numeric;\n }\n const unit = this.propName.match(/height|^(top|bottom)$/) ? \"vh\" : \"vw\";\n return new Css.Numeric(numeric.num, unit);\n }\n return numeric;\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n if (this.propName == \"font-size\") {\n const val = CssParser.evaluateCSSToCSS(this.context, expr, this.propName);\n return val.visit(this);\n }\n return expr;\n }\n}\n\nexport function convertFontRelativeLengthToPx(\n numeric: Css.Numeric,\n baseFontSize: number,\n context: Exprs.Context,\n): Css.Numeric {\n const unit = numeric.unit;\n const num = numeric.num;\n if (unit === \"em\" || unit === \"ex\") {\n const ratio = Exprs.defaultUnitSizes[unit] / Exprs.defaultUnitSizes[\"em\"];\n return new Css.Numeric(num * ratio * baseFontSize, \"px\");\n } else if (unit === \"rem\") {\n return new Css.Numeric(num * context.fontSize(), \"px\");\n } else {\n return numeric;\n }\n}\n\nexport function convertFontSizeToPx(\n numeric: Css.Numeric,\n parentFontSize: number,\n context: Exprs.Context,\n): Css.Numeric {\n numeric = convertFontRelativeLengthToPx(numeric, parentFontSize, context);\n const unit = numeric.unit;\n const num = numeric.num;\n if (unit === \"px\") {\n return numeric;\n } else if (unit === \"%\") {\n return new Css.Numeric((num / 100) * parentFontSize, \"px\");\n } else {\n return new Css.Numeric(num * context.queryUnitSize(unit, false), \"px\");\n }\n}\n\nexport type ActionTable = {\n [key: string]: CascadeAction;\n};\n\nexport class CascadeAction {\n apply(cascadeInstance: CascadeInstance): void {}\n\n mergeWith(other: CascadeAction): CascadeAction {\n return new CompoundAction([this, other]);\n }\n\n clone(): CascadeAction {\n // Mutable actions will override\n return this;\n }\n}\n\nexport class ConditionItemAction extends CascadeAction {\n constructor(public readonly conditionItem: ConditionItem) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n cascadeInstance.pushConditionItem(\n this.conditionItem.fresh(cascadeInstance),\n );\n }\n}\n\nexport class CompoundAction extends CascadeAction {\n constructor(public readonly list: CascadeAction[]) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n for (let i = 0; i < this.list.length; i++) {\n this.list[i].apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n mergeWith(other: CascadeAction): CascadeAction {\n this.list.push(other);\n return this;\n }\n\n /**\n * @override\n */\n clone(): CascadeAction {\n return new CompoundAction([].concat(this.list));\n }\n}\n\nexport class ApplyRuleAction extends CascadeAction {\n constructor(\n public readonly style: ElementStyle,\n public readonly specificity: number,\n public readonly pseudoelement: string | null,\n public readonly regionId: string | null,\n public readonly viewConditionId: string | null,\n ) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n mergeIn(\n cascadeInstance.context,\n cascadeInstance.currentStyle,\n this.style,\n this.specificity,\n this.pseudoelement,\n this.regionId,\n cascadeInstance.buildViewConditionMatcher(this.viewConditionId),\n );\n }\n}\n\nexport class ChainedAction extends CascadeAction {\n chained: CascadeAction = null;\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n this.chained.apply(cascadeInstance);\n }\n\n getPriority(): number {\n return 0;\n }\n\n makePrimary(cascade: Cascade): boolean {\n // cannot be made primary\n return false;\n }\n}\n\nexport class CheckClassAction extends ChainedAction {\n constructor(public readonly className: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentClassNames.includes(this.className)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 10;\n }\n // class should be checked after id\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.classes, this.className, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckIdAction extends ChainedAction {\n constructor(public readonly id: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentId == this.id ||\n cascadeInstance.currentXmlId == this.id\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 11;\n }\n // id should be checked after :root\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.ids, this.id, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckLocalNameAction extends ChainedAction {\n constructor(public readonly localName: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentLocalName == this.localName) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 8;\n }\n // tag is a pretty good thing to check, after epub:type\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.tags, this.localName, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckNSTagAction extends ChainedAction {\n constructor(public readonly ns: string, public readonly localName: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentLocalName == this.localName &&\n cascadeInstance.currentNamespace == this.ns\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 8;\n }\n // tag is a pretty good thing to check, after epub:type\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n let prefix = cascade.nsPrefix[this.ns];\n if (!prefix) {\n prefix = `ns${cascade.nsCount++}:`;\n cascade.nsPrefix[this.ns] = prefix;\n }\n const nsTag = prefix + this.localName;\n cascade.insertInTable(cascade.nstags, nsTag, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckTargetEpubTypeAction extends ChainedAction {\n constructor(public readonly epubTypePatt: RegExp) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if (elem && cascadeInstance.currentLocalName == \"a\") {\n const href = elem.getAttribute(\"href\");\n if (href && href.match(/^#/)) {\n const id = href.substring(1);\n const target = elem.ownerDocument.getElementById(id);\n if (target) {\n const epubType = target.getAttributeNS(Base.NS.epub, \"type\");\n if (epubType && epubType.match(this.epubTypePatt)) {\n this.chained.apply(cascadeInstance);\n }\n }\n }\n }\n }\n}\n\nexport class CheckNamespaceAction extends ChainedAction {\n constructor(public readonly ns: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentNamespace == this.ns) {\n this.chained.apply(cascadeInstance);\n }\n }\n}\n\nexport class CheckAttributePresentAction extends ChainedAction {\n constructor(public readonly ns: string, public readonly name: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentElement &&\n cascadeInstance.currentElement.hasAttributeNS(this.ns, this.name)\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n}\n\nexport class CheckAttributeEqAction extends ChainedAction {\n constructor(\n public readonly ns: string,\n public readonly name: string,\n public readonly value: string,\n ) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentElement &&\n cascadeInstance.currentElement.getAttributeNS(this.ns, this.name) ==\n this.value\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n if (this.name == \"type\" && this.ns == Base.NS.epub) {\n return 9; // epub:type is a pretty good thing to check\n }\n return 0;\n }\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.name == \"type\" && this.ns == Base.NS.epub) {\n if (this.chained) {\n cascade.insertInTable(cascade.epubtypes, this.value, this.chained);\n }\n return true;\n }\n return false;\n }\n}\n\nexport class CheckNamespaceSupportedAction extends ChainedAction {\n constructor(public readonly ns: string, public readonly name: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentElement) {\n const ns = cascadeInstance.currentElement.getAttributeNS(\n this.ns,\n this.name,\n );\n if (ns && supportedNamespaces[ns]) {\n this.chained.apply(cascadeInstance);\n }\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 0;\n }\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n return false;\n }\n}\n\nexport class CheckAttributeRegExpAction extends ChainedAction {\n constructor(\n public readonly ns: string,\n public readonly name: string,\n public readonly regexp: RegExp,\n ) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentElement) {\n const attr = cascadeInstance.currentElement.getAttributeNS(\n this.ns,\n this.name,\n );\n if (attr && attr.match(this.regexp)) {\n this.chained.apply(cascadeInstance);\n }\n }\n }\n}\n\nexport class CheckLangAction extends ChainedAction {\n constructor(public readonly langRegExp: RegExp) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.lang.match(this.langRegExp)) {\n this.chained.apply(cascadeInstance);\n }\n }\n}\n\nexport class IsFirstAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.isFirst) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 6;\n }\n}\n\nexport class IsRootAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.isRoot) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 12; // :root is the first thing to check\n }\n}\n\nexport class IsNthAction extends ChainedAction {\n constructor(public readonly a: number, public readonly b: number) {\n super();\n }\n\n /**\n * Checkes whether given order can be represented as an+b with a non-negative\n * interger n\n */\n protected matchANPlusB(order: number): boolean {\n return Matchers.matchANPlusB(order, this.a, this.b);\n }\n}\n\nexport class IsNthSiblingAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (this.matchANPlusB(cascadeInstance.currentSiblingOrder)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsNthSiblingOfTypeAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const order =\n cascadeInstance.currentSiblingTypeCounts[\n cascadeInstance.currentNamespace\n ][cascadeInstance.currentLocalName];\n if (this.matchANPlusB(order)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsNthLastSiblingAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n let order = cascadeInstance.currentFollowingSiblingOrder;\n if (order === null) {\n order = cascadeInstance.currentFollowingSiblingOrder =\n cascadeInstance.currentElement.parentNode.childElementCount -\n cascadeInstance.currentSiblingOrder +\n 1;\n }\n if (this.matchANPlusB(order)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class IsNthLastSiblingOfTypeAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const counts = cascadeInstance.currentFollowingSiblingTypeCounts;\n if (!counts[cascadeInstance.currentNamespace]) {\n let elem = cascadeInstance.currentElement;\n do {\n const ns = elem.namespaceURI;\n const localName = elem.localName;\n let nsCounts = counts[ns];\n if (!nsCounts) {\n nsCounts = counts[ns] = {};\n }\n nsCounts[localName] = (nsCounts[localName] || 0) + 1;\n } while ((elem = elem.nextElementSibling));\n }\n if (\n this.matchANPlusB(\n counts[cascadeInstance.currentNamespace][\n cascadeInstance.currentLocalName\n ],\n )\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class IsEmptyAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n let node: Node | null = cascadeInstance.currentElement.firstChild;\n while (node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n return;\n case Node.TEXT_NODE:\n if ((node as Text).length > 0) {\n return;\n }\n }\n node = node.nextSibling;\n }\n this.chained.apply(cascadeInstance);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class IsEnabledAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if ((elem as any).disabled === false) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsDisabledAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if ((elem as any).disabled === true) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsCheckedAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if ((elem as any).selected === true || (elem as any).checked === true) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class CheckConditionAction extends ChainedAction {\n constructor(public readonly condition: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.conditions[this.condition]) {\n try {\n cascadeInstance.dependentConditions.push(this.condition);\n this.chained.apply(cascadeInstance);\n } finally {\n cascadeInstance.dependentConditions.pop();\n }\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class CheckAppliedAction extends CascadeAction {\n applied = false;\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n this.applied = true;\n }\n\n /**\n * @override\n */\n clone(): CascadeAction {\n const cloned = new CheckAppliedAction();\n cloned.applied = this.applied;\n return cloned;\n }\n}\n\nexport class NegateActionsSet extends ChainedAction {\n checkAppliedAction: CheckAppliedAction;\n firstAction: CascadeAction;\n\n constructor(list: ChainedAction[]) {\n super();\n this.checkAppliedAction = new CheckAppliedAction();\n this.firstAction = chainActions(list, this.checkAppliedAction);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n this.firstAction.apply(cascadeInstance);\n if (!this.checkAppliedAction.applied) {\n this.chained.apply(cascadeInstance);\n }\n this.checkAppliedAction.applied = false;\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return (this.firstAction as ChainedAction).getPriority();\n }\n}\n\n/**\n * An object that is notified as elements are pushed and popped and typically\n * controls a \"named condition\" (which is a count associated with a name).\n */\nexport interface ConditionItem {\n /**\n * Returns a \"fresh\" copy of this item. May be this if immutable.\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem;\n\n /**\n * Depth is 0 for element itself and its siblings, 1 for direct children and\n * -1 for the parent.\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean;\n\n /**\n * @return return true if no more notifications are desired\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean;\n}\n\nexport class AbstractConditionItem {\n constructor(\n public readonly condition: string,\n public readonly viewConditionId: string | null,\n public readonly viewCondition: Matchers.Matcher,\n ) {}\n\n increment(cascadeInstance: CascadeInstance) {\n cascadeInstance.increment(this.condition, this.viewCondition);\n }\n\n decrement(cascadeInstance: CascadeInstance) {\n cascadeInstance.decrement(this.condition, this.viewCondition);\n }\n\n buildViewConditionMatcher(\n cascadeInstance: CascadeInstance,\n ): Matchers.Matcher {\n return cascadeInstance.buildViewConditionMatcher(this.viewConditionId);\n }\n}\n\nexport class DescendantConditionItem extends AbstractConditionItem\n implements ConditionItem {\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new DescendantConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.increment(cascadeInstance);\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.decrement(cascadeInstance);\n return true;\n }\n return false;\n }\n}\n\nexport class ChildConditionItem extends AbstractConditionItem\n implements ConditionItem {\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new ChildConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.increment(cascadeInstance);\n } else if (depth == 1) {\n this.decrement(cascadeInstance);\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.decrement(cascadeInstance);\n return true;\n } else if (depth == 1) {\n this.increment(cascadeInstance);\n }\n return false;\n }\n}\n\nexport class AdjacentSiblingConditionItem extends AbstractConditionItem\n implements ConditionItem {\n fired: boolean = false;\n\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new AdjacentSiblingConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n this.decrement(cascadeInstance);\n return true;\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n this.decrement(cascadeInstance);\n return true;\n }\n if (depth == 0) {\n // Leaving element that triggered this item.\n this.fired = true;\n this.increment(cascadeInstance);\n }\n return false;\n }\n}\n\nexport class FollowingSiblingConditionItem extends AbstractConditionItem\n implements ConditionItem {\n fired: boolean = false;\n\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new FollowingSiblingConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n if (depth == -1) {\n this.increment(cascadeInstance);\n } else if (depth == 0) {\n this.decrement(cascadeInstance);\n }\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n if (depth == -1) {\n this.decrement(cascadeInstance);\n return true;\n } else if (depth == 0) {\n this.increment(cascadeInstance);\n }\n } else {\n if (depth == 0) {\n // Leaving element that triggered this item.\n this.fired = true;\n this.increment(cascadeInstance);\n }\n }\n return false;\n }\n}\n\n/**\n * Not a true condition item, this class manages proper handling of \"after\"\n * pseudoelement.\n */\nexport class AfterPseudoelementItem implements ConditionItem {\n constructor(\n public readonly afterprop: ElementStyle,\n public readonly element: Element,\n ) {}\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return this;\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n cascadeInstance.processPseudoelementProps(this.afterprop, this.element);\n return true;\n }\n return false;\n }\n}\n\n/**\n * Not a true condition item, this class restores current language.\n */\nexport class RestoreLangItem implements ConditionItem {\n constructor(public readonly lang: string) {}\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return this;\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n cascadeInstance.lang = this.lang;\n return true;\n }\n return false;\n }\n}\n\n/**\n * Not a true condition item, this class manages inheritance of quotes property\n */\nexport class QuotesScopeItem implements ConditionItem {\n constructor(public readonly oldQuotes: Css.Str[]) {}\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return this;\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n cascadeInstance.quotes = this.oldQuotes;\n return true;\n }\n return false;\n }\n}\nexport type CounterValues = {\n [key: string]: number[];\n};\n\nexport interface CounterListener {\n countersOfId(id: string, counters: CounterValues);\n\n getExprContentListener(): Vtree.ExprContentListener;\n}\n\nexport interface CounterResolver {\n /**\n * Returns an Exprs.Val, whose value is calculated at the layout time by\n * retrieving the innermost page-based counter (null if it does not exist) by\n * its name and formatting the value into a string.\n * @param name Name of the page-based counter to be retrieved\n * @param format A function that formats the counter value into a string\n */\n getPageCounterVal(\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val;\n\n /**\n * Returns an Exprs.Val, whose value is calculated at the layout time by\n * retrieving the page-based counters by its name and formatting the values\n * into a string.\n * @param name Name of the page-based counters to be retrieved\n * @param format A function that formats the counter values (passed as an\n * array ordered by the nesting depth with the outermost counter first and\n * the innermost last) into a string\n */\n getPageCountersVal(name: string, format: (p1: number[]) => string): Exprs.Val;\n\n getTargetCounterVal(\n url: string,\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val;\n\n getTargetCountersVal(\n url: string,\n name: string,\n format: (p1: number[]) => string,\n ): Exprs.Val;\n\n setStyler(styler: any);\n}\n\nexport class AttrValueFilterVisitor extends Css.FilterVisitor {\n constructor(public element: Element) {\n super();\n }\n\n private createValueFromString(str: string | null, type: string): Css.Val {\n switch (type) {\n case \"url\":\n if (str) {\n return new Css.URL(str); // TODO should convert to absolute path\n }\n return new Css.URL(\"about:invalid\");\n case \"string\":\n default:\n if (str) {\n return new Css.Str(str);\n }\n return new Css.Str(\"\");\n }\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n if (func.name !== \"attr\") {\n return super.visitFunc(func);\n }\n let type = \"string\";\n let attributeName: string | null = null;\n let defaultValue: Css.Val = null;\n if (func.values[0] instanceof Css.SpaceList) {\n const values = (func.values[0] as Css.SpaceList).values;\n if (values.length >= 2) {\n type = values[1].stringValue();\n }\n attributeName = values[0].stringValue();\n } else {\n attributeName = func.values[0].stringValue();\n }\n if (func.values.length > 1) {\n defaultValue = this.createValueFromString(\n func.values[1].stringValue(),\n type,\n );\n } else {\n defaultValue = this.createValueFromString(null, type);\n }\n if (this.element && this.element.hasAttribute(attributeName)) {\n return this.createValueFromString(\n this.element.getAttribute(attributeName),\n type,\n );\n }\n return defaultValue;\n }\n}\n\nexport class ContentPropVisitor extends Css.FilterVisitor {\n constructor(\n public cascade: CascadeInstance,\n public element: Element,\n public readonly counterResolver: CounterResolver,\n ) {\n super();\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n const cascade = this.cascade;\n const quotes = cascade.quotes;\n const maxDepth = Math.floor(quotes.length / 2) - 1;\n switch (ident.name) {\n case \"open-quote\": {\n const result = quotes[2 * Math.min(maxDepth, cascade.quoteDepth)];\n cascade.quoteDepth++;\n return result;\n }\n case \"close-quote\":\n if (cascade.quoteDepth > 0) {\n cascade.quoteDepth--;\n }\n return quotes[2 * Math.min(maxDepth, cascade.quoteDepth) + 1];\n case \"no-open-quote\":\n cascade.quoteDepth++;\n return new Css.Str(\"\");\n case \"no-close-quote\":\n if (cascade.quoteDepth > 0) {\n cascade.quoteDepth--;\n }\n return new Css.Str(\"\");\n }\n return ident;\n }\n\n private format(num: number, type: string): string {\n let upper = false; // type == \"armenian\";\n // content-counter-10.xht assumes armenian is uppercase, enable if desired\n\n let lower = false;\n let r: RegExpMatchArray;\n if ((r = type.match(/^upper-(.*)/)) != null) {\n upper = true;\n type = r[1];\n } else if ((r = type.match(/^lower-(.*)/)) != null) {\n lower = true;\n type = r[1];\n }\n let result = \"\";\n if (additiveNumbering[type]) {\n result = additiveFormat(additiveNumbering[type], num);\n } else if (alphabeticNumbering[type]) {\n result = alphabeticFormat(alphabeticNumbering[type], num);\n } else if (fixed[type] != null) {\n result = fixed[type];\n } else if (type == \"decimal-leading-zero\") {\n result = `${num}`;\n if (result.length == 1) {\n result = `0${result}`;\n }\n } else if (type == \"cjk-ideographic\" || type == \"trad-chinese-informal\") {\n result = chineseCounter(num, chineseTradInformal);\n } else {\n result = `${num}`;\n }\n if (upper) {\n return result.toUpperCase();\n }\n if (lower) {\n return result.toLowerCase();\n }\n return result;\n }\n\n visitFuncCounter(values: Css.Val[]): Css.Val {\n const counterName = values[0].toString();\n const type = values.length > 1 ? values[1].stringValue() : \"decimal\";\n const arr = this.cascade.counters[counterName];\n if (arr && arr.length) {\n const numval = (arr && arr.length && arr[arr.length - 1]) || 0;\n return new Css.Str(this.format(numval, type));\n } else {\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getPageCounterVal(counterName, (numval) =>\n self.format(numval || 0, type),\n ),\n );\n return new Css.SpaceList([c]);\n }\n }\n\n visitFuncCounters(values: Css.Val[]): Css.Val {\n const counterName = values[0].toString();\n const separator = values[1].stringValue();\n const type = values.length > 2 ? values[2].stringValue() : \"decimal\";\n const arr = this.cascade.counters[counterName];\n const sb = new Base.StringBuffer();\n if (arr && arr.length) {\n for (let i = 0; i < arr.length; i++) {\n if (i > 0) {\n sb.append(separator);\n }\n sb.append(this.format(arr[i], type));\n }\n }\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getPageCountersVal(counterName, (numvals) => {\n const parts = [] as string[];\n if (numvals.length) {\n for (let i = 0; i < numvals.length; i++) {\n parts.push(self.format(numvals[i], type));\n }\n }\n const elementCounters = sb.toString();\n if (elementCounters.length) {\n parts.push(elementCounters);\n }\n if (parts.length) {\n return parts.join(separator);\n } else {\n return self.format(0, type);\n }\n }),\n );\n return new Css.SpaceList([c]);\n }\n\n visitFuncTargetCounter(values: Css.Val[]): Css.Val {\n const targetUrl = values[0];\n let targetUrlStr: string;\n if (targetUrl instanceof Css.URL) {\n targetUrlStr = targetUrl.url;\n } else {\n targetUrlStr = targetUrl.stringValue();\n }\n const counterName = values[1].toString();\n const type = values.length > 2 ? values[2].stringValue() : \"decimal\";\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getTargetCounterVal(\n targetUrlStr,\n counterName,\n (numval) => self.format(numval || 0, type),\n ),\n );\n return new Css.SpaceList([c]);\n }\n\n visitFuncTargetCounters(values: Css.Val[]): Css.Val {\n const targetUrl = values[0];\n let targetUrlStr: string;\n if (targetUrl instanceof Css.URL) {\n targetUrlStr = targetUrl.url;\n } else {\n targetUrlStr = targetUrl.stringValue();\n }\n const counterName = values[1].toString();\n const separator = values[2].stringValue();\n const type = values.length > 3 ? values[3].stringValue() : \"decimal\";\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getTargetCountersVal(\n targetUrlStr,\n counterName,\n (numvals) => {\n const parts = numvals.map((numval) => self.format(numval, type));\n if (parts.length) {\n return parts.join(separator);\n } else {\n return self.format(0, type);\n }\n },\n ),\n );\n return new Css.SpaceList([c]);\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n switch (func.name) {\n case \"counter\":\n if (func.values.length <= 2) {\n return this.visitFuncCounter(func.values);\n }\n break;\n case \"counters\":\n if (func.values.length <= 3) {\n return this.visitFuncCounters(func.values);\n }\n break;\n case \"target-counter\":\n if (func.values.length <= 3) {\n return this.visitFuncTargetCounter(func.values);\n }\n break;\n case \"target-counters\":\n if (func.values.length <= 4) {\n return this.visitFuncTargetCounters(func.values);\n }\n break;\n }\n Logging.logger.warn(\"E_CSS_CONTENT_PROP:\", func.toString());\n return new Css.Str(\"\");\n }\n}\n\nexport function roman(num: number): string {\n if (num <= 0 || num != Math.round(num) || num > 3999) {\n return \"\";\n }\n const digits = [\"I\", \"V\", \"X\", \"L\", \"C\", \"D\", \"M\"];\n let offset = 0;\n let acc = \"\";\n while (num > 0) {\n let digit = num % 10;\n num = (num - digit) / 10;\n let result = \"\";\n if (digit == 9) {\n result += digits[offset] + digits[offset + 2];\n } else if (digit == 4) {\n result += digits[offset] + digits[offset + 1];\n } else {\n if (digit >= 5) {\n result += digits[offset + 1];\n digit -= 5;\n }\n while (digit > 0) {\n result += digits[offset];\n digit--;\n }\n }\n acc = result + acc;\n offset += 2;\n }\n return acc;\n}\n\nexport const additiveNumbering = {\n roman: [\n 4999,\n 1000,\n \"M\",\n 900,\n \"CM\",\n 500,\n \"D\",\n 400,\n \"CD\",\n 100,\n \"C\",\n 90,\n \"XC\",\n 50,\n \"L\",\n 40,\n \"XL\",\n 10,\n \"X\",\n 9,\n \"IX\",\n 5,\n \"V\",\n 4,\n \"IV\",\n 1,\n \"I\",\n ],\n armenian: [\n 9999,\n 9000,\n \"\\u0584\",\n 8000,\n \"\\u0583\",\n 7000,\n \"\\u0582\",\n 6000,\n \"\\u0581\",\n 5000,\n \"\\u0580\",\n 4000,\n \"\\u057f\",\n 3000,\n \"\\u057e\",\n 2000,\n \"\\u057d\",\n 1000,\n \"\\u057c\",\n 900,\n \"\\u057b\",\n 800,\n \"\\u057a\",\n 700,\n \"\\u0579\",\n 600,\n \"\\u0578\",\n 500,\n \"\\u0577\",\n 400,\n \"\\u0576\",\n 300,\n \"\\u0575\",\n 200,\n \"\\u0574\",\n 100,\n \"\\u0573\",\n 90,\n \"\\u0572\",\n 80,\n \"\\u0571\",\n 70,\n \"\\u0570\",\n 60,\n \"\\u056f\",\n 50,\n \"\\u056e\",\n 40,\n \"\\u056d\",\n 30,\n \"\\u056c\",\n 20,\n \"\\u056b\",\n 10,\n \"\\u056a\",\n 9,\n \"\\u0569\",\n 8,\n \"\\u0568\",\n 7,\n \"\\u0567\",\n 6,\n \"\\u0566\",\n 5,\n \"\\u0565\",\n 4,\n \"\\u0564\",\n 3,\n \"\\u0563\",\n 2,\n \"\\u0562\",\n 1,\n \"\\u0561\",\n ],\n georgian: [\n 19999,\n 10000,\n \"\\u10f5\",\n 9000,\n \"\\u10f0\",\n 8000,\n \"\\u10ef\",\n 7000,\n \"\\u10f4\",\n 6000,\n \"\\u10ee\",\n 5000,\n \"\\u10ed\",\n 4000,\n \"\\u10ec\",\n 3000,\n \"\\u10eb\",\n 2000,\n \"\\u10ea\",\n 1000,\n \"\\u10e9\",\n 900,\n \"\\u10e8\",\n 800,\n \"\\u10e7\",\n 700,\n \"\\u10e6\",\n 600,\n \"\\u10e5\",\n 500,\n \"\\u10e4\",\n 400,\n \"\\u10f3\",\n 300,\n \"\\u10e2\",\n 200,\n \"\\u10e1\",\n 100,\n \"\\u10e0\",\n 90,\n \"\\u10df\",\n 80,\n \"\\u10de\",\n 70,\n \"\\u10dd\",\n 60,\n \"\\u10f2\",\n 50,\n \"\\u10dc\",\n 40,\n \"\\u10db\",\n 30,\n \"\\u10da\",\n 20,\n \"\\u10d9\",\n 10,\n \"\\u10d8\",\n 9,\n \"\\u10d7\",\n 8,\n \"\\u10f1\",\n 7,\n \"\\u10d6\",\n 6,\n \"\\u10d5\",\n 5,\n \"\\u10d4\",\n 4,\n \"\\u10d3\",\n 3,\n \"\\u10d2\",\n 2,\n \"\\u10d1\",\n 1,\n \"\\u10d0\",\n ],\n hebrew: [\n 999,\n 400,\n \"\\u05ea\",\n 300,\n \"\\u05e9\",\n 200,\n \"\\u05e8\",\n 100,\n \"\\u05e7\",\n 90,\n \"\\u05e6\",\n 80,\n \"\\u05e4\",\n 70,\n \"\\u05e2\",\n 60,\n \"\\u05e1\",\n 50,\n \"\\u05e0\",\n 40,\n \"\\u05de\",\n 30,\n \"\\u05dc\",\n 20,\n \"\\u05db\",\n 19,\n \"\\u05d9\\u05d8\",\n 18,\n \"\\u05d9\\u05d7\",\n 17,\n \"\\u05d9\\u05d6\",\n 16,\n \"\\u05d8\\u05d6\",\n 15,\n \"\\u05d8\\u05d5\",\n 10,\n \"\\u05d9\",\n 9,\n \"\\u05d8\",\n 8,\n \"\\u05d7\",\n 7,\n \"\\u05d6\",\n 6,\n \"\\u05d5\",\n 5,\n \"\\u05d4\",\n 4,\n \"\\u05d3\",\n 3,\n \"\\u05d2\",\n 2,\n \"\\u05d1\",\n 1,\n \"\\u05d0\",\n ],\n};\n\nexport const alphabeticNumbering = {\n latin: \"a-z\",\n alpha: \"a-z\",\n greek: \"\\u03b1-\\u03c1\\u03c3-\\u03c9\",\n russian: \"\\u0430-\\u0438\\u043a-\\u0449\\u044d-\\u044f\",\n};\n\nexport const fixed = {\n square: \"\\u25a0\",\n disc: \"\\u2022\",\n circle: \"\\u25e6\",\n none: \"\",\n};\n\nexport function additiveFormat(entries: any[], num: number): string {\n const max = entries[0] as number;\n if (num > max || num <= 0 || num != Math.round(num)) {\n return \"\";\n }\n let result = \"\";\n for (let i = 1; i < entries.length; i += 2) {\n const value = entries[i] as number;\n let count = Math.floor(num / value);\n if (count > 20) {\n return \"\";\n }\n num -= count * value;\n while (count > 0) {\n result += entries[i + 1];\n count--;\n }\n }\n return result;\n}\n\nexport function expandAlphabet(str: string): string[] | null {\n const arr = [];\n let i = 0;\n while (i < str.length) {\n if (str.substr(i + 1, 1) == \"-\") {\n const first = str.charCodeAt(i);\n const last = str.charCodeAt(i + 2);\n i += 3;\n for (let k = first; k <= last; k++) {\n arr.push(String.fromCharCode(k));\n }\n } else {\n arr.push(str.substr(i++, 1));\n }\n }\n return arr;\n}\n\nexport function alphabeticFormat(alphabetStr: string, num: number): string {\n if (num <= 0 || num != Math.round(num)) {\n return \"\";\n }\n const alphabet = expandAlphabet(alphabetStr);\n let result = \"\";\n do {\n num--;\n const digit = num % alphabet.length;\n result = alphabet[digit] + result;\n num = (num - digit) / alphabet.length;\n } while (num > 0);\n return result;\n}\n\nexport type ChineseNumbering = {\n digits: string;\n markers: string;\n negative: string;\n formal: boolean;\n};\n\n/**\n * From http://www.w3.org/TR/css3-lists/\n */\nexport const chineseTradInformal: ChineseNumbering = {\n formal: false,\n digits: \"\\u96f6\\u4e00\\u4e8c\\u4e09\\u56db\\u4e94\\u516d\\u4e03\\u516b\\u4e5d\",\n markers: \"\\u5341\\u767e\\u5343\",\n negative: \"\\u8ca0\",\n};\n\nexport function chineseCounter(\n num: number,\n numbering: ChineseNumbering,\n): string {\n if (num > 9999 || num < -9999) {\n return `${num}`; // TODO: should be cjk-decimal\n }\n if (num == 0) {\n return numbering.digits.charAt(0);\n }\n const res = new Base.StringBuffer();\n if (num < 0) {\n res.append(numbering.negative);\n num = -num;\n }\n if (num < 10) {\n res.append(numbering.digits.charAt(num));\n } else if (!numbering.formal && num <= 19) {\n res.append(numbering.markers.charAt(0));\n if (num != 0) {\n res.append(numbering.digits.charAt(num - 10));\n }\n } else {\n const thousands = Math.floor(num / 1000);\n if (thousands) {\n res.append(numbering.digits.charAt(thousands));\n res.append(numbering.markers.charAt(2));\n }\n const hundreds = Math.floor(num / 100) % 10;\n if (hundreds) {\n res.append(numbering.digits.charAt(hundreds));\n res.append(numbering.markers.charAt(1));\n }\n const tens = Math.floor(num / 10) % 10;\n if (tens) {\n res.append(numbering.digits.charAt(tens));\n res.append(numbering.markers.charAt(0));\n }\n const ones = num % 10;\n if (ones) {\n res.append(numbering.digits.charAt(ones));\n }\n }\n\n // res.append(\"\\u3001\");\n return res.toString();\n}\n\n/**\n * Fitting order and specificity in the same number. Order is recorded in the\n * fractional part. Select value so that\n *\n * 0x7FFFFFFF != 0x7FFFFFFF + ORDER_INCREMENT\n *\n */\nexport const ORDER_INCREMENT = 1 / 1048576;\n\nexport function copyTable(src: ActionTable, dst: ActionTable): void {\n for (const n in src) {\n dst[n] = src[n].clone();\n }\n}\n\nexport class Cascade {\n nsCount: number = 0;\n nsPrefix: { [key: string]: string } = {};\n tags: ActionTable = {};\n nstags: ActionTable = {};\n epubtypes: ActionTable = {};\n classes: ActionTable = {};\n ids: ActionTable = {};\n pagetypes: ActionTable = {};\n order: number = 0;\n\n clone(): Cascade {\n const r = new Cascade();\n r.nsCount = this.nsCount;\n for (const p in this.nsPrefix) {\n r.nsPrefix[p] = this.nsPrefix[p];\n }\n copyTable(this.tags, r.tags);\n copyTable(this.nstags, r.nstags);\n copyTable(this.epubtypes, r.epubtypes);\n copyTable(this.classes, r.classes);\n copyTable(this.ids, r.ids);\n copyTable(this.pagetypes, r.pagetypes);\n r.order = this.order;\n return r;\n }\n\n insertInTable(table: ActionTable, key: string, action: CascadeAction): void {\n const a = table[key];\n if (a) {\n action = a.mergeWith(action);\n }\n table[key] = action;\n }\n\n createInstance(\n context: Exprs.Context,\n counterListener: CounterListener,\n counterResolver: CounterResolver,\n lang,\n ): CascadeInstance {\n return new CascadeInstance(\n this,\n context,\n counterListener,\n counterResolver,\n lang,\n );\n }\n\n nextOrder(): number {\n return (this.order += ORDER_INCREMENT);\n }\n}\n\nexport class CascadeInstance {\n code: Cascade;\n stack = [[], []] as ConditionItem[][];\n conditions = {} as { [key: string]: number };\n currentElement: Element | null = null;\n currentElementOffset: number | null = null;\n currentStyle: ElementStyle | null = null;\n currentClassNames: string[] | null = null;\n currentLocalName: string = \"\";\n currentNamespace: string = \"\";\n currentId: string = \"\";\n currentXmlId: string = \"\";\n currentNSTag: string = \"\";\n currentEpubTypes: string[] | null = null;\n currentPageType: string | null = null;\n isFirst: boolean = true;\n isRoot: boolean = true;\n counters: { [key: string]: number[] } = {};\n counterScoping: { [key: string]: boolean }[] = [{}];\n quotes: Css.Str[];\n quoteDepth: number = 0;\n lang: string = \"\";\n siblingOrderStack: number[] = [0];\n currentSiblingOrder: number = 0;\n siblingTypeCountsStack: { [key: string]: { [key: string]: number } }[] = [{}];\n currentSiblingTypeCounts: { [key: string]: { [key: string]: number } };\n currentFollowingSiblingOrder: number | null = null;\n followingSiblingOrderStack: (number | null)[];\n followingSiblingTypeCountsStack: {\n [key: string]: { [key: string]: number };\n }[] = [{}];\n currentFollowingSiblingTypeCounts: {\n [key: string]: { [key: string]: number };\n };\n viewConditions: { [key: string]: Matchers.Matcher[] } = {};\n dependentConditions: string[] = [];\n elementStack: Element[];\n currentDoc?: Document | null;\n\n constructor(\n cascade: Cascade,\n public readonly context: Exprs.Context,\n public readonly counterListener: CounterListener,\n public readonly counterResolver: CounterResolver,\n lang: string,\n ) {\n this.code = cascade;\n this.quotes = [\n new Css.Str(\"\\u201c\"),\n new Css.Str(\"\\u201d\"),\n new Css.Str(\"\\u2018\"),\n new Css.Str(\"\\u2019\"),\n ];\n this.currentSiblingTypeCounts = this.siblingTypeCountsStack[0];\n this.followingSiblingOrderStack = [this.currentFollowingSiblingOrder];\n this.currentFollowingSiblingTypeCounts = this.siblingTypeCountsStack[0];\n if (VIVLIOSTYLE_DEBUG) {\n this.elementStack = [];\n }\n }\n\n pushConditionItem(item: ConditionItem): void {\n this.stack[this.stack.length - 1].push(item);\n }\n\n increment(condition: string, viewCondition: Matchers.Matcher): void {\n this.conditions[condition] = (this.conditions[condition] || 0) + 1;\n if (!viewCondition) {\n return;\n }\n if (this.viewConditions[condition]) {\n this.viewConditions[condition].push(viewCondition);\n } else {\n this.viewConditions[condition] = [viewCondition];\n }\n }\n\n decrement(condition: string, viewCondition: Matchers.Matcher): void {\n this.conditions[condition]--;\n if (!this.viewConditions[condition]) {\n return;\n }\n this.viewConditions[condition] = this.viewConditions[condition].filter(\n (item) => item !== viewCondition,\n );\n if (this.viewConditions[condition].length === 0) {\n delete this.viewConditions[condition];\n }\n }\n\n buildViewConditionMatcher(viewConditionId: string | null): Matchers.Matcher {\n let matcher: Matchers.Matcher = null;\n if (viewConditionId) {\n Asserts.assert(this.currentElementOffset);\n matcher = Matchers.MatcherBuilder.buildViewConditionMatcher(\n this.currentElementOffset,\n viewConditionId,\n );\n }\n const dependentConditionMatchers = this.dependentConditions\n .map((conditionId) => {\n const conditions = this.viewConditions[conditionId];\n if (conditions && conditions.length > 0) {\n return conditions.length === 1\n ? conditions[0]\n : Matchers.MatcherBuilder.buildAnyMatcher([].concat(conditions));\n } else {\n return null;\n }\n })\n .filter((item) => item);\n if (dependentConditionMatchers.length <= 0) {\n return matcher;\n }\n if (matcher === null) {\n return dependentConditionMatchers.length === 1\n ? dependentConditionMatchers[0]\n : Matchers.MatcherBuilder.buildAllMatcher(dependentConditionMatchers);\n }\n return Matchers.MatcherBuilder.buildAllMatcher(\n [matcher].concat(dependentConditionMatchers),\n );\n }\n\n applyAction(table: ActionTable, key: string): void {\n const action = table[key];\n if (action) {\n action.apply(this);\n }\n }\n\n pushRule(\n classes: string[],\n pageType: string | null,\n baseStyle: ElementStyle,\n ): void {\n this.currentElement = null;\n this.currentElementOffset = null;\n this.currentStyle = baseStyle;\n this.currentNamespace = \"\";\n this.currentLocalName = \"\";\n this.currentId = \"\";\n this.currentXmlId = \"\";\n this.currentClassNames = classes;\n this.currentNSTag = \"\";\n this.currentEpubTypes = EMPTY;\n this.currentPageType = pageType;\n this.applyActions();\n }\n\n defineCounter(counterName: string, value: number) {\n if (this.counters[counterName]) {\n this.counters[counterName].push(value);\n } else {\n this.counters[counterName] = [value];\n }\n let scoping = this.counterScoping[this.counterScoping.length - 1];\n if (!scoping) {\n scoping = {};\n this.counterScoping[this.counterScoping.length - 1] = scoping;\n }\n scoping[counterName] = true;\n }\n\n pushCounters(props: ElementStyle): void {\n let displayVal = Css.ident.inline;\n const display = props[\"display\"];\n if (display) {\n displayVal = display.evaluate(this.context);\n }\n let resetMap: { [key: string]: number } = null;\n let incrementMap: { [key: string]: number } = null;\n let setMap: { [key: string]: number } = null;\n const reset = props[\"counter-reset\"];\n if (reset) {\n const resetVal = reset.evaluate(this.context);\n if (resetVal) {\n resetMap = CssProp.toCounters(resetVal, true);\n }\n }\n const set = props[\"counter-set\"];\n if (set) {\n const setVal = set.evaluate(this.context);\n if (setVal) {\n setMap = CssProp.toCounters(setVal, false);\n }\n }\n const increment = props[\"counter-increment\"];\n if (increment) {\n const incrementVal = increment.evaluate(this.context);\n if (incrementVal) {\n incrementMap = CssProp.toCounters(incrementVal, false);\n }\n }\n if (\n (this.currentLocalName == \"ol\" || this.currentLocalName == \"ul\") &&\n this.currentNamespace == Base.NS.XHTML\n ) {\n if (!resetMap) {\n resetMap = {};\n }\n resetMap[\"ua-list-item\"] = 0;\n }\n if (displayVal === Css.ident.list_item) {\n if (!incrementMap) {\n incrementMap = {};\n }\n incrementMap[\"ua-list-item\"] = 1;\n }\n if (resetMap) {\n for (const resetCounterName in resetMap) {\n this.defineCounter(resetCounterName, resetMap[resetCounterName]);\n }\n }\n if (setMap) {\n for (const setCounterName in setMap) {\n if (!this.counters[setCounterName]) {\n this.defineCounter(setCounterName, setMap[setCounterName]);\n } else {\n const counterValues = this.counters[setCounterName];\n counterValues[counterValues.length - 1] = setMap[setCounterName];\n }\n }\n }\n if (incrementMap) {\n for (const incrementCounterName in incrementMap) {\n if (!this.counters[incrementCounterName]) {\n this.defineCounter(incrementCounterName, 0);\n }\n const counterValues = this.counters[incrementCounterName];\n counterValues[counterValues.length - 1] +=\n incrementMap[incrementCounterName];\n }\n }\n if (displayVal === Css.ident.list_item) {\n const listItemCounts = this.counters[\"ua-list-item\"];\n const listItemCount = listItemCounts[listItemCounts.length - 1];\n props[\"ua-list-item-count\"] = new CascadeValue(\n new Css.Num(listItemCount),\n 0,\n );\n }\n this.counterScoping.push(null);\n }\n\n popCounters(): void {\n const scoping = this.counterScoping.pop();\n if (scoping) {\n for (const counterName in scoping) {\n const arr = this.counters[counterName];\n if (arr) {\n if (arr.length == 1) {\n delete this.counters[counterName];\n } else {\n arr.pop();\n }\n }\n }\n }\n }\n\n processPseudoelementProps(pseudoprops: ElementStyle, element: Element): void {\n this.pushCounters(pseudoprops);\n if (pseudoprops[\"content\"]) {\n pseudoprops[\"content\"] = pseudoprops[\"content\"].filterValue(\n new ContentPropVisitor(this, element, this.counterResolver),\n );\n }\n this.popCounters();\n }\n\n pushElement(\n element: Element,\n baseStyle: ElementStyle,\n elementOffset: number,\n ): void {\n if (VIVLIOSTYLE_DEBUG) {\n this.elementStack.push(element);\n }\n\n // do not apply page rules\n this.currentPageType = null;\n this.currentElement = element;\n this.currentElementOffset = elementOffset;\n this.currentStyle = baseStyle;\n this.currentNamespace = element.namespaceURI;\n this.currentLocalName = element.localName;\n const prefix = this.code.nsPrefix[this.currentNamespace];\n if (prefix) {\n this.currentNSTag = prefix + this.currentLocalName;\n } else {\n this.currentNSTag = \"\";\n }\n this.currentId = element.getAttribute(\"id\");\n this.currentXmlId = element.getAttributeNS(Base.NS.XML, \"id\");\n const classes = element.getAttribute(\"class\");\n if (classes) {\n this.currentClassNames = classes.split(/\\s+/);\n } else {\n this.currentClassNames = EMPTY;\n }\n const types = element.getAttributeNS(Base.NS.epub, \"type\");\n if (types) {\n this.currentEpubTypes = types.split(/\\s+/);\n } else {\n this.currentEpubTypes = EMPTY;\n }\n if (\n this.currentLocalName == \"style\" &&\n this.currentNamespace == Base.NS.FB2\n ) {\n // special case\n const className = element.getAttribute(\"name\") || \"\";\n this.currentClassNames = [className];\n }\n const lang = Base.getLangAttribute(element);\n if (lang) {\n this.stack[this.stack.length - 1].push(new RestoreLangItem(this.lang));\n this.lang = lang.toLowerCase();\n }\n const isRoot = this.isRoot;\n const siblingOrderStack = this.siblingOrderStack;\n this.currentSiblingOrder = ++siblingOrderStack[\n siblingOrderStack.length - 1\n ];\n siblingOrderStack.push(0);\n const siblingTypeCountsStack = this.siblingTypeCountsStack;\n const currentSiblingTypeCounts = (this.currentSiblingTypeCounts =\n siblingTypeCountsStack[siblingTypeCountsStack.length - 1]);\n let currentNamespaceTypeCounts =\n currentSiblingTypeCounts[this.currentNamespace];\n if (!currentNamespaceTypeCounts) {\n currentNamespaceTypeCounts = currentSiblingTypeCounts[\n this.currentNamespace\n ] = {};\n }\n currentNamespaceTypeCounts[this.currentLocalName] =\n (currentNamespaceTypeCounts[this.currentLocalName] || 0) + 1;\n siblingTypeCountsStack.push({});\n const followingSiblingOrderStack = this.followingSiblingOrderStack;\n if (\n followingSiblingOrderStack[followingSiblingOrderStack.length - 1] !== null\n ) {\n this.currentFollowingSiblingOrder = --followingSiblingOrderStack[\n followingSiblingOrderStack.length - 1\n ];\n } else {\n this.currentFollowingSiblingOrder = null;\n }\n followingSiblingOrderStack.push(null);\n const followingSiblingTypeCountsStack = this\n .followingSiblingTypeCountsStack;\n const currentFollowingSiblingTypeCounts = (this.currentFollowingSiblingTypeCounts =\n followingSiblingTypeCountsStack[\n followingSiblingTypeCountsStack.length - 1\n ]);\n if (\n currentFollowingSiblingTypeCounts &&\n currentFollowingSiblingTypeCounts[this.currentNamespace]\n ) {\n currentFollowingSiblingTypeCounts[this.currentNamespace][\n this.currentLocalName\n ]--;\n }\n followingSiblingTypeCountsStack.push({});\n this.applyActions();\n this.applyAttrFilter(element);\n const quotesCasc = baseStyle[\"quotes\"];\n let itemToPushLast: QuotesScopeItem | null = null;\n if (quotesCasc) {\n const quotesVal = quotesCasc.evaluate(this.context);\n if (quotesVal) {\n itemToPushLast = new QuotesScopeItem(this.quotes);\n if (quotesVal === Css.ident.none) {\n this.quotes = [new Css.Str(\"\"), new Css.Str(\"\")];\n } else if (quotesVal instanceof Css.SpaceList) {\n this.quotes = (quotesVal as Css.SpaceList).values as Css.Str[];\n }\n }\n }\n this.pushCounters(this.currentStyle);\n const id =\n this.currentId || this.currentXmlId || element.getAttribute(\"name\") || \"\";\n if (isRoot || id) {\n const counters: { [key: string]: number[] } = {};\n Object.keys(this.counters).forEach((name) => {\n counters[name] = Array.from(this.counters[name]);\n });\n this.counterListener.countersOfId(id, counters);\n }\n const pseudos = getStyleMap(this.currentStyle, \"_pseudos\");\n if (pseudos) {\n let before = true;\n for (const pseudoName of pseudoNames) {\n if (!pseudoName) {\n // content\n before = false;\n }\n const pseudoProps = pseudos[pseudoName];\n if (pseudoProps) {\n if (before) {\n this.processPseudoelementProps(pseudoProps, element);\n } else {\n this.stack[this.stack.length - 2].push(\n new AfterPseudoelementItem(pseudoProps, element),\n );\n }\n }\n }\n }\n if (itemToPushLast) {\n this.stack[this.stack.length - 2].push(itemToPushLast);\n }\n }\n\n private applyAttrFilterInner(visitor, elementStyle): void {\n for (const propName in elementStyle) {\n if (isPropName(propName)) {\n elementStyle[propName] = elementStyle[propName].filterValue(visitor);\n }\n }\n }\n\n private applyAttrFilter(element): void {\n const visitor = new AttrValueFilterVisitor(element);\n const currentStyle = this.currentStyle;\n const pseudoMap = getStyleMap(currentStyle, \"_pseudos\");\n for (const pseudoName in pseudoMap) {\n this.applyAttrFilterInner(visitor, pseudoMap[pseudoName]);\n }\n this.applyAttrFilterInner(visitor, currentStyle);\n }\n\n private applyActions(): void {\n let i: number;\n for (i = 0; i < this.currentClassNames.length; i++) {\n this.applyAction(this.code.classes, this.currentClassNames[i]);\n }\n for (i = 0; i < this.currentEpubTypes.length; i++) {\n this.applyAction(this.code.epubtypes, this.currentEpubTypes[i]);\n }\n this.applyAction(this.code.ids, this.currentId);\n this.applyAction(this.code.tags, this.currentLocalName);\n if (this.currentLocalName != \"\") {\n // Universal selector does not apply to page-master-related rules.\n this.applyAction(this.code.tags, \"*\");\n }\n this.applyAction(this.code.nstags, this.currentNSTag);\n\n // Apply page rules only when currentPageType is not null\n if (this.currentPageType !== null) {\n this.applyAction(this.code.pagetypes, this.currentPageType);\n\n // We represent page rules without selectors by *, though it is illegal in\n // CSS\n this.applyAction(this.code.pagetypes, \"*\");\n }\n this.currentElement = null;\n this.currentDoc = null;\n this.stack.push([]);\n for (let depth = 1; depth >= -1; --depth) {\n const list = this.stack[this.stack.length - depth - 2];\n i = 0;\n while (i < list.length) {\n if (list[i].push(this, depth)) {\n // done\n list.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n this.isFirst = true;\n this.isRoot = false;\n }\n\n private pop(): void {\n for (let depth = 1; depth >= -1; --depth) {\n const list = this.stack[this.stack.length - depth - 2];\n let i = 0;\n while (i < list.length) {\n if (list[i].pop(this, depth)) {\n // done\n list.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n this.stack.pop();\n this.isFirst = false;\n }\n\n popRule(): void {\n this.pop();\n }\n\n popElement(element: Element): void {\n if (VIVLIOSTYLE_DEBUG) {\n const e = this.elementStack.pop();\n if (e !== element) {\n throw new Error(\"Invalid call to popElement\");\n }\n }\n this.siblingOrderStack.pop();\n this.siblingTypeCountsStack.pop();\n this.followingSiblingOrderStack.pop();\n this.followingSiblingTypeCountsStack.pop();\n this.pop();\n this.popCounters();\n }\n}\n\nexport const EMPTY = [];\n\n/**\n * Pseudoelement names in the order they should be processed, empty string is\n * the place where the element's DOM children are processed.\n */\nexport const pseudoNames = [\n \"before\",\n \"transclusion-before\",\n \"footnote-call\",\n \"footnote-marker\",\n \"inner\",\n \"first-letter\",\n \"first-line\",\n \"\",\n /* content */\n \"transclusion-after\",\n \"after\",\n];\n\n/**\n * @enum {number}\n */\nexport enum ParseState {\n TOP,\n SELECTOR,\n RULE,\n}\n\n/**\n * Cascade for base User Agent stylesheet.\n */\nexport let uaBaseCascade: Cascade = null;\nexport function setUABaseCascade(value: Cascade): void {\n uaBaseCascade = value;\n}\n\n//------------- parsing ------------\nexport class CascadeParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n chain: ChainedAction[] = null;\n specificity: number = 0;\n elementStyle: ElementStyle = null;\n conditionCount: number = 0;\n pseudoelement: string | null = null;\n footnoteContent: boolean = false;\n cascade: Cascade;\n state: ParseState;\n viewConditionId: string | null = null;\n insideSelectorRule: ParseState;\n\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly condition: Exprs.Val,\n parent: CascadeParserHandler,\n public readonly regionId: string | null,\n public readonly validatorSet: CssValidator.ValidatorSet,\n topLevel: boolean,\n ) {\n super(scope, owner, topLevel);\n this.cascade = parent\n ? parent.cascade\n : uaBaseCascade\n ? uaBaseCascade.clone()\n : new Cascade();\n this.state = ParseState.TOP;\n }\n\n protected insertNonPrimary(action: CascadeAction): void {\n this.cascade.insertInTable(this.cascade.tags, \"*\", action);\n }\n\n processChain(action: CascadeAction): void {\n const chained = chainActions(this.chain, action);\n if (\n chained !== action &&\n (chained as ChainedAction).makePrimary(this.cascade)\n ) {\n return;\n }\n this.insertNonPrimary(chained);\n }\n\n isInsideSelectorRule(mnemonics: string): boolean {\n if (this.state != ParseState.TOP) {\n this.reportAndSkip(mnemonics);\n return true;\n }\n return false;\n }\n\n /**\n * @override\n */\n tagSelector(ns: string | null, name: string | null): void {\n if (!name && !ns) {\n return;\n }\n this.specificity += 1;\n if (name && ns) {\n this.chain.push(new CheckNSTagAction(ns, name.toLowerCase()));\n } else if (name) {\n this.chain.push(new CheckLocalNameAction(name.toLowerCase()));\n } else {\n this.chain.push(new CheckNamespaceAction(ns as string));\n }\n }\n\n /**\n * @override\n */\n classSelector(name: string): void {\n if (this.pseudoelement) {\n Logging.logger.warn(`::${this.pseudoelement}`, `followed by .${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n return;\n }\n this.specificity += 256;\n this.chain.push(new CheckClassAction(name));\n }\n\n /**\n * @override\n */\n pseudoclassSelector(name: string, params: (number | string)[]): void {\n if (this.pseudoelement) {\n Logging.logger.warn(`::${this.pseudoelement}`, `followed by :${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n return;\n }\n switch (name.toLowerCase()) {\n case \"enabled\":\n this.chain.push(new IsEnabledAction());\n break;\n case \"disabled\":\n this.chain.push(new IsDisabledAction());\n break;\n case \"checked\":\n this.chain.push(new IsCheckedAction());\n break;\n case \"root\":\n this.chain.push(new IsRootAction());\n break;\n case \"link\":\n this.chain.push(new CheckLocalNameAction(\"a\"));\n this.chain.push(new CheckAttributePresentAction(\"\", \"href\"));\n break;\n case \"-adapt-href-epub-type\":\n case \"href-epub-type\":\n if (params && params.length == 1 && typeof params[0] == \"string\") {\n const value = params[0] as string;\n const patt = new RegExp(`(^|s)${Base.escapeRegExp(value)}(\\$|s)`);\n this.chain.push(new CheckTargetEpubTypeAction(patt));\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n case \"-adapt-footnote-content\":\n case \"footnote-content\":\n // content inside the footnote\n this.footnoteContent = true;\n break;\n case \"visited\":\n case \"active\":\n case \"hover\":\n case \"focus\":\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n case \"lang\":\n if (params && params.length == 1 && typeof params[0] == \"string\") {\n const langValue = params[0] as string;\n this.chain.push(\n new CheckLangAction(\n new RegExp(\n `^${Base.escapeRegExp(langValue.toLowerCase())}(\\$|-)`,\n ),\n ),\n );\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fais\n }\n break;\n case \"nth-child\":\n case \"nth-last-child\":\n case \"nth-of-type\":\n case \"nth-last-of-type\": {\n const ActionClass = nthSelectorActionClasses[name.toLowerCase()];\n if (params && params.length == 2) {\n this.chain.push(\n new ActionClass(params[0] as number, params[1] as number),\n );\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n }\n case \"first-child\":\n this.chain.push(new IsFirstAction());\n break;\n case \"last-child\":\n this.chain.push(new IsNthLastSiblingAction(0, 1));\n break;\n case \"first-of-type\":\n this.chain.push(new IsNthSiblingOfTypeAction(0, 1));\n break;\n case \"last-of-type\":\n this.chain.push(new IsNthLastSiblingOfTypeAction(0, 1));\n break;\n case \"only-child\":\n this.chain.push(new IsFirstAction());\n this.chain.push(new IsNthLastSiblingAction(0, 1));\n break;\n case \"only-of-type\":\n this.chain.push(new IsNthSiblingOfTypeAction(0, 1));\n this.chain.push(new IsNthLastSiblingOfTypeAction(0, 1));\n break;\n case \"empty\":\n this.chain.push(new IsEmptyAction());\n break;\n case \"before\":\n case \"after\":\n case \"first-line\":\n case \"first-letter\":\n this.pseudoelementSelector(name, params);\n return;\n default:\n Logging.logger.warn(`unknown pseudo-class selector: ${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n }\n this.specificity += 256;\n }\n\n /**\n * @override\n */\n pseudoelementSelector(name: string, params: (number | string)[]): void {\n switch (name) {\n case \"before\":\n case \"after\":\n case \"first-line\":\n case \"first-letter\":\n case \"footnote-call\":\n case \"footnote-marker\":\n case \"inner\":\n case \"after-if-continues\":\n if (!this.pseudoelement) {\n this.pseudoelement = name;\n } else {\n Logging.logger.warn(\n `Double pseudoelement ::${this.pseudoelement}::${name}`,\n );\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n case \"first-n-lines\":\n if (params && params.length == 1 && typeof params[0] == \"number\") {\n const n = Math.round(params[0] as number);\n if (n > 0 && n == params[0]) {\n if (!this.pseudoelement) {\n this.pseudoelement = `first-${n}-lines`;\n } else {\n Logging.logger.warn(\n `Double pseudoelement ::${this.pseudoelement}::${name}`,\n );\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n }\n }\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n case \"nth-fragment\":\n if (params && params.length == 2) {\n this.viewConditionId = `NFS_${params[0]}_${params[1]}`;\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n default:\n Logging.logger.warn(`Unrecognized pseudoelement: ::${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n }\n this.specificity += 1;\n }\n\n /**\n * @override\n */\n idSelector(id: string): void {\n this.specificity += 65536;\n this.chain.push(new CheckIdAction(id));\n }\n\n /**\n * @override\n */\n attributeSelector(\n ns: string,\n name: string,\n op: CssTokenizer.TokenType,\n value: string | null,\n ): void {\n this.specificity += 256;\n name = name.toLowerCase();\n value = value || \"\";\n let action;\n switch (op) {\n case CssTokenizer.TokenType.EOF:\n action = new CheckAttributePresentAction(ns, name);\n break;\n case CssTokenizer.TokenType.EQ:\n action = new CheckAttributeEqAction(ns, name, value);\n break;\n case CssTokenizer.TokenType.TILDE_EQ:\n if (!value || value.match(/\\s/)) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`(^|\\\\s)${Base.escapeRegExp(value)}(\\$|\\\\s)`),\n );\n }\n break;\n case CssTokenizer.TokenType.BAR_EQ:\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`^${Base.escapeRegExp(value)}(\\$|-)`),\n );\n break;\n case CssTokenizer.TokenType.HAT_EQ:\n if (!value) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`^${Base.escapeRegExp(value)}`),\n );\n }\n break;\n case CssTokenizer.TokenType.DOLLAR_EQ:\n if (!value) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`${Base.escapeRegExp(value)}\\$`),\n );\n }\n break;\n case CssTokenizer.TokenType.STAR_EQ:\n if (!value) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(Base.escapeRegExp(value)),\n );\n }\n break;\n case CssTokenizer.TokenType.COL_COL:\n if (value == \"supported\") {\n action = new CheckNamespaceSupportedAction(ns, name);\n } else {\n Logging.logger.warn(\"Unsupported :: attr selector op:\", value);\n action = new CheckConditionAction(\"\"); // always fails\n }\n break;\n default:\n Logging.logger.warn(\"Unsupported attr selector:\", op);\n action = new CheckConditionAction(\"\"); // always fails\n }\n this.chain.push(action);\n }\n\n /**\n * @override\n */\n descendantSelector(): void {\n const condition = `d${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new DescendantConditionItem(condition, this.viewConditionId, null),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n childSelector(): void {\n const condition = `c${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new ChildConditionItem(condition, this.viewConditionId, null),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n adjacentSiblingSelector(): void {\n const condition = `a${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new AdjacentSiblingConditionItem(condition, this.viewConditionId, null),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n followingSiblingSelector(): void {\n const condition = `f${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new FollowingSiblingConditionItem(\n condition,\n this.viewConditionId,\n null,\n ),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.finishChain();\n this.pseudoelement = null;\n this.footnoteContent = false;\n this.specificity = 0;\n this.chain = [];\n }\n\n /**\n * @override\n */\n startSelectorRule(): void {\n if (this.isInsideSelectorRule(\"E_CSS_UNEXPECTED_SELECTOR\")) {\n return;\n }\n this.state = ParseState.SELECTOR;\n this.elementStyle = {} as ElementStyle;\n this.pseudoelement = null;\n this.specificity = 0;\n this.footnoteContent = false;\n this.chain = [];\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n super.error(mnemonics, token);\n if (this.state == ParseState.SELECTOR) {\n this.state = ParseState.TOP;\n }\n }\n\n /**\n * @override\n */\n startStylesheet(flavor: CssParser.StylesheetFlavor): void {\n super.startStylesheet(flavor);\n this.state = ParseState.TOP;\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.finishChain();\n super.startRuleBody();\n if (this.state == ParseState.SELECTOR) {\n this.state = ParseState.TOP;\n }\n }\n\n /**\n * @override\n */\n endRule(): void {\n super.endRule();\n this.insideSelectorRule = ParseState.TOP;\n }\n\n finishChain(): void {\n if (this.chain) {\n const specificity: number = this.specificity + this.cascade.nextOrder();\n this.processChain(this.makeApplyRuleAction(specificity));\n this.chain = null;\n this.pseudoelement = null;\n this.viewConditionId = null;\n this.footnoteContent = false;\n this.specificity = 0;\n }\n }\n\n protected makeApplyRuleAction(specificity: number): ApplyRuleAction {\n let regionId = this.regionId;\n if (this.footnoteContent) {\n if (regionId) {\n regionId = \"xxx-bogus-xxx\";\n } else {\n regionId = \"footnote\";\n }\n }\n return new ApplyRuleAction(\n this.elementStyle,\n specificity,\n this.pseudoelement,\n regionId,\n this.viewConditionId,\n );\n }\n\n special(name: string, value: Css.Val) {\n let val: CascadeValue;\n if (!this.condition) {\n val = new CascadeValue(value, 0);\n } else {\n val = new ConditionalCascadeValue(value, 0, this.condition);\n }\n const arr = getMutableSpecial(this.elementStyle, name);\n arr.push(val);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY_VALUE ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n if (\n name == \"display\" &&\n (value === Css.ident.oeb_page_head || value === Css.ident.oeb_page_foot)\n ) {\n this.simpleProperty(\n \"flow-options\",\n new Css.SpaceList([Css.ident.exclusive, Css.ident._static]),\n important,\n );\n this.simpleProperty(\"flow-into\", value, important);\n value = Css.ident.block;\n }\n const hooks = Plugin.getHooksForName(\"SIMPLE_PROPERTY\");\n hooks.forEach((hook) => {\n const original = { name: name, value: value, important: important };\n const converted = hook(original);\n name = converted[\"name\"];\n value = converted[\"value\"];\n important = converted[\"important\"];\n });\n const specificity = important\n ? this.getImportantSpecificity()\n : this.getBaseSpecificity();\n const cascval = this.condition\n ? new ConditionalCascadeValue(value, specificity, this.condition)\n : new CascadeValue(value, specificity);\n setProp(this.elementStyle, name, cascval);\n }\n\n finish(): Cascade {\n return this.cascade;\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n switch (funcName) {\n case \"not\": {\n const notParserHandler = new NotParameterParserHandler(this);\n notParserHandler.startSelectorRule();\n this.owner.pushHandler(notParserHandler);\n break;\n }\n default:\n // TODO\n break;\n }\n }\n}\n\nexport const nthSelectorActionClasses: { [key: string]: typeof IsNthAction } = {\n \"nth-child\": IsNthSiblingAction,\n \"nth-of-type\": IsNthSiblingOfTypeAction,\n \"nth-last-child\": IsNthLastSiblingAction,\n \"nth-last-of-type\": IsNthLastSiblingOfTypeAction,\n};\n\nexport let conditionCount: number = 0;\n\nexport class NotParameterParserHandler extends CascadeParserHandler {\n parentChain: ChainedAction[];\n\n constructor(public readonly parent: CascadeParserHandler) {\n super(\n parent.scope,\n parent.owner,\n parent.condition,\n parent,\n parent.regionId,\n parent.validatorSet,\n false,\n );\n this.parentChain = parent.chain;\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n if (funcName == \"not\") {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_NOT\");\n }\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_RULE_BODY\");\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_NEXT_SELECTOR\");\n }\n\n /**\n * @override\n */\n endFuncWithSelector(): void {\n if (this.chain && this.chain.length > 0) {\n this.parentChain.push(new NegateActionsSet(this.chain));\n }\n this.parent.specificity += this.specificity;\n this.owner.popHandler();\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n super.error(mnemonics, token);\n this.owner.popHandler();\n }\n}\n\n/**\n * @override\n */\nexport class DefineParserHandler extends CssParser.SlaveParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n ) {\n super(scope, owner, false);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n if (this.scope.values[name]) {\n this.error(`E_CSS_NAME_REDEFINED ${name}`, this.getCurrentToken());\n } else {\n const unit = name.match(/height|^(top|bottom)$/) ? \"vh\" : \"vw\";\n const dim = new Exprs.Numeric(this.scope, 100, unit);\n this.scope.defineName(name, value.toExpr(this.scope, dim));\n }\n }\n}\n\nexport class PropSetParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n order: number;\n\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly condition: Exprs.Val,\n public readonly elementStyle: ElementStyle,\n public readonly validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, false);\n this.order = 0;\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n if (important) {\n Logging.logger.warn(\"E_IMPORTANT_NOT_ALLOWED\");\n } else {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n Logging.logger.warn(\n \"E_INVALID_PROPERTY_VALUE\",\n `${name}:`,\n value.toString(),\n );\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n Logging.logger.warn(\"E_INVALID_PROPERTY\", `${name}:`, value.toString());\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n let specificity = important\n ? this.getImportantSpecificity()\n : this.getBaseSpecificity();\n specificity += this.order;\n this.order += ORDER_INCREMENT;\n const av = this.condition\n ? new ConditionalCascadeValue(value, specificity, this.condition)\n : new CascadeValue(value, specificity);\n setProp(this.elementStyle, name, av);\n }\n}\n\nexport class PropertyParserHandler extends CssParser.ErrorHandler\n implements CssValidator.PropertyReceiver {\n elementStyle = {} as ElementStyle;\n order: number = 0;\n\n constructor(\n scope: Exprs.LexicalScope,\n public readonly validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n Logging.logger.warn(\n \"E_INVALID_PROPERTY_VALUE\",\n `${name}:`,\n value.toString(),\n );\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n Logging.logger.warn(\"E_INVALID_PROPERTY\", `${name}:`, value.toString());\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n let specificity = important\n ? CssParser.SPECIFICITY_STYLE_IMPORTANT\n : CssParser.SPECIFICITY_STYLE;\n specificity += this.order;\n this.order += ORDER_INCREMENT;\n const cascval = new CascadeValue(value, specificity);\n setProp(this.elementStyle, name, cascval);\n }\n}\n\nexport function forEachViewConditionalStyles(\n style: ElementStyle,\n callback: (p1: ElementStyle) => any,\n): void {\n const viewConditionalStyles = getViewConditionalStyleMap(style);\n if (!viewConditionalStyles) {\n return;\n }\n viewConditionalStyles.forEach((entry) => {\n if (!entry.matcher.matches()) {\n return;\n }\n callback(entry.styles);\n });\n}\n\nexport function mergeViewConditionalStyles(\n cascMap: { [key: string]: CascadeValue },\n context: Exprs.Context,\n style: ElementStyle,\n): void {\n forEachViewConditionalStyles(style, (viewConditionalStyles) => {\n mergeStyle(cascMap, viewConditionalStyles, context);\n });\n}\n\nexport function parseStyleAttribute(\n scope: Exprs.LexicalScope,\n validatorSet: CssValidator.ValidatorSet,\n baseURL: string,\n styleAttrValue: string,\n): ElementStyle {\n const handler = new PropertyParserHandler(scope, validatorSet);\n const tokenizer = new CssTokenizer.Tokenizer(styleAttrValue, handler);\n try {\n CssParser.parseStyleAttribute(tokenizer, handler, baseURL);\n } catch (err) {\n Logging.logger.warn(err, \"Style attribute parse error:\");\n }\n return handler.elementStyle;\n}\n\nexport function isVertical(\n cascaded: { [key: string]: CascadeValue },\n context: Exprs.Context,\n vertical: boolean,\n): boolean {\n const writingModeCasc = cascaded[\"writing-mode\"];\n if (writingModeCasc) {\n const writingMode = writingModeCasc.evaluate(context, \"writing-mode\");\n if (writingMode && writingMode !== Css.ident.inherit) {\n return writingMode === Css.ident.vertical_rl;\n }\n }\n return vertical;\n}\n\nexport function isRtl(\n cascaded: { [key: string]: CascadeValue },\n context: Exprs.Context,\n rtl: boolean,\n): boolean {\n const directionCasc = cascaded[\"direction\"];\n if (directionCasc) {\n const direction = directionCasc.evaluate(context, \"direction\");\n if (direction && direction !== Css.ident.inherit) {\n return direction === Css.ident.rtl;\n }\n }\n return rtl;\n}\n\nexport function flattenCascadedStyle(\n style: ElementStyle,\n context: Exprs.Context,\n regionIds: string[],\n isFootnote: boolean,\n nodeContext: Vtree.NodeContext,\n): { [key: string]: CascadeValue } {\n const cascMap = {} as { [key: string]: CascadeValue };\n for (const n in style) {\n if (isPropName(n)) {\n cascMap[n] = getProp(style, n);\n }\n }\n mergeViewConditionalStyles(cascMap, context, style);\n forEachStylesInRegion(\n style,\n regionIds,\n isFootnote,\n (regionId, regionStyle) => {\n mergeStyle(cascMap, regionStyle, context);\n mergeViewConditionalStyles(cascMap, context, regionStyle);\n },\n );\n return cascMap;\n}\n\nexport function forEachStylesInRegion(\n style: ElementStyle,\n regionIds: string[],\n isFootnote: boolean,\n callback: (p1: string, p2: ElementStyle) => any,\n): void {\n const regions = getStyleMap(style, \"_regions\");\n if ((regionIds || isFootnote) && regions) {\n if (isFootnote) {\n const footnoteRegion = [\"footnote\"];\n if (!regionIds) {\n regionIds = footnoteRegion;\n } else {\n regionIds = regionIds.concat(footnoteRegion);\n }\n }\n for (const regionId of regionIds) {\n const regionStyle = regions[regionId];\n if (regionStyle) {\n callback(regionId, regionStyle);\n }\n }\n }\n}\n\nexport function mergeStyle(\n to: { [key: string]: CascadeValue },\n from: ElementStyle,\n context: Exprs.Context,\n): void {\n for (const property in from) {\n if (isPropName(property)) {\n const newVal = getProp(from, property);\n const oldVal = to[property];\n to[property] = cascadeValues(context, oldVal, newVal as CascadeValue);\n }\n }\n}\n\n/**\n * Convert logical properties to physical ones, taking specificity into account.\n * @param src Source properties map\n * @param dest Destination map\n * @param transform If supplied, property values are transformed by this\n * function before inserted into the destination map. The first parameter is\n * the property name and the second one is the property value.\n * @template T\n */\nexport const convertToPhysical = <T>(\n src: { [key: string]: CascadeValue },\n dest: { [key: string]: T },\n vertical: boolean,\n rtl: boolean,\n transform: (p1: string, p2: CascadeValue) => T,\n) => {\n const couplingMap = vertical\n ? rtl\n ? couplingMapVertRtl\n : couplingMapVert\n : rtl\n ? couplingMapHorRtl\n : couplingMapHor;\n for (const propName in src) {\n if (src.hasOwnProperty(propName)) {\n const cascVal = src[propName];\n if (!cascVal) {\n continue;\n }\n const coupledName = couplingMap[propName];\n let targetName: string;\n if (coupledName) {\n const coupledCascVal = src[coupledName];\n if (coupledCascVal && coupledCascVal.priority > cascVal.priority) {\n continue;\n }\n targetName = geomNames[coupledName] ? coupledName : propName;\n } else {\n targetName = propName;\n }\n dest[targetName] = transform(propName, cascVal);\n }\n }\n};\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssLogicalUtil - Utilities related to CSS Logical Properties and Values https://drafts.csswg.org/css-logical/\n */\ntype ConversionMap = {\n regexp: RegExp;\n to: string;\n};\n\nfunction createRegExpMap(\n valueMaps: {\n [key: string]: { [key: string]: { logical: string; physical: string }[] };\n },\n toPhysical: boolean,\n): { [key: string]: { [key: string]: ConversionMap[] } } {\n const map = {};\n Object.keys(valueMaps as object).forEach((writingMode) => {\n const dest = (map[writingMode] = {});\n const src = valueMaps[writingMode];\n Object.keys(src as object).forEach((direction) => {\n dest[direction] = src[direction].map((p) => {\n const from = toPhysical ? p.logical : p.physical;\n const to = toPhysical ? p.physical : p.logical;\n return { regexp: new RegExp(`(-?)${from}(-?)`), to: `\\$1${to}\\$2` };\n });\n });\n });\n return map;\n}\n\nfunction convert(\n value: string,\n writingMode: string,\n direction: string | null,\n maps: { [key: string]: { [key: string]: ConversionMap[] } },\n): string {\n const maps2 = maps[writingMode];\n if (!maps2) {\n throw new Error(`unknown writing-mode: ${writingMode}`);\n }\n const map = maps2[direction || \"ltr\"];\n if (!map) {\n throw new Error(`unknown direction: ${direction}`);\n }\n for (const p of map) {\n const replaced = value.replace(p.regexp, p.to);\n if (replaced !== value) {\n return replaced;\n }\n }\n return value;\n}\nconst values: {\n [key: string]: { [key: string]: { logical: string; physical: string }[] };\n} = {\n \"horizontal-tb\": {\n ltr: [\n { logical: \"inline-start\", physical: \"left\" },\n { logical: \"inline-end\", physical: \"right\" },\n { logical: \"block-start\", physical: \"top\" },\n { logical: \"block-end\", physical: \"bottom\" },\n { logical: \"inline-size\", physical: \"width\" },\n { logical: \"block-size\", physical: \"height\" },\n ],\n rtl: [\n { logical: \"inline-start\", physical: \"right\" },\n { logical: \"inline-end\", physical: \"left\" },\n { logical: \"block-start\", physical: \"top\" },\n { logical: \"block-end\", physical: \"bottom\" },\n { logical: \"inline-size\", physical: \"width\" },\n { logical: \"block-size\", physical: \"height\" },\n ],\n },\n \"vertical-rl\": {\n ltr: [\n { logical: \"inline-start\", physical: \"top\" },\n { logical: \"inline-end\", physical: \"bottom\" },\n { logical: \"block-start\", physical: \"right\" },\n { logical: \"block-end\", physical: \"left\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n rtl: [\n { logical: \"inline-start\", physical: \"bottom\" },\n { logical: \"inline-end\", physical: \"top\" },\n { logical: \"block-start\", physical: \"right\" },\n { logical: \"block-end\", physical: \"left\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n },\n \"vertical-lr\": {\n ltr: [\n { logical: \"inline-start\", physical: \"top\" },\n { logical: \"inline-end\", physical: \"bottom\" },\n { logical: \"block-start\", physical: \"left\" },\n { logical: \"block-end\", physical: \"right\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n rtl: [\n { logical: \"inline-start\", physical: \"bottom\" },\n { logical: \"inline-end\", physical: \"top\" },\n { logical: \"block-start\", physical: \"left\" },\n { logical: \"block-end\", physical: \"right\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n },\n};\nconst toPhysicalMaps = createRegExpMap(values, true);\n\nexport function toPhysical(\n value: string,\n writingMode: string,\n direction?: string | null,\n): string {\n return convert(value, writingMode, direction || null, toPhysicalMaps);\n}\nconst toLogicalMaps = createRegExpMap(values, false);\n\nexport function toLogical(\n value: string,\n writingMode: string,\n direction?: string | null,\n): string {\n return convert(value, writingMode, direction || null, toLogicalMaps);\n}\nconst lineRelativeValues: {\n [key: string]: { logical: string; physical: string }[];\n} = {\n \"horizontal-tb\": [\n { logical: \"line-left\", physical: \"left\" },\n { logical: \"line-right\", physical: \"right\" },\n { logical: \"over\", physical: \"top\" },\n { logical: \"under\", physical: \"bottom\" },\n ],\n \"vertical-rl\": [\n { logical: \"line-left\", physical: \"top\" },\n { logical: \"line-right\", physical: \"bottom\" },\n { logical: \"over\", physical: \"right\" },\n { logical: \"under\", physical: \"left\" },\n ],\n \"vertical-lr\": [\n { logical: \"line-left\", physical: \"top\" },\n { logical: \"line-right\", physical: \"bottom\" },\n { logical: \"over\", physical: \"right\" },\n { logical: \"under\", physical: \"left\" },\n ],\n};\n\nexport function toLineRelative(value: string, writingMode: string): string {\n const maps = lineRelativeValues[writingMode];\n if (!maps) {\n throw new Error(`unknown writing-mode: ${writingMode}`);\n }\n for (let i = 0; i < maps.length; i++) {\n if (maps[i].physical === value) {\n return maps[i].logical;\n }\n }\n return value;\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Sizing - CSS Intrinsic & Extrinsic Sizing\n */\nimport * as Base from \"./base\";\nimport * as Vtree from \"./vtree\";\n\n/**\n * Box sizes defined in css-sizing.\n * @enum {string}\n */\nexport enum Size {\n FILL_AVAILABLE_INLINE_SIZE = \"fill-available inline size\",\n FILL_AVAILABLE_BLOCK_SIZE = \"fill-available block size\",\n FILL_AVAILABLE_WIDTH = \"fill-available width\",\n FILL_AVAILABLE_HEIGHT = \"fill-available height\",\n MAX_CONTENT_INLINE_SIZE = \"max-content inline size\",\n MAX_CONTENT_BLOCK_SIZE = \"max-content block size\",\n MAX_CONTENT_WIDTH = \"max-content width\",\n MAX_CONTENT_HEIGHT = \"max-content height\",\n MIN_CONTENT_INLINE_SIZE = \"min-content inline size\",\n MIN_CONTENT_BLOCK_SIZE = \"min-content block size\",\n MIN_CONTENT_WIDTH = \"min-content width\",\n MIN_CONTENT_HEIGHT = \"min-content height\",\n FIT_CONTENT_INLINE_SIZE = \"fit-content inline size\",\n FIT_CONTENT_BLOCK_SIZE = \"fit-content block size\",\n FIT_CONTENT_WIDTH = \"fit-content width\",\n FIT_CONTENT_HEIGHT = \"fit-content height\",\n}\n\n/**\n * Get specified sizes for the element.\n */\nexport function getSize(\n clientLayout: Vtree.ClientLayout,\n element: Element,\n sizes: Size[],\n): { [key in Size]: number } {\n const original = {\n display: (element as any).style.display,\n position: (element as any).style.position,\n width: (element as any).style.width as string,\n maxWidth: (element as any).style.maxWidth as string,\n minWidth: (element as any).style.minWidth as string,\n height: (element as any).style.height as string,\n maxHeight: (element as any).style.maxHeight as string,\n minHeight: (element as any).style.minHeight as string,\n };\n const doc = element.ownerDocument;\n const parent = element.parentNode;\n\n // wrap the element with a dummy container element\n const container = doc.createElement(\"div\");\n Base.setCSSProperty(container, \"position\", original.position);\n parent.insertBefore(container, element);\n container.appendChild(element);\n Base.setCSSProperty(element, \"width\", \"auto\");\n Base.setCSSProperty(element, \"max-width\", \"none\");\n Base.setCSSProperty(element, \"min-width\", \"0\");\n Base.setCSSProperty(element, \"height\", \"auto\");\n Base.setCSSProperty(element, \"max-height\", \"none\");\n Base.setCSSProperty(element, \"min-height\", \"0\");\n\n function getComputedValue(name: string): string {\n return clientLayout.getElementComputedStyle(element).getPropertyValue(name);\n }\n const writingModeProperty = Base.getPrefixedPropertyNames(\"writing-mode\");\n const writingModeValue =\n (writingModeProperty ? getComputedValue(writingModeProperty[0]) : null) ||\n getComputedValue(\"writing-mode\");\n const isVertical =\n writingModeValue === \"vertical-rl\" ||\n writingModeValue === \"tb-rl\" ||\n writingModeValue === \"vertical-lr\" ||\n writingModeValue === \"tb-lr\";\n const inlineSizeName = isVertical ? \"height\" : \"width\";\n const blockSizeName = isVertical ? \"width\" : \"height\";\n\n function getFillAvailableInline(): string {\n Base.setCSSProperty(element, \"display\", \"block\");\n Base.setCSSProperty(element, \"position\", \"static\");\n return getComputedValue(inlineSizeName);\n }\n\n // Inline size of an inline-block element is the fit-content\n // (shrink-to-fit) inline size.\n function getMaxContentInline(): string {\n Base.setCSSProperty(element, \"display\", \"inline-block\");\n\n // When the available inline size is sufficiently large, the fit-content\n // inline size equals to the max-content inline size.\n Base.setCSSProperty(container, inlineSizeName, \"99999999px\"); // 'sufficiently large' value\n const r = getComputedValue(inlineSizeName);\n Base.setCSSProperty(container, inlineSizeName, \"\");\n return r;\n }\n\n function getMinContentInline(): string {\n Base.setCSSProperty(element, \"display\", \"inline-block\");\n\n // When the available inline size is zero, the fit-content inline size\n // equals to the min-content inline size.\n Base.setCSSProperty(container, inlineSizeName, \"0\");\n const r = getComputedValue(inlineSizeName);\n Base.setCSSProperty(container, inlineSizeName, \"\");\n return r;\n }\n\n function getFitContentInline(): string {\n const fillAvailableInline = getFillAvailableInline();\n const minContentInline = getMinContentInline();\n const parsedFillAvailable = parseFloat(fillAvailableInline);\n if (parsedFillAvailable <= parseFloat(minContentInline)) {\n return minContentInline;\n } else {\n const maxContentInline = getMaxContentInline();\n if (parsedFillAvailable <= parseFloat(maxContentInline)) {\n return fillAvailableInline;\n } else {\n return maxContentInline;\n }\n }\n }\n\n function getIdealBlock(): string {\n return getComputedValue(blockSizeName);\n }\n\n function getFillAvailableBlock(): string {\n throw new Error(\"Getting fill-available block size is not implemented\");\n }\n const result = {} as { [key in Size]: number };\n sizes.forEach((size) => {\n let r: string;\n switch (size) {\n case Size.FILL_AVAILABLE_INLINE_SIZE:\n r = getFillAvailableInline();\n break;\n case Size.MAX_CONTENT_INLINE_SIZE:\n r = getMaxContentInline();\n break;\n case Size.MIN_CONTENT_INLINE_SIZE:\n r = getMinContentInline();\n break;\n case Size.FIT_CONTENT_INLINE_SIZE:\n r = getFitContentInline();\n break;\n case Size.FILL_AVAILABLE_BLOCK_SIZE:\n r = getFillAvailableBlock();\n break;\n case Size.MAX_CONTENT_BLOCK_SIZE:\n case Size.MIN_CONTENT_BLOCK_SIZE:\n case Size.FIT_CONTENT_BLOCK_SIZE:\n r = getIdealBlock();\n break;\n case Size.FILL_AVAILABLE_WIDTH:\n r = isVertical ? getFillAvailableBlock() : getFillAvailableInline();\n break;\n case Size.FILL_AVAILABLE_HEIGHT:\n r = isVertical ? getFillAvailableInline() : getFillAvailableBlock();\n break;\n case Size.MAX_CONTENT_WIDTH:\n r = isVertical ? getIdealBlock() : getMaxContentInline();\n break;\n case Size.MAX_CONTENT_HEIGHT:\n r = isVertical ? getMaxContentInline() : getIdealBlock();\n break;\n case Size.MIN_CONTENT_WIDTH:\n r = isVertical ? getIdealBlock() : getMinContentInline();\n break;\n case Size.MIN_CONTENT_HEIGHT:\n r = isVertical ? getMinContentInline() : getIdealBlock();\n break;\n case Size.FIT_CONTENT_WIDTH:\n r = isVertical ? getIdealBlock() : getFitContentInline();\n break;\n case Size.FIT_CONTENT_HEIGHT:\n r = isVertical ? getFitContentInline() : getIdealBlock();\n break;\n }\n result[size] = parseFloat(r);\n Base.setCSSProperty(element, \"position\", original.position);\n Base.setCSSProperty(element, \"display\", original.display);\n });\n Base.setCSSProperty(element, \"width\", original.width);\n Base.setCSSProperty(element, \"max-width\", original.maxWidth);\n Base.setCSSProperty(element, \"min-width\", original.minWidth);\n Base.setCSSProperty(element, \"height\", original.height);\n Base.setCSSProperty(element, \"max-height\", original.maxHeight);\n Base.setCSSProperty(element, \"min-height\", original.minHeight);\n parent.insertBefore(element, container);\n parent.removeChild(container);\n return result;\n}\n","/**\n * This library modifies the diff-patch-match library by Neil Fraser\n * by removing the patch and match functionality and certain advanced\n * options in the diff function. The original license is as follows:\n *\n * ===\n *\n * Diff Match and Patch\n *\n * Copyright 2006 Google Inc.\n * http://code.google.com/p/google-diff-match-patch/\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/**\n * The data structure representing a diff is an array of tuples:\n * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]\n * which means: delete 'Hello', add 'Goodbye' and keep ' world.'\n */\nvar DIFF_DELETE = -1;\nvar DIFF_INSERT = 1;\nvar DIFF_EQUAL = 0;\n\n\n/**\n * Find the differences between two texts. Simplifies the problem by stripping\n * any common prefix or suffix off the texts before diffing.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {Int|Object} [cursor_pos] Edit position in text1 or object with more info\n * @return {Array} Array of diff tuples.\n */\nfunction diff_main(text1, text2, cursor_pos, _fix_unicode) {\n // Check for equality\n if (text1 === text2) {\n if (text1) {\n return [[DIFF_EQUAL, text1]];\n }\n return [];\n }\n\n if (cursor_pos != null) {\n var editdiff = find_cursor_edit_diff(text1, text2, cursor_pos);\n if (editdiff) {\n return editdiff;\n }\n }\n\n // Trim off common prefix (speedup).\n var commonlength = diff_commonPrefix(text1, text2);\n var commonprefix = text1.substring(0, commonlength);\n text1 = text1.substring(commonlength);\n text2 = text2.substring(commonlength);\n\n // Trim off common suffix (speedup).\n commonlength = diff_commonSuffix(text1, text2);\n var commonsuffix = text1.substring(text1.length - commonlength);\n text1 = text1.substring(0, text1.length - commonlength);\n text2 = text2.substring(0, text2.length - commonlength);\n\n // Compute the diff on the middle block.\n var diffs = diff_compute_(text1, text2);\n\n // Restore the prefix and suffix.\n if (commonprefix) {\n diffs.unshift([DIFF_EQUAL, commonprefix]);\n }\n if (commonsuffix) {\n diffs.push([DIFF_EQUAL, commonsuffix]);\n }\n diff_cleanupMerge(diffs, _fix_unicode);\n return diffs;\n};\n\n\n/**\n * Find the differences between two texts. Assumes that the texts do not\n * have any common prefix or suffix.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @return {Array} Array of diff tuples.\n */\nfunction diff_compute_(text1, text2) {\n var diffs;\n\n if (!text1) {\n // Just add some text (speedup).\n return [[DIFF_INSERT, text2]];\n }\n\n if (!text2) {\n // Just delete some text (speedup).\n return [[DIFF_DELETE, text1]];\n }\n\n var longtext = text1.length > text2.length ? text1 : text2;\n var shorttext = text1.length > text2.length ? text2 : text1;\n var i = longtext.indexOf(shorttext);\n if (i !== -1) {\n // Shorter text is inside the longer text (speedup).\n diffs = [\n [DIFF_INSERT, longtext.substring(0, i)],\n [DIFF_EQUAL, shorttext],\n [DIFF_INSERT, longtext.substring(i + shorttext.length)]\n ];\n // Swap insertions for deletions if diff is reversed.\n if (text1.length > text2.length) {\n diffs[0][0] = diffs[2][0] = DIFF_DELETE;\n }\n return diffs;\n }\n\n if (shorttext.length === 1) {\n // Single character string.\n // After the previous speedup, the character can't be an equality.\n return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n }\n\n // Check to see if the problem can be split in two.\n var hm = diff_halfMatch_(text1, text2);\n if (hm) {\n // A half-match was found, sort out the return data.\n var text1_a = hm[0];\n var text1_b = hm[1];\n var text2_a = hm[2];\n var text2_b = hm[3];\n var mid_common = hm[4];\n // Send both pairs off for separate processing.\n var diffs_a = diff_main(text1_a, text2_a);\n var diffs_b = diff_main(text1_b, text2_b);\n // Merge the results.\n return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b);\n }\n\n return diff_bisect_(text1, text2);\n};\n\n\n/**\n * Find the 'middle snake' of a diff, split the problem in two\n * and return the recursively constructed diff.\n * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @return {Array} Array of diff tuples.\n * @private\n */\nfunction diff_bisect_(text1, text2) {\n // Cache the text lengths to prevent multiple calls.\n var text1_length = text1.length;\n var text2_length = text2.length;\n var max_d = Math.ceil((text1_length + text2_length) / 2);\n var v_offset = max_d;\n var v_length = 2 * max_d;\n var v1 = new Array(v_length);\n var v2 = new Array(v_length);\n // Setting all elements to -1 is faster in Chrome & Firefox than mixing\n // integers and undefined.\n for (var x = 0; x < v_length; x++) {\n v1[x] = -1;\n v2[x] = -1;\n }\n v1[v_offset + 1] = 0;\n v2[v_offset + 1] = 0;\n var delta = text1_length - text2_length;\n // If the total number of characters is odd, then the front path will collide\n // with the reverse path.\n var front = (delta % 2 !== 0);\n // Offsets for start and end of k loop.\n // Prevents mapping of space beyond the grid.\n var k1start = 0;\n var k1end = 0;\n var k2start = 0;\n var k2end = 0;\n for (var d = 0; d < max_d; d++) {\n // Walk the front path one step.\n for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {\n var k1_offset = v_offset + k1;\n var x1;\n if (k1 === -d || (k1 !== d && v1[k1_offset - 1] < v1[k1_offset + 1])) {\n x1 = v1[k1_offset + 1];\n } else {\n x1 = v1[k1_offset - 1] + 1;\n }\n var y1 = x1 - k1;\n while (\n x1 < text1_length && y1 < text2_length &&\n text1.charAt(x1) === text2.charAt(y1)\n ) {\n x1++;\n y1++;\n }\n v1[k1_offset] = x1;\n if (x1 > text1_length) {\n // Ran off the right of the graph.\n k1end += 2;\n } else if (y1 > text2_length) {\n // Ran off the bottom of the graph.\n k1start += 2;\n } else if (front) {\n var k2_offset = v_offset + delta - k1;\n if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] !== -1) {\n // Mirror x2 onto top-left coordinate system.\n var x2 = text1_length - v2[k2_offset];\n if (x1 >= x2) {\n // Overlap detected.\n return diff_bisectSplit_(text1, text2, x1, y1);\n }\n }\n }\n }\n\n // Walk the reverse path one step.\n for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {\n var k2_offset = v_offset + k2;\n var x2;\n if (k2 === -d || (k2 !== d && v2[k2_offset - 1] < v2[k2_offset + 1])) {\n x2 = v2[k2_offset + 1];\n } else {\n x2 = v2[k2_offset - 1] + 1;\n }\n var y2 = x2 - k2;\n while (\n x2 < text1_length && y2 < text2_length &&\n text1.charAt(text1_length - x2 - 1) === text2.charAt(text2_length - y2 - 1)\n ) {\n x2++;\n y2++;\n }\n v2[k2_offset] = x2;\n if (x2 > text1_length) {\n // Ran off the left of the graph.\n k2end += 2;\n } else if (y2 > text2_length) {\n // Ran off the top of the graph.\n k2start += 2;\n } else if (!front) {\n var k1_offset = v_offset + delta - k2;\n if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] !== -1) {\n var x1 = v1[k1_offset];\n var y1 = v_offset + x1 - k1_offset;\n // Mirror x2 onto top-left coordinate system.\n x2 = text1_length - x2;\n if (x1 >= x2) {\n // Overlap detected.\n return diff_bisectSplit_(text1, text2, x1, y1);\n }\n }\n }\n }\n }\n // Diff took too long and hit the deadline or\n // number of diffs equals number of characters, no commonality at all.\n return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n};\n\n\n/**\n * Given the location of the 'middle snake', split the diff in two parts\n * and recurse.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} x Index of split point in text1.\n * @param {number} y Index of split point in text2.\n * @return {Array} Array of diff tuples.\n */\nfunction diff_bisectSplit_(text1, text2, x, y) {\n var text1a = text1.substring(0, x);\n var text2a = text2.substring(0, y);\n var text1b = text1.substring(x);\n var text2b = text2.substring(y);\n\n // Compute both diffs serially.\n var diffs = diff_main(text1a, text2a);\n var diffsb = diff_main(text1b, text2b);\n\n return diffs.concat(diffsb);\n};\n\n\n/**\n * Determine the common prefix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the start of each\n * string.\n */\nfunction diff_commonPrefix(text1, text2) {\n // Quick check for common null cases.\n if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) {\n return 0;\n }\n // Binary search.\n // Performance analysis: http://neil.fraser.name/news/2007/10/09/\n var pointermin = 0;\n var pointermax = Math.min(text1.length, text2.length);\n var pointermid = pointermax;\n var pointerstart = 0;\n while (pointermin < pointermid) {\n if (\n text1.substring(pointerstart, pointermid) ==\n text2.substring(pointerstart, pointermid)\n ) {\n pointermin = pointermid;\n pointerstart = pointermin;\n } else {\n pointermax = pointermid;\n }\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n\n if (is_surrogate_pair_start(text1.charCodeAt(pointermid - 1))) {\n pointermid--;\n }\n\n return pointermid;\n};\n\n\n/**\n * Determine the common suffix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of each string.\n */\nfunction diff_commonSuffix(text1, text2) {\n // Quick check for common null cases.\n if (!text1 || !text2 || text1.slice(-1) !== text2.slice(-1)) {\n return 0;\n }\n // Binary search.\n // Performance analysis: http://neil.fraser.name/news/2007/10/09/\n var pointermin = 0;\n var pointermax = Math.min(text1.length, text2.length);\n var pointermid = pointermax;\n var pointerend = 0;\n while (pointermin < pointermid) {\n if (\n text1.substring(text1.length - pointermid, text1.length - pointerend) ==\n text2.substring(text2.length - pointermid, text2.length - pointerend)\n ) {\n pointermin = pointermid;\n pointerend = pointermin;\n } else {\n pointermax = pointermid;\n }\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n\n if (is_surrogate_pair_end(text1.charCodeAt(text1.length - pointermid))) {\n pointermid--;\n }\n\n return pointermid;\n};\n\n\n/**\n * Do the two texts share a substring which is at least half the length of the\n * longer text?\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {Array.<string>} Five element Array, containing the prefix of\n * text1, the suffix of text1, the prefix of text2, the suffix of\n * text2 and the common middle. Or null if there was no match.\n */\nfunction diff_halfMatch_(text1, text2) {\n var longtext = text1.length > text2.length ? text1 : text2;\n var shorttext = text1.length > text2.length ? text2 : text1;\n if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {\n return null; // Pointless.\n }\n\n /**\n * Does a substring of shorttext exist within longtext such that the substring\n * is at least half the length of longtext?\n * Closure, but does not reference any external variables.\n * @param {string} longtext Longer string.\n * @param {string} shorttext Shorter string.\n * @param {number} i Start index of quarter length substring within longtext.\n * @return {Array.<string>} Five element Array, containing the prefix of\n * longtext, the suffix of longtext, the prefix of shorttext, the suffix\n * of shorttext and the common middle. Or null if there was no match.\n * @private\n */\n function diff_halfMatchI_(longtext, shorttext, i) {\n // Start with a 1/4 length substring at position i as a seed.\n var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));\n var j = -1;\n var best_common = '';\n var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;\n while ((j = shorttext.indexOf(seed, j + 1)) !== -1) {\n var prefixLength = diff_commonPrefix(\n longtext.substring(i), shorttext.substring(j));\n var suffixLength = diff_commonSuffix(\n longtext.substring(0, i), shorttext.substring(0, j));\n if (best_common.length < suffixLength + prefixLength) {\n best_common = shorttext.substring(\n j - suffixLength, j) + shorttext.substring(j, j + prefixLength);\n best_longtext_a = longtext.substring(0, i - suffixLength);\n best_longtext_b = longtext.substring(i + prefixLength);\n best_shorttext_a = shorttext.substring(0, j - suffixLength);\n best_shorttext_b = shorttext.substring(j + prefixLength);\n }\n }\n if (best_common.length * 2 >= longtext.length) {\n return [\n best_longtext_a, best_longtext_b,\n best_shorttext_a, best_shorttext_b, best_common\n ];\n } else {\n return null;\n }\n }\n\n // First check if the second quarter is the seed for a half-match.\n var hm1 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 4));\n // Check again based on the third quarter.\n var hm2 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 2));\n var hm;\n if (!hm1 && !hm2) {\n return null;\n } else if (!hm2) {\n hm = hm1;\n } else if (!hm1) {\n hm = hm2;\n } else {\n // Both matched. Select the longest.\n hm = hm1[4].length > hm2[4].length ? hm1 : hm2;\n }\n\n // A half-match was found, sort out the return data.\n var text1_a, text1_b, text2_a, text2_b;\n if (text1.length > text2.length) {\n text1_a = hm[0];\n text1_b = hm[1];\n text2_a = hm[2];\n text2_b = hm[3];\n } else {\n text2_a = hm[0];\n text2_b = hm[1];\n text1_a = hm[2];\n text1_b = hm[3];\n }\n var mid_common = hm[4];\n return [text1_a, text1_b, text2_a, text2_b, mid_common];\n};\n\n\n/**\n * Reorder and merge like edit sections. Merge equalities.\n * Any edit section can move as long as it doesn't cross an equality.\n * @param {Array} diffs Array of diff tuples.\n * @param {boolean} fix_unicode Whether to normalize to a unicode-correct diff\n */\nfunction diff_cleanupMerge(diffs, fix_unicode) {\n diffs.push([DIFF_EQUAL, '']); // Add a dummy entry at the end.\n var pointer = 0;\n var count_delete = 0;\n var count_insert = 0;\n var text_delete = '';\n var text_insert = '';\n var commonlength;\n while (pointer < diffs.length) {\n if (pointer < diffs.length - 1 && !diffs[pointer][1]) {\n diffs.splice(pointer, 1);\n continue;\n }\n switch (diffs[pointer][0]) {\n case DIFF_INSERT:\n\n count_insert++;\n text_insert += diffs[pointer][1];\n pointer++;\n break;\n case DIFF_DELETE:\n count_delete++;\n text_delete += diffs[pointer][1];\n pointer++;\n break;\n case DIFF_EQUAL:\n var previous_equality = pointer - count_insert - count_delete - 1;\n if (fix_unicode) {\n // prevent splitting of unicode surrogate pairs. when fix_unicode is true,\n // we assume that the old and new text in the diff are complete and correct\n // unicode-encoded JS strings, but the tuple boundaries may fall between\n // surrogate pairs. we fix this by shaving off stray surrogates from the end\n // of the previous equality and the beginning of this equality. this may create\n // empty equalities or a common prefix or suffix. for example, if AB and AC are\n // emojis, `[[0, 'A'], [-1, 'BA'], [0, 'C']]` would turn into deleting 'ABAC' and\n // inserting 'AC', and then the common suffix 'AC' will be eliminated. in this\n // particular case, both equalities go away, we absorb any previous inequalities,\n // and we keep scanning for the next equality before rewriting the tuples.\n if (previous_equality >= 0 && ends_with_pair_start(diffs[previous_equality][1])) {\n var stray = diffs[previous_equality][1].slice(-1);\n diffs[previous_equality][1] = diffs[previous_equality][1].slice(0, -1);\n text_delete = stray + text_delete;\n text_insert = stray + text_insert;\n if (!diffs[previous_equality][1]) {\n // emptied out previous equality, so delete it and include previous delete/insert\n diffs.splice(previous_equality, 1);\n pointer--;\n var k = previous_equality - 1;\n if (diffs[k] && diffs[k][0] === DIFF_INSERT) {\n count_insert++;\n text_insert = diffs[k][1] + text_insert;\n k--;\n }\n if (diffs[k] && diffs[k][0] === DIFF_DELETE) {\n count_delete++;\n text_delete = diffs[k][1] + text_delete;\n k--;\n }\n previous_equality = k;\n }\n }\n if (starts_with_pair_end(diffs[pointer][1])) {\n var stray = diffs[pointer][1].charAt(0);\n diffs[pointer][1] = diffs[pointer][1].slice(1);\n text_delete += stray;\n text_insert += stray;\n }\n }\n if (pointer < diffs.length - 1 && !diffs[pointer][1]) {\n // for empty equality not at end, wait for next equality\n diffs.splice(pointer, 1);\n break;\n }\n if (text_delete.length > 0 || text_insert.length > 0) {\n // note that diff_commonPrefix and diff_commonSuffix are unicode-aware\n if (text_delete.length > 0 && text_insert.length > 0) {\n // Factor out any common prefixes.\n commonlength = diff_commonPrefix(text_insert, text_delete);\n if (commonlength !== 0) {\n if (previous_equality >= 0) {\n diffs[previous_equality][1] += text_insert.substring(0, commonlength);\n } else {\n diffs.splice(0, 0, [DIFF_EQUAL, text_insert.substring(0, commonlength)]);\n pointer++;\n }\n text_insert = text_insert.substring(commonlength);\n text_delete = text_delete.substring(commonlength);\n }\n // Factor out any common suffixes.\n commonlength = diff_commonSuffix(text_insert, text_delete);\n if (commonlength !== 0) {\n diffs[pointer][1] =\n text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1];\n text_insert = text_insert.substring(0, text_insert.length - commonlength);\n text_delete = text_delete.substring(0, text_delete.length - commonlength);\n }\n }\n // Delete the offending records and add the merged ones.\n var n = count_insert + count_delete;\n if (text_delete.length === 0 && text_insert.length === 0) {\n diffs.splice(pointer - n, n);\n pointer = pointer - n;\n } else if (text_delete.length === 0) {\n diffs.splice(pointer - n, n, [DIFF_INSERT, text_insert]);\n pointer = pointer - n + 1;\n } else if (text_insert.length === 0) {\n diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete]);\n pointer = pointer - n + 1;\n } else {\n diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete], [DIFF_INSERT, text_insert]);\n pointer = pointer - n + 2;\n }\n }\n if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {\n // Merge this equality with the previous one.\n diffs[pointer - 1][1] += diffs[pointer][1];\n diffs.splice(pointer, 1);\n } else {\n pointer++;\n }\n count_insert = 0;\n count_delete = 0;\n text_delete = '';\n text_insert = '';\n break;\n }\n }\n if (diffs[diffs.length - 1][1] === '') {\n diffs.pop(); // Remove the dummy entry at the end.\n }\n\n // Second pass: look for single edits surrounded on both sides by equalities\n // which can be shifted sideways to eliminate an equality.\n // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC\n var changes = false;\n pointer = 1;\n // Intentionally ignore the first and last element (don't need checking).\n while (pointer < diffs.length - 1) {\n if (diffs[pointer - 1][0] === DIFF_EQUAL &&\n diffs[pointer + 1][0] === DIFF_EQUAL) {\n // This is a single edit surrounded by equalities.\n if (diffs[pointer][1].substring(diffs[pointer][1].length -\n diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) {\n // Shift the edit over the previous equality.\n diffs[pointer][1] = diffs[pointer - 1][1] +\n diffs[pointer][1].substring(0, diffs[pointer][1].length -\n diffs[pointer - 1][1].length);\n diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];\n diffs.splice(pointer - 1, 1);\n changes = true;\n } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) ==\n diffs[pointer + 1][1]) {\n // Shift the edit over the next equality.\n diffs[pointer - 1][1] += diffs[pointer + 1][1];\n diffs[pointer][1] =\n diffs[pointer][1].substring(diffs[pointer + 1][1].length) +\n diffs[pointer + 1][1];\n diffs.splice(pointer + 1, 1);\n changes = true;\n }\n }\n pointer++;\n }\n // If shifts were made, the diff needs reordering and another shift sweep.\n if (changes) {\n diff_cleanupMerge(diffs, fix_unicode);\n }\n};\n\nfunction is_surrogate_pair_start(charCode) {\n return charCode >= 0xD800 && charCode <= 0xDBFF;\n}\n\nfunction is_surrogate_pair_end(charCode) {\n return charCode >= 0xDC00 && charCode <= 0xDFFF;\n}\n\nfunction starts_with_pair_end(str) {\n return is_surrogate_pair_end(str.charCodeAt(0));\n}\n\nfunction ends_with_pair_start(str) {\n return is_surrogate_pair_start(str.charCodeAt(str.length - 1));\n}\n\nfunction remove_empty_tuples(tuples) {\n var ret = [];\n for (var i = 0; i < tuples.length; i++) {\n if (tuples[i][1].length > 0) {\n ret.push(tuples[i]);\n }\n }\n return ret;\n}\n\nfunction make_edit_splice(before, oldMiddle, newMiddle, after) {\n if (ends_with_pair_start(before) || starts_with_pair_end(after)) {\n return null;\n }\n return remove_empty_tuples([\n [DIFF_EQUAL, before],\n [DIFF_DELETE, oldMiddle],\n [DIFF_INSERT, newMiddle],\n [DIFF_EQUAL, after]\n ]);\n}\n\nfunction find_cursor_edit_diff(oldText, newText, cursor_pos) {\n // note: this runs after equality check has ruled out exact equality\n var oldRange = typeof cursor_pos === 'number' ?\n { index: cursor_pos, length: 0 } : cursor_pos.oldRange;\n var newRange = typeof cursor_pos === 'number' ?\n null : cursor_pos.newRange;\n // take into account the old and new selection to generate the best diff\n // possible for a text edit. for example, a text change from \"xxx\" to \"xx\"\n // could be a delete or forwards-delete of any one of the x's, or the\n // result of selecting two of the x's and typing \"x\".\n var oldLength = oldText.length;\n var newLength = newText.length;\n if (oldRange.length === 0 && (newRange === null || newRange.length === 0)) {\n // see if we have an insert or delete before or after cursor\n var oldCursor = oldRange.index;\n var oldBefore = oldText.slice(0, oldCursor);\n var oldAfter = oldText.slice(oldCursor);\n var maybeNewCursor = newRange ? newRange.index : null;\n editBefore: {\n // is this an insert or delete right before oldCursor?\n var newCursor = oldCursor + newLength - oldLength;\n if (maybeNewCursor !== null && maybeNewCursor !== newCursor) {\n break editBefore;\n }\n if (newCursor < 0 || newCursor > newLength) {\n break editBefore;\n }\n var newBefore = newText.slice(0, newCursor);\n var newAfter = newText.slice(newCursor);\n if (newAfter !== oldAfter) {\n break editBefore;\n }\n var prefixLength = Math.min(oldCursor, newCursor);\n var oldPrefix = oldBefore.slice(0, prefixLength);\n var newPrefix = newBefore.slice(0, prefixLength);\n if (oldPrefix !== newPrefix) {\n break editBefore;\n }\n var oldMiddle = oldBefore.slice(prefixLength);\n var newMiddle = newBefore.slice(prefixLength);\n return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldAfter);\n }\n editAfter: {\n // is this an insert or delete right after oldCursor?\n if (maybeNewCursor !== null && maybeNewCursor !== oldCursor) {\n break editAfter;\n }\n var cursor = oldCursor;\n var newBefore = newText.slice(0, cursor);\n var newAfter = newText.slice(cursor);\n if (newBefore !== oldBefore) {\n break editAfter;\n }\n var suffixLength = Math.min(oldLength - cursor, newLength - cursor);\n var oldSuffix = oldAfter.slice(oldAfter.length - suffixLength);\n var newSuffix = newAfter.slice(newAfter.length - suffixLength);\n if (oldSuffix !== newSuffix) {\n break editAfter;\n }\n var oldMiddle = oldAfter.slice(0, oldAfter.length - suffixLength);\n var newMiddle = newAfter.slice(0, newAfter.length - suffixLength);\n return make_edit_splice(oldBefore, oldMiddle, newMiddle, oldSuffix);\n }\n }\n if (oldRange.length > 0 && newRange && newRange.length === 0) {\n replaceRange: {\n // see if diff could be a splice of the old selection range\n var oldPrefix = oldText.slice(0, oldRange.index);\n var oldSuffix = oldText.slice(oldRange.index + oldRange.length);\n var prefixLength = oldPrefix.length;\n var suffixLength = oldSuffix.length;\n if (newLength < prefixLength + suffixLength) {\n break replaceRange;\n }\n var newPrefix = newText.slice(0, prefixLength);\n var newSuffix = newText.slice(newLength - suffixLength);\n if (oldPrefix !== newPrefix || oldSuffix !== newSuffix) {\n break replaceRange;\n }\n var oldMiddle = oldText.slice(prefixLength, oldLength - suffixLength);\n var newMiddle = newText.slice(prefixLength, newLength - suffixLength);\n return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldSuffix);\n }\n }\n\n return null;\n}\n\nfunction diff(text1, text2, cursor_pos) {\n // only pass fix_unicode=true at the top level, not when diff_main is\n // recursively invoked\n return diff_main(text1, text2, cursor_pos, true);\n}\n\ndiff.INSERT = DIFF_INSERT;\ndiff.DELETE = DIFF_DELETE;\ndiff.EQUAL = DIFF_EQUAL;\n\nmodule.exports = diff;\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Types - Type definiions.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as Diff from \"./diff\";\nimport * as Exprs from \"./exprs\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\n\nexport type FormattingContextType =\n | \"Block\"\n | \"RepetitiveElementsOwner\"\n | \"Table\";\n\nexport type FragmentLayoutConstraintType =\n | \"AfterIfContinue\"\n | \"EntireTable\"\n | \"RepetitiveElementsOwner\"\n | \"TableRow\";\n\nexport namespace CssCascade {\n export interface ElementStyle {}\n}\n\nexport namespace CssStyler {\n export interface AbstractStyler {\n getStyle(element: Element, deep: boolean): CssCascade.ElementStyle;\n processContent(element: Element, styles: { [key: string]: Css.Val });\n }\n}\n\nexport namespace Layout {\n /**\n * Represents a constraint on layout\n */\n export interface LayoutConstraint {\n /**\n * Returns if this constraint allows the node context to be laid out at the\n * current position.\n */\n allowLayout(nodeContext: Vtree.NodeContext): boolean;\n }\n /**\n * Represents constraints on laying out fragments\n */\n export interface FragmentLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType;\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Column,\n ): boolean;\n nextCandidate(nodeContext: Vtree.NodeContext): boolean;\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Column,\n );\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Column,\n ): Task.Result<boolean>;\n equalsTo(constraint: FragmentLayoutConstraint): boolean;\n getPriorityOfFinishBreak(): number;\n }\n\n /**\n * Potential breaking position.\n */\n export interface BreakPosition {\n /**\n * @return break position, if found\n */\n findAcceptableBreak(column: Column, penalty: number): Vtree.NodeContext;\n /**\n * @return penalty for this break position\n */\n getMinBreakPenalty(): number;\n calculateOffset(column: Column): { current: number; minimum: number };\n breakPositionChosen(column: Column): void;\n }\n\n export interface AbstractBreakPosition extends BreakPosition {\n getNodeContext(): Vtree.NodeContext;\n }\n\n export type BreakPositionAndNodeContext = {\n breakPosition: BreakPosition;\n nodeContext: Vtree.NodeContext;\n };\n\n /**\n * Potential breaking position inside CSS box (between lines).\n * @param checkPoints array of breaking points for\n * breakable block\n */\n export interface BoxBreakPosition extends AbstractBreakPosition {\n breakNodeContext: Vtree.NodeContext;\n readonly checkPoints: Vtree.NodeContext[];\n readonly penalty: number;\n }\n\n /**\n * Potential edge breaking position.\n */\n export interface EdgeBreakPosition extends AbstractBreakPosition {\n overflowIfRepetitiveElementsDropped: boolean;\n readonly position: Vtree.NodeContext;\n readonly breakOnEdge: string | null;\n overflows: boolean;\n readonly computedBlockSize: number;\n }\n\n export interface Column extends Vtree.Container {\n last: Node;\n viewDocument: Document;\n flowRootFormattingContext: Vtree.FormattingContext;\n isFloat: boolean;\n isFootnote: boolean;\n startEdge: number;\n endEdge: number;\n beforeEdge: number;\n afterEdge: number;\n footnoteEdge: number;\n box: GeometryUtil.Rect;\n chunkPositions: Vtree.ChunkPosition[];\n bands: GeometryUtil.Band[];\n overflown: boolean;\n breakPositions: BreakPosition[];\n pageBreakType: string | null;\n forceNonfitting: boolean;\n leftFloatEdge: number;\n /**\n * bottom of the bottommost left float\n */\n rightFloatEdge: number;\n /**\n * bottom of the bottommost right float\n */\n bottommostFloatTop: number;\n /**\n * Top of the bottommost float\n */\n stopAtOverflow: boolean;\n lastAfterPosition: Vtree.NodePosition | null;\n fragmentLayoutConstraints: FragmentLayoutConstraint[];\n pseudoParent: Column;\n nodeContextOverflowingDueToRepetitiveElements: Vtree.NodeContext | null;\n blockDistanceToBlockEndFloats: number;\n computedBlockSize: number;\n\n layoutContext: Vtree.LayoutContext;\n clientLayout: Vtree.ClientLayout;\n readonly layoutConstraint: LayoutConstraint;\n readonly pageFloatLayoutContext: PageFloats.PageFloatLayoutContext;\n\n getTopEdge(): number;\n getBottomEdge(): number;\n getLeftEdge(): number;\n getRightEdge(): number;\n isFloatNodeContext(nodeContext: Vtree.NodeContext): boolean;\n stopByOverflow(nodeContext: Vtree.NodeContext): boolean;\n isOverflown(edge: number): boolean;\n getExclusions(): GeometryUtil.Shape[];\n openAllViews(position: Vtree.NodePosition): Task.Result<Vtree.NodeContext>;\n calculateOffsetInNodeForNodeContext(position: Vtree.NodePosition): number;\n /**\n * @param count first-XXX nesting identifier\n */\n maybePeelOff(\n position: Vtree.NodeContext,\n count: number,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Builds the view until a CSS box edge is reached.\n * @param position start source position.\n * @param checkPoints array to append possible breaking points.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildViewToNextBlockEdge(\n position: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext>;\n nextInTree(\n position: Vtree.NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Builds the view for a single unbreakable element.\n * @param position start source position.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildDeepElementView(\n position: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * Create a single floating element (for exclusion areas).\n * @param ref container's child to insert float before (can be null).\n * @param side float side (\"left\" or \"right\").\n * @param width float inline dimension.\n * @param height float box progression dimension.\n * @return newly created float element.\n */\n createFloat(\n ref: Node,\n side: string,\n width: number,\n height: number,\n ): Element;\n /**\n * Remove all the exclusion floats.\n */\n killFloats(): void;\n /**\n * Create exclusion floats for a column.\n */\n createFloats(): void;\n /**\n * @param nodeContext position after the block\n * @param checkPoints array of possible breaking points.\n * @param index index of the breaking point\n * @param boxOffset box offset\n * @return edge position\n */\n calculateEdge(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n index: number,\n boxOffset: number,\n ): number;\n /**\n * Parse CSS computed length (in pixels)\n * @param val CSS length in \"px\" units or a number.\n * @return value in pixels or 0 if not parsable\n */\n parseComputedLength(val: string | number): number;\n /**\n * Reads element's computed CSS margin.\n */\n getComputedMargin(element: Element): GeometryUtil.Insets;\n /**\n * Reads element's computed padding + borders.\n */\n getComputedPaddingBorder(element: Element): GeometryUtil.Insets;\n /**\n * Reads element's computed CSS insets(margins + border + padding or margins :\n * depends on box-sizing)\n */\n getComputedInsets(element: Element): GeometryUtil.Insets;\n /**\n * Set element's computed CSS insets to Column Container\n */\n setComputedInsets(element: Element, container: Column): void;\n /**\n * Set element's computed width and height to Column Container\n */\n setComputedWidthAndHeight(element: Element, container: Column): void;\n /**\n * Layout a single unbreakable element.\n */\n layoutUnbreakable(\n nodeContextIn: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Layout a single float element.\n */\n layoutFloat(nodeContext: Vtree.NodeContext): Task.Result<Vtree.NodeContext>;\n\n setupFloatArea(\n area: PageFloatArea,\n floatReference: PageFloats.FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): boolean;\n createPageFloatArea(\n float: PageFloats.PageFloat | null,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): PageFloatArea | null;\n layoutSinglePageFloatFragment(\n continuations: PageFloats.PageFloatContinuation[],\n floatSide: string,\n clearSide: string | null,\n allowFragmented: boolean,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment | null,\n ): Task.Result<SinglePageFloatLayoutResult>;\n layoutPageFloatInner(\n continuation: PageFloats.PageFloatContinuation,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment,\n ): Task.Result<boolean>;\n setFloatAnchorViewNode(nodeContext: Vtree.NodeContext): Vtree.NodeContext;\n resolveFloatReferenceFromColumnSpan(\n floatReference: PageFloats.FloatReference,\n columnSpan: Css.Val,\n nodeContext: Vtree.NodeContext,\n ): Task.Result<PageFloats.FloatReference>;\n layoutPageFloat(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n createJustificationAdjustmentElement(\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n vertical: boolean,\n ): HTMLElement;\n addAndAdjustJustificationElement(\n nodeContext: Vtree.NodeContext,\n insertAfter: boolean,\n node: Node,\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n ): HTMLElement;\n compensateJustificationLineHeight(\n span: Element,\n br: Element,\n nodeContext: Vtree.NodeContext,\n ): void;\n /**\n * Fix justification of the last line of text broken across pages (if\n * needed).\n */\n fixJustificationIfNeeded(\n nodeContext: Vtree.NodeContext,\n endOfColumn: boolean,\n ): void;\n processLineStyling(\n nodeContext: Vtree.NodeContext,\n resNodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext>;\n isLoneImage(checkPoints: Vtree.NodeContext[]): boolean;\n getTrailingMarginEdgeAdjustment(\n trailingEdgeContexts: Vtree.NodeContext[],\n ): number;\n /**\n * Layout a single CSS box.\n */\n layoutBreakableBlock(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n postLayoutBlock(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): void;\n findEndOfLine(\n linePosition: number,\n checkPoints: Vtree.NodeContext[],\n isUpdateMaxReachedAfterEdge: boolean,\n ): {\n nodeContext: Vtree.NodeContext;\n index: number;\n checkPointIndex: number;\n };\n findAcceptableBreakInside(\n checkPoints: Vtree.NodeContext[],\n edgePosition: number,\n force: boolean,\n ): Vtree.NodeContext;\n resolveTextNodeBreaker(nodeContext: Vtree.NodeContext): TextNodeBreaker;\n /**\n * Read ranges skipping special elments\n */\n getRangeBoxes(start: Node, end: Node): Vtree.ClientRect[];\n /**\n * Give block's initial and final nodes, find positions of the line bottoms.\n * This is, of course, somewhat hacky implementation.\n * @return position of line breaks\n */\n findLinePositions(checkPoints: Vtree.NodeContext[]): number[];\n calculateClonedPaddingBorder(nodeContext: Vtree.NodeContext): number;\n findBoxBreakPosition(\n bp: BoxBreakPosition,\n force: boolean,\n ): Vtree.NodeContext;\n getAfterEdgeOfBlockContainer(nodeContext: Vtree.NodeContext): number;\n findFirstOverflowingEdgeAndCheckPoint(\n checkPoints: Vtree.NodeContext[],\n ): { edge: number; checkPoint: Vtree.NodeContext | null };\n findEdgeBreakPosition(bp: EdgeBreakPosition): Vtree.NodeContext;\n /**\n * Finalize a line break.\n * @return holing true\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean>;\n findAcceptableBreakPosition(): BreakPositionAndNodeContext;\n doFinishBreak(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n initialNodeContext: Vtree.NodeContext,\n initialComputedBlockSize: number,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Determines if a page break is acceptable at this position\n */\n isBreakable(flowPosition: Vtree.NodeContext): boolean;\n /**\n * Determines if an indent value is zero\n */\n zeroIndent(val: string | number): boolean;\n /**\n * @return true if overflows\n */\n checkOverflowAndSaveEdge(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n ): boolean;\n /**\n * Save a possible page break position on a CSS block edge. Check if it\n * overflows.\n * @return true if overflows\n */\n checkOverflowAndSaveEdgeAndBreakPosition(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n saveEvenOverflown: boolean,\n breakAtTheEdge: string | null,\n ): boolean;\n applyClearance(nodeContext: Vtree.NodeContext): boolean;\n isBFC(formattingContext: Vtree.FormattingContext): boolean;\n /**\n * Skips positions until either the start of unbreakable block or inline\n * content. Also sets breakBefore on the result combining break-before and\n * break-after properties from all elements that meet at the edge.\n */\n skipEdges(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue: string | null,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Skips non-renderable positions until it hits the end of the flow or some\n * renderable content. Returns the nodeContext that was passed in if some\n * content remains and null if all content could be skipped.\n */\n skipTailEdges(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n layoutFloatOrFootnote(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Layout next portion of the source.\n */\n layoutNext(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue?: string | null,\n ): Task.Result<Vtree.NodeContext>;\n clearOverflownViewNodes(\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ): void;\n initGeom(): void;\n init(): void;\n /**\n * Save the potential breaking position at the edge. Should, in general, save\n * \"after\" position but only after skipping all of the \"before\" ones and\n * getting to the non-empty content (to get breakAtEdge right).\n */\n saveEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakAtEdge: string | null,\n overflows: boolean,\n ): void;\n /**\n * @param checkPoints array of breaking points for breakable block\n */\n saveBoxBreakPosition(checkPoints: Vtree.NodeContext[]): void;\n updateMaxReachedAfterEdge(afterEdge: number): void;\n /**\n * @param chunkPosition starting position.\n * @return holding end position.\n */\n layout(\n chunkPosition: Vtree.ChunkPosition,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<Vtree.ChunkPosition>;\n isFullWithPageFloats(): boolean;\n getMaxBlockSizeOfPageFloats(): number;\n doFinishBreakOfFragmentLayoutConstraints(nodeContext): void;\n /**\n * @param nodeContext starting position.\n * @return holding end position.\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<{\n nodeContext: Vtree.NodeContext;\n overflownNodeContext: Vtree.NodeContext;\n }>;\n /**\n * Re-layout already laid-out chunks. Return the position of the last flow if\n * there is an overflow.\n * TODO: deal with chunks that did not fit at all.\n * @return holding end position.\n */\n redoLayout(): Task.Result<Vtree.ChunkPosition>;\n saveDistanceToBlockEndFloats(): void;\n collectElementsOffset(): RepetitiveElement.ElementsOffset[];\n }\n\n export type SinglePageFloatLayoutResult = {\n floatArea: PageFloatArea | null;\n pageFloatFragment: PageFloats.PageFloatFragment | null;\n newPosition: Vtree.ChunkPosition | null;\n };\n\n /**\n * breaking point resolver for Text Node.\n */\n export interface TextNodeBreaker {\n breakTextNode(\n textNode: Text,\n nodeContext: Vtree.NodeContext,\n low: number,\n checkPoints: Vtree.NodeContext[],\n checkpointIndex: number,\n force: boolean,\n ): Vtree.NodeContext;\n breakAfterSoftHyphen(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number;\n breakAfterOtherCharacter(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number;\n updateNodeContext(\n nodeContext: Vtree.NodeContext,\n viewIndex: number,\n textNode: Text,\n ): Vtree.NodeContext;\n }\n\n export interface LayoutMode {\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext>;\n accept(nodeContext: Vtree.NodeContext, column: Layout.Column): boolean;\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n accepted: boolean,\n ): boolean;\n }\n\n export interface PageFloatArea extends Column {\n adjustContentRelativeSize: boolean;\n readonly floatSide: string;\n readonly parentContainer: Vtree.Container;\n\n convertPercentageSizesToPx(target: Element): void;\n fixFloatSizeAndPosition(nodeContext: Vtree.NodeContext): void;\n getContentInlineSize(): number;\n }\n}\n\nexport namespace LayoutProcessor {\n export interface BlockFormattingContext extends Vtree.FormattingContext {}\n\n export function isInstanceOfBlockFormattingContext(\n object: Vtree.FormattingContext,\n ): object is BlockFormattingContext {\n return object && object.formattingContextType === \"Block\";\n }\n}\n\nexport namespace Net {\n export type Response = {\n status: number;\n statusText: string | null;\n url: string;\n contentType: string | null;\n responseText: string | null;\n responseXML: Document;\n responseBlob: Blob;\n };\n\n export interface ResourceStore<Resource> {\n resources: { [key: string]: Resource };\n fetchers: { [key: string]: TaskUtil.Fetcher<Resource> };\n readonly parser: (\n p1: Response,\n p2: ResourceStore<Resource>,\n ) => Task.Result<Resource>;\n readonly type: XMLHttpRequestResponseType;\n\n /**\n * @return resource for the given URL\n */\n load(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Resource>;\n /**\n * @return fetcher for the resource for the given URL\n */\n fetch(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): TaskUtil.Fetcher<Resource>;\n get(url: string): XmlDoc.XMLDocHolder;\n delete(url: string): void;\n }\n}\n\nexport namespace PageFloats {\n /**\n * @enum {string}\n */\n export enum FloatReference {\n INLINE = \"inline\",\n COLUMN = \"column\",\n REGION = \"region\",\n PAGE = \"page\",\n }\n\n export type PageFloatID = string;\n\n export interface PageFloat {\n order: number | null;\n id: PageFloatID | null;\n readonly nodePosition: Vtree.NodePosition;\n readonly floatReference: FloatReference;\n readonly floatSide: string;\n readonly clearSide: string | null;\n readonly flowName: string;\n readonly floatMinWrapBlock: Css.Numeric | null;\n\n getOrder(): number;\n getId(): PageFloatID;\n isAllowedOnContext(pageFloatLayoutContext: PageFloatLayoutContext): boolean;\n isAllowedToPrecede(other: PageFloat): boolean;\n }\n\n export interface PageFloatFragment {\n readonly floatReference: FloatReference;\n readonly floatSide: string;\n readonly continuations: PageFloatContinuation[];\n readonly area: Vtree.Container;\n readonly continues: boolean;\n\n hasFloat(float: PageFloat): boolean;\n findNotAllowedFloat(context: PageFloatLayoutContext): PageFloat | null;\n getOuterShape(): GeometryUtil.Shape;\n getOuterRect(): GeometryUtil.Rect;\n getOrder(): number;\n shouldBeStashedBefore(float: PageFloat): boolean;\n addContinuations(continuations: PageFloatContinuation[]): void;\n getFlowName(): string;\n }\n\n export interface PageFloatContinuation {\n readonly float: PageFloat;\n readonly nodePosition: Vtree.NodePosition;\n\n equals(other: PageFloatContinuation | null): boolean;\n }\n\n export type PageFloatPlacementCondition = {\n [key: string]: boolean;\n };\n\n export interface PageFloatLayoutContext {\n writingMode: Css.Val;\n direction: Css.Val;\n floatFragments: PageFloatFragment[];\n readonly parent: PageFloatLayoutContext;\n readonly flowName: string | null;\n readonly generatingNodePosition: Vtree.NodePosition | null;\n\n getContainer(floatReference?: FloatReference): Vtree.Container;\n setContainer(container: Vtree.Container);\n addPageFloat(float: PageFloat): void;\n getPageFloatLayoutContext(\n floatReference: FloatReference,\n ): PageFloatLayoutContext;\n findPageFloatByNodePosition(\n nodePosition: Vtree.NodePosition,\n ): PageFloat | null;\n isForbidden(float: PageFloat): boolean;\n addPageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ): void;\n removePageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ): void;\n findPageFloatFragment(float: PageFloat): PageFloatFragment | null;\n hasFloatFragments(condition?: (p1: PageFloatFragment) => boolean): boolean;\n hasContinuingFloatFragmentsInFlow(flowName: string): boolean;\n registerPageFloatAnchor(float: PageFloat, anchorViewNode: Node): void;\n collectPageFloatAnchors(): any;\n isAnchorAlreadyAppeared(floatId: PageFloatID): boolean;\n deferPageFloat(continuation: PageFloatContinuation): void;\n hasPrecedingFloatsDeferredToNext(\n float: PageFloat,\n ignoreReference?: boolean,\n ): boolean;\n getLastFollowingFloatInFragments(float: PageFloat): PageFloat | null;\n getDeferredPageFloatContinuations(\n flowName?: string | null,\n ): PageFloatContinuation[];\n getPageFloatContinuationsDeferredToNext(\n flowName?: string | null,\n ): PageFloatContinuation[];\n getFloatsDeferredToNextInChildContexts(): PageFloat[];\n checkAndForbidNotAllowedFloat(): boolean;\n checkAndForbidFloatFollowingDeferredFloat(): boolean;\n finish(): void;\n hasSameContainerAs(other: PageFloatLayoutContext): boolean;\n invalidate(): void;\n detachChildren(): PageFloatLayoutContext[];\n attachChildren(children: PageFloatLayoutContext[]): void;\n isInvalidated(): boolean;\n validate(): void;\n removeEndFloatFragments(floatSide: string): void;\n stashEndFloatFragments(float: PageFloat): void;\n restoreStashedFragments(floatReference: FloatReference): void;\n discardStashedFragments(floatReference: FloatReference): void;\n getStashedFloatFragments(\n floatReference: FloatReference,\n ): PageFloatFragment[];\n /**\n * @param anchorEdge Null indicates that the anchor is not in the current\n * container.\n * @return Logical float side (snap-block is resolved when init=false). Null\n * indicates that the float area does not fit inside the container\n */\n setFloatAreaDimensions(\n area: Layout.PageFloatArea,\n floatReference: FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n init: boolean,\n force: boolean,\n condition: PageFloatPlacementCondition,\n ): string | null;\n getFloatFragmentExclusions(): GeometryUtil.Shape[];\n getMaxReachedAfterEdge(): number;\n getBlockStartEdgeOfBlockEndFloats(): number;\n getPageFloatClearEdge(clear: string, column: Layout.Column): number;\n getPageFloatPlacementCondition(\n float: PageFloat,\n floatSide: string,\n clearSide: string | null,\n ): PageFloatPlacementCondition;\n getLayoutConstraints(): Layout.LayoutConstraint[];\n addLayoutConstraint(\n layoutConstraint: Layout.LayoutConstraint,\n floatReference: FloatReference,\n ): void;\n getMaxBlockSizeOfPageFloats(): number;\n lock(): void;\n unlock(): void;\n isLocked(): boolean;\n }\n\n export interface PageFloatLayoutStrategy {\n appliesToNodeContext(nodeContext: Vtree.NodeContext): boolean;\n appliesToFloat(float: PageFloat): boolean;\n createPageFloat(\n nodeContext: Vtree.NodeContext,\n pageFloatLayoutContext: PageFloatLayoutContext,\n column: Layout.Column,\n ): Task.Result<PageFloat>;\n createPageFloatFragment(\n continuations: PageFloatContinuation[],\n floatSide: string,\n floatArea: Layout.PageFloatArea,\n continues: boolean,\n ): PageFloatFragment;\n findPageFloatFragment(\n float: PageFloat,\n pageFloatLayoutContext: PageFloatLayoutContext,\n ): PageFloatFragment | null;\n adjustPageFloatArea(\n floatArea: Layout.PageFloatArea,\n floatContainer: Vtree.Container,\n column: Layout.Column,\n );\n forbid(float: PageFloat, pageFloatLayoutContext: PageFloatLayoutContext);\n }\n}\n\nexport namespace Selectors {\n export interface AfterIfContinues {\n readonly sourceNode: Element;\n readonly styler: PseudoElement.PseudoelementStyler;\n\n createElement(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n ): Task.Result<Element>;\n }\n\n export interface AfterIfContinuesLayoutConstraint\n extends Layout.FragmentLayoutConstraint {\n nodeContext: Vtree.NodeContext;\n afterIfContinues: AfterIfContinues;\n pseudoElementHeight: number;\n\n getRepetitiveElements(): AfterIfContinuesElementsOffset;\n }\n\n export function isInstanceOfAfterIfContinuesLayoutConstraint(\n object: Layout.FragmentLayoutConstraint,\n ): object is AfterIfContinuesLayoutConstraint {\n return object && object.flagmentLayoutConstraintType == \"AfterIfContinue\";\n }\n\n export interface AfterIfContinuesElementsOffset\n extends RepetitiveElement.ElementsOffset {\n nodeContext: Vtree.NodeContext;\n pseudoElementHeight: number;\n\n affectTo(nodeContext: Vtree.NodeContext): boolean;\n }\n}\n\nexport namespace PseudoElement {\n export interface PseudoelementStyler extends CssStyler.AbstractStyler {\n contentProcessed: { [key: string]: boolean };\n readonly element: Element;\n style: CssCascade.ElementStyle;\n styler: CssStyler.AbstractStyler;\n readonly context: Exprs.Context;\n readonly exprContentListener: Vtree.ExprContentListener;\n }\n}\n\nexport namespace RepetitiveElement {\n export interface RepetitiveElementsOwnerFormattingContext\n extends Vtree.FormattingContext {\n isRoot: boolean;\n repetitiveElements: RepetitiveElements;\n readonly parent: Vtree.FormattingContext;\n readonly rootSourceNode: Element;\n getRepetitiveElements(): RepetitiveElements;\n getRootViewNode(position: Vtree.NodeContext): Element | null;\n getRootNodeContext(\n nodeContext: Vtree.NodeContext,\n ): Vtree.NodeContext | null;\n initializeRepetitiveElements(vertical: boolean): void;\n }\n\n export function isInstanceOfRepetitiveElementsOwnerFormattingContext(\n object: Vtree.FormattingContext,\n ): object is RepetitiveElementsOwnerFormattingContext {\n if (!object) {\n return false;\n }\n const type = object.formattingContextType;\n return (\n type === \"RepetitiveElementsOwner\" ||\n Table.isInstanceOfTableFormattingContext(object)\n ); // subset\n }\n\n export interface ElementsOffset {\n calculateOffset(nodeContext: Vtree.NodeContext): number;\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number;\n }\n\n export interface RepetitiveElements extends ElementsOffset {\n isSkipHeader: boolean;\n isSkipFooter: boolean;\n enableSkippingFooter: boolean;\n enableSkippingHeader: boolean;\n doneInitialLayout: boolean;\n firstContentSourceNode: Element | null;\n lastContentSourceNode: Element | null;\n allowInsert: boolean;\n allowInsertRepeatitiveElements: boolean;\n ownerSourceNode: Element;\n\n setHeaderNodeContext(nodeContext: Vtree.NodeContext): void;\n setFooterNodeContext(nodeContext: Vtree.NodeContext): void;\n updateHeight(column: Layout.Column): void;\n prepareLayoutFragment(): void;\n appendHeaderToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: Layout.Column,\n ): Task.Result<boolean>;\n appendFooterToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: Layout.Column,\n ): Task.Result<boolean>;\n appendElementToFragment(\n nodePosition: Vtree.NodePosition,\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: Layout.Column,\n ): Task.Result<boolean>;\n moveChildren(from: Element, to: Element, firstChild: Node | null): void;\n isAfterLastContent(nodeContext: Vtree.NodeContext): boolean;\n isFirstContentNode(nodeContext: Vtree.NodeContext): boolean;\n isEnableToUpdateState(): boolean;\n updateState(): void;\n preventSkippingHeader(): void;\n preventSkippingFooter(): void;\n isHeaderRegistered(): boolean;\n isFooterRegistered(): boolean;\n isHeaderSourceNode(node: Node): boolean;\n isFooterSourceNode(node: Node): boolean;\n }\n\n export interface RepetitiveElementsOwnerLayoutConstraint\n extends Layout.FragmentLayoutConstraint {\n getRepetitiveElements(): RepetitiveElements;\n }\n\n export function isInstanceOfRepetitiveElementsOwnerLayoutConstraint(\n object: Layout.FragmentLayoutConstraint,\n ): object is RepetitiveElementsOwnerLayoutConstraint {\n if (!object) {\n return false;\n }\n const type = object.flagmentLayoutConstraintType;\n return (\n type === \"RepetitiveElementsOwner\" ||\n Table.isInstanceOfTableRowLayoutConstraint(object)\n ); // subset\n }\n}\n\nexport namespace Table {\n export interface TableFormattingContext\n extends RepetitiveElement.RepetitiveElementsOwnerFormattingContext {\n // FIXME\n }\n\n export function isInstanceOfTableFormattingContext(\n object: Vtree.FormattingContext,\n ): object is TableFormattingContext {\n return object && object.formattingContextType === \"Table\";\n }\n\n export interface TableRowLayoutConstraint\n extends RepetitiveElement.RepetitiveElementsOwnerLayoutConstraint {\n cellFragmentLayoutConstraints: {\n constraints: Layout.FragmentLayoutConstraint[];\n breakPosition: Vtree.NodeContext;\n }[];\n\n removeDummyRowNodes(nodeContext: Vtree.NodeContext): void;\n getElementsOffsetsForTableCell(\n column: Layout.Column,\n ): RepetitiveElement.ElementsOffset[];\n }\n\n export function isInstanceOfTableRowLayoutConstraint(\n object: Layout.FragmentLayoutConstraint,\n ): object is TableRowLayoutConstraint {\n return object && object.flagmentLayoutConstraintType === \"TableRow\";\n }\n}\n\nexport namespace Vtree {\n export type ClientRect = {\n left: number;\n top: number;\n right: number;\n bottom: number;\n width: number;\n height: number;\n };\n\n /**\n * Interface to read the position assigned to the elements and ranges by the\n * browser.\n */\n export interface ClientLayout {\n getRangeClientRects(range: Range): ClientRect[];\n getElementClientRect(element: Element): ClientRect;\n /**\n * @return element's computed style\n */\n getElementComputedStyle(element: Element): CSSStyleDeclaration;\n }\n\n /**\n * Styling, creating a single node's view, etc.\n */\n export interface LayoutContext {\n /**\n * Creates a functionally equivalent, but uninitialized layout context,\n * suitable for building a separate column.\n */\n clone(): LayoutContext;\n /**\n * Set the current source node and create a view. Parameter firstTime\n * is true (and possibly offsetInNode > 0) if node was broken on\n * the previous page.\n * @return true if children should be processed as well\n */\n setCurrent(\n nodeContext: NodeContext,\n firstTime: boolean,\n atUnforcedBreak?: boolean,\n ): Task.Result<boolean>;\n /**\n * Set the container element that holds view elements produced from the\n * source.\n */\n setViewRoot(viewRoot: Element, isFootnote: boolean);\n /**\n * Moves to the next view node, creating it and appending it to the view tree\n * if needed.\n * @return that corresponds to the next view node\n */\n nextInTree(\n nodeContext: NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<NodeContext>;\n /**\n * Apply pseudo-element styles (if any).\n * @param target element to apply styles to\n */\n applyPseudoelementStyle(\n nodeContext: NodeContext,\n pseudoName: string,\n target: Element,\n ): void;\n /**\n * Apply styles to footnote container.\n * @param target element to apply styles to\n * @return vertical\n */\n applyFootnoteStyle(\n vertical: boolean,\n rtl: boolean,\n target: Element,\n ): boolean;\n /**\n * Peel off innermost first-XXX pseudoelement, create and create view nodes\n * after the end of that pseudoelement.\n */\n peelOff(\n nodeContext: NodeContext,\n nodeOffset: number,\n ): Task.Result<NodeContext>;\n /**\n * Process a block-end edge of a fragmented block.\n */\n processFragmentedBlockEdge(nodeContext: NodeContext);\n convertLengthToPx(\n numeric: Css.Numeric,\n viewNode: Node,\n clientLayout: ClientLayout,\n ): number | Css.Numeric;\n /**\n * Returns if two NodePositions represents the same position in the document.\n */\n isSameNodePosition(\n nodePosition1: NodePosition,\n nodePosition2: NodePosition,\n ): boolean;\n addEventListener(\n type: string,\n listener: Base.EventListener,\n capture?: boolean,\n ): void;\n removeEventListener(\n type: string,\n listener: Base.EventListener,\n capture?: boolean,\n ): void;\n dispatchEvent(evt: Base.Event): void;\n }\n\n /**\n * Formatting context.\n */\n export interface FormattingContext {\n formattingContextType: FormattingContextType;\n getName(): string;\n isFirstTime(nodeContext: NodeContext, firstTime: boolean): boolean;\n getParent(): FormattingContext;\n saveState(): any;\n restoreState(state: any);\n }\n\n export type NodePositionStep = {\n node: Node;\n shadowType: ShadowType;\n shadowContext: ShadowContext | null;\n nodeShadow: ShadowContext | null;\n shadowSibling: NodePositionStep | null;\n formattingContext: FormattingContext | null;\n fragmentIndex: number;\n };\n\n export type NodePosition = {\n steps: NodePositionStep[];\n offsetInNode: number;\n after: boolean;\n preprocessedTextContent: Diff.Change[] | null;\n };\n\n /**\n * Handling of purely whitespace sequences between blocks\n * @enum {number}\n */\n export enum Whitespace {\n /**\n * Whitespace sequence between blocks is ignored\n */\n IGNORE,\n /**\n * Whitespace sequence between blocks is ignored unless it containes newline\n */\n NEWLINE,\n /**\n * Whitespace sequence between blocks is preserved\n */\n PRESERVE,\n }\n\n export interface Container {\n left: number;\n top: number;\n marginLeft: number;\n marginRight: number;\n marginTop: number;\n marginBottom: number;\n borderLeft: number;\n borderRight: number;\n borderTop: number;\n borderBottom: number;\n paddingLeft: number;\n paddingRight: number;\n paddingTop: number;\n paddingBottom: number;\n width: number;\n height: number;\n originX: number;\n originY: number;\n exclusions: GeometryUtil.Shape[];\n innerShape: GeometryUtil.Shape;\n computedBlockSize: number;\n snapWidth: number;\n snapHeight: number;\n snapOffsetX: number;\n snapOffsetY: number;\n vertical: boolean; // vertical writing\n element: Element;\n\n getInsetTop(): number;\n getInsetBottom(): number;\n getInsetLeft(): number;\n getInsetRight(): number;\n getInsetBefore(): number;\n getInsetAfter(): number;\n getInsetStart(): number;\n getInsetEnd(): number;\n getBeforeEdge(box: ClientRect): number;\n getAfterEdge(box: ClientRect): number;\n getStartEdge(box: ClientRect): number;\n getEndEdge(box: ClientRect): number;\n getInlineSize(box: ClientRect): number;\n getBoxSize(box: ClientRect): number;\n getBoxDir(): number;\n getInlineDir(): number;\n copyFrom(other: Container): void;\n setVerticalPosition(top: number, height: number): void;\n setHorizontalPosition(left: number, width: number): void;\n setBlockPosition(start: number, extent: number): void;\n setInlinePosition(start: number, extent: number): void;\n clear(): void;\n getInnerShape(): GeometryUtil.Shape;\n getInnerRect(): GeometryUtil.Rect;\n getPaddingRect(): GeometryUtil.Rect;\n getOuterShape(\n outerShapeProp: Css.Val,\n context: Exprs.Context,\n ): GeometryUtil.Shape;\n getOuterRect(): GeometryUtil.Rect;\n }\n\n /**\n * @enum {number}\n */\n export enum ShadowType {\n NONE,\n CONTENT,\n ROOTLESS,\n ROOTED,\n }\n\n /**\n * Data about shadow tree instance.\n */\n export interface ShadowContext {\n readonly owner: Element;\n readonly root: Element;\n readonly xmldoc: XmlDoc.XMLDocHolder;\n readonly parentShadow: ShadowContext;\n subShadow: ShadowContext;\n readonly type: Vtree.ShadowType;\n readonly styler: object;\n\n equals(other: ShadowContext): boolean;\n }\n\n /**\n * Information about :first-letter or :first-line pseudoelements\n * @param count 0 - first-letter, 1 or more - first line(s)\n */\n export interface FirstPseudo {\n readonly outer: FirstPseudo;\n readonly count: number;\n }\n\n /**\n * NodeContext represents a position in the document + layout-related\n * information attached to it. When after=false and offsetInNode=0, the\n * position is inside the element (node), but just before its first child.\n * When offsetInNode>0 it represents offset in the textual content of the\n * node. When after=true it represents position right after the last child\n * of the node. boxOffset is incremented by 1 for any valid node position.\n */\n export interface NodeContext {\n // position itself\n offsetInNode: number;\n after: boolean;\n shadowType: ShadowType; // parent's shadow type\n shadowContext: Vtree.ShadowContext;\n nodeShadow: Vtree.ShadowContext;\n shadowSibling: NodeContext; // next \"sibling\" in the shadow tree\n // other stuff\n shared: boolean;\n inline: boolean;\n overflow: boolean;\n breakPenalty: number;\n display: string | null;\n floatReference: PageFloats.FloatReference;\n floatSide: string | null;\n clearSide: string | null;\n floatMinWrapBlock: Css.Numeric | null;\n columnSpan: Css.Val | null;\n verticalAlign: string;\n captionSide: string;\n inlineBorderSpacing: number;\n blockBorderSpacing: number;\n flexContainer: boolean;\n whitespace: Whitespace;\n hyphenateCharacter: string | null;\n breakWord: boolean;\n establishesBFC: boolean;\n containingBlockForAbsolute: boolean;\n breakBefore: string | null;\n breakAfter: string | null;\n viewNode: Node;\n clearSpacer: Node;\n inheritedProps: { [key: string]: number | string | Css.Val };\n vertical: boolean;\n direction: string;\n firstPseudo: FirstPseudo;\n lang: string | null;\n preprocessedTextContent: Diff.Change[] | null;\n formattingContext: FormattingContext;\n repeatOnBreak: string | null;\n pluginProps: {\n [key: string]: string | number | undefined | null | (number | null)[];\n };\n fragmentIndex: number;\n afterIfContinues: Selectors.AfterIfContinues;\n footnotePolicy: Css.Ident | null;\n\n sourceNode: Node;\n parent: NodeContext;\n boxOffset: number;\n\n resetView(): void;\n modify(): NodeContext;\n copy(): NodeContext;\n clone(): NodeContext;\n toNodePositionStep(): NodePositionStep;\n toNodePosition(): NodePosition;\n isInsideBFC(): boolean;\n getContainingBlockForAbsolute(): NodeContext;\n /**\n * Walk up NodeContext tree (starting from itself) and call the callback for\n * each block.\n */\n walkUpBlocks(callback: (p1: NodeContext) => any): void;\n belongsTo(formattingContext: FormattingContext): boolean;\n }\n\n export interface ChunkPosition {\n floats: NodePosition[];\n primary: NodePosition;\n\n clone(): ChunkPosition;\n isSamePosition(other: ChunkPosition): boolean;\n }\n\n export type ExprContentListener = (\n p1: Exprs.Val,\n p2: string,\n p3: Document,\n ) => Node | null;\n}\n\nexport namespace XmlDoc {\n export interface XMLDocHolder {\n lang: string | null;\n totalOffset: number;\n root: Element;\n body: Element;\n head: Element;\n last: Element;\n lastOffset: number;\n idMap: { [key: string]: Element };\n readonly store: XMLDocStore;\n readonly url: string;\n readonly document: Document;\n\n doc(): NodeList;\n getElementOffset(element: Element): number;\n getNodeOffset(srcNode: Node, offsetInNode: number, after: boolean): number;\n getTotalOffset(): number;\n /**\n * @return last node such that its offset is less or equal to the given\n */\n getNodeByOffset(offset: number): Node;\n /**\n * Get element by URL in the source document(s). URL must be in either '#id'\n * or 'url#id' form.\n */\n getElement(url: string): Element | null;\n }\n\n export interface Predicate {\n readonly fn: (p1: Node) => boolean;\n\n check(node: Node): boolean;\n withAttribute(name: string, value: string): Predicate;\n withChild(name: string, opt_childPredicate?: Predicate): Predicate;\n }\n\n export interface NodeList {\n readonly nodes: Node[];\n\n asArray(): Node[];\n size(): number;\n /**\n * Filter with predicate\n */\n predicate(pr: Predicate): NodeList;\n forEachNode(fn: (p1: Node, p2: (p1: Node) => void) => void): NodeList;\n forEach<T>(fn: (p1: Node) => T): T[];\n forEachNonNull<T>(fn: (p1: Node) => T): T[];\n child(tag: string): NodeList;\n childElements(): NodeList;\n attribute(name: string): (string | null)[];\n textContent(): (string | null)[];\n }\n\n export type XMLDocStore = Net.ResourceStore<XMLDocHolder>;\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Diff utility\n */\n\nimport fastdiff from \"fast-diff\";\n\nexport type Change = (number | string)[];\n\nexport function diffChars(originalText: string, newText: string): Change[] {\n return fastdiff(originalText, newText, 0);\n}\n\n/**\n * @returns string\n */\nexport function restoreOriginalText(changes: Change[]): any {\n return changes.reduce((result, item) => {\n if (item[0] === fastdiff.INSERT) {\n return result;\n }\n return result + item[1];\n }, \"\");\n}\n\n/**\n * @returns string\n */\nexport function restoreNewText(changes: Change[]): any {\n return changes.reduce((result, item) => {\n if (item[0] === fastdiff.DELETE) {\n return result;\n }\n return result + item[1];\n }, \"\");\n}\n\nexport function resolveNewIndex(changes: Change[], oldIndex: number): number {\n return resolveIndex(changes, oldIndex, 1);\n}\n\nexport function resolveOriginalIndex(\n changes: Change[],\n newIndex: number,\n): number {\n return resolveIndex(changes, newIndex, -1);\n}\n\nexport function resolveIndex(\n changes: Change[],\n index: number,\n coef: number,\n): number {\n let diff = 0;\n let current = 0;\n changes.some((change) => {\n for (let i = 0; i < (change[1] as string).length; i++) {\n switch ((change[0] as number) * coef) {\n case fastdiff.INSERT:\n diff++;\n break;\n case fastdiff.DELETE:\n diff--;\n current++;\n break;\n case fastdiff.EQUAL:\n current++;\n break;\n }\n if (current > index) {\n return true;\n }\n }\n return false;\n });\n return Math.max(Math.min(index, current - 1) + diff, 0);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Vtree - Basic view tree data structures and support utilities.\n */\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Css from \"./css\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Diff from \"./diff\";\nimport * as Exprs from \"./exprs\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as TaskUtil from \"./task-util\";\nimport { assert } from \"./asserts\";\nimport { PageFloats, Selectors, Vtree, XmlDoc } from \"./types\";\n\nexport const delayedProps = {\n transform: true,\n \"transform-origin\": true,\n};\n\nexport const delayedPropsIfRelativePositioned = {\n top: true,\n bottom: true,\n left: true,\n right: true,\n};\n\nexport class DelayedItem {\n constructor(\n public target: Element,\n public name: string,\n public value: Css.Val,\n ) {}\n}\n\nexport type PageHyperlinkEvent = {\n type: string;\n target;\n currentTarget;\n anchorElement: Element;\n href: string;\n};\n\nexport type Trigger = {\n observer: string;\n event: string;\n action: string;\n ref: string;\n};\n\nexport const actions = {\n show: function(obj) {\n obj.style.visibility = \"visible\";\n },\n hide: function(obj) {\n obj.style.visibility = \"hidden\";\n },\n play: function(obj) {\n obj.currentTime = 0;\n obj.play();\n },\n pause: function(obj) {\n obj.pause();\n },\n resume: function(obj) {\n obj.play();\n },\n mute: function(obj) {\n obj.muted = true;\n },\n unmute: function(obj) {\n obj.muted = false;\n },\n};\n\nexport function makeListener(\n refs: Element[],\n action: string,\n): EventListener | null {\n const actionFn = actions[action];\n if (actionFn) {\n return () => {\n for (let k = 0; k < refs.length; k++) {\n try {\n actionFn(refs[k]);\n } catch (err) {}\n }\n };\n }\n return null;\n}\n\nexport class Page extends Base.SimpleEventTarget {\n private static AUTO_PAGE_WIDTH_ATTRIBUTE: string =\n \"data-vivliostyle-auto-page-width\";\n private static AUTO_PAGE_HEIGHT_ATTRIBUTE: string =\n \"data-vivliostyle-auto-page-height\";\n pageAreaElement: HTMLElement | null = null;\n delayedItems: DelayedItem[] = [];\n hrefHandler: (e: Event) => void;\n elementsById: { [key: string]: Element[] } = {};\n dimensions: { width: number; height: number } = { width: 0, height: 0 };\n isFirstPage: boolean = false;\n isLastPage: boolean = false;\n isAutoPageWidth: boolean = true;\n isAutoPageHeight: boolean = true;\n spineIndex: number = 0;\n position: LayoutPosition = null;\n offset: number = -1;\n side: Constants.PageSide | null = null;\n fetchers: TaskUtil.Fetcher<{}>[] = [];\n marginBoxes: {\n top: { [key: string]: Container };\n bottom: { [key: string]: Container };\n left: { [key: string]: Container };\n right: { [key: string]: Container };\n } = { top: {}, bottom: {}, left: {}, right: {} };\n\n constructor(\n public readonly container: HTMLElement,\n public readonly bleedBox: HTMLElement,\n ) {\n super();\n const self = this;\n this.hrefHandler = (e: Event) => {\n const anchorElement = e.currentTarget as Element;\n const href =\n anchorElement.getAttribute(\"href\") ||\n anchorElement.getAttributeNS(Base.NS.XLINK, \"href\");\n if (href) {\n const evt = {\n type: \"hyperlink\",\n target: null,\n currentTarget: null,\n anchorElement,\n href,\n preventDefault() {\n e.preventDefault();\n },\n };\n self.dispatchEvent(evt);\n }\n };\n }\n\n setAutoPageWidth(isAuto: boolean) {\n this.isAutoPageWidth = isAuto;\n if (isAuto) {\n this.container.setAttribute(Page.AUTO_PAGE_WIDTH_ATTRIBUTE, \"true\");\n } else {\n this.container.removeAttribute(Page.AUTO_PAGE_WIDTH_ATTRIBUTE);\n }\n }\n\n setAutoPageHeight(isAuto: boolean) {\n this.isAutoPageHeight = isAuto;\n if (isAuto) {\n this.container.setAttribute(Page.AUTO_PAGE_HEIGHT_ATTRIBUTE, \"true\");\n } else {\n this.container.removeAttribute(Page.AUTO_PAGE_HEIGHT_ATTRIBUTE);\n }\n }\n\n registerElementWithId(element: Element, id: string) {\n const arr = this.elementsById[id];\n if (!arr) {\n this.elementsById[id] = [element];\n } else {\n arr.push(element);\n }\n }\n\n finish(triggers: Trigger[], clientLayout: ClientLayout): void {\n // Remove ID of elements which eventually did not fit in the page\n // (Some nodes may have been removed after registration if they did not fit\n // in the page)\n Object.keys(this.elementsById).forEach((id) => {\n const elems = this.elementsById[id];\n for (let i = 0; i < elems.length; ) {\n if (this.container.contains(elems[i])) {\n i++;\n } else {\n elems.splice(i, 1);\n }\n }\n if (elems.length === 0) {\n delete this.elementsById[id];\n }\n });\n const list = this.delayedItems;\n for (let i = 0; i < list.length; i++) {\n const item = list[i];\n if (\n item.target === this.container &&\n item.name === \"transform\" &&\n !this.isAutoPageWidth &&\n !this.isAutoPageHeight\n ) {\n // When fixed page size is specified, cancel the transform property\n // set at OPFView.makePage() for the specified viewport size\n // (e.g. `<meta name=\"viewport\" content=\"width=1307, height=1920\"/>`)\n // to avoid wrong page resizing.\n continue;\n }\n Base.setCSSProperty(item.target, item.name, item.value.toString());\n }\n\n // use size of the container of the PageMasterInstance\n const rect = clientLayout.getElementClientRect(this.container);\n this.dimensions.width = rect.width;\n this.dimensions.height = rect.height;\n for (let i = 0; i < triggers.length; i++) {\n const trigger = triggers[i];\n const refs = this.elementsById[trigger.ref];\n const observers = this.elementsById[trigger.observer];\n if (refs && observers) {\n const listener = makeListener(refs, trigger.action);\n if (listener) {\n for (let k = 0; k < observers.length; k++) {\n observers[k].addEventListener(trigger.event, listener, false);\n }\n }\n }\n }\n }\n\n /**\n * Zoom page.\n * @param scale Factor to which the page will be scaled.\n */\n zoom(scale: number) {\n Base.setCSSProperty(this.container, \"transform\", `scale(${scale})`);\n }\n\n /**\n * Returns the page area element.\n */\n getPageAreaElement(): HTMLElement {\n return this.pageAreaElement || this.container;\n }\n}\n\nexport type Spread = {\n left: Page;\n right: Page;\n};\n\n/**\n * Marks an element as \"special\". It should not be used in bbox calculations.\n */\nexport const SPECIAL_ATTR = \"data-adapt-spec\";\n\nexport const Whitespace = Vtree.Whitespace;\nexport type Whitespace = Vtree.Whitespace;\n\n/**\n * Resolves Whitespace value from a value of 'white-space' property\n * @param whitespace The value of 'white-space' property\n */\nexport function whitespaceFromPropertyValue(\n whitespace: string,\n): Whitespace | null {\n switch (whitespace) {\n case \"normal\":\n case \"nowrap\":\n return Whitespace.IGNORE;\n case \"pre-line\":\n return Whitespace.NEWLINE;\n case \"pre\":\n case \"pre-wrap\":\n return Whitespace.PRESERVE;\n default:\n return null;\n }\n}\n\nexport function canIgnore(node: Node, whitespace: Whitespace): boolean {\n if (node.nodeType == 1) {\n return false;\n }\n const text = node.textContent;\n switch (whitespace) {\n case Whitespace.IGNORE:\n return !!text.match(/^\\s*$/);\n case Whitespace.NEWLINE:\n return !!text.match(/^[ \\t\\f]*$/);\n case Whitespace.PRESERVE:\n return text.length == 0;\n }\n throw new Error(`Unexpected whitespace: ${whitespace}`);\n}\n\nexport class Flow {\n forcedBreakOffsets = [] as number[];\n formattingContext: FormattingContext | null = null;\n\n constructor(\n public readonly flowName: string,\n public readonly parentFlowName: string | null,\n ) {}\n}\n\nexport class FlowChunk {\n startPage: number = -1;\n\n constructor(\n public flowName: string,\n public element: Element,\n public startOffset: number,\n public priority: number,\n public linger: number,\n public exclusive: boolean,\n public repeated: boolean,\n public last: boolean,\n public breakBefore: string | null,\n ) {}\n\n isBetter(other: FlowChunk): boolean {\n if (!this.exclusive) {\n return false;\n }\n if (!other.exclusive) {\n return true;\n }\n if (this.priority > other.priority) {\n return true;\n }\n return this.last;\n }\n}\n\nexport type ClientRect = Vtree.ClientRect;\n\nexport function clientrectIncreasingTop(\n r1: ClientRect,\n r2: ClientRect,\n): number {\n return r1.top - r2.top;\n}\n\nexport function clientrectDecreasingRight(\n r1: ClientRect,\n r2: ClientRect,\n): number {\n return r2.right - r1.right;\n}\n\n/**\n * Interface to read the position assigned to the elements and ranges by the\n * browser.\n */\nexport type ClientLayout = Vtree.ClientLayout;\n\n/**\n * Styling, creating a single node's view, etc.\n */\nexport type LayoutContext = Vtree.LayoutContext;\n\n/**\n * Formatting context.\n */\nexport type FormattingContext = Vtree.FormattingContext;\n\nexport function eachAncestorFormattingContext(\n nodeContext: NodeContext,\n callback: (p1: FormattingContext) => any,\n): void {\n if (!nodeContext) {\n return;\n }\n for (let fc = nodeContext.formattingContext; fc; fc = fc.getParent()) {\n callback(fc);\n }\n}\n\nexport type NodePositionStep = Vtree.NodePositionStep;\n\nexport function isSameNodePositionStep(\n nps1: NodePositionStep,\n nps2: NodePositionStep,\n): boolean {\n if (nps1 === nps2) {\n return true;\n }\n if (!nps1 || !nps2) {\n return false;\n }\n return (\n nps1.node === nps2.node &&\n nps1.shadowType === nps2.shadowType &&\n isSameShadowContext(nps1.shadowContext, nps2.shadowContext) &&\n isSameShadowContext(nps1.nodeShadow, nps2.nodeShadow) &&\n isSameNodePositionStep(nps1.shadowSibling, nps2.shadowSibling)\n );\n}\n\nexport type NodePosition = Vtree.NodePosition;\n\nexport function isSameNodePosition(\n np1: NodePosition | null,\n np2: NodePosition | null,\n): boolean {\n if (np1 === np2) {\n return true;\n }\n if (!np1 || !np2) {\n return false;\n }\n if (\n np1.offsetInNode !== np2.offsetInNode ||\n np1.after !== np2.after ||\n np1.steps.length !== np2.steps.length\n ) {\n return false;\n }\n for (let i = 0; i < np1.steps.length; i++) {\n if (!isSameNodePositionStep(np1.steps[i], np2.steps[i])) {\n return false;\n }\n }\n return true;\n}\n\nexport function newNodePositionFromNode(node: Node): NodePosition {\n const step: NodePositionStep = {\n node,\n shadowType: ShadowType.NONE,\n shadowContext: null,\n nodeShadow: null,\n shadowSibling: null,\n formattingContext: null,\n fragmentIndex: 0,\n };\n return {\n steps: [step],\n offsetInNode: 0,\n after: false,\n preprocessedTextContent: null,\n };\n}\n\nexport function newNodePositionFromNodeContext(\n nodeContext: Vtree.NodeContext,\n initialFragmentIndex: number | null,\n): NodePosition {\n const step: NodePositionStep = {\n node: nodeContext.sourceNode,\n shadowType: ShadowType.NONE,\n shadowContext: nodeContext.shadowContext,\n nodeShadow: null,\n shadowSibling: null,\n formattingContext: null,\n fragmentIndex:\n initialFragmentIndex != null\n ? initialFragmentIndex\n : nodeContext.fragmentIndex,\n };\n return {\n steps: [step],\n offsetInNode: 0,\n after: false,\n preprocessedTextContent: nodeContext.preprocessedTextContent,\n };\n}\n\nexport function makeNodeContextFromNodePositionStep(\n step: NodePositionStep,\n parent: Vtree.NodeContext,\n): NodeContext {\n const nodeContext = new NodeContext(step.node, parent as NodeContext, 0);\n nodeContext.shadowType = step.shadowType;\n nodeContext.shadowContext = step.shadowContext;\n nodeContext.nodeShadow = step.nodeShadow;\n nodeContext.shadowSibling = step.shadowSibling\n ? makeNodeContextFromNodePositionStep(step.shadowSibling, parent.copy())\n : null;\n nodeContext.formattingContext = step.formattingContext;\n nodeContext.fragmentIndex = step.fragmentIndex + 1;\n return nodeContext;\n}\n\nexport const ShadowType = Vtree.ShadowType;\nexport type ShadowType = Vtree.ShadowType;\n\n/**\n * Data about shadow tree instance.\n */\nexport class ShadowContext implements Vtree.ShadowContext {\n subShadow: ShadowContext = null;\n\n constructor(\n public readonly owner: Element,\n public readonly root: Element,\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n public readonly parentShadow: ShadowContext,\n superShadow: ShadowContext,\n public readonly type: ShadowType,\n public readonly styler: object,\n ) {\n if (superShadow) {\n superShadow.subShadow = this;\n }\n }\n\n equals(other: ShadowContext): boolean {\n if (!other) {\n return false;\n }\n return (\n this.owner === other.owner &&\n this.xmldoc === other.xmldoc &&\n this.type === other.type &&\n isSameShadowContext(this.parentShadow, other.parentShadow)\n );\n }\n}\n\nexport function isSameShadowContext(\n sc1: ShadowContext,\n sc2: ShadowContext,\n): boolean {\n return sc1 === sc2 || (!!sc1 && !!sc2 && sc1.equals(sc2));\n}\n\n/**\n * Information about :first-letter or :first-line pseudoelements\n * @param count 0 - first-letter, 1 or more - first line(s)\n */\nexport class FirstPseudo implements Vtree.FirstPseudo {\n constructor(\n public readonly outer: FirstPseudo,\n public readonly count: number,\n ) {}\n}\n\n/**\n * NodeContext represents a position in the document + layout-related\n * information attached to it. When after=false and offsetInNode=0, the\n * position is inside the element (node), but just before its first child.\n * When offsetInNode>0 it represents offset in the textual content of the\n * node. When after=true it represents position right after the last child\n * of the node. boxOffset is incremented by 1 for any valid node position.\n */\nexport class NodeContext implements Vtree.NodeContext {\n // position itself\n offsetInNode: number = 0;\n after: boolean = false;\n shadowType: ShadowType;\n\n // parent's shadow type\n shadowContext: ShadowContext;\n nodeShadow: ShadowContext = null;\n shadowSibling: NodeContext = null;\n\n // next \"sibling\" in the shadow tree\n // other stuff\n shared: boolean = false;\n inline: boolean = true;\n overflow: boolean = false;\n breakPenalty: number;\n display: string | null = null;\n floatReference: PageFloats.FloatReference;\n floatSide: string | null = null;\n clearSide: string | null = null;\n floatMinWrapBlock: Css.Numeric | null = null;\n columnSpan: Css.Val | null = null;\n verticalAlign: string = \"baseline\";\n captionSide: string = \"top\";\n inlineBorderSpacing: number = 0;\n blockBorderSpacing: number = 0;\n flexContainer: boolean = false;\n whitespace: Whitespace;\n hyphenateCharacter: string | null;\n breakWord: boolean;\n establishesBFC: boolean = false;\n containingBlockForAbsolute: boolean = false;\n breakBefore: string | null = null;\n breakAfter: string | null = null;\n viewNode: Node = null;\n clearSpacer: Node = null;\n inheritedProps: { [key: string]: number | string | Css.Val };\n vertical: boolean;\n direction: string;\n firstPseudo: FirstPseudo;\n lang: string | null = null;\n preprocessedTextContent: Diff.Change[] | null = null;\n formattingContext: FormattingContext;\n repeatOnBreak: string | null = null;\n pluginProps: {\n [key: string]: string | number | undefined | null | (number | null)[];\n } = {};\n fragmentIndex: number = 1;\n afterIfContinues: Selectors.AfterIfContinues = null;\n footnotePolicy: Css.Ident | null = null;\n\n constructor(\n public sourceNode: Node,\n public parent: NodeContext,\n public boxOffset: number,\n ) {\n this.shadowType = ShadowType.NONE;\n this.shadowContext = parent ? parent.shadowContext : null;\n this.breakPenalty = parent ? parent.breakPenalty : 0;\n this.floatReference = PageFloats.FloatReference.INLINE;\n this.whitespace = parent ? parent.whitespace : Whitespace.IGNORE;\n this.hyphenateCharacter = parent ? parent.hyphenateCharacter : null;\n this.breakWord = parent ? parent.breakWord : false;\n this.inheritedProps = parent ? parent.inheritedProps : {};\n this.vertical = parent ? parent.vertical : false;\n this.direction = parent ? parent.direction : \"ltr\";\n this.firstPseudo = parent ? parent.firstPseudo : null;\n this.formattingContext = parent ? parent.formattingContext : null;\n }\n\n resetView(): void {\n this.inline = true;\n this.breakPenalty = this.parent ? this.parent.breakPenalty : 0;\n this.viewNode = null;\n this.clearSpacer = null;\n this.offsetInNode = 0;\n this.after = false;\n this.display = null;\n this.floatReference = PageFloats.FloatReference.INLINE;\n this.floatSide = null;\n this.clearSide = null;\n this.floatMinWrapBlock = null;\n this.columnSpan = null;\n this.verticalAlign = \"baseline\";\n this.flexContainer = false;\n this.whitespace = this.parent ? this.parent.whitespace : Whitespace.IGNORE;\n this.hyphenateCharacter = this.parent\n ? this.parent.hyphenateCharacter\n : null;\n this.breakWord = this.parent ? this.parent.breakWord : false;\n this.breakBefore = null;\n this.breakAfter = null;\n this.nodeShadow = null;\n this.establishesBFC = false;\n this.containingBlockForAbsolute = false;\n this.vertical = this.parent ? this.parent.vertical : false;\n this.nodeShadow = null;\n this.preprocessedTextContent = null;\n this.formattingContext = this.parent ? this.parent.formattingContext : null;\n this.repeatOnBreak = null;\n this.pluginProps = {};\n this.fragmentIndex = 1;\n this.afterIfContinues = null;\n this.footnotePolicy = null;\n }\n\n private cloneItem(): NodeContext {\n const np = new NodeContext(this.sourceNode, this.parent, this.boxOffset);\n np.offsetInNode = this.offsetInNode;\n np.after = this.after;\n np.nodeShadow = this.nodeShadow;\n np.shadowType = this.shadowType;\n np.shadowContext = this.shadowContext;\n np.shadowSibling = this.shadowSibling;\n np.inline = this.inline;\n np.breakPenalty = this.breakPenalty;\n np.display = this.display;\n np.floatReference = this.floatReference;\n np.floatSide = this.floatSide;\n np.clearSide = this.clearSide;\n np.floatMinWrapBlock = this.floatMinWrapBlock;\n np.columnSpan = this.columnSpan;\n np.verticalAlign = this.verticalAlign;\n np.captionSide = this.captionSide;\n np.inlineBorderSpacing = this.inlineBorderSpacing;\n np.blockBorderSpacing = this.blockBorderSpacing;\n np.establishesBFC = this.establishesBFC;\n np.containingBlockForAbsolute = this.containingBlockForAbsolute;\n np.flexContainer = this.flexContainer;\n np.whitespace = this.whitespace;\n np.hyphenateCharacter = this.hyphenateCharacter;\n np.breakWord = this.breakWord;\n np.breakBefore = this.breakBefore;\n np.breakAfter = this.breakAfter;\n np.viewNode = this.viewNode;\n np.clearSpacer = this.clearSpacer;\n np.firstPseudo = this.firstPseudo;\n np.vertical = this.vertical;\n np.overflow = this.overflow;\n np.preprocessedTextContent = this.preprocessedTextContent;\n np.formattingContext = this.formattingContext;\n np.repeatOnBreak = this.repeatOnBreak;\n np.pluginProps = Object.create(this.pluginProps);\n np.fragmentIndex = this.fragmentIndex;\n np.afterIfContinues = this.afterIfContinues;\n np.footnotePolicy = this.footnotePolicy;\n return np;\n }\n\n modify(): NodeContext {\n if (!this.shared) {\n return this;\n }\n return this.cloneItem();\n }\n\n copy(): NodeContext {\n let np: NodeContext = this;\n do {\n if (np.shared) {\n break;\n }\n np.shared = true;\n np = np.parent;\n } while (np);\n return this;\n }\n\n clone(): NodeContext {\n const np = this.cloneItem();\n let npc = np;\n let npp: NodeContext;\n while ((npp = npc.parent) != null) {\n npp = npp.cloneItem();\n npc.parent = npp;\n npc = npp;\n }\n return np;\n }\n\n toNodePositionStep(): NodePositionStep {\n return {\n node: this.sourceNode,\n shadowType: this.shadowType,\n shadowContext: this.shadowContext,\n nodeShadow: this.nodeShadow,\n shadowSibling: this.shadowSibling\n ? this.shadowSibling.toNodePositionStep()\n : null,\n formattingContext: this.formattingContext,\n fragmentIndex: this.fragmentIndex,\n };\n }\n\n toNodePosition(): NodePosition {\n let nc: NodeContext = this;\n const steps = [];\n do {\n // We need fully \"peeled\" path, so don't record first-XXX pseudoelement\n // containers\n if (\n !nc.firstPseudo ||\n !nc.parent ||\n nc.parent.firstPseudo === nc.firstPseudo\n ) {\n steps.push(nc.toNodePositionStep());\n }\n nc = nc.parent;\n } while (nc);\n const actualOffsetInNode = this.preprocessedTextContent\n ? Diff.resolveOriginalIndex(\n this.preprocessedTextContent,\n this.offsetInNode,\n )\n : this.offsetInNode;\n return {\n steps,\n offsetInNode: actualOffsetInNode,\n after: this.after,\n preprocessedTextContent: this.preprocessedTextContent,\n };\n }\n\n isInsideBFC(): boolean {\n let parent = this.parent;\n while (parent) {\n if (parent.establishesBFC) {\n return true;\n }\n parent = parent.parent;\n }\n return false;\n }\n\n getContainingBlockForAbsolute(): NodeContext {\n let parent = this.parent;\n while (parent) {\n if (parent.containingBlockForAbsolute) {\n return parent;\n }\n parent = parent.parent;\n }\n return null;\n }\n\n /**\n * Walk up NodeContext tree (starting from itself) and call the callback for\n * each block.\n */\n walkUpBlocks(callback: (p1: NodeContext) => any) {\n let nodeContext: NodeContext = this;\n while (nodeContext) {\n if (!nodeContext.inline) {\n callback(nodeContext);\n }\n nodeContext = nodeContext.parent;\n }\n }\n\n belongsTo(formattingContext: FormattingContext): boolean {\n return (\n this.formattingContext === formattingContext &&\n !!this.parent &&\n this.parent.formattingContext === formattingContext\n );\n }\n}\n\nexport class ChunkPosition implements Vtree.ChunkPosition {\n floats: NodePosition[] = null;\n\n constructor(public primary: NodePosition) {}\n\n clone(): ChunkPosition {\n const result = new ChunkPosition(this.primary);\n if (this.floats) {\n result.floats = [];\n for (let i = 0; i < this.floats.length; ++i) {\n result.floats[i] = this.floats[i];\n }\n }\n return result;\n }\n\n isSamePosition(other: ChunkPosition): boolean {\n if (!other) {\n return false;\n }\n if (this === other) {\n return true;\n }\n if (!isSameNodePosition(this.primary, other.primary)) {\n return false;\n }\n if (this.floats) {\n if (!other.floats || this.floats.length !== other.floats.length) {\n return false;\n }\n for (let i = 0; i < this.floats.length; i++) {\n if (!isSameNodePosition(this.floats[i], other.floats[i])) {\n return false;\n }\n }\n } else if (other.floats) {\n return false;\n }\n return true;\n }\n}\n\nexport class FlowChunkPosition {\n constructor(\n public chunkPosition: ChunkPosition,\n public readonly flowChunk: FlowChunk,\n ) {}\n\n clone(): FlowChunkPosition {\n return new FlowChunkPosition(this.chunkPosition.clone(), this.flowChunk);\n }\n\n isSamePosition(other: FlowChunkPosition): boolean {\n return (\n !!other &&\n (this === other || this.chunkPosition.isSamePosition(other.chunkPosition))\n );\n }\n}\n\nexport class FlowPosition {\n positions: FlowChunkPosition[] = [];\n startSide: string = \"any\";\n breakAfter: string | null = null;\n\n clone(): FlowPosition {\n const newfp = new FlowPosition();\n const arr = this.positions;\n const newarr = newfp.positions;\n for (let i = 0; i < arr.length; i++) {\n newarr[i] = arr[i].clone();\n }\n newfp.startSide = this.startSide;\n newfp.breakAfter = this.breakAfter;\n return newfp;\n }\n\n isSamePosition(other: FlowPosition): boolean {\n if (this === other) {\n return true;\n }\n if (!other || this.positions.length !== other.positions.length) {\n return false;\n }\n for (let i = 0; i < this.positions.length; i++) {\n if (!this.positions[i].isSamePosition(other.positions[i])) {\n return false;\n }\n }\n return true;\n }\n\n hasContent(offset: number): boolean {\n return (\n this.positions.length > 0 &&\n this.positions[0].flowChunk.startOffset <= offset\n );\n }\n}\n\nexport class LayoutPosition {\n /**\n * One-based, incremented before layout.\n */\n page: number = 0;\n flows: { [key: string]: Flow } = {};\n flowPositions: { [key: string]: FlowPosition } = {};\n\n /**\n * flowPositions is built up to this offset.\n */\n highestSeenOffset: number = 0;\n\n // FIXME: This properties seem to be not used\n highestSeenNode: Node;\n lookupPositionOffset: number;\n\n clone(): LayoutPosition {\n const newcp = new LayoutPosition();\n newcp.page = this.page;\n newcp.highestSeenNode = this.highestSeenNode;\n newcp.highestSeenOffset = this.highestSeenOffset;\n newcp.lookupPositionOffset = this.lookupPositionOffset;\n newcp.flows = this.flows;\n for (const name in this.flowPositions) {\n newcp.flowPositions[name] = this.flowPositions[name].clone();\n }\n return newcp;\n }\n\n isSamePosition(other: LayoutPosition): boolean {\n if (this === other) {\n return true;\n }\n if (\n !other ||\n this.page !== other.page ||\n this.highestSeenOffset !== other.highestSeenOffset\n ) {\n return false;\n }\n const thisFlowNames = Object.keys(this.flowPositions);\n const otherFlowNames = Object.keys(other.flowPositions);\n if (thisFlowNames.length !== otherFlowNames.length) {\n return false;\n }\n for (const flowName of thisFlowNames) {\n if (\n !this.flowPositions[flowName].isSamePosition(\n other.flowPositions[flowName],\n )\n ) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * @param name flow name.\n */\n hasContent(name: string, offset: number): boolean {\n const flowPos = this.flowPositions[name];\n if (!flowPos) {\n return false;\n }\n return flowPos.hasContent(offset);\n }\n\n startSideOfFlow(name: string): string {\n const flowPos = this.flowPositions[name];\n if (!flowPos) {\n return \"any\";\n }\n return flowPos.startSide;\n }\n\n firstFlowChunkOfFlow(name: string): FlowChunk | null {\n const flowPos = this.flowPositions[name];\n if (!flowPos) {\n return null;\n }\n const flowChunkPosition = flowPos.positions[0];\n if (!flowChunkPosition) {\n return null;\n }\n return flowChunkPosition.flowChunk;\n }\n}\n\nexport class Container implements Vtree.Container {\n left: number = 0;\n top: number = 0;\n marginLeft: number = 0;\n marginRight: number = 0;\n marginTop: number = 0;\n marginBottom: number = 0;\n borderLeft: number = 0;\n borderRight: number = 0;\n borderTop: number = 0;\n borderBottom: number = 0;\n paddingLeft: number = 0;\n paddingRight: number = 0;\n paddingTop: number = 0;\n paddingBottom: number = 0;\n width: number = 0;\n height: number = 0;\n originX: number = 0;\n originY: number = 0;\n exclusions: GeometryUtil.Shape[] = null;\n innerShape: GeometryUtil.Shape = null;\n computedBlockSize: number = 0;\n snapWidth: number = 0;\n snapHeight: number = 0;\n snapOffsetX: number = 0;\n snapOffsetY: number = 0;\n vertical: boolean = false; // vertical writing\n\n constructor(public element: Element) {}\n\n getInsetTop() {\n return this.marginTop + this.borderTop + this.paddingTop;\n }\n\n getInsetBottom() {\n return this.marginBottom + this.borderBottom + this.paddingBottom;\n }\n\n getInsetLeft() {\n return this.marginLeft + this.borderLeft + this.paddingLeft;\n }\n\n getInsetRight() {\n return this.marginRight + this.borderRight + this.paddingRight;\n }\n\n getInsetBefore() {\n if (this.vertical) {\n return this.getInsetRight();\n } else {\n return this.getInsetTop();\n }\n }\n\n getInsetAfter() {\n if (this.vertical) {\n return this.getInsetLeft();\n } else {\n return this.getInsetBottom();\n }\n }\n\n getInsetStart() {\n if (this.vertical) {\n return this.getInsetTop();\n } else {\n return this.getInsetLeft();\n }\n }\n\n getInsetEnd() {\n if (this.vertical) {\n return this.getInsetBottom();\n } else {\n return this.getInsetRight();\n }\n }\n\n getBeforeEdge(box: ClientRect): number {\n return this.vertical ? box.right : box.top;\n }\n\n getAfterEdge(box: ClientRect): number {\n return this.vertical ? box.left : box.bottom;\n }\n\n getStartEdge(box: ClientRect): number {\n return this.vertical ? box.top : box.left;\n }\n\n getEndEdge(box: ClientRect): number {\n return this.vertical ? box.bottom : box.right;\n }\n\n getInlineSize(box: ClientRect): number {\n return this.vertical ? box.bottom - box.top : box.right - box.left;\n }\n\n getBoxSize(box: ClientRect): number {\n return this.vertical ? box.right - box.left : box.bottom - box.top;\n }\n\n getBoxDir(): number {\n return this.vertical ? -1 : 1;\n }\n\n getInlineDir(): number {\n return 1;\n }\n\n copyFrom(other: Container): void {\n this.element = other.element;\n this.left = other.left;\n this.top = other.top;\n this.marginLeft = other.marginLeft;\n this.marginRight = other.marginRight;\n this.marginTop = other.marginTop;\n this.marginBottom = other.marginBottom;\n this.borderLeft = other.borderLeft;\n this.borderRight = other.borderRight;\n this.borderTop = other.borderTop;\n this.borderBottom = other.borderBottom;\n this.paddingLeft = other.paddingLeft;\n this.paddingRight = other.paddingRight;\n this.paddingTop = other.paddingTop;\n this.paddingBottom = other.paddingBottom;\n this.width = other.width;\n this.height = other.height;\n this.originX = other.originX;\n this.originY = other.originY;\n this.innerShape = other.innerShape;\n this.exclusions = other.exclusions;\n this.computedBlockSize = other.computedBlockSize;\n this.snapWidth = other.snapWidth;\n this.snapHeight = other.snapHeight;\n this.vertical = other.vertical;\n }\n\n setVerticalPosition(top: number, height: number): void {\n this.top = top;\n this.height = height;\n Base.setCSSProperty(this.element, \"top\", `${top}px`);\n Base.setCSSProperty(this.element, \"height\", `${height}px`);\n }\n\n setHorizontalPosition(left: number, width: number): void {\n this.left = left;\n this.width = width;\n Base.setCSSProperty(this.element, \"left\", `${left}px`);\n Base.setCSSProperty(this.element, \"width\", `${width}px`);\n }\n\n setBlockPosition(start: number, extent: number): void {\n if (this.vertical) {\n this.setHorizontalPosition(start + extent * this.getBoxDir(), extent);\n } else {\n this.setVerticalPosition(start, extent);\n }\n }\n\n setInlinePosition(start: number, extent: number): void {\n if (this.vertical) {\n this.setVerticalPosition(start, extent);\n } else {\n this.setHorizontalPosition(start, extent);\n }\n }\n\n clear() {\n const parent = this.element;\n let c: Node;\n while ((c = parent.lastChild)) {\n parent.removeChild(c);\n }\n }\n\n getInnerShape(): GeometryUtil.Shape {\n const rect = this.getInnerRect();\n if (this.innerShape) {\n return this.innerShape.withOffset(rect.x1, rect.y1);\n }\n return GeometryUtil.shapeForRect(rect.x1, rect.y1, rect.x2, rect.y2);\n }\n\n getInnerRect(): GeometryUtil.Rect {\n const offsetX = this.originX + this.left + this.getInsetLeft();\n const offsetY = this.originY + this.top + this.getInsetTop();\n return new GeometryUtil.Rect(\n offsetX,\n offsetY,\n offsetX + this.width,\n offsetY + this.height,\n );\n }\n\n getPaddingRect(): GeometryUtil.Rect {\n const paddingX =\n this.originX + this.left + this.marginLeft + this.borderLeft;\n const paddingY = this.originY + this.top + this.marginTop + this.borderTop;\n const paddingWidth = this.paddingLeft + this.width + this.paddingRight;\n const paddingHeight = this.paddingTop + this.height + this.paddingBottom;\n return new GeometryUtil.Rect(\n paddingX,\n paddingY,\n paddingX + paddingWidth,\n paddingY + paddingHeight,\n );\n }\n\n getOuterShape(\n outerShapeProp: Css.Val,\n context: Exprs.Context,\n ): GeometryUtil.Shape {\n const rect = this.getOuterRect();\n return CssProp.toShape(\n outerShapeProp,\n rect.x1,\n rect.y1,\n rect.x2 - rect.x1,\n rect.y2 - rect.y1,\n context,\n );\n }\n\n getOuterRect(): GeometryUtil.Rect {\n const outerX = this.originX + this.left;\n const outerY = this.originY + this.top;\n const outerWidth = this.getInsetLeft() + this.width + this.getInsetRight();\n const outerHeight =\n this.getInsetTop() + this.height + this.getInsetBottom();\n return new GeometryUtil.Rect(\n outerX,\n outerY,\n outerX + outerWidth,\n outerY + outerHeight,\n );\n }\n}\n\nexport type ExprContentListener = Vtree.ExprContentListener;\n\nexport class ContentPropertyHandler extends Css.Visitor {\n constructor(\n public readonly elem: Element,\n public readonly context: Exprs.Context,\n public readonly rootContentValue: Css.Val,\n public readonly exprContentListener: ExprContentListener,\n ) {\n super();\n }\n\n private visitStrInner(str: string, node?: Node | null) {\n if (!node) {\n node = this.elem.ownerDocument.createTextNode(str);\n }\n this.elem.appendChild(node);\n }\n\n /** @override */\n visitStr(str: Css.Str): Css.Val {\n this.visitStrInner(str.str);\n return null;\n }\n\n /** @override */\n visitURL(url: Css.URL): Css.Val {\n if ((this.rootContentValue as any).url) {\n this.elem.setAttribute(\"src\", url.url);\n } else {\n const img = this.elem.ownerDocument.createElementNS(Base.NS.XHTML, \"img\");\n img.setAttribute(\"src\", url.url);\n this.elem.appendChild(img);\n }\n return null;\n }\n\n /** @override */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return null;\n }\n\n /** @override */\n visitExpr(expr: Css.Expr): Css.Val {\n const ex = expr.toExpr();\n let val = ex.evaluate(this.context);\n if (typeof val === \"string\") {\n if (ex instanceof Exprs.Named) {\n // For env(pub-title) and env(doc-title)\n // Need to unquote the result. To be consistent with cssparse.evaluateExprToCSS()\n val = CssParser.parseValue(\n ex.scope,\n new CssTokenizer.Tokenizer(val, null),\n \"\",\n ).stringValue();\n }\n assert(this.elem.ownerDocument);\n const node = this.exprContentListener(ex, val, this.elem.ownerDocument);\n this.visitStrInner(val, node);\n }\n return null;\n }\n}\n\nexport function nonTrivialContent(val: Css.Val): boolean {\n return (\n val != null &&\n val !== Css.ident.normal &&\n val !== Css.ident.none &&\n val !== Css.ident.inherit\n );\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview PageFloats - CSS Page Floats\n */\nimport * as Asserts from \"./asserts\";\nimport * as Css from \"./css\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Logging from \"./logging\";\nimport * as CssLogicalUtil from \"./css-logical-util\";\nimport * as Sizing from \"./sizing\";\nimport * as Task from \"./task\";\nimport * as VtreeImpl from \"./vtree\";\nimport { Layout as LayoutType, PageFloats, Vtree } from \"./types\";\n\nexport const FloatReference = PageFloats.FloatReference;\nexport type FloatReference = PageFloats.FloatReference;\n\ntype PageFloatID = PageFloats.PageFloatID;\n\nexport function floatReferenceOf(str: string): FloatReference {\n switch (str) {\n case \"inline\":\n return FloatReference.INLINE;\n case \"column\":\n return FloatReference.COLUMN;\n case \"region\":\n return FloatReference.REGION;\n case \"page\":\n return FloatReference.PAGE;\n default:\n throw new Error(`Unknown float-reference: ${str}`);\n }\n}\n\nexport function isPageFloat(floatReference: FloatReference): boolean {\n switch (floatReference) {\n case FloatReference.INLINE:\n return false;\n case FloatReference.COLUMN:\n case FloatReference.REGION:\n case FloatReference.PAGE:\n return true;\n default:\n throw new Error(`Unknown float-reference: ${floatReference}`);\n }\n}\n\n/**\n * Interpret a float value with the writing-mode and direction assuming the\n * float-reference is inline and returns \"left\" or \"right\".\n */\nexport function resolveInlineFloatDirection(\n floatSide: string,\n vertical: boolean,\n direction: string,\n): string {\n const writingMode = vertical ? \"vertical-rl\" : \"horizontal-tb\";\n if (floatSide === \"top\" || floatSide === \"bottom\") {\n floatSide = CssLogicalUtil.toLogical(floatSide, writingMode, direction);\n }\n if (floatSide === \"block-start\") {\n floatSide = \"inline-start\";\n }\n if (floatSide === \"block-end\") {\n floatSide = \"inline-end\";\n }\n if (floatSide === \"inline-start\" || floatSide === \"inline-end\") {\n const physicalValue = CssLogicalUtil.toPhysical(\n floatSide,\n writingMode,\n direction,\n );\n const lineRelativeValue = CssLogicalUtil.toLineRelative(\n physicalValue,\n writingMode,\n );\n if (lineRelativeValue === \"line-left\") {\n floatSide = \"left\";\n } else if (lineRelativeValue === \"line-right\") {\n floatSide = \"right\";\n }\n }\n if (floatSide !== \"left\" && floatSide !== \"right\") {\n Logging.logger.warn(`Invalid float value: ${floatSide}. Fallback to left.`);\n floatSide = \"left\";\n }\n return floatSide;\n}\n\nexport class PageFloat implements PageFloats.PageFloat {\n order: number | null = null;\n id: PageFloatID | null = null;\n\n constructor(\n public readonly nodePosition: Vtree.NodePosition,\n public readonly floatReference: FloatReference,\n public readonly floatSide: string,\n public readonly clearSide: string | null,\n public readonly flowName: string,\n public readonly floatMinWrapBlock: Css.Numeric | null,\n ) {}\n\n getOrder(): number {\n if (this.order === null) {\n throw new Error(\"The page float is not yet added\");\n }\n return this.order;\n }\n\n getId(): PageFloatID {\n if (!this.id) {\n throw new Error(\"The page float is not yet added\");\n }\n return this.id;\n }\n\n isAllowedOnContext(pageFloatLayoutContext: PageFloatLayoutContext): boolean {\n return pageFloatLayoutContext.isAnchorAlreadyAppeared(this.getId());\n }\n\n isAllowedToPrecede(other: PageFloat): boolean {\n return false;\n }\n}\n\nexport class PageFloatStore {\n private floats: PageFloat[] = [];\n private nextPageFloatIndex: number = 0;\n\n private nextOrder(): number {\n return this.nextPageFloatIndex++;\n }\n\n private createPageFloatId(order: number): PageFloatID {\n return `pf${order}`;\n }\n\n addPageFloat(float: PageFloat) {\n const index = this.floats.findIndex((f) =>\n VtreeImpl.isSameNodePosition(f.nodePosition, float.nodePosition),\n );\n if (index >= 0) {\n throw new Error(\n \"A page float with the same source node is already registered\",\n );\n } else {\n const order = (float.order = this.nextOrder());\n float.id = this.createPageFloatId(order);\n this.floats.push(float);\n }\n }\n\n findPageFloatByNodePosition(\n nodePosition: Vtree.NodePosition,\n ): PageFloat | null {\n const index = this.floats.findIndex((f) =>\n VtreeImpl.isSameNodePosition(f.nodePosition, nodePosition),\n );\n return index >= 0 ? this.floats[index] : null;\n }\n\n findPageFloatById(id: PageFloatID) {\n const index = this.floats.findIndex((f) => f.id === id);\n return index >= 0 ? this.floats[index] : null;\n }\n}\n\n/**\n * @param continues Represents whether the float is fragmented and continues\n * after this fragment\n */\nexport class PageFloatFragment implements PageFloats.PageFloatFragment {\n constructor(\n public readonly floatReference: FloatReference,\n public readonly floatSide: string,\n public readonly continuations: PageFloatContinuation[],\n public readonly area: Vtree.Container,\n public readonly continues: boolean,\n ) {}\n\n hasFloat(float: PageFloat): boolean {\n return this.continuations.some((c) => c.float === float);\n }\n\n findNotAllowedFloat(context: PageFloatLayoutContext): PageFloat | null {\n for (let i = this.continuations.length - 1; i >= 0; i--) {\n const f = this.continuations[i].float;\n if (!f.isAllowedOnContext(context)) {\n return f;\n }\n }\n return null;\n }\n\n getOuterShape(): GeometryUtil.Shape {\n return this.area.getOuterShape(null, null);\n }\n\n getOuterRect(): GeometryUtil.Rect {\n return this.area.getOuterRect();\n }\n\n getOrder(): number {\n const floats = this.continuations.map((c) => c.float);\n return Math.min.apply(\n null,\n floats.map((f) => f.getOrder()),\n );\n }\n\n shouldBeStashedBefore(float: PageFloat): boolean {\n return this.getOrder() < float.getOrder();\n }\n\n addContinuations(continuations: PageFloatContinuation[]) {\n continuations.forEach((c) => {\n this.continuations.push(c);\n });\n }\n\n getFlowName(): string {\n const flowName = this.continuations[0].float.flowName;\n Asserts.assert(\n this.continuations.every((c) => c.float.flowName === flowName),\n );\n return flowName;\n }\n}\n\nexport class PageFloatContinuation implements PageFloats.PageFloatContinuation {\n constructor(\n public readonly float: PageFloat,\n public readonly nodePosition: Vtree.NodePosition,\n ) {}\n\n equals(other: PageFloatContinuation | null): boolean {\n if (!other) {\n return false;\n }\n if (this === other) {\n return true;\n }\n return (\n this.float === other.float &&\n VtreeImpl.isSameNodePosition(this.nodePosition, other.nodePosition)\n );\n }\n}\n\nexport type PageFloatPlacementCondition = PageFloats.PageFloatPlacementCondition;\n\n/**\n * @param generatingNodePosition Source NodePosition generating the context.\n * Specify when a column context is generated by a non-root element (for\n * example page floats)\n */\nexport class PageFloatLayoutContext\n implements PageFloats.PageFloatLayoutContext {\n private children: PageFloatLayoutContext[] = [];\n writingMode: Css.Val;\n direction: Css.Val;\n private invalidated: boolean = false;\n private floatStore: PageFloatStore;\n private forbiddenFloats: PageFloatID[] = [];\n floatFragments: PageFloatFragment[] = [];\n private stashedFloatFragments: PageFloatFragment[] = [];\n private floatAnchors: { [key in PageFloatID]: Node } = {};\n private floatsDeferredToNext: PageFloatContinuation[] = [];\n private floatsDeferredFromPrevious: PageFloatContinuation[];\n private layoutConstraints: LayoutType.LayoutConstraint[] = [];\n private locked: boolean = false;\n\n constructor(\n public readonly parent: PageFloatLayoutContext,\n private readonly floatReference: FloatReference | null,\n private container: Vtree.Container,\n public readonly flowName: string | null,\n public readonly generatingNodePosition: Vtree.NodePosition | null,\n writingMode: Css.Val | null,\n direction: Css.Val | null,\n ) {\n if (parent) {\n parent.children.push(this);\n }\n this.writingMode =\n writingMode || (parent && parent.writingMode) || Css.ident.horizontal_tb;\n this.direction = direction || (parent && parent.direction) || Css.ident.ltr;\n this.floatStore = parent ? parent.floatStore : new PageFloatStore();\n const previousSibling = this.getPreviousSibling();\n this.floatsDeferredFromPrevious = previousSibling\n ? [].concat(previousSibling.floatsDeferredToNext)\n : [];\n }\n\n private getParent(floatReference: FloatReference): PageFloatLayoutContext {\n if (!this.parent) {\n throw new Error(`No PageFloatLayoutContext for ${floatReference}`);\n }\n return this.parent;\n }\n\n private getPreviousSiblingOf(\n child: PageFloatLayoutContext | null,\n floatReference: FloatReference | null,\n flowName: string | null,\n generatingNodePosition: Vtree.NodePosition | null,\n ): PageFloatLayoutContext | null {\n let index = this.children.indexOf(child as PageFloatLayoutContext);\n if (index < 0) {\n index = this.children.length;\n }\n for (let i = index - 1; i >= 0; i--) {\n let result = this.children[i];\n if (\n result.floatReference === floatReference &&\n result.flowName === flowName &&\n VtreeImpl.isSameNodePosition(\n result.generatingNodePosition,\n generatingNodePosition,\n )\n ) {\n return result;\n } else {\n result = result.getPreviousSiblingOf(\n null,\n floatReference,\n flowName,\n generatingNodePosition,\n );\n if (result) {\n return result;\n }\n }\n }\n return null;\n }\n\n private getPreviousSibling(): PageFloatLayoutContext | null {\n let child: PageFloatLayoutContext = this;\n let parent = this.parent;\n let result: PageFloatLayoutContext;\n while (parent) {\n result = parent.getPreviousSiblingOf(\n child,\n this.floatReference,\n this.flowName,\n this.generatingNodePosition,\n );\n if (result) {\n return result;\n }\n child = parent;\n parent = parent.parent;\n }\n return null;\n }\n\n getContainer(floatReference?: FloatReference): Vtree.Container {\n if (!floatReference || floatReference === this.floatReference) {\n return this.container;\n }\n return this.getParent(floatReference).getContainer(floatReference);\n }\n\n setContainer(container: Vtree.Container) {\n this.container = container;\n this.reattachFloatFragments();\n }\n\n addPageFloat(float: PageFloat) {\n this.floatStore.addPageFloat(float);\n }\n\n getPageFloatLayoutContext(\n floatReference: FloatReference,\n ): PageFloatLayoutContext {\n if (floatReference === this.floatReference) {\n return this;\n }\n return this.getParent(floatReference).getPageFloatLayoutContext(\n floatReference,\n );\n }\n\n findPageFloatByNodePosition(\n nodePosition: Vtree.NodePosition,\n ): PageFloat | null {\n return this.floatStore.findPageFloatByNodePosition(nodePosition);\n }\n\n private forbid(float: PageFloat) {\n const id = float.getId();\n const floatReference = float.floatReference;\n if (floatReference === this.floatReference) {\n if (!this.forbiddenFloats.includes(id)) {\n this.forbiddenFloats.push(id);\n const strategy = new PageFloatLayoutStrategyResolver().findByFloat(\n float,\n );\n strategy.forbid(float, this);\n }\n } else {\n const parent = this.getParent(floatReference);\n parent.forbid(float);\n }\n }\n\n isForbidden(float: PageFloat): boolean {\n const id = float.getId();\n const floatReference = float.floatReference;\n if (floatReference === this.floatReference) {\n return this.forbiddenFloats.includes(id);\n } else {\n const parent = this.getParent(floatReference);\n return parent.isForbidden(float);\n }\n }\n\n addPageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ) {\n const floatReference = floatFragment.floatReference;\n if (floatReference !== this.floatReference) {\n const parent = this.getParent(floatReference);\n parent.addPageFloatFragment(floatFragment, dontInvalidate);\n } else if (!this.floatFragments.includes(floatFragment)) {\n this.floatFragments.push(floatFragment);\n this.floatFragments.sort((fr1, fr2) => fr1.getOrder() - fr2.getOrder());\n }\n if (!dontInvalidate) {\n this.invalidate();\n }\n }\n\n removePageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ) {\n const floatReference = floatFragment.floatReference;\n if (floatReference !== this.floatReference) {\n const parent = this.getParent(floatReference);\n parent.removePageFloatFragment(floatFragment, dontInvalidate);\n } else {\n const index = this.floatFragments.indexOf(floatFragment);\n if (index >= 0) {\n const fragment = this.floatFragments.splice(index, 1)[0];\n const element = fragment.area && fragment.area.element;\n if (element && element.parentNode) {\n element.parentNode.removeChild(element);\n }\n if (!dontInvalidate) {\n this.invalidate();\n }\n }\n }\n }\n\n findPageFloatFragment(float: PageFloat): PageFloatFragment | null {\n if (float.floatReference !== this.floatReference) {\n const parent = this.getParent(float.floatReference);\n return parent.findPageFloatFragment(float);\n }\n const index = this.floatFragments.findIndex((f) => f.hasFloat(float));\n if (index >= 0) {\n return this.floatFragments[index];\n } else {\n return null;\n }\n }\n\n hasFloatFragments(condition?: (p1: PageFloatFragment) => boolean): boolean {\n if (this.floatFragments.length > 0) {\n if (!condition || this.floatFragments.some(condition)) {\n return true;\n }\n }\n if (this.parent) {\n return this.parent.hasFloatFragments(condition);\n } else {\n return false;\n }\n }\n\n hasContinuingFloatFragmentsInFlow(flowName: string): boolean {\n return this.hasFloatFragments(\n (fragment) => fragment.continues && fragment.getFlowName() === flowName,\n );\n }\n\n registerPageFloatAnchor(float: PageFloat, anchorViewNode: Node) {\n this.floatAnchors[float.getId()] = anchorViewNode;\n }\n\n collectPageFloatAnchors() {\n const anchors = Object.assign({}, this.floatAnchors);\n return this.children.reduce(\n (prev, child) => Object.assign(prev, child.collectPageFloatAnchors()),\n anchors,\n );\n }\n\n isAnchorAlreadyAppeared(floatId: PageFloatID) {\n const deferredFloats = this.getDeferredPageFloatContinuations();\n if (deferredFloats.some((cont) => cont.float.getId() === floatId)) {\n return true;\n }\n const floatAnchors = this.collectPageFloatAnchors();\n const anchorViewNode = floatAnchors[floatId];\n if (!anchorViewNode) {\n return false;\n }\n if (this.container && this.container.element) {\n return this.container.element.contains(anchorViewNode);\n }\n return false;\n }\n\n deferPageFloat(continuation: PageFloatContinuation) {\n const float = continuation.float;\n if (float.floatReference === this.floatReference) {\n const index = this.floatsDeferredToNext.findIndex(\n (c) => c.float === float,\n );\n if (index >= 0) {\n this.floatsDeferredToNext.splice(index, 1, continuation);\n } else {\n this.floatsDeferredToNext.push(continuation);\n }\n } else {\n const parent = this.getParent(float.floatReference);\n parent.deferPageFloat(continuation);\n }\n }\n\n hasPrecedingFloatsDeferredToNext(\n float: PageFloat,\n ignoreReference?: boolean,\n ): boolean {\n if (!ignoreReference && float.floatReference !== this.floatReference) {\n return this.getParent(\n float.floatReference,\n ).hasPrecedingFloatsDeferredToNext(float, false);\n }\n const order = float.getOrder();\n const hasPrecedingFloatsDeferredToNext = this.floatsDeferredToNext.some(\n (c) => c.float.getOrder() < order && !float.isAllowedToPrecede(c.float),\n );\n if (hasPrecedingFloatsDeferredToNext) {\n return true;\n } else if (this.parent) {\n return this.parent.hasPrecedingFloatsDeferredToNext(float, true);\n } else {\n return false;\n }\n }\n\n getLastFollowingFloatInFragments(float: PageFloat): PageFloat | null {\n const order = float.getOrder();\n let lastFollowing: PageFloat = null;\n this.floatFragments.forEach((fragment) => {\n fragment.continuations.forEach((c) => {\n const f = c.float;\n const o = f.getOrder();\n if (o > order && (!lastFollowing || o > lastFollowing.getOrder())) {\n lastFollowing = f;\n }\n });\n });\n if (this.parent) {\n const lastFollowingOfParent = this.parent.getLastFollowingFloatInFragments(\n float,\n );\n if (\n lastFollowingOfParent &&\n (!lastFollowing ||\n lastFollowingOfParent.getOrder() > lastFollowing.getOrder())\n ) {\n lastFollowing = lastFollowingOfParent;\n }\n }\n return lastFollowing;\n }\n\n getDeferredPageFloatContinuations(\n flowName?: string | null,\n ): PageFloatContinuation[] {\n flowName = flowName || this.flowName;\n let result = this.floatsDeferredFromPrevious.filter(\n (cont) => !flowName || cont.float.flowName === flowName,\n );\n if (this.parent) {\n result = this.parent\n .getDeferredPageFloatContinuations(flowName)\n .concat(result);\n }\n return result.sort((c1, c2) => c1.float.getOrder() - c2.float.getOrder());\n }\n\n getPageFloatContinuationsDeferredToNext(\n flowName?: string | null,\n ): PageFloatContinuation[] {\n flowName = flowName || this.flowName;\n const result = this.floatsDeferredToNext.filter(\n (cont) => !flowName || cont.float.flowName === flowName,\n );\n if (this.parent) {\n return this.parent\n .getPageFloatContinuationsDeferredToNext(flowName)\n .concat(result);\n } else {\n return result;\n }\n }\n\n getFloatsDeferredToNextInChildContexts(): PageFloat[] {\n let result = [];\n const done = [];\n for (let i = this.children.length - 1; i >= 0; i--) {\n const child = this.children[i];\n if (done.includes(child.flowName)) {\n continue;\n }\n done.push(child.flowName);\n result = result.concat(child.floatsDeferredToNext.map((c) => c.float));\n result = result.concat(child.getFloatsDeferredToNextInChildContexts());\n }\n return result;\n }\n\n checkAndForbidNotAllowedFloat(): boolean {\n if (this.checkAndForbidFloatFollowingDeferredFloat()) {\n return true;\n }\n for (let i = this.floatFragments.length - 1; i >= 0; i--) {\n const fragment = this.floatFragments[i];\n const notAllowedFloat = fragment.findNotAllowedFloat(this);\n if (notAllowedFloat) {\n if (this.locked) {\n this.invalidate();\n } else {\n this.removePageFloatFragment(fragment);\n this.forbid(notAllowedFloat);\n\n // If the removed float is a block-end/inline-end float,\n // we should re-layout preceding floats with the same float direction.\n this.removeEndFloatFragments(fragment.floatSide);\n }\n return true;\n }\n }\n if (this.floatReference === FloatReference.REGION && this.parent.locked) {\n return this.parent.checkAndForbidNotAllowedFloat();\n }\n return false;\n }\n\n checkAndForbidFloatFollowingDeferredFloat(): boolean {\n const deferredFloats = this.getFloatsDeferredToNextInChildContexts();\n const floatsInFragments = this.floatFragments.reduce(\n (r, fr) => r.concat(fr.continuations.map((c) => c.float)),\n [],\n );\n floatsInFragments.sort((f1, f2) => f2.getOrder() - f1.getOrder());\n for (const float of floatsInFragments) {\n const order = float.getOrder();\n if (\n deferredFloats.some(\n (d) => !float.isAllowedToPrecede(d) && order > d.getOrder(),\n )\n ) {\n if (this.locked) {\n this.invalidate();\n } else {\n this.forbid(float);\n const fragment = this.findPageFloatFragment(float);\n Asserts.assert(fragment);\n this.removePageFloatFragment(fragment);\n }\n return true;\n }\n }\n return false;\n }\n\n finish() {\n if (this.checkAndForbidNotAllowedFloat()) {\n return;\n }\n for (let i = this.floatsDeferredToNext.length - 1; i >= 0; i--) {\n const continuation = this.floatsDeferredToNext[i];\n if (!continuation.float.isAllowedOnContext(this)) {\n if (this.locked) {\n this.invalidate();\n return;\n }\n this.floatsDeferredToNext.splice(i, 1);\n }\n }\n this.floatsDeferredFromPrevious.forEach((continuation) => {\n if (\n this.floatsDeferredToNext.findIndex((c) => continuation.equals(c)) >= 0\n ) {\n return;\n }\n if (this.floatFragments.some((f) => f.hasFloat(continuation.float))) {\n return;\n }\n this.floatsDeferredToNext.push(continuation);\n });\n }\n\n hasSameContainerAs(other: PageFloatLayoutContext): boolean {\n return (\n !!this.container &&\n !!other.container &&\n this.container.element === other.container.element\n );\n }\n\n invalidate() {\n this.invalidated = true;\n if (this.locked) {\n return;\n }\n if (this.container) {\n this.children.forEach((child) => {\n // Since the same container element is shared by a region page float\n // layout context and a column page float layout context in a single\n // column region, view elements of float fragments of the child (column)\n // context need to be removed here.\n if (this.hasSameContainerAs(child)) {\n child.floatFragments.forEach((fragment) => {\n const elem = fragment.area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n }\n });\n this.container.clear();\n }\n this.children.forEach((child) => {\n child.layoutConstraints.splice(0);\n });\n this.children.splice(0);\n Object.keys(this.floatAnchors).forEach((k) => {\n delete this.floatAnchors[k];\n });\n }\n\n detachChildren(): PageFloatLayoutContext[] {\n const children = this.children.splice(0);\n children.forEach((child) => {\n child.floatFragments.forEach((fragment) => {\n const elem = fragment.area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n });\n return children;\n }\n\n attachChildren(children: PageFloatLayoutContext[]) {\n children.forEach((child) => {\n this.children.push(child);\n child.reattachFloatFragments();\n });\n }\n\n isInvalidated() {\n return this.invalidated || (!!this.parent && this.parent.isInvalidated());\n }\n\n validate() {\n this.invalidated = false;\n }\n\n private toLogical(side: string): string {\n const writingMode = this.writingMode.toString();\n const direction = this.direction.toString();\n return CssLogicalUtil.toLogical(side, writingMode, direction);\n }\n\n private toPhysical(side: string): string {\n const writingMode = this.writingMode.toString();\n const direction = this.direction.toString();\n return CssLogicalUtil.toPhysical(side, writingMode, direction);\n }\n\n removeEndFloatFragments(floatSide: string) {\n const logicalFloatSide = this.toLogical(floatSide);\n if (logicalFloatSide === \"block-end\" || logicalFloatSide === \"inline-end\") {\n let i = 0;\n while (i < this.floatFragments.length) {\n const fragment = this.floatFragments[i];\n const logicalFloatSide2 = this.toLogical(fragment.floatSide);\n if (logicalFloatSide2 === logicalFloatSide) {\n this.removePageFloatFragment(fragment);\n } else {\n i++;\n }\n }\n }\n }\n\n stashEndFloatFragments(float: PageFloat) {\n const floatReference = float.floatReference;\n if (floatReference !== this.floatReference) {\n this.getParent(floatReference).stashEndFloatFragments(float);\n return;\n }\n const logicalFloatSide = this.toLogical(float.floatSide);\n if (\n logicalFloatSide === \"block-end\" ||\n logicalFloatSide === \"snap-block\" ||\n logicalFloatSide === \"inline-end\"\n ) {\n let i = 0;\n while (i < this.floatFragments.length) {\n const fragment = this.floatFragments[i];\n const fragmentFloatSide = this.toLogical(fragment.floatSide);\n if (\n (fragmentFloatSide === logicalFloatSide ||\n (logicalFloatSide === \"snap-block\" &&\n fragmentFloatSide === \"block-end\")) &&\n fragment.shouldBeStashedBefore(float)\n ) {\n this.stashedFloatFragments.push(fragment);\n this.floatFragments.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n }\n\n restoreStashedFragments(floatReference: FloatReference) {\n if (floatReference !== this.floatReference) {\n this.getParent(floatReference).restoreStashedFragments(floatReference);\n return;\n }\n this.stashedFloatFragments.forEach((stashed) => {\n this.addPageFloatFragment(stashed, true);\n });\n this.stashedFloatFragments.splice(0);\n }\n\n discardStashedFragments(floatReference: FloatReference) {\n if (floatReference !== this.floatReference) {\n this.getParent(floatReference).discardStashedFragments(floatReference);\n return;\n }\n this.stashedFloatFragments.splice(0);\n }\n\n getStashedFloatFragments(\n floatReference: FloatReference,\n ): PageFloatFragment[] {\n if (floatReference === this.floatReference) {\n return this.stashedFloatFragments\n .concat()\n .sort((fr1, fr2) => fr2.getOrder() - fr1.getOrder()); // return in reverse order\n } else {\n return this.getParent(floatReference).getStashedFloatFragments(\n floatReference,\n );\n }\n }\n\n private getLimitValue(\n side: string,\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n condition?: (p1: PageFloatFragment, p2: PageFloatLayoutContext) => boolean,\n ): number {\n Asserts.assert(this.container);\n const logicalSide = this.toLogical(side);\n const physicalSide = this.toPhysical(side);\n const limit = this.getLimitValueInner(\n logicalSide,\n layoutContext,\n clientLayout,\n condition,\n );\n if (this.parent && this.parent.container) {\n const parentLimit = this.parent.getLimitValue(\n physicalSide,\n layoutContext,\n clientLayout,\n condition,\n );\n switch (physicalSide) {\n case \"top\":\n return Math.max(limit, parentLimit);\n case \"left\":\n return Math.max(limit, parentLimit);\n case \"bottom\":\n return Math.min(limit, parentLimit);\n case \"right\":\n return Math.min(limit, parentLimit);\n default:\n Asserts.fail(\"Should be unreachable\");\n }\n }\n return limit;\n }\n\n private getLimitValueInner(\n logicalSide: string,\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n condition?: (p1: PageFloatFragment, p2: PageFloatLayoutContext) => boolean,\n ): number {\n Asserts.assert(this.container);\n const limits = this.getLimitValuesInner(\n layoutContext,\n clientLayout,\n condition,\n );\n switch (logicalSide) {\n case \"block-start\":\n return this.container.vertical ? limits.right : limits.top;\n case \"block-end\":\n return this.container.vertical ? limits.left : limits.bottom;\n case \"inline-start\":\n return this.container.vertical ? limits.top : limits.left;\n case \"inline-end\":\n return this.container.vertical ? limits.bottom : limits.right;\n default:\n throw new Error(`Unknown logical side: ${logicalSide}`);\n }\n }\n\n private getLimitValuesInner(\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n condition?: (p1: PageFloatFragment, p2: PageFloatLayoutContext) => boolean,\n ): {\n top: number;\n left: number;\n bottom: number;\n right: number;\n floatMinWrapBlockStart: number;\n floatMinWrapBlockEnd: number;\n } {\n Asserts.assert(this.container);\n const offsetX = this.container.originX;\n const offsetY = this.container.originY;\n const paddingRect = this.container.getPaddingRect();\n let limits = {\n top: paddingRect.y1 - offsetY,\n left: paddingRect.x1 - offsetX,\n bottom: paddingRect.y2 - offsetY,\n right: paddingRect.x2 - offsetX,\n floatMinWrapBlockStart: 0,\n floatMinWrapBlockEnd: 0,\n };\n\n function resolveLengthPercentage(numeric, viewNode, containerLength) {\n if (numeric.unit === \"%\") {\n return (containerLength * numeric.num) / 100;\n } else {\n return layoutContext.convertLengthToPx(numeric, viewNode, clientLayout);\n }\n }\n const fragments = this.floatFragments;\n if (fragments.length > 0) {\n limits = fragments.reduce((l, f) => {\n if (condition && !condition(f, this)) {\n return l;\n }\n const logicalFloatSide = this.toLogical(f.floatSide);\n const area = f.area;\n const floatMinWrapBlock = f.continuations[0].float.floatMinWrapBlock;\n let top = l.top;\n let left = l.left;\n let bottom = l.bottom;\n let right = l.right;\n let floatMinWrapBlockStart = l.floatMinWrapBlockStart;\n let floatMinWrapBlockEnd = l.floatMinWrapBlockEnd;\n switch (logicalFloatSide) {\n case \"inline-start\":\n if (area.vertical) {\n top = Math.max(top, area.top + area.height);\n } else {\n left = Math.max(left, area.left + area.width);\n }\n break;\n case \"block-start\":\n if (area.vertical) {\n if (floatMinWrapBlock && area.left < right) {\n floatMinWrapBlockStart = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.x2 - paddingRect.x1,\n ) as number;\n }\n right = Math.min(right, area.left);\n } else {\n if (floatMinWrapBlock && area.top + area.height > top) {\n floatMinWrapBlockStart = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.y2 - paddingRect.y1,\n ) as number;\n }\n top = Math.max(top, area.top + area.height);\n }\n break;\n case \"inline-end\":\n if (area.vertical) {\n bottom = Math.min(bottom, area.top);\n } else {\n right = Math.min(right, area.left);\n }\n break;\n case \"block-end\":\n if (area.vertical) {\n if (floatMinWrapBlock && area.left + area.width > left) {\n floatMinWrapBlockEnd = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.x2 - paddingRect.x1,\n ) as number;\n }\n left = Math.max(left, area.left + area.width);\n } else {\n if (floatMinWrapBlock && area.top < bottom) {\n floatMinWrapBlockEnd = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.y2 - paddingRect.y1,\n ) as number;\n }\n bottom = Math.min(bottom, area.top);\n }\n break;\n default:\n throw new Error(`Unknown logical float side: ${logicalFloatSide}`);\n }\n return {\n top,\n left,\n bottom,\n right,\n floatMinWrapBlockStart,\n floatMinWrapBlockEnd,\n };\n }, limits);\n }\n limits.left += offsetX;\n limits.right += offsetX;\n limits.top += offsetY;\n limits.bottom += offsetY;\n return limits;\n }\n\n /**\n * @param anchorEdge Null indicates that the anchor is not in the current\n * container.\n * @return Logical float side (snap-block is resolved when init=false). Null\n * indicates that the float area does not fit inside the container\n */\n setFloatAreaDimensions(\n area: LayoutType.PageFloatArea,\n floatReference: FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n init: boolean,\n force: boolean,\n condition: PageFloatPlacementCondition,\n ): string | null {\n if (floatReference !== this.floatReference) {\n const parent = this.getParent(floatReference);\n return parent.setFloatAreaDimensions(\n area,\n floatReference,\n floatSide,\n anchorEdge,\n init,\n force,\n condition,\n );\n }\n let logicalFloatSide = this.toLogical(floatSide);\n if (logicalFloatSide === \"snap-block\") {\n if (!condition[\"block-start\"] && !condition[\"block-end\"]) {\n return null;\n }\n } else {\n if (!condition[logicalFloatSide]) {\n return null;\n }\n }\n Asserts.assert(area.clientLayout);\n let blockStart = this.getLimitValue(\n \"block-start\",\n area.layoutContext,\n area.clientLayout,\n );\n let blockEnd = this.getLimitValue(\n \"block-end\",\n area.layoutContext,\n area.clientLayout,\n );\n let inlineStart = this.getLimitValue(\n \"inline-start\",\n area.layoutContext,\n area.clientLayout,\n );\n let inlineEnd = this.getLimitValue(\n \"inline-end\",\n area.layoutContext,\n area.clientLayout,\n );\n const blockOffset = area.vertical ? area.originX : area.originY;\n const inlineOffset = area.vertical ? area.originY : area.originX;\n blockStart = area.vertical\n ? Math.min(\n blockStart,\n area.left +\n area.getInsetLeft() +\n area.width +\n area.getInsetRight() +\n blockOffset,\n )\n : Math.max(blockStart, area.top + blockOffset);\n blockEnd = area.vertical\n ? Math.max(blockEnd, area.left + blockOffset)\n : Math.min(\n blockEnd,\n area.top +\n area.getInsetTop() +\n area.height +\n area.getInsetBottom() +\n blockOffset,\n );\n\n function limitBlockStartEndValueWithOpenRect(getRect, rect) {\n let openRect = getRect(area.bands, rect);\n if (openRect) {\n if (area.vertical) {\n openRect = GeometryUtil.unrotateBox(openRect);\n }\n blockStart = area.vertical\n ? Math.min(blockStart, openRect.x2)\n : Math.max(blockStart, openRect.y1);\n blockEnd = area.vertical\n ? Math.max(blockEnd, openRect.x1)\n : Math.min(blockEnd, openRect.y2);\n return true;\n } else {\n return force;\n }\n }\n let blockSize: number;\n let inlineSize: number;\n let outerBlockSize: number;\n let outerInlineSize: number;\n if (init) {\n const rect = area.vertical\n ? GeometryUtil.rotateBox(\n new GeometryUtil.Rect(blockEnd, inlineStart, blockStart, inlineEnd),\n )\n : new GeometryUtil.Rect(inlineStart, blockStart, inlineEnd, blockEnd);\n if (\n logicalFloatSide === \"block-start\" ||\n logicalFloatSide === \"snap-block\" ||\n logicalFloatSide === \"inline-start\"\n ) {\n if (\n !limitBlockStartEndValueWithOpenRect(\n GeometryUtil.findUppermostFullyOpenRect,\n rect,\n )\n ) {\n return null;\n }\n }\n if (\n logicalFloatSide === \"block-end\" ||\n logicalFloatSide === \"snap-block\" ||\n logicalFloatSide === \"inline-end\"\n ) {\n if (\n !limitBlockStartEndValueWithOpenRect(\n GeometryUtil.findBottommostFullyOpenRect,\n rect,\n )\n ) {\n return null;\n }\n }\n outerBlockSize = (blockEnd - blockStart) * area.getBoxDir();\n blockSize = outerBlockSize - area.getInsetBefore() - area.getInsetAfter();\n outerInlineSize = inlineEnd - inlineStart;\n inlineSize = outerInlineSize - area.getInsetStart() - area.getInsetEnd();\n if (!force && (blockSize <= 0 || inlineSize <= 0)) {\n return null;\n }\n } else {\n blockSize = area.computedBlockSize;\n outerBlockSize = blockSize + area.getInsetBefore() + area.getInsetAfter();\n const availableBlockSize = (blockEnd - blockStart) * area.getBoxDir();\n if (logicalFloatSide === \"snap-block\") {\n if (anchorEdge === null) {\n // Deferred from previous container\n logicalFloatSide = \"block-start\";\n } else {\n const containerRect = this.container.getPaddingRect();\n const fromStart =\n this.container.getBoxDir() *\n (anchorEdge -\n (this.container.vertical ? containerRect.x2 : containerRect.y1));\n const fromEnd =\n this.container.getBoxDir() *\n ((this.container.vertical ? containerRect.x1 : containerRect.y2) -\n anchorEdge -\n outerBlockSize);\n if (fromStart <= fromEnd) {\n logicalFloatSide = \"block-start\";\n } else {\n logicalFloatSide = \"block-end\";\n }\n }\n if (!condition[logicalFloatSide]) {\n if (condition[\"block-end\"]) {\n logicalFloatSide = \"block-end\";\n } else {\n return null;\n }\n }\n }\n if (!force && availableBlockSize < outerBlockSize) {\n return null;\n }\n if (\n logicalFloatSide === \"inline-start\" ||\n logicalFloatSide === \"inline-end\"\n ) {\n inlineSize = Sizing.getSize(area.clientLayout, area.element, [\n Sizing.Size.FIT_CONTENT_INLINE_SIZE,\n ])[Sizing.Size.FIT_CONTENT_INLINE_SIZE];\n } else if (area.adjustContentRelativeSize) {\n inlineSize = area.getContentInlineSize();\n } else {\n inlineSize = area.vertical ? area.height : area.width;\n }\n outerInlineSize = inlineSize + area.getInsetStart() + area.getInsetEnd();\n const availableInlineSize = inlineEnd - inlineStart;\n if (!force && availableInlineSize < outerInlineSize) {\n return null;\n }\n }\n blockStart -= blockOffset;\n blockEnd -= blockOffset;\n inlineStart -= inlineOffset;\n inlineEnd -= inlineOffset;\n switch (logicalFloatSide) {\n case \"inline-start\":\n case \"block-start\":\n case \"snap-block\":\n area.setInlinePosition(inlineStart, inlineSize);\n area.setBlockPosition(blockStart, blockSize);\n break;\n case \"inline-end\":\n case \"block-end\":\n area.setInlinePosition(inlineEnd - outerInlineSize, inlineSize);\n area.setBlockPosition(\n blockEnd - outerBlockSize * area.getBoxDir(),\n blockSize,\n );\n break;\n default:\n throw new Error(`unknown float direction: ${floatSide}`);\n }\n return logicalFloatSide;\n }\n\n getFloatFragmentExclusions(): GeometryUtil.Shape[] {\n const result = this.floatFragments.map((fragment) =>\n fragment.getOuterShape(),\n );\n if (this.parent) {\n return this.parent.getFloatFragmentExclusions().concat(result);\n } else {\n return result;\n }\n }\n\n private reattachFloatFragments() {\n const parent = this.container.element && this.container.element.parentNode;\n if (parent) {\n this.floatFragments.forEach((fragment) => {\n parent.appendChild(fragment.area.element);\n });\n }\n }\n\n getMaxReachedAfterEdge(): number {\n const isVertical = this.getContainer().vertical;\n return this.floatFragments.reduce(\n (edge, fragment) => {\n const rect = fragment.getOuterRect();\n if (isVertical) {\n return Math.min(edge, rect.x1);\n } else {\n return Math.max(edge, rect.y2);\n }\n },\n isVertical ? Infinity : 0,\n );\n }\n\n getBlockStartEdgeOfBlockEndFloats(): number {\n const isVertical = this.getContainer().vertical;\n return this.floatFragments\n .filter((fragment) => fragment.floatSide === \"block-end\")\n .reduce(\n (edge, fragment) => {\n const rect = fragment.getOuterRect();\n if (isVertical) {\n return Math.max(edge, rect.x2);\n } else {\n return Math.min(edge, rect.y1);\n }\n },\n isVertical ? 0 : Infinity,\n );\n }\n\n getPageFloatClearEdge(clear: string, column: LayoutType.Column): number {\n function isContinuationOfAlreadyAppearedFloat(context) {\n return (continuation) =>\n context.isAnchorAlreadyAppeared(continuation.float.getId());\n }\n\n function isFragmentWithAlreadyAppearedFloat(fragment, context) {\n return fragment.continuations.some(\n isContinuationOfAlreadyAppearedFloat(context),\n );\n }\n const columnRect = column.getPaddingRect();\n const columnBlockEnd = column.vertical ? columnRect.x1 : columnRect.y2;\n let context: PageFloatLayoutContext = this;\n while (context) {\n if (\n context.floatsDeferredToNext.some(\n isContinuationOfAlreadyAppearedFloat(context),\n )\n ) {\n return columnBlockEnd;\n }\n context = context.parent;\n }\n Asserts.assert(column.clientLayout);\n const blockStartLimit = this.getLimitValue(\n \"block-start\",\n column.layoutContext,\n column.clientLayout,\n isFragmentWithAlreadyAppearedFloat,\n );\n const blockEndLimit = this.getLimitValue(\n \"block-end\",\n column.layoutContext,\n column.clientLayout,\n isFragmentWithAlreadyAppearedFloat,\n );\n if (\n blockEndLimit * column.getBoxDir() <\n columnBlockEnd * column.getBoxDir()\n ) {\n return columnBlockEnd;\n } else {\n return blockStartLimit;\n }\n }\n\n getPageFloatPlacementCondition(\n float: PageFloat,\n floatSide: string,\n clearSide: string | null,\n ): PageFloatPlacementCondition {\n if (float.floatReference !== this.floatReference) {\n const parent = this.getParent(float.floatReference);\n return parent.getPageFloatPlacementCondition(float, floatSide, clearSide);\n }\n const result: PageFloatPlacementCondition = {\n \"block-start\": true,\n \"block-end\": true,\n \"inline-start\": true,\n \"inline-end\": true,\n };\n if (!clearSide) {\n return result;\n }\n const logicalFloatSide = this.toLogical(floatSide);\n const logicalClearSide = this.toLogical(clearSide);\n let logicalSides: string[];\n if (logicalClearSide === \"all\") {\n logicalSides = [\"block-start\", \"block-end\", \"inline-start\", \"inline-end\"];\n } else if (logicalClearSide === \"both\") {\n logicalSides = [\"inline-start\", \"inline-end\"];\n } else if (logicalClearSide === \"same\") {\n if (logicalFloatSide === \"snap-block\") {\n logicalSides = [\"block-start\", \"block-end\"];\n } else {\n logicalSides = [logicalFloatSide];\n }\n } else {\n logicalSides = [logicalClearSide];\n }\n const floatOrder = float.getOrder();\n\n function isPrecedingFragment(\n side: string,\n ): (p1: PageFloatFragment) => boolean {\n return (fragment) =>\n fragment.floatSide === side && fragment.getOrder() < floatOrder;\n }\n\n function hasPrecedingFragmentInChildren(\n context: PageFloatLayoutContext,\n side: string,\n ): boolean {\n return context.children.some(\n (child) =>\n child.floatFragments.some(isPrecedingFragment(side)) ||\n hasPrecedingFragmentInChildren(child, side),\n );\n }\n\n function hasPrecedingFragmentInParents(\n context: PageFloatLayoutContext,\n side: string,\n ): boolean {\n const parent = context.parent;\n return (\n !!parent &&\n (parent.floatFragments.some(isPrecedingFragment(side)) ||\n hasPrecedingFragmentInParents(parent, side))\n );\n }\n logicalSides.forEach((side) => {\n switch (side) {\n case \"block-start\":\n case \"inline-start\":\n result[side] = !hasPrecedingFragmentInChildren(this, side);\n break;\n case \"block-end\":\n case \"inline-end\":\n result[side] = !hasPrecedingFragmentInParents(this, side);\n break;\n default:\n throw new Error(`Unexpected side: ${side}`);\n }\n });\n return result;\n }\n\n getLayoutConstraints(): LayoutType.LayoutConstraint[] {\n const constraints = this.parent ? this.parent.getLayoutConstraints() : [];\n return constraints.concat(this.layoutConstraints);\n }\n\n addLayoutConstraint(\n layoutConstraint: LayoutType.LayoutConstraint,\n floatReference: FloatReference,\n ) {\n if (floatReference === this.floatReference) {\n this.layoutConstraints.push(layoutConstraint);\n } else {\n this.getParent(floatReference).addLayoutConstraint(\n layoutConstraint,\n floatReference,\n );\n }\n }\n\n isColumnFullWithPageFloats(column: LayoutType.Column): boolean {\n const layoutContext = column.layoutContext;\n const clientLayout = column.clientLayout;\n Asserts.assert(clientLayout);\n let context: PageFloatLayoutContext = this;\n let limits: {\n top: number;\n left: number;\n bottom: number;\n right: number;\n floatMinWrapBlockStart: number;\n floatMinWrapBlockEnd: number;\n } = null;\n while (context && context.container) {\n const l = context.getLimitValuesInner(layoutContext, clientLayout);\n if (limits) {\n if (column.vertical) {\n if (l.right < limits.right) {\n limits.right = l.right;\n limits.floatMinWrapBlockStart = l.floatMinWrapBlockStart;\n }\n if (l.left > limits.left) {\n limits.left = l.left;\n limits.floatMinWrapBlockEnd = l.floatMinWrapBlockEnd;\n }\n } else {\n if (l.top > limits.top) {\n limits.top = l.top;\n limits.floatMinWrapBlockStart = l.floatMinWrapBlockStart;\n }\n if (l.bottom < limits.bottom) {\n limits.bottom = l.bottom;\n limits.floatMinWrapBlockEnd = l.floatMinWrapBlockEnd;\n }\n }\n } else {\n limits = l;\n }\n context = context.parent;\n }\n const floatMinWrapBlock = Math.max(\n limits.floatMinWrapBlockStart,\n limits.floatMinWrapBlockEnd,\n );\n const blockSpace = column.vertical\n ? limits.right - limits.left\n : limits.bottom - limits.top;\n return blockSpace <= floatMinWrapBlock;\n }\n\n getMaxBlockSizeOfPageFloats(): number {\n const isVertical = this.getContainer().vertical;\n if (!this.floatFragments.length) {\n return 0;\n }\n return Math.max.apply(\n null,\n this.floatFragments.map((fragment) => {\n const area = fragment.area;\n if (isVertical) {\n return area.width;\n } else {\n return area.height;\n }\n }),\n );\n }\n\n lock() {\n this.locked = true;\n }\n\n unlock() {\n this.locked = false;\n }\n\n isLocked(): boolean {\n return this.locked;\n }\n}\n\nexport interface PageFloatLayoutStrategy\n extends PageFloats.PageFloatLayoutStrategy {}\n\nconst pageFloatLayoutStrategies: PageFloatLayoutStrategy[] = [];\n\nexport class PageFloatLayoutStrategyResolver {\n static register(strategy: PageFloatLayoutStrategy) {\n pageFloatLayoutStrategies.push(strategy);\n }\n\n findByNodeContext(nodeContext: Vtree.NodeContext): PageFloatLayoutStrategy {\n for (let i = pageFloatLayoutStrategies.length - 1; i >= 0; i--) {\n const strategy = pageFloatLayoutStrategies[i];\n if (strategy.appliesToNodeContext(nodeContext)) {\n return strategy;\n }\n }\n throw new Error(`No PageFloatLayoutStrategy found for ${nodeContext}`);\n }\n\n findByFloat(float: PageFloat): PageFloatLayoutStrategy {\n for (let i = pageFloatLayoutStrategies.length - 1; i >= 0; i--) {\n const strategy = pageFloatLayoutStrategies[i];\n if (strategy.appliesToFloat(float)) {\n return strategy;\n }\n }\n throw new Error(`No PageFloatLayoutStrategy found for ${float}`);\n }\n}\n\nexport class NormalPageFloatLayoutStrategy implements PageFloatLayoutStrategy {\n /**\n * @override\n */\n appliesToNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return isPageFloat(nodeContext.floatReference);\n }\n\n /**\n * @override\n */\n appliesToFloat(float: PageFloat): boolean {\n return true;\n }\n\n /**\n * @override\n */\n createPageFloat(\n nodeContext: Vtree.NodeContext,\n pageFloatLayoutContext: PageFloatLayoutContext,\n column: LayoutType.Column,\n ): Task.Result<PageFloat> {\n let floatReference = nodeContext.floatReference;\n Asserts.assert(nodeContext.floatSide);\n const floatSide: string = nodeContext.floatSide;\n const nodePosition = nodeContext.toNodePosition();\n return column\n .resolveFloatReferenceFromColumnSpan(\n floatReference,\n nodeContext.columnSpan,\n nodeContext,\n )\n .thenAsync((ref) => {\n floatReference = ref;\n Asserts.assert(pageFloatLayoutContext.flowName);\n const float = new PageFloat(\n nodePosition,\n floatReference,\n floatSide,\n nodeContext.clearSide,\n pageFloatLayoutContext.flowName,\n nodeContext.floatMinWrapBlock,\n );\n pageFloatLayoutContext.addPageFloat(float);\n return Task.newResult(float);\n });\n }\n\n /**\n * @override\n */\n createPageFloatFragment(\n continuations: PageFloatContinuation[],\n floatSide: string,\n floatArea: LayoutType.PageFloatArea,\n continues: boolean,\n ): PageFloatFragment {\n const f = continuations[0].float;\n return new PageFloatFragment(\n f.floatReference,\n floatSide,\n continuations,\n floatArea,\n continues,\n );\n }\n\n /**\n * @override\n */\n findPageFloatFragment(\n float: PageFloat,\n pageFloatLayoutContext: PageFloatLayoutContext,\n ): PageFloatFragment | null {\n return pageFloatLayoutContext.findPageFloatFragment(float);\n }\n\n /**\n * @override\n */\n adjustPageFloatArea(\n floatArea: LayoutType.PageFloatArea,\n floatContainer: Vtree.Container,\n column: LayoutType.Column,\n ) {}\n\n /**\n * @override\n */\n forbid(float: PageFloat, pageFloatLayoutContext: PageFloatLayoutContext) {}\n}\n\nPageFloatLayoutStrategyResolver.register(new NormalPageFloatLayoutStrategy());\n","/**\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Footnotes\n */\nimport * as Asserts from \"./asserts\";\nimport * as Css from \"./css\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Task from \"./task\";\nimport * as Vtree from \"./vtree\";\nimport { Layout } from \"./types\";\n\nconst PageFloatFragment = PageFloats.PageFloatFragment;\n\nexport class Footnote extends PageFloats.PageFloat {\n constructor(\n nodePosition: Vtree.NodePosition,\n floatReference: PageFloats.FloatReference,\n flowName: string,\n public readonly footnotePolicy: Css.Ident | null,\n floatMinWrapBlock: Css.Numeric | null,\n ) {\n super(\n nodePosition,\n floatReference,\n \"block-end\",\n null,\n flowName,\n floatMinWrapBlock,\n );\n }\n\n /**\n * @override\n */\n isAllowedToPrecede(other: PageFloats.PageFloat): boolean {\n return !(other instanceof Footnote);\n }\n}\n\n/**\n * @extends PageFloatFragment\n */\nexport class FootnoteFragment extends PageFloatFragment {\n constructor(\n floatReference: PageFloats.FloatReference,\n continuations: PageFloats.PageFloatContinuation[],\n area: Vtree.Container,\n continues: boolean,\n ) {\n super(floatReference, \"block-end\", continuations, area, continues);\n }\n\n /**\n * @override\n */\n getOrder(): number {\n return Infinity;\n }\n\n /**\n * @override\n */\n shouldBeStashedBefore(float: PageFloats.PageFloat): boolean {\n if (float instanceof Footnote) {\n return true;\n } else {\n return this.getOrder() < float.getOrder();\n }\n }\n}\n\nexport class LineFootnotePolicyLayoutConstraint\n implements Layout.LayoutConstraint {\n constructor(public readonly footnote: Footnote) {}\n\n allowLayout(nodeContext: Vtree.NodeContext): boolean {\n const nodePosition = nodeContext.toNodePosition();\n return !Vtree.isSameNodePosition(nodePosition, this.footnote.nodePosition);\n }\n}\n\nexport class FootnoteLayoutStrategy\n implements PageFloats.PageFloatLayoutStrategy {\n /**\n * @override\n */\n appliesToNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return nodeContext.floatSide === \"footnote\";\n }\n\n /**\n * @override\n */\n appliesToFloat(float: PageFloats.PageFloat): boolean {\n return float instanceof Footnote;\n }\n\n /**\n * @override\n */\n createPageFloat(\n nodeContext: Vtree.NodeContext,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n column: Layout.Column,\n ): Task.Result<PageFloats.PageFloat> {\n let floatReference = PageFloats.FloatReference.REGION;\n\n // If the region context has the same container as the page context,\n // use the page context as the context for the footnote.\n const regionContext = pageFloatLayoutContext.getPageFloatLayoutContext(\n floatReference,\n );\n const pageContext = pageFloatLayoutContext.getPageFloatLayoutContext(\n PageFloats.FloatReference.PAGE,\n );\n if (pageContext.hasSameContainerAs(regionContext)) {\n floatReference = PageFloats.FloatReference.PAGE;\n }\n const nodePosition = nodeContext.toNodePosition();\n Asserts.assert(pageFloatLayoutContext.flowName);\n const float: PageFloats.PageFloat = new Footnote(\n nodePosition,\n floatReference,\n pageFloatLayoutContext.flowName,\n nodeContext.footnotePolicy,\n nodeContext.floatMinWrapBlock,\n );\n pageFloatLayoutContext.addPageFloat(float);\n return Task.newResult(float);\n }\n\n /**\n * @override\n */\n createPageFloatFragment(\n continuations: PageFloats.PageFloatContinuation[],\n floatSide: string,\n floatArea: Layout.PageFloatArea,\n continues: boolean,\n ): PageFloats.PageFloatFragment {\n const f = continuations[0].float;\n return new FootnoteFragment(\n f.floatReference,\n continuations,\n floatArea,\n continues,\n );\n }\n\n /**\n * @override\n */\n findPageFloatFragment(\n float: PageFloats.PageFloat,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ): PageFloats.PageFloatFragment | null {\n const context = pageFloatLayoutContext.getPageFloatLayoutContext(\n float.floatReference,\n );\n const fragments = context.floatFragments.filter(\n (fr) => fr instanceof FootnoteFragment,\n );\n Asserts.assert(fragments.length <= 1);\n return fragments[0] || null;\n }\n\n /**\n * @override\n */\n adjustPageFloatArea(\n floatArea: Layout.PageFloatArea,\n floatContainer: Vtree.Container,\n column: Layout.Column,\n ) {\n floatArea.isFootnote = true;\n floatArea.adjustContentRelativeSize = false;\n const element = floatArea.element;\n Asserts.assert(element);\n floatArea.vertical = column.layoutContext.applyFootnoteStyle(\n floatContainer.vertical,\n (column.layoutContext as any).nodeContext &&\n (column.layoutContext as any).nodeContext.direction === \"rtl\",\n element,\n );\n floatArea.convertPercentageSizesToPx(element);\n column.setComputedInsets(element, floatArea);\n column.setComputedWidthAndHeight(element, floatArea);\n }\n\n /**\n * @override\n */\n forbid(\n float: PageFloats.PageFloat,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ) {\n const footnote = float as Footnote;\n switch (footnote.footnotePolicy) {\n case Css.ident.line: {\n const constraint = new LineFootnotePolicyLayoutConstraint(footnote);\n pageFloatLayoutContext.addLayoutConstraint(\n constraint,\n footnote.floatReference,\n );\n break;\n }\n }\n }\n}\n\nPageFloats.PageFloatLayoutStrategyResolver.register(\n new FootnoteLayoutStrategy(),\n);\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Break - Control fragmentation.\n */\nimport * as Css from \"./css\";\nimport * as Plugin from \"./plugin\";\n\n/**\n * Convert old page-break-* properties to break-* properties with appropriate\n * values as specified by CSS Fragmentation module:\n * https://drafts.csswg.org/css-break/#page-break-properties\n */\nexport function convertPageBreakAliases(original: {\n name: string;\n value: Css.Val;\n important: boolean;\n}): { name: string; value: Css.Val; important: boolean } {\n const name = original[\"name\"];\n const value = original[\"value\"];\n switch (name) {\n case \"page-break-before\":\n case \"page-break-after\":\n case \"page-break-inside\":\n return {\n name: name.replace(/^page-/, \"\"),\n value: value === Css.ident.always ? Css.ident.page : value,\n important: original[\"important\"],\n };\n default:\n return original;\n }\n}\n\nexport const forcedBreakValues: { [key: string]: boolean | null } = {\n page: true,\n left: true,\n right: true,\n recto: true,\n verso: true,\n column: true,\n region: true,\n};\n\n/**\n * Returns if the value is one of the forced break values.\n * @param value The break value to be judged. Treats null as 'auto'.\n */\nexport function isForcedBreakValue(value: string | null): boolean {\n return !!forcedBreakValues[value];\n}\n\nexport const avoidBreakValues: { [key: string]: boolean | null } = {\n avoid: true,\n \"avoid-page\": true,\n \"avoid-column\": true,\n \"avoid-region\": true,\n};\n\n/**\n * Returns if the value is one of the avoid break values.\n * @param value The break value to be judged. Treats null as 'auto'.\n */\nexport function isAvoidBreakValue(value: string | null): boolean {\n return !!avoidBreakValues[value];\n}\n\n/**\n * Resolves the effective break value given two break values at a single break\n * point. The order of the arguments are relevant, since a value specified on\n * the latter element takes precedence over one on the former. A forced break\n * value is chosen if present. Otherwise, an avoid break value is chosen if\n * present. See CSS Fragmentation Module for the rule:\n * https://drafts.csswg.org/css-break/#forced-breaks\n * https://drafts.csswg.org/css-break/#unforced-breaks\n * Note that though the spec requires to honor multiple break values at a single\n * break point, the current implementation choose one of them and discard the\n * others.\n * @param first The break value specified on the former element. null means\n * 'auto' (not specified)\n * @param second The break value specified on the latter element. null means\n * 'auto' (not specified)\n */\nexport function resolveEffectiveBreakValue(\n first: string | null,\n second: string | null,\n): string | null {\n if (!first) {\n return second;\n } else if (!second) {\n return first;\n } else {\n const firstIsForcedBreakValue = isForcedBreakValue(first);\n const secondIsForcedBreakValue = isForcedBreakValue(second);\n if (firstIsForcedBreakValue && secondIsForcedBreakValue) {\n switch (second) {\n case \"column\":\n // \"column\" is the weakest value\n return first;\n case \"region\":\n // \"region\" is stronger than \"column\" but weaker than page\n // values\n return first === \"column\" ? second : first;\n default:\n // page values are strongest\n return second;\n }\n } else if (secondIsForcedBreakValue) {\n return second;\n } else if (firstIsForcedBreakValue) {\n return first;\n } else if (isAvoidBreakValue(second)) {\n return second;\n } else if (isAvoidBreakValue(first)) {\n return first;\n } else {\n return second;\n }\n }\n}\n\nexport function breakValueToStartSideValue(breakValue: string | null): string {\n switch (breakValue) {\n case \"left\":\n case \"right\":\n case \"recto\":\n case \"verso\":\n return breakValue;\n default:\n return \"any\";\n }\n}\n\nexport function startSideValueToBreakValue(\n startSideValue: string,\n): string | null {\n switch (startSideValue) {\n case \"left\":\n case \"right\":\n case \"recto\":\n case \"verso\":\n return startSideValue;\n default:\n return null;\n }\n}\n\nPlugin.registerHook(\"SIMPLE_PROPERTY\", convertPageBreakAliases);\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutHelper - Helper functions of Layout.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\nimport * as VtreeImpl from \"./vtree\";\nimport { Layout, Vtree } from \"./types\";\n\n/**\n * Though method used to be used as a workaround for Chrome bug, it seems that\n * the bug has been already fixed:\n * https://bugs.chromium.org/p/chromium/issues/detail?id=297808\n * We now use this method as a workaround for Firefox bug:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1159309\n */\nexport function fixBoxesForNode(\n clientLayout: Vtree.ClientLayout,\n boxes: Vtree.ClientRect[],\n node: Node,\n): Vtree.ClientRect[] {\n const fullRange = node.ownerDocument.createRange();\n fullRange.setStart(node, 0);\n fullRange.setEnd(node, node.textContent.length);\n const fullBoxes = clientLayout.getRangeClientRects(fullRange);\n const result = [];\n for (const box of boxes) {\n let k: number;\n for (k = 0; k < fullBoxes.length; k++) {\n const fullBox = fullBoxes[k];\n if (\n box.top >= fullBox.top &&\n box.bottom <= fullBox.bottom &&\n Math.abs(box.left - fullBox.left) < 1\n ) {\n result.push({\n top: box.top,\n left: fullBox.left,\n bottom: box.bottom,\n right: fullBox.right,\n });\n break;\n }\n }\n if (k == fullBoxes.length) {\n Logging.logger.warn(\"Could not fix character box\");\n result.push(box);\n }\n }\n return result;\n}\n\n/**\n * Calculate the position of the \"after\" edge in the block-progression\n * dimension. Return 0 if position was determined successfully and return\n * non-zero if position could not be determined and the node should be\n * considered zero-height.\n */\nexport function calculateEdge(\n nodeContext: Vtree.NodeContext,\n clientLayout: Vtree.ClientLayout,\n extraOffset: number,\n vertical: boolean,\n): number {\n const node = nodeContext.viewNode;\n if (!node) {\n return NaN;\n }\n if (node.nodeType == 1) {\n if (nodeContext.after || !nodeContext.inline) {\n const cbox = clientLayout.getElementClientRect(node as Element);\n if (cbox.right >= cbox.left && cbox.bottom >= cbox.top) {\n if (nodeContext.after) {\n return vertical ? cbox.left : cbox.bottom;\n } else {\n return vertical ? cbox.right : cbox.top;\n }\n }\n }\n return NaN;\n } else {\n let edge = NaN;\n const range = node.ownerDocument.createRange();\n const length = node.textContent.length;\n if (!length) {\n return NaN;\n }\n if (nodeContext.after) {\n extraOffset += length;\n }\n if (extraOffset >= length) {\n extraOffset = length - 1;\n }\n range.setStart(node, extraOffset);\n range.setEnd(node, extraOffset + 1);\n let boxes = clientLayout.getRangeClientRects(range);\n if (vertical && Base.checkVerticalBBoxBug(document.body)) {\n boxes = fixBoxesForNode(clientLayout, boxes, node);\n }\n let maxSize = 0;\n\n // Get first of the widest boxes (works around Chrome results for soft\n // hyphens).\n for (const box of boxes) {\n const boxSize = vertical ? box.bottom - box.top : box.right - box.left;\n if (\n box.right > box.left &&\n box.bottom > box.top &&\n (isNaN(edge) || boxSize > maxSize)\n ) {\n edge = vertical ? box.left : box.bottom;\n maxSize = boxSize;\n }\n }\n return edge;\n }\n}\n\nexport function getElementHeight(\n element: Element,\n column: Layout.Column,\n vertical: boolean,\n): number {\n const rect = column.clientLayout.getElementClientRect(element);\n const margin = column.getComputedMargin(element);\n return vertical\n ? rect[\"width\"] + margin[\"left\"] + margin[\"right\"]\n : rect[\"height\"] + margin[\"top\"] + margin[\"bottom\"];\n}\n\nexport function isOrphan(node: Node): boolean {\n while (node) {\n if (node.parentNode === node.ownerDocument) {\n return false;\n }\n node = node.parentNode;\n }\n return true;\n}\n\nexport function removeFollowingSiblings(\n parentNode: Node,\n viewNode: Node,\n): void {\n if (!parentNode) {\n return;\n }\n let lastChild: Node;\n while ((lastChild = parentNode.lastChild) != viewNode) {\n parentNode.removeChild(lastChild);\n }\n}\n\nexport function isSpecial(e: Element): boolean {\n return !!e.getAttribute(VtreeImpl.SPECIAL_ATTR);\n}\n\nexport function isSpecialNodeContext(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext) {\n return false;\n }\n const viewNode = nodeContext.viewNode;\n if (viewNode && viewNode.nodeType === 1) {\n return isSpecial(viewNode as Element);\n } else {\n return false;\n }\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview BreakPosition - Definitions of BreakPosition.\n */\nimport * as Break from \"./break\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport { Layout, RepetitiveElement, Vtree } from \"./types\";\n\n/**\n * Potential breaking position.\n */\nexport type BreakPosition = Layout.BreakPosition;\n\nexport abstract class AbstractBreakPosition\n implements Layout.AbstractBreakPosition {\n abstract findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext;\n\n abstract getMinBreakPenalty(): number;\n\n calculateOffset(column): { current: number; minimum: number } {\n return calculateOffset(\n this.getNodeContext(),\n column.collectElementsOffset(),\n );\n }\n\n /**\n * @override\n */\n breakPositionChosen(column: Layout.Column): void {}\n\n getNodeContext(): Vtree.NodeContext {\n return null;\n }\n}\n\nexport function calculateOffset(\n nodeContext: Vtree.NodeContext,\n elementsOffsets: RepetitiveElement.ElementsOffset[],\n): { current: number; minimum: number } {\n return {\n current: elementsOffsets.reduce(\n (val, repetitiveElement) =>\n val + repetitiveElement.calculateOffset(nodeContext),\n 0,\n ),\n minimum: elementsOffsets.reduce(\n (val, repetitiveElement) =>\n val + repetitiveElement.calculateMinimumOffset(nodeContext),\n 0,\n ),\n };\n}\n\n/**\n * Potential edge breaking position.\n */\nexport class EdgeBreakPosition extends AbstractBreakPosition\n implements Layout.EdgeBreakPosition {\n overflowIfRepetitiveElementsDropped: boolean;\n protected isEdgeUpdated: boolean = false;\n private edge: number = 0;\n\n constructor(\n public readonly position: Vtree.NodeContext,\n public readonly breakOnEdge: string | null,\n public overflows: boolean,\n public readonly computedBlockSize: number,\n ) {\n super();\n this.overflowIfRepetitiveElementsDropped = overflows;\n }\n\n /**\n * @override\n */\n findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext {\n this.updateOverflows(column);\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n return column.findEdgeBreakPosition(this);\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n if (!this.isEdgeUpdated) {\n throw new Error(\"EdgeBreakPosition.prototype.updateEdge not called\");\n }\n const preferDropping =\n this.isFirstContentOfRepetitiveElementsOwner() &&\n !this.overflowIfRepetitiveElementsDropped;\n return (\n (Break.isAvoidBreakValue(this.breakOnEdge) ? 1 : 0) +\n (this.overflows && !preferDropping ? 3 : 0) +\n (this.position.parent ? this.position.parent.breakPenalty : 0)\n );\n }\n\n private updateEdge(column: Layout.Column) {\n const clonedPaddingBorder = column.calculateClonedPaddingBorder(\n this.position,\n );\n this.edge =\n LayoutHelper.calculateEdge(\n this.position,\n column.clientLayout,\n 0,\n column.vertical,\n ) + clonedPaddingBorder;\n this.isEdgeUpdated = true;\n }\n\n private updateOverflows(column: Layout.Column) {\n if (!this.isEdgeUpdated) {\n this.updateEdge(column);\n }\n const edge = this.edge;\n const offsets = this.calculateOffset(column);\n this.overflowIfRepetitiveElementsDropped = column.isOverflown(\n edge + (column.vertical ? -1 : 1) * offsets.minimum,\n );\n this.overflows = this.position.overflow = column.isOverflown(\n edge + (column.vertical ? -1 : 1) * offsets.current,\n );\n }\n\n /** @override */\n getNodeContext(): Vtree.NodeContext {\n return this.position;\n }\n\n private isFirstContentOfRepetitiveElementsOwner(): boolean {\n const nodeContext = this.getNodeContext();\n if (!nodeContext || !nodeContext.parent) {\n return false;\n }\n const { formattingContext } = nodeContext.parent;\n if (\n !RepetitiveElement.isInstanceOfRepetitiveElementsOwnerFormattingContext(\n formattingContext,\n )\n ) {\n return false;\n }\n\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (!repetitiveElements) {\n return false;\n }\n return repetitiveElements.isFirstContentNode(nodeContext);\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Display - CSS Display Module\n */\nimport * as Css from \"./css\";\n\nexport const FLOW_ROOT_ATTR = \"data-vivliostyle-flow-root\";\n\nexport function isFlowRoot(element: Element): boolean {\n return element.getAttribute(FLOW_ROOT_ATTR) === \"true\";\n}\n\n/**\n * 'Blockify' a display value.\n * cf. https://drafts.csswg.org/css-display/#transformations\n * https://drafts.csswg.org/css2/visuren.html#dis-pos-flo\n */\nexport function blockify(display: Css.Ident): Css.Ident {\n const displayStr = display.toString();\n let blockifiedStr: string;\n switch (displayStr) {\n case \"inline-flex\":\n blockifiedStr = \"flex\";\n break;\n case \"inline-grid\":\n blockifiedStr = \"grid\";\n break;\n case \"inline-table\":\n blockifiedStr = \"table\";\n break;\n case \"inline\":\n case \"table-row-group\":\n case \"table-column\":\n case \"table-column-group\":\n case \"table-header-group\":\n case \"table-footer-group\":\n case \"table-row\":\n case \"table-cell\":\n case \"table-caption\":\n case \"inline-block\":\n blockifiedStr = \"block\";\n break;\n default:\n blockifiedStr = displayStr;\n }\n return Css.getName(blockifiedStr);\n}\n\n/**\n * Judge if the generated box is absolutely positioned.\n */\nexport function isAbsolutelyPositioned(position: Css.Ident): boolean {\n return position === Css.ident.absolute || position === Css.ident.fixed;\n}\n\n/**\n * Get computed values of display, position and float.\n * cf. https://drafts.csswg.org/css-display/#transformations\n * https://drafts.csswg.org/css2/visuren.html#dis-pos-flo\n */\nexport function getComputedDislayValue(\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n isRoot: boolean,\n): { display: Css.Ident; position: Css.Ident; float: Css.Ident } {\n if (display === Css.ident.none) {\n // no need to convert values when 'display' is 'none'\n } else if (isAbsolutelyPositioned(position)) {\n float = Css.ident.none;\n display = blockify(display);\n } else if ((float && float !== Css.ident.none) || isRoot) {\n display = blockify(display);\n }\n return { display, position, float };\n}\n\n/**\n * Judges if the generated box is block.\n */\nexport function isBlock(\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n isRoot: boolean,\n): boolean {\n return (\n getComputedDislayValue(display, position, float, isRoot).display ===\n Css.ident.block\n );\n}\n\nexport function isInlineLevel(display: Css.Ident): boolean {\n switch (display.toString()) {\n case \"inline\":\n case \"inline-block\":\n case \"inline-list-item\":\n case \"inline-flex\":\n case \"inline-grid\":\n case \"ruby\":\n case \"inline-table\":\n return true;\n default:\n return false;\n }\n}\n\nexport function isRubyInternalDisplay(display: Css.Ident): boolean {\n switch (display.toString()) {\n case \"ruby-base\":\n case \"ruby-text\":\n case \"ruby-base-container\":\n case \"ruby-text-container\":\n return true;\n default:\n return false;\n }\n}\n\n/**\n * Judges if the generated box establishes a new block formatting context.\n */\nexport function establishesBFC(\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n overflow: Css.Ident,\n writingMode?: Css.Ident,\n parentWritingMode?: Css.Ident,\n isFlowRoot?: boolean,\n): boolean {\n writingMode = writingMode || parentWritingMode || Css.ident.horizontal_tb;\n return (\n !!isFlowRoot ||\n (!!float && float !== Css.ident.none) ||\n isAbsolutelyPositioned(position) ||\n display === Css.ident.inline_block ||\n display === Css.ident.table_cell ||\n display === Css.ident.table_caption ||\n display == Css.ident.flex ||\n ((display === Css.ident.block || display === Css.ident.list_item) &&\n !!overflow &&\n overflow !== Css.ident.visible) ||\n (!!parentWritingMode && writingMode !== parentWritingMode)\n );\n}\n\n/**\n * Judges if the generated box establishes a containing block for descendant\n * boxes with 'position: absolute'.\n */\nexport function establishesCBForAbsolute(position: Css.Ident): boolean {\n return (\n position === Css.ident.relative ||\n position === Css.ident.absolute ||\n position === Css.ident.fixed\n );\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutProcessor - Definitions of LayoutProcessor.\n */\nimport * as BreakPosition from \"./break-position\";\nimport * as Display from \"./display\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as Plugin from \"./plugin\";\nimport * as Task from \"./task\";\nimport { FormattingContextType, Layout, LayoutProcessor, Vtree } from \"./types\";\n\n/**\n * Processor doing some special layout (e.g. table layout)\n */\nexport interface LayoutProcessor {\n /**\n * Do actual layout in the column starting from given NodeContext.\n */\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * Potential edge breaking position.\n */\n createEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ): Layout.BreakPosition;\n\n /**\n * process nodecontext at the start of a non inline element.\n * @return return true if you skip the subsequent nodes\n */\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean;\n\n /**\n * process nodecontext after a non inline element.\n * @return return true if you skip the subsequent nodes\n */\n afterNonInlineElementNode(\n nodeContext: Vtree.NodeContext,\n stopAtOverflow: boolean,\n ): boolean;\n\n /**\n * @return holing true\n */\n finishBreak(\n column: Layout.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean>;\n\n clearOverflownViewNodes(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n );\n}\n\n/**\n * Resolver finding an appropriate LayoutProcessor given a formatting context\n */\nexport class LayoutProcessorResolver {\n /**\n * Find LayoutProcessor corresponding to given formatting context.\n */\n find(formattingContext: Vtree.FormattingContext): LayoutProcessor {\n const hooks: Plugin.ResolveLayoutProcessorHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n );\n for (let i = 0; i < hooks.length; i++) {\n const processor = hooks[i](formattingContext);\n if (processor) {\n return processor;\n }\n }\n throw new Error(\n `No processor found for a formatting context: ${formattingContext.getName()}`,\n );\n }\n}\n\nexport class BlockLayoutProcessor implements LayoutProcessor {\n /**\n * @override\n */\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext> {\n if (column.isFloatNodeContext(nodeContext)) {\n return column.layoutFloatOrFootnote(nodeContext);\n } else if (column.isBreakable(nodeContext)) {\n return column.layoutBreakableBlock(nodeContext);\n } else {\n return column.layoutUnbreakable(nodeContext);\n }\n }\n\n /**\n * @override\n */\n createEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ): Layout.BreakPosition {\n return new BreakPosition.EdgeBreakPosition(\n position.copy(),\n breakOnEdge,\n overflows,\n columnBlockSize,\n );\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean {\n return false;\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n nodeContext: Vtree.NodeContext,\n stopAtOverflow: boolean,\n ): boolean {\n return false;\n }\n\n /**\n * @override\n */\n clearOverflownViewNodes(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ) {\n if (!nodeContext.viewNode) {\n return;\n }\n if (!nodeContext.viewNode.parentNode) {\n return;\n }\n const parentNode = nodeContext.viewNode.parentNode;\n LayoutHelper.removeFollowingSiblings(parentNode, nodeContext.viewNode);\n if (removeSelf) {\n parentNode.removeChild(nodeContext.viewNode);\n }\n }\n\n /**\n * @return holing true\n * @override\n */\n finishBreak(\n column: Layout.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n const removeSelf =\n forceRemoveSelf ||\n (nodeContext.viewNode != null &&\n nodeContext.viewNode.nodeType == 1 &&\n !nodeContext.after);\n column.clearOverflownViewNodes(nodeContext, removeSelf);\n if (endOfColumn) {\n column.fixJustificationIfNeeded(nodeContext, true);\n column.layoutContext.processFragmentedBlockEdge(\n removeSelf ? nodeContext : nodeContext.parent,\n );\n }\n return Task.newResult(true);\n }\n}\n\nexport class BlockFormattingContext\n implements LayoutProcessor.BlockFormattingContext {\n formattingContextType: FormattingContextType = \"Block\";\n\n constructor(private readonly parent: Vtree.FormattingContext) {}\n\n /**\n * @override\n */\n getName(): string {\n return \"Block formatting context (BlockFormattingContext)\";\n }\n\n /**\n * @override\n */\n isFirstTime(nodeContext: Vtree.NodeContext, firstTime: boolean): boolean {\n return firstTime;\n }\n\n /**\n * @override\n */\n getParent(): Vtree.FormattingContext {\n return this.parent;\n }\n\n /** @override */\n saveState(): any {}\n\n /** @override */\n restoreState(state: any) {}\n}\n\nexport const blockLayoutProcessor = new BlockLayoutProcessor();\n\nexport const isInstanceOfBlockFormattingContext =\n LayoutProcessor.isInstanceOfBlockFormattingContext;\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_FORMATTING_CONTEXT,\n (nodeContext, firstTime, display, position, floatSide, isRoot) => {\n const parent = nodeContext.parent;\n if (!parent && nodeContext.formattingContext) {\n return null;\n } else if (\n parent &&\n nodeContext.formattingContext !== parent.formattingContext\n ) {\n return null;\n } else if (\n nodeContext.establishesBFC ||\n (!nodeContext.formattingContext &&\n Display.isBlock(display, position, floatSide, isRoot))\n ) {\n return new BlockFormattingContext(\n parent ? parent.formattingContext : null,\n );\n } else {\n return null;\n }\n },\n);\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n (formattingContext) => {\n if (formattingContext instanceof BlockFormattingContext) {\n return blockLayoutProcessor;\n }\n return null;\n },\n);\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutRetryers - Definitions of LayoutRetryer.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Task from \"./task\";\nimport { Layout, Vtree } from \"./types\";\n\n/**\n * @abstract\n */\nexport abstract class AbstractLayoutRetryer {\n initialBreakPositions: Layout.BreakPosition[] = null;\n initialStateOfFormattingContext: Vtree.NodeContext = null;\n initialPosition: Vtree.NodeContext;\n initialFragmentLayoutConstraints: Layout.FragmentLayoutConstraint[];\n\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n this.prepareLayout(nodeContext, column);\n return this.tryLayout(nodeContext, column);\n }\n\n private tryLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"AbstractLayoutRetryer.tryLayout\",\n );\n this.saveState(nodeContext, column);\n const mode = this.resolveLayoutMode(nodeContext);\n mode.doLayout(nodeContext, column).then((positionAfter) => {\n let accepted = mode.accept(positionAfter, column);\n accepted = mode.postLayout(\n positionAfter,\n this.initialPosition,\n column,\n accepted,\n );\n if (accepted) {\n frame.finish(positionAfter);\n } else {\n Asserts.assert(this.initialPosition);\n this.clearNodes(this.initialPosition);\n this.restoreState(nodeContext, column);\n this.tryLayout(this.initialPosition, column).thenFinish(frame);\n }\n });\n return frame.result();\n }\n\n /**\n * @abstract\n */\n abstract resolveLayoutMode(nodeContext: Vtree.NodeContext): Layout.LayoutMode;\n\n prepareLayout(nodeContext: Vtree.NodeContext, column: Layout.Column) {}\n\n clearNodes(initialPosition: Vtree.NodeContext) {\n const viewNode =\n initialPosition.viewNode || initialPosition.parent.viewNode;\n let child: Node;\n while ((child = viewNode.lastChild)) {\n viewNode.removeChild(child);\n }\n let sibling: Node;\n while ((sibling = viewNode.nextSibling)) {\n sibling.parentNode.removeChild(sibling);\n }\n }\n\n saveState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n this.initialPosition = nodeContext.copy();\n this.initialBreakPositions = [].concat(column.breakPositions);\n this.initialFragmentLayoutConstraints = [].concat(\n column.fragmentLayoutConstraints,\n );\n if (nodeContext.formattingContext) {\n this.initialStateOfFormattingContext = nodeContext.formattingContext.saveState();\n }\n }\n\n restoreState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n column.breakPositions = this.initialBreakPositions;\n column.fragmentLayoutConstraints = this.initialFragmentLayoutConstraints;\n if (nodeContext.formattingContext) {\n nodeContext.formattingContext.restoreState(\n this.initialStateOfFormattingContext,\n );\n }\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutUtil - Utilities related to layout.\n */\nimport * as Break from \"./break\";\nimport * as Task from \"./task\";\nimport * as VtreeImpl from \"./vtree\";\nimport { Layout, Vtree } from \"./types\";\n\nexport type LayoutIteratorState = {\n nodeContext: Vtree.NodeContext;\n atUnforcedBreak: boolean;\n break: boolean;\n leadingEdge?: boolean;\n breakAtTheEdge?: string | null;\n onStartEdges?: boolean;\n leadingEdgeContexts?: Vtree.NodeContext[];\n lastAfterNodeContext?: Vtree.NodeContext | null;\n};\n\nexport class LayoutIteratorStrategy {\n initialState(initialNodeContext: Vtree.NodeContext): LayoutIteratorState {\n return {\n nodeContext: initialNodeContext,\n atUnforcedBreak: false,\n break: false,\n };\n }\n\n startNonDisplayableNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterNonDisplayableNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startIgnoredTextNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterIgnoredTextNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startNonElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterNonElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n finish(state: LayoutIteratorState): void | Task.Result<boolean> {}\n}\n\nexport class LayoutIterator {\n constructor(\n private readonly strategy: LayoutIteratorStrategy,\n private readonly layoutContext: Vtree.LayoutContext,\n ) {}\n\n iterate(\n initialNodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n const strategy = this.strategy;\n const state = strategy.initialState(initialNodeContext);\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"LayoutIterator\",\n );\n frame\n .loopWithFrame((loopFrame) => {\n let r: void | Task.Result<boolean>;\n while (state.nodeContext) {\n if (!state.nodeContext.viewNode) {\n if (state.nodeContext.after) {\n r = strategy.afterNonDisplayableNode(state);\n } else {\n r = strategy.startNonDisplayableNode(state);\n }\n } else if (state.nodeContext.viewNode.nodeType !== 1) {\n if (\n VtreeImpl.canIgnore(\n state.nodeContext.viewNode,\n state.nodeContext.whitespace,\n )\n ) {\n if (state.nodeContext.after) {\n r = strategy.afterIgnoredTextNode(state);\n } else {\n r = strategy.startIgnoredTextNode(state);\n }\n } else {\n if (state.nodeContext.after) {\n r = strategy.afterNonElementNode(state);\n } else {\n r = strategy.startNonElementNode(state);\n }\n }\n } else {\n if (state.nodeContext.inline) {\n if (state.nodeContext.after) {\n r = strategy.afterInlineElementNode(state);\n } else {\n r = strategy.startInlineElementNode(state);\n }\n } else {\n if (state.nodeContext.after) {\n r = strategy.afterNonInlineElementNode(state);\n } else {\n r = strategy.startNonInlineElementNode(state);\n }\n }\n }\n const cont = r && r.isPending() ? r : Task.newResult(true);\n const nextResult = cont.thenAsync(() => {\n if (state.break) {\n return Task.newResult(null);\n }\n return this.layoutContext.nextInTree(\n state.nodeContext,\n state.atUnforcedBreak,\n );\n });\n if (nextResult.isPending()) {\n nextResult.then((nextNodeContext) => {\n if (state.break) {\n loopFrame.breakLoop();\n } else {\n state.nodeContext = nextNodeContext;\n loopFrame.continueLoop();\n }\n });\n return;\n } else if (state.break) {\n loopFrame.breakLoop();\n return;\n } else {\n state.nodeContext = nextResult.get();\n }\n }\n strategy.finish(state);\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(state.nodeContext);\n });\n return frame.result();\n }\n}\n\nexport class EdgeSkipper extends LayoutIteratorStrategy {\n constructor(protected readonly leadingEdge?: boolean) {\n super();\n }\n\n startNonInlineBox(state: LayoutIteratorState): void | Task.Result<boolean> {}\n\n endEmptyNonInlineBox(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n endNonInlineBox(state: LayoutIteratorState): void | Task.Result<boolean> {}\n\n initialState(initialNodeContext: Vtree.NodeContext): LayoutIteratorState {\n return {\n nodeContext: initialNodeContext,\n atUnforcedBreak: !!this.leadingEdge && initialNodeContext.after,\n break: false,\n leadingEdge: this.leadingEdge,\n breakAtTheEdge: null,\n onStartEdges: false,\n leadingEdgeContexts: [],\n lastAfterNodeContext: null,\n };\n }\n\n /**\n * @return Returns true if a forced break occurs.\n */\n processForcedBreak(\n state: LayoutIteratorState,\n column: Layout.Column,\n ): boolean {\n const needForcedBreak =\n !state.leadingEdge && Break.isForcedBreakValue(state.breakAtTheEdge);\n if (needForcedBreak) {\n const nodeContext = (state.nodeContext =\n state.leadingEdgeContexts[0] || state.nodeContext);\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n column.pageBreakType = state.breakAtTheEdge;\n }\n return needForcedBreak;\n }\n\n /**\n * @return Returns true if the node overflows the column.\n */\n saveEdgeAndProcessOverflow(\n state: LayoutIteratorState,\n column: Layout.Column,\n ): boolean {\n const overflow = column.checkOverflowAndSaveEdgeAndBreakPosition(\n state.lastAfterNodeContext,\n null,\n true,\n state.breakAtTheEdge,\n );\n if (overflow) {\n state.nodeContext = (\n state.lastAfterNodeContext || state.nodeContext\n ).modify();\n state.nodeContext.overflow = true;\n }\n return overflow;\n }\n\n /**\n * @returns Returns true if the layout constraint is violated.\n */\n processLayoutConstraint(\n state: LayoutIteratorState,\n layoutConstraint: Layout.LayoutConstraint,\n column: Layout.Column,\n ): boolean {\n let nodeContext = state.nodeContext;\n const violateConstraint = !layoutConstraint.allowLayout(nodeContext);\n if (violateConstraint) {\n column.checkOverflowAndSaveEdgeAndBreakPosition(\n state.lastAfterNodeContext,\n null,\n false,\n state.breakAtTheEdge,\n );\n nodeContext = state.nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n }\n return violateConstraint;\n }\n\n /**\n * @override\n */\n startNonElementNode(state: LayoutIteratorState): void | Task.Result<boolean> {\n state.onStartEdges = false;\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {\n state.leadingEdgeContexts.push(state.nodeContext.copy());\n state.breakAtTheEdge = Break.resolveEffectiveBreakValue(\n state.breakAtTheEdge,\n state.nodeContext.breakBefore,\n );\n state.onStartEdges = true;\n return this.startNonInlineBox(state);\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {\n let r: void | Task.Result<boolean>;\n let cont: Task.Result<boolean>;\n if (state.onStartEdges) {\n r = this.endEmptyNonInlineBox(state);\n cont = r && r.isPending() ? r : Task.newResult(true);\n cont = cont.thenAsync(() => {\n if (!state.break) {\n state.leadingEdgeContexts = [];\n state.leadingEdge = false;\n state.atUnforcedBreak = false;\n state.breakAtTheEdge = null;\n }\n return Task.newResult(true);\n });\n } else {\n r = this.endNonInlineBox(state);\n cont = r && r.isPending() ? r : Task.newResult(true);\n }\n return cont.thenAsync(() => {\n if (!state.break) {\n state.onStartEdges = false;\n state.lastAfterNodeContext = state.nodeContext.copy();\n state.breakAtTheEdge = Break.resolveEffectiveBreakValue(\n state.breakAtTheEdge,\n state.nodeContext.breakAfter,\n );\n }\n return Task.newResult(true);\n });\n }\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Shared - Global variables of Vivliostyle.js\n */\nimport { RepetitiveElement } from \"./types\";\n\nexport let repetitiveElementsCache: {\n root: Element;\n elements: RepetitiveElement.RepetitiveElements;\n}[] = [];\n\nexport function clearRepetitiveElementsCache(): void {\n repetitiveElementsCache = [];\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview PseudoElement - CSS pseudo elements.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssStyler from \"./css-styler\";\nimport * as Exprs from \"./exprs\";\nimport * as Vtree from \"./vtree\";\nimport { PseudoElement } from \"./types\";\n\nexport const document = new DOMParser().parseFromString(\n `<root xmlns=\"${Base.NS.SHADOW}\"/>`,\n \"text/xml\",\n);\n\n/**\n * Pseudoelement names in the order they should be inserted in the shadow DOM,\n * empty string is the place where the element's DOM children are processed.\n */\nexport const pseudoNames = [\n \"footnote-marker\",\n \"first-5-lines\",\n \"first-4-lines\",\n \"first-3-lines\",\n \"first-2-lines\",\n \"first-line\",\n \"first-letter\",\n \"before\",\n \"\",\n /* content */\n \"after\",\n];\n\nexport const PSEUDO_ATTR = \"data-adapt-pseudo\";\n\nexport function getPseudoName(element: Element): string {\n return element.getAttribute(PSEUDO_ATTR) || \"\";\n}\n\nexport function setPseudoName(element: Element, name: string): void {\n element.setAttribute(PSEUDO_ATTR, name);\n}\n\nexport class PseudoelementStyler implements PseudoElement.PseudoelementStyler {\n contentProcessed: { [key: string]: boolean } = {};\n\n // after content: update style\n\n constructor(\n public readonly element: Element,\n public style: CssCascade.ElementStyle,\n public styler: CssStyler.AbstractStyler,\n public readonly context: Exprs.Context,\n public readonly exprContentListener: Vtree.ExprContentListener,\n ) {}\n\n /**\n * @override\n */\n getStyle(element: Element, deep: boolean): CssCascade.ElementStyle {\n const pseudoName = getPseudoName(element);\n if (this.styler && pseudoName && pseudoName.match(/after$/)) {\n this.style = this.styler.getStyle(this.element, true);\n this.styler = null;\n }\n const pseudoMap = CssCascade.getStyleMap(this.style, \"_pseudos\");\n const style = pseudoMap[pseudoName] || ({} as CssCascade.ElementStyle);\n if (pseudoName.match(/^first-/) && !style[\"x-first-pseudo\"]) {\n let nest = 1;\n let r: RegExpMatchArray;\n if (pseudoName == \"first-letter\") {\n nest = 0;\n } else if ((r = pseudoName.match(/^first-([0-9]+)-lines$/)) != null) {\n nest = (r[1] as any) - 0;\n }\n style[\"x-first-pseudo\"] = new CssCascade.CascadeValue(\n new Css.Int(nest),\n 0,\n );\n }\n return style;\n }\n\n /**\n * @override\n */\n processContent(element: Element, styles: { [key: string]: Css.Val }) {\n const pseudoName = getPseudoName(element);\n if (!this.contentProcessed[pseudoName]) {\n this.contentProcessed[pseudoName] = true;\n const contentVal = styles[\"content\"];\n if (contentVal) {\n if (Vtree.nonTrivialContent(contentVal)) {\n contentVal.visit(\n new Vtree.ContentPropertyHandler(\n element,\n this.context,\n contentVal,\n this.exprContentListener,\n ),\n );\n }\n }\n }\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Layout - Fills a column with styled content.\n * This file does not communicate with the styling system directly.\n * Instead it goes through the layout interface that gives it one view tree\n * node at a time.\n */\nimport * as LayoutRetryers from \"./layout-retryers\";\nimport * as Asserts from \"./asserts\";\nimport * as Shared from \"./shared\";\nimport * as Sizing from \"./sizing\";\nimport * as Break from \"./break\";\nimport * as Logging from \"./logging\";\nimport * as Diff from \"./diff\";\nimport * as Base from \"./base\";\nimport * as BreakPosition from \"./break-position\";\nimport * as Css from \"./css\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Plugin from \"./plugin\";\nimport * as Matchers from \"./matchers\";\nimport * as PseudoElement from \"./pseudo-element\";\nimport * as Task from \"./task\";\nimport * as Vgen from \"./vgen\";\nimport * as VtreeImpl from \"./vtree\";\nimport {\n FragmentLayoutConstraintType,\n Layout,\n RepetitiveElement,\n Selectors,\n Table,\n Vtree,\n} from \"./types\";\n\nexport const isInstanceOfAfterIfContinuesLayoutConstraint =\n Selectors.isInstanceOfAfterIfContinuesLayoutConstraint;\nexport const registerFragmentIndex =\n Matchers.NthFragmentMatcher.registerFragmentIndex;\nexport const clearFragmentIndices =\n Matchers.NthFragmentMatcher.clearFragmentIndices;\n\nexport class AfterIfContinues implements Selectors.AfterIfContinues {\n constructor(\n public readonly sourceNode: Element,\n public readonly styler: PseudoElement.PseudoelementStyler,\n ) {}\n\n createElement(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n ): Task.Result<Element> {\n const doc = parentNodeContext.viewNode.ownerDocument;\n const viewRoot = doc.createElement(\"div\");\n const pseudoColumn = new PseudoColumn(column, viewRoot, parentNodeContext);\n const initialPageBreakType = pseudoColumn.getColumn().pageBreakType;\n pseudoColumn.getColumn().pageBreakType = null;\n return pseudoColumn\n .layout(this.createNodePositionForPseudoElement(), true)\n .thenAsync(() => {\n this.styler.contentProcessed[\"after-if-continues\"] = false;\n pseudoColumn.getColumn().pageBreakType = initialPageBreakType;\n const pseudoElement = viewRoot.firstChild as Element;\n Base.setCSSProperty(pseudoElement, \"display\", \"block\");\n return Task.newResult(pseudoElement);\n });\n }\n\n private createNodePositionForPseudoElement(): Vtree.ChunkPosition {\n const sourceNode = PseudoElement.document.createElementNS(\n Base.NS.XHTML,\n \"div\",\n );\n PseudoElement.setPseudoName(sourceNode, \"after-if-continues\");\n const shadowContext = this.createShadowContext(sourceNode);\n const step = {\n node: sourceNode,\n shadowType: shadowContext.type,\n shadowContext,\n nodeShadow: null,\n shadowSibling: null,\n };\n const nodePosition = {\n steps: [step],\n offsetInNode: 0,\n after: false,\n preprocessedTextContent: null,\n };\n return new VtreeImpl.ChunkPosition(nodePosition as any);\n }\n\n private createShadowContext(root: Element): Vtree.ShadowContext {\n return new VtreeImpl.ShadowContext(\n this.sourceNode,\n root,\n null,\n null,\n null,\n Vtree.ShadowType.ROOTED,\n this.styler,\n );\n }\n}\n\nexport class AfterIfContinuesLayoutConstraint\n implements Selectors.AfterIfContinuesLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType =\n \"AfterIfContinue\";\n\n constructor(\n public nodeContext: Vtree.NodeContext,\n public afterIfContinues: Selectors.AfterIfContinues,\n public pseudoElementHeight: number,\n ) {}\n\n /** @override */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): boolean {\n if (\n (overflownNodeContext && !nodeContext) ||\n (nodeContext && nodeContext.overflow)\n ) {\n return false;\n } else {\n return true;\n }\n }\n\n /** @override */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n return false;\n }\n\n /** @override */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n ) {}\n\n /** @override */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<boolean> {\n if (!this.getRepetitiveElements().affectTo(nodeContext)) {\n return Task.newResult(true);\n }\n return this.afterIfContinues\n .createElement(column, this.nodeContext)\n .thenAsync((element) => {\n this.nodeContext.viewNode.appendChild(element);\n return Task.newResult(true);\n });\n }\n\n getRepetitiveElements() {\n return new AfterIfContinuesElementsOffset(\n this.nodeContext,\n this.pseudoElementHeight,\n );\n }\n\n /** @override */\n equalsTo(constraint: Layout.FragmentLayoutConstraint): boolean {\n if (!(constraint instanceof AfterIfContinuesLayoutConstraint)) {\n return false;\n }\n return (\n this.afterIfContinues ==\n (constraint as AfterIfContinuesLayoutConstraint).afterIfContinues\n );\n }\n\n /** @override */\n getPriorityOfFinishBreak(): number {\n return 9;\n }\n}\n\nexport class AfterIfContinuesElementsOffset\n implements Selectors.AfterIfContinuesElementsOffset {\n constructor(public nodeContext, public pseudoElementHeight) {}\n\n /** @override */\n calculateOffset(nodeContext: Vtree.NodeContext): number {\n if (!this.affectTo(nodeContext)) {\n return 0;\n }\n return this.pseudoElementHeight;\n }\n\n /** @override */\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number {\n return this.calculateOffset(nodeContext);\n }\n\n affectTo(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext) {\n return false;\n }\n const sourceNode = nodeContext.shadowContext\n ? nodeContext.shadowContext.owner\n : nodeContext.sourceNode;\n if (sourceNode === this.nodeContext.sourceNode) {\n return !!nodeContext.after;\n }\n for (let n = sourceNode.parentNode; n; n = n.parentNode) {\n if (n === this.nodeContext.sourceNode) {\n return true;\n }\n }\n return false;\n }\n}\n\nfunction processAfterIfContinuesOfNodeContext(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n): Task.Result<Vtree.NodeContext> {\n if (\n !nodeContext ||\n !nodeContext.afterIfContinues ||\n nodeContext.after ||\n column.isFloatNodeContext(nodeContext)\n ) {\n return Task.newResult(nodeContext);\n }\n const afterIfContinues = nodeContext.afterIfContinues;\n return afterIfContinues\n .createElement(column, nodeContext)\n .thenAsync((pseudoElement) => {\n Asserts.assert(nodeContext !== null);\n const pseudoElementHeight = calculatePseudoElementHeight(\n nodeContext,\n column,\n pseudoElement,\n );\n column.fragmentLayoutConstraints.push(\n new AfterIfContinuesLayoutConstraint(\n nodeContext as Vtree.NodeContext,\n afterIfContinues,\n pseudoElementHeight,\n ),\n );\n return Task.newResult(nodeContext);\n });\n}\n\nexport function processAfterIfContinues(\n result: Task.Result<Vtree.NodeContext>,\n column: Layout.Column,\n): Task.Result<Vtree.NodeContext> {\n return result.thenAsync((nodeContext) =>\n processAfterIfContinuesOfNodeContext(nodeContext, column),\n );\n}\n\nexport function processAfterIfContinuesOfAncestors(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\n \"processAfterIfContinuesOfAncestors\",\n );\n let current: Vtree.NodeContext = nodeContext;\n frame\n .loop(() => {\n if (current !== null) {\n const result = processAfterIfContinuesOfNodeContext(current, column);\n current = current.parent;\n return result.thenReturn(true);\n } else {\n return Task.newResult(false);\n }\n })\n .then(() => {\n frame.finish(true);\n });\n return frame.result();\n}\n\nexport function calculatePseudoElementHeight(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n pseudoElement: Element,\n): number {\n const parentNode = nodeContext.viewNode as Element;\n parentNode.appendChild(pseudoElement);\n const height = LayoutHelper.getElementHeight(\n pseudoElement,\n column,\n nodeContext.vertical,\n );\n parentNode.removeChild(pseudoElement);\n return height;\n}\n\nexport const mediaTags = {\n img: true,\n svg: true,\n audio: true,\n video: true,\n};\n\n/**\n * Represents a constraint on layout\n */\nexport type LayoutConstraint = Layout.LayoutConstraint;\n\n/**\n * Represents a constraint that allows layout if all the constraints it contains\n * allow layout.\n */\nexport class AllLayoutConstraint implements LayoutConstraint {\n constructor(public readonly constraints: LayoutConstraint[]) {}\n\n /**\n * @override\n */\n allowLayout(nodeContext: Vtree.NodeContext): boolean {\n return this.constraints.every((c) => c.allowLayout(nodeContext));\n }\n}\n\n/**\n * Represents constraints on laying out fragments\n */\nexport type FragmentLayoutConstraint = Layout.FragmentLayoutConstraint;\n\nexport type BreakPositionAndNodeContext = Layout.BreakPositionAndNodeContext;\n\n/**\n * Potential breaking position inside CSS box (between lines).\n * @param checkPoints array of breaking points for breakable block\n */\nexport class BoxBreakPosition extends BreakPosition.AbstractBreakPosition\n implements Layout.BoxBreakPosition {\n private alreadyEvaluated: boolean = false;\n breakNodeContext: Vtree.NodeContext = null;\n\n constructor(\n public readonly checkPoints: Vtree.NodeContext[],\n public readonly penalty: number,\n ) {\n super();\n }\n\n /**\n * @override\n */\n findAcceptableBreak(column: Column, penalty: number): Vtree.NodeContext {\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n if (!this.alreadyEvaluated) {\n this.breakNodeContext = column.findBoxBreakPosition(this, penalty > 0);\n this.alreadyEvaluated = true;\n }\n return this.breakNodeContext;\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n return this.penalty;\n }\n\n /** @override */\n getNodeContext(): Vtree.NodeContext {\n return this.alreadyEvaluated\n ? this.breakNodeContext\n : this.checkPoints[this.checkPoints.length - 1];\n }\n}\n\nexport function validateCheckPoints(checkPoints: Vtree.NodeContext[]): void {\n for (let i = 1; i < checkPoints.length; i++) {\n const cp0 = checkPoints[i - 1];\n const cp1 = checkPoints[i];\n if (cp0 === cp1) {\n Logging.logger.warn(\"validateCheckPoints: duplicate entry\");\n } else if (cp0.boxOffset >= cp1.boxOffset) {\n Logging.logger.warn(\"validateCheckPoints: incorrect boxOffset\");\n } else if (cp0.sourceNode == cp1.sourceNode) {\n if (cp1.after) {\n if (cp0.after) {\n Logging.logger.warn(\"validateCheckPoints: duplicate after points\");\n }\n } else {\n if (!cp0.after) {\n if (\n cp1.boxOffset - cp0.boxOffset !=\n cp1.offsetInNode - cp0.offsetInNode\n ) {\n Logging.logger.warn(\n \"validateCheckPoints: boxOffset inconsistent with offsetInNode\",\n );\n }\n }\n }\n }\n }\n}\n\nexport function isSpecialInlineDisplay(display: string): boolean {\n switch (display) {\n case \"ruby\":\n case \"inline-block\":\n case \"inline-flex\":\n case \"inline-grid\":\n case \"inline-list-item\":\n case \"inline-table\":\n return true;\n }\n return false;\n}\n\nexport class Column extends VtreeImpl.Container implements Layout.Column {\n last: Node;\n viewDocument: Document;\n flowRootFormattingContext: Vtree.FormattingContext = null;\n isFloat: boolean = false;\n isFootnote: boolean = false;\n startEdge: number = 0;\n endEdge: number = 0;\n beforeEdge: number = 0;\n afterEdge: number = 0;\n footnoteEdge: number = 0;\n box: GeometryUtil.Rect = null;\n chunkPositions: Vtree.ChunkPosition[] = null;\n bands: GeometryUtil.Band[] = null;\n overflown: boolean = false;\n breakPositions: BreakPosition.BreakPosition[] = null;\n pageBreakType: string | null = null;\n forceNonfitting: boolean = true;\n leftFloatEdge: number = 0; // bottom of the bottommost left float\n rightFloatEdge: number = 0; // bottom of the bottommost right float\n bottommostFloatTop: number = 0; // Top of the bottommost float\n stopAtOverflow: boolean = true;\n lastAfterPosition: Vtree.NodePosition | null = null;\n fragmentLayoutConstraints: FragmentLayoutConstraint[] = [];\n pseudoParent: Column = null;\n nodeContextOverflowingDueToRepetitiveElements: Vtree.NodeContext | null = null;\n blockDistanceToBlockEndFloats: number = NaN;\n computedBlockSize: number;\n\n constructor(\n element: Element,\n public layoutContext: Vtree.LayoutContext,\n public clientLayout: Vtree.ClientLayout,\n public readonly layoutConstraint: LayoutConstraint,\n public readonly pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ) {\n super(element);\n this.last = element.lastChild;\n this.viewDocument = element.ownerDocument;\n pageFloatLayoutContext.setContainer(this);\n }\n\n getTopEdge(): number {\n return this.vertical ? this.startEdge : this.beforeEdge;\n }\n\n getBottomEdge(): number {\n return this.vertical ? this.endEdge : this.afterEdge;\n }\n\n getLeftEdge(): number {\n return this.vertical ? this.afterEdge : this.startEdge;\n }\n\n getRightEdge(): number {\n return this.vertical ? this.beforeEdge : this.endEdge;\n }\n\n isFloatNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return !!nodeContext.floatSide && (!this.isFloat || !!nodeContext.parent);\n }\n\n stopByOverflow(nodeContext: Vtree.NodeContext): boolean {\n return this.stopAtOverflow && !!nodeContext && nodeContext.overflow;\n }\n\n isOverflown(edge: number): boolean {\n if (this.vertical) {\n return edge < this.footnoteEdge;\n } else {\n return edge > this.footnoteEdge;\n }\n }\n\n getExclusions(): GeometryUtil.Shape[] {\n const pageFloatExclusions = this.pageFloatLayoutContext.getFloatFragmentExclusions();\n return this.exclusions.concat(pageFloatExclusions);\n }\n\n openAllViews(position: Vtree.NodePosition): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"openAllViews\");\n const steps = position.steps;\n self.layoutContext.setViewRoot(self.element, self.isFootnote);\n let stepIndex = steps.length - 1;\n let nodeContext: Vtree.NodeContext = null;\n frame\n .loop(() => {\n while (stepIndex >= 0) {\n const prevContext = nodeContext;\n const step = steps[stepIndex];\n nodeContext = VtreeImpl.makeNodeContextFromNodePositionStep(\n step,\n prevContext,\n );\n if (\n stepIndex === steps.length - 1 &&\n !nodeContext.formattingContext\n ) {\n nodeContext.formattingContext = self.flowRootFormattingContext;\n }\n if (stepIndex == 0) {\n nodeContext.offsetInNode = self.calculateOffsetInNodeForNodeContext(\n position,\n );\n nodeContext.after = position.after;\n nodeContext.preprocessedTextContent =\n position.preprocessedTextContent;\n if (nodeContext.after) {\n break;\n }\n }\n const r = self.layoutContext.setCurrent(\n nodeContext,\n stepIndex == 0 && nodeContext.offsetInNode == 0,\n );\n stepIndex--;\n if (r.isPending()) {\n return r;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n Asserts.assert(nodeContext);\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n calculateOffsetInNodeForNodeContext(position: Vtree.NodePosition): number {\n return position.preprocessedTextContent\n ? Diff.resolveNewIndex(\n position.preprocessedTextContent,\n position.offsetInNode,\n )\n : position.offsetInNode;\n }\n\n /**\n * @param count first-XXX nesting identifier\n */\n maybePeelOff(\n position: Vtree.NodeContext,\n count: number,\n ): Task.Result<Vtree.NodeContext> {\n if (\n position.firstPseudo &&\n position.inline &&\n !position.after &&\n position.firstPseudo.count == 0\n ) {\n // first char\n if (position.viewNode.nodeType != 1) {\n const text = position.viewNode.textContent;\n const r = text.match(firstCharPattern);\n return this.layoutContext.peelOff(position, r[0].length);\n }\n }\n return Task.newResult(position) as Task.Result<Vtree.NodeContext>;\n }\n\n /**\n * Builds the view until a CSS box edge is reached.\n * @param position start source position.\n * @param checkPoints array to append possible breaking points.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildViewToNextBlockEdge(\n position: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n let violateConstraint = false;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"buildViewToNextBlockEdge\",\n );\n frame\n .loopWithFrame((bodyFrame) => {\n if (position.viewNode && !LayoutHelper.isSpecialNodeContext(position)) {\n checkPoints.push(position.copy());\n }\n self.maybePeelOff(position, 0).then((position1Param) => {\n const position1 = position1Param as Vtree.NodeContext;\n if (position1 !== position) {\n position = position1;\n if (!LayoutHelper.isSpecialNodeContext(position)) {\n checkPoints.push(position.copy());\n }\n }\n self.nextInTree(position).then((positionParam) => {\n position = positionParam as Vtree.NodeContext;\n if (!position) {\n // Exit the loop\n bodyFrame.breakLoop();\n return;\n }\n if (\n violateConstraint ||\n !self.layoutConstraint.allowLayout(position)\n ) {\n violateConstraint = true;\n position = position.modify();\n position.overflow = true;\n }\n if (self.isFloatNodeContext(position) && !self.vertical) {\n self.layoutFloatOrFootnote(position).then((positionParam) => {\n position = positionParam as Vtree.NodeContext;\n if (self.pageFloatLayoutContext.isInvalidated()) {\n position = null;\n }\n if (!position) {\n bodyFrame.breakLoop();\n return;\n }\n bodyFrame.continueLoop();\n });\n } else if (!position.inline) {\n // Exit the loop\n bodyFrame.breakLoop();\n } else {\n // Continue the loop\n bodyFrame.continueLoop();\n }\n });\n });\n })\n .then(() => {\n frame.finish(position);\n });\n return frame.result();\n }\n\n nextInTree(\n position: Vtree.NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<Vtree.NodeContext> {\n const cont = this.layoutContext.nextInTree(position, atUnforcedBreak);\n return processAfterIfContinues(cont, this);\n }\n\n /**\n * Builds the view for a single unbreakable element.\n * @param position start source position.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildDeepElementView(\n position: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n if (!position.viewNode) {\n return Task.newResult(position);\n }\n let checkPoints: Vtree.NodeContext[] = [];\n const sourceNode = position.sourceNode;\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"buildDeepElementView\",\n );\n\n // TODO: end the loop based on depth, not sourceNode comparison\n frame\n .loopWithFrame((bodyFrame) => {\n if (\n position.viewNode &&\n position.inline &&\n !LayoutHelper.isSpecialNodeContext(position)\n ) {\n checkPoints.push(position.copy());\n } else {\n if (checkPoints.length > 0) {\n self.postLayoutBlock(position, checkPoints);\n }\n checkPoints = [];\n }\n self.maybePeelOff(position, 0).then((position1Param) => {\n const position1 = position1Param as Vtree.NodeContext;\n if (position1 !== position) {\n let p = position1;\n while (p && p.sourceNode != sourceNode) {\n p = p.parent;\n }\n if (p == null) {\n // outside of the subtree\n position = position1;\n bodyFrame.breakLoop();\n return;\n }\n if (!LayoutHelper.isSpecialNodeContext(position1)) {\n checkPoints.push(position1.copy());\n }\n }\n self.nextInTree(position1).then((positionParam) => {\n position = positionParam as Vtree.NodeContext;\n if (!position || position.sourceNode == sourceNode) {\n bodyFrame.breakLoop();\n } else if (!self.layoutConstraint.allowLayout(position)) {\n position = position.modify();\n position.overflow = true;\n if (self.stopAtOverflow) {\n bodyFrame.breakLoop();\n } else {\n bodyFrame.continueLoop();\n }\n } else {\n bodyFrame.continueLoop();\n }\n });\n });\n })\n .then(() => {\n if (checkPoints.length > 0) {\n self.postLayoutBlock(position, checkPoints);\n }\n frame.finish(position);\n });\n return frame.result();\n }\n\n /**\n * Create a single floating element (for exclusion areas).\n * @param ref container's child to insert float before (can be null).\n * @param side float side (\"left\" or \"right\").\n * @param width float inline dimension.\n * @param height float box progression dimension.\n * @return newly created float element.\n */\n createFloat(ref: Node, side: string, width: number, height: number): Element {\n const div = this.viewDocument.createElement(\"div\");\n if (this.vertical) {\n if (height >= this.height) {\n height -= 0.1;\n }\n Base.setCSSProperty(div, \"height\", `${width}px`);\n Base.setCSSProperty(div, \"width\", `${height}px`);\n } else {\n if (width >= this.width) {\n width -= 0.1;\n }\n Base.setCSSProperty(div, \"width\", `${width}px`);\n Base.setCSSProperty(div, \"height\", `${height}px`);\n }\n Base.setCSSProperty(div, \"float\", side);\n Base.setCSSProperty(div, \"clear\", side);\n\n // enable to visualize\n // Base.setCSSProperty(div, \"background-color\", \"#50F0FF\");\n this.element.insertBefore(div, ref);\n return div;\n }\n\n /**\n * Remove all the exclusion floats.\n */\n killFloats(): void {\n let c: Node = this.element.firstChild;\n while (c) {\n const nc = c.nextSibling;\n if (c.nodeType == 1) {\n const e = c as HTMLElement;\n const f = e.style.cssFloat;\n if (f == \"left\" || f == \"right\") {\n this.element.removeChild(e);\n } else {\n break;\n }\n }\n c = nc;\n }\n }\n\n /**\n * Create exclusion floats for a column.\n */\n createFloats(): void {\n const ref = this.element.firstChild;\n const bands = this.bands;\n const x1 = this.vertical ? this.getTopEdge() : this.getLeftEdge();\n const x2 = this.vertical ? this.getBottomEdge() : this.getRightEdge();\n for (const band of bands) {\n const height = band.y2 - band.y1;\n band.left = this.createFloat(ref, \"left\", band.x1 - x1, height);\n band.right = this.createFloat(ref, \"right\", x2 - band.x2, height);\n }\n }\n\n /**\n * @param nodeContext position after the block\n * @param checkPoints array of possible breaking points.\n * @param index index of the breaking point\n * @param boxOffset box offset\n * @return edge position\n */\n calculateEdge(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n index: number,\n boxOffset: number,\n ): number {\n let edge: number;\n if (nodeContext && LayoutHelper.isOrphan(nodeContext.viewNode)) {\n return NaN;\n } else if (nodeContext && nodeContext.after && !nodeContext.inline) {\n edge = LayoutHelper.calculateEdge(\n nodeContext,\n this.clientLayout,\n 0,\n this.vertical,\n );\n if (!isNaN(edge)) {\n return edge;\n }\n }\n nodeContext = checkPoints[index];\n let offset = boxOffset - nodeContext.boxOffset;\n while (true) {\n edge = LayoutHelper.calculateEdge(\n nodeContext,\n this.clientLayout,\n offset,\n this.vertical,\n );\n if (!isNaN(edge)) {\n return edge;\n }\n if (offset > 0) {\n offset--;\n continue;\n }\n index--;\n if (index < 0) {\n return this.beforeEdge;\n }\n nodeContext = checkPoints[index];\n if (nodeContext.viewNode.nodeType != 1) {\n offset = nodeContext.viewNode.textContent.length;\n }\n }\n }\n\n /**\n * Parse CSS computed length (in pixels)\n * @param val CSS length in \"px\" units or a number.\n * @return value in pixels or 0 if not parsable\n */\n parseComputedLength(val: string | number): number {\n if (typeof val == \"number\") {\n return val;\n }\n const r = val.match(/^(-?[0-9]*(\\.[0-9]*)?)px$/);\n if (r) {\n return parseFloat(r[0]);\n }\n return 0;\n }\n\n /**\n * Reads element's computed CSS margin.\n */\n getComputedMargin(element: Element): GeometryUtil.Insets {\n const style = this.clientLayout.getElementComputedStyle(element);\n const insets = new GeometryUtil.Insets(0, 0, 0, 0);\n if (style) {\n insets.left = this.parseComputedLength(style.marginLeft);\n insets.top = this.parseComputedLength(style.marginTop);\n insets.right = this.parseComputedLength(style.marginRight);\n insets.bottom = this.parseComputedLength(style.marginBottom);\n }\n return insets;\n }\n\n /**\n * Reads element's computed padding + borders.\n */\n getComputedPaddingBorder(element: Element): GeometryUtil.Insets {\n const style = this.clientLayout.getElementComputedStyle(element);\n const insets = new GeometryUtil.Insets(0, 0, 0, 0);\n if (style) {\n insets.left =\n this.parseComputedLength(style.borderLeftWidth) +\n this.parseComputedLength(style.paddingLeft);\n insets.top =\n this.parseComputedLength(style.borderTopWidth) +\n this.parseComputedLength(style.paddingTop);\n insets.right =\n this.parseComputedLength(style.borderRightWidth) +\n this.parseComputedLength(style.paddingRight);\n insets.bottom =\n this.parseComputedLength(style.borderBottomWidth) +\n this.parseComputedLength(style.paddingBottom);\n }\n return insets;\n }\n\n /**\n * Reads element's computed CSS insets(margins + border + padding or margins :\n * depends on box-sizing)\n */\n getComputedInsets(element: Element): GeometryUtil.Insets {\n const style = this.clientLayout.getElementComputedStyle(element);\n const insets = new GeometryUtil.Insets(0, 0, 0, 0);\n if (style) {\n if (style.boxSizing == \"border-box\") {\n return this.getComputedMargin(element);\n }\n insets.left =\n this.parseComputedLength(style.marginLeft) +\n this.parseComputedLength(style.borderLeftWidth) +\n this.parseComputedLength(style.paddingLeft);\n insets.top =\n this.parseComputedLength(style.marginTop) +\n this.parseComputedLength(style.borderTopWidth) +\n this.parseComputedLength(style.paddingTop);\n insets.right =\n this.parseComputedLength(style.marginRight) +\n this.parseComputedLength(style.borderRightWidth) +\n this.parseComputedLength(style.paddingRight);\n insets.bottom =\n this.parseComputedLength(style.marginBottom) +\n this.parseComputedLength(style.borderBottomWidth) +\n this.parseComputedLength(style.paddingBottom);\n }\n return insets;\n }\n\n /**\n * Set element's computed CSS insets to Column Container\n */\n setComputedInsets(element: Element, container: Column) {\n const style = this.clientLayout.getElementComputedStyle(element);\n if (style) {\n container.marginLeft = this.parseComputedLength(style.marginLeft);\n container.borderLeft = this.parseComputedLength(style.borderLeftWidth);\n container.paddingLeft = this.parseComputedLength(style.paddingLeft);\n container.marginTop = this.parseComputedLength(style.marginTop);\n container.borderTop = this.parseComputedLength(style.borderTopWidth);\n container.paddingTop = this.parseComputedLength(style.paddingTop);\n container.marginRight = this.parseComputedLength(style.marginRight);\n container.borderRight = this.parseComputedLength(style.borderRightWidth);\n container.paddingRight = this.parseComputedLength(style.paddingRight);\n container.marginBottom = this.parseComputedLength(style.marginBottom);\n container.borderBottom = this.parseComputedLength(\n style.borderBottomWidth,\n );\n container.paddingBottom = this.parseComputedLength(style.paddingBottom);\n }\n }\n\n /**\n * Set element's computed width and height to Column Container\n */\n setComputedWidthAndHeight(element: Element, container: Column) {\n const style = this.clientLayout.getElementComputedStyle(element);\n if (style) {\n container.width = this.parseComputedLength(style.width);\n container.height = this.parseComputedLength(style.height);\n }\n }\n\n /**\n * Layout a single unbreakable element.\n */\n layoutUnbreakable(\n nodeContextIn: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n return this.buildDeepElementView(nodeContextIn);\n }\n\n /**\n * Layout a single float element.\n */\n layoutFloat(nodeContext: Vtree.NodeContext): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"layoutFloat\");\n const element = nodeContext.viewNode as Element;\n const floatSide = nodeContext.floatSide as string;\n Base.setCSSProperty(element, \"float\", \"none\");\n Base.setCSSProperty(element, \"display\", \"inline-block\");\n Base.setCSSProperty(element, \"vertical-align\", \"top\");\n self.buildDeepElementView(nodeContext).then((nodeContextAfter) => {\n const floatBBox = self.clientLayout.getElementClientRect(element);\n const margin = self.getComputedMargin(element);\n let floatBox = new GeometryUtil.Rect(\n floatBBox.left - margin.left,\n floatBBox.top - margin.top,\n floatBBox.right + margin.right,\n floatBBox.bottom + margin.bottom,\n );\n let x1 = self.startEdge;\n let x2 = self.endEdge;\n let parent = nodeContext.parent;\n while (parent && parent.inline) {\n parent = parent.parent;\n }\n if (parent) {\n // Position it at the parent element's edge.\n // We need to get the edge of the parent's content area, calling\n // getElementClientRect will also give us borders. Avoid it by creating\n // a temporary element and using it for measurment.\n const probe = parent.viewNode.ownerDocument.createElement(\"div\");\n probe.style.left = \"0px\";\n probe.style.top = \"0px\";\n if (self.vertical) {\n probe.style.bottom = \"0px\";\n probe.style.width = \"1px\";\n } else {\n probe.style.right = \"0px\";\n probe.style.height = \"1px\";\n }\n parent.viewNode.appendChild(probe);\n const parentBox = self.clientLayout.getElementClientRect(probe);\n x1 = Math.max(self.getStartEdge(parentBox), x1);\n x2 = Math.min(self.getEndEdge(parentBox), x2);\n parent.viewNode.removeChild(probe);\n const floatBoxMeasure = self.vertical\n ? floatBox.y2 - floatBox.y1\n : floatBox.x2 - floatBox.x1;\n if (floatSide == \"left\") {\n x2 = Math.max(x2, x1 + floatBoxMeasure);\n } else {\n x1 = Math.min(x1, x2 - floatBoxMeasure);\n }\n\n // Move the float below the block parent.\n // Otherwise, if the float is attached to an inline box with 'position:\n // relative', the absolute positioning of the float gets broken, since\n // the inline parent can be pushed horizontally by exclusion floats\n // after the layout of the float is done.\n parent.viewNode.appendChild(nodeContext.viewNode);\n }\n\n // box is rotated for vertical orientation\n let box = new GeometryUtil.Rect(\n x1,\n self.getBoxDir() * self.beforeEdge,\n x2,\n self.getBoxDir() * self.afterEdge,\n );\n let floatHorBox = floatBox;\n if (self.vertical) {\n floatHorBox = GeometryUtil.rotateBox(floatBox);\n }\n const dir = self.getBoxDir();\n if (floatHorBox.y1 < self.bottommostFloatTop * dir) {\n const boxExtent = floatHorBox.y2 - floatHorBox.y1;\n floatHorBox.y1 = self.bottommostFloatTop * dir;\n floatHorBox.y2 = floatHorBox.y1 + boxExtent;\n }\n GeometryUtil.positionFloat(box, self.bands, floatHorBox, floatSide);\n if (self.vertical) {\n floatBox = GeometryUtil.unrotateBox(floatHorBox);\n }\n const insets = self.getComputedInsets(element);\n Base.setCSSProperty(\n element,\n \"width\",\n `${floatBox.x2 - floatBox.x1 - insets.left - insets.right}px`,\n );\n Base.setCSSProperty(\n element,\n \"height\",\n `${floatBox.y2 - floatBox.y1 - insets.top - insets.bottom}px`,\n );\n Base.setCSSProperty(element, \"position\", \"absolute\");\n Asserts.assert(nodeContext.display);\n Base.setCSSProperty(element, \"display\", nodeContext.display);\n let offsets;\n let containingBlockForAbsolute: Vtree.NodeContext = null;\n if (parent) {\n if (parent.containingBlockForAbsolute) {\n containingBlockForAbsolute = parent;\n } else {\n containingBlockForAbsolute = parent.getContainingBlockForAbsolute();\n }\n }\n if (containingBlockForAbsolute) {\n const probe = containingBlockForAbsolute.viewNode.ownerDocument.createElement(\n \"div\",\n );\n probe.style.position = \"absolute\";\n if (containingBlockForAbsolute.vertical) {\n probe.style.right = \"0\";\n } else {\n probe.style.left = \"0\";\n }\n probe.style.top = \"0\";\n containingBlockForAbsolute.viewNode.appendChild(probe);\n offsets = self.clientLayout.getElementClientRect(probe);\n containingBlockForAbsolute.viewNode.removeChild(probe);\n } else {\n offsets = {\n left: self.getLeftEdge() - self.paddingLeft,\n right: self.getRightEdge() + self.paddingRight,\n top: self.getTopEdge() - self.paddingTop,\n };\n }\n if (\n containingBlockForAbsolute\n ? containingBlockForAbsolute.vertical\n : self.vertical\n ) {\n Base.setCSSProperty(\n element,\n \"right\",\n `${offsets.right - floatBox.x2}px`,\n );\n } else {\n Base.setCSSProperty(element, \"left\", `${floatBox.x1 - offsets.left}px`);\n }\n Base.setCSSProperty(element, \"top\", `${floatBox.y1 - offsets.top}px`);\n if (nodeContext.clearSpacer) {\n nodeContext.clearSpacer.parentNode.removeChild(nodeContext.clearSpacer);\n nodeContext.clearSpacer = null;\n }\n const floatBoxEdge = self.vertical ? floatBox.x1 : floatBox.y2;\n const floatBoxTop = self.vertical ? floatBox.x2 : floatBox.y1;\n\n // TODO: subtract after margin when determining overflow.\n if (!self.isOverflown(floatBoxEdge) || self.breakPositions.length == 0) {\n // no overflow\n self.killFloats();\n box = new GeometryUtil.Rect(\n self.getLeftEdge(),\n self.getTopEdge(),\n self.getRightEdge(),\n self.getBottomEdge(),\n );\n if (self.vertical) {\n box = GeometryUtil.rotateBox(box);\n }\n GeometryUtil.addFloatToBands(\n box,\n self.bands,\n floatHorBox,\n null,\n floatSide,\n );\n self.createFloats();\n if (floatSide == \"left\") {\n self.leftFloatEdge = floatBoxEdge;\n } else {\n self.rightFloatEdge = floatBoxEdge;\n }\n self.bottommostFloatTop = floatBoxTop;\n self.updateMaxReachedAfterEdge(floatBoxEdge);\n frame.finish(nodeContextAfter);\n } else {\n nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n frame.finish(nodeContext);\n }\n });\n return frame.result();\n }\n\n setupFloatArea(\n area: PageFloatArea,\n floatReference: PageFloats.FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): boolean {\n const floatLayoutContext = this.pageFloatLayoutContext;\n const floatContainer = floatLayoutContext.getContainer(floatReference);\n const element = area.element;\n floatContainer.element.parentNode.appendChild(element);\n area.isFloat = true;\n area.originX = floatContainer.originX;\n area.originY = floatContainer.originY;\n area.vertical = floatContainer.vertical;\n area.marginLeft = area.marginRight = area.marginTop = area.marginBottom = 0;\n area.borderLeft = area.borderRight = area.borderTop = area.borderBottom = 0;\n area.paddingLeft = area.paddingRight = area.paddingTop = area.paddingBottom = 0;\n area.exclusions = (floatContainer.exclusions || []).concat();\n area.forceNonfitting = !floatLayoutContext.hasFloatFragments();\n area.innerShape = null;\n const containingBlockRect = floatContainer.getPaddingRect();\n area.setHorizontalPosition(\n containingBlockRect.x1 - floatContainer.originX,\n containingBlockRect.x2 - containingBlockRect.x1,\n );\n area.setVerticalPosition(\n containingBlockRect.y1 - floatContainer.originY,\n containingBlockRect.y2 - containingBlockRect.y1,\n );\n strategy.adjustPageFloatArea(area, floatContainer, this);\n\n // Calculate bands from the exclusions before setting float area dimensions\n area.init();\n const fitWithinContainer = !!floatLayoutContext.setFloatAreaDimensions(\n area,\n floatReference,\n floatSide,\n anchorEdge,\n true,\n !floatLayoutContext.hasFloatFragments(),\n condition,\n );\n if (fitWithinContainer) {\n // New dimensions have been set, remove exclusion floats and re-init\n area.killFloats();\n area.init();\n } else {\n floatContainer.element.parentNode.removeChild(element);\n }\n return fitWithinContainer;\n }\n\n createPageFloatArea(\n float: PageFloats.PageFloat | null,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): PageFloatArea | null {\n const floatAreaElement = this.element.ownerDocument.createElement(\"div\");\n Base.setCSSProperty(floatAreaElement, \"position\", \"absolute\");\n const parentPageFloatLayoutContext = this.pageFloatLayoutContext.getPageFloatLayoutContext(\n float.floatReference,\n );\n\n // TODO: establish how to specify an appropriate generating element for the\n // new page float layout context\n const pageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n null,\n PageFloats.FloatReference.COLUMN,\n null,\n this.pageFloatLayoutContext.flowName,\n float.nodePosition,\n null,\n null,\n );\n const parentContainer = parentPageFloatLayoutContext.getContainer();\n const floatArea = new PageFloatArea(\n floatSide,\n floatAreaElement,\n this.layoutContext.clone(),\n this.clientLayout,\n this.layoutConstraint,\n pageFloatLayoutContext,\n parentContainer,\n );\n pageFloatLayoutContext.setContainer(floatArea);\n if (\n this.setupFloatArea(\n floatArea,\n float.floatReference,\n floatSide,\n anchorEdge,\n strategy,\n condition,\n )\n ) {\n return floatArea;\n } else {\n return null;\n }\n }\n\n layoutSinglePageFloatFragment(\n continuations: PageFloats.PageFloatContinuation[],\n floatSide: string,\n clearSide: string | null,\n allowFragmented: boolean,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment | null,\n ): Task.Result<SinglePageFloatLayoutResult> {\n const context = this.pageFloatLayoutContext;\n const originalContinuations = pageFloatFragment\n ? pageFloatFragment.continuations\n : [];\n continuations = originalContinuations.concat(continuations);\n const firstFloat = continuations[0].float;\n const condition = context.getPageFloatPlacementCondition(\n firstFloat,\n floatSide,\n clearSide,\n );\n const floatArea = this.createPageFloatArea(\n firstFloat,\n floatSide,\n anchorEdge,\n strategy,\n condition,\n );\n const result: SinglePageFloatLayoutResult = {\n floatArea,\n pageFloatFragment: null,\n newPosition: null,\n };\n if (!floatArea) {\n return Task.newResult(result);\n }\n const frame = Task.newFrame<SinglePageFloatLayoutResult>(\n \"layoutSinglePageFloatFragment\",\n );\n let failed = false;\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i >= continuations.length) {\n loopFrame.breakLoop();\n return;\n }\n const c = continuations[i];\n const floatChunkPosition = new VtreeImpl.ChunkPosition(c.nodePosition);\n floatArea.layout(floatChunkPosition, true).then((newPosition) => {\n result.newPosition = newPosition;\n if (!newPosition || allowFragmented) {\n i++;\n loopFrame.continueLoop();\n } else {\n failed = true;\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n if (!failed) {\n Asserts.assert(floatArea);\n const logicalFloatSide = context.setFloatAreaDimensions(\n floatArea,\n firstFloat.floatReference,\n floatSide,\n anchorEdge,\n false,\n allowFragmented,\n condition,\n );\n if (!logicalFloatSide) {\n failed = true;\n } else {\n const newFragment = strategy.createPageFloatFragment(\n continuations,\n logicalFloatSide,\n floatArea,\n !!result.newPosition,\n );\n context.addPageFloatFragment(newFragment, true);\n result.pageFloatFragment = newFragment;\n }\n }\n frame.finish(result);\n });\n return frame.result();\n }\n\n layoutPageFloatInner(\n continuation: PageFloats.PageFloatContinuation,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment,\n ): Task.Result<boolean> {\n const context = this.pageFloatLayoutContext;\n const float = continuation.float;\n context.stashEndFloatFragments(float);\n\n function cancelLayout(floatArea, pageFloatFragment) {\n if (pageFloatFragment) {\n context.removePageFloatFragment(pageFloatFragment, true);\n } else if (floatArea) {\n floatArea.element.parentNode.removeChild(floatArea.element);\n }\n context.restoreStashedFragments(float.floatReference);\n context.deferPageFloat(continuation);\n }\n const frame: Task.Frame<boolean> = Task.newFrame(\"layoutPageFloatInner\");\n const self = this;\n this.layoutSinglePageFloatFragment(\n [continuation],\n float.floatSide,\n float.clearSide,\n !context.hasFloatFragments(),\n strategy,\n anchorEdge,\n pageFloatFragment,\n ).then((result) => {\n const floatArea = result.floatArea;\n const newFragment = result.pageFloatFragment;\n const newPosition = result.newPosition;\n if (newFragment) {\n self\n .layoutStashedPageFloats(float.floatReference, [pageFloatFragment])\n .then((success) => {\n if (success) {\n // Add again to invalidate the context\n Asserts.assert(newFragment);\n context.addPageFloatFragment(newFragment);\n context.discardStashedFragments(float.floatReference);\n if (newPosition) {\n const continuation = new PageFloats.PageFloatContinuation(\n float,\n newPosition.primary,\n );\n context.deferPageFloat(continuation);\n }\n frame.finish(true);\n } else {\n cancelLayout(floatArea, newFragment);\n frame.finish(false);\n }\n });\n } else {\n cancelLayout(floatArea, newFragment);\n frame.finish(false);\n }\n });\n return frame.result();\n }\n\n /**\n * @returns Represents if the layout was succeeded or not\n */\n private layoutStashedPageFloats(\n floatReference: PageFloats.FloatReference,\n excluded: PageFloats.PageFloatFragment[],\n ): Task.Result<boolean> {\n const context = this.pageFloatLayoutContext;\n const stashedFloatFragments = context.getStashedFloatFragments(\n floatReference,\n );\n const newFloatAreas = [];\n const newFragments = [];\n let failed = false;\n const frame = Task.newFrame<boolean>(\"layoutStashedPageFloats\");\n const self = this;\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i >= stashedFloatFragments.length) {\n loopFrame.breakLoop();\n return;\n }\n const stashedFragment = stashedFloatFragments[i];\n if (excluded.includes(stashedFragment)) {\n i++;\n loopFrame.continueLoop();\n return;\n }\n const strategy = new PageFloats.PageFloatLayoutStrategyResolver().findByFloat(\n stashedFragment.continuations[0].float,\n );\n\n // Value of 'clear' is irrelevant when laying out stashed floats\n // since whether the 'clear' value allows placing the float\n // here is already resolved.\n self\n .layoutSinglePageFloatFragment(\n stashedFragment.continuations,\n stashedFragment.floatSide,\n null,\n false,\n strategy,\n null,\n )\n .then((result) => {\n const floatArea = result.floatArea;\n if (floatArea) {\n newFloatAreas.push(floatArea);\n }\n const fragment = result.pageFloatFragment;\n if (fragment) {\n newFragments.push(fragment);\n i++;\n loopFrame.continueLoop();\n } else {\n failed = true;\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n if (failed) {\n newFragments.forEach((fragment) => {\n context.removePageFloatFragment(fragment, true);\n });\n newFloatAreas.forEach((area) => {\n const elem = area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n } else {\n stashedFloatFragments.forEach((fragment) => {\n const elem = fragment.area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n }\n frame.finish(!failed);\n });\n return frame.result();\n }\n\n setFloatAnchorViewNode(nodeContext: Vtree.NodeContext): Vtree.NodeContext {\n const parent = nodeContext.viewNode.parentNode;\n const anchor = parent.ownerDocument.createElement(\"span\");\n anchor.setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n if (nodeContext.floatSide === \"footnote\") {\n // Defaults for footnote-call, can be overriden by the stylesheet.\n this.layoutContext.applyPseudoelementStyle(\n nodeContext,\n \"footnote-call\",\n anchor,\n );\n }\n parent.appendChild(anchor);\n parent.removeChild(nodeContext.viewNode);\n const nodeContextAfter = nodeContext.modify();\n nodeContextAfter.after = true;\n nodeContextAfter.viewNode = anchor;\n return nodeContextAfter;\n }\n\n resolveFloatReferenceFromColumnSpan(\n floatReference: PageFloats.FloatReference,\n columnSpan: Css.Val,\n nodeContext: Vtree.NodeContext,\n ): Task.Result<PageFloats.FloatReference> {\n const self = this;\n const frame = Task.newFrame(\n \"resolveFloatReferenceFromColumnSpan\",\n ) as Task.Frame<PageFloats.FloatReference>;\n const columnContext = this.pageFloatLayoutContext;\n const regionContext = columnContext.getPageFloatLayoutContext(\n PageFloats.FloatReference.REGION,\n );\n const isRegionWider =\n columnContext.getContainer().width < regionContext.getContainer().width;\n if (isRegionWider && floatReference === PageFloats.FloatReference.COLUMN) {\n if (columnSpan === Css.ident.auto) {\n this.buildDeepElementView(nodeContext.copy()).then((position) => {\n const element = position.viewNode as Element;\n let inlineSize = Sizing.getSize(self.clientLayout, element, [\n Sizing.Size.MIN_CONTENT_INLINE_SIZE,\n ])[Sizing.Size.MIN_CONTENT_INLINE_SIZE];\n const margin = self.getComputedMargin(element);\n if (self.vertical) {\n inlineSize += margin.top + margin.bottom;\n } else {\n inlineSize += margin.left + margin.right;\n }\n if (inlineSize > self.width) {\n frame.finish(PageFloats.FloatReference.REGION);\n } else {\n frame.finish(floatReference);\n }\n });\n } else if (columnSpan === Css.ident.all) {\n frame.finish(PageFloats.FloatReference.REGION);\n } else {\n frame.finish(floatReference);\n }\n } else {\n frame.finish(floatReference);\n }\n return frame.result();\n }\n\n layoutPageFloat(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const context = this.pageFloatLayoutContext;\n const strategy = new PageFloats.PageFloatLayoutStrategyResolver().findByNodeContext(\n nodeContext,\n );\n let cont: Task.Result<PageFloats.PageFloat>;\n const float = context.findPageFloatByNodePosition(\n nodeContext.toNodePosition(),\n );\n if (!float) {\n cont = strategy.createPageFloat(nodeContext, context, this);\n } else {\n cont = Task.newResult(float);\n }\n return cont.thenAsync((float) => {\n const nodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nodeContext,\n 0,\n );\n const nodeContextAfter = self.setFloatAnchorViewNode(nodeContext);\n const pageFloatFragment = strategy.findPageFloatFragment(float, context);\n const continuation = new PageFloats.PageFloatContinuation(\n float,\n nodePosition,\n );\n if (pageFloatFragment && pageFloatFragment.hasFloat(float)) {\n context.registerPageFloatAnchor(float, nodeContextAfter.viewNode);\n return Task.newResult(nodeContextAfter as Vtree.NodeContext);\n } else if (\n context.isForbidden(float) ||\n context.hasPrecedingFloatsDeferredToNext(float)\n ) {\n context.deferPageFloat(continuation);\n context.registerPageFloatAnchor(float, nodeContextAfter.viewNode);\n return Task.newResult(nodeContextAfter as Vtree.NodeContext);\n } else if (self.nodeContextOverflowingDueToRepetitiveElements) {\n return Task.newResult(null);\n } else {\n const edge = LayoutHelper.calculateEdge(\n nodeContextAfter,\n self.clientLayout,\n 0,\n self.vertical,\n );\n if (self.isOverflown(edge)) {\n return Task.newResult(nodeContextAfter);\n } else {\n return self\n .layoutPageFloatInner(\n continuation,\n strategy,\n edge,\n pageFloatFragment,\n )\n .thenAsync((success) => {\n Asserts.assert(float);\n if (!success) {\n context.registerPageFloatAnchor(\n float,\n nodeContextAfter.viewNode,\n );\n return Task.newResult(nodeContextAfter);\n } else {\n return Task.newResult(null);\n }\n });\n }\n }\n });\n }\n\n createJustificationAdjustmentElement(\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n vertical: boolean,\n ): HTMLElement {\n const span = doc.createElement(\"span\") as HTMLElement;\n span.style.visibility = \"hidden\";\n span.style.verticalAlign = \"top\";\n span.setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n const inner = doc.createElement(\"span\") as HTMLElement;\n inner.style.fontSize = \"0\";\n inner.style.lineHeight = \"0\";\n inner.textContent = \" #\";\n span.appendChild(inner);\n\n // Measure inline-start and inline-end edge positions of the line box,\n // taking (exclusion) floats into consideration\n span.style.display = \"block\";\n span.style.textIndent = \"0\";\n span.style.textAlign = \"left\";\n parentNode.insertBefore(span, insertionPoint);\n const leftPos = this.clientLayout.getElementClientRect(inner);\n span.style.textAlign = \"right\";\n const rightPos = this.clientLayout.getElementClientRect(inner);\n span.style.textAlign = \"\";\n if (Base.checkInlineBlockJustificationBug(document.body)) {\n // For Chrome\n span.style.display = \"inline\";\n } else {\n // For Firefox, Edge and IE\n span.style.display = \"inline-block\";\n }\n const padding = vertical\n ? rightPos.top - leftPos.top\n : rightPos.left - leftPos.left;\n const paddingStr = padding >= 1 ? `${padding - 1}px` : \"100%\";\n if (vertical) {\n span.style.paddingTop = paddingStr;\n } else {\n span.style.paddingLeft = paddingStr;\n }\n return span;\n }\n\n addAndAdjustJustificationElement(\n nodeContext: Vtree.NodeContext,\n insertAfter: boolean,\n node: Node,\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n ): HTMLElement {\n fixJustificationOnHyphen(nodeContext, insertAfter, node, insertionPoint);\n return this.createJustificationAdjustmentElement(\n insertionPoint,\n doc,\n parentNode,\n nodeContext.vertical,\n );\n }\n\n compensateJustificationLineHeight(\n span: Element,\n br: Element,\n nodeContext: Vtree.NodeContext,\n ) {\n const spanRect = this.clientLayout.getElementClientRect(span);\n const brRect = this.clientLayout.getElementClientRect(br);\n if (nodeContext.vertical) {\n (br as HTMLElement).style.marginRight = `${brRect.right -\n spanRect.right}px`;\n (br as HTMLElement).style.width = \"0px\";\n } else {\n (br as HTMLElement).style.marginTop = `${spanRect.top - brRect.top}px`;\n (br as HTMLElement).style.height = \"0px\";\n }\n br.setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n }\n\n /**\n * Fix justification of the last line of text broken across pages (if\n * needed).\n */\n fixJustificationIfNeeded(\n nodeContext: Vtree.NodeContext,\n endOfColumn: boolean,\n ): void {\n if (nodeContext.after && !nodeContext.inline) {\n return;\n }\n if (endOfColumn) {\n let textAlign = \"\";\n for (\n let parent = nodeContext.parent;\n parent && !textAlign;\n parent = parent.parent\n ) {\n if (!parent.inline && parent.viewNode) {\n textAlign = (parent.viewNode as HTMLElement).style.textAlign;\n }\n }\n if (textAlign !== \"justify\") {\n return;\n }\n }\n const node = nodeContext.viewNode;\n const doc = node.ownerDocument;\n const insertAfter =\n endOfColumn && (nodeContext.after || node.nodeType != 1);\n let insertionPoint = insertAfter ? node.nextSibling : node;\n if (insertionPoint && !insertionPoint.parentNode) {\n // Possible if removeSelf = false in finishBreak()\n insertionPoint = null;\n }\n const parentNode =\n node.parentNode || (nodeContext.parent && nodeContext.parent.viewNode);\n if (!parentNode) {\n // Possible if nothing was added to the column\n return;\n }\n const span = this.addAndAdjustJustificationElement(\n nodeContext,\n insertAfter,\n node,\n insertionPoint,\n doc,\n parentNode,\n );\n if (!endOfColumn) {\n const br = doc.createElement(\"div\") as HTMLElement;\n parentNode.insertBefore(br, insertionPoint);\n this.compensateJustificationLineHeight(span, br, nodeContext);\n }\n }\n\n processLineStyling(\n nodeContext: Vtree.NodeContext,\n resNodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"processLineStyling\",\n );\n if (VIVLIOSTYLE_DEBUG) {\n validateCheckPoints(checkPoints);\n }\n let lastCheckPoints = checkPoints.concat([]); // make a copy\n checkPoints.splice(0, checkPoints.length); // make empty\n let totalLineCount = 0;\n let firstPseudo = nodeContext.firstPseudo; // :first-letter is not processed here\n if (firstPseudo.count == 0) {\n firstPseudo = firstPseudo.outer; // move to line pseudoelement (if any)\n }\n frame\n .loopWithFrame((loopFrame) => {\n if (!firstPseudo) {\n loopFrame.breakLoop();\n return;\n }\n const linePositions = self.findLinePositions(lastCheckPoints);\n const count = firstPseudo.count - totalLineCount;\n if (linePositions.length <= count) {\n loopFrame.breakLoop();\n return;\n }\n const lineBreak = self.findAcceptableBreakInside(\n lastCheckPoints,\n linePositions[count - 1],\n true,\n );\n if (lineBreak == null) {\n loopFrame.breakLoop();\n return;\n }\n self.finishBreak(lineBreak, false, false).then(() => {\n totalLineCount += count;\n self.layoutContext\n .peelOff(lineBreak, 0)\n .then((resNodeContextParam) => {\n nodeContext = resNodeContextParam;\n self.fixJustificationIfNeeded(nodeContext, false);\n firstPseudo = nodeContext.firstPseudo;\n lastCheckPoints = []; // Wipe out line breaks inside pseudoelements\n self\n .buildViewToNextBlockEdge(nodeContext, lastCheckPoints)\n .then((resNodeContextParam) => {\n resNodeContext = resNodeContextParam;\n loopFrame.continueLoop();\n });\n });\n });\n })\n .then(() => {\n Array.prototype.push.apply(checkPoints, lastCheckPoints);\n if (VIVLIOSTYLE_DEBUG) {\n validateCheckPoints(checkPoints);\n }\n frame.finish(resNodeContext);\n });\n return frame.result();\n }\n\n isLoneImage(checkPoints: Vtree.NodeContext[]): boolean {\n if (checkPoints.length != 2 && this.breakPositions.length > 0) {\n return false;\n }\n return (\n checkPoints[0].sourceNode == checkPoints[1].sourceNode &&\n mediaTags[(checkPoints[0].sourceNode as Element).localName]\n );\n }\n\n getTrailingMarginEdgeAdjustment(\n trailingEdgeContexts: Vtree.NodeContext[],\n ): number {\n // Margins push the computed height, but are not counted as overflow. We\n // need to find the overall collapsed margin from all enclosed blocks.\n let maxPos = 0;\n let minNeg = 0;\n for (let i = trailingEdgeContexts.length - 1; i >= 0; i--) {\n const nodeContext = trailingEdgeContexts[i];\n if (\n !nodeContext.after ||\n !nodeContext.viewNode ||\n nodeContext.viewNode.nodeType != 1\n ) {\n break;\n }\n const margin = this.getComputedMargin(nodeContext.viewNode as Element);\n const m = this.vertical ? -margin.left : margin.bottom;\n if (m > 0) {\n maxPos = Math.max(maxPos, m);\n } else {\n minNeg = Math.min(minNeg, m);\n }\n }\n return maxPos - minNeg;\n }\n\n /**\n * Layout a single CSS box.\n */\n layoutBreakableBlock(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"layoutBreakableBlock\",\n );\n const checkPoints: Vtree.NodeContext[] = [];\n self\n .buildViewToNextBlockEdge(nodeContext, checkPoints)\n .then((resNodeContext) => {\n // at this point a single block was appended to the column\n // flowPosition is either null or\n // - if !after: contains view for the next block element\n // - if after: contains view for the enclosing block element\n const checkPointIndex = checkPoints.length - 1;\n if (checkPointIndex < 0) {\n frame.finish(resNodeContext);\n return;\n }\n\n // Record the height\n // TODO: should this be done after first-line calculation?\n let edge = self.calculateEdge(\n resNodeContext,\n checkPoints,\n checkPointIndex,\n checkPoints[checkPointIndex].boxOffset,\n );\n let overflown = false;\n if (\n !resNodeContext ||\n !LayoutHelper.isOrphan(resNodeContext.viewNode)\n ) {\n const offsets = BreakPosition.calculateOffset(\n resNodeContext,\n self.collectElementsOffset(),\n );\n overflown = self.isOverflown(\n edge + (self.vertical ? -1 : 1) * offsets.minimum,\n );\n if (\n self.isOverflown(\n edge + (self.vertical ? -1 : 1) * offsets.current,\n ) &&\n !self.nodeContextOverflowingDueToRepetitiveElements\n ) {\n self.nodeContextOverflowingDueToRepetitiveElements = resNodeContext;\n }\n }\n if (resNodeContext == null) {\n edge += self.getTrailingMarginEdgeAdjustment(checkPoints);\n }\n self.updateMaxReachedAfterEdge(edge);\n let lineCont: Task.Result<Vtree.NodeContext>;\n if (nodeContext.firstPseudo) {\n // possibly need to deal with :first-line and friends\n lineCont = self.processLineStyling(\n nodeContext,\n resNodeContext,\n checkPoints,\n );\n } else {\n lineCont = Task.newResult(resNodeContext);\n }\n lineCont.then((nodeContext) => {\n self.postLayoutBlock(nodeContext, checkPoints);\n if (checkPoints.length > 0) {\n self.saveBoxBreakPosition(checkPoints);\n\n // TODO: how to signal overflow in the last pagargaph???\n if (overflown && !self.isLoneImage(checkPoints) && nodeContext) {\n nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n }\n }\n frame.finish(nodeContext);\n });\n });\n return frame.result();\n }\n\n postLayoutBlock(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ) {\n const hooks: Plugin.PostLayoutBlockHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.POST_LAYOUT_BLOCK,\n );\n hooks.forEach((hook) => {\n hook(nodeContext, checkPoints, this);\n });\n }\n\n findEndOfLine(\n linePosition: number,\n checkPoints: Vtree.NodeContext[],\n isUpdateMaxReachedAfterEdge: boolean,\n ): {\n nodeContext: Vtree.NodeContext;\n index: number;\n checkPointIndex: number;\n } {\n if (VIVLIOSTYLE_DEBUG) {\n validateCheckPoints(checkPoints);\n }\n\n // Workaround for Blink not returning correct fractional values for\n // Range.getClientRects.\n // https://bugs.chromium.org/p/chromium/issues/detail?id=629828\n const effectiveLinePosition = this.vertical\n ? linePosition - 1\n : linePosition + 1;\n\n // find the first character which is out\n let lowCP = 0;\n let low = checkPoints[0].boxOffset;\n let low1 = lowCP;\n let highCP = checkPoints.length - 1;\n let high = checkPoints[highCP].boxOffset;\n let mid: number;\n while (low < high) {\n mid = low + Math.ceil((high - low) / 2);\n\n // find the node which contains mid index\n low1 = lowCP;\n let high1 = highCP;\n while (low1 < high1) {\n const mid1 = low1 + Math.ceil((high1 - low1) / 2);\n if (checkPoints[mid1].boxOffset > mid) {\n high1 = mid1 - 1;\n } else {\n low1 = mid1;\n }\n }\n const edge = this.calculateEdge(null, checkPoints, low1, mid);\n if (\n this.vertical\n ? edge <= effectiveLinePosition\n : edge >= effectiveLinePosition\n ) {\n high = mid - 1;\n while (checkPoints[low1].boxOffset == mid) {\n low1--;\n }\n highCP = low1;\n } else {\n if (isUpdateMaxReachedAfterEdge) {\n this.updateMaxReachedAfterEdge(edge);\n }\n low = mid;\n lowCP = low1;\n }\n }\n return {\n nodeContext: checkPoints[low1],\n index: low,\n checkPointIndex: low1,\n };\n }\n\n findAcceptableBreakInside(\n checkPoints: Vtree.NodeContext[],\n edgePosition: number,\n force: boolean,\n ): Vtree.NodeContext {\n const position = this.findEndOfLine(edgePosition, checkPoints, true);\n let nodeContext = position.nodeContext;\n const viewNode = nodeContext.viewNode;\n if (viewNode.nodeType != 1) {\n const textNode = viewNode as Text;\n const textNodeBreaker = this.resolveTextNodeBreaker(nodeContext);\n nodeContext = textNodeBreaker.breakTextNode(\n textNode,\n nodeContext,\n position.index,\n checkPoints,\n position.checkPointIndex,\n force,\n );\n }\n this.clearOverflownViewNodes(nodeContext, false);\n return nodeContext;\n }\n\n resolveTextNodeBreaker(nodeContext: Vtree.NodeContext): TextNodeBreaker {\n const hooks: Plugin.ResolveTextNodeBreakerHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.RESOLVE_TEXT_NODE_BREAKER,\n );\n return hooks.reduce(\n (prev, hook) => hook(nodeContext) || prev,\n TextNodeBreaker.instance,\n );\n }\n\n /**\n * Read ranges skipping special elments\n */\n getRangeBoxes(start: Node, end: Node): Vtree.ClientRect[] {\n const arr = [];\n const range = start.ownerDocument.createRange();\n let wentUp = false;\n let node = start;\n let lastGood: Node = null;\n let haveStart = false;\n let endNotReached = true;\n while (endNotReached) {\n let seekRange = true;\n do {\n let next: Node = null;\n if (node == end) {\n if (end.nodeType === 1) {\n // If end is an element, continue traversing its children to find\n // the last text node inside it. Finish when end has no child or\n // when came back from its children (wentUp==true).\n endNotReached = !(!end.firstChild || wentUp);\n } else {\n endNotReached = false;\n }\n }\n if (node.nodeType != 1) {\n if (!haveStart) {\n range.setStartBefore(node);\n haveStart = true;\n }\n lastGood = node;\n } else if (wentUp) {\n wentUp = false;\n } else if (LayoutHelper.isSpecial(node as Element)) {\n // Skip special\n seekRange = !haveStart;\n } else if (\n (node as Element).localName == \"ruby\" ||\n isSpecialInlineDisplay(\n this.clientLayout.getElementComputedStyle(node as Element).display,\n )\n ) {\n // ruby, inline-block, etc.\n seekRange = !haveStart;\n if (seekRange) {\n range.setStartBefore(node);\n haveStart = true;\n lastGood = node;\n }\n if (node.contains(end)) {\n endNotReached = false;\n }\n } else {\n next = node.firstChild;\n }\n if (!next) {\n next = node.nextSibling;\n if (!next) {\n wentUp = true;\n next = node.parentNode;\n }\n }\n node = next;\n } while (seekRange && endNotReached);\n if (haveStart) {\n range.setEndAfter(lastGood);\n const boxList = this.clientLayout.getRangeClientRects(range);\n for (let i = 0; i < boxList.length; i++) {\n arr.push(boxList[i]);\n }\n haveStart = false;\n }\n }\n return arr;\n }\n\n /**\n * Give block's initial and final nodes, find positions of the line bottoms.\n * This is, of course, somewhat hacky implementation.\n * @return position of line breaks\n */\n findLinePositions(checkPoints: Vtree.NodeContext[]): number[] {\n const LOW_OVERLAP = 0.2;\n const MID_OVERLAP = 0.6;\n const positions = [];\n const boxes = this.getRangeBoxes(\n checkPoints[0].viewNode,\n checkPoints[checkPoints.length - 1].viewNode,\n );\n boxes.sort(\n this.vertical\n ? VtreeImpl.clientrectDecreasingRight\n : VtreeImpl.clientrectIncreasingTop,\n );\n let lineBefore = 0;\n let lineAfter = 0;\n let lineEnd = 0;\n let lineLength = 0;\n let i = 0;\n const dir = this.getBoxDir();\n while (true) {\n if (i < boxes.length) {\n const box = boxes[i];\n let overlap = 1;\n if (lineLength > 0) {\n const boxSize = Math.max(this.getBoxSize(box), 1);\n if (dir * this.getBeforeEdge(box) < dir * lineBefore) {\n overlap = (dir * (this.getAfterEdge(box) - lineBefore)) / boxSize;\n } else if (dir * this.getAfterEdge(box) > dir * lineAfter) {\n overlap = (dir * (lineAfter - this.getBeforeEdge(box))) / boxSize;\n } else {\n overlap = 1;\n }\n }\n if (\n lineLength == 0 ||\n overlap >= MID_OVERLAP ||\n (overlap >= LOW_OVERLAP && this.getStartEdge(box) >= lineEnd - 1)\n ) {\n lineEnd = this.getEndEdge(box);\n if (this.vertical) {\n lineBefore =\n lineLength == 0 ? box.right : Math.max(lineBefore, box.right);\n lineAfter =\n lineLength == 0 ? box.left : Math.min(lineAfter, box.left);\n } else {\n lineBefore =\n lineLength == 0 ? box.top : Math.min(lineBefore, box.top);\n lineAfter =\n lineLength == 0 ? box.bottom : Math.max(lineAfter, box.bottom);\n }\n lineLength++;\n i++;\n continue;\n }\n }\n\n // Add line\n if (lineLength > 0) {\n positions.push(lineAfter);\n lineLength = 0;\n }\n if (i >= boxes.length) {\n break;\n }\n }\n positions.sort(Base.numberCompare);\n if (this.vertical) {\n positions.reverse();\n }\n return positions;\n }\n\n calculateClonedPaddingBorder(nodeContext: Vtree.NodeContext): number {\n let clonedPaddingBorder = 0;\n nodeContext.walkUpBlocks((block) => {\n if (block.inheritedProps[\"box-decoration-break\"] === \"clone\") {\n Asserts.assert(block.viewNode instanceof Element);\n const paddingBorders = this.getComputedPaddingBorder(\n block.viewNode as Element,\n );\n clonedPaddingBorder += block.vertical\n ? -paddingBorders.left\n : paddingBorders.bottom;\n if (block.display === \"table\") {\n clonedPaddingBorder += block.blockBorderSpacing;\n }\n }\n });\n return clonedPaddingBorder;\n }\n\n private getOffsetByRepetitiveElements(\n bp?: BreakPosition.BreakPosition,\n ): number {\n let offset: { current: number; minimum: number };\n if (bp) {\n offset = bp.calculateOffset(this);\n } else {\n offset = BreakPosition.calculateOffset(\n null,\n this.collectElementsOffset(),\n );\n }\n return offset.current;\n }\n\n findBoxBreakPosition(\n bp: BoxBreakPosition,\n force: boolean,\n ): Vtree.NodeContext {\n const self = this;\n const checkPoints = bp.checkPoints;\n let block = checkPoints[0];\n while (block.parent && block.inline) {\n block = block.parent;\n }\n let widows: number;\n let orphans: number;\n if (force) {\n // Last resort, ignore widows/orphans\n widows = 1;\n orphans = 1;\n } else {\n // Get widows/orphans settings from the block element\n widows = Math.max(\n ((block.inheritedProps[\"widows\"] as number) || 2) - 0,\n 1,\n );\n orphans = Math.max(\n ((block.inheritedProps[\"orphans\"] as number) || 2) - 0,\n 1,\n );\n }\n\n // In case of box-decoration-break: clone, width (or height in vertical\n // writing mode) of cloned paddings and borders should be taken into\n // account.\n const clonedPaddingBorder = self.calculateClonedPaddingBorder(block);\n\n // Select the first overflowing line break position\n const linePositions = this.findLinePositions(checkPoints);\n let edge = this.footnoteEdge - clonedPaddingBorder;\n const dir = this.getBoxDir();\n const repetitiveElementsOffset = this.getOffsetByRepetitiveElements(bp);\n edge -= dir * repetitiveElementsOffset;\n\n // If an \"overflowing\" checkpoint (e.g. not allowed by LayoutConstraint)\n // exists before the edge, a line containing the checkpoint should be\n // deferred to the next column.\n const firstOverflowing = this.findFirstOverflowingEdgeAndCheckPoint(\n checkPoints,\n );\n if (isNaN(firstOverflowing.edge)) {\n firstOverflowing.edge = dir * Infinity;\n }\n let lineIndex = Base.binarySearch(linePositions.length, (i) => {\n const p = linePositions[i];\n return self.vertical\n ? p < edge || p <= firstOverflowing.edge\n : p > edge || p >= firstOverflowing.edge;\n });\n\n // If no break point is found due to the \"overflowing\" checkpoint,\n // give up deferring a line containing the checkpoint and try to cut the\n // line just before it.\n const forceCutBeforeOverflowing = lineIndex <= 0;\n if (forceCutBeforeOverflowing) {\n lineIndex = Base.binarySearch(linePositions.length, (i) =>\n self.vertical ? linePositions[i] < edge : linePositions[i] > edge,\n );\n }\n\n // First edge after the one that both fits and satisfies widows constraint.\n lineIndex = Math.min(linePositions.length - widows, lineIndex);\n if (lineIndex < orphans) {\n // Not enough lines to satisfy orphans constraint, cannot break here.\n return null;\n }\n edge = linePositions[lineIndex - 1];\n let nodeContext: Vtree.NodeContext;\n if (forceCutBeforeOverflowing) {\n nodeContext = firstOverflowing.checkPoint;\n } else {\n nodeContext = this.findAcceptableBreakInside(bp.checkPoints, edge, force);\n }\n if (nodeContext) {\n // When line-height is small, the edge calculated above (using Range)\n // can be larger than the edge of the block container containing the text.\n // We update the edge by measuring the block edge.\n const blockEdge = this.getAfterEdgeOfBlockContainer(nodeContext);\n if (!isNaN(blockEdge) && blockEdge < edge) {\n edge = blockEdge;\n }\n this.computedBlockSize =\n dir * (edge - this.beforeEdge) + repetitiveElementsOffset;\n }\n return nodeContext;\n }\n\n getAfterEdgeOfBlockContainer(nodeContext: Vtree.NodeContext): number {\n let blockParent = nodeContext;\n do {\n blockParent = blockParent.parent;\n } while (blockParent && blockParent.inline);\n if (blockParent) {\n blockParent = blockParent.copy().modify();\n blockParent.after = true;\n return LayoutHelper.calculateEdge(\n blockParent,\n this.clientLayout,\n 0,\n this.vertical,\n );\n } else {\n return NaN;\n }\n }\n\n findFirstOverflowingEdgeAndCheckPoint(\n checkPoints: Vtree.NodeContext[],\n ): { edge: number; checkPoint: Vtree.NodeContext | null } {\n const index = checkPoints.findIndex((cp) => cp.overflow);\n if (index < 0) {\n return { edge: NaN, checkPoint: null };\n }\n const cp = checkPoints[index];\n return {\n edge: this.calculateEdge(null, checkPoints, index, cp.boxOffset),\n checkPoint: cp,\n };\n }\n\n findEdgeBreakPosition(\n bp: BreakPosition.EdgeBreakPosition,\n ): Vtree.NodeContext {\n this.computedBlockSize =\n bp.computedBlockSize + this.getOffsetByRepetitiveElements(bp);\n return bp.position;\n }\n\n /**\n * Finalize a line break.\n * @return holing true\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n Asserts.assert(nodeContext.formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n nodeContext.formattingContext,\n );\n let result = layoutProcessor.finishBreak(\n this,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n if (!result) {\n result = LayoutProcessor.blockLayoutProcessor.finishBreak(\n this,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n }\n return result;\n }\n\n findAcceptableBreakPosition(): BreakPositionAndNodeContext {\n let bp: Layout.BreakPosition = null;\n let nodeContext: Vtree.NodeContext = null;\n let penalty = 0;\n let nextPenalty = 0;\n do {\n penalty = nextPenalty;\n nextPenalty = Number.MAX_VALUE;\n for (\n let i = this.breakPositions.length - 1;\n i >= 0 && !nodeContext;\n --i\n ) {\n bp = this.breakPositions[i];\n nodeContext = bp.findAcceptableBreak(this, penalty);\n const minPenalty = bp.getMinBreakPenalty();\n if (minPenalty > penalty) {\n nextPenalty = Math.min(nextPenalty, minPenalty);\n }\n }\n } while (\n // Don't need to find a non-optimal break position if\n // forceNonfitting=false\n nextPenalty > penalty &&\n !nodeContext &&\n this.forceNonfitting\n );\n return { breakPosition: nodeContext ? bp : null, nodeContext };\n }\n\n doFinishBreak(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n initialNodeContext: Vtree.NodeContext,\n initialComputedBlockSize: number,\n ): Task.Result<Vtree.NodeContext> {\n if (\n this.pageFloatLayoutContext.isInvalidated() ||\n this.pageBreakType ||\n !overflownNodeContext\n ) {\n return Task.newResult(nodeContext);\n }\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"doFinishBreak\");\n let forceRemoveSelf = false;\n if (!nodeContext) {\n // Last resort\n if (this.forceNonfitting) {\n Logging.logger.warn(\"Could not find any page breaks?!!\");\n self.skipTailEdges(overflownNodeContext).then((nodeContext) => {\n if (nodeContext) {\n nodeContext = nodeContext.modify();\n nodeContext.overflow = false;\n self.finishBreak(nodeContext, forceRemoveSelf, true).then(() => {\n frame.finish(nodeContext);\n });\n } else {\n frame.finish(nodeContext);\n }\n });\n return frame.result();\n } else {\n nodeContext = initialNodeContext;\n forceRemoveSelf = true;\n self.computedBlockSize = initialComputedBlockSize;\n }\n }\n this.finishBreak(nodeContext, forceRemoveSelf, true).then(() => {\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n /**\n * Determines if a page break is acceptable at this position\n */\n isBreakable(flowPosition: Vtree.NodeContext): boolean {\n if (flowPosition.after) {\n return true; // may be an empty block\n }\n switch (flowPosition.sourceNode.namespaceURI) {\n case Base.NS.SVG:\n return false;\n }\n return !flowPosition.flexContainer;\n }\n\n /**\n * Determines if an indent value is zero\n */\n zeroIndent(val: string | number): boolean {\n const s = val.toString();\n return s == \"\" || s == \"auto\" || !!s.match(/^0+(.0*)?[^0-9]/);\n }\n\n /**\n * @return true if overflows\n */\n checkOverflowAndSaveEdge(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n ): boolean {\n if (!nodeContext) {\n return false;\n }\n if (LayoutHelper.isOrphan(nodeContext.viewNode)) {\n return false;\n }\n let edge = LayoutHelper.calculateEdge(\n nodeContext,\n this.clientLayout,\n 0,\n this.vertical,\n );\n const offsets = BreakPosition.calculateOffset(\n nodeContext,\n this.collectElementsOffset(),\n );\n const overflown = this.isOverflown(\n edge + (this.vertical ? -1 : 1) * offsets.minimum,\n );\n if (\n this.isOverflown(edge + (this.vertical ? -1 : 1) * offsets.current) &&\n !this.nodeContextOverflowingDueToRepetitiveElements\n ) {\n this.nodeContextOverflowingDueToRepetitiveElements = nodeContext;\n } else if (trailingEdgeContexts) {\n // If the edge does not overflow add the trailing margin, which is\n // truncated to the remaining fragmentainer extent.\n const marginEdge =\n edge + this.getTrailingMarginEdgeAdjustment(trailingEdgeContexts);\n const footnoteEdge =\n this.footnoteEdge - this.getBoxDir() * offsets.current;\n edge = this.vertical\n ? Math.min(edge, Math.max(marginEdge, footnoteEdge))\n : Math.max(edge, Math.min(marginEdge, footnoteEdge));\n }\n this.updateMaxReachedAfterEdge(edge);\n return overflown;\n }\n\n /**\n * Save a possible page break position on a CSS block edge. Check if it\n * overflows.\n * @return true if overflows\n */\n checkOverflowAndSaveEdgeAndBreakPosition(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n saveEvenOverflown: boolean,\n breakAtTheEdge: string | null,\n ): boolean {\n if (!nodeContext) {\n return false;\n }\n if (LayoutHelper.isOrphan(nodeContext.viewNode)) {\n return false;\n }\n const overflown = this.checkOverflowAndSaveEdge(\n nodeContext,\n trailingEdgeContexts,\n );\n if (saveEvenOverflown || !overflown) {\n this.saveEdgeBreakPosition(nodeContext, breakAtTheEdge, overflown);\n }\n return overflown;\n }\n\n applyClearance(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext.viewNode.parentNode) {\n // Cannot do ceralance for nodes without parents\n return false;\n }\n\n // measure where the edge of the element would be without clearance\n const margin = this.getComputedMargin(nodeContext.viewNode as Element);\n const spacer = nodeContext.viewNode.ownerDocument.createElement(\"div\");\n if (this.vertical) {\n spacer.style.bottom = \"0px\";\n spacer.style.width = \"1px\";\n spacer.style.marginRight = `${margin.right}px`;\n } else {\n spacer.style.right = \"0px\";\n spacer.style.height = \"1px\";\n spacer.style.marginTop = `${margin.top}px`;\n }\n nodeContext.viewNode.parentNode.insertBefore(spacer, nodeContext.viewNode);\n let spacerBox = this.clientLayout.getElementClientRect(spacer);\n const edge = this.getBeforeEdge(spacerBox);\n const dir = this.getBoxDir();\n const clear = nodeContext.clearSide;\n let clearEdge = -this.getBoxDir() * Infinity;\n if (clear === \"all\") {\n clearEdge = this.pageFloatLayoutContext.getPageFloatClearEdge(\n clear,\n this,\n );\n }\n switch (clear) {\n case \"left\":\n clearEdge = dir * Math.max(clearEdge * dir, this.leftFloatEdge * dir);\n break;\n case \"right\":\n clearEdge = dir * Math.max(clearEdge * dir, this.rightFloatEdge * dir);\n break;\n default:\n clearEdge =\n dir *\n Math.max(\n clearEdge * dir,\n Math.max(this.rightFloatEdge * dir, this.leftFloatEdge * dir),\n );\n }\n\n // edge holds the position where element border \"before\" edge will be\n // without clearance. clearEdge is the \"after\" edge of the float to clear.\n if (edge * dir >= clearEdge * dir) {\n // No need for clearance\n nodeContext.viewNode.parentNode.removeChild(spacer);\n return false;\n } else {\n // Need some clearance, determine how much. Add the clearance node,\n // measure its after edge and adjust after margin (required due to\n // possible margin collapse before clearance was introduced).\n const height = Math.max(1, (clearEdge - edge) * dir);\n if (this.vertical) {\n spacer.style.width = `${height}px`;\n } else {\n spacer.style.height = `${height}px`;\n }\n spacerBox = this.clientLayout.getElementClientRect(spacer);\n const afterEdge = this.getAfterEdge(spacerBox);\n if (this.vertical) {\n let wAdj = afterEdge + margin.right - clearEdge;\n if (wAdj > 0 == margin.right >= 0) {\n // In addition to collapsed portion\n wAdj += margin.right;\n }\n spacer.style.marginLeft = `${wAdj}px`;\n } else {\n let hAdj = clearEdge - (afterEdge + margin.top);\n if (hAdj > 0 == margin.top >= 0) {\n // In addition to collapsed portion\n hAdj += margin.top;\n }\n spacer.style.marginBottom = `${hAdj}px`;\n }\n nodeContext.clearSpacer = spacer;\n return true;\n }\n }\n\n isBFC(formattingContext: Vtree.FormattingContext): boolean {\n if (LayoutProcessor.isInstanceOfBlockFormattingContext(formattingContext)) {\n return true;\n }\n if (\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerFormattingContext(\n formattingContext,\n )\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Skips positions until either the start of unbreakable block or inline\n * content. Also sets breakBefore on the result combining break-before and\n * break-after properties from all elements that meet at the edge.\n */\n skipEdges(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue: string | null,\n ): Task.Result<Vtree.NodeContext> {\n const fc = nodeContext.after\n ? nodeContext.parent && nodeContext.parent.formattingContext\n : nodeContext.formattingContext;\n if (fc && !this.isBFC(fc)) {\n return Task.newResult(nodeContext);\n }\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"skipEdges\");\n\n // If a forced break occurred at the end of the previous column,\n // nodeContext.after should be false.\n let atUnforcedBreak =\n !forcedBreakValue && leadingEdge && nodeContext && nodeContext.after;\n let breakAtTheEdge = forcedBreakValue;\n let lastAfterNodeContext: Vtree.NodeContext = null;\n let leadingEdgeContexts: Vtree.NodeContext[] = [];\n let trailingEdgeContexts: Vtree.NodeContext[] = [];\n let onStartEdges = false;\n\n function needForcedBreak() {\n // leadingEdge=true means that we are at the beginning of the new column\n // and hence must avoid a break (Otherwise leading to an infinite loop)\n return (\n !!forcedBreakValue ||\n (!leadingEdge && Break.isForcedBreakValue(breakAtTheEdge))\n );\n }\n\n function processForcedBreak() {\n nodeContext = leadingEdgeContexts[0] || nodeContext;\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n self.pageBreakType = breakAtTheEdge;\n }\n frame\n .loopWithFrame((loopFrame) => {\n while (nodeContext) {\n Asserts.assert(nodeContext.formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n nodeContext.formattingContext,\n );\n\n // A code block to be able to use break. Break moves to the next\n // node position.\n do {\n if (!nodeContext.viewNode) {\n // Non-displayable content, skip\n break;\n }\n if (nodeContext.inline && nodeContext.viewNode.nodeType != 1) {\n if (\n VtreeImpl.canIgnore(\n nodeContext.viewNode,\n nodeContext.whitespace,\n )\n ) {\n // Ignorable text content, skip\n break;\n }\n if (!nodeContext.after) {\n // Leading edge of non-empty block -> finished going through\n // all starting edges of the box\n if (needForcedBreak()) {\n processForcedBreak();\n } else if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n true,\n breakAtTheEdge,\n )\n ) {\n nodeContext = (self.stopAtOverflow\n ? lastAfterNodeContext || nodeContext\n : nodeContext\n ).modify();\n nodeContext.overflow = true;\n } else {\n nodeContext = nodeContext.modify();\n nodeContext.breakBefore = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (!nodeContext.after) {\n if (layoutProcessor) {\n if (layoutProcessor.startNonInlineElementNode(nodeContext)) {\n break;\n }\n }\n if (nodeContext.clearSide) {\n // clear\n if (\n self.applyClearance(nodeContext) &&\n leadingEdge &&\n self.breakPositions.length === 0\n ) {\n self.saveEdgeBreakPosition(\n nodeContext.copy(),\n breakAtTheEdge,\n false,\n );\n }\n }\n if (\n !self.isBFC(nodeContext.formattingContext) ||\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n ) ||\n self.isFloatNodeContext(nodeContext) ||\n nodeContext.flexContainer\n ) {\n // new formatting context, or float or flex container\n // (unbreakable)\n leadingEdgeContexts.push(nodeContext.copy());\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n\n // check if a forced break must occur before the block.\n if (needForcedBreak()) {\n processForcedBreak();\n } else if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n true,\n breakAtTheEdge,\n ) ||\n !self.layoutConstraint.allowLayout(nodeContext)\n ) {\n // overflow\n nodeContext = (self.stopAtOverflow\n ? lastAfterNodeContext || nodeContext\n : nodeContext\n ).modify();\n nodeContext.overflow = true;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (nodeContext.viewNode.nodeType != 1) {\n // not an element\n break;\n }\n const style = (nodeContext.viewNode as HTMLElement).style;\n if (nodeContext.after) {\n // Skip an empty inline box at the start of a block\n // (An anonymous block consisting entirely of\n // collapsible white space is removed from the rendering tree)\n if (nodeContext.inline) {\n break;\n }\n if (layoutProcessor) {\n if (\n layoutProcessor.afterNonInlineElementNode(\n nodeContext,\n self.stopAtOverflow,\n )\n ) {\n break;\n }\n }\n\n // Trailing edge\n if (onStartEdges) {\n // finished going through all starting edges of the box.\n // check if a forced break must occur before the block.\n if (needForcedBreak()) {\n processForcedBreak();\n loopFrame.breakLoop();\n return;\n }\n\n // since a break did not occur, move to the next edge. this\n // edge is no longer the leading edge.\n leadingEdgeContexts = [];\n leadingEdge = false;\n atUnforcedBreak = false;\n breakAtTheEdge = null;\n }\n onStartEdges = false; // we are now on end edges.\n lastAfterNodeContext = nodeContext.copy();\n trailingEdgeContexts.push(lastAfterNodeContext);\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakAfter,\n );\n if (\n style &&\n !(\n self.zeroIndent(style.paddingBottom) &&\n self.zeroIndent(style.borderBottomWidth)\n )\n ) {\n // Non-zero trailing inset.\n // Margins don't collapse across non-zero borders and\n // paddings.\n trailingEdgeContexts = [lastAfterNodeContext];\n }\n } else {\n // Leading edge\n leadingEdgeContexts.push(nodeContext.copy());\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n if (!self.layoutConstraint.allowLayout(nodeContext)) {\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n !self.stopAtOverflow,\n breakAtTheEdge,\n );\n nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n if (self.stopAtOverflow) {\n loopFrame.breakLoop();\n return;\n }\n }\n const viewTag = (nodeContext.viewNode as Element).localName;\n if (mediaTags[viewTag]) {\n // elements that have inherent content\n // check if a forced break must occur before the block.\n if (needForcedBreak()) {\n processForcedBreak();\n } else if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n true,\n breakAtTheEdge,\n )\n ) {\n // overflow\n nodeContext = (self.stopAtOverflow\n ? lastAfterNodeContext || nodeContext\n : nodeContext\n ).modify();\n nodeContext.overflow = true;\n }\n loopFrame.breakLoop();\n return;\n }\n if (\n style &&\n !(\n self.zeroIndent(style.paddingTop) &&\n self.zeroIndent(style.borderTopWidth)\n )\n ) {\n // Non-zero leading inset\n atUnforcedBreak = false;\n trailingEdgeContexts = [];\n }\n onStartEdges = true; // we are now on starting edges.\n }\n } while (false); // End of block of code to use break\n\n const nextResult = self.nextInTree(nodeContext, atUnforcedBreak);\n if (nextResult.isPending()) {\n nextResult.then((nodeContextParam) => {\n nodeContext = nodeContextParam;\n loopFrame.continueLoop();\n });\n return;\n } else {\n nodeContext = nextResult.get();\n }\n }\n\n if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n trailingEdgeContexts,\n !self.stopAtOverflow,\n breakAtTheEdge,\n )\n ) {\n if (lastAfterNodeContext && self.stopAtOverflow) {\n nodeContext = lastAfterNodeContext.modify();\n nodeContext.overflow = true;\n } else {\n // TODO: what to return here??\n }\n } else if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n })\n .then(() => {\n if (lastAfterNodeContext) {\n self.lastAfterPosition = lastAfterNodeContext.toNodePosition();\n }\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n /**\n * Skips non-renderable positions until it hits the end of the flow or some\n * renderable content. Returns the nodeContext that was passed in if some\n * content remains and null if all content could be skipped.\n */\n skipTailEdges(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n let resultNodeContext = nodeContext.copy();\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"skipEdges\");\n let breakAtTheEdge: string | null = null;\n let onStartEdges = false;\n frame\n .loopWithFrame((loopFrame) => {\n while (nodeContext) {\n // A code block to be able to use break. Break moves to the next\n // node position.\n do {\n if (!nodeContext.viewNode) {\n // Non-displayable content, skip\n break;\n }\n if (nodeContext.inline && nodeContext.viewNode.nodeType != 1) {\n if (\n VtreeImpl.canIgnore(\n nodeContext.viewNode,\n nodeContext.whitespace,\n )\n ) {\n // Ignorable text content, skip\n break;\n }\n if (!nodeContext.after) {\n // Leading edge of non-empty block -> finished going through\n // all starting edges of the box\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (!nodeContext.after) {\n if (\n self.isFloatNodeContext(nodeContext) ||\n nodeContext.flexContainer\n ) {\n // float or flex container (unbreakable)\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n\n // check if a forced break must occur before the block.\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (nodeContext.viewNode.nodeType != 1) {\n // not an element\n break;\n }\n const style = (nodeContext.viewNode as HTMLElement).style;\n if (nodeContext.after) {\n // Trailing edge\n if (onStartEdges) {\n // finished going through all starting edges of the box.\n // check if a forced break must occur before the block.\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n loopFrame.breakLoop();\n return;\n }\n\n // since a break did not occur, move to the next edge.\n breakAtTheEdge = null;\n }\n onStartEdges = false; // we are now on end edges.\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakAfter,\n );\n } else {\n // Leading edge\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n const viewTag = (nodeContext.viewNode as Element).localName;\n if (mediaTags[viewTag]) {\n // elements that have inherent content\n // check if a forced break must occur before the block.\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n if (\n style &&\n !(\n self.zeroIndent(style.paddingTop) &&\n self.zeroIndent(style.borderTopWidth)\n )\n ) {\n // Non-zero leading inset\n loopFrame.breakLoop();\n return;\n }\n }\n onStartEdges = true; // we are now on starting edges.\n } while (false); // End of block of code to use break\n\n const nextResult = self.layoutContext.nextInTree(nodeContext);\n if (nextResult.isPending()) {\n nextResult.then((nodeContextParam) => {\n nodeContext = nodeContextParam;\n loopFrame.continueLoop();\n });\n return;\n } else {\n nodeContext = nextResult.get();\n }\n }\n resultNodeContext = null;\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(resultNodeContext);\n });\n return frame.result();\n }\n\n layoutFloatOrFootnote(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n if (\n PageFloats.isPageFloat(nodeContext.floatReference) ||\n nodeContext.floatSide === \"footnote\"\n ) {\n return this.layoutPageFloat(nodeContext);\n } else {\n return this.layoutFloat(nodeContext);\n }\n }\n\n /**\n * Layout next portion of the source.\n */\n layoutNext(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue?: string | null,\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"layoutNext\");\n this.skipEdges(nodeContext, leadingEdge, forcedBreakValue || null).then(\n (nodeContextParam) => {\n nodeContext = nodeContextParam as Vtree.NodeContext;\n if (\n !nodeContext ||\n self.pageBreakType ||\n self.stopByOverflow(nodeContext)\n ) {\n // finished all content, explicit page break or overflow (automatic\n // page break)\n frame.finish(nodeContext);\n } else {\n const formattingContext = nodeContext.formattingContext;\n Asserts.assert(formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n formattingContext,\n );\n layoutProcessor\n .layout(nodeContext, self, leadingEdge)\n .thenFinish(frame);\n }\n },\n );\n return frame.result();\n }\n\n clearOverflownViewNodes(\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ): void {\n if (!nodeContext) {\n return;\n }\n for (\n let parent = nodeContext.parent;\n nodeContext;\n nodeContext = parent, parent = parent ? parent.parent : null\n ) {\n const formattingContext = (parent || nodeContext).formattingContext;\n Asserts.assert(formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n formattingContext,\n );\n layoutProcessor.clearOverflownViewNodes(\n this,\n parent,\n nodeContext,\n removeSelf,\n );\n removeSelf = false;\n }\n }\n\n initGeom(): void {\n // TODO: we should be able to avoid querying the layout engine at this\n // point. Create an element that fills the content area and query its size.\n // Calling getElementClientRect on the container element includes element\n // padding which is wrong for our purposes.\n const probe = this.element.ownerDocument.createElement(\n \"div\",\n ) as HTMLElement;\n probe.style.position = \"absolute\";\n probe.style.top = `${this.paddingTop}px`;\n probe.style.right = `${this.paddingRight}px`;\n probe.style.bottom = `${this.paddingBottom}px`;\n probe.style.left = `${this.paddingLeft}px`;\n this.element.appendChild(probe);\n const columnBBox = this.clientLayout.getElementClientRect(probe);\n this.element.removeChild(probe);\n const offsetX = this.originX + this.left + this.getInsetLeft();\n const offsetY = this.originY + this.top + this.getInsetTop();\n this.box = new GeometryUtil.Rect(\n offsetX,\n offsetY,\n offsetX + this.width,\n offsetY + this.height,\n );\n this.startEdge = columnBBox\n ? this.vertical\n ? columnBBox.top\n : columnBBox.left\n : 0;\n this.endEdge = columnBBox\n ? this.vertical\n ? columnBBox.bottom\n : columnBBox.right\n : 0;\n this.beforeEdge = columnBBox\n ? this.vertical\n ? columnBBox.right\n : columnBBox.top\n : 0;\n this.afterEdge = columnBBox\n ? this.vertical\n ? columnBBox.left\n : columnBBox.bottom\n : 0;\n this.leftFloatEdge = this.beforeEdge;\n this.rightFloatEdge = this.beforeEdge;\n this.bottommostFloatTop = this.beforeEdge;\n this.footnoteEdge = this.afterEdge;\n this.bands = GeometryUtil.shapesToBands(\n this.box,\n [this.getInnerShape()],\n this.getExclusions(),\n 8,\n this.snapHeight,\n this.vertical,\n );\n this.createFloats();\n }\n\n init(): void {\n this.chunkPositions = [];\n Base.setCSSProperty(this.element, \"width\", `${this.width}px`);\n Base.setCSSProperty(this.element, \"height\", `${this.height}px`);\n this.initGeom();\n this.computedBlockSize = 0;\n this.overflown = false;\n this.pageBreakType = null;\n this.lastAfterPosition = null;\n }\n\n /**\n * Save the potential breaking position at the edge. Should, in general, save\n * \"after\" position but only after skipping all of the \"before\" ones and\n * getting to the non-empty content (to get breakAtEdge right).\n */\n saveEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakAtEdge: string | null,\n overflows: boolean,\n ): void {\n Asserts.assert(position.formattingContext);\n const copy = position.copy();\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n position.formattingContext,\n );\n const clonedPaddingBorder = this.calculateClonedPaddingBorder(copy);\n const bp = layoutProcessor.createEdgeBreakPosition(\n copy,\n breakAtEdge,\n overflows,\n this.computedBlockSize + clonedPaddingBorder,\n );\n this.breakPositions.push(bp);\n }\n\n /**\n * @param checkPoints array of breaking points for breakable block\n */\n saveBoxBreakPosition(checkPoints: Vtree.NodeContext[]): void {\n const penalty = checkPoints[0].breakPenalty;\n const bp = new BoxBreakPosition(checkPoints, penalty);\n this.breakPositions.push(bp);\n }\n\n updateMaxReachedAfterEdge(afterEdge: number) {\n if (!isNaN(afterEdge)) {\n const size = this.getBoxDir() * (afterEdge - this.beforeEdge);\n this.computedBlockSize = Math.max(size, this.computedBlockSize);\n }\n }\n\n /**\n * @param chunkPosition starting position.\n * @return holding end position.\n */\n layout(\n chunkPosition: Vtree.ChunkPosition,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<Vtree.ChunkPosition> {\n this.chunkPositions.push(chunkPosition); // So we can re-layout this column later\n if (chunkPosition.primary.after) {\n this.lastAfterPosition = chunkPosition.primary;\n }\n if (this.stopAtOverflow && this.overflown) {\n return Task.newResult(chunkPosition as Vtree.ChunkPosition);\n }\n if (this.isFullWithPageFloats()) {\n if (\n chunkPosition.primary.after &&\n chunkPosition.primary.steps.length === 1\n ) {\n // End of contents\n return Task.newResult(null as Vtree.ChunkPosition);\n } else {\n return Task.newResult(chunkPosition as Vtree.ChunkPosition);\n }\n }\n const self = this;\n const frame: Task.Frame<Vtree.ChunkPosition> = Task.newFrame(\"layout\");\n\n // ------ start the column -----------\n self.openAllViews(chunkPosition.primary).then((nodeContext) => {\n let initialNodeContext: Vtree.NodeContext = null;\n if (nodeContext.viewNode) {\n initialNodeContext = nodeContext.copy();\n } else {\n const nextInTreeListener = (evt) => {\n if (evt.nodeContext.viewNode) {\n initialNodeContext = evt.nodeContext;\n self.layoutContext.removeEventListener(\n \"nextInTree\",\n nextInTreeListener,\n );\n }\n };\n self.layoutContext.addEventListener(\"nextInTree\", nextInTreeListener);\n }\n const retryer = new ColumnLayoutRetryer(leadingEdge, breakAfter);\n retryer.layout(nodeContext, self).then((nodeContextParam) => {\n self\n .doFinishBreak(\n nodeContextParam,\n retryer.context.overflownNodeContext,\n initialNodeContext,\n retryer.initialComputedBlockSize,\n )\n .then((positionAfter) => {\n let cont: Task.Result<boolean> = null;\n if (!self.pseudoParent) {\n cont = self.doFinishBreakOfFragmentLayoutConstraints(\n positionAfter,\n );\n } else {\n cont = Task.newResult(null);\n }\n cont.then(() => {\n if (self.pageFloatLayoutContext.isInvalidated()) {\n frame.finish(null);\n return;\n }\n if (!positionAfter) {\n frame.finish(null);\n } else {\n self.overflown = true;\n const result = new VtreeImpl.ChunkPosition(\n positionAfter.toNodePosition(),\n );\n frame.finish(result);\n }\n });\n });\n });\n });\n return frame.result();\n }\n\n isFullWithPageFloats(): boolean {\n return this.pageFloatLayoutContext.isColumnFullWithPageFloats(this);\n }\n\n getMaxBlockSizeOfPageFloats(): number {\n return this.pageFloatLayoutContext.getMaxBlockSizeOfPageFloats();\n }\n\n doFinishBreakOfFragmentLayoutConstraints(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\n \"doFinishBreakOfFragmentLayoutConstraints\",\n );\n const sortedFragmentLayoutConstraints = [].concat(\n this.fragmentLayoutConstraints,\n );\n sortedFragmentLayoutConstraints.sort(\n (a, b) => a.getPriorityOfFinishBreak() - b.getPriorityOfFinishBreak(),\n );\n let i = 0;\n frame\n .loop(() => {\n if (i < sortedFragmentLayoutConstraints.length) {\n const result = sortedFragmentLayoutConstraints[i++].finishBreak(\n nodeContext,\n this,\n );\n return result.thenReturn(true);\n } else {\n return Task.newResult(false);\n }\n })\n .then(() => {\n frame.finish(true);\n });\n return frame.result();\n }\n\n /**\n * @param nodeContext starting position.\n * @return holding end position.\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<{\n nodeContext: Vtree.NodeContext;\n overflownNodeContext: Vtree.NodeContext;\n }> {\n const self = this;\n const frame: Task.Frame<{\n nodeContext: Vtree.NodeContext;\n overflownNodeContext: Vtree.NodeContext;\n }> = Task.newFrame(\"doLayout\");\n let overflownNodeContext: Vtree.NodeContext = null;\n\n // ------ init backtracking list -----\n self.breakPositions = [];\n self.nodeContextOverflowingDueToRepetitiveElements = null;\n\n // ------- fill the column -------------\n frame\n .loopWithFrame((loopFrame) => {\n while (nodeContext) {\n // fill a single block\n let pending = true;\n self\n .layoutNext(nodeContext, leadingEdge, breakAfter || null)\n .then((nodeContextParam) => {\n leadingEdge = false;\n breakAfter = null;\n if (\n self.nodeContextOverflowingDueToRepetitiveElements &&\n self.stopAtOverflow\n ) {\n self.pageBreakType = null;\n nodeContext =\n self.nodeContextOverflowingDueToRepetitiveElements;\n nodeContext.overflow = true;\n } else {\n nodeContext = nodeContextParam;\n }\n if (self.pageFloatLayoutContext.isInvalidated()) {\n loopFrame.breakLoop();\n } else if (self.pageBreakType) {\n // explicit page break\n loopFrame.breakLoop(); // Loop end\n } else if (nodeContext && self.stopByOverflow(nodeContext)) {\n // overflow (implicit page break): back up and find a\n // page break\n overflownNodeContext = nodeContext;\n const bp = self.findAcceptableBreakPosition();\n nodeContext = bp.nodeContext;\n if (bp.breakPosition) {\n bp.breakPosition.breakPositionChosen(self);\n }\n loopFrame.breakLoop(); // Loop end\n } else {\n if (pending) {\n // Sync case\n pending = false;\n } else {\n // Async case\n loopFrame.continueLoop();\n }\n }\n });\n if (pending) {\n // Async case and loop end\n pending = false;\n return;\n }\n }\n\n // Sync case\n self.computedBlockSize += self.getOffsetByRepetitiveElements();\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish({ nodeContext, overflownNodeContext });\n });\n return frame.result();\n }\n\n /**\n * Re-layout already laid-out chunks. Return the position of the last flow if\n * there is an overflow.\n * TODO: deal with chunks that did not fit at all.\n * @return holding end position.\n */\n redoLayout(): Task.Result<Vtree.ChunkPosition> {\n const chunkPositions = this.chunkPositions;\n let last: Node = this.element.lastChild;\n while (last != this.last) {\n const prev = last.previousSibling;\n if (\n !(\n this.element === last.parentNode &&\n (this.layoutContext as Vgen.ViewFactory).isPseudoelement(last)\n )\n ) {\n this.element.removeChild(last);\n }\n last = prev;\n }\n this.killFloats();\n this.init();\n const self = this;\n const frame: Task.Frame<Vtree.ChunkPosition> = Task.newFrame(\"redoLayout\");\n let i = 0;\n let res: Vtree.ChunkPosition = null;\n let leadingEdge = true;\n frame\n .loopWithFrame((loopFrame) => {\n if (i < chunkPositions.length) {\n const chunkPosition = chunkPositions[i++];\n self.layout(chunkPosition, leadingEdge).then((pos) => {\n leadingEdge = false;\n if (pos) {\n res = pos;\n loopFrame.breakLoop();\n } else {\n loopFrame.continueLoop();\n }\n });\n return;\n }\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(res);\n });\n return frame.result();\n }\n\n saveDistanceToBlockEndFloats() {\n const blockStartEdgeOfBlockEndFloats = this.pageFloatLayoutContext.getBlockStartEdgeOfBlockEndFloats();\n if (\n blockStartEdgeOfBlockEndFloats > 0 &&\n isFinite(blockStartEdgeOfBlockEndFloats)\n ) {\n this.blockDistanceToBlockEndFloats =\n this.getBoxDir() *\n (blockStartEdgeOfBlockEndFloats -\n this.beforeEdge -\n this.computedBlockSize);\n }\n }\n\n collectElementsOffset(): RepetitiveElement.ElementsOffset[] {\n const repetitiveElements: RepetitiveElement.ElementsOffset[] = [];\n for (let current: Column = this; current; current = current.pseudoParent) {\n current.fragmentLayoutConstraints.forEach((constraint) => {\n if (\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerLayoutConstraint(\n constraint,\n )\n ) {\n const repetitiveElement = constraint.getRepetitiveElements();\n repetitiveElements.push(repetitiveElement);\n }\n if (\n Selectors.isInstanceOfAfterIfContinuesLayoutConstraint(constraint)\n ) {\n const repetitiveElement = constraint.getRepetitiveElements();\n repetitiveElements.push(repetitiveElement);\n }\n if (Table.isInstanceOfTableRowLayoutConstraint(constraint)) {\n constraint\n .getElementsOffsetsForTableCell(this)\n .forEach((repetitiveElement) => {\n repetitiveElements.push(repetitiveElement);\n });\n }\n });\n }\n return repetitiveElements;\n }\n}\n\n/**\n * Represents a \"pseudo\"-column nested inside a real column.\n * This class is created to handle parallel fragmented flows (e.g. table columns\n * in a single table row). A pseudo-column behaves in the same way as the\n * original column, sharing its properties. Property changes on the\n * pseudo-column are not propagated to the original column. The LayoutContext of\n * the original column is also cloned and used by the pseudo-column, not to\n * propagate state changes of the LayoutContext caused by the pseudo-column.\n * @param column The original (parent) column\n * @param viewRoot Root element for the pseudo-column, i.e., the root of the\n * fragmented flow.\n * @param parentNodeContext A NodeContext generating this PseudoColumn\n */\nexport class PseudoColumn {\n startNodeContexts: Vtree.NodeContext[] = [];\n private column: Layout.Column;\n constructor(\n column: Layout.Column,\n viewRoot: Element,\n parentNodeContext: Vtree.NodeContext,\n ) {\n this.column = Object.create(column) as Layout.Column;\n this.column.element = viewRoot;\n this.column.layoutContext = column.layoutContext.clone();\n this.column.stopAtOverflow = false;\n this.column.flowRootFormattingContext = parentNodeContext.formattingContext;\n this.column.pseudoParent = column;\n const parentClonedPaddingBorder = this.column.calculateClonedPaddingBorder(\n parentNodeContext,\n );\n this.column.footnoteEdge =\n this.column.footnoteEdge - parentClonedPaddingBorder;\n const pseudoColumn = this;\n this.column.openAllViews = function(position) {\n return Column.prototype.openAllViews\n .call(this, position)\n .thenAsync((result) => {\n pseudoColumn.startNodeContexts.push(result.copy());\n return Task.newResult(result);\n });\n };\n }\n /**\n * @param chunkPosition starting position.\n * @return holding end position.\n */\n layout(\n chunkPosition: Vtree.ChunkPosition,\n leadingEdge: boolean,\n ): Task.Result<Vtree.ChunkPosition> {\n return this.column.layout(chunkPosition, leadingEdge);\n }\n findAcceptableBreakPosition(\n allowBreakAtStartPosition: boolean,\n ): Layout.BreakPositionAndNodeContext {\n const p = this.column.findAcceptableBreakPosition();\n if (allowBreakAtStartPosition) {\n const startNodeContext = this.startNodeContexts[0].copy();\n const bp = new BreakPosition.EdgeBreakPosition(\n startNodeContext,\n null,\n startNodeContext.overflow,\n 0,\n );\n bp.findAcceptableBreak(this.column, 0);\n if (!p.nodeContext) {\n return { breakPosition: bp, nodeContext: startNodeContext };\n }\n }\n return p;\n }\n /**\n * @return holing true\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n return this.column.finishBreak(nodeContext, forceRemoveSelf, endOfColumn);\n }\n doFinishBreakOfFragmentLayoutConstraints(positionAfter: Vtree.NodeContext) {\n this.column.doFinishBreakOfFragmentLayoutConstraints(positionAfter);\n }\n isStartNodeContext(nodeContext: Vtree.NodeContext): boolean {\n const startNodeContext = this.startNodeContexts[0];\n return (\n startNodeContext.viewNode === nodeContext.viewNode &&\n startNodeContext.after === nodeContext.after &&\n startNodeContext.offsetInNode === nodeContext.offsetInNode\n );\n }\n isLastAfterNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return VtreeImpl.isSameNodePosition(\n nodeContext.toNodePosition(),\n this.column.lastAfterPosition,\n );\n }\n getColumnElement(): Element {\n return this.column.element;\n }\n getColumn(): Layout.Column {\n return this.column;\n }\n}\n\nexport const firstCharPattern = /^[^A-Za-z0-9_\\u009E\\u009F\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02AF\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527]*([A-Za-z0-9_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02AF\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527][^A-Za-z0-9_\\u009E\\u009F\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02AF\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527]*)?/;\n\nexport type SinglePageFloatLayoutResult = Layout.SinglePageFloatLayoutResult;\n\nexport function fixJustificationOnHyphen(\n nodeContext: Vtree.NodeContext,\n insertAfter: boolean,\n node: Node,\n insertionPoint: Node,\n): void {\n if (Base.checkSoftWrapOpportunityAfterHyphenBug(document.body)) {\n const hyphenChar = resolveHyphenateCharacter(nodeContext);\n const prevSibling = insertAfter ? node : node.previousSibling;\n const prevText = prevSibling ? prevSibling.textContent : \"\";\n if (prevText.charAt(prevText.length - 1) === hyphenChar) {\n const doc = node.ownerDocument;\n const parent = node.parentNode;\n if (Base.checkSoftWrapOpportunityByWbrBug(document.body)) {\n // For IE\n parent.insertBefore(doc.createTextNode(\" \"), insertionPoint);\n } else {\n // For Edge\n parent.insertBefore(doc.createElement(\"wbr\"), insertionPoint);\n }\n }\n }\n}\n\n/**\n * breaking point resolver for Text Node.\n */\nexport class TextNodeBreaker implements Layout.TextNodeBreaker {\n breakTextNode(\n textNode: Text,\n nodeContext: Vtree.NodeContext,\n low: number,\n checkPoints: Vtree.NodeContext[],\n checkpointIndex: number,\n force: boolean,\n ): Vtree.NodeContext {\n if (nodeContext.after) {\n nodeContext.offsetInNode = textNode.length;\n } else {\n // Character with index low is the last one that fits.\n let viewIndex = low - nodeContext.boxOffset;\n const text = textNode.data;\n if (text.charCodeAt(viewIndex) == 173) {\n viewIndex = this.breakAfterSoftHyphen(\n textNode,\n text,\n viewIndex,\n nodeContext,\n );\n } else {\n viewIndex = this.breakAfterOtherCharacter(\n textNode,\n text,\n viewIndex,\n nodeContext,\n );\n }\n if (viewIndex > 0) {\n nodeContext = this.updateNodeContext(nodeContext, viewIndex, textNode);\n }\n }\n return nodeContext;\n }\n\n breakAfterSoftHyphen(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number {\n // convert trailing soft hyphen to a real hyphen\n textNode.replaceData(\n viewIndex,\n text.length - viewIndex,\n !nodeContext.breakWord ? resolveHyphenateCharacter(nodeContext) : \"\",\n );\n return viewIndex + 1;\n }\n\n breakAfterOtherCharacter(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number {\n // keep the trailing character (it may be a space or not)\n const ch0 = text.charAt(viewIndex);\n viewIndex++;\n const ch1 = text.charAt(viewIndex);\n\n // If automatic hyphen was inserted here, add a real hyphen.\n textNode.replaceData(\n viewIndex,\n text.length - viewIndex,\n !nodeContext.breakWord && Base.isLetter(ch0) && Base.isLetter(ch1)\n ? resolveHyphenateCharacter(nodeContext)\n : \"\",\n );\n return viewIndex;\n }\n\n updateNodeContext(\n nodeContext: Vtree.NodeContext,\n viewIndex: number,\n textNode: Text,\n ): Vtree.NodeContext {\n nodeContext = nodeContext.modify();\n nodeContext.offsetInNode += viewIndex;\n nodeContext.breakBefore = null;\n return nodeContext;\n }\n\n static instance: TextNodeBreaker;\n}\nTextNodeBreaker.instance = new TextNodeBreaker();\n\nexport function resolveHyphenateCharacter(\n nodeContext: Vtree.NodeContext,\n): string {\n return (\n nodeContext.hyphenateCharacter ||\n (nodeContext.parent && nodeContext.parent.hyphenateCharacter) ||\n \"-\"\n );\n}\n\nexport class ColumnLayoutRetryer extends LayoutRetryers.AbstractLayoutRetryer {\n breakAfter: string | null;\n private initialPageBreakType: string | null = null;\n initialComputedBlockSize: number = 0;\n private initialOverflown: boolean = false;\n context: { overflownNodeContext: Vtree.NodeContext } = {\n overflownNodeContext: null,\n };\n\n constructor(\n public readonly leadingEdge: boolean,\n breakAfter?: string | null,\n ) {\n super();\n this.breakAfter = breakAfter || null;\n }\n\n /**\n * @override\n */\n resolveLayoutMode(nodeContext: Vtree.NodeContext): Layout.LayoutMode {\n return new DefaultLayoutMode(\n this.leadingEdge,\n this.breakAfter,\n this.context,\n );\n }\n\n /**\n * @override\n */\n prepareLayout(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n column.fragmentLayoutConstraints = [];\n if (!column.pseudoParent) {\n Shared.clearRepetitiveElementsCache();\n }\n }\n\n /**\n * @override\n */\n clearNodes(initialPosition: Vtree.NodeContext) {\n super.clearNodes(initialPosition);\n let nodeContext = initialPosition;\n while (nodeContext) {\n const viewNode = nodeContext.viewNode;\n if (viewNode) {\n LayoutHelper.removeFollowingSiblings(viewNode.parentNode, viewNode);\n }\n nodeContext = nodeContext.parent;\n }\n }\n\n /**\n * @override\n */\n saveState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n super.saveState(nodeContext, column);\n this.initialPageBreakType = column.pageBreakType;\n this.initialComputedBlockSize = column.computedBlockSize;\n this.initialOverflown = column.overflown;\n }\n\n /**\n * @override\n */\n restoreState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n super.restoreState(nodeContext, column);\n column.pageBreakType = this.initialPageBreakType;\n column.computedBlockSize = this.initialComputedBlockSize;\n column.overflown = this.initialOverflown;\n }\n}\n\nexport class DefaultLayoutMode implements Layout.LayoutMode {\n constructor(\n public readonly leadingEdge: boolean,\n public readonly breakAfter: string | null,\n public readonly context: { overflownNodeContext: Vtree.NodeContext },\n ) {}\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"DefaultLayoutMode.doLayout\",\n );\n\n processAfterIfContinuesOfAncestors(nodeContext, column).then(() => {\n column\n .doLayout(nodeContext, this.leadingEdge, this.breakAfter)\n .then((result) => {\n this.context.overflownNodeContext = result.overflownNodeContext;\n frame.finish(result.nodeContext);\n });\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: Layout.Column): boolean {\n if (column.pageFloatLayoutContext.isInvalidated() || column.pageBreakType) {\n return true;\n }\n if (column.fragmentLayoutConstraints.length <= 0) {\n return true;\n }\n return column.fragmentLayoutConstraints.every((constraint) =>\n constraint.allowLayout(\n nodeContext,\n this.context.overflownNodeContext,\n column,\n ),\n );\n }\n\n /**\n * @override\n */\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n accepted: boolean,\n ): boolean {\n if (!accepted) {\n const hasNextCandidate = column.fragmentLayoutConstraints.some(\n (constraint) => constraint.nextCandidate(positionAfter),\n );\n\n // If there is no next candidate, we accept the current layout trial.\n // Later Column#doFinishBreak decides whether the overflowing content\n // should be placed as is or be deferred to the next column,\n // depending on the value of Column#forceNonfitting.\n accepted = !hasNextCandidate;\n }\n column.fragmentLayoutConstraints.forEach((constraint) => {\n constraint.postLayout(accepted, positionAfter, initialPosition, column);\n });\n return accepted;\n }\n}\n\nexport class PageFloatArea extends Column implements Layout.PageFloatArea {\n private rootViewNodes: Element[] = [];\n private floatMargins: GeometryUtil.Insets[] = [];\n adjustContentRelativeSize: boolean = true;\n\n constructor(\n public readonly floatSide: string,\n element: Element,\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n layoutConstraint: LayoutConstraint,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n public readonly parentContainer: Vtree.Container,\n ) {\n super(\n element,\n layoutContext,\n clientLayout,\n layoutConstraint,\n pageFloatLayoutContext,\n );\n }\n\n /**\n * @override\n */\n openAllViews(position: Vtree.NodePosition): Task.Result<Vtree.NodeContext> {\n return super.openAllViews(position).thenAsync((nodeContext) => {\n if (nodeContext) {\n this.fixFloatSizeAndPosition(nodeContext);\n }\n return Task.newResult(nodeContext);\n });\n }\n\n convertPercentageSizesToPx(target: Element) {\n const containingBlockRect = this.parentContainer.getPaddingRect();\n const refWidth = containingBlockRect.x2 - containingBlockRect.x1;\n const refHeight = containingBlockRect.y2 - containingBlockRect.y1;\n\n function convertPercentageToPx(props: string[], refValue: number) {\n props.forEach((propName) => {\n const valueString = Base.getCSSProperty(target, propName);\n if (valueString && valueString.charAt(valueString.length - 1) === \"%\") {\n const percentageValue = parseFloat(valueString);\n const value = (refValue * percentageValue) / 100;\n Base.setCSSProperty(target, propName, `${value}px`);\n }\n });\n }\n convertPercentageToPx([\"width\", \"max-width\", \"min-width\"], refWidth);\n convertPercentageToPx([\"height\", \"max-height\", \"min-height\"], refHeight);\n convertPercentageToPx(\n [\n \"margin-top\",\n \"margin-right\",\n \"margin-bottom\",\n \"margin-left\",\n \"padding-top\",\n \"padding-right\",\n \"padding-bottom\",\n \"padding-left\",\n ],\n this.vertical ? refHeight : refWidth,\n );\n [\"margin-top\", \"margin-right\", \"margin-bottom\", \"margin-left\"].forEach(\n (propName) => {\n const value = Base.getCSSProperty(target, propName);\n if (value === \"auto\") {\n Base.setCSSProperty(target, propName, \"0\");\n }\n },\n );\n }\n\n fixFloatSizeAndPosition(nodeContext: Vtree.NodeContext) {\n while (nodeContext.parent) {\n nodeContext = nodeContext.parent;\n }\n Asserts.assert(nodeContext.viewNode.nodeType === 1);\n const rootViewNode = nodeContext.viewNode as Element;\n this.rootViewNodes.push(rootViewNode);\n if (this.adjustContentRelativeSize) {\n this.convertPercentageSizesToPx(rootViewNode);\n }\n this.floatMargins.push(this.getComputedMargin(rootViewNode));\n if (this.adjustContentRelativeSize) {\n const floatSide = this.floatSide;\n const isVertical = this.parentContainer.vertical;\n if (isVertical) {\n if (floatSide === \"block-end\" || floatSide === \"left\") {\n const height = Base.getCSSProperty(rootViewNode, \"height\");\n if (height !== \"\" && height !== \"auto\") {\n Base.setCSSProperty(rootViewNode, \"margin-top\", \"auto\");\n }\n }\n } else {\n if (floatSide === \"block-end\" || floatSide === \"bottom\") {\n const width = Base.getCSSProperty(rootViewNode, \"width\");\n if (width !== \"\" && width !== \"auto\") {\n Base.setCSSProperty(rootViewNode, \"margin-left\", \"auto\");\n }\n }\n }\n }\n }\n\n getContentInlineSize(): number {\n return Math.max.apply(\n null,\n this.rootViewNodes.map((r, i) => {\n const box = this.clientLayout.getElementClientRect(r);\n const margin = this.floatMargins[i];\n return this.vertical\n ? margin.top + box.height + margin.bottom\n : margin.left + box.width + margin.right;\n }),\n );\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview RepetitiveElement - Elements repeated in every fragment\n * by repeat-on-break property.\n */\nimport * as Asserts from \"./asserts\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as LayoutRetryers from \"./layout-retryers\";\nimport * as LayoutUtil from \"./layout-util\";\nimport * as Plugin from \"./plugin\";\nimport * as Shared from \"./shared\";\nimport * as Task from \"./task\";\nimport * as VtreeImpl from \"./vtree\";\nimport * as Layout from \"./layout\";\nimport {\n FormattingContextType,\n FragmentLayoutConstraintType,\n Layout as LayoutType,\n RepetitiveElement,\n Table,\n Vtree,\n} from \"./types\";\n\nexport class RepetitiveElementsOwnerFormattingContext\n implements RepetitiveElement.RepetitiveElementsOwnerFormattingContext {\n formattingContextType: FormattingContextType = \"RepetitiveElementsOwner\";\n isRoot: boolean = false;\n repetitiveElements: RepetitiveElement.RepetitiveElements = null;\n\n constructor(\n public readonly parent: Vtree.FormattingContext,\n public readonly rootSourceNode: Element,\n ) {}\n\n /**\n * @override\n */\n getName(): string {\n return \"Repetitive elements owner formatting context (RepetitiveElementsOwnerFormattingContext)\";\n }\n\n /**\n * @override\n */\n isFirstTime(nodeContext: Vtree.NodeContext, firstTime: boolean): boolean {\n return firstTime;\n }\n\n /**\n * @override\n */\n getParent(): Vtree.FormattingContext {\n return this.parent;\n }\n\n getRepetitiveElements(): RepetitiveElement.RepetitiveElements {\n return this.repetitiveElements;\n }\n\n getRootViewNode(position: Vtree.NodeContext): Element | null {\n const root = this.getRootNodeContext(position);\n return root ? (root.viewNode as Element) : null;\n }\n\n getRootNodeContext(nodeContext: Vtree.NodeContext): Vtree.NodeContext | null {\n do {\n if (\n !nodeContext.belongsTo(this) &&\n nodeContext.sourceNode === this.rootSourceNode\n ) {\n return nodeContext;\n }\n } while ((nodeContext = nodeContext.parent));\n return null;\n }\n\n initializeRepetitiveElements(vertical: boolean) {\n if (this.repetitiveElements) {\n return;\n }\n const found = Shared.repetitiveElementsCache.some((entry) => {\n if (entry.root === this.rootSourceNode) {\n this.repetitiveElements = entry.elements;\n return true;\n }\n return false;\n });\n if (!found) {\n this.repetitiveElements = new RepetitiveElements(\n vertical,\n this.rootSourceNode,\n );\n Shared.repetitiveElementsCache.push({\n root: this.rootSourceNode,\n elements: this.repetitiveElements,\n });\n }\n }\n\n /** @override */\n saveState(): any {}\n\n /** @override */\n restoreState(state: any) {}\n}\n\nexport type ElementsOffset = RepetitiveElement.ElementsOffset;\n\nexport class RepetitiveElements\n implements RepetitiveElement.RepetitiveElements {\n private headerSourceNode: Element | null = null;\n private footerSourceNode: Element | null = null;\n private headerViewNode: Element | null = null;\n private footerViewNode: Element | null = null;\n private headerNodePosition: Vtree.NodePosition | null = null;\n private footerNodePosition: Vtree.NodePosition | null = null;\n private headerHeight: number = 0;\n private footerHeight: number = 0;\n isSkipHeader: boolean = false;\n isSkipFooter: boolean = false;\n enableSkippingFooter: boolean = true;\n enableSkippingHeader: boolean = true;\n doneInitialLayout: boolean = false;\n firstContentSourceNode: Element | null = null;\n lastContentSourceNode: Element | null = null;\n private affectedNodeCache: {\n nodeContext: Vtree.NodeContext;\n result: boolean;\n }[] = [];\n private afterLastContentNodeCache: {\n nodeContext: Vtree.NodeContext;\n result: boolean;\n }[] = [];\n allowInsert: boolean = false;\n allowInsertRepeatitiveElements: boolean;\n\n constructor(\n private readonly vertical: boolean,\n public ownerSourceNode: Element,\n ) {}\n\n setHeaderNodeContext(nodeContext: Vtree.NodeContext) {\n if (this.headerNodePosition) {\n return; // use first one.\n }\n this.headerNodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nodeContext,\n 0,\n );\n this.headerSourceNode = nodeContext.sourceNode as Element;\n this.headerViewNode = nodeContext.viewNode as Element;\n }\n\n setFooterNodeContext(nodeContext: Vtree.NodeContext) {\n if (this.footerNodePosition) {\n return; // use first one.\n }\n this.footerNodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nodeContext,\n 0,\n );\n this.footerSourceNode = nodeContext.sourceNode as Element;\n this.footerViewNode = nodeContext.viewNode as Element;\n }\n\n updateHeight(column: LayoutType.Column) {\n if (this.headerViewNode) {\n this.headerHeight = LayoutHelper.getElementHeight(\n this.headerViewNode,\n column,\n this.vertical,\n );\n this.headerViewNode = null;\n }\n if (this.footerViewNode) {\n this.footerHeight = LayoutHelper.getElementHeight(\n this.footerViewNode,\n column,\n this.vertical,\n );\n this.footerViewNode = null;\n }\n }\n\n prepareLayoutFragment() {\n this.isSkipHeader = this.isSkipFooter = false;\n this.enableSkippingFooter = true;\n this.enableSkippingHeader = true;\n }\n\n appendHeaderToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n if (!this.headerNodePosition || this.isSkipHeader) {\n return Task.newResult(true);\n }\n return this.appendElementToFragment(\n this.headerNodePosition,\n rootNodeContext,\n firstChild,\n column,\n );\n }\n\n appendFooterToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n if (!this.footerNodePosition || this.isSkipFooter) {\n return Task.newResult(true);\n }\n return this.appendElementToFragment(\n this.footerNodePosition,\n rootNodeContext,\n firstChild,\n column,\n );\n }\n\n /**\n * @return\n */\n appendElementToFragment(\n nodePosition: Vtree.NodePosition,\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n const doc = rootNodeContext.viewNode.ownerDocument;\n const rootViewNode = rootNodeContext.viewNode as Element;\n const viewRoot = doc.createElement(\"div\");\n rootViewNode.appendChild(viewRoot);\n const pseudoColumn = new Layout.PseudoColumn(\n column,\n viewRoot,\n rootNodeContext,\n );\n const initialPageBreakType = pseudoColumn.getColumn().pageBreakType;\n pseudoColumn.getColumn().pageBreakType = null;\n this.allowInsertRepeatitiveElements = true;\n return pseudoColumn\n .layout(new VtreeImpl.ChunkPosition(nodePosition), true)\n .thenAsync(() => {\n this.allowInsertRepeatitiveElements = false;\n rootViewNode.removeChild(viewRoot);\n this.moveChildren(viewRoot, rootViewNode, firstChild);\n pseudoColumn.getColumn().pageBreakType = initialPageBreakType;\n return Task.newResult(true);\n });\n }\n\n moveChildren(from: Element, to: Element, firstChild: Node | null) {\n if (!to) {\n return;\n }\n while (from.firstChild) {\n const child = from.firstChild;\n from.removeChild(child);\n (child as Element).setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n if (firstChild) {\n to.insertBefore(child, firstChild);\n } else {\n to.appendChild(child);\n }\n }\n }\n\n /** @override */\n calculateOffset(nodeContext: Vtree.NodeContext): number {\n let offset = 0;\n if (nodeContext && !this.affectTo(nodeContext)) {\n return offset;\n }\n if (\n !this.isSkipFooter ||\n (nodeContext && this.isAfterLastContent(nodeContext))\n ) {\n offset += this.footerHeight;\n }\n if (!this.isSkipHeader) {\n offset += this.headerHeight;\n }\n return offset;\n }\n\n /** @override */\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number {\n let offset = 0;\n if (nodeContext && !this.affectTo(nodeContext)) {\n return offset;\n }\n if (nodeContext && this.isAfterLastContent(nodeContext)) {\n offset += this.footerHeight;\n }\n if (!this.enableSkippingHeader) {\n offset += this.headerHeight;\n }\n return offset;\n }\n\n isAfterLastContent(nodeContext: Vtree.NodeContext): boolean {\n return this.findResultFromCache(\n nodeContext,\n this.afterLastContentNodeCache,\n (nc) =>\n this.isAfterNodeContextOf(\n this.lastContentSourceNode as Element,\n nodeContext,\n false,\n ),\n );\n }\n\n private affectTo(nodeContext: Vtree.NodeContext): boolean {\n return this.findResultFromCache(nodeContext, this.affectedNodeCache, (nc) =>\n this.isAfterNodeContextOf(this.ownerSourceNode, nodeContext, true),\n );\n }\n\n private findResultFromCache(\n nodeContext: Vtree.NodeContext,\n cache: { nodeContext: Vtree.NodeContext; result: boolean }[],\n calculator: (p1: Vtree.NodeContext) => boolean,\n ): boolean {\n const cacheEntry = cache.filter(\n (cache) =>\n cache.nodeContext.sourceNode === nodeContext.sourceNode &&\n cache.nodeContext.after === nodeContext.after,\n );\n if (cacheEntry.length > 0) {\n return cacheEntry[0].result;\n } else {\n const result = calculator(nodeContext);\n cache.push({ nodeContext, result });\n return result;\n }\n }\n\n private isAfterNodeContextOf(\n node: Element,\n nodeContext: Vtree.NodeContext,\n includeChildren: boolean,\n ): boolean {\n const parentsOfNode = [];\n for (let n: Node | null = node; n; n = n.parentNode) {\n if (nodeContext.sourceNode === n) {\n return nodeContext.after;\n } else {\n parentsOfNode.push(n);\n }\n }\n for (\n let currentParent: Node | null = nodeContext.sourceNode;\n currentParent;\n currentParent = currentParent.parentNode\n ) {\n const index = parentsOfNode.indexOf(currentParent);\n if (index >= 0) {\n return includeChildren ? index === 0 : false;\n } else {\n for (\n let current: Element | null = currentParent as Element;\n current;\n current = current.previousElementSibling\n ) {\n if (parentsOfNode.includes(current)) {\n return true;\n }\n }\n }\n }\n return nodeContext.after;\n }\n\n isFirstContentNode(nodeContext: Vtree.NodeContext): boolean {\n return (\n nodeContext && this.firstContentSourceNode === nodeContext.sourceNode\n );\n }\n\n isEnableToUpdateState(): boolean {\n if (\n (!this.isSkipFooter &&\n this.enableSkippingFooter &&\n this.footerNodePosition) ||\n (!this.isSkipHeader &&\n this.enableSkippingHeader &&\n this.headerNodePosition)\n ) {\n return true;\n } else {\n return false;\n }\n }\n\n updateState() {\n if (\n !this.isSkipFooter &&\n this.enableSkippingFooter &&\n this.footerNodePosition\n ) {\n this.isSkipFooter = true;\n } else if (\n !this.isSkipHeader &&\n this.enableSkippingHeader &&\n this.headerNodePosition\n ) {\n this.isSkipHeader = true;\n }\n }\n\n preventSkippingHeader() {\n this.isSkipHeader = false;\n this.enableSkippingHeader = false;\n }\n\n preventSkippingFooter() {\n this.isSkipFooter = false;\n this.enableSkippingFooter = false;\n }\n\n isHeaderRegistered(): boolean {\n return !!this.headerNodePosition;\n }\n\n isFooterRegistered(): boolean {\n return !!this.footerNodePosition;\n }\n\n isHeaderSourceNode(node: Node): boolean {\n return this.headerSourceNode === node;\n }\n\n isFooterSourceNode(node: Node): boolean {\n return this.footerSourceNode === node;\n }\n}\n\n/**\n * @abstract\n */\nexport abstract class LayoutEntireBlock implements LayoutType.LayoutMode {\n constructor(\n public formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n ) {}\n\n /**\n * @override\n */\n abstract doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: LayoutType.Column): boolean {\n return !!nodeContext;\n }\n\n /**\n * @override\n */\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: LayoutType.Column,\n accepted: boolean,\n ): boolean {\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n if (repetitiveElements) {\n Asserts.assert(column.clientLayout);\n if (!repetitiveElements.doneInitialLayout) {\n repetitiveElements.updateHeight(column);\n repetitiveElements.doneInitialLayout = true;\n }\n }\n return accepted;\n }\n}\n\n/**\n * @abstract\n */\nexport abstract class LayoutFragmentedBlock implements LayoutType.LayoutMode {\n constructor(\n public formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n ) {}\n\n /**\n * @override\n */\n abstract doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: LayoutType.Column): boolean {\n return true;\n }\n\n /**\n * @override\n */\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: LayoutType.Column,\n accepted: boolean,\n ): boolean {\n return accepted;\n }\n}\n\nexport class LayoutEntireOwnerBlock extends LayoutEntireBlock {\n constructor(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n public readonly processor: RepetitiveElementsOwnerLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n // FIXME: LayoutEntireBlock.prototype.doLayout is undefined because it's abstract method.\n // Probably, removing this call is ok.\n // LayoutEntireBlock.prototype.doLayout.call(this, nodeContext, column);\n return this.processor.doInitialLayout(nodeContext, column);\n }\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: LayoutType.Column): boolean {\n return false;\n }\n}\n\nexport class LayoutFragmentedOwnerBlock extends LayoutFragmentedBlock {\n constructor(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n public readonly processor: RepetitiveElementsOwnerLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n if (!nodeContext.belongsTo(this.formattingContext) && !nodeContext.after) {\n column.fragmentLayoutConstraints.unshift(\n new RepetitiveElementsOwnerLayoutConstraint(nodeContext),\n );\n }\n return this.processor.doLayout(nodeContext, column);\n }\n}\n\nexport class RepetitiveElementsOwnerLayoutConstraint\n implements RepetitiveElement.RepetitiveElementsOwnerLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType =\n \"RepetitiveElementsOwner\";\n nodeContext: Vtree.NodeContext;\n\n constructor(nodeContext: Vtree.NodeContext) {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n this.nodeContext = formattingContext.getRootNodeContext(nodeContext);\n }\n\n /** @override */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): boolean {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return true;\n }\n if (LayoutHelper.isOrphan(this.nodeContext.viewNode)) {\n return true;\n }\n if (!repetitiveElements.isEnableToUpdateState()) {\n return true;\n }\n if (\n (overflownNodeContext && !nodeContext) ||\n (nodeContext && nodeContext.overflow)\n ) {\n return false;\n } else {\n return true;\n }\n }\n\n /** @override */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return false;\n }\n if (repetitiveElements.isEnableToUpdateState()) {\n repetitiveElements.updateState();\n return true;\n } else {\n return false;\n }\n }\n\n /** @override */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: LayoutType.Column,\n ) {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return;\n }\n if (allowed) {\n if (column.stopAtOverflow) {\n if (\n positionAfter == null ||\n repetitiveElements.isAfterLastContent(positionAfter)\n ) {\n repetitiveElements.preventSkippingFooter();\n }\n }\n }\n }\n\n /** @override */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n this.nodeContext.formattingContext,\n );\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return Task.newResult(true);\n }\n const rootNodeContext = this.nodeContext;\n return appendHeader(formattingContext, rootNodeContext, column).thenAsync(\n () =>\n appendFooter(formattingContext, rootNodeContext, column).thenAsync(\n () => {\n repetitiveElements.prepareLayoutFragment();\n return Task.newResult(true);\n },\n ),\n );\n }\n\n getRepetitiveElements(): RepetitiveElement.RepetitiveElements {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n this.nodeContext.formattingContext,\n );\n return formattingContext.getRepetitiveElements();\n }\n\n /** @override */\n equalsTo(constraint: LayoutType.FragmentLayoutConstraint): boolean {\n if (!(constraint instanceof RepetitiveElementsOwnerLayoutConstraint)) {\n return false;\n }\n return (\n getRepetitiveElementsOwnerFormattingContext(\n this.nodeContext.formattingContext,\n ) ===\n getRepetitiveElementsOwnerFormattingContext(\n constraint.nodeContext.formattingContext,\n )\n );\n }\n\n /** @override */\n getPriorityOfFinishBreak(): number {\n return 10;\n }\n}\n\nexport class RepetitiveElementsOwnerLayoutRetryer extends LayoutRetryers.AbstractLayoutRetryer {\n constructor(\n public readonly formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n private readonly processor: RepetitiveElementsOwnerLayoutProcessor,\n ) {\n super();\n }\n\n /**\n * @override\n */\n resolveLayoutMode(nodeContext: Vtree.NodeContext): LayoutType.LayoutMode {\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n if (\n !nodeContext.belongsTo(this.formattingContext) &&\n !repetitiveElements.doneInitialLayout\n ) {\n return new LayoutEntireOwnerBlock(this.formattingContext, this.processor);\n } else {\n if (\n !nodeContext.belongsTo(this.formattingContext) &&\n !nodeContext.after\n ) {\n if (repetitiveElements) {\n repetitiveElements.preventSkippingHeader();\n }\n }\n return new LayoutFragmentedOwnerBlock(\n this.formattingContext,\n this.processor,\n );\n }\n }\n}\n\nexport class EntireBlockLayoutStrategy extends LayoutUtil.EdgeSkipper {\n constructor(\n public readonly formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n public readonly column: LayoutType.Column,\n ) {\n super();\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const nodeContext = state.nodeContext;\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (\n nodeContext.parent &&\n formattingContext.rootSourceNode === nodeContext.parent.sourceNode\n ) {\n switch (nodeContext.repeatOnBreak) {\n case \"header\":\n if (!repetitiveElements.isHeaderRegistered()) {\n repetitiveElements.setHeaderNodeContext(nodeContext);\n return Task.newResult(true);\n } else {\n nodeContext.repeatOnBreak = \"none\";\n }\n break;\n case \"footer\":\n if (!repetitiveElements.isFooterRegistered()) {\n repetitiveElements.setFooterNodeContext(nodeContext);\n return Task.newResult(true);\n } else {\n nodeContext.repeatOnBreak = \"none\";\n }\n break;\n }\n if (!repetitiveElements.firstContentSourceNode) {\n repetitiveElements.firstContentSourceNode = nodeContext.sourceNode as Element;\n }\n }\n return LayoutUtil.EdgeSkipper.prototype.startNonInlineElementNode.call(\n this,\n state,\n );\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const nodeContext = state.nodeContext;\n if (nodeContext.sourceNode === formattingContext.rootSourceNode) {\n formattingContext.getRepetitiveElements().lastContentSourceNode =\n state.lastAfterNodeContext &&\n (state.lastAfterNodeContext.sourceNode as Element);\n state.break = true;\n }\n if (\n nodeContext.repeatOnBreak === \"header\" ||\n nodeContext.repeatOnBreak === \"footer\"\n ) {\n return Task.newResult(true);\n } else {\n return LayoutUtil.EdgeSkipper.prototype.afterNonInlineElementNode.call(\n this,\n state,\n );\n }\n }\n}\n\nexport class FragmentedBlockLayoutStrategy extends LayoutUtil.EdgeSkipper {\n constructor(\n public readonly formattingContext: RepetitiveElementsOwnerFormattingContext,\n public readonly column: LayoutType.Column,\n ) {\n super();\n }\n}\n\nexport class RepetitiveElementsOwnerLayoutProcessor\n extends LayoutProcessor.BlockLayoutProcessor\n implements LayoutProcessor.LayoutProcessor {\n layout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext> {\n if (column.isFloatNodeContext(nodeContext)) {\n return column.layoutFloatOrFootnote(nodeContext);\n }\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const rootViewNode = formattingContext.getRootViewNode(nodeContext);\n if (!rootViewNode) {\n return column.buildDeepElementView(nodeContext);\n } else {\n if (leadingEdge) {\n appendHeaderToAncestors(nodeContext.parent, column);\n }\n if (!nodeContext.belongsTo(formattingContext)) {\n return new RepetitiveElementsOwnerLayoutRetryer(\n formattingContext,\n this,\n ).layout(nodeContext, column);\n } else {\n return LayoutProcessor.BlockLayoutProcessor.prototype.layout.call(\n this,\n nodeContext,\n column,\n leadingEdge,\n );\n }\n }\n }\n\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean {\n const formattingContext = getRepetitiveElementsOwnerFormattingContextOrNull(\n nodeContext,\n );\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (!repetitiveElements) {\n return false;\n }\n if (\n !repetitiveElements.allowInsertRepeatitiveElements &&\n (repetitiveElements.isHeaderSourceNode(nodeContext.sourceNode) ||\n repetitiveElements.isFooterSourceNode(nodeContext.sourceNode))\n ) {\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n }\n return false;\n }\n\n doInitialLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"BlockLayoutProcessor.doInitialLayout\",\n );\n this.layoutEntireBlock(nodeContext, column).thenFinish(frame);\n return frame.result();\n }\n\n private layoutEntireBlock(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const strategy = new EntireBlockLayoutStrategy(formattingContext, column);\n const iterator = new LayoutUtil.LayoutIterator(\n strategy,\n column.layoutContext,\n );\n return iterator.iterate(nodeContext);\n }\n\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"doLayout\");\n const cont = column.layoutContext.nextInTree(nodeContext, false);\n Layout.processAfterIfContinues(cont, column).then((resNodeContext) => {\n let nextNodeContext = resNodeContext;\n frame\n .loopWithFrame((loopFrame) => {\n while (nextNodeContext) {\n let pending = true;\n column\n .layoutNext(nextNodeContext, false)\n .then((nodeContextParam) => {\n nextNodeContext = nodeContextParam;\n if (column.pageFloatLayoutContext.isInvalidated()) {\n loopFrame.breakLoop();\n } else if (column.pageBreakType) {\n loopFrame.breakLoop(); // Loop end\n } else if (\n nextNodeContext &&\n column.stopByOverflow(nextNodeContext)\n ) {\n loopFrame.breakLoop(); // Loop end\n } else if (\n nextNodeContext &&\n nextNodeContext.after &&\n nextNodeContext.sourceNode == formattingContext.rootSourceNode\n ) {\n loopFrame.breakLoop(); // Loop end\n } else {\n if (pending) {\n // Sync case\n pending = false;\n } else {\n // Async case\n loopFrame.continueLoop();\n }\n }\n });\n if (pending) {\n // Async case and loop end\n pending = false;\n return;\n }\n }\n\n // Sync case\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(nextNodeContext);\n });\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n finishBreak(\n column: LayoutType.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> | null {\n return LayoutProcessor.BlockLayoutProcessor.prototype.finishBreak.call(\n this,\n column,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n }\n\n /**\n * @override\n */\n clearOverflownViewNodes(\n column: LayoutType.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ) {\n LayoutProcessor.BlockLayoutProcessor.prototype.clearOverflownViewNodes(\n column,\n parentNodeContext,\n nodeContext,\n removeSelf,\n );\n }\n}\n\nfunction eachAncestorNodeContext(\n nodeContext: Vtree.NodeContext,\n callback: (\n p1: RepetitiveElementsOwnerFormattingContext,\n p2: Vtree.NodeContext,\n ) => any,\n): void {\n for (let nc = nodeContext; nc; nc = nc.parent) {\n const formattingContext = nc.formattingContext;\n if (\n formattingContext &&\n formattingContext instanceof RepetitiveElementsOwnerFormattingContext &&\n !nc.belongsTo(formattingContext)\n ) {\n callback(formattingContext, nc);\n }\n }\n}\n\nexport function appendHeaderToAncestors(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n): void {\n if (!nodeContext) {\n return;\n }\n eachAncestorNodeContext(\n nodeContext.after ? nodeContext.parent : nodeContext,\n (formattingContext, nc) => {\n if (Table.isInstanceOfTableFormattingContext(formattingContext)) {\n return;\n }\n column.fragmentLayoutConstraints.push(\n new RepetitiveElementsOwnerLayoutConstraint(nc),\n );\n },\n );\n}\n\nexport function appendHeader(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n): Task.Result<boolean> {\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (repetitiveElements) {\n const rootNodeContext = formattingContext.getRootNodeContext(nodeContext);\n if (rootNodeContext.viewNode) {\n const firstChild = rootNodeContext.viewNode.firstChild;\n return repetitiveElements.appendHeaderToFragment(\n rootNodeContext,\n firstChild,\n column,\n );\n }\n }\n return Task.newResult(true);\n}\n\nexport function appendFooter(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n): Task.Result<boolean> {\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (repetitiveElements) {\n if (!repetitiveElements.isSkipFooter) {\n const rootNodeContext = formattingContext.getRootNodeContext(nodeContext);\n if (rootNodeContext.viewNode) {\n return repetitiveElements.appendFooterToFragment(\n rootNodeContext,\n null,\n column,\n );\n }\n }\n }\n return Task.newResult(true);\n}\n\nfunction getRepetitiveElementsOwnerFormattingContextOrNull(\n nodeContext: Vtree.NodeContext,\n): RepetitiveElement.RepetitiveElementsOwnerFormattingContext | null {\n const formattingContext = nodeContext.formattingContext;\n if (!formattingContext) {\n return null;\n }\n if (\n !(formattingContext instanceof RepetitiveElementsOwnerFormattingContext)\n ) {\n return null;\n }\n return formattingContext;\n}\n\nfunction getRepetitiveElementsOwnerFormattingContext(\n formattingContext: Vtree.FormattingContext,\n): RepetitiveElement.RepetitiveElementsOwnerFormattingContext {\n Asserts.assert(\n formattingContext instanceof RepetitiveElementsOwnerFormattingContext,\n );\n return formattingContext as RepetitiveElement.RepetitiveElementsOwnerFormattingContext;\n}\n\nconst repetitiveLayoutProcessor = new RepetitiveElementsOwnerLayoutProcessor();\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n (formattingContext) => {\n if (\n formattingContext instanceof RepetitiveElementsOwnerFormattingContext &&\n !Table.isInstanceOfTableFormattingContext(formattingContext)\n ) {\n return repetitiveLayoutProcessor;\n }\n return null;\n },\n);\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Table - Table formatting context and layout.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as BreakPosition from \"./break-position\";\nimport * as Css from \"./css\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as LayoutRetryers from \"./layout-retryers\";\nimport * as LayoutUtil from \"./layout-util\";\nimport * as Plugin from \"./plugin\";\nimport * as RepetitiveElementImpl from \"./repetitive-element\";\nimport * as Task from \"./task\";\nimport * as Vgen from \"./vgen\";\nimport * as VtreeImpl from \"./vtree\";\nimport * as Layout from \"./layout\";\nimport {\n FormattingContextType,\n FragmentLayoutConstraintType,\n Layout as LayoutType,\n RepetitiveElement,\n Table,\n Vtree,\n} from \"./types\";\n\nexport class TableRow {\n cells: TableCell[] = [];\n\n constructor(\n public readonly rowIndex: number,\n public readonly sourceNode: Node,\n ) {}\n\n addCell(cell: TableCell) {\n this.cells.push(cell);\n }\n\n getMinimumHeight(): number {\n return Math.min.apply(\n null,\n this.cells.map((c) => c.height),\n );\n }\n}\n\nexport class TableCell {\n viewElement: Element | null;\n colSpan: number;\n rowSpan: number;\n height: number = 0;\n anchorSlot: TableSlot = null;\n\n constructor(\n public readonly rowIndex: number,\n public readonly columnIndex: number,\n viewElement: Element,\n ) {\n this.viewElement = viewElement;\n this.colSpan = (viewElement as HTMLTableCellElement).colSpan || 1;\n this.rowSpan = (viewElement as HTMLTableCellElement).rowSpan || 1;\n }\n\n setHeight(height: number) {\n this.height = height;\n }\n\n setAnchorSlot(slot: TableSlot) {\n this.anchorSlot = slot;\n }\n}\n\nexport class TableSlot {\n constructor(\n public readonly rowIndex: number,\n public readonly columnIndex: number,\n public readonly cell: TableCell,\n ) {}\n}\n\nexport class TableCellFragment {\n pseudoColumn: Layout.PseudoColumn;\n empty: boolean = false;\n\n constructor(\n public readonly column: Layout.Column,\n pseudoColumnContainer: Element,\n public readonly cellNodeContext: Vtree.NodeContext,\n ) {\n this.pseudoColumn = new Layout.PseudoColumn(\n column,\n pseudoColumnContainer,\n cellNodeContext,\n );\n }\n\n findAcceptableBreakPosition(): Layout.BreakPositionAndNodeContext {\n const element = this.cellNodeContext.viewNode as Element;\n const verticalAlign = this.cellNodeContext.verticalAlign;\n if (verticalAlign === \"middle\" || verticalAlign === \"bottom\") {\n Base.setCSSProperty(element, \"vertical-align\", \"top\");\n }\n const bp = this.pseudoColumn.findAcceptableBreakPosition(true);\n Base.setCSSProperty(element, \"vertical-align\", verticalAlign);\n return bp;\n }\n}\n\nexport class TableCaptionView {\n constructor(\n public readonly viewNode: Element,\n public readonly side: string,\n ) {}\n}\n\nexport class BetweenTableRowBreakPosition extends BreakPosition.EdgeBreakPosition {\n private formattingContext: TableFormattingContext;\n\n acceptableCellBreakPositions: Layout.BreakPositionAndNodeContext[] = null;\n private rowIndex: number | null = null;\n\n constructor(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ) {\n super(position, breakOnEdge, overflows, columnBlockSize);\n this.formattingContext = position.formattingContext as TableFormattingContext;\n }\n\n /**\n * @override\n */\n findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext {\n const breakNodeContext = super.findAcceptableBreak(column, penalty);\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n const allCellsBreakable = this.getAcceptableCellBreakPositions().every(\n (bp) => !!bp.nodeContext,\n );\n if (allCellsBreakable) {\n return breakNodeContext;\n } else {\n return null;\n }\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n let penalty = super.getMinBreakPenalty();\n this.getAcceptableCellBreakPositions().forEach((bp) => {\n penalty += bp.breakPosition.getMinBreakPenalty();\n });\n return penalty;\n }\n\n getAcceptableCellBreakPositions(): Layout.BreakPositionAndNodeContext[] {\n if (!this.acceptableCellBreakPositions) {\n const formattingContext = this.formattingContext;\n const cellFragments = this.getCellFragments();\n this.acceptableCellBreakPositions = cellFragments.map((cellFragment) =>\n cellFragment.findAcceptableBreakPosition(),\n );\n }\n return this.acceptableCellBreakPositions;\n }\n\n private getRowIndex(): number {\n if (this.rowIndex != null) {\n return this.rowIndex;\n }\n return (this.rowIndex = this.formattingContext.findRowIndexBySourceNode(\n this.position.sourceNode,\n ));\n }\n\n private getCellFragments() {\n return this.formattingContext\n .getRowSpanningCellsOverflowingTheRow(this.getRowIndex())\n .map(\n this.formattingContext.getCellFragmentOfCell,\n this.formattingContext,\n );\n }\n}\n\nexport class InsideTableRowBreakPosition extends BreakPosition.AbstractBreakPosition {\n acceptableCellBreakPositions: Layout.BreakPositionAndNodeContext[] = null;\n\n constructor(\n public readonly rowIndex: number,\n public readonly beforeNodeContext: Vtree.NodeContext,\n public readonly formattingContext: TableFormattingContext,\n ) {\n super();\n }\n\n /**\n * @override\n */\n findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext {\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n const cellFragments = this.getCellFragments();\n const acceptableCellBreakPositions = this.getAcceptableCellBreakPositions();\n const allCellsBreakable =\n acceptableCellBreakPositions.every((bp) => !!bp.nodeContext) &&\n acceptableCellBreakPositions.some((bp, index) => {\n const pseudoColumn = cellFragments[index].pseudoColumn;\n const nodeContext = bp.nodeContext;\n return (\n !pseudoColumn.isStartNodeContext(nodeContext) &&\n !pseudoColumn.isLastAfterNodeContext(nodeContext)\n );\n });\n this.beforeNodeContext.overflow = acceptableCellBreakPositions.some(\n (bp) => bp.nodeContext && bp.nodeContext.overflow,\n );\n if (allCellsBreakable) {\n return this.beforeNodeContext;\n } else {\n return null;\n }\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n const formattingContext = this.formattingContext;\n const row = formattingContext.getRowByIndex(this.rowIndex);\n let penalty = 0;\n if (!formattingContext.isFreelyFragmentableRow(row)) {\n penalty += 10;\n }\n this.getAcceptableCellBreakPositions().forEach((bp) => {\n penalty += bp.breakPosition.getMinBreakPenalty();\n });\n return penalty;\n }\n\n getAcceptableCellBreakPositions(): Layout.BreakPositionAndNodeContext[] {\n if (!this.acceptableCellBreakPositions) {\n const cellFragments = this.getCellFragments();\n this.acceptableCellBreakPositions = cellFragments.map((cellFragment) =>\n cellFragment.findAcceptableBreakPosition(),\n );\n }\n return this.acceptableCellBreakPositions;\n }\n\n private getCellFragments() {\n return this.formattingContext\n .getCellsFallingOnRow(this.rowIndex)\n .map(\n this.formattingContext.getCellFragmentOfCell,\n this.formattingContext,\n );\n }\n}\n\nexport type BrokenTableCellPosition = {\n cellNodePosition: Vtree.NodePosition;\n breakChunkPosition: Vtree.ChunkPosition;\n cell: TableCell;\n};\n\n/**\n * @param tableSourceNode Source node of the table\n */\nexport class TableFormattingContext\n extends RepetitiveElementImpl.RepetitiveElementsOwnerFormattingContext\n implements Table.TableFormattingContext {\n formattingContextType: FormattingContextType = \"Table\";\n vertical: boolean = false;\n columnCount: number = -1;\n tableWidth: number = 0;\n captions: TableCaptionView[] = [];\n colGroups: DocumentFragment | null = null;\n colWidths: number[] | null = null;\n inlineBorderSpacing: number = 0;\n rows: TableRow[] = [];\n slots: TableSlot[][] = [];\n cellFragments: TableCellFragment[][] = [];\n lastRowViewNode: Element | null = null;\n cellBreakPositions: BrokenTableCellPosition[] = [];\n repetitiveElements: RepetitiveElement.RepetitiveElements | null = null;\n\n constructor(\n parent: Vtree.FormattingContext,\n public readonly tableSourceNode: Element,\n ) {\n super(parent, tableSourceNode);\n }\n\n /**\n * @override\n */\n getName(): string {\n return \"Table formatting context (Table.TableFormattingContext)\";\n }\n\n /**\n * @override\n */\n isFirstTime(nodeContext: Vtree.NodeContext, firstTime: boolean): boolean {\n if (!firstTime) {\n return firstTime;\n }\n switch (nodeContext.display) {\n case \"table-row\":\n return this.cellBreakPositions.length === 0;\n case \"table-cell\":\n return !this.cellBreakPositions.some(\n (p) => p.cellNodePosition.steps[0].node === nodeContext.sourceNode,\n );\n default:\n return firstTime;\n }\n }\n\n /**\n * @override\n */\n getParent(): Vtree.FormattingContext {\n return this.parent;\n }\n\n finishFragment() {\n this.cellFragments = [];\n }\n\n addRow(rowIndex: number, row: TableRow) {\n this.rows[rowIndex] = row;\n }\n\n getRowSlots(rowIndex: number): TableSlot[] {\n let rowSlots = this.slots[rowIndex];\n if (!rowSlots) {\n rowSlots = this.slots[rowIndex] = [];\n }\n return rowSlots;\n }\n\n addCell(rowIndex: number, cell: TableCell) {\n let row = this.rows[rowIndex];\n if (!row) {\n this.addRow(rowIndex, new TableRow(rowIndex, null));\n row = this.rows[rowIndex];\n }\n Asserts.assert(row);\n row.addCell(cell);\n const rowUpper = rowIndex + cell.rowSpan;\n let rowSlots = this.getRowSlots(rowIndex);\n let startColIndex = 0;\n while (rowSlots[startColIndex]) {\n startColIndex++;\n }\n for (; rowIndex < rowUpper; rowIndex++) {\n rowSlots = this.getRowSlots(rowIndex);\n for (let i = startColIndex; i < startColIndex + cell.colSpan; i++) {\n const slot = (rowSlots[i] = new TableSlot(rowIndex, i, cell));\n if (!cell.anchorSlot) {\n cell.setAnchorSlot(slot);\n }\n }\n }\n }\n\n getRowByIndex(index: number): TableRow {\n const row = this.rows[index];\n Asserts.assert(row);\n return row;\n }\n\n findRowIndexBySourceNode(sourceNode: Node): number {\n return this.rows.findIndex((row) => sourceNode === row.sourceNode);\n }\n\n addCellFragment(\n rowIndex: number,\n columnIndex: number,\n cellFragment: TableCellFragment,\n ) {\n let list = this.cellFragments[rowIndex];\n if (!list) {\n list = this.cellFragments[rowIndex] = [];\n }\n list[columnIndex] = cellFragment;\n }\n\n getCellsFallingOnRow(rowIndex: number): TableCell[] {\n const rowSlots = this.getRowSlots(rowIndex);\n return rowSlots.reduce((uniqueCells, slot) => {\n if (slot.cell !== uniqueCells[uniqueCells.length - 1]) {\n return uniqueCells.concat(slot.cell);\n } else {\n return uniqueCells;\n }\n }, []);\n }\n\n getRowSpanningCellsOverflowingTheRow(rowIndex: number): TableCell[] {\n return this.getCellsFallingOnRow(rowIndex).filter(\n (cell) => cell.rowIndex + cell.rowSpan - 1 > rowIndex,\n );\n }\n\n getCellFragmentOfCell(cell: TableCell): TableCellFragment {\n return (\n this.cellFragments[cell.rowIndex] &&\n this.cellFragments[cell.rowIndex][cell.columnIndex]\n );\n }\n\n isFreelyFragmentableRow(row: TableRow): boolean {\n return row.getMinimumHeight() > this.tableWidth / 2;\n }\n\n getColumnCount(): number {\n if (this.columnCount < 0) {\n this.columnCount = Math.max.apply(\n null,\n this.rows.map((row) =>\n row.cells.reduce((sum, c) => sum + c.colSpan, 0),\n ),\n );\n }\n return this.columnCount;\n }\n\n updateCellSizes(clientLayout: Vtree.ClientLayout) {\n this.rows.forEach((row) => {\n row.cells.forEach((cell) => {\n const rect = clientLayout.getElementClientRect(\n cell.viewElement as Element,\n );\n cell.viewElement = null;\n cell.setHeight(this.vertical ? rect[\"width\"] : rect[\"height\"]);\n });\n });\n }\n\n /**\n * @return position\n */\n findCellFromColumn(\n column: Layout.Column,\n ): { rowIndex: number; columnIndex: number } | null {\n if (!column) {\n return null;\n }\n let tableCell: TableCell = null;\n let row = 0;\n let col = 0;\n loop: for (row = 0; row < this.cellFragments.length; row++) {\n if (!this.cellFragments[row]) {\n continue;\n }\n for (col = 0; col < this.cellFragments[row].length; col++) {\n if (!this.cellFragments[row][col]) {\n continue;\n }\n if (column === this.cellFragments[row][col].pseudoColumn.getColumn()) {\n tableCell = this.rows[row].cells[col];\n break loop;\n }\n }\n }\n if (!tableCell) {\n return null;\n }\n for (; row < this.slots.length; row++) {\n for (; col < this.slots[row].length; col++) {\n const slot = this.slots[row][col];\n if (slot.cell === tableCell) {\n return { rowIndex: slot.rowIndex, columnIndex: slot.columnIndex };\n }\n }\n }\n return null;\n }\n\n collectElementsOffsetOfUpperCells(\n position: { rowIndex: number; columnIndex: number } | null,\n ): RepetitiveElement.ElementsOffset[] {\n const collected = [];\n return this.slots.reduce((repetitiveElements, row, index) => {\n if (index >= position.rowIndex) {\n return repetitiveElements;\n }\n const cellFragment = this.getCellFragmentOfCell(\n row[position.columnIndex].cell,\n );\n if (!cellFragment || collected.includes(cellFragment)) {\n return repetitiveElements;\n }\n this.collectElementsOffsetFromColumn(\n cellFragment.pseudoColumn.getColumn(),\n repetitiveElements,\n );\n collected.push(cellFragment);\n return repetitiveElements;\n }, [] as RepetitiveElement.ElementsOffset[]);\n }\n\n collectElementsOffsetOfHighestColumn(): RepetitiveElement.ElementsOffset[] {\n const elementsInColumn = [];\n this.rows.forEach((row) => {\n row.cells.forEach((cell, index) => {\n if (!elementsInColumn[index]) {\n elementsInColumn[index] = { collected: [], elements: [] };\n }\n const state = elementsInColumn[index];\n const cellFragment = this.getCellFragmentOfCell(cell);\n if (!cellFragment || state.collected.includes(cellFragment)) {\n return;\n }\n this.collectElementsOffsetFromColumn(\n cellFragment.pseudoColumn.getColumn(),\n state.elements,\n );\n state.collected.push(cellFragment);\n });\n });\n return [\n new ElementsOffsetOfTableCell(\n elementsInColumn.map((entry) => entry.elements),\n ),\n ];\n }\n\n private collectElementsOffsetFromColumn(\n column: LayoutType.Column,\n repetitiveElements: RepetitiveElement.ElementsOffset[],\n ) {\n column.fragmentLayoutConstraints.forEach((constraint) => {\n if (\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerLayoutConstraint(\n constraint,\n )\n ) {\n const repetitiveElement = constraint.getRepetitiveElements();\n repetitiveElements.push(repetitiveElement);\n }\n if (Table.isInstanceOfTableRowLayoutConstraint(constraint)) {\n constraint\n .getElementsOffsetsForTableCell(null)\n .forEach((repetitiveElement) => {\n repetitiveElements.push(repetitiveElement);\n });\n }\n });\n }\n\n /** @override */\n saveState(): any {\n return [].concat(this.cellBreakPositions);\n }\n\n /** @override */\n restoreState(state: any) {\n this.cellBreakPositions = state as BrokenTableCellPosition[];\n }\n}\n\nexport class ElementsOffsetOfTableCell\n implements RepetitiveElement.ElementsOffset {\n constructor(\n public readonly repeatitiveElementsInColumns: RepetitiveElement.ElementsOffset[][],\n ) {}\n\n /** @override */\n calculateOffset(nodeContext: Vtree.NodeContext): number {\n return this.calculateMaxOffsetOfColumn(\n nodeContext,\n (offsets) => offsets.current,\n );\n }\n\n /** @override */\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number {\n return this.calculateMaxOffsetOfColumn(\n nodeContext,\n (offsets) => offsets.minimum,\n );\n }\n\n private calculateMaxOffsetOfColumn(nodeContext, resolver) {\n let maxOffset = 0;\n this.repeatitiveElementsInColumns.forEach((repetitiveElements) => {\n const offsets = BreakPosition.calculateOffset(\n nodeContext,\n repetitiveElements,\n );\n maxOffset = Math.max(maxOffset, resolver(offsets));\n });\n return maxOffset;\n }\n}\n\nfunction getTableFormattingContext(\n formattingContext: Vtree.FormattingContext,\n): TableFormattingContext {\n Asserts.assert(formattingContext instanceof TableFormattingContext);\n return formattingContext as TableFormattingContext;\n}\n\nfunction isTableRowGrouping(display: string | null): boolean {\n return (\n display === \"table-row-group\" ||\n display === \"table-header-group\" ||\n display === \"table-footer-group\"\n );\n}\n\nfunction isTableRoot(display: string | null): boolean {\n return display === \"table\" || display === \"inline-table\";\n}\n\nfunction isValidParentOfTableRow(display: string | null): boolean {\n return isTableRowGrouping(display) || isTableRoot(display);\n}\n\nfunction skipNestedTable(\n state: LayoutUtil.LayoutIteratorState,\n formattingContext: TableFormattingContext,\n column: Layout.Column,\n): Task.Result<boolean> | null {\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n const parentDisplay = nodeContext.parent ? nodeContext.parent.display : null;\n\n // Is inline-table nested in another table?\n let isNestedInlineTable = false;\n if (\n parentDisplay === \"inline-table\" &&\n !(nodeContext.formattingContext instanceof TableFormattingContext)\n ) {\n for (let nc = nodeContext.parent; nc; nc = nc.parent) {\n if (nc.formattingContext instanceof TableFormattingContext) {\n isNestedInlineTable = nc.formattingContext === formattingContext;\n break;\n }\n }\n }\n const isNestedTable =\n isNestedInlineTable ||\n (display === \"table-row\" && !isValidParentOfTableRow(parentDisplay)) ||\n (display === \"table-cell\" &&\n parentDisplay !== \"table-row\" &&\n !isValidParentOfTableRow(parentDisplay)) ||\n (nodeContext.formattingContext instanceof TableFormattingContext &&\n nodeContext.formattingContext !== formattingContext);\n if (isNestedTable) {\n return column\n .buildDeepElementView(nodeContext)\n .thenAsync((nodeContextAfter) => {\n state.nodeContext = nodeContextAfter;\n return Task.newResult(true);\n });\n } else {\n return null;\n }\n}\n\nexport class EntireTableLayoutStrategy extends LayoutUtil.EdgeSkipper {\n rowIndex: number = -1;\n columnIndex: number = 0;\n inRow: boolean = false;\n checkPoints: Vtree.NodeContext[] = [];\n inHeaderOrFooter: boolean = false;\n\n constructor(\n public readonly formattingContext: TableFormattingContext,\n public readonly column: Layout.Column,\n ) {\n super();\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const r = skipNestedTable(state, formattingContext, this.column);\n if (r) {\n return r;\n }\n this.postLayoutBlockContents(state);\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n const repetitiveElements = formattingContext.getRepetitiveElements();\n switch (display) {\n case \"table\":\n formattingContext.inlineBorderSpacing = nodeContext.inlineBorderSpacing;\n break;\n case \"table-caption\": {\n const captionView = new TableCaptionView(\n nodeContext.viewNode as Element,\n nodeContext.captionSide,\n );\n formattingContext.captions.push(captionView);\n break;\n }\n case \"table-header-group\":\n if (!repetitiveElements.isHeaderRegistered()) {\n this.inHeaderOrFooter = true;\n repetitiveElements.setHeaderNodeContext(nodeContext);\n }\n return Task.newResult(true);\n case \"table-footer-group\":\n if (!repetitiveElements.isFooterRegistered()) {\n this.inHeaderOrFooter = true;\n repetitiveElements.setFooterNodeContext(nodeContext);\n }\n return Task.newResult(true);\n case \"table-row\":\n if (!this.inHeaderOrFooter) {\n this.inRow = true;\n this.rowIndex++;\n Asserts.assert(nodeContext.sourceNode);\n this.columnIndex = 0;\n formattingContext.addRow(\n this.rowIndex,\n new TableRow(this.rowIndex, nodeContext.sourceNode),\n );\n if (!repetitiveElements.firstContentSourceNode) {\n repetitiveElements.firstContentSourceNode = nodeContext.sourceNode as Element;\n }\n }\n break;\n }\n return super.startNonInlineElementNode(state);\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n const clientLayout = this.column.clientLayout;\n this.postLayoutBlockContents(state);\n if (nodeContext.sourceNode === formattingContext.tableSourceNode) {\n const computedStyle = clientLayout.getElementComputedStyle(\n formattingContext.getRootViewNode(nodeContext) as Element,\n );\n formattingContext.tableWidth = parseFloat(\n computedStyle[formattingContext.vertical ? \"height\" : \"width\"],\n );\n formattingContext.getRepetitiveElements().lastContentSourceNode =\n state.lastAfterNodeContext &&\n (state.lastAfterNodeContext.sourceNode as Element);\n state.break = true;\n } else {\n switch (display) {\n case \"table-header-group\":\n case \"table-footer-group\":\n if (this.inHeaderOrFooter) {\n this.inHeaderOrFooter = false;\n return Task.newResult(true);\n }\n break;\n case \"table-row\":\n if (!this.inHeaderOrFooter) {\n formattingContext.lastRowViewNode = nodeContext.viewNode as Element;\n this.inRow = false;\n }\n break;\n case \"table-cell\":\n if (!this.inHeaderOrFooter) {\n if (!this.inRow) {\n this.rowIndex++;\n this.columnIndex = 0;\n this.inRow = true;\n }\n const elem = nodeContext.viewNode as Element;\n formattingContext.addCell(\n this.rowIndex,\n new TableCell(this.rowIndex, this.columnIndex, elem),\n );\n this.columnIndex++;\n }\n break;\n }\n }\n return super.afterNonInlineElementNode(state);\n }\n\n /** @override */\n startNonElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n /** @override */\n afterNonElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n /** @override */\n startInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n /** @override */\n afterInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n registerCheckPoint(state: LayoutUtil.LayoutIteratorState) {\n const nodeContext = state.nodeContext;\n if (\n nodeContext &&\n nodeContext.viewNode &&\n !LayoutHelper.isSpecialNodeContext(nodeContext)\n ) {\n this.checkPoints.push(nodeContext.clone());\n }\n }\n\n postLayoutBlockContents(state: LayoutUtil.LayoutIteratorState) {\n if (this.checkPoints.length > 0) {\n this.column.postLayoutBlock(state.nodeContext, this.checkPoints);\n }\n this.checkPoints = [];\n }\n}\n\nexport class TableLayoutStrategy extends LayoutUtil.EdgeSkipper {\n private static ignoreList: { [key: string]: boolean } = {\n \"table-caption\": true,\n \"table-column-group\": true,\n \"table-column\": true,\n };\n inRow: boolean = false;\n currentRowIndex: number = -1;\n currentColumnIndex: number = 0;\n originalStopAtOverflow: boolean;\n inHeader: boolean;\n inFooter: boolean;\n\n constructor(\n public readonly formattingContext: TableFormattingContext,\n public readonly column: Layout.Column,\n ) {\n super(true);\n this.originalStopAtOverflow = column.stopAtOverflow;\n column.stopAtOverflow = false;\n }\n\n resetColumn() {\n this.column.stopAtOverflow = this.originalStopAtOverflow;\n }\n\n getColSpanningCellWidth(cell: TableCell): number {\n const colWidths = this.formattingContext.colWidths;\n Asserts.assert(colWidths);\n let width = 0;\n for (let i = 0; i < cell.colSpan; i++) {\n width += colWidths[cell.anchorSlot.columnIndex + i];\n }\n width += this.formattingContext.inlineBorderSpacing * (cell.colSpan - 1);\n return width;\n }\n\n layoutCell(\n cell: TableCell,\n cellNodeContext: Vtree.NodeContext,\n startChunkPosition: Vtree.ChunkPosition,\n ): Task.Result<boolean> {\n const rowIndex = cell.rowIndex;\n const columnIndex = cell.columnIndex;\n const colSpan = cell.colSpan;\n const cellViewNode = cellNodeContext.viewNode as Element;\n const verticalAlign = cellNodeContext.verticalAlign;\n if (colSpan > 1) {\n Base.setCSSProperty(cellViewNode, \"box-sizing\", \"border-box\");\n Base.setCSSProperty(\n cellViewNode,\n this.formattingContext.vertical ? \"height\" : \"width\",\n `${this.getColSpanningCellWidth(cell)}px`,\n );\n }\n const pseudoColumnContainer = cellViewNode.ownerDocument.createElement(\n \"div\",\n );\n cellViewNode.appendChild(pseudoColumnContainer);\n const cellFragment = new TableCellFragment(\n this.column,\n pseudoColumnContainer,\n cellNodeContext,\n );\n this.formattingContext.addCellFragment(rowIndex, columnIndex, cellFragment);\n if (\n startChunkPosition.primary.steps.length === 1 &&\n startChunkPosition.primary.after\n ) {\n // Contents of the cell have ended in the previous fragment\n cellFragment.empty = true;\n }\n return cellFragment.pseudoColumn\n .layout(startChunkPosition, true)\n .thenReturn(true);\n }\n\n hasBrokenCellAtSlot(slotIndex): boolean {\n const cellBreakPosition = this.formattingContext.cellBreakPositions[0];\n if (cellBreakPosition) {\n return cellBreakPosition.cell.anchorSlot.columnIndex === slotIndex;\n }\n return false;\n }\n\n private extractRowSpanningCellBreakPositions(): BrokenTableCellPosition[][] {\n const cellBreakPositions = this.formattingContext.cellBreakPositions;\n if (cellBreakPositions.length === 0) {\n return [];\n }\n const rowSpanningCellBreakPositions = [];\n let i = 0;\n do {\n const p = cellBreakPositions[i];\n const rowIndex = p.cell.rowIndex;\n if (rowIndex < this.currentRowIndex) {\n let arr = rowSpanningCellBreakPositions[rowIndex];\n if (!arr) {\n arr = rowSpanningCellBreakPositions[rowIndex] = [];\n }\n arr.push(p);\n cellBreakPositions.splice(i, 1);\n } else {\n i++;\n }\n } while (i < cellBreakPositions.length);\n return rowSpanningCellBreakPositions;\n }\n\n layoutRowSpanningCellsFromPreviousFragment(\n state: LayoutUtil.LayoutIteratorState,\n ): Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const rowSpanningCellBreakPositions = this.extractRowSpanningCellBreakPositions();\n const rowCount = rowSpanningCellBreakPositions.reduce((s) => s + 1, 0);\n if (rowCount === 0) {\n return Task.newResult(true);\n }\n const layoutContext = this.column.layoutContext;\n const currentRow = state.nodeContext;\n currentRow.viewNode.parentNode.removeChild(currentRow.viewNode);\n const frame = Task.newFrame<boolean>(\n \"layoutRowSpanningCellsFromPreviousFragment\",\n );\n let cont = Task.newResult(true);\n let spanningCellRowIndex = 0;\n const occupiedSlotIndices = [];\n rowSpanningCellBreakPositions.forEach((rowCellBreakPositions) => {\n cont = cont.thenAsync(() => {\n // Is it always correct to assume steps[1] to be the row?\n const rowNodeContext = VtreeImpl.makeNodeContextFromNodePositionStep(\n rowCellBreakPositions[0].cellNodePosition.steps[1],\n currentRow.parent,\n );\n return layoutContext.setCurrent(rowNodeContext, false).thenAsync(() => {\n let cont1 = Task.newResult(true);\n let columnIndex = 0;\n\n function addDummyCellUntil(upperColumnIndex) {\n while (columnIndex < upperColumnIndex) {\n if (!occupiedSlotIndices.includes(columnIndex)) {\n const dummy = rowNodeContext.viewNode.ownerDocument.createElement(\n \"td\",\n );\n Base.setCSSProperty(dummy, \"padding\", \"0\");\n rowNodeContext.viewNode.appendChild(dummy);\n }\n columnIndex++;\n }\n }\n rowCellBreakPositions.forEach((cellBreakPosition) => {\n cont1 = cont1.thenAsync(() => {\n const cell = cellBreakPosition.cell;\n addDummyCellUntil(cell.anchorSlot.columnIndex);\n const cellNodePosition = cellBreakPosition.cellNodePosition;\n const cellNodeContext = VtreeImpl.makeNodeContextFromNodePositionStep(\n cellNodePosition.steps[0],\n rowNodeContext,\n );\n cellNodeContext.offsetInNode = cellNodePosition.offsetInNode;\n cellNodeContext.after = cellNodePosition.after;\n cellNodeContext.fragmentIndex =\n cellNodePosition.steps[0].fragmentIndex + 1;\n return layoutContext\n .setCurrent(cellNodeContext, false)\n .thenAsync(() => {\n const breakChunkPosition =\n cellBreakPosition.breakChunkPosition;\n for (let i = 0; i < cell.colSpan; i++) {\n occupiedSlotIndices.push(columnIndex + i);\n }\n columnIndex += cell.colSpan;\n return this.layoutCell(\n cell,\n cellNodeContext,\n breakChunkPosition,\n ).thenAsync(() => {\n (cellNodeContext.viewNode as HTMLTableCellElement).rowSpan =\n cell.rowIndex +\n cell.rowSpan -\n this.currentRowIndex +\n rowCount -\n spanningCellRowIndex;\n return Task.newResult(true);\n });\n });\n });\n });\n return cont1.thenAsync(() => {\n addDummyCellUntil(formattingContext.getColumnCount());\n spanningCellRowIndex++;\n return Task.newResult(true);\n });\n });\n });\n });\n cont.then(() => {\n layoutContext\n .setCurrent(currentRow, true, state.atUnforcedBreak)\n .then(() => {\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n startTableRow(state: LayoutUtil.LayoutIteratorState): Task.Result<boolean> {\n if (this.inHeader || this.inFooter) {\n return Task.newResult(true);\n }\n const nodeContext = state.nodeContext;\n const formattingContext = this.formattingContext;\n if (this.currentRowIndex < 0) {\n Asserts.assert(nodeContext.sourceNode);\n this.currentRowIndex = formattingContext.findRowIndexBySourceNode(\n nodeContext.sourceNode,\n );\n } else {\n this.currentRowIndex++;\n }\n this.currentColumnIndex = 0;\n this.inRow = true;\n return this.layoutRowSpanningCellsFromPreviousFragment(state).thenAsync(\n () => {\n this.registerCellFragmentIndex();\n const overflown = this.column.checkOverflowAndSaveEdgeAndBreakPosition(\n state.lastAfterNodeContext,\n null,\n true,\n state.breakAtTheEdge,\n );\n if (\n overflown &&\n formattingContext.getRowSpanningCellsOverflowingTheRow(\n this.currentRowIndex - 1,\n ).length === 0\n ) {\n this.resetColumn();\n nodeContext.overflow = true;\n state.break = true;\n }\n return Task.newResult(true);\n },\n );\n }\n\n private registerCellFragmentIndex() {\n const cells = this.formattingContext.getRowByIndex(this.currentRowIndex)\n .cells;\n cells.forEach((cell) => {\n const cellBreakPosition = this.formattingContext.cellBreakPositions[\n cell.columnIndex\n ];\n if (\n cellBreakPosition &&\n cellBreakPosition.cell.anchorSlot.columnIndex ==\n cell.anchorSlot.columnIndex\n ) {\n const tdNodeStep = cellBreakPosition.cellNodePosition.steps[0];\n const offset = (this.column\n .layoutContext as Vgen.ViewFactory).xmldoc.getElementOffset(\n tdNodeStep.node as Element,\n );\n Layout.registerFragmentIndex(offset, tdNodeStep.fragmentIndex + 1, 1);\n }\n });\n }\n\n startTableCell(state: LayoutUtil.LayoutIteratorState): Task.Result<boolean> {\n if (this.inHeader || this.inFooter) {\n return Task.newResult(true);\n }\n const nodeContext = state.nodeContext;\n if (!this.inRow) {\n if (this.currentRowIndex < 0) {\n this.currentRowIndex = 0;\n } else {\n this.currentRowIndex++;\n }\n this.currentColumnIndex = 0;\n this.inRow = true;\n }\n const cell = this.formattingContext.getRowByIndex(this.currentRowIndex)\n .cells[this.currentColumnIndex];\n const afterNodeContext = nodeContext.copy().modify();\n afterNodeContext.after = true;\n state.nodeContext = afterNodeContext;\n const frame = Task.newFrame<boolean>(\"startTableCell\");\n let cont: Task.Result<Vtree.ChunkPosition>;\n if (this.hasBrokenCellAtSlot(cell.anchorSlot.columnIndex)) {\n const cellBreakPosition = this.formattingContext.cellBreakPositions.shift();\n nodeContext.fragmentIndex =\n cellBreakPosition.cellNodePosition.steps[0].fragmentIndex + 1;\n cont = Task.newResult(cellBreakPosition.breakChunkPosition);\n } else {\n cont = this.column\n .nextInTree(nodeContext, state.atUnforcedBreak)\n .thenAsync((nextNodeContext) => {\n if (nextNodeContext.viewNode) {\n nodeContext.viewNode.removeChild(nextNodeContext.viewNode);\n }\n const startNodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nextNodeContext,\n 0,\n );\n return Task.newResult(new VtreeImpl.ChunkPosition(startNodePosition));\n });\n }\n cont.then((startChunkPosition) => {\n Asserts.assert(nodeContext);\n this.layoutCell(cell, nodeContext, startChunkPosition).then(() => {\n this.afterNonInlineElementNode(state);\n this.currentColumnIndex++;\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n startNonInlineBox(\n state: LayoutUtil.LayoutIteratorState,\n ): Task.Result<boolean> {\n const r = skipNestedTable(\n state,\n getTableFormattingContext(this.formattingContext),\n this.column,\n );\n if (r) {\n return r;\n }\n const nodeContext = state.nodeContext;\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n const display = nodeContext.display;\n if (\n display === \"table-header-group\" &&\n repetitiveElements &&\n repetitiveElements.isHeaderSourceNode(nodeContext.sourceNode)\n ) {\n this.inHeader = true;\n return Task.newResult(true);\n } else if (\n display === \"table-footer-group\" &&\n repetitiveElements &&\n repetitiveElements.isFooterSourceNode(nodeContext.sourceNode)\n ) {\n this.inFooter = true;\n return Task.newResult(true);\n } else if (display === \"table-row\") {\n return this.startTableRow(state);\n } else if (display === \"table-cell\") {\n return this.startTableCell(state);\n } else {\n return Task.newResult(true);\n }\n }\n\n endNonInlineBox(state: LayoutUtil.LayoutIteratorState): Task.Result<boolean> {\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n if (display === \"table-row\") {\n this.inRow = false;\n if (!this.inHeader && !this.inFooter) {\n const beforeNodeContext = nodeContext.copy().modify();\n beforeNodeContext.after = false;\n const bp = new InsideTableRowBreakPosition(\n this.currentRowIndex,\n beforeNodeContext,\n this.formattingContext,\n );\n this.column.breakPositions.push(bp);\n }\n }\n return Task.newResult(true);\n }\n\n afterNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const nodeContext = state.nodeContext;\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n const display = nodeContext.display;\n if (display === \"table-header-group\") {\n if (\n repetitiveElements &&\n !repetitiveElements.allowInsertRepeatitiveElements &&\n repetitiveElements.isHeaderSourceNode(nodeContext.sourceNode)\n ) {\n this.inHeader = false;\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n } else {\n Base.setCSSProperty(\n nodeContext.viewNode as Element,\n \"display\",\n \"table-row-group\",\n );\n }\n } else if (display === \"table-footer-group\") {\n if (\n repetitiveElements &&\n !repetitiveElements.allowInsertRepeatitiveElements &&\n repetitiveElements.isFooterSourceNode(nodeContext.sourceNode)\n ) {\n this.inFooter = false;\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n } else {\n Base.setCSSProperty(\n nodeContext.viewNode as Element,\n \"display\",\n \"table-row-group\",\n );\n }\n }\n if (display && TableLayoutStrategy.ignoreList[display]) {\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n } else if (\n nodeContext.sourceNode === this.formattingContext.tableSourceNode\n ) {\n nodeContext.overflow = this.column.checkOverflowAndSaveEdge(\n nodeContext,\n null,\n );\n this.resetColumn();\n state.break = true;\n } else {\n return super.afterNonInlineElementNode(state);\n }\n return Task.newResult(true);\n }\n}\n\ntype TableLayoutOption = {\n calculateBreakPositionsInside: boolean;\n};\nconst tableLayoutOptionCache: {\n root: Node;\n tableLayoutOption: TableLayoutOption;\n}[] = [];\n\nfunction getTableLayoutOption(\n tableRootSourceNode: Node,\n): TableLayoutOption | null {\n const i = tableLayoutOptionCache.findIndex(\n (c) => c.root === tableRootSourceNode,\n );\n const pair = tableLayoutOptionCache[i];\n return pair ? pair.tableLayoutOption : null;\n}\n\nfunction clearTableLayoutOptionCache(tableRootSourceNode: Node): void {\n const i = tableLayoutOptionCache.findIndex(\n (c) => c.root === tableRootSourceNode,\n );\n if (i >= 0) {\n tableLayoutOptionCache.splice(i, 1);\n }\n}\n\nexport class TableLayoutProcessor implements LayoutProcessor.LayoutProcessor {\n private layoutEntireTable(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n const strategy = new EntireTableLayoutStrategy(formattingContext, column);\n const iterator = new LayoutUtil.LayoutIterator(\n strategy,\n column.layoutContext,\n );\n return iterator.iterate(nodeContext);\n }\n\n private getColumnWidths(\n lastRow: Element,\n columnCount: number,\n vertical: boolean,\n clientLayout: Vtree.ClientLayout,\n ): number[] {\n const doc = lastRow.ownerDocument;\n const dummyRow = doc.createElement(\"tr\");\n const dummyCells = [];\n for (let i = 0; i < columnCount; i++) {\n const cell = doc.createElement(\"td\");\n dummyRow.appendChild(cell);\n dummyCells.push(cell);\n }\n lastRow.parentNode.insertBefore(dummyRow, lastRow.nextSibling);\n const colWidths = dummyCells.map((cell) => {\n const rect = clientLayout.getElementClientRect(cell);\n return vertical ? rect[\"height\"] : rect[\"width\"];\n });\n lastRow.parentNode.removeChild(dummyRow);\n return colWidths;\n }\n\n private getColGroupElements(tableElement: Element): Element[] {\n const colGroups = [];\n let child = tableElement.firstElementChild;\n while (child) {\n if (child.localName === \"colgroup\") {\n colGroups.push(child);\n }\n child = child.nextElementSibling;\n }\n return colGroups;\n }\n\n private normalizeAndGetColElements(colGroups: Element[]): Element[] {\n const cols = [];\n colGroups.forEach((colGroup) => {\n // Replace colgroup[span=n] with colgroup with n col elements\n let span = (colGroup as any).span;\n colGroup.removeAttribute(\"span\");\n let col = colGroup.firstElementChild;\n while (col) {\n if (col.localName === \"col\") {\n // Replace col[span=n] with n col elements\n let s = (col as any).span;\n col.removeAttribute(\"span\");\n span -= s;\n while (s-- > 1) {\n const cloned = col.cloneNode(true);\n colGroup.insertBefore(cloned, col);\n cols.push(cloned);\n }\n cols.push(col);\n }\n col = col.nextElementSibling;\n }\n while (span-- > 0) {\n col = colGroup.ownerDocument.createElement(\"col\");\n colGroup.appendChild(col);\n cols.push(col);\n }\n });\n return cols;\n }\n\n private addMissingColElements(\n cols: Element[],\n colGroups: Element[],\n columnCount: number,\n tableElement: Element,\n ) {\n if (cols.length < columnCount) {\n const colGroup = tableElement.ownerDocument.createElement(\"colgroup\");\n colGroups.push(colGroup);\n for (let i = cols.length; i < columnCount; i++) {\n const col = tableElement.ownerDocument.createElement(\"col\");\n colGroup.appendChild(col);\n cols.push(col);\n }\n }\n }\n\n /**\n * Measure width of columns and normalize colgroup and col elements so that\n * each column has a corresponding col element with the width specified.\n */\n normalizeColGroups(\n formattingContext: TableFormattingContext,\n tableElement: Element,\n column: Layout.Column,\n ) {\n const vertical = formattingContext.vertical;\n const lastRow = formattingContext.lastRowViewNode;\n if (!lastRow) {\n return;\n }\n Asserts.assert(lastRow);\n formattingContext.lastRowViewNode = null;\n const doc = lastRow.ownerDocument;\n const fragment = doc.createDocumentFragment();\n\n // Count columns\n const columnCount = formattingContext.getColumnCount();\n if (!(columnCount > 0)) {\n formattingContext.colGroups = fragment;\n return;\n }\n\n // Measure column widths\n const colWidths = (formattingContext.colWidths = this.getColumnWidths(\n lastRow,\n columnCount,\n vertical,\n column.clientLayout,\n ));\n\n // Normalize colgroup and col elements\n const colGroups = this.getColGroupElements(tableElement);\n const cols = this.normalizeAndGetColElements(colGroups);\n\n // Add missing col elements for remaining columns\n this.addMissingColElements(cols, colGroups, columnCount, tableElement);\n\n // Assign width to col elements\n cols.forEach((col, i) => {\n Base.setCSSProperty(\n col,\n vertical ? \"height\" : \"width\",\n `${colWidths[i]}px`,\n );\n });\n colGroups.forEach((colGroup) => {\n fragment.appendChild(colGroup.cloneNode(true));\n });\n formattingContext.colGroups = fragment;\n }\n\n doInitialLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n formattingContext.vertical = nodeContext.vertical;\n formattingContext.initializeRepetitiveElements(nodeContext.vertical);\n Asserts.assert(nodeContext.sourceNode);\n const tableLayoutOption = getTableLayoutOption(nodeContext.sourceNode);\n clearTableLayoutOptionCache(nodeContext.sourceNode);\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"TableLayoutProcessor.doInitialLayout\",\n );\n const initialNodeContext = nodeContext.copy();\n this.layoutEntireTable(nodeContext, column).then((nodeContextAfter) => {\n const tableElement = nodeContextAfter.viewNode as Element;\n const tableBBox = column.clientLayout.getElementClientRect(tableElement);\n let edge = column.vertical ? tableBBox.left : tableBBox.bottom;\n edge +=\n (column.vertical ? -1 : 1) *\n BreakPosition.calculateOffset(\n nodeContext,\n column.collectElementsOffset(),\n ).current;\n if (\n !column.isOverflown(edge) &&\n (!tableLayoutOption || !tableLayoutOption.calculateBreakPositionsInside)\n ) {\n column.breakPositions.push(\n new EntireTableBreakPosition(initialNodeContext),\n );\n frame.finish(nodeContextAfter);\n return;\n }\n this.normalizeColGroups(formattingContext, tableElement, column);\n formattingContext.updateCellSizes(column.clientLayout);\n frame.finish(null);\n });\n return frame.result();\n }\n\n addCaptions(\n formattingContext: TableFormattingContext,\n rootViewNode: Element,\n firstChild: Node | null,\n ) {\n const captions = formattingContext.captions;\n captions.forEach((caption, i) => {\n if (caption) {\n rootViewNode.insertBefore(caption.viewNode, firstChild);\n if (caption.side === \"top\") {\n captions[i] = null;\n }\n }\n });\n }\n\n addColGroups(\n formattingContext: TableFormattingContext,\n rootViewNode: Element,\n firstChild: Node | null,\n ) {\n if (\n formattingContext.colGroups &&\n this.getColGroupElements(rootViewNode).length === 0\n ) {\n rootViewNode.insertBefore(\n formattingContext.colGroups.cloneNode(true),\n firstChild,\n );\n }\n }\n\n removeColGroups(\n formattingContext: TableFormattingContext,\n rootViewNode: Element,\n ) {\n if (formattingContext.colGroups && rootViewNode) {\n const colGroups = this.getColGroupElements(rootViewNode);\n if (colGroups) {\n colGroups.forEach((colGroup) => {\n rootViewNode.removeChild(colGroup);\n });\n }\n }\n }\n\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n const rootViewNode = formattingContext.getRootViewNode(\n nodeContext,\n ) as Element;\n const firstChild = rootViewNode.firstChild;\n this.addCaptions(formattingContext, rootViewNode, firstChild);\n this.addColGroups(formattingContext, rootViewNode, firstChild);\n const strategy = new TableLayoutStrategy(formattingContext, column);\n const iterator = new LayoutUtil.LayoutIterator(\n strategy,\n column.layoutContext,\n );\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"TableFormattingContext.doLayout\",\n );\n iterator.iterate(nodeContext).thenFinish(frame);\n return frame.result();\n }\n\n /**\n * @override\n */\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n const rootViewNode = formattingContext.getRootViewNode(nodeContext);\n if (!rootViewNode) {\n return column.buildDeepElementView(nodeContext);\n } else {\n if (leadingEdge) {\n RepetitiveElementImpl.appendHeaderToAncestors(\n nodeContext.parent,\n column,\n );\n }\n return new LayoutRetryer(formattingContext, this).layout(\n nodeContext,\n column,\n );\n }\n }\n\n /**\n * @override\n */\n createEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ): LayoutType.BreakPosition {\n return new BetweenTableRowBreakPosition(\n position,\n breakOnEdge,\n overflows,\n columnBlockSize,\n );\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean {\n return false;\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n nodeContext: Vtree.NodeContext,\n stopAtOverflow: boolean,\n ): boolean {\n return false;\n }\n\n /**\n * @override\n */\n finishBreak(\n column: Layout.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n if (nodeContext.display === \"table-row\") {\n Asserts.assert(nodeContext.sourceNode);\n const rowIndex = formattingContext.findRowIndexBySourceNode(\n nodeContext.sourceNode,\n );\n formattingContext.cellBreakPositions = [];\n let cells: TableCell[];\n if (!nodeContext.after) {\n cells = formattingContext.getCellsFallingOnRow(rowIndex);\n } else {\n cells = formattingContext.getRowSpanningCellsOverflowingTheRow(\n rowIndex,\n );\n }\n if (cells.length) {\n const frame = Task.newFrame<boolean>(\n \"TableLayoutProcessor.finishBreak\",\n );\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i === cells.length) {\n loopFrame.breakLoop();\n return;\n }\n const cell = cells[i++];\n const cellFragment = formattingContext.getCellFragmentOfCell(cell);\n const breakNodeContext = cellFragment.findAcceptableBreakPosition()\n .nodeContext;\n Asserts.assert(breakNodeContext);\n const cellNodeContext = cellFragment.cellNodeContext;\n const cellNodePosition = cellNodeContext.toNodePosition();\n const breakChunkPosition = new VtreeImpl.ChunkPosition(\n breakNodeContext.toNodePosition(),\n );\n formattingContext.cellBreakPositions.push({\n cellNodePosition,\n breakChunkPosition,\n cell,\n } as BrokenTableCellPosition);\n const cellViewNode = cellNodeContext.viewNode as HTMLTableCellElement;\n cellFragment.column.layoutContext.processFragmentedBlockEdge(\n cellFragment.cellNodeContext,\n );\n if (rowIndex < cell.rowIndex + cell.rowSpan - 1) {\n cellViewNode.rowSpan = rowIndex - cell.rowIndex + 1;\n }\n if (!cellFragment.empty) {\n cellFragment.pseudoColumn\n .finishBreak(breakNodeContext, false, true)\n .then(() => {\n Asserts.assert(cellFragment);\n adjustCellHeight(\n cellFragment,\n formattingContext,\n breakNodeContext,\n );\n loopFrame.continueLoop();\n });\n } else {\n loopFrame.continueLoop();\n }\n })\n .then(() => {\n column.clearOverflownViewNodes(nodeContext, false);\n column.layoutContext.processFragmentedBlockEdge(nodeContext);\n formattingContext.finishFragment();\n frame.finish(true);\n });\n return frame.result();\n }\n }\n formattingContext.finishFragment();\n return LayoutProcessor.blockLayoutProcessor.finishBreak(\n column,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n }\n\n /** @override */\n clearOverflownViewNodes(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ) {\n LayoutProcessor.BlockLayoutProcessor.prototype.clearOverflownViewNodes(\n column,\n parentNodeContext,\n nodeContext,\n removeSelf,\n );\n }\n}\n\nfunction adjustCellHeight(\n cellFragment: TableCellFragment,\n formattingContext: TableFormattingContext,\n breakNodeContext: Vtree.NodeContext,\n): void {\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (!repetitiveElements) {\n return;\n }\n const vertical = formattingContext.vertical;\n const column = cellFragment.column;\n const cellContentElement = cellFragment.pseudoColumn.getColumnElement();\n const cellElement = cellFragment.cellNodeContext.viewNode as Element;\n const cellElementRect = column.clientLayout.getElementClientRect(cellElement);\n const padding = column.getComputedPaddingBorder(cellElement);\n if (vertical) {\n const width =\n cellElementRect.right -\n column.footnoteEdge -\n repetitiveElements.calculateOffset(breakNodeContext) -\n padding.right;\n Base.setCSSProperty(cellContentElement, \"max-width\", `${width}px`);\n } else {\n const height =\n column.footnoteEdge -\n repetitiveElements.calculateOffset(breakNodeContext) -\n cellElementRect.top -\n padding.top;\n Base.setCSSProperty(cellContentElement, \"max-height\", `${height}px`);\n }\n Base.setCSSProperty(cellContentElement, \"overflow\", \"hidden\");\n}\n\nexport class LayoutRetryer extends LayoutRetryers.AbstractLayoutRetryer {\n constructor(\n private tableFormattingContext: TableFormattingContext,\n private readonly processor: TableLayoutProcessor,\n ) {\n super();\n }\n\n /**\n * @override\n */\n resolveLayoutMode(nodeContext: Vtree.NodeContext): LayoutType.LayoutMode {\n const repetitiveElements = this.tableFormattingContext.getRepetitiveElements();\n if (!repetitiveElements || !repetitiveElements.doneInitialLayout) {\n return new LayoutEntireTable(this.tableFormattingContext, this.processor);\n } else {\n if (\n nodeContext.sourceNode ===\n this.tableFormattingContext.tableSourceNode &&\n !nodeContext.after\n ) {\n if (repetitiveElements) {\n repetitiveElements.preventSkippingHeader();\n }\n }\n return new LayoutFragmentedTable(\n this.tableFormattingContext,\n this.processor,\n );\n }\n }\n\n /**\n * @override\n */\n clearNodes(initialPosition: Vtree.NodeContext) {\n super.clearNodes(initialPosition);\n const rootViewNode = this.tableFormattingContext.getRootViewNode(\n initialPosition,\n );\n this.processor.removeColGroups(this.tableFormattingContext, rootViewNode);\n }\n\n /**\n * @override\n */\n restoreState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n super.restoreState(nodeContext, column);\n this.tableFormattingContext.finishFragment();\n }\n}\n\nexport class LayoutEntireTable extends RepetitiveElementImpl.LayoutEntireBlock {\n constructor(\n formattingContext: TableFormattingContext,\n public readonly processor: TableLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n return this.processor.doInitialLayout(nodeContext, column);\n }\n}\n\nexport class EntireTableBreakPosition extends BreakPosition.EdgeBreakPosition {\n constructor(tableNodeContext: Vtree.NodeContext) {\n super(tableNodeContext, null, tableNodeContext.overflow, 0);\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n if (!this.isEdgeUpdated) {\n throw new Error(\"EdgeBreakPosition.prototype.updateEdge not called\");\n }\n return (\n (this.overflows ? 3 : 0) +\n (this.position.parent ? this.position.parent.breakPenalty : 0)\n );\n }\n\n /**\n * @override\n */\n breakPositionChosen(column: Layout.Column): void {\n column.fragmentLayoutConstraints.push(\n new EntireTableLayoutConstraint(this.position.sourceNode),\n );\n }\n}\n\nexport class EntireTableLayoutConstraint\n implements Layout.FragmentLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType = \"EntireTable\";\n\n constructor(public tableRootNode: Node) {}\n\n /**\n * @override\n */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): boolean {\n // If the nodeContext overflows, any EntireTableLayoutConstraint should not\n // be registered in the first place. See\n // TableLayoutProcessor.prototype.doInitialLayout.\n Asserts.assert(!nodeContext.overflow);\n return false;\n }\n\n /**\n * @override\n */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n return true;\n }\n\n /**\n * @override\n */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n ) {\n Asserts.assert(positionAfter.sourceNode);\n tableLayoutOptionCache.push({\n root: positionAfter.sourceNode,\n tableLayoutOption: {\n calculateBreakPositionsInside: true,\n } as TableLayoutOption,\n });\n }\n\n /**\n * @override\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<boolean> {\n return Task.newResult(true);\n }\n\n /**\n * @override\n */\n equalsTo(constraint: Layout.FragmentLayoutConstraint): boolean {\n return (\n constraint instanceof EntireTableLayoutConstraint &&\n constraint.tableRootNode === this.tableRootNode\n );\n }\n\n /**\n * @override\n */\n getPriorityOfFinishBreak(): number {\n return 0;\n }\n}\n\nexport class LayoutFragmentedTable extends RepetitiveElementImpl.LayoutFragmentedBlock {\n constructor(\n formattingContext: TableFormattingContext,\n public readonly processor: TableLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n if (\n repetitiveElements &&\n !repetitiveElements.isAfterLastContent(nodeContext)\n ) {\n const constraint = new TableRowLayoutConstraint(nodeContext);\n if (\n !column.fragmentLayoutConstraints.some((c) => constraint.equalsTo(c))\n ) {\n column.fragmentLayoutConstraints.unshift(constraint);\n }\n }\n return this.processor.doLayout(nodeContext, column);\n }\n}\n\nexport class TableRowLayoutConstraint\n extends RepetitiveElementImpl.RepetitiveElementsOwnerLayoutConstraint\n implements Table.TableRowLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType = \"TableRow\";\n cellFragmentLayoutConstraints: {\n constraints: Layout.FragmentLayoutConstraint[];\n breakPosition: Vtree.NodeContext;\n }[] = [];\n\n constructor(nodeContext: Vtree.NodeContext) {\n super(nodeContext);\n }\n\n /** @override */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): boolean {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return true;\n }\n if (column.pseudoParent) {\n return true;\n }\n if (LayoutHelper.isOrphan(this.nodeContext.viewNode)) {\n return true;\n }\n if (!repetitiveElements.isEnableToUpdateState()) {\n return true;\n }\n if (\n (overflownNodeContext && !nodeContext) ||\n (nodeContext && nodeContext.overflow)\n ) {\n return false;\n } else {\n return true;\n }\n }\n\n /** @override */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n const cellFragmentConstraints = this.collectCellFragmentLayoutConstraints(\n nodeContext,\n formattingContext,\n );\n if (\n cellFragmentConstraints.some((entry) =>\n entry.constraints.some((constraint) =>\n constraint.nextCandidate(nodeContext),\n ),\n )\n ) {\n return true;\n }\n return super.nextCandidate(nodeContext);\n }\n\n /** @override */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n ) {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n this.cellFragmentLayoutConstraints = this.collectCellFragmentLayoutConstraints(\n positionAfter,\n formattingContext,\n );\n this.cellFragmentLayoutConstraints.forEach((entry) => {\n entry.constraints.forEach((constraint) => {\n constraint.postLayout(\n allowed,\n entry.breakPosition,\n initialPosition,\n column,\n );\n });\n });\n if (!allowed) {\n const rootViewNode = formattingContext.getRootViewNode(this.nodeContext);\n new TableLayoutProcessor().removeColGroups(\n formattingContext,\n rootViewNode as Element,\n );\n this.removeDummyRowNodes(initialPosition);\n }\n super.postLayout(allowed, positionAfter, initialPosition, column);\n }\n\n /** @override */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<boolean> {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n const frame: Task.Frame<boolean> = Task.newFrame(\"finishBreak\");\n const constraints = this.cellFragmentLayoutConstraints.reduce(\n (array, entry) =>\n array.concat(\n entry.constraints.map((constraint) => ({\n constraint,\n breakPosition: entry.breakPosition,\n })),\n ),\n [],\n );\n let i = 0;\n frame\n .loop(() => {\n if (i < constraints.length) {\n const entry = constraints[i++];\n return entry.constraint\n .finishBreak(entry.breakPosition, column)\n .thenReturn(true);\n } else {\n return Task.newResult(false);\n }\n })\n .then(() => {\n frame.finish(true);\n });\n return frame\n .result()\n .thenAsync(() => super.finishBreak(nodeContext, column));\n }\n\n removeDummyRowNodes(nodeContext: Vtree.NodeContext) {\n if (\n !nodeContext ||\n nodeContext.display !== \"table-row\" ||\n !nodeContext.viewNode\n ) {\n return;\n }\n while ((nodeContext.viewNode as Element).previousElementSibling) {\n const dummyNode = (nodeContext.viewNode as Element)\n .previousElementSibling;\n if (dummyNode.parentNode) {\n dummyNode.parentNode.removeChild(dummyNode);\n }\n }\n }\n\n private collectCellFragmentLayoutConstraints(\n nodeContext: Vtree.NodeContext,\n formattingContext: TableFormattingContext,\n ): {\n constraints: Layout.FragmentLayoutConstraint[];\n breakPosition: Vtree.NodeContext;\n }[] {\n return this.getCellFragemnts(nodeContext, formattingContext).map(\n (entry) => ({\n constraints: entry.fragment.pseudoColumn.getColumn()\n .fragmentLayoutConstraints,\n breakPosition: entry.breakPosition,\n }),\n );\n }\n\n private getCellFragemnts(\n nodeContext: Vtree.NodeContext,\n formattingContext: TableFormattingContext,\n ): { fragment: TableCellFragment; breakPosition: Vtree.NodeContext }[] {\n let rowIndex = Number.MAX_VALUE;\n if (nodeContext && nodeContext.display === \"table-row\") {\n Asserts.assert(nodeContext.sourceNode);\n rowIndex =\n formattingContext.findRowIndexBySourceNode(nodeContext.sourceNode) + 1;\n }\n rowIndex = Math.min(formattingContext.cellFragments.length, rowIndex);\n const cellFragments = [];\n for (let i = 0; i < rowIndex; i++) {\n if (!formattingContext.cellFragments[i]) {\n continue;\n }\n formattingContext.cellFragments[i].forEach((cellFragment) => {\n if (!cellFragment) {\n return;\n }\n cellFragments.push({\n fragment: cellFragment,\n breakPosition: cellFragment.findAcceptableBreakPosition().nodeContext,\n });\n });\n }\n return cellFragments;\n }\n\n getElementsOffsetsForTableCell(\n column: Layout.Column,\n ): RepetitiveElement.ElementsOffset[] {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n const position = formattingContext.findCellFromColumn(column);\n if (position) {\n return formattingContext.collectElementsOffsetOfUpperCells(position);\n } else {\n return formattingContext.collectElementsOffsetOfHighestColumn();\n }\n }\n\n /** @override */\n equalsTo(constraint: Layout.FragmentLayoutConstraint): boolean {\n if (!(constraint instanceof TableRowLayoutConstraint)) {\n return false;\n }\n return (\n getTableFormattingContext(this.nodeContext.formattingContext) ===\n getTableFormattingContext(constraint.nodeContext.formattingContext)\n );\n }\n}\n\nconst tableLayoutProcessor = new TableLayoutProcessor();\n\nfunction resolveFormattingContextHook(\n nodeContext: Vtree.NodeContext,\n firstTime: boolean,\n display: Css.Ident,\n position: Css.Ident,\n floatSide: Css.Ident,\n isRoot: boolean,\n): TableFormattingContext | null {\n if (!firstTime) {\n return null;\n }\n if (display === Css.ident.table) {\n const parent = nodeContext.parent;\n return new TableFormattingContext(\n parent ? parent.formattingContext : null,\n nodeContext.sourceNode as Element,\n );\n }\n return null;\n}\n\nfunction resolveLayoutProcessor(\n formattingContext,\n): TableLayoutProcessor | null {\n if (formattingContext instanceof TableFormattingContext) {\n return tableLayoutProcessor;\n }\n return null;\n}\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_FORMATTING_CONTEXT,\n resolveFormattingContextHook,\n);\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n resolveLayoutProcessor,\n);\n","/**\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview MathUtil - Math utilities\n */\nexport function mean(array: number[]): number {\n return array.reduce((prev, curr) => prev + curr, 0) / array.length;\n}\n\nexport function variance(array: number[]): number {\n const meanValue = mean(array);\n return mean(\n array.map((x) => {\n const d = x - meanValue;\n return d * d;\n }),\n );\n}\n","/**\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Columns - Control column layout.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Css from \"./css\";\nimport * as MathUtil from \"./math-util\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Task from \"./task\";\nimport * as Vtree from \"./vtree\";\nimport { Layout } from \"./types\";\n\nexport type ColumnLayoutResult = {\n columns: Layout.Column[];\n position: Vtree.LayoutPosition;\n columnPageFloatLayoutContexts?: PageFloats.PageFloatLayoutContext[];\n};\n\nexport type ColumnGenerator = () => Task.Result<ColumnLayoutResult | null>;\n\nexport class ColumnBalancingTrialResult {\n constructor(\n public readonly layoutResult: ColumnLayoutResult,\n public readonly penalty: number,\n ) {}\n}\n\nfunction getBlockSize(container: Vtree.Container): number {\n if (container.vertical) {\n return container.width;\n } else {\n return container.height;\n }\n}\n\nfunction setBlockSize(container: Vtree.Container, size: number) {\n if (container.vertical) {\n container.width = size;\n } else {\n container.height = size;\n }\n}\n\nexport abstract class ColumnBalancer {\n originalContainerBlockSize: number;\n\n constructor(\n public readonly layoutContainer: Vtree.Container,\n public readonly columnGenerator: ColumnGenerator,\n public readonly regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ) {\n this.originalContainerBlockSize = getBlockSize(layoutContainer);\n }\n\n balanceColumns(\n layoutResult: ColumnLayoutResult,\n ): Task.Result<ColumnLayoutResult> {\n const self = this;\n const frame: Task.Frame<ColumnLayoutResult> = Task.newFrame(\n \"ColumnBalancer#balanceColumns\",\n );\n self.preBalance(layoutResult);\n self.savePageFloatLayoutContexts(layoutResult);\n self.layoutContainer.clear();\n const candidates = [self.createTrialResult(layoutResult)];\n frame\n .loopWithFrame((loopFrame) => {\n if (!self.hasNextCandidate(candidates)) {\n loopFrame.breakLoop();\n return;\n }\n self.updateCondition(candidates);\n self.columnGenerator().then((layoutResult) => {\n self.savePageFloatLayoutContexts(layoutResult);\n self.layoutContainer.clear();\n if (!layoutResult) {\n loopFrame.breakLoop();\n return;\n }\n candidates.push(self.createTrialResult(layoutResult));\n loopFrame.continueLoop();\n });\n })\n .then(() => {\n const result = candidates.reduce(\n (prev, curr) => (curr.penalty < prev.penalty ? curr : prev),\n candidates[0],\n );\n self.restoreContents(result.layoutResult);\n self.postBalance();\n frame.finish(result.layoutResult);\n });\n return frame.result();\n }\n\n private createTrialResult(\n layoutResult: ColumnLayoutResult,\n ): ColumnBalancingTrialResult {\n const penalty = this.calculatePenalty(layoutResult);\n return new ColumnBalancingTrialResult(layoutResult, penalty);\n }\n\n protected preBalance(layoutResult: ColumnLayoutResult) {}\n\n protected abstract calculatePenalty(layoutResult: ColumnLayoutResult): number;\n\n protected abstract hasNextCandidate(\n candidates: ColumnBalancingTrialResult[],\n ): boolean;\n\n protected abstract updateCondition(\n candidates: ColumnBalancingTrialResult[],\n ): void;\n\n protected postBalance() {\n setBlockSize(this.layoutContainer, this.originalContainerBlockSize);\n }\n\n savePageFloatLayoutContexts(layoutResult: ColumnLayoutResult | null) {\n const children = this.regionPageFloatLayoutContext.detachChildren();\n if (layoutResult) {\n layoutResult.columnPageFloatLayoutContexts = children;\n }\n }\n\n private restoreContents(newLayoutResult: ColumnLayoutResult) {\n const parent = this.layoutContainer.element;\n newLayoutResult.columns.forEach((c) => {\n parent.appendChild(c.element);\n });\n Asserts.assert(newLayoutResult.columnPageFloatLayoutContexts);\n this.regionPageFloatLayoutContext.attachChildren(\n newLayoutResult.columnPageFloatLayoutContexts,\n );\n }\n}\nconst COLUMN_LENGTH_STEP = 1;\n\nexport function canReduceContainerSize(\n candidates: ColumnBalancingTrialResult[],\n): boolean {\n const lastCandidate = candidates[candidates.length - 1];\n if (lastCandidate.penalty === 0) {\n return false;\n }\n const secondLastCandidate = candidates[candidates.length - 2];\n if (\n secondLastCandidate &&\n lastCandidate.penalty >= secondLastCandidate.penalty\n ) {\n return false;\n }\n const columns = lastCandidate.layoutResult.columns;\n const maxColumnBlockSize = Math.max.apply(\n null,\n columns.map((c) => c.computedBlockSize),\n );\n const maxPageFloatBlockSize = Math.max.apply(\n null,\n columns.map((c) => c.getMaxBlockSizeOfPageFloats()),\n );\n return maxColumnBlockSize > maxPageFloatBlockSize + COLUMN_LENGTH_STEP;\n}\n\nexport function reduceContainerSize(\n candidates: ColumnBalancingTrialResult[],\n container: Vtree.Container,\n): void {\n const columns = candidates[candidates.length - 1].layoutResult.columns;\n const maxColumnBlockSize = Math.max.apply(\n null,\n columns.map((c) => {\n if (!isNaN(c.blockDistanceToBlockEndFloats)) {\n return (\n c.computedBlockSize -\n c.blockDistanceToBlockEndFloats +\n COLUMN_LENGTH_STEP\n );\n } else {\n return c.computedBlockSize;\n }\n }),\n );\n const newEdge = maxColumnBlockSize - COLUMN_LENGTH_STEP;\n if (newEdge < getBlockSize(container)) {\n setBlockSize(container, newEdge);\n } else {\n setBlockSize(container, getBlockSize(container) - 1);\n }\n}\n\nexport class BalanceLastColumnBalancer extends ColumnBalancer {\n originalPosition: Vtree.LayoutPosition | null = null;\n foundUpperBound: boolean = false;\n\n constructor(\n columnGenerator: ColumnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n public readonly columnCount: number,\n ) {\n super(layoutContainer, columnGenerator, regionPageFloatLayoutContext);\n }\n\n /**\n * @override\n */\n preBalance(layoutResult: ColumnLayoutResult) {\n const columns = layoutResult.columns;\n const totalBlockSize = columns.reduce(\n (prev, c) => prev + c.computedBlockSize,\n 0,\n );\n setBlockSize(this.layoutContainer, totalBlockSize / this.columnCount);\n this.originalPosition = layoutResult.position;\n }\n\n private checkPosition(position: Vtree.LayoutPosition | null): boolean {\n if (this.originalPosition) {\n return this.originalPosition.isSamePosition(position);\n } else {\n return position === null;\n }\n }\n\n /**\n * @override\n */\n calculatePenalty(layoutResult: ColumnLayoutResult): number {\n if (!this.checkPosition(layoutResult.position)) {\n return Infinity;\n }\n const columns = layoutResult.columns;\n if (isLastColumnLongerThanAnyOtherColumn(columns)) {\n return Infinity;\n }\n return Math.max.apply(\n null,\n columns.map((c) => c.computedBlockSize),\n );\n }\n\n /**\n * @override\n */\n hasNextCandidate(candidates: ColumnBalancingTrialResult[]): boolean {\n if (candidates.length === 1) {\n return true;\n } else if (this.foundUpperBound) {\n return canReduceContainerSize(candidates);\n } else {\n const lastCandidate = candidates[candidates.length - 1];\n if (this.checkPosition(lastCandidate.layoutResult.position)) {\n if (\n !isLastColumnLongerThanAnyOtherColumn(\n lastCandidate.layoutResult.columns,\n )\n ) {\n this.foundUpperBound = true;\n return true;\n }\n }\n return (\n getBlockSize(this.layoutContainer) < this.originalContainerBlockSize\n );\n }\n }\n\n /**\n * @override\n */\n updateCondition(candidates: ColumnBalancingTrialResult[]): void {\n if (this.foundUpperBound) {\n reduceContainerSize(candidates, this.layoutContainer);\n } else {\n const newEdge = Math.min(\n this.originalContainerBlockSize,\n getBlockSize(this.layoutContainer) +\n this.originalContainerBlockSize * 0.1,\n );\n setBlockSize(this.layoutContainer, newEdge);\n }\n }\n}\n\nfunction isLastColumnLongerThanAnyOtherColumn(\n columns: Layout.Column[],\n): boolean {\n if (columns.length <= 1) {\n return false;\n }\n const lastColumnBlockSize = columns[columns.length - 1].computedBlockSize;\n const otherColumns = columns.slice(0, columns.length - 1);\n return otherColumns.every((c) => lastColumnBlockSize > c.computedBlockSize);\n}\n\nexport class BalanceNonLastColumnBalancer extends ColumnBalancer {\n constructor(\n columnGenerator: ColumnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n ) {\n super(layoutContainer, columnGenerator, regionPageFloatLayoutContext);\n }\n\n /**\n * @override\n */\n calculatePenalty(layoutResult: ColumnLayoutResult): number {\n if (layoutResult.columns.every((c) => c.computedBlockSize === 0)) {\n return Infinity;\n }\n const computedBlockSizes = layoutResult.columns\n .filter((c) => !c.pageBreakType)\n .map((c) => c.computedBlockSize);\n return MathUtil.variance(computedBlockSizes);\n }\n\n /**\n * @override\n */\n hasNextCandidate(candidates: ColumnBalancingTrialResult[]): boolean {\n return canReduceContainerSize(candidates);\n }\n\n /**\n * @override\n */\n updateCondition(candidates: ColumnBalancingTrialResult[]): void {\n reduceContainerSize(candidates, this.layoutContainer);\n }\n}\n\nexport function createColumnBalancer(\n columnCount: number,\n columnFill: Css.Ident,\n columnGenerator: ColumnGenerator,\n regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n columns: Layout.Column[],\n flowPosition: Vtree.FlowPosition,\n): ColumnBalancer | null {\n if (columnFill === Css.ident.auto) {\n return null;\n } else {\n // TODO: how to handle a case where no more in-flow contents but some\n // page floats\n const noMoreContent = flowPosition.positions.length === 0;\n const lastColumn = columns[columns.length - 1];\n const isLastColumnForceBroken = !!(lastColumn && lastColumn.pageBreakType);\n if (noMoreContent || isLastColumnForceBroken) {\n return new BalanceLastColumnBalancer(\n columnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer,\n columnCount,\n );\n } else if (columnFill === Css.ident.balance_all) {\n return new BalanceNonLastColumnBalancer(\n columnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer,\n );\n } else {\n Asserts.assert(columnFill === Css.ident.balance);\n return null;\n }\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssStyler - Apply CSS cascade to a document incrementally and\n * cache the result.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Break from \"./break\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Display from \"./display\";\nimport * as Exprs from \"./exprs\";\nimport * as Vtree from \"./vtree\";\nimport { CssStyler, XmlDoc } from \"./types\";\n\nexport class SlipRange {\n endStuckFixed: number;\n endFixed: number;\n endSlipped: number;\n\n constructor(endStuckFixed, endFixed, endSlipped) {\n this.endStuckFixed = endStuckFixed;\n this.endFixed = endFixed;\n this.endSlipped = endSlipped;\n }\n}\n\n/**\n * Maps all ints in a range (\"fixed\") to ints with slippage (\"slipped\")\n */\nexport class SlipMap {\n map = [] as SlipRange[];\n\n getMaxFixed(): number {\n if (this.map.length == 0) {\n return 0;\n }\n const range = this.map[this.map.length - 1];\n return range.endFixed;\n }\n\n getMaxSlipped(): number {\n if (this.map.length == 0) {\n return 0;\n }\n const range = this.map[this.map.length - 1];\n return range.endSlipped;\n }\n\n addStuckRange(endFixed: number): void {\n if (this.map.length == 0) {\n this.map.push(new SlipRange(endFixed, endFixed, endFixed));\n } else {\n const range = this.map[this.map.length - 1];\n const endSlipped = range.endSlipped + endFixed - range.endFixed;\n if (range.endFixed == range.endStuckFixed) {\n range.endFixed = endFixed;\n range.endStuckFixed = endFixed;\n range.endSlipped = endSlipped;\n } else {\n this.map.push(new SlipRange(endFixed, endFixed, endSlipped));\n }\n }\n }\n\n addSlippedRange(endFixed: number): void {\n if (this.map.length == 0) {\n this.map.push(new SlipRange(endFixed, 0, 0));\n } else {\n this.map[this.map.length - 1].endFixed = endFixed;\n }\n }\n\n slippedByFixed(fixed: number): number {\n const self = this;\n const index = Base.binarySearch(\n this.map.length,\n (index) => fixed <= self.map[index].endFixed,\n );\n const range = this.map[index];\n return range.endSlipped - Math.max(0, range.endStuckFixed - fixed);\n }\n\n /**\n * Smallest fixed for a given slipped.\n */\n fixedBySlipped(slipped: number): number {\n const self = this;\n const index = Base.binarySearch(\n this.map.length,\n (index) => slipped <= self.map[index].endSlipped,\n );\n const range = this.map[index];\n return range.endStuckFixed - (range.endSlipped - slipped);\n }\n}\n\nexport interface FlowListener {\n /**\n * @return void\n */\n encounteredFlowChunk(flowChunk: Vtree.FlowChunk, flow: Vtree.Flow): any;\n}\n\nexport interface AbstractStyler extends CssStyler.AbstractStyler {}\n\n/**\n * Represent a box generated by a (pseudo)element. When constructed, a box\n * corresponding to `::before` pseudoelement is also constructed and stored in\n * `beforeBox` property, whereas one corresponding `::after` pseudoelement is\n * not constructed and `afterBox` property is `null`. `afterBox` is constructed\n * by `buildAfterPseudoElementBox` method.\n * @param style Cascaded style values for the box.\n * @param offset The start offset of the box. It coincides with the start offset\n * of the element if the box is generated by the element or the `::before`\n * pseudoelement. When the box corresponds to the `::after` pseudoelement,\n * the offset is just after the content before the `::after` pseudoelement.\n * @param isRoot True if the box is generated by the root element (not\n * pseudoelement).\n * @param flowChunk FlowChunk to which the box belongs to.\n * @param atBlockStart True if the box is right after the block start edge.\n * @param atFlowStart True if the box is right after the flow start.\n * @param isParentBoxDisplayed True if the parent box has a displayed box.\n */\nexport class Box {\n flowName: string;\n isBlockValue: boolean | null = null;\n hasBoxValue: boolean | null = null;\n styleValues = {} as { [key: string]: Css.Val };\n beforeBox: Box = null;\n afterBox: Box = null;\n breakBefore: string | null = null;\n\n constructor(\n public readonly context: Exprs.Context,\n public readonly style: CssCascade.ElementStyle,\n public readonly offset: number,\n public readonly isRoot: boolean,\n public readonly flowChunk: Vtree.FlowChunk,\n public readonly atBlockStart: boolean,\n public readonly atFlowStart: boolean,\n public readonly isParentBoxDisplayed: boolean,\n ) {\n this.flowName = flowChunk.flowName;\n if (this.hasBox()) {\n const pseudoMap = style[\"_pseudos\"];\n if (pseudoMap) {\n if (pseudoMap[\"before\"]) {\n const beforeBox = new Box(\n context,\n pseudoMap[\"before\"],\n offset,\n false,\n flowChunk,\n this.isBlock(),\n atFlowStart,\n true,\n );\n const beforeContent = beforeBox.styleValue(\"content\");\n if (Vtree.nonTrivialContent(beforeContent)) {\n this.beforeBox = beforeBox;\n this.breakBefore = beforeBox.breakBefore;\n }\n }\n }\n }\n this.breakBefore = Break.resolveEffectiveBreakValue(\n this.getBreakValue(\"before\"),\n this.breakBefore,\n );\n if (this.atFlowStart && Break.isForcedBreakValue(this.breakBefore)) {\n flowChunk.breakBefore = Break.resolveEffectiveBreakValue(\n flowChunk.breakBefore,\n this.breakBefore,\n );\n }\n }\n\n /**\n * Build a box corresponding to `::after` pseudoelement and stores it in\n * `afterBox` property.\n * @param offset The start offset of the `::after` pseudoelement box, which is\n * just after the content before the `::after` pseudoelement.\n * @param atBlockStart True if the box is right after the block start edge.\n * @param atFlowStart True if the box is right after the flow start.\n */\n buildAfterPseudoElementBox(\n offset: number,\n atBlockStart: boolean,\n atFlowStart: boolean,\n ) {\n if (this.hasBox()) {\n const pseudoMap = this.style[\"_pseudos\"];\n if (pseudoMap) {\n if (pseudoMap[\"after\"]) {\n const afterBox = new Box(\n this.context,\n pseudoMap[\"after\"],\n offset,\n false,\n this.flowChunk,\n atBlockStart,\n atFlowStart,\n true,\n );\n const afterContent = afterBox.styleValue(\"content\");\n if (Vtree.nonTrivialContent(afterContent)) {\n this.afterBox = afterBox;\n }\n }\n }\n }\n }\n\n styleValue(name: string, defaultValue?: Css.Val): Css.Val | null {\n if (!(name in this.styleValues)) {\n const cv = this.style[name];\n this.styleValues[name] = cv\n ? cv.evaluate(this.context, name)\n : defaultValue || null;\n }\n return this.styleValues[name];\n }\n\n displayValue(): Css.Val {\n return this.styleValue(\"display\", Css.ident.inline);\n }\n\n isBlock(): boolean {\n if (this.isBlockValue === null) {\n const display = this.displayValue() as Css.Ident;\n const position = this.styleValue(\"position\") as Css.Ident;\n const float = this.styleValue(\"float\") as Css.Ident;\n this.isBlockValue = Display.isBlock(\n display,\n position,\n float,\n this.isRoot,\n );\n }\n return this.isBlockValue;\n }\n\n hasBox(): boolean {\n if (this.hasBoxValue === null) {\n this.hasBoxValue =\n this.isParentBoxDisplayed && this.displayValue() !== Css.ident.none;\n }\n return this.hasBoxValue;\n }\n\n getBreakValue(edge: string): string | null {\n let breakValue: string | null = null;\n if (this.isBlock()) {\n const val = this.styleValue(`break-${edge}`);\n if (val) {\n breakValue = val.toString();\n }\n }\n return breakValue;\n }\n}\n\n/**\n * Manages boxes generated by elements as a stack.\n */\nexport class BoxStack {\n stack = [] as Box[];\n atBlockStart: boolean = true; // indicates if the next pushed box will be at the block start\n atFlowStart: boolean = true; // indicates if the next pushed box will be at the flow start\n atStartStack = [] as { atBlockStart: boolean; atFlowStart: boolean }[]; // pushed when a new flow starts\n\n constructor(public readonly context: Exprs.Context) {}\n\n /**\n * Returns if the stack is empty.\n */\n empty(): boolean {\n return this.stack.length === 0;\n }\n\n /**\n * Returns the last box in the stack.\n */\n lastBox(): Box | undefined {\n return this.stack[this.stack.length - 1];\n }\n\n /**\n * Returns the flow name of the last box in the stack.\n */\n lastFlowName(): string | null {\n const lastBox = this.lastBox();\n return lastBox ? lastBox.flowChunk.flowName : null;\n }\n\n /**\n * Returns if the last box in the stack is displayed.\n */\n isCurrentBoxDisplayed(): boolean {\n return this.stack.every((box) => box.displayValue() !== Css.ident.none);\n }\n\n /**\n * Create a new box and push it to the stack.\n * @param style Cascaded style values for the box.\n * @param offset The start offset of the box.\n * @param isRoot True if the box is generated by the root element\n * @param newFlowChunk Specify if the element is a flow element (i.e. the\n * element is specified a new `flow-into` value)\n */\n push(\n style: CssCascade.ElementStyle,\n offset: number,\n isRoot: boolean,\n newFlowChunk?: Vtree.FlowChunk,\n ): Box {\n const lastBox = this.lastBox();\n if (newFlowChunk && lastBox && newFlowChunk.flowName !== lastBox.flowName) {\n this.atStartStack.push({\n atBlockStart: this.atBlockStart,\n atFlowStart: this.atFlowStart,\n });\n }\n const flowChunk = newFlowChunk || lastBox.flowChunk;\n const isAtFlowStart = this.atFlowStart || !!newFlowChunk;\n const isParentBoxDisplayed = this.isCurrentBoxDisplayed();\n const box = new Box(\n this.context,\n style,\n offset,\n isRoot,\n flowChunk,\n isAtFlowStart || this.atBlockStart,\n isAtFlowStart,\n isParentBoxDisplayed,\n );\n this.stack.push(box);\n this.atBlockStart = box.hasBox()\n ? !box.beforeBox && box.isBlock()\n : this.atBlockStart;\n this.atFlowStart = box.hasBox()\n ? !box.beforeBox && isAtFlowStart\n : this.atFlowStart;\n return box;\n }\n\n encounteredTextNode(node: Node) {\n const box = this.lastBox();\n if ((this.atBlockStart || this.atFlowStart) && box.hasBox()) {\n const whitespaceValue = box\n .styleValue(\"white-space\", Css.ident.normal)\n .toString();\n const whitespace = Vtree.whitespaceFromPropertyValue(whitespaceValue);\n Asserts.assert(whitespace !== null);\n if (!Vtree.canIgnore(node, whitespace)) {\n this.atBlockStart = false;\n this.atFlowStart = false;\n }\n }\n }\n\n /**\n * Pop the last box.\n */\n pop(offset: number): Box {\n const box = this.stack.pop();\n box.buildAfterPseudoElementBox(offset, this.atBlockStart, this.atFlowStart);\n if (this.atFlowStart && box.afterBox) {\n const breakBefore = box.afterBox.getBreakValue(\"before\");\n box.flowChunk.breakBefore = Break.resolveEffectiveBreakValue(\n box.flowChunk.breakBefore,\n breakBefore,\n );\n }\n const parent = this.lastBox();\n if (parent) {\n if (parent.flowName === box.flowName) {\n if (box.hasBox()) {\n this.atBlockStart = this.atFlowStart = false;\n }\n } else {\n const atStart = this.atStartStack.pop();\n this.atBlockStart = atStart.atBlockStart;\n this.atFlowStart = atStart.atFlowStart;\n }\n }\n return box;\n }\n\n /**\n * Find the start offset of the nearest block start edge to which the\n * `break-before` value of the box should be propagated. This method can be\n * called when after pushing the box into the stack or after popping the box\n * out of the stack.\n */\n nearestBlockStartOffset(box: Box): number {\n if (!box.atBlockStart) {\n return box.offset;\n }\n let i = this.stack.length - 1;\n let parent = this.stack[i];\n\n // When called just after the box is popped out, the last box in the stack\n // is different from the box and it is the parent of the box. When called\n // after the box is pushed, the last box in the stack is identical to the\n // box and the parent of the box is a box right before the specified box.\n if (parent === box) {\n i--;\n parent = this.stack[i];\n }\n while (i >= 0) {\n if (parent.flowName !== box.flowName) {\n return box.offset;\n }\n if (!parent.atBlockStart) {\n return parent.offset;\n }\n if (parent.isRoot) {\n return parent.offset;\n }\n box = parent;\n parent = this.stack[--i];\n }\n throw new Error(\"No block start offset found!\");\n }\n}\n\nexport class Styler implements AbstractStyler {\n root: Element;\n cascadeHolder: CssCascade.Cascade;\n last: Node;\n rootStyle = {} as CssCascade.ElementStyle;\n styleMap: { [key: string]: CssCascade.ElementStyle } = {};\n flows = {} as { [key: string]: Vtree.Flow };\n flowChunks = [] as Vtree.FlowChunk[];\n flowListener: FlowListener = null;\n flowToReach: string | null = null;\n idToReach: string | null = null;\n cascade: CssCascade.CascadeInstance;\n offsetMap: SlipMap;\n primary: boolean = true;\n primaryStack = [] as boolean[];\n rootBackgroundAssigned: boolean = false;\n rootLayoutAssigned: boolean = false;\n lastOffset: number;\n breakBeforeValues = {} as { [key: number]: string | null };\n boxStack: BoxStack;\n bodyReached: boolean = true;\n\n constructor(\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n cascade: CssCascade.Cascade,\n public readonly scope: Exprs.LexicalScope,\n public readonly context: Exprs.Context,\n public readonly primaryFlows: { [key: string]: boolean },\n public readonly validatorSet: CssValidator.ValidatorSet,\n public readonly counterListener: CssCascade.CounterListener,\n counterResolver: CssCascade.CounterResolver,\n ) {\n this.root = xmldoc.root;\n this.cascadeHolder = cascade;\n this.last = this.root;\n this.cascade = cascade.createInstance(\n context,\n counterListener,\n counterResolver,\n xmldoc.lang,\n );\n this.offsetMap = new SlipMap();\n const rootOffset = xmldoc.getElementOffset(this.root);\n this.lastOffset = rootOffset;\n this.boxStack = new BoxStack(context);\n this.offsetMap.addStuckRange(rootOffset);\n const style = this.getAttrStyle(this.root);\n this.cascade.pushElement(this.root, style, rootOffset);\n this.postprocessTopStyle(style, false);\n switch (this.root.namespaceURI) {\n case Base.NS.XHTML:\n case Base.NS.FB2:\n this.bodyReached = false;\n break;\n }\n this.primaryStack.push(true);\n this.styleMap = {};\n this.styleMap[`e${rootOffset}`] = style;\n this.lastOffset++;\n this.replayFlowElementsFromOffset(-1);\n }\n\n hasProp(\n style: CssCascade.ElementStyle,\n map: CssValidator.ValueMap,\n name: string,\n ): boolean {\n const cascVal = style[name];\n return cascVal && cascVal.evaluate(this.context) !== map[name];\n }\n\n transferPropsToRoot(\n srcStyle: CssCascade.ElementStyle,\n map: CssValidator.ValueMap,\n ): void {\n for (const pname in map) {\n const cascval = srcStyle[pname];\n if (cascval) {\n this.rootStyle[pname] = cascval;\n delete srcStyle[pname];\n } else {\n const val = map[pname];\n if (val) {\n this.rootStyle[pname] = new CssCascade.CascadeValue(\n val,\n CssParser.SPECIFICITY_AUTHOR,\n );\n }\n }\n }\n }\n\n /**\n * Transfer properties that should be applied on the container (partition)\n * level to this.rootStyle.\n * @param elemStyle (source) element style\n */\n postprocessTopStyle(\n elemStyle: CssCascade.ElementStyle,\n isBody: boolean,\n ): void {\n [\"writing-mode\", \"direction\"].forEach((propName) => {\n if (elemStyle[propName] && !(isBody && this.rootStyle[propName])) {\n // Copy it over, but keep it at the root element as well.\n this.rootStyle[propName] = elemStyle[propName];\n }\n });\n if (!this.rootBackgroundAssigned) {\n const backgroundColor = this.hasProp(\n elemStyle,\n this.validatorSet.backgroundProps,\n \"background-color\",\n )\n ? elemStyle[\"background-color\"].evaluate(this.context)\n : (null as Css.Val);\n const backgroundImage = this.hasProp(\n elemStyle,\n this.validatorSet.backgroundProps,\n \"background-image\",\n )\n ? elemStyle[\"background-image\"].evaluate(this.context)\n : (null as Css.Val);\n if (\n (backgroundColor && backgroundColor !== Css.ident.inherit) ||\n (backgroundImage && backgroundImage !== Css.ident.inherit)\n ) {\n this.transferPropsToRoot(elemStyle, this.validatorSet.backgroundProps);\n this.rootBackgroundAssigned = true;\n }\n }\n if (!this.rootLayoutAssigned) {\n for (let i = 0; i < columnProps.length; i++) {\n if (\n this.hasProp(elemStyle, this.validatorSet.layoutProps, columnProps[i])\n ) {\n this.transferPropsToRoot(elemStyle, this.validatorSet.layoutProps);\n this.rootLayoutAssigned = true;\n break;\n }\n }\n }\n if (!isBody) {\n const fontSize = elemStyle[\"font-size\"];\n if (fontSize) {\n const val = fontSize.evaluate(this.context);\n let px = val.num;\n switch (val.unit) {\n case \"em\":\n case \"rem\":\n px *= this.context.initialFontSize;\n break;\n case \"ex\":\n px *=\n (this.context.initialFontSize * Exprs.defaultUnitSizes[\"ex\"]) /\n Exprs.defaultUnitSizes[\"em\"];\n break;\n case \"%\":\n px *= this.context.initialFontSize / 100;\n break;\n default: {\n const unitSize = Exprs.defaultUnitSizes[val.unit];\n if (unitSize) {\n px *= unitSize;\n }\n }\n }\n this.context.rootFontSize = px;\n }\n }\n }\n\n getTopContainerStyle(): CssCascade.ElementStyle {\n let offset = 0;\n while (!this.bodyReached) {\n offset += 5000;\n if (this.styleUntil(offset, 0) == Number.POSITIVE_INFINITY) {\n break;\n }\n }\n return this.rootStyle;\n }\n\n getAttrStyle(elem: Element): CssCascade.ElementStyle {\n // skip cases in which elements for XML other than HTML or SVG\n // have 'style' attribute not for CSS declaration\n if ((elem as any).style instanceof CSSStyleDeclaration) {\n const styleAttrValue = elem.getAttribute(\"style\");\n if (styleAttrValue) {\n return CssCascade.parseStyleAttribute(\n this.scope,\n this.validatorSet,\n this.xmldoc.url,\n styleAttrValue,\n );\n }\n }\n return {} as CssCascade.ElementStyle;\n }\n\n /**\n * @return currently reached offset\n */\n getReachedOffset(): number {\n return this.lastOffset;\n }\n\n /**\n * Replay flow elements that were encountered since the given offset\n */\n replayFlowElementsFromOffset(offset: number): void {\n if (offset >= this.lastOffset) {\n return;\n }\n const context = this.context;\n const rootOffset = this.xmldoc.getElementOffset(this.root);\n if (offset < rootOffset) {\n const rootStyle = this.getStyle(this.root, false);\n Asserts.assert(rootStyle);\n const flowName = CssCascade.getProp(rootStyle, \"flow-into\");\n const flowNameStr = flowName\n ? flowName.evaluate(context, \"flow-into\").toString()\n : \"body\";\n const newFlowChunk = this.encounteredFlowElement(\n flowNameStr,\n rootStyle,\n this.root,\n rootOffset,\n );\n if (this.boxStack.empty()) {\n this.boxStack.push(rootStyle, rootOffset, true, newFlowChunk);\n }\n }\n let node = this.xmldoc.getNodeByOffset(offset);\n let nodeOffset = this.xmldoc.getNodeOffset(node, 0, false);\n if (nodeOffset >= this.lastOffset) {\n return;\n }\n while (true) {\n if (node.nodeType != 1) {\n nodeOffset += node.textContent.length;\n } else {\n const elem = node as Element;\n if (VIVLIOSTYLE_DEBUG) {\n if (nodeOffset != this.xmldoc.getElementOffset(elem)) {\n throw new Error(\"Inconsistent offset\");\n }\n }\n const style = this.getStyle(elem, false);\n const flowName = style[\"flow-into\"];\n if (flowName) {\n const flowNameStr = flowName\n .evaluate(context, \"flow-into\")\n .toString();\n this.encounteredFlowElement(flowNameStr, style, elem, nodeOffset);\n }\n nodeOffset++;\n }\n if (nodeOffset >= this.lastOffset) {\n break;\n }\n let next: Node = node.firstChild;\n if (next == null) {\n while (true) {\n next = node.nextSibling;\n if (next) {\n break;\n }\n node = node.parentNode;\n if (node === this.root) {\n return;\n }\n }\n }\n node = next;\n }\n }\n\n resetFlowChunkStream(flowListener: FlowListener): void {\n this.flowListener = flowListener;\n for (let i = 0; i < this.flowChunks.length; i++) {\n this.flowListener.encounteredFlowChunk(\n this.flowChunks[i],\n this.flows[this.flowChunks[i].flowName],\n );\n }\n }\n\n styleUntilFlowIsReached(flowName: string) {\n this.flowToReach = flowName;\n let offset = 0;\n while (true) {\n if (this.flowToReach == null) {\n break;\n }\n offset += 5000;\n if (this.styleUntil(offset, 0) == Number.POSITIVE_INFINITY) {\n break;\n }\n }\n }\n\n styleUntilIdIsReached(id: string) {\n if (!id) {\n return;\n }\n this.idToReach = id;\n let offset = 0;\n while (true) {\n if (!this.idToReach) {\n break;\n }\n offset += 5000;\n if (this.styleUntil(offset, 0) === Number.POSITIVE_INFINITY) {\n break;\n }\n }\n this.idToReach = null;\n }\n\n private encounteredFlowElement(\n flowName: string,\n style: CssCascade.ElementStyle,\n elem: Element,\n startOffset: number,\n ): Vtree.FlowChunk {\n let priority = 0;\n let linger = Number.POSITIVE_INFINITY;\n let exclusive = false;\n let repeated = false;\n let last = false;\n const optionsCV = style[\"flow-options\"];\n if (optionsCV) {\n const options = CssProp.toSet(\n optionsCV.evaluate(this.context, \"flow-options\"),\n );\n exclusive = !!options[\"exclusive\"];\n repeated = !!options[\"static\"];\n last = !!options[\"last\"];\n }\n const lingerCV = style[\"flow-linger\"];\n if (lingerCV) {\n linger = CssProp.toInt(\n lingerCV.evaluate(this.context, \"flow-linger\"),\n Number.POSITIVE_INFINITY,\n );\n }\n const priorityCV = style[\"flow-priority\"];\n if (priorityCV) {\n priority = CssProp.toInt(\n priorityCV.evaluate(this.context, \"flow-priority\"),\n 0,\n );\n }\n const breakBefore = this.breakBeforeValues[startOffset] || null;\n let flow = this.flows[flowName];\n if (!flow) {\n const parentFlowName = this.boxStack.lastFlowName();\n flow = this.flows[flowName] = new Vtree.Flow(flowName, parentFlowName);\n }\n const flowChunk = new Vtree.FlowChunk(\n flowName,\n elem,\n startOffset,\n priority,\n linger,\n exclusive,\n repeated,\n last,\n breakBefore,\n );\n this.flowChunks.push(flowChunk);\n if (this.flowToReach == flowName) {\n this.flowToReach = null;\n }\n if (this.flowListener) {\n this.flowListener.encounteredFlowChunk(flowChunk, flow);\n }\n return flowChunk;\n }\n\n registerForcedBreakOffset(\n breakValue: string | null,\n offset: number,\n flowName: string,\n ) {\n if (Break.isForcedBreakValue(breakValue)) {\n const forcedBreakOffsets = this.flows[flowName].forcedBreakOffsets;\n if (\n forcedBreakOffsets.length === 0 ||\n forcedBreakOffsets[forcedBreakOffsets.length - 1] < offset\n ) {\n forcedBreakOffsets.push(offset);\n }\n }\n const previousValue = this.breakBeforeValues[offset];\n this.breakBeforeValues[offset] = Break.resolveEffectiveBreakValue(\n previousValue,\n breakValue,\n );\n }\n\n /**\n * @param startOffset current position in the document\n * @param lookup lookup window size for the next page\n * @return lookup offset in the document for the next page\n */\n styleUntil(startOffset: number, lookup: number): number {\n let targetSlippedOffset = -1;\n let slippedOffset: number;\n if (startOffset <= this.lastOffset) {\n slippedOffset = this.offsetMap.slippedByFixed(startOffset);\n targetSlippedOffset = slippedOffset + lookup;\n if (targetSlippedOffset < this.offsetMap.getMaxSlipped()) {\n // got to the desired point\n return this.offsetMap.fixedBySlipped(targetSlippedOffset);\n }\n }\n if (this.last == null) {\n return Number.POSITIVE_INFINITY;\n }\n const context = this.context;\n while (true) {\n let next: Node = this.last.firstChild;\n if (next == null) {\n while (true) {\n if (this.last.nodeType == 1) {\n this.cascade.popElement(this.last as Element);\n this.primary = this.primaryStack.pop();\n const box = this.boxStack.pop(this.lastOffset);\n let breakAfter: string | null = null;\n if (box.afterBox) {\n const afterPseudoBreakBefore = box.afterBox.getBreakValue(\n \"before\",\n );\n this.registerForcedBreakOffset(\n afterPseudoBreakBefore,\n box.afterBox.atBlockStart\n ? this.boxStack.nearestBlockStartOffset(box)\n : box.afterBox.offset,\n box.flowName,\n );\n breakAfter = box.afterBox.getBreakValue(\"after\");\n }\n breakAfter = Break.resolveEffectiveBreakValue(\n breakAfter,\n box.getBreakValue(\"after\"),\n );\n this.registerForcedBreakOffset(\n breakAfter,\n this.lastOffset,\n box.flowName,\n );\n }\n next = this.last.nextSibling;\n if (next) {\n break;\n }\n this.last = this.last.parentNode;\n if (this.last === this.root) {\n this.last = null;\n if (startOffset < this.lastOffset) {\n if (targetSlippedOffset < 0) {\n slippedOffset = this.offsetMap.slippedByFixed(startOffset);\n targetSlippedOffset = slippedOffset + lookup;\n }\n if (targetSlippedOffset <= this.offsetMap.getMaxSlipped()) {\n // got to the desired point\n return this.offsetMap.fixedBySlipped(targetSlippedOffset);\n }\n }\n return Number.POSITIVE_INFINITY;\n }\n }\n }\n this.last = next;\n if (this.last.nodeType != 1) {\n this.lastOffset += this.last.textContent.length;\n this.boxStack.encounteredTextNode(this.last);\n if (this.primary) {\n this.offsetMap.addStuckRange(this.lastOffset);\n } else {\n this.offsetMap.addSlippedRange(this.lastOffset);\n }\n } else {\n const elem = this.last as Element;\n const style = this.getAttrStyle(elem);\n this.primaryStack.push(this.primary);\n this.cascade.pushElement(elem, style, this.lastOffset);\n const id =\n elem.getAttribute(\"id\") || elem.getAttributeNS(Base.NS.XML, \"id\");\n if (id && id === this.idToReach) {\n this.idToReach = null;\n }\n if (\n !this.bodyReached &&\n elem.localName == \"body\" &&\n elem.parentNode == this.root\n ) {\n this.postprocessTopStyle(style, true);\n this.bodyReached = true;\n }\n let box: Box;\n const flowName = style[\"flow-into\"];\n if (flowName) {\n const flowNameStr = flowName\n .evaluate(context, \"flow-into\")\n .toString();\n const newFlowChunk = this.encounteredFlowElement(\n flowNameStr,\n style,\n elem,\n this.lastOffset,\n );\n this.primary = !!this.primaryFlows[flowNameStr];\n box = this.boxStack.push(\n style,\n this.lastOffset,\n elem === this.root,\n newFlowChunk,\n );\n } else {\n box = this.boxStack.push(style, this.lastOffset, elem === this.root);\n }\n const blockStartOffset = this.boxStack.nearestBlockStartOffset(box);\n this.registerForcedBreakOffset(\n box.breakBefore,\n blockStartOffset,\n box.flowName,\n );\n if (box.beforeBox) {\n const beforePseudoBreakAfter = box.beforeBox.getBreakValue(\"after\");\n this.registerForcedBreakOffset(\n beforePseudoBreakAfter,\n box.beforeBox.atBlockStart ? blockStartOffset : box.offset,\n box.flowName,\n );\n }\n if (this.primary) {\n if (box.displayValue() === Css.ident.none) {\n this.primary = false;\n }\n }\n if (VIVLIOSTYLE_DEBUG) {\n const offset = this.xmldoc.getElementOffset(this.last as Element);\n if (offset != this.lastOffset) {\n throw new Error(\"Inconsistent offset\");\n }\n }\n this.styleMap[`e${this.lastOffset}`] = style;\n this.lastOffset++;\n if (this.primary) {\n this.offsetMap.addStuckRange(this.lastOffset);\n } else {\n this.offsetMap.addSlippedRange(this.lastOffset);\n }\n if (startOffset < this.lastOffset) {\n if (targetSlippedOffset < 0) {\n slippedOffset = this.offsetMap.slippedByFixed(startOffset);\n targetSlippedOffset = slippedOffset + lookup;\n }\n if (targetSlippedOffset <= this.offsetMap.getMaxSlipped()) {\n // got to the desired point\n return this.offsetMap.fixedBySlipped(targetSlippedOffset);\n }\n }\n }\n }\n }\n\n /**\n * @override\n */\n getStyle(element: Element, deep: boolean): CssCascade.ElementStyle {\n let offset = this.xmldoc.getElementOffset(element);\n const key = `e${offset}`;\n if (deep) {\n offset = this.xmldoc.getNodeOffset(element, 0, true);\n }\n if (this.lastOffset <= offset) {\n this.styleUntil(offset, 0);\n }\n return this.styleMap[key];\n }\n\n /**\n * @override\n */\n processContent(element: Element, styles: { [key: string]: Css.Val }) {}\n}\n\nexport const columnProps = [\"column-count\", \"column-width\", \"column-fill\"];\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssValidator - Parse validation rules (validation.txt), validate\n * properties and shorthands.\n */\nimport * as Css from \"./css\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Logging from \"./logging\";\nimport ValidationTxt from \"./assets/validation.txt\";\n\nexport interface PropertyReceiver {\n unknownProperty(name: string, value: Css.Val): void;\n\n invalidPropertyValue(name: string, value: Css.Val): void;\n\n simpleProperty(name: string, value: Css.Val, important): void;\n}\n\nexport class Node {\n success: Node = null;\n failure: Node = null;\n code: number = 0;\n\n constructor(public validator: PropertyValidator) {}\n\n isSpecial(): boolean {\n return this.code != 0;\n }\n\n markAsStartGroup(): void {\n this.code = -1;\n }\n\n isStartGroup(): boolean {\n return this.code == -1;\n }\n\n markAsEndGroup(): void {\n this.code = -2;\n }\n\n isEndGroup(): boolean {\n return this.code == -2;\n }\n\n markAsStartAlternate(index: number): void {\n this.code = 2 * index + 1;\n }\n\n isStartAlternate(): boolean {\n return this.code > 0 && this.code % 2 != 0;\n }\n\n markAsEndAlternate(index: number): void {\n this.code = 2 * index + 2;\n }\n\n isEndAlternate(): boolean {\n return this.code > 0 && this.code % 2 == 0;\n }\n\n getAlternate(): number {\n return Math.floor((this.code - 1) / 2);\n }\n}\n\nexport class Connection {\n what: number = -1;\n\n constructor(public where: number, public success: boolean) {}\n}\n\n/**\n * @enum {number}\n */\nexport enum Add {\n FOLLOW = 1,\n OPTIONAL,\n REPEATED,\n ALTERNATE,\n}\n\n/**\n * A class to build a list validator from other validators.\n */\nexport class ValidatingGroup {\n nodes: Node[] = [];\n connections: Connection[] = [];\n match: number[] = []; // connector indicies\n nomatch: number[] = []; // connector indicies\n error: number[] = []; // connector indicies\n emptyHead: boolean = true;\n\n connect(arr: number[], nodeIndex: number): void {\n for (let i = 0; i < arr.length; i++) {\n this.connections[arr[i]].what = nodeIndex;\n }\n arr.splice(0, arr.length);\n }\n\n clone(): ValidatingGroup {\n const group = new ValidatingGroup();\n for (let i = 0; i < this.nodes.length; i++) {\n const node = this.nodes[i];\n const clonedNode = new Node(node.validator);\n clonedNode.code = node.code;\n group.nodes.push(clonedNode);\n }\n for (let i = 0; i < this.connections.length; i++) {\n const connection = this.connections[i];\n const groupConnection = new Connection(\n connection.where,\n connection.success,\n );\n groupConnection.what = connection.what;\n group.connections.push(groupConnection);\n }\n group.match.push(...this.match);\n group.nomatch.push(...this.nomatch);\n group.error.push(...this.error);\n return group;\n }\n\n /**\n * Add \"special\" validation node to a given array (match, nomatch, or error).\n * @param start if this a start or the end of a clause/group\n * @param clause 0 indicates group start/end, otherwise clause index\n */\n private addSpecialToArr(arr: number[], start: boolean, clause: number): void {\n const index = this.nodes.length;\n const node = new Node(ALWAYS_FAIL);\n if (clause >= 0) {\n if (start) {\n node.markAsStartAlternate(clause);\n } else {\n node.markAsEndAlternate(clause);\n }\n } else {\n if (start) {\n node.markAsStartGroup();\n } else {\n node.markAsEndGroup();\n }\n }\n this.nodes.push(node);\n this.connect(arr, index);\n const success = new Connection(index, true);\n const failure = new Connection(index, false);\n arr.push(this.connections.length);\n this.connections.push(failure);\n arr.push(this.connections.length);\n this.connections.push(success);\n }\n\n endSpecialGroup(): void {\n const arrs = [this.match, this.nomatch, this.error];\n for (let i = 0; i < arrs.length; i++) {\n this.addSpecialToArr(arrs[i], false, -1);\n }\n }\n\n startSpecialGroup(): void {\n if (this.nodes.length) {\n throw new Error(\"invalid call\");\n }\n this.addSpecialToArr(this.match, true, -1);\n }\n\n endClause(clause: number): void {\n this.addSpecialToArr(this.match, false, clause);\n }\n\n startClause(clause: number): void {\n if (this.nodes.length) {\n throw new Error(\"invalid call\");\n }\n const node = new Node(ALWAYS_FAIL);\n node.markAsStartAlternate(clause);\n this.nodes.push(node);\n const success = new Connection(0, true);\n const failure = new Connection(0, false);\n this.nomatch.push(this.connections.length);\n this.connections.push(failure);\n this.match.push(this.connections.length);\n this.connections.push(success);\n }\n\n addPrimitive(validator: PropertyValidator): void {\n const index = this.nodes.length;\n this.nodes.push(new Node(validator));\n const success = new Connection(index, true);\n const failure = new Connection(index, false);\n this.connect(this.match, index);\n if (this.emptyHead) {\n // if did not validate -> no match\n this.nomatch.push(this.connections.length);\n this.emptyHead = false;\n } else {\n // if did not validate -> failure\n this.error.push(this.connections.length);\n }\n this.connections.push(failure);\n this.match.push(this.connections.length);\n this.connections.push(success);\n }\n\n isSimple(): boolean {\n return this.nodes.length == 1 && !this.nodes[0].isSpecial();\n }\n\n isPrimitive(): boolean {\n return (\n this.isSimple() && this.nodes[0].validator instanceof PrimitiveValidator\n );\n }\n\n addGroup(group: ValidatingGroup, how: Add): void {\n if (group.nodes.length == 0) {\n return;\n }\n const index = this.nodes.length;\n\n // optimization for alternate primitive validators\n if (\n how == Add.ALTERNATE &&\n index == 1 &&\n group.isPrimitive() &&\n this.isPrimitive()\n ) {\n this.nodes[0].validator = (this.nodes[0]\n .validator as PrimitiveValidator).combine(\n group.nodes[0].validator as PrimitiveValidator,\n );\n return;\n }\n for (let i = 0; i < group.nodes.length; i++) {\n this.nodes.push(group.nodes[i]);\n }\n\n // nodes[index] is group start\n if (how == Add.ALTERNATE) {\n this.emptyHead = true;\n this.connect(this.nomatch, index);\n } else {\n this.connect(this.match, index);\n }\n const connectionIndex = this.connections.length;\n for (let i = 0; i < group.connections.length; i++) {\n const connection = group.connections[i];\n connection.where += index;\n if (connection.what >= 0) {\n connection.what += index;\n }\n this.connections.push(connection);\n }\n for (let i = 0; i < group.match.length; i++) {\n this.match.push(group.match[i] + connectionIndex);\n }\n if (how == Add.REPEATED) {\n this.connect(this.match, index);\n }\n if (how == Add.OPTIONAL || how == Add.REPEATED) {\n for (let i = 0; i < group.nomatch.length; i++) {\n this.match.push(group.nomatch[i] + connectionIndex);\n }\n } else if (this.emptyHead) {\n for (let i = 0; i < group.nomatch.length; i++) {\n this.nomatch.push(group.nomatch[i] + connectionIndex);\n }\n this.emptyHead = group.emptyHead;\n } else {\n for (let i = 0; i < group.nomatch.length; i++) {\n this.error.push(group.nomatch[i] + connectionIndex);\n }\n }\n for (let i = 0; i < group.error.length; i++) {\n this.error.push(group.error[i] + connectionIndex);\n }\n\n // invalidate group\n group.nodes = null;\n group.connections = null;\n }\n\n /**\n * @return how\n */\n finish(successTerminal: Node, failTerminal: Node): Node {\n const index = this.nodes.length;\n this.nodes.push(successTerminal);\n this.nodes.push(failTerminal);\n this.connect(this.match, index);\n this.connect(this.nomatch, index + 1);\n this.connect(this.error, index + 1);\n for (const connection of this.connections) {\n if (connection.success) {\n this.nodes[connection.where].success = this.nodes[connection.what];\n } else {\n this.nodes[connection.where].failure = this.nodes[connection.what];\n }\n }\n\n // make sure that our data structure is correct\n for (let j = 0; j < index; j++) {\n if (this.nodes[j].failure == null || this.nodes[j].success == null) {\n throw new Error(\"Invalid validator state\");\n }\n }\n return this.nodes[0];\n }\n}\n\nexport const ALLOW_EMPTY = 1;\n\nexport const ALLOW_STR = 2;\n\nexport const ALLOW_IDENT = 4;\n\nexport const ALLOW_POS_NUMERIC = 8;\n\nexport const ALLOW_POS_NUM = 16;\n\nexport const ALLOW_POS_INT = 32;\n\nexport const ALLOW_COLOR = 64;\n\nexport const ALLOW_URL = 128;\n\nexport const ALLOW_NEGATIVE = 256;\n\nexport const ALLOW_ZERO = 512;\n\nexport const ALLOW_ZERO_PERCENT = 1024;\n\nexport const ALLOW_SLASH = 2048;\n\nexport type ValueMap = {\n [key: string]: Css.Val;\n};\n\n/**\n * Abstract class to validate simple CSS property value (not a shorthand)\n */\nexport class PropertyValidator extends Css.Visitor {\n constructor() {\n super();\n }\n\n /**\n * Validate a subsequence of the given values from the given index. Return the\n * list of matched values or null if there is no match.\n */\n validateForShorthand(values: Css.Val[], index: number): Css.Val[] {\n const rval = values[index].visit(this);\n if (rval) {\n return [rval];\n }\n return null;\n }\n}\n\n/**\n * Validate a primitive CSS value (not a list or function).\n * @param allowed mask of ALLOW_*** constants.\n */\nexport class PrimitiveValidator extends PropertyValidator {\n constructor(\n public readonly allowed: number,\n public readonly idents: ValueMap,\n public readonly units: ValueMap,\n ) {\n super();\n }\n\n /**\n * @override\n */\n visitEmpty(empty: Css.Val): Css.Val {\n if (this.allowed & ALLOW_EMPTY) {\n return empty;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitSlash(slash: Css.Val): Css.Val {\n if (this.allowed & ALLOW_SLASH) {\n return slash;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitStr(str: Css.Str): Css.Val {\n if (this.allowed & ALLOW_STR) {\n return str;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n const val = this.idents[ident.name.toLowerCase()];\n if (val) {\n return val;\n }\n if (this.allowed & ALLOW_IDENT) {\n return ident;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n if (numeric.num == 0 && !(this.allowed & ALLOW_ZERO)) {\n if (numeric.unit == \"%\" && this.allowed & ALLOW_ZERO_PERCENT) {\n return numeric;\n }\n return null;\n }\n if (numeric.num < 0 && !(this.allowed & ALLOW_NEGATIVE)) {\n return null;\n }\n if (this.units[numeric.unit]) {\n return numeric;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n if (num.num == 0) {\n return this.allowed & ALLOW_ZERO ? num : null;\n }\n if (num.num <= 0 && !(this.allowed & ALLOW_NEGATIVE)) {\n return null;\n }\n if (this.allowed & ALLOW_POS_NUM) {\n return num;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n if (num.num == 0) {\n return this.allowed & ALLOW_ZERO ? num : null;\n }\n if (num.num <= 0 && !(this.allowed & ALLOW_NEGATIVE)) {\n return null;\n }\n if (this.allowed & (ALLOW_POS_INT | ALLOW_POS_NUM)) {\n return num;\n }\n const val = this.idents[`${num.num}`];\n if (val) {\n return val;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitColor(color: Css.Color): Css.Val {\n if (this.allowed & ALLOW_COLOR) {\n return color;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitURL(url: Css.URL): Css.Val {\n if (this.allowed & ALLOW_URL) {\n return url;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n if (this.allowed & 0x7fe) {\n // ALLOW_STR|ALLOW_IDENT|...|ALLOW_ZERO_PERCENT\n return expr;\n }\n return null;\n }\n\n combine(other: PrimitiveValidator): PrimitiveValidator {\n const idents: ValueMap = {};\n const units: ValueMap = {};\n for (const ident in this.idents) {\n idents[ident] = this.idents[ident];\n }\n for (const ident in other.idents) {\n idents[ident] = other.idents[ident];\n }\n for (const unit in this.units) {\n units[unit] = this.units[unit];\n }\n for (const unit in other.units) {\n units[unit] = other.units[unit];\n }\n return new PrimitiveValidator(this.allowed | other.allowed, idents, units);\n }\n}\n\nconst NO_IDENTS = {};\n\nexport const ALWAYS_FAIL = new PrimitiveValidator(0, NO_IDENTS, NO_IDENTS);\n\n/**\n * Base class for list validation.\n */\nexport class ListValidator extends PropertyValidator {\n successTerminal: Node;\n failureTerminal: Node;\n first: Node;\n\n constructor(group: ValidatingGroup) {\n super();\n this.successTerminal = new Node(null);\n this.failureTerminal = new Node(null);\n this.first = group.finish(this.successTerminal, this.failureTerminal);\n }\n\n validateList(arr: Css.Val[], slice: boolean, startIndex: number): Css.Val[] {\n let out: Css.Val[] = slice ? [] : arr;\n let current = this.first;\n let index = startIndex;\n let alternativeStack: string[][] = null;\n let alternatives: string[] = null;\n while (\n current !== this.successTerminal &&\n current !== this.failureTerminal\n ) {\n if (index >= arr.length) {\n current = current.failure;\n continue;\n }\n const inval = arr[index];\n let outval = inval;\n if (current.isSpecial()) {\n let success = true;\n if (current.isStartGroup()) {\n if (alternativeStack) {\n alternativeStack.push(alternatives);\n } else {\n alternativeStack = [alternatives];\n }\n alternatives = [];\n } else if (current.isEndGroup()) {\n if (alternativeStack.length > 0) {\n alternatives = alternativeStack.pop();\n } else {\n alternatives = null;\n }\n } else if (current.isEndAlternate()) {\n alternatives[current.getAlternate()] = \"taken\";\n } else {\n success = alternatives[current.getAlternate()] == null;\n }\n current = success ? current.success : current.failure;\n } else {\n if (\n index == 0 &&\n !slice &&\n current.validator instanceof SpaceListValidator &&\n this instanceof SpaceListValidator\n ) {\n // Special nesting case: validate the input space list as a whole.\n outval = new Css.SpaceList(arr).visit(current.validator);\n if (outval) {\n index = arr.length;\n current = current.success;\n continue;\n }\n } else if (\n index == 0 &&\n !slice &&\n current.validator instanceof CommaListValidator &&\n this instanceof SpaceListValidator\n ) {\n // Special nesting case: validate the input comma list as a whole.\n outval = new Css.CommaList(arr).visit(current.validator);\n if (outval) {\n index = arr.length;\n current = current.success;\n continue;\n }\n } else {\n outval = inval.visit(current.validator);\n }\n if (!outval) {\n current = current.failure;\n continue;\n }\n if (outval !== inval && arr === out) {\n // startIndex is zero here\n out = [];\n for (let k = 0; k < index; k++) {\n out[k] = arr[k];\n }\n }\n if (arr !== out) {\n out[index - startIndex] = outval;\n }\n index++;\n current = current.success;\n }\n }\n if (current === this.successTerminal) {\n if (slice ? out.length > 0 : index == arr.length) {\n return out;\n }\n }\n return null;\n }\n\n validateSingle(inval: Css.Val): Css.Val {\n // no need to worry about \"specials\"\n let outval: Css.Val = null;\n let current = this.first;\n while (\n current !== this.successTerminal &&\n current !== this.failureTerminal\n ) {\n if (!inval) {\n current = current.failure;\n continue;\n }\n if (current.isSpecial()) {\n current = current.success;\n continue;\n }\n outval = inval.visit(current.validator);\n if (!outval) {\n current = current.failure;\n continue;\n }\n inval = null;\n current = current.success;\n }\n if (current === this.successTerminal) {\n return outval;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitEmpty(empty: Css.Val): Css.Val {\n return this.validateSingle(empty);\n }\n\n /**\n * @override\n */\n visitSlash(slash: Css.Val): Css.Val {\n return this.validateSingle(slash);\n }\n\n /**\n * @override\n */\n visitStr(str: Css.Str): Css.Val {\n return this.validateSingle(str);\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n return this.validateSingle(ident);\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n return this.validateSingle(numeric);\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitColor(color: Css.Color): Css.Val {\n return this.validateSingle(color);\n }\n\n /**\n * @override\n */\n visitURL(url: Css.URL): Css.Val {\n return this.validateSingle(url);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n return this.validateSingle(func);\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n return null;\n }\n}\n\nexport class SpaceListValidator extends ListValidator {\n constructor(group: ValidatingGroup) {\n super(group);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n const arr = this.validateList(list.values, false, 0);\n if (arr === list.values) {\n return list;\n }\n if (!arr) {\n return null;\n }\n return new Css.SpaceList(arr);\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n // Special Case : Issue #156\n let node = this.first;\n let hasCommaListValidator = false;\n while (node) {\n if (node.validator instanceof CommaListValidator) {\n hasCommaListValidator = true;\n break;\n }\n node = node.failure;\n }\n if (hasCommaListValidator) {\n const arr = this.validateList(list.values, false, 0);\n if (arr === list.values) {\n return list;\n }\n if (!arr) {\n return null;\n }\n return new Css.CommaList(arr);\n }\n return null;\n }\n\n /**\n * @override\n */\n validateForShorthand(values: Css.Val[], index: number): Css.Val[] {\n return this.validateList(values, true, index);\n }\n}\n\nexport class CommaListValidator extends ListValidator {\n constructor(group: ValidatingGroup) {\n super(group);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n return this.validateSingle(list);\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n const arr = this.validateList(list.values, false, 0);\n if (arr === list.values) {\n return list;\n }\n if (!arr) {\n return null;\n }\n return new Css.CommaList(arr);\n }\n\n /**\n * @override\n */\n validateForShorthand(values: Css.Val[], index: number): Css.Val[] {\n let current = this.first;\n let rval: Css.Val[];\n while (current !== this.failureTerminal) {\n rval = current.validator.validateForShorthand(values, index);\n if (rval) {\n return rval;\n }\n current = current.failure;\n }\n return null;\n }\n}\n\nexport class FuncValidator extends ListValidator {\n constructor(public readonly name: string, group: ValidatingGroup) {\n super(group);\n }\n\n /**\n * @override\n */\n validateSingle(inval: Css.Val): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n if (func.name.toLowerCase() != this.name) {\n return null;\n }\n const arr = this.validateList(func.values, false, 0);\n if (arr === func.values) {\n return func;\n }\n if (!arr) {\n return null;\n }\n return new Css.Func(func.name, arr);\n }\n}\n\n//----------------------- Shorthands\n//------------------------------------------------------------\nexport class ShorthandSyntaxNode {\n /**\n * @return new index.\n */\n tryParse(\n values: Css.Val[],\n index: number,\n shorthandValidator: ShorthandValidator,\n ): number {\n return index;\n }\n\n success(rval: Css.Val, shorthandValidator: ShorthandValidator): void {}\n}\n\nexport class ShorthandSyntaxProperty extends ShorthandSyntaxNode {\n validator: PropertyValidator;\n\n constructor(validatorSet: ValidatorSet, public readonly name: string) {\n super();\n this.validator = validatorSet.validators[this.name];\n }\n\n /**\n * @override\n */\n tryParse(\n values: Css.Val[],\n index: number,\n shorthandValidator: ShorthandValidator,\n ): number {\n if (shorthandValidator.values[this.name]) {\n return index;\n }\n const rvals = this.validator.validateForShorthand(values, index);\n if (rvals) {\n const len = rvals.length;\n const rval = len > 1 ? new Css.SpaceList(rvals) : rvals[0];\n this.success(rval, shorthandValidator);\n return index + len;\n }\n return index;\n }\n\n /**\n * @override\n */\n success(rval: Css.Val, shorthandValidator: ShorthandValidator): void {\n shorthandValidator.values[this.name] = rval;\n }\n}\n\nexport class ShorthandSyntaxPropertyN extends ShorthandSyntaxProperty {\n constructor(validatorSet: ValidatorSet, public readonly names: string[]) {\n super(validatorSet, names[0]);\n }\n\n /**\n * @override\n */\n success(rval: Css.Val, shorthandValidator: ShorthandValidator): void {\n for (let i = 0; i < this.names.length; i++) {\n shorthandValidator.values[this.names[i]] = rval;\n }\n }\n}\n\nexport class ShorthandSyntaxCompound extends ShorthandSyntaxNode {\n constructor(\n public readonly nodes: ShorthandSyntaxNode[],\n public readonly slash: boolean,\n ) {\n super();\n }\n\n /**\n * @override\n */\n tryParse(\n values: Css.Val[],\n index: number,\n shorthandValidator: ShorthandValidator,\n ): number {\n const index0 = index;\n if (this.slash) {\n if (values[index] == Css.slash) {\n if (++index == values.length) {\n return index0;\n }\n } else {\n return index0;\n }\n }\n let newIndex = this.nodes[0].tryParse(values, index, shorthandValidator);\n if (newIndex == index) {\n return index0;\n }\n index = newIndex;\n for (let i = 1; i < this.nodes.length && index < values.length; i++) {\n newIndex = this.nodes[i].tryParse(values, index, shorthandValidator);\n if (newIndex == index) {\n break;\n }\n index = newIndex;\n }\n return index;\n }\n}\n\nexport class ShorthandValidator extends Css.Visitor {\n syntax: ShorthandSyntaxNode[] = null;\n propList: string[] = null;\n error: boolean = false;\n values: ValueMap = {};\n validatorSet: ValidatorSet = null;\n\n setOwner(validatorSet: ValidatorSet) {\n this.validatorSet = validatorSet;\n }\n\n syntaxNodeForProperty(name: string): ShorthandSyntaxNode {\n return new ShorthandSyntaxProperty(this.validatorSet, name);\n }\n\n clone(): this {\n const other = new (this.constructor as any)();\n other.syntax = this.syntax;\n other.propList = this.propList;\n other.validatorSet = this.validatorSet;\n return other;\n }\n\n init(syntax: ShorthandSyntaxNode[], propList: string[]): void {\n this.syntax = syntax;\n this.propList = propList;\n }\n\n finish(important: boolean, receiver: PropertyReceiver): boolean {\n if (!this.error) {\n for (const name of this.propList) {\n receiver.simpleProperty(\n name,\n this.values[name] || this.validatorSet.defaultValues[name],\n important,\n );\n }\n return true;\n }\n return false;\n }\n\n propagateInherit(important: boolean, receiver: PropertyReceiver): void {\n for (const name of this.propList) {\n receiver.simpleProperty(name, Css.ident.inherit, important);\n }\n }\n\n validateList(list: Css.Val[]): number {\n this.error = true;\n return 0;\n }\n\n validateSingle(val: Css.Val): Css.Val {\n this.validateList([val]);\n return null;\n }\n\n /**\n * @override\n */\n visitEmpty(empty: Css.Val): Css.Val {\n return this.validateSingle(empty);\n }\n\n /**\n * @override\n */\n visitStr(str: Css.Str): Css.Val {\n return this.validateSingle(str);\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n return this.validateSingle(ident);\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n return this.validateSingle(numeric);\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitColor(color: Css.Color): Css.Val {\n return this.validateSingle(color);\n }\n\n /**\n * @override\n */\n visitURL(url: Css.URL): Css.Val {\n return this.validateSingle(url);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.validateList(list.values);\n return null;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n this.error = true;\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n return this.validateSingle(func);\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n this.error = true;\n return null;\n }\n}\n\nexport class SimpleShorthandValidator extends ShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n let index = 0;\n let i = 0;\n while (index < list.length) {\n const newIndex = this.syntax[i].tryParse(list, index, this);\n if (newIndex > index) {\n index = newIndex;\n i = 0;\n continue;\n }\n if (++i == this.syntax.length) {\n this.error = true;\n break;\n }\n }\n return index;\n }\n}\n\nexport class InsetsShorthandValidator extends ShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n if (list.length > this.syntax.length || list.length == 0) {\n this.error = true;\n return 0;\n }\n for (let i = 0; i < this.syntax.length; i++) {\n let index = i;\n while (index >= list.length) {\n index = index == 1 ? 0 : index - 2;\n }\n if (this.syntax[i].tryParse(list, index, this) != index + 1) {\n this.error = true;\n return 0;\n }\n }\n return list.length;\n }\n\n createSyntaxNode(): ShorthandSyntaxPropertyN {\n return new ShorthandSyntaxPropertyN(this.validatorSet, this.propList);\n }\n}\n\nexport class InsetsSlashShorthandValidator extends ShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n let slashIndex = list.length;\n for (let i = 0; i < list.length; i++) {\n if (list[i] === Css.slash) {\n slashIndex = i;\n break;\n }\n }\n if (slashIndex > this.syntax.length || list.length == 0) {\n this.error = true;\n return 0;\n }\n for (let i = 0; i < this.syntax.length; i++) {\n let index0 = i;\n while (index0 >= slashIndex) {\n index0 = index0 == 1 ? 0 : index0 - 2;\n }\n let index1: number;\n if (slashIndex + 1 < list.length) {\n index1 = slashIndex + i + 1;\n while (index1 >= list.length) {\n index1 = index1 - (index1 == slashIndex + 2 ? 1 : 2);\n }\n } else {\n index1 = index0;\n }\n const vals = [list[index0], list[index1]];\n if (this.syntax[i].tryParse(vals, 0, this) != 2) {\n this.error = true;\n return 0;\n }\n }\n return list.length;\n }\n}\n\nexport class CommaShorthandValidator extends SimpleShorthandValidator {\n constructor() {\n super();\n }\n\n mergeIn(acc: { [key: string]: Css.Val[] }, values: ValueMap) {\n for (const name of this.propList) {\n const val = values[name] || this.validatorSet.defaultValues[name];\n let arr = acc[name];\n if (!arr) {\n arr = [];\n acc[name] = arr;\n }\n arr.push(val);\n }\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n const acc: { [key: string]: Css.Val[] } = {};\n for (let i = 0; i < list.values.length; i++) {\n this.values = {};\n if (list.values[i] instanceof Css.CommaList) {\n this.error = true;\n } else {\n list.values[i].visit(this);\n this.mergeIn(acc, this.values);\n if (this.values[\"background-color\"] && i != list.values.length - 1) {\n this.error = true;\n }\n }\n if (this.error) {\n return null;\n }\n }\n this.values = {};\n for (const name in acc) {\n if (name == \"background-color\") {\n this.values[name] = acc[name].pop();\n } else {\n this.values[name] = new Css.CommaList(acc[name]);\n }\n }\n return null;\n }\n}\n\nexport class FontShorthandValidator extends SimpleShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n init(syntax: ShorthandSyntaxNode[], propList: string[]): void {\n super.init(syntax, propList);\n this.propList.push(\"font-family\", \"line-height\", \"font-size\");\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n let index = super.validateList(list);\n\n // must at least have font-size and font-family at the end\n if (index + 2 > list.length) {\n this.error = true;\n return index;\n }\n this.error = false;\n const validators = this.validatorSet.validators;\n if (!list[index].visit(validators[\"font-size\"])) {\n this.error = true;\n return index;\n }\n this.values[\"font-size\"] = list[index++];\n if (list[index] === Css.slash) {\n index++;\n\n // must at least have line-height and font-family at the end\n if (index + 2 > list.length) {\n this.error = true;\n return index;\n }\n if (!list[index].visit(validators[\"line-height\"])) {\n this.error = true;\n return index;\n }\n this.values[\"line-height\"] = list[index++];\n }\n const fontFamily =\n index == list.length - 1\n ? list[index]\n : new Css.SpaceList(list.slice(index, list.length));\n if (!fontFamily.visit(validators[\"font-family\"])) {\n this.error = true;\n return index;\n }\n this.values[\"font-family\"] = fontFamily;\n return list.length;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n list.values[0].visit(this);\n if (this.error) {\n return null;\n }\n const familyList = [this.values[\"font-family\"]];\n for (let i = 1; i < list.values.length; i++) {\n familyList.push(list.values[i]);\n }\n const family = new Css.CommaList(familyList);\n if (!family.visit(this.validatorSet.validators[\"font-family\"])) {\n this.error = true;\n } else {\n this.values[\"font-family\"] = family;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n const props = this.validatorSet.systemFonts[ident.name];\n if (props) {\n for (const name in props) {\n this.values[name] = props[name];\n }\n } else {\n this.error = true;\n }\n return null;\n }\n}\n\nexport const shorthandValidators: {\n [key: string]: typeof ShorthandValidator;\n} = {\n SIMPLE: SimpleShorthandValidator,\n INSETS: InsetsShorthandValidator,\n INSETS_SLASH: InsetsSlashShorthandValidator,\n COMMA: CommaShorthandValidator,\n FONT: FontShorthandValidator,\n};\n\n//---- validation grammar parser and public property validator\n//------------------------\n\n/**\n * Object that validates simple and shorthand properties, breaking up shorthand\n * properties into corresponding simple ones, also stripping property prefixes.\n */\nexport class ValidatorSet {\n validators: { [key: string]: PropertyValidator } = {};\n prefixes: { [key: string]: { [key: string]: boolean } } = {};\n defaultValues: ValueMap = {};\n namedValidators: { [key: string]: ValidatingGroup } = {};\n systemFonts: { [key: string]: ValueMap } = {};\n shorthands: { [key: string]: ShorthandValidator } = {};\n layoutProps: ValueMap = {};\n backgroundProps: ValueMap = {};\n\n private addReplacement(\n val: ValidatingGroup,\n token: CssTokenizer.Token,\n ): ValidatingGroup {\n let cssval: Css.Val;\n if (token.type == CssTokenizer.TokenType.NUMERIC) {\n cssval = new Css.Numeric(token.num, token.text);\n } else if (token.type == CssTokenizer.TokenType.HASH) {\n cssval = CssParser.colorFromHash(token.text);\n } else if (token.type == CssTokenizer.TokenType.IDENT) {\n cssval = Css.getName(token.text);\n } else {\n throw new Error(\"unexpected replacement\");\n }\n if (val.isPrimitive()) {\n const validator = val.nodes[0].validator as PrimitiveValidator;\n const idents = validator.idents;\n for (const ident in idents) {\n idents[ident] = cssval;\n }\n return val;\n }\n throw new Error(\"unexpected replacement\");\n }\n\n private newGroup(op: string, vals: ValidatingGroup[]): ValidatingGroup {\n const group = new ValidatingGroup();\n if (op == \"||\") {\n for (let i = 0; i < vals.length; i++) {\n const subgroup = new ValidatingGroup();\n subgroup.startClause(i);\n subgroup.addGroup(vals[i], Add.FOLLOW);\n subgroup.endClause(i);\n group.addGroup(subgroup, i == 0 ? Add.FOLLOW : Add.ALTERNATE);\n }\n const outer = new ValidatingGroup();\n outer.startSpecialGroup();\n outer.addGroup(group, Add.REPEATED);\n outer.endSpecialGroup();\n return outer;\n } else {\n let how: Add;\n switch (op) {\n case \" \":\n how = Add.FOLLOW;\n break;\n case \"|\":\n case \"||\":\n how = Add.ALTERNATE;\n break;\n default:\n throw new Error(\"unexpected op\");\n }\n for (let i = 0; i < vals.length; i++) {\n group.addGroup(vals[i], i == 0 ? Add.FOLLOW : how);\n }\n return group;\n }\n }\n\n private addCounts(\n val: ValidatingGroup,\n min: number,\n max: number,\n ): ValidatingGroup {\n const group = new ValidatingGroup();\n for (let i = 0; i < min; i++) {\n group.addGroup(val.clone(), Add.FOLLOW);\n }\n if (max == Number.POSITIVE_INFINITY) {\n group.addGroup(val, Add.REPEATED);\n } else {\n for (let i = min; i < max; i++) {\n group.addGroup(val.clone(), Add.OPTIONAL);\n }\n }\n return group;\n }\n\n private primitive(validator: PropertyValidator): ValidatingGroup {\n const group = new ValidatingGroup();\n group.addPrimitive(validator);\n return group;\n }\n\n private newFunc(fn: string, val: ValidatingGroup): ValidatingGroup {\n let validator: PropertyValidator;\n switch (fn) {\n case \"COMMA\":\n validator = new CommaListValidator(val);\n break;\n case \"SPACE\":\n validator = new SpaceListValidator(val);\n break;\n default:\n validator = new FuncValidator(fn.toLowerCase(), val);\n break;\n }\n return this.primitive(validator);\n }\n\n initBuiltInValidators(): void {\n this.namedValidators[\"HASHCOLOR\"] = this.primitive(\n new PrimitiveValidator(ALLOW_COLOR, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_INT\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_INT, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_NUM\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUM, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_PERCENTAGE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, { \"%\": Css.empty }),\n );\n this.namedValidators[\"NEGATIVE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_NEGATIVE, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"ZERO\"] = this.primitive(\n new PrimitiveValidator(ALLOW_ZERO, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"ZERO_PERCENTAGE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_ZERO_PERCENT, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_LENGTH\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n em: Css.empty,\n ex: Css.empty,\n ch: Css.empty,\n rem: Css.empty,\n vw: Css.empty,\n vh: Css.empty,\n vi: Css.empty,\n vb: Css.empty,\n vmin: Css.empty,\n vmax: Css.empty,\n pvw: Css.empty,\n pvh: Css.empty,\n pvi: Css.empty,\n pvb: Css.empty,\n pvmin: Css.empty,\n pvmax: Css.empty,\n cm: Css.empty,\n mm: Css.empty,\n in: Css.empty,\n px: Css.empty,\n pt: Css.empty,\n pc: Css.empty,\n q: Css.empty,\n }),\n );\n this.namedValidators[\"POS_ANGLE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n deg: Css.empty,\n grad: Css.empty,\n rad: Css.empty,\n turn: Css.empty,\n }),\n );\n this.namedValidators[\"POS_TIME\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n s: Css.empty,\n ms: Css.empty,\n }),\n );\n this.namedValidators[\"FREQUENCY\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n Hz: Css.empty,\n kHz: Css.empty,\n }),\n );\n this.namedValidators[\"RESOLUTION\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n dpi: Css.empty,\n dpcm: Css.empty,\n dppx: Css.empty,\n }),\n );\n this.namedValidators[\"URI\"] = this.primitive(\n new PrimitiveValidator(ALLOW_URL, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"IDENT\"] = this.primitive(\n new PrimitiveValidator(ALLOW_IDENT, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"STRING\"] = this.primitive(\n new PrimitiveValidator(ALLOW_STR, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"SLASH\"] = this.primitive(\n new PrimitiveValidator(ALLOW_SLASH, NO_IDENTS, NO_IDENTS),\n );\n const stdfont = { \"font-family\": Css.getName(\"sans-serif\") };\n this.systemFonts[\"caption\"] = stdfont;\n this.systemFonts[\"icon\"] = stdfont;\n this.systemFonts[\"menu\"] = stdfont;\n this.systemFonts[\"message-box\"] = stdfont;\n this.systemFonts[\"small-caption\"] = stdfont;\n this.systemFonts[\"status-bar\"] = stdfont;\n }\n\n private isBuiltIn(name: string): boolean {\n return !!name.match(/^[A-Z_0-9]+$/);\n }\n\n private readNameAndPrefixes(\n tok: CssTokenizer.Tokenizer,\n section: number,\n ): string | null {\n let token = tok.token();\n if (token.type == CssTokenizer.TokenType.EOF) {\n // Finished normally\n return null;\n }\n const rulePrefixes: { [key: string]: boolean } = { \"\": true };\n if (token.type == CssTokenizer.TokenType.O_BRK) {\n do {\n tok.consume();\n token = tok.token();\n if (token.type != CssTokenizer.TokenType.IDENT) {\n throw new Error(\"Prefix name expected\");\n }\n rulePrefixes[token.text] = true;\n tok.consume();\n token = tok.token();\n } while (token.type == CssTokenizer.TokenType.COMMA);\n if (token.type != CssTokenizer.TokenType.C_BRK) {\n throw new Error(\"']' expected\");\n }\n tok.consume();\n token = tok.token();\n }\n if (token.type != CssTokenizer.TokenType.IDENT) {\n throw new Error(\"Property name expected\");\n }\n if (section == 2 ? token.text == \"SHORTHANDS\" : token.text == \"DEFAULTS\") {\n tok.consume();\n return null;\n }\n const name = token.text;\n tok.consume();\n if (section != 2) {\n if (tok.token().type != CssTokenizer.TokenType.EQ) {\n throw new Error(\"'=' expected\");\n }\n if (!this.isBuiltIn(name)) {\n this.prefixes[name] = rulePrefixes;\n }\n } else {\n if (tok.token().type != CssTokenizer.TokenType.COLON) {\n throw new Error(\"':' expected\");\n }\n }\n return name;\n }\n\n private parseValidators(tok: CssTokenizer.Tokenizer): void {\n while (true) {\n const ruleName = this.readNameAndPrefixes(tok, 1);\n if (!ruleName) {\n return;\n }\n let vals: ValidatingGroup[] = [];\n const stack = [];\n let op = \"\";\n let val: ValidatingGroup;\n let expectval = true;\n const self = this;\n const reduce = (): ValidatingGroup => {\n if (vals.length == 0) {\n throw new Error(\"No values\");\n }\n if (vals.length == 1) {\n return vals[0];\n }\n return self.newGroup(op, vals);\n };\n const setop = (currop: string): void => {\n if (expectval) {\n throw new Error(`'${currop}': unexpected`);\n }\n if (op && op != currop) {\n throw new Error(`mixed operators: '${currop}' and '${op}'`);\n }\n op = currop;\n expectval = true;\n };\n let result: ValidatingGroup = null;\n while (!result) {\n tok.consume();\n let token = tok.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n if (!expectval) {\n setop(\" \");\n }\n if (this.isBuiltIn(token.text)) {\n const builtIn = this.namedValidators[token.text];\n if (!builtIn) {\n throw new Error(`'${token.text}' unexpected`);\n }\n vals.push(builtIn.clone());\n } else {\n const idents = {};\n idents[token.text.toLowerCase()] = Css.getName(token.text);\n vals.push(\n this.primitive(new PrimitiveValidator(0, idents, NO_IDENTS)),\n );\n }\n expectval = false;\n break;\n case CssTokenizer.TokenType.INT: {\n const idents = {};\n idents[`${token.num}`] = new Css.Int(token.num);\n vals.push(\n this.primitive(new PrimitiveValidator(0, idents, NO_IDENTS)),\n );\n expectval = false;\n break;\n }\n case CssTokenizer.TokenType.BAR:\n setop(\"|\");\n break;\n case CssTokenizer.TokenType.BAR_BAR:\n setop(\"||\");\n break;\n case CssTokenizer.TokenType.O_BRK:\n if (!expectval) {\n setop(\" \");\n }\n stack.push({ vals, op, b: \"[\" });\n op = \"\";\n vals = [];\n expectval = true;\n break;\n case CssTokenizer.TokenType.FUNC:\n if (!expectval) {\n setop(\" \");\n }\n stack.push({ vals, op, b: \"(\", fn: token.text });\n op = \"\";\n vals = [];\n expectval = true;\n break;\n case CssTokenizer.TokenType.C_BRK: {\n val = reduce();\n const open = stack.pop();\n if (open.b != \"[\") {\n throw new Error(\"']' unexpected\");\n }\n vals = open.vals;\n vals.push(val);\n op = open.op;\n expectval = false;\n break;\n }\n case CssTokenizer.TokenType.C_PAR: {\n val = reduce();\n const open = stack.pop();\n if (open.b != \"(\") {\n throw new Error(\"')' unexpected\");\n }\n vals = open.vals;\n vals.push(this.newFunc(open.fn, val));\n op = open.op;\n expectval = false;\n break;\n }\n case CssTokenizer.TokenType.COLON:\n if (expectval) {\n throw new Error(\"':' unexpected\");\n }\n tok.consume();\n vals.push(this.addReplacement(vals.pop(), tok.token()));\n break;\n case CssTokenizer.TokenType.QMARK:\n if (expectval) {\n throw new Error(\"'?' unexpected\");\n }\n vals.push(this.addCounts(vals.pop(), 0, 1));\n break;\n case CssTokenizer.TokenType.STAR:\n if (expectval) {\n throw new Error(\"'*' unexpected\");\n }\n vals.push(this.addCounts(vals.pop(), 0, Number.POSITIVE_INFINITY));\n break;\n case CssTokenizer.TokenType.PLUS:\n if (expectval) {\n throw new Error(\"'+' unexpected\");\n }\n vals.push(this.addCounts(vals.pop(), 1, Number.POSITIVE_INFINITY));\n break;\n case CssTokenizer.TokenType.O_BRC: {\n tok.consume();\n token = tok.token();\n if (token.type != CssTokenizer.TokenType.INT) {\n throw new Error(\"<int> expected\");\n }\n const min = token.num;\n let max = min;\n tok.consume();\n token = tok.token();\n if (token.type == CssTokenizer.TokenType.COMMA) {\n tok.consume();\n token = tok.token();\n if (token.type != CssTokenizer.TokenType.INT) {\n throw new Error(\"<int> expected\");\n }\n max = token.num;\n tok.consume();\n token = tok.token();\n }\n if (token.type != CssTokenizer.TokenType.C_BRC) {\n throw new Error(\"'}' expected\");\n }\n vals.push(this.addCounts(vals.pop(), min, max));\n break;\n }\n case CssTokenizer.TokenType.SEMICOL:\n result = reduce();\n if (stack.length > 0) {\n throw new Error(`unclosed '${stack.pop().b}'`);\n }\n break;\n default:\n throw new Error(\"unexpected token\");\n }\n }\n tok.consume();\n if (this.isBuiltIn(ruleName)) {\n this.namedValidators[ruleName] = result;\n } else {\n if (result.isSimple()) {\n this.validators[ruleName] = result.nodes[0].validator;\n } else {\n this.validators[ruleName] = new SpaceListValidator(result);\n }\n }\n }\n }\n\n private parseDefaults(tok: CssTokenizer.Tokenizer): void {\n while (true) {\n const propName = this.readNameAndPrefixes(tok, 2);\n if (!propName) {\n return;\n }\n const vals: Css.Val[] = [];\n while (true) {\n tok.consume();\n const token = tok.token();\n if (token.type == CssTokenizer.TokenType.SEMICOL) {\n tok.consume();\n break;\n }\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n vals.push(Css.getName(token.text));\n break;\n case CssTokenizer.TokenType.NUM:\n vals.push(new Css.Num(token.num));\n break;\n case CssTokenizer.TokenType.INT:\n vals.push(new Css.Int(token.num));\n break;\n case CssTokenizer.TokenType.NUMERIC:\n vals.push(new Css.Numeric(token.num, token.text));\n break;\n default:\n throw new Error(\"unexpected token\");\n }\n }\n this.defaultValues[propName] =\n vals.length > 1 ? new Css.SpaceList(vals) : vals[0];\n }\n }\n\n private parseShorthands(tok: CssTokenizer.Tokenizer): void {\n while (true) {\n const ruleName = this.readNameAndPrefixes(tok, 3);\n if (!ruleName) {\n return;\n }\n let token = tok.nthToken(1);\n let shorthandValidator: ShorthandValidator;\n if (\n token.type == CssTokenizer.TokenType.IDENT &&\n shorthandValidators[token.text]\n ) {\n shorthandValidator = new shorthandValidators[token.text]();\n tok.consume();\n } else {\n shorthandValidator = new SimpleShorthandValidator();\n }\n shorthandValidator.setOwner(this);\n let result = false;\n let syntax: ShorthandSyntaxNode[] = [];\n let slash = false;\n const stack = [];\n const propList = [];\n while (!result) {\n tok.consume();\n token = tok.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n if (this.validators[token.text]) {\n syntax.push(shorthandValidator.syntaxNodeForProperty(token.text));\n propList.push(token.text);\n } else if (\n this.shorthands[token.text] instanceof InsetsShorthandValidator\n ) {\n const insetShorthand = this.shorthands[\n token.text\n ] as InsetsShorthandValidator;\n syntax.push(insetShorthand.createSyntaxNode());\n propList.push(...insetShorthand.propList);\n } else {\n throw new Error(\n `'${token.text}' is neither a simple property nor an inset shorthand`,\n );\n }\n break;\n case CssTokenizer.TokenType.SLASH:\n if (syntax.length > 0 || slash) {\n throw new Error(\"unexpected slash\");\n }\n slash = true;\n break;\n case CssTokenizer.TokenType.O_BRK:\n stack.push({ slash, syntax });\n syntax = [];\n slash = false;\n break;\n case CssTokenizer.TokenType.C_BRK: {\n const compound = new ShorthandSyntaxCompound(syntax, slash);\n const item = stack.pop();\n syntax = item.syntax;\n slash = item.slash;\n syntax.push(compound);\n break;\n }\n case CssTokenizer.TokenType.SEMICOL:\n result = true;\n tok.consume();\n break;\n default:\n throw new Error(\"unexpected token\");\n }\n }\n shorthandValidator.init(syntax, propList);\n this.shorthands[ruleName] = shorthandValidator;\n }\n }\n\n parse(text: string): void {\n // Not as robust as CSS parser.\n const tok = new CssTokenizer.Tokenizer(text, null);\n this.parseValidators(tok);\n this.parseDefaults(tok);\n this.parseShorthands(tok);\n this.backgroundProps = this.makePropSet([\"background\"]);\n this.layoutProps = this.makePropSet([\n \"margin\",\n \"border\",\n \"padding\",\n \"columns\",\n \"column-gap\",\n \"column-rule\",\n \"column-fill\",\n ]);\n }\n\n makePropSet(propList: string[]): ValueMap {\n const map: ValueMap = {};\n for (const prop of propList) {\n const shorthand = this.shorthands[prop];\n const list = shorthand ? shorthand.propList : [prop];\n for (const pname of list) {\n const pval = this.defaultValues[pname];\n if (!pval) {\n Logging.logger.warn(\"Unknown property in makePropSet:\", pname);\n } else {\n map[pname] = pval;\n }\n }\n }\n return map;\n }\n\n validatePropertyAndHandleShorthand(\n name: string,\n value: Css.Val,\n important: boolean,\n receiver: PropertyReceiver,\n ): void {\n let prefix = \"\";\n const origName = name;\n name = name.toLowerCase();\n const r = name.match(/^-([a-z]+)-([-a-z0-9]+)$/);\n if (r) {\n prefix = r[1];\n name = r[2];\n }\n const px = this.prefixes[name];\n if (!px || !px[prefix]) {\n receiver.unknownProperty(origName, value);\n return;\n }\n const validator = this.validators[name];\n if (validator) {\n const rvalue =\n value === Css.ident.inherit || value.isExpr()\n ? value\n : value.visit(validator);\n if (rvalue) {\n receiver.simpleProperty(name, rvalue, important);\n } else {\n receiver.invalidPropertyValue(origName, value);\n }\n } else {\n const shorthand = this.shorthands[name].clone();\n if (value === Css.ident.inherit) {\n shorthand.propagateInherit(important, receiver);\n } else {\n value.visit(shorthand);\n if (!shorthand.finish(important, receiver)) {\n receiver.invalidPropertyValue(origName, value);\n }\n }\n }\n }\n}\n\nexport function baseValidatorSet(): ValidatorSet {\n const validatorSet = new ValidatorSet();\n validatorSet.initBuiltInValidators();\n validatorSet.parse(ValidationTxt);\n return validatorSet;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Font - Deal with embedded fonts.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as Exprs from \"./exprs\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\n\nexport const traitProps: { [key: string]: Css.Val } = {\n \"font-style\": Css.ident.normal,\n \"font-variant\": Css.ident.normal,\n \"font-weight\": Css.ident.normal,\n};\n\nexport const bogusFontData = `OTTO${new Date().valueOf()}`;\n\nexport let bogusFontCounter: number = 1;\n\nexport function makeFontTraitKey(properties: {\n [key: string]: Css.Val;\n}): string {\n const sb = new Base.StringBuffer();\n for (const prop in traitProps) {\n sb.append(\" \");\n sb.append(properties[prop].toString());\n }\n return sb.toString();\n}\n\nexport function fillDefaults(properties: { [key: string]: Css.Val }): void {\n for (const prop in traitProps) {\n if (!properties[prop]) {\n properties[prop] = traitProps[prop];\n }\n }\n}\n\nexport function prepareProperties(\n properties: CssCascade.ElementStyle,\n context: Exprs.Context,\n): { [key: string]: Css.Val } {\n const result = {} as { [key: string]: Css.Val };\n for (const prop in properties) {\n result[prop] = CssCascade.getProp(properties, prop).evaluate(context, prop);\n }\n fillDefaults(result);\n return result;\n}\n\n/**\n * A font declared in a font-face rule.\n */\nexport class Face {\n fontTraitKey: string;\n src: string | null;\n blobURLs: string[] = [];\n blobs: Blob[] = [];\n family: string | null;\n\n constructor(public readonly properties: { [key: string]: Css.Val }) {\n this.fontTraitKey = makeFontTraitKey(this.properties);\n this.src = this.properties[\"src\"]\n ? this.properties[\"src\"].toString()\n : null;\n const family = this.properties[\"font-family\"];\n this.family = family ? family.stringValue() : null;\n }\n\n /**\n * Check if font traits are the same for two font faces\n */\n traitsEqual(other: Face): boolean {\n return this.fontTraitKey == other.fontTraitKey;\n }\n\n /**\n * Create \"at\" font-face rule.\n */\n makeAtRule(src: string, fontBytes: Blob): string {\n const sb = new Base.StringBuffer();\n sb.append(\"@font-face {\\n font-family: \");\n sb.append(this.family as string);\n sb.append(\";\\n \");\n for (const prop in traitProps) {\n sb.append(prop);\n sb.append(\": \");\n this.properties[prop].appendTo(sb, true);\n sb.append(\";\\n \");\n }\n if (fontBytes) {\n sb.append('src: url(\"');\n const blobURL = Net.createObjectURL(fontBytes);\n sb.append(blobURL);\n this.blobURLs.push(blobURL);\n this.blobs.push(fontBytes);\n sb.append('\")');\n } else {\n sb.append(\"src: \");\n sb.append(src);\n }\n sb.append(\";\\n}\\n\");\n return sb.toString();\n }\n}\n\n/**\n * Set of the fonts declared in all stylesheets of a document.\n * @param deobfuscator function\n * that takes url and returns data deobfuscator\n */\nexport class DocumentFaces {\n /**\n * Maps source font family names to the family names used in the HTML view.\n */\n familyMap = {} as { [key: string]: string };\n\n constructor(\n public readonly deobfuscator:\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null,\n ) {}\n\n registerFamily(srcFace: Face, viewFace: Face): void {\n const srcFamily = srcFace.family as string;\n const viewFamilyFromSrc = this.familyMap[srcFamily];\n const viewFamilyFromView = viewFace.family;\n if (viewFamilyFromSrc) {\n if (viewFamilyFromSrc != viewFamilyFromView) {\n throw new Error(`E_FONT_FAMILY_INCONSISTENT ${srcFace.family}`);\n }\n } else {\n this.familyMap[srcFamily] = viewFamilyFromView as string;\n }\n }\n\n filterFontFamily(val: Css.Val): Css.Val {\n if (val instanceof Css.CommaList) {\n const list = (val as Css.CommaList).values;\n const newValues = [] as Css.Val[];\n for (const v of list) {\n const r = this.familyMap[v.stringValue()];\n if (r) {\n newValues.push(Css.getName(r));\n }\n newValues.push(v);\n }\n return new Css.CommaList(newValues);\n } else {\n const rf = this.familyMap[val.stringValue()];\n if (rf) {\n return new Css.CommaList([Css.getName(rf), val]);\n }\n return val;\n }\n }\n}\n\n/**\n * Object that loads fonts in a document and allocates font families for them\n * in the view document\n * @param head where to add styles in the view document (normally head element)\n * @param body where to probe text in the view document (normally body element)\n */\nexport class Mapper {\n /**\n * Maps Face.src to an entry for an already-loaded font.\n */\n srcURLMap: { [key: string]: TaskUtil.Fetcher<Face> } = {};\n familyPrefix: string;\n familyCounter: number = 0;\n\n constructor(\n public readonly head: Element,\n public readonly body: Element,\n opt_familyPrefix?: string,\n ) {\n this.familyPrefix = opt_familyPrefix || \"Fnt_\";\n }\n\n getViewFontFamily(srcFace: Face, documentFaces: DocumentFaces): string {\n const srcFamily = srcFace.family as string;\n let viewFamily = documentFaces.familyMap[srcFamily];\n if (viewFamily) {\n return viewFamily;\n }\n viewFamily = this.familyPrefix + ++this.familyCounter;\n documentFaces.familyMap[srcFamily] = viewFamily;\n return viewFamily;\n }\n\n /**\n * @param fontBytes deobfuscated font bytes (if deobfuscation is needed)\n */\n private initFont(\n srcFace: Face,\n fontBytes: Blob,\n documentFaces: DocumentFaces,\n ): Task.Result<Face> {\n const frame: Task.Frame<Face> = Task.newFrame(\"initFont\");\n const self = this;\n const src = srcFace.src as string;\n const props = {} as { [key: string]: Css.Val };\n for (const prop in traitProps) {\n props[prop] = srcFace.properties[prop];\n }\n const fontFamily = self.getViewFontFamily(srcFace, documentFaces);\n props[\"font-family\"] = Css.getName(fontFamily);\n const viewFontFace = new Face(props);\n const probe = self.body.ownerDocument.createElement(\"span\") as HTMLElement;\n probe.textContent = \"M\";\n const killTime = new Date().valueOf() + 1000;\n const style = self.head.ownerDocument.createElement(\"style\");\n const bogusData = bogusFontData + bogusFontCounter++;\n style.textContent = viewFontFace.makeAtRule(\"\", Net.makeBlob([bogusData]));\n self.head.appendChild(style);\n self.body.appendChild(probe);\n probe.style.visibility = \"hidden\";\n probe.style.fontFamily = fontFamily;\n for (const pname in traitProps) {\n Base.setCSSProperty(probe, pname, props[pname].toString());\n }\n const rect = probe.getBoundingClientRect();\n const initWidth = rect.right - rect.left;\n const initHeight = rect.bottom - rect.top;\n style.textContent = viewFontFace.makeAtRule(src, fontBytes);\n Logging.logger.info(\"Starting to load font:\", src);\n let loaded = false;\n frame\n .loop(() => {\n const rect = probe.getBoundingClientRect();\n const currWidth = rect.right - rect.left;\n const currHeight = rect.bottom - rect.top;\n if (initWidth != currWidth || initHeight != currHeight) {\n loaded = true;\n return Task.newResult(false);\n }\n const currTime = new Date().valueOf();\n if (currTime > killTime) {\n return Task.newResult(false);\n }\n return frame.sleep(10);\n })\n .then(() => {\n if (loaded) {\n Logging.logger.info(\"Loaded font:\", src);\n } else {\n Logging.logger.warn(\"Failed to load font:\", src);\n }\n self.body.removeChild(probe);\n frame.finish(viewFontFace);\n });\n return frame.result();\n }\n\n loadFont(\n srcFace: Face,\n documentFaces: DocumentFaces,\n ): TaskUtil.Fetcher<Face> {\n const src = srcFace.src as string;\n let fetcher = this.srcURLMap[src];\n const self = this;\n if (fetcher) {\n fetcher.piggyback((viewFaceParam) => {\n const viewFace = viewFaceParam as Face;\n if (!viewFace.traitsEqual(srcFace)) {\n Logging.logger.warn(\"E_FONT_FACE_INCOMPATIBLE\", srcFace.src);\n } else {\n documentFaces.registerFamily(srcFace, viewFace);\n Logging.logger.warn(\"Found already-loaded font:\", src);\n }\n });\n } else {\n fetcher = new TaskUtil.Fetcher(() => {\n const frame: Task.Frame<Face> = Task.newFrame(\"loadFont\");\n const deobfuscator = documentFaces.deobfuscator\n ? documentFaces.deobfuscator(src)\n : null;\n if (deobfuscator) {\n Net.ajax(src, Net.XMLHttpRequestResponseType.BLOB).then((xhr) => {\n if (!xhr.responseBlob) {\n frame.finish(null);\n return;\n }\n deobfuscator(xhr.responseBlob).then((fontBytes) => {\n self\n .initFont(srcFace, fontBytes, documentFaces)\n .thenFinish(frame);\n });\n });\n } else {\n self.initFont(srcFace, null, documentFaces).thenFinish(frame);\n }\n return frame.result();\n }, `loadFont ${src}`);\n this.srcURLMap[src] = fetcher;\n fetcher.start();\n }\n return fetcher;\n }\n\n findOrLoadFonts(\n srcFaces: Face[],\n documentFaces: DocumentFaces,\n ): Task.Result<boolean> {\n const fetchers = [] as TaskUtil.Fetcher<Face>[];\n for (const srcFace of srcFaces) {\n if (!srcFace.src || !srcFace.family) {\n Logging.logger.warn(\"E_FONT_FACE_INVALID\");\n continue;\n }\n fetchers.push(this.loadFont(srcFace, documentFaces));\n }\n return TaskUtil.waitForFetchers(fetchers);\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview PageMaster - Deal with page masters, partition groups, and partitions.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Vtree from \"./vtree\";\n\nexport let keyCount: number = 1;\n\n/**\n * Represent an at-rule which creates a page-level CSS box (page-master,\n * partition, and partition-group).\n */\nexport abstract class PageBox<\n I extends PageBoxInstance = PageBoxInstance<any>\n> {\n // styles specified in the at-rule\n specified: CssCascade.ElementStyle = {};\n children: PageBox[] = [];\n pageMaster: PageMaster = null;\n index: number = 0;\n key: string;\n\n protected _scope: Exprs.LexicalScope;\n\n get scope(): Exprs.LexicalScope {\n return this._scope;\n }\n\n constructor(\n scope: Exprs.LexicalScope,\n public readonly name: string | null,\n public readonly pseudoName: string | null,\n public readonly classes: string[],\n public readonly parent: PageBox,\n ) {\n this._scope = scope;\n this.key = `p${keyCount++}`;\n if (parent) {\n this.index = parent.children.length;\n parent.children.push(this);\n }\n }\n\n createInstance(parentInstance: PageBoxInstance): PageBoxInstance {\n throw new Error(\"E_UNEXPECTED_CALL\");\n }\n\n /**\n * Clone the PageBox.\n * @param param parent: The parent of the cloned PageBox.\n * pseudoName: Assign this value as the pseudoName of the cloned PageBox.\n */\n clone(param: { parent?: PageBox; pseudoName?: string }): PageBox<I> {\n throw new Error(\"E_UNEXPECTED_CALL\");\n }\n\n /**\n * Copy 'specified' properties to another instance.\n * @param dest The PageBox into which 'specified' properties are copied\n */\n protected copySpecified(dest: PageBox) {\n const specified = this.specified;\n const destSpecified = dest.specified;\n for (const prop in specified) {\n if (Object.prototype.hasOwnProperty.call(specified, prop)) {\n destSpecified[prop] = specified[prop];\n }\n }\n }\n\n /**\n * Clone children with the specified PageBox as their parent.\n */\n protected cloneChildren(parent: PageBox) {\n for (let i = 0; i < this.children.length; i++) {\n // the cloned child is added to parent.children in the child constructor.\n this.children[i].clone({ parent });\n }\n }\n}\n\n/**\n * Parent of all page masters\n */\nexport class RootPageBox extends PageBox<RootPageBoxInstance> {\n constructor(scope: Exprs.LexicalScope) {\n super(scope, null, null, [], null);\n this.specified[\"width\"] = new CssCascade.CascadeValue(Css.fullWidth, 0);\n this.specified[\"height\"] = new CssCascade.CascadeValue(Css.fullHeight, 0);\n }\n}\n\nexport class PageMasterScope extends Exprs.LexicalScope {\n constructor(scope: Exprs.LexicalScope, public pageMaster: PageMaster) {\n super(scope, resolver);\n const self = this;\n function resolver(qualifiedName, isFunc) {\n const r = qualifiedName.match(/^([^.]+)\\.([^.]+)$/);\n if (r) {\n const key = self.pageMaster.keyMap[r[1]];\n if (key) {\n const holder = this as InstanceHolder;\n const boxInstance = holder.lookupInstance(key);\n if (boxInstance) {\n if (isFunc) {\n return boxInstance.resolveFunc(r[2]);\n } else {\n return boxInstance.resolveName(r[2]);\n }\n }\n }\n }\n return null;\n }\n }\n}\n\n/**\n * Represent a page-master rule\n */\nexport class PageMaster<\n I extends PageMasterInstance = PageMasterInstance<any>\n> extends PageBox<I> {\n pageMaster: PageMaster;\n keyMap: { [key: string]: string } = {};\n\n constructor(\n scope: Exprs.LexicalScope,\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n parent: RootPageBox,\n public readonly condition: Exprs.Val,\n public readonly specificity: number,\n ) {\n super(scope, name, pseudoName, classes, parent);\n // if PageMasterScope object is passed, use (share) it.\n if (!(scope instanceof PageMasterScope)) {\n this._scope = new PageMasterScope(scope, this);\n }\n this.pageMaster = this;\n this.specified[\"width\"] = new CssCascade.CascadeValue(Css.fullWidth, 0);\n this.specified[\"height\"] = new CssCascade.CascadeValue(Css.fullHeight, 0);\n this.specified[\"wrap-flow\"] = new CssCascade.CascadeValue(\n Css.ident.auto,\n 0,\n );\n this.specified[\"position\"] = new CssCascade.CascadeValue(\n Css.ident.relative,\n 0,\n );\n this.specified[\"overflow\"] = new CssCascade.CascadeValue(\n Css.ident.visible,\n 0,\n );\n\n // Shift 1px to workaround Chrome printing bug\n // this.specified[\"top\"] = new CssCascade.CascadeValue(new Css.Numeric(-1, \"px\"), 0);\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageBoxInstance {\n return new PageMasterInstance(parentInstance, this);\n }\n\n /**\n * @override\n */\n clone(param): PageMaster {\n // The cloned page master shares the same scope object with the original\n // one.\n const cloned = new PageMaster(\n this.scope,\n this.name,\n param.pseudoName || this.pseudoName,\n this.classes,\n this.parent as RootPageBox,\n this.condition,\n this.specificity,\n );\n this.copySpecified(cloned);\n this.cloneChildren(cloned);\n return cloned;\n }\n\n /**\n * Point the pageMaster reference in the PageMasterScope to the current page\n * master. This is needed when a page master is cloned and shares a common\n * scope with the original page master. Since every Exprs.Val which the\n * page master holds has a reference to the scope and uses it for variable\n * resolution, this reference must be updated properly before the page master\n * instance is used.\n */\n resetScope() {\n (this.scope as any).pageMaster = this;\n }\n}\n\n/**\n * Represent a partition-group rule\n */\nexport class PartitionGroup extends PageBox<PartitionGroupInstance> {\n pageMaster: PageMaster;\n\n constructor(\n scope: Exprs.LexicalScope,\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n parent: PageBox,\n ) {\n super(scope, name, pseudoName, classes, parent);\n this.pageMaster = parent.pageMaster;\n if (name) {\n this.pageMaster.keyMap[name] = this.key;\n }\n this.specified[\"wrap-flow\"] = new CssCascade.CascadeValue(\n Css.ident.auto,\n 0,\n );\n }\n\n /**\n * @override\n */\n createInstance(parentInstance: PageBoxInstance): PageBoxInstance {\n return new PartitionGroupInstance(parentInstance, this);\n }\n\n /**\n * @override\n */\n clone(param): PartitionGroup {\n const cloned = new PartitionGroup(\n param.parent.scope,\n this.name,\n this.pseudoName,\n this.classes,\n param.parent,\n );\n this.copySpecified(cloned);\n this.cloneChildren(cloned);\n return cloned;\n }\n}\n\n/**\n * Represent a partition rule\n */\nexport class Partition<\n I extends PartitionInstance = PartitionInstance\n> extends PageBox<I> {\n pageMaster: PageMaster;\n\n constructor(\n scope: Exprs.LexicalScope,\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n parent: PageBox,\n ) {\n super(scope, name, pseudoName, classes, parent);\n this.pageMaster = parent.pageMaster;\n if (name) {\n this.pageMaster.keyMap[name] = this.key;\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageBoxInstance {\n return new PartitionInstance(parentInstance, this);\n }\n\n /**\n * @override\n */\n clone(param): Partition {\n const cloned = new Partition(\n param.parent.scope,\n this.name,\n this.pseudoName,\n this.classes,\n param.parent,\n );\n this.copySpecified(cloned);\n this.cloneChildren(cloned);\n return cloned;\n }\n}\n\n//---------------------------- Instance --------------------------------\n\n/**\n * @param def default value\n */\nexport function toExprIdent(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n def: string,\n): Exprs.Val {\n if (!val) {\n return new Exprs.Const(scope, def);\n }\n return val.toExpr(scope, scope.zero);\n}\n\nexport function toExprAuto(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || val === Css.ident.auto) {\n return null;\n }\n return val.toExpr(scope, ref);\n}\n\nexport function toExprNormal(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || val === Css.ident.normal) {\n return null;\n }\n return val.toExpr(scope, ref);\n}\n\nexport function toExprZero(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || val === Css.ident.auto) {\n return scope.zero;\n }\n return val.toExpr(scope, ref);\n}\n\n/**\n * If the value is not specified (null), returns zero.\n * If the value is 'auto', returns null.\n * Otherwise, return the value itself.\n */\nexport function toExprZeroAuto(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val) {\n return scope.zero;\n } else if (val === Css.ident.auto) {\n return null;\n } else {\n return val.toExpr(scope, ref);\n }\n}\n\nexport function toExprZeroBorder(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n styleVal: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || styleVal === Css.ident.none) {\n return scope.zero;\n }\n return val.toExpr(scope, ref);\n}\n\nexport function toExprBool(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n def: Exprs.Val,\n): Exprs.Val {\n if (!val) {\n return def;\n }\n if (val === Css.ident._true) {\n return scope._true;\n }\n if (val === Css.ident._false) {\n return scope._false;\n }\n return val.toExpr(scope, scope.zero);\n}\n\nexport interface InstanceHolder extends Exprs.Context {\n registerInstance(key: string, instance: PageBoxInstance): void;\n\n /**\n * @return instance\n */\n lookupInstance(key: string): PageBoxInstance;\n}\n\nexport class PageBoxInstance<P extends PageBox = PageBox<any>> {\n /**\n * cascaded styles, geometric ones converted to Css.Expr\n */\n protected cascaded: CssCascade.ElementStyle = {};\n style: { [key: string]: Css.Val } = {};\n private autoWidth: Exprs.Native = null;\n private autoHeight: Exprs.Native = null;\n children: PageBoxInstance[] = [];\n isAutoWidth: boolean = false;\n isAutoHeight: boolean = false;\n isTopDependentOnAutoHeight: boolean = false;\n isRightDependentOnAutoWidth: boolean = false;\n private calculatedWidth: number = 0;\n private calculatedHeight: number = 0;\n pageMasterInstance: PageMasterInstance = null;\n namedValues: { [key: string]: Exprs.Val } = {};\n namedFuncs: { [key: string]: Exprs.Val } = {};\n vertical: boolean = false;\n rtl: boolean = false;\n suppressEmptyBoxGeneration: boolean = false;\n\n constructor(\n public readonly parentInstance: PageBoxInstance,\n public readonly pageBox: P,\n ) {\n if (parentInstance) {\n parentInstance.children.push(this);\n }\n }\n\n /**\n * Reset information related to layout.\n */\n reset() {\n this.calculatedWidth = 0;\n this.calculatedHeight = 0;\n }\n\n private addNamedValues(name1: string, name2: string): Exprs.Val {\n const v1 = this.resolveName(name1);\n const v2 = this.resolveName(name2);\n if (!v1 || !v2) {\n throw new Error(\"E_INTERNAL\");\n }\n return Exprs.add(this.pageBox.scope, v1, v2);\n }\n\n resolveName(name: string): Exprs.Val {\n let expr = this.namedValues[name];\n if (expr) {\n return expr;\n }\n const val = this.style[name];\n if (val) {\n expr = val.toExpr(this.pageBox.scope, this.pageBox.scope.zero);\n }\n switch (name) {\n case \"margin-left-edge\":\n expr = this.resolveName(\"left\");\n break;\n case \"margin-top-edge\":\n expr = this.resolveName(\"top\");\n break;\n case \"margin-right-edge\":\n expr = this.addNamedValues(\"border-right-edge\", \"margin-right\");\n break;\n case \"margin-bottom-edge\":\n expr = this.addNamedValues(\"border-bottom-edge\", \"margin-bottom\");\n break;\n case \"border-left-edge\":\n expr = this.addNamedValues(\"margin-left-edge\", \"margin-left\");\n break;\n case \"border-top-edge\":\n expr = this.addNamedValues(\"margin-top-edge\", \"margin-top\");\n break;\n case \"border-right-edge\":\n expr = this.addNamedValues(\"padding-right-edge\", \"border-right-width\");\n break;\n case \"border-bottom-edge\":\n expr = this.addNamedValues(\n \"padding-bottom-edge\",\n \"border-bottom-width\",\n );\n break;\n case \"padding-left-edge\":\n expr = this.addNamedValues(\"border-left-edge\", \"border-left-width\");\n break;\n case \"padding-top-edge\":\n expr = this.addNamedValues(\"border-top-edge\", \"border-top-width\");\n break;\n case \"padding-right-edge\":\n expr = this.addNamedValues(\"right-edge\", \"padding-right\");\n break;\n case \"padding-bottom-edge\":\n expr = this.addNamedValues(\"bottom-edge\", \"padding-bottom\");\n break;\n case \"left-edge\":\n expr = this.addNamedValues(\"padding-left-edge\", \"padding-left\");\n break;\n case \"top-edge\":\n expr = this.addNamedValues(\"padding-top-edge\", \"padding-top\");\n break;\n case \"right-edge\":\n expr = this.addNamedValues(\"left-edge\", \"width\");\n break;\n case \"bottom-edge\":\n expr = this.addNamedValues(\"top-edge\", \"height\");\n break;\n }\n if (!expr) {\n let altName: string;\n if (name == \"extent\") {\n altName = this.vertical ? \"width\" : \"height\";\n } else if (name == \"measure\") {\n altName = this.vertical ? \"height\" : \"width\";\n } else {\n const map = this.vertical\n ? CssCascade.couplingMapVert\n : CssCascade.couplingMapHor;\n altName = name;\n for (const key in map) {\n altName = altName.replace(key, map[key]);\n }\n }\n if (altName != name) {\n expr = this.resolveName(altName);\n }\n }\n if (expr) {\n this.namedValues[name] = expr;\n }\n return expr;\n }\n\n resolveFunc(name) {\n let expr = this.namedFuncs[name];\n if (expr) {\n return expr;\n }\n switch (name) {\n case \"columns\": {\n // min(count,column-count) * (column-width + column-gap) - column-gap\n const scope = this.pageBox.scope;\n const count = new Exprs.Param(scope, 0);\n const columnCount = this.resolveName(\"column-count\");\n const columnWidth = this.resolveName(\"column-width\");\n const columnGap = this.resolveName(\"column-gap\");\n expr = Exprs.sub(\n scope,\n Exprs.mul(\n scope,\n new Exprs.Call(scope, \"min\", [count, columnCount]),\n Exprs.add(scope, columnWidth, columnGap),\n ),\n columnGap,\n );\n break;\n }\n }\n if (expr) {\n this.namedFuncs[name] = expr;\n }\n return expr;\n }\n\n private initEnabled(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n let enabled = toExprBool(scope, style[\"enabled\"], scope._true);\n const page = toExprAuto(scope, style[\"page\"], scope.zero);\n if (page) {\n const currentPage = new Exprs.Named(scope, \"page-number\");\n enabled = Exprs.and(\n scope,\n enabled,\n new Exprs.Eq(scope, page, currentPage),\n );\n }\n const minPageWidth = toExprAuto(scope, style[\"min-page-width\"], scope.zero);\n if (minPageWidth) {\n enabled = Exprs.and(\n scope,\n enabled,\n new Exprs.Ge(scope, new Exprs.Named(scope, \"page-width\"), minPageWidth),\n );\n }\n const minPageHeight = toExprAuto(\n scope,\n style[\"min-page-height\"],\n scope.zero,\n );\n if (minPageHeight) {\n enabled = Exprs.and(\n scope,\n enabled,\n new Exprs.Ge(\n scope,\n new Exprs.Named(scope, \"page-height\"),\n minPageHeight,\n ),\n );\n }\n enabled = this.boxSpecificEnabled(enabled);\n style[\"enabled\"] = new Css.Expr(enabled);\n }\n\n protected boxSpecificEnabled(enabled: Exprs.Val): Exprs.Val {\n return enabled;\n }\n\n protected initHorizontal(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n const parentWidth = this.parentInstance\n ? this.parentInstance.style[\"width\"].toExpr(scope, null)\n : null;\n let left = toExprAuto(scope, style[\"left\"], parentWidth);\n let marginLeft = toExprAuto(scope, style[\"margin-left\"], parentWidth);\n const borderLeftWidth = toExprZeroBorder(\n scope,\n style[\"border-left-width\"],\n style[\"border-left-style\"],\n parentWidth,\n );\n const paddingLeft = toExprZero(scope, style[\"padding-left\"], parentWidth);\n let width = toExprAuto(scope, style[\"width\"], parentWidth);\n let maxWidth = toExprAuto(scope, style[\"max-width\"], parentWidth);\n const paddingRight = toExprZero(scope, style[\"padding-right\"], parentWidth);\n const borderRightWidth = toExprZeroBorder(\n scope,\n style[\"border-right-width\"],\n style[\"border-right-style\"],\n parentWidth,\n );\n let marginRight = toExprAuto(scope, style[\"margin-right\"], parentWidth);\n let right = toExprAuto(scope, style[\"right\"], parentWidth);\n const leftBP = Exprs.add(scope, borderLeftWidth, paddingLeft);\n const rightBP = Exprs.add(scope, borderLeftWidth, paddingRight);\n if (left && right && width) {\n let extra = Exprs.sub(\n scope,\n parentWidth,\n Exprs.add(\n scope,\n width,\n Exprs.add(scope, Exprs.add(scope, left, leftBP), rightBP),\n ),\n );\n if (!marginLeft) {\n extra = Exprs.sub(scope, extra, right);\n if (!marginRight) {\n marginLeft = Exprs.mul(scope, extra, new Exprs.Const(scope, 0.5));\n marginRight = marginLeft;\n } else {\n marginLeft = Exprs.sub(scope, extra, marginRight);\n }\n } else {\n if (!marginRight) {\n marginRight = Exprs.sub(\n scope,\n extra,\n Exprs.add(scope, right, marginLeft),\n );\n } else {\n // overconstraint\n right = Exprs.sub(scope, extra, marginRight);\n }\n }\n } else {\n if (!marginLeft) {\n marginLeft = scope.zero;\n }\n if (!marginRight) {\n marginRight = scope.zero;\n }\n if (!left && !right && !width) {\n left = scope.zero;\n }\n if (!left && !width) {\n width = this.autoWidth;\n this.isAutoWidth = true;\n } else if (!left && !right) {\n left = scope.zero;\n } else if (!width && !right) {\n width = this.autoWidth;\n this.isAutoWidth = true;\n }\n const remains = Exprs.sub(\n scope,\n parentWidth,\n Exprs.add(\n scope,\n Exprs.add(scope, marginLeft, leftBP),\n Exprs.add(scope, marginRight, rightBP),\n ),\n );\n if (this.isAutoWidth) {\n if (!maxWidth) {\n // TODO: handle the case when right/left depends on width\n maxWidth = Exprs.sub(scope, remains, left ? left : right);\n }\n\n // For multi-column layout, width is max-width.\n if (\n !this.vertical &&\n (toExprAuto(scope, style[\"column-width\"], null) ||\n toExprAuto(scope, style[\"column-count\"], null))\n ) {\n width = maxWidth;\n this.isAutoWidth = false;\n }\n }\n if (!left) {\n left = Exprs.sub(scope, remains, Exprs.add(scope, right, width));\n } else if (!width) {\n width = Exprs.sub(scope, remains, Exprs.add(scope, left, right));\n } else if (!right) {\n right = Exprs.sub(scope, remains, Exprs.add(scope, left, width));\n }\n }\n\n // snap-width is inherited\n const snapWidthVal =\n style[\"snap-width\"] ||\n (this.parentInstance ? this.parentInstance.style[\"snap-width\"] : null);\n const snapWidth = toExprZero(scope, snapWidthVal, parentWidth);\n style[\"left\"] = new Css.Expr(left);\n style[\"margin-left\"] = new Css.Expr(marginLeft);\n style[\"border-left-width\"] = new Css.Expr(borderLeftWidth);\n style[\"padding-left\"] = new Css.Expr(paddingLeft);\n style[\"width\"] = new Css.Expr(width);\n style[\"max-width\"] = new Css.Expr(maxWidth ? maxWidth : width);\n style[\"padding-right\"] = new Css.Expr(paddingRight);\n style[\"border-right-width\"] = new Css.Expr(borderRightWidth);\n style[\"margin-right\"] = new Css.Expr(marginRight);\n style[\"right\"] = new Css.Expr(right);\n style[\"snap-width\"] = new Css.Expr(snapWidth);\n }\n\n protected initVertical(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n const parentWidth = this.parentInstance\n ? this.parentInstance.style[\"width\"].toExpr(scope, null)\n : null;\n const parentHeight = this.parentInstance\n ? this.parentInstance.style[\"height\"].toExpr(scope, null)\n : null;\n let top = toExprAuto(scope, style[\"top\"], parentHeight);\n let marginTop = toExprAuto(scope, style[\"margin-top\"], parentWidth);\n const borderTopWidth = toExprZeroBorder(\n scope,\n style[\"border-top-width\"],\n style[\"border-top-style\"],\n parentWidth,\n );\n const paddingTop = toExprZero(scope, style[\"padding-top\"], parentWidth);\n let height = toExprAuto(scope, style[\"height\"], parentHeight);\n let maxHeight = toExprAuto(scope, style[\"max-height\"], parentHeight);\n const paddingBottom = toExprZero(\n scope,\n style[\"padding-bottom\"],\n parentWidth,\n );\n const borderBottomWidth = toExprZeroBorder(\n scope,\n style[\"border-bottom-width\"],\n style[\"border-bottom-style\"],\n parentWidth,\n );\n let marginBottom = toExprAuto(scope, style[\"margin-bottom\"], parentWidth);\n let bottom = toExprAuto(scope, style[\"bottom\"], parentHeight);\n const topBP = Exprs.add(scope, borderTopWidth, paddingTop);\n const bottomBP = Exprs.add(scope, borderBottomWidth, paddingBottom);\n if (top && bottom && height) {\n let extra = Exprs.sub(\n scope,\n parentHeight,\n Exprs.add(\n scope,\n height,\n Exprs.add(scope, Exprs.add(scope, top, topBP), bottomBP),\n ),\n );\n if (!marginTop) {\n extra = Exprs.sub(scope, extra, bottom);\n if (!marginBottom) {\n marginTop = Exprs.mul(scope, extra, new Exprs.Const(scope, 0.5));\n marginBottom = marginTop;\n } else {\n marginTop = Exprs.sub(scope, extra, marginBottom);\n }\n } else {\n if (!marginBottom) {\n marginBottom = Exprs.sub(\n scope,\n extra,\n Exprs.add(scope, bottom, marginTop),\n );\n } else {\n // overconstraint\n bottom = Exprs.sub(scope, extra, marginTop);\n }\n }\n } else {\n if (!marginTop) {\n marginTop = scope.zero;\n }\n if (!marginBottom) {\n marginBottom = scope.zero;\n }\n if (!top && !bottom && !height) {\n top = scope.zero;\n }\n if (!top && !height) {\n height = this.autoHeight;\n this.isAutoHeight = true;\n } else if (!top && !bottom) {\n top = scope.zero;\n } else if (!height && !bottom) {\n height = this.autoHeight;\n this.isAutoHeight = true;\n }\n const remains = Exprs.sub(\n scope,\n parentHeight,\n Exprs.add(\n scope,\n Exprs.add(scope, marginTop, topBP),\n Exprs.add(scope, marginBottom, bottomBP),\n ),\n );\n if (this.isAutoHeight) {\n if (!maxHeight) {\n // TODO: handle the case when top/bottom depends on height\n maxHeight = Exprs.sub(scope, remains, top ? top : bottom);\n }\n\n // For multi-column layout in vertical writing, height is max-height.\n if (\n this.vertical &&\n (toExprAuto(scope, style[\"column-width\"], null) ||\n toExprAuto(scope, style[\"column-count\"], null))\n ) {\n height = maxHeight;\n this.isAutoHeight = false;\n }\n }\n if (!top) {\n top = Exprs.sub(scope, remains, Exprs.add(scope, bottom, height));\n } else if (!height) {\n height = Exprs.sub(scope, remains, Exprs.add(scope, bottom, top));\n } else if (!bottom) {\n bottom = Exprs.sub(scope, remains, Exprs.add(scope, top, height));\n }\n }\n\n // snap-height is inherited\n const snapHeightVal =\n style[\"snap-height\"] ||\n (this.parentInstance ? this.parentInstance.style[\"snap-height\"] : null);\n const snapHeight = toExprZero(scope, snapHeightVal, parentWidth);\n style[\"top\"] = new Css.Expr(top);\n style[\"margin-top\"] = new Css.Expr(marginTop);\n style[\"border-top-width\"] = new Css.Expr(borderTopWidth);\n style[\"padding-top\"] = new Css.Expr(paddingTop);\n style[\"height\"] = new Css.Expr(height);\n style[\"max-height\"] = new Css.Expr(maxHeight ? maxHeight : height);\n style[\"padding-bottom\"] = new Css.Expr(paddingBottom);\n style[\"border-bottom-width\"] = new Css.Expr(borderBottomWidth);\n style[\"margin-bottom\"] = new Css.Expr(marginBottom);\n style[\"bottom\"] = new Css.Expr(bottom);\n style[\"snap-height\"] = new Css.Expr(snapHeight);\n }\n\n private initColumns(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n const width = toExprAuto(\n scope,\n style[this.vertical ? \"height\" : \"width\"],\n null,\n );\n let columnWidth = toExprAuto(scope, style[\"column-width\"], width);\n let columnCount = toExprAuto(scope, style[\"column-count\"], null);\n let columnGap = toExprNormal(scope, style[\"column-gap\"], null);\n if (!columnGap) {\n columnGap = new Exprs.Numeric(scope, 1, \"em\");\n }\n if (columnWidth && !columnCount) {\n columnCount = new Exprs.Call(scope, \"floor\", [\n Exprs.div(\n scope,\n Exprs.add(scope, width, columnGap),\n Exprs.add(scope, columnWidth, columnGap),\n ),\n ]);\n columnCount = new Exprs.Call(scope, \"max\", [scope.one, columnCount]);\n }\n if (!columnCount) {\n columnCount = scope.one;\n }\n columnWidth = Exprs.sub(\n scope,\n Exprs.div(scope, Exprs.add(scope, width, columnGap), columnCount),\n columnGap,\n );\n style[\"column-width\"] = new Css.Expr(columnWidth);\n style[\"column-count\"] = new Css.Expr(columnCount);\n style[\"column-gap\"] = new Css.Expr(columnGap);\n }\n\n private depends(\n propName: string,\n val: Exprs.Val,\n context: Exprs.Context,\n ): boolean {\n return this.style[propName]\n .toExpr(this.pageBox.scope, null)\n .depend(val, context);\n }\n\n private init(context: Exprs.Context): void {\n // If context does not implement InstanceHolder we would not be able to\n // resolve \"partition.property\" names later.\n const holder = context as InstanceHolder;\n holder.registerInstance(this.pageBox.key, this);\n const scope = this.pageBox.scope;\n const style = this.style;\n const self = this;\n const regionIds = this.parentInstance\n ? this.parentInstance.getActiveRegions(context)\n : null;\n const cascMap = CssCascade.flattenCascadedStyle(\n this.cascaded,\n context,\n regionIds,\n false,\n null,\n );\n this.vertical = CssCascade.isVertical(\n cascMap,\n context,\n this.parentInstance ? this.parentInstance.vertical : false,\n );\n this.rtl = CssCascade.isRtl(\n cascMap,\n context,\n this.parentInstance ? this.parentInstance.rtl : false,\n );\n CssCascade.convertToPhysical(\n cascMap,\n style,\n this.vertical,\n this.rtl,\n (name, cascVal) => cascVal.value,\n );\n this.autoWidth = new Exprs.Native(\n scope,\n () => self.calculatedWidth,\n \"autoWidth\",\n );\n this.autoHeight = new Exprs.Native(\n scope,\n () => self.calculatedHeight,\n \"autoHeight\",\n );\n this.initHorizontal();\n this.initVertical();\n this.initColumns();\n this.initEnabled();\n }\n\n getProp(context: Exprs.Context, name: string): Css.Val {\n let val = this.style[name];\n if (val) {\n val = CssParser.evaluateCSSToCSS(context, val, name);\n }\n return val;\n }\n\n getPropAsNumber(context: Exprs.Context, name: string): number {\n let val = this.style[name];\n if (val) {\n val = CssParser.evaluateCSSToCSS(context, val, name);\n }\n return Css.toNumber(val, context);\n }\n\n getSpecial(context: Exprs.Context, name: string): Css.Val[] {\n const arr = CssCascade.getSpecial(this.cascaded, name);\n if (arr) {\n const result = [] as Css.Val[];\n for (let i = 0; i < arr.length; i++) {\n const v = arr[i].evaluate(context, \"\");\n if (v && v !== Css.empty) {\n result.push(v);\n }\n }\n if (result.length) {\n return result;\n }\n }\n return null;\n }\n\n getActiveRegions(context: Exprs.Context): string[] {\n const arr = this.getSpecial(context, \"region-id\");\n if (arr) {\n const result = [] as string[];\n for (let i = 0; i < arr.length; i++) {\n result[i] = arr[i].toString();\n }\n return result;\n }\n return null;\n }\n\n propagateProperty(\n context: Exprs.Context,\n container: Vtree.Container,\n name: string,\n docFaces: Font.DocumentFaces,\n ): void {\n this.propagatePropertyToElement(context, container.element, name, docFaces);\n }\n\n propagatePropertyToElement(\n context: Exprs.Context,\n element: Element,\n name: string,\n docFaces: Font.DocumentFaces,\n ): void {\n let val = this.getProp(context, name);\n if (val) {\n if (\n val.isNumeric() &&\n Exprs.needUnitConversion((val as Css.Numeric).unit)\n ) {\n val = Css.convertNumericToPx(val, context);\n }\n if (name === \"font-family\") {\n val = docFaces.filterFontFamily(val);\n }\n Base.setCSSProperty(element, name, val.toString());\n }\n }\n\n propagateDelayedProperty(\n context: Exprs.Context,\n container: Vtree.Container,\n name: string,\n delayedItems: Vtree.DelayedItem[],\n ): void {\n const val = this.getProp(context, name);\n if (val) {\n delayedItems.push(new Vtree.DelayedItem(container.element, name, val));\n }\n }\n\n assignLeftPosition(context: Exprs.Context, container: Vtree.Container): void {\n const left = this.getPropAsNumber(context, \"left\");\n const marginLeft = this.getPropAsNumber(context, \"margin-left\");\n const paddingLeft = this.getPropAsNumber(context, \"padding-left\");\n const borderLeftWidth = this.getPropAsNumber(context, \"border-left-width\");\n const width = this.getPropAsNumber(context, \"width\");\n container.setHorizontalPosition(left, width);\n Base.setCSSProperty(container.element, \"margin-left\", `${marginLeft}px`);\n Base.setCSSProperty(container.element, \"padding-left\", `${paddingLeft}px`);\n Base.setCSSProperty(\n container.element,\n \"border-left-width\",\n `${borderLeftWidth}px`,\n );\n container.marginLeft = marginLeft;\n container.borderLeft = borderLeftWidth;\n container.paddingLeft = paddingLeft;\n }\n\n assignRightPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n const right = this.getPropAsNumber(context, \"right\");\n const snapWidth = this.getPropAsNumber(context, \"snap-height\");\n const marginRight = this.getPropAsNumber(context, \"margin-right\");\n let paddingRight = this.getPropAsNumber(context, \"padding-right\");\n const borderRightWidth = this.getPropAsNumber(\n context,\n \"border-right-width\",\n );\n Base.setCSSProperty(container.element, \"margin-right\", `${marginRight}px`);\n Base.setCSSProperty(\n container.element,\n \"padding-right\",\n `${paddingRight}px`,\n );\n Base.setCSSProperty(\n container.element,\n \"border-right-width\",\n `${borderRightWidth}px`,\n );\n container.marginRight = marginRight;\n container.borderRight = borderRightWidth;\n if (this.vertical && snapWidth > 0) {\n const xpos = right + container.getInsetRight();\n const r = xpos - Math.floor(xpos / snapWidth) * snapWidth;\n if (r > 0) {\n container.snapOffsetX = snapWidth - r;\n paddingRight += container.snapOffsetX;\n }\n }\n container.paddingRight = paddingRight;\n container.snapWidth = snapWidth;\n }\n\n assignTopPosition(context: Exprs.Context, container: Vtree.Container): void {\n const snapHeight = this.getPropAsNumber(context, \"snap-height\");\n const top = this.getPropAsNumber(context, \"top\");\n const marginTop = this.getPropAsNumber(context, \"margin-top\");\n let paddingTop = this.getPropAsNumber(context, \"padding-top\");\n const borderTopWidth = this.getPropAsNumber(context, \"border-top-width\");\n container.top = top;\n container.marginTop = marginTop;\n container.borderTop = borderTopWidth;\n container.snapHeight = snapHeight;\n if (!this.vertical && snapHeight > 0) {\n const ypos = top + container.getInsetTop();\n const r = ypos - Math.floor(ypos / snapHeight) * snapHeight;\n if (r > 0) {\n container.snapOffsetY = snapHeight - r;\n paddingTop += container.snapOffsetY;\n }\n }\n container.paddingTop = paddingTop;\n Base.setCSSProperty(container.element, \"top\", `${top}px`);\n Base.setCSSProperty(container.element, \"margin-top\", `${marginTop}px`);\n Base.setCSSProperty(container.element, \"padding-top\", `${paddingTop}px`);\n Base.setCSSProperty(\n container.element,\n \"border-top-width\",\n `${borderTopWidth}px`,\n );\n }\n\n assignBottomPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n const marginBottom = this.getPropAsNumber(context, \"margin-bottom\");\n const paddingBottom = this.getPropAsNumber(context, \"padding-bottom\");\n const borderBottomWidth = this.getPropAsNumber(\n context,\n \"border-bottom-width\",\n );\n const height =\n this.getPropAsNumber(context, \"height\") - container.snapOffsetY;\n Base.setCSSProperty(container.element, \"height\", `${height}px`);\n Base.setCSSProperty(\n container.element,\n \"margin-bottom\",\n `${marginBottom}px`,\n );\n Base.setCSSProperty(\n container.element,\n \"padding-bottom\",\n `${paddingBottom}px`,\n );\n Base.setCSSProperty(\n container.element,\n \"border-bottom-width\",\n `${borderBottomWidth}px`,\n );\n container.height = height - container.snapOffsetY;\n container.marginBottom = marginBottom;\n container.borderBottom = borderBottomWidth;\n container.paddingBottom = paddingBottom;\n }\n\n assignBeforePosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n if (this.vertical) {\n this.assignRightPosition(context, container);\n } else {\n this.assignTopPosition(context, container);\n }\n }\n\n assignAfterPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n if (this.vertical) {\n this.assignLeftPosition(context, container);\n } else {\n this.assignBottomPosition(context, container);\n }\n }\n\n assignStartEndPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n if (this.vertical) {\n this.assignTopPosition(context, container);\n this.assignBottomPosition(context, container);\n } else {\n this.assignRightPosition(context, container);\n this.assignLeftPosition(context, container);\n }\n }\n\n sizeWithMaxHeight(context: Exprs.Context, container: Vtree.Container): void {\n Base.setCSSProperty(container.element, \"border-top-width\", \"0px\");\n let height = this.getPropAsNumber(context, \"max-height\");\n if (this.isTopDependentOnAutoHeight) {\n container.setVerticalPosition(0, height);\n } else {\n this.assignTopPosition(context, container);\n height -= container.snapOffsetY;\n container.height = height;\n Base.setCSSProperty(container.element, \"height\", `${height}px`);\n }\n }\n\n sizeWithMaxWidth(context: Exprs.Context, container: Vtree.Container): void {\n Base.setCSSProperty(container.element, \"border-left-width\", \"0px\");\n let width = this.getPropAsNumber(context, \"max-width\");\n if (this.isRightDependentOnAutoWidth) {\n container.setHorizontalPosition(0, width);\n } else {\n this.assignRightPosition(context, container);\n width -= container.snapOffsetX;\n container.width = width;\n const right = this.getPropAsNumber(context, \"right\");\n Base.setCSSProperty(container.element, \"right\", `${right}px`);\n Base.setCSSProperty(container.element, \"width\", `${width}px`);\n }\n }\n\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n if (!this.parentInstance || this.vertical != this.parentInstance.vertical) {\n Base.setCSSProperty(\n container.element,\n \"writing-mode\",\n this.vertical ? \"vertical-rl\" : \"horizontal-tb\",\n );\n }\n if (this.vertical ? this.isAutoWidth : this.isAutoHeight) {\n if (this.vertical) {\n this.sizeWithMaxWidth(context, container);\n } else {\n this.sizeWithMaxHeight(context, container);\n }\n } else {\n this.assignBeforePosition(context, container);\n this.assignAfterPosition(context, container);\n }\n if (this.vertical ? this.isAutoHeight : this.isAutoWidth) {\n if (this.vertical) {\n this.sizeWithMaxHeight(context, container);\n } else {\n this.sizeWithMaxWidth(context, container);\n }\n } else {\n this.assignStartEndPosition(context, container);\n }\n for (let i = 0; i < passPreProperties.length; i++) {\n this.propagateProperty(\n context,\n container,\n passPreProperties[i],\n docFaces,\n );\n }\n }\n\n transferContentProps(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n ): void {\n for (let i = 0; i < passContentProperties.length; i++) {\n this.propagateProperty(\n context,\n container,\n passContentProperties[i],\n docFaces,\n );\n }\n }\n\n transferSinglUriContentProps(\n context: Exprs.Context,\n element: Element,\n docFaces: Font.DocumentFaces,\n ): void {\n for (let i = 0; i < passSingleUriContentProperties.length; i++) {\n this.propagatePropertyToElement(\n context,\n element,\n passSingleUriContentProperties[i],\n docFaces,\n );\n }\n }\n\n /**\n * @param column (null when content comes from the content property)\n */\n finishContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n column: Vtree.Container,\n columnCount: number,\n clientLayout: Vtree.ClientLayout,\n docFaces: Font.DocumentFaces,\n ): void {\n if (this.vertical) {\n this.calculatedWidth =\n container.computedBlockSize + container.snapOffsetX;\n } else {\n this.calculatedHeight =\n container.computedBlockSize + container.snapOffsetY;\n }\n const readHeight = (this.vertical || !column) && this.isAutoHeight;\n const readWidth = (!this.vertical || !column) && this.isAutoWidth;\n let bbox: Vtree.ClientRect = null;\n if (readWidth || readHeight) {\n if (readWidth) {\n Base.setCSSProperty(container.element, \"width\", \"auto\");\n }\n if (readHeight) {\n Base.setCSSProperty(container.element, \"height\", \"auto\");\n }\n bbox = clientLayout.getElementClientRect(\n column ? column.element : container.element,\n );\n if (readWidth) {\n this.calculatedWidth = Math.ceil(\n bbox.right -\n bbox.left -\n container.paddingLeft -\n container.borderLeft -\n container.paddingRight -\n container.borderRight,\n );\n if (this.vertical) {\n this.calculatedWidth += container.snapOffsetX;\n }\n }\n if (readHeight) {\n this.calculatedHeight =\n bbox.bottom -\n bbox.top -\n container.paddingTop -\n container.borderTop -\n container.paddingBottom -\n container.borderBottom;\n if (!this.vertical) {\n this.calculatedHeight += container.snapOffsetY;\n }\n }\n }\n if (this.vertical ? this.isAutoHeight : this.isAutoWidth) {\n this.assignStartEndPosition(context, container);\n }\n if (this.vertical ? this.isAutoWidth : this.isAutoHeight) {\n if (\n this.vertical\n ? this.isRightDependentOnAutoWidth\n : this.isTopDependentOnAutoHeight\n ) {\n this.assignBeforePosition(context, container);\n }\n this.assignAfterPosition(context, container);\n }\n if (columnCount > 1) {\n const ruleWidth = this.getPropAsNumber(context, \"column-rule-width\");\n const ruleStyle = this.getProp(context, \"column-rule-style\");\n const ruleColor = this.getProp(context, \"column-rule-color\");\n if (\n ruleWidth > 0 &&\n ruleStyle &&\n ruleStyle != Css.ident.none &&\n ruleColor != Css.ident.transparent\n ) {\n const columnGap = this.getPropAsNumber(context, \"column-gap\");\n const containerSize = this.vertical\n ? container.height\n : container.width;\n const border = this.vertical ? \"border-top\" : \"border-left\";\n for (let i = 1; i < columnCount; i++) {\n const pos =\n ((containerSize + columnGap) * i) / columnCount -\n columnGap / 2 +\n container.paddingLeft -\n ruleWidth / 2;\n const size =\n container.height + container.paddingTop + container.paddingBottom;\n const rule = container.element.ownerDocument.createElement(\"div\");\n Base.setCSSProperty(rule, \"position\", \"absolute\");\n Base.setCSSProperty(rule, this.vertical ? \"left\" : \"top\", \"0px\");\n Base.setCSSProperty(rule, this.vertical ? \"top\" : \"left\", `${pos}px`);\n Base.setCSSProperty(rule, this.vertical ? \"height\" : \"width\", \"0px\");\n Base.setCSSProperty(\n rule,\n this.vertical ? \"width\" : \"height\",\n `${size}px`,\n );\n Base.setCSSProperty(\n rule,\n border,\n `${ruleWidth}px ${ruleStyle.toString()}${\n ruleColor ? ` ${ruleColor.toString()}` : \"\"\n }`,\n );\n container.element.insertBefore(rule, container.element.firstChild);\n }\n }\n }\n for (let i = 0; i < passPostProperties.length; i++) {\n this.propagateProperty(\n context,\n container,\n passPostProperties[i],\n docFaces,\n );\n }\n for (let i = 0; i < delayedProperties.length; i++) {\n this.propagateDelayedProperty(\n context,\n container,\n delayedProperties[i],\n page.delayedItems,\n );\n }\n }\n\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n const style = this.cascaded;\n const specified = this.pageBox.specified;\n for (const name in specified) {\n if (CssCascade.isPropName(name)) {\n CssCascade.setProp(style, name, CssCascade.getProp(specified, name));\n }\n }\n if (this.pageBox.pseudoName == userAgentPageMasterPseudo) {\n for (const name in docElementStyle) {\n if (name.match(/^background-/) || name == \"writing-mode\") {\n style[name] = docElementStyle[name];\n }\n }\n }\n if (this.pageBox.pseudoName == \"layout-host\") {\n for (const name in docElementStyle) {\n if (!name.match(/^background-/) && name != \"writing-mode\") {\n style[name] = docElementStyle[name];\n }\n }\n }\n cascade.pushRule(this.pageBox.classes, null, style);\n if (style[\"content\"]) {\n style[\"content\"] = style[\"content\"].filterValue(\n new CssCascade.ContentPropVisitor(\n cascade,\n null,\n cascade.counterResolver,\n ),\n );\n }\n this.init(cascade.context);\n for (const child of this.pageBox.children) {\n const childInstance = child.createInstance(this);\n childInstance.applyCascadeAndInit(cascade, docElementStyle);\n }\n cascade.popRule();\n }\n\n resolveAutoSizing(context: Exprs.Context): void {\n // all implicit dependencies are set up at this point\n if (this.isAutoWidth) {\n this.isRightDependentOnAutoWidth =\n this.depends(\"right\", this.autoWidth, context) ||\n this.depends(\"margin-right\", this.autoWidth, context) ||\n this.depends(\"border-right-width\", this.autoWidth, context) ||\n this.depends(\"padding-right\", this.autoWidth, context);\n }\n if (this.isAutoHeight) {\n this.isTopDependentOnAutoHeight =\n this.depends(\"top\", this.autoHeight, context) ||\n this.depends(\"margin-top\", this.autoHeight, context) ||\n this.depends(\"border-top-width\", this.autoHeight, context) ||\n this.depends(\"padding-top\", this.autoHeight, context);\n }\n for (const childInstance of this.children) {\n childInstance.resolveAutoSizing(context);\n }\n }\n}\n\n/**\n * Properties that are passed through before the layout.\n */\nexport const passPreProperties = [\n \"border-left-style\",\n \"border-right-style\",\n \"border-top-style\",\n \"border-bottom-style\",\n \"border-left-color\",\n \"border-right-color\",\n \"border-top-color\",\n \"border-bottom-color\",\n \"outline-style\",\n \"outline-color\",\n \"outline-width\",\n \"overflow\",\n \"visibility\",\n];\n\n/**\n * Properties that are passed through after the layout.\n */\nexport const passPostProperties = [\n \"border-top-left-radius\",\n \"border-top-right-radius\",\n \"border-bottom-right-radius\",\n \"border-bottom-left-radius\",\n \"border-image-source\",\n \"border-image-slice\",\n \"border-image-width\",\n \"border-image-outset\",\n \"border-image-repeat\",\n \"background-attachment\",\n \"background-color\",\n \"background-image\",\n \"background-repeat\",\n \"background-position\",\n \"background-clip\",\n \"background-origin\",\n \"background-size\",\n \"opacity\",\n \"z-index\",\n \"background-blend-mode\",\n \"isolation\",\n \"mix-blend-mode\",\n \"filter\",\n];\n\n/**\n * Only passed when there is content assigned by the content property.\n */\nexport const passContentProperties = [\n \"color\",\n \"font-family\",\n \"font-size\",\n \"font-style\",\n \"font-weight\",\n \"font-variant\",\n \"line-height\",\n \"letter-spacing\",\n \"text-align\",\n \"text-decoration\",\n \"text-indent\",\n \"text-transform\",\n \"white-space\",\n \"word-spacing\",\n \"font-feature-settings\",\n \"font-kerning\",\n \"font-size-adjust\",\n \"font-variant-east-asian\",\n \"font-stretch\",\n \"text-decoration-color\",\n \"text-decoration-line\",\n \"text-decoration-skip\",\n \"text-decoration-style\",\n \"text-emphasis\",\n \"text-emphasis-color\",\n \"text-emphasis-position\",\n \"text-emphasis-style\",\n \"text-shadow\",\n \"text-underline-position\",\n];\n\nexport const passSingleUriContentProperties = [\n \"width\",\n \"height\",\n \"image-resolution\",\n \"object-fit\",\n \"object-position\",\n];\n\nexport const delayedProperties = [\"transform\", \"transform-origin\"];\n\nexport const userAgentPageMasterPseudo = \"background-host\";\n\nexport class RootPageBoxInstance extends PageBoxInstance<RootPageBox> {\n constructor(pageBox: RootPageBox) {\n super(null, pageBox);\n }\n\n /**\n * @override\n */\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n super.applyCascadeAndInit(cascade, docElementStyle);\n\n // Sort page masters using order and specificity.\n const pageMasters = this.children;\n (pageMasters as PageMasterInstance[]).sort(\n (a, b) =>\n (b.pageBox as any).specificity - (a.pageBox as any).specificity || // probably cause NaN\n a.pageBox.index - b.pageBox.index,\n );\n }\n}\n\nexport class PageMasterInstance<\n P extends PageMaster = PageMaster<PageMasterInstance<any>>\n> extends PageBoxInstance<P> {\n pageMasterInstance: PageMasterInstance;\n\n constructor(parentInstance: PageBoxInstance, pageBox: P) {\n super(parentInstance, pageBox);\n this.pageMasterInstance = this;\n }\n\n /**\n * @override\n */\n boxSpecificEnabled(enabled: Exprs.Val): Exprs.Val {\n const pageMaster = this.pageBox.pageMaster;\n if (pageMaster.condition) {\n enabled = Exprs.and(pageMaster.scope, enabled, pageMaster.condition);\n }\n return enabled;\n }\n\n /**\n * Called after layout of contents of the page has done to adjust the overall\n * page layout. Override in subclasses.\n */\n adjustPageLayout(\n context: Exprs.Context,\n page: Vtree.Page,\n clientLayout: Vtree.ClientLayout,\n ) {}\n}\n\nexport class PartitionGroupInstance extends PageBoxInstance<PartitionGroup> {\n pageMasterInstance: PageMasterInstance;\n\n constructor(parentInstance: PageBoxInstance, pageBox: PageBox) {\n super(parentInstance, pageBox);\n this.pageMasterInstance = parentInstance.pageMasterInstance;\n }\n}\n\nexport class PartitionInstance<\n P extends Partition = Partition<PartitionInstance<any>>\n> extends PageBoxInstance<P> {\n pageMasterInstance: PageMasterInstance;\n\n constructor(parentInstance: PageBoxInstance, pageBox: P) {\n super(parentInstance, pageBox);\n this.pageMasterInstance = parentInstance.pageMasterInstance;\n }\n\n processPartitionList(\n enabled: Exprs.Val,\n listVal: Css.Val,\n conflicting: boolean,\n ): Exprs.Val {\n let list: Css.Val[] = null;\n if (listVal instanceof Css.Ident) {\n list = [listVal];\n }\n if (listVal instanceof Css.CommaList) {\n list = (listVal as Css.CommaList).values;\n }\n if (list) {\n const scope = this.pageBox.scope;\n for (let i = 0; i < list.length; i++) {\n if (list[i] instanceof Css.Ident) {\n const qname = Exprs.makeQualifiedName(\n (list[i] as Css.Ident).name,\n \"enabled\",\n );\n let term: Exprs.Val = new Exprs.Named(scope, qname);\n if (conflicting) {\n term = new Exprs.Not(scope, term);\n }\n enabled = Exprs.and(scope, enabled, term);\n }\n }\n }\n return enabled;\n }\n\n /**\n * @override\n */\n boxSpecificEnabled(enabled: Exprs.Val): Exprs.Val {\n const scope = this.pageBox.scope;\n const style = this.style;\n const required =\n toExprBool(scope, style[\"required\"], scope._false) !== scope._false;\n if (required || this.isAutoHeight) {\n const flowName = toExprIdent(scope, style[\"flow-from\"], \"body\");\n const hasContent = new Exprs.Call(scope, \"has-content\", [flowName]);\n enabled = Exprs.and(scope, enabled, hasContent);\n }\n enabled = this.processPartitionList(\n enabled,\n style[\"required-partitions\"],\n false,\n );\n enabled = this.processPartitionList(\n enabled,\n style[\"conflicting-partitions\"],\n true,\n );\n if (required) {\n const pmEnabledVal = this.pageMasterInstance.style[\"enabled\"];\n let pmEnabled = pmEnabledVal\n ? pmEnabledVal.toExpr(scope, null)\n : scope._true;\n pmEnabled = Exprs.and(scope, pmEnabled, enabled);\n this.pageMasterInstance.style[\"enabled\"] = new Css.Expr(pmEnabled);\n }\n return enabled;\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n Base.setCSSProperty(container.element, \"overflow\", \"hidden\"); // default value\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n }\n}\n\n//--------------------- parsing -----------------------\nexport class PageBoxParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly target: PageBox,\n public readonly validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, false);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY_VALUE ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n this.target.specified[name] = new CssCascade.CascadeValue(\n value,\n important\n ? CssParser.SPECIFICITY_STYLE\n : CssParser.SPECIFICITY_STYLE_IMPORTANT,\n );\n }\n}\n\nexport class PartitionParserHandler extends PageBoxParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n target: Partition,\n validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, target, validatorSet);\n }\n}\n\nexport class PartitionGroupParserHandler extends PageBoxParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n target: PartitionGroup,\n validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, target, validatorSet);\n target.specified[\"width\"] = new CssCascade.CascadeValue(\n Css.hundredPercent,\n 0,\n );\n target.specified[\"height\"] = new CssCascade.CascadeValue(\n Css.hundredPercent,\n 0,\n );\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partition = new Partition(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionParserHandler(\n this.scope,\n this.owner,\n partition,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partitionGroup = new PartitionGroup(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionGroupParserHandler(\n this.scope,\n this.owner,\n partitionGroup,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n}\n\nexport class PageMasterParserHandler extends PageBoxParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n target: PageMaster,\n validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, target, validatorSet);\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partition = new Partition(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionParserHandler(\n this.scope,\n this.owner,\n partition,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partitionGroup = new PartitionGroup(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionGroupParserHandler(\n this.scope,\n this.owner,\n partitionGroup,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssPage - `@page` rule (CSS Paged Media) support https://drafts.csswg.org/css-page/\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as PageMaster from \"./page-master\";\nimport * as Sizing from \"./sizing\";\nimport * as Vtree from \"./vtree\";\n\n/**\n * Resolve page progression direction from writing-mode and direction.\n */\nexport function resolvePageProgression(\n style: CssCascade.ElementStyle,\n): Constants.PageProgression {\n let writingMode = style[\"writing-mode\"];\n writingMode = writingMode && writingMode.value;\n let direction = style[\"direction\"];\n direction = direction && direction.value;\n if (\n writingMode === Css.ident.vertical_lr ||\n (writingMode !== Css.ident.vertical_rl && direction !== Css.ident.rtl)\n ) {\n return Constants.PageProgression.LTR;\n } else {\n return Constants.PageProgression.RTL;\n }\n}\nexport type PageSize = {\n width: Css.Numeric;\n height: Css.Numeric;\n};\n\n/**\n * Named page sizes.\n */\nexport const pageSizes: { [key: string]: PageSize } = {\n a5: { width: new Css.Numeric(148, \"mm\"), height: new Css.Numeric(210, \"mm\") },\n a4: { width: new Css.Numeric(210, \"mm\"), height: new Css.Numeric(297, \"mm\") },\n a3: { width: new Css.Numeric(297, \"mm\"), height: new Css.Numeric(420, \"mm\") },\n b5: { width: new Css.Numeric(176, \"mm\"), height: new Css.Numeric(250, \"mm\") },\n b4: { width: new Css.Numeric(250, \"mm\"), height: new Css.Numeric(353, \"mm\") },\n \"jis-b5\": {\n width: new Css.Numeric(182, \"mm\"),\n height: new Css.Numeric(257, \"mm\"),\n },\n \"jis-b4\": {\n width: new Css.Numeric(257, \"mm\"),\n height: new Css.Numeric(364, \"mm\"),\n },\n letter: {\n width: new Css.Numeric(8.5, \"in\"),\n height: new Css.Numeric(11, \"in\"),\n },\n legal: {\n width: new Css.Numeric(8.5, \"in\"),\n height: new Css.Numeric(14, \"in\"),\n },\n ledger: {\n width: new Css.Numeric(11, \"in\"),\n height: new Css.Numeric(17, \"in\"),\n },\n};\n\n/**\n * Default value for line width of printer marks\n */\nexport const defaultPrinterMarkLineWidth: Css.Numeric = new Css.Numeric(\n 0.24,\n \"pt\",\n);\n\n/**\n * Default value for distance between an edge of the page and printer marks\n */\nexport const defaultPrinterMarkOffset: Css.Numeric = new Css.Numeric(3, \"mm\");\n\n/**\n * Default value for line length of the (shorter) line of a crop mark and the\n * shorter line of a cross mark\n */\nexport const defaultPrinterMarkLineLength: Css.Numeric = new Css.Numeric(\n 10,\n \"mm\",\n);\n\n/**\n * Default value for bleed offset (= defaultPrinterMarkOffset +\n * defaultPrinterMarkLineLength)\n */\nexport const defaultBleedOffset: Css.Numeric = new Css.Numeric(3 + 10, \"mm\");\n\nexport type PageSizeAndBleed = {\n width: Css.Numeric;\n height: Css.Numeric;\n bleed: Css.Numeric;\n bleedOffset: Css.Numeric;\n};\n\nexport function resolvePageSizeAndBleed(style: {\n [key: string]: CssCascade.CascadeValue;\n}): PageSizeAndBleed {\n // default value (fit to viewport, no bleed)\n const pageSizeAndBleed: PageSizeAndBleed = {\n width: Css.fullWidth,\n height: Css.fullHeight,\n bleed: Css.numericZero,\n bleedOffset: Css.numericZero,\n };\n const size: CssCascade.CascadeValue = style[\"size\"];\n\n if (!size || size.value === Css.ident.auto) {\n // if size is auto, fit to the viewport (use default value)\n } else {\n /** !type {!Css.Val} */\n const value = size.value;\n let val1: Css.Val;\n let val2: Css.Val;\n if (value.isSpaceList()) {\n val1 = (value as Css.SpaceList).values[0];\n val2 = (value as Css.SpaceList).values[1];\n } else {\n val1 = value;\n val2 = null;\n }\n if (val1.isNumeric()) {\n // <length>{1,2}\n pageSizeAndBleed.width = val1 as Css.Numeric;\n pageSizeAndBleed.height = (val2 || val1) as Css.Numeric;\n } else {\n // <page-size> || [ portrait | landscape ]\n const s =\n (val1 as any).name && pageSizes[(val1 as Css.Ident).name.toLowerCase()];\n if (!s) {\n // portrait or landscape is specified alone. fallback to fit to the\n // viewport (use default value)\n } else if (val2 && val2 === Css.ident.landscape) {\n // swap\n pageSizeAndBleed.width = s.height;\n pageSizeAndBleed.height = s.width;\n } else {\n // return {\n pageSizeAndBleed.width = s.width;\n pageSizeAndBleed.height = s.height;\n }\n }\n }\n const marks = style[\"marks\"];\n if (marks && marks.value !== Css.ident.none) {\n pageSizeAndBleed.bleedOffset = defaultBleedOffset;\n }\n const bleed = style[\"bleed\"];\n if (!bleed || bleed.value === Css.ident.auto) {\n // \"('auto' value) Computes to 6pt if marks has crop and to zero\n // otherwise.\" https://drafts.csswg.org/css-page/#valdef-page-bleed-auto\n if (marks) {\n let hasCrop = false;\n if (marks.value.isSpaceList()) {\n hasCrop = (marks.value as Css.SpaceList).values.some(\n (v) => v === Css.ident.crop,\n );\n } else {\n hasCrop = marks.value === Css.ident.crop;\n }\n if (hasCrop) {\n pageSizeAndBleed.bleed = new Css.Numeric(6, \"pt\");\n }\n }\n } else if (bleed.value && bleed.value.isNumeric()) {\n pageSizeAndBleed.bleed = bleed.value as Css.Numeric;\n }\n return pageSizeAndBleed;\n}\n\nexport type EvaluatedPageSizeAndBleed = {\n pageWidth: number;\n pageHeight: number;\n bleed: number;\n bleedOffset: number;\n cropOffset: number;\n};\n\n/**\n * Evaluate actual page width, height and bleed from style specified in page\n * context.\n */\nexport function evaluatePageSizeAndBleed(\n pageSizeAndBleed: PageSizeAndBleed,\n context: Exprs.Context,\n): EvaluatedPageSizeAndBleed {\n const evaluated = {} as EvaluatedPageSizeAndBleed;\n const bleed =\n pageSizeAndBleed.bleed.num *\n context.queryUnitSize(pageSizeAndBleed.bleed.unit, false);\n const bleedOffset =\n pageSizeAndBleed.bleedOffset.num *\n context.queryUnitSize(pageSizeAndBleed.bleedOffset.unit, false);\n const cropOffset = bleed + bleedOffset;\n const width = pageSizeAndBleed.width;\n if (width === Css.fullWidth) {\n if (context.pref.defaultPaperSize) {\n evaluated.pageWidth =\n context.pref.defaultPaperSize.width *\n context.queryUnitSize(\"px\", false);\n } else {\n evaluated.pageWidth =\n (context.pref.spreadView\n ? Math.floor(context.viewportWidth / 2) - context.pref.pageBorder\n : context.viewportWidth) -\n cropOffset * 2;\n }\n } else {\n evaluated.pageWidth = width.num * context.queryUnitSize(width.unit, false);\n }\n const height = pageSizeAndBleed.height;\n if (height === Css.fullHeight) {\n if (context.pref.defaultPaperSize) {\n evaluated.pageHeight =\n context.pref.defaultPaperSize.height *\n context.queryUnitSize(\"px\", false);\n } else {\n evaluated.pageHeight = context.viewportHeight - cropOffset * 2;\n }\n } else {\n evaluated.pageHeight =\n height.num * context.queryUnitSize(height.unit, false);\n }\n evaluated.bleed = bleed;\n evaluated.bleedOffset = bleedOffset;\n evaluated.cropOffset = cropOffset;\n return evaluated;\n}\n\n/**\n * Create an 'svg' element for a printer mark.\n */\nexport function createPrinterMarkSvg(\n doc: Document,\n width: number,\n height: number,\n): Element {\n const mark = doc.createElementNS(Base.NS.SVG, \"svg\");\n mark.setAttribute(\"width\", width);\n mark.setAttribute(\"height\", height);\n mark.style.position = \"absolute\";\n return mark;\n}\n\n/**\n * Create an SVG element for a printer mark line.\n * @param elementType Specifies which type of element to create. Default value\n * is \"polyline\".\n */\nexport function createPrinterMarkElement(\n doc: Document,\n lineWidth: number,\n elementType?: string,\n): Element {\n elementType = elementType || \"polyline\";\n const line = doc.createElementNS(Base.NS.SVG, elementType);\n line.setAttribute(\"stroke\", \"black\");\n line.setAttribute(\"stroke-width\", lineWidth);\n line.setAttribute(\"fill\", \"none\");\n return line;\n}\n\n/**\n * Position of a corner mark\n * @enum {string}\n */\nexport enum CornerMarkPosition {\n TOP_LEFT = \"top left\",\n TOP_RIGHT = \"top right\",\n BOTTOM_LEFT = \"bottom left\",\n BOTTOM_RIGHT = \"bottom right\",\n}\n\n/**\n * Create a corner mark.\n */\nexport function createCornerMark(\n doc: Document,\n position: CornerMarkPosition,\n lineWidth: number,\n cropMarkLineLength: number,\n bleed: number,\n offset: number,\n): Element {\n let bleedMarkLineLength = cropMarkLineLength;\n\n // bleed mark line should be longer than bleed + 2mm\n if (bleedMarkLineLength <= bleed + 2 * Exprs.defaultUnitSizes[\"mm\"]) {\n bleedMarkLineLength = bleed + cropMarkLineLength / 2;\n }\n const maxLineLength = Math.max(cropMarkLineLength, bleedMarkLineLength);\n const svgWidth = bleed + maxLineLength + lineWidth / 2;\n const mark = createPrinterMarkSvg(doc, svgWidth, svgWidth);\n let points1 = [\n [0, bleed + cropMarkLineLength],\n [cropMarkLineLength, bleed + cropMarkLineLength],\n [cropMarkLineLength, bleed + cropMarkLineLength - bleedMarkLineLength],\n ];\n\n // reflect with respect to y=x\n let points2 = points1.map((p) => [p[1], p[0]]);\n if (\n position === CornerMarkPosition.TOP_RIGHT ||\n position === CornerMarkPosition.BOTTOM_RIGHT\n ) {\n // reflect with respect to a vertical axis\n points1 = points1.map((p) => [bleed + maxLineLength - p[0], p[1]]);\n points2 = points2.map((p) => [bleed + maxLineLength - p[0], p[1]]);\n }\n if (\n position === CornerMarkPosition.BOTTOM_LEFT ||\n position === CornerMarkPosition.BOTTOM_RIGHT\n ) {\n // reflect with respect to a vertical axis\n points1 = points1.map((p) => [p[0], bleed + maxLineLength - p[1]]);\n points2 = points2.map((p) => [p[0], bleed + maxLineLength - p[1]]);\n }\n const line1 = createPrinterMarkElement(doc, lineWidth);\n line1.setAttribute(\"points\", points1.map((p) => p.join(\",\")).join(\" \"));\n mark.appendChild(line1);\n const line2 = createPrinterMarkElement(doc, lineWidth);\n line2.setAttribute(\"points\", points2.map((p) => p.join(\",\")).join(\" \"));\n mark.appendChild(line2);\n position.split(\" \").forEach((side) => {\n (mark as any).style[side] = `${offset}px`;\n });\n return mark;\n}\n\n/**\n * Position of a cross mark\n * @enum {string}\n */\nexport enum CrossMarkPosition {\n TOP = \"top\",\n BOTTOM = \"bottom\",\n LEFT = \"left\",\n RIGHT = \"right\",\n}\n\n/**\n * Create a cross mark.\n */\nexport function createCrossMark(\n doc: Document,\n position: CrossMarkPosition,\n lineWidth: number,\n lineLength: number,\n offset: number,\n): Element {\n const longLineLength = lineLength * 2;\n let width: number;\n let height: number;\n if (\n position === CrossMarkPosition.TOP ||\n position === CrossMarkPosition.BOTTOM\n ) {\n width = longLineLength;\n height = lineLength;\n } else {\n width = lineLength;\n height = longLineLength;\n }\n const mark = createPrinterMarkSvg(doc, width, height);\n const horizontalLine = createPrinterMarkElement(doc, lineWidth);\n horizontalLine.setAttribute(\n \"points\",\n `0,${height / 2} ${width},${height / 2}`,\n );\n mark.appendChild(horizontalLine);\n const verticalLine = createPrinterMarkElement(doc, lineWidth);\n verticalLine.setAttribute(\"points\", `${width / 2},0 ${width / 2},${height}`);\n mark.appendChild(verticalLine);\n const circle = createPrinterMarkElement(doc, lineWidth, \"circle\");\n circle.setAttribute(\"cx\", width / 2);\n circle.setAttribute(\"cy\", height / 2);\n circle.setAttribute(\"r\", lineLength / 4);\n mark.appendChild(circle);\n let opposite: CrossMarkPosition;\n switch (position) {\n case CrossMarkPosition.TOP:\n opposite = CrossMarkPosition.BOTTOM;\n break;\n case CrossMarkPosition.BOTTOM:\n opposite = CrossMarkPosition.TOP;\n break;\n case CrossMarkPosition.LEFT:\n opposite = CrossMarkPosition.RIGHT;\n break;\n case CrossMarkPosition.RIGHT:\n opposite = CrossMarkPosition.LEFT;\n break;\n }\n Object.keys(CrossMarkPosition).forEach((key) => {\n const side = CrossMarkPosition[key];\n if (side === position) {\n (mark as any).style[side] = `${offset}px`;\n } else if (side !== opposite) {\n (mark as any).style[side] = \"0\";\n (mark as any).style[`margin-${side}`] = \"auto\";\n }\n });\n return mark;\n}\n\n/**\n * Add printer marks to the page.\n */\nexport function addPrinterMarks(\n cascadedPageStyle: CssCascade.ElementStyle,\n evaluatedPageSizeAndBleed: EvaluatedPageSizeAndBleed,\n page: Vtree.Page,\n context: Exprs.Context,\n): void {\n let crop = false;\n let cross = false;\n const marks = cascadedPageStyle[\"marks\"];\n if (marks) {\n const value = marks.value;\n if (value.isSpaceList()) {\n value.values.forEach((v) => {\n if (v === Css.ident.crop) {\n crop = true;\n } else if (v === Css.ident.cross) {\n cross = true;\n }\n });\n } else if (value === Css.ident.crop) {\n crop = true;\n } else if (value === Css.ident.cross) {\n cross = true;\n }\n }\n if (!crop && !cross) {\n return;\n }\n const container = page.container;\n const doc = container.ownerDocument as Document;\n Asserts.assert(doc);\n const bleed = evaluatedPageSizeAndBleed.bleed;\n const lineWidth = Css.toNumber(defaultPrinterMarkLineWidth, context);\n const printerMarkOffset = Css.toNumber(defaultPrinterMarkOffset, context);\n const lineLength = Css.toNumber(defaultPrinterMarkLineLength, context);\n\n if (bleed) {\n const bgcolor = cascadedPageStyle[\"background-color\"];\n if (bgcolor && bgcolor.value) {\n page.bleedBox.style.backgroundColor = bgcolor.value.stringValue();\n }\n }\n\n // corner marks\n if (crop) {\n Object.keys(CornerMarkPosition).forEach((key) => {\n const position = CornerMarkPosition[key];\n const mark = createCornerMark(\n doc,\n position,\n lineWidth,\n lineLength,\n bleed,\n printerMarkOffset,\n );\n container.appendChild(mark);\n });\n }\n\n // cross marks\n if (cross) {\n Object.keys(CrossMarkPosition).forEach((key) => {\n const position = CrossMarkPosition[key];\n const mark = createCrossMark(\n doc,\n position,\n lineWidth,\n lineLength,\n printerMarkOffset,\n );\n container.appendChild(mark);\n });\n }\n}\n\n/**\n * Properties transfered from the PageRuleMaster to the PageRulePartition\n */\nexport const propertiesAppliedToPartition = (() => {\n const sides = [\n \"left\",\n \"right\",\n \"top\",\n \"bottom\",\n \"before\",\n \"after\",\n \"start\",\n \"end\",\n \"block-start\",\n \"block-end\",\n \"inline-start\",\n \"inline-end\",\n ];\n const props = {\n width: true,\n height: true,\n \"block-size\": true,\n \"inline-size\": true,\n margin: true,\n padding: true,\n border: true,\n outline: true,\n \"outline-width\": true,\n \"outline-style\": true,\n \"outline-color\": true,\n };\n sides.forEach((side) => {\n props[`margin-${side}`] = true;\n props[`padding-${side}`] = true;\n props[`border-${side}-width`] = true;\n props[`border-${side}-style`] = true;\n props[`border-${side}-color`] = true;\n });\n return props;\n})();\n\n/**\n * Represents position of a margin box along the variable dimension of the page.\n * START and END can be interpreted as 'inline-start' and 'inline-end' in\n * horizontal and vertical writing modes. For example, for top margin boxes\n * (@top-left-corner, @top-left, @top-center, @top-right, @top-right-corner),\n * @top-left corresponds to START, @top-center to CENTER, and @top-right to END.\n * The corner boxes (@top-left-corner and @top-right-corner) have a 'null'\n * position.\n * @enum {string}\n */\nexport enum MarginBoxPositionAlongVariableDimension {\n START = \"start\",\n CENTER = \"center\",\n END = \"end\",\n}\n\nexport type PageMarginBoxInformation = {\n order: number;\n isInTopRow: boolean;\n isInBottomRow: boolean;\n isInLeftColumn: boolean;\n isInRightColumn: boolean;\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension;\n};\n\n/**\n * Page-margin boxes.\n * @dict\n */\nexport const pageMarginBoxes: { [key: string]: PageMarginBoxInformation } = {\n \"top-left-corner\": {\n order: 1,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: true,\n positionAlongVariableDimension: null,\n },\n \"top-left\": {\n order: 2,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n \"top-center\": {\n order: 3,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"top-right\": {\n order: 4,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"top-right-corner\": {\n order: 5,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension: null,\n },\n \"right-top\": {\n order: 6,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n \"right-middle\": {\n order: 7,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"right-bottom\": {\n order: 8,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"bottom-right-corner\": {\n order: 9,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension: null,\n },\n \"bottom-right\": {\n order: 10,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"bottom-center\": {\n order: 11,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"bottom-left\": {\n order: 12,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n \"bottom-left-corner\": {\n order: 13,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension: null,\n },\n \"left-bottom\": {\n order: 14,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"left-middle\": {\n order: 15,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"left-top\": {\n order: 16,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n};\n\n/**\n * Names for page-margin boxes order in the default painting order.\n */\nexport const pageMarginBoxNames: string[] = (() => {\n const boxes = pageMarginBoxes;\n return Object.keys(boxes).sort((a, b) => boxes[a].order - boxes[b].order);\n})();\n\n/**\n * Indicates that the page master is generated for `@page` rules.\n */\nexport const pageRuleMasterPseudoName = \"vivliostyle-page-rule-master\";\n\n/**\n * Key for properties in margin contexts.\n * Styles in margin contexts are stored in pageStyle[\"_marginBoxes\"][(margin\n * box's name)].\n */\nexport const marginBoxesKey: string = \"_marginBoxes\";\n\n/**\n * Represent a page master generated for `@page` rules\n * @param style Cascaded style for `@page` rules\n */\nexport class PageRuleMaster extends PageMaster.PageMaster<\n PageRuleMasterInstance\n> {\n private bodyPartitionKey: string;\n private pageMarginBoxes = {} as {\n [key: string]: PageMarginBoxPartition;\n };\n\n constructor(\n scope: Exprs.LexicalScope,\n parent: PageMaster.RootPageBox,\n style: CssCascade.ElementStyle,\n ) {\n super(scope, null, pageRuleMasterPseudoName, [], parent, null, 0);\n const pageSize = resolvePageSizeAndBleed(style as any);\n const partition = new PageRulePartition(this.scope, this, style, pageSize);\n this.bodyPartitionKey = partition.key;\n this.createPageMarginBoxes(style);\n this.applySpecified(style, pageSize);\n }\n\n /**\n * Create page-margin boxes\n */\n createPageMarginBoxes(style: CssCascade.ElementStyle) {\n const marginBoxesMap = style[marginBoxesKey];\n if (marginBoxesMap) {\n const self = this;\n pageMarginBoxNames.forEach((name) => {\n if (marginBoxesMap[name]) {\n self.pageMarginBoxes[name] = new PageMarginBoxPartition(\n self.scope,\n self,\n name,\n style,\n );\n }\n });\n }\n }\n\n /**\n * Transfer cascaded style for `@page` rules to 'specified' style of this\n * PageBox\n */\n private applySpecified(style: CssCascade.ElementStyle, pageSize: PageSize) {\n this.specified[\"position\"] = new CssCascade.CascadeValue(\n Css.ident.relative,\n 0,\n );\n this.specified[\"width\"] = new CssCascade.CascadeValue(pageSize.width, 0);\n this.specified[\"height\"] = new CssCascade.CascadeValue(pageSize.height, 0);\n for (const name in style) {\n if (!propertiesAppliedToPartition[name] && name !== \"background-clip\") {\n this.specified[name] = style[name];\n }\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageRuleMasterInstance {\n return new PageRuleMasterInstance(parentInstance, this);\n }\n}\n\n/**\n * Represent a partition placed in a PageRuleMaster\n * @param style Cascaded style for `@page` rules\n */\nexport class PageRulePartition extends PageMaster.Partition<\n PageRulePartitionInstance\n> {\n constructor(\n scope: Exprs.LexicalScope,\n parent: PageRuleMaster,\n style: CssCascade.ElementStyle,\n public readonly pageSize: PageSize,\n ) {\n super(scope, null, null, [], parent);\n this.specified[\"z-index\"] = new CssCascade.CascadeValue(new Css.Int(0), 0);\n this.applySpecified(style);\n }\n\n /**\n * Transfer cascaded style for `@page` rules to 'specified' style of this\n * PageBox\n */\n private applySpecified(style: CssCascade.ElementStyle) {\n this.specified[\"flow-from\"] = new CssCascade.CascadeValue(\n Css.getName(\"body\"),\n 0,\n );\n\n // Use absolute positioning so that this partition's margins don't collapse\n // with its parent's margins\n this.specified[\"position\"] = new CssCascade.CascadeValue(\n Css.ident.absolute,\n 0,\n );\n this.specified[\"overflow\"] = new CssCascade.CascadeValue(\n Css.ident.visible,\n 0,\n );\n for (const prop in propertiesAppliedToPartition) {\n if (propertiesAppliedToPartition.hasOwnProperty(prop)) {\n this.specified[prop] = style[prop];\n }\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageMaster.PageBoxInstance {\n return new PageRulePartitionInstance(parentInstance, this);\n }\n}\n\n/**\n * Represent a partition for a page-margin box\n */\nexport class PageMarginBoxPartition extends PageMaster.Partition<\n PageMarginBoxPartitionInstance\n> {\n constructor(\n scope: Exprs.LexicalScope,\n parent: PageRuleMaster,\n public readonly marginBoxName: string,\n style: CssCascade.ElementStyle,\n ) {\n super(scope, null, null, [], parent);\n this.applySpecified(style);\n }\n\n /**\n * Transfer cascaded style for `@page` rules to 'specified' style of this\n * PageMarginBox\n */\n applySpecified(style: CssCascade.ElementStyle) {\n const ownStyle = style[marginBoxesKey][\n this.marginBoxName\n ] as CssCascade.ElementStyle;\n\n // Inherit properties in the page context to the page-margin context\n for (const prop in style) {\n const val = style[prop] as CssCascade.CascadeValue;\n const ownVal = ownStyle[prop] as CssCascade.CascadeValue;\n if (\n CssCascade.inheritedProps[prop] ||\n (ownVal && ownVal.value === Css.ident.inherit)\n ) {\n this.specified[prop] = val;\n }\n }\n for (const prop in ownStyle) {\n if (Object.prototype.hasOwnProperty.call(ownStyle, prop)) {\n const val = ownStyle[prop] as CssCascade.CascadeValue;\n if (val && val.value !== Css.ident.inherit) {\n this.specified[prop] = val;\n }\n }\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageMaster.PageBoxInstance {\n return new PageMarginBoxPartitionInstance(parentInstance, this);\n }\n}\n\n//---------------------------- Instance --------------------------------\nexport type PageAreaDimension = {\n borderBoxWidth: Exprs.Val;\n borderBoxHeight: Exprs.Val;\n marginTop: Exprs.Val;\n marginBottom: Exprs.Val;\n marginLeft: Exprs.Val;\n marginRight: Exprs.Val;\n};\n\nexport class PageRuleMasterInstance extends PageMaster.PageMasterInstance<\n PageRuleMaster\n> {\n pageAreaDimension: PageAreaDimension | null = null;\n pageMarginBoxInstances: {\n [key: string]: PageMarginBoxPartitionInstance;\n } = {};\n\n constructor(\n parentInstance: PageMaster.PageBoxInstance,\n pageRuleMaster: PageRuleMaster,\n ) {\n super(parentInstance, pageRuleMaster);\n }\n\n /**\n * @override\n */\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n const style = this.cascaded;\n for (const name in docElementStyle) {\n if (Object.prototype.hasOwnProperty.call(docElementStyle, name)) {\n switch (name) {\n case \"writing-mode\":\n case \"direction\":\n style[name] = docElementStyle[name];\n }\n }\n }\n super.applyCascadeAndInit(cascade, docElementStyle);\n }\n\n /**\n * @override\n */\n initHorizontal(): void {\n const style = this.style;\n style[\"left\"] = Css.numericZero;\n style[\"margin-left\"] = Css.numericZero;\n style[\"border-left-width\"] = Css.numericZero;\n style[\"padding-left\"] = Css.numericZero;\n style[\"padding-right\"] = Css.numericZero;\n style[\"border-right-width\"] = Css.numericZero;\n style[\"margin-right\"] = Css.numericZero;\n style[\"right\"] = Css.numericZero;\n }\n\n /**\n * @override\n */\n initVertical(): void {\n const style = this.style;\n\n // Shift 1px to workaround Chrome printing bug\n // style[\"top\"] = new Css.Numeric(-1, \"px\");\n style[\"top\"] = Css.numericZero;\n style[\"margin-top\"] = Css.numericZero;\n style[\"border-top-width\"] = Css.numericZero;\n style[\"padding-top\"] = Css.numericZero;\n style[\"padding-bottom\"] = Css.numericZero;\n style[\"border-bottom-width\"] = Css.numericZero;\n style[\"margin-bottom\"] = Css.numericZero;\n style[\"bottom\"] = Css.numericZero;\n }\n\n setPageAreaDimension(dim: PageAreaDimension) {\n this.pageAreaDimension = dim;\n const style = this.style;\n style[\"width\"] = new Css.Expr(dim.borderBoxWidth);\n style[\"height\"] = new Css.Expr(dim.borderBoxHeight);\n style[\"padding-left\"] = new Css.Expr(dim.marginLeft);\n style[\"padding-right\"] = new Css.Expr(dim.marginRight);\n style[\"padding-top\"] = new Css.Expr(dim.marginTop);\n style[\"padding-bottom\"] = new Css.Expr(dim.marginBottom);\n }\n\n /**\n * @override\n */\n adjustPageLayout(\n context: Exprs.Context,\n page: Vtree.Page,\n clientLayout: Vtree.ClientLayout,\n ) {\n const marginBoxContainers = page.marginBoxes;\n const horizontalDimensions = {\n start: this.pageAreaDimension.marginLeft,\n end: this.pageAreaDimension.marginRight,\n extent: this.pageAreaDimension.borderBoxWidth,\n };\n const verticalDimensions = {\n start: this.pageAreaDimension.marginTop,\n end: this.pageAreaDimension.marginBottom,\n extent: this.pageAreaDimension.borderBoxHeight,\n };\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.top,\n true,\n horizontalDimensions,\n context,\n clientLayout,\n );\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.bottom,\n true,\n horizontalDimensions,\n context,\n clientLayout,\n );\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.left,\n false,\n verticalDimensions,\n context,\n clientLayout,\n );\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.right,\n false,\n verticalDimensions,\n context,\n clientLayout,\n );\n }\n\n /**\n * Determine and set margin boxes' sizes along variable dimension using an\n * algorithm specified in CSS Paged Media spec.\n * @param marginBoxContainers Containers corresponding to the target margin\n * boxes in one page edge (top, bottom, left, right)\n * @param isHorizontal Indicates if the target margin boxes are on the\n * horizontal edge (top or bottom) or not (left or right).\n * @param dimensions Page dimensions. start: margin-left or margin-top. end:\n * margin-right or margin-bottom. extent: border-box width or height of\n * the page area (= available width or height for the target margin boxes)\n */\n private sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers: { [key: string]: Vtree.Container },\n isHorizontal: boolean,\n dimensions: { start: Exprs.Val; end: Exprs.Val; extent: Exprs.Val },\n context: Exprs.Context,\n clientLayout: Vtree.ClientLayout,\n ) {\n const START = MarginBoxPositionAlongVariableDimension.START;\n const CENTER = MarginBoxPositionAlongVariableDimension.CENTER;\n const END = MarginBoxPositionAlongVariableDimension.END;\n\n // prepare parameters\n const scope = this.pageBox.scope;\n const containers: {\n [key in MarginBoxPositionAlongVariableDimension]?: Vtree.Container;\n } = {};\n const boxInstances: {\n [key in MarginBoxPositionAlongVariableDimension]?: PageMarginBoxPartitionInstance;\n } = {};\n const boxParams: {\n [key in MarginBoxPositionAlongVariableDimension]?: MarginBoxSizingParam;\n } = {};\n for (const name in marginBoxContainers) {\n const boxInfo = pageMarginBoxes[name];\n if (boxInfo) {\n const container = marginBoxContainers[name];\n const boxInstance = this.pageMarginBoxInstances[name];\n const boxParam = new SingleBoxMarginBoxSizingParam(\n container,\n (boxInstance as any).style,\n isHorizontal,\n scope,\n clientLayout,\n );\n containers[boxInfo.positionAlongVariableDimension] = container;\n boxInstances[boxInfo.positionAlongVariableDimension] = boxInstance;\n boxParams[boxInfo.positionAlongVariableDimension] = boxParam;\n }\n }\n\n // determine sizes\n const evaluatedDim = {\n start: dimensions.start.evaluate(context) as number,\n end: dimensions.end.evaluate(context) as number,\n extent: dimensions.extent.evaluate(context) as number,\n };\n let sizes = this.getSizesOfMarginBoxesAlongVariableDimension(\n boxParams,\n evaluatedDim.extent,\n );\n let needRecalculate: boolean = false;\n\n // Check max-width/max-height\n const maxOuterSizes: {\n [key in MarginBoxPositionAlongVariableDimension]?: number;\n } = {};\n Object.keys(containers).forEach((n) => {\n const name = n as MarginBoxPositionAlongVariableDimension;\n const maxSize = PageMaster.toExprAuto(\n scope,\n boxInstances[name].style[isHorizontal ? \"max-width\" : \"max-height\"],\n dimensions.extent,\n );\n if (maxSize) {\n const evaluatedMaxSize = maxSize.evaluate(context) as number;\n if (sizes[name] > evaluatedMaxSize) {\n const p = (boxParams[name] = new FixedSizeMarginBoxSizingParam(\n containers[name],\n boxInstances[name].style,\n isHorizontal,\n scope,\n clientLayout,\n evaluatedMaxSize,\n ));\n maxOuterSizes[name] = p.getOuterSize();\n needRecalculate = true;\n }\n }\n });\n if (needRecalculate) {\n sizes = this.getSizesOfMarginBoxesAlongVariableDimension(\n boxParams,\n evaluatedDim.extent,\n );\n needRecalculate = false;\n [START, CENTER, END].forEach((name) => {\n sizes[name] = maxOuterSizes[name] || sizes[name];\n });\n }\n\n // Check min-width/min-height\n const minOuterSizes: {\n [key in MarginBoxPositionAlongVariableDimension]?: number;\n } = {};\n Object.keys(containers).forEach((n) => {\n const name = n as MarginBoxPositionAlongVariableDimension;\n const minSize = PageMaster.toExprAuto(\n scope,\n boxInstances[name].style[isHorizontal ? \"min-width\" : \"min-height\"],\n dimensions.extent,\n );\n if (minSize) {\n const evaluatedMinSize = minSize.evaluate(context) as number;\n if (sizes[name] < evaluatedMinSize) {\n const p = (boxParams[name] = new FixedSizeMarginBoxSizingParam(\n containers[name],\n boxInstances[name].style,\n isHorizontal,\n scope,\n clientLayout,\n evaluatedMinSize,\n ));\n minOuterSizes[name] = p.getOuterSize();\n needRecalculate = true;\n }\n }\n });\n if (needRecalculate) {\n sizes = this.getSizesOfMarginBoxesAlongVariableDimension(\n boxParams,\n evaluatedDim.extent,\n );\n [START, CENTER, END].forEach((name) => {\n sizes[name] = minOuterSizes[name] || sizes[name];\n });\n }\n\n // set sizes\n const endEdge = evaluatedDim.start + evaluatedDim.extent;\n const startEndSum =\n evaluatedDim.start + (evaluatedDim.start + evaluatedDim.extent);\n [START, CENTER, END].forEach((name) => {\n const outerSize = sizes[name];\n if (outerSize) {\n const container = containers[name];\n let offset = 0;\n switch (name) {\n case START:\n offset = isHorizontal ? container.left : container.top;\n break;\n case CENTER:\n offset = (startEndSum - outerSize) / 2;\n break;\n case END:\n offset = endEdge - outerSize;\n break;\n }\n if (isHorizontal) {\n container.setHorizontalPosition(\n offset,\n outerSize - container.getInsetLeft() - container.getInsetRight(),\n );\n } else {\n container.setVerticalPosition(\n offset,\n outerSize - container.getInsetTop() - container.getInsetBottom(),\n );\n }\n }\n });\n }\n\n private getSizesOfMarginBoxesAlongVariableDimension(\n boxParams: {\n [key in MarginBoxPositionAlongVariableDimension]?: MarginBoxSizingParam;\n },\n availableSize: number,\n ): { [key in MarginBoxPositionAlongVariableDimension]?: number } {\n const startBoxParam =\n boxParams[MarginBoxPositionAlongVariableDimension.START];\n const centerBoxParam =\n boxParams[MarginBoxPositionAlongVariableDimension.CENTER];\n const endBoxParam = boxParams[MarginBoxPositionAlongVariableDimension.END];\n const sizes: {\n [key in MarginBoxPositionAlongVariableDimension]?: number;\n } = {};\n if (!centerBoxParam) {\n const startEndSizes = this.distributeAutoMarginBoxSizes(\n startBoxParam,\n endBoxParam,\n availableSize,\n );\n if (startEndSizes.xSize) {\n sizes[MarginBoxPositionAlongVariableDimension.START] =\n startEndSizes.xSize;\n }\n if (startEndSizes.ySize) {\n sizes[MarginBoxPositionAlongVariableDimension.END] =\n startEndSizes.ySize;\n }\n } else {\n const params = [startBoxParam, endBoxParam].filter((p) => p);\n const startEndBoxParam = params.length\n ? new MultipleBoxesMarginBoxSizingParam(params)\n : null;\n const centerSizes = this.distributeAutoMarginBoxSizes(\n centerBoxParam,\n startEndBoxParam,\n availableSize,\n );\n if (centerSizes.xSize) {\n sizes[MarginBoxPositionAlongVariableDimension.CENTER] =\n centerSizes.xSize;\n }\n const centerSize = centerSizes.xSize || centerBoxParam.getOuterSize();\n const startEndAutoSize = (availableSize - centerSize) / 2;\n if (startBoxParam && startBoxParam.hasAutoSize()) {\n sizes[MarginBoxPositionAlongVariableDimension.START] = startEndAutoSize;\n }\n if (endBoxParam && endBoxParam.hasAutoSize()) {\n sizes[MarginBoxPositionAlongVariableDimension.END] = startEndAutoSize;\n }\n }\n return sizes;\n }\n\n /**\n * Distribute auto margin sizes among two margin boxes using an algorithm\n * specified in CSS Paged Media spec.\n * @param x Parameter for the first margin box. null if the box is not\n * generated.\n * @param y Parameter for the second margin box. null if the box is not\n * generated.\n * @param availableSize Available size for the margin boxes.\n * @returns Determined sizes for the two boxes. Each value is present only\n * when the size of the corresponding box is 'auto'.\n */\n private distributeAutoMarginBoxSizes(\n x: MarginBoxSizingParam,\n y: MarginBoxSizingParam,\n availableSize: number,\n ): { xSize: number | null; ySize: number | null } {\n const result: { xSize: number | null; ySize: number | null } = {\n xSize: null,\n ySize: null,\n };\n if (x && y) {\n if (x.hasAutoSize() && y.hasAutoSize()) {\n const xOuterMaxContentSize = x.getOuterMaxContentSize();\n const yOuterMaxContentSize = y.getOuterMaxContentSize();\n if (xOuterMaxContentSize > 0 && yOuterMaxContentSize > 0) {\n const maxContentSizeSum = xOuterMaxContentSize + yOuterMaxContentSize;\n if (maxContentSizeSum < availableSize) {\n result.xSize =\n (availableSize * xOuterMaxContentSize) / maxContentSizeSum;\n } else {\n const xOuterMinContentSize = x.getOuterMinContentSize();\n const yOuterMinContentSize = y.getOuterMinContentSize();\n const minContentSizeSum =\n xOuterMinContentSize + yOuterMinContentSize;\n if (minContentSizeSum < availableSize) {\n result.xSize =\n xOuterMinContentSize +\n ((availableSize - minContentSizeSum) *\n (xOuterMaxContentSize - xOuterMinContentSize)) /\n (maxContentSizeSum - minContentSizeSum);\n } else if (minContentSizeSum > 0) {\n result.xSize =\n (availableSize * xOuterMinContentSize) / minContentSizeSum;\n }\n }\n if (result.xSize > 0) {\n result.ySize = availableSize - result.xSize;\n }\n } else if (xOuterMaxContentSize > 0) {\n result.xSize = availableSize;\n } else if (yOuterMaxContentSize > 0) {\n result.ySize = availableSize;\n }\n } else if (x.hasAutoSize()) {\n result.xSize = Math.max(availableSize - y.getOuterSize(), 0);\n } else if (y.hasAutoSize()) {\n result.ySize = Math.max(availableSize - x.getOuterSize(), 0);\n }\n } else if (x) {\n if (x.hasAutoSize()) {\n result.xSize = availableSize;\n }\n } else if (y) {\n if (y.hasAutoSize()) {\n result.ySize = availableSize;\n }\n }\n return result;\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n\n // Add an attribute to the element so that it can be refered from external\n // style sheets.\n container.element.setAttribute(\"data-vivliostyle-page-box\", true);\n }\n}\n\n/**\n * Interface used for parameters passed to distributeAutoMarginBoxSizes method.\n */\ninterface MarginBoxSizingParam {\n hasAutoSize(): boolean;\n\n getOuterMaxContentSize(): number;\n\n getOuterMinContentSize(): number;\n\n getOuterSize(): number;\n}\n\n/**\n * MarginBoxSizingParam for a single page-margin box.\n * @param container A container corresponding to the target margin box.\n * @param style Styles specified to the target margin box.\n */\nclass SingleBoxMarginBoxSizingParam implements MarginBoxSizingParam {\n private hasAutoSize_: boolean;\n private size: { [key in Sizing.Size]: number } | null = null;\n\n constructor(\n protected readonly container: Vtree.Container,\n style: { [key: string]: Css.Val },\n protected readonly isHorizontal: boolean,\n scope: Exprs.LexicalScope,\n private readonly clientLayout: Vtree.ClientLayout,\n ) {\n this.hasAutoSize_ = !PageMaster.toExprAuto(\n scope,\n style[isHorizontal ? \"width\" : \"height\"],\n new Exprs.Numeric(scope, 0, \"px\"),\n );\n }\n\n /**\n * @override\n */\n hasAutoSize(): boolean {\n return this.hasAutoSize_;\n }\n\n private getSize(): { [key in Sizing.Size]: number } {\n if (!this.size) {\n const sizes = this.isHorizontal\n ? [Sizing.Size.MAX_CONTENT_WIDTH, Sizing.Size.MIN_CONTENT_WIDTH]\n : [Sizing.Size.MAX_CONTENT_HEIGHT, Sizing.Size.MIN_CONTENT_HEIGHT];\n this.size = Sizing.getSize(\n this.clientLayout,\n this.container.element,\n sizes,\n );\n }\n return this.size;\n }\n\n /**\n * @override\n */\n getOuterMaxContentSize(): number {\n const size = this.getSize();\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n size[Sizing.Size.MAX_CONTENT_WIDTH] +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n size[Sizing.Size.MAX_CONTENT_HEIGHT] +\n this.container.getInsetBottom()\n );\n }\n }\n\n /**\n * @override\n */\n getOuterMinContentSize(): number {\n const size = this.getSize();\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n size[Sizing.Size.MIN_CONTENT_WIDTH] +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n size[Sizing.Size.MIN_CONTENT_HEIGHT] +\n this.container.getInsetBottom()\n );\n }\n }\n\n /**\n * @override\n */\n getOuterSize(): number {\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n this.container.width +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n this.container.height +\n this.container.getInsetBottom()\n );\n }\n }\n}\n\n/**\n * MarginBoxSizingParam with which multiple margin boxes are treated as one\n * margin box. Each method querying a dimension returns the maximum of the boxes\n * multiplied by the number of the boxes.\n * @param params MarginBoxSizingParam's of the target margin boxes.\n */\nclass MultipleBoxesMarginBoxSizingParam implements MarginBoxSizingParam {\n constructor(private readonly params: MarginBoxSizingParam[]) {}\n\n /**\n * @override\n */\n hasAutoSize(): boolean {\n return this.params.some((p) => p.hasAutoSize());\n }\n\n /**\n * @override\n */\n getOuterMaxContentSize(): number {\n const sizes = this.params.map((p) => p.getOuterMaxContentSize());\n return Math.max.apply(null, sizes) * sizes.length;\n }\n\n /**\n * @override\n */\n getOuterMinContentSize(): number {\n const sizes = this.params.map((p) => p.getOuterMinContentSize());\n return Math.max.apply(null, sizes) * sizes.length;\n }\n\n /**\n * @override\n */\n getOuterSize(): number {\n const sizes = this.params.map((p) => p.getOuterSize());\n return Math.max.apply(null, sizes) * sizes.length;\n }\n}\n\n/**\n * MarginBoxSizingParam for a single page-margin box with a fixed size along the\n * variable dimension.\n * @param container A container corresponding to the target margin box.\n * @param style Styles specified to the target margin box.\n * @param size The fixed size (width or height) along the variable dimension.\n */\nclass FixedSizeMarginBoxSizingParam extends SingleBoxMarginBoxSizingParam {\n private fixedSize: number;\n\n constructor(\n container: Vtree.Container,\n style: { [key: string]: Css.Val },\n isHorizontal: boolean,\n scope: Exprs.LexicalScope,\n clientLayout: Vtree.ClientLayout,\n size: number,\n ) {\n super(container, style, isHorizontal, scope, clientLayout);\n this.fixedSize = size;\n }\n\n /**\n * @override\n */\n hasAutoSize(): boolean {\n return false;\n }\n\n /**\n * @override\n */\n getOuterMaxContentSize(): number {\n return this.getOuterSize();\n }\n\n /**\n * @override\n */\n getOuterMinContentSize(): number {\n return this.getOuterSize();\n }\n\n /**\n * @override\n */\n getOuterSize(): number {\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n this.fixedSize +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n this.fixedSize +\n this.container.getInsetBottom()\n );\n }\n }\n}\n\nexport class PageRulePartitionInstance extends PageMaster.PartitionInstance<\n PageRulePartition\n> {\n borderBoxWidth: Exprs.Val = null;\n borderBoxHeight: Exprs.Val = null;\n marginTop: Exprs.Val = null;\n marginRight: Exprs.Val = null;\n marginBottom: Exprs.Val = null;\n marginLeft: Exprs.Val = null;\n\n constructor(\n parentInstance: PageMaster.PageBoxInstance,\n pageRulePartition: PageRulePartition,\n ) {\n super(parentInstance, pageRulePartition);\n }\n\n /**\n * @override\n */\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n const style = this.cascaded;\n for (const name in docElementStyle) {\n if (Object.prototype.hasOwnProperty.call(docElementStyle, name)) {\n if (name.match(/^column.*$/) || name.match(/^background-/)) {\n style[name] = docElementStyle[name];\n }\n }\n }\n super.applyCascadeAndInit(cascade, docElementStyle);\n const pageRuleMasterInstance = this\n .parentInstance as PageRuleMasterInstance;\n pageRuleMasterInstance.setPageAreaDimension({\n borderBoxWidth: this.borderBoxWidth,\n borderBoxHeight: this.borderBoxHeight,\n marginTop: this.marginTop,\n marginRight: this.marginRight,\n marginBottom: this.marginBottom,\n marginLeft: this.marginLeft,\n });\n }\n\n /**\n * @override\n */\n initHorizontal(): void {\n const dim = this.resolvePageBoxDimensions({\n start: \"left\",\n end: \"right\",\n extent: \"width\",\n });\n this.borderBoxWidth = dim.borderBoxExtent;\n this.marginLeft = dim.marginStart;\n this.marginRight = dim.marginEnd;\n }\n\n /**\n * @override\n */\n initVertical(): void {\n const dim = this.resolvePageBoxDimensions({\n start: \"top\",\n end: \"bottom\",\n extent: \"height\",\n });\n this.borderBoxHeight = dim.borderBoxExtent;\n this.marginTop = dim.marginStart;\n this.marginBottom = dim.marginEnd;\n }\n\n /**\n * Calculate page dimensions as specified in CSS Paged Media\n * (http://dev.w3.org/csswg/css-page/#page-model) Page border box extent and\n * margins. Since the containing block can be resized in the over-constrained\n * case, the sum of these values is not necessarily same to the original page\n * dimension specified in the page at-rules.\n */\n private resolvePageBoxDimensions(names: {\n start: string;\n end: string;\n extent: string;\n }): {\n borderBoxExtent: Exprs.Val;\n marginStart: Exprs.Val;\n marginEnd: Exprs.Val;\n } {\n const style = this.style;\n const pageSize = this.pageBox.pageSize;\n const scope = this.pageBox.scope;\n const startSide = names.start;\n const endSide = names.end;\n const extentName = names.extent;\n const pageExtent = pageSize[extentName].toExpr(scope, null);\n let extent = PageMaster.toExprAuto(scope, style[extentName], pageExtent);\n let marginStart = PageMaster.toExprAuto(\n scope,\n style[`margin-${startSide}`],\n pageExtent,\n );\n let marginEnd = PageMaster.toExprAuto(\n scope,\n style[`margin-${endSide}`],\n pageExtent,\n );\n const paddingStart = PageMaster.toExprZero(\n scope,\n style[`padding-${startSide}`],\n pageExtent,\n );\n const paddingEnd = PageMaster.toExprZero(\n scope,\n style[`padding-${endSide}`],\n pageExtent,\n );\n const borderStartWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${startSide}-width`],\n style[`border-${startSide}-style`],\n pageExtent,\n );\n const borderEndWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${endSide}-width`],\n style[`border-${endSide}-style`],\n pageExtent,\n );\n let remains = Exprs.sub(\n scope,\n pageExtent,\n Exprs.add(\n scope,\n Exprs.add(scope, borderStartWidth, paddingStart),\n Exprs.add(scope, borderEndWidth, paddingEnd),\n ),\n );\n\n // The dimensions are calculated as for a non-replaced block element in\n // normal flow (http://www.w3.org/TR/CSS21/visudet.html#blockwidth)\n if (!extent) {\n if (!marginStart) {\n marginStart = scope.zero;\n }\n if (!marginEnd) {\n marginEnd = scope.zero;\n }\n extent = Exprs.sub(\n scope,\n remains,\n Exprs.add(scope, marginStart, marginEnd),\n );\n } else {\n remains = Exprs.sub(scope, remains, extent);\n if (!marginStart && !marginEnd) {\n marginStart = Exprs.mul(scope, remains, new Exprs.Const(scope, 0.5));\n marginEnd = marginStart;\n } else if (marginStart) {\n marginEnd = Exprs.sub(scope, remains, marginStart);\n } else {\n marginStart = Exprs.sub(scope, remains, marginEnd);\n }\n }\n\n // TODO over-constrained case\n // \"if the values are over-constrained, instead of ignoring any margins, the\n // containing block is resized to coincide with the margin edges of the page\n // box.\" (CSS Paged Media http://dev.w3.org/csswg/css-page/#page-model)\n style[startSide] = new Css.Expr(marginStart);\n style[endSide] = new Css.Expr(marginEnd);\n style[`margin-${startSide}`] = Css.numericZero;\n style[`margin-${endSide}`] = Css.numericZero;\n style[`padding-${startSide}`] = new Css.Expr(paddingStart);\n style[`padding-${endSide}`] = new Css.Expr(paddingEnd);\n style[`border-${startSide}-width`] = new Css.Expr(borderStartWidth);\n style[`border-${endSide}-width`] = new Css.Expr(borderEndWidth);\n style[extentName] = new Css.Expr(extent);\n style[`max-${extentName}`] = new Css.Expr(extent);\n return {\n borderBoxExtent: Exprs.sub(\n scope,\n pageExtent,\n Exprs.add(scope, marginStart, marginEnd),\n ),\n marginStart,\n marginEnd,\n };\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n page.pageAreaElement = container.element as HTMLElement;\n\n // Set page area size for vw/vh unit calculation\n context.pageAreaWidth = parseFloat(page.pageAreaElement.style.width);\n context.pageAreaHeight = parseFloat(page.pageAreaElement.style.height);\n }\n}\n\nexport class PageMarginBoxPartitionInstance extends PageMaster.PartitionInstance<\n PageMarginBoxPartition\n> {\n boxInfo: PageMarginBoxInformation;\n suppressEmptyBoxGeneration: boolean = true;\n\n constructor(\n parentInstance: PageMaster.PageBoxInstance,\n pageMarginBoxPartition: PageMarginBoxPartition,\n ) {\n super(parentInstance, pageMarginBoxPartition);\n const name = pageMarginBoxPartition.marginBoxName;\n this.boxInfo = pageMarginBoxes[name];\n const pageRuleMasterInstance = parentInstance as PageRuleMasterInstance;\n pageRuleMasterInstance.pageMarginBoxInstances[name] = this;\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n this.applyVerticalAlign(context, container.element);\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n }\n\n private applyVerticalAlign(context: Exprs.Context, element: Element) {\n Base.setCSSProperty(element, \"display\", \"flex\");\n const verticalAlign: Css.Val = this.getProp(context, \"vertical-align\");\n let flexAlign: string | null = null;\n if (verticalAlign === Css.getName(\"middle\")) {\n flexAlign = \"center\";\n } else if (verticalAlign === Css.getName(\"top\")) {\n flexAlign = \"flex-start\";\n } else if (verticalAlign === Css.getName(\"bottom\")) {\n flexAlign = \"flex-end\";\n }\n if (flexAlign) {\n Base.setCSSProperty(\n element,\n \"flex-flow\",\n this.vertical ? \"row\" : \"column\",\n );\n Base.setCSSProperty(element, \"justify-content\", flexAlign);\n }\n }\n\n /**\n * Calculate page-margin boxes positions along the variable dimension of the\n * page. For CENTER and END margin boxes, the position is calculated only if\n * the dimension (width or height) is non-auto, so that it can be resolved at\n * this point. If the dimension is auto, the calculation is deffered.\n */\n private positionAlongVariableDimension(\n names: { start: string; end: string; extent: string },\n dim: PageAreaDimension | null,\n ): void {\n const style = this.style;\n const scope = this.pageBox.scope;\n const startSide = names.start;\n const endSide = names.end;\n const extentName = names.extent;\n const isHorizontal = startSide === \"left\";\n const availableExtent = isHorizontal\n ? dim.borderBoxWidth\n : dim.borderBoxHeight;\n const extent = PageMaster.toExprAuto(\n scope,\n style[extentName],\n availableExtent,\n );\n const startOffset = isHorizontal ? dim.marginLeft : dim.marginTop;\n if (\n this.boxInfo.positionAlongVariableDimension ===\n MarginBoxPositionAlongVariableDimension.START\n ) {\n style[startSide] = new Css.Expr(startOffset);\n } else if (extent) {\n const marginStart = PageMaster.toExprZero(\n scope,\n style[`margin-${startSide}`],\n availableExtent,\n );\n const marginEnd = PageMaster.toExprZero(\n scope,\n style[`margin-${endSide}`],\n availableExtent,\n );\n const paddingStart = PageMaster.toExprZero(\n scope,\n style[`padding-${startSide}`],\n availableExtent,\n );\n const paddingEnd = PageMaster.toExprZero(\n scope,\n style[`padding-${endSide}`],\n availableExtent,\n );\n const borderStartWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${startSide}-width`],\n style[`border-${startSide}-style`],\n availableExtent,\n );\n const borderEndWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${endSide}-width`],\n style[`border-${endSide}-style`],\n availableExtent,\n );\n const outerExtent = Exprs.add(\n scope,\n extent,\n Exprs.add(\n scope,\n Exprs.add(scope, paddingStart, paddingEnd),\n Exprs.add(\n scope,\n Exprs.add(scope, borderStartWidth, borderEndWidth),\n Exprs.add(scope, marginStart, marginEnd),\n ),\n ),\n );\n switch (this.boxInfo.positionAlongVariableDimension) {\n case MarginBoxPositionAlongVariableDimension.CENTER:\n style[startSide] = new Css.Expr(\n Exprs.add(\n scope,\n startOffset,\n Exprs.div(\n scope,\n Exprs.sub(scope, availableExtent, outerExtent),\n new Exprs.Const(scope, 2),\n ),\n ),\n );\n break;\n case MarginBoxPositionAlongVariableDimension.END:\n style[startSide] = new Css.Expr(\n Exprs.sub(\n scope,\n Exprs.add(scope, startOffset, availableExtent),\n outerExtent,\n ),\n );\n break;\n }\n }\n }\n\n /**\n * Calculate page-margin boxes positions along the fixed dimension of the\n * page.\n */\n private positionAndSizeAlongFixedDimension(\n names: { inside: string; outside: string; extent: string },\n dim: PageAreaDimension | null,\n ): void {\n const style = this.style;\n const scope = this.pageBox.scope;\n const insideName = names.inside;\n const outsideName = names.outside;\n const extentName = names.extent;\n const pageMargin =\n dim[\n `margin${outsideName.charAt(0).toUpperCase()}${outsideName.substring(\n 1,\n )}`\n ];\n const marginInside = PageMaster.toExprZeroAuto(\n scope,\n style[`margin-${insideName}`],\n pageMargin,\n );\n const marginOutside = PageMaster.toExprZeroAuto(\n scope,\n style[`margin-${outsideName}`],\n pageMargin,\n );\n const paddingInside = PageMaster.toExprZero(\n scope,\n style[`padding-${insideName}`],\n pageMargin,\n );\n const paddingOutside = PageMaster.toExprZero(\n scope,\n style[`padding-${outsideName}`],\n pageMargin,\n );\n const borderInsideWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${insideName}-width`],\n style[`border-${insideName}-style`],\n pageMargin,\n );\n const borderOutsideWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${outsideName}-width`],\n style[`border-${outsideName}-style`],\n pageMargin,\n );\n const extent = PageMaster.toExprAuto(scope, style[extentName], pageMargin);\n let result: {\n extent: Exprs.Result;\n marginInside: Exprs.Result;\n marginOutside: Exprs.Result;\n } = null;\n\n function getComputedValues(\n context: Exprs.Context,\n ): {\n extent: Exprs.Result | null;\n marginInside: Exprs.Result | null;\n marginOutside: Exprs.Result | null;\n } {\n if (result) {\n return result;\n }\n result = {\n extent: extent ? extent.evaluate(context) : null,\n marginInside: marginInside ? marginInside.evaluate(context) : null,\n marginOutside: marginOutside ? marginOutside.evaluate(context) : null,\n };\n const pageMarginValue = pageMargin.evaluate(context);\n let borderAndPadding = 0;\n [\n borderInsideWidth,\n paddingInside,\n paddingOutside,\n borderOutsideWidth,\n ].forEach((x) => {\n if (x) {\n borderAndPadding += x.evaluate(context) as number;\n }\n });\n if (result.marginInside === null || result.marginOutside === null) {\n const total =\n borderAndPadding +\n (result.extent as number) +\n (result.marginInside as number) +\n (result.marginOutside as number);\n if (total > pageMarginValue) {\n if (result.marginInside === null) {\n result.marginInside = 0;\n }\n if (result.marginOutside === null) {\n result.marginOutside = 0;\n }\n }\n }\n if (\n result.extent !== null &&\n result.marginInside !== null &&\n result.marginOutside !== null\n ) {\n // over-constrained\n result.marginOutside = null;\n }\n if (\n result.extent === null &&\n result.marginInside !== null &&\n result.marginOutside !== null\n ) {\n result.extent =\n pageMarginValue -\n borderAndPadding -\n (result.marginInside as number) -\n (result.marginOutside as number);\n } else if (\n result.extent !== null &&\n (result.marginInside as number) === null &&\n (result.marginOutside as number) !== null\n ) {\n result.marginInside =\n pageMarginValue -\n borderAndPadding -\n (result.extent as number) -\n (result.marginOutside as number);\n } else if (\n result.extent !== null &&\n result.marginInside !== null &&\n result.marginOutside === null\n ) {\n result.marginOutside =\n pageMarginValue -\n borderAndPadding -\n (result.extent as number) -\n (result.marginInside as number);\n } else if (result.extent === null) {\n result.marginInside = result.marginOutside = 0;\n result.extent = pageMarginValue - borderAndPadding;\n } else {\n result.marginInside = result.marginOutside =\n (pageMarginValue - borderAndPadding - (result.extent as number)) / 2;\n }\n return result;\n }\n style[extentName] = new Css.Expr(\n new Exprs.Native(\n scope,\n function() {\n const value = getComputedValues(this).extent;\n return value === null ? 0 : value;\n },\n extentName,\n ),\n );\n style[`margin-${insideName}`] = new Css.Expr(\n new Exprs.Native(\n scope,\n function() {\n const value = getComputedValues(this).marginInside;\n return value === null ? 0 : value;\n },\n `margin-${insideName}`,\n ),\n );\n style[`margin-${outsideName}`] = new Css.Expr(\n new Exprs.Native(\n scope,\n function() {\n const value = getComputedValues(this).marginOutside;\n return value === null ? 0 : value;\n },\n `margin-${outsideName}`,\n ),\n );\n if (insideName === \"left\") {\n style[\"left\"] = new Css.Expr(\n Exprs.add(scope, dim.marginLeft, dim.borderBoxWidth),\n );\n } else if (insideName === \"top\") {\n style[\"top\"] = new Css.Expr(\n Exprs.add(scope, dim.marginTop, dim.borderBoxHeight),\n );\n }\n }\n\n /**\n * @override\n */\n initHorizontal(): void {\n const pageRuleMasterInstance = this\n .parentInstance as PageRuleMasterInstance;\n const dim = pageRuleMasterInstance.pageAreaDimension;\n if (this.boxInfo.isInLeftColumn) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"right\", outside: \"left\", extent: \"width\" },\n dim,\n );\n } else if (this.boxInfo.isInRightColumn) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"left\", outside: \"right\", extent: \"width\" },\n dim,\n );\n } else {\n this.positionAlongVariableDimension(\n { start: \"left\", end: \"right\", extent: \"width\" },\n dim,\n );\n }\n }\n\n /**\n * @override\n */\n initVertical(): void {\n const pageRuleMasterInstance = this\n .parentInstance as PageRuleMasterInstance;\n const dim = pageRuleMasterInstance.pageAreaDimension;\n if (this.boxInfo.isInTopRow) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"bottom\", outside: \"top\", extent: \"height\" },\n dim,\n );\n } else if (this.boxInfo.isInBottomRow) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"top\", outside: \"bottom\", extent: \"height\" },\n dim,\n );\n } else {\n this.positionAlongVariableDimension(\n { start: \"top\", end: \"bottom\", extent: \"height\" },\n dim,\n );\n }\n }\n\n /**\n * @override\n */\n finishContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n column: Vtree.Container,\n columnCount: number,\n clientLayout: Vtree.ClientLayout,\n docFaces: Font.DocumentFaces,\n ): void {\n super.finishContainer(\n context,\n container,\n page,\n column,\n columnCount,\n clientLayout,\n docFaces,\n );\n\n // finishContainer is called only when the margin box is generated.\n // In this case, store the generated container for the margin box in the\n // page object. (except when it is a corner margin box, because size of a\n // corner margin box does not need to be adjusted after the layout)\n const marginBoxes = page.marginBoxes;\n const name = (this.pageBox as any).marginBoxName;\n const boxInfo = this.boxInfo;\n if (!boxInfo.isInLeftColumn && !boxInfo.isInRightColumn) {\n if (boxInfo.isInTopRow) {\n marginBoxes.top[name] = container;\n } else if (boxInfo.isInBottomRow) {\n marginBoxes.bottom[name] = container;\n }\n } else if (!boxInfo.isInTopRow && !boxInfo.isInBottomRow) {\n if (boxInfo.isInLeftColumn) {\n marginBoxes.left[name] = container;\n } else if (boxInfo.isInRightColumn) {\n marginBoxes.right[name] = container;\n }\n }\n }\n}\n\n/**\n * Dynamically generate and manage page masters corresponding to page at-rules.\n */\nexport class PageManager {\n private pageMasterCache: any = {} as {\n [key: string]: PageMaster.PageMasterInstance;\n };\n\n constructor(\n private readonly cascadeInstance: CssCascade.CascadeInstance,\n private readonly pageScope: Exprs.LexicalScope,\n private readonly rootPageBoxInstance: PageMaster.RootPageBoxInstance,\n private readonly context: Exprs.Context,\n private readonly docElementStyle: CssCascade.ElementStyle,\n ) {\n this.definePageProgression();\n }\n\n /**\n * Determine the page progression and define left/right/recto/verso pages.\n */\n private definePageProgression() {\n // TODO If a page break is forced before the root element, recto/verso pages\n // are no longer odd/even pages. left/right are reversed too.\n const scope = this.pageScope;\n const pageNumber = new Exprs.Named(scope, \"page-number\");\n const isEvenPage = new Exprs.Eq(\n scope,\n new Exprs.Modulo(scope, pageNumber, new Exprs.Const(scope, 2)),\n scope.zero,\n );\n scope.defineName(\"recto-page\", new Exprs.Not(scope, isEvenPage));\n scope.defineName(\"verso-page\", isEvenPage);\n const styleInstance: any /* Ops.StyleInstance */ = this.context;\n const pageProgression =\n styleInstance.pageProgression ||\n resolvePageProgression(this.docElementStyle);\n if (pageProgression === Constants.PageProgression.LTR) {\n scope.defineName(\"left-page\", isEvenPage);\n scope.defineName(\"right-page\", new Exprs.Not(scope, isEvenPage));\n } else {\n scope.defineName(\"left-page\", new Exprs.Not(scope, isEvenPage));\n scope.defineName(\"right-page\", isEvenPage);\n }\n }\n\n /**\n * Get cascaded page style specified in page context for the current page.\n */\n getCascadedPageStyle(): CssCascade.ElementStyle {\n const style = {} as CssCascade.ElementStyle;\n this.cascadeInstance.pushRule([], \"\", style);\n this.cascadeInstance.popRule();\n return style;\n }\n\n /**\n * Return a PageMasterInstance with page rules applied. Return a cached\n * instance if there already exists one with the same styles.\n * @param pageMasterInstance The original page master instance.\n * @param cascadedPageStyle Cascaded page style specified in page context.\n */\n getPageRulePageMaster(\n pageMasterInstance: PageMaster.PageMasterInstance,\n cascadedPageStyle: CssCascade.ElementStyle,\n ): PageMaster.PageMasterInstance {\n const pageMaster = pageMasterInstance.pageBox as PageMaster.PageMaster;\n\n // If no properies are specified in @page rules, use the original page\n // master.\n if (Object.keys(cascadedPageStyle).length === 0) {\n pageMaster.resetScope();\n return pageMasterInstance;\n }\n const key = this.makeCacheKey(cascadedPageStyle, pageMaster);\n let applied = this.pageMasterCache[key];\n if (!applied) {\n if (pageMaster.pseudoName === PageMaster.userAgentPageMasterPseudo) {\n // If the passed page master is a UA page master,\n // ignore it and generate a new page master from @page rules.\n applied = this.generatePageRuleMaster(cascadedPageStyle);\n } else {\n // Otherwise cascade some properties from @page rules to the page\n // master.\n applied = this.generateCascadedPageMaster(\n cascadedPageStyle,\n pageMaster,\n );\n }\n this.pageMasterCache[key] = applied;\n }\n applied.pageBox.resetScope();\n return applied;\n }\n\n /**\n * Generate a cache key from the specified styles and the original page master\n * key.\n */\n private makeCacheKey(\n style: CssCascade.ElementStyle,\n pageMaster: PageMaster.PageMaster,\n ): string {\n const propsStr = this.makeCascadeValueObjectKey(style);\n return `${pageMaster.key}^${propsStr}`;\n }\n\n private makeCascadeValueObjectKey(object: CssCascade.ElementStyle): string {\n const props = [] as string[];\n for (const prop in object) {\n if (Object.prototype.hasOwnProperty.call(object, prop)) {\n const val = object[prop];\n let str: string;\n if (val instanceof CssCascade.CascadeValue) {\n str = `${val.value}`;\n } else {\n str = this.makeCascadeValueObjectKey(val);\n }\n props.push(prop + str + (val.priority || \"\"));\n }\n }\n return props.sort().join(\"^\");\n }\n\n private generatePageRuleMaster(\n style: CssCascade.ElementStyle,\n ): PageRuleMasterInstance {\n const pageMaster = new PageRuleMaster(\n this.pageScope,\n this.rootPageBoxInstance.pageBox as PageMaster.RootPageBox,\n style,\n );\n const pageMasterInstance = pageMaster.createInstance(\n this.rootPageBoxInstance,\n );\n\n // Do the same initialization as in Ops.StyleInstance.prototype.init\n pageMasterInstance.applyCascadeAndInit(\n this.cascadeInstance,\n this.docElementStyle,\n );\n pageMasterInstance.resolveAutoSizing(this.context);\n return pageMasterInstance;\n }\n\n /**\n * Cascade some properties from `@page` rules to a page master.\n * For now, only 'width' and 'height' resolved from 'size' value are cascaded.\n * @param style Cascaded style in the page context\n * @param pageMaster The original page master\n */\n private generateCascadedPageMaster(\n style: CssCascade.ElementStyle,\n pageMaster: PageMaster.PageMaster,\n ): PageMaster.PageMasterInstance {\n const newPageMaster = pageMaster.clone({\n pseudoName: pageRuleMasterPseudoName,\n });\n const pageMasterStyle = newPageMaster.specified;\n const size = style[\"size\"];\n if (size) {\n const pageSize = resolvePageSizeAndBleed(style as any);\n const priority = size.priority;\n pageMasterStyle[\"width\"] = CssCascade.cascadeValues(\n this.context,\n pageMasterStyle[\"width\"],\n new CssCascade.CascadeValue(pageSize.width, priority),\n );\n pageMasterStyle[\"height\"] = CssCascade.cascadeValues(\n this.context,\n pageMasterStyle[\"height\"],\n new CssCascade.CascadeValue(pageSize.height, priority),\n );\n }\n\n // Transfer counter properties to the page style so that these specified in\n // the page master are also effective. Note that these values (if specified)\n // always override values in page contexts.\n [\"counter-reset\", \"counter-increment\"].forEach((name) => {\n if (pageMasterStyle[name]) {\n style[name] = pageMasterStyle[name];\n }\n });\n const pageMasterInstance = newPageMaster.createInstance(\n this.rootPageBoxInstance,\n ) as PageMaster.PageMasterInstance;\n\n // Do the same initialization as in Ops.StyleInstance.prototype.init\n pageMasterInstance.applyCascadeAndInit(\n this.cascadeInstance,\n this.docElementStyle,\n );\n pageMasterInstance.resolveAutoSizing(this.context);\n return pageMasterInstance;\n }\n}\n\nexport class CheckPageTypeAction extends CssCascade.ChainedAction {\n constructor(public readonly pageType: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n if (cascadeInstance.currentPageType === this.pageType) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 3;\n }\n\n /**\n * @override\n */\n makePrimary(cascade: CssCascade.Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.pagetypes, this.pageType, this.chained);\n }\n return true;\n }\n}\n\nexport class IsFirstPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const pageNumber = new Exprs.Named(this.scope, \"page-number\");\n if (pageNumber.evaluate(cascadeInstance.context) === 1) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 2;\n }\n}\n\nexport class IsLeftPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const leftPage = new Exprs.Named(this.scope, \"left-page\");\n if (leftPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class IsRightPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const rightPage = new Exprs.Named(this.scope, \"right-page\");\n if (rightPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class IsRectoPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const rectoPage = new Exprs.Named(this.scope, \"recto-page\");\n if (rectoPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class IsVersoPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const versoPage = new Exprs.Named(this.scope, \"verso-page\");\n if (versoPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\n/**\n * Action applying an at-page rule\n */\nexport class ApplyPageRuleAction extends CssCascade.ApplyRuleAction {\n constructor(style: CssCascade.ElementStyle, specificity: number) {\n super(style, specificity, null, null, null);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n mergeInPageRule(\n cascadeInstance.context,\n cascadeInstance.currentStyle,\n this.style,\n this.specificity,\n cascadeInstance,\n );\n }\n}\n\n/**\n * Merge page styles, including styles specified on page-margin boxes,\n * considering specificity. Intended to be used in place of\n * CssCascade.mergeIn, which is for element styles.\n */\nexport function mergeInPageRule(\n context: Exprs.Context,\n target: CssCascade.ElementStyle,\n style: CssCascade.ElementStyle,\n specificity: number,\n cascadeInstance: CssCascade.CascadeInstance,\n): void {\n CssCascade.mergeIn(context, target, style, specificity, null, null, null);\n const marginBoxes = style[marginBoxesKey];\n if (marginBoxes) {\n const targetMap = CssCascade.getMutableStyleMap(target, marginBoxesKey);\n for (const boxName in marginBoxes) {\n if (marginBoxes.hasOwnProperty(boxName)) {\n let targetBox = targetMap[boxName];\n if (!targetBox) {\n targetBox = {} as CssCascade.ElementStyle;\n targetMap[boxName] = targetBox;\n }\n CssCascade.mergeIn(\n context,\n targetBox,\n marginBoxes[boxName],\n specificity,\n null,\n null,\n null,\n );\n }\n }\n }\n}\n\n/**\n * ParserHandler for `@page` rules. It handles properties specified with page\n * contexts. It also does basic cascading (which can be done without information\n * other than the page rules themselves) and stores the result in `pageProps`\n * object as a map from page selectors to sets of properties. This result is\n * later used for adding `@page` rules to the real DOM, which are then used by\n * the PDF renderer (Chromium) to determine page sizes.\n */\nexport class PageParserHandler extends CssCascade.CascadeParserHandler\n implements CssValidator.PropertyReceiver {\n private currentPageSelectors: {\n selectors: string[] | null;\n specificity: number;\n }[] = [];\n private currentNamedPageSelector: string = \"\";\n private currentPseudoPageClassSelectors: string[] = [];\n\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n parent: CssCascade.CascadeParserHandler,\n validatorSet: CssValidator.ValidatorSet,\n private readonly pageProps: { [key: string]: CssCascade.ElementStyle },\n ) {\n super(scope, owner, null, parent, null, validatorSet, false);\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n this.startSelectorRule();\n }\n\n /**\n * @override\n */\n tagSelector(ns: string | null, name: string | null): void {\n Asserts.assert(name);\n this.currentNamedPageSelector = name;\n if (name) {\n this.chain.push(new CheckPageTypeAction(name));\n this.specificity += 65536;\n }\n }\n\n /**\n * @override\n */\n pseudoclassSelector(name: string, params: (number | string)[]): void {\n if (params) {\n this.reportAndSkip(\n `E_INVALID_PAGE_SELECTOR :${name}(${params.join(\"\")})`,\n );\n }\n this.currentPseudoPageClassSelectors.push(`:${name}`);\n switch (name.toLowerCase()) {\n case \"first\":\n this.chain.push(new IsFirstPageAction(this.scope));\n this.specificity += 256;\n break;\n case \"left\":\n this.chain.push(new IsLeftPageAction(this.scope));\n this.specificity += 1;\n break;\n case \"right\":\n this.chain.push(new IsRightPageAction(this.scope));\n this.specificity += 1;\n break;\n case \"recto\":\n this.chain.push(new IsRectoPageAction(this.scope));\n this.specificity += 1;\n break;\n case \"verso\":\n this.chain.push(new IsVersoPageAction(this.scope));\n this.specificity += 1;\n break;\n default:\n this.reportAndSkip(`E_INVALID_PAGE_SELECTOR :${name}`);\n break;\n }\n }\n\n /**\n * Save currently processed selector and reset variables.\n */\n private finishSelector() {\n let selectors: string[];\n if (\n !this.currentNamedPageSelector &&\n !this.currentPseudoPageClassSelectors.length\n ) {\n selectors = null;\n } else {\n selectors = [this.currentNamedPageSelector].concat(\n this.currentPseudoPageClassSelectors.sort(),\n );\n }\n this.currentPageSelectors.push({\n selectors,\n specificity: this.specificity,\n });\n this.currentNamedPageSelector = \"\";\n this.currentPseudoPageClassSelectors = [];\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.finishSelector();\n super.nextSelector();\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.finishSelector();\n super.startRuleBody();\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n // we limit 'bleed' and 'marks' to be effective only when specified without\n // page selectors\n if (\n (name === \"bleed\" || name === \"marks\") &&\n !this.currentPageSelectors.some((s) => s.selectors === null)\n ) {\n return;\n }\n super.simpleProperty(name, value, important);\n const cascVal = CssCascade.getProp(this.elementStyle, name);\n const pageProps = this.pageProps;\n if (name === \"bleed\" || name === \"marks\") {\n if (!pageProps[\"\"]) {\n pageProps[\"\"] = {} as CssCascade.ElementStyle;\n }\n\n // we can simply overwrite without considering specificity\n // since 'bleed' and 'marks' always come from a page rule without page\n // selectors.\n Object.keys(pageProps).forEach((selector) => {\n CssCascade.setProp(pageProps[selector], name, cascVal);\n });\n } else if (name === \"size\") {\n const noPageSelectorProps = pageProps[\"\"];\n this.currentPageSelectors.forEach((s) => {\n // update specificity to reflect the specificity of the selector\n let result = new CssCascade.CascadeValue(\n cascVal.value,\n cascVal.priority + s.specificity,\n );\n const selector = s.selectors ? s.selectors.join(\"\") : \"\";\n let props = pageProps[selector];\n if (!props) {\n // since no properties for this selector have been stored before,\n // we can simply set the 'size', 'bleed' and 'marks' properties.\n props = pageProps[selector] = {} as CssCascade.ElementStyle;\n CssCascade.setProp(props, name, result);\n if (noPageSelectorProps) {\n [\"bleed\", \"marks\"].forEach((n) => {\n if (noPageSelectorProps[n]) {\n CssCascade.setProp(props, n, noPageSelectorProps[n]);\n }\n }, this);\n }\n } else {\n // consider specificity when setting 'size' property.\n // we don't have to set 'bleed' and 'marks' since they should have\n // been already updated.\n const prevCascVal = CssCascade.getProp(props, name);\n result = prevCascVal\n ? CssCascade.cascadeValues(null, result, prevCascVal)\n : result;\n CssCascade.setProp(props, name, result);\n }\n });\n }\n }\n\n /**\n * @override\n */\n insertNonPrimary(action: CssCascade.CascadeAction): void {\n // We represent page rules without selectors by *, though it is illegal in\n // CSS\n this.cascade.insertInTable(this.cascade.pagetypes, \"*\", action);\n }\n\n /**\n * @override\n */\n makeApplyRuleAction(specificity: number): CssCascade.ApplyRuleAction {\n return new ApplyPageRuleAction(this.elementStyle, specificity);\n }\n\n /**\n * @override\n */\n startPageMarginBoxRule(name: string): void {\n const marginBoxMap = CssCascade.getMutableStyleMap(\n this.elementStyle,\n marginBoxesKey,\n );\n let boxStyle = marginBoxMap[name];\n if (!boxStyle) {\n boxStyle = {} as CssCascade.ElementStyle;\n marginBoxMap[name] = boxStyle;\n }\n const handler = new PageMarginBoxParserHandler(\n this.scope,\n this.owner,\n this.validatorSet,\n boxStyle,\n );\n this.owner.pushHandler(handler);\n }\n}\n\n/**\n * Parser handler for a page-margin box rule.\n */\nexport class PageMarginBoxParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly validatorSet: CssValidator.ValidatorSet,\n public readonly boxStyle: CssCascade.ElementStyle,\n ) {\n super(scope, owner, false);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY_VALUE ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n const specificity = important\n ? this.getImportantSpecificity()\n : this.getBaseSpecificity();\n const cascval = new CssCascade.CascadeValue(value, specificity);\n CssCascade.setProp(this.boxStyle, name, cascval);\n }\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Urls - URL Utilities\n */\n\n/**\n * transform all urls in attributeValue using documentURLTransformer.\n *\n * @returns transformed attributeValue\n */\n\nexport const transformURIs = (\n attributeValue,\n baseUrl,\n documentURLTransformer,\n) =>\n attributeValue\n .replace(\n /[uU][rR][lL]\\(\\s*\"((\\\\([^0-9a-fA-F]+|[0-9a-fA-F]+\\s*)|[^\"\\r\\n])+)\"/gm,\n (match, m1) =>\n `url(\"${documentURLTransformer.transformURL(m1, baseUrl)}\"`,\n )\n .replace(\n /[uU][rR][lL]\\(\\s*'((\\\\([^0-9a-fA-F]+|[0-9a-fA-F]+\\s*)|[^'\\r\\n])+)'/gm,\n (match, m1) =>\n `url('${documentURLTransformer.transformURL(m1, baseUrl)}'`,\n )\n .replace(\n /[uU][rR][lL]\\(\\s*((\\\\([^0-9a-fA-F]+|[0-9a-fA-F]+\\s*)|[^\"'\\r\\n\\)\\s])+)/gm,\n (match, m1) => `url(${documentURLTransformer.transformURL(m1, baseUrl)}`,\n );\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Vgen - View tree generator.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssStyler from \"./css-styler\";\nimport * as Diff from \"./diff\";\nimport * as Display from \"./display\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Matchers from \"./matchers\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Plugin from \"./plugin\";\nimport * as PseudoElement from \"./pseudo-element\";\nimport * as RepetitiveElement from \"./repetitive-element\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport * as Urls from \"./urls\";\nimport * as Vtree from \"./vtree\";\nimport * as Layout from \"./layout\";\nimport { XmlDoc } from \"./types\";\n\nconst namespacePrefixMap = {};\n\nexport const frontEdgeBlackListHor: { [key: string]: string } = {\n \"text-indent\": \"0px\",\n \"margin-top\": \"0px\",\n \"padding-top\": \"0px\",\n \"border-top-width\": \"0px\",\n \"border-top-style\": \"none\",\n \"border-top-color\": \"transparent\",\n \"border-top-left-radius\": \"0px\",\n \"border-top-right-radius\": \"0px\",\n};\n\nexport const frontEdgeBlackListVert: { [key: string]: string } = {\n \"text-indent\": \"0px\",\n \"margin-right\": \"0px\",\n \"padding-right\": \"0px\",\n \"border-right-width\": \"0px\",\n \"border-right-style\": \"none\",\n \"border-right-color\": \"transparent\",\n \"border-top-right-radius\": \"0px\",\n \"border-bottom-right-radius\": \"0px\",\n};\n\nexport const frontEdgeUnforcedBreakBlackListHor: { [key: string]: string } = {\n \"margin-top\": \"0px\",\n};\n\nexport const frontEdgeUnforcedBreakBlackListVert: { [key: string]: string } = {\n \"margin-right\": \"0px\",\n};\n\nexport type CustomRenderer = (\n p1: Element,\n p2: Element,\n p3: { [key: string]: Css.Val },\n) => Task.Result<Element>;\n\nexport interface CustomRendererFactory {\n makeCustomRenderer(xmldoc: XmlDoc.XMLDocHolder): CustomRenderer;\n}\n\n/**\n * Creates an epubReadingSystem object in the iframe.contentWindow.navigator\n * when load event fires.\n */\nexport function initIFrame(iframe: HTMLIFrameElement): void {\n iframe.addEventListener(\n \"load\",\n () => {\n iframe.contentWindow.navigator[\"epubReadingSystem\"] = {\n name: \"adapt\",\n version: \"0.1\",\n layoutStyle: \"paginated\",\n hasFeature: function(name, version) {\n switch (name) {\n case \"mouse-events\":\n return true;\n }\n return false;\n },\n };\n },\n false,\n );\n}\n\nexport interface StylerProducer {\n getStylerForDoc(xmldoc: XmlDoc.XMLDocHolder): CssStyler.AbstractStyler;\n}\n\nexport class ViewFactory extends Base.SimpleEventTarget\n implements Vtree.LayoutContext {\n private static SVG_URL_ATTRIBUTES: string[] = [\n \"color-profile\",\n \"clip-path\",\n \"cursor\",\n \"filter\",\n \"marker\",\n \"marker-start\",\n \"marker-end\",\n \"marker-mid\",\n \"fill\",\n \"stroke\",\n \"mask\",\n ];\n document: Document;\n exprContentListener: Vtree.ExprContentListener;\n\n // provided by layout\n nodeContext: Vtree.NodeContext | null = null;\n viewRoot: Element | null = null;\n isFootnote: boolean = false;\n sourceNode: Node | null = null;\n offsetInNode: number = 0;\n\n // computed\n // TODO: only set it on NodeContext\n viewNode: Node | null = null;\n\n constructor(\n public readonly flowName: string,\n public readonly context: Exprs.Context,\n public readonly viewport: Viewport,\n public readonly styler: CssStyler.Styler,\n public readonly regionIds: string[],\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n public readonly docFaces: Font.DocumentFaces,\n public readonly footnoteStyle: CssCascade.ElementStyle,\n public readonly stylerProducer: StylerProducer,\n public readonly page: Vtree.Page,\n public readonly customRenderer: CustomRenderer,\n public readonly fallbackMap: { [key: string]: string },\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n ) {\n super();\n this.document = viewport.document;\n this.exprContentListener = styler.counterListener.getExprContentListener();\n }\n\n /**\n * @override\n */\n clone(): Vtree.LayoutContext {\n return new ViewFactory(\n this.flowName,\n this.context,\n this.viewport,\n this.styler,\n this.regionIds,\n this.xmldoc,\n this.docFaces,\n this.footnoteStyle,\n this.stylerProducer,\n this.page,\n this.customRenderer,\n this.fallbackMap,\n this.documentURLTransformer,\n );\n }\n\n createPseudoelementShadow(\n element: Element,\n isRoot: boolean,\n cascStyle: CssCascade.ElementStyle,\n computedStyle: { [key: string]: Css.Val },\n styler: CssStyler.AbstractStyler,\n context: Exprs.Context,\n parentShadow: Vtree.ShadowContext,\n subShadow: Vtree.ShadowContext,\n ): Vtree.ShadowContext {\n const pseudoMap = this.getPseudoMap(\n cascStyle,\n this.regionIds,\n this.isFootnote,\n this.nodeContext,\n context,\n );\n if (!pseudoMap) {\n return subShadow;\n }\n const addedNames = [];\n const root = PseudoElement.document.createElementNS(Base.NS.SHADOW, \"root\");\n let att = root;\n for (const name of PseudoElement.pseudoNames) {\n let elem: Element;\n if (name) {\n if (!pseudoMap[name]) {\n continue;\n }\n if (name == \"footnote-marker\" && !(isRoot && this.isFootnote)) {\n continue;\n }\n if (name.match(/^first-/)) {\n const display = computedStyle[\"display\"];\n if (!display || display === Css.ident.inline) {\n continue;\n }\n }\n if (name === \"before\" || name === \"after\") {\n const content = pseudoMap[name][\"content\"];\n if (\n !content ||\n content === Css.ident.normal ||\n content === Css.ident.none\n ) {\n continue;\n }\n }\n addedNames.push(name);\n elem = PseudoElement.document.createElementNS(Base.NS.XHTML, \"span\");\n PseudoElement.setPseudoName(elem, name);\n } else {\n elem = PseudoElement.document.createElementNS(\n Base.NS.SHADOW,\n \"content\",\n );\n }\n att.appendChild(elem);\n if (name.match(/^first-/)) {\n att = elem;\n }\n }\n if (!addedNames.length) {\n return subShadow;\n }\n const shadowStyler = new PseudoElement.PseudoelementStyler(\n element,\n cascStyle,\n styler,\n context,\n this.exprContentListener,\n );\n return new Vtree.ShadowContext(\n element,\n root,\n null,\n parentShadow,\n subShadow,\n Vtree.ShadowType.ROOTLESS,\n shadowStyler,\n );\n }\n\n getPseudoMap(\n cascStyle: CssCascade.ElementStyle,\n regionIds: string[],\n isFootnote: boolean,\n nodeContext: Vtree.NodeContext,\n context: Exprs.Context,\n ) {\n const pseudoMap = CssCascade.getStyleMap(cascStyle, \"_pseudos\");\n if (!pseudoMap) {\n return null;\n }\n const computedPseudoStyleMap = {};\n for (const key in pseudoMap) {\n const computedPseudoStyle = (computedPseudoStyleMap[key] = {});\n CssCascade.mergeStyle(computedPseudoStyle, pseudoMap[key], context);\n CssCascade.mergeViewConditionalStyles(\n computedPseudoStyle,\n context,\n pseudoMap[key],\n );\n CssCascade.forEachStylesInRegion(\n pseudoMap[key],\n regionIds,\n isFootnote,\n (regionId, regionStyle) => {\n CssCascade.mergeStyle(computedPseudoStyle, regionStyle, context);\n CssCascade.forEachViewConditionalStyles(\n regionStyle,\n (viewConditionalStyles) => {\n CssCascade.mergeStyle(\n computedPseudoStyle,\n viewConditionalStyles,\n context,\n );\n },\n );\n },\n );\n }\n return computedPseudoStyleMap;\n }\n\n createRefShadow(\n href: string,\n type: Vtree.ShadowType,\n element: Element,\n parentShadow: Vtree.ShadowContext,\n subShadow: Vtree.ShadowContext,\n ): Task.Result<Vtree.ShadowContext> {\n const self = this;\n const frame: Task.Frame<Vtree.ShadowContext> = Task.newFrame(\n \"createRefShadow\",\n );\n self.xmldoc.store.load(href).then((refDocParam) => {\n const refDoc = refDocParam;\n if (refDoc) {\n const refElement = refDoc.getElement(href);\n if (refElement) {\n const refStyler = self.stylerProducer.getStylerForDoc(refDoc);\n subShadow = new Vtree.ShadowContext(\n element,\n refElement,\n refDoc,\n parentShadow,\n subShadow,\n type,\n refStyler,\n );\n }\n }\n frame.finish(subShadow);\n });\n return frame.result();\n }\n\n createShadows(\n element: Element,\n isRoot,\n cascStyle: CssCascade.ElementStyle,\n computedStyle: { [key: string]: Css.Val },\n styler: CssStyler.AbstractStyler,\n context: Exprs.Context,\n shadowContext: Vtree.ShadowContext,\n ): Task.Result<Vtree.ShadowContext> {\n const self = this;\n const frame: Task.Frame<Vtree.ShadowContext> = Task.newFrame(\n \"createShadows\",\n );\n const shadow: Vtree.ShadowContext = null;\n const templateURLVal = computedStyle[\"template\"];\n let cont: Task.Result<Vtree.ShadowContext>;\n if (templateURLVal instanceof Css.URL) {\n const url = (templateURLVal as Css.URL).url;\n cont = self.createRefShadow(\n url,\n Vtree.ShadowType.ROOTLESS,\n element,\n shadowContext,\n shadow,\n );\n } else {\n cont = Task.newResult(shadow);\n }\n cont.then((shadow) => {\n let cont1: Task.Result<Vtree.ShadowContext> = null;\n if (element.namespaceURI == Base.NS.SHADOW) {\n if (element.localName == \"include\") {\n let href = element.getAttribute(\"href\");\n let xmldoc: XmlDoc.XMLDocHolder = null;\n if (href) {\n xmldoc = shadowContext ? shadowContext.xmldoc : self.xmldoc;\n } else if (shadowContext) {\n if (shadowContext.owner.namespaceURI == Base.NS.XHTML) {\n href = shadowContext.owner.getAttribute(\"href\");\n } else {\n href = shadowContext.owner.getAttributeNS(Base.NS.XLINK, \"href\");\n }\n xmldoc = shadowContext.parentShadow\n ? shadowContext.parentShadow.xmldoc\n : self.xmldoc;\n }\n if (href) {\n href = Base.resolveURL(href, xmldoc.url);\n cont1 = self.createRefShadow(\n href,\n Vtree.ShadowType.ROOTED,\n element,\n shadowContext,\n shadow,\n );\n }\n }\n }\n if (cont1 == null) {\n cont1 = Task.newResult(shadow);\n }\n let cont2: Task.Result<Vtree.ShadowContext> = null;\n cont1.then((shadow) => {\n if (computedStyle[\"display\"] === Css.ident.table_cell) {\n const url = Base.resolveURL(\n \"user-agent.xml#table-cell\",\n Base.resourceBaseURL,\n );\n cont2 = self.createRefShadow(\n url,\n Vtree.ShadowType.ROOTLESS,\n element,\n shadowContext,\n shadow,\n );\n } else {\n cont2 = Task.newResult(shadow);\n }\n });\n cont2.then((shadow) => {\n shadow = self.createPseudoelementShadow(\n element,\n isRoot,\n cascStyle,\n computedStyle,\n styler,\n context,\n shadowContext,\n shadow,\n );\n frame.finish(shadow);\n });\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n setViewRoot(viewRoot: Element, isFootnote: boolean) {\n this.viewRoot = viewRoot;\n this.isFootnote = isFootnote;\n }\n\n /**\n * @return vertical\n */\n computeStyle(\n vertical: boolean,\n rtl: boolean,\n style: CssCascade.ElementStyle,\n computedStyle: { [key: string]: Css.Val },\n ): boolean {\n const context = this.context;\n const cascMap = CssCascade.flattenCascadedStyle(\n style,\n context,\n this.regionIds,\n this.isFootnote,\n this.nodeContext,\n );\n vertical = CssCascade.isVertical(cascMap, context, vertical);\n rtl = CssCascade.isRtl(cascMap, context, rtl);\n const self = this;\n CssCascade.convertToPhysical(\n cascMap,\n computedStyle,\n vertical,\n rtl,\n (name, cascVal) => {\n let value = cascVal.evaluate(context, name);\n if (name == \"font-family\") {\n value = self.docFaces.filterFontFamily(value);\n }\n return value;\n },\n );\n\n // Compute values of display, position and float\n const position = computedStyle[\"position\"] as Css.Ident;\n const float = computedStyle[\"float\"] as Css.Ident;\n const displayValues = Display.getComputedDislayValue(\n (computedStyle[\"display\"] as Css.Ident) || Css.ident.inline,\n position,\n float,\n this.sourceNode === this.xmldoc.root,\n );\n [\"display\", \"position\", \"float\"].forEach((name) => {\n if (displayValues[name]) {\n computedStyle[name] = displayValues[name];\n }\n });\n return vertical;\n }\n\n private inheritFromSourceParent(\n elementStyle: CssCascade.ElementStyle,\n ): { lang: string | null; elementStyle: CssCascade.ElementStyle } {\n let node = this.nodeContext.sourceNode;\n const styles = [];\n let lang: string | null = null;\n\n // TODO: this is hacky. We need to recover the path through the shadow\n // trees, but we do not have the full shadow tree structure at this point.\n // This code handles coming out of the shadow trees, but does not go back in\n // (through shadow:content element).\n let shadowContext = this.nodeContext.shadowContext;\n let steps = -1;\n while (node && node.nodeType == 1) {\n const shadowRoot = shadowContext && shadowContext.root == node;\n if (!shadowRoot || shadowContext.type == Vtree.ShadowType.ROOTLESS) {\n const styler = shadowContext\n ? (shadowContext.styler as CssStyler.AbstractStyler)\n : this.styler;\n const nodeStyle = styler.getStyle(node as Element, false);\n styles.push(nodeStyle);\n lang = lang || Base.getLangAttribute(node as Element);\n }\n if (shadowRoot) {\n node = shadowContext.owner;\n shadowContext = shadowContext.parentShadow;\n } else {\n node = node.parentNode;\n steps++;\n }\n }\n const isRoot = steps === 0;\n const fontSize = this.context.queryUnitSize(\"em\", isRoot);\n const props = {\n \"font-size\": new CssCascade.CascadeValue(\n new Css.Numeric(fontSize, \"px\"),\n 0,\n ),\n } as CssCascade.ElementStyle;\n const inheritanceVisitor = new CssCascade.InheritanceVisitor(\n props,\n this.context,\n );\n for (let i = styles.length - 1; i >= 0; --i) {\n const style = styles[i];\n const propList = [];\n for (const propName in style) {\n if (CssCascade.isInherited(propName)) {\n propList.push(propName);\n }\n }\n propList.sort(Css.processingOrderFn);\n for (const name of propList) {\n inheritanceVisitor.setPropName(name);\n const value = CssCascade.getProp(style, name);\n if (value.value !== Css.ident.inherit) {\n props[name] = value.filterValue(inheritanceVisitor);\n }\n }\n }\n for (const sname in elementStyle) {\n if (!CssCascade.isInherited(sname)) {\n props[sname] = elementStyle[sname];\n }\n }\n return { lang, elementStyle: props };\n }\n\n resolveURL(url: string): string {\n url = Base.resolveURL(url, this.xmldoc.url);\n return this.fallbackMap[url] || url;\n }\n\n inheritLangAttribute() {\n this.nodeContext.lang =\n Base.getLangAttribute(this.nodeContext.sourceNode as Element) ||\n (this.nodeContext.parent && this.nodeContext.parent.lang) ||\n this.nodeContext.lang;\n }\n\n transferPolyfilledInheritedProps(computedStyle: { [key: string]: Css.Val }) {\n const polyfilledInheritedProps = CssCascade.getPolyfilledInheritedProps().filter(\n (name) => computedStyle[name],\n );\n if (polyfilledInheritedProps.length) {\n let props = this.nodeContext.inheritedProps;\n if (this.nodeContext.parent) {\n props = this.nodeContext.inheritedProps = {};\n for (const n in this.nodeContext.parent.inheritedProps) {\n props[n] = this.nodeContext.parent.inheritedProps[n];\n }\n }\n polyfilledInheritedProps.forEach((name) => {\n const value = computedStyle[name];\n if (value) {\n if (value instanceof Css.Int) {\n props[name] = (value as Css.Int).num;\n } else if (value instanceof Css.Ident) {\n props[name] = (value as Css.Ident).name;\n } else if (value instanceof Css.Numeric) {\n const numericVal = value as Css.Numeric;\n switch (numericVal.unit) {\n case \"dpi\":\n case \"dpcm\":\n case \"dppx\":\n props[name] =\n numericVal.num * Exprs.defaultUnitSizes[numericVal.unit];\n break;\n }\n } else {\n props[name] = value;\n }\n delete computedStyle[name];\n }\n });\n }\n }\n\n resolveFormattingContext(\n nodeContext: Vtree.NodeContext,\n firstTime: boolean,\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n isRoot: boolean,\n ) {\n const hooks: Plugin.ResolveFormattingContextHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.RESOLVE_FORMATTING_CONTEXT,\n );\n for (let i = 0; i < hooks.length; i++) {\n const formattingContext = hooks[i](\n nodeContext,\n firstTime,\n display,\n position,\n float,\n isRoot,\n );\n if (formattingContext) {\n nodeContext.formattingContext = formattingContext;\n return;\n }\n }\n }\n\n /**\n * @return holding true if children should be processed\n */\n private createElementView(\n firstTime: boolean,\n atUnforcedBreak: boolean,\n ): Task.Result<boolean> {\n const self = this;\n let needToProcessChildren = true;\n const frame: Task.Frame<boolean> = Task.newFrame(\"createElementView\");\n\n // Figure out element's styles\n let element = self.sourceNode as Element;\n const styler = self.nodeContext.shadowContext\n ? (self.nodeContext.shadowContext.styler as CssStyler.AbstractStyler)\n : self.styler;\n let elementStyle = styler.getStyle(element, false);\n if (!self.nodeContext.shadowContext) {\n const offset = this.xmldoc.getElementOffset(element);\n Matchers.NthFragmentMatcher.registerFragmentIndex(\n offset,\n self.nodeContext.fragmentIndex,\n 0,\n );\n }\n const computedStyle = {};\n if (!self.nodeContext.parent) {\n const inheritedValues = self.inheritFromSourceParent(elementStyle);\n elementStyle = inheritedValues.elementStyle;\n self.nodeContext.lang = inheritedValues.lang;\n }\n const floatReference =\n elementStyle[\"float-reference\"] &&\n PageFloats.floatReferenceOf(\n elementStyle[\"float-reference\"].value.toString(),\n );\n if (\n self.nodeContext.parent &&\n floatReference &&\n PageFloats.isPageFloat(floatReference)\n ) {\n // Since a page float will be detached from a view node of its parent,\n // inherited properties need to be inherited from its source parent.\n const inheritedValues = self.inheritFromSourceParent(elementStyle);\n elementStyle = inheritedValues.elementStyle;\n self.nodeContext.lang = inheritedValues.lang;\n }\n self.nodeContext.vertical = self.computeStyle(\n self.nodeContext.vertical,\n self.nodeContext.direction === \"rtl\",\n elementStyle,\n computedStyle,\n );\n styler.processContent(element, computedStyle);\n this.transferPolyfilledInheritedProps(computedStyle);\n this.inheritLangAttribute();\n if (computedStyle[\"direction\"]) {\n self.nodeContext.direction = computedStyle[\"direction\"].toString();\n }\n\n // Sort out the properties\n const flow = computedStyle[\"flow-into\"];\n if (flow && flow.toString() != self.flowName) {\n // foreign flow, don't create a view\n frame.finish(false);\n return frame.result();\n }\n let display = computedStyle[\"display\"];\n if (display === Css.ident.none) {\n // no content\n frame.finish(false);\n return frame.result();\n }\n const isRoot = self.nodeContext.parent == null;\n self.nodeContext.flexContainer = display === Css.ident.flex;\n self\n .createShadows(\n element,\n isRoot,\n elementStyle,\n computedStyle,\n styler,\n self.context,\n self.nodeContext.shadowContext,\n )\n .then((shadowParam) => {\n self.nodeContext.nodeShadow = shadowParam;\n const position = computedStyle[\"position\"];\n let floatSide = computedStyle[\"float\"];\n let clearSide = computedStyle[\"clear\"];\n const writingMode = self.nodeContext.vertical\n ? Css.ident.vertical_rl\n : Css.ident.horizontal_tb;\n const parentWritingMode = self.nodeContext.parent\n ? self.nodeContext.parent.vertical\n ? Css.ident.vertical_rl\n : Css.ident.horizontal_tb\n : writingMode;\n const isFlowRoot = Display.isFlowRoot(element);\n self.nodeContext.establishesBFC = Display.establishesBFC(\n display,\n position,\n floatSide,\n computedStyle[\"overflow\"],\n writingMode,\n parentWritingMode,\n isFlowRoot,\n );\n self.nodeContext.containingBlockForAbsolute = Display.establishesCBForAbsolute(\n position,\n );\n if (\n self.nodeContext.isInsideBFC() &&\n floatSide !== Css.ident.footnote &&\n !(floatReference && PageFloats.isPageFloat(floatReference))\n ) {\n // When the element is already inside a block formatting context\n // (except one from the root), float and clear can be controlled by\n // the browser and we don't need to care.\n floatSide = null;\n clearSide = null;\n }\n let floating =\n floatSide === Css.ident.left ||\n floatSide === Css.ident.right ||\n floatSide === Css.ident.top ||\n floatSide === Css.ident.bottom ||\n floatSide === Css.ident.inline_start ||\n floatSide === Css.ident.inline_end ||\n floatSide === Css.ident.block_start ||\n floatSide === Css.ident.block_end ||\n floatSide === Css.ident.snap_block ||\n floatSide === Css.ident.footnote;\n if (floatSide) {\n // Don't want to set it in view DOM CSS.\n delete computedStyle[\"float\"];\n if (floatSide === Css.ident.footnote) {\n if (self.isFootnote) {\n // No footnotes inside footnotes. self is most likely the root\n // of the footnote body being rendered in footnote area. Treat\n // as block.\n floating = false;\n computedStyle[\"display\"] = Css.ident.block;\n } else {\n computedStyle[\"display\"] = Css.ident.inline;\n }\n }\n }\n if (clearSide) {\n if (clearSide === Css.ident.inherit) {\n if (self.nodeContext.parent && self.nodeContext.parent.clearSide) {\n clearSide = Css.getName(self.nodeContext.parent.clearSide);\n }\n }\n if (\n clearSide === Css.ident.left ||\n clearSide === Css.ident.right ||\n clearSide === Css.ident.top ||\n clearSide === Css.ident.bottom ||\n clearSide === Css.ident.both ||\n clearSide === Css.ident.all ||\n clearSide === Css.ident.same\n ) {\n delete computedStyle[\"clear\"];\n if (\n computedStyle[\"display\"] &&\n computedStyle[\"display\"] != Css.ident.inline\n ) {\n self.nodeContext.clearSide = clearSide.toString();\n }\n }\n }\n const listItem =\n display === Css.ident.list_item &&\n computedStyle[\"ua-list-item-count\"];\n if (\n floating ||\n (computedStyle[\"break-inside\"] &&\n computedStyle[\"break-inside\"] !== Css.ident.auto)\n ) {\n self.nodeContext.breakPenalty++;\n }\n if (\n display &&\n display !== Css.ident.inline &&\n Display.isInlineLevel(display)\n ) {\n // Don't break inside ruby, inline-block, etc.\n self.nodeContext.breakPenalty++;\n }\n self.nodeContext.inline =\n (!floating && !display) ||\n Display.isInlineLevel(display) ||\n Display.isRubyInternalDisplay(display);\n self.nodeContext.display = display ? display.toString() : \"inline\";\n self.nodeContext.floatSide = floating ? floatSide.toString() : null;\n self.nodeContext.floatReference =\n floatReference || PageFloats.FloatReference.INLINE;\n self.nodeContext.floatMinWrapBlock =\n computedStyle[\"float-min-wrap-block\"] || null;\n self.nodeContext.columnSpan = computedStyle[\"column-span\"];\n if (!self.nodeContext.inline) {\n const breakAfter = computedStyle[\"break-after\"];\n if (breakAfter) {\n self.nodeContext.breakAfter = breakAfter.toString();\n }\n const breakBefore = computedStyle[\"break-before\"];\n if (breakBefore) {\n self.nodeContext.breakBefore = breakBefore.toString();\n }\n }\n self.nodeContext.verticalAlign =\n (computedStyle[\"vertical-align\"] &&\n computedStyle[\"vertical-align\"].toString()) ||\n \"baseline\";\n self.nodeContext.captionSide =\n (computedStyle[\"caption-side\"] &&\n computedStyle[\"caption-side\"].toString()) ||\n \"top\";\n const borderCollapse = computedStyle[\"border-collapse\"];\n if (!borderCollapse || borderCollapse === Css.getName(\"separate\")) {\n const borderSpacing = computedStyle[\"border-spacing\"];\n let inlineBorderSpacing;\n let blockBorderSpacing;\n if (borderSpacing) {\n if (borderSpacing.isSpaceList()) {\n inlineBorderSpacing = borderSpacing.values[0];\n blockBorderSpacing = borderSpacing.values[1];\n } else {\n inlineBorderSpacing = blockBorderSpacing = borderSpacing;\n }\n if (inlineBorderSpacing.isNumeric()) {\n self.nodeContext.inlineBorderSpacing = Css.toNumber(\n inlineBorderSpacing,\n self.context,\n );\n }\n if (blockBorderSpacing.isNumeric()) {\n self.nodeContext.blockBorderSpacing = Css.toNumber(\n blockBorderSpacing,\n self.context,\n );\n }\n }\n }\n self.nodeContext.footnotePolicy = computedStyle[\"footnote-policy\"];\n const firstPseudo = computedStyle[\"x-first-pseudo\"];\n if (firstPseudo) {\n const outerPseudo = self.nodeContext.parent\n ? self.nodeContext.parent.firstPseudo\n : null;\n self.nodeContext.firstPseudo = new Vtree.FirstPseudo(\n outerPseudo,\n /** Css.Int */\n firstPseudo.num,\n );\n }\n if (!self.nodeContext.inline) {\n self.processAfterIfcontinues(\n element,\n elementStyle,\n styler,\n self.context,\n );\n }\n const whitespace = computedStyle[\"white-space\"];\n if (whitespace) {\n const whitespaceValue = Vtree.whitespaceFromPropertyValue(\n whitespace.toString(),\n );\n if (whitespaceValue !== null) {\n self.nodeContext.whitespace = whitespaceValue;\n }\n }\n const hyphenateCharacter = computedStyle[\"hyphenate-character\"];\n if (hyphenateCharacter && hyphenateCharacter !== Css.ident.auto) {\n self.nodeContext.hyphenateCharacter = hyphenateCharacter.str;\n }\n const wordBreak = computedStyle[\"word-break\"];\n const overflowWrap = computedStyle[\"overflow-wrap\"] || [\"word-wrap\"];\n self.nodeContext.breakWord =\n wordBreak === Css.ident.break_all ||\n overflowWrap === Css.ident.break_word;\n\n // Resolve formatting context\n self.resolveFormattingContext(\n self.nodeContext,\n firstTime,\n display,\n position,\n floatSide,\n isRoot,\n );\n if (\n self.nodeContext.parent &&\n self.nodeContext.parent.formattingContext\n ) {\n firstTime = self.nodeContext.parent.formattingContext.isFirstTime(\n self.nodeContext,\n firstTime,\n );\n }\n if (!self.nodeContext.inline) {\n self.nodeContext.repeatOnBreak = self.processRepeatOnBreak(\n computedStyle,\n );\n self.findAndProcessRepeatingElements(element, styler);\n }\n\n // Create the view element\n let custom = false;\n let inner: Element = null;\n const fetchers = [];\n let ns = element.namespaceURI;\n let tag = element.localName;\n if (ns == Base.NS.XHTML) {\n if (\n tag == \"html\" ||\n tag == \"body\" ||\n tag == \"script\" ||\n tag == \"link\" ||\n tag == \"meta\"\n ) {\n tag = \"div\";\n } else if (tag == \"vide_\") {\n tag = \"video\";\n } else if (tag == \"audi_\") {\n tag = \"audio\";\n } else if (tag == \"object\") {\n custom = !!self.customRenderer;\n }\n if (element.getAttribute(PseudoElement.PSEUDO_ATTR)) {\n if (\n elementStyle[\"content\"] &&\n elementStyle[\"content\"].value &&\n elementStyle[\"content\"].value.url\n ) {\n tag = \"img\";\n }\n }\n } else if (ns == Base.NS.epub) {\n tag = \"span\";\n ns = Base.NS.XHTML;\n } else if (ns == Base.NS.FB2) {\n ns = Base.NS.XHTML;\n if (tag == \"image\") {\n tag = \"div\";\n const imageRef = element.getAttributeNS(Base.NS.XLINK, \"href\");\n if (imageRef && imageRef.charAt(0) == \"#\") {\n const imageBinary = self.xmldoc.getElement(imageRef);\n if (imageBinary) {\n inner = self.createElement(ns, \"img\");\n const mediaType =\n imageBinary.getAttribute(\"content-type\") || \"image/jpeg\";\n const innerSrc = `data:${mediaType};base64,${imageBinary.textContent.replace(\n /[ \\t\\n\\t]/g,\n \"\",\n )}`;\n fetchers.push(TaskUtil.loadElement(inner, innerSrc));\n }\n }\n } else {\n tag = fb2Remap[tag];\n }\n if (!tag) {\n tag = self.nodeContext.inline ? \"span\" : \"div\";\n }\n } else if (ns == Base.NS.NCX) {\n ns = Base.NS.XHTML;\n if (tag == \"ncx\" || tag == \"navPoint\") {\n tag = \"div\";\n } else if (tag == \"navLabel\") {\n // Cheat here. Translate source to HTML, so it will plug\n // in into the rest of the pipeline.\n tag = \"span\";\n const navParent = element.parentNode;\n if (navParent) {\n // find the content element\n let href: string | null = null;\n for (let c: Node = navParent.firstChild; c; c = c.nextSibling) {\n if (c.nodeType != 1) {\n continue;\n }\n const childElement = c as Element;\n if (\n childElement.namespaceURI == Base.NS.NCX &&\n childElement.localName == \"content\"\n ) {\n href = childElement.getAttribute(\"src\");\n break;\n }\n }\n if (href) {\n tag = \"a\";\n element = element.ownerDocument.createElementNS(ns, \"a\");\n element.setAttribute(\"href\", href);\n }\n }\n } else {\n tag = \"span\";\n }\n } else if (ns == Base.NS.SHADOW) {\n ns = Base.NS.XHTML;\n tag = self.nodeContext.inline ? \"span\" : \"div\";\n } else {\n custom = !!self.customRenderer;\n }\n if (listItem) {\n if (firstTime) {\n tag = \"li\";\n } else {\n tag = \"div\";\n display = Css.ident.block;\n computedStyle[\"display\"] = display;\n }\n } else if (tag == \"body\" || tag == \"li\") {\n tag = \"div\";\n } else if (tag == \"q\") {\n tag = \"span\";\n } else if (tag == \"a\") {\n const hp = computedStyle[\"hyperlink-processing\"];\n if (hp && hp.toString() != \"normal\") {\n tag = \"span\";\n }\n }\n if (computedStyle[\"behavior\"]) {\n const behavior = computedStyle[\"behavior\"].toString();\n if (behavior != \"none\" && self.customRenderer) {\n custom = true;\n }\n }\n if (\n (element as HTMLElement).dataset &&\n element.getAttribute(\"data-math-typeset\") === \"true\"\n ) {\n custom = true;\n }\n let elemResult: Task.Result<Element>;\n if (custom) {\n const parentNode = self.nodeContext.parent\n ? self.nodeContext.parent.viewNode\n : null;\n elemResult = self.customRenderer(\n element,\n parentNode as Element,\n computedStyle,\n );\n } else {\n elemResult = Task.newResult(null);\n }\n elemResult.then((result) => {\n if (result) {\n if (custom) {\n needToProcessChildren =\n result.getAttribute(\"data-adapt-process-children\") == \"true\";\n }\n } else {\n result = self.createElement(ns, tag);\n }\n if (tag == \"a\") {\n result.addEventListener(\"click\", self.page.hrefHandler, false);\n }\n if (inner) {\n self.applyPseudoelementStyle(self.nodeContext, \"inner\", inner);\n result.appendChild(inner);\n }\n if (\n result.localName == \"iframe\" &&\n result.namespaceURI == Base.NS.XHTML\n ) {\n initIFrame(result as HTMLIFrameElement);\n }\n const imageResolution = self.nodeContext.inheritedProps[\n \"image-resolution\"\n ] as number | undefined;\n const images: {\n image: HTMLElement;\n element: HTMLElement;\n fetcher: TaskUtil.Fetcher<string>;\n }[] = [];\n const cssWidth = computedStyle[\"width\"];\n const cssHeight = computedStyle[\"height\"];\n const attrWidth = element.getAttribute(\"width\");\n const attrHeight = element.getAttribute(\"height\");\n const hasAutoWidth =\n cssWidth === Css.ident.auto || (!cssWidth && !attrWidth);\n const hasAutoHeight =\n cssHeight === Css.ident.auto || (!cssHeight && !attrHeight);\n if (element.namespaceURI != Base.NS.FB2 || tag == \"td\") {\n const attributes = element.attributes;\n const attributeCount = attributes.length;\n let delayedSrc: string | null = null;\n for (let i = 0; i < attributeCount; i++) {\n const attribute = attributes[i];\n const attributeNS = attribute.namespaceURI;\n let attributeName = attribute.localName;\n let attributeValue = attribute.nodeValue;\n if (!attributeNS) {\n if (attributeName.match(/^on/)) {\n continue; // don't propagate JavaScript code\n }\n if (attributeName == \"style\") {\n continue; // we do styling ourselves\n }\n if (attributeName == \"id\" || attributeName == \"name\") {\n // Propagate transformed ids and collect them on the page\n // (only first time).\n if (firstTime) {\n attributeValue = self.documentURLTransformer.transformFragment(\n attributeValue,\n self.xmldoc.url,\n );\n result.setAttribute(attributeName, attributeValue);\n self.page.registerElementWithId(result, attributeValue);\n continue;\n }\n }\n\n // TODO: understand the element we are working with.\n if (\n attributeName == \"src\" ||\n attributeName == \"href\" ||\n attributeName == \"poster\"\n ) {\n attributeValue = self.resolveURL(attributeValue);\n if (attributeName === \"href\") {\n attributeValue = self.documentURLTransformer.transformURL(\n attributeValue,\n self.xmldoc.url,\n );\n }\n } else if (attributeName == \"srcset\") {\n attributeValue = attributeValue\n .split(\",\")\n .map((value) => self.resolveURL(value.trim()))\n .join(\",\");\n }\n if (\n attributeName === \"poster\" &&\n tag === \"video\" &&\n ns === Base.NS.XHTML &&\n hasAutoWidth &&\n hasAutoHeight\n ) {\n const image = new Image();\n const fetcher = TaskUtil.loadElement(image, attributeValue);\n fetchers.push(fetcher);\n images.push({\n image,\n element: result as HTMLElement,\n fetcher,\n });\n }\n } else if (attributeNS == \"http://www.w3.org/2000/xmlns/\") {\n continue; // namespace declaration (in Firefox)\n } else if (attributeNS == Base.NS.XLINK) {\n if (attributeName == \"href\") {\n attributeValue = self.resolveURL(attributeValue);\n }\n }\n if (ns == Base.NS.SVG && /^[A-Z\\-]+$/.test(attributeName)) {\n // Workaround for Edge bug\n // See\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/5579311/\n attributeName = attributeName.toLowerCase();\n }\n if (self.isSVGUrlAttribute(attributeName)) {\n attributeValue = Urls.transformURIs(\n attributeValue,\n self.xmldoc.url,\n self.documentURLTransformer,\n );\n }\n if (attributeNS) {\n const attributePrefix = namespacePrefixMap[attributeNS];\n if (attributePrefix) {\n attributeName = `${attributePrefix}:${attributeName}`;\n }\n }\n if (\n attributeName == \"src\" &&\n !attributeNS &&\n (tag == \"img\" || tag == \"input\") &&\n ns == Base.NS.XHTML\n ) {\n // HTML img element should start loading only once all\n // attributes are assigned.\n delayedSrc = attributeValue;\n } else if (\n attributeName == \"href\" &&\n tag == \"image\" &&\n ns == Base.NS.SVG &&\n attributeNS == Base.NS.XLINK\n ) {\n self.page.fetchers.push(\n TaskUtil.loadElement(result, attributeValue),\n );\n } else {\n // When the document is not XML document (e.g. non-XML HTML)\n // attributeNS can be null\n if (attributeNS) {\n result.setAttributeNS(\n attributeNS,\n attributeName,\n attributeValue,\n );\n } else {\n result.setAttribute(attributeName, attributeValue);\n }\n }\n }\n if (delayedSrc) {\n const image = tag === \"input\" ? new Image() : result;\n const imageFetcher = TaskUtil.loadElement(image, delayedSrc);\n if (image !== result) {\n (result as HTMLImageElement).src = delayedSrc;\n }\n if (!hasAutoWidth && !hasAutoHeight) {\n // No need to wait for the image, does not affect layout\n self.page.fetchers.push(imageFetcher);\n } else {\n if (\n hasAutoWidth &&\n hasAutoHeight &&\n imageResolution &&\n imageResolution !== 1\n ) {\n images.push({\n image: image as HTMLElement,\n element: result as HTMLElement,\n fetcher: imageFetcher,\n });\n }\n fetchers.push(imageFetcher);\n }\n }\n }\n delete computedStyle[\"content\"];\n const listStyleImage = computedStyle[\"list-style-image\"];\n if (listStyleImage && listStyleImage instanceof Css.URL) {\n const listStyleURL = (listStyleImage as Css.URL).url;\n fetchers.push(TaskUtil.loadElement(new Image(), listStyleURL));\n }\n self.preprocessElementStyle(computedStyle);\n self.applyComputedStyles(result, computedStyle);\n if (!self.nodeContext.inline) {\n let blackList: { [key: string]: string } = null;\n if (!firstTime) {\n if (\n self.nodeContext.inheritedProps[\"box-decoration-break\"] !==\n \"clone\"\n ) {\n blackList = self.nodeContext.vertical\n ? frontEdgeBlackListVert\n : frontEdgeBlackListHor;\n } else {\n // When box-decoration-break: clone, cloned margins are always\n // truncated to zero.\n blackList = self.nodeContext.vertical\n ? frontEdgeUnforcedBreakBlackListVert\n : frontEdgeUnforcedBreakBlackListHor;\n }\n } else if (atUnforcedBreak) {\n blackList = self.nodeContext.vertical\n ? frontEdgeUnforcedBreakBlackListVert\n : frontEdgeUnforcedBreakBlackListHor;\n }\n if (blackList) {\n for (const propName in blackList) {\n Base.setCSSProperty(result, propName, blackList[propName]);\n }\n }\n }\n if (listItem) {\n result.setAttribute(\n \"value\",\n computedStyle[\"ua-list-item-count\"].stringValue(),\n );\n }\n self.viewNode = result;\n if (fetchers.length) {\n TaskUtil.waitForFetchers(fetchers).then(() => {\n if (imageResolution > 0) {\n self.modifyElemDimensionWithImageResolution(\n images,\n imageResolution,\n computedStyle,\n self.nodeContext.vertical,\n );\n }\n frame.finish(needToProcessChildren);\n });\n } else {\n frame.timeSlice().then(() => {\n frame.finish(needToProcessChildren);\n });\n }\n });\n });\n return frame.result();\n }\n\n private processAfterIfcontinues(\n element: Element,\n cascStyle: CssCascade.ElementStyle,\n styler: CssStyler.AbstractStyler,\n context: Exprs.Context,\n ) {\n const pseudoMap = this.getPseudoMap(\n cascStyle,\n this.regionIds,\n this.isFootnote,\n this.nodeContext,\n context,\n );\n if (!pseudoMap) {\n return;\n }\n if (\n pseudoMap[\"after-if-continues\"] &&\n pseudoMap[\"after-if-continues\"][\"content\"]\n ) {\n const shadowStyler = new PseudoElement.PseudoelementStyler(\n element,\n cascStyle,\n styler,\n context,\n this.exprContentListener,\n );\n this.nodeContext.afterIfContinues = new Layout.AfterIfContinues(\n element,\n shadowStyler,\n );\n }\n }\n\n /**\n * @return isSVGUrlAttribute\n */\n isSVGUrlAttribute(attributeName: string): boolean {\n return ViewFactory.SVG_URL_ATTRIBUTES.includes(attributeName.toLowerCase());\n }\n\n modifyElemDimensionWithImageResolution(\n images: {\n image: HTMLElement;\n element: HTMLElement;\n fetcher: TaskUtil.Fetcher<string>;\n }[],\n imageResolution: number,\n computedStyle: { [key: string]: Css.Val },\n isVertical: boolean,\n ) {\n const self = this;\n images.forEach((param) => {\n if (param.fetcher.get().get() === \"load\") {\n const img = param.image;\n let scaledWidth = (img as HTMLImageElement).width / imageResolution;\n let scaledHeight = (img as HTMLImageElement).height / imageResolution;\n const elem = param.element;\n if (scaledWidth > 0 && scaledHeight > 0) {\n if (computedStyle[\"box-sizing\"] === Css.ident.border_box) {\n if (computedStyle[\"border-left-style\"] !== Css.ident.none) {\n scaledWidth += Css.toNumber(\n computedStyle[\"border-left-width\"],\n self.context,\n );\n }\n if (computedStyle[\"border-right-style\"] !== Css.ident.none) {\n scaledWidth += Css.toNumber(\n computedStyle[\"border-right-width\"],\n self.context,\n );\n }\n if (computedStyle[\"border-top-style\"] !== Css.ident.none) {\n scaledHeight += Css.toNumber(\n computedStyle[\"border-top-width\"],\n self.context,\n );\n }\n if (computedStyle[\"border-bottom-style\"] !== Css.ident.none) {\n scaledHeight += Css.toNumber(\n computedStyle[\"border-bottom-width\"],\n self.context,\n );\n }\n }\n if (imageResolution > 1) {\n const maxWidth = computedStyle[\"max-width\"] || Css.ident.none;\n const maxHeight = computedStyle[\"max-height\"] || Css.ident.none;\n if (maxWidth === Css.ident.none && maxHeight === Css.ident.none) {\n Base.setCSSProperty(elem, \"max-width\", `${scaledWidth}px`);\n } else if (\n maxWidth !== Css.ident.none &&\n maxHeight === Css.ident.none\n ) {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n } else if (\n maxWidth === Css.ident.none &&\n maxHeight !== Css.ident.none\n ) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n // maxWidth != none && maxHeight != none\n Asserts.assert(maxWidth.isNumeric());\n Asserts.assert(maxHeight.isNumeric());\n const numericMaxWidth = maxWidth as Css.Numeric;\n const numericMaxHeight = maxHeight as Css.Numeric;\n if (numericMaxWidth.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"max-width\",\n `${Math.min(\n scaledWidth,\n Css.toNumber(numericMaxWidth, self.context),\n )}px`,\n );\n } else if (numericMaxHeight.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"max-height\",\n `${Math.min(\n scaledHeight,\n Css.toNumber(numericMaxHeight, self.context),\n )}px`,\n );\n } else {\n if (isVertical) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n }\n }\n }\n } else if (imageResolution < 1) {\n const minWidth = computedStyle[\"min-width\"] || Css.numericZero;\n const minHeight = computedStyle[\"min-height\"] || Css.numericZero;\n Asserts.assert(minWidth.isNumeric());\n Asserts.assert(minWidth.isNumeric());\n const numericMinWidth = minWidth as Css.Numeric;\n const numericMinHeight = minHeight as Css.Numeric;\n if (numericMinWidth.num === 0 && numericMinHeight.num === 0) {\n Base.setCSSProperty(elem, \"min-width\", `${scaledWidth}px`);\n } else if (\n numericMinWidth.num !== 0 &&\n numericMinHeight.num === 0\n ) {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n } else if (\n numericMinWidth.num === 0 &&\n numericMinHeight.num !== 0\n ) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n // minWidth != 0 && minHeight != 0\n if (numericMinWidth.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"min-width\",\n `${Math.max(\n scaledWidth,\n Css.toNumber(numericMinWidth, self.context),\n )}px`,\n );\n } else if (numericMinHeight.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"min-height\",\n `${Math.max(\n scaledHeight,\n Css.toNumber(numericMinHeight, self.context),\n )}px`,\n );\n } else {\n if (isVertical) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n }\n }\n }\n }\n }\n }\n });\n }\n\n private preprocessElementStyle(computedStyle: { [key: string]: Css.Val }) {\n const self = this;\n const hooks: Plugin.PreProcessElementStyleHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.PREPROCESS_ELEMENT_STYLE,\n );\n hooks.forEach((hook) => {\n hook(self.nodeContext, computedStyle);\n });\n }\n\n private findAndProcessRepeatingElements(\n element: Element,\n styler: CssStyler.AbstractStyler,\n ) {\n for (\n let child: Node = element.firstChild;\n child;\n child = child.nextSibling\n ) {\n if (child.nodeType !== 1) {\n continue;\n }\n const computedStyle = {};\n const elementStyle = styler.getStyle(child as Element, false);\n this.computeStyle(\n this.nodeContext.vertical,\n this.nodeContext.direction === \"rtl\",\n elementStyle,\n computedStyle,\n );\n const processRepeatOnBreak = this.processRepeatOnBreak(computedStyle);\n if (!processRepeatOnBreak) {\n continue;\n }\n if (\n this.nodeContext.formattingContext instanceof\n RepetitiveElement.RepetitiveElementsOwnerFormattingContext &&\n !this.nodeContext.belongsTo(this.nodeContext.formattingContext)\n ) {\n return;\n }\n const parent = this.nodeContext.parent;\n const parentFormattingContext = parent && parent.formattingContext;\n this.nodeContext.formattingContext = new RepetitiveElement.RepetitiveElementsOwnerFormattingContext(\n parentFormattingContext,\n this.nodeContext.sourceNode as Element,\n );\n (this.nodeContext\n .formattingContext as RepetitiveElement.RepetitiveElementsOwnerFormattingContext).initializeRepetitiveElements(\n this.nodeContext.vertical,\n );\n return;\n }\n }\n\n private processRepeatOnBreak(computedStyle: { [key: string]: Css.Val }) {\n let repeatOnBreak = computedStyle[\"repeat-on-break\"];\n if (repeatOnBreak !== Css.ident.none) {\n if (repeatOnBreak === Css.ident.auto) {\n if (computedStyle[\"display\"] === Css.ident.table_header_group) {\n repeatOnBreak = Css.ident.header;\n } else if (computedStyle[\"display\"] === Css.ident.table_footer_group) {\n repeatOnBreak = Css.ident.footer;\n } else {\n repeatOnBreak = Css.ident.none;\n }\n }\n if (repeatOnBreak && repeatOnBreak !== Css.ident.none) {\n return repeatOnBreak.toString();\n }\n }\n return null;\n }\n\n private createTextNodeView(): Task.Result<boolean> {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"createTextNodeView\");\n this.preprocessTextContent().then(() => {\n const offsetInNode = self.offsetInNode || 0;\n const textContent = Diff.restoreNewText(\n self.nodeContext.preprocessedTextContent,\n ).substr(offsetInNode);\n self.viewNode = document.createTextNode(textContent);\n frame.finish(true);\n });\n return frame.result();\n }\n\n private preprocessTextContent(): Task.Result<boolean> {\n if (this.nodeContext.preprocessedTextContent != null) {\n return Task.newResult(true);\n }\n const self = this;\n let originl: string;\n let textContent = (originl = self.sourceNode.textContent);\n const frame: Task.Frame<boolean> = Task.newFrame(\"preprocessTextContent\");\n const hooks: Plugin.PreProcessTextContentHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.PREPROCESS_TEXT_CONTENT,\n );\n let index = 0;\n frame\n .loop(() => {\n if (index >= hooks.length) {\n return Task.newResult(false);\n }\n return hooks[index++](self.nodeContext, textContent).thenAsync(\n (processedText) => {\n textContent = processedText;\n return Task.newResult(true);\n },\n );\n })\n .then(() => {\n self.nodeContext.preprocessedTextContent = Diff.diffChars(\n originl,\n textContent,\n );\n frame.finish(true);\n });\n return frame.result();\n }\n\n /**\n * @return holding true if children should be processed\n */\n createNodeView(\n firstTime: boolean,\n atUnforcedBreak: boolean,\n ): Task.Result<boolean> {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"createNodeView\");\n let result: Task.Result<boolean>;\n let needToProcessChildren = true;\n if (self.sourceNode.nodeType == 1) {\n result = self.createElementView(firstTime, atUnforcedBreak);\n } else {\n if (self.sourceNode.nodeType == 8) {\n self.viewNode = null; // comment node\n result = Task.newResult(true);\n } else {\n result = self.createTextNodeView();\n }\n }\n result.then((processChildren) => {\n needToProcessChildren = processChildren;\n self.nodeContext.viewNode = self.viewNode;\n if (self.viewNode) {\n const parent = self.nodeContext.parent\n ? self.nodeContext.parent.viewNode\n : self.viewRoot;\n if (parent) {\n parent.appendChild(self.viewNode);\n }\n }\n frame.finish(needToProcessChildren);\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n setCurrent(\n nodeContext: Vtree.NodeContext,\n firstTime: boolean,\n atUnforcedBreak?: boolean,\n ): Task.Result<boolean> {\n this.nodeContext = nodeContext;\n if (nodeContext) {\n this.sourceNode = nodeContext.sourceNode;\n this.offsetInNode = nodeContext.offsetInNode;\n } else {\n this.sourceNode = null;\n this.offsetInNode = -1;\n }\n this.viewNode = null;\n if (this.nodeContext) {\n return this.createNodeView(firstTime, !!atUnforcedBreak);\n }\n return Task.newResult(true);\n }\n\n processShadowContent(pos: Vtree.NodeContext): Vtree.NodeContext {\n if (\n pos.shadowContext == null ||\n (pos.sourceNode as Element).localName != \"content\" ||\n pos.sourceNode.namespaceURI != Base.NS.SHADOW\n ) {\n return pos;\n }\n const boxOffset = pos.boxOffset;\n const shadow = pos.shadowContext;\n const parent = pos.parent;\n\n // content that will be inserted\n let contentNode: Node;\n let contentShadowType: Vtree.ShadowType;\n let contentShadow: Vtree.ShadowContext;\n if (shadow.subShadow) {\n contentShadow = shadow.subShadow;\n contentNode = shadow.root;\n contentShadowType = shadow.type;\n if (contentShadowType == Vtree.ShadowType.ROOTLESS) {\n contentNode = contentNode.firstChild;\n }\n } else {\n contentShadow = shadow.parentShadow;\n contentNode = shadow.owner.firstChild;\n contentShadowType = Vtree.ShadowType.ROOTLESS;\n }\n const nextSibling = pos.sourceNode.nextSibling;\n if (nextSibling) {\n pos.sourceNode = nextSibling;\n pos.resetView();\n } else if (pos.shadowSibling) {\n pos = pos.shadowSibling;\n } else if (contentNode) {\n pos = null;\n } else {\n pos = pos.parent.modify();\n pos.after = true;\n }\n if (contentNode) {\n const r = new Vtree.NodeContext(contentNode, parent, boxOffset);\n r.shadowContext = contentShadow;\n r.shadowType = contentShadowType;\n r.shadowSibling = pos;\n return r;\n }\n pos.boxOffset = boxOffset;\n return pos;\n }\n\n private nextPositionInTree(pos: Vtree.NodeContext): Vtree.NodeContext {\n let boxOffset = pos.boxOffset + 1; // offset for the next position\n if (pos.after) {\n // root, that was the last possible position\n if (!pos.parent) {\n return null;\n }\n\n // we are done with this sourceNode, see if there is a next sibling,\n // unless this is the root of the shadow tree\n if (pos.shadowType != Vtree.ShadowType.ROOTED) {\n const next = pos.sourceNode.nextSibling;\n if (next) {\n pos = pos.modify();\n\n // keep shadowType\n pos.boxOffset = boxOffset;\n pos.sourceNode = next;\n pos.resetView();\n return this.processShadowContent(pos);\n }\n }\n\n // if no viable siblings, check if there are shadow siblings\n if (pos.shadowSibling) {\n // our next position is the element after shadow:content in the parent\n // shadow tree\n pos = pos.shadowSibling.modify();\n pos.boxOffset = boxOffset;\n return pos;\n }\n\n // if not rootless shadow, move to the \"after\" position for the parent\n pos = pos.parent.modify();\n pos.boxOffset = boxOffset;\n pos.after = true;\n return pos;\n } else {\n // any shadow trees?\n if (pos.nodeShadow) {\n let shadowNode: Node | null = pos.nodeShadow.root;\n if (pos.nodeShadow.type == Vtree.ShadowType.ROOTLESS) {\n shadowNode = shadowNode.firstChild;\n }\n if (shadowNode) {\n const sr = new Vtree.NodeContext(shadowNode, pos, boxOffset);\n sr.shadowContext = pos.nodeShadow;\n sr.shadowType = pos.nodeShadow.type;\n return this.processShadowContent(sr);\n }\n }\n\n // any children?\n const child = pos.sourceNode.firstChild;\n if (child) {\n return this.processShadowContent(\n new Vtree.NodeContext(child, pos, boxOffset),\n );\n }\n\n // no children - was there text content?\n if (pos.sourceNode.nodeType != 1) {\n const content = Diff.restoreNewText(pos.preprocessedTextContent);\n boxOffset += content.length - 1 - pos.offsetInNode;\n }\n pos = pos.modify();\n pos.boxOffset = boxOffset;\n pos.after = true;\n return pos;\n }\n }\n\n isTransclusion(\n element: Element,\n elementStyle: CssCascade.ElementStyle,\n transclusionType: string | null,\n ) {\n const proc = CssCascade.getProp(elementStyle, \"hyperlink-processing\");\n if (!proc) {\n return false;\n }\n const prop = proc.evaluate(this.context, \"hyperlink-processing\");\n if (!prop) {\n return false;\n }\n return prop.toString() == transclusionType;\n }\n\n /**\n * @override\n */\n nextInTree(\n position: Vtree.NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<Vtree.NodeContext> {\n let nodeContext = this.nextPositionInTree(position);\n if (!nodeContext || nodeContext.after) {\n return Task.newResult(nodeContext);\n }\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"nextInTree\");\n this.setCurrent(nodeContext, true, atUnforcedBreak).then(\n (processChildren) => {\n if (!nodeContext.viewNode || !processChildren) {\n nodeContext = nodeContext.modify();\n nodeContext.after = true; // skip\n if (!nodeContext.viewNode) {\n nodeContext.inline = true;\n }\n }\n this.dispatchEvent({ type: \"nextInTree\", nodeContext } as any);\n frame.finish(nodeContext);\n },\n );\n return frame.result();\n }\n\n addImageFetchers(bg: Css.Val) {\n if (bg instanceof Css.CommaList) {\n const values = (bg as Css.CommaList).values;\n for (let i = 0; i < values.length; i++) {\n this.addImageFetchers(values[i]);\n }\n } else if (bg instanceof Css.URL) {\n const url = (bg as Css.URL).url;\n this.page.fetchers.push(TaskUtil.loadElement(new Image(), url));\n }\n }\n\n applyComputedStyles(\n target: Element,\n computedStyle: { [key: string]: Css.Val },\n ) {\n const bg = computedStyle[\"background-image\"];\n if (bg) {\n this.addImageFetchers(bg);\n }\n const isRelativePositioned =\n computedStyle[\"position\"] === Css.ident.relative;\n for (const propName in computedStyle) {\n if (propertiesNotPassedToDOM[propName]) {\n continue;\n }\n let value = computedStyle[propName];\n value = value.visit(\n new CssProp.UrlTransformVisitor(\n this.xmldoc.url,\n this.documentURLTransformer,\n ),\n );\n if (\n value.isNumeric() &&\n Exprs.needUnitConversion((value as Css.Numeric).unit)\n ) {\n // font-size for the root element is already converted to px\n value = Css.convertNumericToPx(value, this.context);\n }\n if (\n Vtree.delayedProps[propName] ||\n (isRelativePositioned &&\n Vtree.delayedPropsIfRelativePositioned[propName])\n ) {\n // Set it after page layout is done.\n this.page.delayedItems.push(\n new Vtree.DelayedItem(target, propName, value),\n );\n continue;\n }\n Base.setCSSProperty(target, propName, value.toString());\n }\n }\n\n /**\n * @override\n */\n applyPseudoelementStyle(\n nodeContext: Vtree.NodeContext,\n pseudoName: string,\n target: Element,\n ): void {\n if (nodeContext.after) {\n return;\n }\n const element = this.sourceNode as Element;\n const styler = nodeContext.shadowContext\n ? (nodeContext.shadowContext.styler as CssStyler.AbstractStyler)\n : this.styler;\n let elementStyle = styler.getStyle(element, false);\n const pseudoMap = CssCascade.getStyleMap(elementStyle, \"_pseudos\");\n if (!pseudoMap) {\n return;\n }\n elementStyle = pseudoMap[pseudoName];\n if (!elementStyle) {\n return;\n }\n const computedStyle = {};\n nodeContext.vertical = this.computeStyle(\n nodeContext.vertical,\n nodeContext.direction === \"rtl\",\n elementStyle,\n computedStyle,\n );\n const content = computedStyle[\"content\"];\n if (Vtree.nonTrivialContent(content)) {\n content.visit(\n new Vtree.ContentPropertyHandler(\n target,\n this.context,\n content,\n this.exprContentListener,\n ),\n );\n delete computedStyle[\"content\"];\n }\n this.applyComputedStyles(target, computedStyle);\n }\n\n /**\n * @override\n */\n peelOff(\n nodeContext: Vtree.NodeContext,\n nodeOffset: number,\n ): Task.Result<Vtree.NodeContext> {\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"peelOff\");\n const firstPseudo = nodeContext.firstPseudo;\n let offsetInNode = nodeContext.offsetInNode;\n const after = nodeContext.after;\n if (nodeOffset > 0) {\n const text = nodeContext.viewNode.textContent;\n nodeContext.viewNode.textContent = text.substr(0, nodeOffset);\n offsetInNode += nodeOffset;\n } else if (!after && nodeContext.viewNode && offsetInNode == 0) {\n const parent = nodeContext.viewNode.parentNode;\n if (parent) {\n parent.removeChild(nodeContext.viewNode);\n }\n }\n const boxOffset = nodeContext.boxOffset + nodeOffset;\n const arr = [];\n while (nodeContext.firstPseudo === firstPseudo) {\n arr.push(nodeContext);\n nodeContext = nodeContext.parent;\n }\n let pn = arr.pop(); // container for that pseudoelement\n let shadowSibling = pn.shadowSibling;\n const self = this;\n frame\n .loop(() => {\n while (arr.length > 0) {\n pn = arr.pop();\n nodeContext = new Vtree.NodeContext(\n pn.sourceNode,\n nodeContext,\n boxOffset,\n );\n if (arr.length == 0) {\n nodeContext.offsetInNode = offsetInNode;\n nodeContext.after = after;\n }\n nodeContext.shadowType = pn.shadowType;\n (nodeContext.shadowContext = pn.shadowContext),\n (nodeContext.nodeShadow = pn.nodeShadow);\n nodeContext.shadowSibling = pn.shadowSibling\n ? pn.shadowSibling\n : shadowSibling;\n shadowSibling = null;\n const result = self.setCurrent(nodeContext, false);\n if (result.isPending()) {\n return result;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n createElement(ns: string, tag: string): Element {\n if (ns == Base.NS.XHTML) {\n return this.document.createElement(tag);\n }\n return this.document.createElementNS(ns, tag);\n }\n\n /**\n * @override\n */\n applyFootnoteStyle(\n vertical: boolean,\n rtl: boolean,\n target: Element,\n ): boolean {\n const computedStyle = {};\n const pseudoMap = CssCascade.getStyleMap(this.footnoteStyle, \"_pseudos\");\n vertical = this.computeStyle(\n vertical,\n rtl,\n this.footnoteStyle,\n computedStyle,\n );\n if (pseudoMap && pseudoMap[\"before\"]) {\n const childComputedStyle = {};\n const span = this.createElement(Base.NS.XHTML, \"span\");\n PseudoElement.setPseudoName(span, \"before\");\n target.appendChild(span);\n this.computeStyle(vertical, rtl, pseudoMap[\"before\"], childComputedStyle);\n delete childComputedStyle[\"content\"];\n this.applyComputedStyles(span, childComputedStyle);\n }\n delete computedStyle[\"content\"];\n this.applyComputedStyles(target, computedStyle);\n return vertical;\n }\n\n /**\n * @override\n */\n processFragmentedBlockEdge(nodeContext: Vtree.NodeContext) {\n if (nodeContext) {\n nodeContext.walkUpBlocks((block) => {\n const boxDecorationBreak = block.inheritedProps[\"box-decoration-break\"];\n if (!boxDecorationBreak || boxDecorationBreak === \"slice\") {\n const elem = block.viewNode as Element;\n Asserts.assert(elem instanceof Element);\n if (block.vertical) {\n Base.setCSSProperty(elem, \"padding-left\", \"0\");\n Base.setCSSProperty(elem, \"border-left\", \"none\");\n Base.setCSSProperty(elem, \"border-top-left-radius\", \"0\");\n Base.setCSSProperty(elem, \"border-bottom-left-radius\", \"0\");\n } else {\n Base.setCSSProperty(elem, \"padding-bottom\", \"0\");\n Base.setCSSProperty(elem, \"border-bottom\", \"none\");\n Base.setCSSProperty(elem, \"border-bottom-left-radius\", \"0\");\n Base.setCSSProperty(elem, \"border-bottom-right-radius\", \"0\");\n }\n }\n });\n }\n }\n\n /**\n * @override\n */\n convertLengthToPx(\n numeric: Css.Numeric,\n viewNode: Node,\n clientLayout: Vtree.ClientLayout,\n ): number | Css.Numeric {\n const num = numeric.num;\n const unit = numeric.unit;\n if (Exprs.isFontRelativeLengthUnit(unit)) {\n let elem = viewNode;\n while (elem && elem.nodeType !== 1) {\n elem = elem.parentNode;\n }\n Asserts.assert(elem);\n const fontSize = parseFloat(\n clientLayout.getElementComputedStyle(elem as Element)[\"font-size\"],\n );\n Asserts.assert(this.context);\n return CssCascade.convertFontRelativeLengthToPx(\n numeric,\n fontSize,\n this.context,\n ).num;\n } else {\n const unitSize = this.context.queryUnitSize(unit, false);\n if (unitSize) {\n return num * unitSize;\n } else {\n return numeric;\n }\n }\n }\n\n /**\n * Returns if two NodePositionStep are equivalent.\n */\n isSameNodePositionStep(\n step1: Vtree.NodePositionStep,\n step2: Vtree.NodePositionStep,\n ): boolean {\n if (step1.shadowContext) {\n if (!step2.shadowContext) {\n return false;\n }\n const elem1 =\n step1.node.nodeType === 1\n ? (step1.node as Element)\n : (step1.node.parentElement as Element);\n const elem2 =\n step2.node.nodeType === 1\n ? (step2.node as Element)\n : (step2.node.parentElement as Element);\n return (\n step1.shadowContext.owner === step2.shadowContext.owner &&\n PseudoElement.getPseudoName(elem1) ===\n PseudoElement.getPseudoName(elem2)\n );\n } else {\n return step1.node === step2.node;\n }\n }\n\n /**\n * @override\n */\n isSameNodePosition(\n nodePosition1: Vtree.NodePosition,\n nodePosition2: Vtree.NodePosition,\n ): boolean {\n return (\n nodePosition1.offsetInNode === nodePosition2.offsetInNode &&\n nodePosition1.after == nodePosition2.after &&\n nodePosition1.steps.length === nodePosition2.steps.length &&\n nodePosition1.steps.every((step1, i) => {\n const step2 = nodePosition2.steps[i];\n return this.isSameNodePositionStep(step1, step2);\n })\n );\n }\n\n isPseudoelement(elem) {\n return !!PseudoElement.getPseudoName(elem);\n }\n}\n\nexport const fb2Remap = {\n a: \"a\",\n sub: \"sub\",\n sup: \"sup\",\n table: \"table\",\n tr: \"tr\",\n td: \"td\",\n th: \"th\",\n code: \"code\",\n body: \"div\",\n p: \"p\",\n v: \"p\",\n date: \"p\",\n emphasis: \"em\",\n strong: \"strong\",\n style: \"span\",\n strikethrough: \"del\",\n};\n\nexport const propertiesNotPassedToDOM = {\n \"box-decoration-break\": true,\n \"float-min-wrap-block\": true,\n \"float-reference\": true,\n \"flow-into\": true,\n \"flow-linger\": true,\n \"flow-options\": true,\n \"flow-priority\": true,\n \"footnote-policy\": true,\n page: true,\n};\n\nexport class DefaultClientLayout implements Vtree.ClientLayout {\n layoutBox: Element;\n window: Window;\n\n constructor(viewport: Viewport) {\n this.layoutBox = viewport.layoutBox;\n this.window = viewport.window;\n }\n\n private subtractOffsets(\n rect: Vtree.ClientRect,\n originRect: Vtree.ClientRect,\n ): Vtree.ClientRect {\n const viewportLeft = originRect.left;\n const viewportTop = originRect.top;\n return {\n left: rect.left - viewportLeft,\n top: rect.top - viewportTop,\n right: rect.right - viewportLeft,\n bottom: rect.bottom - viewportTop,\n width: rect.width,\n height: rect.height,\n } as Vtree.ClientRect;\n }\n\n /**\n * @override\n */\n getRangeClientRects(range: Range): ClientRect[] {\n const rects = range[\"getClientRects\"]();\n const layoutBoxRect = this.layoutBox.getBoundingClientRect();\n return Array.from(rects).map((rect) =>\n this.subtractOffsets(rect, layoutBoxRect),\n );\n }\n\n /**\n * @override\n */\n getElementClientRect(element: Element): ClientRect {\n const htmlElement = element as HTMLElement;\n const rect = htmlElement.getBoundingClientRect() as Vtree.ClientRect;\n const layoutBoxRect = this.layoutBox.getBoundingClientRect();\n return this.subtractOffsets(rect, layoutBoxRect);\n }\n\n /**\n * @override\n */\n getElementComputedStyle(element: Element): CSSStyleDeclaration {\n return this.window.getComputedStyle(element, null);\n }\n}\n\nexport class Viewport {\n document: Document;\n root: HTMLElement;\n private outerZoomBox: HTMLElement;\n contentContainer: HTMLElement;\n layoutBox: Element;\n width: number;\n height: number;\n\n constructor(\n public readonly window: Window,\n public readonly fontSize: number,\n opt_root?: HTMLElement,\n opt_width?: number,\n opt_height?: number,\n ) {\n this.document = window.document;\n this.root = opt_root || this.document.body;\n let outerZoomBox = this.root.firstElementChild;\n if (!outerZoomBox) {\n outerZoomBox = this.document.createElement(\"div\");\n outerZoomBox.setAttribute(\"data-vivliostyle-outer-zoom-box\", \"true\");\n this.root.appendChild(outerZoomBox);\n }\n let contentContainer = outerZoomBox.firstElementChild;\n if (!contentContainer) {\n contentContainer = this.document.createElement(\"div\");\n contentContainer.setAttribute(\n \"data-vivliostyle-spread-container\",\n \"true\",\n );\n outerZoomBox.appendChild(contentContainer);\n }\n let layoutBox = outerZoomBox.nextElementSibling;\n if (!layoutBox) {\n layoutBox = this.document.createElement(\"div\");\n layoutBox.setAttribute(\"data-vivliostyle-layout-box\", \"true\");\n this.root.appendChild(layoutBox);\n }\n this.outerZoomBox = outerZoomBox as HTMLElement;\n this.contentContainer = contentContainer as HTMLElement;\n this.layoutBox = layoutBox as HTMLElement;\n const clientLayout = new DefaultClientLayout(this);\n const computedStyle = clientLayout.getElementComputedStyle(this.root);\n this.width =\n opt_width || parseFloat(computedStyle[\"width\"]) || window.innerWidth;\n this.height =\n opt_height || parseFloat(computedStyle[\"height\"]) || window.innerHeight;\n }\n\n /**\n * Reset zoom.\n */\n resetZoom() {\n Base.setCSSProperty(this.outerZoomBox, \"width\", \"\");\n Base.setCSSProperty(this.outerZoomBox, \"height\", \"\");\n Base.setCSSProperty(this.contentContainer, \"width\", \"\");\n Base.setCSSProperty(this.contentContainer, \"height\", \"\");\n Base.setCSSProperty(this.contentContainer, \"transform\", \"\");\n }\n\n /**\n * Zoom viewport.\n * @param width Overall width of contents before scaling (px)\n * @param height Overall height of contents before scaling (px)\n * @param scale Factor to which the viewport will be scaled.\n */\n zoom(width: number, height: number, scale: number) {\n Base.setCSSProperty(this.outerZoomBox, \"width\", `${width * scale}px`);\n Base.setCSSProperty(this.outerZoomBox, \"height\", `${height * scale}px`);\n Base.setCSSProperty(this.contentContainer, \"width\", `${width}px`);\n Base.setCSSProperty(this.contentContainer, \"height\", `${height}px`);\n Base.setCSSProperty(this.contentContainer, \"transform\", `scale(${scale})`);\n }\n\n /**\n * Remove all pages inside the viewport.\n */\n clear() {\n const root = this.root;\n while (root.lastChild) {\n root.removeChild(root.lastChild);\n }\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview XmlDoc - Utility functions to work with XML (mostly XHTML)\n * documents.\n */\nimport * as Base from \"./base\";\nimport * as Net from \"./net\";\nimport * as Task from \"./task\";\nimport { XmlDoc } from \"./types\";\n\nexport type XMLDocStore = XmlDoc.XMLDocStore;\n\nexport const ELEMENT_OFFSET_ATTR = \"data-adapt-eloff\";\n\nexport class XMLDocHolder implements XmlDoc.XMLDocHolder {\n lang: string | null = null;\n totalOffset: number = -1;\n root: Element;\n body: Element;\n head: Element;\n last: Element;\n lastOffset: number = 1;\n idMap: { [key: string]: Element };\n\n constructor(\n public readonly store: XMLDocStore,\n public readonly url: string,\n public readonly document: Document,\n ) {\n this.root = document.documentElement; // html element\n let body: Element = null;\n let head: Element = null;\n if (this.root.namespaceURI == Base.NS.XHTML) {\n for (\n let child: Node = this.root.firstChild;\n child;\n child = child.nextSibling\n ) {\n if (child.nodeType != 1) {\n continue;\n }\n const elem = child as Element;\n if (elem.namespaceURI == Base.NS.XHTML) {\n switch (elem.localName) {\n case \"head\":\n head = elem;\n break;\n case \"body\":\n body = elem;\n break;\n }\n }\n }\n this.lang = this.root.getAttribute(\"lang\");\n } else if (this.root.namespaceURI == Base.NS.FB2) {\n head = this.root;\n for (\n let child: Node = this.root.firstChild;\n child;\n child = child.nextSibling\n ) {\n if (child.nodeType != 1) {\n continue;\n }\n const elem = child as Element;\n if (elem.namespaceURI == Base.NS.FB2) {\n if (elem.localName == \"body\") {\n body = elem;\n }\n }\n }\n const langs = this.doc()\n .child(\"FictionBook\")\n .child(\"description\")\n .child(\"title-info\")\n .child(\"lang\")\n .textContent();\n if (langs.length > 0) {\n this.lang = langs[0];\n }\n } else if (this.root.namespaceURI == Base.NS.SSE) {\n // treat <meta> element as \"head\" of the document\n for (\n let elem = this.root.firstElementChild;\n elem;\n elem = elem.nextElementSibling\n ) {\n const localName = elem.localName;\n if (localName === \"meta\") {\n head = elem;\n } else if (localName === \"body\") {\n body = elem;\n }\n }\n }\n this.body = body as Element;\n this.head = head as Element;\n this.last = this.root;\n this.last.setAttribute(ELEMENT_OFFSET_ATTR, \"0\");\n }\n\n doc(): XmlDoc.NodeList {\n return new NodeList([this.document]);\n }\n\n getElementOffset(element: Element): number {\n const offsetStr = element.getAttribute(ELEMENT_OFFSET_ATTR);\n if (offsetStr) {\n return parseInt(offsetStr, 10);\n }\n let offset = this.lastOffset;\n let last: Node | null = this.last;\n while (last != element) {\n let next: Node | null = last.firstChild;\n if (!next) {\n while (true) {\n next = last.nextSibling;\n if (next) {\n break;\n }\n last = last.parentNode;\n if (last == null) {\n throw new Error(\"Internal error\");\n }\n }\n }\n last = next;\n if (next.nodeType == 1) {\n const nextElement = next as Element;\n nextElement.setAttribute(ELEMENT_OFFSET_ATTR, offset.toString());\n ++offset;\n } else {\n offset += (next.textContent as string).length;\n }\n }\n this.lastOffset = offset;\n this.last = element;\n return offset - 1;\n }\n\n getNodeOffset(srcNode: Node, offsetInNode: number, after: boolean) {\n let extraOffset = 0;\n let node: Node | null = srcNode;\n let prev: Node | null = null;\n if (node.nodeType == 1) {\n // after = true is only valid for elements\n if (!after) {\n return this.getElementOffset(node as Element);\n }\n } else {\n // offsetInNode is only valid for text nodes\n extraOffset = offsetInNode;\n prev = node.previousSibling;\n if (!prev) {\n node = node.parentNode;\n extraOffset += 1;\n return this.getElementOffset(node as Element) + extraOffset;\n }\n node = prev;\n }\n while (true) {\n while (node.lastChild) {\n node = node.lastChild;\n }\n if (node.nodeType == 1) {\n // empty element\n break;\n }\n extraOffset += (node.textContent as string).length;\n prev = node.previousSibling;\n if (!prev) {\n node = node.parentNode;\n break;\n }\n node = prev;\n }\n extraOffset += 1;\n return this.getElementOffset(node as Element) + extraOffset;\n }\n\n getTotalOffset(): number {\n if (this.totalOffset < 0) {\n this.totalOffset = this.getNodeOffset(this.root, 0, true);\n }\n return this.totalOffset;\n }\n\n /**\n * @return last node such that its offset is less or equal to the given\n */\n getNodeByOffset(offset: number): Node {\n let elementOffset: number;\n\n // First, find the last element in the document, such that\n // this.getElementOffset(element) <= offset; if offest matches\n // exactly, just return it.\n const self = this;\n let element = this.root;\n while (true) {\n elementOffset = this.getElementOffset(element);\n if (elementOffset >= offset) {\n return element;\n }\n const children = element.children; // Element children\n if (!children) {\n break;\n }\n const index = Base.binarySearch(children.length, (index) => {\n const child = children[index];\n const childOffset = self.getElementOffset(child);\n return childOffset > offset;\n });\n if (index == 0) {\n break;\n }\n if (VIVLIOSTYLE_DEBUG) {\n if (index < children.length) {\n const elemOffset = self.getElementOffset(children[index]);\n if (elemOffset <= offset) {\n throw new Error(\"Consistency check failed!\");\n }\n }\n }\n element = children[index - 1];\n }\n\n // Now we have element with offset less than desired. Find following\n // (non-element) node with the right offset.\n let nodeOffset = elementOffset + 1;\n let node: Node | null = element;\n let next: Node | null = node.firstChild || node.nextSibling;\n let lastGood: Node | null = null;\n while (true) {\n if (next) {\n if (next.nodeType == 1) {\n break;\n }\n node = next;\n lastGood = node;\n nodeOffset += (next.textContent as string).length;\n if (nodeOffset > offset) {\n break;\n }\n } else {\n node = node.parentNode;\n if (!node) {\n break;\n }\n }\n next = node.nextSibling;\n }\n return lastGood || element;\n }\n\n private buildIdMap(e: Element): void {\n const id = e.getAttribute(\"id\");\n if (id && !this.idMap[id]) {\n this.idMap[id] = e;\n }\n const xmlid = e.getAttributeNS(Base.NS.XML, \"id\");\n if (xmlid && !this.idMap[xmlid]) {\n this.idMap[xmlid] = e;\n }\n for (let c = e.firstElementChild; c; c = c.nextElementSibling) {\n this.buildIdMap(c);\n }\n }\n\n /**\n * Get element by URL in the source document(s). URL must be in either '#id'\n * or 'url#id' form.\n */\n getElement(url: string): Element | null {\n const m = url.match(/([^#]*)#(.+)$/);\n if (!m || (m[1] && m[1] != this.url)) {\n return null;\n }\n const id = m[2];\n let r: Element = this.document.getElementById(id);\n if (!r && this.document.getElementsByName) {\n r = this.document.getElementsByName(id)[0];\n }\n if (!r) {\n if (!this.idMap) {\n this.idMap = {};\n this.buildIdMap(this.document.documentElement);\n }\n r = this.idMap[id];\n }\n return r;\n }\n}\n\n/**\n * cf. https://w3c.github.io/DOM-Parsing/#the-domparser-interface\n * @enum {string}\n */\nexport enum DOMParserSupportedType {\n TEXT_HTML = \"text/html\",\n TEXT_XML = \"text/xml\",\n APPLICATION_XML = \"application/xml\",\n APPLICATION_XHTML_XML = \"application/xhtml_xml\",\n IMAGE_SVG_XML = \"image/svg+xml\",\n}\n\n/**\n * Parses a string with a DOMParser and returns the document.\n * If a parse error occurs, return null.\n */\nexport function parseAndReturnNullIfError(\n str: string,\n type: string,\n opt_parser?: DOMParser,\n): Document | null {\n const parser = opt_parser || new DOMParser();\n let doc: Document;\n try {\n doc = parser.parseFromString(str, type as SupportedType);\n } catch (e) {}\n if (!doc) {\n return null;\n } else {\n const docElement = doc.documentElement;\n const errorTagName = \"parsererror\";\n if (docElement.localName === errorTagName) {\n return null;\n } else {\n for (let c = docElement.firstElementChild; c; c = c.nextElementSibling) {\n if (c.localName === errorTagName) {\n return null;\n }\n }\n }\n }\n return doc;\n}\n\n/**\n * @returns null if contentType cannot be inferred from HTTP header and file\n * extension\n */\nexport function resolveContentType(response: Net.Response): string | null {\n const contentType = response.contentType;\n if (contentType) {\n const supportedKeys = Object.keys(DOMParserSupportedType);\n for (let i = 0; i < supportedKeys.length; i++) {\n if (DOMParserSupportedType[supportedKeys[i]] === contentType) {\n return contentType;\n }\n }\n if (contentType.match(/\\+xml$/)) {\n return DOMParserSupportedType.APPLICATION_XML;\n }\n }\n const match = response.url.match(/\\.([^./]+)$/);\n if (match) {\n const extension = match[1];\n switch (extension) {\n case \"html\":\n case \"htm\":\n return DOMParserSupportedType.TEXT_HTML;\n case \"xhtml\":\n case \"xht\":\n return DOMParserSupportedType.APPLICATION_XHTML_XML;\n case \"svg\":\n case \"svgz\":\n return DOMParserSupportedType.IMAGE_SVG_XML;\n case \"opf\":\n case \"xml\":\n return DOMParserSupportedType.APPLICATION_XML;\n }\n }\n return null;\n}\n\nexport function parseXMLResource(\n response: Net.Response,\n store: XMLDocStore,\n): Task.Result<XmlDoc.XMLDocHolder> {\n let doc = response.responseXML;\n if (!doc) {\n const parser = new DOMParser();\n const text = response.responseText;\n if (text) {\n const contentType = resolveContentType(response);\n doc = parseAndReturnNullIfError(\n text,\n contentType || DOMParserSupportedType.APPLICATION_XML,\n parser,\n );\n\n // When contentType cannot be inferred from HTTP header and file\n // extension, we use root element's tag name to infer the contentType. If\n // it is html or svg, we re-parse the source with an appropriate\n // contentType.\n if (doc && !contentType) {\n const root = doc.documentElement;\n if (root.localName.toLowerCase() === \"html\" && !root.namespaceURI) {\n doc = parseAndReturnNullIfError(\n text,\n DOMParserSupportedType.TEXT_HTML,\n parser,\n );\n } else if (\n root.localName.toLowerCase() === \"svg\" &&\n (doc as any).contentType !== DOMParserSupportedType.IMAGE_SVG_XML\n ) {\n doc = parseAndReturnNullIfError(\n text,\n DOMParserSupportedType.IMAGE_SVG_XML,\n parser,\n );\n }\n }\n if (!doc) {\n // Fallback to HTML parsing\n doc = parseAndReturnNullIfError(\n text,\n DOMParserSupportedType.TEXT_HTML,\n parser,\n );\n }\n }\n }\n const xmldoc = doc ? new XMLDocHolder(store, response.url, doc) : null;\n return Task.newResult(xmldoc);\n}\n\nexport function newXMLDocStore(): XMLDocStore {\n return new Net.ResourceStore(\n parseXMLResource,\n Net.XMLHttpRequestResponseType.DOCUMENT,\n );\n}\n\nexport class Predicate implements XmlDoc.Predicate {\n constructor(public readonly fn: (p1: Node) => boolean) {}\n\n check(node: Node): boolean {\n return this.fn(node);\n }\n\n withAttribute(name: string, value: string): Predicate {\n const self = this;\n return new Predicate(\n (node) =>\n self.check(node) &&\n node.nodeType == 1 &&\n (node as Element).getAttribute(name) == value,\n );\n }\n\n withChild(name: string, opt_childPredicate?: Predicate): Predicate {\n const self = this;\n return new Predicate((node) => {\n if (!self.check(node)) {\n return false;\n }\n let list = new NodeList([node]);\n list = list.child(name);\n if (opt_childPredicate) {\n list = list.predicate(opt_childPredicate);\n }\n return list.size() > 0;\n });\n }\n}\n\nexport const predicate = new Predicate((node) => true);\n\nexport class NodeList implements XmlDoc.NodeList {\n constructor(public readonly nodes: Node[]) {}\n\n asArray(): Node[] {\n return this.nodes;\n }\n\n size(): number {\n return this.nodes.length;\n }\n\n /**\n * Filter with predicate\n */\n predicate(pr: Predicate): NodeList {\n const arr = [];\n for (const n of this.nodes) {\n if (pr.check(n)) {\n arr.push(n);\n }\n }\n return new NodeList(arr);\n }\n\n forEachNode(fn: (p1: Node, p2: (p1: Node) => void) => void): NodeList {\n const arr = [];\n const add = (n) => {\n arr.push(n);\n };\n for (let i = 0; i < this.nodes.length; i++) {\n fn(this.nodes[i], add);\n }\n return new NodeList(arr);\n }\n\n /**\n * @template T\n */\n forEach<T>(fn: (p1: Node) => T): T[] {\n const arr = [];\n for (let i = 0; i < this.nodes.length; i++) {\n arr.push(fn(this.nodes[i]));\n }\n return arr;\n }\n\n /**\n * @template T\n */\n forEachNonNull<T>(fn: (p1: Node) => T): T[] {\n const arr = [];\n for (let i = 0; i < this.nodes.length; i++) {\n const t = fn(this.nodes[i]);\n if (t != null) {\n arr.push(t);\n }\n }\n return arr;\n }\n\n child(tag: string): NodeList {\n return this.forEachNode((node, add) => {\n for (let c: Node = node.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1 && (c as Element).localName == tag) {\n add(c);\n }\n }\n });\n }\n\n childElements(): NodeList {\n return this.forEachNode((node, add) => {\n for (let c: Node = node.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1) {\n add(c);\n }\n }\n });\n }\n\n attribute(name: string): (string | null)[] {\n return this.forEachNonNull((node) => {\n if (node.nodeType == 1) {\n return (node as Element).getAttribute(name);\n }\n return null;\n });\n }\n\n textContent(): (string | null)[] {\n return this.forEach((node) => node.textContent);\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Ops - Render EPUB content files by applying page masters,\n * styling and layout.\n */\nimport \"./footnotes\";\nimport \"./table\";\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Break from \"./break\";\nimport * as Columns from \"./columns\";\nimport * as Constants from \"./constants\";\nimport * as Counters from \"./counters\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssStyler from \"./css-styler\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Layout from \"./layout\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as PageFloats from \"./page-floats\";\nimport * as CssPage from \"./css-page\";\nimport * as Plugin from \"./plugin\";\nimport * as PageMaster from \"./page-master\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport * as XmlDoc from \"./xml-doc\";\nimport { Layout as LayoutType } from \"./types\";\nimport UserAgentBaseCss from \"./assets/user-agent-base.css\";\nimport UserAgentPageCss from \"./assets/user-agent-page.css\";\n\nexport const uaStylesheetBaseFetcher: TaskUtil.Fetcher<boolean> = new TaskUtil.Fetcher(\n () => {\n const frame: Task.Frame<boolean> = Task.newFrame(\"uaStylesheetBase\");\n const validatorSet = CssValidator.baseValidatorSet();\n const url = Base.resolveURL(\"user-agent-base.css\", Base.resourceBaseURL);\n const handler = new CssCascade.CascadeParserHandler(\n null,\n null,\n null,\n null,\n null,\n validatorSet,\n true,\n );\n handler.startStylesheet(CssParser.StylesheetFlavor.USER_AGENT);\n CssCascade.setUABaseCascade(handler.cascade);\n CssParser.parseStylesheetFromText(\n UserAgentBaseCss,\n handler,\n url,\n null,\n null,\n ).thenFinish(frame);\n return frame.result();\n },\n \"uaStylesheetBaseFetcher\",\n);\n\nexport function loadUABase(): Task.Result<boolean> {\n return uaStylesheetBaseFetcher.get();\n}\n\nexport type FontFace = {\n properties: CssCascade.ElementStyle;\n condition: Exprs.Val;\n};\n\nexport class Style {\n fontDeobfuscator:\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null;\n validatorSet: CssValidator.ValidatorSet;\n\n constructor(\n public readonly store: OPSDocStore,\n public readonly rootScope: Exprs.LexicalScope,\n public readonly pageScope: Exprs.LexicalScope,\n public readonly cascade: CssCascade.Cascade,\n public readonly rootBox: PageMaster.RootPageBox,\n public readonly fontFaces: FontFace[],\n public readonly footnoteProps: CssCascade.ElementStyle,\n public readonly flowProps: { [key: string]: CssCascade.ElementStyle },\n public readonly viewportProps: CssCascade.ElementStyle[],\n public readonly pageProps: { [key: string]: CssCascade.ElementStyle },\n ) {\n this.fontDeobfuscator = store.fontDeobfuscator;\n this.validatorSet = store.validatorSet;\n this.pageScope.defineBuiltIn(\"has-content\", function(name) {\n name = name as string;\n const styleInstance = this as StyleInstance;\n const cp = styleInstance.currentLayoutPosition;\n const flowChunk = cp.firstFlowChunkOfFlow(name);\n return (\n styleInstance.matchPageSide(cp.startSideOfFlow(name as string)) &&\n cp.hasContent(name as string, styleInstance.lookupOffset) &&\n !!flowChunk &&\n !styleInstance.flowChunkIsAfterParentFlowForcedBreak(flowChunk)\n );\n });\n this.pageScope.defineName(\n \"page-number\",\n new Exprs.Native(\n this.pageScope,\n function() {\n const styleInstance = this as StyleInstance;\n return (\n styleInstance.pageNumberOffset +\n styleInstance.currentLayoutPosition.page\n );\n },\n \"page-number\",\n ),\n );\n }\n\n sizeViewport(\n viewportWidth: number,\n viewportHeight: number,\n fontSize: number,\n pref?: Exprs.Preferences,\n ): { width: number; height: number; fontSize: number } {\n if (this.viewportProps.length) {\n const context = new Exprs.Context(\n this.rootScope,\n viewportWidth,\n viewportHeight,\n fontSize,\n );\n const viewportProps = CssCascade.mergeAll(context, this.viewportProps);\n const width = viewportProps[\"width\"];\n const height = viewportProps[\"height\"];\n const textZoom = viewportProps[\"text-zoom\"];\n let scaleFactor = 1;\n if ((width && height) || textZoom) {\n const defaultFontSize = Exprs.defaultUnitSizes[\"em\"];\n const zoomVal = textZoom\n ? textZoom.evaluate(context, \"text-zoom\")\n : null;\n if (zoomVal === Css.ident.scale) {\n scaleFactor = defaultFontSize / fontSize;\n fontSize = defaultFontSize;\n viewportWidth *= scaleFactor;\n viewportHeight *= scaleFactor;\n }\n if (width && height) {\n const widthVal = Css.toNumber(\n width.evaluate(context, \"width\"),\n context,\n );\n const heightVal = Css.toNumber(\n height.evaluate(context, \"height\"),\n context,\n );\n if (widthVal > 0 && heightVal > 0) {\n const spreadWidth =\n pref && pref.spreadView\n ? (widthVal + pref.pageBorder) * 2\n : widthVal;\n return { width: spreadWidth, height: heightVal, fontSize };\n }\n }\n }\n }\n return { width: viewportWidth, height: viewportHeight, fontSize };\n }\n}\n\n//-------------------------------------------------------------------------------\nexport class StyleInstance extends Exprs.Context\n implements\n CssStyler.FlowListener,\n PageMaster.InstanceHolder,\n Vgen.StylerProducer {\n lang: string | null;\n primaryFlows = { body: true } as { [key: string]: boolean };\n rootPageBoxInstance: PageMaster.RootPageBoxInstance = null;\n styler: CssStyler.Styler = null;\n stylerMap: { [key: string]: CssStyler.Styler } = null;\n currentLayoutPosition: Vtree.LayoutPosition = null;\n layoutPositionAtPageStart: Vtree.LayoutPosition = null;\n lookupOffset: number = 0;\n faces: Font.DocumentFaces;\n pageBoxInstances: { [key: string]: PageMaster.PageBoxInstance } = {};\n pageManager: CssPage.PageManager = null;\n private rootPageFloatLayoutContext: PageFloats.PageFloatLayoutContext;\n pageBreaks: { [key: string]: boolean } = {};\n pageProgression: Constants.PageProgression | null = null;\n pageSheetSize: { [key: string]: { width: number; height: number } } = {};\n pageSheetHeight: number = 0;\n pageSheetWidth: number = 0;\n actualPageWidth: number;\n actualPageHeight: number;\n\n constructor(\n public readonly style: Style,\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n defaultLang: string | null,\n public readonly viewport: Vgen.Viewport,\n public readonly clientLayout: Vtree.ClientLayout,\n public readonly fontMapper: Font.Mapper,\n public readonly customRenderer: Vgen.CustomRenderer,\n public readonly fallbackMap: { [key: string]: string },\n public readonly pageNumberOffset: number,\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n public readonly counterStore: Counters.CounterStore,\n pageProgression?: Constants.PageProgression,\n ) {\n super(style.rootScope, viewport.width, viewport.height, viewport.fontSize);\n this.lang = xmldoc.lang || defaultLang;\n this.faces = new Font.DocumentFaces(this.style.fontDeobfuscator);\n this.rootPageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n null,\n null,\n null,\n null,\n null,\n null,\n null,\n );\n this.pageProgression = pageProgression || null;\n for (const flowName in style.flowProps) {\n const flowStyle = style.flowProps[flowName];\n const consume = CssCascade.getProp(flowStyle, \"flow-consume\");\n if (consume) {\n const consumeVal = consume.evaluate(this, \"flow-consume\");\n if (consumeVal == Css.ident.all) {\n this.primaryFlows[flowName] = true;\n } else {\n delete this.primaryFlows[flowName];\n }\n }\n }\n }\n\n init(): Task.Result<boolean> {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"StyleInstance.init\");\n const counterListener = self.counterStore.createCounterListener(\n self.xmldoc.url,\n );\n const counterResolver = self.counterStore.createCounterResolver(\n self.xmldoc.url,\n self.style.rootScope,\n self.style.pageScope,\n );\n self.styler = new CssStyler.Styler(\n self.xmldoc,\n self.style.cascade,\n self.style.rootScope,\n self,\n this.primaryFlows,\n self.style.validatorSet,\n counterListener,\n counterResolver,\n );\n counterResolver.setStyler(self.styler);\n self.styler.resetFlowChunkStream(self);\n self.stylerMap = {};\n self.stylerMap[self.xmldoc.url] = self.styler;\n const docElementStyle = self.styler.getTopContainerStyle();\n if (!self.pageProgression) {\n self.pageProgression = CssPage.resolvePageProgression(docElementStyle);\n }\n const rootBox = this.style.rootBox;\n this.rootPageBoxInstance = new PageMaster.RootPageBoxInstance(rootBox);\n const cascadeInstance = this.style.cascade.createInstance(\n self,\n counterListener,\n counterResolver,\n this.lang,\n );\n this.rootPageBoxInstance.applyCascadeAndInit(\n cascadeInstance,\n docElementStyle,\n );\n this.rootPageBoxInstance.resolveAutoSizing(self);\n this.pageManager = new CssPage.PageManager(\n cascadeInstance,\n this.style.pageScope,\n this.rootPageBoxInstance,\n self,\n docElementStyle,\n );\n const srcFaces = [] as Font.Face[];\n for (const fontFace of self.style.fontFaces) {\n if (fontFace.condition && !fontFace.condition.evaluate(self)) {\n continue;\n }\n const properties = Font.prepareProperties(fontFace.properties, self);\n const srcFace = new Font.Face(properties);\n srcFaces.push(srcFace);\n }\n self.fontMapper.findOrLoadFonts(srcFaces, self.faces).thenFinish(frame);\n\n // Determine page sheet sizes corresponding to page selectors\n const pageProps = self.style.pageProps;\n Object.keys(pageProps).forEach((selector) => {\n const pageSizeAndBleed = CssPage.evaluatePageSizeAndBleed(\n CssPage.resolvePageSizeAndBleed(pageProps[selector] as any),\n this,\n );\n this.pageSheetSize[selector] = {\n width: pageSizeAndBleed.pageWidth + pageSizeAndBleed.cropOffset * 2,\n height: pageSizeAndBleed.pageHeight + pageSizeAndBleed.cropOffset * 2,\n };\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n getStylerForDoc(xmldoc: XmlDoc.XMLDocHolder): CssStyler.AbstractStyler {\n let styler = this.stylerMap[xmldoc.url];\n if (!styler) {\n const style = this.style.store.getStyleForDoc(xmldoc);\n\n // We need a separate content, so that variables can get potentially\n // different values.\n const context = new Exprs.Context(\n style.rootScope,\n this.pageWidth(),\n this.pageHeight(),\n this.initialFontSize,\n );\n const counterListener = this.counterStore.createCounterListener(\n xmldoc.url,\n );\n const counterResolver = this.counterStore.createCounterResolver(\n xmldoc.url,\n style.rootScope,\n style.pageScope,\n );\n styler = new CssStyler.Styler(\n xmldoc,\n style.cascade,\n style.rootScope,\n context,\n this.primaryFlows,\n style.validatorSet,\n counterListener,\n counterResolver,\n );\n this.stylerMap[xmldoc.url] = styler;\n }\n return styler;\n }\n\n /**\n * @override\n */\n registerInstance(key: string, instance: PageMaster.PageBoxInstance): void {\n this.pageBoxInstances[key] = instance;\n }\n\n /**\n * @override\n */\n lookupInstance(key: string): PageMaster.PageBoxInstance {\n return this.pageBoxInstances[key];\n }\n\n /**\n * @override\n */\n encounteredFlowChunk(flowChunk: Vtree.FlowChunk, flow: Vtree.Flow): any {\n const cp = this.currentLayoutPosition;\n if (cp) {\n if (!cp.flows[flowChunk.flowName]) {\n cp.flows[flowChunk.flowName] = flow;\n } else {\n flow = cp.flows[flowChunk.flowName];\n }\n let flowPosition = cp.flowPositions[flowChunk.flowName];\n if (!flowPosition) {\n flowPosition = new Vtree.FlowPosition();\n cp.flowPositions[flowChunk.flowName] = flowPosition;\n }\n const nodePosition = Vtree.newNodePositionFromNode(flowChunk.element);\n const chunkPosition = new Vtree.ChunkPosition(nodePosition);\n const flowChunkPosition = new Vtree.FlowChunkPosition(\n chunkPosition,\n flowChunk,\n );\n flowPosition.positions.push(flowChunkPosition);\n }\n }\n\n getConsumedOffset(flowPosition: Vtree.FlowPosition): number {\n let offset = Number.POSITIVE_INFINITY;\n for (let i = 0; i < flowPosition.positions.length; i++) {\n const pos = flowPosition.positions[i].chunkPosition.primary;\n let node = pos.steps[0].node;\n let offsetInNode = pos.offsetInNode;\n let after = pos.after;\n let k = 0;\n while (node.ownerDocument != this.xmldoc.document) {\n k++;\n node = pos.steps[k].node;\n after = false;\n offsetInNode = 0;\n }\n const chunkOffset = this.xmldoc.getNodeOffset(node, offsetInNode, after);\n if (chunkOffset < offset) {\n offset = chunkOffset;\n }\n }\n return offset;\n }\n\n /**\n * @param noLookAhead Do not look ahead elements that are not styled yet\n * @return document offset of the given layoutPosition\n */\n getPosition(\n layoutPosition?: Vtree.LayoutPosition,\n noLookAhead?: boolean,\n ): number {\n if (!layoutPosition) {\n return 0;\n }\n let currentPosition = Number.POSITIVE_INFINITY;\n for (const flowName in this.primaryFlows) {\n let flowPosition = layoutPosition.flowPositions[flowName];\n if (\n !noLookAhead &&\n (!flowPosition || flowPosition.positions.length == 0) &&\n this.currentLayoutPosition\n ) {\n this.styler.styleUntilFlowIsReached(flowName);\n flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n if (layoutPosition != this.currentLayoutPosition) {\n if (flowPosition) {\n flowPosition = flowPosition.clone();\n layoutPosition.flowPositions[flowName] = flowPosition;\n }\n }\n }\n if (flowPosition) {\n const consumedOffset = this.getConsumedOffset(flowPosition);\n if (consumedOffset < currentPosition) {\n currentPosition = consumedOffset;\n }\n }\n }\n return currentPosition;\n }\n\n dumpLocation(position) {\n Logging.logger.debug(\"Location - page\", this.currentLayoutPosition.page);\n Logging.logger.debug(\" current:\", position);\n Logging.logger.debug(\" lookup:\", this.lookupOffset);\n for (const flowName in this.currentLayoutPosition.flowPositions) {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n for (const p of flowPosition.positions) {\n Logging.logger.debug(\n \" Chunk\",\n `${flowName}:`,\n p.flowChunk.startOffset,\n );\n }\n }\n }\n\n matchPageSide(side: string): boolean {\n switch (side) {\n case \"left\":\n case \"right\":\n case \"recto\":\n case \"verso\":\n return new Exprs.Named(this.style.pageScope, `${side}-page`).evaluate(\n this,\n ) as boolean;\n default:\n return true;\n }\n }\n\n updateStartSide(layoutPosition: Vtree.LayoutPosition) {\n for (const name in layoutPosition.flowPositions) {\n const flowPos = layoutPosition.flowPositions[name];\n if (flowPos && flowPos.positions.length > 0) {\n const flowChunk = flowPos.positions[0].flowChunk;\n if (this.getConsumedOffset(flowPos) === flowChunk.startOffset) {\n const flowChunkBreakBefore =\n flowPos.positions[0].flowChunk.breakBefore;\n const flowBreakAfter = Break.startSideValueToBreakValue(\n flowPos.startSide,\n );\n flowPos.startSide = Break.breakValueToStartSideValue(\n Break.resolveEffectiveBreakValue(\n flowBreakAfter,\n flowChunkBreakBefore,\n ),\n );\n }\n }\n }\n }\n\n /**\n * @param cascadedPageStyle Cascaded page style specified in page context\n */\n selectPageMaster(\n cascadedPageStyle: CssCascade.ElementStyle,\n ): PageMaster.PageMasterInstance {\n const self = this;\n const cp = this.currentLayoutPosition;\n\n // 3.5. Page Layout Processing Model\n // 1. Determine current position in the document: Find the minimal\n // consumed-offset for all elements not fully-consumed in each primary flow.\n // Current position is maximum of the results among all primary flows.\n const currentPosition = this.getPosition(cp);\n if (currentPosition == Number.POSITIVE_INFINITY) {\n // end of primary content is reached\n return null;\n }\n\n // 2. Page master selection: for each page master:\n const pageMasters = this.rootPageBoxInstance\n .children as PageMaster.PageMasterInstance[];\n let pageMaster: PageMaster.PageMasterInstance;\n for (let i = 0; i < pageMasters.length; i++) {\n pageMaster = pageMasters[i];\n\n // Skip a page master generated for @page rules\n if (pageMaster.pageBox.pseudoName === CssPage.pageRuleMasterPseudoName) {\n continue;\n }\n let coeff = 1;\n\n // A. Calculate lookup position using current position and utilization\n // (see -epubx-utilization property)\n const utilization = pageMaster.getProp(self, \"utilization\");\n if (utilization && utilization.isNum()) {\n coeff = (utilization as Css.Num).num;\n }\n const em = self.queryUnitSize(\"em\", false);\n const pageArea = self.pageWidth() * self.pageHeight();\n const lookup = Math.ceil((coeff * pageArea) / (em * em));\n\n // B. Determine element eligibility. Each element in a flow is considered\n // eligible if it is is not marked as fully consumed and it comes in the\n // document before the lookup position. Feed lookupOffset and flow\n // availability into the context\n this.lookupOffset = this.styler.styleUntil(currentPosition, lookup);\n Asserts.assert(cp);\n this.updateStartSide(cp);\n\n // update layoutPositionAtPageStart since startSide of FlowChunks may be\n // updated\n this.layoutPositionAtPageStart = cp.clone();\n this.initLingering();\n self.clearScope(this.style.pageScope);\n\n // C. Determine content availability. Flow has content available if it\n // contains eligible elements. D. Determine if page master is enabled\n // using rules in Section 3.4.7\n const enabled = pageMaster.getProp(self, \"enabled\");\n\n // E. First enabled page master is used for the next page\n if (!enabled || enabled === Css.ident._true) {\n if (VIVLIOSTYLE_DEBUG) {\n this.dumpLocation(currentPosition);\n }\n\n // Apply @page rules\n return this.pageManager.getPageRulePageMaster(\n pageMaster,\n cascadedPageStyle,\n );\n }\n }\n throw new Error(\"No enabled page masters\");\n }\n\n flowChunkIsAfterParentFlowForcedBreak(flowChunk: Vtree.FlowChunk): boolean {\n const flows = this.layoutPositionAtPageStart.flows;\n const parentFlowName = flows[flowChunk.flowName].parentFlowName;\n if (parentFlowName) {\n const startOffset = flowChunk.startOffset;\n const forcedBreakOffsets = flows[parentFlowName].forcedBreakOffsets;\n if (!forcedBreakOffsets.length || startOffset < forcedBreakOffsets[0]) {\n return false;\n }\n const breakOffsetBeforeStartIndex =\n Base.binarySearch(\n forcedBreakOffsets.length,\n (i) => forcedBreakOffsets[i] > startOffset,\n ) - 1;\n const breakOffsetBeforeStart =\n forcedBreakOffsets[breakOffsetBeforeStartIndex];\n const parentFlowPosition = this.layoutPositionAtPageStart.flowPositions[\n parentFlowName\n ];\n const parentStartOffset = this.getConsumedOffset(parentFlowPosition);\n if (breakOffsetBeforeStart < parentStartOffset) {\n return false;\n }\n if (parentStartOffset < breakOffsetBeforeStart) {\n return true;\n }\n\n // Special case: parentStartOffset === breakOffsetBeforeStart\n // In this case, the flowChunk can be used if the start side of the parent\n // flow matches the current page side.\n return !this.matchPageSide(parentFlowPosition.startSide);\n }\n return false;\n }\n\n setFormattingContextToColumn(column: LayoutType.Column, flowName: string) {\n const flow = this.currentLayoutPosition.flows[flowName];\n if (!flow.formattingContext) {\n flow.formattingContext = new LayoutProcessor.BlockFormattingContext(null);\n }\n column.flowRootFormattingContext = flow.formattingContext;\n }\n\n layoutDeferredPageFloats(column: LayoutType.Column): Task.Result<boolean> {\n const pageFloatLayoutContext = column.pageFloatLayoutContext;\n const deferredFloats = pageFloatLayoutContext.getDeferredPageFloatContinuations();\n const frame = Task.newFrame<boolean>(\"layoutDeferredPageFloats\");\n let invalidated = false;\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i === deferredFloats.length) {\n loopFrame.breakLoop();\n return;\n }\n const continuation = deferredFloats[i++];\n const float = continuation.float;\n const strategy = new PageFloats.PageFloatLayoutStrategyResolver().findByFloat(\n float,\n );\n const pageFloatFragment = strategy.findPageFloatFragment(\n float,\n pageFloatLayoutContext,\n );\n if (pageFloatFragment && pageFloatFragment.hasFloat(float)) {\n loopFrame.continueLoop();\n return;\n } else if (\n pageFloatLayoutContext.isForbidden(float) ||\n pageFloatLayoutContext.hasPrecedingFloatsDeferredToNext(float)\n ) {\n pageFloatLayoutContext.deferPageFloat(continuation);\n loopFrame.breakLoop();\n return;\n }\n column\n .layoutPageFloatInner(continuation, strategy, null, pageFloatFragment)\n .then((success) => {\n if (!success) {\n loopFrame.breakLoop();\n return;\n }\n const parentInvalidated = pageFloatLayoutContext.parent.isInvalidated();\n if (parentInvalidated) {\n loopFrame.breakLoop();\n return;\n } else if (\n pageFloatLayoutContext.isInvalidated() &&\n !parentInvalidated\n ) {\n invalidated = true;\n pageFloatLayoutContext.validate();\n }\n loopFrame.continueLoop();\n });\n })\n .then(() => {\n if (invalidated) {\n pageFloatLayoutContext.invalidate();\n }\n frame.finish(true);\n });\n return frame.result();\n }\n\n getLastAfterPositionIfDeferredFloatsExists(\n column: LayoutType.Column,\n newPosition: Vtree.ChunkPosition | null,\n ): Vtree.ChunkPosition | null {\n const pageFloatLayoutContext = column.pageFloatLayoutContext;\n const deferredFloats = pageFloatLayoutContext.getPageFloatContinuationsDeferredToNext();\n if (deferredFloats.length > 0) {\n if (column.lastAfterPosition) {\n let result: Vtree.ChunkPosition;\n if (newPosition) {\n // Need overflown footnotes owned by newPosition\n result = newPosition.clone();\n result.primary = column.lastAfterPosition;\n } else {\n result = new Vtree.ChunkPosition(column.lastAfterPosition);\n }\n return result;\n } else {\n Asserts.assert(\"column.lastAfterPosition === null\");\n return null;\n }\n } else {\n return null;\n }\n }\n\n /**\n * @return holding true\n */\n layoutColumn(\n column: LayoutType.Column,\n flowName: string,\n ): Task.Result<boolean> {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n if (!flowPosition || !this.matchPageSide(flowPosition.startSide)) {\n return Task.newResult(true);\n }\n flowPosition.startSide = \"any\";\n this.setFormattingContextToColumn(column, flowName);\n column.init();\n if (this.primaryFlows[flowName] && column.bands.length > 0) {\n // In general, we force non-fitting content. Exception is only for primary\n // flow columns that have exclusions.\n column.forceNonfitting = false;\n }\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"layoutColumn\");\n this.layoutDeferredPageFloats(column).then(() => {\n if (column.pageFloatLayoutContext.isInvalidated()) {\n frame.finish(true);\n return;\n }\n\n // Record indices of repeated positions and removed positions\n const repeatedIndices = [] as number[];\n const removedIndices = [] as number[];\n let leadingEdge = true;\n frame\n .loopWithFrame((loopFrame) => {\n if (\n column.pageFloatLayoutContext.hasContinuingFloatFragmentsInFlow(\n flowName,\n )\n ) {\n loopFrame.breakLoop();\n return;\n }\n while (flowPosition.positions.length - removedIndices.length > 0) {\n let index = 0;\n\n // Skip all removed positions\n while (removedIndices.includes(index)) {\n index++;\n }\n let selected = flowPosition.positions[index];\n if (\n selected.flowChunk.startOffset > self.lookupOffset ||\n self.flowChunkIsAfterParentFlowForcedBreak(selected.flowChunk)\n ) {\n break;\n }\n for (let k = index + 1; k < flowPosition.positions.length; k++) {\n if (removedIndices.includes(k)) {\n continue; // Skip removed positions\n }\n const alt = flowPosition.positions[k];\n if (\n alt.flowChunk.startOffset > self.lookupOffset ||\n self.flowChunkIsAfterParentFlowForcedBreak(alt.flowChunk)\n ) {\n break;\n }\n if (alt.flowChunk.isBetter(selected.flowChunk)) {\n selected = alt;\n index = k;\n }\n }\n const flowChunk = selected.flowChunk;\n let pending = true;\n column\n .layout(\n selected.chunkPosition,\n leadingEdge,\n flowPosition.breakAfter,\n )\n .then((newPosition) => {\n if (column.pageFloatLayoutContext.isInvalidated()) {\n loopFrame.breakLoop();\n return;\n }\n leadingEdge = false;\n\n // static: keep in the flow\n if (\n selected.flowChunk.repeated &&\n (newPosition === null || flowChunk.exclusive)\n ) {\n repeatedIndices.push(index);\n }\n if (flowChunk.exclusive) {\n // exclusive, only can have one, remove from the flow even\n // if it did not fit\n removedIndices.push(index);\n loopFrame.breakLoop();\n return;\n } else {\n // not exclusive\n const endOfColumn = !!newPosition || !!column.pageBreakType;\n const lastAfterPosition = self.getLastAfterPositionIfDeferredFloatsExists(\n column,\n newPosition,\n );\n if (column.pageBreakType && lastAfterPosition) {\n selected.chunkPosition = lastAfterPosition;\n\n // TODO propagate pageBreakType\n flowPosition.breakAfter = column.pageBreakType;\n column.pageBreakType = null;\n } else {\n // go to the next element in the flow\n removedIndices.push(index);\n if (newPosition || lastAfterPosition) {\n // did not fit completely\n selected.chunkPosition = newPosition || lastAfterPosition;\n repeatedIndices.push(index);\n }\n if (column.pageBreakType) {\n // forced break\n flowPosition.startSide = Break.breakValueToStartSideValue(\n column.pageBreakType,\n );\n }\n }\n if (endOfColumn) {\n loopFrame.breakLoop();\n return;\n }\n }\n\n // Since at least one flowChunk has been placed in the\n // column, the next flowChunk of the flow can be deferred to\n // the next partition if there is not enough space in the\n // current partition.\n column.forceNonfitting = false;\n if (pending) {\n // Sync result\n pending = false;\n } else {\n // Async result\n loopFrame.continueLoop();\n }\n });\n if (pending) {\n // Async result\n pending = false;\n return;\n }\n }\n\n // Sync result\n loopFrame.breakLoop();\n })\n .then(() => {\n if (!column.pageFloatLayoutContext.isInvalidated()) {\n // Keep positions repeated or not removed\n flowPosition.positions = flowPosition.positions.filter(\n (pos, i) =>\n repeatedIndices.includes(i) || !removedIndices.includes(i),\n );\n if (flowPosition.breakAfter === \"column\") {\n flowPosition.breakAfter = null;\n }\n column.saveDistanceToBlockEndFloats();\n const edge = column.pageFloatLayoutContext.getMaxReachedAfterEdge();\n column.updateMaxReachedAfterEdge(edge);\n }\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n createLayoutConstraint(\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ): LayoutType.LayoutConstraint {\n const pageIndex = this.currentLayoutPosition.page - 1;\n const counterConstraint = this.counterStore.createLayoutConstraint(\n pageIndex,\n );\n return new Layout.AllLayoutConstraint(\n [counterConstraint].concat(pageFloatLayoutContext.getLayoutConstraints()),\n );\n }\n\n private createAndLayoutColumn(\n boxInstance: PageMaster.PageBoxInstance,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n layoutContainer: Vtree.Container,\n currentColumnIndex: number,\n flowNameStr: string,\n regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n columnCount: number,\n columnGap: number,\n columnWidth: number,\n innerShape: GeometryUtil.Shape,\n layoutContext: Vtree.LayoutContext,\n forceNonFitting: boolean,\n ): Task.Result<LayoutType.Column> {\n const self = this;\n const dontApplyExclusions = boxInstance.vertical\n ? boxInstance.isAutoWidth && boxInstance.isRightDependentOnAutoWidth\n : boxInstance.isAutoHeight && boxInstance.isTopDependentOnAutoHeight;\n const boxContainer = layoutContainer.element;\n const columnPageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n regionPageFloatLayoutContext,\n PageFloats.FloatReference.COLUMN,\n null,\n flowNameStr,\n null,\n null,\n null,\n );\n const positionAtColumnStart = self.currentLayoutPosition.clone();\n const frame: Task.Frame<LayoutType.Column> = Task.newFrame(\n \"createAndLayoutColumn\",\n );\n let column: LayoutType.Column;\n frame\n .loopWithFrame((loopFrame) => {\n const layoutConstraint = self.createLayoutConstraint(\n columnPageFloatLayoutContext,\n );\n if (columnCount > 1) {\n const columnContainer = self.viewport.document.createElement(\"div\");\n Base.setCSSProperty(columnContainer, \"position\", \"absolute\");\n boxContainer.appendChild(columnContainer);\n column = new Layout.Column(\n columnContainer,\n layoutContext,\n self.clientLayout,\n layoutConstraint,\n columnPageFloatLayoutContext,\n );\n column.forceNonfitting = forceNonFitting;\n column.vertical = layoutContainer.vertical;\n column.snapHeight = layoutContainer.snapHeight;\n column.snapWidth = layoutContainer.snapWidth;\n if (layoutContainer.vertical) {\n const columnY =\n currentColumnIndex * (columnWidth + columnGap) +\n layoutContainer.paddingTop;\n column.setHorizontalPosition(\n layoutContainer.paddingLeft,\n layoutContainer.width,\n );\n column.setVerticalPosition(columnY, columnWidth);\n } else {\n const columnX =\n currentColumnIndex * (columnWidth + columnGap) +\n layoutContainer.paddingLeft;\n column.setVerticalPosition(\n layoutContainer.paddingTop,\n layoutContainer.height,\n );\n column.setHorizontalPosition(columnX, columnWidth);\n }\n column.originX = offsetX;\n column.originY = offsetY;\n } else {\n column = new Layout.Column(\n boxContainer,\n layoutContext,\n self.clientLayout,\n layoutConstraint,\n columnPageFloatLayoutContext,\n );\n column.copyFrom(layoutContainer);\n }\n column.exclusions = dontApplyExclusions ? [] : exclusions.concat();\n column.innerShape = innerShape;\n columnPageFloatLayoutContext.setContainer(column);\n if (column.width >= 0) {\n // column.element.style.outline = \"1px dotted green\";\n self.layoutColumn(column, flowNameStr).then(() => {\n if (!columnPageFloatLayoutContext.isInvalidated()) {\n columnPageFloatLayoutContext.finish();\n }\n if (\n column.pageFloatLayoutContext.isInvalidated() &&\n !regionPageFloatLayoutContext.isInvalidated()\n ) {\n column.pageFloatLayoutContext.validate();\n self.currentLayoutPosition = positionAtColumnStart.clone();\n if (column.element !== boxContainer) {\n boxContainer.removeChild(column.element);\n }\n loopFrame.continueLoop();\n } else {\n loopFrame.breakLoop();\n }\n });\n } else {\n columnPageFloatLayoutContext.finish();\n loopFrame.breakLoop();\n }\n })\n .then(() => {\n frame.finish(column);\n });\n return frame.result();\n }\n\n setPagePageFloatLayoutContextContainer(\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n boxInstance: PageMaster.PageBoxInstance,\n layoutContainer: Vtree.Container,\n ) {\n if (\n boxInstance instanceof CssPage.PageRulePartitionInstance ||\n (boxInstance instanceof PageMaster.PageMasterInstance &&\n !(boxInstance instanceof CssPage.PageRuleMasterInstance))\n ) {\n pagePageFloatLayoutContext.setContainer(layoutContainer);\n }\n }\n\n getRegionPageFloatLayoutContext(\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n boxInstance: PageMaster.PageBoxInstance,\n layoutContainer: Vtree.Container,\n flowName: string,\n ): PageFloats.PageFloatLayoutContext {\n Asserts.assert(boxInstance instanceof PageMaster.PartitionInstance);\n const writingMode = boxInstance.getProp(this, \"writing-mode\") || null;\n const direction = boxInstance.getProp(this, \"direction\") || null;\n return new PageFloats.PageFloatLayoutContext(\n pagePageFloatLayoutContext,\n PageFloats.FloatReference.REGION,\n layoutContainer,\n flowName,\n null,\n writingMode,\n direction,\n );\n }\n\n layoutFlowColumnsWithBalancing(\n page: Vtree.Page,\n boxInstance: PageMaster.PageBoxInstance,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n flowNameStr: string,\n columnCount: number,\n ): Task.Result<LayoutType.Column[]> {\n const self = this;\n const positionAtContainerStart = self.currentLayoutPosition.clone();\n const regionPageFloatLayoutContext = self.getRegionPageFloatLayoutContext(\n pagePageFloatLayoutContext,\n boxInstance,\n layoutContainer,\n flowNameStr,\n );\n let isFirstTime = true;\n\n function layoutColumns() {\n self.currentLayoutPosition = positionAtContainerStart.clone();\n return self\n .layoutFlowColumns(\n page,\n boxInstance,\n offsetX,\n offsetY,\n exclusions,\n pagePageFloatLayoutContext,\n regionPageFloatLayoutContext,\n layoutContainer,\n flowNameStr,\n columnCount,\n isFirstTime,\n )\n .thenAsync((columns) => {\n if (columns) {\n return Task.newResult({\n columns,\n position: self.currentLayoutPosition,\n });\n } else {\n return Task.newResult(null);\n }\n });\n }\n return layoutColumns().thenAsync((generatorResult) => {\n if (!generatorResult) {\n return Task.newResult(null);\n }\n if (columnCount <= 1) {\n return Task.newResult(generatorResult.columns);\n }\n const columnFill =\n (boxInstance.getProp(self, \"column-fill\") as Css.Ident) ||\n Css.ident.balance;\n const flowPosition =\n self.currentLayoutPosition.flowPositions[flowNameStr];\n Asserts.assert(flowPosition);\n const columnBalancer = Columns.createColumnBalancer(\n columnCount,\n columnFill,\n layoutColumns,\n regionPageFloatLayoutContext,\n layoutContainer,\n generatorResult.columns,\n flowPosition,\n );\n if (!columnBalancer) {\n return Task.newResult(generatorResult.columns);\n }\n isFirstTime = false;\n pagePageFloatLayoutContext.lock();\n regionPageFloatLayoutContext.lock();\n return columnBalancer\n .balanceColumns(generatorResult)\n .thenAsync((result) => {\n pagePageFloatLayoutContext.unlock();\n pagePageFloatLayoutContext.validate();\n regionPageFloatLayoutContext.unlock();\n self.currentLayoutPosition = result.position;\n return Task.newResult(result.columns);\n });\n });\n }\n\n layoutFlowColumns(\n page: Vtree.Page,\n boxInstance: PageMaster.PageBoxInstance,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n flowNameStr: string,\n columnCount: number,\n forceNonFitting: boolean,\n ): Task.Result<LayoutType.Column[] | null> {\n const self = this;\n const frame: Task.Frame<LayoutType.Column[] | null> = Task.newFrame(\n \"layoutFlowColumns\",\n );\n const positionAtContainerStart = self.currentLayoutPosition.clone();\n const columnGap = boxInstance.getPropAsNumber(self, \"column-gap\");\n\n // Don't query columnWidth when it's not needed, so that width calculation\n // can be delayed for width: auto columns.\n const columnWidth =\n columnCount > 1\n ? boxInstance.getPropAsNumber(self, \"column-width\")\n : layoutContainer.width;\n const regionIds = boxInstance.getActiveRegions(self);\n const innerShapeVal = boxInstance.getProp(self, \"shape-inside\");\n const innerShape = CssProp.toShape(\n innerShapeVal,\n 0,\n 0,\n layoutContainer.width,\n layoutContainer.height,\n self,\n );\n const layoutContext = new Vgen.ViewFactory(\n flowNameStr,\n self,\n self.viewport,\n self.styler,\n regionIds,\n self.xmldoc,\n self.faces,\n self.style.footnoteProps,\n self,\n page,\n self.customRenderer,\n self.fallbackMap,\n this.documentURLTransformer,\n );\n let columnIndex = 0;\n let column: LayoutType.Column = null;\n let columns: LayoutType.Column[] = [];\n frame\n .loopWithFrame((loopFrame) => {\n self\n .createAndLayoutColumn(\n boxInstance,\n offsetX,\n offsetY,\n exclusions,\n layoutContainer,\n columnIndex++,\n flowNameStr,\n regionPageFloatLayoutContext,\n columnCount,\n columnGap,\n columnWidth,\n innerShape,\n layoutContext,\n forceNonFitting,\n )\n .then((c) => {\n if (pagePageFloatLayoutContext.isInvalidated()) {\n columns = null;\n loopFrame.breakLoop();\n return;\n }\n const forcedRegionBreak =\n !!c.pageBreakType && c.pageBreakType !== \"column\";\n if (\n (forcedRegionBreak || columnIndex === columnCount) &&\n !regionPageFloatLayoutContext.isInvalidated()\n ) {\n regionPageFloatLayoutContext.finish();\n }\n if (regionPageFloatLayoutContext.isInvalidated()) {\n columnIndex = 0;\n self.currentLayoutPosition = positionAtContainerStart.clone();\n regionPageFloatLayoutContext.validate();\n if (regionPageFloatLayoutContext.isLocked()) {\n columns = null;\n loopFrame.breakLoop();\n } else {\n loopFrame.continueLoop();\n }\n return;\n }\n column = c;\n columns[columnIndex - 1] = column;\n if (column.pageBreakType) {\n if (column.pageBreakType != \"column\") {\n // skip remaining columns\n columnIndex = columnCount;\n if (column.pageBreakType != \"region\") {\n // skip remaining regions\n self.pageBreaks[flowNameStr] = true;\n }\n }\n }\n if (columnIndex < columnCount) {\n loopFrame.continueLoop();\n } else {\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n frame.finish(columns);\n });\n return frame.result();\n }\n\n /**\n * @return holding true\n */\n layoutContainer(\n page: Vtree.Page,\n boxInstance: PageMaster.PageBoxInstance,\n parentContainer: HTMLElement,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ): Task.Result<boolean> {\n const self = this;\n boxInstance.reset();\n const enabled = boxInstance.getProp(self, \"enabled\");\n if (enabled && enabled !== Css.ident._true) {\n return Task.newResult(true);\n }\n const frame: Task.Frame<boolean> = Task.newFrame(\"layoutContainer\");\n const wrapFlow = boxInstance.getProp(self, \"wrap-flow\");\n const dontExclude = wrapFlow === Css.ident.auto;\n const flowName = boxInstance.getProp(self, \"flow-from\");\n const boxContainer = self.viewport.document.createElement(\"div\");\n const position = boxInstance.getProp(self, \"position\");\n Base.setCSSProperty(\n boxContainer,\n \"position\",\n position ? (position as any).name : \"absolute\",\n );\n parentContainer.insertBefore(boxContainer, parentContainer.firstChild);\n let layoutContainer = new Vtree.Container(boxContainer);\n layoutContainer.vertical = boxInstance.vertical;\n layoutContainer.exclusions = exclusions;\n boxInstance.prepareContainer(\n self,\n layoutContainer,\n page,\n self.faces,\n self.clientLayout,\n );\n layoutContainer.originX = offsetX;\n layoutContainer.originY = offsetY;\n offsetX +=\n layoutContainer.left +\n layoutContainer.marginLeft +\n layoutContainer.borderLeft;\n offsetY +=\n layoutContainer.top +\n layoutContainer.marginTop +\n layoutContainer.borderTop;\n this.setPagePageFloatLayoutContextContainer(\n pagePageFloatLayoutContext,\n boxInstance,\n layoutContainer,\n );\n let cont: Task.Result<boolean>;\n let removed = false;\n if (!flowName || !flowName.isIdent()) {\n const contentVal = boxInstance.getProp(self, \"content\");\n if (contentVal && Vtree.nonTrivialContent(contentVal)) {\n let innerContainerTag = \"span\";\n if ((contentVal as any).url) {\n innerContainerTag = \"img\";\n }\n const innerContainer = self.viewport.document.createElement(\n innerContainerTag,\n );\n contentVal.visit(\n new Vtree.ContentPropertyHandler(\n innerContainer,\n self,\n contentVal,\n self.counterStore.getExprContentListener(),\n ),\n );\n boxContainer.appendChild(innerContainer);\n if (innerContainerTag == \"img\") {\n boxInstance.transferSinglUriContentProps(\n self,\n innerContainer,\n self.faces,\n );\n }\n boxInstance.transferContentProps(\n self,\n layoutContainer,\n page,\n self.faces,\n );\n } else if (boxInstance.suppressEmptyBoxGeneration) {\n parentContainer.removeChild(boxContainer);\n removed = true;\n }\n if (!removed) {\n boxInstance.finishContainer(\n self,\n layoutContainer,\n page,\n null,\n 1,\n self.clientLayout,\n self.faces,\n );\n }\n cont = Task.newResult(true);\n } else if (!self.pageBreaks[flowName.toString()]) {\n const innerFrame: Task.Frame<boolean> = Task.newFrame(\n \"layoutContainer.inner\",\n );\n const flowNameStr = flowName.toString();\n\n // for now only a single column in vertical case\n const columnCount = boxInstance.getPropAsNumber(self, \"column-count\");\n self\n .layoutFlowColumnsWithBalancing(\n page,\n boxInstance,\n offsetX,\n offsetY,\n exclusions,\n pagePageFloatLayoutContext,\n layoutContainer,\n flowNameStr,\n columnCount,\n )\n .then((columns) => {\n if (!pagePageFloatLayoutContext.isInvalidated()) {\n const column = columns[0];\n Asserts.assert(column);\n if (column.element === boxContainer) {\n layoutContainer = column;\n }\n layoutContainer.computedBlockSize = Math.max.apply(\n null,\n columns.map((c) => c.computedBlockSize),\n );\n boxInstance.finishContainer(\n self,\n layoutContainer,\n page,\n column,\n columnCount,\n self.clientLayout,\n self.faces,\n );\n const flowPosition =\n self.currentLayoutPosition.flowPositions[flowNameStr];\n if (flowPosition && flowPosition.breakAfter === \"region\") {\n flowPosition.breakAfter = null;\n }\n }\n innerFrame.finish(true);\n });\n cont = innerFrame.result();\n } else {\n if (!pagePageFloatLayoutContext.isInvalidated()) {\n boxInstance.finishContainer(\n self,\n layoutContainer,\n page,\n null,\n 1,\n self.clientLayout,\n self.faces,\n );\n }\n cont = Task.newResult(true);\n }\n cont.then(() => {\n if (pagePageFloatLayoutContext.isInvalidated()) {\n frame.finish(true);\n return;\n }\n if (\n !boxInstance.isAutoHeight ||\n Math.floor(layoutContainer.computedBlockSize) > 0\n ) {\n if (!removed && !dontExclude) {\n const outerShapeProp = boxInstance.getProp(self, \"shape-outside\");\n const outerShape = layoutContainer.getOuterShape(\n outerShapeProp,\n self,\n );\n\n // Though it seems that LShapeFloatBug still exists in Firefox, it\n // apparently does not occur on exclusion floats. See the test file:\n // test/files/column-break-bug.html\n // if (Base.checkLShapeFloatBug(self.viewport.root)) {\n // \t// Simplistic bug workaround: add a copy of the shape translated up.\n // exclusions.push(outerShape.withOffset(0, -1.25 * self.queryUnitSize(\"em\", false)));\n // }\n exclusions.push(outerShape);\n }\n } else if (boxInstance.children.length == 0) {\n parentContainer.removeChild(boxContainer);\n frame.finish(true);\n return;\n }\n let i = boxInstance.children.length - 1;\n frame\n .loop(() => {\n while (i >= 0) {\n const child = boxInstance.children[i--];\n const r = self.layoutContainer(\n page,\n child,\n boxContainer as HTMLElement,\n offsetX,\n offsetY,\n exclusions,\n pagePageFloatLayoutContext,\n );\n if (r.isPending()) {\n return r.thenAsync(() =>\n Task.newResult(!pagePageFloatLayoutContext.isInvalidated()),\n );\n } else if (pagePageFloatLayoutContext.isInvalidated()) {\n break;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n processLinger(): void {\n const pageNumber = this.currentLayoutPosition.page;\n for (const flowName in this.currentLayoutPosition.flowPositions) {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n for (let i = flowPosition.positions.length - 1; i >= 0; i--) {\n const pos = flowPosition.positions[i];\n if (\n pos.flowChunk.startPage >= 0 &&\n pos.flowChunk.startPage + pos.flowChunk.linger - 1 <= pageNumber\n ) {\n flowPosition.positions.splice(i, 1);\n }\n }\n }\n }\n\n initLingering(): void {\n const pageNumber = this.currentLayoutPosition.page;\n for (const flowName in this.currentLayoutPosition.flowPositions) {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n for (let i = flowPosition.positions.length - 1; i >= 0; i--) {\n const pos = flowPosition.positions[i];\n if (\n pos.flowChunk.startPage < 0 &&\n pos.flowChunk.startOffset < this.lookupOffset\n ) {\n pos.flowChunk.startPage = pageNumber;\n }\n }\n }\n }\n\n noMorePrimaryFlows(cp: Vtree.LayoutPosition): boolean {\n for (const flowName in this.primaryFlows) {\n const flowPosition = cp.flowPositions[flowName];\n if (flowPosition && flowPosition.positions.length > 0) {\n return false;\n }\n }\n return true;\n }\n\n layoutNextPage(\n page: Vtree.Page,\n cp?: Vtree.LayoutPosition,\n ): Task.Result<Vtree.LayoutPosition> {\n const self = this;\n\n // TOC box is special page container, no pagination\n const isTocBox = page.container === page.bleedBox;\n\n self.pageBreaks = {};\n if (cp) {\n self.currentLayoutPosition = cp.clone();\n self.styler.replayFlowElementsFromOffset(cp.highestSeenOffset);\n } else {\n self.currentLayoutPosition = new Vtree.LayoutPosition();\n self.styler.replayFlowElementsFromOffset(-1);\n }\n if (this.lang) {\n page.bleedBox.setAttribute(\"lang\", this.lang);\n }\n cp = self.currentLayoutPosition;\n cp.page++;\n self.clearScope(self.style.pageScope);\n self.layoutPositionAtPageStart = cp.clone();\n\n // Resolve page size before page master selection.\n const cascadedPageStyle = isTocBox\n ? ({} as CssCascade.ElementStyle)\n : self.pageManager.getCascadedPageStyle();\n const pageMaster = self.selectPageMaster(cascadedPageStyle);\n if (!pageMaster) {\n // end of primary content\n return Task.newResult(null as Vtree.LayoutPosition);\n }\n let bleedBoxPaddingEdge = 0;\n if (!isTocBox) {\n page.setAutoPageWidth(\n pageMaster.pageBox.specified[\"width\"].value === Css.fullWidth,\n );\n page.setAutoPageHeight(\n pageMaster.pageBox.specified[\"height\"].value === Css.fullHeight,\n );\n self.counterStore.setCurrentPage(page);\n self.counterStore.updatePageCounters(cascadedPageStyle, self);\n\n // setup bleed area and crop marks\n const evaluatedPageSizeAndBleed = CssPage.evaluatePageSizeAndBleed(\n CssPage.resolvePageSizeAndBleed(cascadedPageStyle as any),\n this,\n );\n self.setPageSizeAndBleed(evaluatedPageSizeAndBleed, page);\n CssPage.addPrinterMarks(\n cascadedPageStyle,\n evaluatedPageSizeAndBleed,\n page,\n this,\n );\n bleedBoxPaddingEdge =\n evaluatedPageSizeAndBleed.bleedOffset + evaluatedPageSizeAndBleed.bleed;\n }\n\n const writingMode =\n (!isTocBox && pageMaster.getProp(self, \"writing-mode\")) ||\n Css.ident.horizontal_tb;\n\n this.pageVertical = writingMode != Css.ident.horizontal_tb;\n\n const direction = pageMaster.getProp(self, \"direction\") || Css.ident.ltr;\n const pageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n self.rootPageFloatLayoutContext,\n PageFloats.FloatReference.PAGE,\n null,\n null,\n null,\n writingMode,\n direction,\n );\n const frame: Task.Frame<Vtree.LayoutPosition> = Task.newFrame(\n \"layoutNextPage\",\n );\n frame\n .loopWithFrame((loopFrame) => {\n // self.layoutContainer(page, pageMaster, page.bleedBox, bleedBoxPaddingEdge, bleedBoxPaddingEdge+1, // Compensate 'top: -1px' on page master\n self\n .layoutContainer(\n page,\n pageMaster,\n page.bleedBox,\n bleedBoxPaddingEdge,\n bleedBoxPaddingEdge,\n [],\n pageFloatLayoutContext,\n )\n .then(() => {\n if (!pageFloatLayoutContext.isInvalidated()) {\n pageFloatLayoutContext.finish();\n }\n if (pageFloatLayoutContext.isInvalidated()) {\n self.currentLayoutPosition = self.layoutPositionAtPageStart.clone();\n pageFloatLayoutContext.validate();\n loopFrame.continueLoop();\n } else {\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n pageMaster.adjustPageLayout(self, page, self.clientLayout);\n if (!isTocBox) {\n const isLeftPage = new Exprs.Named(\n pageMaster.pageBox.scope,\n \"left-page\",\n );\n page.side = isLeftPage.evaluate(self)\n ? Constants.PageSide.LEFT\n : Constants.PageSide.RIGHT;\n self.processLinger();\n cp = self.currentLayoutPosition;\n Object.keys(cp.flowPositions).forEach((flowName) => {\n const flowPosition = cp.flowPositions[flowName];\n const breakAfter = flowPosition.breakAfter;\n if (\n breakAfter &&\n (breakAfter === \"page\" || !self.matchPageSide(breakAfter))\n ) {\n flowPosition.breakAfter = null;\n }\n });\n }\n self.currentLayoutPosition = self.layoutPositionAtPageStart = null;\n cp.highestSeenOffset = self.styler.getReachedOffset();\n const triggers = self.style.store.getTriggersForDoc(self.xmldoc);\n page.finish(triggers, self.clientLayout);\n if (self.noMorePrimaryFlows(cp)) {\n cp = null;\n }\n frame.finish(cp);\n });\n return frame.result();\n }\n\n /**\n * Set actual page width, height and bleed from style specified in page\n * context.\n */\n private setPageSizeAndBleed(\n evaluatedPageSizeAndBleed: CssPage.EvaluatedPageSizeAndBleed,\n page: Vtree.Page,\n ) {\n this.actualPageWidth = evaluatedPageSizeAndBleed.pageWidth;\n this.actualPageHeight = evaluatedPageSizeAndBleed.pageHeight;\n this.pageSheetWidth =\n evaluatedPageSizeAndBleed.pageWidth +\n evaluatedPageSizeAndBleed.cropOffset * 2;\n this.pageSheetHeight =\n evaluatedPageSizeAndBleed.pageHeight +\n evaluatedPageSizeAndBleed.cropOffset * 2;\n page.container.style.width = `${this.pageSheetWidth}px`;\n page.container.style.height = `${this.pageSheetHeight}px`;\n page.bleedBox.style.left = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.right = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.top = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.bottom = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.padding = `${evaluatedPageSizeAndBleed.bleed}px`;\n\n // Shift 1px to workaround Chrome printing bug (Canceled because of another Chrome problem)\n // page.bleedBox.style.paddingTop = `${evaluatedPageSizeAndBleed.bleed+1}px`;\n\n // Shift 0.01px to workaround Firefox printing problem\n // (This small value (< 1/64 px) has no effect to Chrome)\n page.bleedBox.style.paddingTop = `${evaluatedPageSizeAndBleed.bleed +\n 0.01}px`;\n }\n}\n\nexport class BaseParserHandler extends CssCascade.CascadeParserHandler {\n insideRegion: boolean = false;\n\n constructor(\n public masterHandler: StyleParserHandler,\n condition: Exprs.Val,\n parent: BaseParserHandler,\n regionId: string | null,\n ) {\n super(\n masterHandler.rootScope,\n masterHandler,\n condition,\n parent,\n regionId,\n masterHandler.validatorSet,\n !parent,\n );\n }\n\n /**\n * @override\n */\n startPageTemplateRule(): void {}\n\n /**\n * @override\n */\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const pageMaster = new PageMaster.PageMaster(\n this.masterHandler.pageScope,\n name,\n pseudoName,\n classes,\n this.masterHandler.rootBox,\n this.condition,\n this.owner.getBaseSpecificity(),\n );\n this.masterHandler.pushHandler(\n new PageMaster.PageMasterParserHandler(\n pageMaster.scope,\n this.masterHandler,\n pageMaster,\n this.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startWhenRule(expr: Css.Expr): void {\n let condition = expr.expr;\n if (this.condition != null) {\n condition = Exprs.and(this.scope, this.condition, condition);\n }\n this.masterHandler.pushHandler(\n new BaseParserHandler(this.masterHandler, condition, this, this.regionId),\n );\n }\n\n /**\n * @override\n */\n startDefineRule(): void {\n this.masterHandler.pushHandler(\n new CssCascade.DefineParserHandler(this.scope, this.owner),\n );\n }\n\n /**\n * @override\n */\n startFontFaceRule(): void {\n const properties = {} as CssCascade.ElementStyle;\n this.masterHandler.fontFaces.push({\n properties,\n condition: this.condition,\n });\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n null,\n properties,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startFlowRule(flowName: string): void {\n let style = this.masterHandler.flowProps[flowName];\n if (!style) {\n style = {} as CssCascade.ElementStyle;\n this.masterHandler.flowProps[flowName] = style;\n }\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n null,\n style,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startViewportRule(): void {\n const viewportProps = {} as CssCascade.ElementStyle;\n this.masterHandler.viewportProps.push(viewportProps);\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n this.condition,\n viewportProps,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startFootnoteRule(pseudoelem: string | null): void {\n let style = this.masterHandler.footnoteProps;\n if (pseudoelem) {\n const pseudos = CssCascade.getMutableStyleMap(style, \"_pseudos\");\n style = pseudos[pseudoelem];\n if (!style) {\n style = {} as CssCascade.ElementStyle;\n pseudos[pseudoelem] = style;\n }\n }\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n null,\n style,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startRegionRule(): void {\n this.insideRegion = true;\n this.startSelectorRule();\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n const pageHandler = new CssPage.PageParserHandler(\n this.masterHandler.pageScope,\n this.masterHandler,\n this,\n this.validatorSet,\n this.masterHandler.pageProps,\n );\n this.masterHandler.pushHandler(pageHandler);\n pageHandler.startPageRule();\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n CssCascade.CascadeParserHandler.prototype.startRuleBody.call(this);\n if (this.insideRegion) {\n this.insideRegion = false;\n const regionId = `R${this.masterHandler.regionCount++}`;\n this.special(\"region-id\", Css.getName(regionId));\n this.endRule();\n const regionHandler = new BaseParserHandler(\n this.masterHandler,\n this.condition,\n this,\n regionId,\n );\n this.masterHandler.pushHandler(regionHandler);\n regionHandler.startRuleBody();\n }\n }\n}\n\n// override, so we don't register an error\nexport function processViewportMeta(meta: Element): string {\n let content = meta.getAttribute(\"content\");\n if (!content) {\n return \"\";\n }\n const vals = {};\n let r: RegExpMatchArray;\n while (\n (r = content.match(\n /^,?\\s*([-A-Za-z_.][-A-Za-z_0-9.]*)\\s*=\\s*([-+A-Za-z_0-9.]*)\\s*/,\n )) != null\n ) {\n content = content.substr(r[0].length);\n vals[r[1]] = r[2];\n }\n const width = vals[\"width\"] - 0;\n const height = vals[\"height\"] - 0;\n if (width && height) {\n return `@-epubx-viewport{width:${width}px;height:${height}px;}`;\n }\n return \"\";\n}\n\nexport class StyleParserHandler extends CssParser.DispatchParserHandler {\n rootScope: Exprs.LexicalScope;\n pageScope: Exprs.LexicalScope;\n rootBox: PageMaster.RootPageBox;\n cascadeParserHandler: BaseParserHandler;\n regionCount: number = 0;\n fontFaces = [] as FontFace[];\n footnoteProps = {} as CssCascade.ElementStyle;\n flowProps = {} as { [key: string]: CssCascade.ElementStyle };\n viewportProps = [] as CssCascade.ElementStyle[];\n pageProps = {} as { [key: string]: CssCascade.ElementStyle };\n slave: BaseParserHandler;\n\n constructor(public readonly validatorSet: CssValidator.ValidatorSet) {\n super();\n this.rootScope = new Exprs.LexicalScope(null);\n this.pageScope = new Exprs.LexicalScope(this.rootScope);\n this.rootBox = new PageMaster.RootPageBox(this.rootScope);\n this.cascadeParserHandler = new BaseParserHandler(this, null, null, null);\n this.slave = this.cascadeParserHandler;\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n Logging.logger.warn(\"CSS parser:\", mnemonics);\n }\n}\n\nexport type StyleSource = {\n url: string;\n text: string | null;\n flavor: CssParser.StylesheetFlavor;\n classes: string | null;\n media: string | null;\n};\n\nexport function parseOPSResource(\n response: Net.Response,\n store: XmlDoc.XMLDocStore,\n): Task.Result<XmlDoc.XMLDocHolder> {\n return (store as OPSDocStore).parseOPSResource(response);\n}\n\nexport class OPSDocStore extends Net.ResourceStore<XmlDoc.XMLDocHolder> {\n styleByKey: { [key: string]: Style } = {};\n styleFetcherByKey: { [key: string]: TaskUtil.Fetcher<Style> } = {};\n styleByDocURL: { [key: string]: Style } = {};\n triggersByDocURL: { [key: string]: Vtree.Trigger[] } = {};\n validatorSet: CssValidator.ValidatorSet = null;\n private styleSheets: StyleSource[] = [];\n private triggerSingleDocumentPreprocessing: boolean = false;\n\n constructor(\n public fontDeobfuscator:\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null,\n ) {\n super(parseOPSResource, Net.XMLHttpRequestResponseType.DOCUMENT);\n }\n\n init(\n authorStyleSheets: { url: string | null; text: string | null }[] | null,\n userStyleSheets: { url: string | null; text: string | null }[] | null,\n ): Task.Result<boolean> {\n this.setStyleSheets(authorStyleSheets as any, userStyleSheets as any);\n const userAgentXML = Base.resolveURL(\n \"user-agent.xml\",\n Base.resourceBaseURL,\n );\n const frame = Task.newFrame<boolean>(\"OPSDocStore.init\");\n this.validatorSet = CssValidator.baseValidatorSet();\n loadUABase().then(() => {\n this.load(userAgentXML).then(() => {\n this.triggerSingleDocumentPreprocessing = true;\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n getStyleForDoc(xmldoc: XmlDoc.XMLDocHolder): Style {\n return this.styleByDocURL[xmldoc.url];\n }\n\n getTriggersForDoc(xmldoc: XmlDoc.XMLDocHolder): Vtree.Trigger[] {\n return this.triggersByDocURL[xmldoc.url];\n }\n\n /**\n * Set author stylesheets and user stylesheets. Existing style sheets are\n * removed.\n */\n private setStyleSheets(\n authorStyleSheets: StyleSource[] | null,\n userStyleSheets: StyleSource[] | null,\n ) {\n this.clearStyleSheets();\n if (authorStyleSheets) {\n authorStyleSheets.forEach(this.addAuthorStyleSheet, this);\n }\n if (userStyleSheets) {\n userStyleSheets.forEach(this.addUserStyleSheet, this);\n }\n }\n\n private clearStyleSheets() {\n this.styleSheets.splice(0);\n }\n\n private addAuthorStyleSheet(stylesheet: StyleSource) {\n let url = stylesheet.url;\n if (url) {\n url = Base.resolveURL(Base.convertSpecialURL(url), Base.baseURL);\n }\n this.styleSheets.push({\n url,\n text: stylesheet.text,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: null,\n media: null,\n });\n }\n\n private addUserStyleSheet(stylesheet: StyleSource) {\n let url = stylesheet.url;\n if (url) {\n url = Base.resolveURL(Base.convertSpecialURL(url), Base.baseURL);\n }\n this.styleSheets.push({\n url,\n text: stylesheet.text,\n flavor: CssParser.StylesheetFlavor.USER,\n classes: null,\n media: null,\n });\n }\n\n parseOPSResource(response: Net.Response): Task.Result<XmlDoc.XMLDocHolder> {\n const frame: Task.Frame<XmlDoc.XMLDocHolder> = Task.newFrame(\n \"OPSDocStore.load\",\n );\n const self = this;\n const url = response.url;\n\n // Hack for TOCView.showTOC()\n const isTocBox = url.endsWith(\"?viv-toc-box\");\n\n XmlDoc.parseXMLResource(response, self).then(\n (xmldoc: XmlDoc.XMLDocHolder) => {\n if (!xmldoc) {\n frame.finish(null);\n return;\n }\n if (self.triggerSingleDocumentPreprocessing) {\n const hooks: Plugin.PreProcessSingleDocumentHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.PREPROCESS_SINGLE_DOCUMENT,\n );\n for (let i = 0; i < hooks.length; i++) {\n try {\n hooks[i](xmldoc.document);\n } catch (e) {\n Logging.logger.warn(\n \"Error during single document preprocessing:\",\n e,\n );\n }\n }\n }\n const triggers = [];\n const triggerList = xmldoc.document.getElementsByTagNameNS(\n Base.NS.epub,\n \"trigger\",\n );\n for (let i = 0; i < triggerList.length; i++) {\n const triggerElem = triggerList[i];\n const observer = triggerElem.getAttributeNS(Base.NS.EV, \"observer\");\n const event = triggerElem.getAttributeNS(Base.NS.EV, \"event\");\n const action = triggerElem.getAttribute(\"action\");\n const ref = triggerElem.getAttribute(\"ref\");\n if (observer && event && action && ref) {\n triggers.push({ observer, event, action, ref });\n }\n }\n self.triggersByDocURL[url] = triggers;\n const sources = [] as StyleSource[];\n const userAgentURL = Base.resolveURL(\n \"user-agent-page.css\",\n Base.resourceBaseURL,\n );\n sources.push({\n url: userAgentURL,\n text: UserAgentPageCss,\n flavor: CssParser.StylesheetFlavor.USER_AGENT,\n classes: null,\n media: null,\n });\n const head = xmldoc.head;\n if (!isTocBox && head) {\n for (let c: Node = head.firstChild; c; c = c.nextSibling) {\n if (c.nodeType != 1) {\n continue;\n }\n const child = c as Element;\n const ns = child.namespaceURI;\n const localName = child.localName;\n if (ns == Base.NS.XHTML) {\n if (localName == \"style\") {\n const classes = child.getAttribute(\"class\");\n const media = child.getAttribute(\"media\");\n const title = child.getAttribute(\"title\");\n sources.push({\n url,\n text: child.textContent,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: title ? classes : null,\n media,\n });\n } else if (localName == \"link\") {\n const rel = child.getAttribute(\"rel\");\n const classes = child.getAttribute(\"class\");\n const media = child.getAttribute(\"media\");\n if (\n rel == \"stylesheet\" ||\n (rel == \"alternate stylesheet\" && classes)\n ) {\n let src = child.getAttribute(\"href\");\n src = Base.resolveURL(src, url);\n const title = child.getAttribute(\"title\");\n sources.push({\n url: src,\n text: null,\n classes: title ? classes : null,\n media,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n });\n }\n } else if (\n localName == \"meta\" &&\n child.getAttribute(\"name\") == \"viewport\"\n ) {\n sources.push({\n url,\n text: processViewportMeta(child),\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: null,\n media: null,\n });\n }\n } else if (ns == Base.NS.FB2) {\n if (\n localName == \"stylesheet\" &&\n child.getAttribute(\"type\") == \"text/css\"\n ) {\n sources.push({\n url,\n text: child.textContent,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: null,\n media: null,\n });\n }\n } else if (ns == Base.NS.SSE && localName === \"property\") {\n // look for stylesheet specification like:\n // <property><name>stylesheet</name><value>style.css</value></property>\n const name = child.getElementsByTagName(\"name\")[0];\n if (name && name.textContent === \"stylesheet\") {\n const value = child.getElementsByTagName(\"value\")[0];\n if (value) {\n const src = Base.resolveURL(value.textContent, url);\n sources.push({\n url: src,\n text: null,\n classes: null,\n media: null,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n });\n }\n }\n }\n }\n }\n if (!isTocBox) {\n for (let i = 0; i < self.styleSheets.length; i++) {\n sources.push(self.styleSheets[i]);\n }\n }\n let key = \"\";\n for (let i = 0; i < sources.length; i++) {\n key += sources[i].url;\n key += \"^\";\n if (sources[i].text) {\n key += sources[i].text;\n }\n key += \"^\";\n }\n let style = self.styleByKey[key];\n if (style) {\n self.styleByDocURL[url] = style;\n frame.finish(xmldoc);\n return;\n }\n let fetcher = self.styleFetcherByKey[key];\n if (!fetcher) {\n fetcher = new TaskUtil.Fetcher(() => {\n const innerFrame: Task.Frame<Style> = Task.newFrame(\n \"fetchStylesheet\",\n );\n let index = 0;\n const sph = new StyleParserHandler(self.validatorSet);\n innerFrame\n .loop(() => {\n if (index < sources.length) {\n const source = sources[index++];\n sph.startStylesheet(source.flavor);\n if (source.text !== null) {\n return CssParser.parseStylesheetFromText(\n source.text,\n sph,\n source.url,\n source.classes,\n source.media,\n ).thenReturn(true);\n } else {\n return CssParser.parseStylesheetFromURL(\n source.url,\n sph,\n source.classes,\n source.media,\n );\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n const cascade = sph.cascadeParserHandler.finish();\n style = new Style(\n self,\n sph.rootScope,\n sph.pageScope,\n cascade,\n sph.rootBox,\n sph.fontFaces,\n sph.footnoteProps,\n sph.flowProps,\n sph.viewportProps,\n sph.pageProps,\n );\n self.styleByKey[key] = style;\n delete self.styleFetcherByKey[key];\n innerFrame.finish(style);\n });\n return innerFrame.result();\n }, `FetchStylesheet ${url}`);\n self.styleFetcherByKey[key] = fetcher;\n fetcher.start();\n }\n fetcher.get().then((style) => {\n self.styleByDocURL[url] = style;\n frame.finish(xmldoc);\n });\n },\n );\n return frame.result();\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Sha1 - Calculate SHA1 hash of the given content.\n */\nimport * as Base from \"./base\";\n\n/**\n * @return big-endian byte sequence\n */\nexport function encode32(n: number): string {\n return String.fromCharCode(\n (n >>> 24) & 255,\n (n >>> 16) & 255,\n (n >>> 8) & 255,\n n & 255,\n );\n}\n\n/**\n * @param bytes big-endian byte sequence\n */\nexport function decode32(bytes: string): number {\n // Important facts: \"\".charCodeAt(0) == NaN, NaN & 0xFF == 0\n const b0 = bytes.charCodeAt(0) & 255;\n const b1 = bytes.charCodeAt(1) & 255;\n const b2 = bytes.charCodeAt(2) & 255;\n const b3 = bytes.charCodeAt(3) & 255;\n return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return big-endian uint32 numbers representing sha1 hash\n */\nexport function bytesToSHA1Int32(bytes: string): number[] {\n const sb = new Base.StringBuffer();\n sb.append(bytes);\n let appendCount = (55 - bytes.length) & 63;\n sb.append(\"\\u0080\");\n while (appendCount > 0) {\n appendCount--;\n sb.append(\"\\x00\");\n }\n sb.append(\"\\x00\\x00\\x00\\x00\");\n sb.append(encode32(bytes.length * 8));\n bytes = sb.toString();\n const h = [1732584193, 4023233417, 2562383102, 271733878, 3285377520];\n const w =\n /** @type Array.<number> */\n [] as number[];\n let i: number;\n for (let bi = 0; bi < bytes.length; bi += 64) {\n for (i = 0; i < 16; i++) {\n w[i] = decode32(bytes.substr(bi + 4 * i, 4));\n }\n for (; i < 80; i++) {\n const q = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];\n w[i] = (q << 1) | (q >>> 31);\n }\n let a = h[0];\n let b = h[1];\n let c = h[2];\n let d = h[3];\n let e = h[4];\n let f: number;\n for (i = 0; i < 80; i++) {\n if (i < 20) {\n f = ((b & c) | (~b & d)) + 1518500249;\n } else if (i < 40) {\n f = (b ^ c ^ d) + 1859775393;\n } else if (i < 60) {\n f = ((b & c) | (b & d) | (c & d)) + 2400959708;\n } else {\n f = (b ^ c ^ d) + 3395469782;\n }\n f += ((a << 5) | (a >>> 27)) + e + w[i];\n e = d;\n d = c;\n c = (b << 30) | (b >>> 2);\n b = a;\n a = f;\n }\n h[0] = (h[0] + a) | 0;\n h[1] = (h[1] + b) | 0;\n h[2] = (h[2] + c) | 0;\n h[3] = (h[3] + d) | 0;\n h[4] = (h[4] + e) | 0;\n }\n return h;\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return uint8 numbers representing sha1 hash\n */\nexport function bytesToSHA1Int8(bytes: string): number[] {\n const h = bytesToSHA1Int32(bytes);\n const res = [];\n for (const n of h) {\n res.push((n >>> 24) & 255, (n >>> 16) & 255, (n >>> 8) & 255, n & 255);\n }\n return res;\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return chars with codes 0 - 255 equal to SHA1 hash of the input\n */\nexport function bytesToSHA1Bytes(bytes: string): string {\n const h = bytesToSHA1Int32(bytes);\n const sb = new Base.StringBuffer();\n for (let i = 0; i < h.length; i++) {\n sb.append(encode32(h[i]));\n }\n return sb.toString();\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return hex-encoded SHA1 hash\n */\nexport function bytesToSHA1Hex(bytes: string): string {\n const sha1 = bytesToSHA1Bytes(bytes);\n const sb = new Base.StringBuffer();\n for (let i = 0; i < sha1.length; i++) {\n sb.append((sha1.charCodeAt(i) | 256).toString(16).substr(1));\n }\n return sb.toString();\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return base64-encoded SHA1 hash of the input\n */\nexport function bytesToSHA1Base64(bytes: string): string {\n const sha1 = bytesToSHA1Bytes(bytes);\n const sb = new Base.StringBuffer();\n Base.appendBase64(sb, sha1);\n return sb.toString();\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Toc - Table of Contents view.\n */\nimport * as Base from \"./base\";\nimport * as Counters from \"./counters\";\nimport * as Css from \"./css\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as OPS from \"./ops\";\nimport * as Task from \"./task\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport * as XmlDoc from \"./xml-doc\";\n\n// closed: 25B8\n// open: 25BE\n// empty: 25B9\nexport const bulletClosed = \"\\u25b8\";\n\nexport const bulletOpen = \"\\u25be\";\n\nexport const bulletEmpty = \"\\u25b9\";\n\nexport class TOCView implements Vgen.CustomRendererFactory {\n pref: Exprs.Preferences;\n page: Vtree.Page = null;\n instance: OPS.StyleInstance = null;\n\n constructor(\n public readonly store: OPS.OPSDocStore,\n public readonly url: string,\n public readonly lang: string | null,\n public readonly clientLayout: Vtree.ClientLayout,\n public readonly fontMapper: Font.Mapper,\n pref: Exprs.Preferences,\n public readonly rendererFactory: Vgen.CustomRendererFactory,\n public readonly fallbackMap: { [key: string]: string },\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n public readonly counterStore: Counters.CounterStore,\n ) {\n this.pref = Exprs.clonePreferences(pref);\n this.pref.spreadView = false; // No spred view for TOC box\n }\n\n setAutoHeight(elem: Element, depth: number): void {\n if (depth-- == 0) {\n return;\n }\n for (let c: Node = elem.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1) {\n const e = c as Element;\n if (Base.getCSSProperty(e, \"height\", \"auto\") != \"auto\") {\n Base.setCSSProperty(e, \"height\", \"auto\");\n this.setAutoHeight(e, depth);\n }\n if (Base.getCSSProperty(e, \"position\", \"static\") == \"absolute\") {\n Base.setCSSProperty(e, \"position\", \"relative\");\n this.setAutoHeight(e, depth);\n }\n }\n }\n }\n\n /**\n * @override\n */\n makeCustomRenderer(xmldoc: XmlDoc.XMLDocHolder): Vgen.CustomRenderer {\n const renderer = this.rendererFactory.makeCustomRenderer(xmldoc);\n return (\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> => {\n const behavior = computedStyle[\"behavior\"];\n if (behavior) {\n switch (behavior.toString()) {\n case \"body-child\":\n if (\n srcElem.parentElement.getAttribute(\n \"data-vivliostyle-primary-entry\",\n )\n ) {\n if (\n !srcElem.querySelector(\n \"[role=doc-toc], [role=directory], nav li a, .toc, #toc\",\n )\n ) {\n // When the TOC element is a part of the primaty entry (X)HTML,\n // hide elements not containing TOC.\n computedStyle[\"display\"] = Css.ident.none;\n }\n }\n break;\n case \"toc-node-anchor\":\n computedStyle[\"color\"] = Css.ident.inherit;\n computedStyle[\"text-decoration\"] = Css.ident.none;\n break;\n case \"toc-node\":\n computedStyle[\"display\"] = Css.ident.block;\n computedStyle[\"margin\"] = Css.numericZero;\n computedStyle[\"padding\"] = Css.numericZero;\n computedStyle[\"padding-inline-start\"] = new Css.Numeric(1.25, \"em\");\n break;\n case \"toc-node-first-child\":\n computedStyle[\"display\"] = Css.ident.inline_block;\n computedStyle[\"margin\"] = new Css.Numeric(0.2, \"em\");\n computedStyle[\"vertical-align\"] = Css.ident.top;\n computedStyle[\"color\"] = Css.ident.inherit;\n computedStyle[\"text-decoration\"] = Css.ident.none;\n break;\n }\n }\n if (\n !behavior ||\n (behavior.toString() != \"toc-node\" &&\n behavior.toString() != \"toc-container\")\n ) {\n return renderer(srcElem, viewParent, computedStyle);\n }\n // Remove white-space textnode that becomes unwanted space between button and anchor element.\n const firstChild = srcElem.firstChild;\n if (\n firstChild &&\n firstChild.nodeType !== 1 &&\n firstChild.textContent.trim() === \"\"\n ) {\n // To avoid \"Inconsistent offset\" error, create a comment node with same white-space text.\n srcElem.replaceChild(\n srcElem.ownerDocument.createComment(firstChild.textContent),\n firstChild,\n );\n }\n const adaptParentClass = viewParent.getAttribute(\"data-adapt-class\");\n if (adaptParentClass == \"toc-node\") {\n const button = viewParent.firstChild as Element;\n if (button.textContent != bulletClosed) {\n button.textContent = bulletClosed;\n Base.setCSSProperty(button, \"cursor\", \"pointer\");\n button.addEventListener(\"click\", toggleNodeExpansion, false);\n\n button.setAttribute(\"role\", \"button\");\n button.setAttribute(\"aria-expanded\", \"false\");\n viewParent.setAttribute(\"aria-expanded\", \"false\");\n\n // Enable tab move to the button unless hidden.\n if ((viewParent as HTMLElement).style.height !== \"0px\") {\n (button as HTMLElement).tabIndex = 0;\n }\n }\n }\n const element = viewParent.ownerDocument.createElement(\"div\");\n element.setAttribute(\"data-adapt-process-children\", \"true\");\n if (behavior.toString() == \"toc-node\") {\n const button = viewParent.ownerDocument.createElement(\"div\");\n button.textContent = bulletEmpty;\n\n // TODO: define pseudo-element for the button?\n Base.setCSSProperty(button, \"margin\", \"0.2em 0 0 -1em\");\n Base.setCSSProperty(button, \"margin-inline-start\", \"-1em\");\n Base.setCSSProperty(button, \"margin-inline-end\", \"0\");\n Base.setCSSProperty(button, \"display\", \"inline-block\");\n Base.setCSSProperty(button, \"width\", \"1em\");\n Base.setCSSProperty(button, \"text-align\", \"center\");\n Base.setCSSProperty(button, \"vertical-align\", \"top\");\n Base.setCSSProperty(button, \"cursor\", \"default\");\n Base.setCSSProperty(button, \"font-family\", \"Menlo,sans-serif\");\n element.appendChild(button);\n Base.setCSSProperty(element, \"overflow\", \"hidden\");\n element.setAttribute(\"data-adapt-class\", \"toc-node\");\n element.setAttribute(\"role\", \"treeitem\");\n\n if (\n adaptParentClass == \"toc-node\" ||\n adaptParentClass == \"toc-container\"\n ) {\n Base.setCSSProperty(element, \"height\", \"0px\");\n\n // Prevent tab move to hidden anchor.\n const anchorElem = srcElem.firstElementChild;\n if (anchorElem && anchorElem.localName === \"a\") {\n (anchorElem as HTMLElement).tabIndex = -1;\n }\n } else {\n viewParent.setAttribute(\"role\", \"tree\");\n }\n } else {\n if (adaptParentClass == \"toc-node\") {\n element.setAttribute(\"data-adapt-class\", \"toc-container\");\n element.setAttribute(\"role\", \"group\");\n element.setAttribute(\"aria-hidden\", \"true\");\n }\n }\n return Task.newResult(element as Element);\n };\n }\n\n showTOC(\n elem: HTMLElement,\n viewport: Vgen.Viewport,\n width: number,\n height: number,\n fontSize: number,\n ): Task.Result<Vtree.Page> {\n if (this.page) {\n return Task.newResult(this.page as Vtree.Page);\n }\n const self = this;\n const frame: Task.Frame<Vtree.Page> = Task.newFrame(\"showTOC\");\n const page = new Vtree.Page(elem, elem);\n this.page = page;\n\n // The (X)HTML doc for the TOC box may be reused for the TOC page in the book,\n // but they need different styles. So, add \"?viv-toc-box\" to distinguish with TOC page URL.\n const tocBoxUrl = this.url + \"?viv-toc-box\";\n\n this.store.load(tocBoxUrl).then((xmldoc) => {\n // Mark if this doc is the primary entry page.\n const nonTocBoxDoc = this.store.resources[this.url];\n if (\n nonTocBoxDoc &&\n nonTocBoxDoc.body &&\n nonTocBoxDoc.body.getAttribute(\"data-vivliostyle-primary-entry\")\n ) {\n xmldoc.body.setAttribute(\"data-vivliostyle-primary-entry\", true);\n }\n\n const style = self.store.getStyleForDoc(xmldoc);\n const viewportSize = style.sizeViewport(width, 100000, fontSize);\n viewport = new Vgen.Viewport(\n viewport.window,\n viewportSize.fontSize,\n viewport.root,\n viewportSize.width,\n viewportSize.height,\n );\n const customRenderer = self.makeCustomRenderer(xmldoc);\n const instance = new OPS.StyleInstance(\n style,\n xmldoc,\n self.lang,\n viewport,\n self.clientLayout,\n self.fontMapper,\n customRenderer,\n self.fallbackMap,\n 0,\n self.documentURLTransformer,\n self.counterStore,\n );\n self.instance = instance;\n instance.pref = self.pref;\n instance.init().then(() => {\n instance.layoutNextPage(page, null).then(() => {\n Array.from(\n page.container.querySelectorAll(\n \"[data-vivliostyle-toc-box]>*>*>*>*>*[style*='display: none']\",\n ),\n ).forEach((bodyChildElem) => {\n bodyChildElem.setAttribute(\"aria-hidden\", \"true\");\n bodyChildElem.setAttribute(\"hidden\", \"hidden\");\n });\n self.setAutoHeight(elem, 2);\n frame.finish(page);\n });\n });\n });\n return frame.result();\n }\n\n hideTOC(): void {\n if (this.page) {\n this.page.container.style.visibility = \"hidden\";\n this.page.container.setAttribute(\"aria-hidden\", \"true\");\n }\n }\n\n isTOCVisible(): boolean {\n return !!this.page && this.page.container.style.visibility === \"visible\";\n }\n}\n\nexport function toggleNodeExpansion(evt: Event): void {\n const elem = evt.target as Element;\n const open = elem.textContent == bulletClosed;\n elem.textContent = open ? bulletOpen : bulletClosed;\n const tocNodeElem = elem.parentNode as Element;\n elem.setAttribute(\"aria-expanded\", open ? \"true\" : \"false\");\n tocNodeElem.setAttribute(\"aria-expanded\", open ? \"true\" : \"false\");\n let c: Node = tocNodeElem.firstChild;\n while (c) {\n if (c.nodeType === 1) {\n const ce = c as HTMLElement;\n const adaptClass = ce.getAttribute(\"data-adapt-class\");\n if (adaptClass === \"toc-container\") {\n ce.setAttribute(\"aria-hidden\", !open ? \"true\" : \"false\");\n if (ce.firstChild) {\n c = ce.firstChild;\n continue;\n }\n } else if (adaptClass === \"toc-node\") {\n ce.style.height = open ? \"auto\" : \"0px\";\n\n // Update enable/disable tab move to the button and anchor.\n if (ce.children.length >= 2) {\n (ce.children[1] as HTMLElement).tabIndex = open ? 0 : -1;\n }\n if (ce.children.length >= 3) {\n (ce.children[0] as HTMLElement).tabIndex = open ? 0 : -1;\n if (!open) {\n const elem1 = ce.children[0];\n if (elem1.textContent == bulletOpen) {\n elem1.textContent = bulletClosed;\n elem1.setAttribute(\"aria-expanded\", \"false\");\n ce.setAttribute(\"aria-expanded\", \"false\");\n c = ce.children[2];\n continue;\n }\n }\n }\n }\n }\n while (!c.nextSibling && c.parentNode !== tocNodeElem) {\n c = c.parentNode;\n }\n c = c.nextSibling;\n }\n evt.stopPropagation();\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2018 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Epub - Deal with META-INF/ and .opf files in EPUB container.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as CFI from \"./cfi\";\nimport * as Constants from \"./constants\";\nimport * as Counters from \"./counters\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as OPS from \"./ops\";\nimport * as SHA1 from \"./sha1\";\nimport * as Task from \"./task\";\nimport * as Toc from \"./toc\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport * as XmlDoc from \"./xml-doc\";\n\nexport type Position = {\n spineIndex: number;\n pageIndex: number;\n offsetInItem: number;\n};\n\nexport class EPUBDocStore extends OPS.OPSDocStore {\n plainXMLStore: XmlDoc.XMLDocStore;\n jsonStore: Net.JSONStore;\n opfByURL: { [key: string]: OPFDoc } = {};\n primaryOPFByEPubURL: { [key: string]: OPFDoc } = {};\n deobfuscators: { [key: string]: (p1: Blob) => Task.Result<Blob> } = {};\n documents: { [key: string]: Task.Result<XmlDoc.XMLDocHolder> } = {};\n\n constructor() {\n super(null);\n this.fontDeobfuscator = this.makeDeobfuscatorFactory();\n this.plainXMLStore = XmlDoc.newXMLDocStore();\n this.jsonStore = Net.newJSONStore();\n }\n\n makeDeobfuscatorFactory():\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null {\n const self = this;\n return (url: string): ((p1: Blob) => Task.Result<Blob>) | null => {\n return self.deobfuscators[url];\n };\n }\n\n loadAsPlainXML(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<XmlDoc.XMLDocHolder> {\n return this.plainXMLStore.load(\n url,\n opt_required,\n opt_message,\n ) as Task.Result<XmlDoc.XMLDocHolder>;\n }\n\n startLoadingAsPlainXML(url: string): void {\n this.plainXMLStore.fetch(url);\n }\n\n loadAsJSON(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Base.JSON> {\n return this.jsonStore.load(url, opt_required, opt_message);\n }\n\n startLoadingAsJSON(url: string): void {\n this.jsonStore.fetch(url);\n }\n\n loadPubDoc(url: string, haveZipMetadata: boolean): Task.Result<OPFDoc> {\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadPubDoc\");\n\n Net.ajax(url, null, \"HEAD\").then((response) => {\n if (response.status >= 400) {\n // This url can be the root of an unzipped EPUB.\n this.loadEPUBDoc(url, haveZipMetadata).then((opf) => {\n if (opf) {\n frame.finish(opf);\n return;\n }\n Logging.logger.error(\n `Failed to fetch a source document from ${url} (${response.status}${\n response.statusText ? \" \" + response.statusText : \"\"\n })`,\n );\n frame.finish(null);\n });\n } else {\n if (\n !response.status &&\n !response.responseXML &&\n !response.responseText &&\n !response.responseBlob &&\n !response.contentType\n ) {\n // Empty response\n if (/\\/[^/.]+(?:[#?]|$)/.test(url)) {\n // Adding trailing \"/\" may solve the problem.\n url = url.replace(/([#?]|$)/, \"/$1\");\n } else {\n // Ignore empty response of HEAD request, it may become OK with GET request.\n }\n }\n if (\n response.contentType == \"application/oebps-package+xml\" ||\n /\\.opf(?:[#?]|$)/.test(url)\n ) {\n // EPUB OPF\n const [, pubURL, root] = url.match(/^((?:.*\\/)?)([^/]*)$/);\n this.loadOPF(pubURL, root, haveZipMetadata).thenFinish(frame);\n } else if (\n response.contentType == \"application/ld+json\" ||\n response.contentType == \"application/webpub+json\" ||\n response.contentType == \"application/audiobook+json\" ||\n response.contentType == \"application/json\" ||\n /\\.json(?:ld)?(?:[#?]|$)/.test(url)\n ) {\n // Web Publication Manifest\n this.loadAsJSON(url, true).then((manifestObj) => {\n if (!manifestObj) {\n Logging.logger.error(\n `Received an empty response for ${url}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n frame.finish(null);\n return;\n }\n const opf = new OPFDoc(this, url);\n opf.initWithWebPubManifest(manifestObj).then(() => {\n frame.finish(opf);\n });\n });\n } else {\n // Web Publication primary entry (X)HTML\n this.loadWebPub(url).then((opf) => {\n if (opf) {\n frame.finish(opf);\n return;\n }\n // This url can be the root of an unzipped EPUB.\n this.loadEPUBDoc(url, haveZipMetadata).then((opf) => {\n if (opf) {\n frame.finish(opf);\n return;\n }\n Logging.logger.error(`Failed to load ${url}.`);\n frame.finish(null);\n });\n });\n }\n }\n });\n return frame.result();\n }\n\n loadEPUBDoc(url: string, haveZipMetadata: boolean): Task.Result<OPFDoc> {\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadEPUBDoc\");\n if (!url.endsWith(\"/\")) {\n url = url + \"/\";\n }\n if (haveZipMetadata) {\n this.startLoadingAsJSON(url + \"?r=list\");\n }\n this.startLoadingAsPlainXML(url + \"META-INF/encryption.xml\");\n const containerURL = url + \"META-INF/container.xml\";\n this.loadAsPlainXML(containerURL).then((containerXML) => {\n if (containerXML) {\n const roots = containerXML\n .doc()\n .child(\"container\")\n .child(\"rootfiles\")\n .child(\"rootfile\")\n .attribute(\"full-path\");\n for (const root of roots) {\n if (root) {\n this.loadOPF(url, root, haveZipMetadata).thenFinish(frame);\n return;\n }\n }\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n loadOPF(\n pubURL: string,\n root: string,\n haveZipMetadata: boolean,\n ): Task.Result<OPFDoc> {\n const self = this;\n const url = pubURL + root;\n let opf = self.opfByURL[url];\n if (opf) {\n return Task.newResult(opf);\n }\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadOPF\");\n self\n .loadAsPlainXML(url, true, `Failed to fetch EPUB OPF ${url}`)\n .then((opfXML) => {\n if (!opfXML) {\n Logging.logger.error(\n `Received an empty response for EPUB OPF ${url}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n } else {\n self\n .loadAsPlainXML(`${pubURL}META-INF/encryption.xml`)\n .then((encXML) => {\n const zipMetadataResult = haveZipMetadata\n ? self.loadAsJSON(`${pubURL}?r=list`)\n : Task.newResult(null);\n zipMetadataResult.then((zipMetadata) => {\n opf = new OPFDoc(self, pubURL);\n opf\n .initWithXMLDoc(\n opfXML,\n encXML,\n zipMetadata,\n `${pubURL}?r=manifest`,\n )\n .then(() => {\n self.opfByURL[url] = opf;\n self.primaryOPFByEPubURL[pubURL] = opf;\n frame.finish(opf);\n });\n });\n });\n }\n });\n return frame.result();\n }\n\n loadWebPub(url: string): Task.Result<OPFDoc> {\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadWebPub\");\n\n // Load the primary entry page (X)HTML\n this.load(url).then((xmldoc) => {\n if (!xmldoc) {\n Logging.logger.error(\n `Received an empty response for ${url}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n } else if (\n xmldoc.document.querySelector(\n \"a[href='META-INF/'],a[href$='/META-INF/']\",\n )\n ) {\n // This is likely the directory listing of unzipped EPUB top directory\n frame.finish(null);\n } else {\n const doc = xmldoc.document;\n const opf = new OPFDoc(this, url);\n\n if (doc.body) {\n doc.body.setAttribute(\"data-vivliostyle-primary-entry\", true);\n }\n // Find manifest, W3C WebPublication or Readium Web Publication Manifest\n const manifestLink = doc.querySelector(\n \"link[rel='publication'],link[rel='manifest'][type='application/webpub+json']\",\n );\n if (manifestLink) {\n const href = manifestLink.getAttribute(\"href\");\n if (/^#/.test(href)) {\n const manifestObj = Base.stringToJSON(\n doc.getElementById(href.substr(1)).textContent,\n );\n opf.initWithWebPubManifest(manifestObj, doc).then(() => {\n frame.finish(opf);\n });\n } else {\n this.loadAsJSON(\n Base.resolveURL(manifestLink.getAttribute(\"href\"), url),\n ).then((manifestObj) => {\n opf.initWithWebPubManifest(manifestObj, doc).then(() => {\n frame.finish(opf);\n });\n });\n }\n } else {\n // No manifest\n opf.initWithWebPubManifest({}, doc).then(() => {\n if (opf.xhtmlToc && opf.xhtmlToc.src === xmldoc.url) {\n // xhtmlToc is the primari entry (X)HTML\n if (\n !doc.querySelector(\n \"[role=doc-toc], [role=directory], nav, .toc, #toc\",\n )\n ) {\n // TOC is not found in the primari entry (X)HTML\n opf.xhtmlToc = null;\n }\n }\n frame.finish(opf);\n });\n }\n }\n });\n return frame.result();\n }\n\n addDocument(url: string, doc: Document) {\n const frame = Task.newFrame<XmlDoc.XMLDocHolder>(\"EPUBDocStore.load\");\n const docURL = Base.stripFragment(url);\n const r = (this.documents[docURL] = this.parseOPSResource({\n status: 200,\n statusText: \"\",\n url: docURL,\n contentType: (doc as any).contentType,\n responseText: null,\n responseXML: doc,\n responseBlob: null,\n }));\n r.thenFinish(frame);\n return frame.result();\n }\n\n /**\n * @override\n */\n load(url: string): Task.Result<XmlDoc.XMLDocHolder> {\n const docURL = Base.stripFragment(url);\n let r = this.documents[docURL];\n if (r) {\n return r.isPending() ? r : Task.newResult(r.get());\n } else {\n const frame = Task.newFrame<XmlDoc.XMLDocHolder>(\"EPUBDocStore.load\");\n r = super.load(\n docURL,\n true,\n `Failed to fetch a source document from ${docURL}`,\n );\n r.then((xmldoc: XmlDoc.XMLDocHolder) => {\n if (!xmldoc) {\n if (docURL.startsWith(\"data:\")) {\n Logging.logger.error(`Failed to load ${docURL}. Invalid data.`);\n } else if (\n docURL.startsWith(\"http:\") &&\n Base.baseURL.startsWith(\"https:\")\n ) {\n Logging.logger.error(\n `Failed to load ${docURL}. Mixed Content (\"http:\" content on \"https:\" context) is not allowed.`,\n );\n } else {\n Logging.logger.error(\n `Received an empty response for ${docURL}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n }\n } else {\n frame.finish(xmldoc);\n }\n });\n return frame.result();\n }\n }\n}\n\nexport type OPFItemParam = {\n url: string;\n index: number;\n startPage: number | null;\n skipPagesBefore: number | null;\n};\n\nexport class OPFItem {\n id: string | null = null;\n src: string = \"\";\n mediaType: string | null = null;\n title: string | null = null;\n itemRefElement: Element | null = null;\n spineIndex: number = -1;\n compressedSize: number = 0;\n compressed: boolean | null = null;\n epage: number = 0;\n epageCount: number = 0;\n startPage: number | null = null;\n skipPagesBefore: number | null = null;\n itemProperties: { [key: string]: boolean };\n\n constructor() {\n this.itemProperties = Base.emptyObj;\n }\n\n initWithElement(itemElem: Element, opfURL: string): void {\n this.id = itemElem.getAttribute(\"id\");\n this.src = Base.resolveURL(itemElem.getAttribute(\"href\"), opfURL);\n this.mediaType = itemElem.getAttribute(\"media-type\");\n const propStr = itemElem.getAttribute(\"properties\");\n if (propStr) {\n this.itemProperties = Base.arrayToSet(propStr.split(/\\s+/));\n }\n }\n\n initWithParam(param: OPFItemParam) {\n this.spineIndex = param.index;\n this.id = `item${param.index + 1}`;\n this.src = param.url;\n this.startPage = param.startPage;\n this.skipPagesBefore = param.skipPagesBefore;\n }\n}\n\nexport function getOPFItemId(item: OPFItem): string | null {\n return item.id;\n}\n\nexport function makeDeobfuscator(uid: string): (p1: Blob) => Task.Result<Blob> {\n // TODO: use UTF8 of uid\n const sha1Sum = SHA1.bytesToSHA1Int8(uid);\n return (blob) => {\n const frame = Task.newFrame(\"deobfuscator\") as Task.Frame<Blob>;\n let head: Blob;\n let tail: Blob;\n if (blob.slice) {\n head = blob.slice(0, 1040);\n tail = blob.slice(1040, blob.size);\n } else {\n head = blob[\"webkitSlice\"](0, 1040);\n tail = blob[\"webkitSlice\"](1040, blob.size - 1040);\n }\n Net.readBlob(head).then((buf) => {\n const dataView = new DataView(buf);\n for (let k = 0; k < dataView.byteLength; k++) {\n let b = dataView.getUint8(k);\n b ^= sha1Sum[k % 20];\n dataView.setUint8(k, b);\n }\n frame.finish(Net.makeBlob([dataView, tail]));\n });\n return frame.result();\n };\n}\n\nexport function makeObfuscationKey(uid: string): string {\n return `1040:${SHA1.bytesToSHA1Hex(uid)}`;\n}\n\nexport type RawMetaItem = {\n name: string;\n value: string;\n id: string | null;\n refines: string | null;\n scheme: string | null;\n lang: string | null;\n order: number;\n};\n\nexport const predefinedPrefixes = {\n dcterms: \"http://purl.org/dc/terms/\",\n marc: \"http://id.loc.gov/vocabulary/\",\n media: \"http://www.idpf.org/epub/vocab/overlays/#\",\n rendition: \"http://www.idpf.org/vocab/rendition/#\",\n onix: \"http://www.editeur.org/ONIX/book/codelists/current.html#\",\n xsd: \"http://www.w3.org/2001/XMLSchema#\",\n};\n\nexport const defaultIRI = \"http://idpf.org/epub/vocab/package/#\";\n\nexport const metaTerms = {\n language: `${predefinedPrefixes[\"dcterms\"]}language`,\n title: `${predefinedPrefixes[\"dcterms\"]}title`,\n creator: `${predefinedPrefixes[\"dcterms\"]}creator`,\n layout: `${predefinedPrefixes[\"rendition\"]}layout`,\n titleType: `${defaultIRI}title-type`,\n displaySeq: `${defaultIRI}display-seq`,\n alternateScript: `${defaultIRI}alternate-script`,\n};\n\nexport function getMetadataComparator(\n term: string,\n lang: string,\n): (p1: Base.JSON, p2: Base.JSON) => number {\n const empty = {};\n return (item1, item2) => {\n let m1: boolean;\n let m2: boolean;\n const r1 = item1[\"r\"] || empty;\n const r2 = item2[\"r\"] || empty;\n if (term == metaTerms.title) {\n m1 = r1[metaTerms.titleType] == \"main\";\n m2 = r2[metaTerms.titleType] == \"main\";\n if (m1 != m2) {\n return m1 ? -1 : 1;\n }\n }\n let i1 = parseInt(r1[metaTerms.displaySeq], 10);\n if (isNaN(i1)) {\n i1 = Number.MAX_VALUE;\n }\n let i2 = parseInt(r2[metaTerms.displaySeq], 10);\n if (isNaN(i2)) {\n i2 = Number.MAX_VALUE;\n }\n if (i1 != i2) {\n return i1 - i2;\n }\n if (term != metaTerms.language && lang) {\n m1 = (r1[metaTerms.language] || r1[metaTerms.alternateScript]) == lang;\n m2 = (r2[metaTerms.language] || r2[metaTerms.alternateScript]) == lang;\n if (m1 != m2) {\n return m1 ? -1 : 1;\n }\n }\n return item1[\"o\"] - item2[\"o\"];\n };\n}\n\nexport function readMetadata(\n mroot: XmlDoc.NodeList,\n prefixes: string | null,\n): Base.JSON {\n // Parse prefix map (if any)\n let prefixMap;\n if (!prefixes) {\n prefixMap = predefinedPrefixes;\n } else {\n prefixMap = {};\n for (const pn in predefinedPrefixes) {\n prefixMap[pn] = predefinedPrefixes[pn];\n }\n let r: RegExpMatchArray;\n\n // This code permits any non-ASCII characters in the name to avoid bloating\n // the pattern.\n while (\n (r = prefixes.match(\n /^\\s*([A-Z_a-z\\u007F-\\uFFFF][-.A-Z_a-z0-9\\u007F-\\uFFFF]*):\\s*(\\S+)/,\n )) != null\n ) {\n prefixes = prefixes.substr(r[0].length);\n prefixMap[r[1]] = r[2];\n }\n }\n const resolveProperty = (val: string | null): string | null => {\n if (val) {\n const r = val.match(/^\\s*(([^:]*):)?(\\S+)\\s*$/);\n if (r) {\n const iri = r[2] ? prefixMap[r[2]] : defaultIRI;\n if (iri) {\n return iri + r[3];\n }\n }\n }\n return null;\n };\n let order = 1;\n\n // List of metadata items.\n const rawItems = mroot.childElements().forEachNonNull((node: Element) => {\n if (node.localName == \"meta\") {\n const p = resolveProperty((node as Element).getAttribute(\"property\"));\n if (p) {\n return {\n name: p,\n value: node.textContent,\n id: (node as Element).getAttribute(\"id\"),\n order: order++,\n refines: (node as Element).getAttribute(\"refines\"),\n lang: null,\n scheme: resolveProperty((node as Element).getAttribute(\"scheme\")),\n };\n }\n } else if (node.namespaceURI == Base.NS.DC) {\n return {\n name: predefinedPrefixes[\"dcterms\"] + node.localName,\n order: order++,\n lang: (node as Element).getAttribute(\"xml:lang\"),\n value: node.textContent,\n id: (node as Element).getAttribute(\"id\"),\n refines: null,\n scheme: null,\n };\n }\n return null;\n });\n\n // Items grouped by their target id.\n const rawItemsByTarget = Base.multiIndexArray(\n rawItems,\n (rawItem) => rawItem.refines,\n );\n const makeMetadata = (map: {\n [key: string]: any[];\n }): { [key: string]: any[] } =>\n Base.mapObj(map, (rawItemArr, itemName) =>\n rawItemArr.map((rawItem) => {\n const entry = { v: rawItem.value, o: rawItem.order };\n if (rawItem.schema) {\n entry[\"s\"] = rawItem.scheme;\n }\n if (rawItem.id || rawItem.lang) {\n let refs = rawItemsByTarget[rawItem.id];\n if (refs || rawItem.lang) {\n if (rawItem.lang) {\n // Special handling for xml:lang\n const langItem = {\n name: metaTerms.language,\n value: rawItem.lang,\n lang: null,\n id: null,\n refines: rawItem.id,\n scheme: null,\n order: rawItem.order,\n };\n if (refs) {\n refs.push(langItem);\n } else {\n refs = [langItem];\n }\n }\n const entryMap = Base.multiIndexArray(\n refs,\n (rawItem) => rawItem.name,\n );\n entry[\"r\"] = makeMetadata(entryMap);\n }\n }\n return entry;\n }),\n );\n const metadata = makeMetadata(\n Base.multiIndexArray(rawItems, (rawItem) =>\n rawItem.refines ? null : rawItem.name,\n ),\n );\n let lang: string | null = null;\n if (metadata[metaTerms.language]) {\n lang = metadata[metaTerms.language][0][\"v\"];\n }\n const sortMetadata = (metadata: { [key: string]: any[] }) => {\n for (const term in metadata) {\n const arr = metadata[term];\n arr.sort(getMetadataComparator(term, lang));\n for (let i = 0; i < arr.length; i++) {\n const r = arr[i][\"r\"];\n if (r) {\n sortMetadata(r);\n }\n }\n }\n };\n sortMetadata(metadata);\n return metadata;\n}\n\nexport function getMathJaxHub(): object {\n const math = window[\"MathJax\"];\n if (math) {\n return math[\"Hub\"];\n }\n return null;\n}\n\nexport function checkMathJax(): void {\n if (getMathJaxHub()) {\n CssCascade.supportedNamespaces[Base.NS.MATHML] = true;\n }\n}\n\nexport const supportedMediaTypes = {\n \"application/xhtml+xml\": true,\n \"image/jpeg\": true,\n \"image/png\": true,\n \"image/svg+xml\": true,\n \"image/gif\": true,\n \"audio/mp3\": true,\n};\n\nexport const transformedIdPrefix = \"viv-id-\";\n\nexport class OPFDoc {\n opfXML: XmlDoc.XMLDocHolder = null;\n encXML: XmlDoc.XMLDocHolder = null;\n items: OPFItem[] = null;\n spine: OPFItem[] = null;\n itemMap: { [key: string]: OPFItem } = null;\n itemMapByPath: { [key: string]: OPFItem } = null;\n uid: string | null = null;\n bindings: { [key: string]: string } = {};\n lang: string | null = null;\n epageCount: number = 0;\n prePaginated: boolean = false;\n epageIsRenderedPage: boolean = true;\n epageCountCallback: (p1: number) => void | null = null;\n metadata: Base.JSON = {};\n ncxToc: OPFItem = null;\n xhtmlToc: OPFItem = null;\n cover: OPFItem = null;\n fallbackMap: { [key: string]: string } = {};\n pageProgression: Constants.PageProgression | null = null;\n documentURLTransformer: Base.DocumentURLTransformer;\n\n constructor(\n public readonly store: EPUBDocStore,\n public readonly pubURL: string,\n ) {\n this.documentURLTransformer = this.createDocumentURLTransformer();\n checkMathJax();\n }\n\n // FIXME: TS4055\n createDocumentURLTransformer(): Base.DocumentURLTransformer {\n const self = this;\n class OPFDocumentURLTransformer implements Base.DocumentURLTransformer {\n /**\n * @override\n */\n transformFragment(fragment: string, baseURL: string): string {\n const url = baseURL + (fragment ? `#${fragment}` : \"\");\n return transformedIdPrefix + Base.escapeNameStrToHex(url, \":\");\n }\n\n /**\n * @override\n */\n transformURL(url: string, baseURL: string): string {\n const r = url.match(/^([^#]*)#?(.*)$/);\n if (r) {\n const path = r[1] || baseURL;\n const fragment = r[2];\n if (path) {\n if (self.items.some((item) => item.src === path)) {\n return `#${this.transformFragment(fragment, path)}`;\n }\n }\n }\n return url;\n }\n\n /**\n * @override\n */\n restoreURL(encoded: string): string[] {\n if (encoded.charAt(0) === \"#\") {\n encoded = encoded.substring(1);\n }\n if (encoded.indexOf(transformedIdPrefix) === 0) {\n encoded = encoded.substring(transformedIdPrefix.length);\n }\n const decoded = Base.unescapeStrFromHex(encoded, \":\");\n const r = decoded.match(/^([^#]*)#?(.*)$/);\n return r ? [r[1], r[2]] : [];\n }\n }\n return new OPFDocumentURLTransformer();\n }\n\n /**\n * Metadata is organized in the following way: fully-expanded property names\n * (with IRI prefixes prepended) point to an array of values. Array contains\n * at least one element. First element is primary and should be used by\n * default. Element values are objects have the following keys:\n * - \"v\" - item value as string,\n * - \"s\" - scheme,\n * - \"o\" - index in the order of appearing in the source,\n * - \"r\" - refinement submetadata (organized just like the top-level\n * metadata).\n */\n getMetadata(): Base.JSON {\n return this.metadata;\n }\n\n getPathFromURL(url: string): string | null {\n if (url.startsWith(\"data:\")) {\n return url === this.pubURL ? \"\" : url;\n }\n if (this.pubURL) {\n let epubBaseURL = Base.resolveURL(\"\", this.pubURL);\n if (url === epubBaseURL || url + \"/\" === epubBaseURL) {\n return \"\";\n }\n if (epubBaseURL.charAt(epubBaseURL.length - 1) != \"/\") {\n epubBaseURL += \"/\";\n }\n return url.substr(0, epubBaseURL.length) == epubBaseURL\n ? decodeURI(url.substr(epubBaseURL.length))\n : null;\n } else {\n return url;\n }\n }\n\n initWithXMLDoc(\n opfXML: XmlDoc.XMLDocHolder,\n encXML: XmlDoc.XMLDocHolder,\n zipMetadata: Base.JSON,\n manifestURL: string,\n ): Task.Result<any> {\n const self = this;\n this.opfXML = opfXML;\n this.encXML = encXML;\n const pkg = opfXML.doc().child(\"package\");\n const uidref = pkg.attribute(\"unique-identifier\")[0];\n if (uidref) {\n const uidElem = opfXML.getElement(`${opfXML.url}#${uidref}`);\n if (uidElem) {\n this.uid = uidElem.textContent.replace(/[ \\n\\r\\t]/g, \"\");\n }\n }\n const srcToFallbackId = {};\n this.items = pkg\n .child(\"manifest\")\n .child(\"item\")\n .asArray()\n .map((node) => {\n const item = new OPFItem();\n const elem = node as Element;\n item.initWithElement(elem, opfXML.url);\n const fallback = elem.getAttribute(\"fallback\");\n if (fallback && !supportedMediaTypes[item.mediaType]) {\n srcToFallbackId[item.src] = fallback;\n }\n if (!self.xhtmlToc && item.itemProperties[\"nav\"]) {\n self.xhtmlToc = item;\n }\n if (!self.cover && item.itemProperties[\"cover-image\"]) {\n self.cover = item;\n }\n return item;\n });\n this.itemMap = Base.indexArray(\n this.items,\n getOPFItemId as (p1: OPFItem) => string | null,\n );\n this.itemMapByPath = Base.indexArray(this.items, (item) =>\n self.getPathFromURL(item.src),\n );\n for (const src in srcToFallbackId) {\n let fallbackSrc = src;\n while (true) {\n const item = this.itemMap[srcToFallbackId[fallbackSrc]];\n if (!item) {\n break;\n }\n if (supportedMediaTypes[item.mediaType]) {\n this.fallbackMap[src] = item.src;\n break;\n }\n fallbackSrc = item.src;\n }\n }\n this.spine = pkg\n .child(\"spine\")\n .child(\"itemref\")\n .asArray()\n .map((node, index) => {\n const elem = node as Element;\n const id = elem.getAttribute(\"idref\");\n const item = self.itemMap[id as string];\n if (item) {\n item.itemRefElement = elem;\n item.spineIndex = index;\n }\n return item;\n });\n const tocAttr = pkg.child(\"spine\").attribute(\"toc\")[0];\n if (tocAttr) {\n this.ncxToc = this.itemMap[tocAttr];\n }\n const pageProgressionAttr = pkg\n .child(\"spine\")\n .attribute(\"page-progression-direction\")[0];\n if (pageProgressionAttr) {\n this.pageProgression = Constants.pageProgressionOf(pageProgressionAttr);\n }\n const idpfObfURLs = !encXML\n ? []\n : encXML\n .doc()\n .child(\"encryption\")\n .child(\"EncryptedData\")\n .predicate(\n XmlDoc.predicate.withChild(\n \"EncryptionMethod\",\n XmlDoc.predicate.withAttribute(\n \"Algorithm\",\n \"http://www.idpf.org/2008/embedding\",\n ),\n ),\n )\n .child(\"CipherData\")\n .child(\"CipherReference\")\n .attribute(\"URI\");\n const mediaTypeElems = pkg\n .child(\"bindings\")\n .child(\"mediaType\")\n .asArray() as Element[];\n for (let i = 0; i < mediaTypeElems.length; i++) {\n const handlerId = mediaTypeElems[i].getAttribute(\"handler\");\n const mediaType = mediaTypeElems[i].getAttribute(\"media-type\");\n if (mediaType && handlerId && this.itemMap[handlerId]) {\n this.bindings[mediaType] = this.itemMap[handlerId].src;\n }\n }\n this.metadata = readMetadata(\n pkg.child(\"metadata\"),\n pkg.attribute(\"prefix\")[0],\n );\n if (this.metadata[metaTerms.language]) {\n this.lang = this.metadata[metaTerms.language][0][\"v\"];\n }\n if (this.metadata[metaTerms.layout]) {\n this.prePaginated =\n this.metadata[metaTerms.layout][0][\"v\"] === \"pre-paginated\";\n }\n\n if (!zipMetadata) {\n if (idpfObfURLs.length > 0 && this.uid) {\n // Have to deobfuscate in JavaScript\n const deobfuscator = makeDeobfuscator(this.uid);\n for (let i = 0; i < idpfObfURLs.length; i++) {\n this.store.deobfuscators[this.pubURL + idpfObfURLs[i]] = deobfuscator;\n }\n }\n if (this.prePaginated) {\n this.assignAutoPages();\n }\n return Task.newResult(true);\n }\n const manifestText = new Base.StringBuffer();\n const obfuscations = {};\n if (idpfObfURLs.length > 0 && this.uid) {\n // Deobfuscate in the server.\n const obfuscationKey = makeObfuscationKey(this.uid);\n for (let i = 0; i < idpfObfURLs.length; i++) {\n obfuscations[idpfObfURLs[i]] = obfuscationKey;\n }\n }\n for (let i = 0; i < zipMetadata.length; i++) {\n const entry = zipMetadata[i];\n const encodedPath = entry[\"n\"];\n if (encodedPath) {\n const path = decodeURI(encodedPath);\n const item = this.itemMapByPath[path];\n let mediaType: string | null = null;\n if (item) {\n item.compressed = entry[\"m\"] != 0;\n item.compressedSize = entry[\"c\"];\n if (item.mediaType) {\n mediaType = item.mediaType.replace(/\\s+/g, \"\");\n }\n }\n const obfuscation = obfuscations[path];\n if (mediaType || obfuscation) {\n manifestText.append(encodedPath);\n manifestText.append(\" \");\n manifestText.append(mediaType || \"application/octet-stream\");\n if (obfuscation) {\n manifestText.append(\" \");\n manifestText.append(obfuscation);\n }\n manifestText.append(\"\\n\");\n }\n }\n }\n self.assignAutoPages();\n return Net.ajax(\n manifestURL,\n Net.XMLHttpRequestResponseType.DEFAULT,\n \"POST\",\n manifestText.toString(),\n \"text/plain\",\n );\n }\n\n assignAutoPages(): void {\n let epage = 0;\n for (const item of this.spine) {\n const epageCount = this.prePaginated\n ? 1\n : Math.ceil(item.compressedSize / 1024);\n item.epage = epage;\n item.epageCount = epageCount;\n epage += epageCount;\n }\n this.epageCount = epage;\n\n if (this.epageCountCallback) {\n this.epageCountCallback(this.epageCount);\n }\n }\n\n setEPageCountMode(epageIsRenderedPage: boolean) {\n this.epageIsRenderedPage = epageIsRenderedPage || this.prePaginated;\n }\n\n countEPages(\n epageCountCallback: ((p1: number) => void) | null,\n ): Task.Result<boolean> {\n this.epageCountCallback = epageCountCallback;\n\n if (this.epageIsRenderedPage) {\n if (this.prePaginated && this.epageCount == 0) {\n this.assignAutoPages();\n }\n return Task.newResult(true);\n }\n\n let epage = 0;\n let i = 0;\n const frame: Task.Frame<boolean> = Task.newFrame(\"countEPages\");\n frame\n .loopWithFrame((loopFrame) => {\n if (i === this.spine.length) {\n loopFrame.breakLoop();\n return;\n }\n const item = this.spine[i++];\n item.epage = epage;\n this.store.load(item.src).then((xmldoc) => {\n // According to the old comment,\n // \"Estimate that offset=2700 roughly corresponds to 1024 bytes of compressed size.\"\n // However, it should depend on the language.\n // Further adjustment needed.\n\n //let offsetPerEPage = 2700;\n let offsetPerEPage = 1800;\n const lang = xmldoc.lang || this.lang;\n if (lang && lang.match(/^(ja|ko|zh)/)) {\n offsetPerEPage /= 3;\n }\n item.epageCount = Math.ceil(xmldoc.getTotalOffset() / offsetPerEPage);\n epage += item.epageCount;\n this.epageCount = epage;\n if (this.epageCountCallback) {\n this.epageCountCallback(this.epageCount);\n }\n loopFrame.continueLoop();\n });\n })\n .thenFinish(frame);\n return frame.result();\n }\n\n /**\n * Creates a fake OPF \"document\" that contains OPS chapters.\n */\n initWithChapters(params: OPFItemParam[], doc?: Document | null) {\n this.itemMap = {};\n this.itemMapByPath = {};\n this.items = [];\n this.spine = this.items;\n\n // create a minimum fake OPF XML for navigation with EPUB CFI\n const opfXML = (this.opfXML = new XmlDoc.XMLDocHolder(\n null,\n \"\",\n new DOMParser().parseFromString(\"<spine></spine>\", \"text/xml\"),\n ));\n params.forEach((param) => {\n const item = new OPFItem();\n item.initWithParam(param);\n Asserts.assert(item.id);\n const itemref = opfXML.document.createElement(\"itemref\");\n itemref.setAttribute(\"idref\", item.id);\n opfXML.root.appendChild(itemref);\n item.itemRefElement = itemref;\n this.itemMap[item.id] = item;\n let path = this.getPathFromURL(param.url);\n if (path == null) {\n path = param.url;\n }\n this.itemMapByPath[path] = item;\n this.items.push(item);\n });\n if (doc) {\n return this.store.addDocument(params[0].url, doc);\n } else {\n return Task.newResult(null);\n }\n }\n\n initWithWebPubManifest(\n manifestObj: Base.JSON,\n doc?: Document,\n ): Task.Result<boolean> {\n if (manifestObj[\"readingProgression\"]) {\n this.pageProgression = manifestObj[\"readingProgression\"];\n }\n if (this.metadata === undefined) {\n this.metadata = {};\n }\n const title =\n (doc && doc.title) ||\n manifestObj[\"name\"] ||\n (manifestObj[\"metadata\"] && manifestObj[\"metadata\"][\"title\"]);\n if (title) {\n this.metadata[metaTerms.title] = [{ v: title }];\n }\n // TODO: other metadata...\n\n const primaryEntryPath = this.getPathFromURL(this.pubURL);\n if (!manifestObj[\"readingOrder\"] && doc && primaryEntryPath !== null) {\n manifestObj[\"readingOrder\"] = [encodeURI(primaryEntryPath)];\n\n // Find TOC in the primary entry (X)HTML\n const selector =\n \"[role=doc-toc] a[href],\" +\n \"[role=directory] a[href],\" +\n \"nav li a[href],\" +\n \".toc a[href],\" +\n \"#toc a[href]\";\n Array.from(doc.querySelectorAll(selector)).forEach((anchorElem) => {\n const hrefNoFragment = Base.stripFragment(\n Base.resolveURL(anchorElem.getAttribute(\"href\"), this.pubURL),\n );\n const path = this.getPathFromURL(hrefNoFragment);\n const url = path !== null ? encodeURI(path) : hrefNoFragment;\n if (manifestObj[\"readingOrder\"].indexOf(url) == -1) {\n manifestObj[\"readingOrder\"].push(url);\n }\n });\n }\n\n const params = [];\n let itemCount = 0;\n let tocFound = -1;\n [manifestObj[\"readingOrder\"], manifestObj[\"resources\"]].forEach(\n (readingOrderOrResources) => {\n if (readingOrderOrResources instanceof Array) {\n readingOrderOrResources.forEach((itemObj) => {\n const isInReadingOrder = manifestObj[\"readingOrder\"].includes(\n itemObj,\n );\n const url =\n typeof itemObj === \"string\"\n ? itemObj\n : itemObj.url || itemObj.href;\n const encodingFormat =\n typeof itemObj === \"string\"\n ? \"\"\n : itemObj.encodingFormat ||\n (itemObj.href && itemObj.type) ||\n \"\";\n if (\n isInReadingOrder ||\n encodingFormat === \"text/html\" ||\n encodingFormat === \"application/xhtml+xml\" ||\n /(^|\\/)([^/]+\\.(x?html|htm|xht)|[^/.]*)([#?]|$)/.test(url)\n ) {\n const param = {\n url: Base.resolveURL(Base.convertSpecialURL(url), this.pubURL),\n index: itemCount++,\n startPage: null,\n skipPagesBefore: null,\n };\n if (itemObj.rel === \"contents\" && tocFound === -1) {\n tocFound = param.index;\n }\n params.push(param);\n\n //TODO: items not in readingOrder should be excluded from linear reading but available with internal link navigation.\n }\n });\n }\n },\n );\n const frame: Task.Frame<boolean> = Task.newFrame(\"initWithWebPubManifest\");\n this.initWithChapters(params).then(() => {\n if (tocFound !== -1) {\n this.xhtmlToc = this.items[tocFound];\n }\n\n if (!this.xhtmlToc) {\n this.xhtmlToc = this.itemMapByPath[primaryEntryPath];\n }\n\n frame.finish(true);\n });\n return frame.result();\n }\n\n /**\n * @return cfi\n */\n getCFI(spineIndex: number, offsetInItem: number): Task.Result<string | null> {\n const item = this.spine[spineIndex];\n const frame: Task.Frame<string | null> = Task.newFrame(\"getCFI\");\n this.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n const node = xmldoc.getNodeByOffset(offsetInItem);\n let cfi: string | null = null;\n if (node) {\n const startOffset = xmldoc.getNodeOffset(node, 0, false);\n const offsetInNode = offsetInItem - startOffset;\n const fragment = new CFI.Fragment();\n fragment.prependPathFromNode(node, offsetInNode, false, null);\n if (item.itemRefElement) {\n fragment.prependPathFromNode(item.itemRefElement, 0, false, null);\n }\n cfi = fragment.toString();\n }\n frame.finish(cfi);\n });\n return frame.result();\n }\n\n resolveFragment(fragstr: string | null): Task.Result<Position | null> {\n const self = this;\n return Task.handle(\n \"resolveFragment\",\n (frame: Task.Frame<Position | null>): void => {\n if (!fragstr) {\n frame.finish(null);\n return;\n }\n let fragment = new CFI.Fragment();\n fragment.fromString(fragstr);\n let item: OPFItem;\n if (self.opfXML) {\n const opfNav = fragment.navigate(self.opfXML.document);\n if (opfNav.node.nodeType != 1 || opfNav.after || !opfNav.ref) {\n frame.finish(null);\n return;\n }\n const elem = opfNav.node as Element;\n const idref = elem.getAttribute(\"idref\");\n if (elem.localName != \"itemref\" || !idref || !self.itemMap[idref]) {\n frame.finish(null);\n return;\n }\n item = self.itemMap[idref];\n fragment = opfNav.ref;\n } else {\n item = self.spine[0];\n }\n self.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n const nodeNav = fragment.navigate(xmldoc.document);\n const offset = xmldoc.getNodeOffset(\n nodeNav.node,\n nodeNav.offset,\n nodeNav.after,\n );\n frame.finish({\n spineIndex: item.spineIndex,\n offsetInItem: offset,\n pageIndex: -1,\n });\n });\n },\n (frame: Task.Frame<Position | null>, err: Error): void => {\n Logging.logger.warn(err, \"Cannot resolve fragment:\", fragstr);\n frame.finish(null);\n },\n );\n }\n\n resolveEPage(epage: number): Task.Result<Position | null> {\n const self = this;\n return Task.handle(\n \"resolveEPage\",\n (frame: Task.Frame<Position | null>): void => {\n if (epage <= 0) {\n frame.finish({ spineIndex: 0, offsetInItem: 0, pageIndex: -1 });\n return;\n }\n if (self.epageIsRenderedPage) {\n let spineIndex = self.spine.findIndex((item) => {\n return (\n (item.epage == 0 && item.epageCount == 0) ||\n (item.epage <= epage && item.epage + item.epageCount > epage)\n );\n });\n if (spineIndex == -1) {\n spineIndex = self.spine.length - 1;\n }\n let item = self.spine[spineIndex];\n if (!item || item.epageCount == 0) {\n item = self.spine[--spineIndex];\n }\n const pageIndex = Math.floor(epage - item.epage);\n frame.finish({ spineIndex, offsetInItem: -1, pageIndex: pageIndex });\n return;\n }\n let spineIndex = Base.binarySearch(self.spine.length, (index) => {\n const item = self.spine[index];\n return item.epage + item.epageCount > epage;\n });\n if (spineIndex == self.spine.length) {\n spineIndex--;\n }\n const item = self.spine[spineIndex];\n self.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n epage -= item.epage;\n if (epage > item.epageCount) {\n epage = item.epageCount;\n }\n let offset = 0;\n if (epage > 0) {\n const totalOffset = xmldoc.getTotalOffset();\n offset = Math.round((totalOffset * epage) / item.epageCount);\n if (offset == totalOffset) {\n offset--;\n }\n }\n frame.finish({ spineIndex, offsetInItem: offset, pageIndex: -1 });\n });\n },\n (frame: Task.Frame<Position | null>, err: Error): void => {\n Logging.logger.warn(err, \"Cannot resolve epage:\", epage);\n frame.finish(null);\n },\n );\n }\n\n getEPageFromPosition(position: Position): Task.Result<number> {\n const item = this.spine[position.spineIndex];\n if (this.epageIsRenderedPage) {\n const epage = item.epage + position.pageIndex;\n return Task.newResult(epage);\n }\n if (position.offsetInItem <= 0) {\n return Task.newResult(item.epage);\n }\n const frame: Task.Frame<number> = Task.newFrame(\"getEPage\");\n this.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n const totalOffset = xmldoc.getTotalOffset();\n const offset = Math.min(totalOffset, position.offsetInItem);\n frame.finish(item.epage + (offset * item.epageCount) / totalOffset);\n });\n return frame.result();\n }\n}\n\nexport type PageAndPosition = {\n page: Vtree.Page;\n position: Position;\n};\n\nexport const makePageAndPosition = (\n page: Vtree.Page,\n pageIndex: number,\n): PageAndPosition => ({\n page,\n position: {\n spineIndex: page.spineIndex,\n pageIndex,\n offsetInItem: page.offset,\n },\n});\n\nexport type OPFViewItem = {\n item: OPFItem;\n xmldoc: XmlDoc.XMLDocHolder;\n instance: OPS.StyleInstance;\n layoutPositions: Vtree.LayoutPosition[];\n pages: Vtree.Page[];\n complete: boolean;\n};\n\nexport class OPFView implements Vgen.CustomRendererFactory {\n spineItems: OPFViewItem[] = [];\n spineItemLoadingContinuations: Task.Continuation<any>[][] = [];\n pref: Exprs.Preferences;\n clientLayout: Vgen.DefaultClientLayout;\n counterStore: Counters.CounterStore;\n tocAutohide: boolean = false;\n tocView?: Toc.TOCView;\n\n constructor(\n public readonly opf: OPFDoc,\n public readonly viewport: Vgen.Viewport,\n public readonly fontMapper: Font.Mapper,\n pref: Exprs.Preferences,\n public readonly pageSheetSizeReporter: (\n p1: { width: number; height: number },\n p2: { [key: string]: { width: number; height: number } },\n p3: number,\n p4: number,\n ) => any,\n ) {\n this.pref = Exprs.clonePreferences(pref);\n this.clientLayout = new Vgen.DefaultClientLayout(viewport);\n this.counterStore = new Counters.CounterStore(opf.documentURLTransformer);\n }\n\n private getPage(position: Position): Vtree.Page {\n const viewItem = this.spineItems[position.spineIndex];\n return viewItem ? viewItem.pages[position.pageIndex] : null;\n }\n\n getCurrentPageProgression(\n position: Position,\n ): Constants.PageProgression | null {\n if (this.opf.pageProgression) {\n return this.opf.pageProgression;\n } else {\n const viewItem = this.spineItems[position ? position.spineIndex : 0];\n return viewItem ? viewItem.instance.pageProgression : null;\n }\n }\n\n private finishPageContainer(\n viewItem: OPFViewItem,\n page: Vtree.Page,\n pageIndex: number,\n ) {\n page.container.style.display = \"none\";\n page.container.style.visibility = \"visible\";\n page.container.style.position = \"\";\n page.container.style.top = \"\";\n page.container.style.left = \"\";\n page.container.setAttribute(\n \"data-vivliostyle-page-side\",\n page.side as string,\n );\n const oldPage = viewItem.pages[pageIndex];\n page.isFirstPage = viewItem.item.spineIndex == 0 && pageIndex == 0;\n viewItem.pages[pageIndex] = page;\n\n if (this.opf.epageIsRenderedPage) {\n if (pageIndex == 0 && viewItem.item.spineIndex > 0) {\n const prevItem = this.opf.spine[viewItem.item.spineIndex - 1];\n viewItem.item.epage = prevItem.epage + prevItem.epageCount;\n }\n viewItem.item.epageCount = viewItem.pages.length;\n this.opf.epageCount = this.opf.spine.reduce(\n (count, item) => count + item.epageCount,\n 0,\n );\n\n if (this.opf.epageCountCallback) {\n this.opf.epageCountCallback(this.opf.epageCount);\n }\n }\n\n if (oldPage) {\n viewItem.instance.viewport.contentContainer.replaceChild(\n page.container,\n oldPage.container,\n );\n oldPage.dispatchEvent({\n type: \"replaced\",\n target: null,\n currentTarget: null,\n preventDefault: null,\n newPage: page,\n });\n } else {\n // Find insert position in contentContainer.\n let insertPos: Element | null = null;\n if (pageIndex > 0) {\n insertPos = viewItem.pages[pageIndex - 1].container.nextElementSibling;\n } else {\n for (\n let i = viewItem.item.spineIndex + 1;\n i < this.spineItems.length;\n i++\n ) {\n const item = this.spineItems[i];\n if (item && item.pages[0]) {\n insertPos = item.pages[0].container;\n break;\n }\n }\n }\n viewItem.instance.viewport.contentContainer.insertBefore(\n page.container,\n insertPos,\n );\n }\n this.pageSheetSizeReporter(\n {\n width: viewItem.instance.pageSheetWidth,\n height: viewItem.instance.pageSheetHeight,\n },\n viewItem.instance.pageSheetSize,\n viewItem.item.spineIndex,\n viewItem.instance.pageNumberOffset + pageIndex,\n );\n }\n\n /**\n * Render a single page. If the new page contains elements with ids that are\n * referenced from other pages by 'target-counter()', those pages are rendered\n * too (calling `renderSinglePage` recursively).\n */\n private renderSinglePage(\n viewItem: OPFViewItem,\n pos: Vtree.LayoutPosition,\n ): Task.Result<RenderSinglePageResult> {\n const frame: Task.Frame<RenderSinglePageResult> = Task.newFrame(\n \"renderSinglePage\",\n );\n let page = this.makePage(viewItem, pos);\n const self = this;\n viewItem.instance.layoutNextPage(page, pos).then((posParam) => {\n pos = posParam as Vtree.LayoutPosition;\n const pageIndex = pos\n ? pos.page - 1\n : viewItem.layoutPositions.length - 1;\n self.finishPageContainer(viewItem, page, pageIndex);\n self.counterStore.finishPage(page.spineIndex, pageIndex);\n\n // If the position of the page break change, we should re-layout the next\n // page too.\n let cont: Task.Result<any> = null;\n if (pos) {\n const prevPos = viewItem.layoutPositions[pos.page];\n viewItem.layoutPositions[pos.page] = pos;\n if (prevPos && viewItem.pages[pos.page]) {\n if (!pos.isSamePosition(prevPos)) {\n cont = self.renderSinglePage(viewItem, pos);\n }\n }\n }\n if (!cont) {\n cont = Task.newResult(true);\n }\n cont.then(() => {\n const unresolvedRefs = self.counterStore.getUnresolvedRefsToPage(page);\n let index = 0;\n frame\n .loopWithFrame((loopFrame) => {\n index++;\n if (index > unresolvedRefs.length) {\n loopFrame.breakLoop();\n return;\n }\n const refs = unresolvedRefs[index - 1];\n refs.refs = refs.refs.filter((ref) => !ref.isResolved());\n if (refs.refs.length === 0) {\n loopFrame.continueLoop();\n return;\n }\n self.getPageViewItem(refs.spineIndex).then((viewItem) => {\n if (!viewItem) {\n loopFrame.continueLoop();\n return;\n }\n self.counterStore.pushPageCounters(refs.pageCounters);\n self.counterStore.pushReferencesToSolve(refs.refs);\n const pos = viewItem.layoutPositions[refs.pageIndex];\n self.renderSinglePage(viewItem, pos).then((result) => {\n self.counterStore.popPageCounters();\n self.counterStore.popReferencesToSolve();\n const resultPosition = result.pageAndPosition.position;\n if (\n resultPosition.spineIndex === page.spineIndex &&\n resultPosition.pageIndex === pageIndex\n ) {\n page = result.pageAndPosition.page;\n }\n loopFrame.continueLoop();\n });\n });\n })\n .then(() => {\n if (!page.container.parentElement) {\n // page is replaced\n page = viewItem.pages[pageIndex];\n }\n page.isLastPage =\n !pos && viewItem.item.spineIndex === self.opf.spine.length - 1;\n if (page.isLastPage) {\n Asserts.assert(self.viewport);\n self.counterStore.finishLastPage(self.viewport);\n }\n frame.finish({\n pageAndPosition: makePageAndPosition(page, pageIndex),\n nextLayoutPosition: pos,\n });\n });\n });\n });\n return frame.result();\n }\n\n private normalizeSeekPosition(\n position: Position,\n viewItem: OPFViewItem,\n ): Position | null {\n let pageIndex = position.pageIndex;\n let seekOffset = -1;\n if (pageIndex < 0) {\n seekOffset = position.offsetInItem;\n\n // page with offset higher than seekOffset\n const seekOffsetPageIndex = Base.binarySearch(\n viewItem.layoutPositions.length,\n (pageIndex) => {\n // 'noLookAhead' argument of getPosition must be true, since\n // otherwise StyleInstance.currentLayoutPosition is modified\n // unintentionally.\n const offset = viewItem.instance.getPosition(\n viewItem.layoutPositions[pageIndex],\n true,\n );\n return offset > seekOffset;\n },\n );\n if (seekOffsetPageIndex === viewItem.layoutPositions.length) {\n if (viewItem.complete) {\n pageIndex = viewItem.layoutPositions.length - 1;\n } else {\n // need to search through pages that are not yet produced\n pageIndex = Number.POSITIVE_INFINITY;\n }\n } else {\n // page that contains seekOffset\n pageIndex = seekOffsetPageIndex - 1;\n }\n } else if (\n pageIndex === Number.POSITIVE_INFINITY &&\n position.offsetInItem !== -1\n ) {\n seekOffset = position.offsetInItem;\n }\n return {\n spineIndex: position.spineIndex,\n pageIndex,\n offsetInItem: seekOffset,\n } as Position;\n }\n\n /**\n * Find a page corresponding to a specified position among already laid out\n * pages.\n * @param sync If true, find the page synchronously (not waiting another\n * rendering task)\n */\n private findPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const self = this;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\"findPage\");\n self.getPageViewItem(position.spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n let resultPage: Vtree.Page = null;\n let pageIndex: number;\n frame\n .loopWithFrame((loopFrame) => {\n const normalizedPosition = self.normalizeSeekPosition(\n position,\n viewItem,\n );\n pageIndex = normalizedPosition.pageIndex;\n resultPage = viewItem.pages[pageIndex];\n if (resultPage) {\n loopFrame.breakLoop();\n } else if (viewItem.complete) {\n pageIndex = viewItem.layoutPositions.length - 1;\n resultPage = viewItem.pages[pageIndex];\n loopFrame.breakLoop();\n } else if (sync) {\n self.renderPage(normalizedPosition).then((result) => {\n if (result) {\n resultPage = result.page;\n pageIndex = result.position.pageIndex;\n }\n loopFrame.breakLoop();\n });\n } else {\n // Wait for the layout task and retry\n frame.sleep(100).then(() => {\n loopFrame.continueLoop();\n });\n }\n })\n .then(() => {\n Asserts.assert(resultPage);\n frame.finish(makePageAndPosition(resultPage, pageIndex));\n });\n });\n return frame.result();\n }\n\n /**\n * Renders a page at the specified position.\n */\n renderPage(position: Position): Task.Result<PageAndPosition | null> {\n const self = this;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"renderPage\",\n );\n self.getPageViewItem(position.spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n const normalizedPosition = self.normalizeSeekPosition(position, viewItem);\n let pageIndex = normalizedPosition.pageIndex;\n const seekOffset = normalizedPosition.offsetInItem;\n let resultPage = viewItem.pages[pageIndex];\n if (resultPage) {\n frame.finish(makePageAndPosition(resultPage, pageIndex));\n return;\n }\n frame\n .loopWithFrame((loopFrame) => {\n if (pageIndex < viewItem.layoutPositions.length) {\n loopFrame.breakLoop();\n return;\n }\n if (viewItem.complete) {\n pageIndex = viewItem.layoutPositions.length - 1;\n loopFrame.breakLoop();\n return;\n }\n let pos =\n viewItem.layoutPositions[viewItem.layoutPositions.length - 1];\n self.renderSinglePage(viewItem, pos).then((result) => {\n const page = result.pageAndPosition.page;\n pos = result.nextLayoutPosition;\n if (pos) {\n if (seekOffset >= 0) {\n // Searching for offset, don't know the page number.\n const offset = viewItem.instance.getPosition(pos);\n if (offset > seekOffset) {\n resultPage = page;\n pageIndex = viewItem.layoutPositions.length - 2;\n loopFrame.breakLoop();\n return;\n }\n }\n loopFrame.continueLoop();\n } else {\n resultPage = page;\n pageIndex = result.pageAndPosition.position.pageIndex;\n viewItem.complete = true;\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n resultPage = resultPage || viewItem.pages[pageIndex];\n const pos = viewItem.layoutPositions[pageIndex];\n if (resultPage) {\n frame.finish(makePageAndPosition(resultPage, pageIndex));\n return;\n }\n self.renderSinglePage(viewItem, pos).then((result) => {\n if (!result.nextLayoutPosition) {\n viewItem.complete = true;\n }\n frame.finish(result.pageAndPosition);\n });\n });\n });\n return frame.result();\n }\n\n renderAllPages(): Task.Result<PageAndPosition | null> {\n return this.renderPagesUpto(\n {\n spineIndex: this.opf.spine.length - 1,\n pageIndex: Number.POSITIVE_INFINITY,\n offsetInItem: -1,\n },\n false,\n );\n }\n\n /**\n * Render pages from (spineIndex=0, pageIndex=0) to the specified (spineIndex,\n * pageIndex).\n * @param notAllPages If true, render from biginning of specified spine item.\n */\n renderPagesUpto(\n position: Position,\n notAllPages: boolean,\n ): Task.Result<PageAndPosition | null> {\n const self = this;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"renderPagesUpto\",\n );\n if (!position) {\n position = { spineIndex: 0, pageIndex: 0, offsetInItem: 0 };\n }\n const spineIndex = position.spineIndex;\n const pageIndex = position.pageIndex;\n let s = 0;\n\n if (notAllPages) {\n // Render pages from biginning of specified spine item.\n s = spineIndex;\n }\n\n let lastResult: PageAndPosition;\n frame\n .loopWithFrame((loopFrame) => {\n const pos = {\n spineIndex: s,\n pageIndex: s === spineIndex ? pageIndex : Number.POSITIVE_INFINITY,\n offsetInItem: s === spineIndex ? position.offsetInItem : -1,\n };\n self.renderPage(pos).then((result) => {\n lastResult = result;\n if (++s > spineIndex) {\n loopFrame.breakLoop();\n } else {\n loopFrame.continueLoop();\n }\n });\n })\n .then(() => {\n frame.finish(lastResult);\n });\n return frame.result();\n }\n\n /**\n * Move to the first page and render it.\n */\n firstPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n return this.findPage(\n { spineIndex: 0, pageIndex: 0, offsetInItem: -1 },\n sync,\n );\n }\n\n /**\n * Move to the last page and render it.\n */\n lastPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n return this.findPage(\n {\n spineIndex: this.opf.spine.length - 1,\n pageIndex: Number.POSITIVE_INFINITY,\n offsetInItem: -1,\n },\n sync,\n );\n }\n\n /**\n * Move to the next page position and render page.\n * @param sync If true, get the page synchronously (not waiting another\n * rendering task)\n */\n nextPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const self = this;\n let spineIndex = position.spineIndex;\n let pageIndex = position.pageIndex;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\"nextPage\");\n self.getPageViewItem(spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n if (\n viewItem.complete &&\n pageIndex == viewItem.layoutPositions.length - 1\n ) {\n if (spineIndex >= self.opf.spine.length - 1) {\n frame.finish(null);\n return;\n }\n spineIndex++;\n pageIndex = 0;\n\n // Remove next viewItem if its first page has same side as the current page\n // to avoid unpaired page.\n const nextViewItem = this.spineItems[spineIndex];\n const nextPage = nextViewItem && nextViewItem.pages[0];\n const currentPage = viewItem.pages[viewItem.pages.length - 1];\n if (nextPage && currentPage && nextPage.side == currentPage.side) {\n nextViewItem.pages.forEach((page) => {\n if (page.container) page.container.remove();\n });\n this.spineItems[spineIndex] = null;\n this.spineItemLoadingContinuations[spineIndex] = null;\n }\n } else {\n pageIndex++;\n }\n self\n .findPage({ spineIndex, pageIndex, offsetInItem: -1 }, sync)\n .thenFinish(frame);\n });\n return frame.result();\n }\n\n /**\n * Move to the previous page and render it.\n */\n previousPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n let spineIndex = position.spineIndex;\n let pageIndex = position.pageIndex;\n if (pageIndex == 0) {\n if (spineIndex == 0) {\n return Task.newResult(null as PageAndPosition | null);\n }\n spineIndex--;\n pageIndex = Number.POSITIVE_INFINITY;\n } else {\n pageIndex--;\n }\n return this.findPage({ spineIndex, pageIndex, offsetInItem: -1 }, sync);\n }\n\n /**\n * @param page This page should be a currently displayed page.\n */\n private isRectoPage(page: Vtree.Page, position: Position): boolean {\n const isLeft = page.side === Constants.PageSide.LEFT;\n const isLTR =\n this.getCurrentPageProgression(position) ===\n Constants.PageProgression.LTR;\n return (!isLeft && isLTR) || (isLeft && !isLTR);\n }\n\n /**\n * Get a spread containing the currently displayed page.\n * @param sync If true, get the spread synchronously (not waiting another\n * rendering task)\n */\n getSpread(position: Position, sync: boolean): Task.Result<Vtree.Spread> {\n const frame: Task.Frame<Vtree.Spread> = Task.newFrame(\"getCurrentSpread\");\n const page = this.getPage(position);\n if (!page) {\n return Task.newResult(\n /** @type Vtree.Spread */\n { left: null, right: null } as Vtree.Spread,\n );\n }\n const isLeft = page.side === Constants.PageSide.LEFT;\n let other: Task.Result<PageAndPosition>;\n if (this.isRectoPage(page, position)) {\n other = this.previousPage(position, sync);\n } else {\n other = this.nextPage(position, sync);\n }\n other.then((otherPageAndPosition) => {\n // this page may be replaced during nextPage(), so get thisPage again.\n const thisPage = this.getPage(position);\n\n let otherPage = otherPageAndPosition && otherPageAndPosition.page;\n if (otherPage && otherPage.side === thisPage.side) {\n // otherPage must not be same side\n otherPage = null;\n }\n\n if (isLeft) {\n frame.finish({ left: thisPage, right: otherPage });\n } else {\n frame.finish({ left: otherPage, right: thisPage });\n }\n });\n return frame.result();\n }\n\n /**\n * Move to the next spread and render pages.\n * @param sync If true, get the spread synchronously (not waiting another\n * rendering task)\n * @returns The 'verso' page of the next spread.\n */\n nextSpread(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const page = this.getPage(position);\n if (!page) {\n return Task.newResult(null as PageAndPosition | null);\n }\n const isRecto = this.isRectoPage(page, position);\n const next = this.nextPage(position, sync);\n if (isRecto) {\n return next;\n } else {\n const self = this;\n return next.thenAsync((result) => {\n if (result) {\n if (result.page.side === page.side) {\n // If same side, this is the next spread.\n return next;\n }\n const next2 = self.nextPage(result.position, sync);\n return next2.thenAsync((result2) => {\n if (result2) {\n return next2;\n } else {\n // If this is tha last spread, move to next page in the same spread.\n return next;\n }\n });\n } else {\n return Task.newResult(null as PageAndPosition | null);\n }\n });\n }\n }\n\n /**\n * Move to the previous spread and render pages.\n * @returns The 'recto' page of the previous spread.\n */\n previousSpread(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const page = this.getPage(position);\n if (!page) {\n return Task.newResult(null as PageAndPosition | null);\n }\n const isRecto = this.isRectoPage(page, position);\n const prev = this.previousPage(position, sync);\n const oldPrevPageCont = page.container.previousElementSibling;\n if (isRecto) {\n const self = this;\n return prev.thenAsync((result) => {\n if (result) {\n if (result.page.side === page.side) {\n // If same side, this is the previous spread.\n return prev;\n }\n if (result.page.container !== oldPrevPageCont) {\n // If previous page is changed, return it.\n return prev;\n }\n return self.previousPage(result.position, sync);\n } else {\n return Task.newResult(null as PageAndPosition | null);\n }\n });\n } else {\n return prev;\n }\n }\n\n /**\n * Move to the epage specified by the given number (zero-based) and render it.\n */\n navigateToEPage(\n epage: number,\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"navigateToEPage\",\n );\n const self = this;\n this.opf.resolveEPage(epage).then((position) => {\n if (position) {\n self.findPage(position, sync).thenFinish(frame);\n } else {\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n /**\n * Move to the page specified by the given CFI and render it.\n */\n navigateToFragment(\n fragment: string,\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"navigateToCFI\",\n );\n const self = this;\n self.opf.resolveFragment(fragment).then((position) => {\n if (position) {\n self.findPage(position, sync).thenFinish(frame);\n } else {\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n /**\n * Move to the page specified by the given URL and render it.\n */\n navigateTo(\n href: string,\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n Logging.logger.debug(\"Navigate to\", href);\n let path = this.opf.getPathFromURL(Base.stripFragment(href));\n if (!path) {\n if (this.opf.opfXML && href.match(/^#epubcfi\\(/)) {\n // CFI fragment is \"relative\" to OPF.\n path = this.opf.getPathFromURL(this.opf.opfXML.url);\n } else if (href.charAt(0) === \"#\") {\n const restored = this.opf.documentURLTransformer.restoreURL(href);\n if (this.opf.opfXML) {\n path = this.opf.getPathFromURL(restored[0]);\n if (path == null) {\n path = restored[0];\n }\n } else {\n path = restored[0];\n }\n href = restored[0] + (restored[1] ? `#${restored[1]}` : \"\");\n }\n if (path == null) {\n return Task.newResult(null as PageAndPosition | null);\n }\n }\n const item = this.opf.itemMapByPath[path];\n if (!item) {\n if (\n this.opf.opfXML &&\n path == this.opf.getPathFromURL(this.opf.opfXML.url)\n ) {\n // CFI link?\n const fragmentIndex = href.indexOf(\"#\");\n if (fragmentIndex >= 0) {\n return this.navigateToFragment(\n href.substr(fragmentIndex + 1),\n position,\n sync,\n );\n }\n }\n return Task.newResult(null as PageAndPosition | null);\n }\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"navigateTo\",\n );\n const self = this;\n self.getPageViewItem(item.spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n const target = viewItem.xmldoc.getElement(href);\n if (target) {\n self\n .findPage(\n {\n spineIndex: item.spineIndex,\n pageIndex: -1,\n offsetInItem: viewItem.xmldoc.getElementOffset(target),\n },\n sync,\n )\n .thenFinish(frame);\n } else if (position.spineIndex !== item.spineIndex) {\n // no fragment, different spine item\n self\n .findPage(\n {\n spineIndex: item.spineIndex,\n pageIndex: 0,\n offsetInItem: -1,\n },\n sync,\n )\n .thenFinish(frame);\n } else {\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n makePage(viewItem: OPFViewItem, pos: Vtree.LayoutPosition): Vtree.Page {\n const viewport = viewItem.instance.viewport;\n const pageCont = viewport.document.createElement(\"div\") as HTMLElement;\n pageCont.setAttribute(\"data-vivliostyle-page-container\", \"true\");\n pageCont.setAttribute(\"role\", \"region\");\n pageCont.style.position = \"absolute\";\n pageCont.style.top = \"0\";\n pageCont.style.left = \"0\";\n if (!Constants.isDebug) {\n pageCont.style.visibility = \"hidden\";\n pageCont.setAttribute(\"aria-hidden\", \"true\");\n }\n viewport.layoutBox.appendChild(pageCont);\n const bleedBox = viewport.document.createElement(\"div\") as HTMLElement;\n bleedBox.setAttribute(\"data-vivliostyle-bleed-box\", \"true\");\n pageCont.appendChild(bleedBox);\n const page = new Vtree.Page(pageCont, bleedBox);\n page.spineIndex = viewItem.item.spineIndex;\n page.position = pos;\n page.offset = viewItem.instance.getPosition(pos);\n if (page.offset === 0) {\n const id = this.opf.documentURLTransformer.transformFragment(\n \"\",\n viewItem.item.src,\n );\n bleedBox.setAttribute(\"id\", id);\n page.registerElementWithId(bleedBox, id);\n }\n if (viewport !== this.viewport) {\n const matrix = Exprs.letterbox(\n this.viewport.width,\n this.viewport.height,\n viewport.width,\n viewport.height,\n );\n const cssMatrix = CssParser.parseValue(\n null,\n new CssTokenizer.Tokenizer(matrix, null),\n \"\",\n );\n page.delayedItems.push(\n new Vtree.DelayedItem(pageCont, \"transform\", cssMatrix),\n );\n }\n return page;\n }\n\n makeObjectView(\n xmldoc: XmlDoc.XMLDocHolder,\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> {\n let data = srcElem.getAttribute(\"data\");\n let result: Element | null = null;\n if (data) {\n data = Base.resolveURL(data, xmldoc.url);\n let mediaType = srcElem.getAttribute(\"media-type\");\n if (!mediaType) {\n const path = this.opf.getPathFromURL(data);\n if (path) {\n const item = this.opf.itemMapByPath[path];\n if (item) {\n mediaType = item.mediaType;\n }\n }\n }\n if (mediaType) {\n const handlerSrc = this.opf.bindings[mediaType];\n if (handlerSrc) {\n result = this.viewport.document.createElement(\"iframe\");\n (result as HTMLElement).style.border = \"none\";\n const srcParam = Base.lightURLEncode(data);\n const typeParam = Base.lightURLEncode(mediaType);\n const sb = new Base.StringBuffer();\n sb.append(handlerSrc);\n sb.append(\"?src=\");\n sb.append(srcParam);\n sb.append(\"&type=\");\n sb.append(typeParam);\n for (let c: Node = srcElem.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1) {\n const ce = c as Element;\n if (ce.localName == \"param\" && ce.namespaceURI == Base.NS.XHTML) {\n const pname = ce.getAttribute(\"name\");\n const pvalue = ce.getAttribute(\"value\");\n if (pname && pvalue) {\n sb.append(\"&\");\n sb.append(encodeURIComponent(pname));\n sb.append(\"=\");\n sb.append(encodeURIComponent(pvalue));\n }\n }\n }\n }\n result.setAttribute(\"src\", sb.toString());\n const width = srcElem.getAttribute(\"width\");\n if (width) {\n result.setAttribute(\"width\", width);\n }\n const height = srcElem.getAttribute(\"height\");\n if (height) {\n result.setAttribute(\"height\", height);\n }\n }\n }\n }\n if (!result) {\n result = this.viewport.document.createElement(\"span\");\n result.setAttribute(\"data-adapt-process-children\", \"true\");\n }\n\n // Need to cast because we need {Element}, not {!Element}\n return Task.newResult(result as Element);\n }\n\n makeMathJaxView(\n xmldoc: XmlDoc.XMLDocHolder,\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> {\n // See if MathJax installed, use it if it is.\n const hub = getMathJaxHub();\n if (hub) {\n const doc = viewParent.ownerDocument;\n const span = doc.createElement(\"span\");\n viewParent.appendChild(span);\n const clonedMath = doc.importNode(srcElem, true);\n this.resolveURLsInMathML(clonedMath, xmldoc);\n span.appendChild(clonedMath);\n const queue = hub[\"queue\"];\n queue[\"Push\"]([\"Typeset\", hub, span]);\n const frame: Task.Frame<Element> = Task.newFrame(\"makeMathJaxView\");\n const continuation = frame.suspend();\n queue[\"Push\"](() => {\n continuation.schedule(span);\n });\n return frame.result();\n }\n return Task.newResult(null as Element);\n }\n\n private resolveURLsInMathML(node: Node, xmldoc: XmlDoc.XMLDocHolder) {\n if (node == null) {\n return;\n }\n if (node.nodeType === 1 && (node as Element).tagName === \"mglyph\") {\n const attrs = Array.from((node as Element).attributes);\n for (const attr of attrs) {\n if (attr.name !== \"src\") {\n continue;\n }\n const newUrl = Base.resolveURL(attr.nodeValue, xmldoc.url);\n if (attr.namespaceURI) {\n (node as Element).setAttributeNS(\n attr.namespaceURI,\n attr.name,\n newUrl,\n );\n } else {\n (node as Element).setAttribute(attr.name, newUrl);\n }\n }\n }\n if (node.firstChild) {\n this.resolveURLsInMathML(node.firstChild, xmldoc);\n }\n if (node.nextSibling) {\n this.resolveURLsInMathML(node.nextSibling, xmldoc);\n }\n }\n\n // TODO move makeSSEView to a more appropriate class (SSE XML content is not\n // allowed in EPUB)\n /**\n * @param computedStyle\n */\n makeSSEView(\n xmldoc: XmlDoc.XMLDocHolder,\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> {\n const doc = viewParent ? viewParent.ownerDocument : this.viewport.document;\n const srcTagName = srcElem.localName;\n let tagName: string;\n switch (srcTagName) {\n case \"t\":\n case \"tab\":\n case \"ec\":\n case \"nt\":\n case \"fraction\":\n case \"comment\":\n case \"mark\":\n tagName = \"span\";\n break;\n case \"ruby\":\n case \"rp\":\n case \"rt\":\n tagName = srcTagName;\n break;\n default:\n tagName = \"div\";\n }\n const result = doc.createElement(tagName);\n result.setAttribute(\"data-adapt-process-children\", \"true\");\n\n // Need to cast because we need {Element}, not {!Element}\n return Task.newResult(result as Element);\n }\n\n /**\n * @override\n */\n makeCustomRenderer(xmldoc: XmlDoc.XMLDocHolder): Vgen.CustomRenderer {\n const self = this;\n return (\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> => {\n if (\n srcElem.localName == \"object\" &&\n srcElem.namespaceURI == Base.NS.XHTML\n ) {\n return self.makeObjectView(xmldoc, srcElem, viewParent, computedStyle);\n } else if (srcElem.namespaceURI == Base.NS.MATHML) {\n return self.makeMathJaxView(xmldoc, srcElem, viewParent, computedStyle);\n } else if (srcElem.namespaceURI == Base.NS.SSE) {\n return self.makeSSEView(xmldoc, srcElem, viewParent, computedStyle);\n } else if (\n (srcElem as HTMLElement).dataset &&\n (srcElem as HTMLElement).dataset[\"mathTypeset\"] == \"true\"\n ) {\n return self.makeMathJaxView(xmldoc, srcElem, viewParent, computedStyle);\n }\n return Task.newResult(null as Element);\n };\n }\n\n getPageViewItem(spineIndex: number): Task.Result<OPFViewItem> {\n const self = this;\n if (spineIndex === -1 || spineIndex >= self.opf.spine.length) {\n return Task.newResult(null as OPFViewItem);\n }\n let viewItem = self.spineItems[spineIndex];\n if (viewItem) {\n return Task.newResult(viewItem);\n }\n const frame: Task.Frame<OPFViewItem> = Task.newFrame(\"getPageViewItem\");\n\n // If loading for the item has already been started, suspend and wait for\n // the result.\n let loadingContinuations = this.spineItemLoadingContinuations[spineIndex];\n if (loadingContinuations) {\n const cont = frame.suspend();\n loadingContinuations.push(cont);\n return frame.result();\n } else {\n loadingContinuations = this.spineItemLoadingContinuations[\n spineIndex\n ] = [];\n }\n const item = self.opf.spine[spineIndex];\n const store = self.opf.store;\n store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n item.title = xmldoc.document.title;\n const style = store.getStyleForDoc(xmldoc);\n const customRenderer = self.makeCustomRenderer(xmldoc);\n let viewport = self.viewport;\n const viewportSize = style.sizeViewport(\n viewport.width,\n viewport.height,\n viewport.fontSize,\n self.pref,\n );\n if (\n viewportSize.width != viewport.width ||\n viewportSize.height != viewport.height ||\n viewportSize.fontSize != viewport.fontSize\n ) {\n viewport = new Vgen.Viewport(\n viewport.window,\n viewportSize.fontSize,\n viewport.root,\n viewportSize.width,\n viewportSize.height,\n );\n }\n const previousViewItem = self.spineItems[spineIndex - 1];\n let pageNumberOffset: number;\n if (item.startPage !== null) {\n pageNumberOffset = item.startPage - 1;\n } else {\n if (\n spineIndex > 0 &&\n (!previousViewItem || !previousViewItem.complete)\n ) {\n // When navigate to a new spine item skipping the previous items,\n // give up calculate pageNumberOffset and use epage (or spineIndex if epage is unset).\n pageNumberOffset = item.epage || spineIndex;\n if (!self.opf.prePaginated && pageNumberOffset % 2 == 0) {\n // Force to odd number to avoid unpaired page. (This is 0 based and even number is recto)\n pageNumberOffset++;\n }\n } else {\n pageNumberOffset = previousViewItem\n ? previousViewItem.instance.pageNumberOffset +\n previousViewItem.pages.length\n : 0;\n }\n if (item.skipPagesBefore !== null) {\n pageNumberOffset += item.skipPagesBefore;\n }\n }\n self.counterStore.forceSetPageCounter(pageNumberOffset);\n const instance = new OPS.StyleInstance(\n style,\n xmldoc,\n self.opf.lang,\n viewport,\n self.clientLayout,\n self.fontMapper,\n customRenderer,\n self.opf.fallbackMap,\n pageNumberOffset,\n self.opf.documentURLTransformer,\n self.counterStore,\n self.opf.pageProgression,\n );\n instance.pref = self.pref;\n\n // For env(pub-title) and env(doc-title)\n const pubTitles = self.opf.metadata && self.opf.metadata[metaTerms.title];\n instance.pubTitle =\n (pubTitles && pubTitles[0] && pubTitles[0][\"v\"]) || \"\";\n instance.docTitle = item.title || \"\";\n\n instance.init().then(() => {\n viewItem = {\n item,\n xmldoc,\n instance,\n layoutPositions: [null],\n pages: [],\n complete: false,\n };\n self.spineItems[spineIndex] = viewItem;\n frame.finish(viewItem);\n loadingContinuations.forEach((c) => {\n c.schedule(viewItem);\n });\n });\n });\n return frame.result();\n }\n\n removeRenderedPages() {\n const items = this.spineItems;\n for (const item of items) {\n if (item) {\n item.pages.splice(0);\n }\n }\n this.viewport.clear();\n }\n\n /**\n * Returns if at least one page has 'auto' size\n */\n hasAutoSizedPages(): boolean {\n const items = this.spineItems;\n for (const item of items) {\n if (item) {\n const pages = item.pages;\n for (const page of pages) {\n if (page.isAutoPageWidth && page.isAutoPageHeight) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n hasPages(): boolean {\n return this.spineItems.some((item) => item && item.pages.length > 0);\n }\n\n showTOC(autohide: boolean): Task.Result<Vtree.Page> {\n const opf = this.opf;\n const toc = opf.xhtmlToc || opf.ncxToc;\n this.tocAutohide = autohide;\n if (!toc) {\n return Task.newResult(null as Vtree.Page);\n }\n if (this.tocView && this.tocView.page) {\n this.tocView.page.container.style.visibility = \"visible\";\n this.tocView.page.container.setAttribute(\"aria-hidden\", \"false\");\n return Task.newResult(this.tocView.page);\n }\n const frame: Task.Frame<Vtree.Page> = Task.newFrame(\"showTOC\");\n if (!this.tocView) {\n this.tocView = new Toc.TOCView(\n opf.store,\n toc.src,\n opf.lang,\n this.clientLayout,\n this.fontMapper,\n this.pref,\n this,\n opf.fallbackMap,\n opf.documentURLTransformer,\n this.counterStore,\n );\n }\n const viewport = this.viewport;\n const tocWidth = Math.min(350, Math.round(0.67 * viewport.width) - 16);\n const tocHeight = viewport.height - 6;\n const pageCont = viewport.document.createElement(\"div\") as HTMLElement;\n viewport.root.appendChild(pageCont);\n // pageCont.style.position = \"absolute\";\n pageCont.style.visibility = \"hidden\";\n // pageCont.style.left = \"3px\";\n // pageCont.style.top = \"3px\";\n pageCont.style.width = `${tocWidth + 10}px`;\n pageCont.style.maxHeight = `${tocHeight}px`;\n // pageCont.style.overflow = \"scroll\";\n // pageCont.style.overflowX = \"hidden\";\n // pageCont.style.background = \"rgba(248,248,248,0.9)\";\n // pageCont.style[\"borderRadius\"] = \"2px\";\n // pageCont.style[\"boxShadow\"] = \"1px 1px 2px rgba(0,0,0,0.4)\";\n\n pageCont.setAttribute(\"data-vivliostyle-toc-box\", \"true\");\n pageCont.setAttribute(\"role\", \"navigation\");\n\n this.tocView\n .showTOC(pageCont, viewport, tocWidth, tocHeight, this.viewport.fontSize)\n .then((page) => {\n pageCont.style.visibility = \"visible\";\n pageCont.setAttribute(\"aria-hidden\", \"false\");\n frame.finish(page);\n });\n return frame.result();\n }\n\n hideTOC(): void {\n if (this.tocView) {\n this.tocView.hideTOC();\n }\n }\n\n isTOCVisible(): boolean {\n return !!this.tocView && this.tocView.isTOCVisible();\n }\n}\n\nexport interface RenderSinglePageResult {\n pageAndPosition: PageAndPosition;\n nextLayoutPosition: Vtree.LayoutPosition;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2018 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview AdaptiveViewer - Viewer implementation.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Epub from \"./epub\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Logging from \"./logging\";\nimport * as Plugin from \"./plugin\";\nimport * as Profile from \"./profile\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\n\nexport type Action = (p1: Base.JSON) => Task.Result<boolean>;\n\nexport type ViewportSize = {\n marginLeft: number;\n marginRight: number;\n marginTop: number;\n marginBottom: number;\n width: number;\n height: number;\n};\n\nexport const VIEWPORT_STATUS_ATTRIBUTE = \"data-vivliostyle-viewer-status\";\n\nexport const VIEWPORT_SPREAD_VIEW_ATTRIBUTE = \"data-vivliostyle-spread-view\";\n\n/**\n * @enum {string}\n */\nexport enum PageViewMode {\n SINGLE_PAGE = \"singlePage\",\n SPREAD = \"spread\",\n AUTO_SPREAD = \"autoSpread\",\n}\n\nexport type SingleDocumentParam = {\n url: string;\n startPage: number | null;\n skipPagesBefore: number | null;\n};\n\nexport class AdaptiveViewer {\n fontMapper: Font.Mapper;\n kick: () => void;\n sendCommand: (p1: Base.JSON | string) => void;\n resizeListener: () => void;\n hyperlinkListener: Base.EventListener;\n pageRuleStyleElement: HTMLElement;\n pageSheetSizeAlreadySet: boolean = false;\n renderTask: Task.Task | null = null;\n actions: { [key: string]: Action };\n readyState: Constants.ReadyState;\n packageURL: string[];\n opf: Epub.OPFDoc;\n haveZipMetadata: boolean;\n touchActive: boolean;\n touchX: number;\n touchY: number;\n needResize: boolean;\n needRefresh: boolean;\n viewportSize: ViewportSize | null;\n currentPage: Vtree.Page;\n currentSpread: Vtree.Spread | null;\n pagePosition: Epub.Position | null;\n fontSize: number;\n zoom: number;\n fitToScreen: boolean;\n pageViewMode: PageViewMode;\n waitForLoading: boolean;\n renderAllPages: boolean;\n pref: Exprs.Preferences;\n pageSizes: { width: number; height: number }[];\n\n // force relayout\n viewport: Vgen.Viewport | null;\n opfView: Epub.OPFView;\n\n constructor(\n public readonly window: Window,\n public readonly viewportElement: HTMLElement,\n public readonly instanceId: string,\n public readonly callbackFn: (p1: Base.JSON) => void,\n ) {\n const self = this;\n viewportElement.setAttribute(\"data-vivliostyle-viewer-viewport\", true);\n if (Constants.isDebug) {\n viewportElement.setAttribute(\"data-vivliostyle-debug\", true);\n }\n viewportElement.setAttribute(VIEWPORT_STATUS_ATTRIBUTE, \"loading\");\n const document = window.document;\n this.fontMapper = new Font.Mapper(document.head, viewportElement);\n this.init();\n this.kick = () => {};\n this.sendCommand = () => {};\n this.resizeListener = () => {\n self.needResize = true;\n self.kick();\n };\n this.pageReplacedListener = this.pageReplacedListener.bind(this);\n this.hyperlinkListener = (evt) => {};\n this.pageRuleStyleElement = document.getElementById(\n \"vivliostyle-page-rules\",\n );\n this.actions = {\n loadPublication: this.loadPublication,\n loadXML: this.loadXML,\n configure: this.configure,\n moveTo: this.moveTo,\n toc: this.showTOC,\n };\n this.addLogListeners();\n }\n\n private init(): void {\n this.readyState = Constants.ReadyState.LOADING;\n this.packageURL = [];\n this.opf = null;\n this.haveZipMetadata = false;\n this.touchActive = false;\n this.touchX = 0;\n this.touchY = 0;\n this.needResize = false;\n this.needRefresh = false;\n this.viewportSize = null;\n this.currentPage = null;\n this.currentSpread = null;\n this.pagePosition = null;\n this.fontSize = 16;\n this.zoom = 1;\n this.fitToScreen = false;\n this.pageViewMode = PageViewMode.SINGLE_PAGE;\n this.waitForLoading = false;\n this.renderAllPages = true;\n this.pref = Exprs.defaultPreferences();\n this.pageSizes = [];\n }\n\n addLogListeners() {\n const logLevel = Logging.LogLevel;\n Logging.logger.addListener(logLevel.DEBUG, (info) => {\n this.callback({ t: \"debug\", content: info });\n });\n Logging.logger.addListener(logLevel.INFO, (info) => {\n this.callback({ t: \"info\", content: info });\n });\n Logging.logger.addListener(logLevel.WARN, (info) => {\n this.callback({ t: \"warn\", content: info });\n });\n Logging.logger.addListener(logLevel.ERROR, (info) => {\n this.callback({ t: \"error\", content: info });\n });\n }\n\n private callback(message: Base.JSON): void {\n message[\"i\"] = this.instanceId;\n this.callbackFn(message);\n }\n\n /**\n * Set readyState and notify to listeners\n */\n setReadyState(readyState: Constants.ReadyState) {\n if (this.readyState !== readyState) {\n this.readyState = readyState;\n this.viewportElement.setAttribute(VIEWPORT_STATUS_ATTRIBUTE, readyState);\n this.callback({ t: \"readystatechange\" });\n }\n }\n\n loadPublication(command: Base.JSON): Task.Result<boolean> {\n Profile.profiler.registerStartTiming(\"beforeRender\");\n this.setReadyState(Constants.ReadyState.LOADING);\n const url = command[\"url\"] as string;\n const fragment = command[\"fragment\"] as string | null;\n const haveZipMetadata = !!command[\"zipmeta\"];\n const authorStyleSheet = command[\"authorStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n const userStyleSheet = command[\"userStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n this.viewport = null;\n const frame: Task.Frame<boolean> = Task.newFrame(\"loadPublication\");\n const self = this;\n self.configure(command).then(() => {\n const store = new Epub.EPUBDocStore();\n store.init(authorStyleSheet, userStyleSheet).then(() => {\n const pubURL = Base.resolveURL(\n Base.convertSpecialURL(url),\n self.window.location.href,\n );\n self.packageURL = [pubURL];\n store.loadPubDoc(pubURL, haveZipMetadata).then((opf) => {\n if (opf) {\n self.opf = opf;\n self.render(fragment).then(() => {\n frame.finish(true);\n });\n } else {\n frame.finish(false);\n }\n });\n });\n });\n return frame.result();\n }\n\n loadXML(command: Base.JSON): Task.Result<boolean> {\n Profile.profiler.registerStartTiming(\"beforeRender\");\n this.setReadyState(Constants.ReadyState.LOADING);\n const params: SingleDocumentParam[] = command[\"url\"];\n const doc = command[\"document\"] as Document;\n const fragment = command[\"fragment\"] as string | null;\n const authorStyleSheet = command[\"authorStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n const userStyleSheet = command[\"userStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n\n // force relayout\n this.viewport = null;\n const frame: Task.Frame<boolean> = Task.newFrame(\"loadXML\");\n const self = this;\n self.configure(command).then(() => {\n const store = new Epub.EPUBDocStore();\n store.init(authorStyleSheet, userStyleSheet).then(() => {\n const resolvedParams: Epub.OPFItemParam[] = params.map((p, index) => ({\n url: Base.resolveURL(\n Base.convertSpecialURL(p.url),\n self.window.location.href,\n ),\n index,\n startPage: p.startPage,\n skipPagesBefore: p.skipPagesBefore,\n }));\n self.packageURL = resolvedParams.map((p) => p.url);\n self.opf = new Epub.OPFDoc(store, \"\");\n self.opf.initWithChapters(resolvedParams, doc).then(() => {\n self.render(fragment).then(() => {\n frame.finish(true);\n });\n });\n });\n });\n return frame.result();\n }\n\n private render(fragment?: string | null): Task.Result<boolean> {\n this.cancelRenderingTask();\n const self = this;\n let cont: Task.Result<boolean>;\n if (fragment) {\n cont = this.opf.resolveFragment(fragment).thenAsync((position) => {\n self.pagePosition = position;\n return Task.newResult(true);\n });\n } else {\n cont = Task.newResult(true);\n }\n return cont.thenAsync(() => {\n Profile.profiler.registerEndTiming(\"beforeRender\");\n return self.resize();\n });\n }\n\n private resolveLength(specified: string): number {\n const value = parseFloat(specified);\n const unitPattern = /[a-z]+$/;\n let matched: RegExpMatchArray;\n if (\n typeof specified === \"string\" &&\n (matched = specified.match(unitPattern))\n ) {\n const unit = matched[0];\n if (unit === \"em\" || unit === \"rem\") {\n return value * this.fontSize;\n }\n if (unit === \"ex\") {\n return (\n (value * Exprs.defaultUnitSizes[\"ex\"] * this.fontSize) /\n Exprs.defaultUnitSizes[\"em\"]\n );\n }\n const unitSize = Exprs.defaultUnitSizes[unit];\n if (unitSize) {\n return value * unitSize;\n }\n }\n return value;\n }\n\n configure(command: Base.JSON): Task.Result<boolean> {\n if (typeof command[\"autoresize\"] == \"boolean\") {\n if (command[\"autoresize\"]) {\n this.viewportSize = null;\n this.window.addEventListener(\"resize\", this.resizeListener, false);\n this.needResize = true;\n } else {\n this.window.removeEventListener(\"resize\", this.resizeListener, false);\n }\n }\n if (typeof command[\"fontSize\"] == \"number\") {\n const fontSize = command[\"fontSize\"] as number;\n if (fontSize >= 5 && fontSize <= 72 && this.fontSize != fontSize) {\n this.fontSize = fontSize;\n this.needResize = true;\n }\n }\n if (typeof command[\"viewport\"] == \"object\" && command[\"viewport\"]) {\n const vp = command[\"viewport\"];\n const viewportSize = {\n marginLeft: this.resolveLength(vp[\"margin-left\"]) || 0,\n marginRight: this.resolveLength(vp[\"margin-right\"]) || 0,\n marginTop: this.resolveLength(vp[\"margin-top\"]) || 0,\n marginBottom: this.resolveLength(vp[\"margin-bottom\"]) || 0,\n width: this.resolveLength(vp[\"width\"]) || 0,\n height: this.resolveLength(vp[\"height\"]) || 0,\n };\n if (viewportSize.width >= 200 || viewportSize.height >= 200) {\n this.window.removeEventListener(\"resize\", this.resizeListener, false);\n this.viewportSize = viewportSize;\n this.needResize = true;\n }\n }\n if (typeof command[\"hyphenate\"] == \"boolean\") {\n this.pref.hyphenate = command[\"hyphenate\"];\n this.needResize = true;\n }\n if (typeof command[\"horizontal\"] == \"boolean\") {\n this.pref.horizontal = command[\"horizontal\"];\n this.needResize = true;\n }\n if (typeof command[\"nightMode\"] == \"boolean\") {\n this.pref.nightMode = command[\"nightMode\"];\n this.needResize = true;\n }\n if (typeof command[\"lineHeight\"] == \"number\") {\n this.pref.lineHeight = command[\"lineHeight\"];\n this.needResize = true;\n }\n if (typeof command[\"columnWidth\"] == \"number\") {\n this.pref.columnWidth = command[\"columnWidth\"];\n this.needResize = true;\n }\n if (typeof command[\"fontFamily\"] == \"string\") {\n this.pref.fontFamily = command[\"fontFamily\"];\n this.needResize = true;\n }\n if (typeof command[\"load\"] == \"boolean\") {\n this.waitForLoading = command[\"load\"]; // Load images (and other resources) on the page.\n }\n if (typeof command[\"renderAllPages\"] == \"boolean\") {\n this.renderAllPages = command[\"renderAllPages\"];\n }\n // for backward compatibility\n if (typeof command[\"userAgentRootURL\"] == \"string\") {\n Base.setBaseURL(command[\"userAgentRootURL\"].replace(/resources\\/?$/, \"\"));\n Base.setResourceBaseURL(command[\"userAgentRootURL\"]);\n }\n if (typeof command[\"rootURL\"] == \"string\") {\n Base.setBaseURL(command[\"rootURL\"]);\n Base.setResourceBaseURL(`${Base.baseURL}resources/`);\n }\n if (\n typeof command[\"pageViewMode\"] == \"string\" &&\n command[\"pageViewMode\"] !== this.pageViewMode\n ) {\n this.pageViewMode = command[\"pageViewMode\"] as PageViewMode;\n this.needResize = true;\n }\n if (\n typeof command[\"pageBorder\"] == \"number\" &&\n command[\"pageBorder\"] !== this.pref.pageBorder\n ) {\n // Force relayout\n this.viewport = null;\n this.pref.pageBorder = command[\"pageBorder\"];\n this.needResize = true;\n }\n if (typeof command[\"zoom\"] == \"number\" && command[\"zoom\"] !== this.zoom) {\n this.zoom = command[\"zoom\"];\n this.needRefresh = true;\n }\n if (\n typeof command[\"fitToScreen\"] == \"boolean\" &&\n command[\"fitToScreen\"] !== this.fitToScreen\n ) {\n this.fitToScreen = command[\"fitToScreen\"];\n this.needRefresh = true;\n }\n if (\n typeof command[\"defaultPaperSize\"] == \"object\" &&\n typeof command[\"defaultPaperSize\"].width == \"number\" &&\n typeof command[\"defaultPaperSize\"].height == \"number\"\n ) {\n this.viewport = null;\n this.pref.defaultPaperSize = command[\"defaultPaperSize\"];\n this.needResize = true;\n }\n this.configurePlugins(command);\n return Task.newResult(true);\n }\n\n configurePlugins(command: Base.JSON) {\n const hooks: Plugin.ConfigurationHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.CONFIGURATION,\n );\n hooks.forEach((hook) => {\n const result = hook(command);\n this.needResize = result.needResize || this.needResize;\n this.needRefresh = result.needRefresh || this.needRefresh;\n });\n }\n\n /**\n * Refresh view when a currently displayed page is replaced (by re-layout\n * caused by cross reference resolutions)\n */\n pageReplacedListener(evt: Base.Event) {\n const currentPage = this.currentPage;\n const spread = this.currentSpread;\n const target = evt.target;\n if (spread) {\n if (spread.left === target || spread.right === target) {\n this.showCurrent(evt.newPage);\n }\n } else if (currentPage === evt.target) {\n this.showCurrent(evt.newPage);\n }\n }\n\n /**\n * Iterate through currently displayed pages and do something\n */\n private forCurrentPages(fn: (p1: Vtree.Page) => any) {\n const pages = [];\n if (this.currentPage) {\n pages.push(this.currentPage);\n }\n if (this.currentSpread) {\n pages.push(this.currentSpread.left);\n pages.push(this.currentSpread.right);\n }\n pages.forEach((page) => {\n if (page) {\n fn(page);\n }\n });\n }\n\n private removePageListeners() {\n this.forCurrentPages((page) => {\n page.removeEventListener(\"hyperlink\", this.hyperlinkListener, false);\n page.removeEventListener(\"replaced\", this.pageReplacedListener, false);\n });\n }\n\n /**\n * Hide current pages (this.currentPage, this.currentSpread)\n */\n private hidePages() {\n this.removePageListeners();\n this.forCurrentPages((page) => {\n Base.setCSSProperty(page.container, \"display\", \"none\");\n page.container.setAttribute(\"aria-hidden\", \"true\");\n });\n this.currentPage = null;\n this.currentSpread = null;\n }\n\n private showSinglePage(page: Vtree.Page) {\n page.addEventListener(\"hyperlink\", this.hyperlinkListener, false);\n page.addEventListener(\"replaced\", this.pageReplacedListener, false);\n Base.setCSSProperty(page.container, \"visibility\", \"visible\");\n Base.setCSSProperty(page.container, \"display\", \"block\");\n page.container.setAttribute(\"aria-hidden\", \"false\");\n }\n\n private showPage(page: Vtree.Page): void {\n this.hidePages();\n this.currentPage = page;\n page.container.style.marginLeft = \"\";\n page.container.style.marginRight = \"\";\n this.showSinglePage(page);\n }\n\n private showSpread(spread: Vtree.Spread) {\n this.hidePages();\n this.currentSpread = spread;\n if (spread.left && spread.right) {\n // Adjust spread horizontal alignment when left/right page widths differ\n let leftWidth = parseFloat(spread.left.container.style.width);\n let rightWidth = parseFloat(spread.right.container.style.width);\n if (leftWidth && rightWidth && leftWidth !== rightWidth) {\n if (leftWidth < rightWidth) {\n spread.left.container.style.marginLeft = `${rightWidth -\n leftWidth}px`;\n } else {\n spread.right.container.style.marginRight = `${leftWidth -\n rightWidth}px`;\n }\n }\n }\n if (spread.left) {\n this.showSinglePage(spread.left);\n if (!spread.right) {\n spread.left.container.setAttribute(\n \"data-vivliostyle-unpaired-page\",\n true,\n );\n } else {\n spread.left.container.removeAttribute(\"data-vivliostyle-unpaired-page\");\n }\n }\n if (spread.right) {\n this.showSinglePage(spread.right);\n if (!spread.left) {\n spread.right.container.setAttribute(\n \"data-vivliostyle-unpaired-page\",\n true,\n );\n } else {\n spread.right.container.removeAttribute(\n \"data-vivliostyle-unpaired-page\",\n );\n }\n }\n }\n\n private reportPosition(): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\"reportPosition\");\n const self = this;\n Asserts.assert(self.pagePosition);\n self.opf\n .getCFI(this.pagePosition.spineIndex, this.pagePosition.offsetInItem)\n .then((cfi) => {\n const page = self.currentPage;\n const r =\n self.waitForLoading && page.fetchers.length > 0\n ? TaskUtil.waitForFetchers(page.fetchers)\n : Task.newResult(true);\n r.then(() => {\n self.sendLocationNotification(page, cfi).thenFinish(frame);\n });\n });\n return frame.result();\n }\n\n private createViewport(): Vgen.Viewport {\n const viewportElement = this.viewportElement;\n if (this.viewportSize) {\n const vs = this.viewportSize;\n viewportElement.style.marginLeft = `${vs.marginLeft}px`;\n viewportElement.style.marginRight = `${vs.marginRight}px`;\n viewportElement.style.marginTop = `${vs.marginTop}px`;\n viewportElement.style.marginBottom = `${vs.marginBottom}px`;\n return new Vgen.Viewport(\n this.window,\n this.fontSize,\n viewportElement,\n vs.width,\n vs.height,\n );\n } else {\n return new Vgen.Viewport(this.window, this.fontSize, viewportElement);\n }\n }\n\n private resolveSpreadView(viewport: Vgen.Viewport): boolean {\n switch (this.pageViewMode) {\n case PageViewMode.SINGLE_PAGE:\n return false;\n case PageViewMode.SPREAD:\n return true;\n case PageViewMode.AUTO_SPREAD:\n default:\n // wide enough for a pair of pages of A/B paper sizes, but not too\n // narrow\n return viewport.width / viewport.height >= 1.45 && viewport.width > 800;\n }\n }\n\n private updateSpreadView(spreadView: boolean) {\n this.pref.spreadView = spreadView;\n this.viewportElement.setAttribute(\n VIEWPORT_SPREAD_VIEW_ATTRIBUTE,\n spreadView.toString(),\n );\n }\n\n private sizeIsGood(): boolean {\n const viewport = this.createViewport();\n const spreadView = this.resolveSpreadView(viewport);\n const spreadViewChanged = this.pref.spreadView !== spreadView;\n this.updateSpreadView(spreadView);\n if (\n this.viewportSize ||\n !this.viewport ||\n this.viewport.fontSize != this.fontSize\n ) {\n return false;\n }\n if (\n !spreadViewChanged &&\n viewport.width == this.viewport.width &&\n viewport.height == this.viewport.height\n ) {\n return true;\n }\n\n if (\n !spreadViewChanged &&\n viewport.width == this.viewport.width &&\n viewport.height != this.viewport.height &&\n /Android|iPhone|iPad|iPod/.test(navigator.userAgent)\n ) {\n // On mobile browsers, the viewport height may change unexpectedly\n // when soft keyboard appears or tab/address bar auto-hide occurs,\n // so ignore resizing in this condition.\n return true;\n }\n\n if (\n this.opfView &&\n this.opfView.hasPages() &&\n !this.opfView.hasAutoSizedPages()\n ) {\n this.viewport.width = viewport.width;\n this.viewport.height = viewport.height;\n this.needRefresh = true;\n return true;\n }\n return false;\n }\n\n private setPageSize(\n pageSize: { width: number; height: number },\n pageSheetSize: { [key: string]: { width: number; height: number } },\n spineIndex: number,\n pageIndex: number,\n ) {\n this.pageSizes[pageIndex] = pageSize;\n this.setPageSizePageRules(pageSheetSize, spineIndex, pageIndex);\n }\n\n private setPageSizePageRules(\n pageSheetSize: { [key: string]: { width: number; height: number } },\n spineIndex: number,\n pageIndex: number,\n ) {\n if (!this.pageSheetSizeAlreadySet && this.pageRuleStyleElement) {\n let styleText = \"\";\n Object.keys(pageSheetSize).forEach((selector) => {\n styleText += `@page ${selector}{margin:0;size:`;\n const size = pageSheetSize[selector];\n styleText += `${size.width}px ${size.height}px;}`;\n });\n this.pageRuleStyleElement.textContent = styleText;\n this.pageSheetSizeAlreadySet = true;\n }\n }\n\n removePageSizePageRules() {\n if (this.pageRuleStyleElement) {\n this.pageRuleStyleElement.textContent = \"\";\n this.pageSheetSizeAlreadySet = false;\n }\n }\n\n private reset(): void {\n let tocVisible = false;\n let tocAutohide = false;\n if (this.opfView) {\n tocVisible = this.opfView.isTOCVisible();\n tocAutohide = this.opfView.tocAutohide;\n this.opfView.hideTOC();\n this.opfView.removeRenderedPages();\n }\n this.removePageSizePageRules();\n this.viewport = this.createViewport();\n this.viewport.resetZoom();\n this.opfView = new Epub.OPFView(\n this.opf,\n this.viewport,\n this.fontMapper,\n this.pref,\n this.setPageSize.bind(this),\n );\n if (tocVisible) {\n this.sendCommand({ a: \"toc\", v: \"show\", autohide: tocAutohide });\n }\n }\n\n /**\n * Show current page or spread depending on the setting\n * (this.pref.spreadView).\n * @param sync If true, get the necessary page synchronously (not waiting\n * another rendering task)\n */\n private showCurrent(page: Vtree.Page, sync?: boolean): Task.Result<null> {\n this.needRefresh = false;\n this.removePageListeners();\n const self = this;\n if (this.pref.spreadView) {\n return this.opfView\n .getSpread(this.pagePosition, sync)\n .thenAsync((spread) => {\n self.showSpread(spread);\n self.setSpreadZoom(spread);\n self.currentPage = page;\n return Task.newResult(null);\n });\n } else {\n this.showPage(page);\n this.setPageZoom(page);\n this.currentPage = page;\n return Task.newResult(null);\n }\n }\n\n setPageZoom(page: Vtree.Page) {\n const zoom = this.getAdjustedZoomFactor(page.dimensions);\n this.viewport.zoom(page.dimensions.width, page.dimensions.height, zoom);\n }\n\n setSpreadZoom(spread: Vtree.Spread) {\n const dim = this.getSpreadDimensions(spread);\n this.viewport.zoom(dim.width, dim.height, this.getAdjustedZoomFactor(dim));\n }\n\n /**\n * @returns adjusted zoom factor\n */\n getAdjustedZoomFactor(pageDimension: {\n width: number;\n height: number;\n }): number {\n return this.fitToScreen\n ? this.calculateZoomFactorToFitInsideViewPort(pageDimension)\n : this.zoom;\n }\n\n /**\n * Returns width and height of the spread, including the margin between pages.\n */\n getSpreadDimensions(spread: Vtree.Spread): { width: number; height: number } {\n let width = 0;\n let height = 0;\n if (spread.left) {\n width += spread.left.dimensions.width;\n height = spread.left.dimensions.height;\n }\n if (spread.right) {\n width += spread.right.dimensions.width;\n height = Math.max(height, spread.right.dimensions.height);\n }\n if (spread.left && spread.right) {\n width += this.pref.pageBorder * 2;\n // Adjust spread horizontal alignment when left/right page widths differ\n width += Math.abs(\n spread.left.dimensions.width - spread.right.dimensions.width,\n );\n }\n return { width, height };\n }\n\n /**\n * Returns zoom factor corresponding to the specified zoom type.\n */\n queryZoomFactor(type: ZoomType): number {\n if (!this.currentPage) {\n throw new Error(\"no page exists.\");\n }\n switch (type) {\n case ZoomType.FIT_INSIDE_VIEWPORT: {\n let pageDim: { width: number; height: number };\n if (this.pref.spreadView) {\n Asserts.assert(this.currentSpread);\n pageDim = this.getSpreadDimensions(this.currentSpread);\n } else {\n pageDim = this.currentPage.dimensions;\n }\n return this.calculateZoomFactorToFitInsideViewPort(pageDim);\n }\n default:\n throw new Error(`unknown zoom type: ${type}`);\n }\n }\n\n /**\n * @returns zoom factor to fit inside viewport\n */\n calculateZoomFactorToFitInsideViewPort(pageDimension: {\n width: number;\n height: number;\n }): number {\n const widthZoom = this.viewport.width / pageDimension.width;\n const heightZoom = this.viewport.height / pageDimension.height;\n return Math.min(widthZoom, heightZoom);\n }\n\n private cancelRenderingTask() {\n if (this.renderTask) {\n this.renderTask.interrupt(new RenderingCanceledError());\n }\n this.renderTask = null;\n }\n\n resize(): Task.Result<boolean> {\n this.needResize = false;\n this.needRefresh = false;\n if (this.sizeIsGood()) {\n return Task.newResult(true);\n }\n const self = this;\n this.setReadyState(Constants.ReadyState.LOADING);\n this.cancelRenderingTask();\n const resizeTask = Task.currentTask()\n .getScheduler()\n .run(() =>\n Task.handle(\n \"resize\",\n (frame) => {\n if (!self.opf) {\n frame.finish(false);\n return;\n }\n self.renderTask = resizeTask;\n Profile.profiler.registerStartTiming(\"render (resize)\");\n self.reset();\n if (self.pagePosition) {\n // When resizing, do not use the current page index, for a page\n // index corresponding to the current position in the document\n // (offsetInItem) can change due to different layout caused by\n // different viewport size.\n\n // Update(2019-03): to avoid unexpected page move (first page to next),\n // keep pageIndex == 0 when offsetInItem == 0\n if (\n !(\n self.pagePosition.pageIndex == 0 &&\n self.pagePosition.offsetInItem == 0\n )\n ) {\n self.pagePosition.pageIndex = -1;\n }\n }\n\n // epageCount counting depends renderAllPages mode\n self.opf.setEPageCountMode(self.renderAllPages);\n\n // With renderAllPages option specified, the rendering is\n // performed after the initial page display, otherwise users are\n // forced to wait the rendering finish in front of a blank page.\n self.opfView\n .renderPagesUpto(self.pagePosition, !self.renderAllPages)\n .then((result) => {\n if (!result) {\n frame.finish(false);\n return;\n }\n self.pagePosition = result.position;\n self.showCurrent(result.page, true).then(() => {\n self.setReadyState(Constants.ReadyState.INTERACTIVE);\n\n self.opf\n .countEPages((epageCount) => {\n const notification = {\n t: \"nav\",\n epageCount: epageCount,\n first: self.currentPage.isFirstPage,\n last: self.currentPage.isLastPage,\n metadata: self.opf.metadata,\n docTitle:\n self.opf.spine[self.pagePosition.spineIndex].title,\n };\n if (\n self.currentPage.isFirstPage ||\n (self.pagePosition.pageIndex == 0 &&\n self.opf.spine[self.pagePosition.spineIndex].epage)\n ) {\n notification[\"epage\"] =\n self.opf.spine[self.pagePosition.spineIndex].epage;\n }\n self.callback(notification);\n })\n .then(() => {\n self.reportPosition().then((p) => {\n const r = self.renderAllPages\n ? self.opfView.renderAllPages()\n : Task.newResult(null);\n r.then(() => {\n if (self.renderTask === resizeTask) {\n self.renderTask = null;\n }\n Profile.profiler.registerEndTiming(\"render (resize)\");\n if (self.renderAllPages) {\n self.setReadyState(Constants.ReadyState.COMPLETE);\n }\n self.callback({ t: \"loaded\" });\n frame.finish(p);\n });\n });\n });\n });\n });\n },\n (frame, err) => {\n if (err instanceof RenderingCanceledError) {\n Profile.profiler.registerEndTiming(\"render (resize)\");\n Logging.logger.debug(err.message);\n } else {\n throw err;\n }\n },\n ),\n );\n return Task.newResult(true);\n }\n\n private sendLocationNotification(\n page: Vtree.Page,\n cfi: string | null,\n ): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\n \"sendLocationNotification\",\n );\n const notification = {\n t: \"nav\",\n first: page.isFirstPage,\n last: page.isLastPage,\n metadata: this.opf.metadata,\n docTitle: this.opf.spine[page.spineIndex].title,\n };\n const self = this;\n this.opf\n .getEPageFromPosition(self.pagePosition as Epub.Position)\n .then((epage) => {\n notification[\"epage\"] = epage;\n notification[\"epageCount\"] = self.opf.epageCount;\n if (cfi) {\n notification[\"cfi\"] = cfi;\n }\n self.callback(notification);\n frame.finish(true);\n });\n return frame.result();\n }\n\n getCurrentPageProgression(): Constants.PageProgression | null {\n return this.opfView\n ? this.opfView.getCurrentPageProgression(this.pagePosition)\n : null;\n }\n\n moveTo(command: Base.JSON): Task.Result<boolean> {\n let method: () => Task.Result<Epub.PageAndPosition>;\n const self = this;\n if (\n this.readyState !== Constants.ReadyState.COMPLETE &&\n command[\"where\"] !== \"next\"\n ) {\n this.setReadyState(Constants.ReadyState.LOADING);\n }\n if (typeof command[\"where\"] == \"string\") {\n let m: (\n position: Epub.Position,\n sync: boolean,\n ) => Task.Result<Epub.PageAndPosition>;\n switch (command[\"where\"]) {\n case \"next\":\n m = this.pref.spreadView\n ? this.opfView.nextSpread\n : this.opfView.nextPage;\n break;\n case \"previous\":\n m = this.pref.spreadView\n ? this.opfView.previousSpread\n : this.opfView.previousPage;\n break;\n case \"last\":\n m = this.opfView.lastPage;\n break;\n case \"first\":\n m = this.opfView.firstPage;\n break;\n default:\n return Task.newResult(true);\n }\n if (m) {\n method = () =>\n m.call(self.opfView, self.pagePosition, !self.renderAllPages);\n }\n } else if (typeof command[\"epage\"] == \"number\") {\n const epage = command[\"epage\"] as number;\n method = () =>\n self.opfView.navigateToEPage(\n epage,\n self.pagePosition,\n !self.renderAllPages,\n );\n } else if (typeof command[\"url\"] == \"string\") {\n const url = command[\"url\"] as string;\n method = () =>\n self.opfView.navigateTo(url, self.pagePosition, !self.renderAllPages);\n } else {\n return Task.newResult(true);\n }\n const frame: Task.Frame<boolean> = Task.newFrame(\"moveTo\");\n method.call(self.opfView).then((result) => {\n let cont: Task.Result<boolean>;\n if (result) {\n self.pagePosition = result.position;\n const innerFrame: Task.Frame<boolean> = Task.newFrame(\n \"moveTo.showCurrent\",\n );\n cont = innerFrame.result();\n self.showCurrent(result.page, !self.renderAllPages).then(() => {\n self.reportPosition().thenFinish(innerFrame);\n });\n } else {\n cont = Task.newResult(true);\n }\n cont.then((res) => {\n if (self.readyState === Constants.ReadyState.LOADING) {\n self.setReadyState(Constants.ReadyState.INTERACTIVE);\n }\n frame.finish(res);\n });\n });\n return frame.result();\n }\n\n showTOC(command: Base.JSON): Task.Result<boolean> {\n const autohide = !!command[\"autohide\"];\n const visibility = command[\"v\"];\n const currentVisibility = this.opfView.isTOCVisible();\n const changeAutohide =\n autohide != this.opfView.tocAutohide && visibility != \"hide\";\n if (currentVisibility) {\n if (visibility == \"show\" && !changeAutohide) {\n return Task.newResult(true);\n }\n } else {\n if (visibility == \"hide\") {\n return Task.newResult(true);\n }\n }\n if (currentVisibility && visibility != \"show\") {\n this.opfView.hideTOC();\n return Task.newResult(true);\n } else {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"showTOC\");\n this.opfView.showTOC(autohide).then((page) => {\n if (page) {\n if (changeAutohide) {\n page.listeners = {};\n }\n if (autohide) {\n const hideTOC = () => {\n self.opfView.hideTOC();\n };\n page.addEventListener(\"hyperlink\", hideTOC, false);\n // page.container.addEventListener(\"click\", hideTOC, false);\n }\n page.addEventListener(\"hyperlink\", self.hyperlinkListener, false);\n }\n frame.finish(true);\n });\n return frame.result();\n }\n }\n\n runCommand(command: Base.JSON): Task.Result<boolean> {\n const self = this;\n const actionName = command[\"a\"] || \"\";\n return Task.handle(\n \"runCommand\",\n (frame) => {\n const action = self.actions[actionName];\n if (action) {\n action.call(self, command).then(() => {\n self.callback({ t: \"done\", a: actionName });\n frame.finish(true);\n });\n } else {\n Logging.logger.error(\"No such action:\", actionName);\n frame.finish(true);\n }\n },\n (frame, err) => {\n Logging.logger.error(err, \"Error during action:\", actionName);\n frame.finish(true);\n },\n );\n }\n\n initEmbed(cmd: Base.JSON | string): void {\n let command = maybeParse(cmd);\n let continuation: Task.Continuation<boolean> | null = null;\n const viewer = this;\n Task.start(() => {\n const frame: Task.Frame<boolean> = Task.newFrame(\"commandLoop\");\n const scheduler = Task.currentTask().getScheduler();\n viewer.hyperlinkListener = (evt) => {\n const hrefEvent = evt as Vtree.PageHyperlinkEvent;\n const internal =\n hrefEvent.href.charAt(0) === \"#\" ||\n viewer.packageURL.some(\n (url) => hrefEvent.href.substr(0, url.length) == url,\n );\n if (internal) {\n evt.preventDefault();\n const msg = {\n t: \"hyperlink\",\n href: hrefEvent.href,\n internal: internal,\n };\n scheduler.run(() => {\n viewer.callback(msg);\n return Task.newResult(true);\n });\n }\n };\n frame\n .loopWithFrame((loopFrame) => {\n if (viewer.needResize) {\n viewer.resize().then(() => {\n loopFrame.continueLoop();\n });\n } else if (viewer.needRefresh) {\n if (viewer.currentPage) {\n viewer.showCurrent(viewer.currentPage).then(() => {\n loopFrame.continueLoop();\n });\n }\n } else if (command) {\n const cmd = command;\n command = null;\n viewer.runCommand(cmd).then(() => {\n loopFrame.continueLoop();\n });\n } else {\n const frameInternal: Task.Frame<boolean> = Task.newFrame(\n \"waitForCommand\",\n );\n continuation = frameInternal.suspend(self);\n frameInternal.result().then(() => {\n loopFrame.continueLoop();\n });\n }\n })\n .thenFinish(frame);\n return frame.result();\n });\n viewer.kick = () => {\n const cont = continuation;\n if (cont) {\n continuation = null;\n cont.schedule(true);\n }\n };\n viewer.sendCommand = (cmd) => {\n if (command) {\n return false;\n }\n command = maybeParse(cmd);\n viewer.kick();\n return true;\n };\n this.window[\"adapt_command\"] = viewer.sendCommand;\n }\n}\n\n/**\n * @enum {string}\n */\nexport enum ZoomType {\n FIT_INSIDE_VIEWPORT = \"fit inside viewport\",\n}\n\n/**\n * Error representing that the rendering has been canceled.\n */\nclass RenderingCanceledError extends Error {\n name: string = \"RenderingCanceledError\";\n message: string = \"Page rendering has been canceled\";\n stack: string;\n\n constructor() {\n super();\n // Set the prototype explicitly.\n // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, RenderingCanceledError.prototype);\n this.stack = new Error().stack;\n }\n}\n\nexport function maybeParse(cmd: any): Base.JSON {\n if (typeof cmd == \"string\") {\n return Base.stringToJSON(cmd);\n }\n return cmd;\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2018 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CoreViewer - Vivliostyle CoreViewer class\n */\nimport * as AdaptiveViewer from \"./adaptive-viewer\";\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Profile from \"./profile\";\n\nexport interface Payload {\n type: string;\n internal: boolean;\n href: string;\n content: string;\n cfi: string;\n first: boolean;\n last: boolean;\n epage: unknown;\n epageCount: number;\n metadata: unknown;\n docTitle: string;\n}\n\nconst PageProgression = Constants.PageProgression;\n\n/**\n * Viewer settings that must be passed to Viewer's constructor.\n * - userAgentRootURL: URL of a directory from which viewer resource files\n * (under resources/ directory in the source repository) are served.\n * - viewportElement: An element used as the viewport of the displayed contents.\n * - window: Window object. If omitted, current `window` is used.\n * - debug: Debug flag.\n */\nexport type CoreViewerSettings = {\n userAgentRootURL?: string;\n viewportElement: HTMLElement;\n window?: Window;\n debug?: boolean;\n};\n\n/**\n * Viewer options that can be set after the Viewer object is constructed.\n * - autoResize: Run layout again when the window is resized. default: true\n * - fontSize: Default font size (px). default: 16\n * - pageBorderWidth: Width of a border between two pages in a single\n * spread (px). Effective only in spread view mode. default: 1\n * - renderAllPages: Render all pages at the document load time. default: true\n * - pageViewMode: Page view mode (singlePage / spread / autoSpread).\n * default: singlePage\n * - zoom: Zoom factor with which pages are displayed. default: 1\n * - fitToScreen: Auto adjust zoom factor to fit the screen. default: false\n * - defaultPaperSize: Default paper size in px. Effective when `@page` size\n * is set to auto. default: undefined (means the windows size is used as\n * paper size).\n */\nexport type CoreViewerOptions = {\n autoResize?: boolean;\n fontSize?: number;\n pageBorderWidth?: number;\n renderAllPages?: boolean;\n pageViewMode?: AdaptiveViewer.PageViewMode;\n zoom?: number;\n fitToScreen?: boolean;\n defaultPaperSize?: { width: number; height: number };\n};\n\nfunction getDefaultViewerOptions(): CoreViewerOptions {\n return {\n autoResize: true,\n fontSize: 16,\n pageBorderWidth: 1,\n renderAllPages: true,\n pageViewMode: AdaptiveViewer.PageViewMode.AUTO_SPREAD,\n zoom: 1,\n fitToScreen: false,\n defaultPaperSize: undefined,\n };\n}\n\nfunction convertViewerOptions(options: CoreViewerOptions): object {\n const converted = {};\n Object.keys(options).forEach((key) => {\n const v = options[key];\n switch (key) {\n case \"autoResize\":\n converted[\"autoresize\"] = v;\n break;\n case \"pageBorderWidth\":\n converted[\"pageBorder\"] = v;\n break;\n default:\n converted[key] = v;\n }\n });\n return converted;\n}\n\n/**\n * Options for the displayed document.\n * - documentObject: Document object for the document. If provided, it is used\n * directly without parsing the source again.\n * - fragment: Fragmentation identifier (EPUB CFI) of the location in the\n * document which is to be displayed.\n * - authorStyleSheet: An array of author style sheets to be injected after all\n * author style sheets referenced from the document. A single stylesheet may\n * be a URL of the style sheet or a text content of the style sheet.\n * - userStyleSheet: An array of user style sheets to be injected.\n * A single stylesheet may be a URL of the style sheet or a text content of\n * the style sheet.\n */\nexport type DocumentOptions = {\n documentObject?: Document;\n fragment?: string;\n authorStyleSheet?: { url?: string; text?: string }[];\n userStyleSheet?: { url?: string; text?: string }[];\n};\n\n/**\n * Options for a single source document.\n * - url: URL of the document.\n * - startPage: If specified, the `page` page-based counter is set to the\n * specified value on the first page of the document. It is equivalent to\n * specifying `counter-reset: page [specified value - 1]` on that page.\n * - skipPagesBefore: If specified, the `page` page-based counter is\n * incremented by the specified value *before* updating page-based counters\n * on the first page of the document.\n * This option is ignored if `startPageNumber` option is also specified.\n */\nexport type SingleDocumentOptions =\n | string\n | {\n url: string;\n startPage?: number;\n skipPagesBefore?: number;\n };\n\n/**\n * Vivliostyle Viewer class.\n */\nexport class CoreViewer {\n private initialized: boolean = false;\n private adaptViewer_: AdaptiveViewer.AdaptiveViewer;\n private options: CoreViewerOptions;\n private eventTarget: Base.SimpleEventTarget;\n readyState: Constants.ReadyState;\n\n constructor(\n private readonly settings: CoreViewerSettings,\n opt_options?: CoreViewerOptions,\n ) {\n Constants.setDebug(settings.debug);\n this.adaptViewer_ = new AdaptiveViewer.AdaptiveViewer(\n settings[\"window\"] || window,\n settings[\"viewportElement\"],\n \"main\",\n this.dispatcher.bind(this),\n );\n this.options = getDefaultViewerOptions();\n if (opt_options) {\n this.setOptions(opt_options);\n }\n this.eventTarget = new Base.SimpleEventTarget();\n Object.defineProperty(this, \"readyState\", {\n get() {\n return this.adaptViewer_.readyState;\n },\n });\n }\n\n /**\n * Set ViewerOptions to the viewer.\n */\n setOptions(options: CoreViewerOptions) {\n const command = Object.assign(\n { a: \"configure\" },\n convertViewerOptions(options),\n );\n this.adaptViewer_.sendCommand(command);\n Object.assign(this.options, options);\n }\n\n private dispatcher(msg: Base.JSON) {\n /** @dict */\n const event = { type: msg[\"t\"] };\n const o = msg as object;\n Object.keys(o).forEach((key) => {\n if (key !== \"t\") {\n event[key] = o[key];\n }\n });\n this.eventTarget.dispatchEvent(event);\n }\n\n /**\n * Add a listener function, which is invoked when the specified type of event\n * is dispatched.\n * @param type Event type.\n * @param listener Listener function.\n */\n addListener(type: string, listener: (payload: Payload) => void) {\n this.eventTarget.addEventListener(\n type,\n listener as Base.EventListener,\n false,\n );\n }\n\n /**\n * Remove an event listener.\n * @param type Event type.\n * @param listener Listener function.\n */\n removeListener(type: string, listener: (payload: Payload) => void) {\n this.eventTarget.removeEventListener(\n type,\n listener as Base.EventListener,\n false,\n );\n }\n\n /**\n * Load an HTML or XML document(s).\n */\n loadDocument(\n singleDocumentOptions: SingleDocumentOptions | SingleDocumentOptions[],\n opt_documentOptions?: DocumentOptions,\n opt_viewerOptions?: CoreViewerOptions,\n ) {\n if (!singleDocumentOptions) {\n this.eventTarget.dispatchEvent({\n type: \"error\",\n content: \"No URL specified\",\n });\n }\n this.loadDocumentOrPublication(\n singleDocumentOptions,\n null,\n opt_documentOptions,\n opt_viewerOptions,\n );\n }\n\n /**\n * Load an EPUB/WebPub publication.\n */\n loadPublication(\n pubUrl: string,\n opt_documentOptions?: DocumentOptions,\n opt_viewerOptions?: CoreViewerOptions,\n ) {\n if (!pubUrl) {\n this.eventTarget.dispatchEvent({\n type: \"error\",\n content: \"No URL specified\",\n });\n }\n this.loadDocumentOrPublication(\n null,\n pubUrl,\n opt_documentOptions,\n opt_viewerOptions,\n );\n }\n\n /**\n * Load an HTML or XML document, or an EPUB/WebPub publication.\n */\n private loadDocumentOrPublication(\n singleDocumentOptions:\n | SingleDocumentOptions\n | SingleDocumentOptions[]\n | null,\n pubUrl: string | null,\n opt_documentOptions?: DocumentOptions,\n opt_viewerOptions?: CoreViewerOptions,\n ) {\n const documentOptions = opt_documentOptions || {};\n\n function convertStyleSheetArray(arr) {\n if (arr) {\n return arr.map((s) => ({ url: s.url || null, text: s.text || null }));\n } else {\n return undefined;\n }\n }\n const authorStyleSheet = convertStyleSheetArray(\n documentOptions[\"authorStyleSheet\"],\n );\n const userStyleSheet = convertStyleSheetArray(\n documentOptions[\"userStyleSheet\"],\n );\n if (opt_viewerOptions) {\n Object.assign(this.options, opt_viewerOptions);\n }\n const command = Object.assign(\n {\n a: singleDocumentOptions ? \"loadXML\" : \"loadPublication\",\n userAgentRootURL: this.settings[\"userAgentRootURL\"],\n url: convertSingleDocumentOptions(singleDocumentOptions) || pubUrl,\n document: documentOptions[\"documentObject\"],\n fragment: documentOptions[\"fragment\"],\n authorStyleSheet: authorStyleSheet,\n userStyleSheet: userStyleSheet,\n },\n convertViewerOptions(this.options),\n );\n if (this.initialized) {\n this.adaptViewer_.sendCommand(command);\n } else {\n this.initialized = true;\n this.adaptViewer_.initEmbed(command);\n }\n }\n\n /**\n * Returns the current page progression of the viewer. If no document is\n * loaded, returns null.\n */\n getCurrentPageProgression(): Constants.PageProgression | null {\n return this.adaptViewer_.getCurrentPageProgression();\n }\n\n private resolveNavigation(nav: Navigation): Navigation {\n switch (nav) {\n case Navigation.LEFT:\n return this.getCurrentPageProgression() === PageProgression.LTR\n ? Navigation.PREVIOUS\n : Navigation.NEXT;\n case Navigation.RIGHT:\n return this.getCurrentPageProgression() === PageProgression.LTR\n ? Navigation.NEXT\n : Navigation.PREVIOUS;\n default:\n return nav;\n }\n }\n\n /**\n * Navigate to the specified page.\n */\n navigateToPage(nav: Navigation, opt_epage?: number) {\n if (nav === Navigation.EPAGE) {\n this.adaptViewer_.sendCommand({\n a: \"moveTo\",\n epage: opt_epage,\n });\n } else {\n this.adaptViewer_.sendCommand({\n a: \"moveTo\",\n where: this.resolveNavigation(nav),\n });\n }\n }\n\n /**\n * Navigate to the specified internal URL.\n */\n navigateToInternalUrl(url: string) {\n this.adaptViewer_.sendCommand({ a: \"moveTo\", url: url });\n }\n\n /**\n * @returns True if TOC is visible, false if hidden, null if TOC is unavailable\n */\n isTOCVisible(): boolean | null {\n if (\n this.adaptViewer_.opfView &&\n this.adaptViewer_.opfView.opf &&\n (this.adaptViewer_.opfView.opf.xhtmlToc ||\n this.adaptViewer_.opfView.opf.ncxToc)\n ) {\n return !!this.adaptViewer_.opfView.isTOCVisible();\n } else {\n return null;\n }\n }\n\n /**\n * Show or hide TOC box\n * @param opt_autohide If true, automatically hide when click TOC item\n * @param opt_show If true show TOC, false hide TOC. If null or undefined toggle TOC.\n */\n showTOC(opt_show?: boolean | null, opt_autohide?: boolean) {\n const visibility = opt_show == null ? \"toggle\" : opt_show ? \"show\" : \"hide\";\n this.adaptViewer_.sendCommand({\n a: \"toc\",\n v: visibility,\n autohide: opt_autohide,\n });\n }\n\n /**\n * Returns zoom factor corresponding to the specified zoom type.\n */\n queryZoomFactor(type: AdaptiveViewer.ZoomType): number {\n return this.adaptViewer_.queryZoomFactor(type);\n }\n\n getPageSizes(): { width: number; height: number }[] {\n return this.adaptViewer_.pageSizes;\n }\n}\n\nfunction convertSingleDocumentOptions(\n singleDocumentOptions: SingleDocumentOptions | SingleDocumentOptions[],\n): AdaptiveViewer.SingleDocumentParam[] | null {\n function toNumberOrNull(num: any): number | null {\n return typeof num === \"number\" ? num : null;\n }\n\n function convert(opt) {\n if (typeof opt === \"string\") {\n return {\n url: opt,\n startPage: null,\n skipPagesBefore: null,\n } as AdaptiveViewer.SingleDocumentParam;\n } else {\n return {\n url: opt[\"url\"],\n startPage: toNumberOrNull(opt[\"startPage\"]),\n skipPagesBefore: toNumberOrNull(opt[\"skipPagesBefore\"]),\n } as AdaptiveViewer.SingleDocumentParam;\n }\n }\n if (Array.isArray(singleDocumentOptions)) {\n return singleDocumentOptions.map(convert);\n } else if (singleDocumentOptions) {\n return [convert(singleDocumentOptions)];\n } else {\n return null;\n }\n}\n\n/**\n * @enum {string}\n */\nexport enum Navigation {\n PREVIOUS = \"previous\",\n NEXT = \"next\",\n LEFT = \"left\",\n RIGHT = \"right\",\n FIRST = \"first\",\n LAST = \"last\",\n EPAGE = \"epage\",\n}\n\nexport type ZoomType = AdaptiveViewer.ZoomType;\nexport const ZoomType = AdaptiveViewer.ZoomType;\n\nexport type PageViewMode = AdaptiveViewer.PageViewMode;\nexport const PageViewMode = AdaptiveViewer.PageViewMode;\n\nexport const viewer = {\n CoreViewer,\n PageViewMode,\n ZoomType,\n};\n\nProfile.profiler.forceRegisterEndTiming(\"load_vivliostyle\");\n","// Johannes Wilm\n// Vivliostyle Foundation\n\nimport * as CoreViewer from \"./core-viewer\";\nimport viewportCss from \"../../resources/vivliostyle-viewport.css\";\nimport viewportScreenCss from \"../../resources/vivliostyle-viewport-screen.css\";\n\ninterface IFrameWindowForPrint {\n printInstance?: VivliostylePrint;\n}\n\ninterface PrintConfig {\n title: string;\n printCallback: (iframeWin: Window) => void;\n hideIframe: boolean;\n removeIframe: boolean;\n}\n\nclass VivliostylePrint {\n htmlDoc: string;\n title: string;\n printCallback: (iframeWin: Window) => void;\n hideIframe: boolean;\n removeIframe: boolean;\n iframe: HTMLIFrameElement;\n iframeWin: Window;\n window: Window & typeof globalThis & IFrameWindowForPrint;\n\n constructor(\n htmlDoc: string,\n {\n title = \"\",\n printCallback = (iframeWin: Window) => iframeWin.print(),\n hideIframe = true,\n removeIframe = true,\n }: PrintConfig,\n ) {\n this.htmlDoc = htmlDoc;\n this.title = title;\n this.printCallback = printCallback;\n this.hideIframe = hideIframe;\n this.removeIframe = removeIframe;\n }\n\n init() {\n this.iframe = document.createElement(\"iframe\");\n\n if (this.hideIframe) {\n this.iframe.style.width = \"0\"; // We don't want the iframe to be seen, so we make it zero size with zero border.\n this.iframe.style.height = \"0\";\n this.iframe.style.borderWidth = \"0\";\n }\n\n this.window = window;\n this.window.printInstance = this;\n this.iframe.srcdoc = `\n <!DOCTYPE html>\n <html data-vivliostyle-paginated=\"true\">\n <head>\n <meta charset='utf-8'/>\n <meta name='viewport' content='width=device-width, initial-scale=1.0'/>\n <title>${this.title}</title>\n <style>${viewportCss}</style>\n <style>${viewportScreenCss}</style>\n <style>\n html[data-vivliostyle-paginated] {\n width: 100%;\n height: 100%;\n }\n html[data-vivliostyle-paginated] body,\n html[data-vivliostyle-paginated] [data-vivliostyle-viewer-viewport] {\n width: 100% !important;\n height: 100% !important;\n }\n html[data-vivliostyle-paginated],\n html[data-vivliostyle-paginated] body {\n margin: 0;\n padding: 0;\n }\n </style>\n <style id='vivliostyle-page-rules'></style>\n </head>\n <body onload='parent.printInstance.runInIframe(window)'>\n <div id=\"vivliostyle-viewer-viewport\"></div>\n </body>\n </html>`;\n\n document.body.appendChild(this.iframe);\n }\n\n runInIframe(iframeWin: Window) {\n this.iframeWin = iframeWin;\n return this.preparePrint()\n .then(() => this.browserPrint())\n .then(() => this.cleanUp());\n }\n\n preparePrint() {\n this.iframeWin.document.title = this.title;\n const docBlob = new Blob([this.htmlDoc], {\n type: \"text/html\",\n }),\n docURL = URL.createObjectURL(docBlob),\n Viewer = new CoreViewer.CoreViewer(\n {\n viewportElement: this.iframeWin.document.body\n .firstElementChild as HTMLElement,\n window: this.iframeWin,\n debug: true,\n },\n {\n defaultPaperSize: {\n width: 794, // These numbers give weird output, but not setting them crashes the browser when there is no CSS.\n height: 1122,\n },\n },\n );\n return new Promise((resolve) => {\n Viewer.addListener(\"readystatechange\", () => {\n if (Viewer.readyState === \"complete\") {\n resolve();\n }\n });\n\n Viewer.loadDocument({\n url: docURL,\n });\n });\n }\n\n browserPrint() {\n this.printCallback(this.iframeWin);\n }\n\n cleanUp() {\n delete this.window.printInstance;\n if (this.removeIframe) {\n this.iframe.parentElement.removeChild(this.iframe);\n }\n }\n}\n\nexport function printHTML(htmlDoc: string, config: PrintConfig) {\n const instance = new VivliostylePrint(htmlDoc, config);\n instance.init();\n}\n"],"names":["isDebug","setDebug","value","PageProgression","PageSide","ReadyState","pageProgressionOf","str","LTR","RTL","Error","constants","LogLevel","argumentsToErrorInfo","args","a","Array","from","e","shift","error","messages","buildMessageAndStackTrace","stack","concat","length","logger","[object Object]","opt_console","this","msg","debug","log","console","info","warn","level","listeners","forEach","listener","push","var_args","arguments","consoleDebug","triggerListeners","DEBUG","consoleInfo","INFO","consoleWarn","WARN","consoleError","ERROR","HOOKS","hooks","registerHook","name","fn","hooksForName","Logging.logger","removeHook","index","indexOf","splice","getHooksForName","plugin","Profiler","performanceInstance","registerTiming","noop","registerStartTiming","registerEndTiming","timestamp","call","timestamps","st","Object","keys","stamps","l","i","t","startEnd","now","fallbackPerformanceInstance","Date","profiler","window","performance","forceRegisterStartTiming","profile","printTimings","disable","enable","emptyObj","stringToJSON","JSON","parse","stripFragment","url","r","match","baseURL","location","href","setBaseURL","resourceBaseURL","setResourceBaseURL","resolveURL","relURL","startsWith","toLowerCase","substr","stripFragmentAndQuery","lastIndexOf","urlOption","j","replace","convertSpecialURL","exec","NS","asString","v","toString","PriorityQueue","queue","item","parentIndex","Math","floor","parent","compare","result","curr","pop","size","childIndex","knownPrefixes","propNameMap","checkIfPropertySupported","prefix","prop","probe","document","createElement","style","setProperty","documentElement","cssPropName","txt","toUpperCase","cssToJSProp","getPrefixedPropertyNames","prefixed","setCSSProperty","elem","prefixedPropertyNames","err","getCSSProperty","opt_value","propertyNames","getPropertyValue","getLangAttribute","element","lang","getAttributeNS","XML","namespaceURI","XHTML","getAttribute","StringBuffer","list","join","escapeChar","charCodeAt","escapeCSSIdent","escapeCSSStr","lightURLEncode","encodeURIComponent","isLetter","ch","escapeNameStrToHex","s","escapeCharToHex","escapeRegExp","unescapeStrFromHex","regexp","RegExp","String","fromCharCode","parseInt","substring","unescapeCharFromHex","binarySearch","high","good","h","m","numberCompare","b","indexArray","arr","key","map","k","multiIndexArray","SimpleEventTarget","evt","type","target","currentTarget","capture","hasVerticalBBoxBug","hasInlineBlockJustificationBug","hasSoftWrapOpportunityAfterHyphenBug","hasSoftWrapOpportunityByWbrBug","getId","node","nodeType","idtxt","escape","unescapeChar","unescape","parseExtVal","extstr","p","parseExt","ext","RefStep","sb","append","pos","ChildStep","id","sideBias","childElements","children","childElementCount","child","firstChild","min","next","nextSibling","after","OffsetStep","offset","textBefore","textAfter","textLength","textContent","Fragment","fragstr","steps","charAt","Base.asString","doc","ref","applyTo","slice","text","parentNode","previousSibling","trim","reverse","Base.StringBuffer","appendTo","clonePreferences","pref","fontFamily","lineHeight","margin","hyphenate","columnWidth","horizontal","nightMode","spreadView","pageBorder","enabledMediaTypes","assign","defaultPaperSize","undefined","defaultPreferencesInstance","vivliostyle","print","Special","PENDING","letterbox","viewW","viewH","objW","objH","scale","cssString","Base.escapeCSSStr","cssIdent","Base.escapeCSSIdent","makeQualifiedName","objName","memberName","nextKeyIndex","LexicalScope","resolver","scopeKey","zero","Const","one","_true","_false","builtIns","ceil","round","sqrt","max","x","defineBuiltInName","pageWidth","pageHeight","fontSize","pubTitle","docTitle","values","Native","qualifiedName","val","funcs","isViewportRelativeLengthUnit","unit","defaultUnitSizes","px","in","pt","pc","cm","mm","q","em","rem","ex","dppx","dpi","dpcm","needUnitConversion","Context","rootScope","viewportWidth","viewportHeight","actualPageWidth","actualPageHeight","initialFontSize","rootFontSize","scope","scopes","clearScope","isRoot","pvw","pvh","vw","pageAreaWidth","vh","pageAreaHeight","pageVertical","params","noBuiltInEval","body","evaluate","apply","not","enabled","feature","req","actual","screen","availWidth","availHeight","pixelDepth","getScopeContext","Val","buf","priority","context","other","dependencyCache","cached","dependCore","dependOuter","queryVal","evaluateCore","storeVal","Prefix","super","evalPrefix","getOp","expand","constructor","Infix","lhs","rhs","evalInfix","thisPriority","getPriority","Logical","Comparison","Additive","Multiplicative","Not","Negate","And","AndMedia","Or","OrMedia","Lt","Le","Gt","Ge","Eq","Ne","Add","Subtract","Multiply","Divide","Modulo","Numeric","num","queryUnitSize","Named","evalName","MediaName","evalMediaName","Call","appendValArray","evalCall","expandedParams","expanded","expandValArray","Cond","cond","ifTrue","ifFalse","MediaTest","evalMediaTest","Param","and","v1","v2","add","sub","mul","div","Visitor","visit","empty","slash","ident","numeric","visitNum","color","func","expr","FilterVisitor","before","visitValues","SpaceList","CommaList","Func","visitor","Empty","instance","Exprs.Const","visitEmpty","Slash","visitSlash","Str","visitStr","nameTable","Ident","visitIdent","getName","Exprs.Multiply","Exprs.Numeric","visitNumeric","Num","Int","visitInt","Color","rgb","visitColor","URL","visitURL","appendList","separator","visitSpaceList","visitCommaList","visitFunc","Expr","visitExpr","toNumber","isNumeric","isNum","convertNumericToPx","absolute","all","always","auto","avoid","balance","balance_all","block","block_end","block_start","both","bottom","border_box","break_all","break_word","crop","cross","column","exclusive","fixed","flex","footnote","footer","header","hidden","horizontal_tb","inherit","inline","inline_block","inline_end","inline_start","landscape","left","line","list_item","ltr","manual","none","normal","oeb_page_foot","oeb_page_head","page","relative","right","same","snap_block","spread","_static","rtl","table","table_caption","table_cell","table_footer_group","table_header_group","table_row","top","transparent","vertical_lr","vertical_rl","visible","hundredPercent","fullWidth","fullHeight","numericZero","processingOrder","font-size","processingOrderFn","name1","name2","Number","MAX_VALUE","Rect","x1","y1","x2","y2","Point","y","Insets","Segment","low","winding","shapeId","Band","segmentCompare","s1","s2","Shape","points","prev","offsetX","offsetY","shapeForEllipse","cx","cy","rx","ry","PI","sin","cos","shapeForRect","BandIntersection","lowOrHigh","intersectY","isNaN","addBandIntersections","intersections","w1","w2","mergeIntersections","includeCount","excludeCount","shapeCount","windings1","windings2","xranges","inside","intersectionCount","intersection","stillInside","rotateBox","box","unrotateBox","rotateShape","shape","point","rotatePoint","normalize","bands","currBand","prevBand","findBand","mid","findUppermostFullyOpenRect","rect","band","topEdge","bottomEdge","findBottommostFullyOpenRect","SetVisitor","Css.Visitor","propSet","IntVisitor","toInt","def","ShapeVisitor","collect","coords","Css.Numeric","width","height","numbers","coord","GeometryUtil.Point","GeometryUtil.Shape","GeometryUtil.shapeForRect","GeometryUtil.shapeForEllipse","toShape","getShape","CountersVisitor","reset","counters","toCounters","UrlTransformVisitor","Css.FilterVisitor","baseUrl","transformer","Css.URL","transformURL","cloneCounterValues","TargetCounterReference","targetId","resolved","spineIndex","pageIndex","CounterListener","counterStore","documentURLTransformer","transformFragment","countersById","getExprContentListener","CounterResolver","pageScope","styler","transformedId","Base.resolveURL","format","self","Exprs.Native","currentPageCounters","getCounterNumber","registerPageCounterExpr","lookForElement","targetCounters","styleUntilIdIsReached","currentPage","elementsById","pageCountersById","getFragment","getTransformedId","getTargetCounters","countersOfName","pageCounters","getTargetPageCounters","resolveReference","pageCountersOfName","saveReferenceOfCurrentPage","elementCountersOfName","CounterStore","counterName","pageNumber","cascadedPageStyle","resetMap","previousPageCounters","resetVal","CssProp.toCounters","resetCounterName","definePageCounter","incrementMap","increment","incrementVal","incrementCounterName","counterValues","currentPageCountersStack","unresolvedRefs","unresolvedReferences","resolvedRefs","resolvedReferences","pushed","referencesToSolve","resolve","newReferencesOfCurrentPage","some","ids","oldPageIndex","pageIndicesById","unresolve","prevPageCounters","isResolved","every","equals","refs","idRefs","sort","r1","r2","o","referencesToSolveStack","pagesCounterExprs","exprContentListener","bind","findIndex","setAttribute","PAGES_COUNTER_ATTR","viewport","nodes","root","querySelectorAll","pages","LayoutConstraint","nodeContext","viewNode","escapeParseSingle","code","escapeParse","TokenType","Action","Token","EOF","makeActions","spec","END","INVALID","actionsNormal","SPACE","BANG","STR2","HASH","DOLLAR","PERCENT","AMP","STR1","O_PAR","C_PAR","STAR","PLUS","COMMA","MINUS","DOT","SLASH","INT","COLON","SEMICOL","LT","EQ","GT","QMARK","AT","IDENT","O_BRK","BSLASH","C_BRK","HAT","O_BRC","BAR","C_BRC","TILDE","actionsIdent","ENDIDNT","FUNC","CONT","IDNTESC","actionsNumOrClass","TOCLASS","TONUM","TOIDES","actionsMinus","MINMIN","TOINT","TOIDENT","actionsIdentEsc","ENDIDES","CHKPOSS","FUNCES","actionsInt","ENDINT","PCUNIT","NUMBER","UNIT","actionsNumber","ENDNUM","actionsCheckEq","EQTAIL","actionsColon","COL_COL","actionsBar","BAR_BAR","actionsAmp","AMP_AMP","actionsSlash","COMMENT","actionsComment","COMMST","actionsCommentStar","ENDNOTK","actionsMinusMinus","KILL1","actionsLt","LT_BG","actionsLtBang","LT_BG_M","actionsLtBangMinus","KILL2","actionsIdentEscChr","IDESCH","actionsStr1","ENDSTR","STR1ESC","actionsStr2","STR2ESC","actionsStr1Esc","ENDESTR","CHKPOSN","actionsStr2Esc","actionsURL","URL2","URL1","actionsURLInside","ENDURL","CHKSP","URLESC","NaN","actionsURLInside1","TERMURL","actionsURLInside2","actionsURLTail","FINURL","INITIAL_INDEX_MASK","Tokenizer","input","handler","indexMask","buffer","tail","fillBuffer","n","head","newIndexMask","newBuffer","oldIndex","newIndex","position","token","mnemonics","reallocate","actions","tokenType","tokenPosition","tokenText","tokenNum","seenSpace","backslashPos","charCode","STR","CLASS","BANG_EQ","NUM","parseFloat","NUMERIC","precededBySpace","privateCurrentTask","primaryScheduler","currentTask","newFrame","task","frame","Frame","state","FrameState","ACTIVE","newResult","SyncResultImpl","handle","onErr","raise","start","opt_name","opt_timer","getScheduler","Scheduler","TimerImpl","run","valueOf","delay","setTimeout","clearTimeout","timer","Base.PriorityQueue","timeout","currentTime","sliceOverTime","inTimeSlice","newTime","peek","scheduledTime","timeoutToken","wakeupTime","doTimeSlice","continuation","opt_delay","c","order","arm","remove","canceled","resumeInternal","Task","then","done","running","callback","callbacks","savedTask","schedule","suspend","Continuation","otherComp","scheduler","finish","cancel","waitTarget","whenDone","exception","opt_frame","fillStack","f","unwind","out","ResultImpl","isPending","res1","res2","res","thenAsync","INIT","checkEnvironment","FINISHED","DEAD","isTimeSliceOver","step","more","loop","LoopBodyFrame","get","opt_waitTarget","Fetcher","fetch","Task.currentTask","Task.newFrame","resource","piggibacks","piggybacks","arrived","Task.newResult","waitForFetchers","fetchers","thenReturn","fetcher","hasArrived","loadElement","src","localName","removeAttribute","addEventListener","Base.NS","SVG","setAttributeNS","XLINK","XMLHttpRequestResponseType","ajax","opt_type","opt_method","opt_data","opt_contentType","request","XMLHttpRequest","response","status","statusText","contentType","responseText","responseXML","responseBlob","open","responseType","onreadystatechange","readyState","DOCUMENT","HTMLDocument","TEXT","makeBlob","contentTypeHeader","getResponseHeader","setRequestHeader","send","test","overrideMimeType","parts","builderCtr","builder","getBlob","Blob","ResourceStore","parser","opt_required","opt_message","Base.stripFragment","resources","isTocBox","endsWith","userAgentXmlUrl","Base.resourceBaseURL","isUserAgentXml","UserAgentXml","TaskUtil.Fetcher","fetchInner","parseJSONResource","store","Base.stringToJSON","SPECIFICITY_USER_AGENT","SPECIFICITY_USER","SPECIFICITY_AUTHOR","SPECIFICITY_STYLE","SPECIFICITY_STYLE_IMPORTANT","SPECIFICITY_AUTHOR_IMPORTANT","SPECIFICITY_USER_IMPORTANT","StylesheetFlavor","colorFromHash","Css.Color","ParserHandler","flavor","AUTHOR","ns","op","pseudoelem","startWhenRule","flowName","pseudoName","classes","important","funcName","USER_AGENT","USER","DispatchParserHandler","slave","tokenizer","getScope","startStylesheet","tagSelector","classSelector","pseudoclassSelector","pseudoelementSelector","idSelector","attributeSelector","descendantSelector","childSelector","adjacentSiblingSelector","followingSiblingSelector","nextSelector","startSelectorRule","startFontFaceRule","startFootnoteRule","startViewportRule","startDefineRule","startRegionRule","startPageRule","startPageMarginBoxRule","startFlowRule","startPageTemplateRule","startPageMasterRule","startPartitionRule","startPartitionGroupRule","startRuleBody","property","endRule","startFuncWithSelector","endFuncWithSelector","SkippingParserHandler","owner","topLevel","getCurrentToken","errorMsg","depth","popHandler","SlaveParserHandler","message","report","pushHandler","reportAndSkip","actionsBase","actionsStyleAttribute","actionsSelector","actionsSelectorInFunc","actionsSelectorCont","actionsSelectorStart","actionsPropVal","actionsExprVal","actionsExprOp","actionsError","actionsErrorDecl","actionsErrorSelector","OP_MEDIA_AND","CssTokenizer.TokenType","LAST","ExprContext","SELECTOR_START","RULE_END","DONE","PROP","SELECTOR_NAME","SELECTOR_ANY","SELECTOR_ID","SELECTOR_CLASS","SELECTOR_ATTR","SELECTOR_PSEUDOCLASS","SELECTOR_CHILD","SELECTOR_SIBLING","SELECTOR_FOLLOWING_SIBLING","SELECTOR_NAME_1","SELECTOR_ANY_1","SELECTOR_ID_1","SELECTOR_CLASS_1","SELECTOR_ATTR_1","SELECTOR_BODY","SELECTOR_PSEUDOCLASS_1","SELECTOR_PSEUDOELEM","SELECTOR_NEXT","VAL_IDENT","VAL_HASH","VAL_NUM","VAL_INT","VAL_NUMERIC","VAL_STR","VAL_URL","VAL_COMMA","VAL_SLASH","VAL_FUNC","VAL_C_PAR","VAL_END","VAL_BRC","VAL_BANG","VAL_PLUS","VAL_FINISH","EXPR_IDENT","EXPR_NUM","EXPR_NUMERIC","EXPR_STR","EXPR_O_PAR","EXPR_FUNC","EXPR_PREFIX","EXPR_PARAM","EXPR_INFIX_NAME","EXPR_INFIX","GT_EQ","LT_EQ","EQ_EQ","EXPR_C_PAR","EXPR_O_BRC","EXPR_SEMICOL","ERROR_PUSH","ERROR_POP","ERROR_SEMICOL","ERROR_POP_DECL","Parser","exprContext","MEDIA","sep","valStack","count","Css.SpaceList","Css.Func","extractVals","Css.CommaList","propName","val2","tok","unshift","e1","e2","er","Exprs.OrMedia","Css.Expr","Exprs.Call","Exprs.makeQualifiedName","isMediaName","Exprs.MediaTest","Exprs.Not","exprError","Exprs.Negate","Exprs.And","Exprs.AndMedia","Exprs.Or","Exprs.Lt","Exprs.Gt","Exprs.Le","Exprs.Ge","Exprs.Eq","Exprs.Ne","Exprs.Add","Exprs.Subtract","Exprs.Divide","Exprs.Modulo","Exprs.Cond","consume","hasLeadingPlus","hasMinusSign","hasSign","condition","classList","split","className","Exprs.and","Exprs.Named","ruleStack","parsingValue","parsingStyleAttr","parsingMediaQuery","parsingFunctionParam","token1","parserLoop","nthToken","isInsidePropertyOnlyRule","mark","propImportant","namespacePrefixToURI","defaultNamespaceURI","pseudoclassType","runParser","POSITIVE_INFINITY","readNthPseudoParams","readPseudoParams","TILDE_EQ","BAR_EQ","HAT_EQ","DOLLAR_EQ","STAR_EQ","regionRule","pageRule","Css.getName","Css.Num","Css.Int","Exprs.isViewportRelativeLengthUnit","Css.Str","valStackReduce","Css.slash","hasMark","unmark","IMPORT","Exprs.MediaName","Exprs.Param","exprStackReduce","WHEN","startMediaRule","importCondition","importReady","importURL","ruleName","rulePseudoName","errorBrackets","ErrorHandler","parseStylesheet","media","parseMediaQuery","CssTokenizer.Tokenizer","makeCondition","toExpr","resolvedURL","innerFrame","parseStylesheetFromURL","timeSlice","parseStylesheetFromText","Task.handle","thenFinish","Net.ajax","xhr","parseValue","numProp","z-index","column-count","flow-linger","opacity","flow-priority","utilization","evaluateExprToCSS","takesOnlyNum","Css.empty","Css.ident","evaluateCSSToCSS","isExpr","matchANPlusB","AnyMatcher","matchers","matcher","matches","AllMatcher","NthFragmentMatcher","elementOffset","fragmentIndex","indices","fragmentIndices","entry","MatcherBuilder","viewCondition","strs","inheritedProps","azimuth","border-collapse","border-spacing","caption-side","clip-rule","color-interpolation","color-rendering","cursor","direction","elevation","empty-cells","fill","fill-opacity","fill-rule","font-kerning","font-size-adjust","font-family","font-feature-settings","font-style","font-stretch","font-variant","font-weight","glyph-orientation-vertical","hyphens","hyphenate-character","hyphenate-limit-chars","hyphenate-limit-last","image-rendering","image-resolution","letter-spacing","line-break","line-height","list-style-image","list-style-position","list-style-type","marker","marker-end","marker-mid","marker-start","orphans","overflow-wrap","paint-order","pointer-events","pitch-range","quotes","richness","ruby-align","ruby-position","speak-header","speak-numeral","speak-punctuation","speech-rate","shape-rendering","stress","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","tab-size","text-align","text-align-last","text-anchor","text-decoration-skip","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-combine-upright","text-indent","text-justify","text-rendering","text-size-adjust","text-transform","text-underline-position","visibility","voice-family","volume","white-space","widows","word-break","word-spacing","word-wrap","writing-mode","polyfilledInheritedProps","getPolyfilledInheritedProps","Plugin.getHooksForName","Plugin.HOOKS","POLYFILLED_INHERITED_PROPS","reduce","props","supportedNamespaces","http://www.idpf.org/2007/ops","http://www.w3.org/1999/xhtml","http://www.w3.org/2000/svg","coupledPatterns","coupledExtentPatterns","geomNames","sides","names","max-width","max-height","min-width","min-height","buildCouplingMap","sideMap","extentMap","pattern","side","extentPattern","extent","couplingMapVert","block-start","block-end","inline-start","inline-end","block-size","inline-size","couplingMapHor","couplingMapVertRtl","couplingMapHorRtl","CascadeValue","specificity","CssParser.evaluateCSSToCSS","ConditionalCascadeValue","cascadeValues","tv","av","isEnabled","getBaseValue","SPECIALS","region-id","fragment-selector-id","isSpecialName","isPropName","isInherited","getProp","setProp","getStyleMap","getMutableStyleMap","getViewConditionalStyleMap","getSpecial","getMutableSpecial","mergeIn","pseudoelement","regionId","viewConditionMatcher","styleKey","styleMap","styles","as","ts","prototype","increaseSpecificity","chainActions","chain","action","chained","InheritanceVisitor","Exprs.isAbsoluteLengthUnit","Exprs.defaultUnitSizes","parentFontSize","convertFontRelativeLengthToPx","convertFontSizeToPx","getFontSize","baseFontSize","ratio","CascadeAction","cascadeInstance","CompoundAction","ConditionItemAction","conditionItem","pushConditionItem","fresh","ApplyRuleAction","viewConditionId","currentStyle","buildViewConditionMatcher","ChainedAction","cascade","CheckClassAction","currentClassNames","includes","insertInTable","CheckIdAction","currentId","currentXmlId","CheckLocalNameAction","currentLocalName","tags","CheckNSTagAction","currentNamespace","nsPrefix","nsCount","nsTag","nstags","CheckTargetEpubTypeAction","epubTypePatt","currentElement","ownerDocument","getElementById","epubType","epub","CheckNamespaceAction","CheckAttributePresentAction","hasAttributeNS","CheckAttributeEqAction","epubtypes","CheckNamespaceSupportedAction","CheckAttributeRegExpAction","attr","CheckLangAction","langRegExp","IsFirstAction","isFirst","IsRootAction","IsNthAction","Matchers.matchANPlusB","IsNthSiblingOfTypeAction","currentSiblingTypeCounts","IsNthLastSiblingAction","currentFollowingSiblingOrder","currentSiblingOrder","IsNthLastSiblingOfTypeAction","counts","currentFollowingSiblingTypeCounts","nsCounts","nextElementSibling","IsEmptyAction","Node","ELEMENT_NODE","TEXT_NODE","IsEnabledAction","disabled","IsDisabledAction","IsCheckedAction","selected","checked","CheckConditionAction","conditions","dependentConditions","CheckAppliedAction","applied","cloned","NegateActionsSet","checkAppliedAction","firstAction","AbstractConditionItem","decrement","DescendantConditionItem","ChildConditionItem","AdjacentSiblingConditionItem","fired","FollowingSiblingConditionItem","AfterPseudoelementItem","afterprop","processPseudoelementProps","RestoreLangItem","QuotesScopeItem","oldQuotes","AttrValueFilterVisitor","attributeName","defaultValue","stringValue","createValueFromString","hasAttribute","ContentPropVisitor","counterResolver","maxDepth","quoteDepth","upper","lower","additiveNumbering","entries","additiveFormat","alphabeticNumbering","alphabetStr","alphabet","first","last","expandAlphabet","digit","alphabeticFormat","numbering","digits","negative","formal","markers","thousands","hundreds","tens","ones","chineseCounter","chineseTradInformal","numval","getPageCounterVal","getPageCountersVal","numvals","elementCounters","targetUrl","targetUrlStr","getTargetCounterVal","getTargetCountersVal","visitFuncCounter","visitFuncCounters","visitFuncTargetCounter","visitFuncTargetCounters","roman","armenian","georgian","hebrew","latin","alpha","greek","russian","square","disc","circle","ORDER_INCREMENT","copyTable","dst","clone","Cascade","pagetypes","mergeWith","counterListener","CascadeInstance","siblingTypeCountsStack","followingSiblingOrderStack","viewConditions","filter","currentElementOffset","Matchers.MatcherBuilder","dependentConditionMatchers","conditionId","buildAnyMatcher","buildAllMatcher","pageType","baseStyle","currentNSTag","currentEpubTypes","EMPTY","currentPageType","applyActions","scoping","counterScoping","displayVal","display","setMap","set","setVal","defineCounter","setCounterName","listItemCounts","listItemCount","pseudoprops","pushCounters","filterValue","popCounters","types","FB2","Base.getLangAttribute","siblingOrderStack","currentNamespaceTypeCounts","followingSiblingTypeCountsStack","applyAttrFilter","quotesCasc","itemToPushLast","quotesVal","countersOfId","pseudos","pseudoNames","pseudoProps","elementStyle","pseudoMap","applyAttrFilterInner","applyAction","currentDoc","ParseState","uaBaseCascade","CascadeParserHandler","CssParser.SlaveParserHandler","validatorSet","TOP","makePrimary","insertNonPrimary","patt","Base.escapeRegExp","footnoteContent","langValue","ActionClass","nthSelectorActionClasses","conditionCount","processChain","finishChain","isInsideSelectorRule","SELECTOR","insideSelectorRule","nextOrder","makeApplyRuleAction","validatePropertyAndHandleShorthand","simpleProperty","hook","converted","getImportantSpecificity","getBaseSpecificity","cascval","notParserHandler","NotParameterParserHandler","nth-child","nth-of-type","nth-last-child","nth-last-of-type","parentChain","DefineParserHandler","dim","defineName","PropSetParserHandler","PropertyParserHandler","CssParser.ErrorHandler","CssParser.SPECIFICITY_STYLE_IMPORTANT","CssParser.SPECIFICITY_STYLE","forEachViewConditionalStyles","viewConditionalStyles","mergeViewConditionalStyles","cascMap","mergeStyle","parseStyleAttribute","styleAttrValue","CssParser.parseStyleAttribute","isVertical","cascaded","vertical","writingModeCasc","writingMode","isRtl","directionCasc","flattenCascadedStyle","regionIds","isFootnote","forEachStylesInRegion","regionStyle","regions","footnoteRegion","to","newVal","oldVal","convertToPhysical","dest","transform","couplingMap","hasOwnProperty","cascVal","coupledName","targetName","coupledCascVal","createRegExpMap","valueMaps","toPhysical","logical","physical","convert","maps","maps2","replaced","horizontal-tb","vertical-rl","vertical-lr","toPhysicalMaps","toLogicalMaps","Size","getSize","clientLayout","sizes","original","maxWidth","minWidth","maxHeight","minHeight","container","getComputedValue","getElementComputedStyle","Base.setCSSProperty","insertBefore","appendChild","writingModeProperty","Base.getPrefixedPropertyNames","writingModeValue","inlineSizeName","blockSizeName","getFillAvailableInline","getMaxContentInline","getMinContentInline","getFitContentInline","fillAvailableInline","minContentInline","parsedFillAvailable","maxContentInline","getIdealBlock","getFillAvailableBlock","FILL_AVAILABLE_INLINE_SIZE","MAX_CONTENT_INLINE_SIZE","MIN_CONTENT_INLINE_SIZE","FIT_CONTENT_INLINE_SIZE","FILL_AVAILABLE_BLOCK_SIZE","MAX_CONTENT_BLOCK_SIZE","MIN_CONTENT_BLOCK_SIZE","FIT_CONTENT_BLOCK_SIZE","FILL_AVAILABLE_WIDTH","FILL_AVAILABLE_HEIGHT","MAX_CONTENT_WIDTH","MAX_CONTENT_HEIGHT","MIN_CONTENT_WIDTH","MIN_CONTENT_HEIGHT","FIT_CONTENT_WIDTH","FIT_CONTENT_HEIGHT","removeChild","DIFF_DELETE","DIFF_INSERT","DIFF_EQUAL","diff_main","text1","text2","cursor_pos","_fix_unicode","editdiff","oldText","newText","oldRange","newRange","oldLength","newLength","oldCursor","oldBefore","oldAfter","maybeNewCursor","newCursor","newBefore","newAfter","prefixLength","oldPrefix","newPrefix","oldMiddle","newMiddle","make_edit_splice","suffixLength","oldSuffix","newSuffix","find_cursor_edit_diff","commonlength","diff_commonPrefix","commonprefix","diff_commonSuffix","commonsuffix","diffs","longtext","shorttext","hm","diff_halfMatchI_","best_longtext_a","best_longtext_b","best_shorttext_a","best_shorttext_b","seed","best_common","text1_a","text1_b","text2_a","text2_b","hm1","hm2","mid_common","diff_halfMatch_","diffs_a","diffs_b","text1_length","text2_length","max_d","v_offset","v_length","delta","front","k1start","k1end","k2start","k2end","d","k1","k1_offset","k2_offset","diff_bisectSplit_","k2","diff_bisect_","diff_compute_","diff_cleanupMerge","fix_unicode","pointer","count_delete","count_insert","text_delete","text_insert","previous_equality","ends_with_pair_start","stray","starts_with_pair_end","changes","text1a","text2a","text1b","text2b","diffsb","pointermin","pointermax","pointermid","pointerstart","is_surrogate_pair_start","pointerend","is_surrogate_pair_end","tuples","ret","remove_empty_tuples","diff","INSERT","DELETE","EQUAL","LayoutProcessor","PageFloats","Selectors","RepetitiveElement","Table","Vtree","restoreNewText","fastdiff","resolveIndex","coef","current","change","object","formattingContextType","FloatReference","flagmentLayoutConstraintType","isInstanceOfTableFormattingContext","isInstanceOfTableRowLayoutConstraint","Whitespace","ShadowType","delayedProps","transform-origin","delayedPropsIfRelativePositioned","DelayedItem","show","obj","hide","play","pause","resume","mute","muted","unmute","makeListener","actionFn","Page","Base.SimpleEventTarget","bleedBox","hrefHandler","anchorElement","preventDefault","dispatchEvent","isAuto","isAutoPageWidth","AUTO_PAGE_WIDTH_ATTRIBUTE","isAutoPageHeight","AUTO_PAGE_HEIGHT_ATTRIBUTE","triggers","elems","contains","delayedItems","getElementClientRect","dimensions","trigger","observers","observer","event","pageAreaElement","SPECIAL_ATTR","whitespaceFromPropertyValue","whitespace","IGNORE","NEWLINE","PRESERVE","canIgnore","Flow","parentFlowName","FlowChunk","startOffset","linger","repeated","breakBefore","clientrectIncreasingTop","clientrectDecreasingRight","isSameNodePositionStep","nps1","nps2","shadowType","isSameShadowContext","shadowContext","nodeShadow","shadowSibling","isSameNodePosition","np1","np2","offsetInNode","newNodePositionFromNodeContext","initialFragmentIndex","sourceNode","NONE","formattingContext","preprocessedTextContent","makeNodeContextFromNodePositionStep","NodeContext","copy","ShadowContext","xmldoc","parentShadow","superShadow","subShadow","sc1","sc2","FirstPseudo","outer","boxOffset","breakPenalty","floatReference","INLINE","hyphenateCharacter","breakWord","firstPseudo","clearSpacer","floatSide","clearSide","floatMinWrapBlock","columnSpan","verticalAlign","flexContainer","breakAfter","establishesBFC","containingBlockForAbsolute","repeatOnBreak","pluginProps","afterIfContinues","footnotePolicy","np","captionSide","inlineBorderSpacing","blockBorderSpacing","overflow","create","shared","cloneItem","npp","npc","toNodePositionStep","nc","ChunkPosition","primary","floats","FlowChunkPosition","chunkPosition","flowChunk","isSamePosition","FlowPosition","newfp","positions","newarr","startSide","LayoutPosition","newcp","highestSeenNode","highestSeenOffset","lookupPositionOffset","flows","flowPositions","thisFlowNames","otherFlowNames","flowPos","hasContent","flowChunkPosition","Container","marginTop","borderTop","paddingTop","marginBottom","borderBottom","paddingBottom","marginLeft","borderLeft","paddingLeft","marginRight","borderRight","paddingRight","getInsetRight","getInsetTop","getInsetLeft","getInsetBottom","originX","originY","innerShape","exclusions","computedBlockSize","snapWidth","snapHeight","setHorizontalPosition","getBoxDir","setVerticalPosition","lastChild","getInnerRect","withOffset","GeometryUtil.Rect","paddingX","paddingY","paddingWidth","paddingHeight","outerShapeProp","getOuterRect","CssProp.toShape","outerX","outerY","outerWidth","outerHeight","ContentPropertyHandler","rootContentValue","createTextNode","visitStrInner","img","createElementNS","CssParser.parseValue","nonTrivialContent","isPageFloat","COLUMN","REGION","PAGE","PageFloat","nodePosition","pageFloatLayoutContext","isAnchorAlreadyAppeared","PageFloatStore","nextPageFloatIndex","float","VtreeImpl.isSameNodePosition","createPageFloatId","PageFloatFragment","continuations","area","continues","isAllowedOnContext","getOuterShape","getOrder","PageFloatContinuation","PageFloatLayoutContext","generatingNodePosition","floatStore","getPreviousSibling","floatsDeferredFromPrevious","floatsDeferredToNext","getPreviousSiblingOf","getParent","getContainer","reattachFloatFragments","addPageFloat","getPageFloatLayoutContext","findPageFloatByNodePosition","forbiddenFloats","PageFloatLayoutStrategyResolver","findByFloat","forbid","isForbidden","floatFragment","dontInvalidate","addPageFloatFragment","floatFragments","fr1","fr2","invalidate","removePageFloatFragment","fragment","findPageFloatFragment","hasFloat","hasFloatFragments","getFlowName","anchorViewNode","floatAnchors","anchors","collectPageFloatAnchors","floatId","getDeferredPageFloatContinuations","cont","deferPageFloat","ignoreReference","hasPrecedingFloatsDeferredToNext","isAllowedToPrecede","lastFollowing","lastFollowingOfParent","getLastFollowingFloatInFragments","c1","c2","getPageFloatContinuationsDeferredToNext","getFloatsDeferredToNextInChildContexts","checkAndForbidFloatFollowingDeferredFloat","notAllowedFloat","findNotAllowedFloat","locked","removeEndFloatFragments","checkAndForbidNotAllowedFloat","deferredFloats","floatsInFragments","fr","f1","f2","invalidated","hasSameContainerAs","clear","layoutConstraints","isInvalidated","CssLogicalUtil.toLogical","CssLogicalUtil.toPhysical","logicalFloatSide","toLogical","stashEndFloatFragments","fragmentFloatSide","shouldBeStashedBefore","stashedFloatFragments","stashed","restoreStashedFragments","discardStashedFragments","getStashedFloatFragments","layoutContext","logicalSide","physicalSide","limit","getLimitValueInner","parentLimit","getLimitValue","limits","getLimitValuesInner","paddingRect","getPaddingRect","floatMinWrapBlockStart","floatMinWrapBlockEnd","resolveLengthPercentage","containerLength","convertLengthToPx","fragments","rootViewNodes","anchorEdge","init","force","setFloatAreaDimensions","blockStart","blockEnd","inlineStart","inlineEnd","blockOffset","inlineOffset","limitBlockStartEndValueWithOpenRect","getRect","openRect","GeometryUtil.unrotateBox","blockSize","inlineSize","outerBlockSize","outerInlineSize","GeometryUtil.rotateBox","GeometryUtil.findUppermostFullyOpenRect","GeometryUtil.findBottommostFullyOpenRect","getInsetBefore","getInsetAfter","getInsetStart","getInsetEnd","availableBlockSize","containerRect","Sizing.getSize","Sizing.Size","adjustContentRelativeSize","getContentInlineSize","availableInlineSize","setInlinePosition","setBlockPosition","getFloatFragmentExclusions","edge","Infinity","isContinuationOfAlreadyAppearedFloat","isFragmentWithAlreadyAppearedFloat","columnRect","columnBlockEnd","blockStartLimit","getPageFloatPlacementCondition","logicalClearSide","logicalSides","floatOrder","isPrecedingFragment","hasPrecedingFragmentInChildren","hasPrecedingFragmentInParents","getLayoutConstraints","layoutConstraint","addLayoutConstraint","pageFloatLayoutStrategies","strategy","appliesToNodeContext","appliesToFloat","register","toNodePosition","resolveFloatReferenceFromColumnSpan","floatArea","floatContainer","PageFloats.PageFloatFragment","Footnote","PageFloats.PageFloat","FootnoteFragment","LineFootnotePolicyLayoutConstraint","Vtree.isSameNodePosition","PageFloats.PageFloatLayoutStrategyResolver","PageFloats.FloatReference","regionContext","applyFootnoteStyle","convertPercentageSizesToPx","setComputedInsets","setComputedWidthAndHeight","constraint","forcedBreakValues","recto","verso","region","isForcedBreakValue","avoidBreakValues","avoid-page","avoid-column","avoid-region","isAvoidBreakValue","resolveEffectiveBreakValue","second","firstIsForcedBreakValue","secondIsForcedBreakValue","breakValueToStartSideValue","breakValue","startSideValueToBreakValue","startSideValue","calculateEdge","extraOffset","cbox","range","createRange","setStart","setEnd","boxes","getRangeClientRects","getBoundingClientRect","Base.checkVerticalBBoxBug","fullRange","fullBoxes","fullBox","abs","fixBoxesForNode","maxSize","boxSize","getElementHeight","getComputedMargin","isOrphan","removeFollowingSiblings","isSpecial","VtreeImpl.SPECIAL_ATTR","isSpecialNodeContext","Plugin.registerHook","AbstractBreakPosition","calculateOffset","getNodeContext","collectElementsOffset","elementsOffsets","repetitiveElement","minimum","calculateMinimumOffset","EdgeBreakPosition","breakOnEdge","overflows","overflowIfRepetitiveElementsDropped","penalty","updateOverflows","getMinBreakPenalty","findEdgeBreakPosition","isEdgeUpdated","preferDropping","isFirstContentOfRepetitiveElementsOwner","Break.isAvoidBreakValue","clonedPaddingBorder","calculateClonedPaddingBorder","LayoutHelper.calculateEdge","updateEdge","offsets","isOverflown","isInstanceOfRepetitiveElementsOwnerFormattingContext","repetitiveElements","getRepetitiveElements","isFirstContentNode","FLOW_ROOT_ATTR","blockify","displayStr","blockifiedStr","isAbsolutelyPositioned","getComputedDislayValue","isBlock","isInlineLevel","LayoutProcessorResolver","RESOLVE_LAYOUT_PROCESSOR","processor","BlockLayoutProcessor","leadingEdge","isFloatNodeContext","layoutFloatOrFootnote","isBreakable","layoutBreakableBlock","layoutUnbreakable","columnBlockSize","BreakPosition.EdgeBreakPosition","stopAtOverflow","parentNodeContext","removeSelf","LayoutHelper.removeFollowingSiblings","forceRemoveSelf","endOfColumn","clearOverflownViewNodes","fixJustificationIfNeeded","processFragmentedBlockEdge","BlockFormattingContext","firstTime","blockLayoutProcessor","isInstanceOfBlockFormattingContext","RESOLVE_FORMATTING_CONTEXT","Display.isBlock","AbstractLayoutRetryer","prepareLayout","tryLayout","saveState","mode","resolveLayoutMode","doLayout","positionAfter","accepted","accept","postLayout","initialPosition","clearNodes","restoreState","sibling","initialBreakPositions","breakPositions","initialFragmentLayoutConstraints","fragmentLayoutConstraints","initialStateOfFormattingContext","LayoutIteratorStrategy","initialNodeContext","atUnforcedBreak","break","LayoutIterator","initialState","loopWithFrame","loopFrame","VtreeImpl.canIgnore","afterIgnoredTextNode","startIgnoredTextNode","afterNonElementNode","startNonElementNode","afterInlineElementNode","startInlineElementNode","afterNonInlineElementNode","startNonInlineElementNode","afterNonDisplayableNode","startNonDisplayableNode","nextResult","nextInTree","nextNodeContext","breakLoop","continueLoop","EdgeSkipper","breakAtTheEdge","onStartEdges","leadingEdgeContexts","lastAfterNodeContext","needForcedBreak","Break.isForcedBreakValue","pageBreakType","checkOverflowAndSaveEdgeAndBreakPosition","modify","violateConstraint","allowLayout","Break.resolveEffectiveBreakValue","startNonInlineBox","endEmptyNonInlineBox","endNonInlineBox","repetitiveElementsCache","DOMParser","parseFromString","SHADOW","PSEUDO_ATTR","getPseudoName","setPseudoName","PseudoelementStyler","deep","getStyle","CssCascade.getStyleMap","nest","CssCascade.CascadeValue","contentProcessed","contentVal","Vtree.nonTrivialContent","Vtree.ContentPropertyHandler","isInstanceOfAfterIfContinuesLayoutConstraint","registerFragmentIndex","Matchers.NthFragmentMatcher","AfterIfContinues","viewRoot","pseudoColumn","PseudoColumn","initialPageBreakType","getColumn","layout","createNodePositionForPseudoElement","pseudoElement","PseudoElement.document","PseudoElement.setPseudoName","createShadowContext","VtreeImpl.ChunkPosition","VtreeImpl.ShadowContext","ROOTED","AfterIfContinuesLayoutConstraint","pseudoElementHeight","overflownNodeContext","allowed","affectTo","AfterIfContinuesElementsOffset","processAfterIfContinuesOfNodeContext","LayoutHelper.getElementHeight","calculatePseudoElementHeight","processAfterIfContinues","mediaTags","svg","audio","video","AllLayoutConstraint","constraints","BoxBreakPosition","BreakPosition.AbstractBreakPosition","checkPoints","alreadyEvaluated","breakNodeContext","findBoxBreakPosition","isSpecialInlineDisplay","Column","VtreeImpl.Container","viewDocument","setContainer","startEdge","beforeEdge","endEdge","afterEdge","isFloat","footnoteEdge","pageFloatExclusions","setViewRoot","stepIndex","prevContext","VtreeImpl.makeNodeContextFromNodePositionStep","flowRootFormattingContext","calculateOffsetInNodeForNodeContext","setCurrent","firstCharPattern","peelOff","bodyFrame","LayoutHelper.isSpecialNodeContext","maybePeelOff","position1Param","positionParam","postLayoutBlock","position1","cssFloat","getTopEdge","getLeftEdge","getBottomEdge","getRightEdge","createFloat","LayoutHelper.isOrphan","insets","GeometryUtil.Insets","parseComputedLength","borderLeftWidth","borderTopWidth","borderRightWidth","borderBottomWidth","boxSizing","nodeContextIn","buildDeepElementView","nodeContextAfter","floatBBox","floatBox","parentBox","getStartEdge","getEndEdge","floatBoxMeasure","floatHorBox","dir","bottommostFloatTop","boxExtent","floatWidth","floatHeight","floatBottom","GeometryUtil.positionFloat","getComputedInsets","getContainingBlockForAbsolute","floatBoxEdge","floatBoxTop","killFloats","floatBands","lastY","floatBand","GeometryUtil.addFloatToBands","createFloats","leftFloatEdge","rightFloatEdge","updateMaxReachedAfterEdge","floatLayoutContext","forceNonfitting","containingBlockRect","adjustPageFloatArea","fitWithinContainer","floatAreaElement","parentPageFloatLayoutContext","PageFloats.PageFloatLayoutContext","parentContainer","PageFloatArea","setupFloatArea","allowFragmented","pageFloatFragment","originalContinuations","firstFloat","createPageFloatArea","newPosition","failed","floatChunkPosition","newFragment","createPageFloatFragment","cancelLayout","layoutSinglePageFloatFragment","layoutStashedPageFloats","success","PageFloats.PageFloatContinuation","excluded","newFloatAreas","newFragments","stashedFragment","anchor","applyPseudoelementStyle","columnContext","findByNodeContext","createPageFloat","VtreeImpl.newNodePositionFromNodeContext","setFloatAnchorViewNode","registerPageFloatAnchor","nodeContextOverflowingDueToRepetitiveElements","layoutPageFloatInner","insertionPoint","span","inner","textIndent","textAlign","leftPos","rightPos","inlineBlock","Base.checkInlineBlockJustificationBug","padding","paddingStr","insertAfter","Base.checkSoftWrapOpportunityAfterHyphenBug","hyphenChar","resolveHyphenateCharacter","prevSibling","prevText","Base.checkSoftWrapOpportunityByWbrBug","fixJustificationOnHyphen","createJustificationAdjustmentElement","br","spanRect","brRect","addAndAdjustJustificationElement","compensateJustificationLineHeight","resNodeContext","lastCheckPoints","totalLineCount","linePositions","findLinePositions","lineBreak","findAcceptableBreakInside","finishBreak","resNodeContextParam","buildViewToNextBlockEdge","trailingEdgeContexts","maxPos","minNeg","checkPointIndex","lineCont","overflown","BreakPosition.calculateOffset","getTrailingMarginEdgeAdjustment","processLineStyling","saveBoxBreakPosition","isLoneImage","POST_LAYOUT_BLOCK","linePosition","isUpdateMaxReachedAfterEdge","effectiveLinePosition","lowCP","low1","highCP","high1","mid1","edgePosition","findEndOfLine","textNode","resolveTextNodeBreaker","breakTextNode","RESOLVE_TEXT_NODE_BREAKER","TextNodeBreaker","end","wentUp","lastGood","haveStart","endNotReached","seekRange","setStartBefore","LayoutHelper.isSpecial","setEndAfter","boxList","getRangeBoxes","VtreeImpl.clientrectDecreasingRight","VtreeImpl.clientrectIncreasingTop","lineBefore","lineAfter","lineEnd","lineLength","overlap","getBoxSize","getBeforeEdge","getAfterEdge","Base.numberCompare","walkUpBlocks","Element","paddingBorders","getComputedPaddingBorder","bp","repetitiveElementsOffset","getOffsetByRepetitiveElements","firstOverflowing","findFirstOverflowingEdgeAndCheckPoint","lineIndex","Base.binarySearch","forceCutBeforeOverflowing","checkPoint","blockEdge","getAfterEdgeOfBlockContainer","blockParent","cp","LayoutProcessor.LayoutProcessorResolver","find","LayoutProcessor.blockLayoutProcessor","nextPenalty","findAcceptableBreak","minPenalty","breakPosition","initialComputedBlockSize","skipTailEdges","flowPosition","marginEdge","saveEvenOverflown","checkOverflowAndSaveEdge","saveEdgeBreakPosition","spacer","spacerBox","clearEdge","getPageFloatClearEdge","wAdj","hAdj","LayoutProcessor.isInstanceOfBlockFormattingContext","forcedBreakValue","fc","isBFC","processForcedBreak","layoutProcessor","applyClearance","zeroIndent","viewTag","nodeContextParam","lastAfterPosition","resultNodeContext","PageFloats.isPageFloat","layoutPageFloat","layoutFloat","skipEdges","stopByOverflow","columnBBox","include","exclude","granularity","segments","segment","addSegments","segmentCount","lowestIncludeIndex","segmentIndex","activeSegments","y2min","yn","bandIntersections","bi1","bi2","rw","GeometryUtil.shapesToBands","getInnerShape","getExclusions","chunkPositions","initGeom","breakAtEdge","createEdgeBreakPosition","isFullWithPageFloats","openAllViews","nextInTreeListener","removeEventListener","retryer","ColumnLayoutRetryer","doFinishBreak","pseudoParent","doFinishBreakOfFragmentLayoutConstraints","isColumnFullWithPageFloats","getMaxBlockSizeOfPageFloats","sortedFragmentLayoutConstraints","getPriorityOfFinishBreak","pending","layoutNext","findAcceptableBreakPosition","breakPositionChosen","isPseudoelement","blockStartEdgeOfBlockEndFloats","getBlockStartEdgeOfBlockEndFloats","isFinite","blockDistanceToBlockEndFloats","isInstanceOfRepetitiveElementsOwnerLayoutConstraint","getElementsOffsetsForTableCell","parentClonedPaddingBorder","startNodeContexts","allowBreakAtStartPosition","startNodeContext","checkpointIndex","viewIndex","data","breakAfterSoftHyphen","breakAfterOtherCharacter","updateNodeContext","replaceData","ch0","ch1","Base.isLetter","LayoutRetryers.AbstractLayoutRetryer","DefaultLayoutMode","initialOverflown","processAfterIfContinuesOfAncestors","hasNextCandidate","nextCandidate","fixFloatSizeAndPosition","refWidth","refHeight","convertPercentageToPx","refValue","valueString","Base.getCSSProperty","percentageValue","rootViewNode","floatMargins","RepetitiveElementsOwnerFormattingContext","rootSourceNode","getRootNodeContext","belongsTo","Shared.repetitiveElementsCache","elements","RepetitiveElements","ownerSourceNode","headerNodePosition","headerSourceNode","headerViewNode","footerNodePosition","footerSourceNode","footerViewNode","headerHeight","footerHeight","isSkipHeader","isSkipFooter","enableSkippingFooter","enableSkippingHeader","rootNodeContext","appendElementToFragment","Layout.PseudoColumn","allowInsertRepeatitiveElements","moveChildren","isAfterLastContent","findResultFromCache","afterLastContentNodeCache","isAfterNodeContextOf","lastContentSourceNode","affectedNodeCache","cache","calculator","cacheEntry","includeChildren","parentsOfNode","currentParent","previousElementSibling","firstContentSourceNode","LayoutEntireBlock","doneInitialLayout","updateHeight","LayoutFragmentedBlock","LayoutEntireOwnerBlock","doInitialLayout","LayoutFragmentedOwnerBlock","RepetitiveElementsOwnerLayoutConstraint","isEnableToUpdateState","updateState","preventSkippingFooter","appendHeaderToFragment","appendHeader","appendFooterToFragment","appendFooter","prepareLayoutFragment","RepetitiveElementsOwnerLayoutRetryer","preventSkippingHeader","EntireBlockLayoutStrategy","LayoutUtil.EdgeSkipper","isHeaderRegistered","setHeaderNodeContext","isFooterRegistered","setFooterNodeContext","appendHeaderToAncestors","eachAncestorNodeContext","repetitiveLayoutProcessor","LayoutProcessor.BlockLayoutProcessor","getRootViewNode","getRepetitiveElementsOwnerFormattingContextOrNull","isHeaderSourceNode","isFooterSourceNode","layoutEntireBlock","LayoutUtil.LayoutIterator","iterate","Layout.processAfterIfContinues","TableRow","rowIndex","cell","cells","TableCell","columnIndex","viewElement","colSpan","rowSpan","slot","anchorSlot","TableSlot","TableCellFragment","pseudoColumnContainer","cellNodeContext","TableCaptionView","BetweenTableRowBreakPosition","getAcceptableCellBreakPositions","acceptableCellBreakPositions","cellFragments","getCellFragments","cellFragment","findRowIndexBySourceNode","getRowSpanningCellsOverflowingTheRow","getRowIndex","getCellFragmentOfCell","InsideTableRowBreakPosition","beforeNodeContext","allCellsBreakable","isStartNodeContext","isLastAfterNodeContext","row","getRowByIndex","isFreelyFragmentableRow","getCellsFallingOnRow","TableFormattingContext","RepetitiveElementImpl.RepetitiveElementsOwnerFormattingContext","tableSourceNode","cellBreakPositions","cellNodePosition","rows","rowSlots","slots","addRow","addCell","rowUpper","getRowSlots","startColIndex","setAnchorSlot","uniqueCells","getMinimumHeight","tableWidth","columnCount","sum","setHeight","tableCell","col","collected","collectElementsOffsetFromColumn","elementsInColumn","ElementsOffsetOfTableCell","repeatitiveElementsInColumns","calculateMaxOffsetOfColumn","maxOffset","isValidParentOfTableRow","isTableRowGrouping","isTableRoot","skipNestedTable","parentDisplay","isNestedInlineTable","EntireTableLayoutStrategy","postLayoutBlockContents","captionView","captions","inHeaderOrFooter","inRow","computedStyle","lastRowViewNode","registerCheckPoint","TableLayoutStrategy","originalStopAtOverflow","colWidths","startChunkPosition","cellViewNode","getColSpanningCellWidth","addCellFragment","slotIndex","cellBreakPosition","rowSpanningCellBreakPositions","currentRowIndex","extractRowSpanningCellBreakPositions","rowCount","currentRow","spanningCellRowIndex","occupiedSlotIndices","rowCellBreakPositions","rowNodeContext","cont1","addDummyCellUntil","upperColumnIndex","dummy","breakChunkPosition","layoutCell","getColumnCount","inHeader","inFooter","currentColumnIndex","layoutRowSpanningCellsFromPreviousFragment","registerCellFragmentIndex","resetColumn","tdNodeStep","getElementOffset","Layout.registerFragmentIndex","afterNodeContext","hasBrokenCellAtSlot","startNodePosition","startTableRow","startTableCell","ignoreList","table-caption","table-column-group","table-column","tableLayoutOptionCache","TableLayoutProcessor","lastRow","dummyRow","dummyCells","tableElement","colGroups","firstElementChild","cols","colGroup","cloneNode","createDocumentFragment","getColumnWidths","getColGroupElements","normalizeAndGetColElements","addMissingColElements","initializeRepetitiveElements","tableLayoutOption","tableRootSourceNode","pair","getTableLayoutOption","clearTableLayoutOptionCache","layoutEntireTable","tableBBox","calculateBreakPositionsInside","EntireTableBreakPosition","normalizeColGroups","updateCellSizes","caption","addCaptions","addColGroups","iterator","RepetitiveElementImpl.appendHeaderToAncestors","LayoutRetryer","cellContentElement","getColumnElement","cellElement","cellElementRect","adjustCellHeight","finishFragment","tableFormattingContext","LayoutFragmentedTable","LayoutEntireTable","removeColGroups","RepetitiveElementImpl.LayoutEntireBlock","tableNodeContext","EntireTableLayoutConstraint","tableRootNode","RepetitiveElementImpl.LayoutFragmentedBlock","TableRowLayoutConstraint","equalsTo","RepetitiveElementImpl.RepetitiveElementsOwnerLayoutConstraint","collectCellFragmentLayoutConstraints","cellFragmentLayoutConstraints","removeDummyRowNodes","array","dummyNode","getCellFragemnts","findCellFromColumn","collectElementsOffsetOfUpperCells","collectElementsOffsetOfHighestColumn","tableLayoutProcessor","mean","ColumnBalancingTrialResult","layoutResult","getBlockSize","setBlockSize","ColumnBalancer","layoutContainer","columnGenerator","regionPageFloatLayoutContext","originalContainerBlockSize","preBalance","savePageFloatLayoutContexts","candidates","createTrialResult","updateCondition","restoreContents","postBalance","calculatePenalty","detachChildren","columnPageFloatLayoutContexts","newLayoutResult","columns","attachChildren","COLUMN_LENGTH_STEP","canReduceContainerSize","lastCandidate","secondLastCandidate","reduceContainerSize","newEdge","BalanceLastColumnBalancer","totalBlockSize","originalPosition","checkPosition","isLastColumnLongerThanAnyOtherColumn","foundUpperBound","lastColumnBlockSize","BalanceNonLastColumnBalancer","meanValue","MathUtil.variance","SlipRange","endStuckFixed","endFixed","endSlipped","SlipMap","slipped","Box","atBlockStart","atFlowStart","isParentBoxDisplayed","hasBox","beforeBox","styleValue","getBreakValue","afterBox","styleValues","cv","isBlockValue","displayValue","hasBoxValue","BoxStack","lastBox","newFlowChunk","atStartStack","isAtFlowStart","isCurrentBoxDisplayed","Vtree.canIgnore","Vtree.whitespaceFromPropertyValue","buildAfterPseudoElementBox","atStart","Styler","primaryFlows","cascadeHolder","createInstance","offsetMap","rootOffset","lastOffset","boxStack","addStuckRange","getAttrStyle","pushElement","postprocessTopStyle","bodyReached","primaryStack","replayFlowElementsFromOffset","srcStyle","pname","rootStyle","CssParser.SPECIFICITY_AUTHOR","elemStyle","isBody","rootBackgroundAssigned","backgroundColor","hasProp","backgroundProps","backgroundImage","transferPropsToRoot","rootLayoutAssigned","columnProps","layoutProps","unitSize","styleUntil","CSSStyleDeclaration","CssCascade.parseStyleAttribute","CssCascade.getProp","flowNameStr","encounteredFlowElement","getNodeByOffset","nodeOffset","getNodeOffset","flowListener","flowChunks","encounteredFlowChunk","flowToReach","idToReach","optionsCV","options","CssProp.toSet","lingerCV","CssProp.toInt","priorityCV","breakBeforeValues","flow","lastFlowName","Vtree.Flow","Vtree.FlowChunk","forcedBreakOffsets","previousValue","lookup","slippedOffset","targetSlippedOffset","slippedByFixed","getMaxSlipped","fixedBySlipped","popElement","afterPseudoBreakBefore","registerForcedBreakOffset","nearestBlockStartOffset","encounteredTextNode","addSlippedRange","blockStartOffset","beforePseudoBreakAfter","validator","Connection","where","ValidatingGroup","nodeIndex","connections","what","group","clonedNode","connection","groupConnection","nomatch","clause","ALWAYS_FAIL","markAsStartAlternate","markAsEndAlternate","markAsStartGroup","markAsEndGroup","connect","failure","arrs","addSpecialToArr","emptyHead","isSimple","PrimitiveValidator","how","ALTERNATE","isPrimitive","combine","connectionIndex","REPEATED","OPTIONAL","successTerminal","failTerminal","ALLOW_EMPTY","ALLOW_STR","ALLOW_IDENT","ALLOW_POS_NUMERIC","ALLOW_POS_NUM","ALLOW_POS_INT","ALLOW_COLOR","ALLOW_URL","ALLOW_NEGATIVE","ALLOW_ZERO","ALLOW_ZERO_PERCENT","ALLOW_SLASH","PropertyValidator","rval","idents","units","NO_IDENTS","ListValidator","failureTerminal","startIndex","alternativeStack","alternatives","inval","outval","isStartGroup","isEndGroup","isEndAlternate","getAlternate","SpaceListValidator","CommaListValidator","validateSingle","validateList","hasCommaListValidator","validateForShorthand","FuncValidator","ShorthandSyntaxNode","shorthandValidator","ShorthandSyntaxProperty","validators","rvals","len","ShorthandSyntaxPropertyN","ShorthandSyntaxCompound","index0","tryParse","ShorthandValidator","syntax","propList","receiver","defaultValues","SimpleShorthandValidator","InsetsShorthandValidator","shorthandValidators","SIMPLE","INSETS","INSETS_SLASH","slashIndex","index1","vals","acc","FONT","familyList","family","systemFonts","ValidatorSet","cssval","CssParser.colorFromHash","subgroup","startClause","addGroup","FOLLOW","endClause","startSpecialGroup","endSpecialGroup","addPrimitive","primitive","namedValidators","%","vi","vb","vmin","vmax","pvi","pvb","pvmin","pvmax","deg","grad","rad","turn","ms","Hz","kHz","stdfont","section","rulePrefixes","isBuiltIn","prefixes","readNameAndPrefixes","expectval","newGroup","setop","currop","builtIn","newFunc","addReplacement","addCounts","setOwner","syntaxNodeForProperty","shorthands","insetShorthand","createSyntaxNode","compound","parseValidators","parseDefaults","parseShorthands","makePropSet","shorthand","pval","origName","unknownProperty","rvalue","invalidPropertyValue","propagateInherit","baseValidatorSet","initBuiltInValidators","ValidationTxt","traitProps","bogusFontData","bogusFontCounter","prepareProperties","properties","fillDefaults","Face","fontTraitKey","makeFontTraitKey","fontBytes","blobURL","blob","createObjectURL","blobURLs","blobs","DocumentFaces","deobfuscator","srcFace","viewFace","srcFamily","viewFamilyFromSrc","familyMap","viewFamilyFromView","newValues","rf","Mapper","opt_familyPrefix","familyPrefix","documentFaces","viewFamily","familyCounter","getViewFontFamily","viewFontFace","killTime","bogusData","makeAtRule","Net.makeBlob","initWidth","initHeight","loaded","currWidth","currHeight","sleep","srcURLMap","piggyback","viewFaceParam","traitsEqual","registerFamily","Net.XMLHttpRequestResponseType","BLOB","initFont","srcFaces","loadFont","TaskUtil.waitForFetchers","keyCount","PageBox","_scope","parentInstance","param","specified","destSpecified","RootPageBox","Css.fullWidth","Css.fullHeight","PageMasterScope","Exprs.LexicalScope","pageMaster","isFunc","keyMap","boxInstance","lookupInstance","resolveFunc","resolveName","PageMaster","PageMasterInstance","copySpecified","cloneChildren","PartitionGroup","PartitionGroupInstance","Partition","PartitionInstance","toExprAuto","toExprZero","toExprZeroAuto","toExprZeroBorder","styleVal","toExprBool","PageBoxInstance","pageBox","calculatedWidth","calculatedHeight","Exprs.add","namedValues","addNamedValues","altName","CssCascade.couplingMapVert","CssCascade.couplingMapHor","namedFuncs","columnGap","Exprs.sub","Exprs.mul","minPageWidth","minPageHeight","boxSpecificEnabled","parentWidth","leftBP","rightBP","extra","autoWidth","isAutoWidth","remains","parentHeight","topBP","bottomBP","autoHeight","isAutoHeight","toExprNormal","Exprs.div","depend","registerInstance","getActiveRegions","CssCascade.flattenCascadedStyle","CssCascade.isVertical","CssCascade.isRtl","CssCascade.convertToPhysical","initHorizontal","initVertical","initColumns","initEnabled","Css.toNumber","CssCascade.getSpecial","docFaces","propagatePropertyToElement","Exprs.needUnitConversion","Css.convertNumericToPx","filterFontFamily","Vtree.DelayedItem","getPropAsNumber","xpos","snapOffsetX","ypos","snapOffsetY","assignRightPosition","assignTopPosition","assignLeftPosition","assignBottomPosition","isTopDependentOnAutoHeight","isRightDependentOnAutoWidth","sizeWithMaxWidth","sizeWithMaxHeight","assignBeforePosition","assignAfterPosition","assignStartEndPosition","passPreProperties","propagateProperty","passContentProperties","passSingleUriContentProperties","readHeight","readWidth","bbox","ruleWidth","ruleStyle","ruleColor","containerSize","border","rule","passPostProperties","delayedProperties","propagateDelayedProperty","docElementStyle","CssCascade.isPropName","CssCascade.setProp","userAgentPageMasterPseudo","pushRule","CssCascade.ContentPropVisitor","applyCascadeAndInit","popRule","depends","childInstance","resolveAutoSizing","RootPageBoxInstance","pageMasterInstance","listVal","conflicting","Css.Ident","qname","term","required","toExprIdent","processPartitionList","pmEnabledVal","pmEnabled","prepareContainer","PageBoxParserHandler","PartitionParserHandler","PartitionGroupParserHandler","Css.hundredPercent","partition","partitionGroup","PageMasterParserHandler","resolvePageProgression","Constants.PageProgression","pageSizes","a5","a4","a3","b5","b4","jis-b5","jis-b4","letter","legal","ledger","defaultPrinterMarkLineWidth","defaultPrinterMarkOffset","defaultPrinterMarkLineLength","defaultBleedOffset","resolvePageSizeAndBleed","pageSizeAndBleed","bleed","Css.numericZero","bleedOffset","val1","isSpaceList","marks","hasCrop","evaluatePageSizeAndBleed","evaluated","cropOffset","createPrinterMarkSvg","createPrinterMarkElement","lineWidth","elementType","CornerMarkPosition","CrossMarkPosition","addPrinterMarks","evaluatedPageSizeAndBleed","printerMarkOffset","bgcolor","cropMarkLineLength","bleedMarkLineLength","maxLineLength","svgWidth","points1","points2","TOP_RIGHT","BOTTOM_RIGHT","BOTTOM_LEFT","line1","line2","createCornerMark","longLineLength","BOTTOM","horizontalLine","verticalLine","opposite","LEFT","RIGHT","createCrossMark","propertiesAppliedToPartition","outline","outline-width","outline-style","outline-color","MarginBoxPositionAlongVariableDimension","pageMarginBoxes","top-left-corner","isInTopRow","isInBottomRow","isInLeftColumn","isInRightColumn","positionAlongVariableDimension","top-left","START","top-center","CENTER","top-right","top-right-corner","right-top","right-middle","right-bottom","bottom-right-corner","bottom-right","bottom-center","bottom-left","bottom-left-corner","left-bottom","left-middle","left-top","pageMarginBoxNames","pageRuleMasterPseudoName","marginBoxesKey","PageRuleMaster","PageMaster.PageMaster","pageSize","PageRulePartition","bodyPartitionKey","createPageMarginBoxes","applySpecified","marginBoxesMap","PageMarginBoxPartition","PageRuleMasterInstance","PageMaster.Partition","PageRulePartitionInstance","marginBoxName","ownStyle","ownVal","CssCascade.inheritedProps","PageMarginBoxPartitionInstance","PageMaster.PageMasterInstance","pageRuleMaster","pageAreaDimension","borderBoxWidth","borderBoxHeight","marginBoxContainers","marginBoxes","horizontalDimensions","verticalDimensions","sizeMarginBoxesAlongVariableDimension","isHorizontal","containers","boxInstances","boxParams","boxInfo","pageMarginBoxInstances","boxParam","SingleBoxMarginBoxSizingParam","evaluatedDim","getSizesOfMarginBoxesAlongVariableDimension","needRecalculate","maxOuterSizes","PageMaster.toExprAuto","evaluatedMaxSize","FixedSizeMarginBoxSizingParam","getOuterSize","minOuterSizes","minSize","evaluatedMinSize","startEndSum","outerSize","availableSize","startBoxParam","centerBoxParam","endBoxParam","startEndBoxParam","MultipleBoxesMarginBoxSizingParam","centerSizes","distributeAutoMarginBoxSizes","xSize","startEndAutoSize","hasAutoSize","startEndSizes","ySize","xOuterMaxContentSize","getOuterMaxContentSize","yOuterMaxContentSize","maxContentSizeSum","xOuterMinContentSize","getOuterMinContentSize","minContentSizeSum","hasAutoSize_","fixedSize","PageMaster.PartitionInstance","pageRulePartition","setPageAreaDimension","resolvePageBoxDimensions","borderBoxExtent","marginStart","marginEnd","endSide","extentName","pageExtent","paddingStart","PageMaster.toExprZero","paddingEnd","borderStartWidth","PageMaster.toExprZeroBorder","borderEndWidth","pageMarginBoxPartition","applyVerticalAlign","flexAlign","availableExtent","outerExtent","insideName","outsideName","outside","pageMargin","marginInside","PageMaster.toExprZeroAuto","marginOutside","paddingInside","paddingOutside","borderInsideWidth","borderOutsideWidth","getComputedValues","pageMarginValue","borderAndPadding","positionAndSizeAlongFixedDimension","finishContainer","PageManager","rootPageBoxInstance","definePageProgression","isEvenPage","pageProgression","resetScope","makeCacheKey","pageMasterCache","PageMaster.userAgentPageMasterPseudo","generatePageRuleMaster","generateCascadedPageMaster","propsStr","makeCascadeValueObjectKey","newPageMaster","pageMasterStyle","CssCascade.cascadeValues","CheckPageTypeAction","CssCascade.ChainedAction","IsFirstPageAction","IsLeftPageAction","IsRightPageAction","IsRectoPageAction","IsVersoPageAction","ApplyPageRuleAction","CssCascade.ApplyRuleAction","CssCascade.mergeIn","targetMap","CssCascade.getMutableStyleMap","boxName","targetBox","mergeInPageRule","PageParserHandler","CssCascade.CascadeParserHandler","pageProps","currentNamedPageSelector","currentPseudoPageClassSelectors","selectors","currentPageSelectors","finishSelector","selector","noPageSelectorProps","prevCascVal","marginBoxMap","boxStyle","PageMarginBoxParserHandler","transformURIs","attributeValue","m1","namespacePrefixMap","frontEdgeBlackListHor","margin-top","padding-top","border-top-width","border-top-style","border-top-color","border-top-left-radius","border-top-right-radius","frontEdgeBlackListVert","margin-right","padding-right","border-right-width","border-right-style","border-right-color","border-bottom-right-radius","frontEdgeUnforcedBreakBlackListHor","frontEdgeUnforcedBreakBlackListVert","ViewFactory","footnoteStyle","stylerProducer","customRenderer","fallbackMap","cascStyle","getPseudoMap","addedNames","att","PseudoElement.pseudoNames","content","shadowStyler","PseudoElement.PseudoelementStyler","Vtree.ShadowContext","Vtree.ShadowType","ROOTLESS","computedPseudoStyleMap","computedPseudoStyle","CssCascade.mergeStyle","CssCascade.mergeViewConditionalStyles","CssCascade.forEachStylesInRegion","CssCascade.forEachViewConditionalStyles","load","refDocParam","refDoc","refElement","getElement","refStyler","getStylerForDoc","templateURLVal","createRefShadow","shadow","cont2","createPseudoelementShadow","displayValues","Display.getComputedDislayValue","shadowRoot","nodeStyle","inheritanceVisitor","CssCascade.InheritanceVisitor","CssCascade.isInherited","Css.processingOrderFn","setPropName","sname","CssCascade.getPolyfilledInheritedProps","numericVal","needToProcessChildren","inheritedValues","inheritFromSourceParent","PageFloats.floatReferenceOf","computeStyle","processContent","transferPolyfilledInheritedProps","inheritLangAttribute","createShadows","shadowParam","parentWritingMode","isFlowRoot","Display.isFlowRoot","Display.establishesBFC","Display.establishesCBForAbsolute","isInsideBFC","floating","listItem","Display.isInlineLevel","Display.isRubyInternalDisplay","borderCollapse","borderSpacing","outerPseudo","Vtree.FirstPseudo","processAfterIfcontinues","whitespaceValue","wordBreak","overflowWrap","resolveFormattingContext","isFirstTime","processRepeatOnBreak","findAndProcessRepeatingElements","custom","elemResult","tag","PseudoElement.PSEUDO_ATTR","imageRef","imageBinary","innerSrc","TaskUtil.loadElement","fb2Remap","NCX","navParent","childElement","hp","dataset","iframe","contentWindow","navigator","version","layoutStyle","hasFeature","initIFrame","imageResolution","images","cssWidth","cssHeight","attrWidth","attrHeight","hasAutoWidth","hasAutoHeight","attributes","attributeCount","delayedSrc","attribute","attributeNS","nodeValue","registerElementWithId","image","Image","isSVGUrlAttribute","Urls.transformURIs","attributePrefix","imageFetcher","listStyleImage","listStyleURL","preprocessElementStyle","applyComputedStyles","blackList","modifyElemDimensionWithImageResolution","Layout.AfterIfContinues","SVG_URL_ATTRIBUTES","scaledWidth","scaledHeight","numericMaxWidth","numericMaxHeight","numericMinWidth","numericMinHeight","PREPROCESS_ELEMENT_STYLE","RepetitiveElement.RepetitiveElementsOwnerFormattingContext","parentFormattingContext","preprocessTextContent","Diff.restoreNewText","originl","PREPROCESS_TEXT_CONTENT","processedText","originalText","Diff.diffChars","createElementView","createTextNodeView","processChildren","createNodeView","contentNode","contentShadowType","contentShadow","resetView","Vtree.NodeContext","processShadowContent","shadowNode","sr","transclusionType","proc","nextPositionInTree","bg","addImageFetchers","isRelativePositioned","propertiesNotPassedToDOM","CssProp.UrlTransformVisitor","Vtree.delayedProps","Vtree.delayedPropsIfRelativePositioned","pn","childComputedStyle","boxDecorationBreak","Exprs.isFontRelativeLengthUnit","CssCascade.convertFontRelativeLengthToPx","step1","step2","elem1","parentElement","elem2","PseudoElement.getPseudoName","nodePosition1","nodePosition2","sup","tr","td","th","date","emphasis","strong","strikethrough","box-decoration-break","float-min-wrap-block","float-reference","flow-into","flow-options","footnote-policy","DefaultClientLayout","layoutBox","originRect","viewportLeft","viewportTop","rects","layoutBoxRect","subtractOffsets","getComputedStyle","Viewport","opt_root","opt_width","opt_height","outerZoomBox","contentContainer","innerWidth","innerHeight","ELEMENT_OFFSET_ATTR","XMLDocHolder","langs","SSE","NodeList","offsetStr","srcNode","totalOffset","idMap","xmlid","buildIdMap","getElementsByName","DOMParserSupportedType","parseAndReturnNullIfError","opt_parser","docElement","errorTagName","parseXMLResource","supportedKeys","APPLICATION_XML","TEXT_HTML","APPLICATION_XHTML_XML","IMAGE_SVG_XML","resolveContentType","Predicate","check","opt_childPredicate","predicate","pr","forEachNode","forEachNonNull","uaStylesheetBaseFetcher","CssValidator.baseValidatorSet","CssParser.StylesheetFlavor","CssCascade.setUABaseCascade","CssParser.parseStylesheetFromText","Style","rootBox","fontFaces","footnoteProps","flowProps","viewportProps","fontDeobfuscator","defineBuiltIn","currentLayoutPosition","firstFlowChunkOfFlow","matchPageSide","startSideOfFlow","lookupOffset","flowChunkIsAfterParentFlowForcedBreak","pageNumberOffset","Exprs.Context","CssCascade.mergeAll","textZoom","scaleFactor","defaultFontSize","widthVal","heightVal","StyleInstance","defaultLang","fontMapper","faces","Font.DocumentFaces","rootPageFloatLayoutContext","createCounterListener","createCounterResolver","CssStyler.Styler","setStyler","resetFlowChunkStream","stylerMap","getTopContainerStyle","CssPage.resolvePageProgression","PageMaster.RootPageBoxInstance","pageManager","CssPage.PageManager","fontFace","Font.prepareProperties","Font.Face","findOrLoadFonts","CssPage.evaluatePageSizeAndBleed","CssPage.resolvePageSizeAndBleed","pageSheetSize","getStyleForDoc","pageBoxInstances","Vtree.FlowPosition","Vtree.ChunkPosition","Vtree.FlowChunkPosition","chunkOffset","layoutPosition","noLookAhead","currentPosition","styleUntilFlowIsReached","consumedOffset","getConsumedOffset","flowChunkBreakBefore","flowBreakAfter","Break.startSideValueToBreakValue","Break.breakValueToStartSideValue","getPosition","pageMasters","CssPage.pageRuleMasterPseudoName","coeff","pageArea","updateStartSide","layoutPositionAtPageStart","initLingering","getPageRulePageMaster","breakOffsetBeforeStartIndex","breakOffsetBeforeStart","parentFlowPosition","parentStartOffset","LayoutProcessor.BlockFormattingContext","parentInvalidated","validate","setFormattingContextToColumn","layoutDeferredPageFloats","repeatedIndices","removedIndices","hasContinuingFloatFragmentsInFlow","alt","isBetter","getLastAfterPositionIfDeferredFloatsExists","saveDistanceToBlockEndFloats","getMaxReachedAfterEdge","counterConstraint","createLayoutConstraint","Layout.AllLayoutConstraint","forceNonFitting","dontApplyExclusions","boxContainer","columnPageFloatLayoutContext","positionAtColumnStart","columnContainer","Layout.Column","columnY","columnX","copyFrom","layoutColumn","pagePageFloatLayoutContext","CssPage.PageRulePartitionInstance","CssPage.PageRuleMasterInstance","positionAtContainerStart","getRegionPageFloatLayoutContext","layoutColumns","layoutFlowColumns","generatorResult","columnFill","columnBalancer","noMoreContent","lastColumn","isLastColumnForceBroken","Columns.createColumnBalancer","lock","balanceColumns","unlock","Vgen.ViewFactory","createAndLayoutColumn","isLocked","pageBreaks","dontExclude","Vtree.Container","setPagePageFloatLayoutContextContainer","removed","isIdent","layoutFlowColumnsWithBalancing","innerContainerTag","innerContainer","transferSinglUriContentProps","transferContentProps","suppressEmptyBoxGeneration","outerShape","startPage","Vtree.LayoutPosition","getCascadedPageStyle","selectPageMaster","bleedBoxPaddingEdge","setAutoPageWidth","setAutoPageHeight","setCurrentPage","updatePageCounters","setPageSizeAndBleed","CssPage.addPrinterMarks","adjustPageLayout","isLeftPage","Constants.PageSide","processLinger","getReachedOffset","getTriggersForDoc","noMorePrimaryFlows","pageSheetWidth","pageSheetHeight","BaseParserHandler","masterHandler","PageMaster.PageMasterParserHandler","CssCascade.DefineParserHandler","CssCascade.PropSetParserHandler","insideRegion","pageHandler","CssPage.PageParserHandler","regionCount","special","regionHandler","processViewportMeta","meta","StyleParserHandler","CssParser.DispatchParserHandler","PageMaster.RootPageBox","cascadeParserHandler","parseOPSResource","OPSDocStore","Net.ResourceStore","authorStyleSheets","userStyleSheets","setStyleSheets","userAgentXML","triggerSingleDocumentPreprocessing","styleByDocURL","triggersByDocURL","clearStyleSheets","addAuthorStyleSheet","addUserStyleSheet","styleSheets","stylesheet","Base.convertSpecialURL","Base.baseURL","XmlDoc.parseXMLResource","PREPROCESS_SINGLE_DOCUMENT","triggerList","getElementsByTagNameNS","triggerElem","EV","sources","userAgentURL","UserAgentPageCss","title","rel","getElementsByTagName","styleByKey","styleFetcherByKey","sph","source","CssParser.parseStylesheetFromURL","encode32","decode32","bytes","bytesToSHA1Int32","appendCount","w","bi","bytesToSHA1Hex","sha1","bytesToSHA1Bytes","bulletClosed","bulletOpen","bulletEmpty","TOCView","rendererFactory","Exprs.clonePreferences","setAutoHeight","renderer","makeCustomRenderer","srcElem","viewParent","behavior","querySelector","replaceChild","createComment","adaptParentClass","button","toggleNodeExpansion","tabIndex","anchorElem","Vtree.Page","tocBoxUrl","nonTocBoxDoc","viewportSize","sizeViewport","Vgen.Viewport","OPS.StyleInstance","layoutNextPage","bodyChildElem","tocNodeElem","ce","adaptClass","stopPropagation","EPUBDocStore","OPS.OPSDocStore","makeDeobfuscatorFactory","plainXMLStore","jsonStore","deobfuscators","haveZipMetadata","loadEPUBDoc","opf","pubURL","loadOPF","loadAsJSON","manifestObj","OPFDoc","initWithWebPubManifest","loadWebPub","startLoadingAsJSON","startLoadingAsPlainXML","containerURL","loadAsPlainXML","containerXML","roots","opfByURL","opfXML","encXML","zipMetadata","initWithXMLDoc","primaryOPFByEPubURL","manifestLink","xhtmlToc","docURL","documents","OPFItem","itemProperties","Base.emptyObj","itemElem","opfURL","mediaType","propStr","Base.arrayToSet","skipPagesBefore","getOPFItemId","makeDeobfuscator","uid","sha1Sum","SHA1.bytesToSHA1Int8","fileReader","FileReader","readAsArrayBuffer","Net.readBlob","dataView","DataView","byteLength","getUint8","setUint8","predefinedPrefixes","dcterms","marc","rendition","onix","xsd","defaultIRI","metaTerms","language","creator","titleType","displaySeq","alternateScript","getMetadataComparator","item1","item2","m2","i1","i2","getMathJaxHub","math","supportedMediaTypes","application/xhtml+xml","image/jpeg","image/png","image/svg+xml","image/gif","audio/mp3","transformedIdPrefix","createDocumentURLTransformer","CssCascade.supportedNamespaces","MATHML","Base.escapeNameStrToHex","path","items","encoded","Base.unescapeStrFromHex","metadata","epubBaseURL","decodeURI","manifestURL","pkg","uidref","uidElem","srcToFallbackId","asArray","initWithElement","fallback","cover","itemMap","Base.indexArray","itemMapByPath","getPathFromURL","fallbackSrc","spine","itemRefElement","tocAttr","ncxToc","pageProgressionAttr","Constants.pageProgressionOf","idpfObfURLs","XmlDoc.predicate","withChild","withAttribute","mediaTypeElems","handlerId","bindings","mroot","prefixMap","resolveProperty","iri","rawItems","refines","scheme","DC","rawItemsByTarget","Base.multiIndexArray","rawItem","makeMetadata","Base.mapObj","rawItemArr","itemName","schema","langItem","entryMap","sortMetadata","readMetadata","prePaginated","assignAutoPages","manifestText","obfuscations","obfuscationKey","SHA1.bytesToSHA1Hex","encodedPath","compressed","compressedSize","obfuscation","DEFAULT","epage","epageCount","epageCountCallback","epageIsRenderedPage","offsetPerEPage","getTotalOffset","XmlDoc.XMLDocHolder","initWithParam","itemref","addDocument","primaryEntryPath","encodeURI","hrefNoFragment","itemCount","tocFound","readingOrderOrResources","itemObj","isInReadingOrder","encodingFormat","initWithChapters","offsetInItem","cfi","CFI.Fragment","prependPathFromNode","fromString","opfNav","navigate","idref","nodeNav","makePageAndPosition","OPFView","pageSheetSizeReporter","Vgen.DefaultClientLayout","Counters.CounterStore","viewItem","spineItems","oldPage","isFirstPage","prevItem","newPage","insertPos","makePage","posParam","layoutPositions","finishPageContainer","finishPage","prevPos","renderSinglePage","getUnresolvedRefsToPage","getPageViewItem","pushPageCounters","pushReferencesToSolve","popPageCounters","popReferencesToSolve","resultPosition","pageAndPosition","isLastPage","finishLastPage","nextLayoutPosition","seekOffset","seekOffsetPageIndex","complete","sync","resultPage","normalizedPosition","normalizeSeekPosition","renderPage","renderPagesUpto","notAllPages","lastResult","findPage","nextViewItem","nextPage","spineItemLoadingContinuations","isLeft","isLTR","getCurrentPageProgression","getPage","isRectoPage","previousPage","otherPageAndPosition","thisPage","otherPage","isRecto","next2","result2","oldPrevPageCont","resolveEPage","resolveFragment","restored","restoreURL","navigateToFragment","pageCont","Constants.isDebug","matrix","Exprs.letterbox","cssMatrix","handlerSrc","srcParam","Base.lightURLEncode","typeParam","pvalue","hub","clonedMath","importNode","resolveURLsInMathML","tagName","attrs","newUrl","srcTagName","makeObjectView","makeMathJaxView","makeSSEView","loadingContinuations","previousViewItem","forceSetPageCounter","pubTitles","autohide","toc","tocAutohide","tocView","Toc.TOCView","tocWidth","tocHeight","showTOC","hideTOC","isTOCVisible","VIEWPORT_STATUS_ATTRIBUTE","VIEWPORT_SPREAD_VIEW_ATTRIBUTE","PageViewMode","ZoomType","AdaptiveViewer","viewportElement","instanceId","callbackFn","Font.Mapper","kick","sendCommand","resizeListener","needResize","pageReplacedListener","hyperlinkListener","pageRuleStyleElement","loadPublication","loadXML","configure","moveTo","addLogListeners","Constants.ReadyState","LOADING","packageURL","touchActive","touchX","touchY","needRefresh","currentSpread","pagePosition","zoom","fitToScreen","pageViewMode","SINGLE_PAGE","waitForLoading","renderAllPages","logLevel","Logging.LogLevel","addListener","command","Profile.profiler","setReadyState","authorStyleSheet","userStyleSheet","Epub.EPUBDocStore","loadPubDoc","render","resolvedParams","Epub.OPFDoc","cancelRenderingTask","resize","matched","vp","resolveLength","Base.setBaseURL","Base.setResourceBaseURL","configurePlugins","CONFIGURATION","showCurrent","forCurrentPages","removePageListeners","hidePages","showSinglePage","leftWidth","rightWidth","getCFI","sendLocationNotification","vs","SPREAD","AUTO_SPREAD","createViewport","resolveSpreadView","spreadViewChanged","updateSpreadView","userAgent","opfView","hasPages","hasAutoSizedPages","setPageSizePageRules","pageSheetSizeAlreadySet","styleText","tocVisible","removeRenderedPages","removePageSizePageRules","resetZoom","Epub.OPFView","setPageSize","getSpread","showSpread","setSpreadZoom","showPage","setPageZoom","getAdjustedZoomFactor","getSpreadDimensions","pageDimension","calculateZoomFactorToFitInsideViewPort","FIT_INSIDE_VIEWPORT","pageDim","widthZoom","heightZoom","renderTask","interrupt","RenderingCanceledError","sizeIsGood","resizeTask","setEPageCountMode","INTERACTIVE","countEPages","notification","reportPosition","COMPLETE","getEPageFromPosition","method","nextSpread","previousSpread","lastPage","firstPage","navigateToEPage","navigateTo","currentVisibility","changeAutohide","actionName","cmd","maybeParse","viewer","Task.start","hrefEvent","internal","runCommand","frameInternal","setPrototypeOf","convertViewerOptions","CoreViewer","settings","opt_options","Constants.setDebug","adaptViewer_","AdaptiveViewer.AdaptiveViewer","dispatcher","autoResize","pageBorderWidth","AdaptiveViewer.PageViewMode","setOptions","eventTarget","defineProperty","singleDocumentOptions","opt_documentOptions","opt_viewerOptions","loadDocumentOrPublication","pubUrl","documentOptions","convertStyleSheetArray","userAgentRootURL","convertSingleDocumentOptions","initialized","initEmbed","nav","Navigation","PREVIOUS","NEXT","opt_epage","EPAGE","resolveNavigation","opt_show","opt_autohide","queryZoomFactor","toNumberOrNull","opt","isArray","AdaptiveViewer.ZoomType","forceRegisterEndTiming","VivliostylePrint","htmlDoc","printCallback","iframeWin","hideIframe","removeIframe","borderWidth","printInstance","srcdoc","viewportCss","viewportScreenCss","preparePrint","browserPrint","cleanUp","docBlob","Viewer","CoreViewer.CoreViewer","Promise","loadDocument","printHTML","config"],"mappings":"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,OAAQsD,GAAK,EAChChE,EAAEivB,EAAKjrB,IAAMirB,EAAKjrB,EAAI,GAExB,OAAOhE,GAhGT,SAAY6uB,GACVA,qBACAA,iBACAA,qBACAA,mBACAA,mBACAA,uBACAA,yBACAA,iBACAA,sBACAA,sBACAA,oBACAA,oBACAA,sBACAA,sBACAA,kBACAA,sBACAA,sBACAA,0BACAA,gBACAA,gBACAA,gBACAA,sBACAA,gBACAA,sBACAA,sBACAA,sBACAA,sBACAA,wBACAA,kBACAA,kBACAA,sBACAA,oBACAA,oBACAA,kBACAA,wBACAA,wBACAA,wBACAA,oBACAA,oBACAA,wBACAA,wBACAA,0BACAA,0BACAA,0BAGAA,wBACAA,0BAGAA,0BACAA,0BACAA,0BACAA,0BACAA,oBACAA,wBACAA,0BACAA,wBACAA,0BACAA,wBACAA,sBACAA,sBACAA,0BACAA,wBACAA,sBACAA,sBACAA,kBACAA,oBACAA,oBACAA,wBACAA,0BACAA,wBACAA,sBACAA,0BACAA,0BACAA,0BACAA,0BACAA,wBACAA,wBACAA,0BACAA,0BACAA,sBACAA,kBAnFF,CAAYA,KAAAA,QAsGZ,MAAaO,GAA0B,CACrCP,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOQ,MACPR,GAAOQ,MACPR,GAAOM,QACPN,GAAOQ,MACPR,GAAOQ,MACPR,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOQ,MACPR,GAAOS,KACPT,GAAOU,KACPV,GAAOW,KACPX,GAAOY,OACPZ,GAAOa,QACPb,GAAOc,IACPd,GAAOe,KACPf,GAAOgB,MACPhB,GAAOiB,MACPjB,GAAOkB,KACP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xB,OAAOI,KAAK8lD,kBAAkBprC,EAAKxI,QAErC,MACF,IAAK,iBACH,GAAIwI,EAAKxI,OAAOtS,QAAU,EACxB,OAAOI,KAAK+lD,uBAAuBrrC,EAAKxI,QAE1C,MACF,IAAK,kBACH,GAAIwI,EAAKxI,OAAOtS,QAAU,EACxB,OAAOI,KAAKgmD,wBAAwBtrC,EAAKxI,QAK/C,OADArQ,EAAevB,KAAK,sBAAuBoa,EAAK7U,YACzC,IAAIgpC,GAAQ,KAIvB,MA+BaiV,GAAoB,CAC/BmC,MAAO,CACL,KACA,IACA,IACA,IACA,KACA,IACA,IACA,IACA,KACA,IACA,IACA,GACA,KACA,GACA,IACA,GACA,KACA,GACA,IACA,EACA,KACA,EACA,IACA,EACA,KACA,EACA,KAEFC,SAAU,CACR,KACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,KAEFC,SAAU,CACR,MACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,KAEFC,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"}
\No newline at end of file