Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outline fields which are required (bug 1724918) #15000

Merged
merged 1 commit into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/core/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,7 @@ class WidgetAnnotation extends Annotation {
}

data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
data.required = this.hasFieldFlag(AnnotationFieldFlag.REQUIRED);
data.hidden = this._hasFlag(data.annotationFlags, AnnotationFlag.HIDDEN);
}

Expand Down
35 changes: 35 additions & 0 deletions src/core/xfa/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ function* getContainedChildren(node) {
}
}

function isRequired(node) {
return node.validate && node.validate.nullTest === "error";
}

function setTabIndex(node) {
while (node) {
if (!node.traversal) {
Expand Down Expand Up @@ -1368,13 +1372,19 @@ class CheckButton extends XFAObject {
xfaOn: exportedValue.on,
xfaOff: exportedValue.off,
"aria-label": ariaLabel(field),
"aria-required": false,
},
};

if (groupId) {
input.attributes.name = groupId;
}

if (isRequired(field)) {
input.attributes["aria-required"] = true;
input.attributes.required = true;
}

return HTMLResult.success({
name: "label",
attributes: {
Expand Down Expand Up @@ -1465,8 +1475,14 @@ class ChoiceList extends XFAObject {
dataId: (field[$data] && field[$data][$uid]) || field[$uid],
style,
"aria-label": ariaLabel(field),
"aria-required": false,
};

if (isRequired(field)) {
selectAttributes["aria-required"] = true;
selectAttributes.required = true;
}

if (this.open === "multiSelect") {
selectAttributes.multiple = true;
}
Expand Down Expand Up @@ -1704,9 +1720,15 @@ class DateTimeEdit extends XFAObject {
class: ["xfaTextfield"],
style,
"aria-label": ariaLabel(field),
"aria-required": false,
},
};

if (isRequired(field)) {
html.attributes["aria-required"] = true;
html.attributes.required = true;
}

return HTMLResult.success({
name: "label",
attributes: {
Expand Down Expand Up @@ -3859,9 +3881,15 @@ class NumericEdit extends XFAObject {
class: ["xfaTextfield"],
style,
"aria-label": ariaLabel(field),
"aria-required": false,
},
};

if (isRequired(field)) {
html.attributes["aria-required"] = true;
html.attributes.required = true;
}

return HTMLResult.success({
name: "label",
attributes: {
Expand Down Expand Up @@ -5833,6 +5861,7 @@ class TextEdit extends XFAObject {
class: ["xfaTextfield"],
style,
"aria-label": ariaLabel(field),
"aria-required": false,
},
};
} else {
Expand All @@ -5845,10 +5874,16 @@ class TextEdit extends XFAObject {
class: ["xfaTextfield"],
style,
"aria-label": ariaLabel(field),
"aria-required": false,
},
};
}

if (isRequired(field)) {
html.attributes["aria-required"] = true;
html.attributes.required = true;
}

return HTMLResult.success({
name: "label",
attributes: {
Expand Down
20 changes: 15 additions & 5 deletions src/display/annotation_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,7 @@ class AnnotationElement {
}
},
required: event => {
if (event.detail.required) {
event.target.setAttribute("required", "");
} else {
event.target.removeAttribute("required");
}
this._setRequired(event.target, event.detail.required);
},
bgColor: event => {
setColor("bgColor", "backgroundColor", event);
Expand Down Expand Up @@ -944,6 +940,15 @@ class WidgetAnnotationElement extends AnnotationElement {
style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
}
}

_setRequired(element, isRequired) {
if (isRequired) {
element.setAttribute("required", true);
} else {
element.removeAttribute("required");
}
element.setAttribute("aria-required", isRequired);
}
}

class TextWidgetAnnotationElement extends WidgetAnnotationElement {
Expand Down Expand Up @@ -1010,6 +1015,8 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
elementData.userValue = textContent;
element.setAttribute("id", id);

this._setRequired(element, this.data.required);

element.addEventListener("input", event => {
storage.setValue(id, { value: event.target.value });
this.setPropertyOnSiblings(
Expand Down Expand Up @@ -1255,6 +1262,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
const element = document.createElement("input");
GetElementsByNameSet.add(element);
element.disabled = data.readOnly;
this._setRequired(element, this.data.required);
element.type = "checkbox";
element.name = data.fieldName;
if (value) {
Expand Down Expand Up @@ -1338,6 +1346,7 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
const element = document.createElement("input");
GetElementsByNameSet.add(element);
element.disabled = data.readOnly;
this._setRequired(element, this.data.required);
element.type = "radio";
element.name = data.fieldName;
if (value) {
Expand Down Expand Up @@ -1447,6 +1456,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
const selectElement = document.createElement("select");
GetElementsByNameSet.add(selectElement);
selectElement.disabled = this.data.readOnly;
this._setRequired(selectElement, this.data.required);
selectElement.name = this.data.fieldName;
selectElement.setAttribute("id", id);
selectElement.tabIndex = DEFAULT_TAB_INDEX;
Expand Down
2 changes: 1 addition & 1 deletion test/pdfs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -525,4 +525,4 @@
!issue14862.pdf
!issue14705.pdf
!bug1771477.pdf

!bug1724918.pdf
Binary file added test/pdfs/bug1724918.pdf
Binary file not shown.
7 changes: 7 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6553,5 +6553,12 @@
"link": true,
"type": "eq",
"annotations": true
},
{ "id": "bug1724918",
"file": "pdfs/bug1724918.pdf",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is not included in the patch.

"md5": "ab30269570c8ff2c9f8eb73fb376a081",
"rounds": 1,
"type": "eq",
"annotations": true
}
]
20 changes: 19 additions & 1 deletion web/annotation_layer_builder.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
--annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>");
}

@media (forced-colors: active) {
.annotationLayer .textWidgetAnnotation input:required,
.annotationLayer .textWidgetAnnotation textarea:required,
.annotationLayer .choiceWidgetAnnotation select:required,
.annotationLayer .buttonWidgetAnnotation.checkBox input:required,
.annotationLayer .buttonWidgetAnnotation.radioButton input:required {
outline: 1.5px solid selectedItem;
}
}

.annotationLayer section {
position: absolute;
text-align: initial;
Expand Down Expand Up @@ -66,6 +76,14 @@
width: 100%;
}

.annotationLayer .textWidgetAnnotation input:required,
.annotationLayer .textWidgetAnnotation textarea:required,
.annotationLayer .choiceWidgetAnnotation select:required,
.annotationLayer .buttonWidgetAnnotation.checkBox input:required,
.annotationLayer .buttonWidgetAnnotation.radioButton input:required {
outline: 1.5px solid red;
}

.annotationLayer .choiceWidgetAnnotation select option {
padding: 0;
}
Expand Down Expand Up @@ -116,7 +134,7 @@
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before,
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after,
.annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before {
background-color: rgba(0, 0, 0, 1);
background-color: CanvasText;
content: "";
display: block;
position: absolute;
Expand Down
10 changes: 10 additions & 0 deletions web/xfa_layer_builder.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
--xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>");
}

@media (forced-colors: active) {
.xfaLayer *:required {
outline: 1.5px solid selectedItem;
}
}

.xfaLayer .highlight {
margin: -1px;
padding: 1px;
Expand Down Expand Up @@ -87,6 +93,10 @@
line-height: inherit;
}

.xfaLayer *:required {
outline: 1.5px solid red;
}

.xfaLayer div {
pointer-events: none;
}
Expand Down