Back to index

lightning-sunbird  0.9+nobinonly
nsXULTemplateBuilder.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Robert Churchill <rjc@netscape.com>
00024  *   David Hyatt <hyatt@netscape.com>
00025  *   Chris Waterson <waterson@netscape.com>
00026  *   Pierre Phaneuf <pp@ludusdesign.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either of the GNU General Public License Version 2 or later (the "GPL"),
00030  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #ifndef nsXULTemplateBuilder_h__
00043 #define nsXULTemplateBuilder_h__
00044 
00045 #include "nsStubDocumentObserver.h"
00046 #include "nsIScriptSecurityManager.h"
00047 #include "nsIRDFCompositeDataSource.h"
00048 #include "nsIRDFContainer.h"
00049 #include "nsIRDFContainerUtils.h"
00050 #include "nsIRDFDataSource.h"
00051 #include "nsIRDFObserver.h"
00052 #include "nsIRDFService.h"
00053 #include "nsIXULTemplateBuilder.h"
00054 
00055 #include "nsConflictSet.h"
00056 #include "nsFixedSizeAllocator.h"
00057 #include "nsResourceSet.h"
00058 #include "nsRuleNetwork.h"
00059 #include "nsVoidArray.h"
00060 #include "nsCOMArray.h"
00061 
00062 #include "prlog.h"
00063 #ifdef PR_LOGGING
00064 extern PRLogModuleInfo* gXULTemplateLog;
00065 #endif
00066 
00067 class nsClusterKeySet;
00068 class nsTemplateMatch;
00069 class nsTemplateRule;
00070 class nsIXULDocument;
00071 class nsIRDFCompositeDataSource;
00072 
00077 class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
00078                              public nsStubDocumentObserver,
00079                              public nsIRDFObserver
00080 {
00081 public:
00082     nsXULTemplateBuilder();
00083     virtual ~nsXULTemplateBuilder();
00084 
00085     nsresult Init();
00086 
00087     // nsISupports interface
00088     NS_DECL_ISUPPORTS
00089 
00090     // nsIXULTemplateBuilder interface
00091     NS_DECL_NSIXULTEMPLATEBUILDER
00092    
00093     // nsIDocumentObserver
00094     virtual void AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
00095                                   PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00096                                   PRInt32 aModType);
00097     virtual void DocumentWillBeDestroyed(nsIDocument *aDocument);
00098 
00099     // nsIRDFObserver interface
00100     NS_DECL_NSIRDFOBSERVER
00101 
00102     nsresult
00103     ComputeContainmentProperties();
00104 
00105     static PRBool
00106     IsTemplateElement(nsIContent* aContent);
00107 
00111     virtual nsresult
00112     InitializeRuleNetwork();
00113 
00118     virtual nsresult
00119     InitializeRuleNetworkForSimpleRules(InnerNode** aChildNode) = 0;
00120 
00121     virtual nsresult
00122     RebuildAll() = 0; // must be implemented by subclasses
00123 
00127     nsresult
00128     GetTemplateRoot(nsIContent** aResult);
00129 
00133     nsresult
00134     CompileRules();
00135 
00140     nsresult
00141     CompileExtendedRule(nsIContent* aRuleElement,
00142                         PRInt32 aPriority,
00143                         InnerNode* aParentNode);
00144 
00149     nsresult
00150     CompileConditions(nsTemplateRule* aRule,
00151                       nsIContent* aConditions,
00152                       InnerNode* aParentNode,
00153                       InnerNode** aLastNode);
00154 
00160     virtual nsresult
00161     CompileCondition(nsIAtom* aTag,
00162                      nsTemplateRule* aRule,
00163                      nsIContent* aConditions,
00164                      InnerNode* aParentNode,
00165                      TestNode** aResult);
00166 
00170     nsresult
00171     CompileTripleCondition(nsTemplateRule* aRule,
00172                            nsIContent* aCondition,
00173                            InnerNode* aParentNode,
00174                            TestNode** aResult);
00175 
00179     nsresult
00180     CompileMemberCondition(nsTemplateRule* aRule,
00181                            nsIContent* aCondition,
00182                            InnerNode* aParentNode,
00183                            TestNode** aResult);
00184 
00185 
00189     nsresult
00190     CompileBindings(nsTemplateRule* aRule, nsIContent* aBindings);
00191 
00195     nsresult
00196     CompileBinding(nsTemplateRule* aRule, nsIContent* aBinding);
00197 
00202     nsresult
00203     CompileSimpleRule(nsIContent* aRuleElement, PRInt32 aPriorty, InnerNode* aParentNode);
00204 
00210     virtual PRBool
00211     CompileSimpleAttributeCondition(PRInt32 aNameSpaceID,
00212                                     nsIAtom* aAttribute,
00213                                     const nsAString& aValue,
00214                                     InnerNode* aParentNode,
00215                                     TestNode** aResult);
00216 
00221     nsresult ParseLiteral(const nsString& aParseType, 
00222                           const nsString& aValue,
00223                           nsIRDFNode** aResult);
00224     
00228     nsresult
00229     AddSimpleRuleBindings(nsTemplateRule* aRule, nsIContent* aElement);
00230 
00231     static void
00232     AddBindingsFor(nsXULTemplateBuilder* aSelf,
00233                    const nsAString& aVariable,
00234                    void* aClosure);
00235 
00236     // XXX sigh, the string template foo doesn't mix with
00237     // operator->*() on egcs-1.1.2, so we'll need to explicitly pass
00238     // "this" and use good ol' fashioned static callbacks.
00239     void
00240     ParseAttribute(const nsAString& aAttributeValue,
00241                    void (*aVariableCallback)(nsXULTemplateBuilder* aThis, const nsAString&, void*),
00242                    void (*aTextCallback)(nsXULTemplateBuilder* aThis, const nsAString&, void*),
00243                    void* aClosure);
00244 
00245     nsresult
00246     LoadDataSources(nsIDocument* aDoc);
00247 
00248     nsresult
00249     InitHTMLTemplateRoot();
00250 
00251     nsresult
00252     SubstituteText(nsTemplateMatch& aMatch,
00253                    const nsAString& aAttributeValue,
00254                    nsAString& aResult);
00255 
00256     static void
00257     SubstituteTextAppendText(nsXULTemplateBuilder* aThis, const nsAString& aText, void* aClosure);
00258 
00259     static void
00260     SubstituteTextReplaceVariable(nsXULTemplateBuilder* aThis, const nsAString& aVariable, void* aClosure);    
00261 
00262     PRBool
00263     IsAttrImpactedByVars(nsTemplateMatch& aMatch,
00264                          const nsAString& aAttributeValue,
00265                          const VariableSet& aModifiedVars);
00266 
00267     static void
00268     IsVarInSet(nsXULTemplateBuilder* aThis, const nsAString& aVariable, void* aClosure);
00269 
00270     nsresult
00271     SynchronizeAll(nsIRDFResource* aSource,
00272                    nsIRDFResource* aProperty,
00273                    nsIRDFNode* aOldTarget,
00274                    nsIRDFNode* aNewTarget);
00275 
00276     nsresult
00277     Propagate(nsIRDFResource* aSource,
00278               nsIRDFResource* aProperty,
00279               nsIRDFNode* aTarget,
00280               nsClusterKeySet& aNewKeys);
00281 
00282     nsresult
00283     FireNewlyMatchedRules(const nsClusterKeySet& aNewKeys);
00284 
00285     nsresult
00286     Retract(nsIRDFResource* aSource,
00287             nsIRDFResource* aProperty,
00288             nsIRDFNode* aTarget);
00289 
00290     nsresult
00291     CheckContainer(nsIRDFResource* aTargetResource, PRBool* aIsContainer, PRBool* aIsEmpty);
00292 
00293     nsresult 
00294     IsSystemPrincipal(nsIPrincipal *principal, PRBool *result);
00295 
00296 #ifdef PR_LOGGING
00297     nsresult
00298     Log(const char* aOperation,
00299         nsIRDFResource* aSource,
00300         nsIRDFResource* aProperty,
00301         nsIRDFNode* aTarget);
00302 
00303 #define LOG(_op, _src, _prop, _targ) \
00304     Log(_op, _src, _prop, _targ)
00305 
00306 #else
00307 #define LOG(_op, _src, _prop, _targ)
00308 #endif
00309 
00310 protected:
00311     // We are an observer of the composite datasource. The cycle is
00312     // broken when the document is destroyed.
00313     nsCOMPtr<nsIRDFDataSource> mDB;
00314     nsCOMPtr<nsIRDFCompositeDataSource> mCompDB;
00315 
00316     // Circular reference, broken when the document is destroyed.
00317     nsCOMPtr<nsIContent> mRoot;
00318 
00319     nsCOMPtr<nsIRDFDataSource> mCache;
00320 
00321     nsCOMArray<nsIXULBuilderListener> mListeners;
00322 
00323     PRInt32     mUpdateBatchNest;
00324 
00325     // For the rule network
00326     nsResourceSet mContainmentProperties;
00327     PRBool        mRulesCompiled;
00328 
00329 public:
00330     nsRuleNetwork    mRules;
00331     PRInt32          mContainerVar;
00332     nsString         mContainerSymbol;
00333     PRInt32          mMemberVar;
00334     nsString         mMemberSymbol;
00335     nsConflictSet    mConflictSet;
00336     ReteNodeSet      mRDFTests;
00337 
00338 protected:
00339     // pseudo-constants
00340     static nsrefcnt gRefCnt;
00341     static nsIRDFService*            gRDFService;
00342     static nsIRDFContainerUtils*     gRDFContainerUtils;
00343     static nsIScriptSecurityManager* gScriptSecurityManager;
00344     static nsIPrincipal*             gSystemPrincipal;
00345 
00346     enum {
00347         eDontTestEmpty = (1 << 0)
00348     };
00349 
00350     PRInt32 mFlags;
00351 
00357     class ActivationEntry {
00358     public:
00359         nsIRDFResource   *mResource;
00360         ActivationEntry  *mPrevious;
00361         ActivationEntry **mLink;
00362 
00363         ActivationEntry(nsIRDFResource *aResource, ActivationEntry **aLink)
00364             : mResource(aResource),
00365               mPrevious(*aLink),
00366               mLink(aLink) { *mLink = this; }
00367 
00368         ~ActivationEntry() { *mLink = mPrevious; }
00369     };
00370 
00375     ActivationEntry *mTop;
00376 
00380     PRBool
00381     IsActivated(nsIRDFResource *aResource);
00382 
00387     virtual nsresult
00388     ReplaceMatch(nsIRDFResource* aMember, const nsTemplateMatch* aOldMatch, nsTemplateMatch* aNewMatch) = 0;
00389 
00398     virtual nsresult
00399     SynchronizeMatch(nsTemplateMatch* aMatch, const VariableSet& aModifiedVars) = 0;
00400 };
00401 
00402 #endif // nsXULTemplateBuilder_h__