mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-23 19:14:08 +00:00
Merge pull request #291 from sharelatex/pr-workaround-safari-scroll
Workaround for safari scrolling bug
This commit is contained in:
commit
18d0c51da9
2 changed files with 83 additions and 0 deletions
|
@ -9,6 +9,7 @@ define [
|
|||
"ide/pdf/PdfManager"
|
||||
"ide/binary-files/BinaryFilesManager"
|
||||
"ide/references/ReferencesManager"
|
||||
"ide/SafariScrollPatcher"
|
||||
"ide/settings/index"
|
||||
"ide/share/index"
|
||||
"ide/chat/index"
|
||||
|
@ -40,6 +41,7 @@ define [
|
|||
PdfManager
|
||||
BinaryFilesManager
|
||||
ReferencesManager
|
||||
SafariScrollPatcher
|
||||
) ->
|
||||
|
||||
App.controller "IdeController", ($scope, $timeout, ide, localStorage, event_tracking) ->
|
||||
|
@ -135,6 +137,9 @@ define [
|
|||
catch err
|
||||
console.error err
|
||||
|
||||
if ide.browserIsSafari
|
||||
ide.safariScrollPatcher = new SafariScrollPatcher($scope)
|
||||
|
||||
# User can append ?ft=somefeature to url to activate a feature toggle
|
||||
ide.featureToggle = location?.search?.match(/^\?ft=(\w+)$/)?[1]
|
||||
|
||||
|
|
78
services/web/public/coffee/ide/SafariScrollPatcher.coffee
Normal file
78
services/web/public/coffee/ide/SafariScrollPatcher.coffee
Normal file
|
@ -0,0 +1,78 @@
|
|||
define [
|
||||
], () ->
|
||||
class SafariScrollPatcher
|
||||
constructor: ($scope) ->
|
||||
@isOverAce = false # Flag to control if the pointer is over Ace.
|
||||
@pdfDiv = null
|
||||
@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.
|
||||
@handlePdfDivMouseLeave = () =>
|
||||
@pdfDiv.addEventListener "wheel", @dispatchToAce
|
||||
|
||||
# Stop listening to wheel events when the pointer enters the PDF region. If
|
||||
# the pointer is over the PDF, native behaviour is adequate.
|
||||
@handlePdfDivMouseEnter = () =>
|
||||
@pdfDiv.removeEventListener "wheel", @dispatchToAce
|
||||
|
||||
# Set the "pointer over Ace" flag as false, when the mouse leaves its area.
|
||||
@handleAceDivMouseLeave = () =>
|
||||
@isOverAce = false
|
||||
|
||||
# Set the "pointer over Ace" flag as true, when the mouse enters its area.
|
||||
@handleAceDivMouseEnter = () =>
|
||||
@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).
|
||||
@setListeners = () =>
|
||||
@isOverAce = false
|
||||
|
||||
# If elements aren't null, remove existing listeners.
|
||||
if @pdfDiv?
|
||||
@pdfDiv.removeEventListener @handlePdfDivMouseLeave
|
||||
@pdfDiv.removeEventListener @handlePdfDivMouseEnter
|
||||
|
||||
if @aceDiv?
|
||||
@aceDiv.removeEventListener @handleAceDivMouseLeave
|
||||
@aceDiv.removeEventListener @handleAceDivMouseEnter
|
||||
|
||||
# Grab elements.
|
||||
@pdfDiv = document.querySelector ".pdfjs-viewer" # Grab the PDF div.
|
||||
@aceDiv = document.querySelector ".ace_content" # Also the editor.
|
||||
|
||||
# Set hover-related listeners.
|
||||
@pdfDiv.addEventListener "mouseleave", @handlePdfDivMouseLeave
|
||||
@pdfDiv.addEventListener "mouseenter", @handlePdfDivMouseEnter
|
||||
@aceDiv.addEventListener "mouseleave", @handleAceDivMouseLeave
|
||||
@aceDiv.addEventListener "mouseenter", @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.
|
||||
@dispatchToAce = (e) =>
|
||||
if @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).
|
||||
@aceDiv.dispatchEvent e
|
||||
, 1)
|
||||
|
||||
# Avoid scrolling the PDF, as we assume this was intended to the
|
||||
# editor.
|
||||
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", () =>
|
||||
@setListeners()
|
||||
|
||||
|
Loading…
Reference in a new issue