Merge pull request #10738 from Snuffleupagus/ViewerPreferences-api

[api-minor] Add support for ViewerPreferences in the API (issue 10736)
This commit is contained in:
Tim van der Meij 2019-04-20 18:39:32 +02:00 committed by GitHub
commit 762c58e0fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 176 additions and 7 deletions

View File

@ -14,9 +14,10 @@
*/
import {
bytesToString, createPromiseCapability, createValidAbsoluteUrl, FormatError,
info, InvalidPDFException, isBool, isNum, isString, PermissionFlag, shadow,
stringToPDFString, stringToUTF8String, unreachable, warn
assert, bytesToString, createPromiseCapability, createValidAbsoluteUrl,
FormatError, info, InvalidPDFException, isBool, isNum, isString,
PermissionFlag, shadow, stringToPDFString, stringToUTF8String, unreachable,
warn
} from '../shared/util';
import {
Dict, isCmd, isDict, isName, isRef, isRefsEqual, isStream, Ref, RefSet,
@ -415,6 +416,136 @@ class Catalog {
return shadow(this, 'pageMode', pageMode);
}
get viewerPreferences() {
const ViewerPreferencesValidators = {
HideToolbar: isBool,
HideMenubar: isBool,
HideWindowUI: isBool,
FitWindow: isBool,
CenterWindow: isBool,
DisplayDocTitle: isBool,
NonFullScreenPageMode: isName,
Direction: isName,
ViewArea: isName,
ViewClip: isName,
PrintArea: isName,
PrintClip: isName,
PrintScaling: isName,
Duplex: isName,
PickTrayByPDFSize: isBool,
PrintPageRange: Array.isArray,
NumCopies: Number.isInteger,
};
const obj = this.catDict.get('ViewerPreferences');
const prefs = Object.create(null);
if (isDict(obj)) {
for (const key in ViewerPreferencesValidators) {
if (!obj.has(key)) {
continue;
}
const value = obj.get(key);
// Make sure the (standard) value conforms to the specification.
if (!ViewerPreferencesValidators[key](value)) {
info(`Bad value in ViewerPreferences for "${key}".`);
continue;
}
let prefValue;
switch (key) {
case 'NonFullScreenPageMode':
switch (value.name) {
case 'UseNone':
case 'UseOutlines':
case 'UseThumbs':
case 'UseOC':
prefValue = value.name;
break;
default:
prefValue = 'UseNone';
}
break;
case 'Direction':
switch (value.name) {
case 'L2R':
case 'R2L':
prefValue = value.name;
break;
default:
prefValue = 'L2R';
}
break;
case 'ViewArea':
case 'ViewClip':
case 'PrintArea':
case 'PrintClip':
switch (value.name) {
case 'MediaBox':
case 'CropBox':
case 'BleedBox':
case 'TrimBox':
case 'ArtBox':
prefValue = value.name;
break;
default:
prefValue = 'CropBox';
}
break;
case 'PrintScaling':
switch (value.name) {
case 'None':
case 'AppDefault':
prefValue = value.name;
break;
default:
prefValue = 'AppDefault';
}
break;
case 'Duplex':
switch (value.name) {
case 'Simplex':
case 'DuplexFlipShortEdge':
case 'DuplexFlipLongEdge':
prefValue = value.name;
break;
default:
prefValue = 'None';
}
break;
case 'PrintPageRange':
const length = value.length;
if (length % 2 !== 0) { // The number of elements must be even.
break;
}
const isValid = value.every((page, i, arr) => {
return (Number.isInteger(page) && page > 0) &&
(i === 0 || page >= arr[i - 1]) && page <= this.numPages;
});
if (isValid) {
prefValue = value;
}
break;
case 'NumCopies':
if (value > 0) {
prefValue = value;
}
break;
default:
assert(typeof value === 'boolean');
prefValue = value;
}
if (prefValue !== undefined) {
prefs[key] = prefValue;
} else {
info(`Bad value in ViewerPreferences for "${key}".`);
}
}
}
return shadow(this, 'viewerPreferences', prefs);
}
get openActionDestination() {
const obj = this.catDict.get('OpenAction');
let openActionDest = null;

View File

@ -525,7 +525,11 @@ var WorkerMessageHandler = {
return pdfManager.ensureCatalog('pageMode');
});
handler.on('getOpenActionDestination', function(data) {
handler.on('GetViewerPreferences', function(data) {
return pdfManager.ensureCatalog('viewerPreferences');
});
handler.on('GetOpenActionDestination', function(data) {
return pdfManager.ensureCatalog('openActionDestination');
});

View File

@ -674,6 +674,14 @@ class PDFDocumentProxy {
return this._transport.getPageMode();
}
/**
* @return {Promise} A promise that is resolved with an {Object} containing
* the viewer preferences.
*/
getViewerPreferences() {
return this._transport.getViewerPreferences();
}
/**
* @return {Promise} A promise that is resolved with an {Array} containing the
* destination, or `null` when no open action is present in the PDF file.
@ -2247,8 +2255,12 @@ class WorkerTransport {
return this.messageHandler.sendWithPromise('GetPageMode', null);
}
getViewerPreferences() {
return this.messageHandler.sendWithPromise('GetViewerPreferences', null);
}
getOpenActionDestination() {
return this.messageHandler.sendWithPromise('getOpenActionDestination',
return this.messageHandler.sendWithPromise('GetOpenActionDestination',
null);
}

View File

@ -18,8 +18,9 @@ import {
NodeFileReaderFactory, TEST_PDFS_PATH
} from './test_utils';
import {
createPromiseCapability, FontType, InvalidPDFException, MissingPDFException,
OPS, PasswordException, PasswordResponses, PermissionFlag, StreamType
createPromiseCapability, FontType, InvalidPDFException, isEmptyObj,
MissingPDFException, OPS, PasswordException, PasswordResponses,
PermissionFlag, StreamType
} from '../../src/shared/util';
import {
DOMCanvasFactory, RenderingCancelledException, StatTimer
@ -646,6 +647,27 @@ describe('api', function() {
}).catch(done.fail);
});
it('gets default viewer preferences', function(done) {
var loadingTask = getDocument(buildGetDocumentParams('tracemonkey.pdf'));
loadingTask.promise.then(function(pdfDocument) {
return pdfDocument.getViewerPreferences();
}).then(function(prefs) {
expect(typeof prefs === 'object' && prefs !== null &&
isEmptyObj(prefs)).toEqual(true);
loadingTask.destroy().then(done);
}).catch(done.fail);
});
it('gets non-default viewer preferences', function(done) {
doc.getViewerPreferences().then(function(prefs) {
expect(prefs).toEqual({
Direction: 'L2R',
});
done();
}).catch(done.fail);
});
it('gets default open action destination', function(done) {
var loadingTask = getDocument(buildGetDocumentParams('tracemonkey.pdf'));