mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
chore: move sandbox to apps/ (#1171)
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { getInitialSkin, getInitialSource } from '@app/shared/sandbox-listener';
|
||||
import type { SourceId } from '@app/shared/sources';
|
||||
import type { Skin, Styling } from '@app/types';
|
||||
|
||||
function getInitialStyling(): Styling {
|
||||
return new URLSearchParams(location.search).get('styling') === 'tailwind' ? 'tailwind' : 'css';
|
||||
}
|
||||
|
||||
export type HtmlSandboxState = {
|
||||
skin: Skin;
|
||||
source: SourceId;
|
||||
styling: Styling;
|
||||
};
|
||||
|
||||
export function createHtmlSandboxState(audioOnly?: boolean): HtmlSandboxState {
|
||||
return {
|
||||
skin: getInitialSkin(),
|
||||
source: getInitialSource(audioOnly),
|
||||
styling: getInitialStyling(),
|
||||
};
|
||||
}
|
||||
|
||||
export function createLatestLoader() {
|
||||
let loadVersion = 0;
|
||||
|
||||
return async <Result>(load: () => Promise<Result>): Promise<Result | undefined> => {
|
||||
const version = ++loadVersion;
|
||||
try {
|
||||
const result = await load();
|
||||
return version === loadVersion ? result : undefined;
|
||||
} catch (error) {
|
||||
// Swallow load errors to avoid unhandled promise rejections in callers
|
||||
// that do not await the returned promise. Callers can treat `undefined`
|
||||
// as a signal that no valid result is available.
|
||||
console.error('Failed to load latest result', error);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { Skin } from '@app/types';
|
||||
|
||||
type SkinTagMap = Record<Skin, { video: string; audio: string }>;
|
||||
|
||||
export const CSS_SKIN_TAGS: SkinTagMap = {
|
||||
default: { video: 'video-skin', audio: 'audio-skin' },
|
||||
minimal: { video: 'video-minimal-skin', audio: 'audio-minimal-skin' },
|
||||
};
|
||||
|
||||
export const TAILWIND_SKIN_TAGS: SkinTagMap = {
|
||||
default: { video: 'video-skin-tailwind', audio: 'audio-skin-tailwind' },
|
||||
minimal: { video: 'video-minimal-skin-tailwind', audio: 'audio-minimal-skin-tailwind' },
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { Skin, Styling } from '@app/types';
|
||||
import { CSS_SKIN_TAGS, TAILWIND_SKIN_TAGS } from './skin-tags';
|
||||
import { loadAudioStylesheets, loadVideoStylesheets } from './stylesheets';
|
||||
|
||||
async function loadVideoCssSkin(skin: Skin): Promise<string> {
|
||||
if (skin === 'default') {
|
||||
await import('@videojs/html/video/skin');
|
||||
} else {
|
||||
await import('@videojs/html/video/minimal-skin');
|
||||
}
|
||||
|
||||
loadVideoStylesheets(skin);
|
||||
|
||||
return CSS_SKIN_TAGS[skin].video;
|
||||
}
|
||||
|
||||
async function loadAudioCssSkin(skin: Skin): Promise<string> {
|
||||
if (skin === 'default') {
|
||||
await import('@videojs/html/audio/skin');
|
||||
} else {
|
||||
await import('@videojs/html/audio/minimal-skin');
|
||||
}
|
||||
|
||||
loadAudioStylesheets(skin);
|
||||
|
||||
return CSS_SKIN_TAGS[skin].audio;
|
||||
}
|
||||
|
||||
async function loadVideoTailwindSkin(skin: Skin): Promise<string> {
|
||||
if (skin === 'default') {
|
||||
const { VideoSkinTailwindElement } = await import('@videojs/html/video/skin.tailwind');
|
||||
const { getTailwindStyles } = await import('./tailwind-setup');
|
||||
|
||||
VideoSkinTailwindElement.styles = getTailwindStyles();
|
||||
} else {
|
||||
const { MinimalVideoSkinTailwindElement } = await import('@videojs/html/video/minimal-skin.tailwind');
|
||||
const { getTailwindStyles } = await import('./tailwind-setup');
|
||||
|
||||
MinimalVideoSkinTailwindElement.styles = getTailwindStyles();
|
||||
}
|
||||
|
||||
return TAILWIND_SKIN_TAGS[skin].video;
|
||||
}
|
||||
|
||||
async function loadAudioTailwindSkin(skin: Skin): Promise<string> {
|
||||
if (skin === 'default') {
|
||||
const { AudioSkinTailwindElement } = await import('@videojs/html/audio/skin.tailwind');
|
||||
const { getTailwindStyles } = await import('./tailwind-setup');
|
||||
|
||||
AudioSkinTailwindElement.styles = getTailwindStyles();
|
||||
} else {
|
||||
const { MinimalAudioSkinTailwindElement } = await import('@videojs/html/audio/minimal-skin.tailwind');
|
||||
const { getTailwindStyles } = await import('./tailwind-setup');
|
||||
|
||||
MinimalAudioSkinTailwindElement.styles = getTailwindStyles();
|
||||
}
|
||||
|
||||
return TAILWIND_SKIN_TAGS[skin].audio;
|
||||
}
|
||||
|
||||
export function loadVideoSkinTag(skin: Skin, styling: Styling): Promise<string> {
|
||||
return styling === 'tailwind' ? loadVideoTailwindSkin(skin) : loadVideoCssSkin(skin);
|
||||
}
|
||||
|
||||
export function loadAudioSkinTag(skin: Skin, styling: Styling): Promise<string> {
|
||||
return styling === 'tailwind' ? loadAudioTailwindSkin(skin) : loadAudioCssSkin(skin);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function renderStoryboard(src?: string | undefined): string {
|
||||
return src ? `<track kind="metadata" label="thumbnails" src="${src}" default />` : '';
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Skin } from '../../types';
|
||||
|
||||
const videoStylesheets: Record<Skin, string> = {
|
||||
default: new URL('@videojs/html/video/skin.css', import.meta.url).href,
|
||||
minimal: new URL('@videojs/html/video/minimal-skin.css', import.meta.url).href,
|
||||
};
|
||||
|
||||
const audioStylesheets: Record<Skin, string> = {
|
||||
default: new URL('@videojs/html/audio/skin.css', import.meta.url).href,
|
||||
minimal: new URL('@videojs/html/audio/minimal-skin.css', import.meta.url).href,
|
||||
};
|
||||
|
||||
function loadStylesheet(id: string, url: string) {
|
||||
const existing = document.querySelector(`link[rel="stylesheet"][data-sandbox-stylesheet="${id}"]`);
|
||||
existing?.remove();
|
||||
|
||||
const link = document.createElement('link');
|
||||
link.dataset.sandboxStylesheet = id;
|
||||
link.rel = 'stylesheet';
|
||||
link.href = url;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
|
||||
export function loadVideoStylesheets(skin: Skin) {
|
||||
loadStylesheet('video-skin', videoStylesheets[skin]);
|
||||
}
|
||||
|
||||
export function loadAudioStylesheets(skin: Skin) {
|
||||
loadStylesheet('audio-skin', audioStylesheets[skin]);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import tailwindCSS from '@app/styles.css?inline';
|
||||
|
||||
const tailwindStyles = new CSSStyleSheet();
|
||||
tailwindStyles.replaceSync(tailwindCSS);
|
||||
|
||||
export function getTailwindStyles(): CSSStyleSheet {
|
||||
return tailwindStyles;
|
||||
}
|
||||
Reference in New Issue
Block a user