Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: mojofy autofill renderer->browser #18760

Merged
merged 5 commits into from Aug 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions filenames.gni
Expand Up @@ -125,6 +125,10 @@ filenames = {
"shell/browser/auto_updater.cc",
"shell/browser/auto_updater.h",
"shell/browser/auto_updater_mac.mm",
"shell/browser/atom_autofill_driver_factory.cc",
"shell/browser/atom_autofill_driver_factory.h",
"shell/browser/atom_autofill_driver.cc",
"shell/browser/atom_autofill_driver.h",
"shell/browser/atom_blob_reader.cc",
"shell/browser/atom_blob_reader.h",
"shell/browser/atom_browser_client.cc",
Expand Down
43 changes: 10 additions & 33 deletions shell/browser/api/atom_api_web_contents.cc
Expand Up @@ -50,6 +50,7 @@
#include "shell/browser/api/atom_api_browser_window.h"
#include "shell/browser/api/atom_api_debugger.h"
#include "shell/browser/api/atom_api_session.h"
#include "shell/browser/atom_autofill_driver_factory.h"
#include "shell/browser/atom_browser_client.h"
#include "shell/browser/atom_browser_context.h"
#include "shell/browser/atom_browser_main_parts.h"
Expand Down Expand Up @@ -471,6 +472,7 @@ void WebContents::InitWithSessionAndOptions(
base::Unretained(this)));
bindings_.set_connection_error_handler(base::BindRepeating(
&WebContents::OnElectronBrowserConnectionError, base::Unretained(this)));
AutofillDriverFactory::CreateForWebContents(web_contents());

web_contents()->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(),
false);
Expand Down Expand Up @@ -626,7 +628,13 @@ void WebContents::SetContentsBounds(content::WebContents* source,

void WebContents::CloseContents(content::WebContents* source) {
Emit("close");
HideAutofillPopup();

auto* autofill_driver_factory =
AutofillDriverFactory::FromWebContents(web_contents());
if (autofill_driver_factory) {
autofill_driver_factory->CloseAllPopups();
}

if (managed_web_contents())
managed_web_contents()->GetView()->SetDelegate(nullptr);
for (ExtendedWebContentsObserver& observer : observers_)
Expand Down Expand Up @@ -1153,26 +1161,6 @@ void WebContents::DevToolsClosed() {
Emit("devtools-closed");
}

void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
bool offscreen = IsOffScreen() || (embedder_ && embedder_->IsOffScreen());
gfx::RectF popup_bounds(bounds);
content::RenderFrameHost* embedder_frame_host = nullptr;
if (embedder_) {
auto* embedder_view = embedder_->web_contents()->GetMainFrame()->GetView();
auto* view = web_contents()->GetMainFrame()->GetView();
auto offset = view->GetViewBounds().origin() -
embedder_view->GetViewBounds().origin();
popup_bounds.Offset(offset.x(), offset.y());
embedder_frame_host = embedder_->web_contents()->GetMainFrame();
}

CommonWebContentsDelegate::ShowAutofillPopup(
frame_host, embedder_frame_host, offscreen, popup_bounds, values, labels);
}

bool WebContents::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
Expand Down Expand Up @@ -2214,17 +2202,6 @@ void WebContents::DoGetZoomLevel(DoGetZoomLevelCallback callback) {
std::move(callback).Run(GetZoomLevel());
}

void WebContents::ShowAutofillPopup(const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
content::RenderFrameHost* frame_host = bindings_.dispatch_context();
ShowAutofillPopup(frame_host, bounds, values, labels);
}

void WebContents::HideAutofillPopup() {
CommonWebContentsDelegate::HideAutofillPopup();
}

std::vector<base::FilePath::StringType> WebContents::GetPreloadPaths() const {
auto result = SessionPreferences::GetValidPreloads(GetBrowserContext());

Expand Down Expand Up @@ -2279,7 +2256,7 @@ v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, session_);
}

content::WebContents* WebContents::HostWebContents() {
content::WebContents* WebContents::HostWebContents() const {
if (!embedder_)
return nullptr;
return embedder_->web_contents();
Expand Down
18 changes: 4 additions & 14 deletions shell/browser/api/atom_api_web_contents.h
Expand Up @@ -14,6 +14,7 @@
#include "base/observer_list_types.h"
#include "content/common/cursors/webcursor.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_binding_set.h"
#include "content/public/browser/web_contents_observer.h"
Expand All @@ -27,7 +28,6 @@
#include "shell/browser/api/save_page_handler.h"
#include "shell/browser/api/trackable_object.h"
#include "shell/browser/common_web_contents_delegate.h"
#include "shell/browser/ui/autofill_popup.h"
#include "ui/gfx/image/image.h"

#if BUILDFLAG(ENABLE_PRINTING)
Expand Down Expand Up @@ -305,7 +305,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Properties.
int32_t ID() const;
v8::Local<v8::Value> Session(v8::Isolate* isolate);
content::WebContents* HostWebContents();
content::WebContents* HostWebContents() const;
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
v8::Local<v8::Value> Debugger(v8::Isolate* isolate);

Expand All @@ -323,6 +323,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
bool EmitNavigationEvent(const std::string& event,
content::NavigationHandle* navigation_handle);

WebContents* embedder() { return embedder_; }

protected:
// Does not manage lifetime of |web_contents|.
WebContents(v8::Isolate* isolate, content::WebContents* web_contents);
Expand Down Expand Up @@ -469,13 +471,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DevToolsOpened() override;
void DevToolsClosed() override;

#if defined(TOOLKIT_VIEWS)
void ShowAutofillPopup(content::RenderFrameHost* frame_host,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels);
#endif

private:
AtomBrowserContext* GetBrowserContext() const;

Expand Down Expand Up @@ -514,11 +509,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
void SetTemporaryZoomLevel(double level) override;
void DoGetZoomLevel(DoGetZoomLevelCallback callback) override;

void ShowAutofillPopup(const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) override;
void HideAutofillPopup() override;

// Called when we receive a CursorChange message from chromium.
void OnCursorChange(const content::WebCursor& cursor);

Expand Down
63 changes: 63 additions & 0 deletions shell/browser/atom_autofill_driver.cc
@@ -0,0 +1,63 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/browser/atom_autofill_driver.h"

#include <utility>

#include "content/public/browser/render_widget_host_view.h"
#include "shell/browser/api/atom_api_web_contents.h"
#include "shell/browser/native_window.h"

namespace electron {

AutofillDriver::AutofillDriver(
content::RenderFrameHost* render_frame_host,
mojom::ElectronAutofillDriverAssociatedRequest request)
: render_frame_host_(render_frame_host), binding_(this) {
autofill_popup_.reset(new AutofillPopup());
binding_.Bind(std::move(request));
}

AutofillDriver::~AutofillDriver() {}

void AutofillDriver::ShowAutofillPopup(
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
auto* web_contents =
api::WebContents::From(
v8::Isolate::GetCurrent(),
content::WebContents::FromRenderFrameHost(render_frame_host_))
.get();
if (!web_contents || !web_contents->owner_window())
return;

auto* embedder = web_contents->embedder();

bool osr =
web_contents->IsOffScreen() || (embedder && embedder->IsOffScreen());
gfx::RectF popup_bounds(bounds);
content::RenderFrameHost* embedder_frame_host = nullptr;
if (embedder) {
auto* embedder_view = embedder->web_contents()->GetMainFrame()->GetView();
auto* view = web_contents->web_contents()->GetMainFrame()->GetView();
auto offset = view->GetViewBounds().origin() -
embedder_view->GetViewBounds().origin();
popup_bounds.Offset(offset.x(), offset.y());
embedder_frame_host = embedder->web_contents()->GetMainFrame();
}

autofill_popup_->CreateView(render_frame_host_, embedder_frame_host, osr,
web_contents->owner_window()->content_view(),
bounds);
autofill_popup_->SetItems(values, labels);
}

void AutofillDriver::HideAutofillPopup() {
if (autofill_popup_)
autofill_popup_->Hide();
}

} // namespace electron
44 changes: 44 additions & 0 deletions shell/browser/atom_autofill_driver.h
@@ -0,0 +1,44 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#ifndef SHELL_BROWSER_ATOM_AUTOFILL_DRIVER_H_
#define SHELL_BROWSER_ATOM_AUTOFILL_DRIVER_H_

#include <memory>
#include <vector>

#if defined(TOOLKIT_VIEWS)
#include "shell/browser/ui/autofill_popup.h"
#endif

#include "mojo/public/cpp/bindings/associated_binding.h"
#include "shell/common/api/api.mojom.h"

namespace electron {

class AutofillDriver : public mojom::ElectronAutofillDriver {
public:
AutofillDriver(content::RenderFrameHost* render_frame_host,
mojom::ElectronAutofillDriverAssociatedRequest request);

~AutofillDriver() override;

void ShowAutofillPopup(const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) override;
void HideAutofillPopup() override;

private:
content::RenderFrameHost* const render_frame_host_;

#if defined(TOOLKIT_VIEWS)
std::unique_ptr<AutofillPopup> autofill_popup_;
#endif

mojo::AssociatedBinding<mojom::ElectronAutofillDriver> binding_;
};

} // namespace electron

#endif // SHELL_BROWSER_ATOM_AUTOFILL_DRIVER_H_
111 changes: 111 additions & 0 deletions shell/browser/atom_autofill_driver_factory.cc
@@ -0,0 +1,111 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/browser/atom_autofill_driver_factory.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "shell/browser/atom_autofill_driver.h"

namespace electron {

namespace {

std::unique_ptr<AutofillDriver> CreateDriver(
content::RenderFrameHost* render_frame_host,
mojom::ElectronAutofillDriverAssociatedRequest request) {
return std::make_unique<AutofillDriver>(render_frame_host,
std::move(request));
}

} // namespace

AutofillDriverFactory::~AutofillDriverFactory() {}

// static
void AutofillDriverFactory::BindAutofillDriver(
mojom::ElectronAutofillDriverAssociatedRequest request,
content::RenderFrameHost* render_frame_host) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
if (!web_contents)
return;

AutofillDriverFactory* factory =
AutofillDriverFactory::FromWebContents(web_contents);
if (!factory)
return;

AutofillDriver* driver = factory->DriverForFrame(render_frame_host);
if (!driver)
factory->AddDriverForFrame(
render_frame_host,
base::BindOnce(CreateDriver, render_frame_host, std::move(request)));
}

AutofillDriverFactory::AutofillDriverFactory(content::WebContents* web_contents)
codebytere marked this conversation as resolved.
Show resolved Hide resolved
: content::WebContentsObserver(web_contents) {
const std::vector<content::RenderFrameHost*> frames =
web_contents->GetAllFrames();
for (content::RenderFrameHost* frame : frames) {
if (frame->IsRenderFrameLive())
RenderFrameCreated(frame);
}
}

void AutofillDriverFactory::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
DeleteDriverForFrame(render_frame_host);
}

void AutofillDriverFactory::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
// For the purposes of this code, a navigation is not important if it has not
// committed yet or if it's in a subframe.
if (!navigation_handle->HasCommitted() ||
!navigation_handle->IsInMainFrame()) {
return;
}

CloseAllPopups();
}

AutofillDriver* AutofillDriverFactory::DriverForFrame(
content::RenderFrameHost* render_frame_host) {
auto mapping = driver_map_.find(render_frame_host);
return mapping == driver_map_.end() ? nullptr : mapping->second.get();
}

void AutofillDriverFactory::AddDriverForFrame(
content::RenderFrameHost* render_frame_host,
CreationCallback factory_method) {
auto insertion_result =
driver_map_.insert(std::make_pair(render_frame_host, nullptr));
// This can be called twice for the key representing the main frame.
if (insertion_result.second) {
insertion_result.first->second = std::move(factory_method).Run();
}
}

void AutofillDriverFactory::DeleteDriverForFrame(
content::RenderFrameHost* render_frame_host) {
driver_map_.erase(render_frame_host);
}

void AutofillDriverFactory::CloseAllPopups() {
for (auto& it : driver_map_) {
it.second->HideAutofillPopup();
}
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(AutofillDriverFactory)

} // namespace electron