Vývoj rozšíření pro Firefox

8. 4. 2009 - Zdeněk Malý – Application Developer

Co má společného Firefox a cvičená opice? Firefox také můžete naučit, aby dělal to, co chcete.


Pro webový Prohlížeč Firefox existují stovky rozšíření, které funkcionalitu této Aplikace posouvají daleko za rámec pouhého browseru. A pokud nastane situace, kdy pro požadovanou funkčnost rozšíření neexistuje (nebo nesplňuje vaše očekávání), lze si takový addon jednoduše napsat.

Jediné, co programátorovi stačí k vytvoření vlastního rozšíření, je znalost JavaScriptu a základní znalost XUL (XML User Interface Language), pomocí kterého je definováno GUI Prohlížeče. Vlastní rozšíření je pouze obyčejným ZIP souborem přejmenovaným na XPI (Croxx-Platform Installer Module), který splňuje určité předpoklady.

Jedním z nich je přítomnost správně formulovaného instalačního manifestu, druhým pak vlastní program, na který instalační manifest odkazuje. Pomocí XPI Modulů jsou distribuovány plug-iny (Aplikace schopné zobrazit obsah, s nímž Firefox neumí nakládat – např. Adobe Reader pro čtení PDF), rozšíření (představuje novou funkčnost založenou na nativních knihovnách) a témata (upravují uživatelský interface).

Instalační manifest

XPI musí v kořenu struktury obsahovat instalační manifest pro správce rozšíření ve formátu RDF/XML (do verze Firefoxu 0.9 to byl soubor install.js, od této verze pak INSTALL.RDF) a adresář „chrome“ s Aplikací. Instalační instrukce musí povinně specifikovat tyto vlastnosti:

  • id,
  • version,
  • type,
  • targetApplication,
  • name,
  • updateURL.

id

Id rozšíření musí být unikátní a může být specifikováno jako:

  • řetězec formátovaný jako emailová adresa: jméno@doména.přípona;
  • GUID (Globally Unique Identifier), unikátní číselný identifikátor, který je možné vygenerovat pomocí programu GUIDGEN v registry formátu.

(http://www.microsoft.com/downloads/details.aspx?FamilyId=94551F58-484F-4A8C-BB39-ADB270833AFC&displaylang=en)

<em>
	<em:id>{daf44bf7-a45e-4450-979c-91cf07434c3d}</em:id>
</em>

version

Verze rozšíření:

<em:version>1.0.2</em:version>

type

Číselná hodnota představující typ Aplikace. Rozšíření Aplikace Firefox má hodnotu typu 2. Typ Aplikace (v našem případě mozilla: extension) lze vyjádřit i v elementu popisujícím soubor s vlastním programem.

<em>
	<em:type>2</em:type>
</em>

nebo

<RDF:Description RDF:about="urn:mozilla:install-manifest">
	<em:file RDF:resource="urn:mozilla:extension:file:debugger.jar"/>
</RDF:Description>

targetApplication

Element targetApplication popisuje cílovou Aplikaci (hostitele), pro kterou je rozšíření určeno, včetně její nejnižší a nejvyšší možné verze podporující rozšíření. Konkrétní Aplikace je určena pomocí id ve formátu GUID.

Firefox je registrován pod GUID {ec8030f7-c20a-464f-9b0e-13a3a9e97384}.

Seznam identifikátorů GUID jednotlivých programů a jejich dostupných verzí od společnosti Mozilla najdete na adrese https://addons.mozilla.org/en-US/firefox/pages/appversions.

<em:targetApplication>
	<Description>
		<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <! -- FireFox GUID-->
		<em:minVersion>1.5</em:minVersion>
		<em:maxVersion>3.0.*</em:maxVersion>
	</Description>
</em:targetApplication>

Tip: Je sice doporučeno používat maxVersion jako jednu z dostupných verzí zveřejněnou v seznamu, nicméně - pokud nechce vývojář věnovat zbytečně mnoho úsilí hlídání dostupných verzí a úpravám instalačních manifestů jenom proto, aby předešel možné nekompatibilitě v případě vydání nové verze Prohlížeče - je běžné používání čísel vysokých verzí (např. 9.9). V tomto případě je ovšem nutné ověřovat funkčnost při vydání nové majoritní verze.

name

Jméno Pluginu, které bude v manageru rozšíření zobrazeno uživateli.

<em:name>FGdebugger</em:name>

Tolik výčet povinných parametrů, bez nichž extension manager odmítne nainstalovat rozšíření. Mezi volitelnými vlastnostmi popsanými v manifestu INSTALL.RDF, bude vývojáře určitě zajímat také entita update URL.

updateURL

Tato entita určuje umístění manifestu pro správu verzí rozšíření. Stejně jako instalační manifest obsahuje i aktualizační soubor údaje o verzích a jejich sledu, zdrojových souborech a v případě použití nezabezpečeného https kanálu i informace o integritě dat. O aktualizaci rozšíření bude řeč později.

<em:updateURL>https://www.foo.com/extension/windows.rdf</em:updateURL>

Ukázka struktury Install.rdf

Jednotlivé elementy mohou být v instalačním manifestu install.rdf zapsány v nezkrácené syntaxi, např. takto:

<em:targetApplication>
	<Description>
		<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
		<em:minVersion>0.7</em:minVersion>
		<em:maxVersion>3.1</em:maxVersion>
	</Description>
</em:targetApplication>

Pokud bude rozšíření distribuováno po nezabezpečeném kanálu, je nutné opatřit soubor install.rdf digitálním podpisem, např. pomocí programu McCoy (https://developer.mozilla.org/en/McCoy).

McCoy je Aplikací umožňující vývojářům poskytovat zabezpečená rozšíření, která zaručují, že data programu nebyla od chvíle uvolnění modifikována třetí stranou. Jedním z úskalí použití tohoto programu je fakt, že generuje novou podobu jím podepisovaného souboru do zkráceného tvaru. Navíc si ještě vytváří vlastní značky k popisování závislosti mezi elementy, což ztěžuje porozumění daným souborům. O těchto závislostech se dozvíte v části o aktualizaci rozšíření, kde tato skutečnost patrně vadí nejvíce. Následující úryvek kódu představuje stejný element generovaný pomocí programu McCoy ve zkrácené syntaxi:

<RDF:Description RDF:about="urn:mozilla:install-manifest"
	<em:targetApplication RDF:resource="rdf:#$bnmxI1"/>
</RDF:Description>
<RDF:Description RDF:about="rdf:#$bnmxI1"
	em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
	em:minVersion="0.7"
	em:maxVersion="3.1" /> 

Výsledný soubor install.rdf nutný pro instalaci rozšíření by tedy mohl mít následující strukturu:

<?xml version="1.0"?>
	<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
		xmlns:NC="http://home.netscape.com/NC-rdf#"
		xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

	<-- definice souboru s rozšířením -->
	<RDF:Description RDF:about="urn:mozilla:extension:file:debugger.jar"

	<-- package popisuje složku s aplikací  -->
	em:package="content/debugger/"
	em:skin="skin/classic/debugger/"

	<-- popis rdf souboru který jej definuje jako instalační manifest rozšíření -->
	<RDF:Description RDF:about="urn:mozilla:install-manifest"
		em:id="{F2FF34E5-A290-4491-A2F8-05D51AC06135}"
		em:name="FG debugger"
		em:version="0.1.4"
		em:description="Opens pop-up window using URL derived from current one."
		em:creator="Zdenek Maly"
		em:homepageURL="http://fg.cz"
		em:iconURL="chrome://debugger/skin/fg_mark.gif"
		em:aboutURL="chrome://debugger/content/about.xul"
		em:updateURL="https://fg.cz/slozka_s_rozsirenim/update.rdf"
		<em:file RDF:resource="urn:mozilla:extension:file:debugger.jar"/>
		<em:targetApplication RDF:resource="rdf:#$bnmxI1"/>
	</RDF:Description>

	<-- značka na kterou odkazuje targetApplivation. Zde je řečeno že hostitel rozšíření je FireFox od verze 1.5 do verze 3.1 -->
	<RDF:Description RDF:about="rdf:#$bnmxI1"
		em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
		em:minVersion="0.7"
		em:maxVersion="3.1" />
</RDF:RDF>

Zdrojové soubory

Kromě instalačního manifestu musí distribuce rozšíření obsahovat také data vlastní Aplikace. Ta jsou povinně obsažena v adresáři „chrome“ a soubor s Aplikací musí být přesně specifikován v install.rdf. Zde jsou popsány pouze jednotlivé balíčky, kde správce rozšíření vyhledává soubor contents.rdf, sloužící pouze jako „rozcestník“ ke XUL souborům, které již zahrnují aplikační logiku. Jejich umístění, název a obsah má plně ve svých rukou vývojář.

Contents.RDF

Následující úryvek kódu z install.rdf říká, že v adresáři chrome se nachází balíček debugger.jar, který obsahuje  na cestách /Content/debugger a /Skin/classic/debugger soubory contents.rdf.

<EM>
	<RDF:Description RDF:about="urn:mozilla:extension:file:debugger.jar"
	em:package="content/debugger/"
	em:skin="skin/classic/debugger/" />
</EM>

Zajímavějším pro nás bude contents.rdf v adresáři /Content/debugger, odkazuje totiž na konkrétní soubory s implementovaným rozšířením. Zájemcům o bližší studium doporučuji http://roachfiend.com/archives/2004/12/08/how-to-create-firefox-extensions nebo velice stručný a krátký tutorial http://www.devilsworkshop.o ... tutorial-for-firefox-extensiontoolbar-development, kde je srozumitelně popsáno sestavení a použití XUL souborů.

Kromě cest ke XUL souborům jsou v contents.rdf uvedeny také vztahy těchto souborů k Aplikaci. Rozšíření jsou založena na možnosti dědění vlastností určitého prvku Prohlížeče do nového objektu a doplnění o nové chování. Takto upravený prvek je navrstven na stávající. Za tímto vrstvením stojí právě contents.rdf. Ten obsahuje sadu elementů, z nichž každý identifikuje atribut about sloužící jako značka, na kterou odkazuje jiný element. Každý soubor má svoji povinnou značku (nebo značky), kterou vyhledá parser při zavádění rozšíření. Tyto povinné elementy potom odkazují na ty přidané. Důležitá značka pro contents.rdf je RDF:about="urn:mozilla:package:root", obsahující informace, které budou uživateli zobrazeny při instalaci.

Všimněte si prvku s atributem RDF: about="urn:mozilla:overlays", představující abstraktní vrstvu, kterou můžeme rozšiřovat. Vnitřní element resource potom říká, z jakého objektu bude rozšiřovaná vrstva odvozená. V našem případě má resource parametr hodnotu chrome://Browser/Content/Browser.xul, což je reference na vnitřní rám Prohlížeče (seznam prvků naleznete na http://kb.mozillazine.org/Dev_:_Firefox_Chrome_URLs). Tato hodnota neslouží pouze jako definice vrstvy, kterou budeme rozšiřovat. Zároveň je její pomocí identifikován i prvek, kterým budeme rozšiřovat. To je patrné u elementu s atributem RDF: about="chrome://Browser/Content/Browser.xul”, kde about představuje již pouze značku prvku definujícího rozšiřující soubor (v tomto případě je to chrome://debugger/Content/debuggerOverlay.xul) a na který se odkazuje RDF:about="urn:mozilla:overlays".

Ukázka contents.rdf

<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
	<RDF:Seq RDF:about="urn:mozilla:package:root">
		<RDF:li RDF:resource="urn:mozilla:package:debugger"/>
	</RDF:Seq>
	<RDF:Seq RDF:about="urn:mozilla:overlays">
		<RDF:li RDF:resource="chrome://browser/content/browser.xul"/>
	</RDF:Seq>
	<RDF:Seq RDF:about="chrome://browser/content/browser.xul">
		<RDF:li>chrome://debugger/content/debuggerOverlay.xul</RDF:li>
	</RDF:Seq>
	<RDF:Description RDF:about="urn:mozilla:package:debugger"
		chrome:displayName="RamJet Inspector"
		chrome:author="Zdeněk Malý"
		chrome:authorURL="mailto:malyz@fg.cz"
		chrome:name="debugger"
		chrome:extension="true"
		chrome:description="Opens pup-up window using URL derived from current one">
	</RDF:Description>
</RDF:RDF> 

XUL

Soubory XUL jsou xml soubory, ve kterých je definován způsob použití prvků z jádra Prohlížeče včetně jejich atributů a hodnot. Uvnitř debuggerOverlay.xul je uveden element <overlay> fungující jako kontejner prvků obsažených v rozšíření. Obsah elementu <overlay> se vkládá  do jiného souboru XUL (překrývá jej) ve chvíli, kdy je obsah překrývaného souboru vykreslován do uživatelského interface Aplikace. Do jakého XUL se kontejner vkládá je popsáno v contents.rdf. V tomto případě se jedná o chrome: //Browser/Content/Browser.xul.

V souboru debuggerOverlay.xul jsou popsány prvky (toolbar a jeho buttony, položka v menu Prohlížeče a pop up menu vyvolané pravým tlačítkem), které reagují na události Prohlížeče voláním funkcí JavaScriptu. Funkce je možné rozdělit do několika souborů a každý JavaScript soubor definujeme v XUL obdobně jako v HTML.

Ukázka debuggerOverlay.xul

<?xml version="1.0"?>
<overlay id="FGdebuggerOverlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

	// Takto definujeme soubor javascriptu
	<script type="application/x-javascript" src="chrome://debugger/content/debuggerOverlay.js" />

	// kontejner obsahující toolbary (vertikálně orientovaný)
	<toolbox id="navigator-toolbox">

		//vlastní toolbar
		<toolbar id="TutTB-Toolbar" toolbarname="RamJet Inspector toolbar" accesskey="T"
			class="chromeclass-toolbar" context="toolbar-context-menu"
			hidden="false" persist="hidden">

			//prvek toolbaru
			<toolbaritem flex="0">

			//říká, že prvek je typu button, po stisknutí zavolá funkci showToolbarWindow()
			<toolbarbutton id="Debugger" tooltiptext="FG debugger"
			label="RamJet Inspector" accesskey="I" image="chrome://debugger/skin/fg_mark.gif" oncommand="showToolbarWindow()" />
			</toolbaritem>
		</toolbar>
	</toolbox>

	// vyvolá pop-up menu po stisknutí pravého talčítka
	<popup id="contentAreaContextMenu">

		//přidá položku do popup menu, pokud uživatel položku vybere zavolá funkci showDebugWindow()
		<menuitem id="debugger" label="RamJet Inspector" accesskey="I"
			insertbefore="context-viewpartialsource-selection" oncommand="showDebugWindow()"/>
	</popup>

	// přidá položku do menu prohlížeče, po vybrání zavolá funkci showToolbarWindow().
	<menupopup id="menu_ToolsPopup">
		<menuitem insertafter="devToolsSeparator" label="RamJet Inspector"
		accesskey="F" oncommand="showToolbarWindow()" />
	</menupopup>
</overlay>  

debuggerOverlay.js

Jak již bylo zmíněno, v JavaScript souborech jsou definovány funkce rozšíření, které jsou volány při zachycení událostí (vybrání položky menu, stisk pravého tlačítka atd.). Zde potom začíná opravdová legrace. Programátorovi je dostupná většina objektů (ne-li všechny) z jádra Prohlížeče, což mu dává možnost změnit a rozšířit Prohlížeč zásadním způsobem.

Ukázkový Plugin řešil situaci, kdy bylo třeba v child okně promítnout pozměněné URL z parent okna. K tomu je nutné uchovat referenci child okna v globální proměnné, aby mu mohlo být změněno URL a zavolána metoda refresh(). Pro zabránění otevírání nových a nových oken při opětovném stisku tlačítka volajícího funkci pro otevření okna, použijeme druhou globální proměnnou, v níž bude uloženo URL parenta. Nové okno otevřeme pouze v případě, že je reference na objekt child okna nulová. Pokud nulová není a URL parenta se liší od URL v globální proměnné, provedeme refresh. Reference na okno se vytváří v okamžiku jeho otvírání:

var WindowObjectReference;
var PreviousUrl;
function openWindow(url) {
	//child okno ještě nebylo otevřeno, nebo už bylo zavřeno
	if(WindowObjectReference == null || WindowObjectReference.closed) {

		//do parent okna registrujeme na objekt UrlBaru listener na stisknutí klávesy. Tato událost zavolá funkci checkForEnter(e), kde ji zpracujeme
		document.getElementById("urlbar").addEventListener('keypress', checkForEnter, true);

		//vytvoříme referenci na child okno a otevřeme ho
		WindowObjectReference = window.open(url, "WindowObjectReference");
		return true;  
} //pokud se od minulého volání openWindow nezměnilo url, provede se pouze focus if(PreviousUrl != url){ WindowObjectReference.location = url; WindowObjectReference.focus(); WindowObjectReference.refresh(); } else  { WindowObjectReference.focus(); }; PreviousUrl = url; } 

Tím jsme vytvořili funkci, která při otevření nového okna registruje do rodičovského okna (do urlBaru) posluchač na stisk klávesy a při opětovném volání již pracuje s referencí child okna. Tím ale není zaručeno, že se po zadání nové URL do rodičovského zaktualizuje i obsah  druhého okna. To nám zaručí následující funkce:

function checkForEnter(e){
	// pokud je kód klávesy která vyvolala událost 13 (enter) a reference child okna je nenulová, potom načteme url z parentu a refreshujeme child okno
	if( e.keyCode == 13 && WindowObjectReference != null){
		WindowObjectReference.location= document.getElementById("urlbar").value;
		var title = document.title;
		WindowObjectReference.title = "FG Inspector - " + title;
		WindowObjectReference.refresh();
	}
} 

Kromě posluchače na stisk enteru je třeba také registrovat listener na změnu URL při stisku myši (např. nad odkazem). Bohužel, urlBar sám žádnou takovou událost nemá, takže nezbude nic jiného,  než sáhnout hlouběji do jádra Prohlížeče. To implementuje rozhraní nsIURIContentListener, využívané komponentami, které potřebují znát a umějí nakládat s Content Type (typicky třeba Plugin pro zobrazování pdf v rámu Prohlížeče). Právě implementaci tohoto listeneru je třeba upravit tak, aby při zavádění nového URL zavolala funkci, která načte budoucí URL a zaktualizuje child okno.

Nejdříve definujeme nový listener:

var myListener =
{
	QueryInterface: function(iid){
		if (iid.equals(Components.interfaces.nsIURIContentListener) ||
		iid.equals(Components.interfaces.nsISupportsWeakReference) ||
		iid.equals(Components.interfaces.nsISupports))
		return this;
		throw Components.results.NS_NOINTERFACE;
	},

	// tato funkce je volána při zavádění nového url. Jako parametr přijímá objekt implementující rozhraní nsIURI, a deklaruje součásti URI - <CODE>scheme (ftp/http...)</CODE>, <CODE>userPass, host, port, path, prePath</CODE>
	onStartURIOpen: function(aUri){
		if(WindowObjectReference != null){
			//aUri implementuje nsIURI a atribut spec vraci stringovou reprezentaci URL
			WindowObjectReference.location= aUri.spec;
			var title = document.title;
			WindowObjectReference.title = "RamJet Inspector";
			WindowObjectReference.refresh();
			//return false nechá dokončit proces zavádění nového url. Hodnota true akci zastaví a nová stránka se nenačte. To lze využít třeba ke kontrole le-li stránka na black-listu apod.
			return false;
		}
	},
	doContent: function(aContentType, aIsContentPreferred, aRequest, aContentHandler )
	{
		throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
	},
	canHandleContent: function(aContentType, aIsContentPreferred, aDesiredContentType)
	{
		throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
	},
	isPreferred: function(aContentType, aDesiredContentType)
	{
		try
		{
			var webNavInfo =
			Components.classes["@mozilla.org/webnavigation-info;1"]
			.getService(Components.interfaces.nsIWebNavigationInfo);
			return webNavInfo.isTypeSupported(aContentType, null);
		}
		catch (e)
		{
			return false;
		}
	},
	GetWeakReference : function()
	{
		throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
	}
} 

Tak. Referenci listeneru, který na stisknutí levého tlačítka refreshuje child okno máme uloženou v proměnné myListener. Nyní zbývá pouze nahradit původní implementaci nsIURIContentListeneru tou naší:

window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
	.getInterface(Components.interfaces.nsIWebNavigation)
	.QueryInterface(Components.interfaces.nsIDocShell)
	.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
	.getInterface(Components.interfaces.nsIURIContentListener).parentContentListener = myListener; 

Updatování rozšíření

Pokud je v instalačním manifestu odkaz na aktualizační soubor, kontroluje správce rozšíření, je-li dostupná nová verze. Záznam o umístění seznamu aktualizací je v install.rdf definován takto:

<RDF:Description RDF:about="urn:mozilla:install-manifest"
	em:updateURL="https://fg.cz/nova_verze_rozsireni/update.rdf"
</RDF:Description>

Ale! Firefox třetí řady nastolil novou bezpečnostní politiku nejen při updatování rozšíření, čímž se nám věci trochu zkomplikovaly. Předchozí záznam by byl dostatečný za předpokladu, že se bude aktualizační manifest i soubor s rozšířením přenášet po https. Pokud tomu tak není, je třeba do instalačního manifestu vložit digitální podpis pro soubor s rozšířením a další digitální podpis (tentokrát nazvaný jako updateKey) do hlavní části manifestu. Obojí umožňuje již zmiňovaný program McCoy, který vytvoří certifikát pro podpis souboru i manifestu. K vložení updateKey slouží funkce INSTALL, podepsání souboru JAR se provede pomocí funkce SIGN. Porovnejte si předchozí definici pro aktualizaci s tou následující:

<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
	xmlns:NC="http://home.netscape.com/NC-rdf#"
	xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
	<RDF:Description RDF:about="urn:mozilla:extension:file:debugger.jar"
		em:package="content/debugger/"
		em:skin="skin/classic/debugger/"
		em:signature="MIGTMA0GCSqGSIb3DQEBDQUAA4GBAAy+6FCYd0vgkouZJtwrlm04C9AfkXo5jW/rwIZG5RKODdwz5wSHqhs4VgIBOdVnhLbbWoBkLpkFsI8n3N0iz1PXsQbcwQY7f2zDhndRD7R73eZ48Gjo5FMKFIOWArWkjbDsJMyac36RI6jqcMhs5bjDtWe3Q+xuXUGZAW/ydlpi" />
	<RDF:Description RDF:about="urn:mozilla:install-manifest"
		em:updateURL=" http://fg.cz/nova_verze_rozsireni/update.rdf"
		em:updateKey="MIGfMA0GCSqGSIb3DwEBAQUAA4GNADCBiQKBgQDFT1qZHAlC+mS8z01jh0qPzeeXNnIlV+UPBRT64D1u18xaAPzVUdGBBSVVFwTjRL2qz9utECOgkNVSjjy/v6sWy7cFPVsxW/uwB2rkecaVJcFhgh9JpH08cWsX7hEUUz2Iy+n/pG6EZ0wbN9L9wxDu0muFPd3H+lKQd5gs9OgarwIDAQAB">
</RDF:RDF> 

Tím ale naše zábava zdaleka nekončí. Je totiž potřeba zabezpečit i samotný aktualizační manifest. Program McCoy má tu nepříjemnou vlastnost, že při podepisování jak instalačního, tak aktualizačního manifestu přegeneruje jejich podobu do téměř nečitelného formátu. Není sice problém se v něm po čase zorientovat, ale systém interních značek a odkazování se na ně prodlužuje dobu, která je nutná k uvedení nové verze do update rdf. Samotné soubory s aktualizací před stažením podléhají kontrole. V tomto případě je nutné vypočítat hash kód souboru (např. pomocí programu HashCalc – http://www.slavasoft.com/hashcalc/) a vložit ho do elementu updateHash. Před vlastní hodnotu hashe je nutné uvést, jakým algoritmem byl spočítán. Podporovanými algoritmy jsou sha1, sha256, sha384 a sha512.

Vzhledem k tomu, že na internetu existuje mnoho tutorialů, které se zabývají aktualizací rozšíření po zabezpečeném kanále (velké množství rozšíření je hostováno na https://addons.mozilla.org, kde problémy s podepisováním odpadají), následující ukázka aktualizačního manifestu update.rdf se týká pouze přenosu po nekódovaném http protokolu. Všimněte si neuspořádaného pořadí elementů a odkazových značek, o kterých již byla řeč:

<?xml version="1.0"?>
<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
	xmlns:NC="http://home.netscape.com/NC-rdf#"
	xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

	<-- element Seq představuje seznam aktualizací, jednotlivé li jsou konkrétní verze. Jejich ID musí být unikátní, proto se za GUID přidává dvojtečka a verze rozšíření -->
	<RDF:Seq RDF:about="rdf:#$zSjc91">
		<RDF:li RDF:resource="urn:mozilla:extension:{F2FF34E5-A290-4491-A2F8-05D51AC06135:1.0}"/>
		<RDF:li RDF:resource="urn:mozilla:extension:{F2FF34E5-A290-4491-A2F8-05D51AC06135:1.1}"/>
	</RDF:Seq>

	<-- tento element popisuje soubor s aktualizací a je na něho odkazováno se seznamu Seq-->
	<RDF:Description RDF:about="urn:mozilla:extension:{F2FF34E5-A290-4491-A2F8-05D51AC06135:1.1}"
		em:version="1.1"
		<-- updateLink je URL soubor s aktualizací-->
		em:updateLink=" http://fg.cz/nova_verze_rozsireni/FGdebugger2.xpi"

		<-- kontrola updateHash že soubor nebyl od bydání nikým změněn-->
		em:updateHash="sha1:411c4dc8c6c539464377f01163a17e9843eb4861"

		<-- digitální podpis aktualizace-->
		em:signature="MIGTMA0GCSqGSIb3DQEBDQUAA4GBAG2ZNs9NLWjUociaIpw+xWKifAuCDu1bSA2X5V0j4CK/Qrkv5ozjk8g+JRQb8RbEoq+JSY85oKhx+f2OrsZ7lmFhijditra83gpBBdK5UuysNAx1UYsQa/MV4vG/3ywKSkSKMOjCHEyOmKyrXvZTb21owTFhje8htPtVRjoWOwWG" >

	<-- toto je kořenový prvek update.rdf který říká, že aktualizace se týkají aplikace s GUID F2FF34E5.. což je naše rozšíření -->
	<RDF:Description RDF:about="urn:mozilla:extension:{F2FF34E5-A290-4491-A2F8-05D51AC06135}"

		<-- digitální podpis instalačního manifestu -->
		em:signature="MIGTMA0GCSqGSIb3DQEBDQUAA4GBAKlyCQLN43S73HIONb5JtPn2J7QxtWjZMY5nLa98EWxKjbO0Lp5j8vkvyRt+fCywEjTcTNnlX9K6MBI+zQsiDZmyZULVM9HT/IA2cKlsCZaQsN78e6B7PnzOXqqHK4CVPF8/lo4CSj1FHoPIdYoFqm0lwRITJmmQ8OViCf8OcEuv">

		<-- odkaz na seznam aktualizací -->
		<em:updates RDF:resource="rdf:#$SFWIU3"/>
	</RDF:Description>
</RDF:RDF>  

Důležité při sestavování aktualizace je vlastní pořadí kroků. Při nesprávném postupu může nastat problém s ověřováním integrity souborů aktualizace, nebo pravosti některého z manifestu. Při releasu nové verze je nutné postupovat takto:

  • zabalit obsah složky chrome do JAR souboru,
  • upravit verzi v install.rdf,
  • spočítat hash JAR souboru a vložit do updateHash,
  • podepsat manifest a soubor (INSTALL a SIGN v McCoy),
  • vytvořit nové XPI a umístit na server,
  • upravit update.rdf – zkopírovat blok s definicí souboru rozšíření, upravit pro nové hodnoty, zavést do seznamu aktualizací odkaz na tento nový blok,
  • podepsat update.rdf.

Pokud vás neodradilo ani tohle, dám vám malou radu nakonec. Správce rozšíření je velice skoupý na poskytování chybových hlášek. I to málo je nakonec lepší než nic. Pokud chcete v chybové konzole (Ctrl+Shift+J) zobrazovat hlášky týkající se rozšíření, napište do addressbaru „about:config“ a po potvrzení stupidní hlášky vyhledejte extensions.logging.enabled a nastavte na true.

Zdroje


Potřebujete...

... profesionální webovou prezentaci?

Realizujeme firemní weby, rozsáhlé portály i stručné microsites.

  • Analýzy a testování
  • Špičkový design
  • Tvorba struktury, textů nebo videa
  • Systém pro správu obsahu

Více informací

... efektivně komunikovat uvnitř firmy?

Komplexně zajistíme efektivní intranetové řešení.

  • Návrh business procesů
  • Systém pro správu obsahu
  • Personalizovaný přístup
  • Integrace s dalšími systémy

Více informací

... úspěšnou on-line kampaň?

Proměníme návštěvníky internetu v zákazníky.

  • Microsites a hry
  • E-mail a mobilní marketing
  • Videa pro internet
  • Multimediální CD a DVD

Více informací

FG Tipy

Internet už používá 53 % české populace.

Získejte mezi nimi nové zákazníky - nabídka je široká!

Zkušenost s nákupem on-line má více než čtvrtina Čechů starších 15 let.

Prodávejte na internetu - přes weby a portály!

3 ze 4 uživatelů se díky vyhledávačům seznamují s novými značkami. Většina značku považuje za kvalitní a významnou, pokud ji vyhledávač uvede na přední pozici.

Vyzkoušejte on-line marketing!

Reklamní hry, které mají tématickou návaznost na značku, výrazně pomáhají utvářet pozitivní vztah se zákazníky.

Získejte si náklonnost internetových uživatelů originální on-line kampaní!

Způsob čtení z webu je specifický. Internetový čtenář je nedočkavý a text vstřebává nesouvisle.

Nepodceňujte to - objednejte si profesionální weby a portály!

Mobilní telefon používá 89 % obyvatel ČR ve věku nad 15 let.

Vyzkoušejte mobilní marketing!

Názor na web si uživatel utvoří během první vteřiny návštěvy. Do 30 vteřin odejde, pokud není spokojen. Ve 4 případech z 10 se už nevrátí.

Objednejte si profesionální webová řešení!

Polovina aktivních uživatelů před nákupem běžně hledá informace o produktu na internetu.

Udržujte svůj web aktuální - pomocí Edee CMS!

Internet patří mezi nejvýznamnější zdroje informací o produktech a značkách. Dle mnoha výzkumů jej uživatelé v tomto směru řadí už na 2. místo.

Internet vám získá nové zákazníky - objednejte si profesionální web!

Správná vnitrofiremní komunikace nejen podporuje týmovost a výkonnost zaměstnanců. Výrazně ovlivňuje úspěch celé společnosti.

Komunikujte se zaměstnanci rychle, efektivně a zábavně - pomocí intranetu!


Odběr článků

odebírat přes RSS

Tiskové zprávy

Tiskové zprávy o nás a našich projektech.

Čtěte

2