Bug 1238804. Make <base> actually work in a srcdoc document. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 13 Jan 2016 21:36:24 -0500
changeset 279894 37067b8102be559525e0e7e95be28e98c2596f95
parent 279893 9bba3baa2ce769798c5e1d9196c8c443bd97c43b
child 279895 2e8e06c6d251bfacc87ca4677379452b72c76c63
push id70248
push userbzbarsky@mozilla.com
push dateThu, 14 Jan 2016 02:43:27 +0000
treeherdermozilla-inbound@6b1aff2a5757 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1238804
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1238804. Make <base> actually work in a srcdoc document. r=smaug
dom/base/nsIDocument.h
dom/html/HTMLSharedElement.cpp
testing/web-platform/tests/html/infrastructure/urls/terminology-0/document-base-url.html
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -344,27 +344,42 @@ public:
    */
   already_AddRefed<nsILoadGroup> GetDocumentLoadGroup() const
   {
     nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
     return group.forget();
   }
 
   /**
-   * Return the base URI for relative URIs in the document (the document uri
-   * unless it's overridden by SetBaseURI, HTML <base> tags, etc.).  The
-   * returned URI could be null if there is no document URI.  If the document
-   * is a srcdoc document, return the parent document's base URL.
+   * Return the fallback base URL for this document, as defined in the HTML
+   * specification.  Note that this can return null if there is no document URI.
+   *
+   * XXXbz: This doesn't implement the bits for about:blank yet.
    */
-  nsIURI* GetDocBaseURI() const
+  nsIURI* GetFallbackBaseURI() const
   {
     if (mIsSrcdocDocument && mParentDocument) {
       return mParentDocument->GetDocBaseURI();
     }
-    return mDocumentBaseURI ? mDocumentBaseURI : mDocumentURI;
+    return mDocumentURI;
+  }
+
+  /**
+   * Return the base URI for relative URIs in the document (the document uri
+   * unless it's overridden by SetBaseURI, HTML <base> tags, etc.).  The
+   * returned URI could be null if there is no document URI.  If the document is
+   * a srcdoc document and has no explicit base URL, return the parent
+   * document's base URL.
+   */
+  nsIURI* GetDocBaseURI() const
+  {
+    if (mDocumentBaseURI) {
+      return mDocumentBaseURI;
+    }
+    return GetFallbackBaseURI();
   }
   virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;
 
   virtual nsresult SetBaseURI(nsIURI* aURI) = 0;
 
   /**
    * Get/Set the base target of a link in a document.
    */
--- a/dom/html/HTMLSharedElement.cpp
+++ b/dom/html/HTMLSharedElement.cpp
@@ -159,24 +159,25 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocu
   for (nsIContent* child = aDocument->GetFirstChild(); child;
        child = child->GetNextNode()) {
     if (child->IsHTMLElement(nsGkAtoms::base) &&
         child->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
       if (aMustMatch && child != aMustMatch) {
         return;
       }
 
-      // Resolve the <base> element's href relative to our document URI
+      // Resolve the <base> element's href relative to our document's
+      // fallback base URI.
       nsAutoString href;
       child->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
 
       nsCOMPtr<nsIURI> newBaseURI;
       nsContentUtils::NewURIWithDocumentCharset(
         getter_AddRefs(newBaseURI), href, aDocument,
-        aDocument->GetDocumentURI());
+        aDocument->GetFallbackBaseURI());
 
       // Try to set our base URI.  If that fails, try to set base URI to null
       nsresult rv = aDocument->SetBaseURI(newBaseURI);
       aDocument->SetChromeXHRDocBaseURI(nullptr);
       if (NS_FAILED(rv)) {
         aDocument->SetBaseURI(nullptr);
       }
       return;
--- a/testing/web-platform/tests/html/infrastructure/urls/terminology-0/document-base-url.html
+++ b/testing/web-platform/tests/html/infrastructure/urls/terminology-0/document-base-url.html
@@ -72,10 +72,22 @@
       var iframe = document.createElement("iframe");
       iframe.onload = this.step_func_done(function () {
         assert_resolve_url(iframe.contentDocument, location.href.replace("/document-base-url.html", ""));
         assert_equals(iframe.contentDocument.baseURI, document.baseURI, "The document base URL should be the containing document's base URL.");
       });
       iframe.setAttribute("srcdoc", "<p>foobar</p>");
       document.body.appendChild(iframe);
     }, "The fallback base URL of an iframe srcdoc document is the document base URL of the document's browsing context's browsing context container's document.");
+
+    async_test(function () {
+      var iframe = document.createElement("iframe");
+      iframe.onload = this.step_func_done(function () {
+        var doc = iframe.contentDocument;
+        assert_resolve_url(doc, location.href.replace("/document-base-url.html", "/sub"));
+        assert_equals(doc.baseURI, document.baseURI.replace("/document-base-url.html", "/sub/"),
+                      "The srcdoc document's base URL should be set by the <base> tag.");
+      });
+      iframe.setAttribute("srcdoc", "<base href='sub/'><p>foobar</p>");
+      document.body.appendChild(iframe);
+    }, "The base URL of an iframe srcdoc document with a <base> tag should be set by that tag.");
   </script>
 </body>