diff options
author | Julius Härtl <jus@bitgrid.net> | 2020-11-03 18:01:59 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-03 18:01:59 +0300 |
commit | a6908b82a999454a05c3d4dc1d84fb6ae8efc0a3 (patch) | |
tree | d3c9198b869913add27678042952e6cef32ac538 /core/src | |
parent | 2466902e2a9c933002064089c246f51f3a2006af (diff) | |
parent | f2de58db8cac3c0f10aa4e8e001b0e310be4a73e (diff) |
Merge pull request #23785 from nextcloud/bugfix/21459/workaround-snap-js
Work around snap.js state mess
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/init.js | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/core/src/init.js b/core/src/init.js index d2282beb023..b6bb49346bd 100644 --- a/core/src/init.js +++ b/core/src/init.js @@ -217,18 +217,74 @@ export const initCore = () => { $('#app-content').prepend('<div id="app-navigation-toggle" class="icon-menu" style="display:none" tabindex="0"></div>') - const toggleSnapperOnButton = () => { - if (snapper.state().state === 'left') { - snapper.close() - } else { - snapper.open('left') + // keep track whether snapper is currently animating, and + // prevent to call open or close while that is the case + // to avoid duplicating events (snap.js doesn't check this) + let animating = false + snapper.on('animating', () => { + // we need this because the trigger button + // is also implicitly wired to close by snapper + animating = true + }) + snapper.on('animated', () => { + animating = false + }) + snapper.on('start', () => { + // we need this because dragging triggers that + animating = true + }) + snapper.on('end', () => { + // we need this because dragging stop triggers that + animating = false + }) + + // These are necessary because calling open or close + // on snapper during an animation makes it trigger an + // unfinishable animation, which itself will continue + // triggering animating events and cause high CPU load, + // + // Ref https://github.com/jakiestfu/Snap.js/issues/216 + const oldSnapperOpen = snapper.open + const oldSnapperClose = snapper.close + const _snapperOpen = () => { + if (animating || snapper.state().state !== 'closed') { + return + } + oldSnapperOpen('left') + } + + const _snapperClose = () => { + if (animating || snapper.state().state === 'closed') { + return + } + oldSnapperClose() + } + + // Needs to be deferred to properly catch in-between + // events that snap.js is triggering after dragging. + // + // Skipped when running unit tests as we are not testing + // the snap.js workarounds... + if (!window.TESTING) { + snapper.open = () => { + _.defer(_snapperOpen) + } + snapper.close = () => { + _.defer(_snapperClose) } } - $('#app-navigation-toggle').click(toggleSnapperOnButton) + $('#app-navigation-toggle').click((e) => { + // close is implicit in the button by snap.js + if (snapper.state().state !== 'left') { + snapper.open() + } + }) $('#app-navigation-toggle').keypress(e => { - if (e.which === 13) { - toggleSnapperOnButton() + if (snapper.state().state === 'left') { + snapper.close() + } else { + snapper.open() } }) |