407 lines
13 KiB
JavaScript
407 lines
13 KiB
JavaScript
"use strict";
|
|
|
|
const parsers = require("../parsers");
|
|
const backgroundImage = require("./backgroundImage");
|
|
const backgroundPosition = require("./backgroundPosition");
|
|
const backgroundSize = require("./backgroundSize");
|
|
const backgroundRepeat = require("./backgroundRepeat");
|
|
const backgroundOrigin = require("./backgroundOrigin");
|
|
const backgroundClip = require("./backgroundClip");
|
|
const backgroundAttachment = require("./backgroundAttachment");
|
|
const backgroundColor = require("./backgroundColor");
|
|
|
|
const property = "background";
|
|
|
|
module.exports.initialValues = new Map([
|
|
[backgroundImage.property, "none"],
|
|
[backgroundPosition.property, "0% 0%"],
|
|
[backgroundSize.property, "auto"],
|
|
[backgroundRepeat.property, "repeat"],
|
|
[backgroundOrigin.property, "padding-box"],
|
|
[backgroundClip.property, "border-box"],
|
|
[backgroundAttachment.property, "scroll"],
|
|
[backgroundColor.property, "transparent"]
|
|
]);
|
|
|
|
module.exports.shorthandFor = new Map([
|
|
[backgroundImage.property, backgroundImage],
|
|
[backgroundPosition.property, backgroundPosition],
|
|
[backgroundSize.property, backgroundSize],
|
|
[backgroundRepeat.property, backgroundRepeat],
|
|
[backgroundOrigin.property, backgroundOrigin],
|
|
[backgroundClip.property, backgroundClip],
|
|
[backgroundAttachment.property, backgroundAttachment],
|
|
[backgroundColor.property, backgroundColor]
|
|
]);
|
|
|
|
module.exports.parse = (v, opt = {}) => {
|
|
const { globalObject } = opt;
|
|
if (v === "") {
|
|
return v;
|
|
} else if (parsers.hasCalcFunc(v)) {
|
|
v = parsers.resolveCalc(v);
|
|
}
|
|
if (!parsers.isValidPropertyValue(property, v)) {
|
|
return;
|
|
}
|
|
const values = parsers.splitValue(v, {
|
|
delimiter: ","
|
|
});
|
|
const bgValues = [];
|
|
const l = values.length;
|
|
for (let i = 0; i < l; i++) {
|
|
let bg = {
|
|
[backgroundImage.property]: module.exports.initialValues.get(backgroundImage.property),
|
|
[backgroundPosition.property]: module.exports.initialValues.get(backgroundPosition.property),
|
|
[backgroundSize.property]: module.exports.initialValues.get(backgroundSize.property),
|
|
[backgroundRepeat.property]: module.exports.initialValues.get(backgroundRepeat.property),
|
|
[backgroundOrigin.property]: module.exports.initialValues.get(backgroundOrigin.property),
|
|
[backgroundClip.property]: module.exports.initialValues.get(backgroundClip.property),
|
|
[backgroundAttachment.property]: module.exports.initialValues.get(
|
|
backgroundAttachment.property
|
|
),
|
|
[backgroundColor.property]: module.exports.initialValues.get(backgroundColor.property)
|
|
};
|
|
if (l > 1 && i !== l - 1) {
|
|
bg = {
|
|
[backgroundImage.property]: module.exports.initialValues.get(backgroundImage.property),
|
|
[backgroundPosition.property]: module.exports.initialValues.get(
|
|
backgroundPosition.property
|
|
),
|
|
[backgroundSize.property]: module.exports.initialValues.get(backgroundSize.property),
|
|
[backgroundRepeat.property]: module.exports.initialValues.get(backgroundRepeat.property),
|
|
[backgroundOrigin.property]: module.exports.initialValues.get(backgroundOrigin.property),
|
|
[backgroundClip.property]: module.exports.initialValues.get(backgroundClip.property),
|
|
[backgroundAttachment.property]: module.exports.initialValues.get(
|
|
backgroundAttachment.property
|
|
)
|
|
};
|
|
}
|
|
const bgPosition = [];
|
|
const bgSize = [];
|
|
const bgRepeat = [];
|
|
const bgBox = [];
|
|
const bgParts = parsers.splitValue(values[i], {
|
|
delimiter: "/"
|
|
});
|
|
if (!bgParts.length || bgParts.length > 2) {
|
|
return;
|
|
}
|
|
const [bgPart1, bgPart2 = ""] = bgParts;
|
|
const parts1 = parsers.splitValue(bgPart1);
|
|
for (const part of parts1) {
|
|
let partValid = false;
|
|
for (const [longhand, value] of module.exports.shorthandFor) {
|
|
if (parsers.isValidPropertyValue(longhand, part)) {
|
|
partValid = true;
|
|
switch (longhand) {
|
|
case backgroundClip.property:
|
|
case backgroundOrigin.property: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bgBox.push(parsedValue);
|
|
}
|
|
break;
|
|
}
|
|
case backgroundColor.property: {
|
|
if (i !== values.length - 1) {
|
|
return;
|
|
}
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bg[longhand] = parsedValue;
|
|
}
|
|
break;
|
|
}
|
|
case backgroundPosition.property: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bgPosition.push(parsedValue);
|
|
}
|
|
break;
|
|
}
|
|
case backgroundRepeat.property: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bgRepeat.push(parsedValue);
|
|
}
|
|
break;
|
|
}
|
|
case backgroundSize.property: {
|
|
break;
|
|
}
|
|
default: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bg[longhand] = parsedValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!partValid) {
|
|
return;
|
|
}
|
|
}
|
|
if (bgPart2) {
|
|
const parts2 = parsers.splitValue(bgPart2);
|
|
for (const part of parts2) {
|
|
let partValid = false;
|
|
for (const [longhand, value] of module.exports.shorthandFor) {
|
|
if (parsers.isValidPropertyValue(longhand, part)) {
|
|
partValid = true;
|
|
switch (longhand) {
|
|
case backgroundClip.property:
|
|
case backgroundOrigin.property: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bgBox.push(parsedValue);
|
|
}
|
|
break;
|
|
}
|
|
case backgroundColor.property: {
|
|
if (i !== l - 1) {
|
|
return;
|
|
}
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bg[longhand] = parsedValue;
|
|
}
|
|
break;
|
|
}
|
|
case backgroundPosition.property: {
|
|
break;
|
|
}
|
|
case backgroundRepeat.property: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bgRepeat.push(parsedValue);
|
|
}
|
|
break;
|
|
}
|
|
case backgroundSize.property: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bgSize.push(parsedValue);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
const parsedValue = value.parse(part, { globalObject });
|
|
if (parsedValue) {
|
|
bg[longhand] = parsedValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!partValid) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (bgPosition.length) {
|
|
const { parse: parser } = module.exports.shorthandFor.get(backgroundPosition.property);
|
|
const value = parser(bgPosition.join(" "), { globalObject });
|
|
if (value) {
|
|
bg[backgroundPosition.property] = value;
|
|
}
|
|
}
|
|
if (bgSize.length) {
|
|
const { parse: parser } = module.exports.shorthandFor.get(backgroundSize.property);
|
|
const value = parser(bgSize.join(" "), { globalObject });
|
|
if (value) {
|
|
bg[backgroundSize.property] = value;
|
|
}
|
|
}
|
|
if (bgRepeat.length) {
|
|
const { parse: parser } = module.exports.shorthandFor.get(backgroundRepeat.property);
|
|
const value = parser(bgRepeat.join(" "), { globalObject });
|
|
if (value) {
|
|
bg[backgroundRepeat.property] = value;
|
|
}
|
|
}
|
|
if (bgBox.length) {
|
|
switch (bgBox.length) {
|
|
case 1: {
|
|
const [value] = bgBox;
|
|
bg[backgroundOrigin.property] = value;
|
|
bg[backgroundClip.property] = value;
|
|
break;
|
|
}
|
|
case 2: {
|
|
const [value1, value2] = bgBox;
|
|
bg[backgroundOrigin.property] = value1;
|
|
bg[backgroundClip.property] = value2;
|
|
break;
|
|
}
|
|
default: {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
bgValues.push(bg);
|
|
}
|
|
return bgValues;
|
|
};
|
|
|
|
module.exports.definition = {
|
|
set(v) {
|
|
v = parsers.prepareValue(v);
|
|
if (v === "" || parsers.hasVarFunc(v)) {
|
|
for (const [key] of module.exports.shorthandFor) {
|
|
this._setProperty(key, "");
|
|
}
|
|
this._setProperty(property, v);
|
|
} else {
|
|
const bgValues = module.exports.parse(v, {
|
|
globalObject: this._global
|
|
});
|
|
if (!Array.isArray(bgValues)) {
|
|
return;
|
|
}
|
|
const bgMap = new Map([
|
|
[backgroundImage.property, []],
|
|
[backgroundPosition.property, []],
|
|
[backgroundSize.property, []],
|
|
[backgroundRepeat.property, []],
|
|
[backgroundOrigin.property, []],
|
|
[backgroundClip.property, []],
|
|
[backgroundAttachment.property, []],
|
|
[backgroundColor.property, []]
|
|
]);
|
|
const backgrounds = [];
|
|
for (const bgValue of bgValues) {
|
|
const bg = [];
|
|
for (const [longhand, value] of Object.entries(bgValue)) {
|
|
if (value) {
|
|
const arr = bgMap.get(longhand);
|
|
arr.push(value);
|
|
bgMap.set(longhand, arr);
|
|
if (value !== module.exports.initialValues.get(longhand)) {
|
|
if (longhand === backgroundSize.property) {
|
|
bg.push(`/ ${value}`);
|
|
} else {
|
|
bg.push(value);
|
|
}
|
|
} else if (longhand === backgroundImage.property) {
|
|
if (v === "none") {
|
|
bg.push(value);
|
|
}
|
|
} else if (longhand === backgroundColor.property) {
|
|
if (v === "transparent") {
|
|
bg.push(value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
backgrounds.push(bg.join(" "));
|
|
}
|
|
const priority = this._priorities.get(property) ?? "";
|
|
for (const [longhand, value] of bgMap) {
|
|
this._setProperty(longhand, value.join(", "), priority);
|
|
}
|
|
this._setProperty(property, backgrounds.join(", "), priority);
|
|
}
|
|
},
|
|
get() {
|
|
const v = this.getPropertyValue(property);
|
|
if (parsers.hasVarFunc(v)) {
|
|
return v;
|
|
}
|
|
const bgMap = new Map();
|
|
let l = 0;
|
|
for (const [longhand] of module.exports.shorthandFor) {
|
|
const val = this.getPropertyValue(longhand);
|
|
if (longhand === backgroundImage.property) {
|
|
if (
|
|
val === "none" &&
|
|
v === "none" &&
|
|
this.getPropertyValue(backgroundColor.property) === "transparent"
|
|
) {
|
|
return val;
|
|
}
|
|
if (val !== module.exports.initialValues.get(longhand)) {
|
|
const imgValues = parsers.splitValue(val, {
|
|
delimiter: ","
|
|
});
|
|
l = imgValues.length;
|
|
bgMap.set(longhand, imgValues);
|
|
}
|
|
} else if (longhand === backgroundColor.property) {
|
|
if (val !== module.exports.initialValues.get(longhand) || v.includes(val)) {
|
|
bgMap.set(longhand, [val]);
|
|
}
|
|
} else if (val !== module.exports.initialValues.get(longhand)) {
|
|
bgMap.set(
|
|
longhand,
|
|
parsers.splitValue(val, {
|
|
delimiter: ","
|
|
})
|
|
);
|
|
}
|
|
}
|
|
if (l === 0) {
|
|
const bgColArr = bgMap.get(backgroundColor.property);
|
|
const background = bgColArr ? bgColArr[0] : null;
|
|
if (background) {
|
|
return background;
|
|
}
|
|
return "";
|
|
}
|
|
const bgValues = [];
|
|
for (let i = 0; i < l; i++) {
|
|
bgValues[i] = [];
|
|
}
|
|
for (const [longhand, values] of bgMap) {
|
|
for (let i = 0; i < l; i++) {
|
|
switch (longhand) {
|
|
case backgroundColor.property: {
|
|
if (i === l - 1) {
|
|
const value = values[0];
|
|
if (parsers.hasVarFunc(value)) {
|
|
return "";
|
|
}
|
|
if (value && value !== module.exports.initialValues.get(longhand)) {
|
|
const bgValue = bgValues[i];
|
|
bgValue.push(value);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case backgroundSize.property: {
|
|
const value = values[i];
|
|
if (parsers.hasVarFunc(value)) {
|
|
return "";
|
|
}
|
|
if (value && value !== module.exports.initialValues.get(longhand)) {
|
|
const bgValue = bgValues[i];
|
|
bgValue.push(`/ ${value}`);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
const value = values[i];
|
|
if (parsers.hasVarFunc(value)) {
|
|
return "";
|
|
}
|
|
if (value && value !== module.exports.initialValues.get(longhand)) {
|
|
const bgValue = bgValues[i];
|
|
bgValue.push(value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const backgrounds = [];
|
|
for (const bgValue of bgValues) {
|
|
backgrounds.push(bgValue.join(" "));
|
|
}
|
|
return backgrounds.join(", ");
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
};
|
|
|
|
module.exports.property = property;
|