forked from mirrors/gecko-dev
Backed out 4 changesets (bug 1639067) for XPCshell failures in tests/unit/test_getMIMEInfo_pdf.js. CLOSED TREE
Backed out changeset 1e400fafd80b (bug 1639067) Backed out changeset 7bb3c2ec5c7a (bug 1639067) Backed out changeset 755fd5771648 (bug 1639067) Backed out changeset 951e10b7354f (bug 1639067)
This commit is contained in:
parent
1bfd4639dc
commit
806d75bb33
22 changed files with 80 additions and 824 deletions
|
|
@ -386,11 +386,6 @@ pref("browser.download.openInSystemViewerContextMenuItem", true);
|
|||
// This records whether or not to show the 'Always open...' context menu item when appropriate
|
||||
pref("browser.download.alwaysOpenInSystemViewerContextMenuItem", true);
|
||||
|
||||
// Open downloaded file types internally for the given types.
|
||||
// This is a comma-separated list, the empty string ("") means no types are
|
||||
// viewable internally.
|
||||
pref("browser.download.viewableInternally.enabledTypes", "xml,svg,webp,avif");
|
||||
|
||||
|
||||
// This controls whether the button is automatically shown/hidden depending
|
||||
// on whether there are downloads to show.
|
||||
|
|
|
|||
|
|
@ -711,8 +711,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
Corroborate: "resource://gre/modules/Corroborate.jsm",
|
||||
Discovery: "resource:///modules/Discovery.jsm",
|
||||
DoHController: "resource:///modules/DoHController.jsm",
|
||||
DownloadsViewableInternally:
|
||||
"resource:///modules/DownloadsViewableInternally.jsm",
|
||||
ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
|
||||
FirefoxMonitor: "resource:///modules/FirefoxMonitor.jsm",
|
||||
FxAccounts: "resource://gre/modules/FxAccounts.jsm",
|
||||
|
|
@ -1126,10 +1124,6 @@ BrowserGlue.prototype = {
|
|||
// pdf content handler, and initializes parent side message manager
|
||||
// shim for privileged api access.
|
||||
PdfJs.init(this._isNewProfile);
|
||||
|
||||
// Allow certain viewable internally types to be opened from downloads.
|
||||
DownloadsViewableInternally.register();
|
||||
|
||||
break;
|
||||
case "shield-init-complete":
|
||||
this._shieldInitComplete = true;
|
||||
|
|
|
|||
|
|
@ -311,14 +311,14 @@ class DownloadsSubview extends DownloadsViewUI.BaseView {
|
|||
"temporary-block",
|
||||
button.classList.contains("temporary-block")
|
||||
);
|
||||
// menu items are conditionally displayed via CSS based on a viewable-internally attribute
|
||||
// menu items are conditionally displayed via CSS based on an is-pdf attribute
|
||||
DownloadsCommon.log(
|
||||
"DownloadsSubview, updateContextMenu, download is viewable internally? ",
|
||||
"DownloadsSubview, updateContextMenu, download is pdf? ",
|
||||
download.target.path,
|
||||
button.hasAttribute("viewable-internally")
|
||||
button.hasAttribute("is-pdf")
|
||||
);
|
||||
if (button.hasAttribute("viewable-internally")) {
|
||||
menu.setAttribute("viewable-internally", "true");
|
||||
if (button.hasAttribute("is-pdf")) {
|
||||
menu.setAttribute("is-pdf", "true");
|
||||
let alwaysUseSystemViewerItem = menu.querySelector(
|
||||
".downloadAlwaysUseSystemDefaultMenuItem"
|
||||
);
|
||||
|
|
@ -339,7 +339,7 @@ class DownloadsSubview extends DownloadsViewUI.BaseView {
|
|||
DownloadsCommon.openInSystemViewerItemEnabled
|
||||
);
|
||||
} else {
|
||||
menu.removeAttribute("viewable-internally");
|
||||
menu.removeAttribute("is-pdf");
|
||||
}
|
||||
|
||||
for (let menuitem of menu.getElementsByTagName("menuitem")) {
|
||||
|
|
|
|||
|
|
@ -31,17 +31,6 @@ XPCOMUtils.defineLazyServiceGetter(
|
|||
"nsIHandlerService"
|
||||
);
|
||||
|
||||
const { Integration } = ChromeUtils.import(
|
||||
"resource://gre/modules/Integration.jsm"
|
||||
);
|
||||
|
||||
/* global DownloadIntegration */
|
||||
Integration.downloads.defineModuleGetter(
|
||||
this,
|
||||
"DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm"
|
||||
);
|
||||
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
var gDownloadElementButtons = {
|
||||
|
|
@ -476,12 +465,11 @@ DownloadsViewUI.DownloadElementShell.prototype = {
|
|||
// This is a completed download, and the target file still exists.
|
||||
this.element.setAttribute("exists", "true");
|
||||
|
||||
this.element.toggleAttribute(
|
||||
"viewable-internally",
|
||||
DownloadIntegration.shouldViewDownloadInternally(
|
||||
DownloadsCommon.getMimeInfo(this.download)?.type
|
||||
)
|
||||
const isPDF = DownloadsCommon.isFileOfType(
|
||||
this.download,
|
||||
"application/pdf"
|
||||
);
|
||||
this.element.toggleAttribute("is-pdf", isPDF);
|
||||
|
||||
let sizeWithUnits = DownloadsViewUI.getSizeWithUnits(this.download);
|
||||
if (this.isPanel) {
|
||||
|
|
@ -753,9 +741,7 @@ DownloadsViewUI.DownloadElementShell.prototype = {
|
|||
return this.download.stopped;
|
||||
case "downloadsCmd_openInSystemViewer":
|
||||
case "downloadsCmd_alwaysOpenInSystemViewer":
|
||||
return DownloadIntegration.shouldViewDownloadInternally(
|
||||
DownloadsCommon.getMimeInfo(this.download)?.type
|
||||
);
|
||||
return DownloadsCommon.isFileOfType(this.download, "application/pdf");
|
||||
}
|
||||
return DownloadsViewUI.isCommandName(aCommand) && !!this[aCommand];
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,351 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* TODO: This is based on what PdfJs was already doing, it would be
|
||||
* best to use this over there as well to reduce duplication and
|
||||
* inconsistency.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"DownloadsViewableInternally",
|
||||
"PREF_ENABLED_TYPES",
|
||||
"PREF_BRANCH_WAS_REGISTERED",
|
||||
"PREF_BRANCH_PREVIOUS_ACTION",
|
||||
"PREF_BRANCH_PREVIOUS_ASK",
|
||||
];
|
||||
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this,
|
||||
"HandlerService",
|
||||
"@mozilla.org/uriloader/handler-service;1",
|
||||
"nsIHandlerService"
|
||||
);
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this,
|
||||
"MIMEService",
|
||||
"@mozilla.org/mime;1",
|
||||
"nsIMIMEService"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"Integration",
|
||||
"resource://gre/modules/Integration.jsm"
|
||||
);
|
||||
|
||||
const PREF_BRANCH = "browser.download.viewableInternally.";
|
||||
const PREF_ENABLED_TYPES = PREF_BRANCH + "enabledTypes";
|
||||
const PREF_BRANCH_WAS_REGISTERED = PREF_BRANCH + "typeWasRegistered.";
|
||||
const PREF_BRANCH_PREVIOUS_ACTION =
|
||||
PREF_BRANCH + "previousHandler.preferredAction.";
|
||||
const PREF_BRANCH_PREVIOUS_ASK =
|
||||
PREF_BRANCH + "previousHandler.alwaysAskBeforeHandling.";
|
||||
|
||||
let DownloadsViewableInternally = {
|
||||
/**
|
||||
* Initially add/remove handlers, watch pref, register with Integration.downloads.
|
||||
*/
|
||||
register() {
|
||||
// Watch the pref
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_enabledTypes",
|
||||
PREF_ENABLED_TYPES,
|
||||
"",
|
||||
() => this._updateAllHandlers(),
|
||||
pref => {
|
||||
let itemStr = pref.trim();
|
||||
return itemStr ? itemStr.split(",").map(s => s.trim()) : [];
|
||||
}
|
||||
);
|
||||
|
||||
for (let handlerType of this._downloadTypesViewableInternally) {
|
||||
if (handlerType.initAvailable) {
|
||||
handlerType.initAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
// Initially update handlers
|
||||
this._updateAllHandlers();
|
||||
|
||||
// Register the check for use in DownloadIntegration
|
||||
Integration.downloads.register(base => ({
|
||||
shouldViewDownloadInternally: this._shouldViewDownloadInternally.bind(
|
||||
this
|
||||
),
|
||||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
* MIME types to handle with an internal viewer, for downloaded files.
|
||||
*
|
||||
* |extension| is an extenson that will be viewable, as an alternative for
|
||||
* the MIME type itself. It is also used more generally to identify this
|
||||
* type: It is part of a pref name to indicate the handler was set up once,
|
||||
* and it is the string present in |PREF_ENABLED_TYPES| to enable the type.
|
||||
*
|
||||
* |mimeTypes| are the types that will be viewable. A handler is set up for
|
||||
* the first element in the array.
|
||||
*
|
||||
* If |managedElsewhere| is falsy, |_updateAllHandlers()| will set
|
||||
* up or remove handlers for the type, and |_shouldViewDownloadInternally()|
|
||||
* will check for it in |PREF_ENABLED_TYPES|.
|
||||
*
|
||||
* |available| is used to check whether this type should have
|
||||
* handleInternally handlers set up, and if false then
|
||||
* |_shouldViewDownloadInternally()| will also return false for this
|
||||
* type. If |available| would change, |DownloadsViewableInternally._updateHandler()|
|
||||
* should be called for the type.
|
||||
*
|
||||
* |initAvailable()| is an opportunity to initially set |available|, set up
|
||||
* observers to change it when prefs change, etc.
|
||||
*
|
||||
*/
|
||||
_downloadTypesViewableInternally: [
|
||||
{
|
||||
extension: "xml",
|
||||
mimeTypes: ["text/xml", "application/xml"],
|
||||
available: true,
|
||||
},
|
||||
{
|
||||
extension: "svg",
|
||||
mimeTypes: ["image/svg+xml"],
|
||||
|
||||
initAvailable() {
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"available",
|
||||
"svg.disabled",
|
||||
true,
|
||||
() => DownloadsViewableInternally._updateHandler(this),
|
||||
// transform disabled to enabled/available
|
||||
disabledPref => !disabledPref
|
||||
);
|
||||
},
|
||||
// available getter is set by initAvailable()
|
||||
},
|
||||
{
|
||||
extension: "webp",
|
||||
mimeTypes: ["image/webp"],
|
||||
initAvailable() {
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"available",
|
||||
"image.webp.enabled",
|
||||
false,
|
||||
() => DownloadsViewableInternally._updateHandler(this)
|
||||
);
|
||||
},
|
||||
// available getter is set by initAvailable()
|
||||
},
|
||||
{
|
||||
extension: "avif",
|
||||
mimeTypes: ["image/avif"],
|
||||
initAvailable() {
|
||||
// NOTE: This does not handle MOZ_AV1, which determines whether
|
||||
// the browser is built with AV1, and therefore AVIF, support.
|
||||
// When image.avif.enabled is set true by default in
|
||||
// StaticPrefList.yaml, it should be wrapped in #ifdef MOZ_AV1
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"available",
|
||||
"image.avif.enabled",
|
||||
false,
|
||||
() => DownloadsViewableInternally._updateHandler(this)
|
||||
);
|
||||
},
|
||||
// available getter is set by initAvailable()
|
||||
},
|
||||
{
|
||||
extension: "pdf",
|
||||
mimeTypes: ["application/pdf"],
|
||||
// PDF uses pdfjs.disabled rather than PREF_ENABLED_TYPES.
|
||||
// pdfjs.disabled isn't checked here because PdfJs's own _becomeHandler
|
||||
// and _unbecomeHandler manage the handler if the pref is set, and there
|
||||
// is an explicit check in nsUnknownContentTypeDialog.shouldShowInternalHandlerOption
|
||||
available: true,
|
||||
managedElsewhere: true,
|
||||
},
|
||||
],
|
||||
|
||||
/*
|
||||
* Implementation for DownloadIntegration.shouldViewDownloadInternally
|
||||
*/
|
||||
_shouldViewDownloadInternally(aMimeType, aExtension) {
|
||||
if (!aMimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this._downloadTypesViewableInternally.some(handlerType => {
|
||||
if (
|
||||
!handlerType.managedElsewhere &&
|
||||
!this._enabledTypes.includes(handlerType.extension)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
(handlerType.mimeTypes.includes(aMimeType) ||
|
||||
handlerType.extension == aExtension?.toLowerCase()) &&
|
||||
handlerType.available
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
_makeFakeHandler(aMimeType, aExtension) {
|
||||
// Based on PdfJs gPdfFakeHandlerInfo.
|
||||
return {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIMIMEInfo"]),
|
||||
getFileExtensions() {
|
||||
return [aExtension];
|
||||
},
|
||||
possibleApplicationHandlers: Cc["@mozilla.org/array;1"].createInstance(
|
||||
Ci.nsIMutableArray
|
||||
),
|
||||
extensionExists(ext) {
|
||||
return ext == aExtension;
|
||||
},
|
||||
alwaysAskBeforeHandling: false,
|
||||
preferredAction: Ci.nsIHandlerInfo.handleInternally,
|
||||
type: aMimeType,
|
||||
};
|
||||
},
|
||||
|
||||
_saveSettings(handlerInfo, handlerType) {
|
||||
Services.prefs.setIntPref(
|
||||
PREF_BRANCH_PREVIOUS_ACTION + handlerType.extension,
|
||||
handlerInfo.preferredAction
|
||||
);
|
||||
Services.prefs.setBoolPref(
|
||||
PREF_BRANCH_PREVIOUS_ASK + handlerType.extension,
|
||||
handlerInfo.alwaysAskBeforeHandling
|
||||
);
|
||||
},
|
||||
|
||||
_restoreSettings(handlerInfo, handlerType) {
|
||||
const prevActionPref = PREF_BRANCH_PREVIOUS_ACTION + handlerType.extension;
|
||||
if (Services.prefs.prefHasUserValue(prevActionPref)) {
|
||||
handlerInfo.alwaysAskBeforeHandling = Services.prefs.getBoolPref(
|
||||
PREF_BRANCH_PREVIOUS_ASK + handlerType.extension
|
||||
);
|
||||
handlerInfo.preferredAction = Services.prefs.getIntPref(prevActionPref);
|
||||
HandlerService.store(handlerInfo);
|
||||
} else {
|
||||
// Nothing to restore, just remove the handler.
|
||||
HandlerService.remove(handlerInfo);
|
||||
}
|
||||
},
|
||||
|
||||
_clearSavedSettings(extension) {
|
||||
Services.prefs.clearUserPref(PREF_BRANCH_PREVIOUS_ACTION + extension);
|
||||
Services.prefs.clearUserPref(PREF_BRANCH_PREVIOUS_ASK + extension);
|
||||
},
|
||||
|
||||
_updateAllHandlers() {
|
||||
// Set up or remove handlers for each type, if not done already
|
||||
for (const handlerType of this._downloadTypesViewableInternally) {
|
||||
if (!handlerType.managedElsewhere) {
|
||||
this._updateHandler(handlerType);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_updateHandler(handlerType) {
|
||||
const wasRegistered = Services.prefs.getBoolPref(
|
||||
PREF_BRANCH_WAS_REGISTERED + handlerType.extension,
|
||||
false
|
||||
);
|
||||
|
||||
const toBeRegistered =
|
||||
this._enabledTypes.includes(handlerType.extension) &&
|
||||
handlerType.available;
|
||||
|
||||
if (toBeRegistered && !wasRegistered) {
|
||||
this._becomeHandler(handlerType);
|
||||
} else if (!toBeRegistered && wasRegistered) {
|
||||
this._unbecomeHandler(handlerType);
|
||||
}
|
||||
},
|
||||
|
||||
_becomeHandler(handlerType) {
|
||||
// Set up an empty handler with only a preferred action, to avoid
|
||||
// having to ask the OS about handlers on startup.
|
||||
let fakeHandlerInfo = this._makeFakeHandler(
|
||||
handlerType.mimeTypes[0],
|
||||
handlerType.extension
|
||||
);
|
||||
if (!HandlerService.exists(fakeHandlerInfo)) {
|
||||
HandlerService.store(fakeHandlerInfo);
|
||||
} else {
|
||||
const handlerInfo = MIMEService.getFromTypeAndExtension(
|
||||
handlerType.mimeTypes[0],
|
||||
handlerType.extension
|
||||
);
|
||||
|
||||
if (handlerInfo.preferredAction != Ci.nsIHandlerInfo.handleInternally) {
|
||||
// Save the previous settings of preferredAction and
|
||||
// alwaysAskBeforeHandling in case we need to revert them.
|
||||
// Even if we don't force preferredAction here, the user could
|
||||
// set handleInternally manually.
|
||||
this._saveSettings(handlerInfo, handlerType);
|
||||
} else {
|
||||
// handleInternally shouldn't already have been set, the best we
|
||||
// can do to restore is to remove the handler, so make sure
|
||||
// the settings are clear.
|
||||
this._clearSavedSettings(handlerType.extension);
|
||||
}
|
||||
|
||||
// Replace the preferred action if it didn't indicate an external viewer.
|
||||
// Note: This is a point of departure from PdfJs, which always replaces
|
||||
// the preferred action.
|
||||
if (
|
||||
handlerInfo.preferredAction != Ci.nsIHandlerInfo.useHelperApp &&
|
||||
handlerInfo.preferredAction != Ci.nsIHandlerInfo.useSystemDefault
|
||||
) {
|
||||
handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
|
||||
handlerInfo.alwaysAskBeforeHandling = false;
|
||||
|
||||
HandlerService.store(handlerInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// Note that we set up for this type so a) we don't keep replacing the
|
||||
// handler and b) so it can be cleared later.
|
||||
Services.prefs.setBoolPref(
|
||||
PREF_BRANCH_WAS_REGISTERED + handlerType.extension,
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
_unbecomeHandler(handlerType) {
|
||||
let handlerInfo;
|
||||
try {
|
||||
handlerInfo = MIMEService.getFromTypeAndExtension(
|
||||
handlerType.mimeTypes[0],
|
||||
handlerType.extension
|
||||
);
|
||||
} catch (ex) {
|
||||
// Allow the handler lookup to fail.
|
||||
}
|
||||
// Restore preferred action if it is still handleInternally
|
||||
// (possibly just removing the handler if nothing was saved for it).
|
||||
if (handlerInfo?.preferredAction == Ci.nsIHandlerInfo.handleInternally) {
|
||||
this._restoreSettings(handlerInfo, handlerType);
|
||||
}
|
||||
|
||||
// In any case we do not control this handler now.
|
||||
this._clearSavedSettings(handlerType.extension);
|
||||
Services.prefs.clearUserPref(
|
||||
PREF_BRANCH_WAS_REGISTERED + handlerType.extension
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
@ -715,8 +715,8 @@ DownloadsPlacesView.prototype = {
|
|||
contextMenu.setAttribute("exists", "true");
|
||||
contextMenu.classList.toggle("temporary-block", !!download.hasBlockedData);
|
||||
|
||||
if (element.hasAttribute("viewable-internally")) {
|
||||
contextMenu.setAttribute("viewable-internally", "true");
|
||||
if (element.hasAttribute("is-pdf")) {
|
||||
contextMenu.setAttribute("is-pdf", "true");
|
||||
let alwaysUseSystemViewerItem = contextMenu.querySelector(
|
||||
".downloadAlwaysUseSystemDefaultMenuItem"
|
||||
);
|
||||
|
|
@ -737,7 +737,7 @@ DownloadsPlacesView.prototype = {
|
|||
DownloadsCommon.openInSystemViewerItemEnabled
|
||||
);
|
||||
} else {
|
||||
contextMenu.removeAttribute("viewable-internally");
|
||||
contextMenu.removeAttribute("is-pdf");
|
||||
}
|
||||
|
||||
if (!download.stopped) {
|
||||
|
|
|
|||
|
|
@ -99,10 +99,10 @@
|
|||
|
||||
/* the system-viewer context menu items are only shown for certain mime-types
|
||||
and can be individually enabled via prefs */
|
||||
.download-state:not([viewable-internally]) .downloadUseSystemDefaultMenuItem,
|
||||
.download-state:not([is-pdf]) .downloadUseSystemDefaultMenuItem,
|
||||
.download-state .downloadUseSystemDefaultMenuItem:not([enabled]),
|
||||
.download-state .downloadAlwaysUseSystemDefaultMenuItem:not([enabled]),
|
||||
.download-state:not([viewable-internally]) .downloadAlwaysUseSystemDefaultMenuItem
|
||||
.download-state:not([is-pdf]) .downloadAlwaysUseSystemDefaultMenuItem
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -953,8 +953,8 @@ var DownloadsView = {
|
|||
"temporary-block",
|
||||
element.classList.contains("temporary-block")
|
||||
);
|
||||
if (element.hasAttribute("viewable-internally")) {
|
||||
contextMenu.setAttribute("viewable-internally", "true");
|
||||
if (element.hasAttribute("is-pdf")) {
|
||||
contextMenu.setAttribute("is-pdf", "true");
|
||||
let alwaysUseSystemViewerItem = contextMenu.querySelector(
|
||||
".downloadAlwaysUseSystemDefaultMenuItem"
|
||||
);
|
||||
|
|
@ -975,7 +975,7 @@ var DownloadsView = {
|
|||
DownloadsCommon.openInSystemViewerItemEnabled
|
||||
);
|
||||
} else {
|
||||
contextMenu.removeAttribute("viewable-internally");
|
||||
contextMenu.removeAttribute("is-pdf");
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ EXTRA_JS_MODULES += [
|
|||
'DownloadsCommon.jsm',
|
||||
'DownloadsSubview.jsm',
|
||||
'DownloadsTaskbar.jsm',
|
||||
'DownloadsViewableInternally.jsm',
|
||||
'DownloadsViewUI.jsm',
|
||||
]
|
||||
|
||||
|
|
@ -27,4 +26,4 @@ if toolkit == 'cocoa':
|
|||
with Files('**'):
|
||||
BUG_COMPONENT = ('Firefox', 'Downloads Panel')
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const PREF_SVG_DISABLED = "svg.disabled";
|
||||
const PREF_WEBP_ENABLED = "image.webp.enabled";
|
||||
const PDF_MIME = "application/pdf";
|
||||
const OCTET_MIME = "application/octet-stream";
|
||||
const XML_MIME = "text/xml";
|
||||
const SVG_MIME = "image/svg+xml";
|
||||
const WEBP_MIME = "image/webp";
|
||||
|
||||
const { Integration } = ChromeUtils.import(
|
||||
"resource://gre/modules/Integration.jsm"
|
||||
);
|
||||
const {
|
||||
DownloadsViewableInternally,
|
||||
PREF_ENABLED_TYPES,
|
||||
PREF_BRANCH_WAS_REGISTERED,
|
||||
PREF_BRANCH_PREVIOUS_ACTION,
|
||||
PREF_BRANCH_PREVIOUS_ASK,
|
||||
} = ChromeUtils.import("resource:///modules/DownloadsViewableInternally.jsm");
|
||||
|
||||
/* global DownloadIntegration */
|
||||
Integration.downloads.defineModuleGetter(
|
||||
this,
|
||||
"DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm"
|
||||
);
|
||||
|
||||
const HandlerService = Cc[
|
||||
"@mozilla.org/uriloader/handler-service;1"
|
||||
].getService(Ci.nsIHandlerService);
|
||||
const MIMEService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
|
||||
function checkPreferInternal(mime, ext, expectedPreferInternal) {
|
||||
const handler = MIMEService.getFromTypeAndExtension(mime, ext);
|
||||
if (expectedPreferInternal) {
|
||||
Assert.equal(
|
||||
handler?.preferredAction,
|
||||
Ci.nsIHandlerInfo.handleInternally,
|
||||
`checking ${mime} preferredAction == handleInternally`
|
||||
);
|
||||
} else {
|
||||
Assert.notEqual(
|
||||
handler?.preferredAction,
|
||||
Ci.nsIHandlerInfo.handleInternally,
|
||||
`checking ${mime} preferredAction != handleInternally`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function shouldView(mime, ext) {
|
||||
return DownloadIntegration.shouldViewDownloadInternally(mime, ext);
|
||||
}
|
||||
|
||||
function checkShouldView(mime, ext, expectedShouldView) {
|
||||
Assert.equal(
|
||||
shouldView(mime, ext),
|
||||
expectedShouldView,
|
||||
`checking ${mime} shouldViewDownloadInternally`
|
||||
);
|
||||
}
|
||||
|
||||
function checkWasRegistered(ext, expectedWasRegistered) {
|
||||
Assert.equal(
|
||||
Services.prefs.getBoolPref(PREF_BRANCH_WAS_REGISTERED + ext, false),
|
||||
expectedWasRegistered,
|
||||
`checking ${ext} was registered pref`
|
||||
);
|
||||
}
|
||||
|
||||
function checkAll(mime, ext, expected) {
|
||||
checkPreferInternal(mime, ext, expected);
|
||||
checkShouldView(mime, ext, expected);
|
||||
checkWasRegistered(ext, expected);
|
||||
}
|
||||
|
||||
add_task(async function test_viewable_internally() {
|
||||
Services.prefs.setCharPref(PREF_ENABLED_TYPES, "xml , svg,webp");
|
||||
Services.prefs.setBoolPref(PREF_SVG_DISABLED, false);
|
||||
Services.prefs.setBoolPref(PREF_WEBP_ENABLED, true);
|
||||
|
||||
checkAll(XML_MIME, "xml", false);
|
||||
checkAll(SVG_MIME, "svg", false);
|
||||
checkAll(WEBP_MIME, "webp", false);
|
||||
|
||||
DownloadsViewableInternally.register();
|
||||
|
||||
checkAll(XML_MIME, "xml", true);
|
||||
checkAll(SVG_MIME, "svg", true);
|
||||
checkAll(WEBP_MIME, "webp", true);
|
||||
|
||||
// Remove SVG so it won't be cleared
|
||||
Services.prefs.clearUserPref(PREF_BRANCH_WAS_REGISTERED + "svg");
|
||||
|
||||
// Disable xml and svg, check that xml becomes disabled
|
||||
Services.prefs.setCharPref(PREF_ENABLED_TYPES, "webp");
|
||||
|
||||
checkAll(XML_MIME, "xml", false);
|
||||
checkAll(WEBP_MIME, "webp", true);
|
||||
|
||||
// SVG shouldn't be cleared
|
||||
checkPreferInternal(SVG_MIME, "svg", true);
|
||||
|
||||
Assert.ok(
|
||||
shouldView(PDF_MIME),
|
||||
"application/pdf should be unaffected by pref"
|
||||
);
|
||||
Assert.ok(
|
||||
shouldView(OCTET_MIME, "pdf"),
|
||||
".pdf should be accepted by extension"
|
||||
);
|
||||
Assert.ok(
|
||||
shouldView(OCTET_MIME, "PDF"),
|
||||
".pdf should be detected case-insensitively"
|
||||
);
|
||||
Assert.ok(!shouldView(OCTET_MIME, "exe"), ".exe shouldn't be accepted");
|
||||
|
||||
Assert.ok(!shouldView(XML_MIME), "text/xml should be disabled by pref");
|
||||
Assert.ok(!shouldView(SVG_MIME), "image/xml+svg should be disabled by pref");
|
||||
|
||||
// Enable, check that everything is enabled again
|
||||
Services.prefs.setCharPref(PREF_ENABLED_TYPES, "xml,svg,webp");
|
||||
|
||||
checkPreferInternal(XML_MIME, "xml", true);
|
||||
checkPreferInternal(SVG_MIME, "svg", true);
|
||||
|
||||
Assert.ok(
|
||||
shouldView(PDF_MIME),
|
||||
"application/pdf should be unaffected by pref"
|
||||
);
|
||||
Assert.ok(shouldView(XML_MIME), "text/xml should be enabled by pref");
|
||||
Assert.ok(
|
||||
shouldView("application/xml"),
|
||||
"alternate MIME type application/xml should be accepted"
|
||||
);
|
||||
Assert.ok(
|
||||
shouldView(OCTET_MIME, "xml"),
|
||||
".xml should be accepted by extension"
|
||||
);
|
||||
|
||||
// Disable viewable internally, pre-set handlers.
|
||||
Services.prefs.setCharPref(PREF_ENABLED_TYPES, "");
|
||||
|
||||
for (const [mime, ext, action, ask] of [
|
||||
[XML_MIME, "xml", Ci.nsIHandlerInfo.useSystemDefault, true],
|
||||
[SVG_MIME, "svg", Ci.nsIHandlerInfo.saveToDisk, true],
|
||||
[WEBP_MIME, "webp", Ci.nsIHandlerInfo.saveToDisk, false],
|
||||
]) {
|
||||
let handler = MIMEService.getFromTypeAndExtension(mime, ext);
|
||||
handler.preferredAction = action;
|
||||
handler.alwaysAskBeforeHandling = ask;
|
||||
|
||||
HandlerService.store(handler);
|
||||
checkPreferInternal(mime, ext, false);
|
||||
|
||||
// Expect to read back the same values
|
||||
handler = MIMEService.getFromTypeAndExtension(mime, ext);
|
||||
Assert.equal(handler.preferredAction, action);
|
||||
Assert.equal(handler.alwaysAskBeforeHandling, ask);
|
||||
}
|
||||
|
||||
// Enable viewable internally, XML should not be replaced, SVG and WebP should be saved.
|
||||
Services.prefs.setCharPref(PREF_ENABLED_TYPES, "svg,webp,xml");
|
||||
|
||||
Assert.equal(
|
||||
Services.prefs.getIntPref(PREF_BRANCH_PREVIOUS_ACTION + "svg"),
|
||||
Ci.nsIHandlerInfo.saveToDisk,
|
||||
"svg action should be saved"
|
||||
);
|
||||
Assert.equal(
|
||||
Services.prefs.getBoolPref(PREF_BRANCH_PREVIOUS_ASK + "svg"),
|
||||
true,
|
||||
"svg ask should be saved"
|
||||
);
|
||||
Assert.equal(
|
||||
Services.prefs.getIntPref(PREF_BRANCH_PREVIOUS_ACTION + "webp"),
|
||||
Ci.nsIHandlerInfo.saveToDisk,
|
||||
"webp action should be saved"
|
||||
);
|
||||
Assert.equal(
|
||||
Services.prefs.getBoolPref(PREF_BRANCH_PREVIOUS_ASK + "webp"),
|
||||
false,
|
||||
"webp ask should be saved"
|
||||
);
|
||||
|
||||
{
|
||||
let handler = MIMEService.getFromTypeAndExtension(XML_MIME, "xml");
|
||||
Assert.equal(
|
||||
handler.preferredAction,
|
||||
Ci.nsIHandlerInfo.useSystemDefault,
|
||||
"svg action should be preserved"
|
||||
);
|
||||
Assert.equal(
|
||||
!!handler.alwaysAskBeforeHandling,
|
||||
true,
|
||||
"svg ask should be preserved"
|
||||
);
|
||||
// Clean up
|
||||
HandlerService.remove(handler);
|
||||
}
|
||||
// It should still be possible to view XML internally
|
||||
checkShouldView(XML_MIME, "xml", true);
|
||||
checkWasRegistered("xml", true);
|
||||
|
||||
checkAll(SVG_MIME, "svg", true);
|
||||
checkAll(WEBP_MIME, "webp", true);
|
||||
|
||||
// Disable SVG to test SVG enabled check (depends on the pref)
|
||||
Services.prefs.setBoolPref(PREF_SVG_DISABLED, true);
|
||||
// Should have restored the settings from above
|
||||
{
|
||||
let handler = MIMEService.getFromTypeAndExtension(SVG_MIME, "svg");
|
||||
Assert.equal(handler.preferredAction, Ci.nsIHandlerInfo.saveToDisk);
|
||||
Assert.equal(!!handler.alwaysAskBeforeHandling, true);
|
||||
// Clean up
|
||||
HandlerService.remove(handler);
|
||||
}
|
||||
checkAll(SVG_MIME, "svg", false);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_SVG_DISABLED, false);
|
||||
checkAll(SVG_MIME, "svg", true);
|
||||
|
||||
// Test WebP enabled check (depends on the pref)
|
||||
Services.prefs.setBoolPref(PREF_WEBP_ENABLED, false);
|
||||
// Should have restored the settings from above
|
||||
{
|
||||
let handler = MIMEService.getFromTypeAndExtension(WEBP_MIME, "webp");
|
||||
Assert.equal(handler.preferredAction, Ci.nsIHandlerInfo.saveToDisk);
|
||||
Assert.equal(!!handler.alwaysAskBeforeHandling, false);
|
||||
// Clean up
|
||||
HandlerService.remove(handler);
|
||||
}
|
||||
checkAll(WEBP_MIME, "webp", false);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_WEBP_ENABLED, true);
|
||||
checkAll(WEBP_MIME, "webp", true);
|
||||
|
||||
Assert.ok(!shouldView(null, "pdf"), "missing MIME shouldn't be accepted");
|
||||
Assert.ok(!shouldView(null, "xml"), "missing MIME shouldn't be accepted");
|
||||
Assert.ok(!shouldView(OCTET_MIME), "unsupported MIME shouldn't be accepted");
|
||||
Assert.ok(!shouldView(OCTET_MIME, "exe"), ".exe shouldn't be accepted");
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
// Clear all types to remove any saved values
|
||||
Services.prefs.setCharPref(PREF_ENABLED_TYPES, "");
|
||||
// Reset to the defaults
|
||||
Services.prefs.clearUserPref(PREF_ENABLED_TYPES);
|
||||
Services.prefs.clearUserPref(PREF_SVG_DISABLED);
|
||||
Services.prefs.clearUserPref(PREF_WEBP_ENABLED);
|
||||
});
|
||||
|
|
@ -6,4 +6,3 @@ skip-if = toolkit == 'android'
|
|||
|
||||
[test_DownloadsCommon_getMimeInfo.js]
|
||||
[test_DownloadsCommon_isFileOfType.js]
|
||||
[test_DownloadsViewableInternally.js]
|
||||
|
|
|
|||
|
|
@ -26,15 +26,6 @@ ChromeUtils.defineModuleGetter(
|
|||
"CloudStorage",
|
||||
"resource://gre/modules/CloudStorage.jsm"
|
||||
);
|
||||
var { Integration } = ChromeUtils.import(
|
||||
"resource://gre/modules/Integration.jsm"
|
||||
);
|
||||
/* global DownloadIntegration */
|
||||
Integration.downloads.defineModuleGetter(
|
||||
this,
|
||||
"DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"SelectionChangedMenulist",
|
||||
|
|
@ -1958,18 +1949,7 @@ var gMainPane = {
|
|||
* applications menu.
|
||||
*/
|
||||
_loadInternalHandlers() {
|
||||
let internalHandlers = [new PDFHandlerInfoWrapper()];
|
||||
|
||||
let enabledHandlers = Services.prefs
|
||||
.getCharPref("browser.download.viewableInternally.enabledTypes", "")
|
||||
.trim();
|
||||
if (enabledHandlers) {
|
||||
for (let ext of enabledHandlers.split(",")) {
|
||||
internalHandlers.push(
|
||||
new ViewableInternallyHandlerInfoWrapper(ext.trim())
|
||||
);
|
||||
}
|
||||
}
|
||||
var internalHandlers = [new PDFHandlerInfoWrapper()];
|
||||
for (let internalHandler of internalHandlers) {
|
||||
if (internalHandler.enabled) {
|
||||
this._handledTypes[internalHandler.type] = internalHandler;
|
||||
|
|
@ -2562,7 +2542,7 @@ var gMainPane = {
|
|||
* Filter the list when the user enters a filter term into the filter field.
|
||||
*/
|
||||
filter() {
|
||||
this._rebuildView(); // FIXME: Should this be await since bug 1508156?
|
||||
this._rebuildView();
|
||||
},
|
||||
|
||||
focusFilterBox() {
|
||||
|
|
@ -3652,9 +3632,8 @@ class HandlerInfoWrapper {
|
|||
* menu.
|
||||
*/
|
||||
class InternalHandlerInfoWrapper extends HandlerInfoWrapper {
|
||||
constructor(mimeType, extension) {
|
||||
let type = gMIMEService.getFromTypeAndExtension(mimeType, extension);
|
||||
super(mimeType || type.type, type);
|
||||
constructor(mimeType) {
|
||||
super(mimeType, gMIMEService.getFromTypeAndExtension(mimeType, null));
|
||||
}
|
||||
|
||||
// Override store so we so we can notify any code listening for registration
|
||||
|
|
@ -3666,24 +3645,22 @@ class InternalHandlerInfoWrapper extends HandlerInfoWrapper {
|
|||
get enabled() {
|
||||
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
get description() {
|
||||
return { id: this._appPrefLabel };
|
||||
}
|
||||
}
|
||||
|
||||
class PDFHandlerInfoWrapper extends InternalHandlerInfoWrapper {
|
||||
constructor() {
|
||||
super(TYPE_PDF, null);
|
||||
super(TYPE_PDF);
|
||||
}
|
||||
|
||||
get _appPrefLabel() {
|
||||
return "applications-type-pdf";
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return !Services.prefs.getBoolPref(PREF_PDFJS_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
class ViewableInternallyHandlerInfoWrapper extends InternalHandlerInfoWrapper {
|
||||
constructor(extension) {
|
||||
super(null, extension);
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return DownloadIntegration.shouldViewDownloadInternally(this.type);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,12 +170,9 @@ add_task(async function dialogShowsCorrectContent() {
|
|||
let desc = dialogWin.document.getElementById("appDescription");
|
||||
let descL10n = dialogWin.document.l10n.getAttributes(desc);
|
||||
is(descL10n.id, "app-manager-handle-file", "Should have right string");
|
||||
let stringBundle = Services.strings.createBundle(
|
||||
"chrome://mozapps/locale/downloads/unknownContentType.properties"
|
||||
);
|
||||
is(
|
||||
descL10n.args.type,
|
||||
stringBundle.GetStringFromName("pdfExtHandlerDescription"),
|
||||
await dialogWin.document.l10n.formatValue("applications-type-pdf"),
|
||||
"Should have PDF string bits."
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -378,6 +378,11 @@ applications-manage-app =
|
|||
.label = Application Details…
|
||||
applications-always-ask =
|
||||
.label = Always ask
|
||||
applications-type-pdf = Portable Document Format (PDF)
|
||||
|
||||
# Variables:
|
||||
# $type (String) - the MIME type (e.g application/binary)
|
||||
applications-type-pdf-with-type = { applications-type-pdf } ({ $type })
|
||||
|
||||
# Variables:
|
||||
# $type-description (String) - Description of the type (e.g "Portable Document Format")
|
||||
|
|
|
|||
|
|
@ -698,21 +698,6 @@ var DownloadIntegration = {
|
|||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Decide whether a download of this type, opened from the downloads
|
||||
* list, should open internally.
|
||||
*
|
||||
* @param aMimeType
|
||||
* The MIME type of the file, as a string
|
||||
* @param [optional] aExtension
|
||||
* The file extension, which can match instead of the MIME type.
|
||||
*/
|
||||
shouldViewDownloadInternally(aMimeType, aExtension) {
|
||||
// Refuse all files by default, this is meant to be replaced with a check
|
||||
// for specific types via Integration.downloads.register().
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Launches a file represented by the target of a download. This can
|
||||
* open the file with the default application for the target MIME type
|
||||
|
|
@ -809,6 +794,8 @@ var DownloadIntegration = {
|
|||
return;
|
||||
}
|
||||
|
||||
const PDF_CONTENT_TYPE = "application/pdf";
|
||||
|
||||
if (!useSystemDefault && mimeInfo) {
|
||||
useSystemDefault = mimeInfo.preferredAction == mimeInfo.useSystemDefault;
|
||||
}
|
||||
|
|
@ -817,7 +804,8 @@ var DownloadIntegration = {
|
|||
if (
|
||||
aDownload.handleInternally ||
|
||||
(mimeInfo &&
|
||||
this.shouldViewDownloadInternally(mimeInfo.type, fileExtension) &&
|
||||
(mimeInfo.type == PDF_CONTENT_TYPE ||
|
||||
fileExtension?.toLowerCase() == "pdf") &&
|
||||
!mimeInfo.alwaysAskBeforeHandling &&
|
||||
mimeInfo.preferredAction === Ci.nsIHandlerInfo.handleInternally &&
|
||||
!aDownload.launchWhenSucceeded)
|
||||
|
|
|
|||
|
|
@ -16,8 +16,4 @@ unknownCancel.label=Cancel
|
|||
fileType=%S file
|
||||
# LOCALIZATION NOTE (orderedFileSizeWithType): first %S is type, second %S is size, and third %S is unit
|
||||
orderedFileSizeWithType=%1$S (%2$S %3$S)
|
||||
avifExtHandlerDescription=AV1 Image File (AVIF)
|
||||
pdfExtHandlerDescription=Portable Document Format (PDF)
|
||||
svgExtHandlerDescription=Scalable Vector Graphics (SVG)
|
||||
webpExtHandlerDescription=WebP Image
|
||||
xmlExtHandlerDescription=Extensible Markup Language (XML)
|
||||
pdfHandlerDescription=Portable Document Format
|
||||
|
|
|
|||
|
|
@ -22,16 +22,6 @@ XPCOMUtils.defineLazyServiceGetter(
|
|||
Ci.nsIApplicationReputationService
|
||||
);
|
||||
|
||||
const { Integration } = ChromeUtils.import(
|
||||
"resource://gre/modules/Integration.jsm"
|
||||
);
|
||||
/* global DownloadIntegration */
|
||||
Integration.downloads.defineModuleGetter(
|
||||
this,
|
||||
"DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm"
|
||||
);
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// // Helper Functions
|
||||
|
||||
|
|
@ -1282,6 +1272,8 @@ nsUnknownContentTypeDialog.prototype = {
|
|||
},
|
||||
|
||||
shouldShowInternalHandlerOption() {
|
||||
// This is currently available only for PDF files and when
|
||||
// pdf.js is enabled.
|
||||
let browsingContext = this.mDialog.BrowsingContext.get(
|
||||
this.mLauncher.browsingContextId
|
||||
);
|
||||
|
|
@ -1291,25 +1283,16 @@ nsUnknownContentTypeDialog.prototype = {
|
|||
// known extensions for this mimetype.
|
||||
primaryExtension = this.mLauncher.MIMEInfo.primaryExtension;
|
||||
} catch (e) {}
|
||||
|
||||
// Only available for PDF files when pdf.js is enabled.
|
||||
// Skip if the current window uses the resource scheme, to avoid
|
||||
// showing the option when using the Download button in pdf.js.
|
||||
if (primaryExtension == "pdf") {
|
||||
return (
|
||||
!browsingContext?.currentWindowGlobal?.documentPrincipal?.URI?.schemeIs(
|
||||
"resource"
|
||||
) &&
|
||||
!Services.prefs.getBoolPref("pdfjs.disabled", true) &&
|
||||
Services.prefs.getBoolPref(
|
||||
"browser.helperApps.showOpenOptionForPdfJS",
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return DownloadIntegration.shouldViewDownloadInternally(
|
||||
this.mLauncher.MIMEInfo.MIMEType
|
||||
return (
|
||||
!browsingContext?.currentWindowGlobal?.documentPrincipal?.URI?.schemeIs(
|
||||
"resource"
|
||||
) &&
|
||||
primaryExtension == "pdf" &&
|
||||
!Services.prefs.getBoolPref("pdfjs.disabled", true) &&
|
||||
Services.prefs.getBoolPref(
|
||||
"browser.helperApps.showOpenOptionForPdfJS",
|
||||
false
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -539,16 +539,6 @@ static const nsDefaultMimeTypeEntry nonDecodableExtensions[] = {
|
|||
{APPLICATION_COMPRESS, "z"},
|
||||
{APPLICATION_GZIP, "svgz"}};
|
||||
|
||||
/**
|
||||
* Primary extensions of types whose descriptions should be overwritten.
|
||||
* This extension is concatenated with "ExtHandlerDescription" to look up the
|
||||
* description in unknownContentType.properties.
|
||||
* NOTE: These MUST be lower-case and ASCII.
|
||||
*/
|
||||
static const char* descriptionOverwriteExtensions[] = {
|
||||
"avif", "pdf", "svg", "webp", "xml",
|
||||
};
|
||||
|
||||
static StaticRefPtr<nsExternalHelperAppService> sExtHelperAppSvcSingleton;
|
||||
|
||||
/**
|
||||
|
|
@ -2576,6 +2566,28 @@ NS_IMETHODIMP nsExternalHelperAppService::GetFromTypeAndExtension(
|
|||
found = found || NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
// Next, overwrite with generic description if the extension is PDF
|
||||
// since the file format is supported by Firefox and we don't want
|
||||
// other brands positioning themselves as the sole viewer for a system.
|
||||
if (aFileExt.LowerCaseEqualsASCII("pdf") ||
|
||||
aFileExt.LowerCaseEqualsASCII(".pdf")) {
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIStringBundle> unknownContentTypeBundle;
|
||||
rv = bundleService->CreateBundle(
|
||||
"chrome://mozapps/locale/downloads/unknownContentType.properties",
|
||||
getter_AddRefs(unknownContentTypeBundle));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString pdfHandlerDescription;
|
||||
rv = unknownContentTypeBundle->GetStringFromName("pdfHandlerDescription",
|
||||
pdfHandlerDescription);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
(*_retval)->SetDescription(pdfHandlerDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now, let's see if we can find something in our datastore.
|
||||
// This will not overwrite the OS information that interests us
|
||||
// (i.e. default application, default app. description)
|
||||
|
|
@ -2645,37 +2657,6 @@ NS_IMETHODIMP nsExternalHelperAppService::GetFromTypeAndExtension(
|
|||
}
|
||||
}
|
||||
|
||||
// Overwrite with a generic description if the primary extension for the
|
||||
// type is in our list; these are file formats supported by Firefox and
|
||||
// we don't want other brands positioning themselves as the sole viewer
|
||||
// for a system.
|
||||
nsAutoCString primaryExtension;
|
||||
rv = (*_retval)->GetPrimaryExtension(primaryExtension);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
for (const char* ext : descriptionOverwriteExtensions) {
|
||||
if (primaryExtension.Equals(ext)) {
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIStringBundle> unknownContentTypeBundle;
|
||||
rv = bundleService->CreateBundle(
|
||||
"chrome://mozapps/locale/downloads/unknownContentType.properties",
|
||||
getter_AddRefs(unknownContentTypeBundle));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoCString stringName(ext);
|
||||
stringName.AppendLiteral("ExtHandlerDescription");
|
||||
nsAutoString handlerDescription;
|
||||
rv = unknownContentTypeBundle->GetStringFromName(stringName.get(),
|
||||
handlerDescription);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
(*_retval)->SetDescription(handlerDescription);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString type;
|
||||
(*_retval)->GetMIMEType(type);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ support-files =
|
|||
file_pdf_binary_octet_stream.pdf^headers^
|
||||
file_txt_attachment_test.txt
|
||||
file_txt_attachment_test.txt^headers^
|
||||
file_xml_attachment_test.xml
|
||||
file_xml_attachment_test.xml^headers^
|
||||
[browser_download_urlescape.js]
|
||||
support-files =
|
||||
file_with@@funny_name.png
|
||||
|
|
|
|||
|
|
@ -390,44 +390,11 @@ add_task(async function test_check_open_with_external_then_internal() {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Check that the "Open with internal handler" option is presented
|
||||
* for other viewable internally types.
|
||||
*/
|
||||
add_task(
|
||||
async function test_internal_handler_hidden_with_viewable_internally_type() {
|
||||
let dialogWindowPromise = BrowserTestUtils.domWindowOpenedAndLoaded();
|
||||
let loadingTab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
TEST_PATH + "file_xml_attachment_test.xml"
|
||||
);
|
||||
let dialogWindow = await dialogWindowPromise;
|
||||
is(
|
||||
dialogWindow.location.href,
|
||||
"chrome://mozapps/content/downloads/unknownContentType.xhtml",
|
||||
"Should have seen the unknown content dialogWindow."
|
||||
);
|
||||
let doc = dialogWindow.document;
|
||||
let internalHandlerRadio = doc.querySelector("#handleInternally");
|
||||
|
||||
// Prevent racing with initialization of the dialog and make sure that
|
||||
// the final state of the dialog has the correct visibility of the internal-handler option.
|
||||
await waitForAcceptButtonToGetEnabled(doc);
|
||||
|
||||
ok(!internalHandlerRadio.hidden, "The option should be visible for XML");
|
||||
ok(internalHandlerRadio.selected, "The option should be selected");
|
||||
|
||||
let dialog = doc.querySelector("#unknownContentType");
|
||||
dialog.cancelDialog();
|
||||
BrowserTestUtils.removeTab(loadingTab);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Check that the "Open with internal handler" option is not presented
|
||||
* for non-PDF, non-viewable-internally types.
|
||||
* for non-PDF types.
|
||||
*/
|
||||
add_task(async function test_internal_handler_hidden_with_other_type() {
|
||||
add_task(async function test_internal_handler_hidden_with_nonpdf_type() {
|
||||
let dialogWindowPromise = BrowserTestUtils.domWindowOpenedAndLoaded();
|
||||
let loadingTab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version = "1.0" encoding = "utf-8"?>
|
||||
|
||||
<something>
|
||||
</something>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Content-Disposition: attachment; filename=file_xml_attachment_test.xml
|
||||
Content-Type: text/xml
|
||||
Loading…
Reference in a new issue