d684ffb9e63e52aa850a4a76521e310ed147c54a
[yaffs-website] / views / AuralView.js
1 /**
2  * @file
3  * A Backbone View that provides the aural view of the edit mode toggle.
4  */
5
6 (function ($, Drupal, Backbone, _) {
7
8   'use strict';
9
10   Drupal.contextualToolbar.AuralView = Backbone.View.extend(/** @lends Drupal.contextualToolbar.AuralView# */{
11
12     /**
13      * Tracks whether the tabbing constraint announcement has been read once.
14      *
15      * @type {bool}
16      */
17     announcedOnce: false,
18
19     /**
20      * Renders the aural view of the edit mode toggle (screen reader support).
21      *
22      * @constructs
23      *
24      * @augments Backbone.View
25      *
26      * @param {object} options
27      *   Options for the view.
28      */
29     initialize: function (options) {
30       this.options = options;
31
32       this.listenTo(this.model, 'change', this.render);
33       this.listenTo(this.model, 'change:isViewing', this.manageTabbing);
34
35       $(document).on('keyup', _.bind(this.onKeypress, this));
36     },
37
38     /**
39      * @inheritdoc
40      *
41      * @return {Drupal.contextualToolbar.AuralView}
42      *   The current contextual toolbar aural view.
43      */
44     render: function () {
45       // Render the state.
46       this.$el.find('button').attr('aria-pressed', !this.model.get('isViewing'));
47
48       return this;
49     },
50
51     /**
52      * Limits tabbing to the contextual links and edit mode toolbar tab.
53      */
54     manageTabbing: function () {
55       var tabbingContext = this.model.get('tabbingContext');
56       // Always release an existing tabbing context.
57       if (tabbingContext) {
58         tabbingContext.release();
59         Drupal.announce(this.options.strings.tabbingReleased);
60       }
61       // Create a new tabbing context when edit mode is enabled.
62       if (!this.model.get('isViewing')) {
63         tabbingContext = Drupal.tabbingManager.constrain($('.contextual-toolbar-tab, .contextual'));
64         this.model.set('tabbingContext', tabbingContext);
65         this.announceTabbingConstraint();
66         this.announcedOnce = true;
67       }
68     },
69
70     /**
71      * Announces the current tabbing constraint.
72      */
73     announceTabbingConstraint: function () {
74       var strings = this.options.strings;
75       Drupal.announce(Drupal.formatString(strings.tabbingConstrained, {
76         '@contextualsCount': Drupal.formatPlural(Drupal.contextual.collection.length, '@count contextual link', '@count contextual links')
77       }));
78       Drupal.announce(strings.pressEsc);
79     },
80
81     /**
82      * Responds to esc and tab key press events.
83      *
84      * @param {jQuery.Event} event
85      *   The keypress event.
86      */
87     onKeypress: function (event) {
88       // The first tab key press is tracked so that an annoucement about tabbing
89       // constraints can be raised if edit mode is enabled when the page is
90       // loaded.
91       if (!this.announcedOnce && event.keyCode === 9 && !this.model.get('isViewing')) {
92         this.announceTabbingConstraint();
93         // Set announce to true so that this conditional block won't run again.
94         this.announcedOnce = true;
95       }
96       // Respond to the ESC key. Exit out of edit mode.
97       if (event.keyCode === 27) {
98         this.model.set('isViewing', true);
99       }
100     }
101
102   });
103
104 })(jQuery, Drupal, Backbone, _);