Bug 71530. Implement RDF outliner. Break nsXULTemplateBuilder into two subclasses: nsXULContentBuilder and nsXULOutlinerBuilder. Explode helper classes into separate files. Fix ownership and communication between nsXULElement, nsXULDocument, and nsXULTemplateBuilder. r=hyatt, sr=ben

This commit is contained in:
waterson%netscape.com 2001-03-23 10:56:18 +00:00
parent 76f46987c3
commit d669429d9d
26 changed files with 1784 additions and 7686 deletions

View File

@ -237,6 +237,10 @@
#define NS_XULTEMPLATEBUILDER_CID \
{ 0x3d262d00, 0x8b5a, 0x11d2, { 0x8e, 0xb0, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
// {1abdcc96-1dd2-11b2-b520-f8f59cdd67bc}
#define NS_XULOUTLINERBUILDER_CID \
{ 0x1abdcc96, 0x1dd2, 0x11b2, { 0xb5, 0x20, 0xf8, 0xf5, 0x9c, 0xdd, 0x67, 0xbc } }
// {CE058B21-BA9C-11d2-BF86-00105A1B0627}
#define NS_XULCONTENTSINK_CID \
{ 0xce058b21, 0xba9c, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }

View File

@ -237,6 +237,10 @@
#define NS_XULTEMPLATEBUILDER_CID \
{ 0x3d262d00, 0x8b5a, 0x11d2, { 0x8e, 0xb0, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
// {1abdcc96-1dd2-11b2-b520-f8f59cdd67bc}
#define NS_XULOUTLINERBUILDER_CID \
{ 0x1abdcc96, 0x1dd2, 0x11b2, { 0xb5, 0x20, 0xf8, 0xf5, 0x9c, 0xdd, 0x67, 0xbc } }
// {CE058B21-BA9C-11d2-BF86-00105A1B0627}
#define NS_XULCONTENTSINK_CID \
{ 0xce058b21, 0xba9c, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }

View File

@ -171,6 +171,7 @@ extern nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
static NS_DEFINE_CID(kXULSortServiceCID, NS_XULSORTSERVICE_CID);
static NS_DEFINE_CID(kXULTemplateBuilderCID, NS_XULTEMPLATEBUILDER_CID);
static NS_DEFINE_CID(kXULOutlinerBuilderCID, NS_XULOUTLINERBUILDER_CID);
static NS_DEFINE_CID(kXULContentSinkCID, NS_XULCONTENTSINK_CID);
static NS_DEFINE_CID(kXULDocumentCID, NS_XULDOCUMENT_CID);
static NS_DEFINE_CID(kXULPopupListenerCID, NS_XULPOPUPLISTENER_CID);
@ -530,9 +531,16 @@ nsContentFactory::CreateInstance(nsISupports *aOuter,
}
}
else if (mClassID.Equals(kXULTemplateBuilderCID)) {
res = NS_NewXULTemplateBuilder((nsIRDFContentModelBuilder**) &inst);
res = NS_NewXULContentBuilder(nsnull, aIID, (void**) &inst);
if (NS_FAILED(res)) {
LOG_NEW_FAILURE("NS_NewXULTemplateBuilder", res);
LOG_NEW_FAILURE("NS_NewXULContentBuilder", res);
return res;
}
}
else if (mClassID.Equals(kXULOutlinerBuilderCID)) {
res = NS_NewXULOutlinerBuilder(nsnull, aIID, (void**) &inst);
if (NS_FAILED(res)) {
LOG_NEW_FAILURE("NS_NewXULOutlinerBuilder", res);
return res;
}
}

View File

@ -358,6 +358,8 @@ static Components gComponents[] = {
"@mozilla.org/xul/xul-sort-service;1", },
{ "XUL Template Builder", NS_XULTEMPLATEBUILDER_CID,
"@mozilla.org/xul/xul-template-builder;1", },
{ "XUL Outliner Builder", NS_XULOUTLINERBUILDER_CID,
"@mozilla.org/xul/xul-outliner-builder;1", },
{ "XUL Content Sink", NS_XULCONTENTSINK_CID,
"@mozilla.org/xul/xul-content-sink;1", },
{ "XUL Document", NS_XULDOCUMENT_CID,

Binary file not shown.

View File

@ -79,6 +79,8 @@ XUL_ATOM(focus, "focus")
XUL_ATOM(outliner, "outliner")
XUL_ATOM(outlinerbody, "outlinerbody")
XUL_ATOM(outlinercol, "outlinercol")
XUL_ATOM(outlinerrow, "outlinerrow")
XUL_ATOM(outlinercell, "outlinercell")
XUL_ATOM(cycler, "cycler")
XUL_ATOM(primary, "primary")
@ -249,9 +251,23 @@ XUL_ATOM(child, "child")
XUL_ATOM(object, "object")
XUL_ATOM(tag, "tag")
XUL_ATOM(content, "content")
XUL_ATOM(coalesceduplicatearcs, "coalesceduplicatearcs")
XUL_ATOM(allownegativeassertions, "allownegativeassertions")
XUL_ATOM(datasources, "datasources")
XUL_ATOM(commandupdater, "commandupdater")
XUL_ATOM(keyset, "keyset")
XUL_ATOM(element, "element")
XUL_ATOM(attribute, "attribute")
XUL_ATOM(overlay, "overlay")
XUL_ATOM(insertbefore, "insertbefore")
XUL_ATOM(insertafter, "insertafter")
XUL_ATOM(position, "position")
XUL_ATOM(removeelement, "removeelement")
XUL_ATOM(blankrow, "blankrow")
XUL_ATOM(titlebar, "titlebar")
XUL_ATOM(resizer, "resizer")
XUL_ATOM(dir, "dir")
XUL_ATOM(properties, "properties")
XUL_ATOM(sort, "sort")
XUL_ATOM(sortDirection, "sortDirection")
XUL_ATOM(sortActive, "sortActive")

View File

@ -104,12 +104,6 @@ public:
* should call this method, think again. You shouldn't.
*/
NS_IMETHOD ForceElementToOwnResource(PRBool aForce) = 0;
/**
* Initialize the root element in a XUL template
*/
NS_IMETHOD InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder) = 0;
};
#endif // nsIXULContent_h__

View File

@ -88,6 +88,7 @@
#include "nsIPresShell.h"
#include "nsIPrincipal.h"
#include "nsIRDFCompositeDataSource.h"
#include "nsIRDFContentModelBuilder.h"
#include "nsIRDFNode.h"
#include "nsIRDFService.h"
#include "nsIScriptContext.h"
@ -1891,25 +1892,6 @@ nsXULElement::ForceElementToOwnResource(PRBool aForce)
}
NS_IMETHODIMP
nsXULElement::InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder)
{
// Sanity check
NS_PRECONDITION(Database() == nsnull, "already initialized");
if (Database())
return NS_ERROR_ALREADY_INITIALIZED;
nsresult rv;
rv = EnsureSlots();
if (NS_FAILED(rv)) return rv;
mSlots->mDatabase = aDatabase;
mSlots->mBuilder = aBuilder;
return NS_OK;
}
//----------------------------------------------------------------------
// nsIDOMEventReceiver interface
@ -3882,8 +3864,14 @@ nsXULElement::GetResource(nsIRDFResource** aResource)
NS_IMETHODIMP
nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
{
*aDatabase = Database();
NS_IF_ADDREF(*aDatabase);
nsCOMPtr<nsIXULTemplateBuilder> builder;
GetBuilder(getter_AddRefs(builder));
if (builder)
builder->GetDatabase(aDatabase);
else
*aDatabase = nsnull;
return NS_OK;
}
@ -3891,8 +3879,14 @@ nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
NS_IMETHODIMP
nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
{
*aBuilder = Builder();
NS_IF_ADDREF(*aBuilder);
*aBuilder = nsnull;
if (mDocument) {
nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mDocument);
if (xuldoc)
xuldoc->GetTemplateBuilderFor(NS_STATIC_CAST(nsIStyledContent*, this), aBuilder);
}
return NS_OK;
}
@ -3918,14 +3912,35 @@ nsXULElement::EnsureContentsGenerated(void) const
// getters if needed.
unconstThis->mLazyState &= ~nsIXULContent::eChildrenMustBeRebuilt;
nsCOMPtr<nsIXULDocument> rdfDoc = do_QueryInterface(mDocument);
if (! mDocument)
return NS_OK;
// Walk up our ancestor chain, looking for an element with a
// XUL content model builder attached to it.
nsCOMPtr<nsIContent> element
= do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, unconstThis));
nsresult rv = rdfDoc->CreateContents(NS_STATIC_CAST(nsIStyledContent*, unconstThis));
NS_ASSERTION(NS_SUCCEEDED(rv), "problem creating kids");
if (NS_FAILED(rv)) return rv;
do {
nsCOMPtr<nsIDOMXULElement> xulele = do_QueryInterface(element);
if (xulele) {
nsCOMPtr<nsIXULTemplateBuilder> builder;
xulele->GetBuilder(getter_AddRefs(builder));
if (builder) {
nsCOMPtr<nsIRDFContentModelBuilder> contentBuilder =
do_QueryInterface(builder);
if (contentBuilder)
return contentBuilder->CreateContents(NS_STATIC_CAST(nsIStyledContent*, unconstThis));
}
}
nsCOMPtr<nsIContent> parent;
element->GetParent(*getter_AddRefs(parent));
element = parent;
} while (element);
NS_ERROR("lazy state set with no XUL content builder in ancestor chain");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
@ -4645,7 +4660,6 @@ nsXULElement::Slots::Slots(nsXULElement* aElement)
: mElement(aElement),
mBroadcastListeners(nsnull),
mBroadcaster(nsnull),
mBuilder(nsnull),
mAttributes(nsnull),
mInnerXULElement(nsnull)
{

View File

@ -57,6 +57,7 @@
#include "nsIXBLBinding.h"
#include "nsIURI.h"
#include "nsIXULContent.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIBoxObject.h"
#include "nsXULAttributes.h"
#include "nsIChromeEventHandler.h"
@ -70,7 +71,6 @@ class nsIXBLService;
class nsISupportsArray;
class nsIXULContentUtils;
class nsIXULPrototypeDocument;
class nsIXULTemplateBuilder;
class nsRDFDOMNodeList;
class nsString;
class nsXULAttributes;
@ -407,8 +407,6 @@ public:
NS_IMETHOD GetLazyState(PRInt32 aFlag, PRBool& aValue);
NS_IMETHOD AddScriptEventListener(nsIAtom* aName, const nsAReadableString& aValue);
NS_IMETHOD ForceElementToOwnResource(PRBool aForce);
NS_IMETHOD InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder);
// nsIDOMNode (from nsIDOMElement)
NS_DECL_IDOMNODE
@ -532,8 +530,6 @@ protected:
nsVoidArray* mBroadcastListeners; // [WEAK]
nsIDOMXULElement* mBroadcaster; // [WEAK]
nsCOMPtr<nsIControllers> mControllers; // [OWNER]
nsCOMPtr<nsIRDFCompositeDataSource> mDatabase; // [OWNER]
nsIXULTemplateBuilder* mBuilder; // [WEAK]
nsCOMPtr<nsIRDFResource> mOwnedResource; // [OWNER]
nsXULAttributes* mAttributes;
@ -556,8 +552,6 @@ protected:
nsVoidArray* BroadcastListeners() const { return mSlots ? mSlots->mBroadcastListeners : nsnull; }
nsIDOMXULElement* Broadcaster() const { return mSlots ? mSlots->mBroadcaster : nsnull; }
nsIControllers* Controllers() const { return mSlots ? mSlots->mControllers.get() : nsnull; }
nsIRDFCompositeDataSource* Database() const { return mSlots ? mSlots->mDatabase.get() : nsnull; }
nsIXULTemplateBuilder* Builder() const { return mSlots ? mSlots->mBuilder : nsnull; }
nsIRDFResource* OwnedResource() const { return mSlots ? mSlots->mOwnedResource.get() : nsnull; }
nsXULAttributes* Attributes() const { return mSlots ? mSlots->mAttributes : nsnull; }
nsXULAggregateElement* InnerXULElement() const { return mSlots ? mSlots->mInnerXULElement : nsnull; }

View File

@ -42,10 +42,10 @@ class nsForwardReference;
class nsIAtom;
class nsIDOMElement;
class nsIPrincipal;
class nsIRDFContentModelBuilder;
class nsIRDFResource;
class nsISupportsArray;
class nsIXULPrototypeDocument;
class nsIXULTemplateBuilder;
class nsIURI;
// {954F0811-81DC-11d2-B52A-000000000000}
@ -84,13 +84,6 @@ public:
*/
NS_IMETHOD GetElementsForID(const nsAReadableString& aID, nsISupportsArray* aElements) = 0;
NS_IMETHOD CreateContents(nsIContent* aElement) = 0;
/**
* Add a content model builder to the document.
*/
NS_IMETHOD AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) = 0;
/**
* Add a "forward declaration" of a XUL observer. Such declarations
* will be resolved when document loading completes.
@ -136,6 +129,19 @@ public:
* Notify the XUL document that a subtree has been removed
*/
NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aElement) = 0;
/**
* Attach a XUL template builder to the specified content node.
* @param aBuilder the tmeplate builder to attach, or null if
* the builder is to be removed.
*/
NS_IMETHOD SetTemplateBuilderFor(nsIContent* aContent, nsIXULTemplateBuilder* aBuilder) = 0;
/**
* Retrieve the XUL template builder that's attached to a content
* node.
*/
NS_IMETHOD GetTemplateBuilderFor(nsIContent* aContent, nsIXULTemplateBuilder** aResult) = 0;
};
// factory functions

View File

@ -165,6 +165,7 @@ static NS_DEFINE_CID(kXMLElementFactoryCID, NS_XML_ELEMENT_FACTORY_CID);
static NS_DEFINE_CID(kXULContentSinkCID, NS_XULCONTENTSINK_CID);
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
static NS_DEFINE_CID(kXULTemplateBuilderCID, NS_XULTEMPLATEBUILDER_CID);
static NS_DEFINE_CID(kXULOutlinerBuilderCID, NS_XULOUTLINERBUILDER_CID);
static NS_DEFINE_CID(kDOMImplementationCID, NS_DOM_IMPLEMENTATION_CID);
static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID);
@ -200,31 +201,6 @@ const nsForwardReference::Phase nsForwardReference::kPasses[] = {
PRInt32 nsXULDocument::gRefCnt = 0;
nsIAtom* nsXULDocument::kAttributeAtom;
nsIAtom* nsXULDocument::kCommandUpdaterAtom;
nsIAtom* nsXULDocument::kContextAtom;
nsIAtom* nsXULDocument::kDataSourcesAtom;
nsIAtom* nsXULDocument::kElementAtom;
nsIAtom* nsXULDocument::kIdAtom;
nsIAtom* nsXULDocument::kKeysetAtom;
nsIAtom* nsXULDocument::kObservesAtom;
nsIAtom* nsXULDocument::kOpenAtom;
nsIAtom* nsXULDocument::kOverlayAtom;
nsIAtom* nsXULDocument::kPersistAtom;
nsIAtom* nsXULDocument::kPositionAtom;
nsIAtom* nsXULDocument::kInsertAfterAtom;
nsIAtom* nsXULDocument::kInsertBeforeAtom;
nsIAtom* nsXULDocument::kRemoveElementAtom;
nsIAtom* nsXULDocument::kPopupAtom;
nsIAtom* nsXULDocument::kRefAtom;
nsIAtom* nsXULDocument::kRuleAtom;
nsIAtom* nsXULDocument::kStyleAtom;
nsIAtom* nsXULDocument::kTemplateAtom;
nsIAtom* nsXULDocument::kTooltipAtom;
nsIAtom* nsXULDocument::kCoalesceAtom;
nsIAtom* nsXULDocument::kAllowNegativesAtom;
nsIRDFService* nsXULDocument::gRDFService;
nsIRDFResource* nsXULDocument::kNC_persist;
nsIRDFResource* nsXULDocument::kNC_attribute;
@ -237,8 +213,6 @@ nsINameSpaceManager* nsXULDocument::gNameSpaceManager;
PRInt32 nsXULDocument::kNameSpaceID_XUL;
nsIXULPrototypeCache* nsXULDocument::gXULCache;
nsIScriptSecurityManager* nsXULDocument::gScriptSecurityManager;
nsIPrincipal* nsXULDocument::gSystemPrincipal;
PRLogModuleInfo* nsXULDocument::gXULLog;
@ -427,11 +401,12 @@ nsXULDocument::nsXULDocument(void)
mNextSrcLoadWaiter(nsnull),
mDisplaySelection(PR_FALSE),
mIsPopup(PR_FALSE),
mBoxObjectTable(nsnull),
mTemplateBuilderTable(nsnull),
mResolutionPhase(nsForwardReference::eStart),
mNextContentID(NS_CONTENT_ID_COUNTER_BASE),
mState(eState_Master),
mCurrentScriptProto(nsnull),
mBoxObjectTable(nsnull),
mNumCapturers(0)
{
NS_INIT_REFCNT();
@ -453,6 +428,13 @@ nsXULDocument::~nsXULDocument()
// decls never got resolved.
DestroyForwardReferences();
// Notify observer that we're about to go away
PRInt32 i;
for (i = mObservers.Count() - 1; i >= 0; --i) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i);
observer->DocumentWillBeDestroyed(this);
}
// mParentDocument is never refcounted
// Delete references to sub-documents
{
@ -483,45 +465,10 @@ nsXULDocument::~nsXULDocument()
mCSSLoader->DropDocumentReference();
}
delete mTemplateBuilderTable;
delete mBoxObjectTable;
#if 0
PRInt32 i;
for (i = 0; i < mObservers.Count(); i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i);
observer->DocumentWillBeDestroyed(this);
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
i--;
}
}
#endif
if (--gRefCnt == 0) {
NS_IF_RELEASE(kAttributeAtom);
NS_IF_RELEASE(kCommandUpdaterAtom);
NS_IF_RELEASE(kContextAtom);
NS_IF_RELEASE(kDataSourcesAtom);
NS_IF_RELEASE(kElementAtom);
NS_IF_RELEASE(kIdAtom);
NS_IF_RELEASE(kKeysetAtom);
NS_IF_RELEASE(kObservesAtom);
NS_IF_RELEASE(kOpenAtom);
NS_IF_RELEASE(kOverlayAtom);
NS_IF_RELEASE(kPersistAtom);
NS_IF_RELEASE(kPositionAtom);
NS_IF_RELEASE(kInsertAfterAtom);
NS_IF_RELEASE(kInsertBeforeAtom);
NS_IF_RELEASE(kRemoveElementAtom);
NS_IF_RELEASE(kPopupAtom);
NS_IF_RELEASE(kRefAtom);
NS_IF_RELEASE(kRuleAtom);
NS_IF_RELEASE(kStyleAtom);
NS_IF_RELEASE(kTemplateAtom);
NS_IF_RELEASE(kTooltipAtom);
NS_IF_RELEASE(kCoalesceAtom);
NS_IF_RELEASE(kAllowNegativesAtom);
if (gRDFService) {
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
gRDFService = nsnull;
@ -543,13 +490,6 @@ nsXULDocument::~nsXULDocument()
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache);
gXULCache = nsnull;
}
if (gScriptSecurityManager) {
nsServiceManager::ReleaseService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, gScriptSecurityManager);
gScriptSecurityManager = nsnull;
}
NS_IF_RELEASE(gSystemPrincipal);
}
}
@ -1411,31 +1351,6 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
if (mRootContent)
mRootContent->SetDocument(nsnull, PR_TRUE, PR_TRUE);
// set all builder references to document to nsnull -- out of band notification
// to break ownership cycle
if (mBuilders) {
PRUint32 cnt = 0;
nsresult rv = mBuilders->Count(&cnt);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
for (PRUint32 i = 0; i < cnt; ++i) {
nsIRDFContentModelBuilder* builder
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
NS_ASSERTION(builder != nsnull, "null ptr");
if (! builder) continue;
rv = builder->SetDocument(nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "error unlinking builder from document");
// XXX ignore error code?
rv = builder->SetDataBase(nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "error unlinking builder from database");
NS_RELEASE(builder);
}
}
// Propagate the out-of-band notification to each PresShell's
// anonymous content as well. This ensures that there aren't
// any accidental script references left in anonymous content
@ -1617,7 +1532,7 @@ nsXULDocument::AttributeChanged(nsIContent* aElement,
if (NS_FAILED(rv)) return rv;
// First see if we need to update our element map.
if ((aAttribute == kIdAtom) || (aAttribute == kRefAtom)) {
if ((aAttribute == nsXULAtoms::id) || (aAttribute == nsXULAtoms::ref)) {
rv = mElementMap.Enumerate(RemoveElementsFromMapByContent, aElement);
if (NS_FAILED(rv)) return rv;
@ -1628,22 +1543,6 @@ nsXULDocument::AttributeChanged(nsIContent* aElement,
if (NS_FAILED(rv)) return rv;
}
// Handle "open" and "close" cases. We do this handling before
// we've notified the observer, so that content is already created
// for the frame system to walk.
if ((nameSpaceID == kNameSpaceID_XUL) && (aAttribute == kOpenAtom)) {
nsAutoString open;
rv = aElement->GetAttribute(kNameSpaceID_None, kOpenAtom, open);
if (NS_FAILED(rv)) return rv;
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && (open == NS_LITERAL_STRING("true"))) {
OpenWidgetItem(aElement);
}
else {
CloseWidgetItem(aElement);
}
}
// Now notify external observers
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
@ -1653,20 +1552,12 @@ nsXULDocument::AttributeChanged(nsIContent* aElement,
}
}
// Check for a change to the 'ref' attribute on an atom, in which
// case we may need to nuke and rebuild the entire content model
// beneath the element.
if (aAttribute == kRefAtom) {
RebuildWidgetItem(aElement);
}
// Finally, see if there is anything we need to persist in the
// localstore.
//
// XXX Namespace handling broken :-(
nsAutoString persist;
rv = aElement->GetAttribute(kNameSpaceID_None, kPersistAtom, persist);
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::persist, persist);
if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
@ -2096,7 +1987,6 @@ nsXULDocument::RemoveElementForID(const nsAReadableString& aID, nsIContent* aEle
return NS_OK;
}
NS_IMETHODIMP
nsXULDocument::GetElementsForID(const nsAReadableString& aID, nsISupportsArray* aElements)
{
@ -2108,60 +1998,6 @@ nsXULDocument::GetElementsForID(const nsAReadableString& aID, nsISupportsArray*
return NS_OK;
}
NS_IMETHODIMP
nsXULDocument::CreateContents(nsIContent* aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
if (! mBuilders)
return NS_ERROR_NOT_INITIALIZED;
PRUint32 cnt = 0;
nsresult rv = mBuilders->Count(&cnt);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
for (PRUint32 i = 0; i < cnt; ++i) {
// XXX we should QueryInterface() here
nsIRDFContentModelBuilder* builder
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
NS_ASSERTION(builder != nsnull, "null ptr");
if (! builder)
continue;
rv = builder->CreateContents(aElement);
NS_ASSERTION(NS_SUCCEEDED(rv), "error creating content");
// XXX ignore error code?
NS_RELEASE(builder);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULDocument::AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder)
{
NS_PRECONDITION(aBuilder != nsnull, "null ptr");
if (! aBuilder)
return NS_ERROR_NULL_POINTER;
nsresult rv;
if (! mBuilders) {
rv = NS_NewISupportsArray(getter_AddRefs(mBuilders));
if (NS_FAILED(rv)) return rv;
}
rv = aBuilder->SetDocument(this);
if (NS_FAILED(rv)) return rv;
return mBuilders->AppendElement(aBuilder) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULDocument::AddForwardReference(nsForwardReference* aRef)
{
@ -3169,7 +3005,7 @@ nsXULDocument::AddElementToDocumentPre(nsIContent* aElement)
// "commandupdater='true'" attribute), then add the element to the
// document's command dispatcher
nsAutoString value;
rv = aElement->GetAttribute(kNameSpaceID_None, kCommandUpdaterAtom, value);
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::commandupdater, value);
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && value == NS_LITERAL_STRING("true")) {
rv = nsXULContentUtils::SetCommandUpdater(this, aElement);
if (NS_FAILED(rv)) return rv;
@ -3259,7 +3095,7 @@ nsXULDocument::RemoveSubtreeFromDocument(nsIContent* aElement)
// 3. If the element is a 'command updater', then remove the
// element from the document's command dispatcher.
nsAutoString value;
rv = aElement->GetAttribute(kNameSpaceID_None, kCommandUpdaterAtom, value);
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::commandupdater, value);
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && value == NS_LITERAL_STRING("true")) {
nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
NS_ASSERTION(domelement != nsnull, "not a DOM element");
@ -3273,9 +3109,43 @@ nsXULDocument::RemoveSubtreeFromDocument(nsIContent* aElement)
return NS_OK;
}
NS_IMETHODIMP
nsXULDocument::SetTemplateBuilderFor(nsIContent* aContent, nsIXULTemplateBuilder* aBuilder)
{
if (! mTemplateBuilderTable) {
mTemplateBuilderTable = new nsSupportsHashtable();
if (! mTemplateBuilderTable)
return NS_ERROR_OUT_OF_MEMORY;
}
nsISupportsKey key(aContent);
if (aContent) {
mTemplateBuilderTable->Put(&key, aBuilder);
}
else {
mTemplateBuilderTable->Remove(&key);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULDocument::GetTemplateBuilderFor(nsIContent* aContent, nsIXULTemplateBuilder** aResult)
{
if (mTemplateBuilderTable) {
nsISupportsKey key(aContent);
*aResult = NS_STATIC_CAST(nsIXULTemplateBuilder*, mTemplateBuilderTable->Get(&key));
}
else
*aResult = nsnull;
return NS_OK;
}
// Attributes that are used with getElementById() and the
// resource-to-element map.
nsIAtom** nsXULDocument::kIdentityAttrs[] = { &kIdAtom, &kRefAtom, nsnull };
nsIAtom** nsXULDocument::kIdentityAttrs[] = { &nsXULAtoms::id, &nsXULAtoms::ref, nsnull };
nsresult
nsXULDocument::AddElementToMap(nsIContent* aElement)
@ -3900,31 +3770,6 @@ nsXULDocument::Init()
#endif
if (gRefCnt++ == 0) {
kAttributeAtom = NS_NewAtom("attribute");
kCommandUpdaterAtom = NS_NewAtom("commandupdater");
kContextAtom = NS_NewAtom("context");
kDataSourcesAtom = NS_NewAtom("datasources");
kElementAtom = NS_NewAtom("element");
kIdAtom = NS_NewAtom("id");
kKeysetAtom = NS_NewAtom("keyset");
kObservesAtom = NS_NewAtom("observes");
kOpenAtom = NS_NewAtom("open");
kOverlayAtom = NS_NewAtom("overlay");
kPersistAtom = NS_NewAtom("persist");
kPopupAtom = NS_NewAtom("popup");
kPositionAtom = NS_NewAtom("position");
kInsertAfterAtom = NS_NewAtom("insertafter");
kInsertBeforeAtom = NS_NewAtom("insertbefore");
kRemoveElementAtom = NS_NewAtom("removeelement");
kRefAtom = NS_NewAtom("ref");
kRuleAtom = NS_NewAtom("rule");
kStyleAtom = NS_NewAtom("style");
kTemplateAtom = NS_NewAtom("template");
kTooltipAtom = NS_NewAtom("tooltip");
kCoalesceAtom = NS_NewAtom("coalesceduplicatearcs");
kAllowNegativesAtom = NS_NewAtom("allownegativeassertions");
// Keep the RDF service cached in a member variable to make using
// it a bit less painful
rv = nsServiceManager::GetService(kRDFServiceCID,
@ -3968,14 +3813,6 @@ static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
NS_GET_IID(nsIXULPrototypeCache),
(nsISupports**) &gXULCache);
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID,
NS_GET_IID(nsIScriptSecurityManager),
(nsISupports**) &gScriptSecurityManager);
if (NS_FAILED(rv)) return rv;
rv = gScriptSecurityManager->GetSystemPrincipal(&gSystemPrincipal);
if (NS_FAILED(rv)) return rv;
}
#ifdef PR_LOGGING
@ -4366,160 +4203,6 @@ nsXULDocument::ReleaseEvent(const nsAReadableString& aType)
return NS_ERROR_FAILURE;
}
nsresult
nsXULDocument::OpenWidgetItem(nsIContent* aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
if (! mBuilders)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
nsCOMPtr<nsIAtom> tag;
rv = aElement->GetTag(*getter_AddRefs(tag));
if (NS_FAILED(rv)) return rv;
nsAutoString tagStr;
tag->ToString(tagStr);
nsCAutoString tagstrC;
tagstrC.AssignWithConversion(tagStr);
PR_LOG(gXULLog, PR_LOG_DEBUG,
("xuldoc open-widget-item %s",
(const char*) tagstrC));
}
#endif
PRUint32 cnt = 0;
rv = mBuilders->Count(&cnt);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
for (PRUint32 i = 0; i < cnt; ++i) {
// XXX we should QueryInterface() here
nsIRDFContentModelBuilder* builder
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
NS_ASSERTION(builder != nsnull, "null ptr");
if (! builder)
continue;
rv = builder->OpenContainer(aElement);
NS_ASSERTION(NS_SUCCEEDED(rv), "error opening container");
// XXX ignore error code?
NS_RELEASE(builder);
}
return NS_OK;
}
nsresult
nsXULDocument::CloseWidgetItem(nsIContent* aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
if (! mBuilders)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
nsCOMPtr<nsIAtom> tag;
rv = aElement->GetTag(*getter_AddRefs(tag));
if (NS_FAILED(rv)) return rv;
nsAutoString tagStr;
tag->ToString(tagStr);
nsCAutoString tagstrC;
tagstrC.AssignWithConversion(tagStr);
PR_LOG(gXULLog, PR_LOG_DEBUG,
("xuldoc close-widget-item %s",
(const char*) tagstrC));
}
#endif
PRUint32 cnt = 0;
rv = mBuilders->Count(&cnt);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
for (PRUint32 i = 0; i < cnt; ++i) {
// XXX we should QueryInterface() here
nsIRDFContentModelBuilder* builder
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
NS_ASSERTION(builder != nsnull, "null ptr");
if (! builder)
continue;
rv = builder->CloseContainer(aElement);
NS_ASSERTION(NS_SUCCEEDED(rv), "error closing container");
// XXX ignore error code?
NS_RELEASE(builder);
}
return NS_OK;
}
nsresult
nsXULDocument::RebuildWidgetItem(nsIContent* aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
if (! mBuilders)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
nsCOMPtr<nsIAtom> tag;
rv = aElement->GetTag(*getter_AddRefs(tag));
if (NS_FAILED(rv)) return rv;
nsAutoString tagStr;
tag->ToString(tagStr);
nsCAutoString tagstrC;
tagstrC.AssignWithConversion(tagStr);
PR_LOG(gXULLog, PR_LOG_DEBUG,
("xuldoc close-widget-item %s",
(const char*) tagstrC));
}
#endif
PRUint32 cnt = 0;
rv = mBuilders->Count(&cnt);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
for (PRUint32 i = 0; i < cnt; ++i) {
// XXX we should QueryInterface() here
nsIRDFContentModelBuilder* builder
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
NS_ASSERTION(builder != nsnull, "null ptr");
if (! builder)
continue;
rv = builder->RebuildContainer(aElement);
NS_ASSERTION(NS_SUCCEEDED(rv), "error rebuilding container");
// XXX ignore error code?
NS_RELEASE(builder);
}
return NS_OK;
}
nsresult
nsXULDocument::CreateElement(nsINodeInfo *aNodeInfo, nsIContent** aResult)
{
@ -4881,7 +4564,7 @@ nsXULDocument::ContextStack::IsInsideXULTemplate()
if (nameSpaceID == kNameSpaceID_XUL) {
nsCOMPtr<nsIAtom> tag;
element->GetTag(*getter_AddRefs(tag));
if (tag.get() == kTemplateAtom) {
if (tag.get() == nsXULAtoms::Template) {
return PR_TRUE;
}
}
@ -5565,7 +5248,7 @@ nsXULDocument::CreateElement(nsXULPrototypeElement* aPrototype, nsIContent** aRe
if (NS_FAILED(rv)) return rv;
// We also need to pay special attention to the keyset tag to set up a listener
if (aPrototype->mNodeInfo->Equals(kKeysetAtom, kNameSpaceID_XUL)) {
if (aPrototype->mNodeInfo->Equals(nsXULAtoms::keyset, kNameSpaceID_XUL)) {
// Create our XUL key listener and hook it up.
NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv);
if (xblService) {
@ -5649,7 +5332,7 @@ nsXULDocument::CheckTemplateBuilder(nsIContent* aElement)
}
nsAutoString datasources;
rv = aElement->GetAttribute(kNameSpaceID_None, kDataSourcesAtom, datasources);
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::datasources, datasources);
if (NS_FAILED(rv)) return rv;
if (rv != NS_CONTENT_ATTR_HAS_VALUE)
@ -5657,180 +5340,54 @@ nsXULDocument::CheckTemplateBuilder(nsIContent* aElement)
// Get the document and its URL
nsCOMPtr<nsIDocument> doc;
rv = aElement->GetDocument(*getter_AddRefs(doc));
if (NS_FAILED(rv)) return rv;
aElement->GetDocument(*getter_AddRefs(doc));
NS_ASSERTION(doc != nsnull, "no document");
if (! doc)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIURI> docurl = dont_AddRef(doc->GetDocumentURL());
// construct a new builder
nsCOMPtr<nsIRDFContentModelBuilder> builder;
rv = nsComponentManager::CreateInstance(kXULTemplateBuilderCID,
nsnull,
NS_GET_IID(nsIRDFContentModelBuilder),
getter_AddRefs(builder));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create tree content model builder");
if (NS_FAILED(rv)) return rv;
PRInt32 nameSpaceID = 0;
nsCOMPtr<nsIAtom> baseTag;
rv = builder->SetRootContent(aElement);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set builder's root content element");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIXBLService> xblService = do_GetService("@mozilla.org/xbl;1");
if (xblService)
xblService->ResolveTag(aElement, &nameSpaceID, getter_AddRefs(baseTag));
// create a database for the builder
nsCOMPtr<nsIRDFCompositeDataSource> db;
rv = nsComponentManager::CreateInstance(kRDFCompositeDataSourceCID,
nsnull,
NS_GET_IID(nsIRDFCompositeDataSource),
getter_AddRefs(db));
if ((nameSpaceID == kNameSpaceID_XUL) &&
(baseTag.get() == nsXULAtoms::outlinerbody)) {
nsCOMPtr<nsIXULTemplateBuilder> builder =
do_CreateInstance("@mozilla.org/xul/xul-outliner-builder;1");
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to construct new composite data source");
if (NS_FAILED(rv)) return rv;
if (! builder)
return NS_ERROR_FAILURE;
// check for magical attributes
nsAutoString attrib;
if (NS_SUCCEEDED(rv = aElement->GetAttribute(kNameSpaceID_None, kCoalesceAtom, attrib))
&& (rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrib == NS_LITERAL_STRING("false")))
{
db->SetCoalesceDuplicateArcs(PR_FALSE);
}
if (NS_SUCCEEDED(rv = aElement->GetAttribute(kNameSpaceID_None, kAllowNegativesAtom, attrib))
&& (rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrib == NS_LITERAL_STRING("false")))
{
db->SetAllowNegativeAssertions(PR_FALSE);
}
// Grab the doc's principal...
nsCOMPtr<nsIPrincipal> docPrincipal;
rv = doc->GetPrincipal(getter_AddRefs(docPrincipal));
if (NS_FAILED(rv)) return rv;
if (docPrincipal.get() == gSystemPrincipal) {
// If we're a privileged (e.g., chrome) document, then add the
// local store as the first data source in the db. Note that
// we _might_ not be able to get a local store if we haven't
// got a profile to read from yet.
nsCOMPtr<nsIRDFDataSource> localstore;
rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
if (NS_SUCCEEDED(rv)) {
rv = db->AddDataSource(localstore);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add local store to db");
if (NS_FAILED(rv)) return rv;
}
}
// Parse datasources: they are assumed to be a whitespace
// separated list of URIs; e.g.,
//
// rdf:bookmarks rdf:history http://foo.bar.com/blah.cgi?baz=9
//
PRUint32 first = 0;
while(1) {
while (first < datasources.Length() && nsCRT::IsAsciiSpace(datasources.CharAt(first)))
++first;
if (first >= datasources.Length())
break;
PRUint32 last = first;
while (last < datasources.Length() && !nsCRT::IsAsciiSpace(datasources.CharAt(last)))
++last;
nsAutoString uriStr;
datasources.Mid(uriStr, first, last - first);
first = last + 1;
// A special 'dummy' datasource
if (uriStr == NS_LITERAL_STRING("rdf:null"))
continue;
// N.B. that `failure' (e.g., because it's an unknown
// protocol) leaves uriStr unaltered.
NS_MakeAbsoluteURI(uriStr, uriStr, docurl);
if (docPrincipal.get() != gSystemPrincipal) {
// Our document is untrusted, so check to see if we can
// load the datasource that they've asked for.
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), uriStr);
if (NS_FAILED(rv) || !uri)
continue; // Necko will barf if our URI is weird
nsCOMPtr<nsIPrincipal> principal;
rv = gScriptSecurityManager->GetCodebasePrincipal(uri, getter_AddRefs(principal));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get codebase principal");
if (NS_FAILED(rv)) return rv;
PRBool same;
rv = docPrincipal->Equals(principal, &same);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to test same origin");
if (NS_FAILED(rv)) return rv;
if (! same)
continue;
// If we get here, we've run the gauntlet, and the
// datasource's URI has the same origin as our
// document. Let it load!
}
nsCOMPtr<nsIRDFDataSource> ds;
nsCAutoString uristrC;
uristrC.AssignWithConversion(uriStr);
rv = gRDFService->GetDataSource(uristrC, getter_AddRefs(ds));
if (NS_FAILED(rv)) {
// This is only a warning because the data source may not
// be accessable for any number of reasons, including
// security, a bad URL, etc.
#ifdef DEBUG
nsCAutoString msg;
msg.Append("unable to load datasource '");
msg.AppendWithConversion(uriStr);
msg.Append('\'');
NS_WARNING((const char*) msg);
#endif
continue;
}
rv = db->AddDataSource(ds);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add datasource to composite data source");
if (NS_FAILED(rv)) return rv;
}
// add it to the set of builders in use by the document
nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(doc);
if (! xuldoc)
return NS_ERROR_UNEXPECTED;
rv = xuldoc->AddContentModelBuilder(builder);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add builder to the document");
if (NS_FAILED(rv)) return rv;
rv = builder->SetDataBase(db);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set builder's database");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(aElement);
if (xulcontent) {
// Mark the XUL element as being lazy, so the template builder
// will run when layout first asks for these nodes.
//
//rv = xulcontent->ClearLazyState(eTemplateContentsBuilt | eContainerContentsBuilt);
//if (NS_FAILED(rv)) return rv;
xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt);
if (NS_FAILED(rv)) return rv;
// Because the outliner box object won't be created until the
// frame is available, we need to tuck the template builder
// away in the binding manager so there's at least one
// reference to it.
nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(doc);
if (xuldoc)
xuldoc->SetTemplateBuilderFor(aElement, builder);
}
else {
// Force construction of immediate template sub-content _now_.
rv = builder->CreateContents(aElement);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create template contents");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFContentModelBuilder> builder
= do_CreateInstance("@mozilla.org/xul/xul-template-builder;1");
if (! builder)
return NS_ERROR_FAILURE;
builder->SetRootContent(aElement);
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(aElement);
if (xulcontent) {
// Mark the XUL element as being lazy, so the template builder
// will run when layout first asks for these nodes.
xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt);
}
else {
// Force construction of immediate template sub-content _now_.
builder->CreateContents(aElement);
}
}
return NS_OK;
@ -5899,7 +5456,7 @@ nsXULDocument::OverlayForwardReference::Resolve()
nsresult rv;
nsAutoString id;
rv = mOverlay->GetAttribute(kNameSpaceID_None, kIdAtom, id);
rv = mOverlay->GetAttribute(kNameSpaceID_None, nsXULAtoms::id, id);
if (NS_FAILED(rv)) return eResolve_Error;
nsCOMPtr<nsIDOMElement> domtarget;
@ -5964,7 +5521,7 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
if (NS_FAILED(rv)) return rv;
// We don't want to swap IDs, they should be the same.
if (nameSpaceID == kNameSpaceID_None && attr.get() == kIdAtom)
if (nameSpaceID == kNameSpaceID_None && attr.get() == nsXULAtoms::id)
continue;
nsAutoString value;
@ -5972,11 +5529,11 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
if (NS_FAILED(rv)) return rv;
nsAutoString tempID;
rv = aOverlayNode->GetAttribute(kNameSpaceID_None, kIdAtom, tempID);
rv = aOverlayNode->GetAttribute(kNameSpaceID_None, nsXULAtoms::id, tempID);
// Element in the overlay has the 'removeelement' attribute set
// so remove it from the actual document.
if (attr.get() == kRemoveElementAtom &&
if (attr.get() == nsXULAtoms::removeelement &&
value.EqualsIgnoreCase("true")) {
nsCOMPtr<nsIContent> parent;
rv = aTargetNode->GetParent(*getter_AddRefs(parent));
@ -6021,7 +5578,7 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
if (NS_FAILED(rv)) return rv;
nsAutoString id;
rv = currContent->GetAttribute(kNameSpaceID_None, kIdAtom, id);
rv = currContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::id, id);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMElement> nodeInDocument;
@ -6049,7 +5606,7 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
// also has aTargetNode as its parent.
nsAutoString documentParentID;
rv = aTargetNode->GetAttribute(kNameSpaceID_None, kIdAtom,
rv = aTargetNode->GetAttribute(kNameSpaceID_None, nsXULAtoms::id,
documentParentID);
if (NS_FAILED(rv)) return rv;
@ -6089,7 +5646,7 @@ nsXULDocument::OverlayForwardReference::~OverlayForwardReference()
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULLog, PR_LOG_ALWAYS) && !mResolved) {
nsAutoString id;
mOverlay->GetAttribute(kNameSpaceID_None, kIdAtom, id);
mOverlay->GetAttribute(kNameSpaceID_None, nsXULAtoms::id, id);
nsCAutoString idC;
idC.AssignWithConversion(id);
@ -6133,15 +5690,15 @@ nsXULDocument::BroadcasterHookup::~BroadcasterHookup()
nsAutoString broadcasterID;
nsAutoString attribute;
if (tag.get() == kObservesAtom) {
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kElementAtom, broadcasterID);
if (tag.get() == nsXULAtoms::observes) {
rv = mObservesElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::element, broadcasterID);
if (NS_FAILED(rv)) return;
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kAttributeAtom, attribute);
rv = mObservesElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::attribute, attribute);
if (NS_FAILED(rv)) return;
}
else {
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kObservesAtom, broadcasterID);
rv = mObservesElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::observes, broadcasterID);
if (NS_FAILED(rv)) return;
attribute.Assign(NS_LITERAL_STRING("*"));
@ -6193,7 +5750,7 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
nsAutoString broadcasterID;
nsAutoString attribute;
if ((nameSpaceID == kNameSpaceID_XUL) && (tag.get() == kObservesAtom)) {
if ((nameSpaceID == kNameSpaceID_XUL) && (tag.get() == nsXULAtoms::observes)) {
// It's an <observes> element, which means that the actual
// listener is the _parent_ node. This element should have an
// 'element' attribute that specifies the ID of the
@ -6209,17 +5766,17 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
// If we're still parented by an 'overlay' tag, then we haven't
// made it into the real document yet. Defer hookup.
if (parentTag.get() == kOverlayAtom) {
if (parentTag.get() == nsXULAtoms::overlay) {
*aNeedsHookup = PR_TRUE;
return NS_OK;
}
listener = do_QueryInterface(parent);
rv = aElement->GetAttribute(kNameSpaceID_None, kElementAtom, broadcasterID);
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::element, broadcasterID);
if (NS_FAILED(rv)) return rv;
rv = aElement->GetAttribute(kNameSpaceID_None, kAttributeAtom, attribute);
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::attribute, attribute);
if (NS_FAILED(rv)) return rv;
}
else {
@ -6227,7 +5784,7 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
// value of the 'observes' attribute to determine the ID of
// the broadcaster element, and we'll watch _all_ of its
// values.
rv = aElement->GetAttribute(kNameSpaceID_None, kObservesAtom, broadcasterID);
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::observes, broadcasterID);
if (NS_FAILED(rv)) return rv;
// Bail if there's no broadcasterID
@ -6331,12 +5888,12 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild)
PRBool wasInserted = PR_FALSE;
// insert after an element of a given id
rv = aChild->GetAttribute(kNameSpaceID_None, kInsertAfterAtom, posStr);
rv = aChild->GetAttribute(kNameSpaceID_None, nsXULAtoms::insertafter, posStr);
if (NS_FAILED(rv)) return rv;
PRBool isInsertAfter = PR_TRUE;
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
rv = aChild->GetAttribute(kNameSpaceID_None, kInsertBeforeAtom, posStr);
rv = aChild->GetAttribute(kNameSpaceID_None, nsXULAtoms::insertbefore, posStr);
if (NS_FAILED(rv)) return rv;
isInsertAfter = PR_FALSE;
}
@ -6350,14 +5907,14 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild)
nsCOMPtr<nsIDOMElement> domElement;
char* str = posStr.ToNewCString();
char* remainder;
char* token = nsCRT::strtok(str, ", ", &remainder);
char* rest;
char* token = nsCRT::strtok(str, ", ", &rest);
while (token) {
rv = xulDocument->GetElementById(NS_ConvertASCIItoUCS2(token), getter_AddRefs(domElement));
if (domElement) break;
token = nsCRT::strtok(remainder, ", ", &remainder);
token = nsCRT::strtok(rest, ", ", &rest);
}
nsMemory::Free(str);
if (NS_FAILED(rv)) return rv;
@ -6383,7 +5940,7 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild)
if (!wasInserted) {
rv = aChild->GetAttribute(kNameSpaceID_None, kPositionAtom, posStr);
rv = aChild->GetAttribute(kNameSpaceID_None, nsXULAtoms::position, posStr);
if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {

View File

@ -293,8 +293,6 @@ public:
NS_IMETHOD AddElementForID(const nsAReadableString& aID, nsIContent* aElement);
NS_IMETHOD RemoveElementForID(const nsAReadableString& aID, nsIContent* aElement);
NS_IMETHOD GetElementsForID(const nsAReadableString& aID, nsISupportsArray* aElements);
NS_IMETHOD CreateContents(nsIContent* aElement);
NS_IMETHOD AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder);
NS_IMETHOD AddForwardReference(nsForwardReference* aRef);
NS_IMETHOD ResolveForwardReferences();
NS_IMETHOD SetMasterPrototype(nsIXULPrototypeDocument* aDocument);
@ -304,6 +302,8 @@ public:
NS_IMETHOD PrepareStyleSheets(nsIURI* anURL);
NS_IMETHOD AddSubtreeToDocument(nsIContent* aElement);
NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aElement);
NS_IMETHOD SetTemplateBuilderFor(nsIContent* aContent, nsIXULTemplateBuilder* aBuilder);
NS_IMETHOD GetTemplateBuilderFor(nsIContent* aContent, nsIXULTemplateBuilder** aResult);
// nsIDOMEventCapturer interface
NS_IMETHOD CaptureEvent(const nsAReadableString& aType);
@ -383,10 +383,6 @@ protected:
nsresult Init(void);
nsresult StartLayout(void);
nsresult OpenWidgetItem(nsIContent* aElement);
nsresult CloseWidgetItem(nsIContent* aElement);
nsresult RebuildWidgetItem(nsIContent* aElement);
nsresult
AddElementToMap(nsIContent* aElement);
@ -440,31 +436,6 @@ protected:
// pseudo constants
static PRInt32 gRefCnt;
static nsIAtom* kAttributeAtom;
static nsIAtom* kCommandUpdaterAtom;
static nsIAtom* kContextAtom;
static nsIAtom* kDataSourcesAtom;
static nsIAtom* kElementAtom;
static nsIAtom* kIdAtom;
static nsIAtom* kKeysetAtom;
static nsIAtom* kObservesAtom;
static nsIAtom* kOpenAtom;
static nsIAtom* kOverlayAtom;
static nsIAtom* kPersistAtom;
static nsIAtom* kPopupAtom;
static nsIAtom* kPositionAtom;
static nsIAtom* kInsertAfterAtom;
static nsIAtom* kInsertBeforeAtom;
static nsIAtom* kRemoveElementAtom;
static nsIAtom* kRefAtom;
static nsIAtom* kRuleAtom;
static nsIAtom* kStyleAtom;
static nsIAtom* kTemplateAtom;
static nsIAtom* kTooltipAtom;
static nsIAtom* kCoalesceAtom;
static nsIAtom* kAllowNegativesAtom;
static nsIAtom** kIdentityAttrs[];
static nsIRDFService* gRDFService;
@ -480,8 +451,6 @@ protected:
static nsIXULContentUtils* gXULUtils;
static nsIXULPrototypeCache* gXULCache;
static nsIScriptSecurityManager* gScriptSecurityManager;
static nsIPrincipal* gSystemPrincipal;
static PRLogModuleInfo* gXULLog;
@ -527,7 +496,6 @@ protected:
nsCOMPtr<nsIHTMLCSSStyleSheet> mInlineStyleSheet; // [OWNER]
nsCOMPtr<nsICSSLoader> mCSSLoader; // [OWNER]
nsElementMap mElementMap;
nsCOMPtr<nsISupportsArray> mBuilders; // [OWNER] of array, elements shouldn't own this, but they do
nsCOMPtr<nsIRDFDataSource> mLocalStore;
nsCOMPtr<nsILineBreaker> mLineBreaker; // [OWNER]
nsCOMPtr<nsIWordBreaker> mWordBreaker; // [OWNER]
@ -538,6 +506,10 @@ protected:
nsCOMPtr<nsIBindingManager> mBindingManager; // [OWNER] of all bindings
nsSupportsHashtable* mBoxObjectTable; // Box objects for content nodes.
// Maintains the template builders that have been attached to
// content elements
nsSupportsHashtable* mTemplateBuilderTable;
nsVoidArray mForwardReferences;
nsForwardReference::Phase mResolutionPhase;

View File

@ -33,12 +33,7 @@
#include "nsISupports.h"
class nsIAtom;
class nsIContent;
class nsIRDFCompositeDataSource;
class nsIXULDocument;
class nsIRDFNode;
class nsIRDFResource;
// {541AFCB0-A9A3-11d2-8EC5-00805F29F370}
#define NS_IRDFCONTENTMODELBUILDER_IID \
@ -50,44 +45,24 @@ public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFCONTENTMODELBUILDER_IID; return iid; }
/**
* Point the content model builder to the document. The content model
* builder must not reference count the document.
* Called to initialize a XUL content builder on a particular root
* element. This element presumably has a ``datasources''
* attribute, which the builder will parse to set up the template
* builder's datasources.
*/
NS_IMETHOD SetDocument(nsIXULDocument* aDocument) = 0;
NS_IMETHOD SetDataBase(nsIRDFCompositeDataSource* aDataBase) = 0;
NS_IMETHOD GetDataBase(nsIRDFCompositeDataSource** aDataBase) = 0;
/**
* Set the root element from which this content model will
* operate.
*/
NS_IMETHOD CreateRootContent(nsIRDFResource* aResource) = 0;
NS_IMETHOD SetRootContent(nsIContent* aElement) = 0;
/**
* Construct the contents for a container element.
* Invoked lazily by a XUL element that needs its child content
* built.
*/
NS_IMETHOD CreateContents(nsIContent* aElement) = 0;
/**
* 'Open' a container element that was closed before. This gives
* the container a chance to populate its contents.
*/
NS_IMETHOD OpenContainer(nsIContent* aContainer) = 0;
/**
* 'Close' an open container. This gives the container a chance to
* release unused content nodes.
*/
NS_IMETHOD CloseContainer(nsIContent* aContainer) = 0;
/**
* Rebuild the contents of a container.
*/
NS_IMETHOD RebuildContainer(nsIContent* aContainer) = 0;
};
extern nsresult NS_NewXULTemplateBuilder(nsIRDFContentModelBuilder** aResult);
extern NS_IMETHODIMP
NS_NewXULContentBuilder(nsISupports* aOuter, REFNSIID aIID, void** aResult);
extern NS_IMETHODIMP
NS_NewXULOutlinerBuilder(nsISupports* aOuter, REFNSIID aIID, void** aResult);
#endif // nsIRDFContentModelBuilder_h__

View File

@ -20,14 +20,36 @@
* Contributor(s):
*/
#include "domstubs.idl"
#include "nsISupports.idl"
#include "nsIRDFCompositeDataSource.idl"
#include "nsIRDFResource.idl"
[scriptable, uuid(fb744f8e-1dd1-11b2-a5d7-935c9ab60602)]
interface nsIXULTemplateBuilder : nsISupports
{
/**
* The ``root'' node in the DOM to which this builder is attached
*/
readonly attribute nsIDOMElement root;
/**
* The composite datasource that the template builder observes
* and uses to create content
*/
readonly attribute nsIRDFCompositeDataSource database;
/**
* Force the template builder to rebuild its content.
*/
void rebuild();
};
[scriptable, uuid(06b31b15-ebf5-4e74-a0e2-6bc0a18a3969)]
interface nsIXULOutlinerBuilder : nsISupports
{
/**
* Retrieve the RDF resource associated with the specified row.
*/
nsIRDFResource getResourceFor(in long aRowIndex);
};

View File

@ -31,8 +31,26 @@ LIBRARY_NAME = gkconxultmpl_s
REQUIRES = xpcom string js xpconnect timer caps widget dom rdf necko locale xul xuldoc xultmpl
CPPSRCS = \
nsClusterKey.cpp \
nsClusterKeySet.cpp \
nsConflictSet.cpp \
nsContentSupportMap.cpp \
nsContentTagTestNode.cpp \
nsContentTestNode.cpp \
nsInstantiationNode.cpp \
nsOutlinerRowTestNode.cpp \
nsOutlinerRows.cpp \
nsRDFConInstanceTestNode.cpp \
nsRDFConMemberTestNode.cpp \
nsRDFPropertyTestNode.cpp \
nsResourceSet.cpp \
nsRuleNetwork.cpp \
nsTemplateMatch.cpp \
nsTemplateMatchSet.cpp \
nsTemplateRule.cpp \
nsXULContentBuilder.cpp \
nsXULContentUtils.cpp \
nsXULOutlinerBuilder.cpp \
nsXULSortService.cpp \
nsXULTemplateBuilder.cpp \
$(NULL)

View File

@ -27,15 +27,51 @@ MODULE=raptor
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
CPPSRCS= \
nsClusterKey.cpp \
nsClusterKeySet.cpp \
nsConflictSet.cpp \
nsContentSupportMap.cpp \
nsContentTagTestNode.cpp \
nsContentTestNode.cpp \
nsInstantiationNode.cpp \
nsOutlinerRowTestNode.cpp \
nsOutlinerRows.cpp \
nsRDFConInstanceTestNode.cpp \
nsRDFConMemberTestNode.cpp \
nsRDFPropertyTestNode.cpp \
nsResourceSet.cpp \
nsRuleNetwork.cpp \
nsTemplateMatch.cpp \
nsTemplateMatchSet.cpp \
nsTemplateRule.cpp \
nsXULContentBuilder.cpp \
nsXULContentUtils.cpp \
nsXULOutlinerBuilder.cpp \
nsXULSortService.cpp \
nsXULTemplateBuilder.cpp \
$(NULL)
CPP_OBJS= \
.\$(OBJDIR)\nsClusterKey.obj \
.\$(OBJDIR)\nsClusterKeySet.obj \
.\$(OBJDIR)\nsConflictSet.obj \
.\$(OBJDIR)\nsContentSupportMap.obj \
.\$(OBJDIR)\nsContentTagTestNode.obj \
.\$(OBJDIR)\nsContentTestNode.obj \
.\$(OBJDIR)\nsInstantiationNode.obj \
.\$(OBJDIR)\nsOutlinerRowTestNode.obj \
.\$(OBJDIR)\nsOutlinerRows.obj \
.\$(OBJDIR)\nsRDFConInstanceTestNode.obj \
.\$(OBJDIR)\nsRDFConMemberTestNode.obj \
.\$(OBJDIR)\nsRDFPropertyTestNode.obj \
.\$(OBJDIR)\nsResourceSet.obj \
.\$(OBJDIR)\nsRuleNetwork.obj \
.\$(OBJDIR)\nsTemplateMatch.obj \
.\$(OBJDIR)\nsTemplateMatchSet.obj \
.\$(OBJDIR)\nsTemplateRule.obj \
.\$(OBJDIR)\nsXULContentBuilder.obj \
.\$(OBJDIR)\nsXULContentUtils.obj \
.\$(OBJDIR)\nsXULOutlinerBuilder.obj \
.\$(OBJDIR)\nsXULSortService.obj \
.\$(OBJDIR)\nsXULTemplateBuilder.obj \
$(NULL)

View File

@ -40,7 +40,7 @@ nsContentTagTestNode::nsContentTagTestNode(InnerNode* aParent,
{
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
nsAutoString tag = NS_LITERAL_STRING("(none)");
nsAutoString tag(NS_LITERAL_STRING("(none)"));
if (mTag)
mTag->ToString(tag);

View File

@ -78,7 +78,7 @@ nsContentTestNode::nsContentTestNode(InnerNode* aParent,
{
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
nsAutoString tag = NS_LITERAL_STRING("(none)");
nsAutoString tag(NS_LITERAL_STRING("(none)"));
if (mTag)
mTag->ToString(tag);

View File

@ -126,7 +126,7 @@ nsRDFConMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations,
if (hasContainerBinding)
VALUE_TO_IRDFRESOURCE(containerValue)->GetValueConst(&container);
nsAutoString member = NS_LITERAL_STRING("(unbound)");
nsAutoString member(NS_LITERAL_STRING("(unbound)"));
if (hasMemberBinding)
nsXULContentUtils::GetTextForNode(VALUE_TO_IRDFRESOURCE(memberValue), member);

View File

@ -160,7 +160,7 @@ nsRDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations, v
if (hasSourceBinding)
VALUE_TO_IRDFRESOURCE(sourceValue)->GetValueConst(&source);
nsAutoString target = NS_LITERAL_STRING("(unbound)");
nsAutoString target(NS_LITERAL_STRING("(unbound)"));
if (hasTargetBinding)
nsXULContentUtils::GetTextForNode(VALUE_TO_IRDFNODE(targetValue), target);
@ -245,7 +245,7 @@ nsRDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations, v
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
nsAutoString s = NS_LITERAL_STRING("(none found)");
nsAutoString s(NS_LITERAL_STRING("(none found)"));
if (target)
nsXULContentUtils::GetTextForNode(target, s);

View File

@ -44,40 +44,84 @@
#include "nsRuleNetwork.h"
#include "plhash.h"
#include "prlog.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gXULTemplateLog;
#endif
//----------------------------------------------------------------------
//
// nsRuleNetwork
//
nsRuleNetwork::nsRuleNetwork()
: mNextVariable(0)
static PLDHashNumber CRT_CALL
HashEntry(PLDHashTable* aTable, const void* aKey)
{
return nsCRT::HashCode(NS_STATIC_CAST(const PRUnichar*, aKey));
}
nsRuleNetwork::~nsRuleNetwork()
static PRBool CRT_CALL
MatchEntry(PLDHashTable* aTable, const PLDHashEntryHdr* aEntry, const void* aKey)
{
Clear();
const nsRuleNetwork::SymtabEntry* entry =
NS_REINTERPRET_CAST(const nsRuleNetwork::SymtabEntry*, aEntry);
return 0 == nsCRT::strcmp(entry->mSymbol, NS_STATIC_CAST(const PRUnichar*, aKey));
}
nsresult
nsRuleNetwork::CreateVariable(PRInt32* aVariable)
static void CRT_CALL
ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
{
*aVariable = ++mNextVariable;
return NS_OK;
nsRuleNetwork::SymtabEntry* entry =
NS_REINTERPRET_CAST(nsRuleNetwork::SymtabEntry*, aEntry);
nsCRT::free(entry->mSymbol);
PL_DHashClearEntryStub(aTable, aEntry);
}
static PLDHashOperator
RemoveEach(PLDHashTable* aTable, PLDHashEntryHdr* aEntry, PRUint32 aNumber, void* aArg)
{
return PL_DHASH_REMOVE;
}
nsresult
nsRuleNetwork::Clear()
static void CRT_CALL
FinalizeTable(PLDHashTable* aTable)
{
PL_DHashTableEnumerate(aTable, RemoveEach, nsnull);
PL_DHashFinalizeStub(aTable);
}
PLDHashTableOps nsRuleNetwork::gOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
PL_DHashGetKeyStub,
HashEntry,
MatchEntry,
PL_DHashMoveEntryStub,
ClearEntry,
FinalizeTable
};
void
nsRuleNetwork::Init()
{
mNextVariable = 0;
PL_DHashTableInit(&mSymtab, &gOps, nsnull, sizeof(SymtabEntry), PL_DHASH_MIN_SIZE);
}
void
nsRuleNetwork::Finish()
{
PL_DHashTableFinish(&mSymtab);
// We "own" the nodes. So it's up to us to delete 'em
for (NodeSet::Iterator node = mNodes.First(); node != mNodes.Last(); ++node)
delete *node;
mNodes.Clear();
mRoot.RemoveAllChildren();
return NS_OK;
}
@ -86,6 +130,33 @@ nsRuleNetwork::Clear()
// Value
//
#ifdef DEBUG
/**
* A debug-only implementation that verifies that 1) aValue really
* is an nsISupports, and 2) that it really does support the IID
* that is being asked for.
*/
nsISupports*
value_to_isupports(const nsIID& aIID, const Value& aValue)
{
nsresult rv;
// Need to const_cast aValue because QI() & Release() are not const
nsISupports* isupports = NS_STATIC_CAST(nsISupports*, NS_CONST_CAST(Value&, aValue));
if (isupports) {
nsISupports* dummy;
rv = isupports->QueryInterface(aIID, (void**) &dummy);
if (NS_SUCCEEDED(rv)) {
NS_RELEASE(dummy);
}
else {
NS_ERROR("value does not support expected interface");
}
}
return isupports;
}
#endif
Value::Value(const Value& aValue)
: mType(aValue.mType)
{
@ -103,26 +174,35 @@ Value::Value(const Value& aValue)
case eString:
mString = nsCRT::strdup(aValue.mString);
break;
case eInteger:
mInteger = aValue.mInteger;
break;
}
}
Value::Value(nsISupports* aISupports)
: mType(eISupports)
{
MOZ_COUNT_CTOR(Value);
mType = eISupports;
mISupports = aISupports;
NS_IF_ADDREF(mISupports);
}
Value::Value(const PRUnichar* aString)
: mType(eString)
{
MOZ_COUNT_CTOR(Value);
mType = eString;
mString = nsCRT::strdup(aString);
}
Value::Value(PRInt32 aInteger)
: mType(eInteger)
{
MOZ_COUNT_CTOR(Value);
mInteger = aInteger;
}
Value&
Value::operator=(const Value& aValue)
{
@ -142,6 +222,10 @@ Value::operator=(const Value& aValue)
case eString:
mString = nsCRT::strdup(aValue.mString);
break;
case eInteger:
mInteger = aValue.mInteger;
break;
}
return *this;
@ -182,6 +266,7 @@ void
Value::Clear()
{
switch (mType) {
case eInteger:
case eUndefined:
break;
@ -192,6 +277,7 @@ Value::Clear()
case eString:
nsCRT::free(mString);
break;
}
}
@ -209,6 +295,9 @@ Value::Equals(const Value& aValue) const
case eString:
return nsCRT::strcmp(mString, aValue.mString) == 0;
case eInteger:
return mInteger == aValue.mInteger;
}
}
return PR_FALSE;
@ -226,6 +315,12 @@ Value::Equals(const PRUnichar* aString) const
return (mType == eString) && (nsCRT::strcmp(aString, mString) == 0);
}
PRBool
Value::Equals(PRInt32 aInteger) const
{
return (mType == eInteger) && (mInteger == aInteger);
}
PLHashNumber
Value::Hash() const
@ -250,6 +345,10 @@ Value::Hash() const
}
}
break;
case eInteger:
temp = mInteger;
break;
}
return temp;
@ -268,6 +367,12 @@ Value::operator const PRUnichar*() const
return (mType == eString) ? mString : 0;
}
Value::operator PRInt32() const
{
NS_ASSERTION(mType == eInteger, "not an integer");
return (mType == eInteger) ? mInteger : 0;
}
//----------------------------------------------------------------------
//
@ -590,16 +695,25 @@ InstantiationSet::HasAssignmentFor(PRInt32 aVariable) const
nsresult
RootNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure)
{
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("RootNode[%p]: Propogate() begin", this));
NodeSet::Iterator last = mKids.Last();
for (NodeSet::Iterator kid = mKids.First(); kid != last; ++kid)
kid->Propogate(aInstantiations, aClosure);
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("RootNode[%p]: Propogate() end", this));
return NS_OK;
}
nsresult
RootNode::Constrain(InstantiationSet& aInstantiations, void* aClosure)
{
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("RootNode[%p]: Constrain()", this));
return NS_OK;
}
@ -866,16 +980,26 @@ TestNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure)
{
nsresult rv;
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Propogate() begin", this));
InstantiationSet instantiations = aInstantiations;
rv = FilterInstantiations(instantiations, aClosure);
if (NS_FAILED(rv)) return rv;
if (! instantiations.Empty()) {
NodeSet::Iterator last = mKids.Last();
for (NodeSet::Iterator kid = mKids.First(); kid != last; ++kid)
for (NodeSet::Iterator kid = mKids.First(); kid != last; ++kid) {
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Propogate() passing to child %p", this, kid.operator->()));
kid->Propogate(instantiations, aClosure);
}
}
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Propogate() end", this));
return NS_OK;
}
@ -885,18 +1009,31 @@ TestNode::Constrain(InstantiationSet& aInstantiations, void* aClosure)
{
nsresult rv;
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() begin", this));
rv = FilterInstantiations(aInstantiations, aClosure);
if (NS_FAILED(rv)) return rv;
if (! aInstantiations.Empty()) {
// if we still have instantiations, then ride 'em on up to the
// parent to narrow them.
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() passing to parent %p", this, mParent));
rv = mParent->Constrain(aInstantiations, aClosure);
}
else {
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() failed", this));
rv = NS_OK;
}
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() end", this));
return rv;
}

View File

@ -17,10 +17,8 @@
* Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author(s):
* Chris Waterson <waterson@netscape.com>
*
* Contributor(s):
* Chris Waterson <waterson@netscape.com>
*/
/*
@ -51,6 +49,7 @@
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "plhash.h"
#include "pldhash.h"
class nsIRDFResource;
class nsIRDFNode;
@ -63,7 +62,7 @@ class nsIRDFNode;
*/
class Value {
public:
enum Type { eUndefined, eISupports, eString };
enum Type { eUndefined, eISupports, eString, eInteger };
protected:
Type mType;
@ -71,11 +70,13 @@ protected:
union {
nsISupports* mISupports;
PRUnichar* mString;
PRInt32 mInteger;
};
PRBool Equals(const Value& aValue) const;
PRBool Equals(nsISupports* aISupports) const;
PRBool Equals(const PRUnichar* aString) const;
PRBool Equals(PRInt32 aInteger) const;
void Clear();
@ -86,20 +87,24 @@ public:
Value(const Value& aValue);
Value(nsISupports* aISupports);
Value(const PRUnichar* aString);
Value(PRInt32 aInteger);
Value& operator=(const Value& aValue);
Value& operator=(nsISupports* aISupports);
Value& operator=(const PRUnichar* aString);
Value& operator=(PRInt32 aInteger);
~Value();
PRBool operator==(const Value& aValue) const { return Equals(aValue); }
PRBool operator==(nsISupports* aISupports) const { return Equals(aISupports); }
PRBool operator==(const PRUnichar* aString) const { return Equals(aString); }
PRBool operator==(PRInt32 aInteger) const { return Equals(aInteger); }
PRBool operator!=(const Value& aValue) const { return !Equals(aValue); }
PRBool operator!=(nsISupports* aISupports) const { return !Equals(aISupports); }
PRBool operator!=(const PRUnichar* aString) const { return !Equals(aString); }
PRBool operator!=(PRInt32 aInteger) const { return !Equals(aInteger); }
/**
* Get the value's type
@ -122,9 +127,35 @@ public:
*/
operator const PRUnichar*() const;
/**
* Treat the value as an integer.
* @return the value as an integer, or zero if the value is
* not an integer
*/
operator PRInt32() const;
PLHashNumber Hash() const;
};
#ifdef DEBUG
extern nsISupports*
value_to_isupports(const nsIID& aIID, const Value& aValue);
# define VALUE_TO_ISUPPORTS(type, v) \
NS_STATIC_CAST(type*, value_to_isupports(NS_GET_IID(type), (v)))
#else
# define VALUE_TO_ISUPPORTS(type, v) \
NS_STATIC_CAST(type*, NS_STATIC_CAST(nsISupports*, (v)))
#endif
// Convenience wrappers for |Value::operator nsISupports*()|. In a
// debug build, they expand to versions that will call QI() and verify
// that the types are kosher. In an optimized build, they'll just cast
// n' go. Rock on!
#define VALUE_TO_IRDFRESOURCE(v) VALUE_TO_ISUPPORTS(nsIRDFResource, (v))
#define VALUE_TO_IRDFNODE(v) VALUE_TO_ISUPPORTS(nsIRDFNode, (v))
#define VALUE_TO_ICONTENT(v) VALUE_TO_ISUPPORTS(nsIContent, (v))
//----------------------------------------------------------------------
/**
@ -1054,15 +1085,21 @@ protected:
class nsRuleNetwork
{
public:
nsRuleNetwork();
~nsRuleNetwork();
struct SymtabEntry {
PLDHashEntryHdr mHdr;
PRUnichar* mSymbol;
PRInt32 mVariable;
};
nsRuleNetwork() { Init(); }
~nsRuleNetwork() { Finish(); }
/**
* Remove all the nodes from the network. The nodes will be
* destroyed
* @return NS_OK if no errors occur
*/
nsresult Clear();
void Clear() { Finish(); Init(); }
/**
* Add a node to the network. The network assumes ownership of the
@ -1074,25 +1111,80 @@ public:
*/
nsresult AddNode(ReteNode* aNode) { return mNodes.Add(aNode); }
/**
* Create a new, unique variable.
* @param aVariable an out parameter that receives the new
* variable.
* @return NS_OK if no errors occur
*/
nsresult CreateVariable(PRInt32* aVariable);
/**
* Retrieve the root node in the rule network
* @return the root node in the rule network
*/
RootNode* GetRoot() { return &mRoot; };
/**
* Create an unnamed variable
*/
PRInt32 CreateAnonymousVariable() { return ++mNextVariable; }
/**
* Assign a symbol to a variable
*/
void PutSymbol(const PRUnichar* aSymbol, PRInt32 aVariable) {
NS_PRECONDITION(LookupSymbol(aSymbol) == 0, "symbol already defined");
SymtabEntry* entry =
NS_REINTERPRET_CAST(SymtabEntry*,
PL_DHashTableOperate(&mSymtab,
aSymbol,
PL_DHASH_ADD));
if (entry) {
entry->mSymbol = nsCRT::strdup(aSymbol);
entry->mVariable = aVariable;
} };
/**
* Lookup the variable associated with the symbol
*/
PRInt32 LookupSymbol(const PRUnichar* aSymbol, PRBool aCreate = PR_FALSE) {
SymtabEntry* entry =
NS_REINTERPRET_CAST(SymtabEntry*,
PL_DHashTableOperate(&mSymtab,
aSymbol,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(&entry->mHdr))
return entry->mVariable;
PRInt32 result = 0;
if (aCreate) {
result = CreateAnonymousVariable();
PutSymbol(aSymbol, result);
}
return result; }
protected:
/**
* The root node in the network
*/
RootNode mRoot;
/**
* Other nodes in the network
*/
NodeSet mNodes;
void Init();
void Finish();
/**
* Symbol table, mapping symbolic names to variable identifiers
*/
PLDHashTable mSymtab;
/**
* The next available variable identifier
*/
PRInt32 mNextVariable;
RootNode mRoot;
static PLDHashTableOps gOps;
};

View File

@ -1598,8 +1598,11 @@ nsXULContentBuilder::SetContainerAttrs(nsIContent *aElement, const nsTemplateMat
PRBool iscontainer, isempty;
CheckContainer(VALUE_TO_IRDFRESOURCE(containerval), &iscontainer, &isempty);
NS_NAMED_LITERAL_STRING(true_, "true");
NS_NAMED_LITERAL_STRING(false_, "false");
const nsAReadableString& newcontainer =
iscontainer ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false");
iscontainer ? true_ : false_;
if (oldcontainer != newcontainer) {
aElement->SetAttribute(kNameSpaceID_None, nsXULAtoms::container,
@ -1611,9 +1614,7 @@ nsXULContentBuilder::SetContainerAttrs(nsIContent *aElement, const nsTemplateMat
aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::empty, oldempty);
const nsAReadableString& newempty =
(iscontainer && isempty)
? NS_LITERAL_STRING("true")
: NS_LITERAL_STRING("false");
(iscontainer && isempty) ? true_ : false_;
if (oldempty != newempty) {
aElement->SetAttribute(kNameSpaceID_None, nsXULAtoms::empty,
@ -2025,7 +2026,7 @@ nsXULContentBuilder::OpenContainer(nsIContent* aElement)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsXULContentBuilder::CloseContainer(nsIContent* aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");

View File

@ -85,6 +85,12 @@ nsIRDFService* nsXULContentUtils::gRDF;
nsINameSpaceManager* nsXULContentUtils::gNameSpaceManager;
nsIDateTimeFormat* nsXULContentUtils::gFormat;
#define XUL_RESOURCE(ident, uri) nsIRDFResource* nsXULContentUtils::ident
#define XUL_LITERAL(ident, val) nsIRDFLiteral* nsXULContentUtils::ident
#include "nsXULResourceList.h"
#undef XUL_RESOURCE
#undef XUL_LITERAL
//------------------------------------------------------------------------
// Constructors n' stuff
//
@ -99,6 +105,22 @@ nsXULContentUtils::Init()
(nsISupports**) &gRDF);
if (NS_FAILED(rv)) return rv;
#define XUL_RESOURCE(ident, uri) \
PR_BEGIN_MACRO \
rv = gRDF->GetResource((uri), &(ident)); \
if (NS_FAILED(rv)) return rv; \
PR_END_MACRO
#define XUL_LITERAL(ident, val) \
PR_BEGIN_MACRO \
rv = gRDF->GetLiteral(NS_LITERAL_STRING(val).get(), &(ident)); \
if (NS_FAILED(rv)) return rv; \
PR_END_MACRO
#include "nsXULResourceList.h"
#undef XUL_RESOURCE
#undef XUL_LITERAL
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
nsnull,
NS_GET_IID(nsINameSpaceManager),
@ -126,6 +148,12 @@ nsXULContentUtils::Finish()
gRDF = nsnull;
}
#define XUL_RESOURCE(ident, uri) NS_IF_RELEASE(ident)
#define XUL_LITERAL(ident, val) NS_IF_RELEASE(ident)
#include "nsXULResourceList.h"
#undef XUL_RESOURCE
#undef XUL_LITERAL
NS_IF_RELEASE(gNameSpaceManager);
NS_IF_RELEASE(gFormat);
}

View File

@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* Chris Waterson <waterson@netscape.com>
*/
/*
@ -39,6 +40,7 @@ class nsIRDFNode;
class nsCString;
class nsString;
class nsIRDFResource;
class nsIRDFLiteral;
class nsIRDFService;
class nsINameSpaceManager;
class nsIDateTimeFormat;
@ -112,6 +114,12 @@ public:
static nsresult
SetCommandUpdater(nsIDocument* aDocument, nsIContent* aElement);
#define XUL_RESOURCE(ident, uri) static nsIRDFResource* ident
#define XUL_LITERAL(ident, val) static nsIRDFLiteral* ident
#include "nsXULResourceList.h"
#undef XUL_RESOURCE
#undef XUL_LITERAL
};

File diff suppressed because it is too large Load Diff