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 () {