2019-10-13 18:50:23 +02:00
// ************************************************************************
2017-08-12 16:22:34 +02:00
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
2019-10-19 10:58:34 +02:00
// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based
2017-08-12 16:22:34 +02:00
// browser in Delphi applications.
//
// The original license of DCEF3 still applies to CEF4Delphi.
//
// For more information about CEF4Delphi visit :
// https://www.briskbard.com/index.php?lang=en&pageid=cef
//
2020-01-01 12:48:10 +01:00
// Copyright © 2020 Salvador Diaz Fau. All rights reserved.
2017-08-12 16:22:34 +02:00
//
// ************************************************************************
// ************ vvvv Original license and comments below vvvv *************
// ************************************************************************
( *
* Delphi 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.
*
* Unit owner : Henri Gourvest < hgourvest@ gmail. com>
* Web site : http: //www.progdigy.com
* Repository : http: //code.google.com/p/delphichromiumembedded/
* Group : http: //groups.google.com/group/delphichromiumembedded
*
* Embarcadero Technologies, Inc is not permitted to use or redistribute
* this source code without explicit permission.
*
* )
unit uJSEval;
2019-05-19 16:08:15 +02:00
{$MODE Delphi}
2017-08-12 16:22:34 +02:00
{$I cef.inc}
interface
uses
2019-05-19 16:08:15 +02:00
LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics, Menus,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, base64,
2019-03-22 13:12:44 +01:00
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
2019-10-14 15:39:27 +02:00
uCEFWinControl, uCEFSentinel;
2017-08-12 16:22:34 +02:00
const
MINIBROWSER_SHOWTEXTVIEWER = WM_APP + $101 ;
MINIBROWSER_EVALJSCODE = WM_APP + $102 ;
2017-09-07 10:58:09 +02:00
MINIBROWSER_JSBINPARAM = WM_APP + $103 ;
2019-03-22 13:12:44 +01:00
MINIBROWSER_GETSCROLLPOS = WM_APP + $104 ;
2017-08-12 16:22:34 +02:00
2019-03-22 13:12:44 +01:00
MINIBROWSER_CONTEXTMENU_EVALJSCODE = MENU_ID_USER_FIRST + 1 ;
MINIBROWSER_CONTEXTMENU_JSBINPARAM = MENU_ID_USER_FIRST + 2 ;
MINIBROWSER_CONTEXTMENU_GETSCROLLPOS = MENU_ID_USER_FIRST + 3 ;
2017-08-12 16:22:34 +02:00
2017-09-01 22:44:58 +02:00
EVAL_JS = 'JSContextEvalDemo' ;
BINARY_PARAM_JS = 'JSBinaryParameter' ;
2017-08-12 16:22:34 +02:00
type
2019-10-14 15:39:27 +02:00
{ TJSEvalFrm }
2017-08-12 16:22:34 +02:00
TJSEvalFrm = class( TForm)
CEFWindowParent1: TCEFWindowParent;
Chromium1: TChromium;
AddressBarPnl: TPanel;
GoBtn: TButton;
AddressEdt: TEdit;
2017-11-04 18:32:29 +01:00
Timer1: TTimer;
2019-10-14 15:39:27 +02:00
procedure CEFSentinel1Close( Sender: TObject) ;
2017-08-12 16:22:34 +02:00
procedure Chromium1AfterCreated( Sender: TObject; const browser: ICefBrowser) ;
procedure GoBtnClick( Sender: TObject) ;
procedure FormShow( Sender: TObject) ;
procedure Chromium1ProcessMessageReceived( Sender: TObject;
2019-06-16 10:31:13 +02:00
const browser: ICefBrowser; const frame: ICefFrame; sourceProcess: TCefProcessId;
2017-08-12 16:22:34 +02:00
const message : ICefProcessMessage; out Result : Boolean ) ;
procedure Chromium1BeforeContextMenu( Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
const params: ICefContextMenuParams; const model: ICefMenuModel) ;
procedure Chromium1ContextMenuCommand( Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
const params: ICefContextMenuParams; commandId: Integer ;
eventFlags: Cardinal ; out Result : Boolean ) ;
2017-11-04 18:32:29 +01:00
procedure Timer1Timer( Sender: TObject) ;
2018-02-16 18:41:13 +01:00
procedure Chromium1BeforePopup( Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const targetUrl,
targetFrameName: ustring;
targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean ;
2018-03-29 20:02:04 +02:00
const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo;
2018-02-16 18:41:13 +01:00
var client: ICefClient; var settings: TCefBrowserSettings;
2019-06-16 10:31:13 +02:00
var extra_info: ICefDictionaryValue;
2018-03-29 20:02:04 +02:00
var noJavascriptAccess: Boolean ; var Result : Boolean ) ;
2018-03-31 18:08:18 +02:00
procedure FormCloseQuery( Sender: TObject; var CanClose: Boolean ) ;
procedure Chromium1Close( Sender: TObject; const browser: ICefBrowser;
2019-03-28 10:40:36 +01:00
var aAction : TCefCloseBrowserAction) ;
2018-03-31 18:08:18 +02:00
procedure Chromium1BeforeClose( Sender: TObject;
const browser: ICefBrowser) ;
2017-08-12 16:22:34 +02:00
private
{ Private declarations }
protected
FText : string ;
2018-03-31 18:08:18 +02:00
// Variables to control when can we destroy the form safely
FCanClose : boolean ; // Set to True in TChromium.OnBeforeClose
FClosing : boolean ; // Set to True in the CloseQuery event.
2017-08-12 16:22:34 +02:00
2017-09-07 10:58:09 +02:00
procedure BrowserCreatedMsg( var aMessage : TMessage) ; message CEF_AFTERCREATED;
2018-03-31 18:08:18 +02:00
procedure BrowserDestroyMsg( var aMessage : TMessage) ; message CEF_DESTROY;
2017-08-12 16:22:34 +02:00
procedure ShowTextViewerMsg( var aMessage : TMessage) ; message MINIBROWSER_SHOWTEXTVIEWER;
procedure EvalJSCodeMsg( var aMessage : TMessage) ; message MINIBROWSER_EVALJSCODE;
2019-03-22 13:12:44 +01:00
procedure GetScrollPosMsg( var aMessage : TMessage) ; message MINIBROWSER_GETSCROLLPOS;
2017-09-07 10:58:09 +02:00
procedure EvalJSBinParamMsg( var aMessage : TMessage) ; message MINIBROWSER_JSBINPARAM;
2017-08-12 16:22:34 +02:00
procedure WMMove( var aMessage : TWMMove) ; message WM_MOVE;
procedure WMMoving( var aMessage : TMessage) ; message WM_MOVING;
2017-12-18 19:38:56 +01:00
procedure WMEnterMenuLoop( var aMessage: TMessage) ; message WM_ENTERMENULOOP;
procedure WMExitMenuLoop( var aMessage: TMessage) ; message WM_EXITMENULOOP;
2017-08-12 16:22:34 +02:00
end ;
var
JSEvalFrm: TJSEvalFrm;
2018-06-17 14:18:11 +02:00
procedure CreateGlobalCEFApp;
2017-08-12 16:22:34 +02:00
implementation
2019-05-19 16:08:15 +02:00
{$R *.lfm}
2017-08-12 16:22:34 +02:00
uses
2019-05-19 16:08:15 +02:00
uSimpleTextViewer, uCEFProcessMessage, uCEFBinaryValue, uCEFMiscFunctions;
2017-08-12 16:22:34 +02:00
// 99.9% of the code in this demo was created by xpert13 and shared in the CEF4Delphi forum.
// Steps to evaluate some JavaScript code using the V8Context
// ----------------------------------------------------------
2018-06-17 14:18:11 +02:00
// 1. Set GlobalCEFApp.OnProcessMessageReceived to RenderProcessHandler_OnProcessMessageReceivedEvent.
2018-03-29 20:02:04 +02:00
// 2. To get the Javascript code in this demo we use a context menu that sends a MINIBROWSER_EVALJSCODE to the form.
// 3. The EvalJSCodeMsg asks for the Javascript code and sends it to the renderer using a process message.
// 4. RenderProcessHandler_OnProcessMessageReceivedEvent receives the process message and calls ParseEvalJsAnswer
2017-09-07 10:58:09 +02:00
// to evaluate the code.
2018-03-29 20:02:04 +02:00
// 5. ParseEvalJsAnswer evaluates the code and sends a message with the results to the browser process using a
2017-09-07 10:58:09 +02:00
// process message.
2018-03-29 20:02:04 +02:00
// 6. Chromium1ProcessMessageReceived receives the message, stores the results and sends a
2017-09-07 10:58:09 +02:00
// MINIBROWSER_SHOWTEXTVIEWER message to the form.
2018-03-29 20:02:04 +02:00
// 7. ShowTextViewerMsg shows the results safely using a SimpleTextViewer.
2017-08-12 16:22:34 +02:00
2017-09-01 22:44:58 +02:00
// This demo also has an example of binary parameters in process messages
// ----------------------------------------------------------------------
2018-06-17 14:18:11 +02:00
// 1. Set GlobalCEFApp.OnProcessMessageReceived to RenderProcessHandler_OnProcessMessageReceivedEvent.
2018-03-29 20:02:04 +02:00
// 2. The context menu has a 'Send JPEG image' option that sends a MINIBROWSER_JSBINPARAM message to the form.
// 3. EvalJSBinParamMsg asks for a JPEG image and sends a process message with a ICefBinaryValue parameter to the
2017-09-07 10:58:09 +02:00
// renderer process.
2018-03-29 20:02:04 +02:00
// 4. The renderer process parses the binary parameter in the ParseBinaryValue function and sends back the image
2017-09-07 10:58:09 +02:00
// size and encoded image data to the browser process.
2018-03-29 20:02:04 +02:00
// 5. Chromium1ProcessMessageReceived receives the message, stores the results and sends a
2017-09-07 10:58:09 +02:00
// MINIBROWSER_SHOWTEXTVIEWER message to the form.
2018-03-29 20:02:04 +02:00
// 6. ShowTextViewerMsg shows the results safely using a SimpleTextViewer.
2017-09-01 22:44:58 +02:00
// About binary parameters
// -----------------------
// There is a size limit in the binary parameters of only a few kilobytes.
2019-10-19 10:58:34 +02:00
// For more info and alternatives read this thread in the official CEF forum :
2017-09-01 22:44:58 +02:00
// http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10590
//
// Compress the binary data if necessary!
2018-03-31 18:08:18 +02:00
// Destruction steps
// =================
// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event.
// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event.
2020-02-26 13:28:29 +01:00
// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form.
2017-09-01 22:44:58 +02:00
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. Chromium1AfterCreated( Sender: TObject; const browser: ICefBrowser) ;
begin
2017-09-07 10:58:09 +02:00
PostMessage( Handle, CEF_AFTERCREATED, 0 , 0 ) ;
2017-08-12 16:22:34 +02:00
end ;
2019-10-14 15:39:27 +02:00
procedure TJSEvalFrm. CEFSentinel1Close( Sender: TObject) ;
2018-03-31 18:08:18 +02:00
begin
2020-02-26 13:28:29 +01:00
2018-03-31 18:08:18 +02:00
end ;
2019-10-14 15:39:27 +02:00
procedure TJSEvalFrm. Chromium1BeforeClose( Sender: TObject;
const browser: ICefBrowser) ;
begin
2020-02-26 13:28:29 +01:00
FCanClose : = True ;
PostMessage( Handle, WM_CLOSE, 0 , 0 ) ;
2019-10-14 15:39:27 +02:00
end ;
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. Chromium1BeforeContextMenu( Sender : TObject;
const browser : ICefBrowser;
const frame : ICefFrame;
const params : ICefContextMenuParams;
const model : ICefMenuModel) ;
begin
2019-03-22 13:12:44 +01:00
model. AddItem( MINIBROWSER_CONTEXTMENU_EVALJSCODE, 'Evaluate JavaScript code...' ) ;
model. AddItem( MINIBROWSER_CONTEXTMENU_GETSCROLLPOS, 'Get vertical scroll position...' ) ;
2019-05-19 16:08:15 +02:00
// TODO: Fix bug in creating a TCefBinaryValueRef
2019-11-11 17:33:16 +01:00
model. AddItem( MINIBROWSER_CONTEXTMENU_JSBINPARAM, 'Send JPEG image...' ) ;
2017-08-12 16:22:34 +02:00
end ;
2018-02-16 18:41:13 +01:00
procedure TJSEvalFrm. Chromium1BeforePopup( Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; const targetUrl,
targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition;
2018-03-29 20:02:04 +02:00
userGesture: Boolean ; const popupFeatures: TCefPopupFeatures;
2018-02-16 18:41:13 +01:00
var windowInfo: TCefWindowInfo; var client: ICefClient;
2019-06-16 10:31:13 +02:00
var settings: TCefBrowserSettings;
var extra_info: ICefDictionaryValue;
var noJavascriptAccess: Boolean ;
2018-03-29 20:02:04 +02:00
var Result : Boolean ) ;
2018-02-16 18:41:13 +01:00
begin
// For simplicity, this demo blocks all popup windows and new tabs
Result : = ( targetDisposition in [ WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW] ) ;
end ;
2018-03-31 18:08:18 +02:00
procedure TJSEvalFrm. Chromium1Close( Sender: TObject;
2019-03-28 10:40:36 +01:00
const browser: ICefBrowser; var aAction : TCefCloseBrowserAction) ;
2018-03-31 18:08:18 +02:00
begin
PostMessage( Handle, CEF_DESTROY, 0 , 0 ) ;
2019-03-28 10:40:36 +01:00
aAction : = cbaDelay;
2018-03-31 18:08:18 +02:00
end ;
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. Chromium1ContextMenuCommand( Sender : TObject;
const browser : ICefBrowser;
const frame : ICefFrame;
const params : ICefContextMenuParams;
commandId : Integer ;
eventFlags : Cardinal ;
out Result : Boolean ) ;
begin
Result : = False ;
case commandId of
2019-03-22 13:12:44 +01:00
MINIBROWSER_CONTEXTMENU_EVALJSCODE : PostMessage( Handle, MINIBROWSER_EVALJSCODE, 0 , 0 ) ;
MINIBROWSER_CONTEXTMENU_JSBINPARAM : PostMessage( Handle, MINIBROWSER_JSBINPARAM, 0 , 0 ) ;
MINIBROWSER_CONTEXTMENU_GETSCROLLPOS : PostMessage( Handle, MINIBROWSER_GETSCROLLPOS, 0 , 0 ) ;
2017-08-12 16:22:34 +02:00
end ;
end ;
2018-03-31 18:08:18 +02:00
procedure TJSEvalFrm. FormCloseQuery( Sender: TObject; var CanClose: Boolean ) ;
begin
CanClose : = FCanClose;
if not( FClosing) then
begin
FClosing : = True ;
Visible : = False ;
Chromium1. CloseBrowser( True ) ;
end ;
end ;
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. FormShow( Sender: TObject) ;
begin
2017-11-04 18:32:29 +01:00
// GlobalCEFApp.GlobalContextInitialized has to be TRUE before creating any browser
// If it's not initialized yet, we use a simple timer to create the browser later.
if not( Chromium1. CreateBrowser( CEFWindowParent1, '' ) ) then Timer1. Enabled : = True ;
2017-08-12 16:22:34 +02:00
end ;
procedure TJSEvalFrm. GoBtnClick( Sender: TObject) ;
begin
Chromium1. LoadURL( AddressEdt. Text ) ;
end ;
procedure TJSEvalFrm. BrowserCreatedMsg( var aMessage : TMessage) ;
begin
2017-08-23 12:28:45 +02:00
CEFWindowParent1. UpdateSize;
2017-08-12 16:22:34 +02:00
AddressBarPnl. Enabled : = True ;
GoBtn. Click;
end ;
2018-03-31 18:08:18 +02:00
procedure TJSEvalFrm. BrowserDestroyMsg( var aMessage : TMessage) ;
begin
CEFWindowParent1. Free;
end ;
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. ShowTextViewerMsg( var aMessage : TMessage) ;
begin
SimpleTextViewerFrm. Memo1. Lines. Text : = FText;
SimpleTextViewerFrm. ShowModal;
end ;
2017-11-04 18:32:29 +01:00
procedure TJSEvalFrm. Timer1Timer( Sender: TObject) ;
begin
Timer1. Enabled : = False ;
2017-11-16 12:49:15 +01:00
if not( Chromium1. CreateBrowser( CEFWindowParent1, '' ) ) and not( Chromium1. Initialized) then
Timer1. Enabled : = True ;
2017-11-04 18:32:29 +01:00
end ;
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. WMMove( var aMessage : TWMMove) ;
begin
inherited ;
if ( Chromium1 < > nil ) then Chromium1. NotifyMoveOrResizeStarted;
end ;
procedure TJSEvalFrm. WMMoving( var aMessage : TMessage) ;
begin
inherited ;
if ( Chromium1 < > nil ) then Chromium1. NotifyMoveOrResizeStarted;
end ;
2017-12-18 19:38:56 +01:00
procedure TJSEvalFrm. WMEnterMenuLoop( var aMessage: TMessage) ;
begin
inherited ;
if ( aMessage. wParam = 0 ) and ( GlobalCEFApp < > nil ) then GlobalCEFApp. OsmodalLoop : = True ;
end ;
procedure TJSEvalFrm. WMExitMenuLoop( var aMessage: TMessage) ;
begin
inherited ;
if ( aMessage. wParam = 0 ) and ( GlobalCEFApp < > nil ) then GlobalCEFApp. OsmodalLoop : = False ;
end ;
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. EvalJSCodeMsg( var aMessage : TMessage) ;
var
TempMsg : ICefProcessMessage;
TempScript : string ;
begin
TempScript : = InputBox( 'JSEval demo' , 'Please type some JavaScript code' , 'document.title;' ) ;
if ( length( TempScript) > 0 ) then
begin
TempMsg : = TCefProcessMessageRef. New( EVAL_JS) ;
2017-09-01 22:44:58 +02:00
if TempMsg. ArgumentList. SetString( 0 , TempScript) then
Chromium1. SendProcessMessage( PID_RENDERER, TempMsg) ;
end ;
end ;
2019-03-22 13:12:44 +01:00
procedure TJSEvalFrm. GetScrollPosMsg( var aMessage : TMessage) ;
var
TempMsg : ICefProcessMessage;
begin
TempMsg : = TCefProcessMessageRef. New( EVAL_JS) ;
if TempMsg. ArgumentList. SetString( 0 , 'window.pageYOffset' ) then
Chromium1. SendProcessMessage( PID_RENDERER, TempMsg) ;
end ;
2017-09-01 22:44:58 +02:00
procedure TJSEvalFrm. EvalJSBinParamMsg( var aMessage : TMessage) ;
var
2017-09-07 10:58:09 +02:00
TempMsg : ICefProcessMessage;
2017-09-01 22:44:58 +02:00
TempOpenDialog : TOpenDialog;
2017-09-07 10:58:09 +02:00
TempStream : TFileStream;
TempBinValue : ICefBinaryValue;
TempBuffer : TBytes;
TempSize : NativeUInt ;
TempPointer : pointer ;
2017-09-01 22:44:58 +02:00
begin
TempOpenDialog : = nil ;
TempStream : = nil ;
try
try
2019-11-11 17:33:16 +01:00
TempOpenDialog : = TOpenDialog. Create( nil ) ;
TempOpenDialog. Options : = TempOpenDialog. Options + [ ofFileMustExist] ;
TempOpenDialog. Filter : = 'JPEG files (*.jpg)|*.JPG' ;
2017-09-01 22:44:58 +02:00
if TempOpenDialog. Execute then
begin
TempStream : = TFileStream. Create( TempOpenDialog. FileName, fmOpenRead) ;
TempSize : = TempStream. Size;
if ( TempSize > 0 ) then
begin
SetLength( TempBuffer, TempSize) ;
2019-11-11 17:33:16 +01:00
TempSize : = TempStream. Read( TempBuffer[ 0 ] , TempSize) ;
2017-09-01 22:44:58 +02:00
if ( TempSize > 0 ) then
begin
TempPointer : = @ TempBuffer[ 0 ] ;
TempBinValue : = TCefBinaryValueRef. New( TempPointer, TempSize) ;
2017-09-07 10:58:09 +02:00
TempMsg : = TCefProcessMessageRef. New( BINARY_PARAM_JS) ;
2017-09-01 22:44:58 +02:00
if TempMsg. ArgumentList. SetBinary( 0 , TempBinValue) then
Chromium1. SendProcessMessage( PID_RENDERER, TempMsg) ;
end ;
end ;
end ;
except
on e : exception do
if CustomExceptionHandler( 'TJSEvalFrm.EvalJSBinParamMsg' , e) then raise ;
2017-08-12 16:22:34 +02:00
end ;
2017-09-01 22:44:58 +02:00
finally
if ( TempOpenDialog < > nil ) then FreeAndNil( TempOpenDialog) ;
if ( TempStream < > nil ) then FreeAndNil( TempStream) ;
SetLength( TempBuffer, 0 ) ;
end ;
2017-08-12 16:22:34 +02:00
end ;
2018-06-17 14:18:11 +02:00
procedure ParseEvalJsAnswer( const pMessage : ICefProcessMessage;
2019-06-16 10:31:13 +02:00
const pBrowser : ICefBrowser;
const pFrame : ICefFrame;
const pReturnValue : ICefv8Value;
const pException : ICefV8Exception) ;
2017-08-12 16:22:34 +02:00
var
pAnswer : ICefProcessMessage;
strResult : String ;
bGoodDataType : Boolean ;
begin
pAnswer : = TCefProcessMessageRef. New( EVAL_JS) ;
if ( pReturnValue = nil ) or not( pReturnValue. IsValid) then
begin
pAnswer. ArgumentList. SetBool( 0 , false ) ;
pAnswer. ArgumentList. SetString( 1 , pException. Message ) ;
end
else
begin
bGoodDataType : = True ;
if pReturnValue. IsString then strResult : = pReturnValue. GetStringValue
else if pReturnValue. IsBool then strResult : = BoolToStr( pReturnValue. GetBoolValue)
else if pReturnValue. IsInt then strResult : = IntToStr( pReturnValue. GetIntValue)
else if pReturnValue. IsUInt then strResult : = IntToStr( pReturnValue. GetUIntValue)
else if pReturnValue. IsDouble then strResult : = FloatToStr( pReturnValue. GetDoubleValue)
else bGoodDataType : = False ;
if bGoodDataType then
begin
pAnswer. ArgumentList. SetBool( 0 , true ) ;
pAnswer. ArgumentList. SetString( 1 , strResult) ;
end
else
begin
pAnswer. ArgumentList. SetBool( 0 , false ) ;
pAnswer. ArgumentList. SetString( 1 , 'Result data type need to be string, int, uint or double!' ) ;
end ;
end ;
2019-10-13 18:50:23 +02:00
if ( pFrame < > nil ) and pFrame. IsValid then
pFrame. SendProcessMessage( PID_BROWSER, pAnswer) ;
2017-08-12 16:22:34 +02:00
end ;
2019-06-16 10:31:13 +02:00
procedure ParseBinaryValue( const pBrowser : ICefBrowser; const pFrame: ICefFrame; const aBinaryValue : ICefBinaryValue) ;
2017-09-01 22:44:58 +02:00
var
2017-09-07 10:58:09 +02:00
pAnswer : ICefProcessMessage;
TempBuffer : TBytes;
TempPointer : pointer ;
TempSize : NativeUInt ;
TempString : string ;
2019-11-11 17:33:16 +01:00
TempDecodedStream : TBytesStream;
2019-05-19 16:08:15 +02:00
TempEncodedStream : TStringStream;
TempEncoder : TBase64EncodingStream;
2017-09-01 22:44:58 +02:00
begin
2019-05-19 16:08:15 +02:00
TempDecodedStream : = nil ;
TempEncodedStream : = nil ;
TempEncoder : = nil ;
2017-09-01 22:44:58 +02:00
if ( aBinaryValue = nil ) then exit;
2017-09-07 10:58:09 +02:00
try
try
TempSize : = aBinaryValue. GetSize;
2017-09-01 22:44:58 +02:00
if ( TempSize > 0 ) then
begin
2017-09-07 10:58:09 +02:00
SetLength( TempBuffer, TempSize) ;
TempPointer : = @ TempBuffer[ 0 ] ;
TempSize : = aBinaryValue. GetData( TempPointer, TempSize, 0 ) ;
2017-09-01 22:44:58 +02:00
2017-09-07 10:58:09 +02:00
if ( TempSize > 0 ) then
begin
2019-11-11 17:33:16 +01:00
TempDecodedStream : = TBytesStream. Create( TempBuffer) ;
2019-05-19 16:08:15 +02:00
TempEncodedStream : = TStringStream. Create( '' ) ;
TempEncoder : = TBase64EncodingStream. Create( TempEncodedStream) ;
TempEncoder. CopyFrom( TempDecodedStream, TempDecodedStream. Size) ;
2017-09-07 10:58:09 +02:00
pAnswer : = TCefProcessMessageRef. New( BINARY_PARAM_JS) ;
TempString : = 'Image size : ' + inttostr( TempSize) + #13 + #10 +
2019-05-19 16:08:15 +02:00
'Encoded image : ' + TempEncodedStream. DataString;
2017-09-01 22:44:58 +02:00
2019-10-13 18:50:23 +02:00
if ( pFrame < > nil ) and pFrame. IsValid and pAnswer. ArgumentList. SetString( 0 , TempString) then
2019-06-16 10:31:13 +02:00
pFrame. SendProcessMessage( PID_BROWSER, pAnswer) ;
2017-09-07 10:58:09 +02:00
end ;
end ;
except
on e : exception do
2018-06-17 14:18:11 +02:00
if CustomExceptionHandler( 'ParseBinaryValue' , e) then raise ;
2017-09-01 22:44:58 +02:00
end ;
2017-09-07 10:58:09 +02:00
finally
2019-05-19 16:08:15 +02:00
if ( TempDecodedStream < > nil ) then FreeAndnil( TempDecodedStream) ;
if ( TempEncodedStream < > nil ) then FreeAndnil( TempEncodedStream) ;
if ( TempEncoder < > nil ) then FreeAndnil( TempEncoder) ;
2017-09-07 10:58:09 +02:00
SetLength( TempBuffer, 0 ) ;
end ;
2017-09-01 22:44:58 +02:00
end ;
2018-06-17 14:18:11 +02:00
procedure RenderProcessHandler_OnProcessMessageReceivedEvent( const pBrowser : ICefBrowser;
2019-06-16 10:31:13 +02:00
const pFrame : ICefFrame;
2018-06-17 14:18:11 +02:00
uSourceProcess : TCefProcessId;
const pMessage : ICefProcessMessage;
var aHandled : boolean ) ;
var
pV8Context : ICefv8Context;
pReturnValue : ICefv8Value;
pException : ICefV8Exception;
TempScript : string ;
TempBinValue : ICefBinaryValue;
begin
aHandled : = False ;
if ( pMessage = nil ) or ( pMessage. ArgumentList = nil ) then exit;
if ( pMessage. Name = EVAL_JS) then
begin
TempScript : = pMessage. ArgumentList. GetString( 0 ) ;
2019-10-13 18:50:23 +02:00
if ( length( TempScript) > 0 ) and ( pFrame < > nil ) and pFrame. IsValid then
2018-06-17 14:18:11 +02:00
begin
2019-10-13 18:50:23 +02:00
pV8Context : = pFrame. GetV8Context;
2018-06-17 14:18:11 +02:00
if pV8Context. Enter then
begin
pV8Context. Eval( TempScript, '' , 1 , pReturnValue, pException) ;
2019-06-16 10:31:13 +02:00
ParseEvalJsAnswer( pMessage, pBrowser, pFrame, pReturnValue, pException) ;
2018-06-17 14:18:11 +02:00
pV8Context. Exit;
end ;
end ;
aHandled : = True ;
end
else
if ( pMessage. Name = BINARY_PARAM_JS) then
begin
TempBinValue : = pMessage. ArgumentList. GetBinary( 0 ) ;
2019-06-16 10:31:13 +02:00
ParseBinaryValue( pBrowser, pFrame, TempBinValue) ;
2018-06-17 14:18:11 +02:00
aHandled : = True ;
end ;
end ;
procedure CreateGlobalCEFApp;
begin
GlobalCEFApp : = TCefApplication. Create;
GlobalCEFApp. OnProcessMessageReceived : = RenderProcessHandler_OnProcessMessageReceivedEvent;
end ;
2017-08-12 16:22:34 +02:00
procedure TJSEvalFrm. Chromium1ProcessMessageReceived( Sender : TObject;
const browser : ICefBrowser;
2019-06-16 10:31:13 +02:00
const frame : ICefFrame;
2017-08-12 16:22:34 +02:00
sourceProcess : TCefProcessId;
const message : ICefProcessMessage;
out Result : Boolean ) ;
begin
2017-09-08 17:27:05 +02:00
Result : = False ;
2017-08-12 16:22:34 +02:00
if ( message = nil ) or ( message . ArgumentList = nil ) then exit;
if ( message . Name = EVAL_JS) then
begin
FText : = message . ArgumentList. GetString( 1 ) ;
PostMessage( Handle, MINIBROWSER_SHOWTEXTVIEWER, 0 , 0 ) ;
Result : = True ;
end
else
2017-09-01 22:44:58 +02:00
if ( message . Name = BINARY_PARAM_JS) then
begin
FText : = message . ArgumentList. GetString( 0 ) ;
PostMessage( Handle, MINIBROWSER_SHOWTEXTVIEWER, 0 , 0 ) ;
Result : = True ;
2017-09-08 17:27:05 +02:00
end ;
2017-08-12 16:22:34 +02:00
end ;
end .