<!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>[166066] trunk</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/166066">166066</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2014-03-21 09:31:22 -0700 (Fri, 21 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge WebVTT Tokenizer Updates
https://bugs.webkit.org/show_bug.cgi?id=130565

Reviewed by Eric Carlson.

Source/WebCore: 

Merged from Blink (patch by fs@opera.com):
https://chromium.googlesource.com/chromium/blink/+/923db263aa65d6efd71c5b55708ad7eea6b23f53
http://crbug.com/73813002
https://chromium.googlesource.com/chromium/blink/+/48375b1d56b2d8850ae93a6c6fb01c69fae82c75
http://crbug.com/77553004
https://chromium.googlesource.com/chromium/blink/+/98d4fc4f5cb716a31d11907120b10538d4ba0f09
http://crbug.com/78833002
https://chromium.googlesource.com/chromium/blink/+/0e53d4f9f140e979b7f32de495551684bc7f4cd2
http://crbug.com/81113003
https://chromium.googlesource.com/chromium/blink/+/730ef1e7f9a1919964f7e74e7ccb2f343e10a148
http://crbug.com/97103002
https://chromium.googlesource.com/chromium/blink/+/c373ee914ffabeaf833939129538251d8f2f4eca
http://crbug.com/98763004
https://chromium.googlesource.com/chromium/blink/+/4ddb4d57948228fa05e49e06bd58a1179c09f212
http://crbug.com/118263002
 
* html/track/VTTCue.cpp:
(WebCore::scanPercentage):
(WebCore::VTTCue::setCueSettings):
* html/track/WebVTTParser.cpp:
(WebCore::WebVTTTreeBuilder::buildFromString):
(WebCore::WebVTTTreeBuilder::constructTreeFromToken):
* html/track/WebVTTToken.h:
(WebCore::WebVTTToken::WebVTTToken):
(WebCore::WebVTTToken::StringToken):
(WebCore::WebVTTToken::StartTag):
(WebCore::WebVTTToken::EndTag):
(WebCore::WebVTTToken::TimestampTag):
(WebCore::WebVTTToken::type):
(WebCore::WebVTTToken::name):
(WebCore::WebVTTToken::characters):
(WebCore::WebVTTToken::classes):
(WebCore::WebVTTToken::annotation):
* html/track/WebVTTTokenizer.cpp:
(WebCore::addNewClass):
(WebCore::emitToken):
(WebCore::advanceAndEmitToken):
(WebCore::WebVTTTokenizer::WebVTTTokenizer):
(WebCore::WebVTTTokenizer::nextToken):
* html/track/WebVTTTokenizer.h:
(WebCore::WebVTTTokenizer::shouldSkipNullCharacters):

LayoutTests: 

Merged from Blink (patch by fs@opera.com):
https://chromium.googlesource.com/chromium/blink/+/923db263aa65d6efd71c5b55708ad7eea6b23f53
http://crbug.com/73813002
https://chromium.googlesource.com/chromium/blink/+/48375b1d56b2d8850ae93a6c6fb01c69fae82c75
http://crbug.com/77553004
https://chromium.googlesource.com/chromium/blink/+/98d4fc4f5cb716a31d11907120b10538d4ba0f09
http://crbug.com/78833002
https://chromium.googlesource.com/chromium/blink/+/0e53d4f9f140e979b7f32de495551684bc7f4cd2
http://crbug.com/81113003
https://chromium.googlesource.com/chromium/blink/+/730ef1e7f9a1919964f7e74e7ccb2f343e10a148
http://crbug.com/97103002
https://chromium.googlesource.com/chromium/blink/+/c373ee914ffabeaf833939129538251d8f2f4eca
http://crbug.com/98763004
https://chromium.googlesource.com/chromium/blink/+/4ddb4d57948228fa05e49e06bd58a1179c09f212
http://crbug.com/118263002

* TestExpectations:
* media/track/captions-webvtt/tc022-entities-wrong.vtt:
* media/track/captions-webvtt/tc022-entities.vtt:
* media/track/track-webvtt-tc022-entities-expected.txt:
* media/track/track-webvtt-tc022-entities.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsmediatrackcaptionswebvtttc022entitieswrongvtt">trunk/LayoutTests/media/track/captions-webvtt/tc022-entities-wrong.vtt</a></li>
<li><a href="#trunkLayoutTestsmediatrackcaptionswebvtttc022entitiesvtt">trunk/LayoutTests/media/track/captions-webvtt/tc022-entities.vtt</a></li>
<li><a href="#trunkLayoutTestsmediatracktrackwebvtttc022entitiesexpectedtxt">trunk/LayoutTests/media/track/track-webvtt-tc022-entities-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediatracktrackwebvtttc022entitieshtml">trunk/LayoutTests/media/track/track-webvtt-tc022-entities.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</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="#trunkSourceWebCorehtmltrackWebVTTTokenh">trunk/Source/WebCore/html/track/WebVTTToken.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTTokenizercpp">trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTTokenizerh">trunk/Source/WebCore/html/track/WebVTTTokenizer.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/LayoutTests/ChangeLog        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2014-03-20  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Merge WebVTT Tokenizer Updates
+        https://bugs.webkit.org/show_bug.cgi?id=130565
+
+        Reviewed by Eric Carlson.
+
+        Merged from Blink (patch by fs@opera.com):
+        https://chromium.googlesource.com/chromium/blink/+/923db263aa65d6efd71c5b55708ad7eea6b23f53
+        http://crbug.com/73813002
+        https://chromium.googlesource.com/chromium/blink/+/48375b1d56b2d8850ae93a6c6fb01c69fae82c75
+        http://crbug.com/77553004
+        https://chromium.googlesource.com/chromium/blink/+/98d4fc4f5cb716a31d11907120b10538d4ba0f09
+        http://crbug.com/78833002
+        https://chromium.googlesource.com/chromium/blink/+/0e53d4f9f140e979b7f32de495551684bc7f4cd2
+        http://crbug.com/81113003
+        https://chromium.googlesource.com/chromium/blink/+/730ef1e7f9a1919964f7e74e7ccb2f343e10a148
+        http://crbug.com/97103002
+        https://chromium.googlesource.com/chromium/blink/+/c373ee914ffabeaf833939129538251d8f2f4eca
+        http://crbug.com/98763004
+        https://chromium.googlesource.com/chromium/blink/+/4ddb4d57948228fa05e49e06bd58a1179c09f212
+        http://crbug.com/118263002
+
+        * TestExpectations:
+        * media/track/captions-webvtt/tc022-entities-wrong.vtt:
+        * media/track/captions-webvtt/tc022-entities.vtt:
+        * media/track/track-webvtt-tc022-entities-expected.txt:
+        * media/track/track-webvtt-tc022-entities.html:
+
</ins><span class="cx"> 2014-03-21  Frédéric Wang  &lt;fred.wang@free.fr&gt;
</span><span class="cx"> 
</span><span class="cx">         Bug 130345 - Refine childShouldCreateRenderer for MathML elements
</span></span></pre></div>
<a id="trunkLayoutTestsmediatrackcaptionswebvtttc022entitieswrongvtt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/track/captions-webvtt/tc022-entities-wrong.vtt (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/track/captions-webvtt/tc022-entities-wrong.vtt        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/LayoutTests/media/track/captions-webvtt/tc022-entities-wrong.vtt        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -1,19 +1,14 @@
</span><span class="cx"> WEBVTT
</span><del>-Invalid use of &amp;, &lt;, and &gt; characters.
</del><ins>+Invalid use of &lt; and &gt; characters.
</ins><span class="cx"> 
</span><span class="cx"> 1
</span><del>-00:00:00.000 --&gt; 00:00:30.500 align:start position:20%
-This cue has an amp &amp; character.
-Ampersand is ignored.
-
-2
</del><span class="cx"> 00:00:31.000 --&gt; 00:01:00.500 align:start position:20%
</span><span class="cx"> This cue has a less than &lt; character.
</span><span class="cx"> It turns everything from there on into an annotation
</span><span class="cx"> for an empty tag and ends only at the next &amp;gt; or &amp;amp; character.
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-3
</del><ins>+2
</ins><span class="cx"> 00:01:01.000 --&gt; 00:02:00.500 align:start position:20%
</span><span class="cx"> This cue has a greater than &gt; character.
</span><span class="cx"> Since it's not related to a &amp;lt; character,
</span></span></pre></div>
<a id="trunkLayoutTestsmediatrackcaptionswebvtttc022entitiesvtt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/track/captions-webvtt/tc022-entities.vtt (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/track/captions-webvtt/tc022-entities.vtt        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/LayoutTests/media/track/captions-webvtt/tc022-entities.vtt        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -3,7 +3,7 @@
</span><span class="cx"> 
</span><span class="cx"> 1
</span><span class="cx"> 00:00:00.000 --&gt; 00:00:30.500 align:start position:20%
</span><del>-This cue has an amp character: &amp;amp;
</del><ins>+This cue has an ampersand character: &amp;amp;
</ins><span class="cx"> 
</span><span class="cx"> 2
</span><span class="cx"> 00:00:31.000 --&gt; 00:01:00.500 align:start position:20%
</span><span class="lines">@@ -14,13 +14,17 @@
</span><span class="cx"> This cue has a greater than character: &amp;gt;
</span><span class="cx"> 
</span><span class="cx"> 4
</span><del>-00:02:01.000 --&gt; 00:03:00.500 align:start position:20%
</del><ins>+00:02:01.000 --&gt; 00:02:30.500 align:start position:20%
</ins><span class="cx"> This cue has a right-to-left mark (RLM): &amp;rlm;
</span><span class="cx"> 
</span><span class="cx"> 5
</span><del>-00:03:01.000 --&gt; 00:04:00.500 align:start position:20%
</del><ins>+00:02:31.000 --&gt; 00:03:00.500 align:start position:20%
</ins><span class="cx"> This cue has a left-to-right mark (LRM): &amp;lrm;
</span><span class="cx"> 
</span><span class="cx"> 6
</span><del>-00:04:01.000 --&gt; 00:05:00.500 align:start position:20%
-This cue has a non-breakable space (NBSP): &amp;nbsp;
</del><span class="cx">\ No newline at end of file
</span><ins>+00:03:01.000 --&gt; 00:03:30.500 align:start position:20%
+This cue has a non-breakable space (NBSP): &amp;nbsp;
+
+7
+00:03:31.000 --&gt; 00:04:00.500
+This &amp; is parsed to the same as &amp;amp;.
</ins></span></pre></div>
<a id="trunkLayoutTestsmediatracktrackwebvtttc022entitiesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/track/track-webvtt-tc022-entities-expected.txt (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/track/track-webvtt-tc022-entities-expected.txt        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/LayoutTests/media/track/track-webvtt-tc022-entities-expected.txt        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -3,18 +3,18 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> *** Testing text track 0
</span><del>-EXPECTED (cues.length == '6') OK
-EXPECTED (cues[0].getCueAsHTML().textContent == 'This cue has an amp character: &amp;') OK
</del><ins>+EXPECTED (cues.length == '7') OK
+EXPECTED (cues[0].getCueAsHTML().textContent == 'This cue has an ampersand character: &amp;') OK
</ins><span class="cx"> EXPECTED (cues[1].getCueAsHTML().textContent == 'This cue has a less than character: &lt;') OK
</span><span class="cx"> EXPECTED (cues[2].getCueAsHTML().textContent == 'This cue has a greater than character: &gt;') OK
</span><span class="cx"> EXPECTED (cues[3].getCueAsHTML().textContent == 'This cue has a right-to-left mark (RLM): ‏') OK
</span><span class="cx"> EXPECTED (cues[4].getCueAsHTML().textContent == 'This cue has a left-to-right mark (LRM): ‎') OK
</span><span class="cx"> EXPECTED (cues[5].getCueAsHTML().textContent == 'This cue has a non-breakable space (NBSP):  ') OK
</span><ins>+EXPECTED (cues[6].getCueAsHTML().textContent == 'This &amp; is parsed to the same as &amp;.') OK
</ins><span class="cx"> 
</span><span class="cx"> *** Testing text track 1
</span><del>-EXPECTED (cues.length == '3') OK
-EXPECTED (cues[0].getCueAsHTML().textContent == 'This cue has an amp character. Ampersand is ignored.') OK
-EXPECTED (cues[1].getCueAsHTML().textContent == 'This cue has a less than ') OK
-EXPECTED (cues[2].getCueAsHTML().textContent == 'This cue has a greater than &gt; character. Since it's not related to a &lt; character, it's just interpreted as text.') OK
</del><ins>+EXPECTED (cues.length == '2') OK
+EXPECTED (cues[0].getCueAsHTML().textContent == 'This cue has a less than ') OK
+EXPECTED (cues[1].getCueAsHTML().textContent == 'This cue has a greater than &gt; character. Since it's not related to a &lt; character, it's just interpreted as text.') OK
</ins><span class="cx"> END OF TEST
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsmediatracktrackwebvtttc022entitieshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/track/track-webvtt-tc022-entities.html (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/track/track-webvtt-tc022-entities.html        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/LayoutTests/media/track/track-webvtt-tc022-entities.html        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -24,18 +24,19 @@
</span><span class="cx">                 findMediaElement();
</span><span class="cx">                 var expected = 
</span><span class="cx">                 {
</span><del>-                    length : 6,
</del><ins>+                    length : 7,
</ins><span class="cx">                     tests:
</span><span class="cx">                     [
</span><span class="cx">                         {
</span><span class="cx">                             property : &quot;getCueAsHTML().textContent&quot;,
</span><span class="cx">                             values : [
</span><del>-                                        &quot;This cue has an amp character: \u0026&quot;,
</del><ins>+                                        &quot;This cue has an ampersand character: \u0026&quot;,
</ins><span class="cx">                                         &quot;This cue has a less than character: \u003C&quot;,
</span><span class="cx">                                         &quot;This cue has a greater than character: \u003E&quot;,
</span><span class="cx">                                         &quot;This cue has a right-to-left mark (RLM): \u200f&quot;,
</span><span class="cx">                                         &quot;This cue has a left-to-right mark (LRM): \u200e&quot;,
</span><del>-                                        &quot;This cue has a non-breakable space (NBSP): \u00a0&quot;
</del><ins>+                                        &quot;This cue has a non-breakable space (NBSP): \u00a0&quot;,
+                                        &quot;This &amp; is parsed to the same as &amp;.&quot;
</ins><span class="cx">                                      ],
</span><span class="cx">                         },
</span><span class="cx">                     ],
</span><span class="lines">@@ -50,13 +51,12 @@
</span><span class="cx">                 findMediaElement();
</span><span class="cx">                 var expected = 
</span><span class="cx">                 {
</span><del>-                    length : 3,
</del><ins>+                    length : 2,
</ins><span class="cx">                     tests:
</span><span class="cx">                     [
</span><span class="cx">                         {
</span><span class="cx">                             property : &quot;getCueAsHTML().textContent&quot;,
</span><del>-                            values : [&quot;This cue has an amp character.\nAmpersand is ignored.&quot;,
-                                      &quot;This cue has a less than &quot;,
</del><ins>+                            values : [&quot;This cue has a less than &quot;,
</ins><span class="cx">                                       &quot;This cue has a greater than &gt; character.\nSince it's not related to a &lt; character,\nit's just interpreted as text.&quot;],
</span><span class="cx">                         },
</span><span class="cx">                     ],
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/Source/WebCore/ChangeLog        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -1,3 +1,52 @@
</span><ins>+2014-03-20  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Merge WebVTT Tokenizer Updates
+        https://bugs.webkit.org/show_bug.cgi?id=130565
+
+        Reviewed by Eric Carlson.
+
+        Merged from Blink (patch by fs@opera.com):
+        https://chromium.googlesource.com/chromium/blink/+/923db263aa65d6efd71c5b55708ad7eea6b23f53
+        http://crbug.com/73813002
+        https://chromium.googlesource.com/chromium/blink/+/48375b1d56b2d8850ae93a6c6fb01c69fae82c75
+        http://crbug.com/77553004
+        https://chromium.googlesource.com/chromium/blink/+/98d4fc4f5cb716a31d11907120b10538d4ba0f09
+        http://crbug.com/78833002
+        https://chromium.googlesource.com/chromium/blink/+/0e53d4f9f140e979b7f32de495551684bc7f4cd2
+        http://crbug.com/81113003
+        https://chromium.googlesource.com/chromium/blink/+/730ef1e7f9a1919964f7e74e7ccb2f343e10a148
+        http://crbug.com/97103002
+        https://chromium.googlesource.com/chromium/blink/+/c373ee914ffabeaf833939129538251d8f2f4eca
+        http://crbug.com/98763004
+        https://chromium.googlesource.com/chromium/blink/+/4ddb4d57948228fa05e49e06bd58a1179c09f212
+        http://crbug.com/118263002

+        * html/track/VTTCue.cpp:
+        (WebCore::scanPercentage):
+        (WebCore::VTTCue::setCueSettings):
+        * html/track/WebVTTParser.cpp:
+        (WebCore::WebVTTTreeBuilder::buildFromString):
+        (WebCore::WebVTTTreeBuilder::constructTreeFromToken):
+        * html/track/WebVTTToken.h:
+        (WebCore::WebVTTToken::WebVTTToken):
+        (WebCore::WebVTTToken::StringToken):
+        (WebCore::WebVTTToken::StartTag):
+        (WebCore::WebVTTToken::EndTag):
+        (WebCore::WebVTTToken::TimestampTag):
+        (WebCore::WebVTTToken::type):
+        (WebCore::WebVTTToken::name):
+        (WebCore::WebVTTToken::characters):
+        (WebCore::WebVTTToken::classes):
+        (WebCore::WebVTTToken::annotation):
+        * html/track/WebVTTTokenizer.cpp:
+        (WebCore::addNewClass):
+        (WebCore::emitToken):
+        (WebCore::advanceAndEmitToken):
+        (WebCore::WebVTTTokenizer::WebVTTTokenizer):
+        (WebCore::WebVTTTokenizer::nextToken):
+        * html/track/WebVTTTokenizer.h:
+        (WebCore::WebVTTTokenizer::shouldSkipNullCharacters):
+
</ins><span class="cx"> 2014-03-21  Frédéric Wang  &lt;fred.wang@free.fr&gt;
</span><span class="cx"> 
</span><span class="cx">         Bug 130345 - Refine childShouldCreateRenderer for MathML elements
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTCuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/VTTCue.cpp (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTCue.cpp        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/Source/WebCore/html/track/VTTCue.cpp        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -861,6 +861,37 @@
</span><span class="cx">     return None;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// Used for 'position' and 'size'.
+static bool scanPercentage(const String&amp; input, unsigned&amp; position, int&amp; number)
+{
+    // 1. If value contains any characters other than U+0025 PERCENT SIGN
+    //    characters (%) and characters in the range U+0030 DIGIT ZERO (0) to
+    //    U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
+    // 2. If value does not contain at least one character in the range U+0030
+    //    DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step
+    //    labeled next setting.
+    if (!WebVTTParser::collectDigitsToInt(input, position, number))
+        return false;
+    if (position &gt;= input.length())
+        return false;
+
+    // 3. If any character in value other than the last character is a U+0025
+    //    PERCENT SIGN character (%), then jump to the step labeled next
+    //    setting.
+    // 4. If the last character in value is not a U+0025 PERCENT SIGN character
+    //    (%), then jump to the step labeled next setting.
+    if (input[position++] != '%')
+        return false;
+    if (position &lt; input.length() &amp;&amp; !WebVTTParser::isValidSettingDelimiter(input[position]))
+        return false;
+
+    // 5. Ignoring the trailing percent sign, interpret value as an integer,
+    //    and let number be that number.
+    // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step
+    //    labeled next setting.
+    return number &gt;= 0 &amp;&amp; number &lt;= 100;
+}
+
</ins><span class="cx"> void VTTCue::setCueSettings(const String&amp; input)
</span><span class="cx"> {
</span><span class="cx">     m_settings = input;
</span><span class="lines">@@ -898,8 +929,7 @@
</span><span class="cx"> 
</span><span class="cx">         // 4. Run the appropriate substeps that apply for the value of name, as follows:
</span><span class="cx">         switch (name) {
</span><del>-        case Vertical:
-            {
</del><ins>+        case Vertical: {
</ins><span class="cx">             // If name is a case-sensitive match for &quot;vertical&quot;
</span><span class="cx">             // 1. If value is a case-sensitive match for the string &quot;rl&quot;, then let cue's text track cue writing direction 
</span><span class="cx">             //    be vertical growing left.
</span><span class="lines">@@ -911,10 +941,9 @@
</span><span class="cx">             //    direction be vertical growing right.
</span><span class="cx">             else if (writingDirection == verticalGrowingRightKeyword())
</span><span class="cx">                 m_writingDirection = VerticalGrowingRight;
</span><del>-            }
</del><span class="cx">             break;
</span><del>-        case Line:
-            {
</del><ins>+        }
+        case Line: {
</ins><span class="cx">             // 1-2 - Collect chars that are either '-', '%', or a digit.
</span><span class="cx">             // 1. If value contains any characters other than U+002D HYPHEN-MINUS characters (-), U+0025 PERCENT SIGN 
</span><span class="cx">             //    characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
</span><span class="lines">@@ -962,70 +991,29 @@
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             m_linePosition = number;
</span><del>-            }
</del><span class="cx">             break;
</span><del>-        case Position:
-            {
-            // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the range 
-            //    U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
-            // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9),
-            //    then jump to the step labeled next setting.
</del><ins>+        }
+        case Position: {
</ins><span class="cx">             int number;
</span><del>-            if (!WebVTTParser::collectDigitsToInt(input, position, number))
</del><ins>+            // Steps 1 - 6.
+            if (!scanPercentage(input, position, number))            
</ins><span class="cx">                 break;
</span><del>-            if (position &gt;= input.length())
-                break;
</del><span class="cx"> 
</span><del>-            // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then jump
-            //    to the step labeled next setting.
-            // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step labeled
-            //    next setting.
-            if (input[position++] != '%')
-                break;
-            if (position &lt; input.length() &amp;&amp; !WebVTTParser::isValidSettingDelimiter(input[position]))
-                break;
-
-            // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
-            // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
-            if (number &lt; 0 || number &gt; 100)
-                break;
-
</del><span class="cx">             // 7. Let cue's text track cue text position be number.
</span><span class="cx">             m_textPosition = number;
</span><del>-            }
</del><span class="cx">             break;
</span><del>-        case Size:
-            {
-            // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the
-            //    range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
-            // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT 
-            //    NINE (9), then jump to the step labeled next setting.
</del><ins>+        }
+        case Size: {
</ins><span class="cx">             int number;
</span><del>-            if (!WebVTTParser::collectDigitsToInt(input, position, number))
</del><ins>+            // Steps 1 - 6.
+            if (!scanPercentage(input, position, number))            
</ins><span class="cx">                 break;
</span><del>-            if (position &gt;= input.length())
-                break;
</del><span class="cx"> 
</span><del>-            // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%),
-            //    then jump to the step labeled next setting.
-            // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step
-            //    labeled next setting.
-            if (input[position++] != '%')
-                break;
-            if (position &lt; input.length() &amp;&amp; !WebVTTParser::isValidSettingDelimiter(input[position]))
-                break;
-
-            // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
-            // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
-            if (number &lt; 0 || number &gt; 100)
-                break;
-
</del><span class="cx">             // 7. Let cue's text track cue size be number.
</span><span class="cx">             m_cueSize = number;
</span><del>-            }
</del><span class="cx">             break;
</span><del>-        case Align:
-            {
</del><ins>+        }
+        case Align: {
</ins><span class="cx">             String cueAlignment = WebVTTParser::collectWord(input, &amp;position);
</span><span class="cx"> 
</span><span class="cx">             // 1. If value is a case-sensitive match for the string &quot;start&quot;, then let cue's text track cue alignment be start alignment.
</span><span class="lines">@@ -1047,8 +1035,8 @@
</span><span class="cx">             // 5. If value is a case-sensitive match for the string &quot;right&quot;, then let cue's text track cue alignment be right alignment.
</span><span class="cx">             else if (cueAlignment == rightKeyword())
</span><span class="cx">                 m_cueAlignment = Right;
</span><del>-            }
</del><span class="cx">             break;
</span><ins>+        }
</ins><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><span class="cx">         case RegionId:
</span><span class="cx">             m_regionId = WebVTTParser::collectWord(input, &amp;position);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTParser.cpp (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTParser.cpp        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/Source/WebCore/html/track/WebVTTParser.cpp        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -404,12 +404,10 @@
</span><span class="cx"> 
</span><span class="cx">     m_currentNode = fragment;
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;WebVTTTokenizer&gt; tokenizer(std::make_unique&lt;WebVTTTokenizer&gt;());
-    m_token.clear();
</del><ins>+    WebVTTTokenizer tokenizer(cueText);
</ins><span class="cx">     m_languageStack.clear();
</span><span class="cx"> 
</span><del>-    SegmentedString content(cueText);
-    while (tokenizer-&gt;nextToken(content, m_token))
</del><ins>+    while (tokenizer.nextToken(m_token))
</ins><span class="cx">         constructTreeFromToken(m_document);
</span><span class="cx">     
</span><span class="cx">     return fragment.release();
</span><span class="lines">@@ -552,8 +550,7 @@
</span><span class="cx"> 
</span><span class="cx">     switch (m_token.type()) {
</span><span class="cx">     case WebVTTTokenTypes::Character: {
</span><del>-        String content = m_token.characters().toString();
-        RefPtr&lt;Text&gt; child = Text::create(document, content);
</del><ins>+        RefPtr&lt;Text&gt; child = Text::create(document, m_token.characters());
</ins><span class="cx">         m_currentNode-&gt;parserAppendChild(child);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -569,12 +566,12 @@
</span><span class="cx"> 
</span><span class="cx">         RefPtr&lt;WebVTTElement&gt; child = WebVTTElement::create(nodeType, document);
</span><span class="cx">         if (!m_token.classes().isEmpty())
</span><del>-            child-&gt;setAttribute(classAttr, m_token.classes().toAtomicString());
</del><ins>+            child-&gt;setAttribute(classAttr, m_token.classes());
</ins><span class="cx"> 
</span><span class="cx">         if (nodeType == WebVTTNodeTypeVoice)
</span><del>-            child-&gt;setAttribute(WebVTTElement::voiceAttributeName(), m_token.annotation().toAtomicString());
</del><ins>+            child-&gt;setAttribute(WebVTTElement::voiceAttributeName(), m_token.annotation());
</ins><span class="cx">         else if (nodeType == WebVTTNodeTypeLanguage) {
</span><del>-            m_languageStack.append(m_token.annotation().toAtomicString());
</del><ins>+            m_languageStack.append(m_token.annotation());
</ins><span class="cx">             child-&gt;setAttribute(WebVTTElement::langAttributeName(), m_languageStack.last());
</span><span class="cx">         }
</span><span class="cx">         if (!m_languageStack.isEmpty())
</span><span class="lines">@@ -611,7 +608,7 @@
</span><span class="cx">     }
</span><span class="cx">     case WebVTTTokenTypes::TimestampTag: {
</span><span class="cx">         unsigned position = 0;
</span><del>-        String charactersString = m_token.characters().toString();
</del><ins>+        String charactersString = m_token.characters();
</ins><span class="cx">         double parsedTimeStamp;
</span><span class="cx">         if (WebVTTParser::collectTimeStamp(charactersString, position, parsedTimeStamp))
</span><span class="cx">             m_currentNode-&gt;parserAppendChild(ProcessingInstruction::create(document, &quot;timestamp&quot;, charactersString));
</span><span class="lines">@@ -620,7 +617,6 @@
</span><span class="cx">     default:
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-    m_token.clear();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebVTTParser::skipWhiteSpace(const String&amp; line, unsigned&amp; position)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTTokenh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTToken.h (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTToken.h        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/Source/WebCore/html/track/WebVTTToken.h        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -34,8 +34,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx"> 
</span><del>-#include &lt;wtf/text/StringBuilder.h&gt;
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class WebVTTTokenTypes {
</span><span class="lines">@@ -46,166 +44,54 @@
</span><span class="cx">         StartTag,
</span><span class="cx">         EndTag,
</span><span class="cx">         TimestampTag,
</span><del>-        EndOfFile,
</del><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class WebVTTToken {
</span><del>-    WTF_MAKE_NONCOPYABLE(WebVTTToken);
-    WTF_MAKE_FAST_ALLOCATED;
</del><span class="cx"> public:
</span><span class="cx">     typedef WebVTTTokenTypes Type;
</span><span class="cx"> 
</span><del>-    WebVTTToken() { clear(); }
</del><ins>+    WebVTTToken()
+        : m_type(Type::Uninitialized) { }
</ins><span class="cx"> 
</span><del>-    void appendToName(UChar character)
</del><ins>+    static WebVTTToken StringToken(const String&amp; characterData)
</ins><span class="cx">     {
</span><del>-        ASSERT(m_type == WebVTTTokenTypes::StartTag || m_type == WebVTTTokenTypes::EndTag);
-        ASSERT(character);
-        m_data.append(character);
</del><ins>+        return WebVTTToken(Type::Character, characterData);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Type::Type type() const { return m_type; }
-
-    StringBuilder&amp; name()
</del><ins>+    static WebVTTToken StartTag(const String&amp; tagName, const AtomicString&amp; classes = emptyAtom, const AtomicString&amp; annotation = emptyAtom)
</ins><span class="cx">     {
</span><del>-        return m_data;
</del><ins>+        WebVTTToken token(Type::StartTag, tagName);
+        token.m_classes = classes;
+        token.m_annotation = annotation;
+        return token;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StringBuilder&amp; characters()
</del><ins>+    static WebVTTToken EndTag(const String&amp; tagName)
</ins><span class="cx">     {
</span><del>-        ASSERT(m_type == Type::Character || m_type == Type::TimestampTag);
-        return m_data;
</del><ins>+        return WebVTTToken(Type::EndTag, tagName);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Starting a character token works slightly differently than starting
-    // other types of tokens because we want to save a per-character branch.
-    void ensureIsCharacterToken()
</del><ins>+    static WebVTTToken TimestampTag(const String&amp; timestampData)
</ins><span class="cx">     {
</span><del>-        ASSERT(m_type == Type::Uninitialized || m_type == Type::Character);
-        m_type = Type::Character;
</del><ins>+        return WebVTTToken(Type::TimestampTag, timestampData);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void appendToCharacter(char character)
-    {
-        ASSERT(m_type == Type::Character);
-        m_data.append(character);
-    }
</del><ins>+    Type::Type type() const { return m_type; }
+    const String&amp; name() const { return m_data; }
+    const String&amp; characters() const { return m_data; }
+    const AtomicString&amp; classes() const { return m_classes; }
+    const AtomicString&amp; annotation() const { return m_annotation; }
</ins><span class="cx"> 
</span><del>-    void appendToCharacter(UChar character)
-    {
-        ASSERT(m_type == Type::Character);
-        m_data.append(character);
-    }
-
-    void appendToCharacter(const StringBuilder&amp; characters)
-    {
-        ASSERT(m_type == Type::Character);
-        m_data.append(characters);
-    }
-
-    void beginEmptyStartTag()
-    {
-        ASSERT(m_type == Type::Uninitialized);
-        m_type = Type::StartTag;
-        m_data.clear();
-    }

-    void beginStartTag(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == Type::Uninitialized);
-        m_type = Type::StartTag;
-        m_data.append(character);
-    }
-
-    void beginEndTag(LChar character)
-    {
-        ASSERT(m_type == Type::Uninitialized);
-        m_type = Type::EndTag;
-        m_data.append(character);
-    }
-
-    void beginTimestampTag(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == Type::Uninitialized);
-        m_type = Type::TimestampTag;
-        m_data.append(character);
-    }
-    
-    void appendToTimestamp(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == Type::TimestampTag);
-        m_data.append(character);
-    }
-
-    void appendToClass(UChar character)
-    {
-        appendToStartType(character);
-    }
-
-    void addNewClass()
-    {
-        ASSERT(m_type == Type::StartTag);
-        if (!m_classes.isEmpty())
-            m_classes.append(' ');
-        m_classes.append(m_currentBuffer);
-        m_currentBuffer.clear();
-    }
-    
-    StringBuilder&amp; classes()
-    {
-        return m_classes;
-    }
-
-    void appendToAnnotation(UChar character)
-    {
-        appendToStartType(character);
-    }
-        
-    void addNewAnnotation()
-    {
-        ASSERT(m_type == Type::StartTag);
-        m_annotation.clear();
-        m_annotation.append(m_currentBuffer);
-        m_currentBuffer.clear();
-    }
-    
-    StringBuilder&amp; annotation()
-    {
-        return m_annotation;
-    }
-
-    void makeEndOfFile()
-    {
-        ASSERT(m_type == Type::Uninitialized);
-        m_type = Type::EndOfFile;
-    }
-    
-    void clear()
-    {
-        m_type = Type::Uninitialized;
-        m_data.clear();
-        m_annotation.clear();
-        m_classes.clear();
-        m_currentBuffer.clear();
-    }
-
</del><span class="cx"> private:
</span><del>-    void appendToStartType(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == Type::StartTag);
-        m_currentBuffer.append(character);
-    }
</del><ins>+    WebVTTToken(Type::Type type, const String&amp; data)
+        : m_type(type)
+        , m_data(data) { }
</ins><span class="cx"> 
</span><span class="cx">     Type::Type m_type;
</span><del>-    StringBuilder m_data;
-    StringBuilder m_annotation;
-    StringBuilder m_classes;
-    StringBuilder m_currentBuffer;
</del><ins>+    String m_data;
+    AtomicString m_annotation;
+    AtomicString m_classes;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTTokenizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -36,59 +36,101 @@
</span><span class="cx"> #include &quot;WebVTTTokenizer.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;MarkupTokenizerInlines.h&quot;
</span><ins>+#include &lt;wtf/text/StringBuilder.h&gt;
</ins><span class="cx"> #include &lt;wtf/unicode/CharacterNames.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-#define WEBVTT_BEGIN_STATE(stateName) BEGIN_STATE(WebVTTTokenizerState, stateName)
-#define WEBVTT_ADVANCE_TO(stateName) ADVANCE_TO(WebVTTTokenizerState, stateName)
</del><ins>+#define WEBVTT_BEGIN_STATE(stateName) case stateName: stateName:
+#define WEBVTT_ADVANCE_TO(stateName)                               \
+    do {                                                           \
+        state = stateName;                                         \
+        ASSERT(!m_input.isEmpty());                                \
+        m_inputStreamPreprocessor.advance(m_input);                \
+        cc = m_inputStreamPreprocessor.nextInputCharacter();       \
+        goto stateName;                                            \
+    } while (false)
</ins><span class="cx"> 
</span><ins>+    
</ins><span class="cx"> template&lt;unsigned charactersCount&gt;
</span><span class="cx"> ALWAYS_INLINE bool equalLiteral(const StringBuilder&amp; s, const char (&amp;characters)[charactersCount])
</span><span class="cx"> {
</span><span class="cx">     return WTF::equal(s, reinterpret_cast&lt;const LChar*&gt;(characters), charactersCount - 1);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebVTTTokenizer::WebVTTTokenizer()
-    : m_inputStreamPreprocessor(this)
</del><ins>+static void addNewClass(StringBuilder&amp; classes, const StringBuilder&amp; newClass)
</ins><span class="cx"> {
</span><del>-    reset();
</del><ins>+    if (!classes.isEmpty())
+        classes.append(' ');
+    classes.append(newClass);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebVTTTokenizer::reset()
</del><ins>+inline bool emitToken(WebVTTToken&amp; resultToken, const WebVTTToken&amp; token)
</ins><span class="cx"> {
</span><del>-    m_state = WebVTTTokenizerState::DataState;
-    m_token = 0;
-    m_buffer.clear();
</del><ins>+    resultToken = token;
+    return true;
</ins><span class="cx"> }
</span><del>-    
-bool WebVTTTokenizer::nextToken(SegmentedString&amp; source, WebVTTToken&amp; token)
</del><ins>+
+inline bool advanceAndEmitToken(SegmentedString&amp; source, WebVTTToken&amp; resultToken, const WebVTTToken&amp; token)
</ins><span class="cx"> {
</span><del>-    // If we have a token in progress, then we're supposed to be called back
-    // with the same token so we can finish it.
-    ASSERT(!m_token || m_token == &amp;token || token.type() == WebVTTTokenTypes::Uninitialized);
-    m_token = &amp;token;
</del><ins>+    source.advanceAndUpdateLineNumber();
+    return emitToken(resultToken, token);
+}
</ins><span class="cx"> 
</span><del>-    if (source.isEmpty() || !m_inputStreamPreprocessor.peek(source))
-        return haveBufferedCharacterToken();
</del><ins>+WebVTTTokenizer::WebVTTTokenizer(const String&amp; input)
+    : m_input(input)
+    , m_inputStreamPreprocessor(this)
+{
+    // Append an EOF marker and close the input &quot;stream&quot;.
+    ASSERT(!m_input.isClosed());
+    m_input.append(SegmentedString(String(&amp;kEndOfFileMarker, 1)));
+    m_input.close();
+}
</ins><span class="cx"> 
</span><ins>+bool WebVTTTokenizer::nextToken(WebVTTToken&amp; token)
+{
+    if (m_input.isEmpty() || !m_inputStreamPreprocessor.peek(m_input))
+        return false;
+
</ins><span class="cx">     UChar cc = m_inputStreamPreprocessor.nextInputCharacter();
</span><ins>+    if (cc == kEndOfFileMarker) {
+        m_inputStreamPreprocessor.advance(m_input);
+        return false;
+    }
</ins><span class="cx"> 
</span><ins>+    StringBuilder buffer;
+    StringBuilder result;
+    StringBuilder classes;
+
+    enum {
+        DataState,
+        EscapeState,
+        TagState,
+        StartTagState,
+        StartTagClassState,
+        StartTagAnnotationState,
+        EndTagState,
+        TimestampTagState,
+    } state = DataState;
+
</ins><span class="cx">     // 4.8.10.13.4 WebVTT cue text tokenizer
</span><del>-    switch (m_state) {
</del><ins>+    switch (state) {
</ins><span class="cx">     WEBVTT_BEGIN_STATE(DataState) {
</span><span class="cx">         if (cc == '&amp;') {
</span><del>-            m_buffer.append(static_cast&lt;LChar&gt;(cc));
</del><ins>+            buffer.append(static_cast&lt;LChar&gt;(cc));
</ins><span class="cx">             WEBVTT_ADVANCE_TO(EscapeState);
</span><span class="cx">         } else if (cc == '&lt;') {
</span><del>-            if (m_token-&gt;type() == WebVTTTokenTypes::Uninitialized || m_token-&gt;characters().isEmpty())
</del><ins>+            if (result.isEmpty())
</ins><span class="cx">                 WEBVTT_ADVANCE_TO(TagState);
</span><del>-            else
-                return emitAndResumeIn(source, WebVTTTokenizerState::TagState);
</del><ins>+            else {
+                // We don't want to advance input or perform a state transition - just return a (new) token.
+                // (On the next call to nextToken we will see '&lt;' again, but take the other branch in this if instead.)
+                return emitToken(token, WebVTTToken::StringToken(result.toString()));
+            }
</ins><span class="cx">         } else if (cc == kEndOfFileMarker)
</span><del>-            return emitEndOfFile(source);
</del><ins>+            return advanceAndEmitToken(m_input, token, WebVTTToken::StringToken(result.toString()));
</ins><span class="cx">         else {
</span><del>-            bufferCharacter(cc);
</del><ins>+            result.append(cc);
</ins><span class="cx">             WEBVTT_ADVANCE_TO(DataState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -96,34 +138,42 @@
</span><span class="cx"> 
</span><span class="cx">     WEBVTT_BEGIN_STATE(EscapeState) {
</span><span class="cx">         if (cc == ';') {
</span><del>-            if (equalLiteral(m_buffer, &quot;&amp;amp&quot;))
-                bufferCharacter('&amp;');
-            else if (equalLiteral(m_buffer, &quot;&amp;lt&quot;))
-                bufferCharacter('&lt;');
-            else if (equalLiteral(m_buffer, &quot;&amp;gt&quot;))
-                bufferCharacter('&gt;');
-            else if (equalLiteral(m_buffer, &quot;&amp;lrm&quot;))
-                bufferCharacter(leftToRightMark);
-            else if (equalLiteral(m_buffer, &quot;&amp;rlm&quot;))
-                bufferCharacter(rightToLeftMark);
-            else if (equalLiteral(m_buffer, &quot;&amp;nbsp&quot;))
-                bufferCharacter(noBreakSpace);
</del><ins>+            if (equalLiteral(buffer, &quot;&amp;amp&quot;))
+                result.append('&amp;');
+            else if (equalLiteral(buffer, &quot;&amp;lt&quot;))
+                result.append('&lt;');
+            else if (equalLiteral(buffer, &quot;&amp;gt&quot;))
+                result.append('&gt;');
+            else if (equalLiteral(buffer, &quot;&amp;lrm&quot;))
+                result.append(leftToRightMark);
+            else if (equalLiteral(buffer, &quot;&amp;rlm&quot;))
+                result.append(rightToLeftMark);
+            else if (equalLiteral(buffer, &quot;&amp;nbsp&quot;))
+                result.append(noBreakSpace);
</ins><span class="cx">             else {
</span><del>-                m_buffer.append(static_cast&lt;LChar&gt;(cc));
-                m_token-&gt;appendToCharacter(m_buffer);
</del><ins>+                buffer.append(static_cast&lt;LChar&gt;(cc));
+                result.append(buffer);
</ins><span class="cx">             }
</span><del>-            m_buffer.clear();
</del><ins>+            buffer.clear();
</ins><span class="cx">             WEBVTT_ADVANCE_TO(DataState);
</span><span class="cx">         } else if (isASCIIAlphanumeric(cc)) {
</span><del>-            m_buffer.append(static_cast&lt;LChar&gt;(cc));
</del><ins>+            buffer.append(static_cast&lt;LChar&gt;(cc));
</ins><span class="cx">             WEBVTT_ADVANCE_TO(EscapeState);
</span><ins>+        } else if (cc == '&lt;') {
+            result.append(buffer);
+            return emitToken(token, WebVTTToken::StringToken(result.toString()));
</ins><span class="cx">         } else if (cc == kEndOfFileMarker) {
</span><del>-            m_token-&gt;appendToCharacter(m_buffer);
-            return emitEndOfFile(source);
</del><ins>+            result.append(buffer);
+            return advanceAndEmitToken(m_input, token, WebVTTToken::StringToken(result.toString()));
</ins><span class="cx">         } else {
</span><del>-            if (!equalLiteral(m_buffer, &quot;&amp;&quot;))
-                m_token-&gt;appendToCharacter(m_buffer);
-            m_buffer.clear();
</del><ins>+            result.append(buffer);
+            buffer.clear();
+
+            if (cc == '&amp;') {
+                buffer.append(static_cast&lt;LChar&gt;(cc));
+                WEBVTT_ADVANCE_TO(EscapeState);
+            }
+            result.append(cc);
</ins><span class="cx">             WEBVTT_ADVANCE_TO(DataState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -131,21 +181,21 @@
</span><span class="cx"> 
</span><span class="cx">     WEBVTT_BEGIN_STATE(TagState) {
</span><span class="cx">         if (isTokenizerWhitespace(cc)) {
</span><del>-            m_token-&gt;beginEmptyStartTag();
</del><ins>+            ASSERT(result.isEmpty());
</ins><span class="cx">             WEBVTT_ADVANCE_TO(StartTagAnnotationState);
</span><span class="cx">         } else if (cc == '.') {
</span><del>-            m_token-&gt;beginEmptyStartTag();
</del><ins>+            ASSERT(result.isEmpty());
</ins><span class="cx">             WEBVTT_ADVANCE_TO(StartTagClassState);
</span><span class="cx">         } else if (cc == '/') {
</span><del>-            WEBVTT_ADVANCE_TO(EndTagOpenState);
</del><ins>+            WEBVTT_ADVANCE_TO(EndTagState);
</ins><span class="cx">         } else if (WTF::isASCIIDigit(cc)) {
</span><del>-            m_token-&gt;beginTimestampTag(cc);
</del><ins>+            result.append(cc);
</ins><span class="cx">             WEBVTT_ADVANCE_TO(TimestampTagState);
</span><span class="cx">         } else if (cc == '&gt;' || cc == kEndOfFileMarker) {
</span><del>-            m_token-&gt;beginEmptyStartTag();
-            return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
</del><ins>+            ASSERT(result.isEmpty());
+            return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString()));
</ins><span class="cx">         } else {
</span><del>-            m_token-&gt;beginStartTag(cc);
</del><ins>+            result.append(cc);
</ins><span class="cx">             WEBVTT_ADVANCE_TO(StartTagState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -157,9 +207,9 @@
</span><span class="cx">         else if (cc == '.')
</span><span class="cx">             WEBVTT_ADVANCE_TO(StartTagClassState);
</span><span class="cx">         else if (cc == '&gt;' || cc == kEndOfFileMarker)
</span><del>-            return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
</del><ins>+            return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString()));
</ins><span class="cx">         else {
</span><del>-            m_token-&gt;appendToName(cc);
</del><ins>+            result.append(cc);
</ins><span class="cx">             WEBVTT_ADVANCE_TO(StartTagState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -167,16 +217,19 @@
</span><span class="cx"> 
</span><span class="cx">     WEBVTT_BEGIN_STATE(StartTagClassState) {
</span><span class="cx">         if (isTokenizerWhitespace(cc)) {
</span><del>-            m_token-&gt;addNewClass();
</del><ins>+            addNewClass(classes, buffer);
+            buffer.clear();
</ins><span class="cx">             WEBVTT_ADVANCE_TO(StartTagAnnotationState);
</span><span class="cx">         } else if (cc == '.') {
</span><del>-            m_token-&gt;addNewClass();
</del><ins>+            addNewClass(classes, buffer);
+            buffer.clear();
</ins><span class="cx">             WEBVTT_ADVANCE_TO(StartTagClassState);
</span><span class="cx">         } else if (cc == '&gt;' || cc == kEndOfFileMarker) {
</span><del>-            m_token-&gt;addNewClass();
-            return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
</del><ins>+            addNewClass(classes, buffer);
+            buffer.clear();
+            return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString(), classes.toAtomicString()));
</ins><span class="cx">         } else {
</span><del>-            m_token-&gt;appendToClass(cc);
</del><ins>+            buffer.append(cc);
</ins><span class="cx">             WEBVTT_ADVANCE_TO(StartTagClassState);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -185,36 +238,25 @@
</span><span class="cx"> 
</span><span class="cx">     WEBVTT_BEGIN_STATE(StartTagAnnotationState) {
</span><span class="cx">         if (cc == '&gt;' || cc == kEndOfFileMarker) {
</span><del>-            m_token-&gt;addNewAnnotation();
-            return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
</del><ins>+            return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString(), classes.toAtomicString(), buffer.toAtomicString()));
</ins><span class="cx">         }
</span><del>-        m_token-&gt;appendToAnnotation(cc);
</del><ins>+        buffer.append(cc);
</ins><span class="cx">         WEBVTT_ADVANCE_TO(StartTagAnnotationState);
</span><span class="cx">     }
</span><span class="cx">     END_STATE()
</span><span class="cx">     
</span><del>-    WEBVTT_BEGIN_STATE(EndTagOpenState) {
-        if (cc == '&gt;' || cc == kEndOfFileMarker) {
-            m_token-&gt;beginEndTag('\0');
-            return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
-        }
-        m_token-&gt;beginEndTag(cc);
-        WEBVTT_ADVANCE_TO(EndTagState);
-    }
-    END_STATE()
-
</del><span class="cx">     WEBVTT_BEGIN_STATE(EndTagState) {
</span><span class="cx">         if (cc == '&gt;' || cc == kEndOfFileMarker)
</span><del>-            return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
-        m_token-&gt;appendToName(cc);
</del><ins>+            return advanceAndEmitToken(m_input, token, WebVTTToken::EndTag(result.toString()));
+        result.append(cc);
</ins><span class="cx">         WEBVTT_ADVANCE_TO(EndTagState);
</span><span class="cx">     }
</span><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     WEBVTT_BEGIN_STATE(TimestampTagState) {
</span><span class="cx">         if (cc == '&gt;' || cc == kEndOfFileMarker)
</span><del>-            return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
-        m_token-&gt;appendToTimestamp(cc);
</del><ins>+            return advanceAndEmitToken(m_input, token, WebVTTToken::TimestampTag(result.toString()));
+        result.append(cc);
</ins><span class="cx">         WEBVTT_ADVANCE_TO(TimestampTagState);
</span><span class="cx">     }
</span><span class="cx">     END_STATE()
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTTokenizerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTTokenizer.h (166065 => 166066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTTokenizer.h        2014-03-21 16:19:36 UTC (rev 166065)
+++ trunk/Source/WebCore/html/track/WebVTTTokenizer.h        2014-03-21 16:31:22 UTC (rev 166066)
</span><span class="lines">@@ -36,77 +36,21 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;InputStreamPreprocessor.h&quot;
</span><span class="cx"> #include &quot;WebVTTToken.h&quot;
</span><del>-#include &lt;wtf/text/StringBuilder.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class WebVTTTokenizerState {
-public:
-    enum State {
-        DataState,
-        EscapeState,
-        TagState,
-        StartTagState,
-        StartTagClassState,
-        StartTagAnnotationState,
-        EndTagState,
-        EndTagOpenState,
-        TimestampTagState,
-    };
-};
-
</del><span class="cx"> class WebVTTTokenizer {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(WebVTTTokenizer);
</span><del>-    WTF_MAKE_FAST_ALLOCATED;
</del><span class="cx"> public:
</span><del>-    WebVTTTokenizer();
</del><ins>+    explicit WebVTTTokenizer(const String&amp;);
</ins><span class="cx"> 
</span><del>-    typedef WebVTTTokenizerState State;
</del><ins>+    bool nextToken(WebVTTToken&amp;);
</ins><span class="cx"> 
</span><del>-    void reset();
-    
-    bool nextToken(SegmentedString&amp;, WebVTTToken&amp;);
</del><ins>+    inline bool shouldSkipNullCharacters() const { return true; }
</ins><span class="cx"> 
</span><del>-    inline bool haveBufferedCharacterToken()
-    {
-        return m_token-&gt;type() == WebVTTToken::Type::Character;
-    }
-
-    inline void bufferCharacter(UChar character)
-    {
-        ASSERT(character != kEndOfFileMarker);
-        m_token-&gt;ensureIsCharacterToken();
-        m_token-&gt;appendToCharacter(character);
-    }
-
-    inline bool emitAndResumeIn(SegmentedString&amp; source, State::State state)
-    {
-        m_state = state;
-        source.advanceAndUpdateLineNumber();
-        return true;
-    }
-
-    inline bool emitEndOfFile(SegmentedString&amp; source)
-    {
-        if (haveBufferedCharacterToken())
-            return true;
-        m_state = State::DataState;
-        source.advanceAndUpdateLineNumber();
-        m_token-&gt;clear();
-        m_token-&gt;makeEndOfFile();
-        return true;
-    }
-
-    bool shouldSkipNullCharacters() const { return true; }
-
</del><span class="cx"> private:
</span><del>-    // m_token is owned by the caller. If nextToken is not on the stack,
-    // this member might be pointing to unallocated memory.
-    WebVTTToken* m_token;
-    WebVTTTokenizerState::State m_state;
</del><ins>+    SegmentedString m_input;
</ins><span class="cx"> 
</span><del>-    StringBuilder m_buffer;
-
</del><span class="cx">     // ://www.whatwg.org/specs/web-apps/current-work/#preprocessing-the-input-stream
</span><span class="cx">     InputStreamPreprocessor&lt;WebVTTTokenizer&gt; m_inputStreamPreprocessor;
</span><span class="cx"> };
</span></span></pre>
</div>
</div>

</body>
</html>