Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "mozilla/dom/HTMLTrackElement.h"
7 : #include "mozilla/dom/TextTrackCue.h"
8 : #include "mozilla/dom/TextTrackList.h"
9 : #include "mozilla/dom/TextTrackRegion.h"
10 : #include "nsComponentManagerUtils.h"
11 : #include "mozilla/ClearOnShutdown.h"
12 :
13 : namespace mozilla {
14 : namespace dom {
15 :
16 0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrackCue,
17 : DOMEventTargetHelper,
18 : mDocument,
19 : mTrack,
20 : mTrackElement,
21 : mDisplayState,
22 : mRegion)
23 :
24 0 : NS_IMPL_ADDREF_INHERITED(TextTrackCue, DOMEventTargetHelper)
25 0 : NS_IMPL_RELEASE_INHERITED(TextTrackCue, DOMEventTargetHelper)
26 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackCue)
27 0 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
28 :
29 3 : StaticRefPtr<nsIWebVTTParserWrapper> TextTrackCue::sParserWrapper;
30 :
31 : // Set cue setting defaults based on step 19 & seq.
32 : // in http://dev.w3.org/html5/webvtt/#parsing
33 : void
34 0 : TextTrackCue::SetDefaultCueSettings()
35 : {
36 0 : mPositionIsAutoKeyword = true;
37 0 : mPositionAlign = PositionAlignSetting::Center;
38 0 : mSize = 100.0;
39 0 : mPauseOnExit = false;
40 0 : mSnapToLines = true;
41 0 : mLineIsAutoKeyword = true;
42 0 : mAlign = AlignSetting::Center;
43 0 : mLineAlign = LineAlignSetting::Start;
44 0 : mVertical = DirectionSetting::_empty;
45 0 : mActive = false;
46 0 : }
47 :
48 0 : TextTrackCue::TextTrackCue(nsPIDOMWindowInner* aOwnerWindow,
49 : double aStartTime,
50 : double aEndTime,
51 : const nsAString& aText,
52 0 : ErrorResult& aRv)
53 : : DOMEventTargetHelper(aOwnerWindow)
54 : , mText(aText)
55 : , mStartTime(aStartTime)
56 : , mEndTime(aEndTime)
57 : , mReset(false, "TextTrackCue::mReset")
58 : , mHaveStartedWatcher(false)
59 0 : , mWatchManager(this, GetOwnerGlobal()->AbstractMainThreadFor(TaskCategory::Other))
60 : {
61 0 : SetDefaultCueSettings();
62 0 : MOZ_ASSERT(aOwnerWindow);
63 0 : if (NS_FAILED(StashDocument())) {
64 0 : aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
65 : }
66 0 : }
67 :
68 0 : TextTrackCue::TextTrackCue(nsPIDOMWindowInner* aOwnerWindow,
69 : double aStartTime,
70 : double aEndTime,
71 : const nsAString& aText,
72 : HTMLTrackElement* aTrackElement,
73 0 : ErrorResult& aRv)
74 : : DOMEventTargetHelper(aOwnerWindow)
75 : , mText(aText)
76 : , mStartTime(aStartTime)
77 : , mEndTime(aEndTime)
78 : , mTrackElement(aTrackElement)
79 : , mReset(false, "TextTrackCue::mReset")
80 : , mHaveStartedWatcher(false)
81 0 : , mWatchManager(this, GetOwnerGlobal()->AbstractMainThreadFor(TaskCategory::Other))
82 : {
83 0 : SetDefaultCueSettings();
84 0 : MOZ_ASSERT(aOwnerWindow);
85 0 : if (NS_FAILED(StashDocument())) {
86 0 : aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
87 : }
88 0 : }
89 :
90 0 : TextTrackCue::~TextTrackCue()
91 : {
92 0 : }
93 :
94 : /** Save a reference to our creating document so we don't have to
95 : * keep getting it from our window.
96 : */
97 : nsresult
98 0 : TextTrackCue::StashDocument()
99 : {
100 0 : nsPIDOMWindowInner* window = GetOwner();
101 0 : if (!window) {
102 0 : return NS_ERROR_NO_INTERFACE;
103 : }
104 0 : mDocument = window->GetDoc();
105 0 : if (!mDocument) {
106 0 : return NS_ERROR_NOT_AVAILABLE;
107 : }
108 0 : return NS_OK;
109 : }
110 :
111 : already_AddRefed<DocumentFragment>
112 0 : TextTrackCue::GetCueAsHTML()
113 : {
114 : // mDocument may be null during cycle collector shutdown.
115 : // See bug 941701.
116 0 : if (!mDocument) {
117 0 : return nullptr;
118 : }
119 :
120 0 : if (!sParserWrapper) {
121 : nsresult rv;
122 : nsCOMPtr<nsIWebVTTParserWrapper> parserWrapper =
123 0 : do_CreateInstance(NS_WEBVTTPARSERWRAPPER_CONTRACTID, &rv);
124 0 : if (NS_FAILED(rv)) {
125 0 : return mDocument->CreateDocumentFragment();
126 : }
127 0 : sParserWrapper = parserWrapper;
128 0 : ClearOnShutdown(&sParserWrapper);
129 : }
130 :
131 0 : nsPIDOMWindowInner* window = mDocument->GetInnerWindow();
132 0 : if (!window) {
133 0 : return mDocument->CreateDocumentFragment();
134 : }
135 :
136 0 : nsCOMPtr<nsIDOMDocumentFragment> frag;
137 0 : sParserWrapper->ConvertCueToDOMTree(window, this,
138 0 : getter_AddRefs(frag));
139 0 : if (!frag) {
140 0 : return mDocument->CreateDocumentFragment();
141 : }
142 0 : return frag.forget().downcast<DocumentFragment>();
143 : }
144 :
145 : void
146 0 : TextTrackCue::SetTrackElement(HTMLTrackElement* aTrackElement)
147 : {
148 0 : mTrackElement = aTrackElement;
149 0 : }
150 :
151 : JSObject*
152 0 : TextTrackCue::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
153 : {
154 0 : return VTTCueBinding::Wrap(aCx, this, aGivenProto);
155 : }
156 :
157 : TextTrackRegion*
158 0 : TextTrackCue::GetRegion()
159 : {
160 0 : return mRegion;
161 : }
162 :
163 : void
164 0 : TextTrackCue::SetRegion(TextTrackRegion* aRegion)
165 : {
166 0 : if (mRegion == aRegion) {
167 0 : return;
168 : }
169 0 : mRegion = aRegion;
170 0 : mReset = true;
171 : }
172 :
173 : double
174 0 : TextTrackCue::ComputedLine()
175 : {
176 : // See spec https://w3c.github.io/webvtt/#cue-computed-line
177 0 : if (!mLineIsAutoKeyword && !mSnapToLines &&
178 0 : (mLine < 0.0 || mLine > 100.0)) {
179 0 : return 100.0;
180 0 : } else if (!mLineIsAutoKeyword) {
181 0 : return mLine;
182 0 : } else if (mLineIsAutoKeyword && !mSnapToLines) {
183 0 : return 100.0;
184 0 : } else if (!mTrack ||
185 0 : !mTrack->GetTextTrackList() ||
186 0 : !mTrack->GetTextTrackList()->GetMediaElement()) {
187 0 : return -1.0;
188 : }
189 :
190 0 : RefPtr<TextTrackList> trackList = mTrack->GetTextTrackList();
191 : bool dummy;
192 0 : uint32_t showingTracksNum = 0;
193 0 : for (uint32_t idx = 0; idx < trackList->Length(); idx++) {
194 0 : RefPtr<TextTrack> track = trackList->IndexedGetter(idx, dummy);
195 0 : if (track->Mode() == TextTrackMode::Showing) {
196 0 : showingTracksNum++;
197 : }
198 :
199 0 : if (mTrack == track) {
200 0 : break;
201 : }
202 : }
203 :
204 0 : return (-1.0) * showingTracksNum;
205 : }
206 :
207 : double
208 0 : TextTrackCue::ComputedPosition()
209 : {
210 : // See spec https://w3c.github.io/webvtt/#cue-computed-position
211 0 : if (!mPositionIsAutoKeyword) {
212 0 : return mPosition;
213 0 : } else if (mAlign == AlignSetting::Left) {
214 0 : return 0.0;
215 0 : } else if (mAlign == AlignSetting::Right) {
216 0 : return 100.0;
217 : }
218 0 : return 50.0;
219 : }
220 :
221 : PositionAlignSetting
222 0 : TextTrackCue::ComputedPositionAlign()
223 : {
224 : // See spec https://w3c.github.io/webvtt/#cue-computed-position-alignment
225 0 : if (mPositionAlign != PositionAlignSetting::Auto) {
226 0 : return mPositionAlign;
227 0 : } else if (mAlign == AlignSetting::Left) {
228 0 : return PositionAlignSetting::Line_left;
229 0 : } else if (mAlign == AlignSetting::Right) {
230 0 : return PositionAlignSetting::Line_right;
231 : }
232 0 : return PositionAlignSetting::Center;
233 : }
234 :
235 : void
236 0 : TextTrackCue::NotifyDisplayStatesChanged()
237 : {
238 0 : if (!mReset) {
239 0 : return;
240 : }
241 :
242 0 : if (!mTrack ||
243 0 : !mTrack->GetTextTrackList() ||
244 0 : !mTrack->GetTextTrackList()->GetMediaElement()) {
245 0 : return;
246 : }
247 :
248 0 : mTrack->GetTextTrackList()->GetMediaElement()->NotifyCueDisplayStatesChanged();
249 : }
250 :
251 : } // namespace dom
252 : } // namespace mozilla
|