michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsXULTemplateBuilder_h__ michael@0: #define nsXULTemplateBuilder_h__ michael@0: michael@0: #include "nsStubDocumentObserver.h" michael@0: #include "nsIScriptSecurityManager.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsIRDFCompositeDataSource.h" michael@0: #include "nsIRDFContainer.h" michael@0: #include "nsIRDFContainerUtils.h" michael@0: #include "nsIRDFDataSource.h" michael@0: #include "nsIRDFObserver.h" michael@0: #include "nsIRDFService.h" michael@0: #include "nsIXULTemplateBuilder.h" michael@0: michael@0: #include "nsCOMArray.h" michael@0: #include "nsTArray.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsTemplateRule.h" michael@0: #include "nsTemplateMatch.h" michael@0: #include "nsIXULTemplateQueryProcessor.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: michael@0: #include "prlog.h" michael@0: #ifdef PR_LOGGING michael@0: extern PRLogModuleInfo* gXULTemplateLog; michael@0: #endif michael@0: michael@0: class nsIContent; michael@0: class nsIObserverService; michael@0: class nsIRDFCompositeDataSource; michael@0: class nsIXULDocument; michael@0: michael@0: /** michael@0: * An object that translates an RDF graph into a presentation using a michael@0: * set of rules. michael@0: */ michael@0: class nsXULTemplateBuilder : public nsIXULTemplateBuilder, michael@0: public nsIObserver, michael@0: public nsStubDocumentObserver michael@0: { michael@0: void CleanUp(bool aIsFinal); michael@0: michael@0: public: michael@0: nsXULTemplateBuilder(); michael@0: virtual ~nsXULTemplateBuilder(); michael@0: michael@0: nsresult InitGlobals(); michael@0: michael@0: /** michael@0: * Clear the template builder structures. The aIsFinal flag is set to true michael@0: * when the template is going away. michael@0: */ michael@0: virtual void Uninit(bool aIsFinal); michael@0: michael@0: // nsISupports interface michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULTemplateBuilder, michael@0: nsIXULTemplateBuilder) michael@0: michael@0: // nsIXULTemplateBuilder interface michael@0: NS_DECL_NSIXULTEMPLATEBUILDER michael@0: michael@0: // nsIObserver Interface michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: // nsIMutationObserver michael@0: NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED michael@0: NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED michael@0: NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED michael@0: michael@0: /** michael@0: * Remove an old result and/or add a new result. This method will retrieve michael@0: * the set of containers where the result could be inserted and either add michael@0: * the new result to those containers, or remove the result from those michael@0: * containers. UpdateResultInContainer is called for each container. michael@0: * michael@0: * @param aOldResult result to remove michael@0: * @param aNewResult result to add michael@0: * @param aQueryNode query node for new result michael@0: */ michael@0: nsresult michael@0: UpdateResult(nsIXULTemplateResult* aOldResult, michael@0: nsIXULTemplateResult* aNewResult, michael@0: nsIDOMNode* aQueryNode); michael@0: michael@0: /** michael@0: * Remove an old result and/or add a new result from a specific container. michael@0: * michael@0: * @param aOldResult result to remove michael@0: * @param aNewResult result to add michael@0: * @param aQueryNode queryset for the new result michael@0: * @param aOldId id of old result michael@0: * @param aNewId id of new result michael@0: * @param aInsertionPoint container to remove or add result inside michael@0: */ michael@0: nsresult michael@0: UpdateResultInContainer(nsIXULTemplateResult* aOldResult, michael@0: nsIXULTemplateResult* aNewResult, michael@0: nsTemplateQuerySet* aQuerySet, michael@0: nsIRDFResource* aOldId, michael@0: nsIRDFResource* aNewId, michael@0: nsIContent* aInsertionPoint); michael@0: michael@0: nsresult michael@0: ComputeContainmentProperties(); michael@0: michael@0: static bool michael@0: IsTemplateElement(nsIContent* aContent); michael@0: michael@0: virtual nsresult michael@0: RebuildAll() = 0; // must be implemented by subclasses michael@0: michael@0: void RunnableRebuild() { Rebuild(); } michael@0: void RunnableLoadAndRebuild() { michael@0: Uninit(false); // Reset results michael@0: michael@0: nsCOMPtr doc = mRoot ? mRoot->GetDocument() : nullptr; michael@0: if (doc) { michael@0: bool shouldDelay; michael@0: LoadDataSources(doc, &shouldDelay); michael@0: if (!shouldDelay) { michael@0: Rebuild(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: // mRoot should not be cleared until after Uninit is finished so that michael@0: // generated content can be removed during uninitialization. michael@0: void UninitFalse() { Uninit(false); mRoot = nullptr; } michael@0: void UninitTrue() { Uninit(true); mRoot = nullptr; } michael@0: michael@0: /** michael@0: * Find the