Skip to content

Commit 33bf228

Browse files
author
mstriemer
committed
Bug 1883941 - Add sidebar launcher to sidebar r=Gijs
* Add a cleaned-up sidebar-launcher component and put behind a pref Differential Revision: https://phabricator.services.mozilla.com/D204217
1 parent c7362ab commit 33bf228

File tree

12 files changed

+275
-24
lines changed

12 files changed

+275
-24
lines changed

browser/app/profile/firefox.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,10 +1847,9 @@ pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
18471847
// Try to convert PDFs sent as octet-stream
18481848
pref("pdfjs.handleOctetStream", true);
18491849

1850-
pref("sidebar.companion", false);
1851-
18521850
// Is the sidebar positioned ahead of the content browser
18531851
pref("sidebar.position_start", true);
1852+
pref("sidebar.revamp", false);
18541853

18551854
pref("security.protectionspopup.recordEventTelemetry", true);
18561855
pref("security.app_menu.recordEventTelemetry", true);

browser/base/content/browser-box.inc.xhtml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

55
<hbox flex="1" id="browser">
6+
<html:sidebar-launcher id="sidebar-launcher" flex="1" hidden="true"></html:sidebar-launcher>
67
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
78
<box id="sidebar-header" align="center">
89
<toolbarbutton id="sidebar-switcher-target" class="tabbable" aria-expanded="false">

browser/base/content/browser-sidebar.js

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ var SidebarUI = {
9898
return this._inited;
9999
},
100100

101-
init() {
101+
async init() {
102102
this._box = document.getElementById("sidebar-box");
103103
this._splitter = document.getElementById("sidebar-splitter");
104104
this._reversePositionButton = document.getElementById(
@@ -108,12 +108,18 @@ var SidebarUI = {
108108
this._switcherTarget = document.getElementById("sidebar-switcher-target");
109109
this._switcherArrow = document.getElementById("sidebar-switcher-arrow");
110110

111-
this._switcherTarget.addEventListener("command", () => {
112-
this.toggleSwitcherPanel();
113-
});
114-
this._switcherTarget.addEventListener("keydown", event => {
115-
this.handleKeydown(event);
116-
});
111+
if (this.sidebarRevampEnabled) {
112+
await import("chrome://browser/content/sidebar/sidebar-launcher.mjs");
113+
document.getElementById("sidebar-launcher").hidden = false;
114+
document.getElementById("sidebar-header").hidden = true;
115+
} else {
116+
this._switcherTarget.addEventListener("command", () => {
117+
this.toggleSwitcherPanel();
118+
});
119+
this._switcherTarget.addEventListener("keydown", event => {
120+
this.handleKeydown(event);
121+
});
122+
}
117123

118124
this._inited = true;
119125

@@ -292,19 +298,25 @@ var SidebarUI = {
292298
[...browser.children].forEach((node, i) => {
293299
node.style.order = i + 1;
294300
});
301+
let sidebarLauncher = document.querySelector("sidebar-launcher");
295302

296303
if (!this._positionStart) {
297-
// DOM ordering is: | sidebar-box | splitter | appcontent |
298-
// Want to display as: | appcontent | splitter | sidebar-box |
299-
// So we just swap box and appcontent ordering
304+
// DOM ordering is: sidebar-launcher | sidebar-box | splitter | appcontent |
305+
// Want to display as: | appcontent | splitter | sidebar-box | sidebar-launcher
306+
// So we just swap box and appcontent ordering and move sidebar-launcher to the end
300307
let appcontent = document.getElementById("appcontent");
301308
let boxOrdinal = this._box.style.order;
302309
this._box.style.order = appcontent.style.order;
310+
303311
appcontent.style.order = boxOrdinal;
312+
// the launcher should be on the right of the sidebar-box
313+
sidebarLauncher.style.order = parseInt(this._box.style.order) + 1;
304314
// Indicate we've switched ordering to the box
305315
this._box.setAttribute("positionend", true);
316+
sidebarLauncher.setAttribute("positionend", true);
306317
} else {
307318
this._box.removeAttribute("positionend");
319+
sidebarLauncher.removeAttribute("positionend");
308320
}
309321

310322
this.hideSwitcherPanel();
@@ -563,21 +575,30 @@ var SidebarUI = {
563575
*/
564576
_show(commandID) {
565577
return new Promise(resolve => {
566-
this.selectMenuItem(commandID);
578+
if (this.sidebarRevampEnabled) {
579+
this._box.dispatchEvent(
580+
new CustomEvent("sidebar-show", { detail: { viewId: commandID } })
581+
);
582+
} else {
583+
this.hideSwitcherPanel();
584+
}
567585

586+
this.selectMenuItem(commandID);
568587
this._box.hidden = this._splitter.hidden = false;
588+
// sets the sidebar to the left or right, based on a pref
569589
this.setPosition();
570590

571-
this.hideSwitcherPanel();
572-
573591
this._box.setAttribute("checked", "true");
574592
this._box.setAttribute("sidebarcommand", commandID);
575-
this.lastOpenedId = commandID;
576593

577594
let { url, title, sourceL10nEl } = this.sidebars.get(commandID);
595+
596+
// use to live update <tree> elements if the locale changes
597+
this.lastOpenedId = commandID;
578598
this.title = title;
579-
// Keep the title element in sync with any l10n changes.
599+
// Keep the title element in the switcher in sync with any l10n changes.
580600
this.observeTitleChanges(sourceL10nEl);
601+
581602
this.browser.setAttribute("src", url); // kick off async load
582603

583604
if (this.browser.contentDocument.location.href != url) {
@@ -616,7 +637,9 @@ var SidebarUI = {
616637
}
617638

618639
this.hideSwitcherPanel();
619-
640+
if (this.sidebarRevampEnabled) {
641+
this._box.dispatchEvent(new CustomEvent("sidebar-hide"));
642+
}
620643
this.selectMenuItem("");
621644

622645
// Replace the document currently displayed in the sidebar with about:blank
@@ -672,3 +695,9 @@ XPCOMUtils.defineLazyPreferenceGetter(
672695
true,
673696
SidebarUI.setPosition.bind(SidebarUI)
674697
);
698+
XPCOMUtils.defineLazyPreferenceGetter(
699+
SidebarUI,
700+
"sidebarRevampEnabled",
701+
"sidebar.revamp",
702+
false
703+
);

browser/base/content/browser.xhtml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
<link rel="localization" href="preview/select-translations.ftl"/>
9696
<link rel="localization" href="browser/shopping.ftl"/>
9797
<link rel="localization" href="preview/shopping.ftl"/>
98+
<link rel="localization" href="preview/sidebar.ftl"/>
9899
<link rel="localization" href="preview/profiles.ftl"/>
99100
<link rel="localization" href="preview/onboarding.ftl"/>
100101

browser/base/content/test/sidebar/browser_sidebar_move.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ registerCleanupFunction(() => {
44
});
55

66
const EXPECTED_START_ORDINALS = [
7-
["sidebar-box", 1],
8-
["sidebar-splitter", 2],
9-
["appcontent", 3],
7+
["sidebar-launcher", 1],
8+
["sidebar-box", 2],
9+
["sidebar-splitter", 3],
10+
["appcontent", 4],
1011
];
1112

1213
const EXPECTED_END_ORDINALS = [
13-
["sidebar-box", 3],
14-
["sidebar-splitter", 2],
15-
["appcontent", 1],
14+
["sidebar-launcher", 5],
15+
["sidebar-box", 4],
16+
["sidebar-splitter", 3],
17+
["appcontent", 2],
1618
];
1719

1820
function getBrowserChildrenWithOrdinals() {

browser/components/sidebar/jar.mn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

55
browser.jar:
6+
content/browser/sidebar/sidebar-launcher.css
7+
content/browser/sidebar/sidebar-launcher.mjs
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4+
5+
.wrapper {
6+
display: grid;
7+
grid-template-rows: auto 1fr;
8+
box-sizing: border-box;
9+
height: 100%;
10+
padding: var(--space-medium);
11+
border-inline-end: 1px solid var(--chrome-content-separator-color);
12+
background-color: var(--sidebar-background-color);
13+
color: var(--sidebar-text-color);
14+
:host([positionend]) & {
15+
border-inline-start: 1px solid var(--chrome-content-separator-color);
16+
border-inline-end: none;;
17+
}
18+
}
19+
20+
:host([positionend]) {
21+
.wrapper {
22+
border-inline-start: 1px solid var(--chrome-content-separator-color);
23+
}
24+
}
25+
26+
.actions-list {
27+
display: flex;
28+
flex-direction: column;
29+
justify-content: end;
30+
}
31+
32+
.icon-button::part(button) {
33+
background-image: var(--action-icon);
34+
}
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
import {
6+
html,
7+
ifDefined,
8+
styleMap,
9+
} from "chrome://global/content/vendor/lit.all.mjs";
10+
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
11+
12+
// eslint-disable-next-line import/no-unassigned-import
13+
import "chrome://global/content/elements/moz-button.mjs";
14+
15+
/**
16+
* Vertical strip attached to the launcher that provides an entry point
17+
* to various sidebar panels.
18+
*
19+
*/
20+
export default class SidebarLauncher extends MozLitElement {
21+
static properties = {
22+
topActions: { type: Array },
23+
bottomActions: { type: Array },
24+
selectedView: { type: String },
25+
open: { type: Boolean },
26+
};
27+
28+
constructor() {
29+
super();
30+
this.topActions = [
31+
{
32+
icon: `url("chrome://browser/skin/insights.svg")`,
33+
view: null,
34+
l10nId: "sidebar-launcher-insights",
35+
},
36+
];
37+
38+
this.bottomActions = [
39+
{
40+
l10nId: "sidebar-menu-history",
41+
icon: `url("chrome://browser/content/firefoxview/view-history.svg")`,
42+
view: "viewHistorySidebar",
43+
},
44+
{
45+
l10nId: "sidebar-menu-bookmarks",
46+
icon: `url("chrome://browser/skin/bookmark-hollow.svg")`,
47+
view: "viewBookmarksSidebar",
48+
},
49+
{
50+
l10nId: "sidebar-menu-synced-tabs",
51+
icon: `url("chrome://browser/skin/device-phone.svg")`,
52+
view: "viewTabsSidebar",
53+
},
54+
];
55+
56+
this.selectedView = window.SidebarUI.currentID;
57+
this.open = window.SidebarUI.isOpen;
58+
this.menuMutationObserver = new MutationObserver(() =>
59+
this.#setExtensionItems()
60+
);
61+
}
62+
63+
connectedCallback() {
64+
super.connectedCallback();
65+
this._sidebarBox = document.getElementById("sidebar-box");
66+
this._sidebarBox.addEventListener("sidebar-show", this);
67+
this._sidebarBox.addEventListener("sidebar-hide", this);
68+
this._sidebarMenu = document.getElementById("viewSidebarMenu");
69+
70+
this.menuMutationObserver.observe(this._sidebarMenu, {
71+
childList: true,
72+
subtree: true,
73+
});
74+
this.#setExtensionItems();
75+
}
76+
77+
disconnectedCallback() {
78+
super.disconnectedCallback();
79+
this._sidebarBox.removeEventListener("sidebar-show", this);
80+
this._sidebarBox.removeEventListener("sidebar-hide", this);
81+
this.menuMutationObserver.disconnect();
82+
}
83+
84+
getImageUrl(icon, targetURI) {
85+
if (window.IS_STORYBOOK) {
86+
return `chrome://global/skin/icons/defaultFavicon.svg`;
87+
}
88+
if (!icon) {
89+
if (targetURI?.startsWith("moz-extension")) {
90+
return "chrome://mozapps/skin/extensions/extension.svg";
91+
}
92+
return `chrome://global/skin/icons/defaultFavicon.svg`;
93+
}
94+
// If the icon is not for website (doesn't begin with http), we
95+
// display it directly. Otherwise we go through the page-icon
96+
// protocol to try to get a cached version. We don't load
97+
// favicons directly.
98+
if (icon.startsWith("http")) {
99+
return `page-icon:${targetURI}`;
100+
}
101+
return icon;
102+
}
103+
104+
#setExtensionItems() {
105+
for (let item of this._sidebarMenu.children) {
106+
if (item.id.endsWith("-sidebar-action")) {
107+
this.topActions.push({
108+
tooltiptext: item.label,
109+
icon: item.style.getPropertyValue("--webextension-menuitem-image"),
110+
view: item.id.slice("menubar_menu_".length),
111+
});
112+
}
113+
}
114+
}
115+
116+
handleEvent(e) {
117+
switch (e.type) {
118+
case "sidebar-show":
119+
this.selectedView = e.detail.viewId;
120+
this.open = true;
121+
break;
122+
case "sidebar-hide":
123+
this.open = false;
124+
break;
125+
}
126+
}
127+
128+
showView(e) {
129+
let view = e.target.getAttribute("view");
130+
window.SidebarUI.toggle(view);
131+
}
132+
133+
buttonType(action) {
134+
return this.open && action.view == this.selectedView
135+
? "icon"
136+
: "icon ghost";
137+
}
138+
139+
entrypointTemplate(action) {
140+
return html`<moz-button
141+
class="icon-button"
142+
type=${this.buttonType(action)}
143+
view=${action.view}
144+
@click=${action.view ? this.showView : null}
145+
title=${ifDefined(action.tooltiptext)}
146+
data-l10n-id=${ifDefined(action.l10nId)}
147+
style=${styleMap({ "--action-icon": action.icon })}
148+
>
149+
</moz-button>`;
150+
}
151+
152+
render() {
153+
return html`
154+
<link
155+
rel="stylesheet"
156+
href="chrome://browser/content/sidebar/sidebar-launcher.css"
157+
/>
158+
<div class="wrapper">
159+
<div class="top-actions actions-list">
160+
${this.topActions.map(action => this.entrypointTemplate(action))}
161+
</div>
162+
<div class="bottom-actions actions-list">
163+
${this.bottomActions.map(action => this.entrypointTemplate(action))}
164+
</div>
165+
</div>
166+
`;
167+
}
168+
}
169+
customElements.define("sidebar-launcher", SidebarLauncher);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this
3+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
sidebar-launcher-insights =
6+
.title = Insights

browser/locales/jar.mn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
preview/interventions.ftl (../components/urlbar/content/interventions.ftl)
1414
preview/enUS-searchFeatures.ftl (../components/urlbar/content/enUS-searchFeatures.ftl)
1515
preview/shopping.ftl (../components/shopping/content/shopping.ftl)
16+
preview/sidebar.ftl (../components/sidebar/sidebar.ftl)
1617
preview/onboarding.ftl (../components/aboutwelcome/content/onboarding.ftl)
1718
preview/select-translations.ftl (../locales-preview/select-translations.ftl)
1819
preview/translations.ftl (../locales-preview/translations.ftl)

0 commit comments

Comments
 (0)