new functions and fixes
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
# Browser libraries
|
||||
|
||||
Only `rustpad-player/` belongs to the repository. Mermaid and Highlight.js are generated directories and must not be committed.
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python3 scripts/update_browser_libs.py
|
||||
```
|
||||
|
||||
The updater resolves the current stable npm versions, verifies package integrity, copies the required browser assets and licenses, and atomically replaces:
|
||||
|
||||
- `static/libs/mermaid/`
|
||||
- `static/libs/highlight/`
|
||||
|
||||
`./dev.sh` runs the updater before local Cargo development. Docker downloads the same libraries in the `browser-libs` build stage. The application lazy-loads them only when matching content is rendered.
|
||||
|
||||
Project-owned media helpers remain in `static/libs/rustpad-player/`.
|
||||
@@ -0,0 +1,56 @@
|
||||
.rustpad-media {
|
||||
width: min(100%, 960px);
|
||||
margin: 18px auto;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
background: #000;
|
||||
box-shadow: 0 12px 30px color-mix(in srgb, #000 22%, transparent);
|
||||
}
|
||||
|
||||
.rustpad-media__player,
|
||||
.rustpad-media__player iframe,
|
||||
.rustpad-media__player video,
|
||||
video.rustpad-media__player {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.rustpad-media__player[data-player-kind="youtube"] {
|
||||
position: relative;
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
.rustpad-media__player[data-player-kind="youtube"] iframe {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
video.rustpad-media__player,
|
||||
.rustpad-media__player video {
|
||||
max-height: min(72vh, 760px);
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.rustpad-media__fallback {
|
||||
margin: 0;
|
||||
padding: 10px 12px;
|
||||
border-top: 1px solid color-mix(in srgb, white 18%, transparent);
|
||||
background: var(--surface-deep);
|
||||
color: var(--muted);
|
||||
font-size: .78rem;
|
||||
}
|
||||
|
||||
.rustpad-media__fallback a {
|
||||
color: var(--accent-soft);
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.rustpad-media {
|
||||
margin-block: 14px;
|
||||
border-radius: 9px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* RustPad media player helpers.
|
||||
* Project-owned code: keeps native video playback and YouTube embeds responsive.
|
||||
*/
|
||||
|
||||
const initialized = new WeakSet();
|
||||
|
||||
function createYouTubeFrame(node) {
|
||||
const videoId = String(node.dataset.videoId || "").trim();
|
||||
if (!/^[A-Za-z0-9_-]{6,20}$/.test(videoId)) return;
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(videoId)}?rel=0&modestbranding=1&playsinline=1`;
|
||||
iframe.title = node.dataset.playerTitle || "YouTube video";
|
||||
iframe.loading = "lazy";
|
||||
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";
|
||||
iframe.referrerPolicy = "strict-origin-when-cross-origin";
|
||||
iframe.allowFullscreen = true;
|
||||
node.replaceChildren(iframe);
|
||||
}
|
||||
|
||||
function initializeNativeVideo(video) {
|
||||
video.controls = true;
|
||||
video.playsInline = true;
|
||||
video.preload = video.preload || "metadata";
|
||||
|
||||
const fallback = video.closest(".rustpad-media")?.querySelector(".rustpad-media__fallback");
|
||||
if (!fallback) return;
|
||||
const revealFallback = () => { fallback.hidden = false; };
|
||||
video.addEventListener("error", revealFallback, { once: true });
|
||||
video.querySelectorAll("source").forEach(source => source.addEventListener("error", revealFallback, { once: true }));
|
||||
}
|
||||
|
||||
export function hydrateMediaPlayers(root = document) {
|
||||
root.querySelectorAll("[data-rustpad-player]").forEach(node => {
|
||||
if (initialized.has(node)) return;
|
||||
initialized.add(node);
|
||||
if (node.dataset.playerKind === "youtube") createYouTubeFrame(node);
|
||||
else if (node instanceof HTMLVideoElement) initializeNativeVideo(node);
|
||||
});
|
||||
}
|
||||
|
||||
export function destroyMediaPlayers(root = document) {
|
||||
root.querySelectorAll('[data-rustpad-player][data-player-kind="youtube"] iframe').forEach(frame => {
|
||||
frame.src = "about:blank";
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user