diff --git a/app/brave_app_management.grdp b/app/brave_app_management.grdp new file mode 100644 index 00000000000..a676ad568d5 --- /dev/null +++ b/app/brave_app_management.grdp @@ -0,0 +1,13 @@ + + + + + Open mode + + + Open as tabbed window + + + Open in browser + + diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd index e9f992af78d..b89184f3161 100644 --- a/app/brave_generated_resources.grd +++ b/app/brave_generated_resources.grd @@ -172,6 +172,9 @@ + + + diff --git a/app/feature_defaults_unittest.cc b/app/feature_defaults_unittest.cc index 3f895ae7e2e..4094a1d46b9 100644 --- a/app/feature_defaults_unittest.cc +++ b/app/feature_defaults_unittest.cc @@ -266,6 +266,7 @@ TEST(FeatureDefaultsTest, EnabledFeatures) { &blink::features::kReduceUserAgentMinorVersion, &blink::features::kUACHOverrideBlank, &features::kCertificateTransparencyAskBeforeEnabling, + &features::kDesktopPWAsTabStripSettings, #if !BUILDFLAG(IS_ANDROID) &features::kLocationProviderManager, #endif diff --git a/chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts new file mode 100644 index 00000000000..752a2456dcd --- /dev/null +++ b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts @@ -0,0 +1,23 @@ +// Copyright (c) 2025 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 { mangle } from 'lit_mangler'; + +mangle((element) => { + const toggleRow = element.querySelector('app-management-toggle-row') + if (!toggleRow) { + throw new Error('[Brave App Settings] Could not find app-management-toggle-row. Maybe upstream has changed to a radio button?') + } + toggleRow.outerHTML = `
+
+
$i18n{appManagementOpenModeLabel}
+
+
+ \${this.windowModes.map(mode => html\` + \${mode.label} + \`)} +
+
` +}, t => t.text.includes('id="toggle-row"')) diff --git a/chromium_src/chrome/browser/resources/app_settings/window_mode_item.ts b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.ts new file mode 100644 index 00000000000..3c1ea440e5c --- /dev/null +++ b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.ts @@ -0,0 +1,83 @@ +// Copyright (c) 2025 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 type { App } from '//resources/cr_components/app_management/app_management.mojom-webui.js'; +import { CrLitElement, css } from '//resources/lit/v3_0/lit.rollup.js'; + +import { getCss } from './app_management_shared_style.css.js'; +import { createDummyApp } from './web_app_settings_utils.js'; +import { getHtml } from './window_mode_item.html.js'; +import { loadTimeData } from '//resources/js/load_time_data.js'; +import { BrowserProxy } from '//resources/cr_components/app_management/browser_proxy.js'; +import { WindowMode } from '//resources/cr_components/app_management/constants.js'; + +export class WindowModeItemElement extends CrLitElement { + static get is() { + return 'app-management-window-mode-item'; + } + + static override get styles() { + return [ + getCss(), + css` + :host > div { + width: 100%; + } + + leo-radiobutton { + display: flex; + } + ` + ]; + } + + override render() { + return getHtml.bind(this)(); + } + + static override get properties() { + return { + windowModeLabel: { type: String }, + + app: { type: Object }, + }; + } + + get tabStripSettingsEnabled_(): boolean { + return loadTimeData.getBoolean('isPWAsTabStripSettingsEnabled'); + } + + get windowModes() { + return [ + { + label: loadTimeData.getString('appManagementWindowModeLabel'), + value: WindowMode.kWindow, + }, + { + label: loadTimeData.getString('appManagementBrowserModeLabel'), + value: WindowMode.kBrowser, + }, + ...this.tabStripSettingsEnabled_ ? [{ + label: loadTimeData.getString('appManagementTabbedWindowModeLabel'), + value: WindowMode.kTabbedWindow, + }] : [], + ] + } + + accessor windowModeLabel: string = ''; + accessor app: App = createDummyApp(); + + onChange(e: { value: string }) { + BrowserProxy.getInstance().handler.setWindowMode(this.app.id, parseInt(e.value) as WindowMode); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'app-management-window-mode-item': WindowModeItemElement; + } +} + +customElements.define(WindowModeItemElement.is, WindowModeItemElement); diff --git a/chromium_src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc b/chromium_src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc new file mode 100644 index 00000000000..0d3f0d796ab --- /dev/null +++ b/chromium_src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc @@ -0,0 +1,31 @@ +// Copyright (c) 2025 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/. + +#include "chrome/browser/ui/webui/app_settings/web_app_settings_ui.h" + +#include "base/feature_list.h" +#include "chrome/common/chrome_features.h" +#include "content/public/browser/web_ui_data_source.h" +#include "ui/webui/webui_util.h" + +#define SetupWebUIDataSource(...) \ + SetupWebUIDataSource(__VA_ARGS__); \ + html_source->AddBoolean( \ + "isPWAsTabStripSettingsEnabled", \ + base::FeatureList::IsEnabled(features::kDesktopPWAsTabStripSettings)) + +#define AddLocalizedStrings(...) \ + AddLocalizedStrings(__VA_ARGS__); \ + html_source->AddLocalizedString("appManagementTabbedWindowModeLabel", \ + IDS_APP_MANAGEMENT_TABBED_WINDOW); \ + html_source->AddLocalizedString("appManagementBrowserModeLabel", \ + IDS_APP_MANAGEMENT_BROWSER); \ + html_source->AddLocalizedString("appManagementOpenModeLabel", \ + IDS_APP_MANAGEMENT_OPEN_MODE) + +#include "src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc" + +#undef AddLocalizedStrings +#undef SetupWebUIDataSource diff --git a/chromium_src/chrome/common/chrome_features.cc b/chromium_src/chrome/common/chrome_features.cc index 146609c457d..be842e71b65 100644 --- a/chromium_src/chrome/common/chrome_features.cc +++ b/chromium_src/chrome/common/chrome_features.cc @@ -13,6 +13,7 @@ namespace features { OVERRIDE_FEATURE_DEFAULT_STATES({{ {kChromeStructuredMetrics, base::FEATURE_DISABLED_BY_DEFAULT}, + {kDesktopPWAsTabStripSettings, base::FEATURE_ENABLED_BY_DEFAULT}, {kHttpsFirstBalancedMode, base::FEATURE_DISABLED_BY_DEFAULT}, {kKAnonymityService, base::FEATURE_DISABLED_BY_DEFAULT}, {kKAnonymityServiceOHTTPRequests, base::FEATURE_DISABLED_BY_DEFAULT}, diff --git a/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap b/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap index 31d68f63483..c1fd81daa18 100644 --- a/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap +++ b/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap @@ -1,5 +1,34 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`mangled files should have up to date snapshots ./chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts should match snapshot 1`] = ` +"=================================================================== +--- ../chrome/browser/resources/app_settings/window_mode_item.html.ts ++++ gen/chrome/browser/resources/app_settings/preprocessed/window_mode_item.html.ts +@@ -3,11 +3,16 @@ + import type {WindowModeItemElement} from './window_mode_item.js'; + + export function getHtml(this: WindowModeItemElement) { + return html\` +- +- ++
++
++
$i18n{appManagementOpenModeLabel}
++
++
++ \${this.windowModes.map(mode => html\` ++ \${mode.label} ++ \`)} ++
++
+ \`; + } +" +`; + exports[`mangled files should have up to date snapshots ./chromium_src/chrome/browser/resources/extensions/detail_view.html.ts.lit_mangler.ts should match snapshot 1`] = ` "=================================================================== --- ../chrome/browser/resources/extensions/detail_view.html.ts diff --git a/ui/webui/resources/leo/web_components.ts b/ui/webui/resources/leo/web_components.ts index a775cc9aaad..720c4afbaf2 100644 --- a/ui/webui/resources/leo/web_components.ts +++ b/ui/webui/resources/leo/web_components.ts @@ -16,6 +16,7 @@ import '@brave/leo/web-components/progressRing' import '@brave/leo/web-components/textarea' import '@brave/leo/web-components/toggle' import '@brave/leo/web-components/tooltip' +import '@brave/leo/web-components/radioButton' import { setIconBasePath } from '@brave/leo/web-components/icon' import iconsMeta from '@brave/leo/icons/meta'