| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 } | 55 } |
| 56 | 56 |
| 57 String WebVTTParser::collectWord(const String& input, unsigned* position) | 57 String WebVTTParser::collectWord(const String& input, unsigned* position) |
| 58 { | 58 { |
| 59 StringBuilder string; | 59 StringBuilder string; |
| 60 while (*position < input.length() && !isASpace(input[*position])) | 60 while (*position < input.length() && !isASpace(input[*position])) |
| 61 string.append(input[(*position)++]); | 61 string.append(input[(*position)++]); |
| 62 return string.toString(); | 62 return string.toString(); |
| 63 } | 63 } |
| 64 | 64 |
| 65 #if ENABLE(WEBVTT_REGIONS) | |
| 66 float WebVTTParser::parseFloatPercentageValue(const String& value, bool& isValid
Setting) | 65 float WebVTTParser::parseFloatPercentageValue(const String& value, bool& isValid
Setting) |
| 67 { | 66 { |
| 68 // '%' must be present and at the end of the setting value. | 67 // '%' must be present and at the end of the setting value. |
| 69 if (value.find('%', 1) != value.length() - 1) { | 68 if (value.find('%', 1) != value.length() - 1) { |
| 70 isValidSetting = false; | 69 isValidSetting = false; |
| 71 return 0; | 70 return 0; |
| 72 } | 71 } |
| 73 | 72 |
| 74 unsigned position = 0; | 73 unsigned position = 0; |
| 75 | 74 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 103 | 102 |
| 104 bool isFirstValueValid; | 103 bool isFirstValueValid; |
| 105 float firstCoord = parseFloatPercentageValue(value.substring(0, delimiterOff
set), isFirstValueValid); | 104 float firstCoord = parseFloatPercentageValue(value.substring(0, delimiterOff
set), isFirstValueValid); |
| 106 | 105 |
| 107 bool isSecondValueValid; | 106 bool isSecondValueValid; |
| 108 float secondCoord = parseFloatPercentageValue(value.substring(delimiterOffse
t + 1, value.length() - 1), isSecondValueValid); | 107 float secondCoord = parseFloatPercentageValue(value.substring(delimiterOffse
t + 1, value.length() - 1), isSecondValueValid); |
| 109 | 108 |
| 110 isValidSetting = isFirstValueValid && isSecondValueValid; | 109 isValidSetting = isFirstValueValid && isSecondValueValid; |
| 111 return FloatPoint(firstCoord, secondCoord); | 110 return FloatPoint(firstCoord, secondCoord); |
| 112 } | 111 } |
| 113 #endif | |
| 114 | 112 |
| 115 WebVTTParser::WebVTTParser(WebVTTParserClient* client, ExecutionContext* context
) | 113 WebVTTParser::WebVTTParser(WebVTTParserClient* client, ExecutionContext* context
) |
| 116 : m_executionContext(context) | 114 : m_executionContext(context) |
| 117 , m_state(Initial) | 115 , m_state(Initial) |
| 118 , m_currentStartTime(0) | 116 , m_currentStartTime(0) |
| 119 , m_currentEndTime(0) | 117 , m_currentEndTime(0) |
| 120 , m_tokenizer(WebVTTTokenizer::create()) | 118 , m_tokenizer(WebVTTTokenizer::create()) |
| 121 , m_client(client) | 119 , m_client(client) |
| 122 { | 120 { |
| 123 } | 121 } |
| 124 | 122 |
| 125 void WebVTTParser::getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues) | 123 void WebVTTParser::getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues) |
| 126 { | 124 { |
| 127 outputCues = m_cuelist; | 125 outputCues = m_cuelist; |
| 128 m_cuelist.clear(); | 126 m_cuelist.clear(); |
| 129 } | 127 } |
| 130 | 128 |
| 131 #if ENABLE(WEBVTT_REGIONS) | |
| 132 void WebVTTParser::getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions
) | 129 void WebVTTParser::getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions
) |
| 133 { | 130 { |
| 134 outputRegions = m_regionList; | 131 outputRegions = m_regionList; |
| 135 m_regionList.clear(); | 132 m_regionList.clear(); |
| 136 } | 133 } |
| 137 #endif | |
| 138 | 134 |
| 139 void WebVTTParser::parseBytes(const char* data, unsigned length) | 135 void WebVTTParser::parseBytes(const char* data, unsigned length) |
| 140 { | 136 { |
| 141 // 4.8.10.13.3 WHATWG WebVTT Parser algorithm. | 137 // 4.8.10.13.3 WHATWG WebVTT Parser algorithm. |
| 142 // 1-3 - Initial setup. | 138 // 1-3 - Initial setup. |
| 143 unsigned position = 0; | 139 unsigned position = 0; |
| 144 | 140 |
| 145 while (position < length) { | 141 while (position < length) { |
| 146 String line = collectNextLine(data, length, &position); | 142 String line = collectNextLine(data, length, &position); |
| 147 | 143 |
| 148 switch (m_state) { | 144 switch (m_state) { |
| 149 case Initial: | 145 case Initial: |
| 150 // Buffer up at least 9 bytes before proceeding with checking for th
e file identifier. | 146 // Buffer up at least 9 bytes before proceeding with checking for th
e file identifier. |
| 151 m_identifierData.append(data, length); | 147 m_identifierData.append(data, length); |
| 152 if (m_identifierData.size() < bomLength + fileIdentifierLength) | 148 if (m_identifierData.size() < bomLength + fileIdentifierLength) |
| 153 return; | 149 return; |
| 154 | 150 |
| 155 // 4-12 - Collect the first line and check for "WEBVTT". | 151 // 4-12 - Collect the first line and check for "WEBVTT". |
| 156 if (!hasRequiredFileIdentifier()) { | 152 if (!hasRequiredFileIdentifier()) { |
| 157 if (m_client) | 153 if (m_client) |
| 158 m_client->fileFailedToParse(); | 154 m_client->fileFailedToParse(); |
| 159 return; | 155 return; |
| 160 } | 156 } |
| 161 | 157 |
| 162 m_state = Header; | 158 m_state = Header; |
| 163 m_identifierData.clear(); | 159 m_identifierData.clear(); |
| 164 break; | 160 break; |
| 165 | 161 |
| 166 case Header: | 162 case Header: |
| 163 collectMetadataHeader(line); |
| 164 |
| 167 // 13-18 - Allow a header (comment area) under the WEBVTT line. | 165 // 13-18 - Allow a header (comment area) under the WEBVTT line. |
| 168 #if ENABLE(WEBVTT_REGIONS) | |
| 169 if (line.isEmpty()) { | 166 if (line.isEmpty()) { |
| 170 if (m_client && m_regionList.size()) | 167 if (m_client && m_regionList.size()) |
| 171 m_client->newRegionsParsed(); | 168 m_client->newRegionsParsed(); |
| 172 | 169 |
| 173 m_state = Id; | 170 m_state = Id; |
| 174 break; | 171 break; |
| 175 } | 172 } |
| 176 collectHeader(line); | |
| 177 | 173 |
| 178 break; | 174 break; |
| 179 | 175 |
| 180 case Metadata: | |
| 181 #endif | |
| 182 if (line.isEmpty()) | |
| 183 m_state = Id; | |
| 184 break; | |
| 185 | |
| 186 case Id: | 176 case Id: |
| 187 // 19-29 - Allow any number of line terminators, then initialize new
cue values. | 177 // 19-29 - Allow any number of line terminators, then initialize new
cue values. |
| 188 if (line.isEmpty()) | 178 if (line.isEmpty()) |
| 189 break; | 179 break; |
| 190 resetCueValues(); | 180 resetCueValues(); |
| 191 | 181 |
| 192 // 30-39 - Check if this line contains an optional identifier or tim
ing data. | 182 // 30-39 - Check if this line contains an optional identifier or tim
ing data. |
| 193 m_state = collectCueId(line); | 183 m_state = collectCueId(line); |
| 194 break; | 184 break; |
| 195 | 185 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 224 if (line.length() < fileIdentifierLength) | 214 if (line.length() < fileIdentifierLength) |
| 225 return false; | 215 return false; |
| 226 if (line.substring(0, fileIdentifierLength) != "WEBVTT") | 216 if (line.substring(0, fileIdentifierLength) != "WEBVTT") |
| 227 return false; | 217 return false; |
| 228 if (line.length() > fileIdentifierLength && line[fileIdentifierLength] != '
' && line[fileIdentifierLength] != '\t') | 218 if (line.length() > fileIdentifierLength && line[fileIdentifierLength] != '
' && line[fileIdentifierLength] != '\t') |
| 229 return false; | 219 return false; |
| 230 | 220 |
| 231 return true; | 221 return true; |
| 232 } | 222 } |
| 233 | 223 |
| 234 #if ENABLE(WEBVTT_REGIONS) | 224 void WebVTTParser::collectMetadataHeader(const String& line) |
| 235 void WebVTTParser::collectHeader(const String& line) | |
| 236 { | 225 { |
| 237 // 4.1 Extension of WebVTT header parsing (11 - 15) | 226 // 4.1 Extension of WebVTT header parsing (11 - 15) |
| 238 DEFINE_STATIC_LOCAL(const AtomicString, regionHeaderName, ("Region", AtomicS
tring::ConstructFromLiteral)); | 227 DEFINE_STATIC_LOCAL(const AtomicString, regionHeaderName, ("Region", AtomicS
tring::ConstructFromLiteral)); |
| 239 | 228 |
| 240 // 15.4 If line contains the character ":" (A U+003A COLON), then set metada
ta's | 229 // 15.4 If line contains the character ":" (A U+003A COLON), then set metada
ta's |
| 241 // name to the substring of line before the first ":" character and | 230 // name to the substring of line before the first ":" character and |
| 242 // metadata's value to the substring after this character. | 231 // metadata's value to the substring after this character. |
| 243 if (!line.contains(":")) | 232 if (!RuntimeEnabledFeatures::webVTTRegionsEnabled() || !line.contains(":")) |
| 244 return; | 233 return; |
| 245 | 234 |
| 246 unsigned colonPosition = line.find(":"); | 235 unsigned colonPosition = line.find(":"); |
| 247 m_currentHeaderName = line.substring(0, colonPosition); | 236 m_currentHeaderName = line.substring(0, colonPosition); |
| 248 | 237 |
| 249 // 15.5 If metadata's name equals "Region": | 238 // 15.5 If metadata's name equals "Region": |
| 250 if (m_currentHeaderName == regionHeaderName) { | 239 if (m_currentHeaderName == regionHeaderName) { |
| 251 m_currentHeaderValue = line.substring(colonPosition + 1, line.length() -
1); | 240 m_currentHeaderValue = line.substring(colonPosition + 1, line.length() -
1); |
| 252 // 15.5.1 - 15.5.8 Region creation: Let region be a new text track regio
n [...] | 241 // 15.5.1 - 15.5.8 Region creation: Let region be a new text track regio
n [...] |
| 253 createNewRegion(); | 242 createNewRegion(); |
| 254 } | 243 } |
| 255 } | 244 } |
| 256 #endif | |
| 257 | 245 |
| 258 WebVTTParser::ParseState WebVTTParser::collectCueId(const String& line) | 246 WebVTTParser::ParseState WebVTTParser::collectCueId(const String& line) |
| 259 { | 247 { |
| 260 if (line.contains("-->")) | 248 if (line.contains("-->")) |
| 261 return collectTimingsAndSettings(line); | 249 return collectTimingsAndSettings(line); |
| 262 m_currentId = line; | 250 m_currentId = line; |
| 263 return TimingsAndSettings; | 251 return TimingsAndSettings; |
| 264 } | 252 } |
| 265 | 253 |
| 266 WebVTTParser::ParseState WebVTTParser::collectTimingsAndSettings(const String& l
ine) | 254 WebVTTParser::ParseState WebVTTParser::collectTimingsAndSettings(const String& l
ine) |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 | 355 |
| 368 void WebVTTParser::resetCueValues() | 356 void WebVTTParser::resetCueValues() |
| 369 { | 357 { |
| 370 m_currentId = emptyString(); | 358 m_currentId = emptyString(); |
| 371 m_currentSettings = emptyString(); | 359 m_currentSettings = emptyString(); |
| 372 m_currentStartTime = 0; | 360 m_currentStartTime = 0; |
| 373 m_currentEndTime = 0; | 361 m_currentEndTime = 0; |
| 374 m_currentContent.clear(); | 362 m_currentContent.clear(); |
| 375 } | 363 } |
| 376 | 364 |
| 377 #if ENABLE(WEBVTT_REGIONS) | |
| 378 void WebVTTParser::createNewRegion() | 365 void WebVTTParser::createNewRegion() |
| 379 { | 366 { |
| 380 if (!m_currentHeaderValue.length()) | 367 if (!m_currentHeaderValue.length()) |
| 381 return; | 368 return; |
| 382 | 369 |
| 383 RefPtr<TextTrackRegion> region = TextTrackRegion::create(m_executionContext)
; | 370 RefPtr<TextTrackRegion> region = TextTrackRegion::create(m_executionContext)
; |
| 384 region->setRegionSettings(m_currentHeaderValue); | 371 region->setRegionSettings(m_currentHeaderValue); |
| 385 | 372 |
| 386 // 15.5.10 If the text track list of regions regions contains a region | 373 // 15.5.10 If the text track list of regions regions contains a region |
| 387 // with the same region identifier value as region, remove that region. | 374 // with the same region identifier value as region, remove that region. |
| 388 for (size_t i = 0; i < m_regionList.size(); ++i) | 375 for (size_t i = 0; i < m_regionList.size(); ++i) |
| 389 if (m_regionList[i]->id() == region->id()) { | 376 if (m_regionList[i]->id() == region->id()) { |
| 390 m_regionList.remove(i); | 377 m_regionList.remove(i); |
| 391 break; | 378 break; |
| 392 } | 379 } |
| 393 | 380 |
| 394 m_regionList.append(region); | 381 m_regionList.append(region); |
| 395 } | 382 } |
| 396 #endif | |
| 397 | 383 |
| 398 double WebVTTParser::collectTimeStamp(const String& line, unsigned* position) | 384 double WebVTTParser::collectTimeStamp(const String& line, unsigned* position) |
| 399 { | 385 { |
| 400 // 4.8.10.13.3 Collect a WebVTT timestamp. | 386 // 4.8.10.13.3 Collect a WebVTT timestamp. |
| 401 // 1-4 - Initial checks, let most significant units be minutes. | 387 // 1-4 - Initial checks, let most significant units be minutes. |
| 402 enum Mode { minutes, hours }; | 388 enum Mode { minutes, hours }; |
| 403 Mode mode = minutes; | 389 Mode mode = minutes; |
| 404 if (*position >= line.length() || !isASCIIDigit(line[*position])) | 390 if (*position >= line.length() || !isASCIIDigit(line[*position])) |
| 405 return malformedTime; | 391 return malformedTime; |
| 406 | 392 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 unsigned oldPosition = *position; | 552 unsigned oldPosition = *position; |
| 567 while (*position < length && data[*position] != '\r' && data[*position] != '
\n') | 553 while (*position < length && data[*position] != '\r' && data[*position] != '
\n') |
| 568 (*position)++; | 554 (*position)++; |
| 569 String line = String::fromUTF8(data + oldPosition, *position - oldPosition); | 555 String line = String::fromUTF8(data + oldPosition, *position - oldPosition); |
| 570 skipLineTerminator(data, length, position); | 556 skipLineTerminator(data, length, position); |
| 571 return line; | 557 return line; |
| 572 } | 558 } |
| 573 | 559 |
| 574 } | 560 } |
| 575 | 561 |
| OLD | NEW |