XFA - Fix layout issues (again)
- some elements weren't displayed because their rotation angle was not taken into account; - fix box model (XFA concept): - remove use of outline; - position correctly border which isn't part of box dimensions; - fix margins issues (see issue #13474). - move border on button instead of having it on wrapping div;
This commit is contained in:
parent
e8fe0711ee
commit
cfa727474e
@ -172,68 +172,22 @@ const converters = {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (node.hAlign) {
|
switch (node.hAlign) {
|
||||||
case "right":
|
case "left":
|
||||||
|
style.alignSelf = "start";
|
||||||
|
break;
|
||||||
case "center":
|
case "center":
|
||||||
style.justifyContent = node.hAlign;
|
style.alignSelf = "center";
|
||||||
|
break;
|
||||||
|
case "right":
|
||||||
|
style.alignSelf = "end";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
borderMarginPadding(node, style) {
|
margin(node, style) {
|
||||||
// Get border width in order to compute margin and padding.
|
|
||||||
const borderWidths = [0, 0, 0, 0];
|
|
||||||
const borderInsets = [0, 0, 0, 0];
|
|
||||||
const marginNode = node.margin
|
|
||||||
? [
|
|
||||||
node.margin.topInset,
|
|
||||||
node.margin.rightInset,
|
|
||||||
node.margin.bottomInset,
|
|
||||||
node.margin.leftInset,
|
|
||||||
]
|
|
||||||
: [0, 0, 0, 0];
|
|
||||||
|
|
||||||
let borderMargin;
|
|
||||||
if (node.border) {
|
|
||||||
Object.assign(style, node.border[$toStyle](borderWidths, borderInsets));
|
|
||||||
borderMargin = style.margin;
|
|
||||||
delete style.margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (borderWidths.every(x => x === 0)) {
|
|
||||||
if (marginNode.every(x => x === 0)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No border: margin & padding are padding
|
|
||||||
Object.assign(style, node.margin[$toStyle]());
|
|
||||||
style.padding = style.margin;
|
|
||||||
delete style.margin;
|
|
||||||
delete style.outline;
|
|
||||||
delete style.outlineOffset;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.margin) {
|
if (node.margin) {
|
||||||
Object.assign(style, node.margin[$toStyle]());
|
style.margin = node.margin[$toStyle]().margin;
|
||||||
style.padding = style.margin;
|
|
||||||
delete style.margin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!style.borderWidth) {
|
|
||||||
// We've an outline so no need to fake one.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
style.borderData = {
|
|
||||||
borderWidth: style.borderWidth,
|
|
||||||
borderColor: style.borderColor,
|
|
||||||
borderStyle: style.borderStyle,
|
|
||||||
margin: borderMargin,
|
|
||||||
};
|
|
||||||
|
|
||||||
delete style.borderWidth;
|
|
||||||
delete style.borderColor;
|
|
||||||
delete style.borderStyle;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -441,92 +395,99 @@ function toStyle(node, ...names) {
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addExtraDivForBorder(html) {
|
function createWrapper(node, html) {
|
||||||
const style = html.attributes.style;
|
const { attributes } = html;
|
||||||
const data = style.borderData;
|
const { style } = attributes;
|
||||||
const children = [];
|
|
||||||
|
|
||||||
const attributes = {
|
const wrapper = {
|
||||||
class: "xfaWrapper",
|
name: "div",
|
||||||
style: Object.create(null),
|
attributes: {
|
||||||
|
class: ["xfaWrapper"],
|
||||||
|
style: Object.create(null),
|
||||||
|
},
|
||||||
|
children: [html],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const key of ["top", "left"]) {
|
attributes.class.push("xfaWrapped");
|
||||||
|
|
||||||
|
if (node.border) {
|
||||||
|
const { widths, insets } = node.border[$extra];
|
||||||
|
let shiftH = 0;
|
||||||
|
let shiftW = 0;
|
||||||
|
switch (node.border.hand) {
|
||||||
|
case "even":
|
||||||
|
shiftW = widths[0] / 2;
|
||||||
|
shiftH = widths[3] / 2;
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
shiftW = widths[0];
|
||||||
|
shiftH = widths[3];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const insetsW = insets[1] + insets[3];
|
||||||
|
const insetsH = insets[0] + insets[2];
|
||||||
|
const border = {
|
||||||
|
name: "div",
|
||||||
|
attributes: {
|
||||||
|
class: ["xfaBorder"],
|
||||||
|
style: {
|
||||||
|
top: `${insets[0] - widths[0] + shiftW}px`,
|
||||||
|
left: `${insets[3] - widths[3] + shiftH}px`,
|
||||||
|
width: insetsW ? `calc(100% - ${insetsW}px)` : "100%",
|
||||||
|
height: insetsH ? `calc(100% - ${insetsH}px)` : "100%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const key of [
|
||||||
|
"border",
|
||||||
|
"borderWidth",
|
||||||
|
"borderColor",
|
||||||
|
"borderRadius",
|
||||||
|
"borderStyle",
|
||||||
|
]) {
|
||||||
|
if (style[key] !== undefined) {
|
||||||
|
border.attributes.style[key] = style[key];
|
||||||
|
delete style[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrapper.children.push(border);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of [
|
||||||
|
"background",
|
||||||
|
"backgroundClip",
|
||||||
|
"top",
|
||||||
|
"left",
|
||||||
|
"width",
|
||||||
|
"height",
|
||||||
|
"minWidth",
|
||||||
|
"minHeight",
|
||||||
|
"maxWidth",
|
||||||
|
"maxHeight",
|
||||||
|
"transform",
|
||||||
|
"transformOrigin",
|
||||||
|
]) {
|
||||||
if (style[key] !== undefined) {
|
if (style[key] !== undefined) {
|
||||||
attributes.style[key] = style[key];
|
wrapper.attributes.style[key] = style[key];
|
||||||
|
delete style[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete style.top;
|
|
||||||
delete style.left;
|
|
||||||
|
|
||||||
if (style.position === "absolute") {
|
if (style.position === "absolute") {
|
||||||
attributes.style.position = "absolute";
|
wrapper.attributes.style.position = "absolute";
|
||||||
} else {
|
} else {
|
||||||
attributes.style.position = "relative";
|
wrapper.attributes.style.position = "relative";
|
||||||
}
|
}
|
||||||
delete style.position;
|
delete style.position;
|
||||||
|
|
||||||
if (style.justifyContent) {
|
if (style.alignSelf) {
|
||||||
attributes.style.justifyContent = style.justifyContent;
|
wrapper.attributes.style.alignSelf = style.alignSelf;
|
||||||
delete style.justifyContent;
|
delete style.alignSelf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data) {
|
return wrapper;
|
||||||
delete style.borderData;
|
|
||||||
|
|
||||||
let insets;
|
|
||||||
if (data.margin) {
|
|
||||||
insets = data.margin.split(" ");
|
|
||||||
delete data.margin;
|
|
||||||
} else {
|
|
||||||
insets = ["0px", "0px", "0px", "0px"];
|
|
||||||
}
|
|
||||||
|
|
||||||
let width = "100%";
|
|
||||||
let height = width;
|
|
||||||
|
|
||||||
if (insets[1] !== "0px" || insets[3] !== "0px") {
|
|
||||||
width = `calc(100% - ${parseInt(insets[1]) + parseInt(insets[3])}px`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insets[0] !== "0px" || insets[2] !== "0px") {
|
|
||||||
height = `calc(100% - ${parseInt(insets[0]) + parseInt(insets[2])}px`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const borderStyle = {
|
|
||||||
top: insets[0],
|
|
||||||
left: insets[3],
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(data)) {
|
|
||||||
borderStyle[k] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (style.transform) {
|
|
||||||
borderStyle.transform = style.transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
const borderDiv = {
|
|
||||||
name: "div",
|
|
||||||
attributes: {
|
|
||||||
class: "xfaBorderDiv",
|
|
||||||
style: borderStyle,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
children.push(borderDiv);
|
|
||||||
}
|
|
||||||
|
|
||||||
children.push(html);
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: "div",
|
|
||||||
attributes,
|
|
||||||
children,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixTextIndent(styles) {
|
function fixTextIndent(styles) {
|
||||||
@ -535,11 +496,12 @@ function fixTextIndent(styles) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If indent is negative then it's a hanging indent.
|
||||||
const align = styles.textAlign || "left";
|
const align = styles.textAlign || "left";
|
||||||
if (align === "left" || align === "right") {
|
if (align === "left" || align === "right") {
|
||||||
const name = "margin" + (align === "left" ? "Left" : "Right");
|
const name = "padding" + (align === "left" ? "Left" : "Right");
|
||||||
const margin = getMeasurement(styles[name], "0px");
|
const padding = getMeasurement(styles[name], "0px");
|
||||||
styles[name] = `${margin - indent}pt`;
|
styles[name] = `${padding - indent}px`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,8 +535,8 @@ function getFonts(family) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
addExtraDivForBorder,
|
|
||||||
computeBbox,
|
computeBbox,
|
||||||
|
createWrapper,
|
||||||
fixDimensions,
|
fixDimensions,
|
||||||
fixTextIndent,
|
fixTextIndent,
|
||||||
getFonts,
|
getFonts,
|
||||||
|
@ -46,6 +46,9 @@ import { measureToString } from "./html_utils.js";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function flushHTML(node) {
|
function flushHTML(node) {
|
||||||
|
if (!node[$extra]) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const attributes = node[$extra].attributes;
|
const attributes = node[$extra].attributes;
|
||||||
const html = {
|
const html = {
|
||||||
name: "div",
|
name: "div",
|
||||||
@ -88,7 +91,7 @@ function addHTML(node, html, bbox) {
|
|||||||
extra.line = {
|
extra.line = {
|
||||||
name: "div",
|
name: "div",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: node.layout === "lr-tb" ? "xfaLr" : "xfaRl",
|
class: [node.layout === "lr-tb" ? "xfaLr" : "xfaRl"],
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
@ -120,12 +123,7 @@ function addHTML(node, html, bbox) {
|
|||||||
extra.height = Math.max(extra.height, h);
|
extra.height = Math.max(extra.height, h);
|
||||||
const height = measureToString(extra.height);
|
const height = measureToString(extra.height);
|
||||||
for (const child of extra.children) {
|
for (const child of extra.children) {
|
||||||
if (child.attributes.class === "xfaWrapper") {
|
child.attributes.style.height = height;
|
||||||
child.children[child.children.length - 1].attributes.style.height =
|
|
||||||
height;
|
|
||||||
} else {
|
|
||||||
child.attributes.style.height = height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -148,6 +146,12 @@ function addHTML(node, html, bbox) {
|
|||||||
|
|
||||||
function getAvailableSpace(node) {
|
function getAvailableSpace(node) {
|
||||||
const availableSpace = node[$extra].availableSpace;
|
const availableSpace = node[$extra].availableSpace;
|
||||||
|
const [marginW, marginH] = node.margin
|
||||||
|
? [
|
||||||
|
node.margin.leftInset + node.margin.rightInset,
|
||||||
|
node.margin.topInset + node.margin.leftInset,
|
||||||
|
]
|
||||||
|
: [0, 0];
|
||||||
|
|
||||||
switch (node.layout) {
|
switch (node.layout) {
|
||||||
case "lr-tb":
|
case "lr-tb":
|
||||||
@ -155,18 +159,18 @@ function getAvailableSpace(node) {
|
|||||||
switch (node[$extra].attempt) {
|
switch (node[$extra].attempt) {
|
||||||
case 0:
|
case 0:
|
||||||
return {
|
return {
|
||||||
width: availableSpace.width - node[$extra].currentWidth,
|
width: availableSpace.width - marginW - node[$extra].currentWidth,
|
||||||
height: availableSpace.height - node[$extra].prevHeight,
|
height: availableSpace.height - marginH - node[$extra].prevHeight,
|
||||||
};
|
};
|
||||||
case 1:
|
case 1:
|
||||||
return {
|
return {
|
||||||
width: availableSpace.width,
|
width: availableSpace.width - marginW,
|
||||||
height: availableSpace.height - node[$extra].height,
|
height: availableSpace.height - marginH - node[$extra].height,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
width: Infinity,
|
width: Infinity,
|
||||||
height: availableSpace.height - node[$extra].prevHeight,
|
height: availableSpace.height - marginH - node[$extra].prevHeight,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case "rl-row":
|
case "rl-row":
|
||||||
@ -174,12 +178,12 @@ function getAvailableSpace(node) {
|
|||||||
const width = node[$extra].columnWidths
|
const width = node[$extra].columnWidths
|
||||||
.slice(node[$extra].currentColumn)
|
.slice(node[$extra].currentColumn)
|
||||||
.reduce((a, x) => a + x);
|
.reduce((a, x) => a + x);
|
||||||
return { width, height: availableSpace.height };
|
return { width, height: availableSpace.height - marginH };
|
||||||
case "table":
|
case "table":
|
||||||
case "tb":
|
case "tb":
|
||||||
return {
|
return {
|
||||||
width: availableSpace.width,
|
width: availableSpace.width - marginW,
|
||||||
height: availableSpace.height - node[$extra].height,
|
height: availableSpace.height - marginH - node[$extra].height,
|
||||||
};
|
};
|
||||||
case "position":
|
case "position":
|
||||||
default:
|
default:
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
$acceptWhitespace,
|
||||||
$addHTML,
|
$addHTML,
|
||||||
$appendChild,
|
$appendChild,
|
||||||
$break,
|
$break,
|
||||||
@ -34,6 +35,7 @@ import {
|
|||||||
$namespaceId,
|
$namespaceId,
|
||||||
$nodeName,
|
$nodeName,
|
||||||
$onChild,
|
$onChild,
|
||||||
|
$onText,
|
||||||
$removeChild,
|
$removeChild,
|
||||||
$searchNode,
|
$searchNode,
|
||||||
$setSetAttributes,
|
$setSetAttributes,
|
||||||
@ -50,9 +52,10 @@ import {
|
|||||||
XFAObjectArray,
|
XFAObjectArray,
|
||||||
} from "./xfa_object.js";
|
} from "./xfa_object.js";
|
||||||
import { $buildXFAObject, NamespaceIds } from "./namespaces.js";
|
import { $buildXFAObject, NamespaceIds } from "./namespaces.js";
|
||||||
|
import { addHTML, flushHTML, getAvailableSpace } from "./layout.js";
|
||||||
import {
|
import {
|
||||||
addExtraDivForBorder,
|
|
||||||
computeBbox,
|
computeBbox,
|
||||||
|
createWrapper,
|
||||||
fixDimensions,
|
fixDimensions,
|
||||||
fixTextIndent,
|
fixTextIndent,
|
||||||
getFonts,
|
getFonts,
|
||||||
@ -61,7 +64,6 @@ import {
|
|||||||
measureToString,
|
measureToString,
|
||||||
toStyle,
|
toStyle,
|
||||||
} from "./html_utils.js";
|
} from "./html_utils.js";
|
||||||
import { addHTML, flushHTML, getAvailableSpace } from "./layout.js";
|
|
||||||
import {
|
import {
|
||||||
getBBox,
|
getBBox,
|
||||||
getColor,
|
getColor,
|
||||||
@ -103,26 +105,90 @@ function getRoot(node) {
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTransformedBBox(node) {
|
||||||
|
// Take into account rotation and anchor the get the
|
||||||
|
// real bounding box.
|
||||||
|
let w = node.w === "" ? NaN : node.w;
|
||||||
|
let h = node.h === "" ? NaN : node.h;
|
||||||
|
let [centerX, centerY] = [0, 0];
|
||||||
|
switch (node.anchorType || "") {
|
||||||
|
case "bottomCenter":
|
||||||
|
[centerX, centerY] = [w / 2, h];
|
||||||
|
break;
|
||||||
|
case "bottomLeft":
|
||||||
|
[centerX, centerY] = [0, h];
|
||||||
|
break;
|
||||||
|
case "bottomRight":
|
||||||
|
[centerX, centerY] = [w, h];
|
||||||
|
break;
|
||||||
|
case "middleCenter":
|
||||||
|
[centerX, centerY] = [w / 2, h / 2];
|
||||||
|
break;
|
||||||
|
case "middleLeft":
|
||||||
|
[centerX, centerY] = [0, h / 2];
|
||||||
|
break;
|
||||||
|
case "middleRight":
|
||||||
|
[centerX, centerY] = [w, h / 2];
|
||||||
|
break;
|
||||||
|
case "topCenter":
|
||||||
|
[centerX, centerY] = [w / 2, 0];
|
||||||
|
break;
|
||||||
|
case "topRight":
|
||||||
|
[centerX, centerY] = [w, 0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let x;
|
||||||
|
let y;
|
||||||
|
switch (node.rotate || 0) {
|
||||||
|
case 0:
|
||||||
|
[x, y] = [-centerX, -centerY];
|
||||||
|
break;
|
||||||
|
case 90:
|
||||||
|
[x, y] = [-centerY, centerX];
|
||||||
|
[w, h] = [h, -w];
|
||||||
|
break;
|
||||||
|
case 180:
|
||||||
|
[x, y] = [centerX, centerY];
|
||||||
|
[w, h] = [-w, -h];
|
||||||
|
break;
|
||||||
|
case 270:
|
||||||
|
[x, y] = [centerY, -centerX];
|
||||||
|
[w, h] = [-h, w];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
node.x + x + Math.min(0, w),
|
||||||
|
node.y + y + Math.min(0, h),
|
||||||
|
Math.abs(w),
|
||||||
|
Math.abs(h),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const NOTHING = 0;
|
const NOTHING = 0;
|
||||||
const NOSPACE = 1;
|
const NOSPACE = 1;
|
||||||
const VALID = 2;
|
const VALID = 2;
|
||||||
function checkDimensions(node, space) {
|
function checkDimensions(node, space) {
|
||||||
if (node.w !== "" && Math.round(node.w + node.x - space.width) > 1) {
|
const [x, y, w, h] = getTransformedBBox(node);
|
||||||
|
if (node.w !== "" && Math.round(x + w - space.width) > 1) {
|
||||||
const area = getRoot(node)[$extra].currentContentArea;
|
const area = getRoot(node)[$extra].currentContentArea;
|
||||||
if (node.w + node.x > area.w) {
|
if (x + w > area.w) {
|
||||||
return NOTHING;
|
|
||||||
}
|
|
||||||
return NOSPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.h !== "" && Math.round(node.h + node.y - space.height) > 1) {
|
|
||||||
const area = getRoot(node)[$extra].currentContentArea;
|
|
||||||
if (node.h + node.y > area.h) {
|
|
||||||
return NOTHING;
|
return NOTHING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NOSPACE;
|
return NOSPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node.h !== "" && Math.round(y + h - space.height) > 1) {
|
||||||
|
const area = getRoot(node)[$extra].currentContentArea;
|
||||||
|
if (y + h > area.h) {
|
||||||
|
return NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NOSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
return VALID;
|
return VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +277,7 @@ class Area extends XFAObject {
|
|||||||
const attributes = {
|
const attributes = {
|
||||||
style,
|
style,
|
||||||
id: this[$uid],
|
id: this[$uid],
|
||||||
class: "xfaArea",
|
class: ["xfaArea"],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.name) {
|
if (this.name) {
|
||||||
@ -503,7 +569,7 @@ class Border extends XFAObject {
|
|||||||
this.margin = null;
|
this.margin = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[$toStyle](widths, margins) {
|
[$toStyle]() {
|
||||||
// TODO: incomplete.
|
// TODO: incomplete.
|
||||||
const edges = this.edge.children.slice();
|
const edges = this.edge.children.slice();
|
||||||
if (edges.length < 4) {
|
if (edges.length < 4) {
|
||||||
@ -513,41 +579,32 @@ class Border extends XFAObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
widths = widths || [0, 0, 0, 0];
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
widths[i] = edges[i].thickness;
|
|
||||||
}
|
|
||||||
|
|
||||||
margins = margins || [0, 0, 0, 0];
|
|
||||||
|
|
||||||
const edgeStyles = edges.map(node => {
|
const edgeStyles = edges.map(node => {
|
||||||
const style = node[$toStyle]();
|
const style = node[$toStyle]();
|
||||||
style.color = style.color || "#000000";
|
style.color = style.color || "#000000";
|
||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
let style;
|
|
||||||
if (this.margin) {
|
|
||||||
style = this.margin[$toStyle]();
|
|
||||||
margins[0] = this.margin.topInset;
|
|
||||||
margins[1] = this.margin.rightInset;
|
|
||||||
margins[2] = this.margin.bottomInset;
|
|
||||||
margins[3] = this.margin.leftInset;
|
|
||||||
} else {
|
|
||||||
style = Object.create(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
let isForUi = false;
|
const widths = edges.map(edge => edge.thickness);
|
||||||
const parent = this[$getParent]();
|
const insets = [0, 0, 0, 0];
|
||||||
const grandParent = parent ? parent[$getParent]() : null;
|
if (this.margin) {
|
||||||
if (grandParent instanceof Ui) {
|
insets[0] = this.margin.topInset;
|
||||||
isForUi = true;
|
insets[1] = this.margin.rightInset;
|
||||||
|
insets[2] = this.margin.bottomInset;
|
||||||
|
insets[3] = this.margin.leftInset;
|
||||||
|
}
|
||||||
|
this[$extra] = { widths, insets };
|
||||||
|
// TODO: hand.
|
||||||
|
|
||||||
|
const style = Object.create(null);
|
||||||
|
if (this.margin) {
|
||||||
|
Object.assign(style, this.margin[$toStyle]());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fill) {
|
if (this.fill) {
|
||||||
Object.assign(style, this.fill[$toStyle]());
|
Object.assign(style, this.fill[$toStyle]());
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasRadius = false;
|
|
||||||
if (this.corner.children.some(node => node.radius !== 0)) {
|
if (this.corner.children.some(node => node.radius !== 0)) {
|
||||||
const cornerStyles = this.corner.children.map(node => node[$toStyle]());
|
const cornerStyles = this.corner.children.map(node => node[$toStyle]());
|
||||||
if (cornerStyles.length === 2 || cornerStyles.length === 3) {
|
if (cornerStyles.length === 2 || cornerStyles.length === 3) {
|
||||||
@ -558,62 +615,24 @@ class Border extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
style.borderRadius = cornerStyles.map(s => s.radius).join(" ");
|
style.borderRadius = cornerStyles.map(s => s.radius).join(" ");
|
||||||
hasRadius = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const firstEdge = edgeStyles[0];
|
switch (this.presence) {
|
||||||
if (
|
case "invisible":
|
||||||
!hasRadius &&
|
case "hidden":
|
||||||
(this.edge.children.length <= 1 ||
|
style.borderStyle = "";
|
||||||
(edgeStyles.every(
|
break;
|
||||||
x =>
|
case "inactive":
|
||||||
x.style === firstEdge.style &&
|
style.borderStyle = "none";
|
||||||
x.width === firstEdge.width &&
|
break;
|
||||||
x.color === firstEdge.color
|
default:
|
||||||
) &&
|
style.borderStyle = edgeStyles.map(s => s.style).join(" ");
|
||||||
margins.every(x => x === margins[0])))
|
break;
|
||||||
) {
|
|
||||||
// Rectangular border and same values for each edge then we've an outline
|
|
||||||
// so no need to emulate it.
|
|
||||||
|
|
||||||
let borderStyle;
|
|
||||||
switch (this.presence) {
|
|
||||||
case "invisible":
|
|
||||||
case "hidden":
|
|
||||||
borderStyle = "";
|
|
||||||
break;
|
|
||||||
case "inactive":
|
|
||||||
borderStyle = "none";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
borderStyle = firstEdge.style;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
style.outline = `${firstEdge.width} ${firstEdge.color} ${borderStyle}`;
|
|
||||||
const offset = edges[0].thickness + margins[0];
|
|
||||||
style.outlineOffset = `-${measureToString(offset)}`;
|
|
||||||
if (isForUi) {
|
|
||||||
style.padding = `${measureToString(offset + 1)}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (this.presence) {
|
|
||||||
case "invisible":
|
|
||||||
case "hidden":
|
|
||||||
style.borderStyle = "";
|
|
||||||
break;
|
|
||||||
case "inactive":
|
|
||||||
style.borderStyle = "none";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
style.borderStyle = edgeStyles.map(s => s.style).join(" ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
style.borderWidth = edgeStyles.map(s => s.width).join(" ");
|
|
||||||
style.borderColor = edgeStyles.map(s => s.color).join(" ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style.borderWidth = edgeStyles.map(s => s.width).join(" ");
|
||||||
|
style.borderColor = edgeStyles.map(s => s.color).join(" ");
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -729,7 +748,8 @@ class Button extends XFAObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "button",
|
name: "button",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaButton",
|
id: this[$uid],
|
||||||
|
class: ["xfaButton"],
|
||||||
style: {},
|
style: {},
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
@ -830,7 +850,7 @@ class Caption extends XFAObject {
|
|||||||
name: "div",
|
name: "div",
|
||||||
attributes: {
|
attributes: {
|
||||||
style,
|
style,
|
||||||
class: "xfaCaption",
|
class: ["xfaCaption"],
|
||||||
},
|
},
|
||||||
children,
|
children,
|
||||||
});
|
});
|
||||||
@ -917,7 +937,7 @@ class CheckButton extends XFAObject {
|
|||||||
const input = {
|
const input = {
|
||||||
name: "input",
|
name: "input",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: className,
|
class: [className],
|
||||||
style,
|
style,
|
||||||
fieldId,
|
fieldId,
|
||||||
type,
|
type,
|
||||||
@ -935,7 +955,7 @@ class CheckButton extends XFAObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "label",
|
name: "label",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaLabel",
|
class: ["xfaLabel"],
|
||||||
},
|
},
|
||||||
children: [input],
|
children: [input],
|
||||||
});
|
});
|
||||||
@ -990,7 +1010,7 @@ class ChoiceList extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selectAttributes = {
|
const selectAttributes = {
|
||||||
class: "xfaSelect",
|
class: ["xfaSelect"],
|
||||||
fieldId: this[$getParent]()[$getParent]()[$uid],
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
style,
|
style,
|
||||||
};
|
};
|
||||||
@ -1002,7 +1022,7 @@ class ChoiceList extends XFAObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "label",
|
name: "label",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaLabel",
|
class: ["xfaLabel"],
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -1101,7 +1121,7 @@ class ContentArea extends XFAObject {
|
|||||||
children: [],
|
children: [],
|
||||||
attributes: {
|
attributes: {
|
||||||
style,
|
style,
|
||||||
class: "xfaContentarea",
|
class: ["xfaContentarea"],
|
||||||
id: this[$uid],
|
id: this[$uid],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -1219,7 +1239,7 @@ class DateTimeEdit extends XFAObject {
|
|||||||
attributes: {
|
attributes: {
|
||||||
type: "text",
|
type: "text",
|
||||||
fieldId: this[$getParent]()[$getParent]()[$uid],
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: ["xfaTextfield"],
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -1227,7 +1247,7 @@ class DateTimeEdit extends XFAObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "label",
|
name: "label",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaLabel",
|
class: ["xfaLabel"],
|
||||||
},
|
},
|
||||||
children: [html],
|
children: [html],
|
||||||
});
|
});
|
||||||
@ -1432,7 +1452,8 @@ class Draw extends XFAObject {
|
|||||||
"presence",
|
"presence",
|
||||||
"rotate",
|
"rotate",
|
||||||
"anchorType",
|
"anchorType",
|
||||||
"borderMarginPadding"
|
"border",
|
||||||
|
"margin"
|
||||||
);
|
);
|
||||||
|
|
||||||
const classNames = ["xfaDraw"];
|
const classNames = ["xfaDraw"];
|
||||||
@ -1443,7 +1464,7 @@ class Draw extends XFAObject {
|
|||||||
const attributes = {
|
const attributes = {
|
||||||
style,
|
style,
|
||||||
id: this[$uid],
|
id: this[$uid],
|
||||||
class: classNames.join(" "),
|
class: classNames,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.name) {
|
if (this.name) {
|
||||||
@ -1456,16 +1477,15 @@ class Draw extends XFAObject {
|
|||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const extra = addExtraDivForBorder(html);
|
|
||||||
const bbox = computeBbox(this, html, availableSpace);
|
const bbox = computeBbox(this, html, availableSpace);
|
||||||
|
|
||||||
const value = this.value ? this.value[$toHTML](availableSpace).html : null;
|
const value = this.value ? this.value[$toHTML](availableSpace).html : null;
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
return HTMLResult.success(extra, bbox);
|
return HTMLResult.success(createWrapper(this, html), bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
html.children.push(value);
|
html.children.push(value);
|
||||||
if (value.attributes.class === "xfaRich") {
|
if (value.attributes.class.includes("xfaRich")) {
|
||||||
if (this.h === "") {
|
if (this.h === "") {
|
||||||
style.height = "auto";
|
style.height = "auto";
|
||||||
}
|
}
|
||||||
@ -1502,7 +1522,7 @@ class Draw extends XFAObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTMLResult.success(extra, bbox);
|
return HTMLResult.success(createWrapper(this, html), bbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1528,11 +1548,7 @@ class Edge extends XFAObject {
|
|||||||
"lowered",
|
"lowered",
|
||||||
"raised",
|
"raised",
|
||||||
]);
|
]);
|
||||||
// Cheat the thickness to have something nice at the end
|
this.thickness = getMeasurement(attributes.thickness, "0.5pt");
|
||||||
this.thickness = Math.max(
|
|
||||||
1,
|
|
||||||
Math.round(getMeasurement(attributes.thickness, "0.5pt"))
|
|
||||||
);
|
|
||||||
this.use = attributes.use || "";
|
this.use = attributes.use || "";
|
||||||
this.usehref = attributes.usehref || "";
|
this.usehref = attributes.usehref || "";
|
||||||
this.color = null;
|
this.color = null;
|
||||||
@ -1544,7 +1560,7 @@ class Edge extends XFAObject {
|
|||||||
const style = toStyle(this, "visibility");
|
const style = toStyle(this, "visibility");
|
||||||
Object.assign(style, {
|
Object.assign(style, {
|
||||||
linecap: this.cap,
|
linecap: this.cap,
|
||||||
width: measureToString(Math.max(1, Math.round(this.thickness))),
|
width: measureToString(this.thickness),
|
||||||
color: this.color ? this.color[$toStyle]() : "#000000",
|
color: this.color ? this.color[$toStyle]() : "#000000",
|
||||||
style: "",
|
style: "",
|
||||||
});
|
});
|
||||||
@ -1983,7 +1999,8 @@ class ExclGroup extends XFAObject {
|
|||||||
"dimensions",
|
"dimensions",
|
||||||
"position",
|
"position",
|
||||||
"presence",
|
"presence",
|
||||||
"borderMarginPadding",
|
"border",
|
||||||
|
"margin",
|
||||||
"hAlign"
|
"hAlign"
|
||||||
);
|
);
|
||||||
const classNames = ["xfaExclgroup"];
|
const classNames = ["xfaExclgroup"];
|
||||||
@ -1993,7 +2010,7 @@ class ExclGroup extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attributes.style = style;
|
attributes.style = style;
|
||||||
attributes.class = classNames.join(" ");
|
attributes.class = classNames;
|
||||||
|
|
||||||
if (this.name) {
|
if (this.name) {
|
||||||
attributes.xfaName = this.name;
|
attributes.xfaName = this.name;
|
||||||
@ -2025,6 +2042,9 @@ class ExclGroup extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (failure) {
|
if (failure) {
|
||||||
|
if (this.layout === "position") {
|
||||||
|
delete this[$extra];
|
||||||
|
}
|
||||||
return HTMLResult.FAILURE;
|
return HTMLResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2042,13 +2062,12 @@ class ExclGroup extends XFAObject {
|
|||||||
style.height = measureToString(this[$extra].height + marginV);
|
style.height = measureToString(this[$extra].height + marginV);
|
||||||
}
|
}
|
||||||
|
|
||||||
let html = {
|
const html = {
|
||||||
name: "div",
|
name: "div",
|
||||||
attributes,
|
attributes,
|
||||||
children,
|
children,
|
||||||
};
|
};
|
||||||
|
|
||||||
html = addExtraDivForBorder(html);
|
|
||||||
let bbox;
|
let bbox;
|
||||||
if (this.w !== "" && this.h !== "") {
|
if (this.w !== "" && this.h !== "") {
|
||||||
bbox = [this.x, this.y, this.w, this.h];
|
bbox = [this.x, this.y, this.w, this.h];
|
||||||
@ -2061,7 +2080,7 @@ class ExclGroup extends XFAObject {
|
|||||||
|
|
||||||
delete this[$extra];
|
delete this[$extra];
|
||||||
|
|
||||||
return HTMLResult.success(html, bbox);
|
return HTMLResult.success(createWrapper(this, html), bbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2227,7 +2246,7 @@ class Field extends XFAObject {
|
|||||||
"rotate",
|
"rotate",
|
||||||
"anchorType",
|
"anchorType",
|
||||||
"presence",
|
"presence",
|
||||||
"borderMarginPadding",
|
"margin",
|
||||||
"hAlign"
|
"hAlign"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2240,7 +2259,7 @@ class Field extends XFAObject {
|
|||||||
const attributes = {
|
const attributes = {
|
||||||
style,
|
style,
|
||||||
id: this[$uid],
|
id: this[$uid],
|
||||||
class: classNames.join(" "),
|
class: classNames,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.name) {
|
if (this.name) {
|
||||||
@ -2248,29 +2267,37 @@ class Field extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const children = [];
|
const children = [];
|
||||||
let html = {
|
const html = {
|
||||||
name: "div",
|
name: "div",
|
||||||
attributes,
|
attributes,
|
||||||
children,
|
children,
|
||||||
};
|
};
|
||||||
|
|
||||||
const bbox = computeBbox(this, html, availableSpace);
|
const borderStyle = this.border ? this.border[$toStyle]() : null;
|
||||||
html = addExtraDivForBorder(html);
|
|
||||||
|
|
||||||
|
const bbox = computeBbox(this, html, availableSpace);
|
||||||
const ui = this.ui ? this.ui[$toHTML]().html : null;
|
const ui = this.ui ? this.ui[$toHTML]().html : null;
|
||||||
if (!ui) {
|
if (!ui) {
|
||||||
return HTMLResult.success(html, bbox);
|
Object.assign(style, borderStyle);
|
||||||
|
return HTMLResult.success(createWrapper(this, html), bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ui.attributes.style) {
|
if (!ui.attributes.style) {
|
||||||
ui.attributes.style = Object.create(null);
|
ui.attributes.style = Object.create(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.ui.button) {
|
||||||
|
Object.assign(ui.attributes.style, borderStyle);
|
||||||
|
} else {
|
||||||
|
Object.assign(style, borderStyle);
|
||||||
|
}
|
||||||
|
|
||||||
children.push(ui);
|
children.push(ui);
|
||||||
|
|
||||||
if (this.value) {
|
if (this.value) {
|
||||||
if (this.ui.imageEdit) {
|
if (this.ui.imageEdit) {
|
||||||
ui.children.push(this.value[$toHTML]().html);
|
ui.children.push(this.value[$toHTML]().html);
|
||||||
} else if (ui.name !== "button") {
|
} else if (!this.ui.button) {
|
||||||
const value = this.value[$toHTML]().html;
|
const value = this.value[$toHTML]().html;
|
||||||
if (value) {
|
if (value) {
|
||||||
if (ui.children[0].name === "textarea") {
|
if (ui.children[0].name === "textarea") {
|
||||||
@ -2284,43 +2311,42 @@ class Field extends XFAObject {
|
|||||||
|
|
||||||
const caption = this.caption ? this.caption[$toHTML]().html : null;
|
const caption = this.caption ? this.caption[$toHTML]().html : null;
|
||||||
if (!caption) {
|
if (!caption) {
|
||||||
return HTMLResult.success(html, bbox);
|
return HTMLResult.success(createWrapper(this, html), bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui.name === "button") {
|
if (this.ui.button) {
|
||||||
ui.attributes.style.background = style.background;
|
|
||||||
delete style.background;
|
|
||||||
if (caption.name === "div") {
|
if (caption.name === "div") {
|
||||||
caption.name = "span";
|
caption.name = "span";
|
||||||
}
|
}
|
||||||
ui.children.push(caption);
|
ui.children.push(caption);
|
||||||
|
|
||||||
return HTMLResult.success(html, bbox);
|
return HTMLResult.success(html, bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ui.attributes.class) {
|
||||||
|
ui.attributes.class = [];
|
||||||
|
}
|
||||||
|
|
||||||
ui.children.splice(0, 0, caption);
|
ui.children.splice(0, 0, caption);
|
||||||
switch (this.caption.placement) {
|
switch (this.caption.placement) {
|
||||||
case "left":
|
case "left":
|
||||||
ui.attributes.style.flexDirection = "row";
|
ui.attributes.class.push("xfaLeft");
|
||||||
break;
|
break;
|
||||||
case "right":
|
case "right":
|
||||||
ui.attributes.style.flexDirection = "row-reverse";
|
ui.attributes.class.push("xfaRight");
|
||||||
break;
|
break;
|
||||||
case "top":
|
case "top":
|
||||||
ui.attributes.style.alignItems = "start";
|
ui.attributes.class.push("xfaTop");
|
||||||
ui.attributes.style.flexDirection = "column";
|
|
||||||
break;
|
break;
|
||||||
case "bottom":
|
case "bottom":
|
||||||
ui.attributes.style.alignItems = "start";
|
ui.attributes.class.push("xfaBottom");
|
||||||
ui.attributes.style.flexDirection = "column-reverse";
|
|
||||||
break;
|
break;
|
||||||
case "inline":
|
case "inline":
|
||||||
delete ui.attributes.class;
|
// TODO;
|
||||||
caption.attributes.style.float = "left";
|
ui.attributes.class.push("xfaInline");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTMLResult.success(html, bbox);
|
return HTMLResult.success(createWrapper(this, html), bbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2660,7 +2686,7 @@ class Image extends StringObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "img",
|
name: "img",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaImage",
|
class: ["xfaImage"],
|
||||||
style: {},
|
style: {},
|
||||||
src: URL.createObjectURL(blob),
|
src: URL.createObjectURL(blob),
|
||||||
},
|
},
|
||||||
@ -2987,7 +3013,7 @@ class NumericEdit extends XFAObject {
|
|||||||
attributes: {
|
attributes: {
|
||||||
type: "text",
|
type: "text",
|
||||||
fieldId: this[$getParent]()[$getParent]()[$uid],
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: ["xfaTextfield"],
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -2995,7 +3021,7 @@ class NumericEdit extends XFAObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "label",
|
name: "label",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaLabel",
|
class: ["xfaLabel"],
|
||||||
},
|
},
|
||||||
children: [html],
|
children: [html],
|
||||||
});
|
});
|
||||||
@ -3955,7 +3981,8 @@ class Subform extends XFAObject {
|
|||||||
"dimensions",
|
"dimensions",
|
||||||
"position",
|
"position",
|
||||||
"presence",
|
"presence",
|
||||||
"borderMarginPadding",
|
"border",
|
||||||
|
"margin",
|
||||||
"hAlign"
|
"hAlign"
|
||||||
);
|
);
|
||||||
const classNames = ["xfaSubform"];
|
const classNames = ["xfaSubform"];
|
||||||
@ -3965,7 +3992,7 @@ class Subform extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attributes.style = style;
|
attributes.style = style;
|
||||||
attributes.class = classNames.join(" ");
|
attributes.class = classNames;
|
||||||
|
|
||||||
if (this.name) {
|
if (this.name) {
|
||||||
attributes.xfaName = this.name;
|
attributes.xfaName = this.name;
|
||||||
@ -3997,6 +4024,9 @@ class Subform extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (failure) {
|
if (failure) {
|
||||||
|
if (this.layout === "position") {
|
||||||
|
delete this[$extra];
|
||||||
|
}
|
||||||
return HTMLResult.FAILURE;
|
return HTMLResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4014,13 +4044,12 @@ class Subform extends XFAObject {
|
|||||||
style.height = measureToString(this[$extra].height + marginV);
|
style.height = measureToString(this[$extra].height + marginV);
|
||||||
}
|
}
|
||||||
|
|
||||||
let html = {
|
const html = {
|
||||||
name: "div",
|
name: "div",
|
||||||
attributes,
|
attributes,
|
||||||
children,
|
children,
|
||||||
};
|
};
|
||||||
|
|
||||||
html = addExtraDivForBorder(html);
|
|
||||||
let bbox;
|
let bbox;
|
||||||
if (this.w !== "" && this.h !== "") {
|
if (this.w !== "" && this.h !== "") {
|
||||||
bbox = [this.x, this.y, this.w, this.h];
|
bbox = [this.x, this.y, this.w, this.h];
|
||||||
@ -4034,13 +4063,16 @@ class Subform extends XFAObject {
|
|||||||
if (this.breakAfter.children.length >= 1) {
|
if (this.breakAfter.children.length >= 1) {
|
||||||
const breakAfter = this.breakAfter.children[0];
|
const breakAfter = this.breakAfter.children[0];
|
||||||
getRoot(this)[$break](breakAfter);
|
getRoot(this)[$break](breakAfter);
|
||||||
this[$extra].afterBreakAfter = HTMLResult.success(html, bbox);
|
this[$extra].afterBreakAfter = HTMLResult.success(
|
||||||
|
createWrapper(this, html),
|
||||||
|
bbox
|
||||||
|
);
|
||||||
return HTMLResult.FAILURE;
|
return HTMLResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this[$extra];
|
delete this[$extra];
|
||||||
|
|
||||||
return HTMLResult.success(html, bbox);
|
return HTMLResult.success(createWrapper(this, html), bbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4296,8 +4328,8 @@ class Template extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const contentAreas = pageArea.contentArea.children;
|
const contentAreas = pageArea.contentArea.children;
|
||||||
const htmlContentAreas = page.children.filter(
|
const htmlContentAreas = page.children.filter(node =>
|
||||||
node => node.attributes.class === "xfaContentarea"
|
node.attributes.class.includes("xfaContentarea")
|
||||||
);
|
);
|
||||||
for (let i = 0, ii = contentAreas.length; i < ii; i++) {
|
for (let i = 0, ii = contentAreas.length; i < ii; i++) {
|
||||||
const contentArea = (this[$extra].currentContentArea = contentAreas[i]);
|
const contentArea = (this[$extra].currentContentArea = contentAreas[i]);
|
||||||
@ -4404,6 +4436,10 @@ class Text extends ContentObject {
|
|||||||
this.usehref = attributes.usehref || "";
|
this.usehref = attributes.usehref || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[$acceptWhitespace]() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
[$onChild](child) {
|
[$onChild](child) {
|
||||||
if (child[$namespaceId] === NamespaceIds.xhtml.id) {
|
if (child[$namespaceId] === NamespaceIds.xhtml.id) {
|
||||||
this[$content] = child;
|
this[$content] = child;
|
||||||
@ -4413,6 +4449,13 @@ class Text extends ContentObject {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[$onText](str) {
|
||||||
|
if (this[$content] instanceof XFAObject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super[$onText](str);
|
||||||
|
}
|
||||||
|
|
||||||
[$toHTML](availableSpace) {
|
[$toHTML](availableSpace) {
|
||||||
if (typeof this[$content] === "string") {
|
if (typeof this[$content] === "string") {
|
||||||
// \u2028 is a line separator.
|
// \u2028 is a line separator.
|
||||||
@ -4420,7 +4463,7 @@ class Text extends ContentObject {
|
|||||||
const html = {
|
const html = {
|
||||||
name: "span",
|
name: "span",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaRich",
|
class: ["xfaRich"],
|
||||||
style: {},
|
style: {},
|
||||||
},
|
},
|
||||||
value: this[$content],
|
value: this[$content],
|
||||||
@ -4521,7 +4564,7 @@ class TextEdit extends XFAObject {
|
|||||||
name: "textarea",
|
name: "textarea",
|
||||||
attributes: {
|
attributes: {
|
||||||
fieldId: this[$getParent]()[$getParent]()[$uid],
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: ["xfaTextfield"],
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -4531,7 +4574,7 @@ class TextEdit extends XFAObject {
|
|||||||
attributes: {
|
attributes: {
|
||||||
type: "text",
|
type: "text",
|
||||||
fieldId: this[$getParent]()[$getParent]()[$uid],
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: ["xfaTextfield"],
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -4540,7 +4583,7 @@ class TextEdit extends XFAObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "label",
|
name: "label",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaLabel",
|
class: ["xfaLabel"],
|
||||||
},
|
},
|
||||||
children: [html],
|
children: [html],
|
||||||
});
|
});
|
||||||
|
@ -80,9 +80,9 @@ const StyleMapping = new Map([
|
|||||||
],
|
],
|
||||||
["xfa-spacerun", ""],
|
["xfa-spacerun", ""],
|
||||||
["xfa-tab-stops", ""],
|
["xfa-tab-stops", ""],
|
||||||
["font-size", value => measureToString(1 * getMeasurement(value))],
|
["font-size", value => measureToString(getMeasurement(value))],
|
||||||
["letter-spacing", value => measureToString(getMeasurement(value))],
|
["letter-spacing", value => measureToString(getMeasurement(value))],
|
||||||
["line-height", value => measureToString(0.99 * getMeasurement(value))],
|
["line-height", value => measureToString(getMeasurement(value))],
|
||||||
["margin", value => measureToString(getMeasurement(value))],
|
["margin", value => measureToString(getMeasurement(value))],
|
||||||
["margin-bottom", value => measureToString(getMeasurement(value))],
|
["margin-bottom", value => measureToString(getMeasurement(value))],
|
||||||
["margin-left", value => measureToString(getMeasurement(value))],
|
["margin-left", value => measureToString(getMeasurement(value))],
|
||||||
@ -216,7 +216,7 @@ class Body extends XhtmlObject {
|
|||||||
return HTMLResult.EMPTY;
|
return HTMLResult.EMPTY;
|
||||||
}
|
}
|
||||||
html.name = "div";
|
html.name = "div";
|
||||||
html.attributes.class = "xfaRich";
|
html.attributes.class = ["xfaRich"];
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ class Html extends XhtmlObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "div",
|
name: "div",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaRich",
|
class: ["xfaRich"],
|
||||||
style: {},
|
style: {},
|
||||||
},
|
},
|
||||||
value: this[$content] || "",
|
value: this[$content] || "",
|
||||||
@ -262,7 +262,7 @@ class Html extends XhtmlObject {
|
|||||||
|
|
||||||
if (children.length === 1) {
|
if (children.length === 1) {
|
||||||
const child = children[0];
|
const child = children[0];
|
||||||
if (child.attributes && child.attributes.class === "xfaRich") {
|
if (child.attributes && child.attributes.class.includes("xfaRich")) {
|
||||||
return HTMLResult.success(child);
|
return HTMLResult.success(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ class Html extends XhtmlObject {
|
|||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
name: "div",
|
name: "div",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaRich",
|
class: ["xfaRich"],
|
||||||
style: {},
|
style: {},
|
||||||
},
|
},
|
||||||
children,
|
children,
|
||||||
|
@ -20,7 +20,9 @@ class XfaLayer {
|
|||||||
const storedData = storage.getValue(fieldId, { value: null });
|
const storedData = storage.getValue(fieldId, { value: null });
|
||||||
switch (element.name) {
|
switch (element.name) {
|
||||||
case "textarea":
|
case "textarea":
|
||||||
html.textContent = storedData.value !== null ? storedData.value : "";
|
if (storedData.value !== null) {
|
||||||
|
html.textContent = storedData.value;
|
||||||
|
}
|
||||||
if (intent === "print") {
|
if (intent === "print") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -103,6 +105,8 @@ class XfaLayer {
|
|||||||
if (key !== "style") {
|
if (key !== "style") {
|
||||||
if (key === "textContent") {
|
if (key === "textContent") {
|
||||||
html.textContent = value;
|
html.textContent = value;
|
||||||
|
} else if (key === "class") {
|
||||||
|
html.setAttribute(key, value.join(" "));
|
||||||
} else {
|
} else {
|
||||||
html.setAttribute(key, value);
|
html.setAttribute(key, value);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ describe("XFAFactory", function () {
|
|||||||
|
|
||||||
expect(page1.children.length).toEqual(2);
|
expect(page1.children.length).toEqual(2);
|
||||||
const container = page1.children[0];
|
const container = page1.children[0];
|
||||||
expect(container.attributes.class).toEqual("xfaContentarea");
|
expect(container.attributes.class).toEqual(["xfaContentarea"]);
|
||||||
expect(container.attributes.style).toEqual({
|
expect(container.attributes.style).toEqual({
|
||||||
height: "789px",
|
height: "789px",
|
||||||
width: "456px",
|
width: "456px",
|
||||||
@ -78,24 +78,29 @@ describe("XFAFactory", function () {
|
|||||||
const wrapper = page1.children[1];
|
const wrapper = page1.children[1];
|
||||||
const draw = wrapper.children[0];
|
const draw = wrapper.children[0];
|
||||||
|
|
||||||
expect(wrapper.attributes.class).toEqual("xfaWrapper");
|
expect(wrapper.attributes.class).toEqual(["xfaWrapper"]);
|
||||||
expect(wrapper.attributes.style).toEqual({
|
expect(wrapper.attributes.style).toEqual({
|
||||||
|
alignSelf: "start",
|
||||||
|
height: "22px",
|
||||||
left: "2px",
|
left: "2px",
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "1px",
|
top: "1px",
|
||||||
|
transform: "rotate(-90deg)",
|
||||||
|
transformOrigin: "top left",
|
||||||
|
width: "11px",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(draw.attributes.class).toEqual("xfaDraw xfaFont");
|
expect(draw.attributes.class).toEqual([
|
||||||
|
"xfaDraw",
|
||||||
|
"xfaFont",
|
||||||
|
"xfaWrapped",
|
||||||
|
]);
|
||||||
expect(draw.attributes.style).toEqual({
|
expect(draw.attributes.style).toEqual({
|
||||||
color: "#0c1722",
|
color: "#0c1722",
|
||||||
fontFamily: "FooBar",
|
fontFamily: "FooBar",
|
||||||
fontSize: "6.93px",
|
fontSize: "6.93px",
|
||||||
height: "22px",
|
margin: "1px 4px 2px 3px",
|
||||||
padding: "1px 4px 2px 3px",
|
|
||||||
transform: "rotate(-90deg)",
|
|
||||||
transformOrigin: "top left",
|
|
||||||
verticalAlign: "2px",
|
verticalAlign: "2px",
|
||||||
width: "11px",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// draw element must be on each page.
|
// draw element must be on each page.
|
||||||
|
@ -35,6 +35,11 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaLayer div {
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaLayer a {
|
.xfaLayer a {
|
||||||
@ -45,6 +50,10 @@
|
|||||||
margin-left: 3em;
|
margin-left: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.xfaLayer p {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
.xfaFont {
|
.xfaFont {
|
||||||
color: black;
|
color: black;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
@ -70,38 +79,79 @@
|
|||||||
|
|
||||||
.xfaRich {
|
.xfaRich {
|
||||||
z-index: 300;
|
z-index: 300;
|
||||||
line-height: 1.2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaSubform {
|
.xfaSubform {
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.xfaCaption {
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.xfaLabel {
|
.xfaLabel {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaLeft {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaCaption {
|
.xfaLeft > .xfaCaption {
|
||||||
flex: 1 1 auto;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaBorderDiv {
|
.xfaRight {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaRight > .xfaCaption {
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaTop {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaTop > .xfaCaption {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaBottom {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaBottom > .xfaCaption {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaInline {
|
||||||
|
float: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaBorder {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaWrapper {
|
.xfaWrapper {
|
||||||
position: relative;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: stretch;
|
||||||
justify-content: center;
|
}
|
||||||
width: auto;
|
|
||||||
height: auto;
|
.xfaWrapped {
|
||||||
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaContentArea {
|
.xfaContentArea {
|
||||||
@ -122,7 +172,7 @@
|
|||||||
.xfaSelect {
|
.xfaSelect {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex: 100 1 0;
|
flex: 1 1 0;
|
||||||
border: none;
|
border: none;
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
@ -160,10 +210,6 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaPosition {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.xfaLrTb,
|
.xfaLrTb,
|
||||||
.xfaRlTb,
|
.xfaRlTb,
|
||||||
.xfaTb {
|
.xfaTb {
|
||||||
@ -178,18 +224,28 @@
|
|||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaTb > div {
|
.xfaLr {
|
||||||
justify-content: left;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaLr > div {
|
.xfaLr > div {
|
||||||
display: inline;
|
flex: 1 1 auto;
|
||||||
float: left;
|
}
|
||||||
|
|
||||||
|
.xfaRl {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaRl > div {
|
.xfaRl > div {
|
||||||
display: inline;
|
flex: 1 1 auto;
|
||||||
float: right;
|
}
|
||||||
|
|
||||||
|
.xfaTb > div {
|
||||||
|
justify-content: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaPosition {
|
.xfaPosition {
|
||||||
@ -205,25 +261,20 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaLrTb > div {
|
|
||||||
display: inline;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.xfaRlTb > div {
|
|
||||||
display: inline;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.xfaTable {
|
.xfaTable {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaTable > div {
|
||||||
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaTable .xfaRow {
|
.xfaTable .xfaRow {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex: 1 1 auto;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaTable .xfaRow > div {
|
.xfaTable .xfaRow > div {
|
||||||
@ -233,6 +284,7 @@
|
|||||||
.xfaTable .xfaRlRow {
|
.xfaTable .xfaRlRow {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
align-items: stretch;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user