XFA - Always bind root subform on root data
- it partially fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1717805 (on the data side at least but there is still a layout issue).
This commit is contained in:
parent
2bae399422
commit
b836616667
@ -55,12 +55,12 @@ class Binder {
|
|||||||
this.root = root;
|
this.root = root;
|
||||||
this.datasets = root.datasets;
|
this.datasets = root.datasets;
|
||||||
if (root.datasets && root.datasets.data) {
|
if (root.datasets && root.datasets.data) {
|
||||||
this.emptyMerge = false;
|
|
||||||
this.data = root.datasets.data;
|
this.data = root.datasets.data;
|
||||||
} else {
|
} else {
|
||||||
this.emptyMerge = true;
|
|
||||||
this.data = new XmlObject(NamespaceIds.datasets.id, "data");
|
this.data = new XmlObject(NamespaceIds.datasets.id, "data");
|
||||||
}
|
}
|
||||||
|
this.emptyMerge = this.data[$getChildren]().length === 0;
|
||||||
|
|
||||||
this.root.form = this.form = root.template[$clone]();
|
this.root.form = this.form = root.template[$clone]();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,6 +477,23 @@ class Binder {
|
|||||||
|
|
||||||
if (this._mergeMode === undefined && child[$nodeName] === "subform") {
|
if (this._mergeMode === undefined && child[$nodeName] === "subform") {
|
||||||
this._mergeMode = child.mergeMode === "consumeData";
|
this._mergeMode = child.mergeMode === "consumeData";
|
||||||
|
|
||||||
|
// XFA specs p. 182:
|
||||||
|
// The highest-level subform and the data node representing
|
||||||
|
// the current record are special; they are always
|
||||||
|
// bound even if their names don't match.
|
||||||
|
const dataChildren = dataNode[$getChildren]();
|
||||||
|
if (dataChildren.length > 0) {
|
||||||
|
this._bindOccurrences(child, [dataChildren[0]], null);
|
||||||
|
} else if (this.emptyMerge) {
|
||||||
|
const dataChild = new XmlObject(
|
||||||
|
dataNode[$namespaceId],
|
||||||
|
child.name || "root"
|
||||||
|
);
|
||||||
|
dataNode[$appendChild](dataChild);
|
||||||
|
this._bindElement(child, dataChild);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let global = false;
|
let global = false;
|
||||||
@ -570,21 +587,29 @@ class Binder {
|
|||||||
}
|
}
|
||||||
match = matches.length > 0 ? matches : null;
|
match = matches.length > 0 ? matches : null;
|
||||||
} else {
|
} else {
|
||||||
|
// If we've an empty merge, there are no reason
|
||||||
|
// to make multiple bind so skip consumed nodes.
|
||||||
match = dataNode[$getRealChildrenByNameIt](
|
match = dataNode[$getRealChildrenByNameIt](
|
||||||
child.name,
|
child.name,
|
||||||
/* allTransparent = */ false,
|
/* allTransparent = */ false,
|
||||||
/* skipConsumed = */ false
|
/* skipConsumed = */ this.emptyMerge
|
||||||
).next().value;
|
).next().value;
|
||||||
if (!match) {
|
if (!match) {
|
||||||
// We're in matchTemplate mode so create a node in data to reflect
|
// We're in matchTemplate mode so create a node in data to reflect
|
||||||
// what we've in template.
|
// what we've in template.
|
||||||
match = new XmlObject(dataNode[$namespaceId], child.name);
|
match = new XmlObject(dataNode[$namespaceId], child.name);
|
||||||
|
if (this.emptyMerge) {
|
||||||
|
match[$consumed] = true;
|
||||||
|
}
|
||||||
dataNode[$appendChild](match);
|
dataNode[$appendChild](match);
|
||||||
|
|
||||||
// Don't bind the value in newly created node because it's empty.
|
// Don't bind the value in newly created node because it's empty.
|
||||||
this._bindElement(child, match);
|
this._bindElement(child, match);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (this.emptyMerge) {
|
||||||
|
match[$consumed] = true;
|
||||||
|
}
|
||||||
match = [match];
|
match = [match];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,4 +219,55 @@ describe("XFAFactory", function () {
|
|||||||
expect(field2).not.toEqual(null);
|
expect(field2).not.toEqual(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should have an input or textarea", function () {
|
||||||
|
const xml = `
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
|
||||||
|
<template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
|
||||||
|
<subform name="root" mergeMode="matchTemplate">
|
||||||
|
<pageSet>
|
||||||
|
<pageArea>
|
||||||
|
<contentArea x="123pt" w="456pt" h="789pt"/>
|
||||||
|
<medium stock="default" short="456pt" long="789pt"/>
|
||||||
|
<field y="1pt" w="11pt" h="22pt" x="2pt">
|
||||||
|
<ui>
|
||||||
|
<textEdit multiLine="1"/>
|
||||||
|
</ui>
|
||||||
|
</field>
|
||||||
|
</pageArea>
|
||||||
|
</pageSet>
|
||||||
|
<subform name="first">
|
||||||
|
<field y="1pt" w="11pt" h="22pt" x="2pt" name="hello">
|
||||||
|
<ui>
|
||||||
|
<textEdit/>
|
||||||
|
</ui>
|
||||||
|
<value>
|
||||||
|
<integer/>
|
||||||
|
</value>
|
||||||
|
</field>
|
||||||
|
</subform>
|
||||||
|
</subform>
|
||||||
|
</template>
|
||||||
|
<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
|
||||||
|
<xfa:data>
|
||||||
|
<toto>
|
||||||
|
<first>
|
||||||
|
<hello>123
|
||||||
|
</hello>
|
||||||
|
</first>
|
||||||
|
</toto>
|
||||||
|
</xfa:data>
|
||||||
|
</xfa:datasets>
|
||||||
|
</xdp:xdp>
|
||||||
|
`;
|
||||||
|
const factory = new XFAFactory({ "xdp:xdp": xml });
|
||||||
|
|
||||||
|
expect(factory.numberPages).toEqual(1);
|
||||||
|
|
||||||
|
const pages = factory.getPages();
|
||||||
|
const field1 = searchHtmlNode(pages, "name", "input");
|
||||||
|
expect(field1).not.toEqual(null);
|
||||||
|
expect(field1.attributes.value).toEqual("123");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user