diff --git a/core/modules/contextual/contextual.toolbar.js b/core/modules/contextual/contextual.toolbar.js index df941b2..704bfdb 100644 --- a/core/modules/contextual/contextual.toolbar.js +++ b/core/modules/contextual/contextual.toolbar.js @@ -1,6 +1,6 @@ /** * @file - * Attaches behaviors for the Contextual module's "Edit" toolbar tab. + * Attaches behaviors for the Contextual module's edit toolbar tab. */ (function ($, Backbone, Drupal, document, localStorage) { @@ -8,20 +8,28 @@ "use strict"; /** - * Attaches contextual's "Edit" toolbar tab behavior. + * Attaches contextual's edit toolbar tab behavior. * * Events - * Contextual triggers a number of events that can be used by other scripts. - * - drupalEditModeChanged: This event is triggered when the edit mode changes. + * Contextual triggers an event that can be used by other scripts. + * - drupalEditModeChanged: Triggered when the edit mode changes. */ Drupal.behaviors.contextualToolbar = { attach: function (context) { $('body').once('contextualToolbar-init', function () { + 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({ - el: $('.js .toolbar .bar .contextual-toolbar-tab'), + 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 }); @@ -34,8 +42,8 @@ Drupal.behaviors.contextualToolbar = { model.set('isVisible', true); }); - // Update the model to show the "Edit" tab if there's >=1 contextual link. - if ($(context).find('.contextual-links').length > 0) { + // Update the model to show the edit tab if there's >=1 contextual link. + if ($contextuals.length > 0) { model.set('isVisible', true); } @@ -50,7 +58,7 @@ Drupal.behaviors.contextualToolbar = { Drupal.contextualToolbar = Drupal.contextualToolbar || { models: {}, views: {}}; /** - * Backbone Model for the "Edit" toggle. + * Backbone Model for the edit toggle. */ Drupal.contextualToolbar.models.EditToggleModel = Backbone.Model.extend({ defaults: { @@ -62,14 +70,14 @@ Drupal.contextualToolbar.models.EditToggleModel = Backbone.Model.extend({ }); /** - * Backbone View to make the "Edit" toggle interactive. + * Handles edit mode toggle interactions. */ -Drupal.contextualToolbar.views.EditToggleView = Backbone.View.extend({ +Drupal.contextualToolbar.views.EditToggleVisualView = Backbone.View.extend({ events: { 'click': 'onClick' }, /** - * Implements Backbone Views' initialize() function. + * Implements Backbone Views' initialize(). */ initialize: function () { this.model.on('change', this.render, this); @@ -77,9 +85,10 @@ Drupal.contextualToolbar.views.EditToggleView = Backbone.View.extend({ }, /** - * Implements Backbone Views' render() function. + * Implements Backbone Views' render(). */ render: function () { + var args = arguments; // Render the visibility. this.$el.toggleClass('element-hidden', !this.model.get('isVisible')); @@ -108,7 +117,42 @@ Drupal.contextualToolbar.views.EditToggleView = Backbone.View.extend({ event.preventDefault(); event.stopPropagation(); } +}); + +/** + * 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; + } }); +/** + * 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);