mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fc703fb1e6 | ||
|
b15e34cfa1 | ||
|
fb6b4df1ef | ||
|
307bd4b411 | ||
|
63d0d96b03 | ||
|
43f22da146 | ||
|
6a2150951b | ||
|
e4984ab99d | ||
|
205f769165 | ||
|
947a2e77de | ||
|
3be7c0098f | ||
|
a58aaabcf8 | ||
|
3133d06335 |
@@ -7,5 +7,6 @@
|
||||
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
|
||||
|
||||
{
|
||||
'chromium_checkout': 'refs/tags/123.0.6312.0'
|
||||
'chromium_checkout': 'refs/tags/123.0.6312.124',
|
||||
'depot_tools_checkout': 'cb43b5d82d'
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#define CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_
|
||||
#pragma once
|
||||
|
||||
#include <memory.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "include/internal/cef_string_types.h"
|
||||
|
@@ -31,7 +31,8 @@ class CefOverlayControllerImpl : public CefOverlayController {
|
||||
}
|
||||
|
||||
bool IsSame(CefRefPtr<CefOverlayController> that) override {
|
||||
return that && that->GetContentsView()->IsSame(view_);
|
||||
return IsValid() && that && that->IsValid() &&
|
||||
that->GetContentsView()->IsSame(view_);
|
||||
}
|
||||
|
||||
CefRefPtr<CefView> GetContentsView() override { return view_; }
|
||||
@@ -52,11 +53,17 @@ class CefOverlayControllerImpl : public CefOverlayController {
|
||||
|
||||
void Destroy() override {
|
||||
if (IsValid()) {
|
||||
host_->Destroy();
|
||||
view_ = nullptr;
|
||||
// Results in a call to Destroyed().
|
||||
host_->Close();
|
||||
host_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Destroyed() {
|
||||
DCHECK(view_);
|
||||
view_ = nullptr;
|
||||
}
|
||||
|
||||
void SetBounds(const CefRect& bounds) override {
|
||||
if (IsValid() && host_->docking_mode() == CEF_DOCKING_MODE_CUSTOM) {
|
||||
host_->SetOverlayBounds(
|
||||
@@ -155,7 +162,7 @@ class CefOverlayControllerImpl : public CefOverlayController {
|
||||
bool IsDrawn() override { return IsVisible(); }
|
||||
|
||||
private:
|
||||
CefOverlayViewHost* const host_;
|
||||
CefOverlayViewHost* host_;
|
||||
CefRefPtr<CefView> view_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefOverlayControllerImpl);
|
||||
@@ -180,7 +187,8 @@ void CefOverlayViewHost::Init(views::View* host_view,
|
||||
|
||||
cef_controller_ = new CefOverlayControllerImpl(this, view);
|
||||
|
||||
// Initialize the Widget.
|
||||
// Initialize the Widget. |widget_| will be deleted by the NativeWidget or
|
||||
// when WidgetDelegate::DeleteDelegate() deletes |this|.
|
||||
widget_ = std::make_unique<ThemeCopyingWidget>(window_view_->GetWidget());
|
||||
views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
|
||||
params.delegate = this;
|
||||
@@ -193,15 +201,23 @@ void CefOverlayViewHost::Init(views::View* host_view,
|
||||
: views::Widget::InitParams::Activatable::kNo;
|
||||
widget_->Init(std::move(params));
|
||||
|
||||
view_ = widget_->GetContentsView()->AddChildView(std::move(controls_view));
|
||||
// |widget_| should now be associated with |this|.
|
||||
DCHECK_EQ(widget_.get(), GetWidget());
|
||||
|
||||
// Make the Widget background transparent. The View might still be opaque.
|
||||
if (widget_->GetCompositor()) {
|
||||
widget_->GetCompositor()->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||
}
|
||||
|
||||
host_view_ = host_view;
|
||||
view_util::SetHostView(widget_.get(), host_view);
|
||||
|
||||
// Cause WidgetDelegate::DeleteDelegate() to delete |this| after executing the
|
||||
// registered DeleteDelegate callback.
|
||||
SetOwnedByWidget(true);
|
||||
RegisterDeleteDelegateCallback(
|
||||
base::BindOnce(&CefOverlayViewHost::Cleanup, base::Unretained(this)));
|
||||
|
||||
if (cef::IsChromeRuntimeEnabled()) {
|
||||
// Some attributes associated with a Chrome toolbar are located via the
|
||||
// Widget. See matching logic in BrowserView::AddedToWidget.
|
||||
@@ -213,6 +229,11 @@ void CefOverlayViewHost::Init(views::View* host_view,
|
||||
}
|
||||
}
|
||||
|
||||
// Call AddChildView after the Widget properties have been configured.
|
||||
// Notifications resulting from this call may attempt to access those
|
||||
// properties (OnThemeChanged calling GetHostView, for example).
|
||||
view_ = widget_->GetContentsView()->AddChildView(std::move(controls_view));
|
||||
|
||||
// Set the initial bounds after the View has been added to the Widget.
|
||||
// Otherwise, preferred size won't calculate correctly.
|
||||
gfx::Rect bounds;
|
||||
@@ -236,15 +257,12 @@ void CefOverlayViewHost::Init(views::View* host_view,
|
||||
widget_->Hide();
|
||||
}
|
||||
|
||||
void CefOverlayViewHost::Destroy() {
|
||||
void CefOverlayViewHost::Close() {
|
||||
if (widget_ && !widget_->IsClosed()) {
|
||||
// Remove the child View immediately. It may be reused by the client.
|
||||
auto view = view_util::GetFor(view_, /*find_known_parent=*/false);
|
||||
widget_->GetContentsView()->RemoveChildView(view_);
|
||||
if (view) {
|
||||
view_util::ResumeOwnership(view);
|
||||
}
|
||||
// Remove all references ASAP, before the Widget is destroyed.
|
||||
Cleanup();
|
||||
|
||||
// Eventually calls DeleteDelegate().
|
||||
widget_->Close();
|
||||
}
|
||||
}
|
||||
@@ -330,3 +348,37 @@ gfx::Rect CefOverlayViewHost::ComputeBounds() const {
|
||||
|
||||
return gfx::Rect(x, y, prefsize.width(), prefsize.height());
|
||||
}
|
||||
|
||||
void CefOverlayViewHost::Cleanup() {
|
||||
// This method may be called multiple times. For example, explicitly after the
|
||||
// client calls CefOverlayController::Destroy or implicitly when the host
|
||||
// Widget is being closed or destroyed. In most implicit cases
|
||||
// CefWindowView::WindowClosing will call this before the host Widget is
|
||||
// destroyed, allowing the client to optionally reuse the child View. However,
|
||||
// if CefWindowView::WindowClosing is not called, DeleteDelegate will call
|
||||
// this after the host Widget and all associated Widgets/Views have been
|
||||
// destroyed. In the DeleteDelegate case |widget_| will return nullptr.
|
||||
if (view_ && widget_) {
|
||||
// Remove the child View immediately. It may be reused by the client.
|
||||
auto view = view_util::GetFor(view_, /*find_known_parent=*/false);
|
||||
widget_->GetContentsView()->RemoveChildView(view_);
|
||||
if (view) {
|
||||
view_util::ResumeOwnership(view);
|
||||
}
|
||||
view_->RemoveObserver(this);
|
||||
view_ = nullptr;
|
||||
}
|
||||
|
||||
if (cef_controller_) {
|
||||
CefOverlayControllerImpl* controller_impl =
|
||||
static_cast<CefOverlayControllerImpl*>(cef_controller_.get());
|
||||
controller_impl->Destroyed();
|
||||
cef_controller_ = nullptr;
|
||||
}
|
||||
|
||||
if (window_view_) {
|
||||
window_view_->RemoveOverlayView(this, host_view_);
|
||||
window_view_ = nullptr;
|
||||
host_view_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "include/views/cef_view.h"
|
||||
|
||||
#include "ui/views/view_observer.h"
|
||||
#include "ui/views/widget/unique_widget_ptr.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
class CefWindowView;
|
||||
@@ -34,7 +35,7 @@ class CefOverlayViewHost : public views::WidgetDelegate,
|
||||
// relative to views with layers and views with associated NativeViews.
|
||||
void Init(views::View* host_view, CefRefPtr<CefView> view, bool can_activate);
|
||||
|
||||
void Destroy();
|
||||
void Close();
|
||||
|
||||
void MoveIfNecessary();
|
||||
|
||||
@@ -55,17 +56,22 @@ class CefOverlayViewHost : public views::WidgetDelegate,
|
||||
private:
|
||||
gfx::Rect ComputeBounds() const;
|
||||
|
||||
void Cleanup();
|
||||
|
||||
// The CefWindowView that created us.
|
||||
CefWindowView* const window_view_;
|
||||
CefWindowView* window_view_;
|
||||
|
||||
const cef_docking_mode_t docking_mode_;
|
||||
|
||||
// The host view that the overlay is positioned relative to.
|
||||
views::View* host_view_ = nullptr;
|
||||
|
||||
// Our view, which is responsible for drawing the UI.
|
||||
views::View* view_ = nullptr;
|
||||
|
||||
// The Widget implementation that is created and maintained by the overlay.
|
||||
// It contains |view_|.
|
||||
std::unique_ptr<views::Widget> widget_;
|
||||
views::UniqueWidgetPtr widget_;
|
||||
|
||||
CefRefPtr<CefOverlayController> cef_controller_;
|
||||
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "libcef/browser/views/window_impl.h"
|
||||
#include "libcef/features/runtime.h"
|
||||
|
||||
#include "base/ranges/algorithm.h"
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
@@ -415,8 +416,8 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
|
||||
params.type = views::Widget::InitParams::TYPE_WINDOW;
|
||||
}
|
||||
|
||||
// WidgetDelegate::DeleteDelegate() will delete |this| after executing the
|
||||
// registered callback.
|
||||
// Cause WidgetDelegate::DeleteDelegate() to delete |this| after executing the
|
||||
// registered DeleteDelegate callback.
|
||||
SetOwnedByWidget(true);
|
||||
RegisterDeleteDelegateCallback(
|
||||
base::BindOnce(&CefWindowView::DeleteDelegate, base::Unretained(this)));
|
||||
@@ -602,6 +603,9 @@ CefRefPtr<CefWindow> CefWindowView::GetCefWindow() const {
|
||||
}
|
||||
|
||||
void CefWindowView::DeleteDelegate() {
|
||||
// Any overlays should already be removed.
|
||||
DCHECK(overlay_hosts_.empty());
|
||||
|
||||
// Remove all child Views before deleting the Window so that notifications
|
||||
// resolve correctly.
|
||||
RemoveAllChildViews();
|
||||
@@ -648,6 +652,14 @@ ui::ImageModel CefWindowView::GetWindowAppIcon() {
|
||||
}
|
||||
|
||||
void CefWindowView::WindowClosing() {
|
||||
// Close any overlays now, before the Widget is destroyed.
|
||||
// Use a copy of the array because the original may be modified while
|
||||
// iterating.
|
||||
std::vector<CefOverlayViewHost*> overlay_hosts = overlay_hosts_;
|
||||
for (auto* overlay_host : overlay_hosts) {
|
||||
overlay_host->Close();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
#if BUILDFLAG(IS_OZONE_X11)
|
||||
if (host_widget()) {
|
||||
@@ -663,6 +675,8 @@ void CefWindowView::WindowClosing() {
|
||||
#endif
|
||||
|
||||
window_delegate_->OnWindowClosing();
|
||||
|
||||
views::WidgetDelegateView::WindowClosing();
|
||||
}
|
||||
|
||||
views::View* CefWindowView::GetContentsView() {
|
||||
@@ -756,7 +770,11 @@ void CefWindowView::OnWidgetActivationChanged(views::Widget* widget,
|
||||
|
||||
void CefWindowView::OnWidgetBoundsChanged(views::Widget* widget,
|
||||
const gfx::Rect& new_bounds) {
|
||||
MoveOverlaysIfNecessary();
|
||||
// Size is set to zero when the host Widget is hidden. We don't need to move
|
||||
// overlays in that case.
|
||||
if (!new_bounds.IsEmpty()) {
|
||||
MoveOverlaysIfNecessary();
|
||||
}
|
||||
|
||||
if (cef_delegate()) {
|
||||
cef_delegate()->OnWindowBoundsChanged(
|
||||
@@ -818,10 +836,10 @@ CefRefPtr<CefOverlayController> CefWindowView::AddOverlayView(
|
||||
// Owned by the View hierarchy. Acts as a z-order reference for the overlay.
|
||||
auto overlay_host_view = AddChildView(std::make_unique<views::View>());
|
||||
|
||||
overlay_hosts_.push_back(
|
||||
std::make_unique<CefOverlayViewHost>(this, docking_mode));
|
||||
// Owned by the resulting Widget, after calling Init().
|
||||
auto* overlay_host = new CefOverlayViewHost(this, docking_mode);
|
||||
overlay_hosts_.push_back(overlay_host);
|
||||
|
||||
auto& overlay_host = overlay_hosts_.back();
|
||||
overlay_host->Init(overlay_host_view, view, can_activate);
|
||||
|
||||
return overlay_host->controller();
|
||||
@@ -830,6 +848,18 @@ CefRefPtr<CefOverlayController> CefWindowView::AddOverlayView(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefWindowView::RemoveOverlayView(CefOverlayViewHost* host,
|
||||
views::View* host_view) {
|
||||
DCHECK_EQ(host_view->parent(), this);
|
||||
RemoveChildView(host_view);
|
||||
|
||||
const auto it = base::ranges::find_if(
|
||||
overlay_hosts_,
|
||||
[host](CefOverlayViewHost* current) { return current == host; });
|
||||
DCHECK(it != overlay_hosts_.end());
|
||||
overlay_hosts_.erase(it);
|
||||
}
|
||||
|
||||
void CefWindowView::MoveOverlaysIfNecessary() {
|
||||
if (overlay_hosts_.empty()) {
|
||||
return;
|
||||
|
@@ -109,6 +109,9 @@ class CefWindowView
|
||||
cef_docking_mode_t docking_mode,
|
||||
bool can_activate);
|
||||
|
||||
// Called from CefOverlayViewHost::Cleanup().
|
||||
void RemoveOverlayView(CefOverlayViewHost* host, views::View* host_view);
|
||||
|
||||
// Set/get the draggable regions.
|
||||
void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions);
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
@@ -133,7 +136,7 @@ class CefWindowView
|
||||
views::Widget* host_widget() const;
|
||||
|
||||
private:
|
||||
// Called when removed from the Widget and before |this| is deleted.
|
||||
// Called after Widget teardown starts, before |this| is deleted.
|
||||
void DeleteDelegate();
|
||||
|
||||
void MoveOverlaysIfNecessary();
|
||||
@@ -161,7 +164,7 @@ class CefWindowView
|
||||
std::unique_ptr<WidgetDestructionObserver> host_widget_destruction_observer_;
|
||||
|
||||
// Hosts for overlay widgets.
|
||||
std::vector<std::unique_ptr<CefOverlayViewHost>> overlay_hosts_;
|
||||
std::vector<CefOverlayViewHost*> overlay_hosts_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_WINDOW_VIEW_H_
|
||||
|
@@ -422,7 +422,7 @@ void CefFrameImpl::OnDetached() {
|
||||
browser_->FrameDetached(frame_);
|
||||
frame_ = nullptr;
|
||||
|
||||
OnDisconnect(DisconnectReason::DETACHED);
|
||||
OnDisconnect(DisconnectReason::DETACHED, std::string());
|
||||
|
||||
browser_ = nullptr;
|
||||
|
||||
@@ -511,9 +511,8 @@ void CefFrameImpl::ConnectBrowserFrame(ConnectReason reason) {
|
||||
// connection.
|
||||
browser_frame->FrameAttached(receiver_.BindNewPipeAndPassRemote(),
|
||||
reattached);
|
||||
receiver_.set_disconnect_handler(
|
||||
base::BindOnce(&CefFrameImpl::OnDisconnect, this,
|
||||
DisconnectReason::RENDER_FRAME_DISCONNECT));
|
||||
receiver_.set_disconnect_with_reason_handler(
|
||||
base::BindOnce(&CefFrameImpl::OnRenderFrameDisconnect, this));
|
||||
}
|
||||
|
||||
const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame(
|
||||
@@ -527,9 +526,8 @@ const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame(
|
||||
// Triggers creation of a CefBrowserFrame in the browser process.
|
||||
render_frame->GetBrowserInterfaceBroker()->GetInterface(
|
||||
browser_frame_.BindNewPipeAndPassReceiver());
|
||||
browser_frame_.set_disconnect_handler(
|
||||
base::BindOnce(&CefFrameImpl::OnDisconnect, this,
|
||||
DisconnectReason::BROWSER_FRAME_DISCONNECT));
|
||||
browser_frame_.set_disconnect_with_reason_handler(
|
||||
base::BindOnce(&CefFrameImpl::OnBrowserFrameDisconnect, this));
|
||||
}
|
||||
}
|
||||
return browser_frame_;
|
||||
@@ -537,10 +535,73 @@ const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame(
|
||||
|
||||
void CefFrameImpl::OnBrowserFrameTimeout() {
|
||||
LOG(ERROR) << frame_debug_str_ << " connection timeout";
|
||||
OnDisconnect(DisconnectReason::CONNECT_TIMEOUT);
|
||||
OnDisconnect(DisconnectReason::CONNECT_TIMEOUT, std::string());
|
||||
}
|
||||
|
||||
void CefFrameImpl::OnDisconnect(DisconnectReason reason) {
|
||||
void CefFrameImpl::OnBrowserFrameDisconnect(uint32_t custom_reason,
|
||||
const std::string& description) {
|
||||
OnDisconnect(DisconnectReason::BROWSER_FRAME_DISCONNECT, description);
|
||||
}
|
||||
|
||||
void CefFrameImpl::OnRenderFrameDisconnect(uint32_t custom_reason,
|
||||
const std::string& description) {
|
||||
OnDisconnect(DisconnectReason::RENDER_FRAME_DISCONNECT, description);
|
||||
}
|
||||
|
||||
// static
|
||||
std::string CefFrameImpl::GetDisconnectDebugString(
|
||||
ConnectionState connection_state,
|
||||
bool frame_is_valid,
|
||||
DisconnectReason reason,
|
||||
const std::string& description) {
|
||||
std::string reason_str;
|
||||
switch (reason) {
|
||||
case DisconnectReason::DETACHED:
|
||||
reason_str = "DETACHED";
|
||||
break;
|
||||
case DisconnectReason::BROWSER_FRAME_DETACHED:
|
||||
reason_str = "BROWSER_FRAME_DETACHED";
|
||||
break;
|
||||
case DisconnectReason::CONNECT_TIMEOUT:
|
||||
reason_str = "CONNECT_TIMEOUT";
|
||||
break;
|
||||
case DisconnectReason::RENDER_FRAME_DISCONNECT:
|
||||
reason_str = "RENDER_FRAME_DISCONNECT";
|
||||
break;
|
||||
case DisconnectReason::BROWSER_FRAME_DISCONNECT:
|
||||
reason_str = "BROWSER_FRAME_DISCONNECT";
|
||||
break;
|
||||
};
|
||||
|
||||
std::string state_str;
|
||||
switch (connection_state) {
|
||||
case ConnectionState::DISCONNECTED:
|
||||
state_str = "DISCONNECTED";
|
||||
break;
|
||||
case ConnectionState::CONNECTION_PENDING:
|
||||
state_str = "CONNECTION_PENDING";
|
||||
break;
|
||||
case ConnectionState::CONNECTION_ACKED:
|
||||
state_str = "CONNECTION_ACKED";
|
||||
break;
|
||||
case ConnectionState::RECONNECT_PENDING:
|
||||
state_str = "RECONNECT_PENDING";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!frame_is_valid) {
|
||||
state_str += ", FRAME_INVALID";
|
||||
}
|
||||
|
||||
if (!description.empty()) {
|
||||
state_str += ", " + description;
|
||||
}
|
||||
|
||||
return "(reason=" + reason_str + ", current_state=" + state_str + ")";
|
||||
}
|
||||
|
||||
void CefFrameImpl::OnDisconnect(DisconnectReason reason,
|
||||
const std::string& description) {
|
||||
// Ignore multiple calls in close proximity (which may occur if both
|
||||
// |browser_frame_| and |receiver_| disconnect). |frame_| will be nullptr
|
||||
// when called from/after OnDetached().
|
||||
@@ -549,49 +610,11 @@ void CefFrameImpl::OnDisconnect(DisconnectReason reason) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (VLOG_IS_ON(1)) {
|
||||
std::string reason_str;
|
||||
switch (reason) {
|
||||
case DisconnectReason::DETACHED:
|
||||
reason_str = "DETACHED";
|
||||
break;
|
||||
case DisconnectReason::BROWSER_FRAME_DETACHED:
|
||||
reason_str = "BROWSER_FRAME_DETACHED";
|
||||
break;
|
||||
case DisconnectReason::CONNECT_TIMEOUT:
|
||||
reason_str = "CONNECT_TIMEOUT";
|
||||
break;
|
||||
case DisconnectReason::RENDER_FRAME_DISCONNECT:
|
||||
reason_str = "RENDER_FRAME_DISCONNECT";
|
||||
break;
|
||||
case DisconnectReason::BROWSER_FRAME_DISCONNECT:
|
||||
reason_str = "BROWSER_FRAME_DISCONNECT";
|
||||
break;
|
||||
};
|
||||
|
||||
std::string state_str;
|
||||
switch (browser_connection_state_) {
|
||||
case ConnectionState::DISCONNECTED:
|
||||
state_str = "DISCONNECTED";
|
||||
break;
|
||||
case ConnectionState::CONNECTION_PENDING:
|
||||
state_str = "CONNECTION_PENDING";
|
||||
break;
|
||||
case ConnectionState::CONNECTION_ACKED:
|
||||
state_str = "CONNECTION_ACKED";
|
||||
break;
|
||||
case ConnectionState::RECONNECT_PENDING:
|
||||
state_str = "RECONNECT_PENDING";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!frame_) {
|
||||
state_str += ", FRAME_INVALID";
|
||||
}
|
||||
|
||||
VLOG(1) << frame_debug_str_ << " disconnected (reason=" << reason_str
|
||||
<< ", current_state=" << state_str << ")";
|
||||
}
|
||||
const auto connection_state = browser_connection_state_;
|
||||
const bool frame_is_valid = !!frame_;
|
||||
VLOG(1) << frame_debug_str_ << " disconnected "
|
||||
<< GetDisconnectDebugString(connection_state, frame_is_valid,
|
||||
reason, description);
|
||||
|
||||
browser_frame_.reset();
|
||||
receiver_.reset();
|
||||
@@ -617,7 +640,9 @@ void CefFrameImpl::OnDisconnect(DisconnectReason reason) {
|
||||
ConnectReason::RETRY));
|
||||
} else {
|
||||
// Trigger a crash in official builds.
|
||||
LOG(FATAL) << frame_debug_str_ << " connection retry failed";
|
||||
LOG(FATAL) << frame_debug_str_ << " connection retry failed "
|
||||
<< GetDisconnectDebugString(connection_state, frame_is_valid,
|
||||
reason, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -690,7 +715,7 @@ void CefFrameImpl::FrameAttachedAck() {
|
||||
void CefFrameImpl::FrameDetached() {
|
||||
// Sent from the browser process in response to CefFrameHostImpl::Detach().
|
||||
CHECK_EQ(ConnectionState::CONNECTION_ACKED, browser_connection_state_);
|
||||
OnDisconnect(DisconnectReason::BROWSER_FRAME_DETACHED);
|
||||
OnDisconnect(DisconnectReason::BROWSER_FRAME_DETACHED, std::string());
|
||||
}
|
||||
|
||||
void CefFrameImpl::SendMessage(const std::string& name,
|
||||
|
@@ -116,6 +116,13 @@ class CefFrameImpl
|
||||
// Called if the BrowserFrame connection attempt times out.
|
||||
void OnBrowserFrameTimeout();
|
||||
|
||||
// Called if the BrowserFrame connection is disconnected.
|
||||
void OnBrowserFrameDisconnect(uint32_t custom_reason,
|
||||
const std::string& description);
|
||||
// Called if the RenderFrame connection is disconnected.
|
||||
void OnRenderFrameDisconnect(uint32_t custom_reason,
|
||||
const std::string& description);
|
||||
|
||||
enum class DisconnectReason {
|
||||
DETACHED,
|
||||
BROWSER_FRAME_DETACHED,
|
||||
@@ -127,7 +134,7 @@ class CefFrameImpl
|
||||
// Called if/when a disconnect occurs. This may occur due to frame navigation,
|
||||
// destruction, or insertion into the bfcache (when the browser-side frame
|
||||
// representation is destroyed and closes the connection).
|
||||
void OnDisconnect(DisconnectReason reason);
|
||||
void OnDisconnect(DisconnectReason reason, const std::string& description);
|
||||
|
||||
// Send an action to the remote BrowserFrame. This will queue the action if
|
||||
// the remote frame is not yet attached.
|
||||
@@ -181,6 +188,11 @@ class CefFrameImpl
|
||||
RECONNECT_PENDING,
|
||||
} browser_connection_state_ = ConnectionState::DISCONNECTED;
|
||||
|
||||
static std::string GetDisconnectDebugString(ConnectionState connection_state,
|
||||
bool frame_is_valid,
|
||||
DisconnectReason reason,
|
||||
const std::string& description);
|
||||
|
||||
base::OneShotTimer browser_connect_timer_;
|
||||
|
||||
std::queue<std::pair<std::string, BrowserFrameAction>>
|
||||
|
@@ -6,6 +6,7 @@
|
||||
// Otherwise there will be compile errors in wtf/MathExtras.h.
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -49,6 +50,8 @@
|
||||
namespace {
|
||||
|
||||
static const char kCefTrackObject[] = "Cef::TrackObject";
|
||||
constexpr int32_t kMaxInt32 = std::numeric_limits<int32_t>::max();
|
||||
constexpr uint32_t kMaxInt32AsUint32 = static_cast<uint32_t>(kMaxInt32);
|
||||
|
||||
void MessageListenerCallbackImpl(v8::Handle<v8::Message> message,
|
||||
v8::Handle<v8::Value> data);
|
||||
@@ -1693,12 +1696,13 @@ bool CefV8ValueImpl::IsBool() {
|
||||
|
||||
bool CefV8ValueImpl::IsInt() {
|
||||
CEF_V8_REQUIRE_ISOLATE_RETURN(false);
|
||||
return (type_ == TYPE_INT || type_ == TYPE_UINT);
|
||||
return type_ == TYPE_INT ||
|
||||
(type_ == TYPE_UINT && uint_value_ <= kMaxInt32AsUint32);
|
||||
}
|
||||
|
||||
bool CefV8ValueImpl::IsUInt() {
|
||||
CEF_V8_REQUIRE_ISOLATE_RETURN(false);
|
||||
return (type_ == TYPE_INT || type_ == TYPE_UINT);
|
||||
return type_ == TYPE_UINT || (type_ == TYPE_INT && int_value_ >= 0);
|
||||
}
|
||||
|
||||
bool CefV8ValueImpl::IsDouble() {
|
||||
@@ -1807,17 +1811,23 @@ bool CefV8ValueImpl::GetBoolValue() {
|
||||
|
||||
int32_t CefV8ValueImpl::GetIntValue() {
|
||||
CEF_V8_REQUIRE_ISOLATE_RETURN(0);
|
||||
if (type_ == TYPE_INT || type_ == TYPE_UINT) {
|
||||
if (type_ == TYPE_INT) {
|
||||
return int_value_;
|
||||
}
|
||||
if (type_ == TYPE_UINT && uint_value_ <= kMaxInt32AsUint32) {
|
||||
return static_cast<int32_t>(uint_value_);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t CefV8ValueImpl::GetUIntValue() {
|
||||
CEF_V8_REQUIRE_ISOLATE_RETURN(0);
|
||||
if (type_ == TYPE_INT || type_ == TYPE_UINT) {
|
||||
if (type_ == TYPE_UINT) {
|
||||
return uint_value_;
|
||||
}
|
||||
if (type_ == TYPE_INT && int_value_ >= 0) {
|
||||
return static_cast<uint32_t>(int_value_);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git content/browser/child_process_security_policy_impl.cc content/browser/child_process_security_policy_impl.cc
|
||||
index 7517bd98e4f7c..6a49e25d63436 100644
|
||||
index 34a70f8af5d6f..eba2a5b3a620f 100644
|
||||
--- content/browser/child_process_security_policy_impl.cc
|
||||
+++ content/browser/child_process_security_policy_impl.cc
|
||||
@@ -1900,6 +1900,16 @@ bool ChildProcessSecurityPolicyImpl::CanAccessDataForMaybeOpaqueOrigin(
|
||||
@@ -1905,6 +1905,16 @@ bool ChildProcessSecurityPolicyImpl::CanAccessDataForMaybeOpaqueOrigin(
|
||||
// DeclarativeApiTest.PersistRules.
|
||||
if (actual_process_lock.matches_scheme(url::kDataScheme))
|
||||
return true;
|
||||
|
@@ -363,7 +363,7 @@ index 2e973c9e279b0..12b62efb8071f 100644
|
||||
BrowserFrame(const BrowserFrame&) = delete;
|
||||
BrowserFrame& operator=(const BrowserFrame&) = delete;
|
||||
diff --git chrome/browser/ui/views/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
|
||||
index 874b4502f94e2..8c15da46dad67 100644
|
||||
index 114fe04f0cd05..c3c8c1a7970fd 100644
|
||||
--- chrome/browser/ui/views/frame/browser_view.cc
|
||||
+++ chrome/browser/ui/views/frame/browser_view.cc
|
||||
@@ -347,11 +347,10 @@ using content::NativeWebKeyboardEvent;
|
||||
@@ -381,7 +381,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
// UMA histograms that record animation smoothness for tab loading animation.
|
||||
@@ -678,6 +677,14 @@ class BrowserViewLayoutDelegateImpl : public BrowserViewLayoutDelegate {
|
||||
@@ -684,6 +683,14 @@ class BrowserViewLayoutDelegateImpl : public BrowserViewLayoutDelegate {
|
||||
return browser_view_->frame()->GetTopInset() - browser_view_->y();
|
||||
}
|
||||
|
||||
@@ -396,7 +396,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
bool IsToolbarVisible() const override {
|
||||
return browser_view_->IsToolbarVisible();
|
||||
}
|
||||
@@ -829,11 +836,21 @@ class BrowserView::AccessibilityModeObserver : public ui::AXModeObserver {
|
||||
@@ -835,11 +842,21 @@ class BrowserView::AccessibilityModeObserver : public ui::AXModeObserver {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BrowserView, public:
|
||||
|
||||
@@ -419,7 +419,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
// Store the actions so that the access is available for other classes.
|
||||
if (features::IsSidePanelPinningEnabled()) {
|
||||
browser_->SetUserData(BrowserActions::UserDataKey(),
|
||||
@@ -938,8 +955,15 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
|
||||
@@ -944,8 +961,15 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
|
||||
contents_container->SetLayoutManager(std::make_unique<ContentsLayoutManager>(
|
||||
devtools_web_view_, contents_web_view_, watermark_view));
|
||||
|
||||
@@ -437,7 +437,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
|
||||
contents_separator_ =
|
||||
top_container_->AddChildView(std::make_unique<ContentsSeparator>());
|
||||
@@ -1013,7 +1037,9 @@ BrowserView::~BrowserView() {
|
||||
@@ -1019,7 +1043,9 @@ BrowserView::~BrowserView() {
|
||||
|
||||
// All the tabs should have been destroyed already. If we were closed by the
|
||||
// OS with some tabs than the NativeBrowserFrame should have destroyed them.
|
||||
@@ -447,7 +447,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
|
||||
// Stop the animation timer explicitly here to avoid running it in a nested
|
||||
// message loop, which may run by Browser destructor.
|
||||
@@ -1027,12 +1053,14 @@ BrowserView::~BrowserView() {
|
||||
@@ -1033,12 +1059,14 @@ BrowserView::~BrowserView() {
|
||||
// child views and it is an observer for avatar toolbar button if any.
|
||||
autofill_bubble_handler_.reset();
|
||||
|
||||
@@ -462,7 +462,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
|
||||
// The TabStrip attaches a listener to the model. Make sure we shut down the
|
||||
// TabStrip first so that it can cleanly remove the listener.
|
||||
@@ -1050,7 +1078,9 @@ BrowserView::~BrowserView() {
|
||||
@@ -1056,7 +1084,9 @@ BrowserView::~BrowserView() {
|
||||
|
||||
// `SidePanelUI::RemoveSidePanelUIForBrowser()` deletes the
|
||||
// SidePanelCoordinator.
|
||||
@@ -472,7 +472,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -2003,9 +2033,14 @@ void BrowserView::OnExclusiveAccessUserInput() {
|
||||
@@ -2009,9 +2039,14 @@ void BrowserView::OnExclusiveAccessUserInput() {
|
||||
|
||||
bool BrowserView::ShouldHideUIForFullscreen() const {
|
||||
// Immersive mode needs UI for the slide-down top panel.
|
||||
@@ -488,7 +488,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
return frame_->GetFrameView()->ShouldHideTopUIForFullscreen();
|
||||
}
|
||||
|
||||
@@ -3123,7 +3158,8 @@ DownloadShelf* BrowserView::GetDownloadShelf() {
|
||||
@@ -3129,7 +3164,8 @@ DownloadShelf* BrowserView::GetDownloadShelf() {
|
||||
}
|
||||
|
||||
DownloadBubbleUIController* BrowserView::GetDownloadBubbleUIController() {
|
||||
@@ -498,7 +498,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
if (auto* download_button = toolbar_button_provider_->GetDownloadButton())
|
||||
return download_button->bubble_controller();
|
||||
return nullptr;
|
||||
@@ -3678,7 +3714,8 @@ void BrowserView::ReparentTopContainerForEndOfImmersive() {
|
||||
@@ -3684,7 +3720,8 @@ void BrowserView::ReparentTopContainerForEndOfImmersive() {
|
||||
if (top_container()->parent() == this)
|
||||
return;
|
||||
|
||||
@@ -508,7 +508,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
top_container()->DestroyLayer();
|
||||
AddChildViewAt(top_container(), 0);
|
||||
EnsureFocusOrder();
|
||||
@@ -4159,11 +4196,38 @@ void BrowserView::GetAccessiblePanes(std::vector<views::View*>* panes) {
|
||||
@@ -4166,11 +4203,38 @@ void BrowserView::GetAccessiblePanes(std::vector<views::View*>* panes) {
|
||||
bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
||||
gfx::NativeView child,
|
||||
const gfx::Point& location) {
|
||||
@@ -549,7 +549,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
// Draggable regions are defined relative to the web contents.
|
||||
gfx::Point point_in_contents_web_view_coords(location);
|
||||
views::View::ConvertPointToTarget(GetWidget()->GetRootView(),
|
||||
@@ -4172,7 +4236,7 @@ bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
||||
@@ -4179,7 +4243,7 @@ bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
||||
|
||||
// Draggable regions should be ignored for clicks into any browser view's
|
||||
// owned widgets, for example alerts, permission prompts or find bar.
|
||||
@@ -558,7 +558,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
point_in_contents_web_view_coords.x(),
|
||||
point_in_contents_web_view_coords.y()) ||
|
||||
WidgetOwnedByAnchorContainsPoint(point_in_contents_web_view_coords);
|
||||
@@ -4283,8 +4347,10 @@ void BrowserView::Layout(PassKey) {
|
||||
@@ -4290,8 +4354,10 @@ void BrowserView::Layout(PassKey) {
|
||||
|
||||
// TODO(jamescook): Why was this in the middle of layout code?
|
||||
toolbar_->location_bar()->omnibox_view()->SetFocusBehavior(
|
||||
@@ -571,7 +571,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
|
||||
// Some of the situations when the BrowserView is laid out are:
|
||||
// - Enter/exit immersive fullscreen mode.
|
||||
@@ -4350,6 +4416,11 @@ void BrowserView::AddedToWidget() {
|
||||
@@ -4357,6 +4423,11 @@ void BrowserView::AddedToWidget() {
|
||||
SetThemeProfileForWindow(GetNativeWindow(), browser_->profile());
|
||||
#endif
|
||||
|
||||
@@ -583,7 +583,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
toolbar_->Init();
|
||||
|
||||
// TODO(pbos): Investigate whether the side panels should be creatable when
|
||||
@@ -4398,13 +4469,9 @@ void BrowserView::AddedToWidget() {
|
||||
@@ -4405,13 +4476,9 @@ void BrowserView::AddedToWidget() {
|
||||
|
||||
EnsureFocusOrder();
|
||||
|
||||
@@ -599,7 +599,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
using_native_frame_ = frame_->ShouldUseNativeFrame();
|
||||
|
||||
MaybeInitializeWebUITabStrip();
|
||||
@@ -4830,7 +4897,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
|
||||
@@ -4837,7 +4904,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
|
||||
// Undo our anti-jankiness hacks and force a re-layout.
|
||||
in_process_fullscreen_ = false;
|
||||
ToolbarSizeChanged(false);
|
||||
@@ -609,7 +609,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
}
|
||||
|
||||
bool BrowserView::ShouldUseImmersiveFullscreenForUrl(const GURL& url) const {
|
||||
@@ -5241,6 +5309,8 @@ Profile* BrowserView::GetProfile() {
|
||||
@@ -5248,6 +5316,8 @@ Profile* BrowserView::GetProfile() {
|
||||
}
|
||||
|
||||
void BrowserView::UpdateUIForTabFullscreen() {
|
||||
@@ -618,7 +618,7 @@ index 874b4502f94e2..8c15da46dad67 100644
|
||||
frame()->GetFrameView()->UpdateFullscreenTopUI();
|
||||
}
|
||||
|
||||
@@ -5263,6 +5333,8 @@ void BrowserView::HideDownloadShelf() {
|
||||
@@ -5270,6 +5340,8 @@ void BrowserView::HideDownloadShelf() {
|
||||
}
|
||||
|
||||
bool BrowserView::CanUserExitFullscreen() const {
|
||||
@@ -941,7 +941,7 @@ index e864e22e920c8..0b82bf831be8f 100644
|
||||
}
|
||||
|
||||
diff --git chrome/browser/ui/views/toolbar/toolbar_view.cc chrome/browser/ui/views/toolbar/toolbar_view.cc
|
||||
index 8ee63a3430928..5a296e7dfe09c 100644
|
||||
index 8ee63a3430928..bb0f09b960677 100644
|
||||
--- chrome/browser/ui/views/toolbar/toolbar_view.cc
|
||||
+++ chrome/browser/ui/views/toolbar/toolbar_view.cc
|
||||
@@ -191,7 +191,7 @@ class TabstripLikeBackground : public views::Background {
|
||||
@@ -1035,6 +1035,15 @@ index 8ee63a3430928..5a296e7dfe09c 100644
|
||||
if (companion::IsCompanionFeatureEnabled()) {
|
||||
side_panel_container_ = container_view_->AddChildView(
|
||||
std::make_unique<SidePanelToolbarContainer>(browser_view_));
|
||||
@@ -811,7 +828,7 @@ void ToolbarView::Layout(PassKey) {
|
||||
if (display_mode_ == DisplayMode::NORMAL) {
|
||||
LayoutCommon();
|
||||
|
||||
- if (features::IsChromeRefresh2023()) {
|
||||
+ if (features::IsChromeRefresh2023() && !browser_->toolbar_overridden()) {
|
||||
UpdateClipPath();
|
||||
}
|
||||
}
|
||||
diff --git chrome/browser/ui/views/toolbar/toolbar_view.h chrome/browser/ui/views/toolbar/toolbar_view.h
|
||||
index 53f8ff18e0119..05d005f026d33 100644
|
||||
--- chrome/browser/ui/views/toolbar/toolbar_view.h
|
||||
|
@@ -39,10 +39,10 @@ index 6e7e22ee886fa..97d0184ceae99 100644
|
||||
factory = std::move(factory_builder).Finish(std::move(loader_factory));
|
||||
} else {
|
||||
diff --git content/public/browser/content_browser_client.cc content/public/browser/content_browser_client.cc
|
||||
index 737dcbdee639d..1344e564a9d1f 100644
|
||||
index 6533ed7f83572..2b7e8791fc7ab 100644
|
||||
--- content/public/browser/content_browser_client.cc
|
||||
+++ content/public/browser/content_browser_client.cc
|
||||
@@ -1071,7 +1071,7 @@ ContentBrowserClient::CreateURLLoaderHandlerForServiceWorkerNavigationPreload(
|
||||
@@ -1075,7 +1075,7 @@ ContentBrowserClient::CreateURLLoaderHandlerForServiceWorkerNavigationPreload(
|
||||
void ContentBrowserClient::OnNetworkServiceCreated(
|
||||
network::mojom::NetworkService* network_service) {}
|
||||
|
||||
@@ -51,7 +51,7 @@ index 737dcbdee639d..1344e564a9d1f 100644
|
||||
BrowserContext* context,
|
||||
bool in_memory,
|
||||
const base::FilePath& relative_partition_path,
|
||||
@@ -1080,6 +1080,7 @@ void ContentBrowserClient::ConfigureNetworkContextParams(
|
||||
@@ -1084,6 +1084,7 @@ void ContentBrowserClient::ConfigureNetworkContextParams(
|
||||
cert_verifier_creation_params) {
|
||||
network_context_params->user_agent = GetUserAgentBasedOnPolicy(context);
|
||||
network_context_params->accept_language = "en-us,en";
|
||||
@@ -60,7 +60,7 @@ index 737dcbdee639d..1344e564a9d1f 100644
|
||||
|
||||
std::vector<base::FilePath>
|
||||
diff --git content/public/browser/content_browser_client.h content/public/browser/content_browser_client.h
|
||||
index 26999a1fa55c7..1c5fbd03212f1 100644
|
||||
index dd7ec4f73bd37..b059c32564b31 100644
|
||||
--- content/public/browser/content_browser_client.h
|
||||
+++ content/public/browser/content_browser_client.h
|
||||
@@ -43,6 +43,7 @@
|
||||
@@ -71,7 +71,7 @@ index 26999a1fa55c7..1c5fbd03212f1 100644
|
||||
#include "content/public/common/alternative_error_page_override_info.mojom-forward.h"
|
||||
#include "content/public/common/page_visibility_state.h"
|
||||
#include "content/public/common/window_container_type.mojom-forward.h"
|
||||
@@ -2018,7 +2019,7 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -2024,7 +2025,7 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
//
|
||||
// If |relative_partition_path| is the empty string, it means this needs to
|
||||
// create the default NetworkContext for the BrowserContext.
|
||||
@@ -80,7 +80,7 @@ index 26999a1fa55c7..1c5fbd03212f1 100644
|
||||
BrowserContext* context,
|
||||
bool in_memory,
|
||||
const base::FilePath& relative_partition_path,
|
||||
@@ -2238,6 +2239,19 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -2244,6 +2245,19 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
RenderFrameHost* initiator_document,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory);
|
||||
|
||||
@@ -100,7 +100,7 @@ index 26999a1fa55c7..1c5fbd03212f1 100644
|
||||
// Creates an OverlayWindow to be used for video or Picture-in-Picture.
|
||||
// This window will house the content shown when in Picture-in-Picture mode.
|
||||
// This will return a new OverlayWindow.
|
||||
@@ -2295,6 +2309,10 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -2301,6 +2315,10 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
// Used as part of the user agent string.
|
||||
virtual std::string GetProduct();
|
||||
|
||||
@@ -150,10 +150,10 @@ index fef1829ebda85..23df06b6c60bb 100644
|
||||
base::BindRepeating(&RenderThreadImpl::OnRendererInterfaceReceiver,
|
||||
base::Unretained(this)));
|
||||
diff --git content/renderer/renderer_blink_platform_impl.cc content/renderer/renderer_blink_platform_impl.cc
|
||||
index 132aca6cb29e9..39374c08425b1 100644
|
||||
index 0ade3663828bd..75d313fc285f7 100644
|
||||
--- content/renderer/renderer_blink_platform_impl.cc
|
||||
+++ content/renderer/renderer_blink_platform_impl.cc
|
||||
@@ -1011,6 +1011,15 @@ SkBitmap* RendererBlinkPlatformImpl::GetSadPageBitmap() {
|
||||
@@ -1003,6 +1003,15 @@ SkBitmap* RendererBlinkPlatformImpl::GetSadPageBitmap() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -170,10 +170,10 @@ index 132aca6cb29e9..39374c08425b1 100644
|
||||
RendererBlinkPlatformImpl::CreateWebV8ValueConverter() {
|
||||
return std::make_unique<V8ValueConverterImpl>();
|
||||
diff --git content/renderer/renderer_blink_platform_impl.h content/renderer/renderer_blink_platform_impl.h
|
||||
index c1b86ec95d41c..8dca87a7201a4 100644
|
||||
index ecbcf12493f77..2c529b2f07a14 100644
|
||||
--- content/renderer/renderer_blink_platform_impl.h
|
||||
+++ content/renderer/renderer_blink_platform_impl.h
|
||||
@@ -237,6 +237,9 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
|
||||
@@ -236,6 +236,9 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
|
||||
InertAndMinimumIntervalOfUserLevelMemoryPressureSignal() override;
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git content/browser/renderer_host/render_process_host_impl.cc content/browser/renderer_host/render_process_host_impl.cc
|
||||
index fd63bad192e9b..262a286478b67 100644
|
||||
index beb0522f59f96..baed58b1fddd3 100644
|
||||
--- content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -1623,7 +1623,8 @@ bool RenderProcessHostImpl::Init() {
|
||||
|
@@ -1,18 +1,18 @@
|
||||
diff --git chrome/common/media/component_widevine_cdm_hint_file_linux.cc chrome/common/media/component_widevine_cdm_hint_file_linux.cc
|
||||
index 60033bb10af50..afb0d23c07a34 100644
|
||||
index d529ecfb270c4..2e922ef345f04 100644
|
||||
--- chrome/common/media/component_widevine_cdm_hint_file_linux.cc
|
||||
+++ chrome/common/media/component_widevine_cdm_hint_file_linux.cc
|
||||
@@ -18,6 +18,7 @@
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "base/path_service.h"
|
||||
#include "base/values.h"
|
||||
#include "base/version.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
+#include "third_party/widevine/cdm/widevine_cdm_common.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -25,12 +26,31 @@ namespace {
|
||||
const char kPath[] = "Path";
|
||||
const char kLastBundledVersion[] = "LastBundledVersion";
|
||||
@@ -35,14 +36,33 @@ base::FilePath GetPath(const base::Value::Dict& dict) {
|
||||
return path;
|
||||
}
|
||||
|
||||
+// On Linux the Widevine CDM is loaded into the zygote at startup. When the
|
||||
+// component updater runs sometime later and finds a newer version of the
|
||||
@@ -34,17 +34,9 @@ index 60033bb10af50..afb0d23c07a34 100644
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
// Returns the hint file contents as a Value::Dict. Returned result may be an
|
||||
// empty dictionary if the hint file does not exist or is formatted incorrectly.
|
||||
base::Value::Dict GetHintFileContents() {
|
||||
base::FilePath hint_file_path;
|
||||
- CHECK(base::PathService::Get(chrome::FILE_COMPONENT_WIDEVINE_CDM_HINT,
|
||||
- &hint_file_path));
|
||||
+ CHECK(GetHintFilePath(&hint_file_path));
|
||||
DVLOG(1) << __func__ << " checking " << hint_file_path;
|
||||
} // namespace
|
||||
|
||||
if (!base::PathExists(hint_file_path)) {
|
||||
@@ -65,8 +85,7 @@ bool UpdateWidevineCdmHintFile(const base::FilePath& cdm_base_path,
|
||||
bool UpdateWidevineCdmHintFile(const base::FilePath& cdm_base_path) {
|
||||
DCHECK(!cdm_base_path.empty());
|
||||
|
||||
base::FilePath hint_file_path;
|
||||
@@ -54,3 +46,13 @@ index 60033bb10af50..afb0d23c07a34 100644
|
||||
|
||||
base::Value::Dict dict;
|
||||
dict.Set(kPath, cdm_base_path.value());
|
||||
@@ -60,8 +80,7 @@ bool UpdateWidevineCdmHintFile(const base::FilePath& cdm_base_path) {
|
||||
|
||||
base::FilePath GetLatestComponentUpdatedWidevineCdmDirectory() {
|
||||
base::FilePath hint_file_path;
|
||||
- CHECK(base::PathService::Get(chrome::FILE_COMPONENT_WIDEVINE_CDM_HINT,
|
||||
- &hint_file_path));
|
||||
+ CHECK(GetHintFilePath(&hint_file_path));
|
||||
|
||||
if (!base::PathExists(hint_file_path)) {
|
||||
DVLOG(2) << "CDM hint file at " << hint_file_path << " does not exist.";
|
||||
|
@@ -13,10 +13,10 @@ index 431df5d50debe..0fcc9ea8fbb1a 100644
|
||||
return nullptr;
|
||||
}
|
||||
diff --git content/browser/renderer_host/render_widget_host_impl.cc content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index d07266a32e786..5a0baf4aa9c6d 100644
|
||||
index 5e4c61925a7ff..4bfdebe9cd5c7 100644
|
||||
--- content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -3313,6 +3313,11 @@ void RenderWidgetHostImpl::OnInvalidInputEventSource() {
|
||||
@@ -3317,6 +3317,11 @@ void RenderWidgetHostImpl::OnInvalidInputEventSource() {
|
||||
GetProcess(), bad_message::INPUT_ROUTER_INVALID_EVENT_SOURCE);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ index d07266a32e786..5a0baf4aa9c6d 100644
|
||||
const WebInputEvent& event) {
|
||||
if ((base::FeatureList::IsEnabled(
|
||||
diff --git content/browser/renderer_host/render_widget_host_impl.h content/browser/renderer_host/render_widget_host_impl.h
|
||||
index 8e48429dbce98..daf8386513031 100644
|
||||
index 7d8224bbb4141..af0fdad6399a3 100644
|
||||
--- content/browser/renderer_host/render_widget_host_impl.h
|
||||
+++ content/browser/renderer_host/render_widget_host_impl.h
|
||||
@@ -811,6 +811,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git content/browser/renderer_host/render_frame_host_impl.cc content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 04988fb23c26a..8d41d7b90f420 100644
|
||||
index 5181caded5641..034c54372fd59 100644
|
||||
--- content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -10351,6 +10351,7 @@ void RenderFrameHostImpl::CommitNavigation(
|
||||
|
@@ -134,7 +134,7 @@ index cbc1a0e7833fe..da451800b1a56 100644
|
||||
friend class test::InkDropHostTestApi;
|
||||
|
||||
diff --git ui/views/controls/button/label_button.cc ui/views/controls/button/label_button.cc
|
||||
index 30555a9c9c2a6..399eabb548184 100644
|
||||
index 1769fd6c47586..a30229e71e818 100644
|
||||
--- ui/views/controls/button/label_button.cc
|
||||
+++ ui/views/controls/button/label_button.cc
|
||||
@@ -578,6 +578,12 @@ void LabelButton::OnThemeChanged() {
|
||||
@@ -670,7 +670,7 @@ diff --git ui/views/controls/menu/menu_runner_impl_cocoa.mm ui/views/controls/me
|
||||
index c585f056973e2..02af08d23a9b9 100644
|
||||
--- ui/views/controls/menu/menu_runner_impl_cocoa.mm
|
||||
+++ ui/views/controls/menu/menu_runner_impl_cocoa.mm
|
||||
@@ -70,6 +70,7 @@
|
||||
@@ -70,6 +70,7 @@ void MenuRunnerImplCocoa::RunMenuAt(
|
||||
MenuAnchorPosition anchor,
|
||||
int32_t run_types,
|
||||
gfx::NativeView native_view_for_gestures,
|
||||
@@ -707,7 +707,7 @@ diff --git ui/views/controls/menu/menu_runner_impl_mac.mm ui/views/controls/menu
|
||||
index 0fb98f56e84c8..1e332dc57b62f 100644
|
||||
--- ui/views/controls/menu/menu_runner_impl_mac.mm
|
||||
+++ ui/views/controls/menu/menu_runner_impl_mac.mm
|
||||
@@ -47,6 +47,7 @@
|
||||
@@ -47,6 +47,7 @@ void MenuRunnerImplMac::RunMenuAt(
|
||||
MenuAnchorPosition anchor,
|
||||
int32_t run_types,
|
||||
gfx::NativeView native_view_for_gestures,
|
||||
@@ -715,7 +715,7 @@ index 0fb98f56e84c8..1e332dc57b62f 100644
|
||||
absl::optional<gfx::RoundedCornersF> corners,
|
||||
absl::optional<std::string> show_menu_host_duration_histogram) {
|
||||
if (!implementation_) {
|
||||
@@ -59,8 +60,8 @@
|
||||
@@ -59,8 +60,8 @@ void MenuRunnerImplMac::RunMenuAt(
|
||||
}
|
||||
}
|
||||
implementation_->RunMenuAt(parent, button_controller, bounds, anchor,
|
||||
@@ -742,7 +742,7 @@ diff --git ui/views/controls/menu/menu_runner_impl_remote_cocoa.mm ui/views/cont
|
||||
index 92e105c78dec5..5a46ea93c5322 100644
|
||||
--- ui/views/controls/menu/menu_runner_impl_remote_cocoa.mm
|
||||
+++ ui/views/controls/menu/menu_runner_impl_remote_cocoa.mm
|
||||
@@ -70,6 +70,7 @@
|
||||
@@ -70,6 +70,7 @@ void MenuRunnerImplRemoteCocoa::RunMenuAt(
|
||||
MenuAnchorPosition anchor,
|
||||
int32_t run_types,
|
||||
gfx::NativeView native_view_for_gestures,
|
||||
@@ -791,7 +791,7 @@ index 9228af7f0b02e..a6957017fef5c 100644
|
||||
#if !BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
if (root_location != root_current_location &&
|
||||
diff --git ui/views/view.h ui/views/view.h
|
||||
index 90905a70c39f1..59e1959efe352 100644
|
||||
index 04ece3c06453f..7d03bcf7e6a5e 100644
|
||||
--- ui/views/view.h
|
||||
+++ ui/views/view.h
|
||||
@@ -25,6 +25,7 @@
|
||||
|
@@ -529,10 +529,10 @@ index cbe655d5879d6..a72c3450d1fa7 100644
|
||||
break;
|
||||
case ui::SHOW_STATE_END:
|
||||
diff --git ui/views/widget/widget.cc ui/views/widget/widget.cc
|
||||
index 257e4c1059db7..9a080524825c7 100644
|
||||
index 0a60563a52cb4..5a2cbcd8aa331 100644
|
||||
--- ui/views/widget/widget.cc
|
||||
+++ ui/views/widget/widget.cc
|
||||
@@ -399,7 +399,8 @@ void Widget::Init(InitParams params) {
|
||||
@@ -400,7 +400,8 @@ void Widget::Init(InitParams params) {
|
||||
}
|
||||
|
||||
params.child |= (params.type == InitParams::TYPE_CONTROL);
|
||||
@@ -542,7 +542,7 @@ index 257e4c1059db7..9a080524825c7 100644
|
||||
is_headless_ = params.ShouldInitAsHeadless();
|
||||
|
||||
if (params.opacity == views::Widget::InitParams::WindowOpacity::kInferred &&
|
||||
@@ -497,9 +498,14 @@ void Widget::Init(InitParams params) {
|
||||
@@ -498,9 +499,14 @@ void Widget::Init(InitParams params) {
|
||||
|
||||
if (show_state == ui::SHOW_STATE_MAXIMIZED) {
|
||||
Maximize();
|
||||
@@ -557,7 +557,7 @@ index 257e4c1059db7..9a080524825c7 100644
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
@@ -513,7 +519,12 @@ void Widget::Init(InitParams params) {
|
||||
@@ -514,7 +520,12 @@ void Widget::Init(InitParams params) {
|
||||
} else if (delegate) {
|
||||
SetContentsView(delegate->TransferOwnershipOfContentsView());
|
||||
if (should_set_initial_bounds) {
|
||||
@@ -571,7 +571,7 @@ index 257e4c1059db7..9a080524825c7 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1655,10 +1666,16 @@ void Widget::OnNativeWidgetParentChanged(gfx::NativeView parent) {
|
||||
@@ -1660,10 +1671,16 @@ void Widget::OnNativeWidgetParentChanged(gfx::NativeView parent) {
|
||||
}
|
||||
|
||||
gfx::Size Widget::GetMinimumSize() const {
|
||||
@@ -588,7 +588,7 @@ index 257e4c1059db7..9a080524825c7 100644
|
||||
return non_client_view_ ? non_client_view_->GetMaximumSize() : gfx::Size();
|
||||
}
|
||||
|
||||
@@ -1909,7 +1926,8 @@ bool Widget::SetInitialFocus(ui::WindowShowState show_state) {
|
||||
@@ -1914,7 +1931,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 ||
|
||||
@@ -599,7 +599,7 @@ index 257e4c1059db7..9a080524825c7 100644
|
||||
// focus when the window is restored.
|
||||
if (v)
|
||||
diff --git ui/views/widget/widget.h ui/views/widget/widget.h
|
||||
index 5d190896a1308..36322410b8373 100644
|
||||
index d47c52cc154ce..97bd67e923168 100644
|
||||
--- ui/views/widget/widget.h
|
||||
+++ ui/views/widget/widget.h
|
||||
@@ -356,6 +356,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git third_party/blink/public/platform/platform.h third_party/blink/public/platform/platform.h
|
||||
index 165bd4eae9e1b..dd4d7af0a561d 100644
|
||||
index 38c079e1f9c37..6a029e131a870 100644
|
||||
--- third_party/blink/public/platform/platform.h
|
||||
+++ third_party/blink/public/platform/platform.h
|
||||
@@ -784,6 +784,11 @@ class BLINK_PLATFORM_EXPORT Platform {
|
||||
@@ -780,6 +780,11 @@ class BLINK_PLATFORM_EXPORT Platform {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -62,7 +62,7 @@ index db7f1cb1b0f68..4c70aa22d0a34 100644
|
||||
gfx::Transform device_emulation_transform_;
|
||||
|
||||
diff --git third_party/blink/renderer/core/page/chrome_client_impl.cc third_party/blink/renderer/core/page/chrome_client_impl.cc
|
||||
index 59f54f7f98dd6..481e1991a77ac 100644
|
||||
index bc0a65ed90b64..f346c3b050fae 100644
|
||||
--- third_party/blink/renderer/core/page/chrome_client_impl.cc
|
||||
+++ third_party/blink/renderer/core/page/chrome_client_impl.cc
|
||||
@@ -981,7 +981,7 @@ PopupMenu* ChromeClientImpl::OpenPopupMenu(LocalFrame& frame,
|
||||
|
@@ -49,7 +49,9 @@ enum V8TestMode {
|
||||
V8TEST_NULL_CREATE,
|
||||
V8TEST_BOOL_CREATE,
|
||||
V8TEST_INT_CREATE,
|
||||
V8TEST_NEGATIVE_INT_CREATE,
|
||||
V8TEST_UINT_CREATE,
|
||||
V8TEST_BIG_UINT_CREATE,
|
||||
V8TEST_DOUBLE_CREATE,
|
||||
V8TEST_DATE_CREATE,
|
||||
V8TEST_STRING_CREATE,
|
||||
@@ -120,9 +122,15 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
||||
case V8TEST_INT_CREATE:
|
||||
RunIntCreateTest();
|
||||
break;
|
||||
case V8TEST_NEGATIVE_INT_CREATE:
|
||||
RunNegativeIntCreateTest();
|
||||
break;
|
||||
case V8TEST_UINT_CREATE:
|
||||
RunUIntCreateTest();
|
||||
break;
|
||||
case V8TEST_BIG_UINT_CREATE:
|
||||
RunBigUIntCreateTest();
|
||||
break;
|
||||
case V8TEST_DOUBLE_CREATE:
|
||||
RunDoubleCreateTest();
|
||||
break;
|
||||
@@ -349,6 +357,29 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunNegativeIntCreateTest() {
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreateInt(-12);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsInt());
|
||||
EXPECT_TRUE(value->IsDouble());
|
||||
EXPECT_EQ(-12, value->GetIntValue());
|
||||
EXPECT_EQ(-12, value->GetDoubleValue());
|
||||
EXPECT_EQ(0u, value->GetUIntValue());
|
||||
|
||||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsUndefined());
|
||||
EXPECT_FALSE(value->IsArray());
|
||||
EXPECT_FALSE(value->IsBool());
|
||||
EXPECT_FALSE(value->IsDate());
|
||||
EXPECT_FALSE(value->IsFunction());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunUIntCreateTest() {
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreateUInt(12);
|
||||
EXPECT_TRUE(value.get());
|
||||
@@ -372,6 +403,30 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunBigUIntCreateTest() {
|
||||
uint32_t big_value = 2147483648u;
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreateUInt(big_value);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsUInt());
|
||||
EXPECT_TRUE(value->IsDouble());
|
||||
EXPECT_EQ(big_value, value->GetUIntValue());
|
||||
EXPECT_EQ(big_value, value->GetDoubleValue());
|
||||
EXPECT_EQ(0, value->GetIntValue());
|
||||
|
||||
EXPECT_FALSE(value->IsInt());
|
||||
EXPECT_FALSE(value->IsUndefined());
|
||||
EXPECT_FALSE(value->IsArray());
|
||||
EXPECT_FALSE(value->IsBool());
|
||||
EXPECT_FALSE(value->IsDate());
|
||||
EXPECT_FALSE(value->IsFunction());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunDoubleCreateTest() {
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreateDouble(12.1223);
|
||||
EXPECT_TRUE(value.get());
|
||||
@@ -3355,7 +3410,9 @@ void CreateV8RendererTests(ClientAppRenderer::DelegateSet& delegates) {
|
||||
V8_TEST(NullCreate, V8TEST_NULL_CREATE)
|
||||
V8_TEST(BoolCreate, V8TEST_BOOL_CREATE)
|
||||
V8_TEST(IntCreate, V8TEST_INT_CREATE)
|
||||
V8_TEST(NegativeIntCreate, V8TEST_NEGATIVE_INT_CREATE)
|
||||
V8_TEST(UIntCreate, V8TEST_UINT_CREATE)
|
||||
V8_TEST(BigUIntCreate, V8TEST_BIG_UINT_CREATE)
|
||||
V8_TEST(DoubleCreate, V8TEST_DOUBLE_CREATE)
|
||||
V8_TEST(DateCreate, V8TEST_DATE_CREATE)
|
||||
V8_TEST(StringCreate, V8TEST_STRING_CREATE)
|
||||
|
@@ -35,7 +35,8 @@ const int TestWindowDelegate::kWSize = 400;
|
||||
|
||||
// static
|
||||
void TestWindowDelegate::RunTest(CefRefPtr<CefWaitableEvent> event,
|
||||
std::unique_ptr<Config> config) {
|
||||
std::unique_ptr<Config> config,
|
||||
TestWindowDelegateFactory factory) {
|
||||
CefSize window_size{config->window_size, config->window_size};
|
||||
|
||||
if (!config->frameless) {
|
||||
@@ -64,8 +65,15 @@ void TestWindowDelegate::RunTest(CefRefPtr<CefWaitableEvent> event,
|
||||
#endif
|
||||
}
|
||||
|
||||
CefWindow::CreateTopLevelWindow(
|
||||
new TestWindowDelegate(event, std::move(config), window_size));
|
||||
TestWindowDelegate* delegate;
|
||||
if (!factory.is_null()) {
|
||||
delegate = std::move(factory).Run(event, std::move(config), window_size);
|
||||
CHECK(delegate);
|
||||
} else {
|
||||
delegate = new TestWindowDelegate(event, std::move(config), window_size);
|
||||
}
|
||||
|
||||
CefWindow::CreateTopLevelWindow(delegate);
|
||||
}
|
||||
|
||||
void TestWindowDelegate::OnWindowCreated(CefRefPtr<CefWindow> window) {
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "include/base/cef_callback.h"
|
||||
#include "include/base/cef_callback_helpers.h"
|
||||
#include "include/base/cef_weak_ptr.h"
|
||||
#include "include/cef_waitable_event.h"
|
||||
#include "include/views/cef_window.h"
|
||||
@@ -41,6 +42,11 @@ class TestWindowDelegate : public CefWindowDelegate {
|
||||
cef_show_state_t initial_show_state = CEF_SHOW_STATE_NORMAL;
|
||||
};
|
||||
|
||||
using TestWindowDelegateFactory =
|
||||
base::OnceCallback<TestWindowDelegate*(CefRefPtr<CefWaitableEvent> event,
|
||||
std::unique_ptr<Config> config,
|
||||
const CefSize& window_size)>;
|
||||
|
||||
// Creates a Window with a new TestWindowDelegate instance and executes
|
||||
// |window_test| after the Window is created. |event| will be signaled once
|
||||
// the Window is closed. If |frameless| is true the Window will be created
|
||||
@@ -48,7 +54,8 @@ class TestWindowDelegate : public CefWindowDelegate {
|
||||
// immediately after |window_test| returns. Otherwise, the caller is
|
||||
// responsible for closing the Window passed to |window_test|.
|
||||
static void RunTest(CefRefPtr<CefWaitableEvent> event,
|
||||
std::unique_ptr<Config> config);
|
||||
std::unique_ptr<Config> config,
|
||||
TestWindowDelegateFactory factory = base::NullCallback());
|
||||
|
||||
// CefWindowDelegate methods:
|
||||
void OnWindowCreated(CefRefPtr<CefWindow> window) override;
|
||||
@@ -63,12 +70,16 @@ class TestWindowDelegate : public CefWindowDelegate {
|
||||
bool OnKeyEvent(CefRefPtr<CefWindow> window,
|
||||
const CefKeyEvent& event) override;
|
||||
|
||||
private:
|
||||
protected:
|
||||
TestWindowDelegate(CefRefPtr<CefWaitableEvent> event,
|
||||
std::unique_ptr<Config> config,
|
||||
const CefSize& window_size);
|
||||
~TestWindowDelegate() override;
|
||||
|
||||
Config* config() const { return config_.get(); }
|
||||
CefRefPtr<CefWindow> window() const { return window_; }
|
||||
|
||||
private:
|
||||
void OnCloseWindow();
|
||||
void OnTimeoutWindow();
|
||||
|
||||
|
@@ -620,3 +620,173 @@ WINDOW_TEST_ASYNC(WindowFullscreenFrameless)
|
||||
WINDOW_TEST_ASYNC(WindowIcon)
|
||||
WINDOW_TEST_ASYNC(WindowIconFrameless)
|
||||
WINDOW_TEST_ASYNC(WindowAccelerator)
|
||||
|
||||
namespace {
|
||||
|
||||
enum class OverlayTestMode {
|
||||
// Destroy the overlay after the Window is destroyed.
|
||||
kDestroyAfterWindowDestroyImplicit,
|
||||
kDestroyAfterWindowDestroyExplicit,
|
||||
|
||||
// Destroy the overlay explicitly before the Window is shown.
|
||||
kDestroyBeforeWindowShow,
|
||||
kDestroyBeforeWindowShowAndAddAgain,
|
||||
|
||||
// Destroy the overlay explicitly after the Window is shown.
|
||||
kDestroyAfterWindowShow,
|
||||
kDestroyAfterWindowShowAndAddAgain,
|
||||
};
|
||||
|
||||
class OverlayTestWindowDelegate : public TestWindowDelegate {
|
||||
public:
|
||||
static TestWindowDelegate* Factory(OverlayTestMode test_mode,
|
||||
CefRefPtr<CefWaitableEvent> event,
|
||||
std::unique_ptr<Config> config,
|
||||
const CefSize& window_size) {
|
||||
return new OverlayTestWindowDelegate(test_mode, event, std::move(config),
|
||||
window_size);
|
||||
}
|
||||
|
||||
private:
|
||||
OverlayTestWindowDelegate(OverlayTestMode test_mode,
|
||||
CefRefPtr<CefWaitableEvent> event,
|
||||
std::unique_ptr<Config> config,
|
||||
const CefSize& window_size)
|
||||
: TestWindowDelegate(event, std::move(config), window_size),
|
||||
test_mode_(test_mode) {
|
||||
this->config()->on_window_created = base::BindOnce(
|
||||
&OverlayTestWindowDelegate::RunWindowCreated, base::Unretained(this));
|
||||
this->config()->on_window_destroyed = base::BindOnce(
|
||||
&OverlayTestWindowDelegate::RunWindowDestroyed, base::Unretained(this));
|
||||
}
|
||||
|
||||
bool DestroyBeforeShow() const {
|
||||
return test_mode_ == OverlayTestMode::kDestroyBeforeWindowShow ||
|
||||
test_mode_ == OverlayTestMode::kDestroyBeforeWindowShowAndAddAgain;
|
||||
}
|
||||
|
||||
bool DestroyAfterShow() const {
|
||||
return test_mode_ == OverlayTestMode::kDestroyAfterWindowShow ||
|
||||
test_mode_ == OverlayTestMode::kDestroyAfterWindowShowAndAddAgain;
|
||||
}
|
||||
|
||||
bool AddAgain() const {
|
||||
return test_mode_ == OverlayTestMode::kDestroyBeforeWindowShowAndAddAgain ||
|
||||
test_mode_ == OverlayTestMode::kDestroyAfterWindowShowAndAddAgain;
|
||||
}
|
||||
|
||||
void RunWindowCreated(CefRefPtr<CefWindow> window) {
|
||||
CreateOverlay();
|
||||
|
||||
if (DestroyBeforeShow()) {
|
||||
DestroyOverlay();
|
||||
}
|
||||
|
||||
window->Show();
|
||||
|
||||
if (DestroyAfterShow()) {
|
||||
DestroyOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
void RunWindowDestroyed(CefRefPtr<CefWindow> window) {
|
||||
if (test_mode_ == OverlayTestMode::kDestroyAfterWindowDestroyExplicit) {
|
||||
DestroyOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
void CreateOverlay() {
|
||||
// |view_| may be reused.
|
||||
if (!view_) {
|
||||
view_ = CefPanel::CreatePanel(nullptr);
|
||||
}
|
||||
|
||||
// View is visible but not drawn.
|
||||
EXPECT_EQ(nullptr, view_->GetWindow());
|
||||
EXPECT_TRUE(view_->IsVisible());
|
||||
EXPECT_FALSE(view_->IsDrawn());
|
||||
|
||||
EXPECT_FALSE(controller_);
|
||||
controller_ = window()->AddOverlayView(view_, CEF_DOCKING_MODE_TOP_LEFT,
|
||||
/*can_activate=*/false);
|
||||
|
||||
// View is visible/drawn (because it belongs to the controller), but the
|
||||
// controller itself is not.
|
||||
EXPECT_FALSE(controller_->IsVisible());
|
||||
EXPECT_FALSE(controller_->IsDrawn());
|
||||
EXPECT_TRUE(window()->IsSame(view_->GetWindow()));
|
||||
EXPECT_TRUE(view_->IsVisible());
|
||||
EXPECT_TRUE(view_->IsDrawn());
|
||||
|
||||
controller_->SetVisible(true);
|
||||
|
||||
EXPECT_TRUE(controller_->IsValid());
|
||||
EXPECT_TRUE(controller_->GetContentsView()->IsSame(view_));
|
||||
EXPECT_TRUE(controller_->GetWindow()->IsSame(window()));
|
||||
EXPECT_EQ(CEF_DOCKING_MODE_TOP_LEFT, controller_->GetDockingMode());
|
||||
|
||||
// Controller is visible/drawn if the host window is drawn.
|
||||
if (window()->IsDrawn()) {
|
||||
EXPECT_TRUE(controller_->IsVisible());
|
||||
EXPECT_TRUE(controller_->IsDrawn());
|
||||
} else {
|
||||
EXPECT_FALSE(controller_->IsVisible());
|
||||
EXPECT_FALSE(controller_->IsDrawn());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(view_->IsVisible());
|
||||
EXPECT_TRUE(view_->IsDrawn());
|
||||
}
|
||||
|
||||
void DestroyOverlay() {
|
||||
// Disassociates the controller from the view and host window.
|
||||
controller_->Destroy();
|
||||
|
||||
EXPECT_FALSE(controller_->IsValid());
|
||||
EXPECT_EQ(nullptr, controller_->GetContentsView());
|
||||
EXPECT_EQ(nullptr, controller_->GetWindow());
|
||||
EXPECT_FALSE(controller_->IsVisible());
|
||||
EXPECT_FALSE(controller_->IsDrawn());
|
||||
|
||||
// View is still visible but no longer drawn (because it no longer belongs
|
||||
// to the controller).
|
||||
EXPECT_EQ(nullptr, view_->GetWindow());
|
||||
EXPECT_TRUE(view_->IsVisible());
|
||||
EXPECT_FALSE(view_->IsDrawn());
|
||||
|
||||
controller_ = nullptr;
|
||||
|
||||
if (AddAgain()) {
|
||||
CreateOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
OverlayTestMode const test_mode_;
|
||||
CefRefPtr<CefView> view_;
|
||||
CefRefPtr<CefOverlayController> controller_;
|
||||
};
|
||||
|
||||
void WindowOverlay(OverlayTestMode test_mode,
|
||||
CefRefPtr<CefWaitableEvent> event) {
|
||||
auto config = std::make_unique<TestWindowDelegate::Config>();
|
||||
TestWindowDelegate::RunTest(
|
||||
event, std::move(config),
|
||||
base::BindOnce(&OverlayTestWindowDelegate::Factory, test_mode));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#define WINDOW_OVERLAY_TEST(name) \
|
||||
namespace { \
|
||||
void WindowOverlay##name##Impl(CefRefPtr<CefWaitableEvent> event) { \
|
||||
WindowOverlay(OverlayTestMode::k##name, event); \
|
||||
} \
|
||||
} \
|
||||
WINDOW_TEST_ASYNC(WindowOverlay##name)
|
||||
|
||||
WINDOW_OVERLAY_TEST(DestroyAfterWindowDestroyImplicit)
|
||||
WINDOW_OVERLAY_TEST(DestroyAfterWindowDestroyExplicit)
|
||||
WINDOW_OVERLAY_TEST(DestroyBeforeWindowShow)
|
||||
WINDOW_OVERLAY_TEST(DestroyBeforeWindowShowAndAddAgain)
|
||||
WINDOW_OVERLAY_TEST(DestroyAfterWindowShow)
|
||||
WINDOW_OVERLAY_TEST(DestroyAfterWindowShowAndAddAgain)
|
||||
|
@@ -133,11 +133,11 @@ class cef_api_hash:
|
||||
def __parse_objects(self, content):
|
||||
""" Returns array of objects in content file. """
|
||||
objects = []
|
||||
content = re.sub("//.*\n", "", content)
|
||||
content = re.sub(r"//.*\n", "", content)
|
||||
|
||||
# function declarations
|
||||
for m in re.finditer(
|
||||
"\nCEF_EXPORT\s+?.*?\s+?(\w+)\s*?\(.*?\)\s*?;",
|
||||
r"\nCEF_EXPORT\s+?.*?\s+?(\w+)\s*?\(.*?\)\s*?;",
|
||||
content,
|
||||
flags=re.DOTALL):
|
||||
object = {"name": m.group(1), "text": m.group(0).strip()}
|
||||
@@ -145,7 +145,7 @@ class cef_api_hash:
|
||||
|
||||
# structs
|
||||
for m in re.finditer(
|
||||
"\ntypedef\s+?struct\s+?(\w+)\s+?\{.*?\}\s+?(\w+)\s*?;",
|
||||
r"\ntypedef\s+?struct\s+?(\w+)\s+?\{.*?\}\s+?(\w+)\s*?;",
|
||||
content,
|
||||
flags=re.DOTALL):
|
||||
object = {"name": m.group(2), "text": m.group(0).strip()}
|
||||
@@ -153,12 +153,12 @@ class cef_api_hash:
|
||||
|
||||
# enums
|
||||
for m in re.finditer(
|
||||
"\ntypedef\s+?enum\s+?\{.*?\}\s+?(\w+)\s*?;", content, flags=re.DOTALL):
|
||||
r"\ntypedef\s+?enum\s+?\{.*?\}\s+?(\w+)\s*?;", content, flags=re.DOTALL):
|
||||
object = {"name": m.group(1), "text": m.group(0).strip()}
|
||||
objects.append(object)
|
||||
|
||||
# typedefs
|
||||
for m in re.finditer("\ntypedef\s+?.*?\s+(\w+);", content, flags=0):
|
||||
for m in re.finditer(r"\ntypedef\s+?.*?\s+(\w+);", content, flags=0):
|
||||
object = {"name": m.group(1), "text": m.group(0).strip()}
|
||||
objects.append(object)
|
||||
|
||||
@@ -168,7 +168,7 @@ class cef_api_hash:
|
||||
""" Grab defined CEF_STRING_TYPE_xxx """
|
||||
objects = []
|
||||
for m in re.finditer(
|
||||
"\n\s*?#\s*?define\s+?(CEF_STRING_TYPE_\w+)\s+?.*?\n", content,
|
||||
r"\n\s*?#\s*?define\s+?(CEF_STRING_TYPE_\w+)\s+?.*?\n", content,
|
||||
flags=0):
|
||||
object = {
|
||||
"name": m.group(1),
|
||||
@@ -179,8 +179,8 @@ class cef_api_hash:
|
||||
|
||||
def __prepare_text(self, text):
|
||||
text = text.strip()
|
||||
text = re.sub("\s+", " ", text)
|
||||
text = re.sub("\(\s+", "(", text)
|
||||
text = re.sub(r"\s+", " ", text)
|
||||
text = re.sub(r"\(\s+", "(", text)
|
||||
return text
|
||||
|
||||
def __get_final_sig(self, objects, platform):
|
||||
|
@@ -273,7 +273,7 @@ def format_translation_includes(header, body):
|
||||
result += '#include "libcef_dll/template_util.h"\n'
|
||||
|
||||
# identify what CppToC classes are being used
|
||||
p = re.compile('([A-Za-z0-9_]{1,})CppToC')
|
||||
p = re.compile(r'([A-Za-z0-9_]{1,})CppToC')
|
||||
list = sorted(set(p.findall(body)))
|
||||
for item in list:
|
||||
directory = ''
|
||||
@@ -286,7 +286,7 @@ def format_translation_includes(header, body):
|
||||
get_capi_name(item[3:], False)+'_cpptoc.h"\n'
|
||||
|
||||
# identify what CToCpp classes are being used
|
||||
p = re.compile('([A-Za-z0-9_]{1,})CToCpp')
|
||||
p = re.compile(r'([A-Za-z0-9_]{1,})CToCpp')
|
||||
list = sorted(set(p.findall(body)))
|
||||
for item in list:
|
||||
directory = ''
|
||||
@@ -355,21 +355,21 @@ def dict_to_str(dict):
|
||||
|
||||
|
||||
# regex for matching comment-formatted attributes
|
||||
_cre_attrib = '/\*--cef\(([A-Za-z0-9_ ,=:\n]{0,})\)--\*/'
|
||||
_cre_attrib = r'/\*--cef\(([A-Za-z0-9_ ,=:\n]{0,})\)--\*/'
|
||||
# regex for matching class and function names
|
||||
_cre_cfname = '([A-Za-z0-9_]{1,})'
|
||||
_cre_cfname = r'([A-Za-z0-9_]{1,})'
|
||||
# regex for matching class and function names including path separators
|
||||
_cre_cfnameorpath = '([A-Za-z0-9_\/]{1,})'
|
||||
_cre_cfnameorpath = r'([A-Za-z0-9_\/]{1,})'
|
||||
# regex for matching typedef value and name combination
|
||||
_cre_typedef = '([A-Za-z0-9_<>:,\*\&\s]{1,})'
|
||||
_cre_typedef = r'([A-Za-z0-9_<>:,\*\&\s]{1,})'
|
||||
# regex for matching function return value and name combination
|
||||
_cre_func = '([A-Za-z][A-Za-z0-9_<>:,\*\&\s]{1,})'
|
||||
_cre_func = r'([A-Za-z][A-Za-z0-9_<>:,\*\&\s]{1,})'
|
||||
# regex for matching virtual function modifiers + arbitrary whitespace
|
||||
_cre_vfmod = '([\sA-Za-z0-9_]{0,})'
|
||||
_cre_vfmod = r'([\sA-Za-z0-9_]{0,})'
|
||||
# regex for matching arbitrary whitespace
|
||||
_cre_space = '[\s]{1,}'
|
||||
_cre_space = r'[\s]{1,}'
|
||||
# regex for matching optional virtual keyword
|
||||
_cre_virtual = '(?:[\s]{1,}virtual){0,1}'
|
||||
_cre_virtual = r'(?:[\s]{1,}virtual){0,1}'
|
||||
|
||||
# Simple translation types. Format is:
|
||||
# 'cpp_type' : ['capi_type', 'capi_default_value']
|
||||
@@ -437,11 +437,11 @@ def get_function_impls(content, ident, has_impl=True):
|
||||
content = content.replace('NO_SANITIZE("cfi-icall")\n', '')
|
||||
|
||||
# extract the functions
|
||||
find_regex = '\n' + _cre_func + '\((.*?)\)([A-Za-z0-9_\s]{0,})'
|
||||
find_regex = r'\n' + _cre_func + r'\((.*?)\)([A-Za-z0-9_\s]{0,})'
|
||||
if has_impl:
|
||||
find_regex += '\{(.*?)\n\}'
|
||||
find_regex += r'\{(.*?)\n\}'
|
||||
else:
|
||||
find_regex += '(;)'
|
||||
find_regex += r'(;)'
|
||||
p = re.compile(find_regex, re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(content)
|
||||
|
||||
@@ -603,7 +603,7 @@ class obj_header:
|
||||
data = data.replace("> >", ">>")
|
||||
|
||||
# extract global typedefs
|
||||
p = re.compile('\ntypedef' + _cre_space + _cre_typedef + ';',
|
||||
p = re.compile(r'\ntypedef' + _cre_space + _cre_typedef + r';',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(data)
|
||||
if len(list) > 0:
|
||||
@@ -617,7 +617,7 @@ class obj_header:
|
||||
self.typedefs.append(obj_typedef(self, filename, value, alias))
|
||||
|
||||
# extract global functions
|
||||
p = re.compile('\n' + _cre_attrib + '\n' + _cre_func + '\((.*?)\)',
|
||||
p = re.compile(r'\n' + _cre_attrib + r'\n' + _cre_func + r'\((.*?)\)',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(data)
|
||||
if len(list) > 0:
|
||||
@@ -631,17 +631,17 @@ class obj_header:
|
||||
obj_function(self, filename, attrib, retval, argval, comment))
|
||||
|
||||
# extract includes
|
||||
p = re.compile('\n#include \"include/' + _cre_cfnameorpath + '.h')
|
||||
p = re.compile(r'\n#include \"include/' + _cre_cfnameorpath + r'.h')
|
||||
includes = p.findall(data)
|
||||
|
||||
# extract forward declarations
|
||||
p = re.compile('\nclass' + _cre_space + _cre_cfname + ';')
|
||||
p = re.compile(r'\nclass' + _cre_space + _cre_cfname + r';')
|
||||
forward_declares = p.findall(data)
|
||||
|
||||
# extract empty classes
|
||||
p = re.compile('\n' + _cre_attrib + '\nclass' + _cre_space + _cre_cfname +
|
||||
_cre_space + ':' + _cre_space + 'public' + _cre_virtual +
|
||||
_cre_space + _cre_cfname + _cre_space + '{};',
|
||||
p = re.compile(r'\n' + _cre_attrib + r'\nclass' + _cre_space + _cre_cfname +
|
||||
_cre_space + r':' + _cre_space + r'public' + _cre_virtual +
|
||||
_cre_space + _cre_cfname + _cre_space + r'{};',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(data)
|
||||
if len(list) > 0:
|
||||
@@ -663,9 +663,9 @@ class obj_header:
|
||||
data = p.sub('', data)
|
||||
|
||||
# extract classes
|
||||
p = re.compile('\n' + _cre_attrib + '\nclass' + _cre_space + _cre_cfname +
|
||||
_cre_space + ':' + _cre_space + 'public' + _cre_virtual +
|
||||
_cre_space + _cre_cfname + _cre_space + '{(.*?)\n};',
|
||||
p = re.compile(r'\n' + _cre_attrib + r'\nclass' + _cre_space + _cre_cfname +
|
||||
_cre_space + r':' + _cre_space + r'public' + _cre_virtual +
|
||||
_cre_space + _cre_cfname + _cre_space + r'{(.*?)\n};',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(data)
|
||||
if len(list) > 0:
|
||||
@@ -852,7 +852,7 @@ class obj_class:
|
||||
|
||||
# extract typedefs
|
||||
p = re.compile(
|
||||
'\n' + _cre_space + 'typedef' + _cre_space + _cre_typedef + ';',
|
||||
r'\n' + _cre_space + r'typedef' + _cre_space + _cre_typedef + r';',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(body)
|
||||
|
||||
@@ -867,8 +867,8 @@ class obj_class:
|
||||
self.typedefs.append(obj_typedef(self, filename, value, alias))
|
||||
|
||||
# extract static functions
|
||||
p = re.compile('\n' + _cre_space + _cre_attrib + '\n' + _cre_space +
|
||||
'static' + _cre_space + _cre_func + '\((.*?)\)',
|
||||
p = re.compile(r'\n' + _cre_space + _cre_attrib + r'\n' + _cre_space +
|
||||
r'static' + _cre_space + _cre_func + r'\((.*?)\)',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(body)
|
||||
|
||||
@@ -882,8 +882,8 @@ class obj_class:
|
||||
|
||||
# extract virtual functions
|
||||
p = re.compile(
|
||||
'\n' + _cre_space + _cre_attrib + '\n' + _cre_space + 'virtual' +
|
||||
_cre_space + _cre_func + '\((.*?)\)' + _cre_vfmod,
|
||||
r'\n' + _cre_space + _cre_attrib + r'\n' + _cre_space + r'virtual' +
|
||||
_cre_space + _cre_func + r'\((.*?)\)' + _cre_vfmod,
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(body)
|
||||
|
||||
@@ -1766,7 +1766,7 @@ class obj_analysis:
|
||||
return {'result_type': 'structure', 'result_value': value}
|
||||
|
||||
# check for CEF reference pointers
|
||||
p = re.compile('^CefRefPtr<(.*?)>$', re.DOTALL)
|
||||
p = re.compile(r'^CefRefPtr<(.*?)>$', re.DOTALL)
|
||||
list = p.findall(value)
|
||||
if len(list) == 1:
|
||||
return {
|
||||
@@ -1776,7 +1776,7 @@ class obj_analysis:
|
||||
}
|
||||
|
||||
# check for CEF owned pointers
|
||||
p = re.compile('^CefOwnPtr<(.*?)>$', re.DOTALL)
|
||||
p = re.compile(r'^CefOwnPtr<(.*?)>$', re.DOTALL)
|
||||
list = p.findall(value)
|
||||
if len(list) == 1:
|
||||
return {
|
||||
@@ -1786,7 +1786,7 @@ class obj_analysis:
|
||||
}
|
||||
|
||||
# check for CEF raw pointers
|
||||
p = re.compile('^CefRawPtr<(.*?)>$', re.DOTALL)
|
||||
p = re.compile(r'^CefRawPtr<(.*?)>$', re.DOTALL)
|
||||
list = p.findall(value)
|
||||
if len(list) == 1:
|
||||
return {
|
||||
|
@@ -258,11 +258,7 @@ def GetRecommendedDefaultArgs():
|
||||
# https://groups.google.com/a/chromium.org/g/chromium-packagers/c/-2VGexQAK6w/m/5K5ppK9WBAAJ
|
||||
result['use_qt'] = False
|
||||
|
||||
if platform == 'mac':
|
||||
# Disable the allocator shim. Default is True. See issue #3061.
|
||||
result['use_allocator_shim'] = False
|
||||
|
||||
if platform == 'mac' or platform == 'linux':
|
||||
if platform == 'linux':
|
||||
# Use the system allocator instead of PartitionAlloc. Default is True with
|
||||
# the allocator shim enabled. See issues #3061 and #3095.
|
||||
result['use_partition_alloc_as_malloc'] = False
|
||||
|
@@ -34,10 +34,10 @@ def MakeFileSegment(input, all_names):
|
||||
# #define IDR_RESOURCE_NAME 12345
|
||||
# [1] See https://crbug.com/684788#c18
|
||||
|
||||
regex = '#define\s([A-Za-z0-9_]{1,})\s+'
|
||||
regex = r'#define\s([A-Za-z0-9_]{1,})\s+'
|
||||
if contents.find('ui::WhitelistedResource') > 0:
|
||||
regex += '.*<'
|
||||
regex += '([0-9]{1,})'
|
||||
regex += r'.*<'
|
||||
regex += r'([0-9]{1,})'
|
||||
|
||||
# identify the defines in the file
|
||||
p = re.compile(regex)
|
||||
|
Reference in New Issue
Block a user