diff --git a/lib/client/dom.js b/lib/client/dom.js index 8e903f32..1bd9a340 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -583,6 +583,22 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog; return ret; }; + + /* + * unselect all files + */ + this.unselectFiles = function(files) { + var array, + isArray = Array.isArray(files); + + if (!files) { + array = DOM.getSelectedFiles(); + } else if (!isArray) + array = [].slice.call(files); + + array.forEach(DOM.toggleSelectedFile); + }; + /** * get all selected files with current included * diff --git a/lib/client/listeners.js b/lib/client/listeners.js index 74878d5f..e7aad33f 100644 --- a/lib/client/listeners.js +++ b/lib/client/listeners.js @@ -145,23 +145,29 @@ var Util, DOM, CloudFunc, CloudCmd; } function onClick(event) { - var ctrl = event.ctrlKey, - meta = event.metaKey; + var ctrl = event.ctrlKey; - if (!ctrl && !meta) + if (!ctrl) event.preventDefault(); - else - toggleSelect(ctrl, meta); changePanel(event.target); } - function toggleSelect(ctrl, meta) { - var Info = DOM.CurrentInfo, - isMac = /Mac/.test(window.navigator.platform); + function toggleSelect(key, files) { + var isMac = /Mac/.test(window.navigator.platform); - if (isMac && meta || ctrl) - DOM.toggleSelectedFile(Info.element); + if (!key) + throw Error('key should not be undefined!'); + + if (isMac && key.meta || key.ctrl) + DOM.toggleSelectedFile(files[0]); + else if (key.shift) + files.forEach(function(current) { + if (!DOM.isSelected(current)) + DOM.toggleSelectedFile(current); + }); + else + DOM.unselectFiles(); } function changePanel(element) { @@ -247,8 +253,58 @@ var Util, DOM, CloudFunc, CloudCmd; } function setCurrentFileByEvent(event) { - var element = getLIElement(event.target); + var fromName, + toName, + BUTTON_LEFT = 0, + files = [], + key = { + ctrl: event.ctrlKey, + meta: event.metaKey, + shift: event.shiftKey + }, + + element = getLIElement(event.target); + + fromName = Info.name; DOM.setCurrentFile(element); + toName = Info.name; + + if (key.shift) + files = getFilesRange(fromName, toName); + else + files.push(Info.element); + + if (event.button === BUTTON_LEFT) + toggleSelect(key, files); + } + + function getFilesRange(from, to) { + var i = 0, + delta = 0, + result = [], + files = [].slice.call(DOM.getFiles()), + names = DOM.getSelectedNames(files), + indexFrom, + indexTo; + + if (names[0] === '..') { + names.shift(); + delta = 1; + } + + indexFrom = names.indexOf(from); + indexTo = names.indexOf(to); + + if (indexFrom < indexTo) + for (i = indexFrom; i <= indexTo; i++) + result.push(files[i + delta]); + else if (indexFrom > indexTo) + for (i = indexFrom; i >= indexTo; i--) + result.push(files[i + delta]); + else + result.push(to); + + return result; } function contextMenu() {