Title: [106426] trunk
Revision
106426
Author
[email protected]
Date
2012-01-31 20:07:52 -0800 (Tue, 31 Jan 2012)

Log Message

HTMLPreloadScanner should understand the <base> element
https://bugs.webkit.org/show_bug.cgi?id=77231

Reviewed by Eric Seidel.

Source/WebCore:

Previously, the HTMLPreloadScanner would ignore the <base> element when
preloading resources.  If there was a <base> tag, this could cause the
preload scanner to make a bunch of useless requests.

This patch teaches the preload scanner to use <base> tags to better
predict which URLs will be used by the document.

Tests: fast/preloader/first-base-tag-scanned-wins.html
       fast/preloader/first-base-tag-wins.html
       fast/preloader/understands-base-tag.html

* dom/Document.cpp:
(WebCore::Document::completeURL):
(WebCore):
* dom/Document.h:
(Document):
(WebCore::Document::baseElementURL):
* html/parser/HTMLPreloadScanner.cpp:
(WebCore::HTMLNames::PreloadTask::PreloadTask):
(WebCore::HTMLNames::PreloadTask::processAttributes):
(WebCore::HTMLNames::PreloadTask::preload):
(WebCore::HTMLNames::PreloadTask::baseElementHref):
(PreloadTask):
(WebCore::HTMLPreloadScanner::scan):
(WebCore::HTMLPreloadScanner::processToken):
(WebCore::HTMLPreloadScanner::updatePredictedBaseElementURL):
(WebCore):
* html/parser/HTMLPreloadScanner.h:
(HTMLPreloadScanner):

LayoutTests:

These tests ensure that we understand the <base> element and that we
understand that the first <base> element is the one that maters.

* fast/preloader/first-base-tag-scanned-wins-expected.txt: Added.
* fast/preloader/first-base-tag-scanned-wins.html: Added.
* fast/preloader/first-base-tag-wins-expected.txt: Added.
* fast/preloader/first-base-tag-wins.html: Added.
* fast/preloader/resources/base-image1.png: Copied from LayoutTests/fast/preloader/resources/image1.png.
* fast/preloader/resources/base-image2.png: Copied from LayoutTests/fast/preloader/resources/image1.png.
* fast/preloader/resources/base-image3.png: Copied from LayoutTests/fast/preloader/resources/image1.png.
* fast/preloader/understands-base-tag-expected.txt: Added.
* fast/preloader/understands-base-tag.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (106425 => 106426)


--- trunk/LayoutTests/ChangeLog	2012-02-01 03:51:23 UTC (rev 106425)
+++ trunk/LayoutTests/ChangeLog	2012-02-01 04:07:52 UTC (rev 106426)
@@ -1,3 +1,23 @@
+2012-01-31  Adam Barth  <[email protected]>
+
+        HTMLPreloadScanner should understand the <base> element
+        https://bugs.webkit.org/show_bug.cgi?id=77231
+
+        Reviewed by Eric Seidel.
+
+        These tests ensure that we understand the <base> element and that we
+        understand that the first <base> element is the one that maters.
+
+        * fast/preloader/first-base-tag-scanned-wins-expected.txt: Added.
+        * fast/preloader/first-base-tag-scanned-wins.html: Added.
+        * fast/preloader/first-base-tag-wins-expected.txt: Added.
+        * fast/preloader/first-base-tag-wins.html: Added.
+        * fast/preloader/resources/base-image1.png: Copied from LayoutTests/fast/preloader/resources/image1.png.
+        * fast/preloader/resources/base-image2.png: Copied from LayoutTests/fast/preloader/resources/image1.png.
+        * fast/preloader/resources/base-image3.png: Copied from LayoutTests/fast/preloader/resources/image1.png.
+        * fast/preloader/understands-base-tag-expected.txt: Added.
+        * fast/preloader/understands-base-tag.html: Added.
+
 2012-01-31  Adam Klein  <[email protected]>
 
         ProcessingInstruction should not be a ContainerNode

Added: trunk/LayoutTests/fast/preloader/first-base-tag-scanned-wins-expected.txt (0 => 106426)


--- trunk/LayoutTests/fast/preloader/first-base-tag-scanned-wins-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/preloader/first-base-tag-scanned-wins-expected.txt	2012-02-01 04:07:52 UTC (rev 106426)
@@ -0,0 +1,7 @@
+base-image3.png has MIME type image/png
+This test requires DumpRenderTree to see the log of what resources are loaded.
+
+<base href=""
+<base href=""
+<img src=""
+

Added: trunk/LayoutTests/fast/preloader/first-base-tag-scanned-wins.html (0 => 106426)


--- trunk/LayoutTests/fast/preloader/first-base-tag-scanned-wins.html	                        (rev 0)
+++ trunk/LayoutTests/fast/preloader/first-base-tag-scanned-wins.html	2012-02-01 04:07:52 UTC (rev 106426)
@@ -0,0 +1,13 @@
+<body>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpResourceResponseMIMETypes();
+}
+</script>
+This test requires DumpRenderTree to see the log of what resources are loaded.
+<script src=""
+<script>document.write("<plaintext>");</script>
+<base href=""
+<base href=""
+<img src=""

Added: trunk/LayoutTests/fast/preloader/first-base-tag-wins-expected.txt (0 => 106426)


--- trunk/LayoutTests/fast/preloader/first-base-tag-wins-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/preloader/first-base-tag-wins-expected.txt	2012-02-01 04:07:52 UTC (rev 106426)
@@ -0,0 +1,6 @@
+base-image2.png has MIME type image/png
+This test requires DumpRenderTree to see the log of what resources are loaded.
+
+<base href=""
+<img src=""
+

Added: trunk/LayoutTests/fast/preloader/first-base-tag-wins.html (0 => 106426)


--- trunk/LayoutTests/fast/preloader/first-base-tag-wins.html	                        (rev 0)
+++ trunk/LayoutTests/fast/preloader/first-base-tag-wins.html	2012-02-01 04:07:52 UTC (rev 106426)
@@ -0,0 +1,13 @@
+<body>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpResourceResponseMIMETypes();
+}
+</script>
+<base href=""
+This test requires DumpRenderTree to see the log of what resources are loaded.
+<script src=""
+<script>document.write("<plaintext>");</script>
+<base href=""
+<img src=""

Added: trunk/LayoutTests/fast/preloader/resources/base-image1.png ( => )


Added: trunk/LayoutTests/fast/preloader/resources/base-image2.png
===================================================================

Added: trunk/LayoutTests/fast/preloader/resources/base-image3.png ( => )


Added: trunk/LayoutTests/fast/preloader/understands-base-tag-expected.txt
===================================================================
--- trunk/LayoutTests/fast/preloader/understands-base-tag-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/preloader/understands-base-tag-expected.txt	2012-02-01 04:07:52 UTC (rev 106426)
@@ -0,0 +1,6 @@
+base-image1.png has MIME type image/png
+This test requires DumpRenderTree to see the log of what resources are loaded.
+
+<base href=""
+<img src=""
+

Added: trunk/LayoutTests/fast/preloader/understands-base-tag.html (0 => 106426)


--- trunk/LayoutTests/fast/preloader/understands-base-tag.html	                        (rev 0)
+++ trunk/LayoutTests/fast/preloader/understands-base-tag.html	2012-02-01 04:07:52 UTC (rev 106426)
@@ -0,0 +1,12 @@
+<body>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpResourceResponseMIMETypes();
+}
+</script>
+This test requires DumpRenderTree to see the log of what resources are loaded.
+<script src=""
+<script>document.write("<plaintext>");</script>
+<base href=""
+<img src=""

Modified: trunk/Source/WebCore/ChangeLog (106425 => 106426)


--- trunk/Source/WebCore/ChangeLog	2012-02-01 03:51:23 UTC (rev 106425)
+++ trunk/Source/WebCore/ChangeLog	2012-02-01 04:07:52 UTC (rev 106426)
@@ -1,3 +1,40 @@
+2012-01-31  Adam Barth  <[email protected]>
+
+        HTMLPreloadScanner should understand the <base> element
+        https://bugs.webkit.org/show_bug.cgi?id=77231
+
+        Reviewed by Eric Seidel.
+
+        Previously, the HTMLPreloadScanner would ignore the <base> element when
+        preloading resources.  If there was a <base> tag, this could cause the
+        preload scanner to make a bunch of useless requests.
+
+        This patch teaches the preload scanner to use <base> tags to better
+        predict which URLs will be used by the document.
+
+        Tests: fast/preloader/first-base-tag-scanned-wins.html
+               fast/preloader/first-base-tag-wins.html
+               fast/preloader/understands-base-tag.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::completeURL):
+        (WebCore):
+        * dom/Document.h:
+        (Document):
+        (WebCore::Document::baseElementURL):
+        * html/parser/HTMLPreloadScanner.cpp:
+        (WebCore::HTMLNames::PreloadTask::PreloadTask):
+        (WebCore::HTMLNames::PreloadTask::processAttributes):
+        (WebCore::HTMLNames::PreloadTask::preload):
+        (WebCore::HTMLNames::PreloadTask::baseElementHref):
+        (PreloadTask):
+        (WebCore::HTMLPreloadScanner::scan):
+        (WebCore::HTMLPreloadScanner::processToken):
+        (WebCore::HTMLPreloadScanner::updatePredictedBaseElementURL):
+        (WebCore):
+        * html/parser/HTMLPreloadScanner.h:
+        (HTMLPreloadScanner):
+
 2012-01-31  Raymond Liu  <[email protected]>
 
         Dynamic allocate AudioBus with required number of channels for AudioNodeInput

Modified: trunk/Source/WebCore/dom/Document.cpp (106425 => 106426)


--- trunk/Source/WebCore/dom/Document.cpp	2012-02-01 03:51:23 UTC (rev 106425)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-02-01 04:07:52 UTC (rev 106426)
@@ -4018,19 +4018,24 @@
     m_decoder = decoder;
 }
 
-KURL Document::completeURL(const String& url) const
+KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
 {
     // Always return a null URL when passed a null string.
     // FIXME: Should we change the KURL constructor to have this behavior?
     // See also [CSS]StyleSheet::completeURL(const String&)
     if (url.isNull())
         return KURL();
-    const KURL& baseURL = ((m_baseURL.isEmpty() || m_baseURL == blankURL()) && parentDocument()) ? parentDocument()->baseURL() : m_baseURL;
+    const KURL& baseURL = ((baseURLOverride.isEmpty() || baseURLOverride == blankURL()) && parentDocument()) ? parentDocument()->baseURL() : baseURLOverride;
     if (!m_decoder)
         return KURL(baseURL, url);
     return KURL(baseURL, url, m_decoder->encoding());
 }
 
+KURL Document::completeURL(const String& url) const
+{
+    return completeURL(url, m_baseURL);
+}
+
 void Document::setInPageCache(bool flag)
 {
     if (m_inPageCache == flag)

Modified: trunk/Source/WebCore/dom/Document.h (106425 => 106426)


--- trunk/Source/WebCore/dom/Document.h	2012-02-01 03:51:23 UTC (rev 106425)
+++ trunk/Source/WebCore/dom/Document.h	2012-02-01 04:07:52 UTC (rev 106426)
@@ -600,13 +600,17 @@
     const KURL& url() const { return m_url; }
     void setURL(const KURL&);
 
+    // To understand how these concepts relate to one another, please see the
+    // comments surrounding their declaration.
     const KURL& baseURL() const { return m_baseURL; }
     void setBaseURLOverride(const KURL&);
     const KURL& baseURLOverride() const { return m_baseURLOverride; }
+    const KURL& baseElementURL() const { return m_baseElementURL; }
     const String& baseTarget() const { return m_baseTarget; }
     void processBaseElement();
 
     KURL completeURL(const String&) const;
+    KURL completeURL(const String&, const KURL& baseURLOverride) const;
 
     virtual String userAgent(const KURL&) const;
 
@@ -1201,7 +1205,7 @@
     // Document URLs.
     KURL m_url; // Document.URL: The URL from which this document was retrieved.
     KURL m_baseURL; // Node.baseURI: The URL to use when resolving relative URLs.
-    KURL m_baseURLOverride; // An alternative base URL that takes precedence ove m_baseURL (but not m_baseElementURL).
+    KURL m_baseURLOverride; // An alternative base URL that takes precedence over m_baseURL (but not m_baseElementURL).
     KURL m_baseElementURL; // The URL set by the <base> element.
     KURL m_cookieURL; // The URL to use for cookie access.
     KURL m_firstPartyForCookies; // The policy URL for third-party cookie blocking.

Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp (106425 => 106426)


--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp	2012-02-01 03:51:23 UTC (rev 106425)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp	2012-02-01 04:07:52 UTC (rev 106426)
@@ -47,7 +47,7 @@
 
 class PreloadTask {
 public:
-    PreloadTask(const HTMLToken& token)
+    explicit PreloadTask(const HTMLToken& token)
         : m_tagName(token.name().data(), token.name().size())
         , m_linkIsStyleSheet(false)
         , m_linkMediaAttributeIsScreen(true)
@@ -61,7 +61,8 @@
         if (m_tagName != imgTag
             && m_tagName != inputTag
             && m_tagName != linkTag
-            && m_tagName != scriptTag)
+            && m_tagName != scriptTag
+            && m_tagName != baseTag)
             return;
 
         for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
@@ -87,6 +88,9 @@
                     setUrlToLoad(attributeValue);
                 else if (attributeName == typeAttr)
                     m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image());
+            } else if (m_tagName == baseTag) {
+                if (attributeName == hrefAttr)
+                    m_baseElementHref = stripLeadingAndTrailingHTMLSpaces(attributeValue);
             }
         }
     }
@@ -119,13 +123,13 @@
         m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue);
     }
 
-    void preload(Document* document, bool scanningBody)
+    void preload(Document* document, bool scanningBody, const KURL& baseURL)
     {
         if (m_urlToLoad.isEmpty())
             return;
 
         CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
-        ResourceRequest request = document->completeURL(m_urlToLoad);
+        ResourceRequest request = document->completeURL(m_urlToLoad, baseURL);
         if (m_tagName == scriptTag)
             cachedResourceLoader->preload(CachedResource::Script, request, m_charset, scanningBody);
         else if (m_tagName == imgTag || (m_tagName == inputTag && m_inputIsImage))
@@ -135,11 +139,13 @@
     }
 
     const AtomicString& tagName() const { return m_tagName; }
+    const String& baseElementHref() const { return m_baseElementHref; }
 
 private:
     AtomicString m_tagName;
     String m_urlToLoad;
     String m_charset;
+    String m_baseElementHref;
     bool m_linkIsStyleSheet;
     bool m_linkMediaAttributeIsScreen;
     bool m_inputIsImage;
@@ -163,6 +169,9 @@
 
 void HTMLPreloadScanner::scan()
 {
+    // When we start scanning, our best prediction of the baseElementURL is the real one!
+    m_predictedBaseElementURL = m_document->baseElementURL();
+
     // FIXME: We should save and re-use these tokens in HTMLDocumentParser if
     // the pending script doesn't end up calling document.write.
     while (m_tokenizer->nextToken(m_source, m_token)) {
@@ -194,7 +203,10 @@
     if (task.tagName() == styleTag)
         m_inStyle = true;
 
-    task.preload(m_document, scanningBody());
+    if (task.tagName() == baseTag)
+        updatePredictedBaseElementURL(KURL(m_document->url(), task.baseElementHref()));
+
+    task.preload(m_document, scanningBody(), m_predictedBaseElementURL.isEmpty() ? m_document->baseURL() : m_predictedBaseElementURL);
 }
 
 bool HTMLPreloadScanner::scanningBody() const
@@ -202,4 +214,12 @@
     return m_document->body() || m_bodySeen;
 }
 
+void HTMLPreloadScanner::updatePredictedBaseElementURL(const KURL& baseElementURL)
+{
+    // The first <base> element is the one that wins.
+    if (!m_predictedBaseElementURL.isEmpty())
+        return;
+    m_predictedBaseElementURL = baseElementURL;
 }
+
+}

Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h (106425 => 106426)


--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h	2012-02-01 03:51:23 UTC (rev 106425)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h	2012-02-01 04:07:52 UTC (rev 106426)
@@ -41,7 +41,7 @@
 class HTMLPreloadScanner {
     WTF_MAKE_NONCOPYABLE(HTMLPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
 public:
-    HTMLPreloadScanner(Document*);
+    explicit HTMLPreloadScanner(Document*);
 
     void appendToEnd(const SegmentedString&);
     void scan();
@@ -49,6 +49,7 @@
 private:
     void processToken();
     bool scanningBody() const;
+    void updatePredictedBaseElementURL(const KURL& baseElementURL);
 
     Document* m_document;
     SegmentedString m_source;
@@ -57,6 +58,7 @@
     HTMLToken m_token;
     bool m_bodySeen;
     bool m_inStyle;
+    KURL m_predictedBaseElementURL;
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to