290 likes | 419 Views
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
E N D
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 • Koncept rozwiązania
Mozilla – (Mosaickiller) 1994 – NetscapeNavigator 1998 – MozillaOrganization (przebudowa Netscape) 2003 – MozillaFoundation (rozwój Mozillasuite) 2003 – Mozilla Corporation (dostarczanie firefoksa)
Mozilla Dziś Mozilla Firefox Thunderbird XULRunner …
Architektura Platforma Mozilla Toolkit Zarządzanie Dodatkami Sprawdzanie pisowni Aktualizacja Content SQLite XUL DOM CSS SVG HTML XML Necko JavaScript Widget XPConnect XPCOM NetscapePortableRuntime
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 <overlayid="helloworld-overlay„ …> <menupopupid="taskPopup"> <menuitemid="helloworld-hello" label="&helloworld;" </menupopup> </overlay> Jak Znaleźć ID?
Rejestracja… chrome.manifest contenthelloworldcontent/ overlay chrome://messenger/content/messenger.xul chrome://helloworld/content/overlay.xul localehelloworld en locale/en/ localehelloworldpllocale/pl/ skin helloworldclassic/1.0 skin/
JavaScript – jak to działa? • Podobnie jak w klasycznym HTML: <scriptsrc="overlay.js"/> oncommand="Helloworld.onMenuItemCommand(event);" varHelloworld = { 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 – ComponentObject 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, ...
Programowanie Komponentowe Komponent Komponent Komponent Świadomość Komponentu Interfejs Interfejs Interfejs Interfejs Interfejs Komponent Komponent Komponent
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 make-makefile make XPIDL Makefile.in .h typelibrary
Przydatne MAKRA • NS_GENERIC_FACTORYCONSTRUCTOR • NS_IMPL_NSGETMODULE • NS_IMPL_ISUPPARTS (1…n) • NS_DECL_... • NS_INIT_ISUPPORTS
MAKRA c.d. #include <stdio.h> #defineMOZILLA_STRICT_API #include "nsIModule.h" #include "nsIFactory.h" #include "nsIComponentManager.h" #include "nsIComponentRegistrar.h" staticconstnsIIDkIModuleIID = NS_IMODULE_IID; staticconstnsIIDkIFactoryIID = NS_IFACTORY_IID; staticconstnsIIDkISupportsIID = NS_ISUPPORTS_IID; staticconstnsIIDkIComponentRegistrarIID = NS_ICOMPONENTREGISTRAR_IID; #defineSAMPLE_CID \ { 0x777f7150, 0x4a2b, 0x4301, \ { 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}} staticconstnsCIDkSampleCID = SAMPLE_CID; classSample: public nsISupports { private: nsrefcntmRefCnt; public: Sample(); virtual ~Sample(); NS_IMETHODQueryInterface(constnsIID &aIID, void **aResult); NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); }; Sample::Sample() { mRefCnt = 0; } Sample::~Sample() { } NS_IMETHODIMPSample::QueryInterface(constnsIID &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) { deletethis; return 0; } return mRefCnt; } // factoryimplementationclass for componentclassSampleFactory: public nsIFactory{ private: nsrefcntmRefCnt; public: SampleFactory(); virtual ~SampleFactory(); NS_IMETHODQueryInterface(constnsIID &aIID, void **aResult); NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); NS_IMETHODCreateInstance(nsISupports *aOuter, constnsIID & iid, void * *result); NS_IMETHODLockFactory(PRBool lock); }; SampleFactory::SampleFactory() { mRefCnt = 0; } SampleFactory::~SampleFactory() { } NS_IMETHODIMPSampleFactory::QueryInterface(constnsIID &aIID, void **aResult) { if (aResult == NULL) { return NS_ERROR_NULL_POINTER; } *aResult = NULL; if (aIID.Equals(kISupportsIID)) { *aResult = (void *) this; } elseif (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) { deletethis; return 0; } return mRefCnt; } NS_IMETHODIMPSampleFactory::CreateInstance(nsISupports *aOuter, constnsIID & iid, void * *result) { if (!result) return NS_ERROR_INVALID_ARG; Sample* sample = newSample(); if (!sample) return NS_ERROR_OUT_OF_MEMORY; nsresultrv = sample->QueryInterface(iid, result); if (NS_FAILED(rv)) { *result = nsnull; deletesample; } return rv; } NS_IMETHODIMPSampleFactory::LockFactory(PRBool lock) { return NS_ERROR_NOT_IMPLEMENTED; } // Module implementationclassSampleModule : public nsIModule { public: SampleModule(); virtual ~SampleModule(); // nsISupportsmethods: NS_IMETHODQueryInterface(constnsIID & uuid, void * *result); NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); // nsIModulemethods: NS_IMETHODGetClassObject(nsIComponentManager *aCompMgr, constnsCID & aClass, constnsIID & aIID, void * *aResult); NS_IMETHODRegisterSelf(nsIComponentManager *aCompMgr, nsIFile *aLocation, const char *aLoaderStr, const char *aType); NS_IMETHODUnregisterSelf(nsIComponentManager *aCompMgr, nsIFile *aLocation, const char *aLoaderStr); NS_IMETHODCanUnload(nsIComponentManager *aCompMgr, PRBool *_retval); private: nsrefcntmRefCnt; }; //---------------------------------------------------------------------- SampleModule::SampleModule() { mRefCnt = 0; } SampleModule::~SampleModule() { } // nsISupportsimplementionNS_IMETHODIMP_(nsrefcnt) SampleModule::AddRef(void) { return ++mRefCnt; } NS_IMETHODIMP_(nsrefcnt) SampleModule::Release(void) { if (--mRefCnt == 0) { mRefCnt = 1; /* stabilize */ deletethis; return 0; } return mRefCnt; } NS_IMETHODIMPSampleModule::QueryInterface(REFNSIID aIID, void** aInstancePtr) { if (!aInstancePtr) return NS_ERROR_NULL_POINTER; nsISupports* foundInterface; if (aIID.Equals(kIModuleIID)) { foundInterface = (nsIModule*) this; } elseif ( 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 factoryobject for creatinginstances of aClass. NS_IMETHODIMPSampleModule::GetClassObject(nsIComponentManager *aCompMgr, constnsCID& aClass, constnsIID& aIID, void** result) { if (!kSampleCID.Equals(aClass)) return NS_ERROR_FACTORY_NOT_REGISTERED; if (!result) return NS_ERROR_INVALID_ARG; SampleFactory* factory = newSampleFactory(); if (!factory) return NS_ERROR_OUT_OF_MEMORY; nsresultrv = factory->QueryInterface(aIID, result); if (NS_FAILED(rv)) { *result = nsnull; deletefactory; } return rv; } //---------------------------------------- NS_IMETHODIMPSampleModule::RegisterSelf(nsIComponentManager *aCompMgr, nsIFile* aPath, const char* registryLocation, const char* componentType) { nsIComponentRegistrar* compReg = nsnull; nsresultrv = aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg); if (NS_FAILED(rv)) return rv; rv = compReg->RegisterFactoryLocation(kSampleCID, "SampleClass", nsnull, aPath, registryLocation, componentType); compReg->Release(); return rv; } NS_IMETHODIMPSampleModule::UnregisterSelf(nsIComponentManager* aCompMgr, nsIFile* aPath, const char* registryLocation) { nsIComponentRegistrar* compReg = nsnull; nsresultrv = aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg); if (NS_FAILED(rv)) return rv; rv = compReg->UnregisterFactoryLocation(kSampleCID, aPath); compReg->Release(); return rv; } NS_IMETHODIMPSampleModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload) { *okToUnload = PR_FALSE; // we do not knowhow to unload. return NS_OK; } //---------------------------------------------------------------------- extern "C" NS_EXPORTnsresultNSGetModule(nsIComponentManager *servMgr, nsIFile* location, nsIModule** return_cobj) { nsresultrv = NS_OK; // Create and initializethe module instanceSampleModule *m = newSampleModule(); if (!m) { return NS_ERROR_OUT_OF_MEMORY; } // Increaserefcnt and storeawaynsIModuleinterface to m inreturn_cobjrv = m->QueryInterface(kIModuleIID, (void**)return_cobj); if (NS_FAILED(rv)) { delete m; } return rv; }
MAKRA c.d. #include "nsIGenericFactory.h" #include "nsISupportsUtils.h" #defineSAMPLE_CID \ { 0x777f7150, 0x4a2b, 0x4301, \ { 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}} classSample: public nsISupports { public: Sample(); virtual ~Sample(); NS_DECL_ISUPPORTS }; Sample::Sample() { // note: innewerversions of Gecko (1.3 orlater) // youdon'thave to do this: NS_INIT_ISUPPORTS(); } Sample::~Sample() { } NS_IMPL_ISUPPORTS1(Sample, nsISupports); NS_GENERIC_FACTORY_CONSTRUCTOR(Sample); staticconstnsModuleComponentInfocomponents[] = { { "PrettyClassName", SAMPLE_CID, "@company.com/sample", SampleConstructor } }; NS_IMPL_NSGETMODULE(nsSampleModule, components)