f243e4bd34d0f9b93b008e380279bc61aaf8ae11
[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     },
34
35     /**
36      * @inheritdoc
37      *
38      * @return {Drupal.contextualToolbar.AuralView}
39      *   The current contextual toolbar aural view.
40      */
41     render() {
42       // Render the state.
43       this.$el.find('button').attr('aria-pressed', !this.model.get('isViewing'));
44
45       return this;
46     },
47
48     /**
49      * Limits tabbing to the contextual links and edit mode toolbar tab.
50      */
51     manageTabbing() {
52       let tabbingContext = this.model.get('tabbingContext');
53       // Always release an existing tabbing context.
54       if (tabbingContext) {
55         // Only announce release when the context was active.
56         if (tabbingContext.active) {
57           Drupal.announce(this.options.strings.tabbingReleased);
58         }
59         tabbingContext.release();
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() {
74       const 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(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 }(jQuery, Drupal, Backbone, _));