feat(ui): finalize E-TIB modernization with footer redesign, video optimization, and TS fixes

Former-commit-id: 67ac02c8404cc66893fdf97308574701cca6000c
This commit is contained in:
2026-05-07 10:43:20 +02:00
parent f2fdea96ec
commit 5439df72ea
3712 changed files with 932332 additions and 1867 deletions
@@ -0,0 +1 @@
../../micromark-core-commonmark@2.0.3/node_modules/micromark-core-commonmark
@@ -0,0 +1,2 @@
// Note: more types exposed from `index.d.ts`.
export { mdxjsEsm } from './lib/syntax.js';
@@ -0,0 +1,267 @@
/**
* @typedef {import('micromark-util-events-to-acorn').Acorn} Acorn
* @typedef {import('micromark-util-events-to-acorn').AcornOptions} AcornOptions
* @typedef {import('micromark-util-types').Extension} Extension
* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
*/
/**
* @typedef Options
* Configuration (required).
* @property {Acorn} acorn
* Acorn parser to use (required).
* @property {AcornOptions | null | undefined} [acornOptions]
* Configuration for acorn (default: `{ecmaVersion: 2024, locations: true,
* sourceType: 'module'}`); all fields except `locations` can be set.
* @property {boolean | null | undefined} [addResult=false]
* Whether to add `estree` fields to tokens with results from acorn
* (default: `false`).
*/
import { blankLine } from 'micromark-core-commonmark';
import { asciiAlpha, markdownLineEnding } from 'micromark-util-character';
import { eventsToAcorn } from 'micromark-util-events-to-acorn';
import { positionFromEstree } from 'unist-util-position-from-estree';
import { VFileMessage } from 'vfile-message';
const blankLineBefore = {
tokenize: tokenizeNextBlank,
partial: true
};
const trouble = 'https://github.com/micromark/micromark-extension-mdxjs-esm';
const allowedAcornTypes = new Set(['ExportAllDeclaration', 'ExportDefaultDeclaration', 'ExportNamedDeclaration', 'ImportDeclaration']);
/**
* Create an extension for `micromark` to enable MDX ESM syntax.
*
* @param {Options} options
* Configuration (required).
* @returns {Extension}
* Extension for `micromark` that can be passed in `extensions` to enable MDX
* ESM syntax.
*/
export function mdxjsEsm(options) {
const exportImportConstruct = {
tokenize: tokenizeExportImport,
concrete: true
};
if (!options || !options.acorn || !options.acorn.parse) {
throw new Error('Expected an `acorn` instance passed in as `options.acorn`');
}
const acorn = options.acorn;
const acornOptions = Object.assign({
ecmaVersion: 2024,
sourceType: 'module'
}, options.acornOptions, {
locations: true
});
return {
flow: {
[101]: exportImportConstruct,
[105]: exportImportConstruct
}
};
/**
* @this {TokenizeContext}
* @type {Tokenizer}
*/
function tokenizeExportImport(effects, ok, nok) {
const self = this;
const definedModuleSpecifiers = self.parser.definedModuleSpecifiers || (self.parser.definedModuleSpecifiers = []);
const eventStart = this.events.length + 1; // Add the main `mdxjsEsm` token
let buffer = '';
return self.interrupt ? nok : start;
/**
* Start of MDX ESM.
*
* ```markdown
* > | import a from 'b'
* ^
* ```
*
* @type {State}
*/
function start(code) {
// Only at the start of a line, not at whitespace or in a container.
if (self.now().column > 1) return nok(code);
effects.enter('mdxjsEsm');
effects.enter('mdxjsEsmData');
effects.consume(code);
// eslint-disable-next-line unicorn/prefer-code-point
buffer += String.fromCharCode(code);
return word;
}
/**
* In keyword.
*
* ```markdown
* > | import a from 'b'
* ^^^^^^
* ```
*
* @type {State}
*/
function word(code) {
if (asciiAlpha(code)) {
effects.consume(code);
// @ts-expect-error: definitely a number.
// eslint-disable-next-line unicorn/prefer-code-point
buffer += String.fromCharCode(code);
return word;
}
if ((buffer === 'import' || buffer === 'export') && code === 32) {
effects.consume(code);
return inside;
}
return nok(code);
}
/**
* In data.
*
* ```markdown
* > | import a from 'b'
* ^
* ```
*
* @type {State}
*/
function inside(code) {
if (code === null || markdownLineEnding(code)) {
effects.exit('mdxjsEsmData');
return lineStart(code);
}
effects.consume(code);
return inside;
}
/**
* At line ending.
*
* ```markdown
* > | import a from 'b'
* ^
* | export {a}
* ```
*
* @type {State}
*/
function lineStart(code) {
if (code === null) {
return atEnd(code);
}
if (markdownLineEnding(code)) {
return effects.check(blankLineBefore, atEnd, continuationStart)(code);
}
effects.enter('mdxjsEsmData');
return inside(code);
}
/**
* At line ending that continues.
*
* ```markdown
* > | import a from 'b'
* ^
* | export {a}
* ```
*
* @type {State}
*/
function continuationStart(code) {
effects.enter("lineEnding");
effects.consume(code);
effects.exit("lineEnding");
return lineStart;
}
/**
* At end of line (blank or eof).
*
* ```markdown
* > | import a from 'b'
* ^
* ```
*
* @type {State}
*/
function atEnd(code) {
const result = eventsToAcorn(self.events.slice(eventStart), {
acorn,
acornOptions,
tokenTypes: ['mdxjsEsmData'],
prefix: definedModuleSpecifiers.length > 0 ? 'var ' + definedModuleSpecifiers.join(',') + '\n' : ''
});
if (result.error) {
// There’s an error, which could be solved with more content, and there
// is more content.
if (code !== null && result.swallow) {
return continuationStart(code);
}
const error = new VFileMessage('Could not parse import/exports with acorn', {
cause: result.error,
place: {
line: result.error.loc.line,
column: result.error.loc.column + 1,
offset: result.error.pos
},
ruleId: 'acorn',
source: 'micromark-extension-mdxjs-esm'
});
error.url = trouble + '#could-not-parse-importexports-with-acorn';
throw error;
}
// Remove the `VariableDeclaration`.
if (definedModuleSpecifiers.length > 0) {
const declaration = result.estree.body.shift();
}
let index = -1;
while (++index < result.estree.body.length) {
const node = result.estree.body[index];
if (!allowedAcornTypes.has(node.type)) {
const error = new VFileMessage('Unexpected `' + node.type + '` in code: only import/exports are supported', {
place: positionFromEstree(node),
ruleId: 'non-esm',
source: 'micromark-extension-mdxjs-esm'
});
error.url = trouble + '#unexpected-type-in-code-only-importexports-are-supported';
throw error;
}
// Otherwise, when we’re not interrupting (hacky, because `interrupt` is
// used to parse containers and “sniff” if this is ESM), collect all the
// local values that are imported.
if (node.type === 'ImportDeclaration' && !self.interrupt) {
let index = -1;
while (++index < node.specifiers.length) {
const specifier = node.specifiers[index];
definedModuleSpecifiers.push(specifier.local.name);
}
}
}
Object.assign(effects.exit('mdxjsEsm'), options.addResult ? {
estree: result.estree
} : undefined);
return ok(code);
}
}
}
/** @type {Tokenizer} */
function tokenizeNextBlank(effects, ok, nok) {
return start;
/**
* @type {State}
*/
function start(code) {
effects.enter("lineEndingBlank");
effects.consume(code);
effects.exit("lineEndingBlank");
return effects.attempt(blankLine, ok, nok);
}
}
@@ -0,0 +1,112 @@
{
"name": "micromark-extension-mdxjs-esm",
"version": "3.0.0",
"description": "micromark extension to support MDX JS import/exports",
"license": "MIT",
"keywords": [
"micromark",
"micromark-extension",
"mdx",
"mdxjs",
"import",
"export",
"js",
"javascript",
"es",
"ecmascript",
"markdown",
"unified"
],
"repository": "micromark/micromark-extension-mdxjs-esm",
"bugs": "https://github.com/micromark/micromark-extension-mdxjs-esm/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"sideEffects": false,
"type": "module",
"exports": {
"development": "./dev/index.js",
"default": "./index.js"
},
"files": [
"dev/",
"lib/",
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/estree": "^1.0.0",
"devlop": "^1.0.0",
"micromark-core-commonmark": "^2.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-events-to-acorn": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0",
"unist-util-position-from-estree": "^2.0.0",
"vfile-message": "^4.0.0"
},
"devDependencies": {
"@types/acorn": "^4.0.0",
"@types/node": "^20.0.0",
"acorn": "^8.0.0",
"acorn-jsx": "^5.0.0",
"c8": "^8.0.0",
"micromark": "^4.0.0",
"micromark-build": "^2.0.0",
"prettier": "^3.0.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"type-coverage": "^2.0.0",
"typescript": "^5.0.0",
"xo": "^0.56.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "tsc --build --clean && tsc --build && type-coverage && micromark-build",
"format": "remark . -qfo && prettier . -w --log-level warn && xo --fix",
"test-api-prod": "node --conditions production test/index.js",
"test-api-dev": "node --conditions development test/index.js",
"test-api": "npm run test-api-dev && npm run test-api-prod",
"test-coverage": "c8 --100 --reporter lcov npm run test-api",
"test": "npm run build && npm run format && npm run test-coverage"
},
"prettier": {
"bracketSpacing": false,
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false
},
"remarkConfig": {
"plugins": [
"remark-preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"ignoreCatch": true,
"strict": true
},
"xo": {
"prettier": true,
"rules": {
"n/file-extension-in-import": "off",
"unicorn/no-this-assignment": "off"
},
"overrides": [
{
"files": "test/**/*.js",
"rules": {
"no-await-in-loop": "off"
}
}
]
}
}
@@ -0,0 +1 @@
../../micromark-util-character@2.1.1/node_modules/micromark-util-character
@@ -0,0 +1 @@
../../micromark-util-events-to-acorn@2.0.3/node_modules/micromark-util-events-to-acorn
@@ -0,0 +1 @@
../../unist-util-position-from-estree@2.0.0/node_modules/unist-util-position-from-estree
@@ -0,0 +1 @@
../../vfile-message@4.0.3/node_modules/vfile-message