Skip to content

Allow additional async redraw even if the first redraw is skipped #3021

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

Merged
merged 3 commits into from
May 10, 2025

Conversation

kfule
Copy link
Contributor

@kfule kfule commented May 7, 2025

Description

This PR allows asynchronous redraw processing even if the first redraw is skipped by setting event.redraw=false before await in the async function.
Also, this PR avoids redraw after the dom or component is removed.

Motivation and Context

This PR is intended to address the following cases of zulip

If it was set to false before the first await and then true after it, the first redraw should be skipped, but the second one shouldn't.

In #3020 , I didn't consider the case where event.redraw would later be true.

How Has This Been Tested?

npm run test with additional test

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My change requires a documentation update, and I've opened a pull request to update it already:
  • I have read https://mithril.js.org/contributing.html.

@kfule kfule requested a review from a team as a code owner May 7, 2025 12:56
Copy link
Member

@dead-claudia dead-claudia left a comment

Choose a reason for hiding this comment

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

I missed this during the first review, but while we're at it, can you make sure to skip redraws after the component is removed, so removals don't trigger further redraws? (This bug also exists with sync event handlers, being able to fire events post-removal, and we should fix both in a single step.)

You should be able to get away with just doing this:

  1. Add a if (self._ != null) check to the condition in the resolver handler where self is the outer event listener object.
  2. Add an if (vnode.events != null) vnode.events._ = null right before this line.

That'd fix both.

@kfule
Copy link
Contributor Author

kfule commented May 9, 2025

@dead-claudia Thanks for your review.
As you suggested, I have changed the code so that it does not redraw after removing a dom or component (with the tests.)

With this commit, I removed the eventRedraw variable that holds this._, because self holds this. (i.e., changed the code to look like the old (0, this._) ())

@kfule kfule requested a review from dead-claudia May 9, 2025 10:28
@kfule kfule force-pushed the true-after-await branch from 2c5a545 to 8c3734b Compare May 9, 2025 14:28
@kfule
Copy link
Contributor Author

kfule commented May 9, 2025

@dead-claudia
This is not directly related to this PR, but it appears that the number of assertions in Test and maybe release / run-tests / test-node is the number of main branch (16789 assertions) and not the number of branches in this PR (just 16800 assertions).
The appropriate branch may not have been checked out in the test Actions.

I was curious about the difference in the number of assertions, so I rebased the commits just to be sure, but the result was not changed.


Edit: The number of assertions may have been different for #3020.

@dead-claudia
Copy link
Member

@dead-claudia

This is not directly related to this PR, but it appears that the number of assertions in Test and maybe release / run-tests / test-node is the number of main branch (16789 assertions) and not the number of branches in this PR (just 16800 assertions).

The appropriate branch may not have been checked out in the test Actions.

That's a good catch. Filed MithrilJS/infra#69 to track it down. (This is in a common workflow script.)

Copy link
Member

@dead-claudia dead-claudia left a comment

Choose a reason for hiding this comment

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

See comments.

Should hopefully be the last request for changes.

@@ -884,4 +916,48 @@ o.spec("event", function() {
})
})
})
o("avoid sync redraw after removal", function() {
Copy link
Member

Choose a reason for hiding this comment

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

Can you extend this test to also verify the event listener itself wasn't called?

That way, we know it couldn't possibly attempt an async redraw later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added assertions about whether the event listener itself was called or not.

The event listener itself is not removed and will be called, but it should be clearer that redraw is not being called.

Comment on lines +943 to +945
o(redraw.callCount).equals(1)
o(redraw.this).equals(undefined)
o(redraw.args.length).equals(0)
Copy link
Member

Choose a reason for hiding this comment

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

Can you also assert thenCB is set? That being set also implies that the event listener was actually called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, added the following assertions.

  • Whether the event listener itself has been called or not.
  • Whether thenCB was set or not.

render(root, div)
div.dom.dispatchEvent(e)

o(redraw.callCount).equals(0)
Copy link
Member

Choose a reason for hiding this comment

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

Can you also assert thenCB is set? That being set also implies that the event listener was actually called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ditto

This makes it clear that the event listener is being called but redraw is not being called.
@kfule kfule requested a review from dead-claudia May 9, 2025 23:52
@kfule
Copy link
Contributor Author

kfule commented May 9, 2025

@dead-claudia Thanks for your kind review.
I added assertions about whether the event listeners themselves were called or not where redraw would not be called.

Of course I have confirmed all tests pass (with my local npm run test).

@dead-claudia dead-claudia merged commit a239c77 into MithrilJS:main May 10, 2025
7 checks passed
@JAForbes JAForbes mentioned this pull request May 10, 2025
@kfule kfule deleted the true-after-await branch May 28, 2025 13:25
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.

2 participants