Add a SelectionView class that can be initialized with a cursor, a
SelectionViewManager that maintains SelectionView instances, and a
shadow cursor object that is an invisible caret-less cursor, fed to both
SessionController and SessionView, which follows the selection as it
changes.
Selections by each cursor are colored according to their memberid
Fix a little issue where partial selections of spans would select the
whole span, and add an explanation
* Add a new ShadowCursor class. This class is meant, for now, to only
hold the 'selected range' fed to it, like with any other OdtCursor. It
provides a minimal OdtCursor-like interface, with only the methods
absolutely required to make it work. It does not modify the DOM in any
way.
* Make the shadowCursor object an instance of ShadowCursor, not
OdtCursor. This is ideal because ShadowCursor does not modify anything
in the DOM, and therefore is safer and faster to use for tracking
browser selections. This makes backwards-selections work finally,
because now there are no anchor nodes to interfere with the selection
whilst dragging.
* With the introduction of the ShadowCursor, we no longer have the
selection range's endpoints coinciding the with beginning and end of the
respective startContainer and endContainer. Therefore, modify
getExtremeRanges to reflect this. If an endpoint of the selection range
does not lie within a TextNode, we latch on to the nearest text node
within.
* In the SessionController, call maintainShadowSelection() if the
selection might leak outside the allowed local root, so that the
window selection object remains root-confined.
* Clone ranges if they may be later modified.
Properly detach ranges once they are used in SelectionView, less
memory leaks.
Rerender visible SelectionViews when certain edits take place.
Adds a visible() method to SelectionView and rerenderSelectionViews to
SelectionViewManager.
Hide lastRect and fillerRect when the selection is just on one line
Workaround for a webkit/blink bug where the clientRects
of a range that is collapsed at the last position of a
text node are empty.
This used to throw lots of errors when computing the
firstRect and lastRect in a SelectionView, when the mouse
moved near the ends of certain textnodes
Added root-filtering of nodes in SelectionView.getFillerRect.
The filler rect is now calculated with extra
granularity, and getFillerRect now has different
code paths for various conditions. The computing
is quite fast because we do not walk over every
single node in the fillerRange, and only look
at the start and end siblings below the common
ancestor element in detail.
This fixes several annoying bugs:
* If you dragged a selection towards the right
just over a blinking cursor, it would extend
to the far right
* Drawing selections over annotation markers
caused them to have bad widths due to rects from
nodes that were not of the same root.
Smarter rerendering of selections in SessionView:
* Unsubscribe from requests to rerender when destroying
* Use an interval-based loop of 200ms to check if a redraw
has been requested, and rerender in that case.
Hide the local caret when a shadowCursor selection
is being drawn
* Make hand-drawn selections have proper direction.
* All cursor classes gain hasForwardSelection() methods.
* maintainCursorSelection now preserves selection direction.