feat: LEXAI-23 move Copy As + Download into More dropdown on toolbar
Some checks failed
CI — Test & Build / Test & Build (push) Failing after 45s
Some checks failed
CI — Test & Build / Test & Build (push) Failing after 45s
This commit is contained in:
@@ -243,91 +243,99 @@ export default defineContentScript({
|
||||
toolbar!.appendChild(btn);
|
||||
});
|
||||
|
||||
// ── Separator ────────────────────────────────────────────────────────────
|
||||
const sep = document.createElement('div');
|
||||
Object.assign(sep.style, {
|
||||
width: '1px',
|
||||
height: '20px',
|
||||
background: 'rgba(205,214,244,0.15)',
|
||||
margin: '0 2px',
|
||||
flexShrink: '0',
|
||||
// ─── More button (Copy As + Download) ────────────────────────────────────
|
||||
const moreBtn = document.createElement('button');
|
||||
moreBtn.textContent = '⋯ More';
|
||||
moreBtn.setAttribute('data-lexai', 'true');
|
||||
Object.assign(moreBtn.style, {
|
||||
background: 'rgba(49,50,68,0.8)',
|
||||
color: '#a6adc8',
|
||||
border: '1px solid rgba(205,214,244,0.15)',
|
||||
borderRadius: '6px',
|
||||
padding: '5px 10px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '600',
|
||||
cursor: 'pointer',
|
||||
whiteSpace: 'nowrap',
|
||||
});
|
||||
toolbar!.appendChild(sep);
|
||||
|
||||
// ── LEXAI-19: Copy As button ─────────────────────────────────────────────
|
||||
const copyAsBtn = document.createElement('button');
|
||||
copyAsBtn.textContent = '⎘ Copy As';
|
||||
copyAsBtn.setAttribute('data-lexai', 'true');
|
||||
Object.assign(copyAsBtn.style, {
|
||||
background: 'rgba(49,50,68,0.8)',
|
||||
color: '#f9e2af',
|
||||
border: '1px solid rgba(205,214,244,0.1)',
|
||||
borderRadius: '7px',
|
||||
padding: '4px 10px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '600',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.15s ease',
|
||||
letterSpacing: '0.01em',
|
||||
whiteSpace: 'nowrap',
|
||||
});
|
||||
copyAsBtn.addEventListener('mouseenter', () => {
|
||||
copyAsBtn.style.background = 'rgba(69,71,90,0.9)';
|
||||
copyAsBtn.style.borderColor = '#f9e2af50';
|
||||
copyAsBtn.style.transform = 'translateY(-1px)';
|
||||
});
|
||||
copyAsBtn.addEventListener('mouseleave', () => {
|
||||
copyAsBtn.style.background = 'rgba(49,50,68,0.8)';
|
||||
copyAsBtn.style.borderColor = 'rgba(205,214,244,0.1)';
|
||||
copyAsBtn.style.transform = 'translateY(0)';
|
||||
});
|
||||
copyAsBtn.addEventListener('mousedown', (e) => {
|
||||
e.preventDefault();
|
||||
captureForButton();
|
||||
});
|
||||
copyAsBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
showCopyAsModal(selectedText);
|
||||
});
|
||||
toolbar!.appendChild(copyAsBtn);
|
||||
// Dropdown menu
|
||||
let moreMenu: HTMLElement | null = null;
|
||||
|
||||
// ── LEXAI-20: Download button ────────────────────────────────────────────
|
||||
const downloadBtn = document.createElement('button');
|
||||
downloadBtn.textContent = '⬇ Save';
|
||||
downloadBtn.setAttribute('data-lexai', 'true');
|
||||
Object.assign(downloadBtn.style, {
|
||||
background: 'rgba(49,50,68,0.8)',
|
||||
color: '#9399b2',
|
||||
border: '1px solid rgba(205,214,244,0.1)',
|
||||
borderRadius: '7px',
|
||||
padding: '4px 10px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '600',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.15s ease',
|
||||
letterSpacing: '0.01em',
|
||||
whiteSpace: 'nowrap',
|
||||
});
|
||||
downloadBtn.addEventListener('mouseenter', () => {
|
||||
downloadBtn.style.background = 'rgba(69,71,90,0.9)';
|
||||
downloadBtn.style.borderColor = '#9399b250';
|
||||
downloadBtn.style.transform = 'translateY(-1px)';
|
||||
});
|
||||
downloadBtn.addEventListener('mouseleave', () => {
|
||||
downloadBtn.style.background = 'rgba(49,50,68,0.8)';
|
||||
downloadBtn.style.borderColor = 'rgba(205,214,244,0.1)';
|
||||
downloadBtn.style.transform = 'translateY(0)';
|
||||
});
|
||||
downloadBtn.addEventListener('mousedown', (e) => {
|
||||
e.preventDefault();
|
||||
captureForButton();
|
||||
});
|
||||
downloadBtn.addEventListener('click', (e) => {
|
||||
function closeMoveMenu() {
|
||||
if (moreMenu) { moreMenu.remove(); moreMenu = null; }
|
||||
}
|
||||
|
||||
moreBtn.addEventListener('mousedown', (e) => e.preventDefault());
|
||||
moreBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
hideToolbar();
|
||||
downloadAsText(selectedText);
|
||||
if (moreMenu) { closeMoveMenu(); return; }
|
||||
|
||||
moreMenu = document.createElement('div');
|
||||
moreMenu.setAttribute('data-lexai', 'true');
|
||||
Object.assign(moreMenu.style, {
|
||||
position: 'fixed',
|
||||
background: 'rgba(30,30,46,0.98)',
|
||||
border: '1px solid rgba(205,214,244,0.15)',
|
||||
borderRadius: '8px',
|
||||
padding: '4px',
|
||||
zIndex: '2147483647',
|
||||
minWidth: '140px',
|
||||
boxShadow: '0 4px 20px rgba(0,0,0,0.4)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '2px',
|
||||
});
|
||||
|
||||
// Position above the More button
|
||||
const rect = moreBtn.getBoundingClientRect();
|
||||
moreMenu.style.left = rect.left + 'px';
|
||||
moreMenu.style.top = (rect.top - 8) + 'px';
|
||||
moreMenu.style.transform = 'translateY(-100%)';
|
||||
|
||||
const menuItems = [
|
||||
{ label: '⎘ Copy As', action: 'copy-as' },
|
||||
{ label: '⬇ Download', action: 'download' },
|
||||
];
|
||||
|
||||
menuItems.forEach(({ label, action }) => {
|
||||
const item = document.createElement('button');
|
||||
item.textContent = label;
|
||||
item.setAttribute('data-lexai', 'true');
|
||||
Object.assign(item.style, {
|
||||
background: 'transparent',
|
||||
color: '#cdd6f4',
|
||||
border: 'none',
|
||||
borderRadius: '6px',
|
||||
padding: '7px 12px',
|
||||
fontSize: '13px',
|
||||
cursor: 'pointer',
|
||||
textAlign: 'left',
|
||||
width: '100%',
|
||||
});
|
||||
item.addEventListener('mouseenter', () => { item.style.background = 'rgba(137,180,250,0.1)'; });
|
||||
item.addEventListener('mouseleave', () => { item.style.background = 'transparent'; });
|
||||
item.addEventListener('mousedown', (e) => e.preventDefault());
|
||||
item.addEventListener('click', () => {
|
||||
closeMoveMenu();
|
||||
captureForButton(); // ensure selection is captured
|
||||
if (action === 'download') {
|
||||
downloadAsText(selectedText);
|
||||
} else {
|
||||
showCopyAsModal(selectedText);
|
||||
}
|
||||
});
|
||||
moreMenu!.appendChild(item);
|
||||
});
|
||||
|
||||
document.body.appendChild(moreMenu);
|
||||
});
|
||||
toolbar!.appendChild(downloadBtn);
|
||||
|
||||
toolbar!.appendChild(moreBtn);
|
||||
|
||||
// Close dropdown on outside click / scroll
|
||||
document.addEventListener('click', closeMoveMenu);
|
||||
document.addEventListener('scroll', closeMoveMenu, { passive: true });
|
||||
|
||||
document.body.appendChild(toolbar);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user