nsCOMPtr<nsIFormControl> htmlFormControl = do_QueryInterface(element); if (htmlFormControl) {  nsCOMPtr<nsIDOMHTMLFormElement> htmlFormElement; mDocument->GetForm(getter_AddRefs(htmlFormElement)); if (!htmlFormElement) {  nsAutoString tag("form"); nsCOMPtr<nsIHTMLContent> newElement; rv = mHTMLElementFactory->CreateInstanceByTag(tag, getter_AddRefs(newElement)); NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create HTML element"); if (NS_FAILED(rv)) return rv;  htmlFormElement = do_QueryInterface(newElement); if (!htmlFormElement) { NS_ERROR("Uh-oh! Couldn't make a form!"); return NS_ERROR_FAILURE; } mDocument->SetForm(htmlFormElement); }   htmlFormControl->SetForm(htmlFormElement); }
RDFXULBuilderImpl::CreateHTMLElement(nsINameSpace* aContainingNameSpace,                                     nsIRDFResource* aResource,                                     nsIAtom* aTag,                                     nsIContent** aResult){    nsresult rv;    if (!mHTMLElementFactory) {        rv = nsComponentManager::CreateInstance(kHTMLElementFactoryCID,                                                nsnull,                                                kIHTMLElementFactoryIID,                                                (void**) &mHTMLElementFactory);        if (NS_FAILED(rv)) {            return rv;        }    }    // XXX This is where we go out and create the HTML content. It's a    // bit of a hack: a bridge until we get to a more DOM-based    // solution.    nsCOMPtr<nsIHTMLContent> element;    nsAutoString tag(aTag->GetUnicode());    rv = mHTMLElementFactory->CreateInstanceByTag(tag,                                                  getter_AddRefs(element));    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create HTML element");    if (NS_FAILED(rv)) return rv;    // Force the document to be set _here_. Many of the    // AppendChildTo() implementations do not recursively ensure    // that the child's doc is the same as the parent's.    nsCOMPtr<nsIDocument> doc;    if (NS_FAILED(rv = mDocument->QueryInterface(kIDocumentIID, getter_AddRefs(doc)))) {        NS_ERROR("uh, this isn't a document!");        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?    nsXPIDLCString uri;    if (NS_FAILED(rv = aResource->GetValue( getter_Copies(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);    if (docURL) {        const char* url;        docURL->GetSpec(&url);        rdf_PossiblyMakeRelative(url, fullURI);        NS_RELEASE(docURL);    }           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    // the map.  XUL elements do this in the SetAttribute call, but we don't have    // access to that for HTML elements.  Should they even be in the map?    // For now the answer is NO.    // Now iterate through all the properties and add them as    // attributes on the element.  First, create a cursor that'll    // iterate through all the properties that lead out of this    // resource.    nsCOMPtr<nsISimpleEnumerator> properties;    rv = mDB->ArcLabelsOut(aResource, getter_AddRefs(properties));    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create arcs-out cursor");    if (NS_FAILED(rv)) return rv;    // Advance that cursor 'til it runs outta steam    while (1) {        PRBool hasMore;        rv = properties->HasMoreElements(&hasMore);        if (NS_FAILED(rv)) return rv;        if (! hasMore)            break;        nsCOMPtr<nsISupports> isupports;        rv = properties->GetNext(getter_AddRefs(isupports));        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get property from cursor");        if (NS_FAILED(rv)) return rv;        nsCOMPtr<nsIRDFResource> property = do_QueryInterface(isupports);        // These are special beacuse they're used to specify the tree        // structure of the XUL: ignore them b/c they're not attributes        if ((property.get() == kRDF_instanceOf) ||            (property.get() == kRDF_nextVal) ||            (property.get() == kRDF_type))            continue;        PRBool isOrdinal;        rv = gRDFContainerUtils->IsOrdinalProperty(property, &isOrdinal);        if (NS_FAILED(rv)) return rv;        if (isOrdinal)            continue;        // For each property, get its value: this will be the value of        // the new attribute.        nsCOMPtr<nsIRDFNode> value;        if (NS_FAILED(rv = mDB->GetTarget(aResource, property, PR_TRUE, getter_AddRefs(value)))) {            NS_ERROR("unable to get value for property");            return rv;        }        NS_ASSERTION(rv != NS_RDF_NO_VALUE, "null value in cursor");        if (rv == NS_RDF_NO_VALUE)            continue;        // Add the attribute to the newly constructed element        if (NS_FAILED(rv = AddAttribute(element, property, value))) {            NS_ERROR("unable to add attribute to element");            return rv;        }    }    // Create the children NOW, because we can't do it lazily.    if (NS_FAILED(rv = CreateHTMLContents(aContainingNameSpace, element, aResource))) {        NS_ERROR("error creating child contents");        return rv;    }    if (NS_FAILED(rv = element->QueryInterface(kIContentIID, (void**) aResult))) {        NS_ERROR("unable to get nsIContent interface");        return rv;    }    // The observes relationship has to be hooked up here, since the children    // were already built.  We'll miss out on it if we don't plug in here.    // Now that the contents have been created, perform broadcaster    // hookups if any of the children are observes nodes.    // XXX: Initial sync-up doesn't work, since no document observer exists    // yet.    PRInt32 childCount;    element->ChildCount(childCount);    for (PRInt32 j = 0; j < childCount; j++)    {        nsIContent* childContent = nsnull;        element->ChildAt(j, childContent);              if (!childContent)          break;        nsIAtom* tag = nsnull;        childContent->GetTag(tag);        if (!tag)          break;        nsString tagName;        tag->ToString(tagName);        if (tagName == "observes")        {            // Find the node that we're supposed to be            // observing and perform the hookup.            nsString elementValue;            nsString attributeValue;            nsCOMPtr<nsIDOMElement> domContent;            domContent = do_QueryInterface(childContent);            domContent->GetAttribute("element",                                     elementValue);                        domContent->GetAttribute("attribute",                                     attributeValue);            nsIDOMElement* domElement = nsnull;            nsCOMPtr<nsIDOMXULDocument> xulDoc;            xulDoc = do_QueryInterface(doc);                        if (xulDoc)              xulDoc->GetElementById(elementValue, &domElement);                        if (!domElement)              break;            // We have a DOM element to bind to.  Add a broadcast            // listener to that element, but only if it's a XUL element.            // XXX: Handle context nodes.            nsCOMPtr<nsIDOMElement> listener( do_QueryInterface(element) );            nsCOMPtr<nsIDOMXULElement> broadcaster( do_QueryInterface(domElement) );            if (listener)            {                broadcaster->AddBroadcastListener(attributeValue,                                                  listener);            }            NS_RELEASE(domElement);        }        NS_RELEASE(childContent);        NS_RELEASE(tag);    }    return NS_OK;}