Skip to content
This repository has been archived by the owner on Jan 4, 2019. It is now read-only.

Commit

Permalink
attach/detach
Browse files Browse the repository at this point in the history
  • Loading branch information
bridiver committed Mar 30, 2017
1 parent def7f26 commit 8a21e63
Show file tree
Hide file tree
Showing 20 changed files with 543 additions and 97 deletions.
4 changes: 4 additions & 0 deletions atom/atom_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

<include name="IDR_ATOM_WEB_FRAME_BINDINGS_JS" file="common\api\resources\web_frame_bindings.js" type="BINDATA" />

<include name="IDR_ATOM_WEB_VIEW_EVENTS_API_BINDINGS_JS" file="common\api\resources\web_view_events_api_bindings.js" type="BINDATA" />

<include name="IDR_ATOM_GUEST_VIEW_API_BINDINGS_JS" file="common\api\resources\guest_view_api_bindings.js" type="BINDATA" />

<include name="IDR_ATOM_WEB_VIEW_INTERNAL_BINDINGS_JS" file="common\api\resources\web_view_internal_bindings.js" type="BINDATA" />

<include name="IDR_ATOM_TAB_VIEW_INTERNAL_BINDINGS_JS" file="common\api\resources\tab_view_internal_bindings.js" type="BINDATA" />
Expand Down
2 changes: 0 additions & 2 deletions atom/browser/api/atom_api_app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,6 @@ void App::Observe(
content::WebContents* web_contents =
content::Source<content::WebContents>(source).ptr();
auto browser_context = web_contents->GetBrowserContext();
auto url = web_contents->GetURL();

#if BUILDFLAG(ENABLE_EXTENSIONS)
// make sure background pages get a webcontents
// api wrapper so they can communicate via IPC
Expand Down
30 changes: 8 additions & 22 deletions atom/browser/api/atom_api_web_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,7 @@ void WebContents::Clone(mate::Arguments* args) {
} else {
options = mate::Dictionary::CreateEmpty(isolate());
}
options.Set("userGesture", true);

base::Callback<void(content::WebContents*)> callback;
if (!args->GetNext(&callback)) {
Expand All @@ -1766,18 +1767,8 @@ void WebContents::Clone(mate::Arguments* args) {

create_params.SetBoolean("clone", true);

auto guest_view_manager =
static_cast<GuestViewManager*>(GetBrowserContext()->GetGuestManager());

if (!guest_view_manager) {
callback.Run(nullptr);
return;
}

options.Set("userGesture", true);

guest_view_manager->CreateGuest(brave::TabViewGuest::Type,
HostWebContents(),
extensions::TabHelper::CreateTab(HostWebContents(),
GetBrowserContext(),
create_params,
base::Bind(&WebContents::OnCloneCreated, base::Unretained(this), options,
base::Bind(&WebContents::OnTabCreated, base::Unretained(this),
Expand Down Expand Up @@ -1840,6 +1831,8 @@ void WebContents::Discard() {
if (tab_helper) {
if (!Emit("will-discard") && tab_helper->Discard())
Emit("discarded");
else
Emit("discard-aborted");
}
}

Expand Down Expand Up @@ -2216,6 +2209,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getContentWindowId", &WebContents::GetContentWindowId)
.SetMethod("setActive", &WebContents::SetActive)
.SetMethod("setTabIndex", &WebContents::SetTabIndex)
.SetMethod("discard", &WebContents::Discard)
.SetMethod("setWebRTCIPHandlingPolicy",
&WebContents::SetWebRTCIPHandlingPolicy)
.SetMethod("getWebRTCIPHandlingPolicy",
Expand Down Expand Up @@ -2356,14 +2350,6 @@ void WebContents::CreateTab(mate::Arguments* args) {

auto browser_context = session->browser_context();

auto guest_view_manager =
static_cast<GuestViewManager*>(browser_context->GetGuestManager());

if (!guest_view_manager) {
args->ThrowError("No guest view manager");
return;
}

base::DictionaryValue create_params;
std::string src;
if (options.Get("src", &src) || options.Get("url", &src)) {
Expand All @@ -2373,8 +2359,8 @@ void WebContents::CreateTab(mate::Arguments* args) {
static_cast<brave::BraveBrowserContext*>(
browser_context)->partition_with_prefix());

guest_view_manager->CreateGuest(brave::TabViewGuest::Type,
owner->web_contents(),
extensions::TabHelper::CreateTab(owner->web_contents(),
browser_context,
create_params,
base::Bind(&WebContents::OnTabCreated, base::Unretained(owner),
options, callback));
Expand Down
118 changes: 109 additions & 9 deletions atom/browser/extensions/tab_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/strings/utf_string_conversions.h"
#include "brave/browser/guest_view/tab_view/tab_view_guest.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/memory/tab_manager.h"
#include "chrome/browser/sessions/session_tab_helper.h"
Expand All @@ -35,6 +36,7 @@
#include "net/base/filename_util.h"
#include "ui/base/resource/resource_bundle.h"

using guest_view::GuestViewManager;
using memory::TabManager;

DEFINE_WEB_CONTENTS_USER_DATA_KEY(extensions::TabHelper);
Expand Down Expand Up @@ -81,9 +83,97 @@ TabHelper::~TabHelper() {
BrowserList::RemoveObserver(this);
}

// static
void TabHelper::CreateTab(content::WebContents* owner,
content::BrowserContext* browser_context,
const base::DictionaryValue& create_params,
const GuestViewManager::WebContentsCreatedCallback& callback) {

auto guest_view_manager =
static_cast<GuestViewManager*>(browser_context->GetGuestManager());
DCHECK(guest_view_manager);

guest_view_manager->CreateGuest(brave::TabViewGuest::Type,
owner,
create_params,
callback);
}

// static
content::WebContents* TabHelper::CreateTab(content::WebContents* owner,
content::WebContents::CreateParams create_params) {
auto guest_view_manager = static_cast<GuestViewManager*>(
create_params.browser_context->GetGuestManager());
DCHECK(guest_view_manager);

return guest_view_manager->CreateGuestWithWebContentsParams(
brave::TabViewGuest::Type,
owner,
create_params);
}

// static
void TabHelper::DestroyTab(content::WebContents* tab) {
auto guest = brave::TabViewGuest::FromWebContents(tab);
DCHECK(guest);
guest->Destroy();
}

void TabHelper::OnBrowserRemoved(Browser* browser) {
if (browser_ == browser)
if (browser_ != nullptr && browser_ == browser) {
index_ = TabStripModel::kNoTab;
browser_->tab_strip_model()->RemoveObserver(this);
browser_ = nullptr;
}
}

void TabHelper::TabInsertedAt(TabStripModel* tab_strip_model,
content::WebContents* contents,
int index,
bool foreground) {
if (contents != web_contents())
return;

DCHECK(index != TabStripModel::kNoTab);
index_ = index;
// TODO(bridiver) - deal with foreground
}

void TabHelper::TabReplacedAt(TabStripModel* tab_strip_model,
content::WebContents* old_contents,
content::WebContents* new_contents,
int index) {
if (old_contents != web_contents())
return;

auto old_browser = browser_;

brave::TabViewGuest* old_guest = guest();
int guest_instance_id = old_guest->guest_instance_id();

auto new_helper = TabHelper::FromWebContents(new_contents);
new_helper->index_ = index_;
new_helper->pinned_ = pinned_;

OnBrowserRemoved(old_browser);
new_helper->UpdateBrowser(old_browser);

brave::TabViewGuest* new_guest = new_helper->guest();
// always attach first because detach disconnects the webview
old_guest->AttachGuest(new_guest->guest_instance_id());
old_guest->DetachGuest(false);
}

void TabHelper::TabDetachedAt(content::WebContents* contents, int index) {
if (contents != web_contents())
return;

OnBrowserRemoved(browser_);
}

void TabHelper::UpdateBrowser(Browser* browser) {
browser_ = browser;
browser_->tab_strip_model()->AddObserver(this);
}

void TabHelper::SetBrowser(Browser* browser) {
Expand All @@ -93,13 +183,16 @@ void TabHelper::SetBrowser(Browser* browser) {
if (browser_) {
if (index_ != TabStripModel::kNoTab)
browser_->tab_strip_model()->DetachWebContentsAt(index_);
}

if (!browser)
return;
OnBrowserRemoved(browser_);
}

browser_ = browser;
browser_->tab_strip_model()->AppendWebContents(web_contents(), false);
if (browser) {
UpdateBrowser(browser);
browser_->tab_strip_model()->AppendWebContents(web_contents(), false);
} else {
browser_ = nullptr;
}
}

void TabHelper::SetWindowId(const int32_t& id) {
Expand All @@ -119,10 +212,11 @@ void TabHelper::SetAutoDiscardable(bool auto_discardable) {

bool TabHelper::Discard() {
int64_t web_contents_id = TabManager::IdFromWebContents(web_contents());
if (g_browser_process->GetTabManager()->DiscardTabById(web_contents_id))
return true;
return !!g_browser_process->GetTabManager()->DiscardTabById(web_contents_id);
}

return false;
bool TabHelper::IsDiscarded() {
return g_browser_process->GetTabManager()->IsTabDiscarded(web_contents());
}

void TabHelper::SetPinned(bool pinned) {
Expand All @@ -142,6 +236,12 @@ bool TabHelper::is_active() const {
}
}

brave::TabViewGuest* TabHelper::guest() const {
auto guest = brave::TabViewGuest::FromWebContents(web_contents());
DCHECK(guest);
return guest;
}

void TabHelper::SetTabValues(const base::DictionaryValue& values) {
values_->MergeDictionary(&values);
}
Expand Down
36 changes: 34 additions & 2 deletions atom/browser/extensions/tab_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include "base/macros.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "components/guest_view/browser/guest_view_manager.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "extensions/browser/extension_function_dispatcher.h"
Expand All @@ -22,6 +24,10 @@ namespace base {
class DictionaryValue;
}

namespace brave {
class TabViewGuest;
}

namespace content {
class BrowserContext;
class RenderFrameHost;
Expand All @@ -42,6 +48,8 @@ extern const char kAudibleKey[];
extern const char kMutedKey[];
}

using guest_view::GuestViewManager;

namespace extensions {

class Extension;
Expand All @@ -50,10 +58,19 @@ class Extension;
// window of the tab.
class TabHelper : public content::WebContentsObserver,
public content::WebContentsUserData<TabHelper>,
public chrome::BrowserListObserver {
public chrome::BrowserListObserver,
public TabStripModelObserver {
public:
~TabHelper() override;

static void CreateTab(content::WebContents* owner,
content::BrowserContext* browser_context,
const base::DictionaryValue& create_params,
const GuestViewManager::WebContentsCreatedCallback& callback);
static content::WebContents* CreateTab(content::WebContents* owner,
content::WebContents::CreateParams create_params);
static void DestroyTab(content::WebContents* tab);

// Identifier of the tab.
void SetTabId(content::RenderFrameHost* render_frame_host);
int32_t session_id() const;
Expand All @@ -72,6 +89,8 @@ class TabHelper : public content::WebContentsObserver,

bool Discard();

bool IsDiscarded();

void SetTabValues(const base::DictionaryValue& values);
base::DictionaryValue* getTabValues() {
return values_.get();
Expand All @@ -87,6 +106,8 @@ class TabHelper : public content::WebContentsObserver,
return browser_;
}

brave::TabViewGuest* guest() const;

int get_index() const { return index_; }
bool is_pinned() const { return pinned_; }
bool is_active() const;
Expand All @@ -112,7 +133,18 @@ class TabHelper : public content::WebContentsObserver,
explicit TabHelper(content::WebContents* contents);
friend class content::WebContentsUserData<TabHelper>;

void OnBrowserRemoved(Browser* browser);
void TabDetachedAt(content::WebContents* contents, int index) override;
void TabInsertedAt(TabStripModel* tab_strip_model,
content::WebContents* contents,
int index,
bool foreground) override;
void TabReplacedAt(TabStripModel* tab_strip_model,
content::WebContents* old_contents,
content::WebContents* new_contents,
int index) override;
void OnBrowserRemoved(Browser* browser) override;
void UpdateBrowser(Browser* browser);

void ExecuteScript(
std::string extension_id,
std::unique_ptr<base::DictionaryValue> options,
Expand Down
12 changes: 12 additions & 0 deletions atom/common/api/resources/guest_view_api_bindings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2014 The Brave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This module implements the public-facing API functions for the <webview> tag.

const GuestView = require('guestView').GuestView;

GuestView.prototype.getState = function() {
var internal = privates(this).internal;
return internal.state
}
Loading

0 comments on commit 8a21e63

Please sign in to comment.