cssstyle 4.6.0 → 5.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.
package/lib/parsers.js CHANGED
@@ -83,6 +83,7 @@ const varRegEx = /^var\(/;
83
83
  const varContainedRegEx = /(?<=[*/\s(])var\(/;
84
84
  const calcRegEx =
85
85
  /^(?:a?(?:cos|sin|tan)|abs|atan2|calc|clamp|exp|hypot|log|max|min|mod|pow|rem|round|sign|sqrt)\(/;
86
+ const gradientRegEx = /^(?:repeating-)?(?:conic|linear|radial)-gradient\(/;
86
87
  const functionRegEx = /^([a-z][a-z\d]*(?:-[a-z\d]+)*)\(/i;
87
88
 
88
89
  const getNumericType = function getNumericType(val) {
@@ -429,36 +430,17 @@ exports.parseImage = function parseImage(val) {
429
430
  if (val === "") {
430
431
  return "";
431
432
  }
432
- if (varRegEx.test(val)) {
433
+ if (gradientRegEx.test(val) && varRegEx.test(val)) {
433
434
  return val;
434
435
  }
435
436
  if (keywordRegEx.test(val)) {
436
437
  return exports.parseKeyword(val, ["none"]);
437
438
  }
438
- const values = splitValue(val, {
439
- delimiter: ",",
440
- preserveComment: varContainedRegEx.test(val)
441
- });
442
- let isImage = Boolean(values.length);
443
- for (let i = 0; i < values.length; i++) {
444
- const image = values[i];
445
- if (image === "") {
446
- return "";
447
- }
448
- if (isGradient(image) || /^(?:none|inherit)$/i.test(image)) {
449
- continue;
450
- }
451
- const imageUrl = exports.parseUrl(image);
452
- if (imageUrl) {
453
- values[i] = imageUrl;
454
- } else {
455
- isImage = false;
456
- break;
457
- }
458
- }
459
- if (isImage) {
460
- return values.join(", ");
439
+ // FIXME: need to resolve color values within gradients
440
+ if (isGradient(val)) {
441
+ return val;
461
442
  }
443
+ return exports.parseUrl(val);
462
444
  };
463
445
 
464
446
  exports.parseFunction = function parseFunction(val) {
@@ -1,51 +1,382 @@
1
1
  "use strict";
2
- // FIXME:
3
- // * support multiple backgrounds
4
- // * also fix longhands
5
2
 
6
3
  const parsers = require("../parsers");
7
- const strings = require("../utils/strings");
8
4
  const backgroundImage = require("./backgroundImage");
9
5
  const backgroundPosition = require("./backgroundPosition");
6
+ const backgroundSize = require("./backgroundSize");
10
7
  const backgroundRepeat = require("./backgroundRepeat");
8
+ const backgroundOrigin = require("./backgroundOrigin");
9
+ const backgroundClip = require("./backgroundClip");
11
10
  const backgroundAttachment = require("./backgroundAttachment");
12
11
  const backgroundColor = require("./backgroundColor");
13
12
 
14
- const shorthandFor = new Map([
13
+ module.exports.shorthandFor = new Map([
15
14
  ["background-image", backgroundImage],
16
15
  ["background-position", backgroundPosition],
16
+ ["background-size", backgroundSize],
17
17
  ["background-repeat", backgroundRepeat],
18
+ ["background-origin", backgroundOrigin],
19
+ ["background-clip", backgroundClip],
18
20
  ["background-attachment", backgroundAttachment],
19
21
  ["background-color", backgroundColor]
20
22
  ]);
21
23
 
24
+ const initialValues = new Map([
25
+ ["background-image", "none"],
26
+ ["background-position", "0% 0%"],
27
+ ["background-size", "auto"],
28
+ ["background-repeat", "repeat"],
29
+ ["background-origin", "padding-box"],
30
+ ["background-clip", "border-box"],
31
+ ["background-attachment", "scroll"],
32
+ ["background-color", "transparent"]
33
+ ]);
34
+
35
+ module.exports.parse = function parse(v) {
36
+ const values = parsers.splitValue(v, {
37
+ delimiter: ","
38
+ });
39
+ const bgValues = [];
40
+ const l = values.length;
41
+ for (let i = 0; i < l; i++) {
42
+ let bg = {
43
+ "background-image": initialValues.get("background-image"),
44
+ "background-position": initialValues.get("background-position"),
45
+ "background-size": initialValues.get("background-size"),
46
+ "background-repeat": initialValues.get("background-repeat"),
47
+ "background-origin": initialValues.get("background-origin"),
48
+ "background-clip": initialValues.get("background-clip"),
49
+ "background-attachment": initialValues.get("background-attachment"),
50
+ "background-color": initialValues.get("background-color")
51
+ };
52
+ if (l > 1 && i !== l - 1) {
53
+ bg = {
54
+ "background-image": initialValues.get("background-image"),
55
+ "background-position": initialValues.get("background-position"),
56
+ "background-size": initialValues.get("background-size"),
57
+ "background-repeat": initialValues.get("background-repeat"),
58
+ "background-origin": initialValues.get("background-origin"),
59
+ "background-clip": initialValues.get("background-clip"),
60
+ "background-attachment": initialValues.get("background-attachment")
61
+ };
62
+ }
63
+ const bgPosition = [];
64
+ const bgSize = [];
65
+ const bgRepeat = [];
66
+ const bgBox = [];
67
+ const bgParts = parsers.splitValue(values[i], {
68
+ delimiter: "/"
69
+ });
70
+ if (!bgParts.length || bgParts.length > 2) {
71
+ return;
72
+ }
73
+ const [bgPart1, bgPart2 = ""] = bgParts;
74
+ const parts1 = parsers.splitValue(bgPart1);
75
+ for (const part of parts1) {
76
+ let partValid = false;
77
+ for (const [property, value] of module.exports.shorthandFor) {
78
+ if (value.isValid(part)) {
79
+ partValid = true;
80
+ switch (property) {
81
+ case "background-clip":
82
+ case "background-origin": {
83
+ const parsedValue = value.parse(part);
84
+ if (parsedValue) {
85
+ bgBox.push(parsedValue);
86
+ }
87
+ break;
88
+ }
89
+ case "background-color": {
90
+ if (i !== values.length - 1) {
91
+ return;
92
+ }
93
+ const parsedValue = value.parse(part);
94
+ if (parsedValue) {
95
+ bg[property] = parsedValue;
96
+ }
97
+ break;
98
+ }
99
+ case "background-position": {
100
+ const parsedValue = value.parse(part);
101
+ if (parsedValue) {
102
+ bgPosition.push(parsedValue);
103
+ }
104
+ break;
105
+ }
106
+ case "background-repeat": {
107
+ const parsedValue = value.parse(part);
108
+ if (parsedValue) {
109
+ bgRepeat.push(parsedValue);
110
+ }
111
+ break;
112
+ }
113
+ case "background-size": {
114
+ break;
115
+ }
116
+ default: {
117
+ const parsedValue = value.parse(part);
118
+ if (parsedValue) {
119
+ bg[property] = parsedValue;
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ if (!partValid) {
126
+ return;
127
+ }
128
+ }
129
+ if (bgPart2) {
130
+ const parts2 = parsers.splitValue(bgPart2);
131
+ for (const part of parts2) {
132
+ let partValid = false;
133
+ for (const [property, value] of module.exports.shorthandFor) {
134
+ if (value.isValid(part)) {
135
+ partValid = true;
136
+ switch (property) {
137
+ case "background-clip":
138
+ case "background-origin": {
139
+ const parsedValue = value.parse(part);
140
+ if (parsedValue) {
141
+ bgBox.push(parsedValue);
142
+ }
143
+ break;
144
+ }
145
+ case "background-color": {
146
+ if (i !== l - 1) {
147
+ return;
148
+ }
149
+ const parsedValue = value.parse(part);
150
+ if (parsedValue) {
151
+ bg[property] = parsedValue;
152
+ }
153
+ break;
154
+ }
155
+ case "background-position": {
156
+ break;
157
+ }
158
+ case "background-repeat": {
159
+ const parsedValue = value.parse(part);
160
+ if (parsedValue) {
161
+ bgRepeat.push(parsedValue);
162
+ }
163
+ break;
164
+ }
165
+ case "background-size": {
166
+ const parsedValue = value.parse(part);
167
+ if (parsedValue) {
168
+ bgSize.push(parsedValue);
169
+ }
170
+ break;
171
+ }
172
+ default: {
173
+ const parsedValue = value.parse(part);
174
+ if (parsedValue) {
175
+ bg[property] = parsedValue;
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ if (!partValid) {
182
+ return;
183
+ }
184
+ }
185
+ }
186
+ if (bgPosition.length) {
187
+ const { parse: parser } = module.exports.shorthandFor.get("background-position");
188
+ const value = parser(bgPosition.join(" "));
189
+ if (value) {
190
+ bg["background-position"] = value;
191
+ }
192
+ }
193
+ if (bgSize.length) {
194
+ const { parse: parser } = module.exports.shorthandFor.get("background-size");
195
+ const value = parser(bgSize.join(" "));
196
+ if (value) {
197
+ bg["background-size"] = value;
198
+ }
199
+ }
200
+ if (bgRepeat.length) {
201
+ const { parse: parser } = module.exports.shorthandFor.get("background-repeat");
202
+ const value = parser(bgRepeat.join(" "));
203
+ if (value) {
204
+ bg["background-repeat"] = value;
205
+ }
206
+ }
207
+ if (bgBox.length) {
208
+ switch (bgBox.length) {
209
+ case 1: {
210
+ const [value] = bgBox;
211
+ bg["background-origin"] = value;
212
+ bg["background-clip"] = value;
213
+ break;
214
+ }
215
+ case 2: {
216
+ const [value1, value2] = bgBox;
217
+ bg["background-origin"] = value1;
218
+ bg["background-clip"] = value2;
219
+ break;
220
+ }
221
+ default: {
222
+ return;
223
+ }
224
+ }
225
+ }
226
+ bgValues.push(bg);
227
+ }
228
+ return bgValues;
229
+ };
230
+
22
231
  module.exports.definition = {
23
232
  set(v) {
24
233
  v = parsers.prepareValue(v, this._global);
25
- if (/^none$/i.test(v)) {
26
- for (const [key] of shorthandFor) {
27
- this._setProperty(key, "");
28
- }
29
- this._setProperty("background", strings.asciiLowercase(v));
30
- } else if (parsers.hasVarFunc(v)) {
31
- for (const [key] of shorthandFor) {
234
+ if (v === "" || parsers.hasVarFunc(v)) {
235
+ for (const [key] of module.exports.shorthandFor) {
32
236
  this._setProperty(key, "");
33
237
  }
34
238
  this._setProperty("background", v);
35
239
  } else {
36
- this._shorthandSetter("background", v, shorthandFor);
240
+ const bgValues = module.exports.parse(v);
241
+ if (!Array.isArray(bgValues)) {
242
+ return;
243
+ }
244
+ const bgMap = new Map([
245
+ ["background-image", []],
246
+ ["background-position", []],
247
+ ["background-size", []],
248
+ ["background-repeat", []],
249
+ ["background-origin", []],
250
+ ["background-clip", []],
251
+ ["background-attachment", []],
252
+ ["background-color", []]
253
+ ]);
254
+ const backgrounds = [];
255
+ for (const bgValue of bgValues) {
256
+ const bg = [];
257
+ for (const [property, value] of Object.entries(bgValue)) {
258
+ if (value) {
259
+ const arr = bgMap.get(property);
260
+ arr.push(value);
261
+ bgMap.set(property, arr);
262
+ if (value !== initialValues.get(property)) {
263
+ if (property === "background-size") {
264
+ bg.push(`/ ${value}`);
265
+ } else {
266
+ bg.push(value);
267
+ }
268
+ } else if (property === "background-image") {
269
+ if (v === "none") {
270
+ bg.push(value);
271
+ }
272
+ } else if (property === "background-color") {
273
+ if (v === "transparent") {
274
+ bg.push(value);
275
+ }
276
+ }
277
+ }
278
+ }
279
+ backgrounds.push(bg.join(" "));
280
+ }
281
+ for (const [property, value] of bgMap) {
282
+ this._setProperty(property, value.join(", "));
283
+ }
284
+ this._setProperty("background", backgrounds.join(", "));
37
285
  }
38
286
  },
39
287
  get() {
40
- let val = this.getPropertyValue("background");
41
- if (parsers.hasVarFunc(val)) {
42
- return val;
288
+ const v = this.getPropertyValue("background");
289
+ if (parsers.hasVarFunc(v)) {
290
+ return v;
43
291
  }
44
- val = this._shorthandGetter("background", shorthandFor);
45
- if (parsers.hasVarFunc(val)) {
292
+ const bgMap = new Map();
293
+ let l = 0;
294
+ for (const [property] of module.exports.shorthandFor) {
295
+ const val = this.getPropertyValue(property);
296
+ if (property === "background-image") {
297
+ if (
298
+ val === "none" &&
299
+ v === "none" &&
300
+ this.getPropertyValue("background-color") === "transparent"
301
+ ) {
302
+ return val;
303
+ }
304
+ if (val !== initialValues.get(property)) {
305
+ const imgValues = parsers.splitValue(val, {
306
+ delimiter: ","
307
+ });
308
+ l = imgValues.length;
309
+ bgMap.set(property, imgValues);
310
+ }
311
+ } else if (property === "background-color") {
312
+ if (val !== initialValues.get(property) || v.includes(val)) {
313
+ bgMap.set(property, [val]);
314
+ }
315
+ } else if (val !== initialValues.get(property)) {
316
+ bgMap.set(
317
+ property,
318
+ parsers.splitValue(val, {
319
+ delimiter: ","
320
+ })
321
+ );
322
+ }
323
+ }
324
+ if (l === 0) {
325
+ const [background] = bgMap.get("background-color");
326
+ if (background) {
327
+ return background;
328
+ }
46
329
  return "";
47
330
  }
48
- return val;
331
+ const bgValues = [];
332
+ for (let i = 0; i < l; i++) {
333
+ bgValues[i] = [];
334
+ }
335
+ for (const [property, values] of bgMap) {
336
+ for (let i = 0; i < l; i++) {
337
+ switch (property) {
338
+ case "background-color": {
339
+ if (i === l - 1) {
340
+ const value = values[0];
341
+ if (parsers.hasVarFunc(value)) {
342
+ return "";
343
+ }
344
+ if (value && value !== initialValues.get(property)) {
345
+ const bgValue = bgValues[i];
346
+ bgValue.push(value);
347
+ }
348
+ }
349
+ break;
350
+ }
351
+ case "background-size": {
352
+ const value = values[i];
353
+ if (parsers.hasVarFunc(value)) {
354
+ return "";
355
+ }
356
+ if (value && value !== initialValues.get(property)) {
357
+ const bgValue = bgValues[i];
358
+ bgValue.push(`/ ${value}`);
359
+ }
360
+ break;
361
+ }
362
+ default: {
363
+ const value = values[i];
364
+ if (parsers.hasVarFunc(value)) {
365
+ return "";
366
+ }
367
+ if (value && value !== initialValues.get(property)) {
368
+ const bgValue = bgValues[i];
369
+ bgValue.push(value);
370
+ }
371
+ }
372
+ }
373
+ }
374
+ }
375
+ const backgrounds = [];
376
+ for (const bgValue of bgValues) {
377
+ backgrounds.push(bgValue.join(" "));
378
+ }
379
+ return backgrounds.join(", ");
49
380
  },
50
381
  enumerable: true,
51
382
  configurable: true
@@ -3,8 +3,25 @@
3
3
  const parsers = require("../parsers");
4
4
 
5
5
  module.exports.parse = function parse(v) {
6
+ if (v === "") {
7
+ return v;
8
+ }
9
+ const values = parsers.splitValue(v, {
10
+ delimiter: ","
11
+ });
6
12
  const keywords = ["fixed", "scroll", "local"];
7
- return parsers.parseKeyword(v, keywords);
13
+ const parsedValues = [];
14
+ for (const value of values) {
15
+ const parsedValue = parsers.parseKeyword(value, keywords);
16
+ if (parsedValue) {
17
+ parsedValues.push(parsedValue);
18
+ } else {
19
+ return;
20
+ }
21
+ }
22
+ if (parsedValues.length) {
23
+ return parsedValues.join(", ");
24
+ }
8
25
  };
9
26
 
10
27
  module.exports.isValid = function isValid(v) {
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ const parsers = require("../parsers");
4
+
5
+ module.exports.parse = function parse(v) {
6
+ if (v === "") {
7
+ return v;
8
+ }
9
+ const values = parsers.splitValue(v, {
10
+ delimiter: ","
11
+ });
12
+ const keywords = ["border-box", "padding-box", "content-box"];
13
+ const parsedValues = [];
14
+ for (const value of values) {
15
+ const parsedValue = parsers.parseKeyword(value, keywords);
16
+ if (parsedValue) {
17
+ parsedValues.push(parsedValue);
18
+ } else {
19
+ return;
20
+ }
21
+ }
22
+ if (parsedValues.length) {
23
+ return parsedValues.join(", ");
24
+ }
25
+ };
26
+
27
+ module.exports.isValid = function isValid(v) {
28
+ if (v === "") {
29
+ return true;
30
+ }
31
+ return typeof module.exports.parse(v) === "string";
32
+ };
33
+
34
+ module.exports.definition = {
35
+ set(v) {
36
+ v = parsers.prepareValue(v, this._global);
37
+ if (parsers.hasVarFunc(v)) {
38
+ this._setProperty("background", "");
39
+ this._setProperty("background-clip", v);
40
+ } else {
41
+ this._setProperty("background-clip", module.exports.parse(v));
42
+ }
43
+ },
44
+ get() {
45
+ return this.getPropertyValue("background-clip");
46
+ },
47
+ enumerable: true,
48
+ configurable: true
49
+ };
@@ -3,11 +3,28 @@
3
3
  const parsers = require("../parsers");
4
4
 
5
5
  module.exports.parse = function parse(v) {
6
- return parsers.parseImage(v);
6
+ if (v === "") {
7
+ return v;
8
+ }
9
+ const values = parsers.splitValue(v, {
10
+ delimiter: ","
11
+ });
12
+ const parsedValues = [];
13
+ for (const value of values) {
14
+ const parsedValue = parsers.parseImage(value);
15
+ if (parsedValue) {
16
+ parsedValues.push(parsedValue);
17
+ } else {
18
+ return;
19
+ }
20
+ }
21
+ if (parsedValues.length) {
22
+ return parsedValues.join(", ");
23
+ }
7
24
  };
8
25
 
9
26
  module.exports.isValid = function isValid(v) {
10
- if (v === "" || typeof parsers.parseKeyword(v, ["none"]) === "string") {
27
+ if (v === "") {
11
28
  return true;
12
29
  }
13
30
  return typeof module.exports.parse(v) === "string";
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ const parsers = require("../parsers");
4
+
5
+ module.exports.parse = function parse(v) {
6
+ if (v === "") {
7
+ return v;
8
+ }
9
+ const values = parsers.splitValue(v, {
10
+ delimiter: ","
11
+ });
12
+ const keywords = ["border-box", "padding-box", "content-box"];
13
+ const parsedValues = [];
14
+ for (const value of values) {
15
+ const parsedValue = parsers.parseKeyword(value, keywords);
16
+ if (parsedValue) {
17
+ parsedValues.push(parsedValue);
18
+ } else {
19
+ return;
20
+ }
21
+ }
22
+ if (parsedValues.length) {
23
+ return parsedValues.join(", ");
24
+ }
25
+ };
26
+
27
+ module.exports.isValid = function isValid(v) {
28
+ if (v === "") {
29
+ return true;
30
+ }
31
+ return typeof module.exports.parse(v) === "string";
32
+ };
33
+
34
+ module.exports.definition = {
35
+ set(v) {
36
+ v = parsers.prepareValue(v, this._global);
37
+ if (parsers.hasVarFunc(v)) {
38
+ this._setProperty("background", "");
39
+ this._setProperty("background-origin", v);
40
+ } else {
41
+ this._setProperty("background-origin", module.exports.parse(v));
42
+ }
43
+ },
44
+ get() {
45
+ return this.getPropertyValue("background-origin");
46
+ },
47
+ enumerable: true,
48
+ configurable: true
49
+ };