gecko-dev/dom/media/TextTrackCue.h
2016-10-18 15:52:54 +03:00

419 lines
8.9 KiB
C++

/* -*- 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
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/VTTCueBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIWebVTTParserWrapper.h"
#include "mozilla/StaticPtr.h"
#include "nsIDocument.h"
#include "mozilla/dom/HTMLDivElement.h"
#include "mozilla/dom/TextTrack.h"
#include "mozilla/StateWatching.h"
namespace mozilla {
namespace dom {
class HTMLTrackElement;
class TextTrackRegion;
class TextTrackCue final : public DOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrackCue, DOMEventTargetHelper)
// 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)
{
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<TextTrackCue> ttcue = new TextTrackCue(window, aStartTime,
aEndTime, aText, aRv);
return ttcue.forget();
}
TextTrackCue(nsPIDOMWindowInner* aGlobal, double aStartTime, double aEndTime,
const nsAString& aText, ErrorResult& aRv);
TextTrackCue(nsPIDOMWindowInner* aGlobal, double aStartTime, double aEndTime,
const nsAString& aText, HTMLTrackElement* aTrackElement,
ErrorResult& aRv);
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
TextTrack* GetTrack() const
{
return mTrack;
}
void GetId(nsAString& aId) const
{
aId = mId;
}
void SetId(const nsAString& aId)
{
if (mId == aId) {
return;
}
mId = aId;
}
double StartTime() const
{
return mStartTime;
}
void SetStartTime(double aStartTime)
{
if (mStartTime == aStartTime) {
return;
}
mStartTime = aStartTime;
mReset = true;
NotifyCueUpdated(this);
}
double EndTime() const
{
return mEndTime;
}
void SetEndTime(double aEndTime)
{
if (mEndTime == aEndTime) {
return;
}
mEndTime = aEndTime;
mReset = true;
NotifyCueUpdated(this);
}
bool PauseOnExit()
{
return mPauseOnExit;
}
void SetPauseOnExit(bool aPauseOnExit)
{
if (mPauseOnExit == aPauseOnExit) {
return;
}
mPauseOnExit = aPauseOnExit;
NotifyCueUpdated(nullptr);
}
TextTrackRegion* GetRegion();
void SetRegion(TextTrackRegion* aRegion);
DirectionSetting Vertical() const
{
return mVertical;
}
void SetVertical(const DirectionSetting& aVertical)
{
if (mVertical == aVertical) {
return;
}
mReset = true;
mVertical = aVertical;
}
bool SnapToLines()
{
return mSnapToLines;
}
void SetSnapToLines(bool aSnapToLines)
{
if (mSnapToLines == aSnapToLines) {
return;
}
mReset = true;
mSnapToLines = aSnapToLines;
}
void GetLine(OwningDoubleOrAutoKeyword& aLine) const
{
if (mLineIsAutoKeyword) {
aLine.SetAsAutoKeyword() = AutoKeyword::Auto;
return;
}
aLine.SetAsDouble() = mLine;
}
void SetLine(const DoubleOrAutoKeyword& aLine)
{
if (aLine.IsDouble() &&
(mLineIsAutoKeyword || (aLine.GetAsDouble() != mLine))) {
mLineIsAutoKeyword = false;
mLine = aLine.GetAsDouble();
mReset = true;
return;
}
if (aLine.IsAutoKeyword() && !mLineIsAutoKeyword) {
mLineIsAutoKeyword = true;
mReset = true;
}
}
LineAlignSetting LineAlign() const
{
return mLineAlign;
}
void SetLineAlign(LineAlignSetting& aLineAlign, ErrorResult& aRv)
{
if (mLineAlign == aLineAlign) {
return;
}
mReset = true;
mLineAlign = aLineAlign;
}
void GetPosition(OwningDoubleOrAutoKeyword& aPosition) const
{
if (mPositionIsAutoKeyword) {
aPosition.SetAsAutoKeyword() = AutoKeyword::Auto;
return;
}
aPosition.SetAsDouble() = mPosition;
}
void SetPosition(const DoubleOrAutoKeyword& aPosition, ErrorResult& aRv)
{
if (!aPosition.IsAutoKeyword() &&
(aPosition.GetAsDouble() > 100.0 || aPosition.GetAsDouble() < 0.0)){
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
if (aPosition.IsDouble() &&
(mPositionIsAutoKeyword || (aPosition.GetAsDouble() != mPosition))) {
mPositionIsAutoKeyword = false;
mPosition = aPosition.GetAsDouble();
mReset = true;
return;
}
if (aPosition.IsAutoKeyword() && !mPositionIsAutoKeyword) {
mPositionIsAutoKeyword = true;
mReset = true;
}
}
PositionAlignSetting PositionAlign() const
{
return mPositionAlign;
}
void SetPositionAlign(PositionAlignSetting aPositionAlign, ErrorResult& aRv)
{
if (mPositionAlign == aPositionAlign) {
return;
}
mReset = true;
mPositionAlign = aPositionAlign;
}
double Size() const
{
return mSize;
}
void SetSize(double aSize, ErrorResult& aRv)
{
if (mSize == aSize) {
return;
}
if (aSize < 0.0 || aSize > 100.0) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
mReset = true;
mSize = aSize;
}
AlignSetting Align() const
{
return mAlign;
}
void SetAlign(AlignSetting& aAlign)
{
if (mAlign == aAlign) {
return;
}
mReset = true;
mAlign = aAlign;
}
void GetText(nsAString& aText) const
{
aText = mText;
}
void SetText(const nsAString& aText)
{
if (mText == aText) {
return;
}
mReset = true;
mText = aText;
}
IMPL_EVENT_HANDLER(enter)
IMPL_EVENT_HANDLER(exit)
HTMLDivElement* GetDisplayState()
{
return static_cast<HTMLDivElement*>(mDisplayState.get());
}
void SetDisplayState(HTMLDivElement* aDisplayState)
{
mDisplayState = aDisplayState;
mReset = false;
}
void Reset()
{
mReset = true;
}
bool HasBeenReset()
{
return mReset;
}
double ComputedLine();
double ComputedPosition();
PositionAlignSetting ComputedPositionAlign();
// Helper functions for implementation.
const nsAString& Id() const
{
return mId;
}
void SetTrack(TextTrack* aTextTrack)
{
mTrack = aTextTrack;
if (!mHaveStartedWatcher && aTextTrack) {
mHaveStartedWatcher = true;
mWatchManager.Watch(mReset, &TextTrackCue::NotifyDisplayStatesChanged);
} else if (mHaveStartedWatcher && !aTextTrack) {
mHaveStartedWatcher = false;
mWatchManager.Unwatch(mReset, &TextTrackCue::NotifyDisplayStatesChanged);
}
}
/**
* Produces a tree of anonymous content based on the tree of the processed
* cue text.
*
* Returns a DocumentFragment that is the head of the tree of anonymous
* content.
*/
already_AddRefed<DocumentFragment> GetCueAsHTML();
void SetTrackElement(HTMLTrackElement* aTrackElement);
void SetActive(bool aActive)
{
if (mActive == aActive) {
return;
}
mActive = aActive;
mDisplayState = mActive ? mDisplayState : nullptr;
}
bool GetActive()
{
return mActive;
}
private:
~TextTrackCue();
void NotifyCueUpdated(TextTrackCue* aCue)
{
if (mTrack) {
mTrack->NotifyCueUpdated(aCue);
}
}
void NotifyDisplayStatesChanged();
void SetDefaultCueSettings();
nsresult StashDocument();
RefPtr<nsIDocument> mDocument;
nsString mText;
double mStartTime;
double mEndTime;
RefPtr<TextTrack> mTrack;
RefPtr<HTMLTrackElement> mTrackElement;
nsString mId;
MOZ_INIT_OUTSIDE_CTOR double mPosition;
bool mPositionIsAutoKeyword;
PositionAlignSetting mPositionAlign;
double mSize;
bool mPauseOnExit;
bool mSnapToLines;
RefPtr<TextTrackRegion> mRegion;
DirectionSetting mVertical;
bool mLineIsAutoKeyword;
MOZ_INIT_OUTSIDE_CTOR double mLine;
AlignSetting mAlign;
LineAlignSetting mLineAlign;
// Holds the computed DOM elements that represent the parsed cue text.
// http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-display-state
RefPtr<nsGenericHTMLElement> mDisplayState;
// Tells whether or not we need to recompute mDisplayState. This is set
// anytime a property that relates to the display of the TextTrackCue is
// changed.
Watchable<bool> mReset;
bool mActive;
static StaticRefPtr<nsIWebVTTParserWrapper> sParserWrapper;
// Only start watcher after the cue has text track.
bool mHaveStartedWatcher;
WatchManager<TextTrackCue> mWatchManager;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TextTrackCue_h