瀏覽代碼

enhanced implementaton to remove srcsets by retrieving the current src and testing image sizes

Gildas 7 年之前
父節點
當前提交
8af76f197f

+ 1 - 0
extension/core/bg/core.js

@@ -138,6 +138,7 @@ singlefile.core = (() => {
 		options.framesData = message.framesData;
 		options.canvasData = message.canvasData;
 		options.stylesheetContents = message.stylesheetContents;
+		options.currentSrcImages = message.currentSrcImages;
 		options.insertSingleFileComment = true;
 		options.insertFaviconLink = true;
 		options.backgroundTab = true;

+ 2 - 2
extension/core/content/content-autosave.js

@@ -47,7 +47,7 @@ this.singlefile.autosave = this.singlefile.autosave || (async () => {
 				if (!options.removeFrames && this.frameTree) {
 					framesData = await frameTree.getAsync(options);
 				}
-				browser.runtime.sendMessage({ processContent: true, content: docHelper.serialize(document, false), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, framesData, url: location.href });
+				browser.runtime.sendMessage({ processContent: true, content: docHelper.serialize(document, false), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, currentSrcImages: docData.currentSrcImages, framesData, url: location.href });
 				docHelper.postProcessDoc(document, window);
 				singlefile.pageAutoSaved = true;
 			}
@@ -75,7 +75,7 @@ this.singlefile.autosave = this.singlefile.autosave || (async () => {
 	function onUnload() {
 		if (!singlefile.pageAutoSaved) {
 			const docData = docHelper.preProcessDoc(document, window, options);
-			browser.runtime.sendMessage({ processContent: true, content: docHelper.serialize(document), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, framesData: this.frameTree && !options.removeFrames && frameTree.getSync(options), url: location.href });
+			browser.runtime.sendMessage({ processContent: true, content: docHelper.serialize(document), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, currentSrcImages: docData.currentSrcImages, framesData: this.frameTree && !options.removeFrames && frameTree.getSync(options), url: location.href });
 		}
 	}
 

+ 25 - 1
lib/single-file/doc-helper.js

@@ -60,7 +60,8 @@ this.docHelper = this.docHelper || (() => {
 		}
 		return {
 			canvasData: getCanvasData(doc),
-			stylesheetContents: getStylesheetContents(doc)
+			stylesheetContents: getStylesheetContents(doc),
+			currentSrcImages: getCurrentSrcImages(doc)
 		};
 	}
 
@@ -120,6 +121,29 @@ this.docHelper = this.docHelper || (() => {
 		}
 	}
 
+	function getCurrentSrcImages(doc) {
+		if (doc) {
+			const urls = [];
+			doc.querySelectorAll("[srcset], [data-srcset]").forEach((element, elementIndex) => {
+				const tagName = element.tagName.toLowerCase();
+				let imageElement;
+				if (tagName == "source") {
+					const parentElement = element.parentElement;
+					if (parentElement.tagName.toLowerCase() == "picture") {
+						imageElement = parentElement.querySelector("img");
+					}
+				}
+				if (tagName == "img") {
+					imageElement = element;
+				}
+				if (imageElement.naturalWidth > 1 && imageElement.naturalHeight > 1 && !imageElement.currentSrc.startsWith("data:")) {
+					urls[elementIndex] = imageElement.currentSrc;
+				}
+			});
+			return urls;
+		}
+	}
+
 	function serialize(doc) {
 		const docType = doc.doctype;
 		let docTypeString = "";

+ 2 - 1
lib/single-file/frame-tree.js

@@ -90,6 +90,7 @@ this.frameTree = this.frameTree || (() => {
 				frameData.baseURI = messageFrameData.baseURI;
 				frameData.title = messageFrameData.title;
 				frameData.stylesheetContents = messageFrameData.stylesheetContents;
+				frameData.currentSrcImages = messageFrameData.currentSrcImages;
 				frameData.canvasData = messageFrameData.canvasData;
 				frameData.processed = messageFrameData.processed;
 				frameData.timeout = messageFrameData.timeout;
@@ -171,7 +172,7 @@ this.frameTree = this.frameTree || (() => {
 		const content = docHelper.serialize(document);
 		docHelper.postProcessDoc(document, window, options);
 		const baseURI = document.baseURI.split("#")[0];
-		return { windowId, content, baseURI, title: document.title, stylesheetContents: docData.stylesheetContents, canvasData: docData.canvasData, processed: true };
+		return { windowId, content, baseURI, title: document.title, stylesheetContents: docData.stylesheetContents, currentSrcImages: docData.currentSrcImages, canvasData: docData.canvasData, processed: true };
 	}
 
 })();

+ 13 - 4
lib/single-file/single-file-core.js

@@ -72,6 +72,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		sync: [
 			{ action: "removeUIElements" },
 			{ action: "replaceStyleContents" },
+			{ option: "removeSrcSet", action: "removeSrcSet" },
 			{ option: "removeFrames", action: "removeFrames" },
 			{ option: "removeImports", action: "removeImports" },
 			{ option: "removeScripts", action: "removeScripts" },
@@ -106,7 +107,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 	}, {
 		sync: [
 			{ option: "lazyLoadImages", action: "lazyLoadImages" },
-			{ option: "removeSrcSet", action: "removeSrcSet" },
 			{ option: "removeAlternativeFonts", action: "postRemoveAlternativeFonts" }
 		],
 		async: [
@@ -130,6 +130,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				const docData = DOM.preProcessDoc(this.options.doc, this.options.win, this.options);
 				this.options.canvasData = docData.canvasData;
 				this.options.stylesheetContents = docData.stylesheetContents;
+				this.options.currentSrcImages = docData.currentSrcImages;
 			}
 			this.options.content = this.options.content || (this.options.doc ? DOM.serialize(this.options.doc, false) : null);
 			this.onprogress = options.onprogress || (() => { });
@@ -398,20 +399,27 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		removeSrcSet() {
-			this.doc.querySelectorAll("[srcset]").forEach(element => {
+			this.doc.querySelectorAll("[srcset], [data-srcset]").forEach((element, elementIndex) => {
 				const tagName = element.tagName.toLowerCase();
+				const currentSrcImage = this.options.currentSrcImages && this.options.currentSrcImages[elementIndex];
 				if (tagName == "source") {
 					const parentElement = element.parentElement;
 					if (parentElement.tagName.toLowerCase() == "picture") {
 						const imageElement = parentElement.querySelector("img");
-						if (imageElement && imageElement.src) {
+						if (imageElement && (imageElement.src || currentSrcImage)) {
 							element.remove();
+							if (currentSrcImage) {
+								imageElement.src = currentSrcImage;
+							}
 						}
 					}
 				}
-				if (tagName == "img" && element.src) {
+				if (tagName == "img" && (element.src || currentSrcImage)) {
 					element.removeAttribute("srcset");
 					element.removeAttribute("sizes");
+					if (currentSrcImage) {
+						element.src = currentSrcImage;
+					}
 				}
 			});
 		}
@@ -574,6 +582,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 									options.content = frameData.content;
 									options.canvasData = frameData.canvasData;
 									options.stylesheetContents = frameData.stylesheetContents;
+									options.currentSrcImages = frameData.currentSrcImages;
 									frameData.processor = new PageProcessor(options);
 									frameData.frameElement = frameElement;
 									await frameData.processor.loadPage();