XFA - CDATA can be xml so parse it when required

This commit is contained in:
Calixte Denizet 2021-06-06 16:28:22 +02:00
parent 1775d5eeb7
commit 5dc7f4ade8
4 changed files with 52 additions and 0 deletions

View File

@ -16,7 +16,9 @@
import { import {
$acceptWhitespace, $acceptWhitespace,
$clean, $clean,
$content,
$finalize, $finalize,
$isCDATAXml,
$nsAttributes, $nsAttributes,
$onChild, $onChild,
$onText, $onText,
@ -150,6 +152,13 @@ class XFAParser extends XMLParserBase {
onEndElement(name) { onEndElement(name) {
const node = this._current; const node = this._current;
if (node[$isCDATAXml]() && typeof node[$content] === "string") {
const parser = new XFAParser();
const root = parser.parse(node[$content]);
node[$content] = null;
node[$onChild](root);
}
node[$finalize](); node[$finalize]();
this._current = this._stack.pop(); this._current = this._stack.pop();
if (this._current[$onChild](node)) { if (this._current[$onChild](node)) {

View File

@ -29,6 +29,7 @@ import {
$hasItem, $hasItem,
$hasSettableValue, $hasSettableValue,
$ids, $ids,
$isCDATAXml,
$isTransparent, $isTransparent,
$namespaceId, $namespaceId,
$nodeName, $nodeName,
@ -1746,6 +1747,10 @@ class ExData extends ContentObject {
this.usehref = attributes.usehref || ""; this.usehref = attributes.usehref || "";
} }
[$isCDATAXml]() {
return this.contentType === "text/html";
}
[$onChild](child) { [$onChild](child) {
if ( if (
this.contentType === "text/html" && this.contentType === "text/html" &&

View File

@ -51,6 +51,7 @@ const $hasSettableValue = Symbol();
const $ids = Symbol(); const $ids = Symbol();
const $indexOf = Symbol(); const $indexOf = Symbol();
const $insertAt = Symbol(); const $insertAt = Symbol();
const $isCDATAXml = Symbol();
const $isDataValue = Symbol(); const $isDataValue = Symbol();
const $isDescendent = Symbol(); const $isDescendent = Symbol();
const $isTransparent = Symbol(); const $isTransparent = Symbol();
@ -148,6 +149,10 @@ class XFAObject {
return false; return false;
} }
[$isCDATAXml]() {
return false;
}
[$setId](ids) { [$setId](ids) {
if (this.id && this[$namespaceId] === NamespaceIds.template.id) { if (this.id && this[$namespaceId] === NamespaceIds.template.id) {
ids.set(this.id, this); ids.set(this.id, this);
@ -970,6 +975,7 @@ export {
$ids, $ids,
$indexOf, $indexOf,
$insertAt, $insertAt,
$isCDATAXml,
$isDataValue, $isDataValue,
$isDescendent, $isDescendent,
$isTransparent, $isTransparent,

View File

@ -256,6 +256,38 @@ describe("XFAParser", function () {
expect(root[$dump]()).toEqual(expected); expect(root[$dump]()).toEqual(expected);
}); });
it("should parse a xfa document and parse CDATA when needed", 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>
<field>
<extras>
<exData contentType="text/html" name="foo">
<![CDATA[<body xmlns="http://www.w3.org/1999/xhtml">
<span>hello</span></body>]]>
</exData>
</extra>
</field>
</subform>
</template>
</xdp:xdp>
`;
const root = new XFAParser().parse(xml);
const exdata = searchNode(root, root, "foo")[0];
const body = exdata[$dump]().$content[$dump]();
const expected = {
$name: "body",
attributes: {},
children: [
{ $content: "hello", $name: "span", attributes: {}, children: [] },
],
};
expect(body).toEqual(expected);
});
it("should parse a xfa document and apply some prototypes", function () { it("should parse a xfa document and apply some prototypes", function () {
const xml = ` const xml = `
<?xml version="1.0"?> <?xml version="1.0"?>