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
Родитель e452be8652
Коммит cf9c004fa1
26 изменённых файлов: 1784 добавлений и 7686 удалений

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

@ -237,6 +237,10 @@
#define NS_XULTEMPLATEBUILDER_CID \ #define NS_XULTEMPLATEBUILDER_CID \
{ 0x3d262d00, 0x8b5a, 0x11d2, { 0x8e, 0xb0, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } { 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} // {CE058B21-BA9C-11d2-BF86-00105A1B0627}
#define NS_XULCONTENTSINK_CID \ #define NS_XULCONTENTSINK_CID \
{ 0xce058b21, 0xba9c, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } } { 0xce058b21, 0xba9c, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }

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

@ -237,6 +237,10 @@
#define NS_XULTEMPLATEBUILDER_CID \ #define NS_XULTEMPLATEBUILDER_CID \
{ 0x3d262d00, 0x8b5a, 0x11d2, { 0x8e, 0xb0, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } { 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} // {CE058B21-BA9C-11d2-BF86-00105A1B0627}
#define NS_XULCONTENTSINK_CID \ #define NS_XULCONTENTSINK_CID \
{ 0xce058b21, 0xba9c, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } } { 0xce058b21, 0xba9c, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }

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

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

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

@ -358,6 +358,8 @@ static Components gComponents[] = {
"@mozilla.org/xul/xul-sort-service;1", }, "@mozilla.org/xul/xul-sort-service;1", },
{ "XUL Template Builder", NS_XULTEMPLATEBUILDER_CID, { "XUL Template Builder", NS_XULTEMPLATEBUILDER_CID,
"@mozilla.org/xul/xul-template-builder;1", }, "@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, { "XUL Content Sink", NS_XULCONTENTSINK_CID,
"@mozilla.org/xul/xul-content-sink;1", }, "@mozilla.org/xul/xul-content-sink;1", },
{ "XUL Document", NS_XULDOCUMENT_CID, { "XUL Document", NS_XULDOCUMENT_CID,

Двоичные данные
content/macbuild/content.mcp

Двоичный файл не отображается.

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

@ -79,6 +79,8 @@ XUL_ATOM(focus, "focus")
XUL_ATOM(outliner, "outliner") XUL_ATOM(outliner, "outliner")
XUL_ATOM(outlinerbody, "outlinerbody") XUL_ATOM(outlinerbody, "outlinerbody")
XUL_ATOM(outlinercol, "outlinercol") XUL_ATOM(outlinercol, "outlinercol")
XUL_ATOM(outlinerrow, "outlinerrow")
XUL_ATOM(outlinercell, "outlinercell")
XUL_ATOM(cycler, "cycler") XUL_ATOM(cycler, "cycler")
XUL_ATOM(primary, "primary") XUL_ATOM(primary, "primary")
@ -249,9 +251,23 @@ XUL_ATOM(child, "child")
XUL_ATOM(object, "object") XUL_ATOM(object, "object")
XUL_ATOM(tag, "tag") XUL_ATOM(tag, "tag")
XUL_ATOM(content, "content") 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(blankrow, "blankrow")
XUL_ATOM(titlebar, "titlebar") XUL_ATOM(titlebar, "titlebar")
XUL_ATOM(resizer, "resizer") XUL_ATOM(resizer, "resizer")
XUL_ATOM(dir, "dir") XUL_ATOM(dir, "dir")
XUL_ATOM(properties, "properties")
XUL_ATOM(sort, "sort")
XUL_ATOM(sortDirection, "sortDirection")
XUL_ATOM(sortActive, "sortActive")

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

@ -104,12 +104,6 @@ public:
* should call this method, think again. You shouldn't. * should call this method, think again. You shouldn't.
*/ */
NS_IMETHOD ForceElementToOwnResource(PRBool aForce) = 0; 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__ #endif // nsIXULContent_h__

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

@ -88,6 +88,7 @@
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
#include "nsIRDFCompositeDataSource.h" #include "nsIRDFCompositeDataSource.h"
#include "nsIRDFContentModelBuilder.h"
#include "nsIRDFNode.h" #include "nsIRDFNode.h"
#include "nsIRDFService.h" #include "nsIRDFService.h"
#include "nsIScriptContext.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 // nsIDOMEventReceiver interface
@ -3882,8 +3864,14 @@ nsXULElement::GetResource(nsIRDFResource** aResource)
NS_IMETHODIMP NS_IMETHODIMP
nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase) nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
{ {
*aDatabase = Database(); nsCOMPtr<nsIXULTemplateBuilder> builder;
NS_IF_ADDREF(*aDatabase); GetBuilder(getter_AddRefs(builder));
if (builder)
builder->GetDatabase(aDatabase);
else
*aDatabase = nsnull;
return NS_OK; return NS_OK;
} }
@ -3891,8 +3879,14 @@ nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
NS_IMETHODIMP NS_IMETHODIMP
nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder) nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
{ {
*aBuilder = Builder(); *aBuilder = nsnull;
NS_IF_ADDREF(*aBuilder);
if (mDocument) {
nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mDocument);
if (xuldoc)
xuldoc->GetTemplateBuilderFor(NS_STATIC_CAST(nsIStyledContent*, this), aBuilder);
}
return NS_OK; return NS_OK;
} }
@ -3918,14 +3912,35 @@ nsXULElement::EnsureContentsGenerated(void) const
// getters if needed. // getters if needed.
unconstThis->mLazyState &= ~nsIXULContent::eChildrenMustBeRebuilt; unconstThis->mLazyState &= ~nsIXULContent::eChildrenMustBeRebuilt;
nsCOMPtr<nsIXULDocument> rdfDoc = do_QueryInterface(mDocument); // Walk up our ancestor chain, looking for an element with a
if (! mDocument) // XUL content model builder attached to it.
return NS_OK; nsCOMPtr<nsIContent> element
= do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, unconstThis));
nsresult rv = rdfDoc->CreateContents(NS_STATIC_CAST(nsIStyledContent*, unconstThis)); do {
NS_ASSERTION(NS_SUCCEEDED(rv), "problem creating kids"); nsCOMPtr<nsIDOMXULElement> xulele = do_QueryInterface(element);
if (NS_FAILED(rv)) return rv; 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; return NS_OK;
} }
@ -4645,7 +4660,6 @@ nsXULElement::Slots::Slots(nsXULElement* aElement)
: mElement(aElement), : mElement(aElement),
mBroadcastListeners(nsnull), mBroadcastListeners(nsnull),
mBroadcaster(nsnull), mBroadcaster(nsnull),
mBuilder(nsnull),
mAttributes(nsnull), mAttributes(nsnull),
mInnerXULElement(nsnull) mInnerXULElement(nsnull)
{ {

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

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

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

@ -42,10 +42,10 @@ class nsForwardReference;
class nsIAtom; class nsIAtom;
class nsIDOMElement; class nsIDOMElement;
class nsIPrincipal; class nsIPrincipal;
class nsIRDFContentModelBuilder;
class nsIRDFResource; class nsIRDFResource;
class nsISupportsArray; class nsISupportsArray;
class nsIXULPrototypeDocument; class nsIXULPrototypeDocument;
class nsIXULTemplateBuilder;
class nsIURI; class nsIURI;
// {954F0811-81DC-11d2-B52A-000000000000} // {954F0811-81DC-11d2-B52A-000000000000}
@ -84,13 +84,6 @@ public:
*/ */
NS_IMETHOD GetElementsForID(const nsAReadableString& aID, nsISupportsArray* aElements) = 0; 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 * Add a "forward declaration" of a XUL observer. Such declarations
* will be resolved when document loading completes. * will be resolved when document loading completes.
@ -136,6 +129,19 @@ public:
* Notify the XUL document that a subtree has been removed * Notify the XUL document that a subtree has been removed
*/ */
NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aElement) = 0; 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 // factory functions

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

@ -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(kXULContentSinkCID, NS_XULCONTENTSINK_CID);
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID); static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
static NS_DEFINE_CID(kXULTemplateBuilderCID, NS_XULTEMPLATEBUILDER_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(kDOMImplementationCID, NS_DOM_IMPLEMENTATION_CID);
static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID); static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID);
@ -200,31 +201,6 @@ const nsForwardReference::Phase nsForwardReference::kPasses[] = {
PRInt32 nsXULDocument::gRefCnt = 0; 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; nsIRDFService* nsXULDocument::gRDFService;
nsIRDFResource* nsXULDocument::kNC_persist; nsIRDFResource* nsXULDocument::kNC_persist;
nsIRDFResource* nsXULDocument::kNC_attribute; nsIRDFResource* nsXULDocument::kNC_attribute;
@ -237,8 +213,6 @@ nsINameSpaceManager* nsXULDocument::gNameSpaceManager;
PRInt32 nsXULDocument::kNameSpaceID_XUL; PRInt32 nsXULDocument::kNameSpaceID_XUL;
nsIXULPrototypeCache* nsXULDocument::gXULCache; nsIXULPrototypeCache* nsXULDocument::gXULCache;
nsIScriptSecurityManager* nsXULDocument::gScriptSecurityManager;
nsIPrincipal* nsXULDocument::gSystemPrincipal;
PRLogModuleInfo* nsXULDocument::gXULLog; PRLogModuleInfo* nsXULDocument::gXULLog;
@ -427,11 +401,12 @@ nsXULDocument::nsXULDocument(void)
mNextSrcLoadWaiter(nsnull), mNextSrcLoadWaiter(nsnull),
mDisplaySelection(PR_FALSE), mDisplaySelection(PR_FALSE),
mIsPopup(PR_FALSE), mIsPopup(PR_FALSE),
mBoxObjectTable(nsnull),
mTemplateBuilderTable(nsnull),
mResolutionPhase(nsForwardReference::eStart), mResolutionPhase(nsForwardReference::eStart),
mNextContentID(NS_CONTENT_ID_COUNTER_BASE), mNextContentID(NS_CONTENT_ID_COUNTER_BASE),
mState(eState_Master), mState(eState_Master),
mCurrentScriptProto(nsnull), mCurrentScriptProto(nsnull),
mBoxObjectTable(nsnull),
mNumCapturers(0) mNumCapturers(0)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
@ -453,6 +428,13 @@ nsXULDocument::~nsXULDocument()
// decls never got resolved. // decls never got resolved.
DestroyForwardReferences(); 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 // mParentDocument is never refcounted
// Delete references to sub-documents // Delete references to sub-documents
{ {
@ -483,45 +465,10 @@ nsXULDocument::~nsXULDocument()
mCSSLoader->DropDocumentReference(); mCSSLoader->DropDocumentReference();
} }
delete mTemplateBuilderTable;
delete mBoxObjectTable; 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) { 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) { if (gRDFService) {
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService); nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
gRDFService = nsnull; gRDFService = nsnull;
@ -543,13 +490,6 @@ nsXULDocument::~nsXULDocument()
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache); nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache);
gXULCache = nsnull; 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) if (mRootContent)
mRootContent->SetDocument(nsnull, PR_TRUE, PR_TRUE); 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 // Propagate the out-of-band notification to each PresShell's
// anonymous content as well. This ensures that there aren't // anonymous content as well. This ensures that there aren't
// any accidental script references left in anonymous content // any accidental script references left in anonymous content
@ -1617,7 +1532,7 @@ nsXULDocument::AttributeChanged(nsIContent* aElement,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
// First see if we need to update our element map. // 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); rv = mElementMap.Enumerate(RemoveElementsFromMapByContent, aElement);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
@ -1628,22 +1543,6 @@ nsXULDocument::AttributeChanged(nsIContent* aElement,
if (NS_FAILED(rv)) return rv; 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 // Now notify external observers
for (PRInt32 i = 0; i < mObservers.Count(); i++) { for (PRInt32 i = 0; i < mObservers.Count(); i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[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 // Finally, see if there is anything we need to persist in the
// localstore. // localstore.
// //
// XXX Namespace handling broken :-( // XXX Namespace handling broken :-(
nsAutoString persist; nsAutoString persist;
rv = aElement->GetAttribute(kNameSpaceID_None, kPersistAtom, persist); rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::persist, persist);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) { if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
@ -2096,7 +1987,6 @@ nsXULDocument::RemoveElementForID(const nsAReadableString& aID, nsIContent* aEle
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsXULDocument::GetElementsForID(const nsAReadableString& aID, nsISupportsArray* aElements) nsXULDocument::GetElementsForID(const nsAReadableString& aID, nsISupportsArray* aElements)
{ {
@ -2108,60 +1998,6 @@ nsXULDocument::GetElementsForID(const nsAReadableString& aID, nsISupportsArray*
return NS_OK; 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 NS_IMETHODIMP
nsXULDocument::AddForwardReference(nsForwardReference* aRef) nsXULDocument::AddForwardReference(nsForwardReference* aRef)
{ {
@ -3169,7 +3005,7 @@ nsXULDocument::AddElementToDocumentPre(nsIContent* aElement)
// "commandupdater='true'" attribute), then add the element to the // "commandupdater='true'" attribute), then add the element to the
// document's command dispatcher // document's command dispatcher
nsAutoString value; 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")) { if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && value == NS_LITERAL_STRING("true")) {
rv = nsXULContentUtils::SetCommandUpdater(this, aElement); rv = nsXULContentUtils::SetCommandUpdater(this, aElement);
if (NS_FAILED(rv)) return rv; 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 // 3. If the element is a 'command updater', then remove the
// element from the document's command dispatcher. // element from the document's command dispatcher.
nsAutoString value; 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")) { if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && value == NS_LITERAL_STRING("true")) {
nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement); nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
NS_ASSERTION(domelement != nsnull, "not a DOM element"); NS_ASSERTION(domelement != nsnull, "not a DOM element");
@ -3273,9 +3109,43 @@ nsXULDocument::RemoveSubtreeFromDocument(nsIContent* aElement)
return NS_OK; 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 // Attributes that are used with getElementById() and the
// resource-to-element map. // resource-to-element map.
nsIAtom** nsXULDocument::kIdentityAttrs[] = { &kIdAtom, &kRefAtom, nsnull }; nsIAtom** nsXULDocument::kIdentityAttrs[] = { &nsXULAtoms::id, &nsXULAtoms::ref, nsnull };
nsresult nsresult
nsXULDocument::AddElementToMap(nsIContent* aElement) nsXULDocument::AddElementToMap(nsIContent* aElement)
@ -3900,31 +3770,6 @@ nsXULDocument::Init()
#endif #endif
if (gRefCnt++ == 0) { 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 // Keep the RDF service cached in a member variable to make using
// it a bit less painful // it a bit less painful
rv = nsServiceManager::GetService(kRDFServiceCID, rv = nsServiceManager::GetService(kRDFServiceCID,
@ -3968,14 +3813,6 @@ static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
NS_GET_IID(nsIXULPrototypeCache), NS_GET_IID(nsIXULPrototypeCache),
(nsISupports**) &gXULCache); (nsISupports**) &gXULCache);
if (NS_FAILED(rv)) return rv; 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 #ifdef PR_LOGGING
@ -4366,160 +4203,6 @@ nsXULDocument::ReleaseEvent(const nsAReadableString& aType)
return NS_ERROR_FAILURE; 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 nsresult
nsXULDocument::CreateElement(nsINodeInfo *aNodeInfo, nsIContent** aResult) nsXULDocument::CreateElement(nsINodeInfo *aNodeInfo, nsIContent** aResult)
{ {
@ -4881,7 +4564,7 @@ nsXULDocument::ContextStack::IsInsideXULTemplate()
if (nameSpaceID == kNameSpaceID_XUL) { if (nameSpaceID == kNameSpaceID_XUL) {
nsCOMPtr<nsIAtom> tag; nsCOMPtr<nsIAtom> tag;
element->GetTag(*getter_AddRefs(tag)); element->GetTag(*getter_AddRefs(tag));
if (tag.get() == kTemplateAtom) { if (tag.get() == nsXULAtoms::Template) {
return PR_TRUE; return PR_TRUE;
} }
} }
@ -5565,7 +5248,7 @@ nsXULDocument::CreateElement(nsXULPrototypeElement* aPrototype, nsIContent** aRe
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
// We also need to pay special attention to the keyset tag to set up a listener // 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. // Create our XUL key listener and hook it up.
NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv); NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv);
if (xblService) { if (xblService) {
@ -5649,7 +5332,7 @@ nsXULDocument::CheckTemplateBuilder(nsIContent* aElement)
} }
nsAutoString datasources; nsAutoString datasources;
rv = aElement->GetAttribute(kNameSpaceID_None, kDataSourcesAtom, datasources); rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::datasources, datasources);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (rv != NS_CONTENT_ATTR_HAS_VALUE) if (rv != NS_CONTENT_ATTR_HAS_VALUE)
@ -5657,180 +5340,54 @@ nsXULDocument::CheckTemplateBuilder(nsIContent* aElement)
// Get the document and its URL // Get the document and its URL
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDocument> doc;
rv = aElement->GetDocument(*getter_AddRefs(doc)); aElement->GetDocument(*getter_AddRefs(doc));
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(doc != nsnull, "no document"); NS_ASSERTION(doc != nsnull, "no document");
if (! doc) if (! doc)
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIURI> docurl = dont_AddRef(doc->GetDocumentURL());
// construct a new builder // construct a new builder
nsCOMPtr<nsIRDFContentModelBuilder> builder; PRInt32 nameSpaceID = 0;
rv = nsComponentManager::CreateInstance(kXULTemplateBuilderCID, nsCOMPtr<nsIAtom> baseTag;
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;
rv = builder->SetRootContent(aElement); nsCOMPtr<nsIXBLService> xblService = do_GetService("@mozilla.org/xbl;1");
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set builder's root content element"); if (xblService)
if (NS_FAILED(rv)) return rv; xblService->ResolveTag(aElement, &nameSpaceID, getter_AddRefs(baseTag));
// create a database for the builder if ((nameSpaceID == kNameSpaceID_XUL) &&
nsCOMPtr<nsIRDFCompositeDataSource> db; (baseTag.get() == nsXULAtoms::outlinerbody)) {
rv = nsComponentManager::CreateInstance(kRDFCompositeDataSourceCID, nsCOMPtr<nsIXULTemplateBuilder> builder =
nsnull, do_CreateInstance("@mozilla.org/xul/xul-outliner-builder;1");
NS_GET_IID(nsIRDFCompositeDataSource),
getter_AddRefs(db));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to construct new composite data source"); if (! builder)
if (NS_FAILED(rv)) return rv; return NS_ERROR_FAILURE;
// check for magical attributes // Because the outliner box object won't be created until the
nsAutoString attrib; // frame is available, we need to tuck the template builder
if (NS_SUCCEEDED(rv = aElement->GetAttribute(kNameSpaceID_None, kCoalesceAtom, attrib)) // away in the binding manager so there's at least one
&& (rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrib == NS_LITERAL_STRING("false"))) // reference to it.
{ nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(doc);
db->SetCoalesceDuplicateArcs(PR_FALSE); if (xuldoc)
} xuldoc->SetTemplateBuilderFor(aElement, builder);
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;
} }
else { else {
// Force construction of immediate template sub-content _now_. nsCOMPtr<nsIRDFContentModelBuilder> builder
rv = builder->CreateContents(aElement); = do_CreateInstance("@mozilla.org/xul/xul-template-builder;1");
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create template contents");
if (NS_FAILED(rv)) return rv; 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; return NS_OK;
@ -5899,7 +5456,7 @@ nsXULDocument::OverlayForwardReference::Resolve()
nsresult rv; nsresult rv;
nsAutoString id; nsAutoString id;
rv = mOverlay->GetAttribute(kNameSpaceID_None, kIdAtom, id); rv = mOverlay->GetAttribute(kNameSpaceID_None, nsXULAtoms::id, id);
if (NS_FAILED(rv)) return eResolve_Error; if (NS_FAILED(rv)) return eResolve_Error;
nsCOMPtr<nsIDOMElement> domtarget; nsCOMPtr<nsIDOMElement> domtarget;
@ -5964,7 +5521,7 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
// We don't want to swap IDs, they should be the same. // 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; continue;
nsAutoString value; nsAutoString value;
@ -5972,11 +5529,11 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsAutoString tempID; 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 // Element in the overlay has the 'removeelement' attribute set
// so remove it from the actual document. // so remove it from the actual document.
if (attr.get() == kRemoveElementAtom && if (attr.get() == nsXULAtoms::removeelement &&
value.EqualsIgnoreCase("true")) { value.EqualsIgnoreCase("true")) {
nsCOMPtr<nsIContent> parent; nsCOMPtr<nsIContent> parent;
rv = aTargetNode->GetParent(*getter_AddRefs(parent)); rv = aTargetNode->GetParent(*getter_AddRefs(parent));
@ -6021,7 +5578,7 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsAutoString id; nsAutoString id;
rv = currContent->GetAttribute(kNameSpaceID_None, kIdAtom, id); rv = currContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::id, id);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMElement> nodeInDocument; nsCOMPtr<nsIDOMElement> nodeInDocument;
@ -6049,7 +5606,7 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
// also has aTargetNode as its parent. // also has aTargetNode as its parent.
nsAutoString documentParentID; nsAutoString documentParentID;
rv = aTargetNode->GetAttribute(kNameSpaceID_None, kIdAtom, rv = aTargetNode->GetAttribute(kNameSpaceID_None, nsXULAtoms::id,
documentParentID); documentParentID);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
@ -6089,7 +5646,7 @@ nsXULDocument::OverlayForwardReference::~OverlayForwardReference()
#ifdef PR_LOGGING #ifdef PR_LOGGING
if (PR_LOG_TEST(gXULLog, PR_LOG_ALWAYS) && !mResolved) { if (PR_LOG_TEST(gXULLog, PR_LOG_ALWAYS) && !mResolved) {
nsAutoString id; nsAutoString id;
mOverlay->GetAttribute(kNameSpaceID_None, kIdAtom, id); mOverlay->GetAttribute(kNameSpaceID_None, nsXULAtoms::id, id);
nsCAutoString idC; nsCAutoString idC;
idC.AssignWithConversion(id); idC.AssignWithConversion(id);
@ -6133,15 +5690,15 @@ nsXULDocument::BroadcasterHookup::~BroadcasterHookup()
nsAutoString broadcasterID; nsAutoString broadcasterID;
nsAutoString attribute; nsAutoString attribute;
if (tag.get() == kObservesAtom) { if (tag.get() == nsXULAtoms::observes) {
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kElementAtom, broadcasterID); rv = mObservesElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::element, broadcasterID);
if (NS_FAILED(rv)) return; 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; if (NS_FAILED(rv)) return;
} }
else { else {
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kObservesAtom, broadcasterID); rv = mObservesElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::observes, broadcasterID);
if (NS_FAILED(rv)) return; if (NS_FAILED(rv)) return;
attribute.Assign(NS_LITERAL_STRING("*")); attribute.Assign(NS_LITERAL_STRING("*"));
@ -6193,7 +5750,7 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
nsAutoString broadcasterID; nsAutoString broadcasterID;
nsAutoString attribute; 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 // It's an <observes> element, which means that the actual
// listener is the _parent_ node. This element should have an // listener is the _parent_ node. This element should have an
// 'element' attribute that specifies the ID of the // '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 // If we're still parented by an 'overlay' tag, then we haven't
// made it into the real document yet. Defer hookup. // made it into the real document yet. Defer hookup.
if (parentTag.get() == kOverlayAtom) { if (parentTag.get() == nsXULAtoms::overlay) {
*aNeedsHookup = PR_TRUE; *aNeedsHookup = PR_TRUE;
return NS_OK; return NS_OK;
} }
listener = do_QueryInterface(parent); 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; 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; if (NS_FAILED(rv)) return rv;
} }
else { else {
@ -6227,7 +5784,7 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
// value of the 'observes' attribute to determine the ID of // value of the 'observes' attribute to determine the ID of
// the broadcaster element, and we'll watch _all_ of its // the broadcaster element, and we'll watch _all_ of its
// values. // values.
rv = aElement->GetAttribute(kNameSpaceID_None, kObservesAtom, broadcasterID); rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::observes, broadcasterID);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
// Bail if there's no broadcasterID // Bail if there's no broadcasterID
@ -6331,12 +5888,12 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild)
PRBool wasInserted = PR_FALSE; PRBool wasInserted = PR_FALSE;
// insert after an element of a given id // 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; if (NS_FAILED(rv)) return rv;
PRBool isInsertAfter = PR_TRUE; PRBool isInsertAfter = PR_TRUE;
if (rv != NS_CONTENT_ATTR_HAS_VALUE) { 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; if (NS_FAILED(rv)) return rv;
isInsertAfter = PR_FALSE; isInsertAfter = PR_FALSE;
} }
@ -6350,14 +5907,14 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild)
nsCOMPtr<nsIDOMElement> domElement; nsCOMPtr<nsIDOMElement> domElement;
char* str = posStr.ToNewCString(); char* str = posStr.ToNewCString();
char* remainder; char* rest;
char* token = nsCRT::strtok(str, ", ", &remainder); char* token = nsCRT::strtok(str, ", ", &rest);
while (token) { while (token) {
rv = xulDocument->GetElementById(NS_ConvertASCIItoUCS2(token), getter_AddRefs(domElement)); rv = xulDocument->GetElementById(NS_ConvertASCIItoUCS2(token), getter_AddRefs(domElement));
if (domElement) break; if (domElement) break;
token = nsCRT::strtok(remainder, ", ", &remainder); token = nsCRT::strtok(rest, ", ", &rest);
} }
nsMemory::Free(str); nsMemory::Free(str);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
@ -6383,7 +5940,7 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild)
if (!wasInserted) { if (!wasInserted) {
rv = aChild->GetAttribute(kNameSpaceID_None, kPositionAtom, posStr); rv = aChild->GetAttribute(kNameSpaceID_None, nsXULAtoms::position, posStr);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) { if (rv == NS_CONTENT_ATTR_HAS_VALUE) {

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

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

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

@ -33,12 +33,7 @@
#include "nsISupports.h" #include "nsISupports.h"
class nsIAtom;
class nsIContent; class nsIContent;
class nsIRDFCompositeDataSource;
class nsIXULDocument;
class nsIRDFNode;
class nsIRDFResource;
// {541AFCB0-A9A3-11d2-8EC5-00805F29F370} // {541AFCB0-A9A3-11d2-8EC5-00805F29F370}
#define NS_IRDFCONTENTMODELBUILDER_IID \ #define NS_IRDFCONTENTMODELBUILDER_IID \
@ -50,44 +45,24 @@ public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFCONTENTMODELBUILDER_IID; return iid; } static const nsIID& GetIID() { static nsIID iid = NS_IRDFCONTENTMODELBUILDER_IID; return iid; }
/** /**
* Point the content model builder to the document. The content model * Called to initialize a XUL content builder on a particular root
* builder must not reference count the document. * 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; 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; 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__ #endif // nsIRDFContentModelBuilder_h__

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

@ -20,14 +20,36 @@
* Contributor(s): * Contributor(s):
*/ */
#include "domstubs.idl"
#include "nsISupports.idl" #include "nsISupports.idl"
#include "nsIRDFCompositeDataSource.idl"
#include "nsIRDFResource.idl"
[scriptable, uuid(fb744f8e-1dd1-11b2-a5d7-935c9ab60602)] [scriptable, uuid(fb744f8e-1dd1-11b2-a5d7-935c9ab60602)]
interface nsIXULTemplateBuilder : nsISupports 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. * Force the template builder to rebuild its content.
*/ */
void rebuild(); 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);
};

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

@ -31,8 +31,26 @@ LIBRARY_NAME = gkconxultmpl_s
REQUIRES = xpcom string js xpconnect timer caps widget dom rdf necko locale xul xuldoc xultmpl REQUIRES = xpcom string js xpconnect timer caps widget dom rdf necko locale xul xuldoc xultmpl
CPPSRCS = \ 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 \ nsRuleNetwork.cpp \
nsTemplateMatch.cpp \
nsTemplateMatchSet.cpp \
nsTemplateRule.cpp \
nsXULContentBuilder.cpp \
nsXULContentUtils.cpp \ nsXULContentUtils.cpp \
nsXULOutlinerBuilder.cpp \
nsXULSortService.cpp \ nsXULSortService.cpp \
nsXULTemplateBuilder.cpp \ nsXULTemplateBuilder.cpp \
$(NULL) $(NULL)

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

@ -27,15 +27,51 @@ MODULE=raptor
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
CPPSRCS= \ 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 \ nsRuleNetwork.cpp \
nsTemplateMatch.cpp \
nsTemplateMatchSet.cpp \
nsTemplateRule.cpp \
nsXULContentBuilder.cpp \
nsXULContentUtils.cpp \ nsXULContentUtils.cpp \
nsXULOutlinerBuilder.cpp \
nsXULSortService.cpp \ nsXULSortService.cpp \
nsXULTemplateBuilder.cpp \ nsXULTemplateBuilder.cpp \
$(NULL) $(NULL)
CPP_OBJS= \ 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)\nsRuleNetwork.obj \
.\$(OBJDIR)\nsTemplateMatch.obj \
.\$(OBJDIR)\nsTemplateMatchSet.obj \
.\$(OBJDIR)\nsTemplateRule.obj \
.\$(OBJDIR)\nsXULContentBuilder.obj \
.\$(OBJDIR)\nsXULContentUtils.obj \ .\$(OBJDIR)\nsXULContentUtils.obj \
.\$(OBJDIR)\nsXULOutlinerBuilder.obj \
.\$(OBJDIR)\nsXULSortService.obj \ .\$(OBJDIR)\nsXULSortService.obj \
.\$(OBJDIR)\nsXULTemplateBuilder.obj \ .\$(OBJDIR)\nsXULTemplateBuilder.obj \
$(NULL) $(NULL)

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

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

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

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

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

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

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

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

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

@ -44,40 +44,84 @@
#include "nsRuleNetwork.h" #include "nsRuleNetwork.h"
#include "plhash.h" #include "plhash.h"
#include "prlog.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gXULTemplateLog;
#endif
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// //
// nsRuleNetwork // nsRuleNetwork
// //
nsRuleNetwork::nsRuleNetwork() static PLDHashNumber CRT_CALL
: mNextVariable(0) 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 static void CRT_CALL
nsRuleNetwork::CreateVariable(PRInt32* aVariable) ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
{ {
*aVariable = ++mNextVariable; nsRuleNetwork::SymtabEntry* entry =
return NS_OK; 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 static void CRT_CALL
nsRuleNetwork::Clear() 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 // We "own" the nodes. So it's up to us to delete 'em
for (NodeSet::Iterator node = mNodes.First(); node != mNodes.Last(); ++node) for (NodeSet::Iterator node = mNodes.First(); node != mNodes.Last(); ++node)
delete *node; delete *node;
mNodes.Clear(); mNodes.Clear();
mRoot.RemoveAllChildren(); mRoot.RemoveAllChildren();
return NS_OK;
} }
@ -86,6 +130,33 @@ nsRuleNetwork::Clear()
// Value // 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) Value::Value(const Value& aValue)
: mType(aValue.mType) : mType(aValue.mType)
{ {
@ -103,26 +174,35 @@ Value::Value(const Value& aValue)
case eString: case eString:
mString = nsCRT::strdup(aValue.mString); mString = nsCRT::strdup(aValue.mString);
break; break;
case eInteger:
mInteger = aValue.mInteger;
break;
} }
} }
Value::Value(nsISupports* aISupports) Value::Value(nsISupports* aISupports)
: mType(eISupports)
{ {
MOZ_COUNT_CTOR(Value); MOZ_COUNT_CTOR(Value);
mType = eISupports;
mISupports = aISupports; mISupports = aISupports;
NS_IF_ADDREF(mISupports); NS_IF_ADDREF(mISupports);
} }
Value::Value(const PRUnichar* aString) Value::Value(const PRUnichar* aString)
: mType(eString)
{ {
MOZ_COUNT_CTOR(Value); MOZ_COUNT_CTOR(Value);
mType = eString;
mString = nsCRT::strdup(aString); mString = nsCRT::strdup(aString);
} }
Value::Value(PRInt32 aInteger)
: mType(eInteger)
{
MOZ_COUNT_CTOR(Value);
mInteger = aInteger;
}
Value& Value&
Value::operator=(const Value& aValue) Value::operator=(const Value& aValue)
{ {
@ -142,6 +222,10 @@ Value::operator=(const Value& aValue)
case eString: case eString:
mString = nsCRT::strdup(aValue.mString); mString = nsCRT::strdup(aValue.mString);
break; break;
case eInteger:
mInteger = aValue.mInteger;
break;
} }
return *this; return *this;
@ -182,6 +266,7 @@ void
Value::Clear() Value::Clear()
{ {
switch (mType) { switch (mType) {
case eInteger:
case eUndefined: case eUndefined:
break; break;
@ -192,6 +277,7 @@ Value::Clear()
case eString: case eString:
nsCRT::free(mString); nsCRT::free(mString);
break; break;
} }
} }
@ -209,6 +295,9 @@ Value::Equals(const Value& aValue) const
case eString: case eString:
return nsCRT::strcmp(mString, aValue.mString) == 0; return nsCRT::strcmp(mString, aValue.mString) == 0;
case eInteger:
return mInteger == aValue.mInteger;
} }
} }
return PR_FALSE; return PR_FALSE;
@ -226,6 +315,12 @@ Value::Equals(const PRUnichar* aString) const
return (mType == eString) && (nsCRT::strcmp(aString, mString) == 0); return (mType == eString) && (nsCRT::strcmp(aString, mString) == 0);
} }
PRBool
Value::Equals(PRInt32 aInteger) const
{
return (mType == eInteger) && (mInteger == aInteger);
}
PLHashNumber PLHashNumber
Value::Hash() const Value::Hash() const
@ -250,6 +345,10 @@ Value::Hash() const
} }
} }
break; break;
case eInteger:
temp = mInteger;
break;
} }
return temp; return temp;
@ -268,6 +367,12 @@ Value::operator const PRUnichar*() const
return (mType == eString) ? mString : 0; 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 nsresult
RootNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) RootNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure)
{ {
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("RootNode[%p]: Propogate() begin", this));
NodeSet::Iterator last = mKids.Last(); NodeSet::Iterator last = mKids.Last();
for (NodeSet::Iterator kid = mKids.First(); kid != last; ++kid) for (NodeSet::Iterator kid = mKids.First(); kid != last; ++kid)
kid->Propogate(aInstantiations, aClosure); kid->Propogate(aInstantiations, aClosure);
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("RootNode[%p]: Propogate() end", this));
return NS_OK; return NS_OK;
} }
nsresult nsresult
RootNode::Constrain(InstantiationSet& aInstantiations, void* aClosure) RootNode::Constrain(InstantiationSet& aInstantiations, void* aClosure)
{ {
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("RootNode[%p]: Constrain()", this));
return NS_OK; return NS_OK;
} }
@ -866,16 +980,26 @@ TestNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure)
{ {
nsresult rv; nsresult rv;
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Propogate() begin", this));
InstantiationSet instantiations = aInstantiations; InstantiationSet instantiations = aInstantiations;
rv = FilterInstantiations(instantiations, aClosure); rv = FilterInstantiations(instantiations, aClosure);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (! instantiations.Empty()) { if (! instantiations.Empty()) {
NodeSet::Iterator last = mKids.Last(); 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); kid->Propogate(instantiations, aClosure);
}
} }
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Propogate() end", this));
return NS_OK; return NS_OK;
} }
@ -885,18 +1009,31 @@ TestNode::Constrain(InstantiationSet& aInstantiations, void* aClosure)
{ {
nsresult rv; nsresult rv;
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() begin", this));
rv = FilterInstantiations(aInstantiations, aClosure); rv = FilterInstantiations(aInstantiations, aClosure);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (! aInstantiations.Empty()) { if (! aInstantiations.Empty()) {
// if we still have instantiations, then ride 'em on up to the // if we still have instantiations, then ride 'em on up to the
// parent to narrow them. // parent to narrow them.
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() passing to parent %p", this, mParent));
rv = mParent->Constrain(aInstantiations, aClosure); rv = mParent->Constrain(aInstantiations, aClosure);
} }
else { else {
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() failed", this));
rv = NS_OK; rv = NS_OK;
} }
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("TestNode[%p]: Constrain() end", this));
return rv; return rv;
} }

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

@ -17,10 +17,8 @@
* Copyright (C) 2000 Netscape Communications Corporation. All * Copyright (C) 2000 Netscape Communications Corporation. All
* Rights Reserved. * Rights Reserved.
* *
* Original Author(s):
* Chris Waterson <waterson@netscape.com>
*
* Contributor(s): * Contributor(s):
* Chris Waterson <waterson@netscape.com>
*/ */
/* /*
@ -51,6 +49,7 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "plhash.h" #include "plhash.h"
#include "pldhash.h"
class nsIRDFResource; class nsIRDFResource;
class nsIRDFNode; class nsIRDFNode;
@ -63,7 +62,7 @@ class nsIRDFNode;
*/ */
class Value { class Value {
public: public:
enum Type { eUndefined, eISupports, eString }; enum Type { eUndefined, eISupports, eString, eInteger };
protected: protected:
Type mType; Type mType;
@ -71,11 +70,13 @@ protected:
union { union {
nsISupports* mISupports; nsISupports* mISupports;
PRUnichar* mString; PRUnichar* mString;
PRInt32 mInteger;
}; };
PRBool Equals(const Value& aValue) const; PRBool Equals(const Value& aValue) const;
PRBool Equals(nsISupports* aISupports) const; PRBool Equals(nsISupports* aISupports) const;
PRBool Equals(const PRUnichar* aString) const; PRBool Equals(const PRUnichar* aString) const;
PRBool Equals(PRInt32 aInteger) const;
void Clear(); void Clear();
@ -86,20 +87,24 @@ public:
Value(const Value& aValue); Value(const Value& aValue);
Value(nsISupports* aISupports); Value(nsISupports* aISupports);
Value(const PRUnichar* aString); Value(const PRUnichar* aString);
Value(PRInt32 aInteger);
Value& operator=(const Value& aValue); Value& operator=(const Value& aValue);
Value& operator=(nsISupports* aISupports); Value& operator=(nsISupports* aISupports);
Value& operator=(const PRUnichar* aString); Value& operator=(const PRUnichar* aString);
Value& operator=(PRInt32 aInteger);
~Value(); ~Value();
PRBool operator==(const Value& aValue) const { return Equals(aValue); } PRBool operator==(const Value& aValue) const { return Equals(aValue); }
PRBool operator==(nsISupports* aISupports) const { return Equals(aISupports); } PRBool operator==(nsISupports* aISupports) const { return Equals(aISupports); }
PRBool operator==(const PRUnichar* aString) const { return Equals(aString); } 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!=(const Value& aValue) const { return !Equals(aValue); }
PRBool operator!=(nsISupports* aISupports) const { return !Equals(aISupports); } PRBool operator!=(nsISupports* aISupports) const { return !Equals(aISupports); }
PRBool operator!=(const PRUnichar* aString) const { return !Equals(aString); } PRBool operator!=(const PRUnichar* aString) const { return !Equals(aString); }
PRBool operator!=(PRInt32 aInteger) const { return !Equals(aInteger); }
/** /**
* Get the value's type * Get the value's type
@ -122,9 +127,35 @@ public:
*/ */
operator const PRUnichar*() const; 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; 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 class nsRuleNetwork
{ {
public: public:
nsRuleNetwork(); struct SymtabEntry {
~nsRuleNetwork(); PLDHashEntryHdr mHdr;
PRUnichar* mSymbol;
PRInt32 mVariable;
};
nsRuleNetwork() { Init(); }
~nsRuleNetwork() { Finish(); }
/** /**
* Remove all the nodes from the network. The nodes will be * Remove all the nodes from the network. The nodes will be
* destroyed * destroyed
* @return NS_OK if no errors occur * @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 * 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); } 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 * Retrieve the root node in the rule network
* @return the root node in the rule network * @return the root node in the rule network
*/ */
RootNode* GetRoot() { return &mRoot; }; 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: protected:
/**
* The root node in the network
*/
RootNode mRoot;
/**
* Other nodes in the network
*/
NodeSet mNodes; NodeSet mNodes;
void Init();
void Finish();
/**
* Symbol table, mapping symbolic names to variable identifiers
*/
PLDHashTable mSymtab;
/**
* The next available variable identifier
*/
PRInt32 mNextVariable; PRInt32 mNextVariable;
RootNode mRoot; static PLDHashTableOps gOps;
}; };

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

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

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

@ -85,6 +85,12 @@ nsIRDFService* nsXULContentUtils::gRDF;
nsINameSpaceManager* nsXULContentUtils::gNameSpaceManager; nsINameSpaceManager* nsXULContentUtils::gNameSpaceManager;
nsIDateTimeFormat* nsXULContentUtils::gFormat; 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 // Constructors n' stuff
// //
@ -99,6 +105,22 @@ nsXULContentUtils::Init()
(nsISupports**) &gRDF); (nsISupports**) &gRDF);
if (NS_FAILED(rv)) return rv; 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, rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
nsnull, nsnull,
NS_GET_IID(nsINameSpaceManager), NS_GET_IID(nsINameSpaceManager),
@ -126,6 +148,12 @@ nsXULContentUtils::Finish()
gRDF = nsnull; 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(gNameSpaceManager);
NS_IF_RELEASE(gFormat); NS_IF_RELEASE(gFormat);
} }

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

@ -18,6 +18,7 @@
* Rights Reserved. * Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* Chris Waterson <waterson@netscape.com>
*/ */
/* /*
@ -39,6 +40,7 @@ class nsIRDFNode;
class nsCString; class nsCString;
class nsString; class nsString;
class nsIRDFResource; class nsIRDFResource;
class nsIRDFLiteral;
class nsIRDFService; class nsIRDFService;
class nsINameSpaceManager; class nsINameSpaceManager;
class nsIDateTimeFormat; class nsIDateTimeFormat;
@ -112,6 +114,12 @@ public:
static nsresult static nsresult
SetCommandUpdater(nsIDocument* aDocument, nsIContent* aElement); 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
}; };

Разница между файлами не показана из-за своего большого размера Загрузить разницу