Merge pull request #9975 from Snuffleupagus/getDestination-refactor
Re-factor `destinations`/`getDestination` to reduce unnecessary duplication, and reject non-string inputs
This commit is contained in:
commit
1268aea2b6
@ -28,6 +28,10 @@ import { ChunkedStream } from './chunked_stream';
|
|||||||
import { CipherTransformFactory } from './crypto';
|
import { CipherTransformFactory } from './crypto';
|
||||||
import { ColorSpace } from './colorspace';
|
import { ColorSpace } from './colorspace';
|
||||||
|
|
||||||
|
function fetchDestination(dest) {
|
||||||
|
return isDict(dest) ? dest.get('D') : dest;
|
||||||
|
}
|
||||||
|
|
||||||
var Catalog = (function CatalogClosure() {
|
var Catalog = (function CatalogClosure() {
|
||||||
function Catalog(pdfManager, xref) {
|
function Catalog(pdfManager, xref) {
|
||||||
this.pdfManager = pdfManager;
|
this.pdfManager = pdfManager;
|
||||||
@ -173,64 +177,37 @@ var Catalog = (function CatalogClosure() {
|
|||||||
// shadow the prototype getter
|
// shadow the prototype getter
|
||||||
return shadow(this, 'numPages', obj);
|
return shadow(this, 'numPages', obj);
|
||||||
},
|
},
|
||||||
|
|
||||||
get destinations() {
|
get destinations() {
|
||||||
function fetchDestination(dest) {
|
const obj = this._readDests(), dests = Object.create(null);
|
||||||
return isDict(dest) ? dest.get('D') : dest;
|
if (obj instanceof NameTree) {
|
||||||
}
|
const names = obj.getAll();
|
||||||
|
for (let name in names) {
|
||||||
var xref = this.xref;
|
|
||||||
var dests = {}, 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;
|
|
||||||
}
|
|
||||||
dests[key] = fetchDestination(value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (nameTreeRef) {
|
|
||||||
var nameTree = new NameTree(nameTreeRef, xref);
|
|
||||||
var names = nameTree.getAll();
|
|
||||||
for (var name in names) {
|
|
||||||
dests[name] = fetchDestination(names[name]);
|
dests[name] = fetchDestination(names[name]);
|
||||||
}
|
}
|
||||||
|
} else if (obj instanceof Dict) {
|
||||||
|
obj.forEach(function(key, value) {
|
||||||
|
if (value) {
|
||||||
|
dests[key] = fetchDestination(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return shadow(this, 'destinations', dests);
|
return shadow(this, 'destinations', dests);
|
||||||
},
|
},
|
||||||
getDestination: function Catalog_getDestination(destinationId) {
|
getDestination(destinationId) {
|
||||||
function fetchDestination(dest) {
|
const obj = this._readDests();
|
||||||
return isDict(dest) ? dest.get('D') : dest;
|
if (obj instanceof NameTree || obj instanceof Dict) {
|
||||||
|
return fetchDestination(obj.get(destinationId) || null);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
var xref = this.xref;
|
},
|
||||||
var dest = null, nameTreeRef, nameDictionaryRef;
|
_readDests() {
|
||||||
var obj = this.catDict.get('Names');
|
const obj = this.catDict.get('Names');
|
||||||
if (obj && obj.has('Dests')) {
|
if (obj && obj.has('Dests')) {
|
||||||
nameTreeRef = obj.getRaw('Dests');
|
return new NameTree(obj.getRaw('Dests'), this.xref);
|
||||||
} else if (this.catDict.has('Dests')) {
|
} else if (this.catDict.has('Dests')) { // Simple destination dictionary.
|
||||||
nameDictionaryRef = this.catDict.get('Dests');
|
return this.catDict.get('Dests');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameDictionaryRef) { // Simple destination dictionary.
|
|
||||||
var value = nameDictionaryRef.get(destinationId);
|
|
||||||
if (value) {
|
|
||||||
dest = fetchDestination(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nameTreeRef) {
|
|
||||||
var nameTree = new NameTree(nameTreeRef, xref);
|
|
||||||
dest = fetchDestination(nameTree.get(destinationId));
|
|
||||||
}
|
|
||||||
return dest;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get pageLabels() {
|
get pageLabels() {
|
||||||
|
@ -627,7 +627,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
|
|||||||
return this.transport.getDestinations();
|
return this.transport.getDestinations();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @param {string} id The named destination to get.
|
* @param {string} id - The named destination to get.
|
||||||
* @return {Promise} A promise that is resolved with all information
|
* @return {Promise} A promise that is resolved with all information
|
||||||
* of the given named destination.
|
* of the given named destination.
|
||||||
*/
|
*/
|
||||||
@ -2119,6 +2119,9 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getDestination: function WorkerTransport_getDestination(id) {
|
getDestination: function WorkerTransport_getDestination(id) {
|
||||||
|
if (typeof id !== 'string') {
|
||||||
|
return Promise.reject(new Error('Invalid destination request.'));
|
||||||
|
}
|
||||||
return this.messageHandler.sendWithPromise('GetDestination', {
|
return this.messageHandler.sendWithPromise('GetDestination', {
|
||||||
id,
|
id,
|
||||||
});
|
});
|
||||||
|
@ -583,6 +583,32 @@ describe('api', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('gets non-string destination', function(done) {
|
||||||
|
let numberPromise = doc.getDestination(4.3);
|
||||||
|
let booleanPromise = doc.getDestination(true);
|
||||||
|
let arrayPromise = doc.getDestination([
|
||||||
|
{ num: 17, gen: 0, }, { name: 'XYZ', }, 0, 841.89, null]);
|
||||||
|
|
||||||
|
numberPromise = numberPromise.then(function() {
|
||||||
|
throw new Error('shall fail for non-string destination.');
|
||||||
|
}, function(reason) {
|
||||||
|
expect(reason instanceof Error).toEqual(true);
|
||||||
|
});
|
||||||
|
booleanPromise = booleanPromise.then(function() {
|
||||||
|
throw new Error('shall fail for non-string destination.');
|
||||||
|
}, function(reason) {
|
||||||
|
expect(reason instanceof Error).toEqual(true);
|
||||||
|
});
|
||||||
|
arrayPromise = arrayPromise.then(function() {
|
||||||
|
throw new Error('shall fail for non-string destination.');
|
||||||
|
}, function(reason) {
|
||||||
|
expect(reason instanceof Error).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all([numberPromise, booleanPromise, arrayPromise]).then(
|
||||||
|
done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
it('gets non-existent page labels', function (done) {
|
it('gets non-existent page labels', function (done) {
|
||||||
var promise = doc.getPageLabels();
|
var promise = doc.getPageLabels();
|
||||||
promise.then(function (data) {
|
promise.then(function (data) {
|
||||||
|
Loading…
Reference in New Issue
Block a user