[Libreoffice-commits] online.git: loleaflet/build loleaflet/src
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Fri May 10 10:41:16 UTC 2019
loleaflet/build/deps.js | 2
loleaflet/src/control/Control.Tabs.js | 52 ++++++-----
loleaflet/src/dom/DomEvent.LongTap.js | 148 ++++++++++++++++++++++++++++++++++
3 files changed, 177 insertions(+), 25 deletions(-)
New commits:
commit d6fe8ff0856170d922d29dbb869496dd24aab233
Author: Iván Sánchez Ortega <ivan.sanchez at collabora.com>
AuthorDate: Fri May 10 11:54:52 2019 +0200
Commit: Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Fri May 10 12:40:58 2019 +0200
loleaflet: Make Calc sheet context menu work on iOS safari
This is done with a combination of a 'contextment' event shim in
loleaflet/src/dom/DomEvent.LongTap.js, mimicking the technique from
loleaflet/src/map/handler/Map.Tap.js, and triggering the jQuery
contextmenu manually from such a shimmed 'contextmenu'.
Change-Id: I5cba975b7a5559315c91a8bf4c9a5ced00dfc6e1
Reviewed-on: https://gerrit.libreoffice.org/72115
Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
Tested-by: Szymon Kłos <szymon.klos at collabora.com>
diff --git a/loleaflet/build/deps.js b/loleaflet/build/deps.js
index 5a1650e22..4e18f1989 100644
--- a/loleaflet/build/deps.js
+++ b/loleaflet/build/deps.js
@@ -356,6 +356,8 @@ var deps = {
ControlTabs: {
src: ['control/Control.js',
+ 'dom/DomEvent.js',
+ 'dom/DomEvent.LongTap.js',
'control/Control.Tabs.js'],
heading: 'Controls',
desc: 'Tabs for switching sheets'
diff --git a/loleaflet/src/control/Control.Tabs.js b/loleaflet/src/control/Control.Tabs.js
index e173c2bac..d120bb08a 100644
--- a/loleaflet/src/control/Control.Tabs.js
+++ b/loleaflet/src/control/Control.Tabs.js
@@ -20,7 +20,7 @@ L.Control.Tabs = L.Control.extend({
}
setTimeout(function() {
$('.spreadsheet-tab').contextMenu(e.perm === 'edit');
- }, 1000);
+ }, 100);
if (window.mode.isMobile() == true) {
if (e.perm === 'edit') {
@@ -38,36 +38,28 @@ L.Control.Tabs = L.Control.extend({
this._initialized = true;
this._tabsInitialized = false;
this._spreadsheetTabs = {};
+ this._tabForContextMenu = 0;
var map = this._map;
var docContainer = map.options.documentContainer;
this._tabsCont = L.DomUtil.create('div', 'spreadsheet-tabs-container', docContainer.parentElement);
- L.DomEvent.on(this._tabsCont, 'touchstart',
- function (e) {
- if (e && e.touches.length > 1) {
- L.DomEvent.preventDefault(e);
- }
- },
- this);
$.contextMenu({
selector: '.spreadsheet-tab',
className: 'loleaflet-font',
- callback: function(key, options) {
- var nPos = parseInt(options.$trigger.attr('id').split('spreadsheet-tab')[1]);
-
+ callback: (function(key) {
if (key === 'insertsheetbefore') {
- map.insertPage(nPos);
+ map.insertPage(this._tabForContextMenu);
}
if (key === 'insertsheetafter') {
- map.insertPage(nPos + 1);
+ map.insertPage(this._tabForContextMenu + 1);
}
- },
+ }).bind(this),
items: {
'insertsheetbefore': {name: _('Insert sheet before this')},
'insertsheetafter': {name: _('Insert sheet after this')},
'deletesheet': {name: _UNO('.uno:Remove', 'spreadsheet', true),
- callback: function(key, options) {
- var nPos = parseInt(options.$trigger.attr('id').split('spreadsheet-tab')[1]);
+ callback: (function(key, options) {
+ var nPos = this._tabForContextMenu;
vex.dialog.confirm({
message: _('Are you sure you want to delete sheet, %sheet% ?').replace('%sheet%', options.$trigger.text()),
callback: function(data) {
@@ -76,11 +68,11 @@ L.Control.Tabs = L.Control.extend({
}
}
});
- }
+ }).bind(this)
},
'renamesheet': {name: _UNO('.uno:RenameTable', 'spreadsheet', true),
- callback: function(key, options) {
- var nPos = parseInt(options.$trigger.attr('id').split('spreadsheet-tab')[1]);
+ callback: (function(key, options) {
+ var nPos = this._tabForContextMenu;
vex.dialog.open({
message: _('Enter new sheet name'),
input: '<input name="sheetname" type="text" value="' + options.$trigger.text() + '" required />',
@@ -88,18 +80,19 @@ L.Control.Tabs = L.Control.extend({
map.renamePage(data.sheetname, nPos);
}
});
- }},
+ }).bind(this)
+ } ,
'showsheets': {
name: _UNO('.uno:Show', 'spreadsheet', true),
- callback: function() {
+ callback: (function() {
map.showPage();
- }
+ }).bind(this)
},
'hiddensheets': {
name: _UNO('.uno:Hide', 'spreadsheet', true),
- callback: function() {
+ callback: (function() {
map.hidePage();
- }
+ }).bind(this)
}
},
zIndex: 1000
@@ -138,7 +131,16 @@ L.Control.Tabs = L.Control.extend({
if (e.hiddenParts.indexOf(i) !== -1)
continue;
var id = 'spreadsheet-tab' + i;
- var tab = L.DomUtil.create('div', 'spreadsheet-tab', ssTabScroll);
+ var tab = L.DomUtil.create('button', 'spreadsheet-tab', ssTabScroll);
+ L.DomEvent.enableLongTap(tab);
+
+ L.DomEvent.on(tab, 'contextmenu', function(j) {
+ return function() {
+ this._tabForContextMenu = j;
+ $('spreadsheet-tab' + j).contextMenu();
+ }
+ }(i).bind(this));
+
tab.textContent = e.partNames[i];
tab.id = id;
diff --git a/loleaflet/src/dom/DomEvent.LongTap.js b/loleaflet/src/dom/DomEvent.LongTap.js
new file mode 100644
index 000000000..c0e06ca12
--- /dev/null
+++ b/loleaflet/src/dom/DomEvent.LongTap.js
@@ -0,0 +1,148 @@
+/*
+ * Similar to DomEvent.DoubleTap.js (which implements the 'dblclick' event for
+ * touchscreens), this implements the 'contextmenu' event on long touchscreen
+ * press for combination of browsers/input devices that don't - namely,
+ * Safari on iOS devices.
+ *
+ * This has been mostly copy-pasted from map/handler/Map.Tap.js and should be
+ * refactored somehow.
+ */
+L.DomEvent.enableLongTap = function enableLongTap(el, tolerance, timeout) {
+ // Skip non-touchscreens and browsers which implement PointerEvent
+ if (!L.Browser.touch || L.Browser.pointer) {
+ return;
+ }
+
+ // Prevent double handling
+ if (el._hasLongTapContextMenus) {
+ return;
+ }
+ el._hasLongTapContextMenus = true;
+
+ // Default value for the 'tolerance' parameter: 15 pixels
+ // This is the amount of pixels that the touch can move around during
+ // a long tap, and still fire contextmenu events.
+ if (!tolerance) {
+ tolerance = 15;
+ }
+
+ // Default value for the 'timeout' parameter: 2000 milliseconds
+ // This is how long a user has to hold down the touch to trigger the
+ // contextmenu event
+ if (!timeout) {
+ timeout = 2000;
+ }
+
+ var holdTimeout;
+ var fireClick = true; // Whether to fire a click event on touchup
+ var startPos; // Position of the touch on touchstart
+ var newPos; // Position of the touch on the last touchmove
+
+ function onDown(ev) {
+ if (!ev.touches) {
+ return;
+ }
+
+ L.DomEvent.preventDefault(ev);
+ fireClick = true;
+
+ // don't simulate click or track longpress if more than 1 touch
+ if (ev.touches.length > 1) {
+ fireClick = false;
+ clearTimeout(holdTimeout);
+ return;
+ }
+
+ var first = ev.touches[0],
+ target = first.target;
+
+ startPos = newPos = L.point(first.clientX, first.clientY);
+
+ // if touching a link, highlight it
+ if (target.tagName && target.tagName.toLowerCase() === 'a') {
+ L.DomUtil.addClass(target, 'leaflet-active');
+ }
+
+ // simulate long hold but setting a timeout
+ holdTimeout = setTimeout(function() {
+ if (isTapValid()) {
+ fireClick = false;
+ onUp();
+ simulateEvent('contextmenu', first);
+ }
+ }, timeout);
+
+ simulateEvent('mousedown', first);
+
+ L.DomEvent.on(el, {
+ touchmove: onMove,
+ touchend: onUp
+ });
+ }
+
+ function isTapValid() {
+ return newPos.distanceTo(startPos) <= tolerance;
+ }
+
+ function onUp(ev) {
+ clearTimeout(holdTimeout);
+
+ L.DomEvent.off(el, {
+ touchmove: onMove,
+ touchend: onUp
+ });
+
+ if (fireClick && ev && ev.changedTouches) {
+ var first = ev.changedTouches[0],
+ target = first.target;
+
+ if (target && target.tagName && el.tagName.toLowerCase() === 'a') {
+ L.DomUtil.removeClass(target, 'leaflet-active');
+ }
+
+ simulateEvent('mouseup', first);
+
+ // simulate click if the touch didn't move too much
+ if (isTapValid()) {
+ simulateEvent('click', first);
+ }
+ }
+ }
+
+ function onMove(ev) {
+ var first = ev.touches[0];
+ newPos = new L.Point(first.clientX, first.clientY);
+ simulateEvent('mousemove', first);
+ }
+
+ function simulateEvent(type, ev) {
+ var simulatedEvent = document.createEvent('MouseEvents');
+
+ simulatedEvent._simulated = true;
+ ev.target._simulatedClick = true;
+
+ simulatedEvent.initMouseEvent(
+ type,
+ true,
+ true,
+ window,
+ 1,
+ ev.screenX,
+ ev.screenY,
+ ev.clientX,
+ ev.clientY,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null
+ );
+
+ console.log('dispatching simulated contextmenu event: ', simulatedEvent);
+
+ ev.target.dispatchEvent(simulatedEvent);
+ }
+
+ L.DomEvent.on(el, 'touchstart', onDown, this);
+};
More information about the Libreoffice-commits
mailing list