From ee28eda9982d3d31e9c7d12b831de006369e6db9 Mon Sep 17 00:00:00 2001
From: Jon Gunderson
Date: Tue, 12 Oct 2021 12:56:18 -0500
Subject: [PATCH] Checkbox Example (Mixed-State): Restore Focus Appearance and
Update Code Style (pull #1801)
* Restored visual focus styling features that were mistakenly removed.
* Added documentation of accessibility features.
* Updated JS code to use current coding practices.
* Changed from using event.keyCode to event.key in event handlers.
* Change to use SVG graphics
* Renamed example HTML file: checkbox-mixed.html .
Co-authored-by: Matt King
---
.../checkbox/checkbox-2/js/checkboxMixed.js | 151 ---------------
.../checkbox-2/js/controlledCheckbox.js | 98 ----------
.../checkbox-2.html => checkbox-mixed.html} | 68 ++++---
examples/checkbox/css/checkbox-mixed.css | 62 +++++++
examples/checkbox/js/checkbox-mixed.js | 173 ++++++++++++++++++
examples/index.html | 6 +-
...eckbox-2.js => checkbox_checkbox-mixed.js} | 10 +-
7 files changed, 275 insertions(+), 293 deletions(-)
delete mode 100644 examples/checkbox/checkbox-2/js/checkboxMixed.js
delete mode 100644 examples/checkbox/checkbox-2/js/controlledCheckbox.js
rename examples/checkbox/{checkbox-2/checkbox-2.html => checkbox-mixed.html} (74%)
create mode 100644 examples/checkbox/css/checkbox-mixed.css
create mode 100644 examples/checkbox/js/checkbox-mixed.js
rename test/tests/{checkbox_checkbox-2.js => checkbox_checkbox-mixed.js} (96%)
diff --git a/examples/checkbox/checkbox-2/js/checkboxMixed.js b/examples/checkbox/checkbox-2/js/checkboxMixed.js
deleted file mode 100644
index 84698448be..0000000000
--- a/examples/checkbox/checkbox-2/js/checkboxMixed.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * This content is licensed according to the W3C Software License at
- * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
- *
- * File: CheckboxMixed.js
- *
- * Desc: CheckboxMixed widget that implements ARIA Authoring Practices
- * for a menu of links
- */
-
-/* global ControlledCheckbox */
-
-'use strict';
-
-/*
- * @constructor CheckboxMixed
- *
- *
- */
-var CheckboxMixed = function (domNode) {
- this.domNode = domNode;
-
- this.controlledCheckboxes = [];
-
- this.keyCode = Object.freeze({
- RETURN: 13,
- SPACE: 32,
- });
-};
-
-CheckboxMixed.prototype.init = function () {
- this.domNode.tabIndex = 0;
-
- var ids = this.domNode.getAttribute('aria-controls').split(' ');
-
- for (var i = 0; i < ids.length; i++) {
- var node = document.getElementById(ids[i]);
- var ccb = new ControlledCheckbox(node, this);
- ccb.init();
- this.controlledCheckboxes.push(ccb);
- }
-
- this.domNode.addEventListener('keydown', this.handleKeydown.bind(this));
- this.domNode.addEventListener('click', this.handleClick.bind(this));
- this.domNode.addEventListener('focus', this.handleFocus.bind(this));
- this.domNode.addEventListener('blur', this.handleBlur.bind(this));
-
- this.updateCheckboxMixed();
-};
-
-CheckboxMixed.prototype.updateCheckboxMixed = function () {
- var count = 0;
-
- for (var i = 0; i < this.controlledCheckboxes.length; i++) {
- if (this.controlledCheckboxes[i].isChecked()) {
- count++;
- }
- }
-
- if (count === 0) {
- this.domNode.setAttribute('aria-checked', 'false');
- } else {
- if (count === this.controlledCheckboxes.length) {
- this.domNode.setAttribute('aria-checked', 'true');
- } else {
- this.domNode.setAttribute('aria-checked', 'mixed');
- this.updateControlledStates();
- }
- }
-};
-
-CheckboxMixed.prototype.updateControlledStates = function () {
- for (var i = 0; i < this.controlledCheckboxes.length; i++) {
- this.controlledCheckboxes[i].lastState = this.controlledCheckboxes[
- i
- ].isChecked();
- }
-};
-
-CheckboxMixed.prototype.anyLastChecked = function () {
- var count = 0;
-
- for (var i = 0; i < this.controlledCheckboxes.length; i++) {
- if (this.controlledCheckboxes[i].lastState) {
- count++;
- }
- }
-
- return count > 0;
-};
-
-CheckboxMixed.prototype.setControlledCheckboxes = function (value) {
- for (var i = 0; i < this.controlledCheckboxes.length; i++) {
- this.controlledCheckboxes[i].setChecked(value);
- }
-
- this.updateCheckboxMixed();
-};
-
-CheckboxMixed.prototype.toggleCheckboxMixed = function () {
- var state = this.domNode.getAttribute('aria-checked');
-
- if (state === 'false') {
- if (this.anyLastChecked()) {
- this.setControlledCheckboxes('last');
- } else {
- this.setControlledCheckboxes('true');
- }
- } else {
- if (state === 'mixed') {
- this.setControlledCheckboxes('true');
- } else {
- this.setControlledCheckboxes('false');
- }
- }
-
- this.updateCheckboxMixed();
-};
-
-/* EVENT HANDLERS */
-
-CheckboxMixed.prototype.handleKeydown = function (event) {
- var flag = false;
-
- switch (event.keyCode) {
- case this.keyCode.SPACE:
- this.toggleCheckboxMixed();
- flag = true;
- break;
-
- default:
- break;
- }
-
- if (flag) {
- event.stopPropagation();
- event.preventDefault();
- }
-};
-
-CheckboxMixed.prototype.handleClick = function () {
- this.toggleCheckboxMixed();
-};
-
-CheckboxMixed.prototype.handleFocus = function () {
- this.domNode.classList.add('focus');
-};
-
-CheckboxMixed.prototype.handleBlur = function () {
- this.domNode.classList.remove('focus');
-};
diff --git a/examples/checkbox/checkbox-2/js/controlledCheckbox.js b/examples/checkbox/checkbox-2/js/controlledCheckbox.js
deleted file mode 100644
index a8684309a5..0000000000
--- a/examples/checkbox/checkbox-2/js/controlledCheckbox.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * This content is licensed according to the W3C Software License at
- * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
- *
- * File: controlledCheckbox.js
- *
- * Desc: ControlledCheckbox widget that implements ARIA Authoring Practices
- * for a mixed checkbox
- */
-
-'use strict';
-
-/*
- * @constructor ControlledCheckbox
- *
- *
- */
-var ControlledCheckbox = function (domNode, controllerObj) {
- this.domNode = domNode;
- this.controller = controllerObj;
- this.lastState = false;
-};
-
-ControlledCheckbox.prototype.init = function () {
- this.lastState = this.isChecked();
-
- this.domNode.addEventListener('change', this.handleChange.bind(this));
-
- this.domNode.addEventListener('keydown', this.handleKeyup.bind(this), true);
- this.domNode.addEventListener('click', this.handleClick.bind(this), true);
-};
-
-ControlledCheckbox.prototype.isChecked = function () {
- // if standard input[type=checkbox]
- if (typeof this.domNode.checked === 'boolean') {
- return this.domNode.checked;
- }
-
- // If ARIA checkbox widget
- return this.domNode.getAttribute('aria-checked') === 'true';
-};
-
-ControlledCheckbox.prototype.setChecked = function (value) {
- // if standard input[type=checkbox]
- if (typeof this.domNode.checked === 'boolean') {
- switch (value) {
- case 'true':
- this.domNode.checked = true;
- break;
-
- case 'false':
- this.domNode.checked = false;
- break;
-
- case 'last':
- this.domNode.checked = this.lastState;
- break;
-
- default:
- break;
- }
- }
-
- // If ARIA checkbox widget
- if (typeof this.domNode.getAttribute('aria-checked') === 'string') {
- switch (value) {
- case 'true':
- case 'false':
- this.domNode.setAttribute('aria-checked', value);
- break;
-
- case 'last':
- if (this.lastState) {
- this.domNode.setAttribute('aria-checked', 'true');
- } else {
- this.domNode.setAttribute('aria-checked', 'false');
- }
- break;
-
- default:
- break;
- }
- }
-};
-
-/* EVENT HANDLERS */
-
-ControlledCheckbox.prototype.handleChange = function () {
- this.controller.updateCheckboxMixed();
-};
-
-ControlledCheckbox.prototype.handleKeyup = function () {
- this.lastState = this.isChecked();
-};
-
-ControlledCheckbox.prototype.handleClick = function () {
- this.lastState = this.isChecked();
-};
diff --git a/examples/checkbox/checkbox-2/checkbox-2.html b/examples/checkbox/checkbox-mixed.html
similarity index 74%
rename from examples/checkbox/checkbox-2/checkbox-2.html
rename to examples/checkbox/checkbox-mixed.html
index 42681efcc2..925b12e5de 100644
--- a/examples/checkbox/checkbox-2/checkbox-2.html
+++ b/examples/checkbox/checkbox-mixed.html
@@ -6,14 +6,13 @@
-
-
-
-
+
+
+
+
-
-
-
+
+
-
- This example also demonstrates use of fieldset
and Legend
elements for labeling the checkbox group.
-
Similar examples include:
- Checkbox (Two State): Simple two state checkbox.
@@ -46,7 +42,7 @@ Example
-