Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f81e3f1
refactor(sandbox): share the template runtime
mihar-22 Sep 2, 2026
424d7bc
refactor(sandbox): describe each media in one table
mihar-22 Sep 2, 2026
4eec999
feat(sandbox): add player width, color scheme, and direction controls
mihar-22 Sep 2, 2026
b7de7b0
test(e2e): build the registry packages under webpack and Rspack
mihar-22 Sep 2, 2026
7b269bf
feat(sandbox): choose where skins come from
mihar-22 Sep 2, 2026
50c7967
feat(sandbox): compile authored skins in the workspace
mihar-22 Sep 2, 2026
51c6b37
feat(sandbox): compare two configurations side by side
mihar-22 Sep 2, 2026
c08c29f
feat(sandbox): mirror playback state across compare panels
mihar-22 Sep 2, 2026
cbbbd99
feat(sandbox): copy a preview report with preferences and errors
mihar-22 Sep 2, 2026
41bcc15
test(e2e): run skin parity against the sandbox
mihar-22 Sep 2, 2026
0f1ea94
chore(skins): remove the playground
mihar-22 Sep 2, 2026
1eed000
fix(vjsc): parse only script modules in the vite adapter
mihar-22 Sep 2, 2026
82efade
fix(sandbox): keep the compiler out of the task config
mihar-22 Sep 2, 2026
967a65e
fix(skins): stop anchored menu highlights from doubling the item back…
mihar-22 Sep 2, 2026
d81eef6
fix(skins): restore the highlight under default menu separators
mihar-22 Sep 2, 2026
834f069
fix(skins): restore the scrim over the default thumbnail preview
mihar-22 Sep 2, 2026
96094fd
fix(skins): match the legacy preview label and thumbnail offsets
mihar-22 Sep 2, 2026
27522cc
test(skins): boot the Vite workflow tests from their own config
mihar-22 Sep 3, 2026
b3357fd
fix(sandbox): let the generated-tree guard run in container checkouts
mihar-22 Sep 3, 2026
9c0c7a3
style(sandbox): format the templates touched by the extension path re…
mihar-22 Sep 3, 2026
f3f8443
fix(e2e): start the player web server from the e2e package
mihar-22 Sep 3, 2026
7fb2f16
fix(sandbox): create the scratch tree before writing the app shell
mihar-22 Sep 3, 2026
1b268d6
fix(sandbox): build workspace packages before the unit tests
mihar-22 Sep 3, 2026
47a06aa
fix(e2e): resolve the player web server binary through npx and surfac…
mihar-22 Sep 3, 2026
4990415
fix(e2e): serve the player suite through Vite+
mihar-22 Sep 3, 2026
45b3ad9
Revert "fix(skins): match the legacy preview label and thumbnail offs…
mihar-22 Sep 3, 2026
d924bbe
test(e2e): settle web fonts before each skin parity capture
mihar-22 Sep 3, 2026
3a02d83
test(e2e): refresh the video error dialog baselines with web fonts se…
mihar-22 Sep 3, 2026
5f324fa
fix(skins): match the legacy preview label and thumbnail offsets
mihar-22 Sep 2, 2026
6da8c78
test(e2e): pin the fullscreen preview geometry to the legacy offsets
mihar-22 Sep 3, 2026
f965ee2
feat(sandbox): move the preview options into a side panel
mihar-22 Sep 3, 2026
4524e68
refactor(skins): rename the scrim tokens to backdrop
mihar-22 Sep 3, 2026
d5d29d0
fix(skins): give the Minimal skins their own copies of preset-shared …
mihar-22 Sep 3, 2026
47acdba
fix(vjsc): compare import closures before reusing a published registr…
mihar-22 Sep 3, 2026
b8cda46
refactor(skins): name the indicator backdrop filter after what it blurs
mihar-22 Sep 3, 2026
5cedc64
fix(html): keep the generated skin registrations in sideEffects
mihar-22 Sep 3, 2026
03bb344
fix(sandbox): add CDN caption tracks, default skins per platform, and…
mihar-22 Sep 3, 2026
b0642f6
fix(sandbox): constrain styling by the selection and mirror state on …
mihar-22 Sep 3, 2026
cefbb6a
fix(sandbox): boot the StackBlitz template outside the workspace
mihar-22 Sep 3, 2026
679b447
fix(sandbox): default Tailwind to a skin source the page can load
mihar-22 Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ jobs:
- '@videojs/element'
- '@videojs/html'
- '@videojs/react'
- '@videojs/sandbox'

steps:
- name: Checkout code
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/pkg-pr-new.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ jobs:
# open a running player built from the pull request. Its `dev` script
# regenerates the gitignored src/ from templates/ on boot, so the sandbox
# still works even though src/ is never part of the upload.
# The template is apps/sandbox alone: no workspace catalog to resolve its `catalog:` specs, and no preview of
# the private packages its `workspace:` ranges name. Rewrite its manifest in place; this checkout is disposable.
- name: Prepare the StackBlitz template
run: pnpm --filter @videojs/sandbox exec tsx scripts/prepare-template.ts

- name: Publish preview packages
env:
VIDEOJS_SKIP_PACKAGE_DOCS: '1'
Expand Down
2 changes: 1 addition & 1 deletion apps/e2e/suites/player/app/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function getPageEntries(): Record<string, string> {
}

export default defineConfig({
root: 'src',
root: resolve(packageDir, 'src'),
appType: 'mpa',
define: {
__DEV__: 'true',
Expand Down
8 changes: 6 additions & 2 deletions apps/e2e/suites/player/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ export default defineConfig({
use: { ...devices['Desktop Firefox'], baseURL: 'http://localhost:5180' },
},
],
// The workspace overrides vite with the Vite+ core package, which only ships the vp binary, and the app folder is not
// a workspace package, so run Vite+ from the e2e package and point it at the app directory.
webServer: {
command: 'pnpm exec vite --port 5180',
cwd: resolve(import.meta.dirname, 'app'),
command: 'pnpm exec vp -C suites/player/app dev --port 5180 --strictPort',
cwd: resolve(import.meta.dirname, '../..'),
port: 5180,
stdout: 'pipe',
stderr: 'pipe',
reuseExistingServer: !process.env.CI,
timeout: 120_000,
},
Expand Down
13 changes: 13 additions & 0 deletions apps/e2e/suites/registry/overlays/rspack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "rspack-html-css",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "rspack build --mode production"
},
"devDependencies": {
"@rspack/cli": "2.2.2",
"@rspack/core": "2.2.2",
"typescript": "5.9.3"
}
}
30 changes: 30 additions & 0 deletions apps/e2e/suites/registry/overlays/rspack/rspack.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { fileURLToPath } from 'node:url';

import { rspack } from '@rspack/core';

const source = fileURLToPath(new URL('./src', import.meta.url));

export default {
entry: `${source}/main.ts`,
output: {
path: fileURLToPath(new URL('./dist', import.meta.url)),
filename: '[name].[contenthash].js',
clean: true,
},
resolve: {
extensions: ['.ts', '.js'],
alias: { '@': source },
},
module: {
rules: [
{ test: /\.ts$/, exclude: /node_modules/, loader: 'builtin:swc-loader', type: 'javascript/auto' },
// The registry's HTML skin templates are imported as strings.
{ resourceQuery: /raw/, type: 'asset/source' },
{ test: /\.css$/, type: 'css' },
],
},
plugins: [new rspack.HtmlRspackPlugin({ template: `${source}/index.html` })],
// Rspack's built-in CSS pipeline is opt-in; the skin's stylesheets are imported from its module.
experiments: { css: true },
performance: { hints: false },
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="data:," />
<title>Video.js Skins</title>
<title>Video.js registry consumer</title>
</head>
<body>
<main id="root"></main>
<script type="module" src="./main.tsx"></script>
<div id="app"></div>
</body>
</html>
15 changes: 15 additions & 0 deletions apps/e2e/suites/registry/overlays/rspack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"isolatedModules": true,
"skipLibCheck": true,
"noEmit": true,
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
},
"include": ["src"]
}
38 changes: 38 additions & 0 deletions apps/e2e/suites/registry/overlays/static/serve.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Serves a bundler's `dist/` the way any static host would, so the suite drives the built output rather than a dev server.
import { readFile } from 'node:fs/promises';
import { createServer } from 'node:http';
import { extname, join, normalize, resolve } from 'node:path';

const [directory = 'dist', port = '0'] = process.argv.slice(2);
const root = resolve(directory);
const types = {
'.css': 'text/css; charset=utf-8',
'.html': 'text/html; charset=utf-8',
'.js': 'text/javascript; charset=utf-8',
'.json': 'application/json; charset=utf-8',
'.map': 'application/json; charset=utf-8',
'.mjs': 'text/javascript; charset=utf-8',
'.svg': 'image/svg+xml',
'.woff2': 'font/woff2',
};

createServer(async (request, response) => {
const { pathname } = new URL(request.url ?? '/', 'http://127.0.0.1');
const path = normalize(join(root, pathname.endsWith('/') ? `${pathname}index.html` : pathname));

if (!path.startsWith(root)) {
response.statusCode = 400;
response.end('Invalid path.');
return;
}

try {
const body = await readFile(path);

response.setHeader('content-type', types[extname(path)] ?? 'application/octet-stream');
response.end(body);
} catch {
response.statusCode = 404;
response.end('Not found.');
}
}).listen(Number(port), '127.0.0.1');
23 changes: 23 additions & 0 deletions apps/e2e/suites/registry/overlays/webpack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "webpack-react-css",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "webpack --mode production"
},
"dependencies": {
"react": "19.2.8",
"react-dom": "19.2.8"
},
"devDependencies": {
"@types/react": "19.2.18",
"@types/react-dom": "19.2.5",
"css-loader": "7.1.5",
"html-webpack-plugin": "5.6.8",
"style-loader": "4.0.0",
"ts-loader": "9.6.2",
"typescript": "5.9.3",
"webpack": "5.110.3",
"webpack-cli": "7.2.3"
}
}
1 change: 1 addition & 0 deletions apps/e2e/suites/registry/overlays/webpack/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module '*.css';
11 changes: 11 additions & 0 deletions apps/e2e/suites/registry/overlays/webpack/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Video.js registry consumer</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
10 changes: 10 additions & 0 deletions apps/e2e/suites/registry/overlays/webpack/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createRoot } from 'react-dom/client';

import { Player } from './player';

import './style.css';

const root = document.querySelector('#app');
if (!root) throw new Error('Could not find the application root.');

createRoot(root).render(<Player />);
5 changes: 5 additions & 0 deletions apps/e2e/suites/registry/overlays/webpack/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
body {
margin: 0;
padding: 2rem;
font-family: system-ui, sans-serif;
}
18 changes: 18 additions & 0 deletions apps/e2e/suites/registry/overlays/webpack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"noEmit": true,
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
},
"include": ["src"]
}
27 changes: 27 additions & 0 deletions apps/e2e/suites/registry/overlays/webpack/webpack.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { fileURLToPath } from 'node:url';

import HtmlWebpackPlugin from 'html-webpack-plugin';

const source = fileURLToPath(new URL('./src', import.meta.url));

export default {
entry: `${source}/main.tsx`,
output: {
path: fileURLToPath(new URL('./dist', import.meta.url)),
filename: '[name].[contenthash].js',
clean: true,
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
alias: { '@': source },
},
module: {
rules: [
// Types are checked separately with `tsc`; the loader only strips them.
{ test: /\.tsx?$/, exclude: /node_modules/, loader: 'ts-loader', options: { transpileOnly: true } },
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
],
},
plugins: [new HtmlWebpackPlugin({ template: `${source}/index.html` })],
performance: { hints: false },
};
23 changes: 23 additions & 0 deletions apps/e2e/suites/registry/projects.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { skinCatalog } from '../../../../packages/skins/build/catalog.ts';

/** The tool that scaffolds, builds, and serves a consumer. Bundler compatibility is a property of the packages. */
export type RegistryConsumerBundler = 'next' | 'vite' | 'webpack' | 'rspack';

interface RegistryConsumerProjectBase {
readonly name: string;
readonly directory: string;
readonly port: number;
readonly bundler: RegistryConsumerBundler;
}

export type RegistryConsumerProject = RegistryConsumerProjectBase &
Expand All @@ -24,20 +28,39 @@ export const registryConsumerProjects = [
directory: 'next-react-tailwind',
framework: 'react',
styling: 'tailwind',
bundler: 'next',
port: 5310,
},
{
name: 'next-react-css',
directory: 'next-react-css',
framework: 'react',
styling: 'css',
bundler: 'next',
port: 5311,
},
{
name: 'vite-html-css',
directory: 'vite-html-css',
framework: 'html',
styling: 'css',
bundler: 'vite',
port: 5312,
},
{
name: 'webpack-react-css',
directory: 'webpack-react-css',
framework: 'react',
styling: 'css',
bundler: 'webpack',
port: 5313,
},
{
name: 'rspack-html-css',
directory: 'rspack-html-css',
framework: 'html',
styling: 'css',
bundler: 'rspack',
port: 5314,
},
] as const satisfies readonly RegistryConsumerProject[];
Loading
Loading