1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is Mozilla Communicator client code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
23
* Robert Churchill <rjc@netscape.com>
24
* David Hyatt <hyatt@netscape.com>
25
* Chris Waterson <waterson@netscape.com>
26
* Pierre Phaneuf <pp@ludusdesign.com>
27
* Jan Varga <jan@mozdevgroup.com>
29
* Alternatively, the contents of this file may be used under the terms of
30
* either the GNU General Public License Version 2 or later (the "GPL"), or
31
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32
* in which case the provisions of the GPL or the LGPL are applicable instead
33
* of those above. If you wish to allow use of your version of this file only
34
* under the terms of either the GPL or the LGPL, and not to allow others to
35
* use your version of this file under the terms of the NPL, indicate your
36
* decision by deleting the provisions above and replace them with the notice
37
* and other provisions required by the GPL or the LGPL. If you do not delete
38
* the provisions above, a recipient may use your version of this file under
39
* the terms of any one of the NPL, the GPL or the LGPL.
41
* ***** END LICENSE BLOCK ***** */
43
#ifndef nsXULTemplateBuilder_h__
44
#define nsXULTemplateBuilder_h__
46
#include "nsStubDocumentObserver.h"
47
#include "nsIScriptSecurityManager.h"
48
#include "nsISecurityCheckedComponent.h"
49
#include "nsIRDFCompositeDataSource.h"
50
#include "nsIRDFContainer.h"
51
#include "nsIRDFContainerUtils.h"
52
#include "nsIRDFDataSource.h"
53
#include "nsIRDFObserver.h"
54
#include "nsIRDFService.h"
55
#include "nsIXULTemplateBuilder.h"
57
#include "nsConflictSet.h"
58
#include "nsFixedSizeAllocator.h"
59
#include "nsResourceSet.h"
60
#include "nsRuleNetwork.h"
61
#include "nsVoidArray.h"
62
#include "nsCOMArray.h"
66
extern PRLogModuleInfo* gXULTemplateLog;
69
class nsClusterKeySet;
70
class nsTemplateMatch;
73
class nsIRDFCompositeDataSource;
76
* An object that translates an RDF graph into a presentation using a
79
class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
80
public nsISecurityCheckedComponent,
81
public nsStubDocumentObserver,
85
nsXULTemplateBuilder();
86
virtual ~nsXULTemplateBuilder();
90
// nsISupports interface
93
// nsIXULTemplateBuilder interface
94
NS_DECL_NSIXULTEMPLATEBUILDER
96
// nsISecurityCheckedComponent
97
NS_DECL_NSISECURITYCHECKEDCOMPONENT
99
// nsIDocumentObserver
100
virtual void AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
101
PRInt32 aNameSpaceID, nsIAtom* aAttribute,
103
virtual void DocumentWillBeDestroyed(nsIDocument *aDocument);
105
// nsIRDFObserver interface
106
NS_DECL_NSIRDFOBSERVER
109
ComputeContainmentProperties();
112
IsTemplateElement(nsIContent* aContent);
115
* Initialize the rule network.
118
InitializeRuleNetwork();
121
* Initialize the rule network for handling rules that use the
125
InitializeRuleNetworkForSimpleRules(InnerNode** aChildNode) = 0;
128
RebuildAll() = 0; // must be implemented by subclasses
131
* Find the <template> tag that applies for this builder
134
GetTemplateRoot(nsIContent** aResult);
137
* Compile the template's rules
143
* Compile a rule that's specified using the extended template
147
CompileExtendedRule(nsIContent* aRuleElement,
149
InnerNode* aParentNode);
152
* Compile the <conditions> of a rule that uses the extended
156
CompileConditions(nsTemplateRule* aRule,
157
nsIContent* aConditions,
158
InnerNode* aParentNode,
159
InnerNode** aLastNode);
162
* Compile a single condition from an extended template syntax
163
* rule. Subclasses may override to provide additional,
164
* subclass-specific condition processing.
167
CompileCondition(nsIAtom* aTag,
168
nsTemplateRule* aRule,
169
nsIContent* aConditions,
170
InnerNode* aParentNode,
174
* Compile a <triple> condition
177
CompileTripleCondition(nsTemplateRule* aRule,
178
nsIContent* aCondition,
179
InnerNode* aParentNode,
183
* Compile a <member> condition
186
CompileMemberCondition(nsTemplateRule* aRule,
187
nsIContent* aCondition,
188
InnerNode* aParentNode,
192
* Compile a <where> condition
195
CompileWhereCondition(nsTemplateRule* aRule,
196
nsIContent* aCondition,
197
InnerNode* aParentNode,
201
* Compile the <bindings> for an extended template syntax rule.
204
CompileBindings(nsTemplateRule* aRule, nsIContent* aBindings);
207
* Compile a single binding for an extended template syntax rule.
210
CompileBinding(nsTemplateRule* aRule, nsIContent* aBinding);
213
* Compile a rule that's specified using the simple template
217
CompileSimpleRule(nsIContent* aRuleElement, PRInt32 aPriorty, InnerNode* aParentNode);
220
* Can be overridden by subclasses to handle special attribute conditions
221
* for the simple syntax.
222
* @return PR_TRUE if the condition was handled
225
CompileSimpleAttributeCondition(PRInt32 aNameSpaceID,
227
const nsAString& aValue,
228
InnerNode* aParentNode,
231
* Add automatic bindings for simple rules
234
AddSimpleRuleBindings(nsTemplateRule* aRule, nsIContent* aElement);
237
AddBindingsFor(nsXULTemplateBuilder* aSelf,
238
const nsAString& aVariable,
241
// XXX sigh, the string template foo doesn't mix with
242
// operator->*() on egcs-1.1.2, so we'll need to explicitly pass
243
// "this" and use good ol' fashioned static callbacks.
245
ParseAttribute(const nsAString& aAttributeValue,
246
void (*aVariableCallback)(nsXULTemplateBuilder* aThis, const nsAString&, void*),
247
void (*aTextCallback)(nsXULTemplateBuilder* aThis, const nsAString&, void*),
251
LoadDataSources(nsIDocument* aDoc);
254
InitHTMLTemplateRoot();
257
SubstituteText(nsTemplateMatch& aMatch,
258
const nsAString& aAttributeValue,
262
SubstituteTextAppendText(nsXULTemplateBuilder* aThis, const nsAString& aText, void* aClosure);
265
SubstituteTextReplaceVariable(nsXULTemplateBuilder* aThis, const nsAString& aVariable, void* aClosure);
268
IsAttrImpactedByVars(nsTemplateMatch& aMatch,
269
const nsAString& aAttributeValue,
270
const VariableSet& aModifiedVars);
273
IsVarInSet(nsXULTemplateBuilder* aThis, const nsAString& aVariable, void* aClosure);
276
SynchronizeAll(nsIRDFResource* aSource,
277
nsIRDFResource* aProperty,
278
nsIRDFNode* aOldTarget,
279
nsIRDFNode* aNewTarget);
282
Propagate(nsIRDFResource* aSource,
283
nsIRDFResource* aProperty,
285
nsClusterKeySet& aNewKeys);
288
FireNewlyMatchedRules(const nsClusterKeySet& aNewKeys);
291
Retract(nsIRDFResource* aSource,
292
nsIRDFResource* aProperty,
293
nsIRDFNode* aTarget);
296
CheckContainer(nsIRDFResource* aTargetResource, PRBool* aIsContainer, PRBool* aIsEmpty);
299
IsSystemPrincipal(nsIPrincipal *principal, PRBool *result);
303
Log(const char* aOperation,
304
nsIRDFResource* aSource,
305
nsIRDFResource* aProperty,
306
nsIRDFNode* aTarget);
308
#define LOG(_op, _src, _prop, _targ) \
309
Log(_op, _src, _prop, _targ)
312
#define LOG(_op, _src, _prop, _targ)
316
// We are an observer of the composite datasource. The cycle is
317
// broken when the document is destroyed.
318
nsCOMPtr<nsIRDFDataSource> mDB;
319
nsCOMPtr<nsIRDFCompositeDataSource> mCompDB;
321
// Circular reference, broken when the document is destroyed.
322
nsCOMPtr<nsIContent> mRoot;
324
nsCOMPtr<nsIRDFDataSource> mCache;
326
nsCOMArray<nsIXULBuilderListener> mListeners;
328
PRInt32 mUpdateBatchNest;
330
// For the rule network
331
nsResourceSet mContainmentProperties;
332
PRBool mRulesCompiled;
335
nsRuleNetwork mRules;
336
PRInt32 mContainerVar;
337
nsString mContainerSymbol;
339
nsString mMemberSymbol;
340
nsConflictSet mConflictSet;
341
ReteNodeSet mRDFTests;
345
static nsrefcnt gRefCnt;
346
static nsIRDFService* gRDFService;
347
static nsIRDFContainerUtils* gRDFContainerUtils;
348
static nsIScriptSecurityManager* gScriptSecurityManager;
349
static nsIPrincipal* gSystemPrincipal;
352
eDontTestEmpty = (1 << 0),
353
eSortContainersFirst = (1 << 1),
354
eCaseSensitiveSorting = (1 << 2),
355
eTwoStateSorting = (1 << 3)
361
* Stack-based helper class to maintain a list of ``activated''
362
* resources; i.e., resources for which we are currently building
365
class ActivationEntry {
367
nsIRDFResource *mResource;
368
ActivationEntry *mPrevious;
369
ActivationEntry **mLink;
371
ActivationEntry(nsIRDFResource *aResource, ActivationEntry **aLink)
372
: mResource(aResource),
374
mLink(aLink) { *mLink = this; }
376
~ActivationEntry() { *mLink = mPrevious; }
380
* The top of the stack of resources that we're currently building
383
ActivationEntry *mTop;
386
* Determine if a resource is currently on the activation stack.
389
IsActivated(nsIRDFResource *aResource);
392
* Must be implemented by subclasses. Handle replacing aOldMatch
393
* with aNewMatch. Either aOldMatch or aNewMatch may be null.
396
ReplaceMatch(nsIRDFResource* aMember, const nsTemplateMatch* aOldMatch, nsTemplateMatch* aNewMatch) = 0;
399
* Must be implemented by subclasses. Handle change in bound
400
* variable values for aMatch. aModifiedVars contains the set
401
* of variables that have changed.
402
* @param aMatch the match for which variable bindings has changed.
403
* @param aModifiedVars the set of variables for which the bindings
407
SynchronizeMatch(nsTemplateMatch* aMatch, const VariableSet& aModifiedVars) = 0;
410
#endif // nsXULTemplateBuilder_h__