Bug 309020. SVG content references in XBL anonymous content should reference content copied from the binding document. This is a partial fix. We also refactor some code to make it shareable in nsContentUtils. r=biesi,tor sr=bzbarsky

git-svn-id: svn://10.0.0.236/trunk@182487 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
roc+%cs.cmu.edu
2005-10-18 20:33:35 +00:00
parent 195ae411fb
commit 3aa042c0b4
13 changed files with 291 additions and 212 deletions

View File

@@ -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

View File

@@ -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 <nsIAtom> docCharsetAtom;
nsCOMPtr<nsICharsetConverterManager> ccm =
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIUnicodeDecoder> 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);

View File

@@ -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<nsIXMLContent> 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<nsICharsetConverterManager> ccm =
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIUnicodeDecoder> 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<nsIURI> u1;
nsCOMPtr<nsIURI> 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<nsIURL> url1 = do_QueryInterface(u1);
nsCOMPtr<nsIURL> 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<nsIURL> 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<nsIURL> 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<nsIContent> content;
if (isXBL) {
nsCOMPtr<nsIDOMNodeList> anonymousChildren;
doc->BindingManager()->
GetAnonymousNodesFor(bindingParent, getter_AddRefs(anonymousChildren));
if (anonymousChildren) {
PRUint32 length;
anonymousChildren->GetLength(&length);
for (PRUint32 i = 0; i < length && !content; ++i) {
nsCOMPtr<nsIDOMNode> node;
anonymousChildren->Item(i, getter_AddRefs(node));
nsCOMPtr<nsIContent> c = do_QueryInterface(node);
if (c) {
content = MatchElementId(c, ref);
}
}
}
} else {
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
NS_ASSERTION(domDoc, "Content doesn't reference a dom Document");
nsCOMPtr<nsIDOMElement> element;
rv = domDoc->GetElementById(ref, getter_AddRefs(element));
if (element) {
content = do_QueryInterface(element);
}
}
return content;
}

View File

@@ -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);
}
}

View File

@@ -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<nsIXMLContent> 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;

View File

@@ -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();

View File

@@ -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();

View File

@@ -655,12 +655,14 @@ nsSVGGradientFrame::checkURITarget(void) {
return PR_FALSE; // No, return the default
}
// Get the Gradient
nsCAutoString aGradStr;
CopyUTF16toUTF8(mNextGradStr, aGradStr);
nsCOMPtr<nsIURI> targetURI;
nsCOMPtr<nsIURI> 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);

View File

@@ -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();

View File

@@ -810,12 +810,14 @@ nsSVGPatternFrame::checkURITarget(void) {
return PR_FALSE; // No, return the default
}
// Get the Pattern
nsCAutoString aPatternStr;
CopyUTF16toUTF8(mNextPatternStr, aPatternStr);
nsCOMPtr<nsIURI> targetURI;
nsCOMPtr<nsIURI> 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);

View File

@@ -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<nsIURI> targetURI;
nsCOMPtr<nsIURI> 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;

View File

@@ -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<nsIURI> 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<nsIURI> 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
nsCOMPtr<nsIDOMDocument>domDoc = do_QueryInterface(myDoc);
NS_ASSERTION(domDoc, "Content doesn't reference a dom Document");
if (domDoc == nsnull) {
return NS_ERROR_FAILURE;
}
// Get the element
nsCOMPtr<nsIDOMElement> element;
rv = domDoc->GetElementById(aURIName, getter_AddRefs(element));
if (!NS_SUCCEEDED(rv) || element == nsnull) {
return NS_ERROR_FAILURE;
}
// Get the Primary Frame
nsCOMPtr<nsIContent> 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;

View File

@@ -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