Commit 5df30f9d authored by Tibor Goldschwendt's avatar Tibor Goldschwendt Committed by Commit Bot

[webui-ntp] Add UI to uninstall third-party theme

Bug: 1032327
Change-Id: I8953cb4b21a26c26772342e9e4f159df368519c8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1973196
Commit-Queue: Tibor Goldschwendt <tiborg@chromium.org>
Reviewed-by: default avatarMoe Ahmadi <mahmadi@chromium.org>
Reviewed-by: default avatarAlex Gough <ajgo@chromium.org>
Auto-Submit: Tibor Goldschwendt <tiborg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#727423}
parent 07cbc4bc
...@@ -4,8 +4,57 @@ ...@@ -4,8 +4,57 @@
} }
div[slot=body] { div[slot=body] {
align-items: center;
display: flex;
flex-direction: column;
min-height: 423px; min-height: 423px;
text-align: center; }
#thirdPartyThemeContainer {
width: 100%;
}
#thirdPartyTheme {
align-items: center;
border: 1px solid var(--google-grey-200);
border-radius: 5px;
display: flex;
flex-direction: row;
margin-bottom: 24px;
padding: 0 16px;
}
#thirdPartyBrushIcon {
-webkit-mask-image: url(icons/brush.svg);
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 100%;
background-color: var(--cr-secondary-text-color);
height: 24px;
margin-inline-end: 20px;
width: 24px;
}
#thirdPartyThemeNameContainer {
flex-grow: 1;
margin-inline-end: 24px;
}
#thirdPartyThemeName {
font-weight: bold;
}
#thirdPartyLink {
-webkit-mask-image: url(chrome://resources/images/open_in_new.svg);
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 100%;
background-color: var(--cr-secondary-text-color);
height: 20px;
margin-inline-end: 24px;
width: 20px;
}
#uninstallThirdPartyButton {
margin: 16px 0;
} }
#themesContainer { #themesContainer {
...@@ -13,6 +62,7 @@ ...@@ -13,6 +62,7 @@
grid-column-gap: 25px; grid-column-gap: 25px;
grid-row-gap: 25px; grid-row-gap: 25px;
grid-template-columns: repeat(6, auto); grid-template-columns: repeat(6, auto);
width: fit-content;
} }
ntp-theme-icon { ntp-theme-icon {
...@@ -33,6 +83,26 @@ ...@@ -33,6 +83,26 @@
</style> </style>
<cr-dialog id="dialog"> <cr-dialog id="dialog">
<div slot="body"> <div slot="body">
<div id="thirdPartyThemeContainer" hidden="[[!isThirdPartyTheme_(theme_)]]">
<div id="thirdPartyTheme">
<div id="thirdPartyBrushIcon"></div>
<div id="thirdPartyThemeNameContainer">
<div id="thirdPartyThemeName" >
[[theme_.info.thirdPartyThemeInfo.name]]
</div>
<div>
$i18n{thirdPartyThemeDescription}
</div>
</div>
<a id="thirdPartyLink" target="_blank"
href$="https://chrome.google.com/webstore/detail/[[theme_.info.thirdPartyThemeInfo.id]]">
</a>
<cr-button id="uninstallThirdPartyButton"
on-click="onUninstallThirdPartyThemeClick_">
$i18n{uninstallThirdPartyThemeButton}
</cr-button>
</div>
</div>
<input id="colorPicker" type="color" on-change="onCustomFrameColorChange_" <input id="colorPicker" type="color" on-change="onCustomFrameColorChange_"
hidden> hidden>
</input> </input>
...@@ -42,7 +112,7 @@ ...@@ -42,7 +112,7 @@
on-click="onAutogeneratedThemeClick_" on-click="onAutogeneratedThemeClick_"
selected$="[[isThemeIconSelected_('autogenerated', theme_)]]"> selected$="[[isThemeIconSelected_('autogenerated', theme_)]]">
</ntp-theme-icon> </ntp-theme-icon>
<ntp-theme-icon id="defaultTheme" title="$i18n{defaultColorLabel}" <ntp-theme-icon id="defaultTheme" title="$i18n{defaultThemeLabel}"
on-click="onDefaultThemeClick_" on-click="onDefaultThemeClick_"
selected$="[[isThemeIconSelected_('default', theme_)]]"> selected$="[[isThemeIconSelected_('default', theme_)]]">
</ntp-theme-icon> </ntp-theme-icon>
......
...@@ -162,6 +162,15 @@ class CustomizeDialogElement extends PolymerElement { ...@@ -162,6 +162,15 @@ class CustomizeDialogElement extends PolymerElement {
this.$.themes.itemForElement(e.target).id); this.$.themes.itemForElement(e.target).id);
} }
/**
* @param {!Event} e
* @private
*/
onUninstallThirdPartyThemeClick_(e) {
this.pageHandler_.applyDefaultTheme();
this.pageHandler_.confirmThemeChanges();
}
/** /**
* @param {string|number} id * @param {string|number} id
* @return {boolean} * @return {boolean}
...@@ -180,6 +189,14 @@ class CustomizeDialogElement extends PolymerElement { ...@@ -180,6 +189,14 @@ class CustomizeDialogElement extends PolymerElement {
id === this.theme_.info.chromeThemeId; id === this.theme_.info.chromeThemeId;
} }
} }
/**
* @return {boolean}
* @private
*/
isThirdPartyTheme_() {
return this.theme_.type === newTabPage.mojom.ThemeType.THIRD_PARTY;
}
} }
customElements.define(CustomizeDialogElement.is, CustomizeDialogElement); customElements.define(CustomizeDialogElement.is, CustomizeDialogElement);
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M7 14c-1.66 0-3 1.34-3 3 0 1.31-1.16 2-2 2 .92 1.22 2.49 2 4 2 2.21 0 4-1.79 4-4 0-1.66-1.34-3-3-3zm13.71-9.37l-1.34-1.34a.996.996 0 0 0-1.41 0L9 12.25 11.75 15l8.96-8.96a.996.996 0 0 0 0-1.41z"/></svg>
\ No newline at end of file
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
<include name="IDR_NEW_TAB_PAGE_THEME_ICON_JS" <include name="IDR_NEW_TAB_PAGE_THEME_ICON_JS"
file="${root_gen_dir}/chrome/browser/resources/new_tab_page/theme_icon.js" file="${root_gen_dir}/chrome/browser/resources/new_tab_page/theme_icon.js"
use_base_dir="false" type="BINDATA" compress="gzip" /> use_base_dir="false" type="BINDATA" compress="gzip" />
<include name="IDR_NEW_TAB_PAGE_BRUSH_ICON_SVG"
file="icons/brush.svg" type="BINDATA" compress="gzip" />
</includes> </includes>
<structures> <structures>
<structure name="IDR_NEW_TAB_PAGE_NEW_TAB_PAGE_HTML" <structure name="IDR_NEW_TAB_PAGE_NEW_TAB_PAGE_HTML"
......
...@@ -42,11 +42,21 @@ enum ThemeType { ...@@ -42,11 +42,21 @@ enum ThemeType {
THIRD_PARTY, THIRD_PARTY,
}; };
// Additional info for third-party themes.
struct ThirdPartyThemeInfo {
// ID in the Chrome Web Store.
string id;
// Human-readable theme name.
string name;
};
union ThemeInfo { union ThemeInfo {
// Set if the theme is a Chrome theme. // Set if the theme is a Chrome theme.
int32 chrome_theme_id; int32 chrome_theme_id;
// Set if the theme is autogenerated. // Set if the theme is autogenerated.
ThemeColors autogenerated_theme_colors; ThemeColors autogenerated_theme_colors;
// Set if the theme is a third-party theme.
ThirdPartyThemeInfo third_party_theme_info;
}; };
// A generic theme. // A generic theme.
......
...@@ -24,10 +24,15 @@ namespace { ...@@ -24,10 +24,15 @@ namespace {
new_tab_page::mojom::ThemePtr MakeTheme(const NtpTheme& ntp_theme) { new_tab_page::mojom::ThemePtr MakeTheme(const NtpTheme& ntp_theme) {
auto theme = new_tab_page::mojom::Theme::New(); auto theme = new_tab_page::mojom::Theme::New();
if (ntp_theme.color_id == -1) { if (ntp_theme.using_default_theme) {
theme->type = ntp_theme.using_default_theme theme->type = new_tab_page::mojom::ThemeType::DEFAULT;
? new_tab_page::mojom::ThemeType::DEFAULT } else if (ntp_theme.color_id == -1) {
: new_tab_page::mojom::ThemeType::THIRD_PARTY; theme->type = new_tab_page::mojom::ThemeType::THIRD_PARTY;
auto info = new_tab_page::mojom::ThirdPartyThemeInfo::New();
info->id = ntp_theme.theme_id;
info->name = ntp_theme.theme_name;
theme->info =
new_tab_page::mojom::ThemeInfo::NewThirdPartyThemeInfo(std::move(info));
} else if (ntp_theme.color_id == 0) { } else if (ntp_theme.color_id == 0) {
theme->type = new_tab_page::mojom::ThemeType::AUTOGENERATED; theme->type = new_tab_page::mojom::ThemeType::AUTOGENERATED;
auto theme_colors = new_tab_page::mojom::ThemeColors::New(); auto theme_colors = new_tab_page::mojom::ThemeColors::New();
......
...@@ -62,8 +62,10 @@ content::WebUIDataSource* CreateNewTabPageUiHtmlSource() { ...@@ -62,8 +62,10 @@ content::WebUIDataSource* CreateNewTabPageUiHtmlSource() {
{"cancelButton", IDS_CANCEL}, {"cancelButton", IDS_CANCEL},
{"colorPickerLabel", IDS_NTP_CUSTOMIZE_COLOR_PICKER_LABEL}, {"colorPickerLabel", IDS_NTP_CUSTOMIZE_COLOR_PICKER_LABEL},
{"customizeButton", IDS_NTP_CUSTOMIZE_BUTTON_LABEL}, {"customizeButton", IDS_NTP_CUSTOMIZE_BUTTON_LABEL},
{"defaultColorLabel", IDS_NTP_CUSTOMIZE_DEFAULT_LABEL}, {"defaultThemeLabel", IDS_NTP_CUSTOMIZE_DEFAULT_LABEL},
{"doneButton", IDS_DONE}, {"doneButton", IDS_DONE},
{"thirdPartyThemeDescription", IDS_NTP_CUSTOMIZE_3PT_THEME_DESC},
{"uninstallThirdPartyThemeButton", IDS_NTP_CUSTOMIZE_3PT_THEME_UNINSTALL},
}; };
AddLocalizedStringsBulk(source, kStrings); AddLocalizedStringsBulk(source, kStrings);
......
...@@ -188,4 +188,70 @@ suite('NewTabPageCustomizeDialogTest', () => { ...@@ -188,4 +188,70 @@ suite('NewTabPageCustomizeDialogTest', () => {
assertEquals(selectedIcons.length, 1); assertEquals(selectedIcons.length, 1);
assertEquals(selectedIcons[0].getAttribute('title'), 'foo'); assertEquals(selectedIcons[0].getAttribute('title'), 'foo');
}); });
test('setting third-party theme shows uninstall UI', async () => {
// Arrange.
const customizeDialog = createCustomizeDialog();
// Act.
testProxy.callbackRouterRemote.setTheme({
type: newTabPage.mojom.ThemeType.THIRD_PARTY,
info: {
thirdPartyThemeInfo: {
id: 'foo',
name: 'bar',
},
}
});
await testProxy.callbackRouterRemote.$.flushForTesting();
// Assert.
assertStyle(customizeDialog.$.thirdPartyThemeContainer, 'display', 'block');
assertEquals(
customizeDialog.$.thirdPartyThemeName.textContent.trim(), 'bar');
assertEquals(
customizeDialog.$.thirdPartyLink.getAttribute('href'),
'https://chrome.google.com/webstore/detail/foo');
});
test('setting non-third-party theme hides uninstall UI', async () => {
// Arrange.
const customizeDialog = createCustomizeDialog();
// Act.
testProxy.callbackRouterRemote.setTheme({
type: newTabPage.mojom.ThemeType.DEFAULT,
info: {chromeThemeId: 0},
});
await testProxy.callbackRouterRemote.$.flushForTesting();
// Assert.
assertStyle(customizeDialog.$.thirdPartyThemeContainer, 'display', 'none');
});
test('uninstalling third-party theme sets default theme', async () => {
// Arrange.
const customizeDialog = createCustomizeDialog();
testProxy.callbackRouterRemote.setTheme({
type: newTabPage.mojom.ThemeType.THIRD_PARTY,
info: {
thirdPartyThemeInfo: {
id: 'foo',
name: 'bar',
},
}
});
await testProxy.callbackRouterRemote.$.flushForTesting();
const applyDefaultThemeCalled =
testProxy.handler.whenCalled('applyDefaultTheme');
const confirmThemeChangesCalled =
testProxy.handler.whenCalled('confirmThemeChanges');
// Act.
customizeDialog.$.uninstallThirdPartyButton.click();
// Assert.
await applyDefaultThemeCalled;
await confirmThemeChangesCalled;
});
}); });
...@@ -39,6 +39,7 @@ class FakePageHandler { ...@@ -39,6 +39,7 @@ class FakePageHandler {
'applyDefaultTheme', 'applyDefaultTheme',
'applyAutogeneratedTheme', 'applyAutogeneratedTheme',
'applyChromeTheme', 'applyChromeTheme',
'confirmThemeChanges',
]); ]);
} }
...@@ -117,6 +118,11 @@ class FakePageHandler { ...@@ -117,6 +118,11 @@ class FakePageHandler {
applyChromeTheme(id) { applyChromeTheme(id) {
this.callTracker_.methodCalled('applyChromeTheme', id); this.callTracker_.methodCalled('applyChromeTheme', id);
} }
/** @override */
confirmThemeChanges() {
this.callTracker_.methodCalled('confirmThemeChanges');
}
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment