1
0
mirror of https://github.com/coalaura/whiskr.git synced 2025-09-08 17:06:42 +00:00

draggable tables

This commit is contained in:
Laura
2025-09-04 17:15:09 +02:00
parent a819ec7b38
commit aeed519df0
2 changed files with 106 additions and 9 deletions

View File

@@ -91,10 +91,26 @@
border-radius: 4px;
}
.markdown .table-wrapper {
width: 100%;
overflow-x: auto;
margin: 16px 0;
cursor: grab;
touch-action: pan-y;
}
.markdown .table-wrapper:not(.overflowing) {
cursor: default;
overflow-x: hidden;
}
.markdown .table-wrapper.dragging {
cursor: grabbing;
}
.markdown table {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
font-size: 14px;
}

View File

@@ -1,5 +1,12 @@
(() => {
const timeouts = new WeakMap();
const timeouts = new WeakMap(),
scrollState = {
el: null,
startX: 0,
scrollLeft: 0,
pointerId: null,
moved: false,
};
marked.use({
async: false,
@@ -7,13 +14,13 @@
gfm: true,
pedantic: false,
walkTokens: (token) => {
walkTokens: token => {
const { type, text } = token;
if (type === "html") {
token.text = token.text.replace(/&/g, "&")
token.text = token.text.replace(/</g, "&lt;")
token.text = token.text.replace(/>/g, "&gt;")
token.text = token.text.replace(/&/g, "&amp;");
token.text = token.text.replace(/</g, "&lt;");
token.text = token.text.replace(/>/g, "&gt;");
return;
} else if (type !== "code") {
@@ -48,9 +55,18 @@
return `<a href="${link.href}" target="_blank">${escapeHtml(link.text || link.href)}</a>`;
},
},
hooks: {
postprocess: html => {
html = html.replace(/<table>/g, `<div class="table-wrapper"><table>`);
html = html.replace(/<\/ ?table>/g, `</table></div>`);
return html;
},
},
});
document.body.addEventListener("click", (event) => {
addEventListener("click", event => {
const button = event.target,
header = button.closest(".pre-header"),
pre = header?.closest("pre"),
@@ -70,11 +86,76 @@
pre,
setTimeout(() => {
button.classList.remove("copied");
}, 1000),
}, 1000)
);
});
window.render = (markdown) => {
addEventListener("pointerover", event => {
if (event.pointerType !== "mouse") {
return;
}
const el = event.target.closest(".table-wrapper");
if (!el) {
return;
}
el.classList.toggle("overflowing", el.scrollWidth - el.clientWidth > 1);
});
addEventListener("pointerdown", event => {
if (event.button !== 0) {
return;
}
const el = event.target.closest(".table-wrapper");
if (!el) {
return;
}
scrollState.el = el;
scrollState.pointerId = event.pointerId;
scrollState.startX = event.clientX;
scrollState.scrollLeft = el.scrollLeft;
scrollState.moved = false;
el.classList.add("dragging");
el.setPointerCapture?.(event.pointerId);
event.preventDefault();
});
addEventListener("pointermove", event => {
if (!scrollState.el || event.pointerId !== scrollState.pointerId) {
return;
}
const dx = event.clientX - scrollState.startX;
if (Math.abs(dx) > 3) {
scrollState.moved = true;
}
scrollState.el.scrollLeft = scrollState.scrollLeft - dx;
});
function endScroll(event) {
if (!scrollState.el || (event && event.pointerId !== scrollState.pointerId)) {
return;
}
scrollState.el.classList.remove("dragging");
scrollState.el.releasePointerCapture?.(scrollState.pointerId);
scrollState.el = null;
scrollState.pointerId = null;
}
addEventListener("pointerup", endScroll);
addEventListener("pointercancel", endScroll);
window.render = markdown => {
return marked.parse(markdown);
};
})();