summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-01-03 00:12:54 +0100
committerGitHub <noreply@github.com>2018-01-03 00:12:54 +0100
commit9d43724d455d5c538b000529f223b101fb1b7c9c (patch)
tree00c5d2d10b0ef9af3c6ff7c268d29d274dd558a4 /core
parent7fdd9097bb8cfa4a5d3afe161e1ee2a71da3a8eb (diff)
parentde4028336aca79ab243fc0d1ad3a904d4cc72299 (diff)
downloadnextcloud-server-9d43724d455d5c538b000529f223b101fb1b7c9c.tar.gz
nextcloud-server-9d43724d455d5c538b000529f223b101fb1b7c9c.zip
Merge pull request #7526 from nextcloud/make-possible-for-apps-to-disable-the-navigation-bar-slide-gesture
Make possible for apps to disable the navigation bar slide gesture
Diffstat (limited to 'core')
-rw-r--r--core/js/js.js37
-rw-r--r--core/js/tests/specs/coreSpec.js427
-rw-r--r--core/vendor/core.js6
-rw-r--r--core/vendor/snapjs/dist/latest/snap.js6
4 files changed, 473 insertions, 3 deletions
diff --git a/core/js/js.js b/core/js/js.js
index 9af80676d5e..a9180663405 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -1612,12 +1612,47 @@ function initCore() {
snapper.close();
});
+ var navigationBarSlideGestureEnabled = false;
+ var navigationBarSlideGestureAllowed = true;
+ var navigationBarSlideGestureEnablePending = false;
+
+ OC.allowNavigationBarSlideGesture = function() {
+ navigationBarSlideGestureAllowed = true;
+
+ if (navigationBarSlideGestureEnablePending) {
+ snapper.enable();
+
+ navigationBarSlideGestureEnabled = true;
+ navigationBarSlideGestureEnablePending = false;
+ }
+ };
+
+ OC.disallowNavigationBarSlideGesture = function() {
+ navigationBarSlideGestureAllowed = false;
+
+ if (navigationBarSlideGestureEnabled) {
+ var endCurrentDrag = true;
+ snapper.disable(endCurrentDrag);
+
+ navigationBarSlideGestureEnabled = false;
+ navigationBarSlideGestureEnablePending = true;
+ }
+ };
+
var toggleSnapperOnSize = function() {
if($(window).width() > 768) {
snapper.close();
snapper.disable();
- } else {
+
+ navigationBarSlideGestureEnabled = false;
+ navigationBarSlideGestureEnablePending = false;
+ } else if (navigationBarSlideGestureAllowed) {
snapper.enable();
+
+ navigationBarSlideGestureEnabled = true;
+ navigationBarSlideGestureEnablePending = false;
+ } else {
+ navigationBarSlideGestureEnablePending = true;
}
};
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 9848fb46ffc..b6c617303cf 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -1112,4 +1112,431 @@ describe('Core base tests', function() {
expect(OC._ajaxConnectionLostHandler.calls.count()).toBe(1);
});
});
+ describe('Snapper', function() {
+ var snapConstructorStub;
+ var snapperStub;
+ var clock;
+
+ beforeEach(function() {
+ snapConstructorStub = sinon.stub(window, 'Snap');
+
+ snapperStub = {};
+ snapperStub.enable = sinon.stub();
+ snapperStub.disable = sinon.stub();
+ snapperStub.close = sinon.stub();
+
+ snapConstructorStub.returns(snapperStub);
+
+ clock = sinon.useFakeTimers();
+
+ // _.now could have been set to Date.now before Sinon replaced it
+ // with a fake version, so _.now must be stubbed to ensure that the
+ // fake Date.now will be called instead of the original one.
+ _.now = sinon.stub(_, 'now').callsFake(function() {
+ return new Date().getTime();
+ });
+
+ $('#testArea').append('<div id="app-navigation">The navigation bar</div><div id="app-content">Content</div>');
+ });
+ afterEach(function() {
+ snapConstructorStub.restore();
+
+ clock.restore();
+
+ _.now.restore();
+
+ // Remove the event handler for the resize event added to the window
+ // due to calling window.initCore() when there is an #app-navigation
+ // element.
+ $(window).off('resize');
+
+ viewport.reset();
+ });
+
+ it('is enabled on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapConstructorStub.calledOnce).toBe(true);
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ });
+ it('is disabled when disallowing the gesture on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is not disabled again when disallowing the gesture twice on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is enabled when allowing the gesture after disallowing it on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledTwice).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is not enabled again when allowing the gesture twice after disallowing it on a narrow screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.disable.alwaysCalledWithExactly(true)).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledTwice).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledTwice).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.called).toBe(false);
+ });
+ it('is disabled on a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapConstructorStub.calledOnce).toBe(true);
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is not disabled again when disallowing the gesture on a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is not enabled when allowing the gesture after disallowing it on a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is enabled when resizing to a narrow screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is not enabled when resizing to a narrow screen after disallowing the gesture', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is enabled when resizing to a narrow screen after disallowing the gesture and allowing it', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is enabled when allowing the gesture after disallowing it and resizing to a narrow screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ });
+ it('is disabled when disallowing the gesture after disallowing it, resizing to a narrow screen and allowing it', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledTwice).toBe(true);
+ expect(snapperStub.disable.getCall(1).calledWithExactly(true)).toBe(true);
+ });
+ it('is disabled when resizing to a wide screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ viewport.set(1280);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is not disabled again when disallowing the gesture after resizing to a wide screen', function() {
+ viewport.set(480);
+
+ window.initCore();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.called).toBe(false);
+ expect(snapperStub.close.called).toBe(false);
+
+ viewport.set(1280);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.calledOnce).toBe(true);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+ });
+ it('is not enabled when allowing the gesture after disallowing it, resizing to a narrow screen and resizing to a wide screen', function() {
+ viewport.set(1280);
+
+ window.initCore();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ OC.disallowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ viewport.set(480);
+
+ // Setting the viewport width does not automatically trigger a
+ // resize.
+ $(window).resize();
+
+ // The resize handler is debounced to be executed a few milliseconds
+ // after the resize event.
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledOnce).toBe(true);
+ expect(snapperStub.close.calledOnce).toBe(true);
+
+ viewport.set(1280);
+
+ $(window).resize();
+
+ clock.tick(1000);
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledTwice).toBe(true);
+ expect(snapperStub.close.calledTwice).toBe(true);
+
+ OC.allowNavigationBarSlideGesture();
+
+ expect(snapperStub.enable.called).toBe(false);
+ expect(snapperStub.disable.calledTwice).toBe(true);
+ expect(snapperStub.close.calledTwice).toBe(true);
+ });
+ });
});
diff --git a/core/vendor/core.js b/core/vendor/core.js
index bda270892ad..e573ef10642 100644
--- a/core/vendor/core.js
+++ b/core/vendor/core.js
@@ -6704,9 +6704,13 @@ dav.Client.prototype = {
/**
* Disables Snap.js events
+ * @param {Boolean} endCurrentDrag Whether to end the current drag (if any) or not.
*/
- disable: function() {
+ disable: function(endCurrentDrag) {
utils.dispatchEvent('disable');
+ if (endCurrentDrag) {
+ this.action.drag.endDrag();
+ }
this.action.drag.stopListening();
},
diff --git a/core/vendor/snapjs/dist/latest/snap.js b/core/vendor/snapjs/dist/latest/snap.js
index a0274138de0..7ae088d0aea 100644
--- a/core/vendor/snapjs/dist/latest/snap.js
+++ b/core/vendor/snapjs/dist/latest/snap.js
@@ -744,9 +744,13 @@
/**
* Disables Snap.js events
+ * @param {Boolean} endCurrentDrag Whether to end the current drag (if any) or not.
*/
- disable: function() {
+ disable: function(endCurrentDrag) {
utils.dispatchEvent('disable');
+ if (endCurrentDrag) {
+ this.action.drag.endDrag();
+ }
this.action.drag.stopListening();
},