mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
[api-minor] Add support for relative URLs, in both annotations and the outline, by adding a docBaseUrl
parameter to PDFJS.getDocument
(bug 766086)
Note that in `FIREFOX/MOZCENTRAL/CHROME` builds of the standard viewer the `docBaseUrl` parameter will be set by default, since in that case it makes sense to use the current URL as a base. For the `GENERIC` viewer, or the API itself, it doesn't make sense to try and set the `docBaseUrl` by default. However, custom deployments/implementations may still find the parameter useful.
This commit is contained in:
parent
71a781ee5c
commit
d284cfd5eb
11 changed files with 304 additions and 47 deletions
|
@ -64,11 +64,12 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ {
|
|||
/**
|
||||
* @param {XRef} xref
|
||||
* @param {Object} ref
|
||||
* @param {PDFManager} pdfManager
|
||||
* @param {string} uniquePrefix
|
||||
* @param {Object} idCounters
|
||||
* @returns {Annotation}
|
||||
*/
|
||||
create: function AnnotationFactory_create(xref, ref,
|
||||
create: function AnnotationFactory_create(xref, ref, pdfManager,
|
||||
uniquePrefix, idCounters) {
|
||||
var dict = xref.fetchIfRef(ref);
|
||||
if (!isDict(dict)) {
|
||||
|
@ -88,6 +89,7 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ {
|
|||
ref: isRef(ref) ? ref : null,
|
||||
subtype: subtype,
|
||||
id: id,
|
||||
pdfManager: pdfManager,
|
||||
};
|
||||
|
||||
switch (subtype) {
|
||||
|
@ -846,6 +848,7 @@ var LinkAnnotation = (function LinkAnnotationClosure() {
|
|||
Catalog.parseDestDictionary({
|
||||
destDict: params.dict,
|
||||
resultObj: data,
|
||||
docBaseUrl: params.pdfManager.docBaseUrl,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -329,6 +329,7 @@ var Page = (function PageClosure() {
|
|||
for (var i = 0, n = annotationRefs.length; i < n; ++i) {
|
||||
var annotationRef = annotationRefs[i];
|
||||
var annotation = annotationFactory.create(this.xref, annotationRef,
|
||||
this.pdfManager,
|
||||
this.uniquePrefix,
|
||||
this.idCounters);
|
||||
if (annotation) {
|
||||
|
|
|
@ -157,6 +157,7 @@ var Catalog = (function CatalogClosure() {
|
|||
Catalog.parseDestDictionary({
|
||||
destDict: outlineDict,
|
||||
resultObj: data,
|
||||
docBaseUrl: this.pdfManager.docBaseUrl,
|
||||
});
|
||||
var title = outlineDict.get('Title');
|
||||
var flags = outlineDict.get('F') || 0;
|
||||
|
@ -590,6 +591,8 @@ var Catalog = (function CatalogClosure() {
|
|||
* @param {Dict} destDict - The dictionary containing the destination.
|
||||
* @param {Object} resultObj - The object where the parsed destination
|
||||
* properties will be placed.
|
||||
* @param {string} docBaseUrl - (optional) The document base URL that is used
|
||||
* when attempting to recover valid absolute URLs from relative ones.
|
||||
*/
|
||||
Catalog.parseDestDictionary = function Catalog_parseDestDictionary(params) {
|
||||
// Lets URLs beginning with 'www.' default to using the 'http://' protocol.
|
||||
|
@ -619,6 +622,7 @@ var Catalog = (function CatalogClosure() {
|
|||
warn('Catalog_parseDestDictionary: "resultObj" must be an object.');
|
||||
return;
|
||||
}
|
||||
var docBaseUrl = params.docBaseUrl || null;
|
||||
|
||||
var action = destDict.get('A'), url, dest;
|
||||
if (isDict(action)) {
|
||||
|
@ -694,7 +698,7 @@ var Catalog = (function CatalogClosure() {
|
|||
|
||||
if (isString(url)) {
|
||||
url = tryConvertUrlEncoding(url);
|
||||
var absoluteUrl = createValidAbsoluteUrl(url);
|
||||
var absoluteUrl = createValidAbsoluteUrl(url, docBaseUrl);
|
||||
if (absoluteUrl) {
|
||||
resultObj.url = absoluteUrl.href;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
}(this, function (exports, sharedUtil, coreStream, coreChunkedStream,
|
||||
coreDocument) {
|
||||
|
||||
var warn = sharedUtil.warn;
|
||||
var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
|
||||
var shadow = sharedUtil.shadow;
|
||||
var NotImplementedException = sharedUtil.NotImplementedException;
|
||||
var MissingDataException = sharedUtil.MissingDataException;
|
||||
var createPromiseCapability = sharedUtil.createPromiseCapability;
|
||||
|
@ -49,6 +52,19 @@ var BasePdfManager = (function BasePdfManagerClosure() {
|
|||
return this._docId;
|
||||
},
|
||||
|
||||
get docBaseUrl() {
|
||||
var docBaseUrl = null;
|
||||
if (this._docBaseUrl) {
|
||||
var absoluteUrl = createValidAbsoluteUrl(this._docBaseUrl);
|
||||
if (absoluteUrl) {
|
||||
docBaseUrl = absoluteUrl.href;
|
||||
} else {
|
||||
warn('Invalid absolute docBaseUrl: "' + this._docBaseUrl + '".');
|
||||
}
|
||||
}
|
||||
return shadow(this, 'docBaseUrl', docBaseUrl);
|
||||
},
|
||||
|
||||
onLoadedStream: function BasePdfManager_onLoadedStream() {
|
||||
throw new NotImplementedException();
|
||||
},
|
||||
|
@ -110,8 +126,10 @@ var BasePdfManager = (function BasePdfManagerClosure() {
|
|||
})();
|
||||
|
||||
var LocalPdfManager = (function LocalPdfManagerClosure() {
|
||||
function LocalPdfManager(docId, data, password, evaluatorOptions) {
|
||||
function LocalPdfManager(docId, data, password, evaluatorOptions,
|
||||
docBaseUrl) {
|
||||
this._docId = docId;
|
||||
this._docBaseUrl = docBaseUrl;
|
||||
this.evaluatorOptions = evaluatorOptions;
|
||||
var stream = new Stream(data);
|
||||
this.pdfDocument = new PDFDocument(this, stream, password);
|
||||
|
@ -158,8 +176,10 @@ var LocalPdfManager = (function LocalPdfManagerClosure() {
|
|||
})();
|
||||
|
||||
var NetworkPdfManager = (function NetworkPdfManagerClosure() {
|
||||
function NetworkPdfManager(docId, pdfNetworkStream, args, evaluatorOptions) {
|
||||
function NetworkPdfManager(docId, pdfNetworkStream, args, evaluatorOptions,
|
||||
docBaseUrl) {
|
||||
this._docId = docId;
|
||||
this._docBaseUrl = docBaseUrl;
|
||||
this.msgHandler = args.msgHandler;
|
||||
this.evaluatorOptions = evaluatorOptions;
|
||||
|
||||
|
|
|
@ -480,6 +480,7 @@ var WorkerMessageHandler = {
|
|||
var WorkerTasks = [];
|
||||
|
||||
var docId = docParams.docId;
|
||||
var docBaseUrl = docParams.docBaseUrl;
|
||||
var workerHandlerName = docParams.docId + '_worker';
|
||||
var handler = new MessageHandler(workerHandlerName, docId, port);
|
||||
|
||||
|
@ -544,7 +545,7 @@ var WorkerMessageHandler = {
|
|||
if (source.data) {
|
||||
try {
|
||||
pdfManager = new LocalPdfManager(docId, source.data, source.password,
|
||||
evaluatorOptions);
|
||||
evaluatorOptions, docBaseUrl);
|
||||
pdfManagerCapability.resolve(pdfManager);
|
||||
} catch (ex) {
|
||||
pdfManagerCapability.reject(ex);
|
||||
|
@ -593,7 +594,7 @@ var WorkerMessageHandler = {
|
|||
length: fullRequest.contentLength,
|
||||
disableAutoFetch: disableAutoFetch,
|
||||
rangeChunkSize: source.rangeChunkSize
|
||||
}, evaluatorOptions);
|
||||
}, evaluatorOptions, docBaseUrl);
|
||||
pdfManagerCapability.resolve(pdfManager);
|
||||
cancelXHRs = null;
|
||||
}).catch(function (reason) {
|
||||
|
@ -610,7 +611,7 @@ var WorkerMessageHandler = {
|
|||
// the data is array, instantiating directly from it
|
||||
try {
|
||||
pdfManager = new LocalPdfManager(docId, pdfFile, source.password,
|
||||
evaluatorOptions);
|
||||
evaluatorOptions, docBaseUrl);
|
||||
pdfManagerCapability.resolve(pdfManager);
|
||||
} catch (ex) {
|
||||
pdfManagerCapability.reject(ex);
|
||||
|
|
|
@ -129,6 +129,9 @@ if (typeof PDFJSDev !== 'undefined' &&
|
|||
* 2^16 = 65536.
|
||||
* @property {PDFWorker} worker - The worker that will be used for the loading
|
||||
* and parsing of the PDF data.
|
||||
* @property {string} docBaseUrl - (optional) The base URL of the document,
|
||||
* used when attempting to recover valid absolute URLs for annotations, and
|
||||
* outline items, that (incorrectly) only specify relative URLs.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -301,6 +304,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
|||
disableCreateObjectURL: getDefaultSetting('disableCreateObjectURL'),
|
||||
postMessageTransfers: getDefaultSetting('postMessageTransfers') &&
|
||||
!isPostMessageTransfersDisabled,
|
||||
docBaseUrl: source.docBaseUrl,
|
||||
}).then(function (workerId) {
|
||||
if (worker.destroyed) {
|
||||
throw new Error('Worker was destroyed');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue