single-file-core 1.0.22 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -36,7 +36,9 @@ class MatchedRules {
|
|
|
36
36
|
this.mediaAllInfo = createMediaInfo(MEDIA_ALL);
|
|
37
37
|
const matchedElementsCache = new Map();
|
|
38
38
|
let sheetIndex = 0;
|
|
39
|
-
const
|
|
39
|
+
const workStyleSheet = doc.createElement("style");
|
|
40
|
+
doc.body.appendChild(workStyleSheet);
|
|
41
|
+
const workStyleElement = doc.createElement("span");
|
|
40
42
|
doc.body.appendChild(workStyleElement);
|
|
41
43
|
stylesheets.forEach(stylesheetInfo => {
|
|
42
44
|
if (!stylesheetInfo.scoped) {
|
|
@@ -45,9 +47,9 @@ class MatchedRules {
|
|
|
45
47
|
if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
|
|
46
48
|
const mediaInfo = createMediaInfo(stylesheetInfo.mediaText);
|
|
47
49
|
this.mediaAllInfo.medias.set("style-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaInfo);
|
|
48
|
-
getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex, styles, matchedElementsCache,
|
|
50
|
+
getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex, styles, matchedElementsCache, workStyleSheet);
|
|
49
51
|
} else {
|
|
50
|
-
getMatchedElementsRules(doc, cssRules, this.mediaAllInfo, sheetIndex, styles, matchedElementsCache,
|
|
52
|
+
getMatchedElementsRules(doc, cssRules, this.mediaAllInfo, sheetIndex, styles, matchedElementsCache, workStyleSheet);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -64,7 +66,8 @@ class MatchedRules {
|
|
|
64
66
|
startTime = Date.now();
|
|
65
67
|
log(" -- STARTED computeCascade");
|
|
66
68
|
}
|
|
67
|
-
computeCascade(this.mediaAllInfo, [], this.mediaAllInfo, workStyleElement);
|
|
69
|
+
computeCascade(this.mediaAllInfo, [], this.mediaAllInfo, workStyleSheet, workStyleElement);
|
|
70
|
+
workStyleSheet.remove();
|
|
68
71
|
workStyleElement.remove();
|
|
69
72
|
if (DEBUG) {
|
|
70
73
|
log(" -- ENDED computeCascade", Date.now() - startTime);
|
|
@@ -222,9 +225,9 @@ function addRule(element, selectorInfo, styles) {
|
|
|
222
225
|
elementInfo.push(selectorInfo);
|
|
223
226
|
}
|
|
224
227
|
|
|
225
|
-
function computeCascade(mediaInfo, parentMediaInfo, mediaAllInfo, workStylesheet) {
|
|
228
|
+
function computeCascade(mediaInfo, parentMediaInfo, mediaAllInfo, workStylesheet, workStyleElement) {
|
|
226
229
|
mediaInfo.elements.forEach((elementInfo/*, element*/) =>
|
|
227
|
-
getDeclarationsInfo(elementInfo, workStylesheet/*, element*/).forEach((declarationsInfo, property) => {
|
|
230
|
+
getDeclarationsInfo(elementInfo, workStylesheet, workStyleElement/*, element*/).forEach((declarationsInfo, property) => {
|
|
228
231
|
if (declarationsInfo.selectorInfo.ruleInfo || mediaInfo == mediaAllInfo) {
|
|
229
232
|
let info;
|
|
230
233
|
if (declarationsInfo.selectorInfo.ruleInfo) {
|
|
@@ -249,10 +252,10 @@ function computeCascade(mediaInfo, parentMediaInfo, mediaAllInfo, workStylesheet
|
|
|
249
252
|
}
|
|
250
253
|
}));
|
|
251
254
|
delete mediaInfo.elements;
|
|
252
|
-
mediaInfo.medias.forEach(childMediaInfo => computeCascade(childMediaInfo, [mediaInfo, ...parentMediaInfo], mediaAllInfo, workStylesheet));
|
|
255
|
+
mediaInfo.medias.forEach(childMediaInfo => computeCascade(childMediaInfo, [mediaInfo, ...parentMediaInfo], mediaAllInfo, workStylesheet, workStyleElement));
|
|
253
256
|
}
|
|
254
257
|
|
|
255
|
-
function getDeclarationsInfo(elementInfo, workStylesheet/*, element*/) {
|
|
258
|
+
function getDeclarationsInfo(elementInfo, workStylesheet, workStyleElement/*, element*/) {
|
|
256
259
|
const declarationsInfo = new Map();
|
|
257
260
|
const processedProperties = new Set();
|
|
258
261
|
elementInfo.forEach(selectorInfo => {
|
|
@@ -262,17 +265,17 @@ function getDeclarationsInfo(elementInfo, workStylesheet/*, element*/) {
|
|
|
262
265
|
} else {
|
|
263
266
|
declarations = selectorInfo.ruleInfo.ruleData.block.children;
|
|
264
267
|
}
|
|
265
|
-
processDeclarations(declarationsInfo, declarations, selectorInfo, processedProperties, workStylesheet);
|
|
268
|
+
processDeclarations(declarationsInfo, declarations, selectorInfo, processedProperties, workStylesheet, workStyleElement);
|
|
266
269
|
});
|
|
267
270
|
return declarationsInfo;
|
|
268
271
|
}
|
|
269
272
|
|
|
270
|
-
function processDeclarations(declarationsInfo, declarations, selectorInfo, processedProperties, workStylesheet) {
|
|
273
|
+
function processDeclarations(declarationsInfo, declarations, selectorInfo, processedProperties, workStylesheet, workStyleElement) {
|
|
271
274
|
for (let declaration = declarations.tail; declaration; declaration = declaration.prev) {
|
|
272
275
|
const declarationData = declaration.data;
|
|
273
276
|
const declarationText = cssTree.generate(declarationData);
|
|
274
277
|
if (declarationData.type == "Declaration" &&
|
|
275
|
-
(declarationText.match(REGEXP_VENDOR_IDENTIFIER) || !processedProperties.has(declarationData.property) || declarationData.important) && !invalidDeclaration(declarationText,
|
|
278
|
+
(declarationText.match(REGEXP_VENDOR_IDENTIFIER) || !processedProperties.has(declarationData.property) || declarationData.important) && !invalidDeclaration(declarationText, workStyleElement)) {
|
|
276
279
|
const declarationInfo = declarationsInfo.get(declarationData);
|
|
277
280
|
if (!declarationInfo || (declarationData.important && !declarationInfo.important)) {
|
|
278
281
|
declarationsInfo.set(declarationData, { selectorInfo, important: declarationData.important });
|
|
@@ -284,10 +287,10 @@ function processDeclarations(declarationsInfo, declarations, selectorInfo, proce
|
|
|
284
287
|
}
|
|
285
288
|
}
|
|
286
289
|
|
|
287
|
-
function invalidDeclaration(declarationText,
|
|
290
|
+
function invalidDeclaration(declarationText, workStyleElement) {
|
|
288
291
|
let invalidDeclaration;
|
|
289
|
-
|
|
290
|
-
if (
|
|
292
|
+
workStyleElement.style = declarationText;
|
|
293
|
+
if (!workStyleElement.style.length) {
|
|
291
294
|
if (!declarationText.match(REGEXP_VENDOR_IDENTIFIER)) {
|
|
292
295
|
invalidDeclaration = true;
|
|
293
296
|
}
|
|
@@ -101,9 +101,13 @@ function setSrc(srcData, imgElement, pictureElement) {
|
|
|
101
101
|
|
|
102
102
|
function getSourceSrc(sourceSrcSet) {
|
|
103
103
|
if (sourceSrcSet) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
try {
|
|
105
|
+
const srcset = srcsetParser.process(sourceSrcSet);
|
|
106
|
+
if (srcset.length) {
|
|
107
|
+
return (srcset.find(srcset => srcset.url)).url;
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
// ignored
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
}
|
|
@@ -145,7 +145,7 @@ function serializeAttribute(attribute, element, compressHTML) {
|
|
|
145
145
|
simpleQuotesValue = true;
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
const invalidUnquotedValue = !compressHTML ||
|
|
148
|
+
const invalidUnquotedValue = !compressHTML || value.match(/[ \t\n\f\r'"`=<>]/);
|
|
149
149
|
content += " ";
|
|
150
150
|
if (!attribute.namespace) {
|
|
151
151
|
content += name;
|
package/package.json
CHANGED
package/single-file-core.js
CHANGED
|
@@ -1854,10 +1854,6 @@ class ProcessorHelper {
|
|
|
1854
1854
|
if (testValidURL(resourceURL)) {
|
|
1855
1855
|
let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL,
|
|
1856
1856
|
{ asBinary: true, expectedType, groupDuplicates: options.groupDuplicateImages && resourceElement.tagName == "IMG" && attributeName == "src" });
|
|
1857
|
-
if (resourceURL.includes("openbenchmarking.org/embed.php")) {
|
|
1858
|
-
debugger
|
|
1859
|
-
}
|
|
1860
|
-
|
|
1861
1857
|
if (originURL) {
|
|
1862
1858
|
if (content == util.EMPTY_RESOURCE) {
|
|
1863
1859
|
try {
|
package/single-file-helper.js
CHANGED
|
@@ -148,7 +148,7 @@ function preProcessDoc(doc, win, options) {
|
|
|
148
148
|
elementsInfo = getElementsInfo(win, doc, doc.documentElement, options);
|
|
149
149
|
if (options.moveStylesInHead) {
|
|
150
150
|
doc.querySelectorAll("body style, body ~ style").forEach(element => {
|
|
151
|
-
const computedStyle =
|
|
151
|
+
const computedStyle = getComputedStyle(win, element);
|
|
152
152
|
if (computedStyle && testHiddenElement(element, computedStyle)) {
|
|
153
153
|
element.setAttribute(STYLE_ATTRIBUTE_NAME, "");
|
|
154
154
|
elementsInfo.markedElements.push(element);
|
|
@@ -186,7 +186,7 @@ function getElementsInfo(win, doc, element, options, data = { usedFonts: new Map
|
|
|
186
186
|
elements.forEach(element => {
|
|
187
187
|
let elementHidden, elementKept, computedStyle;
|
|
188
188
|
if (!options.autoSaveExternalSave && (options.removeHiddenElements || options.removeUnusedFonts || options.compressHTML)) {
|
|
189
|
-
computedStyle =
|
|
189
|
+
computedStyle = getComputedStyle(win, element);
|
|
190
190
|
if (element instanceof win.HTMLElement) {
|
|
191
191
|
if (options.removeHiddenElements) {
|
|
192
192
|
elementKept = ((ascendantHidden || element.closest("html > head")) && KEPT_TAG_NAMES.includes(element.tagName)) || element.closest("details");
|
|
@@ -209,9 +209,9 @@ function getElementsInfo(win, doc, element, options, data = { usedFonts: new Map
|
|
|
209
209
|
}
|
|
210
210
|
if (options.removeUnusedFonts) {
|
|
211
211
|
getUsedFont(computedStyle, options, data.usedFonts);
|
|
212
|
-
getUsedFont(
|
|
213
|
-
getUsedFont(
|
|
214
|
-
getUsedFont(
|
|
212
|
+
getUsedFont(getComputedStyle(win, element, ":first-letter"), options, data.usedFonts);
|
|
213
|
+
getUsedFont(getComputedStyle(win, element, ":before"), options, data.usedFonts);
|
|
214
|
+
getUsedFont(getComputedStyle(win, element, ":after"), options, data.usedFonts);
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
}
|
|
@@ -269,11 +269,7 @@ function getResourcesInfo(win, doc, element, options, data, elementHidden, compu
|
|
|
269
269
|
element.setAttribute(IMAGE_ATTRIBUTE_NAME, data.images.length - 1);
|
|
270
270
|
data.markedElements.push(element);
|
|
271
271
|
element.removeAttribute(LAZY_SRC_ATTRIBUTE_NAME);
|
|
272
|
-
|
|
273
|
-
computedStyle = computedStyle || win.getComputedStyle(element);
|
|
274
|
-
} catch (error) {
|
|
275
|
-
// ignored
|
|
276
|
-
}
|
|
272
|
+
computedStyle = computedStyle || getComputedStyle(win, element);
|
|
277
273
|
if (computedStyle) {
|
|
278
274
|
imageData.size = getSize(win, element, computedStyle);
|
|
279
275
|
const boxShadow = computedStyle.getPropertyValue("box-shadow");
|
|
@@ -292,9 +288,9 @@ function getResourcesInfo(win, doc, element, options, data, elementHidden, compu
|
|
|
292
288
|
if (element.tagName == "VIDEO") {
|
|
293
289
|
const src = element.currentSrc;
|
|
294
290
|
if (src && !src.startsWith("blob:") && !src.startsWith("data:")) {
|
|
295
|
-
const
|
|
291
|
+
const computedStyle = getComputedStyle(win, element.parentNode);
|
|
296
292
|
data.videos.push({
|
|
297
|
-
positionParent,
|
|
293
|
+
positionParent: computedStyle && computedStyle.getPropertyValue("position"),
|
|
298
294
|
src,
|
|
299
295
|
size: {
|
|
300
296
|
pxWidth: element.clientWidth,
|
|
@@ -469,37 +465,39 @@ function getSize(win, imageElement, computedStyle) {
|
|
|
469
465
|
let pxHeight = imageElement.naturalHeight;
|
|
470
466
|
if (!pxWidth && !pxHeight) {
|
|
471
467
|
const noStyleAttribute = imageElement.getAttribute("style") == null;
|
|
472
|
-
computedStyle = computedStyle ||
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
468
|
+
computedStyle = computedStyle || getComputedStyle(win, imageElement);
|
|
469
|
+
if (computedStyle) {
|
|
470
|
+
let removeBorderWidth = false;
|
|
471
|
+
if (computedStyle.getPropertyValue("box-sizing") == "content-box") {
|
|
472
|
+
const boxSizingValue = imageElement.style.getPropertyValue("box-sizing");
|
|
473
|
+
const boxSizingPriority = imageElement.style.getPropertyPriority("box-sizing");
|
|
474
|
+
const clientWidth = imageElement.clientWidth;
|
|
475
|
+
imageElement.style.setProperty("box-sizing", "border-box", "important");
|
|
476
|
+
removeBorderWidth = imageElement.clientWidth != clientWidth;
|
|
477
|
+
if (boxSizingValue) {
|
|
478
|
+
imageElement.style.setProperty("box-sizing", boxSizingValue, boxSizingPriority);
|
|
479
|
+
} else {
|
|
480
|
+
imageElement.style.removeProperty("box-sizing");
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
let paddingLeft, paddingRight, paddingTop, paddingBottom, borderLeft, borderRight, borderTop, borderBottom;
|
|
484
|
+
paddingLeft = getWidth("padding-left", computedStyle);
|
|
485
|
+
paddingRight = getWidth("padding-right", computedStyle);
|
|
486
|
+
paddingTop = getWidth("padding-top", computedStyle);
|
|
487
|
+
paddingBottom = getWidth("padding-bottom", computedStyle);
|
|
488
|
+
if (removeBorderWidth) {
|
|
489
|
+
borderLeft = getWidth("border-left-width", computedStyle);
|
|
490
|
+
borderRight = getWidth("border-right-width", computedStyle);
|
|
491
|
+
borderTop = getWidth("border-top-width", computedStyle);
|
|
492
|
+
borderBottom = getWidth("border-bottom-width", computedStyle);
|
|
482
493
|
} else {
|
|
483
|
-
|
|
494
|
+
borderLeft = borderRight = borderTop = borderBottom = 0;
|
|
495
|
+
}
|
|
496
|
+
pxWidth = Math.max(0, imageElement.clientWidth - paddingLeft - paddingRight - borderLeft - borderRight);
|
|
497
|
+
pxHeight = Math.max(0, imageElement.clientHeight - paddingTop - paddingBottom - borderTop - borderBottom);
|
|
498
|
+
if (noStyleAttribute) {
|
|
499
|
+
imageElement.removeAttribute("style");
|
|
484
500
|
}
|
|
485
|
-
}
|
|
486
|
-
let paddingLeft, paddingRight, paddingTop, paddingBottom, borderLeft, borderRight, borderTop, borderBottom;
|
|
487
|
-
paddingLeft = getWidth("padding-left", computedStyle);
|
|
488
|
-
paddingRight = getWidth("padding-right", computedStyle);
|
|
489
|
-
paddingTop = getWidth("padding-top", computedStyle);
|
|
490
|
-
paddingBottom = getWidth("padding-bottom", computedStyle);
|
|
491
|
-
if (removeBorderWidth) {
|
|
492
|
-
borderLeft = getWidth("border-left-width", computedStyle);
|
|
493
|
-
borderRight = getWidth("border-right-width", computedStyle);
|
|
494
|
-
borderTop = getWidth("border-top-width", computedStyle);
|
|
495
|
-
borderBottom = getWidth("border-bottom-width", computedStyle);
|
|
496
|
-
} else {
|
|
497
|
-
borderLeft = borderRight = borderTop = borderBottom = 0;
|
|
498
|
-
}
|
|
499
|
-
pxWidth = Math.max(0, imageElement.clientWidth - paddingLeft - paddingRight - borderLeft - borderRight);
|
|
500
|
-
pxHeight = Math.max(0, imageElement.clientHeight - paddingTop - paddingBottom - borderTop - borderBottom);
|
|
501
|
-
if (noStyleAttribute) {
|
|
502
|
-
imageElement.removeAttribute("style");
|
|
503
501
|
}
|
|
504
502
|
}
|
|
505
503
|
return { pxWidth, pxHeight };
|
|
@@ -550,4 +548,12 @@ function getFontWeight(weight) {
|
|
|
550
548
|
|
|
551
549
|
function flatten(array) {
|
|
552
550
|
return array.flat ? array.flat() : array.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function getComputedStyle(win, element, pseudoElement) {
|
|
554
|
+
try {
|
|
555
|
+
return win.getComputedStyle(element, pseudoElement);
|
|
556
|
+
} catch (error) {
|
|
557
|
+
// ignored
|
|
558
|
+
}
|
|
553
559
|
}
|