2014-04-24 21:23:25 +02:00
|
|
|
/* Copyright 2012 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.
|
|
|
|
*/
|
|
|
|
|
2024-04-03 23:49:06 +04:00
|
|
|
/** @typedef {import("./event_utils.js").EventBus} EventBus */
|
|
|
|
// eslint-disable-next-line max-len
|
|
|
|
/** @typedef {import("./download_manager.js").DownloadManager} DownloadManager */
|
|
|
|
/** @typedef {import("./interfaces.js").IPDFLinkService} IPDFLinkService */
|
|
|
|
// eslint-disable-next-line max-len
|
|
|
|
/** @typedef {import("../src/display/api.js").PDFDocumentProxy} PDFDocumentProxy */
|
|
|
|
|
2020-08-04 12:40:59 +02:00
|
|
|
import { BaseTreeViewer } from "./base_tree_viewer.js";
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
import { SidebarView } from "./ui_utils.js";
|
2016-02-26 12:46:46 +01:00
|
|
|
|
2015-01-27 22:54:14 +01:00
|
|
|
/**
|
2016-02-21 13:36:24 +01:00
|
|
|
* @typedef {Object} PDFOutlineViewerOptions
|
2015-01-27 22:54:14 +01:00
|
|
|
* @property {HTMLDivElement} container - The viewer element.
|
2016-04-25 17:57:15 -05:00
|
|
|
* @property {EventBus} eventBus - The application event bus.
|
2022-10-03 17:55:13 +02:00
|
|
|
* @property {IPDFLinkService} linkService - The navigation/linking service.
|
|
|
|
* @property {DownloadManager} downloadManager - The download manager.
|
2015-01-27 22:54:14 +01:00
|
|
|
*/
|
|
|
|
|
2016-02-21 13:36:24 +01:00
|
|
|
/**
|
|
|
|
* @typedef {Object} PDFOutlineViewerRenderParameters
|
|
|
|
* @property {Array|null} outline - An array of outline objects.
|
2024-04-03 23:49:06 +04:00
|
|
|
* @property {PDFDocumentProxy} pdfDocument - A {PDFDocument} instance.
|
2016-02-21 13:36:24 +01:00
|
|
|
*/
|
|
|
|
|
2020-08-04 12:40:59 +02:00
|
|
|
class PDFOutlineViewer extends BaseTreeViewer {
|
2015-01-27 22:54:14 +01:00
|
|
|
/**
|
2016-02-21 13:36:24 +01:00
|
|
|
* @param {PDFOutlineViewerOptions} options
|
2015-01-27 22:54:14 +01:00
|
|
|
*/
|
2020-08-04 12:40:59 +02:00
|
|
|
constructor(options) {
|
|
|
|
super(options);
|
|
|
|
this.linkService = options.linkService;
|
2022-10-03 17:55:13 +02:00
|
|
|
this.downloadManager = options.downloadManager;
|
2018-10-02 13:08:24 +02:00
|
|
|
|
2020-08-04 12:40:59 +02:00
|
|
|
this.eventBus._on("toggleoutlinetree", this._toggleAllTreeItems.bind(this));
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
this.eventBus._on(
|
|
|
|
"currentoutlineitem",
|
|
|
|
this._currentOutlineItem.bind(this)
|
|
|
|
);
|
|
|
|
|
|
|
|
this.eventBus._on("pagechanging", evt => {
|
|
|
|
this._currentPageNumber = evt.pageNumber;
|
|
|
|
});
|
|
|
|
this.eventBus._on("pagesloaded", evt => {
|
|
|
|
this._isPagesLoaded = !!evt.pagesCount;
|
2021-04-10 12:52:53 +02:00
|
|
|
|
2021-04-11 10:36:46 +02:00
|
|
|
// If the capability is still pending, see the `_dispatchEvent`-method,
|
|
|
|
// we know that the `currentOutlineItem`-button can be enabled here.
|
[api-minor] Replace the `PromiseCapability` with `Promise.withResolvers()`
This replaces our custom `PromiseCapability`-class with the new native `Promise.withResolvers()` functionality, which does *almost* the same thing[1]; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
The only difference is that `PromiseCapability` also had a `settled`-getter, which was however not widely used and the call-sites can either be removed or re-factored to avoid it. In particular:
- In `src/display/api.js` we can tweak the `PDFObjects`-class to use a "special" initial data-value and just compare against that, in order to replace the `settled`-state.
- In `web/app.js` we change the only case to manually track the `settled`-state, which should hopefully be OK given how this is being used.
- In `web/pdf_outline_viewer.js` we can remove the `settled`-checks, since the code should work just fine without it. The only thing that could potentially happen is that we try to `resolve` a Promise multiple times, which is however *not* a problem since the value of a Promise cannot be changed once fulfilled or rejected.
- In `web/pdf_viewer.js` we can remove the `settled`-checks, since the code should work fine without them:
- For the `_onePageRenderedCapability` case the `settled`-check is used in a `EventBus`-listener which is *removed* on its first (valid) invocation.
- For the `_pagesCapability` case the `settled`-check is used in a print-related helper that works just fine with "only" the other checks.
- In `test/unit/api_spec.js` we can change the few relevant cases to manually track the `settled`-state, since this is both simple and *test-only* code.
---
[1] In browsers/environments that lack native support, note [the compatibility data](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers#browser_compatibility), it'll be polyfilled via the `core-js` library (but only in `legacy` builds).
2024-03-28 16:42:37 +01:00
|
|
|
this._currentOutlineItemCapability?.resolve(
|
|
|
|
/* enabled = */ this._isPagesLoaded
|
|
|
|
);
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
});
|
|
|
|
this.eventBus._on("sidebarviewchanged", evt => {
|
|
|
|
this._sidebarView = evt.view;
|
|
|
|
});
|
2014-04-24 21:23:25 +02:00
|
|
|
}
|
|
|
|
|
2017-04-17 17:13:48 +02:00
|
|
|
reset() {
|
2020-08-04 12:40:59 +02:00
|
|
|
super.reset();
|
|
|
|
this._outline = null;
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
|
|
|
|
this._pageNumberToDestHashCapability = null;
|
|
|
|
this._currentPageNumber = 1;
|
2021-12-04 16:48:15 +01:00
|
|
|
this._isPagesLoaded = null;
|
2021-04-10 12:52:53 +02:00
|
|
|
|
[api-minor] Replace the `PromiseCapability` with `Promise.withResolvers()`
This replaces our custom `PromiseCapability`-class with the new native `Promise.withResolvers()` functionality, which does *almost* the same thing[1]; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
The only difference is that `PromiseCapability` also had a `settled`-getter, which was however not widely used and the call-sites can either be removed or re-factored to avoid it. In particular:
- In `src/display/api.js` we can tweak the `PDFObjects`-class to use a "special" initial data-value and just compare against that, in order to replace the `settled`-state.
- In `web/app.js` we change the only case to manually track the `settled`-state, which should hopefully be OK given how this is being used.
- In `web/pdf_outline_viewer.js` we can remove the `settled`-checks, since the code should work just fine without it. The only thing that could potentially happen is that we try to `resolve` a Promise multiple times, which is however *not* a problem since the value of a Promise cannot be changed once fulfilled or rejected.
- In `web/pdf_viewer.js` we can remove the `settled`-checks, since the code should work fine without them:
- For the `_onePageRenderedCapability` case the `settled`-check is used in a `EventBus`-listener which is *removed* on its first (valid) invocation.
- For the `_pagesCapability` case the `settled`-check is used in a print-related helper that works just fine with "only" the other checks.
- In `test/unit/api_spec.js` we can change the few relevant cases to manually track the `settled`-state, since this is both simple and *test-only* code.
---
[1] In browsers/environments that lack native support, note [the compatibility data](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers#browser_compatibility), it'll be polyfilled via the `core-js` library (but only in `legacy` builds).
2024-03-28 16:42:37 +01:00
|
|
|
this._currentOutlineItemCapability?.resolve(/* enabled = */ false);
|
2021-04-10 12:52:53 +02:00
|
|
|
this._currentOutlineItemCapability = null;
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-04-03 23:49:06 +04:00
|
|
|
* @protected
|
2017-04-17 17:13:48 +02:00
|
|
|
*/
|
|
|
|
_dispatchEvent(outlineCount) {
|
[api-minor] Replace the `PromiseCapability` with `Promise.withResolvers()`
This replaces our custom `PromiseCapability`-class with the new native `Promise.withResolvers()` functionality, which does *almost* the same thing[1]; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
The only difference is that `PromiseCapability` also had a `settled`-getter, which was however not widely used and the call-sites can either be removed or re-factored to avoid it. In particular:
- In `src/display/api.js` we can tweak the `PDFObjects`-class to use a "special" initial data-value and just compare against that, in order to replace the `settled`-state.
- In `web/app.js` we change the only case to manually track the `settled`-state, which should hopefully be OK given how this is being used.
- In `web/pdf_outline_viewer.js` we can remove the `settled`-checks, since the code should work just fine without it. The only thing that could potentially happen is that we try to `resolve` a Promise multiple times, which is however *not* a problem since the value of a Promise cannot be changed once fulfilled or rejected.
- In `web/pdf_viewer.js` we can remove the `settled`-checks, since the code should work fine without them:
- For the `_onePageRenderedCapability` case the `settled`-check is used in a `EventBus`-listener which is *removed* on its first (valid) invocation.
- For the `_pagesCapability` case the `settled`-check is used in a print-related helper that works just fine with "only" the other checks.
- In `test/unit/api_spec.js` we can change the few relevant cases to manually track the `settled`-state, since this is both simple and *test-only* code.
---
[1] In browsers/environments that lack native support, note [the compatibility data](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers#browser_compatibility), it'll be polyfilled via the `core-js` library (but only in `legacy` builds).
2024-03-28 16:42:37 +01:00
|
|
|
this._currentOutlineItemCapability = Promise.withResolvers();
|
2021-04-10 12:52:53 +02:00
|
|
|
if (
|
|
|
|
outlineCount === 0 ||
|
|
|
|
this._pdfDocument?.loadingParams.disableAutoFetch
|
|
|
|
) {
|
|
|
|
this._currentOutlineItemCapability.resolve(/* enabled = */ false);
|
2021-12-04 16:48:15 +01:00
|
|
|
} else if (this._isPagesLoaded !== null) {
|
|
|
|
this._currentOutlineItemCapability.resolve(
|
|
|
|
/* enabled = */ this._isPagesLoaded
|
|
|
|
);
|
2021-04-10 12:52:53 +02:00
|
|
|
}
|
|
|
|
|
2017-04-17 17:13:48 +02:00
|
|
|
this.eventBus.dispatch("outlineloaded", {
|
|
|
|
source: this,
|
|
|
|
outlineCount,
|
2021-04-10 12:52:53 +02:00
|
|
|
currentOutlineItemPromise: this._currentOutlineItemCapability.promise,
|
2017-04-17 17:13:48 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-04-03 23:49:06 +04:00
|
|
|
* @protected
|
2017-04-17 17:13:48 +02:00
|
|
|
*/
|
2022-10-03 17:55:13 +02:00
|
|
|
_bindLink(
|
|
|
|
element,
|
|
|
|
{ url, newWindow, action, attachment, dest, setOCGState }
|
|
|
|
) {
|
2019-12-27 00:22:32 +01:00
|
|
|
const { linkService } = this;
|
2018-02-13 14:03:52 +01:00
|
|
|
|
|
|
|
if (url) {
|
2021-09-30 13:30:55 +02:00
|
|
|
linkService.addLinkAttributes(element, url, newWindow);
|
2017-04-17 17:13:48 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-08-30 18:40:27 +02:00
|
|
|
if (action) {
|
|
|
|
element.href = linkService.getAnchorUrl("");
|
|
|
|
element.onclick = () => {
|
|
|
|
linkService.executeNamedAction(action);
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
return;
|
|
|
|
}
|
2022-10-03 17:55:13 +02:00
|
|
|
if (attachment) {
|
|
|
|
element.href = linkService.getAnchorUrl("");
|
|
|
|
element.onclick = () => {
|
|
|
|
this.downloadManager.openOrDownloadData(
|
|
|
|
attachment.content,
|
|
|
|
attachment.filename
|
|
|
|
);
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
return;
|
|
|
|
}
|
2022-08-31 17:50:28 +02:00
|
|
|
if (setOCGState) {
|
|
|
|
element.href = linkService.getAnchorUrl("");
|
|
|
|
element.onclick = () => {
|
|
|
|
linkService.executeSetOCGState(setOCGState);
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
return;
|
|
|
|
}
|
2016-10-22 17:44:17 +02:00
|
|
|
|
2018-02-17 15:08:28 +01:00
|
|
|
element.href = linkService.getDestinationHash(dest);
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
element.onclick = evt => {
|
|
|
|
this._updateCurrentTreeItem(evt.target.parentNode);
|
|
|
|
|
2018-02-13 14:03:52 +01:00
|
|
|
if (dest) {
|
2020-10-03 17:43:33 +02:00
|
|
|
linkService.goToDestination(dest);
|
2016-01-31 16:39:29 +01:00
|
|
|
}
|
2017-04-17 17:13:48 +02:00
|
|
|
return false;
|
|
|
|
};
|
|
|
|
}
|
2016-01-31 16:39:29 +01:00
|
|
|
|
2017-04-17 17:13:48 +02:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2018-02-13 14:03:52 +01:00
|
|
|
_setStyles(element, { bold, italic }) {
|
|
|
|
if (bold) {
|
2020-02-05 22:02:13 +01:00
|
|
|
element.style.fontWeight = "bold";
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
2018-02-13 14:03:52 +01:00
|
|
|
if (italic) {
|
2020-02-05 22:02:13 +01:00
|
|
|
element.style.fontStyle = "italic";
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
|
|
|
}
|
2014-04-24 21:23:25 +02:00
|
|
|
|
2017-04-17 17:13:48 +02:00
|
|
|
/**
|
2024-04-03 23:49:06 +04:00
|
|
|
* @protected
|
2017-04-17 17:13:48 +02:00
|
|
|
*/
|
2019-06-07 12:19:28 +02:00
|
|
|
_addToggleButton(div, { count, items }) {
|
2020-12-09 20:48:36 +01:00
|
|
|
let hidden = false;
|
|
|
|
if (count < 0) {
|
|
|
|
let totalCount = items.length;
|
|
|
|
if (totalCount > 0) {
|
|
|
|
const queue = [...items];
|
|
|
|
while (queue.length > 0) {
|
|
|
|
const { count: nestedCount, items: nestedItems } = queue.shift();
|
|
|
|
if (nestedCount > 0 && nestedItems.length > 0) {
|
|
|
|
totalCount += nestedItems.length;
|
|
|
|
queue.push(...nestedItems);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Math.abs(count) === totalCount) {
|
|
|
|
hidden = true;
|
|
|
|
}
|
|
|
|
}
|
2020-08-04 12:40:59 +02:00
|
|
|
super._addToggleButton(div, hidden);
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
2015-07-21 19:52:49 +02:00
|
|
|
|
2017-04-17 17:13:48 +02:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
2020-08-04 12:40:59 +02:00
|
|
|
_toggleAllTreeItems() {
|
|
|
|
if (!this._outline) {
|
2017-04-17 17:13:48 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-08-04 12:40:59 +02:00
|
|
|
super._toggleAllTreeItems();
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {PDFOutlineViewerRenderParameters} params
|
|
|
|
*/
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
render({ outline, pdfDocument }) {
|
2020-08-04 12:40:59 +02:00
|
|
|
if (this._outline) {
|
2017-04-17 17:13:48 +02:00
|
|
|
this.reset();
|
|
|
|
}
|
2020-08-04 12:40:59 +02:00
|
|
|
this._outline = outline || null;
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
this._pdfDocument = pdfDocument || null;
|
2017-04-17 17:13:48 +02:00
|
|
|
|
|
|
|
if (!outline) {
|
2020-08-04 12:40:59 +02:00
|
|
|
this._dispatchEvent(/* outlineCount = */ 0);
|
2017-04-17 17:13:48 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-12-27 00:22:32 +01:00
|
|
|
const fragment = document.createDocumentFragment();
|
2020-08-04 12:40:59 +02:00
|
|
|
const queue = [{ parent: fragment, items: outline }];
|
|
|
|
let outlineCount = 0,
|
|
|
|
hasAnyNesting = false;
|
2017-04-17 17:13:48 +02:00
|
|
|
while (queue.length > 0) {
|
2019-06-07 12:19:28 +02:00
|
|
|
const levelData = queue.shift();
|
|
|
|
for (const item of levelData.items) {
|
2019-12-27 00:22:32 +01:00
|
|
|
const div = document.createElement("div");
|
2020-08-04 12:40:59 +02:00
|
|
|
div.className = "treeItem";
|
2017-04-17 17:13:48 +02:00
|
|
|
|
2019-12-27 00:22:32 +01:00
|
|
|
const element = document.createElement("a");
|
2017-04-17 17:13:48 +02:00
|
|
|
this._bindLink(element, item);
|
|
|
|
this._setStyles(element, item);
|
2020-08-04 12:40:59 +02:00
|
|
|
element.textContent = this._normalizeTextContent(item.title);
|
2017-04-17 17:13:48 +02:00
|
|
|
|
2022-06-12 12:20:25 +02:00
|
|
|
div.append(element);
|
2017-04-17 17:13:48 +02:00
|
|
|
|
|
|
|
if (item.items.length > 0) {
|
|
|
|
hasAnyNesting = true;
|
2019-06-07 12:19:28 +02:00
|
|
|
this._addToggleButton(div, item);
|
2017-04-17 17:13:48 +02:00
|
|
|
|
2019-12-27 00:22:32 +01:00
|
|
|
const itemsDiv = document.createElement("div");
|
2020-08-04 12:40:59 +02:00
|
|
|
itemsDiv.className = "treeItems";
|
2022-06-12 12:20:25 +02:00
|
|
|
div.append(itemsDiv);
|
2020-08-04 12:40:59 +02:00
|
|
|
|
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 12:46:12 +02:00
|
|
|
queue.push({ parent: itemsDiv, items: item.items });
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
|
|
|
|
2022-06-12 12:20:25 +02:00
|
|
|
levelData.parent.append(div);
|
2017-04-17 17:13:48 +02:00
|
|
|
outlineCount++;
|
|
|
|
}
|
2014-04-24 21:23:25 +02:00
|
|
|
}
|
2019-06-07 12:19:28 +02:00
|
|
|
|
2020-12-28 14:42:47 +01:00
|
|
|
this._finishRendering(fragment, outlineCount, hasAnyNesting);
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Find/highlight the current outline item, corresponding to the active page.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
async _currentOutlineItem() {
|
|
|
|
if (!this._isPagesLoaded) {
|
|
|
|
throw new Error("_currentOutlineItem: All pages have not been loaded.");
|
|
|
|
}
|
|
|
|
if (!this._outline || !this._pdfDocument) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const pageNumberToDestHash = await this._getPageNumberToDestHash(
|
|
|
|
this._pdfDocument
|
|
|
|
);
|
|
|
|
if (!pageNumberToDestHash) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this._updateCurrentTreeItem(/* treeItem = */ null);
|
|
|
|
|
|
|
|
if (this._sidebarView !== SidebarView.OUTLINE) {
|
|
|
|
return; // The outline view is no longer visible, hence do nothing.
|
|
|
|
}
|
|
|
|
// When there is no destination on the current page, always check the
|
|
|
|
// previous ones in (reverse) order.
|
|
|
|
for (let i = this._currentPageNumber; i > 0; i--) {
|
|
|
|
const destHash = pageNumberToDestHash.get(i);
|
|
|
|
if (!destHash) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const linkElement = this.container.querySelector(`a[href="${destHash}"]`);
|
|
|
|
if (!linkElement) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
this._scrollToCurrentTreeItem(linkElement.parentNode);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* To (significantly) simplify the overall implementation, we will only
|
|
|
|
* consider *one* destination per page when finding/highlighting the current
|
|
|
|
* outline item (similar to e.g. Adobe Reader); more specifically, we choose
|
|
|
|
* the *first* outline item at the *lowest* level of the outline tree.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
async _getPageNumberToDestHash(pdfDocument) {
|
|
|
|
if (this._pageNumberToDestHashCapability) {
|
|
|
|
return this._pageNumberToDestHashCapability.promise;
|
|
|
|
}
|
[api-minor] Replace the `PromiseCapability` with `Promise.withResolvers()`
This replaces our custom `PromiseCapability`-class with the new native `Promise.withResolvers()` functionality, which does *almost* the same thing[1]; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
The only difference is that `PromiseCapability` also had a `settled`-getter, which was however not widely used and the call-sites can either be removed or re-factored to avoid it. In particular:
- In `src/display/api.js` we can tweak the `PDFObjects`-class to use a "special" initial data-value and just compare against that, in order to replace the `settled`-state.
- In `web/app.js` we change the only case to manually track the `settled`-state, which should hopefully be OK given how this is being used.
- In `web/pdf_outline_viewer.js` we can remove the `settled`-checks, since the code should work just fine without it. The only thing that could potentially happen is that we try to `resolve` a Promise multiple times, which is however *not* a problem since the value of a Promise cannot be changed once fulfilled or rejected.
- In `web/pdf_viewer.js` we can remove the `settled`-checks, since the code should work fine without them:
- For the `_onePageRenderedCapability` case the `settled`-check is used in a `EventBus`-listener which is *removed* on its first (valid) invocation.
- For the `_pagesCapability` case the `settled`-check is used in a print-related helper that works just fine with "only" the other checks.
- In `test/unit/api_spec.js` we can change the few relevant cases to manually track the `settled`-state, since this is both simple and *test-only* code.
---
[1] In browsers/environments that lack native support, note [the compatibility data](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers#browser_compatibility), it'll be polyfilled via the `core-js` library (but only in `legacy` builds).
2024-03-28 16:42:37 +01:00
|
|
|
this._pageNumberToDestHashCapability = Promise.withResolvers();
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
|
|
|
|
const pageNumberToDestHash = new Map(),
|
|
|
|
pageNumberNesting = new Map();
|
|
|
|
const queue = [{ nesting: 0, items: this._outline }];
|
|
|
|
while (queue.length > 0) {
|
|
|
|
const levelData = queue.shift(),
|
|
|
|
currentNesting = levelData.nesting;
|
|
|
|
for (const { dest, items } of levelData.items) {
|
|
|
|
let explicitDest, pageNumber;
|
|
|
|
if (typeof dest === "string") {
|
|
|
|
explicitDest = await pdfDocument.getDestination(dest);
|
|
|
|
|
|
|
|
if (pdfDocument !== this._pdfDocument) {
|
|
|
|
return null; // The document was closed while the data resolved.
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
explicitDest = dest;
|
|
|
|
}
|
|
|
|
if (Array.isArray(explicitDest)) {
|
|
|
|
const [destRef] = explicitDest;
|
|
|
|
|
2024-04-24 21:55:50 +02:00
|
|
|
if (destRef && typeof destRef === "object") {
|
|
|
|
// The page reference must be available, since the current method
|
|
|
|
// won't be invoked until all pages have been loaded.
|
|
|
|
pageNumber = pdfDocument.cachedPageNumber(destRef);
|
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.
Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:
- The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.
- With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.
- The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.
- Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.
Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.
---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.
[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2020-12-25 12:57:43 +01:00
|
|
|
} else if (Number.isInteger(destRef)) {
|
|
|
|
pageNumber = destRef + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
Number.isInteger(pageNumber) &&
|
|
|
|
(!pageNumberToDestHash.has(pageNumber) ||
|
|
|
|
currentNesting > pageNumberNesting.get(pageNumber))
|
|
|
|
) {
|
|
|
|
const destHash = this.linkService.getDestinationHash(dest);
|
|
|
|
pageNumberToDestHash.set(pageNumber, destHash);
|
|
|
|
pageNumberNesting.set(pageNumber, currentNesting);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (items.length > 0) {
|
|
|
|
queue.push({ nesting: currentNesting + 1, items });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this._pageNumberToDestHashCapability.resolve(
|
|
|
|
pageNumberToDestHash.size > 0 ? pageNumberToDestHash : null
|
|
|
|
);
|
|
|
|
return this._pageNumberToDestHashCapability.promise;
|
|
|
|
}
|
2017-04-17 17:13:48 +02:00
|
|
|
}
|
2016-04-08 12:34:27 -05:00
|
|
|
|
2017-03-28 01:07:27 +02:00
|
|
|
export { PDFOutlineViewer };
|