Преглед изворни кода

Fix "Edit file" link in visual editor tooltip (#19532)

GitOrigin-RevId: 1f196c3d195b69eae8169c9ffc0629f1cdf6d97b
Alf Eaton пре 2 година
родитељ
комит
30074fbe4e

+ 4 - 32
services/web/frontend/js/features/source-editor/components/command-tooltip/include-tooltip.tsx

@@ -1,18 +1,12 @@
 import { FC } from 'react'
 import { useTranslation } from 'react-i18next'
-import { useCodeMirrorStateContext } from '../codemirror-editor'
 import { Button } from 'react-bootstrap'
-import { resolveCommandNode } from '../../extensions/command-tooltip'
-import {
-  FilePathArgument,
-  LiteralArgContent,
-} from '../../lezer-latex/latex.terms.mjs'
-import Icon from '../../../../shared/components/icon'
-import { EditorState } from '@codemirror/state'
+import Icon from '@/shared/components/icon'
+import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file'
 
 export const IncludeTooltipContent: FC = () => {
   const { t } = useTranslation()
-  const state = useCodeMirrorStateContext()
+  const { openIncludedFile } = useIncludedFile('IncludeArgument')
 
   return (
     <div className="ol-cm-command-tooltip-content">
@@ -20,17 +14,7 @@ export const IncludeTooltipContent: FC = () => {
         type="button"
         bsStyle="link"
         className="ol-cm-command-tooltip-link"
-        onClick={() => {
-          const name = readFileName(state)
-          if (name) {
-            window.dispatchEvent(
-              new CustomEvent('editor:open-file', {
-                detail: { name },
-              })
-            )
-            // TODO: handle file not found
-          }
-        }}
+        onClick={openIncludedFile}
       >
         <Icon type="edit" fw />
         {t('open_file')}
@@ -38,15 +22,3 @@ export const IncludeTooltipContent: FC = () => {
     </div>
   )
 }
-
-const readFileName = (state: EditorState) => {
-  const commandNode = resolveCommandNode(state)
-  const argumentNode = commandNode
-    ?.getChild('IncludeArgument')
-    ?.getChild(FilePathArgument)
-    ?.getChild(LiteralArgContent)
-
-  if (argumentNode) {
-    return state.sliceDoc(argumentNode.from, argumentNode.to)
-  }
-}

+ 4 - 32
services/web/frontend/js/features/source-editor/components/command-tooltip/input-tooltip.tsx

@@ -1,18 +1,12 @@
 import { FC } from 'react'
 import { useTranslation } from 'react-i18next'
-import { useCodeMirrorStateContext } from '../codemirror-editor'
 import { Button } from 'react-bootstrap'
-import { resolveCommandNode } from '../../extensions/command-tooltip'
-import {
-  FilePathArgument,
-  LiteralArgContent,
-} from '../../lezer-latex/latex.terms.mjs'
-import Icon from '../../../../shared/components/icon'
-import { EditorState } from '@codemirror/state'
+import Icon from '@/shared/components/icon'
+import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file'
 
 export const InputTooltipContent: FC = () => {
   const { t } = useTranslation()
-  const state = useCodeMirrorStateContext()
+  const { openIncludedFile } = useIncludedFile('InputArgument')
 
   return (
     <div className="ol-cm-command-tooltip-content">
@@ -20,17 +14,7 @@ export const InputTooltipContent: FC = () => {
         type="button"
         bsStyle="link"
         className="ol-cm-command-tooltip-link"
-        onClick={() => {
-          const name = readFileName(state)
-          if (name) {
-            window.dispatchEvent(
-              new CustomEvent('editor:open-file', {
-                detail: { name },
-              })
-            )
-            // TODO: handle file not found
-          }
-        }}
+        onClick={openIncludedFile}
       >
         <Icon type="edit" fw />
         {t('open_file')}
@@ -38,15 +22,3 @@ export const InputTooltipContent: FC = () => {
     </div>
   )
 }
-
-const readFileName = (state: EditorState) => {
-  const commandNode = resolveCommandNode(state)
-  const argumentNode = commandNode
-    ?.getChild('InputArgument')
-    ?.getChild(FilePathArgument)
-    ?.getChild(LiteralArgContent)
-
-  if (argumentNode) {
-    return state.sliceDoc(argumentNode.from, argumentNode.to)
-  }
-}

+ 47 - 0
services/web/frontend/js/features/source-editor/hooks/use-included-file.ts

@@ -0,0 +1,47 @@
+import { useCodeMirrorStateContext } from '@/features/source-editor/components/codemirror-editor'
+import { useFileTreePathContext } from '@/features/file-tree/contexts/file-tree-path'
+import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
+import { useCallback } from 'react'
+import { EditorState } from '@codemirror/state'
+import { resolveCommandNode } from '@/features/source-editor/extensions/command-tooltip'
+import {
+  FilePathArgument,
+  LiteralArgContent,
+} from '@/features/source-editor/lezer-latex/latex.terms.mjs'
+
+export const useIncludedFile = (argumentType: string) => {
+  const state = useCodeMirrorStateContext()
+  const { findEntityByPath } = useFileTreePathContext()
+  const { openDocId } = useEditorManagerContext()
+
+  const openIncludedFile = useCallback(() => {
+    const name = readIncludedPath(state, argumentType)
+    if (name) {
+      // TODO: find in relative path or root folder
+      for (const extension of ['.tex', '']) {
+        const result = findEntityByPath(`${name}${extension}`)
+        if (result) {
+          return openDocId(result.entity._id)
+        }
+      }
+      // TODO: handle file not found
+    }
+  }, [argumentType, findEntityByPath, openDocId, state])
+
+  return { openIncludedFile }
+}
+
+const readIncludedPath = (
+  state: EditorState,
+  argumentType: string | number
+) => {
+  const commandNode = resolveCommandNode(state)
+  const argumentNode = commandNode
+    ?.getChild(argumentType)
+    ?.getChild(FilePathArgument)
+    ?.getChild(LiteralArgContent)
+
+  if (argumentNode) {
+    return state.sliceDoc(argumentNode.from, argumentNode.to)
+  }
+}