From 6461d46f830bc4bce9f82f8918e747b62e164103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?"J.=20Rene=CC=81e=20Beach"?= Date: Sun, 10 Feb 2013 00:44:22 -0500 Subject: [PATCH] Issue #1913214 by jessebeach: Accessibility followup for Edit tab toggle of contextual links for in-place editing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: J. ReneĢe Beach --- core/modules/contextual/contextual.module | 1 + core/modules/contextual/contextual.toolbar.js | 89 +++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/core/modules/contextual/contextual.module b/core/modules/contextual/contextual.module index 7aca273..ccd30ca 100644 --- a/core/modules/contextual/contextual.module +++ b/core/modules/contextual/contextual.module @@ -106,6 +106,7 @@ function contextual_library_info() { 'dependencies' => array( array('system', 'jquery'), array('system', 'jquery.once'), + array('system', 'drupal.tabbingmanager'), array('system', 'backbone'), ), ); diff --git a/core/modules/contextual/contextual.toolbar.js b/core/modules/contextual/contextual.toolbar.js index 0c911c0..8c5af84 100644 --- a/core/modules/contextual/contextual.toolbar.js +++ b/core/modules/contextual/contextual.toolbar.js @@ -20,9 +20,19 @@ Drupal.behaviors.contextualToolbar = { var $contextuals = $(context).find('.contextual-links'); var $tab = $('.js .toolbar .bar .contextual-toolbar-tab'); var model = new Drupal.contextualToolbar.models.EditToggleModel({ - isViewing: (localStorage.getItem('Drupal.contextualToolbar.isViewing') === null) ? true : false + isViewing: (localStorage.getItem('Drupal.contextualToolbar.isViewing') === null) ? true : false, + '$contextuals': $contextuals }); - var view = new Drupal.contextualToolbar.views.EditToggleView({ + var visualView = new Drupal.contextualToolbar.views.EditToggleVisualView({ + el: $tab, + model: model + }); + var auralView = new Drupal.contextualToolbar.views.editToggleAuralView({ + // Append a messages element for aural state change announcements. + el: $(Drupal.theme('contextualMessageBox')).appendTo($tab), + model: model + }); + var tabbingView = new Drupal.contextualToolbar.views.editToggleTabbing({ el: $tab, model: model }); @@ -59,14 +69,16 @@ Drupal.contextualToolbar.models.EditToggleModel = Backbone.Model.extend({ /* Indicates whether the toggle is currently in "view" or "edit" mode. */ isViewing: true, /* Indicates whether the toggle should be visible or hidden. */ - isVisible: false + isVisible: false, + /* A jQuery list of the contextual link elements on the page. */ + '$contextuals': $() } }); /** * Handles edit mode toggle interactions. */ -Drupal.contextualToolbar.views.EditToggleView = Backbone.View.extend({ +Drupal.contextualToolbar.views.EditToggleVisualView = Backbone.View.extend({ events: { 'click': 'onClick' }, @@ -82,7 +94,6 @@ Drupal.contextualToolbar.views.EditToggleView = Backbone.View.extend({ * Implements Backbone Views' render(). */ render: function () { - var args = arguments; // Render the visibility. this.$el.toggleClass('element-hidden', !this.model.get('isVisible')); @@ -113,4 +124,72 @@ Drupal.contextualToolbar.views.EditToggleView = Backbone.View.extend({ } }); +/** + * Responds to edit mode changes by announcing the application state. + */ +Drupal.contextualToolbar.views.editToggleAuralView = Backbone.View.extend({ + /** + * Implements Backbone Views' initialize(). + */ + initialize: function () { + this.model.on('change', this.render, this); + }, + + /** + * Implements Backbone Views' render(). + */ + render: function () { + var isViewing = this.model.get('isViewing'); + // Inform aural users of state change. + var activatedText = Drupal.t('Edit mode is active. There are @count contextual link triggers. Tabbing will navigate between them.', {'@count': this.model.get('$contextuals').length}); + var deactivatedText = Drupal.t('Edit mode is inactive'); + this.$el + .text((!isViewing) ? activatedText : deactivatedText); + + return this; + } +}); + +/** + * Responds to edit mode changes by constraining element tabbing to contextual + * link triggers. + */ +Drupal.contextualToolbar.views.editToggleTabbing = Backbone.View.extend({ + /** + * Implements Backbone Views' initialize(). + */ + initialize: function () { + this.model.on('change:isViewing', this.render, this); + }, + + /** + * Implements Backbone Views' render(). + */ + render: function () { + var isViewing = this.model.get('isViewing'); + var $contextuals = this.model.get('$contextuals'); + var tabset; + if (!isViewing) { + tabset = Drupal.TabbingManager.constrain($contextuals.prev('.trigger').add(this.$el.find('button'))); + this.model.set('tabset', tabset); + } + if (isViewing && this.model.get('tabset')) { + tabset = this.model.get('tabset'); + tabset.release(); + } + + return this; + } +}); + +/** + * A region to post messages that a screen reading UA will announce. + * + * @return {String} + * A string representing a DOM fragment. + */ +Drupal.theme.contextualMessageBox = function () { + return '
'; +}; + })(jQuery, Backbone, Drupal, document, localStorage); -- 1.7.10.4