XUL, maščevanje plazilca
Odpiranje programov v splet je nadvse priljubljeno, žal pa spletni brskalniki niso bili nikoli namenjeni izvajanju resnih programov. Dokler ni prišel XUL.
Res, spletni brskalniki so - kot pove že njihovo ime - namenjeni brskanju po spletu, ki ga sestavljajo predvsem oblikovani dokumenti, torej besedilo in slike. S ključno inovacijo podjetja Netscape: spletnim obrazcem (web form), ki omogoča pošiljanje podatkov nazaj v strežnik, se je odškrnila možnost razvoja spletnih programov. Od takrat splet ni bil več enak, spletni mojstri pa so bili zasuti s tehnologijami in rešitvami, ki naj bi jim omogočile razvoj rešitev, primerljivih z visoko zmogljivimi programi, ki jih uporabljamo na namizju osebnega računalnika.
Najprej je prišla java, a je bila za kaj več kot animirano "prevračanje kopic" preokorna. Razvijalci so se je v spletnih brskalnikih naveličali, preden je dosegla uporabno zmogljivostno raven. Potem sta prišli dve nezdružljivi ponudbi dinamičnega HTML, Microsoftov in Netscapov. Zmeda ne bi mogla biti večja in še danes ni mogoče razviti malo bolj zapletenega programa za splet, ki ne bi preverjal vrsto brskalnika. Pisanje kode, ki bi delovala povsod, je resnično preizkušanje potrpljenja.
Obet boljših časov je bil Netscapov odločen prelom s staro kodo in rojstvo projekta Mozilla, katerega cilj je bil povsem nov rod spletnega brskalnika. Čeprav je bila "vojna brskalnikov" že končana, je Mozilla vztrajno pridobivala zmogljivosti z jasnim ciljem: postati spletni brskalnik, najbolj skladen s standardi konzorcija W3C. W3C že dolgo poizkuša uveljaviti podrobno določene standarde, ki bi lahko olajšali razvoj spletnih programov, žal pa tržna prevlada enega samega brskalnika ni ravno okolje, v katerem bi lahko W3C s svojimi pobudami uspelo.
Na srečo so brskalniki z majhnimi tržnimi deleži preživeli in se jim obeta lepa prihodnost. Norveška Opera je našla svoje mesto predvsem v prenosnih napravah, v okolju KDE je na voljo visoko zmogljiv Konqueror, ki je tudi osnova Applovega Safarija, s katerim je v sistemu MacOS nadomestil Microsoftov brskalnik. Trenutno verjetno najboljši brskalnik pa je sveža Mozilla, trenutno v različici 1.6, ki prinaša obljubljeno - najboljšo podporo spletnim standardom, neodvisnost od podlage, odprto kodo, predvsem pa široko skupnost razvijalcev, ki ne sodelujejo le pri razvoju same Mozille, temveč na njej gradijo nove rešitve. To jim omogoča XUL.
Pomen uporabniškega vmesnika
Spletne strani so zelo priljubljene tudi zaradi preprostosti HTML, s katerim lahko hitro sestavimo za oko privlačne uporabniške vmesnike, ki delujejo na najrazličnejših napravah. Žal programa zgolj s HTML ne moremo razviti. Številni razvijalci porabijo vse preveč časa za zunanjo podobo namesto za ključno funkcionalnost programa. Lišp je včasih celo pomembnejši od uporabne vrednosti. Težava pri današnjih orodjih, ki omogočajo razvoj spletnih vmesnikov, neodvisnih od podlage, je tudi previsoka sklopljenost vmesnika in programske logike. Sprememba enega skoraj vedno povzroči tudi popravljanje drugega.
Razvoj spleta je dokazal, da je mogoče z označevalnimi jeziki hitro graditi zmogljive uporabniške vmesnike. Mar ne bi bilo lepo, ko bi lahko tudi namenskim programom določili vmesnik kar s pomočjo HTML? To je osnovna zamisel XULa, označevalnega jezika za uporabniške vmesnike (eXtensible User interface Language, izg. zul).
XUL je še eno izmed narečij priljubljenega XML, nastal pa je v projektu Mozilla kot orodje za opis uporabniških vmesnikov, ki ni odvisno od podlage, na kateri se program izvaja. Uspešnost XULa dokazuje sama Mozilla, katere vmesnik je pravzaprav v celoti določen z njim, vse, kar dobi od operacijskega sistema, je prazna površina glavnega okna. Menuji, orodjarne, seznami, e-nabiralniki in spletne strani - vse to upodabljajo gradniki XUL. Ker je XUL narečje XML, je uporabniški vmesnik odprt, urejamo pa ga lahko navsezadnje s preprostim urejevalnikom besedila, saj je njegov zapis človeku berljiv.
Okvirček: Priljubljene pošasti
Razvijalci Mozille imajo očitno zelo radi filme z različnimi pošastmi. Japonsko zverino so uporabili za navdih pri imenu projekta, "zul" pa je seveda kratica, nastala po zgledu iz Preganjalcev duhov. Če je kdo v dvomih, si lahko prebere oznako imenskega prostora, ki mora biti sestavni del vseh dokumentov v XUL:
http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul.
Če vam ta naslov nič ne pove, potem je čas, da si (znova?) ogledate priljubljeni nadvse zabaven film iz 80. let.
Značilnosti XULa
Razvijalci, ki spoznajo XUL, zagotovo cenijo njegovo usmerjenost k znanim in sprejetim spletnim standardom. Še bolj navdušeni bodo nad izborom gradnikov, saj imamo na voljo praktično vse, kar si zaželimo, od preprostega gumba do vizualnega spletnega urejevalnika. Ne pozabimo - čisto vsi sestavni deli Mozille (brskalnik, odjemalec za e-pošto, klepetalnica, urejevalnik, prihaja tudi koledar) so zgrajeni s pomočjo XULa.
Neodvisnost in razslojenost
Dve najpomembnejši prednosti XULa sta neodvisnost od programske podlage in razslojenost, ki nam omogoča, da sloje neodvisno posodabljamo in spet uporabljamo v drugih projektih. Sloje programa v XULu ponazarja slika 1.
Programi v XUL so jasno razslojeni, kar omogoča učinkovito sodelovanje ekip, ki se osredotočijo na svoje področje in sodelujejo z okolico prek dobro definiranih spletnih strandardov, kot so XML, DTD ali CSS.
Razslojenost ugodno vpliva tudi na kakovost izdelka, kot je Mozilla. Majhne skupine razvijalcev se lahko ukvarjajo s svojim slojem, ne da bi rušile trud drugih ekip, ki posodabljajo sloje na višji ali nižji ravni.
Standardni zapisi
XUL je načrtovan tako, da izkorišča druge spletne standarde, kot so XML 1.0 kot temeljno obliko zapisa, HTML 4 za osnovno in CSS 1 ter 2 za naprednejše oblikovanje, DOM za predmetni opis vmesnika, RDF za opis sredstev (resources), javascript 1.5 (zajema ECMAscript 3) za pisanje povezovalne kode ter XBL (eXtensible Binding Language), še eno narečje XML, namenjeno razvoju novih gradnikov. Podprta sta tudi SVG za grafiko in MathML za znanstvene dokumente. Izkušeni načrtovalec spletnih vmesnikov lahko XUL osvoji v kratkem času, saj je naravna nadgradnja standardov, ki jih uporablja že pri izgradnji spletnih strani.
Mozilla je specifikacijo povezovalnega jezika XBL predala organizaciji W3C, tako da bo tudi ta element XULa najverjetneje kmalu standardiziran.
Novi gradniki
Tudi če v pestrem naboru gradnikov XUL in HTML, ki jih je mogoče združevati v uporabniške vmesnike, ne najdemo rešitev našega problema, lahko uporabimo XBL, s katerim lahko izdelamo lastne gradnike tako, da zdajšnje prvine med seboj povežemo in dopolnimo ali pa kar v celoti izgradimo sami, npr. s pomočjo grafičnih datotek in programske kode v javascriptu.
Prekrivki
Ker je XUL preizkušen v praksi prav pri njegovih tvorcih, v njem najdemo vse polno zelo uporabnih zamisli. Ena izmed najpomembnejših so prekrivki (overlays). Z njimi lahko na enem mestu opišemo elemente, ki jih bomo v uporabniškem vmesniku pogosto uporabljali, npr. orodjarno z osnovnimi opravili urejanja (izreži, prilepi, razveljavi).
Spodaj je zgled prekrivka v XUL:
<?xml version="1.0"?>
<overlay id="orodjarna1"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<toolbarbutton id="gumbNova" class="gumbOrodjarne" tooltiptext="Nova datoteka" oncommand="fnNovaDatoteka()" label="Nova"/>
</overlay>
Gre za klasično datoteko XML, v kateri določimo imenski prostor (http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul). Mozilla ga ne bo prenašala iz spleta, saj ga prepozna interno in obravnava ustrezno oznako kot narečje XUL. Oznaka <overlay> določa prekrivek, v katerega smo za zgled uvrstili gumb orodjarne, tega določa oznaka <toolbarbutton>. XUL opisuje le hierarhijo dokumentov, njihov videz in obnašanje pa je (lahko) določeno drugje, s slogi in preoblekami (skins) ter kodo v javascriptu. Razslojenost XULa omogoča, da programu zlahka spremenimo zunanjo podobo, ne da bi posegali v kodo XUL (zgled so preobleke za samo Mozillo).
Če bi zgoraj navedeni zgled shranili v datoteko z imenom mojaOrodjarna.xul, bi prekrivek lahko uporabili v drugih vmesnikih s preprosto vključitvijo datoteke:
<?xul-overlay href="mojaOrodjarna.xul"?>
Na želenem mestu pa bi dodali prej določeno orodjarno z oznako:
<toolbarbutton id="orodjarna1" />
Vse druge nastavitve so že določene v prekrivku. Seveda bi bil lahko prekrivek precej bolj zapleten. XUL nam omogoča, da prekrivek vključimo v celoti ali pa izkoristimo le njegov del. Na ta način je vzdrževanje kode silno poenostavljeno, saj podvajanje elementov v nobenem primeru ni potrebno, še posebej, ker lahko prekrivke delimo med projekti.
GPL ali ne?
Prekrivki so pomembni tudi za uporabnike XUL, ki jih morda skrbi, da bodo zaradi uporabe proste kode morali obelodaniti tudi kodo lastne aplikacije. Dovoljenji NPL in MPL, po katerih se Mozilla razpečuje, dopuščata razširjanje zmogljivosti s pomočjo prekrivkov, ne da bi bili prisiljeni te razširitve tudi objaviti v obliki izvirne kode.
Lokalizacija
Za nas silno pomembna lastnost XULa je možnost popolne jezikovne prilagoditve. Mozillo lahko npr. prevedemo v številne jezike preprosto tako, da iz spleta prenesemo lokalizacijski paket, ki je pravzaprav le seznam besed. Isto možnost lahko izkoriščajo naši izdelki, katerih vmesnike lahko z lahkoto prevedemo v poljubno število jezikov. XUL za lokalizacijo izkorišča format DTD (Document Type Definition), ki je sicer sprejet kot spletni standard za opisovanje skladnje.
Podatki
XUL omogoča razvoj predlog, ki izkoriščajo standardni jezik za opis sredstev v spletu, RDF (Resource Description Framework), s pomočjo katerega se lahko dinamično priklopimo na najrazličnejše vire podatkov, jih prebiramo, pa tudi zapisujemo vanje.
Programski gradniki
Spletni standardi, ki jih izkorišča XUL, so neodvisni od podlage, vendar programski jezik javascript ne zadošča za razvoj visoko zmogljivih programov. Mozilla zato prinaša dva pripomočka: XPCOM in XPConnect. Platformsko neodvisni programski gradniki (Cross Platform Components) so sestavni del podlage, ki izvaja namenske programe v XULu. Če je to Mozilla, imamo na voljo bogato knjižnico, lahko pa se XUL izvaja tudi v drugačnem okolju. Pomembno je le, da to vsebuje knjižnico za upodabljanje Gekon (Gecko, tako okolje je nastajajoči GRE, Gecko runtime Environment), ki je pogoj za izkoriščanje XULa. Gradnike XPCOM lahko razvijemo v številnih programskih jezikih (C, C++, javascript, python, perl...), vendar jim moramo najpogosteje pripraviti ločeno za vsako podlago, na kateri želimo poganjati naš program.
Ko je gradnik pripravljen, pa se na vseh podlagah izkorišča enako. XPConnect je tehnologija, ki omogoča neproblematično izkoriščanje gradnikov XPCOM v prenosljivi kodi javascript. Zgled programa v XUL, ki izkorišča XPCOM, je koledar za Mozillo. Velika večina ga je izdelana v popolnoma prenosljivem XULu, delček kode pa je vsebovan v gradniku XPCOM, razvitem v jeziku C, ki je preveden v ločenih različicah za Unix, Okna in MacOS.
Koledar
Podjetje Oeone (http://www.oeone.com/) je na temelju Mozille izdelalo celovito namizje za osebne računalnike, ki jih poganja Linux. S pomočjo XULa so razvili visoko zmogljiv program, ki omogoča delo z internetom (brskanje, e-pošta, takojšnje sporočanje), urejanje dokumentov, pregledovanje večpredstavnih datotek, spremljanje in snemanje tv programa in urejanje koledarja. Koledar so podarili projektu Mozilla, kjer se počasi izpopolnjuje in bo verjetno postal sestavni del skupka. Čeprav je bil razvit za Linux, so ga zaradi XULa lahko v nekaj dneh prenesli v Okna in MacOS. Poglavitna težava je bil drobec kode, ki se je uporabljal kot gradnik XPCOM. Ker uporabljena programska knjižnica ni bila na voljo za Okna, so jo razvijalci OEOne tja prenesli sami.
http://www.mozilla.org/projects/calendar/
Preprosta namestitev
Programi v XULu so pri uporabniki priljubljeni tudi zaradi preproste namestitve. XPInstall je mehanizem, ki omogoča namestitev z enim samim klikom. V paketu (prepoznamo ga po končnici .xpi) se skrivajo vse potrebne datoteke in namestitveni postopek, ki se izvede na strani odjemalca po prenosu celotnega paketa.
XPInstall omogoča preprosto prilagajanje Mozille, z njegovo pomočjo lahko nalagamo nove preobleke, prevode in dodatke, ki se samodejno namestijo.
XUL v praksi
Da predstavitev XULa ne bo zgolj naštevanje njegovih lastnosti, si bomo ogledali še praktične zglede preprostega programa v njem. Skozi njegov razvoj se bomo s tem zmogljivim orodjem pobliže spoznali, kar nam bo omogočilo nadaljnje raziskovanje in prilagajanje.
Preden se lahko lotimo dela, moramo namestiti Mozillo, ki je najprimernejše orodje za igračkanje z XULom. Poleg tega, da je njen uporabniški vmesnik v celoti izdelan z njim, kar nam ponuja čudovito priložnost za igranje, prilagajanje in spoznavanje te tehnologije, ima Mozilla cel kup orodij, ki olajšajo razvoj. Predvsem je pomemben visoko zmogljiv razhroščevalnik javascripta (Venkman, tudi njegov vmesnik je v XULu) in pregledovalnik predmetne strukture poljubnega okna (model DOM ne opisuje le spletnih strani, temveč tudi vse vmesnike v XULu).
Pozdravljen, svet!
Začeli bomo z najpreprostejšim in tudi najbolj zlajnanim zgledom:
<?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" title="Pozdrav">
<description value="Pozdravljen, svet!" style="font: bold 16pt monospace"/>
</window>
Zgornja datoteka XML spet opiše element uporabniškega vmesnika, kot ga določa narečje XUL. Gradnik, ki ga ponazarja oznaka <window>, je samostojno okno, vanj pa smo dodali izpisano besedilo s pomočjo oznake <description>. Tej smo za začimbo dodali še slog, zapisan v CSS. Vsebino shranimo v datoteko s podaljškom .XUL.
Če imamo nameščeno Mozillo, je ta najverjetneje prijavljena za obravnavo tovrstnih datotek, zato lahko primerček preizkusimo kar z zagonom te datoteke. Na sliki 2 vidimo zgled v Mozilli 1.6 s preobleko Orbital. Vsebina datoteke XUL je prikazana kot spletni dokument na sredini okna, preostanek je običajna Mozilla. Datoteke torej nismo pognali kot pravi program, temveč jo pregledujemo kot nekakšen spletni dokument, kar je zelo koristen način preizkušanja.
Paketi
Preden lahko z XULom izdelamo pravi program, moramo spoznati pakete. Datoteka XUL je namreč le temeljno vezivo programa, ki ga v celoti določajo tri skupine datotek ali paketi. Paketi lahko določajo vsebino, preobleko in prevod programa. Obvezni paket je le vsebina (content), ki poleg temeljnega veziva v glavni datoteki XUL vsebuje še druge gradnike v XULu, programsko kodo v datotekah z javascriptom, temeljne sloge CSS, grafične datoteke in podobno.
Paket s preobleko (skin) nam omogoča, da obliko izločimo in s tem omogočimo spreminjanje videza brez poseganja v paket z vsebino.
Prevod (locale) je paket, ki vsebuje vse nize besedila, uporabljene v vsebini, s pomočjo simboličnih povezav. Različni prevodi nam omogočajo, da program v XULu v trenutku prevedemo v poljuben jezik.
Pakete moramo urediti s pomočjo map oz. imenikov na disku. Položaj in ime map sicer ni vnaprej določeno, a je koristno, da se držimo dogovorjenih pravil. Naš zgled bomo razvijali znotraj izhodiščne mape chrome/, ki jo najdemo v mapi, v katero smo namestili Mozillo.
Naš zgled bo omogočal urejanje zapiskov, zato ga bomo uvrstili kar v podmapo z imenom zapiski. Znotraj nje bomo pripravili še dve podmapi, za paketa vsebine in prevodov. Celotna struktura map je ponazorjena spodaj:
chrome
zapiski
content
zapiski
locale
sl-SI
zapiski
en-US
zapiski
Očitno bomo pripravili dva prevoda in eno vsebino. S preobleko se ne bomo ukvarjali, ker bomo izkoristili kar tisto, ki jo uporablja sama Mozilla.
Izhodiščni XUL
Najprej bomo poskrbeli za vezivo. V paketu vsebine, znotraj mape content/zapiski, bomo pripravili temeljno datoteko XUL. Njeno ime je enako imenu programa, torej v našem primeru zapiski.xul. Njena analiza sledi.
Začeli bomo po navadi:
<?xml version="1.0"?>
<?xml-stylesheet href="zapiski.css" type="text/css"?>
Znova pripravljamo datoteko XML, tokrat pa smo ji priključili še zunanji slog, ki ga bomo našli v isti mapi, v datoteki zapiski.css.
<?xul-overlay href="chrome://zapiski/content/zapiskiMenuOverlay.xul"?>
Menuji našega programa ne bodo vključeni v osnovni datoteki XUL, temveč jih bomo pripravili kot prekrivek. S tem bomo razbremenili osnovno datoteko in omogočilo uporabo menuja na več mestih, če bo to kdaj potrebno. Opazimo lahko, da smo pot do vira navedli s posebnim določilom, ki ga bomo podrobneje spoznali ob naslednji vrstici:
<!DOCTYPE window [
<!ENTITY % zapiskiDTD SYSTEM "chrome://zapiski/locale/zapiski.dtd">
%zapiskiDTD;
]>
V nadaljevanju vključimo prevode. XUL za tovrstne vire uporablja standard DTD. Spet smo uporabili naslavljanje vira s pomočjo "protokola" chrome. Viri, ki jih označuje krajevnik vrste chrome, so pripravljeni prav za razslojeno naravo XULa. Pot //zapiski/locale/ tako ne predstavlja vnaprej določene mape, temveč je odvisna od izbranega prevoda. Če bomo naš program uporabili v angleški različici, bo XUL uporabil datoteko zapiski.dtd iz mape en-US paketa prevodov, v primeru slovenščine pa iz mape sl-SI. Datoteke XUL pa nam ne bo treba nikoli spreminjati. Niti če bomo dodali nove prevode.
<window
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id = "zapiski-main-window"
title = "&window.title;"
width = "400"
height = "300"
orient = "vertical"
persist = "screenX screenY width height">
Sledi naš znanec iz prvega zgleda, oznaka <window>. Tokrat ima kar precej določil. Poleg imenskega prostora, ključnega določila, ki opredeljuje narečje XML, še enolično oznako (id), naslov okna (title), dimenzije ter orientacijo (width, height, orient), zadnje določilo (persist) pa našteva lastnosti, ki jih bo izvajalni sistem samodejno ohranjal med sejami. Našteli smo položaj in velikost okna. Naše okno za zapiske bo torej ob vnovičnem obisku natančno tako, kot ga bomo prej pustili.
Naslova okna nismo zapisali neposredno, temveč bomo uporabili prevod s simboličnim imenom window.title (zato tudi zapis kot entiteta DTD, v obliki &<simbolično ime>;), dejansko besedilo bo določeno z veljavnim prevodom.
<script
type="application/x-javascript"
src="zapiski.js"/>
Čeprav bi lahko v osnovno datoteko XUL vključili tudi kodo v javascriptu, bo te preveč, pa tudi pregledneje je, če jo izločimo v zunanjo datoteko. Ta bo v isti mapi.
<toolbox id="main-toolbox">
<menubar id="menu"/>
</toolbox>
<textbox id="zapisek" multiline="true"
flex="1" oninput="zapiskiDirty();"/>
</window>
Dokončno smo izgradili vmesnik tako, da smo dodali orodjarno (v njej bo pravzaprav prekrivek z menujem) in glavni gradnik, okvir za vnos besedila (<textbox>), ki smo mu priredili enolično ime zapisek, vklopili vnos v več vrsticah, poskrbeli, da zasede ves razpoložljivi prostor v oknu (flex="1"), za povrh pa dodali še nekaj programske kode, ki bo spremljala, ali se je vnos v okviru spremenil. Ker mora biti datoteka XUL lepo vzgojen XML, moramo zapreti vse odprte oznake, torej tudi glavni vsebnik našega programa, gradnik <window>.
Prijava
Da bi naš program pravilno deloval, ga moramo tudi prijaviti v register izvajalnega okolja, v našem primeru Mozille. V ta namen XUL izkorišča priljubljeni spletni standard RDF, s katerim izdelamo ti. manifest, ki mora biti shranjen v datoteki z imenom contents.rdf. Za naše potrebe je njena vsebina naslednja:
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<RDF:Seq about="urn:mozilla:package:root">
<RDF:li resource="urn:mozilla:package:zapiski"/>
</RDF:Seq>
<RDF:Description about="urn:mozilla:package:zapiski"
chrome:displayName="Zapiski - preprost urejevalnik"
chrome:name="zapiski">
</RDF:Description>
<RDF:Seq about="urn:mozilla:overlays">
<RDF:li resource="chrome://communicator/content/tasksOverlay.xul"/>
</RDF:Seq>
<RDF:Seq about="chrome://communicator/content/tasksOverlay.xul">
<RDF:li>chrome://zapiski/content/zapiskiOverlay.xul</RDF:li>
</RDF:Seq>
</RDF:RDF>
Tudi zapis RDF je narečje XML, tokrat pa uporabimo dva imenska prostora, temeljni RDF, ki ga opisuje dokument http://www.w3.org/1999/02/22-rdf-syntax-ns#, ter Mozilli specifični chrome, tega določa http://www.mozilla.org/rdf/chrome#. V osnovi so si vsi manifesti podobni, zato se ne bomo zapletali v podrobnosti. S krepko pisavo smo označili pomembne elemente, ki jih od primera do primera spreminjamo. Določili smo pot in opis paketa z vsebino, da ga Mozilla lahko najde, dodali pa smo še prekrivek iz paketa communicator. XUL nam omogoča, da prekrivke preprosto izmenjujemo med paketi. Prekrivek tasksOverlay bo našemu programu omogočil, da na svojem menuju ponudi tudi segment glavnega menuja Mozille.
Slog
Naš zgled ne bo imel posebnega paketa s preobleko, temveč bomo videz določili v eni sami datoteki CSS, ki smo jo že navedli v temeljni datoteki XUL, vsebina datoteke zapiski.css pa je:
@import url("chrome://communicator/skin/");
#zapisek
{
font-family: monospace;
font-size: 12pt;
}
Preprosto smo uvozili preobleko, ki jo pač uporablja Mozilla (krajevnik chrome: bo spet poskrbel, da se bo vedno uporabila aktualna preobleka), in dodatno poskrbeli zgolj za delček sloga glavnega okvira z urejevalnikom opomb.
Prekrivki za menu
Oglejmo si še izvlečke prekrivkov. Naš menu bo kombinacija lastnega menuja in sistemskih menujev Mozille. Določimo ga v nekaj skupinah. Prva je opis ukazov, ki jih združimo v skupini <comandset>:
<commandset id="maincommands">
<command id="cmd_undo"/>
<command id="cmd_redo"/>
...
<commandset id="tasksCommands"/>
<command id="menu-file-open:command" oncommand="zapiskiFileOpen();"/>
<command id="menu-file-save:command" oncommand="zapiskiFileSave();"/>
<command id="menu-file-close:command" oncommand="zapiskiFileClose();"/>
</commandset>
Čarovnija prekrivkov nam omogoča, da določene ukaze sistemskih menujev posvojimo v celoti (<commandset id="tasksCommands"/>), druge pa zgolj po delčkih (<command id="cmd_undo"/>). Na koncu smo dodali še tri lastne, na katere se bomo odzvali s kodo v javascriptu.
Sledi skupina bližnjic (kombinacij tipk za aktivacijo menuja), ki jo določa oznaka <keyset>:
<keyset id="mainkeys">
<key id="key_undo"/>
<key id="key_redo"/>
...
<key
id = "menu-file-open:key"
key = "&menu-file-open:key;"
modifiers = "accel"
observes = "menu-file-open:command"/>
...
</keyset>
Znova nekaj posvojenega, brez podrobnosti, saj so te že opisane v prekrivku, in naši lastni menuji, za katere bližnjice, ki jih določimo natančneje z enoličnim imenom (id), tipko (key, modifiers; accel tu pomeni sistemsko tipko za menujske bližnjice, za Okna je to npr. tipka Ctrl) in ukazom, ki je vezan nanjo. Bližnjica je lahko odvisna od jezika, zato smo jo podali kot entiteto DTD.
Zadnja skupina oznak je sam menu, oznaka je <menubar>:
<menubar id="menu">
<menu id="menu-file" label="&menu-file:label;" accesskey="&menu-file:accesskey;">
<menupopup id="menu-file-popup">
<menuitem
id = "menu-file-open"
key = "menu-file-open:key"
label = "&menu-file-open:label;"
command = "menu-file-open:command"
accesskey = "&menu-file-open:accesskey;"/>
<menuitem
id = "menu-file-save"
key = "menu-file-save:key"
label = "&menu-file-save:label;"
command = "menu-file-save:command"
accesskey = "&menu-file-save:accesskey;"/>
<menuseparator/>
<menuitem
id = "menu-file-close"
key = "menu-file-close:key"
label = "&menu-file-close:label;"
command = "menu-file-close:command"
accesskey = "&menu-file-close:accesskey;"/>
</menupopup>
</menu>
<menu id="menu_Edit">
<menupopup>
<menuitem id="menu_undo"/>
<menuitem id="menu_redo"/>
</menupopup>
</menu>
<menu id="tasksMenu"/>
<menu id="windowMenu"/>
<menu id="menu_Help"/>
</menubar>
S kombiniranjem oznak lahko izgradimo poljubno menujsko strukturo, v katero vključujemo tako lastne kot vgrajene ukaze (oz. ukaze iz poljubnega prekrivka). Vsa jezikovno odvisna določila so vnesena kot entitete DTD.
Prevodi
Programsko kodo bomo zaenkrat izpustili, raje si še prej oglejmo prevode. Ustrezne datoteke je treba shraniti v podmape paketa prevodov, torej v locale/sl-SI/zapiski (slovenski prevod) in locale/en-US/zapiski (ameriška angleščina). Osnovni dokument je datoteka DTD, ki določa pomen simboličnih imen, ki smo jih uporabljali v zgoraj opisanih datotekah. V slovenščini je vsebina datoteke zapiski.dtd naslednja:
<!ENTITY window.title "Zapiski">
<!ENTITY menu-file:label "Datoteka">
<!ENTITY menu-file:accesskey "D">
<!ENTITY menu-file-open:key "O">
<!ENTITY menu-file-open:label "Odpri">
<!ENTITY menu-file-open:accesskey "O">
<!ENTITY menu-file-save:key "S">
<!ENTITY menu-file-save:label "Shrani">
<!ENTITY menu-file-save:accesskey "S">
<!ENTITY menu-file-close:key "W">
<!ENTITY menu-file-close:label "Zapri">
<!ENTITY menu-file-close:accesskey "Z">
Preveden je naslov okna in postavke menuja, kar za vsako zahteva napis, izpostavljen znak in bližnjico. Bližnjice so tipično enake za vse jezikovne različice, izpostavljeni znak pa mora biti sestavni del besede (poglejmo npr. prevode za "zapri").
Tudi prevode moramo prijaviti v Mozillinem registru, zato tudi v teh mapah pripravimo datoteko, katere ime mora biti contents.rdf, vsebina pa je za slovenski prevod naslednja:
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<RDF:Seq about="urn:mozilla:locale:root">
<RDF:li resource="urn:mozilla:locale:sl-SI"/>
</RDF:Seq>
<RDF:Description about="urn:mozilla:locale:sl-SI">
<chrome:packages>
<RDF:Seq about="urn:mozilla:locale:sl-SI:packages">
<RDF:li resource="urn:mozilla:locale:sl-SI:zapiski"/>
</RDF:Seq>
</chrome:packages>
</RDF:Description>
</RDF:RDF>
Znova smo krepko označili pomembne dele, preostanek datoteke pa je večinoma od primera do primera enak.
Uporabniški del samostojnega programa v XULu je s tem izdelan in pripravljen za preizkus (v resnici potrebujemo še datoteko s kodo v javascriptu, a to bomo trenutno zanemarili).
Preizkus programa
Ker smo Mozilli pripravili ustrezne manifeste, je mogoče naš program zdaj preizkusiti popolnoma drugače, kot smo poizkušali z zagonom datoteke XUL. Izvajalno okolje brez balasta, ki poganja zgolj naš program, je mogoče v Mozilli prikazati s posebnim stikalom ukazne vrstice. Za naš primer bi morali pognati
"c:\program files\mozilla.org\mozilla" -chrome chrome://zapiski/content
Seveda pri pogoju, da je Mozilla nameščena v mapi C:\Program Files\Mozilla.org. Videz vmesnika pri privzeti preobleki in v slovenski različici je na sliki 3.
Preizkus vmesnika programa "Zapiski" v Mozilli z aktivnim slovenskim prevodom.>
Pravilno pripravljene pakete je mogoče pognati še na en način, z odpiranjem novega okna v javascriptu:
window.open(
"chrome://zapiski/content",
"zapiski",
"chrome,width=400,height=300");
Pomembno je, da v tretji parameter metode window.open() zapišemo tudi niz chrome!
Programska koda
In še finale, programska koda, ki vdihne življenje grafičnemu vmesniku. Napisali jo bomo v javascriptu, a smo soočeni s hudo težavo: javascript, vgrajen v Mozillo, sploh nima mehanizmov za delo z datotekami. Tu nam priskočijo na pomoč gradniki XPCOM, ki jih lahko brez posebnih ovir uporabljamo v javascriptu.
Nabor razpoložljivih gradnikov je odvisen od izvajalnega okolja. Mozilla jih prinaša precej, še več jih lahko naknadno dodamo s pomočjo namestitvenih paketov .xpi ali pa jih razvijemo sami.
Za naše potrebe je na srečo lepo poskrbljeno v sami Mozilli in brez težav bomo uporabniku prikazali sistemsko pogovorno okno za izbiro datoteke, ki jo bomo zatem lahko prebrali ali pa vanjo zapisali vsebino opomb, vnesenih v okvir z besedilom.
Najprej si oglejmo bolj preprosti funkciji iz datoteke zapiski.js:
var zapiskiDocumentDirty = false;
function zapiskiDirty() {
zapiskiDocumentDirty = true;
}
function zapiskiFileClose() {
if (!zapiskiDocumentDirty || confirm("Zapiski spremenjeni, res zaprem?"))
window.close();
}
Vpeljali smo globalno spremenljivko, ki bo ponazarjala spremembe zapiska. V začetku je nastavljena na neresnico, vendar se skozi funkcijo zapiskiDirty(), ki jo gradnik XUL pokliče ob vsaki spremembi vsebine, ustrezno nastavi. Če uporabnik s pomočjo menuja ali bližnjice aktivira ukaz za zapiranje, se pokliče metoda zapiskiFileClose(). Tu smo uporabili manjšo zvijačo. Ker se v javascriptu logični izrazi vrednotijo kratkostično, smo morebitno potrditev zavržbe sprememb skrili kar v pogoj stavka if. Drugače tu ni posebnosti, klasični javascript pač.
Povsem drugačna je funkcija za shranjevanje:
function zapiskiFileSave() {
// XPCOM za izbiro datoteke
var filePicker = Components
.classes["@mozilla.org/filepicker;1"]
.createInstance();
// če je gradnik uspešno izdelan
if (filePicker != null) {
// izvleci ustrezen vnesnik
filePicker = filePicker
.QueryInterface(Components.interfaces.nsIFilePicker);
// če je tudi to upelo
if (filePicker != null) {
// prestrezi morebitne izjeme
try {
// podrobneje določamo pogovorno okno
// za izbor datoteke
filePicker.init(
top.window,
"Shrani",
Components.interfaces.nsIFilePicker.modeSave);
// dopuščamo vse vrste datotek
filePicker.appendFilters(
Components.interfaces.nsIFilePicker.filterAll);
// modalni prikaz okna
filePicker.show();
// je uporabnik sploh kaj izbral?
if (filePicker.file &&
(filePicker.file.path.length > 0))
{
// da, rabimo nov gradnik XPCOM, tokrat bomo
// želeni vmesnik izvlekli brez preverjanja
// uspešnosti, tako ali tako imamo blok try{}
var outputStream = Components
.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
// vzpostavimo izhodni tok z nekaj atributi
// - datoteka
// - ustvari datoteko, če je ni, odpri za pisanje
// - pravice (upoštevajo se le na podlagah unix)
outputStream.init( filePicker.file, 0x04 | 0x08 | 0x20, 420, 0 );
// preberemo vsebino gradnika z zapiskom s pomočjo DOM
var output = document.getElementById("zapisek").value;
// v izhodni tok zapišemo natančno toliko znakov
// kot je dolžina zapiska
var result = outputStream.write(output, output.length);
// zapremo tok
outputStream.close();
// označimo shranjene spremembe
zapiskiDocumentDirty = false;
}
else
return false;
} catch(ex) {
// morebitne napake tokrat javljamo
return false;
}
}
}
}
Gradnike XPCom s pomočjo tehnologije XPConnect iz javascripta naslavljamo na prav posebni način. Predmet Components pozna polje classes[], ki ga naslovimo z imenom gradnika. V Mozillo vgrajeni gradniki imajo ime oblike:
@mozilla.org/[<skupina>/]<gradnik>;<različica>
Nekateri gradniki so združeni v skupine, drugi ne. Tovrstna shema poimenovanja omogoča izvajalnemu okolju, da gosti številne knjižnice gradnikov različnih ponudnikov.
Gradnik sam po sebi ni uporaben, ker moramo najprej iz njega izvleči vmesnik. Šele vmesnik določa, kaj vse lahko z nekim gradnikom počnemo. Imena vmesnikov pri Mozillinih gradniki prepoznamo po začetnici nsI (zgodovinsko, Netscape Interface). Po tem je delo z gradnikom enako kot s katerimkoli predmetom v javascriptu.
Naš primer podpira tudi nalaganje, ker pa je funkcija precej podobna je tu ne bomo podrobneje razlagali. Vsekakor je celoten zgled na voljo za prenos s spletnih strani na naslovu: http://www.monitor.si/datoteke/xul.zip.
Komodo
Mozillin XUL ni le potencialno zanimiva podlaga, na njej že danes tečejo zmogljivi programi. Eden najprepričljivejših je razvojno orodje Active State Komodo, profesionalno okolje za razvoj v jezikih perl, PHP, python, tcl in XSLT. Zaradi uporabe Mozille so ga lahko razvili za Okna in Linux, nedavno pa brez posebnih težav prenesli še na Solaris.
http://www.activestate.com/Products/Komodo/
Prijava in namestitev
Program v XULu lahko Mozilli tudi trajno napovemo. Če je v manifestu ustrezno opisan, bo postal sestavni del menuja orodij in ga bomo lahko izbrali kadarkoli med delom. Napoved je mogoče izpeljati ročno ali pa zanjo poskrbimo z namestitvenim paketom.
Ročna prijava je mogoča z urejanjem datoteke installed-chrome.txt, ki jo najdemo v mapi chrome. Gre za preprosto datoteko z besedilom, kjer je v vsaki vrstici določena pot do manifesta posameznega prijavljenega paketa. Mozilla ob vsakem zagonu preveri datum zadnjega popravka te datoteke in, če je treba, obnovi svoj register paketov in tudi seznam prekrivkov, tako da jih je mogoče uporabljati tudi med paketi.
Naš pravkar razviti program bi lahko trajno dodali v Mozillin register tako, da v omenjeno datoteko na koncu dodamo naslednje tri vrstice:
content,install,url,resource:/chrome/zapiski/content/zapiski/
locale,install,url,resource:/chrome/zapiski/locale/sl-SI/zapiski/
locale,install,url,resource:/chrome/zapiski/locale/en-US/zapiski/
S tem smo Mozilli prijavili tri pakete, enega vsebinskega in dva s prevodi, skupaj z ustrezno potjo, tokrat navedeno s pomočjo krajevnika vrste resource:, ki podaja natančen položaj mape znotraj Mozilline namestitve.
Ob vnovičnem zagonu Mozille bomo lahko na menuju Window/Okno našli tudi vrstico Zapiski - simple editor/Zapiski - preprost urejevalnik (odvisno od izbranega prevoda, seveda).
<slika menu.tif>
Številne datoteke, ki sestavljajo program v XULu, je mogoče tudi strniti v zapis JAR (pravzaprav ZIP s spremenjeno končnico). Če preučimo datoteko prijavljenih programov, bomo takoj prepoznali zapis poti za pakete, shranjene v paketih JAR. Takole je npr. prijavljen sam communicator, jedro programskega skupka Mozilla:
content,install,url,jar:resource:/chrome/comm.jar!/content/communicator/
Pot do datoteke JAR je podana običajno, mape znotraj datoteke JAR pa so naštete za klicajem (!).
Če želimo namestitev našega programa avtomatizirati, bomo namesto datoteke JAR naredili XPI (izg. zipi), ki je znova le ZIP s spremenjeno končnico. XPI je zelo podoben datoteki JAR, le da vsebuje še datoteko install.js, ki vključuje namestitveni postopek. Mozilla bo tovrstne datoteke prenesla k odjemalcu, izvlekla omenjeno datoteko in jo pognala. XPI lahko vsebuje tudi več programov, zato je minimalna vsebina namestitvenega postopka podobna spodnjemu zgledu:
var xpi = new Object();
xpi["Zapiski"] = "zapiski.xpi";
// ključna funkcija
InstallTrigger.install(xpi, urejeno);
function urejeno ( ime , izid ){
if (izid) alert("Napaka ob namestitvi: " + izid);
}
Ključna funkcija je InstallTrigger.install(), ki ji posredujemo polje programov za namestitev (v našem primeru ima le en element) in povratno klicano funkcijo, ki sporoči morebiten neuspeh pri nameščanju. Zgornji zgled opisuje le minimalen postopek namestitve, izvajalno okolje ponuja še cel kup posebnih funkcij, s katerimi lahko vplivamo na potek namestitve. Več o njih lahko izvemo s pomočjo virov, ki so našteti na koncu.
S tem, ko so razvijalci Mozille zavrgli špagetasto kodo danes že skoraj pozabljenega Netscape Communicatorja, so naredili najboljšo možno potezo. Čeprav smo Mozillo dolgo čakali, je prinesla veliko več, kot le nov spletni brskalnik. Izvrstno infrastrukturo gradnikov, vsem standardom odprto knjižnico za upodabljanje Gekon, izvrsten paket spletnih programov, za povrh pa še XUL.
NVU
Marsikdo v Linuxu in drugih odprtokodnih sistemih pogreša kakovosten urejevalnik spletišč, primerljiv z Macoromediinim Dreamweaverjem. Mozilla ima vse potrebno že vgrajeno, treba je le še spisati nekaj veziva v XUL. Naloge so se lotili v podjetju Lindows, kjer razvijajo vizualni urejevalnik NVU.
http://www.nvu.com/
Razvoj za splet ostaja vroča tema, učinkovitega orodja za zmogljive odjemalce, ki bi jih lahko sestavljali v jasno ločenih slojih, pa do XULa preprosto nismo imeli. Z opiranjem na uveljavljene spletne standarde, z visoko učinkovitostjo, z razpoložljivostjo v številnih sistemih, z odprto kodo in mogočno skupnostjo uporabnikov je XUL prav lahko podlaga za spletne odjemalce prihodnosti. Izvrstna uporaba XULa bi bilo razvojno okolje zanj, zaradi urejanja velikega števila datotek in različnih skladenj bi bilo kakovostno razvojno in prototipno ortodje, razvito kar v Mozilli, neprecenljivo. Nekaj takih projektov že teče in verjetno si lahko kmalu obetamo tudi uporabne izdelke. Če bo prihodnost prinesla še poenotenje gradnikov XPCOM, UNO (OpenOffice) in JavaBeans, je Mozillina podlaga obsojena na še večji uspeh.
Mozdev
Skupnost razvijalcev v XULu je zelo močna. Posebno spletišče, MozDev, ponuja osrednji pregled projektov v razvoju, ker lahko najdemo marsikateri zanimivi dodatek ali pa se celo sami vključimo v njihov razvoj.
Pomemben projekt, ki nastaja v skupnosti, je razvojno orodje za XUL (seveda razvito kar v XULu) - XULMaker. Dobro razvojno orodje je pri razvoju v XULu neprecenljivo, saj je treba nadzorovati velike količine datotek, precej teh pa je mogoče ustvariti napol samodejno, npr. s pomočjo čarovnika. XULMaker vsebuje precej orodij, nadvse koristen je vizualni urejevalnik uporabniških vmesnikov.
http://www.mozdev.org
Viri in dodatno branje:
1. Dom XULa, http://www.mozilla.org/projects/xul/
2. XUL Planet, http://www.xulplanet.com/
3. Introduction to a XUL Document, http://www.mozilla.org/xpfe/xptoolkit/xulintro.html
4. XBL - Extensible Binding Language 1.0, http://www.mozilla.org/projects/xbl/xbl.html
5. XBL - XML Binding Language (W3C Note), http://www.w3.org/TR/xbl/
6. XUL Overlays, http://www.mozilla.org/xpfe/xptoolkit/overlays.html
7. XPCOM Part 1: An introduction to XPCOM, http://www-106.ibm.com/developerworks/webservices/library/co-xpcom.html
8. XPConnect, http://www.mozilla.org/scriptable/
9. Creating New Packages for Mozilla, http://www.mozilla.org/docs/xul/xulnotes/xulnote_packages.html