XFA - Remove empty pages

- it aims to fix #13583;
  - fix the switch to breakBefore target;
  - force the layout of an unsplittable element on an empty page;
  - don't fail when there is horizontal overflow (except in lr-tb);
  - handle correctly overflow in the same content area (bug 1717805, bug 1717668);
  - fix a typo in radial gradient first argument.
This commit is contained in:
Calixte Denizet 2021-06-21 09:38:50 +02:00
parent f35e4cc9ab
commit ff440d13e7
12 changed files with 329 additions and 113 deletions

View File

@ -257,70 +257,91 @@ function getTransformedBBox(node) {
* in case of lr-tb or changing content area...). * in case of lr-tb or changing content area...).
*/ */
function checkDimensions(node, space) { function checkDimensions(node, space) {
if (node[$getTemplateRoot]()[$extra].firstUnsplittable === null) {
return true;
}
if (node.w === 0 || node.h === 0) { if (node.w === 0 || node.h === 0) {
return true; return true;
} }
if (space.width <= 0 || space.height <= 0) {
return false;
}
const parent = node[$getParent](); const parent = node[$getParent]();
const attempt = (node[$extra] && node[$extra].attempt) || 0; const attempt = (parent[$extra] && parent[$extra].attempt) || 0;
let y, w, h;
switch (parent.layout) { switch (parent.layout) {
case "lr-tb": case "lr-tb":
case "rl-tb": case "rl-tb":
switch (attempt) {
case 0: {
let w, h;
if (node.w !== "" || node.h !== "") { if (node.w !== "" || node.h !== "") {
[, , w, h] = getTransformedBBox(node); [, , w, h] = getTransformedBBox(node);
} }
if (attempt === 0) {
// Try to put an element in the line.
if (!node[$getTemplateRoot]()[$extra].noLayoutFailure) {
if (node.h !== "" && Math.round(h - space.height) > 1) { if (node.h !== "" && Math.round(h - space.height) > 1) {
// Not enough height.
return false; return false;
} }
if (node.w !== "") {
// True if width is enough.
return Math.round(w - space.width) <= 1;
}
return space.width > 0;
}
// No layout failure.
// Put the element on the line but we can fail
// and then in the second step (next line) we'll accept.
if (node.w !== "") { if (node.w !== "") {
return Math.round(w - space.width) <= 1; return Math.round(w - space.width) <= 1;
} }
return node.minW <= space.width; return space.width > 0;
}
case 1: {
if (node.h !== "" && !node[$isSplittable]()) {
const [, , , h] = getTransformedBBox(node);
if (Math.round(h - space.height) > 1) {
return false;
}
} }
// Second attempt: try to put the element on the next line.
if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
// We cannot fail.
return true; return true;
} }
default:
return true; if (node.h !== "") {
// True if height is enough.
return Math.round(h - space.height) <= 1;
} }
return space.height > 0;
case "table": case "table":
case "tb": case "tb":
if (attempt !== 1 && node.h !== "" && !node[$isSplittable]()) { if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
const [, , , h] = getTransformedBBox(node);
if (Math.round(h - space.height) > 1) {
return false;
}
}
return true; return true;
case "position": }
const [x, y, w, h] = getTransformedBBox(node);
const isWidthOk = node.w === "" || Math.round(w + x - space.width) <= 1;
const isHeightOk = node.h === "" || Math.round(h + y - space.height) <= 1;
if (isWidthOk && isHeightOk) { // If the node has a height then check
// if it's fine with available height. If the node
// is breakable then we can return true.
if (node.h !== "" && !node[$isSplittable]()) {
[, , , h] = getTransformedBBox(node);
return Math.round(h - space.height) <= 1;
}
// Else wait and see: this node will be layed out itself
// in the provided space and maybe a children won't fit.
return space.height > 0;
case "position":
if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
return true;
}
[, y, , h] = getTransformedBBox(node);
if (node.h === "" || Math.round(h + y - space.height) <= 1) {
return true; return true;
} }
const area = node[$getTemplateRoot]()[$extra].currentContentArea; const area = node[$getTemplateRoot]()[$extra].currentContentArea;
if (isWidthOk) {
return h + y > area.h; return h + y > area.h;
}
return w + x > area.w;
case "rl-row": case "rl-row":
case "row": case "row":
default: default:

View File

@ -28,6 +28,7 @@ import {
$getAvailableSpace, $getAvailableSpace,
$getChildren, $getChildren,
$getContainedChildren, $getContainedChildren,
$getExtra,
$getNextPage, $getNextPage,
$getParent, $getParent,
$getSubformParent, $getSubformParent,
@ -141,6 +142,84 @@ function valueToHtml(value) {
}); });
} }
function setFirstUnsplittable(node) {
const root = node[$getTemplateRoot]();
if (root[$extra].firstUnsplittable === null) {
root[$extra].firstUnsplittable = node;
root[$extra].noLayoutFailure = true;
}
}
function unsetFirstUnsplittable(node) {
const root = node[$getTemplateRoot]();
if (root[$extra].firstUnsplittable === node) {
root[$extra].noLayoutFailure = false;
}
}
function handleBreak(node) {
if (node[$extra]) {
return false;
}
node[$extra] = Object.create(null);
if (node.targetType === "auto") {
return false;
}
const root = node[$getTemplateRoot]();
let target = null;
if (node.target) {
target = root[$searchNode](node.target, node[$getParent]());
target = target ? target[0] : target;
}
const { currentPageArea, currentContentArea } = root[$extra];
if (node.targetType === "pageArea") {
if (!(target instanceof PageArea)) {
target = null;
}
if (node.startNew) {
node[$extra].target = target || currentPageArea;
return true;
} else if (target && target !== currentPageArea) {
node[$extra].target = target;
return true;
}
return false;
}
if (!(target instanceof ContentArea)) {
target = null;
}
const pageArea = target[$getParent]();
const contentAreas = pageArea.contentArea.children;
let index;
if (node.startNew) {
if (target) {
index = contentAreas.findIndex(e => e === target) - 1;
} else {
index = currentPageArea.contentArea.children.findIndex(
e => e === currentContentArea
);
}
} else if (target && target !== currentContentArea) {
index = contentAreas.findIndex(e => e === target) - 1;
} else {
return false;
}
node[$extra].target = pageArea === currentPageArea ? null : pageArea;
node[$extra].index = index;
return true;
}
class AppearanceFilter extends StringObject { class AppearanceFilter extends StringObject {
constructor(attributes) { constructor(attributes) {
super(TEMPLATE_NS_ID, "appearanceFilter"); super(TEMPLATE_NS_ID, "appearanceFilter");
@ -718,8 +797,6 @@ class BreakAfter extends XFAObject {
"auto", "auto",
"contentArea", "contentArea",
"pageArea", "pageArea",
"pageEven",
"pageOdd",
]); ]);
this.trailer = attributes.trailer || ""; this.trailer = attributes.trailer || "";
this.use = attributes.use || ""; this.use = attributes.use || "";
@ -743,8 +820,6 @@ class BreakBefore extends XFAObject {
"auto", "auto",
"contentArea", "contentArea",
"pageArea", "pageArea",
"pageEven",
"pageOdd",
]); ]);
this.trailer = attributes.trailer || ""; this.trailer = attributes.trailer || "";
this.use = attributes.use || ""; this.use = attributes.use || "";
@ -1176,7 +1251,6 @@ class ContentArea extends XFAObject {
const top = measureToString(this.y); const top = measureToString(this.y);
const style = { const style = {
position: "absolute",
left, left,
top, top,
width: measureToString(this.w), width: measureToString(this.w),
@ -1550,9 +1624,11 @@ class Draw extends XFAObject {
} }
} }
setFirstUnsplittable(this);
if (!checkDimensions(this, availableSpace)) { if (!checkDimensions(this, availableSpace)) {
return HTMLResult.FAILURE; return HTMLResult.FAILURE;
} }
unsetFirstUnsplittable(this);
const style = toStyle( const style = toStyle(
this, this,
@ -2038,21 +2114,32 @@ class ExclGroup extends XFAObject {
[$isSplittable]() { [$isSplittable]() {
// We cannot cache the result here because the contentArea // We cannot cache the result here because the contentArea
// can change. // can change.
if (!this[$getParent]()[$isSplittable]()) {
return false;
}
const root = this[$getTemplateRoot](); const root = this[$getTemplateRoot]();
const contentArea = root[$extra].currentContentArea; const contentArea = root[$extra].currentContentArea;
if (contentArea && Math.max(this.minH, this.h || 0) >= contentArea.h) { if (contentArea && Math.max(this.minH, this.h || 0) >= contentArea.h) {
return true; return true;
} }
if (this[$extra]._isSplittable !== undefined) {
return this[$extra]._isSplittable;
}
if (this.layout === "position") { if (this.layout === "position") {
this[$extra]._isSplittable = false;
return false; return false;
} }
const parentLayout = this[$getParent]().layout; const parentLayout = this[$getParent]().layout;
if (parentLayout && parentLayout.includes("row")) { if (parentLayout && parentLayout.includes("row")) {
this[$extra]._isSplittable = false;
return false; return false;
} }
this[$extra]._isSplittable = true;
return true; return true;
} }
@ -2103,6 +2190,11 @@ class ExclGroup extends XFAObject {
currentWidth: 0, currentWidth: 0,
}); });
const isSplittable = this[$isSplittable]();
if (!isSplittable) {
setFirstUnsplittable(this);
}
if (!checkDimensions(this, availableSpace)) { if (!checkDimensions(this, availableSpace)) {
return HTMLResult.FAILURE; return HTMLResult.FAILURE;
} }
@ -2180,6 +2272,10 @@ class ExclGroup extends XFAObject {
} }
} }
if (!isSplittable) {
unsetFirstUnsplittable(this);
}
if (failure) { if (failure) {
if (this[$isSplittable]()) { if (this[$isSplittable]()) {
delete this[$extra]; delete this[$extra];
@ -2366,9 +2462,11 @@ class Field extends XFAObject {
fixDimensions(this); fixDimensions(this);
setFirstUnsplittable(this);
if (!checkDimensions(this, availableSpace)) { if (!checkDimensions(this, availableSpace)) {
return HTMLResult.FAILURE; return HTMLResult.FAILURE;
} }
unsetFirstUnsplittable(this);
const style = toStyle( const style = toStyle(
this, this,
@ -3320,6 +3418,18 @@ class Overflow extends XFAObject {
this.use = attributes.use || ""; this.use = attributes.use || "";
this.usehref = attributes.usehref || ""; this.usehref = attributes.usehref || "";
} }
[$getExtra]() {
if (!this[$extra]) {
const parent = this[$getParent]();
const root = this[$getTemplateRoot]();
const target = root[$searchNode](this.target, parent);
this[$extra] = {
target: (target && target[0]) || null,
};
}
return this[$extra];
}
} }
class PageArea extends XFAObject { class PageArea extends XFAObject {
@ -3457,8 +3567,10 @@ class PageArea extends XFAObject {
name: "div", name: "div",
children, children,
attributes: { attributes: {
class: ["xfaPage"],
id: this[$uid], id: this[$uid],
style, style,
xfaName: this.name,
}, },
}); });
} }
@ -3875,7 +3987,7 @@ class Radial extends XFAObject {
this.type === "toEdge" this.type === "toEdge"
? `${startColor},${endColor}` ? `${startColor},${endColor}`
: `${endColor},${startColor}`; : `${endColor},${startColor}`;
return `radial-gradient(circle to center, ${colors})`; return `radial-gradient(circle at center, ${colors})`;
} }
} }
@ -4235,32 +4347,44 @@ class Subform extends XFAObject {
return getAvailableSpace(this); return getAvailableSpace(this);
} }
[$isSplittable](x) { [$isSplittable]() {
// We cannot cache the result here because the contentArea // We cannot cache the result here because the contentArea
// can change. // can change.
if (!this[$getParent]()[$isSplittable]()) {
return false;
}
const root = this[$getTemplateRoot](); const root = this[$getTemplateRoot]();
const contentArea = root[$extra].currentContentArea; const contentArea = root[$extra].currentContentArea;
if (contentArea && Math.max(this.minH, this.h || 0) >= contentArea.h) { if (contentArea && Math.max(this.minH, this.h || 0) >= contentArea.h) {
return true; return true;
} }
if (this.overflow) {
return this.overflow[$getExtra]().target !== contentArea;
}
if (this[$extra]._isSplittable !== undefined) {
return this[$extra]._isSplittable;
}
if (this.layout === "position") { if (this.layout === "position") {
this[$extra]._isSplittable = false;
return false; return false;
} }
if (this.keep && this.keep.intact !== "none") { if (this.keep && this.keep.intact !== "none") {
this[$extra]._isSplittable = false;
return false; return false;
} }
const parentLayout = this[$getParent]().layout; const parentLayout = this[$getParent]().layout;
if (parentLayout && parentLayout.includes("row")) { if (parentLayout && parentLayout.includes("row")) {
this[$extra]._isSplittable = false;
return false; return false;
} }
if (this.overflow && this.overflow.target) { this[$extra]._isSplittable = true;
const target = root[$searchNode](this.overflow.target, this);
return target && target[0] === contentArea;
}
return true; return true;
} }
@ -4323,9 +4447,7 @@ class Subform extends XFAObject {
if (this.breakBefore.children.length >= 1) { if (this.breakBefore.children.length >= 1) {
const breakBefore = this.breakBefore.children[0]; const breakBefore = this.breakBefore.children[0];
if (!breakBefore[$extra]) { if (handleBreak(breakBefore)) {
// Set $extra to true to consume it.
breakBefore[$extra] = true;
return HTMLResult.breakNode(breakBefore); return HTMLResult.breakNode(breakBefore);
} }
} }
@ -4359,6 +4481,24 @@ class Subform extends XFAObject {
currentWidth: 0, currentWidth: 0,
}); });
const root = this[$getTemplateRoot]();
const currentContentArea = root[$extra].currentContentArea;
const savedNoLayoutFailure = root[$extra].noLayoutFailure;
if (this.overflow) {
// In case of overflow in the current content area,
// elements must be kept in this subform so it implies
// to have no errors on layout failures.
root[$extra].noLayoutFailure =
root[$extra].noLayoutFailure ||
this.overflow[$getExtra]().target === currentContentArea;
}
const isSplittable = this[$isSplittable]();
if (!isSplittable) {
setFirstUnsplittable(this);
}
if (!checkDimensions(this, availableSpace)) { if (!checkDimensions(this, availableSpace)) {
return HTMLResult.FAILURE; return HTMLResult.FAILURE;
} }
@ -4403,16 +4543,10 @@ class Subform extends XFAObject {
attributes.xfaName = this.name; attributes.xfaName = this.name;
} }
const isSplittable = this[$isSplittable](); const maxRun =
// If the container overflows into itself we add an extra
// layout step to accept finally the element which caused
// the overflow.
let maxRun =
this.layout === "lr-tb" || this.layout === "rl-tb" this.layout === "lr-tb" || this.layout === "rl-tb"
? MAX_ATTEMPTS_FOR_LRTB_LAYOUT ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT
: 1; : 1;
maxRun += !isSplittable && this.layout !== "position" ? 1 : 0;
for (; this[$extra].attempt < maxRun; this[$extra].attempt++) { for (; this[$extra].attempt < maxRun; this[$extra].attempt++) {
const result = this[$childrenToHTML]({ const result = this[$childrenToHTML]({
filter, filter,
@ -4426,6 +4560,11 @@ class Subform extends XFAObject {
} }
} }
if (!isSplittable) {
unsetFirstUnsplittable(this);
}
root[$extra].noLayoutFailure = savedNoLayoutFailure;
if (this[$extra].attempt === maxRun) { if (this[$extra].attempt === maxRun) {
if (this.overflow) { if (this.overflow) {
this[$getTemplateRoot]()[$extra].overflowNode = this.overflow; this[$getTemplateRoot]()[$extra].overflowNode = this.overflow;
@ -4467,9 +4606,11 @@ 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];
if (handleBreak(breakAfter)) {
this[$extra].afterBreakAfter = result; this[$extra].afterBreakAfter = result;
return HTMLResult.breakNode(breakAfter); return HTMLResult.breakNode(breakAfter);
} }
}
delete this[$extra]; delete this[$extra];
@ -4623,6 +4764,10 @@ class Template extends XFAObject {
} }
} }
[$isSplittable]() {
return true;
}
[$searchNode](expr, container) { [$searchNode](expr, container) {
if (expr.startsWith("#")) { if (expr.startsWith("#")) {
// This is an id. // This is an id.
@ -4640,6 +4785,10 @@ class Template extends XFAObject {
} }
this[$extra] = { this[$extra] = {
overflowNode: null, overflowNode: null,
firstUnsplittable: null,
currentContentArea: null,
currentPageArea: null,
noLayoutFailure: false,
pageNumber: 1, pageNumber: 1,
pagePosition: "first", pagePosition: "first",
oddOrEven: "odd", oddOrEven: "odd",
@ -4711,9 +4860,11 @@ class Template extends XFAObject {
let trailer = null; let trailer = null;
let hasSomething = true; let hasSomething = true;
let hasSomethingCounter = 0; let hasSomethingCounter = 0;
let startIndex = 0;
while (true) { while (true) {
if (!hasSomething) { if (!hasSomething) {
mainHtml.children.pop();
// Nothing has been added in the previous page // Nothing has been added in the previous page
if (++hasSomethingCounter === MAX_EMPTY_PAGES) { if (++hasSomethingCounter === MAX_EMPTY_PAGES) {
warn("XFA - Something goes wrong: please file a bug."); warn("XFA - Something goes wrong: please file a bug.");
@ -4724,15 +4875,18 @@ class Template extends XFAObject {
} }
targetPageArea = null; targetPageArea = null;
this[$extra].currentPageArea = pageArea;
const page = pageArea[$toHTML]().html; const page = pageArea[$toHTML]().html;
mainHtml.children.push(page); mainHtml.children.push(page);
if (leader) { if (leader) {
this[$extra].noLayoutFailure = true;
page.children.push(leader[$toHTML](pageArea[$extra].space).html); page.children.push(leader[$toHTML](pageArea[$extra].space).html);
leader = null; leader = null;
} }
if (trailer) { if (trailer) {
this[$extra].noLayoutFailure = true;
page.children.push(trailer[$toHTML](pageArea[$extra].space).html); page.children.push(trailer[$toHTML](pageArea[$extra].space).html);
trailer = null; trailer = null;
} }
@ -4743,6 +4897,8 @@ class Template extends XFAObject {
); );
hasSomething = false; hasSomething = false;
this[$extra].firstUnsplittable = null;
this[$extra].noLayoutFailure = false;
const flush = index => { const flush = index => {
const html = root[$flushHTML](); const html = root[$flushHTML]();
@ -4753,9 +4909,10 @@ class Template extends XFAObject {
} }
}; };
for (let i = 0, ii = contentAreas.length; i < ii; i++) { for (let i = startIndex, ii = contentAreas.length; i < ii; i++) {
const contentArea = (this[$extra].currentContentArea = contentAreas[i]); const contentArea = (this[$extra].currentContentArea = contentAreas[i]);
const space = { width: contentArea.w, height: contentArea.h }; const space = { width: contentArea.w, height: contentArea.h };
startIndex = 0;
if (leader) { if (leader) {
htmlContentAreas[i].children.push(leader[$toHTML](space).html); htmlContentAreas[i].children.push(leader[$toHTML](space).html);
@ -4782,14 +4939,12 @@ class Template extends XFAObject {
if (html.isBreak()) { if (html.isBreak()) {
const node = html.breakNode; const node = html.breakNode;
flush(i);
if (node.targetType === "auto") { if (node.targetType === "auto") {
flush(i);
continue; continue;
} }
const startNew = node.startNew === 1;
if (node.leader) { if (node.leader) {
leader = this[$searchNode](node.leader, node[$getParent]()); leader = this[$searchNode](node.leader, node[$getParent]());
leader = leader ? leader[0] : null; leader = leader ? leader[0] : null;
@ -4800,41 +4955,18 @@ class Template extends XFAObject {
trailer = trailer ? trailer[0] : null; trailer = trailer ? trailer[0] : null;
} }
let target = null;
if (node.target) {
target = this[$searchNode](node.target, node[$getParent]());
target = target ? target[0] : target;
}
if (node.targetType === "pageArea") { if (node.targetType === "pageArea") {
if (!(target instanceof PageArea)) { targetPageArea = node[$extra].target;
target = null; i = Infinity;
} else if (!node[$extra].target) {
// We stay on the same page.
i = node[$extra].index;
} else {
targetPageArea = node[$extra].target;
startIndex = node[$extra].index + 1;
i = Infinity;
} }
if (startNew) {
targetPageArea = target || pageArea;
flush(i);
i = Infinity;
} else if (target && target !== pageArea) {
targetPageArea = target;
flush(i);
i = Infinity;
} else {
i--;
}
} else if (node.targetType === "contentArea") {
if (!(target instanceof ContentArea)) {
target = null;
}
const index = contentAreas.findIndex(e => e === target);
if (index !== -1) {
flush(i);
i = index - 1;
} else {
i--;
}
}
continue; continue;
} }
@ -4860,17 +4992,20 @@ class Template extends XFAObject {
target = target ? target[0] : target; target = target ? target[0] : target;
} }
i = Infinity;
if (target instanceof PageArea) { if (target instanceof PageArea) {
// We must stop the contentAreas filling and go to the next page. // We must stop the contentAreas filling and go to the next page.
targetPageArea = target; targetPageArea = target;
i = Infinity;
continue;
} else if (target instanceof ContentArea) { } else if (target instanceof ContentArea) {
const index = contentAreas.findIndex(e => e === target); const index = contentAreas.findIndex(e => e === target);
if (index !== -1) { if (index !== -1) {
i = index - 1; i = index - 1;
} else { } else {
i--; targetPageArea = target[$getParent]();
startIndex =
targetPageArea.contentArea.children.findIndex(
e => e === target
) - 1;
} }
} }
continue; continue;

View File

@ -43,6 +43,7 @@ const $getChildrenByClass = Symbol();
const $getChildrenByName = Symbol(); const $getChildrenByName = Symbol();
const $getChildrenByNameIt = Symbol(); const $getChildrenByNameIt = Symbol();
const $getDataValue = Symbol(); const $getDataValue = Symbol();
const $getExtra = Symbol();
const $getRealChildrenByNameIt = Symbol(); const $getRealChildrenByNameIt = Symbol();
const $getChildren = Symbol(); const $getChildren = Symbol();
const $getContainedChildren = Symbol(); const $getContainedChildren = Symbol();
@ -177,11 +178,7 @@ class XFAObject {
} }
[$getTemplateRoot]() { [$getTemplateRoot]() {
let parent = this[$getParent](); return this[$globalData].template;
while (parent[$nodeName] !== "template") {
parent = parent[$getParent]();
}
return parent;
} }
[$isSplittable]() { [$isSplittable]() {
@ -1060,6 +1057,7 @@ export {
$getChildrenByNameIt, $getChildrenByNameIt,
$getContainedChildren, $getContainedChildren,
$getDataValue, $getDataValue,
$getExtra,
$getNextPage, $getNextPage,
$getParent, $getParent,
$getRealChildrenByNameIt, $getRealChildrenByNameIt,

View File

@ -0,0 +1 @@
https://bugzilla.mozilla.org/attachment.cgi?id=9228387

View File

@ -0,0 +1 @@
https://bugzilla.mozilla.org/attachment.cgi?id=9228727

View File

@ -0,0 +1 @@
https://bugzilla.mozilla.org/attachment.cgi?id=9228728

View File

@ -0,0 +1 @@
https://bugzilla.mozilla.org/attachment.cgi?id=9228507

View File

@ -0,0 +1 @@
https://web.archive.org/web/20210621073147/https://www.dhl.com/content/dam/downloads/g0/express/emailship_page/globalpage/dhl_emailship_pdfclient_my_en.pdf

View File

@ -0,0 +1 @@
https://github.com/mozilla/pdf.js/files/6695365/2229E.pdf

View File

@ -946,6 +946,38 @@
"enableXfa": true, "enableXfa": true,
"type": "eq" "type": "eq"
}, },
{ "id": "xfa_bug1717805",
"file": "pdfs/xfa_bug1717805.pdf",
"md5": "c68ccebd0d92b8fd70c465660458507f",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_bug17176688_1",
"file": "pdfs/xfa_bug1717668_1.pdf",
"md5": "564ecff67be690b43c2a144ae5967034",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_bug17176688_2",
"file": "pdfs/xfa_bug1717668_2.pdf",
"md5": "08aa8bf9fec5aa7b8ff13d9ba72ca8ac",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_bug17176688_3",
"file": "pdfs/xfa_bug1717668_3.pdf",
"md5": "4ff2531dbefebabc3f128d4ae20552a4",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_bug1718037", { "id": "xfa_bug1718037",
"file": "pdfs/xfa_bug1718037.pdf", "file": "pdfs/xfa_bug1718037.pdf",
"md5": "a0b53d50e9faed9d57950a5159d5da12", "md5": "a0b53d50e9faed9d57950a5159d5da12",
@ -970,6 +1002,14 @@
"enableXfa": true, "enableXfa": true,
"type": "eq" "type": "eq"
}, },
{ "id": "xfa_dhl_shipment",
"file": "pdfs/xfa_dhl_shipment.pdf",
"md5": "503ece429d69e7d626d6932a475fbe63",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_bug1716047", { "id": "xfa_bug1716047",
"file": "pdfs/xfa_bug1716047.pdf", "file": "pdfs/xfa_bug1716047.pdf",
"md5": "2f524163bd8397f43d195090978c3b56", "md5": "2f524163bd8397f43d195090978c3b56",
@ -1050,6 +1090,14 @@
"enableXfa": true, "enableXfa": true,
"type": "eq" "type": "eq"
}, },
{ "id": "xfa_issue13611",
"file": "pdfs/xfa_issue13611.pdf",
"md5": "e713fb46a6b4637660010f1850559ff6",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_issue13634", { "id": "xfa_issue13634",
"file": "pdfs/xfa_issue13634.pdf", "file": "pdfs/xfa_issue13634.pdf",
"md5": "459a04045470811cbab6671772929d3d", "md5": "459a04045470811cbab6671772929d3d",

View File

@ -56,14 +56,18 @@ describe("XFAFactory", function () {
</draw> </draw>
</pageArea> </pageArea>
</pageSet> </pageSet>
<subform name="first">
</subform>
<subform name="second"> <subform name="second">
<breakBefore targetType="pageArea" startNew="1"/> <breakBefore targetType="pageArea" startNew="1"/>
<subform> <subform>
<draw w="1pt" h="1pt"><value><text>foo</text></value></draw> <draw w="1pt" h="1pt"><value><text>foo</text></value></draw>
</subform> </subform>
</subform> </subform>
<subform name="third">
<breakBefore targetType="pageArea" startNew="1"/>
<subform>
<draw w="1pt" h="1pt"><value><text>bar</text></value></draw>
</subform>
</subform>
</subform> </subform>
</template> </template>
<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/"> <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
@ -92,7 +96,6 @@ describe("XFAFactory", function () {
width: "456px", width: "456px",
left: "123px", left: "123px",
top: "0px", top: "0px",
position: "absolute",
}); });
const wrapper = page1.children[0]; const wrapper = page1.children[0];

View File

@ -13,6 +13,15 @@
* limitations under the License. * limitations under the License.
*/ */
.xfaPage {
overflow: hidden;
position: relative;
}
.xfaContentarea {
position: absolute;
}
.xfaPrintOnly { .xfaPrintOnly {
display: none; display: none;
} }
@ -139,10 +148,6 @@
flex: 1 1 auto; flex: 1 1 auto;
} }
.xfaContentArea {
overflow: hidden;
}
.xfaTextfield, .xfaTextfield,
.xfaSelect { .xfaSelect {
background-color: rgba(0, 54, 255, 0.13); background-color: rgba(0, 54, 255, 0.13);