Compare commits

...

37 Commits
6778 ... 6478

Author SHA1 Message Date
Marshall Greenblatt
a5d51ba9db Pin depot_tools version for out-of-support branch 2024-07-29 12:20:48 -04:00
Marshall Greenblatt
3647d39e70 cefclient: Allow download with --hide-controls (fixes #3742) 2024-07-17 15:07:47 -04:00
Marshall Greenblatt
dca51c71fd Update to Chromium version 126.0.6478.183 2024-07-17 15:05:59 +00:00
Marshall Greenblatt
c23cfb8b01 Fix DCHECK adding menu separator with hidden items (fixes #3577) 2024-07-16 16:05:23 -04:00
Marshall Greenblatt
1e880c56ed distrib: Add new tools distribution for mksnapshot (see #3734) 2024-07-16 16:04:32 -04:00
Marshall Greenblatt
239742e877 mac: cefclient: Fix zombie NSWindow object on exit (fixes #3602)
- Don't create a TempWindow when using Views.
- Don't call `close` on an NSWindow that is never opened.
2024-07-15 17:10:36 -04:00
Marshall Greenblatt
f6393726b4 Call SetIsShutdown after CefInitialize (fixes #3738)
Delay shutdown checking until after CefInitialize has drained existing
task pools.
2024-07-15 17:10:27 -04:00
Marshall Greenblatt
162c3d60df Fix duplicate open from DevTools when handling OnOpenURLFromTab (fixes #3735) 2024-07-11 14:31:51 -04:00
Marshall Greenblatt
b281f7aefd tools: win: Remove dynamic_annotations.lib from cef_sandbox
This library was removed in https://crbug.com/40209570.
2024-07-10 12:31:29 -04:00
Nik Pavlov
61241e4482 tools: Fix "invalid escape sequence '\s'" warning 2024-07-01 13:21:53 -04:00
Marshall Greenblatt
169fea9e41 Allow dangling Listener in CefFileDialogManager (fixes #3720) 2024-06-25 13:57:27 -04:00
Marshall Greenblatt
047d3a0b4e Update to Chromium version 126.0.6478.127 2024-06-25 13:37:09 +00:00
Marshall Greenblatt
300bb055bb Allow dangling UnretainedWrapper for ResourceRequest* (fixes #3717)
Change UnretainedWrapper traits from MayNotDangle (default) to
MayDangleUntriaged as a short-term fix.
2024-06-21 13:03:14 -04:00
Marshall Greenblatt
c7c4ac95b1 Fix assertions with Save As dialog
Fixes some issues introduced by 8e79307a62 (see #3314) and
6354d8daf1 (see #3239).

To test:
- Run `cefclient --url=chrome://net-export`
- Click the "Start Logging to Disk" button
- Exit cefclient; get no debug assertions
2024-06-20 14:11:41 -04:00
Marshall Greenblatt
4fc5399f88 Update to Chromium version 126.0.6478.115 2024-06-20 13:35:33 +00:00
Marshall Greenblatt
5e718e01a0 Disable dangling ptr check for PendingRequest::request_ (see #3239, fixes #3717) 2024-06-18 15:46:33 -04:00
Marshall Greenblatt
64eb12c9c4 Revert "Fix potential dangling PendingRequest::request_ (see #3239)"
This reverts commit 47798d3dbf.

It doesn't appear to have fixed the issue (see #3717).
2024-06-18 15:40:46 -04:00
Marshall Greenblatt
ecbe1244cb chrome: Fix CHECK when switching from kPrerendering to kActive
In this case |render_frame_| is not bound, |render_frame_host_| is
non-nullptr and |render_frame_host| equals |render_frame_host_| in
CefFrameHostImpl::MaybeReAttach when called from
CefBrowserInfo::FrameHostStateChanged.
2024-06-18 13:52:24 -04:00
Marshall Greenblatt
d9c1887429 tests: Fix LifeSpanTest.DoClose*WithOnUnloadForce failures 2024-06-18 12:26:14 -04:00
Marshall Greenblatt
5c56e98fc6 Update to Chromium version 126.0.6478.62 2024-06-14 15:12:08 +00:00
Marshall Greenblatt
2be337fb12 views: Add missing patched files (see #3711) 2024-06-13 18:09:03 -04:00
Marshall Greenblatt
7e5ee97d2e Update to Chromium version 126.0.6478.57 2024-06-13 15:21:21 -04:00
Marshall Greenblatt
6090afb12e chrome: Add cleanup when context menu isn't running (fixes #3711)
The menu may not be running in the following cases:

- If the menu is empty (e.g. cleared in OnBeforeContextMenu).
- If the menu is disabled (see e.g. RenderViewContextMenuViews::Show).
- When the run call blocks until the menu is dismissed (macOS behavior).

We explicitly clean up in these cases instead of waiting for OnMenuClosed
which will otherwise never be called for the first 2 cases.

Menu run status is exposed via new ContextMenuDelegate and
RenderViewContextMenuBase methods.
2024-06-13 13:43:40 -04:00
Marshall Greenblatt
3cd94714f7 alloy: Move warning after logging init (fixes #3713) 2024-06-10 11:04:38 -04:00
Julian Waller
69b959514c cmake: Skip docs generation if the Doxyfile is missing
The Doxyfile is not included with minimal distributions.
2024-06-10 11:04:31 -04:00
Marshall Greenblatt
e14495b5cb Fix potential dangling PendingRequest::request_ (see #3239)
See https://magpcss.org/ceforum/viewtopic.php?f=6&t=19802 for error.
2024-06-04 14:13:16 -04:00
Yuta Sekiguchi
4771bb7ee4 chrome: Add CefJSDialogHandler support (fixes #3702) 2024-06-04 12:23:39 -04:00
Marshall Greenblatt
8e0c2ff1d1 win: Enable WinSboxNoFakeGdiInit for Debug component builds (see #3708)
The WinSboxNoFakeGdiInit feature requires delayload of all DLLs that
might load user32.dll in the renderer process. It's enabled as a field
trial for all non-Official builds, but caused problems with Debug
component builds using VS 17.5.0 due to MSVCP140D.dll depending on
OLE32.DLL (which depends on user32.dll). The dependency on OLE32.DLL
is removed with VS 17.9.2 so the feature can now be enabled.

See https://crbug.com/326277735#comment39 for background.
2024-06-04 11:57:14 -04:00
Marshall Greenblatt
caf18bdadb cefclient: linux: Fix gcc -Werror=parentheses (see #3314) 2024-06-04 11:24:19 -04:00
Marshall Greenblatt
59e700b0f0 win: Fix undefined symbol with cef_sandbox and VS 17.9.2 (see #3708)
This avoids a bug in clang + MSVC STL when using the default three-way
comparison operator with base::TimeDelta. The compiler does not throw
away the function call to the `std::_Literal_zero_is_expected` symbol,
which is deliberately undefined.

See also https://github.com/microsoft/STL/issues/4359#issuecomment-2042911928
2024-06-03 13:49:33 -04:00
Marshall Greenblatt
4042303cd8 Remove pinned depot_tools version (see #3709) 2024-06-03 12:53:05 -04:00
Marshall Greenblatt
87d1d2a7f3 Fix deletion of third_party/test_fonts contents
See https://crbug.com/343199633
2024-06-03 10:58:34 -04:00
Marshall Greenblatt
ecea6cc6e9 tests: Fix URLRequestTest failure with ReduceAcceptLanguage trial 2024-05-31 23:16:10 -04:00
Marshall Greenblatt
8af4558412 cefclient: win: Fix MSVC compile error 2024-05-31 13:29:28 -04:00
Marshall Greenblatt
20a659fa66 Pass mime type values as file dialog accept filters (see #3314)
File dialogs that specify mime type (e.g. "image/*") accept filters will pass
those values unchanged to the OnFileDialog |accept_filters| parameter. The
default dialog implementation will show those filters in addition to a combined
"Custom Files" filter. This is a change from preexisting Google Chrome
behavior where only the combined "Custom Files" filter is displayed, and
restores CEF behavior that existed prior to 2ea7459a89.

Document the fact that OnFileDialog may be called twice, once before MIME type
expansion and once afterwards.

Add new OnFileDialog |accept_extensions| and |accept_descriptions| parameters
for MIME type extensions and descriptions.

Details: This change adds a SelectFileDialog::FileTypeInfo::extension_mimetypes
member and improves the logic in FileSelectHelper::GetFileTypesFromAcceptType
and file_dialog_manager.cc SelectFileToFileChooserParams to support recall of
the source mime type when populating the FileChooserParams structure.

To test:
- Run `ceftests --gtest_filter=DialogTest.*`
- Run `cefclient --url=https://tests/dialogs`
2024-05-30 15:46:19 -04:00
Marshall Greenblatt
34de39aac8 Update to Chromium version 126.0.6478.26 2024-05-30 14:07:09 +00:00
Marshall Greenblatt
8abe66c2b2 Update to Chromium version 126.0.6478.17 2024-05-26 13:47:03 -04:00
72 changed files with 1377 additions and 377 deletions

View File

@@ -7,5 +7,6 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{
'chromium_checkout': 'refs/tags/126.0.6478.0'
'chromium_checkout': 'refs/tags/126.0.6478.183',
'depot_tools_checkout': 'fca881606e'
}

View File

@@ -240,16 +240,18 @@ PRINT_CEF_CONFIG()
# Define the API documentation target.
#
find_package(Doxygen)
if(DOXYGEN_FOUND)
add_custom_target(apidocs ALL
# Generate documentation in the docs/html directory.
COMMAND "${DOXYGEN_EXECUTABLE}" Doxyfile
# Write a docs/index.html file.
COMMAND ${CMAKE_COMMAND} -E echo "<html><head><meta http-equiv=\"refresh\" content=\"0;URL='html/index.html'\"/></head></html>" > docs/index.html
WORKING_DIRECTORY "${CEF_ROOT}"
COMMENT "Generating API documentation with Doxygen..."
VERBATIM )
else()
message(WARNING "Doxygen must be installed to generate API documentation.")
endif()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile")
find_package(Doxygen)
if(DOXYGEN_FOUND)
add_custom_target(apidocs ALL
# Generate documentation in the docs/html directory.
COMMAND "${DOXYGEN_EXECUTABLE}" Doxyfile
# Write a docs/index.html file.
COMMAND ${CMAKE_COMMAND} -E echo "<html><head><meta http-equiv=\"refresh\" content=\"0;URL='html/index.html'\"/></head></html>" > docs/index.html
WORKING_DIRECTORY "${CEF_ROOT}"
COMMENT "Generating API documentation with Doxygen..."
VERBATIM )
else()
message(WARNING "Doxygen must be installed to generate API documentation.")
endif()
endif()

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=5644fdc2453dd083079bf9e3616b687eeb49f250$
// $hash=bf7208a86ee17f63fd7163cef8c3a13373a1f1c8$
//
#ifndef CEF_INCLUDE_CAPI_CEF_DIALOG_HANDLER_CAPI_H_
@@ -86,13 +86,20 @@ typedef struct _cef_dialog_handler_t {
/// to show the default title ("Open" or "Save" depending on the mode).
/// |default_file_path| is the path with optional directory and/or file name
/// component that should be initially selected in the dialog.
/// |accept_filters| are used to restrict the selectable file types and may
/// any combination of (a) valid lower-cased MIME types (e.g. "text/*" or
/// "image/*"), (b) individual file extensions (e.g. ".txt" or ".png"), or (c)
/// combined description and file extension delimited using "|" and ";" (e.g.
/// "Image Types|.png;.gif;.jpg"). To display a custom dialog return true (1)
/// and execute |callback| either inline or at a later time. To display the
/// default dialog return false (0).
/// |accept_filters| are used to restrict the selectable file types and may be
/// any combination of valid lower-cased MIME types (e.g. "text/*" or
/// "image/*") and individual file extensions (e.g. ".txt" or ".png").
/// |accept_extensions| provides the semicolon-delimited expansion of MIME
/// types to file extensions (if known, or NULL string otherwise).
/// |accept_descriptions| provides the descriptions for MIME types (if known,
/// or NULL string otherwise). For example, the "image/*" mime type might have
/// extensions ".png;.jpg;.bmp;..." and description "Image Files".
/// |accept_filters|, |accept_extensions| and |accept_descriptions| will all
/// be the same size. To display a custom dialog return true (1) and execute
/// |callback| either inline or at a later time. To display the default dialog
/// return false (0). If this function returns false (0) it may be called an
/// additional time for the same dialog (both before and after MIME type
/// expansion).
///
int(CEF_CALLBACK* on_file_dialog)(
struct _cef_dialog_handler_t* self,
@@ -101,6 +108,8 @@ typedef struct _cef_dialog_handler_t {
const cef_string_t* title,
const cef_string_t* default_file_path,
cef_string_list_t accept_filters,
cef_string_list_t accept_extensions,
cef_string_list_t accept_descriptions,
struct _cef_file_dialog_callback_t* callback);
} cef_dialog_handler_t;

View File

@@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "100bd8428968266a67128c02f63e2fd5aaa90d28"
#define CEF_API_HASH_UNIVERSAL "ed1dfa5ff8a041241f8fb72eb7454811f358f0d3"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "d5cba94f734fb1966f098fad5cc5f342a5d14afe"
#define CEF_API_HASH_PLATFORM "0d99d1b9b85b2efab91a39d6fc325bb6d56fd524"
#elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "f5554ef4857432df5d22a14a9df7f3b1248c3265"
#define CEF_API_HASH_PLATFORM "e585e190387e31a71267207b66d175e213991470"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "5c283fac1f398ae4a5a5c2f16a4984267034950f"
#define CEF_API_HASH_PLATFORM "09d3e280ed38f7a082b794c56ff71c52f86f0ea8"
#endif
#ifdef __cplusplus

View File

@@ -77,21 +77,30 @@ class CefDialogHandler : public virtual CefBaseRefCounted {
/// empty to show the default title ("Open" or "Save" depending on the mode).
/// |default_file_path| is the path with optional directory and/or file name
/// component that should be initially selected in the dialog.
/// |accept_filters| are used to restrict the selectable file types and may
/// any combination of (a) valid lower-cased MIME types (e.g. "text/*" or
/// "image/*"), (b) individual file extensions (e.g. ".txt" or ".png"), or (c)
/// combined description and file extension delimited using "|" and ";" (e.g.
/// "Image Types|.png;.gif;.jpg"). To display a custom dialog return true and
/// execute |callback| either inline or at a later time. To display the
/// default dialog return false.
/// |accept_filters| are used to restrict the selectable file types and may be
/// any combination of valid lower-cased MIME types (e.g. "text/*" or
/// "image/*") and individual file extensions (e.g. ".txt" or ".png").
/// |accept_extensions| provides the semicolon-delimited expansion of MIME
/// types to file extensions (if known, or empty string otherwise).
/// |accept_descriptions| provides the descriptions for MIME types (if known,
/// or empty string otherwise). For example, the "image/*" mime type might
/// have extensions ".png;.jpg;.bmp;..." and description "Image Files".
/// |accept_filters|, |accept_extensions| and |accept_descriptions| will all
/// be the same size. To display a custom dialog return true and execute
/// |callback| either inline or at a later time. To display the default dialog
/// return false. If this method returns false it may be called an additional
/// time for the same dialog (both before and after MIME type expansion).
///
/*--cef(optional_param=title,optional_param=default_file_path,
optional_param=accept_filters)--*/
optional_param=accept_filters,optional_param=accept_extensions,
optional_param=accept_descriptions)--*/
virtual bool OnFileDialog(CefRefPtr<CefBrowser> browser,
FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
CefRefPtr<CefFileDialogCallback> callback) {
return false;
}

View File

@@ -3463,7 +3463,7 @@ typedef enum {
CEF_CPAIT_COOKIE_CONTROLS,
CEF_CPAIT_FILE_SYSTEM_ACCESS,
CEF_CPAIT_FIND,
CEF_CPAIT_HIGH_EFFICIENCY,
CEF_CPAIT_MEMORY_SAVER,
CEF_CPAIT_INTENT_PICKER,
CEF_CPAIT_LOCAL_CARD_MIGRATION,
CEF_CPAIT_MANAGE_PASSWORDS,
@@ -3487,7 +3487,8 @@ typedef enum {
CEF_CPAIT_PRICE_INSIGHTS,
CEF_CPAIT_PRICE_READ_ANYTHING,
CEF_CPAIT_PRODUCT_SPECIFICATIONS,
CEF_CPAIT_MAX_VALUE = CEF_CPAIT_PRODUCT_SPECIFICATIONS,
CEF_CPAIT_LENS_OVERLAY,
CEF_CPAIT_MAX_VALUE = CEF_CPAIT_LENS_OVERLAY,
} cef_chrome_page_action_icon_type_t;
///

View File

@@ -1210,11 +1210,7 @@ void AlloyBrowserHostImpl::RendererResponsive(
content::JavaScriptDialogManager*
AlloyBrowserHostImpl::GetJavaScriptDialogManager(content::WebContents* source) {
if (!javascript_dialog_manager_) {
javascript_dialog_manager_ =
std::make_unique<CefJavaScriptDialogManager>(this);
}
return javascript_dialog_manager_.get();
return CefBrowserHostBase::GetJavaScriptDialogManager();
}
void AlloyBrowserHostImpl::RunFileChooser(

View File

@@ -18,7 +18,6 @@
#include "cef/libcef/browser/browser_host_base.h"
#include "cef/libcef/browser/browser_info.h"
#include "cef/libcef/browser/frame_host_impl.h"
#include "cef/libcef/browser/javascript_dialog_manager.h"
#include "cef/libcef/browser/menu_manager.h"
#include "cef/libcef/browser/request_context_impl.h"
#include "content/public/browser/web_contents.h"
@@ -363,9 +362,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
// on the UI thread.
bool window_destroyed_ = false;
// Used for creating and managing JavaScript dialogs.
std::unique_ptr<CefJavaScriptDialogManager> javascript_dialog_manager_;
// Used for creating and managing context menus.
std::unique_ptr<CefMenuManager> menu_manager_;

View File

@@ -287,6 +287,10 @@ void CefBrowserHostBase::DestroyWebContents(
devtools_protocol_manager_.reset();
devtools_window_runner_.reset();
context_menu_observer_ = nullptr;
if (javascript_dialog_manager_) {
javascript_dialog_manager_->Destroy();
javascript_dialog_manager_.reset();
}
browser_info_->WebContentsDestroyed();
platform_delegate_->WebContentsDestroyed(web_contents);
@@ -1283,6 +1287,15 @@ void CefBrowserHostBase::SelectFileListenerDestroyed(
}
}
content::JavaScriptDialogManager*
CefBrowserHostBase::GetJavaScriptDialogManager() {
if (!javascript_dialog_manager_) {
javascript_dialog_manager_ =
std::make_unique<CefJavaScriptDialogManager>(this);
}
return javascript_dialog_manager_.get();
}
bool CefBrowserHostBase::MaybeAllowNavigation(
content::RenderFrameHost* opener,
const content::OpenURLParams& params) {

View File

@@ -20,6 +20,7 @@
#include "cef/libcef/browser/devtools/devtools_window_runner.h"
#include "cef/libcef/browser/file_dialog_manager.h"
#include "cef/libcef/browser/frame_host_impl.h"
#include "cef/libcef/browser/javascript_dialog_manager.h"
#include "cef/libcef/browser/media_stream_registrar.h"
#include "cef/libcef/browser/request_context_impl.h"
#include "cef/libcef/features/features.h"
@@ -357,6 +358,10 @@ class CefBrowserHostBase : public CefBrowserHost,
void* params);
void SelectFileListenerDestroyed(ui::SelectFileDialog::Listener* listener);
// Called from AlloyBrowserHostImpl::GetJavaScriptDialogManager and
// ChromeBrowserDelegate::GetJavaScriptDialogManager.
content::JavaScriptDialogManager* GetJavaScriptDialogManager();
// Called from CefBrowserInfoManager::MaybeAllowNavigation.
virtual bool MaybeAllowNavigation(content::RenderFrameHost* opener,
const content::OpenURLParams& params);
@@ -471,6 +476,9 @@ class CefBrowserHostBase : public CefBrowserHost,
// Used for creating and managing file dialogs.
std::unique_ptr<CefFileDialogManager> file_dialog_manager_;
// Used for creating and managing JavaScript dialogs.
std::unique_ptr<CefJavaScriptDialogManager> javascript_dialog_manager_;
// Volatile state accessed from multiple threads. All access must be protected
// by |state_lock_|.
base::Lock state_lock_;

View File

@@ -619,6 +619,16 @@ void ChromeBrowserDelegate::CanDownload(
std::move(callback).Run(true);
}
content::JavaScriptDialogManager*
ChromeBrowserDelegate::GetJavaScriptDialogManager(
content::WebContents* source) {
auto browser_host = ChromeBrowserHostImpl::GetBrowserForContents(source);
if (browser_host) {
return browser_host->GetJavaScriptDialogManager();
}
return nullptr;
}
KeyboardEventProcessingResult ChromeBrowserDelegate::PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {

View File

@@ -118,6 +118,8 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
void CanDownload(const GURL& url,
const std::string& request_method,
base::OnceCallback<void(bool)> callback) override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;

View File

@@ -152,6 +152,12 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
}
void OnMenuClosed() override {
// May be called multiple times. For example, if the menu runs and is
// additionally reset via MaybeResetContextMenu.
if (!handler_) {
return;
}
handler_->OnContextMenuDismissed(browser_, GetFrame());
model_->Detach();
@@ -203,17 +209,25 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
base::BindOnce(&CefContextMenuObserver::ExecuteCommandCallback,
weak_ptr_factory_.GetWeakPtr())));
bool handled = handler_->RunContextMenu(browser_, GetFrame(), params_,
model_, callbackImpl.get());
if (!handled && callbackImpl->IsDisconnected()) {
is_handled_ = handler_->RunContextMenu(browser_, GetFrame(), params_,
model_, callbackImpl.get());
if (!is_handled_ && callbackImpl->IsDisconnected()) {
LOG(ERROR) << "Should return true from RunContextMenu when executing the "
"callback";
handled = true;
is_handled_ = true;
}
if (!handled) {
if (!is_handled_) {
callbackImpl->Disconnect();
}
return handled;
return is_handled_;
}
void MaybeResetContextMenu() {
// Don't reset the menu when the client is using custom handling. It will be
// reset via ExecuteCommandCallback instead.
if (!is_handled_) {
OnMenuClosed();
}
}
private:
@@ -282,6 +296,8 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
using ItemInfoMap = std::map<int, ItemInfo>;
ItemInfoMap iteminfomap_;
bool is_handled_ = false;
base::WeakPtrFactory<CefContextMenuObserver> weak_ptr_factory_{this};
};
@@ -336,4 +352,13 @@ bool HandleContextMenu(content::WebContents* opener,
return false;
}
void MaybeResetContextMenu(content::WebContents* opener) {
auto browser = CefBrowserHostBase::GetBrowserForContents(opener);
if (browser && browser->context_menu_observer()) {
return static_cast<CefContextMenuObserver*>(
browser->context_menu_observer())
->MaybeResetContextMenu();
}
}
} // namespace context_menu

View File

@@ -21,6 +21,8 @@ void RegisterCallbacks();
bool HandleContextMenu(content::WebContents* opener,
const content::ContextMenuParams& params);
void MaybeResetContextMenu(content::WebContents* opener);
} // namespace context_menu
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_CONTEXT_MENU_HANDLER_H_

View File

@@ -19,4 +19,14 @@ void ChromeWebContentsViewDelegateCef::ShowContextMenu(
}
ChromeWebContentsViewDelegateBase::ShowContextMenu(render_frame_host, params);
// The menu may not be running in the following cases:
// - If the menu is empty (e.g. cleared in OnBeforeContextMenu).
// - If the menu is disabled (see e.g. RenderViewContextMenuViews::Show).
// - When the above call blocks until the menu is dismissed (macOS behavior).
// We explicitly clean up in these cases instead of waiting for OnMenuClosed
// which will otherwise never be called for the first 2 cases.
if (!IsMenuRunning()) {
context_menu::MaybeResetContextMenu(web_contents_);
}
}

View File

@@ -8,6 +8,8 @@
#include "cef/libcef/browser/browser_host_base.h"
#include "cef/libcef/browser/chrome/chrome_context_menu_handler.h"
#include "cef/libcef/browser/osr/web_contents_view_osr.h"
#include "components/renderer_context_menu/context_menu_delegate.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
namespace extensions {
@@ -42,8 +44,27 @@ bool ChromeMimeHandlerViewGuestDelegateCef::HandleContextMenu(
return true;
}
return ChromeMimeHandlerViewGuestDelegate::HandleContextMenu(
render_frame_host, params);
[[maybe_unused]] bool result =
ChromeMimeHandlerViewGuestDelegate::HandleContextMenu(render_frame_host,
params);
DCHECK(result);
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(&render_frame_host);
ContextMenuDelegate* menu_delegate =
ContextMenuDelegate::FromWebContents(web_contents);
// The menu may not be running in the following cases:
// - If the menu is empty (e.g. cleared in OnBeforeContextMenu).
// - If the menu is disabled (see e.g. RenderViewContextMenuViews::Show).
// - When the above call blocks until the menu is dismissed (macOS behavior).
// We explicitly clean up in these cases instead of waiting for OnMenuClosed
// which will otherwise never be called for the first 2 cases.
if (!menu_delegate->IsMenuRunning()) {
context_menu::MaybeResetContextMenu(owner_web_contents_);
}
return true;
}
} // namespace extensions

View File

@@ -141,16 +141,20 @@ FileChooserParams SelectFileToFileChooserParams(
params.title = title;
params.default_file_name = default_path;
// Note that this translation will lose any mime-type based filters that
// may have existed in the original FileChooserParams::accept_types if this
// dialog was created via FileSelectHelper::RunFileChooser.
if (file_types) {
// A list of allowed extensions. For example, it might be
// |file_types| comes from FileSelectHelper::GetFileTypesFromAcceptType.
// |extensions| is a list of allowed extensions. For example, it might be
// { { "htm", "html" }, { "txt" } }
for (auto& vec : file_types->extensions) {
for (auto& ext : vec) {
params.accept_types.push_back(
FilePathTypeToString16(FILE_PATH_LITERAL(".") + ext));
for (size_t i = 0; i < file_types->extensions.size(); ++i) {
if (file_types->extension_mimetypes.size() > i &&
!file_types->extension_mimetypes[i].empty()) {
// Use the original mime type.
params.accept_types.push_back(file_types->extension_mimetypes[i]);
} else if (file_types->extensions[i].size() == 1) {
// Use the single file extension. We ignore the "Custom Files" filter
// which is the only instance of multiple file extensions.
params.accept_types.push_back(FilePathTypeToString16(
FILE_PATH_LITERAL(".") + file_types->extensions[i][0]));
}
}
}
@@ -270,7 +274,8 @@ CefFileDialogManager::~CefFileDialogManager() = default;
void CefFileDialogManager::Destroy() {
if (dialog_listener_) {
// Cancel the listener and delete related objects.
SelectFileDoneByListenerCallback(/*listener_destroyed=*/false);
SelectFileDoneByListenerCallback(/*listener=*/nullptr,
/*listener_destroyed=*/false);
}
DCHECK(!dialog_);
DCHECK(!dialog_listener_);
@@ -328,8 +333,10 @@ void CefFileDialogManager::RunFileChooser(
// handled here there will be another call to the delegate from RunSelectFile.
// It might be better to execute the delegate only the single time here, but
// we don't currently have sufficient state in RunSelectFile to know that the
// delegate has already been executed.
callback = MaybeRunDelegate(params, std::move(callback));
// delegate has already been executed. Also, we haven't retrieved file
// extension data at this point.
callback = MaybeRunDelegate(params, Extensions(), Descriptions(),
std::move(callback));
if (callback.is_null()) {
// The delegate kept the callback.
return;
@@ -377,14 +384,15 @@ void CefFileDialogManager::RunSelectFile(
active_listeners_.insert(listener);
// This will not be an exact representation of the original params.
auto chooser_params =
SelectFileToFileChooserParams(type, title, default_path, file_types);
auto callback =
base::BindOnce(&CefFileDialogManager::SelectFileDoneByDelegateCallback,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(listener),
base::Unretained(params));
callback = MaybeRunDelegate(chooser_params, std::move(callback));
weak_ptr_factory_.GetWeakPtr(),
base::UnsafeDangling(listener), base::Unretained(params));
callback = MaybeRunDelegate(chooser_params, file_types->extensions,
file_types->extension_description_overrides,
std::move(callback));
if (callback.is_null()) {
// The delegate kept the callback.
return;
@@ -418,7 +426,8 @@ void CefFileDialogManager::RunSelectFile(
listener, params,
base::BindOnce(&CefFileDialogManager::SelectFileDoneByListenerCallback,
weak_ptr_factory_.GetWeakPtr(),
/*listener_destroyed=*/false));
base::UnsafeDangling(listener),
/*listener_destroyed=*/true));
// This call will not be intercepted by CefSelectFileDialogFactory due to the
// |run_from_cef=true| flag.
@@ -443,9 +452,9 @@ void CefFileDialogManager::SelectFileListenerDestroyed(
// This notification will arrive from whomever owns |listener|, so we don't
// want to execute any |listener| methods after this point.
if (dialog_listener_ && listener == dialog_listener_->listener()) {
if (dialog_listener_) {
// Cancel the currently active dialog.
SelectFileDoneByListenerCallback(/*listener_destroyed=*/true);
SelectFileDoneByListenerCallback(listener, /*listener_destroyed=*/true);
} else {
// Any future SelectFileDoneByDelegateCallback call for |listener| becomes a
// no-op.
@@ -456,7 +465,15 @@ void CefFileDialogManager::SelectFileListenerDestroyed(
CefFileDialogManager::RunFileChooserCallback
CefFileDialogManager::MaybeRunDelegate(
const blink::mojom::FileChooserParams& params,
const Extensions& extensions,
const Descriptions& descriptions,
RunFileChooserCallback callback) {
// |extensions| and |descriptions| may be empty, or may contain 1 additional
// entry for the "Custom Files" filter.
DCHECK(extensions.empty() || extensions.size() >= params.accept_types.size());
DCHECK(descriptions.empty() ||
descriptions.size() >= params.accept_types.size());
if (auto client = browser_->client()) {
if (auto handler = browser_->client()->GetDialogHandler()) {
int mode = FILE_DIALOG_OPEN;
@@ -478,12 +495,37 @@ CefFileDialogManager::MaybeRunDelegate(
break;
}
std::vector<std::u16string>::const_iterator it;
std::vector<CefString> accept_filters;
it = params.accept_types.begin();
for (; it != params.accept_types.end(); ++it) {
accept_filters.push_back(*it);
for (auto& accept_type : params.accept_types) {
accept_filters.push_back(accept_type);
}
std::vector<CefString> accept_extensions;
std::vector<CefString> accept_descriptions;
if (extensions.empty()) {
// We don't know the expansion of mime type values at this time,
// so only include the single file extensions.
for (auto& accept_type : params.accept_types) {
accept_extensions.push_back(
accept_type.ends_with(u"/*") ? std::u16string() : accept_type);
}
// Empty descriptions.
accept_descriptions.resize(params.accept_types.size());
} else {
// There may be 1 additional entry in |extensions| and |descriptions|
// that we want to ignore (for the "Custom Files" filter).
for (size_t i = 0; i < params.accept_types.size(); ++i) {
const auto& extension_list = extensions[i];
std::u16string ext_str;
for (auto& ext : extension_list) {
if (!ext_str.empty()) {
ext_str += u";";
}
ext_str += FilePathTypeToString16(FILE_PATH_LITERAL(".") + ext);
}
accept_extensions.push_back(ext_str);
accept_descriptions.push_back(descriptions[i]);
}
}
CefRefPtr<CefFileDialogCallbackImpl> callbackImpl(
@@ -491,10 +533,13 @@ CefFileDialogManager::MaybeRunDelegate(
const bool handled = handler->OnFileDialog(
browser_.get(), static_cast<cef_file_dialog_mode_t>(mode),
params.title, params.default_file_name.value(), accept_filters,
callbackImpl.get());
accept_extensions, accept_descriptions, callbackImpl.get());
if (!handled) {
// May return nullptr if the client has already executed the callback.
callback = callbackImpl->Disconnect();
LOG_IF(ERROR, callback.is_null())
<< "Should return true from OnFileDialog when executing the "
"callback";
}
}
}
@@ -503,7 +548,7 @@ CefFileDialogManager::MaybeRunDelegate(
}
void CefFileDialogManager::SelectFileDoneByDelegateCallback(
ui::SelectFileDialog::Listener* listener,
MayBeDangling<ui::SelectFileDialog::Listener> listener,
void* params,
const std::vector<base::FilePath>& paths) {
CEF_REQUIRE_UIT();
@@ -514,7 +559,7 @@ void CefFileDialogManager::SelectFileDoneByDelegateCallback(
return;
}
active_listeners_.erase(listener);
active_listeners_.erase(listener.get());
if (paths.empty()) {
listener->FileSelectionCanceled(params);
@@ -528,9 +573,14 @@ void CefFileDialogManager::SelectFileDoneByDelegateCallback(
}
void CefFileDialogManager::SelectFileDoneByListenerCallback(
MayBeDangling<ui::SelectFileDialog::Listener> listener,
bool listener_destroyed) {
CEF_REQUIRE_UIT();
// |listener| will be provided iff |listener_destroyed=true|, as
// |dialog_listener_->listener()| will return nullptr at this point.
DCHECK(!listener || listener_destroyed);
// Avoid re-entrancy of this method. CefSelectFileDialogListener callbacks to
// the delegated listener may result in an immediate call to
// SelectFileListenerDestroyed() while |dialog_listener_| is still on the
@@ -545,7 +595,8 @@ void CefFileDialogManager::SelectFileDoneByListenerCallback(
DCHECK(dialog_);
DCHECK(dialog_listener_);
active_listeners_.erase(dialog_listener_->listener());
active_listeners_.erase(listener ? listener.get()
: dialog_listener_->listener());
// Clear |dialog_listener_| before calling Cancel() to avoid re-entrancy.
auto dialog_listener = dialog_listener_;

View File

@@ -73,15 +73,21 @@ class CefFileDialogManager {
void SelectFileListenerDestroyed(ui::SelectFileDialog::Listener* listener);
private:
using Extensions = std::vector<std::vector<base::FilePath::StringType>>;
using Descriptions = std::vector<std::u16string>;
[[nodiscard]] RunFileChooserCallback MaybeRunDelegate(
const blink::mojom::FileChooserParams& params,
const Extensions& extensions,
const Descriptions& descriptions,
RunFileChooserCallback callback);
void SelectFileDoneByDelegateCallback(
ui::SelectFileDialog::Listener* listener,
MayBeDangling<ui::SelectFileDialog::Listener> listener,
void* params,
const std::vector<base::FilePath>& paths);
void SelectFileDoneByListenerCallback(bool listener_destroyed);
void SelectFileDoneByListenerCallback(
MayBeDangling<ui::SelectFileDialog::Listener> listener,
bool listener_destroyed);
// CefBrowserHostBase pointer is guaranteed to outlive this object.
const raw_ptr<CefBrowserHostBase> browser_;

View File

@@ -39,6 +39,8 @@ class CefSelectFileDialogFactory final : public ui::SelectFileDialogFactory {
// Delegates the running of the dialog to CefFileDialogManager.
class CefSelectFileDialog final : public ui::SelectFileDialog {
public:
// |listener| is not owned by this object. It will remain valid until
// ListenerDestroyed() is called.
CefSelectFileDialog(ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy)
: ui::SelectFileDialog(listener, std::move(policy)) {

View File

@@ -559,11 +559,10 @@ void CefFrameHostImpl::MaybeReAttach(
// Should not be called for temporary frames.
CHECK(!is_temporary());
if (require_detached) {
// We expect that Detach() was called previously.
CHECK(!render_frame_.is_bound());
CHECK(!render_frame_host_);
} else if (render_frame_host_) {
// If |require_detached| then we expect that Detach() was called previously.
CHECK(!require_detached || !render_frame_.is_bound());
if (render_frame_host_) {
// Intentionally not clearing |queued_renderer_actions_|, as we may be
// changing RFH during initial browser navigation.
VLOG(1) << GetDebugString()

View File

@@ -182,13 +182,6 @@ void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
content::RenderFrameHost* render_frame_host,
bool is_reload,
DialogClosedCallback callback) {
if (browser_->WillBeDestroyed()) {
// Currently destroying the browser. Accept the unload without showing
// the prompt.
std::move(callback).Run(true, std::u16string());
return;
}
const std::u16string& message_text = u"Is it OK to leave/reload this page?";
// Always call DialogClosed().

View File

@@ -269,12 +269,6 @@ bool CefMainRunner::Initialize(CefSettings* settings,
void* windows_sandbox_info,
bool* initialized,
base::OnceClosure context_initialized) {
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
LOG_IF(WARNING, !settings->chrome_runtime)
<< "Alloy bootstrap is deprecated and will be removed in ~M127. See "
"https://github.com/chromiumembedded/cef/issues/3685";
#endif
DCHECK(!main_delegate_);
main_delegate_ = MakeDelegate(
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)

View File

@@ -143,7 +143,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
}
const int32_t id_;
const raw_ptr<network::ResourceRequest> request_;
const raw_ptr<network::ResourceRequest, DisableDanglingPtrDetection>
request_;
const bool request_was_redirected_;
OnBeforeRequestResultCallback callback_;
CancelRequestCallback cancel_callback_;
@@ -613,8 +614,8 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
&InterceptedRequestHandlerWrapper::AllowCookieAlways);
auto done_cookie_callback = base::BindOnce(
&InterceptedRequestHandlerWrapper::ContinueWithLoadedCookies,
weak_ptr_factory_.GetWeakPtr(), request_id, request,
std::move(callback));
weak_ptr_factory_.GetWeakPtr(), request_id,
base::UnsafeDanglingUntriaged(request), std::move(callback));
cookie_helper::LoadCookies(init_state_->browser_context_getter_, *request,
allow_cookie_callback,
std::move(done_cookie_callback));

View File

@@ -555,6 +555,12 @@ std::optional<int> AlloyMainDelegate::BasicStartupComplete() {
logging::InitLogging(log_settings);
if (is_browser) {
LOG(WARNING)
<< "Alloy bootstrap is deprecated and will be removed in ~M127. See "
"https://github.com/chromiumembedded/cef/issues/3685";
}
ContentSettingsPattern::SetNonWildcardDomainNonPortSchemes(
kNonWildcardDomainNonPortSchemes, kNonWildcardDomainNonPortSchemesSize);

View File

@@ -35,8 +35,6 @@
#include "cef/libcef/common/util_mac.h"
#elif BUILDFLAG(IS_POSIX)
#include "cef/libcef/common/util_linux.h"
#elif BUILDFLAG(IS_WIN)
#include "sandbox/policy/features.h"
#endif
namespace {
@@ -324,15 +322,6 @@ std::optional<int> ChromeMainDelegateCef::BasicStartupComplete() {
disable_features.push_back(base::kEnableHangWatcher.name);
}
#if BUILDFLAG(IS_WIN) && (defined(COMPONENT_BUILD) || !defined(NDEBUG))
// Disable WinSboxNoFakeGdiInit for component and Debug builds. It causes
// renderer processes to crash with STATUS_DLL_INIT_FAILED. This is
// currently enabled via a field trial for non-Official builds.
// See https://crbug.com/326277735#comment37.
disable_features.push_back(
sandbox::policy::features::kWinSboxNoFakeGdiInit.name);
#endif
if (!disable_features.empty()) {
DCHECK(!base::FeatureList::GetInstance());
std::string disable_features_str =

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=1bb6115ab6501d8d006585cede00970e59af9868$
// $hash=3c95f12406eee58308a2c019e8081e0710769e0d$
//
#include "libcef_dll/cpptoc/dialog_handler_cpptoc.h"
@@ -30,6 +30,8 @@ dialog_handler_on_file_dialog(struct _cef_dialog_handler_t* self,
const cef_string_t* title,
const cef_string_t* default_file_path,
cef_string_list_t accept_filters,
cef_string_list_t accept_extensions,
cef_string_list_t accept_descriptions,
cef_file_dialog_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
@@ -49,17 +51,24 @@ dialog_handler_on_file_dialog(struct _cef_dialog_handler_t* self,
if (!callback) {
return 0;
}
// Unverified params: title, default_file_path, accept_filters
// Unverified params: title, default_file_path, accept_filters,
// accept_extensions, accept_descriptions
// Translate param: accept_filters; type: string_vec_byref_const
std::vector<CefString> accept_filtersList;
transfer_string_list_contents(accept_filters, accept_filtersList);
// Translate param: accept_extensions; type: string_vec_byref_const
std::vector<CefString> accept_extensionsList;
transfer_string_list_contents(accept_extensions, accept_extensionsList);
// Translate param: accept_descriptions; type: string_vec_byref_const
std::vector<CefString> accept_descriptionsList;
transfer_string_list_contents(accept_descriptions, accept_descriptionsList);
// Execute
bool _retval = CefDialogHandlerCppToC::Get(self)->OnFileDialog(
CefBrowserCToCpp::Wrap(browser), mode, CefString(title),
CefString(default_file_path), accept_filtersList,
CefFileDialogCallbackCToCpp::Wrap(callback));
CefString(default_file_path), accept_filtersList, accept_extensionsList,
accept_descriptionsList, CefFileDialogCallbackCToCpp::Wrap(callback));
// Return type: bool
return _retval;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=40bd7cc8a8fd361aceda9bbd426f912ac140ac3d$
// $hash=bd2c8c9be10525d69d072dacfb3cfd215486e077$
//
#include "libcef_dll/ctocpp/dialog_handler_ctocpp.h"
@@ -28,6 +28,8 @@ bool CefDialogHandlerCToCpp::OnFileDialog(
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
CefRefPtr<CefFileDialogCallback> callback) {
shutdown_checker::AssertNotShutdown();
@@ -48,7 +50,8 @@ bool CefDialogHandlerCToCpp::OnFileDialog(
if (!callback.get()) {
return false;
}
// Unverified params: title, default_file_path, accept_filters
// Unverified params: title, default_file_path, accept_filters,
// accept_extensions, accept_descriptions
// Translate param: accept_filters; type: string_vec_byref_const
cef_string_list_t accept_filtersList = cef_string_list_alloc();
@@ -56,17 +59,37 @@ bool CefDialogHandlerCToCpp::OnFileDialog(
if (accept_filtersList) {
transfer_string_list_contents(accept_filters, accept_filtersList);
}
// Translate param: accept_extensions; type: string_vec_byref_const
cef_string_list_t accept_extensionsList = cef_string_list_alloc();
DCHECK(accept_extensionsList);
if (accept_extensionsList) {
transfer_string_list_contents(accept_extensions, accept_extensionsList);
}
// Translate param: accept_descriptions; type: string_vec_byref_const
cef_string_list_t accept_descriptionsList = cef_string_list_alloc();
DCHECK(accept_descriptionsList);
if (accept_descriptionsList) {
transfer_string_list_contents(accept_descriptions, accept_descriptionsList);
}
// Execute
int _retval = _struct->on_file_dialog(
_struct, CefBrowserCppToC::Wrap(browser), mode, title.GetStruct(),
default_file_path.GetStruct(), accept_filtersList,
CefFileDialogCallbackCppToC::Wrap(callback));
default_file_path.GetStruct(), accept_filtersList, accept_extensionsList,
accept_descriptionsList, CefFileDialogCallbackCppToC::Wrap(callback));
// Restore param:accept_filters; type: string_vec_byref_const
if (accept_filtersList) {
cef_string_list_free(accept_filtersList);
}
// Restore param:accept_extensions; type: string_vec_byref_const
if (accept_extensionsList) {
cef_string_list_free(accept_extensionsList);
}
// Restore param:accept_descriptions; type: string_vec_byref_const
if (accept_descriptionsList) {
cef_string_list_free(accept_descriptionsList);
}
// Return type: bool
return _retval ? true : false;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=b9efac38dfb7834bd87b6c0dfd29e0fc3179b6ee$
// $hash=48e8da3e0a0ce27bf61f24f601d0ca179d232b90$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_DIALOG_HANDLER_CTOCPP_H_
@@ -42,6 +42,8 @@ class CefDialogHandlerCToCpp
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
CefRefPtr<CefFileDialogCallback> callback) override;
};

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=bc230d77e2985959bc5a6a2af80b500eec070384$
// $hash=4a4490df4b9440aeb853d6625fddb7de5741f5b0$
//
#include "include/capi/cef_app_capi.h"
@@ -131,12 +131,12 @@ CEF_EXPORT int cef_get_exit_code() {
CEF_EXPORT void cef_shutdown() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
CefShutdown();
#if DCHECK_IS_ON()
shutdown_checker::SetIsShutdown();
#endif
// Execute
CefShutdown();
}
CEF_EXPORT void cef_do_message_loop_work() {

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=16d4e51ecbe1fd8eb6915d951a84f707f73dfb1a$
// $hash=e9099c29c9695cabcedfde25b85c1f77f14cb516$
//
#include "include/capi/cef_app_capi.h"
@@ -119,12 +119,12 @@ NO_SANITIZE("cfi-icall") CEF_GLOBAL int CefGetExitCode() {
NO_SANITIZE("cfi-icall") CEF_GLOBAL void CefShutdown() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_shutdown();
#if DCHECK_IS_ON()
shutdown_checker::SetIsShutdown();
#endif
// Execute
cef_shutdown();
}
NO_SANITIZE("cfi-icall") CEF_GLOBAL void CefDoMessageLoopWork() {

View File

@@ -233,6 +233,10 @@ patches = [
# Fix fatal error: 'components/printing/common/print.mojom.h' file not found
# From chrome/browser/ui/browser_commands.cc via
# chrome/browser/printing/print_view_manager_common.h
#
# Avoid duplicate window from DevTools when CEF handles the open via
# OnOpenURLFromTab.
# https://github.com/chromiumembedded/cef/issues/3735
'name': 'chrome_browser_browser',
},
{
@@ -814,5 +818,22 @@ patches = [
# RequestContextTest.PopupNavDestroyParentAfterCreationRCGlobal.
# https://issues.chromium.org/issues/323753235#comment11
'name': 'content_initiator_policy_323753235'
},
{
# Move test_fonts into their own directory.
# https://issues.chromium.org/issues/343199633
'name': 'DEPS'
},
{
# win: Fix undefined std::_Literal_zero_is_expected() when building
# cef_sandbox with VS 17.9.2 version of MSVC STL.
# https://github.com/chromiumembedded/cef/issues/3708
'name': 'win_sandbox_op3way_3708'
},
{
# Fix DCHECK in SimpleMenuModel::AddSeparator when adding a separator with
# hidden menu items.
# https://github.com/chromiumembedded/cef/issues/3577
'name': 'ui_menu_model_3577'
}
]

26
patch/patches/DEPS.patch Normal file
View File

@@ -0,0 +1,26 @@
diff --git DEPS DEPS
index faa0c930d80f9..093beb1feafca 100644
--- DEPS
+++ DEPS
@@ -2102,16 +2102,16 @@ deps = {
'dep_type': 'cipd',
},
- 'src/third_party/test_fonts': {
+ 'src/third_party/test_fonts/test_fonts': {
'dep_type': 'gcs',
'condition': 'non_git_source',
'bucket': 'chromium-fonts',
'objects': [
{
- 'object_name': '336e775eec536b2d785cc80eff6ac39051931286',
- 'sha256sum': 'a2ca2962daf482a8f943163541e1c73ba4b2694fabcd2510981f2db4eda493c8',
- 'size_bytes': 32624734,
- 'generation': 1647440500943755,
+ 'object_name': 'f26f29c9d3bfae588207bbc9762de8d142e58935c62a86f67332819b15203b35',
+ 'sha256sum': 'f26f29c9d3bfae588207bbc9762de8d142e58935c62a86f67332819b15203b35',
+ 'size_bytes': 32750602,
+ 'generation': 1717109450425063,
},
],
},

View File

@@ -1,5 +1,5 @@
diff --git base/BUILD.gn base/BUILD.gn
index 575149b2f3246..74719a39cf4e4 100644
index 4c7130084a91f..c0e00c6fc2636 100644
--- base/BUILD.gn
+++ base/BUILD.gn
@@ -41,6 +41,7 @@ import("//build/nocompile.gni")
@@ -10,7 +10,7 @@ index 575149b2f3246..74719a39cf4e4 100644
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")
@@ -1525,7 +1526,11 @@ component("base") {
@@ -1526,7 +1527,11 @@ component("base") {
"hash/md5_constexpr_internal.h",
"hash/sha1.h",
]
@@ -23,7 +23,7 @@ index 575149b2f3246..74719a39cf4e4 100644
sources += [
"hash/md5_nacl.cc",
"hash/md5_nacl.h",
@@ -1954,6 +1959,12 @@ component("base") {
@@ -1955,6 +1960,12 @@ component("base") {
defines += [ "COM_INIT_CHECK_HOOK_DISABLED" ]
}

View File

@@ -1,5 +1,5 @@
diff --git third_party/blink/public/web/web_element.h third_party/blink/public/web/web_element.h
index 103cbab74b515..3b763e5100340 100644
index 97a83c2510a8e..426594b26de48 100644
--- third_party/blink/public/web/web_element.h
+++ third_party/blink/public/web/web_element.h
@@ -82,6 +82,9 @@ class BLINK_EXPORT WebElement : public WebNode {
@@ -13,10 +13,10 @@ index 103cbab74b515..3b763e5100340 100644
// Returns true if the element's contenteditable attribute is in the true
// state or in the plaintext-only state:
diff --git third_party/blink/renderer/core/exported/web_element.cc third_party/blink/renderer/core/exported/web_element.cc
index f05470ff9c673..7ffee95e4540b 100644
index df64535ec3091..304aa5beb342f 100644
--- third_party/blink/renderer/core/exported/web_element.cc
+++ third_party/blink/renderer/core/exported/web_element.cc
@@ -118,6 +118,24 @@ void WebElement::SetAttribute(const WebString& attr_name,
@@ -119,6 +119,24 @@ void WebElement::SetAttribute(const WebString& attr_name,
IGNORE_EXCEPTION_FOR_TESTING);
}

View File

@@ -20,10 +20,10 @@ index 7822aeab4826a..fa72112bfee98 100644
// Make an exception to allow most visited tiles to commit in
diff --git content/browser/renderer_host/navigation_request.cc content/browser/renderer_host/navigation_request.cc
index e3dd21898b85e..2176fde9c1764 100644
index 6edf9572aec89..0bd41f059307d 100644
--- content/browser/renderer_host/navigation_request.cc
+++ content/browser/renderer_host/navigation_request.cc
@@ -7958,10 +7958,22 @@ NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
@@ -7974,10 +7974,22 @@ NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
bool use_opaque_origin =
(sandbox_flags & network::mojom::WebSandboxFlags::kOrigin) ==
network::mojom::WebSandboxFlags::kOrigin;
@@ -47,7 +47,7 @@ index e3dd21898b85e..2176fde9c1764 100644
}
return origin_and_debug_info;
@@ -8069,6 +8081,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
@@ -8085,6 +8097,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
DetermineInitiatorRelationship(initiator_rfh,
frame_tree_node_->current_frame_host()));

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn
index c9ff70a8f2f71..d056d3758d564 100644
index 0be27cd41b866..18f20a7f36972 100644
--- chrome/browser/BUILD.gn
+++ chrome/browser/BUILD.gn
@@ -11,6 +11,7 @@ import("//build/config/compiler/pgo/pgo.gni")
@@ -10,7 +10,7 @@ index c9ff70a8f2f71..d056d3758d564 100644
import("//chrome/browser/buildflags.gni")
import("//chrome/browser/downgrade/buildflags.gni")
import("//chrome/common/features.gni")
@@ -2091,6 +2092,7 @@ static_library("browser") {
@@ -2097,6 +2098,7 @@ static_library("browser") {
"//build/config/chromebox_for_meetings:buildflags",
"//build/config/compiler:compiler_buildflags",
"//cc",
@@ -18,7 +18,7 @@ index c9ff70a8f2f71..d056d3758d564 100644
"//chrome:extra_resources",
"//chrome:resources",
"//chrome:strings",
@@ -2790,6 +2792,10 @@ static_library("browser") {
@@ -2795,6 +2797,10 @@ static_library("browser") {
]
}

View File

@@ -13,7 +13,7 @@ index 2480282a19d12..dbd1fbf8a15b5 100644
return false;
}
diff --git chrome/browser/devtools/devtools_window.cc chrome/browser/devtools/devtools_window.cc
index e857e2363da9e..3dd4db8ae4267 100644
index e857e2363da9e..e3ed4ad6048bc 100644
--- chrome/browser/devtools/devtools_window.cc
+++ chrome/browser/devtools/devtools_window.cc
@@ -37,6 +37,7 @@
@@ -38,7 +38,21 @@ index e857e2363da9e..3dd4db8ae4267 100644
}
// Create WebContents with devtools.
@@ -1916,12 +1924,28 @@ void DevToolsWindow::CreateDevToolsBrowser() {
@@ -1751,9 +1759,13 @@ void DevToolsWindow::OpenInNewTab(const GURL& url) {
if (!inspected_web_contents ||
!inspected_web_contents->OpenURL(params,
/*navigation_handle_callback=*/{})) {
+#if !BUILDFLAG(ENABLE_CEF)
+ // Remove default behavior when CEF handles the open via OnOpenURLFromTab.
+ // See CEF issue #3735.
chrome::ScopedTabbedBrowserDisplayer displayer(profile_);
chrome::AddSelectedTabWithURL(displayer.browser(), fixed_url,
ui::PAGE_TRANSITION_LINK);
+#endif
}
}
@@ -1916,12 +1928,28 @@ void DevToolsWindow::CreateDevToolsBrowser() {
Browser::CreationStatus::kOk) {
return;
}
@@ -74,7 +88,7 @@ index e857e2363da9e..3dd4db8ae4267 100644
}
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
index 6ca4ed42a601d..feec87943fee4 100644
index f61a369f16ee3..a0313d74a02ee 100644
--- chrome/browser/ui/BUILD.gn
+++ chrome/browser/ui/BUILD.gn
@@ -8,6 +8,7 @@ import("//build/config/compiler/compiler.gni")
@@ -113,7 +127,7 @@ index 6ca4ed42a601d..feec87943fee4 100644
"views/apps/app_info_dialog/arc_app_info_links_panel.cc",
"views/apps/app_info_dialog/arc_app_info_links_panel.h",
"views/apps/chrome_app_window_client_views_chromeos.cc",
@@ -5113,8 +5121,6 @@ static_library("ui") {
@@ -5118,8 +5126,6 @@ static_library("ui") {
"views/accessibility/theme_tracking_non_accessible_image_view.h",
"views/apps/app_dialog/app_dialog_view.cc",
"views/apps/app_dialog/app_dialog_view.h",
@@ -122,7 +136,7 @@ index 6ca4ed42a601d..feec87943fee4 100644
"views/apps/app_info_dialog/app_info_dialog_container.cc",
"views/apps/app_info_dialog/app_info_dialog_container.h",
"views/apps/app_info_dialog/app_info_dialog_views.cc",
@@ -6965,6 +6971,7 @@ static_library("ui") {
@@ -6972,6 +6978,7 @@ static_library("ui") {
if (enable_printing) {
deps += [
"//components/printing/browser",
@@ -131,7 +145,7 @@ index 6ca4ed42a601d..feec87943fee4 100644
]
}
diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc
index a1d50c2e47056..5519a1c7714d5 100644
index f6302e83d3b00..ce0d6010d4b5c 100644
--- chrome/browser/ui/browser.cc
+++ chrome/browser/ui/browser.cc
@@ -269,6 +269,25 @@
@@ -184,7 +198,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
///////////////////////////////////////////////////////////////////////////////
@@ -1170,6 +1199,8 @@ void Browser::WindowFullscreenStateChanged() {
@@ -1174,6 +1203,8 @@ void Browser::WindowFullscreenStateChanged() {
->WindowFullscreenStateChanged();
command_controller_->FullscreenStateChanged();
UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
@@ -193,7 +207,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
void Browser::FullscreenTopUIStateChanged() {
@@ -1511,6 +1542,14 @@ content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent(
@@ -1515,6 +1546,14 @@ content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent(
if (exclusive_access_manager_->HandleUserKeyEvent(event))
return content::KeyboardEventProcessingResult::HANDLED;
@@ -208,7 +222,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
return window()->PreHandleKeyboardEvent(event);
}
@@ -1518,8 +1557,18 @@ bool Browser::HandleKeyboardEvent(content::WebContents* source,
@@ -1522,8 +1561,18 @@ bool Browser::HandleKeyboardEvent(content::WebContents* source,
const NativeWebKeyboardEvent& event) {
DevToolsWindow* devtools_window =
DevToolsWindow::GetInstanceForInspectedWebContents(source);
@@ -229,7 +243,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
bool Browser::TabsNeedBeforeUnloadFired() const {
@@ -1695,6 +1744,16 @@ WebContents* Browser::OpenURLFromTab(
@@ -1699,6 +1748,16 @@ WebContents* Browser::OpenURLFromTab(
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -246,7 +260,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
NavigateParams nav_params(this, params.url, params.transition);
nav_params.FillNavigateParamsFromOpenURLParams(params);
nav_params.source_contents = source;
@@ -1857,6 +1916,8 @@ void Browser::LoadingStateChanged(WebContents* source,
@@ -1861,6 +1920,8 @@ void Browser::LoadingStateChanged(WebContents* source,
bool should_show_loading_ui) {
ScheduleUIUpdate(source, content::INVALIDATE_TYPE_LOAD);
UpdateWindowForLoadingStateChanged(source, should_show_loading_ui);
@@ -255,7 +269,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
void Browser::CloseContents(WebContents* source) {
@@ -1885,6 +1946,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
@@ -1889,6 +1950,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
}
void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
@@ -264,7 +278,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
if (!GetStatusBubble())
return;
@@ -1892,6 +1955,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
@@ -1896,6 +1959,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
GetStatusBubble()->SetURL(url);
}
@@ -282,7 +296,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
void Browser::ContentsMouseEvent(WebContents* source, const ui::Event& event) {
const ui::EventType type = event.type();
const bool exited = type == ui::ET_MOUSE_EXITED;
@@ -1919,6 +1993,19 @@ bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
@@ -1923,6 +1997,19 @@ bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
return false;
}
@@ -302,7 +316,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
void Browser::BeforeUnloadFired(WebContents* web_contents,
bool proceed,
bool* proceed_to_fire_unload) {
@@ -2018,12 +2105,24 @@ void Browser::WebContentsCreated(WebContents* source_contents,
@@ -2022,12 +2109,24 @@ void Browser::WebContentsCreated(WebContents* source_contents,
// Make the tab show up in the task manager.
task_manager::WebContentsTags::CreateForTabContents(new_contents);
@@ -327,7 +341,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
// Don't show the page hung dialog when a HTML popup hangs because
// the dialog will take the focus and immediately close the popup.
RenderWidgetHostView* view = render_widget_host->GetView();
@@ -2036,6 +2135,13 @@ void Browser::RendererUnresponsive(
@@ -2040,6 +2139,13 @@ void Browser::RendererUnresponsive(
void Browser::RendererResponsive(
WebContents* source,
content::RenderWidgetHost* render_widget_host) {
@@ -341,7 +355,23 @@ index a1d50c2e47056..5519a1c7714d5 100644
RenderWidgetHostView* view = render_widget_host->GetView();
if (view && !render_widget_host->GetView()->IsHTMLFormPopup()) {
TabDialogs::FromWebContents(source)->HideHungRendererDialog(
@@ -2089,6 +2195,11 @@ void Browser::DraggableRegionsChanged(
@@ -2049,6 +2155,15 @@ void Browser::RendererResponsive(
content::JavaScriptDialogManager* Browser::GetJavaScriptDialogManager(
WebContents* source) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_) {
+ auto* cef_js_dialog_manager =
+ cef_browser_delegate_->GetJavaScriptDialogManager(source);
+ if (cef_js_dialog_manager) {
+ return cef_js_dialog_manager;
+ }
+ }
+#endif
return javascript_dialogs::TabModalDialogManager::FromWebContents(source);
}
@@ -2093,6 +2208,11 @@ void Browser::DraggableRegionsChanged(
if (app_controller_) {
app_controller_->DraggableRegionsChanged(regions, contents);
}
@@ -353,7 +383,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
void Browser::DidFinishNavigation(
@@ -2169,11 +2280,15 @@ void Browser::EnterFullscreenModeForTab(
@@ -2173,11 +2293,15 @@ void Browser::EnterFullscreenModeForTab(
const blink::mojom::FullscreenOptions& options) {
exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
requesting_frame, options.display_id);
@@ -369,7 +399,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) {
@@ -2373,6 +2488,15 @@ void Browser::RequestMediaAccessPermission(
@@ -2377,6 +2501,15 @@ void Browser::RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
content::MediaResponseCallback callback) {
@@ -385,7 +415,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
const extensions::Extension* extension =
GetExtensionForOrigin(profile_, request.security_origin);
MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
@@ -2917,9 +3041,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
@@ -2921,9 +3054,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
// Browser, Getters for UI (private):
StatusBubble* Browser::GetStatusBubble() {
@@ -398,7 +428,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
// We hide the status bar for web apps windows as this matches native
@@ -2927,6 +3053,12 @@ StatusBubble* Browser::GetStatusBubble() {
@@ -2931,6 +3066,12 @@ StatusBubble* Browser::GetStatusBubble() {
// mode, as the minimal browser UI includes the status bar.
if (web_app::AppBrowserController::IsWebApp(this) &&
!app_controller()->HasMinimalUiButtons()) {
@@ -411,7 +441,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
return nullptr;
}
@@ -3076,6 +3208,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
@@ -3080,6 +3221,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this);
web_contents_collection_.StopObserving(web_contents);
}
@@ -420,7 +450,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
}
void Browser::TabDetachedAtImpl(content::WebContents* contents,
@@ -3230,6 +3364,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature(
@@ -3234,6 +3377,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature(
bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
bool check_can_support) const {
@@ -436,7 +466,7 @@ index a1d50c2e47056..5519a1c7714d5 100644
case TYPE_NORMAL:
return NormalBrowserSupportsWindowFeature(feature, check_can_support);
diff --git chrome/browser/ui/browser.h chrome/browser/ui/browser.h
index af562dfe07909..c81b2b05a85df 100644
index a8581389a1a44..43f864f7210e8 100644
--- chrome/browser/ui/browser.h
+++ chrome/browser/ui/browser.h
@@ -22,6 +22,7 @@
@@ -501,7 +531,7 @@ index af562dfe07909..c81b2b05a85df 100644
// Get the FindBarController for this browser, creating it if it does not
// yet exist.
FindBarController* GetFindBarController();
@@ -947,10 +974,18 @@ class Browser : public TabStripModelObserver,
@@ -948,10 +975,18 @@ class Browser : public TabStripModelObserver,
void SetContentsBounds(content::WebContents* source,
const gfx::Rect& bounds) override;
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
@@ -520,7 +550,7 @@ index af562dfe07909..c81b2b05a85df 100644
void BeforeUnloadFired(content::WebContents* source,
bool proceed,
bool* proceed_to_fire_unload) override;
@@ -1292,6 +1327,10 @@ class Browser : public TabStripModelObserver,
@@ -1293,6 +1328,10 @@ class Browser : public TabStripModelObserver,
// This Browser's window.
raw_ptr<BrowserWindow, DanglingUntriaged> window_;
@@ -531,7 +561,7 @@ index af562dfe07909..c81b2b05a85df 100644
std::unique_ptr<TabStripModelDelegate> const tab_strip_model_delegate_;
std::unique_ptr<TabStripModel> const tab_strip_model_;
@@ -1358,6 +1397,8 @@ class Browser : public TabStripModelObserver,
@@ -1359,6 +1398,8 @@ class Browser : public TabStripModelObserver,
const std::string initial_workspace_;
bool initial_visible_on_all_workspaces_state_;

View File

@@ -1,8 +1,8 @@
diff --git chrome/browser/renderer_context_menu/render_view_context_menu.cc chrome/browser/renderer_context_menu/render_view_context_menu.cc
index b62e659a27d00..e76cc7c0a7813 100644
index de0d60b248414..7eae5ff63383a 100644
--- chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -357,6 +357,18 @@ base::OnceCallback<void(RenderViewContextMenu*)>* GetMenuShownCallback() {
@@ -359,6 +359,18 @@ base::OnceCallback<void(RenderViewContextMenu*)>* GetMenuShownCallback() {
return callback.get();
}
@@ -21,7 +21,7 @@ index b62e659a27d00..e76cc7c0a7813 100644
enum class UmaEnumIdLookupType {
GeneralEnumId,
ContextSpecificEnumId,
@@ -618,6 +630,10 @@ int FindUMAEnumValueForCommand(int id, UmaEnumIdLookupType type) {
@@ -620,6 +632,10 @@ int FindUMAEnumValueForCommand(int id, UmaEnumIdLookupType type) {
if (ContextMenuMatcher::IsExtensionsCustomCommandId(id))
return 1;
@@ -32,7 +32,7 @@ index b62e659a27d00..e76cc7c0a7813 100644
id = CollapseCommandsForUMA(id);
const auto& map = GetIdcToUmaMap(type);
auto it = map.find(id);
@@ -868,6 +884,14 @@ RenderViewContextMenu::RenderViewContextMenu(
@@ -879,6 +895,14 @@ RenderViewContextMenu::RenderViewContextMenu(
pdf_ocr_submenu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
@@ -47,7 +47,7 @@ index b62e659a27d00..e76cc7c0a7813 100644
observers_.AddObserver(&autofill_context_menu_manager_);
}
@@ -1343,6 +1367,12 @@ void RenderViewContextMenu::InitMenu() {
@@ -1354,6 +1378,12 @@ void RenderViewContextMenu::InitMenu() {
autofill::SuggestionHidingReason::kContextMenuOpened);
}
}
@@ -60,7 +60,7 @@ index b62e659a27d00..e76cc7c0a7813 100644
}
Profile* RenderViewContextMenu::GetProfile() const {
@@ -3564,6 +3594,26 @@ void RenderViewContextMenu::RegisterExecutePluginActionCallbackForTesting(
@@ -3590,6 +3620,26 @@ void RenderViewContextMenu::RegisterExecutePluginActionCallbackForTesting(
execute_plugin_action_callback_ = std::move(cb);
}
@@ -88,10 +88,10 @@ index b62e659a27d00..e76cc7c0a7813 100644
RenderViewContextMenu::GetHandlersForLinkUrl() {
custom_handlers::ProtocolHandlerRegistry::ProtocolHandlerList handlers =
diff --git chrome/browser/renderer_context_menu/render_view_context_menu.h chrome/browser/renderer_context_menu/render_view_context_menu.h
index 6c59d4ccaf3d5..21c959aea9c21 100644
index d9f97fbdced53..60a01f70592a3 100644
--- chrome/browser/renderer_context_menu/render_view_context_menu.h
+++ chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -155,7 +155,21 @@ class RenderViewContextMenu
@@ -157,7 +157,21 @@ class RenderViewContextMenu
}
#endif
@@ -113,7 +113,7 @@ index 6c59d4ccaf3d5..21c959aea9c21 100644
Profile* GetProfile() const;
// This may return nullptr (e.g. for WebUI dialogs). Virtual to allow tests to
@@ -464,6 +478,9 @@ class RenderViewContextMenu
@@ -479,6 +493,9 @@ class RenderViewContextMenu
// built.
bool is_protocol_submenu_valid_ = false;
@@ -123,8 +123,20 @@ index 6c59d4ccaf3d5..21c959aea9c21 100644
// An observer that handles spelling suggestions, "Add to dictionary", and
// "Use enhanced spell check" items.
std::unique_ptr<SpellingMenuObserver> spelling_suggestions_menu_observer_;
diff --git chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.h chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.h
index cb51224f9892c..b5a3946999d8f 100644
--- chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.h
+++ chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.h
@@ -29,6 +29,7 @@ class RenderViewContextMenuMacCocoa : public RenderViewContextMenuMac {
// RenderViewContextMenu:
void Show() override;
+ bool IsRunning() override;
private:
// RenderViewContextMenuViewsMac:
diff --git chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm
index b130e9768c2d6..049c5fb235d87 100644
index b130e9768c2d6..3e46b2fe18d0a 100644
--- chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm
+++ chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm
@@ -68,6 +68,10 @@ RenderViewContextMenuMacCocoa::~RenderViewContextMenuMacCocoa() {
@@ -138,8 +150,46 @@ index b130e9768c2d6..049c5fb235d87 100644
views::Widget* widget = views::Widget::GetTopLevelWidgetForNativeView(
source_web_contents_->GetNativeView());
@@ -93,6 +97,10 @@ void RenderViewContextMenuMacCocoa::Show() {
views::ElementTrackerViews::GetContextForWidget(widget));
}
+bool RenderViewContextMenuMacCocoa::IsRunning() {
+ return menu_controller_ && [menu_controller_ isMenuOpen];
+}
+
void RenderViewContextMenuMacCocoa::CancelToolkitMenu() {
[menu_controller_ cancel];
}
diff --git chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.h chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.h
index fb86992cee93f..fe674fe471cc4 100644
--- chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.h
+++ chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.h
@@ -27,6 +27,7 @@ class RenderViewContextMenuMacRemoteCocoa : public RenderViewContextMenuMac {
// RenderViewContextMenu:
void Show() override;
+ bool IsRunning() override;
private:
// RenderViewContextMenuViewsMac:
diff --git chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.mm chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.mm
index 9f6c5fd44f206..dc50bc909897f 100644
--- chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.mm
+++ chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_remote_cocoa.mm
@@ -42,6 +42,10 @@ void RenderViewContextMenuMacRemoteCocoa::Show() {
target_view_id_);
}
+bool RenderViewContextMenuMacRemoteCocoa::IsRunning() {
+ return runner_ && runner_->IsRunning();
+}
+
void RenderViewContextMenuMacRemoteCocoa::CancelToolkitMenu() {
runner_->Cancel();
}
diff --git chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc
index c88a77a0b49e2..d1af9a85c4ec6 100644
index c88a77a0b49e2..31b7224a36ae8 100644
--- chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc
+++ chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc
@@ -149,6 +149,9 @@ void RenderViewContextMenuViews::RunMenuAt(views::Widget* parent,
@@ -163,6 +213,97 @@ index c88a77a0b49e2..d1af9a85c4ec6 100644
if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
return;
@@ -427,6 +434,11 @@ void RenderViewContextMenuViews::Show() {
}
}
+bool RenderViewContextMenuViews::IsRunning() {
+ return static_cast<ToolkitDelegateViews*>(toolkit_delegate())
+ ->IsMenuRunning();
+}
+
views::Widget* RenderViewContextMenuViews::GetTopLevelWidget() {
return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView());
}
diff --git chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.h chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.h
index 55ba34c417e4a..e92f668868e74 100644
--- chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.h
+++ chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.h
@@ -45,6 +45,7 @@ class RenderViewContextMenuViews : public RenderViewContextMenu {
// RenderViewContextMenuBase implementation.
void Show() override;
+ bool IsRunning() override;
protected:
RenderViewContextMenuViews(content::RenderFrameHost& render_frame_host,
diff --git chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
index eb855deeb6040..3ff97b28fa4c6 100644
--- chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
+++ chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
@@ -91,6 +91,10 @@ void ChromeWebContentsViewDelegateViews::ShowMenu(
context_menu_->Show();
}
+bool ChromeWebContentsViewDelegateViews::IsMenuRunning() {
+ return context_menu_ && context_menu_->IsRunning();
+}
+
void ChromeWebContentsViewDelegateViews::ShowContextMenu(
content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) {
diff --git chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h
index 97c98c8738965..96c142806d7b2 100644
--- chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h
+++ chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h
@@ -55,6 +55,7 @@ class ChromeWebContentsViewDelegateViews
content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) override;
void ShowMenu(std::unique_ptr<RenderViewContextMenuBase> menu) override;
+ bool IsMenuRunning() override;
private:
// The context menu is reset every time we show it, but we keep a pointer to
diff --git chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h
index 07e5b3613a2df..293282690bd5a 100644
--- chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h
+++ chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h
@@ -55,6 +55,7 @@ class ChromeWebContentsViewDelegateViewsMac
content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) override;
void ShowMenu(std::unique_ptr<RenderViewContextMenuBase> menu) override;
+ bool IsMenuRunning() override;
private:
content::RenderWidgetHostView* GetActiveRenderWidgetHostView() const;
diff --git chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm
index 0e2cf71973741..e8d9c38b49b6c 100644
--- chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm
+++ chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm
@@ -131,6 +131,10 @@ void ChromeWebContentsViewDelegateViewsMac::ShowMenu(
context_menu_->Show();
}
+bool ChromeWebContentsViewDelegateViewsMac::IsMenuRunning() {
+ return context_menu_ && context_menu_->IsRunning();
+}
+
content::RenderWidgetHostView*
ChromeWebContentsViewDelegateViewsMac::GetActiveRenderWidgetHostView() const {
return web_contents_->GetTopLevelRenderWidgetHostView();
diff --git components/renderer_context_menu/context_menu_delegate.h components/renderer_context_menu/context_menu_delegate.h
index 042428f77f4ad..e4efd98ca45d5 100644
--- components/renderer_context_menu/context_menu_delegate.h
+++ components/renderer_context_menu/context_menu_delegate.h
@@ -45,6 +45,8 @@ class ContextMenuDelegate {
// Displays the context menu.
virtual void ShowMenu(std::unique_ptr<RenderViewContextMenuBase> menu) = 0;
+ virtual bool IsMenuRunning() = 0;
+
private:
raw_ptr<content::WebContents> web_contents_ = nullptr;
};
diff --git components/renderer_context_menu/render_view_context_menu_base.cc components/renderer_context_menu/render_view_context_menu_base.cc
index 8e45cecb17039..e40115e23ee82 100644
--- components/renderer_context_menu/render_view_context_menu_base.cc
@@ -186,11 +327,15 @@ index 8e45cecb17039..e40115e23ee82 100644
command_executed_ = true;
RecordUsedItem(id);
diff --git components/renderer_context_menu/render_view_context_menu_base.h components/renderer_context_menu/render_view_context_menu_base.h
index 57b288bc885e6..112990e3a9ad3 100644
index 57b288bc885e6..9909899e3b5fe 100644
--- components/renderer_context_menu/render_view_context_menu_base.h
+++ components/renderer_context_menu/render_view_context_menu_base.h
@@ -87,6 +87,9 @@ class RenderViewContextMenuBase : public ui::SimpleMenuModel::Delegate,
@@ -85,8 +85,13 @@ class RenderViewContextMenuBase : public ui::SimpleMenuModel::Delegate,
// Programmatically closes the context menu.
void Cancel();
+ virtual bool IsRunning() = 0;
+
const ui::SimpleMenuModel& menu_model() const { return menu_model_; }
const content::ContextMenuParams& params() const { return params_; }
+ content::WebContents* source_web_contents() const {
@@ -199,7 +344,7 @@ index 57b288bc885e6..112990e3a9ad3 100644
// Returns true if the specified command id is known and valid for
// this menu. If the command is known |enabled| is set to indicate
@@ -95,6 +98,9 @@ class RenderViewContextMenuBase : public ui::SimpleMenuModel::Delegate,
@@ -95,6 +100,9 @@ class RenderViewContextMenuBase : public ui::SimpleMenuModel::Delegate,
// SimpleMenuModel::Delegate implementation.
bool IsCommandIdChecked(int command_id) const override;
@@ -246,3 +391,30 @@ index 0527c57abd51c..70bebcbb50461 100644
// Called when a user selects the specified context-menu item. This is
// only called when the observer returns true for IsCommandIdSupported()
// for that |command_id|.
diff --git components/renderer_context_menu/views/toolkit_delegate_views.cc components/renderer_context_menu/views/toolkit_delegate_views.cc
index 823f044316527..85439bf7ad2eb 100644
--- components/renderer_context_menu/views/toolkit_delegate_views.cc
+++ components/renderer_context_menu/views/toolkit_delegate_views.cc
@@ -30,6 +30,10 @@ void ToolkitDelegateViews::RunMenuAt(views::Widget* parent,
anchor_position, type);
}
+bool ToolkitDelegateViews::IsMenuRunning() const {
+ return menu_runner_ && menu_runner_->IsRunning();
+}
+
void ToolkitDelegateViews::Init(ui::SimpleMenuModel* menu_model) {
menu_adapter_ = std::make_unique<views::MenuModelAdapter>(menu_model);
std::unique_ptr<views::MenuItemView> menu_view = menu_adapter_->CreateMenu();
diff --git components/renderer_context_menu/views/toolkit_delegate_views.h components/renderer_context_menu/views/toolkit_delegate_views.h
index eacdc12813204..9084effdaa121 100644
--- components/renderer_context_menu/views/toolkit_delegate_views.h
+++ components/renderer_context_menu/views/toolkit_delegate_views.h
@@ -39,6 +39,7 @@ class ToolkitDelegateViews : public RenderViewContextMenuBase::ToolkitDelegate {
const gfx::Point& point,
ui::MenuSourceType type);
views::MenuItemView* menu_view() { return menu_view_; }
+ bool IsMenuRunning() const;
protected:
// ToolkitDelegate:

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/file_select_helper.cc chrome/browser/file_select_helper.cc
index 447a91b9ac380..cf5ad1b907977 100644
index 447a91b9ac380..0452f0a8b57cf 100644
--- chrome/browser/file_select_helper.cc
+++ chrome/browser/file_select_helper.cc
@@ -20,6 +20,7 @@
@@ -43,30 +43,23 @@ index 447a91b9ac380..cf5ad1b907977 100644
#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS)
enterprise_connectors::ContentAnalysisDelegate::Data data;
if (enterprise_connectors::ContentAnalysisDelegate::IsEnabled(
@@ -459,7 +479,8 @@ void FileSelectHelper::DontAbortOnMissingWebContentsForTesting() {
std::unique_ptr<ui::SelectFileDialog::FileTypeInfo>
FileSelectHelper::GetFileTypesFromAcceptType(
- const std::vector<std::u16string>& accept_types) {
+ const std::vector<std::u16string>& accept_types,
+ bool run_from_cef) {
auto base_file_type = std::make_unique<ui::SelectFileDialog::FileTypeInfo>();
if (accept_types.empty())
return base_file_type;
@@ -472,17 +493,24 @@ FileSelectHelper::GetFileTypesFromAcceptType(
@@ -472,31 +492,51 @@ FileSelectHelper::GetFileTypesFromAcceptType(
std::vector<base::FilePath::StringType>* extensions =
&file_type->extensions.back();
+ // Create individual filters for each accept type.
+ std::vector<std::vector<base::FilePath::StringType>> all_extensions;
+ std::vector<std::u16string> all_overrides;
+ std::vector<std::u16string> all_mimetypes;
+
// Find the corresponding extensions.
int valid_type_count = 0;
int description_id = 0;
+ std::string ascii_type;
for (const auto& accept_type : accept_types) {
+ std::vector<base::FilePath::StringType> current_extensions;
+ description_id = 0;
+ ascii_type.clear();
+
size_t old_extension_size = extensions->size();
if (accept_type[0] == '.') {
@@ -79,7 +72,11 @@ index 447a91b9ac380..cf5ad1b907977 100644
} else {
if (!base::IsStringASCII(accept_type))
continue;
@@ -493,10 +521,18 @@ FileSelectHelper::GetFileTypesFromAcceptType(
- std::string ascii_type = base::UTF16ToASCII(accept_type);
+ ascii_type = base::UTF16ToASCII(accept_type);
if (ascii_type == "image/*")
description_id = IDS_IMAGE_FILES;
else if (ascii_type == "audio/*")
description_id = IDS_AUDIO_FILES;
else if (ascii_type == "video/*")
description_id = IDS_VIDEO_FILES;
@@ -93,6 +90,8 @@ index 447a91b9ac380..cf5ad1b907977 100644
+ all_overrides.push_back(description_id != 0 ?
+ l10n_util::GetStringUTF16(description_id) :
+ std::u16string());
+ all_mimetypes.push_back(ascii_type.empty() ?
+ std::u16string() : accept_type);
+
+ extensions->insert(extensions->end(), current_extensions.begin(),
+ current_extensions.end());
@@ -100,23 +99,40 @@ index 447a91b9ac380..cf5ad1b907977 100644
if (extensions->size() > old_extension_size)
valid_type_count++;
}
@@ -521,6 +557,15 @@ FileSelectHelper::GetFileTypesFromAcceptType(
l10n_util::GetStringUTF16(description_id));
}
@@ -513,12 +553,28 @@ FileSelectHelper::GetFileTypesFromAcceptType(
// dialog uses the first extension in the list to form the description,
// like "EHTML Files". This is not what we want.
if (valid_type_count > 1 ||
- (valid_type_count == 1 && description_id == 0 && extensions->size() > 1))
+ (valid_type_count == 1 && description_id == 0 && extensions->size() > 1)) {
description_id = IDS_CUSTOM_FILES;
+ ascii_type.clear();
+ }
+ if (run_from_cef && all_extensions.size() > 1) {
- if (description_id) {
- file_type->extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(description_id));
+ file_type->extension_description_overrides.push_back(
+ description_id != 0 ?
+ l10n_util::GetStringUTF16(description_id) :
+ std::u16string());
+ file_type->extension_mimetypes.push_back(
+ ascii_type.empty() ? std::u16string() : base::ASCIIToUTF16(ascii_type));
+
+ if (all_extensions.size() > 1) {
+ // Insert filters for the specific accept types at the beginning.
+ file_type->extensions.insert(file_type->extensions.begin(),
+ all_extensions.begin(), all_extensions.end());
+ file_type->extension_description_overrides.insert(
+ file_type->extension_description_overrides.begin(),
+ all_overrides.begin(), all_overrides.end());
+ }
+
return file_type;
}
+ file_type->extension_mimetypes.insert(
+ file_type->extension_mimetypes.begin(),
+ all_mimetypes.begin(), all_mimetypes.end());
}
@@ -528,7 +573,8 @@ FileSelectHelper::GetFileTypesFromAcceptType(
return file_type;
@@ -528,7 +584,8 @@ FileSelectHelper::GetFileTypesFromAcceptType(
void FileSelectHelper::RunFileChooser(
content::RenderFrameHost* render_frame_host,
scoped_refptr<content::FileSelectListener> listener,
@@ -126,7 +142,7 @@ index 447a91b9ac380..cf5ad1b907977 100644
Profile* profile = Profile::FromBrowserContext(
render_frame_host->GetProcess()->GetBrowserContext());
@@ -547,6 +593,7 @@ void FileSelectHelper::RunFileChooser(
@@ -547,6 +604,7 @@ void FileSelectHelper::RunFileChooser(
// message.
scoped_refptr<FileSelectHelper> file_select_helper(
new FileSelectHelper(profile));
@@ -134,18 +150,8 @@ index 447a91b9ac380..cf5ad1b907977 100644
file_select_helper->RunFileChooser(render_frame_host, std::move(listener),
params.Clone());
}
@@ -598,7 +645,8 @@ void FileSelectHelper::RunFileChooser(
}
void FileSelectHelper::GetFileTypesInThreadPool(FileChooserParamsPtr params) {
- select_file_types_ = GetFileTypesFromAcceptType(params->accept_types);
+ select_file_types_ = GetFileTypesFromAcceptType(params->accept_types,
+ run_from_cef_);
select_file_types_->allowed_paths =
params->need_local_path ? ui::SelectFileDialog::FileTypeInfo::NATIVE_PATH
: ui::SelectFileDialog::FileTypeInfo::ANY_PATH;
diff --git chrome/browser/file_select_helper.h chrome/browser/file_select_helper.h
index 7194323c36956..903cdf0c294fc 100644
index 7194323c36956..fd4a5361798f0 100644
--- chrome/browser/file_select_helper.h
+++ chrome/browser/file_select_helper.h
@@ -62,7 +62,8 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
@@ -158,17 +164,7 @@ index 7194323c36956..903cdf0c294fc 100644
// Enumerates all the files in directory.
static void EnumerateDirectory(
@@ -264,7 +265,8 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
// |accept_types| contains only valid lowercased MIME types or file extensions
// beginning with a period (.).
static std::unique_ptr<ui::SelectFileDialog::FileTypeInfo>
- GetFileTypesFromAcceptType(const std::vector<std::u16string>& accept_types);
+ GetFileTypesFromAcceptType(const std::vector<std::u16string>& accept_types,
+ bool run_from_cef);
// Check the accept type is valid. It is expected to be all lower case with
// no whitespace.
@@ -325,6 +327,9 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
@@ -325,6 +326,9 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
// Set to false in unit tests since there is no WebContents.
bool abort_on_missing_web_contents_in_tests_ = true;
@@ -261,7 +257,7 @@ index 68dd62159b686..e94831cd44a2d 100644
return CreateSelectFileDialog(listener, std::move(policy));
}
diff --git ui/shell_dialogs/select_file_dialog.h ui/shell_dialogs/select_file_dialog.h
index 9b12fae59c3cc..dfb534a6f06e6 100644
index 9b12fae59c3cc..a80873f421c8d 100644
--- ui/shell_dialogs/select_file_dialog.h
+++ ui/shell_dialogs/select_file_dialog.h
@@ -102,7 +102,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
@@ -274,7 +270,18 @@ index 9b12fae59c3cc..dfb534a6f06e6 100644
SelectFileDialog(const SelectFileDialog&) = delete;
SelectFileDialog& operator=(const SelectFileDialog&) = delete;
@@ -199,6 +200,19 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
@@ -126,6 +127,10 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
// be used.
std::vector<std::u16string> extension_description_overrides;
+ // Original mime types for the specified extensions. Entries correspond to
+ // |extensions|; if left blank then there was no mime type.
+ std::vector<std::u16string> extension_mimetypes;
+
// Specifies whether there will be a filter added for all files (i.e. *.*).
bool include_all_files = false;
@@ -199,6 +204,19 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
const GURL* caller = nullptr);
bool HasMultipleFileTypeChoices();
@@ -294,7 +301,7 @@ index 9b12fae59c3cc..dfb534a6f06e6 100644
protected:
friend class base::RefCountedThreadSafe<SelectFileDialog>;
@@ -224,6 +238,11 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
@@ -224,6 +242,11 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
// The listener to be notified of selection completion.
raw_ptr<Listener> listener_;
@@ -306,7 +313,7 @@ index 9b12fae59c3cc..dfb534a6f06e6 100644
private:
// Tests if the file selection dialog can be displayed by
// testing if the AllowFileSelectionDialogs-Policy is
@@ -236,8 +255,6 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
@@ -236,8 +259,6 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
// Returns true if the dialog has multiple file type choices.
virtual bool HasMultipleFileTypeChoicesImpl() = 0;

View File

@@ -12,16 +12,15 @@ index b169371e4d42f..509e4bda85b47 100644
// on the screen, we can't actually attach to it.
parent_window = nullptr;
diff --git components/constrained_window/constrained_window_views.cc components/constrained_window/constrained_window_views.cc
index a2ca2f52148fd..7689d43ec9e0b 100644
index 0ffc333329d4d..91b7567c123ac 100644
--- components/constrained_window/constrained_window_views.cc
+++ components/constrained_window/constrained_window_views.cc
@@ -101,9 +101,18 @@ class WidgetModalDialogHostObserverViews : public views::WidgetObserver,
@@ -101,10 +101,17 @@ class WidgetModalDialogHostObserverViews : public views::WidgetObserver,
gfx::Rect GetModalDialogBounds(views::Widget* widget,
web_modal::ModalDialogHost* dialog_host,
const gfx::Size& size) {
- views::Widget* const host_widget =
- views::Widget::GetWidgetForNativeView(dialog_host->GetHostView());
- CHECK(host_widget);
+ // |host_view| will be nullptr with CEF windowless rendering.
+ auto host_view = dialog_host->GetHostView();
+ views::Widget* host_widget =
@@ -31,13 +30,13 @@ index a2ca2f52148fd..7689d43ec9e0b 100644
+ // size. This can happen on MacViews under the Cocoa browser where the window
+ // modal dialogs are displayed as sheets, and their position is managed by a
+ // ConstrainedWindowSheetController instance.
+ if (!host_widget) {
if (!host_widget) {
- return gfx::Rect();
+ return gfx::Rect(dialog_host->GetDialogPosition(size), size);
+ }
}
gfx::Point position = dialog_host->GetDialogPosition(size);
// Align the first row of pixels inside the border. This is the apparent top
@@ -111,43 +120,22 @@ gfx::Rect GetModalDialogBounds(views::Widget* widget,
@@ -113,43 +120,22 @@ gfx::Rect GetModalDialogBounds(views::Widget* widget,
position.set_y(position.y() -
widget->non_client_view()->frame_view()->GetInsets().top());
@@ -95,7 +94,7 @@ index a2ca2f52148fd..7689d43ec9e0b 100644
}
void UpdateModalDialogPosition(views::Widget* widget,
@@ -158,15 +146,24 @@ void UpdateModalDialogPosition(views::Widget* widget,
@@ -160,15 +146,24 @@ void UpdateModalDialogPosition(views::Widget* widget,
return;
}
@@ -122,7 +121,7 @@ index a2ca2f52148fd..7689d43ec9e0b 100644
return;
}
@@ -282,8 +279,13 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
@@ -284,8 +279,13 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
gfx::NativeView parent_view =
parent ? CurrentClient()->GetDialogHostView(parent) : nullptr;
@@ -137,7 +136,7 @@ index a2ca2f52148fd..7689d43ec9e0b 100644
widget->SetNativeWindowProperty(
views::kWidgetIdentifierKey,
const_cast<void*>(kConstrainedWindowWidgetIdentifier));
@@ -299,8 +301,7 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
@@ -301,8 +301,7 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
if (!requires_positioning)
return widget;
@@ -147,7 +146,7 @@ index a2ca2f52148fd..7689d43ec9e0b 100644
if (host) {
DCHECK_EQ(parent_view, host->GetHostView());
ModalDialogHostObserver* dialog_host_observer =
@@ -313,10 +314,17 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
@@ -315,10 +314,17 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
views::Widget* ShowBrowserModal(std::unique_ptr<ui::DialogModel> dialog_model,
gfx::NativeWindow parent) {

View File

@@ -422,7 +422,7 @@ index 3c12614c4d7d2..1dc97ecf5a11e 100644
+#endif
}
diff --git chrome/browser/chrome_content_browser_client.cc chrome/browser/chrome_content_browser_client.cc
index 675a9ab64ea08..d0c160a14b2a7 100644
index 7acca810b6f4e..cc6e90f9a993e 100644
--- chrome/browser/chrome_content_browser_client.cc
+++ chrome/browser/chrome_content_browser_client.cc
@@ -46,6 +46,7 @@
@@ -512,7 +512,7 @@ index 675a9ab64ea08..d0c160a14b2a7 100644
}
base::FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() {
@@ -6592,7 +6599,7 @@ void ChromeContentBrowserClient::OnNetworkServiceCreated(
@@ -6598,7 +6605,7 @@ void ChromeContentBrowserClient::OnNetworkServiceCreated(
#endif
}
@@ -521,7 +521,7 @@ index 675a9ab64ea08..d0c160a14b2a7 100644
content::BrowserContext* context,
bool in_memory,
const base::FilePath& relative_partition_path,
@@ -6610,6 +6617,8 @@ void ChromeContentBrowserClient::ConfigureNetworkContextParams(
@@ -6616,6 +6623,8 @@ void ChromeContentBrowserClient::ConfigureNetworkContextParams(
network_context_params->user_agent = GetUserAgentBasedOnPolicy(context);
network_context_params->accept_language = GetApplicationLocale();
}
@@ -530,7 +530,7 @@ index 675a9ab64ea08..d0c160a14b2a7 100644
}
std::vector<base::FilePath>
@@ -7732,10 +7741,10 @@ void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
@@ -7738,10 +7747,10 @@ void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
const auto now = base::TimeTicks::Now();
const auto timeout = GetKeepaliveTimerTimeout(context);
keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout);
@@ -543,7 +543,7 @@ index 675a9ab64ea08..d0c160a14b2a7 100644
FROM_HERE, keepalive_deadline_ - now,
base::BindOnce(
&ChromeContentBrowserClient::OnKeepaliveTimerFired,
@@ -7754,7 +7763,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
@@ -7760,7 +7769,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
--num_keepalive_requests_;
if (num_keepalive_requests_ == 0) {
DVLOG(1) << "Stopping the keepalive timer";
@@ -553,7 +553,7 @@ index 675a9ab64ea08..d0c160a14b2a7 100644
// This deletes the keep alive handle attached to the timer function and
// unblock the shutdown sequence.
}
@@ -7923,7 +7933,7 @@ void ChromeContentBrowserClient::OnKeepaliveTimerFired(
@@ -7929,7 +7939,7 @@ void ChromeContentBrowserClient::OnKeepaliveTimerFired(
const auto now = base::TimeTicks::Now();
const auto then = keepalive_deadline_;
if (now < then) {
@@ -594,7 +594,7 @@ index 6c9208d7b7907..77f049cc7483c 100644
#endif
diff --git chrome/browser/prefs/browser_prefs.cc chrome/browser/prefs/browser_prefs.cc
index 750d634f641b1..86220ec515c0c 100644
index 21f6c6f5edc95..3a5a83dac9f27 100644
--- chrome/browser/prefs/browser_prefs.cc
+++ chrome/browser/prefs/browser_prefs.cc
@@ -16,6 +16,7 @@
@@ -616,7 +616,7 @@ index 750d634f641b1..86220ec515c0c 100644
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/accessibility/animation_policy_prefs.h"
#include "chrome/browser/apps/platform_apps/shortcut_manager.h"
@@ -1820,7 +1825,8 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
@@ -1827,7 +1832,8 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
#endif // BUILDFLAG(IS_WIN)
@@ -626,7 +626,7 @@ index 750d634f641b1..86220ec515c0c 100644
downgrade::RegisterPrefs(registry);
#endif
@@ -1864,6 +1870,11 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
@@ -1871,6 +1877,11 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
// This is intentionally last.
RegisterLocalStatePrefsForMigration(registry);
@@ -638,7 +638,7 @@ index 750d634f641b1..86220ec515c0c 100644
}
// Register prefs applicable to all profiles.
@@ -2317,6 +2328,10 @@ void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
@@ -2326,6 +2337,10 @@ void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
const std::string& locale) {
RegisterProfilePrefs(registry, locale);

View File

@@ -712,7 +712,7 @@ index e7337adf73caf..6130a2eb8fb5c 100644
// Do not friend BrowserViewLayout. Use the BrowserViewLayoutDelegate
// interface to keep these two classes decoupled and testable.
diff --git chrome/browser/ui/views/frame/browser_view_layout.cc chrome/browser/ui/views/frame/browser_view_layout.cc
index a7f0ff7ce857e..0ee1c61503204 100644
index 96b489221fb3a..b372f67cd5c92 100644
--- chrome/browser/ui/views/frame/browser_view_layout.cc
+++ chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -48,6 +48,10 @@
@@ -755,8 +755,8 @@ index a7f0ff7ce857e..0ee1c61503204 100644
return gfx::Size(content_area.width(), content_area.bottom() - top);
}
@@ -131,6 +139,13 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
return GetHostWidget()->GetNativeView();
@@ -132,6 +140,13 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
return host_widget ? host_widget->GetNativeView() : nullptr;
}
+ int GetDialogTopY() const {
@@ -769,7 +769,7 @@ index a7f0ff7ce857e..0ee1c61503204 100644
// Add/remove observer.
void AddObserver(ModalDialogHostObserver* observer) override {
observer_list_.AddObserver(observer);
@@ -441,6 +456,8 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
@@ -442,6 +457,8 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
if (exclusive_access_bubble)
exclusive_access_bubble->RepositionIfVisible();
@@ -778,7 +778,7 @@ index a7f0ff7ce857e..0ee1c61503204 100644
// Adjust any hosted dialogs if the browser's dialog hosting bounds changed.
const gfx::Rect dialog_bounds(dialog_host_->GetDialogPosition(gfx::Size()),
dialog_host_->GetMaximumDialogSize());
@@ -454,6 +471,7 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
@@ -455,6 +472,7 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
latest_dialog_bounds_in_screen_ = dialog_bounds_in_screen;
dialog_host_->NotifyPositionRequiresUpdate();
}
@@ -786,7 +786,7 @@ index a7f0ff7ce857e..0ee1c61503204 100644
}
gfx::Size BrowserViewLayout::GetPreferredSize(
@@ -589,6 +607,13 @@ int BrowserViewLayout::LayoutWebUITabStrip(int top) {
@@ -590,6 +608,13 @@ int BrowserViewLayout::LayoutWebUITabStrip(int top) {
int BrowserViewLayout::LayoutToolbar(int top) {
TRACE_EVENT0("ui", "BrowserViewLayout::LayoutToolbar");
@@ -931,10 +931,10 @@ index b862ceac7225d..9575440a77d67 100644
LocationBarView* location_bar_view = browser_view_->GetLocationBarView();
CHECK(location_bar_view);
diff --git chrome/browser/ui/views/page_action/page_action_icon_controller.cc chrome/browser/ui/views/page_action/page_action_icon_controller.cc
index ad0147f9b8fe8..80aea21bb605a 100644
index e9bc6c28db30f..38ddcb98139b0 100644
--- chrome/browser/ui/views/page_action/page_action_icon_controller.cc
+++ chrome/browser/ui/views/page_action/page_action_icon_controller.cc
@@ -96,6 +96,12 @@ void PageActionIconController::Init(const PageActionIconParams& params,
@@ -97,6 +97,12 @@ void PageActionIconController::Init(const PageActionIconParams& params,
};
for (PageActionIconType type : params.types_enabled) {

View File

@@ -12,10 +12,10 @@ index 2068552edfba8..6ef07a0a5b7fa 100644
version.Set("V8-Version", V8_VERSION_STRING);
std::string host = info.GetHeaderValue("host");
diff --git content/browser/loader/navigation_url_loader_impl.cc content/browser/loader/navigation_url_loader_impl.cc
index eef1951861e8b..4800ef3400623 100644
index 4909784a9f1e3..ef4e4414a0a9b 100644
--- content/browser/loader/navigation_url_loader_impl.cc
+++ content/browser/loader/navigation_url_loader_impl.cc
@@ -850,7 +850,7 @@ NavigationURLLoaderImpl::CreateNonNetworkLoaderFactory(
@@ -852,7 +852,7 @@ NavigationURLLoaderImpl::CreateNonNetworkLoaderFactory(
mojo::PendingRemote<network::mojom::URLLoaderFactory>
terminal_external_protocol;
bool handled = GetContentClient()->browser()->HandleExternalProtocol(
@@ -24,7 +24,7 @@ index eef1951861e8b..4800ef3400623 100644
frame_tree_node->frame_tree_node_id(), navigation_ui_data,
request_info.is_primary_main_frame,
frame_tree_node->IsInFencedFrameTree(), request_info.sandbox_flags,
@@ -862,6 +862,21 @@ NavigationURLLoaderImpl::CreateNonNetworkLoaderFactory(
@@ -864,6 +864,21 @@ NavigationURLLoaderImpl::CreateNonNetworkLoaderFactory(
*request_info.initiator_document_token)
: nullptr,
&terminal_external_protocol);

View File

@@ -76,7 +76,7 @@ index 1da479dd5eebc..ff9c7e467997c 100644
- visual_studio_runtime_dirs = []
}
diff --git chrome/chrome_paks.gni chrome/chrome_paks.gni
index 87e4b167b6a55..6dafb9ac4ed94 100644
index 55de354155c57..f0af186ba8c8d 100644
--- chrome/chrome_paks.gni
+++ chrome/chrome_paks.gni
@@ -5,6 +5,7 @@

View File

@@ -1,8 +1,8 @@
diff --git tools/gritsettings/resource_ids.spec tools/gritsettings/resource_ids.spec
index f3ca54d7277ac..16a52e64f3078 100644
index 76c5e6b9e2cd2..d55c6665a9411 100644
--- tools/gritsettings/resource_ids.spec
+++ tools/gritsettings/resource_ids.spec
@@ -1312,6 +1312,15 @@
@@ -1315,6 +1315,15 @@
# END "everything else" section.
# Everything but chrome/, components/, content/, and ios/

View File

@@ -1,5 +1,5 @@
diff --git content/browser/renderer_host/render_widget_host_view_aura.cc content/browser/renderer_host/render_widget_host_view_aura.cc
index df08c0e0fc675..1a2af7a635e75 100644
index 66a06bba31b24..e341d0f50a250 100644
--- content/browser/renderer_host/render_widget_host_view_aura.cc
+++ content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -6,6 +6,7 @@
@@ -18,7 +18,7 @@ index df08c0e0fc675..1a2af7a635e75 100644
#include "content/public/common/page_visibility_state.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/input/web_input_event.h"
@@ -738,10 +740,12 @@ gfx::Rect RenderWidgetHostViewAura::GetViewBounds() {
@@ -744,10 +746,12 @@ gfx::Rect RenderWidgetHostViewAura::GetViewBounds() {
void RenderWidgetHostViewAura::UpdateBackgroundColor() {
CHECK(GetBackgroundColor());
@@ -35,7 +35,7 @@ index df08c0e0fc675..1a2af7a635e75 100644
}
#if BUILDFLAG(IS_WIN)
@@ -2371,6 +2375,16 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
@@ -2374,6 +2378,16 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
window_->layer()->SetColor(GetBackgroundColor() ? *GetBackgroundColor()
: SK_ColorWHITE);
UpdateFrameSinkIdRegistration();

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
index 65bc8909d771f..a18907dd1e7ec 100644
index 53ad57b10a919..5cb57dfa46b01 100644
--- chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
+++ chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -23,6 +23,7 @@
@@ -10,7 +10,7 @@ index 65bc8909d771f..a18907dd1e7ec 100644
#include "chrome/browser/browser_process.h"
#include "chrome/browser/enterprise/connectors/analysis/analysis_settings.h"
#include "chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h"
@@ -357,6 +358,11 @@ bool ContentAnalysisDelegate::IsEnabled(Profile* profile,
@@ -362,6 +363,11 @@ bool ContentAnalysisDelegate::IsEnabled(Profile* profile,
GURL url,
Data* data,
AnalysisConnector connector) {

View File

@@ -0,0 +1,23 @@
diff --git ui/base/models/simple_menu_model.cc ui/base/models/simple_menu_model.cc
index bd42c5630ccf0..0c4efb9d44fa9 100644
--- ui/base/models/simple_menu_model.cc
+++ ui/base/models/simple_menu_model.cc
@@ -10,6 +10,7 @@
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/task/single_thread_task_runner.h"
+#include "cef/libcef/features/features.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/image_model.h"
#include "ui/gfx/image/image.h"
@@ -170,8 +171,10 @@ void SimpleMenuModel::AddSeparator(MenuSeparatorType separator_type) {
}
if (items_.at(last_visible_item).type == TYPE_SEPARATOR) {
+#if !BUILDFLAG(ENABLE_CEF)
DCHECK_EQ(NORMAL_SEPARATOR, separator_type);
DCHECK_EQ(NORMAL_SEPARATOR, items_.at(last_visible_item).separator_type);
+#endif
// The last item is already a separator. Don't add another.
return;
}

View File

@@ -165,7 +165,7 @@ index 3c862290eab9c..0e85970c08486 100644
LabelButtonImageContainer* image_container() {
return image_container_.get();
diff --git ui/views/controls/label.cc ui/views/controls/label.cc
index 2c773355d2961..9ccba5a459bd5 100644
index 5fc895ab7b5e2..f913b6964ce32 100644
--- ui/views/controls/label.cc
+++ ui/views/controls/label.cc
@@ -51,12 +51,29 @@ enum LabelPropertyKey {
@@ -198,7 +198,7 @@ index 2c773355d2961..9ccba5a459bd5 100644
} // namespace
namespace views {
@@ -485,6 +502,15 @@ void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
@@ -480,6 +497,15 @@ void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
OnPropertyChanged(&elide_behavior_, kPropertyEffectsPreferredSizeChanged);
}
@@ -214,7 +214,7 @@ index 2c773355d2961..9ccba5a459bd5 100644
std::u16string Label::GetTooltipText() const {
return tooltip_text_;
}
@@ -789,6 +815,16 @@ std::unique_ptr<gfx::RenderText> Label::CreateRenderText() const {
@@ -784,6 +810,16 @@ std::unique_ptr<gfx::RenderText> Label::CreateRenderText() const {
render_text->SelectRange(stored_selection_range_);
}
@@ -791,7 +791,7 @@ index dcf4b60ad92c2..64fa80edefc1b 100644
#if !BUILDFLAG(IS_CHROMEOS_LACROS)
if (root_location != root_current_location &&
diff --git ui/views/view.h ui/views/view.h
index 4024ec9778c21..d4eeb4c2922e1 100644
index e21731ab75726..1af07b1c6eb2c 100644
--- ui/views/view.h
+++ ui/views/view.h
@@ -25,6 +25,7 @@

View File

@@ -259,10 +259,10 @@ index 2cf9330a4e24b..4bf0890ae000b 100644
// Specifies which edges of the window are tiled.
diff --git ui/ozone/platform/x11/x11_window.cc ui/ozone/platform/x11/x11_window.cc
index f1c5f06fb2966..649a206664a00 100644
index 049ca2852542d..a1c6796dccaab 100644
--- ui/ozone/platform/x11/x11_window.cc
+++ ui/ozone/platform/x11/x11_window.cc
@@ -1862,7 +1862,8 @@ void X11Window::CreateXWindow(const PlatformWindowInitProperties& properties) {
@@ -1865,7 +1865,8 @@ void X11Window::CreateXWindow(const PlatformWindowInitProperties& properties) {
req.border_pixel = 0;
bounds_in_pixels_ = SanitizeBounds(bounds);
@@ -350,7 +350,7 @@ index e698f71577c51..8a6e28128564d 100644
base::WeakPtrFactory<DesktopWindowTreeHostLinux> weak_factory_{this};
};
diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
index 389e7186c3429..38f7c34326ef9 100644
index fef32675148d1..ac0f316f475f6 100644
--- ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
+++ ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -281,8 +281,8 @@ void DesktopWindowTreeHostPlatform::Init(const Widget::InitParams& params) {
@@ -530,10 +530,10 @@ index 6383110804d44..e5bc85f63fab9 100644
break;
case ui::SHOW_STATE_END:
diff --git ui/views/widget/widget.cc ui/views/widget/widget.cc
index f2f1f54c474cf..2feb6a47c04e1 100644
index e113e926b324c..572eccab19085 100644
--- ui/views/widget/widget.cc
+++ ui/views/widget/widget.cc
@@ -409,7 +409,8 @@ void Widget::Init(InitParams params) {
@@ -410,7 +410,8 @@ void Widget::Init(InitParams params) {
}
params.child |= (params.type == InitParams::TYPE_CONTROL);
@@ -543,7 +543,7 @@ index f2f1f54c474cf..2feb6a47c04e1 100644
is_headless_ = params.ShouldInitAsHeadless();
is_autosized_ = params.autosize;
@@ -501,9 +502,14 @@ void Widget::Init(InitParams params) {
@@ -502,9 +503,14 @@ void Widget::Init(InitParams params) {
if (show_state == ui::SHOW_STATE_MAXIMIZED) {
Maximize();
@@ -558,7 +558,7 @@ index f2f1f54c474cf..2feb6a47c04e1 100644
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -517,7 +523,12 @@ void Widget::Init(InitParams params) {
@@ -518,7 +524,12 @@ void Widget::Init(InitParams params) {
} else if (delegate) {
SetContentsView(delegate->TransferOwnershipOfContentsView());
if (should_set_initial_bounds) {
@@ -572,7 +572,7 @@ index f2f1f54c474cf..2feb6a47c04e1 100644
}
}
@@ -1696,10 +1707,16 @@ void Widget::OnNativeWidgetParentChanged(gfx::NativeView parent) {
@@ -1704,10 +1715,16 @@ void Widget::OnNativeWidgetParentChanged(gfx::NativeView parent) {
}
gfx::Size Widget::GetMinimumSize() const {
@@ -589,7 +589,7 @@ index f2f1f54c474cf..2feb6a47c04e1 100644
return non_client_view_ ? non_client_view_->GetMaximumSize() : gfx::Size();
}
@@ -1950,7 +1967,8 @@ bool Widget::SetInitialFocus(ui::WindowShowState show_state) {
@@ -1958,7 +1975,8 @@ bool Widget::SetInitialFocus(ui::WindowShowState show_state) {
return false;
View* v = widget_delegate_->GetInitiallyFocusedView();
if (!focus_on_creation_ || show_state == ui::SHOW_STATE_INACTIVE ||

View File

@@ -1,5 +1,5 @@
diff --git content/browser/web_contents/web_contents_impl.cc content/browser/web_contents/web_contents_impl.cc
index d08ad3ae25ab3..0979551ef5fcb 100644
index eb1953c745c77..03b1d98c1bb07 100644
--- content/browser/web_contents/web_contents_impl.cc
+++ content/browser/web_contents/web_contents_impl.cc
@@ -3578,6 +3578,12 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,

View File

@@ -0,0 +1,54 @@
diff --git base/time/time.h base/time/time.h
index 0efbea85491f4..17f9fe92ef78c 100644
--- base/time/time.h
+++ base/time/time.h
@@ -134,6 +134,13 @@ constexpr bool isnan(double d) {
}
+// Clang compiler is unable to eliminate a "dead" function call to an undefined
+// `std::_Literal_zero_is_expected()` function that MSVC uses to allow
+// comparisons with literal zero without warning.
+#define MSVC_OPERATOR_3WAY_BROKEN \
+ BUILDFLAG(IS_WIN) && (__cplusplus >= 202002L || _MSVC_LANG >= 202002L) && \
+ _MSVC_STL_VERSION >= 143 && _MSVC_STL_UPDATE >= 202303
+
// TimeDelta ------------------------------------------------------------------
class BASE_EXPORT TimeDelta {
@@ -320,8 +327,17 @@ class BASE_EXPORT TimeDelta {
// Comparison operators.
friend constexpr bool operator==(TimeDelta, TimeDelta) = default;
+#if MSVC_OPERATOR_3WAY_BROKEN
+ friend constexpr std::strong_ordering operator<=>(TimeDelta lhs,
+ TimeDelta rhs) {
+ if(lhs.delta_ == rhs.delta_) return std::strong_ordering::equal;
+ if(lhs.delta_ < rhs.delta_) return std::strong_ordering::less;
+ return std::strong_ordering::greater;
+ }
+#else
friend constexpr std::strong_ordering operator<=>(TimeDelta,
TimeDelta) = default;
+#endif
// Returns this delta, ceiled/floored/rounded-away-from-zero to the nearest
// multiple of |interval|.
@@ -472,8 +488,17 @@ class TimeBase {
// Comparison operators
friend constexpr bool operator==(const TimeBase&, const TimeBase&) = default;
+#if MSVC_OPERATOR_3WAY_BROKEN
+ friend constexpr std::strong_ordering operator<=>(TimeBase lhs,
+ TimeBase rhs) {
+ if(lhs.us_ == rhs.us_) return std::strong_ordering::equal;
+ if(lhs.us_ < rhs.us_) return std::strong_ordering::less;
+ return std::strong_ordering::greater;
+ }
+#else
friend constexpr std::strong_ordering operator<=>(const TimeBase&,
const TimeBase&) = default;
+#endif
protected:
constexpr explicit TimeBase(int64_t us) : us_(us) {}

View File

@@ -850,12 +850,6 @@ bool ClientHandler::CanDownload(CefRefPtr<CefBrowser> browser,
const CefString& request_method) {
CEF_REQUIRE_UI_THREAD();
if (!with_controls_) {
// Block the download.
LOG(INFO) << "Blocking download";
return false;
}
// Allow the download.
return true;
}

View File

@@ -7,11 +7,13 @@
#include <libgen.h>
#include <sys/stat.h>
#include "include/base/cef_logging.h"
#include "include/cef_browser.h"
#include "include/cef_parser.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/cefclient/browser/root_window.h"
#include "tests/cefclient/browser/util_gtk.h"
#include "tests/shared/common/string_util.h"
namespace client {
@@ -49,11 +51,14 @@ std::string GetDescriptionFromMimeType(const std::string& mime_type) {
}
}
LOG(WARNING) << "Unrecognized mime type: " << mime_type;
return std::string();
}
void AddFilters(GtkFileChooser* chooser,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
bool include_all_files,
std::vector<GtkFileFilter*>* filters) {
bool has_filter = false;
@@ -64,33 +69,13 @@ void AddFilters(GtkFileChooser* chooser,
continue;
}
std::vector<std::string> extensions;
std::string description;
size_t sep_index = filter.find('|');
if (sep_index != std::string::npos) {
// Treat as a filter of the form "Filter Name|.ext1;.ext2;.ext3".
description = filter.substr(0, sep_index);
const std::string& exts = filter.substr(sep_index + 1);
size_t last = 0;
size_t size = exts.size();
for (size_t i = 0; i <= size; ++i) {
if (i == size || exts[i] == ';') {
std::string ext(exts, last, i - last);
if (!ext.empty() && ext[0] == '.') {
extensions.push_back(ext);
}
last = i + 1;
}
}
} else if (filter[0] == '.') {
// Treat as an extension beginning with the '.' character.
extensions.push_back(filter);
} else {
// Otherwise convert mime type to one or more extensions.
description = GetDescriptionFromMimeType(filter);
// Extensions and descriptions may be provided.
std::vector<std::string> extensions =
AsciiStrSplit(accept_extensions[j], ';');
std::string description = accept_descriptions[j];
if (extensions.empty()) {
// Try to convert mime type to one or more extensions.
std::vector<CefString> ext;
CefGetExtensionsForMimeType(filter, ext);
for (size_t x = 0; x < ext.size(); ++x) {
@@ -102,6 +87,10 @@ void AddFilters(GtkFileChooser* chooser,
continue;
}
if (description.empty() && filter[0] != '.') {
description = GetDescriptionFromMimeType(filter);
}
GtkFileFilter* gtk_filter = gtk_file_filter_new();
std::string ext_str;
@@ -154,6 +143,24 @@ GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
return nullptr;
}
// Returns true if |accept_filters| contains a MIME type value without matching
// extensions in |accept_extensions|.
bool MissingMimeTypeData(const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions) {
if (accept_filters.empty()) {
return false;
}
for (size_t i = 0; i < accept_filters.size(); ++i) {
const std::string& filter = accept_filters[i];
if (filter[0] != '.' && accept_extensions[i].empty()) {
return true;
}
}
return false;
}
} // namespace
ClientDialogHandlerGtk::ClientDialogHandlerGtk() : gtk_dialog_(nullptr) {}
@@ -164,8 +171,17 @@ bool ClientDialogHandlerGtk::OnFileDialog(
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
CefRefPtr<CefFileDialogCallback> callback) {
CEF_REQUIRE_UI_THREAD();
DCHECK((accept_filters.size() == accept_extensions.size()) ==
accept_descriptions.size());
if (MissingMimeTypeData(accept_filters, accept_extensions)) {
// Wait for the 2nd call that provides MIME type data.
return false;
}
OnFileDialogParams params;
params.browser = browser;
@@ -173,6 +189,8 @@ bool ClientDialogHandlerGtk::OnFileDialog(
params.title = title;
params.default_file_path = default_file_path;
params.accept_filters = accept_filters;
params.accept_extensions = accept_extensions;
params.accept_descriptions = accept_descriptions;
params.callback = callback;
GetWindowAndContinue(
@@ -309,7 +327,9 @@ void ClientDialogHandlerGtk::OnFileDialogContinue(
}
std::vector<GtkFileFilter*> filters;
AddFilters(GTK_FILE_CHOOSER(dialog), params.accept_filters, true, &filters);
AddFilters(GTK_FILE_CHOOSER(dialog), params.accept_filters,
params.accept_extensions, params.accept_descriptions, true,
&filters);
bool success = false;

View File

@@ -25,6 +25,8 @@ class ClientDialogHandlerGtk : public CefDialogHandler,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
CefRefPtr<CefFileDialogCallback> callback) override;
// CefJSDialogHandler methods.
@@ -48,6 +50,8 @@ class ClientDialogHandlerGtk : public CefDialogHandler,
CefString title;
CefString default_file_path;
std::vector<CefString> accept_filters;
std::vector<CefString> accept_extensions;
std::vector<CefString> accept_descriptions;
CefRefPtr<CefFileDialogCallback> callback;
};
void OnFileDialogContinue(const OnFileDialogParams& params,

View File

@@ -140,16 +140,11 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
if (accept_filters.empty() &&
dialog_state_->mode_ != FILE_DIALOG_OPEN_FOLDER) {
// Build filters based on mime time.
accept_filters.push_back("text/*");
accept_filters.push_back("image/*");
// Build filters based on file extension.
accept_filters.push_back(".log");
accept_filters.push_back(".patch");
// Add specific filters as-is.
accept_filters.push_back("Document Files|.doc;.odt");
accept_filters.push_back("Image Files|.png;.jpg;.gif");
accept_filters.push_back("PDF Files|.pdf");
}
dialog_state_->pending_ = true;

View File

@@ -147,8 +147,9 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
SanityCheckWindowConfig(is_devtools, use_views, use_alloy_style, with_osr);
if (!temp_window_) {
// TempWindow must be created on the UI thread.
if (!temp_window_ && !use_views) {
// TempWindow must be created on the UI thread. It is only used with
// native (non-Views) parent windows.
temp_window_.reset(new TempWindow());
}
@@ -246,11 +247,11 @@ CefRefPtr<CefRequestContext> RootWindowManager::CreateRequestContext(
if (request_context_per_browser_) {
// Synchronous use of non-global request contexts is not safe with the
// Chrome runtime.
CHECK(!callback.is_null()
#if !defined(DISABLE_ALLOY_BOOTSTRAP)
|| !MainContext::Get()->UseChromeBootstrap()
#if defined(DISABLE_ALLOY_BOOTSTRAP)
CHECK(!callback.is_null());
#else
CHECK(!callback.is_null() || !MainContext::Get()->UseChromeBootstrap());
#endif
);
// Create a new request context for each browser.
CefRequestContextSettings settings;

View File

@@ -29,7 +29,7 @@ class TempWindowMacImpl {
}
~TempWindowMacImpl() {
DCHECK(window_);
[window_ close];
window_ = nil;
}
private:

View File

@@ -19,15 +19,22 @@ class DialogTestHandler : public TestHandler {
: mode(dialog_mode),
title("Test Title"),
default_file_name("Test File Name") {
accept_types.push_back("text/*");
accept_types.push_back(".js");
accept_types.push_back(".css");
accept_filters.push_back("image/*");
// We're handling the dialog before MIME type expansion.
accept_extensions.push_back(CefString());
accept_filters.push_back(".js");
accept_extensions.push_back(".js");
accept_filters.push_back(".css");
accept_extensions.push_back(".css");
}
FileDialogMode mode;
CefString title;
CefString default_file_name;
std::vector<CefString> accept_types;
std::vector<CefString> accept_filters;
std::vector<CefString> accept_extensions;
bool skip_first_callback = false;
// True if the callback should execute asynchronously.
bool callback_async = false;
@@ -76,9 +83,9 @@ class DialogTestHandler : public TestHandler {
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) override {
browser->GetHost()->RunFileDialog(config_.mode, config_.title,
config_.default_file_name,
config_.accept_types, new Callback(this));
browser->GetHost()->RunFileDialog(
config_.mode, config_.title, config_.default_file_name,
config_.accept_filters, new Callback(this));
}
void ExecuteCallback(CefRefPtr<CefFileDialogCallback> callback) {
@@ -94,18 +101,58 @@ class DialogTestHandler : public TestHandler {
FileDialogMode mode,
const CefString& title,
const CefString& default_file_name,
const std::vector<CefString>& accept_types,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
CefRefPtr<CefFileDialogCallback> callback) override {
got_onfiledialog_.yes();
got_onfiledialog_ct_++;
std::string url = browser->GetMainFrame()->GetURL();
EXPECT_STREQ(kTestUrl, url.c_str());
EXPECT_EQ(config_.mode, mode);
EXPECT_STREQ(config_.title.ToString().c_str(), title.ToString().c_str());
EXPECT_STREQ(config_.default_file_name.ToString().c_str(),
default_file_name.ToString().c_str());
TestStringVectorEqual(config_.accept_types, accept_types);
EXPECT_EQ(accept_filters.size(), accept_extensions.size());
EXPECT_EQ(accept_filters.size(), accept_descriptions.size());
TestStringVectorEqual(config_.accept_filters, accept_filters);
if (got_onfiledialog_ct_ == 1U) {
// On the 2nd+ call this will be set to the last opened path value
// (possibly leftover from a different test).
EXPECT_STREQ(config_.default_file_name.ToString().c_str(),
default_file_name.ToString().c_str());
TestStringVectorEqual(config_.accept_extensions, accept_extensions);
// All descriptions should be empty.
for (auto& desc : accept_descriptions) {
EXPECT_TRUE(desc.empty());
}
if (config_.skip_first_callback) {
return false;
}
} else if (got_onfiledialog_ct_ == 2U) {
// All MIME types should be resolved to file extensions.
// A description should be provided for MIME types only.
for (size_t i = 0; i < accept_filters.size(); ++i) {
const std::string filter = accept_filters[i];
const std::string ext = accept_extensions[i];
const std::string desc = accept_descriptions[i];
if (filter == "image/*") {
EXPECT_TRUE(ext.find(".png") > 0);
EXPECT_TRUE(ext.find(".jpg") > 0);
EXPECT_FALSE(desc.empty());
} else {
// Single file extensions should match.
EXPECT_STREQ(filter.data(), ext.data());
EXPECT_TRUE(desc.empty());
}
}
} else {
NOTREACHED();
}
if (config_.callback_async) {
CefPostTask(TID_UI, base::BindOnce(&DialogTestHandler::ExecuteCallback,
@@ -118,15 +165,19 @@ class DialogTestHandler : public TestHandler {
}
void DestroyTest() override {
EXPECT_TRUE(got_onfiledialog_);
if (config_.skip_first_callback) {
EXPECT_EQ(2U, got_onfiledialog_ct_);
} else {
EXPECT_EQ(1U, got_onfiledialog_ct_);
}
EXPECT_TRUE(got_onfiledialogdismissed_);
TestHandler::DestroyTest();
}
TestConfig config_;
const TestConfig& config_;
TrackCallback got_onfiledialog_;
size_t got_onfiledialog_ct_ = 0;
TrackCallback got_onfiledialogdismissed_;
IMPLEMENT_REFCOUNTING(DialogTestHandler);
@@ -139,7 +190,8 @@ TEST(DialogTest, FileEmptyParams) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.title.clear();
config.default_file_name.clear();
config.accept_types.clear();
config.accept_filters.clear();
config.accept_extensions.clear();
config.callback_async = false;
config.callback_cancel = false;
@@ -159,6 +211,18 @@ TEST(DialogTest, FileOpen) {
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenSkipFirstCallback) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.callback_async = false;
config.callback_cancel = false;
config.callback_paths.push_back("/path/to/file1.txt");
config.skip_first_callback = true;
CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenCancel) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.callback_async = false;
@@ -169,6 +233,17 @@ TEST(DialogTest, FileOpenCancel) {
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenCancelSkipFirstCallback) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.callback_async = false;
config.callback_cancel = true;
config.skip_first_callback = true;
CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenAsync) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.callback_async = true;
@@ -180,9 +255,21 @@ TEST(DialogTest, FileOpenAsync) {
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenAsyncSkipFirstCallback) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.callback_async = true;
config.callback_cancel = false;
config.callback_paths.push_back("/path/to/file1.txt");
config.skip_first_callback = true;
CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenAsyncCancel) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.callback_async = false;
config.callback_async = true;
config.callback_cancel = true;
CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
@@ -190,6 +277,17 @@ TEST(DialogTest, FileOpenAsyncCancel) {
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenAsyncCancelSkipFirstCallback) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
config.callback_async = true;
config.callback_cancel = true;
config.skip_first_callback = true;
CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
TEST(DialogTest, FileOpenMultiple) {
DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_MULTIPLE);
config.callback_async = false;

View File

@@ -278,7 +278,7 @@ TEST(LifeSpanTest, DoCloseAllowWithOnUnloadForce) {
EXPECT_TRUE(handler->got_after_created_);
EXPECT_TRUE(handler->got_do_close_);
EXPECT_TRUE(handler->got_before_close_);
EXPECT_FALSE(handler->got_before_unload_dialog_);
EXPECT_TRUE(handler->got_before_unload_dialog_);
EXPECT_TRUE(handler->got_unload_message_);
EXPECT_TRUE(handler->got_load_end_);
EXPECT_FALSE(handler->got_delay_close_);
@@ -297,7 +297,7 @@ TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadForce) {
EXPECT_TRUE(handler->got_after_created_);
EXPECT_TRUE(handler->got_do_close_);
EXPECT_FALSE(handler->got_before_close_);
EXPECT_FALSE(handler->got_before_unload_dialog_);
EXPECT_TRUE(handler->got_before_unload_dialog_);
EXPECT_TRUE(handler->got_unload_message_);
EXPECT_TRUE(handler->got_load_end_);
EXPECT_TRUE(handler->got_delay_close_);

View File

@@ -277,6 +277,9 @@ void TestProcessMessageEqual(CefRefPtr<CefProcessMessage> val1,
void TestStringVectorEqual(const std::vector<CefString>& val1,
const std::vector<CefString>& val2) {
EXPECT_EQ(val1.size(), val2.size());
if (val1.size() != val2.size()) {
return;
}
for (size_t i = 0; i < val1.size(); ++i) {
EXPECT_STREQ(val1[i].ToString().c_str(), val2[i].ToString().c_str());

View File

@@ -15,6 +15,7 @@
#include "include/cef_task.h"
#include "include/cef_urlrequest.h"
#include "include/cef_waitable_event.h"
#include "include/test/cef_test_helpers.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_scoped_temp_dir.h"
#include "tests/ceftests/test_handler.h"
@@ -473,8 +474,15 @@ void VerifyNormalRequest(const RequestRunSettings* settings,
// CEF_SETTINGS_ACCEPT_LANGUAGE value from CefSettings.accept_language_list
// set in CefTestSuite::GetSettings() and expanded internally by
// ComputeAcceptLanguageFromPref.
EXPECT_STREQ("en-GB,en;q=0.9",
GetHeaderValue(headerMap, "accept-language").c_str());
const std::string& accept_language =
GetHeaderValue(headerMap, "accept-language");
if (CefIsFeatureEnabledForTests("ReduceAcceptLanguage")) {
EXPECT_TRUE(accept_language == "en-GB" ||
accept_language == "en-GB,en;q=0.9")
<< accept_language;
} else {
EXPECT_STREQ("en-GB,en;q=0.9", accept_language.data());
}
if (server_backend) {
EXPECT_FALSE(GetHeaderValue(headerMap, "accept-encoding").empty());

View File

@@ -5,6 +5,8 @@
#include "tests/shared/common/string_util.h"
#include <algorithm>
#include <iostream>
#include <sstream>
namespace client {
@@ -31,4 +33,16 @@ std::string AsciiStrReplace(const std::string& str,
return result;
}
std::vector<std::string> AsciiStrSplit(const std::string& str, char delim) {
std::vector<std::string> result;
std::stringstream ss(str);
std::string item;
while (getline(ss, item, delim)) {
result.push_back(item);
}
return result;
}
} // namespace client

View File

@@ -7,6 +7,7 @@
#pragma once
#include <string>
#include <vector>
namespace client {
@@ -18,6 +19,9 @@ std::string AsciiStrReplace(const std::string& str,
const std::string& from,
const std::string& to);
// Split |str| at character |delim|.
std::vector<std::string> AsciiStrSplit(const std::string& str, char delim);
} // namespace client
#endif // CEF_TESTS_SHARED_COMMON_STRING_UTIL_H_

View File

@@ -461,6 +461,7 @@ def check_pattern_matches(output_file=None):
# Don't continue when we know the build will be wrong.
sys.exit(1)
def invalid_options_combination(a, b):
print("Invalid combination of options: '%s' and '%s'" % (a, b))
parser.print_help(sys.stderr)
@@ -767,6 +768,18 @@ parser.add_option(
dest='sandboxdistribonly',
default=False,
help='Create a cef_sandbox static library distribution only.')
parser.add_option(
'--tools-distrib',
action='store_true',
dest='toolsdistrib',
default=False,
help='Create a tools distribution.')
parser.add_option(
'--tools-distrib-only',
action='store_true',
dest='toolsdistribonly',
default=False,
help='Create a tools distribution only.')
parser.add_option(
'--no-distrib-docs',
action='store_true',
@@ -814,22 +827,22 @@ if options.runtests:
options.buildtests = True
if (options.nochromiumupdate and options.forceupdate):
invalid_options_combination('--no-chromium-update', '--force-update')
invalid_options_combination('--no-chromium-update', '--force-update')
if (options.nocefupdate and options.forceupdate):
invalid_options_combination('--no-cef-update', '--force-update')
invalid_options_combination('--no-cef-update', '--force-update')
if (options.nobuild and options.forcebuild):
invalid_options_combination('--no-build', '--force-build')
invalid_options_combination('--no-build', '--force-build')
if (options.nodistrib and options.forcedistrib):
invalid_options_combination('--no-distrib', '--force-distrib')
invalid_options_combination('--no-distrib', '--force-distrib')
if (options.forceclean and options.fastupdate):
invalid_options_combination('--force-clean', '--fast-update')
invalid_options_combination('--force-clean', '--fast-update')
if (options.forcecleandeps and options.fastupdate):
invalid_options_combination('--force-clean-deps', '--fast-update')
invalid_options_combination('--force-clean-deps', '--fast-update')
if (options.noreleasebuild and \
(options.minimaldistrib or options.minimaldistribonly or \
options.clientdistrib or options.clientdistribonly)) or \
(options.minimaldistribonly + options.clientdistribonly + options.sandboxdistribonly > 1):
(options.minimaldistribonly + options.clientdistribonly + options.sandboxdistribonly + options.toolsdistribonly > 1):
print('Invalid combination of options.')
parser.print_help(sys.stderr)
sys.exit(1)
@@ -1450,6 +1463,8 @@ if not options.nodistrib and (chromium_checkout_changed or \
distrib_types.append('client')
elif options.sandboxdistribonly:
distrib_types.append('sandbox')
elif options.toolsdistribonly:
distrib_types.append('tools')
else:
distrib_types.append('standard')
if options.minimaldistrib:
@@ -1458,6 +1473,8 @@ if not options.nodistrib and (chromium_checkout_changed or \
distrib_types.append('client')
if options.sandboxdistrib:
distrib_types.append('sandbox')
if options.toolsdistrib:
distrib_types.append('tools')
cef_tools_dir = os.path.join(cef_src_dir, 'tools')
@@ -1482,6 +1499,8 @@ if not options.nodistrib and (chromium_checkout_changed or \
path += ' --client'
elif type == 'sandbox':
path += ' --sandbox'
elif type == 'tools':
path += ' --tools'
if first_type:
if options.nodistribdocs:

View File

@@ -0,0 +1,58 @@
CONTENTS
--------
Debug Contains the Debug build of tools.
Release Contains the Release build of tools.
IMPORTANT NOTE
--------------
CEF/Chromium builds are created using the following host architectures:
- Linux: x86-64 (Intel/AMD)
- Windows: x86-64 (Intel/AMD)
- MacOS: ARM64 (Apple Silicon)
Binaries in this tools package must be run on the supported host OS/architecture
even in cases where the output targets a different architecture.
For example, files targeting a MacOS 64-bit (Intel) application must be created
on a MacOS ARM64 (Apple Silicon) host system using the MacOS 64-bit (Intel)
tools distribution.
USAGE
-----
Start with the required host system and the tools distribution that matches your
application's target OS/architecture and CEF version.
Custom V8 Snapshots
Custom startup snapshots [https://v8.dev/blog/custom-startup-snapshots] can be
used to speed up V8/JavaScript load time in the renderer process. With CEF this
works as follows:
1. Generate a single JavaScript file that contains custom startup data. For
example, using https://github.com/atom/electron-link.
2. Execute the `run_mksnapshot` script to create a `v8_context_snapshot.bin`
file containing the custom data in addition to the default V8 data.
Example:
% run_mksnapshot Release /path/to/snapshot.js
Note that bin file names include an architecture component on MacOS
(e.g. `v8_context_snapshot.[arm64|x86_64].bin`)
3. Replace the existing `v8_context_snapshot.bin` file in the installation
folder or app bundle.
4. Run the application and verify in DevTools that the custom startup data
exists. For example, electron-link adds a global `snapshotResult` object.
Please visit the CEF Website for additional usage information.
https://bitbucket.org/chromiumembedded/cef/

View File

@@ -0,0 +1,66 @@
@echo off
:: Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
:: reserved. Use of this source code is governed by a BSD-style license
:: that can be found in the LICENSE file.
set RC=
setlocal
if not "%1" == "Debug" (
if not "%1" == "Release" (
echo Usage: run_mksnapshot.bat [Debug^|Release] path\to\snapshot.js
set ERRORLEVEL=1
goto end
)
)
set SCRIPT_DIR=%~dp0
set BIN_DIR=%SCRIPT_DIR%%~1
if not exist "%BIN_DIR%" (
echo %BIN_DIR% directory not found
set ERRORLEVEL=1
goto end
)
set CMD_FILE=mksnapshot_cmd.txt
if not exist "%BIN_DIR%\%CMD_FILE%" (
echo %BIN_DIR%\%CMD_FILE% file not found
set ERRORLEVEL=1
goto end
)
cd "%BIN_DIR%"
:: Read %CMD_FILE% into a local variable.
set /p CMDLINE=<%CMD_FILE%
:: Generate snapshot_blob.bin.
echo Running mksnapshot...
call mksnapshot %CMDLINE% %2
set OUT_FILE=v8_context_snapshot.bin
:: Generate v8_context_snapshot.bin.
echo Running v8_context_snapshot_generator...
call v8_context_snapshot_generator --output_file=%OUT_FILE%
if not exist "%BIN_DIR%\%OUT_FILE%" (
echo Failed
set ERRORLEVEL=1
goto end
)
echo Success! Created %BIN_DIR%\%OUT_FILE%
:end
endlocal & set RC=%ERRORLEVEL%
goto omega
:returncode
exit /B %RC%
:omega
call :returncode %RC%

View File

@@ -0,0 +1,68 @@
#!/bin/bash
# Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
# reserved. Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file.
if [ "$1" != "Debug" ] && [ "$1" != "Release" ]; then
echo 'Usage: run_mksnapshot.sh [Debug|Release] /path/to/snapshot.js'
exit 1
fi
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
BIN_DIR=$SCRIPT_DIR/$1
if [ ! -d "$BIN_DIR" ]; then
echo "$BIN_DIR directory not found."
exit 1
fi
CMD_FILE=mksnapshot_cmd.txt
if [ ! -f "$BIN_DIR/$CMD_FILE" ]; then
echo "$BIN_DIR/$CMD_FILE file not found."
exit 1
fi
pushd "$BIN_DIR" > /dev/null
# Read $CMD_FILE into an argument array.
IFS=' ' read -r -a args < $CMD_FILE
if [ "$(uname)" == "Darwin" ]; then
# Execution of tools binaries downloaded on MacOS may be blocked
# by Apple Security settings with a message like "<binary> can't
# be opened because Apple cannot check it for malicious software."
# Remove that block here.
xattr -c ./mksnapshot
xattr -c ./v8_context_snapshot_generator
fi
# Generate snapshot_blob.bin.
echo 'Running mksnapshot...'
./mksnapshot "${args[@]}" "${@:2}"
# Determine the architecture suffix, if any.
suffix=''
if [ "$(uname)" == "Darwin" ]; then
value='--target_arch=arm64'
if [[ " ${args[*]} " =~ [[:space:]]${value}[[:space:]] ]]; then
suffix='.arm64'
else
suffix='.x86_64'
fi
fi
OUT_FILE=v8_context_snapshot${suffix}.bin
# Generate v8_context_snapshot.bin.
echo 'Running v8_context_snapshot_generator...'
./v8_context_snapshot_generator --output_file=$OUT_FILE
popd > /dev/null
if [ -f "$BIN_DIR/$OUT_FILE" ]; then
echo "Success! Created $BIN_DIR/$OUT_FILE"
else
echo "Failed"
exit 1
fi

View File

@@ -64,7 +64,7 @@ def MakeFile(output, input):
segments += MakeFileSegment(file)
# Extract the unique names of all defines.
p = re.compile('#define\s([A-Za-z0-9_]{1,})\s')
p = re.compile(r'#define\s([A-Za-z0-9_]{1,})\s')
all_defines = sorted(set(p.findall(segments)))
undefines = "\n".join(["#undef %s" % define for define in all_defines])

View File

@@ -320,11 +320,6 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
result += '\n'
result_len = len(result)
if is_cef_shutdown:
result += '\n\n#if DCHECK_IS_ON()'\
'\n shutdown_checker::SetIsShutdown();'\
'\n#endif\n'
# execution
result += '\n // Execute\n '
@@ -355,6 +350,11 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
result += ');\n'
if is_cef_shutdown:
result += '\n\n#if DCHECK_IS_ON()'\
'\n shutdown_checker::SetIsShutdown();'\
'\n#endif\n'
result_len = len(result)
# parameter restoration

View File

@@ -335,11 +335,6 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
result += '\n'
result_len = len(result)
if is_cef_shutdown:
result += '\n\n#if DCHECK_IS_ON()'\
'\n shutdown_checker::SetIsShutdown();'\
'\n#endif\n'
# execution
result += '\n // Execute\n '
@@ -369,6 +364,11 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
result += ');\n'
if is_cef_shutdown:
result += '\n\n#if DCHECK_IS_ON()'\
'\n shutdown_checker::SetIsShutdown();'\
'\n#endif\n'
result_len = len(result)
# parameter restoration

View File

@@ -122,7 +122,7 @@ def create_readme():
# format the file
data = header_data + '\n\n' + mode_data
if mode != 'sandbox':
if mode != 'sandbox' and mode != 'tools':
data += '\n\n' + redistrib_data
data += '\n\n' + footer_data
data = data.replace('$CEF_URL$', cef_url)
@@ -165,6 +165,9 @@ def create_readme():
distrib_type = 'Sandbox'
distrib_desc = 'This distribution contains only the cef_sandbox static library. Please see\n' \
'the LICENSING section of this document for licensing terms and conditions.'
elif mode == 'tools':
distrib_type = 'Tools'
distrib_desc = 'This distribution contains additional tools for building CEF-based applications.'
data = data.replace('$DISTRIB_TYPE$', distrib_type)
data = data.replace('$DISTRIB_DESC$', distrib_desc)
@@ -232,6 +235,128 @@ def transfer_gypi_files(src_dir, gypi_paths, gypi_path_prefix, dst_dir, quiet):
copy_file(src, dst, quiet)
def extract_toolchain_cmd(build_dir,
exe_name,
require_toolchain,
require_cmd=True):
""" Extract a toolchain command from the ninja configuration file. """
toolchain_ninja = os.path.join(build_dir, 'toolchain.ninja')
if not os.path.isfile(toolchain_ninja):
if not require_toolchain:
return None, None
raise Exception('Missing file: %s' % toolchain_ninja)
data = read_file(toolchain_ninja)
cmd = None
path = None
# Looking for a value like:
# command = python3 ../../v8/tools/run.py ./exe_name --arg1 --arg2
# OR (for cross-compile):
# command = python3 ../../v8/tools/run.py ./clang_arch1_arch2/exe_name --arg1 --arg2
findstr = '/%s ' % exe_name
start = data.find(findstr)
if start >= 0:
# Extract the command-line arguments.
after_start = start + len(findstr)
end = data.find('\n', after_start)
if end >= after_start:
cmd = data[after_start:end].strip()
print('%s command:' % exe_name, cmd)
if cmd != '' and not re.match(r"^[0-9a-zA-Z\_\- ./=]{1,}$", cmd):
cmd = None
# Extract the relative file path.
dot = start - 1
while data[dot].isalnum() or data[dot] == '_':
dot -= 1
path = data[dot + 1:start]
print('%s path:' % exe_name, path)
if path != '' and not re.match(r"^(win_)?clang_[0-9a-z_]{1,}$", path):
path = None
if require_cmd and (cmd is None or path is None):
raise Exception('Failed to extract %s command from %s' % (exe_name,
toolchain_ninja))
return cmd, path
def get_exe_name(exe_name):
return exe_name + ('.exe' if platform == 'windows' else '')
def get_script_name(script_name):
return script_name + ('.bat' if platform == 'windows' else '.sh')
def transfer_tools_files(script_dir, build_dirs, output_dir):
for build_dir in build_dirs:
is_debug = build_dir.find('Debug') >= 0
dst_dir_name = 'Debug' if is_debug else 'Release'
dst_dir = os.path.join(output_dir, dst_dir_name)
# Retrieve the binary path and command-line arguments.
# See issue #3734 for the expected format.
mksnapshot_name = 'mksnapshot'
tool_cmd, tool_dir = extract_toolchain_cmd(
build_dir, mksnapshot_name, require_toolchain=not options.allowpartial)
if tool_cmd is None:
sys.stdout.write("No %s build toolchain for %s.\n" % (dst_dir_name,
mksnapshot_name))
continue
if options.allowpartial and not path_exists(
os.path.join(build_dir, tool_dir, get_exe_name(mksnapshot_name))):
sys.stdout.write("No %s build of %s.\n" % (dst_dir_name, mksnapshot_name))
continue
# yapf: disable
binaries = [
{'path': get_exe_name(mksnapshot_name)},
{'path': get_exe_name('v8_context_snapshot_generator')},
]
# yapf: disable
# Transfer binaries.
copy_files_list(os.path.join(build_dir, tool_dir), dst_dir, binaries)
# Evaluate command-line arguments and remove relative paths. Copy any input files
# into the distribution.
# - Example input path : ../../v8/tools/builtins-pgo/profiles/x64-rl.profile
# - Example output path: gen/v8/embedded.S
parsed_cmd = []
for cmd in tool_cmd.split(' '):
if cmd.find('/') > 0:
file_name = os.path.split(cmd)[1]
if len(file_name) == 0:
raise Exception('Failed to parse %s command component: %s' % (mksnapshot_name, cmd))
if cmd.startswith('../../'):
file_path = os.path.realpath(os.path.join(build_dir, cmd))
# Validate input file/path.
if not file_path.startswith(src_dir):
raise Exception('Invalid %s command input file: %s' % (mksnapshot_name, file_path))
if not os.path.isfile(file_path):
raise Exception('Missing %s command input file: %s' % (mksnapshot_name, file_path))
# Transfer input file.
copy_file(file_path, os.path.join(dst_dir, file_name), options.quiet)
cmd = file_name
parsed_cmd.append(cmd)
# Write command-line arguments file.
write_file(os.path.join(dst_dir, 'mksnapshot_cmd.txt'), ' '.join(parsed_cmd))
# yapf: disable
files = [
{'path': get_script_name('run_mksnapshot')},
]
# yapf: disable
# Transfer other tools files.
copy_files_list(os.path.join(script_dir, 'distrib', 'tools'), output_dir, files)
def normalize_headers(file, new_path=''):
""" Normalize headers post-processing. Remove the path component from any
project include directives. """
@@ -540,6 +665,12 @@ parser.add_option(
dest='sandbox',
default=False,
help='include only the cef_sandbox static library (macOS and Windows only)')
parser.add_option(
'--tools',
action='store_true',
dest='tools',
default=False,
help='include only the tools')
parser.add_option(
'--ozone',
action='store_true',
@@ -597,10 +728,10 @@ if options.ozone and platform != 'linux':
script_dir = os.path.dirname(__file__)
# CEF root directory
cef_dir = os.path.abspath(os.path.join(script_dir, os.pardir))
cef_dir = os.path.realpath(os.path.join(script_dir, os.pardir))
# src directory
src_dir = os.path.abspath(os.path.join(cef_dir, os.pardir))
src_dir = os.path.realpath(os.path.join(cef_dir, os.pardir))
if not git.is_checkout(cef_dir):
raise Exception('Not a valid checkout: %s' % (cef_dir))
@@ -665,6 +796,9 @@ elif options.client:
elif options.sandbox:
mode = 'sandbox'
output_dir_name = output_dir_name + '_sandbox'
elif options.tools:
mode = 'tools'
output_dir_name = output_dir_name + '_tools'
else:
mode = 'standard'
@@ -882,7 +1016,10 @@ if not options.nodocs:
else:
sys.stdout.write("ERROR: No docs generated.\n")
if platform == 'windows':
if mode == 'tools':
transfer_tools_files(script_dir, (build_dir_debug, build_dir_release),
output_dir)
elif platform == 'windows':
libcef_dll = 'libcef.dll'
libcef_dll_lib = '%s.lib' % libcef_dll
libcef_dll_pdb = '%s.pdb' % libcef_dll
@@ -925,7 +1062,6 @@ if platform == 'windows':
'obj\\base\\base.lib',
'obj\\base\\base_static.lib',
'obj\\base\\third_party\\double_conversion\\double_conversion.lib',
'obj\\base\\third_party\\dynamic_annotations\\dynamic_annotations.lib',
'obj\\base\\win\\pe_image.lib',
cef_sandbox_lib,
'obj\\sandbox\\common\\*.obj',