diff --git a/dom/html/TextTrackManager.cpp b/dom/html/TextTrackManager.cpp
index b39628dd8dcb..3fbbd5bda80b 100644
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -230,6 +230,7 @@ TextTrackManager::UpdateCueDisplay()
}
nsCOMPtr overlay = videoFrame->GetCaptionOverlay();
+ nsCOMPtr controls = videoFrame->GetVideoControls();
if (!overlay) {
return;
}
@@ -247,7 +248,7 @@ TextTrackManager::UpdateCueDisplay()
nsPIDOMWindowInner* window = mMediaElement->OwnerDoc()->GetInnerWindow();
if (window) {
- sParserWrapper->ProcessCues(window, jsCues, overlay);
+ sParserWrapper->ProcessCues(window, jsCues, overlay, controls);
}
} else if (overlay->Length() > 0) {
nsContentUtils::SetNodeTextContent(overlay, EmptyString(), true);
@@ -296,6 +297,10 @@ TextTrackManager::AddListeners()
if (mMediaElement) {
mMediaElement->AddEventListener(NS_LITERAL_STRING("resizevideocontrols"),
this, false, false);
+ mMediaElement->AddEventListener(NS_LITERAL_STRING("seeked"),
+ this, false, false);
+ mMediaElement->AddEventListener(NS_LITERAL_STRING("controlbarchange"),
+ this, false, true);
}
}
@@ -405,11 +410,17 @@ TextTrackManager::HandleEvent(nsIDOMEvent* aEvent)
nsAutoString type;
aEvent->GetType(type);
- if (type.EqualsLiteral("resizevideocontrols")) {
+ if (type.EqualsLiteral("resizevideocontrols") ||
+ type.EqualsLiteral("seeked")) {
for (uint32_t i = 0; i< mTextTracks->Length(); i++) {
((*mTextTracks)[i])->SetCuesDirty();
}
}
+
+ if (type.EqualsLiteral("controlbarchange")) {
+ UpdateCueDisplay();
+ }
+
return NS_OK;
}
diff --git a/dom/media/webvtt/WebVTTParserWrapper.js b/dom/media/webvtt/WebVTTParserWrapper.js
index a8a642982bce..5a36308fda66 100644
--- a/dom/media/webvtt/WebVTTParserWrapper.js
+++ b/dom/media/webvtt/WebVTTParserWrapper.js
@@ -54,9 +54,9 @@ WebVTTParserWrapper.prototype =
return WebVTT.convertCueToDOMTree(window, cue.text);
},
- processCues: function(window, cues, overlay)
+ processCues: function(window, cues, overlay, controls)
{
- WebVTT.processCues(window, cues, overlay);
+ WebVTT.processCues(window, cues, overlay, controls);
},
classDescription: "Wrapper for the JS WebVTT implementation (vtt.js)",
diff --git a/dom/media/webvtt/nsIWebVTTParserWrapper.idl b/dom/media/webvtt/nsIWebVTTParserWrapper.idl
index 018859e0f261..793fcaa3c59b 100644
--- a/dom/media/webvtt/nsIWebVTTParserWrapper.idl
+++ b/dom/media/webvtt/nsIWebVTTParserWrapper.idl
@@ -77,9 +77,10 @@ interface nsIWebVTTParserWrapper : nsISupports
* @param cues An array of VTTCues who need there display state to be
* computed.
* @param overlay The HTMLElement that the cues will be displayed within.
+ * @param controls The video control element that will affect cues position.
*/
void processCues(in mozIDOMWindow window, in nsIVariant cues,
- in nsISupports overlay);
+ in nsISupports overlay, in nsISupports controls);
};
%{C++
diff --git a/dom/media/webvtt/vtt.jsm b/dom/media/webvtt/vtt.jsm
index c7e2c14729d8..e724e8182c6e 100644
--- a/dom/media/webvtt/vtt.jsm
+++ b/dom/media/webvtt/vtt.jsm
@@ -1120,7 +1120,9 @@ this.EXPORTED_SYMBOLS = ["WebVTT"];
// Runs the processing model over the cues and regions passed to it.
// @param overlay A block level element (usually a div) that the computed cues
// and regions will be placed into.
- WebVTT.processCues = function(window, cues, overlay) {
+ // @param controls A Control bar element. Cues' position will be
+ // affected and repositioned according to it.
+ WebVTT.processCues = function(window, cues, overlay, controls) {
if (!window || !cues || !overlay) {
return null;
}
@@ -1130,6 +1132,15 @@ this.EXPORTED_SYMBOLS = ["WebVTT"];
overlay.removeChild(overlay.firstChild);
}
+ var controlBar;
+ var controlBarShown;
+
+ if (controls) {
+ controlBar = controls.ownerDocument.getAnonymousElementByAttribute(
+ controls, "class", "controlBar");
+ controlBarShown = controlBar ? !!controlBar.clientHeight : false;
+ }
+
var paddedOverlay = window.document.createElement("div");
paddedOverlay.style.position = "absolute";
paddedOverlay.style.left = "0";
@@ -1143,6 +1154,10 @@ this.EXPORTED_SYMBOLS = ["WebVTT"];
// be the case if a cue's state has been changed since the last computation or
// if it has not been computed yet.
function shouldCompute(cues) {
+ if (controlBarShown) {
+ return true;
+ }
+
for (var i = 0; i < cues.length; i++) {
if (cues[i].hasBeenReset || !cues[i].displayState) {
return true;
@@ -1169,6 +1184,11 @@ this.EXPORTED_SYMBOLS = ["WebVTT"];
(function() {
var styleBox, cue;
+ if (controlBarShown) {
+ // Add an empty output box that cover the same region as video control bar.
+ boxPositions.push(BoxPosition.getSimpleBoxPosition(controlBar));
+ }
+
for (var i = 0; i < cues.length; i++) {
cue = cues[i];
diff --git a/layout/generic/nsVideoFrame.h b/layout/generic/nsVideoFrame.h
index a65231fa43e6..1fe9b68ceb4f 100644
--- a/layout/generic/nsVideoFrame.h
+++ b/layout/generic/nsVideoFrame.h
@@ -102,6 +102,8 @@ public:
nsIContent *GetCaptionOverlay() { return mCaptionDiv; }
+ nsIContent *GetVideoControls() { return mVideoControls; }
+
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
diff --git a/toolkit/content/widgets/videocontrols.xml b/toolkit/content/widgets/videocontrols.xml
index 2079ed6b9f44..f53cb081f443 100644
--- a/toolkit/content/widgets/videocontrols.xml
+++ b/toolkit/content/widgets/videocontrols.xml
@@ -1323,6 +1323,7 @@
onControlBarTransitioned : function () {
this.textTrackList.setAttribute("hidden", "true");
+ this.video.dispatchEvent(new CustomEvent("controlbarchange"));
},
toggleClosedCaption : function () {