Move HTML canvas and tracks from ExceptionCode to Exception
[WebKit-https.git] / Source / WebCore / html / track / TextTrackCue.cpp
1 /*
2  * Copyright (C) 2011, 2013 Google Inc.  All rights reserved.
3  * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "config.h"
33
34 #if ENABLE(VIDEO_TRACK)
35
36 #include "TextTrackCue.h"
37
38 #include "CSSPropertyNames.h"
39 #include "CSSValueKeywords.h"
40 #include "DocumentFragment.h"
41 #include "Event.h"
42 #include "HTMLDivElement.h"
43 #include "HTMLSpanElement.h"
44 #include "Logging.h"
45 #include "NodeTraversal.h"
46 #include "Text.h"
47 #include "TextTrack.h"
48 #include "TextTrackCueList.h"
49 #include "VTTCue.h"
50 #include "VTTRegionList.h"
51 #include <wtf/MathExtras.h>
52
53 namespace WebCore {
54
55 static const int invalidCueIndex = -1;
56
57 const AtomicString& TextTrackCue::cueShadowPseudoId()
58 {
59     static NeverDestroyed<const AtomicString> cue("cue", AtomicString::ConstructFromLiteral);
60     return cue;
61 }
62
63 TextTrackCue::TextTrackCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end)
64     : m_startTime(start)
65     , m_endTime(end)
66     , m_cueIndex(invalidCueIndex)
67     , m_processingCueChanges(0)
68     , m_track(0)
69     , m_scriptExecutionContext(context)
70     , m_isActive(false)
71     , m_pauseOnExit(false)
72 {
73     ASSERT(m_scriptExecutionContext.isDocument());
74 }
75
76 void TextTrackCue::willChange()
77 {
78     if (++m_processingCueChanges > 1)
79         return;
80
81     if (m_track)
82         m_track->cueWillChange(this);
83 }
84
85 void TextTrackCue::didChange()
86 {
87     ASSERT(m_processingCueChanges);
88     if (--m_processingCueChanges)
89         return;
90
91     if (m_track)
92         m_track->cueDidChange(this);
93 }
94
95 TextTrack* TextTrackCue::track() const
96 {
97     return m_track;
98 }
99
100 void TextTrackCue::setTrack(TextTrack* track)
101 {
102     m_track = track;
103 }
104
105 void TextTrackCue::setId(const String& id)
106 {
107     if (m_id == id)
108         return;
109
110     willChange();
111     m_id = id;
112     didChange();
113 }
114
115 void TextTrackCue::setStartTime(double value)
116 {
117     // TODO(93143): Add spec-compliant behavior for negative time values.
118     if (m_startTime.toDouble() == value || value < 0)
119         return;
120
121     setStartTime(MediaTime::createWithDouble(value));
122 }
123
124 void TextTrackCue::setStartTime(const MediaTime& value)
125 {
126     willChange();
127     m_startTime = value;
128     didChange();
129 }
130     
131 void TextTrackCue::setEndTime(double value)
132 {
133     // TODO(93143): Add spec-compliant behavior for negative time values.
134     if (m_endTime.toDouble() == value || value < 0)
135         return;
136
137     setEndTime(MediaTime::createWithDouble(value));
138 }
139
140 void TextTrackCue::setEndTime(const MediaTime& value)
141 {
142     willChange();
143     m_endTime = value;
144     didChange();
145 }
146     
147 void TextTrackCue::setPauseOnExit(bool value)
148 {
149     if (m_pauseOnExit == value)
150         return;
151     
152     m_pauseOnExit = value;
153 }
154
155 int TextTrackCue::cueIndex()
156 {
157     if (m_cueIndex == invalidCueIndex) {
158         ASSERT(track());
159         ASSERT(track()->cues());
160         if (TextTrackCueList* cueList = track()->cues())
161             m_cueIndex = cueList->getCueIndex(this);
162     }
163
164     return m_cueIndex;
165 }
166
167 void TextTrackCue::invalidateCueIndex()
168 {
169     m_cueIndex = invalidCueIndex;
170 }
171
172 bool TextTrackCue::dispatchEvent(Event& event)
173 {
174     // When a TextTrack's mode is disabled: no cues are active, no events fired.
175     if (!track() || track()->mode() == TextTrack::Mode::Disabled)
176         return false;
177
178     return EventTarget::dispatchEvent(event);
179 }
180
181 bool TextTrackCue::isActive()
182 {
183     return m_isActive && track() && track()->mode() != TextTrack::Mode::Disabled;
184 }
185
186 void TextTrackCue::setIsActive(bool active)
187 {
188     m_isActive = active;
189 }
190
191 bool TextTrackCue::isOrderedBefore(const TextTrackCue* other) const
192 {
193     return startMediaTime() < other->startMediaTime() || (startMediaTime() == other->startMediaTime() && endMediaTime() > other->endMediaTime());
194 }
195
196 bool TextTrackCue::cueContentsMatch(const TextTrackCue& cue) const
197 {
198     if (cueType() != cue.cueType())
199         return false;
200
201     if (id() != cue.id())
202         return false;
203
204     return true;
205 }
206
207 bool TextTrackCue::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
208 {
209     if (cueType() != cue.cueType())
210         return false;
211
212     if (match != IgnoreDuration && endMediaTime() != cue.endMediaTime())
213         return false;
214     if (!hasEquivalentStartTime(cue))
215         return false;
216     if (!cueContentsMatch(cue))
217         return false;
218
219     return true;
220 }
221
222 bool TextTrackCue::hasEquivalentStartTime(const TextTrackCue& cue) const
223 {
224     MediaTime startTimeVariance = MediaTime::zeroTime();
225     if (track())
226         startTimeVariance = track()->startTimeVariance();
227     else if (cue.track())
228         startTimeVariance = cue.track()->startTimeVariance();
229
230     return abs(abs(startMediaTime()) - abs(cue.startMediaTime())) <= startTimeVariance;
231 }
232
233 bool TextTrackCue::doesExtendCue(const TextTrackCue& cue) const
234 {
235     if (!cueContentsMatch(cue))
236         return false;
237
238     if (endMediaTime() != cue.startMediaTime())
239         return false;
240     
241     return true;
242 }
243
244 } // namespace WebCore
245
246 #endif