[Mac] process raw VTT in-band captions
[WebKit-https.git] / Source / WebCore / html / track / WebVTTParser.h
1 /*
2  * Copyright (C) 2011, 2013 Google Inc.  All rights reserved.
3  * Copyright (C) 2013 Cable Television Labs, Inc.
4  * Copyright (C) 2014 Apple Inc.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  *     * Neither the name of Google Inc. nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifndef WebVTTParser_h
34 #define WebVTTParser_h
35
36 #if ENABLE(VIDEO_TRACK)
37
38 #include "BufferedLineReader.h"
39 #include "DocumentFragment.h"
40 #include "HTMLNames.h"
41 #include "TextResourceDecoder.h"
42 #include "VTTRegion.h"
43 #include "WebVTTTokenizer.h"
44 #include <memory>
45 #include <wtf/text/StringBuilder.h>
46
47 namespace WebCore {
48
49 using namespace HTMLNames;
50
51 class Document;
52 class ISOWebVTTCue;
53 class VTTScanner;
54
55 class WebVTTParserClient {
56 public:
57     virtual ~WebVTTParserClient() { }
58
59     virtual void newCuesParsed() = 0;
60 #if ENABLE(WEBVTT_REGIONS)
61     virtual void newRegionsParsed() = 0;
62 #endif
63     virtual void fileFailedToParse() = 0;
64 };
65
66 class WebVTTCueData : public RefCounted<WebVTTCueData> {
67 public:
68
69     static PassRefPtr<WebVTTCueData> create() { return adoptRef(new WebVTTCueData()); }
70     virtual ~WebVTTCueData() { }
71
72     double startTime() const { return m_startTime; }
73     void setStartTime(double startTime) { m_startTime = startTime; }
74
75     double endTime() const { return m_endTime; }
76     void setEndTime(double endTime) { m_endTime = endTime; }
77
78     String id() const { return m_id; }
79     void setId(String id) { m_id = id; }
80
81     String content() const { return m_content; }
82     void setContent(String content) { m_content = content; }
83
84     String settings() const { return m_settings; }
85     void setSettings(String settings) { m_settings = settings; }
86
87     double originalStartTime() const { return m_originalStartTime; }
88     void setOriginalStartTime(double time) { m_originalStartTime = time; }
89
90 private:
91     WebVTTCueData()
92         : m_startTime(0)
93         , m_endTime(0)
94         , m_originalStartTime(0)
95     {
96     }
97
98     double m_startTime;
99     double m_endTime;
100     double m_originalStartTime;
101     String m_id;
102     String m_content;
103     String m_settings;
104 };
105
106 class WebVTTParser final {
107 public:
108     enum ParseState {
109         Initial,
110         Header,
111         Id,
112         TimingsAndSettings,
113         CueText,
114         BadCue,
115         Finished
116     };
117
118     WebVTTParser(WebVTTParserClient*, ScriptExecutionContext*);
119
120     static inline bool isRecognizedTag(const AtomicString& tagName)
121     {
122         return tagName == iTag
123             || tagName == bTag
124             || tagName == uTag
125             || tagName == rubyTag
126             || tagName == rtTag;
127     }
128
129     static inline bool isASpace(UChar c)
130     {
131         // WebVTT space characters are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN    (CR).
132         return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r';
133     }
134     static inline bool isValidSettingDelimiter(UChar c)
135     {
136         // ... a WebVTT cue consists of zero or more of the following components, in any order, separated from each other by one or more 
137         // U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
138         return c == ' ' || c == '\t';
139     }
140     static bool collectTimeStamp(const String&, double&);
141
142 #if ENABLE(WEBVTT_REGIONS)
143     // Useful functions for parsing percentage settings.
144     static bool parseFloatPercentageValue(VTTScanner& valueScanner, float&);
145     static bool parseFloatPercentageValuePair(VTTScanner& valueScanner, char, FloatPoint&);
146 #endif
147
148     // Input data to the parser to parse.
149     void parseBytes(const char*, unsigned);
150     void parseFileHeader(const String&);
151     void parseCueData(const ISOWebVTTCue&);
152     void flush();
153     void fileFinished();
154
155     // Transfers ownership of last parsed cues to caller.
156     void getNewCues(Vector<RefPtr<WebVTTCueData>>&);
157 #if ENABLE(WEBVTT_REGIONS)
158     void getNewRegions(Vector<RefPtr<VTTRegion>>&);
159 #endif
160
161     // Create the DocumentFragment representation of the WebVTT cue text.
162     static PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(Document&, const String&);
163
164 protected:
165     ScriptExecutionContext* m_scriptExecutionContext;
166     ParseState m_state;
167
168 private:
169     void parse();
170     void flushPendingCue();
171     bool hasRequiredFileIdentifier(const String&);
172     ParseState collectCueId(const String&);
173     ParseState collectTimingsAndSettings(const String&);
174     ParseState collectCueText(const String&);
175     ParseState recoverCue(const String&);
176     ParseState ignoreBadCue(const String&);
177
178     void createNewCue();
179     void resetCueValues();
180
181     void collectMetadataHeader(const String&);
182 #if ENABLE(WEBVTT_REGIONS)
183     void createNewRegion(const String& headerValue);
184 #endif
185
186     static bool collectTimeStamp(VTTScanner& input, double& timeStamp);
187
188     BufferedLineReader m_lineReader;
189     RefPtr<TextResourceDecoder> m_decoder;
190     String m_currentId;
191     double m_currentStartTime;
192     double m_currentEndTime;
193     StringBuilder m_currentContent;
194     String m_currentSettings;
195
196     WebVTTParserClient* m_client;
197
198     Vector<RefPtr<WebVTTCueData>> m_cuelist;
199
200 #if ENABLE(WEBVTT_REGIONS)
201     Vector<RefPtr<VTTRegion>> m_regionList;
202 #endif
203 };
204
205 } // namespace WebCore
206
207 #endif
208 #endif