blob: 94400660974bf2db1dd10773a7748fb53682fd29 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/extensions/extensions_side_panel_controller.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/side_panel.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/extension_id.h"
#include "net/base/url_util.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/metadata/metadata_impl_macros.h"
namespace {
// TODO(tluk): Figure out what our default width should be.
constexpr int kDefaultWidth = 450;
const char kPanelActiveKey[] = "active";
const char kPanelActiveValue[] = "true";
const char kPanelWidth[] = "width";
} // namespace
ExtensionsSidePanelController::ExtensionsSidePanelController(
SidePanel* side_panel,
content::BrowserContext* browser_context)
: side_panel_(side_panel),
web_view_(side_panel_->AddChildView(
std::make_unique<views::WebView>(browser_context))) {
DCHECK(base::FeatureList::IsEnabled(features::kExtensionsSidePanel));
side_panel_->SetVisible(false);
side_panel_->SetPanelWidth(kDefaultWidth);
Observe(web_view_->GetWebContents());
// Enable the hosted WebContents to leverage extensions APIs.
extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
web_view_->GetWebContents());
// Set the side panel as type kExtensionPopup given this most closely
// represents how we intend to use the extension for the side panel.
// TODO(tluk): Consider creating a new type specifically for the extension
// side panel.
extensions::SetViewType(web_view_->GetWebContents(),
extensions::mojom::ViewType::kExtensionPopup);
const extensions::ExtensionId& extension_id =
features::kExtensionsSidePanelId.Get();
if (const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(browser_context)
->enabled_extensions()
.GetByID(extension_id)) {
web_view_->LoadInitialURL(extension->GetResourceURL("side_panel.html"));
}
}
ExtensionsSidePanelController::~ExtensionsSidePanelController() = default;
// The extension host uses URL params to control various properties of the side
// panel such as visibility and width. Check for these params and adjust the
// side panel accordingly.
void ExtensionsSidePanelController::NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) {
const GURL& url = load_details.entry->GetURL();
std::string value;
// TODO(crbug.com/1203063): The side panel contents should not be active when
// the panel is not active. This could lead to issues wrt extension lifetime
// and resource consumption. Remove or fix this after the experiment has
// concluded.
if (net::GetValueForKeyInQuery(url, kPanelActiveKey, &value))
side_panel_->SetVisible(value == kPanelActiveValue);
if (net::GetValueForKeyInQuery(url, kPanelWidth, &value)) {
unsigned int width = 0;
base::StringToUint(value, &width);
side_panel_->SetPanelWidth(width);
}
}