Skip to content

Commit

Permalink
feat: supported supports() and layer() in @import at-rule
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Sep 15, 2021
1 parent 28ab0aa commit 31abc62
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 3,110 deletions.
69 changes: 57 additions & 12 deletions src/plugins/postcss-import-parser.js
Expand Up @@ -112,15 +112,40 @@ function parseNode(atRule, key) {
throw error;
}

const mediaNodes = paramsNodes.slice(1);
const additionalNodes = paramsNodes.slice(1);

let supports;
let layer;
let media;

if (mediaNodes.length > 0) {
media = valueParser.stringify(mediaNodes).trim().toLowerCase();
if (additionalNodes.length > 0) {
let nodes = [];

for (const node of additionalNodes) {
nodes.push(node);

if (
(node.type === "function" && node.value.toLowerCase() === "layer") ||
(node.type === "word" && node.value.toLowerCase() === "layer")
) {
layer = valueParser.stringify(nodes).trim().toLowerCase();
nodes = [];
} else if (
node.type === "function" &&
node.value.toLowerCase() === "supports"
) {
supports = valueParser.stringify(nodes).trim().toLowerCase();
nodes = [];
}
}

if (nodes.length > 0) {
media = valueParser.stringify(nodes).trim().toLowerCase();
}
}

// eslint-disable-next-line consistent-return
return { atRule, prefix, url, media, isRequestable };
return { atRule, prefix, url, layer, supports, media, isRequestable };
}

const plugin = (options = {}) => {
Expand Down Expand Up @@ -154,11 +179,23 @@ const plugin = (options = {}) => {

const resolvedAtRules = await Promise.all(
parsedAtRules.map(async (parsedAtRule) => {
const { atRule, isRequestable, prefix, url, media } =
parsedAtRule;
const {
atRule,
isRequestable,
prefix,
url,
layer,
supports,
media,
} = parsedAtRule;

if (options.filter) {
const needKeep = await options.filter(url, media);
const needKeep = await options.filter(
url,
media,
layer,
supports
);

if (!needKeep) {
return;
Expand Down Expand Up @@ -186,13 +223,20 @@ const plugin = (options = {}) => {
atRule.remove();

// eslint-disable-next-line consistent-return
return { url: resolvedUrl, media, prefix, isRequestable };
return {
url: resolvedUrl,
layer,
supports,
media,
prefix,
isRequestable,
};
}

atRule.remove();

// eslint-disable-next-line consistent-return
return { url, media, prefix, isRequestable };
return { url, layer, supports, media, prefix, isRequestable };
})
);

Expand All @@ -206,10 +250,11 @@ const plugin = (options = {}) => {
continue;
}

const { url, isRequestable, media } = resolvedAtRule;
const { url, isRequestable, layer, supports, media } =
resolvedAtRule;

if (!isRequestable) {
options.api.push({ url, media, index });
options.api.push({ url, layer, supports, media, index });

// eslint-disable-next-line no-continue
continue;
Expand All @@ -231,7 +276,7 @@ const plugin = (options = {}) => {
});
}

options.api.push({ importName, media, index });
options.api.push({ importName, layer, supports, media, index });
}
},
};
Expand Down
50 changes: 44 additions & 6 deletions src/runtime/api.js
Expand Up @@ -10,10 +10,32 @@ module.exports = function (cssWithMappingToString) {
// return the list of modules as css string
list.toString = function toString() {
return this.map((item) => {
const content = cssWithMappingToString(item);
let content = "";

if (item[4]) {
content += `@${item[4]} {`;
}

if (item[3]) {
content += `@${item[3]} {`;
}

if (item[2]) {
content += `@media ${item[2]} {`;
}

content += cssWithMappingToString(item);

if (item[2]) {
return `@media ${item[2]} {${content}}`;
content += "}";
}

if (item[3]) {
content += "}";
}

if (item[4]) {
content += "}";
}

return content;
Expand All @@ -22,7 +44,7 @@ module.exports = function (cssWithMappingToString) {

// import a list of modules into the list
// eslint-disable-next-line func-names
list.i = function (modules, mediaQuery, dedupe) {
list.i = function (modules, mediaQueryList, dedupe, layer, supports) {
if (typeof modules === "string") {
// eslint-disable-next-line no-param-reassign
modules = [[null, modules, ""]];
Expand All @@ -49,11 +71,27 @@ module.exports = function (cssWithMappingToString) {
continue;
}

if (mediaQuery) {
if (mediaQueryList) {
if (!item[2]) {
item[2] = mediaQuery;
item[2] = mediaQueryList;
} else {
item[2] = `${mediaQueryList} and ${item[2]}`;
}
}

if (layer) {
if (!item[3]) {
item[3] = layer;
} else {
item[3] = `${layer} and ${item[3]}`;
}
}

if (supports) {
if (!item[4]) {
item[4] = supports;
} else {
item[2] = `${mediaQuery} and ${item[2]}`;
item[4] = `${supports} and ${item[4]}`;
}
}

Expand Down
51 changes: 42 additions & 9 deletions src/utils.js
Expand Up @@ -921,6 +921,32 @@ function normalizeSourceMapForRuntime(map, loaderContext) {
return JSON.stringify(resultMap);
}

function printParams(media, dedupe, supports, layer) {
let result = "";

if (layer) {
result = `, ${JSON.stringify(layer)}`;
}

if (supports) {
result = `, ${JSON.stringify(supports)}${result}`;
}

if (dedupe) {
result = `, true${result}`;
} else if (result.length > 0) {
result = `, false${result}`;
}

if (media) {
result = `${JSON.stringify(media)}${result}`;
} else if (result.length > 0) {
result = `""${result}`;
}

return result;
}

function getModuleCode(result, api, replacements, options, loaderContext) {
if (options.modules.exportOnlyLocals === true) {
return "";
Expand All @@ -939,15 +965,22 @@ function getModuleCode(result, api, replacements, options, loaderContext) {
});\n`;

for (const item of api) {
const { url, media, dedupe } = item;

beforeCode += url
? `___CSS_LOADER_EXPORT___.push([module.id, ${JSON.stringify(
`@import url(${url});`
)}${media ? `, ${JSON.stringify(media)}` : ""}]);\n`
: `___CSS_LOADER_EXPORT___.i(${item.importName}${
media ? `, ${JSON.stringify(media)}` : dedupe ? ', ""' : ""
}${dedupe ? ", true" : ""});\n`;
const { url, layer, supports, media, dedupe } = item;

if (url) {
// eslint-disable-next-line no-undefined
const printedParam = printParams(media, undefined, supports, layer);

beforeCode += `___CSS_LOADER_EXPORT___.push([module.id, ${JSON.stringify(
`@import url(${url});`
)}${printedParam.length > 0 ? `, ${printedParam}` : ""}]);\n`;
} else {
const printedParam = printParams(media, dedupe, supports, layer);

beforeCode += `___CSS_LOADER_EXPORT___.i(${item.importName}${
printedParam.length > 0 ? `, ${printedParam}` : ""
});\n`;
}
}

for (const item of replacements) {
Expand Down

0 comments on commit 31abc62

Please sign in to comment.