From ab6969aba1b50647c9cd6d4d55b749fa84c56569 Mon Sep 17 00:00:00 2001 From: Philipp Fromme Date: Tue, 10 Sep 2024 14:56:04 +0200 Subject: [PATCH] fix: do not restore cached when closing on click outside Related to https://github.com/bpmn-io/bpmn-js/pull/2187 --- lib/features/search-pad/SearchPad.js | 32 +++-- .../spec/features/search-pad/SearchPadSpec.js | 122 +++++++++++++----- 2 files changed, 111 insertions(+), 43 deletions(-) diff --git a/lib/features/search-pad/SearchPad.js b/lib/features/search-pad/SearchPad.js index 36fcc462a..1a99891fb 100644 --- a/lib/features/search-pad/SearchPad.js +++ b/lib/features/search-pad/SearchPad.js @@ -90,7 +90,7 @@ SearchPad.prototype._bindEvents = function() { // close search on clicking anywhere outside listen(document, 'html', 'click', function(e) { - self.close(); + self.close(false); }); // stop event from propagating and closing search @@ -136,7 +136,7 @@ SearchPad.prototype._bindEvents = function() { if (isKey('Enter', e)) { var selected = self._getCurrentResult(); - return selected ? self._select(selected) : self.close(); + return selected ? self._select(selected) : self.close(false); } if (isKey('ArrowUp', e)) { @@ -348,23 +348,31 @@ SearchPad.prototype.open = function() { /** * Close search pad. */ -SearchPad.prototype.close = function() { +SearchPad.prototype.close = function(restoreCached = true) { if (!this.isOpen()) { return; } - if (this._cachedRootElement) { - this._canvas.setRootElement(this._cachedRootElement); - } + if (restoreCached) { + if (this._cachedRootElement) { + this._canvas.setRootElement(this._cachedRootElement); + } - if (this._cachedSelection) { - this._selection.select(this._cachedSelection); - } + if (this._cachedSelection) { + this._selection.select(this._cachedSelection); + } + + if (this._cachedViewbox) { + this._canvas.viewbox(this._cachedViewbox); + } - if (this._cachedViewbox) { - this._canvas.viewbox(this._cachedViewbox); + this._eventBus.fire('searchPad.restored'); } + this._cachedRootElement = null; + this._cachedSelection = null; + this._cachedViewbox = null; + this._unbindEvents(); this._open = false; @@ -441,7 +449,7 @@ SearchPad.prototype._select = function(node) { this._cachedSelection = null; this._cachedViewbox = null; - this.close(); + this.close(false); this._canvas.scrollToElement(element, { top: 400 }); diff --git a/test/spec/features/search-pad/SearchPadSpec.js b/test/spec/features/search-pad/SearchPadSpec.js index 1845eaac7..91f925dcf 100644 --- a/test/spec/features/search-pad/SearchPadSpec.js +++ b/test/spec/features/search-pad/SearchPadSpec.js @@ -20,11 +20,12 @@ var EVENTS = { closed: 'searchPad.closed', opened: 'searchPad.opened', preselected: 'searchPad.preselected', + restored: 'searchPad.restored', selected: 'searchPad.selected' }; -describe('features/searchPad', function() { +describe.only('features/searchPad', function() { beforeEach(bootstrapDiagram({ modules: [ searchPadModule ] })); @@ -193,46 +194,90 @@ describe('features/searchPad', function() { })); - it('should close', inject(function(searchPad) { + describe('close', function() { - // given - searchPad.open(); + it('should close and restore', inject(function(searchPad) { - // when - searchPad.close(); + // given + searchPad.open(); - // then - expect(searchPad.isOpen()).to.equal(false); - expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]); - })); + // when + searchPad.close(); + // then + expect(searchPad.isOpen()).to.equal(false); + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.restored, EVENTS.closed ]); + })); - it('should close on ', inject(function(eventBus, searchPad) { - // given - searchPad.open(); + it('should close and not restore', inject(function(searchPad) { - // when - eventBus.fire('drag.init'); + // given + searchPad.open(); - // then - expect(searchPad.isOpen()).to.equal(false); - expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]); - })); + // when + searchPad.close(false); + // then + expect(searchPad.isOpen()).to.equal(false); + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]); + })); - it('should close on ', inject(function(eventBus, searchPad) { - // given - searchPad.open(); + it('should close on and restore', inject(function(eventBus, searchPad) { - // when - eventBus.fire('elements.changed'); + // given + searchPad.open(); - // then - expect(searchPad.isOpen()).to.equal(false); - expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]); - })); + // when + eventBus.fire('drag.init'); + + // then + expect(searchPad.isOpen()).to.equal(false); + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.restored, EVENTS.closed ]); + })); + + + it('should close on and restore', inject(function(eventBus, searchPad) { + + // given + searchPad.open(); + + // when + eventBus.fire('elements.changed'); + + // then + expect(searchPad.isOpen()).to.equal(false); + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.restored, EVENTS.closed ]); + })); + + + it('should close on and restore', inject(function(searchPad) { + + // given + searchPad.open(); + + // when + triggerKeyEvent(input_node, 'keyup', 'Escape'); + + // then + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.restored, EVENTS.closed ]); + })); + + + it('should close on click and not restore', inject(function(canvas, searchPad) { + + // given + searchPad.open(); + + // when + triggerMouseEvent(canvas.getContainer(), 'click', 0, 0); + + // then + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]); + })); + + }); it('should toggle open/close', inject(function(searchPad) { @@ -243,14 +288,14 @@ describe('features/searchPad', function() { // then expect(searchPad.isOpen()).to.equal(false); - expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]); + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.restored, EVENTS.closed ]); // when searchPad.toggle(); // then expect(searchPad.isOpen()).to.equal(true); - expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed, EVENTS.opened ]); + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.restored, EVENTS.closed, EVENTS.opened ]); })); @@ -461,7 +506,7 @@ describe('features/searchPad', function() { // then expect(searchPad.isOpen()).to.equal(false); - expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]); + expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.restored, EVENTS.closed ]); })); @@ -560,6 +605,21 @@ describe('features/searchPad', function() { }); +function triggerMouseEvent(element, eventType, x, y) { + var event = new MouseEvent(eventType, { + view: window, + bubbles: true, + cancelable: true, + clientX: x, + clientY: y + }); + + element.dispatchEvent(event); + + return event; +} + + function triggerKeyEvent(element, eventType, code) { var event = createKeyEvent(code, { type: eventType });