Bug 865407 - Part 5: Move update display of cues code to TextTrackManager. r=bz, r=rillian

This commit is contained in:
Rick Eyre 2013-12-12 12:02:17 -05:00
parent 57a293b49e
commit 7b7b323893
14 changed files with 117 additions and 148 deletions

View File

@ -3677,12 +3677,12 @@ void HTMLMediaElement::FireTimeUpdate(bool aPeriodic)
mDecoder->SetFragmentEndTime(mFragmentEnd);
}
// Update visible text tracks.
// Update the cues displaying on the video.
// Here mTextTrackManager can be null if the cycle collector has unlinked
// us before our parent. In that case UnbindFromTree will call us
// when our parent is unlinked.
if (mTextTrackManager) {
mTextTrackManager->Update(time);
mTextTrackManager->UpdateCueDisplay();
}
}

View File

@ -8,6 +8,14 @@
#include "mozilla/dom/TextTrackManager.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLTrackElement.h"
#include "mozilla/dom/TextTrack.h"
#include "mozilla/dom/TextTrackCue.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsComponentManagerUtils.h"
#include "nsVideoFrame.h"
#include "nsIFrame.h"
#include "nsTArrayHelpers.h"
#include "nsIWebVTTParserWrapper.h"
namespace mozilla {
namespace dom {
@ -17,6 +25,8 @@ NS_IMPL_CYCLE_COLLECTION_3(TextTrackManager, mTextTracks,
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(TextTrackManager, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(TextTrackManager, Release)
StaticRefPtr<nsIWebVTTParserWrapper> TextTrackManager::sParserWrapper;
TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
: mMediaElement(aMediaElement)
{
@ -25,6 +35,13 @@ TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
mTextTracks = new TextTrackList(mMediaElement->OwnerDoc()->GetParentObject());
mPendingTextTracks =
new TextTrackList(mMediaElement->OwnerDoc()->GetParentObject());
if (!sParserWrapper) {
nsCOMPtr<nsIWebVTTParserWrapper> parserWrapper =
do_CreateInstance(NS_WEBVTTPARSERWRAPPER_CONTRACTID);
sParserWrapper = parserWrapper;
ClearOnShutdown(&sParserWrapper);
}
}
TextTrackManager::~TextTrackManager()
@ -86,9 +103,42 @@ TextTrackManager::DidSeek()
}
void
TextTrackManager::Update(double aTime)
TextTrackManager::UpdateCueDisplay()
{
mTextTracks->Update(aTime);
nsIFrame* frame = mMediaElement->GetPrimaryFrame();
if (!frame) {
return;
}
nsVideoFrame* videoFrame = do_QueryFrame(frame);
if (!videoFrame) {
return;
}
nsCOMPtr<nsIContent> overlay = videoFrame->GetCaptionOverlay();
if (!overlay) {
return;
}
nsTArray<nsRefPtr<TextTrackCue> > activeCues;
mTextTracks->GetAllActiveCues(activeCues);
if (activeCues.Length() > 0) {
nsCOMPtr<nsIWritableVariant> jsCues =
do_CreateInstance("@mozilla.org/variant;1");
jsCues->SetAsArray(nsIDataType::VTYPE_INTERFACE,
&NS_GET_IID(nsIDOMEventTarget),
activeCues.Length(),
static_cast<void*>(activeCues.Elements()));
nsPIDOMWindow* window = mMediaElement->OwnerDoc()->GetWindow();
if (window) {
sParserWrapper->ProcessCues(window, jsCues, overlay);
}
} else if (overlay->nsINode::Length() > 0) {
nsContentUtils::SetNodeTextContent(overlay, EmptyString(), true);
}
}
void

View File

@ -11,11 +11,16 @@
#include "mozilla/dom/TextTrack.h"
#include "mozilla/dom/TextTrackList.h"
#include "mozilla/dom/TextTrackCueList.h"
#include "mozilla/StaticPtr.h"
class nsIWebVTTParserWrapper;
namespace mozilla {
namespace dom {
class HTMLMediaElement;
class TextTrack;
class TextTrackCue;
class TextTrackManager
{
@ -37,9 +42,35 @@ public:
void AddCue(TextTrackCue& aCue);
void AddCues(TextTrack* aTextTrack);
// Update the display of cues on the video as per the current play back time
// of aTime.
void Update(double aTime);
/**
* Overview of WebVTT cuetext and anonymous content setup.
*
* WebVTT nodes are the parsed version of WebVTT cuetext. WebVTT cuetext is
* the portion of a WebVTT cue that specifies what the caption will actually
* show up as on screen.
*
* WebVTT cuetext can contain markup that loosely relates to HTML markup. It
* can contain tags like <b>, <u>, <i>, <c>, <v>, <ruby>, <rt>, <lang>,
* including timestamp tags.
*
* When the caption is ready to be displayed the WebVTT nodes are converted
* over to anonymous DOM content. <i>, <u>, <b>, <ruby>, and <rt> all become
* HTMLElements of their corresponding HTML markup tags. <c> and <v> are
* converted to <span> tags. Timestamp tags are converted to XML processing
* instructions. Additionally, all cuetext tags support specifying of classes.
* This takes the form of <foo.class.subclass>. These classes are then parsed
* and set as the anonymous content's class attribute.
*
* Rules on constructing DOM objects from WebVTT nodes can be found here
* http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules.
* Current rules are taken from revision on April 15, 2013.
*/
/**
* Converts the TextTrackCue's cuetext into a tree of DOM objects and attaches
* it to a div on it's owning TrackElement's MediaElement's caption overlay.
*/
void UpdateCueDisplay();
void PopulatePendingList();
@ -55,6 +86,8 @@ private:
nsRefPtr<TextTrackList> mPendingTextTracks;
// List of newly introduced Text Track cues.
nsRefPtr<TextTrackCueList> mNewCues;
static StaticRefPtr<nsIWebVTTParserWrapper> sParserWrapper;
};
} // namespace dom

View File

@ -72,14 +72,6 @@ TextTrack::SetDefaultSettings()
mReadyState = HTMLTrackElement::NONE;
}
void
TextTrack::Update(double aTime)
{
if (mCueList) {
mCueList->Update(aTime);
}
}
JSObject*
TextTrack::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{

View File

@ -99,9 +99,6 @@ public:
void AddRegion(TextTrackRegion& aRegion);
void RemoveRegion(const TextTrackRegion& aRegion, ErrorResult& aRv);
// Time is in seconds.
void Update(double aTime);
void AddCue(TextTrackCue& aCue);
void RemoveCue(TextTrackCue& aCue, ErrorResult& aRv);
void CueChanged(TextTrackCue& aCue);

View File

@ -5,8 +5,6 @@
#include "mozilla/dom/HTMLTrackElement.h"
#include "mozilla/dom/TextTrackCue.h"
#include "nsIFrame.h"
#include "nsVideoFrame.h"
#include "nsComponentManagerUtils.h"
#include "mozilla/ClearOnShutdown.h"
@ -101,58 +99,6 @@ TextTrackCue::StashDocument(nsISupports* aGlobal)
return NS_OK;
}
void
TextTrackCue::CreateCueOverlay()
{
nsCOMPtr<nsINodeInfo> nodeInfo =
mDocument->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div,
nullptr,
kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
mDisplayState = NS_NewHTMLDivElement(nodeInfo.forget());
mDisplayState->SetClassName(NS_LITERAL_STRING("caption-text"));
}
void
TextTrackCue::RenderCue()
{
nsRefPtr<DocumentFragment> frag = GetCueAsHTML();
if (!frag || !mTrackElement) {
return;
}
if (!mDisplayState) {
CreateCueOverlay();
}
HTMLMediaElement* parent = mTrackElement->mMediaParent;
if (!parent) {
return;
}
nsIFrame* frame = parent->GetPrimaryFrame();
if (!frame) {
return;
}
nsVideoFrame* videoFrame = do_QueryFrame(frame);
if (!videoFrame) {
return;
}
nsIContent* overlay = videoFrame->GetCaptionOverlay();
if (!overlay) {
return;
}
ErrorResult rv;
nsContentUtils::SetNodeTextContent(overlay, EmptyString(), true);
nsContentUtils::SetNodeTextContent(mDisplayState, EmptyString(), true);
mDisplayState->nsINode::AppendChild(*frag, rv);
overlay->AppendChild(*mDisplayState, rv);
}
already_AddRefed<DocumentFragment>
TextTrackCue::GetCueAsHTML()
{

View File

@ -319,36 +319,6 @@ public:
return mId;
}
/**
* Overview of WebVTT cuetext and anonymous content setup.
*
* WebVTT nodes are the parsed version of WebVTT cuetext. WebVTT cuetext is
* the portion of a WebVTT cue that specifies what the caption will actually
* show up as on screen.
*
* WebVTT cuetext can contain markup that loosely relates to HTML markup. It
* can contain tags like <b>, <u>, <i>, <c>, <v>, <ruby>, <rt>, <lang>,
* including timestamp tags.
*
* When the caption is ready to be displayed the WebVTT nodes are converted
* over to anonymous DOM content. <i>, <u>, <b>, <ruby>, and <rt> all become
* HTMLElements of their corresponding HTML markup tags. <c> and <v> are
* converted to <span> tags. Timestamp tags are converted to XML processing
* instructions. Additionally, all cuetext tags support specifying of classes.
* This takes the form of <foo.class.subclass>. These classes are then parsed
* and set as the anonymous content's class attribute.
*
* Rules on constructing DOM objects from WebVTT nodes can be found here
* http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules.
* Current rules are taken from revision on April 15, 2013.
*/
/**
* Converts the TextTrackCue's cuetext into a tree of DOM objects and attaches
* it to a div on it's owning TrackElement's MediaElement's caption overlay.
*/
void RenderCue();
/**
* Produces a tree of anonymous content based on the tree of the processed
* cue text.
@ -363,7 +333,6 @@ public:
private:
void CueChanged();
void SetDefaultCueSettings();
void CreateCueOverlay();
nsresult StashDocument(nsISupports* aGlobal);
nsRefPtr<nsIDocument> mDocument;

View File

@ -38,17 +38,6 @@ TextTrackCueList::TextTrackCueList(nsISupports* aParent) : mParent(aParent)
SetIsDOMBinding();
}
void
TextTrackCueList::Update(double aTime)
{
const uint32_t length = mList.Length();
for (uint32_t i = 0; i < length; i++) {
if (aTime > mList[i]->StartTime() && aTime < mList[i]->EndTime()) {
mList[i]->RenderCue();
}
}
}
JSObject*
TextTrackCueList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{

View File

@ -41,9 +41,6 @@ public:
return mList.Length();
}
// Time is in seconds.
void Update(double aTime);
TextTrackCue* IndexedGetter(uint32_t aIndex, bool& aFound);
TextTrackCue* operator[](uint32_t aIndex);
TextTrackCue* GetCueById(const nsAString& aId);

View File

@ -27,15 +27,6 @@ TextTrackList::TextTrackList(nsISupports* aGlobal) : mGlobal(aGlobal)
SetIsDOMBinding();
}
void
TextTrackList::Update(double aTime)
{
uint32_t length = Length(), i;
for (i = 0; i < length; i++) {
mTextTracks[i]->Update(aTime);
}
}
void
TextTrackList::GetAllActiveCues(nsTArray<nsRefPtr<TextTrackCue> >& aCues)
{

View File

@ -38,9 +38,6 @@ public:
return mTextTracks.Length();
}
// Time is in seconds.
void Update(double aTime);
// Get all the current active cues.
void GetAllActiveCues(nsTArray<nsRefPtr<TextTrackCue> >& aCues);

View File

@ -50,6 +50,11 @@ WebVTTParserWrapper.prototype =
return WebVTTParser.convertCueToDOMTree(window, cue.text);
},
processCues: function(window, cues, overlay)
{
// TODO: Call prcoess cues on vtt.js
},
classDescription: "Wrapper for the JS WebVTTParser (vtt.js)",
classID: Components.ID(WEBVTTPARSERWRAPPER_CID),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebVTTParserWrapper]),

View File

@ -7,6 +7,7 @@
interface nsIDOMHTMLElement;
interface nsIWebVTTListener;
interface nsIDOMWindow;
interface nsIVariant;
/**
* Interface for a wrapper of a JS WebVTT parser (vtt.js).
@ -61,6 +62,24 @@ interface nsIWebVTTParserWrapper : nsISupports
*/
nsIDOMHTMLElement convertCueToDOMTree(in nsIDOMWindow window,
in nsISupports cue);
/**
* Compute the display state of the VTTCues in cues along with any VTTRegions
* that they might be in. First, it computes the positioning and styling of
* the cues and regions passed and converts them into a DOM tree rooted at
* a containing HTMLDivElement. It then adjusts those computed divs for
* overlap avoidance using the dimensions of 'overlay'. Finally, it adds the
* computed divs to the VTTCues display state property for use later.
*
* @param window A window object with which it will create the DOM tree
* and containing div element.
* @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.
*/
void processCues(in nsIDOMWindow window, in nsIVariant cues,
in nsISupports overlay);
};
%{C++

View File

@ -728,25 +728,9 @@ audio:not([controls]) {
video > .caption-box {
position: relative;
pointer-events: none;
}
video > div .caption-text {
position: absolute;
bottom: 24px;
padding: 5px;
left: 0;
right: 0;
text-align: center;
pointer-events: auto;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 20px;
color: white;
text-shadow:
-2px -2px 1px #000,
2px -2px 1px #000,
-2px 2px 1px #000,
2px 2px 1px #000;
overflow: hidden;
padding: 1.5%;
box-sizing: border-box;
}
/* emulation of non-standard HTML <marquee> tag */