initial import
[vuplus_webkit] / Source / WebCore / html / TextTrackCue.cpp
1 /*
2  * Copyright (C) 2011 Google Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #if ENABLE(VIDEO_TRACK)
34
35 #include "TextTrackCue.h"
36
37 #include "DocumentFragment.h"
38 #include "TextTrack.h"
39 #include "WebVTTParser.h"
40 #include <wtf/text/StringBuilder.h>
41
42 namespace WebCore {
43
44 TextTrackCue::TextTrackCue(ScriptExecutionContext* context, const String& id, double start, double end, const String& content, const String& settings, bool pauseOnExit)
45     : ActiveDOMObject(context, this)
46     , m_id(id)
47     , m_startTime(start)
48     , m_endTime(end)
49     , m_content(content)
50     , m_pauseOnExit(pauseOnExit)
51     , m_writingDirection(Horizontal)
52     , m_snapToLines(true)
53     , m_linePosition(-1)
54     , m_textPosition(50)
55     , m_cueSize(100)
56     , m_cueAlignment(Middle)
57     , m_isActive(false)
58 {
59     parseSettings(settings);
60 }
61
62 TextTrackCue::~TextTrackCue()
63 {
64 }
65
66 TextTrack* TextTrackCue::track() const
67 {
68     return m_track;
69 }
70
71 void TextTrackCue::setTrack(TextTrack* track)
72 {
73     m_track = track;
74 }
75
76 String TextTrackCue::id() const
77 {
78     return m_id;
79 }
80
81 double TextTrackCue::startTime() const
82 {
83     return m_startTime;
84 }
85
86 double TextTrackCue::endTime() const
87 {
88     return m_endTime;
89 }
90
91 bool TextTrackCue::pauseOnExit() const
92 {
93     return m_pauseOnExit;
94 }
95
96 String TextTrackCue::direction() const
97 {
98     switch (m_writingDirection) {
99     case Horizontal: 
100         return "horizontal";
101     case VerticalGrowingLeft:
102         return "vertical";
103     case VerticalGrowingRight:
104         return "vertical-lr";
105     default:
106         return "";
107     }
108 }
109
110 String TextTrackCue::alignment() const
111 {
112     switch (m_cueAlignment) {
113     case Start: 
114         return "start";
115     case Middle:
116         return "middle";
117     case End:
118         return "end";
119     default:
120         return "";
121     }
122 }
123
124 String TextTrackCue::getCueAsSource()
125 {
126     return m_content;
127 }
128
129 PassRefPtr<DocumentFragment> TextTrackCue::getCueAsHTML()
130 {
131     return m_documentFragment;
132 }
133
134 void TextTrackCue::setCueHTML(PassRefPtr<DocumentFragment> fragment)
135 {
136     m_documentFragment = fragment;
137 }
138
139 bool TextTrackCue::isActive()
140 {
141     // FIXME(62885): Implement.
142     return false;
143 }
144
145 void TextTrackCue::setIsActive(bool active)
146 {
147     m_isActive = active;
148 }
149
150 ScriptExecutionContext* TextTrackCue::scriptExecutionContext() const
151 {
152     return ActiveDOMObject::scriptExecutionContext();
153 }
154
155 void TextTrackCue::parseSettings(const String& input)
156 {
157     // 4.8.10.13.3 Parse the WebVTT settings.
158     // 1 - Initial setup.
159     unsigned position = 0;
160     while (position < input.length()) {
161         // Discard any space characters between or after settings (not in the spec, but we think it should be).
162         while (position < input.length() && WebVTTParser::isASpace(input[position]))
163             position++;
164
165         // 2-4 Settings - get the next character representing a settings.
166         char setting = input[position++];
167         if (position >= input.length())
168             return;
169
170         // 5-7 - If the character at position is not ':', set setting to empty string.
171         if (input[position++] != ':')
172             setting = '\0';
173         if (position >= input.length())
174             return;
175
176         // 8 - Gather settings based on value of setting.
177         switch (setting) {
178         case 'D':
179             {
180             // 1-3 - Collect the next word and set the writing direction accordingly.
181             String writingDirection = WebVTTParser::collectWord(input, &position);
182             if (writingDirection == "vertical")
183                 m_writingDirection = VerticalGrowingLeft;
184             else if (writingDirection == "vertical-lr")
185                 m_writingDirection = VerticalGrowingRight;
186             }
187             break;
188         case 'L':
189             {
190             // 1-2 - Collect chars that are either '-', '%', or a digit.
191             StringBuilder linePositionBuilder;
192             while (position < input.length() && (input[position] == '-' || input[position] == '%' || isASCIIDigit(input[position])))
193                 linePositionBuilder.append(input[position++]);
194             if (position < input.length() && !WebVTTParser::isASpace(input[position]))
195                 goto Otherwise;
196             String linePosition = linePositionBuilder.toString();
197
198             // 3-5 - If there is not at least one digit character,
199             //       a '-' occurs anywhere other than the front, or
200             //       a '%' occurs anywhere other than the end, then
201             //       ignore this setting and keep looking.
202             if (linePosition.find('-', 1) != notFound || linePosition.reverseFind("%", linePosition.length() - 2) != notFound)
203                 break;
204
205             // 6 - If the first char is a '-' and the last char is a '%', ignore and keep looking.
206             if (linePosition[0] == '-' && linePosition[linePosition.length() - 1] == '%')
207                 break;
208
209             // 7 - Interpret as number (toInt ignores trailing non-digit characters,
210             //     such as a possible '%').
211             bool validNumber;
212             int number = linePosition.toInt(&validNumber);
213             if (!validNumber)
214                 break;
215
216             // 8 - If the last char is a '%' and the value is not between 0 and 100, ignore and keep looking.
217             if (linePosition[linePosition.length() - 1] == '%') {
218                 if (number < 0 || number > 100)
219                     break;
220
221                 // 10 - If '%' then set snap-to-lines flag to false.
222                 m_snapToLines = false;
223             }
224
225             // 9 - Set cue line position to the number found.
226             m_linePosition = number;
227             }
228             break;
229         case 'T':
230             {
231             // 1-2 - Collect characters that are digits.
232             String textPosition = WebVTTParser::collectDigits(input, &position);
233             if (position >= input.length())
234                 break;
235
236             // 3 - Character at end must be '%', otherwise ignore and keep looking.
237             if (input[position++] != '%')
238                 goto Otherwise;
239
240             // 4-6 - Ensure no other chars in this setting and setting is not empty.
241             if (position < input.length() && !WebVTTParser::isASpace(input[position]))
242                 goto Otherwise;
243             if (textPosition.isEmpty())
244                 break;
245
246             // 7-8 - Interpret as number and make sure it is between 0 and 100
247             // (toInt ignores trailing non-digit characters, such as a possible '%').
248             bool validNumber;
249             int number = textPosition.toInt(&validNumber);
250             if (!validNumber)
251                 break;
252             if (number < 0 || number > 100)
253               break;
254
255             // 9 - Set cue text position to the number found.
256             m_textPosition = number;
257             }
258             break;
259         case 'S':
260             {
261             // 1-2 - Collect characters that are digits.
262             String cueSize = WebVTTParser::collectDigits(input, &position);
263             if (position >= input.length())
264                 break;
265
266             // 3 - Character at end must be '%', otherwise ignore and keep looking.
267             if (input[position++] != '%')
268                 goto Otherwise;
269
270             // 4-6 - Ensure no other chars in this setting and setting is not empty.
271             if (position < input.length() && !WebVTTParser::isASpace(input[position]))
272                 goto Otherwise;
273             if (cueSize.isEmpty())
274                 break;
275
276             // 7-8 - Interpret as number and make sure it is between 0 and 100.
277             bool validNumber;
278             int number = cueSize.toInt(&validNumber);
279             if (!validNumber)
280                 break;
281             if (number < 0 || number > 100)
282                 break;
283
284             // 9 - Set cue size to the number found.
285             m_cueSize = number;
286             }
287             break;
288         case 'A':
289             {
290             // 1-4 - Collect the next word and set the cue alignment accordingly.
291             String cueAlignment = WebVTTParser::collectWord(input, &position);
292             if (cueAlignment == "start")
293                 m_cueAlignment = Start;
294             else if (cueAlignment == "middle")
295                 m_cueAlignment = Middle;
296             else if (cueAlignment == "end")
297                 m_cueAlignment = End;
298             }
299             break;
300         }
301
302         continue;
303
304 Otherwise:
305         // Collect a sequence of characters that are not space characters and discard them.
306         WebVTTParser::collectWord(input, &position);
307     }
308 }
309
310 } // namespace WebCore
311
312 #endif