Commit 46355144 authored by Esmael El-Moslimany's avatar Esmael El-Moslimany Committed by Commit Bot

Video Player WebUI: replace paper-slider with cr-slider

The video player progress needs to be updated from the slider value
only when the change is due to a user interaction. For this
reason cr-slider-value-changed-from-ui was introduced.

cr-slider getRatio() was made public since it is meaningful
representation of the slider value.

Swapped the skip direction of ArrowLeft/ArrowRight when the text
direction is RTL.

When the volume value is changed with the keyboard and the media
controls are hidden, the media controls are shown.

Bug: 902873
Change-Id: Ide0a23783274d4c11ea83b367aba8b41a5dd8ad1
Reviewed-on: https://chromium-review.googlesource.com/c/1357216Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Commit-Queue: Esmael El-Moslimany <aee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#613384}
parent 9b34c2c9
......@@ -364,4 +364,29 @@ suite('cr-slider', function() {
assertNoTransition();
});
});
test('getRatio()', () => {
crSlider.min = 1;
crSlider.max = 11;
crSlider.value = 1;
assertEquals(0, crSlider.getRatio());
crSlider.value = 11;
assertEquals(1, crSlider.getRatio());
crSlider.value = 6;
assertEquals(.5, crSlider.getRatio());
});
test('cr-slider-value-changed-from-ui event when mouse clicked', () => {
const wait =
test_util.eventToPromise('cr-slider-value-changed-from-ui', crSlider);
pointerDown(0);
return wait;
});
test('cr-slider-value-changed-from-ui event when key pressed', () => {
const wait =
test_util.eventToPromise('cr-slider-value-changed-from-ui', crSlider);
pressArrowRight();
return wait;
});
});
......@@ -19,8 +19,7 @@
}
.media-button.disabled,
paper-slider[disabled],
paper-slider.readonly {
cr-slider.readonly {
pointer-events: none;
}
......@@ -112,7 +111,7 @@ paper-slider.readonly {
/* Volume slider. */
paper-slider.volume {
cr-slider.volume {
height: 100%;
position: relative;
width: 110px;
......
......@@ -41,7 +41,7 @@ js_library("error_util") {
js_library("media_controls") {
deps = [
"../../file_manager/common/js:util",
"//third_party/polymer/v1_0/components-chromium/paper-slider:paper-slider-extracted",
"//ui/webui/resources/cr_elements/cr_slider:cr_slider",
"//ui/webui/resources/js/cr/ui:menu_button",
]
}
......
......@@ -101,13 +101,13 @@ function MediaControls(containerElement, onMediaError) {
this.playButton_ = null;
/**
* @type {PaperSliderElement}
* @type {CrSliderElement}
* @private
*/
this.progressSlider_ = null;
/**
* @type {PaperSliderElement}
* @type {CrSliderElement}
* @private
*/
this.volume_ = null;
......@@ -372,20 +372,21 @@ MediaControls.prototype.initTimeControls = function(opt_parent) {
// Set the initial width to the minimum to reduce the flicker.
this.updateTimeLabel_(0, 0);
this.progressSlider_ = /** @type {!PaperSliderElement} */ (
document.createElement('paper-slider'));
this.progressSlider_ =
/** @type {!CrSliderElement} */ (document.createElement('cr-slider'));
this.progressSlider_.classList.add('progress', 'media-control');
this.progressSlider_.max = MediaControls.PROGRESS_RANGE;
this.progressSlider_.noKeybindings = true;
this.progressSlider_.setAttribute('aria-label',
str('MEDIA_PLAYER_SEEK_SLIDER_LABEL'));
this.progressSlider_.addEventListener('change', function(event) {
this.onProgressChange_(this.progressSlider_.ratio / 100);
}.bind(this));
this.progressSlider_.addEventListener('dragging-changed', event => {
this.setSeeking_(event.detail.value);
});
this.progressSlider_.addEventListener(
'immediate-value-change',
function(event) {
this.onProgressDrag_();
}.bind(this));
'cr-slider-value-changed-from-ui', () => {
this.onProgressChange_();
this.updateTimeFromSlider_();
});
timeControls.appendChild(this.progressSlider_);
};
......@@ -400,11 +401,19 @@ MediaControls.prototype.displayProgress_ = function(current, duration) {
this.updateTimeLabel_(current);
};
/**
* @param {number} value Progress [0..1].
* @private
*/
MediaControls.prototype.onProgressChange_ = function(value) {
/** @private */
MediaControls.prototype.updateTimeFromSlider_ = function() {
if (!this.media_)
return; // Media is detached.
if (this.media_.duration && this.progressSlider_.max > 0) {
this.media_.currentTime =
this.media_.duration * this.progressSlider_.getRatio();
}
};
/** @private */
MediaControls.prototype.onProgressChange_ = function() {
if (!this.media_)
return; // Media is detached.
......@@ -413,32 +422,13 @@ MediaControls.prototype.onProgressChange_ = function(value) {
return;
}
this.setSeeking_(false);
// Re-start playing the video when the seek bar is moved from ending point.
if (this.media_.ended)
this.play();
var current = this.media_.duration * value;
this.media_.currentTime = current;
this.updateTimeLabel_(current);
};
/**
* @private
*/
MediaControls.prototype.onProgressDrag_ = function() {
if (!this.media_)
return; // Media is detached.
this.setSeeking_(true);
// Show seeking position instead of playing position while dragging.
if (this.media_.duration && this.progressSlider_.max > 0) {
var immediateRatio =
this.progressSlider_.immediateValue / this.progressSlider_.max;
var current = this.media_.duration * immediateRatio;
this.updateTimeLabel_(current);
this.updateTimeLabel_(
this.media_.duration * this.progressSlider_.getRatio());
}
};
......@@ -454,7 +444,8 @@ MediaControls.prototype.skip_ = function(sec) {
this.progressSlider_.value = Math.max(Math.min(
this.progressSlider_.value + stepsToSkip,
this.progressSlider_.max), 0);
this.onProgressChange_(this.progressSlider_.ratio / 100);
this.onProgressChange_();
this.updateTimeFromSlider_();
}
};
......@@ -578,17 +569,13 @@ MediaControls.prototype.initVolumeControls = function(opt_parent) {
this.soundButton_.setAttribute('aria-label',
str('MEDIA_PLAYER_MUTE_BUTTON_LABEL'));
this.volume_ = /** @type {!PaperSliderElement} */ (
document.createElement('paper-slider'));
this.volume_ =
/** @type {!CrSliderElement} */ (document.createElement('cr-slider'));
this.volume_.classList.add('volume', 'media-control');
this.volume_.setAttribute('aria-label',
str('MEDIA_PLAYER_VOLUME_SLIDER_LABEL'));
this.volume_.addEventListener('change', function(event) {
this.onVolumeChange_(this.volume_.ratio / 100);
}.bind(this));
this.volume_.addEventListener('immediate-value-change', function(event) {
this.onVolumeDrag_();
}.bind(this));
this.volume_.addEventListener(
'cr-slider-value-changed-from-ui', this.onVolumeChange_.bind(this));
this.loadVolumeControlState();
volumeControls.appendChild(this.volume_);
};
......@@ -655,27 +642,17 @@ MediaControls.prototype.reflectVolumeToUi_ = function() {
/**
* Handles change event of the volume slider.
* @param {number} value Volume [0..1].
* @private
*/
MediaControls.prototype.onVolumeChange_ = function(value) {
MediaControls.prototype.onVolumeChange_ = function() {
if (!this.media_)
return; // Media is detached.
this.volumeModel_.onVolumeChanged(value);
this.volumeModel_.onVolumeChanged(this.volume_.getRatio());
this.saveVolumeControlState();
this.reflectVolumeToUi_();
};
/**
* @private
*/
MediaControls.prototype.onVolumeDrag_ = function() {
if (this.media_.volume !== 0) {
this.volumeModel_.onVolumeChanged(this.media_.volume);
}
};
/**
* Initializes subtitles button.
*/
......
......@@ -22,6 +22,8 @@ function FullWindowVideoControls(
this.decodeErrorOccured = false;
this.casting = false;
this.isRtl_ =
window.getComputedStyle(this.playerContainer_)['direction'] === 'rtl';
var currentWindow = chrome.app.window.current();
currentWindow.onFullscreened.addListener(this.onFullScreenChanged.bind(this));
......@@ -62,17 +64,17 @@ function FullWindowVideoControls(
break;
case 'ArrowRight':
if (!e.target.classList.contains('volume'))
this.smallSkip(true);
this.smallSkip(!this.isRtl_ /* forward */);
break;
case 'ArrowLeft':
if (!e.target.classList.contains('volume'))
this.smallSkip(false);
this.smallSkip(this.isRtl_ /* forward */);
break;
case 'l':
this.bigSkip(true);
this.bigSkip(true /* forward */);
break;
case 'j':
this.bigSkip(false);
this.bigSkip(false /* forward */);
break;
case 'BrowserBack':
chrome.app.window.current().close();
......@@ -85,6 +87,9 @@ function FullWindowVideoControls(
document.addEventListener('keypress', function(e) {
this.inactivityWatcher_.kick();
}.wrap(this));
controlsContainer.addEventListener('cr-slider-value-changed-from-ui', () => {
this.inactivityWatcher_.kick();
});
// TODO(mtomasz): Simplify. crbug.com/254318.
var clickInProgress = false;
......
......@@ -16,7 +16,7 @@
<link rel="stylesheet" type="text/css" href="css/cast_menu.css">
<link rel="import" href="chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/foreground/elements/files_icon_button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-slider/paper-slider.html">
<link rel="import" href="chrome://resources/cr_elements/cr_slider/cr_slider.html">
<script src="js/video_player_scripts.js"></script>
</head>
......@@ -35,11 +35,11 @@
};
}
paper-slider {
cr-slider {
cursor: pointer;
--paper-slider-knob-color: rgb(64, 138, 241);
--paper-slider-active-color: rgb(66, 133, 244);
--cr-slider-knob-color: rgb(64, 138, 241);
--cr-slider-active-color: rgb(66, 133, 244);
}
</style>
</custom-style>
......
......@@ -34,6 +34,13 @@ cr_slider.SliderTick;
return Math.min(max, Math.max(min, value));
}
/**
* The following are the events emitted from cr-slider.
*
* cr-slider-value-changed-from-ui: fired when updating slider via the UI.
* dragging-changed: fired on pointer down and on pointer up.
* value-changed: fired anytime |value| is changed, manually or via the UI.
*/
Polymer({
is: 'cr-slider',
......@@ -231,7 +238,7 @@ cr_slider.SliderTick;
* @private
*/
getMarkerClass_: function(index) {
const currentStep = (this.markerCount - 1) * this.getRatio_();
const currentStep = (this.markerCount - 1) * this.getRatio();
return index < currentStep ? 'active-marker' : 'inactive-marker';
},
......@@ -241,9 +248,8 @@ cr_slider.SliderTick;
* This is a helper function used to calculate the bar width, knob location
* and label location.
* @return {number}
* @private
*/
getRatio_: function() {
getRatio: function() {
return (this.immediateValue_ - this.min) / (this.max - this.min);
},
......@@ -315,14 +321,15 @@ cr_slider.SliderTick;
} else if (event.key == 'End') {
this.immediateValue_ = this.max;
} else if (this.deltaKeyMap_.has(event.key)) {
const newValue = this.value + this.deltaKeyMap_.get(event.key);
this.immediateValue_ = clamp(this.min, this.max, newValue);
const value = this.value + this.deltaKeyMap_.get(event.key);
this.immediateValue_ = clamp(this.min, this.max, value);
} else {
handled = false;
}
if (handled) {
this.value = this.immediateValue_;
this.fire('cr-slider-value-changed-from-ui');
event.preventDefault();
event.stopPropagation();
setTimeout(() => {
......@@ -407,7 +414,7 @@ cr_slider.SliderTick;
/** @private */
updateKnobAndBar_: function() {
const percent = `${this.getRatio_() * 100}%`;
const percent = `${this.getRatio() * 100}%`;
this.$.bar.style.width = percent;
this.$.knob.style.marginInlineStart = percent;
},
......@@ -434,7 +441,7 @@ cr_slider.SliderTick;
const labelWidth = label.offsetWidth;
// The left and right margin are 16px.
const margin = 16;
const knobLocation = parentWidth * this.getRatio_() + margin;
const knobLocation = parentWidth * this.getRatio() + margin;
const offsetStart = knobLocation - (labelWidth / 2);
// The label should be centered over the knob. Clamping the offset to a
// min and max value prevents the label from being cutoff.
......@@ -467,6 +474,7 @@ cr_slider.SliderTick;
ratio = 1 - ratio;
this.immediateValue_ = ratio * (this.max - this.min) + this.min;
this.ensureValidValue_();
this.fire('cr-slider-value-changed-from-ui');
},
_createRipple: function() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment