diff --git a/components/geckoport/Components/CallbackInterfaces.pas b/components/geckoport/Components/CallbackInterfaces.pas index 2396900ce..a6862519b 100644 --- a/components/geckoport/Components/CallbackInterfaces.pas +++ b/components/geckoport/Components/CallbackInterfaces.pas @@ -49,7 +49,7 @@ unit CallbackInterfaces; interface uses - nsXPCOM, nsTypes,nsInit, nsGeckoStrings; + nsXPCOM, nsTypes; type IGeckoCreateWindowTarget = interface @@ -63,26 +63,6 @@ type function GetCreateWindowTarget: IGeckoCreateWindowTarget; end; - { nsMyDirectoryServiceProvider } - - { IDirectoryServiceProvider } - - IDirectoryServiceProvider = class(TInterfacedObject, - nsIDirectoryServiceProvider) - private - FCacheParentDir: UTF8String; - FProfileDir: UTF8String; - procedure SetCacheDir(const AValue: UTF8String); - procedure SetProfileDir(const AValue: UTF8String); - public - function GetFile(const prop: PAnsiChar; out persistent: PRBool): nsIFile; safecall; - property CacheParentDir: UTF8String read FCacheParentDir write SetCacheDir; - property ProfileDir: UTF8String read FProfileDir write SetProfileDir; - end; - -var - GeckoEngineDirectoryService: IDirectoryServiceProvider; - function InitWindowCreator: Boolean; implementation @@ -181,43 +161,4 @@ begin Result := HRESULT(NS_ERROR_FAILURE); end; -{ IDirectoryServiceProvider } - -procedure IDirectoryServiceProvider.SetCacheDir(const AValue: UTF8String); -begin - if FCacheParentDir=AValue then exit; - FCacheParentDir:=AValue; -end; - -procedure IDirectoryServiceProvider.SetProfileDir(const AValue: UTF8String); -begin - if FProfileDir=AValue then exit; - FProfileDir:=AValue; -end; - -function IDirectoryServiceProvider.GetFile(const prop: PAnsiChar; out - persistent: PRBool): nsIFile; safecall; -var - Local: nsILocalFile; -begin - persistent:=true; //Only ask one time for each directory, it will be remembered - //by the Gecko engine while running. - if prop = 'ProfD' then //Profile directory - begin - if FProfileDir<>'' then - begin - NS_NewLocalFile(NewString(FProfileDir).AString,false,Local); - Local.QueryInterface(nsILocalFile,Result); - end; - end else - if prop = 'cachePDir' then //Cache directory - begin - if FCacheParentDir<>'' then - begin - NS_NewLocalFile(NewString(FCacheParentDir).AString,false,Local); - Local.QueryInterface(nsILocalFile,Result); - end; - end; -end; - end. diff --git a/components/geckoport/Components/GeckoBrowser.pas b/components/geckoport/Components/GeckoBrowser.pas index 027b14b44..1afe3b071 100755 --- a/components/geckoport/Components/GeckoBrowser.pas +++ b/components/geckoport/Components/GeckoBrowser.pas @@ -130,6 +130,10 @@ type EGeckoBrowserNavigationError = class(EGeckoBrowserError) end; + {$PUSH}{$HINTS OFF} //Redefinition to expose the interface + IDirectoryServiceProvider=nsXPCOMGlue.IDirectoryServiceProvider; + {$POP} + TGeckoBrowserContextMenu = procedure (Sender: TObject; aInfo: TCtxMenuInfo) of object; TGeckoBrowserStatusChange = procedure (Sender: TObject; aMessage: WideString) of object; TGeckoBrowserNewWindow = procedure (Sender: TObject; aChromeFlags: Longword; var newWindow: TCustomGeckoBrowser) of object; @@ -1091,8 +1095,12 @@ begin end; if Assigned(FOnDirectoryService) then FOnDirectoryService(Self,GeckoEngineDirectoryService); - GeckoComponentsStartup; - FGeckoComponentsStartupSucceeded := true; + try + GeckoComponentsStartup; + FGeckoComponentsStartupSucceeded := true; + except + FGeckoComponentsStartupSucceeded := false; + end; end; inherited Loaded; DoInitializationIfNeeded; @@ -1113,6 +1121,8 @@ begin OutputDebugString('TGeckoBrowser.DestroyWnd'); {$ENDIF} inherited DestroyWnd; + if not FGeckoComponentsStartupSucceeded then + FreeAndNIL(GeckoEngineDirectoryService); end; procedure TCustomGeckoBrowser.GoBack; @@ -1199,7 +1209,8 @@ end; procedure TCustomGeckoBrowser.LoadURI(const uri: WideString); begin - InnerLoadURI(uri, 0, nil, nil, nil); + if FGeckoComponentsStartupSucceeded then + InnerLoadURI(uri, 0, nil, nil, nil); end; procedure TCustomGeckoBrowser.LoadURI(const uri: WideString; @@ -1864,8 +1875,15 @@ begin Canvas.FillRect(rc); end else begin - baseWin := FWebBrowser as nsIBaseWindow; - baseWin.Repaint(true); + if FGeckoComponentsStartupSucceeded then + begin + baseWin := FWebBrowser as nsIBaseWindow; + baseWin.Repaint(true); + end + else + begin + Canvas.TextOut(0,0,SGeckoBrowserInitError); + end; end; inherited; end; @@ -1948,7 +1966,7 @@ end; procedure TCustomGeckoBrowser.DoInitializationIfNeeded; begin - if not FInitializationStarted then + if not FInitializationStarted and FGeckoComponentsStartupSucceeded then if not (csDesigning in ComponentState) then begin FInitializationStarted:=true; diff --git a/components/geckoport/Components/GeckoInit.pas b/components/geckoport/Components/GeckoInit.pas index b0adb2481..26c346f58 100644 --- a/components/geckoport/Components/GeckoInit.pas +++ b/components/geckoport/Components/GeckoInit.pas @@ -8,17 +8,20 @@ procedure GeckoComponentsShutdown; implementation uses - nsXPCOM, nsInit, nsGeckoStrings, nsTypes, nsConsts, nsErrorUtils, nsError, + nsXPCOM, nsInit, nsTypes, nsErrorUtils, nsError, nsXPCOMGlue, nsXRE {$IFDEF MSWINDOWS}, Windows {$ENDIF}; var sInitCount: Integer = 0; procedure GeckoComponentsStartup(XPComPath: string = ''); +const + NS_DIRECTORY_SERVICE_CID: TGUID = '{f00152d0-b40b-11d3-8c9c-000064657374}'; var rv: nsresult; - errorStr: AnsiString; + ServiceManager: nsIServiceManager; + DirectoryService: nsIDirectoryService; begin if sInitCount>0 then begin @@ -35,6 +38,13 @@ begin raise EGeckoError.Create(string(errorStr)); end; + //Register the service via Service Manager. + if not Assigned(GeckoEngineDirectoryService) then + GeckoEngineDirectoryService:=IDirectoryServiceProvider.Create; + NS_GetServiceManager(ServiceManager); + ServiceManager.GetService(NS_DIRECTORY_SERVICE_CID, DirectoryService,DirectoryService); + DirectoryService.RegisterProvider(GeckoEngineDirectoryService); + Inc(sInitCount); end; diff --git a/components/geckoport/nsErrorUtils.pas b/components/geckoport/nsErrorUtils.pas index 6f13ea3ab..ef985525c 100644 --- a/components/geckoport/nsErrorUtils.pas +++ b/components/geckoport/nsErrorUtils.pas @@ -19,7 +19,7 @@ function NS_GetErrorStringBundleKey(aError: nsresult): AnsiString; implementation uses - nsInit, nsXPCOMGlue, nsXPCOM, nsConsts, nsError; + nsXPCOMGlue, nsXPCOM, nsError; type nsIErrorService = interface; diff --git a/components/geckoport/nsInit.pas b/components/geckoport/nsInit.pas index 0efe4d17e..04b00efaa 100755 --- a/components/geckoport/nsInit.pas +++ b/components/geckoport/nsInit.pas @@ -500,7 +500,7 @@ end; function NS_GetServiceManager(out servMgr: nsIServiceManager): nsresult; begin if Assigned(xpcomFunc.getServiceManager) then - Result := xpcomFunc.getServiceManager(servMgr) + Result := nsresult(xpcomFunc.getServiceManager(servMgr)) else Result := NS_ERROR_FAILURE; end; @@ -534,7 +534,7 @@ function NS_NewLocalFile(const path: nsAString; out newFile: nsILocalFile): nsresult; begin if Assigned(xpcomFunc.newLocalFile) then - Result := xpcomFunc.newLocalFile(path, followLinks, newFile) + Result := nsresult(xpcomFunc.newLocalFile(path, followLinks, newFile)) else Result := NS_ERROR_FAILURE; end; @@ -544,7 +544,7 @@ function NS_NewNativeLocalFile(const path: nsACString; out newFile: nsILocalFile): nsresult; begin if Assigned(xpcomFunc.newNativeLocalFile) then - Result := xpcomFunc.newNativeLocalFile(path, followLinks, newFile) + Result := nsresult(xpcomFunc.newNativeLocalFile(path, followLinks, newFile)) else Result := NS_ERROR_FAILURE; end; @@ -553,7 +553,7 @@ function NS_RegisterXPCOMExitRoutine(exitRoutine: XPCOMExitRoutine; priority: Longword): nsresult; begin if Assigned(xpcomFunc.registerXPCOMExitRoutine) then - Result := xpcomFunc.registerXPCOMExitRoutine(exitRoutine, priority) + Result := nsresult(xpcomFunc.registerXPCOMExitRoutine(exitRoutine, priority)) else Result := NS_ERROR_FAILURE; end; @@ -561,7 +561,7 @@ end; function NS_UnregisterXPCOMExitRoutine(exitRoutine: XPCOMExitRoutine): nsresult; begin if Assigned(xpcomFunc.unregisterXPCOMExitRoutine) then - Result := xpcomFunc.unregisterXPCOMExitRoutine(exitRoutine) + Result := nsresult(xpcomFunc.unregisterXPCOMExitRoutine(exitRoutine)) else Result := NS_ERROR_FAILURE; end; diff --git a/components/geckoport/nsNetUtil.pas b/components/geckoport/nsNetUtil.pas index 5fb09788b..f791bd241 100644 --- a/components/geckoport/nsNetUtil.pas +++ b/components/geckoport/nsNetUtil.pas @@ -39,7 +39,7 @@ unit nsNetUtil; interface uses - nsXPCOM, nsConsts, nsTypes, nsGeckoStrings; + nsXPCOM, nsTypes, nsGeckoStrings; function NS_GetIOService: nsIIOService; diff --git a/components/geckoport/nsXPCOMGlue.pas b/components/geckoport/nsXPCOMGlue.pas index a64c4829a..54e64d304 100644 --- a/components/geckoport/nsXPCOMGlue.pas +++ b/components/geckoport/nsXPCOMGlue.pas @@ -45,7 +45,7 @@ unit nsXPCOMGlue; interface uses - nsXPCOM, nsTypes, SysUtils; + nsXPCOM, nsTypes, nsGeckoStrings, SysUtils; const (* @@ -301,6 +301,21 @@ type function GetWeakReference: nsIWeakReference; safecall; end; + { IDirectoryServiceProvider } + + IDirectoryServiceProvider = class(TInterfacedObject, + nsIDirectoryServiceProvider) + private + FCacheParentDir: UTF8String; + FProfileDir: UTF8String; + procedure SetCacheDir(const AValue: UTF8String); + procedure SetProfileDir(const AValue: UTF8String); + public + function GetFile(const prop: PAnsiChar; out persistent: PRBool): nsIFile; safecall; + property CacheParentDir: UTF8String read FCacheParentDir write SetCacheDir; + property ProfileDir: UTF8String read FProfileDir write SetProfileDir; + end; + EGeckoException = class (Exception); EGeckoError = class(EGeckoException); //Gecko error. It is an error. EGeckoHint = class(EGeckoException); //Gecko Hint. It does not necessary means an error. They could be hidden. @@ -315,6 +330,8 @@ resourcestring SNoSuchSpecialDir = 'Cannot get the Special Directory ''%s.'' '; SNoSuchInterface = 'Cannot get the Interface ''%s.'' '; +var + GeckoEngineDirectoryService: IDirectoryServiceProvider; implementation @@ -325,6 +342,7 @@ var sCompMgr: nsIComponentManager = nil; sSrvMgr: nsIServiceManager = nil; + procedure NS_CreateInstance(const CID, IID: TGUID; out Intf); var rv: nsresult; @@ -553,4 +571,43 @@ begin System.Error(reIntfCastError); end; +{ IDirectoryServiceProvider } + +procedure IDirectoryServiceProvider.SetCacheDir(const AValue: UTF8String); +begin + if FCacheParentDir=AValue then exit; + FCacheParentDir:=AValue; +end; + +procedure IDirectoryServiceProvider.SetProfileDir(const AValue: UTF8String); +begin + if FProfileDir=AValue then exit; + FProfileDir:=AValue; +end; + +function IDirectoryServiceProvider.GetFile(const prop: PAnsiChar; out + persistent: PRBool): nsIFile; safecall; +var + Local: nsILocalFile; +begin + persistent:=true; //Only ask one time for each directory, it will be remembered + //by the Gecko engine while running. + if prop = 'ProfD' then //Profile directory + begin + if FProfileDir<>'' then + begin + NS_NewLocalFile(NewString(FProfileDir).AString,false,Local); + Local.QueryInterface(nsILocalFile,Result); + end; + end else + if prop = 'cachePDir' then //Cache directory + begin + if FCacheParentDir<>'' then + begin + NS_NewLocalFile(NewString(FCacheParentDir).AString,false,Local); + Local.QueryInterface(nsILocalFile,Result); + end; + end; +end; + end. diff --git a/components/geckoport/nsXRE.pas b/components/geckoport/nsXRE.pas index d8e4a9c0f..3abc90d13 100755 --- a/components/geckoport/nsXRE.pas +++ b/components/geckoport/nsXRE.pas @@ -3,7 +3,7 @@ unit nsXRE; interface uses - nsTypes, nsXPCOM, nsInit, CallbackInterfaces; + nsTypes, nsXPCOM, nsInit; type PXREAppData = ^nsXREAppData; @@ -406,10 +406,10 @@ begin XRE_UnloadGRE(); Exit; end; - if not Assigned(GeckoEngineDirectoryService) then - GeckoEngineDirectoryService:=IDirectoryServiceProvider.Create; // NS_LogInit(); - Result := XRE_InitEmbedding(xulDir, appDir, GeckoEngineDirectoryService, nil, 0); + //Warning, do not pass GeckoEngineDirectoryService to XRE_InitEmbedding, it + //will crash Gecko versions prior to 1.9.2.x with AV in line "basewin.Create" + Result := XRE_InitEmbedding(xulDir, appDir, nil, nil, 0); // NS_LogTerm(); end;