Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/TextTrackCue.cpp
Line
Count
Source (jump to first uncovered line)
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
NS_IMPL_CYCLE_COLLECTION_INHERITED(TextTrackCue,
17
                                   DOMEventTargetHelper,
18
                                   mDocument,
19
                                   mTrack,
20
                                   mTrackElement,
21
                                   mDisplayState,
22
                                   mRegion)
23
24
NS_IMPL_ADDREF_INHERITED(TextTrackCue, DOMEventTargetHelper)
25
NS_IMPL_RELEASE_INHERITED(TextTrackCue, DOMEventTargetHelper)
26
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextTrackCue)
27
0
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
28
29
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
TextTrackCue::SetDefaultCueSettings()
35
0
{
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
TextTrackCue::TextTrackCue(nsPIDOMWindowInner* aOwnerWindow,
49
                           double aStartTime,
50
                           double aEndTime,
51
                           const nsAString& aText,
52
                           ErrorResult& aRv)
53
  : DOMEventTargetHelper(aOwnerWindow)
54
  , mText(aText)
55
  , mStartTime(aStartTime)
56
  , mEndTime(aEndTime)
57
  , mPosition(0.0)
58
  , mLine(0.0)
59
  , mReset(false, "TextTrackCue::mReset")
60
  , mHaveStartedWatcher(false)
61
  , mWatchManager(this, GetOwnerGlobal()->AbstractMainThreadFor(TaskCategory::Other))
62
0
{
63
0
  SetDefaultCueSettings();
64
0
  MOZ_ASSERT(aOwnerWindow);
65
0
  if (NS_FAILED(StashDocument())) {
66
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
67
0
  }
68
0
}
69
70
TextTrackCue::TextTrackCue(nsPIDOMWindowInner* aOwnerWindow,
71
                           double aStartTime,
72
                           double aEndTime,
73
                           const nsAString& aText,
74
                           HTMLTrackElement* aTrackElement,
75
                           ErrorResult& aRv)
76
  : DOMEventTargetHelper(aOwnerWindow)
77
  , mText(aText)
78
  , mStartTime(aStartTime)
79
  , mEndTime(aEndTime)
80
  , mTrackElement(aTrackElement)
81
  , mPosition(0.0)
82
  , mLine(0.0)
83
  , mReset(false, "TextTrackCue::mReset")
84
  , mHaveStartedWatcher(false)
85
  , mWatchManager(this, GetOwnerGlobal()->AbstractMainThreadFor(TaskCategory::Other))
86
0
{
87
0
  SetDefaultCueSettings();
88
0
  MOZ_ASSERT(aOwnerWindow);
89
0
  if (NS_FAILED(StashDocument())) {
90
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
91
0
  }
92
0
}
93
94
TextTrackCue::~TextTrackCue()
95
0
{
96
0
}
97
98
/** Save a reference to our creating document so we don't have to
99
 *  keep getting it from our window.
100
 */
101
nsresult
102
TextTrackCue::StashDocument()
103
0
{
104
0
  nsPIDOMWindowInner* window = GetOwner();
105
0
  if (!window) {
106
0
    return NS_ERROR_NO_INTERFACE;
107
0
  }
108
0
  mDocument = window->GetDoc();
109
0
  if (!mDocument) {
110
0
    return NS_ERROR_NOT_AVAILABLE;
111
0
  }
112
0
  return NS_OK;
113
0
}
114
115
already_AddRefed<DocumentFragment>
116
TextTrackCue::GetCueAsHTML()
117
0
{
118
0
  // mDocument may be null during cycle collector shutdown.
119
0
  // See bug 941701.
120
0
  if (!mDocument) {
121
0
    return nullptr;
122
0
  }
123
0
124
0
  if (!sParserWrapper) {
125
0
    nsresult rv;
126
0
    nsCOMPtr<nsIWebVTTParserWrapper> parserWrapper =
127
0
      do_CreateInstance(NS_WEBVTTPARSERWRAPPER_CONTRACTID, &rv);
128
0
    if (NS_FAILED(rv)) {
129
0
      return mDocument->CreateDocumentFragment();
130
0
    }
131
0
    sParserWrapper = parserWrapper;
132
0
    ClearOnShutdown(&sParserWrapper);
133
0
  }
134
0
135
0
  nsPIDOMWindowInner* window = mDocument->GetInnerWindow();
136
0
  if (!window) {
137
0
    return mDocument->CreateDocumentFragment();
138
0
  }
139
0
140
0
  RefPtr<DocumentFragment> frag;
141
0
  sParserWrapper->ConvertCueToDOMTree(window, this,
142
0
                                      getter_AddRefs(frag));
143
0
  if (!frag) {
144
0
    return mDocument->CreateDocumentFragment();
145
0
  }
146
0
  return frag.forget();
147
0
}
148
149
void
150
TextTrackCue::SetTrackElement(HTMLTrackElement* aTrackElement)
151
0
{
152
0
  mTrackElement = aTrackElement;
153
0
}
154
155
JSObject*
156
TextTrackCue::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
157
0
{
158
0
  return VTTCue_Binding::Wrap(aCx, this, aGivenProto);
159
0
}
160
161
TextTrackRegion*
162
TextTrackCue::GetRegion()
163
0
{
164
0
  return mRegion;
165
0
}
166
167
void
168
TextTrackCue::SetRegion(TextTrackRegion* aRegion)
169
0
{
170
0
  if (mRegion == aRegion) {
171
0
    return;
172
0
  }
173
0
  mRegion = aRegion;
174
0
  mReset = true;
175
0
}
176
177
double
178
TextTrackCue::ComputedLine()
179
0
{
180
0
  // See spec https://w3c.github.io/webvtt/#cue-computed-line
181
0
  if (!mLineIsAutoKeyword && !mSnapToLines &&
182
0
      (mLine < 0.0 || mLine > 100.0)) {
183
0
    return 100.0;
184
0
  } else if (!mLineIsAutoKeyword) {
185
0
    return mLine;
186
0
  } else if (mLineIsAutoKeyword && !mSnapToLines) {
187
0
    return 100.0;
188
0
  } else if (!mTrack ||
189
0
             !mTrack->GetTextTrackList() ||
190
0
             !mTrack->GetTextTrackList()->GetMediaElement()) {
191
0
    return -1.0;
192
0
  }
193
0
194
0
  RefPtr<TextTrackList> trackList = mTrack->GetTextTrackList();
195
0
  bool dummy;
196
0
  uint32_t showingTracksNum = 0;
197
0
  for (uint32_t idx = 0; idx < trackList->Length(); idx++) {
198
0
    RefPtr<TextTrack> track = trackList->IndexedGetter(idx, dummy);
199
0
    if (track->Mode() == TextTrackMode::Showing) {
200
0
      showingTracksNum++;
201
0
    }
202
0
203
0
    if (mTrack == track) {
204
0
      break;
205
0
    }
206
0
  }
207
0
208
0
  return (-1.0) * showingTracksNum;
209
0
}
210
211
double
212
TextTrackCue::ComputedPosition()
213
0
{
214
0
  // See spec https://w3c.github.io/webvtt/#cue-computed-position
215
0
  if (!mPositionIsAutoKeyword) {
216
0
    return mPosition;
217
0
  } else if (mAlign == AlignSetting::Left) {
218
0
    return 0.0;
219
0
  } else if (mAlign == AlignSetting::Right) {
220
0
    return 100.0;
221
0
  }
222
0
  return 50.0;
223
0
}
224
225
PositionAlignSetting
226
TextTrackCue::ComputedPositionAlign()
227
0
{
228
0
  // See spec https://w3c.github.io/webvtt/#cue-computed-position-alignment
229
0
  if (mPositionAlign != PositionAlignSetting::Auto) {
230
0
    return mPositionAlign;
231
0
  } else if (mAlign == AlignSetting::Left) {
232
0
    return PositionAlignSetting::Line_left;
233
0
  } else if (mAlign == AlignSetting::Right) {
234
0
    return PositionAlignSetting::Line_right;
235
0
  }
236
0
  return PositionAlignSetting::Center;
237
0
}
238
239
void
240
TextTrackCue::NotifyDisplayStatesChanged()
241
0
{
242
0
  if (!mReset) {
243
0
    return;
244
0
  }
245
0
246
0
  if (!mTrack ||
247
0
      !mTrack->GetTextTrackList() ||
248
0
      !mTrack->GetTextTrackList()->GetMediaElement()) {
249
0
    return;
250
0
  }
251
0
252
0
  mTrack->GetTextTrackList()->GetMediaElement()->NotifyCueDisplayStatesChanged();
253
0
}
254
255
} // namespace dom
256
} // namespace mozilla