|
|
@@ -24,6 +24,7 @@ this.docHelper = this.docHelper || (() => {
|
|
|
|
|
|
const REMOVED_CONTENT_ATTRIBUTE_NAME = "data-single-file-removed-content";
|
|
|
const PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME = "data-single-file-preserved-space-element";
|
|
|
+ const SHADOW_ROOT_ATTRIBUTE_NAME = "data-single-file-shadow-root-element";
|
|
|
const WIN_ID_ATTRIBUTE_NAME = "data-frame-tree-win-id";
|
|
|
const IMAGE_ATTRIBUTE_NAME = "data-single-file-image";
|
|
|
const INPUT_VALUE_ATTRIBUTE_NAME = "data-single-file-value";
|
|
|
@@ -44,6 +45,7 @@ this.docHelper = this.docHelper || (() => {
|
|
|
removedContentAttributeName,
|
|
|
imagesAttributeName,
|
|
|
inputValueAttributeName,
|
|
|
+ shadowRootAttributeName,
|
|
|
removeQuotes
|
|
|
};
|
|
|
|
|
|
@@ -56,19 +58,19 @@ this.docHelper = this.docHelper || (() => {
|
|
|
element.parentElement.replaceChild(disabledNoscriptElement, element);
|
|
|
});
|
|
|
doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.hidden = true);
|
|
|
- let canvasData, imageData, usedFonts;
|
|
|
+ let canvasData, imageData, usedFonts, shadowRootContents;
|
|
|
if (win) {
|
|
|
canvasData = getCanvasData(doc, win);
|
|
|
imageData = getImageData(doc, win, options);
|
|
|
if (options.removeHiddenElements || options.removeUnusedStyles || options.compressHTML) {
|
|
|
- let styles = getStyles(win, doc.body);
|
|
|
+ let elementsInfo = getElementsInfo(win, doc.body);
|
|
|
if (options.removeHiddenElements) {
|
|
|
const markerRemovedContent = removedContentAttributeName(options.sessionId);
|
|
|
let ignoredTags = JSON.parse(JSON.stringify(IGNORED_REMOVED_TAG_NAMES));
|
|
|
if (!options.removeScripts) {
|
|
|
ignoredTags = ignoredTags.concat("SCRIPT");
|
|
|
}
|
|
|
- markHiddenCandidates(win, doc.body, styles, false, markerRemovedContent, new Set(), ignoredTags);
|
|
|
+ markHiddenCandidates(win, doc.body, elementsInfo, false, markerRemovedContent, new Set(), ignoredTags);
|
|
|
markHiddenElements(win, doc.body, markerRemovedContent);
|
|
|
doc.querySelectorAll("iframe").forEach(element => {
|
|
|
const boundingRect = element.getBoundingClientRect();
|
|
|
@@ -76,18 +78,30 @@ this.docHelper = this.docHelper || (() => {
|
|
|
element.setAttribute(markerRemovedContent, "");
|
|
|
}
|
|
|
});
|
|
|
- styles = new Map(Array.from(styles).filter(([element]) => element.getAttribute(markerRemovedContent) != ""));
|
|
|
+ elementsInfo = new Map(Array.from(elementsInfo).filter(([element]) => element.getAttribute(markerRemovedContent) != ""));
|
|
|
}
|
|
|
if (options.removeUnusedStyles) {
|
|
|
- usedFonts = getUsedFonts(styles);
|
|
|
+ usedFonts = getUsedFonts(elementsInfo);
|
|
|
}
|
|
|
if (options.compressHTML) {
|
|
|
- styles.forEach((style, element) => {
|
|
|
- if (style.whiteSpace.startsWith("pre")) {
|
|
|
+ elementsInfo.forEach((elementInfo, element) => {
|
|
|
+ if (elementInfo.whiteSpace.startsWith("pre")) {
|
|
|
element.setAttribute(preservedSpaceAttributeName(options.sessionId), "");
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
+ elementsInfo.forEach((elementInfo, element) => {
|
|
|
+ let elementIndex = 0;
|
|
|
+ if (elementInfo.shadowRoot) {
|
|
|
+ const attributeName = shadowRootAttributeName(options.sessionId);
|
|
|
+ element.setAttribute(attributeName, elementIndex);
|
|
|
+ elementIndex++;
|
|
|
+ if (!shadowRootContents) {
|
|
|
+ shadowRootContents = [];
|
|
|
+ }
|
|
|
+ shadowRootContents.push({ content: element.shadowRoot.innerHTML, height: element.clientHeight });
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
retrieveInputValues(doc, options);
|
|
|
@@ -97,7 +111,8 @@ this.docHelper = this.docHelper || (() => {
|
|
|
stylesheetContents: getStylesheetContents(doc),
|
|
|
imageData,
|
|
|
postersData: getPostersData(doc),
|
|
|
- usedFonts
|
|
|
+ usedFonts,
|
|
|
+ shadowRootContents
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -116,12 +131,12 @@ this.docHelper = this.docHelper || (() => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- function getStyles(win, element, styles = new Map()) {
|
|
|
- const elements = Array.from(element.childNodes).filter(node => node instanceof win.HTMLElement);
|
|
|
+ function getElementsInfo(win, element, elementsInfo = new Map()) {
|
|
|
+ const elements = Array.from(element.childNodes).filter(node => !win || node instanceof win.HTMLElement);
|
|
|
elements.forEach(element => {
|
|
|
- getStyles(win, element, styles);
|
|
|
+ getElementsInfo(win, element, elementsInfo);
|
|
|
const computedStyle = win.getComputedStyle(element);
|
|
|
- styles.set(element, {
|
|
|
+ elementsInfo.set(element, {
|
|
|
display: computedStyle.getPropertyValue("display"),
|
|
|
opacity: computedStyle.getPropertyValue("opacity"),
|
|
|
visibility: computedStyle.getPropertyValue("visibility"),
|
|
|
@@ -129,10 +144,11 @@ this.docHelper = this.docHelper || (() => {
|
|
|
fontWeight: getFontWeight(computedStyle.getPropertyValue("font-weight")),
|
|
|
fontStyle: computedStyle.getPropertyValue("font-style") || "normal",
|
|
|
fontVariant: computedStyle.getPropertyValue("font-variant") || "normal",
|
|
|
- whiteSpace: computedStyle.getPropertyValue("white-space")
|
|
|
+ whiteSpace: computedStyle.getPropertyValue("white-space"),
|
|
|
+ shadowRoot: element.shadowRoot
|
|
|
});
|
|
|
});
|
|
|
- return styles;
|
|
|
+ return elementsInfo;
|
|
|
}
|
|
|
|
|
|
function markHiddenCandidates(win, element, styles, elementHidden, markerRemovedContent, removedCandidates, ignoredTags) {
|
|
|
@@ -186,6 +202,7 @@ this.docHelper = this.docHelper || (() => {
|
|
|
}
|
|
|
doc.querySelectorAll("[" + imagesAttributeName(options.sessionId) + "]").forEach(element => element.removeAttribute(imagesAttributeName(options.sessionId)));
|
|
|
doc.querySelectorAll("[" + inputValueAttributeName(options.sessionId) + "]").forEach(element => element.removeAttribute(inputValueAttributeName(options.sessionId)));
|
|
|
+ doc.querySelectorAll("[" + shadowRootAttributeName(options.sessionId) + "]").forEach(element => element.removeAttribute(shadowRootAttributeName(options.sessionId)));
|
|
|
}
|
|
|
|
|
|
function imagesAttributeName(sessionId) {
|
|
|
@@ -196,6 +213,10 @@ this.docHelper = this.docHelper || (() => {
|
|
|
return PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME + (sessionId || "");
|
|
|
}
|
|
|
|
|
|
+ function shadowRootAttributeName(sessionId) {
|
|
|
+ return SHADOW_ROOT_ATTRIBUTE_NAME + (sessionId || "");
|
|
|
+ }
|
|
|
+
|
|
|
function removedContentAttributeName(sessionId) {
|
|
|
return REMOVED_CONTENT_ATTRIBUTE_NAME + (sessionId || "");
|
|
|
}
|