diff --git a/browser/components/downloads/content/allDownloadsViewOverlay.js b/browser/components/downloads/content/allDownloadsViewOverlay.js
index 021435519537..7165ee296e36 100644
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.js
@@ -302,8 +302,11 @@ HistoryDownloadElementShell.prototype = {
if (this.element.selected) {
goUpdateDownloadCommands();
+ } else {
+ // If a state change occurs in an item that is not currently selected,
+ // this is the only command that may be affected.
+ goUpdateCommand("downloadsCmd_clearDownloads");
}
- goUpdateCommand("downloadsCmd_clearDownloads");
},
onChanged() {
@@ -1136,8 +1139,7 @@ DownloadsPlacesView.prototype = {
// nsIController
supportsCommand(aCommand) {
// Firstly, determine if this is a command that we can handle.
- if (!aCommand.startsWith("cmd_") &&
- !aCommand.startsWith("downloadsCmd_")) {
+ if (!DownloadsViewUI.isCommandName(aCommand)) {
return false;
}
if (!(aCommand in this) &&
@@ -1418,11 +1420,11 @@ for (let methodName of ["load", "applyFilter", "selectNode", "selectItems"]) {
function goUpdateDownloadCommands() {
function updateCommandsForObject(object) {
for (let name in object) {
- if (name.startsWith("cmd_") || name.startsWith("downloadsCmd_")) {
+ if (DownloadsViewUI.isCommandName(name)) {
goUpdateCommand(name);
}
}
}
- updateCommandsForObject(this);
+ updateCommandsForObject(DownloadsPlacesView.prototype);
updateCommandsForObject(HistoryDownloadElementShell.prototype);
}
diff --git a/browser/components/downloads/content/downloads.css b/browser/components/downloads/content/downloads.css
index a15fabf448ac..04210fc7963f 100644
--- a/browser/components/downloads/content/downloads.css
+++ b/browser/components/downloads/content/downloads.css
@@ -177,6 +177,15 @@ richlistitem.download button {
display: none;
}
+/* Make the panel wide enough to show the download list items without improperly
+ truncating them. */
+#downloadsPanel-multiView > .panel-viewcontainer,
+#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack,
+#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack > .panel-mainview {
+ overflow: visible;
+ max-width: unset;
+}
+
/* Show the "show blocked info" button. */
#downloadsPanel-mainView .download-state[state="8"] .downloadShowBlockedInfo {
display: inline;
@@ -186,12 +195,12 @@ richlistitem.download button {
/* The subview should be off to the right and not visible at all. */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype=main] > .panel-subviews {
- transform: translateX(100%);
+ transform: translateX(101%);
transition: transform var(--panelui-subview-transition-duration);
}
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype=main] > .panel-subviews:-moz-locale-dir(rtl) {
- transform: translateX(-100%);
+ transform: translateX(-101%);
}
/** When the subview is showing... **/
diff --git a/browser/components/downloads/content/downloadsOverlay.xul b/browser/components/downloads/content/downloadsOverlay.xul
index 5932246e9660..1a7d00bee42c 100644
--- a/browser/components/downloads/content/downloadsOverlay.xul
+++ b/browser/components/downloads/content/downloadsOverlay.xul
@@ -134,7 +134,7 @@
onkeydown="DownloadsSummary.onKeyDown(event);"
onclick="DownloadsSummary.onClick(event);">
-
+
.downloadTypeIcon {
list-style-image: url("chrome://browser/skin/downloads/download-summary.png");
}
@@ -87,7 +99,7 @@ richlistitem[type="download"]:last-child {
border-bottom: 1px solid transparent;
}
-.downloadStackIcon {
+.downloadTypeIcon {
--inline-offset: 8px;
--block-offset: 4px;
--icon-size: 32px;
diff --git a/caps/moz.build b/caps/moz.build
index 92afc4b7b9e5..b54bb9bb1529 100644
--- a/caps/moz.build
+++ b/caps/moz.build
@@ -6,6 +6,7 @@
MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
+BROWSER_CHROME_MANIFESTS += ['tests/mochitest/browser.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
# Hack to make this file available as a resource:// URI.
diff --git a/caps/tests/mochitest/browser.ini b/caps/tests/mochitest/browser.ini
new file mode 100644
index 000000000000..d8a1278f9b0d
--- /dev/null
+++ b/caps/tests/mochitest/browser.ini
@@ -0,0 +1 @@
+[browser_checkloaduri.js]
diff --git a/caps/tests/mochitest/browser_checkloaduri.js b/caps/tests/mochitest/browser_checkloaduri.js
new file mode 100644
index 000000000000..e229b4049d57
--- /dev/null
+++ b/caps/tests/mochitest/browser_checkloaduri.js
@@ -0,0 +1,121 @@
+"use strict";
+
+let ssm = Services.scriptSecurityManager;
+
+const URLs = new Map([
+ ["http://www.example.com", [
+ // For each of these entries, the booleans represent whether the parent URI can:
+ // - load them
+ // - load them without principal inheritance
+ // - whether the URI can be created at all (some protocol handlers will
+ // refuse to create certain variants)
+ ["http://www.example2.com", true, true, true],
+ ["feed:http://www.example2.com", false, false, true],
+ ["https://www.example2.com", true, true, true],
+ ["chrome://foo/content/bar.xul", false, false, true],
+ ["feed:chrome://foo/content/bar.xul", false, false, false],
+ ["view-source:http://www.example2.com", false, false, true],
+ ["view-source:feed:http://www.example2.com", false, false, true],
+ ["feed:view-source:http://www.example2.com", false, false, false],
+ ["data:text/html,Hi", true, false, true],
+ ["javascript:alert('hi')", true, false, true],
+ ]],
+ ["feed:http://www.example.com", [
+ ["http://www.example2.com", true, true, true],
+ ["feed:http://www.example2.com", true, true, true],
+ ["https://www.example2.com", true, true, true],
+ ["feed:https://www.example2.com", false, false, true],
+ ["chrome://foo/content/bar.xul", false, false, true],
+ ["feed:chrome://foo/content/bar.xul", false, false, false],
+ ["view-source:http://www.example2.com", false, false, true],
+ ["view-source:feed:http://www.example2.com", false, false, true],
+ ["feed:view-source:http://www.example2.com", false, false, false],
+ ["data:text/html,Hi", true, false, true],
+ ["javascript:alert('hi')", true, false, true],
+ ]],
+ ["view-source:http://www.example.com", [
+ ["http://www.example2.com", true, true, true],
+ ["feed:http://www.example2.com", false, false, true],
+ ["https://www.example2.com", true, true, true],
+ ["feed:https://www.example2.com", false, false, true],
+ ["chrome://foo/content/bar.xul", false, false, true],
+ ["feed:chrome://foo/content/bar.xul", false, false, false],
+ ["view-source:http://www.example2.com", true, true, true],
+ ["view-source:feed:http://www.example2.com", false, false, true],
+ ["feed:view-source:http://www.example2.com", false, false, false],
+ ["data:text/html,Hi", true, false, true],
+ ["javascript:alert('hi')", true, false, true],
+ ]],
+]);
+
+function testURL(source, target, canLoad, canLoadWithoutInherit, canCreate, flags) {
+ let threw = false;
+ let targetURI;
+ try {
+ targetURI = makeURI(target);
+ } catch (ex) {
+ ok(!canCreate, "Shouldn't be passing URIs that we can't create. Failed to create: " + target);
+ return;
+ }
+ ok(canCreate, "Created a URI for " + target + " which should " +
+ (canCreate ? "" : "not ") + "be possible.");
+ try {
+ ssm.checkLoadURIWithPrincipal(source, targetURI, flags);
+ } catch (ex) {
+ info(ex.message);
+ threw = true;
+ }
+ let inheritDisallowed = flags & ssm.DISALLOW_INHERIT_PRINCIPAL;
+ let shouldThrow = inheritDisallowed ? !canLoadWithoutInherit : !canLoad;
+ ok(threw == shouldThrow,
+ "Should " + (shouldThrow ? "" : "not ") + "throw an error when loading " +
+ target + " from " + source.URI.spec +
+ (inheritDisallowed ? " without" : " with") + " principal inheritance.");
+}
+
+add_task(function* () {
+ let baseFlags = ssm.STANDARD | ssm.DONT_REPORT_ERRORS;
+ for (let [sourceString, targetsAndExpectations] of URLs) {
+ let source = ssm.createCodebasePrincipal(makeURI(sourceString), {});
+ for (let [target, canLoad, canLoadWithoutInherit, canCreate] of targetsAndExpectations) {
+ testURL(source, target, canLoad, canLoadWithoutInherit, canCreate, baseFlags);
+ testURL(source, target, canLoad, canLoadWithoutInherit, canCreate,
+ baseFlags | ssm.DISALLOW_INHERIT_PRINCIPAL);
+ }
+ }
+
+ // Now test blob URIs, which we need to do in-content.
+ yield BrowserTestUtils.withNewTab("http://www.example.com/", function* (browser) {
+ yield ContentTask.spawn(
+ browser,
+ testURL.toString(),
+ function* (testURLFn) {
+ let testURL = eval("(" + testURLFn + ")");
+ let ssm = Services.scriptSecurityManager;
+ let baseFlags = ssm.STANDARD | ssm.DONT_REPORT_ERRORS;
+ let makeURI = Cu.import("resource://gre/modules/BrowserUtils.jsm", {}).BrowserUtils.makeURI;
+ let b = new content.Blob(["I am a blob"]);
+ let contentBlobURI = content.URL.createObjectURL(b);
+ let contentPrincipal = content.document.nodePrincipal;
+ // Loading this blob URI from the content page should work:
+ testURL(contentPrincipal, contentBlobURI, true, true, true, baseFlags);
+ testURL(contentPrincipal, contentBlobURI, true, true, true,
+ baseFlags | ssm.DISALLOW_INHERIT_PRINCIPAL);
+
+ testURL(contentPrincipal, "view-source:" + contentBlobURI, false, false, true,
+ baseFlags);
+ testURL(contentPrincipal, "view-source:" + contentBlobURI, false, false, true,
+ baseFlags | ssm.DISALLOW_INHERIT_PRINCIPAL);
+
+ // Feed URIs for blobs can't be created, so need to pass false as the fourth param.
+ for (let prefix of ["feed:", "view-source:feed:", "feed:view-source:"]) {
+ testURL(contentPrincipal, prefix + contentBlobURI, false, false, false,
+ baseFlags);
+ testURL(contentPrincipal, prefix + contentBlobURI, false, false, false,
+ baseFlags | ssm.DISALLOW_INHERIT_PRINCIPAL);
+ }
+ }
+ );
+
+ });
+});
diff --git a/devtools/client/shared/widgets/HTMLTooltip.js b/devtools/client/shared/widgets/HTMLTooltip.js
index eae02346c69a..cd15a5799c52 100644
--- a/devtools/client/shared/widgets/HTMLTooltip.js
+++ b/devtools/client/shared/widgets/HTMLTooltip.js
@@ -570,7 +570,7 @@ HTMLTooltip.prototype = {
// Use type="arrow" to prevent side effects (see Bug 1285206)
panel.setAttribute("type", "arrow");
- panel.setAttribute("level", "float");
+ panel.setAttribute("level", "top");
panel.setAttribute("class", "tooltip-xul-wrapper");
return panel;
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index f9e297ba9a2c..37f1bb288f0c 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1031,7 +1031,6 @@ void HTMLMediaElement::NoSupportedMediaSourceError()
DispatchAsyncEvent(NS_LITERAL_STRING("error"));
ChangeDelayLoadStatus(false);
UpdateAudioChannelPlayingState();
- OpenUnsupportedMediaWithExtenalAppIfNeeded();
}
typedef void (HTMLMediaElement::*SyncSectionFn)();
@@ -2698,10 +2697,6 @@ HTMLMediaElement::PlayInternal(bool aCallerIsChrome)
UpdateSrcMediaStreamPlaying();
UpdateAudioChannelPlayingState();
- // The check here is to handle the case that the media element starts playing
- // after it loaded fail. eg. preload the data before playing.
- OpenUnsupportedMediaWithExtenalAppIfNeeded();
-
return NS_OK;
}
@@ -3202,26 +3197,28 @@ nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder");
- aChannel->GetContentType(mMimeType);
- NS_ASSERTION(!mMimeType.IsEmpty(), "We should have the Content-Type.");
+ nsAutoCString mimeType;
+
+ aChannel->GetContentType(mimeType);
+ NS_ASSERTION(!mimeType.IsEmpty(), "We should have the Content-Type.");
DecoderDoctorDiagnostics diagnostics;
RefPtr decoder =
- DecoderTraits::CreateDecoder(mMimeType, this, &diagnostics);
+ DecoderTraits::CreateDecoder(mimeType, this, &diagnostics);
diagnostics.StoreFormatDiagnostics(OwnerDoc(),
- NS_ConvertASCIItoUTF16(mMimeType),
+ NS_ConvertASCIItoUTF16(mimeType),
decoder != nullptr,
__func__);
if (!decoder) {
nsAutoString src;
GetCurrentSrc(src);
- NS_ConvertUTF8toUTF16 mimeUTF16(mMimeType);
+ NS_ConvertUTF8toUTF16 mimeUTF16(mimeType);
const char16_t* params[] = { mimeUTF16.get(), src.get() };
ReportLoadError("MediaLoadUnsupportedMimeType", params, ArrayLength(params));
return NS_ERROR_FAILURE;
}
- LOG(LogLevel::Debug, ("%p Created decoder %p for type %s", this, decoder.get(), mMimeType.get()));
+ LOG(LogLevel::Debug, ("%p Created decoder %p for type %s", this, decoder.get(), mimeType.get()));
RefPtr resource =
MediaResource::Create(decoder->GetResourceCallback(), aChannel);
@@ -3237,7 +3234,7 @@ nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
// We postpone the |FinishDecoderSetup| function call until we get
// |OnConnected| signal from MediaStreamController which is held by
// RtspMediaResource.
- if (DecoderTraits::DecoderWaitsForOnConnected(mMimeType)) {
+ if (DecoderTraits::DecoderWaitsForOnConnected(mimeType)) {
decoder->SetResource(resource);
SetDecoder(decoder);
if (aListener) {
@@ -5935,43 +5932,6 @@ HTMLMediaElement::IsAudible() const
return true;
}
-bool
-HTMLMediaElement::HaveFailedWithSourceNotSupportedError() const
-{
- if (!mError) {
- return false;
- }
-
- uint16_t errorCode;
- mError->GetCode(&errorCode);
- return (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE &&
- errorCode == nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
-}
-
-void
-HTMLMediaElement::OpenUnsupportedMediaWithExtenalAppIfNeeded()
-{
- if (!Preferences::GetBool("media.openUnsupportedTypeWithExternalApp")) {
- return;
- }
-
- if (!HaveFailedWithSourceNotSupportedError()) {
- return;
- }
-
- // If media doesn't start playing, we don't need to open it.
- if (mPaused) {
- return;
- }
-
- LOG(LogLevel::Debug, ("Open unsupported type \'%s\' with external apps.",
- mMimeType.get()));
- nsContentUtils::DispatchTrustedEvent(OwnerDoc(), static_cast(this),
- NS_LITERAL_STRING("OpenMediaWithExternalApp"),
- true,
- true);
-}
-
static const char* VisibilityString(Visibility aVisibility) {
switch(aVisibility) {
case Visibility::UNTRACKED: {
diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h
index 08b0887cc70a..40ffe2a10610 100644
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1193,9 +1193,6 @@ protected:
bool IsAllowedToPlay();
bool IsAudible() const;
- bool HaveFailedWithSourceNotSupportedError() const;
-
- void OpenUnsupportedMediaWithExtenalAppIfNeeded();
class nsAsyncEventRunner;
using nsGenericHTMLElement::DispatchEvent;
@@ -1636,8 +1633,6 @@ private:
// True if media element is audible for users.
bool mAudible;
-
- nsAutoCString mMimeType;
};
} // namespace dom
diff --git a/mobile/android/app/lint.xml b/mobile/android/app/lint.xml
index 484be1ba80a2..6d818a6c1f19 100644
--- a/mobile/android/app/lint.xml
+++ b/mobile/android/app/lint.xml
@@ -15,6 +15,11 @@
+
+
+