|
|
@@ -92,7 +92,8 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
posters: [],
|
|
|
usedFonts: [],
|
|
|
shadowRoots: [],
|
|
|
- imports: []
|
|
|
+ imports: [],
|
|
|
+ markedElements: []
|
|
|
};
|
|
|
}
|
|
|
return {
|
|
|
@@ -104,11 +105,12 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
usedFonts: Array.from(elementsInfo.usedFonts.values()),
|
|
|
shadowRoots: elementsInfo.shadowRoots,
|
|
|
imports: elementsInfo.imports,
|
|
|
- referrer: doc.referrer
|
|
|
+ referrer: doc.referrer,
|
|
|
+ markedElements: elementsInfo.markedElements
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- function getElementsInfo(win, doc, element, options, data = { usedFonts: new Map(), canvases: [], images: [], posters: [], shadowRoots: [], imports: [] }, ascendantHidden) {
|
|
|
+ function getElementsInfo(win, doc, element, options, data = { usedFonts: new Map(), canvases: [], images: [], posters: [], shadowRoots: [], imports: [], markedElements: [] }, ascendantHidden) {
|
|
|
const elements = Array.from(element.childNodes).filter(node => node instanceof win.HTMLElement);
|
|
|
elements.forEach(element => {
|
|
|
let elementHidden, computedStyle;
|
|
|
@@ -119,6 +121,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
Array.from(element.childNodes).filter(node => node instanceof win.HTMLElement).forEach(element => {
|
|
|
if (!IGNORED_REMOVED_TAG_NAMES.includes(element.tagName)) {
|
|
|
element.setAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME, "");
|
|
|
+ data.markedElements.push(element);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
@@ -129,6 +132,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
const whiteSpace = computedStyle.getPropertyValue("white-space");
|
|
|
if (whiteSpace && whiteSpace.startsWith("pre")) {
|
|
|
element.setAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, "");
|
|
|
+ data.markedElements.push(element);
|
|
|
}
|
|
|
}
|
|
|
if (options.removeUnusedFonts) {
|
|
|
@@ -143,6 +147,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
if (element.shadowRoot) {
|
|
|
const shadowRootInfo = {};
|
|
|
element.setAttribute(SHADOW_ROOT_ATTRIBUTE_NAME, data.shadowRoots.length);
|
|
|
+ data.markedElements.push(element);
|
|
|
data.shadowRoots.push(shadowRootInfo);
|
|
|
getElementsInfo(win, doc, element.shadowRoot, options, data, elementHidden);
|
|
|
shadowRootInfo.content = element.shadowRoot.innerHTML;
|
|
|
@@ -160,6 +165,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
const size = getSize(win, element, computedStyle);
|
|
|
data.canvases.push({ dataURI: element.toDataURL("image/png", ""), width: size.width, height: size.height });
|
|
|
element.setAttribute(CANVAS_ATTRIBUTE_NAME, data.canvases.length - 1);
|
|
|
+ data.markedElements.push(element);
|
|
|
} catch (error) {
|
|
|
// ignored
|
|
|
}
|
|
|
@@ -172,6 +178,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
};
|
|
|
data.images.push(imageData);
|
|
|
element.setAttribute(IMAGE_ATTRIBUTE_NAME, data.images.length - 1);
|
|
|
+ data.markedElements.push(element);
|
|
|
element.removeAttribute(LAZY_SRC_ATTRIBUTE_NAME);
|
|
|
computedStyle = computedStyle || win.getComputedStyle(element);
|
|
|
if (computedStyle) {
|
|
|
@@ -199,6 +206,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
context.drawImage(element, 0, 0, canvasElement.width, canvasElement.height);
|
|
|
data.posters.push(canvasElement.toDataURL("image/png", ""));
|
|
|
element.setAttribute(POSTER_ATTRIBUTE_NAME, data.posters.length - 1);
|
|
|
+ data.markedElements.push(element);
|
|
|
} catch (error) {
|
|
|
// ignored
|
|
|
}
|
|
|
@@ -213,23 +221,28 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
if (element.import) {
|
|
|
data.imports.push({ content: serialize(element.import) });
|
|
|
element.setAttribute(HTML_IMPORT_ATTRIBUTE_NAME, data.imports.length - 1);
|
|
|
+ data.markedElements.push(element);
|
|
|
}
|
|
|
}
|
|
|
if (element.tagName == "INPUT") {
|
|
|
if (element.type != "password") {
|
|
|
element.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, element.value);
|
|
|
+ data.markedElements.push(element);
|
|
|
}
|
|
|
if (element.type == "radio" || element.type == "checkbox") {
|
|
|
element.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, element.checked);
|
|
|
+ data.markedElements.push(element);
|
|
|
}
|
|
|
}
|
|
|
if (element.tagName == "TEXTAREA") {
|
|
|
element.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, element.value);
|
|
|
+ data.markedElements.push(element);
|
|
|
}
|
|
|
if (element.tagName == "SELECT") {
|
|
|
element.querySelectorAll("option").forEach(option => {
|
|
|
if (option.selected) {
|
|
|
option.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, "");
|
|
|
+ data.markedElements.push(option);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
@@ -269,7 +282,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
return Boolean(hidden);
|
|
|
}
|
|
|
|
|
|
- function postProcessDoc(doc, options) {
|
|
|
+ function postProcessDoc(doc, markedElements) {
|
|
|
doc.querySelectorAll("disabled-noscript").forEach(element => {
|
|
|
const noscriptElement = doc.createElement("noscript");
|
|
|
Array.from(element.childNodes).forEach(node => noscriptElement.appendChild(node));
|
|
|
@@ -282,18 +295,20 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
|
|
|
if (doc.head) {
|
|
|
doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.removeAttribute("hidden"));
|
|
|
}
|
|
|
- if (options.removeHiddenElements) {
|
|
|
- doc.querySelectorAll("[" + REMOVED_CONTENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME));
|
|
|
+ if (!markedElements) {
|
|
|
+ const singleFileAttributes = [REMOVED_CONTENT_ATTRIBUTE_NAME, PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, IMAGE_ATTRIBUTE_NAME, POSTER_ATTRIBUTE_NAME, CANVAS_ATTRIBUTE_NAME, INPUT_VALUE_ATTRIBUTE_NAME, SHADOW_ROOT_ATTRIBUTE_NAME, HTML_IMPORT_ATTRIBUTE_NAME];
|
|
|
+ markedElements = doc.querySelectorAll(singleFileAttributes.map(name => "[" + name + "]").join(","));
|
|
|
}
|
|
|
- if (options.compressHTML) {
|
|
|
- doc.querySelectorAll("[" + PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME));
|
|
|
- }
|
|
|
- doc.querySelectorAll("[" + IMAGE_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(IMAGE_ATTRIBUTE_NAME));
|
|
|
- doc.querySelectorAll("[" + POSTER_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(POSTER_ATTRIBUTE_NAME));
|
|
|
- doc.querySelectorAll("[" + CANVAS_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(CANVAS_ATTRIBUTE_NAME));
|
|
|
- doc.querySelectorAll("[" + INPUT_VALUE_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(INPUT_VALUE_ATTRIBUTE_NAME));
|
|
|
- doc.querySelectorAll("[" + SHADOW_ROOT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(SHADOW_ROOT_ATTRIBUTE_NAME));
|
|
|
- doc.querySelectorAll("[" + HTML_IMPORT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(HTML_IMPORT_ATTRIBUTE_NAME));
|
|
|
+ markedElements.forEach(element => {
|
|
|
+ element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME);
|
|
|
+ element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME);
|
|
|
+ element.removeAttribute(IMAGE_ATTRIBUTE_NAME);
|
|
|
+ element.removeAttribute(POSTER_ATTRIBUTE_NAME);
|
|
|
+ element.removeAttribute(CANVAS_ATTRIBUTE_NAME);
|
|
|
+ element.removeAttribute(INPUT_VALUE_ATTRIBUTE_NAME);
|
|
|
+ element.removeAttribute(SHADOW_ROOT_ATTRIBUTE_NAME);
|
|
|
+ element.removeAttribute(HTML_IMPORT_ATTRIBUTE_NAME);
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
function getStylesheetsData(doc) {
|