Uso de Componentes XPCOM

Una de las mejores formas de empezar a trabajar con XPCOM - especialmente cuando estás diseñando la interfaz de un componente que será usado por otros, como lo hacemos en Iniciando WebLock - es observar como están usando los componentes XPCOM los clientes.

Aplicaciones como el buscador Mozilla son clientes sofísticados y modularizados de Componentes XPCOM. De hecho, virtualmente toda la funcionalidad que asocias al buscador - navegación, manejo de ventanas, manejo de cookies, marcadores, seguridad, búsqueda, renderizado y otros aspectos - es definida en componentes XPCOM uy accesada por medio de las interfaces de esos componentes. Mozilla está hecho de componentes XPCOM.

Este capítulo demuestra como Mozilla usa algunos de esos objetos XPCOM, como el CookieManager y muestra como se definirá el acceso al componente Weblock.

Ejemplos de Componentes

Puedes encontrar más sobre como puedes usar en particular los componentes descritos aquí en la XPCOM API Reference. Por ahora, lo importante es ver como componentes como los que están en esta sección son obtenidos usando el buscador Mozilla.

Manejador de Cookies

La gestión de Cookies es uno de los muchos conjuntos de funcionalidad que están disponibles en el buscador en la forma de componente XPCOM y puede ser reutilizado por los desarrolladores que quieran una funcionalidad similar en sus aplicaciones. Siempre que un usuario accesa el Cookie Manager para ver, organizar o borrar cookies que han sido guardadas en el sistema, están usando el componente CookieManager detrás de las pantallas. El Diálogo Cookie Manager muestra la interfaz de usuario [cookie-manager-ui] que se presenta al usuario en Mozilla para trabajar con el componente CookieManager.

var el = env.locale; El Diálogo Cookie Manager

Image:cookie_mgr_dlog.png

Este Diálogo está escrito en XUL y JavaScript, usa una parte de XPCOM llamada XPConnect para conectarse sin parches al componente CookieManager (Ve Conexión a Componentes desde la interfaz abajo). XUL es sólo una forma de mostrar la funcionalidad del componente CookieManager, pero es particularmente útil en el mundo de Mozilla.

La funcionalidad del componente CookieManager está disponeble atravéz de la interfaz nsICookieManager, que es comprendido dentro de los métodos públicos en la tabla de abajo.

var el = env.locale; La Interfaz nsICookieManager

removeAll Elimina todas las cookies de la lista de cookies.
enumerator Enumera la lista de cookies.
remove Elimina una cookie en particular de la lista.

En XPCOM se garantiza que la interfaz permanece igual aún cuando la implementación debajo de ella cambie. Las interfaces son públicas en otras palabras y las implementaciones son privadas[private-xpcom-interfaces]. Cuando un usuario selecciona una de las cookies mostradas en la lista y luego presiona el botón Eliminar, el método Remove de la interfaz nsICookieManager es llamado. La función es llevada a cabo poir el componente CookieManager y la cookie seleccionada es borrada del disco y eliminada de la lista.

El trozo de código en Obtener el Componente CookieManager en JavaScript muestra como el método Remove() del componente XPCOM CookieManager puede ser llamado desde JavaScript:

var el = env.locale; Obtener el Componente CookieManager en JavaScript

// xpconnect al cookiemanager
// obtener el componente cookie manager en JavaScript
var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                     .getService();
cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);

// llamado como parte de la función largerDeleteAllCookies()
function FinalizeCookieDeletions() {
  for (var c=0; c<deletedCookies.length; c++) {
    cmgr.remove(deletedCookies[c].host,
                deletedCookies[c].name,
                deletedCookies[c].path);
  } 
  deletedCookies.length = 0;
}

Esto no es todo los que hay acerca del tema, desde luego, pero muestra un aspecto importante de XPCOM. Los arreglos contractuales que XPCOM forza abren una forma de interoperabilidad binaria -para poder accesar, usar y reutilizar componentes XPCOM en tiempo de ejecución. Y ellos hacen posible usar componentes escritos en otros lenguajes - como JavaScript, Python y otros - y usar componentes XPCOM basados en C++ desde esos otros lenguajes también.

En el buscador Mozilla, los componentes son usados desde JavaScript en la interfaz como en C++ o cualquier otro lenguaje. De hecho, una búsqueda en el código fuente de Mozilla revela que este componente CookieManager es llamado sólo desde JavaScript. Usaremos este componente desde JavaScript nosotros mismos como parte de este tutorial[cookie-manager-in-tutorial].

El Componente WebBrowserFind

Todos los componentes son usados en funcionalidad de alto nivel del buscador como nsWebBrowserFind que contiene los métodos find() y findNext() para encontrar el contenido en páginas web y tareas de bajo nivel como manipulación de información. No todas las APIs de Mozilla deben ser integradas en XPCOM, mucha de la funcionalidad está disponible en componentes que pueden ser reutilizados por las extensiones del buscador y/o embebedores de Gecko.

Además del componente CookieManager, por ejemplo, el componente WebBrowserFind es otra parte de una larga lista de interfaces de búsqueda web que puedes usar. Su interfaz nsIWebBrowserFind se muestra en La Interfaz nsIWebBrowserFind. Para usar este componente, los accesas mediante la interfaz nsIWebBrowserFind y llamas sus métodos.

var el = env.locale; La Interfaz nsIWebBrowserFind

findNext Encuentra la siguiente ocurrencia de la cadena buscada.
findBackwards Atributo booleano que ajusta findNext() para buscar hacia arriba del documento.
searchFrames Atributo booleano que indica si se busca o no en subframes del documento actual.
matchCase Atributo booleano que indica si coincide o no el caso en la búsqueda.
entireWord Atributo booleano que especifica si debe coincidir toda la palabra o no.

Una vez que usas la interfaz para obtener el componente, puedes preguntarle al componente que otras interfaces soporta. Este servicio, que es definido en la interfaz básica nsISupports e implementado por todos los componentes XPCOM, te permite requerir y cambiar interfaces en un componente como parte de las capacidades de mecanografía de objeto de tiempo de ejecución de XPCOM. Es gestionada por el método QueryInterface que fue visto en el capítulo ¿Qué es XPCOM?. La XPCOM API Reference es una referencia de todos los componentes disponibles en Mozilla.

El Componente WebLock

Es hora de ver el componente WebLock como otro ejemplo de componentes XPCOM (ya que lo estarás creando muy pronto). En la programación orientada a objetos, es común diseñar primero la interfaz para definir la funcionalidad que tendrá la abstracción sin tener en cuenta como será hecha esta funcionalidad. Así que dejaremos del lado los detalles la implementación hasta el siguiente capítulo y veremos el componente desde afuera, desde la interfaz del componente WebLock.

var el = env.locale; La Interfaz IWebLock

lock Bloquea el buscador al sitio actual(o a la lista blanca de sitios aprobados leída del disco).
unlock Desbloquea el buscador para uso irrestricto.
addSite Añade un nuevo sitio a la lista blanca.
removeSite Elimina un sitio dado de la lista blanca.
sites Enumerador para la lista de sitios aprobados leída de la lista blanca.

El componente WebLock es un programa que implementa todos los métodos descritos en la definición de la interfaz. Se registra a sí mismo para su uso al iniciar el buscador y tiene una factoría que crea una instancia de él para ser usada cuando el usuario o el administrador presionan el icono en la interfaz gráfica del buscador.

Uso de Componentes en Mozilla

Entonces ¿Cómo se obtienen los componentes en Mozilla?. Has visto algunos pedazos de JavaScript en secciones anteriores de este capítulo, pero no hemos explicado como XPCOM hace los componentes disponibles en general.

Esta sección aborda el uso práctico de componentes en Mozilla. Está dividido en tres subsecciones: una acerca de como encontrar todos esos componentes binarios en Mozilla y otras dos que corresponden a cada una de las dos formas en las que los clientes accesan normalmente los componentes XPCOM:

Localizar los Componentes de Mozilla

Este libro trata de dar información de referencia para los componentes XPCOM y sus interfaces que están congeladas al momento de hacer este escrito. El Mozilla embedding project alberga las interfaces congeladas actuales.

Mozilla también tiene algunas herramientas que pueden encontrar y desplegar información de las interfaces disponibles en Gecko como el Visor de Componentes XPCOM descrito abajo, y LXR, que es una herramienta basada en web para ver el código fuente.

El reto de hacer disponible buena información acerca de los componentes XPCOM para los posibles clientes, el proceso de congelar las interfaces que son implementadas por esos componentes aún está en progreso. El Visor de Componentes no distingue los componentes que ya están congelados de los que no. En el código fuente que ves en LXR, las interfaces que han sido congeladas han sido marcadas hasta arriba con @status frozen.

El Visor de Componentes XPCOM

El Visor de Componentes es una extensión que puedes instalar en tu buscador (en sandbox, no está disponible por ahora):

var el = env.locale; Visor de Componentes XPCOM Image:using-component-viewer.png

La columna de la izquierda muestra los componentes, en este caso un subconjunto resultado de la búsqueda de "gfx" como parte del contract ID y en la columna de la derecha una lista de las interfaces. Cuando abres un componente en la izquierda, puedes ver las interfaces que implementa y una lista con los métodos que tiene cada interfaz.

El Visor de Componentes XPCOM puede ser extremadamente útil para esta fuente de grandes interrogantes, pero otra vez: despliega todos los componentes e interfaces contenidas dentro, muchas de las cuales no son prácticas para reutilizarse actualmente o lo suficientemente estables para ser usados viablemente en el desarrollo de tu propia aplicación. Usa estas listas con precaución.

XXX mediawiki is t3h suxx0r XXX give me my C++

Usar Componentes XPCOM en tu Cpp

XPConnect hace fácil accesar los componentes XPCOM como objetos JavaScript, pero usar componentes XPCOM en C++ no es mucho más difícil.

Gestionar Cookies desde Cpp duplica el código de Obtener el Componente CookieManager en JavaScript, pero en C++ en vez de JavaScript.


var el = env.locale; Gestionar Cookies desde Cpp

nsCOMPtr<nsIServiceManager> servMan;
nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
if (NS_FAILED(rv))
  return -1;

nsCOMPtr<nsICookieManager> cookieManager;
rv = servMan->GetServiceByContractID("@mozilla.org/cookiemanager",
                                     NS_GET_IID(nsICookieManager),
                                     getter_AddRefs(cookieManager));

if (NS_FAILED(rv))
  return -1;

PRUint32 len;
deletedCookies->GetLength(&len);

for (int c=0; c<len; c++)
    cookieManager->Remove(deletedCookies[c].host,
                          deletedCookies[c].name,
                          deletedCookies[c].path,
                          PR_FALSE);

XXX: In the original document, there were only the first three parameters to the |Remove| call. I added |PR_FALSE| as a fourth parameter because the interface seems to require it: http://lxr.mozilla.org/mozilla/sourc...Manager.idl#64 This problem also appears in the JavaScript version below, and I've added |false| as a fourth parameter there as well.

Si tu aplicación está escrita en C++, entonces Gestionar Cookies desde Cpp te muestra los pasos que debes seguir para obtener un componente XPCOM, especifica la interfaz en el componente que quieres usar y llama los métodos en esa interfaz.

XPConnect: Usar Componentes XPCOM desde un Script

El componente CookieManager que discutimos al principio del capítulo nos da una buena oportunidad para hablar después acerca de usar componentes desde JavaScript. En el siguiente fragmento de código del diálogo Gestor de Cookies en Mozilla, puedes ver un singletón del componente CookieManager siendo creado con el método getService() y usado para dar la funcionalidad que deja a los usuarios cargar y eliminar cookies desde la interfaz de usuario.

var el = env.locale; Gestionar Cookies desde JavaScript

var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                     .getService();
cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);

function loadCookies() {
  // load cookies into a table
  var enumerator = cmgr.enumerator;
  var count = 0;
  var showPolicyField = false;
  while (enumerator.hasMoreElements()) {
    var nextCookie = enumerator.getNext();
    nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);
    /* .... */
}
function FinalizeCookieDeletions() {
  for (var c=0; c<deletedCookies.length; c++) {
    cmgr.remove(deletedCookies[c].host,
                deletedCookies[c].name,
                deletedCookies[c].path,
                false);
  } 
  deletedCookies.length = 0;
}

XXX: In the original document, there were only the first three parameters to the |remove| call. I added |false| as a fourth parameter because the interface seems to require it: http://lxr.mozilla.org/mozilla/sourc...Manager.idl#64 This problem also appears in the C++ version above, and I've added |PR_FALSE| as a fourth parameter there as well.

Después los métodos estan siendo llamados en el mismo CookieManager (ejm; cookiemanager.remove, que apunta a la función remove() en La Interfaz nsICookieManager), nota los objetos y métodos especiales XPConnect que reflejan el componente XPCOM en JavaScript.

Components es el objeto JavaScript que controla la conexión a componentes y classes es un array de todas las clases por las que puedes preguntar mediante el contract ID. Para instanciar un componente XPCOM en JavaScript, creas un nuevo objeto del componente y pasas el contract ID para el componente que quieres y preguntas si será un singleton o una instancia del componente el resultado regresado:

var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                     .getService();

El objeto resultante cookiemanager nos da acceso a todos los métodos de ese componente que sido definidos en IDL y compilados en una biblioteca de tipos. Usando el componente CookieManager puedes escribir código como este para borrar todas las cookies del sistema:

cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                 .getService();
cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);

// delete all cookies
function trashEm() {
   cmgr.removeAll();
}

Otro aspecto vital del pegamento de XPConnect que muestra este ejemplo es la disponibilidad del método QueryInterface en todos los objetos que son reflejados en JavaScript desde XPCOM. Como en C++, puedes usar este método para preguntar por otras interfaces que esten disponibles en el objeto dado.

Recuerda, QueryInterface te permite requerir a un objeto las interfaces que soporta. En el caso del trozo en La Interfaz nsICookieManager, el método QueryInterface es usado para obtener la interfaz nsICookie del enumerador, así que, para instanciar, el código JavaScript puede accesar los atributos value y name para cada cookie.

  1. Nota: cookie-manager-ui
    Nota que la interfaz no es parte del componente en sí mismo. XPCOM hace fácil usar componentes como CookieManager desde Mozilla's Cross Platform Front End (XPFE) y otras interfaces de usuario, pero el componente no tiene por sí mismo una IU(Interfaz de Usuario).
  1. Nota: private-xpcom-interfaces
    Hay excepciones a esto. Algunas interfaces XPCOM también son privadas y no estan hechas para uso general. Las interfaces privadas no tienen los mismos requerimientos que las que son hechas públicas en IDL.
  2. Nota: cookie-manager-in-tutorial
    El componente CookieManager es usado para proveer para la funcionalidad de bloqueo web descrita en este tutorial.

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

Etiquetas y colaboradores del documento

Colaboradores de esta página: Jorge.barrera, Sheppy, Mgjbot, Maharba
Última actualización por: Jorge.barrera,