calixteman 2021-02-11 03:30:37 -08:00 committed by GitHub
parent 3787bd41ef
commit 0479deef4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 623 additions and 2 deletions

View File

@ -0,0 +1,202 @@
/* Copyright 2021 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $buildXFAObject, NamespaceIds } from "./namespaces.js";
import { StringObject, XFAObject, XFAObjectArray } from "./xfa_object.js";
const CONNECTION_SET_NS_ID = NamespaceIds.connectionSet.id;
class ConnectionSet extends XFAObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "connectionSet", /* hasChildren = */ true);
this.wsdlConnection = new XFAObjectArray();
this.xmlConnection = new XFAObjectArray();
this.xsdConnection = new XFAObjectArray();
}
}
class EffectiveInputPolicy extends XFAObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "effectiveInputPolicy");
this.id = attributes.id || "";
this.name = attributes.name || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class EffectiveOutputPolicy extends XFAObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "effectiveOutputPolicy");
this.id = attributes.id || "";
this.name = attributes.name || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class Operation extends StringObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "operation");
this.id = attributes.id || "";
this.input = attributes.input || "";
this.name = attributes.name || "";
this.output = attributes.output || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class RootElement extends StringObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "rootElement");
this.id = attributes.id || "";
this.name = attributes.name || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class SoapAction extends StringObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "soapAction");
this.id = attributes.id || "";
this.name = attributes.name || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class SoapAddress extends StringObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "soapAddress");
this.id = attributes.id || "";
this.name = attributes.name || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class Uri extends StringObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "uri");
this.id = attributes.id || "";
this.name = attributes.name || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class WsdlAddress extends StringObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "wsdlAddress");
this.id = attributes.id || "";
this.name = attributes.name || "";
this.use = attributes.use || "";
this.usehref = attributes.usehref || "";
}
}
class WsdlConnection extends XFAObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "wsdlConnection", /* hasChildren = */ true);
this.dataDescription = attributes.dataDescription || "";
this.name = attributes.name || "";
this.effectiveInputPolicy = null;
this.effectiveOutputPolicy = null;
this.operation = null;
this.soapAction = null;
this.soapAddress = null;
this.wsdlAddress = null;
}
}
class XmlConnection extends XFAObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "xmlConnection", /* hasChildren = */ true);
this.dataDescription = attributes.dataDescription || "";
this.name = attributes.name || "";
this.uri = null;
}
}
class XsdConnection extends XFAObject {
constructor(attributes) {
super(CONNECTION_SET_NS_ID, "xsdConnection", /* hasChildren = */ true);
this.dataDescription = attributes.dataDescription || "";
this.name = attributes.name || "";
this.rootElement = null;
this.uri = null;
}
}
class ConnectionSetNamespace {
static [$buildXFAObject](name, attributes) {
if (ConnectionSetNamespace.hasOwnProperty(name)) {
return ConnectionSetNamespace[name](attributes);
}
return undefined;
}
static connectionSet(attrs) {
return new ConnectionSet(attrs);
}
static effectiveInputPolicy(attrs) {
return new EffectiveInputPolicy(attrs);
}
static effectiveOutputPolicy(attrs) {
return new EffectiveOutputPolicy(attrs);
}
static operation(attrs) {
return new Operation(attrs);
}
static rootElement(attrs) {
return new RootElement(attrs);
}
static soapAction(attrs) {
return new SoapAction(attrs);
}
static soapAddress(attrs) {
return new SoapAddress(attrs);
}
static uri(attrs) {
return new Uri(attrs);
}
static wsdlAddress(attrs) {
return new WsdlAddress(attrs);
}
static wsdlConnection(attrs) {
return new WsdlConnection(attrs);
}
static xmlConnection(attrs) {
return new XmlConnection(attrs);
}
static xsdConnection(attrs) {
return new XsdConnection(attrs);
}
}
export { ConnectionSetNamespace };

69
src/core/xfa/datasets.js Normal file
View File

@ -0,0 +1,69 @@
/* Copyright 2021 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $buildXFAObject, NamespaceIds } from "./namespaces.js";
import {
$namespaceId,
$nodeName,
$onChildCheck,
XFAObject,
XmlObject,
} from "./xfa_object.js";
const DATASETS_NS_ID = NamespaceIds.datasets.id;
class Data extends XmlObject {
constructor(attributes) {
super(DATASETS_NS_ID, "data", attributes);
}
}
class Datasets extends XFAObject {
constructor(attributes) {
super(DATASETS_NS_ID, "datasets", /* hasChildren = */ true);
this.data = null;
this.Signature = null;
}
[$onChildCheck](child) {
const name = child[$nodeName];
if (name === "data") {
return child[$namespaceId] === DATASETS_NS_ID;
}
if (name === "Signature") {
return child[$namespaceId] === NamespaceIds.signature.id;
}
return false;
}
}
class DatasetsNamespace {
static [$buildXFAObject](name, attributes) {
if (DatasetsNamespace.hasOwnProperty(name)) {
return DatasetsNamespace[name](attributes);
}
return undefined;
}
static datasets(attributes) {
return new Datasets(attributes);
}
static data(attributes) {
return new Data(attributes);
}
}
export { DatasetsNamespace };

View File

@ -42,7 +42,7 @@ class XFAParser extends XMLParserBase {
if (this._whiteRegex.test(text)) {
return;
}
this._current[$onText](text);
this._current[$onText](text.trim());
}
onCdata(text) {

View File

@ -14,15 +14,25 @@
*/
import { ConfigNamespace } from "./config.js";
import { ConnectionSetNamespace } from "./connection_set.js";
import { DatasetsNamespace } from "./datasets.js";
import { LocaleSetNamespace } from "./locale_set.js";
import { SignatureNamespace } from "./signature.js";
import { StylesheetNamespace } from "./stylesheet.js";
import { TemplateNamespace } from "./template.js";
import { XdpNamespace } from "./xdp.js";
import { XhtmlNamespace } from "./xhtml.js";
const NamespaceSetUp = {
config: ConfigNamespace,
connection: ConnectionSetNamespace,
datasets: DatasetsNamespace,
localeSet: LocaleSetNamespace,
signature: SignatureNamespace,
stylesheet: StylesheetNamespace,
template: TemplateNamespace,
xdp: XdpNamespace,
xhtml: XhtmlNamespace,
};
export { NamespaceSetUp };

40
src/core/xfa/signature.js Normal file
View File

@ -0,0 +1,40 @@
/* Copyright 2021 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $buildXFAObject, NamespaceIds } from "./namespaces.js";
import { XFAObject } from "./xfa_object.js";
const SIGNATURE_NS_ID = NamespaceIds.signature.id;
class Signature extends XFAObject {
constructor(attributes) {
super(SIGNATURE_NS_ID, "signature", /* hasChildren = */ true);
}
}
class SignatureNamespace {
static [$buildXFAObject](name, attributes) {
if (SignatureNamespace.hasOwnProperty(name)) {
return SignatureNamespace[name](attributes);
}
return undefined;
}
static signature(attributes) {
return new Signature(attributes);
}
}
export { SignatureNamespace };

View File

@ -0,0 +1,40 @@
/* Copyright 2021 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $buildXFAObject, NamespaceIds } from "./namespaces.js";
import { XFAObject } from "./xfa_object.js";
const STYLESHEET_NS_ID = NamespaceIds.stylesheet.id;
class Stylesheet extends XFAObject {
constructor(attributes) {
super(STYLESHEET_NS_ID, "stylesheet", /* hasChildren = */ true);
}
}
class StylesheetNamespace {
static [$buildXFAObject](name, attributes) {
if (StylesheetNamespace.hasOwnProperty(name)) {
return StylesheetNamespace[name](attributes);
}
return undefined;
}
static stylesheet(attributes) {
return new Stylesheet(attributes);
}
}
export { StylesheetNamespace };

View File

@ -301,12 +301,14 @@ export {
$content,
$dump,
$finalize,
$getChildren,
$isTransparent,
$namespaceId,
$nodeName,
$onChild,
$onChildCheck,
$onText,
$text,
ContentObject,
IntegerObject,
Option01,

225
src/core/xfa/xhtml.js Normal file
View File

@ -0,0 +1,225 @@
/* Copyright 2021 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $buildXFAObject, NamespaceIds } from "./namespaces.js";
import { $text, XmlObject } from "./xfa_object.js";
const XHTML_NS_ID = NamespaceIds.xhtml.id;
const VALID_STYLES = new Set([
"color",
"font",
"font-family",
"font-size",
"font-stretch",
"font-style",
"font-weight",
"margin",
"margin-bottom",
"margin-left",
"margin-right",
"margin-top",
"letter-spacing",
"line-height",
"orphans",
"page-break-after",
"page-break-before",
"page-break-inside",
"tab-interval",
"tab-stop",
"text-decoration",
"text-indent",
"vertical-align",
"widows",
"kerning-mode",
"xfa-font-horizontal-scale",
"xfa-font-vertical-scale",
"xfa-tab-stops",
]);
function checkStyle(style) {
if (!style) {
return "";
}
// Remove any non-allowed keys.
return style
.trim()
.split(/\s*;\s*/)
.filter(s => !!s)
.map(s => s.split(/\s*:\s*/, 2))
.filter(([key]) => VALID_STYLES.has(key))
.map(kv => kv.join(":"))
.join(";");
}
class A extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "a");
this.href = attributes.href || "";
this.style = checkStyle(attributes.style);
}
}
class B extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "b");
this.style = checkStyle(attributes.style);
}
}
class Body extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "body");
this.style = checkStyle(attributes.style);
}
}
class Br extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "br");
this.style = checkStyle(attributes.style);
}
[$text]() {
return "\n";
}
}
class Html extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "html");
this.style = checkStyle(attributes.style);
}
}
class I extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "i");
this.style = checkStyle(attributes.style);
}
}
class Li extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "li");
this.style = checkStyle(attributes.style);
}
}
class Ol extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "ol");
this.style = checkStyle(attributes.style);
}
}
class P extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "p");
this.style = checkStyle(attributes.style);
}
}
class Span extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "span");
this.style = checkStyle(attributes.style);
}
}
class Sub extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "sub");
this.style = checkStyle(attributes.style);
}
}
class Sup extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "sup");
this.style = checkStyle(attributes.style);
}
}
class Ul extends XmlObject {
constructor(attributes) {
super(XHTML_NS_ID, "ul");
this.style = checkStyle(attributes.style);
}
}
class XhtmlNamespace {
static [$buildXFAObject](name, attributes) {
if (XhtmlNamespace.hasOwnProperty(name)) {
return XhtmlNamespace[name](attributes);
}
return undefined;
}
static a(attributes) {
return new A(attributes);
}
static b(attributes) {
return new B(attributes);
}
static body(attributes) {
return new Body(attributes);
}
static br(attributes) {
return new Br(attributes);
}
static html(attributes) {
return new Html(attributes);
}
static i(attributes) {
return new I(attributes);
}
static li(attributes) {
return new Li(attributes);
}
static ol(attributes) {
return new Ol(attributes);
}
static p(attributes) {
return new P(attributes);
}
static span(attributes) {
return new Span(attributes);
}
static sub(attributes) {
return new Sub(attributes);
}
static sup(attributes) {
return new Sup(attributes);
}
static ul(attributes) {
return new Ul(attributes);
}
}
export { XhtmlNamespace };

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
import { $dump } from "../../src/core/xfa/xfa_object.js";
import { $dump, $getChildren, $text } from "../../src/core/xfa/xfa_object.js";
import { XFAParser } from "../../src/core/xfa/parser.js";
describe("XFAParser", function () {
@ -247,5 +247,38 @@ describe("XFAParser", function () {
};
expect(root[$dump]()).toEqual(expected);
});
it("should parse a xfa document with xhtml", 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">
<extras>
<text>
<body xmlns="http://www.w3.org/1999/xhtml">
<p style="foo: bar; text-indent:0.5in; line-height:11px;bar:foo;tab-stop: left 0.5in">
The first line of this paragraph is indented a half-inch.<br/>
Successive lines are not indented.<br/>
This is the last line of the paragraph.<br/>
</p>
</body>
</text>
</extras>
</template>
</xdp:xdp>
`;
const root = new XFAParser().parse(xml)[$dump]();
const p = root.template.extras.text.$content[$getChildren]()[0];
expect(p.style).toEqual(
"text-indent:0.5in;line-height:11px;tab-stop:left 0.5in"
);
expect(p[$text]()).toEqual(
[
"The first line of this paragraph is indented a half-inch.\n",
"Successive lines are not indented.\n",
"This is the last line of the paragraph.\n",
].join("")
);
});
});
});