Bug 1084158 - Update pdf.js to version 1.0.907. r=bdahl, r=Mossop

This commit is contained in:
Ryan VanderMeulen 2014-10-17 14:15:43 -04:00
parent 7c2f78133d
commit 184cfae5bf
14 changed files with 3524 additions and 2479 deletions

View File

@ -1,4 +1,4 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.0.801
Current extension version is: 1.0.907

View File

@ -78,7 +78,9 @@ var DEFAULT_PREFERENCES = {
sidebarViewOnLoad: 0,
enableHandToolOnLoad: false,
enableWebGL: false,
pdfBugEnabled: false,
disableRange: false,
disableStream: false,
disableAutoFetch: false,
disableFontFace: false,
disableTextLayer: false,

View File

@ -77,7 +77,8 @@ function getFindBar(domWindow) {
var browser = getContainingBrowser(domWindow);
try {
var tabbrowser = browser.getTabBrowser();
var tab = tabbrowser.getTabForBrowser(browser);
var tab;
tab = tabbrowser.getTabForBrowser(browser);
return tabbrowser.getFindBar(tab);
} catch (e) {
// FF22 has no _getTabForBrowser, and FF24 has no getFindBar
@ -162,40 +163,38 @@ function makeContentReadable(obj, window) {
// PDF data storage
function PdfDataListener(length) {
this.length = length; // less than 0, if length is unknown
this.data = new Uint8Array(length >= 0 ? length : 0x10000);
this.buffer = null;
this.loaded = 0;
}
PdfDataListener.prototype = {
append: function PdfDataListener_append(chunk) {
var willBeLoaded = this.loaded + chunk.length;
if (this.length >= 0 && this.length < willBeLoaded) {
// In most of the cases we will pass data as we receive it, but at the
// beginning of the loading we may accumulate some data.
if (!this.buffer) {
this.buffer = new Uint8Array(chunk);
} else {
var buffer = this.buffer;
var newBuffer = new Uint8Array(buffer.length + chunk.length);
newBuffer.set(buffer);
newBuffer.set(chunk, buffer.length);
this.buffer = newBuffer;
}
this.loaded += chunk.length;
if (this.length >= 0 && this.length < this.loaded) {
this.length = -1; // reset the length, server is giving incorrect one
}
if (this.length < 0 && this.data.length < willBeLoaded) {
// data length is unknown and new chunk will not fit in the existing
// buffer, resizing the buffer by doubling the its last length
var newLength = this.data.length;
for (; newLength < willBeLoaded; newLength *= 2) {}
var newData = new Uint8Array(newLength);
newData.set(this.data);
this.data = newData;
}
this.data.set(chunk, this.loaded);
this.loaded = willBeLoaded;
this.onprogress(this.loaded, this.length >= 0 ? this.length : void(0));
},
getData: function PdfDataListener_getData() {
var data = this.data;
if (this.loaded != data.length)
data = data.subarray(0, this.loaded);
delete this.data; // releasing temporary storage
return data;
readData: function PdfDataListener_readData() {
var result = this.buffer;
this.buffer = null;
return result;
},
finish: function PdfDataListener_finish() {
this.isDataReady = true;
if (this.oncompleteCallback) {
this.oncompleteCallback(this.getData());
this.oncompleteCallback(this.readData());
}
},
error: function PdfDataListener_error(errorCode) {
@ -211,7 +210,7 @@ PdfDataListener.prototype = {
set oncomplete(value) {
this.oncompleteCallback = value;
if (this.isDataReady) {
value(this.getData());
value(this.readData());
}
if (this.errorCode) {
value(null, this.errorCode);
@ -234,7 +233,7 @@ function ChromeActions(domWindow, contentDispositionFilename) {
ChromeActions.prototype = {
isInPrivateBrowsing: function() {
return PrivateBrowsingUtils.isWindowPrivate(this.domWindow);
return PrivateBrowsingUtils.isContentWindowPrivate(this.domWindow);
},
download: function(data, sendResponse) {
var self = this;
@ -329,9 +328,6 @@ ChromeActions.prototype = {
return 'null';
}
},
pdfBugEnabled: function() {
return getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false);
},
supportsIntegratedFind: function() {
// Integrated find is only supported when we're not in a frame
if (this.domWindow.frameElement !== null) {
@ -511,11 +507,13 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
*/
function RangedChromeActions(
domWindow, contentDispositionFilename, originalRequest,
dataListener) {
rangeEnabled, streamingEnabled, dataListener) {
ChromeActions.call(this, domWindow, contentDispositionFilename);
this.dataListener = dataListener;
this.originalRequest = originalRequest;
this.rangeEnabled = rangeEnabled;
this.streamingEnabled = streamingEnabled;
this.pdfUrl = originalRequest.URI.spec;
this.contentLength = originalRequest.contentLength;
@ -534,7 +532,9 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
this.headers[aHeader] = aValue;
}
};
originalRequest.visitRequestHeaders(httpHeaderVisitor);
if (originalRequest.visitRequestHeaders) {
originalRequest.visitRequestHeaders(httpHeaderVisitor);
}
var self = this;
var xhr_onreadystatechange = function xhr_onreadystatechange() {
@ -573,20 +573,46 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
proto.constructor = RangedChromeActions;
proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() {
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
this.originalRequest = null;
var self = this;
var data;
if (!this.streamingEnabled) {
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
this.originalRequest = null;
data = this.dataListener.readData();
this.dataListener = null;
} else {
data = this.dataListener.readData();
this.dataListener.onprogress = function (loaded, total) {
self.domWindow.postMessage({
pdfjsLoadAction: 'progressiveRead',
loaded: loaded,
total: total,
chunk: self.dataListener.readData()
}, '*');
};
this.dataListener.oncomplete = function () {
delete self.dataListener;
};
}
this.domWindow.postMessage({
pdfjsLoadAction: 'supportsRangedLoading',
rangeEnabled: this.rangeEnabled,
streamingEnabled: this.streamingEnabled,
pdfUrl: this.pdfUrl,
length: this.contentLength,
data: this.dataListener.getData()
data: data
}, '*');
this.dataListener = null;
return true;
};
proto.requestDataRange = function RangedChromeActions_requestDataRange(args) {
if (!this.rangeEnabled) {
return;
}
var begin = args.begin;
var end = args.end;
var domWindow = this.domWindow;
@ -828,6 +854,7 @@ PdfStreamConverter.prototype = {
} catch (e) {}
var rangeRequest = false;
var streamRequest = false;
if (isHttpRequest) {
var contentEncoding = 'identity';
try {
@ -840,10 +867,18 @@ PdfStreamConverter.prototype = {
} catch (e) {}
var hash = aRequest.URI.ref;
var isPDFBugEnabled = getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false);
rangeRequest = contentEncoding === 'identity' &&
acceptRanges === 'bytes' &&
aRequest.contentLength >= 0 &&
hash.indexOf('disableRange=true') < 0;
!getBoolPref(PREF_PREFIX + '.disableRange', false) &&
(!isPDFBugEnabled ||
hash.toLowerCase().indexOf('disablerange=true') < 0);
streamRequest = contentEncoding === 'identity' &&
aRequest.contentLength >= 0 &&
!getBoolPref(PREF_PREFIX + '.disableStream', false) &&
(!isPDFBugEnabled ||
hash.toLowerCase().indexOf('disablestream=true') < 0);
}
aRequest.QueryInterface(Ci.nsIChannel);
@ -897,12 +932,13 @@ PdfStreamConverter.prototype = {
// may have changed during a redirect.
var domWindow = getDOMWindow(channel);
var actions;
if (rangeRequest) {
if (rangeRequest || streamRequest) {
actions = new RangedChromeActions(
domWindow, contentDispositionFilename, aRequest, dataListener);
domWindow, contentDispositionFilename, aRequest,
rangeRequest, streamRequest, dataListener);
} else {
actions = new StandardChromeActions(
domWindow, contentDispositionFilename, dataListener);
domWindow, contentDispositionFilename, dataListener);
}
var requestListener = new RequestListener(actions);
domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {

View File

@ -43,7 +43,9 @@ var DEFAULT_PREFERENCES = {
sidebarViewOnLoad: 0,
enableHandToolOnLoad: false,
enableWebGL: false,
pdfBugEnabled: false,
disableRange: false,
disableStream: false,
disableAutoFetch: false,
disableFontFace: false,
disableTextLayer: false,
@ -285,7 +287,8 @@ let PdfjsChromeUtils = {
*/
function PdfjsFindbarWrapper(aBrowser) {
let tabbrowser = aBrowser.getTabBrowser();
let tab = tabbrowser.getTabForBrowser(aBrowser);
let tab;
tab = tabbrowser.getTabForBrowser(aBrowser);
this._findbar = tabbrowser.getFindBar(tab);
};

View File

@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '1.0.801';
PDFJS.build = 'e77e5c4';
PDFJS.version = '1.0.907';
PDFJS.build = 'e9072ac';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -1362,6 +1362,14 @@ PDFJS.workerSrc = (PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc);
PDFJS.disableRange = (PDFJS.disableRange === undefined ?
false : PDFJS.disableRange);
/**
* Disable streaming of PDF file data. By default PDF.js attempts to load PDF
* in chunks. This default behavior can be disabled.
* @var {boolean}
*/
PDFJS.disableStream = (PDFJS.disableStream === undefined ?
false : PDFJS.disableStream);
/**
* Disable pre-fetching of PDF file data. When range requests are enabled PDF.js
* will automatically keep fetching more data even if it isn't needed to display
@ -1560,10 +1568,20 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
/**
* @return {Promise} A promise that is resolved with a lookup table for
* mapping named destinations to reference numbers.
*
* This can be slow for large documents: use getDestination instead
*/
getDestinations: function PDFDocumentProxy_getDestinations() {
return this.transport.getDestinations();
},
/**
* @param {string} id The named destination to get.
* @return {Promise} A promise that is resolved with all information
* of the given named destination.
*/
getDestination: function PDFDocumentProxy_getDestination(id) {
return this.transport.getDestination(id);
},
/**
* @return {Promise} A promise that is resolved with a lookup table for
* mapping named attachments to their content.
@ -2117,6 +2135,12 @@ var WorkerTransport = (function WorkerTransportClosure() {
});
});
pdfDataRangeTransport.addProgressiveReadListener(function(chunk) {
messageHandler.send('OnDataRange', {
chunk: chunk
});
});
messageHandler.on('RequestDataRange',
function transportDataRange(data) {
pdfDataRangeTransport.requestDataRange(data.begin, data.end);
@ -2177,6 +2201,12 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.downloadInfoCapability.resolve(data);
}, this);
messageHandler.on('PDFManagerReady', function transportPage(data) {
if (this.pdfDataRangeTransport) {
this.pdfDataRangeTransport.transportReady();
}
}, this);
messageHandler.on('StartRenderPage', function transportRender(data) {
var page = this.pageCache[data.pageIndex];
@ -2208,7 +2238,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.commonObjs.resolve(id, error);
break;
} else {
font = new FontFace(exportedData);
font = new FontFaceObject(exportedData);
}
FontLoader.bind(
@ -2321,6 +2351,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
fetchDocument: function WorkerTransport_fetchDocument(source) {
source.disableAutoFetch = PDFJS.disableAutoFetch;
source.disableStream = PDFJS.disableStream;
source.chunkedViewerLoading = !!this.pdfDataRangeTransport;
this.messageHandler.send('GetDocRequest', {
source: source,
@ -2372,6 +2403,10 @@ var WorkerTransport = (function WorkerTransportClosure() {
return this.messageHandler.sendWithPromise('GetDestinations', null);
},
getDestination: function WorkerTransport_getDestination(id) {
return this.messageHandler.sendWithPromise('GetDestination', { id: id } );
},
getAttachments: function WorkerTransport_getAttachments() {
return this.messageHandler.sendWithPromise('GetAttachments', null);
},
@ -5731,8 +5766,8 @@ var FontLoader = {
}
};
var FontFace = (function FontFaceClosure() {
function FontFace(name, file, properties) {
var FontFaceObject = (function FontFaceObjectClosure() {
function FontFaceObject(name, file, properties) {
this.compiledGlyphs = {};
if (arguments.length === 1) {
// importing translated data
@ -5743,8 +5778,9 @@ var FontFace = (function FontFaceClosure() {
return;
}
}
FontFace.prototype = {
bindDOM: function FontFace_bindDOM() {
FontFaceObject.prototype = {
bindDOM: function FontFaceObject_bindDOM() {
if (!this.data) {
return null;
}
@ -5771,7 +5807,7 @@ var FontFace = (function FontFaceClosure() {
return rule;
},
getPathGenerator: function (objs, character) {
getPathGenerator: function FontLoader_getPathGenerator(objs, character) {
if (!(character in this.compiledGlyphs)) {
var js = objs.get(this.loadedName + '_path_' + character);
/*jshint -W054 */
@ -5780,7 +5816,7 @@ var FontFace = (function FontFaceClosure() {
return this.compiledGlyphs[character];
}
};
return FontFace;
return FontFaceObject;
})();

View File

@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '1.0.801';
PDFJS.build = 'e77e5c4';
PDFJS.version = '1.0.907';
PDFJS.build = 'e9072ac';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -1309,7 +1309,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
this.numChunksLoaded = 0;
this.numChunks = Math.ceil(length / chunkSize);
this.manager = manager;
this.initialDataLength = 0;
this.progressiveDataLength = 0;
this.lastSuccessfulEnsureByteChunk = -1; // a single-entry cache
}
@ -1320,7 +1320,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
getMissingChunks: function ChunkedStream_getMissingChunks() {
var chunks = [];
for (var chunk = 0, n = this.numChunks; chunk < n; ++chunk) {
if (!(chunk in this.loadedChunks)) {
if (!this.loadedChunks[chunk]) {
chunks.push(chunk);
}
}
@ -1352,21 +1352,29 @@ var ChunkedStream = (function ChunkedStreamClosure() {
var curChunk;
for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
if (!(curChunk in this.loadedChunks)) {
if (!this.loadedChunks[curChunk]) {
this.loadedChunks[curChunk] = true;
++this.numChunksLoaded;
}
}
},
onReceiveInitialData: function ChunkedStream_onReceiveInitialData(data) {
this.bytes.set(data);
this.initialDataLength = data.length;
var endChunk = (this.end === data.length ?
this.numChunks : Math.floor(data.length / this.chunkSize));
for (var i = 0; i < endChunk; i++) {
this.loadedChunks[i] = true;
++this.numChunksLoaded;
onReceiveProgressiveData:
function ChunkedStream_onReceiveProgressiveData(data) {
var position = this.progressiveDataLength;
var beginChunk = Math.floor(position / this.chunkSize);
this.bytes.set(new Uint8Array(data), position);
position += data.byteLength;
this.progressiveDataLength = position;
var endChunk = position >= this.end ? this.numChunks :
Math.floor(position / this.chunkSize);
var curChunk;
for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
if (!this.loadedChunks[curChunk]) {
this.loadedChunks[curChunk] = true;
++this.numChunksLoaded;
}
}
},
@ -1376,7 +1384,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
return;
}
if (!(chunk in this.loadedChunks)) {
if (!this.loadedChunks[chunk]) {
throw new MissingDataException(pos, pos + 1);
}
this.lastSuccessfulEnsureByteChunk = chunk;
@ -1387,7 +1395,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
return;
}
if (end <= this.initialDataLength) {
if (end <= this.progressiveDataLength) {
return;
}
@ -1395,7 +1403,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
var beginChunk = Math.floor(begin / chunkSize);
var endChunk = Math.floor((end - 1) / chunkSize) + 1;
for (var chunk = beginChunk; chunk < endChunk; ++chunk) {
if (!(chunk in this.loadedChunks)) {
if (!this.loadedChunks[chunk]) {
throw new MissingDataException(begin, end);
}
}
@ -1404,13 +1412,13 @@ var ChunkedStream = (function ChunkedStreamClosure() {
nextEmptyChunk: function ChunkedStream_nextEmptyChunk(beginChunk) {
var chunk, n;
for (chunk = beginChunk, n = this.numChunks; chunk < n; ++chunk) {
if (!(chunk in this.loadedChunks)) {
if (!this.loadedChunks[chunk]) {
return chunk;
}
}
// Wrap around to beginning
for (chunk = 0; chunk < beginChunk; ++chunk) {
if (!(chunk in this.loadedChunks)) {
if (!this.loadedChunks[chunk]) {
return chunk;
}
}
@ -1418,7 +1426,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
},
hasChunk: function ChunkedStream_hasChunk(chunk) {
return chunk in this.loadedChunks;
return !!this.loadedChunks[chunk];
},
get length() {
@ -1517,7 +1525,7 @@ var ChunkedStream = (function ChunkedStreamClosure() {
var endChunk = Math.floor((this.end - 1) / chunkSize) + 1;
var missingChunks = [];
for (var chunk = beginChunk; chunk < endChunk; ++chunk) {
if (!(chunk in this.loadedChunks)) {
if (!this.loadedChunks[chunk]) {
missingChunks.push(chunk);
}
}
@ -1575,28 +1583,16 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
this.chunksNeededByRequest = {};
this.requestsByChunk = {};
this.callbacksByRequest = {};
this.progressiveDataLength = 0;
this._loadedStreamCapability = createPromiseCapability();
if (args.initialData) {
this.setInitialData(args.initialData);
this.onReceiveData({chunk: args.initialData});
}
}
ChunkedStreamManager.prototype = {
setInitialData: function ChunkedStreamManager_setInitialData(data) {
this.stream.onReceiveInitialData(data);
if (this.stream.allChunksLoaded()) {
this._loadedStreamCapability.resolve(this.stream);
} else if (this.msgHandler) {
this.msgHandler.send('DocProgress', {
loaded: data.length,
total: this.length
});
}
},
onLoadedStream: function ChunkedStreamManager_getLoadedStream() {
return this._loadedStreamCapability.promise;
},
@ -1734,13 +1730,21 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() {
onReceiveData: function ChunkedStreamManager_onReceiveData(args) {
var chunk = args.chunk;
var begin = args.begin;
var isProgressive = args.begin === undefined;
var begin = isProgressive ? this.progressiveDataLength : args.begin;
var end = begin + chunk.byteLength;
var beginChunk = this.getBeginChunk(begin);
var endChunk = this.getEndChunk(end);
var beginChunk = Math.floor(begin / this.chunkSize);
var endChunk = end < this.length ? Math.floor(end / this.chunkSize) :
Math.ceil(end / this.chunkSize);
if (isProgressive) {
this.stream.onReceiveProgressiveData(chunk);
this.progressiveDataLength = end;
} else {
this.stream.onReceiveData(begin, chunk);
}
this.stream.onReceiveData(begin, chunk);
if (this.stream.allChunksLoaded()) {
this._loadedStreamCapability.resolve(this.stream);
}
@ -1877,6 +1881,10 @@ var BasePdfManager = (function BasePdfManagerClosure() {
return new NotImplementedException();
},
sendProgressiveData: function BasePdfManager_sendProgressiveData(chunk) {
return new NotImplementedException();
},
updatePassword: function BasePdfManager_updatePassword(password) {
this.pdfDocument.xref.password = this.password = password;
if (this._passwordChangedCapability) {
@ -2013,6 +2021,11 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() {
this.streamManager.requestAllChunks();
};
NetworkPdfManager.prototype.sendProgressiveData =
function NetworkPdfManager_sendProgressiveData(chunk) {
this.streamManager.onReceiveData({ chunk: chunk });
};
NetworkPdfManager.prototype.onLoadedStream =
function NetworkPdfManager_getLoadedStream() {
return this.streamManager.onLoadedStream();
@ -2959,6 +2972,38 @@ var Catalog = (function CatalogClosure() {
}
return shadow(this, 'destinations', dests);
},
getDestination: function Catalog_getDestination(destinationId) {
function fetchDestination(dest) {
return isDict(dest) ? dest.get('D') : dest;
}
var xref = this.xref;
var dest, nameTreeRef, nameDictionaryRef;
var obj = this.catDict.get('Names');
if (obj && obj.has('Dests')) {
nameTreeRef = obj.getRaw('Dests');
} else if (this.catDict.has('Dests')) {
nameDictionaryRef = this.catDict.get('Dests');
}
if (nameDictionaryRef) {
// reading simple destination dictionary
obj = nameDictionaryRef;
obj.forEach(function catalogForEach(key, value) {
if (!value) {
return;
}
if (key === destinationId) {
dest = fetchDestination(value);
}
});
}
if (nameTreeRef) {
var nameTree = new NameTree(nameTreeRef, xref);
dest = fetchDestination(nameTree.get(destinationId));
}
return dest;
},
get attachments() {
var xref = this.xref;
var attachments = null, nameTreeRef;
@ -3860,6 +3905,76 @@ var NameTree = (function NameTreeClosure() {
}
}
return dict;
},
get: function NameTree_get(destinationId) {
if (!this.root) {
return null;
}
var xref = this.xref;
var kidsOrNames = xref.fetchIfRef(this.root);
var loopCount = 0;
var MAX_NAMES_LEVELS = 10;
var l, r, m;
// Perform a binary search to quickly find the entry that
// contains the named destination we are looking for.
while (kidsOrNames.has('Kids')) {
loopCount++;
if (loopCount > MAX_NAMES_LEVELS) {
warn('Search depth limit for named destionations has been reached.');
return null;
}
var kids = kidsOrNames.get('Kids');
if (!isArray(kids)) {
return null;
}
l = 0;
r = kids.length - 1;
while (l <= r) {
m = (l + r) >> 1;
var kid = xref.fetchIfRef(kids[m]);
var limits = kid.get('Limits');
if (destinationId < limits[0]) {
r = m - 1;
} else if (destinationId > limits[1]) {
l = m + 1;
} else {
kidsOrNames = xref.fetchIfRef(kids[m]);
break;
}
}
if (l > r) {
return null;
}
}
// If we get here, then we have found the right entry. Now
// go through the named destinations in the Named dictionary
// until we find the exact destination we're looking for.
var names = kidsOrNames.get('Names');
if (isArray(names)) {
// Perform a binary search to reduce the lookup time.
l = 0;
r = names.length - 2;
while (l <= r) {
// Check only even indices (0, 2, 4, ...) because the
// odd indices contain the actual D array.
m = (l + r) & ~1;
if (destinationId < names[m]) {
r = m - 2;
} else if (destinationId > names[m]) {
l = m + 2;
} else {
return xref.fetchIfRef(names[m + 1]);
}
}
}
return null;
}
};
return NameTree;
@ -15857,6 +15972,12 @@ var Font = (function FontClosure() {
for (var code in GlyphMapForStandardFonts) {
map[+code] = GlyphMapForStandardFonts[code];
}
var isIdentityUnicode = this.toUnicode instanceof IdentityToUnicodeMap;
if (!isIdentityUnicode) {
this.toUnicode.forEach(function(charCode, unicodeCharCode) {
map[+charCode] = unicodeCharCode;
});
}
this.toFontChar = map;
this.toUnicode = new ToUnicodeMap(map);
} else if (/Symbol/i.test(fontName)) {
@ -15868,6 +15989,13 @@ var Font = (function FontClosure() {
}
this.toFontChar[charCode] = fontChar;
}
for (charCode in properties.differences) {
fontChar = GlyphsUnicode[properties.differences[charCode]];
if (!fontChar) {
continue;
}
this.toFontChar[charCode] = fontChar;
}
} else if (/Dingbats/i.test(fontName)) {
var dingbats = Encodings.ZapfDingbatsEncoding;
for (charCode in dingbats) {
@ -15928,6 +16056,9 @@ var Font = (function FontClosure() {
var data;
switch (type) {
case 'MMType1':
info('MMType1 font (' + name + '), falling back to Type1.');
/* falls through */
case 'Type1':
case 'CIDFontType0':
this.mimetype = 'font/opentype';
@ -31206,7 +31337,7 @@ var JpegStream = (function JpegStreamClosure() {
var jpegImage = new JpegImage();
// checking if values needs to be transformed before conversion
if (this.dict && isArray(this.dict.get('Decode'))) {
if (this.forceRGB && this.dict && isArray(this.dict.get('Decode'))) {
var decodeArr = this.dict.get('Decode');
var bitsPerComponent = this.dict.get('BitsPerComponent') || 8;
var decodeArrLength = decodeArr.length;
@ -32840,6 +32971,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
httpHeaders: source.httpHeaders,
withCredentials: source.withCredentials
});
var cachedChunks = [];
var fullRequestXhrId = networkManager.requestFull({
onHeadersReceived: function onHeadersReceived() {
if (disableRange) {
@ -32870,11 +33002,18 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
return;
}
// NOTE: by cancelling the full request, and then issuing range
// requests, there will be an issue for sites where you can only
// 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);
if (networkManager.isStreamingRequest(fullRequestXhrId)) {
// We can continue fetching when progressive loading is enabled,
// and we don't need the autoFetch feature.
source.disableAutoFetch = true;
} else {
// NOTE: by cancelling the full request, and then issuing range
// requests, there will be an issue for sites where you can only
// 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);
}
try {
pdfManager = new NetworkPdfManager(source, handler);
@ -32884,10 +33023,44 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
}
},
onProgressiveData: source.disableStream ? null :
function onProgressiveData(chunk) {
if (!pdfManager) {
cachedChunks.push(chunk);
return;
}
pdfManager.sendProgressiveData(chunk);
},
onDone: function onDone(args) {
if (pdfManager) {
return; // already processed
}
var pdfFile;
if (args === null) {
// TODO add some streaming manager, e.g. for unknown length files.
// The data was returned in the onProgressiveData, combining...
var pdfFileLength = 0, pos = 0;
cachedChunks.forEach(function (chunk) {
pdfFileLength += chunk.byteLength;
});
if (source.length && pdfFileLength !== source.length) {
warn('reported HTTP length is different from actual');
}
var pdfFileArray = new Uint8Array(pdfFileLength);
cachedChunks.forEach(function (chunk) {
pdfFileArray.set(new Uint8Array(chunk), pos);
pos += chunk.byteLength;
});
pdfFile = pdfFileArray.buffer;
} else {
pdfFile = args.chunk;
}
// the data is array, instantiating directly from it
try {
pdfManager = new LocalPdfManager(args.chunk, source.password);
pdfManager = new LocalPdfManager(pdfFile, source.password);
pdfManagerCapability.resolve();
} catch (ex) {
pdfManagerCapability.reject(ex);
@ -32982,6 +33155,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
PDFJS.cMapPacked = data.cMapPacked === true;
getPdfManager(data).then(function () {
handler.send('PDFManagerReady', null);
pdfManager.onLoadedStream().then(function(stream) {
handler.send('DataLoaded', { length: stream.bytes.byteLength });
});
@ -33036,6 +33210,12 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
}
);
handler.on('GetDestination',
function wphSetupGetDestination(data) {
return pdfManager.ensureCatalog('getDestination', [ data.id ]);
}
);
handler.on('GetAttachments',
function wphSetupGetAttachments(data) {
return pdfManager.ensureCatalog('attachments');

View File

@ -62,11 +62,11 @@ var NetworkManager = (function NetworkManagerClosure() {
return data;
}
var length = data.length;
var buffer = new Uint8Array(length);
var array = new Uint8Array(length);
for (var i = 0; i < length; i++) {
buffer[i] = data.charCodeAt(i) & 0xFF;
array[i] = data.charCodeAt(i) & 0xFF;
}
return buffer;
return array.buffer;
}
NetworkManager.prototype = {
@ -81,11 +81,11 @@ var NetworkManager = (function NetworkManagerClosure() {
return this.request(args);
},
requestFull: function NetworkManager_requestRange(listeners) {
requestFull: function NetworkManager_requestFull(listeners) {
return this.request(listeners);
},
request: function NetworkManager_requestRange(args) {
request: function NetworkManager_request(args) {
var xhr = this.getXhr();
var xhrId = this.currXhrId++;
var pendingRequest = this.pendingRequests[xhrId] = {
@ -109,27 +109,54 @@ var NetworkManager = (function NetworkManagerClosure() {
pendingRequest.expectedStatus = 200;
}
xhr.responseType = 'arraybuffer';
if (args.onProgress) {
xhr.onprogress = args.onProgress;
if (args.onProgressiveData) {
xhr.responseType = 'moz-chunked-arraybuffer';
if (xhr.responseType === 'moz-chunked-arraybuffer') {
pendingRequest.onProgressiveData = args.onProgressiveData;
pendingRequest.mozChunked = true;
} else {
xhr.responseType = 'arraybuffer';
}
} else {
xhr.responseType = 'arraybuffer';
}
if (args.onError) {
xhr.onerror = function(evt) {
args.onError(xhr.status);
};
}
xhr.onreadystatechange = this.onStateChange.bind(this, xhrId);
xhr.onprogress = this.onProgress.bind(this, xhrId);
pendingRequest.onHeadersReceived = args.onHeadersReceived;
pendingRequest.onDone = args.onDone;
pendingRequest.onError = args.onError;
pendingRequest.onProgress = args.onProgress;
xhr.send(null);
return xhrId;
},
onProgress: function NetworkManager_onProgress(xhrId, evt) {
var pendingRequest = this.pendingRequests[xhrId];
if (!pendingRequest) {
// Maybe abortRequest was called...
return;
}
if (pendingRequest.mozChunked) {
var chunk = getArrayBuffer(pendingRequest.xhr);
pendingRequest.onProgressiveData(chunk);
}
var onProgress = pendingRequest.onProgress;
if (onProgress) {
onProgress(evt);
}
},
onStateChange: function NetworkManager_onStateChange(xhrId, evt) {
var pendingRequest = this.pendingRequests[xhrId];
if (!pendingRequest) {
@ -190,6 +217,8 @@ var NetworkManager = (function NetworkManagerClosure() {
begin: begin,
chunk: chunk
});
} else if (pendingRequest.onProgressiveData) {
pendingRequest.onDone(null);
} else {
pendingRequest.onDone({
begin: 0,
@ -209,6 +238,10 @@ var NetworkManager = (function NetworkManagerClosure() {
return this.pendingRequests[xhrId].xhr;
},
isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) {
return !!(this.pendingRequests[xhrId].onProgressiveData);
},
isPendingRequest: function NetworkManager_isPendingRequest(xhrId) {
return xhrId in this.pendingRequests;
},

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
/* jshint esnext:true */
/* globals Components, PdfjsContentUtils, PdfJs */
/* globals Components, PdfjsContentUtils, PdfJs, Services */
'use strict';

View File

@ -112,13 +112,20 @@ var FontInspector = (function FontInspectorClosure() {
return moreInfo;
}
var moreInfo = properties(fontObj, ['name', 'type']);
var m = /url\(['"]?([^\)"']+)/.exec(url);
var fontName = fontObj.loadedName;
var font = document.createElement('div');
var name = document.createElement('span');
name.textContent = fontName;
var download = document.createElement('a');
download.href = m[1];
if (url) {
url = /url\(['"]?([^\)"']+)/.exec(url);
download.href = url[1];
} else if (fontObj.data) {
url = URL.createObjectURL(new Blob([fontObj.data], {
type: fontObj.mimeType
}));
}
download.href = url;
download.textContent = 'Download';
var logIt = document.createElement('a');
logIt.href = '';
@ -211,6 +218,7 @@ var StepperManager = (function StepperManagerClosure() {
},
selectStepper: function selectStepper(pageIndex, selectPanel) {
var i;
pageIndex = pageIndex | 0;
if (selectPanel) {
this.manager.selectPanel(this);
}
@ -419,7 +427,7 @@ var Stepper = (function StepperClosure() {
var allRows = this.panel.getElementsByClassName('line');
for (var x = 0, xx = allRows.length; x < xx; ++x) {
var row = allRows[x];
if (parseInt(row.dataset.idx, 10) === idx) {
if ((row.dataset.idx | 0) === idx) {
row.style.backgroundColor = 'rgb(251,250,207)';
row.scrollIntoView();
} else {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,4 +1,4 @@
/* Copyright 2012 Mozilla Foundation
/* Copyright 2014 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,6 +13,141 @@
* limitations under the License.
*/
.textLayer {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.textLayer > div {
color: transparent;
position: absolute;
white-space: pre;
cursor: text;
-moz-transform-origin: 0% 0%;
transform-origin: 0% 0%;
}
.textLayer .highlight {
margin: -1px;
padding: 1px;
background-color: rgb(180, 0, 170);
border-radius: 4px;
}
.textLayer .highlight.begin {
border-radius: 4px 0px 0px 4px;
}
.textLayer .highlight.end {
border-radius: 0px 4px 4px 0px;
}
.textLayer .highlight.middle {
border-radius: 0px;
}
.textLayer .highlight.selected {
background-color: rgb(0, 100, 0);
}
.pdfViewer .canvasWrapper {
overflow: hidden;
}
.pdfViewer .page {
direction: ltr;
width: 816px;
height: 1056px;
margin: 1px auto -8px auto;
position: relative;
overflow: visible;
border: 9px solid transparent;
background-clip: content-box;
border-image: url(images/shadow.png) 9 9 repeat;
background-color: white;
}
.pdfViewer .page canvas {
margin: 0;
display: block;
}
.pdfViewer .page .loadingIcon {
position: absolute;
display: block;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: url('images/loading-icon.gif') center no-repeat;
}
.pdfViewer .page .annotLink > a:hover {
opacity: 0.2;
background: #ff0;
box-shadow: 0px 2px 10px #ff0;
}
:-moz-full-screen .pdfViewer .page {
margin-bottom: 100%;
border: 0;
}
:fullscreen .pdfViewer .page {
margin-bottom: 100%;
border: 0;
}
.pdfViewer .page .annotationHighlight {
position: absolute;
border: 2px #FFFF99 solid;
}
.pdfViewer .page .annotText > img {
position: absolute;
cursor: pointer;
}
.pdfViewer .page .annotTextContentWrapper {
position: absolute;
width: 20em;
}
.pdfViewer .page .annotTextContent {
z-index: 200;
float: left;
max-width: 20em;
background-color: #FFFF99;
box-shadow: 0px 2px 5px #333;
border-radius: 2px;
padding: 0.6em;
cursor: pointer;
}
.pdfViewer .page .annotTextContent > h1 {
font-size: 1em;
border-bottom: 1px solid #000000;
padding-bottom: 0.2em;
}
.pdfViewer .page .annotTextContent > p {
padding-top: 0.2em;
}
.pdfViewer .page .annotLink > a {
position: absolute;
font-size: 1em;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
* {
padding: 0;
margin: 0;
@ -65,16 +200,6 @@ select {
cursor: none;
}
:-moz-full-screen .page {
margin-bottom: 100%;
border: 0;
}
:fullscreen .page {
margin-bottom: 100%;
border: 0;
}
:-moz-full-screen a:not(.internalLink) {
display: none;
}
@ -984,6 +1109,12 @@ html[dir='rtl'] .verticalToolbarSeparator {
width: 40px;
}
.toolbarField.pageNumber.visiblePageIsLoading {
background-image: url(images/loading-small.png);
background-repeat: no-repeat;
background-position: 1px;
}
.toolbarField:hover {
background-color: hsla(0,0%,100%,.11);
border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.43) hsla(0,0%,0%,.45);
@ -1167,135 +1298,17 @@ html[dir='rtl'] .attachmentsItem > button {
cursor: default;
}
.canvasWrapper {
overflow: hidden;
}
canvas {
margin: 0;
display: block;
}
.page {
direction: ltr;
width: 816px;
height: 1056px;
margin: 1px auto -8px auto;
position: relative;
overflow: visible;
border: 9px solid transparent;
background-clip: content-box;
border-image: url(images/shadow.png) 9 9 repeat;
background-color: white;
}
.annotLink > a:hover {
opacity: 0.2;
background: #ff0;
box-shadow: 0px 2px 10px #ff0;
}
.loadingIcon {
position: absolute;
display: block;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: url('images/loading-icon.gif') center no-repeat;
}
.textLayer {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.textLayer > div {
color: transparent;
position: absolute;
white-space: pre;
cursor: text;
-moz-transform-origin: 0% 0%;
transform-origin: 0% 0%;
}
.textLayer .highlight {
margin: -1px;
padding: 1px;
background-color: rgba(180, 0, 170, 0.2);
border-radius: 4px;
}
.textLayer .highlight.begin {
border-radius: 4px 0px 0px 4px;
}
.textLayer .highlight.end {
border-radius: 0px 4px 4px 0px;
}
.textLayer .highlight.middle {
border-radius: 0px;
}
.textLayer .highlight.selected {
background-color: rgba(0, 100, 0, 0.2);
}
/* TODO: file FF bug to support ::-moz-selection:window-inactive
so we can override the opaque grey background when the window is inactive;
see https://bugzilla.mozilla.org/show_bug.cgi?id=706209 */
::selection { background:rgba(0,0,255,0.3); }
::-moz-selection { background:rgba(0,0,255,0.3); }
::selection { background: rgba(0,0,255,0.3); }
::-moz-selection { background: rgba(0,0,255,0.3); }
.annotationHighlight {
position: absolute;
border: 2px #FFFF99 solid;
}
.annotText > img {
position: absolute;
cursor: pointer;
}
.annotTextContentWrapper {
position: absolute;
width: 20em;
}
.annotTextContent {
z-index: 200;
float: left;
max-width: 20em;
background-color: #FFFF99;
box-shadow: 0px 2px 5px #333;
border-radius: 2px;
padding: 0.6em;
cursor: pointer;
}
.annotTextContent > h1 {
font-size: 1em;
border-bottom: 1px solid #000000;
padding-bottom: 0.2em;
}
.annotTextContent > p {
padding-top: 0.2em;
}
.annotLink > a {
position: absolute;
font-size: 1em;
top: 0;
left: 0;
width: 100%;
height: 100%;
.textLayer ::selection { background: rgb(0,0,255); }
.textLayer ::-moz-selection { background: rgb(0,0,255); }
.textLayer {
opacity: 0.2;
}
#errorWrapper {
@ -1477,11 +1490,9 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
.debuggerShowText {
background: none repeat scroll 0 0 yellow;
color: blue;
opacity: 0.3;
}
.debuggerHideText:hover {
background: none repeat scroll 0 0 yellow;
opacity: 0.3;
}
#PDFBug .stats {
font-family: courier;
@ -1561,6 +1572,12 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
left: 186px;
}
.toolbarField.pageNumber.visiblePageIsLoading,
#findInput[data-status="pending"] {
background-image: url(images/loading-small@2x.png);
background-size: 16px 17px;
}
.dropdownToolbarButton {
background: url(images/toolbarButton-menuArrows@2x.png) no-repeat;
background-size: 7px 16px;
@ -1710,6 +1727,8 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
display: none;
border: none;
box-shadow: none;
background-clip: content-box;
background-color: white;
}
.page[data-loaded] {
@ -1731,6 +1750,7 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
position: relative;
top: 0;
left: 0;
display: block;
}
}

View File

@ -245,7 +245,7 @@ http://sourceforge.net/adobe/cmap/wiki/License/
</menu>
<div id="viewerContainer" tabindex="0">
<div id="viewer"></div>
<div id="viewer" class="pdfViewer"></div>
</div>
<div id="errorWrapper" hidden='true'>

File diff suppressed because it is too large Load Diff