Merge pull request #13875 from calixteman/xfa_focus
Annotation & XFA: Add focus outlines on different fields (bug 1723615, bug 1718528)
This commit is contained in:
commit
834e475e1d
@ -118,6 +118,9 @@ const MAX_ATTEMPTS_FOR_LRTB_LAYOUT = 2;
|
|||||||
// the loop after having MAX_EMPTY_PAGES empty pages.
|
// the loop after having MAX_EMPTY_PAGES empty pages.
|
||||||
const MAX_EMPTY_PAGES = 3;
|
const MAX_EMPTY_PAGES = 3;
|
||||||
|
|
||||||
|
// Default value to start with for the tabIndex property.
|
||||||
|
const DEFAULT_TAB_INDEX = 5000;
|
||||||
|
|
||||||
function getBorderDims(node) {
|
function getBorderDims(node) {
|
||||||
if (!node || !node.border) {
|
if (!node || !node.border) {
|
||||||
return { w: 0, h: 0 };
|
return { w: 0, h: 0 };
|
||||||
@ -173,7 +176,12 @@ function* getContainedChildren(node) {
|
|||||||
|
|
||||||
function setTabIndex(node) {
|
function setTabIndex(node) {
|
||||||
while (node) {
|
while (node) {
|
||||||
if (!node.traversal || node[$tabIndex]) {
|
if (!node.traversal) {
|
||||||
|
node[$tabIndex] = node[$getParent]()[$tabIndex];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node[$tabIndex]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +194,7 @@ function setTabIndex(node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!next || !next.ref) {
|
if (!next || !next.ref) {
|
||||||
|
node[$tabIndex] = node[$getParent]()[$tabIndex];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1755,6 +1764,8 @@ class Draw extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[$toHTML](availableSpace) {
|
[$toHTML](availableSpace) {
|
||||||
|
setTabIndex(this);
|
||||||
|
|
||||||
if (this.presence === "hidden" || this.presence === "inactive") {
|
if (this.presence === "hidden" || this.presence === "inactive") {
|
||||||
return HTMLResult.EMPTY;
|
return HTMLResult.EMPTY;
|
||||||
}
|
}
|
||||||
@ -2309,6 +2320,7 @@ class ExclGroup extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[$toHTML](availableSpace) {
|
[$toHTML](availableSpace) {
|
||||||
|
setTabIndex(this);
|
||||||
if (
|
if (
|
||||||
this.presence === "hidden" ||
|
this.presence === "hidden" ||
|
||||||
this.presence === "inactive" ||
|
this.presence === "inactive" ||
|
||||||
@ -2611,6 +2623,8 @@ class Field extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[$toHTML](availableSpace) {
|
[$toHTML](availableSpace) {
|
||||||
|
setTabIndex(this);
|
||||||
|
|
||||||
if (!this.ui) {
|
if (!this.ui) {
|
||||||
// It's allowed to not have an ui, specs say:
|
// It's allowed to not have an ui, specs say:
|
||||||
// If the UI element contains no children or is not present,
|
// If the UI element contains no children or is not present,
|
||||||
@ -2642,7 +2656,6 @@ class Field extends XFAObject {
|
|||||||
this.ui[$appendChild](node);
|
this.ui[$appendChild](node);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTabIndex(this);
|
|
||||||
if (
|
if (
|
||||||
!this.ui ||
|
!this.ui ||
|
||||||
this.presence === "hidden" ||
|
this.presence === "hidden" ||
|
||||||
@ -4833,6 +4846,8 @@ class Subform extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[$toHTML](availableSpace) {
|
[$toHTML](availableSpace) {
|
||||||
|
setTabIndex(this);
|
||||||
|
|
||||||
if (this.break) {
|
if (this.break) {
|
||||||
// break element is deprecated so plug it on one of its replacement
|
// break element is deprecated so plug it on one of its replacement
|
||||||
// breakBefore or breakAfter.
|
// breakBefore or breakAfter.
|
||||||
@ -5255,7 +5270,7 @@ class Template extends XFAObject {
|
|||||||
if (this.subform.children.length >= 2) {
|
if (this.subform.children.length >= 2) {
|
||||||
warn("XFA - Several subforms in template node: please file a bug.");
|
warn("XFA - Several subforms in template node: please file a bug.");
|
||||||
}
|
}
|
||||||
this[$tabIndex] = 1000;
|
this[$tabIndex] = DEFAULT_TAB_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
[$isSplittable]() {
|
[$isSplittable]() {
|
||||||
|
@ -33,6 +33,8 @@ import {
|
|||||||
import { AnnotationStorage } from "./annotation_storage.js";
|
import { AnnotationStorage } from "./annotation_storage.js";
|
||||||
import { ColorConverters } from "../shared/scripting_utils.js";
|
import { ColorConverters } from "../shared/scripting_utils.js";
|
||||||
|
|
||||||
|
const DEFAULT_TAB_INDEX = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AnnotationElementParameters
|
* @typedef {Object} AnnotationElementParameters
|
||||||
* @property {Object} data
|
* @property {Object} data
|
||||||
@ -722,6 +724,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
element.type = "text";
|
element.type = "text";
|
||||||
element.setAttribute("value", textContent);
|
element.setAttribute("value", textContent);
|
||||||
}
|
}
|
||||||
|
element.tabIndex = DEFAULT_TAB_INDEX;
|
||||||
|
|
||||||
elementData.userValue = textContent;
|
elementData.userValue = textContent;
|
||||||
element.setAttribute("id", id);
|
element.setAttribute("id", id);
|
||||||
@ -978,6 +981,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
element.setAttribute("checked", true);
|
element.setAttribute("checked", true);
|
||||||
}
|
}
|
||||||
element.setAttribute("id", id);
|
element.setAttribute("id", id);
|
||||||
|
element.tabIndex = DEFAULT_TAB_INDEX;
|
||||||
|
|
||||||
element.addEventListener("change", function (event) {
|
element.addEventListener("change", function (event) {
|
||||||
const name = event.target.name;
|
const name = event.target.name;
|
||||||
@ -1052,6 +1056,7 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
element.setAttribute("checked", true);
|
element.setAttribute("checked", true);
|
||||||
}
|
}
|
||||||
element.setAttribute("id", id);
|
element.setAttribute("id", id);
|
||||||
|
element.tabIndex = DEFAULT_TAB_INDEX;
|
||||||
|
|
||||||
element.addEventListener("change", function (event) {
|
element.addEventListener("change", function (event) {
|
||||||
const { target } = event;
|
const { target } = event;
|
||||||
@ -1148,6 +1153,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
selectElement.disabled = this.data.readOnly;
|
selectElement.disabled = this.data.readOnly;
|
||||||
selectElement.name = this.data.fieldName;
|
selectElement.name = this.data.fieldName;
|
||||||
selectElement.setAttribute("id", id);
|
selectElement.setAttribute("id", id);
|
||||||
|
selectElement.tabIndex = DEFAULT_TAB_INDEX;
|
||||||
|
|
||||||
selectElement.style.fontSize = `${fontSize}px`;
|
selectElement.style.fontSize = `${fontSize}px`;
|
||||||
|
|
||||||
|
@ -95,6 +95,14 @@
|
|||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.annotationLayer .textWidgetAnnotation input :focus,
|
||||||
|
.annotationLayer .textWidgetAnnotation textarea :focus,
|
||||||
|
.annotationLayer .choiceWidgetAnnotation select :focus,
|
||||||
|
.annotationLayer .buttonWidgetAnnotation.checkBox :focus,
|
||||||
|
.annotationLayer .buttonWidgetAnnotation.radioButton :focus {
|
||||||
|
outline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before,
|
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before,
|
||||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after,
|
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after,
|
||||||
.annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before {
|
.annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before {
|
||||||
|
@ -155,7 +155,13 @@
|
|||||||
.xfaSelect:focus {
|
.xfaSelect:focus {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
outline: none;
|
outline: auto;
|
||||||
|
outline-offset: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xfaCheckbox:focus,
|
||||||
|
.xfaRadio:focus {
|
||||||
|
outline: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaTextfield,
|
.xfaTextfield,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user