Modified: trunk/Source/WebCore/ChangeLog (170314 => 170315)
--- trunk/Source/WebCore/ChangeLog 2014-06-23 20:24:43 UTC (rev 170314)
+++ trunk/Source/WebCore/ChangeLog 2014-06-23 21:01:19 UTC (rev 170315)
@@ -1,3 +1,53 @@
+2014-06-23 Joseph Pecoraro <[email protected]>
+
+ Reduce synchronous layout triggered by _javascript_-based media controls
+ https://bugs.webkit.org/show_bug.cgi?id=134208
+
+ Reviewed by Eric Carlson.
+
+ Avoid always querying the offsetWidth and offsetHeight of the timeline
+ by only calculating these values when the timeline may change size.
+ Also avoid doing work in a few cases where properties did not
+ actually change.
+
+ * Modules/mediacontrols/mediaControlsApple.js:
+ (Controller):
+
+ (Controller.prototype.setNeedsTimelineMetricsUpdate):
+ (Controller.prototype.updateTimelineMetricsIfNeeded):
+ Only update the timeline metrics when they may have changed.
+
+ (Controller.prototype.updateControls):
+ (Controller.prototype.handleTimelineMouseMove):
+ (Controller.prototype.progressFillStyle):
+ (Controller.prototype.showControls):
+ (Controller.prototype.addControls):
+ Mark timeline metrics need update based on various UI changes.
+
+ (Controller.prototype.setStatusHidden):
+ Only do work if the hidden status changed.
+ Mark timeline metrics need update if the timeline is changed.
+
+ (Controller.prototype.updateProgress):
+ Use cached timeline metrics instead of always querying offsetWidth/offsetHeight.
+
+ * Modules/mediacontrols/mediaControlsiOS.js:
+ (ControllerIOS):
+ (ControllerIOS.prototype.updateControls):
+
+ (ControllerIOS.prototype.updateProgress):
+ Use cached timeline metrics instead of always querying offsetWidth/offsetHeight.
+
+ (ControllerIOS.prototype.handleWirelessPlaybackChange):
+ Mark timeline metrics need update as button may have changed.
+
+ (ControllerIOS.prototype.handleWirelessTargetAvailableChange):
+ Only do work if the availability changed.
+ Mark timeline metrics need update as a new button may have appeared.
+
+ (ControllerIOS.prototype.set pageScaleFactor):
+ Only do work if the page scale factor changed.
+
2014-06-23 Brady Eidson <[email protected]>
Add skeleton code for updated Gamepad API
Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js (170314 => 170315)
--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js 2014-06-23 20:24:43 UTC (rev 170314)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js 2014-06-23 21:01:19 UTC (rev 170315)
@@ -11,6 +11,7 @@
this.controls = {};
this.listeners = {};
this.isLive = false;
+ this.statusHidden = true;
this.addVideoListeners();
this.createBase();
@@ -250,6 +251,21 @@
return this.video.controls || this.isFullScreen();
},
+ setNeedsTimelineMetricsUpdate: function()
+ {
+ this.timelineMetricsNeedsUpdate = true;
+ },
+
+ updateTimelineMetricsIfNeeded: function()
+ {
+ if (this.timelineMetricsNeedsUpdate) {
+ this.timelineLeft = this.controls.timeline.offsetLeft;
+ this.timelineWidth = this.controls.timeline.offsetWidth;
+ this.timelineHeight = this.controls.timeline.offsetHeight;
+ this.timelineMetricsNeedsUpdate = false;
+ }
+ },
+
updateBase: function()
{
if (this.shouldHaveAnyUI()) {
@@ -480,6 +496,7 @@
else
this.setControlsType(Controller.InlineControls);
+ this.setNeedsTimelineMetricsUpdate();
},
updateStatusDisplay: function(event)
@@ -723,9 +740,10 @@
if (this.controls.thumbnail.classList.contains(this.ClassNames.hidden))
return;
+ this.updateTimelineMetricsIfNeeded();
this.controls.thumbnail.classList.add(this.ClassNames.show);
var localPoint = webkitConvertPointFromPageToNode(this.controls.timeline, new WebKitPoint(event.clientX, event.clientY));
- var percent = (localPoint.x - this.controls.timeline.offsetLeft) / this.controls.timeline.offsetWidth;
+ var percent = (localPoint.x - this.timelineLeft) / this.timelineWidth;
percent = Math.max(Math.min(1, percent), 0);
this.controls.thumbnail.style.left = percent * 100 + '%';
@@ -897,7 +915,7 @@
progressFillStyle: function(context)
{
- var height = this.controls.timeline.offsetHeight;
+ var height = this.timelineHeight;
var gradient = context.createLinearGradient(0, 0, 0, height);
gradient.addColorStop(0, 'rgb(2, 2, 2)');
gradient.addColorStop(1, 'rgb(23, 23, 23)');
@@ -906,8 +924,11 @@
updateProgress: function()
{
- var width = this.controls.timeline.offsetWidth;
- var height = this.controls.timeline.offsetHeight;
+ this.updateTimelineMetricsIfNeeded();
+
+ var width = this.timelineWidth;
+ var height = this.timelineHeight;
+
var context = document.getCSSCanvasContext('2d', 'timeline-' + this.timelineID, width, height);
context.clearRect(0, 0, width, height);
@@ -970,6 +991,8 @@
{
this.controls.panel.classList.add(this.ClassNames.show);
this.controls.panel.classList.remove(this.ClassNames.hidden);
+
+ this.setNeedsTimelineMetricsUpdate();
},
hideControls: function()
@@ -992,6 +1015,7 @@
addControls: function()
{
this.base.appendChild(this.controls.panel);
+ this.setNeedsTimelineMetricsUpdate();
},
updateTime: function()
@@ -1010,11 +1034,17 @@
setStatusHidden: function(hidden)
{
+ if (this.statusHidden === hidden)
+ return;
+
+ this.statusHidden = hidden;
+
if (hidden) {
this.controls.statusDisplay.classList.add(this.ClassNames.hidden);
this.controls.currentTime.classList.remove(this.ClassNames.hidden);
this.controls.timeline.classList.remove(this.ClassNames.hidden);
this.controls.remainingTime.classList.remove(this.ClassNames.hidden);
+ this.setNeedsTimelineMetricsUpdate();
} else {
this.controls.statusDisplay.classList.remove(this.ClassNames.hidden);
this.controls.currentTime.classList.add(this.ClassNames.hidden);
Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js (170314 => 170315)
--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js 2014-06-23 20:24:43 UTC (rev 170314)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js 2014-06-23 21:01:19 UTC (rev 170315)
@@ -11,6 +11,7 @@
this.updateWirelessTargetAvailable();
this.updateWirelessPlaybackStatus();
+ this.setNeedsTimelineMetricsUpdate();
host.controlsDependOnPageScaleFactor = true;
};
@@ -215,6 +216,7 @@
else
this.setControlsType(Controller.InlineControls);
+ this.setNeedsTimelineMetricsUpdate();
},
updateTime: function() {
@@ -229,8 +231,8 @@
updateProgress: function() {
Controller.prototype.updateProgress.call(this);
- var width = this.controls.timeline.offsetWidth;
- var height = this.controls.timeline.offsetHeight;
+ var width = this.timelineWidth;
+ var height = this.timelineHeight;
// Magic number, matching the value for ::-webkit-media-controls-timeline::-webkit-slider-thumb
// in mediaControlsiOS.css. Since we cannot ask the thumb for its offsetWidth as it's in its own
@@ -389,11 +391,17 @@
handleWirelessPlaybackChange: function(event) {
this.updateWirelessPlaybackStatus();
+ this.setNeedsTimelineMetricsUpdate();
},
handleWirelessTargetAvailableChange: function(event) {
- this.hasWirelessPlaybackTargets = event.availability == "available";
+ var wirelessPlaybackTargetsAvailable = event.availability == "available";
+ if (this.hasWirelessPlaybackTargets === wirelessPlaybackTargetsAvailable)
+ return;
+
+ this.hasWirelessPlaybackTargets = wirelessPlaybackTargetsAvailable;
this.updateWirelessTargetAvailable();
+ this.setNeedsTimelineMetricsUpdate();
},
handleWirelessPickerButtonTouchStart: function() {
@@ -416,6 +424,9 @@
},
set pageScaleFactor(newScaleFactor) {
+ if (this._pageScaleFactor === newScaleFactor)
+ return;
+
this._pageScaleFactor = newScaleFactor;
if (newScaleFactor) {
@@ -425,6 +436,7 @@
if (this.controls.panel) {
this.controls.panel.style.width = (newScaleFactor * 100) + "%";
this.controls.panel.style.webkitTransform = scaleTransform;
+ this.setNeedsTimelineMetricsUpdate();
this.updateProgress();
}
}