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

Rewrite selection buffering implementation #2703

Merged
merged 1 commit into from
Nov 6, 2020
Merged

Conversation

robertknight
Copy link
Member

Rewrite the selection change observer in src/annotator/selections to
make it easier to understand how this functionality works and change it
in future (for example, to address issues like #2626 or modify for use with new document types).

The major change is to remove the dependency on the Observable class
provided by zen-observable, which adds cognitive overhead here, isn't used
elsewhere and is stuck on an old version due to subtle breaking changes in newer releases.

Replace it instead with a SelectionObserver class which is modeled
after DOM APIs like MutationObserver. It takes a callback in the
constructor that is invoked with the selected Range or null when the
selection changes and provides a disconnect method which stops
watching for future changes. The implementation only uses DOM APIs.

Rewrite the selection change observer in `src/annotator/selections` to
make it easier to understand how this functionality works and change it
in future.

The major change is to remove the dependency on the `Observable` class
provided by `zen-observable`, which adds cognitive overhead here, isn't used
elsewhere and is stuck on an old version due to subtle breaking changes in newer releases.

Replace it instead with a `SelectionObserver` class which is modeled
after DOM APIs like `MutationObserver`. It takes a callback in the
constructor that is invoked with the selected `Range` or `null` when the
selection changes and provides a `disconnect` method which stops
watching for future changes. The implementation only uses DOM APIs.
@codecov
Copy link

codecov bot commented Nov 5, 2020

Codecov Report

Merging #2703 into master will decrease coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2703      +/-   ##
==========================================
- Coverage   97.73%   97.72%   -0.01%     
==========================================
  Files         200      199       -1     
  Lines        7497     7470      -27     
  Branches     1647     1654       +7     
==========================================
- Hits         7327     7300      -27     
  Misses        170      170              
Impacted Files Coverage Δ
src/annotator/guest.js 88.93% <100.00%> (-0.05%) ⬇️
src/annotator/selection-observer.js 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cacdd63...83161dc. Read the comment docs.

// makes sure that we only report one when the update has stopped
// changing. In this case we want a longer delay.

const delay = event.type === 'mouseup' ? 10 : 100;
Copy link
Contributor

Choose a reason for hiding this comment

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

The delay differences here are explained quite well in the preceding comments and make sense. I am wondering, however, how much user-facing difference there would be (I'm wondering if possibly negligible) if we always used the longer delay, for simplicity's sake. Put another way: how much value does shortening the delay to 10ms add versus the complexity introduced to explain and manage the difference?

Copy link
Member Author

Choose a reason for hiding this comment

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

Its debatable. 100ms is just long enough to be perceptible, so the effect of always using that delay is that it might feel like the adder was fractionally less responsive in showing up when releasing the mouse.

Copy link
Contributor

@lyzadanger lyzadanger left a comment

Choose a reason for hiding this comment

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

This is an improvement on several levels. I...really don't have many comments to add. I like that it reduces dependencies and is comprehensible.

...That's all I got...

}
},

this.selectionObserver = new SelectionObserver(range => {
Copy link
Contributor

Choose a reason for hiding this comment

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

It's a nice little detail that the API surface is consistent in the new observer class, but without the extra layer of "subscribing".

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, using Observable seemed like a nice idea when the API appeared to be on track to be standardized as part of ES. However progress on that stalled.

selections = obs;
return () => {};
});
'./selection-observer': {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nicer to have this mocked instead of faked out here...good...

@robertknight robertknight merged commit f1dd297 into master Nov 6, 2020
@robertknight robertknight deleted the selection-observer branch November 6, 2020 13:30
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