mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 983747 - Add 'download' method to Browser API r=kanru,paolo
This commit is contained in:
parent
8a53a70162
commit
6ff9f6b846
@ -135,6 +135,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) {
|
||||
defineNoReturnMethod('goForward', this._goForward);
|
||||
defineNoReturnMethod('reload', this._reload);
|
||||
defineNoReturnMethod('stop', this._stop);
|
||||
defineMethod('download', this._download);
|
||||
defineDOMRequestMethod('purgeHistory', 'purge-history');
|
||||
defineMethod('getScreenshot', this._getScreenshot);
|
||||
defineMethod('addNextPaintListener', this._addNextPaintListener);
|
||||
@ -620,6 +621,106 @@ BrowserElementParent.prototype = {
|
||||
this._sendAsyncMsg('stop');
|
||||
},
|
||||
|
||||
_download: function(_url, _options) {
|
||||
let ioService =
|
||||
Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
|
||||
let uri = ioService.newURI(_url, null, null);
|
||||
let url = uri.QueryInterface(Ci.nsIURL);
|
||||
|
||||
// Ensure we have _options, we always use it to send the filename.
|
||||
_options = _options || {};
|
||||
if (!_options.filename) {
|
||||
_options.filename = url.fileName;
|
||||
}
|
||||
|
||||
debug('_options = ' + uneval(_options));
|
||||
|
||||
// Ensure we have a filename.
|
||||
if (!_options.filename) {
|
||||
throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
let interfaceRequestor =
|
||||
this._frameLoader.loadContext.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let req = Services.DOMRequest.createRequest(this._window);
|
||||
|
||||
function DownloadListener() {
|
||||
debug('DownloadListener Constructor');
|
||||
}
|
||||
DownloadListener.prototype = {
|
||||
extListener: null,
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
debug('DownloadListener - onStartRequest');
|
||||
let extHelperAppSvc =
|
||||
Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
|
||||
getService(Ci.nsIExternalHelperAppService);
|
||||
let channel = aRequest.QueryInterface(Ci.nsIChannel);
|
||||
|
||||
this.extListener =
|
||||
extHelperAppSvc.doContent(
|
||||
channel.contentType,
|
||||
aRequest,
|
||||
interfaceRequestor,
|
||||
true);
|
||||
this.extListener.onStartRequest(aRequest, aContext);
|
||||
},
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
debug('DownloadListener - onStopRequest (aStatusCode = ' +
|
||||
aStatusCode + ')');
|
||||
if (aStatusCode == Cr.NS_OK) {
|
||||
// Everything looks great.
|
||||
debug('DownloadListener - Download Successful.');
|
||||
this.services.DOMRequest.fireSuccess(this.req, aStatusCode);
|
||||
}
|
||||
else {
|
||||
// In case of failure, we'll simply return the failure status code.
|
||||
debug('DownloadListener - Download Failed!');
|
||||
this.services.DOMRequest.fireError(this.req, aStatusCode);
|
||||
}
|
||||
|
||||
if (this.extListener) {
|
||||
this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
|
||||
}
|
||||
},
|
||||
onDataAvailable: function(aRequest, aContext, aInputStream,
|
||||
aOffset, aCount) {
|
||||
this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
|
||||
aOffset, aCount);
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener,
|
||||
Ci.nsIRequestObserver])
|
||||
};
|
||||
|
||||
let channel = ioService.newChannelFromURI(url);
|
||||
|
||||
// XXX We would set private browsing information prior to calling this.
|
||||
channel.notificationCallbacks = interfaceRequestor;
|
||||
|
||||
// Since we're downloading our own local copy we'll want to bypass the
|
||||
// cache and local cache if the channel let's us specify this.
|
||||
let flags = Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS |
|
||||
Ci.nsIChannel.LOAD_BYPASS_CACHE;
|
||||
if (channel instanceof Ci.nsICachingChannel) {
|
||||
debug('This is a caching channel. Forcing bypass.');
|
||||
flags |= Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
|
||||
}
|
||||
|
||||
channel.loadFlags |= flags;
|
||||
|
||||
if (channel instanceof Ci.nsIHttpChannel) {
|
||||
debug('Setting HTTP referrer = ' + this._window.document.documentURIObject);
|
||||
channel.referrer = this._window.document.documentURIObject;
|
||||
if (channel instanceof Ci.nsIHttpChannelInternal) {
|
||||
channel.forceAllowThirdPartyCookie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Set-up complete, let's get things started.
|
||||
channel.asyncOpen(new DownloadListener(), null);
|
||||
|
||||
return req;
|
||||
},
|
||||
|
||||
_getScreenshot: function(_width, _height, _mimeType) {
|
||||
let width = parseInt(_width);
|
||||
let height = parseInt(_height);
|
||||
|
37
dom/browser-element/mochitest/browserElement_Download.js
Normal file
37
dom/browser-element/mochitest/browserElement_Download.js
Normal file
@ -0,0 +1,37 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 983747 - Test 'download' method on iframe.
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
var iframe;
|
||||
var downloadURL = 'http://test/tests/dom/browser-element/mochitest/file_download_bin.sjs';
|
||||
|
||||
function runTest() {
|
||||
iframe = document.createElement('iframe');
|
||||
SpecialPowers.wrap(iframe).mozbrowser = true;
|
||||
|
||||
iframe.addEventListener('mozbrowserloadend', loadend);
|
||||
iframe.src = 'data:text/html,<html><body>hello</body></html>';
|
||||
iframe.setAttribute('remote', 'true');
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
function loadend() {
|
||||
var req = iframe.download(downloadURL, { filename: 'test.bin' });
|
||||
req.onsuccess = function() {
|
||||
ok(true, 'Download finished as expected.');
|
||||
SimpleTest.finish();
|
||||
}
|
||||
req.onerror = function() {
|
||||
ok(false, 'Expected no error, got ' + req.error);
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('testready', runTest);
|
4
dom/browser-element/mochitest/file_download_bin.sjs
Normal file
4
dom/browser-element/mochitest/file_download_bin.sjs
Normal file
@ -0,0 +1,4 @@
|
||||
function handleRequest(request, response) {
|
||||
response.setHeader("Content-Type", "application/octet-stream", false);
|
||||
response.write("BIN");
|
||||
}
|
@ -30,6 +30,8 @@ skip-if = (toolkit == 'gonk' && !debug)
|
||||
[test_browserElement_oop_DOMRequestError.html]
|
||||
[test_browserElement_oop_DataURI.html]
|
||||
[test_browserElement_oop_DocumentFirstPaint.html]
|
||||
[test_browserElement_oop_Download.html]
|
||||
disabled = bug 1022281
|
||||
[test_browserElement_oop_ErrorSecurity.html]
|
||||
skip-if = (toolkit == 'gonk' && !debug)
|
||||
[test_browserElement_oop_FirstPaint.html]
|
||||
|
@ -21,6 +21,7 @@ support-files =
|
||||
browserElement_DOMRequestError.js
|
||||
browserElement_DataURI.js
|
||||
browserElement_DocumentFirstPaint.js
|
||||
browserElement_Download.js
|
||||
browserElement_ErrorSecurity.js
|
||||
browserElement_ExposableURI.js
|
||||
browserElement_FirstPaint.js
|
||||
@ -96,6 +97,7 @@ support-files =
|
||||
file_browserElement_XFrameOptionsSameOrigin.html
|
||||
file_bug709759.sjs
|
||||
file_bug741717.sjs
|
||||
file_download_bin.sjs
|
||||
file_empty.html
|
||||
file_empty_script.js
|
||||
file_focus.html
|
||||
@ -134,6 +136,8 @@ skip-if = buildapp == 'b2g'
|
||||
[test_browserElement_inproc_DOMRequestError.html]
|
||||
[test_browserElement_inproc_DataURI.html]
|
||||
[test_browserElement_inproc_DocumentFirstPaint.html]
|
||||
[test_browserElement_inproc_Download.html]
|
||||
disabled = bug 1022281
|
||||
[test_browserElement_inproc_ExposableURI.html]
|
||||
[test_browserElement_inproc_FirstPaint.html]
|
||||
[test_browserElement_inproc_ForwardName.html]
|
||||
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 983747</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_Download.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 983747</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_Download.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1391,8 +1391,18 @@ this.DownloadSaver.prototype = {
|
||||
// The start time is always available when we reach this point.
|
||||
let startPRTime = this.download.startTime.getTime() * 1000;
|
||||
|
||||
gDownloadHistory.addDownload(sourceUri, referrerUri, startPRTime,
|
||||
targetUri);
|
||||
try {
|
||||
gDownloadHistory.addDownload(sourceUri, referrerUri, startPRTime,
|
||||
targetUri);
|
||||
}
|
||||
catch(ex if ex instanceof Components.Exception &&
|
||||
ex.result == Cr.NS_ERROR_NOT_AVAILABLE) {
|
||||
//
|
||||
// Under normal operation the download history service may not
|
||||
// be available. We don't want all downloads that are public to fail
|
||||
// when this happens so we'll ignore this error and this error only!
|
||||
//
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user