Cambios XPCOM en Gecko 2.0

by 3 contributors:

Borrador
Esta página no está completa.

Han tenido lugar una serie de cambios que afectan la compatibilidad de componentes XPCOM en Gecko 2. Este artículo detalla esos cambios y provee sugerencias sobre cómo actualizar tu código.

Se acabaron las interfaces inmovilizadas

Se acabaron las interfaces inmovilizadas; a partir de ahora, todas las interfaces está sujetas a cambios. Se actualizará la documentación según permita el tiempo eliminar las referencias a las interfaces que estén "inmovilizadas " o "no inmovilizadas".

Registro de componentes

La manera en que los componentes XPCOM son registrados cambió en Gecko 2. Antes de Gecko 2, durante el registro de un componente, todos los binarios y ficheros del componente JavaScript eran cargados y llamados, pidiéndoles que se registraran a sí mismos. Si usabas XPCOMUtils.jsm, algo de esto estaba oculto, pero eso pasaba.

Comenzando en Gecko 2, como sea, los componentes son registrados usando archivos manifest, similar a como chrome es registrado. De hecho, el mismo archivo chrome manifest será usado para registrar componentes.

Todos los componentes XPCOM necesitarán ser actualizados para soportar esto. Como sea, es muy fácil hacerlo, y se puede actualmente soportar ambos tipos de registro para conservar la compatibilidad hacia atrás.

Manifestos de componentes

Todo registro de componentes es controlado a través de archivos manifest. Para extensiones, esto es el mismo chrome.manifest actualmente usado para registrar chrome.

Archivos XPT

La ruta de los archivos XPT debe ser listada explicitamente en un manifest usando una directiva interfaces directive:

interfaces components/mycomponent.xpt

Componentes JavaScript

El registro de información para componentes JavaScript ya no está dentro del componente mismo; en cambio, está alojado en el manifest. El componente es cargado solo cuando el administrador de XPCOM necesita crear un componente.

chrome.manifest:

# The {classID} here must match the classID in mycomponent.js
component {e6b866e3-41b2-4f05-a4d2-3d4bde0f7ef8} components/mycomponent.js
contract @foobar/mycomponent;1 {e6b866e3-41b2-4f05-a4d2-3d4bde0f7ef8}
category profile-after-change MyComponent @foobar/mycomponent;1

El código javascript ya no exporta una función NSGetModule(). Ahora debe exportar una función NSGetFactory(), la cual acepta un ID de contrato como parámetro.

Por ejemplo en el código JavaScript de tu componente:

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

function myComponent() {
}
myComponent.prototype = {
  // this must match whatever is in chrome.manifest!
  classID: Components.ID("{e6b866e3-41b2-4f05-a4d2-3d4bde0f7ef8}"),

  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIMyComponent]),

  /* nsIMyComponent implementation goes here */
  ...
};

// The following line is what XPCOM uses to create components. Each component prototype
// must have a .classID which is used to create it.
const NSGetFactory = XPCOMUtils.generateNSGetFactory([myComponent]);

Un componente puede implemente compatibilidad hacia atrás con Gecko 1.9.2 dinámicamente detectando cuál de los simbolos son exportados por XPCOMUtils.jsm y exportando la función correcta:

/**
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
if (XPCOMUtils.generateNSGetFactory)
    var NSGetFactory = XPCOMUtils.generateNSGetFactory([mySample]);
else
    var NSGetModule = XPCOMUtils.generateNSGetModule([mySample]);

Componentes binarios

Los componentes binarios deben ser listados explicitamente en un manifest usando una directiva binary-component:

binary-component components/mycomponent.dll

C++ en el componente debe ser cambiado: un componente binario ya no exporta la función NSGetModule(). En cambio, exporta un simbolo de datos NSModule el cual apunta a la estructura mozilla::Module. Para más información acerca de la estructura mozilla::Module, mira la cabecera Module.h. Para un ejemplo actual de implementación de módulos dinámicos, mira nsSampleModule.cpp.

Notese que nsIGenericFactory.h ha sido eliminado. Referencias a nsIGenericFactory.h deben ser reemplazadas con mozilla/ModuleUtils.h.

Es posible para un componente binario ser compatible con Mozilla 1.9.2 y Mozilla 2.0 usando un macro extraNS_IMPL_MOZILLA192_NSGETMODULE. mira nsSampleModule.cpp para más detalles.

Subdirectorios específicos de plataforma

El sistema component/chrome usado para mirar en los subdirectorios específicos de plataforma de una extensión, del tipo platform/WINNT_x86-msvc/chrome.manifest en Windows. Ya no está soportado. Puedes usar las directivas de registro chrome, OS y ABI para lograr el mismo efecto:

binary-component components/windows/mycomponent.dll ABI=WINNT_x86-msvc
binary-component components/mac/mycomponent.dylib ABI=Darwin_x86-gcc3
binary-component components/mac/mycomponent64.dylib ABI=Darwin_x86-64-gcc3
binary-component components/linux/mycomponent.so ABI=Linux_x86-gcc3

Registro de categoría

Anterior a Gecko 2, las extensiones podían escuchar las notificaciones para el xpcom-startup y app-startup durante el inicio, y realizar acciones durante. Este ya no es el caso. Las más temprana notificacion de inicio que puede recibir una extensión es profile-after-change, la cual tiene siempre que ser una notificación recomendad para observar. Esto es debido a que está entre las notificaciones más tempranas que ocurren despues de que la carpeta de perfil(y por lo tanto preferencias y otros servicios) está disponible.

Qué necesitas cambiar

Si tu extension actualmente observa aún a xpcom-startup ó app-startup, necesitas actualizar tu código para observer en vez a profile-after-change.

Usualmente, las extensiones observaban app-startup porqué en el pasado, necesitabas cargar app-startup con el fin de poder registrarse para observar profile-after-change en primer lugar. A partir de Gecko 1.9.1, este ya no es el caso, como sea; tu puedes registrar ahora profile-after-change usando el administrador de categoría. Mira Recibiendo notificaciones de inicio para más detalles.

Para agregar una entrada de categoria, debes insertar la siguiente linea a tu chrome.manifest:

category profile-after-change MyComponent @foobar/mycomponent;1 
Importante: Formalmente, el id de contrado de la entrada de categoría era prefijada con "service," si el componente era implementado como un servicio. Este prefijo necesita ser eliminado cuando migres a chrome.manifest.

Nombres de categoría cambiados

El administrador de categoría en XPCOM es usado para registrar ciertos objetos auxiliares globales. Como chrome.manifest es un formato de espacio delimitado, los nombres de categoría con espacios no pueden ser registrados. Por lo tanto las siguientes categorías han cambiado:

Nombre anterior Nuevo nombre
JavaScript global constructor Javascript-global-constructor
JavaScript global constructor prototype alias JavaScript-global-constructor-prototype-alias
JavaScript global property JavaScript-global-property
JavaScript global privileged property JavaScript-global-privileged-property
JavaScript global static nameset JavaScript-global-static-nameset
JavaScript global dynamic nameset JavaScript-global-dynamic-nameset
JavaScript DOM class JavaScript-DOM-class
JavaScript DOM interface JavaScript-DOM-interface
XSLT extension functions XSLT-extension-functions

¿Pero por qué?

Previamente, cuando fuera Gecko detectaba que la versión de la aplicación habia cambiado, o una o mas extensiones eran agregadas o eliminadas, activadas o desactivadas, era necesario para tratar todos los registros de componentes existentes, reiniciar la aplicación(Lo que llamamos "Reinicio de administrador de extensiones"), durante su proceso de arranque. Esto fue necesario para asegurar que los componentes que ya no estuvieran disponibles fueran eliminados apropiadamente, y para re-registrar todo, cargando algun nuevo componente que se necesitara.

En teoría, estos es invisible para el usuario, pero es un proceso costoso, ya que cada componente necesita ser cargado y ejecutado, luego descargado, luego recargado de nuevo durante el reinicio.

Además de eso, con el trabajo que estamos haciendo en el soporte multihilo para Firefox, el contenido de los procesos también necesita registrar componentes en una base por proceso, o de alguna manera para compartir la cache de un componente con el proceso chrome.

Los cambios para el modelo de registro de componentes permite este llamado Reinicio de administrador de extensiones volverse una cosa del pasado. En lugar de confiar en una potencial caché de componentes en el arranque, nosotros leemos los registros de componentes de la aplicación fuera de su archivo manifest y cargamos esos componentes. Esto obtiene suficiente de XPCOM cargado y en ejecución con lo que podemos cargar el administrador de extensiones y realizar la instalación, desinstalación y acualización necesaria de algunas extensiones instaladas.

Hecho esto, las extensiones pueden ser cargadas simplemente leyendo su manifesto, cargando sus componentes y continuando el proceso de arranque, todo sin tener que reiniciar el navegador.

Los contenidos de procesos en Electrolysis pueden simplemente leer el registro del componente durante el arranque.

 

Cambios en los contenedores XPCNativeWrapper

No se pueden desactivar del manifiesto  los contenedores XPCNativeWrapper

Ya no se admite la especificación de xpcnativewrappers=no en tu manifiesto. El objetivo de ésta fue siempre ofrecer una solución alternativa a corto plazo que permitiera que las extensiones continuaran funcionando mientras que los autores actualizaban el código para usar los contenedores XPCNativeWrapper.

Si tu agregado/complemento depende de un enlace XBL adjunto a los objetos de contenido - por ejemplo, la capacidad para llamar a las funciones u obtener y establecer las propiedades creadas por el enlace XBL - tendrás que usar la propiedad de los contenedores XPCNativeWrapper wrappedJSObject para tener acceso a los objetos ajustados.

Si necesitas poder llamar a las funciones o tener acceso a las propiedades definidas por el contenido web, tendrás que hacer esto también. Puede ser el caso si, por ejemplo, has escrito una extensión que añade a un servicio de correo web un botón eliminar y el servicio define una función window.delete() que tienes que llamar.

Si, por otro lado, lo único que haces con el contenido es tener acceso a métodos y propiedades DOM, no habrás tenido que usar xpcnativewrappers=no y simplemente deberías eliminarlo de tu manifiesto.

Cambios varios en los contenedores XPCNativeWrapper

  • Ya no se lanza una excepción de seguridad al usar el operador delete en las propiedades "expando" de un contenedor XPCNativeWrapper.

Cambios en XPCOMUtils.jsm

Se ha actualizado el módulo de código XPCOMUtils.jsm  para permitir que especifiques las ID de las aplicaciones en las que deseas registrar tu componente.

Captadores de servicios XPCOM

Una serie de servicios XPCOM que se usan habitualmente disponen ahora de funciones de captadores de servicios en el  mozilla::services namespace; facilitan en gran medida el acceso a estos servicios desde el código C++.

Consulta también

Etiquetas y colaboradores del documento

Contributors to this page: Sheppy, inma_610, JCeb
Última actualización por: Sheppy,