-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
Clear all find highlights when the findbar is closed (issue 7468) #10100
Conversation
@@ -53,11 +53,19 @@ class PDFFindController { | |||
|
|||
this.reset(); | |||
|
|||
eventBus.on('findbarclose', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can implement this feature without tracking any state in the find controller. We should be able to get rid of this active
member variable if the text layer builder listens to the event on the event bus instead and tracks that member variable internally. After all it's a text layer state (whether or not to highlight the matches) and not find controller state (which only produces the matches and leaves the representation to the text layer builder).
In short, can we try removing all changes in this file and introducing this._highlightMatches = true;
in the constructor of the text layer builder, with a listener for the findbarclose
event that toggles this value, and then check this value at https://github.com/mozilla/pdf.js/pull/10100/files#diff-6a8d3c6754c77cfa0876314f0f54bed7R319?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After all it's a text layer state (whether or not to highlight the matches) and not find controller state (which only produces the matches and leaves the representation to the text layer builder).
While I cannot reasonably disagree with any of the above, given that TextLayerBuilder
already have access to PDFFindController
the current solution just seemed like the simplest possible one :-)
In short, can we try removing all changes in this file and introducing
this._highlightMatches = true;
in the constructor of the text layer builder, with a listener for thefindbarclose
event that toggles this value,
There's a slight snag with this suggestion, which is why I went with the current solution:
With the suggested changes there wouldn't be anything resetting this._highlightMatches
for subsequent find operations, thus permanently breaking highlighting of matches once the findbar has been closed just one time.
In order for this to work, you'd basically need to start dispatching an event instead at line
pdf.js/web/pdf_find_controller.js
Line 356 in 54d6c24
this.active = true; |
TextLayerBuilder
instances listen for it in order to set this._highlightMatches = true
. That feels slightly more involved, and there's also the question of what a good event name would be; updatetextlayerhighlight
perhaps?
That should probably work too, although I've not tested it, but at the expense of a bit more event dispatching though. How do you think that we should proceed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having (quickly) tried using events instead, it unfortunately seems that the solution will need to become a bit more complex than current one for things to work out.
Most likely this can all be addressed in a good way, but it's not as easy as one would hope. Besides, there's also the issue described in #10099 (comment) which affects this PR as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My idea was indeed that in the places where we manipulate the this.active
member variable we'd use events instead, so where we set this.active = true/false;
(doing a search sets it to true
and closing the findbar sets it to false
) we dispatch an event instead (updatetextlayerhighlight
seems like a good name to me) and the text layer builder sets this value for the this._highlightMatches
member variable that it tracks to display the highlighted matches or not. I didn't implement it, so it may indeed be a bit more complicated than I can foresee now, but I think that should work so we don't have to do anything in the find controller.
If this does turn out to be more complicated than what I described, can we at least rename active
to highlightMatches
or something similar? I find that a much more descriptive name and then we don't need the extra comment behind its declaration in the reset
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having thought about all the various cases, the conclusion is unfortunately that we still need to track this state in PDFFindController
.
To summarize: There's simply no good way to relay the correct highlight state to all TextLayerBuilder
instances, since they are created lazily; please read on for for additional details.
The important point here is that you need one source of truth, and not multiple, for whether or not find highlights should be displayed. There's only ever going to be one PDFFindController
instance around, but an arbitrary number of TextLayerBuilder
ones (i.e. one per page).
In particular, even attempting to track this in TextLayerBuilder
is basically impossible when you consider all of the cases:
-
Assume that you set
this.highlightMatches = true
in theTextLayerBuilder
constructor.
That means that for currently active pages, i.e. ones in thePDFPageViewBuffer
cache, you'll receive the event to disable the highlights when closing the findbar. However when new pages are scrolled into view, and thus newTextLayerBuilder
instances are created, those will incorrectly have highlights enable since they didn't exist at the point when the events (regardless if those are 'findbarclose' or 'updatetextlayerhighlight') were dispatched. -
Assume instead that
this.highlightMatches = false
is set in theTextLayerBuilder
constructor, and that an event is dispatched whenever searching starts.
Similar to the above, for newTextLayerBuilder
instances created after searching started, no events are received and thus highlights will be permanently disabled in this case.
Furthermore please note that I choose to piggy-back on the 'updatetextlayermatches' event from your PR, for two reasons:
-
First of all, there's fewer events overall that way (and the name fits nicely here as well). Note that this PR alone means that each
TextLayerBuilder
instance registers two event listeners, and with your PR that would have otherwise increased to a total of three events. -
Second of all, by having only
PDFFindController
listen for 'findbarclose' events, there's no longer necessary to worry about the order in which the 'findbarclose' listeners are registered and run, thus guaranteeing thathighlightMatches
has been correctly set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the lazy loading is a really good point which indeed I didn't foresee in my idea. In that case the current code structure seems fine to me!
e86d811
to
7fd3699
Compare
'have been called when page rendering was cancelled.'); | ||
return; | ||
} | ||
for (const name in _boundEvents) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a comment here about why this is necessary? Basically a few lines of summary from the discussion in the other PR so we don't forget the reason why we added this and don't accidentally remove this later without a better alternative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point; please check that the added comment is clear enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good!
7fd3699
to
d5a36da
Compare
…hen rendering is cancelled Also, the patch updates `TextLayerBuilder` to use the new 'pagecancelled' event for (future) event removal purposes.
d5a36da
to
05535b0
Compare
Overall this looks good to me, but I'll do another check in the coming days to make sure I didn't miss anything. We can probably land this first (and create a follow-up issue for |
In all fairness, since your PR was submitted earlier and it's larger too, if you want we could probably land your PR first if you just include my 'pagecancelled' commit there too. Anyway, I'm sorry for blocking your PR like this, but I really don't think it would have been good to (even temporarily) land code that would cause the number of |
Please note that this will require a `mozilla-central` follow-up patch, in order for this to work in the built-in Firefox PDF viewer as well.
05535b0
to
f29b4d1
Compare
/botio-linux preview |
From: Bot.io (Linux m4)ReceivedCommand cmd_preview from @Snuffleupagus received. Current queue size: 0 Live output at: http://54.67.70.0:8877/8cfd0db29365254/output.txt |
From: Bot.io (Linux m4)SuccessFull output at http://54.67.70.0:8877/8cfd0db29365254/output.txt Total script time: 2.97 mins Published |
Thank you for helping out with this! |
Pull request mozilla#10100 removed the last usage of the find controller from the find bar, so we can drop the dependency now.
Please note that this will require a
mozilla-central
follow-up patch, e.g. looking something like this, in order for this to work in the built-in Firefox PDF viewer as well.Fixes #7468.