mozilla chrome
DESCRIPTION
jako platforma deweloperska. Mozilla Chrome. O czym dzisiaj?. O mojej pracy Historia Mozilli Architektura Chrome XUL – jak to wygląda? Javascript – jak to działa? XPCOM – co jest w środku? Narzędzia – jak się tym bawić?. Moja praca. Indeksowanie Biblioteka Lucene Archiwizacja - PowerPoint PPT PresentationTRANSCRIPT
MOZILLA CHROME
jako platforma deweloperska
O czym dzisiaj?
O mojej pracy Historia Mozilli Architektura Chrome XUL – jak to wygląda? Javascript – jak to działa? XPCOM – co jest w środku? Narzędzia – jak się tym bawić?
Moja praca
Indeksowanie Biblioteka Lucene Archiwizacja Koncept rozwiązania
Mozilla – (Mosaic killer)1994 – Netscape Navigator
1998 – Mozilla Organization(przebudowa Netscape)
2003 – Mozilla Foundation(rozwój Mozilla suite)
2003 – Mozilla Corporation(dostarczanie firefoksa)
Mozilla Dziś
MozillaTh
un
derb
ird
Fir
efo
x
XU
LR
un
ner
…
ArchitekturaPlatforma Mozilla
Toolkit
Content
XUL DOM CSS
SVG HTML XML
Zarządzanie Dodatkami Aktualizacja
Sprawdzanie pisowni
NeckoSQLite
XPCOM
XPConnect
JavaScript
Widget
Netscape Portable Runtime
GUI – co zauważono
Ciężko utrzymywać wygląd aplikacji na wielu platformach
HTML to wygodne narzędzie definiowania wyglądu
Pisząc przeglądarkę należy stworzyć silnik graficzny do renderowania stron HTML
Czym jest Gecko?
Gecko
Czym jest XUL?<menu>
<menuitem><menupopup>
Gecko
<window> <label> <button>
XUL a HTML po krótce
XUL
HTML
XUL a HTML trochę szerzej Idea Sandbox Odwołania do obiektów XPCOM Odwołania do systemu plików Ograniczony dostęp do obiektów
Javascript Ograniczone znaczniki
XUL a dodatki<overlay id="helloworld-overlay„ …>
<menupopup id="taskPopup"><menuitem id="helloworld-hello"
label="&helloworld;" </menupopup></overlay>
Jak Znaleźć ID?
Rejestracja Dodatku .rdf
Rejestracja… chrome.manifest
content helloworld content/overlay chrome://messenger/content/messenger.xul
chrome://helloworld/content/overlay.xul
locale helloworld en locale/en/locale helloworld pl locale/pl/
skin helloworld classic/1.0 skin/
JavaScript – jak to działa? Podobnie jak w klasycznym HTML:
<script src="overlay.js"/>
oncommand="Helloworld.onMenuItemCommand(event);"
var Helloworld = { onMenuItemCommand: function() { window.open("chrome://helloworld/content/hello.xul",
"", "chrome"); }};
JavaScript – jak to działa? Inaczej niż w klasycznym HTML:
var c = Components.classes["@mozilla.org/messenger/msgwindow;1"];var i = c.createInstance(Components.interfaces.nsIMsgWindow);var c2 = Components.classes["@mozilla.org/messengercompose;1"];Var i2 = c2.getService(Components.interfaces.nsIMsgComposeService);
Ponad 130 interfejsów Bardzo mało dokumentacji :/
XPCOM - co jest w środku? Microsoft COM – Component Object
Model XPCOM – Cross Platform COM
COM a XPCOM - interfejsy IUnknown
IClassFactory(2)
??
nsISupports
nsIFactory
nsIModule
COM a XPCOM IDL Delphi, C++, Visual
Basic rejestr
Windows
XPIDL C++, JavaScript,
Python pliki rejestracyjne
(rejestracja w locie) Windows, Linux,
Unix, MacOS, ...
Świadomość Komponentu
Programowanie Komponentowe
Komponent
Komponent
Interfejs
Kom
pone
nt
Interfejs
Kompo
nent
Inte
rfejs
Komponent
Interfejs
Komponent
Interfejs
Komponenty - zalety
Łatwy podział obowiązków programistycznych
Łatwa zmiana impleentacji Wydajność – późne ładowanie Utrzymanie modularnego kodu jest
łatwijsze
Komponent, Serwis, Interfejs, Moduł, Fabryka
Komponent implementuje interfejs Jeden Komponent może implementować
wiele interfejsów Interfejs może być implementowany przez
wiele komponentów Serwis – Komponent o jednej instacji Moduł to zbiór komponentów Fabryka służy do instancjonowania
komponentów i zarządzania ich cyklem życia
Idea Zamrażania Interfejsów DLL Hell
Interfejsy zamrożone i nie zamrożone
Po co komu nie zamrożone interfejsy
XPCOM Glue (i inne przydatne klasy)
Rejestracja Komponentu
Module::RegisterSelf
Module::UnregisterSelf
Rejestracja w Mozilli
Proces Budowania
MozillaBuild (cygwin + perl + skrypty) Microsoft Visual C++ Microsoft Windows SDK
XPIDL Makefile.in
make-makefilemake
.htype library
Przydatne MAKRA
NS_GENERIC_FACTORYCONSTRUCTOR NS_IMPL_NSGETMODULE NS_IMPL_ISUPPARTS (1…n) NS_DECL_... NS_INIT_ISUPPORTS
MAKRA c.d.#include <stdio.h> #define MOZILLA_STRICT_API #include "nsIModule.h" #include "nsIFactory.h" #include "nsIComponentManager.h" #include "nsIComponentRegistrar.h" static
const nsIID kIModuleIID = NS_IMODULE_IID; static const nsIID kIFactoryIID = NS_IFACTORY_IID; static const nsIID kISupportsIID = NS_ISUPPORTS_IID; static const nsIID kIComponentRegistrarIID = NS_ICOMPONENTREGISTRAR_IID; #define SAMPLE_CID \ { 0x777f7150, 0x4a2b, 0x4301, \ { 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}} static const nsCID kSampleCID = SAMPLE_CID; class Sample: public nsISupports { private: nsrefcnt mRefCnt; public: Sample(); virtual ~Sample(); NS_IMETHOD QueryInterface(const nsIID &aIID, void **aResult); NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); }; Sample::Sample() { mRefCnt = 0; } Sample::~Sample() { } NS_IMETHODIMP Sample::QueryInterface(const nsIID &aIID, void **aResult) { if (aResult == NULL) { return NS_ERROR_NULL_POINTER; } *aResult = NULL; if (aIID.Equals(kISupportsIID)) { *aResult = (void *) this; } if (*aResult == NULL) { return NS_ERROR_NO_INTERFACE; } AddRef(); return NS_OK; } NS_IMETHODIMP_(nsrefcnt) Sample::AddRef() { return ++mRefCnt; } NS_IMETHODIMP_(nsrefcnt) Sample::Release() { if (--mRefCnt == 0) { delete this; return 0; } return mRefCnt; } // factory implementation class for component class SampleFactory: public nsIFactory{ private: nsrefcnt mRefCnt; public: SampleFactory(); virtual ~SampleFactory(); NS_IMETHOD QueryInterface(const nsIID &aIID, void **aResult); NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); NS_IMETHOD CreateInstance(nsISupports *aOuter, const nsIID & iid, void * *result); NS_IMETHOD LockFactory(PRBool lock); }; SampleFactory::SampleFactory() { mRefCnt = 0; } SampleFactory::~SampleFactory() { } NS_IMETHODIMP SampleFactory::QueryInterface(const nsIID &aIID, void **aResult) { if (aResult == NULL) { return NS_ERROR_NULL_POINTER; } *aResult = NULL; if (aIID.Equals(kISupportsIID)) { *aResult = (void *) this; } else if (aIID.Equals(kIFactoryIID)) { *aResult = (void *) this; } if (*aResult == NULL) { return NS_ERROR_NO_INTERFACE; } AddRef(); return NS_OK; } NS_IMETHODIMP_(nsrefcnt) SampleFactory::AddRef() { return ++mRefCnt; } NS_IMETHODIMP_(nsrefcnt) SampleFactory::Release() { if (--mRefCnt == 0) { delete this; return 0; } return mRefCnt; } NS_IMETHODIMP SampleFactory::CreateInstance(nsISupports *aOuter, const nsIID & iid, void * *result) { if (!result) return NS_ERROR_INVALID_ARG; Sample* sample = new Sample(); if (!sample) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = sample->QueryInterface(iid, result); if (NS_FAILED(rv)) { *result = nsnull; delete sample; } return rv; } NS_IMETHODIMP SampleFactory::LockFactory(PRBool lock) { return NS_ERROR_NOT_IMPLEMENTED; } // Module implementation class SampleModule : public nsIModule { public: SampleModule(); virtual ~SampleModule(); // nsISupports methods: NS_IMETHOD QueryInterface(const nsIID & uuid, void * *result); NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); // nsIModule methods: NS_IMETHOD GetClassObject(nsIComponentManager *aCompMgr, const nsCID & aClass, const nsIID & aIID, void * *aResult); NS_IMETHOD RegisterSelf(nsIComponentManager *aCompMgr, nsIFile *aLocation, const char *aLoaderStr, const char *aType); NS_IMETHOD UnregisterSelf(nsIComponentManager *aCompMgr, nsIFile *aLocation, const char *aLoaderStr); NS_IMETHOD CanUnload(nsIComponentManager *aCompMgr, PRBool *_retval); private: nsrefcnt mRefCnt; }; //---------------------------------------------------------------------- SampleModule::SampleModule() { mRefCnt = 0; } SampleModule::~SampleModule() { } // nsISupports implemention NS_IMETHODIMP_(nsrefcnt) SampleModule::AddRef(void) { return ++mRefCnt; } NS_IMETHODIMP_(nsrefcnt) SampleModule::Release(void) { if (--mRefCnt == 0) { mRefCnt = 1; /* stabilize */ delete this; return 0; } return mRefCnt; } NS_IMETHODIMP SampleModule::QueryInterface(REFNSIID aIID, void** aInstancePtr) { if (!aInstancePtr) return NS_ERROR_NULL_POINTER; nsISupports* foundInterface; if (aIID.Equals(kIModuleIID)) { foundInterface = (nsIModule*) this; } else if ( aIID.Equals(kISupportsIID) ) { foundInterface = (nsISupports*) this; } else { foundInterface = 0; } if (foundInterface) { foundInterface->AddRef(); *aInstancePtr = foundInterface; return NS_OK; } *aInstancePtr = foundInterface; return NS_NOINTERFACE; } // Create a factory object for creating instances of aClass. NS_IMETHODIMP SampleModule::GetClassObject(nsIComponentManager *aCompMgr, const nsCID& aClass, const nsIID& aIID, void** result) { if (!kSampleCID.Equals(aClass)) return NS_ERROR_FACTORY_NOT_REGISTERED; if (!result) return NS_ERROR_INVALID_ARG; SampleFactory* factory = new SampleFactory(); if (!factory) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = factory->QueryInterface(aIID, result); if (NS_FAILED(rv)) { *result = nsnull; delete factory; } return rv; } //---------------------------------------- NS_IMETHODIMP SampleModule::RegisterSelf(nsIComponentManager *aCompMgr, nsIFile* aPath, const char* registryLocation, const char* componentType) { nsIComponentRegistrar* compReg = nsnull; nsresult rv = aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg); if (NS_FAILED(rv)) return rv; rv = compReg->RegisterFactoryLocation(kSampleCID, "Sample Class", nsnull, aPath, registryLocation, componentType); compReg->Release(); return rv; } NS_IMETHODIMP SampleModule::UnregisterSelf(nsIComponentManager* aCompMgr, nsIFile* aPath, const char* registryLocation) { nsIComponentRegistrar* compReg = nsnull; nsresult rv = aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg); if (NS_FAILED(rv)) return rv; rv = compReg->UnregisterFactoryLocation(kSampleCID, aPath); compReg->Release(); return rv; } NS_IMETHODIMP SampleModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload) { *okToUnload = PR_FALSE; // we do not know how to unload. return NS_OK; } //---------------------------------------------------------------------- extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, nsIFile* location, nsIModule** return_cobj) { nsresult rv = NS_OK; // Create and initialize the module instance SampleModule *m = new SampleModule(); if (!m) { return NS_ERROR_OUT_OF_MEMORY; } // Increase refcnt and store away nsIModule interface to m in return_cobj rv = m->QueryInterface(kIModuleIID, (void**)return_cobj); if (NS_FAILED(rv)) { delete m; } return rv; }
MAKRA c.d.#include "nsIGenericFactory.h" #include "nsISupportsUtils.h"
#define SAMPLE_CID \ { 0x777f7150, 0x4a2b, 0x4301, \ { 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}} class Sample: public nsISupports { public: Sample(); virtual ~Sample(); NS_DECL_ISUPPORTS }; Sample::Sample() { // note: in newer versions of Gecko (1.3 or later) // you don't have to do this: NS_INIT_ISUPPORTS(); } Sample::~Sample() { } NS_IMPL_ISUPPORTS1(Sample, nsISupports); NS_GENERIC_FACTORY_CONSTRUCTOR(Sample); static const nsModuleComponentInfo components[] = { { "Pretty Class Name", SAMPLE_CID, "@company.com/sample", SampleConstructor } }; NS_IMPL_NSGETMODULE(nsSampleModule, components)
DZIĘKUJĘ ZA UWAGĘ