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; | ||||
|   } | ||||
| 
 | ||||
|   #setInternalLink() { | ||||
|     this.container.setAttribute("data-internal-link", ""); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Bind internal links to the link element. | ||||
|    * | ||||
| @ -662,7 +666,7 @@ class LinkAnnotationElement extends AnnotationElement { | ||||
|       return false; | ||||
|     }; | ||||
|     if (destination || destination === /* isTooltipOnly = */ "") { | ||||
|       link.className = "internalLink"; | ||||
|       this.#setInternalLink(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -680,7 +684,7 @@ class LinkAnnotationElement extends AnnotationElement { | ||||
|       this.linkService.executeNamedAction(action); | ||||
|       return false; | ||||
|     }; | ||||
|     link.className = "internalLink"; | ||||
|     this.#setInternalLink(); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -698,7 +702,7 @@ class LinkAnnotationElement extends AnnotationElement { | ||||
|       ); | ||||
|       return false; | ||||
|     }; | ||||
|     link.className = "internalLink"; | ||||
|     this.#setInternalLink(); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -712,7 +716,7 @@ class LinkAnnotationElement extends AnnotationElement { | ||||
|       this.linkService.executeSetOCGState(action); | ||||
|       return false; | ||||
|     }; | ||||
|     link.className = "internalLink"; | ||||
|     this.#setInternalLink(); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -750,7 +754,7 @@ class LinkAnnotationElement extends AnnotationElement { | ||||
|     if (!link.onclick) { | ||||
|       link.onclick = () => false; | ||||
|     } | ||||
|     link.className = "internalLink"; | ||||
|     this.#setInternalLink(); | ||||
|   } | ||||
| 
 | ||||
|   _bindResetFormAction(link, resetForm) { | ||||
| @ -758,7 +762,7 @@ class LinkAnnotationElement extends AnnotationElement { | ||||
|     if (!otherClickAction) { | ||||
|       link.href = this.linkService.getAnchorUrl(""); | ||||
|     } | ||||
|     link.className = "internalLink"; | ||||
|     this.#setInternalLink(); | ||||
| 
 | ||||
|     if (!this._fieldObjects) { | ||||
|       warn( | ||||
|  | ||||
| @ -24,6 +24,7 @@ | ||||
| 
 | ||||
| import { AnnotationLayer } from "pdfjs-lib"; | ||||
| import { NullL10n } from "./l10n_utils.js"; | ||||
| import { PresentationModeState } from "./ui_utils.js"; | ||||
| 
 | ||||
| /** | ||||
|  * @typedef {Object} AnnotationLayerBuilderOptions | ||||
| @ -46,6 +47,8 @@ import { NullL10n } from "./l10n_utils.js"; | ||||
|  */ | ||||
| 
 | ||||
| class AnnotationLayerBuilder { | ||||
|   #onPresentationModeChanged = null; | ||||
| 
 | ||||
|   /** | ||||
|    * @param {AnnotationLayerBuilderOptions} options | ||||
|    */ | ||||
| @ -82,6 +85,7 @@ class AnnotationLayerBuilder { | ||||
| 
 | ||||
|     this.div = null; | ||||
|     this._cancelled = false; | ||||
|     this._eventBus = linkService.eventBus; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -134,11 +138,34 @@ class AnnotationLayerBuilder { | ||||
| 
 | ||||
|       AnnotationLayer.render(parameters); | ||||
|       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() { | ||||
|     this._cancelled = true; | ||||
| 
 | ||||
|     if (this.#onPresentationModeChanged) { | ||||
|       this._eventBus?._off( | ||||
|         "presentationmodechanged", | ||||
|         this.#onPresentationModeChanged | ||||
|       ); | ||||
|       this.#onPresentationModeChanged = null; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   hide() { | ||||
| @ -147,6 +174,29 @@ class AnnotationLayerBuilder { | ||||
|     } | ||||
|     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 }; | ||||
|  | ||||
| @ -61,6 +61,11 @@ class IPDFLinkService { | ||||
|    */ | ||||
|   set rotation(value) {} | ||||
| 
 | ||||
|   /** | ||||
|    * @type {boolean} | ||||
|    */ | ||||
|   get isInPresentationMode() {} | ||||
| 
 | ||||
|   /** | ||||
|    * @type {boolean} | ||||
|    */ | ||||
|  | ||||
| @ -173,6 +173,13 @@ class PDFLinkService { | ||||
|     this.pdfViewer.pagesRotation = value; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @type {boolean} | ||||
|    */ | ||||
|   get isInPresentationMode() { | ||||
|     return this.pdfViewer.isInPresentationMode; | ||||
|   } | ||||
| 
 | ||||
|   #goToDestinationHelper(rawDest, namedDest = null, explicitDest) { | ||||
|     // Dest array looks like that: <page-ref> </XYZ|/FitXXX> <args..>
 | ||||
|     const destRef = explicitDest[0]; | ||||
| @ -673,6 +680,13 @@ class SimpleLinkService { | ||||
|    */ | ||||
|   set rotation(value) {} | ||||
| 
 | ||||
|   /** | ||||
|    * @type {boolean} | ||||
|    */ | ||||
|   get isInPresentationMode() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @param {string|Array} dest - The named, or explicit, PDF destination. | ||||
|    */ | ||||
|  | ||||
| @ -224,12 +224,17 @@ class PDFPresentationMode { | ||||
|       evt.preventDefault(); | ||||
|       return; | ||||
|     } | ||||
|     if (evt.button === 0) { | ||||
|     if (evt.button !== 0) { | ||||
|       return; | ||||
|     } | ||||
|     // Enable clicking of links in presentation mode. Note: only links
 | ||||
|     // pointing to destinations in the current PDF document work.
 | ||||
|       const isInternalLink = | ||||
|         evt.target.href && evt.target.classList.contains("internalLink"); | ||||
|       if (!isInternalLink) { | ||||
|     if ( | ||||
|       evt.target.href && | ||||
|       evt.target.parentNode?.hasAttribute("data-internal-link") | ||||
|     ) { | ||||
|       return; | ||||
|     } | ||||
|     // Unless an internal link was clicked, advance one page.
 | ||||
|     evt.preventDefault(); | ||||
| 
 | ||||
| @ -239,8 +244,6 @@ class PDFPresentationMode { | ||||
|       this.pdfViewer.nextPage(); | ||||
|     } | ||||
|   } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   #contextMenu() { | ||||
|     this.contextMenuOpen = true; | ||||
|  | ||||
| @ -222,8 +222,8 @@ body { | ||||
|   user-select: none; | ||||
| } | ||||
| 
 | ||||
| .pdfPresentationMode:fullscreen a:not(.internalLink) { | ||||
|   display: none; | ||||
| .pdfPresentationMode:fullscreen section:not([data-internal-link]) { | ||||
|   pointer-events: none; | ||||
| } | ||||
| 
 | ||||
| .pdfPresentationMode:fullscreen .textLayer span { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user