XFA - Layout correctly a subform with row layout (bug 1718740)

- Fix issues with subformSet elements which are not a real container.
This commit is contained in:
Calixte Denizet 2021-07-06 14:11:21 +02:00
parent b3de26f514
commit 5f76b6370c
5 changed files with 52 additions and 60 deletions

View File

@ -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") {
if (node.minW > 0) {
style.minWidth = measureToString(node.minW);
if (node.maxW) {
}
if (node.maxW > 0) {
style.maxWidth = measureToString(node.maxW);
}
if (node.minH > 0) {
style.minHeight = measureToString(node.minH);
if (node.maxH) {
}
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") {

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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",