mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-20 15:18:08 +02:00
Implement progressive loading of PDFs
This commit is contained in:
parent
added3da8f
commit
ef423ef30c
25 changed files with 2110 additions and 586 deletions
168
web/viewer.css
168
web/viewer.css
|
@ -237,12 +237,14 @@ html[dir='rtl'] #sidebarContent {
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.loadingInProgress #viewerContainer {
|
||||
top: 39px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
position: relative;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 32px;
|
||||
z-index: 9999;
|
||||
cursor: default;
|
||||
}
|
||||
|
@ -271,9 +273,8 @@ html[dir='rtl'] #sidebarContent {
|
|||
0 0 1px hsla(0,0%,0%,.1);
|
||||
}
|
||||
|
||||
#toolbarViewer, .findbar {
|
||||
#toolbarContainer, .findbar {
|
||||
position: relative;
|
||||
height: 32px;
|
||||
background-color: #474747; /* IE9 */
|
||||
background-image: url(images/texture.png),
|
||||
-webkit-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));
|
||||
|
@ -292,6 +293,83 @@ html[dir='rtl'] #sidebarContent {
|
|||
0 1px 1px hsla(0,0%,0%,.1);
|
||||
}
|
||||
|
||||
#toolbarViewer {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
#loadingBar {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
background-color: #333;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
#loadingBar .progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background-color: #ddd;
|
||||
overflow: hidden;
|
||||
-moz-transition: width 200ms;
|
||||
-ms-transition: width 200ms;
|
||||
-webkit-transition: width 200ms;
|
||||
transition: width 200ms;
|
||||
}
|
||||
|
||||
@-moz-keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
@-ms-keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
@keyframes progressIndeterminate {
|
||||
0% { left: 0%; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
#loadingBar .progress.indeterminate {
|
||||
background-color: #999;
|
||||
-moz-transition: none;
|
||||
-ms-transition: none;
|
||||
-webkit-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
#loadingBar .indeterminate .glimmer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 50px;
|
||||
|
||||
background-image: -moz-linear-gradient(left, #999 0%, #fff 50%, #999 100%);
|
||||
background-image: -ms-linear-gradient(left, #999 0%, #fff 50%, #999 100%);
|
||||
background-image: -webkit-linear-gradient(left, #999 0%, #fff 50%, #999 100%);
|
||||
background-image: linear-gradient(left, #999 0%, #fff 50%, #999 100%);
|
||||
background-size: 100% 100% no-repeat;
|
||||
|
||||
-moz-animation: progressIndeterminate 2s linear infinite;
|
||||
-ms-animation: progressIndeterminate 2s linear infinite;
|
||||
-webkit-animation: progressIndeterminate 2s linear infinite;
|
||||
animation: progressIndeterminate 2s linear infinite;
|
||||
}
|
||||
|
||||
.findbar {
|
||||
top: 32px;
|
||||
position: absolute;
|
||||
|
@ -1123,82 +1201,6 @@ canvas {
|
|||
background: url('images/loading-icon.gif') center no-repeat;
|
||||
}
|
||||
|
||||
#loadingBox {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -25px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
color: #ddd;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#loadingBar {
|
||||
display: inline-block;
|
||||
clear: both;
|
||||
margin: 0px;
|
||||
margin-top: 5px;
|
||||
line-height: 0;
|
||||
border-radius: 2px;
|
||||
width: 200px;
|
||||
height: 25px;
|
||||
|
||||
background-color: hsla(0,0%,0%,.3);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
border: 1px solid #000;
|
||||
box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset,
|
||||
0 0 1px hsla(0,0%,0%,.2) inset,
|
||||
0 0 1px 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
#loadingBar .progress {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
|
||||
background: #666;
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2b2b2), color-stop(100%,#898989));
|
||||
background: -webkit-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: -moz-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: -ms-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: -o-linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
background: linear-gradient(top, #b2b2b2 0%,#898989 100%);
|
||||
|
||||
border-top-left-radius: 2px;
|
||||
border-bottom-left-radius: 2px;
|
||||
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#loadingBar .progress.full {
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
#loadingBar .progress.indeterminate {
|
||||
width: 100%;
|
||||
height: 25px;
|
||||
background-image: -moz-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-image: -webkit-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-image: -ms-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-image: -o-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040);
|
||||
background-size: 75px 25px;
|
||||
-moz-animation: progressIndeterminate 1s linear infinite;
|
||||
-webkit-animation: progressIndeterminate 1s linear infinite;
|
||||
}
|
||||
|
||||
@-moz-keyframes progressIndeterminate {
|
||||
from { background-position: 0px 0px; }
|
||||
to { background-position: 75px 0px; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes progressIndeterminate {
|
||||
from { background-position: 0px 0px; }
|
||||
to { background-position: 75px 0px; }
|
||||
}
|
||||
|
||||
.textLayer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
@ -1280,7 +1282,6 @@ canvas {
|
|||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 32px;
|
||||
z-index: 1000;
|
||||
padding: 3px;
|
||||
font-size: 0.8em;
|
||||
|
@ -1430,9 +1431,12 @@ canvas {
|
|||
|
||||
@media all and (max-width: 770px) {
|
||||
#sidebarContainer {
|
||||
top: 33px;
|
||||
top: 32px;
|
||||
z-index: 100;
|
||||
}
|
||||
.loadingInProgress #sidebarContainer {
|
||||
top: 39px;
|
||||
}
|
||||
#sidebarContent {
|
||||
top: 32px;
|
||||
background-color: hsla(0,0%,0%,.7);
|
||||
|
|
|
@ -38,6 +38,9 @@ limitations under the License.
|
|||
<!--#endif-->
|
||||
|
||||
<!--#if !PRODUCTION-->
|
||||
<script type="text/javascript" src="../src/network.js"></script>
|
||||
<script type="text/javascript" src="../src/chunked_stream.js"></script>
|
||||
<script type="text/javascript" src="../src/pdf_manager.js"></script>
|
||||
<script type="text/javascript" src="../src/core.js"></script>
|
||||
<script type="text/javascript" src="../src/util.js"></script>
|
||||
<script type="text/javascript" src="../src/api.js"></script>
|
||||
|
@ -74,7 +77,7 @@ limitations under the License.
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id="outerContainer">
|
||||
<div id="outerContainer" class="loadingInProgress">
|
||||
|
||||
<div id="sidebarContainer">
|
||||
<div id="toolbarSidebar">
|
||||
|
@ -189,6 +192,12 @@ limitations under the License.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loadingBar">
|
||||
<div class="progress">
|
||||
<div class="glimmer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -207,11 +216,6 @@ limitations under the License.
|
|||
<div id="viewer" contextmenu="viewerContextMenu"></div>
|
||||
</div>
|
||||
|
||||
<div id="loadingBox">
|
||||
<div id="loading"></div>
|
||||
<div id="loadingBar"><div class="progress"></div></div>
|
||||
</div>
|
||||
|
||||
<div id="errorWrapper" hidden='true'>
|
||||
<div id="errorMessageLeft">
|
||||
<span id="errorMessage"></span>
|
||||
|
|
|
@ -117,17 +117,12 @@ var ProgressBar = (function ProgressBarClosure() {
|
|||
updateBar: function ProgressBar_updateBar() {
|
||||
if (this._indeterminate) {
|
||||
this.div.classList.add('indeterminate');
|
||||
this.div.style.width = this.width + this.units;
|
||||
return;
|
||||
}
|
||||
|
||||
var progressSize = this.width * this._percent / 100;
|
||||
|
||||
if (this._percent > 95)
|
||||
this.div.classList.add('full');
|
||||
else
|
||||
this.div.classList.remove('full');
|
||||
this.div.classList.remove('indeterminate');
|
||||
|
||||
var progressSize = this.width * this._percent / 100;
|
||||
this.div.style.width = progressSize + this.units;
|
||||
},
|
||||
|
||||
|
@ -945,12 +940,39 @@ var PDFView = {
|
|||
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
|
||||
}
|
||||
|
||||
window.addEventListener('message', function window_message(e) {
|
||||
var pdfDataRangeTransport = {
|
||||
listeners: [],
|
||||
|
||||
addListener: function PdfDataRangeTransport_addListener(listener) {
|
||||
this.listeners.push(listener);
|
||||
},
|
||||
|
||||
onDataRange: function PdfDataRangeTransport_onDataRange(begin, chunk) {
|
||||
for (var i = 0, n = this.listeners.length; i < n; ++i) {
|
||||
this.listeners[i](begin, chunk);
|
||||
}
|
||||
},
|
||||
|
||||
requestDataRange: function PdfDataRangeTransport_requestDataRange(
|
||||
begin, end) {
|
||||
FirefoxCom.request('requestDataRange', { begin: begin, end: end });
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', function windowMessage(e) {
|
||||
var args = e.data;
|
||||
|
||||
if (typeof args !== 'object' || !('pdfjsLoadAction' in args))
|
||||
return;
|
||||
switch (args.pdfjsLoadAction) {
|
||||
case 'supportsRangedLoading':
|
||||
PDFView.open(args.pdfUrl, 0, undefined, pdfDataRangeTransport, {
|
||||
length: args.length
|
||||
});
|
||||
break;
|
||||
case 'range':
|
||||
pdfDataRangeTransport.onDataRange(args.begin, args.chunk);
|
||||
break;
|
||||
case 'progress':
|
||||
PDFView.progress(args.loaded / args.total);
|
||||
break;
|
||||
|
@ -985,7 +1007,9 @@ var PDFView = {
|
|||
//#endif
|
||||
},
|
||||
|
||||
open: function pdfViewOpen(url, scale, password) {
|
||||
// TODO(mack): This function signature should really be pdfViewOpen(url, args)
|
||||
open: function pdfViewOpen(url, scale, password,
|
||||
pdfDataRangeTransport, args) {
|
||||
var parameters = {password: password};
|
||||
if (typeof url === 'string') { // URL
|
||||
this.setTitleUsingUrl(url);
|
||||
|
@ -993,6 +1017,11 @@ var PDFView = {
|
|||
} else if (url && 'byteLength' in url) { // ArrayBuffer
|
||||
parameters.data = url;
|
||||
}
|
||||
if (args) {
|
||||
for (var prop in args) {
|
||||
parameters[prop] = args[prop];
|
||||
}
|
||||
}
|
||||
|
||||
if (!PDFView.loadingBar) {
|
||||
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
|
||||
|
@ -1001,7 +1030,7 @@ var PDFView = {
|
|||
this.pdfDocument = null;
|
||||
var self = this;
|
||||
self.loading = true;
|
||||
PDFJS.getDocument(parameters).then(
|
||||
PDFJS.getDocument(parameters, pdfDataRangeTransport).then(
|
||||
function getDocumentCallback(pdfDocument) {
|
||||
self.load(pdfDocument, scale);
|
||||
self.loading = false;
|
||||
|
@ -1042,9 +1071,6 @@ var PDFView = {
|
|||
//#endif
|
||||
}
|
||||
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.textContent = mozL10n.get('loading_error_indicator',
|
||||
null, 'Error');
|
||||
var moreInfo = {
|
||||
message: message
|
||||
};
|
||||
|
@ -1251,9 +1277,6 @@ var PDFView = {
|
|||
}
|
||||
}
|
||||
|
||||
var loadingBox = document.getElementById('loadingBox');
|
||||
loadingBox.setAttribute('hidden', 'true');
|
||||
|
||||
//#if !(FIREFOX || MOZCENTRAL)
|
||||
var errorWrapper = document.getElementById('errorWrapper');
|
||||
errorWrapper.removeAttribute('hidden');
|
||||
|
@ -1308,10 +1331,12 @@ var PDFView = {
|
|||
var errorWrapper = document.getElementById('errorWrapper');
|
||||
errorWrapper.setAttribute('hidden', 'true');
|
||||
|
||||
var loadingBox = document.getElementById('loadingBox');
|
||||
loadingBox.setAttribute('hidden', 'true');
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.textContent = '';
|
||||
pdfDocument.dataLoaded().then(function() {
|
||||
var loadingBar = document.getElementById('loadingBar');
|
||||
loadingBar.classList.add('hidden');
|
||||
var outerContainer = document.getElementById('outerContainer');
|
||||
outerContainer.classList.remove('loadingInProgress');
|
||||
});
|
||||
|
||||
var thumbsView = document.getElementById('thumbnailView');
|
||||
thumbsView.parentNode.scrollTop = 0;
|
||||
|
@ -3070,8 +3095,13 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
|||
var hash = document.location.hash.substring(1);
|
||||
var hashParams = PDFView.parseQueryString(hash);
|
||||
|
||||
if ('disableWorker' in hashParams)
|
||||
if ('disableWorker' in hashParams) {
|
||||
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
|
||||
}
|
||||
|
||||
if ('disableRange' in hashParams) {
|
||||
PDFJS.disableRange = (hashParams['disableRange'] === 'true');
|
||||
}
|
||||
|
||||
//#if !(FIREFOX || MOZCENTRAL)
|
||||
var locale = navigator.language;
|
||||
|
@ -3237,11 +3267,9 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
|||
});
|
||||
|
||||
//#if (FIREFOX || MOZCENTRAL)
|
||||
//if (FirefoxCom.requestSync('getLoadingType') == 'passive') {
|
||||
// PDFView.setTitleUsingUrl(file);
|
||||
// PDFView.initPassiveLoading();
|
||||
// return;
|
||||
//}
|
||||
//PDFView.setTitleUsingUrl(file);
|
||||
//PDFView.initPassiveLoading();
|
||||
//return;
|
||||
//#endif
|
||||
|
||||
//#if !B2G
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue