XULTemplatesAPI

From MozillaWiki
Jump to: navigation, search

The API for XUL templates

Query Processor

 interface nsIXULTemplateQueryProcessor : nsISupports
 {
  /**
   * Initialize for query generation. This will called before the rules are
   * processed and whenever the rules are rebuilt.
   *
   * @param aDatasource datasource for the data
   * @param aBuilder the template builder
   * @param aTemplateNode the <template> node
   */
  void initializeForBuilding(in nsISupports aDatasource,
                             in nsIXULTemplateBuilder aBuilder,
                             in nsIDOMNode aRootNode);

  /**
   * Called when the template builder is being destroyed so that the query
   * processor can clean up any state.
   */
  void done();

  /**
   * Compile a query from a node. The result of this function will later be
   * passed to generateResults for result generation. If null is returned,
   * default query processing will be used instead.
   *
   * The reference variable may be used within the query as a placeholder for
   * the reference point, if it was set as the container attribute on the
   * template.
   *
   * The member variable is determined from the member attribute on the
   * template, or from the uri in the first action's rule if that attribute is
   * not present. A rule processor may use the member variable as a hint to
   * indicate what variable is expected to contain the results.
   *
   * If necessary, the query builder may use other means to determine these
   * variables.
   *
   * @param aBuilder the template builder
   * @param aQuery <query> node to compile
   * @param aRefVariable the reference variable
   * @param aMemberVariable the member variable
   *
   * @returns a compiled query object
   */
  nsISupports compileQuery(in nsIXULTemplateBuilder aBuilder,
                           in nsIDOMNode aQuery,
                           in nsIAtom aRefVariable,
                           in nsIAtom aMemberVariable);

  /**
   * Generate the results of a query and return them in an enumeration. The
   * enumeration must contain nsIXULTemplateResult objects. If there are no
   * results, an empty enumerator must be returned. The arguments may be used
   * to establish the query and reference point.
   *
   * The context reference (aRef) is a reference point used when calculating
   * results. It is calculated from the ref attribute on the first pass or the
   * parent node when calculating inner children. It may be ignored if it is
   * not deemed relevant. The reference variable specified during query
   * compilation is expected to be a placeholder for the reference point.
   *
   * This method is only called when compileQuery returns a non-null value for
   * a particular query.
   *
   * @param aDatasource datasource for the data
   * @param aRef context reference used as a starting point
   * @param aQuery the compiled query returned from query compilation
   *
   * @returns an enumeration of nsIXULTemplateResult objects as the results
   */
  nsISimpleEnumerator generateResults(in nsISupports aDatasource,
                                      in nsIXULTemplateResult aRef,
                                      in nsISupports aQuery);

  /**
   * Add a binding for a particular rule. A binding calculates a result for
   * an expression after a rule has matched. The bindings are optional
   * variable assignments that should be applied after a rule is found to
   * match.
   *
   * @param aRuleNode rule to add binding to
   * @param aVar variable to assign result to
   * @param aRef variable that holds reference value
   * @param aExpr expression used to compute the value to assign
   */
  void addBinding(in nsIDOMNode aRuleNode,
                  in nsIAtom aVar,
                  in nsIAtom aRef,
                  in AString aExpr);

  /**
   * Translate a ref attribute string into a result. This is used in the first
   * pass. Other passes may use the result object directly.
   *
   * XXX perhaps remove this and use result id's as the ref
   *
   * @param aDatasource datasource for the data
   * @param aRefString the ref attribute string
   *
   * @return the translated ref
   */
  nsIXULTemplateResult translateRef(in nsISupports aDatasource,
                                    in AString aRefString);

  /**
   * Compare two results to determine their order, used when sorting results.
   * This method should return -1 when the left result is less than the right,
   * 0 if both are equivalent, and 1 if the left is greater than the right.
   * The sort should only consider the specified field.
   *
   * This method must only be called with results that were created by this
   * query processor.
   *
   * @param aLeft the left result to compare
   * @param aRight the right result to compare
   * @param aVar field to compare to
   *
   * @param returns -1 if less, 0 if equal, and 1 if greater
   */
   PRInt32 compareResults(in nsIXULTemplateResult aLeft,
                          in nsIXULTemplateResult aRight,
                          in nsIAtom aVar);
 };

Result Objects

 interface nsIXULTemplateResult : nsISupports
 {
  /**
   * True if the result is a container
   */
  readonly attribute boolean isContainer;

  /**
   * True if the result is an empty container
   */
  readonly attribute boolean isEmpty;

  /**
   * True if the template builder may process the children and generate child
   * content. If false, child content is not processed. This may be overriden
   * by syntax used in the template rule.
   */
  readonly attribute boolean mayProcessChildren;

  /**
   * ID of the result. The content will be given this id. The id should be
   * unique for a query.
   */
  readonly attribute AString id;

  /**
   * Resource for the result, which may be null. If set, the uri should be the
   * same as the ID property.
   */
  readonly attribute nsIRDFResource resource;

  /**
   * Get a binding for a variable such as ?name for this result
   *
   * @param aVar the variable to look up
   *
   * @return the value for the variable or a null if not bound
   */
  nsISupports getBindingFor(in nsIAtom aVar);

  /**
   * Get a binding for a variable as a string such as ?name for this result
   *
   * @param aVar the variable to look up
   *
   * @return the value for the variable or a null string if not bound
   */
  AString getBindingAsStringFor(in nsIAtom aVar);

  /**
   * Indicate that a particular rule has matched and that output will be
   * generated for it.
   *
   * @param aQuery the query that matched
   * @param aRuleNode the rule node that matched
   */
  void ruleMatched(in nsISupports aQuery, in nsIDOMNode aRuleNode);

  /**
   * Indicate that the output for a result has been removed and the
   * result is no longer being used by the builder.
   */
  void remove();
 };

Rule Filter

 interface nsIXULTemplateRuleFilter : nsISupports
 {
  /**
   * Evaluate a result for a match. The match method should return true if the
   * rule matches and the result should be accepted, or false if the rule does
   * not match and the result should be dropped.
   *
   * A filter may be added to a rule by calling the builder's addRuleFilter
   * method.
   *
   * @param aRef the result to examine
   * @param aRule the rule node
   *
   * @return true if the rule matches
   */
  boolean match(in nsIXULTemplateResult aRef,
                in nsIDOMNode aRule);
 };

Some additional methods for the Template Builder (nsIXULTemplateBuilder)

    /**
     * The query processor to use to generate results
     * XXX there wouldn't be any real value of getting this outside the
     *     template builder, but there needs to be means to set this.
     */
    attribute nsIXULTemplateQueryProcessor queryProcessor;

   /**
     * Inform the template builder about a result that has been added, changed
     * or removed. This method is expected to be called by a query processor
     * when the datasource has been changed.
     *
     * If both the old result (aOldResult) and the new result (aNewResult) are
     * set, then the result is one that has changed. The results are expected
     * to have the same id. The rules are reapplied to the result and the
     * output content is regenerated. If aIsBindingUpdate is true, then only
     * a rule's binding has changed. In this case, the rules are not reapplied
     * as it is expected that the same rule will still apply.
     *
     * If aOldResult is null, a new result aNewResult is available which
     * should be added to the set of results. The query node that the new
     * result applies to must be specified using the aQuery parameter. The new
     * result will be applied to the rules and the result's RuleMatched method
     * will be called for the matching rule.
     *
     * If aNewResult is null, an existing result aOldResult should be removed
     * as it is no longer valid.
     *
     * @param aOldResult the old result
     * @param aNewResult the new result
     * @param aQueryNode the query that the result applies to
     * @param aIsBindingUpdate true if only the bindings have changed
     */
    void updateResult(in nsIXULTemplateResult aOldResult,
                      in nsIXULTemplateResult aNewResult,
                      in nsIDOMNode aQueryNode,
                      in PRBool aIsBindingUpdate);

    /**
     * Return the root result
     */
    nsIXULTemplateResult getRootResult();

    /**
     * Return the result for a given id. Only one such result is returned and
     * is always the currently active match.
     *
     * @param aId the id to return the result of
     */
    nsIXULTemplateResult getResultForId(in AString aId);

    /**
     * Adds a rule filter for a given rule, which may used for specialized
     * rule filtering. Any existing filter on a rule is removed. The default
     * conditions specified inside the <rule> tag are applied before the
     * rule filter is applied.
     *
     * @param aRule the rule to apply the filter to
     * @param aFilter the filter to add
     */
    void addRuleFilter(in nsIDOMNode aRule, in nsIXULTemplateRuleFilter aFilter);

Issues

  • atoms are used as variable identifiers. This is faster for comparisons but is only accessible to privileged code.
  • the Template Builder should probably have some function which reapplies the rules without performing the query again. This would be useful for non updating cases or when the filters have changed.