- fire touch(start|move|end) events after adding clinetX/Y
- use touch events in video and timeline widgets
- use touchstart to select item in ArrayEditable
Even when there is no tooltip, setTooltip() accounts for about 5% of the
time spent setting the values on an ArrayEditable, of which about 2% is
Ox.filter.
There only a few possible sets of events, so use object identity rather
than calculating the set difference. In particular, this is a lot faster
when self.options.tooltip is false-y.
(I think it was actually wrong before, anyway:
bindTooltipEvents({mouseenter, mouseleave})
bindTooltipEvents({mousemove, mouseleave})
would (correctly) unbind mouseenter and bind mousemove, but would set
boundTooltipEvents = {mousemove} even though mouseleave is still bound.)
When changing the visible annotations in the bins in Pandora, creating
(and destroying) all the Ox.Tooltips takes a substantial fraction of the
time. So instead, maintain only one tooltip for each ArrayEditable.
Previously, if the top match for "Smi" was "John Smith", the contents of
the field would be changed to "Smi[n Smith]" (where square brackets
indicate selection). On top of this, if you then type the fourth letter
("n"), the input becomes "Smin", which is not what you typed.
This preserves the "happy path" for replacing the field contents if
there is a prefix match, but without making the field unusable if
there's an infix match.