[Pkg-mozext-commits] [adblock-plus] 08/87: Issue 2408 - Improved accessibility of checkboxes in options page
David Prévot
taffit at moszumanska.debian.org
Sat Apr 30 17:59:02 UTC 2016
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository adblock-plus.
commit 9faeb60aa7cf712a4dc848476498cc100f83d0fd
Author: Thomas Greiner <thomas at adblockplus.org>
Date: Wed Jan 27 15:53:02 2016 +0100
Issue 2408 - Improved accessibility of checkboxes in options page
---
options.html | 20 ++++++-----
options.js | 108 ++++++++++++++++++++++++++++++++++++++++---------------
skin/options.css | 25 +++++++++++--
3 files changed, 112 insertions(+), 41 deletions(-)
diff --git a/options.html b/options.html
index dde0b64..a5e8695 100644
--- a/options.html
+++ b/options.html
@@ -71,12 +71,12 @@
</footer>
</div>
</div>
- <div id="tab-content">
+ <div id="content">
<div id="content-wrapper">
<div id="dialog-background"></div>
<!-- General tab content -->
- <div id="content-general">
+ <div id="content-general" class="tab-content">
<div>
<h1 class="i18n_options_blocking_title"></h1>
<div class="hbox">
@@ -97,7 +97,7 @@
</div>
<ul id="blocking-languages-table" class="table list">
<template>
- <input type="checkbox" class="control" />
+ <button role="checkbox" class="control"></button>
<span class="display"></span>
</template>
</ul>
@@ -122,14 +122,14 @@
<div id="custom-wrapper">
<ul id="recommend-list-table" class="table list">
<template>
- <input type="checkbox" class="control" />
+ <button role="checkbox" class="control"></button>
<span class="display"></span>
<span class="popular"></span>
</template>
</ul>
<ul id="custom-list-table" class="table list">
<template>
- <input type="checkbox" class="control" />
+ <button role="checkbox" class="control"></button>
<span class="display"></span>
</template>
</ul>
@@ -161,7 +161,7 @@
</div>
<ul id="acceptableads-table" class="table list">
<template>
- <input type="checkbox" class="control" />
+ <button role="checkbox" class="control"></button>
<span class="display"></span>
</template>
</ul>
@@ -211,12 +211,14 @@
</div>
<!-- Advanced tab content -->
- <div id="content-advanced">
+ <div id="content-advanced" class="tab-content">
<div>
<h1><span class="i18n_options_tweaks_title"></span><a class="i18n_options_readMore tooltip" href="#"></a></h1>
<ul class="table" style="width: auto;">
<li>
- <input type="checkbox" id="easylist"/><span id="block-element-explanation" class="i18n_options_tweaks_blockElement"></span></li>
+ <button role="checkbox" id="easylist"></button>
+ <span id="block-element-explanation" class="i18n_options_tweaks_blockElement"></span>
+ </li>
</ul>
</div>
<div>
@@ -281,7 +283,7 @@
</div>
<!-- Help tab content -->
- <div id="content-help">
+ <div id="content-help" class="tab-content">
<h1 class="i18n_options_faq_title"></h1>
<p class="i18n_options_faq_description"></p>
<p>
diff --git a/options.js b/options.js
index f9ec572..300c724 100644
--- a/options.js
+++ b/options.js
@@ -23,6 +23,7 @@
var recommendationsMap = Object.create(null);
var filtersMap = Object.create(null);
var collections = Object.create(null);
+ var maxLabelId = 0;
function Collection(details)
{
@@ -64,19 +65,19 @@
for (var i = 0; i < arguments.length; i++)
{
var item = arguments[i];
- var text = item.title || item.url || item.text;
var listItem = document.createElement("li");
listItem.appendChild(document.importNode(template.content, true));
listItem.setAttribute("data-access", item.url || item.text);
- listItem.querySelector(".display").textContent = text;
- if (text)
- listItem.setAttribute("data-search", text.toLowerCase());
+ var labelId = "label-" + (++maxLabelId);
+ listItem.querySelector(".display").setAttribute("id", labelId);
var control = listItem.querySelector(".control");
if (control)
{
+ // We use aria-labelledby to avoid triggering the control when
+ // interacting with the label
+ control.setAttribute("aria-labelledby", labelId);
control.addEventListener("click", this.details[j].onClick, false);
- control.checked = item.disabled == false;
}
this._setEmpty(table, null);
@@ -84,6 +85,7 @@
table.insertBefore(listItem, table.childNodes[this.items.indexOf(item)]);
else
table.appendChild(listItem);
+ this.updateItem(item);
}
}
return length;
@@ -100,12 +102,53 @@
{
var table = E(this.details[i].id);
var element = table.childNodes[index];
+
+ // Element gets removed so make sure to handle focus appropriately
+ var control = element.querySelector(".control");
+ if (control && control == document.activeElement)
+ {
+ if (!focusNextElement(element.parentElement, control))
+ {
+ // Fall back to next focusable element within same tab or dialog
+ var focusableElement = element.parentElement;
+ while (focusableElement)
+ {
+ if (focusableElement.classList.contains("tab-content")
+ || focusableElement.classList.contains("dialog-content"))
+ break;
+
+ focusableElement = focusableElement.parentElement;
+ }
+ focusNextElement(focusableElement || document, control);
+ }
+ }
+
element.parentElement.removeChild(element);
if (this.items.length == 0)
this._setEmpty(table, this.details[i].emptyText);
}
};
+ Collection.prototype.updateItem = function(item)
+ {
+ var access = (item.url || item.text).replace(/'/g, "\\'");
+ for (var i = 0; i < this.details.length; i++)
+ {
+ var table = E(this.details[i].id);
+ var element = table.querySelector("[data-access='" + access + "']");
+ if (!element)
+ continue;
+
+ var text = item.title || item.url || item.text;
+ element.querySelector(".display").textContent = text;
+ if (text)
+ element.setAttribute("data-search", text.toLowerCase());
+ var control = element.querySelector(".control[role='checkbox']");
+ if (control)
+ control.setAttribute("aria-checked", item.disabled == false);
+ }
+ };
+
Collection.prototype.clearAll = function()
{
this.items = [];
@@ -119,11 +162,27 @@
}
};
+ function focusNextElement(container, currentElement)
+ {
+ var focusables = container.querySelectorAll("a, button, input, .control");
+ focusables = Array.prototype.slice.call(focusables);
+ var index = focusables.indexOf(currentElement);
+ index += (index == focusables.length - 1) ? -1 : 1;
+
+ var nextElement = focusables[index];
+ if (!nextElement)
+ return false;
+
+ nextElement.focus();
+ return true;
+ }
+
function onToggleSubscriptionClick(e)
{
e.preventDefault();
- var subscriptionUrl = e.target.parentNode.getAttribute("data-access");
- if (!e.target.checked)
+ var checkbox = e.target;
+ var subscriptionUrl = checkbox.parentElement.getAttribute("data-access");
+ if (checkbox.getAttribute("aria-checked") == "true")
{
ext.backgroundPage.sendMessage({
type: "subscriptions.remove",
@@ -220,30 +279,21 @@
{
function onObjectChanged()
{
- var access = (subscriptionUrl || subscription.text).replace(/'/g, "\\'");
- var elements = document.querySelectorAll("[data-access='" + access + "']");
- for (var i = 0; i < elements.length; i++)
+ for (var i in collections)
+ collections[i].updateItem(subscription);
+
+ var recommendation = recommendationsMap[subscriptionUrl];
+ if (recommendation && recommendation.type == "ads")
{
- var element = elements[i];
- var control = element.querySelector(".control");
- if (control.localName == "input")
- control.checked = subscription.disabled == false;
- if (subscriptionUrl in recommendationsMap)
+ if (subscription.disabled == false)
{
- var recommendation = recommendationsMap[subscriptionUrl];
- if (recommendation.type == "ads")
- {
- if (subscription.disabled == false)
- {
- collections.allLangs.removeItem(subscription);
- collections.langs.addItems(subscription);
- }
- else
- {
- collections.allLangs.addItems(subscription);
- collections.langs.removeItem(subscription);
- }
- }
+ collections.allLangs.removeItem(subscription);
+ collections.langs.addItems(subscription);
+ }
+ else
+ {
+ collections.allLangs.addItems(subscription);
+ collections.langs.removeItem(subscription);
}
}
}
diff --git a/skin/options.css b/skin/options.css
index e322cd6..2f43e15 100644
--- a/skin/options.css
+++ b/skin/options.css
@@ -92,6 +92,25 @@ input[type="text"], input[type="search"]
box-sizing: border-box;
}
+button[role="checkbox"]
+{
+ vertical-align: top;
+ width: 18px;
+ height: 18px;
+ margin-top: 0px;
+ -moz-margin-end: 20px;
+ -webkit-margin-end: 20px;
+ padding: 0px;
+ border: none;
+ background-color: transparent;
+ background-position: -51px 0px;
+}
+
+button[role="checkbox"][aria-checked="true"]
+{
+ background-position: -68px 0px;
+}
+
.option-name
{
display: flex;
@@ -269,7 +288,7 @@ html[dir="rtl"] body[data-tab="help"] #tab-help
border-top: none;
}
-#tab-content
+#content
{
background-color: #FFFFFF;
border: 1px solid #CDCDCD;
@@ -279,7 +298,7 @@ html[dir="rtl"] body[data-tab="help"] #tab-help
padding: 0px 60px 40px 60px;
}
-#tab-content h1
+#content h1
{
border-bottom: 1px solid #CDCDCD;
margin: 0px;
@@ -474,7 +493,7 @@ div.button
padding-bottom: 10px;
}
-.icon, .table input[type="checkbox"]::before, .table button.delete,
+.icon, .table button[role="checkbox"], .table button.delete,
#content-help a::before, #dialog-close::before,
#custom-filters-add button::after,
#dialog-body button::before
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git
More information about the Pkg-mozext-commits
mailing list