Skip to content

Commit

Permalink
added scroll handling for webcompat dialog
Browse files Browse the repository at this point in the history
Signed-off-by: Vadym Struts <[email protected]>
  • Loading branch information
vadimstruts committed Dec 18, 2024
1 parent 130d286 commit 6c13221
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 16 deletions.
90 changes: 81 additions & 9 deletions browser/ui/webui/webcompat_reporter/webcompat_reporter_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "brave/browser/ui/webui/webcompat_reporter/webcompat_reporter_ui.h"

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

Expand All @@ -15,6 +17,7 @@
#include "base/strings/string_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/values.h"
#include "brave/browser/brave_browser_process.h"
#include "brave/browser/ui/webui/brave_webui_source.h"
#include "brave/browser/ui/webui/webcompat_reporter/webcompat_reporter_dialog.h"
Expand All @@ -31,16 +34,19 @@
#include "brave/components/webcompat_reporter/resources/grit/webcompat_reporter_generated_map.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "components/grit/brave_components_resources.h"
#include "components/language/core/browser/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui_data_source.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/gfx/codec/png_codec.h"
#include "url/gurl.h"
#include "ui/gfx/geometry/size.h"

#if BUILDFLAG(ENABLE_BRAVE_VPN)
#include "brave/browser/brave_vpn/brave_vpn_service_factory.h"
Expand All @@ -53,6 +59,25 @@ namespace {

constexpr char kUISourceHistogramName[] = "Brave.Webcompat.UISource";
constexpr int kMaxScreenshotPixelCount = 1280 * 720;
constexpr char kGetViewPortSizeParamName[] = "height";

content::WebContents* GetWebContents() {
const auto* browser = BrowserList::GetInstance()->GetLastActive();
if (!browser) {
return nullptr;
}

return browser->tab_strip_model()->GetActiveWebContents();
}

std::optional<gfx::Rect> GetNativeViewBounds() {
auto* web_contents = GetWebContents();
if (!web_contents) {
return std::nullopt;
}

return web_contents->GetNativeView()->bounds();
}

} // namespace

Expand All @@ -66,11 +91,7 @@ WebcompatReporterDOMHandler::WebcompatReporterDOMHandler(Profile* profile)

InitAdditionalParameters(profile);

auto* browser = chrome::FindLastActiveWithProfile(profile);
if (!browser) {
return;
}
auto* web_contents = browser->tab_strip_model()->GetActiveWebContents();
auto* web_contents = GetWebContents();
if (!web_contents) {
return;
}
Expand All @@ -97,6 +118,14 @@ void WebcompatReporterDOMHandler::InitAdditionalParameters(Profile* profile) {

WebcompatReporterDOMHandler::~WebcompatReporterDOMHandler() = default;

void WebcompatReporterDOMHandler::OnWindowResize(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
AllowJavascript();
base::Value::Dict event_data;
event_data.Set("height", old_bounds.height());
FireWebUIListener("onViewPortSizeChanged", event_data);
}

void WebcompatReporterDOMHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"webcompat_reporter.submitReport",
Expand All @@ -115,6 +144,10 @@ void WebcompatReporterDOMHandler::RegisterMessages() {
"webcompat_reporter.clearScreenshot",
base::BindRepeating(&WebcompatReporterDOMHandler::HandleClearScreenshot,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"webcompat_reporter.init",
base::BindRepeating(&WebcompatReporterDOMHandler::HandleInit,
base::Unretained(this)));
}

void WebcompatReporterDOMHandler::HandleCaptureScreenshot(
Expand Down Expand Up @@ -192,6 +225,22 @@ void WebcompatReporterDOMHandler::HandleGetCapturedScreenshot(
ResolveJavascriptCallback(args[0], screenshot_b64);
}

void WebcompatReporterDOMHandler::HandleInit(const base::Value::List& args) {
CHECK_EQ(args.size(), 1u);

AllowJavascript();

auto bounds = GetNativeViewBounds();

if (!bounds) {
return;
}

base::Value::Dict event_data;
event_data.Set(kGetViewPortSizeParamName, bounds->height());
ResolveJavascriptCallback(args[0], event_data);
}

void WebcompatReporterDOMHandler::HandleClearScreenshot(
const base::Value::List& args) {
pending_report_->screenshot_png = std::nullopt;
Expand Down Expand Up @@ -248,12 +297,35 @@ WebcompatReporterUI::WebcompatReporterUI(content::WebUI* web_ui)
CreateAndAddWebUIDataSource(
web_ui, kWebcompatReporterHost, kWebcompatReporterGenerated,
kWebcompatReporterGeneratedSize, IDR_WEBCOMPAT_REPORTER_HTML);
Profile* profile = Profile::FromWebUI(web_ui);
auto* profile = Profile::FromWebUI(web_ui);

auto* web_contents = GetWebContents();
if (!web_contents) {
return;
}

auto webcompat_reporter_handler =
std::make_unique<WebcompatReporterDOMHandler>(profile);

webcompat_reporter_handler_ = webcompat_reporter_handler.get();

web_ui->AddMessageHandler(std::move(webcompat_reporter_handler));

web_ui->AddMessageHandler(
std::make_unique<WebcompatReporterDOMHandler>(profile));
observed_windows_.AddObservation(web_contents->GetNativeView());
}

WebcompatReporterUI::~WebcompatReporterUI() = default;

void WebcompatReporterUI::OnWindowBoundsChanged(
aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) {
if (!webcompat_reporter_handler_) {
return;
}

webcompat_reporter_handler_->OnWindowResize(old_bounds, new_bounds);
}

} // namespace webcompat_reporter
24 changes: 21 additions & 3 deletions browser/ui/webui/webcompat_reporter/webcompat_reporter_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
#ifndef BRAVE_BROWSER_UI_WEBUI_WEBCOMPAT_REPORTER_WEBCOMPAT_REPORTER_UI_H_
#define BRAVE_BROWSER_UI_WEBUI_WEBCOMPAT_REPORTER_WEBCOMPAT_REPORTER_UI_H_

#include <memory>
#include <string>
#include <optional>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "base/task/sequenced_task_runner.h"
#include "brave/components/constants/webui_url_constants.h"
#include "brave/components/webcompat_reporter/common/webcompat_reporter.mojom-forward.h"
Expand All @@ -19,6 +20,8 @@
#include "content/public/browser/web_ui_message_handler.h"
#include "content/public/browser/webui_config.h"
#include "content/public/common/url_constants.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/geometry/rect.h"

namespace content {
class RenderWidgetHostView;
Expand Down Expand Up @@ -48,6 +51,8 @@ class WebcompatReporterDOMHandler : public content::WebUIMessageHandler {
// WebUIMessageHandler implementation.
void RegisterMessages() override;

void OnWindowResize(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds);

private:
void InitAdditionalParameters(Profile* profile);

Expand All @@ -61,6 +66,7 @@ class WebcompatReporterDOMHandler : public content::WebUIMessageHandler {
void HandleClearScreenshot(const base::Value::List& args);

void HandleSubmitReport(const base::Value::List& args);
void HandleInit(const base::Value::List& args);

raw_ptr<WebcompatReporterService> reporter_service_ = nullptr;
raw_ptr<PrefService> pref_service_ = nullptr;
Expand All @@ -72,12 +78,24 @@ class WebcompatReporterDOMHandler : public content::WebUIMessageHandler {
base::WeakPtrFactory<WebcompatReporterDOMHandler> weak_ptr_factory_{this};
};

class WebcompatReporterUI : public ConstrainedWebDialogUI {
class WebcompatReporterUI : public ConstrainedWebDialogUI,
public aura::WindowObserver {
public:
explicit WebcompatReporterUI(content::WebUI* web_ui);
WebcompatReporterUI(const WebcompatReporterUI&) = delete;
WebcompatReporterUI& operator=(const WebcompatReporterUI&) = delete;
~WebcompatReporterUI() override;

// aura::WindowObserver
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) override;

private:
raw_ptr<WebcompatReporterDOMHandler> webcompat_reporter_handler_{nullptr};
base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
observed_windows_{this};
};

} // namespace webcompat_reporter
Expand Down
15 changes: 14 additions & 1 deletion components/webcompat_reporter/ui/browser_proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import { sendWithPromise } from 'chrome://resources/js/cr.js';
import {
addWebUiListener,
sendWithPromise
} from 'chrome://resources/js/cr.js';

export function submitReport(reportDetails: { [key: string]: any }) {
chrome.send('webcompat_reporter.submitReport', [
Expand All @@ -29,3 +32,13 @@ export function clearScreenshot() {
export function getCapturedScreenshot(): Promise<string> {
return sendWithPromise('webcompat_reporter.getCapturedScreenshot')
}

export interface ViewPortSizeChangedObject {
height: number
}

export function setViewPortChangeListener(
calback: (data: ViewPortSizeChangedObject) => void) {
sendWithPromise('webcompat_reporter.init').then(calback)
addWebUiListener('onViewPortSizeChanged', calback)
}
5 changes: 3 additions & 2 deletions components/webcompat_reporter/ui/components/ReportView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
ModalTitle,
TextSection,
InfoText,
NonInteractiveURL,
DisclaimerText,
SideBySideButtons,
PaddedButton,
Expand All @@ -24,6 +23,8 @@ import {
ScreenshotLink
} from './basic'

import ShortenedUrl from './ShortenedUrl'

// Localization data
import { getLocale } from '../../../common/locale'
import {
Expand Down Expand Up @@ -129,7 +130,7 @@ export default class ReportView extends React.PureComponent<Props, State> {
</InfoText>
{!isIneligiblePage &&
<>
<NonInteractiveURL>{siteUrl}</NonInteractiveURL>
<ShortenedUrl url={siteUrl}/>
<FieldCtr>
<TextArea
placeholder={getLocale('reportDetails')}
Expand Down
72 changes: 72 additions & 0 deletions components/webcompat_reporter/ui/components/ShortenedUrl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

import * as React from 'react'

import { NonInteractiveURL } from './basic'

interface ShortenedUrlProps {
url: string
maxLength: number
interactive: boolean
}

interface ShortenedUrlState {
shortenedUrl: string
}

class ShortenedUrl
extends React.PureComponent<ShortenedUrlProps, ShortenedUrlState> {
static defaultProps: Partial<ShortenedUrlProps> = {
maxLength: 100,
interactive: false
}

constructor(props: ShortenedUrlProps) {
super(props)
this.state = {
shortenedUrl: this.shortenUrl(props.url, props.maxLength),
}
}

handleOnInteractiveClick =
async (ev: React.MouseEvent<HTMLParagraphElement>) => {
if (this.props.interactive) {
window.open(this.props.url, '_blank', 'noopener')
}
}

shortenUrl(url: string, maxLength: number): string {
if (url.length <= maxLength) {
return url
}
const dots = '......'
const partLength = Math.floor((maxLength - dots.length) / 2)
const start = url.slice(0, partLength)
const end = url.slice(-partLength)

return `${start}${dots}${end}`
}

componentDidUpdate(prevProps: ShortenedUrlProps) {
if (prevProps.url !== this.props.url ||
prevProps.maxLength !== this.props.maxLength) {
this.setState({
shortenedUrl: this.shortenUrl(
this.props.url, this.props.maxLength),
})
}
}

render() {
const { shortenedUrl } = this.state
return (
<NonInteractiveURL onClick={this.handleOnInteractiveClick}>
{shortenedUrl}
</NonInteractiveURL>)
}
}

export default ShortenedUrl;
2 changes: 2 additions & 0 deletions components/webcompat_reporter/ui/webcompat_reporter.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<style>
#root {
height: 100%;
overflow-x: hidden;
overflow-y: auto;
}
body {
margin: 0;
Expand Down
15 changes: 14 additions & 1 deletion components/webcompat_reporter/ui/webcompat_reporter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import App from './containers/App'
// Utils
import store from './store'
import * as webcompatReporterActions from './actions/webcompatreporter_actions'
import { getDialogArgs } from './browser_proxy'
import {
getDialogArgs,
setViewPortChangeListener,
ViewPortSizeChangedObject,
} from './browser_proxy'

let actions: any

Expand All @@ -43,9 +47,18 @@ function loadDialogArgs () {
getActions().setDialogArgs(dialogArgs)
}

function onViewPortSizeChanged(data: ViewPortSizeChangedObject) {
const root = document.getElementById('root')
if (root) {
root.style.maxHeight = `${data.height}px`
}
}

function initialize () {
loadDialogArgs()

setViewPortChangeListener(onViewPortSizeChanged)

new Promise(resolve => chrome.braveTheme.getBraveThemeType(resolve))
.then((themeType: chrome.braveTheme.ThemeType) => {
render(
Expand Down

0 comments on commit 6c13221

Please sign in to comment.