diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 3d612b0598a..9f2dd4ea591 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -195,6 +195,31 @@ public: static PRUint16 ComparePositionWithAncestors(nsIDOMNode *aNode, nsIDOMNode *aOther); + /** + * Brute-force search of the element subtree rooted at aContent for + * an element with the given id. + */ + static nsIContent* MatchElementId(nsIContent *aContent, + const nsAString& aId); + + /** + * Given a URI containing an element reference (#whatever), + * resolve it to the target content element with the given ID. + * + * If aFromContent is anonymous XBL content then the URI + * must refer to its binding document and we will return + * a node in the same anonymous content subtree as aFromContent, + * if one exists with the correct ID. + * + * @param aFromContent the context of the reference; + * currently we only support references to elements in the + * same document as the context, so this must be non-null + * + * @return the element, or nsnull on failure + */ + static nsIContent* GetReferencedElement(nsIURI* aURI, + nsIContent *aFromContent); + /** * Reverses the document position flags passed in. * @@ -304,6 +329,15 @@ public: nsIDocument* aDocument, nsIURI* aBaseURI); + /** + * Convert aInput (in charset aCharset) to UTF16 in aOutput. + * + * @param aCharset the name of the charset; if empty, we assume UTF8 + */ + static nsresult ConvertStringFromCharset(const nsACString& aCharset, + const nsACString& aInput, + nsAString& aOutput); + /** * Determine whether aContent is in some way associated with aForm. If the * form is a container the only elements that are considered to be associated diff --git a/mozilla/content/base/src/nsContentSink.cpp b/mozilla/content/base/src/nsContentSink.cpp index 9fd4aaa5d43..81d4448a5b9 100644 --- a/mozilla/content/base/src/nsContentSink.cpp +++ b/mozilla/content/base/src/nsContentSink.cpp @@ -67,7 +67,6 @@ #include "nsICookieService.h" #include "nsIPrompt.h" #include "nsServiceManagerUtils.h" -#include "nsICharsetConverterManager.h" #include "nsContentUtils.h" #include "nsParserUtils.h" #include "nsCRT.h" @@ -737,53 +736,6 @@ nsContentSink::PrefetchHref(const nsAString &aHref, PRBool aExplicit) } -// Convert the ref from document charset to unicode. -static nsresult -CharsetConvRef(const nsACString& aDocCharset, - const nsCString& aRefInDocCharset, - nsString& aRefInUnicode) -{ - nsresult rv; - - nsCOMPtr docCharsetAtom; - nsCOMPtr ccm = - do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); - - if (NS_FAILED(rv)) { - return rv; - } - - nsCOMPtr decoder; - rv = ccm->GetUnicodeDecoder(PromiseFlatCString(aDocCharset).get(), - getter_AddRefs(decoder)); - if (NS_FAILED(rv)) { - return rv; - } - - PRInt32 srcLen = aRefInDocCharset.Length(); - PRInt32 dstLen; - rv = decoder->GetMaxLength(aRefInDocCharset.get(), srcLen, &dstLen); - if (NS_FAILED(rv)) { - return rv; - } - - PRUnichar *ustr = (PRUnichar *)nsMemory::Alloc((dstLen + 1) * - sizeof(PRUnichar)); - if (!ustr) { - return NS_ERROR_OUT_OF_MEMORY; - } - - rv = decoder->Convert(aRefInDocCharset.get(), &srcLen, ustr, &dstLen); - if (NS_SUCCEEDED(rv)) { - ustr[dstLen] = 0; - aRefInUnicode.Assign(ustr, dstLen); - } - - nsMemory::Free(ustr); - - return rv; -} - PRBool nsContentSink::ScrollToRef(PRBool aReallyScroll) { @@ -826,7 +778,7 @@ nsContentSink::ScrollToRef(PRBool aReallyScroll) if (NS_FAILED(rv)) { const nsACString &docCharset = mDocument->GetDocumentCharacterSet(); - rv = CharsetConvRef(docCharset, unescapedRef, ref); + rv = nsContentUtils::ConvertStringFromCharset(docCharset, unescapedRef, ref); if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) rv = shell->GoToAnchor(ref, aReallyScroll); diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index 45598155a2f..044d08b1d2e 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -119,6 +119,14 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "nsIEventQueueService.h" #include "jsdbgapi.h" #include "nsIJSRuntimeService.h" +#include "nsIDOMDocumentXBL.h" +#include "nsIBindingManager.h" +#include "nsIURI.h" +#include "nsIURL.h" +#include "nsXBLBinding.h" +#include "nsXBLPrototypeBinding.h" +#include "nsEscape.h" +#include "nsICharsetConverterManager.h" // for ReportToConsole #include "nsIStringBundle.h" @@ -2465,3 +2473,210 @@ nsContentUtils::DispatchTrustedEvent(nsIDocument* aDoc, nsISupports* aTarget, PRBool dummy; return target->DispatchEvent(event, aDefaultAction ? aDefaultAction : &dummy); } + +static nsIContent* +MatchElementId(nsIContent *aContent, + const nsACString& aUTF8Id, const nsAString& aId) +{ + if (aContent->IsContentOfType(nsIContent::eHTML)) { + if (aContent->HasAttr(kNameSpaceID_None, nsHTMLAtoms::id)) { + nsAutoString value; + aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::id, value); + + if (aId.Equals(value)) { + return aContent; + } + } + } + else if (aContent->IsContentOfType(nsIContent::eELEMENT)) { + nsCOMPtr xmlContent = do_QueryInterface(aContent); + + if (xmlContent) { + nsIAtom* value = xmlContent->GetID(); + if (value && value->EqualsUTF8(aUTF8Id)) { + return aContent; + } + } + } + + nsIContent *result = nsnull; + PRUint32 i, count = aContent->GetChildCount(); + + for (i = 0; i < count && result == nsnull; i++) { + result = MatchElementId(aContent->GetChildAt(i), aUTF8Id, aId); + } + + return result; +} + +// Id attribute matching function used by nsXMLDocument and +// nsHTMLDocument and others. +/* static */ +nsIContent * +nsContentUtils::MatchElementId(nsIContent *aContent, const nsAString& aId) +{ + return ::MatchElementId(aContent, NS_ConvertUTF16toUTF8(aId), aId); +} + +// Convert the string from the given charset to Unicode. +/* static */ +nsresult +nsContentUtils::ConvertStringFromCharset(const nsACString& aCharset, + const nsACString& aInput, + nsAString& aOutput) +{ + if (aCharset.IsEmpty()) { + // Treat the string as UTF8 + CopyUTF8toUTF16(aInput, aOutput); + return NS_OK; + } + + nsresult rv; + nsCOMPtr ccm = + do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr decoder; + rv = ccm->GetUnicodeDecoder(PromiseFlatCString(aCharset).get(), + getter_AddRefs(decoder)); + if (NS_FAILED(rv)) + return rv; + + nsPromiseFlatCString flatInput(aInput); + PRInt32 srcLen = flatInput.Length(); + PRInt32 dstLen; + rv = decoder->GetMaxLength(flatInput.get(), srcLen, &dstLen); + if (NS_FAILED(rv)) + return rv; + + PRUnichar *ustr = (PRUnichar *)nsMemory::Alloc((dstLen + 1) * + sizeof(PRUnichar)); + if (!ustr) + return NS_ERROR_OUT_OF_MEMORY; + + rv = decoder->Convert(flatInput.get(), &srcLen, ustr, &dstLen); + if (NS_SUCCEEDED(rv)) { + ustr[dstLen] = 0; + aOutput.Assign(ustr, dstLen); + } + + nsMemory::Free(ustr); + return rv; +} + +static PRBool EqualExceptRef(nsIURL* aURL1, nsIURL* aURL2) +{ + nsCOMPtr u1; + nsCOMPtr u2; + + nsresult rv = aURL1->Clone(getter_AddRefs(u1)); + if (NS_SUCCEEDED(rv)) { + rv = aURL2->Clone(getter_AddRefs(u2)); + } + if (NS_FAILED(rv)) + return PR_FALSE; + + nsCOMPtr url1 = do_QueryInterface(u1); + nsCOMPtr url2 = do_QueryInterface(u2); + if (!url1 || !url2) { + NS_WARNING("Cloning a URL produced a non-URL"); + return PR_FALSE; + } + url1->SetRef(EmptyCString()); + url2->SetRef(EmptyCString()); + + PRBool equal; + rv = url1->Equals(url2, &equal); + return NS_SUCCEEDED(rv) && equal; +} + +/* static */ +nsIContent* +nsContentUtils::GetReferencedElement(nsIURI* aURI, nsIContent *aFromContent) +{ + nsCOMPtr url = do_QueryInterface(aURI); + if (!url) + return nsnull; + + nsCAutoString refPart; + url->GetRef(refPart); + // Unescape %-escapes in the reference. The result will be in the + // origin charset of the URL, hopefully... + NS_UnescapeURL(refPart); + + nsCAutoString charset; + url->GetOriginCharset(charset); + nsAutoString ref; + nsresult rv = ConvertStringFromCharset(charset, refPart, ref); + if (NS_FAILED(rv)) { + CopyUTF8toUTF16(refPart, ref); + } + if (ref.IsEmpty()) + return nsnull; + + // Get the current document + nsIDocument *doc = aFromContent->GetCurrentDoc(); + if (!doc) + return nsnull; + + // This will be the URI of the document the content belongs to + // (the URI of the XBL document if the content is anonymous + // XBL content) + nsCOMPtr documentURL = do_QueryInterface(doc->GetDocumentURI()); + nsIContent* bindingParent = aFromContent->GetBindingParent(); + PRBool isXBL = PR_FALSE; + if (bindingParent) { + nsXBLBinding* binding = doc->BindingManager()->GetBinding(bindingParent); + if (binding) { + // XXX sXBL/XBL2 issue + // If this is an anonymous XBL element then the URI is + // relative to the binding document. A full fix requires a + // proper XBL2 implementation but for now URIs that are + // relative to the binding document should be resolve to the + // copy of the target element that has been inserted into the + // bound document. + documentURL = do_QueryInterface(binding->PrototypeBinding()->DocURI()); + isXBL = PR_TRUE; + } + } + if (!documentURL) + return nsnull; + + if (!EqualExceptRef(url, documentURL)) { + // Oops -- we don't support off-document references + return nsnull; + } + + // Get the element + nsCOMPtr content; + if (isXBL) { + nsCOMPtr anonymousChildren; + doc->BindingManager()-> + GetAnonymousNodesFor(bindingParent, getter_AddRefs(anonymousChildren)); + + if (anonymousChildren) { + PRUint32 length; + anonymousChildren->GetLength(&length); + for (PRUint32 i = 0; i < length && !content; ++i) { + nsCOMPtr node; + anonymousChildren->Item(i, getter_AddRefs(node)); + nsCOMPtr c = do_QueryInterface(node); + if (c) { + content = MatchElementId(c, ref); + } + } + } + } else { + nsCOMPtr domDoc = do_QueryInterface(doc); + NS_ASSERTION(domDoc, "Content doesn't reference a dom Document"); + + nsCOMPtr element; + rv = domDoc->GetElementById(ref, getter_AddRefs(element)); + if (element) { + content = do_QueryInterface(element); + } + } + + return content; +} diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index e33a04021c5..6b83c236c77 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -155,11 +155,6 @@ static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID); static PRBool IsNamedItem(nsIContent* aContent, nsIAtom *aTag, nsAString& aName); -// MatchElementId is defined in nsXMLDocument.cpp -nsIContent * -MatchElementId(nsIContent *aContent, const nsACString& aUTF8Id, const nsAString& aId); - - static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID); PRUint32 nsHTMLDocument::gWyciwygSessionCnt = 0; @@ -2394,8 +2389,7 @@ nsHTMLDocument::GetElementById(const nsAString& aElementId, "getElementById(\"\") called, fix caller?"); if (mRootContent && !aElementId.IsEmpty()) { - e = MatchElementId(mRootContent, NS_ConvertUCS2toUTF8(aElementId), - aElementId); + e = nsContentUtils::MatchElementId(mRootContent, aElementId); } } diff --git a/mozilla/content/xml/document/src/nsXMLDocument.cpp b/mozilla/content/xml/document/src/nsXMLDocument.cpp index 2ede539b054..f7d4652bf0a 100644 --- a/mozilla/content/xml/document/src/nsXMLDocument.cpp +++ b/mozilla/content/xml/document/src/nsXMLDocument.cpp @@ -728,42 +728,6 @@ nsXMLDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) return CallQueryInterface(newDoc, aReturn); } -// Id attribute matching function used by nsXMLDocument and -// nsHTMLDocument. -nsIContent * -MatchElementId(nsIContent *aContent, const nsACString& aUTF8Id, const nsAString& aId) -{ - if (aContent->IsContentOfType(nsIContent::eHTML)) { - if (aContent->HasAttr(kNameSpaceID_None, nsHTMLAtoms::id)) { - nsAutoString value; - aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::id, value); - - if (aId.Equals(value)) { - return aContent; - } - } - } - else if (aContent->IsContentOfType(nsIContent::eELEMENT)) { - nsCOMPtr xmlContent = do_QueryInterface(aContent); - - if (xmlContent) { - nsIAtom* value = xmlContent->GetID(); - if (value && value->EqualsUTF8(aUTF8Id)) { - return aContent; - } - } - } - - nsIContent *result = nsnull; - PRUint32 i, count = aContent->GetChildCount(); - - for (i = 0; i < count && result == nsnull; i++) { - result = MatchElementId(aContent->GetChildAt(i), aUTF8Id, aId); - } - - return result; -} - // nsIDOMDocument interface NS_IMETHODIMP @@ -786,9 +750,8 @@ nsXMLDocument::GetElementById(const nsAString& aElementId, // XXX For now, we do a brute force search of the content tree. // We should come up with a more efficient solution. // Note that content is *not* refcounted here, so do *not* release it! - nsIContent *content = MatchElementId(mRootContent, - NS_ConvertUCS2toUTF8(aElementId), - aElementId); + nsIContent *content = + nsContentUtils::MatchElementId(mRootContent, aElementId); if (!content) { return NS_OK; diff --git a/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp b/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp index e73002e35a4..05c42a5b358 100644 --- a/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGClipPathFrame.cpp @@ -109,14 +109,9 @@ NS_GetSVGClipPathFrame(nsSVGClipPathFrame **aResult, nsIURI *aURI, nsIContent *a } nsIPresShell *aPresShell = myDoc->GetShellAt(0); - // Get the URI Spec - nsCAutoString uriSpec; - aURI->GetSpec(uriSpec); - // Find the referenced frame nsIFrame *cpframe; - if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&cpframe, - uriSpec, aContent, aPresShell))) + if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&cpframe, aURI, aContent, aPresShell))) return NS_ERROR_FAILURE; nsIAtom* frameType = cpframe->GetType(); diff --git a/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp b/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp index be56bf4cd2c..80e7313b672 100644 --- a/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGFilterFrame.cpp @@ -154,14 +154,9 @@ NS_GetSVGFilterFrame(nsISVGFilterFrame **aResult, } nsIPresShell *aPresShell = myDoc->GetShellAt(0); - // Get the URI Spec - nsCAutoString uriSpec; - aURI->GetSpec(uriSpec); - // Find the referenced frame nsIFrame *filter; - if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&filter, - uriSpec, aContent, aPresShell))) + if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&filter, aURI, aContent, aPresShell))) return NS_ERROR_FAILURE; nsIAtom* frameType = filter->GetType(); diff --git a/mozilla/layout/svg/base/src/nsSVGGradientFrame.cpp b/mozilla/layout/svg/base/src/nsSVGGradientFrame.cpp index 2e1b9fcaaf8..dac98492bae 100644 --- a/mozilla/layout/svg/base/src/nsSVGGradientFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGGradientFrame.cpp @@ -655,12 +655,14 @@ nsSVGGradientFrame::checkURITarget(void) { return PR_FALSE; // No, return the default } - // Get the Gradient - nsCAutoString aGradStr; - CopyUTF16toUTF8(mNextGradStr, aGradStr); + nsCOMPtr targetURI; + nsCOMPtr base = mContent->GetBaseURI(); + nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), + mNextGradStr, mContent->GetCurrentDoc(), base); + // Note that we are using *our* frame tree for this call, otherwise we're going to have // to get the PresShell in each call - if (nsSVGUtils::GetReferencedFrame(&aNextGrad, aGradStr, mContent, GetPresContext()->PresShell()) == NS_OK) { + if (nsSVGUtils::GetReferencedFrame(&aNextGrad, targetURI, mContent, GetPresContext()->PresShell()) == NS_OK) { nsIAtom* frameType = aNextGrad->GetType(); if ((frameType != nsLayoutAtoms::svgLinearGradientFrame) && (frameType != nsLayoutAtoms::svgRadialGradientFrame)) @@ -1237,15 +1239,13 @@ nsresult NS_GetSVGGradient(nsISVGGradient **aGrad, nsIURI *aURI, nsIContent *aCo { *aGrad = nsnull; - // Get the spec from the URI +#ifdef DEBUG_scooter nsCAutoString uriSpec; aURI->GetSpec(uriSpec); -#ifdef DEBUG_scooter printf("NS_GetSVGGradient: uri = %s\n",uriSpec.get()); #endif nsIFrame *result; - if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&result, - uriSpec, aContent, aPresShell))) { + if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&result, aURI, aContent, aPresShell))) { return NS_ERROR_FAILURE; } return result->QueryInterface(NS_GET_IID(nsISVGGradient), (void **)aGrad); diff --git a/mozilla/layout/svg/base/src/nsSVGMarkerFrame.cpp b/mozilla/layout/svg/base/src/nsSVGMarkerFrame.cpp index bbcf01b4694..fafcddf773f 100644 --- a/mozilla/layout/svg/base/src/nsSVGMarkerFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGMarkerFrame.cpp @@ -113,14 +113,9 @@ NS_GetSVGMarkerFrame(nsSVGMarkerFrame **aResult, nsIURI *aURI, nsIContent *aCont } nsIPresShell *aPresShell = myDoc->GetShellAt(0); - // Get the URI Spec - nsCAutoString uriSpec; - aURI->GetSpec(uriSpec); - // Find the referenced frame nsIFrame *marker; - if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&marker, - uriSpec, aContent, aPresShell))) + if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&marker, aURI, aContent, aPresShell))) return NS_ERROR_FAILURE; nsIAtom* frameType = marker->GetType(); diff --git a/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp b/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp index 20078b448f0..ff46f05cf87 100644 --- a/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGPatternFrame.cpp @@ -810,12 +810,14 @@ nsSVGPatternFrame::checkURITarget(void) { return PR_FALSE; // No, return the default } - // Get the Pattern - nsCAutoString aPatternStr; - CopyUTF16toUTF8(mNextPatternStr, aPatternStr); + nsCOMPtr targetURI; + nsCOMPtr base = mContent->GetBaseURI(); + nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), + mNextPatternStr, mContent->GetCurrentDoc(), base); + // Note that we are using *our* frame tree for this call, // otherwise we're going to have to get the PresShell in each call - if (nsSVGUtils::GetReferencedFrame(&aNextPattern, aPatternStr, mContent, GetPresContext()->PresShell()) == NS_OK) { + if (nsSVGUtils::GetReferencedFrame(&aNextPattern, targetURI, mContent, GetPresContext()->PresShell()) == NS_OK) { nsIAtom* frameType = aNextPattern->GetType(); if (frameType != nsLayoutAtoms::svgPatternFrame) return PR_FALSE; @@ -1221,15 +1223,13 @@ nsresult NS_GetSVGPattern(nsISVGPattern **aPattern, nsIURI *aURI, { *aPattern = nsnull; - // Get the spec from the URI +#ifdef scooter_DEBUG nsCAutoString uriSpec; aURI->GetSpec(uriSpec); -#ifdef scooter_DEBUG printf("NS_GetSVGGradient: uri = %s\n",uriSpec.get()); #endif nsIFrame *result; - if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&result, - uriSpec, + if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&result, aURI, aContent, aPresShell))) return NS_ERROR_FAILURE; return result->QueryInterface(NS_GET_IID(nsISVGPattern), (void **)aPattern); diff --git a/mozilla/layout/svg/base/src/nsSVGTextPathFrame.cpp b/mozilla/layout/svg/base/src/nsSVGTextPathFrame.cpp index 93aef16e74c..58b50a214af 100644 --- a/mozilla/layout/svg/base/src/nsSVGTextPathFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGTextPathFrame.cpp @@ -42,6 +42,7 @@ #include "nsISVGPathFlatten.h" #include "nsSVGLength.h" #include "nsSVGUtils.h" +#include "nsNetUtil.h" #include "nsIDOMSVGAnimatedPathData.h" #include "nsIDOMSVGPathSegList.h" @@ -222,15 +223,16 @@ nsSVGTextPathFrame::GetFlattenedPath(nsSVGPathData **data, nsIFrame *parent) { *data = nsnull; nsIFrame *path; - nsAutoString aStr; - mHref->GetAnimVal(aStr); + nsAutoString str; + mHref->GetAnimVal(str); - nsCAutoString aCStr; - CopyUTF16toUTF8(aStr, aCStr); + nsCOMPtr targetURI; + nsCOMPtr base = mContent->GetBaseURI(); + nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), + str, mContent->GetCurrentDoc(), base); - nsSVGUtils::GetReferencedFrame(&path, aCStr, mContent, + nsSVGUtils::GetReferencedFrame(&path, targetURI, mContent, GetPresContext()->PresShell()); - if (!path) return NS_ERROR_FAILURE; diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.cpp b/mozilla/layout/svg/base/src/nsSVGUtils.cpp index a1233e58ae6..bd4f0eff2d9 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.cpp +++ b/mozilla/layout/svg/base/src/nsSVGUtils.cpp @@ -1,4 +1,3 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -154,82 +153,21 @@ nsSVGUtils::CoordToFloat(nsPresContext *aPresContext, nsIContent *aContent, return val; } -nsresult nsSVGUtils::GetReferencedFrame(nsIFrame **aRefFrame, nsCAutoString& uriSpec, nsIContent *aContent, +nsresult nsSVGUtils::GetReferencedFrame(nsIFrame **aRefFrame, nsIURI* aURI, nsIContent *aContent, nsIPresShell *aPresShell) { - nsresult rv = NS_OK; - *aRefFrame = nsnull; - - // Get the ID from the spec (no ID = an error) - PRInt32 pos = uriSpec.FindChar('#'); - if (pos == -1) { - NS_ASSERTION(pos != -1, "URI Spec not a reference"); + nsIContent* content = nsContentUtils::GetReferencedElement(aURI, aContent); + if (!content) return NS_ERROR_FAILURE; - } - - // Get the current document - nsIDocument *myDoc = aContent->GetCurrentDoc(); - if (!myDoc) { - NS_WARNING("Content doesn't reference a Document!"); - return NS_ERROR_FAILURE; - } - - // Get our URI - nsCOMPtr myURI = myDoc->GetDocumentURI(); - -#ifdef DEBUG_scooter - // Get the uri Spec - nsCAutoString dSpec; - myURI->GetSpec(dSpec); - printf("Document URI = %s, target URI = %s\n",dSpec.get(), uriSpec.get()); -#endif - - // Create a URI out of the target - nsCAutoString aURISName; - uriSpec.Left(aURISName, pos); - nsCOMPtr targetURI; - NS_NewURI(getter_AddRefs(targetURI), aURISName, nsnull, myDoc->GetBaseURI()); - PRBool match; - myURI->Equals(targetURI, &match); - if (!match) { - // Oops -- we don't support off-document references - return NS_ERROR_FAILURE; - } - - // At this point, we know we have a target within our document, but - // it may not point to anything - // Strip off the hash and get the name - nsCAutoString aURICName; - uriSpec.Right(aURICName, uriSpec.Length()-(pos + 1)); - - // Get a unicode string - nsAutoString aURIName; - CopyUTF8toUTF16(aURICName, aURIName); - - // Get the domDocument - nsCOMPtrdomDoc = do_QueryInterface(myDoc); - NS_ASSERTION(domDoc, "Content doesn't reference a dom Document"); - if (domDoc == nsnull) { - return NS_ERROR_FAILURE; - } - - // Get the element - nsCOMPtr element; - rv = domDoc->GetElementById(aURIName, getter_AddRefs(element)); - if (!NS_SUCCEEDED(rv) || element == nsnull) { - return NS_ERROR_FAILURE; - } // Get the Primary Frame - nsCOMPtr aGContent = do_QueryInterface(element); NS_ASSERTION(aPresShell, "Get referenced SVG frame -- no pres shell provided"); if (!aPresShell) return NS_ERROR_FAILURE; - *aRefFrame = aPresShell->GetPrimaryFrameFor(aGContent); - NS_ASSERTION(*aRefFrame, "Get referenced SVG frame -- can't find primary frame"); + *aRefFrame = aPresShell->GetPrimaryFrameFor(content); if (!(*aRefFrame)) return NS_ERROR_FAILURE; - return rv; + return NS_OK; } nsresult nsSVGUtils::GetPaintType(PRUint16 *aPaintType, const nsStyleSVGPaint& aPaint, @@ -238,18 +176,14 @@ nsresult nsSVGUtils::GetPaintType(PRUint16 *aPaintType, const nsStyleSVGPaint& a *aPaintType = aPaint.mType; // If the type is a Paint Server, determine what kind if (*aPaintType == nsISVGGeometrySource::PAINT_TYPE_SERVER) { - nsIURI *aServer = aPaint.mPaint.mPaintServer; - if (aServer == nsnull) + nsIURI *server = aPaint.mPaint.mPaintServer; + if (server == nsnull) return NS_ERROR_FAILURE; - // Get the uri Spec - nsCAutoString uriSpec; - aServer->GetSpec(uriSpec); - // Get the frame nsIFrame *aFrame = nsnull; nsresult rv; - rv = nsSVGUtils::GetReferencedFrame(&aFrame, uriSpec, aContent, aPresShell); + rv = GetReferencedFrame(&aFrame, server, aContent, aPresShell); if (!NS_SUCCEEDED(rv) || !aFrame) return NS_ERROR_FAILURE; diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.h b/mozilla/layout/svg/base/src/nsSVGUtils.h index 4ecb2879105..b09d8e7077c 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.h +++ b/mozilla/layout/svg/base/src/nsSVGUtils.h @@ -50,6 +50,7 @@ struct nsStyleSVGPaint; class nsISVGRendererRegion; class nsIDOMSVGLength; class nsIDOMSVGMatrix; +class nsIURI; class nsSVGUtils { @@ -70,9 +71,8 @@ public: * Gets an internal frame for an element referenced by a URI. Note that this * only works for URIs that reference elements within the same document. */ - static nsresult GetReferencedFrame(nsIFrame **aRefFrame, nsCAutoString& uriSpec, - nsIContent *aContent, - nsIPresShell *aPresShell); + static nsresult GetReferencedFrame(nsIFrame **aRefFrame, nsIURI* aURI, + nsIContent *aContent, nsIPresShell *aPresShell); /* * For SVGPaint attributes (fills, strokes), return the type of the Paint. This * is an expanded type that includes whether this is a solid fill, a gradient, or