2014-09-30 01:05:28 +09:00
|
|
|
/* Copyright 2014 Mozilla Foundation
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2017-05-31 10:38:22 +09:00
|
|
|
import { AnnotationLayer } from 'pdfjs-lib';
|
2017-05-04 10:05:53 +09:00
|
|
|
import { NullL10n } from './ui_utils';
|
2017-04-15 00:32:36 +09:00
|
|
|
import { SimpleLinkService } from './pdf_link_service';
|
2016-04-09 02:34:27 +09:00
|
|
|
|
2014-09-30 01:05:28 +09:00
|
|
|
/**
|
2015-12-17 20:54:53 +09:00
|
|
|
* @typedef {Object} AnnotationLayerBuilderOptions
|
2014-09-30 01:05:28 +09:00
|
|
|
* @property {HTMLDivElement} pageDiv
|
|
|
|
* @property {PDFPage} pdfPage
|
2019-10-12 23:30:32 +09:00
|
|
|
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
|
|
|
* for annotation icons. Include trailing slash.
|
2016-09-18 02:44:25 +09:00
|
|
|
* @property {boolean} renderInteractiveForms
|
2014-09-30 01:05:28 +09:00
|
|
|
* @property {IPDFLinkService} linkService
|
2016-02-15 04:44:00 +09:00
|
|
|
* @property {DownloadManager} downloadManager
|
2017-05-04 10:05:53 +09:00
|
|
|
* @property {IL10n} l10n - Localization service.
|
2014-09-30 01:05:28 +09:00
|
|
|
*/
|
|
|
|
|
2017-04-24 03:52:58 +09:00
|
|
|
class AnnotationLayerBuilder {
|
2014-09-30 01:05:28 +09:00
|
|
|
/**
|
2015-12-17 20:54:53 +09:00
|
|
|
* @param {AnnotationLayerBuilderOptions} options
|
2014-09-30 01:05:28 +09:00
|
|
|
*/
|
2017-06-30 19:55:22 +09:00
|
|
|
constructor({ pageDiv, pdfPage, linkService, downloadManager,
|
2018-02-13 21:17:11 +09:00
|
|
|
imageResourcesPath = '', renderInteractiveForms = false,
|
|
|
|
l10n = NullL10n, }) {
|
2017-06-30 19:55:22 +09:00
|
|
|
this.pageDiv = pageDiv;
|
|
|
|
this.pdfPage = pdfPage;
|
|
|
|
this.linkService = linkService;
|
|
|
|
this.downloadManager = downloadManager;
|
2018-02-13 21:17:11 +09:00
|
|
|
this.imageResourcesPath = imageResourcesPath;
|
2017-06-30 19:55:22 +09:00
|
|
|
this.renderInteractiveForms = renderInteractiveForms;
|
|
|
|
this.l10n = l10n;
|
2014-09-30 01:05:28 +09:00
|
|
|
|
|
|
|
this.div = null;
|
Prevent the `annotationLayer` from, in some cases, becoming duplicated on the first page when the document loads
I don't know if this is a regression, but I noticed earlier today that depending on the initial scale *and* sidebar state, the `annotationLayer` of the first rendered page may end up duplicated; please see screen-shot below.
[screen-shot]
I can reproduce this reliable with e.g. https://arxiv.org/pdf/1112.0542v1.pdf#zoom=page-width&pagemode=bookmarks.
When the document loads, rendering of the first page begins immediately. When the sidebar is then opened, that forces re-rendering which thus aborts rendering of the first page.
Note that calling `PDFPageView.draw()` will always, provided an `AnnotationLayerFactory` instance exists, call `AnnotationLayerBuilder.render()`. Hence the events described above will result in *two* such calls, where the actual annotation rendering/updating happens asynchronously.
For reasons that I don't (at all) understand, when multiple `pdfPage.getAnnotations()` promises are handled back-to-back (in `AnnotationLayerBuilder.render()`), the `this.div` property seems to not update in time for the subsequent calls.
This thus, at least in Firefox, result in double rendering of all annotations on the first page.
Obviously it'd be good to find out why it breaks, since it *really* shouldn't, but this patch at least provides a (hopefully) acceptable work-around by ignoring `getAnnotations()` calls for `AnnotationLayerBuilder` instances that we're destroying (in `PDFPageView.reset()`).
2017-10-07 00:26:54 +09:00
|
|
|
this._cancelled = false;
|
2014-09-30 01:05:28 +09:00
|
|
|
}
|
2015-12-03 08:20:18 +09:00
|
|
|
|
2017-04-24 03:52:58 +09:00
|
|
|
/**
|
|
|
|
* @param {PageViewport} viewport
|
|
|
|
* @param {string} intent (default value is 'display')
|
|
|
|
*/
|
|
|
|
render(viewport, intent = 'display') {
|
2017-04-28 19:02:42 +09:00
|
|
|
this.pdfPage.getAnnotations({ intent, }).then((annotations) => {
|
Prevent the `annotationLayer` from, in some cases, becoming duplicated on the first page when the document loads
I don't know if this is a regression, but I noticed earlier today that depending on the initial scale *and* sidebar state, the `annotationLayer` of the first rendered page may end up duplicated; please see screen-shot below.
[screen-shot]
I can reproduce this reliable with e.g. https://arxiv.org/pdf/1112.0542v1.pdf#zoom=page-width&pagemode=bookmarks.
When the document loads, rendering of the first page begins immediately. When the sidebar is then opened, that forces re-rendering which thus aborts rendering of the first page.
Note that calling `PDFPageView.draw()` will always, provided an `AnnotationLayerFactory` instance exists, call `AnnotationLayerBuilder.render()`. Hence the events described above will result in *two* such calls, where the actual annotation rendering/updating happens asynchronously.
For reasons that I don't (at all) understand, when multiple `pdfPage.getAnnotations()` promises are handled back-to-back (in `AnnotationLayerBuilder.render()`), the `this.div` property seems to not update in time for the subsequent calls.
This thus, at least in Firefox, result in double rendering of all annotations on the first page.
Obviously it'd be good to find out why it breaks, since it *really* shouldn't, but this patch at least provides a (hopefully) acceptable work-around by ignoring `getAnnotations()` calls for `AnnotationLayerBuilder` instances that we're destroying (in `PDFPageView.reset()`).
2017-10-07 00:26:54 +09:00
|
|
|
if (this._cancelled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-30 19:55:22 +09:00
|
|
|
let parameters = {
|
Fix inconsistent spacing and trailing commas in objects in `web/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
*Please note:* This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 002dbf29..1de4e530 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -420,8 +420,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
setPageLabel: function PDFThumbnailView_setPageLabel(label) {
this.pageLabel = (typeof label === 'string' ? label : null);
- this.l10n.get('thumb_page_title', { page: this.pageId, }, 'Page {{page}}').
- then((msg) => {
+ this.l10n.get('thumb_page_title', { page: this.pageId, },
+ 'Page {{page}}').then((msg) => {
this.anchor.title = msg;
});
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 160e0410..6495fc5e 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -65,7 +65,8 @@ class SecondaryToolbar {
{ element: options.printButton, eventName: 'print', close: true, },
{ element: options.downloadButton, eventName: 'download', close: true, },
{ element: options.viewBookmarkButton, eventName: null, close: true, },
- { element: options.firstPageButton, eventName: 'firstpage', close: true, },
+ { element: options.firstPageButton, eventName: 'firstpage',
+ close: true, },
{ element: options.lastPageButton, eventName: 'lastpage', close: true, },
{ element: options.pageRotateCwButton, eventName: 'rotatecw',
close: false, },
@@ -76,7 +77,7 @@ class SecondaryToolbar {
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.documentPropertiesButton,
- eventName: 'documentproperties', close: true, }
+ eventName: 'documentproperties', close: true, },
];
this.items = {
firstPage: options.firstPageButton,
```
2017-06-01 19:46:12 +09:00
|
|
|
viewport: viewport.clone({ dontFlip: true, }),
|
2017-04-24 03:52:58 +09:00
|
|
|
div: this.div,
|
|
|
|
annotations,
|
|
|
|
page: this.pdfPage,
|
2018-02-13 21:17:11 +09:00
|
|
|
imageResourcesPath: this.imageResourcesPath,
|
2017-04-24 03:52:58 +09:00
|
|
|
renderInteractiveForms: this.renderInteractiveForms,
|
|
|
|
linkService: this.linkService,
|
|
|
|
downloadManager: this.downloadManager,
|
2015-11-22 21:56:52 +09:00
|
|
|
};
|
2014-09-30 01:05:28 +09:00
|
|
|
|
2017-04-24 03:52:58 +09:00
|
|
|
if (this.div) {
|
|
|
|
// If an annotationLayer already exists, refresh its children's
|
|
|
|
// transformation matrices.
|
|
|
|
AnnotationLayer.update(parameters);
|
|
|
|
} else {
|
|
|
|
// Create an annotation layer div and render the annotations
|
|
|
|
// if there is at least one annotation.
|
|
|
|
if (annotations.length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.div = document.createElement('div');
|
|
|
|
this.div.className = 'annotationLayer';
|
|
|
|
this.pageDiv.appendChild(this.div);
|
|
|
|
parameters.div = this.div;
|
2015-12-09 07:38:32 +09:00
|
|
|
|
2017-04-24 03:52:58 +09:00
|
|
|
AnnotationLayer.render(parameters);
|
2017-05-04 10:05:53 +09:00
|
|
|
this.l10n.translate(this.div);
|
2014-09-30 01:05:28 +09:00
|
|
|
}
|
2017-04-24 03:52:58 +09:00
|
|
|
});
|
|
|
|
}
|
2015-12-03 08:20:18 +09:00
|
|
|
|
Prevent the `annotationLayer` from, in some cases, becoming duplicated on the first page when the document loads
I don't know if this is a regression, but I noticed earlier today that depending on the initial scale *and* sidebar state, the `annotationLayer` of the first rendered page may end up duplicated; please see screen-shot below.
[screen-shot]
I can reproduce this reliable with e.g. https://arxiv.org/pdf/1112.0542v1.pdf#zoom=page-width&pagemode=bookmarks.
When the document loads, rendering of the first page begins immediately. When the sidebar is then opened, that forces re-rendering which thus aborts rendering of the first page.
Note that calling `PDFPageView.draw()` will always, provided an `AnnotationLayerFactory` instance exists, call `AnnotationLayerBuilder.render()`. Hence the events described above will result in *two* such calls, where the actual annotation rendering/updating happens asynchronously.
For reasons that I don't (at all) understand, when multiple `pdfPage.getAnnotations()` promises are handled back-to-back (in `AnnotationLayerBuilder.render()`), the `this.div` property seems to not update in time for the subsequent calls.
This thus, at least in Firefox, result in double rendering of all annotations on the first page.
Obviously it'd be good to find out why it breaks, since it *really* shouldn't, but this patch at least provides a (hopefully) acceptable work-around by ignoring `getAnnotations()` calls for `AnnotationLayerBuilder` instances that we're destroying (in `PDFPageView.reset()`).
2017-10-07 00:26:54 +09:00
|
|
|
cancel() {
|
|
|
|
this._cancelled = true;
|
|
|
|
}
|
|
|
|
|
2017-04-24 03:52:58 +09:00
|
|
|
hide() {
|
|
|
|
if (!this.div) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.div.setAttribute('hidden', 'true');
|
|
|
|
}
|
|
|
|
}
|
2014-12-18 05:47:14 +09:00
|
|
|
|
|
|
|
/**
|
2015-12-17 20:54:53 +09:00
|
|
|
* @implements IPDFAnnotationLayerFactory
|
2014-12-18 05:47:14 +09:00
|
|
|
*/
|
2017-04-24 03:52:58 +09:00
|
|
|
class DefaultAnnotationLayerFactory {
|
2014-12-18 05:47:14 +09:00
|
|
|
/**
|
|
|
|
* @param {HTMLDivElement} pageDiv
|
|
|
|
* @param {PDFPage} pdfPage
|
2019-10-12 23:30:32 +09:00
|
|
|
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
|
|
|
* for annotation icons. Include trailing slash.
|
2016-09-18 02:44:25 +09:00
|
|
|
* @param {boolean} renderInteractiveForms
|
2017-05-04 10:05:53 +09:00
|
|
|
* @param {IL10n} l10n
|
2015-12-17 20:54:53 +09:00
|
|
|
* @returns {AnnotationLayerBuilder}
|
2014-12-18 05:47:14 +09:00
|
|
|
*/
|
2018-02-13 21:17:11 +09:00
|
|
|
createAnnotationLayerBuilder(pageDiv, pdfPage, imageResourcesPath = '',
|
|
|
|
renderInteractiveForms = false,
|
2017-05-04 10:05:53 +09:00
|
|
|
l10n = NullL10n) {
|
2015-12-17 20:54:53 +09:00
|
|
|
return new AnnotationLayerBuilder({
|
2017-04-24 03:52:58 +09:00
|
|
|
pageDiv,
|
|
|
|
pdfPage,
|
2018-02-13 21:17:11 +09:00
|
|
|
imageResourcesPath,
|
2017-04-24 03:52:58 +09:00
|
|
|
renderInteractiveForms,
|
Simplify the SimpleLinkService and use it to pass in a linkService instance in DefaultAnnotationsLayerFactory
Considering that most methods of `SimpleLinkService` are complete stubs, or practically "useless" considering what they return, we can actually simplify it even more.
*Note:* This depends on the previous patch, that did a small amount of refactoring of `PDFViewer_scrollPageIntoView`, since `PDFViewer.linkService.page` is no longer accessed.
----------
Currently the `pageviewer` components example doesn't work correctly (an error is printed in the console), since no `linkService` is present when the `AnnotationsLayerBuilder` is created.
*Note:* Given that this uses the `SimpleLinkService`, clicking on e.g. internal links won't actually do anything. However, given that internal links (and similar features) are pretty much useless when only *one* page is loaded the `pageviewer` example, I don't think that really matters.
Also, using the complete `PDFLinkService` would require a `PDFViewer` instance. That would significantly complicate the example, thus making it both less clear and less self contained.
2015-06-12 05:20:04 +09:00
|
|
|
linkService: new SimpleLinkService(),
|
2017-05-04 10:05:53 +09:00
|
|
|
l10n,
|
2014-12-18 05:47:14 +09:00
|
|
|
});
|
|
|
|
}
|
2017-04-24 03:52:58 +09:00
|
|
|
}
|
2016-04-09 02:34:27 +09:00
|
|
|
|
2017-03-28 08:07:27 +09:00
|
|
|
export {
|
|
|
|
AnnotationLayerBuilder,
|
|
|
|
DefaultAnnotationLayerFactory,
|
|
|
|
};
|