-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
389 additions
and
567 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { rgbToHexColor, parseHexColor } from 'duoyun-ui/lib/color'; | ||
import { Range, Color } from 'vscode-languageserver/node'; | ||
import type { ColorInformation, ColorPresentation } from 'vscode-languageserver/node'; | ||
import type { HexColor } from 'duoyun-ui/lib/color'; | ||
import type { TextDocument } from 'vscode-languageserver-textdocument'; | ||
|
||
import { COLOR_REG } from './constants'; | ||
|
||
export class ColorProvider { | ||
provideDocumentColors(document: TextDocument) { | ||
COLOR_REG.exec('null'); | ||
|
||
const documentText = document.getText(); | ||
const colors: ColorInformation[] = []; | ||
|
||
let match: RegExpExecArray | null; | ||
while ((match = COLOR_REG.exec(documentText)) !== null) { | ||
const hex = match.groups!.content as HexColor; | ||
const [red, green, blue, alpha] = parseHexColor(hex); | ||
const offset = match.index + (match.groups!.start?.length || 0); | ||
const range = Range.create(document.positionAt(offset), document.positionAt(offset + hex.length)); | ||
const color = Color.create(red / 255, green / 255, blue / 255, alpha); | ||
colors.push({ range, color }); | ||
} | ||
return colors; | ||
} | ||
|
||
provideColorPresentations({ red, green, blue, alpha }: Color): ColorPresentation[] { | ||
return [{ label: rgbToHexColor([red * 255, green * 255, blue * 255, alpha]) }]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export const COLOR_REG = /(?<start>'|")?(?<content>#([0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4}))($1|\s*;|\s*\))/g; | ||
|
||
// 直接通过正则匹配 css 片段,通过条件的结束 ` 号匹配 | ||
export const CSS_REG = /(?<start>\/\*\s*css\s*\*\/\s*`|(?<!`)(?:css|less|scss)\s*`)(?<content>.*?)(`(?=;|,?\s*\)))/gs; | ||
// 直接通过正则匹配 style 片段,通过条件的结束 ` 号匹配 | ||
// 语言服务和高亮都只支持 styled 写法 | ||
export const STYLE_REG = /(?<start>\/\*\s*style\s*\*\/\s*`|(?<!`)styled?\s*`)(?<content>.*?)(`(?=,|\s*}\s*\)))/gs; | ||
|
||
// 处理后进行正则匹配,所以不需要验证后面的 ` 号 | ||
export const HTML_REG = /(?<start>\/\*\s*html\s*\*\/\s*`|(?<!`)(?:html|raw)\s*`)(?<content>[^`]*)(`)/g; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// 只对 CSS 语法和属性做了简单的检查,不做值检查 | ||
// TODO: 激活扩展、打开工作区时需要自动诊断所有文件 | ||
// TODO: 使用 LRU 缓存 | ||
|
||
import { getCSSLanguageService } from 'vscode-css-languageservice'; | ||
import { Range } from 'vscode-languageserver/node'; | ||
import type { Diagnostic } from 'vscode-languageserver/node'; | ||
import type { TextDocument } from 'vscode-languageserver-textdocument'; | ||
|
||
import { CSS_REG, STYLE_REG } from './constants'; | ||
import { createVirtualDocument, removeSlot } from './util'; | ||
|
||
const cssLanguageService = getCSSLanguageService(); | ||
|
||
export function getDiagnostics(document: TextDocument, _relatedInformation: boolean) { | ||
const diagnostics: Diagnostic[] = []; | ||
const text = document.getText(); | ||
|
||
const matchFragments = (regexp: RegExp, appendBefore: string, appendAfter: string) => { | ||
regexp.exec('null'); | ||
|
||
let match; | ||
while ((match = regexp.exec(text))) { | ||
const matchContent = match.groups!.content; | ||
const offset = match.index + match.groups!.start.length; | ||
const virtualDocument = createVirtualDocument('css', `${appendBefore}${removeSlot(matchContent)}${appendAfter}`); | ||
const vCss = cssLanguageService.parseStylesheet(virtualDocument); | ||
const oDiagnostics = cssLanguageService.doValidation(virtualDocument, vCss) as Diagnostic[]; | ||
for (const { message, range } of oDiagnostics) { | ||
const { start, end } = range; | ||
const startOffset = virtualDocument.offsetAt(start) - appendBefore.length + offset; | ||
const endOffset = virtualDocument.offsetAt(end) - appendBefore.length + offset; | ||
diagnostics.push({ | ||
range: Range.create(document.positionAt(startOffset), document.positionAt(endOffset)), | ||
message, | ||
}); | ||
} | ||
} | ||
}; | ||
|
||
matchFragments(CSS_REG, '', ''); | ||
matchFragments(STYLE_REG, ':host { ', ' }'); | ||
|
||
return diagnostics; | ||
} |
Oops, something went wrong.