Skip to content

Commit 9830bdb

Browse files
committed
Added config
1 parent bdc135c commit 9830bdb

File tree

3 files changed

+72
-10
lines changed

3 files changed

+72
-10
lines changed

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@ Missing CSS support for HTML documents.
55
## Features
66

77
- Html class attribute completion.
8-
- Parses `html<link rel="stylesheet">` and `html<style></style>` tags.
9-
- Supports remote css files.
8+
- Parses `<link rel="stylesheet">` and `<style></style>` tags.
9+
- Supports remote style sheets.
10+
11+
## Remote Style Sheets
12+
13+
Remote style sheets can be specified in VS Code settings:
14+
15+
```json
16+
"css.remoteStyleSheets": [
17+
"https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
18+
]
19+
```
1020

1121
## Supported Languages
1222

23+
Support for other types of html like documents can be added in VS Code settings:
24+
1325
```json
1426
"files.associations": {
1527
"*.tpl": "html",

package.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@
2828
"activationEvents": [
2929
"onLanguage:html"
3030
],
31+
"contributes": {
32+
"configuration": {
33+
"title": "CSS Settings",
34+
"properties": {
35+
"css.remoteStyleSheets": {
36+
"type": "array",
37+
"default": [],
38+
"description": "A list of remote style sheets."
39+
}
40+
}
41+
}
42+
},
3143
"main": "./out/extension.js",
3244
"scripts": {
3345
"vscode:prepublish": "npm run compile",
@@ -56,4 +68,4 @@
5668
"@types/node-fetch": "^2.5.7",
5769
"node-fetch": "^2.6.1"
5870
}
59-
}
71+
}

src/extension.ts

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
languages,
33
Range,
4+
workspace,
45
ExtensionContext,
56
CompletionItemProvider,
67
TextDocument,
@@ -27,16 +28,34 @@ class ClassCompletionItemProvider implements CompletionItemProvider {
2728
readonly findLinkRel = /rel\s*=\s*(["'])((?:(?!\1).)+)\1/si;
2829
readonly findLinkHref = /href\s*=\s*(["'])((?:(?!\1).)+)\1/si;
2930

31+
remoteStyles: string[] = [];
32+
33+
constructor(context: ExtensionContext) {
34+
this.parseRemoteConfig();
35+
36+
context.subscriptions.push(workspace.onDidChangeConfiguration(e => this.parseRemoteConfig()));
37+
}
38+
39+
parseRemoteConfig() {
40+
const config = workspace.getConfiguration('css');
41+
const hrefs = config.get('remoteStyleSheets') as string[];
42+
43+
if (hrefs) {
44+
this.remoteStyles = hrefs;
45+
}
46+
}
47+
3048
fetchRemoteStyleSheet(href: string): Thenable<Map<string, CompletionItem>> {
31-
return new Promise((resolve) => {
49+
50+
return new Promise(resolve => {
3251
const selectors = this.cache.get(href);
3352

3453
if (selectors) {
3554
resolve(selectors);
3655
} else {
3756
const selectors = new Map<string, CompletionItem>();
3857

39-
fetch(href).then(res => {
58+
fetch(href).then(res => {
4059
if (res.status === 200) {
4160
res.text().then(text => {
4261
walk(parse(text), (node) => {
@@ -57,8 +76,8 @@ class ClassCompletionItemProvider implements CompletionItemProvider {
5776
});
5877
}
5978

60-
findRemoteStyleSheets(text: string): Thenable<Map<string, CompletionItem>> {
61-
return new Promise((resolve) => {
79+
findDocumentLinks(text: string): Thenable<Map<string, CompletionItem>> {
80+
return new Promise(resolve => {
6281
const links = new Map<string, CompletionItem>();
6382
const findLinks = /<link([^>]+)>/gi;
6483
const promises = [];
@@ -83,6 +102,21 @@ class ClassCompletionItemProvider implements CompletionItemProvider {
83102
});
84103
}
85104

105+
findRemoteStyles(): Thenable<Map<string, CompletionItem>> {
106+
return new Promise(resolve => {
107+
const links = new Map<string, CompletionItem>();
108+
const promises = [];
109+
110+
for (let i = 0; i < this.remoteStyles.length; i++) {
111+
promises.push(this.fetchRemoteStyleSheet(this.remoteStyles[i]).then(items => {
112+
items.forEach((value, key) => links.set(key, value));
113+
}));
114+
}
115+
116+
Promise.all(promises).then(() => resolve(links));
117+
});
118+
}
119+
86120
provideCompletionItems(
87121
document: TextDocument,
88122
position: Position,
@@ -108,9 +142,13 @@ class ClassCompletionItemProvider implements CompletionItemProvider {
108142
});
109143
}
110144

111-
this.findRemoteStyleSheets(text).then(links => {
145+
this.findDocumentLinks(text).then(links => {
112146
styles.forEach((value, key) => links.set(key, value));
113-
resolve([...links.values()]);
147+
148+
this.findRemoteStyles().then(styles => {
149+
styles.forEach((value, key) => links.set(key, value));
150+
resolve([...links.values()]);
151+
});
114152
});
115153
} else {
116154
reject();
@@ -122,7 +160,7 @@ class ClassCompletionItemProvider implements CompletionItemProvider {
122160
export function activate(context: ExtensionContext) {
123161
context.subscriptions.push(
124162
languages.registerCompletionItemProvider("html",
125-
new ClassCompletionItemProvider(), "\"", "'"));
163+
new ClassCompletionItemProvider(context), "\"", "'"));
126164
}
127165

128166
export function deactivate() { }

0 commit comments

Comments
 (0)