Make XBL anonymous content get its base URI from the XBL document (the binding

URI) instead of from the document of the bound element.  This way relative URIs
in a binding are always relative to the binding.  Bug 211128, r=caillon, sr=jst


git-svn-id: svn://10.0.0.236/trunk@144753 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu 2003-07-11 23:06:26 +00:00
parent 5435c5826d
commit c8ff7820a4
11 changed files with 78 additions and 33 deletions

View File

@ -449,7 +449,7 @@ public:
*
* @param aContent the binding parent [OUT]
*/
NS_IMETHOD GetBindingParent(nsIContent** aContent) = 0;
NS_IMETHOD GetBindingParent(nsIContent** aContent) const = 0;
/**
* Bit-flags to pass (or'ed together) to IsContentOfType()

View File

@ -1028,8 +1028,9 @@ nsGenericDOMDataNode::RemoveFocus(nsIPresContext* aPresContext)
}
NS_IMETHODIMP
nsGenericDOMDataNode::GetBindingParent(nsIContent** aContent)
nsGenericDOMDataNode::GetBindingParent(nsIContent** aContent) const
{
*aContent = nsnull;
return NS_OK;
}

View File

@ -208,7 +208,7 @@ public:
NS_IMETHOD SetFocus(nsIPresContext *aPresContext);
NS_IMETHOD RemoveFocus(nsIPresContext *aPresContext);
NS_IMETHOD GetBindingParent(nsIContent** aContent);
NS_IMETHOD GetBindingParent(nsIContent** aContent) const;
NS_IMETHOD SetBindingParent(nsIContent* aParent);
NS_IMETHOD_(PRBool) IsContentOfType(PRUint32 aFlags);

View File

@ -2252,14 +2252,46 @@ nsGenericElement::GetBaseURL(nsIURI** aBaseURL) const
mNodeInfo->GetDocument(getter_AddRefs(doc));
}
// Our base URL depends on whether we have an xml:base attribute, as
// well as on whether any of our ancestors do.
nsCOMPtr<nsIURI> parentBase;
// Our base URL depends on whether we have an xml:base attribute, as well as
// on whether any of our ancestors do. The basic idea is to ask our parent
// (mParent if we have one, our document otherwise) for its base URL. Then we
// resolve our xml:base attr, if any, relative to that.
// The one complication is that we may be an anonymous node bound via XBL.
// If this is the case, we still want to use our parent's baseURL unless our
// parent is not part of our own binding (eg is the element the binding is
// attached to). If that is the case, we want to use the binding url as the
// "parent" url.
nsCOMPtr<nsIContent> bindingParent, parentsBindingParent;
GetBindingParent(getter_AddRefs(bindingParent));
if (mParent) {
mParent->GetBindingParent(getter_AddRefs(parentsBindingParent));
}
nsCOMPtr<nsIURI> parentBase;
// XXX Not all things with a bindingParent are actually XBL anonymous
// content, so we may not end up getting a binding in the case when we have a
// bindingParent... This seems very wrong. Perhaps it should be fixed?
if (bindingParent && bindingParent != parentsBindingParent) {
// Get hold of the binding and get its URI
nsCOMPtr<nsIBindingManager> bindingMgr;
doc->GetBindingManager(getter_AddRefs(bindingMgr));
if (bindingMgr) {
nsCOMPtr<nsIXBLBinding> binding;
bindingMgr->GetBinding(bindingParent, getter_AddRefs(binding));
if (binding) {
nsCAutoString bindingURI;
binding->GetBindingURI(bindingURI);
NS_NewURI(getter_AddRefs(parentBase), bindingURI);
}
}
} else if (mParent) {
mParent->GetBaseURL(getter_AddRefs(parentBase));
} else if (doc) {
// No parent, so just use the document (we must be the root or not in the
// tree).
}
if (!parentBase && doc) {
doc->GetBaseURL(getter_AddRefs(parentBase));
}
@ -2452,7 +2484,7 @@ nsGenericElement::RemoveFocus(nsIPresContext* aPresContext)
}
nsresult
nsGenericElement::GetBindingParent(nsIContent** aContent)
nsGenericElement::GetBindingParent(nsIContent** aContent) const
{
nsDOMSlots *slots = GetExistingDOMSlots();

View File

@ -415,7 +415,7 @@ public:
NS_IMETHOD SetContentID(PRUint32 aID);
NS_IMETHOD SetFocus(nsIPresContext* aContext);
NS_IMETHOD RemoveFocus(nsIPresContext* aContext);
NS_IMETHOD GetBindingParent(nsIContent** aContent);
NS_IMETHOD GetBindingParent(nsIContent** aContent) const;
NS_IMETHOD SetBindingParent(nsIContent* aParent);
NS_IMETHOD_(PRBool) IsContentOfType(PRUint32 aFlags);
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);

View File

@ -119,7 +119,8 @@ public:
NS_IMETHOD SetFocus(nsIPresContext* aPresContext) { return NS_OK; }
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext) { return NS_OK; }
NS_IMETHOD GetBindingParent(nsIContent** aContent) {
NS_IMETHOD GetBindingParent(nsIContent** aContent) const {
*aContent = nsnull;
return NS_OK;
}

View File

@ -324,8 +324,11 @@ nsXBLBinding::InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElem
for (PRInt32 i = 0; i < childCount; i++) {
nsCOMPtr<nsIContent> child;
aAnonParent->ChildAt(i, getter_AddRefs(child));
child->SetParent(aElement);
// Set the binding parent first, since setting the parent may cause
// relative URIs to change (due to xml:base) and |child| may need to be
// able to tell that it's anonymous content as it recomputes its base URI.
child->SetBindingParent(mBoundElement);
child->SetParent(aElement);
#ifdef MOZ_XUL
// To make XUL templates work (and other goodies that happen when

View File

@ -4331,10 +4331,9 @@ nsXULElement::RemoveFocus(nsIPresContext* aPresContext)
}
NS_IMETHODIMP
nsXULElement::GetBindingParent(nsIContent** aContent)
nsXULElement::GetBindingParent(nsIContent** aContent) const
{
*aContent = mBindingParent;
NS_IF_ADDREF(*aContent);
NS_IF_ADDREF(*aContent = mBindingParent);
return NS_OK;
}

View File

@ -152,9 +152,12 @@ nsHTMLEditor::CreateAnonymousElement(const nsAString & aTag, nsIDOMNode * aPare
// establish parenthood of the element
newContent->SetNativeAnonymous(PR_TRUE);
newContent->SetParent(parentContent);
newContent->SetDocument(doc, PR_TRUE, PR_TRUE);
// Set the binding parent first, since setting the parent may cause relative
// URIs to change (due to xml:base) and |newContent| may need to be able to
// tell that it's anonymous content as it recomputes its base URI.
newContent->SetBindingParent(newContent);
newContent->SetParent(parentContent);
// display the element
ps->RecreateFramesFor(newContent);

View File

@ -5127,23 +5127,26 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell
continue;
content->SetNativeAnonymous(PR_TRUE);
content->SetParent(aParent);
content->SetDocument(aDocument, PR_TRUE, PR_TRUE);
// Set the binding parent first, since setting the parent may cause
// relative URIs to change (due to xml:base) and |child| may need to be
// able to tell that it's anonymous content as it recomputes its base
// URI.
nsIContent* bindingParent = content;
#ifdef MOZ_XUL
// Only cut XUL scrollbars off if they're not in a XUL document. This allows
// scrollbars to be styled from XUL (although not from XML or HTML).
nsCOMPtr<nsIAtom> tag;
content->GetTag(getter_AddRefs(tag));
if (tag.get() == nsXULAtoms::scrollbar) {
if (tag == nsXULAtoms::scrollbar) {
nsCOMPtr<nsIDOMXULDocument> xulDoc(do_QueryInterface(aDocument));
if (xulDoc)
content->SetBindingParent(aParent);
else content->SetBindingParent(content);
if (xulDoc) {
bindingParent = aParent;
}
}
else
#endif
content->SetBindingParent(content);
content->SetBindingParent(bindingParent);
content->SetParent(aParent);
nsIFrame * newFrame = nsnull;
nsresult rv = creator->CreateFrameFor(aPresContext, content, &newFrame);

View File

@ -5127,23 +5127,26 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell
continue;
content->SetNativeAnonymous(PR_TRUE);
content->SetParent(aParent);
content->SetDocument(aDocument, PR_TRUE, PR_TRUE);
// Set the binding parent first, since setting the parent may cause
// relative URIs to change (due to xml:base) and |child| may need to be
// able to tell that it's anonymous content as it recomputes its base
// URI.
nsIContent* bindingParent = content;
#ifdef MOZ_XUL
// Only cut XUL scrollbars off if they're not in a XUL document. This allows
// scrollbars to be styled from XUL (although not from XML or HTML).
nsCOMPtr<nsIAtom> tag;
content->GetTag(getter_AddRefs(tag));
if (tag.get() == nsXULAtoms::scrollbar) {
if (tag == nsXULAtoms::scrollbar) {
nsCOMPtr<nsIDOMXULDocument> xulDoc(do_QueryInterface(aDocument));
if (xulDoc)
content->SetBindingParent(aParent);
else content->SetBindingParent(content);
if (xulDoc) {
bindingParent = aParent;
}
}
else
#endif
content->SetBindingParent(content);
content->SetBindingParent(bindingParent);
content->SetParent(aParent);
nsIFrame * newFrame = nsnull;
nsresult rv = creator->CreateFrameFor(aPresContext, content, &newFrame);