Skip to content

Commit 8f9553e

Browse files
committed
XFA - Elements created outside of XML must have all their properties (bug 1722029)
- an Image element was created, attached to its parent but the $globalData property was not set and that led to an error. - the pdf in bug 1722029 has 27 rendered rows (checked in Acrobat) when only one was displayed: this patch some binding issues around the occur element.
1 parent 777d890 commit 8f9553e

File tree

5 files changed

+65
-24
lines changed

5 files changed

+65
-24
lines changed

src/core/xfa/bind.js

+42-23
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
$setValue,
3838
$text,
3939
XFAAttribute,
40+
XFAObjectArray,
4041
XmlObject,
4142
} from "./xfa_object.js";
4243
import { BindItems, Field, Items, SetProperty, Text } from "./template.js";
@@ -391,25 +392,39 @@ class Binder {
391392
// Insert nodes which are not in the template but reflect
392393
// what we've in data tree.
393394

394-
let baseClone;
395-
if (matches.length > 1) {
396-
// Clone before binding to avoid bad state.
397-
baseClone = formNode[$clone]();
395+
const parent = formNode[$getParent]();
396+
const name = formNode[$nodeName];
397+
// Clone before binding to avoid bad state.
398+
const baseClone = formNode[$clone]();
399+
400+
if (!(parent[name] instanceof XFAObjectArray)) {
401+
this._bindValue(formNode, matches[0], picture);
402+
this._setProperties(formNode, matches[0]);
403+
this._bindItems(formNode, matches[0]);
404+
return;
398405
}
399406

400-
this._bindValue(formNode, matches[0], picture);
401-
this._setProperties(formNode, matches[0]);
402-
this._bindItems(formNode, matches[0]);
407+
let i = 0;
408+
for (const child of parent[name].children) {
409+
if (child.name !== formNode.name) {
410+
continue;
411+
}
412+
if (i === matches.length) {
413+
break;
414+
}
415+
const match = matches[i++];
416+
this._bindValue(child, match, picture);
417+
this._setProperties(child, match);
418+
this._bindItems(child, match);
419+
}
403420

404-
if (matches.length === 1) {
421+
if (i >= matches.length) {
405422
return;
406423
}
407424

408-
const parent = formNode[$getParent]();
409-
const name = formNode[$nodeName];
410425
const pos = parent[$indexOf](formNode);
411426

412-
for (let i = 1, ii = matches.length; i < ii; i++) {
427+
for (const ii = matches.length; i < ii; i++) {
413428
const match = matches[i];
414429
const clone = baseClone[$clone]();
415430
clone.occur.min = 1;
@@ -425,10 +440,6 @@ class Binder {
425440
}
426441

427442
_createOccurrences(formNode) {
428-
if (!this.emptyMerge) {
429-
return;
430-
}
431-
432443
const { occur } = formNode;
433444
if (!occur || occur.initial <= 1) {
434445
return;
@@ -437,13 +448,27 @@ class Binder {
437448
const parent = formNode[$getParent]();
438449
const name = formNode[$nodeName];
439450

440-
for (let i = 0, ii = occur.initial; i < ii; i++) {
451+
if (!(parent[name] instanceof XFAObjectArray)) {
452+
return;
453+
}
454+
455+
let currentNumber;
456+
if (formNode.name) {
457+
currentNumber = parent[name].children.filter(
458+
e => e.name === formNode.name
459+
).length;
460+
} else {
461+
currentNumber = parent[name].children.length;
462+
}
463+
464+
const pos = parent[$indexOf](formNode) + 1;
465+
for (let i = 0, ii = occur.initial - currentNumber; i < ii; i++) {
441466
const clone = formNode[$clone]();
442467
clone.occur.min = 1;
443468
clone.occur.max = 1;
444469
clone.occur.initial = 1;
445470
parent[name].push(clone);
446-
parent[$appendChild](clone);
471+
parent[$insertAt](pos + i, clone);
447472
}
448473
}
449474

@@ -629,12 +654,6 @@ class Binder {
629654
}
630655

631656
if (match) {
632-
if (match.length < min) {
633-
warn(
634-
`XFA - Must have at least ${min} occurrences: ${formNode[$nodeName]}.`
635-
);
636-
continue;
637-
}
638657
this._bindOccurrences(child, match, picture);
639658
} else if (min > 0) {
640659
this._setProperties(child, dataNode);

src/core/xfa/template.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -3605,7 +3605,7 @@ class Occur extends XFAObject {
36053605
this.id = attributes.id || "";
36063606
this.initial = getInteger({
36073607
data: attributes.initial,
3608-
defaultValue: 1,
3608+
defaultValue: "",
36093609
validate: x => true,
36103610
});
36113611
this.max = getInteger({
@@ -3622,6 +3622,12 @@ class Occur extends XFAObject {
36223622
this.usehref = attributes.usehref || "";
36233623
this.extras = null;
36243624
}
3625+
3626+
[$clean]() {
3627+
if (this.initial === "") {
3628+
this.initial = this[$getParent]() instanceof Template ? 1 : this.min;
3629+
}
3630+
}
36253631
}
36263632

36273633
class Oid extends StringObject {
@@ -5705,6 +5711,7 @@ class Value extends XFAObject {
57055711
if (parent.ui && parent.ui.imageEdit) {
57065712
if (!this.image) {
57075713
this.image = new Image({});
5714+
this[$appendChild](this.image);
57085715
}
57095716
this.image[$content] = value[$content];
57105717
return;

src/core/xfa/xfa_object.js

+6
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ class XFAObject {
204204
[$appendChild](child) {
205205
child[_parent] = this;
206206
this[_children].push(child);
207+
if (!child[$globalData] && this[$globalData]) {
208+
child[$globalData] = this[$globalData];
209+
}
207210
}
208211

209212
[$removeChild](child) {
@@ -236,6 +239,9 @@ class XFAObject {
236239
[$insertAt](i, child) {
237240
child[_parent] = this;
238241
this[_children].splice(i, 0, child);
242+
if (!child[$globalData] && this[$globalData]) {
243+
child[$globalData] = this[$globalData];
244+
}
239245
}
240246

241247
/**

test/pdfs/xfa_bug1722029.pdf.link

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://bugzilla.mozilla.org/attachment.cgi?id=9233058

test/test_manifest.json

+8
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,14 @@
952952
"enableXfa": true,
953953
"type": "eq"
954954
},
955+
{ "id": "xfa_bug1722029",
956+
"file": "pdfs/xfa_bug1722029.pdf",
957+
"md5": "d8dd6bb20599fc777b4c7ff7b74dd5e3",
958+
"link": true,
959+
"rounds": 1,
960+
"enableXfa": true,
961+
"type": "eq"
962+
},
955963
{ "id": "xfa_bug1721600",
956964
"file": "pdfs/xfa_bug1721600.pdf",
957965
"md5": "5f514f476169eeb7254da380a8db495a",

0 commit comments

Comments
 (0)