| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 (function() { | 5 (function() { |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * Moves |target| element above |anchor| element, in order to match the | 9 * Moves |target| element above |anchor| element, in order to match the |
| 10 * bottom lines. | 10 * bottom lines. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 is: 'control-panel', | 29 is: 'control-panel', |
| 30 | 30 |
| 31 properties: { | 31 properties: { |
| 32 /** | 32 /** |
| 33 * Flag whether the audio is playing or paused. True if playing, or false | 33 * Flag whether the audio is playing or paused. True if playing, or false |
| 34 * paused. | 34 * paused. |
| 35 */ | 35 */ |
| 36 playing: { | 36 playing: { |
| 37 type: Boolean, | 37 type: Boolean, |
| 38 value: false, | 38 value: false, |
| 39 notify: true | 39 notify: true, |
| 40 reflectToAttribute: true, |
| 41 observer: 'playingChanged_' |
| 40 }, | 42 }, |
| 41 | 43 |
| 42 /** | 44 /** |
| 43 * Current elapsed time in the current music in millisecond. | 45 * Current elapsed time in the current music in millisecond. |
| 44 */ | 46 */ |
| 45 time: { | 47 time: { |
| 46 type: Number, | 48 type: Number, |
| 47 value: 0, | 49 value: 0, |
| 48 notify: true | 50 notify: true |
| 49 }, | 51 }, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 }, | 94 }, |
| 93 | 95 |
| 94 /** | 96 /** |
| 95 * Whether the volume slider is expanded or not. | 97 * Whether the volume slider is expanded or not. |
| 96 */ | 98 */ |
| 97 volumeSliderShown: { | 99 volumeSliderShown: { |
| 98 type: Boolean, | 100 type: Boolean, |
| 99 value: false, | 101 value: false, |
| 100 observer: 'volumeSliderShownChanged', | 102 observer: 'volumeSliderShownChanged', |
| 101 notify: true | 103 notify: true |
| 104 }, |
| 105 |
| 106 /** |
| 107 * Whether the knob of time slider is being dragged. |
| 108 */ |
| 109 dragging: { |
| 110 type: Boolean, |
| 111 value: false, |
| 112 notify: true |
| 113 }, |
| 114 |
| 115 /** |
| 116 * Dictionary which contains aria-labels for each controls. |
| 117 */ |
| 118 ariaLabels: { |
| 119 type: Object, |
| 120 observer: 'ariaLabelsChanged_' |
| 102 } | 121 } |
| 103 }, | 122 }, |
| 104 | 123 |
| 105 /** | 124 /** |
| 106 * Initializes an element. This method is called automatically when the | 125 * Initializes an element. This method is called automatically when the |
| 107 * element is ready. | 126 * element is ready. |
| 108 */ | 127 */ |
| 109 ready: function() { | 128 ready: function() { |
| 110 var onFocusoutBound = this.onVolumeControllerFocusout_.bind(this); | 129 var onFocusoutBound = this.onVolumeControllerFocusout_.bind(this); |
| 111 | 130 |
| 112 this.$.volumeSlider.addEventListener('focusout', onFocusoutBound); | 131 this.$.volumeSlider.addEventListener('focusout', onFocusoutBound); |
| 113 this.$.volumeButton.addEventListener('focusout', onFocusoutBound); | 132 this.$.volumeButton.addEventListener('focusout', onFocusoutBound); |
| 114 | 133 |
| 115 // Prevent the time slider from being moved by arrow keys. | 134 this.$.timeSlider.addEventListener('value-change', function() { |
| 116 this.$.timeInput.addEventListener('keydown', function(event) { | 135 if (this.dragging) |
| 117 switch (event.keyCode) { | 136 this.dragging = false; |
| 118 case 37: // Left arrow | 137 }.bind(this)); |
| 119 case 38: // Up arrow | 138 this.$.timeSlider.addEventListener('immediate-value-change', function() { |
| 120 case 39: // Right arrow | 139 if (!this.dragging) |
| 121 case 40: // Down arrow | 140 this.dragging = true; |
| 122 event.preventDefault(); | 141 }.bind(this)); |
| 123 break; | |
| 124 }; | |
| 125 }); | |
| 126 }, | 142 }, |
| 127 | 143 |
| 128 /** | 144 /** |
| 129 * Invoked when the next button is clicked. | 145 * Invoked when the next button is clicked. |
| 130 */ | 146 */ |
| 131 nextClick: function() { | 147 nextClick: function() { |
| 132 this.fire('next-clicked'); | 148 this.fire('next-clicked'); |
| 133 }, | 149 }, |
| 134 | 150 |
| 135 /** | 151 /** |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 /** | 203 /** |
| 188 * Converts the time into human friendly string. | 204 * Converts the time into human friendly string. |
| 189 * @param {number} time Time to be converted. | 205 * @param {number} time Time to be converted. |
| 190 * @return {string} String representation of the given time | 206 * @return {string} String representation of the given time |
| 191 */ | 207 */ |
| 192 time2string_: function(time) { | 208 time2string_: function(time) { |
| 193 return ~~(time / 60000) + ':' + ('0' + ~~(time / 1000 % 60)).slice(-2); | 209 return ~~(time / 60000) + ':' + ('0' + ~~(time / 1000 % 60)).slice(-2); |
| 194 }, | 210 }, |
| 195 | 211 |
| 196 /** | 212 /** |
| 197 * Computes state for play button based on 'playing' property. | 213 * Converts the time and duration into human friendly string. |
| 198 * @return {string} | 214 * @param {number} time Time to be converted. |
| 215 * @param {number} duration Duration to be converted. |
| 216 * @return {string} String representation of the given time |
| 199 */ | 217 */ |
| 200 computePlayState_: function(playing) { | 218 computeTimeString_: function(time, duration) { |
| 201 return playing ? "playing" : "ended"; | 219 return this.time2string_(time) + ' / ' + this.time2string_(duration); |
| 202 }, | 220 }, |
| 203 | 221 |
| 204 /** | 222 /** |
| 205 * Computes style for '.filled' element of progress bar. | 223 * Invoked when the playing property is changed. |
| 206 * @return {string} | 224 * @param {boolean} playing |
| 225 * @private |
| 207 */ | 226 */ |
| 208 computeProgressBarStyle_: function(time, duration) { | 227 playingChanged_: function(playing) { |
| 209 return 'width: ' + (time / duration * 100) + '%;'; | 228 if (this.ariaLabels) { |
| 229 this.$.play.setAttribute('aria-label', |
| 230 playing ? this.ariaLabels.pause : this.ariaLabels.play); |
| 231 } |
| 232 }, |
| 233 |
| 234 /** |
| 235 * Invoked when the ariaLabels property is changed. |
| 236 * @param {Object} ariaLabels |
| 237 * @private |
| 238 */ |
| 239 ariaLabelsChanged_: function(ariaLabels) { |
| 240 assert(ariaLabels); |
| 241 // TODO(fukino): Use data bindings. |
| 242 this.$.volumeSlider.setAttribute('aria-label', ariaLabels.volumeSlider); |
| 243 this.$.shuffle.setAttribute('aria-label', ariaLabels.shuffle); |
| 244 this.$.repeat.setAttribute('aria-label', ariaLabels.repeat); |
| 245 this.$.previous.setAttribute('aria-label', ariaLabels.previous); |
| 246 this.$.play.setAttribute('aria-label', |
| 247 this.playing ? ariaLabels.pause : ariaLabels.play); |
| 248 this.$.next.setAttribute('aria-label', ariaLabels.next); |
| 249 this.$.volumeButton.setAttribute('aria-label', ariaLabels.volume); |
| 250 this.$.playList.setAttribute('aria-label', ariaLabels.playList); |
| 251 this.$.timeSlider.setAttribute('aria-label', ariaLabels.seekSlider); |
| 210 } | 252 } |
| 211 }); | 253 }); |
| 212 })(); // Anonymous closure | 254 })(); // Anonymous closure |
| OLD | NEW |