дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
The Vue editor mode (`@codemirror/lang-vue` over the stock HTML base) parses every `<style>` block as plain CSS, so SCSS — nested rules, $-variables, and so on — rendered uncoloured or mis-highlighted. Register a Vue mode of our own (overriding the language-data entry) that gives the HTML base a nested Sass grammar for `<style>` whose `lang` is `scss` or `sass`; blocks without a dialect keep CSS.
Цей коміт міститься в:
1 джерело
3dac5b8bdc
коміт
95843ea12d
5 files changed
+67
No files matched your search
@@ -46,6 +46,8 @@
|
||||
"@codemirror/lang-html": "^6.4.12",
|
||||
"@codemirror/lang-java": "^6.0.2",
|
||||
"@codemirror/lang-javascript": "^6.2.5",
|
||||
"@codemirror/lang-sass": "^6.0.2",
|
||||
"@codemirror/lang-vue": "^0.1.3",
|
||||
"@codemirror/language": "^6.13.1",
|
||||
"@codemirror/language-data": "^6.5.2",
|
||||
"@codemirror/legacy-modes": "^6.5.5",
|
||||
|
||||
Створено
@@ -23,6 +23,12 @@ importers:
|
||||
'@codemirror/lang-javascript':
|
||||
specifier: ^6.2.5
|
||||
version: 6.2.5
|
||||
'@codemirror/lang-sass':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
'@codemirror/lang-vue':
|
||||
specifier: ^0.1.3
|
||||
version: 0.1.3
|
||||
'@codemirror/language':
|
||||
specifier: ^6.13.1
|
||||
version: 6.13.1
|
||||
|
||||
@@ -131,6 +131,12 @@ const OWN_MODES = [
|
||||
extensions: ["astro"],
|
||||
load: () => import("./astro").then((m) => m.astro()),
|
||||
}),
|
||||
// Overrides the language-data Vue mode so `<style lang="scss">` highlights.
|
||||
LanguageDescription.of({
|
||||
name: "Vue",
|
||||
extensions: ["vue"],
|
||||
load: () => import("./vue").then((m) => m.vueLanguage()),
|
||||
}),
|
||||
LanguageDescription.of({
|
||||
name: "YAML",
|
||||
alias: ["yml"],
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { findLanguageDescription, loadSupport } from "./languages";
|
||||
|
||||
describe("vue language mode", () => {
|
||||
it('highlights SCSS inside <style lang="scss">', async () => {
|
||||
const desc = findLanguageDescription("Vue", "/p/a.vue")!;
|
||||
expect(desc?.name).toBe("Vue");
|
||||
const support = await loadSupport(desc);
|
||||
const src = `<template><div/></template>\n` + `<style lang="scss">\n.a { .b { color: red; } $c: 1; }\n</style>`;
|
||||
const tree = support!.language.parser.parse(src).toString();
|
||||
// SCSS-only syntax that plain CSS can't parse: a nested rule and a $-variable.
|
||||
expect(tree).toContain("SassVariableName");
|
||||
// The nested .b ruleset only parses under the Sass grammar.
|
||||
expect(tree).toMatch(/RuleSet\(ClassSelector.*RuleSet\(ClassSelector/s);
|
||||
});
|
||||
|
||||
it("still parses a plain <style> block as CSS", async () => {
|
||||
const support = await loadSupport(findLanguageDescription("Vue", "/p/a.vue")!);
|
||||
const tree = support!.language.parser
|
||||
.parse(`<template><div/></template><style>.a { color: red; }</style>`)
|
||||
.toString();
|
||||
expect(tree).toContain("StyleSheet");
|
||||
expect(tree).toContain("Declaration");
|
||||
expect(tree).not.toContain("SassVariableName");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Vue single-file components: `@codemirror/lang-vue`'s parser over an HTML
|
||||
* base that also highlights `<style lang="scss|sass">` with the Sass grammar —
|
||||
* stock `vue()` parses every `<style>` as plain CSS, which loses the SCSS
|
||||
* colours.
|
||||
*/
|
||||
import { LanguageSupport } from "@codemirror/language";
|
||||
import { html } from "@codemirror/lang-html";
|
||||
import { sassLanguage } from "@codemirror/lang-sass";
|
||||
import { vue } from "@codemirror/lang-vue";
|
||||
|
||||
export function vueLanguage(): LanguageSupport {
|
||||
return vue({
|
||||
base: html({
|
||||
selfClosingTags: true,
|
||||
// `<style>` without `lang` (or with `lang="css"`) keeps HTML's own CSS
|
||||
// nesting; only an explicit SCSS/Sass dialect re-parses it.
|
||||
nestedLanguages: [
|
||||
{
|
||||
tag: "style",
|
||||
attrs: (a) => a.lang === "scss" || a.lang === "sass",
|
||||
parser: sassLanguage.parser,
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
}
|
||||
Reference in new issue
Заблокувати користувача