Merge pull request #15648 from Snuffleupagus/issue-12232
Prevent interaction with form elements in PresentationMode (issue 12232)
This commit is contained in:
commit
6193537cd3
@ -645,6 +645,10 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
return this.container;
|
return this.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#setInternalLink() {
|
||||||
|
this.container.setAttribute("data-internal-link", "");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind internal links to the link element.
|
* Bind internal links to the link element.
|
||||||
*
|
*
|
||||||
@ -662,7 +666,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if (destination || destination === /* isTooltipOnly = */ "") {
|
if (destination || destination === /* isTooltipOnly = */ "") {
|
||||||
link.className = "internalLink";
|
this.#setInternalLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,7 +684,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
this.linkService.executeNamedAction(action);
|
this.linkService.executeNamedAction(action);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
link.className = "internalLink";
|
this.#setInternalLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -698,7 +702,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
link.className = "internalLink";
|
this.#setInternalLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -712,7 +716,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
this.linkService.executeSetOCGState(action);
|
this.linkService.executeSetOCGState(action);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
link.className = "internalLink";
|
this.#setInternalLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -750,7 +754,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
if (!link.onclick) {
|
if (!link.onclick) {
|
||||||
link.onclick = () => false;
|
link.onclick = () => false;
|
||||||
}
|
}
|
||||||
link.className = "internalLink";
|
this.#setInternalLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
_bindResetFormAction(link, resetForm) {
|
_bindResetFormAction(link, resetForm) {
|
||||||
@ -758,7 +762,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
if (!otherClickAction) {
|
if (!otherClickAction) {
|
||||||
link.href = this.linkService.getAnchorUrl("");
|
link.href = this.linkService.getAnchorUrl("");
|
||||||
}
|
}
|
||||||
link.className = "internalLink";
|
this.#setInternalLink();
|
||||||
|
|
||||||
if (!this._fieldObjects) {
|
if (!this._fieldObjects) {
|
||||||
warn(
|
warn(
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
import { AnnotationLayer } from "pdfjs-lib";
|
import { AnnotationLayer } from "pdfjs-lib";
|
||||||
import { NullL10n } from "./l10n_utils.js";
|
import { NullL10n } from "./l10n_utils.js";
|
||||||
|
import { PresentationModeState } from "./ui_utils.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AnnotationLayerBuilderOptions
|
* @typedef {Object} AnnotationLayerBuilderOptions
|
||||||
@ -46,6 +47,8 @@ import { NullL10n } from "./l10n_utils.js";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class AnnotationLayerBuilder {
|
class AnnotationLayerBuilder {
|
||||||
|
#onPresentationModeChanged = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AnnotationLayerBuilderOptions} options
|
* @param {AnnotationLayerBuilderOptions} options
|
||||||
*/
|
*/
|
||||||
@ -82,6 +85,7 @@ class AnnotationLayerBuilder {
|
|||||||
|
|
||||||
this.div = null;
|
this.div = null;
|
||||||
this._cancelled = false;
|
this._cancelled = false;
|
||||||
|
this._eventBus = linkService.eventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,11 +138,34 @@ class AnnotationLayerBuilder {
|
|||||||
|
|
||||||
AnnotationLayer.render(parameters);
|
AnnotationLayer.render(parameters);
|
||||||
this.l10n.translate(this.div);
|
this.l10n.translate(this.div);
|
||||||
|
|
||||||
|
// Ensure that interactive form elements in the annotationLayer are
|
||||||
|
// disabled while PresentationMode is active (see issue 12232).
|
||||||
|
if (this.linkService.isInPresentationMode) {
|
||||||
|
this.#updatePresentationModeState(PresentationModeState.FULLSCREEN);
|
||||||
|
}
|
||||||
|
if (!this.#onPresentationModeChanged) {
|
||||||
|
this.#onPresentationModeChanged = evt => {
|
||||||
|
this.#updatePresentationModeState(evt.state);
|
||||||
|
};
|
||||||
|
this._eventBus?._on(
|
||||||
|
"presentationmodechanged",
|
||||||
|
this.#onPresentationModeChanged
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this._cancelled = true;
|
this._cancelled = true;
|
||||||
|
|
||||||
|
if (this.#onPresentationModeChanged) {
|
||||||
|
this._eventBus?._off(
|
||||||
|
"presentationmodechanged",
|
||||||
|
this.#onPresentationModeChanged
|
||||||
|
);
|
||||||
|
this.#onPresentationModeChanged = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
@ -147,6 +174,29 @@ class AnnotationLayerBuilder {
|
|||||||
}
|
}
|
||||||
this.div.hidden = true;
|
this.div.hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#updatePresentationModeState(state) {
|
||||||
|
if (!this.div) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let disableFormElements = false;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case PresentationModeState.FULLSCREEN:
|
||||||
|
disableFormElements = true;
|
||||||
|
break;
|
||||||
|
case PresentationModeState.NORMAL:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const section of this.div.childNodes) {
|
||||||
|
if (section.hasAttribute("data-internal-link")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
section.inert = disableFormElements;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { AnnotationLayerBuilder };
|
export { AnnotationLayerBuilder };
|
||||||
|
@ -61,6 +61,11 @@ class IPDFLinkService {
|
|||||||
*/
|
*/
|
||||||
set rotation(value) {}
|
set rotation(value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isInPresentationMode() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
@ -173,6 +173,13 @@ class PDFLinkService {
|
|||||||
this.pdfViewer.pagesRotation = value;
|
this.pdfViewer.pagesRotation = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isInPresentationMode() {
|
||||||
|
return this.pdfViewer.isInPresentationMode;
|
||||||
|
}
|
||||||
|
|
||||||
#goToDestinationHelper(rawDest, namedDest = null, explicitDest) {
|
#goToDestinationHelper(rawDest, namedDest = null, explicitDest) {
|
||||||
// Dest array looks like that: <page-ref> </XYZ|/FitXXX> <args..>
|
// Dest array looks like that: <page-ref> </XYZ|/FitXXX> <args..>
|
||||||
const destRef = explicitDest[0];
|
const destRef = explicitDest[0];
|
||||||
@ -673,6 +680,13 @@ class SimpleLinkService {
|
|||||||
*/
|
*/
|
||||||
set rotation(value) {}
|
set rotation(value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isInPresentationMode() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string|Array} dest - The named, or explicit, PDF destination.
|
* @param {string|Array} dest - The named, or explicit, PDF destination.
|
||||||
*/
|
*/
|
||||||
|
@ -224,21 +224,24 @@ class PDFPresentationMode {
|
|||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (evt.button === 0) {
|
if (evt.button !== 0) {
|
||||||
// Enable clicking of links in presentation mode. Note: only links
|
return;
|
||||||
// pointing to destinations in the current PDF document work.
|
}
|
||||||
const isInternalLink =
|
// Enable clicking of links in presentation mode. Note: only links
|
||||||
evt.target.href && evt.target.classList.contains("internalLink");
|
// pointing to destinations in the current PDF document work.
|
||||||
if (!isInternalLink) {
|
if (
|
||||||
// Unless an internal link was clicked, advance one page.
|
evt.target.href &&
|
||||||
evt.preventDefault();
|
evt.target.parentNode?.hasAttribute("data-internal-link")
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Unless an internal link was clicked, advance one page.
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
if (evt.shiftKey) {
|
if (evt.shiftKey) {
|
||||||
this.pdfViewer.previousPage();
|
this.pdfViewer.previousPage();
|
||||||
} else {
|
} else {
|
||||||
this.pdfViewer.nextPage();
|
this.pdfViewer.nextPage();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,8 +222,8 @@ body {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pdfPresentationMode:fullscreen a:not(.internalLink) {
|
.pdfPresentationMode:fullscreen section:not([data-internal-link]) {
|
||||||
display: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pdfPresentationMode:fullscreen .textLayer span {
|
.pdfPresentationMode:fullscreen .textLayer span {
|
||||||
|
Loading…
Reference in New Issue
Block a user