Merge branch 'main' into dev/mjbvz/esbuild-gunt

This commit is contained in:
Matt Bierner
2026-02-12 15:09:29 -08:00
48 changed files with 1563 additions and 300 deletions
@@ -5,7 +5,6 @@
import DOMPurify from 'dompurify';
import MarkdownIt from 'markdown-it';
import type * as MarkdownItToken from 'markdown-it/lib/token';
import type { ActivationFunction } from 'vscode-notebook-renderer';
const allowedHtmlTags = Object.freeze(['a',
@@ -352,11 +351,11 @@ export const activate: ActivationFunction<void> = (ctx) => {
};
function addNamedHeaderRendering(md: InstanceType<typeof MarkdownIt>): void {
function addNamedHeaderRendering(md: MarkdownIt): void {
const slugCounter = new Map<string, number>();
const originalHeaderOpen = md.renderer.rules.heading_open;
md.renderer.rules.heading_open = (tokens: MarkdownItToken[], idx: number, options, env, self) => {
md.renderer.rules.heading_open = (tokens: MarkdownIt.Token[], idx: number, options, env, self) => {
const title = tokens[idx + 1].children!.reduce<string>((acc, t) => acc + t.content, '');
let slug = slugify(title);
@@ -378,17 +377,16 @@ function addNamedHeaderRendering(md: InstanceType<typeof MarkdownIt>): void {
};
const originalRender = md.render;
md.render = function () {
md.render = function (str: string, env?: unknown) {
slugCounter.clear();
// eslint-disable-next-line local/code-no-any-casts
return originalRender.apply(this, arguments as any);
return originalRender.call(this, str, env);
};
}
function addLinkRenderer(md: MarkdownIt): void {
const original = md.renderer.rules.link_open;
md.renderer.rules.link_open = (tokens: MarkdownItToken[], idx: number, options, env, self) => {
md.renderer.rules.link_open = (tokens: MarkdownIt.Token[], idx: number, options, env, self) => {
const token = tokens[idx];
const href = token.attrGet('href');
if (typeof href === 'string' && href.startsWith('#')) {
+11 -10
View File
@@ -14,7 +14,7 @@
"highlight.js": "^11.8.0",
"markdown-it": "^12.3.2",
"markdown-it-front-matter": "^0.2.4",
"morphdom": "^2.7.4",
"morphdom": "^2.7.7",
"picomatch": "^2.3.1",
"punycode": "^2.3.1",
"vscode-languageclient": "^8.0.2",
@@ -25,7 +25,7 @@
"devDependencies": {
"@types/dompurify": "^3.0.5",
"@types/lodash.throttle": "^4.1.9",
"@types/markdown-it": "12.2.3",
"@types/markdown-it": "^14.1.2",
"@types/node": "22.x",
"@types/picomatch": "^2.3.0",
"@types/vscode-notebook-renderer": "^1.60.0",
@@ -195,13 +195,14 @@
}
},
"node_modules/@types/markdown-it": {
"version": "12.2.3",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
"integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
"version": "14.1.2",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/linkify-it": "*",
"@types/mdurl": "*"
"@types/linkify-it": "^5",
"@types/mdurl": "^2"
}
},
"node_modules/@types/mdurl": {
@@ -523,9 +524,9 @@
}
},
"node_modules/morphdom": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.4.tgz",
"integrity": "sha512-ATTbWMgGa+FaMU3FhnFYB6WgulCqwf6opOll4CBzmVDTLvPMmUPrEv8CudmLPK0MESa64+6B89fWOxP3+YIlxQ==",
"version": "2.7.7",
"resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.7.tgz",
"integrity": "sha512-04GmsiBcalrSCNmzfo+UjU8tt3PhZJKzcOy+r1FlGA7/zri8wre3I1WkYN9PT3sIeIKfW9bpyElA+VzOg2E24g==",
"license": "MIT"
},
"node_modules/node-html-parser": {
@@ -778,7 +778,7 @@
"highlight.js": "^11.8.0",
"markdown-it": "^12.3.2",
"markdown-it-front-matter": "^0.2.4",
"morphdom": "^2.7.4",
"morphdom": "^2.7.7",
"picomatch": "^2.3.1",
"punycode": "^2.3.1",
"vscode-languageclient": "^8.0.2",
@@ -789,7 +789,7 @@
"devDependencies": {
"@types/dompurify": "^3.0.5",
"@types/lodash.throttle": "^4.1.9",
"@types/markdown-it": "12.2.3",
"@types/markdown-it": "^14.1.2",
"@types/node": "22.x",
"@types/picomatch": "^2.3.0",
"@types/vscode-notebook-renderer": "^1.60.0",
@@ -23,8 +23,12 @@ let documentResource = settings.settings.source;
const vscode = acquireVsCodeApi();
// eslint-disable-next-line local/code-no-any-casts
const originalState = vscode.getState() ?? {} as any;
interface State {
scrollProgress?: number;
resource?: string;
}
const originalState: State = vscode.getState() ?? {};
const state = {
...originalState,
...getData<any>('data-state')
@@ -250,7 +254,6 @@ window.addEventListener('message', async event => {
}
newRoot.prepend(...styles);
// eslint-disable-next-line local/code-no-any-casts
morphdom(root, newRoot, {
childrenOnly: true,
onBeforeElUpdated: (fromEl: Element, toEl: Element) => {
@@ -287,7 +290,7 @@ window.addEventListener('message', async event => {
domEval(childNode);
}
}
} as any);
});
}
++documentVersion;
@@ -441,8 +444,7 @@ function domEval(el: Element): void {
for (const key of preservedScriptAttributes) {
const val = node.getAttribute?.(key);
if (val) {
// eslint-disable-next-line local/code-no-any-casts
scriptTag.setAttribute(key, val as any);
scriptTag.setAttribute(key, val);
}
}
@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import type Token = require('markdown-it/lib/token');
import * as vscode from 'vscode';
import { FileRename, RequestType } from 'vscode-languageclient';
import type * as lsp from 'vscode-languageserver-types';
@@ -16,7 +15,7 @@ export type ResolvedDocumentLinkTarget =
| { readonly kind: 'external'; readonly uri: vscode.Uri };
//#region From server
export const parse = new RequestType<{ uri: string; text?: string }, Token[], any>('markdown/parse');
export const parse = new RequestType<{ uri: string; text?: string }, md.Token[], any>('markdown/parse');
export const fs_readFile = new RequestType<{ uri: string }, number[], any>('markdown/fs/readFile');
export const fs_readDirectory = new RequestType<{ uri: string }, [string, { isDirectory: boolean }][], any>('markdown/fs/readDirectory');
@@ -51,8 +51,7 @@ class AddToIgnoreLinksQuickFixProvider implements vscode.CodeActionProvider {
case DiagnosticCode.link_noSuchHeaderInOwnFile:
case DiagnosticCode.link_noSuchFile:
case DiagnosticCode.link_noSuchHeaderInFile: {
// eslint-disable-next-line local/code-no-any-casts
const hrefText = (diagnostic as any).data?.hrefText;
const hrefText = (diagnostic as unknown as Record<string, any>).data?.hrefText;
if (hrefText) {
const fix = new vscode.CodeAction(
vscode.l10n.t("Exclude '{0}' from link validation.", hrefText),
@@ -3,8 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import type MarkdownIt = require('markdown-it');
import type Token = require('markdown-it/lib/token');
import type MarkdownIt from 'markdown-it';
import * as vscode from 'vscode';
import { ILogger } from './logging';
import { MarkdownContributionProvider } from './markdownExtensions';
@@ -50,9 +49,9 @@ class TokenCache {
readonly version: number;
readonly config: MarkdownItConfig;
};
private _tokens?: Token[];
private _tokens?: MarkdownIt.Token[];
public tryGetCached(document: ITextDocument, config: MarkdownItConfig): Token[] | undefined {
public tryGetCached(document: ITextDocument, config: MarkdownItConfig): MarkdownIt.Token[] | undefined {
if (this._cachedDocument
&& this._cachedDocument.uri.toString() === document.uri.toString()
&& document.version >= 0 && this._cachedDocument.version === document.version
@@ -64,7 +63,7 @@ class TokenCache {
return undefined;
}
public update(document: ITextDocument, config: MarkdownItConfig, tokens: Token[]) {
public update(document: ITextDocument, config: MarkdownItConfig, tokens: MarkdownIt.Token[]) {
this._cachedDocument = {
uri: document.uri,
version: document.version,
@@ -94,7 +93,7 @@ interface RenderEnv {
export interface IMdParser {
readonly slugifier: ISlugifier;
tokenize(document: ITextDocument): Promise<Token[]>;
tokenize(document: ITextDocument): Promise<MarkdownIt.Token[]>;
}
export class MarkdownItEngine implements IMdParser {
@@ -143,8 +142,7 @@ export class MarkdownItEngine implements IMdParser {
const frontMatterPlugin = await import('markdown-it-front-matter');
// Extract rules from front matter plugin and apply at a lower precedence
let fontMatterRule: any;
// eslint-disable-next-line local/code-no-any-casts
frontMatterPlugin.default(<any>{
frontMatterPlugin.default({
block: {
ruler: {
before: (_id: any, _id2: any, rule: any) => { fontMatterRule = rule; }
@@ -180,7 +178,7 @@ export class MarkdownItEngine implements IMdParser {
document: ITextDocument,
config: MarkdownItConfig,
engine: MarkdownIt
): Token[] {
): MarkdownIt.Token[] {
const cached = this._tokenCache.tryGetCached(document, config);
if (cached) {
return cached;
@@ -228,7 +226,7 @@ export class MarkdownItEngine implements IMdParser {
};
}
public async tokenize(document: ITextDocument): Promise<Token[]> {
public async tokenize(document: ITextDocument): Promise<MarkdownIt.Token[]> {
const config = this._getConfig(document.uri);
const engine = await this._getEngine(config);
return this._tokenizeDocument(document, config, engine);
@@ -249,7 +247,7 @@ export class MarkdownItEngine implements IMdParser {
private _addImageRenderer(md: MarkdownIt): void {
const original = md.renderer.rules.image;
md.renderer.rules.image = (tokens: Token[], idx: number, options, env: RenderEnv, self) => {
md.renderer.rules.image = (tokens: MarkdownIt.Token[], idx: number, options, env: RenderEnv, self) => {
const token = tokens[idx];
const src = token.attrGet('src');
if (src) {
@@ -271,7 +269,7 @@ export class MarkdownItEngine implements IMdParser {
private _addFencedRenderer(md: MarkdownIt): void {
const original = md.renderer.rules['fenced'];
md.renderer.rules['fenced'] = (tokens: Token[], idx: number, options, env, self) => {
md.renderer.rules['fenced'] = (tokens: MarkdownIt.Token[], idx: number, options, env, self) => {
const token = tokens[idx];
if (token.map?.length) {
token.attrJoin('class', 'hljs');
@@ -313,7 +311,7 @@ export class MarkdownItEngine implements IMdParser {
private _addNamedHeaders(md: MarkdownIt): void {
const original = md.renderer.rules.heading_open;
md.renderer.rules.heading_open = (tokens: Token[], idx: number, options, env: unknown, self) => {
md.renderer.rules.heading_open = (tokens: MarkdownIt.Token[], idx: number, options, env: unknown, self) => {
const title = this._tokenToPlainText(tokens[idx + 1]);
const slug = (env as RenderEnv).slugifier ? (env as RenderEnv).slugifier.add(title) : this.slugifier.fromHeading(title);
tokens[idx].attrSet('id', slug.value);
@@ -326,7 +324,7 @@ export class MarkdownItEngine implements IMdParser {
};
}
private _tokenToPlainText(token: Token): string {
private _tokenToPlainText(token: MarkdownIt.Token): string {
if (token.children) {
return token.children.map(x => this._tokenToPlainText(x)).join('');
}
@@ -344,7 +342,7 @@ export class MarkdownItEngine implements IMdParser {
private _addLinkRenderer(md: MarkdownIt): void {
const original = md.renderer.rules.link_open;
md.renderer.rules.link_open = (tokens: Token[], idx: number, options, env, self) => {
md.renderer.rules.link_open = (tokens: MarkdownIt.Token[], idx: number, options, env, self) => {
const token = tokens[idx];
const href = token.attrGet('href');
// A string, including empty string, may be `href`.