Hack to support automatic printing from pdf javascript.
This commit is contained in:
parent
e20a9846ca
commit
5c43565404
10
src/api.js
10
src/api.js
@ -119,6 +119,16 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
|
||||
promise.resolve(destinations);
|
||||
return promise;
|
||||
},
|
||||
/**
|
||||
* @return {Promise} A promise that is resolved with an array of all the
|
||||
* JavaScript strings in the name tree.
|
||||
*/
|
||||
getJavaScript: function PDFDocumentProxy_getDestinations() {
|
||||
var promise = new PDFJS.Promise();
|
||||
var js = this.pdfInfo.javaScript;
|
||||
promise.resolve(js);
|
||||
return promise;
|
||||
},
|
||||
/**
|
||||
* @return {Promise} A promise that is resolved with an {array} that is a
|
||||
* tree outline (if it has one) of the PDF. The tree is in the format of:
|
||||
|
112
src/obj.js
112
src/obj.js
@ -17,7 +17,7 @@
|
||||
/* globals assertWellFormed, bytesToString, CipherTransformFactory, error, info,
|
||||
InvalidPDFException, isArray, isCmd, isDict, isInt, isName, isRef,
|
||||
isStream, JpegStream, Lexer, log, Page, Parser, Promise, shadow,
|
||||
stringToPDFString, stringToUTF8String, warn */
|
||||
stringToPDFString, stringToUTF8String, warn, isString */
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -292,34 +292,51 @@ var Catalog = (function CatalogClosure() {
|
||||
});
|
||||
}
|
||||
if (nameTreeRef) {
|
||||
// reading name tree
|
||||
var processed = new RefSet();
|
||||
processed.put(nameTreeRef);
|
||||
var queue = [nameTreeRef];
|
||||
while (queue.length > 0) {
|
||||
var i, n;
|
||||
obj = xref.fetch(queue.shift());
|
||||
if (obj.has('Kids')) {
|
||||
var kids = obj.get('Kids');
|
||||
for (i = 0, n = kids.length; i < n; i++) {
|
||||
var kid = kids[i];
|
||||
if (processed.has(kid))
|
||||
error('invalid destinations');
|
||||
queue.push(kid);
|
||||
processed.put(kid);
|
||||
}
|
||||
var nameTree = new NameTree(nameTreeRef, xref);
|
||||
var names = nameTree.getAll();
|
||||
for (var name in names) {
|
||||
if (!names.hasOwnProperty(name)) {
|
||||
continue;
|
||||
}
|
||||
var names = obj.get('Names');
|
||||
if (names) {
|
||||
for (i = 0, n = names.length; i < n; i += 2) {
|
||||
dests[names[i]] = fetchDestination(xref.fetchIfRef(names[i + 1]));
|
||||
}
|
||||
}
|
||||
dests[name] = fetchDestination(names[name]);
|
||||
}
|
||||
}
|
||||
return shadow(this, 'destinations', dests);
|
||||
},
|
||||
get javaScript() {
|
||||
var xref = this.xref;
|
||||
var obj = this.catDict.get('Names');
|
||||
|
||||
var javaScript = [];
|
||||
if (obj && obj.has('JavaScript')) {
|
||||
var nameTree = new NameTree(obj.getRaw('JavaScript'), xref);
|
||||
var names = nameTree.getAll();
|
||||
for (var name in names) {
|
||||
if (!names.hasOwnProperty(name)) {
|
||||
continue;
|
||||
}
|
||||
// We don't really use the JavaScript right now so this code is
|
||||
// defensive so we don't cause errors on document load.
|
||||
var jsDict = names[name];
|
||||
if (!isDict(jsDict)) {
|
||||
continue;
|
||||
}
|
||||
var type = jsDict.get('S');
|
||||
if (!isName(type) || type.name !== 'JavaScript') {
|
||||
continue;
|
||||
}
|
||||
var js = jsDict.get('JS');
|
||||
if (!isString(js) && !isStream(js)) {
|
||||
continue;
|
||||
}
|
||||
if (isStream(js)) {
|
||||
js = bytesToString(js.getBytes());
|
||||
}
|
||||
javaScript.push(js);
|
||||
}
|
||||
}
|
||||
return shadow(this, 'javaScript', javaScript);
|
||||
},
|
||||
getPage: function Catalog_getPage(n) {
|
||||
var pageCache = this.pageCache;
|
||||
if (!pageCache) {
|
||||
@ -755,6 +772,55 @@ var XRef = (function XRefClosure() {
|
||||
return XRef;
|
||||
})();
|
||||
|
||||
/**
|
||||
* A NameTree is like a Dict but has some adventagous properties, see the spec
|
||||
* (7.9.6) for more details.
|
||||
* TODO: implement all the Dict functions and make this more efficent.
|
||||
*/
|
||||
var NameTree = (function NameTreeClosure() {
|
||||
function NameTree(root, xref) {
|
||||
this.root = root;
|
||||
this.xref = xref;
|
||||
}
|
||||
|
||||
NameTree.prototype = {
|
||||
getAll: function NameTree_getAll() {
|
||||
var dict = {};
|
||||
if (!this.root) {
|
||||
return dict;
|
||||
}
|
||||
var xref = this.xref;
|
||||
// reading name tree
|
||||
var processed = new RefSet();
|
||||
processed.put(this.root);
|
||||
var queue = [this.root];
|
||||
while (queue.length > 0) {
|
||||
var i, n;
|
||||
var obj = xref.fetch(queue.shift());
|
||||
if (obj.has('Kids')) {
|
||||
var kids = obj.get('Kids');
|
||||
for (i = 0, n = kids.length; i < n; i++) {
|
||||
var kid = kids[i];
|
||||
if (processed.has(kid))
|
||||
error('invalid destinations');
|
||||
queue.push(kid);
|
||||
processed.put(kid);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
var names = obj.get('Names');
|
||||
if (names) {
|
||||
for (i = 0, n = names.length; i < n; i += 2) {
|
||||
dict[names[i]] = xref.fetchIfRef(names[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
};
|
||||
return NameTree;
|
||||
})();
|
||||
|
||||
/**
|
||||
* A PDF document and page is built of many objects. E.g. there are objects
|
||||
* for fonts, images, rendering code and such. These objects might get processed
|
||||
|
@ -152,6 +152,7 @@ var WorkerMessageHandler = {
|
||||
numPages: pdfModel.numPages,
|
||||
fingerprint: pdfModel.getFingerprint(),
|
||||
destinations: pdfModel.catalog.destinations,
|
||||
javaScript: pdfModel.catalog.javaScript,
|
||||
outline: pdfModel.catalog.documentOutline,
|
||||
info: pdfModel.getDocumentInfo(),
|
||||
metadata: pdfModel.catalog.metadata,
|
||||
|
@ -1310,6 +1310,26 @@ var PDFView = {
|
||||
}
|
||||
|
||||
self.pagesRefMap = pagesRefMap;
|
||||
|
||||
// Wait to do this here so all the canvases are setup.
|
||||
if (PDFView.supportsPrinting) {
|
||||
pdfDocument.getJavaScript().then(function(javaScript) {
|
||||
if (javaScript.length) {
|
||||
PDFView.fallback();
|
||||
}
|
||||
// Hack to support auto printing.
|
||||
var regex = /\bprint\s*\(/g;
|
||||
for (var i = 0, ii = javaScript.length; i < ii; i++) {
|
||||
var js = javaScript[i];
|
||||
if (js && regex.test(js)) {
|
||||
setTimeout(function() {
|
||||
window.print();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var destinationsPromise = pdfDocument.getDestinations();
|
||||
|
Loading…
Reference in New Issue
Block a user