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