Refactoring download button logic
This commit is contained in:
parent
077f08fa6d
commit
ef658bf5f1
86
web/download_manager.js
Normal file
86
web/download_manager.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* Copyright 2013 Mozilla Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/* globals URL*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var DownloadManager = (function DownloadManagerClosure() {
|
||||||
|
|
||||||
|
function download(blobUrl, filename) {
|
||||||
|
var a = document.createElement('a');
|
||||||
|
if (a.click) {
|
||||||
|
// Use a.click() if available. Otherwise, Chrome might show
|
||||||
|
// "Unsafe JavaScript attempt to initiate a navigation change
|
||||||
|
// for frame with URL" and not open the PDF at all.
|
||||||
|
// Supported by (not mentioned = untested):
|
||||||
|
// - Firefox 6 - 19 (4- does not support a.click, 5 ignores a.click)
|
||||||
|
// - Chrome 19 - 26 (18- does not support a.click)
|
||||||
|
// - Opera 9 - 12.15
|
||||||
|
// - Internet Explorer 6 - 10
|
||||||
|
// - Safari 6 (5.1- does not support a.click)
|
||||||
|
a.href = blobUrl;
|
||||||
|
a.target = '_parent';
|
||||||
|
// Use a.download if available. This increases the likelihood that
|
||||||
|
// the file is downloaded instead of opened by another PDF plugin.
|
||||||
|
if ('download' in a) {
|
||||||
|
a.download = filename;
|
||||||
|
}
|
||||||
|
// <a> must be in the document for IE and recent Firefox versions.
|
||||||
|
// (otherwise .click() is ignored)
|
||||||
|
(document.body || document.documentElement).appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.parentNode.removeChild(a);
|
||||||
|
} else {
|
||||||
|
if (window.top === window &&
|
||||||
|
blobUrl.split('#')[0] === window.location.href.split('#')[0]) {
|
||||||
|
// If _parent == self, then opening an identical URL with different
|
||||||
|
// location hash will only cause a navigation, not a download.
|
||||||
|
var padCharacter = blobUrl.indexOf('?') === -1 ? '?' : '&';
|
||||||
|
blobUrl = blobUrl.replace(/#|$/, padCharacter + '$&');
|
||||||
|
}
|
||||||
|
window.open(blobUrl, '_parent');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function DownloadManager() {}
|
||||||
|
|
||||||
|
DownloadManager.prototype = {
|
||||||
|
downloadUrl: function DownloadManager_downloadUrl(url, filename) {
|
||||||
|
download(url + '#pdfjs.action=download', filename);
|
||||||
|
},
|
||||||
|
|
||||||
|
download: function DownloadManager_download(blob, url, filename) {
|
||||||
|
if (!URL) {
|
||||||
|
// URL.createObjectURL is not supported
|
||||||
|
this.downloadUrl(url, filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigator.msSaveBlob) {
|
||||||
|
// IE10 / IE11
|
||||||
|
if (!navigator.msSaveBlob(blob, filename)) {
|
||||||
|
this.downloadUrl(url, filename);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var blobUrl = URL.createObjectURL(blob);
|
||||||
|
download(blobUrl, filename);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return DownloadManager;
|
||||||
|
})();
|
@ -1,3 +1,4 @@
|
|||||||
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
/* Copyright 2012 Mozilla Foundation
|
/* Copyright 2012 Mozilla Foundation
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -13,9 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var FirefoxCom = (function FirefoxComClosure() {
|
'use strict';
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
var FirefoxCom = (function FirefoxComClosure() {
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* Creates an event that the extension is listening for and will
|
* Creates an event that the extension is listening for and will
|
||||||
@ -69,3 +70,35 @@ var FirefoxCom = (function FirefoxComClosure() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var DownloadManager = (function DownloadManagerClosure() {
|
||||||
|
function DownloadManager() {}
|
||||||
|
|
||||||
|
DownloadManager.prototype = {
|
||||||
|
downloadUrl: function DownloadManager_downloadUrl(url) {
|
||||||
|
FirefoxCom.request('download', {
|
||||||
|
originalUrl: url,
|
||||||
|
filename: this.filename
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
download: function DownloadManager_download(blob, url) {
|
||||||
|
var blobUrl = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
FirefoxCom.request('download', {
|
||||||
|
blobUrl: blobUrl,
|
||||||
|
originalUrl: url,
|
||||||
|
filename: this.filename
|
||||||
|
},
|
||||||
|
function response(err) {
|
||||||
|
if (err && this.onerror) {
|
||||||
|
this.onerror(err);
|
||||||
|
}
|
||||||
|
window.URL.revokeObjectURL(blobUrl);
|
||||||
|
}.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return DownloadManager;
|
||||||
|
})();
|
||||||
|
@ -91,6 +91,61 @@ function getOutputScale() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrolls specified element into view of its parent.
|
||||||
|
* element {Object} The element to be visible.
|
||||||
|
* spot {Object} The object with the top property -- offset from the top edge.
|
||||||
|
*/
|
||||||
|
function scrollIntoView(element, spot) {
|
||||||
|
// Assuming offsetParent is available (it's not available when viewer is in
|
||||||
|
// hidden iframe or object). We have to scroll: if the offsetParent is not set
|
||||||
|
// producing the error. See also animationStartedClosure.
|
||||||
|
var parent = element.offsetParent;
|
||||||
|
var offsetY = element.offsetTop + element.clientTop;
|
||||||
|
if (!parent) {
|
||||||
|
console.error('offsetParent is not set -- cannot scroll');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (parent.clientHeight == parent.scrollHeight) {
|
||||||
|
offsetY += parent.offsetTop;
|
||||||
|
parent = parent.offsetParent;
|
||||||
|
if (!parent)
|
||||||
|
return; // no need to scroll
|
||||||
|
}
|
||||||
|
if (spot)
|
||||||
|
offsetY += spot.top;
|
||||||
|
parent.scrollTop = offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the filename or guessed filename from the url (see issue 3455).
|
||||||
|
* url {String} The original PDF location.
|
||||||
|
* @return {String} Guessed PDF file name.
|
||||||
|
*/
|
||||||
|
function getPDFFileNameFromURL(url) {
|
||||||
|
var reURI = /^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
|
||||||
|
// SCHEME HOST 1.PATH 2.QUERY 3.REF
|
||||||
|
// Pattern to get last matching NAME.pdf
|
||||||
|
var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
|
||||||
|
var splitURI = reURI.exec(url);
|
||||||
|
var suggestedFilename = reFilename.exec(splitURI[1]) ||
|
||||||
|
reFilename.exec(splitURI[2]) ||
|
||||||
|
reFilename.exec(splitURI[3]);
|
||||||
|
if (suggestedFilename) {
|
||||||
|
suggestedFilename = suggestedFilename[0];
|
||||||
|
if (suggestedFilename.indexOf('%') != -1) {
|
||||||
|
// URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
|
||||||
|
try {
|
||||||
|
suggestedFilename =
|
||||||
|
reFilename.exec(decodeURIComponent(suggestedFilename))[0];
|
||||||
|
} catch(e) { // Possible (extremely rare) errors:
|
||||||
|
// URIError "Malformed URI", e.g. for "%AA.pdf"
|
||||||
|
// TypeError "null has no properties", e.g. for "%2F.pdf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suggestedFilename || 'document.pdf';
|
||||||
|
}
|
||||||
|
|
||||||
var ProgressBar = (function ProgressBarClosure() {
|
var ProgressBar = (function ProgressBarClosure() {
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<!--#if !PRODUCTION-->
|
<!--#if !PRODUCTION-->
|
||||||
<script type="text/javascript" src="ui_utils.js"></script>
|
<script type="text/javascript" src="ui_utils.js"></script>
|
||||||
|
<script type="text/javascript" src="download_manager.js"></script>
|
||||||
<script type="text/javascript" src="text_layer_builder.js"></script>
|
<script type="text/javascript" src="text_layer_builder.js"></script>
|
||||||
<script type="text/javascript" src="pdf_find_bar.js"></script>
|
<script type="text/javascript" src="pdf_find_bar.js"></script>
|
||||||
<script type="text/javascript" src="pdf_find_controller.js"></script>
|
<script type="text/javascript" src="pdf_find_controller.js"></script>
|
||||||
|
151
web/viewer.js
151
web/viewer.js
@ -14,10 +14,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/* globals URL*/
|
/* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, PDFFindBar, CustomStyle,
|
||||||
/* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, PDFFindBar */
|
PDFFindController, ProgressBar, TextLayerBuilder, DownloadManager,
|
||||||
/* globals PDFFindController, ProgressBar, getFileName, CustomStyle */
|
getFileName, getOutputScale, scrollIntoView, getPDFFileNameFromURL */
|
||||||
/* globals getOutputScale, TextLayerBuilder */
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -55,28 +54,9 @@ PDFJS.imageResourcesPath = './images/';
|
|||||||
var mozL10n = document.mozL10n || document.webL10n;
|
var mozL10n = document.mozL10n || document.webL10n;
|
||||||
|
|
||||||
//#include ui_utils.js
|
//#include ui_utils.js
|
||||||
|
//#if GENERIC || CHROME
|
||||||
function scrollIntoView(element, spot) {
|
//#include download_manager.js
|
||||||
// Assuming offsetParent is available (it's not available when viewer is in
|
//#endif
|
||||||
// hidden iframe or object). We have to scroll: if the offsetParent is not set
|
|
||||||
// producing the error. See also animationStartedClosure.
|
|
||||||
var parent = element.offsetParent;
|
|
||||||
var offsetY = element.offsetTop + element.clientTop;
|
|
||||||
if (!parent) {
|
|
||||||
console.error('offsetParent is not set -- cannot scroll');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (parent.clientHeight == parent.scrollHeight) {
|
|
||||||
offsetY += parent.offsetTop;
|
|
||||||
parent = parent.offsetParent;
|
|
||||||
if (!parent)
|
|
||||||
return; // no need to scroll
|
|
||||||
}
|
|
||||||
if (spot)
|
|
||||||
offsetY += spot.top;
|
|
||||||
parent.scrollTop = offsetY;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//#if FIREFOX || MOZCENTRAL
|
//#if FIREFOX || MOZCENTRAL
|
||||||
//#include firefoxcom.js
|
//#include firefoxcom.js
|
||||||
@ -915,117 +895,28 @@ var PDFView = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
download: function pdfViewDownload() {
|
download: function pdfViewDownload() {
|
||||||
var url = this.url.split('#')[0];
|
|
||||||
function getPDFFileNameFromURL(url) {
|
|
||||||
var reURI = /^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
|
|
||||||
// SCHEME HOST 1.PATH 2.QUERY 3.REF
|
|
||||||
// Pattern to get last matching NAME.pdf
|
|
||||||
var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
|
|
||||||
var splitURI = reURI.exec(url);
|
|
||||||
var suggestedFilename = reFilename.exec(splitURI[1]) ||
|
|
||||||
reFilename.exec(splitURI[2]) ||
|
|
||||||
reFilename.exec(splitURI[3]);
|
|
||||||
if (suggestedFilename) {
|
|
||||||
suggestedFilename = suggestedFilename[0];
|
|
||||||
if (suggestedFilename.indexOf('%') != -1) {
|
|
||||||
// URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
|
|
||||||
try {
|
|
||||||
suggestedFilename =
|
|
||||||
reFilename.exec(decodeURIComponent(suggestedFilename))[0];
|
|
||||||
} catch(e) { // Possible (extremely rare) errors:
|
|
||||||
// URIError "Malformed URI", e.g. for "%AA.pdf"
|
|
||||||
// TypeError "null has no properties", e.g. for "%2F.pdf"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return suggestedFilename || 'document.pdf';
|
|
||||||
}
|
|
||||||
//#if !(FIREFOX || MOZCENTRAL)
|
|
||||||
function noData() {
|
function noData() {
|
||||||
triggerSaveAs(url + '#pdfjs.action=download');
|
downloadManager.downloadUrl(url, filename);
|
||||||
}
|
}
|
||||||
function triggerSaveAs(url, blobUrl) {
|
|
||||||
// If blobUrl is not specified, fall back to non-blob url.
|
|
||||||
if (!blobUrl) blobUrl = url;
|
|
||||||
|
|
||||||
var a = document.createElement('a');
|
var url = this.url.split('#')[0];
|
||||||
if (a.click) {
|
var filename = getPDFFileNameFromURL(url);
|
||||||
// Use a.click() if available. Otherwise, Chrome might show
|
var downloadManager = new DownloadManager();
|
||||||
// "Unsafe JavaScript attempt to initiate a navigation change
|
downloadManager.onerror = function (err) {
|
||||||
// for frame with URL" and not open the PDF at all.
|
// This error won't really be helpful because it's likely the
|
||||||
// Supported by (not mentioned = untested):
|
// fallback won't work either (or is already open).
|
||||||
// - Firefox 6 - 19 (4- does not support a.click, 5 ignores a.click)
|
PDFView.error('PDF failed to download.');
|
||||||
// - Chrome 19 - 26 (18- does not support a.click)
|
};
|
||||||
// - Opera 9 - 12.15
|
|
||||||
// - Internet Explorer 6 - 10
|
if (!this.pdfDocument) { // the PDF is not ready yet
|
||||||
// - Safari 6 (5.1- does not support a.click)
|
noData();
|
||||||
a.href = blobUrl;
|
return;
|
||||||
a.target = '_parent';
|
|
||||||
// Use a.download if available. This increases the likelihood that
|
|
||||||
// the file is downloaded instead of opened by another PDF plugin.
|
|
||||||
if ('download' in a) {
|
|
||||||
a.download = getPDFFileNameFromURL(url);
|
|
||||||
}
|
|
||||||
// <a> must be in the document for IE and recent Firefox versions.
|
|
||||||
// (otherwise .click() is ignored)
|
|
||||||
(document.body || document.documentElement).appendChild(a);
|
|
||||||
a.click();
|
|
||||||
a.parentNode.removeChild(a);
|
|
||||||
} else {
|
|
||||||
if (window.top === window &&
|
|
||||||
blobUrl.split('#')[0] === window.location.href.split('#')[0]) {
|
|
||||||
// If _parent == self, then opening an identical URL with different
|
|
||||||
// location hash will only cause a navigation, not a download.
|
|
||||||
var padCharacter = blobUrl.indexOf('?') === -1 ? '?' : '&';
|
|
||||||
blobUrl = blobUrl.replace(/#|$/, padCharacter + '$&');
|
|
||||||
}
|
|
||||||
window.open(blobUrl, '_parent');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
// function noData() {
|
|
||||||
// FirefoxCom.request('download', {
|
|
||||||
// originalUrl: url,
|
|
||||||
// filename: getPDFFileNameFromURL(url)
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// function triggerSaveAs(url, blobUrl) {
|
|
||||||
// FirefoxCom.request('download', {
|
|
||||||
// blobUrl: blobUrl,
|
|
||||||
// originalUrl: url,
|
|
||||||
// filename: getPDFFileNameFromURL(url)
|
|
||||||
// },
|
|
||||||
// function response(err) {
|
|
||||||
// if (err) {
|
|
||||||
// // This error won't really be helpful because it's likely the
|
|
||||||
// // fallback won't work either (or is already open).
|
|
||||||
// PDFView.error('PDF failed to download.');
|
|
||||||
// }
|
|
||||||
// window.URL.revokeObjectURL(blobUrl);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//#endif
|
|
||||||
// If the PDF is not ready yet, or if URL.createObjectURL is not supported,
|
|
||||||
// just try to download with the url.
|
|
||||||
if (!this.pdfDocument || !URL) {
|
|
||||||
noData();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pdfDocument.getData().then(
|
this.pdfDocument.getData().then(
|
||||||
function getDataSuccess(data) {
|
function getDataSuccess(data) {
|
||||||
var blob = PDFJS.createBlob(data.buffer, 'application/pdf');
|
var blob = PDFJS.createBlob(data.buffer, 'application/pdf');
|
||||||
//#if GENERIC
|
downloadManager.download(blob, url, filename);
|
||||||
if (navigator.msSaveBlob) {
|
|
||||||
// IE10 / IE11
|
|
||||||
if (!navigator.msSaveBlob(blob, getPDFFileNameFromURL(url))) {
|
|
||||||
noData();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//#endif
|
|
||||||
var blobUrl = URL.createObjectURL(blob);
|
|
||||||
triggerSaveAs(url, blobUrl);
|
|
||||||
},
|
},
|
||||||
noData // Error occurred try downloading with just the url.
|
noData // Error occurred try downloading with just the url.
|
||||||
).then(null, noData);
|
).then(null, noData);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user