diff --git a/src/core/xfa/html_utils.js b/src/core/xfa/html_utils.js index 83aaa9a35..0753c6244 100644 --- a/src/core/xfa/html_utils.js +++ b/src/core/xfa/html_utils.js @@ -13,57 +13,108 @@ * limitations under the License. */ -const converters = { - pt: x => x, - cm: x => Math.round((x / 2.54) * 72), - mm: x => Math.round((x / (10 * 2.54)) * 72), - in: x => Math.round(x * 72), -}; +import { $toStyle, XFAObject } from "./xfa_object.js"; +import { warn } from "../../shared/util.js"; function measureToString(m) { - const conv = converters[m.unit]; - if (conv) { - return `${conv(m.value)}px`; - } - return `${m.value}${m.unit}`; + return Number.isInteger(m) ? `${m}px` : `${m.toFixed(2)}px`; } -function setWidthHeight(node, style) { - if (node.w) { - style.width = measureToString(node.w); - } else { - if (node.maxW && node.maxW.value > 0) { - style.maxWidth = measureToString(node.maxW); +const converters = { + anchorType(node, style) { + if (!("transform" in style)) { + style.transform = ""; } - if (node.minW && node.minW.value > 0) { - style.minWidth = measureToString(node.minW); + switch (node.anchorType) { + case "bottomCenter": + style.transform += "translate(-50%, -100%)"; + break; + case "bottomLeft": + style.transform += "translate(0,-100%)"; + break; + case "bottomRight": + style.transform += "translate(-100%,-100%)"; + break; + case "middleCenter": + style.transform += "translate(-50%,-50%)"; + break; + case "middleLeft": + style.transform += "translate(0,-50%)"; + break; + case "middleRight": + style.transform += "translate(-100%,-50%)"; + break; + case "topCenter": + style.transform += "translate(-50%,0)"; + break; + case "topRight": + style.transform += "translate(-100%,0)"; + break; + } + }, + dimensions(node, style) { + if (node.w) { + style.width = measureToString(node.w); + } else { + if (node.maxW && node.maxW.value > 0) { + style.maxWidth = measureToString(node.maxW); + } + if (node.minW && node.minW.value > 0) { + style.minWidth = measureToString(node.minW); + } } - } - if (node.h) { - style.height = measureToString(node.h); - } else { - if (node.maxH && node.maxH.value > 0) { - style.maxHeight = measureToString(node.maxH); + if (node.h) { + style.height = measureToString(node.h); + } else { + if (node.maxH && node.maxH.value > 0) { + style.maxHeight = measureToString(node.maxH); + } + if (node.minH && node.minH.value > 0) { + style.minHeight = measureToString(node.minH); + } } - if (node.minH && node.minH.value > 0) { - style.minHeight = measureToString(node.minH); + }, + position(node, style) { + if (node.x !== "" || node.y !== "") { + style.position = "absolute"; + style.left = measureToString(node.x); + style.top = measureToString(node.y); + } + }, + rotate(node, style) { + if (node.rotate) { + if (!("transform" in style)) { + style.transform = ""; + } + style.transform += `rotate(-${node.rotate}deg)`; + style.transformOrigin = "top left"; + } + }, +}; + +function toStyle(node, ...names) { + const style = Object.create(null); + for (const name of names) { + const value = node[name]; + if (value === null) { + continue; + } + if (value instanceof XFAObject) { + const newStyle = value[$toStyle](); + if (newStyle) { + Object.assign(style, newStyle); + } else { + warn(`(DEBUG) - XFA - style for ${name} not implemented yet`); + } + continue; + } + + if (converters.hasOwnProperty(name)) { + converters[name](node, style); } } + return style; } -function setPosition(node, style) { - style.transform = ""; - if (node.rotate) { - style.transform = `rotate(-${node.rotate}deg) `; - style.transformOrigin = "top left"; - } - - if (node.x !== "" || node.y !== "") { - style.position = "absolute"; - style.left = node.x ? measureToString(node.x) : "0pt"; - style.top = node.y ? measureToString(node.y) : "0pt"; - } -} - -export { measureToString, setPosition, setWidthHeight }; +export { measureToString, toStyle }; diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js index 78f66c0e4..98cbb6c63 100644 --- a/src/core/xfa/template.js +++ b/src/core/xfa/template.js @@ -30,6 +30,7 @@ import { $setSetAttributes, $setValue, $toHTML, + $toStyle, $uid, ContentObject, Option01, @@ -50,8 +51,8 @@ import { getRelevant, getStringOption, } from "./utils.js"; -import { measureToString, setPosition, setWidthHeight } from "./html_utils.js"; -import { warn } from "../../shared/util.js"; +import { measureToString, toStyle } from "./html_utils.js"; +import { Util, warn } from "../../shared/util.js"; const TEMPLATE_NS_ID = NamespaceIds.template.id; @@ -614,6 +615,10 @@ class Color extends XFAObject { [$hasSettableValue]() { return false; } + + [$toStyle]() { + return Util.makeHexColor(this.value.r, this.value.g, this.value.b); + } } class Comb extends XFAObject { @@ -680,7 +685,7 @@ class ContentArea extends XFAObject { children: [], attributes: { style, - className: "xfa-contentarea", + class: "xfaContentarea", id: this[$uid], }, }; @@ -896,10 +901,10 @@ class Draw extends XFAObject { "invisible", ]); this.relevant = getRelevant(attributes.relevant); - this.rotate = getFloat({ + this.rotate = getInteger({ data: attributes.rotate, defaultValue: 0, - validate: x => true, + validate: x => x % 90 === 0, }); this.use = attributes.use || ""; this.usehref = attributes.usehref || ""; @@ -924,6 +929,38 @@ class Draw extends XFAObject { [$setValue](value) { _setValue(this, value); } + + [$toHTML]() { + if (!this.value) { + return null; + } + + const style = toStyle( + this, + "font", + "dimensions", + "position", + "rotate", + "anchorType" + ); + + const clazz = ["xfaDraw"]; + if (this.font) { + clazz.push("xfaFont"); + } + + const attributes = { + style, + id: this[$uid], + class: clazz.join(" "), + }; + + return { + name: "div", + attributes, + children: [], + }; + } } class Edge extends XFAObject { @@ -1269,6 +1306,31 @@ class ExclGroup extends XFAObject { field.value[$setValue](nodeBoolean); } } + + [$toHTML]() { + if (!this.value) { + return null; + } + + const style = toStyle(this, "dimensions", "position", "anchorType"); + const attributes = { + style, + id: this[$uid], + class: "xfaExclgroup", + }; + + const children = this[$childrenToHTML]({ + // TODO: exObject & exclGroup + filter: new Set(["field"]), + include: true, + }); + + return { + name: "div", + attributes, + children, + }; + } } class Execute extends XFAObject { @@ -1360,7 +1422,11 @@ class Field extends XFAObject { "invisible", ]); this.relevant = getRelevant(attributes.relevant); - this.rotate = getStringOption(attributes.rotate, ["0", "angle"]); + this.rotate = getInteger({ + data: attributes.rotate, + defaultValue: 0, + validate: x => x % 90 === 0, + }); this.use = attributes.use || ""; this.usehref = attributes.usehref || ""; this.w = getMeasurement(attributes.w); @@ -1394,6 +1460,38 @@ class Field extends XFAObject { [$setValue](value) { _setValue(this, value); } + + [$toHTML]() { + if (!this.value) { + return null; + } + + const style = toStyle( + this, + "font", + "dimensions", + "position", + "rotate", + "anchorType" + ); + + const clazz = ["xfaField"]; + if (this.font) { + clazz.push("xfaFont"); + } + + const attributes = { + style, + id: this[$uid], + class: clazz.join(" "), + }; + + return { + name: "div", + attributes, + children: [], + }; + } } class Fill extends XFAObject { @@ -1418,6 +1516,26 @@ class Fill extends XFAObject { this.solid = null; this.stipple = null; } + + [$toStyle]() { + let fill = "#000000"; + for (const name of Object.getOwnPropertyNames(this)) { + if (name === "extras" || name === "color") { + continue; + } + const obj = this[name]; + if (!(obj instanceof XFAObject)) { + continue; + } + + fill = obj[$toStyle](this.color); + break; + } + + return { + color: fill, + }; + } } class Filter extends XFAObject { @@ -1522,6 +1640,80 @@ class Font extends XFAObject { this.extras = null; this.fill = null; } + + [$toStyle]() { + const style = toStyle(this, "fill"); + if (style.color) { + if (!style.color.startsWith("#")) { + // We've a gradient which is not possible for a font color + // so use a workaround. + style.backgroundClip = "text"; + style.background = style.color; + style.color = "transparent"; + } else if (style.color === "#000000") { + delete style.color; + } + } + + if (this.baselineShift) { + style.verticalAlign = measureToString(this.baselineShift); + } + + // TODO: fontHorizontalScale + // TODO: fontVerticalScale + + if (this.kerningMode !== "none") { + style.fontKerning = "normal"; + } + + if (this.letterSpacing) { + style.letterSpacing = measureToString(this.letterSpacing); + } + + if (this.lineThrough !== 0) { + style.textDecoration = "line-through"; + if (this.lineThrough === 2) { + style.textDecorationStyle = "double"; + } + } + + // TODO: lineThroughPeriod + + if (this.overline !== 0) { + style.textDecoration = "overline"; + if (this.overline === 2) { + style.textDecorationStyle = "double"; + } + } + + // TODO: overlinePeriod + + if (this.posture !== "normal") { + style.fontStyle = this.posture; + } + + const fontSize = measureToString(this.size); + if (fontSize !== "10px") { + style.fontSize = fontSize; + } + + style.fontFamily = this.typeface; + + if (this.underline !== 0) { + style.textDecoration = "underline"; + if (this.underline === 2) { + style.textDecorationStyle = "double"; + } + } + + // TODO: underlinePeriod + + if (this.weight !== "normal") { + style.fontWeight = this.weight; + } + + return style; + } } class Format extends XFAObject { @@ -1755,6 +1947,13 @@ class Linear extends XFAObject { this.color = null; this.extras = null; } + + [$toStyle](startColor) { + startColor = startColor ? startColor[$toStyle]() : "#FFFFFF"; + const transf = this.type.replace(/([RBLT])/, " $1").toLowerCase(); + const endColor = this.color ? this.color[$toStyle]() : "#000000"; + return `linear-gradient(${transf}, ${startColor}, ${endColor})`; + } } class LockDocument extends ContentObject { @@ -1989,11 +2188,11 @@ class PageArea extends XFAObject { // TODO: handle the case where there are several content areas. const contentArea = children.find( - node => node.attributes.className === "xfa-contentarea" + node => node.attributes.class === "xfaContentarea" ); const style = Object.create(null); - if (this.medium && this.medium.short.value && this.medium.long.value) { + if (this.medium && this.medium.short && this.medium.long) { style.width = measureToString(this.medium.short); style.height = measureToString(this.medium.long); } else { @@ -2133,6 +2332,32 @@ class Pattern extends XFAObject { this.color = null; this.extras = null; } + + [$toStyle](startColor) { + startColor = startColor ? startColor[$toStyle]() : "#FFFFFF"; + const endColor = this.color ? this.color[$toStyle]() : "#000000"; + const width = 5; + const cmd = "repeating-linear-gradient"; + const colors = `${startColor},${startColor} ${width}px,${endColor} ${width}px,${endColor} ${ + 2 * width + }px`; + switch (this.type) { + case "crossHatch": + return `${cmd}(to top,${colors}) ${cmd}(to right,${colors})`; + case "crossDiagonal": + return `${cmd}(45deg,${colors}) ${cmd}(-45deg,${colors})`; + case "diagonalLeft": + return `${cmd}(45deg,${colors})`; + case "diagonalRight": + return `${cmd}(-45deg,${colors})`; + case "horizontal": + return `${cmd}(to top,${colors})`; + case "vertical": + return `${cmd}(to right,${colors})`; + } + + return ""; + } } class Picture extends StringObject { @@ -2270,6 +2495,16 @@ class Radial extends XFAObject { this.color = null; this.extras = null; } + + [$toStyle](startColor) { + startColor = startColor ? startColor[$toStyle]() : "#FFFFFF"; + const endColor = this.color ? this.color[$toStyle]() : "#000000"; + const colors = + this.type === "toEdge" + ? `${startColor},${endColor}` + : `${endColor},${startColor}`; + return `radial-gradient(circle to center, ${colors})`; + } } class Reason extends StringObject { @@ -2393,6 +2628,10 @@ class Solid extends XFAObject { this.usehref = attributes.usehref || ""; this.extras = null; } + + [$toStyle](startColor) { + return startColor ? startColor[$toStyle]() : "#FFFFFF"; + } } class Speak extends StringObject { @@ -2430,6 +2669,15 @@ class Stipple extends XFAObject { this.color = null; this.extras = null; } + + [$toStyle](bgColor) { + const alpha = this.rate / 100; + return Util.makeHexColor( + Math.round(bgColor.value.r * (1 - alpha) + this.value.r * alpha), + Math.round(bgColor.value.g * (1 - alpha) + this.value.g * alpha), + Math.round(bgColor.value.b * (1 - alpha) + this.value.b * alpha) + ); + } } class Subform extends XFAObject { @@ -2568,17 +2816,16 @@ class Subform extends XFAObject { page = pageAreas[pageNumber][$toHTML](); } - const style = Object.create(null); - setWidthHeight(this, style); - setPosition(this, style); + const style = toStyle(this, "dimensions", "position"); const attributes = { style, id: this[$uid], + class: "xfaSubform", }; if (this.name) { - attributes["xfa-name"] = this.name; + attributes.xfaName = this.name; } const children = this[$childrenToHTML]({ diff --git a/src/core/xfa/utils.js b/src/core/xfa/utils.js index 67e137a87..872fff44f 100644 --- a/src/core/xfa/utils.js +++ b/src/core/xfa/utils.js @@ -13,7 +13,13 @@ * limitations under the License. */ -const measurementPattern = /([+-]?)([0-9]+\.?[0-9]*)(.*)/; +const dimConverters = { + pt: x => x, + cm: x => (x / 2.54) * 72, + mm: x => (x / (10 * 2.54)) * 72, + in: x => x * 72, +}; +const measurementPattern = /([+-]?[0-9]+\.?[0-9]*)(.*)/; function getInteger({ data, defaultValue, validate }) { if (!data) { @@ -67,15 +73,22 @@ function getMeasurement(str, def = "0") { if (!match) { return getMeasurement(def); } - const [, sign, valueStr, unit] = match; + const [, valueStr, unit] = match; const value = parseFloat(valueStr); if (isNaN(value)) { return getMeasurement(def); } - return { - value: sign === "-" ? -value : value, - unit: unit || "pt", - }; + + if (value === 0) { + return 0; + } + + const conv = dimConverters[unit]; + if (conv) { + return conv(value); + } + + return value; } function getRatio(data) { @@ -134,7 +147,7 @@ function getColor(data, def = [0, 0, 0]) { } function getBBox(data) { - const def = getMeasurement("-1"); + const def = -1; if (!data) { return { x: def, y: def, width: def, height: def }; } @@ -142,7 +155,7 @@ function getBBox(data) { .trim() .split(/\s*,\s*/) .map(m => getMeasurement(m, "-1")); - if (bbox.length < 4 || bbox[2].value < 0 || bbox[3].value < 0) { + if (bbox.length < 4 || bbox[2] < 0 || bbox[3] < 0) { return { x: def, y: def, width: def, height: def }; } diff --git a/src/core/xfa/xfa_object.js b/src/core/xfa/xfa_object.js index 611af1df0..94b083baf 100644 --- a/src/core/xfa/xfa_object.js +++ b/src/core/xfa/xfa_object.js @@ -59,6 +59,7 @@ const $setSetAttributes = Symbol(); const $setValue = Symbol(); const $text = Symbol(); const $toHTML = Symbol(); +const $toStyle = Symbol(); const $uid = Symbol("uid"); const _applyPrototype = Symbol(); @@ -259,6 +260,10 @@ class XFAObject { return dumped; } + [$toStyle]() { + return null; + } + [$toHTML]() { return null; } @@ -839,6 +844,7 @@ export { $setValue, $text, $toHTML, + $toStyle, $uid, ContentObject, IntegerObject, diff --git a/src/display/xfa_layer.js b/src/display/xfa_layer.js index cfedad885..7bd7d3620 100644 --- a/src/display/xfa_layer.js +++ b/src/display/xfa_layer.js @@ -36,9 +36,13 @@ class XfaLayer { } const stack = [[root, -1, rootHtml]]; - parameters.div.appendChild(rootHtml); + const rootDiv = parameters.div; + rootDiv.appendChild(rootHtml); const coeffs = parameters.viewport.transform.join(","); - parameters.div.style.transform = `matrix(${coeffs})`; + rootDiv.style.transform = `matrix(${coeffs})`; + + // Set defaults. + rootDiv.setAttribute("class", "xfaLayer xfaFont"); while (stack.length > 0) { const [parent, i, html] = stack[stack.length - 1]; diff --git a/test/unit/jasmine-boot.js b/test/unit/jasmine-boot.js index d54427eb8..56aed3cf7 100644 --- a/test/unit/jasmine-boot.js +++ b/test/unit/jasmine-boot.js @@ -87,6 +87,7 @@ async function initializePDFJS(callback) { "pdfjs-test/unit/writer_spec.js", "pdfjs-test/unit/xfa_formcalc_spec.js", "pdfjs-test/unit/xfa_parser_spec.js", + "pdfjs-test/unit/xfa_tohtml_spec.js", "pdfjs-test/unit/xml_spec.js", ].map(function (moduleName) { // eslint-disable-next-line no-unsanitized/method diff --git a/test/unit/xfa_parser_spec.js b/test/unit/xfa_parser_spec.js index 6bfbb78c2..329a40fe7 100644 --- a/test/unit/xfa_parser_spec.js +++ b/test/unit/xfa_parser_spec.js @@ -81,9 +81,9 @@ describe("XFAParser", function () { }; const mediumAttributes = { id: "", - long: { value: 0, unit: "pt" }, + long: 0, orientation: "portrait", - short: { value: 0, unit: "pt" }, + short: 0, stock: "", trayIn: "auto", trayOut: "auto", @@ -116,17 +116,17 @@ describe("XFAParser", function () { allowMacro: 0, anchorType: "topLeft", colSpan: 1, - columnWidths: [{ value: 0, unit: "pt" }], - h: { value: 0, unit: "pt" }, + columnWidths: [0], + h: 0, hAlign: "left", id: "", layout: "position", locale: "", - maxH: { value: 0, unit: "pt" }, - maxW: { value: 0, unit: "pt" }, + maxH: 0, + maxW: 0, mergeMode: "consumeData", - minH: { value: 0, unit: "pt" }, - minW: { value: 0, unit: "pt" }, + minH: 0, + minW: 0, name: "", presence: "visible", relevant: [], @@ -134,15 +134,15 @@ describe("XFAParser", function () { scope: "name", use: "", usehref: "", - w: { value: 0, unit: "pt" }, - x: { value: 0, unit: "pt" }, - y: { value: 0, unit: "pt" }, + w: 0, + x: 0, + y: 0, proto: { area: { ...attributes, colSpan: 1, - x: { value: 0, unit: "pt" }, - y: { value: -3.14, unit: "in" }, + x: 0, + y: -226.08, relevant: [ { excluded: true, viewname: "foo" }, { excluded: false, viewname: "bar" }, @@ -162,19 +162,19 @@ describe("XFAParser", function () { { ...mediumAttributes, imagingBBox: { - x: { value: 1, unit: "pt" }, - y: { value: 2, unit: "in" }, - width: { value: 3.4, unit: "cm" }, - height: { value: 5.67, unit: "px" }, + x: 1, + y: 144, + width: 96.3779527559055, + height: 5.67, }, }, { ...mediumAttributes, imagingBBox: { - x: { value: -1, unit: "pt" }, - y: { value: -1, unit: "pt" }, - width: { value: -1, unit: "pt" }, - height: { value: -1, unit: "pt" }, + x: -1, + y: -1, + width: -1, + height: -1, }, }, ], @@ -288,7 +288,7 @@ describe("XFAParser", function () { let font = root.template.subform.field[0].font; expect(font.typeface).toEqual("Foo"); expect(font.overline).toEqual(0); - expect(font.size).toEqual({ value: 123, unit: "pt" }); + expect(font.size).toEqual(123); expect(font.weight).toEqual("bold"); expect(font.posture).toEqual("italic"); expect(font.fill.color.value).toEqual({ r: 1, g: 2, b: 3 }); @@ -297,7 +297,7 @@ describe("XFAParser", function () { font = root.template.subform.field[1].font; expect(font.typeface).toEqual("Foo"); expect(font.overline).toEqual(0); - expect(font.size).toEqual({ value: 456, unit: "pt" }); + expect(font.size).toEqual(456); expect(font.weight).toEqual("bold"); expect(font.posture).toEqual("normal"); expect(font.fill.color.value).toEqual({ r: 4, g: 5, b: 6 }); @@ -387,7 +387,7 @@ describe("XFAParser", function () { expect(font.typeface).toEqual("helvetica"); expect(font.overline).toEqual(0); - expect(font.size).toEqual({ value: 31, unit: "pt" }); + expect(font.size).toEqual(31); expect(font.weight).toEqual("normal"); expect(font.posture).toEqual("italic"); expect(font.fill.color.value).toEqual({ r: 7, g: 8, b: 9 }); @@ -1005,10 +1005,7 @@ describe("XFAParser", function () { ).toBe("myfont"); expect( searchNode(form, form, "Id.LastName.font.size")[0][$text]() - ).toEqual({ - value: 123.4, - unit: "pt", - }); + ).toEqual(123.4); expect( searchNode(form, form, "Id.LastName.assist.toolTip")[0][$dump]() .$content diff --git a/test/unit/xfa_tohtml_spec.js b/test/unit/xfa_tohtml_spec.js new file mode 100644 index 000000000..299dce95a --- /dev/null +++ b/test/unit/xfa_tohtml_spec.js @@ -0,0 +1,98 @@ +/* Copyright 2020 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. + */ + +import { XFAFactory } from "../../src/core/xfa/factory.js"; + +describe("XFAFactory", function () { + describe("toHTML", function () { + it("should convert some basic properties to CSS", function () { + const xml = ` + + + + + + + + + `; + const factory = new XFAFactory({ "xdp:xdp": xml }); + + expect(factory.numberPages).toEqual(2); + + const page1 = factory.getPage(0); + expect(page1.attributes.style).toEqual({ + height: "789px", + width: "456px", + }); + + expect(page1.children.length).toEqual(2); + const container = page1.children[0]; + expect(container.attributes.class).toEqual("xfaContentarea"); + expect(container.attributes.style).toEqual({ + height: "789px", + width: "456px", + left: "123px", + top: "0px", + position: "absolute", + }); + + const draw = page1.children[1]; + expect(draw.attributes.class).toEqual("xfaDraw xfaFont"); + expect(draw.attributes.style).toEqual({ + color: "#0c1722", + fontFamily: "Arial", + fontSize: "7px", + height: "22px", + left: "2px", + position: "absolute", + top: "1px", + transform: "rotate(-90deg)", + transformOrigin: "top left", + verticalAlign: "2px", + width: "11px", + }); + + // draw element must be on each page. + expect(draw.attributes.style).toEqual( + factory.getPage(1).children[1].attributes.style + ); + }); + }); +}); diff --git a/web/xfa_layer_builder.css b/web/xfa_layer_builder.css index b891225f4..3a36581ca 100644 --- a/web/xfa_layer_builder.css +++ b/web/xfa_layer_builder.css @@ -20,3 +20,43 @@ z-index: 200; transform-origin: 0 0; } + +.xfaLayer * { + color: inherit; + font: inherit; + font-kerning: inherit; + letter-spacing: inherit; + text-decoration: inherit; + vertical-align: inherit; +} + +.xfaFont { + color: black; + font-weight: normal; + font-kerning: none; + font-size: 10px; + font-style: normal; + letter-spacing: 0; + text-decoration: none; + vertical-align: 0; +} + +.xfaDraw { + z-index: 200; + background-color: #ff000080; +} + +.xfaExclgroup { + z-index: 300; + background-color: #0000ff80; +} + +.xfaField { + z-index: 300; + background-color: #00ff0080; +} + +.xfaSubform { + z-index: 100; + background-color: #ffff0080; +} diff --git a/web/xfa_layer_builder.js b/web/xfa_layer_builder.js index b875db21e..1b13a13cb 100644 --- a/web/xfa_layer_builder.js +++ b/web/xfa_layer_builder.js @@ -57,7 +57,6 @@ class XfaLayerBuilder { } else { // Create an xfa layer div and render the form this.div = document.createElement("div"); - this.div.className = "xfaLayer"; this.pageDiv.appendChild(this.div); parameters.div = this.div;