[Extensions] Make extension message bubble factory platform-abstract
[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).
13 /**
14 * A class containing the information needed to speak
15 * a text change event to the user.
17 * @constructor
18 * @param {Element} timeElem The time widget element.
19 * @param {cvox.TtsInterface} tts The TTS object from ChromeVox.
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);
35 this.blurListener_ = function(evt) {
36 self.shutdown();
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
49 // Ensure we have a reasonable value to start with.
50 if (this.timeElem_.value.length == 0) {
51 this.forceInitTime_();
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);
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.
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
87 cvox.ChromeVoxHTMLTimeWidget.prototype.forceInitTime_ = function() {
88 this.timeElem_.setAttribute('value', '12:00');
91 /**
92 * Called when the position changes.
93 * @private
95 cvox.ChromeVoxHTMLTimeWidget.prototype.handlePosChange_ = function() {
96 if (this.pos_ < 0) {
97 this.pos_ = 0;
99 if (this.pos_ > this.maxPos_) {
100 this.pos_ = this.maxPos_;
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;
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;
125 * @param {boolean} shouldSpeakLabel True if the label should be spoken.
126 * @private
128 cvox.ChromeVoxHTMLTimeWidget.prototype.update_ = function(shouldSpeakLabel) {
129 var splitTime = this.timeElem_.value.split(':');
130 if (splitTime.length < 1) {
131 this.forceInitTime_();
132 return;
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];
143 if (splitTime.length > 2) {
144 var splitSecondsAndMilliseconds = splitTime[2].split('.');
145 seconds = splitSecondsAndMilliseconds[0];
146 if (splitSecondsAndMilliseconds.length > 1) {
147 milliseconds = splitSecondsAndMilliseconds[1];
150 if (hours > 12) {
151 hours = hours - 12;
152 ampm = cvox.ChromeVox.msgs.getMsg('timewidget_pm');
154 if (hours == 12) {
155 ampm = cvox.ChromeVox.msgs.getMsg('timewidget_pm');
157 if (hours == 0) {
158 hours = 12;
159 ampm = cvox.ChromeVox.msgs.getMsg('timewidget_am');
162 var changeMessage = '';
164 if (shouldSpeakLabel) {
165 changeMessage = cvox.DomUtil.getName(this.timeElem_, true, true) + '\n';
168 if (hours != this.pHours_) {
169 changeMessage = changeMessage + hours + ' ' +
170 cvox.ChromeVox.msgs.getMsg('timewidget_hours') + '\n';
171 this.pHours_ = hours;
174 if (minutes != this.pMinutes_) {
175 changeMessage = changeMessage + minutes + ' ' +
176 cvox.ChromeVox.msgs.getMsg('timewidget_minutes') + '\n';
177 this.pMinutes_ = minutes;
180 if (seconds != this.pSeconds_) {
181 changeMessage = changeMessage + seconds + ' ' +
182 cvox.ChromeVox.msgs.getMsg('timewidget_seconds') + '\n';
183 this.pSeconds_ = seconds;
186 if (milliseconds != this.pMilliseconds_) {
187 changeMessage = changeMessage + milliseconds + ' ' +
188 cvox.ChromeVox.msgs.getMsg('timewidget_milliseconds') + '\n';
189 this.pMilliseconds_ = milliseconds;
192 if (ampm != this.pAmpm_) {
193 changeMessage = changeMessage + ampm;
194 this.pAmpm_ = ampm;
197 if (changeMessage.length > 0) {
198 this.timeTts_.speak(changeMessage, cvox.QueueMode.FLUSH, null);
203 * @param {Object} evt The event to handle.
204 * @private
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;
214 if (((evt.keyCode == 9) && evt.shiftKey) || (evt.keyCode == 37)) {
215 this.pos_--;
216 this.handlePosChange_();
217 shouldSpeakLabel = true;
220 this.update_(shouldSpeakLabel);