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

Side by Side Diff: ui/file_manager/video_player/js/media_controls.js

Issue 1441603002: Revert of Fix accessibility issues in AudioPlayer and VideoPlayer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 /** 5 /**
6 * @fileoverview MediaControls class implements media playback controls 6 * @fileoverview MediaControls class implements media playback controls
7 * that exist outside of the audio/video HTML element. 7 * that exist outside of the audio/video HTML element.
8 */ 8 */
9 9
10 /** 10 /**
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 if (seconds < 10) result += '0'; 113 if (seconds < 10) result += '0';
114 result += seconds; 114 result += seconds;
115 return result; 115 return result;
116 }; 116 };
117 117
118 /** 118 /**
119 * Create a custom control. 119 * Create a custom control.
120 * 120 *
121 * @param {string} className Class name. 121 * @param {string} className Class name.
122 * @param {HTMLElement=} opt_parent Parent element or container if undefined. 122 * @param {HTMLElement=} opt_parent Parent element or container if undefined.
123 * @param {string=} opt_tagName Tag name of the control. 'div' if undefined.
124 * @return {!HTMLElement} The new control element. 123 * @return {!HTMLElement} The new control element.
125 */ 124 */
126 MediaControls.prototype.createControl = 125 MediaControls.prototype.createControl = function(className, opt_parent) {
127 function(className, opt_parent, opt_tagName) {
128 var parent = opt_parent || this.container_; 126 var parent = opt_parent || this.container_;
129 var control = /** @type {!HTMLElement} */ 127 var control = assertInstanceof(this.document_.createElement('div'),
130 (this.document_.createElement(opt_tagName || 'div')); 128 HTMLDivElement);
131 control.className = className; 129 control.className = className;
132 parent.appendChild(control); 130 parent.appendChild(control);
133 return control; 131 return control;
134 }; 132 };
135 133
136 /** 134 /**
137 * Create a custom button. 135 * Create a custom button.
138 * 136 *
139 * @param {string} className Class name. 137 * @param {string} className Class name.
140 * @param {function(Event)=} opt_handler Click handler. 138 * @param {function(Event)=} opt_handler Click handler.
141 * @param {HTMLElement=} opt_parent Parent element or container if undefined. 139 * @param {HTMLElement=} opt_parent Parent element or container if undefined.
142 * @param {number=} opt_numStates Number of states, default: 1. 140 * @param {number=} opt_numStates Number of states, default: 1.
143 * @return {!HTMLElement} The new button element. 141 * @return {!HTMLElement} The new button element.
144 */ 142 */
145 MediaControls.prototype.createButton = function( 143 MediaControls.prototype.createButton = function(
146 className, opt_handler, opt_parent, opt_numStates) { 144 className, opt_handler, opt_parent, opt_numStates) {
147 opt_numStates = opt_numStates || 1; 145 opt_numStates = opt_numStates || 1;
148 146
149 var button = this.createControl(className, opt_parent, 'files-icon-button'); 147 var button = this.createControl(className, opt_parent);
150 button.classList.add('media-button'); 148 button.classList.add('media-button');
151 149
152 button.setAttribute('state', MediaControls.ButtonStateType.DEFAULT); 150 button.setAttribute('state', MediaControls.ButtonStateType.DEFAULT);
153 151
154 if (opt_handler) 152 if (opt_handler)
155 button.addEventListener('click', opt_handler); 153 button.addEventListener('click', opt_handler);
156 154
157 return button; 155 return button;
158 }; 156 };
159 157
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 MediaControls.prototype.onPlayButtonClicked = function(event) { 223 MediaControls.prototype.onPlayButtonClicked = function(event) {
226 this.togglePlayState(); 224 this.togglePlayState();
227 }; 225 };
228 226
229 /** 227 /**
230 * @param {HTMLElement=} opt_parent Parent container. 228 * @param {HTMLElement=} opt_parent Parent container.
231 */ 229 */
232 MediaControls.prototype.initPlayButton = function(opt_parent) { 230 MediaControls.prototype.initPlayButton = function(opt_parent) {
233 this.playButton_ = this.createButton('play media-control', 231 this.playButton_ = this.createButton('play media-control',
234 this.onPlayButtonClicked.bind(this), opt_parent, 3 /* States. */); 232 this.onPlayButtonClicked.bind(this), opt_parent, 3 /* States. */);
235 this.playButton_.setAttribute('aria-label',
236 str('MEDIA_PLAYER_PLAY_BUTTON_LABEL'));
237 }; 233 };
238 234
239 /* 235 /*
240 * Time controls 236 * Time controls
241 */ 237 */
242 238
243 /** 239 /**
244 * The default range of 100 is too coarse for the media progress slider. 240 * The default range of 100 is too coarse for the media progress slider.
245 */ 241 */
246 MediaControls.PROGRESS_RANGE = 5000; 242 MediaControls.PROGRESS_RANGE = 5000;
247 243
248 /** 244 /**
249 * @param {HTMLElement=} opt_parent Parent container. 245 * @param {HTMLElement=} opt_parent Parent container.
250 */ 246 */
251 MediaControls.prototype.initTimeControls = function(opt_parent) { 247 MediaControls.prototype.initTimeControls = function(opt_parent) {
252 var timeControls = this.createControl('time-controls', opt_parent); 248 var timeControls = this.createControl('time-controls', opt_parent);
253 249
254 var timeBox = this.createControl('time media-control', timeControls); 250 var timeBox = this.createControl('time media-control', timeControls);
255 251
256 this.currentTimeSpacer_ = this.createControl('spacer', timeBox); 252 this.currentTimeSpacer_ = this.createControl('spacer', timeBox);
257 this.currentTime_ = this.createControl('current', timeBox); 253 this.currentTime_ = this.createControl('current', timeBox);
258 // Set the initial width to the minimum to reduce the flicker. 254 // Set the initial width to the minimum to reduce the flicker.
259 this.updateTimeLabel_(0, 0); 255 this.updateTimeLabel_(0, 0);
260 256
261 this.progressSlider_ = /** @type {!PaperSliderElement} */ ( 257 this.progressSlider_ = /** @type {!PaperSliderElement} */ (
262 document.createElement('paper-slider')); 258 document.createElement('paper-slider'));
263 this.progressSlider_.classList.add('progress', 'media-control'); 259 this.progressSlider_.classList.add('progress', 'media-control');
264 this.progressSlider_.max = MediaControls.PROGRESS_RANGE; 260 this.progressSlider_.max = MediaControls.PROGRESS_RANGE;
265 this.progressSlider_.setAttribute('aria-label',
266 str('MEDIA_PLAYER_SEEK_SLIDER_LABEL'));
267 this.progressSlider_.addEventListener('change', function(event) { 261 this.progressSlider_.addEventListener('change', function(event) {
268 this.onProgressChange_(this.progressSlider_.ratio); 262 this.onProgressChange_(this.progressSlider_.ratio);
269 }.bind(this)); 263 }.bind(this));
270 this.progressSlider_.addEventListener( 264 this.progressSlider_.addEventListener(
271 'immediate-value-change', 265 'immediate-value-change',
272 function(event) { 266 function(event) {
273 this.onProgressDrag_(); 267 this.onProgressDrag_();
274 }.bind(this)); 268 }.bind(this));
275 timeControls.appendChild(this.progressSlider_); 269 timeControls.appendChild(this.progressSlider_);
276 }; 270 };
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 378
385 /** 379 /**
386 * @param {HTMLElement=} opt_parent Parent element for the controls. 380 * @param {HTMLElement=} opt_parent Parent element for the controls.
387 */ 381 */
388 MediaControls.prototype.initVolumeControls = function(opt_parent) { 382 MediaControls.prototype.initVolumeControls = function(opt_parent) {
389 var volumeControls = this.createControl('volume-controls', opt_parent); 383 var volumeControls = this.createControl('volume-controls', opt_parent);
390 384
391 this.soundButton_ = this.createButton('sound media-control', 385 this.soundButton_ = this.createButton('sound media-control',
392 this.onSoundButtonClick_.bind(this), volumeControls); 386 this.onSoundButtonClick_.bind(this), volumeControls);
393 this.soundButton_.setAttribute('level', 3); // max level. 387 this.soundButton_.setAttribute('level', 3); // max level.
394 this.soundButton_.setAttribute('aria-label',
395 str('MEDIA_PLAYER_MUTE_BUTTON_LABEL'));
396 388
397 this.volume_ = /** @type {!PaperSliderElement} */ ( 389 this.volume_ = /** @type {!PaperSliderElement} */ (
398 document.createElement('paper-slider')); 390 document.createElement('paper-slider'));
399 this.volume_.classList.add('volume', 'media-control'); 391 this.volume_.classList.add('volume', 'media-control');
400 this.volume_.setAttribute('aria-label',
401 str('MEDIA_PLAYER_VOLUME_SLIDER_LABEL'));
402 this.volume_.addEventListener('change', function(event) { 392 this.volume_.addEventListener('change', function(event) {
403 this.onVolumeChange_(this.volume_.ratio); 393 this.onVolumeChange_(this.volume_.ratio);
404 }.bind(this)); 394 }.bind(this));
405 this.volume_.addEventListener('immediate-value-change', function(event) { 395 this.volume_.addEventListener('immediate-value-change', function(event) {
406 this.onVolumeDrag_(); 396 this.onVolumeDrag_();
407 }.bind(this)); 397 }.bind(this));
408 this.volume_.value = this.volume_.max; 398 this.volume_.value = this.volume_.max;
409 volumeControls.appendChild(this.volume_); 399 volumeControls.appendChild(this.volume_);
410 }; 400 };
411 401
412 /** 402 /**
413 * Click handler for the sound level button. 403 * Click handler for the sound level button.
414 * @private 404 * @private
415 */ 405 */
416 MediaControls.prototype.onSoundButtonClick_ = function() { 406 MediaControls.prototype.onSoundButtonClick_ = function() {
417 if (this.media_.volume == 0) { 407 if (this.media_.volume == 0) {
418 this.volume_.value = (this.savedVolume_ || 1) * this.volume_.max; 408 this.volume_.value = (this.savedVolume_ || 1) * this.volume_.max;
419 this.soundButton_.setAttribute('aria-label',
420 str('MEDIA_PLAYER_MUTE_BUTTON_LABEL'));
421 } else { 409 } else {
422 this.savedVolume_ = this.media_.volume; 410 this.savedVolume_ = this.media_.volume;
423 this.volume_.value = 0; 411 this.volume_.value = 0;
424 this.soundButton_.setAttribute('aria-label',
425 str('MEDIA_PLAYER_UNMUTE_BUTTON_LABEL'));
426 } 412 }
427 this.onVolumeChange_(this.volume_.ratio); 413 this.onVolumeChange_(this.volume_.ratio);
428 }; 414 };
429 415
430 /** 416 /**
431 * @param {number} value Volume [0..1]. 417 * @param {number} value Volume [0..1].
432 * @return {number} The rough level [0..3] used to pick an icon. 418 * @return {number} The rough level [0..3] used to pick an icon.
433 * @private 419 * @private
434 */ 420 */
435 MediaControls.getVolumeLevel_ = function(value) { 421 MediaControls.getVolumeLevel_ = function(value) {
436 if (value == 0) return 0; 422 if (value == 0) return 0;
437 if (value <= 1 / 3) return 1; 423 if (value <= 1 / 3) return 1;
438 if (value <= 2 / 3) return 2; 424 if (value <= 2 / 3) return 2;
439 return 3; 425 return 3;
440 }; 426 };
441 427
442 /** 428 /**
443 * @param {number} value Volume [0..1]. 429 * @param {number} value Volume [0..1].
444 * @private 430 * @private
445 */ 431 */
446 MediaControls.prototype.onVolumeChange_ = function(value) { 432 MediaControls.prototype.onVolumeChange_ = function(value) {
447 if (!this.media_) 433 if (!this.media_)
448 return; // Media is detached. 434 return; // Media is detached.
449 435
450 this.media_.volume = value; 436 this.media_.volume = value;
451 this.soundButton_.setAttribute('level', MediaControls.getVolumeLevel_(value)); 437 this.soundButton_.setAttribute('level', MediaControls.getVolumeLevel_(value));
452 this.soundButton_.setAttribute('aria-label',
453 value === 0 ? str('MEDIA_PLAYER_UNMUTE_BUTTON_LABEL')
454 : str('MEDIA_PLAYER_MUTE_BUTTON_LABEL'));
455 }; 438 };
456 439
457 /** 440 /**
458 * @private 441 * @private
459 */ 442 */
460 MediaControls.prototype.onVolumeDrag_ = function() { 443 MediaControls.prototype.onVolumeDrag_ = function() {
461 if (this.media_.volume !== 0) { 444 if (this.media_.volume !== 0) {
462 this.savedVolume_ = this.media_.volume; 445 this.savedVolume_ = this.media_.volume;
463 } 446 }
464 }; 447 };
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 /** 582 /**
600 * Updates the play button state. 583 * Updates the play button state.
601 * @param {boolean} playing If the video is playing. 584 * @param {boolean} playing If the video is playing.
602 * @private 585 * @private
603 */ 586 */
604 MediaControls.prototype.updatePlayButtonState_ = function(playing) { 587 MediaControls.prototype.updatePlayButtonState_ = function(playing) {
605 if (this.media_.ended && 588 if (this.media_.ended &&
606 this.progressSlider_.value === this.progressSlider_.max) { 589 this.progressSlider_.value === this.progressSlider_.max) {
607 this.playButton_.setAttribute('state', 590 this.playButton_.setAttribute('state',
608 MediaControls.ButtonStateType.ENDED); 591 MediaControls.ButtonStateType.ENDED);
609 this.playButton_.setAttribute('aria-label',
610 str('MEDIA_PLAYER_PLAY_BUTTON_LABEL'));
611 } else if (playing) { 592 } else if (playing) {
612 this.playButton_.setAttribute('state', 593 this.playButton_.setAttribute('state',
613 MediaControls.ButtonStateType.PLAYING); 594 MediaControls.ButtonStateType.PLAYING);
614 this.playButton_.setAttribute('aria-label',
615 str('MEDIA_PLAYER_PAUSE_BUTTON_LABEL'));
616 } else { 595 } else {
617 this.playButton_.setAttribute('state', 596 this.playButton_.setAttribute('state',
618 MediaControls.ButtonStateType.DEFAULT); 597 MediaControls.ButtonStateType.DEFAULT);
619 this.playButton_.setAttribute('aria-label',
620 str('MEDIA_PLAYER_PLAY_BUTTON_LABEL'));
621 } 598 }
622 }; 599 };
623 600
624 /** 601 /**
625 * Restore play state. Base implementation is empty. 602 * Restore play state. Base implementation is empty.
626 */ 603 */
627 MediaControls.prototype.restorePlayState = function() {}; 604 MediaControls.prototype.restorePlayState = function() {};
628 605
629 /** 606 /**
630 * Encode current state into the page URL or the app state. 607 * Encode current state into the page URL or the app state.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 delete window.appState.time; 642 delete window.appState.time;
666 util.saveAppState(); 643 util.saveAppState();
667 return; 644 return;
668 }; 645 };
669 646
670 /** 647 /**
671 * Create video controls. 648 * Create video controls.
672 * 649 *
673 * @param {!HTMLElement} containerElement The container for the controls. 650 * @param {!HTMLElement} containerElement The container for the controls.
674 * @param {function(Event)} onMediaError Function to display an error message. 651 * @param {function(Event)} onMediaError Function to display an error message.
652 * @param {function(string):string} stringFunction Function providing localized
653 * strings.
675 * @param {function(Event)=} opt_fullScreenToggle Function to toggle fullscreen 654 * @param {function(Event)=} opt_fullScreenToggle Function to toggle fullscreen
676 * mode. 655 * mode.
677 * @param {HTMLElement=} opt_stateIconParent The parent for the icon that 656 * @param {HTMLElement=} opt_stateIconParent The parent for the icon that
678 * gives visual feedback when the playback state changes. 657 * gives visual feedback when the playback state changes.
679 * @constructor 658 * @constructor
680 * @struct 659 * @struct
681 * @extends {MediaControls} 660 * @extends {MediaControls}
682 */ 661 */
683 function VideoControls( 662 function VideoControls(containerElement, onMediaError, stringFunction,
684 containerElement, onMediaError, opt_fullScreenToggle, opt_stateIconParent) { 663 opt_fullScreenToggle, opt_stateIconParent) {
685 MediaControls.call(this, containerElement, onMediaError); 664 MediaControls.call(this, containerElement, onMediaError);
665 this.stringFunction_ = stringFunction;
686 666
687 this.container_.classList.add('video-controls'); 667 this.container_.classList.add('video-controls');
688 this.initPlayButton(); 668 this.initPlayButton();
689 this.initTimeControls(); 669 this.initTimeControls();
690 this.initVolumeControls(); 670 this.initVolumeControls();
691 671
692 // Create the cast button. 672 // Create the cast button.
693 // We need to use <button> since cr.ui.MenuButton.decorate modifies prototype 673 this.castButton_ = this.createButton('cast menubutton');
694 // chain, by which <files-icon-button> will not work correctly.
695 // TODO(fukino): Find a way to use files-icon-button consistently.
696 this.castButton_ = this.createControl(
697 'cast media-button', undefined, 'button');
698 this.castButton_.setAttribute('menu', '#cast-menu'); 674 this.castButton_.setAttribute('menu', '#cast-menu');
699 this.castButton_.setAttribute('aria-label', str('VIDEO_PLAYER_PLAY_ON')); 675 this.castButton_.setAttribute(
700 this.castButton_.setAttribute('state', MediaControls.ButtonStateType.DEFAULT); 676 'label', this.stringFunction_('VIDEO_PLAYER_PLAY_ON'));
701 this.castButton_.appendChild(document.createElement('files-ripple'));
702 cr.ui.decorate(this.castButton_, cr.ui.MenuButton); 677 cr.ui.decorate(this.castButton_, cr.ui.MenuButton);
703 678
704 if (opt_fullScreenToggle) { 679 if (opt_fullScreenToggle) {
705 this.fullscreenButton_ = 680 this.fullscreenButton_ =
706 this.createButton('fullscreen', opt_fullScreenToggle); 681 this.createButton('fullscreen', opt_fullScreenToggle);
707 this.fullscreenButton_.setAttribute('aria-label',
708 str('VIDEO_PLAYER_FULL_SCREEN_BUTTON_LABEL'));
709 } 682 }
710 683
711 if (opt_stateIconParent) { 684 if (opt_stateIconParent) {
712 this.stateIcon_ = this.createControl( 685 this.stateIcon_ = this.createControl(
713 'playback-state-icon', opt_stateIconParent); 686 'playback-state-icon', opt_stateIconParent);
714 this.textBanner_ = this.createControl('text-banner', opt_stateIconParent); 687 this.textBanner_ = this.createControl('text-banner', opt_stateIconParent);
715 } 688 }
716 689
717 // Disables all controls at first. 690 // Disables all controls at first.
718 this.enableControls_(false); 691 this.enableControls_(false);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 }; 737 };
765 738
766 /** 739 /**
767 * Shows a text banner. 740 * Shows a text banner.
768 * 741 *
769 * @param {string} identifier String identifier. 742 * @param {string} identifier String identifier.
770 * @private 743 * @private
771 */ 744 */
772 VideoControls.prototype.showTextBanner_ = function(identifier) { 745 VideoControls.prototype.showTextBanner_ = function(identifier) {
773 this.textBanner_.removeAttribute('visible'); 746 this.textBanner_.removeAttribute('visible');
774 this.textBanner_.textContent = str(identifier); 747 this.textBanner_.textContent = this.stringFunction_(identifier);
775 748
776 setTimeout(function() { 749 setTimeout(function() {
777 var onAnimationEnd = function(event) { 750 var onAnimationEnd = function(event) {
778 this.textBanner_.removeEventListener( 751 this.textBanner_.removeEventListener(
779 'webkitAnimationEnd', onAnimationEnd); 752 'webkitAnimationEnd', onAnimationEnd);
780 this.textBanner_.removeAttribute('visible'); 753 this.textBanner_.removeAttribute('visible');
781 }.bind(this); 754 }.bind(this);
782 this.textBanner_.addEventListener('webkitAnimationEnd', onAnimationEnd); 755 this.textBanner_.addEventListener('webkitAnimationEnd', onAnimationEnd);
783 756
784 this.textBanner_.setAttribute('visible', 'true'); 757 this.textBanner_.setAttribute('visible', 'true');
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 var hideBelow = function(selector, limit) { 882 var hideBelow = function(selector, limit) {
910 this.container_.querySelector(selector).style.display = 883 this.container_.querySelector(selector).style.display =
911 width < limit ? 'none' : '-webkit-box'; 884 width < limit ? 'none' : '-webkit-box';
912 }.bind(this); 885 }.bind(this);
913 886
914 hideBelow('.time', 350); 887 hideBelow('.time', 350);
915 hideBelow('.volume', 275); 888 hideBelow('.volume', 275);
916 hideBelow('.volume-controls', 210); 889 hideBelow('.volume-controls', 210);
917 hideBelow('.fullscreen', 150); 890 hideBelow('.fullscreen', 150);
918 }; 891 };
919
920 /**
921 * Updates video control when the window is fullscreened or restored.
922 * @param {boolean} fullscreen True if the window gets fullscreened.
923 */
924 VideoControls.prototype.onFullScreenChanged = function(fullscreen) {
925 if (fullscreen) {
926 this.container_.setAttribute('fullscreen', '');
927 } else {
928 this.container_.removeAttribute('fullscreen');
929 }
930
931 if (this.fullscreenButton_) {
932 this.fullscreenButton_.setAttribute('aria-label',
933 fullscreen ? str('VIDEO_PLAYER_EXIT_FULL_SCREEN_BUTTON_LABEL')
934 : str('VIDEO_PLAYER_FULL_SCREEN_BUTTON_LABEL'));;
935 }
936 };
OLDNEW
« no previous file with comments | « ui/file_manager/video_player/css/media_controls.css ('k') | ui/file_manager/video_player/js/video_player.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698