Explorar o código

added option "Annotation editor > warn if leaving page with unsaved changes"

Gildas %!s(int64=5) %!d(string=hai) anos
pai
achega
82a73e93eb

+ 24 - 16
_locales/de/messages.json

@@ -155,14 +155,6 @@
 		"message": "Inhalt des Infoknopfs im Dialogfenster eingeben",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "annotate the page before saving",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "open pages saved with SingleFile in the annotation editor",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "Automatisches Schließen des Tabs nach dem Speichern der Seite",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -200,10 +192,10 @@
 		"description": "Value for 'name conflict resolution' option: 'prompt for a name'"
 	},
 	"optionFilenameConflictActionSkip": {
-        "message": "Überspringen doppelter Dateien",
-        "description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
-    },
-    "optionsHTMLContentSubTitle": {
+		"message": "Überspringen doppelter Dateien",
+		"description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
+	},
+	"optionsHTMLContentSubTitle": {
 		"message": "HTML-Inhalt",
 		"description": "Options sub-title: 'HTML content'"
 	},
@@ -375,6 +367,26 @@
 		"message": "Zeitraum (s.)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "annotate the page before saving",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "open pages saved with SingleFile in the annotation editor",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "apply the system theme when formatting a page",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "Warnen beim Verlassen der Seite mit ungespeicherten Änderungen",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "Sonstiges",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "Speicherung der Seiten im Hintergrund",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "apply the system theme when formatting a page in the annotation editor",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "Statistik nach Verarbeitung in der Konsole anzeigen",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 20 - 12
_locales/en/messages.json

@@ -155,14 +155,6 @@
 		"message": "open a prompt dialog to edit the infobar content",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "annotate the page before saving",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "open pages saved with SingleFile in the annotation editor",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "auto-close the tab after the page is saved",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -375,6 +367,26 @@
 		"message": "period (s.)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "annotate the page before saving",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "open pages saved with SingleFile in the annotation editor",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "apply the system theme when formatting a page",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "Misc.",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "save pages in background",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "apply the system theme when formatting a page in the annotation editor",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "display stats in the console after processing",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 20 - 12
_locales/es/messages.json

@@ -155,14 +155,6 @@
 		"message": "abrir un cuadro de diálogo para editar el contenido de la barra informativa",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "annotate the page before saving",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "open pages saved with SingleFile in the annotation editor",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "cerrar automáticamente la pestaña después de guardar la página",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -375,6 +367,26 @@
 		"message": "periodo (s)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "annotate the page before saving",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "open pages saved with SingleFile in the annotation editor",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "apply the system theme when formatting a page",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "Miscelánea",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "guardar páginas en segundo plano",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "apply the system theme when formatting a page in the annotation editor",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "mostrar estadísticas en la consola tras el procesado",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 20 - 12
_locales/fr/messages.json

@@ -155,14 +155,6 @@
 		"message": "ouvrir une boite de dialogue pour éditer le contenu de la barre d'information",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "annoter la page avant de la sauvegarder",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "ouvrir les pages sauvées avec SingleFile dans l'éditeur d'annotations",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "fermer automatiquement l'onglet après l'enregistrement de la page",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -375,6 +367,26 @@
 		"message": "période (s)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Éditeur d'annotations",
+		"description": "Options sub-title: 'Éditeur d'annotations'"
+	},
+	"optionOpenEditor": {
+		"message": "annoter la page avant de la sauvegarder",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "ouvrir les pages sauvées avec SingleFile dans l'éditeur d'annotations",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "appliquer le thème système lors du formattage d'une page",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "avertir si l'on quitte la page avec des modifications non sauvegardées",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "Divers",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "sauvegarder la page en tâche de fond",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "appliquer le thème système lors du formattage d'une page dans l'éditeur  d'annotations",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "afficher les statistiques dans la console après la sauvegarde",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 20 - 12
_locales/ja/messages.json

@@ -155,14 +155,6 @@
 		"message": "infobar のコンテンツを編集するためのプロンプトダイアログを開く",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "保存する前にページに注釈を付けます",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "annotation editor で、SingleFile で保存されたページを開く",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "ページが保存された後にタブを自動的に閉じる",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -375,6 +367,26 @@
 		"message": "所要時間(秒)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "注釈エディタ",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "保存する前にページに注釈を付けます",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "annotation editor で、SingleFile で保存されたページを開く",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "ページの書式設定時にシステムテーマを適用する",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "その他",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "バックグラウンドでページを保存する",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "(注釈エディタ)でページをフォーマットするときにシステムテーマを適用する",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "処理後、コンソールに統計情報を表示する",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 20 - 12
_locales/pl/messages.json

@@ -155,14 +155,6 @@
 		"message": "otwieraj okno dialogowe z monitem, aby edytować zawartość paska informacyjnego",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "adnotuj stronę przed zapisaniem",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "otwieraj strony zapisane z SingleFile w edytorze adnotacji",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "automatycznie zamykaj kartę po zapisaniu strony",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -375,6 +367,26 @@
 		"message": "okres (s)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "adnotuj stronę przed zapisaniem",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "otwieraj strony zapisane z SingleFile w edytorze adnotacji",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "zastosuj motyw systemowy podczas formatowania strony",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "Różne",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "zapisuj strony w tle",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "zastosuj motyw systemowy podczas formatowania strony w edytorze adnotacji",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "wyświetlaj statystyki w konsoli po przetworzeniu",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 21 - 13
_locales/ru/messages.json

@@ -155,14 +155,6 @@
 		"message": "открыть диалоговое окно для редактирования содержимого информационной панели",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "аннотировать страницу перед сохранением",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "сохранять открытые страницы из редактора аннотаций SingleFile",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "автозакрытие вкладки после сохранения страницы",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -375,6 +367,26 @@
 		"message": "период (сек.)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "аннотировать страницу перед сохранением",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "сохранять открытые страницы из редактора аннотаций SingleFile",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "использовать системную тему при форматировании страницы",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "Разное",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "сохранять страницы в фоновом режиме",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "использовать системную тему при форматировании страницы в редакторе аннотаций",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "показать статистику в консоли после обработки",
 		"description": "Options page label: 'display stats in the console after processing'"
@@ -639,4 +647,4 @@
 		"message": "Отмена",
 		"description": "Add URLs popup cancel button: 'Cancel'"
 	}
-}
+}

+ 24 - 16
_locales/uk/messages.json

@@ -155,14 +155,6 @@
 		"message": "відкривати діалогове вікно для редагування вмісту інформаційної панелі",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "анотувати сторінки перед збереженням",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "open pages saved with SingleFile in the annotation editor",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "автоматично закривати вкладку після збереження сторінки",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -200,10 +192,10 @@
 		"description": "Value for 'name conflict resolution' option: 'prompt for a name'"
 	},
 	"optionFilenameConflictActionSkip": {
-        "message": "skip duplicate files",
-        "description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
-    },
-    "optionsHTMLContentSubTitle": {
+		"message": "skip duplicate files",
+		"description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
+	},
+	"optionsHTMLContentSubTitle": {
 		"message": "HTML-вміст",
 		"description": "Options sub-title: 'HTML content'"
 	},
@@ -375,6 +367,26 @@
 		"message": "період (с.)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "анотувати сторінки перед збереженням",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "open pages saved with SingleFile in the annotation editor",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "apply the system theme when formatting a page",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "Різне",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "зберігати сторінки у фоновому режимі",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "apply the system theme when formatting a page in the annotation editor",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "відображати статистику в консолі після обробки",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 24 - 16
_locales/zh_CN/messages.json

@@ -155,14 +155,6 @@
 		"message": "打开一个提示对话框来编辑信息栏内容",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "在保存前对该页面进行标注编辑",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "在标注编辑器中打开用 SingleFile 保存的页面",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "页面保存后自动关闭该标签页",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -200,10 +192,10 @@
 		"description": "Value for 'name conflict resolution' option: 'prompt for a name'"
 	},
 	"optionFilenameConflictActionSkip": {
-        "message": "跳过重复文件",
-        "description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
-    },
-    "optionsHTMLContentSubTitle": {
+		"message": "跳过重复文件",
+		"description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
+	},
+	"optionsHTMLContentSubTitle": {
 		"message": "HTML 内容",
 		"description": "Options sub-title: 'HTML content'"
 	},
@@ -375,6 +367,26 @@
 		"message": "周期(秒)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "在保存前对该页面进行标注编辑",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "在标注编辑器中打开用 SingleFile 保存的页面",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "在标注编辑器中打开页面时应用系统主题样式",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "杂项",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "在后台保存页面",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "在标注编辑器中打开页面时应用系统主题样式",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "处理完成后在控制台中显示统计数据",
 		"description": "Options page label: 'display stats in the console after processing'"

+ 24 - 16
_locales/zh_TW/messages.json

@@ -155,14 +155,6 @@
 		"message": "打開一個提示對話框來編輯信息欄內容",
 		"description": "Options page label: 'open a prompt dialog to edit the infobar content'"
 	},
-	"optionOpenEditor": {
-		"message": "在保存前對該頁面進行標註編輯",
-		"description": "Options page label: 'annotate the page before saving'"
-	},
-	"optionAutoOpenEditor": {
-		"message": "在標註編輯器中打開用 SingleFile 保存的頁面",
-		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
-	},
 	"optionAutoClose": {
 		"message": "頁面保存後自動關閉該標籤頁",
 		"description": "Options page label: 'auto-close the tab after the page is saved'"
@@ -200,10 +192,10 @@
 		"description": "Value for 'name conflict resolution' option: 'prompt for a name'"
 	},
 	"optionFilenameConflictActionSkip": {
-        "message": "跳過重複文件",
-        "description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
-    },
-    "optionsHTMLContentSubTitle": {
+		"message": "跳過重複文件",
+		"description": "Value for 'filename conflict resolution' option: 'skip duplicate files'"
+	},
+	"optionsHTMLContentSubTitle": {
 		"message": "HTML 內容",
 		"description": "Options sub-title: 'HTML content'"
 	},
@@ -375,6 +367,26 @@
 		"message": "週期(秒)",
 		"description": "Options page label: 'period (s)'"
 	},
+	"optionsEditorSubTitle": {
+		"message": "Annotation editor",
+		"description": "Options sub-title: 'Annotation editor'"
+	},
+	"optionOpenEditor": {
+		"message": "在保存前對該頁面進行標註編輯",
+		"description": "Options page label: 'annotate the page before saving'"
+	},
+	"optionAutoOpenEditor": {
+		"message": "在標註編輯器中打開用 SingleFile 保存的頁面",
+		"description": "Options page label: 'open pages saved with SingleFile in the annotation editor'"
+	},
+	"optionApplySystemTheme": {
+		"message": "在標註編輯器中打開頁面時應用系統主題樣式",
+		"description": "Title of the button 'apply the system theme when formatting a page'"
+	},
+	"optionWarnUnsavedPage": {
+		"message": "warn if leaving page with unsaved changes",
+		"description": "Title of the button 'warn if leaving page with unsaved changes'"
+	},
 	"optionsMiscSubTitle": {
 		"message": "雜項",
 		"description": "Options sub-title: 'Misc.'"
@@ -383,10 +395,6 @@
 		"message": "在後臺保存頁面",
 		"description": "Options page label: 'save pages in background'"
 	},
-	"optionApplySystemTheme": {
-		"message": "在標註編輯器中打開頁面時應用系統主題樣式",
-		"description": "Title of the button 'apply the system theme when formatting a page in the annotation editor"
-	},
 	"optionDisplayStats": {
 		"message": "處理完成後在控制檯中顯示統計數據",
 		"description": "Options page label: 'display stats in the console after processing'"

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

@@ -92,7 +92,8 @@ singlefile.extension.core.bg.config = (() => {
 		ignoredBookmarkFolders: [],
 		replaceBookmarkURL: true,
 		saveFavicon: true,
-		includeBOM: false
+		includeBOM: false,
+		warnUnsavedPage: true
 	};
 
 	let configStorage;

+ 10 - 0
extension/ui/bg/ui-editor.js

@@ -191,8 +191,17 @@ singlefile.extension.ui.bg.editor = (() => {
 		if (message.method == "disableFormatPage") {
 			formatPageButton.remove();
 		}
+		if (message.method == "onUpdate") {
+			tabData.docSaved = message.saved;
+		}
 	};
 	window.onload = browser.runtime.sendMessage({ method: "editor.getTabData" });
+	window.onbeforeunload = event => {
+		if (tabData.options.warnUnsavedPage && !tabData.docSaved) {
+			event.preventDefault();
+			event.returnValue = "";
+		}
+	};
 
 	browser.runtime.onMessage.addListener(message => {
 		if (message.method == "content.save") {
@@ -213,6 +222,7 @@ singlefile.extension.ui.bg.editor = (() => {
 			}
 			if (!message.truncated || message.finished) {
 				tabData = JSON.parse(tabDataContents.join(""));
+				tabData.docSaved = true;
 				tabDataContents = [];
 				editorElement.contentWindow.postMessage(JSON.stringify({ method: "init", content: tabData.content }), "*");
 				delete tabData.content;

+ 13 - 6
extension/ui/bg/ui-options.js

@@ -60,7 +60,6 @@
 	const displayInfobarLabel = document.getElementById("displayInfobarLabel");
 	const displayStatsLabel = document.getElementById("displayStatsLabel");
 	const backgroundSaveLabel = document.getElementById("backgroundSaveLabel");
-	const applySystemThemeLabel = document.getElementById("applySystemThemeLabel");
 	const autoSaveDelayLabel = document.getElementById("autoSaveDelayLabel");
 	const autoSaveLoadLabel = document.getElementById("autoSaveLoadLabel");
 	const autoSaveUnloadLabel = document.getElementById("autoSaveUnloadLabel");
@@ -90,8 +89,11 @@
 	const groupDuplicateImagesLabel = document.getElementById("groupDuplicateImagesLabel");
 	const confirmInfobarLabel = document.getElementById("confirmInfobarLabel");
 	const autoCloseLabel = document.getElementById("autoCloseLabel");
+	const editorLabel = document.getElementById("editorLabel");
 	const openEditorLabel = document.getElementById("openEditorLabel");
 	const autoOpenEditorLabel = document.getElementById("autoOpenEditorLabel");
+	const applySystemThemeLabel = document.getElementById("applySystemThemeLabel");
+	const warnUnsavedPageLabel = document.getElementById("warnUnsavedPageLabel");
 	const infobarTemplateLabel = document.getElementById("infobarTemplateLabel");
 	const includeInfobarLabel = document.getElementById("includeInfobarLabel");
 	const miscLabel = document.getElementById("miscLabel");
@@ -133,7 +135,6 @@
 	const displayInfobarInput = document.getElementById("displayInfobarInput");
 	const displayStatsInput = document.getElementById("displayStatsInput");
 	const backgroundSaveInput = document.getElementById("backgroundSaveInput");
-	const applySystemThemeInput = document.getElementById("applySystemThemeInput");
 	const autoSaveDelayInput = document.getElementById("autoSaveDelayInput");
 	const autoSaveLoadInput = document.getElementById("autoSaveLoadInput");
 	const autoSaveUnloadInput = document.getElementById("autoSaveUnloadInput");
@@ -152,6 +153,8 @@
 	const autoCloseInput = document.getElementById("autoCloseInput");
 	const openEditorInput = document.getElementById("openEditorInput");
 	const autoOpenEditorInput = document.getElementById("autoOpenEditorInput");
+	const applySystemThemeInput = document.getElementById("applySystemThemeInput");
+	const warnUnsavedPageInput = document.getElementById("warnUnsavedPageInput");
 	const expandAllButton = document.getElementById("expandAllButton");
 	const rulesDeleteAllButton = document.getElementById("rulesDeleteAllButton");
 	const ruleUrlInput = document.getElementById("ruleUrlInput");
@@ -457,7 +460,6 @@
 	displayInfobarLabel.textContent = browser.i18n.getMessage("optionDisplayInfobar");
 	displayStatsLabel.textContent = browser.i18n.getMessage("optionDisplayStats");
 	backgroundSaveLabel.textContent = browser.i18n.getMessage("optionBackgroundSave");
-	applySystemThemeLabel.textContent = browser.i18n.getMessage("optionApplySystemTheme");
 	autoSaveDelayLabel.textContent = browser.i18n.getMessage("optionAutoSaveDelay");
 	autoSaveLoadLabel.textContent = browser.i18n.getMessage("optionAutoSaveLoad");
 	autoSaveUnloadLabel.textContent = browser.i18n.getMessage("optionAutoSaveUnload");
@@ -485,8 +487,11 @@
 	includeInfobarLabel.textContent = browser.i18n.getMessage("optionIncludeInfobar");
 	confirmInfobarLabel.textContent = browser.i18n.getMessage("optionConfirmInfobar");
 	autoCloseLabel.textContent = browser.i18n.getMessage("optionAutoClose");
+	editorLabel.textContent = browser.i18n.getMessage("optionsEditorSubTitle");
 	openEditorLabel.textContent = browser.i18n.getMessage("optionOpenEditor");
 	autoOpenEditorLabel.textContent = browser.i18n.getMessage("optionAutoOpenEditor");
+	applySystemThemeLabel.textContent = browser.i18n.getMessage("optionApplySystemTheme");
+	warnUnsavedPageLabel.textContent = browser.i18n.getMessage("optionWarnUnsavedPage");
 	resetButton.textContent = browser.i18n.getMessage("optionsResetButton");
 	exportButton.textContent = browser.i18n.getMessage("optionsExportButton");
 	importButton.textContent = browser.i18n.getMessage("optionsImportButton");
@@ -644,7 +649,6 @@
 		displayStatsInput.checked = profileOptions.displayStats;
 		backgroundSaveInput.checked = profileOptions.backgroundSave;
 		backgroundSaveInput.disabled = profileOptions.saveToGDrive;
-		applySystemThemeInput.checked = profileOptions.applySystemTheme;
 		autoSaveDelayInput.value = profileOptions.autoSaveDelay;
 		autoSaveDelayInput.disabled = !profileOptions.autoSaveLoadOrUnload && !profileOptions.autoSaveLoad;
 		autoSaveLoadInput.checked = !profileOptions.autoSaveLoadOrUnload && profileOptions.autoSaveLoad;
@@ -669,6 +673,8 @@
 		autoCloseInput.checked = profileOptions.autoClose;
 		openEditorInput.checked = profileOptions.openEditor;
 		autoOpenEditorInput.checked = profileOptions.autoOpenEditor;
+		applySystemThemeInput.checked = profileOptions.applySystemTheme;
+		warnUnsavedPageInput.checked = profileOptions.warnUnsavedPage;
 		removeFramesInput.disabled = saveRawPageInput.checked;
 		removeFramesInput.checked = removeFramesInput.checked || saveRawPageInput.checked;
 		loadDeferredImagesInput.disabled = saveRawPageInput.checked;
@@ -715,7 +721,6 @@
 				displayInfobar: displayInfobarInput.checked,
 				displayStats: displayStatsInput.checked,
 				backgroundSave: backgroundSaveInput.checked,
-				applySystemTheme: applySystemThemeInput.checked,
 				autoSaveDelay: Math.max(autoSaveDelayInput.value, 0),
 				autoSaveLoad: autoSaveLoadInput.checked,
 				autoSaveUnload: autoSaveUnloadInput.checked,
@@ -733,7 +738,9 @@
 				confirmInfobarContent: confirmInfobarInput.checked,
 				autoClose: autoCloseInput.checked,
 				openEditor: openEditorInput.checked,
-				autoOpenEditor: autoOpenEditorInput.checked
+				autoOpenEditor: autoOpenEditorInput.checked,
+				applySystemTheme: applySystemThemeInput.checked,
+				warnUnsavedPage: warnUnsavedPageInput.checked
 			}
 		});
 		await pendingSave;

+ 15 - 1
extension/ui/content/content-ui-editor-web.js

@@ -844,8 +844,9 @@ table {
 		if (message.method == "disableRemoveHighlights") {
 			removeHighlightMode = false;
 		}
-		if (message.method == "enableEditPage") {
+		if (message.method == "enableEditPage") {			
 			document.body.contentEditable = true;
+			onUpdate(false);
 		}
 		if (message.method == "formatPage") {
 			formatPage(true);
@@ -877,6 +878,7 @@ table {
 			}
 		}
 		if (message.method == "getContent") {
+			onUpdate(true);
 			getContent(message.compressHTML);
 		}
 	};
@@ -971,6 +973,7 @@ table {
 		document.documentElement.insertBefore(containerElement, maskPageElement.getRootNode().host);
 		noteElement.classList.add(NOTE_SELECTED_CLASS);
 		selectedNote = noteElement;
+		onUpdate(false);
 	}
 
 	function attachNoteListeners(containerElement, editable = false) {
@@ -1038,6 +1041,7 @@ table {
 				deleteNoteRef(containerElement, noteId);
 				addNoteRef(document.documentElement, noteId);
 			}
+			onUpdate(false);
 		};
 		removeNoteElement.ontouchend = removeNoteElement.onclick = event => {
 			event.preventDefault();
@@ -1144,6 +1148,7 @@ table {
 	function onMouseUp(event) {
 		if (highlightSelectionMode) {
 			highlightSelection();
+			onUpdate(false);
 		}
 		if (removeHighlightMode) {
 			let element = event.target, done;
@@ -1151,6 +1156,7 @@ table {
 				if (element.classList.contains(HIGHLIGHT_CLASS)) {
 					document.querySelectorAll("." + HIGHLIGHT_CLASS + "[data-singlefile-highlight-id=" + JSON.stringify(element.dataset.singlefileHighlightId) + "]").forEach(highlightedElement => {
 						resetHighlightedElement(highlightedElement);
+						onUpdate(false);
 					});
 					done = true;
 				}
@@ -1162,11 +1168,13 @@ table {
 			document.documentElement.style.removeProperty("user-select");
 			maskPageElement.classList.remove(PAGE_MASK_ACTIVE_CLASS);
 			document.documentElement.ontouchmove = document.documentElement.onmousemove = null;
+			onUpdate(false);
 		}
 		if (movingNoteMode) {
 			anchorNote(movingNoteMode.event || event, selectedNote, movingNoteMode.deltaX, movingNoteMode.deltaY);
 			movingNoteMode = null;
 			document.documentElement.ontouchmove = document.documentElement.onmousemove = null;
+			onUpdate(false);
 		}
 		if (collapseNoteTimeout) {
 			clearTimeout(collapseNoteTimeout);
@@ -1177,6 +1185,7 @@ table {
 			if (document.documentElement != element && element.tagName.toLowerCase() != NOTE_TAGNAME) {
 				element.classList.add(REMOVED_CONTENT_CLASS);
 				removedElements.push(element);
+				onUpdate(false);
 			}
 		}
 	}
@@ -1368,6 +1377,7 @@ table {
 		maskPageElement = getMaskElement(PAGE_MASK_CLASS, PAGE_MASK_CONTAINER_CLASS);
 		maskNoteElement = getMaskElement(NOTE_MASK_CLASS);
 		reflowNotes();
+		onUpdate(false);
 	}
 
 	function getContent(compressHTML) {
@@ -1404,6 +1414,10 @@ table {
 		window.parent.postMessage(JSON.stringify({ "method": "setContent", content: singlefile.lib.modules.serializer.process(doc, compressHTML) }), "*");
 	}
 
+	function onUpdate(saved) {
+		window.parent.postMessage(JSON.stringify({ "method": "onUpdate", saved }), "*");
+	}
+
 	function reflowNotes() {
 		document.querySelectorAll(NOTE_TAGNAME).forEach(containerElement => {
 			const noteElement = containerElement.shadowRoot.querySelector("." + NOTE_CLASS);

+ 27 - 18
extension/ui/pages/help.html

@@ -124,18 +124,6 @@
 								a page having "Example Domain" as title.</li>
 						</ul>
 					</li>
-					<li data-options-label="openEditorLabel"> <span class="option">Option: edit page before
-							saving</span>
-						<p>Check this option to open the annotation editor before saving any page. Checking this option
-							removes the entry "Annotate and save the page..." from the context menu.</p>
-						<p class="notice">It is recommended to <u>uncheck</u> this option</p>
-					</li>
-					<li data-options-label="autoOpenEditorLabel"> <span class="option">Option: open the annotation
-							editor when viewing a page saved with SingleFile </span>
-						<p>Check this option to open the annotation editor when displaying a page saved by SingleFile.
-						</p>
-						<p class="notice">It is recommended to <u>uncheck</u> this option</p>
-					</li>
 					<li data-options-label="confirmInfobarLabel"> <span class="option">Option: open a prompt dialog to
 							edit the infobar content</span>
 						<p>Check this option to display a prompt dialog in order to confirm the infobar content before
@@ -345,6 +333,33 @@
 							periodically" option is checked. </p>
 					</li>
 				</ul>
+				<p>Annotation editor</p>
+				<ul>
+					<li data-options-label="applySystemThemeLabel"> <span class="option">Option: apply the system theme
+							when formatting a page in the annotation editor</span>
+						<p>Uncheck this option if you do not want to apply the theme of the operating system or the
+							browser (e.g. dark or light) when you click on the button "Format the page for better
+							readability" in the annotation editor.</p>
+					</li>
+					<li data-options-label="warnUnsavedPageLabel"> <span class="option">Option: warn if leaving page
+							with unsaved changes</span>
+						<p>Check this option to display a blocking popup when you leave the annotation editor (e.g.
+							close the tab) without saving the cahnges.</p>
+						<p class="notice">It is recommended to <u>check</u> this option</p>
+					</li>
+					<li data-options-label="openEditorLabel"> <span class="option">Option: edit page before
+							saving</span>
+						<p>Check this option to open the annotation editor before saving any page. Checking this option
+							removes the entry "Annotate and save the page..." from the context menu.</p>
+						<p class="notice">It is recommended to <u>uncheck</u> this option</p>
+					</li>
+					<li data-options-label="autoOpenEditorLabel"> <span class="option">Option: open the annotation
+							editor when viewing a page saved with SingleFile </span>
+						<p>Check this option to open the annotation editor when displaying a page saved by SingleFile.
+						</p>
+						<p class="notice">It is recommended to <u>uncheck</u> this option</p>
+					</li>
+				</ul>
 				<p>Misc.</p>
 				<ul>
 					<li data-options-label="backgroundSaveLabel"> <span class="option">Option: save pages in
@@ -355,12 +370,6 @@
 							path. Unchecking this option prevent using sub-directories in filename templates.</p>
 						<p class="notice">It is recommended to <u>check</u> this option</p>
 					</li>
-					<li data-options-label="applySystemThemeLabel"> <span class="option">Option: apply the system theme
-							when formatting a page in the annotation editor</span>
-						<p>Uncheck this option if you do not want to apply the theme of the operating system or the
-							browser (e.g. dark or light) when you click on the button "Format the page for better
-							readability" in the annotation editor.</p>
-					</li>
 					<li data-options-label="displayStatsLabel"> <span class="option">Option: display stats in the
 							console after processing</span>
 						<p>Check this option to display stats about processing in the JavaScript developer tools of your

+ 19 - 12
extension/ui/pages/options.html

@@ -42,14 +42,6 @@
 				<label for="infobarTemplateInput" id="infobarTemplateLabel"></label>
 				<input type="text" id="infobarTemplateInput">
 			</div>
-			<div class="option">
-				<label for="openEditorInput" id="openEditorLabel"></label>
-				<input type="checkbox" id="openEditorInput">
-			</div>
-			<div class="option">
-				<label for="autoOpenEditorInput" id="autoOpenEditorLabel"></label>
-				<input type="checkbox" id="autoOpenEditorInput">
-			</div>
 			<div class="option">
 				<label for="confirmInfobarInput" id="confirmInfobarLabel"></label>
 				<input type="checkbox" id="confirmInfobarInput">
@@ -197,16 +189,31 @@
 				<input type="number" id="autoSaveRepeatDelayInput" min="1">
 			</div>
 		</details>
+		<details>
+			<summary id="editorLabel"></summary>
+			<div class="option">
+				<label for="applySystemThemeInput" id="applySystemThemeLabel"></label>
+				<input type="checkbox" id="applySystemThemeInput">
+			</div>
+			<div class="option">
+				<label for="warnUnsavedPageInput" id="warnUnsavedPageLabel"></label>
+				<input type="checkbox" id="warnUnsavedPageInput">
+			</div>
+			<div class="option">
+				<label for="openEditorInput" id="openEditorLabel"></label>
+				<input type="checkbox" id="openEditorInput">
+			</div>
+			<div class="option">
+				<label for="autoOpenEditorInput" id="autoOpenEditorLabel"></label>
+				<input type="checkbox" id="autoOpenEditorInput">
+			</div>
+		</details>
 		<details>
 			<summary id="miscLabel"></summary>
 			<div class="option">
 				<label for="backgroundSaveInput" id="backgroundSaveLabel"></label>
 				<input type="checkbox" id="backgroundSaveInput">
 			</div>
-			<div class="option">
-				<label for="applySystemThemeInput" id="applySystemThemeLabel"></label>
-				<input type="checkbox" id="applySystemThemeInput">
-			</div>
 			<div class="option">
 				<label for="displayStatsInput" id="displayStatsLabel"></label>
 				<input type="checkbox" id="displayStatsInput">