diff -r 000000000000 -r 6474c204b198 content/xul/templates/src/nsTemplateRule.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/xul/templates/src/nsTemplateRule.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,328 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsTemplateRule_h__ +#define nsTemplateRule_h__ + +#include "nsCOMPtr.h" +#include "nsIAtom.h" +#include "nsIRDFDataSource.h" +#include "nsIRDFResource.h" +#include "nsIContent.h" +#include "nsIDOMNode.h" +#include "nsTArray.h" +#include "nsString.h" +#include "nsIXULTemplateRuleFilter.h" +#include "nsCycleCollectionParticipant.h" + +class nsIXULTemplateQueryProcessor; +class nsTemplateQuerySet; + +class nsTemplateCondition +{ +public: + // relations that may be used in a rule. They may be negated with the + // negate flag. Less and Greater are used for numeric comparisons and + // Before and After are used for string comparisons. For Less, Greater, + // Before, After, Startswith, Endswith, and Contains, the source is + // conceptually on the left of the relation and the target is on the + // right. For example, if the relation is Contains, that means Match if + // the source contains the target. + enum ConditionRelation { + eUnknown, + eEquals, + eLess, + eGreater, + eBefore, + eAfter, + eStartswith, + eEndswith, + eContains + }; + + nsTemplateCondition(nsIAtom* aSourceVariable, + const nsAString& aRelation, + nsIAtom* aTargetVariable, + bool mIgnoreCase, + bool mNegate); + + nsTemplateCondition(nsIAtom* aSourceVariable, + const nsAString& aRelation, + const nsAString& aTargets, + bool mIgnoreCase, + bool mNegate, + bool aIsMultiple); + + nsTemplateCondition(const nsAString& aSource, + const nsAString& aRelation, + nsIAtom* aTargetVariable, + bool mIgnoreCase, + bool mNegate); + + ~nsTemplateCondition() { MOZ_COUNT_DTOR(nsTemplateCondition); } + + nsTemplateCondition* GetNext() { return mNext; } + void SetNext(nsTemplateCondition* aNext) { mNext = aNext; } + + void SetRelation(const nsAString& aRelation); + + bool + CheckMatch(nsIXULTemplateResult* aResult); + + bool + CheckMatchStrings(const nsAString& aLeftString, + const nsAString& aRightString); +protected: + + nsCOMPtr mSourceVariable; + nsString mSource; + ConditionRelation mRelation; + nsCOMPtr mTargetVariable; + nsTArray mTargetList; + bool mIgnoreCase; + bool mNegate; + + nsTemplateCondition* mNext; +}; + +/** + * A rule consists of: + * + * - Conditions, a set of unbound variables with consistency + * constraints that specify the values that each variable can + * assume. The conditions must be completely and consistently + * "bound" for the rule to be considered "matched". + * + * - Bindings, a set of unbound variables with consistency constraints + * that specify the values that each variable can assume. Unlike the + * conditions, the bindings need not be bound for the rule to be + * considered matched. + * + * - Content that should be constructed when the rule is "activated". + * + */ +class nsTemplateRule +{ +public: + nsTemplateRule(nsIContent* aRuleNode, + nsIContent* aAction, + nsTemplateQuerySet* aQuerySet); + /** + * The copy-constructor should only be called from nsTArray when appending + * a new rule, otherwise things break because the copy constructor expects + * mBindings and mConditions to be nullptr. + */ + nsTemplateRule(const nsTemplateRule& aOtherRule); + + ~nsTemplateRule(); + + /** + * Return the node that this rule was constructed from, or its + * logical equivalent for shorthand syntaxes. That is, the parent node of + * the content that should be generated for this rule. + */ + nsIContent* GetAction() const { return mAction; } + + /** + * Return the content node that this rule was constructed from. + * @param aResult an out parameter, which will contain the rule node + * @return NS_OK if no errors occur. + */ + nsresult GetRuleNode(nsIDOMNode** aResult) const; + + void SetVars(nsIAtom* aRefVariable, nsIAtom* aMemberVariable) + { + mRefVariable = aRefVariable; + mMemberVariable = aMemberVariable; + } + + void SetRuleFilter(nsIXULTemplateRuleFilter* aRuleFilter) + { + mRuleFilter = aRuleFilter; + } + + nsIAtom* GetTag() { return mTag; } + void SetTag(nsIAtom* aTag) { mTag = aTag; } + + nsIAtom* GetMemberVariable() { return mMemberVariable; } + + /** + * Set the first condition for the rule. Other conditions are linked + * to it using the condition's SetNext method. + */ + void SetCondition(nsTemplateCondition* aConditions); + + /** + * Check if the result matches the rule by first looking at the conditions. + * If the results is accepted by the conditions, the rule filter, if any + * was set, is checked. If either check rejects a result, a match cannot + * occur for this rule and result. + */ + bool + CheckMatch(nsIXULTemplateResult* aResult) const; + + /** + * Determine if the rule has the specified binding + */ + bool + HasBinding(nsIAtom* aSourceVariable, + nsAString& aExpr, + nsIAtom* aTargetVariable) const; + + /** + * Add a binding to the rule. A binding consists of an already-bound + * source variable, and the RDF property that should be tested to + * generate a target value. The target value is bound to a target + * variable. + * + * @param aSourceVariable the source variable that will be used in + * the RDF query. + * @param aExpr the expression that will be used in the query. + * @param aTargetVariable the variable whose value will be bound + * to the RDF node that is returned when querying the binding + * @return NS_OK if no errors occur. + */ + nsresult AddBinding(nsIAtom* aSourceVariable, + nsAString& aExpr, + nsIAtom* aTargetVariable); + + /** + * Inform the query processor of the bindings that are set for a rule. + * This should be called after all the bindings for a rule are compiled. + */ + nsresult + AddBindingsToQueryProcessor(nsIXULTemplateQueryProcessor* aProcessor); + + void Traverse(nsCycleCollectionTraversalCallback &cb) const + { + cb.NoteXPCOMChild(mRuleNode); + cb.NoteXPCOMChild(mAction); + } + +protected: + + struct Binding { + nsCOMPtr mSourceVariable; + nsCOMPtr mTargetVariable; + nsString mExpr; + Binding* mNext; + Binding* mParent; + }; + + // backreference to the query set which owns this rule + nsTemplateQuerySet* mQuerySet; + + // the node, or the