Skip to content

Text Fragments from highlight experimental feature#1504

Draft
schu96 wants to merge 4 commits intointernetarchive:masterfrom
schu96:text-selection-experimental
Draft

Text Fragments from highlight experimental feature#1504
schu96 wants to merge 4 commits intointernetarchive:masterfrom
schu96:text-selection-experimental

Conversation

@schu96
Copy link
Collaborator

@schu96 schu96 commented Feb 2, 2026

Closes #1363

Should allow users to highlight within the bookreader's text and generate a link with URI encoded parameters. The link is automatically copied to the user's clipboard and available for sharing with fellow patrons or new readers.

A test suite that validates the text fragment generation work is partially completed, just need some more specific example data to cover the remaining cases

@codecov
Copy link

codecov bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 45.39007% with 77 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.14%. Comparing base (5c571e0) to head (db40a5c).

Files with missing lines Patch % Lines
src/util/TextSelectionManager.js 49.05% 54 Missing ⚠️
src/plugins/url/UrlPlugin.js 28.57% 15 Missing ⚠️
src/plugins/url/plugin.url.js 38.46% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1504      +/-   ##
==========================================
- Coverage   69.70%   69.14%   -0.56%     
==========================================
  Files          65       65              
  Lines        5373     5496     +123     
  Branches     1182     1209      +27     
==========================================
+ Hits         3745     3800      +55     
- Misses       1594     1662      +68     
  Partials       34       34              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@cdrini cdrini left a comment

Choose a reason for hiding this comment

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

  1. We should put this behind a plugin.experiment for "show highlight menu" ; see https://github.com/internetarchive/bookreader/pull/1481/files for example of how we might do this
  2. We'll need this to work with the urlMode = history that prod uses; I'll set up a testbed for that.
  3. Use a different icon / designs

Comment on lines +182 to 184
$(document.body).on('mouseup', (_) => {
this.hlightBarEl?.remove();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll want to make sure this is only attached once, otherwise it'll cause a memory leak, with the event listener created every time there's a new text layer made.

});
}

highlightToolbar(_) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we will want this toolbar to be a lit element, eg @customElement('br-highlight-bar') class HighlightBar extends LitElement {...}.

That will let us use reactivity, and do some other things. Useful things to note for lit:

  1. Use can use the connectedCallback and disconnectedCallback methods to fire when the element is eg "mounted" and "unmounted" from the DOM. This would be a good place to attach the document.body click listener.
  2. In BookReader we tend not to use shadow dom, so you'll want to add createRenderRoot() { return null; } to disable it for now. This will let you use logic similar to what you currently have, and let you put all the css inside our normal existing scss files. Note since we're not using the shadow dom, IDs and css classes will be global/accessible from the scss, like the default.

Then all the rendering logic will become

const highlightBar = document.createElement('br-highlight-bar');

import { SelectionObserver } from "../BookReader/utils/SelectionObserver.js";

export class TextSelectionManager {
hlightBarEl;
Copy link
Contributor

Choose a reason for hiding this comment

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

Inside the constructor, we can construct a single copy of this. Then the click handler should never have to reconstruct it ; it'll just change its position, and remove/append into the document.body or instead display:none .

this.highlightBar = document.createElement('br-highlight-bar');

@@ -156,17 +157,86 @@ export class TextSelectionManager {
$(textLayer).off(".textSelectPluginHandler");

$(textLayer).on("mousedown.textSelectPluginHandler", (event) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

mousedown/mouseup appear not to fire on mobile ; not getting the menu appearing on firefox/chrome on android. Maybe we can instead use the helper SelectionObserver class? That fires a started event and a cleared event we can use to show/hide the toolbar.

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.

Prototype an Open Library Citation Embed feature (experimental)

2 participants