Content model changes to get the tree widget alive.

This commit is contained in:
waterson%netscape.com 1998-12-09 03:25:33 +00:00
Родитель 0dc62760dc
Коммит 853da1faac
6 изменённых файлов: 219 добавлений и 95 удалений

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

@ -57,7 +57,7 @@ public:
* "content children," that is, a set of nsIRDFContent elements that
* should appear as the node's children in the content model.
*/
NS_IMETHOD CreateChildren(nsIRDFContent* element, nsISupportsArray* children) = 0;
NS_IMETHOD CreateChildren(nsIRDFContent* element) = 0;
// XXX these should probably be strings so you can mess with them
// via the DOM.

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

@ -1157,7 +1157,7 @@ nsRDFDocument::GetDataBase(nsIRDFDataBase*& result)
NS_IMETHODIMP
nsRDFDocument::CreateChildren(nsIRDFContent* element, nsISupportsArray* children)
nsRDFDocument::CreateChildren(nsIRDFContent* element)
{
nsresult rv;
@ -1205,24 +1205,16 @@ nsRDFDocument::CreateChildren(nsIRDFContent* element, nsISupportsArray* children
PRBool moreValues;
while (NS_SUCCEEDED(rv = values->HasMoreElements(moreValues)) && moreValues) {
nsIRDFNode* value = nsnull;
if (NS_FAILED(rv = values->GetNext(value, tv /* ignored */)))
break;
// XXX At this point, we need to decide exactly what kind
// of kid to create in the content model. For example, for
// leaf nodes, we probably want to create some kind of
// text element.
nsIRDFContent* child;
if (NS_FAILED(rv = CreateChild(property, value, child))) {
if (NS_SUCCEEDED(rv = values->GetNext(value, tv /* ignored */))) {
// At this point, the specific nsRDFDocument
// implementations will create an appropriate child
// element (or elements).
rv = AddChild(element, property, value);
NS_RELEASE(value);
break;
}
// And finally, add the child into the content model
children->AppendElement(child);
NS_RELEASE(child);
NS_RELEASE(value);
if (NS_FAILED(rv))
break;
}
NS_RELEASE(values);

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

@ -194,7 +194,7 @@ public:
NS_IMETHOD Init(void);
NS_IMETHOD SetRootResource(nsIRDFNode* resource);
NS_IMETHOD GetDataBase(nsIRDFDataBase*& result);
NS_IMETHOD CreateChildren(nsIRDFContent* element, nsISupportsArray* children);
NS_IMETHOD CreateChildren(nsIRDFContent* element);
NS_IMETHOD AddTreeProperty(nsIRDFNode* resource);
NS_IMETHOD RemoveTreeProperty(nsIRDFNode* resource);
@ -214,9 +214,9 @@ protected:
nsIRDFContent*& result,
PRBool childrenMustBeGenerated);
virtual nsresult CreateChild(nsIRDFNode* property,
nsIRDFNode* value,
nsIRDFContent*& result) = 0;
virtual nsresult AddChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value) = 0;
nsIArena* mArena;
nsVoidArray mObservers;

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

@ -1045,6 +1045,9 @@ nsRDFElement::GetAttributeCount(PRInt32& aResult) const
nsresult rv = NS_OK;
aResult = 0;
if (mAttributes)
aResult += mAttributes->Count();
#if defined(CREATE_PROPERTIES_AS_ATTRIBUTES)
PR_ASSERT(0); // XXX need to write this...
#endif // defined(CREATE_PROPERTIES_AS_ATTRIBUTES)
@ -1062,9 +1065,6 @@ rdf_Indent(FILE* out, PRInt32 aIndent)
NS_IMETHODIMP
nsRDFElement::List(FILE* out, PRInt32 aIndent) const
{
if (! mResource)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
{
@ -1219,9 +1219,12 @@ nsRDFElement::Init(nsIRDFDocument* doc,
PRBool childrenMustBeGenerated)
{
NS_PRECONDITION(doc, "null ptr");
NS_PRECONDITION(resource, "null ptr");
if (!doc || !resource)
// XXX Not using this because of a hack in nsRDFTreeDocument: need
// to expose generic XML elements!
//NS_PRECONDITION(resource, "null ptr");
if (!doc /* || !resource // XXX ibid */)
return NS_ERROR_NULL_POINTER;
mTag = aTag;
@ -1229,15 +1232,13 @@ nsRDFElement::Init(nsIRDFDocument* doc,
mDocument = doc; // not refcounted
mResource = resource;
NS_ADDREF(mResource);
NS_IF_ADDREF(mResource);
mChildrenMustBeGenerated = childrenMustBeGenerated;
if (! childrenMustBeGenerated) {
nsresult rv;
if (NS_FAILED(rv = NS_NewISupportsArray(&mChildren)))
return rv;
}
nsresult rv;
if (NS_FAILED(rv = NS_NewISupportsArray(&mChildren)))
return rv;
return NS_OK;
}
@ -1383,11 +1384,17 @@ nsRDFElement::GenerateChildren(void) const
unconstThis->mChildren->Clear();
}
if (NS_FAILED(rv = mDocument->CreateChildren(unconstThis,
unconstThis->mChildren)))
return rv;
// Clear this value *first*, so we can re-enter the nsIContent
// getters if needed.
unconstThis->mChildrenMustBeGenerated = PR_FALSE;
if (NS_FAILED(rv = mDocument->CreateChildren(unconstThis))) {
// Well, maybe it was a transient error. This'll let use try
// again some time in the future.
unconstThis->mChildrenMustBeGenerated = PR_TRUE;
return rv;
}
return NS_OK;
}

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

@ -43,9 +43,9 @@ public:
virtual ~RDFHTMLDocumentImpl();
protected:
virtual nsresult CreateChild(nsIRDFNode* property,
nsIRDFNode* value,
nsIRDFContent*& result);
virtual nsresult AddChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value);
};
////////////////////////////////////////////////////////////////////////
@ -59,9 +59,9 @@ RDFHTMLDocumentImpl::~RDFHTMLDocumentImpl(void)
}
nsresult
RDFHTMLDocumentImpl::CreateChild(nsIRDFNode* property,
nsIRDFNode* value,
nsIRDFContent*& result)
RDFHTMLDocumentImpl::AddChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value)
{
nsresult rv;
nsIRDFContent* child = nsnull;
@ -96,9 +96,6 @@ RDFHTMLDocumentImpl::CreateChild(nsIRDFNode* property,
if (NS_FAILED(rv = child->SetAttribute("ID", s, PR_FALSE)))
goto done;
result = child;
NS_ADDREF(result);
}
else {
// Otherwise, it's not a tree property. So we'll just create a
@ -115,11 +112,10 @@ RDFHTMLDocumentImpl::CreateChild(nsIRDFNode* property,
if (NS_FAILED(rv = AttachTextNode(child, value)))
goto done;
result = child;
NS_ADDREF(result);
}
rv = parent->AppendChildTo(child, PR_TRUE);
done:
NS_IF_RELEASE(child);
return rv;

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

@ -29,15 +29,36 @@
////////////////////////////////////////////////////////////////////////
static const char* kChildrenTag = "CHILDREN";
static const char* kFolderTag = "FOLDER";
static const char* kItemTag = "ITEM";
////////////////////////////////////////////////////////////////////////
class RDFTreeDocumentImpl : public nsRDFDocument {
public:
RDFTreeDocumentImpl();
virtual ~RDFTreeDocumentImpl();
protected:
virtual nsresult CreateChild(nsIRDFNode* property,
nsIRDFNode* value,
nsIRDFContent*& result);
virtual nsresult
AddChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value);
nsresult
EnsureChildrenElement(nsIContent* parent,
nsIContent*& result);
nsresult
AddTreeChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value);
nsresult
AddPropertyChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value);
};
////////////////////////////////////////////////////////////////////////
@ -50,70 +71,178 @@ RDFTreeDocumentImpl::~RDFTreeDocumentImpl(void)
{
}
nsresult
RDFTreeDocumentImpl::CreateChild(nsIRDFNode* property,
nsIRDFNode* value,
nsIRDFContent*& result)
RDFTreeDocumentImpl::EnsureChildrenElement(nsIContent* parent,
nsIContent*& result)
{
static const char* kTRTag = "TR";
static const char* kTDTag = "TD";
nsresult rv;
result = nsnull; // reasonable default
nsIAtom* childrenTag = NS_NewAtom(kChildrenTag);
if (! childrenTag)
return NS_ERROR_OUT_OF_MEMORY;
PRInt32 count;
if (NS_FAILED(rv = parent->ChildCount(count))) {
NS_RELEASE(childrenTag);
return rv;
}
for (PRInt32 i = 0; i < count; ++i) {
nsIContent* kid;
if (NS_FAILED(rv = parent->ChildAt(i, kid)))
break;
nsIAtom* tag;
if (NS_FAILED(rv = parent->GetTag(tag))) {
NS_RELEASE(kid);
break;
}
if (tag == childrenTag) {
NS_RELEASE(tag);
NS_RELEASE(childrenTag);
result = kid; // no need to addref, got it from ChildAt().
return NS_OK;
}
NS_RELEASE(tag);
NS_RELEASE(kid);
}
NS_RELEASE(childrenTag);
if (NS_FAILED(rv))
return rv;
// if we get here, we need to construct a new <children> element.
// XXX this should be a generic XML element, not an nsRDFElement
nsIRDFContent* children = nsnull;
if (NS_FAILED(rv = NS_NewRDFElement(&children)))
goto done;
if (NS_FAILED(rv = children->Init(this, kChildrenTag, nsnull /* XXX */, PR_FALSE)))
goto done;
if (NS_FAILED(rv = parent->AppendChildTo(children, PR_FALSE)))
goto done;
result = children;
NS_ADDREF(result);
done:
NS_IF_RELEASE(children);
return rv;
}
nsresult
RDFTreeDocumentImpl::AddTreeChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value)
{
// If it's a tree property, then we need to add the new child
// element to a special "children" element in the parent. The
// child element's value will be the value of the
// property. We'll also attach an "ID=" attribute to the new
// child; e.g.,
//
// <parent>
// ...
// <children>
// <item id="value">
// <!-- recursively generated -->
// </item>
// </children>
// ...
// </parent>
nsresult rv;
nsIRDFContent* child = nsnull;
nsIContent* children = nsnull;
nsAutoString s;
if (IsTreeProperty(property) || rdf_IsContainer(mResourceMgr, mDB, value)) {
// If it's a tree property, then create a child element whose
// value is the value of the property. We'll also attach an "ID="
// attribute to the new child; e.g.,
//
// <parent>
// <tr id="value">
// <!-- recursively generated -->
// </tr>
// ...
// </parent>
// Ensure that the <children> element exists on the parent.
if (NS_FAILED(rv = EnsureChildrenElement(parent, children)))
goto done;
nsAutoString s;
// Create a new child that represents the "value"
// resource. PR_TRUE indicates that we want the child to
// dynamically generate its own kids.
if (NS_FAILED(rv = NewChild(kFolderTag, value, child, PR_TRUE)))
goto done;
// PR_TRUE indicates that we want the child to dynamically
// generate its own kids.
if (NS_FAILED(rv = NewChild(kTRTag, value, child, PR_TRUE)))
goto done;
if (NS_FAILED(rv = value->GetStringValue(s)))
goto done;
if (NS_FAILED(rv = value->GetStringValue(s)))
goto done;
if (NS_FAILED(rv = child->SetAttribute("ID", s, PR_FALSE)))
goto done;
if (NS_FAILED(rv = child->SetAttribute("ID", s, PR_FALSE)))
goto done;
#define ALL_NODES_OPEN_HACK
#ifdef ALL_NODES_OPEN_HACK
if (NS_FAILED(rv = child->SetAttribute("OPEN", "TRUE", PR_FALSE)))
goto done;
#endif
result = child;
NS_ADDREF(result);
}
else {
// Otherwise, it's not a tree property. So we'll just create a
// new element for the property, and a simple text node for
// its value; e.g.,
//
// <parent>
// <td>value</td>
// ...
// </parent>
// Finally, add the thing to the <children> element.
children->AppendChildTo(child, PR_TRUE);
if (NS_FAILED(rv = NewChild(kTDTag, property, child, PR_FALSE)))
goto done;
done:
NS_IF_RELEASE(child);
NS_IF_RELEASE(children);
return rv;
}
if (NS_FAILED(rv = AttachTextNode(child, value)))
goto done;
result = child;
NS_ADDREF(result);
}
nsresult
RDFTreeDocumentImpl::AddPropertyChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value)
{
// Otherwise, it's not a tree property. So we'll just create a
// new element for the property, and a simple text node for
// its value; e.g.,
//
// <parent>
// <td>value</td>
// ...
// </parent>
nsresult rv;
nsIRDFContent* child = nsnull;
nsAutoString s;
if (NS_FAILED(rv = property->GetStringValue(s)))
goto done;
if (NS_FAILED(rv = NewChild(s, property, child, PR_FALSE)))
goto done;
if (NS_FAILED(rv = AttachTextNode(child, value)))
goto done;
rv = parent->AppendChildTo(child, PR_TRUE);
done:
NS_IF_RELEASE(child);
return rv;
}
nsresult
RDFTreeDocumentImpl::AddChild(nsIRDFContent* parent,
nsIRDFNode* property,
nsIRDFNode* value)
{
if (IsTreeProperty(property) || rdf_IsContainer(mResourceMgr, mDB, value)) {
return AddTreeChild(parent, property, value);
}
else {
return AddPropertyChild(parent, property, value);
}
}
////////////////////////////////////////////////////////////////////////