Skip to content

Commit 0630908

Browse files
committed
Fix flexbox handling and some clean ups
1 parent 304e555 commit 0630908

38 files changed

+244
-367
lines changed

lib/CSSStyleDeclaration.js

Lines changed: 94 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ const {
1717
} = require("./normalize");
1818
const {
1919
hasVarFunc,
20-
isValidPropertyValue,
20+
isGlobalKeyword,
2121
parseCSS,
2222
parsePropertyValue,
23-
parseShorthand,
2423
prepareValue
2524
} = require("./parsers");
2625
const allExtraProperties = require("./utils/allExtraProperties");
@@ -365,50 +364,6 @@ class CSSStyleDeclaration {
365364

366365
// Internal methods
367366
Object.defineProperties(CSSStyleDeclaration.prototype, {
368-
_shorthandGetter: {
369-
/**
370-
* @param {string} property
371-
* @param {object} shorthandFor
372-
* @param {Map} initialValues
373-
*/
374-
value(property, shorthandFor, initialValues = new Map()) {
375-
const obj = {};
376-
const filter = initialValues.size > 0;
377-
const firstKey = filter && initialValues.keys().next().value;
378-
for (const key of shorthandFor.keys()) {
379-
const val = this.getPropertyValue(key);
380-
if (val === "" || hasVarFunc(val)) {
381-
return "";
382-
}
383-
if (filter) {
384-
const initialValue = initialValues.get(key);
385-
if (key === firstKey) {
386-
obj[key] = val;
387-
} else if (val !== initialValue) {
388-
obj[key] = val;
389-
if (obj[firstKey] && obj[firstKey] === initialValues.get(firstKey)) {
390-
delete obj[firstKey];
391-
}
392-
}
393-
} else {
394-
obj[key] = val;
395-
}
396-
}
397-
if (Object.values(obj).length) {
398-
const value = Object.values(obj).join(" ");
399-
if (isValidPropertyValue(property, value)) {
400-
return value;
401-
}
402-
return "";
403-
}
404-
if (this._values.has(property)) {
405-
return this.getPropertyValue(property);
406-
}
407-
return "";
408-
},
409-
enumerable: false
410-
},
411-
412367
_setProperty: {
413368
/**
414369
* @param {string} property
@@ -456,60 +411,111 @@ Object.defineProperties(CSSStyleDeclaration.prototype, {
456411
enumerable: false
457412
},
458413

459-
// TODO: Check later if this is really the right way to do.
460-
_shorthandSetter: {
414+
_borderSetter: {
461415
/**
462-
* @param {string} property
463-
* @param {string} val
416+
* @param {string} prop
417+
* @param {object|Array|string} val
464418
* @param {string} prior
465-
* @param {object} shorthandFor
466419
*/
467-
value(property, val, prior, shorthandFor) {
468-
const obj = parseShorthand(val, shorthandFor, {
420+
value(prop, val, prior) {
421+
const properties = new Map();
422+
if (prop === "border") {
423+
let priority = "";
424+
if (typeof prior === "string") {
425+
priority = prior;
426+
} else {
427+
priority = this._priorities.get(prop) ?? "";
428+
}
429+
properties.set(prop, { propery: prop, value: val, priority });
430+
} else {
431+
for (let i = 0; i < this._length; i++) {
432+
const property = this[i];
433+
if (borderProperties.has(property)) {
434+
const value = this.getPropertyValue(property);
435+
const longhandPriority = this._priorities.get(property) ?? "";
436+
let priority = longhandPriority;
437+
if (prop === property && typeof prior === "string") {
438+
priority = prior;
439+
}
440+
properties.set(property, { property, value, priority });
441+
}
442+
}
443+
}
444+
const parsedProperties = prepareBorderProperties(prop, val, prior, properties, {
469445
globalObject: this._global
470446
});
471-
if (!obj) {
447+
for (const [property, item] of parsedProperties) {
448+
const { priority, value } = item;
449+
this._setProperty(property, value, priority);
450+
}
451+
},
452+
enumerable: false
453+
},
454+
455+
_flexBoxSetter: {
456+
/**
457+
* @param {string} prop
458+
* @param {string} val
459+
* @param {string} prior
460+
* @param {string} shorthandProperty
461+
*/
462+
value(prop, val, prior, shorthandProperty) {
463+
if (!shorthandProperty || !shorthandProperties.has(shorthandProperty)) {
472464
return;
473465
}
466+
const shorthandPriority = this._priorities.get(shorthandProperty);
467+
this.removeProperty(shorthandProperty);
474468
let priority = "";
475469
if (typeof prior === "string") {
476470
priority = prior;
477471
} else {
478-
priority = this._priorities.get(property) ?? "";
472+
priority = this._priorities.get(prop) ?? "";
473+
}
474+
this.removeProperty(prop);
475+
if (shorthandPriority && priority) {
476+
this._setProperty(prop, val);
477+
} else {
478+
this._setProperty(prop, val, priority);
479479
}
480-
for (const subprop of Object.keys(obj)) {
481-
// In case subprop is an implicit property, this will clear *its*
482-
// subpropertiesX.
483-
const camel = dashedToCamelCase(subprop);
484-
this[camel] = obj[subprop];
485-
// In case it gets translated into something else (0 -> 0px).
486-
obj[subprop] = this[camel];
487-
this.removeProperty(subprop);
488-
// Don't add in empty properties.
489-
if (obj[subprop] !== "") {
490-
this._values.set(subprop, obj[subprop], priority);
480+
if (val && !hasVarFunc(val)) {
481+
const longhandValues = [];
482+
const shorthandItem = shorthandProperties.get(shorthandProperty);
483+
let hasGlobalKeyword = false;
484+
for (const [longhandProperty] of shorthandItem.shorthandFor) {
485+
if (longhandProperty === prop) {
486+
if (isGlobalKeyword(val)) {
487+
hasGlobalKeyword = true;
488+
}
489+
longhandValues.push(val);
490+
} else {
491+
const longhandValue = this.getPropertyValue(longhandProperty);
492+
const longhandPriority = this._priorities.get(longhandProperty) ?? "";
493+
if (!longhandValue || longhandPriority !== priority) {
494+
break;
495+
}
496+
if (isGlobalKeyword(longhandValue)) {
497+
hasGlobalKeyword = true;
498+
}
499+
longhandValues.push(longhandValue);
500+
}
491501
}
492-
}
493-
for (const [subprop] of shorthandFor) {
494-
if (!Object.hasOwn(obj, subprop)) {
495-
this.removeProperty(subprop);
496-
this._values.delete(subprop);
502+
if (longhandValues.length === shorthandItem.shorthandFor.size) {
503+
if (hasGlobalKeyword) {
504+
const [firstValue, ...restValues] = longhandValues;
505+
if (restValues.every((value) => value === firstValue)) {
506+
this._setProperty(shorthandProperty, firstValue, priority);
507+
}
508+
} else {
509+
const parsedValue = shorthandItem.parse(longhandValues.join(" "));
510+
const shorthandValue = Object.values(parsedValue).join(" ");
511+
this._setProperty(shorthandProperty, shorthandValue, priority);
512+
}
497513
}
498514
}
499-
// In case the value is something like 'none' that removes all values,
500-
// check that the generated one is not empty, first remove the property,
501-
// if it already exists, then call the shorthandGetter, if it's an empty
502-
// string, don't set the property.
503-
this.removeProperty(property);
504-
const calculated = this._shorthandGetter(property, shorthandFor);
505-
if (calculated !== "") {
506-
this._setProperty(property, calculated, priority);
507-
}
508-
},
509-
enumerable: false
515+
}
510516
},
511517

512-
_implicitShorthandSetter: {
518+
_positionShorthandSetter: {
513519
/**
514520
* @param {string} prop
515521
* @param {Array|string} val
@@ -558,25 +564,26 @@ Object.defineProperties(CSSStyleDeclaration.prototype, {
558564
}
559565
},
560566

561-
_implicitLonghandSetter: {
567+
_positionLonghandSetter: {
562568
/**
563569
* @param {string} prop
564570
* @param {string} val
565571
* @param {string} prior
572+
* @param {string} shorthandProperty
566573
*/
567-
value(prop, val, prior) {
568-
const { logicalPropertyGroup: shorthandProperty } = implementedProperties.get(prop) ?? {};
574+
value(prop, val, prior, shorthandProperty) {
569575
if (!shorthandProperty || !shorthandProperties.has(shorthandProperty)) {
570576
return;
571577
}
572578
const shorthandPriority = this._priorities.get(shorthandProperty);
573-
this._setProperty(shorthandProperty, "");
579+
this.removeProperty(shorthandProperty);
574580
let priority = "";
575581
if (typeof prior === "string") {
576582
priority = prior;
577583
} else {
578584
priority = this._priorities.get(prop) ?? "";
579585
}
586+
this.removeProperty(prop);
580587
if (shorthandPriority && priority) {
581588
this._setProperty(prop, val);
582589
} else {
@@ -600,47 +607,6 @@ Object.defineProperties(CSSStyleDeclaration.prototype, {
600607
}
601608
}
602609
}
603-
},
604-
605-
_implicitBorderSetter: {
606-
/**
607-
* @param {string} prop
608-
* @param {object|Array|string} val
609-
* @param {string} prior
610-
*/
611-
value(prop, val, prior) {
612-
const properties = new Map();
613-
if (prop === "border") {
614-
let priority = "";
615-
if (typeof prior === "string") {
616-
priority = prior;
617-
} else {
618-
priority = this._priorities.get(prop) ?? "";
619-
}
620-
properties.set(prop, { propery: prop, value: val, priority });
621-
} else {
622-
for (let i = 0; i < this._length; i++) {
623-
const property = this[i];
624-
if (borderProperties.has(property)) {
625-
const value = this.getPropertyValue(property);
626-
const longhandPriority = this._priorities.get(property) ?? "";
627-
let priority = longhandPriority;
628-
if (prop === property && typeof prior === "string") {
629-
priority = prior;
630-
}
631-
properties.set(property, { property, value, priority });
632-
}
633-
}
634-
}
635-
const parsedProperties = prepareBorderProperties(prop, val, prior, properties, {
636-
globalObject: this._global
637-
});
638-
for (const [property, item] of parsedProperties) {
639-
const { priority, value } = item;
640-
this._setProperty(property, value, priority);
641-
}
642-
},
643-
enumerable: false
644610
}
645611
});
646612

lib/parsers.js

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -196,52 +196,6 @@ exports.resolveCalc = (val, opt = { format: "specifiedValue" }) => {
196196
return values.join(" ");
197197
};
198198

199-
// Parse shorthand properties.
200-
exports.parseShorthand = (val, shorthandFor, opt = {}) => {
201-
const { globalObject, preserve } = opt;
202-
if (typeof val !== "string") {
203-
val = exports.prepareValue(val, globalObject);
204-
}
205-
const obj = {};
206-
if (val === "" || exports.hasVarFunc(val)) {
207-
for (const [property] of shorthandFor) {
208-
obj[property] = "";
209-
}
210-
return obj;
211-
}
212-
const value = asciiLowercase(val);
213-
if (GLOBAL_KEY.includes(value)) {
214-
for (const [property] of shorthandFor) {
215-
obj[property] = value;
216-
}
217-
return obj;
218-
}
219-
const parts = splitValue(value);
220-
const longhands = [...shorthandFor];
221-
for (let part of parts) {
222-
if (exports.hasCalcFunc(part)) {
223-
const partValue = exports.resolveCalc(part);
224-
part = partValue;
225-
}
226-
let partValid = false;
227-
for (let i = 0; i < longhands.length; i++) {
228-
const [property, longhand] = longhands[i];
229-
if (exports.isValidPropertyValue(property, part)) {
230-
partValid = true;
231-
obj[property] = longhand.parse(part, opt);
232-
if (!preserve) {
233-
longhands.splice(i, 1);
234-
break;
235-
}
236-
}
237-
}
238-
if (!partValid) {
239-
return;
240-
}
241-
}
242-
return obj;
243-
};
244-
245199
// Parse property value. Returns string or array of parsed object.
246200
exports.parsePropertyValue = (prop, val, opt = {}) => {
247201
const { caseSensitive, globalObject, inArray } = opt;

lib/properties/border.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,14 @@ module.exports.definition = {
145145
set(v) {
146146
v = parsers.prepareValue(v, this._global);
147147
if (parsers.hasVarFunc(v)) {
148-
this._implicitBorderSetter(property, v, "");
148+
this._borderSetter(property, v, "");
149149
} else {
150150
const val = module.exports.parse(v, {
151151
globalObject: this._global
152152
});
153153
if (val || typeof val === "string") {
154154
const priority = this._priorities.get(property) ?? "";
155-
this._implicitBorderSetter(property, val, priority);
155+
this._borderSetter(property, val, priority);
156156
}
157157
}
158158
},

lib/properties/borderBottom.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ module.exports.definition = {
135135
set(v) {
136136
v = parsers.prepareValue(v, this._global);
137137
if (parsers.hasVarFunc(v)) {
138-
this._implicitBorderSetter(property, v, "");
138+
this._borderSetter(property, v, "");
139139
} else {
140140
const val = module.exports.parse(v, {
141141
globalObject: this._global
@@ -144,7 +144,7 @@ module.exports.definition = {
144144
const shorthandPriority = this._priorities.get(shorthand);
145145
const prior = this._priorities.get(property) ?? "";
146146
const priority = shorthandPriority && prior ? "" : prior;
147-
this._implicitBorderSetter(property, val, priority);
147+
this._borderSetter(property, val, priority);
148148
}
149149
}
150150
},

lib/properties/borderBottomColor.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module.exports.definition = {
3535
set(v) {
3636
v = parsers.prepareValue(v, this._global);
3737
if (parsers.hasVarFunc(v)) {
38-
this._implicitBorderSetter(property, v, "");
38+
this._borderSetter(property, v, "");
3939
} else {
4040
const val = module.exports.parse(v, {
4141
globalObject: this._global
@@ -48,7 +48,7 @@ module.exports.definition = {
4848
if ((shorthandPriority || linePriority || positionPriority) && priority) {
4949
priority = "";
5050
}
51-
this._implicitBorderSetter(property, val, priority);
51+
this._borderSetter(property, val, priority);
5252
}
5353
}
5454
},

0 commit comments

Comments
 (0)