Menu
Public repository / 439f0dcabf5cdf2b120c7724be895cf1df30507f
AkurAI-Framework / site/frontend/ai/components/media/video.js
Latest change 36f53e8d189d0609aaabc65e705cf9db9d497d14 - Port Media components as vanilla ES modules by Ólafur Búi Ólafsson
// Video component — renders a native <video controls> card with optional caption.
export const def = {
name: "video",
category: "Media",
title: "Video",
match(payload) {
return typeof payload?.src === "string";
},
render(payload, ctx) {
const { src, poster = "", caption = "" } = payload;
// XSS safety: only set src/poster from payload, never innerHTML
const video = document.createElement("video");
video.src = src;
if (poster) {
video.poster = poster;
}
video.controls = true;
video.style.width = "100%";
video.style.height = "auto";
video.style.borderRadius = "10px";
video.style.display = "block";
video.style.backgroundColor = "#000";
if (!caption) {
// No caption — just the video in a card
const card = document.createElement("div");
card.className = "card";
card.style.padding = "0";
card.style.overflow = "hidden";
card.appendChild(video);
return card;
}
// With caption
const card = document.createElement("div");
card.className = "card";
const videoWrapper = document.createElement("div");
videoWrapper.style.marginBottom = "12px";
videoWrapper.style.overflow = "hidden";
videoWrapper.style.borderRadius = "8px";
videoWrapper.appendChild(video);
const captionEl = document.createElement("p");
captionEl.style.margin = "0";
captionEl.style.fontSize = "13px";
captionEl.style.color = "var(--muted)";
captionEl.style.lineHeight = "1.5";
captionEl.textContent = caption;
card.appendChild(videoWrapper);
card.appendChild(captionEl);
return card;
},
example: {
src: "https://commondatastorage.googleapis.com/gtv-videos-library/sample/big_buck_bunny.mp4",
poster: "https://peach.blender.org/wp-content/uploads/image/poster_bunny.png?x11217",
caption: "Sample video — Big Buck Bunny"
}
};