diff --git a/browser/css/jsdialogs.css b/browser/css/jsdialogs.css
index 326bcd8bbb566..a7400810b7524 100644
--- a/browser/css/jsdialogs.css
+++ b/browser/css/jsdialogs.css
@@ -152,10 +152,6 @@
vertical-align: middle;
}
-.jsdialog.vertical:not(.sidebar):not(.ui-separator) {
- width: 100%;
-}
-
th.jsdialog:not(:first-child) {
padding-inline-end: 24px;
}
diff --git a/browser/css/toolbar.css b/browser/css/toolbar.css
index c3326103b7ea9..9916c33f2a6e6 100644
--- a/browser/css/toolbar.css
+++ b/browser/css/toolbar.css
@@ -60,6 +60,22 @@
margin: 0px;
}
+/* overflow menu */
+.menu-overflow-wrapper {
+ position: absolute;
+ height: var(--header-height);
+ top: var(--header-height);
+ display: flex;
+ background-color: var(--color-background-lighter);
+ border: 1px solid var(--color-toolbar-border);
+ align-items: center;
+ border-radius: 4px;
+ padding: 0 4px;
+ box-shadow: 0 2px 6px 2px rgba(60, 64, 67, .15);
+ opacity: 0;
+ pointer-events: none;
+}
+
/* status bar / mobile bottom bar */
#toolbar-down .ui-badge {
diff --git a/browser/images/dark/lc_menuoverflow.svg b/browser/images/dark/lc_menuoverflow.svg
new file mode 100644
index 0000000000000..1b5ba0a22f6eb
--- /dev/null
+++ b/browser/images/dark/lc_menuoverflow.svg
@@ -0,0 +1,70 @@
+
+
diff --git a/browser/images/lc_menuoverflow.svg b/browser/images/lc_menuoverflow.svg
new file mode 100644
index 0000000000000..d4b90d9e6d174
--- /dev/null
+++ b/browser/images/lc_menuoverflow.svg
@@ -0,0 +1,70 @@
+
+
diff --git a/browser/src/control/Control.TopToolbar.js b/browser/src/control/Control.TopToolbar.js
index 58f7a31414a02..77e8be3b9325a 100644
--- a/browser/src/control/Control.TopToolbar.js
+++ b/browser/src/control/Control.TopToolbar.js
@@ -188,6 +188,7 @@ class TopToolbar extends JSDialog.Toolbar {
{type: 'customtoolitem', id: 'insertannotation', text: _UNO('.uno:InsertAnnotation', '', true), visible: false, lockUno: '.uno:InsertAnnotation'},
{type: 'customtoolitem', id: 'inserthyperlink', command: 'inserthyperlink', text: _UNO('.uno:HyperlinkDialog', '', true), lockUno: '.uno:HyperlinkDialog'},
{type: 'toolitem', id: 'insertsymbol', text: _UNO('.uno:InsertSymbol', '', true), command: '.uno:InsertSymbol'},
+ {type: 'customtoolitem', id: 'menuoverflow', text: _('More'), desktop: true, mobile: false, visible: true},
{type: 'spacer', id: 'topspacer'},
{type: 'separator', orientation: 'vertical', id: 'breaksidebar', visible: false},
{type: 'toolitem', id: 'sidebar', text: _UNO('.uno:Sidebar', '', true), command: '.uno:SidebarDeck.PropertyDeck', visible: false},
@@ -226,14 +227,123 @@ class TopToolbar extends JSDialog.Toolbar {
}
}
+ createOverflowMenu() {
+ const topBarMenu = this.parentContainer.querySelector(
+ '.root-container .vertical',
+ );
+
+ const overflowMenu = L.DomUtil.create(
+ 'div',
+ 'menu-overflow-wrapper',
+ this.parentContainer,
+ );
+
+ const overflowMenuButton =
+ this.parentContainer.querySelector('#menuoverflow');
+
+ const showOverflowMenu = () => {
+ overflowMenu.style.opacity = 1;
+ overflowMenu.style.pointerEvents = 'revert';
+ L.DomUtil.addClass(overflowMenuButton, 'selected');
+ };
+
+ const hideOverflowMenu = () => {
+ overflowMenu.style.opacity = 0;
+ overflowMenu.style.pointerEvents = 'none';
+ L.DomUtil.removeClass(overflowMenuButton, 'selected');
+ };
+
+ overflowMenuButton.addEventListener('click', () => {
+ if (
+ overflowMenu.style.opacity === '0' ||
+ overflowMenu.style.opacity === ''
+ ) {
+ showOverflowMenu();
+ } else {
+ hideOverflowMenu();
+ }
+ });
+
+ const breakSidebar = this.parentContainer.querySelector('#breaksidebar');
+ const foldButton = this.parentContainer.querySelector('#fold');
+
+ const getMenuWidth = () => {
+ const splitPosition =
+ foldButton.offsetLeft +
+ foldButton.offsetWidth * 2 -
+ breakSidebar.offsetLeft;
+ return window.innerWidth - splitPosition;
+ };
+
+ let overflowMenuDebounced = 0;
+ const originalTopbar = topBarMenu.querySelectorAll('.jsdialog');
+
+ const overflowMenuHandler = () => {
+ overflowMenuDebounced && clearTimeout(overflowMenuDebounced);
+
+ hideOverflowMenu();
+
+ overflowMenuDebounced = setTimeout(() => {
+ topBarMenu.replaceChildren(...originalTopbar);
+
+ const topBarButtons = topBarMenu.querySelectorAll('.jsdialog:not(.hidden)');
+ const menuWidth = getMenuWidth();
+
+ const overflowMenuOffscreen = document.createElement('div');
+ overflowMenuOffscreen.className = "menu-overfow-vertical";
+
+ let section = [];
+ let overflow = false;
+
+ const appendSection = () => {
+ for (const element of section) {
+ overflowMenuOffscreen.appendChild(element);
+ }
+ section.length = 0;
+ };
+
+ for (const button of topBarButtons) {
+ if (button.id === 'topspacer' || button.id === 'menuoverflow') {
+ break;
+ }
+
+ if (button.offsetLeft > menuWidth || overflow) {
+ overflow = true;
+ appendSection();
+ overflowMenuOffscreen.appendChild(button);
+ } else if (button.className.includes('vertical')) {
+ section = [button];
+ } else {
+ section.push(button);
+ }
+ }
+
+ overflowMenu.replaceChildren(overflowMenuOffscreen);
+
+ if (overflowMenuOffscreen.children.length <= 0) {
+ overflowMenuButton.style.display = 'none';
+ } else {
+ overflowMenuButton.style.display = 'revert';
+ }
+
+ overflowMenu.style.left =
+ overflowMenuButton.offsetLeft -
+ overflowMenu.clientWidth +
+ overflowMenuButton.offsetWidth +
+ 'px';
+ }, 250);
+ };
+
+ window.addEventListener('resize', overflowMenuHandler);
+ }
+
create() {
this.reset();
var items = this.getToolItems();
this.builder.build(this.parentContainer, items);
- JSDialog.MakeScrollable(this.parentContainer, this.parentContainer.querySelector('div'));
- JSDialog.RefreshScrollables();
+ this.createOverflowMenu();
if (this.map.isRestrictedUser()) {
for (var i = 0; i < items.length; i++) {
@@ -254,8 +364,7 @@ class TopToolbar extends JSDialog.Toolbar {
this.map.createFontSelector('#fontnamecombobox-input');
// on mode switch NB -> Compact
- if (this.map._docLoadedOnce)
- this.onDocLayerInit();
+ if (this.map._docLoadedOnce) this.onDocLayerInit();
}
onDocLayerInit() {