mozilla
Los resultados de tu búsqueda

    Cómo implementar un componente procesador de consultas XUL

    Imagen:traduccion-pendiente.png Esta página está traduciéndose a partir del artículo How_to implement a custom XUL query processor component, razón por la cual puede haber algunos errores sintácticos o partes sin traducir. Puedes colaborar continuando con la traducción


    El servicio XUL apoya el uso de plantillas para crear un bloque de contenidos a partir de una consulta a una fuente de datos. La Guia de Plantillas XUL presenta una gran fuente de información detallada acerca del uso de las plantillas XUL. El servicio XUL proporciona procesadores de consulta de plantillas para RDF, XML y SQL (mozStorage). Este sistema de plantillas también da soporte a la creación de procesadores de consultas personalizadas. Los procesadores de consultas personalizadas son componentes XPCOM que deben implementar la interfaz nsIXULTemplateQueryProcessor y seguir algunos de los criterios que indican cuándo se deben registrar los mismos.

    En este ejemplo, crearemos un sencillo componente XPCOM en JavaScript. Dicho componente mantendrá una pequeña selección de objetos de JavaScript en su fuente de datos. En la práctica, se usaría una fuente propia de datos personalizada.

    A continuación presentamos un ejemplo del posible aspecto que podría tener nuestro servicio de XUL al utilizar un procesador de consultas personalizado:

    <?xml version="1.0"?>
    <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
    <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
        <grid>
            <columns>
                <column flex="1"/>
                <column flex="3"/>
                <column flex="2"/>
                <column flex="1"/>
            </columns>
    
            <rows datasources="dummy" ref="." querytype="simpledata">
                <template>
                    <row uri="?">
                        <label value="?name"/>
                        <label value="?age"/>
                        <label value="?hair"/>
                        <label value="?eye"/>
                    </row>
                </template>
            </rows>
        </grid>
    </window>
    

    Algunas cosas a tener en cuenta. En realidad no estamos utilizando las fuentes de datos en nuestro componente de ejemplo, por lo que lo configuraremos con un valor no válido. Un hilo vacío también valdría. El tipo de consulta es importante. Se usa para crear un caso de nuestro objeto XPCOM. La contracción de la identidad de nuestro componente XPCOM debería tener la forma de "@mozilla.org/xul/xul-query-processor;1?name=xxx", donde las xxx representan el tipo de consulta utilizado en el bloque de plantillas XUL. A continuación mostramos nuestro ejemplo de procesador de consultas XPCOM de JavaScript:

    Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
    
    
    // basic wrapper for nsIXULTemplateResult
    function TemplateResult(aData) {
      this._data = aData;
      // just make a random number for the id
      this._id = Math.random(100000).toString();
    }
    
    TemplateResult.prototype = {
      QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIXULTemplateResult]),
    
      // private storage
      _data: null,
    
      // right now our results are flat lists, so no containing/recursion take place
      isContainer: false,
      isEmpty: true,
      mayProcessChildren: false,
      resource: null,
      type: "simple-item",
    
      get id() {
        return this._id;
      },
    
      // return the value of that bound variable such as ?name
      getBindingFor: function(aVar) {
        // strip off the ? from the beginning of the name
        var name = aVar.toString().slice(1);
        return this._data[name];
      },
    
      // return an object instead of a string for convenient comparison purposes
      // or null to say just use string value
      getBindingObjectFor: function(aVar) {
        return null;
      },
    
      // called when a rule matches this item.
      ruleMatched: function(aQuery, aRuleNode) { },
    
      // the output for a result has been removed and the result is no longer being used by the builder
      hasBeenRemoved: function() { }
    };
    
    
    // basic wrapper for nsISimpleEnumerator
    function TemplateResultSet(aArrayOfData) {
      this._index = 0;
      this._array = aArrayOfData;
    }
    
    TemplateResultSet.prototype = {
      QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISimpleEnumerator]),
    
      hasMoreElements: function() {
        return this._index < this._array.length;
      },
    
      getNext: function() {
        return new TemplateResult(this._array[this._index++]);
      }
    };
    
    
    // The query processor class - implements nsIXULTemplateQueryProcessor
    function TemplateQueryProcessor() {
      // our basic list of data
      this._data = [
                    {name: "mark", age: 36, hair: "brown", eye: "brown"},
                    {name: "bill", age: 25, hair: "red", eye: "black"},
                    {name: "joe", age: 15, hair: "blond", eye: "blue"},
                    {name: "jimmy", age: 65, hair: "gray", eye: "dull"}
                   ];
    }
    
    TemplateQueryProcessor.prototype = {
      QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIXULTemplateQueryProcessor]),
      classDescription: "Sample XUL Template Query Processor",
      classID: Components.ID("{282cc4ea-a49c-44fc-81f4-1f03cbb7825f}"),
      contractID: "@mozilla.org/xul/xul-query-processor;1?name=simpledata",
    
      getDatasource: function(aDataSources, aRootNode, aIsTrusted, aBuilder, aShouldDelayBuilding) {
        // TODO: parse the aDataSources variable
        // for now, ignore everything and let's just signal that we have data
        return this._data;
      },
    
      initializeForBuilding: function(aDatasource, aBuilder, aRootNode) {
        // perform any initialization that can be delayed until the content builder
        // is ready for us to start
      },
    
      done: function() {
        // called when the builder is destroyed to clean up state
      },
    
      compileQuery: function(aBuilder, aQuery, aRefVariable, aMemberVariable) {
        // outputs a query object.
        // eventually we should read the <query> to create filters
        return this._data;
      },
    
      generateResults: function(aDatasource, aRef, aQuery) {
        // preform any query and pass the data to the result set
        return new TemplateResultSet(this._data);
      },
    
      addBinding: function(aRuleNode, aVar, aRef, aExpr) {
        // add a variable binding for a particular rule, which we aren't using yet
      },
    
      translateRef: function(aDatasource, aRefstring) {
        // if we return null, everything stops
        return new TemplateResult(null);
      },
    
      compareResults: function(aLeft, aRight, aVar) {
        // -1 less, 0 ==, +1 greater
        if (aLeft < aRight) {
          return -1;
        }
        else if (aLeft > aRight) {
          return  1;
        }
        else {
          return 0;
        }
      }
    };
    
    
    var components = [TemplateQueryProcessor];
    
    function NSGetModule(compMgr, fileSpec) {
      return XPCOMUtils.generateModule(components);
    }
    

    Nuestro ejemplo de procesador de consultas es muy fácil. Notas aclaratorias:

    • Estamos usando el getBindingFor en vez del getBindingObjectFor para simplificar así el código. La variable introducida en el getBindingFor todavía conserva las “?” por lo que debéis aseguraros de introducirla de forma correcta.
    • No se usarán cualquiera de los elementos <query/> o <rule/> en el bloque de plantillas de XUL. Se podrá hacer uso de éstas para apoyar el filtrado de fuentes de datos.
    • No estamos manejando fuentes de datos, sino que en su lugar, estamos introduciendo a mano el componente. Se podría ampliar fácilmente este ejemplo para manejar varias fuentes de datos a través de la comprobación del valor de las mismas en el getDatasource y en el initializeForBuilding.
    • No se usarán cualquiera de los elementos <query/> o <rule/> en el bloque de plantillas de XUL. Se podrá hacer uso de éstas para apoyar el filtrado de fuentes de datos.

    Etiquetas y colaboradores del documento

    Contributors to this page: Kaltya, Nukeador, Mgjbot
    Última actualización por: Nukeador,