Przeglądaj źródła

add option "block mixed content" (see #804)

Gildas 4 lat temu
rodzic
commit
fc8e0582a6

+ 4 - 0
_locales/de/messages.json

@@ -159,6 +159,10 @@
 		"message": "Muster für Inhalt des Infoknopfs",
 		"message": "Muster für Inhalt des Infoknopfs",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "Blockieren gemischter Inhalte",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "Einfügen Inhalt des Infoknopfs in die gespeicherte Seite",
 		"message": "Einfügen Inhalt des Infoknopfs in die gespeicherte Seite",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/en/messages.json

@@ -159,6 +159,10 @@
 		"message": "template of the infobar content",
 		"message": "template of the infobar content",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},	
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "include the infobar in the saved page",
 		"message": "include the infobar in the saved page",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/es/messages.json

@@ -159,6 +159,10 @@
 		"message": "plantilla del contenido de la barra informativa",
 		"message": "plantilla del contenido de la barra informativa",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "bloqueo de contenido mixto",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "incluir la barra informativa en la página guardada",
 		"message": "incluir la barra informativa en la página guardada",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/fr/messages.json

@@ -159,6 +159,10 @@
 		"message": "modèle du contenu de la barre d'information",
 		"message": "modèle du contenu de la barre d'information",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "bloquer les contenus mixtes",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "inclure la barre d'information dans la page sauvegardée",
 		"message": "inclure la barre d'information dans la page sauvegardée",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/it/messages.json

@@ -159,6 +159,10 @@
 		"message": "Modello del contenuto della barra informativa",
 		"message": "Modello del contenuto della barra informativa",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "includi una barra informativa nella pagina salvata",
 		"message": "includi una barra informativa nella pagina salvata",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/ja/messages.json

@@ -159,6 +159,10 @@
 		"message": "infobar コンテンツのテンプレート",
 		"message": "infobar コンテンツのテンプレート",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "保存されたページに、infobar を含める",
 		"message": "保存されたページに、infobar を含める",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/pl/messages.json

@@ -159,6 +159,10 @@
 		"message": "szablon zawartości paska informacyjnego",
 		"message": "szablon zawartości paska informacyjnego",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "dołączaj pasek informacyjny do zapisanej strony",
 		"message": "dołączaj pasek informacyjny do zapisanej strony",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/ru/messages.json

@@ -159,6 +159,10 @@
 		"message": "шаблон содержимого информационной панели",
 		"message": "шаблон содержимого информационной панели",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "добавить информационную панель в сохраняемую страницу",
 		"message": "добавить информационную панель в сохраняемую страницу",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/uk/messages.json

@@ -159,6 +159,10 @@
 		"message": "шаблон вмісту інформаційної панелі ",
 		"message": "шаблон вмісту інформаційної панелі ",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "додавати інформ. панель в сторінку що зберігається",
 		"message": "додавати інформ. панель в сторінку що зберігається",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/zh_CN/messages.json

@@ -159,6 +159,10 @@
 		"message": "信息栏内容模板",
 		"message": "信息栏内容模板",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "在已保存页面中将信息栏包括在内",
 		"message": "在已保存页面中将信息栏包括在内",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

+ 4 - 0
_locales/zh_TW/messages.json

@@ -159,6 +159,10 @@
 		"message": "信息欄內容模板",
 		"message": "信息欄內容模板",
 		"description": "Options page label: 'template of the infobar content'"
 		"description": "Options page label: 'template of the infobar content'"
 	},
 	},
+	"optionBlockMixedContent": {
+		"message": "block mixed content",
+		"description": "Options page label: 'block mixed content'"
+	},
 	"optionIncludeInfobar": {
 	"optionIncludeInfobar": {
 		"message": "在已保存頁面中將信息欄包括在內",
 		"message": "在已保存頁面中將信息欄包括在內",
 		"description": "Options page label: 'include the infobar in the saved page'"
 		"description": "Options page label: 'include the infobar in the saved page'"

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

@@ -112,6 +112,7 @@ const DEFAULT_CONFIG = {
 	insertMetaCSP: true,
 	insertMetaCSP: true,
 	passReferrerOnError: false,
 	passReferrerOnError: false,
 	insertSingleFileComment: true,
 	insertSingleFileComment: true,
+	blockMixedContent: false,
 	woleetKey: ""
 	woleetKey: ""
 };
 };
 
 

+ 5 - 0
extension/ui/bg/ui-options.js

@@ -113,6 +113,7 @@ const defaultEditorModeLabel = document.getElementById("defaultEditorModeLabel")
 const applySystemThemeLabel = document.getElementById("applySystemThemeLabel");
 const applySystemThemeLabel = document.getElementById("applySystemThemeLabel");
 const warnUnsavedPageLabel = document.getElementById("warnUnsavedPageLabel");
 const warnUnsavedPageLabel = document.getElementById("warnUnsavedPageLabel");
 const infobarTemplateLabel = document.getElementById("infobarTemplateLabel");
 const infobarTemplateLabel = document.getElementById("infobarTemplateLabel");
+const blockMixedContentLabel = document.getElementById("blockMixedContentLabel");
 const includeInfobarLabel = document.getElementById("includeInfobarLabel");
 const includeInfobarLabel = document.getElementById("includeInfobarLabel");
 const miscLabel = document.getElementById("miscLabel");
 const miscLabel = document.getElementById("miscLabel");
 const helpLabel = document.getElementById("helpLabel");
 const helpLabel = document.getElementById("helpLabel");
@@ -181,6 +182,7 @@ const allowedBookmarkFoldersInput = document.getElementById("allowedBookmarkFold
 const ignoredBookmarkFoldersInput = document.getElementById("ignoredBookmarkFoldersInput");
 const ignoredBookmarkFoldersInput = document.getElementById("ignoredBookmarkFoldersInput");
 const groupDuplicateImagesInput = document.getElementById("groupDuplicateImagesInput");
 const groupDuplicateImagesInput = document.getElementById("groupDuplicateImagesInput");
 const infobarTemplateInput = document.getElementById("infobarTemplateInput");
 const infobarTemplateInput = document.getElementById("infobarTemplateInput");
+const blockMixedContentInput = document.getElementById("blockMixedContentInput");
 const includeInfobarInput = document.getElementById("includeInfobarInput");
 const includeInfobarInput = document.getElementById("includeInfobarInput");
 const confirmInfobarInput = document.getElementById("confirmInfobarInput");
 const confirmInfobarInput = document.getElementById("confirmInfobarInput");
 const autoCloseInput = document.getElementById("autoCloseInput");
 const autoCloseInput = document.getElementById("autoCloseInput");
@@ -543,6 +545,7 @@ autoSaveLabel.textContent = browser.i18n.getMessage("optionsAutoSaveSubTitle");
 miscLabel.textContent = browser.i18n.getMessage("optionsMiscSubTitle");
 miscLabel.textContent = browser.i18n.getMessage("optionsMiscSubTitle");
 helpLabel.textContent = browser.i18n.getMessage("optionsHelpLink");
 helpLabel.textContent = browser.i18n.getMessage("optionsHelpLink");
 infobarTemplateLabel.textContent = browser.i18n.getMessage("optionInfobarTemplate");
 infobarTemplateLabel.textContent = browser.i18n.getMessage("optionInfobarTemplate");
+blockMixedContentLabel.textContent = browser.i18n.getMessage("optionBlockMixedContent");
 includeInfobarLabel.textContent = browser.i18n.getMessage("optionIncludeInfobar");
 includeInfobarLabel.textContent = browser.i18n.getMessage("optionIncludeInfobar");
 confirmInfobarLabel.textContent = browser.i18n.getMessage("optionConfirmInfobar");
 confirmInfobarLabel.textContent = browser.i18n.getMessage("optionConfirmInfobar");
 autoCloseLabel.textContent = browser.i18n.getMessage("optionAutoClose");
 autoCloseLabel.textContent = browser.i18n.getMessage("optionAutoClose");
@@ -752,6 +755,7 @@ async function refresh(profileName) {
 	ignoredBookmarkFoldersInput.value = profileOptions.ignoredBookmarkFolders.map(folder => folder.replace(/,/g, "\\,")).join(","); // eslint-disable-line no-useless-escape
 	ignoredBookmarkFoldersInput.value = profileOptions.ignoredBookmarkFolders.map(folder => folder.replace(/,/g, "\\,")).join(","); // eslint-disable-line no-useless-escape
 	ignoredBookmarkFoldersInput.disabled = !profileOptions.saveCreatedBookmarks;
 	ignoredBookmarkFoldersInput.disabled = !profileOptions.saveCreatedBookmarks;
 	infobarTemplateInput.value = profileOptions.infobarTemplate;
 	infobarTemplateInput.value = profileOptions.infobarTemplate;
+	blockMixedContentInput.checked = profileOptions.blockMixedContent;
 	includeInfobarInput.checked = profileOptions.includeInfobar;
 	includeInfobarInput.checked = profileOptions.includeInfobar;
 	confirmInfobarInput.checked = profileOptions.confirmInfobarContent;
 	confirmInfobarInput.checked = profileOptions.confirmInfobarContent;
 	autoCloseInput.checked = profileOptions.autoClose;
 	autoCloseInput.checked = profileOptions.autoClose;
@@ -832,6 +836,7 @@ async function update() {
 			ignoredBookmarkFolders: ignoredBookmarkFoldersInput.value.replace(/([^\\]),/g, "$1 ,").split(/[^\\],/).map(folder => folder.replace(/\\,/g, ",")),
 			ignoredBookmarkFolders: ignoredBookmarkFoldersInput.value.replace(/([^\\]),/g, "$1 ,").split(/[^\\],/).map(folder => folder.replace(/\\,/g, ",")),
 			groupDuplicateImages: groupDuplicateImagesInput.checked,
 			groupDuplicateImages: groupDuplicateImagesInput.checked,
 			infobarTemplate: infobarTemplateInput.value,
 			infobarTemplate: infobarTemplateInput.value,
+			blockMixedContent: blockMixedContentInput.checked,
 			includeInfobar: includeInfobarInput.checked,
 			includeInfobar: includeInfobarInput.checked,
 			confirmInfobarContent: confirmInfobarInput.checked,
 			confirmInfobarContent: confirmInfobarInput.checked,
 			autoClose: autoCloseInput.checked,
 			autoClose: autoCloseInput.checked,

+ 7 - 0
extension/ui/pages/help.html

@@ -219,6 +219,13 @@
 							considerably reduce the size of the file without altering the document most of the time. It
 							considerably reduce the size of the file without altering the document most of the time. It
 							may also decrease the time needed to save a page.</p>
 							may also decrease the time needed to save a page.</p>
 					</li>
 					</li>
+					<li data-options-label="blockMixedContentLabel"> <span class="option"></span>Option: block mixed
+						contents</span>
+						<p>Check this option to block active content served from HTTP when viewing a page in HTTPS. You
+							can find more information about mixed content pages <a
+								href="https://developer.mozilla.org/docs/Web/Security/Mixed_content"
+								target="_blank">here</a>.</p>
+					</li>
 					<li data-options-label="includeInfobarLabel"> <span class="option"></span>Option: include infobar in
 					<li data-options-label="includeInfobarLabel"> <span class="option"></span>Option: include infobar in
 						the saved page</span>
 						the saved page</span>
 						<p>Check this
 						<p>Check this

+ 4 - 0
extension/ui/pages/options.html

@@ -102,6 +102,10 @@
 				<label for="removeFramesInput" id="removeFramesLabel"></label>
 				<label for="removeFramesInput" id="removeFramesLabel"></label>
 				<input type="checkbox" id="removeFramesInput">
 				<input type="checkbox" id="removeFramesInput">
 			</div>
 			</div>
+			<div class="option">
+				<label for="blockMixedContentInput" id="blockMixedContentLabel"></label>
+				<input type="checkbox" id="blockMixedContentInput">
+			</div>
 			<div class="option">
 			<div class="option">
 				<label for="includeInfobarInput" id="includeInfobarLabel"></label>
 				<label for="includeInfobarInput" id="includeInfobarLabel"></label>
 				<input type="checkbox" id="includeInfobarInput">
 				<input type="checkbox" id="includeInfobarInput">

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

@@ -316,9 +316,9 @@ class BatchRequest {
 		this.duplicates = new Map();
 		this.duplicates = new Map();
 	}
 	}
 
 
-	addURL(resourceURL, asBinary, expectedType, groupDuplicates) {
+	addURL(resourceURL, { asBinary, expectedType, groupDuplicates, baseURI, blockMixedContent }) {
 		return new Promise((resolve, reject) => {
 		return new Promise((resolve, reject) => {
-			const requestKey = JSON.stringify([resourceURL, asBinary, expectedType]);
+			const requestKey = JSON.stringify([resourceURL, asBinary, expectedType, baseURI, blockMixedContent]);
 			let resourceRequests = this.requests.get(requestKey);
 			let resourceRequests = this.requests.get(requestKey);
 			if (!resourceRequests) {
 			if (!resourceRequests) {
 				resourceRequests = [];
 				resourceRequests = [];
@@ -345,7 +345,7 @@ class BatchRequest {
 		const resourceURLs = [...this.requests.keys()];
 		const resourceURLs = [...this.requests.keys()];
 		let indexResource = 0;
 		let indexResource = 0;
 		return Promise.all(resourceURLs.map(async requestKey => {
 		return Promise.all(resourceURLs.map(async requestKey => {
-			const [resourceURL, asBinary, expectedType] = JSON.parse(requestKey);
+			const [resourceURL, asBinary, expectedType, baseURI, blockMixedContent] = JSON.parse(requestKey);
 			const resourceRequests = this.requests.get(requestKey);
 			const resourceRequests = this.requests.get(requestKey);
 			try {
 			try {
 				const currentIndexResource = indexResource;
 				const currentIndexResource = indexResource;
@@ -356,7 +356,9 @@ class BatchRequest {
 					maxResourceSize: options.maxResourceSize,
 					maxResourceSize: options.maxResourceSize,
 					maxResourceSizeEnabled: options.maxResourceSizeEnabled,
 					maxResourceSizeEnabled: options.maxResourceSizeEnabled,
 					frameId: options.windowId,
 					frameId: options.windowId,
-					resourceReferrer: options.resourceReferrer
+					resourceReferrer: options.resourceReferrer,
+					baseURI,
+					blockMixedContent
 				});
 				});
 				onloadListener({ url: resourceURL });
 				onloadListener({ url: resourceURL });
 				if (!this.cancelled) {
 				if (!this.cancelled) {
@@ -930,7 +932,8 @@ class Processor {
 				updatedResources: this.options.updatedResources,
 				updatedResources: this.options.updatedResources,
 				rootDocument: this.options.rootDocument,
 				rootDocument: this.options.rootDocument,
 				frameId: this.options.windowId,
 				frameId: this.options.windowId,
-				resourceReferrer: this.options.resourceReferrer
+				resourceReferrer: this.options.resourceReferrer,
+				blockMixedContent: this.options.blockMixedContent
 			};
 			};
 			let mediaText;
 			let mediaText;
 			if (element.media) {
 			if (element.media) {
@@ -1225,7 +1228,9 @@ class Processor {
 					maxResourceSize: this.options.maxResourceSize,
 					maxResourceSize: this.options.maxResourceSize,
 					maxResourceSizeEnabled: this.options.maxResourceSizeEnabled,
 					maxResourceSizeEnabled: this.options.maxResourceSizeEnabled,
 					frameId: this.options.windowId,
 					frameId: this.options.windowId,
-					resourceReferrer: this.options.resourceReferrer
+					resourceReferrer: this.options.resourceReferrer,
+					baseURI: this.options.baseURI,
+					blockMixedContent: this.options.blockMixedContent
 				});
 				});
 				content.data = getUpdatedResourceContent(resourceURL, content, this.options);
 				content.data = getUpdatedResourceContent(resourceURL, content, this.options);
 				if (element.tagName == "SCRIPT") {
 				if (element.tagName == "SCRIPT") {
@@ -1637,7 +1642,9 @@ class ProcessorHelper {
 				validateTextContentType: true,
 				validateTextContentType: true,
 				frameId: options.frameId,
 				frameId: options.frameId,
 				charset: options.charset,
 				charset: options.charset,
-				resourceReferrer: options.resourceReferrer
+				resourceReferrer: options.resourceReferrer,
+				baseURI: options.baseURI,
+				blockMixedContent: options.blockMixedContent
 			});
 			});
 			if (!matchCharsetEquals(content.data, content.charset || options.charset)) {
 			if (!matchCharsetEquals(content.data, content.charset || options.charset)) {
 				options = Object.assign({}, options, { charset: getCharset(content.data) });
 				options = Object.assign({}, options, { charset: getCharset(content.data) });
@@ -1647,7 +1654,9 @@ class ProcessorHelper {
 					validateTextContentType: true,
 					validateTextContentType: true,
 					frameId: options.frameId,
 					frameId: options.frameId,
 					charset: options.charset,
 					charset: options.charset,
-					resourceReferrer: options.resourceReferrer
+					resourceReferrer: options.resourceReferrer,
+					baseURI: options.baseURI,
+					blockMixedContent: options.blockMixedContent
 				});
 				});
 			} else {
 			} else {
 				return content;
 				return content;
@@ -1704,7 +1713,9 @@ class ProcessorHelper {
 				charset: options.charset,
 				charset: options.charset,
 				frameId: options.frameId,
 				frameId: options.frameId,
 				resourceReferrer: options.resourceReferrer,
 				resourceReferrer: options.resourceReferrer,
-				validateTextContentType: true
+				validateTextContentType: true,
+				baseURI: baseURI,
+				blockMixedContent: options.blockMixedContent
 			});
 			});
 			if (!matchCharsetEquals(content.data, content.charset || options.charset)) {
 			if (!matchCharsetEquals(content.data, content.charset || options.charset)) {
 				options = Object.assign({}, options, { charset: getCharset(content.data) });
 				options = Object.assign({}, options, { charset: getCharset(content.data) });
@@ -1753,7 +1764,8 @@ class ProcessorHelper {
 						const resourceURL = normalizeURL(originalResourceURL);
 						const resourceURL = normalizeURL(originalResourceURL);
 						if (!testIgnoredPath(resourceURL)) {
 						if (!testIgnoredPath(resourceURL)) {
 							if (testValidURL(resourceURL)) {
 							if (testValidURL(resourceURL)) {
-								let { content } = await batchRequest.addURL(resourceURL, true, "font");
+								let { content } = await batchRequest.addURL(resourceURL,
+									{ asBinary: true, expectedType: "font", baseURI, blockMixedContent: options.blockMixedContent });
 								let resourceURLs = fontURLs.get(declaration);
 								let resourceURLs = fontURLs.get(declaration);
 								if (!resourceURLs) {
 								if (!resourceURLs) {
 									resourceURLs = [];
 									resourceURLs = [];
@@ -1793,7 +1805,8 @@ class ProcessorHelper {
 					const resourceURL = normalizeURL(originalResourceURL);
 					const resourceURL = normalizeURL(originalResourceURL);
 					if (!testIgnoredPath(resourceURL)) {
 					if (!testIgnoredPath(resourceURL)) {
 						if (testValidURL(resourceURL)) {
 						if (testValidURL(resourceURL)) {
-							let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL, true, "image", true);
+							let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL,
+								{ asBinary: true, expectedType: "image", groupDuplicates: options.groupDuplicateImages });
 							let variableDefined;
 							let variableDefined;
 							const tokens = [];
 							const tokens = [];
 							findURLToken(originalResourceURL, declaration.value.children, (token, parent, rootFunction) => {
 							findURLToken(originalResourceURL, declaration.value.children, (token, parent, rootFunction) => {
@@ -1845,7 +1858,8 @@ class ProcessorHelper {
 							// ignored
 							// ignored
 						}
 						}
 						if (testValidURL(resourceURL)) {
 						if (testValidURL(resourceURL)) {
-							let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL, true, "image", resourceElement.tagName == "IMG" && attributeName == "src");
+							let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL,
+								{ asBinary: true, expectedType: "image", groupDuplicates: options.groupDuplicateImages && resourceElement.tagName == "IMG" && attributeName == "src" });
 							if (originURL) {
 							if (originURL) {
 								if (content == EMPTY_DATA_URI) {
 								if (content == EMPTY_DATA_URI) {
 									try {
 									try {
@@ -1953,7 +1967,7 @@ class ProcessorHelper {
 							// ignored
 							// ignored
 						}
 						}
 						if (testValidURL(resourceURL)) {
 						if (testValidURL(resourceURL)) {
-							const { content } = await batchRequest.addURL(resourceURL, true, "image");
+							const { content } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image" });
 							const forbiddenPrefixFound = PREFIXES_FORBIDDEN_DATA_URI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
 							const forbiddenPrefixFound = PREFIXES_FORBIDDEN_DATA_URI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
 							if (forbiddenPrefixFound) {
 							if (forbiddenPrefixFound) {
 								return "";
 								return "";

+ 3 - 0
lib/single-file/single-file-util.js

@@ -194,6 +194,9 @@ function getInstance(utilOptions) {
 			startTime = Date.now();
 			startTime = Date.now();
 			log("  // STARTED download url =", resourceURL, "asBinary =", options.asBinary);
 			log("  // STARTED download url =", resourceURL, "asBinary =", options.asBinary);
 		}
 		}
+		if (options.blockMixedContent && /^https:/i.test(options.baseURI) && !/^https:/i.test(resourceURL)) {
+			return { data: options.asBinary ? "data:null;base64," : "", resourceURL };
+		}
 		try {
 		try {
 			if (options.frameId) {
 			if (options.frameId) {
 				try {
 				try {