diff --git a/src/core/annotation.js b/src/core/annotation.js index 37c3315966070..c0338cd749b54 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -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, }); } diff --git a/src/core/document.js b/src/core/document.js index 710597a4dfc42..a4aad52898f3f 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -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) { diff --git a/src/core/obj.js b/src/core/obj.js index c8a564c7e9080..7c47b6ea88b12 100644 --- a/src/core/obj.js +++ b/src/core/obj.js @@ -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; } diff --git a/src/core/pdf_manager.js b/src/core/pdf_manager.js index bd5f7933d52fc..15656da0c35d8 100644 --- a/src/core/pdf_manager.js +++ b/src/core/pdf_manager.js @@ -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; diff --git a/src/core/worker.js b/src/core/worker.js index 423bb08627ca3..96746197d9f27 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -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); diff --git a/src/display/api.js b/src/display/api.js index d695f1c2cb190..425dfbc900441 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -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'); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 5559a84b4c632..f07e5921fe392 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -46,6 +46,7 @@ !arial_unicode_ab_cidfont.pdf !arial_unicode_en_cidfont.pdf !asciihexdecode.pdf +!bug766086.pdf !bug793632.pdf !bug1020858.pdf !bug1050040.pdf diff --git a/test/pdfs/bug766086.pdf b/test/pdfs/bug766086.pdf new file mode 100644 index 0000000000000..42900a21bde8e Binary files /dev/null and b/test/pdfs/bug766086.pdf differ diff --git a/test/unit/annotation_layer_spec.js b/test/unit/annotation_layer_spec.js index 276f5bf698d43..16d461716dc18 100644 --- a/test/unit/annotation_layer_spec.js +++ b/test/unit/annotation_layer_spec.js @@ -27,15 +27,24 @@ describe('Annotation layer', function() { }, }; - var annotationFactory; + function PDFManagerMock(params) { + this.docBaseUrl = params.docBaseUrl || null; + } + PDFManagerMock.prototype = {}; + + var annotationFactory, pdfManagerMock; beforeAll(function (done) { annotationFactory = new AnnotationFactory(); + pdfManagerMock = new PDFManagerMock({ + docBaseUrl: null, + }); done(); }); afterAll(function () { annotationFactory = null; + pdfManagerMock = null; }); describe('AnnotationFactory', function () { @@ -49,7 +58,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -66,8 +76,10 @@ describe('Annotation layer', function() { var uniquePrefix = 'p0_', idCounters = { obj: 0, }; var annotation1 = annotationFactory.create(xref, annotationDict, + pdfManagerMock, uniquePrefix, idCounters); var annotation2 = annotationFactory.create(xref, annotationDict, + pdfManagerMock, uniquePrefix, idCounters); var data1 = annotation1.data, data2 = annotation2.data; expect(data1.annotationType).toEqual(AnnotationType.LINK); @@ -86,7 +98,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toBeUndefined(); }); @@ -270,7 +283,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -297,7 +311,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -329,7 +344,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -356,7 +372,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -384,7 +401,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -394,6 +412,38 @@ describe('Annotation layer', function() { expect(data.newWindow).toEqual(true); }); + it('should correctly parse a GoToR action, containing a relative URL, ' + + 'with the "docBaseUrl" parameter specified', function() { + var actionDict = new Dict(); + actionDict.set('Type', Name.get('Action')); + actionDict.set('S', Name.get('GoToR')); + actionDict.set('F', '../../0013/001346/134685E.pdf'); + actionDict.set('D', '4.3'); + + var annotationDict = new Dict(); + annotationDict.set('Type', Name.get('Annot')); + annotationDict.set('Subtype', Name.get('Link')); + annotationDict.set('A', actionDict); + + var annotationRef = new Ref(489, 0); + var xref = new XRefMock([ + { ref: annotationRef, data: annotationDict, } + ]); + var pdfManager = new PDFManagerMock({ + docBaseUrl: 'http://www.example.com/test/pdfs/qwerty.pdf', + }); + + var annotation = annotationFactory.create(xref, annotationRef, + pdfManager); + var data = annotation.data; + expect(data.annotationType).toEqual(AnnotationType.LINK); + + expect(data.url).toEqual( + 'http://www.example.com/0013/001346/134685E.pdf#4.3'); + expect(data.unsafeUrl).toEqual('../../0013/001346/134685E.pdf#4.3'); + expect(data.dest).toBeUndefined(); + }); + it('should correctly parse a GoToR action, with named destination', function() { var actionDict = new Dict(); @@ -412,7 +462,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -441,7 +492,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -469,7 +521,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -489,7 +542,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -511,7 +565,8 @@ describe('Annotation layer', function() { { ref: annotationRef, data: annotationDict, } ]); - var annotation = annotationFactory.create(xref, annotationRef); + var annotation = annotationFactory.create(xref, annotationRef, + pdfManagerMock); var data = annotation.data; expect(data.annotationType).toEqual(AnnotationType.LINK); @@ -545,7 +600,8 @@ describe('Annotation layer', function() { { ref: textWidgetRef, data: textWidgetDict, } ]); - var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef); + var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef, + pdfManagerMock); expect(textWidgetAnnotation.data.textAlignment).toEqual(null); expect(textWidgetAnnotation.data.maxLen).toEqual(null); expect(textWidgetAnnotation.data.readOnly).toEqual(false); @@ -564,7 +620,8 @@ describe('Annotation layer', function() { { ref: textWidgetRef, data: textWidgetDict, } ]); - var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef); + var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef, + pdfManagerMock); expect(textWidgetAnnotation.data.textAlignment).toEqual(null); expect(textWidgetAnnotation.data.maxLen).toEqual(null); expect(textWidgetAnnotation.data.readOnly).toEqual(false); @@ -584,7 +641,8 @@ describe('Annotation layer', function() { { ref: textWidgetRef, data: textWidgetDict, } ]); - var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef); + var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef, + pdfManagerMock); expect(textWidgetAnnotation.data.textAlignment).toEqual(1); expect(textWidgetAnnotation.data.maxLen).toEqual(20); expect(textWidgetAnnotation.data.readOnly).toEqual(true); @@ -599,7 +657,8 @@ describe('Annotation layer', function() { { ref: textWidgetRef, data: textWidgetDict, } ]); - var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef); + var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef, + pdfManagerMock); expect(textWidgetAnnotation.data.comb).toEqual(false); }); @@ -612,7 +671,8 @@ describe('Annotation layer', function() { { ref: textWidgetRef, data: textWidgetDict, } ]); - var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef); + var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef, + pdfManagerMock); expect(textWidgetAnnotation.data.comb).toEqual(true); }); @@ -636,9 +696,8 @@ describe('Annotation layer', function() { { ref: textWidgetRef, data: textWidgetDict, } ]); - var textWidgetAnnotation = annotationFactory.create(xref, - textWidgetRef); - + var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef, + pdfManagerMock); var valid = (invalidFieldFlags.length === 0); expect(textWidgetAnnotation.data.comb).toEqual(valid); @@ -673,7 +732,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.options).toEqual([]); @@ -700,7 +760,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.options).toEqual(expected); @@ -727,7 +788,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.options).toEqual(expected); @@ -744,7 +806,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.fieldValue).toEqual(fieldValue); @@ -761,7 +824,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.fieldValue).toEqual([fieldValue]); @@ -774,7 +838,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.readOnly).toEqual(false); @@ -791,7 +856,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.readOnly).toEqual(false); @@ -810,7 +876,8 @@ describe('Annotation layer', function() { ]); var choiceWidgetAnnotation = annotationFactory.create(xref, - choiceWidgetRef); + choiceWidgetRef, + pdfManagerMock); var data = choiceWidgetAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.WIDGET); expect(data.readOnly).toEqual(true); @@ -869,7 +936,8 @@ describe('Annotation layer', function() { { ref: popupRef, data: popupDict, } ]); - var popupAnnotation = annotationFactory.create(xref, popupRef); + var popupAnnotation = annotationFactory.create(xref, popupRef, + pdfManagerMock); var data = popupAnnotation.data; expect(data.annotationType).toEqual(AnnotationType.POPUP); diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index e593a37250e7f..45d4843327b7c 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -789,6 +789,68 @@ describe('api', function() { done.fail(reason); }); }); + + it('gets annotations containing relative URLs (bug 766086)', + function (done) { + var url = new URL('../pdfs/bug766086.pdf', window.location).href; + + var defaultLoadingTask = PDFJS.getDocument(url); + var defaultPromise = defaultLoadingTask.promise.then(function (pdfDoc) { + return pdfDoc.getPage(1).then(function (pdfPage) { + return pdfPage.getAnnotations(); + }); + }); + + var docBaseUrlLoadingTask = PDFJS.getDocument({ + url: url, + docBaseUrl: 'http://www.example.com/test/pdfs/qwerty.pdf', + }); + var docBaseUrlPromise = docBaseUrlLoadingTask.promise.then( + function (pdfDoc) { + return pdfDoc.getPage(1).then(function (pdfPage) { + return pdfPage.getAnnotations(); + }); + }); + + var invalidDocBaseUrlLoadingTask = PDFJS.getDocument({ + url: url, + docBaseUrl: 'qwerty.pdf', + }); + var invalidDocBaseUrlPromise = invalidDocBaseUrlLoadingTask.promise.then( + function (pdfDoc) { + return pdfDoc.getPage(1).then(function (pdfPage) { + return pdfPage.getAnnotations(); + }); + }); + + Promise.all([defaultPromise, docBaseUrlPromise, + invalidDocBaseUrlPromise]).then(function (data) { + var defaultAnnotations = data[0]; + var docBaseUrlAnnotations = data[1]; + var invalidDocBaseUrlAnnotations = data[2]; + + expect(defaultAnnotations[0].url).toBeUndefined(); + expect(defaultAnnotations[0].unsafeUrl).toEqual( + '../../0021/002156/215675E.pdf#nameddest=15'); + + expect(docBaseUrlAnnotations[0].url).toEqual( + 'http://www.example.com/0021/002156/215675E.pdf#nameddest=15'); + expect(docBaseUrlAnnotations[0].unsafeUrl).toEqual( + '../../0021/002156/215675E.pdf#nameddest=15'); + + expect(invalidDocBaseUrlAnnotations[0].url).toBeUndefined(); + expect(invalidDocBaseUrlAnnotations[0].unsafeUrl).toEqual( + '../../0021/002156/215675E.pdf#nameddest=15'); + + defaultLoadingTask.destroy(); + docBaseUrlLoadingTask.destroy(); + invalidDocBaseUrlLoadingTask.destroy(); + done(); + }).catch(function (reason) { + done.fail(reason); + }); + }); + it('gets text content', function (done) { var defaultPromise = page.getTextContent(); var parametersPromise = page.getTextContent({ diff --git a/web/app.js b/web/app.js index eb3cbe202d1ad..73cc29911f8b5 100644 --- a/web/app.js +++ b/web/app.js @@ -180,6 +180,7 @@ var PDFViewerApplication = { preferenceDefaultZoomValue: '', isViewerEmbedded: (window.parent !== window), url: '', + baseUrl: '', externalServices: DefaultExernalServices, // called once when the document is loaded @@ -522,6 +523,7 @@ var PDFViewerApplication = { setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) { this.url = url; + this.baseUrl = url.split('#')[0]; try { this.setTitle(decodeURIComponent( pdfjsLib.getFilenameFromUrl(url)) || url); @@ -614,6 +616,11 @@ var PDFViewerApplication = { this.setTitleUsingUrl(file.originalUrl); parameters.url = file.url; } + if (typeof PDFJSDev !== 'undefined' && + PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { + parameters.docBaseUrl = this.baseUrl; + } + if (args) { for (var prop in args) { parameters[prop] = args[prop]; @@ -682,7 +689,7 @@ var PDFViewerApplication = { downloadManager.downloadUrl(url, filename); } - var url = this.url.split('#')[0]; + var url = this.baseUrl; var filename = getPDFFileNameFromURL(url); var downloadManager = this.downloadManager; downloadManager.onerror = function (err) { @@ -719,14 +726,15 @@ var PDFViewerApplication = { return; } this.fellback = true; - var url = this.url.split('#')[0]; - this.externalServices.fallback({ featureId: featureId, url: url }, - function response(download) { - if (!download) { - return; - } - PDFViewerApplication.download(); - }); + this.externalServices.fallback({ + featureId: featureId, + url: this.baseUrl, + }, function response(download) { + if (!download) { + return; + } + PDFViewerApplication.download(); + }); } }, @@ -856,7 +864,7 @@ var PDFViewerApplication = { if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { baseDocumentUrl = null; } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) { - baseDocumentUrl = this.url.split('#')[0]; + baseDocumentUrl = this.baseUrl; } else if (PDFJSDev.test('CHROME')) { baseDocumentUrl = location.href.split('#')[0]; }