Title: [143020] trunk/Source/WebCore
Revision
143020
Author
[email protected]
Date
2013-02-15 11:11:38 -0800 (Fri, 15 Feb 2013)

Log Message

TokenPreloadScanner should be able to scan CompactHTMLTokens
https://bugs.webkit.org/show_bug.cgi?id=109861

Reviewed by Eric Seidel.

This patch moves the main scanning logic for the TokenPreloadScanner to
a templated scanCommon routine that can scan either an HTMLToken or a
CompactHTMLToken. This patch will let the BackgroundHTMLParser preload
scan its CompactHTMLTokens.

* html/parser/CSSPreloadScanner.cpp:
(WebCore):
(WebCore::CSSPreloadScanner::scanCommon):
(WebCore::CSSPreloadScanner::scan):
* html/parser/CSSPreloadScanner.h:
(CSSPreloadScanner):
    - Tweak the CSSPreloadScanner API slightly to make it easier to
      call from templated code.
* html/parser/HTMLPreloadScanner.cpp:
(WebCore::TokenPreloadScanner::tagIdFor):
(WebCore):
(WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
(TokenPreloadScanner::StartTagScanner):
(WebCore::TokenPreloadScanner::scan):
(WebCore::TokenPreloadScanner::scanCommon):
(WebCore::TokenPreloadScanner::updatePredictedBaseURL):
(WebCore::HTMLPreloadScanner::scan):
* html/parser/HTMLPreloadScanner.h:
(TokenPreloadScanner):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (143019 => 143020)


--- trunk/Source/WebCore/ChangeLog	2013-02-15 19:06:30 UTC (rev 143019)
+++ trunk/Source/WebCore/ChangeLog	2013-02-15 19:11:38 UTC (rev 143020)
@@ -1,3 +1,35 @@
+2013-02-15  Adam Barth  <[email protected]>
+
+        TokenPreloadScanner should be able to scan CompactHTMLTokens
+        https://bugs.webkit.org/show_bug.cgi?id=109861
+
+        Reviewed by Eric Seidel.
+
+        This patch moves the main scanning logic for the TokenPreloadScanner to
+        a templated scanCommon routine that can scan either an HTMLToken or a
+        CompactHTMLToken. This patch will let the BackgroundHTMLParser preload
+        scan its CompactHTMLTokens.
+
+        * html/parser/CSSPreloadScanner.cpp:
+        (WebCore):
+        (WebCore::CSSPreloadScanner::scanCommon):
+        (WebCore::CSSPreloadScanner::scan):
+        * html/parser/CSSPreloadScanner.h:
+        (CSSPreloadScanner):
+            - Tweak the CSSPreloadScanner API slightly to make it easier to
+              call from templated code.
+        * html/parser/HTMLPreloadScanner.cpp:
+        (WebCore::TokenPreloadScanner::tagIdFor):
+        (WebCore):
+        (WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
+        (TokenPreloadScanner::StartTagScanner):
+        (WebCore::TokenPreloadScanner::scan):
+        (WebCore::TokenPreloadScanner::scanCommon):
+        (WebCore::TokenPreloadScanner::updatePredictedBaseURL):
+        (WebCore::HTMLPreloadScanner::scan):
+        * html/parser/HTMLPreloadScanner.h:
+        (TokenPreloadScanner):
+
 2013-02-15  Alexis Menard  <[email protected]>
 
         WebKit shouldn't accept "none, none" in transition shorthand property.

Modified: trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp (143019 => 143020)


--- trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp	2013-02-15 19:06:30 UTC (rev 143019)
+++ trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp	2013-02-15 19:11:38 UTC (rev 143020)
@@ -50,22 +50,31 @@
     m_ruleValue.clear();
 }
 
-void CSSPreloadScanner::scan(const UChar* begin, const UChar* end, Vector<OwnPtr<PreloadRequest> >& requests)
+template<typename Char>
+void CSSPreloadScanner::scanCommon(const Char* begin, const Char* end, Vector<OwnPtr<PreloadRequest> >& requests)
 {
     m_requests = &requests;
-    for (const UChar* it = begin; it != end && m_state != DoneParsingImportRules; ++it)
+    for (const Char* it = begin; it != end && m_state != DoneParsingImportRules; ++it)
         tokenize(*it);
     m_requests = 0;
 }
 
-void CSSPreloadScanner::scan(const LChar* begin, const LChar* end, Vector<OwnPtr<PreloadRequest> >& requests)
+void CSSPreloadScanner::scan(const HTMLToken::DataVector& data, Vector<OwnPtr<PreloadRequest> >& requests)
 {
-    m_requests = &requests;
-    for (const LChar* it = begin; it != end && m_state != DoneParsingImportRules; ++it)
-        tokenize(*it);
-    m_requests = 0;
+    scanCommon(data.data(), data.data() + data.size(), requests);
 }
 
+void CSSPreloadScanner::scan(const String& data, Vector<OwnPtr<PreloadRequest> >& requests)
+{
+    if (data.is8Bit()) {
+        const LChar* begin = data.characters8();
+        scanCommon(begin, begin + data.length(), requests);
+        return;
+    }
+    const UChar* begin = data.characters16();
+    scanCommon(begin, begin + data.length(), requests);
+}
+
 inline void CSSPreloadScanner::tokenize(UChar c)
 {
     // We are just interested in @import rules, no need for real tokenization here

Modified: trunk/Source/WebCore/html/parser/CSSPreloadScanner.h (143019 => 143020)


--- trunk/Source/WebCore/html/parser/CSSPreloadScanner.h	2013-02-15 19:06:30 UTC (rev 143019)
+++ trunk/Source/WebCore/html/parser/CSSPreloadScanner.h	2013-02-15 19:11:38 UTC (rev 143020)
@@ -28,6 +28,7 @@
 #define CSSPreloadScanner_h
 
 #include "HTMLResourcePreloader.h"
+#include "HTMLToken.h"
 #include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
@@ -40,8 +41,8 @@
 
     void reset();
 
-    void scan(const UChar* begin, const UChar* end, Vector<OwnPtr<PreloadRequest> >&);
-    void scan(const LChar* begin, const LChar* end, Vector<OwnPtr<PreloadRequest> >&);
+    void scan(const HTMLToken::DataVector&, Vector<OwnPtr<PreloadRequest> >&);
+    void scan(const String&, Vector<OwnPtr<PreloadRequest> >&);
 
 private:
     enum State {
@@ -57,6 +58,9 @@
         DoneParsingImportRules,
     };
 
+    template<typename Char>
+    void scanCommon(const Char* begin, const Char* end, Vector<OwnPtr<PreloadRequest> >&);
+
     inline void tokenize(UChar);
     void emitRule();
 

Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp (143019 => 143020)


--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp	2013-02-15 19:06:30 UTC (rev 143019)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp	2013-02-15 19:11:38 UTC (rev 143020)
@@ -43,18 +43,9 @@
 
 using namespace HTMLNames;
 
-static bool isStartTag(HTMLToken::Type type)
+TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVector& data)
 {
-    return type == HTMLToken::StartTag;
-}
-
-static bool isStartOrEndTag(HTMLToken::Type type)
-{
-    return type == HTMLToken::EndTag || isStartTag(type);
-}
-
-TokenPreloadScanner::TagId TokenPreloadScanner::identifierFor(const AtomicString& tagName)
-{
+    AtomicString tagName(data);
     if (tagName == imgTag)
         return ImgTagId;
     if (tagName == inputTag)
@@ -72,6 +63,25 @@
     return UnknownTagId;
 }
 
+TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const String& tagName)
+{
+    if (threadSafeMatch(tagName, imgTag))
+        return ImgTagId;
+    if (threadSafeMatch(tagName, inputTag))
+        return InputTagId;
+    if (threadSafeMatch(tagName, linkTag))
+        return LinkTagId;
+    if (threadSafeMatch(tagName, scriptTag))
+        return ScriptTagId;
+    if (threadSafeMatch(tagName, styleTag))
+        return StyleTagId;
+    if (threadSafeMatch(tagName, baseTag))
+        return BaseTagId;
+    if (threadSafeMatch(tagName, templateTag))
+        return TemplateTagId;
+    return UnknownTagId;
+}
+
 String TokenPreloadScanner::inititatorFor(TagId tagId)
 {
     switch (tagId) {
@@ -107,10 +117,8 @@
     void processAttributes(const HTMLToken::AttributeList& attributes)
     {
         ASSERT(isMainThread());
-
         if (m_tagId >= UnknownTagId)
             return;
-
         for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
             AtomicString attributeName(iter->name);
             String attributeValue = StringImpl::create8BitIfPossible(iter->value);
@@ -118,6 +126,16 @@
         }
     }
 
+#if ENABLE(THREADED_HTML_PARSER)
+    void processAttributes(const Vector<CompactAttribute>& attributes)
+    {
+        if (m_tagId >= UnknownTagId)
+            return;
+        for (Vector<CompactAttribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
+            processAttribute(iter->name(), iter->value());
+    }
+#endif
+
     PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL)
     {
         if (!shouldPreload())
@@ -244,45 +262,84 @@
 {
 }
 
-#if ENABLE(TEMPLATE_ELEMENT)
-bool TokenPreloadScanner::processPossibleTemplateTag(TagId tagId, HTMLToken::Type type)
+void TokenPreloadScanner::scan(const HTMLToken& token, Vector<OwnPtr<PreloadRequest> >& requests)
 {
-    if (isStartOrEndTag(type) && tagId == TemplateTagId) {
-        if (isStartTag(type))
-            m_templateCount++;
-        else
-            m_templateCount--;
-        return true; // Twas our token.
-    }
-    // If we're in a template we "consume" all tokens.
-    return m_templateCount > 0;
+    scanCommon(token, requests);
 }
+
+#if ENABLE(THREADED_HTML_PARSER)
+void TokenPreloadScanner::scan(const CompactHTMLToken& token, Vector<OwnPtr<PreloadRequest> >& requests)
+{
+    scanCommon(token, requests);
+}
 #endif
 
-bool TokenPreloadScanner::processPossibleStyleTag(TagId tagId, HTMLToken::Type type)
+template<typename Token>
+void TokenPreloadScanner::scanCommon(const Token& token, Vector<OwnPtr<PreloadRequest> >& requests)
 {
-    ASSERT(isStartOrEndTag(type));
-    if (tagId != StyleTagId)
-        return false;
+    switch (token.type()) {
+    case HTMLToken::Character: {
+        if (!m_inStyle)
+            return;
+        m_cssScanner.scan(token.data(), requests);
+        return;
+    }
+    case HTMLToken::EndTag: {
+        TagId tagId = tagIdFor(token.data());
+#if ENABLE(TEMPLATE_ELEMENT)
+        if (tagId == TemplateTagId) {
+            if (m_templateCount)
+                --m_templateCount;
+            return;
+        }
+#endif
+        if (tagId == StyleTagId) {
+            if (m_inStyle)
+                m_cssScanner.reset();
+            m_inStyle = false;
+        }
+        return;
+    }
+    case HTMLToken::StartTag: {
+#if ENABLE(TEMPLATE_ELEMENT)
+        if (m_templateCount)
+            return;
+#endif
+        TagId tagId = tagIdFor(token.data());
+#if ENABLE(TEMPLATE_ELEMENT)
+        if (tagId == TemplateTagId) {
+            ++m_templateCount;
+            return;
+        }
+#endif
+        if (tagId == StyleTagId) {
+            m_inStyle = true;
+            return;
+        }
+        if (tagId == BaseTagId) {
+            // The first <base> element is the one that wins.
+            if (!m_predictedBaseElementURL.isEmpty())
+                return;
+            updatePredictedBaseURL(token);
+            return;
+        }
 
-    m_inStyle = isStartTag(type);
-
-    if (!m_inStyle)
-        m_cssScanner.reset();
-
-    return true;
+        StartTagScanner scanner(tagId);
+        scanner.processAttributes(token.attributes());
+        OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL);
+        if (request)
+            requests.append(request.release());
+        return;
+    }
+    default: {
+        return;
+    }
+    }
 }
 
-bool TokenPreloadScanner::processPossibleBaseTag(TagId tagId, const HTMLToken& token)
+void TokenPreloadScanner::updatePredictedBaseURL(const HTMLToken& token)
 {
-    ASSERT(isStartTag(token.type()));
-    if (tagId != BaseTagId)
-        return false;
-
-    // The first <base> element is the one that wins.
-    if (!m_predictedBaseElementURL.isEmpty())
-        return true;
-
+    ASSERT(m_predictedBaseElementURL.isEmpty());
     for (HTMLToken::AttributeList::const_iterator iter = token.attributes().begin(); iter != token.attributes().end(); ++iter) {
         AtomicString attributeName(iter->name);
         if (attributeName == hrefAttr) {
@@ -291,43 +348,16 @@
             break;
         }
     }
-    return true;
 }
 
-void TokenPreloadScanner::scan(const HTMLToken& token, Vector<OwnPtr<PreloadRequest> >& requests)
+#if ENABLE(THREADED_HTML_PARSER)
+void TokenPreloadScanner::updatePredictedBaseURL(const CompactHTMLToken& token)
 {
-    // <style> is the only place we search for urls in non-start/end-tag tokens.
-    if (m_inStyle) {
-        if (token.type() != HTMLToken::Character)
-            return;
-        const HTMLToken::DataVector& characters = token.characters();
-        return m_cssScanner.scan(characters.begin(), characters.end(), requests);
-    }
-
-    if (!isStartOrEndTag(token.type()))
-        return;
-
-    AtomicString tagName(token.name());
-    TagId tagId = identifierFor(tagName);
-
-#if ENABLE(TEMPLATE_ELEMENT)
-    if (processPossibleTemplateTag(tagId, token.type()))
-        return;
+    ASSERT(m_predictedBaseElementURL.isEmpty());
+    m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(token.getAttributeItem(hrefAttr)->value()));
+}
 #endif
-    if (processPossibleStyleTag(tagId, token.type()))
-        return;
-    if (!isStartTag(token.type()))
-        return;
-    if (processPossibleBaseTag(tagId, token))
-        return;
 
-    StartTagScanner scanner(tagId);
-    scanner.processAttributes(token.attributes());
-    OwnPtr<PreloadRequest> request =  scanner.createPreloadRequest(m_predictedBaseElementURL);
-    if (request)
-        requests.append(request.release());
-}
-
 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const KURL& documentURL)
     : m_scanner(documentURL)
     , m_tokenizer(HTMLTokenizer::create(options))
@@ -353,7 +383,7 @@
 
     Vector<OwnPtr<PreloadRequest> > requests;
     while (m_tokenizer->nextToken(m_source, m_token)) {
-        if (isStartTag(m_token.type()))
+        if (m_token.type() == HTMLToken::StartTag)
             m_tokenizer->updateStateFor(AtomicString(m_token.name()));
         m_scanner.scan(m_token, requests);
         m_token.clear();

Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h (143019 => 143020)


--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h	2013-02-15 19:06:30 UTC (rev 143019)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h	2013-02-15 19:11:38 UTC (rev 143020)
@@ -28,6 +28,7 @@
 #define HTMLPreloadScanner_h
 
 #include "CSSPreloadScanner.h"
+#include "CompactHTMLToken.h"
 #include "HTMLToken.h"
 #include "SegmentedString.h"
 
@@ -44,6 +45,9 @@
     ~TokenPreloadScanner();
 
     void scan(const HTMLToken&, Vector<OwnPtr<PreloadRequest> >& requests);
+#if ENABLE(THREADED_HTML_PARSER)
+    void scan(const CompactHTMLToken&, Vector<OwnPtr<PreloadRequest> >& requests);
+#endif
 
     void setPredictedBaseElementURL(const KURL& url) { m_predictedBaseElementURL = url; }
 
@@ -64,16 +68,19 @@
 
     class StartTagScanner;
 
-    static TagId identifierFor(const AtomicString& tagName);
+    template<typename Token>
+    inline void scanCommon(const Token&, Vector<OwnPtr<PreloadRequest> >& requests);
+
+    static TagId tagIdFor(const HTMLToken::DataVector&);
+    static TagId tagIdFor(const String&);
+
     static String inititatorFor(TagId);
 
-#if ENABLE(TEMPLATE_ELEMENT)
-    bool processPossibleTemplateTag(TagId, HTMLToken::Type);
+    void updatePredictedBaseURL(const HTMLToken&);
+#if ENABLE(THREADED_HTML_PARSER)
+    void updatePredictedBaseURL(const CompactHTMLToken&);
 #endif
 
-    bool processPossibleStyleTag(TagId, HTMLToken::Type);
-    bool processPossibleBaseTag(TagId, const HTMLToken&);
-
     CSSPreloadScanner m_cssScanner;
     KURL m_documentURL;
     KURL m_predictedBaseElementURL;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to