Skip to content

Commit

Permalink
Enhance details handling by adding max-height and overflow styles, re…
Browse files Browse the repository at this point in the history
…factor summary generation logic, and improve scrolling behavior for better user experience
  • Loading branch information
tztsai committed Nov 10, 2024
1 parent acfbbcf commit a04b387
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 44 deletions.
5 changes: 5 additions & 0 deletions content/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ details {
margin-top: 0;
}

details > div {
max-height: 600px;
overflow: auto;
}

details summary {
cursor: pointer;
align-items: center;
Expand Down
92 changes: 52 additions & 40 deletions content/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,63 +113,75 @@ var update = (update) => {
}

// Add details & summary tags to each section separated by headers
setTimeout(() => {
document.querySelectorAll('h2, h3, h4').forEach(header => {
if (header.parentNode.tagName === 'summary') return;

const details = document.createElement('details');
const summary = document.createElement('summary');
details.id = 'id-' + Math.random().toString(36).substring(2, 7);
details.appendChild(summary);

let sibling = header.nextElementSibling;
while (sibling && (!/^H[1-6]$/.test(sibling.tagName) || sibling.tagName > header.tagName)) {
const nextSibling = sibling.nextElementSibling;
if (!summary.textContent &&
sibling.tagName === 'blockquote' &&
sibling.textContent.trim().startsWith('Summary:')) {
summary.textContent = sibling.textContent.replace(/^\s*Summary:\s*/m, '');
} else {
details.appendChild(sibling);
}
sibling = nextSibling;
}
setTimeout(makeFoldable, 80);
}

header.parentNode.replaceChild(details, header);
summary.insertAdjacentElement('afterbegin', header);
var makeFoldable = (selector = 'h2, h3, h4') => {
document.querySelectorAll(selector).forEach(header => {
if (header.parentNode.tagName === 'summary') return;

const details = document.createElement('details');
const summary = document.createElement('summary');
const div = document.createElement('div');
details.id = 'id-' + Math.random().toString(36).substring(2, 7);
details.appendChild(summary);
details.appendChild(div);

for (
let s = header.nextElementSibling, p;
s && (!/^H[1-6]$/.test(s.tagName) || s.tagName > header.tagName);
s = p
) {
p = s.nextElementSibling;
div.appendChild(s);
}

// Focus on details when hovering over it
var lastTriggerTime = 0;
details.addEventListener('mouseenter', () => {
const now = Date.now();
if (now - lastTriggerTime >= 400) {
focusOnDetails(details);
lastTriggerTime = now;
}
});
header.parentNode.replaceChild(details, header);
summary.insertAdjacentElement('afterbegin', header);

// Expand a details element when hovering over it
details.addEventListener('mouseenter', () => {
!isScrolling && focusOnDetails(details);
});
document.readyState = 'complete';
}, 80);
});
document.readyState = 'complete';
}

var focusedDetails;
var isScrolling = false;

var focusOnDetails = (details) => {
if (details.open) return;
isScrolling = true;
isDownward = true;
details.open = true;
const rect1 = details.getBoundingClientRect();
while (focusedDetails && !focusedDetails.contains(details)) {
if (focusedDetails.getBoundingClientRect().top > rect1.top)
isDownward = false;
focusedDetails.open = false;
focusedDetails = focusedDetails.parentElement.closest('details');
}
focusedDetails = details;
const rect2 = details.getBoundingClientRect();
dy = rect2.top - rect1.top; // keep the top of rect still
if (dy < -20)
dy += Math.min(rect1.top, rect1.height) * 0.8; // scroll down
else if (dy > 20)
dy -= Math.max(rect1.bottom - window.innerHeight, 0); // scroll up
window.scrollBy(0, dy);
focusedDetails = details;
if (details.querySelector('details')) {
if (isDownward) {
dy += rect2.height + 30;
focusedDetails = details.nextElementSibling;
}
}
else if (isDownward) {
dy += Math.max(Math.min(rect1.top, rect1.height - 50), 0);
}
else if (rect2.bottom > window.innerHeight) {
dy += rect2.bottom - window.innerHeight + 50;
}
window.scrollBy({ top: dy, behavior: 'smooth' });
if (Math.abs(dy) > 200)
setTimeout(() => { isScrolling = false; }, 300);
else
isScrolling = false;
}

var render = (md) => {
Expand Down
8 changes: 4 additions & 4 deletions content/mdwise.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ function cleanHtml() {
}

async function generateSummaries(text) {
// const useAI = state.useAI;
// if (!useAI) return;

// const prompt = `Convert the following text provided by the user to a well-structured Markdown document. For large chunks of text, consider splitting them into smaller subsections. For each section of any level containing too much information for the user to easily digest, **write a brief summary under its header with prefix "> Summary: "**. Do your best to enable the user to clearly and quickly understand the whole document from top level to bottom.`;
const prompt = `In the given HTML file, for each <details> element, if necessary, write a proper and brief summary of its content.
Expand Down Expand Up @@ -79,7 +77,7 @@ async function generateSummaries(text) {
const p = document.createElement('blockquote');
p.textContent = txt.trim();
d.querySelector('summary').appendChild(p);
focusOnDetails(d);
// focusOnDetails(d);
} else {
console.error('Invalid ID:', id)
}
Expand Down Expand Up @@ -140,12 +138,14 @@ async function generateSummaries(text) {
if (document.readyState === 'complete') {
clearInterval(timeout);
content = document.getElementById('_html');
if (!content) return;
for (
s = content.querySelector('h1')?.previousElementSibling;
s; s = s.previousElementSibling
) { s.remove(); }
// convert the markdown content to text
generateSummaries(content.outerHTML);
if (state.content.useAI)
generateSummaries(content.outerHTML);
}
}, 500);
})()

0 comments on commit a04b387

Please sign in to comment.