Bug 833385 - Implement HTMLTrackElement and TextTrack. r=bz,Ms2ger

Add webidl interfaces and implementations of the HTML <track>
element and related TextTrack, TextTrackList, TextTrackCue,
and TextTrackCueList dom objects.

Visibility is controlled by the media.webvtt.enabled pref,
which defaults to false.

HTMLMediaElement:NewURIFromString() is hoisted to
nsGenericHTMLElement so it's available to the track
element as well.

This patch is primarily work by Dale Karp, David Humphrey
and others as Seneca College.
This commit is contained in:
Ralph Giles 2013-05-22 00:14:00 +08:00
parent 01d753df9d
commit cc2db4daf4
33 changed files with 1536 additions and 43 deletions

View File

@ -1875,6 +1875,11 @@ GK_ATOM(onratechange, "onratechange")
GK_ATOM(ondurationchange, "ondurationchange")
GK_ATOM(onvolumechange, "onvolumechange")
GK_ATOM(onMozAudioAvailable, "onMozAudioAvailable")
GK_ATOM(onaddtrack, "onaddtrack")
GK_ATOM(oncuechange, "oncuechange")
GK_ATOM(onenter, "onenter")
GK_ATOM(onexit, "onexit")
GK_ATOM(onremovetrack, "onremovetrack")
GK_ATOM(loadstart, "loadstart")
GK_ATOM(suspend, "suspend")
GK_ATOM(emptied, "emptied")

View File

@ -28,6 +28,8 @@
#include "MediaMetadataManager.h"
#include "AudioChannelAgent.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/TextTrack.h"
#include "mozilla/dom/TextTrackList.h"
#include "mozilla/ErrorResult.h"
// Define to output information on decoding and painting framerate
@ -509,6 +511,16 @@ public:
SetHTMLAttr(nsGkAtoms::mozaudiochannel, aValue, aRv);
}
TextTrackList* TextTracks() const;
already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
const nsAString& aLabel,
const nsAString& aLanguage);
void AddTextTrack(TextTrack* aTextTrack) {
mTextTracks->AddTextTrack(aTextTrack);
}
protected:
class MediaLoadListener;
class StreamListener;
@ -630,11 +642,6 @@ protected:
*/
void AbortExistingLoads();
/**
* Create a URI for the given aURISpec string.
*/
nsresult NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI);
/**
* Called when all potential resources are exhausted. Changes network
* state to NETWORK_NO_SOURCE, and sends error event with code
@ -1103,6 +1110,9 @@ protected:
// An agent used to join audio channel service.
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
// List of our attached text track objects.
nsRefPtr<TextTrackList> mTextTracks;
};
} // namespace dom

View File

@ -412,6 +412,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlayed);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTracks);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
@ -430,6 +431,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputStreams[i].mStream);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPlayed);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTracks);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement)
@ -1947,6 +1949,8 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
RegisterFreezableElement();
NotifyOwnerDocumentActivityChanged();
mTextTracks = new TextTrackList(OwnerDoc()->GetParentObject());
}
HTMLMediaElement::~HTMLMediaElement()
@ -2680,38 +2684,6 @@ void HTMLMediaElement::EndSrcMediaStreamPlayback()
mSrcStream = nullptr;
}
nsresult HTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
*aURI = nullptr;
nsCOMPtr<nsIDocument> doc = OwnerDoc();
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
nsCOMPtr<nsIURI> uri;
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
aURISpec,
doc,
baseURI);
NS_ENSURE_SUCCESS(rv, rv);
bool equal;
if (aURISpec.IsEmpty() &&
doc->GetDocumentURI() &&
NS_SUCCEEDED(doc->GetDocumentURI()->Equals(uri, &equal)) &&
equal) {
// It's not possible for a media resource to be embedded in the current
// document we extracted aURISpec from, so there's no point returning
// the current document URI just to let the caller attempt and fail to
// decode it.
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
uri.forget(aURI);
return NS_OK;
}
void HTMLMediaElement::ProcessMediaFragmentURI()
{
nsMediaFragmentURIParser parser(mLoadingSrc);
@ -3568,6 +3540,14 @@ void HTMLMediaElement::FireTimeUpdate(bool aPeriodic)
mFragmentStart = -1.0;
mDecoder->SetFragmentEndTime(mFragmentEnd);
}
// Update visible text tracks.
// Here mTextTracks 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 (mTextTracks) {
mTextTracks->Update(time);
}
}
void HTMLMediaElement::GetCurrentSpec(nsCString& aString)
@ -3771,5 +3751,20 @@ NS_IMETHODIMP HTMLMediaElement::CanPlayChanged(bool canPlay)
return NS_OK;
}
/* readonly attribute TextTrackList textTracks; */
TextTrackList*
HTMLMediaElement::TextTracks() const
{
return mTextTracks;
}
already_AddRefed<TextTrack>
HTMLMediaElement::AddTextTrack(TextTrackKind aKind,
const nsAString& aLabel,
const nsAString& aLanguage)
{
return mTextTracks->AddTextTrack(aKind, aLabel, aLanguage);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,257 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLTrackElement.h"
#include "mozilla/dom/HTMLTrackElementBinding.h"
#include "mozilla/dom/HTMLUnknownElement.h"
#include "nsAttrValueInlines.h"
#include "nsCOMPtr.h"
#include "nsContentPolicyUtils.h"
#include "nsContentUtils.h"
#include "nsCycleCollectionParticipant.h"
#include "nsGenericHTMLElement.h"
#include "nsGkAtoms.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsICachingChannel.h"
#include "nsIChannelEventSink.h"
#include "nsIChannelPolicy.h"
#include "nsIContentPolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIDocument.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMHTMLMediaElement.h"
#include "nsIFrame.h"
#include "nsIHttpChannel.h"
#include "nsIInterfaceRequestor.h"
#include "nsILoadGroup.h"
#include "nsIObserver.h"
#include "nsIStreamListener.h"
#include "nsISupportsImpl.h"
#include "nsMappedAttributes.h"
#include "nsNetUtil.h"
#include "nsRuleData.h"
#include "nsStyleConsts.h"
#include "nsThreadUtils.h"
#include "nsVideoFrame.h"
#include "webvtt/parser.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gTrackElementLog;
#define LOG(type, msg) PR_LOG(gTrackElementLog, type, msg)
#else
#define LOG(type, msg)
#endif
// Replace the usual NS_IMPL_NS_NEW_HTML_ELEMENT(Track) so
// we can return an UnknownElement instead when pref'd off.
nsGenericHTMLElement*
NS_NewHTMLTrackElement(already_AddRefed<nsINodeInfo> aNodeInfo,
mozilla::dom::FromParser aFromParser)
{
if (!mozilla::dom::HTMLTrackElement::IsWebVTTEnabled()) {
return mozilla::dom::NewHTMLElementHelper::Create<nsHTMLUnknownElement,
mozilla::dom::HTMLUnknownElement>(aNodeInfo);
}
return mozilla::dom::NewHTMLElementHelper::Create<nsHTMLTrackElement,
mozilla::dom::HTMLTrackElement>(aNodeInfo);
}
namespace mozilla {
namespace dom {
/** HTMLTrackElement */
HTMLTrackElement::HTMLTrackElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
, mReadyState(NONE)
{
#ifdef PR_LOGGING
if (!gTrackElementLog) {
gTrackElementLog = PR_NewLogModule("nsTrackElement");
}
#endif
SetIsDOMBinding();
}
HTMLTrackElement::~HTMLTrackElement()
{
}
NS_IMPL_ELEMENT_CLONE(HTMLTrackElement)
NS_IMPL_ADDREF_INHERITED(HTMLTrackElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLTrackElement, Element)
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(HTMLTrackElement, nsGenericHTMLElement,
mTrack, mChannel, mMediaParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTrackElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLElement)
NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
JSObject*
HTMLTrackElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return HTMLTrackElementBinding::Wrap(aCx, aScope, this);
}
bool
HTMLTrackElement::IsWebVTTEnabled()
{
return HTMLTrackElementBinding::PrefEnabled();
}
TextTrack*
HTMLTrackElement::Track()
{
if (!mTrack) {
// We're expected to always have an internal TextTrack so create
// an empty object to return if we don't already have one.
mTrack = new TextTrack(OwnerDoc()->GetParentObject());
}
return mTrack;
}
void
HTMLTrackElement::DisplayCueText(webvtt_node* head)
{
// TODO: Bug 833382 - Propagate to the LoadListener.
}
void
HTMLTrackElement::CreateTextTrack()
{
DOMString label, srcLang;
GetSrclang(srcLang);
GetLabel(label);
mTrack = new TextTrack(OwnerDoc()->GetParentObject(), Kind(), label, srcLang);
if (mMediaParent) {
mMediaParent->AddTextTrack(mTrack);
}
}
TextTrackKind
HTMLTrackElement::Kind() const
{
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::kind);
if (!value) {
return TextTrackKind::Subtitles;
}
return static_cast<TextTrackKind>(value->GetEnumValue());
}
static EnumEntry
StringFromKind(TextTrackKind aKind)
{
return TextTrackKindValues::strings[static_cast<int>(aKind)];
}
void
HTMLTrackElement::SetKind(TextTrackKind aKind, ErrorResult& aError)
{
const EnumEntry& string = StringFromKind(aKind);
nsAutoString kind;
kind.AssignASCII(string.value, string.length);
SetHTMLAttr(nsGkAtoms::kind, kind, aError);
}
bool
HTMLTrackElement::ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
// Map html attribute string values to TextTrackKind enums.
static const nsAttrValue::EnumTable kKindTable[] = {
{ "subtitles", static_cast<int16_t>(TextTrackKind::Subtitles) },
{ "captions", static_cast<int16_t>(TextTrackKind::Captions) },
{ "descriptions", static_cast<int16_t>(TextTrackKind::Descriptions) },
{ "chapters", static_cast<int16_t>(TextTrackKind::Chapters) },
{ "metadata", static_cast<int16_t>(TextTrackKind::Metadata) },
{ 0 }
};
if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::kind) {
// Case-insensitive lookup, with the first element as the default.
return aResult.ParseEnumValue(aValue, kKindTable, false, kKindTable);
}
// Otherwise call the generic implementation.
return nsGenericHTMLElement::ParseAttribute(aNamespaceID,
aAttribute,
aValue,
aResult);
}
nsresult
HTMLTrackElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument,
aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (!aDocument) {
return NS_OK;
}
LOG(PR_LOG_DEBUG, ("Track Element bound to tree."));
if (!aParent || !aParent->IsNodeOfType(nsINode::eMEDIA)) {
return NS_OK;
}
// Store our parent so we can look up its frame for display.
if (!mMediaParent) {
mMediaParent = static_cast<HTMLMediaElement*>(aParent);
HTMLMediaElement* media = static_cast<HTMLMediaElement*>(aParent);
// TODO: separate notification for 'alternate' tracks?
media->NotifyAddedSource();
LOG(PR_LOG_DEBUG, ("Track element sent notification to parent."));
// TODO: this section needs to become async in bug 833382.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=833385#c55.
// Find our 'src' url
nsAutoString src;
// TODO: we might want to instead call LoadResource() in a
// AfterSetAttr, like we do in media element.
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
nsCOMPtr<nsIURI> uri;
nsresult rvTwo = NewURIFromString(src, getter_AddRefs(uri));
if (NS_SUCCEEDED(rvTwo)) {
LOG(PR_LOG_ALWAYS, ("%p Trying to load from src=%s", this,
NS_ConvertUTF16toUTF8(src).get()));
// TODO: bug 833382 - dispatch a load request.
}
}
}
return NS_OK;
}
void
HTMLTrackElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
if (mMediaParent && aNullParent) {
mMediaParent = nullptr;
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,152 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_HTMLTrackElement_h
#define mozilla_dom_HTMLTrackElement_h
#define WEBVTT_NO_CONFIG_H 1
#define WEBVTT_STATIC 1
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/TextTrack.h"
#include "nsCycleCollectionParticipant.h"
#include "nsGenericHTMLElement.h"
#include "nsGkAtoms.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMEventTarget.h"
#include "nsIHttpChannel.h"
#include "webvtt/node.h"
namespace mozilla {
namespace dom {
class HTMLTrackElement MOZ_FINAL : public nsGenericHTMLElement
, public nsIDOMHTMLElement
{
public:
HTMLTrackElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~HTMLTrackElement();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTrackElement,
nsGenericHTMLElement)
// nsIDOMNode
NS_FORWARD_NSIDOMNODE_TO_NSINODE
// nsIDOMElement
NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
// nsIDOMHTMLElement
NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
// HTMLTrackElement WebIDL
TextTrackKind Kind() const;
void SetKind(TextTrackKind aKind, ErrorResult& aError);
void GetSrc(DOMString& aSrc) const
{
GetHTMLURIAttr(nsGkAtoms::src, aSrc);
}
void SetSrc(const nsAString& aSrc, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
}
void GetSrclang(DOMString& aSrclang) const
{
GetHTMLAttr(nsGkAtoms::srclang, aSrclang);
}
void SetSrclang(const nsAString& aSrclang, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::srclang, aSrclang, aError);
}
void GetLabel(DOMString& aLabel) const
{
GetHTMLAttr(nsGkAtoms::label, aLabel);
}
void SetLabel(const nsAString& aLabel, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::label, aLabel, aError);
}
bool Default() const
{
return GetBoolAttr(nsGkAtoms::_default);
}
void SetDefault(bool aDefault, ErrorResult& aError)
{
SetHTMLBoolAttr(nsGkAtoms::_default, aDefault, aError);
}
// Constants for numeric readyState property values.
enum {
NONE = 0U,
LOADING = 1U,
LOADED = 2U,
ERROR = 3U
};
uint16_t ReadyState() const
{
return mReadyState;
}
TextTrack* Track();
virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
// For Track, ItemValue reflects the src attribute
virtual void GetItemValueText(nsAString& aText)
{
DOMString value;
GetSrc(value);
aText = value;
}
virtual void SetItemValueText(const nsAString& aText)
{
ErrorResult rv;
SetSrc(aText, rv);
}
// Override ParseAttribute() to convert kind strings to enum values.
virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
// Override BindToTree() so that we can trigger a load when we become
// the child of a media element.
virtual nsresult BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers) MOZ_OVERRIDE;
virtual void UnbindFromTree(bool aDeep, bool aNullParent) MOZ_OVERRIDE;
void DisplayCueText(webvtt_node* head);
// Check enabling preference.
static bool IsWebVTTEnabled();
protected:
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
nsRefPtr<TextTrack> mTrack;
nsCOMPtr<nsIChannel> mChannel;
nsRefPtr<HTMLMediaElement> mMediaParent;
uint16_t mReadyState;
void CreateTextTrack();
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_HTMLTrackElement_h

View File

@ -81,6 +81,7 @@ CPPSRCS = \
HTMLTextAreaElement.cpp \
HTMLTimeElement.cpp \
HTMLTitleElement.cpp \
HTMLTrackElement.cpp \
HTMLVideoElement.cpp \
HTMLUnknownElement.cpp \
MediaError.cpp \
@ -118,4 +119,6 @@ INCLUDES += \
-I$(topsrcdir)/xpcom/ds \
$(NULL)
DEFINES += -D_IMPL_NS_LAYOUT
DEFINES += \
-D_IMPL_NS_LAYOUT \
$(NULL)

View File

@ -67,6 +67,7 @@ EXPORTS.mozilla.dom += [
'HTMLTextAreaElement.h',
'HTMLTimeElement.h',
'HTMLTitleElement.h',
'HTMLTrackElement.h',
'HTMLUnknownElement.h',
'MediaError.h',
'TimeRanges.h',

View File

@ -3325,3 +3325,37 @@ nsGenericHTMLElement::IsEventAttributeName(nsIAtom *aName)
{
return nsContentUtils::IsEventAttributeName(aName, EventNameType_HTML);
}
/**
* Construct a URI from a string, as an element.src attribute
* would be set to. Helper for the media elements.
*/
nsresult
nsGenericHTMLElement::NewURIFromString(const nsAutoString& aURISpec,
nsIURI** aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
*aURI = nullptr;
nsCOMPtr<nsIDocument> doc = OwnerDoc();
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(aURI, aURISpec,
doc, baseURI);
NS_ENSURE_SUCCESS(rv, rv);
bool equal;
if (aURISpec.IsEmpty() &&
doc->GetDocumentURI() &&
NS_SUCCEEDED(doc->GetDocumentURI()->Equals(*aURI, &equal)) &&
equal) {
// Assume an element can't point to a fragment of its embedding
// document. Fail here instead of returning the recursive URI
// and waiting for the subsequent load to fail.
NS_RELEASE(*aURI);
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
return NS_OK;
}

View File

@ -795,6 +795,13 @@ protected:
virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
/**
* Create a URI for the given aURISpec string.
* Returns INVALID_STATE_ERR and nulls *aURI if aURISpec is empty
* and the document's URI matches the element's base URI.
*/
nsresult NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI);
void GetHTMLAttr(nsIAtom* aName, nsAString& aResult) const
{
GetAttr(kNameSpaceID_None, aName, aResult);
@ -1981,6 +1988,7 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Tfoot)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Thead)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Time)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Title)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Track)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Unknown)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Video)

View File

@ -35,6 +35,10 @@ CPPSRCS = \
MediaStreamGraph.cpp \
MediaStreamTrack.cpp \
StreamBuffer.cpp \
TextTrack.cpp \
TextTrackList.cpp \
TextTrackCue.cpp \
TextTrackCueList.cpp \
VideoFrameContainer.cpp \
VideoSegment.cpp \
VideoStreamTrack.cpp \

View File

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 et tw=78: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TextTrack.h"
#include "mozilla/dom/TextTrackBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(TextTrack,
mParent,
mCueList,
mActiveCueList)
NS_IMPL_ADDREF_INHERITED(TextTrack, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(TextTrack, nsDOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrack)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
TextTrack::TextTrack(nsISupports* aParent,
TextTrackKind aKind,
const nsAString& aLabel,
const nsAString& aLanguage)
: mParent(aParent)
, mKind(aKind)
, mLabel(aLabel)
, mLanguage(aLanguage)
, mMode(TextTrackMode::Hidden)
, mCueList(new TextTrackCueList(aParent))
, mActiveCueList(new TextTrackCueList(aParent))
{
SetIsDOMBinding();
}
TextTrack::TextTrack(nsISupports* aParent)
: mParent(aParent)
, mKind(TextTrackKind::Subtitles)
, mMode(TextTrackMode::Disabled)
, mCueList(new TextTrackCueList(aParent))
, mActiveCueList(new TextTrackCueList(aParent))
{
SetIsDOMBinding();
}
void
TextTrack::Update(double time)
{
mCueList->Update(time);
}
JSObject*
TextTrack::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return TextTrackBinding::Wrap(aCx, aScope, this);
}
void
TextTrack::SetMode(TextTrackMode aValue)
{
mMode = aValue;
}
void
TextTrack::AddCue(TextTrackCue& aCue)
{
//XXX: If cue exists, remove. Bug 867823.
mCueList->AddCue(aCue);
}
void
TextTrack::RemoveCue(TextTrackCue& aCue)
{
//XXX: If cue does not exists throw NotFoundError. Bug 867823.
mCueList->RemoveCue(aCue);
}
void
TextTrack::CueChanged(TextTrackCue& aCue)
{
//XXX: Implement Cue changed. Bug 867823.
}
} // namespace dom
} // namespace mozilla

109
content/media/TextTrack.h Normal file
View File

@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 et tw=78: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TextTrack_h
#define mozilla_dom_TextTrack_h
#include "mozilla/dom/TextTrackBinding.h"
#include "mozilla/dom/TextTrackCue.h"
#include "mozilla/dom/TextTrackCueList.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMEventTargetHelper.h"
#include "nsString.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class TextTrackCue;
class TextTrackCueList;
class TextTrack MOZ_FINAL : public nsDOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrack,
nsDOMEventTargetHelper)
TextTrack(nsISupports* aParent);
TextTrack(nsISupports* aParent,
TextTrackKind aKind,
const nsAString& aLabel,
const nsAString& aLanguage);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
nsISupports* GetParentObject() const
{
return mParent;
}
TextTrackKind Kind() const
{
return mKind;
}
void GetLabel(nsAString& aLabel) const
{
aLabel = mLabel;
}
void GetLanguage(nsAString& aLanguage) const
{
aLanguage = mLanguage;
}
void GetInBandMetadataTrackDispatchType(nsAString& aType) const
{
aType = mType;
}
TextTrackMode Mode() const
{
return mMode;
}
void SetMode(TextTrackMode aValue);
TextTrackCueList* GetCues() const
{
if (mMode == TextTrackMode::Disabled) {
return nullptr;
}
return mCueList;
}
TextTrackCueList* GetActiveCues() const
{
if (mMode == TextTrackMode::Disabled) {
return nullptr;
}
return mActiveCueList;
}
void Update(double time);
void AddCue(TextTrackCue& aCue);
void RemoveCue(TextTrackCue& aCue);
void CueChanged(TextTrackCue& aCue);
IMPL_EVENT_HANDLER(cuechange)
private:
nsCOMPtr<nsISupports> mParent;
TextTrackKind mKind;
nsString mLabel;
nsString mLanguage;
nsString mType;
TextTrackMode mMode;
nsRefPtr<TextTrackCueList> mCueList;
nsRefPtr<TextTrackCueList> mActiveCueList;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TextTrack_h

View File

@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/HTMLTrackElement.h"
#include "mozilla/dom/TextTrackCue.h"
#include "mozilla/dom/TextTrackCueBinding.h"
#include "webvtt/cue.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(TextTrackCue,
mGlobal,
mTrack,
mTrackElement)
NS_IMPL_ADDREF_INHERITED(TextTrackCue, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(TextTrackCue, nsDOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackCue)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
// Set cue setting defaults based on step 19 & seq.
// in http://dev.w3.org/html5/webvtt/#parsing
void
TextTrackCue::SetDefaultCueSettings()
{
mPosition = 50;
mSize = 100;
mPauseOnExit = false;
mSnapToLines = true;
mLine = WEBVTT_AUTO;
mAlign = TextTrackCueAlign::Middle;
}
TextTrackCue::TextTrackCue(nsISupports* aGlobal,
double aStartTime,
double aEndTime,
const nsAString& aText)
: mGlobal(aGlobal)
, mText(aText)
, mStartTime(aStartTime)
, mEndTime(aEndTime)
, mHead(nullptr)
{
SetDefaultCueSettings();
MOZ_ASSERT(aGlobal);
SetIsDOMBinding();
}
TextTrackCue::TextTrackCue(nsISupports* aGlobal,
double aStartTime,
double aEndTime,
const nsAString& aText,
HTMLTrackElement* aTrackElement,
webvtt_node* head)
: mGlobal(aGlobal)
, mText(aText)
, mStartTime(aStartTime)
, mEndTime(aEndTime)
, mTrackElement(aTrackElement)
, mHead(head)
{
// Use the webvtt library's reference counting.
webvtt_ref_node(mHead);
SetDefaultCueSettings();
MOZ_ASSERT(aGlobal);
SetIsDOMBinding();
}
TextTrackCue::~TextTrackCue()
{
if (mHead) {
// Release our reference and null mHead.
webvtt_release_node(&mHead);
}
}
void
TextTrackCue::DisplayCue()
{
if (mTrackElement) {
mTrackElement->DisplayCueText(mHead);
}
}
JSObject*
TextTrackCue::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return TextTrackCueBinding::Wrap(aCx, aScope, this);
}
void
TextTrackCue::CueChanged()
{
if (mTrack) {
mTrack->CueChanged(*this);
}
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,277 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 et tw=78: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TextTrackCue_h
#define mozilla_dom_TextTrackCue_h
#define WEBVTT_NO_CONFIG_H 1
#define WEBVTT_STATIC 1
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/TextTrack.h"
#include "mozilla/dom/TextTrackCueBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMEventTargetHelper.h"
#include "webvtt/node.h"
namespace mozilla {
namespace dom {
class HTMLTrackElement;
class TextTrack;
class TextTrackCue MOZ_FINAL : public nsDOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrackCue,
nsDOMEventTargetHelper)
// TextTrackCue WebIDL
// See bug 868509 about splitting out the WebVTT-specific interfaces.
static already_AddRefed<TextTrackCue>
Constructor(GlobalObject& aGlobal,
double aStartTime,
double aEndTime,
const nsAString& aText,
ErrorResult& aRv)
{
nsRefPtr<TextTrackCue> ttcue = new TextTrackCue(aGlobal.Get(), aStartTime,
aEndTime, aText);
return ttcue.forget();
}
TextTrackCue(nsISupports* aGlobal, double aStartTime, double aEndTime,
const nsAString& aText);
TextTrackCue(nsISupports* aGlobal, double aStartTime, double aEndTime,
const nsAString& aText, HTMLTrackElement* aTrackElement,
webvtt_node* head);
~TextTrackCue();
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
nsISupports* GetParentObject()
{
return mGlobal;
}
TextTrack* GetTrack() const
{
return mTrack;
}
void GetId(nsAString& aId) const
{
aId = mId;
}
void SetId(const nsAString& aId)
{
if (mId == aId) {
return;
}
mId = aId;
CueChanged();
}
double StartTime() const
{
return mStartTime;
}
void SetStartTime(double aStartTime)
{
//XXXhumph: validate? bug 868519.
if (mStartTime == aStartTime)
return;
mStartTime = aStartTime;
CueChanged();
}
double EndTime() const
{
return mEndTime;
}
void SetEndTime(double aEndTime)
{
//XXXhumph: validate? bug 868519.
if (mEndTime == aEndTime)
return;
mEndTime = aEndTime;
CueChanged();
}
bool PauseOnExit()
{
return mPauseOnExit;
}
void SetPauseOnExit(bool aPauseOnExit)
{
if (mPauseOnExit == aPauseOnExit)
return;
mPauseOnExit = aPauseOnExit;
CueChanged();
}
void GetVertical(nsAString& aVertical)
{
aVertical = mVertical;
}
void SetVertical(const nsAString& aVertical)
{
if (mVertical == aVertical)
return;
mVertical = aVertical;
CueChanged();
}
bool SnapToLines()
{
return mSnapToLines;
}
void SetSnapToLines(bool aSnapToLines)
{
if (mSnapToLines == aSnapToLines)
return;
mSnapToLines = aSnapToLines;
CueChanged();
}
double Line() const
{
return mLine;
}
void SetLine(double aLine)
{
//XXX: validate? bug 868519.
mLine = aLine;
}
int32_t Position() const
{
return mPosition;
}
void SetPosition(int32_t aPosition)
{
// XXXhumph: validate? bug 868519.
if (mPosition == aPosition)
return;
mPosition = aPosition;
CueChanged();
}
int32_t Size() const
{
return mSize;
}
void SetSize(int32_t aSize)
{
if (mSize == aSize) {
return;
}
if (aSize < 0 || aSize > 100) {
//XXX:throw IndexSizeError; bug 868519.
}
mSize = aSize;
CueChanged();
}
TextTrackCueAlign Align() const
{
return mAlign;
}
void SetAlign(TextTrackCueAlign& aAlign)
{
if (mAlign == aAlign)
return;
mAlign = aAlign;
CueChanged();
}
void GetText(nsAString& aText) const
{
aText = mText;
}
void SetText(const nsAString& aText)
{
// XXXhumph: validate? bug 868519.
if (mText == aText)
return;
mText = aText;
CueChanged();
}
already_AddRefed<DocumentFragment> GetCueAsHTML() const
{
// XXXhumph: todo. Bug 868509.
return nullptr;
}
IMPL_EVENT_HANDLER(enter)
IMPL_EVENT_HANDLER(exit)
// Helper functions for implementation.
bool
operator==(const TextTrackCue& rhs) const
{
return mId.Equals(rhs.mId);
}
const nsAString& Id() const
{
return mId;
}
void DisplayCue();
private:
void CueChanged();
void SetDefaultCueSettings();
nsCOMPtr<nsISupports> mGlobal;
nsString mText;
double mStartTime;
double mEndTime;
nsRefPtr<TextTrack> mTrack;
nsRefPtr<HTMLTrackElement> mTrackElement;
webvtt_node *mHead;
nsString mId;
int32_t mPosition;
int32_t mSize;
bool mPauseOnExit;
bool mSnapToLines;
nsString mVertical;
int mLine;
TextTrackCueAlign mAlign;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TextTrackCue_h

View File

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TextTrackCueList.h"
#include "mozilla/dom/TextTrackCueListBinding.h"
#include "mozilla/dom/TextTrackCue.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(TextTrackCueList, mParent, mList)
NS_IMPL_CYCLE_COLLECTING_ADDREF(TextTrackCueList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TextTrackCueList)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextTrackCueList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
TextTrackCueList::TextTrackCueList(nsISupports* aParent) : mParent(aParent)
{
SetIsDOMBinding();
}
void
TextTrackCueList::Update(double time)
{
const uint32_t length = mList.Length();
for (uint32_t i = 0; i < length; i++) {
if (time > mList[i]->StartTime() && time < mList[i]->EndTime()) {
mList[i]->DisplayCue();
}
}
}
JSObject*
TextTrackCueList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return TextTrackCueListBinding::Wrap(aCx, aScope, this);
}
TextTrackCue*
TextTrackCueList::IndexedGetter(uint32_t aIndex, bool& aFound)
{
aFound = aIndex < mList.Length();
return aFound ? mList[aIndex] : nullptr;
}
TextTrackCue*
TextTrackCueList::GetCueById(const nsAString& aId)
{
if (aId.IsEmpty()) {
return nullptr;
}
for (uint32_t i = 0; i < mList.Length(); i++) {
if (aId.Equals(mList[i]->Id())) {
return mList[i];
}
}
return nullptr;
}
void
TextTrackCueList::AddCue(TextTrackCue& cue)
{
mList.AppendElement(&cue);
}
void
TextTrackCueList::RemoveCue(TextTrackCue& cue)
{
mList.RemoveElement(&cue);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 et tw=78: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TextTrackCueList_h
#define mozilla_dom_TextTrackCueList_h
#include "mozilla/dom/TextTrackCue.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class TextTrackCue;
class TextTrackCueList MOZ_FINAL : public nsISupports
, public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextTrackCueList)
// TextTrackCueList WebIDL
TextTrackCueList(nsISupports* aParent);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
nsISupports* GetParentObject() const
{
return mParent;
}
uint32_t Length() const
{
return mList.Length();
}
void Update(double time);
TextTrackCue* IndexedGetter(uint32_t aIndex, bool& aFound);
TextTrackCue* GetCueById(const nsAString& aId);
void AddCue(TextTrackCue& cue);
void RemoveCue(TextTrackCue& cue);
private:
nsCOMPtr<nsISupports> mParent;
nsTArray< nsRefPtr<TextTrackCue> > mList;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TextTrackCueList_h

View File

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TextTrackList.h"
#include "mozilla/dom/TextTrackListBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(TextTrackList, mGlobal, mTextTracks)
NS_IMPL_ADDREF_INHERITED(TextTrackList, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(TextTrackList, nsDOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackList)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
TextTrackList::TextTrackList(nsISupports* aGlobal) : mGlobal(aGlobal)
{
SetIsDOMBinding();
}
JSObject*
TextTrackList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return TextTrackListBinding::Wrap(aCx, aScope, this);
}
TextTrack*
TextTrackList::IndexedGetter(uint32_t aIndex, bool& aFound)
{
aFound = aIndex < mTextTracks.Length();
return aFound ? mTextTracks[aIndex] : nullptr;
}
already_AddRefed<TextTrack>
TextTrackList::AddTextTrack(TextTrackKind aKind,
const nsAString& aLabel,
const nsAString& aLanguage)
{
nsRefPtr<TextTrack> track = new TextTrack(mGlobal, aKind, aLabel, aLanguage);
mTextTracks.AppendElement(track);
// TODO: dispatch addtrack event
return track.forget();
}
void
TextTrackList::RemoveTextTrack(const TextTrack& aTrack)
{
mTextTracks.RemoveElement(&aTrack);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 et tw=78: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TextTrackList_h
#define mozilla_dom_TextTrackList_h
#include "mozilla/dom/TextTrack.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMEventTargetHelper.h"
namespace mozilla {
namespace dom {
class TextTrack;
class TextTrackList MOZ_FINAL : public nsDOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrackList,
nsDOMEventTargetHelper)
TextTrackList(nsISupports* aGlobal);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
nsISupports* GetParentObject() const
{
return mGlobal;
}
uint32_t Length() const
{
return mTextTracks.Length();
}
void Update(double time) {
uint32_t length = Length(), i;
for( i = 0; i < length; i++ ) {
mTextTracks[i]->Update(time);
}
}
TextTrack* IndexedGetter(uint32_t aIndex, bool& aFound);
already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
const nsAString& aLabel,
const nsAString& aLanguage);
void AddTextTrack(TextTrack* aTextTrack) {
mTextTracks.AppendElement(aTextTrack);
}
void RemoveTextTrack(const TextTrack& aTrack);
IMPL_EVENT_HANDLER(addtrack)
IMPL_EVENT_HANDLER(removetrack)
private:
nsCOMPtr<nsISupports> mGlobal;
nsTArray< nsRefPtr<TextTrack> > mTextTracks;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TextTrackList_h

View File

@ -77,6 +77,9 @@ EXPORTS += [
EXPORTS.mozilla.dom += [
'AudioStreamTrack.h',
'MediaStreamTrack.h',
'TextTrack.h',
'TextTrackCue.h',
'TextTrackCueList.h',
'TextTrackList.h',
'VideoStreamTrack.h',
]

View File

@ -87,8 +87,12 @@ interface HTMLMediaElement : HTMLElement {
// tracks
//readonly attribute AudioTrackList audioTracks;
//readonly attribute VideoTrackList videoTracks;
//readonly attribute TextTrackList textTracks;
//TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
[Pref="media.webvtt.enabled"]
readonly attribute TextTrackList textTracks;
[Pref="media.webvtt.enabled"]
TextTrack addTextTrack(TextTrackKind kind,
optional DOMString label = "",
optional DOMString language = "");
};
// Mozilla extensions:

View File

@ -0,0 +1,30 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#the-track-element
*/
[Pref="media.webvtt.enabled"]
interface HTMLTrackElement : HTMLElement {
[SetterThrows, Pure]
attribute TextTrackKind kind;
[SetterThrows, Pure]
attribute DOMString src;
[SetterThrows, Pure]
attribute DOMString srclang;
[SetterThrows, Pure]
attribute DOMString label;
[SetterThrows, Pure]
attribute boolean default;
const unsigned short NONE = 0;
const unsigned short LOADING = 1;
const unsigned short LOADED = 2;
const unsigned short ERROR = 3;
readonly attribute unsigned short readyState;
readonly attribute TextTrack track;
};

View File

@ -0,0 +1,41 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#texttrack
*/
enum TextTrackKind {
"subtitles",
"captions",
"descriptions",
"chapters",
"metadata"
};
enum TextTrackMode {
"disabled",
"hidden",
"showing"
};
[Pref="media.webvtt.enabled"]
interface TextTrack : EventTarget {
readonly attribute TextTrackKind kind;
readonly attribute DOMString label;
readonly attribute DOMString language;
readonly attribute DOMString inBandMetadataTrackDispatchType;
attribute TextTrackMode mode;
readonly attribute TextTrackCueList? cues;
readonly attribute TextTrackCueList? activeCues;
void addCue(TextTrackCue cue);
void removeCue(TextTrackCue cue);
[SetterThrows]
attribute EventHandler oncuechange;
};

View File

@ -0,0 +1,46 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#texttrackcue
*/
enum AutoKeyword { "auto" };
/* Non-spec: Request to add this enum to spec
* can be found here: https://www.w3.org/Bugs/Public/show_bug.cgi?id=20996 */
enum TextTrackCueAlign {
"start",
"middle",
"end",
"left",
"right"
};
[Constructor(double startTime, double endTime, DOMString text),
Pref="media.webvtt.enabled"]
interface TextTrackCue : EventTarget {
readonly attribute TextTrack? track;
attribute DOMString id;
attribute double startTime;
attribute double endTime;
attribute boolean pauseOnExit;
attribute DOMString vertical;
attribute boolean snapToLines;
// XXXhumph: https://www.w3.org/Bugs/Public/show_bug.cgi?id=20651
// attribute (long or AutoKeyword) line;
attribute long position;
attribute long size;
attribute TextTrackCueAlign align;
attribute DOMString text;
DocumentFragment getCueAsHTML();
[SetterThrows]
attribute EventHandler onenter;
[SetterThrows]
attribute EventHandler onexit;
};

View File

@ -0,0 +1,15 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#texttrackcuelist
*/
[Pref="media.webvtt.enabled"]
interface TextTrackCueList {
readonly attribute unsigned long length;
getter TextTrackCue (unsigned long index);
TextTrackCue? getCueById(DOMString id);
};

View File

@ -0,0 +1,19 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#texttracklist
*/
[Pref="media.webvtt.enabled"]
interface TextTrackList : EventTarget {
readonly attribute unsigned long length;
getter TextTrack (unsigned long index);
[SetterThrows]
attribute EventHandler onaddtrack;
[SetterThrows]
attribute EventHandler onremovetrack;
};

View File

@ -150,6 +150,7 @@ webidl_files = \
HTMLTableSectionElement.webidl \
HTMLTemplateElement.webidl \
HTMLTextAreaElement.webidl \
HTMLTrackElement.webidl \
HTMLTimeElement.webidl \
HTMLTitleElement.webidl \
HTMLUListElement.webidl \
@ -315,6 +316,10 @@ webidl_files = \
Text.webidl \
TextDecoder.webidl \
TextEncoder.webidl \
TextTrack.webidl \
TextTrackCue.webidl \
TextTrackCueList.webidl \
TextTrackList.webidl \
TimeRanges.webidl \
Touch.webidl \
TouchEvent.webidl \

View File

@ -152,6 +152,7 @@ EDITOR_ATOM(thead, "thead")
EDITOR_ATOM(th, "th")
EDITOR_ATOM(time, "time")
EDITOR_ATOM(tr, "tr")
EDITOR_ATOM(track, "track")
EDITOR_ATOM(tt, "tt")
EDITOR_ATOM(ul, "ul")
EDITOR_ATOM(u, "u")

View File

@ -748,6 +748,7 @@ static const nsElementInfo kElements[eHTMLTag_userdefined] = {
ELEM(time, true, false, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
ELEM(title, true, false, GROUP_HEAD_CONTENT, GROUP_LEAF),
ELEM(tr, true, false, GROUP_TBODY_CONTENT, GROUP_TR_CONTENT),
ELEM(track, false, false, GROUP_NONE, GROUP_NONE),
ELEM(tt, true, true, GROUP_FONTSTYLE, GROUP_INLINE_ELEMENT),
ELEM(u, true, true, GROUP_FONTSTYLE, GROUP_INLINE_ELEMENT),
// XXX Can contain self and ol because editor does sublists illegally.

View File

@ -575,3 +575,9 @@ hb_unicode_funcs_set_eastasian_width_func
hb_unicode_funcs_set_general_category_func
hb_unicode_funcs_set_mirroring_func
hb_unicode_funcs_set_script_func
webvtt_string_text
webvtt_create_parser
webvtt_delete_parser
webvtt_parse_chunk
webvtt_ref_node
webvtt_release_node

View File

@ -202,6 +202,8 @@ pref("media.peerconnection.noise", 1);
pref("media.navigator.enabled", true);
#endif
#endif
// TextTrack support
pref("media.webvtt.enabled", false);
#ifdef MOZ_WEBSPEECH
pref("media.webspeech.recognition.enable", false);

View File

@ -153,6 +153,7 @@ HTML_TAG(template, Template)
HTML_TAG(time, Time)
HTML_TAG(title, Title)
HTML_TAG(tr, TableRow)
HTML_TAG(track, Track)
HTML_HTMLELEMENT_TAG(tt)
HTML_HTMLELEMENT_TAG(u)
HTML_TAG(ul, SharedList)

View File

@ -44,6 +44,7 @@ DECL_TAG_LIST(gParamParents,{eHTMLTag_applet COMMA eHTMLTag_object})
DECL_TAG_LIST(gTRParents,{eHTMLTag_tbody COMMA eHTMLTag_tfoot COMMA eHTMLTag_thead COMMA eHTMLTag_table})
DECL_TAG_LIST(gTREndParents,{eHTMLTag_tbody COMMA eHTMLTag_tfoot COMMA eHTMLTag_thead COMMA eHTMLTag_table COMMA eHTMLTag_applet})
DECL_TAG_LIST(gSourceParents,{eHTMLTag_video COMMA eHTMLTag_audio})
DECL_TAG_LIST(gTrackParents,{eHTMLTag_video COMMA eHTMLTag_audio})
//*********************************************************************************************
// Next, define the set of taglists for tags with special kids...
@ -88,8 +89,8 @@ DECL_TAG_LIST(gTableElemKids,{eHTMLTag_form COMMA eHTMLTag_noscript COMMA eHTMLT
DECL_TAG_LIST(gTRKids,{eHTMLTag_td COMMA eHTMLTag_th COMMA eHTMLTag_form COMMA eHTMLTag_script})// Removed INPUT - Ref. Bug 20087, 25382 | Removed MAP to fix 58942
DECL_TAG_LIST(gTBodyKids,{eHTMLTag_tr COMMA eHTMLTag_form}) // Removed INPUT - Ref. Bug 20087, 25382
DECL_TAG_LIST(gULKids,{eHTMLTag_li COMMA eHTMLTag_p})
DECL_TAG_LIST(gVideoKids,{eHTMLTag_source})
DECL_TAG_LIST(gAudioKids,{eHTMLTag_source})
DECL_TAG_LIST(gVideoKids,{eHTMLTag_source COMMA eHTMLTag_track})
DECL_TAG_LIST(gAudioKids,{eHTMLTag_source COMMA eHTMLTag_track})
//*********************************************************************************************
// The following tag lists are used to define common set of root notes for the HTML elements...
@ -1229,6 +1230,15 @@ const nsHTMLElement gHTMLElements[] = {
/*special props, prop-range*/ (kBadContentWatch|kNoStyleLeaksIn|kNoStyleLeaksOut), kNoPropRange,
/*special parents,kids*/ &gTRParents,&gTRKids,
},
{
/*tag*/ eHTMLTag_track,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gTrackParents,&gTrackParents,
/*autoclose starttags and endtags*/ &gPAutoClose, 0, 0,0,
/*parent,incl,exclgroups*/ kSpecial, kNone, kNone,
/*special props, prop-range*/ kNonContainer,kNoPropRange,
/*special parents,kids*/ &gTrackParents,0,
},
{
/*tag*/ eHTMLTag_tt,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,

View File

@ -259,6 +259,8 @@ static const PRUnichar sHTMLTagUnicodeName_title[] =
{'t', 'i', 't', 'l', 'e', '\0'};
static const PRUnichar sHTMLTagUnicodeName_tr[] =
{'t', 'r', '\0'};
static const PRUnichar sHTMLTagUnicodeName_track[] =
{'t', 'r', 'a', 'c', 'k', '\0'};
static const PRUnichar sHTMLTagUnicodeName_tt[] =
{'t', 't', '\0'};
static const PRUnichar sHTMLTagUnicodeName_u[] =