mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
chrome: Add extension support for Alloy style browsers (see #3681)
This change adds minimal tabs API support for Alloy style browsers. Clicking links in PDF documents now navigate as expected.
This commit is contained in:
4
BUILD.gn
4
BUILD.gn
@ -542,6 +542,8 @@ source_set("libcef_static") {
|
|||||||
"libcef/browser/chrome/chrome_startup_browser_creator.h",
|
"libcef/browser/chrome/chrome_startup_browser_creator.h",
|
||||||
"libcef/browser/chrome/chrome_web_contents_view_delegate_cef.h",
|
"libcef/browser/chrome/chrome_web_contents_view_delegate_cef.h",
|
||||||
"libcef/browser/chrome_crash_reporter_client_stub.cc",
|
"libcef/browser/chrome_crash_reporter_client_stub.cc",
|
||||||
|
"libcef/browser/chrome/extensions/chrome_extension_util.cc",
|
||||||
|
"libcef/browser/chrome/extensions/chrome_extension_util.h",
|
||||||
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.cc",
|
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.cc",
|
||||||
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.h",
|
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.h",
|
||||||
"libcef/browser/chrome/views/browser_platform_delegate_chrome_child_window.cc",
|
"libcef/browser/chrome/views/browser_platform_delegate_chrome_child_window.cc",
|
||||||
@ -930,6 +932,8 @@ source_set("libcef_static") {
|
|||||||
"libcef/features/runtime_checks.h",
|
"libcef/features/runtime_checks.h",
|
||||||
"libcef/renderer/alloy/alloy_content_renderer_client.cc",
|
"libcef/renderer/alloy/alloy_content_renderer_client.cc",
|
||||||
"libcef/renderer/alloy/alloy_content_renderer_client.h",
|
"libcef/renderer/alloy/alloy_content_renderer_client.h",
|
||||||
|
"libcef/renderer/alloy/alloy_render_frame_observer.cc",
|
||||||
|
"libcef/renderer/alloy/alloy_render_frame_observer.h",
|
||||||
"libcef/renderer/alloy/alloy_render_thread_observer.cc",
|
"libcef/renderer/alloy/alloy_render_thread_observer.cc",
|
||||||
"libcef/renderer/alloy/alloy_render_thread_observer.h",
|
"libcef/renderer/alloy/alloy_render_thread_observer.h",
|
||||||
"libcef/renderer/alloy/url_loader_throttle_provider_impl.cc",
|
"libcef/renderer/alloy/url_loader_throttle_provider_impl.cc",
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "chrome/browser/printing/printing_init.h"
|
#include "chrome/browser/printing/printing_init.h"
|
||||||
|
#include "chrome/browser/task_manager/web_contents_tags.h"
|
||||||
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
|
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
|
||||||
|
#include "chrome/browser/ui/tab_helpers.h"
|
||||||
#include "components/find_in_page/find_tab_helper.h"
|
#include "components/find_in_page/find_tab_helper.h"
|
||||||
#include "components/find_in_page/find_types.h"
|
#include "components/find_in_page/find_types.h"
|
||||||
#include "components/javascript_dialogs/tab_modal_dialog_manager.h"
|
#include "components/javascript_dialogs/tab_modal_dialog_manager.h"
|
||||||
@ -31,6 +33,12 @@
|
|||||||
#include "pdf/pdf_features.h"
|
#include "pdf/pdf_features.h"
|
||||||
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
|
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char kAttachedHelpersUserDataKey[] = "CefAttachedHelpers";
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
CefBrowserPlatformDelegateAlloy::CefBrowserPlatformDelegateAlloy()
|
CefBrowserPlatformDelegateAlloy::CefBrowserPlatformDelegateAlloy()
|
||||||
: weak_ptr_factory_(this) {}
|
: weak_ptr_factory_(this) {}
|
||||||
|
|
||||||
@ -99,7 +107,7 @@ void CefBrowserPlatformDelegateAlloy::WebContentsCreated(
|
|||||||
CefBrowserPlatformDelegate::WebContentsCreated(web_contents, owned);
|
CefBrowserPlatformDelegate::WebContentsCreated(web_contents, owned);
|
||||||
|
|
||||||
if (primary_) {
|
if (primary_) {
|
||||||
find_in_page::FindTabHelper::CreateForWebContents(web_contents);
|
AttachHelpers(web_contents);
|
||||||
|
|
||||||
if (owned) {
|
if (owned) {
|
||||||
SetOwnedWebContents(web_contents);
|
SetOwnedWebContents(web_contents);
|
||||||
@ -163,14 +171,7 @@ void CefBrowserPlatformDelegateAlloy::BrowserCreated(
|
|||||||
web_contents_->SetDelegate(
|
web_contents_->SetDelegate(
|
||||||
AlloyBrowserHostImpl::FromBaseChecked(browser).get());
|
AlloyBrowserHostImpl::FromBaseChecked(browser).get());
|
||||||
|
|
||||||
permissions::PermissionRequestManager::CreateForWebContents(web_contents_);
|
AttachHelpers(web_contents_);
|
||||||
PrefsTabHelper::CreateForWebContents(web_contents_);
|
|
||||||
printing::InitializePrintingForWebContents(web_contents_);
|
|
||||||
zoom::ZoomController::CreateForWebContents(web_contents_);
|
|
||||||
|
|
||||||
javascript_dialogs::TabModalDialogManager::CreateForWebContents(
|
|
||||||
web_contents_,
|
|
||||||
CreateAlloyJavaScriptTabModalDialogManagerDelegateDesktop(web_contents_));
|
|
||||||
|
|
||||||
// Used for print preview and JavaScript dialogs.
|
// Used for print preview and JavaScript dialogs.
|
||||||
web_contents_dialog_helper_ =
|
web_contents_dialog_helper_ =
|
||||||
@ -400,3 +401,37 @@ void CefBrowserPlatformDelegateAlloy::OnExtensionHostDeleted() {
|
|||||||
DCHECK(extension_host_);
|
DCHECK(extension_host_);
|
||||||
extension_host_ = nullptr;
|
extension_host_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefBrowserPlatformDelegateAlloy::AttachHelpers(
|
||||||
|
content::WebContents* web_contents) {
|
||||||
|
// If already attached, nothing to be done.
|
||||||
|
base::SupportsUserData::Data* attached_tag =
|
||||||
|
web_contents->GetUserData(&kAttachedHelpersUserDataKey);
|
||||||
|
if (attached_tag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as attached.
|
||||||
|
web_contents->SetUserData(&kAttachedHelpersUserDataKey,
|
||||||
|
std::make_unique<base::SupportsUserData::Data>());
|
||||||
|
|
||||||
|
// Create all the helpers.
|
||||||
|
if (cef::IsAlloyRuntimeEnabled()) {
|
||||||
|
find_in_page::FindTabHelper::CreateForWebContents(web_contents);
|
||||||
|
permissions::PermissionRequestManager::CreateForWebContents(web_contents);
|
||||||
|
PrefsTabHelper::CreateForWebContents(web_contents);
|
||||||
|
printing::InitializePrintingForWebContents(web_contents);
|
||||||
|
zoom::ZoomController::CreateForWebContents(web_contents);
|
||||||
|
|
||||||
|
javascript_dialogs::TabModalDialogManager::CreateForWebContents(
|
||||||
|
web_contents, CreateAlloyJavaScriptTabModalDialogManagerDelegateDesktop(
|
||||||
|
web_contents));
|
||||||
|
} else {
|
||||||
|
// Adopt the WebContents now, so all observers are in place, as the network
|
||||||
|
// requests for its initial navigation will start immediately
|
||||||
|
TabHelpers::AttachTabHelpers(web_contents);
|
||||||
|
|
||||||
|
// Make the tab show up in the task manager.
|
||||||
|
task_manager::WebContentsTags::CreateForTabContents(web_contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -88,6 +88,10 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate {
|
|||||||
|
|
||||||
void ConfigureAutoResize();
|
void ConfigureAutoResize();
|
||||||
|
|
||||||
|
// Attach all the associated helpers that are needed for the WebContents. It
|
||||||
|
// is safe to call this on a WebContents that was already attached.
|
||||||
|
void AttachHelpers(content::WebContents* web_contents);
|
||||||
|
|
||||||
// Non-nullptr if this object owns the WebContents. Will be nullptr for popup
|
// Non-nullptr if this object owns the WebContents. Will be nullptr for popup
|
||||||
// browsers between the calls to WebContentsCreated() and AddNewContents(),
|
// browsers between the calls to WebContentsCreated() and AddNewContents(),
|
||||||
// and may never be set if the parent browser is destroyed during popup
|
// and may never be set if the parent browser is destroyed during popup
|
||||||
|
67
libcef/browser/chrome/extensions/chrome_extension_util.cc
Normal file
67
libcef/browser/chrome/extensions/chrome_extension_util.cc
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 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.
|
||||||
|
|
||||||
|
#include "libcef/browser/chrome/extensions/chrome_extension_util.h"
|
||||||
|
|
||||||
|
#include "libcef/browser/browser_host_base.h"
|
||||||
|
|
||||||
|
#include "chrome/browser/profiles/profile.h"
|
||||||
|
#include "components/sessions/content/session_tab_helper.h"
|
||||||
|
#include "content/public/browser/render_frame_host.h"
|
||||||
|
#include "content/public/browser/render_process_host.h"
|
||||||
|
|
||||||
|
namespace cef {
|
||||||
|
|
||||||
|
bool GetAlloyTabById(int tab_id,
|
||||||
|
Profile* profile,
|
||||||
|
bool include_incognito,
|
||||||
|
content::WebContents** contents) {
|
||||||
|
for (auto rph_iterator = content::RenderProcessHost::AllHostsIterator();
|
||||||
|
!rph_iterator.IsAtEnd(); rph_iterator.Advance()) {
|
||||||
|
content::RenderProcessHost* rph = rph_iterator.GetCurrentValue();
|
||||||
|
|
||||||
|
// Ignore renderers that aren't ready.
|
||||||
|
if (!rph->IsInitializedAndNotDead()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Ignore renderers that aren't from a valid profile. This is either the
|
||||||
|
// same profile or the incognito profile if `include_incognito` is true.
|
||||||
|
Profile* process_profile =
|
||||||
|
Profile::FromBrowserContext(rph->GetBrowserContext());
|
||||||
|
if (process_profile != profile &&
|
||||||
|
!(include_incognito && profile->IsSameOrParent(process_profile))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rph->ForEachRenderFrameHost([&contents,
|
||||||
|
tab_id](content::RenderFrameHost* rfh) {
|
||||||
|
CHECK(rfh);
|
||||||
|
auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
|
||||||
|
CHECK(web_contents);
|
||||||
|
if (sessions::SessionTabHelper::IdForTab(web_contents).id() != tab_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only consider Alloy style CefBrowserHosts in this loop. Otherwise,
|
||||||
|
// we could end up returning a WebContents that shouldn't be exposed to
|
||||||
|
// extensions.
|
||||||
|
auto browser = CefBrowserHostBase::GetBrowserForContents(web_contents);
|
||||||
|
if (!browser || !browser->IsAlloyStyle()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contents) {
|
||||||
|
*contents = web_contents;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (contents && *contents) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cef
|
26
libcef/browser/chrome/extensions/chrome_extension_util.h
Normal file
26
libcef/browser/chrome/extensions/chrome_extension_util.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 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.
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_BROWSER_CHROME_EXTENSIONS_CHROME_EXTENSION_UTIL_H_
|
||||||
|
#define CEF_LIBCEF_BROWSER_CHROME_EXTENSIONS_CHROME_EXTENSION_UTIL_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace content {
|
||||||
|
class WebContents;
|
||||||
|
} // namespace content
|
||||||
|
|
||||||
|
class Profile;
|
||||||
|
|
||||||
|
namespace cef {
|
||||||
|
|
||||||
|
// Same as ExtensionTabUtil::GetTabById but searching only Alloy style
|
||||||
|
// CefBrowserHosts.
|
||||||
|
bool GetAlloyTabById(int tab_id,
|
||||||
|
Profile* profile,
|
||||||
|
bool include_incognito,
|
||||||
|
content::WebContents** contents);
|
||||||
|
|
||||||
|
} // namespace cef
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_BROWSER_CHROME_EXTENSIONS_CHROME_EXTENSION_UTIL_H_
|
@ -97,7 +97,9 @@ void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle,
|
|||||||
std::make_unique<navigation_interception::InterceptNavigationThrottle>(
|
std::make_unique<navigation_interception::InterceptNavigationThrottle>(
|
||||||
navigation_handle, base::BindRepeating(&NavigationOnUIThread),
|
navigation_handle, base::BindRepeating(&NavigationOnUIThread),
|
||||||
navigation_interception::SynchronyMode::kSync);
|
navigation_interception::SynchronyMode::kSync);
|
||||||
throttles.push_back(std::move(throttle));
|
|
||||||
|
// Always execute our throttle first.
|
||||||
|
throttles.emplace(throttles.begin(), std::move(throttle));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace throttle
|
} // namespace throttle
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
#include "libcef/common/extensions/extensions_util.h"
|
#include "libcef/common/extensions/extensions_util.h"
|
||||||
#include "libcef/common/request_impl.h"
|
#include "libcef/common/request_impl.h"
|
||||||
#include "libcef/features/runtime_checks.h"
|
#include "libcef/features/runtime_checks.h"
|
||||||
|
#include "libcef/renderer/alloy/alloy_render_frame_observer.h"
|
||||||
#include "libcef/renderer/alloy/alloy_render_thread_observer.h"
|
#include "libcef/renderer/alloy/alloy_render_thread_observer.h"
|
||||||
#include "libcef/renderer/alloy/url_loader_throttle_provider_impl.h"
|
#include "libcef/renderer/alloy/url_loader_throttle_provider_impl.h"
|
||||||
#include "libcef/renderer/browser_impl.h"
|
#include "libcef/renderer/browser_impl.h"
|
||||||
#include "libcef/renderer/extensions/extensions_renderer_client.h"
|
#include "libcef/renderer/extensions/extensions_renderer_client.h"
|
||||||
#include "libcef/renderer/render_frame_observer.h"
|
|
||||||
#include "libcef/renderer/render_manager.h"
|
#include "libcef/renderer/render_manager.h"
|
||||||
#include "libcef/renderer/thread_util.h"
|
#include "libcef/renderer/thread_util.h"
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ void AlloyContentRendererClient::RenderThreadConnected() {
|
|||||||
|
|
||||||
void AlloyContentRendererClient::RenderFrameCreated(
|
void AlloyContentRendererClient::RenderFrameCreated(
|
||||||
content::RenderFrame* render_frame) {
|
content::RenderFrame* render_frame) {
|
||||||
auto render_frame_observer = new CefRenderFrameObserver(render_frame);
|
auto render_frame_observer = new AlloyRenderFrameObserver(render_frame);
|
||||||
|
|
||||||
if (extensions::ExtensionsEnabled()) {
|
if (extensions::ExtensionsEnabled()) {
|
||||||
extensions_renderer_client_->RenderFrameCreated(
|
extensions_renderer_client_->RenderFrameCreated(
|
||||||
|
21
libcef/renderer/alloy/alloy_render_frame_observer.cc
Normal file
21
libcef/renderer/alloy/alloy_render_frame_observer.cc
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
#include "libcef/renderer/alloy/alloy_render_frame_observer.h"
|
||||||
|
|
||||||
|
AlloyRenderFrameObserver::AlloyRenderFrameObserver(
|
||||||
|
content::RenderFrame* render_frame)
|
||||||
|
: CefRenderFrameObserver(render_frame) {}
|
||||||
|
|
||||||
|
void AlloyRenderFrameObserver::OnInterfaceRequestForFrame(
|
||||||
|
const std::string& interface_name,
|
||||||
|
mojo::ScopedMessagePipeHandle* interface_pipe) {
|
||||||
|
registry_.TryBindInterface(interface_name, interface_pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AlloyRenderFrameObserver::OnAssociatedInterfaceRequestForFrame(
|
||||||
|
const std::string& interface_name,
|
||||||
|
mojo::ScopedInterfaceEndpointHandle* handle) {
|
||||||
|
return associated_interfaces_.TryBindInterface(interface_name, handle);
|
||||||
|
}
|
42
libcef/renderer/alloy/alloy_render_frame_observer.h
Normal file
42
libcef/renderer/alloy/alloy_render_frame_observer.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
#ifndef LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_
|
||||||
|
#define LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_
|
||||||
|
|
||||||
|
#include "libcef/renderer/render_frame_observer.h"
|
||||||
|
|
||||||
|
#include "services/service_manager/public/cpp/binder_registry.h"
|
||||||
|
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
|
||||||
|
|
||||||
|
class AlloyRenderFrameObserver : public CefRenderFrameObserver {
|
||||||
|
public:
|
||||||
|
explicit AlloyRenderFrameObserver(content::RenderFrame* render_frame);
|
||||||
|
|
||||||
|
AlloyRenderFrameObserver(const AlloyRenderFrameObserver&) = delete;
|
||||||
|
AlloyRenderFrameObserver& operator=(const AlloyRenderFrameObserver&) = delete;
|
||||||
|
|
||||||
|
// RenderFrameObserver methods:
|
||||||
|
void OnInterfaceRequestForFrame(
|
||||||
|
const std::string& interface_name,
|
||||||
|
mojo::ScopedMessagePipeHandle* interface_pipe) override;
|
||||||
|
bool OnAssociatedInterfaceRequestForFrame(
|
||||||
|
const std::string& interface_name,
|
||||||
|
mojo::ScopedInterfaceEndpointHandle* handle) override;
|
||||||
|
|
||||||
|
service_manager::BinderRegistry* registry() { return ®istry_; }
|
||||||
|
blink::AssociatedInterfaceRegistry* associated_interfaces() {
|
||||||
|
return &associated_interfaces_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
service_manager::BinderRegistry registry_;
|
||||||
|
|
||||||
|
// For interfaces which must be associated with some IPC::ChannelProxy,
|
||||||
|
// meaning that messages on the interface retain FIFO with respect to legacy
|
||||||
|
// Chrome IPC messages sent or dispatched on the channel.
|
||||||
|
blink::AssociatedInterfaceRegistry associated_interfaces_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LIBCEF_RENDERER_ALLOY_ALLOY_RENDER_FRAME_OBSERVER_H_
|
@ -197,18 +197,6 @@ void CefRenderFrameObserver::OnDestruct() {
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefRenderFrameObserver::OnInterfaceRequestForFrame(
|
|
||||||
const std::string& interface_name,
|
|
||||||
mojo::ScopedMessagePipeHandle* interface_pipe) {
|
|
||||||
registry_.TryBindInterface(interface_name, interface_pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CefRenderFrameObserver::OnAssociatedInterfaceRequestForFrame(
|
|
||||||
const std::string& interface_name,
|
|
||||||
mojo::ScopedInterfaceEndpointHandle* handle) {
|
|
||||||
return associated_interfaces_.TryBindInterface(interface_name, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CefRenderFrameObserver::AttachFrame(CefFrameImpl* frame) {
|
void CefRenderFrameObserver::AttachFrame(CefFrameImpl* frame) {
|
||||||
DCHECK(frame);
|
DCHECK(frame);
|
||||||
DCHECK(!frame_);
|
DCHECK(!frame_);
|
||||||
|
@ -7,14 +7,6 @@
|
|||||||
|
|
||||||
#include "content/public/renderer/render_frame_observer.h"
|
#include "content/public/renderer/render_frame_observer.h"
|
||||||
|
|
||||||
#include "services/service_manager/public/cpp/binder_registry.h"
|
|
||||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
class RenderFrame;
|
|
||||||
class RenderView;
|
|
||||||
} // namespace content
|
|
||||||
|
|
||||||
class CefFrameImpl;
|
class CefFrameImpl;
|
||||||
|
|
||||||
class CefRenderFrameObserver : public content::RenderFrameObserver {
|
class CefRenderFrameObserver : public content::RenderFrameObserver {
|
||||||
@ -38,17 +30,6 @@ class CefRenderFrameObserver : public content::RenderFrameObserver {
|
|||||||
void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
||||||
int world_id) override;
|
int world_id) override;
|
||||||
void OnDestruct() override;
|
void OnDestruct() override;
|
||||||
void OnInterfaceRequestForFrame(
|
|
||||||
const std::string& interface_name,
|
|
||||||
mojo::ScopedMessagePipeHandle* interface_pipe) override;
|
|
||||||
bool OnAssociatedInterfaceRequestForFrame(
|
|
||||||
const std::string& interface_name,
|
|
||||||
mojo::ScopedInterfaceEndpointHandle* handle) override;
|
|
||||||
|
|
||||||
service_manager::BinderRegistry* registry() { return ®istry_; }
|
|
||||||
blink::AssociatedInterfaceRegistry* associated_interfaces() {
|
|
||||||
return &associated_interfaces_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AttachFrame(CefFrameImpl* frame);
|
void AttachFrame(CefFrameImpl* frame);
|
||||||
|
|
||||||
@ -57,13 +38,6 @@ class CefRenderFrameObserver : public content::RenderFrameObserver {
|
|||||||
void OnLoadError();
|
void OnLoadError();
|
||||||
|
|
||||||
CefFrameImpl* frame_ = nullptr;
|
CefFrameImpl* frame_ = nullptr;
|
||||||
|
|
||||||
service_manager::BinderRegistry registry_;
|
|
||||||
|
|
||||||
// For interfaces which must be associated with some IPC::ChannelProxy,
|
|
||||||
// meaning that messages on the interface retain FIFO with respect to legacy
|
|
||||||
// Chrome IPC messages sent or dispatched on the channel.
|
|
||||||
blink::AssociatedInterfaceRegistry associated_interfaces_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIBCEF_RENDERER_RENDER_FRAME_OBSERVER_H_
|
#endif // LIBCEF_RENDERER_RENDER_FRAME_OBSERVER_H_
|
||||||
|
@ -282,6 +282,9 @@ patches = [
|
|||||||
{
|
{
|
||||||
# chrome: Support override of ChromeMimeHandlerViewGuestDelegate.
|
# chrome: Support override of ChromeMimeHandlerViewGuestDelegate.
|
||||||
# https://github.com/chromiumembedded/cef/issues/2969
|
# https://github.com/chromiumembedded/cef/issues/2969
|
||||||
|
#
|
||||||
|
# chrome: Add minimal support for tabs API with Alloy style browsers.
|
||||||
|
# https://github.com/chromiumembedded/cef/issues/3681
|
||||||
'name': 'chrome_browser_extensions',
|
'name': 'chrome_browser_extensions',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -33,3 +33,156 @@ index 4007e26f780c3..5f92d74018f9e 100644
|
|||||||
return std::make_unique<ChromeMimeHandlerViewGuestDelegate>();
|
return std::make_unique<ChromeMimeHandlerViewGuestDelegate>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diff --git chrome/browser/extensions/api/tabs/tabs_api.cc chrome/browser/extensions/api/tabs/tabs_api.cc
|
||||||
|
index 1eab73b209fea..fca0a2318202e 100644
|
||||||
|
--- chrome/browser/extensions/api/tabs/tabs_api.cc
|
||||||
|
+++ chrome/browser/extensions/api/tabs/tabs_api.cc
|
||||||
|
@@ -1550,7 +1550,7 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||||
|
if (DevToolsWindow::IsDevToolsWindow(contents))
|
||||||
|
return RespondNow(Error(tabs_constants::kNotAllowedForDevToolsError));
|
||||||
|
|
||||||
|
- if (!ExtensionTabUtil::BrowserSupportsTabs(browser))
|
||||||
|
+ if (browser && !ExtensionTabUtil::BrowserSupportsTabs(browser))
|
||||||
|
return RespondNow(Error(tabs_constants::kNoCurrentWindowError));
|
||||||
|
|
||||||
|
web_contents_ = contents;
|
||||||
|
@@ -1574,7 +1574,7 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||||
|
return RespondNow(Error(tabs_constants::kTabStripNotEditableError));
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (tab_strip->active_index() != tab_index) {
|
||||||
|
+ if (tab_strip && tab_strip->active_index() != tab_index) {
|
||||||
|
tab_strip->ActivateTabAt(tab_index);
|
||||||
|
DCHECK_EQ(contents, tab_strip->GetActiveWebContents());
|
||||||
|
}
|
||||||
|
@@ -1588,7 +1588,7 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool highlighted = *params->update_properties.highlighted;
|
||||||
|
- if (highlighted != tab_strip->IsTabSelected(tab_index)) {
|
||||||
|
+ if (tab_strip && highlighted != tab_strip->IsTabSelected(tab_index)) {
|
||||||
|
tab_strip->ToggleSelectionAt(tab_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1601,7 +1601,7 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||||
|
base::NumberToString(tab_id))));
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (params->update_properties.opener_tab_id) {
|
||||||
|
+ if (tab_strip && params->update_properties.opener_tab_id) {
|
||||||
|
int opener_id = *params->update_properties.opener_tab_id;
|
||||||
|
WebContents* opener_contents = nullptr;
|
||||||
|
if (opener_id == tab_id) {
|
||||||
|
@@ -1636,11 +1636,11 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool contents_in_an_uneditable_saved_group =
|
||||||
|
- contents && ExtensionTabUtil::TabIsInSavedTabGroup(
|
||||||
|
+ browser && contents && ExtensionTabUtil::TabIsInSavedTabGroup(
|
||||||
|
web_contents_, browser->tab_strip_model()) &&
|
||||||
|
!ExtensionHasLockedFullscreenPermission(extension());
|
||||||
|
|
||||||
|
- if (params->update_properties.pinned) {
|
||||||
|
+ if (tab_strip && params->update_properties.pinned) {
|
||||||
|
// Pinning will result in changes to the tabs index/group affiliation in
|
||||||
|
// some cases, Throw an error if a tab is attempting to be pinned.
|
||||||
|
if (contents_in_an_uneditable_saved_group) {
|
||||||
|
@@ -1671,8 +1671,9 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string updated_url = *params->update_properties.url;
|
||||||
|
- if (browser->profile()->IsIncognitoProfile() &&
|
||||||
|
- !IsURLAllowedInIncognito(GURL(updated_url), browser->profile())) {
|
||||||
|
+ auto* profile = Profile::FromBrowserContext(browser_context());
|
||||||
|
+ if (profile->IsIncognitoProfile() &&
|
||||||
|
+ !IsURLAllowedInIncognito(GURL(updated_url), profile)) {
|
||||||
|
return RespondNow(Error(ErrorUtils::FormatErrorMessage(
|
||||||
|
tabs_constants::kURLsNotAllowedInIncognitoError, updated_url)));
|
||||||
|
}
|
||||||
|
@@ -1686,7 +1687,7 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||||
|
return RespondNow(Error(std::move(error)));
|
||||||
|
}
|
||||||
|
|
||||||
|
- NotifyExtensionTelemetry(Profile::FromBrowserContext(browser_context()),
|
||||||
|
+ NotifyExtensionTelemetry(profile,
|
||||||
|
extension(), safe_browsing::TabsApiInfo::UPDATE,
|
||||||
|
current_url, updated_url);
|
||||||
|
}
|
||||||
|
diff --git chrome/browser/extensions/extension_tab_util.cc chrome/browser/extensions/extension_tab_util.cc
|
||||||
|
index 46154f4501a36..81adec54cee06 100644
|
||||||
|
--- chrome/browser/extensions/extension_tab_util.cc
|
||||||
|
+++ chrome/browser/extensions/extension_tab_util.cc
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include "base/strings/stringprintf.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "base/types/expected_macros.h"
|
||||||
|
+#include "cef/libcef/features/features.h"
|
||||||
|
#include "chrome/browser/browser_process.h"
|
||||||
|
#include "chrome/browser/extensions/api/tab_groups/tab_groups_util.h"
|
||||||
|
#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
|
||||||
|
@@ -73,6 +74,10 @@
|
||||||
|
#include "third_party/blink/public/common/features.h"
|
||||||
|
#include "url/gurl.h"
|
||||||
|
|
||||||
|
+#if BUILDFLAG(ENABLE_CEF)
|
||||||
|
+#include "cef/libcef/browser/chrome/extensions/chrome_extension_util.h"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
using content::NavigationEntry;
|
||||||
|
using content::WebContents;
|
||||||
|
using extensions::mojom::APIPermissionID;
|
||||||
|
@@ -763,6 +768,20 @@ bool ExtensionTabUtil::GetTabById(int tab_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if BUILDFLAG(ENABLE_CEF)
|
||||||
|
+ if (cef::GetAlloyTabById(tab_id, profile, include_incognito, contents)) {
|
||||||
|
+ // |tab_strip| and |tab_index| are tied to a specific Browser window, which
|
||||||
|
+ // doesn't exist for an Alloy style browser.
|
||||||
|
+ if (tab_strip) {
|
||||||
|
+ *tab_strip = nullptr;
|
||||||
|
+ }
|
||||||
|
+ if (tab_index) {
|
||||||
|
+ *tab_index = api::tabs::TAB_INDEX_NONE;
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+#endif // BUILDFLAG(ENABLE_CEF)
|
||||||
|
+
|
||||||
|
if (base::FeatureList::IsEnabled(blink::features::kPrerender2InNewTab)) {
|
||||||
|
// Prerendering tab is not visible and it cannot be in `TabStripModel`, if
|
||||||
|
// the tab id exists as a prerendering tab, and the API will returns
|
||||||
|
diff --git chrome/browser/ui/tab_helpers.h chrome/browser/ui/tab_helpers.h
|
||||||
|
index 2f769363f8519..228c20926634b 100644
|
||||||
|
--- chrome/browser/ui/tab_helpers.h
|
||||||
|
+++ chrome/browser/ui/tab_helpers.h
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
#define CHROME_BROWSER_UI_TAB_HELPERS_H_
|
||||||
|
|
||||||
|
#include "build/build_config.h"
|
||||||
|
+#include "cef/libcef/features/features.h"
|
||||||
|
|
||||||
|
#if BUILDFLAG(IS_ANDROID)
|
||||||
|
|
||||||
|
@@ -37,6 +38,10 @@ namespace prerender {
|
||||||
|
class ChromeNoStatePrefetchContentsDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if BUILDFLAG(ENABLE_CEF)
|
||||||
|
+class CefBrowserPlatformDelegateAlloy;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
// A "tab contents" is a WebContents that is used as a tab in a browser window
|
||||||
|
// (or the equivalent on Android). The TabHelpers class allows specific classes
|
||||||
|
// to attach the set of tab helpers that is used for tab contents.
|
||||||
|
@@ -75,6 +80,10 @@ class TabHelpers {
|
||||||
|
// Link Preview shows a preview of a page, then promote it as a new tab.
|
||||||
|
friend class PreviewTab;
|
||||||
|
|
||||||
|
+#if BUILDFLAG(ENABLE_CEF)
|
||||||
|
+ friend class CefBrowserPlatformDelegateAlloy;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
// FYI: Do NOT add any more friends here. The functions above are the ONLY
|
||||||
|
// ones that need to call AttachTabHelpers; if you think you do, re-read the
|
||||||
|
// design document linked above, especially the section "Reusing tab helpers".
|
||||||
|
@ -437,8 +437,7 @@ class HistoryNavTestHandler : public TestHandler {
|
|||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -927,8 +926,7 @@ class RedirectTestHandler : public TestHandler {
|
|||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -1545,8 +1543,7 @@ class OrderNavTestHandler : public TestHandler {
|
|||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -1990,8 +1987,7 @@ class LoadNavTestHandler : public TestHandler {
|
|||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
|
@ -314,8 +314,7 @@ class RequestSendRecvTestHandler : public TestHandler {
|
|||||||
int64_t received_content_length) override {
|
int64_t received_content_length) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,7 @@ class ResourceManagerTestHandler : public RoutingTestHandler {
|
|||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
|
@ -615,8 +615,7 @@ class BasicResponseTest : public TestHandler {
|
|||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -796,8 +795,7 @@ class BasicResponseTest : public TestHandler {
|
|||||||
int64_t received_content_length) override {
|
int64_t received_content_length) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1682,8 +1680,7 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
|||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -1909,8 +1906,7 @@ class SubresourceResponseTest : public RoutingTestHandler {
|
|||||||
int64_t received_content_length) override {
|
int64_t received_content_length) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3080,7 +3076,7 @@ class RedirectResponseTest : public TestHandler {
|
|||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (IsChromeBootstrap() && request->GetResourceType() == RT_FAVICON) {
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -3188,7 +3184,7 @@ class RedirectResponseTest : public TestHandler {
|
|||||||
int64_t received_content_length) override {
|
int64_t received_content_length) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (IsChromeBootstrap() && request->GetResourceType() == RT_FAVICON) {
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3310,8 +3306,7 @@ class BeforeResourceLoadTest : public TestHandler {
|
|||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -3882,8 +3877,7 @@ class ResponseFilterTestHandler : public TestHandler {
|
|||||||
int64_t received_content_length) override {
|
int64_t received_content_length) override {
|
||||||
EXPECT_IO_THREAD();
|
EXPECT_IO_THREAD();
|
||||||
|
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -118,8 +118,7 @@ class TestSchemeHandler : public TestHandler {
|
|||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefRequest> request,
|
CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
if (!use_alloy_style_browser() &&
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
request->GetResourceType() == RT_FAVICON) {
|
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return RV_CANCEL;
|
return RV_CANCEL;
|
||||||
}
|
}
|
||||||
@ -421,7 +420,7 @@ class ClientSchemeHandler : public CefResourceHandler {
|
|||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
|
||||||
|
|
||||||
if (IsChromeBootstrap() && request->GetResourceType() == RT_FAVICON) {
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -496,7 +495,7 @@ class ClientSchemeHandler : public CefResourceHandler {
|
|||||||
|
|
||||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||||
CefRefPtr<CefCallback> callback) override {
|
CefRefPtr<CefCallback> callback) override {
|
||||||
if (IsChromeBootstrap() && request->GetResourceType() == RT_FAVICON) {
|
if (request->GetResourceType() == RT_FAVICON) {
|
||||||
// Ignore favicon requests.
|
// Ignore favicon requests.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user