Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ npm-debug.log*
# locally as part of its build step — they don't need to be committed.
examples/*/pnpm-lock.yaml
scripts/__tests__/integration/fixtures/*/pnpm-lock.yaml
*.tsbuildinfo
4 changes: 2 additions & 2 deletions examples/extension-sveltekit-ssr-hydration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@lexical/table": "0.44.0",
"@lexical/tailwind": "0.44.0",
"@lexical/utils": "0.44.0",
"@playwright/test": "^1.58.2",
"@playwright/test": "^1.60.0",
"@sveltejs/adapter-auto": "^6.1.1",
"@sveltejs/kit": "^2.53.3",
"@sveltejs/vite-plugin-svelte": "^6.2.4",
Expand All @@ -40,7 +40,7 @@
"eslint-plugin-svelte": "^3.15.0",
"globals": "^16.5.0",
"lexical": "0.44.0",
"playwright": "^1.58.2",
"playwright": "^1.60.0",
"prettier": "^3.8.1",
"prettier-plugin-svelte": "^3.5.0",
"prettier-plugin-tailwindcss": "^0.7.2",
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs-code-shiki/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"react-dom": "^19"
},
"devDependencies": {
"@playwright/test": "^1.51.1",
"@playwright/test": "^1.60.0",
"@types/node": "^20",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.1.9",
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"flow-typed-install": "flow-typed install -s -o --ignoreDeps dev peer bundled",
"tsc": "tsc",
"tsc-scripts": "tsc -p ./tsconfig.scripts.json",
"tsc-test": "tsc -p ./tsconfig.test.json",
"tsc-extension": "pnpm --filter @lexical/devtools run compile",
"tsc-website": "pnpm --filter @lexical/website run tsc",
"tsc-watch": "tsc -w",
Expand Down Expand Up @@ -90,7 +89,7 @@
"lint": "eslint ./",
"lint:fix": "eslint ./ --fix",
"prettier": "prettier --list-different .",
"ci-check": "npm-run-all --parallel tsc tsc-scripts tsc-test tsc-extension tsc-website flow prettier lint",
"ci-check": "npm-run-all --parallel tsc tsc-scripts tsc-extension tsc-website flow prettier lint",
"prettier:fix": "prettier --write .",
"prepare-ci": "pnpm run build-playground-dev",
"prepare-ci-prod": "pnpm run build-playground-prod",
Expand Down Expand Up @@ -126,7 +125,7 @@
"@eslint/js": "^10.0.0",
"@lexical/eslint-plugin": "workspace:*",
"@lexical/eslint-plugin-internal": "workspace:*",
"@playwright/test": "^1.59.1",
"@playwright/test": "^1.60.0",
"@prettier/sync": "^0.6.1",
"@rollup/plugin-alias": "^6.0.0",
"@rollup/plugin-babel": "^7.0.0",
Expand Down
9 changes: 8 additions & 1 deletion packages/lexical-code-shiki/src/CodeHighlighterShiki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,14 @@ function $codeNodeTransform(
let inFlight = false;
if (!isCodeThemeLoaded(theme)) {
loadCodeTheme(theme, editor, nodeKey);
inFlight = true;
// Only the highlight path (a resolved language) consumes the theme. With
// no language the text is plainified, which needs no theme, so don't defer
// the split on a theme load that won't be used — otherwise a code block
// with `defaultLanguage: null` stays an unsplit TextNode until the theme
// happens to finish loading.
if (language) {
inFlight = true;
}
}

// dynamic import of languages
Expand Down
44 changes: 38 additions & 6 deletions packages/lexical-html/src/DOMRenderExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,27 @@
*
*/
import type {DOMRenderConfig, DOMRenderExtensionOutput} from './types';
import type {InitialEditorConfig} from 'lexical';

import {defineExtension, RootNode, shallowMergeConfig} from 'lexical';

import {compileDOMRenderConfigOverrides} from './compileDOMRenderConfigOverrides';
import {DOMRenderExtensionName} from './constants';
import {contextFromPairs} from './ContextRecord';
import {
createEditorContextRecord,
DOMRenderRuntimeImpl,
filterEditorInstalled,
} from './DOMRenderRuntime';

/** @internal The result returned from {@link DOMRenderExtension}'s `init`. */
interface DOMRenderInitResult {
/**
* The `nodes` and base `dom` captured from the editor config before `dom`
* is overwritten with the compiled config — the only fields the runtime
* needs to recompile.
*/
initialEditorConfig: Pick<InitialEditorConfig, 'nodes' | 'dom'>;
}

/**
* @experimental
Expand All @@ -24,12 +39,18 @@ export const DOMRenderExtension = defineExtension<
DOMRenderConfig,
typeof DOMRenderExtensionName,
DOMRenderExtensionOutput,
void
DOMRenderInitResult
>({
build(editor, config, state) {
return {
defaults: contextFromPairs(config.contextDefaults, undefined),
};
const {initialEditorConfig} = state.getInitResult();
const editorContext = createEditorContextRecord(config.contextDefaults);
const runtime = new DOMRenderRuntimeImpl(
editor,
initialEditorConfig,
config.overrides,
editorContext,
);
return {defaults: editorContext, runtime};
},
config: {
contextDefaults: [],
Expand All @@ -49,7 +70,18 @@ export const DOMRenderExtension = defineExtension<
]),
},
init(editorConfig, config) {
editorConfig.dom = compileDOMRenderConfigOverrides(editorConfig, config);
// Capture the user's base `dom` (before we overwrite it) and `nodes` so the
// runtime can recompile from scratch when overrides toggle.
const initialEditorConfig: DOMRenderInitResult['initialEditorConfig'] = {
dom: editorConfig.dom,
nodes: editorConfig.nodes,
};
const editorContext = createEditorContextRecord(config.contextDefaults);
const installed = filterEditorInstalled(config.overrides, editorContext);
editorConfig.dom = compileDOMRenderConfigOverrides(editorConfig, {
overrides: installed,
});
return {initialEditorConfig};
},
mergeConfig(config, partial) {
const merged = shallowMergeConfig(config, partial);
Expand Down
Loading
Loading