MDL-62239 QTYPE: iOS 11.3 broke Moodle drag-drop question types
authorJohn Beedell <jb23347@open.ac.uk>
Mon, 30 Apr 2018 10:33:26 +0000 (11:33 +0100)
committerJohn Beedell <jb23347@open.ac.uk>
Mon, 21 May 2018 10:13:09 +0000 (11:13 +0100)
12 files changed:
question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd-debug.js
question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd-min.js
question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd.js
question/type/ddimageortext/yui/src/ddimageortext/js/ddimageortext.js
question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd-debug.js
question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd-min.js
question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd.js
question/type/ddmarker/yui/src/ddmarker/js/ddmarker.js
question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd-debug.js
question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd-min.js
question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd.js
question/type/ddwtos/yui/src/ddwtos/js/ddwtos.js

index 1048e63..022e28e 100644 (file)
Binary files a/question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd-debug.js and b/question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd-debug.js differ
index 7ebee06..f8ab7a6 100644 (file)
Binary files a/question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd-min.js and b/question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd-min.js differ
index 1048e63..022e28e 100644 (file)
Binary files a/question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd.js and b/question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-dd/moodle-qtype_ddimageortext-dd.js differ
index a165829..979efc6 100644 (file)
@@ -247,7 +247,7 @@ var DDIMAGEORTEXT_QUESTION = function() {
  * This is the code for question rendering.
  */
 Y.extend(DDIMAGEORTEXT_QUESTION, M.qtype_ddimageortext.dd_base_class, {
-    touchscrolldisable: null,
+    passiveSupported: false,
     pendingid: '',
     initializer: function() {
         this.pendingid = 'qtype_ddimageortext-' + Math.random().toString(36).slice(2); // Random string.
@@ -265,6 +265,7 @@ Y.extend(DDIMAGEORTEXT_QUESTION, M.qtype_ddimageortext.dd_base_class, {
                 this.reposition_drags_for_question();
             }, this);
         }
+        this.checkPassiveSupported();
     },
 
     /**
@@ -275,29 +276,36 @@ Y.extend(DDIMAGEORTEXT_QUESTION, M.qtype_ddimageortext.dd_base_class, {
      * draggable items.
      */
     prevent_touchmove_from_scrolling: function(drag) {
-        var touchstart = (Y.UA.ie) ? 'MSPointerStart' : 'touchstart';
-        var touchend = (Y.UA.ie) ? 'MSPointerEnd' : 'touchend';
         var touchmove = (Y.UA.ie) ? 'MSPointerMove' : 'touchmove';
+        var eventHandler = function(event) {
+            event.preventDefault();
+        };
+        var dragId = drag.get('id');
+        var el = document.getElementById(dragId);
+        // Note do not dynamically add events within another event, as this causes issues on iOS11.3.
+        // See https://github.com/atlassian/react-beautiful-dnd/issues/413 and
+        // https://bugs.webkit.org/show_bug.cgi?id=184250 for fuller explanation.
+        el.addEventListener(touchmove, eventHandler, this.passiveSupported ? {passive: false, capture: true} : false);
+    },
 
-        // Disable scrolling when touching the draggable items.
-        drag.on(touchstart, function() {
-            if (this.touchscrolldisable) {
-                return; // Already disabled.
-            }
-            this.touchscrolldisable = Y.one('body').on(touchmove, function(e) {
-                e = e || window.event;
-                e.preventDefault();
+    /**
+     * Some older browsers do not support passing an options object to addEventListener.
+     * This is a check from https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener.
+     */
+    checkPassiveSupported: function() {
+        try {
+            var options = Object.defineProperty({}, 'passive', {
+                get: function() {
+                    this.passiveSupported = true;
+                }.bind(this)
             });
-        }, this);
-
-        // Allow scrolling after releasing the draggable items.
-        drag.on(touchend, function() {
-            if (this.touchscrolldisable) {
-                this.touchscrolldisable.detach();
-                this.touchscrolldisable = null;
-            }
-        }, this);
+            window.addEventListener('test', options, options);
+            window.removeEventListener('test', options, options);
+        } catch (err) {
+            this.passiveSupported = false;
+        }
     },
+
     create_all_drag_and_drops: function() {
         this.init_drops();
         this.update_padding_sizes_all();
index cd19469..c58108d 100644 (file)
Binary files a/question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd-debug.js and b/question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd-debug.js differ
index c15de87..ca407f1 100644 (file)
Binary files a/question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd-min.js and b/question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd-min.js differ
index cd19469..c58108d 100644 (file)
Binary files a/question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd.js and b/question/type/ddmarker/yui/build/moodle-qtype_ddmarker-dd/moodle-qtype_ddmarker-dd.js differ
index b806be6..88cf0f4 100644 (file)
@@ -308,7 +308,7 @@ var DDMARKER_QUESTION = function() {
  * This is the code for question rendering.
  */
 Y.extend(DDMARKER_QUESTION, M.qtype_ddmarker.dd_base_class, {
-    touchscrolldisable: null,
+    passiveSupported: false,
     pendingid: '',
     initializer: function() {
         this.pendingid = 'qtype_ddmarker-' + Math.random().toString(36).slice(2); // Random string.
@@ -317,6 +317,7 @@ Y.extend(DDMARKER_QUESTION, M.qtype_ddmarker.dd_base_class, {
         this.poll_for_image_load(null, false, 0, this.after_image_load);
         this.doc.bg_img().after('load', this.poll_for_image_load, this,
                                                 false, 0, this.after_image_load);
+        this.checkPassiveSupported();
     },
     after_image_load: function() {
         this.redraw_drags_and_drops();
@@ -344,28 +345,34 @@ Y.extend(DDMARKER_QUESTION, M.qtype_ddmarker.dd_base_class, {
      * draggable items.
      */
     prevent_touchmove_from_scrolling: function(drag) {
-        var touchstart = (Y.UA.ie) ? 'MSPointerStart' : 'touchstart';
-        var touchend = (Y.UA.ie) ? 'MSPointerEnd' : 'touchend';
         var touchmove = (Y.UA.ie) ? 'MSPointerMove' : 'touchmove';
+        var eventHandler = function(event) {
+            event.preventDefault();
+        };
+        var dragId = drag.get('id');
+        var el = document.getElementById(dragId);
+        // Note do not dynamically add events within another event, as this causes issues on iOS11.3.
+        // See https://github.com/atlassian/react-beautiful-dnd/issues/413 and
+        // https://bugs.webkit.org/show_bug.cgi?id=184250 for fuller explanation.
+        el.addEventListener(touchmove, eventHandler, this.passiveSupported ? {passive: false, capture: true} : false);
+    },
 
-        // Disable scrolling when touching the draggable items.
-        drag.on(touchstart, function() {
-            if (this.touchscrolldisable) {
-                return; // Already disabled.
-            }
-            this.touchscrolldisable = Y.one('body').on(touchmove, function(e) {
-                e = e || window.event;
-                e.preventDefault();
+    /**
+     * Some older browsers do not support passing an options object to addEventListener.
+     * This is a check from https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener.
+     */
+    checkPassiveSupported: function() {
+        try {
+            var options = Object.defineProperty({}, 'passive', {
+                get: function() {
+                    this.passiveSupported = true;
+                }.bind(this)
             });
-        }, this);
-
-        // Allow scrolling after releasing the draggable items.
-        drag.on(touchend, function() {
-            if (this.touchscrolldisable) {
-                this.touchscrolldisable.detach();
-                this.touchscrolldisable = null;
-            }
-        }, this);
+            window.addEventListener('test', options, options);
+            window.removeEventListener('test', options, options);
+        } catch (err) {
+            this.passiveSupported = false;
+        }
     },
 
     draggable: function(drag) {
index 88f3cb6..eaad12d 100644 (file)
Binary files a/question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd-debug.js and b/question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd-debug.js differ
index 50ec94e..ff5bf8c 100644 (file)
Binary files a/question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd-min.js and b/question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd-min.js differ
index 88f3cb6..eaad12d 100644 (file)
Binary files a/question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd.js and b/question/type/ddwtos/yui/build/moodle-qtype_ddwtos-dd/moodle-qtype_ddwtos-dd.js differ
index b02168e..79fd922 100644 (file)
@@ -32,7 +32,7 @@ var DDWTOS_DD = function() {
  */
 Y.extend(DDWTOS_DD, Y.Base, {
     selectors: null,
-    touchscrolldisable: null,
+    passiveSupported: false,
     initializer: function() {
         var pendingid = 'qtype_ddwtos-' + Math.random().toString(36).slice(2); // Random string.
         M.util.js_pending(pendingid);
@@ -49,6 +49,7 @@ Y.extend(DDWTOS_DD, Y.Base, {
                 this.position_drag_items(pendingid);
             }, this);
         }
+        this.checkPassiveSupported();
     },
     /**
      * put all our selectors in the same place so we can quickly find and change them later
@@ -229,28 +230,34 @@ Y.extend(DDWTOS_DD, Y.Base, {
      * draggable items.
      */
     prevent_touchmove_from_scrolling: function(drag) {
-        var touchstart = (Y.UA.ie) ? 'MSPointerStart' : 'touchstart';
-        var touchend = (Y.UA.ie) ? 'MSPointerEnd' : 'touchend';
         var touchmove = (Y.UA.ie) ? 'MSPointerMove' : 'touchmove';
+        var eventHandler = function(event) {
+            event.preventDefault();
+        };
+        var dragId = drag.get('id');
+        var el = document.getElementById(dragId);
+        // Note do not dynamically add events within another event, as this causes issues on iOS11.3.
+        // See https://github.com/atlassian/react-beautiful-dnd/issues/413 and
+        // https://bugs.webkit.org/show_bug.cgi?id=184250 for fuller explanation.
+        el.addEventListener(touchmove, eventHandler, this.passiveSupported ? {passive: false, capture: true} : false);
+    },
 
-        // Disable scrolling when touching the draggable items.
-        drag.on(touchstart, function() {
-            if (this.touchscrolldisable) {
-                return; // Already disabled.
-            }
-            this.touchscrolldisable = Y.one('body').on(touchmove, function(e) {
-                e = e || window.event;
-                e.preventDefault();
+    /**
+     * Some older browsers do not support passing an options object to addEventListener.
+     * This is a check from https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener.
+     */
+    checkPassiveSupported: function() {
+        try {
+            var options = Object.defineProperty({}, 'passive', {
+                get: function() {
+                    this.passiveSupported = true;
+                }.bind(this)
             });
-        }, this);
-
-        // Allow scrolling after releasing the draggable items.
-        drag.on(touchend, function() {
-            if (this.touchscrolldisable) {
-                this.touchscrolldisable.detach();
-                this.touchscrolldisable = null;
-            }
-        }, this);
+            window.addEventListener('test', options, options);
+            window.removeEventListener('test', options, options);
+        } catch (err) {
+            this.passiveSupported = false;
+        }
     },
 
     make_drop_zones: function() {
@@ -430,4 +437,4 @@ Y.Event.define('dragchange', {
 M.qtype_ddwtos = M.qtype_ddwtos || {};
 M.qtype_ddwtos.init_question = function(config) {
     return new DDWTOS_DD(config);
-};
\ No newline at end of file
+};