Merge pull request #16398 from Snuffleupagus/xfa-optional-chaining

Introduce some optional chaining in the `src/core/xfa/` folder
This commit is contained in:
Tim van der Meij 2023-05-07 14:54:05 +02:00 committed by GitHub
commit bfb664b9a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 46 additions and 65 deletions

View File

@ -57,7 +57,7 @@ class Binder {
constructor(root) { constructor(root) {
this.root = root; this.root = root;
this.datasets = root.datasets; this.datasets = root.datasets;
if (root.datasets && root.datasets.data) { if (root.datasets?.data) {
this.data = root.datasets.data; this.data = root.datasets.data;
} else { } else {
this.data = new XmlObject(NamespaceIds.datasets.id, "data"); this.data = new XmlObject(NamespaceIds.datasets.id, "data");
@ -98,9 +98,7 @@ class Binder {
formNode[$setValue](createText(value)); formNode[$setValue](createText(value));
} else if ( } else if (
formNode instanceof Field && formNode instanceof Field &&
formNode.ui && formNode.ui?.choiceList?.open === "multiSelect"
formNode.ui.choiceList &&
formNode.ui.choiceList.open === "multiSelect"
) { ) {
const value = data[$getChildren]() const value = data[$getChildren]()
.map(child => child[$content].trim()) .map(child => child[$content].trim())
@ -172,7 +170,7 @@ class Binder {
// Thirdly, try to find it in attributes. // Thirdly, try to find it in attributes.
generator = this.data[$getAttributeIt](name, /* skipConsumed = */ true); generator = this.data[$getAttributeIt](name, /* skipConsumed = */ true);
match = generator.next().value; match = generator.next().value;
if (match && match[$isDataValue]()) { if (match?.[$isDataValue]()) {
return match; return match;
} }

View File

@ -118,8 +118,7 @@ class Builder {
const namespaceToUse = this._getNamespaceToUse(nsPrefix); const namespaceToUse = this._getNamespaceToUse(nsPrefix);
const node = const node =
(namespaceToUse && namespaceToUse[$buildXFAObject](name, attributes)) || namespaceToUse?.[$buildXFAObject](name, attributes) || new Empty();
new Empty();
if (node[$isNsAgnostic]()) { if (node[$isNsAgnostic]()) {
this._nsAgnosticLevel++; this._nsAgnosticLevel++;
@ -181,7 +180,7 @@ class Builder {
return this._currentNamespace; return this._currentNamespace;
} }
const prefixStack = this._namespacePrefixes.get(prefix); const prefixStack = this._namespacePrefixes.get(prefix);
if (prefixStack && prefixStack.length > 0) { if (prefixStack?.length > 0) {
return prefixStack.at(-1); return prefixStack.at(-1);
} }

View File

@ -65,17 +65,14 @@ class FontFinder {
} }
if (!property) { if (!property) {
if ( if (pdfFont.name.includes("Bold") || pdfFont.psName?.includes("Bold")) {
pdfFont.name.includes("Bold") ||
(pdfFont.psName && pdfFont.psName.includes("Bold"))
) {
property = "bold"; property = "bold";
} }
if ( if (
pdfFont.name.includes("Italic") || pdfFont.name.includes("Italic") ||
pdfFont.name.endsWith("It") || pdfFont.name.endsWith("It") ||
(pdfFont.psName && pdfFont.psName?.includes("Italic") ||
(pdfFont.psName.includes("Italic") || pdfFont.psName.endsWith("It"))) pdfFont.psName?.endsWith("It")
) { ) {
property += "italic"; property += "italic";
} }
@ -117,9 +114,8 @@ class FontFinder {
if (maybe.length === 0) { if (maybe.length === 0) {
for (const [, pdfFont] of this.fonts.entries()) { for (const [, pdfFont] of this.fonts.entries()) {
if ( if (
pdfFont.regular.name &&
pdfFont.regular.name pdfFont.regular.name
.replaceAll(pattern, "") ?.replaceAll(pattern, "")
.toLowerCase() .toLowerCase()
.startsWith(name) .startsWith(name)
) { ) {
@ -140,9 +136,8 @@ class FontFinder {
if (maybe.length === 0) { if (maybe.length === 0) {
for (const pdfFont of this.fonts.values()) { for (const pdfFont of this.fonts.values()) {
if ( if (
pdfFont.regular.name &&
pdfFont.regular.name pdfFont.regular.name
.replaceAll(pattern, "") ?.replaceAll(pattern, "")
.toLowerCase() .toLowerCase()
.startsWith(name) .startsWith(name)
) { ) {

View File

@ -81,7 +81,7 @@ const converters = {
const parent = node[$getSubformParent](); const parent = node[$getSubformParent]();
let width = node.w; let width = node.w;
const height = node.h; const height = node.h;
if (parent.layout && parent.layout.includes("row")) { if (parent.layout?.includes("row")) {
const extra = parent[$extra]; const extra = parent[$extra];
const colSpan = node.colSpan; const colSpan = node.colSpan;
let w; let w;
@ -117,7 +117,7 @@ const converters = {
}, },
position(node, style) { position(node, style) {
const parent = node[$getSubformParent](); const parent = node[$getSubformParent]();
if (parent && parent.layout && parent.layout !== "position") { if (parent?.layout && parent.layout !== "position") {
// IRL, we've some x/y in tb layout. // IRL, we've some x/y in tb layout.
// Specs say x/y is only used in positioned layout. // Specs say x/y is only used in positioned layout.
return; return;
@ -338,7 +338,7 @@ function computeBbox(node, html, availableSpace) {
function fixDimensions(node) { function fixDimensions(node) {
const parent = node[$getSubformParent](); const parent = node[$getSubformParent]();
if (parent.layout && parent.layout.includes("row")) { if (parent.layout?.includes("row")) {
const extra = parent[$extra]; const extra = parent[$extra];
const colSpan = node.colSpan; const colSpan = node.colSpan;
let width; let width;
@ -566,7 +566,7 @@ function getCurrentPara(node) {
} }
function setPara(node, nodeStyle, value) { function setPara(node, nodeStyle, value) {
if (value.attributes.class && value.attributes.class.includes("xfaRich")) { if (value.attributes.class?.includes("xfaRich")) {
if (nodeStyle) { if (nodeStyle) {
if (node.h === "") { if (node.h === "") {
nodeStyle.height = "auto"; nodeStyle.height = "auto";

View File

@ -273,7 +273,7 @@ function checkDimensions(node, space) {
const ERROR = 2; const ERROR = 2;
const parent = node[$getSubformParent](); const parent = node[$getSubformParent]();
const attempt = (parent[$extra] && parent[$extra].attempt) || 0; const attempt = parent[$extra]?.attempt || 0;
const [, y, w, h] = getTransformedBBox(node); const [, y, w, h] = getTransformedBBox(node);
switch (parent.layout) { switch (parent.layout) {

View File

@ -205,7 +205,7 @@ function* getContainedChildren(node) {
} }
function isRequired(node) { function isRequired(node) {
return node.validate && node.validate.nullTest === "error"; return node.validate?.nullTest === "error";
} }
function setTabIndex(node) { function setTabIndex(node) {
@ -269,7 +269,7 @@ function applyAssist(obj, attributes) {
} else { } else {
const parent = obj[$getParent](); const parent = obj[$getParent]();
if (parent.layout === "row") { if (parent.layout === "row") {
if (parent.assist && parent.assist.role === "TH") { if (parent.assist?.role === "TH") {
attributes.role = "columnheader"; attributes.role = "columnheader";
} else { } else {
attributes.role = "cell"; attributes.role = "cell";
@ -460,7 +460,7 @@ class Arc extends XFAObject {
const edge = this.edge || new Edge({}); const edge = this.edge || new Edge({});
const edgeStyle = edge[$toStyle](); const edgeStyle = edge[$toStyle]();
const style = Object.create(null); const style = Object.create(null);
if (this.fill && this.fill.presence === "visible") { if (this.fill?.presence === "visible") {
Object.assign(style, this.fill[$toStyle]()); Object.assign(style, this.fill[$toStyle]());
} else { } else {
style.fill = "transparent"; style.fill = "transparent";
@ -671,9 +671,7 @@ class Assist extends XFAObject {
} }
[$toHTML]() { [$toHTML]() {
return this.toolTip && this.toolTip[$content] return this.toolTip?.[$content] || null;
? this.toolTip[$content]
: null;
} }
} }
@ -943,7 +941,7 @@ class Border extends XFAObject {
Object.assign(style, this.margin[$toStyle]()); Object.assign(style, this.margin[$toStyle]());
} }
if (this.fill && this.fill.presence === "visible") { if (this.fill?.presence === "visible") {
Object.assign(style, this.fill[$toStyle]()); Object.assign(style, this.fill[$toStyle]());
} }
@ -1343,7 +1341,7 @@ class CheckButton extends XFAObject {
off: (items[1] !== undefined ? items[1] : "off").toString(), off: (items[1] !== undefined ? items[1] : "off").toString(),
}; };
const value = (field.value && field.value[$text]()) || "off"; const value = field.value?.[$text]() || "off";
const checked = value === exportedValue.on || undefined; const checked = value === exportedValue.on || undefined;
const container = field[$getSubformParent](); const container = field[$getSubformParent]();
const fieldId = field[$uid]; const fieldId = field[$uid];
@ -1353,11 +1351,11 @@ class CheckButton extends XFAObject {
groupId = container[$uid]; groupId = container[$uid];
type = "radio"; type = "radio";
className = "xfaRadio"; className = "xfaRadio";
dataId = (container[$data] && container[$data][$uid]) || container[$uid]; dataId = container[$data]?.[$uid] || container[$uid];
} else { } else {
type = "checkbox"; type = "checkbox";
className = "xfaCheckbox"; className = "xfaCheckbox";
dataId = (field[$data] && field[$data][$uid]) || field[$uid]; dataId = field[$data]?.[$uid] || field[$uid];
} }
const input = { const input = {
@ -1423,7 +1421,7 @@ class ChoiceList extends XFAObject {
const style = toStyle(this, "border", "margin"); const style = toStyle(this, "border", "margin");
const ui = this[$getParent](); const ui = this[$getParent]();
const field = ui[$getParent](); const field = ui[$getParent]();
const fontSize = (field.font && field.font.size) || 10; const fontSize = field.font?.size || 10;
const optionStyle = { const optionStyle = {
fontSize: `calc(${fontSize}px * var(--scale-factor))`, fontSize: `calc(${fontSize}px * var(--scale-factor))`,
}; };
@ -1441,7 +1439,7 @@ class ChoiceList extends XFAObject {
const values = items.children[saveIndex][$toHTML]().html; const values = items.children[saveIndex][$toHTML]().html;
let selected = false; let selected = false;
const value = (field.value && field.value[$text]()) || ""; const value = field.value?.[$text]() || "";
for (let i = 0, ii = displayed.length; i < ii; i++) { for (let i = 0, ii = displayed.length; i < ii; i++) {
const option = { const option = {
name: "option", name: "option",
@ -1472,7 +1470,7 @@ class ChoiceList extends XFAObject {
const selectAttributes = { const selectAttributes = {
class: ["xfaSelect"], class: ["xfaSelect"],
fieldId: field[$uid], fieldId: field[$uid],
dataId: (field[$data] && field[$data][$uid]) || field[$uid], dataId: field[$data]?.[$uid] || field[$uid],
style, style,
"aria-label": ariaLabel(field), "aria-label": ariaLabel(field),
"aria-required": false, "aria-required": false,
@ -1716,7 +1714,7 @@ class DateTimeEdit extends XFAObject {
attributes: { attributes: {
type: "text", type: "text",
fieldId: field[$uid], fieldId: field[$uid],
dataId: (field[$data] && field[$data][$uid]) || field[$uid], dataId: field[$data]?.[$uid] || field[$uid],
class: ["xfaTextfield"], class: ["xfaTextfield"],
style, style,
"aria-label": ariaLabel(field), "aria-label": ariaLabel(field),
@ -2424,11 +2422,7 @@ class ExclGroup extends XFAObject {
return false; return false;
} }
if ( if (parent.layout?.endsWith("-tb") && parent[$extra].numberInLine !== 0) {
parent.layout &&
parent.layout.endsWith("-tb") &&
parent[$extra].numberInLine !== 0
) {
// See comment in Subform::[$isSplittable] for an explanation. // See comment in Subform::[$isSplittable] for an explanation.
return false; return false;
} }
@ -2954,7 +2948,7 @@ class Field extends XFAObject {
} }
if (this[$tabIndex]) { if (this[$tabIndex]) {
if (ui.children && ui.children[0]) { if (ui.children?.[0]) {
ui.children[0].attributes.tabindex = this[$tabIndex]; ui.children[0].attributes.tabindex = this[$tabIndex];
} else { } else {
ui.attributes.tabindex = this[$tabIndex]; ui.attributes.tabindex = this[$tabIndex];
@ -2993,7 +2987,7 @@ class Field extends XFAObject {
value = htmlValue.children[0].value; value = htmlValue.children[0].value;
} }
} }
if (this.ui.textEdit && this.value.text && this.value.text.maxChars) { if (this.ui.textEdit && this.value.text?.maxChars) {
ui.children[0].attributes.maxLength = this.value.text.maxChars; ui.children[0].attributes.maxLength = this.value.text.maxChars;
} }
@ -3012,7 +3006,7 @@ class Field extends XFAObject {
} }
} }
if (!this.ui.imageEdit && ui.children && ui.children[0] && this.h) { if (!this.ui.imageEdit && ui.children?.[0] && this.h) {
borderDims = borderDims || getBorderDims(this.ui[$getExtra]()); borderDims = borderDims || getBorderDims(this.ui[$getExtra]());
let captionHeight = 0; let captionHeight = 0;
@ -3151,7 +3145,7 @@ class Fill extends XFAObject {
return style; return style;
} }
if (this.color && this.color.value) { if (this.color?.value) {
const color = this.color[$toStyle](); const color = this.color[$toStyle]();
style[color.startsWith("#") ? propName : altPropName] = color; style[color.startsWith("#") ? propName : altPropName] = color;
} }
@ -4000,9 +3994,9 @@ class Overflow extends XFAObject {
const leader = root[$searchNode](this.leader, parent); const leader = root[$searchNode](this.leader, parent);
const trailer = root[$searchNode](this.trailer, parent); const trailer = root[$searchNode](this.trailer, parent);
this[$extra] = { this[$extra] = {
target: (target && target[0]) || null, target: target?.[0] || null,
leader: (leader && leader[0]) || null, leader: leader?.[0] || null,
trailer: (trailer && trailer[0]) || null, trailer: trailer?.[0] || null,
addLeader: false, addLeader: false,
addTrailer: false, addTrailer: false,
}; };
@ -4609,7 +4603,7 @@ class Rectangle extends XFAObject {
: new Edge({}); : new Edge({});
const edgeStyle = edge[$toStyle](); const edgeStyle = edge[$toStyle]();
const style = Object.create(null); const style = Object.create(null);
if (this.fill && this.fill.presence === "visible") { if (this.fill?.presence === "visible") {
Object.assign(style, this.fill[$toStyle]()); Object.assign(style, this.fill[$toStyle]());
} else { } else {
style.fill = "transparent"; style.fill = "transparent";
@ -4983,11 +4977,7 @@ class Subform extends XFAObject {
return false; return false;
} }
if ( if (parent.layout?.endsWith("-tb") && parent[$extra].numberInLine !== 0) {
parent.layout &&
parent.layout.endsWith("-tb") &&
parent[$extra].numberInLine !== 0
) {
// If parent can fit in w=100 and there's already an element which takes // If parent can fit in w=100 and there's already an element which takes
// 90 then we've 10 for this element. Suppose this element has a tb layout // 90 then we've 10 for this element. Suppose this element has a tb layout
// and 5 elements have a width of 7 and the 6th has a width of 20: // and 5 elements have a width of 7 and the 6th has a width of 20:
@ -5067,7 +5057,7 @@ class Subform extends XFAObject {
} }
} }
if (this[$extra] && this[$extra].afterBreakAfter) { if (this[$extra]?.afterBreakAfter) {
return HTMLResult.EMPTY; return HTMLResult.EMPTY;
} }
@ -5486,7 +5476,7 @@ class Template extends XFAObject {
) { ) {
breakBefore = root.subform.children[0].breakBefore.children[0]; breakBefore = root.subform.children[0].breakBefore.children[0];
breakBeforeTarget = breakBefore.target; breakBeforeTarget = breakBefore.target;
} else if (root.break && root.break.beforeTarget) { } else if (root.break?.beforeTarget) {
breakBefore = root.break; breakBefore = root.break;
breakBeforeTarget = breakBefore.beforeTarget; breakBeforeTarget = breakBefore.beforeTarget;
} else if ( } else if (
@ -5573,7 +5563,7 @@ class Template extends XFAObject {
const flush = index => { const flush = index => {
const html = root[$flushHTML](); const html = root[$flushHTML]();
if (html) { if (html) {
hasSomething ||= !!html.children && html.children.length !== 0; hasSomething ||= html.children?.length > 0;
htmlContentAreas[index].children.push(html); htmlContentAreas[index].children.push(html);
} }
}; };
@ -5596,8 +5586,7 @@ class Template extends XFAObject {
const html = root[$toHTML](space); const html = root[$toHTML](space);
if (html.success) { if (html.success) {
if (html.html) { if (html.html) {
hasSomething ||= hasSomething ||= html.html.children?.length > 0;
!!html.html.children && html.html.children.length !== 0;
htmlContentAreas[i].children.push(html.html); htmlContentAreas[i].children.push(html.html);
} else if (!hasSomething && mainHtml.children.length > 1) { } else if (!hasSomething && mainHtml.children.length > 1) {
mainHtml.children.pop(); mainHtml.children.pop();
@ -5852,7 +5841,7 @@ class TextEdit extends XFAObject {
html = { html = {
name: "textarea", name: "textarea",
attributes: { attributes: {
dataId: (field[$data] && field[$data][$uid]) || field[$uid], dataId: field[$data]?.[$uid] || field[$uid],
fieldId: field[$uid], fieldId: field[$uid],
class: ["xfaTextfield"], class: ["xfaTextfield"],
style, style,
@ -5865,7 +5854,7 @@ class TextEdit extends XFAObject {
name: "input", name: "input",
attributes: { attributes: {
type: "text", type: "text",
dataId: (field[$data] && field[$data][$uid]) || field[$uid], dataId: field[$data]?.[$uid] || field[$uid],
fieldId: field[$uid], fieldId: field[$uid],
class: ["xfaTextfield"], class: ["xfaTextfield"],
style, style,
@ -6084,7 +6073,7 @@ class Value extends XFAObject {
[$setValue](value) { [$setValue](value) {
const parent = this[$getParent](); const parent = this[$getParent]();
if (parent instanceof Field) { if (parent instanceof Field) {
if (parent.ui && parent.ui.imageEdit) { if (parent.ui?.imageEdit) {
if (!this.image) { if (!this.image) {
this.image = new Image({}); this.image = new Image({});
this[$appendChild](this.image); this[$appendChild](this.image);

View File

@ -59,7 +59,7 @@ class FontInfo {
fontFinder.find("Myriad Pro", false) || fontFinder.find("Myriad Pro", false) ||
fontFinder.find("Arial", false) || fontFinder.find("Arial", false) ||
fontFinder.getDefault(); fontFinder.getDefault();
if (font && font.regular) { if (font?.regular) {
const pdfFont = font.regular; const pdfFont = font.regular;
const info = pdfFont.cssFontInfo; const info = pdfFont.cssFontInfo;
const xfaFont = { const xfaFont = {

View File

@ -450,7 +450,7 @@ class Html extends XhtmlObject {
if (children.length === 1) { if (children.length === 1) {
const child = children[0]; const child = children[0];
if (child.attributes && child.attributes.class.includes("xfaRich")) { if (child.attributes?.class.includes("xfaRich")) {
return HTMLResult.success(child); return HTMLResult.success(child);
} }
} }