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