diff --git a/src/core/xfa/html_utils.js b/src/core/xfa/html_utils.js
index c089202b8..708e1e344 100644
--- a/src/core/xfa/html_utils.js
+++ b/src/core/xfa/html_utils.js
@@ -41,7 +41,7 @@ function measureToString(m) {
const converters = {
anchorType(node, style) {
- const parent = node[$getParent]();
+ const parent = node[$getSubformParent]();
if (!parent || (parent.layout && parent.layout !== "position")) {
// anchorType is only used in a positioned layout.
return;
@@ -78,7 +78,7 @@ const converters = {
}
},
dimensions(node, style) {
- const parent = node[$getParent]();
+ const parent = node[$getSubformParent]();
let width = node.w;
const height = node.h;
if (parent.layout && parent.layout.includes("row")) {
@@ -116,7 +116,7 @@ const converters = {
}
},
position(node, style) {
- const parent = node[$getParent]();
+ const parent = node[$getSubformParent]();
if (parent && parent.layout && parent.layout !== "position") {
// IRL, we've some x/y in tb layout.
// Specs say x/y is only used in positioned layout.
@@ -182,14 +182,18 @@ const converters = {
};
function setMinMaxDimensions(node, style) {
- const parent = node[$getParent]();
+ const parent = node[$getSubformParent]();
if (parent.layout === "position") {
- style.minWidth = measureToString(node.minW);
- if (node.maxW) {
+ if (node.minW > 0) {
+ style.minWidth = measureToString(node.minW);
+ }
+ if (node.maxW > 0) {
style.maxWidth = measureToString(node.maxW);
}
- style.minHeight = measureToString(node.minH);
- if (node.maxH) {
+ if (node.minH > 0) {
+ style.minHeight = measureToString(node.minH);
+ }
+ if (node.maxH > 0) {
style.maxHeight = measureToString(node.maxH);
}
}
@@ -297,7 +301,7 @@ function computeBbox(node, html, availableSpace) {
let width = node.w;
if (width === "") {
if (node.maxW === 0) {
- const parent = node[$getParent]();
+ const parent = node[$getSubformParent]();
if (parent.layout === "position" && parent.w !== "") {
width = 0;
} else {
@@ -312,7 +316,7 @@ function computeBbox(node, html, availableSpace) {
let height = node.h;
if (height === "") {
if (node.maxH === 0) {
- const parent = node[$getParent]();
+ const parent = node[$getSubformParent]();
if (parent.layout === "position" && parent.h !== "") {
height = 0;
} else {
@@ -349,25 +353,9 @@ function fixDimensions(node) {
}
}
- if (parent.w && node.w) {
- node.w = Math.min(parent.w, node.w);
- }
-
- if (parent.h && node.h) {
- node.h = Math.min(parent.h, node.h);
- }
-
if (parent.layout && parent.layout !== "position") {
// Useless in this context.
node.x = node.y = 0;
- if (parent.layout === "tb") {
- if (
- parent.w !== "" &&
- (node.w === "" || node.w === 0 || node.w > parent.w)
- ) {
- node.w = parent.w;
- }
- }
}
if (node.layout === "table") {
diff --git a/src/core/xfa/layout.js b/src/core/xfa/layout.js
index dc46ac5e5..f82b42bf5 100644
--- a/src/core/xfa/layout.js
+++ b/src/core/xfa/layout.js
@@ -16,7 +16,7 @@
import {
$extra,
$flushHTML,
- $getParent,
+ $getSubformParent,
$getTemplateRoot,
$isSplittable,
} from "./xfa_object.js";
@@ -265,7 +265,7 @@ function checkDimensions(node, space) {
return true;
}
- const parent = node[$getParent]();
+ const parent = node[$getSubformParent]();
const attempt = (parent[$extra] && parent[$extra].attempt) || 0;
let y, w, h;
switch (parent.layout) {
@@ -344,6 +344,15 @@ function checkDimensions(node, space) {
return h + y > area.h;
case "rl-row":
case "row":
+ if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
+ return true;
+ }
+
+ if (node.h !== "") {
+ [, , , h] = getTransformedBBox(node);
+ return Math.round(h - space.height) <= 1;
+ }
+ return true;
default:
// No layout, so accept everything.
return true;
diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js
index c57b8194c..b3b87f930 100644
--- a/src/core/xfa/template.js
+++ b/src/core/xfa/template.js
@@ -1073,7 +1073,7 @@ class CheckButton extends XFAObject {
const value = (field.value && field.value[$text]()) || "off";
const checked = value === exportedValue.on || undefined;
- const container = field[$getParent]();
+ const container = field[$getSubformParent]();
const fieldId = field[$uid];
let dataId;
@@ -2113,27 +2113,15 @@ class ExclGroup extends XFAObject {
[$isSplittable]() {
// We cannot cache the result here because the contentArea
// can change.
- if (!this[$getParent]()[$isSplittable]()) {
+ if (!this[$getSubformParent]()[$isSplittable]()) {
return false;
}
- const root = this[$getTemplateRoot]();
- const contentArea = root[$extra].currentContentArea;
- if (contentArea && Math.max(this.minH, this.h || 0) >= contentArea.h) {
- return true;
- }
-
if (this[$extra]._isSplittable !== undefined) {
return this[$extra]._isSplittable;
}
- if (this.layout === "position") {
- this[$extra]._isSplittable = false;
- return false;
- }
-
- const parentLayout = this[$getParent]().layout;
- if (parentLayout && parentLayout.includes("row")) {
+ if (this.layout === "position" || this.layout.includes("row")) {
this[$extra]._isSplittable = false;
return false;
}
@@ -2205,8 +2193,8 @@ class ExclGroup extends XFAObject {
const filter = new Set(["field"]);
- if (this.layout === "row") {
- const columnWidths = this[$getParent]().columnWidths;
+ if (this.layout.includes("row")) {
+ const columnWidths = this[$getSubformParent]().columnWidths;
if (Array.isArray(columnWidths) && columnWidths.length > 0) {
this[$extra].columnWidths = columnWidths;
this[$extra].currentColumn = 0;
@@ -4387,6 +4375,14 @@ class Subform extends XFAObject {
this.subformSet = new XFAObjectArray();
}
+ [$getSubformParent]() {
+ const parent = this[$getParent]();
+ if (parent instanceof SubformSet) {
+ return parent[$getSubformParent]();
+ }
+ return parent;
+ }
+
[$isBindable]() {
return true;
}
@@ -4412,25 +4408,21 @@ class Subform extends XFAObject {
[$isSplittable]() {
// We cannot cache the result here because the contentArea
// can change.
- if (!this[$getParent]()[$isSplittable]()) {
+ if (!this[$getSubformParent]()[$isSplittable]()) {
return false;
}
- const root = this[$getTemplateRoot]();
- const contentArea = root[$extra].currentContentArea;
- if (contentArea && Math.max(this.minH, this.h || 0) >= contentArea.h) {
- return true;
- }
+ const contentArea = this[$getTemplateRoot]()[$extra].currentContentArea;
- if (this.overflow) {
- return this.overflow[$getExtra]().target !== contentArea;
+ if (this.overflow && this.overflow[$getExtra]().target === contentArea) {
+ return false;
}
if (this[$extra]._isSplittable !== undefined) {
return this[$extra]._isSplittable;
}
- if (this.layout === "position") {
+ if (this.layout === "position" || this.layout.includes("row")) {
this[$extra]._isSplittable = false;
return false;
}
@@ -4440,12 +4432,6 @@ class Subform extends XFAObject {
return false;
}
- const parentLayout = this[$getParent]().layout;
- if (parentLayout && parentLayout.includes("row")) {
- this[$extra]._isSplittable = false;
- return false;
- }
-
this[$extra]._isSplittable = true;
return true;
diff --git a/test/pdfs/xfa_bug1718740.pdf.link b/test/pdfs/xfa_bug1718740.pdf.link
new file mode 100644
index 000000000..7d38b029c
--- /dev/null
+++ b/test/pdfs/xfa_bug1718740.pdf.link
@@ -0,0 +1 @@
+https://bugzilla.mozilla.org/attachment.cgi?id=9229373
diff --git a/test/test_manifest.json b/test/test_manifest.json
index 6e4e1df89..3917bf409 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -938,6 +938,14 @@
"lastPage": 2,
"type": "eq"
},
+ { "id": "xfa_bug1718740",
+ "file": "pdfs/xfa_bug1718740.pdf",
+ "md5": "fab4277f2c70fd1edb35f597f5fe6819",
+ "link": true,
+ "rounds": 1,
+ "enableXfa": true,
+ "type": "eq"
+ },
{ "id": "xfa_bug1718521_1",
"file": "pdfs/xfa_bug1718521_1.pdf",
"md5": "9b89dd9e6a4c6c3258ca24debd806863",