mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
refactored chrome tabs into "tab row"
This commit is contained in:
parent
8a501521e8
commit
bd97df5ee9
@ -1,144 +0,0 @@
|
|||||||
.chrome-tabs {
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
height: 33px;
|
|
||||||
background: var(--main-background-color);
|
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
overflow: hidden;
|
|
||||||
grid-area: tabs;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
.chrome-tabs * {
|
|
||||||
box-sizing: inherit;
|
|
||||||
font: inherit;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tabs-content {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
height: 36px;
|
|
||||||
width: 240px;
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab[active] {
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab,
|
|
||||||
.chrome-tabs .chrome-tab * {
|
|
||||||
user-select: none;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab.chrome-tab-was-just-added {
|
|
||||||
top: 10px;
|
|
||||||
animation: chrome-tab-was-just-added 120ms forwards ease-in-out;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab .chrome-tab-content {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: var(--tab-content-margin);
|
|
||||||
right: var(--tab-content-margin);
|
|
||||||
padding: 5px 8px;
|
|
||||||
border-top-left-radius: 8px;
|
|
||||||
border-top-right-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
pointer-events: all;
|
|
||||||
background-color: var(--accented-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab[active] .chrome-tab-content {
|
|
||||||
background-color: var(--more-accented-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab[is-mini] .chrome-tab-content {
|
|
||||||
padding-left: 2px;
|
|
||||||
padding-right: 2px;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab .chrome-tab-title {
|
|
||||||
flex: 1;
|
|
||||||
vertical-align: top;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
color: var(--muted-text-color);
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab[is-small] .chrome-tab-title {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab[active] .chrome-tab-title {
|
|
||||||
color: var(--main-text-color);
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab .chrome-tab-drag-handle {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
left: 0;
|
|
||||||
border-top-left-radius: 8px;
|
|
||||||
border-top-right-radius: 8px;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab .chrome-tab-close {
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
border-radius: 50%;
|
|
||||||
z-index: 100;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab .chrome-tab-close span {
|
|
||||||
font-size: 24px;
|
|
||||||
position: relative;
|
|
||||||
top: -6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab .chrome-tab-close:hover {
|
|
||||||
background-color: var(--hover-item-background-color);
|
|
||||||
color: var(--hover-item-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chrome-tabs .chrome-tab[is-smaller] .chrome-tab-close {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab[is-mini]:not([active]) .chrome-tab-close {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chrome-tabs .chrome-tab[is-mini][active] .chrome-tab-close {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
@-moz-keyframes chrome-tab-was-just-added {
|
|
||||||
to {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@-webkit-keyframes chrome-tab-was-just-added {
|
|
||||||
to {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@-o-keyframes chrome-tab-was-just-added {
|
|
||||||
to {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes chrome-tab-was-just-added {
|
|
||||||
to {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.chrome-tabs.chrome-tabs-is-sorting .chrome-tab:not(.chrome-tab-is-dragging),
|
|
||||||
.chrome-tabs:not(.chrome-tabs-is-sorting) .chrome-tab.chrome-tab-was-just-dragged {
|
|
||||||
transition: transform 120ms ease-in-out;
|
|
||||||
}
|
|
@ -10,10 +10,7 @@ import utils from "./utils.js";
|
|||||||
import importDialog from "../dialogs/import.js";
|
import importDialog from "../dialogs/import.js";
|
||||||
import contextMenuService from "./context_menu.js";
|
import contextMenuService from "./context_menu.js";
|
||||||
import treeUtils from "./tree_utils.js";
|
import treeUtils from "./tree_utils.js";
|
||||||
|
import tabRow from "./tab_row.js";
|
||||||
const chromeTabsEl = document.querySelector('.chrome-tabs');
|
|
||||||
const chromeTabs = new ChromeTabs();
|
|
||||||
chromeTabs.init(chromeTabsEl);
|
|
||||||
|
|
||||||
const $tabContentsContainer = $("#note-tab-container");
|
const $tabContentsContainer = $("#note-tab-container");
|
||||||
const $savedIndicator = $(".saved-indicator");
|
const $savedIndicator = $(".saved-indicator");
|
||||||
@ -190,7 +187,7 @@ async function loadNoteDetail(notePath, options = {}) {
|
|||||||
|
|
||||||
if (tabContexts.length === 0 || newTab) {
|
if (tabContexts.length === 0 || newTab) {
|
||||||
// if it's a new tab explicitly by user then it's in background
|
// if it's a new tab explicitly by user then it's in background
|
||||||
ctx = new TabContext(chromeTabs, newTab);
|
ctx = new TabContext(tabRow);
|
||||||
tabContexts.push(ctx);
|
tabContexts.push(ctx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -210,7 +207,7 @@ async function loadNoteDetail(notePath, options = {}) {
|
|||||||
|
|
||||||
if (activate) {
|
if (activate) {
|
||||||
// will also trigger showTab via event
|
// will also trigger showTab via event
|
||||||
chromeTabs.setCurrentTab(ctx.tab);
|
tabRow.setCurrentTab(ctx.tab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +219,7 @@ async function loadNote(noteId) {
|
|||||||
|
|
||||||
async function filterTabs(noteId) {
|
async function filterTabs(noteId) {
|
||||||
for (const tc of tabContexts) {
|
for (const tc of tabContexts) {
|
||||||
chromeTabs.removeTab(tc.tab);
|
tabRow.removeTab(tc.tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
await loadNoteDetail(noteId, {
|
await loadNoteDetail(noteId, {
|
||||||
@ -287,7 +284,7 @@ $tabContentsContainer.on("drop", e => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
chromeTabsEl.addEventListener('activeTabChange', ({ detail }) => {
|
tabRow.el.addEventListener('activeTabChange', ({ detail }) => {
|
||||||
const tabId = detail.tabEl.getAttribute('data-tab-id');
|
const tabId = detail.tabEl.getAttribute('data-tab-id');
|
||||||
|
|
||||||
showTab(tabId);
|
showTab(tabId);
|
||||||
@ -295,7 +292,7 @@ chromeTabsEl.addEventListener('activeTabChange', ({ detail }) => {
|
|||||||
console.log(`Activated tab ${tabId}`);
|
console.log(`Activated tab ${tabId}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
chromeTabsEl.addEventListener('tabRemove', async ({ detail }) => {
|
tabRow.el.addEventListener('tabRemove', async ({ detail }) => {
|
||||||
const tabId = parseInt(detail.tabEl.getAttribute('data-tab-id'));
|
const tabId = parseInt(detail.tabEl.getAttribute('data-tab-id'));
|
||||||
|
|
||||||
await saveNotesIfChanged();
|
await saveNotesIfChanged();
|
||||||
@ -311,8 +308,8 @@ chromeTabsEl.addEventListener('tabRemove', async ({ detail }) => {
|
|||||||
console.log(`Removed tab ${tabId}`);
|
console.log(`Removed tab ${tabId}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(chromeTabsEl).on('contextmenu', '.chrome-tab', e => {
|
$(tabRow.el).on('contextmenu', '.note-tab', e => {
|
||||||
const tab = $(e.target).closest(".chrome-tab");
|
const tab = $(e.target).closest(".note-tab");
|
||||||
|
|
||||||
contextMenuService.initContextMenu(e, {
|
contextMenuService.initContextMenu(e, {
|
||||||
getContextMenuItems: () => {
|
getContextMenuItems: () => {
|
||||||
@ -322,7 +319,7 @@ $(chromeTabsEl).on('contextmenu', '.chrome-tab', e => {
|
|||||||
},
|
},
|
||||||
selectContextMenuItem: (e, cmd) => {
|
selectContextMenuItem: (e, cmd) => {
|
||||||
if (cmd === 'removeAllTabsExceptForThis') {
|
if (cmd === 'removeAllTabsExceptForThis') {
|
||||||
chromeTabs.removeAllTabsExceptForThis(tab[0]);
|
tabRow.removeAllTabsExceptForThis(tab[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -335,30 +332,30 @@ if (utils.isElectron()) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
chromeTabs.removeTab(chromeTabs.activeTabEl);
|
tabRow.removeTab(tabRow.activeTabEl);
|
||||||
});
|
});
|
||||||
|
|
||||||
utils.bindShortcut('ctrl+tab', () => {
|
utils.bindShortcut('ctrl+tab', () => {
|
||||||
const nextTab = chromeTabs.nextTabEl;
|
const nextTab = tabRow.nextTabEl;
|
||||||
|
|
||||||
if (nextTab) {
|
if (nextTab) {
|
||||||
chromeTabs.setCurrentTab(nextTab);
|
tabRow.setCurrentTab(nextTab);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
utils.bindShortcut('ctrl+shift+tab', () => {
|
utils.bindShortcut('ctrl+shift+tab', () => {
|
||||||
const prevTab = chromeTabs.previousTabEl;
|
const prevTab = tabRow.previousTabEl;
|
||||||
|
|
||||||
if (prevTab) {
|
if (prevTab) {
|
||||||
chromeTabs.setCurrentTab(prevTab);
|
tabRow.setCurrentTab(prevTab);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
chromeTabsEl.addEventListener('activeTabChange', openTabsChanged);
|
tabRow.el.addEventListener('activeTabChange', openTabsChanged);
|
||||||
chromeTabsEl.addEventListener('tabAdd', openTabsChanged);
|
tabRow.el.addEventListener('tabAdd', openTabsChanged);
|
||||||
chromeTabsEl.addEventListener('tabRemove', openTabsChanged);
|
tabRow.el.addEventListener('tabRemove', openTabsChanged);
|
||||||
chromeTabsEl.addEventListener('tabReorder', openTabsChanged);
|
tabRow.el.addEventListener('tabReorder', openTabsChanged);
|
||||||
|
|
||||||
let tabsChangedTaskId = null;
|
let tabsChangedTaskId = null;
|
||||||
|
|
||||||
@ -378,10 +375,10 @@ function openTabsChanged() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function saveOpenTabs() {
|
async function saveOpenTabs() {
|
||||||
const activeTabEl = chromeTabs.activeTabEl;
|
const activeTabEl = tabRow.activeTabEl;
|
||||||
const openTabs = [];
|
const openTabs = [];
|
||||||
|
|
||||||
for (const tabEl of chromeTabs.tabEls) {
|
for (const tabEl of tabRow.tabEls) {
|
||||||
const tabId = parseInt(tabEl.getAttribute('data-tab-id'));
|
const tabId = parseInt(tabEl.getAttribute('data-tab-id'));
|
||||||
const tabContext = tabContexts.find(tc => tc.tabId === tabId);
|
const tabContext = tabContexts.find(tc => tc.tabId === tabId);
|
||||||
|
|
||||||
|
@ -33,10 +33,13 @@ const componentClasses = {
|
|||||||
let tabIdCounter = 1;
|
let tabIdCounter = 1;
|
||||||
|
|
||||||
class TabContext {
|
class TabContext {
|
||||||
constructor(chromeTabs) {
|
/**
|
||||||
|
* @param {TabRow} tabRow
|
||||||
|
*/
|
||||||
|
constructor(tabRow) {
|
||||||
this.tabId = tabIdCounter++;
|
this.tabId = tabIdCounter++;
|
||||||
this.chromeTabs = chromeTabs;
|
this.tabRow = tabRow;
|
||||||
this.tab = this.chromeTabs.addTab({
|
this.tab = this.tabRow.addTab({
|
||||||
title: '', // will be set later
|
title: '', // will be set later
|
||||||
id: this.tabId
|
id: this.tabId
|
||||||
}, {
|
}, {
|
||||||
@ -84,7 +87,7 @@ class TabContext {
|
|||||||
this.tab.setAttribute('data-note-id', this.noteId);
|
this.tab.setAttribute('data-note-id', this.noteId);
|
||||||
this.$tabContent.attr('data-note-id', note.noteId);
|
this.$tabContent.attr('data-note-id', note.noteId);
|
||||||
|
|
||||||
this.chromeTabs.updateTab(this.tab, {title: note.title});
|
this.tabRow.updateTab(this.tab, {title: note.title});
|
||||||
|
|
||||||
this.attributes.invalidateAttributes();
|
this.attributes.invalidateAttributes();
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -167,4 +167,149 @@ li.dropdown-submenu:hover > ul.dropdown-menu {
|
|||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row {
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
height: 33px;
|
||||||
|
background: var(--main-background-color);
|
||||||
|
border-radius: 5px 5px 0 0;
|
||||||
|
overflow: hidden;
|
||||||
|
grid-area: tabs;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.note-tab-row * {
|
||||||
|
box-sizing: inherit;
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab-row-content {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
height: 36px;
|
||||||
|
width: 240px;
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab[active] {
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab,
|
||||||
|
.note-tab-row .note-tab * {
|
||||||
|
user-select: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab.note-tab-was-just-added {
|
||||||
|
top: 10px;
|
||||||
|
animation: note-tab-was-just-added 120ms forwards ease-in-out;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab .note-tab-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: var(--tab-content-margin);
|
||||||
|
right: var(--tab-content-margin);
|
||||||
|
padding: 5px 8px;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: all;
|
||||||
|
background-color: var(--accented-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab[active] .note-tab-wrapper {
|
||||||
|
background-color: var(--more-accented-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab[is-mini] .note-tab-wrapper {
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab .note-tab-title {
|
||||||
|
flex: 1;
|
||||||
|
vertical-align: top;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: var(--muted-text-color);
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab[is-small] .note-tab-title {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab[active] .note-tab-title {
|
||||||
|
color: var(--main-text-color);
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab .note-tab-drag-handle {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab .note-tab-close {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
z-index: 100;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab .note-tab-close span {
|
||||||
|
font-size: 24px;
|
||||||
|
position: relative;
|
||||||
|
top: -6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab .note-tab-close:hover {
|
||||||
|
background-color: var(--hover-item-background-color);
|
||||||
|
color: var(--hover-item-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-tab-row .note-tab[is-smaller] .note-tab-close {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab[is-mini]:not([active]) .note-tab-close {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.note-tab-row .note-tab[is-mini][active] .note-tab-close {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
@-moz-keyframes note-tab-was-just-added {
|
||||||
|
to {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes note-tab-was-just-added {
|
||||||
|
to {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes note-tab-was-just-added {
|
||||||
|
to {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes note-tab-was-just-added {
|
||||||
|
to {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.note-tab-row.note-tab-row-is-sorting .note-tab:not(.note-tab-is-dragging),
|
||||||
|
.note-tab-row:not(.note-tab-row-is-sorting) .note-tab.note-tab-was-just-dragged {
|
||||||
|
transition: transform 120ms ease-in-out;
|
||||||
}
|
}
|
@ -210,9 +210,6 @@
|
|||||||
|
|
||||||
<script src="libraries/dayjs.min.js"></script>
|
<script src="libraries/dayjs.min.js"></script>
|
||||||
|
|
||||||
<script src="libraries/chrome-tabs/chrome-tabs.js"></script>
|
|
||||||
<link href="libraries/chrome-tabs/chrome-tabs.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<link href="stylesheets/themes.css" rel="stylesheet">
|
<link href="stylesheets/themes.css" rel="stylesheet">
|
||||||
<link href="stylesheets/style.css" rel="stylesheet">
|
<link href="stylesheets/style.css" rel="stylesheet">
|
||||||
<link href="stylesheets/desktop.css" rel="stylesheet">
|
<link href="stylesheets/desktop.css" rel="stylesheet">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="chrome-tabs">
|
<div class="note-tab-row">
|
||||||
<div class="chrome-tabs-content"></div>
|
<div class="note-tab-row-content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="note-tab-container">
|
<div id="note-tab-container">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user