vscode-css-languageservice 5.4.2 → 6.0.0

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 (84) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/lib/esm/cssLanguageService.d.ts +37 -37
  3. package/lib/esm/cssLanguageService.js +72 -75
  4. package/lib/esm/cssLanguageTypes.d.ts +238 -238
  5. package/lib/esm/cssLanguageTypes.js +42 -42
  6. package/lib/esm/data/webCustomData.js +21965 -21965
  7. package/lib/esm/languageFacts/builtinData.js +142 -142
  8. package/lib/esm/languageFacts/colors.js +469 -472
  9. package/lib/esm/languageFacts/dataManager.js +88 -92
  10. package/lib/esm/languageFacts/dataProvider.js +73 -79
  11. package/lib/esm/languageFacts/entry.js +137 -138
  12. package/lib/esm/languageFacts/facts.js +8 -8
  13. package/lib/esm/parser/cssErrors.js +48 -50
  14. package/lib/esm/parser/cssNodes.js +1502 -2019
  15. package/lib/esm/parser/cssParser.js +1534 -1563
  16. package/lib/esm/parser/cssScanner.js +592 -599
  17. package/lib/esm/parser/cssSymbolScope.js +311 -341
  18. package/lib/esm/parser/lessParser.js +714 -740
  19. package/lib/esm/parser/lessScanner.js +57 -78
  20. package/lib/esm/parser/scssErrors.js +18 -20
  21. package/lib/esm/parser/scssParser.js +796 -818
  22. package/lib/esm/parser/scssScanner.js +95 -116
  23. package/lib/esm/services/cssCodeActions.js +77 -81
  24. package/lib/esm/services/cssCompletion.js +1054 -1149
  25. package/lib/esm/services/cssFolding.js +190 -193
  26. package/lib/esm/services/cssFormatter.js +136 -136
  27. package/lib/esm/services/cssHover.js +148 -151
  28. package/lib/esm/services/cssNavigation.js +378 -470
  29. package/lib/esm/services/cssSelectionRange.js +47 -47
  30. package/lib/esm/services/cssValidation.js +41 -44
  31. package/lib/esm/services/lessCompletion.js +378 -397
  32. package/lib/esm/services/lint.js +518 -532
  33. package/lib/esm/services/lintRules.js +76 -83
  34. package/lib/esm/services/lintUtil.js +196 -205
  35. package/lib/esm/services/pathCompletion.js +157 -231
  36. package/lib/esm/services/scssCompletion.js +354 -378
  37. package/lib/esm/services/scssNavigation.js +82 -154
  38. package/lib/esm/services/selectorPrinting.js +492 -536
  39. package/lib/esm/utils/arrays.js +40 -46
  40. package/lib/esm/utils/objects.js +11 -11
  41. package/lib/esm/utils/resources.js +11 -24
  42. package/lib/esm/utils/strings.js +102 -104
  43. package/lib/umd/cssLanguageService.d.ts +37 -37
  44. package/lib/umd/cssLanguageService.js +99 -102
  45. package/lib/umd/cssLanguageTypes.d.ts +238 -238
  46. package/lib/umd/cssLanguageTypes.js +89 -88
  47. package/lib/umd/data/webCustomData.js +21978 -21978
  48. package/lib/umd/languageFacts/builtinData.js +154 -154
  49. package/lib/umd/languageFacts/colors.js +492 -495
  50. package/lib/umd/languageFacts/dataManager.js +101 -104
  51. package/lib/umd/languageFacts/dataProvider.js +86 -91
  52. package/lib/umd/languageFacts/entry.js +152 -153
  53. package/lib/umd/languageFacts/facts.js +29 -29
  54. package/lib/umd/parser/cssErrors.js +61 -62
  55. package/lib/umd/parser/cssNodes.js +1587 -2034
  56. package/lib/umd/parser/cssParser.js +1547 -1575
  57. package/lib/umd/parser/cssScanner.js +606 -611
  58. package/lib/umd/parser/cssSymbolScope.js +328 -353
  59. package/lib/umd/parser/lessParser.js +727 -752
  60. package/lib/umd/parser/lessScanner.js +70 -90
  61. package/lib/umd/parser/scssErrors.js +31 -32
  62. package/lib/umd/parser/scssParser.js +809 -830
  63. package/lib/umd/parser/scssScanner.js +108 -128
  64. package/lib/umd/services/cssCodeActions.js +90 -93
  65. package/lib/umd/services/cssCompletion.js +1067 -1161
  66. package/lib/umd/services/cssFolding.js +203 -206
  67. package/lib/umd/services/cssFormatter.js +150 -150
  68. package/lib/umd/services/cssHover.js +161 -163
  69. package/lib/umd/services/cssNavigation.js +391 -482
  70. package/lib/umd/services/cssSelectionRange.js +60 -60
  71. package/lib/umd/services/cssValidation.js +54 -56
  72. package/lib/umd/services/lessCompletion.js +391 -409
  73. package/lib/umd/services/lint.js +531 -544
  74. package/lib/umd/services/lintRules.js +91 -95
  75. package/lib/umd/services/lintUtil.js +210 -218
  76. package/lib/umd/services/pathCompletion.js +171 -244
  77. package/lib/umd/services/scssCompletion.js +367 -390
  78. package/lib/umd/services/scssNavigation.js +95 -166
  79. package/lib/umd/services/selectorPrinting.js +510 -550
  80. package/lib/umd/utils/arrays.js +55 -61
  81. package/lib/umd/utils/objects.js +25 -25
  82. package/lib/umd/utils/resources.js +26 -39
  83. package/lib/umd/utils/strings.js +120 -122
  84. package/package.json +10 -10
@@ -1,83 +1,76 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the MIT License. See License.txt in the project root for license information.
4
- *--------------------------------------------------------------------------------------------*/
5
- 'use strict';
6
- import * as nodes from '../parser/cssNodes';
7
- import * as nls from 'vscode-nls';
8
- var localize = nls.loadMessageBundle();
9
- var Warning = nodes.Level.Warning;
10
- var Error = nodes.Level.Error;
11
- var Ignore = nodes.Level.Ignore;
12
- var Rule = /** @class */ (function () {
13
- function Rule(id, message, defaultValue) {
14
- this.id = id;
15
- this.message = message;
16
- this.defaultValue = defaultValue;
17
- // nothing to do
18
- }
19
- return Rule;
20
- }());
21
- export { Rule };
22
- var Setting = /** @class */ (function () {
23
- function Setting(id, message, defaultValue) {
24
- this.id = id;
25
- this.message = message;
26
- this.defaultValue = defaultValue;
27
- // nothing to do
28
- }
29
- return Setting;
30
- }());
31
- export { Setting };
32
- export var Rules = {
33
- AllVendorPrefixes: new Rule('compatibleVendorPrefixes', localize('rule.vendorprefixes.all', "When using a vendor-specific prefix make sure to also include all other vendor-specific properties"), Ignore),
34
- IncludeStandardPropertyWhenUsingVendorPrefix: new Rule('vendorPrefix', localize('rule.standardvendorprefix.all', "When using a vendor-specific prefix also include the standard property"), Warning),
35
- DuplicateDeclarations: new Rule('duplicateProperties', localize('rule.duplicateDeclarations', "Do not use duplicate style definitions"), Ignore),
36
- EmptyRuleSet: new Rule('emptyRules', localize('rule.emptyRuleSets', "Do not use empty rulesets"), Warning),
37
- ImportStatemement: new Rule('importStatement', localize('rule.importDirective', "Import statements do not load in parallel"), Ignore),
38
- BewareOfBoxModelSize: new Rule('boxModel', localize('rule.bewareOfBoxModelSize', "Do not use width or height when using padding or border"), Ignore),
39
- UniversalSelector: new Rule('universalSelector', localize('rule.universalSelector', "The universal selector (*) is known to be slow"), Ignore),
40
- ZeroWithUnit: new Rule('zeroUnits', localize('rule.zeroWidthUnit', "No unit for zero needed"), Ignore),
41
- RequiredPropertiesForFontFace: new Rule('fontFaceProperties', localize('rule.fontFaceProperties', "@font-face rule must define 'src' and 'font-family' properties"), Warning),
42
- HexColorLength: new Rule('hexColorLength', localize('rule.hexColor', "Hex colors must consist of three, four, six or eight hex numbers"), Error),
43
- ArgsInColorFunction: new Rule('argumentsInColorFunction', localize('rule.colorFunction', "Invalid number of parameters"), Error),
44
- UnknownProperty: new Rule('unknownProperties', localize('rule.unknownProperty', "Unknown property."), Warning),
45
- UnknownAtRules: new Rule('unknownAtRules', localize('rule.unknownAtRules', "Unknown at-rule."), Warning),
46
- IEStarHack: new Rule('ieHack', localize('rule.ieHack', "IE hacks are only necessary when supporting IE7 and older"), Ignore),
47
- UnknownVendorSpecificProperty: new Rule('unknownVendorSpecificProperties', localize('rule.unknownVendorSpecificProperty', "Unknown vendor specific property."), Ignore),
48
- PropertyIgnoredDueToDisplay: new Rule('propertyIgnoredDueToDisplay', localize('rule.propertyIgnoredDueToDisplay', "Property is ignored due to the display."), Warning),
49
- AvoidImportant: new Rule('important', localize('rule.avoidImportant', "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored."), Ignore),
50
- AvoidFloat: new Rule('float', localize('rule.avoidFloat', "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes."), Ignore),
51
- AvoidIdSelector: new Rule('idSelector', localize('rule.avoidIdSelector', "Selectors should not contain IDs because these rules are too tightly coupled with the HTML."), Ignore),
52
- };
53
- export var Settings = {
54
- ValidProperties: new Setting('validProperties', localize('rule.validProperties', "A list of properties that are not validated against the `unknownProperties` rule."), [])
55
- };
56
- var LintConfigurationSettings = /** @class */ (function () {
57
- function LintConfigurationSettings(conf) {
58
- if (conf === void 0) { conf = {}; }
59
- this.conf = conf;
60
- }
61
- LintConfigurationSettings.prototype.getRule = function (rule) {
62
- if (this.conf.hasOwnProperty(rule.id)) {
63
- var level = toLevel(this.conf[rule.id]);
64
- if (level) {
65
- return level;
66
- }
67
- }
68
- return rule.defaultValue;
69
- };
70
- LintConfigurationSettings.prototype.getSetting = function (setting) {
71
- return this.conf[setting.id];
72
- };
73
- return LintConfigurationSettings;
74
- }());
75
- export { LintConfigurationSettings };
76
- function toLevel(level) {
77
- switch (level) {
78
- case 'ignore': return nodes.Level.Ignore;
79
- case 'warning': return nodes.Level.Warning;
80
- case 'error': return nodes.Level.Error;
81
- }
82
- return null;
83
- }
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ 'use strict';
6
+ import * as nodes from '../parser/cssNodes';
7
+ import * as nls from 'vscode-nls';
8
+ const localize = nls.loadMessageBundle();
9
+ const Warning = nodes.Level.Warning;
10
+ const Error = nodes.Level.Error;
11
+ const Ignore = nodes.Level.Ignore;
12
+ export class Rule {
13
+ constructor(id, message, defaultValue) {
14
+ this.id = id;
15
+ this.message = message;
16
+ this.defaultValue = defaultValue;
17
+ // nothing to do
18
+ }
19
+ }
20
+ export class Setting {
21
+ constructor(id, message, defaultValue) {
22
+ this.id = id;
23
+ this.message = message;
24
+ this.defaultValue = defaultValue;
25
+ // nothing to do
26
+ }
27
+ }
28
+ export const Rules = {
29
+ AllVendorPrefixes: new Rule('compatibleVendorPrefixes', localize('rule.vendorprefixes.all', "When using a vendor-specific prefix make sure to also include all other vendor-specific properties"), Ignore),
30
+ IncludeStandardPropertyWhenUsingVendorPrefix: new Rule('vendorPrefix', localize('rule.standardvendorprefix.all', "When using a vendor-specific prefix also include the standard property"), Warning),
31
+ DuplicateDeclarations: new Rule('duplicateProperties', localize('rule.duplicateDeclarations', "Do not use duplicate style definitions"), Ignore),
32
+ EmptyRuleSet: new Rule('emptyRules', localize('rule.emptyRuleSets', "Do not use empty rulesets"), Warning),
33
+ ImportStatemement: new Rule('importStatement', localize('rule.importDirective', "Import statements do not load in parallel"), Ignore),
34
+ BewareOfBoxModelSize: new Rule('boxModel', localize('rule.bewareOfBoxModelSize', "Do not use width or height when using padding or border"), Ignore),
35
+ UniversalSelector: new Rule('universalSelector', localize('rule.universalSelector', "The universal selector (*) is known to be slow"), Ignore),
36
+ ZeroWithUnit: new Rule('zeroUnits', localize('rule.zeroWidthUnit', "No unit for zero needed"), Ignore),
37
+ RequiredPropertiesForFontFace: new Rule('fontFaceProperties', localize('rule.fontFaceProperties', "@font-face rule must define 'src' and 'font-family' properties"), Warning),
38
+ HexColorLength: new Rule('hexColorLength', localize('rule.hexColor', "Hex colors must consist of three, four, six or eight hex numbers"), Error),
39
+ ArgsInColorFunction: new Rule('argumentsInColorFunction', localize('rule.colorFunction', "Invalid number of parameters"), Error),
40
+ UnknownProperty: new Rule('unknownProperties', localize('rule.unknownProperty', "Unknown property."), Warning),
41
+ UnknownAtRules: new Rule('unknownAtRules', localize('rule.unknownAtRules', "Unknown at-rule."), Warning),
42
+ IEStarHack: new Rule('ieHack', localize('rule.ieHack', "IE hacks are only necessary when supporting IE7 and older"), Ignore),
43
+ UnknownVendorSpecificProperty: new Rule('unknownVendorSpecificProperties', localize('rule.unknownVendorSpecificProperty', "Unknown vendor specific property."), Ignore),
44
+ PropertyIgnoredDueToDisplay: new Rule('propertyIgnoredDueToDisplay', localize('rule.propertyIgnoredDueToDisplay', "Property is ignored due to the display."), Warning),
45
+ AvoidImportant: new Rule('important', localize('rule.avoidImportant', "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored."), Ignore),
46
+ AvoidFloat: new Rule('float', localize('rule.avoidFloat', "Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes."), Ignore),
47
+ AvoidIdSelector: new Rule('idSelector', localize('rule.avoidIdSelector', "Selectors should not contain IDs because these rules are too tightly coupled with the HTML."), Ignore),
48
+ };
49
+ export const Settings = {
50
+ ValidProperties: new Setting('validProperties', localize('rule.validProperties', "A list of properties that are not validated against the `unknownProperties` rule."), [])
51
+ };
52
+ export class LintConfigurationSettings {
53
+ constructor(conf = {}) {
54
+ this.conf = conf;
55
+ }
56
+ getRule(rule) {
57
+ if (this.conf.hasOwnProperty(rule.id)) {
58
+ const level = toLevel(this.conf[rule.id]);
59
+ if (level) {
60
+ return level;
61
+ }
62
+ }
63
+ return rule.defaultValue;
64
+ }
65
+ getSetting(setting) {
66
+ return this.conf[setting.id];
67
+ }
68
+ }
69
+ function toLevel(level) {
70
+ switch (level) {
71
+ case 'ignore': return nodes.Level.Ignore;
72
+ case 'warning': return nodes.Level.Warning;
73
+ case 'error': return nodes.Level.Error;
74
+ }
75
+ return null;
76
+ }
@@ -1,205 +1,196 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the MIT License. See License.txt in the project root for license information.
4
- *--------------------------------------------------------------------------------------------*/
5
- 'use strict';
6
- import { includes } from '../utils/arrays';
7
- var Element = /** @class */ (function () {
8
- function Element(decl) {
9
- this.fullPropertyName = decl.getFullPropertyName().toLowerCase();
10
- this.node = decl;
11
- }
12
- return Element;
13
- }());
14
- export { Element };
15
- function setSide(model, side, value, property) {
16
- var state = model[side];
17
- state.value = value;
18
- if (value) {
19
- if (!includes(state.properties, property)) {
20
- state.properties.push(property);
21
- }
22
- }
23
- }
24
- function setAllSides(model, value, property) {
25
- setSide(model, 'top', value, property);
26
- setSide(model, 'right', value, property);
27
- setSide(model, 'bottom', value, property);
28
- setSide(model, 'left', value, property);
29
- }
30
- function updateModelWithValue(model, side, value, property) {
31
- if (side === 'top' || side === 'right' ||
32
- side === 'bottom' || side === 'left') {
33
- setSide(model, side, value, property);
34
- }
35
- else {
36
- setAllSides(model, value, property);
37
- }
38
- }
39
- function updateModelWithList(model, values, property) {
40
- switch (values.length) {
41
- case 1:
42
- updateModelWithValue(model, undefined, values[0], property);
43
- break;
44
- case 2:
45
- updateModelWithValue(model, 'top', values[0], property);
46
- updateModelWithValue(model, 'bottom', values[0], property);
47
- updateModelWithValue(model, 'right', values[1], property);
48
- updateModelWithValue(model, 'left', values[1], property);
49
- break;
50
- case 3:
51
- updateModelWithValue(model, 'top', values[0], property);
52
- updateModelWithValue(model, 'right', values[1], property);
53
- updateModelWithValue(model, 'left', values[1], property);
54
- updateModelWithValue(model, 'bottom', values[2], property);
55
- break;
56
- case 4:
57
- updateModelWithValue(model, 'top', values[0], property);
58
- updateModelWithValue(model, 'right', values[1], property);
59
- updateModelWithValue(model, 'bottom', values[2], property);
60
- updateModelWithValue(model, 'left', values[3], property);
61
- break;
62
- }
63
- }
64
- function matches(value, candidates) {
65
- for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
66
- var candidate = candidates_1[_i];
67
- if (value.matches(candidate)) {
68
- return true;
69
- }
70
- }
71
- return false;
72
- }
73
- /**
74
- * @param allowsKeywords whether the initial value of property is zero, so keywords `initial` and `unset` count as zero
75
- * @return `true` if this node represents a non-zero border; otherwise, `false`
76
- */
77
- function checkLineWidth(value, allowsKeywords) {
78
- if (allowsKeywords === void 0) { allowsKeywords = true; }
79
- if (allowsKeywords && matches(value, ['initial', 'unset'])) {
80
- return false;
81
- }
82
- // a <length> is a value and a unit
83
- // so use `parseFloat` to strip the unit
84
- return parseFloat(value.getText()) !== 0;
85
- }
86
- function checkLineWidthList(nodes, allowsKeywords) {
87
- if (allowsKeywords === void 0) { allowsKeywords = true; }
88
- return nodes.map(function (node) { return checkLineWidth(node, allowsKeywords); });
89
- }
90
- /**
91
- * @param allowsKeywords whether keywords `initial` and `unset` count as zero
92
- * @return `true` if this node represents a non-zero border; otherwise, `false`
93
- */
94
- function checkLineStyle(valueNode, allowsKeywords) {
95
- if (allowsKeywords === void 0) { allowsKeywords = true; }
96
- if (matches(valueNode, ['none', 'hidden'])) {
97
- return false;
98
- }
99
- if (allowsKeywords && matches(valueNode, ['initial', 'unset'])) {
100
- return false;
101
- }
102
- return true;
103
- }
104
- function checkLineStyleList(nodes, allowsKeywords) {
105
- if (allowsKeywords === void 0) { allowsKeywords = true; }
106
- return nodes.map(function (node) { return checkLineStyle(node, allowsKeywords); });
107
- }
108
- function checkBorderShorthand(node) {
109
- var children = node.getChildren();
110
- // the only child can be a keyword, a <line-width>, or a <line-style>
111
- // if either check returns false, the result is no border
112
- if (children.length === 1) {
113
- var value = children[0];
114
- return checkLineWidth(value) && checkLineStyle(value);
115
- }
116
- // multiple children can't contain keywords
117
- // if any child means no border, the result is no border
118
- for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
119
- var child = children_1[_i];
120
- var value = child;
121
- if (!checkLineWidth(value, /* allowsKeywords: */ false) ||
122
- !checkLineStyle(value, /* allowsKeywords: */ false)) {
123
- return false;
124
- }
125
- }
126
- return true;
127
- }
128
- export default function calculateBoxModel(propertyTable) {
129
- var model = {
130
- top: { value: false, properties: [] },
131
- right: { value: false, properties: [] },
132
- bottom: { value: false, properties: [] },
133
- left: { value: false, properties: [] },
134
- };
135
- for (var _i = 0, propertyTable_1 = propertyTable; _i < propertyTable_1.length; _i++) {
136
- var property = propertyTable_1[_i];
137
- var value = property.node.value;
138
- if (typeof value === 'undefined') {
139
- continue;
140
- }
141
- switch (property.fullPropertyName) {
142
- case 'box-sizing':
143
- // has `box-sizing`, bail out
144
- return {
145
- top: { value: false, properties: [] },
146
- right: { value: false, properties: [] },
147
- bottom: { value: false, properties: [] },
148
- left: { value: false, properties: [] },
149
- };
150
- case 'width':
151
- model.width = property;
152
- break;
153
- case 'height':
154
- model.height = property;
155
- break;
156
- default:
157
- var segments = property.fullPropertyName.split('-');
158
- switch (segments[0]) {
159
- case 'border':
160
- switch (segments[1]) {
161
- case undefined:
162
- case 'top':
163
- case 'right':
164
- case 'bottom':
165
- case 'left':
166
- switch (segments[2]) {
167
- case undefined:
168
- updateModelWithValue(model, segments[1], checkBorderShorthand(value), property);
169
- break;
170
- case 'width':
171
- // the initial value of `border-width` is `medium`, not zero
172
- updateModelWithValue(model, segments[1], checkLineWidth(value, false), property);
173
- break;
174
- case 'style':
175
- // the initial value of `border-style` is `none`
176
- updateModelWithValue(model, segments[1], checkLineStyle(value, true), property);
177
- break;
178
- }
179
- break;
180
- case 'width':
181
- // the initial value of `border-width` is `medium`, not zero
182
- updateModelWithList(model, checkLineWidthList(value.getChildren(), false), property);
183
- break;
184
- case 'style':
185
- // the initial value of `border-style` is `none`
186
- updateModelWithList(model, checkLineStyleList(value.getChildren(), true), property);
187
- break;
188
- }
189
- break;
190
- case 'padding':
191
- if (segments.length === 1) {
192
- // the initial value of `padding` is zero
193
- updateModelWithList(model, checkLineWidthList(value.getChildren(), true), property);
194
- }
195
- else {
196
- // the initial value of `padding` is zero
197
- updateModelWithValue(model, segments[1], checkLineWidth(value, true), property);
198
- }
199
- break;
200
- }
201
- break;
202
- }
203
- }
204
- return model;
205
- }
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ 'use strict';
6
+ import { includes } from '../utils/arrays';
7
+ export class Element {
8
+ constructor(decl) {
9
+ this.fullPropertyName = decl.getFullPropertyName().toLowerCase();
10
+ this.node = decl;
11
+ }
12
+ }
13
+ function setSide(model, side, value, property) {
14
+ const state = model[side];
15
+ state.value = value;
16
+ if (value) {
17
+ if (!includes(state.properties, property)) {
18
+ state.properties.push(property);
19
+ }
20
+ }
21
+ }
22
+ function setAllSides(model, value, property) {
23
+ setSide(model, 'top', value, property);
24
+ setSide(model, 'right', value, property);
25
+ setSide(model, 'bottom', value, property);
26
+ setSide(model, 'left', value, property);
27
+ }
28
+ function updateModelWithValue(model, side, value, property) {
29
+ if (side === 'top' || side === 'right' ||
30
+ side === 'bottom' || side === 'left') {
31
+ setSide(model, side, value, property);
32
+ }
33
+ else {
34
+ setAllSides(model, value, property);
35
+ }
36
+ }
37
+ function updateModelWithList(model, values, property) {
38
+ switch (values.length) {
39
+ case 1:
40
+ updateModelWithValue(model, undefined, values[0], property);
41
+ break;
42
+ case 2:
43
+ updateModelWithValue(model, 'top', values[0], property);
44
+ updateModelWithValue(model, 'bottom', values[0], property);
45
+ updateModelWithValue(model, 'right', values[1], property);
46
+ updateModelWithValue(model, 'left', values[1], property);
47
+ break;
48
+ case 3:
49
+ updateModelWithValue(model, 'top', values[0], property);
50
+ updateModelWithValue(model, 'right', values[1], property);
51
+ updateModelWithValue(model, 'left', values[1], property);
52
+ updateModelWithValue(model, 'bottom', values[2], property);
53
+ break;
54
+ case 4:
55
+ updateModelWithValue(model, 'top', values[0], property);
56
+ updateModelWithValue(model, 'right', values[1], property);
57
+ updateModelWithValue(model, 'bottom', values[2], property);
58
+ updateModelWithValue(model, 'left', values[3], property);
59
+ break;
60
+ }
61
+ }
62
+ function matches(value, candidates) {
63
+ for (let candidate of candidates) {
64
+ if (value.matches(candidate)) {
65
+ return true;
66
+ }
67
+ }
68
+ return false;
69
+ }
70
+ /**
71
+ * @param allowsKeywords whether the initial value of property is zero, so keywords `initial` and `unset` count as zero
72
+ * @return `true` if this node represents a non-zero border; otherwise, `false`
73
+ */
74
+ function checkLineWidth(value, allowsKeywords = true) {
75
+ if (allowsKeywords && matches(value, ['initial', 'unset'])) {
76
+ return false;
77
+ }
78
+ // a <length> is a value and a unit
79
+ // so use `parseFloat` to strip the unit
80
+ return parseFloat(value.getText()) !== 0;
81
+ }
82
+ function checkLineWidthList(nodes, allowsKeywords = true) {
83
+ return nodes.map(node => checkLineWidth(node, allowsKeywords));
84
+ }
85
+ /**
86
+ * @param allowsKeywords whether keywords `initial` and `unset` count as zero
87
+ * @return `true` if this node represents a non-zero border; otherwise, `false`
88
+ */
89
+ function checkLineStyle(valueNode, allowsKeywords = true) {
90
+ if (matches(valueNode, ['none', 'hidden'])) {
91
+ return false;
92
+ }
93
+ if (allowsKeywords && matches(valueNode, ['initial', 'unset'])) {
94
+ return false;
95
+ }
96
+ return true;
97
+ }
98
+ function checkLineStyleList(nodes, allowsKeywords = true) {
99
+ return nodes.map(node => checkLineStyle(node, allowsKeywords));
100
+ }
101
+ function checkBorderShorthand(node) {
102
+ const children = node.getChildren();
103
+ // the only child can be a keyword, a <line-width>, or a <line-style>
104
+ // if either check returns false, the result is no border
105
+ if (children.length === 1) {
106
+ const value = children[0];
107
+ return checkLineWidth(value) && checkLineStyle(value);
108
+ }
109
+ // multiple children can't contain keywords
110
+ // if any child means no border, the result is no border
111
+ for (const child of children) {
112
+ const value = child;
113
+ if (!checkLineWidth(value, /* allowsKeywords: */ false) ||
114
+ !checkLineStyle(value, /* allowsKeywords: */ false)) {
115
+ return false;
116
+ }
117
+ }
118
+ return true;
119
+ }
120
+ export default function calculateBoxModel(propertyTable) {
121
+ const model = {
122
+ top: { value: false, properties: [] },
123
+ right: { value: false, properties: [] },
124
+ bottom: { value: false, properties: [] },
125
+ left: { value: false, properties: [] },
126
+ };
127
+ for (const property of propertyTable) {
128
+ const value = property.node.value;
129
+ if (typeof value === 'undefined') {
130
+ continue;
131
+ }
132
+ switch (property.fullPropertyName) {
133
+ case 'box-sizing':
134
+ // has `box-sizing`, bail out
135
+ return {
136
+ top: { value: false, properties: [] },
137
+ right: { value: false, properties: [] },
138
+ bottom: { value: false, properties: [] },
139
+ left: { value: false, properties: [] },
140
+ };
141
+ case 'width':
142
+ model.width = property;
143
+ break;
144
+ case 'height':
145
+ model.height = property;
146
+ break;
147
+ default:
148
+ const segments = property.fullPropertyName.split('-');
149
+ switch (segments[0]) {
150
+ case 'border':
151
+ switch (segments[1]) {
152
+ case undefined:
153
+ case 'top':
154
+ case 'right':
155
+ case 'bottom':
156
+ case 'left':
157
+ switch (segments[2]) {
158
+ case undefined:
159
+ updateModelWithValue(model, segments[1], checkBorderShorthand(value), property);
160
+ break;
161
+ case 'width':
162
+ // the initial value of `border-width` is `medium`, not zero
163
+ updateModelWithValue(model, segments[1], checkLineWidth(value, false), property);
164
+ break;
165
+ case 'style':
166
+ // the initial value of `border-style` is `none`
167
+ updateModelWithValue(model, segments[1], checkLineStyle(value, true), property);
168
+ break;
169
+ }
170
+ break;
171
+ case 'width':
172
+ // the initial value of `border-width` is `medium`, not zero
173
+ updateModelWithList(model, checkLineWidthList(value.getChildren(), false), property);
174
+ break;
175
+ case 'style':
176
+ // the initial value of `border-style` is `none`
177
+ updateModelWithList(model, checkLineStyleList(value.getChildren(), true), property);
178
+ break;
179
+ }
180
+ break;
181
+ case 'padding':
182
+ if (segments.length === 1) {
183
+ // the initial value of `padding` is zero
184
+ updateModelWithList(model, checkLineWidthList(value.getChildren(), true), property);
185
+ }
186
+ else {
187
+ // the initial value of `padding` is zero
188
+ updateModelWithValue(model, segments[1], checkLineWidth(value, true), property);
189
+ }
190
+ break;
191
+ }
192
+ break;
193
+ }
194
+ }
195
+ return model;
196
+ }