Přijďte si zasprintovat na Djangu, jiném Python open-source projektu, nebo jen potkat ostatní vývojáře!
… více »Letos v říjnu se v Praze uskuteční hned několik konferencí. Odehraje se zde nově vzniklá konference LinuxDays. K ní se přidá čtvrtý ročník openSUSE Conference, dvanáctý ročník SUSE Labs conference a aby to nebylo málo, přidá se i první ročník Gentoo miniconf. A to vše ve stejné dny a na stejném místě.
… více »V Mozille jde psát komponenty v JavaScriptu. Všechny javaskriptové soubory adresáři components jsou toho příkladem. Je to mnohem jednodušší než psát C++ komponenty, ale i tak je zde spousta kódu, který se opakuje, a na který by byla dobrá nějaká kuchařka. No a protože jsem žádnou přijatelnou na netu nenašel, asi si budu muset napsat svou vlastní. Toto je její první část, ve které si představíme rozhraní nsIModule a funkci NSGetModule.
Pokud ale nemáte ani tucha co je to ten XPCOM, tak lepší místo pro start bude vývojářská sekce na CZilla.cz
Naším cílem tedy nebude nejaké bezduché používání nativních XPCOM objektů z JavaScriptu v chrome ("uživatelská" část Mozilly, většinou XUL a JS soubory), ale rovnou vytvoření své vlastní komponenty přebývající v adresáři components. Pokud mluvím o Mozille, myslím tím Suite, Seamonkey, Firefox, Thunderbird i další podobnou havěť, a adresářem components myslím /usr/lib/mozilla/components (C:\Program Files\Mozilla.org\Mozilla\components či tak něco) etc., ale i podadresáře components uživatelského profilu verzí, které to podporují (a které to jsou Vám neřeknu, protože to teď nechci zjišťovat), popřípadě stejnojmenném adresáři nového formátu rozšíření (Firefox, Thunderbird).
Tyto adresáře si totiž Mozilla hlídá a javascriptové soubory v nich umístěné spouští a registruje v nich komponenty (jak to dělá viz níže). Pro vývoj javascriptových komponent je dobré používat debug build, protože jenom ten vypíše chybové hlášení v případě syntaktické chyby v souboru a jenom ten spouští soubory vždy při jejich změně, nikoli jen poprvé když je uvidí.
Pokud debug build není k dispozici, a kompilovat se nechce nebo nemůže, jde toto obejít tak, že se vždy před spuštěním Mozilly (Firefoxe..) smažou soubory components/compreg.dat (popř. compreg.dat přímo v u uživatelském profilu) a pokud komponenenta nejeví známky života, ve Venkmanu se příkazem /loadd pokusí skipt nahrát do kontextu debuggeru, což jako vedlejší výsledek vyplivne případné syntaktické chyby skriptu.
A jakže se komponenty registrují? Po spuštění se skript otestuje na přítomnost funkce NSGetModule, která pokud existuje, tak se spustí a očekává se od ní, že vrátí objekt implementující rozhraní
nsIModule, terý se postará o zaregistrování komponenty.
NSGetModule a nepřišel jsem na žádné použití toho, že by se něco provedlo "rovnou".
Čas se pomalu schyluje k prvnímu kousku zdrojáku. Předtím ale ještě musím trošku pokecat o možnostech ladění javascriptových komponent. Ono totiž nevím jak na javascriptovou komponentu "napíchnout" Venkman, takže pro ladění zbývají pouze výpisy do konzole, ať už té opravdové nebo javascriptové (o té více v dalších dílech). Do kontextu těchto skriptů jsou proto přidány dvě funkce, debug a dump. Nevýhoda debug je, že funguje jenom v debug buildech, takže stejně používám jenom dump skrz moji funkci d (jsem minimalista ;)), kterou v neladících verzích komponenty nahradím prázdnou funkcí. Funkce d je poněkud delší, což je ale omluveno jejím poměrně sofistikovaných chováním. Takže, první ukázka z kuchařky:
function d() {
dump("js helloworld");
if (d.caller) {
func = d.caller.toString().match(/function\s+(\w+)/);
func = func ? func[1] : "anon";
dump(" "+ func);
if (!arguments.length) {
for (var i = 0; i < d.caller.arguments.length; i++) {
dump((i != 0 ? ",\n\t" : "(\n\t") + d.caller.arguments[i]);
}
dump(")\n");
return;
}
}
dump(":");
if (arguments.length % 2) {
for (var i = 0; i < arguments.length; i++) {
dump(" "+ arguments[i] +"\n");
}
} else {
for (var i = 0; i < arguments.length; i+=2) {
dump(" "+ arguments[i] +": "+ arguments[i+1] +"\n");
}
}
}
var module = {
//nsISupports
QueryInterface: function moduleQueryInterface() { d() },
//nsIModule
registerSelf: function moduleRegisterSelf() { d() },
unregisterSelf: function moduleUnregisterSelf() { d() },
getClassObject: function moduleGetClassObject() { d() },
canUnload: function moduleCanUnload() { d() },
}
d("toplevel");
function NSGetModule() {
d();
return module;
}
// :noTabs=true:indentSize=2:tabSize=2:
Funkce d bez argumentů vypíše jméno a argumenty funkce, ze které byla volána. Při zavolání s argumenty vypíše jméno volající funkce následované výpisem svých argumentů, které pokud je jich sudý počet, tak jsou zformátované jako dvojice název: hodnota. Na ladící výpisy a ozkoušení, co a jak se volá je to docela užitečné.
Pokud se tedy takovýto skript umístí do components/1-d+module.js, vyprodukuje při startu Mozilly tenhle výstup do konzole:
js helloworld: toplevel
js helloworld NSGetModule(
[xpconnect wrapped nsIComponentManager @ 0x82f3460 (native @ 0x80c0a18)],
rel:1-d+module.js)
js helloworld moduleQueryInterface(
{00000000-0000-0000-c000-000000000046})
js helloworld moduleRegisterSelf(
[xpconnect wrapped nsIComponentManager @ 0x82f3460 (native @ 0x80c0a18)],
[xpconnect wrapped (nsISupports, nsILocalFile, nsIFile) @ 0x82f1d78 (native @ 0x82ea748)],
rel:1-d+module.js,
text/javascript)
O čem to svědčí? Výpis "toplevel" svědčí o tom, že se skript opravdu vyhodnotil. "NSGetModule" potom ukazuje, že tato funkce má dva argumenty, pro něž jsem ale nenašel žádné použítí. Že objekty v XPCOMu implementují jako společného předka rozhraní
nsISupports s jedinou skriptovatelnou metodou QueryInterface (bez které by se ale zrovna tato ukázka obešla, ale to na věci nic nemění), a že se Mozilla opravdu pokusila zaregistrovat naši komponentu zavoláním registerSelf s rozličnými argumenty. Jak a co budeme registrovat bude příště. Vzhledem k rozložení sil v senátu se ale obávám, že partnerství to nebude ;)
Tiskni
Sdílej:
Záujem tu rozhodne bude a aj keby nebol, pomôžeš tým Abíčku (a svojej peňaženke). Pravdu povediac... pripraoval som ďalšie pokračovania seriálu (odkaz v 1. komentáre), ale vidím, že sa do Mozilly rozumieš lepšie než ja. Počkám, kým začneš seriál publikovať, aby sa nám nekrýžili témy.
Veľa šťastia a chuti do seriálu :)