mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 00:29:38 +01:00
* All Applications: Get all drag and drop action functionality working cross platform
-Fix drag Out to desktop functionality with Command+Shift keys (for Mac) or Alt+Shift keys (for other platforms) -Fix content selection functionality with Command key (for Mac only) or Ctrl key (for other platforms)
This commit is contained in:
parent
bcbf679f64
commit
981a0a1eb9
@ -2152,6 +2152,35 @@ egwActionObject.prototype.getActionImplementationGroups = function(_test, _group
|
|||||||
return _groups;
|
return _groups;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user tries to get dragOut action
|
||||||
|
*
|
||||||
|
* keys for dragOut:
|
||||||
|
* -Mac: Command + Shift
|
||||||
|
* -Others: Alt + Shift
|
||||||
|
*
|
||||||
|
* @param {event} _event
|
||||||
|
* @return {boolean} return true if Alt+Shift keys and left mouse click arre pressed, otherwise false
|
||||||
|
*/
|
||||||
|
egwActionObject.prototype.isDragOut = function (_event)
|
||||||
|
{
|
||||||
|
return (_event.altKey || _event.metaKey) && _event.shiftKey && _event.which == 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user tries to get selection action
|
||||||
|
*
|
||||||
|
* Keys for selection:
|
||||||
|
* -Mac: Command key
|
||||||
|
* -Others: Ctrl key
|
||||||
|
*
|
||||||
|
* @param {type} _event
|
||||||
|
* @returns {Boolean} return true if left mouse click and Ctrl key are pressed, otherwise false
|
||||||
|
*/
|
||||||
|
egwActionObject.prototype.isSelection = function (_event)
|
||||||
|
{
|
||||||
|
return !(_event.shiftKey) && _event.which == 1 && (_event.metaKey || _event.ctrlKey);
|
||||||
|
};
|
||||||
|
|
||||||
/** egwActionObjectInterface Interface **/
|
/** egwActionObjectInterface Interface **/
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ function egwDragActionImplementation()
|
|||||||
navigator && navigator.userAgent.indexOf('Chrome') >= 0 && egw.app_name() == 'filemanager') // currently only filemanager supports drag out
|
navigator && navigator.userAgent.indexOf('Chrome') >= 0 && egw.app_name() == 'filemanager') // currently only filemanager supports drag out
|
||||||
{
|
{
|
||||||
var key = ["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0 ? 'Ctrl' : 'Command';
|
var key = ["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0 ? 'Ctrl' : 'Command';
|
||||||
text.text(egw.lang('Hold %1 to drag %2 to your computer',key, itemLabel));
|
text.text(egw.lang('Hold Alt + Shift key to drag %2 to your computer',key, itemLabel));
|
||||||
}
|
}
|
||||||
// Final html DOM return as helper structor
|
// Final html DOM return as helper structor
|
||||||
return div;
|
return div;
|
||||||
@ -188,99 +188,123 @@ function egwDragActionImplementation()
|
|||||||
* This way we can at least toggle which one is operating, so they
|
* This way we can at least toggle which one is operating, so they
|
||||||
* both work alternately if not together.
|
* both work alternately if not together.
|
||||||
*/
|
*/
|
||||||
// Native DnD - Doesn't play nice with jQueryUI Sortable
|
// Native DnD - Doesn't play nice with jQueryUI Sortable
|
||||||
// Tell jQuery to include this property
|
// Tell jQuery to include this property
|
||||||
jQuery.event.props.push('dataTransfer');
|
jQuery.event.props.push('dataTransfer');
|
||||||
|
|
||||||
$j(node).off("mousedown")
|
$j(node).off("mousedown")
|
||||||
.on("mousedown", function(event) {
|
.on("mousedown", function(event) {
|
||||||
$j(node).draggable("option","disabled",event.ctrlKey || event.metaKey);
|
var dragOut = _context.isDragOut(event);
|
||||||
$j(this).attr("draggable", event.ctrlKey || event.metaKey ? "true" : "");
|
$j(this).attr("draggable", dragOut? "true" : "");
|
||||||
|
$j(node).draggable("option","disabled",dragOut);
|
||||||
// Disabling draggable adds some UI classes, but we don't care so remove them
|
if (dragOut)
|
||||||
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
|
|
||||||
if(!(event.ctrlKey || event.metaKey) || !this.addEventListener) return;
|
|
||||||
})
|
|
||||||
.on("dragstart", function(event) {
|
|
||||||
if(event.dataTransfer == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
event.dataTransfer.effectAllowed="copy";
|
|
||||||
|
|
||||||
// Get all selected
|
|
||||||
// Multiples aren't supported by event.dataTransfer, yet, so
|
|
||||||
// select only the row they clicked on.
|
|
||||||
// var selected = _context.getSelectedLinks('drag');
|
|
||||||
var selected = [_context];
|
|
||||||
_context.parent.setAllSelected(false);
|
|
||||||
_context.setSelected(true);
|
|
||||||
|
|
||||||
// Set file data
|
|
||||||
for(var i = 0; i < selected.length; i++)
|
|
||||||
{
|
|
||||||
var data = selected[i].data || egw.dataGetUIDdata(selected[i].id).data || {};
|
|
||||||
if(data && data.mime && data.download_url)
|
|
||||||
{
|
|
||||||
var url = data.download_url;
|
|
||||||
|
|
||||||
// NEED an absolute URL
|
|
||||||
if (url[0] == '/') url = egw.link(url);
|
|
||||||
// egw.link adds the webserver, but that might not be an absolute URL - try again
|
|
||||||
if (url[0] == '/') url = window.location.origin+url;
|
|
||||||
|
|
||||||
// Unfortunately, dragging files is currently only supported by Chrome
|
|
||||||
if(navigator && navigator.userAgent.indexOf('Chrome'))
|
|
||||||
{
|
{
|
||||||
event.dataTransfer.setData("DownloadURL", data.mime+':'+data.name+':'+url);
|
// Disabling draggable adds some UI classes, but we don't care so remove them
|
||||||
|
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Include URL as a fallback
|
if (_context.isSelection(event))
|
||||||
event.dataTransfer.setData("text/uri-list", url);
|
{
|
||||||
|
$j(node).draggable("disable");
|
||||||
|
// Disabling draggable adds some UI classes, but we don't care so remove them
|
||||||
|
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
|
||||||
|
}
|
||||||
|
else if(event.which != 3)
|
||||||
|
{
|
||||||
|
document.getSelection().removeAllRanges();
|
||||||
|
}
|
||||||
|
if(!(dragOut) || !this.addEventListener) return;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on ("mouseup", function (event){
|
||||||
|
if (_context.isSelection(event))
|
||||||
|
$j(node).draggable("enable");
|
||||||
|
})
|
||||||
|
.on("dragstart", function(event) {
|
||||||
|
if(_context.isSelection(event)) return;
|
||||||
|
if(event.dataTransfer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.dataTransfer.effectAllowed="copy";
|
||||||
|
|
||||||
|
// Get all selected
|
||||||
|
// Multiples aren't supported by event.dataTransfer, yet, so
|
||||||
|
// select only the row they clicked on.
|
||||||
|
// var selected = _context.getSelectedLinks('drag');
|
||||||
|
var selected = [_context];
|
||||||
|
_context.parent.setAllSelected(false);
|
||||||
|
_context.setSelected(true);
|
||||||
|
|
||||||
|
// Set file data
|
||||||
|
for(var i = 0; i < selected.length; i++)
|
||||||
|
{
|
||||||
|
var data = selected[i].data || egw.dataGetUIDdata(selected[i].id).data || {};
|
||||||
|
if(data && data.mime && data.download_url)
|
||||||
|
{
|
||||||
|
var url = data.download_url;
|
||||||
|
|
||||||
|
// NEED an absolute URL
|
||||||
|
if (url[0] == '/') url = egw.link(url);
|
||||||
|
// egw.link adds the webserver, but that might not be an absolute URL - try again
|
||||||
|
if (url[0] == '/') url = window.location.origin+url;
|
||||||
|
|
||||||
|
// Unfortunately, dragging files is currently only supported by Chrome
|
||||||
|
if(navigator && navigator.userAgent.indexOf('Chrome'))
|
||||||
|
{
|
||||||
|
event.dataTransfer.setData("DownloadURL", data.mime+':'+data.name+':'+url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Include URL as a fallback
|
||||||
|
event.dataTransfer.setData("text/uri-list", url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if(event.dataTransfer.types.length == 0)
|
||||||
if(event.dataTransfer.types.length == 0)
|
{
|
||||||
{
|
// No file data? Abort: drag does nothing
|
||||||
// No file data? Abort: drag does nothing
|
event.preventDefault();
|
||||||
event.preventDefault();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Create drag icon
|
// Create drag icon
|
||||||
_callback.call(_context, _context, ai);
|
_callback.call(_context, _context, ai);
|
||||||
// Drag icon must be visible for setDragImage() - we'll remove it on drag
|
// Drag icon must be visible for setDragImage() - we'll remove it on drag
|
||||||
$j("body").append(ai.helper);
|
$j("body").append(ai.helper);
|
||||||
event.dataTransfer.setDragImage(ai.helper[0],-12,-12);
|
event.dataTransfer.setDragImage(ai.helper[0],-12,-12);
|
||||||
})
|
})
|
||||||
.on("drag", function(e) {
|
.on("drag", function(e) {
|
||||||
// Remove the helper, it has been copied into the dataTransfer object now
|
// Remove the helper, it has been copied into the dataTransfer object now
|
||||||
// Hopefully user didn't notice it...
|
// Hopefully user didn't notice it...
|
||||||
if(e.dataTransfer != null)
|
if(e.dataTransfer != null)
|
||||||
{
|
{
|
||||||
ai.helper.remove();
|
ai.helper.remove();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use Ctrl key in order to select content
|
||||||
|
$j(node).off("mousedown")
|
||||||
|
.on({
|
||||||
|
mousedown: function(event){
|
||||||
|
if (_context.isSelection(event)){
|
||||||
|
$j(node).draggable("disable");
|
||||||
|
// Disabling draggable adds some UI classes, but we don't care so remove them
|
||||||
|
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
|
||||||
|
}
|
||||||
|
else if(event.which != 3)
|
||||||
|
{
|
||||||
|
document.getSelection().removeAllRanges();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mouseup: function (){
|
||||||
|
$j(node).draggable("enable");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Use Ctrl+Alt key in order to select content
|
|
||||||
$j(node).off("mousedown")
|
|
||||||
.on({
|
|
||||||
mousedown: function(event){
|
|
||||||
if ((event.ctrlKey && event.altKey) || (event.ctrlKey && event.metaKey) && event.which == 1){
|
|
||||||
$j(node).draggable("disable");
|
|
||||||
// Disabling draggable adds some UI classes, but we don't care so remove them
|
|
||||||
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
|
|
||||||
}
|
|
||||||
else if(event.which != 3)
|
|
||||||
{
|
|
||||||
document.getSelection().removeAllRanges();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mouseup: function (){
|
|
||||||
$j(node).draggable("enable");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
$j(node).draggable(
|
$j(node).draggable(
|
||||||
{
|
{
|
||||||
"distance": 20,
|
"distance": 20,
|
||||||
@ -331,18 +355,8 @@ function egwDragActionImplementation()
|
|||||||
if (helperTop >= dTarget.offset().top
|
if (helperTop >= dTarget.offset().top
|
||||||
&& helperTop <= (dTarget.height() + dTarget.offset().top) + tipTelorance)
|
&& helperTop <= (dTarget.height() + dTarget.offset().top) + tipTelorance)
|
||||||
{
|
{
|
||||||
var key1='', key2='';
|
var key = (["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0)?"Ctrl": "Command";
|
||||||
if (["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0)
|
egw.message(egw.lang('Hold %1 key to select content.',key),'info');
|
||||||
{
|
|
||||||
key1 = 'Ctrl';
|
|
||||||
key2 = 'Alt';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
key1 ='Command';
|
|
||||||
key2 ='Ctrl';
|
|
||||||
}
|
|
||||||
egw.message(egw.lang('Hold %1 + %2 key to select content.', key1, key2),'info');
|
|
||||||
}
|
}
|
||||||
// Invalid target
|
// Invalid target
|
||||||
return true;
|
return true;
|
||||||
|
@ -234,28 +234,28 @@ function egwPopupActionImplementation()
|
|||||||
|
|
||||||
if (_egw_active_menu)
|
if (_egw_active_menu)
|
||||||
{
|
{
|
||||||
_egw_active_menu.hide()
|
_egw_active_menu.hide();
|
||||||
}
|
}
|
||||||
else if (!e.ctrlKey)
|
else if (!e.ctrlKey && e.which == 3)
|
||||||
{
|
{
|
||||||
_xy = ai._getPageXY(e);
|
var _xy = ai._getPageXY(e);
|
||||||
_callback.call(_context, _xy, ai);
|
_callback.call(_context, _xy, ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.cancelBubble = !e.ctrlKey;
|
e.cancelBubble = !e.ctrlKey || e.which == 1;
|
||||||
if (e.stopPropagation && !e.ctrlKey)
|
if (e.stopPropagation && e.cancelBubble)
|
||||||
{
|
{
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
return e.ctrlKey;
|
return !e.cancelBubble;
|
||||||
}
|
};
|
||||||
|
|
||||||
if (egwIsMobile()) {
|
if (egwIsMobile()) {
|
||||||
$j(_node).bind('taphold', contextHandler);
|
$j(_node).bind('taphold', contextHandler);
|
||||||
} else {
|
} else {
|
||||||
$j(_node).on('contextmenu', contextHandler);
|
$j(_node).on('contextmenu', contextHandler);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
ai.doRegisterAction = function(_aoi, _callback, _context)
|
ai.doRegisterAction = function(_aoi, _callback, _context)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user