pdf.js/web/annotation_layer_builder.js

136 lines
4.0 KiB
JavaScript
Raw Normal View History

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';
import { NullL10n } from './ui_utils';
2017-04-15 00:32:36 +09:00
import { SimpleLinkService } from './pdf_link_service';
2014-09-30 01:05:28 +09:00
/**
* @typedef {Object} AnnotationLayerBuilderOptions
2014-09-30 01:05:28 +09:00
* @property {HTMLDivElement} pageDiv
* @property {PDFPage} pdfPage
* @property {string} [imageResourcesPath] - Path for image resources, mainly
* for annotation icons. Include trailing slash.
* @property {boolean} renderInteractiveForms
2014-09-30 01:05:28 +09:00
* @property {IPDFLinkService} linkService
* @property {DownloadManager} downloadManager
* @property {IL10n} l10n - Localization service.
2014-09-30 01:05:28 +09:00
*/
class AnnotationLayerBuilder {
2014-09-30 01:05:28 +09:00
/**
* @param {AnnotationLayerBuilderOptions} options
2014-09-30 01:05:28 +09:00
*/
constructor({ pageDiv, pdfPage, linkService, downloadManager,
imageResourcesPath = '', renderInteractiveForms = false,
l10n = NullL10n, }) {
this.pageDiv = pageDiv;
this.pdfPage = pdfPage;
this.linkService = linkService;
this.downloadManager = downloadManager;
this.imageResourcesPath = imageResourcesPath;
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
}
/**
* @param {PageViewport} viewport
* @param {string} intent (default value is 'display')
*/
render(viewport, intent = 'display') {
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;
}
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, }),
div: this.div,
annotations,
page: this.pdfPage,
imageResourcesPath: this.imageResourcesPath,
renderInteractiveForms: this.renderInteractiveForms,
linkService: this.linkService,
downloadManager: this.downloadManager,
};
2014-09-30 01:05:28 +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;
AnnotationLayer.render(parameters);
this.l10n.translate(this.div);
2014-09-30 01:05:28 +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;
}
hide() {
if (!this.div) {
return;
}
this.div.setAttribute('hidden', 'true');
}
}
/**
* @implements IPDFAnnotationLayerFactory
*/
class DefaultAnnotationLayerFactory {
/**
* @param {HTMLDivElement} pageDiv
* @param {PDFPage} pdfPage
* @param {string} [imageResourcesPath] - Path for image resources, mainly
* for annotation icons. Include trailing slash.
* @param {boolean} renderInteractiveForms
* @param {IL10n} l10n
* @returns {AnnotationLayerBuilder}
*/
createAnnotationLayerBuilder(pageDiv, pdfPage, imageResourcesPath = '',
renderInteractiveForms = false,
l10n = NullL10n) {
return new AnnotationLayerBuilder({
pageDiv,
pdfPage,
imageResourcesPath,
renderInteractiveForms,
linkService: new SimpleLinkService(),
l10n,
});
}
}
export {
AnnotationLayerBuilder,
DefaultAnnotationLayerFactory,
};