diff --git a/src/core/xfa/html_utils.js b/src/core/xfa/html_utils.js
index b645a580995aa..7fbae9423edad 100644
--- a/src/core/xfa/html_utils.js
+++ b/src/core/xfa/html_utils.js
@@ -448,6 +448,18 @@ function fixTextIndent(styles) {
}
}
+function setAccess(node, classNames) {
+ switch (node.access) {
+ case "nonInteractive":
+ case "readOnly":
+ classNames.push("xfaReadOnly");
+ break;
+ case "protected":
+ classNames.push("xfaDisabled");
+ break;
+ }
+}
+
function getFonts(family) {
if (family.startsWith("'") || family.startsWith('"')) {
family = family.slice(1, family.length - 1);
@@ -466,6 +478,7 @@ export {
layoutClass,
layoutText,
measureToString,
+ setAccess,
setMinMaxDimensions,
toStyle,
};
diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js
index ba4f88c0a5a85..955385bc79845 100644
--- a/src/core/xfa/template.js
+++ b/src/core/xfa/template.js
@@ -72,6 +72,7 @@ import {
layoutClass,
layoutText,
measureToString,
+ setAccess,
setMinMaxDimensions,
toStyle,
} from "./html_utils.js";
@@ -2023,8 +2024,11 @@ class ExclGroup extends XFAObject {
const children = [];
const attributes = {
id: this[$uid],
+ class: [],
};
+ setAccess(this, attributes.class);
+
if (!this[$extra]) {
this[$extra] = Object.create(null);
}
@@ -2329,6 +2333,8 @@ class Field extends XFAObject {
class: classNames,
};
+ setAccess(this, classNames);
+
if (this.name) {
attributes.xfaName = this.name;
}
@@ -4171,8 +4177,11 @@ class Subform extends XFAObject {
const children = [];
const attributes = {
id: this[$uid],
+ class: [],
};
+ setAccess(this, attributes.class);
+
if (!this[$extra]) {
this[$extra] = Object.create(null);
}
diff --git a/src/display/xfa_layer.js b/src/display/xfa_layer.js
index 9717eb74eb478..5b3e16005aa02 100644
--- a/src/display/xfa_layer.js
+++ b/src/display/xfa_layer.js
@@ -181,6 +181,17 @@ class XfaLayer {
childHtml.appendChild(document.createTextNode(child.value));
}
}
+
+ for (const el of rootDiv.querySelectorAll(
+ ".xfaDisabled input, .xfaDisabled textarea"
+ )) {
+ el.setAttribute("disabled", true);
+ }
+ for (const el of rootDiv.querySelectorAll(
+ ".xfaReadOnly input, .xfaReadOnly textarea"
+ )) {
+ el.setAttribute("readOnly", true);
+ }
}
/**
diff --git a/test/pdfs/xfa_bug1716816.pdf.link b/test/pdfs/xfa_bug1716816.pdf.link
new file mode 100644
index 0000000000000..ad16e60c96252
--- /dev/null
+++ b/test/pdfs/xfa_bug1716816.pdf.link
@@ -0,0 +1 @@
+https://bugzilla.mozilla.org/attachment.cgi?id=9227455
diff --git a/test/test_manifest.json b/test/test_manifest.json
index 66f2b817a1938..5d47b6e1aaabf 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -938,6 +938,14 @@
"enableXfa": true,
"type": "eq"
},
+ { "id": "xfa_bug1716816",
+ "file": "pdfs/xfa_bug1716816.pdf",
+ "md5": "3051cd18db7839bc4953df35b52cf3e0",
+ "link": true,
+ "rounds": 1,
+ "enableXfa": true,
+ "type": "eq"
+ },
{ "id": "xfa_bug1716809",
"file": "pdfs/xfa_bug1716809.pdf",
"md5": "7192f9e27e8b84776d107f57cbe353d5",
diff --git a/web/xfa_layer_builder.css b/web/xfa_layer_builder.css
index 7e21fa46ab5d6..5dadb11991812 100644
--- a/web/xfa_layer_builder.css
+++ b/web/xfa_layer_builder.css
@@ -277,6 +277,13 @@
flex: 1;
}
+.xfaDisabled input,
+.xfaDisabled textarea,
+.xfaReadOnly input,
+.xfaReadOnly textarea {
+ background: initial;
+}
+
@media print {
.xfaTextfield,
.xfaSelect {