1/*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2011-2017 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
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#if ENABLE(VIDEO_TRACK)
30
31#include "ContextDestructionObserver.h"
32#include "TextTrackCue.h"
33#include "TrackBase.h"
34
35namespace WebCore {
36
37class ScriptExecutionContext;
38class TextTrack;
39class TextTrackCueList;
40class VTTRegion;
41class VTTRegionList;
42
43class TextTrackClient {
44public:
45 virtual ~TextTrackClient() = default;
46 virtual void textTrackKindChanged(TextTrack&) = 0;
47 virtual void textTrackModeChanged(TextTrack&) = 0;
48 virtual void textTrackAddCues(TextTrack&, const TextTrackCueList&) = 0;
49 virtual void textTrackRemoveCues(TextTrack&, const TextTrackCueList&) = 0;
50 virtual void textTrackAddCue(TextTrack&, TextTrackCue&) = 0;
51 virtual void textTrackRemoveCue(TextTrack&, TextTrackCue&) = 0;
52};
53
54class TextTrack : public TrackBase, public EventTargetWithInlineData, public ContextDestructionObserver {
55 WTF_MAKE_ISO_ALLOCATED(TextTrack);
56public:
57 static Ref<TextTrack> create(ScriptExecutionContext* context, TextTrackClient* client, const AtomString& kind, const AtomString& id, const AtomString& label, const AtomString& language)
58 {
59 return adoptRef(*new TextTrack(context, client, kind, id, label, language, AddTrack));
60 }
61 virtual ~TextTrack();
62
63 EventTargetInterface eventTargetInterface() const final { return TextTrackEventTargetInterfaceType; }
64 ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
65
66 static TextTrack* captionMenuOffItem();
67 static TextTrack* captionMenuAutomaticItem();
68
69 static const AtomString& subtitlesKeyword();
70 static bool isValidKindKeyword(const AtomString&);
71
72 static const AtomString& disabledKeyword();
73 static const AtomString& hiddenKeyword();
74 static const AtomString& showingKeyword();
75
76 enum class Kind { Subtitles, Captions, Descriptions, Chapters, Metadata, Forced };
77 Kind kind() const;
78 void setKind(Kind);
79
80 Kind kindForBindings() const;
81 void setKindForBindings(Kind);
82
83 const AtomString& kindKeyword() const;
84 void setKindKeywordIgnoringASCIICase(StringView);
85
86 virtual AtomString inBandMetadataTrackDispatchType() const { return emptyString(); }
87
88 enum class Mode { Disabled, Hidden, Showing };
89 Mode mode() const;
90 virtual void setMode(Mode);
91
92 enum ReadinessState { NotLoaded = 0, Loading = 1, Loaded = 2, FailedToLoad = 3 };
93 ReadinessState readinessState() const { return m_readinessState; }
94 void setReadinessState(ReadinessState state) { m_readinessState = state; }
95
96 TextTrackCueList* cues();
97 TextTrackCueList* activeCues() const;
98
99 void clearClient() override { m_client = nullptr; }
100 TextTrackClient* client() { return m_client; }
101
102 ExceptionOr<void> addCue(Ref<TextTrackCue>&&);
103 virtual ExceptionOr<void> removeCue(TextTrackCue&);
104
105 bool hasCue(TextTrackCue*, TextTrackCue::CueMatchRules = TextTrackCue::MatchAllFields);
106
107 VTTRegionList* regions();
108 void addRegion(RefPtr<VTTRegion>&&);
109 ExceptionOr<void> removeRegion(VTTRegion*);
110
111 void cueWillChange(TextTrackCue*);
112 void cueDidChange(TextTrackCue*);
113
114 enum TextTrackType { TrackElement, AddTrack, InBand };
115 TextTrackType trackType() const { return m_trackType; }
116
117 virtual bool isClosedCaptions() const { return false; }
118 virtual bool isSDH() const { return false; }
119 virtual bool containsOnlyForcedSubtitles() const;
120 virtual bool isMainProgramContent() const;
121 virtual bool isEasyToRead() const { return false; }
122
123 int trackIndex();
124 void invalidateTrackIndex();
125
126 bool isRendered();
127 int trackIndexRelativeToRenderedTracks();
128
129 bool hasBeenConfigured() const { return m_hasBeenConfigured; }
130 void setHasBeenConfigured(bool flag) { m_hasBeenConfigured = flag; }
131
132 virtual bool isDefault() const { return false; }
133 virtual void setIsDefault(bool) { }
134
135 void removeAllCues();
136
137#if ENABLE(MEDIA_SOURCE)
138 void setLanguage(const AtomString&) override;
139#endif
140
141 virtual bool isInband() const { return false; }
142
143 virtual MediaTime startTimeVariance() const { return MediaTime::zeroTime(); }
144
145 using RefCounted<TrackBase>::ref;
146 using RefCounted<TrackBase>::deref;
147
148 const Optional<Vector<String>>& styleSheets() const { return m_styleSheets; }
149
150protected:
151 TextTrack(ScriptExecutionContext*, TextTrackClient*, const AtomString& kind, const AtomString& id, const AtomString& label, const AtomString& language, TextTrackType);
152
153#if !RELEASE_LOG_DISABLED
154 const char* logClassName() const override { return "TextTrack"; }
155#endif
156
157 RefPtr<TextTrackCueList> m_cues;
158 Optional<Vector<String>> m_styleSheets;
159
160private:
161 bool enabled() const override;
162
163 void refEventTarget() final { ref(); }
164 void derefEventTarget() final { deref(); }
165
166 VTTRegionList& ensureVTTRegionList();
167 RefPtr<VTTRegionList> m_regions;
168
169 TextTrackCueList& ensureTextTrackCueList();
170
171 Mode m_mode { Mode::Disabled };
172 Kind m_kind { Kind::Subtitles };
173 TextTrackClient* m_client;
174 TextTrackType m_trackType;
175 ReadinessState m_readinessState { NotLoaded };
176 Optional<int> m_trackIndex;
177 Optional<int> m_renderedTrackIndex;
178 bool m_hasBeenConfigured { false };
179};
180
181inline auto TextTrack::mode() const -> Mode
182{
183 return m_mode;
184}
185
186inline auto TextTrack::kind() const -> Kind
187{
188 return m_kind;
189}
190
191inline auto TextTrack::kindForBindings() const -> Kind
192{
193 return kind();
194}
195
196#if !ENABLE(MEDIA_SOURCE)
197
198inline void TextTrack::setKindForBindings(Kind)
199{
200 // FIXME: We are using kindForBindings only to implement this empty function, preserving the
201 // behavior of doing nothing when trying to set the kind, originally implemented in a custom setter.
202 // Once we no longer need this special case, we should remove kindForBindings and setKindForBindings.
203}
204
205#else
206
207inline void TextTrack::setKindForBindings(Kind kind)
208{
209 setKind(kind);
210}
211
212#endif
213
214
215} // namespace WebCore
216
217SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::TextTrack)
218 static bool isType(const WebCore::TrackBase& track) { return track.type() == WebCore::TrackBase::TextTrack; }
219SPECIALIZE_TYPE_TRAITS_END()
220
221#endif
222