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

Expose ScopeValueStore via window.overleaf.unstable.store (#16404)

GitOrigin-RevId: 4b251639296405c0a9487f063e8b049687860004
Alf Eaton пре 2 година
родитељ
комит
fc8892e4fb

+ 8 - 0
services/web/frontend/js/features/source-editor/components/codemirror-view.tsx

@@ -1,10 +1,13 @@
 import { memo, useCallback, useEffect } from 'react'
 import { useCodeMirrorViewContext } from './codemirror-editor'
 import useCodeMirrorScope from '../hooks/use-codemirror-scope'
+import useScopeValueSetterOnly from '@/shared/hooks/use-scope-value-setter-only'
 
 function CodeMirrorView() {
   const view = useCodeMirrorViewContext()
 
+  const [, setView] = useScopeValueSetterOnly('editor.view')
+
   // append the editor view dom to the container node when mounted
   const containerRef = useCallback(
     node => {
@@ -22,6 +25,11 @@ function CodeMirrorView() {
     }
   }, [view])
 
+  // add the editor view to the scope value store, so it can be accessed by external extensions
+  useEffect(() => {
+    setView(view)
+  }, [setView, view])
+
   useCodeMirrorScope(view)
 
   return <div ref={containerRef} style={{ height: '100%' }} />

+ 20 - 1
services/web/frontend/js/shared/context/ide-context.tsx

@@ -1,4 +1,4 @@
-import { createContext, FC, useContext, useMemo } from 'react'
+import { createContext, FC, useContext, useEffect, useMemo } from 'react'
 import { ScopeValueStore } from '../../../../types/ide/scope-value-store'
 import { Scope } from '../../../../types/angular/scope'
 import getMeta from '@/utils/meta'
@@ -23,6 +23,25 @@ export const IdeProvider: FC<{
   scopeStore: ScopeValueStore
   scopeEventEmitter: ScopeEventEmitter
 }> = ({ ide, scopeStore, scopeEventEmitter, children }) => {
+  /**
+   * Expose scopeStore via `window.overleaf.unstable.store`, so it can be accessed by external extensions.
+   *
+   * These properties are expected to be available:
+   *   - `editor.view`
+   *   - `project.spellcheckLanguage`
+   *   - `editor.open_doc_name`,
+   *   - `editor.open_doc_id`,
+   */
+  useEffect(() => {
+    window.overleaf = {
+      ...window.overleaf,
+      unstable: {
+        ...window.overleaf?.unstable,
+        store: scopeStore,
+      },
+    }
+  }, [scopeStore])
+
   const value = useMemo<IdeContextValue>(() => {
     return {
       ...ide,

+ 6 - 0
services/web/types/window.ts

@@ -4,6 +4,7 @@ import { OverallThemeMeta } from './project-settings'
 import { User } from './user'
 import 'recurly__recurly-js'
 import { UserSettings } from './user-settings'
+import { ScopeValueStore } from './ide/scope-value-store'
 
 declare global {
   // eslint-disable-next-line no-unused-vars
@@ -44,5 +45,10 @@ declare global {
     expectingLinkedFileRefreshedSocketFor?: string | null
     writefull?: any
     io?: any
+    overleaf: {
+      unstable: {
+        store: ScopeValueStore
+      }
+    }
   }
 }