update pdf.js to improve range request support in chrome
This commit is contained in:
parent
e3f43007a4
commit
3e99e43015
2 changed files with 345 additions and 341 deletions
|
@ -16,8 +16,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var PDFJS = {};
|
var PDFJS = {};
|
||||||
PDFJS.version = '0.7.290';
|
PDFJS.version = '0.7.315';
|
||||||
PDFJS.build = '009bc18';
|
PDFJS.build = '547a8d6';
|
||||||
|
|
||||||
(function pdfjsWrapper() {
|
(function pdfjsWrapper() {
|
||||||
// Use strict in our context only - users might not want it
|
// Use strict in our context only - users might not want it
|
||||||
|
@ -46,6 +46,7 @@ PDFJS.build = '009bc18';
|
||||||
|
|
||||||
var NetworkManager = (function NetworkManagerClosure() {
|
var NetworkManager = (function NetworkManagerClosure() {
|
||||||
function NetworkManager(url, args) {
|
function NetworkManager(url, args) {
|
||||||
|
args = args || {};
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.httpHeaders = args.httpHeaders;
|
this.httpHeaders = args.httpHeaders;
|
||||||
this.getXhr = args.getXhr ||
|
this.getXhr = args.getXhr ||
|
||||||
|
@ -54,8 +55,8 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.currXhrId = 0;
|
this.currXhrId = 0;
|
||||||
this.xhrRequests = {};
|
this.pendingRequests = {};
|
||||||
this.loadedXhrs = {};
|
this.loadedRequests = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArrayBuffer(xhr) {
|
function getArrayBuffer(xhr) {
|
||||||
|
@ -78,9 +79,8 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||||
// e.g. If we already have chunk 3, and we need chunks [2, 5), do not
|
// e.g. If we already have chunk 3, and we need chunks [2, 5), do not
|
||||||
// fetch 2; instead fetch [2, 3) and [4, 5); Realistically though, this
|
// fetch 2; instead fetch [2, 3) and [4, 5); Realistically though, this
|
||||||
// should not happen often w/ PDFs
|
// should not happen often w/ PDFs
|
||||||
// TODO(mack): this optimization might do more harm than good; investigate
|
|
||||||
requestRange: function NetworkManager_requestRange(begin, end, callback) {
|
requestRange: function NetworkManager_requestRange(begin, end, callback) {
|
||||||
this.request({
|
return this.request({
|
||||||
begin: begin,
|
begin: begin,
|
||||||
end: end,
|
end: end,
|
||||||
onDone: callback
|
onDone: callback
|
||||||
|
@ -88,13 +88,13 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||||
},
|
},
|
||||||
|
|
||||||
requestFull: function NetworkManager_requestRange(args) {
|
requestFull: function NetworkManager_requestRange(args) {
|
||||||
this.request(args);
|
return this.request(args);
|
||||||
},
|
},
|
||||||
|
|
||||||
request: function NetworkManager_requestRange(args) {
|
request: function NetworkManager_requestRange(args) {
|
||||||
var xhr = this.getXhr();
|
var xhr = this.getXhr();
|
||||||
var xhrId = this.currXhrId++;
|
var xhrId = this.currXhrId++;
|
||||||
this.xhrRequests[xhrId] = xhr;
|
this.pendingRequests[xhrId] = xhr;
|
||||||
|
|
||||||
xhr.open('GET', this.url);
|
xhr.open('GET', this.url);
|
||||||
if (this.httpHeaders) {
|
if (this.httpHeaders) {
|
||||||
|
@ -131,35 +131,33 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||||
xhr.onDone = args.onDone;
|
xhr.onDone = args.onDone;
|
||||||
|
|
||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
|
|
||||||
|
return xhrId;
|
||||||
},
|
},
|
||||||
|
|
||||||
onStateChange: function NetworkManager_onStateChange(xhrId, evt) {
|
onStateChange: function NetworkManager_onStateChange(xhrId, evt) {
|
||||||
// xhr seems to queue requests for different readyState,
|
var xhr = this.pendingRequests[xhrId];
|
||||||
// so that we come here multiple times; the problem is when we pause
|
|
||||||
// via debugger, then, xhr.readyState will be 4 multiple times. This
|
|
||||||
// is a fix for this issue.
|
|
||||||
if (xhrId in this.loadedXhrs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var xhr = this.xhrRequests[xhrId];
|
|
||||||
if (!xhr) {
|
if (!xhr) {
|
||||||
// Maybe abortRequest was called...
|
// Maybe abortRequest was called...
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xhr.readyState >= 2 && xhr.onHeadersReceived) {
|
if (xhr.readyState >= 2 && xhr.onHeadersReceived) {
|
||||||
xhr.onHeadersReceived({
|
xhr.onHeadersReceived();
|
||||||
xhrId: xhrId
|
|
||||||
});
|
|
||||||
delete xhr.onHeadersReceived;
|
delete xhr.onHeadersReceived;
|
||||||
return;
|
}
|
||||||
} else if (xhr.readyState !== 4) {
|
|
||||||
|
if (xhr.readyState !== 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadedXhrs[xhrId] = true;
|
if (!(xhrId in this.pendingRequests)) {
|
||||||
delete this.xhrRequests[xhrId];
|
// The XHR request might have been aborted in onHeadersReceived()
|
||||||
|
// callback, in which case we should abort request
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.pendingRequests[xhrId];
|
||||||
|
|
||||||
if (xhr.status === 0) {
|
if (xhr.status === 0) {
|
||||||
//warn('Received xhr.status of 0');
|
//warn('Received xhr.status of 0');
|
||||||
|
@ -174,6 +172,8 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.loadedRequests[xhrId] = true;
|
||||||
|
|
||||||
var chunk = getArrayBuffer(xhr);
|
var chunk = getArrayBuffer(xhr);
|
||||||
if (xhr.expectedStatus === 206) {
|
if (xhr.expectedStatus === 206) {
|
||||||
var rangeHeader = xhr.getResponseHeader('Content-Range');
|
var rangeHeader = xhr.getResponseHeader('Content-Range');
|
||||||
|
@ -196,28 +196,36 @@ var NetworkManager = (function NetworkManagerClosure() {
|
||||||
},
|
},
|
||||||
|
|
||||||
hasPendingRequests: function NetworkManager_hasPendingRequests() {
|
hasPendingRequests: function NetworkManager_hasPendingRequests() {
|
||||||
for (var xhrId in this.xhrRequests) {
|
for (var xhrId in this.pendingRequests) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getRequestXhr: function NetworkManager_getXhr(xhrId) {
|
||||||
|
return this.pendingRequests[xhrId];
|
||||||
|
},
|
||||||
|
|
||||||
isPendingRequest: function NetworkManager_isPendingRequest(xhrId) {
|
isPendingRequest: function NetworkManager_isPendingRequest(xhrId) {
|
||||||
return xhrId in this.xhrRequests;
|
return xhrId in this.pendingRequests;
|
||||||
|
},
|
||||||
|
|
||||||
|
isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) {
|
||||||
|
return xhrId in this.loadedRequests;
|
||||||
},
|
},
|
||||||
|
|
||||||
abortXhrs: function NetworkManager_abortXhrs() {
|
abortXhrs: function NetworkManager_abortXhrs() {
|
||||||
for (var xhrId in this.xhrRequests) {
|
for (var xhrId in this.pendingRequests) {
|
||||||
xhrId = xhrId | 0;
|
xhrId = xhrId | 0;
|
||||||
var xhr = this.xhrRequests[xhrId];
|
var xhr = this.pendingRequests[xhrId];
|
||||||
delete this.xhrRequests[xhrId];
|
delete this.pendingRequests[xhrId];
|
||||||
xhr.abort();
|
xhr.abort();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
abortRequest: function NetworkManager_abortRequest(xhrId) {
|
abortRequest: function NetworkManager_abortRequest(xhrId) {
|
||||||
var xhr = this.xhrRequests[xhrId];
|
var xhr = this.pendingRequests[xhrId];
|
||||||
delete this.xhrRequests[xhrId];
|
delete this.pendingRequests[xhrId];
|
||||||
xhr.abort();
|
xhr.abort();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -241,7 +249,6 @@ if (!globalScope.PDFJS) {
|
||||||
globalScope.PDFJS = {};
|
globalScope.PDFJS = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
globalScope.PDFJS.pdfBug = false;
|
globalScope.PDFJS.pdfBug = false;
|
||||||
|
|
||||||
var Page = (function PageClosure() {
|
var Page = (function PageClosure() {
|
||||||
|
@ -594,6 +601,10 @@ var PDFDocument = (function PDFDocumentClosure() {
|
||||||
linearization = false;
|
linearization = false;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (err instanceof MissingDataException) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
warn('The linearization data is not available ' +
|
warn('The linearization data is not available ' +
|
||||||
'or unreadable pdf data is found');
|
'or unreadable pdf data is found');
|
||||||
linearization = false;
|
linearization = false;
|
||||||
|
@ -672,13 +683,12 @@ var PDFDocument = (function PDFDocumentClosure() {
|
||||||
}
|
}
|
||||||
// May not be a PDF file, continue anyway.
|
// May not be a PDF file, continue anyway.
|
||||||
},
|
},
|
||||||
|
setXrefStart: function PDFDocument_setXrefStart() {
|
||||||
|
var startXRef = this.startXRef;
|
||||||
|
this.xref.startXrefQueue = [startXRef];
|
||||||
|
},
|
||||||
setup: function PDFDocument_setup(recoveryMode) {
|
setup: function PDFDocument_setup(recoveryMode) {
|
||||||
this.checkHeader();
|
this.checkHeader();
|
||||||
var startXRef = this.startXRef;
|
|
||||||
// FIXME(mack): Clean up how this done
|
|
||||||
if (!this.xref.startXrefQueue) {
|
|
||||||
this.xref.startXrefQueue = [[startXRef]];
|
|
||||||
}
|
|
||||||
this.xref.parse(recoveryMode);
|
this.xref.parse(recoveryMode);
|
||||||
this.catalog = new Catalog(this.xref);
|
this.catalog = new Catalog(this.xref);
|
||||||
},
|
},
|
||||||
|
@ -1109,6 +1119,12 @@ var Util = PDFJS.Util = (function UtilClosure() {
|
||||||
|
|
||||||
var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
|
var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
|
||||||
function PageViewport(viewBox, scale, rotate, offsetX, offsetY) {
|
function PageViewport(viewBox, scale, rotate, offsetX, offsetY) {
|
||||||
|
this.viewBox = viewBox;
|
||||||
|
this.scale = scale;
|
||||||
|
this.rotate = rotate;
|
||||||
|
this.offsetX = offsetX;
|
||||||
|
this.offsetY = offsetY;
|
||||||
|
|
||||||
// creating transform to convert pdf coordinate system to the normal
|
// creating transform to convert pdf coordinate system to the normal
|
||||||
// canvas like coordinates taking in account scale and rotation
|
// canvas like coordinates taking in account scale and rotation
|
||||||
var centerX = (viewBox[2] + viewBox[0]) / 2;
|
var centerX = (viewBox[2] + viewBox[0]) / 2;
|
||||||
|
@ -1158,13 +1174,22 @@ var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
|
||||||
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
|
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
|
||||||
];
|
];
|
||||||
|
|
||||||
this.offsetX = offsetX;
|
|
||||||
this.offsetY = offsetY;
|
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.fontScale = scale;
|
this.fontScale = scale;
|
||||||
}
|
}
|
||||||
PageViewport.prototype = {
|
PageViewport.prototype = {
|
||||||
|
clone: function PageViewPort_clone(args) {
|
||||||
|
args = args || {};
|
||||||
|
var scale = 'scale' in args ? args.scale : this.scale;
|
||||||
|
var rotate = 'rotate' in args ? args.rotate : this.rotate;
|
||||||
|
var viewBoxClone = [];
|
||||||
|
for (var i = 0; i < this.viewBox.length; ++i) {
|
||||||
|
viewBoxClone[i] = this.viewBox[i];
|
||||||
|
}
|
||||||
|
return new PageViewport(viewBoxClone, scale, rotate,
|
||||||
|
this.offsetX, this.offsetY);
|
||||||
|
},
|
||||||
convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
|
convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
|
||||||
return Util.applyTransform([x, y], this.transform);
|
return Util.applyTransform([x, y], this.transform);
|
||||||
},
|
},
|
||||||
|
@ -1536,7 +1561,7 @@ PDFJS.createBlob = function createBlob(data, contentType) {
|
||||||
*
|
*
|
||||||
* @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
|
* @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
|
||||||
*/
|
*/
|
||||||
PDFJS.getDocument = function getDocument(source) {
|
PDFJS.getDocument = function getDocument(source, pdfDataRangeTransport) {
|
||||||
var workerInitializedPromise, workerReadyPromise, transport;
|
var workerInitializedPromise, workerReadyPromise, transport;
|
||||||
|
|
||||||
if (typeof source === 'string') {
|
if (typeof source === 'string') {
|
||||||
|
@ -1564,9 +1589,9 @@ PDFJS.getDocument = function getDocument(source) {
|
||||||
workerInitializedPromise = new PDFJS.Promise();
|
workerInitializedPromise = new PDFJS.Promise();
|
||||||
workerReadyPromise = new PDFJS.Promise();
|
workerReadyPromise = new PDFJS.Promise();
|
||||||
transport = new WorkerTransport(workerInitializedPromise,
|
transport = new WorkerTransport(workerInitializedPromise,
|
||||||
workerReadyPromise, params);
|
workerReadyPromise, pdfDataRangeTransport);
|
||||||
workerInitializedPromise.then(function transportInitialized() {
|
workerInitializedPromise.then(function transportInitialized() {
|
||||||
transport.fetchDocument();
|
transport.fetchDocument(params);
|
||||||
});
|
});
|
||||||
return workerReadyPromise;
|
return workerReadyPromise;
|
||||||
};
|
};
|
||||||
|
@ -1950,8 +1975,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
|
||||||
*/
|
*/
|
||||||
var WorkerTransport = (function WorkerTransportClosure() {
|
var WorkerTransport = (function WorkerTransportClosure() {
|
||||||
function WorkerTransport(workerInitializedPromise, workerReadyPromise,
|
function WorkerTransport(workerInitializedPromise, workerReadyPromise,
|
||||||
source) {
|
pdfDataRangeTransport) {
|
||||||
this.source = source;
|
this.pdfDataRangeTransport = pdfDataRangeTransport;
|
||||||
|
|
||||||
this.workerReadyPromise = workerReadyPromise;
|
this.workerReadyPromise = workerReadyPromise;
|
||||||
this.commonObjs = new PDFObjects();
|
this.commonObjs = new PDFObjects();
|
||||||
|
@ -2034,15 +2059,19 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||||
function WorkerTransport_setupMessageHandler(messageHandler) {
|
function WorkerTransport_setupMessageHandler(messageHandler) {
|
||||||
this.messageHandler = messageHandler;
|
this.messageHandler = messageHandler;
|
||||||
|
|
||||||
if (this.source.chunkedChromeLoading) {
|
var pdfDataRangeTransport = this.pdfDataRangeTransport;
|
||||||
window.addEventListener('message', function window_message(evt) {
|
if (pdfDataRangeTransport) {
|
||||||
this.messageHandler.send('SendDataRange', evt.data);
|
pdfDataRangeTransport.addListener(function(args) {
|
||||||
}.bind(this));
|
messageHandler.send('OnDataRange', args);
|
||||||
}
|
});
|
||||||
|
|
||||||
messageHandler.on('RequestDataRange', function transportDataRange(args) {
|
messageHandler.on('RequestDataRange',
|
||||||
FirefoxCom.request('requestDataRange', args);
|
function transportDataRange(data) {
|
||||||
}, this);
|
var begin = data.begin;
|
||||||
|
var end = data.end;
|
||||||
|
pdfDataRangeTransport.requestDataRange(begin, end);
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
|
||||||
messageHandler.on('GetDoc', function transportDoc(data) {
|
messageHandler.on('GetDoc', function transportDoc(data) {
|
||||||
var pdfInfo = data.pdfInfo;
|
var pdfInfo = data.pdfInfo;
|
||||||
|
@ -2111,11 +2140,10 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||||
// At this point, only the font object is created but the font is
|
// At this point, only the font object is created but the font is
|
||||||
// not yet attached to the DOM. This is done in `FontLoader.bind`.
|
// not yet attached to the DOM. This is done in `FontLoader.bind`.
|
||||||
var font;
|
var font;
|
||||||
if ('error' in exportedData) {
|
if ('error' in exportedData)
|
||||||
font = new ErrorFont(exportedData.error);
|
font = new ErrorFont(exportedData.error);
|
||||||
} else {
|
else
|
||||||
font = new Font(exportedData);
|
font = new Font(exportedData);
|
||||||
}
|
|
||||||
this.commonObjs.resolve(id, font);
|
this.commonObjs.resolve(id, font);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2207,8 +2235,12 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchDocument: function WorkerTransport_fetchDocument() {
|
fetchDocument: function WorkerTransport_fetchDocument(source) {
|
||||||
this.messageHandler.send('GetDocRequest', {source: this.source});
|
extend(source, { chunkedViewerLoading: !!this.pdfDataRangeTransport });
|
||||||
|
this.messageHandler.send('GetDocRequest', {
|
||||||
|
source: source,
|
||||||
|
rangeSupport: PDFJS.rangeSupport
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getData: function WorkerTransport_getData(promise) {
|
getData: function WorkerTransport_getData(promise) {
|
||||||
|
@ -4084,7 +4116,6 @@ var XRef = (function XRefClosure() {
|
||||||
// prepare the XRef cache
|
// prepare the XRef cache
|
||||||
this.cache = [];
|
this.cache = [];
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.startXrefQueue = undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XRef.prototype = {
|
XRef.prototype = {
|
||||||
|
@ -4248,11 +4279,6 @@ var XRef = (function XRefClosure() {
|
||||||
},
|
},
|
||||||
|
|
||||||
readXRefStream: function XRef_readXRefStream(stream) {
|
readXRefStream: function XRef_readXRefStream(stream) {
|
||||||
//var streamParameters = stream.parameters;
|
|
||||||
//var byteWidths = streamParameters.get('W');
|
|
||||||
//var range = streamParameters.get('Index');
|
|
||||||
//if (!range)
|
|
||||||
// range = [0, streamParameters.get('Size')];
|
|
||||||
var i, j;
|
var i, j;
|
||||||
stream.pos = this.streamState.pos;
|
stream.pos = this.streamState.pos;
|
||||||
|
|
||||||
|
@ -4308,7 +4334,6 @@ var XRef = (function XRefClosure() {
|
||||||
this.streamState.pos = stream.pos;
|
this.streamState.pos = stream.pos;
|
||||||
this.streamState.range.splice(0, 2);
|
this.streamState.range.splice(0, 2);
|
||||||
}
|
}
|
||||||
//return streamParameters;
|
|
||||||
},
|
},
|
||||||
indexObjects: function XRef_indexObjects() {
|
indexObjects: function XRef_indexObjects() {
|
||||||
// Simple scan through the PDF content to find objects,
|
// Simple scan through the PDF content to find objects,
|
||||||
|
@ -4396,7 +4421,7 @@ var XRef = (function XRefClosure() {
|
||||||
}
|
}
|
||||||
// reading XRef streams
|
// reading XRef streams
|
||||||
for (var i = 0, ii = xrefStms.length; i < ii; ++i) {
|
for (var i = 0, ii = xrefStms.length; i < ii; ++i) {
|
||||||
this.startXrefQueue.push([xrefStms[i], true]);
|
this.startXrefQueue.push(xrefStms[i]);
|
||||||
this.readXRef(/* recoveryMode */ true);
|
this.readXRef(/* recoveryMode */ true);
|
||||||
}
|
}
|
||||||
// finding main trailer
|
// finding main trailer
|
||||||
|
@ -4427,7 +4452,7 @@ var XRef = (function XRefClosure() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (this.startXrefQueue.length) {
|
while (this.startXrefQueue.length) {
|
||||||
var startXRef = this.startXrefQueue[0][0];
|
var startXRef = this.startXrefQueue[0];
|
||||||
|
|
||||||
stream.pos = startXRef;
|
stream.pos = startXRef;
|
||||||
|
|
||||||
|
@ -4453,7 +4478,7 @@ var XRef = (function XRefClosure() {
|
||||||
// (possible infinite recursion)
|
// (possible infinite recursion)
|
||||||
if (!(pos in this.xrefstms)) {
|
if (!(pos in this.xrefstms)) {
|
||||||
this.xrefstms[pos] = 1;
|
this.xrefstms[pos] = 1;
|
||||||
this.startXrefQueue.push([pos]);
|
this.startXrefQueue.push(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isInt(obj)) {
|
} else if (isInt(obj)) {
|
||||||
|
@ -4477,11 +4502,11 @@ var XRef = (function XRefClosure() {
|
||||||
// Recursively get previous dictionary, if any
|
// Recursively get previous dictionary, if any
|
||||||
obj = dict.get('Prev');
|
obj = dict.get('Prev');
|
||||||
if (isInt(obj)) {
|
if (isInt(obj)) {
|
||||||
this.startXrefQueue.push([obj, recoveryMode]);
|
this.startXrefQueue.push(obj);
|
||||||
} else if (isRef(obj)) {
|
} else if (isRef(obj)) {
|
||||||
// The spec says Prev must not be a reference, i.e. "/Prev NNN"
|
// The spec says Prev must not be a reference, i.e. "/Prev NNN"
|
||||||
// This is a fallback for non-compliant PDFs, i.e. "/Prev NNN 0 R"
|
// This is a fallback for non-compliant PDFs, i.e. "/Prev NNN 0 R"
|
||||||
this.startXrefQueue.push([obj.num, recoveryMode]);
|
this.startXrefQueue.push(obj.num);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.startXrefQueue.shift();
|
this.startXrefQueue.shift();
|
||||||
|
@ -4496,9 +4521,8 @@ var XRef = (function XRefClosure() {
|
||||||
log('(while reading XRef): ' + e);
|
log('(while reading XRef): ' + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recoveryMode) {
|
if (recoveryMode)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
throw new XrefParseException();
|
throw new XrefParseException();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -30602,13 +30626,7 @@ var Lexer = (function LexerClosure() {
|
||||||
}
|
}
|
||||||
stream.skip();
|
stream.skip();
|
||||||
}
|
}
|
||||||
// TODO(mack): gotta test this optimization
|
var value = parseFloat(str);
|
||||||
var value;
|
|
||||||
if (floating) {
|
|
||||||
value = parseFloat(str);
|
|
||||||
} else {
|
|
||||||
value = str | 0;
|
|
||||||
}
|
|
||||||
if (isNaN(value))
|
if (isNaN(value))
|
||||||
error('Invalid floating point number: ' + value);
|
error('Invalid floating point number: ' + value);
|
||||||
return value;
|
return value;
|
||||||
|
@ -30793,7 +30811,6 @@ var Lexer = (function LexerClosure() {
|
||||||
return Cmd.get(ch);
|
return Cmd.get(ch);
|
||||||
// hex string or dict punctuation
|
// hex string or dict punctuation
|
||||||
case '<':
|
case '<':
|
||||||
var position = stream.pos;
|
|
||||||
ch = stream.lookChar();
|
ch = stream.lookChar();
|
||||||
if (ch == '<') {
|
if (ch == '<') {
|
||||||
// dict punctuation
|
// dict punctuation
|
||||||
|
@ -31319,7 +31336,6 @@ var Stream = (function StreamClosure() {
|
||||||
return this.end - this.start;
|
return this.end - this.start;
|
||||||
},
|
},
|
||||||
getByte: function Stream_getByte() {
|
getByte: function Stream_getByte() {
|
||||||
//throw new Error('getByte');
|
|
||||||
if (this.pos >= this.end)
|
if (this.pos >= this.end)
|
||||||
return null;
|
return null;
|
||||||
return this.bytes[this.pos++];
|
return this.bytes[this.pos++];
|
||||||
|
@ -31327,7 +31343,6 @@ var Stream = (function StreamClosure() {
|
||||||
// returns subarray of original buffer
|
// returns subarray of original buffer
|
||||||
// should only be read
|
// should only be read
|
||||||
getBytes: function Stream_getBytes(length) {
|
getBytes: function Stream_getBytes(length) {
|
||||||
//throw new Error('getBytes');
|
|
||||||
var bytes = this.bytes;
|
var bytes = this.bytes;
|
||||||
var pos = this.pos;
|
var pos = this.pos;
|
||||||
var strEnd = this.end;
|
var strEnd = this.end;
|
||||||
|
@ -31343,13 +31358,11 @@ var Stream = (function StreamClosure() {
|
||||||
return bytes.subarray(pos, end);
|
return bytes.subarray(pos, end);
|
||||||
},
|
},
|
||||||
lookChar: function Stream_lookChar() {
|
lookChar: function Stream_lookChar() {
|
||||||
//throw new Error('lookChar');
|
|
||||||
if (this.pos >= this.end)
|
if (this.pos >= this.end)
|
||||||
return null;
|
return null;
|
||||||
return String.fromCharCode(this.bytes[this.pos]);
|
return String.fromCharCode(this.bytes[this.pos]);
|
||||||
},
|
},
|
||||||
getChar: function Stream_getChar() {
|
getChar: function Stream_getChar() {
|
||||||
//throw new Error('getChar');
|
|
||||||
if (this.pos >= this.end)
|
if (this.pos >= this.end)
|
||||||
return null;
|
return null;
|
||||||
return String.fromCharCode(this.bytes[this.pos++]);
|
return String.fromCharCode(this.bytes[this.pos++]);
|
||||||
|
@ -33678,7 +33691,6 @@ var ChunkedStream = (function ChunkedStreamClosure() {
|
||||||
},
|
},
|
||||||
|
|
||||||
allChunksLoaded: function ChunkedStream_allChunksLoaded() {
|
allChunksLoaded: function ChunkedStream_allChunksLoaded() {
|
||||||
// TODO(mack): might want to use list of unloaded chunks to be safer...
|
|
||||||
return this.numChunksLoaded === this.numChunks;
|
return this.numChunksLoaded === this.numChunks;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -33773,9 +33785,6 @@ var ChunkedStream = (function ChunkedStreamClosure() {
|
||||||
return bytes.subarray(pos, end);
|
return bytes.subarray(pos, end);
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO(mack): make getBytes call this
|
|
||||||
// returns subarray of original buffer
|
|
||||||
// should only be read
|
|
||||||
getByteRange: function ChunkedStream_getBytes(begin, end) {
|
getByteRange: function ChunkedStream_getBytes(begin, end) {
|
||||||
this.ensureRange(begin, end);
|
this.ensureRange(begin, end);
|
||||||
return this.bytes.subarray(begin, end);
|
return this.bytes.subarray(begin, end);
|
||||||
|
@ -33836,23 +33845,10 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
|
||||||
this.length = stream.length;
|
this.length = stream.length;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
|
|
||||||
// Prefill stream with fully loaded chunks
|
if (args.chunkedViewerLoading) {
|
||||||
if (args.loadedChunk && isInt(args.loadedBegin)) {
|
args.msgHandler.on('OnDataRange', this.onReceiveData.bind(this));
|
||||||
var loadedBegin = args.loadedBegin;
|
this.sendRequest = function ChunkedStreamManager_sendRequest(begin, end) {
|
||||||
var actualChunk = args.loadedChunk;
|
args.msgHandler.send('RequestDataRange', { begin: begin, end: end });
|
||||||
var actualEnd = loadedBegin + actualChunk.byteLength;
|
|
||||||
var loadedEnd = Math.floor(actualEnd / this.chunkSize) * this.chunkSize;
|
|
||||||
var loadedChunk = actualChunk.subarray(loadedBegin, loadedEnd);
|
|
||||||
this.stream.onReceiveData(loadedBegin, loadedChunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.fetchByChrome) {
|
|
||||||
args.msgHandler.on('SendDataRange', this.onReceiveData.bind(this));
|
|
||||||
this.sendRequest = function streamManager_sendRequest(begin, end) {
|
|
||||||
args.msgHandler.send(
|
|
||||||
'RequestDataRange',
|
|
||||||
{ begin: begin, end: end }
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -33860,7 +33856,7 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
|
||||||
return new XMLHttpRequest();
|
return new XMLHttpRequest();
|
||||||
};
|
};
|
||||||
this.networkManager = new NetworkManager(this.url, { getXhr: getXhr });
|
this.networkManager = new NetworkManager(this.url, { getXhr: getXhr });
|
||||||
this.sendRequest = function streamManager_sendRequest(begin, end) {
|
this.sendRequest = function ChunkedStreamManager_sendRequest(begin, end) {
|
||||||
this.networkManager.requestRange(
|
this.networkManager.requestRange(
|
||||||
begin, end, this.onReceiveData.bind(this));
|
begin, end, this.onReceiveData.bind(this));
|
||||||
};
|
};
|
||||||
|
@ -34180,9 +34176,7 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
msgHandler: msgHandler,
|
msgHandler: msgHandler,
|
||||||
fetchByChrome: args.chunkedChromeLoading,
|
chunkedViewerLoading: args.chunkedViewerLoading
|
||||||
loadedBegin: args.loadedBegin,
|
|
||||||
loadedChunk: args.loadedChunk
|
|
||||||
};
|
};
|
||||||
this.streamManager = new ChunkedStreamManager(
|
this.streamManager = new ChunkedStreamManager(
|
||||||
this.stream, this.pdfUrl, params);
|
this.stream, this.pdfUrl, params);
|
||||||
|
@ -34270,14 +34264,6 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var START_TIME = (new Date()).getTime() / 1000;
|
|
||||||
function timeLog() {
|
|
||||||
var elapsedTime = (new Date()).getTime() / 1000 - START_TIME;
|
|
||||||
var args = [].slice.call(arguments);
|
|
||||||
args.unshift(elapsedTime);
|
|
||||||
console.log.apply(console, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MessageHandler(name, comObj) {
|
function MessageHandler(name, comObj) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.comObj = comObj;
|
this.comObj = comObj;
|
||||||
|
@ -34304,16 +34290,13 @@ function MessageHandler(name, comObj) {
|
||||||
}];
|
}];
|
||||||
|
|
||||||
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
|
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
|
||||||
|
|
||||||
var handler;
|
|
||||||
|
|
||||||
var data = event.data;
|
var data = event.data;
|
||||||
if (data.isReply) {
|
if (data.isReply) {
|
||||||
var callbackId = data.callbackId;
|
var callbackId = data.callbackId;
|
||||||
if (data.callbackId in callbacks) {
|
if (data.callbackId in callbacks) {
|
||||||
var callback = callbacks[callbackId];
|
var callback = callbacks[callbackId];
|
||||||
delete callbacks[callbackId];
|
delete callbacks[callbackId];
|
||||||
handler = callback.bind(undefined, data.data);
|
callback(data.data);
|
||||||
} else {
|
} else {
|
||||||
error('Cannot resolve callback ' + callbackId);
|
error('Cannot resolve callback ' + callbackId);
|
||||||
}
|
}
|
||||||
|
@ -34328,19 +34311,13 @@ function MessageHandler(name, comObj) {
|
||||||
data: resolvedData
|
data: resolvedData
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
handler = action[0].bind(action[1], data.data, promise);
|
action[0].call(action[1], data.data, promise);
|
||||||
} else {
|
} else {
|
||||||
handler = action[0].bind(action[1], data.data);
|
action[0].call(action[1], data.data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error('Unkown action from worker: ' + data.action);
|
error('Unkown action from worker: ' + data.action);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handler) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handler();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34406,8 +34383,10 @@ var WorkerMessageHandler = {
|
||||||
loadDocumentPromise.reject(e);
|
loadDocumentPromise.reject(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
pdfManager.ensureModel('parse', recoveryMode).then(
|
pdfManager.ensureModel('setXrefStart').then(function() {
|
||||||
parseSuccess, parseFailure);
|
pdfManager.ensureModel('parse', recoveryMode).then(
|
||||||
|
parseSuccess, parseFailure);
|
||||||
|
});
|
||||||
|
|
||||||
return loadDocumentPromise;
|
return loadDocumentPromise;
|
||||||
}
|
}
|
||||||
|
@ -34416,11 +34395,12 @@ var WorkerMessageHandler = {
|
||||||
var pdfManagerPromise = new PDFJS.Promise();
|
var pdfManagerPromise = new PDFJS.Promise();
|
||||||
|
|
||||||
var source = data.source;
|
var source = data.source;
|
||||||
|
var rangeSupport = data.rangeSupport;
|
||||||
if (source.data) {
|
if (source.data) {
|
||||||
pdfManager = new LocalPdfManager(source.data, source.password);
|
pdfManager = new LocalPdfManager(source.data, source.password);
|
||||||
pdfManagerPromise.resolve();
|
pdfManagerPromise.resolve();
|
||||||
return pdfManagerPromise;
|
return pdfManagerPromise;
|
||||||
} else if (source.chunkedChromeLoading) {
|
} else if (source.chunkedViewerLoading) {
|
||||||
pdfManager = new NetworkPdfManager(source, handler);
|
pdfManager = new NetworkPdfManager(source, handler);
|
||||||
pdfManagerPromise.resolve();
|
pdfManagerPromise.resolve();
|
||||||
return pdfManagerPromise;
|
return pdfManagerPromise;
|
||||||
|
@ -34429,30 +34409,33 @@ var WorkerMessageHandler = {
|
||||||
var networkManager = new NetworkManager(source.url, {
|
var networkManager = new NetworkManager(source.url, {
|
||||||
httpHeaders: source.httpHeaders
|
httpHeaders: source.httpHeaders
|
||||||
});
|
});
|
||||||
networkManager.requestFull({
|
var fullRequestXhrId = networkManager.requestFull({
|
||||||
onHeadersReceived: function onHeadersReceieved(args) {
|
onHeadersReceived: function onHeadersReceived() {
|
||||||
var fullRequestXhrId = args.xhrId;
|
if (rangeSupport === 'disable') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// This is done in onHeadersReceived because we want to
|
var fullRequestXhr = networkManager.getRequestXhr(fullRequestXhrId);
|
||||||
// guarantee that the full request is sent first in
|
if (fullRequestXhr.getResponseHeader('Accept-Ranges') !== 'bytes') {
|
||||||
// case that the server will only allow max 1 request
|
return;
|
||||||
// (eg. pay-wall)
|
}
|
||||||
networkManager.requestRange(0, 1, function getPdfLength(args) {
|
|
||||||
// The full request is already finished, in which case we do not
|
|
||||||
// need to fetch chunks
|
|
||||||
if (!networkManager.isPendingRequest(fullRequestXhrId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(mack): In this case, we should access the data that
|
var contentLength = fullRequestXhr.getResponseHeader(
|
||||||
// is already fetched from the full request so we do not refetch
|
'Content-Length');
|
||||||
// the same data
|
contentLength = parseInt(contentLength, 10);
|
||||||
networkManager.abortRequest(fullRequestXhrId);
|
if (!isInt(contentLength)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
source.totalLength = args.totalLength;
|
// NOTE: by cancelling the full request, and then issuing range
|
||||||
pdfManager = new NetworkPdfManager(source, handler);
|
// requests, there will be an issue for sites where you can only
|
||||||
pdfManagerPromise.resolve(pdfManager);
|
// request the pdf once. However, if this is the case, then the
|
||||||
});
|
// server should not be returning that it can support range requests.
|
||||||
|
networkManager.abortRequest(fullRequestXhrId);
|
||||||
|
|
||||||
|
source.totalLength = contentLength;
|
||||||
|
pdfManager = new NetworkPdfManager(source, handler);
|
||||||
|
pdfManagerPromise.resolve(pdfManager);
|
||||||
},
|
},
|
||||||
onDone: function onDone(args) {
|
onDone: function onDone(args) {
|
||||||
// the data is array, instantiating directly from it
|
// the data is array, instantiating directly from it
|
||||||
|
|
|
@ -708,6 +708,10 @@ var PDFView = {
|
||||||
}, false);
|
}, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getPage: function pdfViewGetPage(n) {
|
||||||
|
return this.pdfDocument.getPage(n);
|
||||||
|
},
|
||||||
|
|
||||||
// Helper function to keep track whether a div was scrolled up or down and
|
// Helper function to keep track whether a div was scrolled up or down and
|
||||||
// then call a callback.
|
// then call a callback.
|
||||||
watchScroll: function pdfViewWatchScroll(viewAreaElement, state, callback) {
|
watchScroll: function pdfViewWatchScroll(viewAreaElement, state, callback) {
|
||||||
|
@ -890,28 +894,43 @@ var PDFView = {
|
||||||
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
|
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
|
||||||
}
|
}
|
||||||
|
|
||||||
function windowMessage(e) {
|
var PdfDataRangeTransport = {
|
||||||
|
listeners: [],
|
||||||
|
|
||||||
|
addListener: function PdfDataRangeTransport_addListener(listener) {
|
||||||
|
this.listeners.push(listener);
|
||||||
|
},
|
||||||
|
|
||||||
|
onDataRange: function PdfDataRangeTransport_onDataRange(args) {
|
||||||
|
for (var i = 0; i < this.listeners.length; ++i) {
|
||||||
|
this.listeners[i](args);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
requestDataRange: function PdfDataRangeTransport_requestDataRange(
|
||||||
|
begin, end) {
|
||||||
|
FirefoxCom.request('requestDataRange', { begin: begin, end: end });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('message', function windowMessage(e) {
|
||||||
var args = e.data;
|
var args = e.data;
|
||||||
|
|
||||||
if (typeof args !== 'object' || !('pdfjsLoadAction' in args))
|
if (typeof args !== 'object' || !('pdfjsLoadAction' in args))
|
||||||
return;
|
return;
|
||||||
switch (args.pdfjsLoadAction) {
|
switch (args.pdfjsLoadAction) {
|
||||||
case 'supportsChunkedLoading':
|
case 'supportsChunkedLoading':
|
||||||
window.removeEventListener('message', windowMessage);
|
PDFView.open(args.pdfUrl, 0, undefined, PdfDataRangeTransport, {
|
||||||
PDFView.open({
|
totalLength: args.totalLength
|
||||||
url: args.pdfUrl,
|
});
|
||||||
chunkedChromeLoading: true,
|
break;
|
||||||
totalLength: args.totalLength,
|
case 'chunk':
|
||||||
loadedBegin: args.loadedBegin,
|
PdfDataRangeTransport.onDataRange(args);
|
||||||
loadedChunk: args.loadedChunk
|
|
||||||
}, 0);
|
|
||||||
break;
|
break;
|
||||||
case 'progress':
|
case 'progress':
|
||||||
PDFView.progress(args.loaded / args.total);
|
PDFView.progress(args.loaded / args.total);
|
||||||
break;
|
break;
|
||||||
case 'complete':
|
case 'complete':
|
||||||
// TODO(mack): remove the listener when file loading is complete
|
|
||||||
// window.removeEventListener('message', windowMessage);
|
|
||||||
if (!args.data) {
|
if (!args.data) {
|
||||||
PDFView.error(mozL10n.get('loading_error', null,
|
PDFView.error(mozL10n.get('loading_error', null,
|
||||||
'An error occurred while loading the PDF.'), e);
|
'An error occurred while loading the PDF.'), e);
|
||||||
|
@ -920,8 +939,7 @@ var PDFView = {
|
||||||
PDFView.open(args.data, 0);
|
PDFView.open(args.data, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
window.addEventListener('message', windowMessage);
|
|
||||||
FirefoxCom.requestSync('initPassiveLoading', null);
|
FirefoxCom.requestSync('initPassiveLoading', null);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -940,17 +958,21 @@ var PDFView = {
|
||||||
document.title = title;
|
document.title = title;
|
||||||
},
|
},
|
||||||
|
|
||||||
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) {
|
||||||
|
scale = scale || 1;
|
||||||
var parameters = {password: password};
|
var parameters = {password: password};
|
||||||
if (typeof url === 'string') { // URL
|
if (typeof url === 'string') { // URL
|
||||||
this.setTitleUsingUrl(url);
|
this.setTitleUsingUrl(url);
|
||||||
parameters.url = url;
|
parameters.url = url;
|
||||||
} else if (url && 'byteLength' in url) { // ArrayBuffer
|
} else if (url && 'byteLength' in url) { // ArrayBuffer
|
||||||
parameters.data = url;
|
parameters.data = url;
|
||||||
} else {
|
}
|
||||||
this.setTitleUsingUrl(url.url);
|
if (args) {
|
||||||
parameters = url;
|
for (var prop in args) {
|
||||||
parameters.password = password;
|
parameters[prop] = args[prop];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PDFView.loadingBar) {
|
if (!PDFView.loadingBar) {
|
||||||
|
@ -960,7 +982,7 @@ var PDFView = {
|
||||||
this.pdfDocument = null;
|
this.pdfDocument = null;
|
||||||
var self = this;
|
var self = this;
|
||||||
self.loading = true;
|
self.loading = true;
|
||||||
PDFJS.getDocument(parameters).then(
|
PDFJS.getDocument(parameters, pdfDataRangeTransport).then(
|
||||||
function getDocumentCallback(pdfDocument) {
|
function getDocumentCallback(pdfDocument) {
|
||||||
self.load(pdfDocument, scale);
|
self.load(pdfDocument, scale);
|
||||||
self.loading = false;
|
self.loading = false;
|
||||||
|
@ -1192,7 +1214,6 @@ var PDFView = {
|
||||||
container.removeChild(container.lastChild);
|
container.removeChild(container.lastChild);
|
||||||
|
|
||||||
var pagesCount = pdfDocument.numPages;
|
var pagesCount = pdfDocument.numPages;
|
||||||
|
|
||||||
var id = pdfDocument.fingerprint;
|
var id = pdfDocument.fingerprint;
|
||||||
document.getElementById('numPages').textContent =
|
document.getElementById('numPages').textContent =
|
||||||
mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}');
|
mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}');
|
||||||
|
@ -1209,79 +1230,70 @@ var PDFView = {
|
||||||
this.startedTextExtraction = false;
|
this.startedTextExtraction = false;
|
||||||
var pagesRefMap = this.pagesRefMap = {};
|
var pagesRefMap = this.pagesRefMap = {};
|
||||||
var thumbnails = this.thumbnails = [];
|
var thumbnails = this.thumbnails = [];
|
||||||
var pagePromises = [];
|
|
||||||
|
|
||||||
var firstPageLoaded = true;
|
|
||||||
|
|
||||||
|
var defaultViewportPromise = new PDFJS.Promise();
|
||||||
|
var pagesPromise = new PDFJS.Promise();
|
||||||
var self = this;
|
var self = this;
|
||||||
for (var pageIdx = 0; pageIdx < pagesCount; ++pageIdx) {
|
|
||||||
var pageNum = pageIdx + 1;
|
|
||||||
var pagePromise = pdfDocument.getPage(pageNum);
|
|
||||||
pagePromise.then(function(page) {
|
|
||||||
|
|
||||||
if (firstPageLoaded) {
|
// TODO(mack): Verify is safe to assume at least one page if
|
||||||
var pagesFrag = document.createDocumentFragment();
|
// we're here.
|
||||||
// TODO(mack): clone
|
pdfDocument.getPage(1).then(function(pdfPage) {
|
||||||
var defaultView = page.view;
|
var viewport = pdfPage.getViewport(scale);
|
||||||
for (var pageIdx = 0; pageIdx < pagesCount; ++pageIdx) {
|
defaultViewportPromise.resolve(viewport);
|
||||||
var pageNum = pageIdx + 1;
|
});
|
||||||
var pageView = new PageView(container, pageNum, scale,
|
|
||||||
self.navigateTo.bind(self), defaultView);
|
|
||||||
pages[pageIdx] = pageView;
|
|
||||||
pagesFrag.appendChild(pageView.element);
|
|
||||||
}
|
|
||||||
container.appendChild(pagesFrag);
|
|
||||||
|
|
||||||
var storedHash = null;
|
defaultViewportPromise.then(function(viewport) {
|
||||||
if (store.get('exists', false)) {
|
var pagePromises = [];
|
||||||
var page_ = store.get('page', '1');
|
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
|
||||||
var zoom = store.get('zoom', PDFView.currentScale);
|
var viewportClone = viewport.clone();
|
||||||
var left = store.get('scrollLeft', '0');
|
var pageView = new PageView(container, pageNum, scale,
|
||||||
var top = store.get('scrollTop', '0');
|
self.navigateTo.bind(self),
|
||||||
|
viewportClone);
|
||||||
storedHash =
|
var thumbnailView = new ThumbnailView(thumbsView, pageNum,
|
||||||
'page=' + page_ + '&zoom=' + zoom + ',' + left +',' + top;
|
viewportClone);
|
||||||
}
|
|
||||||
|
|
||||||
self.setInitialView(storedHash, scale);
|
|
||||||
firstPageLoaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pageIdx = page.pageInfo.pageIndex;
|
|
||||||
var pageNum = pageIdx + 1;
|
|
||||||
|
|
||||||
var pageView = pages[pageIdx];
|
|
||||||
pageView.setPdfPage(page);
|
|
||||||
pageView.setStats(page.stats);
|
|
||||||
var thumbnailView = new ThumbnailView(thumbsView, page, pageNum);
|
|
||||||
bindOnAfterDraw(pageView, thumbnailView);
|
bindOnAfterDraw(pageView, thumbnailView);
|
||||||
|
pages.push(pageView);
|
||||||
|
thumbnails.push(thumbnailView);
|
||||||
|
|
||||||
pages[pageIdx] = pageView;
|
var pagePromise = pdfDocument.getPage(pageNum);
|
||||||
thumbnails[pageIdx] = thumbnailView;
|
pagePromise.then(function(pdfPage) {
|
||||||
var pageRef = page.ref;
|
pageView.setPdfPage(pdfPage);
|
||||||
pagesRefMap[pageRef.num + ' ' + pageRef.gen + ' R'] = pageNum;
|
thumbnailView.setPdfPage(pdfPage);
|
||||||
|
|
||||||
var visiblePages = self.visiblePages;
|
var pageRef = pdfPage.ref;
|
||||||
var firstNum = visiblePages.first.id;
|
var refStr = pageRef.num + ' ' + pageRef.gen + ' R';
|
||||||
var lastNum = visiblePages.last.id;
|
pagesRefMap[refStr] = pdfPage.pageNumber;
|
||||||
if (pageNum >= firstNum && pageNum <= lastNum) {
|
});
|
||||||
// TODO(mack): This logic could probably be better, as it's probably
|
pagePromises.push(pagePromise);
|
||||||
// going in here more often than necessary
|
}
|
||||||
self.renderHighestPriority();
|
|
||||||
//updateViewarea();
|
var event = document.createEvent('CustomEvent');
|
||||||
}
|
event.initCustomEvent('documentload', true, true, {});
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
|
||||||
|
var storedHash = null;
|
||||||
|
if (store.get('exists', false)) {
|
||||||
|
var page_ = store.get('page', '1');
|
||||||
|
var zoom = store.get('zoom', PDFView.currentScale);
|
||||||
|
var left = store.get('scrollLeft', '0');
|
||||||
|
var top = store.get('scrollTop', '0');
|
||||||
|
|
||||||
|
storedHash = 'page=' + page_ + '&zoom=' + zoom + ',' + left +',' + top;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.setInitialView(storedHash, scale);
|
||||||
|
|
||||||
|
PDFJS.Promise.all(pagePromises).then(function(pages) {
|
||||||
|
pagesPromise.resolve(pages);
|
||||||
});
|
});
|
||||||
pagePromises.push(pagePromise);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
var pagesPromise = PDFJS.Promise.all(pagePromises);
|
|
||||||
|
|
||||||
var destinationsPromise = pdfDocument.getDestinations();
|
var destinationsPromise = pdfDocument.getDestinations();
|
||||||
destinationsPromise.then(function(destinations) {
|
destinationsPromise.then(function(destinations) {
|
||||||
self.destinations = destinations;
|
self.destinations = destinations;
|
||||||
});
|
});
|
||||||
|
|
||||||
// outline and initial view depends on destinations and pagesRefMap
|
// outline depends on destinations and pagesRefMap
|
||||||
var promises = [pagesPromise, destinationsPromise, storePromise,
|
var promises = [pagesPromise, destinationsPromise, storePromise,
|
||||||
PDFView.animationStartedPromise];
|
PDFView.animationStartedPromise];
|
||||||
PDFJS.Promise.all(promises).then(function() {
|
PDFJS.Promise.all(promises).then(function() {
|
||||||
|
@ -1345,8 +1357,8 @@ var PDFView = {
|
||||||
|
|
||||||
renderHighestPriority: function pdfViewRenderHighestPriority() {
|
renderHighestPriority: function pdfViewRenderHighestPriority() {
|
||||||
// Pages have a higher priority than thumbnails, so check them first.
|
// Pages have a higher priority than thumbnails, so check them first.
|
||||||
this.visiblePages = this.getVisiblePages();
|
var visiblePages = this.getVisiblePages();
|
||||||
var pageView = this.getHighestPriority(this.visiblePages, this.pages,
|
var pageView = this.getHighestPriority(visiblePages, this.pages,
|
||||||
this.pageViewScroll.down);
|
this.pageViewScroll.down);
|
||||||
if (pageView) {
|
if (pageView) {
|
||||||
this.renderView(pageView, 'page');
|
this.renderView(pageView, 'page');
|
||||||
|
@ -1379,7 +1391,7 @@ var PDFView = {
|
||||||
}
|
}
|
||||||
for (var i = 0; i < numVisible; ++i) {
|
for (var i = 0; i < numVisible; ++i) {
|
||||||
var view = visibleViews[i].view;
|
var view = visibleViews[i].view;
|
||||||
if (!this.isViewRenderable(view))
|
if (!this.isViewFinished(view))
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1387,22 +1399,19 @@ var PDFView = {
|
||||||
if (scrolledDown) {
|
if (scrolledDown) {
|
||||||
var nextPageIndex = visible.last.id;
|
var nextPageIndex = visible.last.id;
|
||||||
// ID's start at 1 so no need to add 1.
|
// ID's start at 1 so no need to add 1.
|
||||||
if (views[nextPageIndex] && !this.isViewRenderable(views[nextPageIndex]))
|
if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex]))
|
||||||
return views[nextPageIndex];
|
return views[nextPageIndex];
|
||||||
} else {
|
} else {
|
||||||
var previousPageIndex = visible.first.id - 2;
|
var previousPageIndex = visible.first.id - 2;
|
||||||
if (views[previousPageIndex] &&
|
if (views[previousPageIndex] &&
|
||||||
!this.isViewRenderable(views[previousPageIndex]))
|
!this.isViewFinished(views[previousPageIndex]))
|
||||||
return views[previousPageIndex];
|
return views[previousPageIndex];
|
||||||
}
|
}
|
||||||
// Everything that needs to be rendered has been.
|
// Everything that needs to be rendered has been.
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
isViewRenderable: function pdfViewNeedsRendering(view) {
|
isViewFinished: function pdfViewNeedsRendering(view) {
|
||||||
if (view instanceof PageView && !view.pdfPage) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return view.renderingState === RenderingStates.FINISHED;
|
return view.renderingState === RenderingStates.FINISHED;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1682,7 +1691,7 @@ var PDFView = {
|
||||||
|
|
||||||
for (var i = 0, l = this.thumbnails.length; i < l; i++) {
|
for (var i = 0, l = this.thumbnails.length; i < l; i++) {
|
||||||
var thumb = this.thumbnails[i];
|
var thumb = this.thumbnails[i];
|
||||||
thumb.updateRotation(this.pageRotation);
|
thumb.update(this.pageRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentPage = this.pages[this.page - 1];
|
var currentPage = this.pages[this.page - 1];
|
||||||
|
@ -1764,29 +1773,13 @@ var PDFView = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var PageView = function pageView(container, id, scale,
|
var PageView = function pageView(container, id, scale,
|
||||||
navigateTo, defaultView) {
|
navigateTo, defaultViewport) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
//this.pdfPage = pdfPage;
|
|
||||||
|
|
||||||
this.rotation = 0;
|
this.rotation = 0;
|
||||||
this.scale = scale || 1.0;
|
this.scale = scale || 1.0;
|
||||||
//this.viewport = this.pdfPage.getViewport(this.scale, this.pdfPage.rotate);
|
this.viewport = defaultViewport;
|
||||||
this.defaultView = defaultView;
|
this.pdfPageRotate = defaultViewport.rotate;
|
||||||
|
|
||||||
this.getViewport = function pageViewGetViewport() {
|
|
||||||
var view;
|
|
||||||
var totalRotation;
|
|
||||||
if (this.pdfPage) {
|
|
||||||
totalRotation = (this.rotation + this.pdfPage.rotate) % 360;
|
|
||||||
view = this.pdfPage.view;
|
|
||||||
} else {
|
|
||||||
totalRotation = this.rotation;
|
|
||||||
view = this.defaultView;
|
|
||||||
}
|
|
||||||
return new PDFJS.PageViewport(view, this.scale, totalRotation, 0, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.viewport = this.getViewport();
|
|
||||||
|
|
||||||
this.renderingState = RenderingStates.INITIAL;
|
this.renderingState = RenderingStates.INITIAL;
|
||||||
this.resume = null;
|
this.resume = null;
|
||||||
|
@ -1798,38 +1791,27 @@ var PageView = function pageView(container, id, scale,
|
||||||
anchor.name = '' + this.id;
|
anchor.name = '' + this.id;
|
||||||
|
|
||||||
var div = this.el = document.createElement('div');
|
var div = this.el = document.createElement('div');
|
||||||
//var div = this.el = element;
|
|
||||||
div.id = 'pageContainer' + this.id;
|
div.id = 'pageContainer' + this.id;
|
||||||
div.className = 'page';
|
div.className = 'page';
|
||||||
div.style.width = Math.floor(this.viewport.width) + 'px';
|
div.style.width = Math.floor(this.viewport.width) + 'px';
|
||||||
div.style.height = Math.floor(this.viewport.height) + 'px';
|
div.style.height = Math.floor(this.viewport.height) + 'px';
|
||||||
|
|
||||||
this.container = container;
|
container.appendChild(anchor);
|
||||||
//this.container.appendChild(anchor);
|
container.appendChild(div);
|
||||||
//this.container.appendChild(div);
|
|
||||||
|
|
||||||
var docFrag = document.createDocumentFragment();
|
|
||||||
docFrag.appendChild(anchor);
|
|
||||||
docFrag.appendChild(div);
|
|
||||||
|
|
||||||
Object.defineProperty(this, 'element', {
|
|
||||||
get: function PlaceholderPageView_getElement() {
|
|
||||||
return docFrag;
|
|
||||||
},
|
|
||||||
enumerable: true
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setPdfPage = function pageViewSetPdfPage(pdfPage) {
|
this.setPdfPage = function pageViewSetPdfPage(pdfPage) {
|
||||||
this.pdfPage = pdfPage;
|
this.pdfPage = pdfPage;
|
||||||
};
|
this.pdfPageRotate = pdfPage.rotate;
|
||||||
|
this.viewport = pdfPage.getViewport(this.scale);
|
||||||
this.setStats = function pageViewSetStats(stats) {
|
this.stats = pdfPage.stats;
|
||||||
this.stats = stats;
|
this.update();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.destroy = function pageViewDestroy() {
|
this.destroy = function pageViewDestroy() {
|
||||||
this.update();
|
this.update();
|
||||||
this.pdfPage.destroy();
|
if (this.pdfPage) {
|
||||||
|
this.pdfPage.destroy();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.update = function pageViewUpdate(scale, rotation) {
|
this.update = function pageViewUpdate(scale, rotation) {
|
||||||
|
@ -1841,11 +1823,14 @@ var PageView = function pageView(container, id, scale,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scale = scale || this.scale;
|
this.scale = scale || this.scale;
|
||||||
var viewport = this.getViewport();
|
var totalRotation = (this.rotation + this.pdfPageRotate) % 360;
|
||||||
|
this.viewport = this.viewport.clone({
|
||||||
|
scale: this.scale,
|
||||||
|
rotation: totalRotation
|
||||||
|
});
|
||||||
|
|
||||||
this.viewport = viewport;
|
div.style.width = Math.floor(this.viewport.width) + 'px';
|
||||||
div.style.width = Math.floor(viewport.width) + 'px';
|
div.style.height = Math.floor(this.viewport.height) + 'px';
|
||||||
div.style.height = Math.floor(viewport.height) + 'px';
|
|
||||||
|
|
||||||
while (div.hasChildNodes())
|
while (div.hasChildNodes())
|
||||||
div.removeChild(div.lastChild);
|
div.removeChild(div.lastChild);
|
||||||
|
@ -2047,11 +2032,16 @@ var PageView = function pageView(container, id, scale,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.draw = function pageviewDraw(callback) {
|
this.draw = function pageviewDraw(callback) {
|
||||||
if (!this.pdfPage) {
|
var pdfPage = this.pdfPage;
|
||||||
console.log('Cannot draw without page');
|
|
||||||
|
if (!pdfPage) {
|
||||||
|
var promise = PDFView.getPage(this.id);
|
||||||
|
promise.then(function(pdfPage) {
|
||||||
|
this.setPdfPage(pdfPage);
|
||||||
|
this.draw(callback);
|
||||||
|
}.bind(this));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var pdfPage = this.pdfPage;
|
|
||||||
|
|
||||||
if (this.renderingState !== RenderingStates.INITIAL) {
|
if (this.renderingState !== RenderingStates.INITIAL) {
|
||||||
console.error('Must be in new state before drawing');
|
console.error('Must be in new state before drawing');
|
||||||
|
@ -2110,7 +2100,6 @@ var PageView = function pageView(container, id, scale,
|
||||||
ctx.scale(outputScale.sx, outputScale.sy);
|
ctx.scale(outputScale.sx, outputScale.sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Rendering area
|
// Rendering area
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -2138,6 +2127,15 @@ var PageView = function pageView(container, id, scale,
|
||||||
self.onAfterDraw();
|
self.onAfterDraw();
|
||||||
|
|
||||||
cache.push(self);
|
cache.push(self);
|
||||||
|
|
||||||
|
// TODO(mack): Verify this will not happend for thumbnails
|
||||||
|
// TODO(mack): Maybe should be attaching event to canvas
|
||||||
|
var event = document.createEvent('CustomEvent');
|
||||||
|
event.initCustomEvent('pagerender', true, true, {
|
||||||
|
pageNum: pdfPage.pageNumber
|
||||||
|
});
|
||||||
|
div.dispatchEvent(event);
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2183,13 +2181,14 @@ var PageView = function pageView(container, id, scale,
|
||||||
|
|
||||||
setupAnnotations(this.pdfPage, this.viewport);
|
setupAnnotations(this.pdfPage, this.viewport);
|
||||||
div.setAttribute('data-loaded', true);
|
div.setAttribute('data-loaded', true);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.beforePrint = function pageViewBeforePrint() {
|
this.beforePrint = function pageViewBeforePrint() {
|
||||||
var pdfPage = this.pdfPage;
|
var pdfPage = this.pdfPage;
|
||||||
|
|
||||||
if (!pdfPage) {
|
if (!pdfPage) {
|
||||||
console.log('Pdf page has not been rendered and thus cannot be printed');
|
// TODO(mack): What to do if page is not loaded?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2244,7 +2243,7 @@ var PageView = function pageView(container, id, scale,
|
||||||
|
|
||||||
this.updateStats = function pageViewUpdateStats() {
|
this.updateStats = function pageViewUpdateStats() {
|
||||||
if (!this.stats) {
|
if (!this.stats) {
|
||||||
console.log('No stats available');
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PDFJS.pdfBug && Stats.enabled) {
|
if (PDFJS.pdfBug && Stats.enabled) {
|
||||||
|
@ -2254,7 +2253,7 @@ var PageView = function pageView(container, id, scale,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
var ThumbnailView = function thumbnailView(container, id, defaultViewport) {
|
||||||
var anchor = document.createElement('a');
|
var anchor = document.createElement('a');
|
||||||
anchor.href = PDFView.getAnchorUrl('#page=' + id);
|
anchor.href = PDFView.getAnchorUrl('#page=' + id);
|
||||||
anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}');
|
anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}');
|
||||||
|
@ -2263,18 +2262,20 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
var rotation = 0;
|
this.pdfPage = undefined;
|
||||||
var totalRotation = (rotation + pdfPage.rotate) % 360;
|
this.viewport = defaultViewport;
|
||||||
var viewport = pdfPage.getViewport(1, totalRotation);
|
this.pdfPageRotate = defaultViewport.rotate;
|
||||||
var pageWidth = this.width = viewport.width;
|
|
||||||
var pageHeight = this.height = viewport.height;
|
this.rotation = 0;
|
||||||
var pageRatio = pageWidth / pageHeight;
|
this.totalRotation = (this.rotation + this.pdfPageRotate) % 360;
|
||||||
|
this.pageWidth = this.viewport.width;
|
||||||
|
this.pageHeight = this.viewport.height;
|
||||||
|
this.pageRatio = this.pageWidth / this.pageHeight;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
||||||
var canvasWidth = 98;
|
this.canvasWidth = 98;
|
||||||
var canvasHeight = canvasWidth / this.width * this.height;
|
this.canvasHeight = this.canvasWidth / this.pageWidth * this.pageHeight;
|
||||||
var scaleX = this.scaleX = (canvasWidth / pageWidth);
|
this.scale = (this.canvasWidth / this.pageWidth);
|
||||||
var scaleY = this.scaleY = (canvasHeight / pageHeight);
|
|
||||||
|
|
||||||
var div = this.el = document.createElement('div');
|
var div = this.el = document.createElement('div');
|
||||||
div.id = 'thumbnailContainer' + id;
|
div.id = 'thumbnailContainer' + id;
|
||||||
|
@ -2288,8 +2289,8 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||||
|
|
||||||
var ring = document.createElement('div');
|
var ring = document.createElement('div');
|
||||||
ring.className = 'thumbnailSelectionRing';
|
ring.className = 'thumbnailSelectionRing';
|
||||||
ring.style.width = canvasWidth + 'px';
|
ring.style.width = this.canvasWidth + 'px';
|
||||||
ring.style.height = canvasHeight + 'px';
|
ring.style.height = this.canvasHeight + 'px';
|
||||||
|
|
||||||
div.appendChild(ring);
|
div.appendChild(ring);
|
||||||
anchor.appendChild(div);
|
anchor.appendChild(div);
|
||||||
|
@ -2298,36 +2299,46 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||||
this.hasImage = false;
|
this.hasImage = false;
|
||||||
this.renderingState = RenderingStates.INITIAL;
|
this.renderingState = RenderingStates.INITIAL;
|
||||||
|
|
||||||
this.updateRotation = function(rot) {
|
this.setPdfPage = function thumbnailViewSetPdfPage(pdfPage) {
|
||||||
|
this.pdfPage = pdfPage;
|
||||||
|
this.pdfPageRotate = pdfPage.rotate;
|
||||||
|
this.viewport = pdfPage.getViewport(this.scale);
|
||||||
|
this.update();
|
||||||
|
};
|
||||||
|
|
||||||
rotation = rot;
|
this.update = function(rot) {
|
||||||
totalRotation = (rotation + pdfPage.rotate) % 360;
|
if (rot !== undefined) {
|
||||||
viewport = pdfPage.getViewport(1, totalRotation);
|
this.rotation = rot;
|
||||||
pageWidth = this.width = viewport.width;
|
}
|
||||||
pageHeight = this.height = viewport.height;
|
this.totalRotation = (this.rotation + this.pdfPageRotate) % 360;
|
||||||
pageRatio = pageWidth / pageHeight;
|
this.viewport = this.viewport.clone({
|
||||||
|
scale: 1,
|
||||||
|
rotation: this.totalRotation
|
||||||
|
});
|
||||||
|
this.pageWidth = this.viewport.width;
|
||||||
|
this.pageHeight = this.viewport.height;
|
||||||
|
this.pageRatio = this.pageWidth / this.pageHeight;
|
||||||
|
|
||||||
canvasHeight = canvasWidth / this.width * this.height;
|
this.canvasHeight = this.canvasWidth / this.pageWidth * this.pageHeight;
|
||||||
scaleX = this.scaleX = (canvasWidth / pageWidth);
|
this.scale = (this.canvasHeight / this.pageHeight);
|
||||||
scaleY = this.scaleY = (canvasHeight / pageHeight);
|
|
||||||
|
|
||||||
div.removeAttribute('data-loaded');
|
div.removeAttribute('data-loaded');
|
||||||
ring.textContent = '';
|
ring.textContent = '';
|
||||||
ring.style.width = canvasWidth + 'px';
|
ring.style.width = this.canvasWidth + 'px';
|
||||||
ring.style.height = canvasHeight + 'px';
|
ring.style.height = this.canvasHeight + 'px';
|
||||||
|
|
||||||
this.hasImage = false;
|
this.hasImage = false;
|
||||||
this.renderingState = RenderingStates.INITIAL;
|
this.renderingState = RenderingStates.INITIAL;
|
||||||
this.resume = null;
|
this.resume = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getPageDrawContext() {
|
this.getPageDrawContext = function thumnailViewGetPageDrawContext() {
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
canvas.id = 'thumbnail' + id;
|
canvas.id = 'thumbnail' + id;
|
||||||
canvas.mozOpaque = true;
|
canvas.mozOpaque = true;
|
||||||
|
|
||||||
canvas.width = canvasWidth;
|
canvas.width = this.canvasWidth;
|
||||||
canvas.height = canvasHeight;
|
canvas.height = this.canvasHeight;
|
||||||
canvas.className = 'thumbnailImage';
|
canvas.className = 'thumbnailImage';
|
||||||
canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas',
|
canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas',
|
||||||
{page: id}, 'Thumbnail of Page {{page}}'));
|
{page: id}, 'Thumbnail of Page {{page}}'));
|
||||||
|
@ -2339,16 +2350,25 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||||
var ctx = canvas.getContext('2d');
|
var ctx = canvas.getContext('2d');
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.fillStyle = 'rgb(255, 255, 255)';
|
ctx.fillStyle = 'rgb(255, 255, 255)';
|
||||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
},
|
||||||
|
|
||||||
this.drawingRequired = function thumbnailViewDrawingRequired() {
|
this.drawingRequired = function thumbnailViewDrawingRequired() {
|
||||||
return !this.hasImage;
|
return !this.hasImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.draw = function thumbnailViewDraw(callback) {
|
this.draw = function thumbnailViewDraw(callback) {
|
||||||
|
if (!this.pdfPage) {
|
||||||
|
var promise = PDFView.getPage(this.id);
|
||||||
|
promise.then(function(pdfPage) {
|
||||||
|
this.setPdfPage(pdfPage);
|
||||||
|
this.draw(callback);
|
||||||
|
}.bind(this));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.renderingState !== RenderingStates.INITIAL) {
|
if (this.renderingState !== RenderingStates.INITIAL) {
|
||||||
console.error('Must be in new state before drawing');
|
console.error('Must be in new state before drawing');
|
||||||
}
|
}
|
||||||
|
@ -2360,8 +2380,9 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var ctx = getPageDrawContext();
|
var ctx = this.getPageDrawContext();
|
||||||
var drawViewport = pdfPage.getViewport(scaleX, totalRotation);
|
var drawViewport = this.pdfPage.getViewport(this.scale,
|
||||||
|
this.totalRotation);
|
||||||
var renderContext = {
|
var renderContext = {
|
||||||
canvasContext: ctx,
|
canvasContext: ctx,
|
||||||
viewport: drawViewport,
|
viewport: drawViewport,
|
||||||
|
@ -2377,7 +2398,7 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||||
cont();
|
cont();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
pdfPage.render(renderContext).then(
|
this.pdfPage.render(renderContext).then(
|
||||||
function pdfPageRenderCallback() {
|
function pdfPageRenderCallback() {
|
||||||
self.renderingState = RenderingStates.FINISHED;
|
self.renderingState = RenderingStates.FINISHED;
|
||||||
callback();
|
callback();
|
||||||
|
@ -2394,7 +2415,7 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||||
if (this.hasImage || !img)
|
if (this.hasImage || !img)
|
||||||
return;
|
return;
|
||||||
this.renderingState = RenderingStates.FINISHED;
|
this.renderingState = RenderingStates.FINISHED;
|
||||||
var ctx = getPageDrawContext();
|
var ctx = this.getPageDrawContext();
|
||||||
ctx.drawImage(img, 0, 0, img.width, img.height,
|
ctx.drawImage(img, 0, 0, img.width, img.height,
|
||||||
0, 0, ctx.canvas.width, ctx.canvas.height);
|
0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||||
|
|
||||||
|
@ -2837,8 +2858,13 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
|
||||||
var hash = document.location.hash.substring(1);
|
var hash = document.location.hash.substring(1);
|
||||||
var hashParams = PDFView.parseQueryString(hash);
|
var hashParams = PDFView.parseQueryString(hash);
|
||||||
|
|
||||||
if ('disableWorker' in hashParams)
|
if ('disableWorker' in hashParams) {
|
||||||
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
|
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('rangeSupport' in hashParams) {
|
||||||
|
PDFJS.rangeSupport = hashParams['rangeSupport'];
|
||||||
|
}
|
||||||
|
|
||||||
var locale = navigator.language;
|
var locale = navigator.language;
|
||||||
if ('locale' in hashParams)
|
if ('locale' in hashParams)
|
||||||
|
@ -3157,24 +3183,19 @@ window.addEventListener('pagechange', function pagechange(evt) {
|
||||||
var selected = document.querySelector('.thumbnail.selected');
|
var selected = document.querySelector('.thumbnail.selected');
|
||||||
if (selected)
|
if (selected)
|
||||||
selected.classList.remove('selected');
|
selected.classList.remove('selected');
|
||||||
|
|
||||||
var thumbnail = document.getElementById('thumbnailContainer' + page);
|
var thumbnail = document.getElementById('thumbnailContainer' + page);
|
||||||
// FIXME(mack): remove checking if thumbnail is null hack
|
thumbnail.classList.add('selected');
|
||||||
if (thumbnail) {
|
var visibleThumbs = PDFView.getVisibleThumbs();
|
||||||
thumbnail.classList.add('selected');
|
var numVisibleThumbs = visibleThumbs.views.length;
|
||||||
var visibleThumbs = PDFView.getVisibleThumbs();
|
// If the thumbnail isn't currently visible scroll it into view.
|
||||||
var numVisibleThumbs = visibleThumbs.views.length;
|
if (numVisibleThumbs > 0) {
|
||||||
// If the thumbnail isn't currently visible scroll it into view.
|
var first = visibleThumbs.first.id;
|
||||||
if (numVisibleThumbs > 0) {
|
// Account for only one thumbnail being visible.
|
||||||
var first = visibleThumbs.first.id;
|
var last = numVisibleThumbs > 1 ?
|
||||||
// Account for only one thumbnail being visible.
|
visibleThumbs.last.id : first;
|
||||||
var last = numVisibleThumbs > 1 ?
|
if (page <= first || page >= last)
|
||||||
visibleThumbs.last.id : first;
|
scrollIntoView(thumbnail);
|
||||||
if (page <= first || page >= last)
|
|
||||||
scrollIntoView(thumbnail);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
document.getElementById('previous').disabled = (page <= 1);
|
document.getElementById('previous').disabled = (page <= 1);
|
||||||
document.getElementById('next').disabled = (page >= PDFView.pages.length);
|
document.getElementById('next').disabled = (page >= PDFView.pages.length);
|
||||||
|
|
Loading…
Reference in a new issue