Allow screen-reader to read label & description of non-textable elements. Fixes #4762.

Allow screen-reader to identify the alert errors. Fixes #4763

  Added role alertdialog for confirm and alert dialog.
  Added role status for all status bars/banners.
  Added role alert for error bars.
  Added aria-labelledby for charts on each dashboard.
  Added tabindex for each chart so that it is navigable using tab key.
pull/27/head
Nagesh Dhope 2020-01-28 11:32:11 +05:30 committed by Akshay Joshi
parent 6594481992
commit f167d77b61
15 changed files with 66 additions and 41 deletions

View File

@ -11,6 +11,8 @@ New features
| `Issue #2554 <https://redmine.postgresql.org/issues/2554>`_ - Added support for a multi-level partitioned table.
| `Issue #3452 <https://redmine.postgresql.org/issues/3452>`_ - Added a Schema Diff tool to compare two schemas and generate a diff script.
| `Issue #4762 <https://redmine.postgresql.org/issues/4762>`_ - Allow screen-reader to read label & description of non-textable elements.
| `Issue #4763 <https://redmine.postgresql.org/issues/4763>`_ - Allow screen-reader to identify the alert errors.
Housekeeping
************

View File

@ -24,7 +24,7 @@
<div class="pr-2">
<i class="fa fa-exclamation-triangle text-danger" aria-hidden="true"></i>
</div>
<div class="alert-text" role="status">{{ errmsg }}</div>
<div class="alert-text" role="alert">{{ errmsg }}</div>
</div>
</div>
</div>

View File

@ -44,7 +44,7 @@
<div class="pr-2">
<i class="fa fa-exclamation-triangle text-danger" aria-hidden="true"></i>
</div>
<div class="alert-text" role="status">{{ errmsg }}</div>
<div class="alert-text" role="alert">{{ errmsg }}</div>
</div>
</div>
</div>

View File

@ -201,7 +201,7 @@ define('pgadmin.browser', [
isCloseable: false,
isPrivate: true,
elContainer: true,
content: '<div class="obj_properties container-fluid"><div class="alert alert-info pg-panel-message">' + select_object_msg + '</div></div>',
content: '<div class="obj_properties container-fluid"><div role="status" class="alert alert-info pg-panel-message">' + select_object_msg + '</div></div>',
events: panelEvents,
onCreate: function(myPanel, $container) {
$container.addClass('pg-no-overflow');
@ -215,7 +215,7 @@ define('pgadmin.browser', [
width: 500,
isCloseable: false,
isPrivate: true,
content: '<div class="negative-space p-2"><div class="alert alert-info pg-panel-message pg-panel-statistics-message">' + select_object_msg + '</div><div class="pg-panel-statistics-container d-none"></div></div>',
content: '<div class="negative-space p-2"><div role="status" class="alert alert-info pg-panel-message pg-panel-statistics-message">' + select_object_msg + '</div><div class="pg-panel-statistics-container d-none"></div></div>',
events: panelEvents,
}),
// Reversed engineered SQL for the object
@ -236,7 +236,7 @@ define('pgadmin.browser', [
width: 500,
isCloseable: false,
isPrivate: true,
content: '<div class="negative-space p-2"><div class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-dependencies-container d-none"></div></div>',
content: '<div class="negative-space p-2"><div role="status" class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-dependencies-container d-none"></div></div>',
events: panelEvents,
}),
// Dependents of the object
@ -247,7 +247,7 @@ define('pgadmin.browser', [
width: 500,
isCloseable: false,
isPrivate: true,
content: '<div class="negative-space p-2"><div class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-dependents-container d-none"></div></div>',
content: '<div class="negative-space p-2"><div role="status" class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-dependents-container d-none"></div></div>',
events: panelEvents,
}),
},

View File

@ -216,7 +216,7 @@ define([
j.empty();
j.data('obj-view', gridView);
$msgContainer = '<div class="alert alert-info pg-panel-message pg-panel-properties-message">' +
$msgContainer = '<div role="status" class="alert alert-info pg-panel-message pg-panel-properties-message">' +
gettext('Retrieving data from the server...') + '</div>';
$msgContainer = $($msgContainer).appendTo(j);

View File

@ -329,7 +329,7 @@ define('pgadmin.browser.node', [
<div class="pr-2">
<i class="fa fa-exclamation-triangle text-danger" aria-hidden="true" role="img"></i>
</div>
<div class="alert-text">${msg}</div>
<div role="alert" class="alert-text">${msg}</div>
<div class="ml-auto close-error-bar">
<a class="close-error fa fa-times text-danger"></a>
</div>
@ -396,7 +396,7 @@ define('pgadmin.browser.node', [
if (!newModel.isNew()) {
// This is definetely not in create mode
var msgDiv = '<div class="alert alert-info pg-panel-message pg-panel-properties-message">' +
var msgDiv = '<div role="status" class="alert alert-info pg-panel-message pg-panel-properties-message">' +
gettext('Retrieving data from the server...') + '</div>',
$msgDiv = $(msgDiv);
var timer = setTimeout(function(ctx) {
@ -500,7 +500,7 @@ define('pgadmin.browser.node', [
isPrivate: true,
isLayoutMember: false,
elContainer: true,
content: '<div class="obj_properties container-fluid"><div class="alert alert-info pg-panel-message">' + gettext('Please wait while we fetch information about the node from the server...') + '</div></div>',
content: '<div class="obj_properties container-fluid"><div role="status" class="alert alert-info pg-panel-message">' + gettext('Please wait while we fetch information about the node from the server...') + '</div></div>',
onCreate: function(myPanel, $container) {
$container.addClass('pg-no-overflow');
},

View File

@ -106,7 +106,7 @@ define([
' </div>' +
' <% } %>' +
' <div class="wizard-progress-bar"><% if (show_progress_bar) { %>' +
' <p class="alert alert-info col-sm-12"><%= show_progress_bar %></p><% } %>' +
' <p role="status" class="alert alert-info col-sm-12"><%= show_progress_bar %></p><% } %>' +
' </div>' +
' <div class="wizard-right-panel_content">' +
' </div>' +
@ -119,7 +119,7 @@ define([
' <div class="pr-2"> ' +
' <i class="fa fa-exclamation-triangle text-danger" aria-hidden="true" role="img"></i> ' +
' </div> ' +
' <div class="alert-text"></div> ' +
' <div role="alert" class="alert-text"></div> ' +
' <div class="ml-auto close-error-bar"> ' +
' <a aria-label="' + gettext('Close error bar') + '" class="close-error fa fa-times text-danger"></a> ' +
' </div> ' +

View File

@ -2,8 +2,8 @@
<div id="dashboard-graphs" class="dashboard-hidden">
<div class="row dashboard-row">
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="database-session-graph">
<div class="card-header" id="database-session-graph">
{{ _('Database sessions') }}
</div>
<div class="card-body dashboard-graph-body">
@ -12,8 +12,8 @@
</div>
</div>
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="transactions-per-second-graph">
<div class="card-header" id="transactions-per-second-graph">
{{ _('Transactions per second') }}
</div>
<div class="card-body dashboard-graph-body">
@ -24,8 +24,8 @@
</div>
<div class="row dashboard-row">
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="tuples-in-graph">
<div class="card-header" id="tuples-in-graph">
{{ _('Tuples in') }}
</div>
<div class="card-body dashboard-graph-body">
@ -34,8 +34,8 @@
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="tuples-out-graph">
<div class="card-header" id="tuples-out-graph">
{{ _('Tuples out') }}
</div>
<div class="card-body dashboard-graph-body">
@ -44,8 +44,8 @@
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="block-io-graph">
<div class="card-header" id="block-io-graph">
{{ _('Block I/O') }}
</div>
<div class="card-body dashboard-graph-body">

View File

@ -2,8 +2,8 @@
<div id="dashboard-graphs" class="dashboard-hidden">
<div class="row dashboard-row">
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="server-sessions-graph">
<div class="card-header" id="server-sessions-graph">
{{ _('Server sessions') }}
</div>
<div class="card-body dashboard-graph-body">
@ -12,8 +12,8 @@
</div>
</div>
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="transactions-per-second-graph">
<div class="card-header" id="transactions-per-second-graph">
{{ _('Transactions per second') }}
</div>
<div class="card-body dashboard-graph-body">
@ -24,8 +24,8 @@
</div>
<div class="row dashboard-row">
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="tuples-in-graph">
<div class="card-header" id="tuples-in-graph">
{{ _('Tuples in') }}
</div>
<div class="card-body dashboard-graph-body">
@ -34,8 +34,8 @@
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="tuples-out-graph">
<div class="card-header" id="tuples-out-graph">
{{ _('Tuples out') }}
</div>
<div class="card-body dashboard-graph-body">
@ -44,8 +44,8 @@
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
<div class="card" role="object-document" tabindex="0" aria-labelledby="block-o-graph">
<div class="card-header" id="block-o-graph">
{{ _('Block I/O') }}
</div>
<div class="card-body dashboard-graph-body">

View File

@ -127,8 +127,8 @@ define([
alertMessage = '\
<div class="media text-danger text-14">\
<div class="media-body media-middle">\
<div class="alert-text" role="status">' + promptmsg + '</div><br/>\
<div class="alert-text">' + gettext('Click for details.') + '</div>\
<div class="alert-text" role="alert">' + promptmsg + '</div><br/>\
<div class="alert-text" role="alert">' + gettext('Click for details.') + '</div>\
</div>\
</div>';
}
@ -172,8 +172,8 @@ define([
var alertMessage = '\
<div class="media text-danger text-14">\
<div class="media-body media-middle">\
<div class="alert-text" role="status">' + gettext('INTERNAL SERVER ERROR') + '</div><br/>\
<div class="alert-text">' + gettext('Click for details.') + '</div>\
<div class="alert-text" role="alert">' + gettext('INTERNAL SERVER ERROR') + '</div><br/>\
<div class="alert-text" role="alert">' + gettext('Click for details.') + '</div>\
</div>\
</div>';
@ -457,6 +457,14 @@ define([
$(this.elements.commands.close).attr('title', gettext('Close'));
$(this.elements.commands.maximize).attr('title', gettext('Maximize'));
$(this.elements.content).addClass('ajs-wrap-text');
$(this.elements.header).attr('id', 'confirm-dialog-header');
$(this.elements.body).attr('id', 'confirm-dialog-body');
$(this.elements.dialog).attr({
role: 'alertdialog',
'aria-modal': 'true',
'aria-labelledby': 'confirm-dialog-header',
'aria-describedby': 'confirm-dialog-body',
});
},
reverseButtons: true,
});
@ -465,6 +473,19 @@ define([
reverseButtons: true,
});
alertify.alert().set({
onshow:function() {
$(this.elements.header).attr('id', 'alert-dialog-header');
$(this.elements.body).attr('id', 'alert-dialog-body');
$(this.elements.modal).attr({
role: 'alertdialog',
'aria-modal': 'true',
'aria-labelledby': 'alert-dialog-header',
'aria-describedby': 'alert-dialog-body',
});
},
});
/* Suppress the enter key events occurring from select2 boxes
* so that the dialog does not close.
* Alertify listens to keyup events on the body element unfortunately

View File

@ -129,7 +129,7 @@ let FilterDialog = {
' <div class="pr-2"> ' +
' <i class="fa fa-exclamation-triangle text-danger" aria-hidden="true"></i> ' +
' </div> ' +
' <div class="alert-text" role="status"></div> ' +
' <div class="alert-text" role="alert"></div> ' +
' </div> ' +
' </div> ' +
'</div>').appendTo($container);

View File

@ -59,7 +59,7 @@ export default class QueryHistory {
this.parentNode.empty()
.removeClass('d-flex')
.append(
`<div class='alert alert-info pg-panel-message'>${gettext(
`<div role="status" class='alert alert-info pg-panel-message'>${gettext(
'No history found'
)}</div>`
);

View File

@ -364,6 +364,7 @@
<div class="connection_status_wrapper d-flex">
<div id="btn-conn-status"
role="status"
class="connection_status d-flex justify-content-center align-items-center" data-container="body"
data-toggle="popover" data-placement="bottom"
data-content=""

View File

@ -1726,12 +1726,13 @@ define([
// Create the messages panel to display the message returned from the database server
var messages = new pgAdmin.Browser.Panel({
name: 'messages',
title: gettext('Messages'),
title:
gettext('Messages'),
width: '100%',
height: '100%',
isCloseable: false,
isPrivate: true,
content: '<div id="messages" class="messages" tabindex="0"></div>',
content: '<div role="status" id="messages" class="messages" tabindex="0"></div>',
});
// Create the result panel to display the result after debugging the function

View File

@ -262,7 +262,7 @@ define('tools.querytool', [
height: '100%',
isCloseable: false,
isPrivate: true,
content: '<div class="sql-editor-message" tabindex="0"></div>',
content: '<div role="status" class="sql-editor-message" tabindex="0"></div>',
});
var history = new pgAdmin.Browser.Panel({