Cleaned up code that mutates an element's ID, modulo bug 3971.

This commit is contained in:
waterson%netscape.com 1999-03-18 20:46:02 +00:00
Родитель a65bea02df
Коммит 0338e56e86
11 изменённых файлов: 325 добавлений и 259 удалений

Просмотреть файл

@ -705,11 +705,17 @@ RDFElementImpl::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDO
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnInsertBefore(this, aNewChild, aRefChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnInsertBefore(this, aNewChild, aRefChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -723,11 +729,17 @@ RDFElementImpl::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDO
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnReplaceChild(this, aNewChild, aOldChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnReplaceChild(this, aNewChild, aOldChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -741,11 +753,17 @@ RDFElementImpl::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnRemoveChild(this, aOldChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnRemoveChild(this, aOldChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aOldChild);
*aReturn = aOldChild;
return NS_OK;
@ -759,11 +777,17 @@ RDFElementImpl::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnAppendChild(this, aNewChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnAppendChild(this, aNewChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -1588,29 +1612,6 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
nsresult rv = NS_OK;
// If they're changing the identity of this object, then we need to re-hash
// it into the document's resource-to-element map.
//
// XXX Changing the object's identity is a big deal: we actually need to
// toss the kids and recreate them. We don't do that here.
// XXX This code doesn't work unless ID is set, since GetResource
// actually tries to fetch the ID! We need to move this whole
// block down so that we can figure out whether or not we're making
// a NEW ID or overwriting an EXISTING ID - Dave.
/*if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kIdAtom) { // XXX regardless of namespace
nsCOMPtr<nsIRDFDocument> rdfDoc( do_QueryInterface(mDocument) );
NS_ASSERTION(rdfDoc != nsnull, "not an RDF document");
if (rdfDoc) {
nsCOMPtr<nsIRDFResource> resource;
if (NS_SUCCEEDED(rv = GetResource(getter_AddRefs(resource)))) {
if (NS_FAILED(rv = rdfDoc->RemoveElementForResource(resource, this))) {
NS_ERROR("unable to remove element from map");
return rv;
}
}
}
}*/
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
@ -1656,22 +1657,6 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
mAttributes->AppendElement(attr);
}
// XXX Changing the object's identity is a big deal: we actually need to
// toss the kids and recreate them. We don't do that here.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kIdAtom) { // XXX regardless of namespace
nsCOMPtr<nsIRDFDocument> rdfDoc( do_QueryInterface(mDocument) );
NS_ASSERTION(rdfDoc != nsnull, "not an RDF document");
if (rdfDoc) {
nsCOMPtr<nsIRDFResource> resource;
if (NS_SUCCEEDED(rv = GetResource(getter_AddRefs(resource)))) {
if (NS_FAILED(rv = rdfDoc->AddElementForResource(resource, this))) {
NS_ERROR("unable to remove element from map");
return rv;
}
}
}
}
// Check for event handlers
nsString attributeName;
aName->ToString(attributeName);
@ -2291,6 +2276,7 @@ RDFElementImpl::GetResource(nsIRDFResource** aResource)
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-relative ID attribute into a fully-qualified (that is, with
// the current document's URL) URI.
NS_ASSERTION(mDocument != nsnull, "element has no document");
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
@ -2321,7 +2307,10 @@ RDFElementImpl::EnsureContentsGenerated(void) const
nsresult rv;
// NS_PRECONDITION(mDocument != nsnull, "not initialized");
// Ensure that the element is actually _in_ the document tree;
// otherwise, somebody is trying to generate children for a node
// that's not currently in the content model.
NS_PRECONDITION(mDocument != nsnull, "element not in tree");
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;

Просмотреть файл

@ -273,7 +273,11 @@ public:
}
}
// NS_ERROR("attempt to remove an element that was never added");
// XXX Don't comment out this assert: if you get here,
// something has gone dreadfully, horribly
// wrong. Curse. Scream. File a bug against
// waterson@netscape.com.
NS_ERROR("attempt to remove an element that was never added");
return NS_ERROR_ILLEGAL_VALUE;
}
@ -1933,6 +1937,12 @@ XULDocumentImpl::AddElementForResource(nsIRDFResource* aResource, nsIContent* aE
if (! aElement)
return NS_ERROR_NULL_POINTER;
#ifdef DEBUG
const char* uri;
aResource->GetValue(&uri);
printf("add [%p] <-- %s\n", aElement, uri);
#endif
mResources.Add(aResource, aElement);
return NS_OK;
}
@ -1949,6 +1959,12 @@ XULDocumentImpl::RemoveElementForResource(nsIRDFResource* aResource, nsIContent*
if (! aElement)
return NS_ERROR_NULL_POINTER;
#ifdef DEBUG
const char* uri;
aResource->GetValue(&uri);
printf("remove [%p] <-- %s\n", aElement, uri);
#endif
mResources.Remove(aResource, aElement);
return NS_OK;
}
@ -2282,6 +2298,11 @@ XULDocumentImpl::GetElementById(const nsString& aId, nsIDOMElement** aReturn)
}
if (elements->Count() > 0) {
if (elements->Count() > 1) {
// This is a scary case that our API doesn't deal with well.
NS_WARNING("more than one element found with specified ID; returning first");
}
nsISupports* element = elements->ElementAt(0);
rv = element->QueryInterface(nsIDOMElement::GetIID(), (void**) aReturn);
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM element");
@ -2290,6 +2311,14 @@ XULDocumentImpl::GetElementById(const nsString& aId, nsIDOMElement** aReturn)
}
// Didn't find it in our hash table. Walk the tree looking for the node
// I'd like to make this an NS_ERROR(), but am sure someone would
// just comment it out :-/. This should've all been set up when
// nsRDFElement::SetDocument() got called. (Of course, somebody
// could've inserted a non-RDF element into this tree, so, I guess
// we'll leave it as a warning for now...)
NS_WARNING("unable to find hashed element; crawling the tree to find it");
*aReturn = nsnull;
SearchForNodeByID(aId, mRootContent, aReturn);

Просмотреть файл

@ -587,7 +587,7 @@ XULSortServiceImpl::RemoveAllChildren(nsIContent *container)
for (childIndex=numChildren-1; childIndex >= 0; childIndex--)
{
if (NS_FAILED(rv = container->ChildAt(childIndex, *getter_AddRefs(child)))) break;
container->RemoveChildAt(childIndex, PR_TRUE);
container->RemoveChildAt(childIndex, PR_FALSE);
}
return(rv);
}
@ -832,7 +832,7 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, so
numChildren = 0;
for (loop=0; loop<numElements; loop++)
{
container->InsertChildAt((nsIContent *)flatArray[loop], numChildren++, PR_TRUE);
container->InsertChildAt((nsIContent *)flatArray[loop], numChildren++, PR_FALSE);
}
// recurse on grandchildren
@ -1039,18 +1039,22 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
else if (sortDirection.EqualsIgnoreCase("descending")) sortInfo.descendingSort = PR_TRUE;
}
// get index of sort column, find tree body, remove tree body from tree, sort, then re-add tree body
// get index of sort column, find tree body, and sort. The sort
// _won't_ send any notifications, so we won't trigger any
// reflows...
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, sortDirection, &colIndex))) return(rv);
sortInfo.colIndex = colIndex;
if (NS_FAILED(rv = FindTreeBodyElement(treeNode, &treeBody))) return(rv);
if (NS_FAILED(rv = treeBody->GetParent(treeParent))) return(rv);
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
if (NS_SUCCEEDED(rv = SortTreeChildren(treeBody, colIndex, &sortInfo, 0)))
{
}
if (NS_SUCCEEDED(rv = treeBody->UnsetAttribute(kNameSpaceID_None,
// Now remove the treebody and re-insert it to force the frames to be rebuilt.
if (NS_FAILED(rv = treeBody->GetParent(treeParent))) return(rv);
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
if (NS_SUCCEEDED(rv = treeBody->UnsetAttribute(kNameSpaceID_None,
kTreeContentsGeneratedAtom,PR_FALSE)))
{
}

Просмотреть файл

@ -1489,9 +1489,9 @@ RDFGenericBuilderImpl::GetDOMNodeResource(nsIDOMNode* aNode, nsIRDFResource** aR
nsresult
RDFGenericBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
nsIAtom* aTag,
nsIRDFResource* aResource,
nsIContent** aResult)
nsIAtom* aTag,
nsIRDFResource* aResource,
nsIContent** aResult)
{
nsresult rv;
@ -1515,8 +1515,8 @@ RDFGenericBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
nsresult
RDFGenericBuilderImpl::GetResource(PRInt32 aNameSpaceID,
nsIAtom* aNameAtom,
nsIRDFResource** aResource)
nsIAtom* aNameAtom,
nsIRDFResource** aResource)
{
NS_PRECONDITION(aNameAtom != nsnull, "null ptr");
if (! aNameAtom)

Просмотреть файл

@ -705,11 +705,17 @@ RDFElementImpl::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDO
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnInsertBefore(this, aNewChild, aRefChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnInsertBefore(this, aNewChild, aRefChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -723,11 +729,17 @@ RDFElementImpl::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDO
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnReplaceChild(this, aNewChild, aOldChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnReplaceChild(this, aNewChild, aOldChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -741,11 +753,17 @@ RDFElementImpl::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnRemoveChild(this, aOldChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnRemoveChild(this, aOldChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aOldChild);
*aReturn = aOldChild;
return NS_OK;
@ -759,11 +777,17 @@ RDFElementImpl::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnAppendChild(this, aNewChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnAppendChild(this, aNewChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -1588,29 +1612,6 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
nsresult rv = NS_OK;
// If they're changing the identity of this object, then we need to re-hash
// it into the document's resource-to-element map.
//
// XXX Changing the object's identity is a big deal: we actually need to
// toss the kids and recreate them. We don't do that here.
// XXX This code doesn't work unless ID is set, since GetResource
// actually tries to fetch the ID! We need to move this whole
// block down so that we can figure out whether or not we're making
// a NEW ID or overwriting an EXISTING ID - Dave.
/*if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kIdAtom) { // XXX regardless of namespace
nsCOMPtr<nsIRDFDocument> rdfDoc( do_QueryInterface(mDocument) );
NS_ASSERTION(rdfDoc != nsnull, "not an RDF document");
if (rdfDoc) {
nsCOMPtr<nsIRDFResource> resource;
if (NS_SUCCEEDED(rv = GetResource(getter_AddRefs(resource)))) {
if (NS_FAILED(rv = rdfDoc->RemoveElementForResource(resource, this))) {
NS_ERROR("unable to remove element from map");
return rv;
}
}
}
}*/
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
@ -1656,22 +1657,6 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
mAttributes->AppendElement(attr);
}
// XXX Changing the object's identity is a big deal: we actually need to
// toss the kids and recreate them. We don't do that here.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kIdAtom) { // XXX regardless of namespace
nsCOMPtr<nsIRDFDocument> rdfDoc( do_QueryInterface(mDocument) );
NS_ASSERTION(rdfDoc != nsnull, "not an RDF document");
if (rdfDoc) {
nsCOMPtr<nsIRDFResource> resource;
if (NS_SUCCEEDED(rv = GetResource(getter_AddRefs(resource)))) {
if (NS_FAILED(rv = rdfDoc->AddElementForResource(resource, this))) {
NS_ERROR("unable to remove element from map");
return rv;
}
}
}
}
// Check for event handlers
nsString attributeName;
aName->ToString(attributeName);
@ -2291,6 +2276,7 @@ RDFElementImpl::GetResource(nsIRDFResource** aResource)
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-relative ID attribute into a fully-qualified (that is, with
// the current document's URL) URI.
NS_ASSERTION(mDocument != nsnull, "element has no document");
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
@ -2321,7 +2307,10 @@ RDFElementImpl::EnsureContentsGenerated(void) const
nsresult rv;
// NS_PRECONDITION(mDocument != nsnull, "not initialized");
// Ensure that the element is actually _in_ the document tree;
// otherwise, somebody is trying to generate children for a node
// that's not currently in the content model.
NS_PRECONDITION(mDocument != nsnull, "element not in tree");
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;

Просмотреть файл

@ -1489,9 +1489,9 @@ RDFGenericBuilderImpl::GetDOMNodeResource(nsIDOMNode* aNode, nsIRDFResource** aR
nsresult
RDFGenericBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
nsIAtom* aTag,
nsIRDFResource* aResource,
nsIContent** aResult)
nsIAtom* aTag,
nsIRDFResource* aResource,
nsIContent** aResult)
{
nsresult rv;
@ -1515,8 +1515,8 @@ RDFGenericBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
nsresult
RDFGenericBuilderImpl::GetResource(PRInt32 aNameSpaceID,
nsIAtom* aNameAtom,
nsIRDFResource** aResource)
nsIAtom* aNameAtom,
nsIRDFResource** aResource)
{
NS_PRECONDITION(aNameAtom != nsnull, "null ptr");
if (! aNameAtom)

Просмотреть файл

@ -1161,6 +1161,23 @@ RDFXULBuilderImpl::OnSetAttribute(nsIDOMElement* aElement, const nsString& aName
return NS_OK;
}
// Make sure it's a XUL element; otherwise, we really don't have
// any business with the attribute.
PRBool isXULElement;
if (NS_FAILED(rv = mDB->HasAssertion(resource,
kRDF_instanceOf,
kXUL_element,
PR_TRUE,
&isXULElement))) {
NS_ERROR("unable to determine if element is a XUL element");
return rv;
}
if (! isXULElement)
return NS_OK;
// Okay, so it _is_ a XUL element. Deal with it.
// Get the nsIContent interface, it's a bit more utilitarian
nsCOMPtr<nsIContent> element( do_QueryInterface(aElement) );
if (! element) {
@ -1168,64 +1185,70 @@ RDFXULBuilderImpl::OnSetAttribute(nsIDOMElement* aElement, const nsString& aName
return NS_ERROR_UNEXPECTED;
}
// Make sure it's a XUL element; otherwise, we really don't have
// any business with the attribute.
PRBool isXULElement;
if (NS_SUCCEEDED(rv = mDB->HasAssertion(resource,
kRDF_instanceOf,
kXUL_element,
PR_TRUE,
&isXULElement))
&& isXULElement) {
// Split the property name into its namespace and tag components
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> nameAtom;
if (NS_FAILED(rv = element->ParseAttributeString(aName, *getter_AddRefs(nameAtom), nameSpaceID))) {
NS_ERROR("unable to parse attribute string");
return rv;
}
// Get the nsIContent interface, it's a bit more utilitarian
nsCOMPtr<nsIContent> element( do_QueryInterface(aElement) );
if (! element) {
NS_ERROR("element doesn't support nsIContent");
return NS_ERROR_UNEXPECTED;
// Check for "special" properties that may wreak havoc on the
// content model.
if ((nameSpaceID == kNameSpaceID_None) && (nameAtom == kIdAtom)) {
// They're changing the ID of the element.
// XXX Punt for now.
NS_WARNING("ignoring id change on XUL element");
return NS_OK;
}
else if (nameSpaceID == kNameSpaceID_RDF) {
if (nameAtom == kDataSourcesAtom) {
NS_NOTYETIMPLEMENTED("can't change the data sources yet");
return NS_ERROR_NOT_IMPLEMENTED;
}
// Split the property name into its namespace and tag components
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> nameAtom;
if (NS_FAILED(rv = element->ParseAttributeString(aName, *getter_AddRefs(nameAtom), nameSpaceID))) {
NS_ERROR("unable to parse attribute string");
// XXX we should probably just ignore any changes to rdf: attribute
NS_WARNING("changing an rdf: attribute; this is probably not a good thing");
return NS_OK;
}
// If we get here, it's a vanilla property that we need to go into
// the RDF graph to update. So, build an RDF resource from the
// property name...
nsCOMPtr<nsIRDFResource> property;
if (NS_FAILED(rv = GetResource(nameSpaceID, nameAtom, getter_AddRefs(property)))) {
NS_ERROR("unable to construct resource");
return rv;
}
// Unassert the old value, if there was one.
nsAutoString oldValue;
if (NS_CONTENT_ATTR_HAS_VALUE == element->GetAttribute(nameSpaceID, nameAtom, oldValue)) {
nsCOMPtr<nsIRDFLiteral> value;
if (NS_FAILED(rv = gRDFService->GetLiteral(oldValue, getter_AddRefs(value)))) {
NS_ERROR("unable to construct literal");
return rv;
}
nsCOMPtr<nsIRDFResource> property;
if (NS_FAILED(rv = GetResource(nameSpaceID, nameAtom, getter_AddRefs(property)))) {
NS_ERROR("unable to construct resource");
rv = mDB->Unassert(resource, property, value);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to unassert old property value");
}
// Assert the new value
{
nsCOMPtr<nsIRDFLiteral> value;
if (NS_FAILED(rv = gRDFService->GetLiteral(aValue, getter_AddRefs(value)))) {
NS_ERROR("unable to construct literal");
return rv;
}
// Unassert the old value, if there was one.
nsAutoString oldValue;
if (NS_CONTENT_ATTR_HAS_VALUE == element->GetAttribute(nameSpaceID, nameAtom, oldValue)) {
nsCOMPtr<nsIRDFLiteral> value;
if (NS_FAILED(rv = gRDFService->GetLiteral(oldValue, getter_AddRefs(value)))) {
NS_ERROR("unable to construct literal");
return rv;
}
rv = mDB->Unassert(resource, property, value);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to unassert old property value");
if (NS_FAILED(rv = mDB->Assert(resource, property, value, PR_TRUE))) {
NS_ERROR("unable to assert new property value");
return rv;
}
// Assert the new value
{
nsCOMPtr<nsIRDFLiteral> value;
if (NS_FAILED(rv = gRDFService->GetLiteral(aValue, getter_AddRefs(value)))) {
NS_ERROR("unable to construct literal");
return rv;
}
if (NS_FAILED(rv = mDB->Assert(resource, property, value, PR_TRUE))) {
NS_ERROR("unable to assert new property value");
return rv;
}
}
}
}
return NS_OK;
}
@ -1464,17 +1487,16 @@ RDFXULBuilderImpl::CreateHTMLElement(nsIRDFResource* aResource,
return rv;
}
if (NS_FAILED(rv = element->SetDocument(doc, PR_FALSE))) {
NS_ERROR("couldn't set document on the element");
return rv;
}
// Make sure our ID is set. Unlike XUL elements, we want to make sure
// that our ID is relative if possible.
//
// XXX Why? Is this for supporting inline style or something?
const char* uri;
if (NS_FAILED(rv = aResource->GetValue(&uri)))
return rv;
// XXX Won't somebody just cram this back into a fully qualified
// URI somewhere?
nsString fullURI(uri);
nsIURL* docURL = nsnull;
doc->GetBaseURL(docURL);
@ -1485,8 +1507,18 @@ RDFXULBuilderImpl::CreateHTMLElement(nsIRDFResource* aResource,
NS_RELEASE(docURL);
}
if (NS_FAILED(rv = element->SetAttribute(kNameSpaceID_None, kIdAtom, fullURI, PR_FALSE)))
if (NS_FAILED(rv = element->SetAttribute(kNameSpaceID_None, kIdAtom, fullURI, PR_FALSE))) {
NS_ERROR("unable to set element's ID");
return rv;
}
// Set the document. N.B. that we do this _after_ setting up the
// ID so that we get the element hashed correctly in the
// document's resource-to-element map.
if (NS_FAILED(rv = element->SetDocument(doc, PR_FALSE))) {
NS_ERROR("couldn't set document on the element");
return rv;
}
// XXX Do we add ourselves to the map here? If so, this is non-dynamic!
// If the HTML element's ID changes, we won't adjust
@ -2008,12 +2040,9 @@ RDFXULBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
if (NS_FAILED(rv = NS_NewRDFElement(aNameSpaceID, aTag, getter_AddRefs(result))))
return rv;
// Set the document for this resource element. It must be set now
// in order for event handlers to be detected in the subsequent
// SetAttribute calls (and in the ID-setting call below).
nsCOMPtr<nsIDocument> document( do_QueryInterface(mDocument) );
result->SetDocument(document, PR_FALSE);
// Set the element's ID. We do this _before_ we insert the element
// into the document so that it gets properly hashed into the
// document's resource-to-element map.
const char* uri;
if (NS_FAILED(rv = aResource->GetValue(&uri)))
return rv;
@ -2021,6 +2050,10 @@ RDFXULBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
if (NS_FAILED(rv = result->SetAttribute(kNameSpaceID_None, kIdAtom, uri, PR_FALSE)))
return rv;
// Set the document for this element.
nsCOMPtr<nsIDocument> document( do_QueryInterface(mDocument) );
result->SetDocument(document, PR_FALSE);
*aResult = result;
NS_ADDREF(*aResult);
return NS_OK;

Просмотреть файл

@ -273,7 +273,11 @@ public:
}
}
// NS_ERROR("attempt to remove an element that was never added");
// XXX Don't comment out this assert: if you get here,
// something has gone dreadfully, horribly
// wrong. Curse. Scream. File a bug against
// waterson@netscape.com.
NS_ERROR("attempt to remove an element that was never added");
return NS_ERROR_ILLEGAL_VALUE;
}
@ -1933,6 +1937,12 @@ XULDocumentImpl::AddElementForResource(nsIRDFResource* aResource, nsIContent* aE
if (! aElement)
return NS_ERROR_NULL_POINTER;
#ifdef DEBUG
const char* uri;
aResource->GetValue(&uri);
printf("add [%p] <-- %s\n", aElement, uri);
#endif
mResources.Add(aResource, aElement);
return NS_OK;
}
@ -1949,6 +1959,12 @@ XULDocumentImpl::RemoveElementForResource(nsIRDFResource* aResource, nsIContent*
if (! aElement)
return NS_ERROR_NULL_POINTER;
#ifdef DEBUG
const char* uri;
aResource->GetValue(&uri);
printf("remove [%p] <-- %s\n", aElement, uri);
#endif
mResources.Remove(aResource, aElement);
return NS_OK;
}
@ -2282,6 +2298,11 @@ XULDocumentImpl::GetElementById(const nsString& aId, nsIDOMElement** aReturn)
}
if (elements->Count() > 0) {
if (elements->Count() > 1) {
// This is a scary case that our API doesn't deal with well.
NS_WARNING("more than one element found with specified ID; returning first");
}
nsISupports* element = elements->ElementAt(0);
rv = element->QueryInterface(nsIDOMElement::GetIID(), (void**) aReturn);
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM element");
@ -2290,6 +2311,14 @@ XULDocumentImpl::GetElementById(const nsString& aId, nsIDOMElement** aReturn)
}
// Didn't find it in our hash table. Walk the tree looking for the node
// I'd like to make this an NS_ERROR(), but am sure someone would
// just comment it out :-/. This should've all been set up when
// nsRDFElement::SetDocument() got called. (Of course, somebody
// could've inserted a non-RDF element into this tree, so, I guess
// we'll leave it as a warning for now...)
NS_WARNING("unable to find hashed element; crawling the tree to find it");
*aReturn = nsnull;
SearchForNodeByID(aId, mRootContent, aReturn);

Просмотреть файл

@ -705,11 +705,17 @@ RDFElementImpl::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDO
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnInsertBefore(this, aNewChild, aRefChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnInsertBefore(this, aNewChild, aRefChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -723,11 +729,17 @@ RDFElementImpl::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDO
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnReplaceChild(this, aNewChild, aOldChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnReplaceChild(this, aNewChild, aOldChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -741,11 +753,17 @@ RDFElementImpl::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnRemoveChild(this, aOldChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnRemoveChild(this, aOldChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aOldChild);
*aReturn = aOldChild;
return NS_OK;
@ -759,11 +777,17 @@ RDFElementImpl::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnAppendChild(this, aNewChild);
NS_RELEASE(obs);
// It's possible that mDocument will be null for an element that's
// not in the content model (e.g., somebody is working on a
// "scratch" element that has been removed from the content tree).
if (mDocument) {
nsIDOMNodeObserver* obs;
if (NS_SUCCEEDED(mDocument->QueryInterface(nsIDOMNodeObserver::GetIID(), (void**) &obs))) {
obs->OnAppendChild(this, aNewChild);
NS_RELEASE(obs);
}
}
NS_ADDREF(aNewChild);
*aReturn = aNewChild;
return NS_OK;
@ -1588,29 +1612,6 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
nsresult rv = NS_OK;
// If they're changing the identity of this object, then we need to re-hash
// it into the document's resource-to-element map.
//
// XXX Changing the object's identity is a big deal: we actually need to
// toss the kids and recreate them. We don't do that here.
// XXX This code doesn't work unless ID is set, since GetResource
// actually tries to fetch the ID! We need to move this whole
// block down so that we can figure out whether or not we're making
// a NEW ID or overwriting an EXISTING ID - Dave.
/*if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kIdAtom) { // XXX regardless of namespace
nsCOMPtr<nsIRDFDocument> rdfDoc( do_QueryInterface(mDocument) );
NS_ASSERTION(rdfDoc != nsnull, "not an RDF document");
if (rdfDoc) {
nsCOMPtr<nsIRDFResource> resource;
if (NS_SUCCEEDED(rv = GetResource(getter_AddRefs(resource)))) {
if (NS_FAILED(rv = rdfDoc->RemoveElementForResource(resource, this))) {
NS_ERROR("unable to remove element from map");
return rv;
}
}
}
}*/
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
@ -1656,22 +1657,6 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
mAttributes->AppendElement(attr);
}
// XXX Changing the object's identity is a big deal: we actually need to
// toss the kids and recreate them. We don't do that here.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kIdAtom) { // XXX regardless of namespace
nsCOMPtr<nsIRDFDocument> rdfDoc( do_QueryInterface(mDocument) );
NS_ASSERTION(rdfDoc != nsnull, "not an RDF document");
if (rdfDoc) {
nsCOMPtr<nsIRDFResource> resource;
if (NS_SUCCEEDED(rv = GetResource(getter_AddRefs(resource)))) {
if (NS_FAILED(rv = rdfDoc->AddElementForResource(resource, this))) {
NS_ERROR("unable to remove element from map");
return rv;
}
}
}
}
// Check for event handlers
nsString attributeName;
aName->ToString(attributeName);
@ -2291,6 +2276,7 @@ RDFElementImpl::GetResource(nsIRDFResource** aResource)
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-relative ID attribute into a fully-qualified (that is, with
// the current document's URL) URI.
NS_ASSERTION(mDocument != nsnull, "element has no document");
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
@ -2321,7 +2307,10 @@ RDFElementImpl::EnsureContentsGenerated(void) const
nsresult rv;
// NS_PRECONDITION(mDocument != nsnull, "not initialized");
// Ensure that the element is actually _in_ the document tree;
// otherwise, somebody is trying to generate children for a node
// that's not currently in the content model.
NS_PRECONDITION(mDocument != nsnull, "element not in tree");
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;

Просмотреть файл

@ -587,7 +587,7 @@ XULSortServiceImpl::RemoveAllChildren(nsIContent *container)
for (childIndex=numChildren-1; childIndex >= 0; childIndex--)
{
if (NS_FAILED(rv = container->ChildAt(childIndex, *getter_AddRefs(child)))) break;
container->RemoveChildAt(childIndex, PR_TRUE);
container->RemoveChildAt(childIndex, PR_FALSE);
}
return(rv);
}
@ -832,7 +832,7 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, so
numChildren = 0;
for (loop=0; loop<numElements; loop++)
{
container->InsertChildAt((nsIContent *)flatArray[loop], numChildren++, PR_TRUE);
container->InsertChildAt((nsIContent *)flatArray[loop], numChildren++, PR_FALSE);
}
// recurse on grandchildren
@ -1039,18 +1039,22 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
else if (sortDirection.EqualsIgnoreCase("descending")) sortInfo.descendingSort = PR_TRUE;
}
// get index of sort column, find tree body, remove tree body from tree, sort, then re-add tree body
// get index of sort column, find tree body, and sort. The sort
// _won't_ send any notifications, so we won't trigger any
// reflows...
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, sortDirection, &colIndex))) return(rv);
sortInfo.colIndex = colIndex;
if (NS_FAILED(rv = FindTreeBodyElement(treeNode, &treeBody))) return(rv);
if (NS_FAILED(rv = treeBody->GetParent(treeParent))) return(rv);
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
if (NS_SUCCEEDED(rv = SortTreeChildren(treeBody, colIndex, &sortInfo, 0)))
{
}
if (NS_SUCCEEDED(rv = treeBody->UnsetAttribute(kNameSpaceID_None,
// Now remove the treebody and re-insert it to force the frames to be rebuilt.
if (NS_FAILED(rv = treeBody->GetParent(treeParent))) return(rv);
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
if (NS_SUCCEEDED(rv = treeBody->UnsetAttribute(kNameSpaceID_None,
kTreeContentsGeneratedAtom,PR_FALSE)))
{
}

Просмотреть файл

@ -1489,9 +1489,9 @@ RDFGenericBuilderImpl::GetDOMNodeResource(nsIDOMNode* aNode, nsIRDFResource** aR
nsresult
RDFGenericBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
nsIAtom* aTag,
nsIRDFResource* aResource,
nsIContent** aResult)
nsIAtom* aTag,
nsIRDFResource* aResource,
nsIContent** aResult)
{
nsresult rv;
@ -1515,8 +1515,8 @@ RDFGenericBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
nsresult
RDFGenericBuilderImpl::GetResource(PRInt32 aNameSpaceID,
nsIAtom* aNameAtom,
nsIRDFResource** aResource)
nsIAtom* aNameAtom,
nsIRDFResource** aResource)
{
NS_PRECONDITION(aNameAtom != nsnull, "null ptr");
if (! aNameAtom)