From 24b255ef47f8764ef29d046dac37e57d29beac50 Mon Sep 17 00:00:00 2001 From: Jonas Sicking Date: Fri, 23 Apr 2010 09:10:07 -0700 Subject: [PATCH] Bug 515401: Make implementation of HTML5 compliant, and clean it up. r=benjamn a=dholbert --- content/base/public/nsIDocument.h | 25 +-- content/base/src/nsContentSink.cpp | 6 +- content/base/src/nsContentSink.h | 1 - content/base/src/nsDocument.cpp | 105 ++++------- content/base/src/nsDocument.h | 3 +- content/base/src/nsGkAtomList.h | 2 - content/base/test/Makefile.in | 1 + content/base/test/test_bug515401.html | 134 ++++++++++++++ .../html/content/src/nsGenericHTMLElement.cpp | 38 ---- .../html/content/src/nsGenericHTMLElement.h | 2 - .../html/content/src/nsHTMLSharedElement.cpp | 166 ++++++++---------- .../html/document/src/nsHTMLContentSink.cpp | 146 +-------------- .../src/nsHTMLFragmentContentSink.cpp | 104 +---------- content/xml/document/src/nsXMLContentSink.cpp | 37 +--- content/xml/document/src/nsXMLContentSink.h | 3 - content/xslt/src/xslt/txMozillaXMLOutput.cpp | 19 -- content/xslt/src/xslt/txMozillaXMLOutput.h | 2 - parser/html/nsHtml5Parser.cpp | 2 - parser/html/nsHtml5TreeBuilderCppSupplement.h | 6 - parser/html/nsHtml5TreeOpExecutor.cpp | 29 --- parser/html/nsHtml5TreeOpExecutor.h | 7 - parser/html/nsHtml5TreeOperation.cpp | 5 - parser/html/nsHtml5TreeOperation.h | 1 - 23 files changed, 253 insertions(+), 591 deletions(-) create mode 100644 content/base/test/test_bug515401.html diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 2c97ca00b230..cc67568e460b 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -115,8 +115,8 @@ class Link; } // namespace mozilla #define NS_IDOCUMENT_IID \ -{ 0x17e1c0ce, 0x3883, 0x4efc, \ - { 0xbf, 0xdf, 0x40, 0xa6, 0x26, 0x9f, 0xbd, 0x2c } } +{ 0x4a0c9bfa, 0xef60, 0x4bb2, \ + { 0x87, 0x5e, 0xac, 0xdb, 0xe8, 0xfe, 0xa1, 0xb5 } } // Flag for AddStyleSheet(). #define NS_STYLESHEET_FROM_CATALOG (1 << 0) @@ -249,8 +249,7 @@ public: /** * Get/Set the base target of a link in a document. */ - virtual void GetBaseTarget(nsAString &aBaseTarget) const = 0; - virtual void SetBaseTarget(const nsAString &aBaseTarget) = 0; + virtual void GetBaseTarget(nsAString &aBaseTarget) = 0; /** * Return a standard name for the document's character set. @@ -1328,24 +1327,6 @@ public: */ virtual PRInt32 GetDocumentState() = 0; - /** - * Gets the document's cached pointer to the first element in this - * document which has an href attribute. If the document doesn't contain any - * elements with an href, returns null. - */ - virtual nsIContent* GetFirstBaseNodeWithHref() = 0; - - /** - * Sets the document's cached pointer to the first element with an - * href attribute in this document and updates the document's base URI - * according to the element's href. - * - * If the given node is the same as the current first base node, this - * function still updates the document's base URI according to the node's - * href, if it changed. - */ - virtual nsresult SetFirstBaseNodeWithHref(nsIContent *node) = 0; - virtual nsISupports* GetCurrentContentSink() = 0; /** diff --git a/content/base/src/nsContentSink.cpp b/content/base/src/nsContentSink.cpp index f4cd4dff12c2..19fbf8e751d0 100644 --- a/content/base/src/nsContentSink.cpp +++ b/content/base/src/nsContentSink.cpp @@ -232,7 +232,6 @@ nsContentSink::Init(nsIDocument* aDoc, mDocument = aDoc; mDocumentURI = aURI; - mDocumentBaseURI = aURI; mDocShell = do_QueryInterface(aContainer); if (mDocShell) { PRUint32 loadType = 0; @@ -781,7 +780,8 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement, } nsCOMPtr url; - nsresult rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull, mDocumentBaseURI); + nsresult rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull, + mDocument->GetBaseURI()); if (NS_FAILED(rv)) { // The URI is bad, move along, don't propagate the error (for now) @@ -890,7 +890,7 @@ nsContentSink::PrefetchHref(const nsAString &aHref, nsCOMPtr uri; NS_NewURI(getter_AddRefs(uri), aHref, charset.IsEmpty() ? nsnull : PromiseFlatCString(charset).get(), - mDocumentBaseURI); + mDocument->GetBaseURI()); if (uri) { nsCOMPtr domNode = do_QueryInterface(aSource); prefetchService->PrefetchURI(uri, mDocumentURI, domNode, aExplicit); diff --git a/content/base/src/nsContentSink.h b/content/base/src/nsContentSink.h index c2d961f11249..1163a226a447 100644 --- a/content/base/src/nsContentSink.h +++ b/content/base/src/nsContentSink.h @@ -306,7 +306,6 @@ protected: nsCOMPtr mDocument; nsCOMPtr mParser; nsCOMPtr mDocumentURI; - nsCOMPtr mDocumentBaseURI; nsCOMPtr mDocShell; nsRefPtr mCSSLoader; nsRefPtr mNodeInfoManager; diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 38cdea795c35..7d05927dcf76 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -2913,48 +2913,45 @@ nsDocument::ReleaseCapture() nsresult nsDocument::SetBaseURI(nsIURI* aURI) { - nsresult rv = NS_OK; - - nsCOMPtr oldBase = nsIDocument::GetBaseURI(); - if (aURI) { - rv = nsContentUtils::GetSecurityManager()-> - CheckLoadURIWithPrincipal(NodePrincipal(), aURI, - nsIScriptSecurityManager::STANDARD); - if (NS_SUCCEEDED(rv)) { - mDocumentBaseURI = NS_TryToMakeImmutable(aURI); + if (!aURI && !mDocumentBaseURI) { + return NS_OK; + } + + // Don't do anything if the URI wasn't actually changed. + if (aURI && mDocumentBaseURI) { + PRBool equalBases = PR_FALSE; + mDocumentBaseURI->Equals(aURI, &equalBases); + if (equalBases) { + return NS_OK; } + } + + if (aURI) { + mDocumentBaseURI = NS_TryToMakeImmutable(aURI); } else { mDocumentBaseURI = nsnull; } + RefreshLinkHrefs(); - nsIURI* newBase = nsIDocument::GetBaseURI(); - PRBool equalBases = PR_FALSE; - if (oldBase && newBase) { - oldBase->Equals(newBase, &equalBases); - } - else { - equalBases = !oldBase && !newBase; - } - - // If the document's base URI has changed, we need to re-resolve all the - // cached link hrefs relative to the new base. - if (!equalBases) { - RefreshLinkHrefs(); - } - - return rv; + return NS_OK; } void -nsDocument::GetBaseTarget(nsAString &aBaseTarget) const +nsDocument::GetBaseTarget(nsAString &aBaseTarget) { - aBaseTarget.Assign(mBaseTarget); -} - -void -nsDocument::SetBaseTarget(const nsAString &aBaseTarget) -{ - mBaseTarget.Assign(aBaseTarget); + aBaseTarget.Truncate(); + nsIContent* head = GetHeadContent(); + if (!head) { + return; + } + + for (ChildIterator iter(head); !iter.IsDone(); iter.Next()) { + nsIContent* child = iter; + if (child->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && + child->GetAttr(kNameSpaceID_None, nsGkAtoms::target, aBaseTarget)) { + return; + } + } } void @@ -7572,48 +7569,6 @@ nsDocument::RefreshLinkHrefs() } } -nsIContent* -nsDocument::GetFirstBaseNodeWithHref() -{ - return mFirstBaseNodeWithHref; -} - -nsresult -nsDocument::SetFirstBaseNodeWithHref(nsIContent *elem) -{ - mFirstBaseNodeWithHref = elem; - - if (!elem) { - SetBaseURI(nsnull); - return NS_OK; - } - - NS_ASSERTION(elem->Tag() == nsGkAtoms::base, - "Setting base node to a non element?"); - NS_ASSERTION(elem->GetNameSpaceID() == kNameSpaceID_XHTML, - "Setting base node to a non XHTML element?"); - - nsIDocument* doc = elem->GetOwnerDoc(); - nsIURI* currentURI = nsIDocument::GetDocumentURI(); - - // Resolve the element's href relative to our current URI - nsAutoString href; - PRBool hasHref = elem->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href); - NS_ASSERTION(hasHref, - "Setting first base node to a node with no href attr?"); - - nsCOMPtr newBaseURI; - nsContentUtils::NewURIWithDocumentCharset( - getter_AddRefs(newBaseURI), href, doc, currentURI); - - // Try to set our base URI. If that fails, try to set our base URI to null. - nsresult rv = SetBaseURI(newBaseURI); - if (NS_FAILED(rv)) { - return SetBaseURI(nsnull); - } - return rv; -} - NS_IMETHODIMP nsDocument::GetScriptTypeID(PRUint32 *aScriptType) { diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 9549d7cd6f63..8aa646b4362d 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -544,8 +544,7 @@ public: /** * Get/Set the base target of a link in a document. */ - virtual void GetBaseTarget(nsAString &aBaseTarget) const; - virtual void SetBaseTarget(const nsAString &aBaseTarget); + virtual void GetBaseTarget(nsAString &aBaseTarget); /** * Return a standard name for the document's character set. This will diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 3c28dd338f8a..db20b4c034e0 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -423,8 +423,6 @@ GK_ATOM(href, "href") GK_ATOM(hreflang, "hreflang") GK_ATOM(hspace, "hspace") GK_ATOM(html, "html") -GK_ATOM(htmlBaseHref, "html-base-href") -GK_ATOM(htmlBaseTarget, "html-base-target") GK_ATOM(httpEquiv, "http-equiv") GK_ATOM(i, "i") GK_ATOM(id, "id") diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 23ce3e09ebfb..d6bae010e4a2 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -366,6 +366,7 @@ _TEST_FILES = test_bug5141.html \ test_bug545644.html \ test_bug545644.xhtml \ test_bug553896.xhtml \ + test_bug515401.html \ test_bug541937.html \ file_bug541937.html \ file_bug541937.xhtml \ diff --git a/content/base/test/test_bug515401.html b/content/base/test/test_bug515401.html new file mode 100644 index 000000000000..c34b655eb96f --- /dev/null +++ b/content/base/test/test_bug515401.html @@ -0,0 +1,134 @@ +< + + + + Test for Bug 515401 + + + + + + + + +Mozilla Bug 515401 +Simple link +Link with target + +

+
+
+
+ + + diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 389c22d01647..d4d4ae3e43f9 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -266,23 +266,6 @@ nsGenericHTMLElement::CopyInnerTo(nsGenericElement* aDst) const NS_ENSURE_SUCCESS(rv, rv); } - // Copy the baseuri and basetarget - void* prop; - if ((prop = GetProperty(nsGkAtoms::htmlBaseHref))) { - rv = aDst->SetProperty(nsGkAtoms::htmlBaseHref, prop, - nsPropertyTable::SupportsDtorFunc, PR_TRUE); - if (NS_SUCCEEDED(rv)) { - NS_ADDREF(static_cast(prop)); - } - } - if ((prop = GetProperty(nsGkAtoms::htmlBaseTarget))) { - rv = aDst->SetProperty(nsGkAtoms::htmlBaseTarget, prop, - nsPropertyTable::SupportsDtorFunc, PR_TRUE); - if (NS_SUCCEEDED(rv)) { - NS_ADDREF(static_cast(prop)); - } - } - return NS_OK; } @@ -1153,30 +1136,9 @@ nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, return NS_OK; } -already_AddRefed -nsGenericHTMLElement::GetBaseURI() const -{ - void* prop; - if (HasFlag(NODE_HAS_PROPERTIES) && (prop = GetProperty(nsGkAtoms::htmlBaseHref))) { - nsIURI* uri = static_cast(prop); - NS_ADDREF(uri); - - return uri; - } - - return nsGenericHTMLElementBase::GetBaseURI(); -} - void nsGenericHTMLElement::GetBaseTarget(nsAString& aBaseTarget) const { - void* prop; - if (HasFlag(NODE_HAS_PROPERTIES) && (prop = GetProperty(nsGkAtoms::htmlBaseTarget))) { - static_cast(prop)->ToString(aBaseTarget); - - return; - } - nsIDocument* ownerDoc = GetOwnerDoc(); if (ownerDoc) { ownerDoc->GetBaseTarget(aBaseTarget); diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index f9f918e71c58..1aad01f57d01 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -209,8 +209,6 @@ public: virtual void UpdateEditableState(); - already_AddRefed GetBaseURI() const; - virtual PRBool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, diff --git a/content/html/content/src/nsHTMLSharedElement.cpp b/content/html/content/src/nsHTMLSharedElement.cpp index 5e21cd83c975..4dfefce9c2d0 100644 --- a/content/html/content/src/nsHTMLSharedElement.cpp +++ b/content/html/content/src/nsHTMLSharedElement.cpp @@ -428,6 +428,43 @@ nsHTMLSharedElement::IsAttributeMapped(const nsIAtom* aAttribute) const return nsGenericHTMLElement::IsAttributeMapped(aAttribute); } +void +SetBaseURIUsingFirstBaseWithHref(nsIContent* aHead, nsIContent* aMustMatch) +{ + NS_PRECONDITION(aHead && aHead->GetOwnerDoc() && + aHead->GetOwnerDoc()->GetHeadContent() == aHead, + "Bad head"); + + nsIDocument* doc = aHead->GetOwnerDoc(); + + for (nsINode::ChildIterator iter(aHead); !iter.IsDone(); iter.Next()) { + nsIContent* child = iter; + if (child->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && + child->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) { + if (aMustMatch && child != aMustMatch) { + return; + } + + // Resolve the element's href relative to our document URI + nsAutoString href; + child->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href); + + nsCOMPtr newBaseURI; + nsContentUtils::NewURIWithDocumentCharset( + getter_AddRefs(newBaseURI), href, doc, doc->GetDocumentURI()); + + // Try to set our base URI. If that fails, try to set base URI to null + nsresult rv = doc->SetBaseURI(newBaseURI); + if (NS_FAILED(rv)) { + doc->SetBaseURI(nsnull); + } + return; + } + } + + doc->SetBaseURI(nsnull); +} + nsresult nsHTMLSharedElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix, const nsAString& aValue, @@ -435,64 +472,22 @@ nsHTMLSharedElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, { nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue, aNotify); + NS_ENSURE_SUCCESS(rv, rv); // If the href attribute of a tag is changing, we may need to update // the document's base URI, which will cause all the links on the page to be // re-resolved given the new base. - if (NS_SUCCEEDED(rv) && - mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && + nsIContent* head; + if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_None && - GetOwnerDoc() == GetCurrentDoc()) { - - nsIDocument* doc = GetCurrentDoc(); - NS_ENSURE_TRUE(doc, NS_OK); - - // We become the first base node with an href if - // * there's no other base node with an href, or - // * we come before the first base node with an href (this would happen - // if we didn't have an href before this call to SetAttr). - // Additionally, we call doc->SetFirstBaseNodeWithHref if we're the first - // base node with an href so the document updates its base URI with our new - // href. - nsIContent* firstBase = doc->GetFirstBaseNodeWithHref(); - if (!firstBase || this == firstBase || - nsContentUtils::PositionIsBefore(this, firstBase)) { - - return doc->SetFirstBaseNodeWithHref(this); - } + IsInDoc() && + (head = GetParent()) && + head == GetOwnerDoc()->GetHeadContent()) { + SetBaseURIUsingFirstBaseWithHref(head, this); } - return rv; -} - -// Helper function for nsHTMLSharedElement::UnbindFromTree. Finds and returns -// the first tag with an href attribute which is a child of elem, if one -// exists. -static nsIContent* -FindBaseRecursive(nsINode * const elem) -{ - // We can't use NS_GetContentList to get the list of elements, because - // that flushes content notifications, and we need this function to work in - // UnbindFromTree. Once we land the HTML5 parser and get rid of content - // notifications, we should fix this up. (bug 515819) - - PRUint32 childCount; - nsIContent * const * child = elem->GetChildArray(&childCount); - nsIContent * const * end = child + childCount; - for ( ; child != end; child++) { - nsIContent *childElem = *child; - - if (childElem->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && - childElem->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) - return childElem; - - nsIContent* base = FindBaseRecursive(childElem); - if (base) - return base; - } - - return nsnull; + return NS_OK; } nsresult @@ -500,31 +495,22 @@ nsHTMLSharedElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify) { nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aName, aNotify); + NS_ENSURE_SUCCESS(rv, rv); // If we're the first with an href and our href attribute is being // unset, then we're no longer the first with an href, and we need to // find the new one. - if (NS_SUCCEEDED(rv) && - mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && + nsIContent* head; + if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_None && - GetOwnerDoc() == GetCurrentDoc()) { - - nsIDocument* doc = GetCurrentDoc(); - NS_ENSURE_TRUE(doc, NS_OK); - - // If we're not the first in the document, then unsetting our href - // doesn't affect the document's base URI. - if (this != doc->GetFirstBaseNodeWithHref()) - return NS_OK; - - // We're the first base, but we don't have an href; find the first base - // which does have an href, and set the document's first base to that. - nsIContent* newBaseNode = FindBaseRecursive(doc); - return doc->SetFirstBaseNodeWithHref(newBaseNode); + IsInDoc() && + (head = GetParent()) && + head == GetOwnerDoc()->GetHeadContent()) { + SetBaseURIUsingFirstBaseWithHref(head, nsnull); } - return rv; + return NS_OK; } nsresult @@ -535,46 +521,46 @@ nsHTMLSharedElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent, aBindingParent, aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv, rv); // The document stores a pointer to its first element, which we may // need to update here. - if (NS_SUCCEEDED(rv) && - mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && + if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && HasAttr(kNameSpaceID_None, nsGkAtoms::href) && - aDocument) { + aDocument && aParent && + aDocument->GetHeadContent() == aParent) { - // If there's no in the document, or if this comes before the one - // that's currently there, set the document's first to this. - nsINode* curBaseNode = aDocument->GetFirstBaseNodeWithHref(); - if (!curBaseNode || - nsContentUtils::PositionIsBefore(this, curBaseNode)) { - - aDocument->SetFirstBaseNodeWithHref(this); - } + SetBaseURIUsingFirstBaseWithHref(aParent, this); } - return rv; + return NS_OK; } void nsHTMLSharedElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) { - nsCOMPtr doc = GetCurrentDoc(); + nsIDocument* doc; + nsIContent* parent; + PRBool inHeadBase = mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && + (doc = GetCurrentDoc()) && + (parent = GetParent()) && + parent->NodeInfo()->Equals(nsGkAtoms::head, + kNameSpaceID_XHTML); nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); // If we're removing a from a document, we may need to update the // document's record of the first base node. - if (doc && mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML)) { - - // If we're not the first base node, then we don't need to do anything. - if (this != doc->GetFirstBaseNodeWithHref()) - return; - - // If we were the first base node, we need to find the new first base. - - nsIContent* newBaseNode = FindBaseRecursive(doc); - doc->SetFirstBaseNodeWithHref(newBaseNode); + if (inHeadBase) { + // We might have gotten here as a result of the being removed + // from the document. In that case we need to call SetBaseURI(nsnull) + nsIContent* head = doc->GetHeadContent(); + if (head) { + SetBaseURIUsingFirstBaseWithHref(head, nsnull); + } + else { + doc->SetBaseURI(nsnull); + } } } diff --git a/content/html/document/src/nsHTMLContentSink.cpp b/content/html/document/src/nsHTMLContentSink.cpp index a2e0855c1f8f..eba4accb5c9b 100644 --- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/content/html/document/src/nsHTMLContentSink.cpp @@ -250,9 +250,6 @@ protected: SinkContext* mHeadContext; PRInt32 mNumOpenIFRAMES; - nsCOMPtr mBaseHref; - nsCOMPtr mBaseTarget; - // depth of containment within , <noframes> etc PRInt32 mInsideNoXXXTag; @@ -277,14 +274,6 @@ protected: void StartLayout(PRBool aIgnorePendingSheets); - /** - * 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(nsIContent* aContent); - // Routines for tags that require special handling nsresult CloseHTML(); nsresult OpenFrameset(const nsIParserNode& aNode); @@ -293,7 +282,6 @@ protected: nsresult CloseBody(); nsresult OpenForm(const nsIParserNode& aNode); nsresult CloseForm(); - void ProcessBASEElement(nsGenericHTMLElement* aElement); nsresult ProcessLINKTag(const nsIParserNode& aNode); // Routines for tags that require special handling when we reach their end @@ -788,39 +776,6 @@ SinkContext::OpenContainer(const nsIParserNode& aNode) ssle->SetEnableUpdates(PR_FALSE); } - - // 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 "src=" - case eHTMLTag_script: - - // 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); MaybeSetForm(content, nodeType, mSink); @@ -1047,28 +1002,8 @@ SinkContext::AddLeaf(const nsIParserNode& aNode) mSink->CreateContentObject(aNode, nodeType); NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY); - // 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_area: - case eHTMLTag_meta: - case eHTMLTag_img: - case eHTMLTag_frame: - case eHTMLTag_input: - case eHTMLTag_embed: - mSink->AddBaseTagInfo(content); - break; - - // <form> can end up as a leaf if it's misnested with table elements - case eHTMLTag_form: - mSink->AddBaseTagInfo(content); + if (nodeType == eHTMLTag_form) { mSink->mCurrentForm = content; - - break; - default: - break; } rv = mSink->AddAttributes(aNode, content); @@ -1082,12 +1017,6 @@ SinkContext::AddLeaf(const nsIParserNode& aNode) // Additional processing needed once the element is in the tree switch (nodeType) { - case eHTMLTag_base: - if (!mSink->mInsideNoXXXTag) { - mSink->ProcessBASEElement(content); - } - break; - case eHTMLTag_meta: // XXX It's just not sufficient to check if the parent is head. Also // check for the preference. @@ -2630,28 +2559,6 @@ HTMLContentSink::StartLayout(PRBool aIgnorePendingSheets) nsContentSink::StartLayout(aIgnorePendingSheets); } -void -HTMLContentSink::AddBaseTagInfo(nsIContent* aContent) -{ - nsresult rv; - if (mBaseHref) { - rv = aContent->SetProperty(nsGkAtoms::htmlBaseHref, mBaseHref, - nsPropertyTable::SupportsDtorFunc, PR_TRUE); - if (NS_SUCCEEDED(rv)) { - // circumvent nsDerivedSafe - NS_ADDREF(static_cast<nsIURI*>(mBaseHref)); - } - } - if (mBaseTarget) { - rv = aContent->SetProperty(nsGkAtoms::htmlBaseTarget, mBaseTarget, - nsPropertyTable::SupportsDtorFunc, PR_TRUE); - if (NS_SUCCEEDED(rv)) { - // circumvent nsDerivedSafe - NS_ADDREF(static_cast<nsIAtom*>(mBaseTarget)); - } - } -} - nsresult HTMLContentSink::OpenHeadContext() { @@ -2703,56 +2610,6 @@ HTMLContentSink::CloseHeadContext() } } -void -HTMLContentSink::ProcessBASEElement(nsGenericHTMLElement* aElement) -{ - // href attribute - nsAutoString attrValue; - if (aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, attrValue)) { - //-- Make sure this page is allowed to load this URI - nsresult rv; - nsCOMPtr<nsIURI> baseHrefURI; - rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(baseHrefURI), - attrValue, mDocument, - nsnull); - if (NS_FAILED(rv)) - return; - - // Setting "BASE URI" from the last BASE tag appearing in HEAD. - if (!mBody) { - // The document checks if it is legal to set this base. Failing here is - // ok, we just won't set a new base. - rv = mDocument->SetBaseURI(baseHrefURI); - if (NS_SUCCEEDED(rv)) { - mDocumentBaseURI = mDocument->GetBaseURI(); - } - } else { - // NAV compatibility quirk - - nsIScriptSecurityManager *securityManager = - nsContentUtils::GetSecurityManager(); - - rv = securityManager-> - CheckLoadURIWithPrincipal(mDocument->NodePrincipal(), baseHrefURI, - nsIScriptSecurityManager::STANDARD); - if (NS_SUCCEEDED(rv)) { - mBaseHref = baseHrefURI; - } - } - } - - // target attribute - if (aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::target, attrValue)) { - if (!mBody) { - // still in real HEAD - mDocument->SetBaseTarget(attrValue); - } else { - // NAV compatibility quirk - mBaseTarget = do_GetAtom(attrValue); - } - } -} - nsresult HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode) { @@ -2781,7 +2638,6 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode) // Add in the attributes and add the style content object to the // head container. - AddBaseTagInfo(element); result = AddAttributes(aNode, element); if (NS_FAILED(result)) { return result; diff --git a/content/html/document/src/nsHTMLFragmentContentSink.cpp b/content/html/document/src/nsHTMLFragmentContentSink.cpp index 7cddd9dc934e..1eb81e7f730b 100644 --- a/content/html/document/src/nsHTMLFragmentContentSink.cpp +++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp @@ -136,9 +136,6 @@ public: nsresult AddText(const nsAString& aString); nsresult FlushText(); - void ProcessBaseTag(nsIContent* aContent); - void AddBaseTagInfo(nsIContent* aContent); - nsresult Init(); PRPackedBool mAllContent; @@ -156,9 +153,6 @@ public: PRInt32 mTextLength; PRInt32 mTextSize; - nsCOMPtr<nsIURI> mBaseHref; - nsCOMPtr<nsIAtom> mBaseTarget; - nsCOMPtr<nsIDocument> mTargetDocument; nsRefPtr<nsNodeInfoManager> mNodeInfoManager; @@ -328,63 +322,6 @@ nsHTMLFragmentContentSink::OpenHead() return NS_OK; } -void -nsHTMLFragmentContentSink::ProcessBaseTag(nsIContent* aContent) -{ - nsAutoString value; - if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, value)) { - nsCOMPtr<nsIURI> baseHrefURI; - nsresult rv = - nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(baseHrefURI), - value, mTargetDocument, - nsnull); - if (NS_FAILED(rv)) - return; - - nsIScriptSecurityManager *securityManager = - nsContentUtils::GetSecurityManager(); - - NS_ASSERTION(aContent->NodePrincipal() == mTargetDocument->NodePrincipal(), - "How'd that happpen?"); - - rv = securityManager-> - CheckLoadURIWithPrincipal(mTargetDocument->NodePrincipal(), baseHrefURI, - nsIScriptSecurityManager::STANDARD); - if (NS_SUCCEEDED(rv)) { - mBaseHref = baseHrefURI; - } - } - if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::target, value)) { - mBaseTarget = do_GetAtom(value); - } -} - -void -nsHTMLFragmentContentSink::AddBaseTagInfo(nsIContent* aContent) -{ - if (!aContent) { - return; - } - - nsresult rv; - if (mBaseHref) { - rv = aContent->SetProperty(nsGkAtoms::htmlBaseHref, mBaseHref, - nsPropertyTable::SupportsDtorFunc, PR_TRUE); - if (NS_SUCCEEDED(rv)) { - // circumvent nsDerivedSafe - NS_ADDREF(static_cast<nsIURI*>(mBaseHref)); - } - } - if (mBaseTarget) { - rv = aContent->SetProperty(nsGkAtoms::htmlBaseTarget, mBaseTarget, - nsPropertyTable::SupportsDtorFunc, PR_TRUE); - if (NS_SUCCEEDED(rv)) { - // circumvent nsDerivedSafe - NS_ADDREF(static_cast<nsIAtom*>(mBaseTarget)); - } - } -} - NS_IMETHODIMP nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode) { @@ -459,16 +396,6 @@ nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode) parent->AppendChildTo(content, PR_FALSE); PushContent(content); - - if (nodeType == eHTMLTag_table - || nodeType == eHTMLTag_thead - || nodeType == eHTMLTag_tbody - || nodeType == eHTMLTag_tfoot - || nodeType == eHTMLTag_tr - || nodeType == eHTMLTag_td - || nodeType == eHTMLTag_th) - // XXX if navigator_quirks_mode (only body in html supports background) - AddBaseTagInfo(content); } else if (mProcessing && mIgnoreContainer) { mIgnoreContainer = PR_FALSE; @@ -553,12 +480,6 @@ nsHTMLFragmentContentSink::AddLeaf(const nsIParserNode& aNode) } parent->AppendChildTo(content, PR_FALSE); - - if (nodeType == eHTMLTag_img || nodeType == eHTMLTag_frame - || nodeType == eHTMLTag_input) // elements with 'SRC=' - AddBaseTagInfo(content); - else if (nodeType == eHTMLTag_base) - ProcessBaseTag(content); } break; case eToken_text: @@ -1073,16 +994,6 @@ nsHTMLParanoidFragmentSink::AddAttributes(const nsIParserNode& aNode, // Add attribute to content aContent->SetAttr(kNameSpaceID_None, keyAtom, v, PR_FALSE); } - - if (nodeType == eHTMLTag_a || - nodeType == eHTMLTag_form || - nodeType == eHTMLTag_img || - nodeType == eHTMLTag_map || - nodeType == eHTMLTag_q || - nodeType == eHTMLTag_blockquote || - nodeType == eHTMLTag_input) { - AddBaseTagInfo(aContent); - } } return NS_OK; @@ -1150,21 +1061,8 @@ nsHTMLParanoidFragmentSink::AddLeaf(const nsIParserNode& aNode) rv = NameFromNode(aNode, getter_AddRefs(name)); NS_ENSURE_SUCCESS(rv, rv); - // We will process base tags, but we won't include them - // in the output + // Don't include base tags in output. if (name == nsGkAtoms::base) { - nsCOMPtr<nsIContent> content; - nsCOMPtr<nsINodeInfo> nodeInfo; - nsIParserService* parserService = nsContentUtils::GetParserService(); - if (!parserService) - return NS_ERROR_OUT_OF_MEMORY; - nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, - kNameSpaceID_XHTML); - NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); - rv = NS_NewHTMLElement(getter_AddRefs(content), nodeInfo, PR_FALSE); - NS_ENSURE_SUCCESS(rv, rv); - AddAttributes(aNode, content); - ProcessBaseTag(content); return NS_OK; } diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 8ad33588fad0..2d7b0e486c97 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -632,13 +632,7 @@ nsXMLContentSink::CloseElement(nsIContent* aContent) return rv; } - if (nodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) && - !mHasProcessedBase) { - // The first base wins - ProcessBASETag(aContent); - mHasProcessedBase = PR_TRUE; - } - else if (nodeInfo->Equals(nsGkAtoms::meta, kNameSpaceID_XHTML) && + if (nodeInfo->Equals(nsGkAtoms::meta, kNameSpaceID_XHTML) && // Need to check here to make sure this meta tag does not set // mPrettyPrintXML to false when we have a special root! (!mPrettyPrintXML || !mPrettyPrintHasSpecialRoot)) { @@ -756,7 +750,8 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement, return NS_OK; nsCOMPtr<nsIURI> url; - rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull, mDocumentBaseURI); + rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull, + mDocument->GetBaseURI()); NS_ENSURE_SUCCESS(rv, rv); // Do security check @@ -797,32 +792,6 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement, return rv; } -void -nsXMLContentSink::ProcessBASETag(nsIContent* aContent) -{ - NS_ASSERTION(aContent, "missing base-element"); - - if (mDocument) { - nsAutoString value; - - if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::target, value)) { - mDocument->SetBaseTarget(value); - } - - if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, value)) { - nsCOMPtr<nsIURI> baseURI; - nsresult rv = NS_NewURI(getter_AddRefs(baseURI), value); - if (NS_SUCCEEDED(rv)) { - rv = mDocument->SetBaseURI(baseURI); // The document checks if it is legal to set this base - if (NS_SUCCEEDED(rv)) { - mDocumentBaseURI = mDocument->GetBaseURI(); - } - } - } - } -} - - NS_IMETHODIMP nsXMLContentSink::SetDocumentCharset(nsACString& aCharset) { diff --git a/content/xml/document/src/nsXMLContentSink.h b/content/xml/document/src/nsXMLContentSink.h index 271794000b6a..974712bcd069 100644 --- a/content/xml/document/src/nsXMLContentSink.h +++ b/content/xml/document/src/nsXMLContentSink.h @@ -152,8 +152,6 @@ protected: void PopContent(); PRBool HaveNotifiedForCurrentContent() const; - void ProcessBASETag(nsIContent* aContent); - nsresult FlushTags(); void UpdateChildCounts(); @@ -206,7 +204,6 @@ protected: PRUint8 mPrettyPrintXML : 1; PRUint8 mPrettyPrintHasSpecialRoot : 1; PRUint8 mPrettyPrintHasFactoredElements : 1; - PRUint8 mHasProcessedBase : 1; PRUint8 mPrettyPrinting : 1; // True if we called PrettyPrint() and it // decided we should in fact prettyprint. diff --git a/content/xslt/src/xslt/txMozillaXMLOutput.cpp b/content/xslt/src/xslt/txMozillaXMLOutput.cpp index 91f6ad6ab1c6..4f912d91ca7b 100644 --- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp +++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp @@ -86,7 +86,6 @@ txMozillaXMLOutput::txMozillaXMLOutput(const nsSubstring& aRootName, : mTreeDepth(0), mBadChildLevel(0), mTableState(NORMAL), - mHaveBaseElement(PR_FALSE), mCreatingNewDocument(PR_TRUE), mOpenedElementIsHTML(PR_FALSE), mRootContentCreated(PR_FALSE), @@ -111,7 +110,6 @@ txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat, : mTreeDepth(0), mBadChildLevel(0), mTableState(NORMAL), - mHaveBaseElement(PR_FALSE), mCreatingNewDocument(PR_FALSE), mOpenedElementIsHTML(PR_FALSE), mRootContentCreated(PR_FALSE), @@ -763,23 +761,6 @@ txMozillaXMLOutput::endHTMLElement(nsIContent* aElement) return NS_OK; } - else if (mCreatingNewDocument && atom == txHTMLAtoms::base && - !mHaveBaseElement) { - // The first base wins - mHaveBaseElement = PR_TRUE; - - nsAutoString value; - aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::target, value); - mDocument->SetBaseTarget(value); - - aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::href, value); - nsCOMPtr<nsIURI> baseURI; - NS_NewURI(getter_AddRefs(baseURI), value, nsnull); - - if (baseURI) { - mDocument->SetBaseURI(baseURI); // The document checks if it is legal to set this base - } - } else if (mCreatingNewDocument && atom == txHTMLAtoms::meta) { // handle HTTP-EQUIV data nsAutoString httpEquiv; diff --git a/content/xslt/src/xslt/txMozillaXMLOutput.h b/content/xslt/src/xslt/txMozillaXMLOutput.h index 99bfbc63ffd1..2e4d491f9032 100644 --- a/content/xslt/src/xslt/txMozillaXMLOutput.h +++ b/content/xslt/src/xslt/txMozillaXMLOutput.h @@ -153,8 +153,6 @@ private: txOutputFormat mOutputFormat; - PRPackedBool mHaveBaseElement; - PRPackedBool mCreatingNewDocument; PRPackedBool mOpenedElementIsHTML; diff --git a/parser/html/nsHtml5Parser.cpp b/parser/html/nsHtml5Parser.cpp index 40d5353b3213..518c32e6d62e 100644 --- a/parser/html/nsHtml5Parser.cpp +++ b/parser/html/nsHtml5Parser.cpp @@ -449,8 +449,6 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer, Initialize(doc, uri, nsnull, nsnull); - // Initialize() doesn't deal with base URI - mExecutor->SetBaseUriFromDocument(); mExecutor->SetParser(this); mExecutor->SetNodeInfoManager(doc->NodeInfoManager()); diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h index c5ce6fcf3af2..513749e77e46 100644 --- a/parser/html/nsHtml5TreeBuilderCppSupplement.h +++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h @@ -501,12 +501,6 @@ nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent treeOp->Init(eTreeOpDoneCreatingElement, aElement); return; } - if (aName == nsHtml5Atoms::base) { - nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); - NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpProcessBase, aElement); - return; - } if (aName == nsHtml5Atoms::meta) { nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp index 8ce26943ebea..dbfb042c4183 100644 --- a/parser/html/nsHtml5TreeOpExecutor.cpp +++ b/parser/html/nsHtml5TreeOpExecutor.cpp @@ -603,34 +603,6 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite() } } -nsresult -nsHtml5TreeOpExecutor::ProcessBASETag(nsIContent* aContent) -{ - NS_ASSERTION(aContent, "missing base-element"); - if (mHasProcessedBase) { - return NS_OK; - } - mHasProcessedBase = PR_TRUE; - nsresult rv = NS_OK; - if (mDocument) { - nsAutoString value; - if (aContent->GetAttr(kNameSpaceID_None, nsHtml5Atoms::target, value)) { - mDocument->SetBaseTarget(value); - } - if (aContent->GetAttr(kNameSpaceID_None, nsHtml5Atoms::href, value)) { - nsCOMPtr<nsIURI> baseURI; - rv = NS_NewURI(getter_AddRefs(baseURI), value); - if (NS_SUCCEEDED(rv)) { - rv = mDocument->SetBaseURI(baseURI); // The document checks if it is legal to set this base - if (NS_SUCCEEDED(rv)) { - mDocumentBaseURI = mDocument->GetBaseURI(); - } - } - } - } - return rv; -} - // copied from HTML content sink PRBool nsHtml5TreeOpExecutor::IsScriptEnabled() @@ -827,7 +799,6 @@ nsHtml5TreeOpExecutor::GetTokenizer() void nsHtml5TreeOpExecutor::Reset() { DropHeldElements(); - mHasProcessedBase = PR_FALSE; mReadingFromStage = PR_FALSE; mOpQueue.Clear(); mStarted = PR_FALSE; diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h index cb47eb531d09..12206f112b0c 100644 --- a/parser/html/nsHtml5TreeOpExecutor.h +++ b/parser/html/nsHtml5TreeOpExecutor.h @@ -97,7 +97,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink, */ PRBool mSuppressEOF; - PRBool mHasProcessedBase; PRBool mReadingFromStage; nsTArray<nsHtml5TreeOperation> mOpQueue; nsTArray<nsIContentPtr> mElementsSeenInThisAppendBatch; @@ -188,7 +187,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink, virtual nsISupports *GetTarget(); // nsContentSink methods - virtual nsresult ProcessBASETag(nsIContent* aContent); virtual void UpdateChildCounts(); virtual nsresult FlushTags(); virtual void PostEvaluateScript(nsIScriptElement *aElement); @@ -214,11 +212,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink, return IsScriptExecutingImpl(); } - void SetBaseUriFromDocument() { - mDocumentBaseURI = mDocument->GetBaseURI(); - mHasProcessedBase = PR_TRUE; - } - void SetNodeInfoManager(nsNodeInfoManager* aManager) { mNodeInfoManager = aManager; } diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp index 28b667e9bdbb..0aef1ccc1dfd 100644 --- a/parser/html/nsHtml5TreeOperation.cpp +++ b/parser/html/nsHtml5TreeOperation.cpp @@ -603,11 +603,6 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder, aBuilder->UpdateStyleSheet(node); return rv; } - case eTreeOpProcessBase: { - nsIContent* node = *(mOne.node); - rv = aBuilder->ProcessBASETag(node); - return rv; - } case eTreeOpProcessMeta: { nsIContent* node = *(mOne.node); rv = aBuilder->ProcessMETATag(node); diff --git a/parser/html/nsHtml5TreeOperation.h b/parser/html/nsHtml5TreeOperation.h index 12d9e41fa554..c53945564c1c 100644 --- a/parser/html/nsHtml5TreeOperation.h +++ b/parser/html/nsHtml5TreeOperation.h @@ -74,7 +74,6 @@ enum eHtml5TreeOperation { eTreeOpSetDocumentCharset, eTreeOpNeedsCharsetSwitchTo, eTreeOpUpdateStyleSheet, - eTreeOpProcessBase, eTreeOpProcessMeta, eTreeOpProcessOfflineManifest, eTreeOpMarkMalformedIfScript,