diff --git a/content/html/document/src/nsHTMLContentSink.cpp b/content/html/document/src/nsHTMLContentSink.cpp
index ad406bc30eab..1bf4ae87c009 100644
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -428,6 +428,12 @@ public:
void ScrollToRef(PRBool aReallyScroll);
void TryToScrollToRef();
+ /**
+ * AddBaseTagInfo adds the "current" base URI and target to the content node
+ * in the form of bogo-attributes. This MUST be called before attributes are
+ * added to the content node, since the way URI attributes are treated may
+ * depend on the value of the base URI
+ */
void AddBaseTagInfo(nsIHTMLContent* aContent);
nsresult ProcessLinkHeader(nsIHTMLContent* aElement,
@@ -448,7 +454,6 @@ public:
nsresult RefreshIfEnabled(nsIViewManager* vm);
// Routines for tags that require special handling
- nsresult ProcessATag(const nsIParserNode& aNode, nsIHTMLContent* aContent);
nsresult ProcessAREATag(const nsIParserNode& aNode);
nsresult ProcessBASETag(const nsIParserNode& aNode);
nsresult ProcessLINKTag(const nsIParserNode& aNode);
@@ -1576,6 +1581,36 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
mStack[mStackPos].mInsertionPoint = -1;
content->SetDocument(mSink->mDocument, PR_FALSE, PR_TRUE);
+ // Make sure to add base tag info, if needed, before setting any other
+ // attributes -- what URI attrs do will depend on the base URI. Only do this
+ // for elements that have useful URI attributes.
+ // See bug 18478 and bug 30617 for why we need to do this.
+ switch (nodeType) {
+ // Containers with "href="
+ case eHTMLTag_a:
+ case eHTMLTag_map:
+
+ // Containers with "action="
+ case eHTMLTag_form:
+
+ // Containers with "data="
+ case eHTMLTag_object:
+
+ // Containers with "background="
+ case eHTMLTag_table:
+ case eHTMLTag_thead:
+ case eHTMLTag_tbody:
+ case eHTMLTag_tfoot:
+ case eHTMLTag_tr:
+ case eHTMLTag_td:
+ case eHTMLTag_th:
+ mSink->AddBaseTagInfo(content);
+
+ break;
+ default:
+ break;
+ }
+
rv = mSink->AddAttributes(aNode, content);
if (mPreAppend) {
@@ -1613,22 +1648,7 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
mSink->mInsideNoXXXTag++;
break;
- case eHTMLTag_a:
- mSink->ProcessATag(aNode, content);
- break;
- case eHTMLTag_form:
- case eHTMLTag_table:
- case eHTMLTag_thead:
- case eHTMLTag_tbody:
- case eHTMLTag_tfoot:
- case eHTMLTag_tr:
- case eHTMLTag_td:
- case eHTMLTag_th:
- // XXX if navigator_quirks_mode (only body in html supports background)
- mSink->AddBaseTagInfo(content);
-
- break;
case eHTMLTag_map:
mSink->ProcessMAPTag(aNode, content);
@@ -1809,14 +1829,16 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
// Set the content's document
content->SetDocument(mSink->mDocument, PR_FALSE, PR_TRUE);
- rv = mSink->AddAttributes(aNode, content);
-
- NS_ENSURE_SUCCESS(rv, rv);
-
+ // Make sure to add base tag info, if needed, before setting any other
+ // attributes -- what URI attrs do will depend on the base URI. Only do
+ // this for elements that have useful URI attributes.
+ // See bug 18478 and bug 30617 for why we need to do this.
switch (nodeType) {
- case eHTMLTag_img: // elements with 'SRC='
+ // leaves with 'SRC='
+ case eHTMLTag_img:
case eHTMLTag_frame:
case eHTMLTag_input:
+ case eHTMLTag_embed:
mSink->AddBaseTagInfo(content);
break;
@@ -1824,6 +1846,10 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
break;
}
+ rv = mSink->AddAttributes(aNode, content);
+
+ NS_ENSURE_SUCCESS(rv, rv);
+
// Add new leaf to its parent
AddLeaf(content);
@@ -4380,15 +4406,6 @@ HTMLContentSink::AddBaseTagInfo(nsIHTMLContent* aContent)
}
}
-nsresult
-HTMLContentSink::ProcessATag(const nsIParserNode& aNode,
- nsIHTMLContent* aContent)
-{
- AddBaseTagInfo(aContent);
-
- return NS_OK;
-}
-
nsresult
HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode)
{
@@ -4405,13 +4422,19 @@ HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode)
return rv;
}
- // Set the content's document and attributes
+ // Set the content's document
area->SetDocument(mDocument, PR_FALSE, PR_TRUE);
+
+ // Make sure to add base tag info, if needed, before setting any other
+ // attributes -- what URI attrs do will depend on the base URI. Only do this
+ // for elements that have useful URI attributes.
+ // See bug 18478 and bug 30617 for why we need to do this.
+ AddBaseTagInfo(area);
+
+ // Set the content's attributes
rv = AddAttributes(aNode, area);
NS_ENSURE_SUCCESS(rv, rv);
- AddBaseTagInfo(area); // basehref or basetarget. Fix. Bug: 30617
-
// Add AREA object to the current map
mCurrentMap->AppendChildTo(area, PR_FALSE, PR_FALSE);
@@ -5025,11 +5048,6 @@ HTMLContentSink::ProcessMAPTag(const nsIParserNode& aNode,
// match a 4.x quirk, but it proved too quirky for us, and IE never
// did that. See bug 79738 for details.
- // This is for nav4 compatibility. (Bug 18478) The base tag should
- // only appear in the head, but nav4 allows the base tag in the body
- // as well.
- AddBaseTagInfo(aContent);
-
// Don't need to add the map to the document here anymore.
// The map adds itself