Skip to content

Commit 29d3a59

Browse files
committed
Fix borders
1 parent a766882 commit 29d3a59

23 files changed

+1150
-222
lines changed

lib/CSSStyleDeclaration.js

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class CSSStyleDeclaration {
124124
}
125125
}
126126

127+
// FIXME:
127128
get cssText() {
128129
if (this._computed) {
129130
return "";
@@ -136,15 +137,17 @@ class CSSStyleDeclaration {
136137
if (priority === "important") {
137138
properties.set(property, `${property}: ${value} !${priority};`);
138139
} else {
139-
if (shorthandProperties.has(property)) {
140-
const longhandProperties = shorthandProperties.get(property);
141-
for (const [longhand] of longhandProperties) {
142-
if (properties.has(longhand) && !this.getPropertyPriority(longhand)) {
143-
properties.delete(longhand);
144-
}
140+
properties.set(property, `${property}: ${value};`);
141+
}
142+
}
143+
for (const [property] of properties) {
144+
if (shorthandProperties.has(property)) {
145+
const longhandProperties = shorthandProperties.get(property);
146+
for (const [longhand] of longhandProperties) {
147+
if (properties.has(longhand) && !this.getPropertyPriority(longhand)) {
148+
properties.delete(longhand);
145149
}
146150
}
147-
properties.set(property, `${property}: ${value};`);
148151
}
149152
}
150153
return [...properties.values()].join(" ");
@@ -491,28 +494,6 @@ Object.defineProperties(CSSStyleDeclaration.prototype, {
491494
enumerable: false
492495
},
493496

494-
// Companion to shorthandSetter, but for the individual parts which takes
495-
// position value in the middle.
496-
_midShorthandSetter: {
497-
/**
498-
* @param {string} property
499-
* @param {string} val
500-
* @param {object} shorthandFor
501-
* @param {Array.<string>} positions
502-
*/
503-
value(property, val, shorthandFor, positions = []) {
504-
const obj = this._shorthandSetter(property, val, shorthandFor);
505-
if (!obj) {
506-
return;
507-
}
508-
for (const position of positions) {
509-
this.removeProperty(`${property}-${position}`);
510-
this._values.set(`${property}-${position}`, val);
511-
}
512-
},
513-
enumerable: false
514-
},
515-
516497
_implicitSetter: {
517498
/**
518499
* @param {string} prefix

lib/parsers.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,9 @@ exports.parseColor = function parseColor(val) {
607607
break;
608608
}
609609
case "Identifier": {
610+
if (SYS_COLOR.includes(name)) {
611+
return name;
612+
}
610613
const res = resolveColor(name, {
611614
format: "specifiedValue"
612615
});
@@ -740,6 +743,14 @@ exports.parsePropertyValue = function parsePropertyValue(prop, val, opt = {}) {
740743
return lowerCasedValue;
741744
} else if (SYS_COLOR.includes(lowerCasedValue)) {
742745
if (/^(?:-webkit-)?(?:[a-z][a-z\d]*-)*color$/i.test(prop)) {
746+
if (inArray) {
747+
return [
748+
{
749+
type: "Identifier",
750+
name: lowerCasedValue
751+
}
752+
];
753+
}
743754
return lowerCasedValue;
744755
}
745756
return;

lib/properties/border.js

Lines changed: 164 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,189 @@ const parsers = require("../parsers");
44
const borderWidth = require("./borderWidth");
55
const borderStyle = require("./borderStyle");
66
const borderColor = require("./borderColor");
7+
const borderTop = require("./borderTop");
8+
const borderRight = require("./borderRight");
9+
const borderBottom = require("./borderBottom");
10+
const borderLeft = require("./borderLeft");
11+
12+
const initialValues = new Map([
13+
["border-width", "medium"],
14+
["border-style", "none"],
15+
["border-color", "currentcolor"]
16+
]);
17+
18+
const positionShorthandFor = new Map([
19+
["border-top", borderTop],
20+
["border-right", borderRight],
21+
["border-bottom", borderBottom],
22+
["border-left", borderLeft]
23+
]);
724

825
module.exports.shorthandFor = new Map([
926
["border-width", borderWidth],
1027
["border-style", borderStyle],
1128
["border-color", borderColor]
1229
]);
1330

31+
module.exports.parse = function parse(v, opt = {}) {
32+
const { globalObject } = opt;
33+
if (v === "") {
34+
return v;
35+
}
36+
const values = parsers.splitValue(v);
37+
const parsedValues = new Map();
38+
for (const val of values) {
39+
const value = parsers.parsePropertyValue("border", val, {
40+
globalObject,
41+
inArray: true
42+
});
43+
if (Array.isArray(value) && value.length === 1) {
44+
const [{ isNumber, name, type, value: itemValue }] = value;
45+
switch (type) {
46+
case "Calc": {
47+
if (isNumber || parsedValues.has("border-width")) {
48+
return;
49+
}
50+
parsedValues.set("border-width", `${name}(${itemValue})`);
51+
break;
52+
}
53+
case "Dimension":
54+
case "Number": {
55+
if (parsedValues.has("border-width")) {
56+
return;
57+
}
58+
const parsedValue = parsers.parseLength(value, {
59+
min: 0
60+
});
61+
if (!parsedValue) {
62+
return;
63+
}
64+
parsedValues.set("border-width", parsedValue);
65+
break;
66+
}
67+
case "Function": {
68+
if (parsedValues.has("border-color")) {
69+
return;
70+
}
71+
const parsedValue = parsers.parseColor(value);
72+
if (!parsedValue) {
73+
return;
74+
}
75+
parsedValues.set("border-color", parsedValue);
76+
break;
77+
}
78+
case "GlobalKeyword": {
79+
if (values.length !== 1) {
80+
return;
81+
}
82+
for (const key of module.exports.shorthandFor.keys()) {
83+
parsedValues.set(key, name);
84+
}
85+
break;
86+
}
87+
case "Hash": {
88+
if (parsedValues.has("border-color")) {
89+
return;
90+
}
91+
const parsedValue = parsers.parseColor(`#${itemValue}`);
92+
if (!parsedValue) {
93+
return;
94+
}
95+
parsedValues.set("border-color", parsedValue);
96+
break;
97+
}
98+
case "Identifier": {
99+
if (parsers.isValidPropertyValue("border-width", name)) {
100+
if (parsedValues.has("border-width")) {
101+
return;
102+
}
103+
parsedValues.set("border-width", name);
104+
break;
105+
} else if (parsers.isValidPropertyValue("border-style", name)) {
106+
if (parsedValues.has("border-style")) {
107+
return;
108+
}
109+
parsedValues.set("border-style", name);
110+
break;
111+
} else if (parsers.isValidPropertyValue("border-color", name)) {
112+
if (parsedValues.has("border-color")) {
113+
return;
114+
}
115+
parsedValues.set("border-color", name);
116+
break;
117+
}
118+
return;
119+
}
120+
default: {
121+
return;
122+
}
123+
}
124+
} else {
125+
return;
126+
}
127+
}
128+
if (parsedValues.size) {
129+
const keys = module.exports.shorthandFor.keys();
130+
const obj = {};
131+
for (const key of keys) {
132+
if (parsedValues.has(key)) {
133+
obj[key] = parsedValues.get(key);
134+
}
135+
}
136+
return obj;
137+
}
138+
};
139+
14140
module.exports.definition = {
15141
set(v) {
16142
v = parsers.prepareValue(v, this._global);
17-
if (/^none$/i.test(v)) {
18-
v = "";
19-
}
20143
if (parsers.hasVarFunc(v)) {
21144
for (const [key] of module.exports.shorthandFor) {
22145
this._setProperty(key, "");
23146
}
147+
for (const [key, parser] of positionShorthandFor) {
148+
this._setProperty(key, "");
149+
for (const [subkey] of parser.shorthandFor) {
150+
this._setProperty(subkey, "");
151+
}
152+
}
24153
this._setProperty("border", v);
154+
this._setProperty("border-image", "none");
25155
} else {
26-
this._midShorthandSetter("border", v, module.exports.shorthandFor, [
27-
"top",
28-
"right",
29-
"bottom",
30-
"left"
31-
]);
156+
const obj = module.exports.parse(v, {
157+
globalObject: this._global
158+
});
159+
if (obj === "") {
160+
for (const [key] of module.exports.shorthandFor) {
161+
this._setProperty(key, "");
162+
}
163+
for (const [key, parser] of positionShorthandFor) {
164+
this._setProperty(key, "");
165+
for (const [subkey] of parser.shorthandFor) {
166+
this._setProperty(subkey, "");
167+
}
168+
}
169+
this._setProperty("border", "");
170+
this._setProperty("border-image", "");
171+
} else if (obj) {
172+
const valueObj = Object.fromEntries(initialValues);
173+
for (const key of Object.keys(obj)) {
174+
valueObj[key] = obj[key];
175+
}
176+
const positions = ["top", "right", "bottom", "left"];
177+
for (const [key, value] of Object.entries(valueObj)) {
178+
this._setProperty(key, value);
179+
const [prefix, suffix] = key.split("-");
180+
const { parse: parser } = module.exports.shorthandFor.get(key);
181+
this._implicitSetter(prefix, suffix, value, parser, positions);
182+
}
183+
this._setProperty("border", [...Object.values(obj)].join(" "));
184+
this._setProperty("border-image", "none");
185+
}
32186
}
33187
},
34188
get() {
35-
let val = this.getPropertyValue("border");
36-
if (parsers.hasVarFunc(val)) {
37-
return val;
38-
}
39-
val = this._shorthandGetter("border", module.exports.shorthandFor);
40-
if (parsers.hasVarFunc(val)) {
41-
return "";
42-
}
43-
return val;
189+
return this.getPropertyValue("border");
44190
},
45191
enumerable: true,
46192
configurable: true

0 commit comments

Comments
 (0)