<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[165997] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/165997">165997</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2014-03-20 13:59:53 -0700 (Thu, 20 Mar 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Add a flushing mechanism for the WebVTTParser
https://bugs.webkit.org/show_bug.cgi?id=130532
Reviewed by Eric Carlson.
Merged from Blink (patch by vcarbune@chromium.org):
https://chromium.googlesource.com/chromium/blink/+/1ac2b3081492ab8661429230004013a9a3623f0f
http://crbug.com/54203003
https://chromium.googlesource.com/chromium/blink/+/24343d32bc36d20d59ef3e10040faddde65929e6
http://crbug.com/59453002
https://chromium.googlesource.com/chromium/blink/+/ef2793f1d9d207389589ecf9a136ea5c7170b4af
http://crbug.com/75233002
https://chromium.googlesource.com/chromium/blink/+/a29f2f8324abcd4826b41e7dc34373dee2ec57a9
http://crbug.com/52713005
https://chromium.googlesource.com/chromium/blink/+/7ce003c8d47b39f116f1f2a592a5dfb4a9e77228
http://crbug.com/64303004
https://chromium.googlesource.com/chromium/blink/+/18f896b3498478311e880f782813d5dfc8c0c7d1
http://crbug.com/96933004
https://chromium.googlesource.com/chromium/blink/+/8670e8ecb13254a651f5493ec83f4484d18c154e
http://crbug.com/98783005
https://chromium.googlesource.com/chromium/blink/+/4ac55780a6af3d76e0159c1d145330964ad56647
http://crbug.com/104713002
Tests: http/tests/media/track/track-webvtt-slow-loading-2.html
http/tests/media/track/track-webvtt-slow-loading.html
* CMakeLists.txt:
* GNUmakefile.list.am:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
* html/track/BufferedLineReader.cpp: Added.
* html/track/BufferedLineReader.h: Added.
* html/track/TextTrackRegion.cpp:
* html/track/VTTCue.cpp:
* html/track/WebVTTParser.cpp:
* html/track/WebVTTParser.h:
* loader/TextTrackLoader.cpp:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreGNUmakefilelistam">trunk/Source/WebCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorehtmltrackTextTrackRegioncpp">trunk/Source/WebCore/html/track/TextTrackRegion.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVTTCuecpp">trunk/Source/WebCore/html/track/VTTCue.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTParsercpp">trunk/Source/WebCore/html/track/WebVTTParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTParserh">trunk/Source/WebCore/html/track/WebVTTParser.h</a></li>
<li><a href="#trunkSourceWebCoreloaderTextTrackLoadercpp">trunk/Source/WebCore/loader/TextTrackLoader.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorehtmltrackBufferedLineReadercpp">trunk/Source/WebCore/html/track/BufferedLineReader.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackBufferedLineReaderh">trunk/Source/WebCore/html/track/BufferedLineReader.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/CMakeLists.txt        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -2725,6 +2725,7 @@
</span><span class="cx"> list(APPEND WebCore_SOURCES
</span><span class="cx"> html/track/AudioTrack.cpp
</span><span class="cx"> html/track/AudioTrackList.cpp
</span><ins>+ html/track/BufferedLineReader.cpp
</ins><span class="cx"> html/track/DataCue.cpp
</span><span class="cx"> html/track/InbandGenericTextTrack.cpp
</span><span class="cx"> html/track/InbandTextTrack.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/ChangeLog        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2014-03-20 Brent Fulgham <bfulgham@apple.com>
+
+ Add a flushing mechanism for the WebVTTParser
+ https://bugs.webkit.org/show_bug.cgi?id=130532
+
+ Reviewed by Eric Carlson.
+
+ Merged from Blink (patch by vcarbune@chromium.org):
+ https://chromium.googlesource.com/chromium/blink/+/1ac2b3081492ab8661429230004013a9a3623f0f
+ http://crbug.com/54203003
+ https://chromium.googlesource.com/chromium/blink/+/24343d32bc36d20d59ef3e10040faddde65929e6
+ http://crbug.com/59453002
+ https://chromium.googlesource.com/chromium/blink/+/ef2793f1d9d207389589ecf9a136ea5c7170b4af
+ http://crbug.com/75233002
+ https://chromium.googlesource.com/chromium/blink/+/a29f2f8324abcd4826b41e7dc34373dee2ec57a9
+ http://crbug.com/52713005
+ https://chromium.googlesource.com/chromium/blink/+/7ce003c8d47b39f116f1f2a592a5dfb4a9e77228
+ http://crbug.com/64303004
+ https://chromium.googlesource.com/chromium/blink/+/18f896b3498478311e880f782813d5dfc8c0c7d1
+ http://crbug.com/96933004
+ https://chromium.googlesource.com/chromium/blink/+/8670e8ecb13254a651f5493ec83f4484d18c154e
+ http://crbug.com/98783005
+ https://chromium.googlesource.com/chromium/blink/+/4ac55780a6af3d76e0159c1d145330964ad56647
+ http://crbug.com/104713002
+
+ Tests: http/tests/media/track/track-webvtt-slow-loading-2.html
+ http/tests/media/track/track-webvtt-slow-loading.html
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * WebCore.vcxproj/WebCore.vcxproj:
+ * WebCore.vcxproj/WebCore.vcxproj.filters:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/track/BufferedLineReader.cpp: Added.
+ * html/track/BufferedLineReader.h: Added.
+ * html/track/TextTrackRegion.cpp:
+ * html/track/VTTCue.cpp:
+ * html/track/WebVTTParser.cpp:
+ * html/track/WebVTTParser.h:
+ * loader/TextTrackLoader.cpp:
+
</ins><span class="cx"> 2014-03-20 Alex Christensen <achristensen@webkit.org>
</span><span class="cx">
</span><span class="cx"> Preparation for using Soup on Windows.
</span></span></pre></div>
<a id="trunkSourceWebCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/GNUmakefile.list.am (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/GNUmakefile.list.am        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/GNUmakefile.list.am        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -3682,6 +3682,8 @@
</span><span class="cx">         Source/WebCore/html/track/AudioTrack.h \
</span><span class="cx">         Source/WebCore/html/track/AudioTrackList.cpp \
</span><span class="cx">         Source/WebCore/html/track/AudioTrackList.h \
</span><ins>+        Source/WebCore/html/track/BufferedLineReader.cpp \
+        Source/WebCore/html/track/BufferedLineReader.h \
</ins><span class="cx">         Source/WebCore/html/track/DataCue.cpp \
</span><span class="cx">         Source/WebCore/html/track/DataCue.h \
</span><span class="cx">         Source/WebCore/html/track/InbandGenericTextTrack.cpp \
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -15836,6 +15836,7 @@
</span><span class="cx"> <ClCompile Include="..\html\shadow\SliderThumbElement.cpp" />
</span><span class="cx"> <ClCompile Include="..\html\shadow\SpinButtonElement.cpp" />
</span><span class="cx"> <ClCompile Include="..\html\shadow\TextControlInnerElements.cpp" />
</span><ins>+ <ClCompile Include="..\html\track\BufferedLineReader.cpp" />
</ins><span class="cx"> <ClCompile Include="..\html\track\DataCue.cpp" />
</span><span class="cx"> <ClCompile Include="..\html\track\InbandGenericTextTrack.cpp" />
</span><span class="cx"> <ClCompile Include="..\html\track\InbandTextTrack.cpp" />
</span><span class="lines">@@ -20584,6 +20585,7 @@
</span><span class="cx"> <ClInclude Include="..\html\shadow\SliderThumbElement.h" />
</span><span class="cx"> <ClInclude Include="..\html\shadow\SpinButtonElement.h" />
</span><span class="cx"> <ClInclude Include="..\html\shadow\TextControlInnerElements.h" />
</span><ins>+ <ClInclude Include="..\html\track\BufferedLineReader.h" />
</ins><span class="cx"> <ClInclude Include="..\html\track\DataCue.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\InbandGenericTextTrack.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\InbandTextTrack.h" />
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -4161,6 +4161,9 @@
</span><span class="cx"> <ClCompile Include="..\html\shadow\TextControlInnerElements.cpp">
</span><span class="cx"> <Filter>html\shadow</Filter>
</span><span class="cx"> </ClCompile>
</span><ins>+ <ClCompile Include="..\html\track\BufferedLineReader.cpp">
+ <Filter>html\track</Filter>
+ </ClCompile>
</ins><span class="cx"> <ClCompile Include="..\html\track\DataCue.cpp">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClCompile>
</span><span class="lines">@@ -11221,6 +11224,9 @@
</span><span class="cx"> <ClInclude Include="..\html\shadow\TextControlInnerElements.h">
</span><span class="cx"> <Filter>html\shadow</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\html\track\BufferedLineReader.h">
+ <Filter>html\track</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\html\track\DataCue.h">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClInclude>
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -2280,6 +2280,8 @@
</span><span class="cx">                 7A24587C1021EAF4000A00AA /* InspectorDOMAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A24587A1021EAF4000A00AA /* InspectorDOMAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7A29BA6A187B7C1D00F29CEB /* TemporaryOpenGLSetting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A29BA69187B781C00F29CEB /* TemporaryOpenGLSetting.cpp */; };
</span><span class="cx">                 7A29F57218C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A29F57118C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h */; };
</span><ins>+                7A45032F18DB717200377B34 /* BufferedLineReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A45032D18DB717200377B34 /* BufferedLineReader.cpp */; };
+                7A45033018DB717200377B34 /* BufferedLineReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A45032E18DB717200377B34 /* BufferedLineReader.h */; };
</ins><span class="cx">                 7A54857F14E02D51006AE05A /* InspectorHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A54857D14E02D51006AE05A /* InspectorHistory.cpp */; };
</span><span class="cx">                 7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A54857E14E02D51006AE05A /* InspectorHistory.h */; };
</span><span class="cx">                 7A54881714E432A1006AE05A /* DOMPatchSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A54881514E432A1006AE05A /* DOMPatchSupport.h */; };
</span><span class="lines">@@ -9275,6 +9277,8 @@
</span><span class="cx">                 7A29BA67187B732200F29CEB /* TemporaryOpenGLSetting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryOpenGLSetting.h; sourceTree = "<group>"; };
</span><span class="cx">                 7A29BA69187B781C00F29CEB /* TemporaryOpenGLSetting.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporaryOpenGLSetting.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 7A29F57118C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OutOfBandTextTrackPrivateAVF.h; path = objc/OutOfBandTextTrackPrivateAVF.h; sourceTree = "<group>"; };
</span><ins>+                7A45032D18DB717200377B34 /* BufferedLineReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BufferedLineReader.cpp; sourceTree = "<group>"; };
+                7A45032E18DB717200377B34 /* BufferedLineReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BufferedLineReader.h; sourceTree = "<group>"; };
</ins><span class="cx">                 7A54857D14E02D51006AE05A /* InspectorHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorHistory.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 7A54857E14E02D51006AE05A /* InspectorHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorHistory.h; sourceTree = "<group>"; };
</span><span class="cx">                 7A54881514E432A1006AE05A /* DOMPatchSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMPatchSupport.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -19231,6 +19235,8 @@
</span><span class="cx">                 B1AD4E7713A12A7200846B27 /* track */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                7A45032D18DB717200377B34 /* BufferedLineReader.cpp */,
+                                7A45032E18DB717200377B34 /* BufferedLineReader.h */,
</ins><span class="cx">                                 BE88E0CC1715D2A200658D98 /* AudioTrack.cpp */,
</span><span class="cx">                                 BE88E0CD1715D2A200658D98 /* AudioTrack.h */,
</span><span class="cx">                                 BE88E0CE1715D2A200658D98 /* AudioTrack.idl */,
</span><span class="lines">@@ -23163,6 +23169,7 @@
</span><span class="cx">                                 A80E6D0C0A1989CA007FB8C5 /* CSSStyleRule.h in Headers */,
</span><span class="cx">                                 A8EA80070A19516E00A8EF5F /* CSSStyleSheet.h in Headers */,
</span><span class="cx">                                 FC54D05716A7673100575E4D /* CSSSupportsRule.h in Headers */,
</span><ins>+                                7A45033018DB717200377B34 /* BufferedLineReader.h in Headers */,
</ins><span class="cx">                                 BC80C9880CD294EE00A0B7B3 /* CSSTimingFunctionValue.h in Headers */,
</span><span class="cx">                                 A882DA231593848D000115ED /* CSSToStyleMap.h in Headers */,
</span><span class="cx">                                 371F53E90D2704F900ECE0D5 /* CSSUnicodeRangeValue.h in Headers */,
</span><span class="lines">@@ -28033,6 +28040,7 @@
</span><span class="cx">                                 B2FA3DCE0AB75A6F000E5AC4 /* JSSVGPathSegLinetoAbs.cpp in Sources */,
</span><span class="cx">                                 B2FA3DD00AB75A6F000E5AC4 /* JSSVGPathSegLinetoHorizontalAbs.cpp in Sources */,
</span><span class="cx">                                 B2FA3DD20AB75A6F000E5AC4 /* JSSVGPathSegLinetoHorizontalRel.cpp in Sources */,
</span><ins>+                                7A45032F18DB717200377B34 /* BufferedLineReader.cpp in Sources */,
</ins><span class="cx">                                 B2FA3DD40AB75A6F000E5AC4 /* JSSVGPathSegLinetoRel.cpp in Sources */,
</span><span class="cx">                                 B2FA3DD60AB75A6F000E5AC4 /* JSSVGPathSegLinetoVerticalAbs.cpp in Sources */,
</span><span class="cx">                                 B2FA3DD80AB75A6F000E5AC4 /* JSSVGPathSegLinetoVerticalRel.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackBufferedLineReadercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/track/BufferedLineReader.cpp (0 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/BufferedLineReader.cpp         (rev 0)
+++ trunk/Source/WebCore/html/track/BufferedLineReader.cpp        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -0,0 +1,104 @@
</span><ins>+/*
+ * Copyright (C) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BufferedLineReader.h"
+
+#include <wtf/unicode/CharacterNames.h>
+
+namespace WebCore {
+
+bool BufferedLineReader::getLine(String& line)
+{
+ if (m_maybeSkipLF) {
+ // We ran out of data after a CR (U+000D), which means that we may be
+ // in the middle of a CRLF pair. If the next character is a LF (U+000A)
+ // then skip it, and then (unconditionally) return the buffered line.
+ if (!m_buffer.isEmpty()) {
+ scanCharacter(newlineCharacter);
+ m_maybeSkipLF = false;
+ }
+ // If there was no (new) data available, then keep m_maybeSkipLF set,
+ // and fall through all the way down to the EOS check at the end of
+ // the method.
+ }
+
+ bool shouldReturnLine = false;
+ bool checkForLF = false;
+ while (!m_buffer.isEmpty()) {
+ UChar c = m_buffer.currentChar();
+ m_buffer.advance();
+
+ if (c == newlineCharacter || c == carriageReturn) {
+ // We found a line ending. Return the accumulated line.
+ shouldReturnLine = true;
+ checkForLF = (c == carriageReturn);
+ break;
+ }
+
+ // NULs are transformed into U+FFFD (REPLACEMENT CHAR.) in step 1 of
+ // the WebVTT parser algorithm.
+ if (c == '\0')
+ c = replacementCharacter;
+
+ m_lineBuffer.append(c);
+ }
+
+ if (checkForLF) {
+ // May be in the middle of a CRLF pair.
+ if (!m_buffer.isEmpty()) {
+ // Scan a potential newline character.
+ scanCharacter(newlineCharacter);
+ } else {
+ // Check for the LF on the next call (unless we reached EOS, in
+ // which case we'll return the contents of the line buffer, and
+ // reset state for the next line.)
+ m_maybeSkipLF = true;
+ }
+ }
+
+ if (isAtEndOfStream()) {
+ // We've reached the end of the stream proper. Emit a line if the
+ // current line buffer is non-empty. (Note that if shouldReturnLine is
+ // set already, we want to return a line nonetheless.)
+ shouldReturnLine |= !m_lineBuffer.isEmpty();
+ }
+
+ if (shouldReturnLine) {
+ line = m_lineBuffer.toString();
+ m_lineBuffer.clear();
+ return true;
+ }
+
+ ASSERT(m_buffer.isEmpty());
+ return false;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmltrackBufferedLineReaderh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/track/BufferedLineReader.h (0 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/BufferedLineReader.h         (rev 0)
+++ trunk/Source/WebCore/html/track/BufferedLineReader.h        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+/*
+ * Copyright (C) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BufferedLineReader_h
+#define BufferedLineReader_h
+
+#include "SegmentedString.h"
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+// Line collection helper for the WebVTT Parser.
+//
+// Converts a stream of data (== a sequence of Strings) into a set of
+// lines. CR, LR or CRLF are considered linebreaks. Normalizes NULs (U+0000)
+// to 'REPLACEMENT CHARACTER' (U+FFFD) and does not return the linebreaks as
+// part of the result.
+class BufferedLineReader {
+ WTF_MAKE_NONCOPYABLE(BufferedLineReader);
+public:
+ BufferedLineReader()
+ : m_endOfStream(false)
+ , m_maybeSkipLF(false) { }
+
+ // Append data to the internal buffer.
+ void append(const String& data)
+ {
+ ASSERT(!m_endOfStream);
+ m_buffer.append(SegmentedString(data));
+ }
+
+ // Indicate that no more data will be appended. This will cause any
+ // potentially "unterminated" line to be returned from getLine.
+ void setEndOfStream() { m_endOfStream = true; }
+
+ // Attempt to read a line from the internal buffer (fed via append).
+ // If successful, true is returned and |line| is set to the line that was
+ // read. If no line could be read false is returned.
+ bool getLine(String& line);
+
+ // Returns true if EOS has been reached proper.
+ bool isAtEndOfStream() const { return m_endOfStream && m_buffer.isEmpty(); }
+
+private:
+ // Consume the next character the buffer if it is the character |c|.
+ void scanCharacter(UChar c)
+ {
+ ASSERT(!m_buffer.isEmpty());
+ if (m_buffer.currentChar() == c)
+ m_buffer.advance();
+ }
+
+ SegmentedString m_buffer;
+ StringBuilder m_lineBuffer;
+ bool m_endOfStream;
+ bool m_maybeSkipLF;
+};
+
+} // namespace WebCore
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmltrackTextTrackRegioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/TextTrackRegion.cpp (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/TextTrackRegion.cpp        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/html/track/TextTrackRegion.cpp        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -262,25 +262,22 @@
</span><span class="cx"> {
</span><span class="cx"> DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, ("up", AtomicString::ConstructFromLiteral));
</span><span class="cx">
</span><del>- bool isValidSetting;
- String numberAsString;
- int number;
- FloatPoint anchorPosition;
-
</del><span class="cx"> switch (setting) {
</span><span class="cx"> case Id:
</span><span class="cx"> if (value.find("-->") == notFound)
</span><span class="cx"> m_id = value;
</span><span class="cx"> break;
</span><del>- case Width:
- number = WebVTTParser::parseFloatPercentageValue(value, isValidSetting);
- if (isValidSetting)
- m_width = number;
</del><ins>+ case Width: {
+ float floatWidth;
+ if (WebVTTParser::parseFloatPercentageValue(value, floatWidth))
+ m_width = floatWidth;
</ins><span class="cx"> else
</span><span class="cx"> LOG(Media, "TextTrackRegion::parseSettingValue, invalid Width");
</span><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx"> case Height: {
</span><span class="cx"> unsigned position = 0;
</span><ins>+ int number;
</ins><span class="cx"> if (WebVTTParser::collectDigitsToInt(value, &position, number) && position == value.length())
</span><span class="cx"> m_heightInLines = number;
</span><span class="cx"> else
</span><span class="lines">@@ -288,17 +285,11 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case RegionAnchor:
</span><del>- anchorPosition = WebVTTParser::parseFloatPercentageValuePair(value, ',', isValidSetting);
- if (isValidSetting)
- m_regionAnchor = anchorPosition;
- else
</del><ins>+ if (!WebVTTParser::parseFloatPercentageValuePair(value, ',', m_regionAnchor))
</ins><span class="cx"> LOG(Media, "TextTrackRegion::parseSettingValue, invalid RegionAnchor");
</span><span class="cx"> break;
</span><span class="cx"> case ViewportAnchor:
</span><del>- anchorPosition = WebVTTParser::parseFloatPercentageValuePair(value, ',', isValidSetting);
- if (isValidSetting)
- m_viewportAnchor = anchorPosition;
- else
</del><ins>+ if (!WebVTTParser::parseFloatPercentageValuePair(value, ',', m_viewportAnchor))
</ins><span class="cx"> LOG(Media, "TextTrackRegion::parseSettingValue, invalid ViewportAnchor");
</span><span class="cx"> break;
</span><span class="cx"> case Scroll:
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTCuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/VTTCue.cpp (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTCue.cpp        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/html/track/VTTCue.cpp        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -427,7 +427,7 @@
</span><span class="cx"> void VTTCue::createWebVTTNodeTree()
</span><span class="cx"> {
</span><span class="cx"> if (!m_webVTTNodeTree)
</span><del>- m_webVTTNodeTree = std::make_unique<WebVTTParser>(nullptr, scriptExecutionContext())->createDocumentFragmentFromCueText(m_content);
</del><ins>+ m_webVTTNodeTree = WebVTTParser::createDocumentFragmentFromCueText(ownerDocument(), m_content);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void VTTCue::copyWebVTTNodeToDOMTree(ContainerNode* webVTTNode, ContainerNode* parent)
</span><span class="lines">@@ -696,8 +696,9 @@
</span><span class="cx"> if (child->nodeName() == timestampTag) {
</span><span class="cx"> unsigned position = 0;
</span><span class="cx"> String timestamp = child->nodeValue();
</span><del>- double currentTimestamp = WebVTTParser::collectTimeStamp(timestamp, &position);
- ASSERT(currentTimestamp != -1);
</del><ins>+ double currentTimestamp;
+ bool check = WebVTTParser::collectTimeStamp(timestamp, position, currentTimestamp);
+ ASSERT_UNUSED(check, check);
</ins><span class="cx">
</span><span class="cx"> if (currentTimestamp > movieTime)
</span><span class="cx"> isPastNode = false;
</span><span class="lines">@@ -970,7 +971,7 @@
</span><span class="cx"> // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9),
</span><span class="cx"> // then jump to the step labeled next setting.
</span><span class="cx"> int number;
</span><del>- if (!WebVTTParser::collectDigitsToInt(input, &position, number))
</del><ins>+ if (!WebVTTParser::collectDigitsToInt(input, position, number))
</ins><span class="cx"> break;
</span><span class="cx"> if (position >= input.length())
</span><span class="cx"> break;
</span><span class="lines">@@ -986,7 +987,6 @@
</span><span class="cx">
</span><span class="cx"> // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
</span><span class="cx"> // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
</span><del>- // NOTE: toInt ignores trailing non-digit characters, such as '%'.
</del><span class="cx"> if (number < 0 || number > 100)
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -1001,7 +1001,7 @@
</span><span class="cx"> // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
</span><span class="cx"> // NINE (9), then jump to the step labeled next setting.
</span><span class="cx"> int number;
</span><del>- if (!WebVTTParser::collectDigitsToInt(input, &position, number))
</del><ins>+ if (!WebVTTParser::collectDigitsToInt(input, position, number))
</ins><span class="cx"> break;
</span><span class="cx"> if (position >= input.length())
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTParser.cpp (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTParser.cpp        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/html/track/WebVTTParser.cpp        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -45,22 +45,20 @@
</span><span class="cx"> const double secondsPerHour = 3600;
</span><span class="cx"> const double secondsPerMinute = 60;
</span><span class="cx"> const double secondsPerMillisecond = 0.001;
</span><del>-const double malformedTime = -1;
-const UChar bom = 0xFEFF;
</del><span class="cx"> const char* fileIdentifier = "WEBVTT";
</span><span class="cx"> const unsigned fileIdentifierLength = 6;
</span><span class="cx">
</span><del>-static unsigned scanDigits(const String& input, unsigned* position)
</del><ins>+static unsigned scanDigits(const String& input, unsigned& position)
</ins><span class="cx"> {
</span><del>- unsigned startPosition = *position;
- while (*position < input.length() && isASCIIDigit(input[*position]))
- (*position)++;
- return *position - startPosition;
</del><ins>+ unsigned startPosition = position;
+ while (position < input.length() && isASCIIDigit(input[position]))
+ position++;
+ return position - startPosition;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-unsigned WebVTTParser::collectDigitsToInt(const String& input, unsigned* position, int& number)
</del><ins>+unsigned WebVTTParser::collectDigitsToInt(const String& input, unsigned& position, int& number)
</ins><span class="cx"> {
</span><del>- unsigned startPosition = *position;
</del><ins>+ unsigned startPosition = position;
</ins><span class="cx"> unsigned numDigits = scanDigits(input, position);
</span><span class="cx"> if (!numDigits) {
</span><span class="cx"> number = 0;
</span><span class="lines">@@ -91,13 +89,11 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><del>-float WebVTTParser::parseFloatPercentageValue(const String& value, bool& isValidSetting)
</del><ins>+bool WebVTTParser::parseFloatPercentageValue(const String& value, float& percentage)
</ins><span class="cx"> {
</span><span class="cx"> // '%' must be present and at the end of the setting value.
</span><del>- if (value.find('%', 1) != value.length() - 1) {
- isValidSetting = false;
- return 0;
- }
</del><ins>+ if (value.isEmpty() || value[value.length() - 1] != '%')
+ return false;
</ins><span class="cx">
</span><span class="cx"> unsigned position = 0;
</span><span class="cx"> unsigned digitsBeforeDot = scanDigits(value, &position);
</span><span class="lines">@@ -109,44 +105,45 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // At least one digit is required
</span><del>- if (!digitsBeforeDot && !digitsAfterDot) {
- isValidSetting = false;
- return 0;
- }
</del><ins>+ if (!digitsBeforeDot && !digitsAfterDot)
+ return false;
</ins><span class="cx">
</span><span class="cx"> float number = value.toFloat();
</span><del>- isValidSetting = number >= 0 && number <= 100;
- return number;
</del><ins>+ if (number < 0 || number > 100)
+ return false;
+
+ percentage = number;
+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-FloatPoint WebVTTParser::parseFloatPercentageValuePair(const String& value, char delimiter, bool& isValidSetting)
</del><ins>+bool WebVTTParser::parseFloatPercentageValuePair(const String& value, char delimiter, FloatPoint& valuePair)
</ins><span class="cx"> {
</span><span class="cx"> // The delimiter can't be the first or second value because a pair of
</span><span class="cx"> // percentages (x%,y%) implies that at least the first two characters
</span><span class="cx"> // are the first percentage value.
</span><span class="cx"> size_t delimiterOffset = value.find(delimiter, 2);
</span><del>- if (delimiterOffset == notFound || delimiterOffset == value.length() - 1) {
- isValidSetting = false;
- return FloatPoint(0, 0);
- }
</del><ins>+ if (delimiterOffset == notFound || delimiterOffset == value.length() - 1)
+ return false;
</ins><span class="cx">
</span><del>- bool isFirstValueValid;
- float firstCoord = parseFloatPercentageValue(value.substring(0, delimiterOffset), isFirstValueValid);
</del><ins>+ float firstCoord;
+ if (!parseFloatPercentageValue(value.substring(0, delimiterOffset), firstCoord))
+ return false;
</ins><span class="cx">
</span><del>- bool isSecondValueValid;
- float secondCoord = parseFloatPercentageValue(value.substring(delimiterOffset + 1, value.length() - 1), isSecondValueValid);
</del><ins>+ float secondCoord;
+ if (!parseFloatPercentageValue(value.substring(delimiterOffset + 1, value.length() - 1), secondCoord))
+ return false;
</ins><span class="cx">
</span><del>- isValidSetting = isFirstValueValid && isSecondValueValid;
- return FloatPoint(firstCoord, secondCoord);
</del><ins>+ valuePair = FloatPoint(firstCoord, secondCoord);
+ return true;
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> WebVTTParser::WebVTTParser(WebVTTParserClient* client, ScriptExecutionContext* context)
</span><span class="cx"> : m_scriptExecutionContext(context)
</span><span class="cx"> , m_state(Initial)
</span><ins>+ , m_decoder(TextResourceDecoder::create("text/plain", UTF8Encoding()))
</ins><span class="cx"> , m_currentStartTime(0)
</span><span class="cx"> , m_currentEndTime(0)
</span><del>- , m_tokenizer(std::make_unique<WebVTTTokenizer>())
</del><span class="cx"> , m_client(client)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -167,16 +164,28 @@
</span><span class="cx">
</span><span class="cx"> void WebVTTParser::parseBytes(const char* data, unsigned length)
</span><span class="cx"> {
</span><ins>+ String textData = m_decoder->decode(data, length);
+ m_lineReader.append(textData);
+ parse();
+}
+
+void WebVTTParser::flush()
+{
+ String textData = m_decoder->flush();
+ m_lineReader.append(textData);
+ m_lineReader.setEndOfStream();
+ parse();
+ flushPendingCue();
+}
+
+void WebVTTParser::parse()
+{
</ins><span class="cx"> // WebVTT parser algorithm. (5.1 WebVTT file parsing.)
</span><span class="cx"> // Steps 1 - 3 - Initial setup.
</span><del>- unsigned position = 0;
-
- while (position < length) {
- String line = collectNextLine(data, length, &position);
- if (line.isNull()) {
- m_buffer.append(data + position, length - position);
</del><ins>+ String line;
+ while (m_lineReader.getLine(line)) {
+ if (line.isNull())
</ins><span class="cx"> return;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> switch (m_state) {
</span><span class="cx"> case Initial:
</span><span class="lines">@@ -206,7 +215,7 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case Id:
</span><del>- // Step 17-20 - Allow any number of line terminators, then initialize new cue values.
</del><ins>+ // Steps 17 - 20 - Allow any number of line terminators, then initialize new cue values.
</ins><span class="cx"> if (line.isEmpty())
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -252,28 +261,26 @@
</span><span class="cx"> m_state = Finished;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebVTTParser::flushPendingCue()
+{
+ ASSERT(m_lineReader.isAtEndOfStream());
+ // If we're in the CueText state when we run out of data, we emit the pending cue.
+ if (m_state == CueText)
+ createNewCue();
+}
+
</ins><span class="cx"> bool WebVTTParser::hasRequiredFileIdentifier(const String& line)
</span><span class="cx"> {
</span><span class="cx"> // A WebVTT file identifier consists of an optional BOM character,
</span><span class="cx"> // the string "WEBVTT" followed by an optional space or tab character,
</span><span class="cx"> // and any number of characters that are not line terminators ...
</span><del>- unsigned linePos = 0;
-
</del><span class="cx"> if (line.isEmpty())
</span><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (line[0] == bom)
- ++linePos;
-
- if (line.length() < fileIdentifierLength + linePos)
</del><ins>+ if (!line.startsWith(fileIdentifier, fileIdentifierLength))
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- for (unsigned i = 0; i < fileIdentifierLength; ++i, ++linePos) {
- if (line[linePos] != fileIdentifier[i])
- return false;
- }
-
- if (linePos < line.length() && line[linePos] != ' ' && line[linePos] != '\t')
</del><ins>+ if (line.length() > fileIdentifierLength && !isASpace(line[fileIdentifierLength]))
</ins><span class="cx"> return false;
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="lines">@@ -287,10 +294,10 @@
</span><span class="cx"> // Step 12.4 If line contains the character ":" (A U+003A COLON), then set metadata's
</span><span class="cx"> // name to the substring of line before the first ":" character and
</span><span class="cx"> // metadata's value to the substring after this character.
</span><del>- if (!line.contains(":"))
</del><ins>+ size_t colonPosition = line.find(':');
+ if (colonPosition == notFound)
</ins><span class="cx"> return;
</span><span class="cx">
</span><del>- unsigned colonPosition = line.find(":");
</del><span class="cx"> String headerName = line.substring(0, colonPosition);
</span><span class="cx">
</span><span class="cx"> // Step 12.5 If metadata's name equals "Region":
</span><span class="lines">@@ -317,16 +324,15 @@
</span><span class="cx"> // Collect WebVTT cue timings and settings. (5.3 WebVTT cue timings and settings parsing.)
</span><span class="cx"> // Steps 1 - 3 - Let input be the string being parsed and position be a pointer into input
</span><span class="cx"> unsigned position = 0;
</span><del>- skipWhiteSpace(line, &position);
</del><ins>+ skipWhiteSpace(line, position);
</ins><span class="cx">
</span><span class="cx"> // Steps 4 - 5 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue start time be the collected time.
</span><del>- m_currentStartTime = collectTimeStamp(line, &position);
- if (m_currentStartTime == malformedTime)
</del><ins>+ if (!collectTimeStamp(line, position, m_currentStartTime))
</ins><span class="cx"> return BadCue;
</span><span class="cx"> if (position >= line.length())
</span><span class="cx"> return BadCue;
</span><span class="cx">
</span><del>- skipWhiteSpace(line, &position);
</del><ins>+ skipWhiteSpace(line, position);
</ins><span class="cx">
</span><span class="cx"> // Steps 6 - 9 - If the next three characters are not "-->", abort and return failure.
</span><span class="cx"> if (line.find("-->", position) == notFound)
</span><span class="lines">@@ -335,13 +341,12 @@
</span><span class="cx"> if (position >= line.length())
</span><span class="cx"> return BadCue;
</span><span class="cx">
</span><del>- skipWhiteSpace(line, &position);
</del><ins>+ skipWhiteSpace(line, position);
</ins><span class="cx">
</span><span class="cx"> // Steps 10 - 11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected time.
</span><del>- m_currentEndTime = collectTimeStamp(line, &position);
- if (m_currentEndTime == malformedTime)
</del><ins>+ if (!collectTimeStamp(line, position, m_currentEndTime))
</ins><span class="cx"> return BadCue;
</span><del>- skipWhiteSpace(line, &position);
</del><ins>+ skipWhiteSpace(line, position);
</ins><span class="cx">
</span><span class="cx"> // Step 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCue).
</span><span class="cx"> m_currentSettings = line.substring(position, line.length()-1);
</span><span class="lines">@@ -357,7 +362,7 @@
</span><span class="cx"> if (!m_currentContent.isEmpty())
</span><span class="cx"> m_currentContent.append("\n");
</span><span class="cx"> m_currentContent.append(line);
</span><del>-
</del><ins>+
</ins><span class="cx"> return CueText;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -368,34 +373,54 @@
</span><span class="cx"> return Id;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-PassRefPtr<DocumentFragment> WebVTTParser::createDocumentFragmentFromCueText(const String& text)
</del><ins>+// A helper class for the construction of a "cue fragment" from the cue text.
+class WebVTTTreeBuilder {
+public:
+ WebVTTTreeBuilder(Document& document)
+ : m_document(document) { }
+
+ PassRefPtr<DocumentFragment> buildFromString(const String& cueText);
+
+private:
+ void constructTreeFromToken(Document&);
+
+ WebVTTToken m_token;
+ RefPtr<ContainerNode> m_currentNode;
+ Vector<AtomicString> m_languageStack;
+ Document& m_document;
+};
+
+PassRefPtr<DocumentFragment> WebVTTTreeBuilder::buildFromString(const String& cueText)
</ins><span class="cx"> {
</span><span class="cx"> // Cue text processing based on
</span><span class="cx"> // 5.4 WebVTT cue text parsing rules, and
</span><span class="cx"> // 5.5 WebVTT cue text DOM construction rules.
</span><ins>+ RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
</ins><span class="cx">
</span><del>- ASSERT(m_scriptExecutionContext->isDocument());
- Document* document = toDocument(m_scriptExecutionContext);
-
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(*document);
-
- if (text.isEmpty()) {
- fragment->parserAppendChild(Text::create(*document, emptyString()));
</del><ins>+ if (cueText.isEmpty()) {
+ fragment->parserAppendChild(Text::create(m_document, emptyString()));
</ins><span class="cx"> return fragment.release();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_currentNode = fragment;
</span><del>- m_tokenizer->reset();
</del><ins>+
+ std::unique_ptr<WebVTTTokenizer> tokenizer(std::make_unique<WebVTTTokenizer>());
</ins><span class="cx"> m_token.clear();
</span><del>-
</del><span class="cx"> m_languageStack.clear();
</span><del>- SegmentedString content(text);
- while (m_tokenizer->nextToken(content, m_token))
- constructTreeFromToken(document);
</del><ins>+
+ SegmentedString content(cueText);
+ while (tokenizer->nextToken(content, m_token))
+ constructTreeFromToken(m_document);
</ins><span class="cx">
</span><span class="cx"> return fragment.release();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+PassRefPtr<DocumentFragment> WebVTTParser::createDocumentFragmentFromCueText(Document& document, const String& cueText)
+{
+ WebVTTTreeBuilder treeBuilder(document);
+ return treeBuilder.buildFromString(cueText);
+}
+
</ins><span class="cx"> void WebVTTParser::createNewCue()
</span><span class="cx"> {
</span><span class="cx"> RefPtr<WebVTTCueData> cue = WebVTTCueData::create();
</span><span class="lines">@@ -442,7 +467,7 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-double WebVTTParser::collectTimeStamp(const String& line, unsigned* position)
</del><ins>+bool WebVTTParser::collectTimeStamp(const String& line, unsigned& position, double& timeStamp)
</ins><span class="cx"> {
</span><span class="cx"> // Collect a WebVTT timestamp (5.3 WebVTT cue timings and settings parsing.)
</span><span class="cx"> // Steps 1 - 4 - Initial checks, let most significant units be minutes.
</span><span class="lines">@@ -454,24 +479,24 @@
</span><span class="cx"> int value1;
</span><span class="cx"> unsigned value1Digits = collectDigitsToInt(line, position, value1);
</span><span class="cx"> if (!value1Digits)
</span><del>- return malformedTime;
</del><ins>+ return false;
</ins><span class="cx"> if (value1Digits != 2 || value1 > 59)
</span><span class="cx"> mode = hours;
</span><span class="cx">
</span><span class="cx"> // Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2 chars).
</span><del>- if (*position >= line.length() || line[(*position)++] != ':')
- return malformedTime;
</del><ins>+ if (position >= line.length() || line[position++] != ':')
+ return false;
</ins><span class="cx"> int value2;
</span><span class="cx"> if (collectDigitsToInt(line, position, value2) != 2)
</span><del>- return malformedTime;
</del><ins>+ return false;
</ins><span class="cx">
</span><span class="cx"> // Step 12 - Detect whether this timestamp includes hours.
</span><span class="cx"> int value3;
</span><del>- if (mode == hours || (*position < line.length() && line[*position] == ':')) {
- if (*position >= line.length() || line[(*position)++] != ':')
- return malformedTime;
</del><ins>+ if (mode == hours || (position < line.length() && line[position] == ':')) {
+ if (position >= line.length() || line[position++] != ':')
+ return false;
</ins><span class="cx"> if (collectDigitsToInt(line, position, value3) != 2)
</span><del>- return malformedTime;
</del><ins>+ return false;
</ins><span class="cx"> } else {
</span><span class="cx"> value3 = value2;
</span><span class="cx"> value2 = value1;
</span><span class="lines">@@ -479,16 +504,17 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars).
</span><del>- if (*position >= line.length() || line[(*position)++] != '.')
- return malformedTime;
</del><ins>+ if (position >= line.length() || line[position++] != '.')
+ return false;
</ins><span class="cx"> int value4;
</span><span class="cx"> if (collectDigitsToInt(line, position, value4) != 3)
</span><del>- return malformedTime;
</del><ins>+ return false;
</ins><span class="cx"> if (value2 > 59 || value3 > 59)
</span><del>- return malformedTime;
</del><ins>+ return false;
</ins><span class="cx">
</span><span class="cx"> // Steps 18 - 19 - Calculate result.
</span><del>- return (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + (value4 * secondsPerMillisecond);
</del><ins>+ timeStamp = (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + (value4 * secondsPerMillisecond);
+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static WebVTTNodeType tokenToNodeType(WebVTTToken& token)
</span><span class="lines">@@ -520,55 +546,75 @@
</span><span class="cx"> return WebVTTNodeTypeNone;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void WebVTTParser::constructTreeFromToken(Document* document)
</del><ins>+void WebVTTTreeBuilder::constructTreeFromToken(Document& document)
</ins><span class="cx"> {
</span><span class="cx"> // http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules
</span><span class="cx">
</span><span class="cx"> switch (m_token.type()) {
</span><span class="cx"> case WebVTTTokenTypes::Character: {
</span><span class="cx"> String content = m_token.characters().toString();
</span><del>- RefPtr<Text> child = Text::create(*document, content);
</del><ins>+ RefPtr<Text> child = Text::create(document, content);
</ins><span class="cx"> m_currentNode->parserAppendChild(child);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case WebVTTTokenTypes::StartTag: {
</span><del>- RefPtr<WebVTTElement> child;
</del><span class="cx"> WebVTTNodeType nodeType = tokenToNodeType(m_token);
</span><del>- if (nodeType != WebVTTNodeTypeNone)
- child = WebVTTElement::create(nodeType, *document);
- if (child) {
- if (!m_token.classes().isEmpty())
- child->setAttribute(classAttr, m_token.classes().toAtomicString());
</del><ins>+ if (nodeType == WebVTTNodeTypeNone)
+ break;
</ins><span class="cx">
</span><del>- if (child->webVTTNodeType() == WebVTTNodeTypeVoice)
- child->setAttribute(WebVTTElement::voiceAttributeName(), m_token.annotation().toAtomicString());
- else if (child->webVTTNodeType() == WebVTTNodeTypeLanguage) {
- m_languageStack.append(m_token.annotation().toAtomicString());
- child->setAttribute(WebVTTElement::langAttributeName(), m_languageStack.last());
- }
- if (!m_languageStack.isEmpty())
- child->setLanguage(m_languageStack.last());
- m_currentNode->parserAppendChild(child);
- m_currentNode = child;
</del><ins>+ WebVTTNodeType currentType = m_currentNode->isWebVTTElement() ? toWebVTTElement(m_currentNode.get())->webVTTNodeType() : WebVTTNodeTypeNone;
+ // <rt> is only allowed if the current node is <ruby>.
+ if (nodeType == WebVTTNodeTypeRubyText && currentType != WebVTTNodeTypeRuby)
+ break;
+
+ RefPtr<WebVTTElement> child = WebVTTElement::create(nodeType, document);
+ if (!m_token.classes().isEmpty())
+ child->setAttribute(classAttr, m_token.classes().toAtomicString());
+
+ if (nodeType == WebVTTNodeTypeVoice)
+ child->setAttribute(WebVTTElement::voiceAttributeName(), m_token.annotation().toAtomicString());
+ else if (nodeType == WebVTTNodeTypeLanguage) {
+ m_languageStack.append(m_token.annotation().toAtomicString());
+ child->setAttribute(WebVTTElement::langAttributeName(), m_languageStack.last());
</ins><span class="cx"> }
</span><ins>+ if (!m_languageStack.isEmpty())
+ child->setLanguage(m_languageStack.last());
+ m_currentNode->parserAppendChild(child);
+ m_currentNode = child;
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case WebVTTTokenTypes::EndTag: {
</span><span class="cx"> WebVTTNodeType nodeType = tokenToNodeType(m_token);
</span><del>- if (nodeType != WebVTTNodeTypeNone) {
- if (nodeType == WebVTTNodeTypeLanguage && m_currentNode->isWebVTTElement() && toWebVTTElement(m_currentNode.get())->webVTTNodeType() == WebVTTNodeTypeLanguage)
- m_languageStack.removeLast();
- if (m_currentNode->parentNode())
- m_currentNode = m_currentNode->parentNode();
</del><ins>+ if (nodeType == WebVTTNodeTypeNone)
+ break;
+
+ // The only non-VTTElement would be the DocumentFragment root. (Text
+ // nodes and PIs will never appear as m_currentNode.)
+ if (!m_currentNode->isWebVTTElement())
+ break;
+
+ WebVTTNodeType currentType = toWebVTTElement(m_currentNode.get())->webVTTNodeType();
+ bool matchesCurrent = nodeType == currentType;
+ if (!matchesCurrent) {
+ // </ruby> auto-closes <rt>
+ if (currentType == WebVTTNodeTypeRubyText && nodeType == WebVTTNodeTypeRuby) {
+ if (m_currentNode->parentNode())
+ m_currentNode = m_currentNode->parentNode();
+ } else
+ break;
</ins><span class="cx"> }
</span><ins>+ if (nodeType == WebVTTNodeTypeLanguage)
+ m_languageStack.removeLast();
+ if (m_currentNode->parentNode())
+ m_currentNode = m_currentNode->parentNode();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case WebVTTTokenTypes::TimestampTag: {
</span><span class="cx"> unsigned position = 0;
</span><span class="cx"> String charactersString = m_token.characters().toString();
</span><del>- double time = collectTimeStamp(charactersString, &position);
- if (time != malformedTime)
- m_currentNode->parserAppendChild(ProcessingInstruction::create(*document, "timestamp", charactersString));
</del><ins>+ double parsedTimeStamp;
+ if (WebVTTParser::collectTimeStamp(charactersString, position, parsedTimeStamp))
+ m_currentNode->parserAppendChild(ProcessingInstruction::create(document, "timestamp", charactersString));
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> default:
</span><span class="lines">@@ -577,34 +623,12 @@
</span><span class="cx"> m_token.clear();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void WebVTTParser::skipWhiteSpace(const String& line, unsigned* position)
</del><ins>+void WebVTTParser::skipWhiteSpace(const String& line, unsigned& position)
</ins><span class="cx"> {
</span><del>- while (*position < line.length() && isASpace(line[*position]))
- (*position)++;
</del><ins>+ while (position < line.length() && isASpace(line[position]))
+ position++;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-String WebVTTParser::collectNextLine(const char* data, unsigned length, unsigned* position)
-{
- unsigned currentPosition = *position;
- while (currentPosition < length && data[currentPosition] != '\r' && data[currentPosition] != '\n')
- currentPosition++;
- if (currentPosition >= length)
- return String();
- String line = String::fromUTF8(data + *position , currentPosition - *position);
- if (data[currentPosition] == '\r')
- currentPosition++;
- if (currentPosition < length && data[currentPosition] == '\n')
- currentPosition++;
- *position = currentPosition;
- if (m_buffer.isEmpty())
- return line;
-
- String lineWithBuffer = String::fromUTF8(m_buffer.data(), m_buffer.size());
- lineWithBuffer.append(line);
- m_buffer.clear();
- return lineWithBuffer;
</del><span class="cx"> }
</span><span class="cx">
</span><del>-}
-
</del><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTParser.h (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTParser.h        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/html/track/WebVTTParser.h        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -35,8 +35,10 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx">
</span><ins>+#include "BufferedLineReader.h"
</ins><span class="cx"> #include "DocumentFragment.h"
</span><span class="cx"> #include "HTMLNames.h"
</span><ins>+#include "TextResourceDecoder.h"
</ins><span class="cx"> #include "TextTrackRegion.h"
</span><span class="cx"> #include "WebVTTTokenizer.h"
</span><span class="cx"> #include <memory>
</span><span class="lines">@@ -128,18 +130,19 @@
</span><span class="cx"> // U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
</span><span class="cx"> return c == ' ' || c == '\t';
</span><span class="cx"> }
</span><del>- static unsigned collectDigitsToInt(const String&, unsigned* position, int& number);
</del><ins>+ static unsigned collectDigitsToInt(const String&, unsigned& position, int& number);
</ins><span class="cx"> static String collectWord(const String&, unsigned*);
</span><del>- static double collectTimeStamp(const String&, unsigned*);
</del><ins>+ static bool collectTimeStamp(const String&, unsigned&, double&);
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><span class="cx"> // Useful functions for parsing percentage settings.
</span><del>- static float parseFloatPercentageValue(const String&, bool&);
- static FloatPoint parseFloatPercentageValuePair(const String&, char, bool&);
</del><ins>+ static bool parseFloatPercentageValue(const String&, float&);
+ static bool parseFloatPercentageValuePair(const String&, char, FloatPoint&);
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> // Input data to the parser to parse.
</span><span class="cx"> void parseBytes(const char* data, unsigned length);
</span><ins>+ void flush();
</ins><span class="cx"> void fileFinished();
</span><span class="cx">
</span><span class="cx"> // Transfers ownership of last parsed cues to caller.
</span><span class="lines">@@ -148,13 +151,16 @@
</span><span class="cx"> void getNewRegions(Vector<RefPtr<TextTrackRegion>>&);
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(const String&);
</del><ins>+ // Create the DocumentFragment representation of the WebVTT cue text.
+ static PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(Document&, const String&);
</ins><span class="cx">
</span><span class="cx"> protected:
</span><span class="cx"> ScriptExecutionContext* m_scriptExecutionContext;
</span><span class="cx"> ParseState m_state;
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ void parse();
+ void flushPendingCue();
</ins><span class="cx"> bool hasRequiredFileIdentifier(const String&);
</span><span class="cx"> ParseState collectCueId(const String&);
</span><span class="cx"> ParseState collectTimingsAndSettings(const String&);
</span><span class="lines">@@ -169,27 +175,18 @@
</span><span class="cx"> void createNewRegion(const String& headerValue);
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- static void skipWhiteSpace(const String&, unsigned*);
</del><ins>+ static void skipWhiteSpace(const String&, unsigned&);
</ins><span class="cx">
</span><del>- String collectNextLine(const char* data, unsigned length, unsigned*);
-
- void constructTreeFromToken(Document*);
-
- Vector<char> m_buffer;
</del><ins>+ BufferedLineReader m_lineReader;
+ RefPtr<TextResourceDecoder> m_decoder;
</ins><span class="cx"> String m_currentId;
</span><span class="cx"> double m_currentStartTime;
</span><span class="cx"> double m_currentEndTime;
</span><span class="cx"> StringBuilder m_currentContent;
</span><span class="cx"> String m_currentSettings;
</span><span class="cx">
</span><del>- WebVTTToken m_token;
- std::unique_ptr<WebVTTTokenizer> m_tokenizer;
-
- RefPtr<ContainerNode> m_currentNode;
-
</del><span class="cx"> WebVTTParserClient* m_client;
</span><span class="cx">
</span><del>- Vector<AtomicString> m_languageStack;
</del><span class="cx"> Vector<RefPtr<WebVTTCueData>> m_cuelist;
</span><span class="cx">
</span><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderTextTrackLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/TextTrackLoader.cpp (165996 => 165997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/TextTrackLoader.cpp        2014-03-20 20:55:05 UTC (rev 165996)
+++ trunk/Source/WebCore/loader/TextTrackLoader.cpp        2014-03-20 20:59:53 UTC (rev 165997)
</span><span class="lines">@@ -141,6 +141,9 @@
</span><span class="cx"> m_state = resource->errorOccurred() ? Failed : Finished;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ if (m_state == Finished && m_cueParser)
+ m_cueParser->flush();
+
</ins><span class="cx"> if (!m_cueLoadTimer.isActive())
</span><span class="cx"> m_cueLoadTimer.startOneShot(0);
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>