diff --git a/package.json b/package.json index 196127130..d0fc05677 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,9 @@ "update-ff:raw": "surfer update", "update-ff:rc": "python3 scripts/update_ff.py --rc", "update-ff:l10n": "python3 scripts/update_ff.py --just-l10n", - "pretty": "prettier . --write && autopep8 -r --in-place scripts/ src/", + "pretty": "prettier . --write --cache && autopep8 -r --in-place scripts/ src/", "lint": "npx eslint src/ && prettier . --check && autopep8 --diff scripts/ src/", - "lint:fix": "npx eslint src/ --fix && npm run pretty", + "lint:fix": "npm run pretty && npx eslint src/ --fix", "prepare": "husky", "reset-ff": "surfer reset", "surfer": "surfer", diff --git a/src/zen/folders/ZenFolder.mjs b/src/zen/folders/ZenFolder.mjs index ac75e310d..8613a1cae 100644 --- a/src/zen/folders/ZenFolder.mjs +++ b/src/zen/folders/ZenFolder.mjs @@ -33,41 +33,21 @@ - - - - + - - - - + - - - - + - - - - + - + - - - - - - - - - + @@ -89,13 +69,6 @@ this.#initialized = true; this._activeTabs = []; this.icon.appendChild(ZenFolder.rawIcon.cloneNode(true)); - // Save original values for animations - this.icon.querySelectorAll('animate, animateTransform, animateMotion').forEach((anim) => { - const vals = anim.getAttribute('values'); - if (vals) { - anim.dataset.origValues = vals; - } - }); this.labelElement.parentElement.setAttribute('context', 'zenFolderActions'); diff --git a/src/zen/folders/ZenFolders.mjs b/src/zen/folders/ZenFolders.mjs index c93084e46..ba57639df 100644 --- a/src/zen/folders/ZenFolders.mjs +++ b/src/zen/folders/ZenFolders.mjs @@ -40,7 +40,6 @@ #lastFolderContextMenu = null; #foldersEnabled = false; - #folderAnimCache = new Map(); #animationCount = 0; @@ -304,7 +303,7 @@ folder.removeAttribute('has-active'); } this.collapseVisibleTab(folder, true); - this.updateFolderIcon(folder, 'close', false); + this.updateFolderIcon(folder, 'close'); } } } @@ -721,7 +720,7 @@ async #convertFolderToSpace(folder) { const currentWorkspace = gZenWorkspaces.getActiveWorkspaceFromCache(); let selectedTab = folder.tabs.find((tab) => tab.selected); - const icon = folder.icon?.querySelector('svg #folder-icon image'); + const icon = folder.icon?.querySelector('svg .icon image'); const newSpace = await gZenWorkspaces.createAndSaveWorkspace( folder.label, @@ -855,7 +854,7 @@ gBrowser.TabStateFlusher.flush(tab.linkedBrowser); }); - this.updateFolderIcon(folder, 'auto', false); + this.updateFolderIcon(folder, 'auto'); if (options.renameFolder) { folder.rename(); @@ -1116,71 +1115,14 @@ } } - updateFolderIcon(group, state = 'auto', play = true) { + updateFolderIcon(group, state = 'auto') { const svg = group.querySelector('svg'); if (!svg) return []; - let animations = this.#folderAnimCache.get(group); - if (!animations) { - animations = svg.querySelectorAll('animate, animateTransform, animateMotion'); - this.#folderAnimCache.set(group, animations); - } const isCollapsed = group.collapsed; svg.setAttribute('state', state === 'auto' ? (isCollapsed ? 'close' : 'open') : state); const hasActive = group.hasAttribute('has-active'); - - const OPACITY = { - 'folder-dots': { active: '0;1', baseOrig: '0;0' }, - 'folder-icon': { active: '1;0', baseOrig: '1;1' }, - }; - - animations.forEach((animation) => { - const parentId = animation.parentElement.id; - const isOpacity = animation.getAttribute('attributeName') === 'opacity'; - - if (!animation.dataset.origValues) { - animation.dataset.origValues = animation.getAttribute('values'); - } - - const origValues = animation.dataset.origValues; - const [fromValue, toValue] = origValues.split(';'); - - const isActiveState = isCollapsed && hasActive && isOpacity; - - if (!play && !isActiveState) { - if (isOpacity && OPACITY[parentId]) { - const staticValue = OPACITY[parentId].baseOrig; - animation.dataset.origValues = staticValue; - animation.setAttribute('values', staticValue); - animation.beginElement(); - } - return; - } - - if (isOpacity && OPACITY[parentId]) { - animation.dataset.origValues = OPACITY[parentId].baseOrig; - } - - let newValues; - - if (isActiveState && OPACITY[parentId]) { - newValues = OPACITY[parentId].active; - const [activeFrom, activeTo] = newValues.split(';'); - animation.dataset.origValues = `${activeTo};${activeFrom}`; - } else { - const stateValues = { - open: `${fromValue};${toValue}`, - close: `${toValue};${fromValue}`, - auto: isCollapsed ? `${toValue};${fromValue}` : `${fromValue};${toValue}`, - }; - newValues = stateValues[state] || stateValues.auto; - } - - if (animation.getAttribute('values') !== newValues) { - animation.setAttribute('values', newValues); - animation.beginElement(); - } - }); + svg.setAttribute('active', hasActive && isCollapsed ? 'true' : 'false'); return []; } @@ -1256,7 +1198,7 @@ } setFolderUserIcon(group, icon) { - const svgIcon = group.icon.querySelector('svg #folder-icon image'); + const svgIcon = group.icon.querySelector('svg .icon image'); if (!svgIcon) return; svgIcon.setAttribute('href', icon ?? ''); if (svgIcon.getAttribute('href') !== icon) { @@ -1305,7 +1247,7 @@ if (group.activeTabs.length === 0) { group.removeAttribute('has-active'); - this.updateFolderIcon(group, 'close', false); + this.updateFolderIcon(group, 'close'); } return this.on_TabGroupCollapse({ @@ -1332,7 +1274,7 @@ if (group.activeTabs.length === 0) { group.removeAttribute('has-active'); - this.updateFolderIcon(group, 'close', false); + this.updateFolderIcon(group, 'close'); } this.on_TabGroupExpand({ target: group, forExpandVisible: true }); @@ -1408,7 +1350,7 @@ if (tabsContainer.hasAttribute('hidden')) tabsContainer.removeAttribute('hidden'); - animations.push(...this.updateFolderIcon(current, 'close', false)); + animations.push(...this.updateFolderIcon(current, 'close')); animations.push( gZenUIManager.motion.animate( groupStart, @@ -1518,7 +1460,7 @@ #groupInit(group, stateData) { // Setup zen-folder icon to the correct position - this.updateFolderIcon(group, 'auto', false); + this.updateFolderIcon(group, 'auto'); if (stateData?.userIcon) { this.setFolderUserIcon(group, stateData.userIcon); } @@ -1575,7 +1517,7 @@ let prevSiblingInfo = null; const prevSibling = folder.previousElementSibling; - const userIcon = folder?.icon?.querySelector('svg #folder-icon image'); + const userIcon = folder?.icon?.querySelector('svg .icon image'); if (prevSibling) { if (gBrowser.isTabGroup(prevSibling)) { diff --git a/src/zen/folders/zen-folders.css b/src/zen/folders/zen-folders.css index 3d45c8f9f..eb44dc756 100644 --- a/src/zen/folders/zen-folders.css +++ b/src/zen/folders/zen-folders.css @@ -6,7 +6,6 @@ tab-group[split-view-group] { display: block; - min-width: 100%; @media (prefers-reduced-motion: no-preference) { transition: var(--zen-tabbox-element-indent-transition); @@ -151,6 +150,10 @@ tab-group[split-view-group] { tab-group .tab-group-container { flex-direction: column; } + + tab-group[split-view-group] { + min-width: 100%; + } } tab-group[split-view-group] .tabbrowser-tab { @@ -295,6 +298,38 @@ zen-folder { fill: var(--zen-folder-stroke); transform: translate(4px, 6.5px); } + + & g, + & rect, + & path { + transition: + transform 0.3s cubic-bezier(0.42, 0, 0, 1), + opacity 0.3s cubic-bezier(0.42, 0, 0, 1); + } + + &[state='open'] .back { + transform: skewX(16deg) translate(-2px, 3.4px) scale(0.85); + } + + &[state='open'] :is(.front, .dots, .icon) { + transform: skewX(-16deg) translate(11.1px, 3.4px) scale(0.85); + } + + & .icon { + opacity: 1; + } + + & .dots { + opacity: 0; + } + + &[active='true'] .icon { + opacity: 0; + } + + &[active='true'] .dots { + opacity: 1; + } } } diff --git a/src/zen/tabs/ZenPinnedTabManager.mjs b/src/zen/tabs/ZenPinnedTabManager.mjs index 52ef1456c..6478041bf 100644 --- a/src/zen/tabs/ZenPinnedTabManager.mjs +++ b/src/zen/tabs/ZenPinnedTabManager.mjs @@ -1246,6 +1246,7 @@ for (const item of this.dragShiftableItems) { item.style.transform = ''; } + delete this._topToNormalTabs; for (const item of gBrowser.tabContainer.ariaFocusableItems) { if (gBrowser.isTab(item)) { let isVisible = true; @@ -1280,7 +1281,7 @@ : [separator]; } - animateSeparatorMove(movingTabs, dropElement, isPinned, event) { + animateSeparatorMove(movingTabs, dropElement, isPinned) { let draggedTab = movingTabs[0]; if (gBrowser.isTabGroupLabel(draggedTab) && draggedTab.group.isZenFolder) { this._isGoingToPinnedTabs = true; @@ -1290,14 +1291,19 @@ draggedTab = draggedTab.group; } const itemsToCheck = this.dragShiftableItems; - const translate = event.screenY; + let translate = movingTabs[isPinned ? movingTabs.length - 1 : 0].getBoundingClientRect().top; + if (isPinned) { + const rect = draggedTab.getBoundingClientRect(); + translate += rect.height; + } const draggingTabHeight = movingTabs.reduce((acc, item) => { return acc + window.windowUtils.getBoundsWithoutFlushing(item).height; }, 0); - let topToNormalTabs = itemsToCheck[0].screenY; - if (!isPinned) { - topToNormalTabs += draggedTab.getBoundingClientRect().height; + if (typeof this._topToNormalTabs === 'undefined') { + const rects = itemsToCheck.map((item) => window.windowUtils.getBoundsWithoutFlushing(item)); + this._topToNormalTabs = rects[0].top + rects.at(-1).height / (isPinned ? 2 : 4); } + let topToNormalTabs = this._topToNormalTabs; const isGoingToPinnedTabs = translate < topToNormalTabs && gBrowser.pinnedTabCount - gBrowser._numZenEssentials > 0; const multiplier = isGoingToPinnedTabs !== isPinned ? (isGoingToPinnedTabs ? 1 : -1) : 0;