Index: ui/file_manager/file_manager/foreground/js/ui/file_table.js |
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js |
index f89edd3de372ffa986836f2d6548948b8d1909ca..7d62b53bb11136a65ffa37ee0587f40689b9459d 100644 |
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js |
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js |
@@ -530,10 +530,6 @@ FileTable.prototype.renderName_ = function(entry, columnId, table) { |
if (FileType.isImage(entry) || FileType.isVideo(entry)) |
icon.appendChild(this.renderThumbnail_(entry)); |
icon.appendChild(this.renderCheckmark_()); |
- icon.addEventListener( |
- 'mouseup', util.repeatMouseEventWithCtrlKey.bind(null, label)); |
- icon.addEventListener( |
- 'mousedown', util.repeatMouseEventWithCtrlKey.bind(null, label)); |
label.appendChild(icon); |
label.entry = entry; |
@@ -967,3 +963,214 @@ filelist.updateListItemExternalProps = function(li, externalProps) { |
if (li.classList.contains('directory')) |
iconDiv.classList.toggle('shared', externalProps.shared); |
}; |
+ |
+/** |
+ * Handles mouseup/mousedown events on file list to change the selection state. |
+ * |
+ * Basically the content of this function is identical to |
+ * cr.ui.ListSelectionController's handlePointerDownUp(), but following |
+ * handlings are inserted to control the check-select mode. |
+ * |
+ * 1) When checkmark area is clicked, toggle item selection and enable the |
+ * check-select mode. |
+ * 2) When non-checkmark area is clicked in check-select mode, disable the |
+ * check-select mode. |
+ * |
+ * @param {!Event} e The browser mouse event. |
+ * @param {number} index The index that was under the mouse pointer, -1 if |
+ * none. |
+ * @this {cr.ui.ListSelectionController} |
+ */ |
+filelist.handlePointerDownUp = function(e, index) { |
+ var sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */ |
+ (this.selectionModel); |
+ var anchorIndex = sm.anchorIndex; |
+ var isDown = (e.type == 'mousedown'); |
+ |
+ var isTargetCheckmark = e.target.classList.contains('detail-checkmark') || |
+ e.target.classList.contains('checkmark'); |
+ // If multiple selection is allowed and the checkmark is clicked without |
+ // modifiers(Ctrl/Shift), the click should toggle the item's selection. |
+ // (i.e. same behavior as Ctrl+Click) |
+ var isClickOnCheckmark = isTargetCheckmark && sm.multiple && index != -1 && |
+ !e.shiftKey && !e.ctrlKey && e.button == 0; |
+ |
+ sm.beginChange(); |
+ |
+ if (index == -1) { |
+ sm.leadIndex = sm.anchorIndex = -1; |
+ sm.unselectAll(); |
+ } else { |
+ if (sm.multiple && (e.ctrlKey || isClickOnCheckmark) && !e.shiftKey) { |
+ // Selection is handled at mouseUp. |
+ if (!isDown) { |
+ // 1) When checkmark area is clicked, toggle item selection and enable |
+ // the check-select mode. |
+ if (isClickOnCheckmark) { |
+ // If a selected item's checkmark is clicked when the selection mode |
+ // is not check-select, we should avoid toggling(unselecting) the |
+ // item. It is done here by toggling the selection twice. |
+ if (!sm.getCheckSelectMode() && sm.getIndexSelected(index)) |
+ sm.setIndexSelected(index, !sm.getIndexSelected(index)); |
+ // Always enables check-select mode on clicks on checkmark. |
+ sm.setCheckSelectMode(true); |
+ } |
+ // Toggle the current one and make it anchor index. |
+ sm.setIndexSelected(index, !sm.getIndexSelected(index)); |
+ sm.leadIndex = index; |
+ sm.anchorIndex = index; |
+ } |
+ } else if (e.shiftKey && anchorIndex != -1 && anchorIndex != index) { |
+ // Shift is done in mousedown. |
+ if (isDown) { |
+ sm.unselectAll(); |
+ sm.leadIndex = index; |
+ if (sm.multiple) |
+ sm.selectRange(anchorIndex, index); |
+ else |
+ sm.setIndexSelected(index, true); |
+ } |
+ } else { |
+ // Right click for a context menu needs to not clear the selection. |
+ var isRightClick = e.button == 2; |
+ |
+ // If the index is selected this is handled in mouseup. |
+ var indexSelected = sm.getIndexSelected(index); |
+ if ((indexSelected && !isDown || !indexSelected && isDown) && |
+ !(indexSelected && isRightClick)) { |
+ // 2) When non-checkmark area is clicked in check-select mode, disable |
+ // the check-select mode. |
+ if (sm.getCheckSelectMode()) { |
+ // Unselect all items once to ensure that the check-select mode is |
+ // terminated. |
+ sm.endChange(); |
+ sm.unselectAll(); |
+ sm.beginChange(); |
+ } |
+ sm.selectedIndex = index; |
+ } |
+ } |
+ } |
+ sm.endChange(); |
+} |
+ |
+/** |
+ * Handles key events on file list to change the selection state. |
+ * |
+ * Basically the content of this function is identical to |
+ * cr.ui.ListSelectionController's handleKeyDown(), but following handlings is |
+ * inserted to control the check-select mode. |
+ * |
+ * 1) When pressing direction key results in a single selection, the |
+ * check-select mode should be terminated. |
+ * |
+ * @param {Event} e The keydown event. |
+ * @this {cr.ui.ListSelectionController} |
+ */ |
+filelist.handleKeyDown = function(e) { |
+ var SPACE_KEY_CODE = 32; |
+ var tagName = e.target.tagName; |
+ |
+ // If focus is in an input field of some kind, only handle navigation keys |
+ // that aren't likely to conflict with input interaction (e.g., text |
+ // editing, or changing the value of a checkbox or select). |
+ if (tagName == 'INPUT') { |
+ var inputType = e.target.type; |
+ // Just protect space (for toggling) for checkbox and radio. |
+ if (inputType == 'checkbox' || inputType == 'radio') { |
+ if (e.keyCode == SPACE_KEY_CODE) |
+ return; |
+ // Protect all but the most basic navigation commands in anything else. |
+ } else if (e.keyIdentifier != 'Up' && e.keyIdentifier != 'Down') { |
+ return; |
+ } |
+ } |
+ // Similarly, don't interfere with select element handling. |
+ if (tagName == 'SELECT') |
+ return; |
+ |
+ var sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */ |
+ (this.selectionModel); |
+ var newIndex = -1; |
+ var leadIndex = sm.leadIndex; |
+ var prevent = true; |
+ |
+ // Ctrl/Meta+A |
+ if (sm.multiple && e.keyCode == 65 && |
+ (cr.isMac && e.metaKey || !cr.isMac && e.ctrlKey)) { |
+ sm.selectAll(); |
+ e.preventDefault(); |
+ return; |
+ } |
+ |
+ // Space |
+ if (e.keyCode == SPACE_KEY_CODE) { |
+ if (leadIndex != -1) { |
+ var selected = sm.getIndexSelected(leadIndex); |
+ if (e.ctrlKey || !selected) { |
+ sm.setIndexSelected(leadIndex, !selected || !sm.multiple); |
+ return; |
+ } |
+ } |
+ } |
+ |
+ switch (e.keyIdentifier) { |
+ case 'Home': |
+ newIndex = this.getFirstIndex(); |
+ break; |
+ case 'End': |
+ newIndex = this.getLastIndex(); |
+ break; |
+ case 'Up': |
+ newIndex = leadIndex == -1 ? |
+ this.getLastIndex() : this.getIndexAbove(leadIndex); |
+ break; |
+ case 'Down': |
+ newIndex = leadIndex == -1 ? |
+ this.getFirstIndex() : this.getIndexBelow(leadIndex); |
+ break; |
+ case 'Left': |
+ case 'MediaPreviousTrack': |
+ newIndex = leadIndex == -1 ? |
+ this.getLastIndex() : this.getIndexBefore(leadIndex); |
+ break; |
+ case 'Right': |
+ case 'MediaNextTrack': |
+ newIndex = leadIndex == -1 ? |
+ this.getFirstIndex() : this.getIndexAfter(leadIndex); |
+ break; |
+ default: |
+ prevent = false; |
+ } |
+ |
+ if (newIndex != -1) { |
+ sm.beginChange(); |
+ |
+ sm.leadIndex = newIndex; |
+ if (e.shiftKey) { |
+ var anchorIndex = sm.anchorIndex; |
+ if (sm.multiple) |
+ sm.unselectAll(); |
+ if (anchorIndex == -1) { |
+ sm.setIndexSelected(newIndex, true); |
+ sm.anchorIndex = newIndex; |
+ } else { |
+ sm.selectRange(anchorIndex, newIndex); |
+ } |
+ } else { |
+ // 1) When pressing direction key results in a single selection, the |
+ // check-select mode should be terminated. |
+ sm.setCheckSelectMode(false); |
+ |
+ if (sm.multiple) |
+ sm.unselectAll(); |
+ sm.setIndexSelected(newIndex, true); |
+ sm.anchorIndex = newIndex; |
+ } |
+ |
+ sm.endChange(); |
+ |
+ if (prevent) |
+ e.preventDefault(); |
+ } |
+} |