Keep the Glass Stage notes toolbar on one row at every player width
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
return { kind:glyphs[glyph], original:prefix+rest.slice(0,length), rest:rest.slice(length) };
|
||||
}
|
||||
function mount(doc) {
|
||||
const decorations = new Set(); let scheduled=false;
|
||||
const decorations = new Set(), tabLabels = new Map(); let scheduled=false;
|
||||
const selector = '#listPane button, .sidebar button, .smart-item .pl-name, .notes-tab, .notes-fold, .mini-btn, .sidebar .playlist-item:not(.smart-item), .pl-offline-badge.all, .home-pl-offline.all, .home-pl-play, .home-pl-thumb-fallback';
|
||||
const svg = kind => { const icon=doc.createElementNS('http://www.w3.org/2000/svg','svg'); icon.setAttribute('viewBox','0 0 24 24');icon.setAttribute('aria-hidden','true');icon.classList.add('glass-control-icon');icon.innerHTML=paths[kind];return icon; };
|
||||
const observer=new root.MutationObserver(schedule), themeObserver=new root.MutationObserver(schedule);
|
||||
@@ -39,9 +39,14 @@
|
||||
record.svg.remove(); if(record.original.isConnected)record.original.replaceWith(doc.createTextNode(record.original.textContent));
|
||||
if(record.addedLabel && record.parent.isConnected)record.parent.removeAttribute('aria-label');
|
||||
}
|
||||
function restoreTab(parent, record) {
|
||||
for(const label of record.labels)if(label.isConnected)label.replaceWith(doc.createTextNode(label.textContent));
|
||||
for(const [name,value] of Object.entries(record.attributes)) { if(value===null)parent.removeAttribute(name);else parent.setAttribute(name,value); }
|
||||
}
|
||||
function paint() {
|
||||
scheduled=false;observer.disconnect();
|
||||
const active=doc.documentElement.dataset.layout==='glass-stage';
|
||||
for(const [parent,record] of tabLabels)if(!active || !parent.isConnected){restoreTab(parent,record);tabLabels.delete(parent);}
|
||||
for(const record of decorations)if(!active || !record.svg.isConnected){restore(record);decorations.delete(record);}
|
||||
if(active) for(const parent of doc.querySelectorAll(selector)) {
|
||||
// Existing SVGs already express the action; only legacy glyphs change.
|
||||
@@ -65,11 +70,22 @@
|
||||
const original=doc.createElement('span');decorations.add({parent,svg:icon,original,addedLabel:false});
|
||||
}
|
||||
}
|
||||
if(active)for(const parent of doc.querySelectorAll('.notes-tab')) {
|
||||
if(tabLabels.has(parent))continue;
|
||||
const record={labels:[],attributes:{'aria-label':parent.getAttribute('aria-label'),title:parent.getAttribute('title')}};
|
||||
const name=parent.dataset.tab==='markers'?'Chapters & bookmarks':parent.dataset.tab==='lyrics'?'Lyrics':'Search';
|
||||
if(!parent.hasAttribute('aria-label'))parent.setAttribute('aria-label',name);
|
||||
if(!parent.hasAttribute('title'))parent.setAttribute('title',name);
|
||||
for(const node of [...parent.childNodes])if(node.nodeType===3 && node.textContent.trim()) {
|
||||
const label=doc.createElement('span');label.className='glass-tab-label';node.replaceWith(label);label.append(node);record.labels.push(label);
|
||||
}
|
||||
tabLabels.set(parent,record);
|
||||
}
|
||||
if(active)observer.observe(doc.body,{childList:true,subtree:true,characterData:true});
|
||||
}
|
||||
function schedule(){if(!scheduled){scheduled=true;root.queueMicrotask(paint);}}
|
||||
themeObserver.observe(doc.documentElement,{attributes:true,attributeFilter:['data-layout']});paint();
|
||||
return ()=>{observer.disconnect();themeObserver.disconnect();for(const record of decorations)restore(record);};
|
||||
return ()=>{observer.disconnect();themeObserver.disconnect();for(const record of decorations)restore(record);for(const [parent,record] of tabLabels)restoreTab(parent,record);};
|
||||
}
|
||||
if(typeof module!=='undefined')module.exports={leadingGlyph,paths};
|
||||
else if(root.document.readyState==='loading')root.document.addEventListener('DOMContentLoaded',()=>mount(root.document),{once:true});
|
||||
|
||||
@@ -35,3 +35,22 @@ html[data-layout="glass-stage"] #listPane {
|
||||
html[data-layout="glass-stage"] .player-pane { padding-bottom:14px; }
|
||||
html[data-layout="glass-stage"] #listPane { padding-bottom:16px !important; }
|
||||
}
|
||||
|
||||
/* Keep the notes toolbar one row, even when the player is a narrow desktop pane. */
|
||||
html[data-layout="glass-stage"] #notesPanel { container-type:inline-size; container-name:glass-notes; min-width:0; }
|
||||
html[data-layout="glass-stage"] .notes-tabs { flex-wrap:nowrap; min-width:0; align-items:center; }
|
||||
html[data-layout="glass-stage"] .notes-tab { flex:0 1 auto; min-width:44px; min-height:44px; white-space:nowrap; letter-spacing:.04em; }
|
||||
html[data-layout="glass-stage"] .glass-tab-label { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
||||
html[data-layout="glass-stage"] .notes-status { flex:1 1 0; min-width:0; margin-left:0; font-size:11px; }
|
||||
html[data-layout="glass-stage"] .notes-count { flex:none; margin-left:0; }
|
||||
html[data-layout="glass-stage"] .notes-fold { flex:none; width:44px; height:44px; margin-left:auto; }
|
||||
@container glass-notes (max-width:560px) {
|
||||
html[data-layout="glass-stage"] .notes-tabs { gap:4px; padding:6px; }
|
||||
html[data-layout="glass-stage"] .notes-tab { padding:8px; letter-spacing:0; font-size:11px; }
|
||||
}
|
||||
@container glass-notes (max-width:440px) {
|
||||
html[data-layout="glass-stage"] .notes-tab[data-tab="markers"] .glass-tab-label { display:none; }
|
||||
}
|
||||
@container glass-notes (max-width:340px) {
|
||||
html[data-layout="glass-stage"] .notes-tab .glass-tab-label { display:none; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user