<!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>[177952] 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/177952">177952</a></dd>
<dt>Author</dt> <dd>darin@apple.com</dd>
<dt>Date</dt> <dd>2015-01-06 00:06:09 -0800 (Tue, 06 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Modernize and streamline HTMLToken and AtomicHTMLToken
https://bugs.webkit.org/show_bug.cgi?id=140046

Reviewed by Andreas Kling.

Source/WebCore:

* editing/MarkupAccumulator.cpp:
(WebCore::MarkupAccumulator::appendDocumentType): Added code to properly
handle empty strings for systemId and publicId, rather than treating them
the same as missing systemId and publicId.

* html/parser/AtomicHTMLToken.h: Removed unneeded includes.
Moved function bodies out of the class so it's easier to see the contents of
the class. Renamed the isAll8BitData function to charactersIsAll8BitData
to make it clear that it is correct only for AtomicHTMLToken::characters.
Made more things private. Moved the findAttributeInVector function here
and renamed it to just findAttribute. Use unsigned instead of int and
size_t as appropriate. Changed the constructor that makes a fake one of
these to move the Vector of attributes in rather than copying it.

* html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::insertDoctype): Moved the code to create
a string from here into AtomicHTMLToken.
(WebCore::HTMLConstructionSite::createElementFromSavedToken): Updated
to construct the Vector explicitly because all other call sites pass
ownership of the Vector in to the AtomicHTMLToken.

* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::pumpTokenizer): Check for an uninitialized
token without using a special function just for this purpose.
(WebCore::HTMLDocumentParser::constructTreeFromHTMLToken): Ditto.

* html/parser/HTMLParserIdioms.h: Removed the version of
stripLeadingAndTrailingHTMLSpaces that takes a character vector. Instead
the caller can make a string. Later we might want this to work with
a StringView, or a StringView/String combination.

* html/parser/HTMLPreloadScanner.cpp:
(WebCore::TokenPreloadScanner::scan): Updated to not use HTMLToken::data.
(WebCore::TokenPreloadScanner::updatePredictedBaseURL): Updated to not use
HTMLToken::getAttributeItem and to not require a special overload of the
stripLeadingAndTrailingHTMLSpaces function.

* html/parser/HTMLSourceTracker.cpp:
(WebCore::HTMLSourceTracker::end): Updated to call the token-ending
function by its new name, setEndOffset.
(WebCore::HTMLSourceTracker::sourceForToken): Updated since we no
longer have a startIndex function that already returns 0. Instead just
call length. Also use unsigned instead of size_t.

* html/parser/HTMLStackItem.h:
(WebCore::HTMLStackItem::getAttributeItem): Updated for name change.

* html/parser/HTMLToken.h: Removed the many unneeded includes,
including the self-include! Turned DoctypeData into a normal struct
without m_ prefixes on its member names. Turned HTMLToken::Attribute and
HTMLToken::Attribute::Range into normal structs. Moved function
bodies out of the class so it's easier to see the contents of
the class. Removed a few now-unneeded functions.

* html/parser/HTMLTokenizer.cpp: Removed the AtomicHTMLToken function
members that used to be here. None are needed any more; they are now all
just inlined at the call site. If we need any non-inline functions, then
we sould probably create an AtomicHTMLToken.cpp file instead.
(WebCore::HTMLTokenizer::processEntity): Use the new bufferASCIICharacter
function in all the cases where we know a character is ASCII to cut down
on the amount of 8-bit checking we have to do.
(WebCore::HTMLTokenizer::nextToken): Ditto.

* html/parser/HTMLTokenizer.h: Added a new bufferASCIICharacter function
so we don't have to do 8-bit checks on so many characters as we buffer
them. Also removed the call to ensureIsCharacterToken, since appendToCharacter
now does that. Also deleted overloads of bufferCharacter so we remember to
call bufferASCIICharacter instead.

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::ExternalCharacterTokenBuffer):
Updated for change in AtomicHTMLToken function names.
(WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
(WebCore::hasAttribute): Added.
(WebCore::HTMLTreeBuilder::processTokenInForeignContent): Use hasAtttribute.

* html/parser/TextDocumentParser.cpp:
(WebCore::TextDocumentParser::insertFakePreElement): Move the attributes in
rather than copying them in.

* html/parser/XSSAuditor.cpp:
(WebCore::XSSAuditor::filterCharacterToken): Use clear so we don't have to
have an eraseCharacters function. Use a local variable to avoid overloading
ambiguity.
(WebCore::XSSAuditor::decodedSnippetForAttribute): Fixed a typo and the types
of some local variables.

LayoutTests:

* resources/dump-as-markup.js:
(Markup._get): Add code to handle null systemId and publicId,
dumping them as empty strings for now.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsresourcesdumpasmarkupjs">trunk/LayoutTests/resources/dump-as-markup.js</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreeditingMarkupAccumulatorcpp">trunk/Source/WebCore/editing/MarkupAccumulator.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserAtomicHTMLTokenh">trunk/Source/WebCore/html/parser/AtomicHTMLToken.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLConstructionSitecpp">trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLDocumentParsercpp">trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLParserIdiomsh">trunk/Source/WebCore/html/parser/HTMLParserIdioms.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLPreloadScannercpp">trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLPreloadScannerh">trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLSourceTrackercpp">trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLStackItemh">trunk/Source/WebCore/html/parser/HTMLStackItem.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTokenh">trunk/Source/WebCore/html/parser/HTMLToken.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTokenizercpp">trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTokenizerh">trunk/Source/WebCore/html/parser/HTMLTokenizer.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTreeBuildercpp">trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserTextDocumentParsercpp">trunk/Source/WebCore/html/parser/TextDocumentParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserXSSAuditorcpp">trunk/Source/WebCore/html/parser/XSSAuditor.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/LayoutTests/ChangeLog        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -1,5 +1,16 @@
</span><span class="cx"> 2015-01-05  Darin Adler  &lt;darin@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Modernize and streamline HTMLToken and AtomicHTMLToken
+        https://bugs.webkit.org/show_bug.cgi?id=140046
+
+        Reviewed by Andreas Kling.
+
+        * resources/dump-as-markup.js:
+        (Markup._get): Add code to handle null systemId and publicId,
+        dumping them as empty strings for now.
+
+2015-01-05  Darin Adler  &lt;darin@apple.com&gt;
+
</ins><span class="cx">         * TestExpectations: Re-enabled the test I broke yesterday,
</span><span class="cx">         editing/pasteboard/drag-and-drop-objectimage-contenteditable.html,
</span><span class="cx">         now that it's fixed.
</span></span></pre></div>
<a id="trunkLayoutTestsresourcesdumpasmarkupjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/resources/dump-as-markup.js (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/resources/dump-as-markup.js        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/LayoutTests/resources/dump-as-markup.js        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -149,9 +149,13 @@
</span><span class="cx">     switch (node.nodeType) {
</span><span class="cx">     case Node.DOCUMENT_TYPE_NODE:
</span><span class="cx">         str += '&lt;!DOCTYPE ' + node.nodeName;
</span><ins>+        // FIXME: The actual MarkupAccumulator in WebKit handles these quite differently.
+        // Should we change to match that format? Would probably need to change test results,
+        // but it could help us distinguish empty strings from missing properties and
+        // would include internalSubset, which this omits.
</ins><span class="cx">         if (node.publicId || node.systemId) {
</span><del>-            str += ' &quot;' + node.publicId + '&quot;';
-            str += ' &quot;' + node.systemId + '&quot;';
</del><ins>+            str += ' &quot;' + (node.publicId || '') + '&quot;';
+            str += ' &quot;' + (node.systemId || '') + '&quot;';
</ins><span class="cx">         }
</span><span class="cx">         str += '&gt;';
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/ChangeLog        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -1,5 +1,101 @@
</span><span class="cx"> 2015-01-05  Darin Adler  &lt;darin@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Modernize and streamline HTMLToken and AtomicHTMLToken
+        https://bugs.webkit.org/show_bug.cgi?id=140046
+
+        Reviewed by Andreas Kling.
+
+        * editing/MarkupAccumulator.cpp:
+        (WebCore::MarkupAccumulator::appendDocumentType): Added code to properly
+        handle empty strings for systemId and publicId, rather than treating them
+        the same as missing systemId and publicId.
+
+        * html/parser/AtomicHTMLToken.h: Removed unneeded includes.
+        Moved function bodies out of the class so it's easier to see the contents of
+        the class. Renamed the isAll8BitData function to charactersIsAll8BitData
+        to make it clear that it is correct only for AtomicHTMLToken::characters.
+        Made more things private. Moved the findAttributeInVector function here
+        and renamed it to just findAttribute. Use unsigned instead of int and
+        size_t as appropriate. Changed the constructor that makes a fake one of
+        these to move the Vector of attributes in rather than copying it.
+
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::HTMLConstructionSite::insertDoctype): Moved the code to create
+        a string from here into AtomicHTMLToken.
+        (WebCore::HTMLConstructionSite::createElementFromSavedToken): Updated
+        to construct the Vector explicitly because all other call sites pass
+        ownership of the Vector in to the AtomicHTMLToken.
+
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::pumpTokenizer): Check for an uninitialized
+        token without using a special function just for this purpose.
+        (WebCore::HTMLDocumentParser::constructTreeFromHTMLToken): Ditto.
+
+        * html/parser/HTMLParserIdioms.h: Removed the version of
+        stripLeadingAndTrailingHTMLSpaces that takes a character vector. Instead
+        the caller can make a string. Later we might want this to work with
+        a StringView, or a StringView/String combination.
+
+        * html/parser/HTMLPreloadScanner.cpp:
+        (WebCore::TokenPreloadScanner::scan): Updated to not use HTMLToken::data.
+        (WebCore::TokenPreloadScanner::updatePredictedBaseURL): Updated to not use
+        HTMLToken::getAttributeItem and to not require a special overload of the
+        stripLeadingAndTrailingHTMLSpaces function.
+
+        * html/parser/HTMLSourceTracker.cpp:
+        (WebCore::HTMLSourceTracker::end): Updated to call the token-ending
+        function by its new name, setEndOffset.
+        (WebCore::HTMLSourceTracker::sourceForToken): Updated since we no
+        longer have a startIndex function that already returns 0. Instead just
+        call length. Also use unsigned instead of size_t.
+
+        * html/parser/HTMLStackItem.h:
+        (WebCore::HTMLStackItem::getAttributeItem): Updated for name change.
+
+        * html/parser/HTMLToken.h: Removed the many unneeded includes,
+        including the self-include! Turned DoctypeData into a normal struct
+        without m_ prefixes on its member names. Turned HTMLToken::Attribute and
+        HTMLToken::Attribute::Range into normal structs. Moved function
+        bodies out of the class so it's easier to see the contents of
+        the class. Removed a few now-unneeded functions.
+
+        * html/parser/HTMLTokenizer.cpp: Removed the AtomicHTMLToken function
+        members that used to be here. None are needed any more; they are now all
+        just inlined at the call site. If we need any non-inline functions, then
+        we sould probably create an AtomicHTMLToken.cpp file instead.
+        (WebCore::HTMLTokenizer::processEntity): Use the new bufferASCIICharacter
+        function in all the cases where we know a character is ASCII to cut down
+        on the amount of 8-bit checking we have to do.
+        (WebCore::HTMLTokenizer::nextToken): Ditto.
+
+        * html/parser/HTMLTokenizer.h: Added a new bufferASCIICharacter function
+        so we don't have to do 8-bit checks on so many characters as we buffer
+        them. Also removed the call to ensureIsCharacterToken, since appendToCharacter
+        now does that. Also deleted overloads of bufferCharacter so we remember to
+        call bufferASCIICharacter instead.
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::ExternalCharacterTokenBuffer):
+        Updated for change in AtomicHTMLToken function names.
+        (WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
+        (WebCore::hasAttribute): Added.
+        (WebCore::HTMLTreeBuilder::processTokenInForeignContent): Use hasAtttribute.
+
+        * html/parser/TextDocumentParser.cpp:
+        (WebCore::TextDocumentParser::insertFakePreElement): Move the attributes in
+        rather than copying them in.
+
+        * html/parser/XSSAuditor.cpp:
+        (WebCore::XSSAuditor::filterCharacterToken): Use clear so we don't have to
+        have an eraseCharacters function. Use a local variable to avoid overloading
+        ambiguity.
+        (WebCore::XSSAuditor::decodedSnippetForAttribute): Fixed a typo and the types
+        of some local variables.
+
+2015-01-05  Darin Adler  &lt;darin@apple.com&gt;
+
</ins><span class="cx">         Revert mistake in yesterday's HTMLDocumentParser refactor.
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=140041
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingMarkupAccumulatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/MarkupAccumulator.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/MarkupAccumulator.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/editing/MarkupAccumulator.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -392,22 +392,22 @@
</span><span class="cx"> 
</span><span class="cx">     result.appendLiteral(&quot;&lt;!DOCTYPE &quot;);
</span><span class="cx">     result.append(documentType.name());
</span><del>-    if (!documentType.publicId().isEmpty()) {
</del><ins>+    if (!documentType.publicId().isNull()) {
</ins><span class="cx">         result.appendLiteral(&quot; PUBLIC \&quot;&quot;);
</span><span class="cx">         result.append(documentType.publicId());
</span><span class="cx">         result.append('&quot;');
</span><del>-        if (!documentType.systemId().isEmpty()) {
</del><ins>+        if (!documentType.systemId().isNull()) {
</ins><span class="cx">             result.append(' ');
</span><span class="cx">             result.append('&quot;');
</span><span class="cx">             result.append(documentType.systemId());
</span><span class="cx">             result.append('&quot;');
</span><span class="cx">         }
</span><del>-    } else if (!documentType.systemId().isEmpty()) {
</del><ins>+    } else if (!documentType.systemId().isNull()) {
</ins><span class="cx">         result.appendLiteral(&quot; SYSTEM \&quot;&quot;);
</span><span class="cx">         result.append(documentType.systemId());
</span><span class="cx">         result.append('&quot;');
</span><span class="cx">     }
</span><del>-    if (!documentType.internalSubset().isEmpty()) {
</del><ins>+    if (!documentType.internalSubset().isNull()) {
</ins><span class="cx">         result.append(' ');
</span><span class="cx">         result.append('[');
</span><span class="cx">         result.append(documentType.internalSubset());
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserAtomicHTMLTokenh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/AtomicHTMLToken.h (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/AtomicHTMLToken.h        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/AtomicHTMLToken.h        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2013 Google, Inc. All Rights Reserved.
</span><ins>+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -26,218 +27,226 @@
</span><span class="cx"> #ifndef AtomicHTMLToken_h
</span><span class="cx"> #define AtomicHTMLToken_h
</span><span class="cx"> 
</span><del>-#include &quot;Attribute.h&quot;
</del><span class="cx"> #include &quot;HTMLToken.h&quot;
</span><del>-#include &lt;wtf/RefCounted.h&gt;
-#include &lt;wtf/RefPtr.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class AtomicHTMLToken {
</span><del>-    WTF_MAKE_NONCOPYABLE(AtomicHTMLToken);
</del><span class="cx"> public:
</span><ins>+    explicit AtomicHTMLToken(HTMLToken&amp;);
+    AtomicHTMLToken(HTMLToken::Type, const AtomicString&amp; name, Vector&lt;Attribute&gt;&amp;&amp; = Vector&lt;Attribute&gt;()); // Only StartTag or EndTag.
</ins><span class="cx"> 
</span><del>-    bool forceQuirks() const
-    {
-        ASSERT(m_type == HTMLToken::DOCTYPE);
-        return m_doctypeData-&gt;m_forceQuirks;
-    }
</del><ins>+    HTMLToken::Type type() const;
</ins><span class="cx"> 
</span><del>-    HTMLToken::Type type() const { return m_type; }
</del><ins>+    // StartTag, EndTag, DOCTYPE.
</ins><span class="cx"> 
</span><del>-    const AtomicString&amp; name() const
-    {
-        ASSERT(usesName());
-        return m_name;
-    }
</del><ins>+    void setName(const AtomicString&amp;);
</ins><span class="cx"> 
</span><del>-    void setName(const AtomicString&amp; name)
-    {
-        ASSERT(usesName());
-        m_name = name;
-    }
</del><ins>+    const AtomicString&amp; name() const;
</ins><span class="cx"> 
</span><del>-    bool selfClosing() const
-    {
-        ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
-        return m_selfClosing;
-    }
</del><ins>+    // DOCTYPE.
</ins><span class="cx"> 
</span><del>-    Attribute* getAttributeItem(const QualifiedName&amp; attributeName)
-    {
-        ASSERT(usesAttributes());
-        return findAttributeInVector(m_attributes, attributeName);
-    }
</del><ins>+    bool forceQuirks() const;
+    String publicIdentifier() const;
+    String systemIdentifier() const;
</ins><span class="cx"> 
</span><del>-    Vector&lt;Attribute&gt;&amp; attributes()
-    {
-        ASSERT(usesAttributes());
-        return m_attributes;
-    }
</del><ins>+    // StartTag, EndTag.
</ins><span class="cx"> 
</span><del>-    const Vector&lt;Attribute&gt;&amp; attributes() const
-    {
-        ASSERT(usesAttributes());
-        return m_attributes;
-    }
</del><ins>+    Vector&lt;Attribute&gt;&amp; attributes();
</ins><span class="cx"> 
</span><del>-    const UChar* characters() const
-    {
-        ASSERT(m_type == HTMLToken::Character);
-        return m_externalCharacters;
-    }
</del><ins>+    bool selfClosing() const;
+    const Vector&lt;Attribute&gt;&amp; attributes() const;
</ins><span class="cx"> 
</span><del>-    size_t charactersLength() const
-    {
-        ASSERT(m_type == HTMLToken::Character);
-        return m_externalCharactersLength;
-    }
</del><ins>+    // Characters
</ins><span class="cx"> 
</span><del>-    bool isAll8BitData() const
-    {
-        return m_isAll8BitData;
-    }
</del><ins>+    const UChar* characters() const;
+    unsigned charactersLength() const;
+    bool charactersIsAll8BitData() const;
</ins><span class="cx"> 
</span><del>-    const String&amp; comment() const
-    {
-        ASSERT(m_type == HTMLToken::Comment);
-        return m_data;
-    }
</del><ins>+    // Comment
</ins><span class="cx"> 
</span><del>-    // FIXME: Distinguish between a missing public identifier and an empty one.
-    Vector&lt;UChar&gt;&amp; publicIdentifier() const
-    {
-        ASSERT(m_type == HTMLToken::DOCTYPE);
-        return m_doctypeData-&gt;m_publicIdentifier;
-    }
</del><ins>+    const String&amp; comment() const;
</ins><span class="cx"> 
</span><del>-    // FIXME: Distinguish between a missing system identifier and an empty one.
-    Vector&lt;UChar&gt;&amp; systemIdentifier() const
-    {
-        ASSERT(m_type == HTMLToken::DOCTYPE);
-        return m_doctypeData-&gt;m_systemIdentifier;
-    }
</del><ins>+private:
+    HTMLToken::Type m_type;
</ins><span class="cx"> 
</span><del>-    explicit AtomicHTMLToken(HTMLToken&amp; token)
-        : m_type(token.type())
-    {
-        switch (m_type) {
-        case HTMLToken::Uninitialized:
-            ASSERT_NOT_REACHED();
-            break;
-        case HTMLToken::DOCTYPE:
-            m_name = AtomicString(token.name());
-            m_doctypeData = token.releaseDoctypeData();
-            break;
-        case HTMLToken::EndOfFile:
-            break;
-        case HTMLToken::StartTag:
-        case HTMLToken::EndTag: {
-            m_selfClosing = token.selfClosing();
-            m_name = AtomicString(token.name());
-            initializeAttributes(token.attributes());
-            break;
-        }
-        case HTMLToken::Comment:
-            if (token.isAll8BitData())
-                m_data = String::make8BitFrom16BitSource(token.comment());
-            else
-                m_data = String(token.comment());
-            break;
-        case HTMLToken::Character:
-            m_externalCharacters = token.characters().data();
-            m_externalCharactersLength = token.characters().size();
-            m_isAll8BitData = token.isAll8BitData();
-            break;
-        }
-    }
</del><ins>+    void initializeAttributes(const HTMLToken::AttributeList&amp; attributes);
</ins><span class="cx"> 
</span><del>-    explicit AtomicHTMLToken(HTMLToken::Type type)
-        : m_type(type)
-        , m_externalCharacters(0)
-        , m_externalCharactersLength(0)
-        , m_isAll8BitData(false)
-        , m_selfClosing(false)
-    {
-    }
</del><ins>+    AtomicString m_name; // StartTag, EndTag, DOCTYPE.
</ins><span class="cx"> 
</span><del>-    AtomicHTMLToken(HTMLToken::Type type, const AtomicString&amp; name, const Vector&lt;Attribute&gt;&amp; attributes = Vector&lt;Attribute&gt;())
-        : m_type(type)
-        , m_name(name)
-        , m_externalCharacters(0)
-        , m_externalCharactersLength(0)
-        , m_isAll8BitData(false)
-        , m_selfClosing(false)
-        , m_attributes(attributes)
-    {
-        ASSERT(usesName());
-    }
</del><ins>+    String m_data; // Comment
</ins><span class="cx"> 
</span><del>-private:
-    HTMLToken::Type m_type;
</del><ins>+    // We don't want to copy the the characters out of the HTMLToken, so we keep a pointer to its buffer instead.
+    // This buffer is owned by the HTMLToken and causes a lifetime dependence between these objects.
+    // FIXME: Add a mechanism for &quot;internalizing&quot; the characters when the HTMLToken is destroyed.
+    const UChar* m_externalCharacters; // Character
+    unsigned m_externalCharactersLength; // Character
+    bool m_externalCharactersIsAll8BitData; // Character
</ins><span class="cx"> 
</span><del>-    void initializeAttributes(const HTMLToken::AttributeList&amp; attributes);
-    QualifiedName nameForAttribute(const HTMLToken::Attribute&amp;) const;
</del><ins>+    std::unique_ptr&lt;DoctypeData&gt; m_doctypeData; // DOCTYPE.
</ins><span class="cx"> 
</span><del>-    bool usesName() const;
</del><ins>+    bool m_selfClosing; // StartTag, EndTag.
+    Vector&lt;Attribute&gt; m_attributes; // StartTag, EndTag.
+};
</ins><span class="cx"> 
</span><del>-    bool usesAttributes() const;
</del><ins>+Attribute* findAttribute(Vector&lt;Attribute&gt;&amp;, const QualifiedName&amp;);
</ins><span class="cx"> 
</span><del>-    // &quot;name&quot; for DOCTYPE, StartTag, and EndTag
-    AtomicString m_name;
</del><ins>+inline HTMLToken::Type AtomicHTMLToken::type() const
+{
+    return m_type;
+}
</ins><span class="cx"> 
</span><del>-    // &quot;data&quot; for Comment
-    String m_data;
</del><ins>+inline const AtomicString&amp; AtomicHTMLToken::name() const
+{
+    ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE);
+    return m_name;
+}
</ins><span class="cx"> 
</span><del>-    // &quot;characters&quot; for Character
-    //
-    // We don't want to copy the the characters out of the Token, so we
-    // keep a pointer to its buffer instead. This buffer is owned by the
-    // Token and causes a lifetime dependence between these objects.
-    //
-    // FIXME: Add a mechanism for &quot;internalizing&quot; the characters when the
-    //        HTMLToken is destructed.
-    const UChar* m_externalCharacters;
-    size_t m_externalCharactersLength;
-    bool m_isAll8BitData;
</del><ins>+inline void AtomicHTMLToken::setName(const AtomicString&amp; name)
+{
+    ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE);
+    m_name = name;
+}
</ins><span class="cx"> 
</span><del>-    // For DOCTYPE
-    std::unique_ptr&lt;DoctypeData&gt; m_doctypeData;
</del><ins>+inline bool AtomicHTMLToken::selfClosing() const
+{
+    ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
+    return m_selfClosing;
+}
</ins><span class="cx"> 
</span><del>-    // For StartTag and EndTag
-    bool m_selfClosing;
</del><ins>+inline Vector&lt;Attribute&gt;&amp; AtomicHTMLToken::attributes()
+{
+    ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
+    return m_attributes;
+}
</ins><span class="cx"> 
</span><del>-    Vector&lt;Attribute&gt; m_attributes;
-};
</del><ins>+inline const Vector&lt;Attribute&gt;&amp; AtomicHTMLToken::attributes() const
+{
+    ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
+    return m_attributes;
+}
</ins><span class="cx"> 
</span><ins>+inline const UChar* AtomicHTMLToken::characters() const
+{
+    ASSERT(m_type == HTMLToken::Character);
+    return m_externalCharacters;
+}
+
+inline unsigned AtomicHTMLToken::charactersLength() const
+{
+    ASSERT(m_type == HTMLToken::Character);
+    return m_externalCharactersLength;
+}
+
+inline bool AtomicHTMLToken::charactersIsAll8BitData() const
+{
+    return m_externalCharactersIsAll8BitData;
+}
+
+inline const String&amp; AtomicHTMLToken::comment() const
+{
+    ASSERT(m_type == HTMLToken::Comment);
+    return m_data;
+}
+
+inline bool AtomicHTMLToken::forceQuirks() const
+{
+    ASSERT(m_type == HTMLToken::DOCTYPE);
+    return m_doctypeData-&gt;forceQuirks;
+}
+
+inline String AtomicHTMLToken::publicIdentifier() const
+{
+    ASSERT(m_type == HTMLToken::DOCTYPE);
+    if (!m_doctypeData-&gt;hasPublicIdentifier)
+        return String();
+    return StringImpl::create8BitIfPossible(m_doctypeData-&gt;publicIdentifier);
+}
+
+inline String AtomicHTMLToken::systemIdentifier() const
+{
+    if (!m_doctypeData-&gt;hasSystemIdentifier)
+        return String();
+    return StringImpl::create8BitIfPossible(m_doctypeData-&gt;systemIdentifier);
+}
+
+inline Attribute* findAttribute(Vector&lt;Attribute&gt;&amp; attributes, const QualifiedName&amp; name)
+{
+    for (auto&amp; attribute : attributes) {
+        if (attribute.name().matches(name))
+            return &amp;attribute;
+    }
+    return nullptr;
+}
+
</ins><span class="cx"> inline void AtomicHTMLToken::initializeAttributes(const HTMLToken::AttributeList&amp; attributes)
</span><span class="cx"> {
</span><del>-    size_t size = attributes.size();
</del><ins>+    unsigned size = attributes.size();
</ins><span class="cx">     if (!size)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_attributes.clear();
</del><span class="cx">     m_attributes.reserveInitialCapacity(size);
</span><del>-    for (size_t i = 0; i &lt; size; ++i) {
</del><ins>+    for (unsigned i = 0; i &lt; size; ++i) {
</ins><span class="cx">         const HTMLToken::Attribute&amp; attribute = attributes[i];
</span><span class="cx">         if (attribute.name.isEmpty())
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        // FIXME: We should be able to add the following ASSERT once we fix
-        // https://bugs.webkit.org/show_bug.cgi?id=62971
-        //   ASSERT(attribute.nameRange.start);
</del><ins>+        ASSERT(attribute.nameRange.start);
</ins><span class="cx">         ASSERT(attribute.nameRange.end);
</span><span class="cx">         ASSERT(attribute.valueRange.start);
</span><span class="cx">         ASSERT(attribute.valueRange.end);
</span><span class="cx"> 
</span><del>-        AtomicString value(attribute.value);
-        const QualifiedName&amp; name = nameForAttribute(attribute);
</del><ins>+        QualifiedName name(nullAtom, AtomicString(attribute.name), nullAtom);
+
</ins><span class="cx">         // FIXME: This is N^2 for the number of attributes.
</span><del>-        if (!findAttributeInVector(m_attributes, name))
-            m_attributes.append(Attribute(name, value));
</del><ins>+        if (!findAttribute(m_attributes, name))
+            m_attributes.append(Attribute(name, AtomicString(attribute.value)));
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline AtomicHTMLToken::AtomicHTMLToken(HTMLToken&amp; token)
+    : m_type(token.type())
+{
+    switch (m_type) {
+    case HTMLToken::Uninitialized:
+        ASSERT_NOT_REACHED();
+        return;
+    case HTMLToken::DOCTYPE:
+        m_name = AtomicString(token.name());
+        m_doctypeData = token.releaseDoctypeData();
+        return;
+    case HTMLToken::EndOfFile:
+        return;
+    case HTMLToken::StartTag:
+    case HTMLToken::EndTag:
+        m_selfClosing = token.selfClosing();
+        m_name = AtomicString(token.name());
+        initializeAttributes(token.attributes());
+        return;
+    case HTMLToken::Comment:
+        if (token.commentIsAll8BitData())
+            m_data = String::make8BitFrom16BitSource(token.comment());
+        else
+            m_data = String(token.comment());
+        return;
+    case HTMLToken::Character:
+        m_externalCharacters = token.characters().data();
+        m_externalCharactersLength = token.characters().size();
+        m_externalCharactersIsAll8BitData = token.charactersIsAll8BitData();
+        return;
+    }
+    ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline AtomicHTMLToken::AtomicHTMLToken(HTMLToken::Type type, const AtomicString&amp; name, Vector&lt;Attribute&gt;&amp;&amp; attributes)
+    : m_type(type)
+    , m_name(name)
+    , m_selfClosing(false)
+    , m_attributes(WTF::move(attributes))
+{
+    ASSERT(type == HTMLToken::StartTag || type == HTMLToken::EndTag);
+}
+
+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLConstructionSitecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -408,8 +408,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(token-&gt;type() == HTMLToken::DOCTYPE);
</span><span class="cx"> 
</span><del>-    const String&amp; publicId = StringImpl::create8BitIfPossible(token-&gt;publicIdentifier());
-    const String&amp; systemId = StringImpl::create8BitIfPossible(token-&gt;systemIdentifier());
</del><ins>+    String publicId = token-&gt;publicIdentifier();
+    String systemId = token-&gt;systemIdentifier();
+
</ins><span class="cx">     RefPtr&lt;DocumentType&gt; doctype = DocumentType::create(*m_document, token-&gt;name(), publicId, systemId);
</span><span class="cx">     attachLater(m_attachmentRoot, doctype.release());
</span><span class="cx"> 
</span><span class="lines">@@ -424,9 +425,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (token-&gt;forceQuirks())
</span><span class="cx">         setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
</span><del>-    else {
</del><ins>+    else
</ins><span class="cx">         setCompatibilityModeFromDoctype(token-&gt;name(), publicId, systemId);
</span><del>-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLConstructionSite::insertComment(AtomicHTMLToken* token)
</span><span class="lines">@@ -650,7 +650,7 @@
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Element&gt; element;
</span><span class="cx">     // NOTE: Moving from item -&gt; token -&gt; item copies the Attribute vector twice!
</span><del>-    AtomicHTMLToken fakeToken(HTMLToken::StartTag, item-&gt;localName(), item-&gt;attributes());
</del><ins>+    AtomicHTMLToken fakeToken(HTMLToken::StartTag, item-&gt;localName(), Vector&lt;Attribute&gt;(item-&gt;attributes()));
</ins><span class="cx">     if (item-&gt;namespaceURI() == HTMLNames::xhtmlNamespaceURI)
</span><span class="cx">         element = createHTMLElement(&amp;fakeToken);
</span><span class="cx">     else
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLDocumentParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -294,7 +294,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         constructTreeFromHTMLToken(m_token);
</span><del>-        ASSERT(m_token.isUninitialized());
</del><ins>+        ASSERT(m_token.type() == HTMLToken::Uninitialized);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Ensure we haven't been totally deref'ed after pumping. Any caller of this
</span><span class="lines">@@ -338,7 +338,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_treeBuilder-&gt;constructTree(token);
</span><span class="cx"> 
</span><del>-    if (!rawToken.isUninitialized()) {
</del><ins>+    if (rawToken.type() != HTMLToken::Uninitialized) {
</ins><span class="cx">         ASSERT(rawToken.type() == HTMLToken::Character);
</span><span class="cx">         rawToken.clear();
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLParserIdiomsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLParserIdioms.h (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLParserIdioms.h        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLParserIdioms.h        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -40,11 +40,6 @@
</span><span class="cx"> 
</span><span class="cx"> // Strip leading and trailing whitespace as defined by the HTML specification. 
</span><span class="cx"> WEBCORE_EXPORT String stripLeadingAndTrailingHTMLSpaces(const String&amp;);
</span><del>-template&lt;size_t inlineCapacity&gt;
-String stripLeadingAndTrailingHTMLSpaces(const Vector&lt;UChar, inlineCapacity&gt;&amp; vector)
-{
-    return stripLeadingAndTrailingHTMLSpaces(StringImpl::create8BitIfPossible(vector));
-}
</del><span class="cx"> 
</span><span class="cx"> // An implementation of the HTML specification's algorithm to convert a number to a string for number and range types.
</span><span class="cx"> String serializeForNumberType(const Decimal&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLPreloadScannercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -284,11 +284,11 @@
</span><span class="cx">     case HTMLToken::Character:
</span><span class="cx">         if (!m_inStyle)
</span><span class="cx">             return;
</span><del>-        m_cssScanner.scan(token.data(), requests);
</del><ins>+        m_cssScanner.scan(token.characters(), requests);
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case HTMLToken::EndTag: {
</span><del>-        TagId tagId = tagIdFor(token.data());
</del><ins>+        TagId tagId = tagIdFor(token.name());
</ins><span class="cx"> #if ENABLE(TEMPLATE_ELEMENT)
</span><span class="cx">         if (tagId == TagId::Template) {
</span><span class="cx">             if (m_templateCount)
</span><span class="lines">@@ -309,7 +309,7 @@
</span><span class="cx">         if (m_templateCount)
</span><span class="cx">             return;
</span><span class="cx"> #endif
</span><del>-        TagId tagId = tagIdFor(token.data());
</del><ins>+        TagId tagId = tagIdFor(token.name());
</ins><span class="cx"> #if ENABLE(TEMPLATE_ELEMENT)
</span><span class="cx">         if (tagId == TagId::Template) {
</span><span class="cx">             ++m_templateCount;
</span><span class="lines">@@ -340,12 +340,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename Token&gt;
-void TokenPreloadScanner::updatePredictedBaseURL(const Token&amp; token)
</del><ins>+void TokenPreloadScanner::updatePredictedBaseURL(const HTMLToken&amp; token)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_predictedBaseElementURL.isEmpty());
</span><del>-    if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(hrefAttr))
-        m_predictedBaseElementURL = URL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute-&gt;value)).copy();
</del><ins>+    if (auto* hrefAttribute = findAttribute(token.attributes(), hrefAttr.localName().string()))
+        m_predictedBaseElementURL = URL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(StringImpl::create8BitIfPossible(hrefAttribute-&gt;value))).copy();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions&amp; options, const URL&amp; documentURL, float deviceScaleFactor)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLPreloadScannerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -83,8 +83,7 @@
</span><span class="cx"> 
</span><span class="cx">     static String initiatorFor(TagId);
</span><span class="cx"> 
</span><del>-    template&lt;typename Token&gt;
-    void updatePredictedBaseURL(const Token&amp;);
</del><ins>+    void updatePredictedBaseURL(const HTMLToken&amp;);
</ins><span class="cx"> 
</span><span class="cx">     struct Checkpoint {
</span><span class="cx">         Checkpoint(const URL&amp; predictedBaseElementURL, bool inStyle
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLSourceTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">     m_cachedSourceForToken = String();
</span><span class="cx"> 
</span><span class="cx">     // FIXME: This work should really be done by the HTMLTokenizer.
</span><del>-    token.end(currentInput.numberOfCharactersConsumed() - tokenizer-&gt;numberOfBufferedCharacters());
</del><ins>+    token.setEndOffset(currentInput.numberOfCharactersConsumed() - tokenizer-&gt;numberOfBufferedCharacters());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String HTMLSourceTracker::sourceForToken(const HTMLToken&amp; token)
</span><span class="lines">@@ -63,13 +63,12 @@
</span><span class="cx">     if (!m_cachedSourceForToken.isEmpty())
</span><span class="cx">         return m_cachedSourceForToken;
</span><span class="cx"> 
</span><del>-    ASSERT(!token.startIndex());
-    size_t length = static_cast&lt;size_t&gt;(token.endIndex() - token.startIndex());
</del><ins>+    unsigned length = token.length();
</ins><span class="cx"> 
</span><span class="cx">     StringBuilder source;
</span><span class="cx">     source.reserveCapacity(length);
</span><span class="cx"> 
</span><del>-    size_t i = 0;
</del><ins>+    unsigned i = 0;
</ins><span class="cx">     for ( ; i &lt; length &amp;&amp; !m_previousSource.isEmpty(); ++i) {
</span><span class="cx">         source.append(m_previousSource.currentChar());
</span><span class="cx">         m_previousSource.advance();
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLStackItemh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLStackItem.h (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLStackItem.h        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLStackItem.h        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -149,7 +149,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline const Attribute* HTMLStackItem::findAttribute(const QualifiedName&amp; attributeName) const
</span><span class="cx"> {
</span><del>-    return findAttributeInVector(const_cast&lt;Vector&lt;Attribute&gt;&amp;&gt;(attributes()), attributeName);
</del><ins>+    return WebCore::findAttribute(const_cast&lt;Vector&lt;Attribute&gt;&amp;&gt;(attributes()), attributeName);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool HTMLStackItem::hasTagName(const QualifiedName&amp; name) const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTokenh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLToken.h (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLToken.h        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLToken.h        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2013 Google, Inc. All Rights Reserved.
</span><ins>+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -27,42 +28,18 @@
</span><span class="cx"> #define HTMLToken_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Attribute.h&quot;
</span><del>-#include &quot;HTMLToken.h&quot;
-#include &lt;wtf/RefCounted.h&gt;
-#include &lt;wtf/RefPtr.h&gt;
-#include &lt;wtf/text/StringView.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class DoctypeData {
-    WTF_MAKE_NONCOPYABLE(DoctypeData);
-public:
-    DoctypeData()
-        : m_hasPublicIdentifier(false)
-        , m_hasSystemIdentifier(false)
-        , m_forceQuirks(false)
-    {
-    }
-
-    // FIXME: This should use String instead of Vector&lt;UChar&gt;.
-    bool m_hasPublicIdentifier;
-    bool m_hasSystemIdentifier;
-    WTF::Vector&lt;UChar&gt; m_publicIdentifier;
-    WTF::Vector&lt;UChar&gt; m_systemIdentifier;
-    bool m_forceQuirks;
</del><ins>+struct DoctypeData {
+    bool hasPublicIdentifier { false };
+    bool hasSystemIdentifier { false };
+    Vector&lt;UChar&gt; publicIdentifier;
+    Vector&lt;UChar&gt; systemIdentifier;
+    bool forceQuirks { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-static inline Attribute* findAttributeInVector(Vector&lt;Attribute&gt;&amp; attributes, const QualifiedName&amp; name)
-{
-    for (unsigned i = 0; i &lt; attributes.size(); ++i) {
-        if (attributes.at(i).name().matches(name))
-            return &amp;attributes.at(i);
-    }
-    return 0;
-}
-
</del><span class="cx"> class HTMLToken {
</span><del>-    WTF_MAKE_NONCOPYABLE(HTMLToken);
</del><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     enum Type {
</span><span class="lines">@@ -75,12 +52,10 @@
</span><span class="cx">         EndOfFile,
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    class Attribute {
-    public:
-        class Range {
-        public:
-            int start;
-            int end;
</del><ins>+    struct Attribute {
+        struct Range {
+            unsigned start;
+            unsigned end;
</ins><span class="cx">         };
</span><span class="cx"> 
</span><span class="cx">         Range nameRange;
</span><span class="lines">@@ -92,360 +67,433 @@
</span><span class="cx">     typedef Vector&lt;Attribute, 10&gt; AttributeList;
</span><span class="cx">     typedef Vector&lt;UChar, 256&gt; DataVector;
</span><span class="cx"> 
</span><del>-    HTMLToken() { clear(); }
</del><ins>+    HTMLToken();
</ins><span class="cx"> 
</span><del>-    void clear()
-    {
-        m_type = Uninitialized;
-        m_range.start = 0;
-        m_range.end = 0;
-        m_baseOffset = 0;
-        m_data.clear();
-        m_orAllData = 0;
-    }
</del><ins>+    void clear();
</ins><span class="cx"> 
</span><del>-    bool isUninitialized() { return m_type == Uninitialized; }
-    Type type() const { return m_type; }
</del><ins>+    Type type() const;
</ins><span class="cx"> 
</span><del>-    void makeEndOfFile()
-    {
-        ASSERT(m_type == Uninitialized);
-        m_type = EndOfFile;
-    }
</del><ins>+    // Used by HTMLSourceTracker.
+    void setBaseOffset(unsigned); // Base for attribute offsets, and the end of token offset.
+    void setEndOffset(unsigned);
+    unsigned length() const;
</ins><span class="cx"> 
</span><del>-    /* Range and offset methods exposed for HTMLSourceTracker */
-    int startIndex() const { return m_range.start; }
-    int endIndex() const { return m_range.end; }
</del><ins>+    // EndOfFile
</ins><span class="cx"> 
</span><del>-    void setBaseOffset(int offset)
-    {
-        m_baseOffset = offset;
-    }
</del><ins>+    void makeEndOfFile();
</ins><span class="cx"> 
</span><del>-    void end(int endOffset)
-    {
-        m_range.end = endOffset - m_baseOffset;
-    }
</del><ins>+    // StartTag, EndTag, DOCTYPE.
</ins><span class="cx"> 
</span><del>-    const DataVector&amp; data() const
-    {
-        ASSERT(m_type == Character || m_type == Comment || m_type == StartTag || m_type == EndTag);
-        return m_data;
-    }
</del><ins>+    const DataVector&amp; name() const;
</ins><span class="cx"> 
</span><del>-    bool isAll8BitData() const
-    {
-        return (m_orAllData &lt;= 0xff);
-    }
</del><ins>+    void appendToName(UChar);
</ins><span class="cx"> 
</span><del>-    const DataVector&amp; name() const
-    {
-        ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
-        return m_data;
-    }
</del><ins>+    // DOCTYPE.
</ins><span class="cx"> 
</span><del>-    void appendToName(UChar character)
-    {
-        ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
-        ASSERT(character);
-        m_data.append(character);
-        m_orAllData |= character;
-    }
</del><ins>+    void beginDOCTYPE();
+    void beginDOCTYPE(UChar);
</ins><span class="cx"> 
</span><del>-    /* DOCTYPE Tokens */
</del><ins>+    void setForceQuirks();
</ins><span class="cx"> 
</span><del>-    bool forceQuirks() const
-    {
-        ASSERT(m_type == DOCTYPE);
-        return m_doctypeData-&gt;m_forceQuirks;
-    }
</del><ins>+    void setPublicIdentifierToEmptyString();
+    void setSystemIdentifierToEmptyString();
</ins><span class="cx"> 
</span><del>-    void setForceQuirks()
-    {
-        ASSERT(m_type == DOCTYPE);
-        m_doctypeData-&gt;m_forceQuirks = true;
-    }
</del><ins>+    void appendToPublicIdentifier(UChar);
+    void appendToSystemIdentifier(UChar);
</ins><span class="cx"> 
</span><del>-    void beginDOCTYPE()
-    {
-        ASSERT(m_type == Uninitialized);
-        m_type = DOCTYPE;
-        m_doctypeData = std::make_unique&lt;DoctypeData&gt;();
-    }
</del><ins>+    std::unique_ptr&lt;DoctypeData&gt; releaseDoctypeData();
</ins><span class="cx"> 
</span><del>-    void beginDOCTYPE(UChar character)
-    {
-        ASSERT(character);
-        beginDOCTYPE();
-        m_data.append(character);
-        m_orAllData |= character;
-    }
</del><ins>+    // StartTag, EndTag.
</ins><span class="cx"> 
</span><del>-    // FIXME: Distinguish between a missing public identifier and an empty one.
-    const WTF::Vector&lt;UChar&gt;&amp; publicIdentifier() const
-    {
-        ASSERT(m_type == DOCTYPE);
-        return m_doctypeData-&gt;m_publicIdentifier;
-    }
</del><ins>+    bool selfClosing() const;
+    const AttributeList&amp; attributes() const;
</ins><span class="cx"> 
</span><del>-    // FIXME: Distinguish between a missing system identifier and an empty one.
-    const WTF::Vector&lt;UChar&gt;&amp; systemIdentifier() const
-    {
-        ASSERT(m_type == DOCTYPE);
-        return m_doctypeData-&gt;m_systemIdentifier;
-    }
</del><ins>+    void beginStartTag(UChar);
</ins><span class="cx"> 
</span><del>-    void setPublicIdentifierToEmptyString()
-    {
-        ASSERT(m_type == DOCTYPE);
-        m_doctypeData-&gt;m_hasPublicIdentifier = true;
-        m_doctypeData-&gt;m_publicIdentifier.clear();
-    }
</del><ins>+    void beginEndTag(LChar);
+    void beginEndTag(const Vector&lt;LChar, 32&gt;&amp;);
</ins><span class="cx"> 
</span><del>-    void setSystemIdentifierToEmptyString()
-    {
-        ASSERT(m_type == DOCTYPE);
-        m_doctypeData-&gt;m_hasSystemIdentifier = true;
-        m_doctypeData-&gt;m_systemIdentifier.clear();
-    }
</del><ins>+    void addNewAttribute();
</ins><span class="cx"> 
</span><del>-    void appendToPublicIdentifier(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == DOCTYPE);
-        ASSERT(m_doctypeData-&gt;m_hasPublicIdentifier);
-        m_doctypeData-&gt;m_publicIdentifier.append(character);
-    }
</del><ins>+    void beginAttributeName(unsigned offset);
+    void appendToAttributeName(UChar);
+    void endAttributeName(unsigned offset);
</ins><span class="cx"> 
</span><del>-    void appendToSystemIdentifier(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == DOCTYPE);
-        ASSERT(m_doctypeData-&gt;m_hasSystemIdentifier);
-        m_doctypeData-&gt;m_systemIdentifier.append(character);
-    }
</del><ins>+    void beginAttributeValue(unsigned offset);
+    void appendToAttributeValue(UChar);
+    void endAttributeValue(unsigned offset);
</ins><span class="cx"> 
</span><del>-    std::unique_ptr&lt;DoctypeData&gt; releaseDoctypeData()
-    {
-        return WTF::move(m_doctypeData);
-    }
</del><ins>+    void setSelfClosing();
</ins><span class="cx"> 
</span><del>-    /* Start/End Tag Tokens */
</del><ins>+public:
+    // Used by the XSSAuditor to nuke XSS-laden attributes.
+    void eraseValueOfAttribute(unsigned index);
+    void appendToAttributeValue(unsigned index, StringView value);
</ins><span class="cx"> 
</span><del>-    bool selfClosing() const
-    {
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        return m_selfClosing;
-    }
</del><ins>+    // Character.
</ins><span class="cx"> 
</span><del>-    void setSelfClosing()
-    {
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        m_selfClosing = true;
-    }
</del><ins>+    // Starting a character token works slightly differently than starting
+    // other types of tokens because we want to save a per-character branch.
+    // There is no beginCharacters, and appending a character sets the type.
</ins><span class="cx"> 
</span><del>-    void beginStartTag(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == Uninitialized);
-        m_type = StartTag;
-        m_selfClosing = false;
-        m_currentAttribute = 0;
-        m_attributes.clear();
</del><ins>+    const DataVector&amp; characters() const;
+    bool charactersIsAll8BitData() const;
</ins><span class="cx"> 
</span><del>-        m_data.append(character);
-        m_orAllData |= character;
-    }
</del><ins>+    void appendToCharacter(LChar);
+    void appendToCharacter(UChar);
+    void appendToCharacter(const Vector&lt;LChar, 32&gt;&amp;);
</ins><span class="cx"> 
</span><del>-    void beginEndTag(LChar character)
-    {
-        ASSERT(m_type == Uninitialized);
-        m_type = EndTag;
-        m_selfClosing = false;
-        m_currentAttribute = 0;
-        m_attributes.clear();
</del><ins>+    // Comment.
</ins><span class="cx"> 
</span><del>-        m_data.append(character);
-    }
</del><ins>+    const DataVector&amp; comment() const;
+    bool commentIsAll8BitData() const;
</ins><span class="cx"> 
</span><del>-    void beginEndTag(const Vector&lt;LChar, 32&gt;&amp; characters)
-    {
-        ASSERT(m_type == Uninitialized);
-        m_type = EndTag;
-        m_selfClosing = false;
-        m_currentAttribute = 0;
-        m_attributes.clear();
</del><ins>+    void beginComment();
+    void appendToComment(UChar);
</ins><span class="cx"> 
</span><del>-        m_data.appendVector(characters);
-    }
</del><ins>+private:
+    Type m_type;
</ins><span class="cx"> 
</span><del>-    void addNewAttribute()
-    {
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        m_attributes.grow(m_attributes.size() + 1);
-        m_currentAttribute = &amp;m_attributes.last();
-#ifndef NDEBUG
-        m_currentAttribute-&gt;nameRange.start = 0;
-        m_currentAttribute-&gt;nameRange.end = 0;
-        m_currentAttribute-&gt;valueRange.start = 0;
-        m_currentAttribute-&gt;valueRange.end = 0;
-#endif
-    }
</del><ins>+    unsigned m_baseOffset;
+    unsigned m_length;
</ins><span class="cx"> 
</span><del>-    void beginAttributeName(int offset)
-    {
-        m_currentAttribute-&gt;nameRange.start = offset - m_baseOffset;
-    }
</del><ins>+    DataVector m_data;
+    UChar m_data8BitCheck;
</ins><span class="cx"> 
</span><del>-    void endAttributeName(int offset)
-    {
-        int index = offset - m_baseOffset;
-        m_currentAttribute-&gt;nameRange.end = index;
-        m_currentAttribute-&gt;valueRange.start = index;
-        m_currentAttribute-&gt;valueRange.end = index;
-    }
</del><ins>+    // For StartTag and EndTag
+    bool m_selfClosing;
+    AttributeList m_attributes;
+    Attribute* m_currentAttribute;
</ins><span class="cx"> 
</span><del>-    void beginAttributeValue(int offset)
-    {
-        m_currentAttribute-&gt;valueRange.start = offset - m_baseOffset;
-#ifndef NDEBUG
-        m_currentAttribute-&gt;valueRange.end = 0;
</del><ins>+    // For DOCTYPE
+    std::unique_ptr&lt;DoctypeData&gt; m_doctypeData;
+};
+
+const HTMLToken::Attribute* findAttribute(const Vector&lt;HTMLToken::Attribute&gt;&amp;, StringView name);
+
+inline HTMLToken::HTMLToken()
+{
+    clear();
+}
+
+inline void HTMLToken::clear()
+{
+    m_type = Uninitialized;
+    m_data.clear();
+    m_data8BitCheck = 0;
+
+    m_length = 0;
+    m_baseOffset = 0;
+}
+
+inline HTMLToken::Type HTMLToken::type() const
+{
+    return m_type;
+}
+
+inline void HTMLToken::makeEndOfFile()
+{
+    ASSERT(m_type == Uninitialized);
+    m_type = EndOfFile;
+}
+
+inline unsigned HTMLToken::length() const
+{
+    return m_length;
+}
+
+inline void HTMLToken::setBaseOffset(unsigned offset)
+{
+    m_baseOffset = offset;
+}
+
+inline void HTMLToken::setEndOffset(unsigned endOffset)
+{
+    m_length = endOffset - m_baseOffset;
+}
+
+inline const HTMLToken::DataVector&amp; HTMLToken::name() const
+{
+    ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
+    return m_data;
+}
+
+inline void HTMLToken::appendToName(UChar character)
+{
+    ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
+    ASSERT(character);
+    m_data.append(character);
+    m_data8BitCheck |= character;
+}
+
+inline void HTMLToken::setForceQuirks()
+{
+    ASSERT(m_type == DOCTYPE);
+    m_doctypeData-&gt;forceQuirks = true;
+}
+
+inline void HTMLToken::beginDOCTYPE()
+{
+    ASSERT(m_type == Uninitialized);
+    m_type = DOCTYPE;
+    m_doctypeData = std::make_unique&lt;DoctypeData&gt;();
+}
+
+inline void HTMLToken::beginDOCTYPE(UChar character)
+{
+    ASSERT(character);
+    beginDOCTYPE();
+    m_data.append(character);
+    m_data8BitCheck |= character;
+}
+
+inline void HTMLToken::setPublicIdentifierToEmptyString()
+{
+    ASSERT(m_type == DOCTYPE);
+    m_doctypeData-&gt;hasPublicIdentifier = true;
+    m_doctypeData-&gt;publicIdentifier.clear();
+}
+
+inline void HTMLToken::setSystemIdentifierToEmptyString()
+{
+    ASSERT(m_type == DOCTYPE);
+    m_doctypeData-&gt;hasSystemIdentifier = true;
+    m_doctypeData-&gt;systemIdentifier.clear();
+}
+
+inline void HTMLToken::appendToPublicIdentifier(UChar character)
+{
+    ASSERT(character);
+    ASSERT(m_type == DOCTYPE);
+    ASSERT(m_doctypeData-&gt;hasPublicIdentifier);
+    m_doctypeData-&gt;publicIdentifier.append(character);
+}
+
+inline void HTMLToken::appendToSystemIdentifier(UChar character)
+{
+    ASSERT(character);
+    ASSERT(m_type == DOCTYPE);
+    ASSERT(m_doctypeData-&gt;hasSystemIdentifier);
+    m_doctypeData-&gt;systemIdentifier.append(character);
+}
+
+inline std::unique_ptr&lt;DoctypeData&gt; HTMLToken::releaseDoctypeData()
+{
+    return WTF::move(m_doctypeData);
+}
+
+inline bool HTMLToken::selfClosing() const
+{
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    return m_selfClosing;
+}
+
+inline void HTMLToken::setSelfClosing()
+{
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    m_selfClosing = true;
+}
+
+inline void HTMLToken::beginStartTag(UChar character)
+{
+    ASSERT(character);
+    ASSERT(m_type == Uninitialized);
+    m_type = StartTag;
+    m_selfClosing = false;
+    m_currentAttribute = nullptr;
+    m_attributes.clear();
+
+    m_data.append(character);
+    m_data8BitCheck = character;
+}
+
+inline void HTMLToken::beginEndTag(LChar character)
+{
+    ASSERT(m_type == Uninitialized);
+    m_type = EndTag;
+    m_selfClosing = false;
+    m_currentAttribute = nullptr;
+    m_attributes.clear();
+
+    m_data.append(character);
+}
+
+inline void HTMLToken::beginEndTag(const Vector&lt;LChar, 32&gt;&amp; characters)
+{
+    ASSERT(m_type == Uninitialized);
+    m_type = EndTag;
+    m_selfClosing = false;
+    m_currentAttribute = nullptr;
+    m_attributes.clear();
+
+    m_data.appendVector(characters);
+}
+
+inline void HTMLToken::addNewAttribute()
+{
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    m_attributes.grow(m_attributes.size() + 1);
+    m_currentAttribute = &amp;m_attributes.last();
+
+#if !ASSERT_DISABLED
+    m_currentAttribute-&gt;nameRange.start = 0;
+    m_currentAttribute-&gt;nameRange.end = 0;
+    m_currentAttribute-&gt;valueRange.start = 0;
+    m_currentAttribute-&gt;valueRange.end = 0;
</ins><span class="cx"> #endif
</span><del>-    }
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    void endAttributeValue(int offset)
-    {
-        m_currentAttribute-&gt;valueRange.end = offset - m_baseOffset;
-    }
</del><ins>+inline void HTMLToken::beginAttributeName(unsigned offset)
+{
+    ASSERT(offset);
+    ASSERT(!m_currentAttribute-&gt;nameRange.start);
+    m_currentAttribute-&gt;nameRange.start = offset - m_baseOffset;
+}
</ins><span class="cx"> 
</span><del>-    void appendToAttributeName(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        // FIXME: We should be able to add the following ASSERT once we fix
-        // https://bugs.webkit.org/show_bug.cgi?id=62971
-        //   ASSERT(m_currentAttribute-&gt;nameRange.start);
-        m_currentAttribute-&gt;name.append(character);
-    }
</del><ins>+inline void HTMLToken::endAttributeName(unsigned offset)
+{
+    ASSERT(offset);
+    ASSERT(m_currentAttribute-&gt;nameRange.start);
+    ASSERT(!m_currentAttribute-&gt;nameRange.end);
</ins><span class="cx"> 
</span><del>-    void appendToAttributeValue(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        ASSERT(m_currentAttribute-&gt;valueRange.start);
-        m_currentAttribute-&gt;value.append(character);
-    }
</del><ins>+    unsigned adjustedOffset = offset - m_baseOffset;
+    m_currentAttribute-&gt;nameRange.end = adjustedOffset;
</ins><span class="cx"> 
</span><del>-    void appendToAttributeValue(size_t i, StringView value)
-    {
-        ASSERT(!value.isEmpty());
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        append(m_attributes[i].value, value);
-    }
</del><ins>+    // FIXME: Is this intentional? Why point the value at the end of the name?
+    m_currentAttribute-&gt;valueRange.start = adjustedOffset;
+    m_currentAttribute-&gt;valueRange.end = adjustedOffset;
+}
</ins><span class="cx"> 
</span><del>-    const AttributeList&amp; attributes() const
-    {
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        return m_attributes;
-    }
</del><ins>+inline void HTMLToken::beginAttributeValue(unsigned offset)
+{
+    ASSERT(offset);
+    m_currentAttribute-&gt;valueRange.start = offset - m_baseOffset;
+}
</ins><span class="cx"> 
</span><del>-    const Attribute* getAttributeItem(const QualifiedName&amp; name) const
-    {
-        for (unsigned i = 0; i &lt; m_attributes.size(); ++i) {
-            if (AtomicString(m_attributes.at(i).name) == name.localName())
-                return &amp;m_attributes.at(i);
-        }
-        return 0;
-    }
</del><ins>+inline void HTMLToken::endAttributeValue(unsigned offset)
+{
+    ASSERT(offset);
+    m_currentAttribute-&gt;valueRange.end = offset - m_baseOffset;
+}
</ins><span class="cx"> 
</span><del>-    // Used by the XSSAuditor to nuke XSS-laden attributes.
-    void eraseValueOfAttribute(size_t i)
-    {
-        ASSERT(m_type == StartTag || m_type == EndTag);
-        m_attributes[i].value.clear();
-    }
</del><ins>+inline void HTMLToken::appendToAttributeName(UChar character)
+{
+    ASSERT(character);
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    ASSERT(m_currentAttribute-&gt;nameRange.start);
+    m_currentAttribute-&gt;name.append(character);
+}
</ins><span class="cx"> 
</span><del>-    /* Character Tokens */
</del><ins>+inline void HTMLToken::HTMLToken::appendToAttributeValue(UChar character)
+{
+    ASSERT(character);
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    ASSERT(m_currentAttribute-&gt;valueRange.start);
+    m_currentAttribute-&gt;value.append(character);
+}
</ins><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()
-    {
-        ASSERT(m_type == Uninitialized || m_type == Character);
-        m_type = Character;
-    }
</del><ins>+inline void HTMLToken::HTMLToken::appendToAttributeValue(unsigned i, StringView value)
+{
+    ASSERT(!value.isEmpty());
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    append(m_attributes[i].value, value);
+}
</ins><span class="cx"> 
</span><del>-    const DataVector&amp; characters() const
-    {
-        ASSERT(m_type == Character);
-        return m_data;
-    }
</del><ins>+inline const HTMLToken::AttributeList&amp; HTMLToken::attributes() const
+{
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    return m_attributes;
+}
</ins><span class="cx"> 
</span><del>-    void appendToCharacter(char character)
-    {
-        ASSERT(m_type == Character);
-        m_data.append(character);
-    }
</del><ins>+// Used by the XSSAuditor to nuke XSS-laden attributes.
+inline void HTMLToken::eraseValueOfAttribute(unsigned i)
+{
+    ASSERT(m_type == StartTag || m_type == EndTag);
+    ASSERT(i &lt; m_attributes.size());
+    m_attributes[i].value.clear();
+}
</ins><span class="cx"> 
</span><del>-    void appendToCharacter(UChar character)
-    {
-        ASSERT(m_type == Character);
-        m_data.append(character);
-        m_orAllData |= character;
-    }
</del><ins>+inline const HTMLToken::DataVector&amp; HTMLToken::characters() const
+{
+    ASSERT(m_type == Character);
+    return m_data;
+}
</ins><span class="cx"> 
</span><del>-    void appendToCharacter(const Vector&lt;LChar, 32&gt;&amp; characters)
-    {
-        ASSERT(m_type == Character);
-        m_data.appendVector(characters);
-    }
</del><ins>+inline bool HTMLToken::charactersIsAll8BitData() const
+{
+    ASSERT(m_type == Character);
+    return m_data8BitCheck &lt;= 0xFF;
+}
</ins><span class="cx"> 
</span><del>-    /* Comment Tokens */
</del><ins>+inline void HTMLToken::appendToCharacter(LChar character)
+{
+    ASSERT(m_type == Uninitialized || m_type == Character);
+    m_type = Character;
+    m_data.append(character);
+}
</ins><span class="cx"> 
</span><del>-    const DataVector&amp; comment() const
-    {
-        ASSERT(m_type == Comment);
-        return m_data;
-    }
</del><ins>+inline void HTMLToken::appendToCharacter(UChar character)
+{
+    ASSERT(m_type == Uninitialized || m_type == Character);
+    m_type = Character;
+    m_data.append(character);
+    m_data8BitCheck |= character;
+}
</ins><span class="cx"> 
</span><del>-    void beginComment()
-    {
-        ASSERT(m_type == Uninitialized);
-        m_type = Comment;
-    }
</del><ins>+inline void HTMLToken::appendToCharacter(const Vector&lt;LChar, 32&gt;&amp; characters)
+{
+    ASSERT(m_type == Uninitialized || m_type == Character);
+    m_type = Character;
+    m_data.appendVector(characters);
+}
</ins><span class="cx"> 
</span><del>-    void appendToComment(UChar character)
-    {
-        ASSERT(character);
-        ASSERT(m_type == Comment);
-        m_data.append(character);
-        m_orAllData |= character;
-    }
</del><ins>+inline const HTMLToken::DataVector&amp; HTMLToken::comment() const
+{
+    ASSERT(m_type == Comment);
+    return m_data;
+}
</ins><span class="cx"> 
</span><del>-    void eraseCharacters()
-    {
-        ASSERT(m_type == Character);
-        m_data.clear();
-        m_orAllData = 0;
-    }
</del><ins>+inline bool HTMLToken::commentIsAll8BitData() const
+{
+    ASSERT(m_type == Comment);
+    return m_data8BitCheck &lt;= 0xFF;
+}
</ins><span class="cx"> 
</span><del>-private:
-    Type m_type;
-    Attribute::Range m_range; // Always starts at zero.
-    int m_baseOffset;
-    DataVector m_data;
-    UChar m_orAllData;
</del><ins>+inline void HTMLToken::beginComment()
+{
+    ASSERT(m_type == Uninitialized);
+    m_type = Comment;
+}
</ins><span class="cx"> 
</span><del>-    // For StartTag and EndTag
-    bool m_selfClosing;
-    AttributeList m_attributes;
</del><ins>+inline void HTMLToken::appendToComment(UChar character)
+{
+    ASSERT(character);
+    ASSERT(m_type == Comment);
+    m_data.append(character);
+    m_data8BitCheck |= character;
+}
</ins><span class="cx"> 
</span><del>-    // A pointer into m_attributes used during lexing.
-    Attribute* m_currentAttribute;
</del><ins>+inline bool nameMatches(const HTMLToken::Attribute&amp; attribute, StringView name)
+{
+    unsigned size = name.length();
+    if (attribute.name.size() != size)
+        return false;
+    for (unsigned i = 0; i &lt; size; ++i) {
+        // FIXME: The one caller that uses this probably wants to ignore letter case.
+        if (attribute.name[i] != name[i])
+            return false;
+    }
+    return true;
+}
</ins><span class="cx"> 
</span><del>-    // For DOCTYPE
-    std::unique_ptr&lt;DoctypeData&gt; m_doctypeData;
-};
</del><ins>+inline const HTMLToken::Attribute* findAttribute(const HTMLToken::AttributeList&amp; attributes, StringView name)
+{
+    for (auto&amp; attribute : attributes) {
+        if (nameMatches(attribute, name))
+            return &amp;attribute;
+    }
+    return nullptr;
+}
</ins><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTokenizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -42,23 +42,6 @@
</span><span class="cx"> 
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx"> 
</span><del>-// This has to go in a .cpp file, as the linker doesn't like it being included more than once.
-// We don't have an HTMLToken.cpp though, so this is the next best place.
-QualifiedName AtomicHTMLToken::nameForAttribute(const HTMLToken::Attribute&amp; attribute) const
-{
-    return QualifiedName(nullAtom, AtomicString(attribute.name), nullAtom);
-}
-
-bool AtomicHTMLToken::usesName() const
-{
-    return m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE;
-}
-
-bool AtomicHTMLToken::usesAttributes() const
-{
-    return m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag;
-}
-
</del><span class="cx"> static inline UChar toLowerCase(UChar cc)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isASCIIUpper(cc));
</span><span class="lines">@@ -128,7 +111,7 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!success) {
</span><span class="cx">         ASSERT(decodedEntity.isEmpty());
</span><del>-        bufferCharacter('&amp;');
</del><ins>+        bufferASCIICharacter('&amp;');
</ins><span class="cx">     } else {
</span><span class="cx">         for (unsigned i = 0; i &lt; decodedEntity.length(); ++i)
</span><span class="cx">             bufferCharacter(decodedEntity[i]);
</span><span class="lines">@@ -292,7 +275,7 @@
</span><span class="cx">             HTML_RECONSUME_IN(BogusCommentState);
</span><span class="cx">         } else {
</span><span class="cx">             parseError();
</span><del>-            bufferCharacter('&lt;');
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_RECONSUME_IN(DataState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -312,8 +295,8 @@
</span><span class="cx">             HTML_ADVANCE_TO(DataState);
</span><span class="cx">         } else if (cc == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             HTML_RECONSUME_IN(DataState);
</span><span class="cx">         } else {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -350,7 +333,7 @@
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><span class="cx">             HTML_ADVANCE_TO(RCDATAEndTagOpenState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_RECONSUME_IN(RCDATAState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -366,8 +349,8 @@
</span><span class="cx">             addToPossibleEndTag(static_cast&lt;LChar&gt;(cc));
</span><span class="cx">             HTML_ADVANCE_TO(RCDATAEndTagNameState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             HTML_RECONSUME_IN(RCDATAState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -399,8 +382,8 @@
</span><span class="cx">                     return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             m_token-&gt;appendToCharacter(m_temporaryBuffer);
</span><span class="cx">             m_bufferedEndTagName.clear();
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="lines">@@ -415,7 +398,7 @@
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><span class="cx">             HTML_ADVANCE_TO(RAWTEXTEndTagOpenState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_RECONSUME_IN(RAWTEXTState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -431,8 +414,8 @@
</span><span class="cx">             addToPossibleEndTag(static_cast&lt;LChar&gt;(cc));
</span><span class="cx">             HTML_ADVANCE_TO(RAWTEXTEndTagNameState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             HTML_RECONSUME_IN(RAWTEXTState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -464,8 +447,8 @@
</span><span class="cx">                     return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             m_token-&gt;appendToCharacter(m_temporaryBuffer);
</span><span class="cx">             m_bufferedEndTagName.clear();
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="lines">@@ -480,11 +463,11 @@
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataEndTagOpenState);
</span><span class="cx">         } else if (cc == '!') {
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('!');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('!');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapeStartState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_RECONSUME_IN(ScriptDataState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -500,8 +483,8 @@
</span><span class="cx">             addToPossibleEndTag(static_cast&lt;LChar&gt;(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataEndTagNameState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             HTML_RECONSUME_IN(ScriptDataState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -533,8 +516,8 @@
</span><span class="cx">                     return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             m_token-&gt;appendToCharacter(m_temporaryBuffer);
</span><span class="cx">             m_bufferedEndTagName.clear();
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="lines">@@ -545,7 +528,7 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataEscapeStartState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapeStartDashState);
</span><span class="cx">         } else
</span><span class="cx">             HTML_RECONSUME_IN(ScriptDataState);
</span><span class="lines">@@ -554,7 +537,7 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataEscapeStartDashState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedDashDashState);
</span><span class="cx">         } else
</span><span class="cx">             HTML_RECONSUME_IN(ScriptDataState);
</span><span class="lines">@@ -563,7 +546,7 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataEscapedState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedDashState);
</span><span class="cx">         } else if (cc == '&lt;')
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedLessThanSignState);
</span><span class="lines">@@ -579,7 +562,7 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataEscapedDashState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedDashDashState);
</span><span class="cx">         } else if (cc == '&lt;')
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedLessThanSignState);
</span><span class="lines">@@ -595,12 +578,12 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataEscapedDashDashState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedDashDashState);
</span><span class="cx">         } else if (cc == '&lt;')
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedLessThanSignState);
</span><span class="cx">         else if (cc == '&gt;') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('&gt;');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataState);
</span><span class="cx">         } else if (cc == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -618,19 +601,19 @@
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedEndTagOpenState);
</span><span class="cx">         } else if (isASCIIUpper(cc)) {
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter(cc);
</ins><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             m_temporaryBuffer.append(toLowerCase(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
</span><span class="cx">         } else if (isASCIILower(cc)) {
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter(cc);
</ins><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             m_temporaryBuffer.append(static_cast&lt;LChar&gt;(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_RECONSUME_IN(ScriptDataEscapedState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -646,8 +629,8 @@
</span><span class="cx">             addToPossibleEndTag(static_cast&lt;LChar&gt;(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataEscapedEndTagNameState);
</span><span class="cx">         } else {
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             HTML_RECONSUME_IN(ScriptDataEscapedState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -679,8 +662,8 @@
</span><span class="cx">                     return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-            bufferCharacter('&lt;');
-            bufferCharacter('/');
</del><ins>+            bufferASCIICharacter('&lt;');
+            bufferASCIICharacter('/');
</ins><span class="cx">             m_token-&gt;appendToCharacter(m_temporaryBuffer);
</span><span class="cx">             m_bufferedEndTagName.clear();
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="lines">@@ -691,17 +674,17 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataDoubleEscapeStartState) {
</span><span class="cx">         if (isTokenizerWhitespace(cc) || cc == '/' || cc == '&gt;') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter(cc);
</ins><span class="cx">             if (temporaryBufferIs(scriptTag.localName()))
</span><span class="cx">                 HTML_ADVANCE_TO(ScriptDataDoubleEscapedState);
</span><span class="cx">             else
</span><span class="cx">                 HTML_ADVANCE_TO(ScriptDataEscapedState);
</span><span class="cx">         } else if (isASCIIUpper(cc)) {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter(cc);
</ins><span class="cx">             m_temporaryBuffer.append(toLowerCase(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
</span><span class="cx">         } else if (isASCIILower(cc)) {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter(cc);
</ins><span class="cx">             m_temporaryBuffer.append(static_cast&lt;LChar&gt;(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
</span><span class="cx">         } else
</span><span class="lines">@@ -711,10 +694,10 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataDoubleEscapedState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapedDashState);
</span><span class="cx">         } else if (cc == '&lt;') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
</span><span class="cx">         } else if (cc == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -728,10 +711,10 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataDoubleEscapedDashState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
</span><span class="cx">         } else if (cc == '&lt;') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
</span><span class="cx">         } else if (cc == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -745,13 +728,13 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataDoubleEscapedDashDashState) {
</span><span class="cx">         if (cc == '-') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('-');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
</span><span class="cx">         } else if (cc == '&lt;') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('&lt;');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
</span><span class="cx">         } else if (cc == '&gt;') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('&gt;');
</ins><span class="cx">             HTML_ADVANCE_TO(ScriptDataState);
</span><span class="cx">         } else if (cc == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -765,7 +748,7 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataDoubleEscapedLessThanSignState) {
</span><span class="cx">         if (cc == '/') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter('/');
</ins><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapeEndState);
</span><span class="cx">         } else
</span><span class="lines">@@ -775,17 +758,17 @@
</span><span class="cx"> 
</span><span class="cx">     HTML_BEGIN_STATE(ScriptDataDoubleEscapeEndState) {
</span><span class="cx">         if (isTokenizerWhitespace(cc) || cc == '/' || cc == '&gt;') {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter(cc);
</ins><span class="cx">             if (temporaryBufferIs(scriptTag.localName()))
</span><span class="cx">                 HTML_ADVANCE_TO(ScriptDataEscapedState);
</span><span class="cx">             else
</span><span class="cx">                 HTML_ADVANCE_TO(ScriptDataDoubleEscapedState);
</span><span class="cx">         } else if (isASCIIUpper(cc)) {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter(cc);
</ins><span class="cx">             m_temporaryBuffer.append(toLowerCase(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapeEndState);
</span><span class="cx">         } else if (isASCIILower(cc)) {
</span><del>-            bufferCharacter(cc);
</del><ins>+            bufferASCIICharacter(cc);
</ins><span class="cx">             m_temporaryBuffer.append(static_cast&lt;LChar&gt;(cc));
</span><span class="cx">             HTML_ADVANCE_TO(ScriptDataDoubleEscapeEndState);
</span><span class="cx">         } else
</span><span class="lines">@@ -1542,7 +1525,7 @@
</span><span class="cx">         if (cc == ']')
</span><span class="cx">             HTML_ADVANCE_TO(CDATASectionDoubleRightSquareBracketState);
</span><span class="cx">         else {
</span><del>-            bufferCharacter(']');
</del><ins>+            bufferASCIICharacter(']');
</ins><span class="cx">             HTML_RECONSUME_IN(CDATASectionState);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1551,8 +1534,8 @@
</span><span class="cx">         if (cc == '&gt;')
</span><span class="cx">             HTML_ADVANCE_TO(DataState);
</span><span class="cx">         else {
</span><del>-            bufferCharacter(']');
-            bufferCharacter(']');
</del><ins>+            bufferASCIICharacter(']');
+            bufferASCIICharacter(']');
</ins><span class="cx">             HTML_RECONSUME_IN(CDATASectionState);
</span><span class="cx">         }
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTokenizerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLTokenizer.h (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLTokenizer.h        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLTokenizer.h        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -177,12 +177,20 @@
</span><span class="cx"> 
</span><span class="cx">     inline void parseError();
</span><span class="cx"> 
</span><del>-    inline void bufferCharacter(UChar character)
</del><ins>+    void bufferASCIICharacter(UChar character)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(character != kEndOfFileMarker);
</span><del>-        m_token-&gt;ensureIsCharacterToken();
</del><ins>+        ASSERT(isASCII(character));
+        m_token-&gt;appendToCharacter(static_cast&lt;LChar&gt;(character));
+    }
+
+    void bufferCharacter(UChar character)
+    {
+        ASSERT(character != kEndOfFileMarker);
</ins><span class="cx">         m_token-&gt;appendToCharacter(character);
</span><span class="cx">     }
</span><ins>+    void bufferCharacter(char) = delete;
+    void bufferCharacter(LChar) = delete;
</ins><span class="cx"> 
</span><span class="cx">     inline bool emitAndResumeIn(SegmentedString&amp; source, State state)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTreeBuildercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -130,7 +130,7 @@
</span><span class="cx"> public:
</span><span class="cx">     explicit ExternalCharacterTokenBuffer(AtomicHTMLToken&amp; token)
</span><span class="cx">         : m_text(token.characters(), token.charactersLength())
</span><del>-        , m_isAll8BitData(token.isAll8BitData())
</del><ins>+        , m_isAll8BitData(token.charactersIsAll8BitData())
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(!isEmpty());
</span><span class="cx">     }
</span><span class="lines">@@ -460,13 +460,11 @@
</span><span class="cx">         return;
</span><span class="cx">     notImplemented(); // Acknowledge self-closing flag
</span><span class="cx">     processFakeStartTag(formTag);
</span><del>-    Attribute* actionAttribute = token.getAttributeItem(actionAttr);
-    if (actionAttribute)
</del><ins>+    if (Attribute* actionAttribute = findAttribute(token.attributes(), actionAttr))
</ins><span class="cx">         m_tree.form()-&gt;setAttribute(actionAttr, actionAttribute-&gt;value());
</span><span class="cx">     processFakeStartTag(hrTag);
</span><span class="cx">     processFakeStartTag(labelTag);
</span><del>-    Attribute* promptAttribute = token.getAttributeItem(promptAttr);
-    if (promptAttribute)
</del><ins>+    if (Attribute* promptAttribute = findAttribute(token.attributes(), promptAttr))
</ins><span class="cx">         processFakeCharacters(promptAttribute-&gt;value());
</span><span class="cx">     else
</span><span class="cx">         processFakeCharacters(searchableIndexIntroduction());
</span><span class="lines">@@ -777,16 +775,14 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     if (token.name() == inputTag) {
</span><del>-        Attribute* typeAttribute = token.getAttributeItem(typeAttr);
</del><ins>+        Attribute* typeAttribute = findAttribute(token.attributes(), typeAttr);
</ins><span class="cx">         m_tree.reconstructTheActiveFormattingElements();
</span><span class="cx">         m_tree.insertSelfClosingHTMLElement(&amp;token);
</span><span class="cx">         if (!typeAttribute || !equalIgnoringCase(typeAttribute-&gt;value(), &quot;hidden&quot;))
</span><span class="cx">             m_framesetOk = false;
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    if (token.name() == paramTag
-        || token.name() == sourceTag
-        || token.name() == trackTag) {
</del><ins>+    if (token.name() == paramTag || token.name() == sourceTag || token.name() == trackTag) {
</ins><span class="cx">         m_tree.insertSelfClosingHTMLElement(&amp;token);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -1023,7 +1019,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     if (token.name() == inputTag) {
</span><del>-        Attribute* typeAttribute = token.getAttributeItem(typeAttr);
</del><ins>+        Attribute* typeAttribute = findAttribute(token.attributes(), typeAttr);
</ins><span class="cx">         if (typeAttribute &amp;&amp; equalIgnoringCase(typeAttribute-&gt;value(), &quot;hidden&quot;)) {
</span><span class="cx">             parseError(token);
</span><span class="cx">             m_tree.insertSelfClosingHTMLElement(&amp;token);
</span><span class="lines">@@ -2812,6 +2808,11 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool hasAttribute(AtomicHTMLToken&amp; token, const QualifiedName&amp; name)
+{
+    return findAttribute(token.attributes(), name);
+}
+
</ins><span class="cx"> void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken&amp; token)
</span><span class="cx"> {
</span><span class="cx">     HTMLStackItem&amp; adjustedCurrentNode = adjustedCurrentStackItem();
</span><span class="lines">@@ -2863,7 +2864,7 @@
</span><span class="cx">             || token.name() == uTag
</span><span class="cx">             || token.name() == ulTag
</span><span class="cx">             || token.name() == varTag
</span><del>-            || (token.name() == fontTag &amp;&amp; (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)))) {
</del><ins>+            || (token.name() == fontTag &amp;&amp; (hasAttribute(token, colorAttr) || hasAttribute(token, faceAttr) || hasAttribute(token, sizeAttr)))) {
</ins><span class="cx">             parseError(token);
</span><span class="cx">             m_tree.openElements().popUntilForeignContentScopeMarker();
</span><span class="cx">             processStartTag(token);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserTextDocumentParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/TextDocumentParser.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/TextDocumentParser.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/TextDocumentParser.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">     // distrubing the line/column number calculations.
</span><span class="cx">     Vector&lt;Attribute&gt; attributes;
</span><span class="cx">     attributes.append(Attribute(styleAttr, &quot;word-wrap: break-word; white-space: pre-wrap;&quot;));
</span><del>-    AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), attributes);
</del><ins>+    AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), WTF::move(attributes));
</ins><span class="cx">     treeBuilder().constructTree(fakePre);
</span><span class="cx"> 
</span><span class="cx">     // Normally we would skip the first \n after a &lt;pre&gt; element, but we don't
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserXSSAuditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/XSSAuditor.cpp (177951 => 177952)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/XSSAuditor.cpp        2015-01-06 07:46:07 UTC (rev 177951)
+++ trunk/Source/WebCore/html/parser/XSSAuditor.cpp        2015-01-06 08:06:09 UTC (rev 177952)
</span><span class="lines">@@ -388,8 +388,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_scriptTagNestingLevel);
</span><span class="cx">     if (isContainedInRequest(m_cachedDecodedSnippet) &amp;&amp; isContainedInRequest(decodedSnippetForJavaScript(request))) {
</span><del>-        request.token.eraseCharacters();
-        request.token.appendToCharacter(' '); // Technically, character tokens can't be empty.
</del><ins>+        request.token.clear();
+        LChar space = ' ';
+        request.token.appendToCharacter(space); // Technically, character tokens can't be empty.
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="lines">@@ -570,12 +571,12 @@
</span><span class="cx"> 
</span><span class="cx"> String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest&amp; request, const HTMLToken::Attribute&amp; attribute, AttributeKind treatment)
</span><span class="cx"> {
</span><del>-    // The range doesn't inlcude the character which terminates the value. So,
</del><ins>+    // The range doesn't include the character which terminates the value. So,
</ins><span class="cx">     // for an input of |name=&quot;value&quot;|, the snippet is |name=&quot;value|. For an
</span><span class="cx">     // unquoted input of |name=value |, the snippet is |name=value|.
</span><span class="cx">     // FIXME: We should grab one character before the name also.
</span><del>-    int start = attribute.nameRange.start - request.token.startIndex();
-    int end = attribute.valueRange.end - request.token.startIndex();
</del><ins>+    unsigned start = attribute.nameRange.start;
+    unsigned end = attribute.valueRange.end;
</ins><span class="cx">     String decodedSnippet = fullyDecodeString(request.sourceTracker.sourceForToken(request.token).substring(start, end - start), m_encoding);
</span><span class="cx">     decodedSnippet.truncate(kMaximumFragmentLengthTarget);
</span><span class="cx">     if (treatment == SrcLikeAttribute) {
</span></span></pre>
</div>
</div>

</body>
</html>