From ea40db52bef37e7ae2e4b0b01fe5ea5676d58559 Mon Sep 17 00:00:00 2001 From: "locka%iol.ie" Date: Wed, 11 Oct 2000 13:50:45 +0000 Subject: [PATCH] Fix for anchor scrolling regression. b=55244, r=waterson@netscape.com, a=waterson@netscape.com git-svn-id: svn://10.0.0.236/trunk@80936 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsPresShell.cpp | 84 +++++++++++++++++--- mozilla/layout/html/base/src/nsPresShell.cpp | 84 +++++++++++++++++--- 2 files changed, 144 insertions(+), 24 deletions(-) diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 160341e5f28..b17f106a834 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -3287,27 +3287,87 @@ PresShell::CantRenderReplacedElement(nsIPresContext* aPresContext, NS_IMETHODIMP PresShell::GoToAnchor(const nsString& aAnchorName) const { - nsCOMPtr doc; - nsresult rv = NS_OK; - nsCOMPtr content; + nsCOMPtr doc = do_QueryInterface(mDocument); + nsCOMPtr htmlDoc = do_QueryInterface(mDocument); + nsresult rv = NS_OK; + nsCOMPtr content; - if (NS_SUCCEEDED(mDocument->QueryInterface(NS_GET_IID(nsIDOMDocument), - getter_AddRefs(doc)))) { + // Search for an element with a matching "id" attribute + if (doc) { nsCOMPtr element; - - // Find the element with the specified id rv = doc->GetElementById(aAnchorName, getter_AddRefs(element)); if (NS_SUCCEEDED(rv) && element) { // Get the nsIContent interface, because that's what we need to // get the primary frame - rv = element->QueryInterface(NS_GET_IID(nsIContent), - getter_AddRefs(content)); + content = do_QueryInterface(element); } } - if (NS_SUCCEEDED(rv) && content) { + // Search for an anchor element with a matching "name" attribute + if (!content && htmlDoc) { + nsCOMPtr list; + // Find a matching list of named nodes + rv = htmlDoc->GetElementsByName(aAnchorName, getter_AddRefs(list)); + if (NS_SUCCEEDED(rv) && list) { + PRUint32 count; + PRUint32 i; + list->GetLength(&count); + // Loop through the named nodes looking for the first anchor + for (i = 0; i < count; i++) { + nsCOMPtr node; + rv = list->Item(i, getter_AddRefs(node)); + if (NS_FAILED(rv)) { + break; + } + // Ensure it's an anchor element + nsCOMPtr element = do_QueryInterface(node); + nsAutoString tagName; + if (element && NS_SUCCEEDED(element->GetTagName(tagName))) { + tagName.ToLowerCase(); + if (tagName.EqualsWithConversion("a")) { + content = do_QueryInterface(element); + break; + } + } + } + } + } + + // Search for anchor in the HTML namespace with a matching name + if (!content && !htmlDoc) + { + nsCOMPtr list; + NS_NAMED_LITERAL_STRING(nameSpace, "http://www.w3.org/1999/xhtml"); + // Get the list of anchor elements + rv = doc->GetElementsByTagNameNS(nameSpace, NS_LITERAL_STRING("a"), getter_AddRefs(list)); + if (NS_SUCCEEDED(rv) && list) { + PRUint32 count; + PRUint32 i; + list->GetLength(&count); + // Loop through the named nodes looking for the first anchor + for (i = 0; i < count; i++) { + nsCOMPtr node; + rv = list->Item(i, getter_AddRefs(node)); + if (NS_FAILED(rv)) { + break; + } + // Compare the name attribute + nsCOMPtr element = do_QueryInterface(node); + nsAutoString value; + if (element && NS_SUCCEEDED(element->GetAttribute(NS_LITERAL_STRING("name"), value))) { + if (value.EqualsWithConversion(aAnchorName)) { + content = do_QueryInterface(element); + break; + } + } + } + } + } + + + if (content) { nsIFrame* frame; - + // Get the primary frame if (NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame))) { rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP, @@ -4566,7 +4626,7 @@ PresShell::Paint(nsIView *aView, PRBool clipState; aRenderingContext.PopState(clipState); } - + #ifdef NS_DEBUG // Draw a border around the frame if (nsIFrameDebug::GetShowFrameBorders()) { diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 160341e5f28..b17f106a834 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -3287,27 +3287,87 @@ PresShell::CantRenderReplacedElement(nsIPresContext* aPresContext, NS_IMETHODIMP PresShell::GoToAnchor(const nsString& aAnchorName) const { - nsCOMPtr doc; - nsresult rv = NS_OK; - nsCOMPtr content; + nsCOMPtr doc = do_QueryInterface(mDocument); + nsCOMPtr htmlDoc = do_QueryInterface(mDocument); + nsresult rv = NS_OK; + nsCOMPtr content; - if (NS_SUCCEEDED(mDocument->QueryInterface(NS_GET_IID(nsIDOMDocument), - getter_AddRefs(doc)))) { + // Search for an element with a matching "id" attribute + if (doc) { nsCOMPtr element; - - // Find the element with the specified id rv = doc->GetElementById(aAnchorName, getter_AddRefs(element)); if (NS_SUCCEEDED(rv) && element) { // Get the nsIContent interface, because that's what we need to // get the primary frame - rv = element->QueryInterface(NS_GET_IID(nsIContent), - getter_AddRefs(content)); + content = do_QueryInterface(element); } } - if (NS_SUCCEEDED(rv) && content) { + // Search for an anchor element with a matching "name" attribute + if (!content && htmlDoc) { + nsCOMPtr list; + // Find a matching list of named nodes + rv = htmlDoc->GetElementsByName(aAnchorName, getter_AddRefs(list)); + if (NS_SUCCEEDED(rv) && list) { + PRUint32 count; + PRUint32 i; + list->GetLength(&count); + // Loop through the named nodes looking for the first anchor + for (i = 0; i < count; i++) { + nsCOMPtr node; + rv = list->Item(i, getter_AddRefs(node)); + if (NS_FAILED(rv)) { + break; + } + // Ensure it's an anchor element + nsCOMPtr element = do_QueryInterface(node); + nsAutoString tagName; + if (element && NS_SUCCEEDED(element->GetTagName(tagName))) { + tagName.ToLowerCase(); + if (tagName.EqualsWithConversion("a")) { + content = do_QueryInterface(element); + break; + } + } + } + } + } + + // Search for anchor in the HTML namespace with a matching name + if (!content && !htmlDoc) + { + nsCOMPtr list; + NS_NAMED_LITERAL_STRING(nameSpace, "http://www.w3.org/1999/xhtml"); + // Get the list of anchor elements + rv = doc->GetElementsByTagNameNS(nameSpace, NS_LITERAL_STRING("a"), getter_AddRefs(list)); + if (NS_SUCCEEDED(rv) && list) { + PRUint32 count; + PRUint32 i; + list->GetLength(&count); + // Loop through the named nodes looking for the first anchor + for (i = 0; i < count; i++) { + nsCOMPtr node; + rv = list->Item(i, getter_AddRefs(node)); + if (NS_FAILED(rv)) { + break; + } + // Compare the name attribute + nsCOMPtr element = do_QueryInterface(node); + nsAutoString value; + if (element && NS_SUCCEEDED(element->GetAttribute(NS_LITERAL_STRING("name"), value))) { + if (value.EqualsWithConversion(aAnchorName)) { + content = do_QueryInterface(element); + break; + } + } + } + } + } + + + if (content) { nsIFrame* frame; - + // Get the primary frame if (NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame))) { rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP, @@ -4566,7 +4626,7 @@ PresShell::Paint(nsIView *aView, PRBool clipState; aRenderingContext.PopState(clipState); } - + #ifdef NS_DEBUG // Draw a border around the frame if (nsIFrameDebug::GetShowFrameBorders()) {