Cross-browser selection UI injection flow:

  1. Listen for mouseup on body
  2. When triggered, let s be window.getSelection()
  3. If s.isCollapsed === false, return
  4. Else, let r be s.getRangeAt(0)
  5. Create a new element e
  6. Call r.surroundContents(e)
  7. e.innerHTML and e.textContent now return useful values, and e’s coordinates can be used to inject UI into the page

To resolve: what element should e be? Or more accurately, what display property should it have? Possibly inline-block (inline mucks up if selection is across block elements, block mucks up selections within text nodes)

Turns out there are problems with r.surroundContent, namely that it does not handle partial element selections. See MDNs explanation and solution.
updated: