Skip to content

Commit

Permalink
fix(js/css): Fixes intellisense inside inline styles and scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Princesseuh committed Jul 9, 2024
1 parent 9e45765 commit 6e548df
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
3 changes: 2 additions & 1 deletion packages/language-server/src/core/astro2tsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import type { ConvertToTSXOptions, TSXResult } from '@astrojs/compiler/types';
import { decode } from '@jridgewell/sourcemap-codec';
import type { CodeInformation, CodeMapping, VirtualCode } from '@volar/language-core';
import { Range } from '@volar/language-server';
import { HTMLDocument, TextDocument } from 'vscode-html-languageservice';
import type { HTMLDocument } from 'vscode-html-languageservice';
import { TextDocument } from 'vscode-languageserver-textdocument';
import { patchTSX } from './utils.js';

export interface LSPTSXRanges {
Expand Down
18 changes: 15 additions & 3 deletions packages/language-server/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import type { TypeScriptExtraServiceScript } from '@volar/typescript';
import type ts from 'typescript';
import type { HTMLDocument } from 'vscode-html-languageservice';
import { TextDocument } from 'vscode-languageserver-textdocument';
import type { URI } from 'vscode-uri';
import { type AstroInstall, getLanguageServerTypesDir } from '../utils.js';
import { astro2tsx } from './astro2tsx';
Expand Down Expand Up @@ -161,6 +162,13 @@ export class AstroVirtualCode implements VirtualCode {
];
this.compilerDiagnostics = [];

const astroDocument = TextDocument.create(
fileName + '.astro',
'astro',
0,
snapshot.getText(0, snapshot.getLength())
);

const astroMetadata = getAstroMetadata(
this.fileName,
this.snapshot.getText(0, this.snapshot.getLength())
Expand All @@ -178,13 +186,17 @@ export class AstroVirtualCode implements VirtualCode {
);
this.htmlDocument = htmlDocument;

const scriptTags = extractScriptTags(this.snapshot, htmlDocument, astroMetadata.ast);
const scriptTags = extractScriptTags(
this.snapshot,
astroDocument,
htmlDocument,
astroMetadata.ast
);

this.scriptCodeIds = scriptTags.map((scriptTag) => scriptTag.id);

htmlVirtualCode.embeddedCodes = [];
htmlVirtualCode.embeddedCodes.push(
...extractStylesheets(this.snapshot, htmlDocument, astroMetadata.ast),
...extractStylesheets(this.snapshot, astroDocument, htmlDocument, astroMetadata.ast),
...scriptTags
);

Expand Down
7 changes: 4 additions & 3 deletions packages/language-server/src/core/parseCSS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { is } from '@astrojs/compiler/utils';
import type { CodeInformation, VirtualCode } from '@volar/language-core';
import { Segment, toString } from 'muggle-string';
import type ts from 'typescript';
import type { HTMLDocument, Node } from 'vscode-html-languageservice';
import type { HTMLDocument, Node, TextDocument } from 'vscode-html-languageservice';
import { buildMappings } from '../buildMappings.js';
import type { AttributeNodeWithPosition } from './compilerUtils.js';
import { type AttributeNodeWithPosition, PointToPosition } from './compilerUtils.js';

export function extractStylesheets(
snapshot: ts.IScriptSnapshot,
astroDocument: TextDocument,
htmlDocument: HTMLDocument,
ast: ParseResult['ast']
): VirtualCode[] {
Expand All @@ -22,7 +23,7 @@ export function extractStylesheets(
codes.push([
inlineStyle.value,
undefined,
inlineStyle.position.start.offset + 'style="'.length,
astroDocument.offsetAt(PointToPosition(inlineStyle.position.start)) + 'style="'.length,
{
completion: true,
verification: false,
Expand Down
15 changes: 11 additions & 4 deletions packages/language-server/src/core/parseJS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import { is } from '@astrojs/compiler/utils';
import type { CodeInformation, VirtualCode } from '@volar/language-core';
import { Segment, toString } from 'muggle-string';
import type ts from 'typescript';
import type { HTMLDocument, Node } from 'vscode-html-languageservice';
import type { HTMLDocument, Node, TextDocument } from 'vscode-html-languageservice';
import { buildMappings } from '../buildMappings';
import { PointToPosition } from './compilerUtils.js';

export function extractScriptTags(
snapshot: ts.IScriptSnapshot,
astroDocument: TextDocument,
htmlDocument: HTMLDocument,
ast: ParseResult['ast']
): VirtualCode[] {
const embeddedJSCodes: VirtualCode[] = findModuleScripts(snapshot, htmlDocument.roots);

const javascriptContexts = [
...findClassicScripts(htmlDocument, snapshot),
...findEventAttributes(ast),
...findEventAttributes(ast, astroDocument),
].sort((a, b) => a.startOffset - b.startOffset);

if (javascriptContexts.length > 0) {
Expand Down Expand Up @@ -153,7 +155,10 @@ function isJSON(type: string | null | undefined): boolean {
return JSON_TYPES.includes(type.slice(1, -1));
}

function findEventAttributes(ast: ParseResult['ast']): JavaScriptContext[] {
function findEventAttributes(
ast: ParseResult['ast'],
astroDocument: TextDocument
): JavaScriptContext[] {
const eventAttrs: JavaScriptContext[] = [];

// `@astrojs/compiler`'s `walk` method is async, so we can't use it here. Arf
Expand All @@ -172,7 +177,9 @@ function findEventAttributes(ast: ParseResult['ast']): JavaScriptContext[] {
// This is not perfect, but it's better than nothing
// See: https://github.com/microsoft/vscode/blob/e8e04769ec817a3374c3eaa26a08d3ae491820d5/extensions/html-language-features/server/src/modes/embeddedSupport.ts#L192
content: eventAttribute.value + ';',
startOffset: eventAttribute.position.start.offset + `${eventAttribute.name}="`.length,
startOffset:
astroDocument.offsetAt(PointToPosition(eventAttribute.position.start)) +
`${eventAttribute.name}="`.length,
});
}
}
Expand Down

0 comments on commit 6e548df

Please sign in to comment.