From a676245311cb334c1e3c2a6aef6f86813b8c73b6 Mon Sep 17 00:00:00 2001 From: "d.l.i.w" Date: Sat, 16 Aug 2014 14:01:50 +0200 Subject: [PATCH] add support for OSR other changes: - remove cef3api_static - add examples: JavaScript, OSRDemo - fix DragHandler (thanks to Michl on lazarusforum.de) --- Component/cef3.lpk | 12 +- Component/cef3.pas | 3 +- Component/cef3lcl.pas | 98 ++- Component/cef3osr.pas | 1022 +++++++++++++++++++++++++++++ Component/{icon.lrs => icons.lrs} | 52 ++ Examples/Examples.txt | 10 + Examples/JavaScript/handler.pas | 94 +++ Examples/JavaScript/js.ico | Bin 0 -> 137040 bytes Examples/JavaScript/js.lpi | 208 ++++++ Examples/JavaScript/js.lpr | 20 + Examples/JavaScript/main.lfm | 113 ++++ Examples/JavaScript/main.pas | 87 +++ Examples/OSRDemo/main.lfm | 84 +++ Examples/OSRDemo/main.pas | 197 ++++++ Examples/OSRDemo/osrdemo.ico | Bin 0 -> 137040 bytes Examples/OSRDemo/osrdemo.lpi | 209 ++++++ Examples/OSRDemo/osrdemo.lpr | 20 + Examples/WinMinimal/minimal.lpr | 2 +- Readme.md | 7 +- cef3api.pas | 1 - cef3api_static.pas | 675 ------------------- cef3gui.pas | 30 +- cef3intf.pas | 7 +- cef3lib.pas | 34 +- cef3own.pas | 17 +- cef3ref.pas | 138 ++-- cef3types.pas | 52 +- 27 files changed, 2367 insertions(+), 825 deletions(-) create mode 100644 Component/cef3osr.pas rename Component/{icon.lrs => icons.lrs} (51%) create mode 100644 Examples/JavaScript/handler.pas create mode 100644 Examples/JavaScript/js.ico create mode 100644 Examples/JavaScript/js.lpi create mode 100644 Examples/JavaScript/js.lpr create mode 100644 Examples/JavaScript/main.lfm create mode 100644 Examples/JavaScript/main.pas create mode 100644 Examples/OSRDemo/main.lfm create mode 100644 Examples/OSRDemo/main.pas create mode 100644 Examples/OSRDemo/osrdemo.ico create mode 100644 Examples/OSRDemo/osrdemo.lpi create mode 100644 Examples/OSRDemo/osrdemo.lpr delete mode 100644 cef3api_static.pas diff --git a/Component/cef3.lpk b/Component/cef3.lpk index 2e3824f..767938e 100644 --- a/Component/cef3.lpk +++ b/Component/cef3.lpk @@ -18,8 +18,6 @@ - - @@ -27,14 +25,15 @@ + - - + + @@ -72,6 +71,11 @@ + + + + + diff --git a/Component/cef3.pas b/Component/cef3.pas index effbea6..7f77fcf 100644 --- a/Component/cef3.pas +++ b/Component/cef3.pas @@ -8,13 +8,14 @@ interface uses cef3types, cef3api, cef3lib, cef3intf, cef3ref, cef3own, cef3gui, cef3lcl, - LazarusPackageIntf; + cef3osr, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('cef3lcl', @cef3lcl.Register); + RegisterUnit('cef3osr', @cef3osr.Register); end; initialization diff --git a/Component/cef3lcl.pas b/Component/cef3lcl.pas index f711531..1ab26cf 100644 --- a/Component/cef3lcl.pas +++ b/Component/cef3lcl.pas @@ -64,7 +64,7 @@ {$ENDIF} cef3types, cef3lib, cef3intf, cef3gui; -type +Type { TCustomChromium } @@ -124,8 +124,9 @@ TCustomChromium = class(TWinControl, IChromiumEvents) { RenderHandler } FOnPopupShow: TOnPopupShow; FOnPopupSize: TOnPopupSize; - FOnPaint: TOnPaint; + // FOnPaint: TOnPaint; {$NOTE !} FOnCursorChange: TOnCursorChange; + FOnScrollOffsetChanged: TOnScrollOffsetChanged; { RequestHandler } FOnBeforeBrowse: TOnBeforeBrowse; FOnBeforeResourceLoad: TOnBeforeResourceLoad; @@ -226,12 +227,14 @@ TCustomChromium = class(TWinControl, IChromiumEvents) function doOnGetViewRect(const Browser: ICefBrowser; rect: PCefRect): Boolean; function doOnGetScreenPoint(const Browser: ICefBrowser; viewX, viewY: Integer; screenX, screenY: PInteger): Boolean; + function doOnGetScreenInfo(const browser: ICefBrowser; var screenInfo: TCefScreenInfo): Boolean; procedure doOnPopupShow(const Browser: ICefBrowser; doshow: Boolean); procedure doOnPopupSize(const Browser: ICefBrowser; const rect: PCefRect); procedure doOnPaint(const Browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: TSize; const dirtyRects: PCefRectArray; const buffer: Pointer; awidth, aheight: Integer); procedure doOnCursorChange(const Browser: ICefBrowser; acursor: TCefCursorHandle); + procedure doOnScrollOffsetChanged(const browser: ICefBrowser); { RequestHandler } function doOnBeforeBrowse(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; isRedirect: Boolean): Boolean; virtual; @@ -302,6 +305,7 @@ TCustomChromium = class(TWinControl, IChromiumEvents) property OnLoadEnd: TOnLoadEnd read FOnLoadEnd write FOnLoadEnd; property OnLoadError: TOnLoadError read FOnLoadError write FOnLoadError; { RenderHandler } + property OnScrollOffsetChanged: TOnScrollOffsetChanged read FOnScrollOffsetChanged write FOnScrollOffsetChanged; { RequestHandler } property OnBeforeBrowse: TOnBeforeBrowse read FOnBeforeBrowse write FOnBeforeBrowse; property OnBeforeResourceLoad: TOnBeforeResourceLoad read FOnBeforeResourceLoad write FOnBeforeResourceLoad; @@ -345,61 +349,74 @@ TChromium = class(TCustomChromium) property Visible; property OnProcessMessageReceived; - property OnLoadStart; - property OnLoadEnd; - property OnLoadError; - property OnRenderProcessTerminated; - property OnPluginCrashed; - property OnTakeFocus; - property OnSetFocus; - property OnGotFocus; property OnBeforeContextMenu; property OnContextMenuCommand; property OnContextMenuDismissed; - property OnPreKeyEvent; - property OnKeyEvent; - property OnLoadingStateChange; + + property OnFileDialog; property OnAddressChange; property OnTitleChange; property OnTooltip; property OnStatusMessage; property OnConsoleMessage; + property OnBeforeDownload; property OnDownloadUpdated; + + property OnDragEnter; + + property OnTakeFocus; + property OnSetFocus; + property OnGotFocus; + property OnRequestGeolocationPermission; property OnCancelGeolocationPermission; - property OnJsdialog; + property OnJsdialog; property OnBeforeUnloadDialog; property OnResetDialogState; + + property OnPreKeyEvent; + property OnKeyEvent; + property OnBeforePopup; property OnAfterCreated; property OnBeforeClose; property OnRunModal; property OnClose; + + property OnLoadingStateChange; + property OnLoadStart; + property OnLoadEnd; + property OnLoadError; + + property OnScrollOffsetChanged; + + property OnBeforeBrowse; property OnBeforeResourceLoad; property OnGetResourceHandler; property OnResourceRedirect; property OnGetAuthCredentials; + property OnQuotaRequest; property OnGetCookieManager; property OnProtocolExecution; - - property OnFileDialog; - + property OnCertificateError; + property OnBeforePluginLoad; + property OnPluginCrashed; + property OnRenderProcessTerminated; property Options; property FontOptions; property DefaultEncoding; property UserStyleSheetLocation; - - property Handler; end; procedure Register; Implementation + {$IFNDEF CEF_MULTI_THREADED_MESSAGE_LOOP} Uses ExtCtrls; Var @@ -430,7 +447,7 @@ TWSChromiumControl = class(TWSWinControl) procedure Register; begin - RegisterComponents('Chromium',[TChromium]); + RegisterComponents('Chromium', [TChromium]); end; {$IFNDEF CEF_MULTI_THREADED_MESSAGE_LOOP} @@ -458,7 +475,7 @@ constructor TLCLClientHandler.Create(const crm : IChromiumEvents); begin Timer := TTimer.Create(nil); Timer.Interval := 15; - Timer.Enabled := false; + Timer.Enabled := False; Timer.OnTimer := @OnTimer; {$IFDEF DEBUG} @@ -486,7 +503,7 @@ procedure TLCLClientHandler.Cleanup; If CefInstances = 0 then begin - Timer.Enabled := false; + Timer.Enabled := False; FreeAndNil(Timer); @@ -522,8 +539,8 @@ procedure TCustomChromium.GetSettings(var settings : TCefBrowserSettings); settings.minimum_font_size := FFontOptions.MinimumFontSize; settings.minimum_logical_font_size := FFontOptions.MinimumLogicalFontSize; settings.remote_fonts := FFontOptions.RemoteFonts; - settings.default_encoding := CefString(DefaultEncoding); - settings.user_style_sheet_location := CefString(UserStyleSheetLocation); + settings.default_encoding := CefString(FDefaultEncoding); + settings.user_style_sheet_location := CefString(FUserStyleSheetLocation); settings.javascript := FOptions.Javascript; settings.javascript_open_windows := FOptions.JavascriptOpenWindows; @@ -663,9 +680,9 @@ procedure TCustomChromium.CreateBrowser; GetSettings(settings); {$IFDEF CEF_MULTI_THREADED_MESSAGE_LOOP} - CefBrowserHostCreate(@info, FHandler, FDefaultUrl, @settings, nil); + CefBrowserHostCreateBrowser(@info, FHandler, FDefaultUrl, @settings, nil); {$ELSE} - FBrowser := CefBrowserHostCreateSync(@info, FHandler, '', @settings, nil); + FBrowser := CefBrowserHostCreateBrowserSync(@info, FHandler, '', @settings, nil); FBrowserId := FBrowser.Identifier; {$ENDIF} @@ -766,8 +783,7 @@ procedure TCustomChromium.doOnBeforeClose(const Browser: ICefBrowser); procedure TCustomChromium.doOnBeforeContextMenu(const Browser: ICefBrowser; const Frame: ICefFrame; const params: ICefContextMenuParams; const model: ICefMenuModel); begin - If Assigned(FOnBeforeContextMenu) then - FOnBeforeContextMenu(Self, Browser, Frame, params, model); + If Assigned(FOnBeforeContextMenu) then FOnBeforeContextMenu(Self, Browser, Frame, params, model); end; procedure TCustomChromium.doOnBeforeDownload(const Browser: ICefBrowser; @@ -843,11 +859,17 @@ procedure TCustomChromium.doOnContextMenuDismissed(const Browser: ICefBrowser; c If Assigned(FOnContextMenuDismissed) then FOnContextMenuDismissed(Self, Browser, Frame); end; -procedure TCustomChromium.doOnCursorChange(const Browser: ICefBrowser; aCursor: TCefCursorHandle); +procedure TCustomChromium.doOnCursorChange(const Browser : ICefBrowser; + acursor : TCefCursorHandle); begin If Assigned(FOnCursorChange) then FOnCursorChange(Self, Browser, aCursor); end; +procedure TCustomChromium.doOnScrollOffsetChanged(const browser : ICefBrowser); +begin + If Assigned(FOnScrollOffsetChanged) then FOnScrollOffsetChanged(Self, browser); +end; + function TCustomChromium.doOnBeforeBrowse(const browser : ICefBrowser; const frame : ICefFrame; const request : ICefRequest; isRedirect : Boolean) : Boolean; begin @@ -866,8 +888,7 @@ function TCustomChromium.doOnDragEnter(const Browser: ICefBrowser; const dragDat mask: TCefDragOperationsMask): Boolean; begin Result := False; - If Assigned(FOnDragEnter) then - FOnDragEnter(Self, Browser, dragData, mask, Result); + If Assigned(FOnDragEnter) then FOnDragEnter(Self, Browser, dragData, mask, Result); end; function TCustomChromium.doOnFileDialog(const Browser: ICefBrowser; mode: TCefFileDialogMode; @@ -914,6 +935,12 @@ function TCustomChromium.doOnGetScreenPoint(const Browser: ICefBrowser; viewX, Result := False; end; +function TCustomChromium.doOnGetScreenInfo(const browser : ICefBrowser; + var screenInfo : TCefScreenInfo) : Boolean; +begin + Result := False; +end; + function TCustomChromium.doOnGetViewRect(const Browser: ICefBrowser; rect: PCefRect): Boolean; begin Result := False; @@ -1012,10 +1039,11 @@ procedure TCustomChromium.doOnProtocolExecution(const Browser: ICefBrowser; end; function TCustomChromium.doOnCertificateError(certError : TCefErrorcode; - const requestUrl : ustring; - callback : ICefAllowCertificateErrorCallback) : Boolean; + const requestUrl : ustring; callback : ICefAllowCertificateErrorCallback) : Boolean; begin - { TODO } + Result := False; + If Assigned(FOnCertificateError) then + FOnCertificateError(Self, certError, requestUrl, callback, Result); end; function TCustomChromium.doOnQuotaRequest(const Browser: ICefBrowser; const originUrl: ustring; @@ -1125,6 +1153,6 @@ class procedure TWSChromiumControl.DestroyHandle(const AWinControl: TWinControl) Initialization RegisterWSComponent(TCustomChromium, TWSChromiumControl); - {$I icon.lrs} + {$I icons.lrs} end. diff --git a/Component/cef3osr.pas b/Component/cef3osr.pas new file mode 100644 index 0000000..304d3a6 --- /dev/null +++ b/Component/cef3osr.pas @@ -0,0 +1,1022 @@ +(* + * Free Pascal Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Author: d.l.i.w + * Repository: http://github.com/dliw/fpCEF3 + * + *) + +Unit cef3osr; + +{$MODE objfpc}{$H+} + +{$I cef.inc} + +Interface + +Uses + Classes, SysUtils, fpTimer, + cef3types, cef3lib, cef3intf, cef3gui; + +Type + TCustomChromiumOSR = class(TComponent, IChromiumEvents) + private + FHandler: ICefClient; + FBrowser: ICefBrowser; + FBrowserId: Integer; + FDefaultUrl: ustring; + + { Client } + FOnProcessMessageReceived: TOnProcessMessageReceived; + + { ContextMenuHandler } + FOnBeforeContextMenu: TOnBeforeContextMenu; + FOnContextMenuCommand: TOnContextMenuCommand; + FOnContextMenuDismissed: TOnContextMenuDismissed; + + { DialogHandler } + FOnFileDialog: TOnFileDialog; + + { DisplayHandler } + FOnAddressChange: TOnAddressChange; + FOnTitleChange: TOnTitleChange; + FOnTooltip: TOnTooltip; + FOnStatusMessage: TOnStatusMessage; + FOnConsoleMessage: TOnConsoleMessage; + + { DownloadHandler } + FOnBeforeDownload: TOnBeforeDownload; + FOnDownloadUpdated: TOnDownloadUpdated; + + { DragHandler } + FOnDragEnter: TOnDragEnter; + + { FocusHandler } + FOnTakeFocus: TOnTakeFocus; + FOnSetFocus: TOnSetFocus; + FOnGotFocus: TOnGotFocus; + + { GeolocationHandler } + FOnRequestGeolocationPermission: TOnRequestGeolocationPermission; + FOnCancelGeolocationPermission: TOnCancelGeolocationPermission; + + { JsDialogHandler } + FOnJsdialog: TOnJsdialog; + FOnBeforeUnloadDialog: TOnBeforeUnloadDialog; + FOnResetDialogState: TOnResetDialogState; + + { KeyboardHandler } + FOnPreKeyEvent: TOnPreKeyEvent; + FOnKeyEvent: TOnKeyEvent; + + { LiveSpanHandler } + FOnBeforePopup: TOnBeforePopup; + FOnAfterCreated: TOnAfterCreated; + FOnBeforeClose: TOnBeforeClose; + FOnRunModal: TOnRunModal; + FOnClose: TOnClose; + + { LoadHandler } + FOnLoadingStateChange: TOnLoadingStateChange; + FOnLoadStart: TOnLoadStart; + FOnLoadEnd: TOnLoadEnd; + FOnLoadError: TOnLoadError; + + { RenderHandler } + FOnGetRootScreenRect: TOnGetRootScreenRect; + FOnGetViewRect: TOnGetViewRect; + FOnGetScreenPoint: TOnGetScreenPoint; + FOnGetScreenInfo: TOnGetScreenInfo; + FOnPopupShow: TOnPopupShow; + FOnPopupSize: TOnPopupSize; + FOnPaint: TOnPaint; + FOnCursorChange: TOnCursorChange; + FOnScrollOffsetChanged: TOnScrollOffsetChanged; + + { RequestHandler } + FOnBeforeBrowse: TOnBeforeBrowse; + FOnBeforeResourceLoad: TOnBeforeResourceLoad; + FOnGetResourceHandler: TOnGetResourceHandler; + FOnResourceRedirect: TOnResourceRedirect; + FOnGetAuthCredentials: TOnGetAuthCredentials; + FOnQuotaRequest: TOnQuotaRequest; + FOnGetCookieManager: TOnGetCookieManager; + FOnProtocolExecution: TOnProtocolExecution; + FOnCertificateError: TOnCertificateError; + FOnBeforePluginLoad: TOnBeforePluginLoad; + FOnPluginCrashed: TOnPluginCrashed; + FOnRenderProcessTerminated: TOnRenderProcessTerminated; + + FOptions: TChromiumOptions; + FUserStyleSheetLocation: ustring; + FDefaultEncoding: ustring; + FFontOptions: TChromiumFontOptions; + + procedure GetSettings(var settings: TCefBrowserSettings); + procedure CreateBrowser; + protected + procedure Loaded; override; + + { Client } + function doOnProcessMessageReceived(const Browser: ICefBrowser; + sourceProcess: TCefProcessId; const Message: ICefProcessMessage): Boolean; virtual; + + { ContextMenuHandler } + procedure doOnBeforeContextMenu(const Browser: ICefBrowser; const Frame: ICefFrame; + const params: ICefContextMenuParams; const model: ICefMenuModel); virtual; + function doOnContextMenuCommand(const Browser: ICefBrowser; const Frame: ICefFrame; + const params: ICefContextMenuParams; commandId: Integer; + eventFlags: TCefEventFlags): Boolean; virtual; + procedure doOnContextMenuDismissed(const Browser: ICefBrowser; const Frame: ICefFrame); virtual; + + { DialogHandler } + function doOnFileDialog(const Browser: ICefBrowser; mode: TCefFileDialogMode; + const title, defaultFileName: ustring; acceptTypes: TStrings; + const callback: ICefFileDialogCallback): Boolean; + + { DisplayHandler } + procedure doOnAddressChange(const Browser: ICefBrowser; const Frame: ICefFrame; const url: ustring); virtual; + procedure doOnTitleChange(const Browser: ICefBrowser; const title: ustring); virtual; + function doOnTooltip(const Browser: ICefBrowser; var atext: ustring): Boolean; virtual; + procedure doOnStatusMessage(const Browser: ICefBrowser; const value: ustring); virtual; + function doOnConsoleMessage(const Browser: ICefBrowser; const Message, Source: ustring; line: Integer): Boolean; virtual; + + { DownloadHandler } + procedure doOnBeforeDownload(const Browser: ICefBrowser; const downloadItem: ICefDownloadItem; + const suggestedName: ustring; const callback: ICefBeforeDownloadCallback); virtual; + procedure doOnDownloadUpdated(const Browser: ICefBrowser; const downloadItem: ICefDownloadItem; + const callback: ICefDownloadItemCallback); virtual; + + { DragHandler } + function doOnDragEnter(const Browser: ICefBrowser; const dragData: ICefDragData; mask: TCefDragOperationsMask): Boolean; virtual; + + { FocusHandler } + procedure doOnTakeFocus(const Browser: ICefBrowser; next: Boolean); virtual; + function doOnSetFocus(const Browser: ICefBrowser; Source: TCefFocusSource): Boolean; virtual; + procedure doOnGotFocus(const Browser: ICefBrowser); virtual; + + { GeolocationHandler } + procedure doOnRequestGeolocationPermission(const Browser: ICefBrowser; + const requestingUrl: ustring; requestId: Integer; const callback: ICefGeolocationCallback); virtual; + procedure doOnCancelGeolocationPermission(const Browser: ICefBrowser; + const requestingUrl: ustring; requestId: Integer); virtual; + + { JsDialogHandler } + function doOnJsdialog(const Browser: ICefBrowser; const originUrl, acceptLang: ustring; + dialogType: TCefJsDialogType; const messageText, defaultPromptText: ustring; + callback: ICefJsDialogCallback; out suppressMessage: Boolean): Boolean; virtual; + function doOnBeforeUnloadDialog(const Browser: ICefBrowser; + const messageText: ustring; isReload: Boolean; + const callback: ICefJsDialogCallback): Boolean; virtual; + procedure doOnResetDialogState(const Browser: ICefBrowser); virtual; + + { KeyboardHander } + function doOnPreKeyEvent(const Browser: ICefBrowser; const event: PCefKeyEvent; + osEvent: TCefEventHandle; out isKeyboardShortcut: Boolean): Boolean; virtual; + function doOnKeyEvent(const Browser: ICefBrowser; const event: PCefKeyEvent; + osEvent: TCefEventHandle): Boolean; virtual; + + { LiveSpanHandler } + function doOnBeforePopup(const Browser: ICefBrowser; + const Frame: ICefFrame; const targetUrl, targetFrameName: ustring; + var popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; + var client: ICefClient; var settings: TCefBrowserSettings; + var noJavascriptAccess: Boolean): Boolean; virtual; + procedure doOnAfterCreated(const Browser: ICefBrowser); virtual; + procedure doOnBeforeClose(const Browser: ICefBrowser); virtual; + function doOnRunModal(const Browser: ICefBrowser): Boolean; virtual; + function doOnClose(const Browser: ICefBrowser): Boolean; virtual; + + { LoadHandler } + procedure doOnLoadingStateChange(const Browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); virtual; + procedure doOnLoadStart(const Browser: ICefBrowser; const Frame: ICefFrame); virtual; + procedure doOnLoadEnd(const Browser: ICefBrowser; const Frame: ICefFrame; httpStatusCode: Integer); virtual; + procedure doOnLoadError(const Browser: ICefBrowser; const Frame: ICefFrame; errorCode: TCefErrorCode; + const errorText, failedUrl: ustring); virtual; + + { RenderHandler } + function doOnGetRootScreenRect(const Browser: ICefBrowser; rect: PCefRect): Boolean; + function doOnGetViewRect(const Browser: ICefBrowser; rect: PCefRect): Boolean; + function doOnGetScreenPoint(const Browser: ICefBrowser; viewX, viewY: Integer; + screenX, screenY: PInteger): Boolean; + function doOnGetScreenInfo(const browser: ICefBrowser; var screenInfo: TCefScreenInfo): Boolean; + procedure doOnPopupShow(const Browser: ICefBrowser; doshow: Boolean); + procedure doOnPopupSize(const Browser: ICefBrowser; const rect: PCefRect); + procedure doOnPaint(const Browser: ICefBrowser; kind: TCefPaintElementType; + dirtyRectsCount: TSize; const dirtyRects: PCefRectArray; + const buffer: Pointer; awidth, aheight: Integer); + procedure doOnCursorChange(const Browser: ICefBrowser; acursor: TCefCursorHandle); + procedure doOnScrollOffsetChanged(const browser: ICefBrowser); + + { RequestHandler } + function doOnBeforeBrowse(const Browser: ICefBrowser; const frame: ICefFrame; + const request: ICefRequest; isRedirect: Boolean): Boolean; virtual; + function doOnBeforeResourceLoad(const Browser: ICefBrowser; const Frame: ICefFrame; + const request: ICefRequest): Boolean; virtual; + function doOnGetResourceHandler(const Browser: ICefBrowser; const Frame: ICefFrame; + const request: ICefRequest): ICefResourceHandler; virtual; + procedure doOnResourceRedirect(const Browser: ICefBrowser; const Frame: ICefFrame; + const oldUrl: ustring; var newUrl: ustring); virtual; + function doOnGetAuthCredentials(const Browser: ICefBrowser; const Frame: ICefFrame; + isProxy: Boolean; const host: ustring; port: Integer; const realm, scheme: ustring; + const callback: ICefAuthCallback): Boolean; virtual; + function doOnQuotaRequest(const Browser: ICefBrowser; const originUrl: ustring; + newSize: Int64; const callback: ICefQuotaCallback): Boolean; virtual; + function doOnGetCookieManager(const Browser: ICefBrowser; + const mainUrl: ustring): ICefCookieManager; virtual; + procedure doOnProtocolExecution(const Browser: ICefBrowser; + const url: ustring; out allowOsExecution: Boolean); virtual; + function doOnCertificateError(certError: TCefErrorcode; const requestUrl: ustring; + callback: ICefAllowCertificateErrorCallback): Boolean; + function doOnBeforePluginLoad(const Browser: ICefBrowser; const url, policyUrl: ustring; + const info: ICefWebPluginInfo): Boolean; virtual; + procedure doOnPluginCrashed(const Browser: ICefBrowser; const pluginPath: ustring); virtual; + procedure doOnRenderProcessTerminated(const Browser: ICefBrowser; Status: TCefTerminationStatus); virtual; + + { Client } + property OnProcessMessageReceived: TOnProcessMessageReceived read FOnProcessMessageReceived write FOnProcessMessageReceived; + + { ContextMenuHandler } + property OnBeforeContextMenu: TOnBeforeContextMenu read FOnBeforeContextMenu write FOnBeforeContextMenu; + property OnContextMenuCommand: TOnContextMenuCommand read FOnContextMenuCommand write FOnContextMenuCommand; + property OnContextMenuDismissed: TOnContextMenuDismissed read FOnContextMenuDismissed write FOnContextMenuDismissed; + + { DialogHandler } + property OFileDialog: TOnFileDialog read FOnFileDialog write FOnFileDialog; + + { DisplayHandler } + property OnAddressChange: TOnAddressChange read FOnAddressChange write FOnAddressChange; + property OnTitleChange: TOnTitleChange read FOnTitleChange write FOnTitleChange; + property OnTooltip: TOnTooltip read FOnTooltip write FOnTooltip; + property OnStatusMessage: TOnStatusMessage read FOnStatusMessage write FOnStatusMessage; + property OnConsoleMessage: TOnConsoleMessage read FOnConsoleMessage write FOnConsoleMessage; + + { DownloadHandler } + property OnBeforeDownload: TOnBeforeDownload read FOnBeforeDownload write FOnBeforeDownload; + property OnDownloadUpdated: TOnDownloadUpdated read FOnDownloadUpdated write FOnDownloadUpdated; + + { DragHandler } + property OnDragEnter: TOnDragEnter read FOnDragEnter write FOnDragEnter; + + { FocusHandler } + property OnTakeFocus: TOnTakeFocus read FOnTakeFocus write FOnTakeFocus; + property OnSetFocus: TOnSetFocus read FOnSetFocus write FOnSetFocus; + property OnGotFocus: TOnGotFocus read FOnGotFocus write FOnGotFocus; + + { GeolocationHandler } + property OnRequestGeolocationPermission: TOnRequestGeolocationPermission read FOnRequestGeolocationPermission write FOnRequestGeolocationPermission; + property OnCancelGeolocationPermission: TOnCancelGeolocationPermission read FOnCancelGeolocationPermission write FOnCancelGeolocationPermission; + + { JsDialogHandler } + property OnJsdialog: TOnJsdialog read FOnJsdialog write FOnJsdialog; + property OnBeforeUnloadDialog: TOnBeforeUnloadDialog read FOnBeforeUnloadDialog write FOnBeforeUnloadDialog; + property OnResetDialogState: TOnResetDialogState read FOnResetDialogState write FOnResetDialogState; + + { KeyboardHandler } + property OnPreKeyEvent: TOnPreKeyEvent read FOnPreKeyEvent write FOnPreKeyEvent; + property OnKeyEvent: TOnKeyEvent read FOnKeyEvent write FOnKeyEvent; + + { LiveSpanHandler } + property OnBeforePopup: TOnBeforePopup read FOnBeforePopup write FOnBeforePopup; + property OnAfterCreated: TOnAfterCreated read FOnAfterCreated write FOnAfterCreated; + property OnBeforeClose: TOnBeforeClose read FOnBeforeClose write FOnBeforeClose; + property OnRunModal: TOnRunModal read FOnRunModal write FOnRunModal; + property OnClose: TOnClose read FOnClose write FOnClose; + + { LoadHandler } + property OnLoadingStateChange: TOnLoadingStateChange read FOnLoadingStateChange write FOnLoadingStateChange; + property OnLoadStart: TOnLoadStart read FOnLoadStart write FOnLoadStart; + property OnLoadEnd: TOnLoadEnd read FOnLoadEnd write FOnLoadEnd; + property OnLoadError: TOnLoadError read FOnLoadError write FOnLoadError; + + { RenderHandler } + property OnGetRootScreenRect: TOnGetRootScreenRect read FOnGetRootScreenRect write FOnGetRootScreenRect; + property OnGetViewRect: TOnGetViewRect read FOnGetViewRect write FOnGetViewRect; + property OnGetScreenPoint: TOnGetScreenPoint read FOnGetScreenPoint write FOnGetScreenPoint; + property OnGetScreenInfo: TOnGetScreenInfo read FOnGetScreenInfo write FOnGetScreenInfo; + property OnPopupShow: TOnPopupShow read FOnPopupShow write FOnPopupShow; + property OnPopupSize: TOnPopupSize read FOnPopupSize write FOnPopupSize; + property OnPaint: TOnPaint read FOnPaint write FOnPaint; + property OnCursorChange: TOnCursorChange read FOnCursorChange write FOnCursorChange; + property OnScrollOffsetChanged: TOnScrollOffsetChanged read FOnScrollOffsetChanged write FOnScrollOffsetChanged; + + { RequestHandler } + property OnBeforeBrowse: TOnBeforeBrowse read FOnBeforeBrowse write FOnBeforeBrowse; + property OnBeforeResourceLoad: TOnBeforeResourceLoad read FOnBeforeResourceLoad write FOnBeforeResourceLoad; + property OnGetResourceHandler: TOnGetResourceHandler read FOnGetResourceHandler write FOnGetResourceHandler; + property OnResourceRedirect: TOnResourceRedirect read FOnResourceRedirect write FOnResourceRedirect; + property OnGetAuthCredentials: TOnGetAuthCredentials read FOnGetAuthCredentials write FOnGetAuthCredentials; + property OnQuotaRequest: TOnQuotaRequest read FOnQuotaRequest write FOnQuotaRequest; + property OnGetCookieManager: TOnGetCookieManager read FOnGetCookieManager write FOnGetCookieManager; + property OnProtocolExecution: TOnProtocolExecution read FOnProtocolExecution write FOnProtocolExecution; + property OnCertificateError: TOnCertificateError read FOnCertificateError write FOnCertificateError; + property OnBeforePluginLoad: TOnBeforePluginLoad read FOnBeforePluginLoad write FOnBeforePluginLoad; + property OnPluginCrashed: TOnPluginCrashed read FOnPluginCrashed write FOnPluginCrashed; + property OnRenderProcessTerminated: TOnRenderProcessTerminated read FOnRenderProcessTerminated write FOnRenderProcessTerminated; + + property DefaultUrl: ustring read FDefaultUrl write FDefaultUrl; + property Options: TChromiumOptions read FOptions write FOptions; + property FontOptions: TChromiumFontOptions read FFontOptions; + property DefaultEncoding: ustring read FDefaultEncoding write FDefaultEncoding; + property UserStyleSheetLocation: ustring read FUserStyleSheetLocation write FUserStyleSheetLocation; + property BrowserId: Integer read FBrowserId; + property Browser: ICefBrowser read FBrowser; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Load(const url: ustring); + end; + + TChromiumOSR = class(TCustomChromiumOSR) + public + property BrowserId; + property Browser; + published + property DefaultUrl; + + property OnProcessMessageReceived; + + property OnBeforeContextMenu; + property OnContextMenuCommand; + property OnContextMenuDismissed; + + property OFileDialog; + + property OnAddressChange; + property OnTitleChange; + property OnTooltip; + property OnStatusMessage; + property OnConsoleMessage; + + property OnBeforeDownload; + property OnDownloadUpdated; + + property OnDragEnter; + + property OnTakeFocus; + property OnSetFocus; + property OnGotFocus; + + property OnRequestGeolocationPermission; + property OnCancelGeolocationPermission; + + property OnJsdialog; + property OnBeforeUnloadDialog; + property OnResetDialogState; + + property OnPreKeyEvent: TOnPreKeyEvent; + property OnKeyEvent: TOnKeyEvent; + + property OnBeforePopup; + property OnAfterCreated; + property OnBeforeClose; + property OnRunModal; + property OnClose; + + property OnLoadingStateChange; + property OnLoadStart; + property OnLoadEnd; + property OnLoadError; + + property OnGetRootScreenRect; + property OnGetViewRect; + property OnGetScreenPoint; + property OnGetScreenInfo; + property OnPopupShow; + property OnPopupSize; + property OnPaint; + property OnCursorChange; + property OnScrollOffsetChanged; + + property OnBeforeBrowse; + property OnBeforeResourceLoad; + property OnGetResourceHandler; + property OnResourceRedirect; + property OnGetAuthCredentials; + property OnQuotaRequest; + property OnGetCookieManager; + property OnProtocolExecution; + property OnCertificateError; + property OnBeforePluginLoad; + property OnPluginCrashed; + property OnRenderProcessTerminated; + + property Options; + property FontOptions; + property DefaultEncoding; + property UserStyleSheetLocation; + end; + +procedure Register; + +Implementation + +{$IFNDEF CEF_MULTI_THREADED_MESSAGE_LOOP} +Uses ExtCtrls; +Var + CefInstances : Integer = 0; + Timer : TFPTimer; + Looping : Boolean = False; +{$ENDIF} + +Type + + { TOSRClientHandler } + + TOSRClientHandler = class(TCustomClientHandler) + private + class procedure OnTimer(Sender : TObject); + public + constructor Create(const crm: IChromiumEvents); override; + procedure Cleanup; + procedure StartTimer; + end; + +procedure Register; +begin + RegisterComponents('Chromium', [TChromiumOSR]); +end; + +class procedure TOSRClientHandler.OnTimer(Sender : TObject); +begin + If Looping then Exit; + If CefInstances > 0 then + begin + Looping := True; + try + CefDoMessageLoopWork; + finally + Looping := False; + end; + end; +end; + +constructor TOSRClientHandler.Create(const crm : IChromiumEvents); +begin + inherited Create(crm); + + {$IFNDEF CEF_MULTI_THREADED_MESSAGE_LOOP} + If not assigned(Timer) then + begin + Timer := TFPTimer.Create(nil); + Timer.Interval := 15; + Timer.Enabled := False; + Timer.OnTimer := @OnTimer; + + {$IFDEF DEBUG} + Debugln('Timer created.'); + {$ENDIF} + end; + + InterLockedIncrement(CefInstances); + {$ENDIF} + + {$IFDEF DEBUG} + Debugln('ClientHandler instances: ', IntToStr(CefInstances)); + {$ENDIF} +end; + +procedure TOSRClientHandler.Cleanup; +begin + { TODO : Check, why Destroy; override never gets called } + {$IFDEF DEBUG} + Debugln('LCLClientHandler.Cleanup'); + {$ENDIF} + + {$IFNDEF CEF_MULTI_THREADED_MESSAGE_LOOP} + InterLockedDecrement(CefInstances); + + If CefInstances = 0 then + begin + Timer.Enabled := False; + + FreeAndNil(Timer); + + {$IFDEF DEBUG} + Debugln('Timer cleaned.'); + {$ENDIF} + end; + {$ENDIF} + + // inherited; +end; + +procedure TOSRClientHandler.StartTimer; +begin + If not Assigned(Timer) then Exit; + + Timer.Enabled := True; +end; + +{ TCustomChromiumOSR } + +procedure TCustomChromiumOSR.GetSettings(var settings : TCefBrowserSettings); +begin + If not (settings.size >= SizeOf(settings)) then raise Exception.Create('settings invalid'); + settings.standard_font_family := CefString(FFontOptions.StandardFontFamily); + settings.fixed_font_family := CefString(FFontOptions.FixedFontFamily); + settings.serif_font_family := CefString(FFontOptions.SerifFontFamily); + settings.sans_serif_font_family := CefString(FFontOptions.SansSerifFontFamily); + settings.cursive_font_family := CefString(FFontOptions.CursiveFontFamily); + settings.fantasy_font_family := CefString(FFontOptions.FantasyFontFamily); + settings.default_font_size := FFontOptions.DefaultFontSize; + settings.default_fixed_font_size := FFontOptions.DefaultFixedFontSize; + settings.minimum_font_size := FFontOptions.MinimumFontSize; + settings.minimum_logical_font_size := FFontOptions.MinimumLogicalFontSize; + settings.remote_fonts := FFontOptions.RemoteFonts; + settings.default_encoding := CefString(FDefaultEncoding); + settings.user_style_sheet_location := CefString(FUserStyleSheetLocation); + + settings.javascript := FOptions.Javascript; + settings.javascript_open_windows := FOptions.JavascriptOpenWindows; + settings.javascript_close_windows := FOptions.JavascriptCloseWindows; + settings.javascript_access_clipboard := FOptions.JavascriptAccessClipboard; + settings.javascript_dom_paste := FOptions.JavascriptDomPaste; + settings.caret_browsing := FOptions.CaretBrowsing; + settings.java := FOptions.Java; + settings.plugins := FOptions.Plugins; + settings.universal_access_from_file_urls := FOptions.UniversalAccessFromFileUrls; + settings.file_access_from_file_urls := FOptions.FileAccessFromFileUrls; + settings.web_security := FOptions.WebSecurity; + settings.image_loading := FOptions.ImageLoading; + settings.image_shrink_standalone_to_fit := FOptions.ImageShrinkStandaloneToFit; + settings.text_area_resize := FOptions.TextAreaResize; + settings.tab_to_links := FOptions.TabToLinks; + settings.author_and_user_styles := FOptions.AuthorAndUserStyles; + settings.local_storage := FOptions.LocalStorage; + settings.databases := FOptions.Databases; + settings.application_cache := FOptions.ApplicationCache; + settings.webgl := FOptions.Webgl; + settings.accelerated_compositing := FOptions.AcceleratedCompositing; +end; + +procedure TCustomChromiumOSR.CreateBrowser; +Var + info: TCefWindowInfo; + settings: TCefBrowserSettings; +begin + If not (csDesigning in ComponentState) then + begin + FillChar(info, SizeOf(info), 0); + info.window_rendering_disabled := True; + // info.transparent_painting := ???; + + FillChar(settings, SizeOf(TCefBrowserSettings), 0); + settings.size := SizeOf(TCefBrowserSettings); + GetSettings(settings); + + {$IFDEF CEF_MULTI_THREADED_MESSAGE_LOOP} + CefBrowserHostCreateBrowser(@info, FHandler, FDefaultUrl, @settings, nil); + {$ELSE} + FBrowser := CefBrowserHostCreateBrowserSync(@info, FHandler, '', @settings, nil); + FBrowserId := FBrowser.Identifier; + {$ENDIF} + + (FHandler as TOSRClientHandler).StartTimer; + end; +end; + + +procedure TCustomChromiumOSR.Loaded; +begin + inherited; + + CreateBrowser; + // Load(FDefaultUrl); +end; + +function TCustomChromiumOSR.doOnProcessMessageReceived(const Browser : ICefBrowser; + sourceProcess : TCefProcessId; const Message : ICefProcessMessage) : Boolean; +begin + Result := False; + if Assigned(FOnProcessMessageReceived) then + FOnProcessMessageReceived(Self, Browser, sourceProcess, message, Result); +end; + +procedure TCustomChromiumOSR.doOnBeforeContextMenu(const Browser : ICefBrowser; + const Frame : ICefFrame; const params : ICefContextMenuParams; const model : ICefMenuModel); +begin + If Assigned(FOnBeforeContextMenu) then FOnBeforeContextMenu(Self, Browser, frame, params, model); +end; + +function TCustomChromiumOSR.doOnContextMenuCommand(const Browser : ICefBrowser; + const Frame : ICefFrame; const params : ICefContextMenuParams; + commandId : Integer; eventFlags : TCefEventFlags) : Boolean; +begin + Result := False; + If Assigned(FOnContextMenuCommand) then + FOnContextMenuCommand(Self, Browser, frame, params, commandId, eventFlags, Result); +end; + +procedure TCustomChromiumOSR.doOnContextMenuDismissed(const Browser : ICefBrowser; + const Frame : ICefFrame); +begin + If Assigned(FOnContextMenuDismissed) then FOnContextMenuDismissed(Self, Browser, frame); +end; + +function TCustomChromiumOSR.doOnFileDialog(const Browser : ICefBrowser; + mode : TCefFileDialogMode; const title, defaultFileName : ustring; + acceptTypes : TStrings; const callback : ICefFileDialogCallback) : Boolean; +begin + Result := False; + If Assigned(FOnFileDialog) then + FOnFileDialog(Self, Browser, mode, title, defaultFileName, acceptTypes, callback, Result); +end; + +procedure TCustomChromiumOSR.doOnAddressChange(const Browser : ICefBrowser; + const Frame : ICefFrame; const url : ustring); +begin + If Assigned(FOnAddressChange) then FOnAddressChange(Self, Browser, frame, url); +end; + +procedure TCustomChromiumOSR.doOnTitleChange(const Browser : ICefBrowser; const title : ustring); +begin + If Assigned(FOnTitleChange) then FOnTitleChange(Self, Browser, title); +end; + +function TCustomChromiumOSR.doOnTooltip(const Browser : ICefBrowser; var atext : ustring) : Boolean; +begin + Result := False; + If Assigned(FOnTooltip) then FOnTooltip(Self, Browser, atext, Result); +end; + +procedure TCustomChromiumOSR.doOnStatusMessage(const Browser : ICefBrowser; const value : ustring); +begin + If Assigned(FOnStatusMessage) then FOnStatusMessage(Self, Browser, value); +end; + +function TCustomChromiumOSR.doOnConsoleMessage(const Browser : ICefBrowser; + const Message, Source : ustring; line : Integer) : Boolean; +begin + Result := False; + If Assigned(FOnConsoleMessage) then FOnConsoleMessage(Self, Browser, message, source, line, Result); +end; + +procedure TCustomChromiumOSR.doOnBeforeDownload(const Browser : ICefBrowser; + const downloadItem : ICefDownloadItem; const suggestedName : ustring; + const callback : ICefBeforeDownloadCallback); +begin + If Assigned(FOnBeforeDownload) then + OnBeforeDownload(Self, Browser, downloadItem, suggestedName, callback); +end; + +procedure TCustomChromiumOSR.doOnDownloadUpdated(const Browser : ICefBrowser; + const downloadItem : ICefDownloadItem; + const callback : ICefDownloadItemCallback); +begin + If Assigned(FOnDownloadUpdated) then FOnDownloadUpdated(Self, Browser, downloadItem, callback); +end; + +function TCustomChromiumOSR.doOnDragEnter(const Browser : ICefBrowser; + const dragData : ICefDragData; mask : TCefDragOperationsMask) : Boolean; +begin + Result := False; + If Assigned(FOnDragEnter) then FOnDragEnter(Self, Browser, dragData, mask, Result); +end; + +procedure TCustomChromiumOSR.doOnTakeFocus(const Browser : ICefBrowser; next : Boolean); +begin + If Assigned(FOnTakeFocus) then FOnTakeFocus(Self, Browser, next); +end; + +function TCustomChromiumOSR.doOnSetFocus(const Browser : ICefBrowser; + Source : TCefFocusSource) : Boolean; +begin + Result := False; + If Assigned(FOnSetFocus) then FOnSetFocus(Self, Browser, source, Result); +end; + +procedure TCustomChromiumOSR.doOnGotFocus(const Browser : ICefBrowser); +begin + If Assigned(FOnGotFocus) then FOnGotFocus(Self, Browser); +end; + +procedure TCustomChromiumOSR.doOnRequestGeolocationPermission(const Browser : ICefBrowser; + const requestingUrl : ustring; requestId : Integer; + const callback : ICefGeolocationCallback); +begin + If Assigned(FOnRequestGeolocationPermission) then + FOnRequestGeolocationPermission(Self, Browser, requestingUrl, requestId, callback); +end; + +procedure TCustomChromiumOSR.doOnCancelGeolocationPermission(const Browser : ICefBrowser; + const requestingUrl : ustring; requestId : Integer); +begin + If Assigned(FOnCancelGeolocationPermission) then + FOnCancelGeolocationPermission(Self, Browser, requestingUrl, requestId); +end; + +function TCustomChromiumOSR.doOnJsdialog(const Browser : ICefBrowser; + const originUrl, acceptLang : ustring; dialogType : TCefJsDialogType; + const messageText, defaultPromptText : ustring; + callback : ICefJsDialogCallback; out suppressMessage : Boolean) : Boolean; +begin + Result := False; + If Assigned(FOnJsdialog) then + FOnJsdialog(Self, Browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, suppressMessage, Result); +end; + +function TCustomChromiumOSR.doOnBeforeUnloadDialog(const Browser : ICefBrowser; + const messageText : ustring; isReload : Boolean; + const callback : ICefJsDialogCallback) : Boolean; +begin + Result := False; + If Assigned(FOnBeforeUnloadDialog) then + FOnBeforeUnloadDialog(Self, Browser, messageText, isReload, callback, Result); +end; + +procedure TCustomChromiumOSR.doOnResetDialogState(const Browser : ICefBrowser); +begin + If Assigned(FOnResetDialogState) then FOnResetDialogState(Self, Browser); +end; + +function TCustomChromiumOSR.doOnPreKeyEvent(const Browser : ICefBrowser; const event : PCefKeyEvent; + osEvent : TCefEventHandle; out isKeyboardShortcut : Boolean) : Boolean; +begin + Result := False; + If Assigned(FOnPreKeyEvent) then + FOnPreKeyEvent(Self, Browser, event, osEvent, isKeyboardShortcut, Result); +end; + +function TCustomChromiumOSR.doOnKeyEvent(const Browser : ICefBrowser; + const event : PCefKeyEvent; osEvent : TCefEventHandle) : Boolean; +begin + Result := False; + If Assigned(FOnKeyEvent) then FOnKeyEvent(Self, Browser, event, osEvent, Result); +end; + +function TCustomChromiumOSR.doOnBeforePopup(const Browser : ICefBrowser; + const Frame : ICefFrame; const targetUrl, targetFrameName : ustring; + var popupFeatures : TCefPopupFeatures; var windowInfo : TCefWindowInfo; + var client : ICefClient; var settings : TCefBrowserSettings; + var noJavascriptAccess : Boolean) : Boolean; +begin + Result := False; + If Assigned(FOnBeforePopup) then + FOnBeforePopup(Self, Browser, frame, targetUrl, targetFrameName, popupFeatures, + windowInfo, client, settings, noJavascriptAccess, Result); +end; + +procedure TCustomChromiumOSR.doOnAfterCreated(const Browser : ICefBrowser); +begin + If Assigned(FOnAfterCreated) then FOnAfterCreated(Self, Browser); +end; + +procedure TCustomChromiumOSR.doOnBeforeClose(const Browser : ICefBrowser); +begin + If Assigned(FOnBeforeClose) then FOnBeforeClose(Self, Browser); +end; + +function TCustomChromiumOSR.doOnRunModal(const Browser : ICefBrowser) : Boolean; +begin + Result := False; + If Assigned(FOnRunModal) then FOnRunModal(Self, Browser, Result); +end; + +function TCustomChromiumOSR.doOnClose(const Browser : ICefBrowser) : Boolean; +begin + Result := False; + if Assigned(FOnClose) then FOnClose(Self, Browser, Result); +end; + +procedure TCustomChromiumOSR.doOnLoadingStateChange(const Browser : ICefBrowser; + isLoading, canGoBack, canGoForward : Boolean); +begin + If Assigned(FOnLoadingStateChange) then + FOnLoadingStateChange(Self, Browser, isLoading, canGoBack, canGoForward); +end; + +procedure TCustomChromiumOSR.doOnLoadStart(const Browser : ICefBrowser; const Frame : ICefFrame); +begin + If Assigned(FOnLoadStart) then FOnLoadStart(Self, Browser, frame); +end; + +procedure TCustomChromiumOSR.doOnLoadEnd(const Browser : ICefBrowser; + const Frame : ICefFrame; httpStatusCode : Integer); +begin + If Assigned(FOnLoadEnd) then FOnLoadEnd(Self, Browser, frame, httpStatusCode); +end; + +procedure TCustomChromiumOSR.doOnLoadError(const Browser : ICefBrowser; + const Frame : ICefFrame; errorCode : TCefErrorCode; const errorText, failedUrl : ustring); +begin + If Assigned(FOnLoadError) then + FOnLoadError(Self, Browser, frame, errorCode, errorText, failedUrl); +end; + +function TCustomChromiumOSR.doOnGetRootScreenRect(const Browser : ICefBrowser; + rect : PCefRect) : Boolean; +begin + Result := False; + If Assigned(FOnGetRootScreenRect) then FOnGetRootScreenRect(Self, Browser, rect, Result); +end; + +function TCustomChromiumOSR.doOnGetViewRect(const Browser : ICefBrowser; rect : PCefRect) : Boolean; +begin + Result := False; + If Assigned(FOnGetViewRect) then FOnGetViewRect(Self, Browser, rect, Result); +end; + +function TCustomChromiumOSR.doOnGetScreenPoint(const Browser : ICefBrowser; + viewX, viewY : Integer; screenX, screenY : PInteger) : Boolean; +begin + Result := False; + If Assigned(FOnGetScreenPoint) then + FOnGetScreenPoint(Self, Browser, viewX, viewY, screenX, screenY, Result); +end; + +function TCustomChromiumOSR.doOnGetScreenInfo(const browser : ICefBrowser; + var screenInfo : TCefScreenInfo) : Boolean; +begin + Result := False; + If Assigned(FOnGetScreenInfo) then FOnGetScreenInfo(Self, Browser, screenInfo, Result); +end; + +procedure TCustomChromiumOSR.doOnPopupShow(const Browser : ICefBrowser; doshow : Boolean); +begin + If Assigned(FOnPopupShow) then FOnPopupShow(Self, Browser, doshow); +end; + +procedure TCustomChromiumOSR.doOnPopupSize(const Browser : ICefBrowser; const rect : PCefRect); +begin + If Assigned(FOnPopupSize) then FOnPopupSize(Self, Browser, rect); +end; + +procedure TCustomChromiumOSR.doOnPaint(const Browser : ICefBrowser; + kind : TCefPaintElementType; dirtyRectsCount : TSize; const dirtyRects : PCefRectArray; + const buffer : Pointer; awidth, aheight : Integer); +begin + If Assigned(FOnPaint) then + FOnPaint(Self, Browser, kind, dirtyRectsCount, dirtyRects, buffer, awidth, aheight); +end; + +procedure TCustomChromiumOSR.doOnCursorChange(const Browser : ICefBrowser; + acursor : TCefCursorHandle); +begin + If Assigned(FOnCursorChange) then FOnCursorChange(Self, Browser, acursor); +end; + +procedure TCustomChromiumOSR.doOnScrollOffsetChanged(const browser : ICefBrowser); +begin + If Assigned(FOnScrollOffsetChanged) then FOnScrollOffsetChanged(Self, Browser); +end; + +function TCustomChromiumOSR.doOnBeforeBrowse(const Browser : ICefBrowser; + const frame : ICefFrame; const request : ICefRequest; isRedirect : Boolean) : Boolean; +begin + Result := False; + If Assigned(FOnBeforeBrowse) then + FOnBeforeBrowse(Self, Browser, frame, request, isRedirect, Result); +end; + +function TCustomChromiumOSR.doOnBeforeResourceLoad(const Browser : ICefBrowser; + const Frame : ICefFrame; const request : ICefRequest) : Boolean; +begin + Result := False; + If Assigned(FOnBeforeResourceLoad) then FOnBeforeResourceLoad(Self, Browser, frame, request, Result); +end; + +function TCustomChromiumOSR.doOnGetResourceHandler(const Browser : ICefBrowser; + const Frame : ICefFrame; const request : ICefRequest) : ICefResourceHandler; +begin + If Assigned(FOnGetResourceHandler) then FOnGetResourceHandler(Self, Browser, frame, request, Result) + Else Result := nil; +end; + +procedure TCustomChromiumOSR.doOnResourceRedirect(const Browser : ICefBrowser; + const Frame : ICefFrame; const oldUrl : ustring; var newUrl : ustring); +begin + If Assigned(FOnResourceRedirect) then FOnResourceRedirect(Self, Browser, frame, oldUrl, newUrl); +end; + +function TCustomChromiumOSR.doOnGetAuthCredentials(const Browser : ICefBrowser; + const Frame : ICefFrame; isProxy : Boolean; const host : ustring; + port : Integer; const realm, scheme : ustring; + const callback : ICefAuthCallback) : Boolean; +begin + Result := False; + If Assigned(FOnGetAuthCredentials) then + FOnGetAuthCredentials(Self, Browser, frame, isProxy, host, port, realm, scheme, callback, Result); +end; + +function TCustomChromiumOSR.doOnQuotaRequest(const Browser : ICefBrowser; + const originUrl : ustring; newSize : Int64; const callback : ICefQuotaCallback) : Boolean; +begin + Result := False; + If Assigned(FOnQuotaRequest) then + FOnQuotaRequest(Self, Browser, originUrl, newSize, callback, Result); +end; + +function TCustomChromiumOSR.doOnGetCookieManager(const Browser : ICefBrowser; + const mainUrl : ustring) : ICefCookieManager; +begin + If Assigned(FOnGetCookieManager) then FOnGetCookieManager(Self, Browser, mainUrl, Result) + Else Result := nil; +end; + +procedure TCustomChromiumOSR.doOnProtocolExecution(const Browser : ICefBrowser; + const url : ustring; out allowOsExecution : Boolean); +begin + If Assigned(FOnProtocolExecution) then + FOnProtocolExecution(Self, Browser, url, allowOsExecution); +end; + +function TCustomChromiumOSR.doOnCertificateError(certError : TCefErrorcode; + const requestUrl : ustring; callback : ICefAllowCertificateErrorCallback) : Boolean; +begin + Result := False; + If Assigned(FOnCertificateError) then + FOnCertificateError(Self, certError, requestUrl, callback, Result); +end; + +function TCustomChromiumOSR.doOnBeforePluginLoad(const Browser : ICefBrowser; + const url, policyUrl : ustring; const info : ICefWebPluginInfo) : Boolean; +begin + Result := False; + If Assigned(FOnBeforePluginLoad) then + FOnBeforePluginLoad(Self, Browser, url, policyUrl, info, Result); +end; + +procedure TCustomChromiumOSR.doOnPluginCrashed(const Browser : ICefBrowser; + const pluginPath : ustring); +begin + If Assigned(FOnPluginCrashed) then FOnPluginCrashed(Self, Browser, pluginPath); +end; + +procedure TCustomChromiumOSR.doOnRenderProcessTerminated(const Browser : ICefBrowser; + Status : TCefTerminationStatus); +begin + If Assigned(FOnRenderProcessTerminated) then FOnRenderProcessTerminated(Self, Browser, status); +end; + +constructor TCustomChromiumOSR.Create(AOwner : TComponent); +begin + inherited; + + FDefaultUrl := 'about:blank'; + + If not (csDesigning in ComponentState) then + begin + FHandler := TOSRClientHandler.Create(Self); + + If not Assigned(FHandler) then raise Exception.Create('FHandler is nil'); + end; + + FOptions := TChromiumOptions.Create; + FFontOptions := TChromiumFontOptions.Create; + + FUserStyleSheetLocation := ''; + FDefaultEncoding := ''; + FBrowserId := 0; + FBrowser := nil; +end; + +destructor TCustomChromiumOSR.Destroy; +begin + // FreeAndNil(FCanvas); + + If FBrowser <> nil then + begin + FBrowser.StopLoad; + FBrowser.Host.ParentWindowWillClose; + end; + + If FHandler <> nil then + begin + (FHandler as TOSRClientHandler).Cleanup; + (FHandler as ICefClientHandler).Disconnect; + end; + + FHandler := nil; + FBrowser := nil; + FFontOptions.Free; + FOptions.Free; + + inherited; +end; + +procedure TCustomChromiumOSR.Load(const url : ustring); +Var Frame : ICefFrame; +begin + If FBrowser <> nil then + begin + Frame := FBrowser.MainFrame; + + If Frame <> nil then + begin + FBrowser.StopLoad; + Frame.LoadUrl(url); + end; + end; +end; + +end. + diff --git a/Component/icon.lrs b/Component/icons.lrs similarity index 51% rename from Component/icon.lrs rename to Component/icons.lrs index b58735f..3ae5549 100644 --- a/Component/icon.lrs +++ b/Component/icons.lrs @@ -52,3 +52,55 @@ LazarusResources.Add('TChromium','PNG',[ +#226#176'M'#246#199#207#174#238'*]'#151'q'#187#127'['#254#5#220#135#138#30 +#220#236'H'#214#0#0#0#0'IEND'#174'B`'#130 ]); +LazarusResources.Add('TChromiumOSR','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#0#6'bKGD'#0#255#0#255#0#255#160#189#167#147#0#0#0#9'pHYs'#0#0#1'L'#0#0#1 + +'L'#1'i'#134#189'9'#0#0#0#7'tIME'#7#222#8#16#10'0%'#29'\'#172#195#0#0#4'JIDA' + +'TH'#199#197#149'kh\E'#20#199#255'3s'#239#205#190#242#216'Mlt'#211#24#26#26 + +'['#181#193#128'l'#146#214'B'#171'h4'#5#21'?$'#31#20'+R'#17#170' '#21'[Qi' + +#161#133'*j'#213'ZZZ'#165'T?'#8'F"'#149'j_'#148'j#'#177#16#237#131'bjkj4'#233 + +#22'R['#187#224'f7'#221#189#143#185's'#252#176#217#187#143'FK'#17'q'#224#192 + +#204'='#231#254#127#247#156'9s'#7#248#143#7#187#145#224#229'o|Q'#235#144#208 + +'d'#139#149#248#188#183#215#253#215#128'''7'#29#10'J3'#253#140#224'|'#169#16 + +#162#157's'#17#5#0'W'#145#173#148#28'u'#165#26#178'ms'#227#238#141'O'#196'o' + +#8#208#211#223'/p'#22'+5M['''#184#152'%8'#3#231#28#156'3'#128#0#151#20#148'"' + +#184'J'#193'UdI'#219#218'!y'#197#134'='#235#31'K^'#23#208#211#211'/'#228'|' + +#183'O'#211#140#30'O'#152'1p'#206#188'`E'#0'Q'#14#160#136#160#20'A'#186#242 + +#162'cf'#150#238'{'#251#233#209#191#5',]?'#160#137'T'#252#171#128#223#215'm' + +#232#2#156#229#196#25'c`'#12'`'#211#209'4'#13'PyS'#4#219#145'0m'#231#162#233 + +#152#11#143'ny'#246'B^S+'#6#184#137#243#239'+'#129#238#172'eC'#186#26#12'M@' + +#136#28#4#12#200#231'@ '#15'"]'#5'GJ'#216#142#11'W'#169#168#128#216#5#224#129 + +'k2X'#177#237'T4T)F~8:Ti'#4#12'p'#206#192#25#131#16#28#130'sh'#26'Gc$'#148#14 + +#6#253#21#137#180'iH'#169'r%R'#10'T$d92'#213#24#9#173#222#186'j'#217#206#146 + +#12#12#31#173#11#6'|'#149#243#239'h'#193#240#143'gQY'#29#130#226#4'r]<'#218 + +'q[r'#225#157's'#252'i['#25#138#184#17#14#234#200#186#10#137#140#132#224#12 + +#130'3h'#130#193#208'8t'#13'UP'#244#218#214'U'#216'Y'#200#128#136#189#248#201 + +#217'+'#149#161#138#218#128'O'#224#192#254#1'\'#205'd'#16#170#14#226#241#251 + +#218#208#24#173#151'?MdJ'#202#217'R'#31#196#156#155#252#152't'#20'*t'#14#141 + +#23'|'#4#224#207#137#203#209#174#197#243'~'#231#0#176#242#163#225'6'#161#137 + +'ZMpp'#193#17#235'\'#0#199'q'#17#246#25#184'kn'#20#223#255':'#169'Me'#29#20 + +#219#169#243'Id'#28#137#186#160#14']0'#175#1#242'C'#15#249#150#0#0#7#0'e'#201 + +'&'#206#167'['#145#1#209#217#245#152#221'T'#143#174#216'\('#174'!'#157'uJ' + +#205#204#217#207#19'S'#8#234'*;'#211'Y'#210't'#163#221#3'H'#178'\V'#214#188 + +#157#247#180#162'm'#222'-'#24#187'<'#133')'#211')'#181#233','#206'\'#152'DM' + +#200'WR:*;'#2#26#0'0'#198#157'\'#219#21#162#170#170'B'#176#9#178'!'#226#211 + +#210'Yg'#198#223'@4'#236#195#228'U'#211#1'H'#167'2'#10#129#236#2#128'W$'#21 + +#17#214'=2'#199#139#217'<'#24#199'oYR'#189#11#194'j'#203#254'Q'#190#231#149 + +#197'%'#226#15#191#254#29#186'Z'#235#172#166#250#234'@9'#248#216'X'#18#142't' + +#139'N4'#17#155#206#142#222':'#24#167#252'|'#243'`'#156#134'F/'#167#243#235 + +'%k'#143#208#146#181'G<'#255#129#147#151#188#249#137#241'$'#29#31'Oz'#235#237 + +'_'#158#168'->h'#4#0#175#246#255#130#160'_'#135'ap'#188#252'`'#19#0#224#221 + +#129'8^'#186'77'#255#250#228#132'i'#187#208#193#184'8'#247'G'#6#139'n'#143 + +#160#163'9'#12#0'8>'#158#4#8#136'5'#215#148#236#1'/N'#205'r'#228#148'e'#187 + +#144#178'PQ%'#11#254#251#239'n'#240'-ko'#16'{'#135#19'h'#168#243'C'#20#247'&' + +#149'l'#176'7J'#0#233'Tj'#141'e'#187'0-Y'#2'x'#243'`'#28#27#247#142'{'#207'v' + +#172'hEoG'#180'D0'#214'\'#131#246#178#175#191#6#176'se'#231#7#169#201#228#134 + +'l'#17' cJd'#178#14'2'#166#196#154#190#17'<'#183#235#244#140'=y'#232't'#226 + +#186#183#27#21#189'B'#0'h'#245#167'#'#180#166'o'#196#219#184#231'?>M'#239#236 + +#27#243#214#199#198#10#155#250#225'@|p'#219#225's'#209'2'#157'k.'#28#207#177 + +'|'#211#225'E'#129'p'#221'v'#193#245'6E'#132#29'+ZK'#2#15#12'_'#193'U'#203'E' + +'O'#236#230#153#180#242':'#236#159'/}"'#246#212'{'#223#196't_'#240'!a'#4'z' + +#27'"'#254#200#173#179#2#194'V'#238#165'l'#198'>#'#149#243#173#206#245#207'^' + +#232'nI'#225#255#26#127#1#156#132#30#239#25#155#183#7#0#0#0#0'IEND'#174'B`' + +#130 +]); diff --git a/Examples/Examples.txt b/Examples/Examples.txt index 80952be..4c8eed5 100644 --- a/Examples/Examples.txt +++ b/Examples/Examples.txt @@ -7,9 +7,19 @@ DOMAccess GTK2Minimal Minimal gtk2 example, doesn't use LCL and classes, direct use of cef3api +JavaScript + Shows interaction with JavaScript + + Thanks to stacho for sharing: + http://www.lazarusforum.de/viewtopic.php?p=70126#p70134 + LCLSimple Simple LCL example to get started +OSRDemo + Basic example on how to use TChromiumOSR. + You need BGRAControls for this example (http://wiki.lazarus.freepascal.org/BGRAControls). + SubProcess Minimal subprocess, can be used as is as long as no custom render handler is needed diff --git a/Examples/JavaScript/handler.pas b/Examples/JavaScript/handler.pas new file mode 100644 index 0000000..ce3b223 --- /dev/null +++ b/Examples/JavaScript/handler.pas @@ -0,0 +1,94 @@ +Unit Handler; + +{$MODE objfpc}{$H+} + +(* + * Everything in here is called from a render process, so there is no access to GUI and all the + * data of the main process. + *) + +Interface + +Uses + Classes, SysUtils, + cef3lcl, cef3types, cef3intf, cef3ref, cef3own, cef3lib; + +Type + { Custom handler for the render process } + TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) + protected + // Für Test Window Bindings + procedure OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context); override; + // Für Test Extension + procedure OnWebKitInitialized; override; + end; + + TMyHandler = class(TCefv8HandlerOwn) + protected + function Execute(const name: ustring; const obj: ICefv8Value; + const arguments: TCefv8ValueArray; var retval: ICefv8Value; + var exception: ustring): Boolean; override; + end; + +Implementation + +Var + mystr : String; + +{ TMyHandler } + +function TMyHandler.Execute(const name : ustring; const obj : ICefv8Value; + const arguments : TCefv8ValueArray; var retval : ICefv8Value; + var exception : ustring) : Boolean; +begin + Result := False; + + Writeln('Execute'); +end; + +{ TCustomRenderProcessHandler } + +procedure TCustomRenderProcessHandler.OnContextCreated(const browser : ICefBrowser; + const frame : ICefFrame; const context : ICefv8Context); +Var + myWin : ICefv8Value; + str : String; + args : TCefv8ValueArray; +begin + myWin := context.GetGlobal; + mystr := 'a test string'; + SetLength(args,1); + args[0] := TCefv8ValueRef.NewString(mystr); + myWin.SetValueByKey('myval', args[0], V8_PROPERTY_ATTRIBUTE_NONE); +end; + +procedure TCustomRenderProcessHandler.OnWebKitInitialized; +Var + Code: ustring; +begin + Code := + 'var cef;'+ + 'if (!cef)'+ + ' cef = {};'+ + 'if (!cef.test)'+ + ' cef.test = {};'+ + '(function() {'+ + ' cef.test.__defineGetter__(''test_param'', function() {'+ + ' native function GetTestParam();'+ + ' return GetTestParam();'+ + ' });'+ + ' cef.test.__defineSetter__(''test_param'', function(b) {'+ + ' native function SetTestParam();'+ + ' if(b) SetTestParam(b);'+ + ' });'+ + ' cef.test.test_object = function() {'+ + ' native function GetTestObject();'+ + ' return GetTestObject();'+ + ' };'+ + '})();'; + + CefRegisterExtension('example/v8', Code, TMyHandler.Create as ICefv8Handler); +end; + +end. + diff --git a/Examples/JavaScript/js.ico b/Examples/JavaScript/js.ico new file mode 100644 index 0000000000000000000000000000000000000000..0341321b5d952e1662a3d9444a73cf9f42a7db37 GIT binary patch literal 137040 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 G`+orYGy**U literal 0 HcmV?d00001 diff --git a/Examples/JavaScript/js.lpi b/Examples/JavaScript/js.lpi new file mode 100644 index 0000000..d56cbb9 --- /dev/null +++ b/Examples/JavaScript/js.lpi @@ -0,0 +1,208 @@ + + + + + + + + + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <Icon Value="0"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <MacroValues Count="1"> + <Macro1 Name="LCLWidgetType" Value="gtk2"/> + </MacroValues> + <BuildModes Count="3"> + <Item1 Name="Linux" Default="True"/> + <Item2 Name="Win32"> + <MacroValues Count="1"> + <Macro2 Name="LCLWidgetType" Value="win32"/> + </MacroValues> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="simple32"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <AllowLabel Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True"/> + <Checks> + <IOChecks Value="True"/> + <RangeChecks Value="True"/> + <OverflowChecks Value="True"/> + </Checks> + <TargetCPU Value="i386"/> + <TargetOS Value="win32"/> + </CodeGeneration> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + </Item2> + <Item3 Name="Win64"> + <MacroValues Count="1"> + <Macro2 Name="LCLWidgetType" Value="win32"/> + </MacroValues> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="simple64"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <AllowLabel Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True"/> + <Checks> + <IOChecks Value="True"/> + <RangeChecks Value="True"/> + <OverflowChecks Value="True"/> + </Checks> + <TargetCPU Value="x86_64"/> + <TargetOS Value="win64"/> + </CodeGeneration> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + </Item3> + <SharedMatrixOptions Count="2"> + <Item1 ID="661871476567" Modes="Linux" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/> + <Item2 ID="279904151772" Modes="Win32,Win64" Type="IDEMacro" MacroName="LCLWidgetType" Value="win32"/> + </SharedMatrixOptions> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + <environment> + <UserOverrides Count="1"> + <Variable0 Name="LD_LIBRARY_PATH" Value="."/> + </UserOverrides> + </environment> + </RunParams> + <RequiredPackages Count="2"> + <Item1> + <PackageName Value="CEF3"/> + </Item1> + <Item2> + <PackageName Value="LCL"/> + </Item2> + </RequiredPackages> + <Units Count="3"> + <Unit0> + <Filename Value="js.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="js"/> + </Unit0> + <Unit1> + <Filename Value="main.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Mainform"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="Main"/> + </Unit1> + <Unit2> + <Filename Value="handler.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Handler"/> + </Unit2> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="js"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <AllowLabel Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <Checks> + <IOChecks Value="True"/> + <RangeChecks Value="True"/> + </Checks> + <TargetCPU Value="x86_64"/> + <TargetOS Value="linux"/> + </CodeGeneration> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Examples/JavaScript/js.lpr b/Examples/JavaScript/js.lpr new file mode 100644 index 0000000..a45eca0 --- /dev/null +++ b/Examples/JavaScript/js.lpr @@ -0,0 +1,20 @@ +Program js; + +{$MODE objfpc}{$H+} + +Uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, Main; + +{$R *.res} + +begin + RequireDerivedFormResource := True; + Application.Initialize; + Application.CreateForm(TMainform, Mainform); + Application.Run; +end. + diff --git a/Examples/JavaScript/main.lfm b/Examples/JavaScript/main.lfm new file mode 100644 index 0000000..ca24903 --- /dev/null +++ b/Examples/JavaScript/main.lfm @@ -0,0 +1,113 @@ +object Mainform: TMainform + Left = 186 + Height = 587 + Top = 31 + Width = 921 + Anchors = [] + Caption = 'Browser -' + ClientHeight = 587 + ClientWidth = 921 + OnCreate = FormCreate + LCLVersion = '1.2.4.0' + object Chromium: TChromium + AnchorSideLeft.Control = Owner + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = Log + Left = 0 + Height = 368 + Top = 80 + Width = 921 + Anchors = [akTop, akLeft, akRight, akBottom] + DefaultUrl = 'www.google.de' + TabOrder = 0 + OnTitleChange = ChromiumTitleChange + end + object BGo: TButton + AnchorSideTop.Control = Owner + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + Left = 837 + Height = 25 + Top = 10 + Width = 79 + Anchors = [akTop, akRight] + BorderSpacing.Top = 10 + BorderSpacing.Right = 5 + Caption = 'Go' + OnClick = BGoClick + TabOrder = 1 + end + object LUrl: TStaticText + AnchorSideTop.Control = Owner + Left = 8 + Height = 22 + Top = 12 + Width = 25 + BorderSpacing.Top = 12 + Caption = 'Url:' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 2 + end + object EUrl: TEdit + AnchorSideLeft.Control = LUrl + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = Owner + AnchorSideRight.Control = BGo + Left = 38 + Height = 25 + Top = 10 + Width = 794 + Anchors = [akTop, akLeft, akRight] + AutoSize = False + BorderSpacing.Left = 5 + BorderSpacing.Top = 10 + BorderSpacing.Right = 5 + OnKeyDown = EUrlKeyDown + TabOrder = 3 + Text = 'http://' + end + object Log: TMemo + AnchorSideLeft.Control = Owner + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 0 + Height = 139 + Top = 448 + Width = 921 + Anchors = [akLeft, akRight, akBottom] + ScrollBars = ssAutoVertical + TabOrder = 4 + end + object Button1: TButton + Left = 38 + Height = 25 + Top = 48 + Width = 75 + Caption = 'Button1' + OnClick = Button1Click + TabOrder = 5 + end + object Button2: TButton + Left = 128 + Height = 25 + Top = 48 + Width = 75 + Caption = 'Button2' + OnClick = Button2Click + TabOrder = 6 + end + object Button3: TButton + Left = 216 + Height = 25 + Top = 48 + Width = 75 + Caption = 'Button3' + OnClick = Button3Click + TabOrder = 7 + end +end diff --git a/Examples/JavaScript/main.pas b/Examples/JavaScript/main.pas new file mode 100644 index 0000000..f2386af --- /dev/null +++ b/Examples/JavaScript/main.pas @@ -0,0 +1,87 @@ +Unit Main; + +{$MODE objfpc}{$H+} + +Interface + +Uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, LCLType, ExtCtrls, + cef3types, cef3lib, cef3intf, cef3lcl, + Handler; // custom render process handler + +Type + + { TMainform } + + TMainform = class(TForm) + BGo : TButton; + Button1 : TButton; + Button2 : TButton; + Button3 : TButton; + Chromium : TChromium; + EUrl : TEdit; + LUrl : TStaticText; + Log : TMemo; + procedure BGoClick(Sender : TObject); + procedure Button1Click(Sender : TObject); + procedure Button2Click(Sender : TObject); + procedure Button3Click(Sender : TObject); + procedure ChromiumTitleChange(Sender : TObject; const Browser : ICefBrowser; + const title : ustring); + procedure EUrlKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState); + procedure FormCreate(Sender : TObject); + private + { private declarations } + public + { public declarations } + end; + +Var + Mainform : TMainform; + +Implementation + +{$R *.lfm} + +{ TMainform } + +procedure TMainform.BGoClick(Sender : TObject); +begin + Chromium.Load(EUrl.Text); +end; + +procedure TMainform.Button1Click(Sender : TObject); +begin + Chromium.Load('about:blank'); +end; + +// JavaScript shows value of window.myval +procedure TMainform.Button2Click(Sender : TObject); +begin + Chromium.Browser.MainFrame.ExecuteJavaScript('alert(window.myval);', 'about:blank', 0); +end; + +// JavaScript executes TMyHandler.Execute +procedure TMainform.Button3Click(Sender : TObject); +begin + Chromium.Browser.MainFrame.ExecuteJavaScript('cef.test.test_object().GetMessage();', 'about:blank', 0); +end; + +procedure TMainform.ChromiumTitleChange(Sender : TObject; const Browser : ICefBrowser; const title : ustring); +begin + Caption := 'Browser - ' + UTF8Encode(title); +end; + +procedure TMainform.EUrlKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState); +begin + If Key = VK_RETURN then BGoClick(Sender); +end; + +procedure TMainform.FormCreate(Sender : TObject); +begin + // No subprocess here + // If you want to use a subprocess, this CefRenderProcessHandler has to be registered in subprocess + CefRenderProcessHandler := TCustomRenderProcessHandler.Create; +end; + +end. diff --git a/Examples/OSRDemo/main.lfm b/Examples/OSRDemo/main.lfm new file mode 100644 index 0000000..22c4673 --- /dev/null +++ b/Examples/OSRDemo/main.lfm @@ -0,0 +1,84 @@ +object Mainform: TMainform + Left = 338 + Height = 475 + Top = 133 + Width = 762 + Caption = 'Browser -' + ClientHeight = 475 + ClientWidth = 762 + OnCreate = FormCreate + LCLVersion = '1.2.4.0' + object BGo: TButton + AnchorSideTop.Control = Owner + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + Left = 678 + Height = 25 + Top = 10 + Width = 79 + Anchors = [akTop, akRight] + BorderSpacing.Top = 10 + BorderSpacing.Right = 5 + Caption = 'Go' + OnClick = BGoClick + TabOrder = 0 + end + object LUrl: TStaticText + AnchorSideTop.Control = Owner + Left = 8 + Height = 22 + Top = 12 + Width = 25 + BorderSpacing.Top = 12 + Caption = 'Url:' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + end + object EUrl: TEdit + AnchorSideLeft.Control = LUrl + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = Owner + AnchorSideRight.Control = BGo + Left = 38 + Height = 25 + Top = 10 + Width = 635 + Anchors = [akTop, akLeft, akRight] + AutoSize = False + BorderSpacing.Left = 5 + BorderSpacing.Top = 10 + BorderSpacing.Right = 5 + OnKeyDown = EUrlKeyDown + TabOrder = 2 + Text = 'http://' + end + object PaintBox: TPaintBox + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = EUrl + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 0 + Height = 430 + Top = 45 + Width = 762 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Top = 10 + OnMouseDown = PaintBoxMouseDown + OnMouseMove = PaintBoxMouseMove + OnMouseUp = PaintBoxMouseUp + OnMouseWheel = PaintBoxMouseWheel + OnResize = PaintBoxResize + end + object Chromium: TChromiumOSR + DefaultUrl = 'about:blank' + OnGetRootScreenRect = ChromiumGetRootScreenRect + OnGetViewRect = ChromiumGetViewRect + OnPaint = ChromiumPaint + left = 8 + top = 40 + end +end diff --git a/Examples/OSRDemo/main.pas b/Examples/OSRDemo/main.pas new file mode 100644 index 0000000..6bf74c6 --- /dev/null +++ b/Examples/OSRDemo/main.pas @@ -0,0 +1,197 @@ +Unit Main; + +{$MODE objfpc}{$H+} + +Interface + +Uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, LCLType, ExtCtrls, + BGRABitmap, BGRABitmapTypes, + cef3types, cef3lib, cef3intf, cef3lcl, cef3osr, types; + +Type + + { TMainform } + + TMainform = class(TForm) + BGo : TButton; + Chromium : TChromiumOSR; + EUrl : TEdit; + LUrl : TStaticText; + PaintBox : TPaintBox; + procedure BGoClick(Sender : TObject); + procedure ChromiumGetRootScreenRect(Sender : TObject; + const Browser : ICefBrowser; rect : PCefRect; out Result : Boolean); + procedure ChromiumGetViewRect(Sender : TObject; + const Browser : ICefBrowser; rect : PCefRect; out Result : Boolean); + procedure ChromiumPaint(Sender : TObject; const Browser : ICefBrowser; kind : TCefPaintElementType; + dirtyRectsCount : Cardinal; const dirtyRects : PCefRectArray; const buffer : Pointer; + awidth, aheight : Integer); + procedure EUrlKeyDown(Sender : TObject; var Key : Word; + Shift : TShiftState); + procedure FormCreate(Sender : TObject); + procedure PaintBoxMouseDown(Sender : TObject; Button : TMouseButton; + Shift : TShiftState; X, Y : Integer); + procedure PaintBoxMouseMove(Sender : TObject; Shift : TShiftState; + X, Y : Integer); + procedure PaintBoxMouseUp(Sender : TObject; Button : TMouseButton; + Shift : TShiftState; X, Y : Integer); + procedure PaintBoxMouseWheel(Sender : TObject; Shift : TShiftState; + WheelDelta : Integer; MousePos : TPoint; var Handled : Boolean); + procedure PaintBoxResize(Sender : TObject); + private + { private declarations } + public + { public declarations } + end; + +Var + Mainform : TMainform; + +Implementation + +{$R *.lfm} + +function getModifiers(Shift: TShiftState): TCefEventFlags; +begin + Result := []; + if ssShift in Shift then Include(Result, EVENTFLAG_SHIFT_DOWN); + if ssAlt in Shift then Include(Result, EVENTFLAG_ALT_DOWN); + if ssCtrl in Shift then Include(Result, EVENTFLAG_CONTROL_DOWN); + if ssLeft in Shift then Include(Result, EVENTFLAG_LEFT_MOUSE_BUTTON); + if ssRight in Shift then Include(Result, EVENTFLAG_RIGHT_MOUSE_BUTTON); + if ssMiddle in Shift then Include(Result, EVENTFLAG_MIDDLE_MOUSE_BUTTON); +end; + +function getButton(Button: TMouseButton): TCefMouseButtonType; +begin + Case Button of + TMouseButton.mbLeft: Result := MBT_LEFT; + TMouseButton.mbRight: Result := MBT_RIGHT; + TMouseButton.mbMiddle: Result := MBT_MIDDLE; + end; +end; + +{ TMainform } + +procedure TMainform.BGoClick(Sender : TObject); +begin + Chromium.Load(EUrl.Text); +end; + +procedure TMainform.ChromiumGetRootScreenRect(Sender : TObject; const Browser : ICefBrowser; + rect : PCefRect; out Result : Boolean); +begin + rect^.x := 0; + rect^.y := 0; + rect^.width := PaintBox.Width; + rect^.height := PaintBox.Height; + Result := True; +end; + +procedure TMainform.ChromiumGetViewRect(Sender : TObject; const Browser : ICefBrowser; + rect : PCefRect; out Result : Boolean); +Var + Point: TPoint; +begin + Point.X := 0; + Point.Y := 0; + + Point := PaintBox.ClientToScreen(Point); + + rect^.x := Point.X; + rect^.y := Point.Y; + rect^.height := PaintBox.Height; + rect^.width := PaintBox.Width; + + Result := True; +end; + +procedure TMainform.ChromiumPaint(Sender : TObject; const Browser : ICefBrowser; + kind : TCefPaintElementType; dirtyRectsCount : Cardinal; const dirtyRects : PCefRectArray; + const buffer : Pointer; awidth, aheight : Integer); +Var + Rect : TRect; +begin + // Much more intelligent implementation possible here + + {$IFDEF WINDOWS} + Rect.Bottom := aheight; + Rect.Top := 0; + {$ELSE} + Rect.Bottom := 0; + Rect.Top := aheight; + {$ENDIF} + Rect.Left := 0; + Rect.Right := awidth; + + PaintBox.Canvas.Lock; + BGRABitmapDraw(PaintBox.Canvas, Rect, buffer, False, awidth, aheight, True); + PaintBox.Canvas.Unlock; +end; + +procedure TMainform.EUrlKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState); +begin + If Key = VK_RETURN then BGoClick(Sender); +end; + +procedure TMainform.PaintBoxMouseDown(Sender : TObject; Button : TMouseButton; + Shift : TShiftState; X, Y : Integer); +Var + MouseEvent: TCefMouseEvent; +begin + MouseEvent.x := X; + MouseEvent.y := Y; + MouseEvent.modifiers := getModifiers(Shift); + Chromium.Browser.Host.SendMouseClickEvent(MouseEvent, getButton(Button), False, 1); +end; + +procedure TMainform.PaintBoxMouseMove(Sender : TObject; Shift : TShiftState; X, Y : Integer); +Var + MouseEvent: TCefMouseEvent; +begin + MouseEvent.x := X; + MouseEvent.y := Y; + MouseEvent.modifiers := getModifiers(Shift); + + Chromium.Browser.Host.SendMouseMoveEvent(MouseEvent, not PaintBox.MouseEntered); +end; + +procedure TMainform.PaintBoxMouseUp(Sender : TObject; Button : TMouseButton; + Shift : TShiftState; X, Y : Integer); +Var + MouseEvent: TCefMouseEvent; +begin + MouseEvent.x := X; + MouseEvent.y := Y; + MouseEvent.modifiers := getModifiers(Shift); + Chromium.Browser.Host.SendMouseClickEvent(MouseEvent, getButton(Button), True, 1); +end; + +procedure TMainform.PaintBoxMouseWheel(Sender : TObject; Shift : TShiftState; WheelDelta : Integer; + MousePos : TPoint; var Handled : Boolean); +Var + MouseEvent: TCefMouseEvent; +begin + MouseEvent.x := MousePos.X; + MouseEvent.y := MousePos.Y; + MouseEvent.modifiers := getModifiers(Shift); + + Chromium.Browser.Host.SendMouseWheelEvent(MouseEvent, 0, WheelDelta); + Handled := True; +end; + +procedure TMainform.PaintBoxResize(Sender : TObject); +begin + Chromium.Browser.Host.WasResized; + Chromium.Browser.Host.SendFocusEvent(1); + Application.ProcessMessages; +end; + +procedure TMainform.FormCreate(Sender : TObject); +begin + {$INFO subprocess is set here, uncomment to use a subprocess} + //CefBrowserSubprocessPath := '.' + PathDelim + 'subprocess'{$IFDEF WINDOWS}+'.exe'{$ENDIF}; +end; + +end. diff --git a/Examples/OSRDemo/osrdemo.ico b/Examples/OSRDemo/osrdemo.ico new file mode 100644 index 0000000000000000000000000000000000000000..0341321b5d952e1662a3d9444a73cf9f42a7db37 GIT binary patch literal 137040 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 G`+orYGy**U literal 0 HcmV?d00001 diff --git a/Examples/OSRDemo/osrdemo.lpi b/Examples/OSRDemo/osrdemo.lpi new file mode 100644 index 0000000..0b2e134 --- /dev/null +++ b/Examples/OSRDemo/osrdemo.lpi @@ -0,0 +1,209 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="9"/> + <General> + <SessionStorage Value="InProjectDir"/> + <MainUnit Value="0"/> + <Title Value="osrdemo"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <Icon Value="0"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <MacroValues Count="1"> + <Macro1 Name="LCLWidgetType" Value="gtk2"/> + </MacroValues> + <BuildModes Count="3"> + <Item1 Name="Linux" Default="True"/> + <Item2 Name="Win32"> + <MacroValues Count="1"> + <Macro2 Name="LCLWidgetType" Value="win32"/> + </MacroValues> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="simple32"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <AllowLabel Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True"/> + <Checks> + <IOChecks Value="True"/> + <RangeChecks Value="True"/> + <OverflowChecks Value="True"/> + </Checks> + <TargetCPU Value="i386"/> + <TargetOS Value="win32"/> + </CodeGeneration> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + </Item2> + <Item3 Name="Win64"> + <MacroValues Count="1"> + <Macro2 Name="LCLWidgetType" Value="win32"/> + </MacroValues> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="simple64"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <AllowLabel Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <RelocatableUnit Value="True"/> + <Checks> + <IOChecks Value="True"/> + <RangeChecks Value="True"/> + <OverflowChecks Value="True"/> + </Checks> + <TargetCPU Value="x86_64"/> + <TargetOS Value="win64"/> + </CodeGeneration> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + </Item3> + <SharedMatrixOptions Count="2"> + <Item1 ID="661871476567" Modes="Linux" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/> + <Item2 ID="279904151772" Modes="Win32,Win64" Type="IDEMacro" MacroName="LCLWidgetType" Value="win32"/> + </SharedMatrixOptions> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + <environment> + <UserOverrides Count="1"> + <Variable0 Name="LD_LIBRARY_PATH" Value="."/> + </UserOverrides> + </environment> + </RunParams> + <RequiredPackages Count="3"> + <Item1> + <PackageName Value="BGRABitmapPack"/> + </Item1> + <Item2> + <PackageName Value="CEF3"/> + </Item2> + <Item3> + <PackageName Value="LCL"/> + </Item3> + </RequiredPackages> + <Units Count="2"> + <Unit0> + <Filename Value="osrdemo.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="osrdemo"/> + </Unit0> + <Unit1> + <Filename Value="main.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Mainform"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="Main"/> + </Unit1> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="osrdemo"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + <AllowLabel Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <Checks> + <IOChecks Value="True"/> + <RangeChecks Value="True"/> + <OverflowChecks Value="True"/> + <StackChecks Value="True"/> + </Checks> + <TargetCPU Value="x86_64"/> + <TargetOS Value="linux"/> + </CodeGeneration> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Examples/OSRDemo/osrdemo.lpr b/Examples/OSRDemo/osrdemo.lpr new file mode 100644 index 0000000..56524e3 --- /dev/null +++ b/Examples/OSRDemo/osrdemo.lpr @@ -0,0 +1,20 @@ +Program osrdemo; + +{$MODE objfpc}{$H+} + +Uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, Main, bgrabitmappack; + +{$R *.res} + +begin + RequireDerivedFormResource := True; + Application.Initialize; + Application.CreateForm(TMainform, Mainform); + Application.Run; +end. + diff --git a/Examples/WinMinimal/minimal.lpr b/Examples/WinMinimal/minimal.lpr index 5ad34c9..9d9cd9f 100644 --- a/Examples/WinMinimal/minimal.lpr +++ b/Examples/WinMinimal/minimal.lpr @@ -55,7 +55,7 @@ function CefWndProc(Wnd: HWND; message: UINT; wParam: Integer; lParam: Integer): info.Height := rect.bottom - rect.top; FillChar(setting, sizeof(setting), 0); setting.size := SizeOf(setting); - CefBrowserHostCreateSync(@info, handl, navigateto, @setting, nil); + CefBrowserHostCreateBrowserSync(@info, handl, navigateto, @setting, nil); SetTimer(Wnd, 1, 100, nil); result := 0; end; diff --git a/Readme.md b/Readme.md index 7348c6c..c74dca8 100644 --- a/Readme.md +++ b/Readme.md @@ -68,8 +68,8 @@ Further details can be found [here][6]. ## FAQ: ### Which versions of CEF are supported? -fpCEF3 only supports CEF3, *no* support for CEF1. -Version 3.1650 (and newer) should work. +fpCEF3 only supports CEF3, *no* support for CEF1. +See changelog for the latest supported version, older ones usually don't work, newer ones *may* work, but are *not* recommended. ### Which platforms are supported? @@ -96,14 +96,13 @@ If you feel like contributing some more Pascal examples - please do. - compatibility with Free Pascal / Lazarus - reworked unit layout - more modular - slightly changed mechanism for loading the library -- cef3api_static unit - _removed_ VLC and FMX component ### Can I help? Of course - patches are always welcome :) ### Can you help? -To a certain amount - yes, but don't expect too much. +To a certain amount - yes. ## Links: * [Chromium Embedded Framework](http://code.google.com/p/chromiumembedded) diff --git a/cef3api.pas b/cef3api.pas index a53f04f..2256602 100644 --- a/cef3api.pas +++ b/cef3api.pas @@ -4567,7 +4567,6 @@ TCefZipReader = record cef_api_hash: function(entry: Integer): PChar; cdecl; - procedure CefLoadLibrary; procedure CefCloseLibrary; diff --git a/cef3api_static.pas b/cef3api_static.pas deleted file mode 100644 index ca48218..0000000 --- a/cef3api_static.pas +++ /dev/null @@ -1,675 +0,0 @@ -(* - * Free Pascal Chromium Embedded 3 - * - * Usage allowed under the restrictions of the Lesser GNU General Public License - * or alternatively the restrictions of the Mozilla Public License 1.1 - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * Author: d.l.i.w <dev.dliw@gmail.com> - * Repository: http://github.com/dliw/fpCEF3 - * - *) - -Unit cef3api_static; - -{$MODE objfpc}{$H+} - -Interface - -Uses - cef3lib; - -{$IFDEF WINDOWS} - {$DEFINE DYNLINK} -{$ENDIF} - -{$IF Defined(DYNLINK)} -Const -{$IF Defined(WINDOWS)} - ceflib = 'libcef.dll'; -{$ELSEIF Defined(UNIX)} - ceflib = 'libcef.so'; -{$ELSE} - {$MESSAGE ERROR 'DYNLINK not supported'} -{$IFEND} -{$ELSEIF Defined(Darwin)} - {$linkframework cef} -{$ELSE} - {$LINKLIB cef} -{$ENDIF} - -// These functions set string values. If |copy| is true (1) the value will be -// copied instead of referenced. It is up to the user to properly manage -// the lifespan of references. -//function cef_string_wide_set(const src: PWideChar; src_len: Cardinal; output: PCefStringWide; copy: Integer): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_utf8_set(const src: PAnsiChar; src_len: Cardinal; output: PCefStringUtf8; copy: Integer): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_utf16_set(const src: PChar16; src_len: Cardinal; output: PCefStringUtf16; copy: Integer): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_set(const src: PCefChar; src_len: Cardinal; output: PCefString; copy: Integer): Integer; - - -// These functions clear string values. The structure itself is not freed. -//procedure cef_string_wide_clear(str: PCefStringWide); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//procedure cef_string_utf8_clear(str: PCefStringUtf8); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -procedure cef_string_utf16_clear(str: PCefStringUtf16); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -procedure cef_string_clear(str: PCefString); - - -// These functions compare two string values with the same results as strcmp(). -//function cef_string_wide_cmp(const str1, str2: PCefStringWide): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_utf8_cmp(const str1, str2: PCefStringUtf8): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_utf16_cmp(const str1, str2: PCefStringUtf16): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - - -// These functions convert between UTF-8, -16, and -32 strings. They are -// potentially slow so unnecessary conversions should be avoided. The best -// possible result will always be written to |output| with the boolean return -// value indicating whether the conversion is 100% valid. -//function cef_string_wide_to_utf8(const src: PWideChar; src_len: Cardinal; output: PCefStringUtf8): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_utf8_to_wide(const src: PAnsiChar; src_len: Cardinal; output: PCefStringWide): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -function cef_string_wide_to_utf16(const src: PWideChar; src_len: Cardinal; output: PCefStringUtf16): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_utf16_to_wide(const src: PChar16; src_len: Cardinal; output: PCefStringWide): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -function cef_string_utf8_to_utf16(const src: PAnsiChar; src_len: Cardinal; output: PCefStringUtf16): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_utf16_to_utf8(const src: PChar16; src_len: Cardinal; output: PCefStringUtf8): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -function cef_string_from_utf8(const src: PAnsiChar; src_len: Cardinal; output: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_from_utf16(const src: PChar16; src_len: Cardinal; output: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_from_wide(const src: PWideChar; src_len: Cardinal; output: PCefString): Integer; -//function cef_string_to_utf8(const src: PCefChar; src_len: Cardinal; output: PCefStringUtf8): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_to_utf16(const src: PCefChar; src_len: Cardinal; output: PCefStringUtf16): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_to_wide(const src: PCefChar; src_len: Cardinal; output: PCefStringWide): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - - -// These functions convert an ASCII string, typically a hardcoded constant, to a -// Wide/UTF16 string. Use instead of the UTF8 conversion routines if you know -// the string is ASCII. -//function cef_string_ascii_to_wide(const src: PAnsiChar; src_len: Cardinal; output: PCefStringWide): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_ascii_to_utf16(const src: PAnsiChar; src_len: Cardinal; output: PCefStringUtf16): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_from_ascii(const src: PAnsiChar; src_len: Cardinal; output: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - - -// These functions allocate a new string structure. They must be freed by -// calling the associated free function. -//function cef_string_userfree_wide_alloc(): PCefStringUserFreeWide; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_userfree_utf8_alloc(): PCefStringUserFreeUtf8; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_userfree_utf16_alloc(): PCefStringUserFreeUtf16; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_userfree_alloc(): PCefStringUserFree; - - -// These functions free the string structure allocated by the associated -// alloc function. Any string contents will first be cleared. -//procedure cef_string_userfree_wide_free(str: PCefStringUserFreeWide); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//procedure cef_string_userfree_utf8_free(str: PCefStringUserFreeUtf8); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -procedure cef_string_userfree_utf16_free(str: PCefStringUserFreeUtf16); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -procedure cef_string_userfree_free(str: PCefStringUserFree); - -{ - -// Convenience macros for copying values. -function cef_string_wide_copy(const src: PWideChar; src_len: Cardinal; output: PCefStringWide): Integer; -begin - Result := cef_string_wide_set(src, src_len, output, ord(True)) -end; - -function cef_string_utf8_copy(const src: PAnsiChar; src_len: Cardinal; output: PCefStringUtf8): Integer; -begin - Result := cef_string_utf8_set(src, src_len, output, ord(True)) -end; - -function cef_string_utf16_copy(const src: PChar16; src_len: Cardinal; output: PCefStringUtf16): Integer; -begin - Result := cef_string_utf16_set(src, src_len, output, ord(True)) -end; - -function cef_string_copy(const src: PCefChar; src_len: Cardinal; output: PCefString): Integer; -begin - Result := cef_string_set(src, src_len, output, ord(True)); -end; - -} - -// Create a new browser window using the window parameters specified by -// |windowInfo|. All values will be copied internally and the actual window will -// be created on the UI thread. This function can be called on any browser -// process thread and will not block. -function cef_browser_host_create_browser( - const windowInfo: PCefWindowInfo; client: PCefClient; - const url: PCefString; const settings: PCefBrowserSettings): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new browser window using the window parameters specified by -// |windowInfo|. This function can only be called on the browser process UI -// thread. -function cef_browser_host_create_browser_sync( - const windowInfo: PCefWindowInfo; client: PCefClient; - const url: PCefString; const settings: PCefBrowserSettings): PCefBrowser; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Perform a single iteration of CEF message loop processing. This function is -// used to integrate the CEF message loop into an existing application message -// loop. Care must be taken to balance performance against excessive CPU usage. -// This function should only be called on the main application thread and only -// if cef_initialize() is called with a CefSettings.multi_threaded_message_loop -// value of false (0). This function will not block. -procedure cef_do_message_loop_work(); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Run the CEF message loop. Use this function instead of an application- -// provided message loop to get the best balance between performance and CPU -// usage. This function should only be called on the main application thread and -// only if cef_initialize() is called with a -// CefSettings.multi_threaded_message_loop value of false (0). This function -// will block until a quit message is received by the system. -procedure cef_run_message_loop; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Quit the CEF message loop that was started by calling cef_run_message_loop(). -// This function should only be called on the main application thread and only -// if cef_run_message_loop() was used. -procedure cef_quit_message_loop; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Set to true (1) before calling Windows APIs like TrackPopupMenu that enter a -// modal message loop. Set to false (0) after exiting the modal message loop. -procedure cef_set_osmodal_loop(osModalLoop : Integer); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// This function should be called from the application entry point function to -// execute a secondary process. It can be used to run secondary processes from -// the browser client executable (default behavior) or from a separate -// executable specified by the CefSettings.browser_subprocess_path value. If -// called for the browser process (identified by no "type" command-line value) -// it will return immediately with a value of -1. If called for a recognized -// secondary process it will block until the process should exit and then return -// the process exit code. The |application| parameter may be NULL. -function cef_execute_process(const args: PCefMainArgs; application: PCefApp): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// This function should be called on the main application thread to initialize -// the CEF browser process. The |application| parameter may be NULL. A return -// value of true (1) indicates that it succeeded and false (0) indicates that it -// failed. -function cef_initialize(const args: PCefMainArgs; const settings: PCefSettings; application: PCefApp): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// This function should be called on the main application thread to shut down -// the CEF browser process before the application exits. -procedure cef_shutdown(); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Allocate a new string map. -function cef_string_map_alloc(): TCefStringMap; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -//function cef_string_map_size(map: TCefStringMap): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -function cef_string_map_size(map: TCefStringMap): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Return the value assigned to the specified key. -function cef_string_map_find(map: TCefStringMap; const key: PCefString; var value: TCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Return the key at the specified zero-based string map index. -function cef_string_map_key(map: TCefStringMap; index: Integer; var key: TCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Return the value at the specified zero-based string map index. -function cef_string_map_value(map: TCefStringMap; index: Integer; var value: TCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Append a new key/value pair at the end of the string map. -function cef_string_map_append(map: TCefStringMap; const key, value: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Clear the string map. -procedure cef_string_map_clear(map: TCefStringMap); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Free the string map. -procedure cef_string_map_free(map: TCefStringMap); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Allocate a new string map. -function cef_string_list_alloc(): TCefStringList; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Return the number of elements in the string list. -function cef_string_list_size(list: TCefStringList): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Retrieve the value at the specified zero-based string list index. Returns -// true (1) if the value was successfully retrieved. -function cef_string_list_value(list: TCefStringList; index: Integer; value: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Append a new value at the end of the string list. -procedure cef_string_list_append(list: TCefStringList; const value: PCefString); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Clear the string list. -procedure cef_string_list_clear(list: TCefStringList); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Free the string list. -procedure cef_string_list_free(list: TCefStringList); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Creates a copy of an existing string list. -function cef_string_list_copy(list: TCefStringList): TCefStringList; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - - -// Register a new V8 extension with the specified JavaScript extension code and -// handler. Functions implemented by the handler are prototyped using the -// keyword 'native'. The calling of a native function is restricted to the scope -// in which the prototype of the native function is defined. This function may -// only be called on the render process main thread. -// -// Example JavaScript extension code: -// -// // create the 'example' global object if it doesn't already exist. -// if (!example) -// example = {}; -// // create the 'example.test' global object if it doesn't already exist. -// if (!example.test) -// example.test = {}; -// (function() { -// // Define the function 'example.test.myfunction'. -// example.test.myfunction = function() { -// // Call CefV8Handler::Execute() with the function name 'MyFunction' -// // and no arguments. -// native function MyFunction(); -// return MyFunction(); -// }; -// // Define the getter function for parameter 'example.test.myparam'. -// example.test.__defineGetter__('myparam', function() { -// // Call CefV8Handler::Execute() with the function name 'GetMyParam' -// // and no arguments. -// native function GetMyParam(); -// return GetMyParam(); -// }); -// // Define the setter function for parameter 'example.test.myparam'. -// example.test.__defineSetter__('myparam', function(b) { -// // Call CefV8Handler::Execute() with the function name 'SetMyParam' -// // and a single argument. -// native function SetMyParam(); -// if(b) SetMyParam(b); -// }); -// -// // Extension definitions can also contain normal JavaScript variables -// // and functions. -// var myint = 0; -// example.test.increment = function() { -// myint += 1; -// return myint; -// }; -// })(); -// -// Example usage in the page: -// -// // Call the function. -// example.test.myfunction(); -// // Set the parameter. -// example.test.myparam = value; -// // Get the parameter. -// value = example.test.myparam; -// // Call another function. -// example.test.increment(); -// -function cef_register_extension(const extension_name, - javascript_code: PCefString; handler: PCefv8Handler): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Register a scheme handler factory for the specified |scheme_name| and -// optional |domain_name|. An NULL |domain_name| value for a standard scheme -// will cause the factory to match all domain names. The |domain_name| value -// will be ignored for non-standard schemes. If |scheme_name| is a built-in -// scheme and no handler is returned by |factory| then the built-in scheme -// handler factory will be called. If |scheme_name| is a custom scheme the -// CefRegisterCustomScheme() function should be called for that scheme. This -// function may be called multiple times to change or remove the factory that -// matches the specified |scheme_name| and optional |domain_name|. Returns false -// (0) if an error occurs. This function may be called on any thread. -function cef_register_scheme_handler_factory( - const scheme_name, domain_name: PCefString; - factory: PCefSchemeHandlerFactory): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Clear all registered scheme handler factories. Returns false (0) on error. -// This function may be called on any thread. -function cef_clear_scheme_handler_factories: Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Add an entry to the cross-origin access whitelist. -// -// The same-origin policy restricts how scripts hosted from different origins -// (scheme + domain + port) can communicate. By default, scripts can only access -// resources with the same origin. Scripts hosted on the HTTP and HTTPS schemes -// (but no other schemes) can use the "Access-Control-Allow-Origin" header to -// allow cross-origin requests. For example, https://source.example.com can make -// XMLHttpRequest requests on http://target.example.com if the -// http://target.example.com request returns an "Access-Control-Allow-Origin: -// https://source.example.com" response header. -// -// Scripts in separate frames or iframes and hosted from the same protocol and -// domain suffix can execute cross-origin JavaScript if both pages set the -// document.domain value to the same domain suffix. For example, -// scheme://foo.example.com and scheme://bar.example.com can communicate using -// JavaScript if both domains set document.domain="example.com". -// -// This function is used to allow access to origins that would otherwise violate -// the same-origin policy. Scripts hosted underneath the fully qualified -// |source_origin| URL (like http://www.example.com) will be allowed access to -// all resources hosted on the specified |target_protocol| and |target_domain|. -// If |target_domain| is non-NULL and |allow_target_subdomains| if false (0) -// only exact domain matches will be allowed. If |target_domain| is non-NULL and -// |allow_target_subdomains| is true (1) sub-domain matches will be allowed. If -// |target_domain| is NULL and |allow_target_subdomains| if true (1) all domains -// and IP addresses will be allowed. -// -// This function cannot be used to bypass the restrictions on local or display -// isolated schemes. See the comments on CefRegisterCustomScheme for more -// information. -// -// This function may be called on any thread. Returns false (0) if -// |source_origin| is invalid or the whitelist cannot be accessed. -function cef_add_cross_origin_whitelist_entry(const source_origin, target_protocol, - target_domain: PCefString; allow_target_subdomains: Integer): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Remove an entry from the cross-origin access whitelist. Returns false (0) if -// |source_origin| is invalid or the whitelist cannot be accessed. -function cef_remove_cross_origin_whitelist_entry( - const source_origin, target_protocol, target_domain: PCefString; - allow_target_subdomains: Integer): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Remove all entries from the cross-origin access whitelist. Returns false (0) -// if the whitelist cannot be accessed. -function cef_clear_cross_origin_whitelist: Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns true (1) if called on the specified thread. Equivalent to using -// cef_task_runner_t::GetForThread(threadId)->belongs_to_current_thread(). -function cef_currently_on(threadId: TCefThreadId): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Post a task for execution on the specified thread. Equivalent to using -// cef_task_runner_t::GetForThread(threadId)->PostTask(task). -function cef_post_task(threadId: TCefThreadId; task: PCefTask): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Post a task for delayed execution on the specified thread. Equivalent to -// using cef_task_runner_t::GetForThread(threadId)->PostDelayedTask(task, -// delay_ms). -function cef_post_delayed_task(threadId: TCefThreadId; - task: PCefTask; delay_ms: Int64): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Parse the specified |url| into its component parts. Returns false (0) if the -// URL is NULL or invalid. -function cef_parse_url(const url: PCefString; var parts: TCefUrlParts): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Creates a URL from the specified |parts|, which must contain a non-NULL spec -// or a non-NULL host and path (at a minimum), but not both. Returns false (0) -// if |parts| isn't initialized as described. -function cef_create_url(parts: PCefUrlParts; url: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new TCefRequest object. -function cef_request_create(): PCefRequest; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new TCefPostData object. -function cef_post_data_create(): PCefPostData; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_post_data_Element object. -function cef_post_data_element_create(): PCefPostDataElement; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_stream_reader_t object from a file. -function cef_stream_reader_create_for_file(const fileName: PCefString): PCefStreamReader; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_stream_reader_t object from data. -function cef_stream_reader_create_for_data(data: Pointer; size: Cardinal): PCefStreamReader; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_stream_reader_t object from a custom handler. -function cef_stream_reader_create_for_handler(handler: PCefReadHandler): PCefStreamReader; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_stream_writer_t object for a file. -function cef_stream_writer_create_for_file(const fileName: PCefString): PCefStreamWriter; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_stream_writer_t object for a custom handler. -function cef_stream_writer_create_for_handler(handler: PCefWriteHandler): PCefStreamWriter; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns the current (top) context object in the V8 context stack. -function cef_v8context_get_current_context(): PCefv8Context; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns the entered (bottom) context object in the V8 context stack. -function cef_v8context_get_entered_context(): PCefv8Context; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns true (1) if V8 is currently inside a context. -function cef_v8context_in_context(): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_v8value_t object of type undefined. -function cef_v8value_create_undefined(): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type null. -function cef_v8value_create_null(): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type bool. -function cef_v8value_create_bool(value: Integer): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type int. -function cef_v8value_create_int(value: Integer): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type unsigned int. -function cef_v8value_create_uint(value: Cardinal): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type double. -function cef_v8value_create_double(value: Double): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type Date. This function should only be -// called from within the scope of a cef_v8context_tHandler, cef_v8handler_t or -// cef_v8accessor_t callback, or in combination with calling enter() and exit() -// on a stored cef_v8context_t reference. -function cef_v8value_create_date(const value: PCefTime): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type string. -function cef_v8value_create_string(const value: PCefString): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_v8value_t object of type object with optional accessor. This -// function should only be called from within the scope of a -// cef_v8context_tHandler, cef_v8handler_t or cef_v8accessor_t callback, or in -// combination with calling enter() and exit() on a stored cef_v8context_t -// reference. -function cef_v8value_create_object(accessor: PCefV8Accessor): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type array with the specified |length|. -// If |length| is negative the returned array will have length 0. This function -// should only be called from within the scope of a cef_v8context_tHandler, -// cef_v8handler_t or cef_v8accessor_t callback, or in combination with calling -// enter() and exit() on a stored cef_v8context_t reference. -function cef_v8value_create_array(length: Integer): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; -// Create a new cef_v8value_t object of type function. -function cef_v8value_create_function(const name: PCefString; handler: PCefv8Handler): PCefv8Value; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns the stack trace for the currently active context. |frame_limit| is -// the maximum number of frames that will be captured. -function cef_v8stack_trace_get_current(frame_limit: Integer): PCefV8StackTrace; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_xml_reader_t object. The returned object's functions can -// only be called from the thread that created the object. -function cef_xml_reader_create(stream: PCefStreamReader; - encodingType: TCefXmlEncodingType; const URI: PCefString): PCefXmlReader; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_zip_reader_t object. The returned object's functions can -// only be called from the thread that created the object. -function cef_zip_reader_create(stream: PCefStreamReader): PCefZipReader; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Allocate a new string multimap. -function cef_string_multimap_alloc: TCefStringMultimap; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Return the number of elements in the string multimap. -function cef_string_multimap_size(map: TCefStringMultimap): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Return the number of values with the specified key. -function cef_string_multimap_find_count(map: TCefStringMultimap; const key: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Return the value_index-th value with the specified key. -function cef_string_multimap_enumerate(map: TCefStringMultimap; - const key: PCefString; value_index: Integer; var value: TCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Return the key at the specified zero-based string multimap index. -function cef_string_multimap_key(map: TCefStringMultimap; index: Integer; var key: TCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Return the value at the specified zero-based string multimap index. -function cef_string_multimap_value(map: TCefStringMultimap; index: Integer; var value: TCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Append a new key/value pair at the end of the string multimap. -function cef_string_multimap_append(map: TCefStringMultimap; const key, value: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Clear the string multimap. -procedure cef_string_multimap_clear(map: TCefStringMultimap); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Free the string multimap. -procedure cef_string_multimap_free(map: TCefStringMultimap); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -function cef_build_revision: Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns the global cookie manager. By default data will be stored at -// CefSettings.cache_path if specified or in memory otherwise. -function cef_cookie_manager_get_global_manager(): PCefCookieManager; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Creates a new cookie manager. If |path| is NULL data will be stored in memory -// only. Returns NULL if creation fails. -function cef_cookie_manager_create_manager(const path: PCefString): PCefCookieManager; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_command_line_t instance. -function cef_command_line_create(): PCefCommandLine; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns the singleton global cef_command_line_t object. The returned object -// will be read-only. -function cef_command_line_get_global(): PCefCommandLine; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - - -// Create a new cef_process_message_t object with the specified name. -function cef_process_message_create(const name: PCefString): PCefProcessMessage; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Creates a new object that is not owned by any other object. The specified -// |data| will be copied. -function cef_binary_value_create(const data: Pointer; data_size: Cardinal): PCefBinaryValue; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Creates a new object that is not owned by any other object. -function cef_dictionary_value_create: PCefDictionaryValue; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Creates a new object that is not owned by any other object. -function cef_list_value_create: PCefListValue; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Retrieve the path associated with the specified |key|. Returns true (1) on -// success. Can be called on any thread in the browser process. -function cef_get_path(key: TCefPathKey; path: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Launches the process specified via |command_line|. Returns true (1) upon -// success. Must be called on the browser process TID_PROCESS_LAUNCHER thread. -// -// Unix-specific notes: - All file descriptors open in the parent process will -// be closed in the -// child process except for stdin, stdout, and stderr. -// - If the first argument on the command line does not contain a slash, -// PATH will be searched. (See man execvp.) -function cef_launch_process(command_line: PCefCommandLine): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new cef_response_t object. -function cef_response_create: PCefResponse; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Create a new URL request. Only GET, POST, HEAD, DELETE and PUT request -// functions are supported. The |request| object will be marked as read-only -// after calling this function. -function cef_urlrequest_create(request: PCefRequest; client: PCefUrlRequestClient): PCefUrlRequest; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Visit web plugin information. -procedure cef_visit_web_plugin_info(visitor: PCefWebPluginInfoVisitor); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Cause the plugin list to refresh the next time it is accessed regardless of -// whether it has already been loaded. Can be called on any thread in the -// browser process. -procedure cef_refresh_web_plugins; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Add a plugin path (directory + file). This change may not take affect until -// after cef_refresh_web_plugins() is called. Can be called on any thread in the -// browser process. -procedure cef_add_web_plugin_path(const path: PCefString); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Add a plugin directory. This change may not take affect until after -// cef_refresh_web_plugins() is called. Can be called on any thread in the -// browser process. -procedure cef_add_web_plugin_directory(const dir: PCefString); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Remove a plugin path (directory + file). This change may not take affect -// until after cef_refresh_web_plugins() is called. Can be called on any thread -// in the browser process. -procedure cef_remove_web_plugin_path(const path: PCefString); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Unregister an internal plugin. This may be undone the next time -// cef_refresh_web_plugins() is called. Can be called on any thread in the -// browser process. -procedure cef_unregister_internal_web_plugin(const path: PCefString); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Force a plugin to shutdown. Can be called on any thread in the browser -// process but will be executed on the IO thread. -procedure cef_force_web_plugin_shutdown(const path: PCefString); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Register a plugin crash. Can be called on any thread in the browser process -// but will be executed on the IO thread. -procedure cef_register_web_plugin_crash(const path: PCefString); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Query if a plugin is unstable. Can be called on any thread in the browser -// process. -procedure cef_is_web_plugin_unstable(const path: PCefString; - callback: PCefWebPluginUnstableCallback); cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Request a one-time geolocation update. This function bypasses any user -// permission checks so should only be used by code that is allowed to access -// location information. -function cef_get_geolocation(callback: PCefGetGeolocationCallback): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns the task runner for the current thread. Only CEF threads will have -// task runners. An NULL reference will be returned if this function is called -// on an invalid thread. -function cef_task_runner_get_for_current_thread: PCefTaskRunner; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Returns the task runner for the specified CEF thread. -function cef_task_runner_get_for_thread(threadId: TCefThreadId): PCefTaskRunner; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - - - -// Start tracing events on all processes. Tracing begins immediately locally, -// and asynchronously on child processes as soon as they receive the -// BeginTracing request. -// -// If CefBeginTracing was called previously, or if a CefEndTracingAsync call is -// pending, CefBeginTracing will fail and return false (0). -// -// |categories| is a comma-delimited list of category wildcards. A category can -// have an optional '-' prefix to make it an excluded category. Having both -// included and excluded categories in the same list is not supported. -// -// Example: "test_MyTest*" Example: "test_MyTest*,test_OtherStuff" Example: -// "-excluded_category1,-excluded_category2" -// -// This function must be called on the browser process UI thread. -function cef_begin_tracing(client: PCefTraceClient; const categories: PCefString): Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Get the maximum trace buffer percent full state across all processes. -// -// cef_trace_client_t::OnTraceBufferPercentFullReply will be called -// asynchronously after the value is determibed. When any child process reaches -// 100% full tracing will end automatically and -// cef_trace_client_t::OnEndTracingComplete will be called. This function fails -// and returns false (0) if trace is ending or disabled, no cef_trace_client_t -// was passed to CefBeginTracing, or if a previous call to -// CefGetTraceBufferPercentFullAsync is pending. -// -// This function must be called on the browser process UI thread. -function cef_get_trace_buffer_percent_full_async: Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -// Stop tracing events on all processes. -// -// This function will fail and return false (0) if a previous call to -// CefEndTracingAsync is already pending or if CefBeginTracing was not called. -// -// This function must be called on the browser process UI thread. -function cef_end_tracing_async: Integer; cdecl; external {$IFDEF DYNLINK}ceflib{$ENDIF}; - -{external {$IFDEF DYNLINK}ceflib{$ENDIF};} - -Implementation - -Uses Math; - -function cef_string_set(const src : PCefChar; src_len : Cardinal; output : PCefString; copy : Integer) : Integer; -begin - {$IFDEF CEF_STRING_TYPE_UTF16} - Result := cef_string_set(src, src_len, output, copy); - {$ENDIF} -end; - -procedure cef_string_clear(str : PCefString); -begin - {$IFDEF CEF_STRING_TYPE_UTF16} - cef_string_utf16_clear(str); - {$ENDIF} -end; - -function cef_string_from_wide(const src : PWideChar; src_len : Cardinal; output : PCefString) : Integer; -begin - {$IFDEF CEF_STRING_TYPE_UTF16} - Result := cef_string_wide_to_utf16(src, src_len, output); - {$ENDIF} -end; - -function cef_string_userfree_alloc : PCefStringUserFree; -begin - {$IFDEF CEF_STRING_TYPE_UTF16} - Result := cef_string_userfree_utf16_alloc; - {$ENDIF} -end; - -procedure cef_string_userfree_free(str : PCefStringUserFree); -begin - {$IFDEF CEF_STRING_TYPE_UTF16} - cef_string_userfree_utf16_free(str); - {$ENDIF} -end; - -Initialization - // Set exception masks - Set8087CW(Get8087CW or $3F); - SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]); - -end. \ No newline at end of file diff --git a/cef3gui.pas b/cef3gui.pas index 58a24e4..61924ca 100644 --- a/cef3gui.pas +++ b/cef3gui.pas @@ -116,15 +116,18 @@ rect: PCefRect; out Result: Boolean) of object; TOnGetScreenPoint = procedure(Sender: TObject; const Browser: ICefBrowser; viewX, viewY: Integer; screenX, screenY: PInteger; out Result: Boolean) of object; + TOnGetScreenInfo = procedure(Sender: TObject; const browser : ICefBrowser; + var screenInfo : TCefScreenInfo; out Result: Boolean) of object; TOnPopupShow = procedure(Sender: TObject; const Browser: ICefBrowser; - show: Boolean) of Object; + show_: Boolean) of object; TOnPopupSize = procedure(Sender: TObject; const Browser: ICefBrowser; const rect: PCefRect) of object; TOnPaint = procedure(Sender: TObject; const Browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: Cardinal; const dirtyRects: PCefRectArray; - const buffer: Pointer; width, height: Integer) of object; + const buffer: Pointer; awidth, aheight: Integer) of object; TOnCursorChange = procedure(Sender: TObject; const Browser: ICefBrowser; cursor: TCefCursorHandle) of object; + TOnScrollOffsetChanged = procedure(Sender: TObject; const Browser: ICefBrowser) of object; { RequestHandler } TOnBeforeBrowse = procedure(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; @@ -145,8 +148,8 @@ const mainUrl: ustring; out Result: ICefCookieManager) of object; TOnProtocolExecution = procedure(Sender: TObject; const Browser: ICefBrowser; const url: ustring; out allowOsExecution: Boolean) of object; - TOnCertificateError = function(Sender: TObject; certError: TCefErrorcode; const requestUrl: ustring; - callback: ICefAllowCertificateErrorCallback): Boolean of object; + TOnCertificateError = procedure(Sender: TObject; certError: TCefErrorcode; const requestUrl: ustring; + callback: ICefAllowCertificateErrorCallback; out Result: Boolean) of object; TOnBeforePluginLoad = procedure(Sender: TObject; const Browser: ICefBrowser; const url, policyUrl: ustring; const info: ICefWebPluginInfo; out Result: Boolean) of object; TOnPluginCrashed = procedure(Sender: TObject; const browser: ICefBrowser; const plugin_path: ustring) of object; @@ -312,14 +315,14 @@ TChromiumFontOptions = class(TPersistent) function doOnGetViewRect(const browser: ICefBrowser; rect: PCefRect): Boolean; function doOnGetScreenPoint(const browser: ICefBrowser; viewX, viewY: Integer; screenX, screenY: PInteger): Boolean; - // function doGetSceenInfo(browser: ICefBrowser; var screenInfo: PCefScreenInfo): Boolean; { TODO } + function doOnGetScreenInfo(const browser: ICefBrowser; var screenInfo: TCefScreenInfo): Boolean; procedure doOnPopupShow(const browser: ICefBrowser; show: Boolean); procedure doOnPopupSize(const browser: ICefBrowser; const rect: PCefRect); procedure doOnPaint(const browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: TSize; const dirtyRects: PCefRectArray; const buffer: Pointer; width, height: Integer); procedure doOnCursorChange(const browser: ICefBrowser; cursor: TCefCursorHandle); - //procedure doOnScrollOffsetChanged(const browser: ICefBrowser); { TODO } + procedure doOnScrollOffsetChanged(const browser: ICefBrowser); { CefRequestHandler } function doOnBeforeBrowse(const browser: ICefBrowser; const frame: ICefFrame; @@ -557,12 +560,14 @@ TCustomRenderHandler = class(TCefRenderHandlerOwn) function GetViewRect(const Browser: ICefBrowser; rect: PCefRect): Boolean; override; function GetScreenPoint(const Browser: ICefBrowser; viewX, viewY: Integer; screenX, screenY: PInteger): Boolean; override; + function GetScreenInfo(const Browser: ICefBrowser; screenInfo: PCefScreenInfo): Boolean; override; procedure OnPopupShow(const Browser: ICefBrowser; show: Boolean); override; procedure OnPopupSize(const Browser: ICefBrowser; const rect: PCefRect); override; procedure OnPaint(const Browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: TSize; const dirtyRects: PCefRectArray; const buffer: Pointer; width, height: Integer); override; procedure OnCursorChange(const Browser: ICefBrowser; cursor: TCefCursorHandle); override; + procedure OnScrollOffsetChanged(const Browser: ICefBrowser); override; public constructor Create(const events: IChromiumEvents); reintroduce; virtual; end; @@ -612,6 +617,7 @@ constructor TCustomClientHandler.Create(const events: IChromiumEvents); FKeyboardHandler := TCustomKeyboardHandler.Create(events); FDisplayHandler := TCustomDisplayHandler.Create(events); FDownloadHandler := TCustomDownloadHandler.Create(events); + FDragHandler := TCustomDragHandler.Create(events); FGeolocationHandler := TCustomGeolocationHandler.Create(events); FJsDialogHandler := TCustomJsDialogHandler.Create(events); FLifeSpanHandler := TCustomLifeSpanHandler.Create(events); @@ -629,6 +635,7 @@ procedure TCustomClientHandler.Disconnect; FKeyboardHandler := nil; FDisplayHandler := nil; FDownloadHandler := nil; + FDragHandler := nil; FGeolocationHandler := nil; FJsDialogHandler := nil; FLifeSpanHandler := nil; @@ -1055,6 +1062,12 @@ function TCustomRenderHandler.GetScreenPoint(const Browser: ICefBrowser; viewX, Result := FEvent.doOnGetScreenPoint(Browser, viewX, viewY, screenX, screenY); end; +function TCustomRenderHandler.GetScreenInfo(const Browser : ICefBrowser; + screenInfo : PCefScreenInfo) : Boolean; +begin + Result := FEvent.doOnGetScreenInfo(Browser, screenInfo^); +end; + function TCustomRenderHandler.GetViewRect(const Browser: ICefBrowser; rect: PCefRect): Boolean; begin Result := FEvent.doOnGetViewRect(Browser, rect); @@ -1065,6 +1078,11 @@ procedure TCustomRenderHandler.OnCursorChange(const Browser: ICefBrowser; cursor FEvent.doOnCursorChange(Browser, cursor); end; +procedure TCustomRenderHandler.OnScrollOffsetChanged(const Browser : ICefBrowser); +begin + FEvent.doOnScrollOffsetChanged(Browser); +end; + procedure TCustomRenderHandler.OnPaint(const Browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: TSize; const dirtyRects: PCefRectArray; const buffer: Pointer; width, height: Integer); diff --git a/cef3intf.pas b/cef3intf.pas index d7a72bb..d44c849 100644 --- a/cef3intf.pas +++ b/cef3intf.pas @@ -700,7 +700,7 @@ function GetViewRect(const browser: ICefBrowser; rect: PCefRect): Boolean; function GetScreenPoint(const browser: ICefBrowser; viewX, viewY: Integer; screenX, screenY: PInteger): Boolean; - function GetScreenInfo(browser: ICefBrowser; screenInfo: PCefScreenInfo): Boolean; + function GetScreenInfo(const browser: ICefBrowser; screenInfo: PCefScreenInfo): Boolean; procedure OnPopupShow(const browser: ICefBrowser; show: Boolean); procedure OnPopupSize(const browser: ICefBrowser; const rect: PCefRect); procedure OnPaint(const browser: ICefBrowser; aType: TCefPaintElementType; @@ -901,14 +901,14 @@ ICefUrlRequest = interface(ICefBase) ['{59226AC1-A0FA-4D59-9DF4-A65C42391A67}'] function GetRequest: ICefRequest; - function GetClient: ICefClient; {$NOTE !} + function GetClient: ICefUrlRequestClient; function GetRequestStatus: TCefUrlRequestStatus; function GetRequestError: TCefErrorcode; function GetResponse: ICefResponse; procedure Cancel; end; - ICefUrlrequestClient = interface(ICefBase) ['{114155BD-C248-4651-9A4F-26F3F9A4F737}'] + ICefUrlRequestClient = interface(ICefBase) ['{114155BD-C248-4651-9A4F-26F3F9A4F737}'] procedure OnRequestComplete(const request: ICefUrlRequest); procedure OnUploadProgress(const request: ICefUrlRequest; current, total: UInt64); procedure OnDownloadProgress(const request: ICefUrlRequest; current, total: UInt64); @@ -939,7 +939,6 @@ var exception: ustring): Boolean; end; - {$NOTE (u)string ?} ICefV8Accessor = interface(ICefBase) ['{DCA6D4A2-726A-4E24-AA64-5E8C731D868A}'] function Get(const name: ustring; const obj: ICefv8Value; out value: ICefv8Value; const exception: string): Boolean; diff --git a/cef3lib.pas b/cef3lib.pas index a74c7d0..a3afaef 100644 --- a/cef3lib.pas +++ b/cef3lib.pas @@ -73,8 +73,7 @@ function CefRemoveCrossOriginWhitelistEntry( AllowTargetSubdomains: Boolean): Boolean; function CefClearCrossOriginWhitelist: Boolean; -function CefRegisterExtension(const name, code: ustring; - const Handler: ICefv8Handler): Boolean; +function CefRegisterExtension(const name, code: ustring; const Handler: ICefv8Handler): Boolean; function CefCurrentlyOn(ThreadId: TCefThreadId): Boolean; procedure CefPostTask(ThreadId: TCefThreadId; const task: ICefTask); procedure CefPostDelayedTask(ThreadId: TCefThreadId; const task: ICefTask; delayMs: Int64); @@ -105,14 +104,14 @@ procedure CefRunMessageLoop; procedure CefQuitMessageLoop; {$ENDIF} -function CefBrowserHostCreateSync(windowInfo: PCefWindowInfo; const client: ICefClient; +function CefBrowserHostCreateBrowserSync(windowInfo: PCefWindowInfo; const client: ICefClient; const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): ICefBrowser; function CefBrowserHostCreateBrowser(windowInfo: PCefWindowInfo; const client: ICefClient; const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): Boolean; -function CefRequestCreate:ICefRequest; -function CefPostDataCreate:ICefPostData; -function CefPostDataElementCreate:ICefPostDataElement; +function CefRequestCreate: ICefRequest; +function CefPostDataCreate: ICefPostData; +function CefPostDataElementCreate: ICefPostDataElement; function CefBeginTracing(const client: ICefTraceClient; const categories: ustring): Boolean; function CefGetTraceBufferPercentFullAsync: Integer; @@ -209,7 +208,6 @@ function CefInitialize(const Cache, UserAgent, ProductVersion, Locale, LogFile, ErrCode: Integer; Args : TCefMainArgs; - i : Integer; begin {$IFDEF DEBUG} Debugln('CefInitialize'); @@ -442,12 +440,12 @@ function CefClearCrossOriginWhitelist: Boolean; Result := cef_clear_cross_origin_whitelist() <> 0; end; -function CefRegisterExtension(const name, code: ustring; - const Handler: ICefv8Handler): Boolean; +function CefRegisterExtension(const name, code: ustring; const Handler: ICefv8Handler): Boolean; Var n, c: TCefString; begin - CefInitDefault; + { TODO : Hier wird doppelt initialisiert? } + //CefInitDefault; n := CefString(name); c := CefString(code); Result := cef_register_extension(@n, @c, CefGetData(handler)) <> 0; @@ -615,19 +613,7 @@ procedure CefQuitMessageLoop; end; {$ENDIF} -{$NOTE duplicate? } -function CefBrowserHostCreate(windowInfo: PCefWindowInfo; const client: ICefClient; - const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): Boolean; - -Var - u: TCefString; -begin - CefInitDefault; - u := CefString(url); - Result := cef_browser_host_create_browser(windowInfo, CefGetData(client), @u, settings, CefGetData(requestContext)) <> 0; -end; - -function CefBrowserHostCreateSync(windowInfo: PCefWindowInfo; const client: ICefClient; +function CefBrowserHostCreateBrowserSync(windowInfo: PCefWindowInfo; const client: ICefClient; const url: ustring; const settings: PCefBrowserSettings; const requestContext: ICefRequestContext): ICefBrowser; Var u: TCefString; @@ -767,4 +753,4 @@ procedure TC.Execute; Finalization CefShutDown; -end. +end. \ No newline at end of file diff --git a/cef3own.pas b/cef3own.pas index 37def50..dd13f08 100644 --- a/cef3own.pas +++ b/cef3own.pas @@ -286,14 +286,14 @@ TCefRenderHandlerOwn = class(TCefBaseOwn, ICefRenderHandler) function GetViewRect(const browser: ICefBrowser; rect: PCefRect): Boolean; virtual; function GetScreenPoint(const browser: ICefBrowser; viewX, viewY: Integer; screenX, screenY: PInteger): Boolean; virtual; - function GetScreenInfo(browser: ICefBrowser; screenInfo: PCefScreenInfo): Boolean; + function GetScreenInfo(const browser: ICefBrowser; screenInfo: PCefScreenInfo): Boolean; virtual; procedure OnPopupShow(const browser: ICefBrowser; show: Boolean); virtual; procedure OnPopupSize(const browser: ICefBrowser; const rect: PCefRect); virtual; procedure OnPaint(const browser: ICefBrowser; kind: TCefPaintElementType; dirtyRectsCount: TSize; const dirtyRects: PCefRectArray; const buffer: Pointer; width, height: Integer); virtual; procedure OnCursorChange(const browser: ICefBrowser; cursor: TCefCursorHandle); virtual; - procedure OnScrollOffsetChanged(const browser: ICefBrowser); + procedure OnScrollOffsetChanged(const browser: ICefBrowser); virtual; public constructor Create; virtual; end; @@ -364,7 +364,7 @@ TCefRequestHandlerOwn = class(TCefBaseOwn, ICefRequestHandler) function OnBeforePluginLoad(const browser: ICefBrowser; const url, policyUrl: ustring; const info: ICefWebPluginInfo): Boolean; virtual; function OnCertificateError(certError: TCefErrorcode; const requestUrl: ustring; - callback: ICefAllowCertificateErrorCallback): Boolean; {$NOTE !} + callback: ICefAllowCertificateErrorCallback): Boolean; procedure OnPluginCrashed(const browser: ICefBrowser; const plugin_path: ustring); procedure OnRenderProcessTerminated(const browser: ICefBrowser; status: TCefTerminationStatus); public @@ -623,7 +623,7 @@ function cef_drag_handler_on_drag_enter(self: PCefDragHandler; browser: PCefBrow dragData: PCefDragData; mask: TCefDragOperationsMask): Integer; cconv; begin Result := Ord(TCefDragHandlerOwn(CefGetObject(self)).OnDragEnter( - TCefBrowserRef.UnWrap(browser), TCefDragDataRef(dragData), mask)); + TCefBrowserRef.UnWrap(browser), TCefDragDataRef.UnWrap(dragData), mask)); end; function TCefDragHandlerOwn.OnDragEnter(const browser : ICefBrowser; const dragData : ICefDragData; @@ -672,7 +672,7 @@ constructor TCefBaseOwn.CreateData(size : TSize; owned : Boolean); destructor TCefBaseOwn.Destroy; begin {$IFDEF DEBUG} - WriteLn(Self.ClassName, '.Destroy; RefCount: ', Self.RefCount); + DebugLn(Self.ClassName, '.Destroy; RefCount: ', Self.RefCount); {$ENDIF} Dec(FData, SizeOf(Pointer)); @@ -1789,8 +1789,7 @@ procedure cef_render_handler_on_paint(self : PCefRenderHandler; browser: PCefBro const buffer : Pointer; width, height : Integer); cconv; begin With TCefRenderHandlerOwn(CefGetObject(self)) do - OnPaint(TCefBrowserRef.UnWrap(browser), type_, dirtyRectsCount, dirtyRects, - buffer, width, height); + OnPaint(TCefBrowserRef.UnWrap(browser), type_, dirtyRectsCount, dirtyRects, buffer, width, height); end; procedure cef_render_handler_on_cursor_change(self : PCefRenderHandler; browser : PCefBrowser; @@ -1823,7 +1822,7 @@ function TCefRenderHandlerOwn.GetScreenPoint(const browser : ICefBrowser; Result := False; end; -function TCefRenderHandlerOwn.GetScreenInfo(browser : ICefBrowser; +function TCefRenderHandlerOwn.GetScreenInfo(const browser : ICefBrowser; screenInfo : PCefScreenInfo) : Boolean; begin Result := False; @@ -2269,8 +2268,6 @@ function cef_request_handler_on_before_plugin_load(self : PCefRequestHandler; br function cef_request_handler_on_certificate_error(self : PCefRequestHandler; cert_error : TCefErrorcode; const request_url : PCefString; callback : PCefAllowCertificateErrorCallback) : Integer; cconv; -Var - r : ustring; begin With TCefRequestHandlerOwn(CefGetObject(self)) do Result := Ord(OnCertificateError(cert_error, CefString(request_url), diff --git a/cef3ref.pas b/cef3ref.pas index b6489ee..0867e80 100644 --- a/cef3ref.pas +++ b/cef3ref.pas @@ -96,9 +96,9 @@ TCefBrowserHostRef = class(TCefBaseRef, ICefBrowserHost) procedure WasResized; procedure WasHidden(hidden: Boolean); procedure NotifyScreenInfoChanged; - procedure Invalidate(const dirtyRect:PCefRect; const aType:TCefPaintElementType); + procedure Invalidate(const dirtyRect: PCefRect; const aType: TCefPaintElementType); procedure SendKeyEvent(const event:TCefKeyEvent); - procedure SendMouseClickEvent(const event:TCefMouseEvent; aType:TCefMouseButtonType; + procedure SendMouseClickEvent(const event: TCefMouseEvent; aType: TCefMouseButtonType; mouseUp: Boolean; clickCount: Integer); procedure SendMouseMoveEvent(event:TCefMouseEvent; mouseLeave:boolean); procedure SendMouseWheelEvent(const event:TCefMouseEvent; deltaX, deltaY: Integer); @@ -596,7 +596,7 @@ TCefTaskRunnerRef = class(TCefBaseRef, ICefTaskRunner) TCefUrlRequestRef = class(TCefBaseRef, ICefUrlRequest) protected function GetRequest: ICefRequest; - function GetClient: ICefClient; {$NOTE !} + function GetClient: ICefUrlRequestClient; function GetRequestStatus: TCefUrlRequestStatus; function GetRequestError: TCefErrorcode; function GetResponse: ICefResponse; @@ -606,6 +606,18 @@ TCefUrlRequestRef = class(TCefBaseRef, ICefUrlRequest) class function New(const request: ICefRequest; const client: ICefUrlRequestClient): ICefUrlRequest; end; + TCefUrlRequestClientRef = class(TCefBaseRef, ICefUrlRequestClient) + protected + procedure OnRequestComplete(const request: ICefUrlRequest); + procedure OnUploadProgress(const request: ICefUrlRequest; current, total: UInt64); + procedure OnDownloadProgress(const request: ICefUrlRequest; current, total: UInt64); + procedure OnDownloadData(const request: ICefUrlRequest; data: Pointer; dataLength: TSize); + function GetAuthCredentials(isProxy: Boolean; const host: ustring; port: Integer; + const realm, scheme: ustring; callback: ICefAuthCallback): Boolean; + public + class function UnWrap(data: Pointer): ICefUrlRequestClient; + end; + TCefv8ContextRef = class(TCefBaseRef, ICefv8Context) protected function GetTaskRunner:ICefTaskRunner; @@ -909,42 +921,6 @@ class function TCefAllowCertificateErrorCallbackRef.UnWrap(data : Pointer) : ICe Else Result := nil; end; -{ TCefRequestContextHandlerRef } - -function TCefRequestContextHandlerRef.GetCookieManager : ICefCookieManager; -begin - Result := TCefCookieManagerRef.UnWrap(PCefRequestContextHandler(FData)^.get_cookie_manager(FData)); -end; - -class function TCefRequestContextHandlerRef.UnWrap(data : Pointer) : ICefRequestContextHandler; -begin - If data <> nil then Result := Create(data) as ICefRequestContextHandler - Else Result := nil; -end; - -{ TCefRequestContextRef } - -function TCefRequestContextRef.IsSame(other : ICefRequestContext) : Boolean; -begin - Result := PCefRequestContext(FData)^.is_same(PCefRequestContext(FData), CefGetData(other)) <> 0; -end; - -function TCefRequestContextRef.IsGlobal : Boolean; -begin - Result := PCefRequestContext(FData)^.is_global(PCefRequestContext(FData)) <> 0; -end; - -function TCefRequestContextRef.GetHandler : ICefRequestContextHandler; -begin - Result := TCefRequestContextHandlerRef.UnWrap(PCefRequestContext(FData)^.get_handler(PCefRequestContext(FData))); -end; - -class function TCefRequestContextRef.UnWrap(data : Pointer) : ICefRequestContext; -begin - If data <> nil then Result := Create(data) as ICefRequestContext - Else Result := nil; -end; - { TCefBaseRef } constructor TCefBaseRef.Create(data : Pointer); @@ -2973,6 +2949,42 @@ class function TCefPostDataElementRef.New : ICefPostDataElement; Result := UnWrap(cef_post_data_element_create); end; +{ TCefRequestContextRef } + +function TCefRequestContextRef.IsSame(other : ICefRequestContext) : Boolean; +begin + Result := PCefRequestContext(FData)^.is_same(PCefRequestContext(FData), CefGetData(other)) <> 0; +end; + +function TCefRequestContextRef.IsGlobal : Boolean; +begin + Result := PCefRequestContext(FData)^.is_global(PCefRequestContext(FData)) <> 0; +end; + +function TCefRequestContextRef.GetHandler : ICefRequestContextHandler; +begin + Result := TCefRequestContextHandlerRef.UnWrap(PCefRequestContext(FData)^.get_handler(PCefRequestContext(FData))); +end; + +class function TCefRequestContextRef.UnWrap(data : Pointer) : ICefRequestContext; +begin + If data <> nil then Result := Create(data) as ICefRequestContext + Else Result := nil; +end; + +{ TCefRequestContextHandlerRef } + +function TCefRequestContextHandlerRef.GetCookieManager : ICefCookieManager; +begin + Result := TCefCookieManagerRef.UnWrap(PCefRequestContextHandler(FData)^.get_cookie_manager(FData)); +end; + +class function TCefRequestContextHandlerRef.UnWrap(data : Pointer) : ICefRequestContextHandler; +begin + If data <> nil then Result := Create(data) as ICefRequestContextHandler + Else Result := nil; +end; + { TCefAuthCallbackRef } procedure TCefAuthCallbackRef.Cont(const username, password : ustring); @@ -3218,10 +3230,9 @@ function TCefUrlRequestRef.GetRequest : ICefRequest; Result := TCefRequestRef.UnWrap(PCefUrlRequest(FData)^.get_request(FData)); end; -function TCefUrlRequestRef.GetClient : ICefClient; +function TCefUrlRequestRef.GetClient : ICefUrlrequestClient; begin - {$NOTE TODO} - // Result := TCefUrlRequestClientRef.UnWrap(PCefUrlRequest(FData)^.get_client(FData)); + Result := TCefUrlRequestClientRef.UnWrap(PCefUrlRequest(FData)^.get_client(FData)); end; function TCefUrlRequestRef.GetRequestStatus : TCefUrlRequestStatus; @@ -3256,6 +3267,49 @@ class function TCefUrlRequestRef.New(const request : ICefRequest; Result := UnWrap(cef_urlrequest_create(CefGetData(request), CefGetData(client))); end; +{ TCefUrlRequestClientRef } + +procedure TCefUrlRequestClientRef.OnRequestComplete(const request : ICefUrlRequest); +begin + PCefUrlRequestClient(FData)^.on_request_complete(FData, CefGetData(request)); +end; + +procedure TCefUrlRequestClientRef.OnUploadProgress(const request : ICefUrlRequest; + current, total : UInt64); +begin + PCefUrlRequestClient(FData)^.on_upload_progress(FData, CefGetData(request), current, total); +end; + +procedure TCefUrlRequestClientRef.OnDownloadProgress(const request : ICefUrlRequest; + current, total : UInt64); +begin + PCefUrlRequestClient(FData)^.on_download_progress(FData, CefGetData(request), current, total); +end; + +procedure TCefUrlRequestClientRef.OnDownloadData(const request : ICefUrlRequest; + data : Pointer; dataLength : TSize); +begin + PCefUrlRequestClient(FData)^.on_download_data(FData, CefGetData(request), data, dataLength); +end; + +function TCefUrlRequestClientRef.GetAuthCredentials(isProxy : Boolean; + const host : ustring; port : Integer; const realm, scheme : ustring; + callback : ICefAuthCallback) : Boolean; +Var + h, r, s: TCefString; +begin + h := CefString(host); + r := CefString(realm); + s := CefString(scheme); + Result := PCefUrlRequestClient(FData)^.get_auth_credentials(FData, Ord(isProxy), @h, port, @r, @s, CefGetData(callback)) <> 0; +end; + +class function TCefUrlRequestClientRef.UnWrap(data : Pointer) : ICefUrlRequestClient; +begin + If data <> nil then Result := Create(data) as ICefUrlRequestClient + Else Result := nil; +end; + { TCefv8ContextRef } function TCefv8ContextRef.GetTaskRunner : ICefTaskRunner; diff --git a/cef3types.pas b/cef3types.pas index 863d3ea..59a4d0a 100644 --- a/cef3types.pas +++ b/cef3types.pas @@ -248,23 +248,14 @@ TCefTime = record // in a known order. Equivalent to the SkColor type. TCefColor = UInt32; -{ TODO - // Return the alpha byte from a cef_color_t value. - #define CefColorGetA(color) (((color) >> 24) & 0xFF) - // Return the red byte from a cef_color_t value. - #define CefColorGetR(color) (((color) >> 16) & 0xFF) - // Return the green byte from a cef_color_t value. - #define CefColorGetG(color) (((color) >> 8) & 0xFF) - // Return the blue byte from a cef_color_t value. - #define CefColorGetB(color) (((color) >> 0) & 0xFF) - - // Return an cef_color_t value with the specified byte component values. - #define CefColorSetARGB(a, r, g, b) static_cast<cef_color_t>(\ - (static_cast<unsigned>(a) << 24) | \ - (static_cast<unsigned>(r) << 16) | \ - (static_cast<unsigned>(g) << 8) | \ - (static_cast<unsigned>(b) << 0)) -} +function CefColorGetA(color: TCefColor): Byte; +function CefColorGetR(color: TCefColor): Byte; +function CefColorGetG(color: TCefColor): Byte; +function CefColorGetB(color: TCefColor): Byte; + +function CefColorSetARGB(a, r, g, b: Byte): TCefColor; + +Type // Log severity levels. TCefLogSeverity = ( @@ -1109,7 +1100,7 @@ TCefScreenInfo = record EVENTFLAG_NUM_LOCK_ON, //= 1 shl 8, EVENTFLAG_IS_KEY_PAD, //= 1 shl 9, EVENTFLAG_IS_LEFT, //= 1 shl 10, - EVENTFLAG_IS_RIGHT //= 1 shl 11 + EVENTFLAG_IS_RIGHT //= 1 shl 11 ); TCefEventFlags = set of TCefEventFlag; @@ -1437,4 +1428,29 @@ TCefGeoposition = record Implementation +function CefColorGetA(color : TCefColor) : Byte; +begin + Result := (color shr 24) and $FF; +end; + +function CefColorGetR(color : TCefColor) : Byte; +begin + Result := (color shr 16) and $FF; +end; + +function CefColorGetG(color : TCefColor) : Byte; +begin + Result := (color shr 8) and $FF; +end; + +function CefColorGetB(color : TCefColor) : Byte; +begin + Result := (color shr 0) and $FF; +end; + +function CefColorSetARGB(a, r, g, b : Byte) : TCefColor; +begin + Result := (a shl 24) or (r shl 16) or (g shl 8) or (b shl 0); +end; + end.