~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/content/xul/templates/src/nsXULTemplateBuilder.h

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
4
 *
 
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/
 
9
 *
 
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
 
13
 * License.
 
14
 *
 
15
 * The Original Code is Mozilla Communicator client code.
 
16
 *
 
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.
 
21
 *
 
22
 * Contributor(s):
 
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>
 
28
 *
 
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.
 
40
 *
 
41
 * ***** END LICENSE BLOCK ***** */
 
42
 
 
43
#ifndef nsXULTemplateBuilder_h__
 
44
#define nsXULTemplateBuilder_h__
 
45
 
 
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"
 
56
 
 
57
#include "nsConflictSet.h"
 
58
#include "nsFixedSizeAllocator.h"
 
59
#include "nsResourceSet.h"
 
60
#include "nsRuleNetwork.h"
 
61
#include "nsVoidArray.h"
 
62
#include "nsCOMArray.h"
 
63
 
 
64
#include "prlog.h"
 
65
#ifdef PR_LOGGING
 
66
extern PRLogModuleInfo* gXULTemplateLog;
 
67
#endif
 
68
 
 
69
class nsClusterKeySet;
 
70
class nsTemplateMatch;
 
71
class nsTemplateRule;
 
72
class nsIXULDocument;
 
73
class nsIRDFCompositeDataSource;
 
74
 
 
75
/**
 
76
 * An object that translates an RDF graph into a presentation using a
 
77
 * set of rules.
 
78
 */
 
79
class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
 
80
                             public nsISecurityCheckedComponent,
 
81
                             public nsStubDocumentObserver,
 
82
                             public nsIRDFObserver
 
83
{
 
84
public:
 
85
    nsXULTemplateBuilder();
 
86
    virtual ~nsXULTemplateBuilder();
 
87
 
 
88
    nsresult Init();
 
89
 
 
90
    // nsISupports interface
 
91
    NS_DECL_ISUPPORTS
 
92
 
 
93
    // nsIXULTemplateBuilder interface
 
94
    NS_DECL_NSIXULTEMPLATEBUILDER
 
95
   
 
96
    // nsISecurityCheckedComponent
 
97
    NS_DECL_NSISECURITYCHECKEDCOMPONENT
 
98
 
 
99
    // nsIDocumentObserver
 
100
    virtual void AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
 
101
                                  PRInt32 aNameSpaceID, nsIAtom* aAttribute,
 
102
                                  PRInt32 aModType);
 
103
    virtual void DocumentWillBeDestroyed(nsIDocument *aDocument);
 
104
 
 
105
    // nsIRDFObserver interface
 
106
    NS_DECL_NSIRDFOBSERVER
 
107
 
 
108
    nsresult
 
109
    ComputeContainmentProperties();
 
110
 
 
111
    static PRBool
 
112
    IsTemplateElement(nsIContent* aContent);
 
113
 
 
114
    /**
 
115
     * Initialize the rule network.
 
116
     */
 
117
    virtual nsresult
 
118
    InitializeRuleNetwork();
 
119
 
 
120
    /**
 
121
     * Initialize the rule network for handling rules that use the
 
122
     * ``simple'' syntax.
 
123
     */
 
124
    virtual nsresult
 
125
    InitializeRuleNetworkForSimpleRules(InnerNode** aChildNode) = 0;
 
126
 
 
127
    virtual nsresult
 
128
    RebuildAll() = 0; // must be implemented by subclasses
 
129
 
 
130
    /**
 
131
     * Find the <template> tag that applies for this builder
 
132
     */
 
133
    nsresult
 
134
    GetTemplateRoot(nsIContent** aResult);
 
135
 
 
136
    /**
 
137
     * Compile the template's rules
 
138
     */
 
139
    nsresult
 
140
    CompileRules();
 
141
 
 
142
    /**
 
143
     * Compile a rule that's specified using the extended template
 
144
     * syntax.
 
145
     */
 
146
    nsresult
 
147
    CompileExtendedRule(nsIContent* aRuleElement,
 
148
                        PRInt32 aPriority,
 
149
                        InnerNode* aParentNode);
 
150
 
 
151
    /**
 
152
     * Compile the <conditions> of a rule that uses the extended
 
153
     * template syntax.
 
154
     */
 
155
    nsresult
 
156
    CompileConditions(nsTemplateRule* aRule,
 
157
                      nsIContent* aConditions,
 
158
                      InnerNode* aParentNode,
 
159
                      InnerNode** aLastNode);
 
160
 
 
161
    /**
 
162
     * Compile a single condition from an extended template syntax
 
163
     * rule. Subclasses may override to provide additional,
 
164
     * subclass-specific condition processing.
 
165
     */
 
166
    virtual nsresult
 
167
    CompileCondition(nsIAtom* aTag,
 
168
                     nsTemplateRule* aRule,
 
169
                     nsIContent* aConditions,
 
170
                     InnerNode* aParentNode,
 
171
                     TestNode** aResult);
 
172
 
 
173
    /**
 
174
     * Compile a <triple> condition
 
175
     */
 
176
    nsresult
 
177
    CompileTripleCondition(nsTemplateRule* aRule,
 
178
                           nsIContent* aCondition,
 
179
                           InnerNode* aParentNode,
 
180
                           TestNode** aResult);
 
181
 
 
182
    /**
 
183
     * Compile a <member> condition
 
184
     */
 
185
    nsresult
 
186
    CompileMemberCondition(nsTemplateRule* aRule,
 
187
                           nsIContent* aCondition,
 
188
                           InnerNode* aParentNode,
 
189
                           TestNode** aResult);
 
190
 
 
191
    /**
 
192
     * Compile a <where> condition
 
193
     */
 
194
    nsresult
 
195
    CompileWhereCondition(nsTemplateRule* aRule,
 
196
                          nsIContent* aCondition,
 
197
                          InnerNode* aParentNode,
 
198
                          TestNode** aResult);
 
199
 
 
200
    /**
 
201
     * Compile the <bindings> for an extended template syntax rule.
 
202
     */
 
203
    nsresult
 
204
    CompileBindings(nsTemplateRule* aRule, nsIContent* aBindings);
 
205
 
 
206
    /**
 
207
     * Compile a single binding for an extended template syntax rule.
 
208
     */
 
209
    nsresult
 
210
    CompileBinding(nsTemplateRule* aRule, nsIContent* aBinding);
 
211
 
 
212
    /**
 
213
     * Compile a rule that's specified using the simple template
 
214
     * syntax.
 
215
     */
 
216
    nsresult
 
217
    CompileSimpleRule(nsIContent* aRuleElement, PRInt32 aPriorty, InnerNode* aParentNode);
 
218
 
 
219
    /**
 
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
 
223
     */
 
224
    virtual PRBool
 
225
    CompileSimpleAttributeCondition(PRInt32 aNameSpaceID,
 
226
                                    nsIAtom* aAttribute,
 
227
                                    const nsAString& aValue,
 
228
                                    InnerNode* aParentNode,
 
229
                                    TestNode** aResult);
 
230
    /**
 
231
     * Add automatic bindings for simple rules
 
232
     */
 
233
    nsresult
 
234
    AddSimpleRuleBindings(nsTemplateRule* aRule, nsIContent* aElement);
 
235
 
 
236
    static void
 
237
    AddBindingsFor(nsXULTemplateBuilder* aSelf,
 
238
                   const nsAString& aVariable,
 
239
                   void* aClosure);
 
240
 
 
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.
 
244
    void
 
245
    ParseAttribute(const nsAString& aAttributeValue,
 
246
                   void (*aVariableCallback)(nsXULTemplateBuilder* aThis, const nsAString&, void*),
 
247
                   void (*aTextCallback)(nsXULTemplateBuilder* aThis, const nsAString&, void*),
 
248
                   void* aClosure);
 
249
 
 
250
    nsresult
 
251
    LoadDataSources(nsIDocument* aDoc);
 
252
 
 
253
    nsresult
 
254
    InitHTMLTemplateRoot();
 
255
 
 
256
    nsresult
 
257
    SubstituteText(nsTemplateMatch& aMatch,
 
258
                   const nsAString& aAttributeValue,
 
259
                   nsAString& aResult);
 
260
 
 
261
    static void
 
262
    SubstituteTextAppendText(nsXULTemplateBuilder* aThis, const nsAString& aText, void* aClosure);
 
263
 
 
264
    static void
 
265
    SubstituteTextReplaceVariable(nsXULTemplateBuilder* aThis, const nsAString& aVariable, void* aClosure);    
 
266
 
 
267
    PRBool
 
268
    IsAttrImpactedByVars(nsTemplateMatch& aMatch,
 
269
                         const nsAString& aAttributeValue,
 
270
                         const VariableSet& aModifiedVars);
 
271
 
 
272
    static void
 
273
    IsVarInSet(nsXULTemplateBuilder* aThis, const nsAString& aVariable, void* aClosure);
 
274
 
 
275
    nsresult
 
276
    SynchronizeAll(nsIRDFResource* aSource,
 
277
                   nsIRDFResource* aProperty,
 
278
                   nsIRDFNode* aOldTarget,
 
279
                   nsIRDFNode* aNewTarget);
 
280
 
 
281
    nsresult
 
282
    Propagate(nsIRDFResource* aSource,
 
283
              nsIRDFResource* aProperty,
 
284
              nsIRDFNode* aTarget,
 
285
              nsClusterKeySet& aNewKeys);
 
286
 
 
287
    nsresult
 
288
    FireNewlyMatchedRules(const nsClusterKeySet& aNewKeys);
 
289
 
 
290
    nsresult
 
291
    Retract(nsIRDFResource* aSource,
 
292
            nsIRDFResource* aProperty,
 
293
            nsIRDFNode* aTarget);
 
294
 
 
295
    nsresult
 
296
    CheckContainer(nsIRDFResource* aTargetResource, PRBool* aIsContainer, PRBool* aIsEmpty);
 
297
 
 
298
    nsresult 
 
299
    IsSystemPrincipal(nsIPrincipal *principal, PRBool *result);
 
300
 
 
301
#ifdef PR_LOGGING
 
302
    nsresult
 
303
    Log(const char* aOperation,
 
304
        nsIRDFResource* aSource,
 
305
        nsIRDFResource* aProperty,
 
306
        nsIRDFNode* aTarget);
 
307
 
 
308
#define LOG(_op, _src, _prop, _targ) \
 
309
    Log(_op, _src, _prop, _targ)
 
310
 
 
311
#else
 
312
#define LOG(_op, _src, _prop, _targ)
 
313
#endif
 
314
 
 
315
protected:
 
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;
 
320
 
 
321
    // Circular reference, broken when the document is destroyed.
 
322
    nsCOMPtr<nsIContent> mRoot;
 
323
 
 
324
    nsCOMPtr<nsIRDFDataSource> mCache;
 
325
 
 
326
    nsCOMArray<nsIXULBuilderListener> mListeners;
 
327
 
 
328
    PRInt32     mUpdateBatchNest;
 
329
 
 
330
    // For the rule network
 
331
    nsResourceSet mContainmentProperties;
 
332
    PRBool        mRulesCompiled;
 
333
 
 
334
public:
 
335
    nsRuleNetwork    mRules;
 
336
    PRInt32          mContainerVar;
 
337
    nsString         mContainerSymbol;
 
338
    PRInt32          mMemberVar;
 
339
    nsString         mMemberSymbol;
 
340
    nsConflictSet    mConflictSet;
 
341
    ReteNodeSet      mRDFTests;
 
342
 
 
343
protected:
 
344
    // pseudo-constants
 
345
    static nsrefcnt gRefCnt;
 
346
    static nsIRDFService*            gRDFService;
 
347
    static nsIRDFContainerUtils*     gRDFContainerUtils;
 
348
    static nsIScriptSecurityManager* gScriptSecurityManager;
 
349
    static nsIPrincipal*             gSystemPrincipal;
 
350
 
 
351
    enum {
 
352
        eDontTestEmpty = (1 << 0),
 
353
        eSortContainersFirst = (1 << 1),
 
354
        eCaseSensitiveSorting = (1 << 2),
 
355
        eTwoStateSorting = (1 << 3)
 
356
    };
 
357
 
 
358
    PRInt32 mFlags;
 
359
 
 
360
    /**
 
361
     * Stack-based helper class to maintain a list of ``activated''
 
362
     * resources; i.e., resources for which we are currently building
 
363
     * content.
 
364
     */
 
365
    class ActivationEntry {
 
366
    public:
 
367
        nsIRDFResource   *mResource;
 
368
        ActivationEntry  *mPrevious;
 
369
        ActivationEntry **mLink;
 
370
 
 
371
        ActivationEntry(nsIRDFResource *aResource, ActivationEntry **aLink)
 
372
            : mResource(aResource),
 
373
              mPrevious(*aLink),
 
374
              mLink(aLink) { *mLink = this; }
 
375
 
 
376
        ~ActivationEntry() { *mLink = mPrevious; }
 
377
    };
 
378
 
 
379
    /**
 
380
     * The top of the stack of resources that we're currently building
 
381
     * content for.
 
382
     */
 
383
    ActivationEntry *mTop;
 
384
 
 
385
    /**
 
386
     * Determine if a resource is currently on the activation stack.
 
387
     */
 
388
    PRBool
 
389
    IsActivated(nsIRDFResource *aResource);
 
390
 
 
391
    /**
 
392
     * Must be implemented by subclasses. Handle replacing aOldMatch
 
393
     * with aNewMatch. Either aOldMatch or aNewMatch may be null.
 
394
     */
 
395
    virtual nsresult
 
396
    ReplaceMatch(nsIRDFResource* aMember, const nsTemplateMatch* aOldMatch, nsTemplateMatch* aNewMatch) = 0;
 
397
 
 
398
    /**
 
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
 
404
     * have changed.
 
405
     */
 
406
    virtual nsresult
 
407
    SynchronizeMatch(nsTemplateMatch* aMatch, const VariableSet& aModifiedVars) = 0;
 
408
};
 
409
 
 
410
#endif // nsXULTemplateBuilder_h__