123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- /**
- * @licstart The following is the entire license notice for the
- * Javascript code in this page
- *
- * Copyright 2021 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * Javascript code in this page
- */
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.XhtmlNamespace = void 0;
- var _xfa_object = require("./xfa_object.js");
- var _namespaces = require("./namespaces.js");
- var _html_utils = require("./html_utils.js");
- var _utils = require("./utils.js");
- const XHTML_NS_ID = _namespaces.NamespaceIds.xhtml.id;
- const VALID_STYLES = new Set(["color", "font", "font-family", "font-size", "font-stretch", "font-style", "font-weight", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "letter-spacing", "line-height", "orphans", "page-break-after", "page-break-before", "page-break-inside", "tab-interval", "tab-stop", "text-align", "text-decoration", "text-indent", "vertical-align", "widows", "kerning-mode", "xfa-font-horizontal-scale", "xfa-font-vertical-scale", "xfa-spacerun", "xfa-tab-stops"]);
- const StyleMapping = new Map([["page-break-after", "breakAfter"], ["page-break-before", "breakBefore"], ["page-break-inside", "breakInside"], ["kerning-mode", value => value === "none" ? "none" : "normal"], ["xfa-font-horizontal-scale", value => `scaleX(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], ["xfa-font-vertical-scale", value => `scaleY(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], ["xfa-spacerun", ""], ["xfa-tab-stops", ""], ["font-size", (value, original) => {
- value = original.fontSize = (0, _utils.getMeasurement)(value);
- return (0, _html_utils.measureToString)(0.99 * value);
- }], ["letter-spacing", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["line-height", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-bottom", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-left", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-right", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-top", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["text-indent", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["font-family", value => value]]);
- const spacesRegExp = /\s+/g;
- const crlfRegExp = /[\r\n]+/g;
- function mapStyle(styleStr, node) {
- const style = Object.create(null);
- if (!styleStr) {
- return style;
- }
- const original = Object.create(null);
- for (const [key, value] of styleStr.split(";").map(s => s.split(":", 2))) {
- const mapping = StyleMapping.get(key);
- if (mapping === "") {
- continue;
- }
- let newValue = value;
- if (mapping) {
- if (typeof mapping === "string") {
- newValue = mapping;
- } else {
- newValue = mapping(value, original);
- }
- }
- if (key.endsWith("scale")) {
- if (style.transform) {
- style.transform = `${style[key]} ${newValue}`;
- } else {
- style.transform = newValue;
- }
- } else {
- style[key.replaceAll(/-([a-zA-Z])/g, (_, x) => x.toUpperCase())] = newValue;
- }
- }
- if (style.fontFamily) {
- (0, _html_utils.setFontFamily)({
- typeface: style.fontFamily,
- weight: style.fontWeight || "normal",
- posture: style.fontStyle || "normal",
- size: original.fontSize || 0
- }, node, node[_xfa_object.$globalData].fontFinder, style);
- }
- (0, _html_utils.fixTextIndent)(style);
- return style;
- }
- function checkStyle(node) {
- if (!node.style) {
- return "";
- }
- return node.style.trim().split(/\s*;\s*/).filter(s => !!s).map(s => s.split(/\s*:\s*/, 2)).filter(([key, value]) => {
- if (key === "font-family") {
- node[_xfa_object.$globalData].usedTypefaces.add(value);
- }
- return VALID_STYLES.has(key);
- }).map(kv => kv.join(":")).join(";");
- }
- const NoWhites = new Set(["body", "html"]);
- class XhtmlObject extends _xfa_object.XmlObject {
- constructor(attributes, name) {
- super(XHTML_NS_ID, name);
- this.style = attributes.style || "";
- }
- [_xfa_object.$clean](builder) {
- super[_xfa_object.$clean](builder);
- this.style = checkStyle(this);
- }
- [_xfa_object.$acceptWhitespace]() {
- return !NoWhites.has(this[_xfa_object.$nodeName]);
- }
- [_xfa_object.$onText](str) {
- str = str.replace(crlfRegExp, "");
- if (!this.style.includes("xfa-spacerun:yes")) {
- str = str.replace(spacesRegExp, " ");
- }
- if (str) {
- this[_xfa_object.$content] += str;
- }
- }
- [_xfa_object.$pushGlyphs](measure, mustPop = true) {
- const xfaFont = Object.create(null);
- const margin = {
- top: NaN,
- bottom: NaN,
- left: NaN,
- right: NaN
- };
- let lineHeight = null;
- for (const [key, value] of this.style.split(";").map(s => s.split(":", 2))) {
- switch (key) {
- case "font-family":
- xfaFont.typeface = (0, _utils.stripQuotes)(value);
- break;
- case "font-size":
- xfaFont.size = (0, _utils.getMeasurement)(value);
- break;
- case "font-weight":
- xfaFont.weight = value;
- break;
- case "font-style":
- xfaFont.posture = value;
- break;
- case "letter-spacing":
- xfaFont.letterSpacing = (0, _utils.getMeasurement)(value);
- break;
- case "margin":
- const values = value.split(/ \t/).map(x => (0, _utils.getMeasurement)(x));
- switch (values.length) {
- case 1:
- margin.top = margin.bottom = margin.left = margin.right = values[0];
- break;
- case 2:
- margin.top = margin.bottom = values[0];
- margin.left = margin.right = values[1];
- break;
- case 3:
- margin.top = values[0];
- margin.bottom = values[2];
- margin.left = margin.right = values[1];
- break;
- case 4:
- margin.top = values[0];
- margin.left = values[1];
- margin.bottom = values[2];
- margin.right = values[3];
- break;
- }
- break;
- case "margin-top":
- margin.top = (0, _utils.getMeasurement)(value);
- break;
- case "margin-bottom":
- margin.bottom = (0, _utils.getMeasurement)(value);
- break;
- case "margin-left":
- margin.left = (0, _utils.getMeasurement)(value);
- break;
- case "margin-right":
- margin.right = (0, _utils.getMeasurement)(value);
- break;
- case "line-height":
- lineHeight = (0, _utils.getMeasurement)(value);
- break;
- }
- }
- measure.pushData(xfaFont, margin, lineHeight);
- if (this[_xfa_object.$content]) {
- measure.addString(this[_xfa_object.$content]);
- } else {
- for (const child of this[_xfa_object.$getChildren]()) {
- if (child[_xfa_object.$nodeName] === "#text") {
- measure.addString(child[_xfa_object.$content]);
- continue;
- }
- child[_xfa_object.$pushGlyphs](measure);
- }
- }
- if (mustPop) {
- measure.popFont();
- }
- }
- [_xfa_object.$toHTML](availableSpace) {
- const children = [];
- this[_xfa_object.$extra] = {
- children
- };
- this[_xfa_object.$childrenToHTML]({});
- if (children.length === 0 && !this[_xfa_object.$content]) {
- return _utils.HTMLResult.EMPTY;
- }
- return _utils.HTMLResult.success({
- name: this[_xfa_object.$nodeName],
- attributes: {
- href: this.href,
- style: mapStyle(this.style, this)
- },
- children,
- value: this[_xfa_object.$content] || ""
- });
- }
- }
- class A extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "a");
- this.href = (0, _html_utils.fixURL)(attributes.href) || "";
- }
- }
- class B extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "b");
- }
- [_xfa_object.$pushGlyphs](measure) {
- measure.pushFont({
- weight: "bold"
- });
- super[_xfa_object.$pushGlyphs](measure);
- measure.popFont();
- }
- }
- class Body extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "body");
- }
- [_xfa_object.$toHTML](availableSpace) {
- const res = super[_xfa_object.$toHTML](availableSpace);
- const {
- html
- } = res;
- if (!html) {
- return _utils.HTMLResult.EMPTY;
- }
- html.name = "div";
- html.attributes.class = ["xfaRich"];
- return res;
- }
- }
- class Br extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "br");
- }
- [_xfa_object.$text]() {
- return "\n";
- }
- [_xfa_object.$pushGlyphs](measure) {
- measure.addString("\n");
- }
- [_xfa_object.$toHTML](availableSpace) {
- return _utils.HTMLResult.success({
- name: "br"
- });
- }
- }
- class Html extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "html");
- }
- [_xfa_object.$toHTML](availableSpace) {
- const children = [];
- this[_xfa_object.$extra] = {
- children
- };
- this[_xfa_object.$childrenToHTML]({});
- if (children.length === 0) {
- return _utils.HTMLResult.success({
- name: "div",
- attributes: {
- class: ["xfaRich"],
- style: {}
- },
- value: this[_xfa_object.$content] || ""
- });
- }
- if (children.length === 1) {
- const child = children[0];
- if (child.attributes && child.attributes.class.includes("xfaRich")) {
- return _utils.HTMLResult.success(child);
- }
- }
- return _utils.HTMLResult.success({
- name: "div",
- attributes: {
- class: ["xfaRich"],
- style: {}
- },
- children
- });
- }
- }
- class I extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "i");
- }
- [_xfa_object.$pushGlyphs](measure) {
- measure.pushFont({
- posture: "italic"
- });
- super[_xfa_object.$pushGlyphs](measure);
- measure.popFont();
- }
- }
- class Li extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "li");
- }
- }
- class Ol extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "ol");
- }
- }
- class P extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "p");
- }
- [_xfa_object.$pushGlyphs](measure) {
- super[_xfa_object.$pushGlyphs](measure, false);
- measure.addString("\n");
- measure.addPara();
- measure.popFont();
- }
- [_xfa_object.$text]() {
- return super[_xfa_object.$text]() + "\n";
- }
- }
- class Span extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "span");
- }
- }
- class Sub extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "sub");
- }
- }
- class Sup extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "sup");
- }
- }
- class Ul extends XhtmlObject {
- constructor(attributes) {
- super(attributes, "ul");
- }
- }
- class XhtmlNamespace {
- static [_namespaces.$buildXFAObject](name, attributes) {
- if (XhtmlNamespace.hasOwnProperty(name)) {
- return XhtmlNamespace[name](attributes);
- }
- return undefined;
- }
- static a(attributes) {
- return new A(attributes);
- }
- static b(attributes) {
- return new B(attributes);
- }
- static body(attributes) {
- return new Body(attributes);
- }
- static br(attributes) {
- return new Br(attributes);
- }
- static html(attributes) {
- return new Html(attributes);
- }
- static i(attributes) {
- return new I(attributes);
- }
- static li(attributes) {
- return new Li(attributes);
- }
- static ol(attributes) {
- return new Ol(attributes);
- }
- static p(attributes) {
- return new P(attributes);
- }
- static span(attributes) {
- return new Span(attributes);
- }
- static sub(attributes) {
- return new Sub(attributes);
- }
- static sup(attributes) {
- return new Sup(attributes);
- }
- static ul(attributes) {
- return new Ul(attributes);
- }
- }
- exports.XhtmlNamespace = XhtmlNamespace;
|