vscode-css-languageservice 6.1.0 → 6.2.1

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -3
  3. package/lib/esm/beautify/beautify-css.js +1 -1
  4. package/lib/esm/cssLanguageService.d.ts +2 -1
  5. package/lib/esm/cssLanguageService.js +1 -0
  6. package/lib/esm/cssLanguageTypes.d.ts +2 -2
  7. package/lib/esm/data/webCustomData.js +3502 -310
  8. package/lib/esm/languageFacts/colors.js +6 -7
  9. package/lib/esm/parser/cssErrors.js +34 -35
  10. package/lib/esm/parser/cssNodes.js +25 -4
  11. package/lib/esm/parser/cssParser.js +31 -16
  12. package/lib/esm/parser/lessParser.js +1 -0
  13. package/lib/esm/parser/scssErrors.js +4 -5
  14. package/lib/esm/parser/scssParser.js +4 -0
  15. package/lib/esm/services/cssCodeActions.js +2 -3
  16. package/lib/esm/services/cssCompletion.js +13 -4
  17. package/lib/esm/services/cssNavigation.js +44 -25
  18. package/lib/esm/services/lessCompletion.js +58 -59
  19. package/lib/esm/services/lint.js +64 -18
  20. package/lib/esm/services/lintRules.js +21 -22
  21. package/lib/esm/services/scssCompletion.js +107 -107
  22. package/lib/esm/services/scssNavigation.js +35 -57
  23. package/lib/esm/services/selectorPrinting.js +2 -3
  24. package/lib/umd/beautify/beautify-css.js +1 -1
  25. package/lib/umd/cssLanguageService.d.ts +2 -1
  26. package/lib/umd/cssLanguageService.js +1 -0
  27. package/lib/umd/cssLanguageTypes.d.ts +2 -2
  28. package/lib/umd/data/webCustomData.js +3502 -310
  29. package/lib/umd/languageFacts/colors.js +7 -8
  30. package/lib/umd/parser/cssErrors.js +35 -36
  31. package/lib/umd/parser/cssNodes.js +27 -5
  32. package/lib/umd/parser/cssParser.js +31 -16
  33. package/lib/umd/parser/lessParser.js +1 -0
  34. package/lib/umd/parser/scssErrors.js +5 -6
  35. package/lib/umd/parser/scssParser.js +4 -0
  36. package/lib/umd/services/cssCodeActions.js +3 -4
  37. package/lib/umd/services/cssCompletion.js +14 -5
  38. package/lib/umd/services/cssNavigation.js +45 -26
  39. package/lib/umd/services/lessCompletion.js +59 -60
  40. package/lib/umd/services/lint.js +65 -19
  41. package/lib/umd/services/lintRules.js +22 -23
  42. package/lib/umd/services/scssCompletion.js +108 -108
  43. package/lib/umd/services/scssNavigation.js +34 -56
  44. package/lib/umd/services/selectorPrinting.js +3 -4
  45. package/package.json +13 -16
@@ -3,14 +3,13 @@
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as nodes from '../parser/cssNodes';
6
- import * as nls from 'vscode-nls';
7
- const localize = nls.loadMessageBundle();
6
+ import * as l10n from '@vscode/l10n';
8
7
  export const colorFunctions = [
9
- { func: 'rgb($red, $green, $blue)', desc: localize('css.builtin.rgb', 'Creates a Color from red, green, and blue values.') },
10
- { func: 'rgba($red, $green, $blue, $alpha)', desc: localize('css.builtin.rgba', 'Creates a Color from red, green, blue, and alpha values.') },
11
- { func: 'hsl($hue, $saturation, $lightness)', desc: localize('css.builtin.hsl', 'Creates a Color from hue, saturation, and lightness values.') },
12
- { func: 'hsla($hue, $saturation, $lightness, $alpha)', desc: localize('css.builtin.hsla', 'Creates a Color from hue, saturation, lightness, and alpha values.') },
13
- { func: 'hwb($hue $white $black)', desc: localize('css.builtin.hwb', 'Creates a Color from hue, white and black.') }
8
+ { func: 'rgb($red, $green, $blue)', desc: l10n.t('Creates a Color from red, green, and blue values.') },
9
+ { func: 'rgba($red, $green, $blue, $alpha)', desc: l10n.t('Creates a Color from red, green, blue, and alpha values.') },
10
+ { func: 'hsl($hue, $saturation, $lightness)', desc: l10n.t('Creates a Color from hue, saturation, and lightness values.') },
11
+ { func: 'hsla($hue, $saturation, $lightness, $alpha)', desc: l10n.t('Creates a Color from hue, saturation, lightness, and alpha values.') },
12
+ { func: 'hwb($hue $white $black)', desc: l10n.t('Creates a Color from hue, white and black.') }
14
13
  ];
15
14
  export const colors = {
16
15
  aliceblue: '#f0f8ff',
@@ -3,8 +3,7 @@
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  'use strict';
6
- import * as nls from 'vscode-nls';
7
- const localize = nls.loadMessageBundle();
6
+ import * as l10n from '@vscode/l10n';
8
7
  export class CSSIssueType {
9
8
  constructor(id, message) {
10
9
  this.id = id;
@@ -12,37 +11,37 @@ export class CSSIssueType {
12
11
  }
13
12
  }
14
13
  export const ParseError = {
15
- NumberExpected: new CSSIssueType('css-numberexpected', localize('expected.number', "number expected")),
16
- ConditionExpected: new CSSIssueType('css-conditionexpected', localize('expected.condt', "condition expected")),
17
- RuleOrSelectorExpected: new CSSIssueType('css-ruleorselectorexpected', localize('expected.ruleorselector', "at-rule or selector expected")),
18
- DotExpected: new CSSIssueType('css-dotexpected', localize('expected.dot', "dot expected")),
19
- ColonExpected: new CSSIssueType('css-colonexpected', localize('expected.colon', "colon expected")),
20
- SemiColonExpected: new CSSIssueType('css-semicolonexpected', localize('expected.semicolon', "semi-colon expected")),
21
- TermExpected: new CSSIssueType('css-termexpected', localize('expected.term', "term expected")),
22
- ExpressionExpected: new CSSIssueType('css-expressionexpected', localize('expected.expression', "expression expected")),
23
- OperatorExpected: new CSSIssueType('css-operatorexpected', localize('expected.operator', "operator expected")),
24
- IdentifierExpected: new CSSIssueType('css-identifierexpected', localize('expected.ident', "identifier expected")),
25
- PercentageExpected: new CSSIssueType('css-percentageexpected', localize('expected.percentage', "percentage expected")),
26
- URIOrStringExpected: new CSSIssueType('css-uriorstringexpected', localize('expected.uriorstring', "uri or string expected")),
27
- URIExpected: new CSSIssueType('css-uriexpected', localize('expected.uri', "URI expected")),
28
- VariableNameExpected: new CSSIssueType('css-varnameexpected', localize('expected.varname', "variable name expected")),
29
- VariableValueExpected: new CSSIssueType('css-varvalueexpected', localize('expected.varvalue', "variable value expected")),
30
- PropertyValueExpected: new CSSIssueType('css-propertyvalueexpected', localize('expected.propvalue', "property value expected")),
31
- LeftCurlyExpected: new CSSIssueType('css-lcurlyexpected', localize('expected.lcurly', "{ expected")),
32
- RightCurlyExpected: new CSSIssueType('css-rcurlyexpected', localize('expected.rcurly', "} expected")),
33
- LeftSquareBracketExpected: new CSSIssueType('css-rbracketexpected', localize('expected.lsquare', "[ expected")),
34
- RightSquareBracketExpected: new CSSIssueType('css-lbracketexpected', localize('expected.rsquare', "] expected")),
35
- LeftParenthesisExpected: new CSSIssueType('css-lparentexpected', localize('expected.lparen', "( expected")),
36
- RightParenthesisExpected: new CSSIssueType('css-rparentexpected', localize('expected.rparent', ") expected")),
37
- CommaExpected: new CSSIssueType('css-commaexpected', localize('expected.comma', "comma expected")),
38
- PageDirectiveOrDeclarationExpected: new CSSIssueType('css-pagedirordeclexpected', localize('expected.pagedirordecl', "page directive or declaraton expected")),
39
- UnknownAtRule: new CSSIssueType('css-unknownatrule', localize('unknown.atrule', "at-rule unknown")),
40
- UnknownKeyword: new CSSIssueType('css-unknownkeyword', localize('unknown.keyword', "unknown keyword")),
41
- SelectorExpected: new CSSIssueType('css-selectorexpected', localize('expected.selector', "selector expected")),
42
- StringLiteralExpected: new CSSIssueType('css-stringliteralexpected', localize('expected.stringliteral', "string literal expected")),
43
- WhitespaceExpected: new CSSIssueType('css-whitespaceexpected', localize('expected.whitespace', "whitespace expected")),
44
- MediaQueryExpected: new CSSIssueType('css-mediaqueryexpected', localize('expected.mediaquery', "media query expected")),
45
- IdentifierOrWildcardExpected: new CSSIssueType('css-idorwildcardexpected', localize('expected.idorwildcard', "identifier or wildcard expected")),
46
- WildcardExpected: new CSSIssueType('css-wildcardexpected', localize('expected.wildcard', "wildcard expected")),
47
- IdentifierOrVariableExpected: new CSSIssueType('css-idorvarexpected', localize('expected.idorvar', "identifier or variable expected")),
14
+ NumberExpected: new CSSIssueType('css-numberexpected', l10n.t("number expected")),
15
+ ConditionExpected: new CSSIssueType('css-conditionexpected', l10n.t("condition expected")),
16
+ RuleOrSelectorExpected: new CSSIssueType('css-ruleorselectorexpected', l10n.t("at-rule or selector expected")),
17
+ DotExpected: new CSSIssueType('css-dotexpected', l10n.t("dot expected")),
18
+ ColonExpected: new CSSIssueType('css-colonexpected', l10n.t("colon expected")),
19
+ SemiColonExpected: new CSSIssueType('css-semicolonexpected', l10n.t("semi-colon expected")),
20
+ TermExpected: new CSSIssueType('css-termexpected', l10n.t("term expected")),
21
+ ExpressionExpected: new CSSIssueType('css-expressionexpected', l10n.t("expression expected")),
22
+ OperatorExpected: new CSSIssueType('css-operatorexpected', l10n.t("operator expected")),
23
+ IdentifierExpected: new CSSIssueType('css-identifierexpected', l10n.t("identifier expected")),
24
+ PercentageExpected: new CSSIssueType('css-percentageexpected', l10n.t("percentage expected")),
25
+ URIOrStringExpected: new CSSIssueType('css-uriorstringexpected', l10n.t("uri or string expected")),
26
+ URIExpected: new CSSIssueType('css-uriexpected', l10n.t("URI expected")),
27
+ VariableNameExpected: new CSSIssueType('css-varnameexpected', l10n.t("variable name expected")),
28
+ VariableValueExpected: new CSSIssueType('css-varvalueexpected', l10n.t("variable value expected")),
29
+ PropertyValueExpected: new CSSIssueType('css-propertyvalueexpected', l10n.t("property value expected")),
30
+ LeftCurlyExpected: new CSSIssueType('css-lcurlyexpected', l10n.t("{ expected")),
31
+ RightCurlyExpected: new CSSIssueType('css-rcurlyexpected', l10n.t("} expected")),
32
+ LeftSquareBracketExpected: new CSSIssueType('css-rbracketexpected', l10n.t("[ expected")),
33
+ RightSquareBracketExpected: new CSSIssueType('css-lbracketexpected', l10n.t("] expected")),
34
+ LeftParenthesisExpected: new CSSIssueType('css-lparentexpected', l10n.t("( expected")),
35
+ RightParenthesisExpected: new CSSIssueType('css-rparentexpected', l10n.t(") expected")),
36
+ CommaExpected: new CSSIssueType('css-commaexpected', l10n.t("comma expected")),
37
+ PageDirectiveOrDeclarationExpected: new CSSIssueType('css-pagedirordeclexpected', l10n.t("page directive or declaraton expected")),
38
+ UnknownAtRule: new CSSIssueType('css-unknownatrule', l10n.t("at-rule unknown")),
39
+ UnknownKeyword: new CSSIssueType('css-unknownkeyword', l10n.t("unknown keyword")),
40
+ SelectorExpected: new CSSIssueType('css-selectorexpected', l10n.t("selector expected")),
41
+ StringLiteralExpected: new CSSIssueType('css-stringliteralexpected', l10n.t("string literal expected")),
42
+ WhitespaceExpected: new CSSIssueType('css-whitespaceexpected', l10n.t("whitespace expected")),
43
+ MediaQueryExpected: new CSSIssueType('css-mediaqueryexpected', l10n.t("media query expected")),
44
+ IdentifierOrWildcardExpected: new CSSIssueType('css-idorwildcardexpected', l10n.t("identifier or wildcard expected")),
45
+ WildcardExpected: new CSSIssueType('css-wildcardexpected', l10n.t("wildcard expected")),
46
+ IdentifierOrVariableExpected: new CSSIssueType('css-idorvarexpected', l10n.t("identifier or variable expected")),
48
47
  };
@@ -96,6 +96,7 @@ export var NodeType;
96
96
  NodeType[NodeType["Layer"] = 83] = "Layer";
97
97
  NodeType[NodeType["LayerNameList"] = 84] = "LayerNameList";
98
98
  NodeType[NodeType["LayerName"] = 85] = "LayerName";
99
+ NodeType[NodeType["PropertyAtRule"] = 86] = "PropertyAtRule";
99
100
  })(NodeType || (NodeType = {}));
100
101
  export var ReferenceType;
101
102
  (function (ReferenceType) {
@@ -108,6 +109,7 @@ export var ReferenceType;
108
109
  ReferenceType[ReferenceType["Module"] = 6] = "Module";
109
110
  ReferenceType[ReferenceType["Forward"] = 7] = "Forward";
110
111
  ReferenceType[ReferenceType["ForwardVisibility"] = 8] = "ForwardVisibility";
112
+ ReferenceType[ReferenceType["Property"] = 9] = "Property";
111
113
  })(ReferenceType || (ReferenceType = {}));
112
114
  export function getNodeAtOffset(node, offset) {
113
115
  let candidate = null;
@@ -150,6 +152,7 @@ export function getParentDeclaration(node) {
150
152
  return null;
151
153
  }
152
154
  export class Node {
155
+ get end() { return this.offset + this.length; }
153
156
  constructor(offset = -1, len = -1, nodeType) {
154
157
  this.parent = null;
155
158
  this.offset = offset;
@@ -158,7 +161,6 @@ export class Node {
158
161
  this.nodeType = nodeType;
159
162
  }
160
163
  }
161
- get end() { return this.offset + this.length; }
162
164
  set type(type) {
163
165
  this.nodeType = type;
164
166
  }
@@ -893,6 +895,25 @@ export class Layer extends BodyDeclaration {
893
895
  return this.names;
894
896
  }
895
897
  }
898
+ export class PropertyAtRule extends BodyDeclaration {
899
+ constructor(offset, length) {
900
+ super(offset, length);
901
+ }
902
+ get type() {
903
+ return NodeType.PropertyAtRule;
904
+ }
905
+ setName(node) {
906
+ if (node) {
907
+ node.attachTo(this);
908
+ this.name = node;
909
+ return true;
910
+ }
911
+ return false;
912
+ }
913
+ getName() {
914
+ return this.name;
915
+ }
916
+ }
896
917
  export class Document extends BodyDeclaration {
897
918
  constructor(offset, length) {
898
919
  super(offset, length);
@@ -1494,14 +1515,14 @@ export class DefaultVisitor implements IVisitor {
1494
1515
  }
1495
1516
  */
1496
1517
  export class ParseErrorCollector {
1497
- constructor() {
1498
- this.entries = [];
1499
- }
1500
1518
  static entries(node) {
1501
1519
  const visitor = new ParseErrorCollector();
1502
1520
  node.acceptVisitor(visitor);
1503
1521
  return visitor.entries;
1504
1522
  }
1523
+ constructor() {
1524
+ this.entries = [];
1525
+ }
1505
1526
  visitNode(node) {
1506
1527
  if (node.isErroneous()) {
1507
1528
  node.collectIssues(this.entries);
@@ -272,6 +272,7 @@ export class Parser {
272
272
  || this._parseKeyframe()
273
273
  || this._parseSupports(isNested)
274
274
  || this._parseLayer()
275
+ || this._parsePropertyAtRule()
275
276
  || this._parseViewPort()
276
277
  || this._parseNamespace()
277
278
  || this._parseDocument()
@@ -717,6 +718,20 @@ export class Parser {
717
718
  }
718
719
  return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
719
720
  }
721
+ _parsePropertyAtRule() {
722
+ // @property <custom-property-name> {
723
+ // <declaration-list>
724
+ // }
725
+ if (!this.peekKeyword('@property')) {
726
+ return null;
727
+ }
728
+ const node = this.create(nodes.PropertyAtRule);
729
+ this.consumeToken(); // @layer
730
+ if (!this.peekRegExp(TokenType.Ident, /^--/) || !node.setName(this._parseIdent([nodes.ReferenceType.Property]))) {
731
+ return this.finish(node, ParseError.IdentifierExpected);
732
+ }
733
+ return this._parseBody(node, this._parseDeclaration.bind(this));
734
+ }
720
735
  _parseLayer() {
721
736
  // @layer layer-name {rules}
722
737
  // @layer layer-name;
@@ -954,29 +969,17 @@ export class Parser {
954
969
  // <mf-plain> = <mf-name> : <mf-value>
955
970
  // <mf-boolean> = <mf-name>
956
971
  // <mf-range> = <mf-name> [ '<' | '>' ]? '='? <mf-value> | <mf-value> [ '<' | '>' ]? '='? <mf-name> | <mf-value> '<' '='? <mf-name> '<' '='? <mf-value> | <mf-value> '>' '='? <mf-name> '>' '='? <mf-value>
957
- const parseRangeOperator = () => {
958
- if (this.acceptDelim('<') || this.acceptDelim('>')) {
959
- if (!this.hasWhitespace()) {
960
- this.acceptDelim('=');
961
- }
962
- return true;
963
- }
964
- else if (this.acceptDelim('=')) {
965
- return true;
966
- }
967
- return false;
968
- };
969
972
  if (node.addChild(this._parseMediaFeatureName())) {
970
973
  if (this.accept(TokenType.Colon)) {
971
974
  if (!node.addChild(this._parseMediaFeatureValue())) {
972
975
  return this.finish(node, ParseError.TermExpected, [], resyncStopToken);
973
976
  }
974
977
  }
975
- else if (parseRangeOperator()) {
978
+ else if (this._parseMediaFeatureRangeOperator()) {
976
979
  if (!node.addChild(this._parseMediaFeatureValue())) {
977
980
  return this.finish(node, ParseError.TermExpected, [], resyncStopToken);
978
981
  }
979
- if (parseRangeOperator()) {
982
+ if (this._parseMediaFeatureRangeOperator()) {
980
983
  if (!node.addChild(this._parseMediaFeatureValue())) {
981
984
  return this.finish(node, ParseError.TermExpected, [], resyncStopToken);
982
985
  }
@@ -987,13 +990,13 @@ export class Parser {
987
990
  }
988
991
  }
989
992
  else if (node.addChild(this._parseMediaFeatureValue())) {
990
- if (!parseRangeOperator()) {
993
+ if (!this._parseMediaFeatureRangeOperator()) {
991
994
  return this.finish(node, ParseError.OperatorExpected, [], resyncStopToken);
992
995
  }
993
996
  if (!node.addChild(this._parseMediaFeatureName())) {
994
997
  return this.finish(node, ParseError.IdentifierExpected, [], resyncStopToken);
995
998
  }
996
- if (parseRangeOperator()) {
999
+ if (this._parseMediaFeatureRangeOperator()) {
997
1000
  if (!node.addChild(this._parseMediaFeatureValue())) {
998
1001
  return this.finish(node, ParseError.TermExpected, [], resyncStopToken);
999
1002
  }
@@ -1004,6 +1007,18 @@ export class Parser {
1004
1007
  }
1005
1008
  return this.finish(node);
1006
1009
  }
1010
+ _parseMediaFeatureRangeOperator() {
1011
+ if (this.acceptDelim('<') || this.acceptDelim('>')) {
1012
+ if (!this.hasWhitespace()) {
1013
+ this.acceptDelim('=');
1014
+ }
1015
+ return true;
1016
+ }
1017
+ else if (this.acceptDelim('=')) {
1018
+ return true;
1019
+ }
1020
+ return false;
1021
+ }
1007
1022
  _parseMediaFeatureName() {
1008
1023
  return this._parseIdent();
1009
1024
  }
@@ -273,6 +273,7 @@ export class LESSParser extends cssParser.Parser {
273
273
  || this._parseImport()
274
274
  || this._parseSupports(true) // @supports
275
275
  || this._parseLayer() // @layer
276
+ || this._parsePropertyAtRule() // @property
276
277
  || this._parseDetachedRuleSetMixin() // less detached ruleset mixin
277
278
  || this._parseVariableDeclaration() // Variable declarations
278
279
  || super._parseRuleSetDeclarationAtStatement();
@@ -3,8 +3,7 @@
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  'use strict';
6
- import * as nls from 'vscode-nls';
7
- const localize = nls.loadMessageBundle();
6
+ import * as l10n from '@vscode/l10n';
8
7
  export class SCSSIssueType {
9
8
  constructor(id, message) {
10
9
  this.id = id;
@@ -12,7 +11,7 @@ export class SCSSIssueType {
12
11
  }
13
12
  }
14
13
  export const SCSSParseError = {
15
- FromExpected: new SCSSIssueType('scss-fromexpected', localize('expected.from', "'from' expected")),
16
- ThroughOrToExpected: new SCSSIssueType('scss-throughexpected', localize('expected.through', "'through' or 'to' expected")),
17
- InExpected: new SCSSIssueType('scss-fromexpected', localize('expected.in', "'in' expected")),
14
+ FromExpected: new SCSSIssueType('scss-fromexpected', l10n.t("'from' expected")),
15
+ ThroughOrToExpected: new SCSSIssueType('scss-throughexpected', l10n.t("'through' or 'to' expected")),
16
+ InExpected: new SCSSIssueType('scss-fromexpected', l10n.t("'in' expected")),
18
17
  };
@@ -89,6 +89,9 @@ export class SCSSParser extends cssParser.Parser {
89
89
  _parseMediaCondition() {
90
90
  return this._parseInterpolation() || super._parseMediaCondition();
91
91
  }
92
+ _parseMediaFeatureRangeOperator() {
93
+ return this.accept(scssScanner.SmallerEqualsOperator) || this.accept(scssScanner.GreaterEqualsOperator) || super._parseMediaFeatureRangeOperator();
94
+ }
92
95
  _parseMediaFeatureName() {
93
96
  return this._parseModuleMember()
94
97
  || this._parseFunction() // function before ident
@@ -215,6 +218,7 @@ export class SCSSParser extends cssParser.Parser {
215
218
  || this._parseRuleset(true) // @at-rule
216
219
  || this._parseSupports(true) // @supports
217
220
  || this._parseLayer() // @layer
221
+ || this._parsePropertyAtRule() // @property
218
222
  || super._parseRuleSetDeclarationAtStatement();
219
223
  }
220
224
  return this._parseVariableDeclaration() // variable declaration
@@ -7,8 +7,7 @@ import * as nodes from '../parser/cssNodes';
7
7
  import { difference } from '../utils/strings';
8
8
  import { Rules } from '../services/lintRules';
9
9
  import { Command, TextEdit, CodeAction, CodeActionKind, TextDocumentEdit, VersionedTextDocumentIdentifier } from '../cssLanguageTypes';
10
- import * as nls from 'vscode-nls';
11
- const localize = nls.loadMessageBundle();
10
+ import * as l10n from '@vscode/l10n';
12
11
  export class CSSCodeActions {
13
12
  constructor(cssDataManager) {
14
13
  this.cssDataManager = cssDataManager;
@@ -44,7 +43,7 @@ export class CSSCodeActions {
44
43
  let maxActions = 3;
45
44
  for (const candidate of candidates) {
46
45
  const propertyName = candidate.property;
47
- const title = localize('css.codeaction.rename', "Rename to '{0}'", propertyName);
46
+ const title = l10n.t("Rename to '{0}'", propertyName);
48
47
  const edit = TextEdit.replace(marker.range, propertyName);
49
48
  const documentIdentifier = VersionedTextDocumentIdentifier.create(document.uri, document.version);
50
49
  const workspaceEdit = { documentChanges: [TextDocumentEdit.create(documentIdentifier, [edit])] };
@@ -8,10 +8,9 @@ import { Symbols } from '../parser/cssSymbolScope';
8
8
  import * as languageFacts from '../languageFacts/facts';
9
9
  import * as strings from '../utils/strings';
10
10
  import { Position, CompletionItemKind, Range, TextEdit, InsertTextFormat, MarkupKind, CompletionItemTag } from '../cssLanguageTypes';
11
- import * as nls from 'vscode-nls';
11
+ import * as l10n from '@vscode/l10n';
12
12
  import { isDefined } from '../utils/objects';
13
13
  import { PathCompletionParticipant } from './pathCompletion';
14
- const localize = nls.loadMessageBundle();
15
14
  const SnippetFormat = InsertTextFormat.Snippet;
16
15
  const retriggerCommand = {
17
16
  title: 'Suggest',
@@ -57,6 +56,7 @@ export class CSSCompletion {
57
56
  const pathCompletionResult = await participant.computeCompletions(document, documentContext);
58
57
  return {
59
58
  isIncomplete: result.isIncomplete || pathCompletionResult.isIncomplete,
59
+ itemDefaults: result.itemDefaults,
60
60
  items: pathCompletionResult.items.concat(result.items)
61
61
  };
62
62
  }
@@ -73,7 +73,16 @@ export class CSSCompletion {
73
73
  this.styleSheet = styleSheet;
74
74
  this.documentSettings = documentSettings;
75
75
  try {
76
- const result = { isIncomplete: false, items: [] };
76
+ const result = {
77
+ isIncomplete: false,
78
+ itemDefaults: {
79
+ editRange: {
80
+ start: { line: position.line, character: position.character - this.currentWord.length },
81
+ end: position
82
+ }
83
+ },
84
+ items: []
85
+ };
77
86
  this.nodePath = nodes.getNodePath(this.styleSheet, this.offset);
78
87
  for (let i = this.nodePath.length - 1; i >= 0; i--) {
79
88
  const node = this.nodePath[i];
@@ -401,7 +410,7 @@ export class CSSCompletion {
401
410
  if (symbol.node.type === nodes.NodeType.FunctionParameter) {
402
411
  const mixinNode = (symbol.node.getParent());
403
412
  if (mixinNode.type === nodes.NodeType.MixinDeclaration) {
404
- completionItem.detail = localize('completion.argument', 'argument from \'{0}\'', mixinNode.getName());
413
+ completionItem.detail = l10n.t('argument from \'{0}\'', mixinNode.getName());
405
414
  }
406
415
  }
407
416
  result.items.push(completionItem);
@@ -4,13 +4,12 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  'use strict';
6
6
  import { DocumentHighlightKind, Location, Range, SymbolKind, TextEdit, FileType } from '../cssLanguageTypes';
7
- import * as nls from 'vscode-nls';
7
+ import * as l10n from '@vscode/l10n';
8
8
  import * as nodes from '../parser/cssNodes';
9
9
  import { Symbols } from '../parser/cssSymbolScope';
10
10
  import { getColorValue, hslFromColor, hwbFromColor } from '../languageFacts/facts';
11
11
  import { startsWith } from '../utils/strings';
12
12
  import { dirname, joinPath } from '../utils/resources';
13
- const localize = nls.loadMessageBundle();
14
13
  const startsWithSchemeRegex = /^\w+:\/\//;
15
14
  const startsWithData = /^data:/;
16
15
  export class CSSNavigation {
@@ -43,16 +42,23 @@ export class CSSNavigation {
43
42
  };
44
43
  });
45
44
  }
46
- findDocumentHighlights(document, position, stylesheet) {
47
- const result = [];
45
+ getHighlightNode(document, position, stylesheet) {
48
46
  const offset = document.offsetAt(position);
49
47
  let node = nodes.getNodeAtOffset(stylesheet, offset);
50
48
  if (!node || node.type === nodes.NodeType.Stylesheet || node.type === nodes.NodeType.Declarations) {
51
- return result;
49
+ return;
52
50
  }
53
51
  if (node.type === nodes.NodeType.Identifier && node.parent && node.parent.type === nodes.NodeType.ClassSelector) {
54
52
  node = node.parent;
55
53
  }
54
+ return node;
55
+ }
56
+ findDocumentHighlights(document, position, stylesheet) {
57
+ const result = [];
58
+ const node = this.getHighlightNode(document, position, stylesheet);
59
+ if (!node) {
60
+ return result;
61
+ }
56
62
  const symbols = new Symbols(stylesheet);
57
63
  const symbol = symbols.findSymbolFromNode(node);
58
64
  const name = node.getText();
@@ -115,7 +121,7 @@ export class CSSNavigation {
115
121
  resolvedLinks.push(link);
116
122
  }
117
123
  else {
118
- const resolvedTarget = await this.resolveRelativeReference(target, document.uri, documentContext, data.isRawLink);
124
+ const resolvedTarget = await this.resolveReference(target, document.uri, documentContext, data.isRawLink);
119
125
  if (resolvedTarget !== undefined) {
120
126
  link.target = resolvedTarget;
121
127
  resolvedLinks.push(link);
@@ -230,11 +236,11 @@ export class CSSNavigation {
230
236
  collect(node.getName(), SymbolKind.Function, node, node.getIdentifier(), node.getDeclarations());
231
237
  }
232
238
  else if (node instanceof nodes.Keyframe) {
233
- const name = localize('literal.keyframes', "@keyframes {0}", node.getName());
239
+ const name = l10n.t("@keyframes {0}", node.getName());
234
240
  collect(name, SymbolKind.Class, node, node.getIdentifier(), node.getDeclarations());
235
241
  }
236
242
  else if (node instanceof nodes.FontFace) {
237
- const name = localize('literal.fontface', "@font-face");
243
+ const name = l10n.t("@font-face");
238
244
  collect(name, SymbolKind.Class, node, undefined, node.getDeclarations());
239
245
  }
240
246
  else if (node instanceof nodes.Media) {
@@ -294,6 +300,12 @@ export class CSSNavigation {
294
300
  result.push({ label: label, textEdit: TextEdit.replace(range, label) });
295
301
  return result;
296
302
  }
303
+ prepareRename(document, position, stylesheet) {
304
+ const node = this.getHighlightNode(document, position, stylesheet);
305
+ if (node) {
306
+ return Range.create(document.positionAt(node.offset), document.positionAt(node.end));
307
+ }
308
+ }
297
309
  doRename(document, position, newName, stylesheet) {
298
310
  const highlights = this.findDocumentHighlights(document, position, stylesheet);
299
311
  const edits = highlights.map(h => TextEdit.replace(h.range, newName));
@@ -304,39 +316,46 @@ export class CSSNavigation {
304
316
  async resolveModuleReference(ref, documentUri, documentContext) {
305
317
  if (startsWith(documentUri, 'file://')) {
306
318
  const moduleName = getModuleNameFromPath(ref);
307
- const rootFolderUri = documentContext.resolveReference('/', documentUri);
308
- const documentFolderUri = dirname(documentUri);
309
- const modulePath = await this.resolvePathToModule(moduleName, documentFolderUri, rootFolderUri);
310
- if (modulePath) {
311
- const pathWithinModule = ref.substring(moduleName.length + 1);
312
- return joinPath(modulePath, pathWithinModule);
319
+ if (moduleName && moduleName !== '.' && moduleName !== '..') {
320
+ const rootFolderUri = documentContext.resolveReference('/', documentUri);
321
+ const documentFolderUri = dirname(documentUri);
322
+ const modulePath = await this.resolvePathToModule(moduleName, documentFolderUri, rootFolderUri);
323
+ if (modulePath) {
324
+ const pathWithinModule = ref.substring(moduleName.length + 1);
325
+ return joinPath(modulePath, pathWithinModule);
326
+ }
313
327
  }
314
328
  }
315
329
  return undefined;
316
330
  }
317
- async resolveRelativeReference(ref, documentUri, documentContext, isRawLink) {
318
- const relativeReference = documentContext.resolveReference(ref, documentUri);
331
+ async mapReference(target, isRawLink) {
332
+ return target;
333
+ }
334
+ async resolveReference(target, documentUri, documentContext, isRawLink = false) {
319
335
  // Following [css-loader](https://github.com/webpack-contrib/css-loader#url)
320
336
  // and [sass-loader's](https://github.com/webpack-contrib/sass-loader#imports)
321
337
  // convention, if an import path starts with ~ then use node module resolution
322
338
  // *unless* it starts with "~/" as this refers to the user's home directory.
323
- if (ref[0] === '~' && ref[1] !== '/' && this.fileSystemProvider) {
324
- ref = ref.substring(1);
325
- return await this.resolveModuleReference(ref, documentUri, documentContext) || relativeReference;
339
+ if (target[0] === '~' && target[1] !== '/' && this.fileSystemProvider) {
340
+ target = target.substring(1);
341
+ return this.mapReference(await this.resolveModuleReference(target, documentUri, documentContext), isRawLink);
326
342
  }
343
+ const ref = await this.mapReference(documentContext.resolveReference(target, documentUri), isRawLink);
327
344
  // Following [less-loader](https://github.com/webpack-contrib/less-loader#imports)
328
345
  // and [sass-loader's](https://github.com/webpack-contrib/sass-loader#resolving-import-at-rules)
329
- // new resolving import at-rules (~ is deprecated). The loader will first try to resolve @import as a relative path. If it cannot be resolved,
346
+ // new resolving import at-rules (~ is deprecated). The loader will first try to resolve @import as a relative path. If it cannot be resolved,
330
347
  // then the loader will try to resolve @import inside node_modules.
331
348
  if (this.resolveModuleReferences) {
332
- if (relativeReference && await this.fileExists(relativeReference)) {
333
- return relativeReference;
349
+ if (ref && await this.fileExists(ref)) {
350
+ return ref;
334
351
  }
335
- else {
336
- return await this.resolveModuleReference(ref, documentUri, documentContext) || relativeReference;
352
+ const moduleReference = await this.mapReference(await this.resolveModuleReference(target, documentUri, documentContext), isRawLink);
353
+ if (moduleReference) {
354
+ return moduleReference;
337
355
  }
338
356
  }
339
- return relativeReference;
357
+ // fall back. it might not exists
358
+ return ref;
340
359
  }
341
360
  async resolvePathToModule(_moduleName, documentFolderUri, rootFolderUri) {
342
361
  // resolve the module relative to the document. We can't use `require` here as the code is webpacked.