]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fixed touch scrolling issue in Surface and WP devices (#18737)
authorJohannes Tuikkala <johannes@vaadin.com>
Thu, 29 Sep 2016 08:03:29 +0000 (11:03 +0300)
committerVaadin Code Review <review@vaadin.com>
Tue, 8 Nov 2016 11:59:01 +0000 (11:59 +0000)
Fixed by using mouse events instead of touchevents when the browser is
IE or Edge (added isIEOrEdge utility method in the BrowserInfo). Also
added touch-action: none; css rules into escalator.css to prevent
default touch behaviour on IE and Edge
No new unit tests since we do not have automatic touch testing
possibilities yet.
Please test manually with Surface: IE and Edge, use for example uitest:
com.vaadin.tests.components.grid.basics.GridBasics

Change-Id: I5b37f1648e2051ea0ab4d56ab767186b532da07c

client/src/main/java/com/vaadin/client/BrowserInfo.java
client/src/main/java/com/vaadin/client/widgets/Escalator.java
themes/src/main/themes/VAADIN/themes/base/escalator/escalator.scss

index f037fba17513726f3cf4c64f0166e1e73403625c..bce96fe2c7fd74e002eb00e4f244c46516a40ed0 100644 (file)
@@ -245,6 +245,10 @@ public class BrowserInfo {
         return browserDetails.isEdge();
     }
 
+    public boolean isIEOrEdge() {
+        return browserDetails.isIE() || browserDetails.isEdge();
+    }
+
     public boolean isFirefox() {
         return browserDetails.isFirefox();
     }
index 9eaa7ddd3671adf43c356a865bb3316b1f671fae..14c75a00ba03bc22a97bb1e037d4bdbfa1793b36 100644 (file)
@@ -457,6 +457,15 @@ public class Escalator extends Widget
                 }
 
                 int pagePosition(CustomTouchEvent event) {
+                    // Use native event's screen x and y for IEs and Edge
+                    // since there is no touches for these browsers (#18737)
+                    if (BrowserInfo.get().isIEOrEdge()) {
+                        return vertical
+                                ? event.getNativeEvent().getClientY()
+                                        + Window.getScrollTop()
+                                : event.getNativeEvent().getClientX()
+                                        + Window.getScrollLeft();
+                    }
                     JsArray<Touch> a = event.getNativeEvent().getTouches();
                     return vertical ? a.get(0).getPageY() : a.get(0).getPageX();
                 }
@@ -496,7 +505,7 @@ public class Escalator extends Widget
             };
 
             public void touchStart(final CustomTouchEvent event) {
-                if (event.getNativeEvent().getTouches().length() == 1) {
+                if (allowTouch(event)) {
                     if (yMov == null) {
                         yMov = new Movement(true);
                         xMov = new Movement(false);
@@ -544,6 +553,15 @@ public class Escalator extends Widget
                 }
             }
 
+            // Allow touchStart for IE and Edge even though there is no touch
+            // (#18737),
+            // otherwise allow touch only if there is a single touch in the
+            // event
+            private boolean allowTouch(final CustomTouchEvent event) {
+                return BrowserInfo.get().isIEOrEdge()
+                        || event.getNativeEvent().getTouches().length() == 1;
+            }
+
             private double easingInOutCos(double val, double max) {
                 return 0.5 - 0.5 * Math.cos(Math.PI * Math.signum(val)
                         * Math.min(Math.abs(val), max) / max);
@@ -958,7 +976,7 @@ public class Escalator extends Widget
 
         public native void attachTouchListeners(Element element)
         /*
-         * Detaching events with JSNI instead of the GWT event mechanism because
+         * Attaching events with JSNI instead of the GWT event mechanism because
          * GWT didn't provide enough details in events, or triggering the event
          * handlers with GWT bindings was unsuccessful. Maybe, with more time
          * and skill, it could be done with better success. JavaScript overlay
@@ -996,6 +1014,48 @@ public class Escalator extends Widget
             }
         }-*/;
 
+        /**
+         * Using mousedown, mousemove, and mouseup for IE and Edge instead of
+         * touch* listeners (#18737)
+         * 
+         * @param element
+         */
+        public native void attachMouseDragListeners(Element element)
+        /*
+         * Attaching events with JSNI instead of the GWT event mechanism because
+         * GWT didn't provide enough details in events, or triggering the event
+         * handlers with GWT bindings was unsuccessful. Maybe, with more time
+         * and skill, it could be done with better success. JavaScript overlay
+         * types might work. This might also get rid of the JsniWorkaround
+         * class.
+         */
+        /*-{
+            element.addEventListener("mousedown", this.@com.vaadin.client.widgets.JsniWorkaround::touchStartFunction);
+            element.addEventListener("mousemove", this.@com.vaadin.client.widgets.JsniWorkaround::touchMoveFunction);
+            element.addEventListener("mouseup", this.@com.vaadin.client.widgets.JsniWorkaround::touchEndFunction);
+        }-*/;
+
+        /**
+         * Using mousedown, mousemove, and mouseup for IE and Edge instead of
+         * touch* listeners (#18737)
+         * 
+         * @param element
+         */
+        public native void detachMouseDragListeners(Element element)
+        /*
+         * Detaching events with JSNI instead of the GWT event mechanism because
+         * GWT didn't provide enough details in events, or triggering the event
+         * handlers with GWT bindings was unsuccessful. Maybe, with more time
+         * and skill, it could be done with better success. JavaScript overlay
+         * types might work. This might also get rid of the JsniWorkaround
+         * class.
+         */
+        /*-{
+            element.removeEventListener("mousedown", this.@com.vaadin.client.widgets.JsniWorkaround::touchStartFunction);
+            element.removeEventListener("mousemove", this.@com.vaadin.client.widgets.JsniWorkaround::touchMoveFunction);
+            element.removeEventListener("mouseup", this.@com.vaadin.client.widgets.JsniWorkaround::touchEndFunction);
+        }-*/;
+
         public void scrollToColumn(final int columnIndex,
                 final ScrollDestination destination, final int padding) {
             assert columnIndex >= columnConfiguration.frozenColumns : "Can't scroll to a frozen column";
@@ -5772,7 +5832,13 @@ public class Escalator extends Widget
         scroller.attachScrollListener(verticalScrollbar.getElement());
         scroller.attachScrollListener(horizontalScrollbar.getElement());
         scroller.attachMousewheelListener(getElement());
-        scroller.attachTouchListeners(getElement());
+
+        if (BrowserInfo.get().isIEOrEdge()) {
+            // Touch listeners doesn't work for IE and Edge (#18737)
+            scroller.attachMouseDragListeners(getElement());
+        } else {
+            scroller.attachTouchListeners(getElement());
+        }
     }
 
     @Override
@@ -5781,7 +5847,13 @@ public class Escalator extends Widget
         scroller.detachScrollListener(verticalScrollbar.getElement());
         scroller.detachScrollListener(horizontalScrollbar.getElement());
         scroller.detachMousewheelListener(getElement());
-        scroller.detachTouchListeners(getElement());
+
+        if (BrowserInfo.get().isIEOrEdge()) {
+            // Touch listeners doesn't work for IE and Edge (#18737)
+            scroller.detachMouseDragListeners(getElement());
+        } else {
+            scroller.detachTouchListeners(getElement());
+        }
 
         /*
          * We can call paintRemoveRows here, because static ranges are simple to
index 2d5ad729fcc8a2e8ca7978dedfed3b65777148f1..15fda265caa22b985411f856c7199f0d5bf2ef6a 100644 (file)
@@ -75,6 +75,9 @@
   }
 
   .#{$primaryStyleName}-body {
+    -ms-touch-action: none;
+    touch-action: none;
+
     z-index: 0;
     top: 0;