|
|
@@ -1034,65 +1034,64 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
static async processStylesheet(doc, stylesheetContent, cssRules, baseURI, options, batchRequest) {
|
|
|
- let sheetContent = "", variablesInfo = { index: 0, cssText: "" };
|
|
|
- const urlFunctions = DomUtil.getUrlFunctions(stylesheetContent);
|
|
|
- const resourceInfos = new Map();
|
|
|
- await Promise.all(urlFunctions.map(async urlFunction => {
|
|
|
+ const urlFunctions = getURLFunctions(cssRules);
|
|
|
+ const styleResources = Promise.all(urlFunctions.style.map(urlFunction => processURLFunction(urlFunction, true)));
|
|
|
+ const otherResources = Promise.all(urlFunctions.other.map(urlFunction => processURLFunction(urlFunction, false)));
|
|
|
+ await Promise.all([styleResources, otherResources]);
|
|
|
+ return stylesheetContent;
|
|
|
+
|
|
|
+ async function processURLFunction(urlFunction, groupDuplicates) {
|
|
|
const originalResourceURL = DomUtil.matchURL(urlFunction);
|
|
|
const resourceURL = DomUtil.normalizeURL(originalResourceURL);
|
|
|
if (!DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
- if (DomUtil.testValidURL(resourceURL, baseURI, options.url) && stylesheetContent.includes(urlFunction)) {
|
|
|
+ if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
const { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL);
|
|
|
- urlFunction = "url(" + JSON.stringify(originalResourceURL) + ")";
|
|
|
- const regExpUrlFunction = DomUtil.getRegExp(urlFunction);
|
|
|
- if (duplicate && options.groupDuplicateImages) {
|
|
|
- resourceInfos.set(resourceURL, { regExpUrlFunction, indexResource, dataURI: content, variableName: "var(" + SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource + ")" });
|
|
|
- } else {
|
|
|
- resourceInfos.set(resourceURL, { regExpUrlFunction, indexResource, dataURI: content });
|
|
|
+ let regExpUrlFunction = DomUtil.getRegExp(urlFunction);
|
|
|
+ if (!stylesheetContent.match(regExpUrlFunction)) {
|
|
|
+ urlFunction = "url(" + originalResourceURL + ")";
|
|
|
+ regExpUrlFunction = DomUtil.getRegExp(urlFunction);
|
|
|
+ }
|
|
|
+ if (!stylesheetContent.match(regExpUrlFunction)) {
|
|
|
+ urlFunction = "url('" + originalResourceURL + "')";
|
|
|
+ regExpUrlFunction = DomUtil.getRegExp(urlFunction);
|
|
|
+ }
|
|
|
+ if (stylesheetContent.match(regExpUrlFunction)) {
|
|
|
+ if (duplicate && options.groupDuplicateImages && groupDuplicates) {
|
|
|
+ stylesheetContent = stylesheetContent.replace(regExpUrlFunction, "var(" + SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource + ")");
|
|
|
+ DomUtil.insertVariable(doc, indexResource, content, options);
|
|
|
+ } else {
|
|
|
+ stylesheetContent = stylesheetContent.replace(regExpUrlFunction, urlFunction.replace(originalResourceURL, content));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }));
|
|
|
- const rulesContent = processRules(cssRules);
|
|
|
- if (variablesInfo.cssText) {
|
|
|
- sheetContent += ":root{" + variablesInfo.cssText + "}";
|
|
|
}
|
|
|
- return sheetContent + rulesContent;
|
|
|
|
|
|
- function processRules(cssRules) {
|
|
|
- let rulesContent = "";
|
|
|
+ function getURLFunctions(cssRules, urlFunctions = { style: new Set(), other: new Set() }) {
|
|
|
Array.from(cssRules).forEach(cssRule => {
|
|
|
if (cssRule.type == CSSRule.MEDIA_RULE) {
|
|
|
- const mediaRulesContent = processRules(cssRule.cssRules);
|
|
|
- rulesContent += "@media " + Array.from(cssRule.media).join(",") + "{" + mediaRulesContent + "}";
|
|
|
+ getURLFunctions(cssRule.cssRules, urlFunctions);
|
|
|
} else if (cssRule.type == CSSRule.STYLE_RULE) {
|
|
|
- rulesContent += processURLFunctions(cssRule.cssText);
|
|
|
+ getURLFunctionsRule(cssRule.cssText, urlFunctions.style);
|
|
|
} else {
|
|
|
-
|
|
|
- rulesContent += processURLFunctions(cssRule.cssText, true);
|
|
|
+ getURLFunctionsRule(cssRule.cssText, urlFunctions.other);
|
|
|
}
|
|
|
});
|
|
|
- return rulesContent;
|
|
|
+ return { style: Array.from(urlFunctions.style), other: Array.from(urlFunctions.other) };
|
|
|
}
|
|
|
|
|
|
- function processURLFunctions(cssText, preventGrouping) {
|
|
|
- const urlFunctions = DomUtil.getUrlFunctions(cssText);
|
|
|
- urlFunctions.forEach(urlFunction => {
|
|
|
+ function getURLFunctionsRule(cssText, urlFunctions) {
|
|
|
+ const urlFunctionsRule = DomUtil.getUrlFunctions(cssText);
|
|
|
+ urlFunctionsRule.forEach(urlFunction => {
|
|
|
const originalResourceURL = DomUtil.matchURL(urlFunction);
|
|
|
const resourceURL = DomUtil.normalizeURL(originalResourceURL);
|
|
|
if (!DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
if (DomUtil.testValidURL(resourceURL, baseURI, options.url) && cssText.includes(urlFunction)) {
|
|
|
- const resourceInfo = resourceInfos.get(resourceURL);
|
|
|
- if (options.groupDuplicateImages && resourceInfo.variableName && !preventGrouping) {
|
|
|
- cssText = cssText.replace(resourceInfo.regExpUrlFunction, resourceInfo.variableName);
|
|
|
- DomUtil.insertVariable(doc, resourceInfo.indexResource, resourceInfo.dataURI, options);
|
|
|
- } else {
|
|
|
- cssText = cssText.replace(resourceInfo.regExpUrlFunction, urlFunction.replace(originalResourceURL, resourceInfo.dataURI));
|
|
|
- }
|
|
|
+ urlFunctions.add(urlFunction);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
- return cssText;
|
|
|
+ return urlFunctions;
|
|
|
}
|
|
|
}
|
|
|
|