mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-27 12:01:55 +00:00
8b35db3fc1
Check for existence of elements before attaching event listeners in SafariScrollPatcher GitOrigin-RevId: 67338581878871cf67fc050dc233da93f14753a7
117 lines
4.1 KiB
JavaScript
117 lines
4.1 KiB
JavaScript
/* eslint-disable
|
|
max-len,
|
|
no-return-assign,
|
|
no-unused-vars,
|
|
*/
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
// Fix any style issues and re-enable lint.
|
|
/*
|
|
* decaffeinate suggestions:
|
|
* DS102: Remove unnecessary code created because of implicit returns
|
|
* DS207: Consider shorter variations of null checks
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
*/
|
|
let SafariScrollPatcher
|
|
|
|
export default SafariScrollPatcher = class SafariScrollPatcher {
|
|
constructor($scope) {
|
|
this.isOverAce = false // Flag to control if the pointer is over Ace.
|
|
this.pdfDiv = null
|
|
this.aceDiv = null
|
|
|
|
// Start listening to PDF wheel events when the pointer leaves the PDF region.
|
|
// P.S. This is the problem in a nutshell: although the pointer is elsewhere,
|
|
// wheel events keep being dispatched to the PDF.
|
|
this.handlePdfDivMouseLeave = () => {
|
|
return this.pdfDiv.addEventListener('wheel', this.dispatchToAce)
|
|
}
|
|
|
|
// Stop listening to wheel events when the pointer enters the PDF region. If
|
|
// the pointer is over the PDF, native behaviour is adequate.
|
|
this.handlePdfDivMouseEnter = () => {
|
|
return this.pdfDiv.removeEventListener('wheel', this.dispatchToAce)
|
|
}
|
|
|
|
// Set the "pointer over Ace" flag as false, when the mouse leaves its area.
|
|
this.handleAceDivMouseLeave = () => {
|
|
return (this.isOverAce = false)
|
|
}
|
|
|
|
// Set the "pointer over Ace" flag as true, when the mouse enters its area.
|
|
this.handleAceDivMouseEnter = () => {
|
|
return (this.isOverAce = true)
|
|
}
|
|
|
|
// Grab the elements (pdfDiv, aceDiv) and set the "hover" event listeners.
|
|
// If elements are already defined, clear existing event listeners and do
|
|
// the process again (grab elements, set listeners).
|
|
this.setListeners = () => {
|
|
this.isOverAce = false
|
|
|
|
// If elements aren't null, remove existing listeners.
|
|
if (this.pdfDiv != null) {
|
|
this.pdfDiv.removeEventListener(
|
|
'mouseleave',
|
|
this.handlePdfDivMouseLeave
|
|
)
|
|
this.pdfDiv.removeEventListener(
|
|
'mouseenter',
|
|
this.handlePdfDivMouseEnter
|
|
)
|
|
}
|
|
|
|
if (this.aceDiv != null) {
|
|
this.aceDiv.removeEventListener(
|
|
'mouseleave',
|
|
this.handleAceDivMouseLeave
|
|
)
|
|
this.aceDiv.removeEventListener(
|
|
'mouseenter',
|
|
this.handleAceDivMouseEnter
|
|
)
|
|
}
|
|
|
|
// Grab elements.
|
|
this.pdfDiv = document.querySelector('.pdfjs-viewer') // Grab the PDF div.
|
|
this.aceDiv = document.querySelector('.ace_content') // Also the editor.
|
|
|
|
// Set hover-related listeners.
|
|
if (this.pdfDiv != null) {
|
|
this.pdfDiv.addEventListener('mouseleave', this.handlePdfDivMouseLeave)
|
|
this.pdfDiv.addEventListener('mouseenter', this.handlePdfDivMouseEnter)
|
|
}
|
|
if (this.aceDiv != null) {
|
|
this.aceDiv.addEventListener('mouseleave', this.handleAceDivMouseLeave)
|
|
this.aceDiv.addEventListener('mouseenter', this.handleAceDivMouseEnter)
|
|
}
|
|
}
|
|
|
|
// Handler for wheel events on the PDF.
|
|
// If the pointer is over Ace, grab the event, prevent default behaviour
|
|
// and dispatch it to Ace.
|
|
this.dispatchToAce = e => {
|
|
if (this.isOverAce) {
|
|
// If this is logged, the problem just happened: the event arrived
|
|
// here (the PDF wheel handler), but it should've gone to Ace.
|
|
|
|
// Small timeout - if we dispatch immediately, an exception is thrown.
|
|
window.setTimeout(() => {
|
|
// Dispatch the exact same event to Ace (this will keep values
|
|
// values e.g. `wheelDelta` consistent with user interaction).
|
|
return this.aceDiv.dispatchEvent(e)
|
|
}, 1)
|
|
|
|
// Avoid scrolling the PDF, as we assume this was intended to the
|
|
// editor.
|
|
return e.preventDefault()
|
|
}
|
|
}
|
|
|
|
// "loaded" event is emitted from the pdfViewer controller $scope. This means
|
|
// that the previous PDF DOM element was destroyed and a new one is available,
|
|
// so we need to grab the elements and set the listeners again.
|
|
$scope.$on('loaded', () => {
|
|
return this.setListeners()
|
|
})
|
|
}
|
|
}
|