1

I have a particular problem with handling a download link within Chromium.

The issue is not so much the download (answered here quite well: CEF4 Chromium Delphi 10.2 Tokyo - how to handle download dialogue? ) ...but this particular link is tagged with target="_blank".

Which triggers OnBeforePopup with targetDisposition=WOD_NEW_FOREGROUND_TAB However, in almost all the example code, the OnBeforePopup handler has the following code:

  // 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]);

This effectively blocks that link from proceeding, thus the OnBeforeDownload event never triggers.

If I comment out the popup blocker, the default behaviour seems to be to open a new blank window, and then proceed with the download events as expected. However, the download never quite completes (it goes to 100% but never "complete"), and the new window never goes away.

My question is in two parts:

  1. Could I get some guidance on how to either create a new browser window that I have control over in the OnBeforePopup event?
  2. How to I make the download properly complete?

Note: If I paste the actual targetURL of the download file into the address bar, the download completes quite cheerfully, so I suspect the key is in the handling of the default window.

Note: I have found the CEF API documentation, it is not super informative.

Note: I'm aware TabBrowser2 handles the popup intercept, but it is far from clear what is going on, apparently calling a client window to then call the main window which in turn calls the client window again. Plus the structure I have so far does not really lend itself to that solution. The

Robbie Matthews
  • 1,404
  • 14
  • 22

2 Answers2

1

Partial answer: The PopupBrowser demo shows it much more clearly. and at least partially documents what is happening.

From the comments:

// VCL components *MUST* be created and destroyed in the main thread but CEF executes the
// TChromium.OnBeforePopup in a different thread.

// For this reason this demo creates a hidden popup form (TChildForm) in case CEF needs to show a popup window.
// TChromium.OnBeforePopup calls TChildForm.CreateClientHandler to initialize some parameters and create the new ICefClient.
// After that, it sends a CEF_CREATENEXTCHILD message to show the popup form and create a new one.

This explains what is happening fairly clearly.

CreateClientHandler(var aClient : ICefClient...

populates the clienthandler parameter passed in the BeforePopup call.

Robbie Matthews
  • 1,404
  • 14
  • 22
1

You can open the new tab using the event ChromiumBeforePopup

procedure ChromiumBeforePopup(Sender: TObject; const browser: ICefBrowser;
  const frame: ICefFrame; const targetUrl, targetFrameName: ustring;
  targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean;
  const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient;
  var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess,
  Result: Boolean);
begin
  Result := not(CreateClientHandler(windowInfo, client, targetFrameName, popupFeatures));
end;