1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-21 07:38:07 +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:
Jonas Jenwald 2016-10-01 12:05:07 +02:00
parent 71a781ee5c
commit d284cfd5eb
11 changed files with 304 additions and 47 deletions

View file

@ -46,6 +46,7 @@
!arial_unicode_ab_cidfont.pdf
!arial_unicode_en_cidfont.pdf
!asciihexdecode.pdf
!bug766086.pdf
!bug793632.pdf
!bug1020858.pdf
!bug1050040.pdf

85
test/pdfs/bug766086.pdf Normal file
View file

@ -0,0 +1,85 @@
%PDF-1.7
%âãÏÓ
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
2 0 obj
<<
/Kids [3 0 R]
/Count 1
/Type /Pages
>>
endobj
3 0 obj
<<
/Parent 2 0 R
/Annots [4 0 R]
/MediaBox [0 0 200 50]
/Resources
<<
/Font
<<
/F1 5 0 R
>>
>>
/Contents 6 0 R
/Type /Page
>>
endobj
4 0 obj
<<
/Border [0 0 1]
/Subtype /Link
/C [1 0 0]
/A
<<
/F (../../0021/002156/215675E.pdf)
/D (15)
/Type /Action
/S /GoToR
>>
/Type /Annot
/Rect [5 10 190 40]
>>
endobj
5 0 obj
<<
/BaseFont /Times-Roman
/Subtype /Type1
/Encoding /WinAnsiEncoding
/Type /Font
>>
endobj
6 0 obj
<<
/Length 58
>>
stream
BT
10 20 TD
/F1 16 Tf
(Bug 766086 - relative links) Tj
ET
endstream
endobj xref
0 7
0000000000 65535 f
0000000015 00000 n
0000000066 00000 n
0000000125 00000 n
0000000270 00000 n
0000000445 00000 n
0000000546 00000 n
trailer
<<
/Root 1 0 R
/Size 7
>>
startxref
656
%%EOF

View file

@ -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);

View file

@ -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({