Parcourir la source

add `load deferred frames` option
(fix #779), (see #1176)

Gildas il y a 2 ans
Parent
commit
60b5431cf7

+ 4 - 0
_locales/de/messages.json

@@ -279,6 +279,10 @@
 		"message": "Ereignis \"scroll\" versenden",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "Speicherung zurückgestellter Rahmen",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "Bilder für alternative Bildschirmauflösungen entfernen",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/en/messages.json

@@ -279,6 +279,10 @@
 		"message": "dispatch \"scroll\" event",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "load deferred frames",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "remove images for alternative screen resolutions",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/es/messages.json

@@ -279,6 +279,10 @@
 		"message": "enviar evento \"scroll\"",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "guardar marco (frame) diferidas",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "eliminar imágenes para resoluciones alternativas de pantalla",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/fr/messages.json

@@ -279,6 +279,10 @@
 		"message": "envoyer l'évènement \"scroll\"",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "charger les cadres différés",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "supprimer les images pour des résolutions d'écran alternatives",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/it/messages.json

@@ -279,6 +279,10 @@
 		"message": "inviare evento \"scroll\"",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "salva frame differite",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "rimuovi immagini per risoluzioni dello schermo alternative",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/ja/messages.json

@@ -279,6 +279,10 @@
 		"message": "dispatch \"scroll\" event",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "load deferred frames",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "代替画面解像度用の画像を削除します",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/pl/messages.json

@@ -283,6 +283,10 @@
 		"message": "usuwaj obrazy dla alternatywnych rozdzielczości ekranu",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "zapisuj odroczone ramki",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionsFontsSubTitle": {
 		"message": "Czcionki",
 		"description": "Options sub-title: 'Fonts'"

+ 4 - 0
_locales/pt_br/messages.json

@@ -279,6 +279,10 @@
 		"message": "dispatch \"scroll\" event",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "salvar frames diferidas",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "remover imagens para resoluções alternativas de tela",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/ru/messages.json

@@ -279,6 +279,10 @@
 		"message": "отправить команду прокрутки",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "сохранить отложенные фреймы",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "удалить изображения для альтернативных разрешений экрана",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/tr/messages.json

@@ -279,6 +279,10 @@
 		"message": "\"scroll\" olayını gönder",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "ertelenen çerçeveleri kaydet",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "alternatif ekran çözünürlükleri için görüntüleri kaldır",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/uk/messages.json

@@ -279,6 +279,10 @@
 		"message": "відправка події \"прокрутка\"",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "зберегти відстрочені фрейми",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "видалити зображення для альтернативних розширень екрану ",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/zh_CN/messages.json

@@ -279,6 +279,10 @@
 		"message": "触发滚动事件",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "load deferred frames",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "移除用于备选分辨率的图片",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

+ 4 - 0
_locales/zh_TW/messages.json

@@ -279,6 +279,10 @@
 		"message": "觸發滾動事件",
 		"description": "Options page label: 'dispatch \"scroll\" event'"
 	},
+	"optionLoadDeferredImagesBeforeFrames": {
+		"message": "load deferred frames",
+		"description": "Options page label: 'load deferred frames'"
+	},
 	"optionRemoveAlternativeImages": {
 		"message": "移除用於備選分辨率的圖片",
 		"description": "Options page label: 'remove images for alternative screen resolutions'"

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

@@ -58,6 +58,7 @@ const DEFAULT_CONFIG = {
 	loadDeferredImagesBlockStorage: false,
 	loadDeferredImagesKeepZoomLevel: false,
 	loadDeferredImagesDispatchScrollEvent: false,
+	loadDeferredImagesBeforeFrames: false,
 	filenameTemplate: "{page-title} ({date-locale} {time-locale}).html",
 	infobarTemplate: "",
 	includeInfobar: !INFOBAR_SUPPORTED,

+ 53 - 37
src/core/content/content.js

@@ -21,7 +21,7 @@
  *   Source.
  */
 
-/* global browser, document, globalThis, location, setTimeout */
+/* global browser, document, globalThis, location */
 
 import * as download from "./../common/download.js";
 import { fetch, frameFetch } from "./../../lib/single-file/fetch/content/content-fetch.js";
@@ -121,33 +121,6 @@ async function processPage(options) {
 	processor = new singlefile.SingleFile(options);
 	const preInitializationPromises = [];
 	options.insertCanonicalLink = true;
-	if (!options.saveRawPage) {
-		if (!options.removeFrames && frames && globalThis.frames && globalThis.frames.length) {
-			let frameTreePromise;
-			if (options.loadDeferredImages) {
-				frameTreePromise = new Promise(resolve => setTimeout(() => resolve(frames.getAsync(options)), options.loadDeferredImagesMaxIdleTime - frames.TIMEOUT_INIT_REQUEST_MESSAGE));
-			} else {
-				frameTreePromise = frames.getAsync(options);
-			}
-			ui.onLoadingFrames(options);
-			frameTreePromise.then(() => {
-				if (!processor.cancelled) {
-					ui.onLoadFrames(options);
-				}
-			});
-			preInitializationPromises.push(frameTreePromise);
-		}
-		if (options.loadDeferredImages) {
-			const lazyLoadPromise = singlefile.processors.lazy.process(options);
-			ui.onLoadingDeferResources(options);
-			lazyLoadPromise.then(() => {
-				if (!processor.cancelled) {
-					ui.onLoadDeferResources(options);
-				}
-			});
-			preInitializationPromises.push(lazyLoadPromise);
-		}
-	}
 	let index = 0, maxIndex = 0;
 	options.onprogress = event => {
 		if (!processor.cancelled) {
@@ -184,15 +157,58 @@ async function processPage(options) {
 			}
 		}
 	};
-	[options.frames] = await new Promise(resolve => {
-		const preInitializationAllPromises = Promise.all(preInitializationPromises);
-		const cancelProcessor = processor.cancel.bind(processor);
-		processor.cancel = function () {
-			cancelProcessor();
-			resolve([[]]);
-		};
-		preInitializationAllPromises.then(() => resolve(preInitializationAllPromises));
-	});
+	const cancelProcessor = processor.cancel.bind(processor);
+	if (!options.saveRawPage) {
+		if (options.loadDeferredImages) {
+			const lazyLoadPromise = singlefile.processors.lazy.process(options);
+			ui.onLoadingDeferResources(options);
+			lazyLoadPromise.then(() => {
+				if (!processor.cancelled) {
+					ui.onLoadDeferResources(options);
+				}
+			});
+			if (options.loadDeferredImagesBeforeFrames) {
+				await lazyLoadPromise;
+			} else {
+				preInitializationPromises.push(lazyLoadPromise);
+			}
+		}
+		if (!options.removeFrames && frames && globalThis.frames) {
+			let frameTreePromise;
+			if (options.loadDeferredImages) {
+				frameTreePromise = new Promise(resolve => globalThis.setTimeout(() => resolve(frames.getAsync(options)), options.loadDeferredImagesBeforeFrames ? 0 : options.loadDeferredImagesMaxIdleTime / 2));
+			} else {
+				frameTreePromise = frames.getAsync(options);
+			}
+			ui.onLoadingFrames(options);
+			frameTreePromise.then(() => {
+				if (!processor.cancelled) {
+					ui.onLoadFrames(options);
+				}
+			});
+			if (options.loadDeferredImagesBeforeFrames) {
+				options.frames = await new Promise(resolve => {
+					processor.cancel = function () {
+						cancelProcessor();
+						resolve([]);
+					};
+					frameTreePromise.then(resolve);
+				});
+			} else {
+				preInitializationPromises.push(frameTreePromise);
+			}
+		}
+	}
+	if (!options.loadDeferredImagesBeforeFrames) {
+		[,options.frames] = await new Promise(resolve => {
+			const preInitializationAllPromises = Promise.all(preInitializationPromises);
+			processor.cancel = function () {
+				cancelProcessor();
+				resolve([[]]);
+			};
+			preInitializationAllPromises.then(() => resolve(preInitializationAllPromises));
+		});
+	}
 	framesSessionId = options.frames && options.frames.sessionId;
 	const selectedFrame = options.frames && options.frames.find(frameData => frameData.requestedFrame);
 	options.win = globalThis;

+ 6 - 0
src/ui/bg/ui-options.js

@@ -97,6 +97,7 @@ const loadDeferredImagesLabel = document.getElementById("loadDeferredImagesLabel
 const loadDeferredImagesMaxIdleTimeLabel = document.getElementById("loadDeferredImagesMaxIdleTimeLabel");
 const loadDeferredImagesKeepZoomLevelLabel = document.getElementById("loadDeferredImagesKeepZoomLevelLabel");
 const loadDeferredImagesDispatchScrollEventLabel = document.getElementById("loadDeferredImagesDispatchScrollEventLabel");
+const loadDeferredImagesBeforeFramesLabel = document.getElementById("loadDeferredImagesBeforeFramesLabel");
 const addMenuEntryLabel = document.getElementById("addMenuEntryLabel");
 const filenameTemplateLabel = document.getElementById("filenameTemplateLabel");
 const filenameMaxLengthLabel = document.getElementById("filenameMaxLengthLabel");
@@ -221,6 +222,7 @@ const loadDeferredImagesInput = document.getElementById("loadDeferredImagesInput
 const loadDeferredImagesMaxIdleTimeInput = document.getElementById("loadDeferredImagesMaxIdleTimeInput");
 const loadDeferredImagesKeepZoomLevelInput = document.getElementById("loadDeferredImagesKeepZoomLevelInput");
 const loadDeferredImagesDispatchScrollEventInput = document.getElementById("loadDeferredImagesDispatchScrollEventInput");
+const loadDeferredImagesBeforeFramesInput = document.getElementById("loadDeferredImagesBeforeFramesInput");
 const contextMenuEnabledInput = document.getElementById("contextMenuEnabledInput");
 const filenameTemplateInput = document.getElementById("filenameTemplateInput");
 const filenameMaxLengthInput = document.getElementById("filenameMaxLengthInput");
@@ -595,6 +597,7 @@ loadDeferredImagesLabel.textContent = browser.i18n.getMessage("optionLoadDeferre
 loadDeferredImagesMaxIdleTimeLabel.textContent = browser.i18n.getMessage("optionLoadDeferredImagesMaxIdleTime");
 loadDeferredImagesKeepZoomLevelLabel.textContent = browser.i18n.getMessage("optionLoadDeferredImagesKeepZoomLevel");
 loadDeferredImagesDispatchScrollEventLabel.textContent = browser.i18n.getMessage("optionLoadDeferredImagesDispatchScrollEvent");
+loadDeferredImagesBeforeFramesLabel.textContent = browser.i18n.getMessage("optionLoadDeferredImagesBeforeFrames");
 addMenuEntryLabel.textContent = browser.i18n.getMessage("optionAddMenuEntry");
 filenameTemplateLabel.textContent = browser.i18n.getMessage("optionFilenameTemplate");
 filenameMaxLengthLabel.textContent = browser.i18n.getMessage("optionFilenameMaxLength");
@@ -880,6 +883,8 @@ async function refresh(profileName) {
 	loadDeferredImagesMaxIdleTimeInput.disabled = !profileOptions.loadDeferredImages;
 	loadDeferredImagesDispatchScrollEventInput.checked = profileOptions.loadDeferredImagesDispatchScrollEvent;
 	loadDeferredImagesDispatchScrollEventInput.disabled = !profileOptions.loadDeferredImages;
+	loadDeferredImagesBeforeFramesInput.checked = profileOptions.loadDeferredImagesBeforeFrames;
+	loadDeferredImagesBeforeFramesInput.disabled = !profileOptions.loadDeferredImages;
 	contextMenuEnabledInput.checked = profileOptions.contextMenuEnabled;
 	filenameTemplateInput.value = profileOptions.filenameTemplate;
 	filenameMaxLengthInput.value = profileOptions.filenameMaxLength;
@@ -993,6 +998,7 @@ async function update() {
 			loadDeferredImagesMaxIdleTime: Math.max(loadDeferredImagesMaxIdleTimeInput.value, 0),
 			loadDeferredImagesKeepZoomLevel: loadDeferredImagesKeepZoomLevelInput.checked,
 			loadDeferredImagesDispatchScrollEvent: loadDeferredImagesDispatchScrollEventInput.checked,
+			loadDeferredImagesBeforeFrames: loadDeferredImagesBeforeFramesInput.checked,
 			contextMenuEnabled: contextMenuEnabledInput.checked,
 			filenameTemplate: filenameTemplateInput.value,
 			filenameMaxLength: filenameMaxLengthInput.value,

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

@@ -326,6 +326,13 @@
 							saving pages using infinite virtual lists for example. </p>
 						<p class="notice">It is recommended to <u>uncheck</u> this option</p>
 					</li>
+					<li data-options-label="loadDeferredImagesBeforeFramesLabel"> <span class="option">Option: load
+							deferred frames</span>
+						<p>Check this option to load deferred frames and images before saving frame contents. It will
+							increase the time needed to save a page.
+						</p>
+						<p class="notice">It is recommended to <u>uncheck</u> this option</p>
+					</li>
 					<li data-options-label="removeAlternativeImagesLabel"> <span class="option">Option: remove images
 							for alternative screen resolutions</span>
 						<p>Check this option to remove images that are alternatives in lower and/or higher resolutions

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

@@ -171,6 +171,10 @@
 				<label for="loadDeferredImagesKeepZoomLevelInput" id="loadDeferredImagesKeepZoomLevelLabel"></label>
 				<input type="checkbox" id="loadDeferredImagesKeepZoomLevelInput">
 			</div>
+			<div class="option second-level">
+				<label for="loadDeferredImagesBeforeFramesInput" id="loadDeferredImagesBeforeFramesLabel"></label>
+				<input type="checkbox" id="loadDeferredImagesBeforeFramesInput">
+			</div>
 			<div class="option">
 				<label for="removeAlternativeImagesInput" id="removeAlternativeImagesLabel"></label>
 				<input type="checkbox" id="removeAlternativeImagesInput">