Skip to content

Commit

Permalink
[Performance Settings] Add tabbed add exception dialog behind a flag
Browse files Browse the repository at this point in the history
Creates a new add exception dialog with two tabs, the first holding a
list of sites from current open tabs ordered by most recently accessed,
and the second holding the original manual input field. This new dialog
will be shown when clicking the add button in the exception list while
the flag "DiscardExceptionsImprovements" is on. When the flag is off,
the original add dialog with just the manual input will be shown.

To enable the new UI: --enable-features=DiscardExceptionsImprovements

Screenshots:
https://screenshot.googleplex.com/Begz7kT6aRsDwVd.png
https://screenshot.googleplex.com/8hCsh2C8SBpj4An.png
https://screenshot.googleplex.com/3oUQWjJ9stRsJA5.png
https://screenshot.googleplex.com/3opaqbNmayuDgng.png

Design doc:
docs.google.com/document/d/1ureyY_ElAgM0IrcN60-a-vNs9CPRvgnOrvtrUQ1pSWs

Bug: 1424223
Change-Id: I78ab010e347c651ef5808101209d9f69f654845e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4539688
Reviewed-by: John Lee <johntlee@chromium.org>
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Charles Meng <charlesmeng@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1149910}
  • Loading branch information
Charles Meng authored and Chromium LUCI CQ committed May 26, 2023
1 parent f01aef2 commit fab4b9c
Show file tree
Hide file tree
Showing 18 changed files with 721 additions and 102 deletions.
9 changes: 9 additions & 0 deletions chrome/app/settings_strings.grdp
Expand Up @@ -1555,6 +1555,15 @@
<message name="IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADDITIONAL_SITES" desc="Label for button that expands the tab discarding exceptions list to show all entries. Sites added to the list will not be discarded by memory saver.">
Additional sites
</message>
<message name="IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADD_DIALOG_CURRENT_TABS" desc="Label for the first tab of the tab discarding exception list add dialog, that allows users to pick sites from currently opened tabs to add to the list." translateable="false">
Add open tabs
</message>
<message name="IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADD_DIALOG_MANUAL" desc="Label for the second tab of the tab discarding exception list add dialog, where users can manually input a site to be added to the list." translateable="false">
Add sites manually
</message>
<message name="IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADD_DIALOG_HELP" desc="Label for button that expands the tab discarding exceptions list to show all entries. Sites added to the list will not be discarded by memory saver." translateable="false">
Sites you add remain active and won't be used to give active tabs and other apps more resources. <ph name="BEGIN_LINK">&lt;a href="$1" target="_blank"&gt;</ph>Learn more about site exclusion<ph name="END_LINK">&lt;/a&gt;</ph>
</message>
<message name="IDS_SETTINGS_BATTERY_PAGE_TITLE" desc="Title of the power section of the performance settings page">
Power
</message>
Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/resources/settings/BUILD.gn
Expand Up @@ -115,10 +115,12 @@ build_webui("build") {
"performance_page/performance_page.ts",
"performance_page/tab_discard_exception_add_dialog.ts",
"performance_page/tab_discard_exception_add_input.ts",
"performance_page/tab_discard_exception_current_sites_list.ts",
"performance_page/tab_discard_exception_edit_dialog.ts",
"performance_page/tab_discard_exception_edit_input.ts",
"performance_page/tab_discard_exception_entry.ts",
"performance_page/tab_discard_exception_list.ts",
"performance_page/tab_discard_exception_tabbed_add_dialog.ts",
"people_page/people_page.ts",
"people_page/signout_dialog.ts",
"people_page/sync_account_control.ts",
Expand Down
Expand Up @@ -5,13 +5,18 @@
import {sendWithPromise} from 'chrome://resources/js/cr.js';

export interface PerformanceBrowserProxy {
getCurrentOpenSites(): Promise<string[]>;
getDeviceHasBattery(): Promise<boolean>;
openBatterySaverFeedbackDialog(): void;
openHighEfficiencyFeedbackDialog(): void;
validateTabDiscardExceptionRule(rule: string): Promise<boolean>;
}

export class PerformanceBrowserProxyImpl implements PerformanceBrowserProxy {
getCurrentOpenSites() {
return sendWithPromise('getCurrentOpenSites');
}

getDeviceHasBattery() {
return sendWithPromise('getDeviceHasBattery');
}
Expand Down
@@ -0,0 +1,33 @@
<style include="settings-shared">
cr-checkbox::part(label-container) {
min-width: 0;
}

.label-slot {
align-items: center;
display: flex;
}

.checkbox-label {
margin-inline-start: 10px;
}
</style>
<div id="container" scrollable>
<iron-list id="list" scroll-target="container" role="grid"
items="[[currentSites_]]" selected-items="{{selectedSites_}}"
selection-enabled multi-selection
aria-rowcount$="[[currentSites_.length]]"
hidden$="[[!currentSites_.length]]">
<template>
<cr-checkbox class="list-item no-outline" role="row"
tab-index="[[tabIndex]]"
aria-rowindex$="[[getAriaRowindex_(index)]]"
on-change="onToggleSelection_" checked="{{selected}}">
<div class="label-slot">
<site-favicon url="[[item]]"></site-favicon>
<div class="checkbox-label text-elide">[[item]]</div>
</div>
</cr-checkbox>
</template>
</iron-list>
</div>
@@ -0,0 +1,119 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js';
import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
import '../settings_shared.css.js';
import '../site_favicon.js';

import {PrefsMixin, PrefsMixinInterface} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js';
import {CrScrollableMixin, CrScrollableMixinInterface} from 'chrome://resources/cr_elements/cr_scrollable_mixin.js';
import {ListPropertyUpdateMixin, ListPropertyUpdateMixinInterface} from 'chrome://resources/cr_elements/list_property_update_mixin.js';
import {assert} from 'chrome://resources/js/assert_ts.js';
import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';

import {PerformanceBrowserProxy, PerformanceBrowserProxyImpl} from './performance_browser_proxy.js';
import {HighEfficiencyModeExceptionListAction, PerformanceMetricsProxy, PerformanceMetricsProxyImpl} from './performance_metrics_proxy.js';
import {getTemplate} from './tab_discard_exception_current_sites_list.html.js';
import {TAB_DISCARD_EXCEPTIONS_PREF} from './tab_discard_exception_validation_mixin.js';

export interface TabDiscardExceptionCurrentSitesListElement {
$: {
list: IronListElement,
};
}

type Constructor<T> = new (...args: any[]) => T;
const TabDiscardExceptionCurrentSitesListElementBase =
ListPropertyUpdateMixin(CrScrollableMixin(PrefsMixin(PolymerElement))) as
Constructor<ListPropertyUpdateMixinInterface&CrScrollableMixinInterface&
PrefsMixinInterface&PolymerElement>;

export class TabDiscardExceptionCurrentSitesListElement extends
TabDiscardExceptionCurrentSitesListElementBase {
static get is() {
return 'tab-discard-exception-current-sites-list';
}

static get template() {
return getTemplate();
}

static get properties() {
return {
currentSites_: {type: Array, value: []},

selectedSites_: {type: Array, value: []},

submitDisabled: {
type: Boolean,
computed: 'computeSubmitDisabled_(selectedSites_.length)',
notify: true,
},
};
}

private browserProxy_: PerformanceBrowserProxy =
PerformanceBrowserProxyImpl.getInstance();
private metricsProxy_: PerformanceMetricsProxy =
PerformanceMetricsProxyImpl.getInstance();

private currentSites_: string[];
private selectedSites_: string[];
private submitDisabled: boolean;

override async connectedCallback() {
super.connectedCallback();

const currentRules = await this.browserProxy_.getCurrentOpenSites();
const existingRules =
new Set(this.getPref(TAB_DISCARD_EXCEPTIONS_PREF).value);
this.updateList(
'currentSites_', x => x,
currentRules.filter(rule => !existingRules.has(rule)));
if (this.currentSites_.length) {
this.updateScrollableContents();
}
this.dispatchEvent(new CustomEvent('sites-populated', {
detail: {length: this.currentSites_.length},
}));
}

private computeSubmitDisabled_() {
return !this.selectedSites_.length;
}

private onToggleSelection_(e: {model: {index: number}}) {
this.$.list.toggleSelectionForIndex(e.model.index);
}

private getAriaRowindex_(index: number): number {
return index + 1;
}

async submit() {
assert(!this.submitDisabled);
this.selectedSites_.forEach(rule => {
this.appendPrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, rule);
});
this.dispatchEvent(new CustomEvent('add-exception', {
bubbles: true,
composed: true,
}));
this.metricsProxy_.recordExceptionListAction(
HighEfficiencyModeExceptionListAction.ADD);
}
}

declare global {
interface HTMLElementTagNameMap {
'tab-discard-exception-current-sites-list':
TabDiscardExceptionCurrentSitesListElement;
}
}

customElements.define(
TabDiscardExceptionCurrentSitesListElement.is,
TabDiscardExceptionCurrentSitesListElement);
Expand Up @@ -76,6 +76,11 @@
on-close="onAddDialogClose_" on-add-exception="onAddException_">
</tab-discard-exception-add-dialog>
</template>
<template is="dom-if" if="[[showTabbedAddDialog_]]" restamp>
<tab-discard-exception-tabbed-add-dialog prefs="{{prefs}}"
on-close="onTabbedAddDialogClose_" on-add-exception="onAddException_">
</tab-discard-exception-tabbed-add-dialog>
</template>
<template is="dom-if" if="[[showEditDialog_]]" restamp>
<tab-discard-exception-edit-dialog prefs="{{prefs}}"
on-close="onEditDialogClose_" rule-to-edit="[[selectedRule_]]">
Expand Down
Expand Up @@ -13,6 +13,7 @@ import '../settings_shared.css.js';
import './tab_discard_exception_add_dialog.js';
import './tab_discard_exception_edit_dialog.js';
import './tab_discard_exception_entry.js';
import './tab_discard_exception_tabbed_add_dialog.js';

import {PrefsMixin, PrefsMixinInterface} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js';
import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
Expand All @@ -21,6 +22,7 @@ import {CrExpandButtonElement} from 'chrome://resources/cr_elements/cr_expand_bu
import {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
import {ListPropertyUpdateMixin, ListPropertyUpdateMixinInterface} from 'chrome://resources/cr_elements/list_property_update_mixin.js';
import {assert} from 'chrome://resources/js/assert_ts.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
import {IronCollapseElement} from 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
import {PaperTooltipElement} from 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js';
import {DomRepeat, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
Expand Down Expand Up @@ -82,11 +84,25 @@ export class TabDiscardExceptionListElement extends
value: '',
},

isDiscardExceptionsImprovementsEnabled_: {
readOnly: true,
type: Boolean,
value() {
return loadTimeData.getBoolean(
'isDiscardExceptionsImprovementsEnabled');
},
},

showAddDialog_: {
type: Boolean,
value: false,
},

showTabbedAddDialog_: {
type: Boolean,
value: false,
},

showEditDialog_: {
type: Boolean,
value: false,
Expand All @@ -106,7 +122,9 @@ export class TabDiscardExceptionListElement extends
private siteList_: TabDiscardExceptionEntry[];
private overflowSiteListExpanded: boolean;
private selectedRule_: string;
private isDiscardExceptionsImprovementsEnabled_: boolean;
private showAddDialog_: boolean;
private showTabbedAddDialog_: boolean;
private showEditDialog_: boolean;
private tooltipText_: string;

Expand All @@ -131,7 +149,11 @@ export class TabDiscardExceptionListElement extends

private onAddClick_() {
assert(!this.showEditDialog_);
this.showAddDialog_ = true;
if (this.isDiscardExceptionsImprovementsEnabled_) {
this.showTabbedAddDialog_ = true;
} else {
this.showAddDialog_ = true;
}
}

private onMenuClick_(e: CustomEvent<{target: HTMLElement, site: string}>) {
Expand All @@ -143,6 +165,7 @@ export class TabDiscardExceptionListElement extends
private onEditClick_() {
assert(this.selectedRule_);
assert(!this.showAddDialog_);
assert(!this.showTabbedAddDialog_);
this.showEditDialog_ = true;
this.$.menu.get().close();
}
Expand All @@ -158,6 +181,10 @@ export class TabDiscardExceptionListElement extends
this.showAddDialog_ = false;
}

private onTabbedAddDialogClose_() {
this.showTabbedAddDialog_ = false;
}

private onEditDialogClose_() {
this.showEditDialog_ = false;
}
Expand Down
@@ -0,0 +1,64 @@
<style>
cr-tabs {
--cr-tabs-font-size: 100%;
--cr-tabs-height: 40px;
}

#dialog {
--border-top-color: var(--google-grey-300);
--cr-dialog-body-border-top: 1px solid var(--border-top-color);
}

@media (prefers-color-scheme: dark) {
#dialog {
--border-top-color: var(--cr-separator-color);
}
}

#dialog::part(body-container) {
height: 250px;
}

#helpText {
padding-bottom: 20px;
}

#inputPage {
padding-top: 20px;
}
</style>
<cr-dialog id="dialog" close-text="$i18n{close}">
<div slot="title">$i18n{addSiteTitle}</div>
<div slot="header">
<cr-tabs id="tabs" tab-names="[[tabNames_]]" selected="{{selectedTab_}}">
</cr-tabs>
</div>
<div slot="body">
<iron-pages selected="[[selectedTab_]]">
<tab-discard-exception-current-sites-list id="list" prefs="{{prefs}}"
on-sites-populated="onSitesPopulated_"
submit-disabled="{{submitDisabledList_}}">
</tab-discard-exception-current-sites-list>
<div id="inputPage">
<div id="helpText">
$i18nRaw{tabDiscardingExceptionsAddDialogHelp}
</div>
<tab-discard-exception-add-input id="input" prefs="{{prefs}}"
submit-disabled="{{submitDisabledManual_}}">
</tab-discard-exception-add-input>
</div>
</iron-pages>
</div>
<div slot="button-container">
<cr-button id="cancelButton" class="cancel-button"
on-click="onCancelClick_">
$i18n{cancel}
</cr-button>
<cr-button id="actionButton" class="action-button" on-click="onSubmitClick_"
disabled$="[[isSubmitDisabled_(
submitDisabledList_, submitDisabledManual_, selectedTab_)]]"
aria-label$="$i18n{tabDiscardingExceptionsAddButtonAriaLabel}">
$i18n{add}
</cr-button>
</div>
</cr-dialog>

0 comments on commit fab4b9c

Please sign in to comment.