From 9badeaf49d1336a8c8cc003087107086c38b13bc Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Thu, 12 Dec 2019 08:28:05 -0500 Subject: leaflet: fix long-tap in text selection We only track selections with the corner points. This makes checks for where the mouse event is inaccurate, because text selections are rarely squares. Typically, they are rectangles spanning the whole width of the line, and so we need to capture the actual area (which we don't). Here we assume the text is the full width of the document, which is true most of the time, so our check for where we tap. Change-Id: I79d005aa707e29ba90b82cfcbfef1a3cdb08b629 Reviewed-on: https://gerrit.libreoffice.org/85052 Tested-by: Jenkins CollaboraOffice Reviewed-by: Ashod Nakashian --- loleaflet/src/geo/LatLngBounds.js | 29 +++++++++++++++++++++++++++ loleaflet/src/layer/tile/TileLayer.js | 3 +++ loleaflet/src/map/handler/Map.TouchGesture.js | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/loleaflet/src/geo/LatLngBounds.js b/loleaflet/src/geo/LatLngBounds.js index e6f7396a2..80e059750 100644 --- a/loleaflet/src/geo/LatLngBounds.js +++ b/loleaflet/src/geo/LatLngBounds.js @@ -131,6 +131,35 @@ L.LatLngBounds.prototype = { (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng); }, + // Similar to contains() but for line selections, + // where the whole horizontal area is selected. + // This is of course an oversimplification, as + // text can be in a column, but at the moment we + // don't capture the area of text selections, only + // the first and last points. + inBand: function (obj) { + if (typeof obj[0] === 'number' || obj instanceof L.LatLng) { + obj = L.latLng(obj); + } else { + obj = L.latLngBounds(obj); + } + + var sw = this._southWest, + ne = this._northEast, + sw2, ne2; + + if (obj instanceof L.LatLngBounds) { + sw2 = obj.getSouthWest(); + ne2 = obj.getNorthEast(); + } else { + sw2 = ne2 = obj; + } + + // Assume the longitudes are 100% the document width, + // so always matches. + return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat); + }, + intersects: function (bounds) { // (LatLngBounds) bounds = L.latLngBounds(bounds); diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 26afa6c71..0da191937 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -1705,6 +1705,9 @@ L.TileLayer = L.GridLayer.extend({ var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); var bottomRightTwips = topLeftTwips.add(offset); var oldSelection = this._textSelectionStart; + //FIXME: The selection is really not two points, as they can be + //FIXME: on top of each other, but on separate lines. We should + //FIXME: capture the whole area in _onTextSelectionMsg. this._textSelectionStart = new L.LatLngBounds( this._twipsToLatLng(topLeftTwips, this._map.getZoom()), this._twipsToLatLng(bottomRightTwips, this._map.getZoom())); diff --git a/loleaflet/src/map/handler/Map.TouchGesture.js b/loleaflet/src/map/handler/Map.TouchGesture.js index 01544d5de..d682cb4c5 100644 --- a/loleaflet/src/map/handler/Map.TouchGesture.js +++ b/loleaflet/src/map/handler/Map.TouchGesture.js @@ -268,7 +268,7 @@ L.Map.TouchGesture = L.Handler.extend({ if (docLayer._textSelectionStart && docLayer._textSelectionEnd) textSelection = new L.LatLngBounds(docLayer._textSelectionStart.getSouthWest(), docLayer._textSelectionEnd.getNorthEast()); - if ((textSelection && textSelection.contains(latlng)) + if ((textSelection && textSelection.inBand(latlng)) || (graphicSelection && graphicSelection.contains(latlng)) || (cellCursor && cellCursor.contains(latlng))) { // long touched an already selected object -- cgit v1.2.3