Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unbind tooltip remove focus listeners #9232

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

hollowM1ke
Copy link
Contributor

My solution for #9071

Copy link
Member

@Falke-Design Falke-Design left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for trying to solve this issue but this solution causes other tests to fail. Please make sure to test if all the tests are successfull. You can do this with npm run test

grafik

@hollowM1ke
Copy link
Contributor Author

hollowM1ke commented Jan 30, 2024

@Falke-Design it is really strange. I get the same tests result on my branch and on main.

So I've run npm run test on my branch and I get the following:
error1

Then I wanted to see if I get any errors on the main branch. And I get this:
error2

Would there be a reason this happens?

@Falke-Design
Copy link
Member

Did you do a re-build? npm run watch

@hollowM1ke
Copy link
Contributor Author

hollowM1ke commented Jan 30, 2024

Did you do a re-build? npm run watch

I've done npm run build and then npm run test. Should I do npm run test and then npm run watch? If yes, then I'm not sure how, because npm run test doesn't terminate and I have to force cancel.

@Falke-Design
Copy link
Member

no, you did it correct. First build and then test.

I will check it the next days by myself. In the mean time you can merge the latest commit from main into your branch

@hollowM1ke
Copy link
Contributor Author

@Falke-Design so I've realized that I forgot to npm run build one more time after changing from my branch to main. That's why I had the same errors appearing. All the tests pass on main no problem. I'm sorry, my mistake. How would I start debugging the tests that fail? Could you give me a starting point? I would appreciate your help.

Copy link
Member

@Falke-Design Falke-Design left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks better now 😄
Can you please try to add a test which covers your changes

Comment on lines 414 to 418
DomEvent.on(el, 'focus', function () {
this._tooltip._source = layer;
this.openTooltip();
}, this);
DomEvent.on(el, 'blur', this.closeTooltip, this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove the events here too

Comment on lines 401 to 409
_handleFocus() {
this._tooltip._source = this;
this.openTooltip();
},

_handleBlur() {
this.closeTooltip();
},

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code exists twice: here and in _addFocusListenersOnLayer

@hollowM1ke
Copy link
Contributor Author

Hi @Falke-Design, could I get an update?

Copy link
Member

@Falke-Design Falke-Design left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for letting you wait so long.
I rewrote the functions, what do you think about it?

Comment on lines +388 to 420
_addFocusListeners(remove) {
if (this.getElement) {
this._addFocusListenersOnLayer(this);
} else if (this.eachLayer) {
this.eachLayer(this._addFocusListenersOnLayer, this);
const el = this.getElement();
if (el) {
const onOff = remove ? 'off' : 'on';
DomEvent[onOff](el, 'focus', () => this._handleFocus(this), this);
DomEvent[onOff](el, 'blur', this._handleBlur, this);
}
} else if (this.eachLayer && this._map.getRenderer(this)) {
this.eachLayer(layer => this._addFocusListenersOnLayer(layer), this);
}
},

_addFocusListenersOnLayer(layer) {
const el = typeof layer.getElement === 'function' && layer.getElement();
if (el) {
DomEvent.on(el, 'focus', function () {
this._tooltip._source = layer;
this.openTooltip();
}, this);
DomEvent.on(el, 'blur', this.closeTooltip, this);
_handleFocus(source) {
if (this._tooltip) {
this._tooltip._source = source;
this.openTooltip();
}
},

_handleBlur() {
this.closeTooltip();
},

_addFocusListenersOnLayer(layer, remove) {
if (layer.getElement) {
const el = layer.getElement();
if (el) {
const onOff = remove ? 'off' : 'on';
DomEvent[onOff](el, 'focus', () => this._handleFocus(layer), this);
DomEvent[onOff](el, 'blur', this._handleBlur, this);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should do the following (or something similar if there is a better way):

  1. _addFocusListeners does the same for a element as _addFocusListenersOnLayer, so we don't duplicate the code.
  2. Then the _handleBlur don't need to be a function anymore, because we can call closeTooltip directly
  3. We store the named function / listener (el._leaflet_focus_handler) for the focus on the element, because an anonymous function / listener can't be removed with off
	_addFocusListeners(remove) {
		if (this.getElement) {
			this._addFocusListenersOnLayer(this, remove);
		} else if (this.eachLayer && this._map.getRenderer(this)) {
			this.eachLayer(layer => this._addFocusListenersOnLayer(layer, remove), this);
		}
	},

	_addFocusListenersOnLayer(layer, remove) {
		const el = typeof layer.getElement === 'function' && layer.getElement();
		if (el) {
			const onOff = remove ? 'off' : 'on';
			if (!remove) {
				// Remove focus listener, if already existing
				el._leaflet_focus_handler && DomEvent.off(el, 'focus', el._leaflet_focus_handler, this);

				el._leaflet_focus_handler = () => {
					if (this._tooltip) {
						this._tooltip._source = layer;
						this.openTooltip();
					}
				};
			}

			el._leaflet_focus_handler && DomEvent[onOff](el, 'focus', el._leaflet_focus_handler, this);
			DomEvent[onOff](el, 'blur', this.closeTooltip, this);

			if (remove) {
				delete el._leaflet_focus_handler;
			}
		}
	},

setTimeout(() => {
expect(() => UIEventSimulator.fire('focus', marker.getElement())).to.not.throw();
}, 2000);
});
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test for a LayerGroup too:

const marker = new Marker(latlng);

			var lg = new LayerGroup([marker]).addTo(map);

			lg
				.bindTooltip('Tooltip that will be unbinded in two seconds')
				.openTooltip()
				.unbindTooltip();


setTimeout(() => {
expect(() => UIEventSimulator.fire('focus', marker.getElement())).to.not.throw();
}, 2000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not wait so long. Maximum of 500ms is allowed, better is earlier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants