Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / common / time_widget.js
blob869189d6db4b34c4968c98cd5f3ac3af6742245b
1 // Copyright 2014 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.
5 goog.provide('cvox.ChromeVoxHTMLTimeWidget');
7 /**
8  * @fileoverview Gives the user spoken feedback as they interact with the time
9  * widget (input type=time).
10  *
11  */
13 /**
14  * A class containing the information needed to speak
15  * a text change event to the user.
16  *
17  * @constructor
18  * @param {Element} timeElem The time widget element.
19  * @param {cvox.TtsInterface} tts The TTS object from ChromeVox.
20  */
21 cvox.ChromeVoxHTMLTimeWidget = function(timeElem, tts) {
22   var self = this;
23   this.timeElem_ = timeElem;
24   this.timeTts_ = tts;
25   this.pHours_ = -1;
26   this.pMinutes_ = -1;
27   this.pSeconds_ = 0;
28   this.pMilliseconds_ = 0;
29   this.pAmpm_ = '';
30   this.pos_ = 0;
31   this.maxPos_ = 2;
32   this.keyListener_ = function(evt) {
33     self.eventHandler_(evt);
34   };
35   this.blurListener_ = function(evt) {
36     self.shutdown();
37   };
38   if (this.timeElem_.hasAttribute('step')) {
39     var step = this.timeElem_.getAttribute('step');
40     if (step > 0) { // 0 or invalid values show hh:mm AM/PM
41       if (step >= 1) {
42         this.maxPos_ = 3; // Anything larger than 1 shows hh:mm:ss AM/PM
43       } else {
44         this.maxPos_ = 4; // Anything less than 1 shows hh:mm:ss.ms AM/PM
45       }
46     }
47   }
49   // Ensure we have a reasonable value to start with.
50   if (this.timeElem_.value.length == 0) {
51     this.forceInitTime_();
52   }
54   // Move the cursor to the first position so that we are guaranteed to start
55   // off at the hours position.
56   for (var i = 0; i < this.maxPos_; i++) {
57     var evt = document.createEvent('KeyboardEvent');
58     evt.initKeyboardEvent(
59           'keydown', true, true, window, 'Left', 0, false, false, false, false);
60     this.timeElem_.dispatchEvent(evt);
61     evt = document.createEvent('KeyboardEvent');
62     evt.initKeyboardEvent(
63           'keyup', true, true, window, 'Left', 0, false, false, false, false);
64     this.timeElem_.dispatchEvent(evt);
65   }
67   this.timeElem_.addEventListener('keydown', this.keyListener_, false);
68   this.timeElem_.addEventListener('keyup', this.keyListener_, false);
69   this.timeElem_.addEventListener('blur', this.blurListener_, false);
70   this.update_(true);
73 /**
74  * Removes the key listeners for the time widget.
75  *
76  */
77 cvox.ChromeVoxHTMLTimeWidget.prototype.shutdown = function() {
78   this.timeElem_.removeEventListener('blur', this.blurListener_, false);
79   this.timeElem_.removeEventListener('keydown', this.keyListener_, false);
80   this.timeElem_.removeEventListener('keyup', this.keyListener_, false);
83 /**
84  * Initialize to midnight.
85  * @private
86  */
87 cvox.ChromeVoxHTMLTimeWidget.prototype.forceInitTime_ = function() {
88   this.timeElem_.setAttribute('value', '12:00');
91 /**
92  * Called when the position changes.
93  * @private
94  */
95 cvox.ChromeVoxHTMLTimeWidget.prototype.handlePosChange_ = function() {
96   if (this.pos_ < 0) {
97     this.pos_ = 0;
98   }
99   if (this.pos_ > this.maxPos_) {
100     this.pos_ = this.maxPos_;
101   }
102   // Reset the cached state of the new field so that the field will be spoken
103   // in the update.
104   if (this.pos_ == this.maxPos_) {
105     this.pAmpm_ = '';
106     return;
107   }
108   switch (this.pos_) {
109     case 0:
110       this.pHours_ = -1;
111       break;
112     case 1:
113       this.pMinutes_ = -1;
114       break;
115     case 2:
116       this.pSeconds_ = -1;
117       break;
118     case 3:
119       this.pMilliseconds_ = -1;
120       break;
121   }
125  * @param {boolean} shouldSpeakLabel True if the label should be spoken.
126  * @private
127  */
128 cvox.ChromeVoxHTMLTimeWidget.prototype.update_ = function(shouldSpeakLabel) {
129   var splitTime = this.timeElem_.value.split(':');
130   if (splitTime.length < 1) {
131     this.forceInitTime_();
132     return;
133   }
135   var hours = splitTime[0];
136   var minutes = -1;
137   var seconds = 0;
138   var milliseconds = 0;
139   var ampm = cvox.ChromeVox.msgs.getMsg('timewidget_am');
140   if (splitTime.length > 1) {
141     minutes = splitTime[1];
142   }
143   if (splitTime.length > 2) {
144     var splitSecondsAndMilliseconds = splitTime[2].split('.');
145     seconds = splitSecondsAndMilliseconds[0];
146     if (splitSecondsAndMilliseconds.length > 1) {
147       milliseconds = splitSecondsAndMilliseconds[1];
148     }
149   }
150   if (hours > 12) {
151     hours = hours - 12;
152     ampm = cvox.ChromeVox.msgs.getMsg('timewidget_pm');
153   }
154   if (hours == 12) {
155     ampm = cvox.ChromeVox.msgs.getMsg('timewidget_pm');
156   }
157   if (hours == 0) {
158     hours = 12;
159     ampm = cvox.ChromeVox.msgs.getMsg('timewidget_am');
160   }
162   var changeMessage = '';
164   if (shouldSpeakLabel) {
165     changeMessage = cvox.DomUtil.getName(this.timeElem_, true, true) + '\n';
166   }
168   if (hours != this.pHours_) {
169     changeMessage = changeMessage + hours + ' ' +
170         cvox.ChromeVox.msgs.getMsg('timewidget_hours') + '\n';
171     this.pHours_ = hours;
172   }
174   if (minutes != this.pMinutes_) {
175     changeMessage = changeMessage + minutes + ' ' +
176         cvox.ChromeVox.msgs.getMsg('timewidget_minutes') + '\n';
177     this.pMinutes_ = minutes;
178   }
180   if (seconds != this.pSeconds_) {
181     changeMessage = changeMessage + seconds + ' ' +
182         cvox.ChromeVox.msgs.getMsg('timewidget_seconds') + '\n';
183     this.pSeconds_ = seconds;
184   }
186   if (milliseconds != this.pMilliseconds_) {
187     changeMessage = changeMessage + milliseconds + ' ' +
188         cvox.ChromeVox.msgs.getMsg('timewidget_milliseconds') + '\n';
189     this.pMilliseconds_ = milliseconds;
190   }
192   if (ampm != this.pAmpm_) {
193     changeMessage = changeMessage + ampm;
194     this.pAmpm_ = ampm;
195   }
197   if (changeMessage.length > 0) {
198     this.timeTts_.speak(changeMessage, cvox.QueueMode.FLUSH, null);
199   }
203  * @param {Object} evt The event to handle.
204  * @private
205  */
206 cvox.ChromeVoxHTMLTimeWidget.prototype.eventHandler_ = function(evt) {
207   var shouldSpeakLabel = false;
208   if (evt.type == 'keydown') {
209     if (((evt.keyCode == 9) && !evt.shiftKey) || (evt.keyCode == 39)) {
210       this.pos_++;
211       this.handlePosChange_();
212       shouldSpeakLabel = true;
213     }
214     if (((evt.keyCode == 9) && evt.shiftKey) || (evt.keyCode == 37)) {
215       this.pos_--;
216       this.handlePosChange_();
217       shouldSpeakLabel = true;
218     }
219   }
220   this.update_(shouldSpeakLabel);