vscode-css-languageservice 6.3.3 → 6.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,7 +58,7 @@ All top-level properties share two basic properties, `name` and `description`. F
58
58
  }
59
59
  ```
60
60
 
61
- You can also specify 4 additional properties for them:
61
+ You can also specify 5 additional properties for them:
62
62
 
63
63
  ```jsonc
64
64
  {
@@ -73,6 +73,11 @@ You can also specify 4 additional properties for them:
73
73
  "IE10",
74
74
  "O37"
75
75
  ],
76
+ "baseline": {
77
+ "status": "high",
78
+ "baseline_low_date": "2015-09-30",
79
+ "baseline_high_date": "2018-03-30"
80
+ },
76
81
  "status": "standard",
77
82
  "references": [
78
83
  {
@@ -91,14 +96,25 @@ You can also specify 4 additional properties for them:
91
96
  export let browserNames = {
92
97
  E: 'Edge',
93
98
  FF: 'Firefox',
99
+ FFA: 'Firefox on Android',
94
100
  S: 'Safari',
101
+ SM: 'Safari on iOS',
95
102
  C: 'Chrome',
103
+ CA: 'Chrome on Android',
96
104
  IE: 'IE',
97
105
  O: 'Opera'
98
106
  };
99
107
  ```
100
108
  The browser compatibility will be rendered at completion and hover. Items that is supported in only one browser are dropped from completion.
101
109
 
110
+ - `baseline`: An object containing [Baseline](https://web-platform-dx.github.io/web-features/) information about the feature's browser compatibility, as defined by the [WebDX Community Group](https://web-platform-dx.github.io/web-features/webdx-cg/).
111
+
112
+ - `status`: The Baseline status is either `"false"` (limited availability across major browsers), `"low"` (newly available across major browsers), or `"high"` (widely available across major browsers).
113
+
114
+ - `baseline_low_date`: A date in the format `YYYY-MM-DD` representing when the feature became newly available, or undefined if it hasn't yet reached that status.
115
+
116
+ - `baseline_high_date`: A date in the format `YYYY-MM-DD` representing when the feature became widely available, or undefined if it hasn't yet reached that status. The widely available date is always 30 months after the newly available date.
117
+
102
118
  - `status`: The status of the item. The format is:
103
119
  ```
104
120
  export type EntryStatus = 'standard' | 'experimental' | 'nonstandard' | 'obsolete';
@@ -83,8 +83,31 @@
83
83
  "description": "Supported browsers",
84
84
  "items": {
85
85
  "type": "string",
86
- "pattern": "(E|FF|S|C|IE|O)([\\d|\\.]+)?",
87
- "patternErrorMessage": "Browser item must follow the format of `${browser}${version}`. `browser` is one of:\n- E: Edge\n- FF: Firefox\n- S: Safari\n- C: Chrome\n- IE: Internet Explorer\n- O: Opera"
86
+ "pattern": "(E|FFA|FF|SM|S|CA|C|IE|O)([\\d|\\.]+)?",
87
+ "patternErrorMessage": "Browser item must follow the format of `${browser}${version}`. `browser` is one of:\n- E: Edge\n- FF: Firefox\n- FM: Firefox Android\n- S: Safari\n- SM: Safari on iOS\n- C: Chrome\n- CM: Chrome on Android\n- IE: Internet Explorer\n- O: Opera"
88
+ }
89
+ },
90
+ "baseline": {
91
+ "type": "object",
92
+ "description": "Baseline information for the feature",
93
+ "properties": {
94
+ "status": {
95
+ "type": "string",
96
+ "description": "Baseline status",
97
+ "enum": ["high", "low", "false"]
98
+ },
99
+ "baseline_low_date": {
100
+ "type": "string",
101
+ "description": "Date when the feature became newly supported in all major browsers",
102
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
103
+ "patternErrorMessage": "Date must be in the format of `YYYY-MM-DD`"
104
+ },
105
+ "baseline_high_date": {
106
+ "type": "string",
107
+ "description": "Date when the feature became widely supported in all major browsers",
108
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
109
+ "patternErrorMessage": "Date must be in the format of `YYYY-MM-DD`"
110
+ }
88
111
  }
89
112
  },
90
113
  "references": {
@@ -445,7 +445,7 @@ export const cssData = {
445
445
  }
446
446
  ],
447
447
  "syntax": "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>",
448
- "relevance": 74,
448
+ "relevance": 75,
449
449
  "references": [
450
450
  {
451
451
  "name": "MDN Reference",
@@ -722,7 +722,7 @@ export const cssData = {
722
722
  }
723
723
  ],
724
724
  "syntax": "<single-animation-fill-mode>#",
725
- "relevance": 64,
725
+ "relevance": 65,
726
726
  "references": [
727
727
  {
728
728
  "name": "MDN Reference",
@@ -870,7 +870,7 @@ export const cssData = {
870
870
  "O30"
871
871
  ],
872
872
  "syntax": "<easing-function>#",
873
- "relevance": 72,
873
+ "relevance": 73,
874
874
  "references": [
875
875
  {
876
876
  "name": "MDN Reference",
@@ -2630,7 +2630,7 @@ export const cssData = {
2630
2630
  "O3.5"
2631
2631
  ],
2632
2632
  "syntax": "<line-width> || <line-style> || <color>",
2633
- "relevance": 81,
2633
+ "relevance": 82,
2634
2634
  "references": [
2635
2635
  {
2636
2636
  "name": "MDN Reference",
@@ -2790,7 +2790,7 @@ export const cssData = {
2790
2790
  "O9.2"
2791
2791
  ],
2792
2792
  "syntax": "<line-width> || <line-style> || <color>",
2793
- "relevance": 80,
2793
+ "relevance": 81,
2794
2794
  "references": [
2795
2795
  {
2796
2796
  "name": "MDN Reference",
@@ -3078,7 +3078,7 @@ export const cssData = {
3078
3078
  "O10.5"
3079
3079
  ],
3080
3080
  "syntax": "<length-percentage>{1,2}",
3081
- "relevance": 76,
3081
+ "relevance": 75,
3082
3082
  "references": [
3083
3083
  {
3084
3084
  "name": "MDN Reference",
@@ -3174,7 +3174,7 @@ export const cssData = {
3174
3174
  ],
3175
3175
  "values": [],
3176
3176
  "syntax": "<line-width>{1,4}",
3177
- "relevance": 82,
3177
+ "relevance": 83,
3178
3178
  "references": [
3179
3179
  {
3180
3180
  "name": "MDN Reference",
@@ -3212,7 +3212,7 @@ export const cssData = {
3212
3212
  }
3213
3213
  ],
3214
3214
  "syntax": "<length> | <percentage> | auto",
3215
- "relevance": 90,
3215
+ "relevance": 91,
3216
3216
  "references": [
3217
3217
  {
3218
3218
  "name": "MDN Reference",
@@ -3333,7 +3333,7 @@ export const cssData = {
3333
3333
  }
3334
3334
  ],
3335
3335
  "syntax": "content-box | border-box",
3336
- "relevance": 92,
3336
+ "relevance": 93,
3337
3337
  "references": [
3338
3338
  {
3339
3339
  "name": "MDN Reference",
@@ -6939,7 +6939,7 @@ export const cssData = {
6939
6939
  }
6940
6940
  ],
6941
6941
  "syntax": "<absolute-size> | <relative-size> | <length-percentage>",
6942
- "relevance": 94,
6942
+ "relevance": 95,
6943
6943
  "references": [
6944
6944
  {
6945
6945
  "name": "MDN Reference",
@@ -8083,7 +8083,7 @@ export const cssData = {
8083
8083
  }
8084
8084
  ],
8085
8085
  "syntax": "<grid-line>",
8086
- "relevance": 52,
8086
+ "relevance": 53,
8087
8087
  "references": [
8088
8088
  {
8089
8089
  "name": "MDN Reference",
@@ -8970,7 +8970,7 @@ export const cssData = {
8970
8970
  }
8971
8971
  ],
8972
8972
  "syntax": "<length> | <percentage> | auto",
8973
- "relevance": 94,
8973
+ "relevance": 95,
8974
8974
  "references": [
8975
8975
  {
8976
8976
  "name": "MDN Reference",
@@ -16284,7 +16284,7 @@ export const cssData = {
16284
16284
  }
16285
16285
  ],
16286
16286
  "syntax": "none | <length>",
16287
- "relevance": 54,
16287
+ "relevance": 55,
16288
16288
  "references": [
16289
16289
  {
16290
16290
  "name": "MDN Reference",
@@ -17630,7 +17630,7 @@ export const cssData = {
17630
17630
  "O67"
17631
17631
  ],
17632
17632
  "syntax": "<number>",
17633
- "relevance": 53,
17633
+ "relevance": 54,
17634
17634
  "references": [
17635
17635
  {
17636
17636
  "name": "MDN Reference",
@@ -22213,7 +22213,7 @@ export const cssData = {
22213
22213
  }
22214
22214
  ],
22215
22215
  "syntax": "normal | break-word",
22216
- "relevance": 77,
22216
+ "relevance": 78,
22217
22217
  "description": "Specifies whether the UA may break within a word to prevent overflow when an otherwise-unbreakable string is too long to fit.",
22218
22218
  "restrictions": [
22219
22219
  "enum"
@@ -24753,7 +24753,7 @@ export const cssData = {
24753
24753
  {
24754
24754
  "name": "inset-inline-end",
24755
24755
  "syntax": "<'top'>",
24756
- "relevance": 54,
24756
+ "relevance": 55,
24757
24757
  "browsers": [
24758
24758
  "E87",
24759
24759
  "FF63",
@@ -5,17 +5,43 @@
5
5
  'use strict';
6
6
  import { MarkupKind } from '../cssLanguageTypes';
7
7
  export const browserNames = {
8
- E: 'Edge',
9
- FF: 'Firefox',
10
- S: 'Safari',
11
- C: 'Chrome',
12
- IE: 'IE',
13
- O: 'Opera'
8
+ 'C': {
9
+ name: 'Chrome',
10
+ platform: 'desktop'
11
+ },
12
+ 'CA': {
13
+ name: 'Chrome',
14
+ platform: 'Android'
15
+ },
16
+ 'E': {
17
+ name: 'Edge',
18
+ platform: 'desktop'
19
+ },
20
+ 'FF': {
21
+ name: 'Firefox',
22
+ platform: 'desktop'
23
+ },
24
+ 'FFA': {
25
+ name: 'Firefox',
26
+ platform: 'Android'
27
+ },
28
+ 'S': {
29
+ name: 'Safari',
30
+ platform: 'macOS'
31
+ },
32
+ 'SM': {
33
+ name: 'Safari',
34
+ platform: 'iOS'
35
+ }
36
+ };
37
+ const shortCompatPattern = /(E|FFA|FF|SM|S|CA|C|IE|O)([\d|\.]+)?/;
38
+ export const BaselineImages = {
39
+ BASELINE_LIMITED: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ncmF5LXNoYXBlIHsKICAgICAgZmlsbDogI0M2QzZDNjsgLyogTGlnaHQgbW9kZSAqLwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgLmdyYXktc2hhcGUgewogICAgICAgIGZpbGw6ICM1NjU2NTY7IC8qIERhcmsgbW9kZSAqLwogICAgICB9CiAgICB9CiAgPC9zdHlsZT4KICA8cGF0aCBkPSJNMTUwIDBMMjQwIDkwTDIxMCAxMjBMMTIwIDMwTDE1MCAwWiIgZmlsbD0iI0YwOTQwOSIvPgogIDxwYXRoIGQ9Ik00MjAgMzBMNTQwIDE1MEw0MjAgMjcwTDM5MCAyNDBMNDgwIDE1MEwzOTAgNjBMNDIwIDMwWiIgY2xhc3M9ImdyYXktc2hhcGUiLz4KICA8cGF0aCBkPSJNMzMwIDE4MEwzMDAgMjEwTDM5MCAzMDBMNDIwIDI3MEwzMzAgMTgwWiIgZmlsbD0iI0YwOTQwOSIvPgogIDxwYXRoIGQ9Ik0xMjAgMzBMMTUwIDYwTDYwIDE1MEwxNTAgMjQwTDEyMCAyNzBMMCAxNTBMMTIwIDMwWiIgY2xhc3M9ImdyYXktc2hhcGUiLz4KICA8cGF0aCBkPSJNMzkwIDBMNDIwIDMwTDE1MCAzMDBMMTIwIDI3MEwzOTAgMFoiIGZpbGw9IiNGMDk0MDkiLz4KPC9zdmc+',
40
+ BASELINE_LOW: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ibHVlLXNoYXBlIHsKICAgICAgZmlsbDogI0E4QzdGQTsgLyogTGlnaHQgbW9kZSAqLwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgLmJsdWUtc2hhcGUgewogICAgICAgIGZpbGw6ICMyRDUwOUU7IC8qIERhcmsgbW9kZSAqLwogICAgICB9CiAgICB9CgogICAgLmRhcmtlci1ibHVlLXNoYXBlIHsKICAgICAgICBmaWxsOiAjMUI2RUYzOwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgICAuZGFya2VyLWJsdWUtc2hhcGUgewogICAgICAgICAgICBmaWxsOiAjNDE4NUZGOwogICAgICAgIH0KICAgIH0KCiAgPC9zdHlsZT4KICA8cGF0aCBkPSJNMTUwIDBMMTgwIDMwTDE1MCA2MEwxMjAgMzBMMTUwIDBaIiBjbGFzcz0iYmx1ZS1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0yMTAgNjBMMjQwIDkwTDIxMCAxMjBMMTgwIDkwTDIxMCA2MFoiIGNsYXNzPSJibHVlLXNoYXBlIi8+CiAgPHBhdGggZD0iTTQ1MCA2MEw0ODAgOTBMNDUwIDEyMEw0MjAgOTBMNDUwIDYwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNNTEwIDEyMEw1NDAgMTUwTDUxMCAxODBMNDgwIDE1MEw1MTAgMTIwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNNDUwIDE4MEw0ODAgMjEwTDQ1MCAyNDBMNDIwIDIxMEw0NTAgMTgwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNMzkwIDI0MEw0MjAgMjcwTDM5MCAzMDBMMzYwIDI3MEwzOTAgMjQwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNMzMwIDE4MEwzNjAgMjEwTDMzMCAyNDBMMzAwIDIxMEwzMzAgMTgwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNOTAgNjBMMTIwIDkwTDkwIDEyMEw2MCA5MEw5MCA2MFoiIGNsYXNzPSJibHVlLXNoYXBlIi8+CiAgPHBhdGggZD0iTTM5MCAwTDQyMCAzMEwxNTAgMzAwTDAgMTUwTDMwIDEyMEwxNTAgMjQwTDM5MCAwWiIgY2xhc3M9ImRhcmtlci1ibHVlLXNoYXBlIi8+Cjwvc3ZnPg==',
41
+ BASELINE_HIGH: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ncmVlbi1zaGFwZSB7CiAgICAgIGZpbGw6ICNDNEVFRDA7IC8qIExpZ2h0IG1vZGUgKi8KICAgIH0KCiAgICBAbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKSB7CiAgICAgIC5ncmVlbi1zaGFwZSB7CiAgICAgICAgZmlsbDogIzEyNTIyNTsgLyogRGFyayBtb2RlICovCiAgICAgIH0KICAgIH0KICA8L3N0eWxlPgogIDxwYXRoIGQ9Ik00MjAgMzBMMzkwIDYwTDQ4MCAxNTBMMzkwIDI0MEwzMzAgMTgwTDMwMCAyMTBMMzkwIDMwMEw1NDAgMTUwTDQyMCAzMFoiIGNsYXNzPSJncmVlbi1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0xNTAgMEwzMCAxMjBMNjAgMTUwTDE1MCA2MEwyMTAgMTIwTDI0MCA5MEwxNTAgMFoiIGNsYXNzPSJncmVlbi1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0zOTAgMEw0MjAgMzBMMTUwIDMwMEwwIDE1MEwzMCAxMjBMMTUwIDI0MEwzOTAgMFoiIGZpbGw9IiMxRUE0NDYiLz4KPC9zdmc+'
14
42
  };
15
43
  function getEntryStatus(status) {
16
44
  switch (status) {
17
- case 'experimental':
18
- return '⚠️ Property is experimental. Be cautious when using it.️\n\n';
19
45
  case 'nonstandard':
20
46
  return '🚨️ Property is nonstandard. Avoid using it.\n\n';
21
47
  case 'obsolete':
@@ -24,6 +50,35 @@ function getEntryStatus(status) {
24
50
  return '';
25
51
  }
26
52
  }
53
+ function getEntryBaselineStatus(baseline, browsers) {
54
+ if (baseline.status === "false") {
55
+ const missingBrowsers = getMissingBaselineBrowsers(browsers);
56
+ let status = `Limited availability across major browsers`;
57
+ if (missingBrowsers) {
58
+ status += ` (Not fully implemented in ${missingBrowsers})`;
59
+ }
60
+ return status;
61
+ }
62
+ const baselineYear = baseline.baseline_low_date?.split('-')[0];
63
+ return `${baseline.status === 'low' ? 'Newly' : 'Widely'} available across major browsers (Baseline since ${baselineYear})`;
64
+ }
65
+ function getEntryBaselineImage(baseline) {
66
+ if (!baseline) {
67
+ return '';
68
+ }
69
+ let baselineImg;
70
+ switch (baseline?.status) {
71
+ case 'low':
72
+ baselineImg = BaselineImages.BASELINE_LOW;
73
+ break;
74
+ case 'high':
75
+ baselineImg = BaselineImages.BASELINE_HIGH;
76
+ break;
77
+ default:
78
+ baselineImg = BaselineImages.BASELINE_LIMITED;
79
+ }
80
+ return `![Baseline icon](${baselineImg})`;
81
+ }
27
82
  export function getEntryDescription(entry, doesSupportMarkdown, settings) {
28
83
  let result;
29
84
  if (doesSupportMarkdown) {
@@ -56,13 +111,14 @@ function getEntryStringDescription(entry, settings) {
56
111
  }
57
112
  let result = '';
58
113
  if (settings?.documentation !== false) {
114
+ let status = '';
59
115
  if (entry.status) {
60
- result += getEntryStatus(entry.status);
116
+ status = getEntryStatus(entry.status);
117
+ result += status;
61
118
  }
62
119
  result += entry.description;
63
- const browserLabel = getBrowserLabel(entry.browsers);
64
- if (browserLabel) {
65
- result += '\n(' + browserLabel + ')';
120
+ if (entry.baseline && !status) {
121
+ result += `\n\n${getEntryBaselineStatus(entry.baseline, entry.browsers)}`;
66
122
  }
67
123
  if ('syntax' in entry) {
68
124
  result += `\n\nSyntax: ${entry.syntax}`;
@@ -84,8 +140,10 @@ function getEntryMarkdownDescription(entry, settings) {
84
140
  }
85
141
  let result = '';
86
142
  if (settings?.documentation !== false) {
143
+ let status = '';
87
144
  if (entry.status) {
88
- result += getEntryStatus(entry.status);
145
+ status = getEntryStatus(entry.status);
146
+ result += status;
89
147
  }
90
148
  if (typeof entry.description === 'string') {
91
149
  result += textToMarkedString(entry.description);
@@ -93,9 +151,8 @@ function getEntryMarkdownDescription(entry, settings) {
93
151
  else {
94
152
  result += entry.description.kind === MarkupKind.Markdown ? entry.description.value : textToMarkedString(entry.description.value);
95
153
  }
96
- const browserLabel = getBrowserLabel(entry.browsers);
97
- if (browserLabel) {
98
- result += '\n\n(' + textToMarkedString(browserLabel) + ')';
154
+ if (entry.baseline && !status) {
155
+ result += `\n\n${getEntryBaselineImage(entry.baseline)} _${getEntryBaselineStatus(entry.baseline, entry.browsers)}_`;
99
156
  }
100
157
  if ('syntax' in entry && entry.syntax) {
101
158
  result += `\n\nSyntax: ${textToMarkedString(entry.syntax)}`;
@@ -111,26 +168,35 @@ function getEntryMarkdownDescription(entry, settings) {
111
168
  }
112
169
  return result;
113
170
  }
171
+ // TODO: Remove "as any" when tsconfig supports es2021+
172
+ const missingBaselineBrowserFormatter = new Intl.ListFormat("en", {
173
+ style: "long",
174
+ type: "disjunction",
175
+ });
114
176
  /**
115
- * Input is like `["E12","FF49","C47","IE","O"]`
116
- * Output is like `Edge 12, Firefox 49, Chrome 47, IE, Opera`
177
+ * Input is like [E12, FF28, FM28, C29, CM29, IE11, O16]
178
+ * Output is like `Safari`
117
179
  */
118
- export function getBrowserLabel(browsers = []) {
119
- if (browsers.length === 0) {
120
- return null;
121
- }
122
- const entries = [];
123
- for (const b of browsers) {
124
- const matches = b.match(/([A-Z]+)(\d+)?/);
125
- const name = matches[1];
126
- const version = matches[2];
127
- if (name in browserNames) {
128
- let result = browserNames[name];
129
- if (version) {
130
- result += ' ' + version;
131
- }
132
- entries.push(result);
180
+ export function getMissingBaselineBrowsers(browsers) {
181
+ if (!browsers) {
182
+ return '';
183
+ }
184
+ const missingBrowsers = new Map(Object.entries(browserNames));
185
+ for (const shortCompatString of browsers) {
186
+ const match = shortCompatPattern.exec(shortCompatString);
187
+ if (!match) {
188
+ continue;
133
189
  }
190
+ const browser = match[1];
191
+ missingBrowsers.delete(browser);
134
192
  }
135
- return entries.join(', ');
193
+ return missingBaselineBrowserFormatter.format(Object.values(Array.from(missingBrowsers.entries()).reduce((browsers, [browserId, browser]) => {
194
+ if (browser.name in browsers || browserId === 'E') {
195
+ browsers[browser.name] = browser.name;
196
+ return browsers;
197
+ }
198
+ // distinguish between platforms when applicable
199
+ browsers[browser.name] = `${browser.name} on ${browser.platform}`;
200
+ return browsers;
201
+ }, {})));
136
202
  }
@@ -457,7 +457,7 @@
457
457
  }
458
458
  ],
459
459
  "syntax": "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>",
460
- "relevance": 74,
460
+ "relevance": 75,
461
461
  "references": [
462
462
  {
463
463
  "name": "MDN Reference",
@@ -734,7 +734,7 @@
734
734
  }
735
735
  ],
736
736
  "syntax": "<single-animation-fill-mode>#",
737
- "relevance": 64,
737
+ "relevance": 65,
738
738
  "references": [
739
739
  {
740
740
  "name": "MDN Reference",
@@ -882,7 +882,7 @@
882
882
  "O30"
883
883
  ],
884
884
  "syntax": "<easing-function>#",
885
- "relevance": 72,
885
+ "relevance": 73,
886
886
  "references": [
887
887
  {
888
888
  "name": "MDN Reference",
@@ -2642,7 +2642,7 @@
2642
2642
  "O3.5"
2643
2643
  ],
2644
2644
  "syntax": "<line-width> || <line-style> || <color>",
2645
- "relevance": 81,
2645
+ "relevance": 82,
2646
2646
  "references": [
2647
2647
  {
2648
2648
  "name": "MDN Reference",
@@ -2802,7 +2802,7 @@
2802
2802
  "O9.2"
2803
2803
  ],
2804
2804
  "syntax": "<line-width> || <line-style> || <color>",
2805
- "relevance": 80,
2805
+ "relevance": 81,
2806
2806
  "references": [
2807
2807
  {
2808
2808
  "name": "MDN Reference",
@@ -3090,7 +3090,7 @@
3090
3090
  "O10.5"
3091
3091
  ],
3092
3092
  "syntax": "<length-percentage>{1,2}",
3093
- "relevance": 76,
3093
+ "relevance": 75,
3094
3094
  "references": [
3095
3095
  {
3096
3096
  "name": "MDN Reference",
@@ -3186,7 +3186,7 @@
3186
3186
  ],
3187
3187
  "values": [],
3188
3188
  "syntax": "<line-width>{1,4}",
3189
- "relevance": 82,
3189
+ "relevance": 83,
3190
3190
  "references": [
3191
3191
  {
3192
3192
  "name": "MDN Reference",
@@ -3224,7 +3224,7 @@
3224
3224
  }
3225
3225
  ],
3226
3226
  "syntax": "<length> | <percentage> | auto",
3227
- "relevance": 90,
3227
+ "relevance": 91,
3228
3228
  "references": [
3229
3229
  {
3230
3230
  "name": "MDN Reference",
@@ -3345,7 +3345,7 @@
3345
3345
  }
3346
3346
  ],
3347
3347
  "syntax": "content-box | border-box",
3348
- "relevance": 92,
3348
+ "relevance": 93,
3349
3349
  "references": [
3350
3350
  {
3351
3351
  "name": "MDN Reference",
@@ -6951,7 +6951,7 @@
6951
6951
  }
6952
6952
  ],
6953
6953
  "syntax": "<absolute-size> | <relative-size> | <length-percentage>",
6954
- "relevance": 94,
6954
+ "relevance": 95,
6955
6955
  "references": [
6956
6956
  {
6957
6957
  "name": "MDN Reference",
@@ -8095,7 +8095,7 @@
8095
8095
  }
8096
8096
  ],
8097
8097
  "syntax": "<grid-line>",
8098
- "relevance": 52,
8098
+ "relevance": 53,
8099
8099
  "references": [
8100
8100
  {
8101
8101
  "name": "MDN Reference",
@@ -8982,7 +8982,7 @@
8982
8982
  }
8983
8983
  ],
8984
8984
  "syntax": "<length> | <percentage> | auto",
8985
- "relevance": 94,
8985
+ "relevance": 95,
8986
8986
  "references": [
8987
8987
  {
8988
8988
  "name": "MDN Reference",
@@ -16296,7 +16296,7 @@
16296
16296
  }
16297
16297
  ],
16298
16298
  "syntax": "none | <length>",
16299
- "relevance": 54,
16299
+ "relevance": 55,
16300
16300
  "references": [
16301
16301
  {
16302
16302
  "name": "MDN Reference",
@@ -17642,7 +17642,7 @@
17642
17642
  "O67"
17643
17643
  ],
17644
17644
  "syntax": "<number>",
17645
- "relevance": 53,
17645
+ "relevance": 54,
17646
17646
  "references": [
17647
17647
  {
17648
17648
  "name": "MDN Reference",
@@ -22225,7 +22225,7 @@
22225
22225
  }
22226
22226
  ],
22227
22227
  "syntax": "normal | break-word",
22228
- "relevance": 77,
22228
+ "relevance": 78,
22229
22229
  "description": "Specifies whether the UA may break within a word to prevent overflow when an otherwise-unbreakable string is too long to fit.",
22230
22230
  "restrictions": [
22231
22231
  "enum"
@@ -24765,7 +24765,7 @@
24765
24765
  {
24766
24766
  "name": "inset-inline-end",
24767
24767
  "syntax": "<'top'>",
24768
- "relevance": 54,
24768
+ "relevance": 55,
24769
24769
  "browsers": [
24770
24770
  "E87",
24771
24771
  "FF63",
@@ -13,23 +13,49 @@
13
13
  *--------------------------------------------------------------------------------------------*/
14
14
  'use strict';
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.browserNames = void 0;
16
+ exports.BaselineImages = exports.browserNames = void 0;
17
17
  exports.getEntryDescription = getEntryDescription;
18
18
  exports.textToMarkedString = textToMarkedString;
19
- exports.getBrowserLabel = getBrowserLabel;
19
+ exports.getMissingBaselineBrowsers = getMissingBaselineBrowsers;
20
20
  const cssLanguageTypes_1 = require("../cssLanguageTypes");
21
21
  exports.browserNames = {
22
- E: 'Edge',
23
- FF: 'Firefox',
24
- S: 'Safari',
25
- C: 'Chrome',
26
- IE: 'IE',
27
- O: 'Opera'
22
+ 'C': {
23
+ name: 'Chrome',
24
+ platform: 'desktop'
25
+ },
26
+ 'CA': {
27
+ name: 'Chrome',
28
+ platform: 'Android'
29
+ },
30
+ 'E': {
31
+ name: 'Edge',
32
+ platform: 'desktop'
33
+ },
34
+ 'FF': {
35
+ name: 'Firefox',
36
+ platform: 'desktop'
37
+ },
38
+ 'FFA': {
39
+ name: 'Firefox',
40
+ platform: 'Android'
41
+ },
42
+ 'S': {
43
+ name: 'Safari',
44
+ platform: 'macOS'
45
+ },
46
+ 'SM': {
47
+ name: 'Safari',
48
+ platform: 'iOS'
49
+ }
50
+ };
51
+ const shortCompatPattern = /(E|FFA|FF|SM|S|CA|C|IE|O)([\d|\.]+)?/;
52
+ exports.BaselineImages = {
53
+ BASELINE_LIMITED: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ncmF5LXNoYXBlIHsKICAgICAgZmlsbDogI0M2QzZDNjsgLyogTGlnaHQgbW9kZSAqLwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgLmdyYXktc2hhcGUgewogICAgICAgIGZpbGw6ICM1NjU2NTY7IC8qIERhcmsgbW9kZSAqLwogICAgICB9CiAgICB9CiAgPC9zdHlsZT4KICA8cGF0aCBkPSJNMTUwIDBMMjQwIDkwTDIxMCAxMjBMMTIwIDMwTDE1MCAwWiIgZmlsbD0iI0YwOTQwOSIvPgogIDxwYXRoIGQ9Ik00MjAgMzBMNTQwIDE1MEw0MjAgMjcwTDM5MCAyNDBMNDgwIDE1MEwzOTAgNjBMNDIwIDMwWiIgY2xhc3M9ImdyYXktc2hhcGUiLz4KICA8cGF0aCBkPSJNMzMwIDE4MEwzMDAgMjEwTDM5MCAzMDBMNDIwIDI3MEwzMzAgMTgwWiIgZmlsbD0iI0YwOTQwOSIvPgogIDxwYXRoIGQ9Ik0xMjAgMzBMMTUwIDYwTDYwIDE1MEwxNTAgMjQwTDEyMCAyNzBMMCAxNTBMMTIwIDMwWiIgY2xhc3M9ImdyYXktc2hhcGUiLz4KICA8cGF0aCBkPSJNMzkwIDBMNDIwIDMwTDE1MCAzMDBMMTIwIDI3MEwzOTAgMFoiIGZpbGw9IiNGMDk0MDkiLz4KPC9zdmc+',
54
+ BASELINE_LOW: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ibHVlLXNoYXBlIHsKICAgICAgZmlsbDogI0E4QzdGQTsgLyogTGlnaHQgbW9kZSAqLwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgLmJsdWUtc2hhcGUgewogICAgICAgIGZpbGw6ICMyRDUwOUU7IC8qIERhcmsgbW9kZSAqLwogICAgICB9CiAgICB9CgogICAgLmRhcmtlci1ibHVlLXNoYXBlIHsKICAgICAgICBmaWxsOiAjMUI2RUYzOwogICAgfQoKICAgIEBtZWRpYSAocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspIHsKICAgICAgICAuZGFya2VyLWJsdWUtc2hhcGUgewogICAgICAgICAgICBmaWxsOiAjNDE4NUZGOwogICAgICAgIH0KICAgIH0KCiAgPC9zdHlsZT4KICA8cGF0aCBkPSJNMTUwIDBMMTgwIDMwTDE1MCA2MEwxMjAgMzBMMTUwIDBaIiBjbGFzcz0iYmx1ZS1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0yMTAgNjBMMjQwIDkwTDIxMCAxMjBMMTgwIDkwTDIxMCA2MFoiIGNsYXNzPSJibHVlLXNoYXBlIi8+CiAgPHBhdGggZD0iTTQ1MCA2MEw0ODAgOTBMNDUwIDEyMEw0MjAgOTBMNDUwIDYwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNNTEwIDEyMEw1NDAgMTUwTDUxMCAxODBMNDgwIDE1MEw1MTAgMTIwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNNDUwIDE4MEw0ODAgMjEwTDQ1MCAyNDBMNDIwIDIxMEw0NTAgMTgwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNMzkwIDI0MEw0MjAgMjcwTDM5MCAzMDBMMzYwIDI3MEwzOTAgMjQwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNMzMwIDE4MEwzNjAgMjEwTDMzMCAyNDBMMzAwIDIxMEwzMzAgMTgwWiIgY2xhc3M9ImJsdWUtc2hhcGUiLz4KICA8cGF0aCBkPSJNOTAgNjBMMTIwIDkwTDkwIDEyMEw2MCA5MEw5MCA2MFoiIGNsYXNzPSJibHVlLXNoYXBlIi8+CiAgPHBhdGggZD0iTTM5MCAwTDQyMCAzMEwxNTAgMzAwTDAgMTUwTDMwIDEyMEwxNTAgMjQwTDM5MCAwWiIgY2xhc3M9ImRhcmtlci1ibHVlLXNoYXBlIi8+Cjwvc3ZnPg==',
55
+ BASELINE_HIGH: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCA1NDAgMzAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzdHlsZT4KICAgIC5ncmVlbi1zaGFwZSB7CiAgICAgIGZpbGw6ICNDNEVFRDA7IC8qIExpZ2h0IG1vZGUgKi8KICAgIH0KCiAgICBAbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKSB7CiAgICAgIC5ncmVlbi1zaGFwZSB7CiAgICAgICAgZmlsbDogIzEyNTIyNTsgLyogRGFyayBtb2RlICovCiAgICAgIH0KICAgIH0KICA8L3N0eWxlPgogIDxwYXRoIGQ9Ik00MjAgMzBMMzkwIDYwTDQ4MCAxNTBMMzkwIDI0MEwzMzAgMTgwTDMwMCAyMTBMMzkwIDMwMEw1NDAgMTUwTDQyMCAzMFoiIGNsYXNzPSJncmVlbi1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0xNTAgMEwzMCAxMjBMNjAgMTUwTDE1MCA2MEwyMTAgMTIwTDI0MCA5MEwxNTAgMFoiIGNsYXNzPSJncmVlbi1zaGFwZSIvPgogIDxwYXRoIGQ9Ik0zOTAgMEw0MjAgMzBMMTUwIDMwMEwwIDE1MEwzMCAxMjBMMTUwIDI0MEwzOTAgMFoiIGZpbGw9IiMxRUE0NDYiLz4KPC9zdmc+'
28
56
  };
29
57
  function getEntryStatus(status) {
30
58
  switch (status) {
31
- case 'experimental':
32
- return '⚠️ Property is experimental. Be cautious when using it.️\n\n';
33
59
  case 'nonstandard':
34
60
  return '🚨️ Property is nonstandard. Avoid using it.\n\n';
35
61
  case 'obsolete':
@@ -38,6 +64,35 @@
38
64
  return '';
39
65
  }
40
66
  }
67
+ function getEntryBaselineStatus(baseline, browsers) {
68
+ if (baseline.status === "false") {
69
+ const missingBrowsers = getMissingBaselineBrowsers(browsers);
70
+ let status = `Limited availability across major browsers`;
71
+ if (missingBrowsers) {
72
+ status += ` (Not fully implemented in ${missingBrowsers})`;
73
+ }
74
+ return status;
75
+ }
76
+ const baselineYear = baseline.baseline_low_date?.split('-')[0];
77
+ return `${baseline.status === 'low' ? 'Newly' : 'Widely'} available across major browsers (Baseline since ${baselineYear})`;
78
+ }
79
+ function getEntryBaselineImage(baseline) {
80
+ if (!baseline) {
81
+ return '';
82
+ }
83
+ let baselineImg;
84
+ switch (baseline?.status) {
85
+ case 'low':
86
+ baselineImg = exports.BaselineImages.BASELINE_LOW;
87
+ break;
88
+ case 'high':
89
+ baselineImg = exports.BaselineImages.BASELINE_HIGH;
90
+ break;
91
+ default:
92
+ baselineImg = exports.BaselineImages.BASELINE_LIMITED;
93
+ }
94
+ return `![Baseline icon](${baselineImg})`;
95
+ }
41
96
  function getEntryDescription(entry, doesSupportMarkdown, settings) {
42
97
  let result;
43
98
  if (doesSupportMarkdown) {
@@ -70,13 +125,14 @@
70
125
  }
71
126
  let result = '';
72
127
  if (settings?.documentation !== false) {
128
+ let status = '';
73
129
  if (entry.status) {
74
- result += getEntryStatus(entry.status);
130
+ status = getEntryStatus(entry.status);
131
+ result += status;
75
132
  }
76
133
  result += entry.description;
77
- const browserLabel = getBrowserLabel(entry.browsers);
78
- if (browserLabel) {
79
- result += '\n(' + browserLabel + ')';
134
+ if (entry.baseline && !status) {
135
+ result += `\n\n${getEntryBaselineStatus(entry.baseline, entry.browsers)}`;
80
136
  }
81
137
  if ('syntax' in entry) {
82
138
  result += `\n\nSyntax: ${entry.syntax}`;
@@ -98,8 +154,10 @@
98
154
  }
99
155
  let result = '';
100
156
  if (settings?.documentation !== false) {
157
+ let status = '';
101
158
  if (entry.status) {
102
- result += getEntryStatus(entry.status);
159
+ status = getEntryStatus(entry.status);
160
+ result += status;
103
161
  }
104
162
  if (typeof entry.description === 'string') {
105
163
  result += textToMarkedString(entry.description);
@@ -107,9 +165,8 @@
107
165
  else {
108
166
  result += entry.description.kind === cssLanguageTypes_1.MarkupKind.Markdown ? entry.description.value : textToMarkedString(entry.description.value);
109
167
  }
110
- const browserLabel = getBrowserLabel(entry.browsers);
111
- if (browserLabel) {
112
- result += '\n\n(' + textToMarkedString(browserLabel) + ')';
168
+ if (entry.baseline && !status) {
169
+ result += `\n\n${getEntryBaselineImage(entry.baseline)} _${getEntryBaselineStatus(entry.baseline, entry.browsers)}_`;
113
170
  }
114
171
  if ('syntax' in entry && entry.syntax) {
115
172
  result += `\n\nSyntax: ${textToMarkedString(entry.syntax)}`;
@@ -125,27 +182,36 @@
125
182
  }
126
183
  return result;
127
184
  }
185
+ // TODO: Remove "as any" when tsconfig supports es2021+
186
+ const missingBaselineBrowserFormatter = new Intl.ListFormat("en", {
187
+ style: "long",
188
+ type: "disjunction",
189
+ });
128
190
  /**
129
- * Input is like `["E12","FF49","C47","IE","O"]`
130
- * Output is like `Edge 12, Firefox 49, Chrome 47, IE, Opera`
191
+ * Input is like [E12, FF28, FM28, C29, CM29, IE11, O16]
192
+ * Output is like `Safari`
131
193
  */
132
- function getBrowserLabel(browsers = []) {
133
- if (browsers.length === 0) {
134
- return null;
135
- }
136
- const entries = [];
137
- for (const b of browsers) {
138
- const matches = b.match(/([A-Z]+)(\d+)?/);
139
- const name = matches[1];
140
- const version = matches[2];
141
- if (name in exports.browserNames) {
142
- let result = exports.browserNames[name];
143
- if (version) {
144
- result += ' ' + version;
145
- }
146
- entries.push(result);
194
+ function getMissingBaselineBrowsers(browsers) {
195
+ if (!browsers) {
196
+ return '';
197
+ }
198
+ const missingBrowsers = new Map(Object.entries(exports.browserNames));
199
+ for (const shortCompatString of browsers) {
200
+ const match = shortCompatPattern.exec(shortCompatString);
201
+ if (!match) {
202
+ continue;
147
203
  }
204
+ const browser = match[1];
205
+ missingBrowsers.delete(browser);
148
206
  }
149
- return entries.join(', ');
207
+ return missingBaselineBrowserFormatter.format(Object.values(Array.from(missingBrowsers.entries()).reduce((browsers, [browserId, browser]) => {
208
+ if (browser.name in browsers || browserId === 'E') {
209
+ browsers[browser.name] = browser.name;
210
+ return browsers;
211
+ }
212
+ // distinguish between platforms when applicable
213
+ browsers[browser.name] = `${browser.name} on ${browser.platform}`;
214
+ return browsers;
215
+ }, {})));
150
216
  }
151
217
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vscode-css-languageservice",
3
- "version": "6.3.3",
3
+ "version": "6.3.4",
4
4
  "description": "Language service for CSS, LESS and SCSS",
5
5
  "main": "./lib/umd/cssLanguageService.js",
6
6
  "typings": "./lib/umd/cssLanguageService",
@@ -17,7 +17,7 @@
17
17
  "devDependencies": {
18
18
  "@types/mocha": "^10.0.10",
19
19
  "@types/node": "18.x",
20
- "@typescript-eslint/eslint-plugin": "^8.27.0",
20
+ "@typescript-eslint/eslint-plugin": "^8.29.0",
21
21
  "@typescript-eslint/parser": "^8.27.0",
22
22
  "@vscode/web-custom-data": "^0.5.0",
23
23
  "eslint": "^9.23.0",
@@ -31,7 +31,7 @@
31
31
  "@vscode/l10n": "^0.0.18",
32
32
  "vscode-languageserver-textdocument": "^1.0.12",
33
33
  "vscode-languageserver-types": "3.17.5",
34
- "vscode-uri": "^3.0.8"
34
+ "vscode-uri": "^3.1.0"
35
35
  },
36
36
  "scripts": {
37
37
  "prepack": "npm run clean && npm run compile-esm && npm run test && npm run remove-sourcemap-refs",