diff --git a/src/components/FileExplorer.js b/src/components/FileExplorer.js
index 3dd07c6..4d7a860 100644
--- a/src/components/FileExplorer.js
+++ b/src/components/FileExplorer.js
@@ -82,7 +82,7 @@ export default class FileExplorer extends React.Component {
}
render() {
- const { stateText, visibleNodes, freeze, handleKeyDown, handleSearchKeyChange, onNodeClick, toggleShowSettings } = this.props
+ const { stateText, visibleNodes, freeze, handleKeyDown, handleSearchKeyChange, onNodeClick, toggleShowSettings, onFocusSearchBar } = this.props
return (
{
@@ -90,7 +90,7 @@ export default class FileExplorer extends React.Component {
?
: visibleNodes && (
-
+
{this.renderFiles(visibleNodes, onNodeClick)}
)
diff --git a/src/components/SearchBar.js b/src/components/SearchBar.js
index 9b8508e..50547a4 100644
--- a/src/components/SearchBar.js
+++ b/src/components/SearchBar.js
@@ -1,9 +1,10 @@
import React from 'react'
-export default function SearchBar({ onSearchKeyChange }) {
+export default function SearchBar({ onSearchKeyChange, onFocus }) {
return (
text => dispatch({
stateText: text,
})
-const handleKeyDown = dispatch => ({ key }) => dispatch(({ visibleNodes: { nodes, focusedNode, expandedNodes, depths } }) => {
+const handleKeyDown = dispatch => event => dispatch(({ visibleNodes: { nodes, focusedNode, expandedNodes, depths } }) => {
+ function handleVerticalMove(index) {
+ if (0 <= index && index < nodes.length) {
+ DOMHelper.focusFileExplorer()
+ dispatch(focusNode, nodes[index])
+ } else {
+ DOMHelper.focusSearchInput()
+ dispatch(focusNode, null)
+ }
+ }
+
+ const { key } = event
+ // prevent document body scrolling if the keypress results in Gitako action
+ let muteEvent = true
if (focusedNode) {
const focusedNodeIndex = nodes.indexOf(focusedNode)
switch (key) {
case 'ArrowUp':
// focus on previous node
- if (focusedNodeIndex === 0) {
- dispatch(focusNode, nodes[nodes.length - 1])
- } else {
- dispatch(focusNode, nodes[focusedNodeIndex - 1])
- }
+ handleVerticalMove(focusedNodeIndex - 1)
break
case 'ArrowDown':
// focus on next node
- if (focusedNodeIndex + 1 < nodes.length) {
- dispatch(focusNode, nodes[focusedNodeIndex + 1])
- } else {
- dispatch(focusNode, nodes[0])
- }
+ handleVerticalMove(focusedNodeIndex + 1)
break
case 'ArrowLeft':
@@ -137,7 +142,6 @@ const handleKeyDown = dispatch => ({ key }) => dispatch(({ visibleNodes: { nodes
} else if (focusedNode.type === 'blob') {
DOMHelper.loadWithPJAX(focusedNode.url)
} else if (focusedNode.type === 'commit') {
- // redirect to its parent folder
window.open(focusedNode.url)
}
break
@@ -148,27 +152,39 @@ const handleKeyDown = dispatch => ({ key }) => dispatch(({ visibleNodes: { nodes
} else if (focusedNode.type === 'blob') {
DOMHelper.loadWithPJAX(focusedNode.url)
} else if (focusedNode.type === 'commit') {
- // redirect to its parent folder
window.open(focusedNode.url)
}
break
-
+ default:
+ muteEvent = false
+ }
+ if (muteEvent) {
+ event.preventDefault()
}
} else {
// now search input is focused
if (nodes.length) {
switch (key) {
case 'ArrowDown':
+ DOMHelper.focusFileExplorer()
dispatch(focusNode, nodes[0])
break
case 'ArrowUp':
+ DOMHelper.focusFileExplorer()
dispatch(focusNode, nodes[nodes.length - 1])
break
+ default:
+ muteEvent = false
+ }
+ if (muteEvent) {
+ event.preventDefault()
}
}
}
})
+const onFocusSearchBar = dispatch => () => dispatch(focusNode, null)
+
const handleSearchKeyChange = dispatch => {
let i = 0
return async event => {
@@ -187,10 +203,7 @@ function shouldDelayExpand(node) {
const setExpand = dispatch => (node, expand) => {
visibleNodesGenerator.setExpand(node, expand)
- const applyChanges = () => {
- dispatch(focusNode, node)
- tasksAfterRender.push(DOMHelper.focusSearchInput)
- }
+ const applyChanges = () => dispatch(focusNode, node)
if (shouldDelayExpand(node)) {
dispatch(mountExpandingIndicator, node)
tasksAfterRender.push(() => setTimeout(applyChanges, 0))
@@ -219,7 +232,6 @@ const focusNode = dispatch => (node, skipScroll) => dispatch(({ visibleNodes: {
// when focus a node not in viewport(by keyboard), scroll to it
const indexOfToBeFocusedNode = nodes.indexOf(node)
tasksAfterRender.push(() => DOMHelper.scrollToNodeElement(indexOfToBeFocusedNode))
- tasksAfterRender.push(DOMHelper.focusSearchInput)
}
dispatch(updateVisibleNodes)
})
@@ -261,6 +273,7 @@ export default {
execAfterRender,
setStateText,
handleKeyDown,
+ onFocusSearchBar,
handleSearchKeyChange,
setExpand,
toggleNodeExpansion,
diff --git a/src/driver/core/SideBar.js b/src/driver/core/SideBar.js
index f5cbf9d..cdb00e2 100644
--- a/src/driver/core/SideBar.js
+++ b/src/driver/core/SideBar.js
@@ -73,7 +73,6 @@ const onPJAXEnd = dispatch => () => {
dispatch(({ metaData, copyFileButton, copySnippetButton }) => {
DOMHelper.unmountTopProgressBar()
DOMHelper.decorateGitHubPageContent({ copyFileButton, copySnippetButton })
- DOMHelper.focusSearchInput()
const mergedMetaData = { ...metaData, ...URLHelper.parse() }
dispatch(setShouldShow, URLHelper.isInCodePage(mergedMetaData))
dispatch(setMetaData, mergedMetaData)
@@ -94,7 +93,7 @@ const onKeyDown = dispatch => e => {
const toggleShowSideBar = dispatch => () => dispatch(({ shouldShow }) => dispatch(setShouldShow, !shouldShow))
const setShouldShow = dispatch => shouldShow => {
- dispatch({ shouldShow }, shouldShow ? DOMHelper.focusSearchInput : null)
+ dispatch({ shouldShow }, shouldShow ? DOMHelper.focusFileExplorer : null)
DOMHelper.setBodyIndent(shouldShow)
}
diff --git a/src/utils/DOMHelper.js b/src/utils/DOMHelper.js
index dddca68..139b326 100644
--- a/src/utils/DOMHelper.js
+++ b/src/utils/DOMHelper.js
@@ -40,7 +40,7 @@ function getCurrentBranch() {
/**
* add the logo element into DOM
- *
+ *
*/
function insertLogoMountPoint() {
const logoSelector = '.gitako .gitako-logo'
@@ -297,16 +297,21 @@ function attachCopySnippet() {
* focus to side bar, user will be able to manipulate it with keyboard
*/
function focusFileExplorer() {
- const sideBarContentSelector = '.gitako .file-explorer'
+ const sideBarContentSelector = '.gitako-side-bar .file-explorer'
const sideBarElement = document.querySelector(sideBarContentSelector)
if (sideBarElement) {
sideBarElement.focus()
}
}
-function focusSearchInput() {
+function getSearchInput() {
const searchInputSelector = '.search-input'
const searchInputElement = document.querySelector(searchInputSelector)
+ return searchInputElement
+}
+
+function focusSearchInput() {
+ const searchInputElement = getSearchInput()
if (searchInputElement) {
if (document.activeElement !== searchInputElement) {
searchInputElement.focus()