|
8 | 8 | import { parse } from '@vue/devtools-kit'
|
9 | 9 | import { isInChromePanel, isInSeparateWindow, sortByKey } from '@vue/devtools-shared'
|
10 | 10 | import { vTooltip, VueButton, VueDialog, VueInput } from '@vue/devtools-ui'
|
11 |
| -import { useElementSize, useEventListener, useToggle, watchDebounced } from '@vueuse/core' |
| 11 | +import { onKeyStroke, useElementSize, useEventListener, useToggle, watchDebounced } from '@vueuse/core' |
12 | 12 | import { flatten, groupBy } from 'lodash-es'
|
13 | 13 | import { Pane, Splitpanes } from 'splitpanes'
|
14 | 14 | import { computed, onUnmounted, ref, watch, watchEffect } from 'vue'
|
@@ -280,6 +280,105 @@ useEventListener('keydown', (event) => {
|
280 | 280 | }
|
281 | 281 | })
|
282 | 282 |
|
| 283 | +onKeyStroke('ArrowRight', () => { |
| 284 | + const isPresentInExpandedNodes = expandedTreeNodes.value.includes(activeComponentId.value) |
| 285 | + const hasChildren = flattenedTreeNodes.value.find(item => item.id === activeComponentId.value)?.children?.length |
| 286 | +
|
| 287 | + if (!isPresentInExpandedNodes && hasChildren) { |
| 288 | + expandedTreeNodes.value.push(activeComponentId.value) |
| 289 | + } |
| 290 | +}) |
| 291 | +onKeyStroke('ArrowLeft', () => { |
| 292 | + if (expandedTreeNodes.value.includes(activeComponentId.value)) { |
| 293 | + expandedTreeNodes.value.splice(expandedTreeNodes.value.indexOf(activeComponentId.value), 1) |
| 294 | + } |
| 295 | +}) |
| 296 | +onKeyStroke('ArrowDown', () => { |
| 297 | + const activeComponentIdIndex = flattenedTreeNodesIds.value.indexOf(activeComponentId.value) |
| 298 | + const isActiveComponentExpanded = expandedTreeNodes.value.includes(activeComponentId.value) |
| 299 | +
|
| 300 | + if (isActiveComponentExpanded && activeComponentIdIndex >= 0 && activeComponentIdIndex < flattenedTreeNodesIds.value.length - 1) { |
| 301 | + activeComponentId.value = flattenedTreeNodesIds.value[activeComponentIdIndex + 1] |
| 302 | + } |
| 303 | + else if (activeComponentIdIndex === 0) { |
| 304 | + return false |
| 305 | + } |
| 306 | + else { |
| 307 | + activeComponentId.value = getNearestNextNode() |
| 308 | + } |
| 309 | +}) |
| 310 | +
|
| 311 | +onKeyStroke('ArrowUp', () => { |
| 312 | + const activeId = activeComponentId.value |
| 313 | + const list = treeNodeLinkedList.value.find(item => item.includes(activeId)) |
| 314 | + if (!list) |
| 315 | + return |
| 316 | +
|
| 317 | + const activeItemListIndex = list.indexOf(activeId) |
| 318 | + const activeItemParentIndex = activeItemListIndex > 0 ? activeItemListIndex - 1 : 0 |
| 319 | + const parentId = list[activeItemParentIndex] |
| 320 | +
|
| 321 | + const element = getNearestPreviousNode(parentId) |
| 322 | + if (element) { |
| 323 | + activeComponentId.value = element.id |
| 324 | + } |
| 325 | +}) |
| 326 | +
|
| 327 | +onKeyStroke([' ', 'Enter'], () => { |
| 328 | + const node = flattenedTreeNodes.value.find(item => item.id === activeComponentId.value) |
| 329 | + if (!node?.children?.length) |
| 330 | + return |
| 331 | +
|
| 332 | + const index = expandedTreeNodes.value.indexOf(activeComponentId.value) |
| 333 | + if (index === -1) |
| 334 | + expandedTreeNodes.value.push(activeComponentId.value) |
| 335 | + else expandedTreeNodes.value.splice(index, 1) |
| 336 | +}) |
| 337 | +
|
| 338 | +function getNearestPreviousNode(parentId: string) { |
| 339 | + const parentNode = flattenedTreeNodes.value.find(item => item.id === parentId) |
| 340 | + if (!parentNode || !parentNode.children?.length) |
| 341 | + return parentNode |
| 342 | +
|
| 343 | + if (parentNode.children.length === 1) |
| 344 | + return parentNode |
| 345 | +
|
| 346 | + const indexInSiblings = parentNode?.children?.findIndex(item => item.id === activeComponentId.value) |
| 347 | +
|
| 348 | + if (indexInSiblings <= 0) |
| 349 | + return parentNode |
| 350 | +
|
| 351 | + let prevSiblingNode = parentNode.children[indexInSiblings - 1] |
| 352 | +
|
| 353 | + while (prevSiblingNode |
| 354 | + && expandedTreeNodes.value.includes(prevSiblingNode.id) |
| 355 | + && prevSiblingNode.children?.length) { |
| 356 | + const lastChildNode = prevSiblingNode.children[prevSiblingNode.children.length - 1] |
| 357 | + const next = getNearestPreviousNode(lastChildNode.id) |
| 358 | +
|
| 359 | + if (!next || next.id === prevSiblingNode.id) |
| 360 | + break |
| 361 | + prevSiblingNode = next |
| 362 | + } |
| 363 | +
|
| 364 | + return prevSiblingNode || parentNode |
| 365 | +} |
| 366 | +
|
| 367 | +function getNearestNextNode() { |
| 368 | + const linkedListTree = treeNodeLinkedList.value |
| 369 | + const activeItemListIndex = [...linkedListTree].findLastIndex(arr => arr?.includes(activeComponentId.value)) |
| 370 | +
|
| 371 | + if (activeItemListIndex === -1) |
| 372 | + return activeComponentId.value |
| 373 | +
|
| 374 | + const arr1 = linkedListTree[activeItemListIndex] |
| 375 | + const arr2 = linkedListTree[activeItemListIndex + 1] |
| 376 | +
|
| 377 | + const cloesestNodeIndex = arr2?.findIndex((val, index) => val !== arr1[index]) ?? -1 |
| 378 | +
|
| 379 | + return cloesestNodeIndex !== -1 ? arr2[cloesestNodeIndex] : activeComponentId.value |
| 380 | +} |
| 381 | +
|
283 | 382 | function scrollToComponent() {
|
284 | 383 | rpc.value.scrollToComponent(activeComponentId.value)
|
285 | 384 | }
|
|
0 commit comments