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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user