Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js

Issue 1457683009: Complete live region support in ChromeVox Next. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix tests Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview Implements support for live regions in ChromeVox Next.
7 */
8
9 goog.provide('LiveRegions');
10
11 goog.require('ChromeVoxState');
12
13 goog.scope(function() {
14 var AutomationNode = chrome.automation.AutomationNode;
15 var TreeChange = chrome.automation.TreeChange;
16
17 /**
18 * ChromeVox2 live region handler.
19 * @param {ChromeVoxState} chromeVoxState The ChromeVox state object,
Peter Lundblad 2015/12/01 12:49:58 Make non-nullable.
dmazzoni 2015/12/01 19:19:01 Done.
20 * keeping track of the current mode and current range.
21 * @constructor
22 */
23 LiveRegions = function(chromeVoxState) {
24 /**
25 * @type {ChromeVoxState}
Peter Lundblad 2015/12/01 12:49:58 Make non-nullable.
dmazzoni 2015/12/01 19:19:01 Done.
26 * @private
27 */
28 this.chromeVoxState_ = chromeVoxState;
29
30 /**
31 * The time the last live region event was output.
32 * @type {Date}
Peter Lundblad 2015/12/01 12:49:58 Non-nullable?
dmazzoni 2015/12/01 19:19:01 Done.
33 * @private
34 */
35 this.lastLiveRegionTime_ = new Date(0);
36
37 /**
38 * Set of nodes that have been announced as part of a live region since
39 * |this.lastLiveRegionTime_|, to prevent duplicate announcements.
40 * @type {WeakSet<AutomationNode>}
Peter Lundblad 2015/12/01 12:49:58 Ditto.
dmazzoni 2015/12/01 19:19:01 Done.
41 * @private
42 */
43 this.liveRegionNodeSet_ = new WeakSet();
44
45 chrome.automation.addTreeChangeObserver(
46 'liveRegionTreeChanges', this.onTreeChange.bind(this));
47 };
48
49 /**
50 * Live region events received in fewer than this many milliseconds will
51 * queue, otherwise they'll be output with a category flush.
52 * @type {number}
53 * @const
54 */
55 LiveRegions.LIVE_REGION_QUEUE_TIME_MS = 500;
56
57 /**
58 * Whether live regions from background tabs should be announced or not.
59 * @private
Peter Lundblad 2015/12/01 12:49:58 @type ...
dmazzoni 2015/12/01 19:19:01 Done.
60 */
61 LiveRegions.announceLiveRegionsFromBackgroundTabs_ = true;
62
63 LiveRegions.prototype = {
64 /**
65 * Called when the automation tree is changed.
66 * @param {TreeChange} treeChange
67 */
68 onTreeChange: function(treeChange) {
69 var node = treeChange.target;
70 if (!node.containerLiveStatus)
71 return;
72
73 var mode = this.chromeVoxState_.mode;
74 var currentRange = this.chromeVoxState_.currentRange;
75
76 if (mode === ChromeVoxMode.CLASSIC || !cvox.ChromeVox.isActive)
77 return;
78
79 if (!currentRange)
80 return;
81
82 if (!LiveRegions.announceLiveRegionsFromBackgroundTabs_ &&
83 !AutomationUtil.isInSameWebpage(node, currentRange.start.node)) {
84 return;
85 }
86
87 var type = treeChange.type;
88 var relevant = node.containerLiveRelevant;
89 if (relevant.indexOf('additions') >= 0 &&
90 (type == 'nodeCreated' || type == 'subtreeCreated')) {
91 this.outputLiveRegionChange_(node, null);
92 }
93
94 if (relevant.indexOf('text') >= 0 && type == 'nodeChanged')
95 this.outputLiveRegionChange_(node, null);
96
97 if (relevant.indexOf('removals') >= 0 && type == 'nodeRemoved')
98 this.outputLiveRegionChange_(node, '@live_regions_removed');
99 },
100
101 /**
102 * Given a node that needs to be spoken as part of a live region
103 * change and an additional optional format string, output the
104 * live region description.
105 * @param {!AutomationNode} node The changed node.
106 * @param {?string=} opt_prependFormatStr If set, a format string for
107 * cvox2.Output to prepend to the output.
108 * @private
109 */
110 outputLiveRegionChange_: function(node, opt_prependFormatStr) {
111 if (node.containerLiveBusy)
112 return;
113
114 if (node.containerLiveAtomic && !node.liveAtomic) {
115 if (node.parent)
116 this.outputLiveRegionChange_(node.parent, opt_prependFormatStr);
117 return;
118 }
119
120 var range = cursors.Range.fromNode(node);
121 var output = new Output();
122 if (opt_prependFormatStr)
123 output.format(opt_prependFormatStr);
124 output.withSpeech(range, range, Output.EventType.NAVIGATE);
125
126 if (!output.hasSpeech && node.liveAtomic)
127 output.format('$descendants', node);
128
129 output.withSpeechCategory(cvox.TtsCategory.LIVE);
130
131 if (!output.hasSpeech)
132 return;
133
134 // Enqueue live region updates that were received at approximately
135 // the same time, otherwise flush previous live region updates.
136 var currentTime = new Date();
137 var queueTime = LiveRegions.LIVE_REGION_QUEUE_TIME_MS;
138 if (currentTime - this.lastLiveRegionTime_ > queueTime) {
139 this.liveRegionNodeSet_ = new WeakSet();
140 output.withQueueMode(cvox.QueueMode.CATEGORY_FLUSH);
141 this.lastLiveRegionTime_ = currentTime;
142 } else {
143 output.withQueueMode(cvox.QueueMode.QUEUE);
144 }
145
146 var parent = node;
147 while (parent) {
148 if (this.liveRegionNodeSet_.has(parent))
149 return;
150 parent = parent.parent;
151 }
152
153 this.liveRegionNodeSet_.add(node);
154 output.go();
155 },
156 };
157
158 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698