The table edition feature of pos_restaurant was using an old lib that was never updated to newer versions of jQuery by its author. For unknown reason, this library went unnoticed when we updated our codebase to jQuery 3. Since this library is impossible to update per se, I decided to remove it entirely and replace it by calls to jQuery.ui. However, the point of this lib was to handle touch events, which jQuery.ui does not. For this, this commit introduces a new library which translates touch events to their click counterparts. Tested on: - Chrome (Windows, MacOS, Linux, Android, iOS) - Firefox (Windows, MacOS, Linux, Android, iOS) - Safari (MacOS, iOS) - Edge (Windows, iOS) - IE11 (Windows) - Samsung Internet (Android) closes odoo/odoo#31719 Signed-off-by: VincentSchippefilt <VincentSchippefilt@users.noreply.github.com>
188 lines
5.6 KiB
JavaScript
188 lines
5.6 KiB
JavaScript
/*!
|
||
* jQuery UI Touch Punch 0.2.3
|
||
*
|
||
* Copyright 2011–2014, Dave Furfero
|
||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||
*
|
||
* Depends:
|
||
* jquery.ui.widget.js
|
||
* jquery.ui.mouse.js
|
||
*/
|
||
(function ($) {
|
||
|
||
// Detect touch support
|
||
$.support.touch = (
|
||
'ontouchend' in document || // Default check
|
||
// Odoo fix for Chrome
|
||
// See: https://github.com/furf/jquery-ui-touch-punch/issues/309
|
||
'ontouchstart' in document ||
|
||
'ontouchstart' in window ||
|
||
navigator.maxTouchPoints > 0 ||
|
||
navigator.msMaxTouchPoints > 0
|
||
);
|
||
|
||
// Ignore browsers without touch support
|
||
if (!$.support.touch) {
|
||
return;
|
||
}
|
||
|
||
var mouseProto = $.ui.mouse.prototype,
|
||
_mouseInit = mouseProto._mouseInit,
|
||
_mouseDestroy = mouseProto._mouseDestroy,
|
||
touchHandled;
|
||
|
||
/**
|
||
* Simulate a mouse event based on a corresponding touch event
|
||
* @param {Object} event A touch event
|
||
* @param {String} simulatedType The corresponding mouse event
|
||
*/
|
||
function simulateMouseEvent (event, simulatedType) {
|
||
|
||
// Ignore multi-touch events
|
||
if (event.originalEvent.touches.length > 1) {
|
||
return;
|
||
}
|
||
|
||
event.preventDefault();
|
||
|
||
var touch = event.originalEvent.changedTouches[0],
|
||
simulatedEvent = document.createEvent('MouseEvents');
|
||
|
||
// Initialize the simulated mouse event using the touch event's coordinates
|
||
simulatedEvent.initMouseEvent(
|
||
simulatedType, // type
|
||
true, // bubbles
|
||
true, // cancelable
|
||
window, // view
|
||
1, // detail
|
||
touch.screenX, // screenX
|
||
touch.screenY, // screenY
|
||
touch.clientX, // clientX
|
||
touch.clientY, // clientY
|
||
false, // ctrlKey
|
||
false, // altKey
|
||
false, // shiftKey
|
||
false, // metaKey
|
||
0, // button
|
||
null // relatedTarget
|
||
);
|
||
|
||
// Dispatch the simulated event to the target element
|
||
event.target.dispatchEvent(simulatedEvent);
|
||
}
|
||
|
||
/**
|
||
* Handle the jQuery UI widget's touchstart events
|
||
* @param {Object} event The widget element's touchstart event
|
||
*/
|
||
mouseProto._touchStart = function (event) {
|
||
|
||
var self = this;
|
||
|
||
// Ignore the event if another widget is already being handled
|
||
if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
|
||
return;
|
||
}
|
||
|
||
// Set the flag to prevent other widgets from inheriting the touch event
|
||
touchHandled = true;
|
||
|
||
// Track movement to determine if interaction was a click
|
||
self._touchMoved = false;
|
||
|
||
// Simulate the mouseover event
|
||
simulateMouseEvent(event, 'mouseover');
|
||
|
||
// Simulate the mousemove event
|
||
simulateMouseEvent(event, 'mousemove');
|
||
|
||
// Simulate the mousedown event
|
||
simulateMouseEvent(event, 'mousedown');
|
||
};
|
||
|
||
/**
|
||
* Handle the jQuery UI widget's touchmove events
|
||
* @param {Object} event The document's touchmove event
|
||
*/
|
||
mouseProto._touchMove = function (event) {
|
||
|
||
// Ignore event if not handled
|
||
if (!touchHandled) {
|
||
return;
|
||
}
|
||
|
||
// Interaction was not a click
|
||
this._touchMoved = true;
|
||
|
||
// Simulate the mousemove event
|
||
simulateMouseEvent(event, 'mousemove');
|
||
};
|
||
|
||
/**
|
||
* Handle the jQuery UI widget's touchend events
|
||
* @param {Object} event The document's touchend event
|
||
*/
|
||
mouseProto._touchEnd = function (event) {
|
||
|
||
// Ignore event if not handled
|
||
if (!touchHandled) {
|
||
return;
|
||
}
|
||
|
||
// Simulate the mouseup event
|
||
simulateMouseEvent(event, 'mouseup');
|
||
|
||
// Simulate the mouseout event
|
||
simulateMouseEvent(event, 'mouseout');
|
||
|
||
// If the touch interaction did not move, it should trigger a click
|
||
if (!this._touchMoved) {
|
||
|
||
// Simulate the click event
|
||
simulateMouseEvent(event, 'click');
|
||
}
|
||
|
||
// Unset the flag to allow other widgets to inherit the touch event
|
||
touchHandled = false;
|
||
};
|
||
|
||
/**
|
||
* A duck punch of the $.ui.mouse _mouseInit method to support touch events.
|
||
* This method extends the widget with bound touch event handlers that
|
||
* translate touch events to mouse events and pass them to the widget's
|
||
* original mouse event handling methods.
|
||
*/
|
||
mouseProto._mouseInit = function () {
|
||
|
||
var self = this;
|
||
|
||
// Delegate the touch handlers to the widget's element
|
||
self.element.bind({
|
||
touchstart: $.proxy(self, '_touchStart'),
|
||
touchmove: $.proxy(self, '_touchMove'),
|
||
touchend: $.proxy(self, '_touchEnd')
|
||
});
|
||
|
||
// Call the original $.ui.mouse init method
|
||
_mouseInit.call(self);
|
||
};
|
||
|
||
/**
|
||
* Remove the touch event handlers
|
||
*/
|
||
mouseProto._mouseDestroy = function () {
|
||
|
||
var self = this;
|
||
|
||
// Delegate the touch handlers to the widget's element
|
||
self.element.unbind({
|
||
touchstart: $.proxy(self, '_touchStart'),
|
||
touchmove: $.proxy(self, '_touchMove'),
|
||
touchend: $.proxy(self, '_touchEnd')
|
||
});
|
||
|
||
// Call the original $.ui.mouse destroy method
|
||
_mouseDestroy.call(self);
|
||
};
|
||
|
||
})(jQuery); |