20 Commits

Author SHA1 Message Date
c2b9664b4b Version 4.0.12 2019-09-13 22:31:55 +02:00
e760d2b022 Handle Chrome state changes correct. 2019-09-12 20:54:16 +02:00
1a836d914b Preroll-nope 401, 402
Closes #89
2019-09-12 13:30:06 +02:00
1b0e6eb6c4 Send referrer with prerolls
See #89
2019-09-12 13:26:24 +02:00
39827ad485 Update TODO 2019-09-12 11:22:55 +02:00
79c4d4e98f typos in the de-locale 2019-09-12 10:00:36 +02:00
427bd2f348 Actually add Italian translation 2019-09-11 23:04:39 +02:00
4fefd0e128 Arabic translation
Closes #90
2019-09-11 23:03:25 +02:00
d79060237d Silence window-type errors 2019-09-10 14:43:49 +02:00
2df7a1c592 do not force ascii in addlocale 2019-09-10 14:43:48 +02:00
8c4ceb3e4b Privetize downloads 2019-09-10 12:44:56 +02:00
bf725ece72 Open links in the correct window context 2019-09-10 12:43:47 +02:00
76992bd4f4 Version 4.0.11 2019-09-10 09:37:00 +02:00
dccd530475 Typo 2019-09-10 09:33:32 +02:00
f1fa01a0eb Add ja to locale list 2019-09-10 09:30:59 +02:00
7949142ef6 Japanese translation (#83) 2019-09-10 09:29:12 +02:00
af1da8fc0a Fix maximized state being refused with dims
Closes #84
2019-09-10 09:23:43 +02:00
39f4237cde Update Indonesian translation (#80) 2019-09-09 18:07:07 +02:00
b676ed74cd Update locale list 2019-09-08 21:30:21 +02:00
bf474877ca Add Italian translation (#49) 2019-09-08 21:27:42 +02:00
20 changed files with 4076 additions and 410 deletions

View File

@ -13,7 +13,6 @@ Planned for later.
* Delete files (well, as far as the browser allows) * Delete files (well, as far as the browser allows)
* Inter-addon API (basic) * Inter-addon API (basic)
* Add downloads * Add downloads
* Chrome support
* vtable perf: cache column widths * vtable perf: cache column widths
* Download options * Download options
* This is a bit more limited, as we cannot modify options of downloads that have been started (and paused) or that are done. * This is a bit more limited, as we cannot modify options of downloads that have been started (and paused) or that are done.

View File

@ -1,17 +1,20 @@
{ {
"ar": "العربية [ar]",
"cs": "Čeština (CZ) [cs]", "cs": "Čeština (CZ) [cs]",
"de": "Deutsch [de]", "de": "Deutsch [de]",
"el": "Ελληνικά [el]", "el": "Ελληνικά [el]",
"en": "English (US) [en]", "en": "English (US) [en]",
"es": "Español (España) [es]", "es": "Español (España) [es]",
"et": "Eesti Keel [et]", "et": "Eesti Keel [et]",
"fr": "Français (FR) [fr]", "fr": "Français [fr]",
"hu": "Magyar (HU) [hu]", "hu": "Magyar (HU) [hu]",
"id": "Bahasa Indonesia [id]", "id": "Bahasa Indonesia [id]",
"it": "Italiano [it]",
"ja": "日本語 (JP) [ja]",
"ko": "한국어 [ko]", "ko": "한국어 [ko]",
"lt": "Lietuvių [lt]", "lt": "Lietuvių [lt]",
"nl": "Nederlands [nl]", "nl": "Nederlands [nl]",
"pl": "Polski (PL) [pl]", "pl": "Polski [pl]",
"pt": "Português (Brasil) [pt]", "pt": "Português (Brasil) [pt]",
"ru": "Русский [ru]", "ru": "Русский [ru]",
"zh_CN": "简体中文 [zh_CN]", "zh_CN": "简体中文 [zh_CN]",

1170
_locales/ar/messages.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,272 +11,6 @@
"message": "Pausiert hinzufügen", "message": "Pausiert hinzufügen",
"description": "Action: Add paused" "description": "Action: Add paused"
}, },
"cancel": {
"message": "Abbrechen",
"description": "Button text: Cancel"
},
"canceled": {
"message": "Abgebrochen",
"description": "Download statu text"
},
"colConnections": {
"message": "Gleichzeitige Verbindungen",
"description": "Table column in prefs/network"
},
"colDomain": {
"message": "Domain",
"description": "Table column in manager"
},
"colETA": {
"message": "Verbl. Zeit",
"description": "Table column in manager"
},
"colNameURL": {
"message": "Name/URL",
"description": "Table column in manager"
},
"colPercent": {
"message": "%",
"description": "Table column in manager"
},
"colProgress": {
"message": "Fortschritt",
"description": "Table column in manager"
},
"colSegments": {
"message": "Segmente",
"description": "Table column in manager"
},
"colSize": {
"message": "Größe",
"description": "Table column in manager"
},
"colSpeed": {
"message": "Geschwindigkeit",
"description": "Table column in manager"
},
"CRASH": {
"message": "Interner Browser Fehler",
"description": "Error Message"
},
"delete": {
"message": "Entfernen",
"description": "button text"
},
"description": {
"message": "Beschreibung",
"description": "Description (keep it short); e.g. the description column in select"
},
"donate": {
"message": "Spenden!",
"description": "Donate button"
},
"done": {
"message": "Fertig",
"description": "Status text"
},
"download": {
"message": "Download",
"description": "Download (noun); e.g. Download column in select"
},
"extensionDescription": {
"message": "Der Massen-Downloader für Deinen Browser",
"description": "DownThemAll! tagline, displayed in about:addons; Please do NOT refer to a specific browser such as firefox, as we will probably support more than one"
},
"fastfiltering": {
"message": "Schnelles Filtern",
"description": "Label for Fast Filtering input"
},
"FILE_FAILED": {
"message": "Dateizugriffsfehler",
"description": "Error Message"
},
"finishing": {
"message": "Beenden",
"description": "Status text"
},
"links": {
"message": "Links",
"description": "Links tab label (short); select window"
},
"mask": {
"message": "Maske",
"description": "Renaming mask (short); used in e.g. select"
},
"media": {
"message": "Medien",
"description": "Media label (short)"
},
"missing": {
"message": "Fehlt",
"description": "Status text in manager"
},
"NETWORK_FAILED": {
"message": "Netzwerkfehler",
"description": "Error Message"
},
"ok": {
"message": "OK",
"description": "Button text; Used in message boxes"
},
"paused": {
"message": "Pausiert",
"description": "Status text; manager"
},
"queued": {
"message": "Wartend",
"description": "Status text"
},
"referrer": {
"message": "Referrer",
"description": "Label for \"Referrer\""
},
"remember": {
"message": "Diese Entscheidung merken",
"description": "Checkbox text for confirmation, e.g. when removing a download in manager"
},
"rename": {
"message": "Umbenennen",
"description": "UI for renaming; currently unused"
},
"renmask": {
"message": "Umbennenungsmaske",
"description": "Renaming mask (long)"
},
"reset": {
"message": "Zurücksetzen",
"description": "Button text; pref window"
},
"running": {
"message": "Laufend",
"description": "Status text"
},
"save": {
"message": "Speichern",
"description": "Button text; e.g. prefs/Network"
},
"search": {
"message": "Suchen…",
"description": "Placeholder text; manager status search field"
},
"SERVER_BAD_CONTENT": {
"message": "Nicht gefunden",
"description": "Error message"
},
"SERVER_FAILED": {
"message": "Server-Fehler",
"description": "Error message"
},
"SERVER_FORBIDDEN": {
"message": "Nicht erlaubt",
"description": "Error message"
},
"SERVER_UNAUTHORIZED": {
"message": "Keine Berechtigung",
"description": "Error message"
},
"sizeB": {
"message": "$S$B",
"description": "Size formatting; bytes",
"placeholders": {
"s": {
"content": "$1",
"example": "100b"
}
}
},
"sizeGB": {
"message": "$S$GB",
"description": "Size formatting; giga bytes",
"placeholders": {
"s": {
"content": "$1",
"example": "100.200GB"
}
}
},
"sizeKB": {
"message": "$S$KB",
"description": "Size formatting; kilo bytes",
"placeholders": {
"s": {
"content": "$1",
"example": "100.2KB"
}
}
},
"sizeMB": {
"message": "$S$MB",
"description": "Size formatting; mega bytes",
"placeholders": {
"s": {
"content": "$1",
"example": "100.22MB"
}
}
},
"sizePB": {
"message": "$S$PB",
"description": "Size formatting; peta bytes (you never know)",
"placeholders": {
"s": {
"content": "$1",
"example": "100.212PB"
}
}
},
"sizeTB": {
"message": "$S$TB",
"description": "Size formatting; tera bytes (you never know)",
"placeholders": {
"s": {
"content": "$1",
"example": "100.002TB"
}
}
},
"speedB": {
"message": "$SPEED$b/s",
"description": "Speed formatting; bytes",
"placeholders": {
"speed": {
"content": "$1",
"example": "100b/s"
}
}
},
"speedKB": {
"message": "$SPEED$KB/s",
"description": "Speed formatting; kilo bytes",
"placeholders": {
"speed": {
"content": "$1",
"example": "100.1KB/s"
}
}
},
"speedMB": {
"message": "$SPEED$MB/s",
"description": "Speed formatting; mega bytes",
"placeholders": {
"speed": {
"content": "$1",
"example": "100.20MB/s"
}
}
},
"title": {
"message": "Titel",
"description": "Column text; Title label (short)"
},
"unlimited": {
"message": "Unbegrenzt",
"description": "Option text; Prefs/Network"
},
"useonlyonce": {
"message": "Einmalig",
"description": "Label for Use-Once checkboxes"
},
"add_download": { "add_download": {
"message": "Download hinzufügen", "message": "Download hinzufügen",
"description": "Action for adding a download" "description": "Action for adding a download"
@ -329,6 +63,14 @@
"message": "Batch Download", "message": "Batch Download",
"description": "Messagebox title for batch confirmations" "description": "Messagebox title for batch confirmations"
}, },
"cancel": {
"message": "Abbrechen",
"description": "Button text: Cancel"
},
"canceled": {
"message": "Abgebrochen",
"description": "Download status text"
},
"cancel_download": { "cancel_download": {
"message": "Abbrechen", "message": "Abbrechen",
"description": "Action to cancel downloads, e.g. from the context menu" "description": "Action to cancel downloads, e.g. from the context menu"
@ -342,9 +84,45 @@
"description": "Checkbox label text for decision confirmations" "description": "Checkbox label text for decision confirmations"
}, },
"check_selected_items": { "check_selected_items": {
"message": "Ausgewählte Einträge makieren", "message": "Ausgewählte Einträge markieren",
"description": "Menu text" "description": "Menu text"
}, },
"colConnections": {
"message": "Gleichzeitige Verbindungen",
"description": "Table column in prefs/network"
},
"colDomain": {
"message": "Domain",
"description": "Table column in manager"
},
"colETA": {
"message": "Verbl. Zeit",
"description": "Table column in manager"
},
"colNameURL": {
"message": "Name/URL",
"description": "Table column in manager"
},
"colPercent": {
"message": "%",
"description": "Table column in manager"
},
"colProgress": {
"message": "Fortschritt",
"description": "Table column in manager"
},
"colSegments": {
"message": "Segmente",
"description": "Table column in manager"
},
"colSize": {
"message": "Größe",
"description": "Table column in manager"
},
"colSpeed": {
"message": "Geschwindigkeit",
"description": "Table column in manager"
},
"conflict_overwrite": { "conflict_overwrite": {
"message": "Überschreiben", "message": "Überschreiben",
"description": "Option text; prefs/general" "description": "Option text; prefs/general"
@ -357,6 +135,10 @@
"message": "Umbenennen", "message": "Umbenennen",
"description": "Option text; prefs/general" "description": "Option text; prefs/general"
}, },
"CRASH": {
"message": "Interner Browser Fehler",
"description": "Error Message"
},
"create_filter": { "create_filter": {
"message": "Filter erstellen", "message": "Filter erstellen",
"description": "Button text; Create filter dialog; prefs/filters" "description": "Button text; Create filter dialog; prefs/filters"
@ -405,26 +187,42 @@
"message": "Videos (mp4, webm, mkv, …)", "message": "Videos (mp4, webm, mkv, …)",
"description": "Filter label for the Videos filter" "description": "Filter label for the Videos filter"
}, },
"delete": {
"message": "Entfernen",
"description": "button text"
},
"description": {
"message": "Beschreibung",
"description": "Description (keep it short); e.g. the description column in select"
},
"disable_other_filters": { "disable_other_filters": {
"message": "Andere deaktivieren", "message": "Andere deaktivieren",
"description": "Checkbox label. Keep it short" "description": "Checkbox label. Keep it short"
}, },
"donate": {
"message": "Spenden!",
"description": "Donate button"
},
"done": {
"message": "Fertig",
"description": "Status text"
},
"download": {
"message": "Download",
"description": "Download (noun); e.g. Download column in select"
},
"download_verb": { "download_verb": {
"message": "Download", "message": "Download",
"description": "Download (verb/action); e.g. in single and select buttons" "description": "Download (verb/action); e.g. in single and select buttons"
}, },
"dta_regular_all": {
"message": "DownThemAll! - Alle Tabs",
"description": "Menu text"
},
"dta_turbo_all": {
"message": "OneClick! - Alle Tabs",
"description": "Menu text"
},
"dta_regular": { "dta_regular": {
"message": "DownThemAll!", "message": "DownThemAll!",
"description": "Regular dta action; Menu text" "description": "Regular dta action; Menu text"
}, },
"dta_regular_all": {
"message": "DownThemAll! - Alle Tabs",
"description": "Menu text"
},
"dta_regular_image": { "dta_regular_image": {
"message": "Bild mit DownThemAll! speichern", "message": "Bild mit DownThemAll! speichern",
"description": "Menu text" "description": "Menu text"
@ -445,6 +243,10 @@
"message": "OneClick!", "message": "OneClick!",
"description": "OneClick! action; Menu text" "description": "OneClick! action; Menu text"
}, },
"dta_turbo_all": {
"message": "OneClick! - Alle Tabs",
"description": "Menu text"
},
"dta_turbo_image": { "dta_turbo_image": {
"message": "Bild mit OneClick! speichern", "message": "Bild mit OneClick! speichern",
"description": "Menu text" "description": "Menu text"
@ -477,16 +279,28 @@
"message": "Nichts ausgewählt", "message": "Nichts ausgewählt",
"description": "Error Message; select window" "description": "Error Message; select window"
}, },
"extensionDescription": {
"message": "Der Massen-Downloader für Deinen Browser",
"description": "DownThemAll! tagline, displayed in about:addons; Please do NOT refer to a specific browser such as firefox, as we will probably support more than one"
},
"fastfiltering": {
"message": "Schnelles Filtern",
"description": "Label for Fast Filtering input"
},
"fastfilter_placeholder": { "fastfilter_placeholder": {
"message": "Platzhalter-Ausdruck oder Regular Expression", "message": "Platzhalter-Ausdruck oder Regular Expression",
"description": "Placeholder for fastfilter inputs" "description": "Placeholder for fastfilter inputs"
}, },
"FILE_FAILED": {
"message": "Dateizugriffsfehler",
"description": "Error Message"
},
"filter_at_least_one": { "filter_at_least_one": {
"message": "Mindestens einen Filter-Typ auswählen!", "message": "Mindestens einen Filter-Typ auswählen!",
"description": "Error message when no filter types are selected for a filter in the preferences UI" "description": "Error message when no filter types are selected for a filter in the preferences UI"
}, },
"filter_create_title": { "filter_create_title": {
"message": "Neuen Filter erstelln", "message": "Neuen Filter erstellen",
"description": "Message box title" "description": "Message box title"
}, },
"filter_expression": { "filter_expression": {
@ -497,6 +311,10 @@
"message": "Filter-Titel", "message": "Filter-Titel",
"description": "Message box label" "description": "Message box label"
}, },
"filter_types": {
"message": "Filter Typen",
"description": "Message box label"
},
"filter_type_link": { "filter_type_link": {
"message": "Link Filter", "message": "Link Filter",
"description": "Message box checkbox label" "description": "Message box checkbox label"
@ -505,9 +323,9 @@
"message": "Medien Filter", "message": "Medien Filter",
"description": "Message box checkbox label" "description": "Message box checkbox label"
}, },
"filter_types": { "finishing": {
"message": "Filter Typen", "message": "Beenden",
"description": "Message box label" "description": "Status text"
}, },
"force_start": { "force_start": {
"message": "Start erzwingen", "message": "Start erzwingen",
@ -557,6 +375,14 @@
"message": "Begrenzt auf", "message": "Begrenzt auf",
"description": "Label text; used in prefs/network" "description": "Label text; used in prefs/network"
}, },
"links": {
"message": "Links",
"description": "Links tab label (short); select window"
},
"manager_short": {
"message": "Manager",
"description": "Menu text"
},
"manager_status_items": { "manager_status_items": {
"message": "$COMPLETE$ von $TOTAL$ Downloads beendet ($SHOWING$ angezeigt), $RUNNING$ laufend", "message": "$COMPLETE$ von $TOTAL$ Downloads beendet ($SHOWING$ angezeigt), $RUNNING$ laufend",
"description": "Status bar text; manager", "description": "Status bar text; manager",
@ -579,18 +405,26 @@
} }
} }
}, },
"manager_short": {
"message": "Manager",
"description": "Menu text"
},
"manager_title": { "manager_title": {
"message": "DownThemAll! Manager", "message": "DownThemAll! Manager",
"description": "Window/tab title" "description": "Window/tab title"
}, },
"mask": {
"message": "Maske",
"description": "Renaming mask (short); used in e.g. select"
},
"mask_default": { "mask_default": {
"message": "Standard-Maske", "message": "Standard-Maske",
"description": "Status text; Used in the mask column, select window" "description": "Status text; Used in the mask column, select window"
}, },
"media": {
"message": "Medien",
"description": "Media label (short)"
},
"missing": {
"message": "Fehlt",
"description": "Status text in manager"
},
"move_bottom": { "move_bottom": {
"message": "Ende", "message": "Ende",
"description": "Action for moving a download to the bottom" "description": "Action for moving a download to the bottom"
@ -617,18 +451,22 @@
} }
} }
}, },
"NETWORK_FAILED": {
"message": "Netzwerkfehler",
"description": "Error Message"
},
"never_ask_again": { "never_ask_again": {
"message": "Nicht wieder fragen", "message": "Nicht wieder fragen",
"description": "Donation button" "description": "Donation button"
}, },
"no_links": {
"message": "Keine Links gefunden!",
"description": "Notification text"
},
"noitems_label": { "noitems_label": {
"message": "Nichts ausgewählt", "message": "Nichts ausgewählt",
"description": "Status bar text in select" "description": "Status bar text in select"
}, },
"no_links": {
"message": "Keine Links gefunden!",
"description": "Notification text"
},
"numitems_label": { "numitems_label": {
"message": "$ITEMS$ Downloads ausgewählt", "message": "$ITEMS$ Downloads ausgewählt",
"description": "Status bar text in select; Number of items selected (label)", "description": "Status bar text in select; Number of items selected (label)",
@ -639,6 +477,10 @@
} }
} }
}, },
"ok": {
"message": "OK",
"description": "Button text; Used in message boxes"
},
"open_directory": { "open_directory": {
"message": "Verzeichnis öffnen", "message": "Verzeichnis öffnen",
"description": "Menu text; manager context" "description": "Menu text; manager context"
@ -663,10 +505,26 @@
"message": "Netzwerk", "message": "Netzwerk",
"description": "Pref tab text" "description": "Pref tab text"
}, },
"paused": {
"message": "Pausiert",
"description": "Status text; manager"
},
"pause_download": { "pause_download": {
"message": "Pausieren", "message": "Pausieren",
"description": "Action for pausing a download" "description": "Action for pausing a download"
}, },
"prefs_conflicts": {
"message": "Wenn eine Datei bereits existiert",
"description": "Preferences/General; group text"
},
"prefs_short": {
"message": "Einstellungen",
"description": "Menu text; Preferences"
},
"prefs_title": {
"message": "DownThemAll! Einstellungen",
"description": "Window/tab title; Preferences"
},
"pref_add_paused": { "pref_add_paused": {
"message": "Neue Downloads immer pausiert hinzufügen, anstatt sie direkt zu starten", "message": "Neue Downloads immer pausiert hinzufügen, anstatt sie direkt zu starten",
"description": "Preferences/General" "description": "Preferences/General"
@ -687,14 +545,26 @@
"message": "Keine allgemeinen Menü-Eintrage anzeigen", "message": "Keine allgemeinen Menü-Eintrage anzeigen",
"description": "Preferences/General" "description": "Preferences/General"
}, },
"pref_manager": {
"message": "Manager",
"description": "Preferences/General; group text"
},
"pref_manager_tooltip": { "pref_manager_tooltip": {
"message": "Keine Tooltips im Manager-Tab anzeigen", "message": "Keine Tooltips im Manager-Tab anzeigen",
"description": "Preferences/General" "description": "Preferences/General"
}, },
"pref_netglobal": {
"message": "Allgemeine Netzwerk-Beschränkungen",
"description": "Preferences/General; group text"
},
"pref_open_manager_on_queue": { "pref_open_manager_on_queue": {
"message": "Den Manager öffnen nachdem neue Downloads zur Warteschlange hinzugefügt wurden", "message": "Den Manager öffnen nachdem neue Downloads zur Warteschlange hinzugefügt wurden",
"description": "Preferences/General" "description": "Preferences/General"
}, },
"pref_queueing": {
"message": "Download-Warteschlange",
"description": "Preferences/General; group text"
},
"pref_queue_notification": { "pref_queue_notification": {
"message": "Benachrichtigung anzeigen, wenn neue Downloads hinzugefügt wurden", "message": "Benachrichtigung anzeigen, wenn neue Downloads hinzugefügt wurden",
"description": "Preferences/General" "description": "Preferences/General"
@ -711,37 +581,13 @@
"message": "Versuche Text-Links in Webseiten zu finden (langsamer)", "message": "Versuche Text-Links in Webseiten zu finden (langsamer)",
"description": "Preferences/General" "description": "Preferences/General"
}, },
"pref_manager": {
"message": "Manager",
"description": "Preferences/General; group text"
},
"pref_netglobal": {
"message": "Allgemeine Netzwerk-Beschränkungen",
"description": "Preferences/General; group text"
},
"pref_queueing": {
"message": "Download-Warteschlange",
"description": "Preferences/General; group text"
},
"pref_ui": { "pref_ui": {
"message": "Benutzeroberfläche", "message": "Benutzeroberfläche",
"description": "Preferences/General; group text" "description": "Preferences/General; group text"
}, },
"prefs_conflicts": { "queued": {
"message": "Wenn eine Datei bereits existiert", "message": "Wartend",
"description": "Preferences/General; group text" "description": "Status text"
},
"prefs_short": {
"message": "Einstellungen",
"description": "Menu text; Preferences"
},
"prefs_title": {
"message": "DownThemAll! Einstellungen",
"description": "Window/tab title; Preferences"
},
"queue_finished": {
"message": "Die Download-Warteschlange ist fertig",
"description": "Notification text"
}, },
"queued_download": { "queued_download": {
"message": "Ein Download hinzugefügt!", "message": "Ein Download hinzugefügt!",
@ -757,6 +603,18 @@
} }
} }
}, },
"queue_finished": {
"message": "Die Download-Warteschlange ist fertig",
"description": "Notification text"
},
"referrer": {
"message": "Referrer",
"description": "Label for \"Referrer\""
},
"remember": {
"message": "Diese Entscheidung merken",
"description": "Checkbox text for confirmation, e.g. when removing a download in manager"
},
"remove_all_complete_downloads": { "remove_all_complete_downloads": {
"message": "Alle fertigen entfernen", "message": "Alle fertigen entfernen",
"description": "Menu text" "description": "Menu text"
@ -831,18 +689,18 @@
"message": "Download entfernen", "message": "Download entfernen",
"description": "Action for removing a download, no matter what state" "description": "Action for removing a download, no matter what state"
}, },
"remove_download_question": {
"message": "Wirklich alle ausgewählten Downloads entfernen?",
"description": "Messagebox text"
},
"remove_downloads": { "remove_downloads": {
"message": "Downloas entfernen", "message": "Downloads entfernen",
"description": "Menu text" "description": "Menu text"
}, },
"remove_downloads_title": { "remove_downloads_title": {
"message": "Wirklich Downloads entfernen?", "message": "Wirklich Downloads entfernen?",
"description": "Messagebox title; manager" "description": "Messagebox title; manager"
}, },
"remove_download_question": {
"message": "Wirklich alle ausgewählten Downloads entfernen?",
"description": "Messagebox text"
},
"remove_failed_downloads": { "remove_failed_downloads": {
"message": "Fehlgeschlagene entfernen", "message": "Fehlgeschlagene entfernen",
"description": "Menu text" "description": "Menu text"
@ -889,6 +747,10 @@
"message": "Ausgewählte entfernen", "message": "Ausgewählte entfernen",
"description": "Menu text" "description": "Menu text"
}, },
"rename": {
"message": "Umbenennen",
"description": "UI for renaming; currently unused"
},
"renamer_batch": { "renamer_batch": {
"message": "Batch Nummer", "message": "Batch Nummer",
"description": "Mask text; see mask button" "description": "Mask text; see mask button"
@ -1005,6 +867,14 @@
"message": "Datum hinzugefügt - Jahr", "message": "Datum hinzugefügt - Jahr",
"description": "Mask text; see mask button" "description": "Mask text; see mask button"
}, },
"renmask": {
"message": "Umbenennungsmaske",
"description": "Renaming mask (long)"
},
"reset": {
"message": "Zurücksetzen",
"description": "Button text; pref window"
},
"reset_confirmations": { "reset_confirmations": {
"message": "Gemerkte Entscheidungen zurücksetzen", "message": "Gemerkte Entscheidungen zurücksetzen",
"description": "Button text; pref/General" "description": "Button text; pref/General"
@ -1025,6 +895,18 @@
"message": "Fortsetzen", "message": "Fortsetzen",
"description": "Action for resuming a download" "description": "Action for resuming a download"
}, },
"running": {
"message": "Laufend",
"description": "Status text"
},
"save": {
"message": "Speichern",
"description": "Button text; e.g. prefs/Network"
},
"search": {
"message": "Suchen…",
"description": "Placeholder text; manager status search field"
},
"select_all": { "select_all": {
"message": "Alles auswählen", "message": "Alles auswählen",
"description": "Menu text; e.g. select context" "description": "Menu text; e.g. select context"
@ -1041,6 +923,22 @@
"message": "DownThemAll! - Downloads auswählen", "message": "DownThemAll! - Downloads auswählen",
"description": "Title of the select window" "description": "Title of the select window"
}, },
"SERVER_BAD_CONTENT": {
"message": "Nicht gefunden",
"description": "Error message"
},
"SERVER_FAILED": {
"message": "Server-Fehler",
"description": "Error message"
},
"SERVER_FORBIDDEN": {
"message": "Nicht erlaubt",
"description": "Error message"
},
"SERVER_UNAUTHORIZED": {
"message": "Keine Berechtigung",
"description": "Error message"
},
"set_mask": { "set_mask": {
"message": "Umbenennungsmaske setzen", "message": "Umbenennungsmaske setzen",
"description": "Menu text; select window" "description": "Menu text; select window"
@ -1050,30 +948,62 @@
"description": "Header text; single window" "description": "Header text; single window"
}, },
"single_header": { "single_header": {
"message": "Download URL (link) und andere Optionen eingeben", "message": "Download URL (Link) und andere Optionen eingeben",
"description": "Header text; single window" "description": "Header text; single window"
}, },
"single_title": { "single_title": {
"message": "DownThemAll! - Link hinzufügen", "message": "DownThemAll! - Link hinzufügen",
"description": "Title of single window" "description": "Title of single window"
}, },
"size_progress": { "sizeB": {
"message": "$WRITTEN$ von $TOTAL$", "message": "$S$B",
"description": "Status text; manager size column", "description": "Size formatting; bytes",
"placeholders": { "placeholders": {
"total": { "s": {
"content": "$2",
"example": ""
},
"written": {
"content": "$1", "content": "$1",
"example": "" "example": "100b"
} }
} }
}, },
"size_unknown": { "sizeGB": {
"message": "Unbekannt", "message": "$S$GB",
"description": "Status text; manager size column" "description": "Size formatting; giga bytes",
"placeholders": {
"s": {
"content": "$1",
"example": "100.200GB"
}
}
},
"sizeKB": {
"message": "$S$KB",
"description": "Size formatting; kilo bytes",
"placeholders": {
"s": {
"content": "$1",
"example": "100.2KB"
}
}
},
"sizeMB": {
"message": "$S$MB",
"description": "Size formatting; mega bytes",
"placeholders": {
"s": {
"content": "$1",
"example": "100.22MB"
}
}
},
"sizePB": {
"message": "$S$PB",
"description": "Size formatting; peta bytes (you never know)",
"placeholders": {
"s": {
"content": "$1",
"example": "100.212PB"
}
}
}, },
"sizes_huge": { "sizes_huge": {
"message": "Riesig (> $HIGH$)", "message": "Riesig (> $HIGH$)",
@ -1127,6 +1057,64 @@
} }
} }
}, },
"sizeTB": {
"message": "$S$TB",
"description": "Size formatting; tera bytes (you never know)",
"placeholders": {
"s": {
"content": "$1",
"example": "100.002TB"
}
}
},
"size_progress": {
"message": "$WRITTEN$ von $TOTAL$",
"description": "Status text; manager size column",
"placeholders": {
"total": {
"content": "$2",
"example": ""
},
"written": {
"content": "$1",
"example": ""
}
}
},
"size_unknown": {
"message": "Unbekannt",
"description": "Status text; manager size column"
},
"speedB": {
"message": "$SPEED$b/s",
"description": "Speed formatting; bytes",
"placeholders": {
"speed": {
"content": "$1",
"example": "100b/s"
}
}
},
"speedKB": {
"message": "$SPEED$KB/s",
"description": "Speed formatting; kilo bytes",
"placeholders": {
"speed": {
"content": "$1",
"example": "100.1KB/s"
}
}
},
"speedMB": {
"message": "$SPEED$MB/s",
"description": "Speed formatting; mega bytes",
"placeholders": {
"speed": {
"content": "$1",
"example": "100.20MB/s"
}
}
},
"statusNetwork_active_title": { "statusNetwork_active_title": {
"message": "Neue Downloads werden gestartet", "message": "Neue Downloads werden gestartet",
"description": "Status bar tooltip; manager network icon" "description": "Status bar tooltip; manager network icon"
@ -1135,8 +1123,12 @@
"message": "Neue Downloads werden nicht gestartet", "message": "Neue Downloads werden nicht gestartet",
"description": "Status bar tooltip; manager network icon" "description": "Status bar tooltip; manager network icon"
}, },
"title": {
"message": "Titel",
"description": "Column text; Title label (short)"
},
"toggle_selected_items": { "toggle_selected_items": {
"message": "Markierungen für Auswahl umgekehren", "message": "Markierungen für Auswahl umkehren",
"description": "Menu text; select" "description": "Menu text; select"
}, },
"tooltip_date": { "tooltip_date": {
@ -1166,5 +1158,13 @@
"uncheck_selected_items": { "uncheck_selected_items": {
"message": "Markierung von Auswahl entfernen", "message": "Markierung von Auswahl entfernen",
"description": "Menu text; select" "description": "Menu text; select"
},
"unlimited": {
"message": "Unbegrenzt",
"description": "Option text; Prefs/Network"
},
"useonlyonce": {
"message": "Einmalig",
"description": "Label for Use-Once checkboxes"
} }
} }

View File

@ -7,6 +7,18 @@
"message": "id", "message": "id",
"description": "Language code the locale will use, e.g. de or en-GB or pt-BR" "description": "Language code the locale will use, e.g. de or en-GB or pt-BR"
}, },
"renamer_tags": {
"message": "Penanda Mask Penamaan",
"description": "Mask text; see mask button"
},
"renmask": {
"message": "Mask penamaan",
"description": "Renaming mask (long)"
},
"set_mask": {
"message": "Set Mask Penamaan",
"description": "Menu text; select window"
},
"addpaused": { "addpaused": {
"message": "Tambahkan dalam kondisi terpause", "message": "Tambahkan dalam kondisi terpause",
"description": "Action: Add paused" "description": "Action: Add paused"
@ -280,15 +292,15 @@
"description": "Message box title" "description": "Message box title"
}, },
"filter_expression": { "filter_expression": {
"message": "Ekspres-Filter", "message": "Ekspresi",
"description": "Message box label" "description": "Message box label"
}, },
"filter_label": { "filter_label": {
"message": "Label-Filter", "message": "Label",
"description": "Message box label" "description": "Message box label"
}, },
"filter_types": { "filter_types": {
"message": "Tipe-Filter", "message": "Tipe",
"description": "Message box label" "description": "Message box label"
}, },
"filter_type_link": { "filter_type_link": {
@ -320,7 +332,7 @@
"description": "Menu text" "description": "Menu text"
}, },
"limited_to": { "limited_to": {
"message": "Terbatas ke", "message": "Batasi ke",
"description": "Label text; used in prefs/network" "description": "Label text; used in prefs/network"
}, },
"links": { "links": {
@ -362,11 +374,11 @@
"description": "Status text; Used in the mask column, select window" "description": "Status text; Used in the mask column, select window"
}, },
"missing": { "missing": {
"message": "Tidak Ada", "message": "Hilang",
"description": "Status text in manager" "description": "Status text in manager"
}, },
"move_bottom": { "move_bottom": {
"message": "Bawah", "message": "Ke Bawah",
"description": "Action for moving a download to the bottom" "description": "Action for moving a download to the bottom"
}, },
"move_down": { "move_down": {
@ -374,7 +386,7 @@
"description": "Action for moving a download down" "description": "Action for moving a download down"
}, },
"move_top": { "move_top": {
"message": "Atas", "message": "Ke Atas",
"description": "Action for moving a download to the top" "description": "Action for moving a download to the top"
}, },
"move_up": { "move_up": {
@ -560,7 +572,7 @@
"description": "Menu text" "description": "Menu text"
}, },
"remove_batch_downloads_question": { "remove_batch_downloads_question": {
"message": "Hapus semua unduhan dari kumpulan yang sama dengan unduhan terpilih?", "message": "Hapus semua unduhan dari batch yang sama dengan unduhan terpilih?",
"description": "Messagebox text" "description": "Messagebox text"
}, },
"remove_complete_downloads": { "remove_complete_downloads": {
@ -600,7 +612,7 @@
} }
}, },
"remove_domain_downloads": { "remove_domain_downloads": {
"message": "Hapus Domain Ini", "message": "Hapus Unduhan Dari Domain Ini",
"description": "Menu text" "description": "Menu text"
}, },
"remove_domain_downloads_question": { "remove_domain_downloads_question": {
@ -630,7 +642,7 @@
"description": "Messagebox text" "description": "Messagebox text"
}, },
"remove_failed_downloads": { "remove_failed_downloads": {
"message": "Gagal Menghapus", "message": "Hapus Unduhan Gagal",
"description": "Menu text" "description": "Menu text"
}, },
"remove_failed_downloads_question": { "remove_failed_downloads_question": {
@ -648,11 +660,11 @@
} }
}, },
"remove_missing": { "remove_missing": {
"message": "Hapus Unduhan Yang Tidak Ada", "message": "Hapus Unduhan Yang Hilang",
"description": "Menu text" "description": "Menu text"
}, },
"remove_missing_downloads_question": { "remove_missing_downloads_question": {
"message": "Hapus semua unduhan yang tidak ada?", "message": "Hapus semua unduhan yang hilang?",
"description": "Messagebox text" "description": "Messagebox text"
}, },
"remove_paused_downloads": { "remove_paused_downloads": {
@ -664,7 +676,7 @@
"description": "Messagebox text" "description": "Messagebox text"
}, },
"remove_selected_complete_downloads": { "remove_selected_complete_downloads": {
"message": "Hapus Yang Selesai Di Pilihan", "message": "Hapus Yang Selesai Dari Unduhan Terpilih",
"description": "Menu text" "description": "Menu text"
}, },
"remove_selected_complete_downloads_question": { "remove_selected_complete_downloads_question": {

1170
_locales/it/messages.json Normal file

File diff suppressed because it is too large Load Diff

1170
_locales/ja/messages.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,9 @@ const CHROME_CONTEXTS = Object.freeze(new Set([
async function runContentJob(tab: Tab, file: string, msg: any) { async function runContentJob(tab: Tab, file: string, msg: any) {
try { try {
if (tab && tab.incognito && msg) {
msg.private = tab.incognito;
}
const res = await tabs.executeScript(tab.id, { const res = await tabs.executeScript(tab.id, {
file, file,
allFrames: true, allFrames: true,

View File

@ -19,6 +19,7 @@ export interface MessageSender {
export interface Tab { export interface Tab {
id?: number; id?: number;
incognito?: boolean;
} }
export interface MenuClickInfo { export interface MenuClickInfo {
@ -39,9 +40,61 @@ export interface RawPort {
postMessage: (message: any) => void; postMessage: (message: any) => void;
} }
interface WebRequestFilter {
urls?: string[];
}
interface WebRequestListener {
addListener(
callback: Function,
filter: WebRequestFilter,
extraInfoSpec: string[]
): void;
removeListener(callback: Function): void;
}
type Header = {name: string; value: string};
export interface DownloadOptions {
conflictAction: string;
filename: string;
saveAs: boolean;
url: string;
method?: string;
body?: string;
incognito?: boolean;
headers: Header[];
}
export interface DownloadsQuery {
id?: number;
}
interface Downloads {
download(download: DownloadOptions): Promise<number>;
open(manId: number): Promise<void>;
show(manId: number): Promise<void>;
pause(manId: number): Promise<void>;
resume(manId: number): Promise<void>;
cancel(manId: number): Promise<void>;
erase(query: DownloadsQuery): Promise<void>;
search(query: DownloadsQuery): Promise<any[]>;
getFileIcon(id: number, options?: any): Promise<string>;
setShelfEnabled(state: boolean): void;
onCreated: ExtensionListener;
onChanged: ExtensionListener;
onErased: ExtensionListener;
}
interface WebRequest {
onBeforeSendHeaders: WebRequestListener;
onSendHeaders: WebRequestListener;
onHeadersReceived: WebRequestListener;
}
export const {browserAction} = polyfill; export const {browserAction} = polyfill;
export const {contextMenus} = polyfill; export const {contextMenus} = polyfill;
export const {downloads} = polyfill; export const {downloads}: {downloads: Downloads} = polyfill;
export const {extension} = polyfill; export const {extension} = polyfill;
export const {history} = polyfill; export const {history} = polyfill;
export const {menus} = polyfill; export const {menus} = polyfill;
@ -51,7 +104,7 @@ export const {sessions} = polyfill;
export const {storage} = polyfill; export const {storage} = polyfill;
export const {tabs} = polyfill; export const {tabs} = polyfill;
export const {webNavigation} = polyfill; export const {webNavigation} = polyfill;
export const {webRequest} = polyfill; export const {webRequest}: {webRequest: WebRequest} = polyfill;
export const {windows} = polyfill; export const {windows} = polyfill;
export const CHROME = navigator.appVersion.includes("Chrome/"); export const CHROME = navigator.appVersion.includes("Chrome/");

View File

@ -1,7 +1,8 @@
"use strict"; "use strict";
// License: MIT // License: MIT
import { CHROME, downloads } from "../browser"; // eslint-disable-next-line no-unused-vars
import { CHROME, downloads, DownloadOptions } from "../browser";
import { Prefs } from "../prefs"; import { Prefs } from "../prefs";
import { PromiseSerializer } from "../pserializer"; import { PromiseSerializer } from "../pserializer";
import { filterInSitu, parsePath } from "../util"; import { filterInSitu, parsePath } from "../util";
@ -22,18 +23,6 @@ import {
} from "./state"; } from "./state";
import { Preroller } from "./preroller"; import { Preroller } from "./preroller";
type Header = {name: string; value: string};
interface Options {
conflictAction: string;
filename: string;
saveAs: boolean;
url: string;
method?: string;
body?: string;
incognito?: boolean;
headers: Header[];
}
export class Download extends BaseDownload { export class Download extends BaseDownload {
public manager: Manager; public manager: Manager;
@ -76,23 +65,23 @@ export class Download extends BaseDownload {
if (this.manId) { if (this.manId) {
const {manId: id} = this; const {manId: id} = this;
try { try {
const state = await downloads.search({id}); const state = (await downloads.search({id})).pop() || {};
if (state[0].state === "in_progress") { if (state.state === "in_progress" && !state.error && !state.paused) {
this.changeState(RUNNING); this.changeState(RUNNING);
this.updateStateFromBrowser(); this.updateStateFromBrowser();
return; return;
} }
if (state[0].state === "complete") { if (state.state === "complete") {
this.changeState(DONE); this.changeState(DONE);
this.updateStateFromBrowser(); this.updateStateFromBrowser();
return; return;
} }
if (!state[0].canResume) { if (!state.canResume) {
throw new Error("Cannot resume"); throw new Error("Cannot resume");
} }
// Cannot await here // Cannot await here
// Firefox bug: will not return until download is finished // Firefox bug: will not return until download is finished
downloads.resume(id).catch(() => {}); downloads.resume(id).catch(console.error);
this.changeState(RUNNING); this.changeState(RUNNING);
return; return;
} }
@ -120,7 +109,7 @@ export class Download extends BaseDownload {
return; return;
} }
} }
const options: Options = { const options: DownloadOptions = {
conflictAction: await Prefs.get("conflict-action"), conflictAction: await Prefs.get("conflict-action"),
filename: this.dest.full, filename: this.dest.full,
saveAs: false, saveAs: false,
@ -140,6 +129,12 @@ export class Download extends BaseDownload {
value: this.referrer value: this.referrer
}); });
} }
else if (CHROME) {
options.headers.push({
name: "X-DTA-ID",
value: this.sessionId.toString(),
});
}
if (this.manId) { if (this.manId) {
this.manager.removeManId(this.manId); this.manager.removeManId(this.manId);
} }
@ -319,7 +314,10 @@ export class Download extends BaseDownload {
this.markDirty(); this.markDirty();
switch (state.state) { switch (state.state) {
case "in_progress": case "in_progress":
if (error) { if (state.paused) {
this.changeState(PAUSED);
}
else if (error) {
this.cancel(); this.cancel();
this.error = error; this.error = error;
} }

View File

@ -16,8 +16,9 @@ import { Download } from "./download";
import { ManagerPort } from "./port"; import { ManagerPort } from "./port";
import { Scheduler } from "./scheduler"; import { Scheduler } from "./scheduler";
import { Limits } from "./limits"; import { Limits } from "./limits";
import { downloads, runtime } from "../browser"; import { downloads, runtime, webRequest, CHROME } from "../browser";
const US = runtime.getURL("");
const AUTOSAVE_TIMEOUT = 2000; const AUTOSAVE_TIMEOUT = 2000;
const DIRTY_TIMEOUT = 100; const DIRTY_TIMEOUT = 100;
@ -83,6 +84,14 @@ export class Manager extends EventEmitter {
Limits.on("changed", () => { Limits.on("changed", () => {
this.resetScheduler(); this.resetScheduler();
}); });
if (CHROME) {
webRequest.onBeforeSendHeaders.addListener(
this.stuffReferrer.bind(this),
{urls: ["<all_urls>"]},
["blocking", "requestHeaders", "extraHeaders"]
);
}
} }
async init() { async init() {
@ -384,6 +393,31 @@ export class Manager extends EventEmitter {
getMsgItems() { getMsgItems() {
return this.items.map(e => e.toMsg()); return this.items.map(e => e.toMsg());
} }
stuffReferrer(details: any): any {
if (details.tabId > 0 && !US.startsWith(details.initiator)) {
return undefined;
}
const sidx = details.requestHeaders.findIndex(
(e: any) => e.name.toLowerCase() === "x-dta-id");
if (sidx < 0) {
return undefined;
}
const sid = parseInt(details.requestHeaders[sidx].value, 10);
details.requestHeaders.splice(sidx, 1);
const item = this.sids.get(sid);
if (!item) {
return undefined;
}
details.requestHeaders.push({
name: "Referer",
value: (item.uReferrer || item.uURL).toString()
});
const rv: any = {
requestHeaders: details.requestHeaders
};
return rv;
}
} }
let inited: Promise<Manager>; let inited: Promise<Manager>;

View File

@ -13,6 +13,17 @@ const PREROLL_HEURISTICS = /dl|attach|download|name|file|get|retr|^n$|\.(php|asp
const PREROLL_HOSTS = /4cdn|chan/; const PREROLL_HOSTS = /4cdn|chan/;
const PREROLL_TIMEOUT = 10000; const PREROLL_TIMEOUT = 10000;
const PREROLL_NOPE = new Set<string>(); const PREROLL_NOPE = new Set<string>();
/* eslint-disable no-magic-numbers */
const NOPE_STATUSES = Object.freeze(new Set([
400,
401,
402,
405,
416,
]));
/* eslint-enable no-magic-numbers */
const PREROLL_SEARCHEXTS = Object.freeze(new Set<string>([ const PREROLL_SEARCHEXTS = Object.freeze(new Set<string>([
"php", "php",
"asp", "asp",
@ -79,7 +90,7 @@ export class Preroller {
private async prerollFirefox() { private async prerollFirefox() {
const controller = new AbortController(); const controller = new AbortController();
const {signal} = controller; const {signal} = controller;
const {uURL} = this.download; const {uURL, uReferrer} = this.download;
const res = await fetch(uURL.toString(), { const res = await fetch(uURL.toString(), {
method: "GET", method: "GET",
headers: new Headers({ headers: new Headers({
@ -87,6 +98,7 @@ export class Preroller {
}), }),
mode: "same-origin", mode: "same-origin",
signal, signal,
referrer: (uReferrer || uURL).toString(),
}); });
if (res.body) { if (res.body) {
res.body.cancel(); res.body.cancel();
@ -98,7 +110,7 @@ export class Preroller {
private async prerollChrome() { private async prerollChrome() {
let rid = ""; let rid = "";
const {uURL} = this.download; const {uURL, uReferrer} = this.download;
const rurl = uURL.toString(); const rurl = uURL.toString();
let listener: any; let listener: any;
const wr = new Promise<any[]>(resolve => { const wr = new Promise<any[]>(resolve => {
@ -132,9 +144,11 @@ export class Preroller {
const res = await fetch(rurl, { const res = await fetch(rurl, {
method: "GET", method: "GET",
headers: new Headers({ headers: new Headers({
Range: "bytes=0-1", "Range": "bytes=0-1",
"X-DTA-ID": this.download.sessionId.toString(),
}), }),
signal, signal,
referrer: (uReferrer || uURL).toString(),
}); });
if (res.body) { if (res.body) {
res.body.cancel(); res.body.cancel();
@ -204,7 +218,7 @@ export class Preroller {
else if (status === 402 || status === 407) { else if (status === 402 || status === 407) {
rv.error = "SERVER_UNAUTHORIZED"; rv.error = "SERVER_UNAUTHORIZED";
} }
else if (status === 400 || status === 405 || status === 416) { else if (NOPE_STATUSES.has(status)) {
PREROLL_NOPE.add(this.download.uURL.host); PREROLL_NOPE.add(this.download.uURL.host);
if (PREROLL_NOPE.size > 1000) { if (PREROLL_NOPE.size > 1000) {
PREROLL_NOPE.delete(PREROLL_NOPE.keys().next().value); PREROLL_NOPE.delete(PREROLL_NOPE.keys().next().value);

View File

@ -187,8 +187,8 @@ export async function select(links: BaseItem[], media: BaseItem[]) {
openPrefs(); openPrefs();
}); });
port.on("openUrls", ({urls}) => { port.on("openUrls", ({urls, incognito}) => {
openUrls(urls); openUrls(urls, incognito);
}); });
try { try {

View File

@ -55,14 +55,16 @@ export class WindowStateTracker {
getOptions(options: any) { getOptions(options: any) {
const result = Object.assign(options, { const result = Object.assign(options, {
width: this.width,
height: this.height,
state: this.state, state: this.state,
}); });
if (result.state !== "maximized") {
result.width = this.width;
result.height = this.height;
if (this.top >= 0) { if (this.top >= 0) {
result.top = this.top; result.top = this.top;
result.left = this.left; result.left = this.left;
} }
}
return result; return result;
} }

View File

@ -8,37 +8,45 @@ import DEFAULT_ICONS from "../data/icons.json";
const DONATE_URL = "https://www.downthemall.org/howto/donate/"; const DONATE_URL = "https://www.downthemall.org/howto/donate/";
const MANAGER_URL = "/windows/manager.html"; const MANAGER_URL = "/windows/manager.html";
export async function mostRecentBrowser(): Promise<any> { export async function mostRecentBrowser(incognito: boolean): Promise<any> {
let window; let window;
try { try {
window = await windows.getCurrent({windowTypes: ["normal"]}); window = await windows.getCurrent();
if (window.type !== "normal") { if (window.type !== "normal") {
throw new Error("not a normal window"); throw new Error("not a normal window");
} }
if (incognito && !window.incognito) {
throw new Error("Not incognito");
}
} }
catch { catch {
try { try {
window = await windows.getlastFocused({windowTypes: ["normal"]}); window = await windows.getlastFocused();
if (window.type !== "normal") { if (window.type !== "normal") {
throw new Error("not a normal window"); throw new Error("not a normal window");
} }
if (incognito && !window.incognito) {
throw new Error("Not incognito");
}
} }
catch { catch {
window = Array.from(await windows.getAll({windowTypes: ["normal"]})). window = Array.from(await windows.getAll({windowTypes: ["normal"]})).
filter((w: any) => w.type === "normal").pop(); filter(
(w: any) => w.type === "normal" && !!w.incognito === !!incognito).
pop();
} }
} }
if (!window) { if (!window) {
window = await windows.create({ window = await windows.create({
url: DONATE_URL, incognito: !!incognito,
type: "normal", type: "normal",
}); });
} }
return window; return window;
} }
export async function openInTab(url: string) { export async function openInTab(url: string, incognito: boolean) {
const window = await mostRecentBrowser(); const window = await mostRecentBrowser(incognito);
await tabs.create({ await tabs.create({
active: true, active: true,
url, url,
@ -47,7 +55,7 @@ export async function openInTab(url: string) {
await windows.update(window.id, {focused: true}); await windows.update(window.id, {focused: true});
} }
export async function openInTabOrFocus(url: string) { export async function openInTabOrFocus(url: string, incognito: boolean) {
const etabs = await tabs.query({ const etabs = await tabs.query({
url url
}); });
@ -57,21 +65,21 @@ export async function openInTabOrFocus(url: string) {
await windows.update(tab.windowId, {focused: true}); await windows.update(tab.windowId, {focused: true});
return; return;
} }
await openInTab(url); await openInTab(url, incognito);
} }
export async function maybeOpenInTab(url: string) { export async function maybeOpenInTab(url: string, incognito: boolean) {
const etabs = await tabs.query({ const etabs = await tabs.query({
url url
}); });
if (etabs.length) { if (etabs.length) {
return; return;
} }
await openInTab(url); await openInTab(url, incognito);
} }
export async function donate() { export async function donate() {
await openInTab(DONATE_URL); await openInTab(DONATE_URL, false);
} }
export async function openPrefs() { export async function openPrefs() {
@ -86,15 +94,15 @@ export async function openManager(focus = true) {
console.error(ex.toString(), ex); console.error(ex.toString(), ex);
} }
if (focus) { if (focus) {
await openInTabOrFocus(await runtime.getURL(MANAGER_URL)); await openInTabOrFocus(await runtime.getURL(MANAGER_URL), false);
} }
else { else {
await maybeOpenInTab(await runtime.getURL(MANAGER_URL)); await maybeOpenInTab(await runtime.getURL(MANAGER_URL), false);
} }
} }
export async function openUrls(urls: string) { export async function openUrls(urls: string, incognito: boolean) {
const window = await mostRecentBrowser(); const window = await mostRecentBrowser(incognito);
for (const url of urls) { for (const url of urls) {
try { try {
await tabs.create({ await tabs.create({

View File

@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "DownThemAll!", "name": "DownThemAll!",
"version": "4.0.10", "version": "4.0.12",
"description": "__MSG_extensionDescription__", "description": "__MSG_extensionDescription__",
"homepage_url": "https://downthemall.org/", "homepage_url": "https://downthemall.org/",
@ -34,7 +34,8 @@
"storage", "storage",
"tabs", "tabs",
"webNavigation", "webNavigation",
"webRequest" "webRequest",
"webRequestBlocking"
], ],
"background": { "background": {

View File

@ -77,6 +77,8 @@ function urlToUsable(e: any, u: string) {
} }
class Gatherer { class Gatherer {
private: boolean;
textLinks: boolean; textLinks: boolean;
selectionOnly: boolean; selectionOnly: boolean;
@ -88,6 +90,7 @@ class Gatherer {
transferable: string[]; transferable: string[];
constructor(options: any) { constructor(options: any) {
this.private = !!options.private;
this.textLinks = options.textLinks; this.textLinks = options.textLinks;
this.selectionOnly = options.selectionOnly; this.selectionOnly = options.selectionOnly;
this.selection = options.selectionOnly ? getSelection() : null; this.selection = options.selectionOnly ? getSelection() : null;
@ -255,6 +258,7 @@ class Gatherer {
return { return {
url: url.href, url: url.href,
title, title,
private: this.private
}; };
} }
catch (ex) { catch (ex) {

View File

@ -70,7 +70,7 @@ def main():
if modified: if modified:
try: try:
with open("messages.json.tmp", "w", encoding="utf-8") as outp: with open("messages.json.tmp", "w", encoding="utf-8") as outp:
json.dump(data, outp, sort_keys=True, indent=2) json.dump(data, outp, sort_keys=True, indent=2, ensure_ascii=False)
os.rename("messages.json.tmp", "_locales/en/messages.json") os.rename("messages.json.tmp", "_locales/en/messages.json")
finally: finally:
try: try:

View File

@ -26,7 +26,7 @@ UNCOMPRESSABLE = set((".png", ".jpg", ".zip", ".woff2"))
LICENSED = set((".css", ".html", ".js", "*.ts")) LICENSED = set((".css", ".html", ".js", "*.ts"))
IGNORED = set((".DS_Store", "Thumbs.db")) IGNORED = set((".DS_Store", "Thumbs.db"))
PERM_IGNORED_FX = set(("downloads.shelf", "webRequest")) PERM_IGNORED_FX = set(("downloads.shelf", "webRequest", "webRequestBlocking"))
PERM_IGNORED_CHROME = set(("menus", "sessions")) PERM_IGNORED_CHROME = set(("menus", "sessions"))
SCRIPTS = [ SCRIPTS = [

View File

@ -428,18 +428,43 @@ class SelectionTable extends VirtualTable {
} }
openSelection() { openSelection() {
const items = this.items.filter((i, idx) => this.selection.contains(idx)); const privates: BaseMatchedItem[] = [];
if (!items.length) { const items = this.items.filter((i, idx) => this.selection.contains(idx)).
filter(i => {
if (i.private) {
privates.push(i);
return false;
}
return true;
});
if (!items.length && !privates.length) {
if (this.focusRow < 0) { if (this.focusRow < 0) {
return; return;
} }
items.push(this.items.at(this.focusRow)); const item = this.items.at(this.focusRow);
if (item.private) {
privates.push(item);
} }
else {
items.push(item);
}
}
if (items.length) {
PORT.postMessage({ PORT.postMessage({
msg: "openUrls", msg: "openUrls",
urls: items.map(e => e.url) urls: items.map(e => e.url),
incognito: false,
}); });
} }
if (privates.length) {
PORT.postMessage({
msg: "openUrls",
urls: privates.map(e => e.url),
incognito: true,
});
}
}
applyDeltaTo(delta: ItemDelta[], items: ItemCollection) { applyDeltaTo(delta: ItemDelta[], items: ItemCollection) {
const active = items === this.items; const active = items === this.items;