Przeglądaj źródła

Add Markdown visual editor support

GitOrigin-RevId: 4ec2ffb276c729a58f82ccb26ed571f4187a4178
Domagoj Kriskovic 2 miesięcy temu
rodzic
commit
5cf1b43ce7

+ 1 - 0
services/web/app/src/Features/Project/ProjectController.mjs

@@ -486,6 +486,7 @@ const _ProjectController = {
       'command-palette',
       'overleaf-library',
       'compile-timeout-cta',
+      'markdown-visual',
     ].filter(Boolean)
 
     const getUserValues = async userId =>

+ 1 - 0
services/web/config/settings.defaults.js

@@ -1027,6 +1027,7 @@ module.exports = {
     tprFileViewNotOriginalImporter: [],
     contactUsModal: [],
     sourceEditorExtensions: [],
+    sourceEditorVisualExtensions: [],
     sourceEditorComponents: [],
     pdfLogEntryHeaderActionComponents: [],
     pdfLogEntryComponents: [],

+ 1 - 1
services/web/frontend/extracted-translations.json

@@ -2350,7 +2350,7 @@
   "viewing": "",
   "viewing_x": "",
   "visual": "",
-  "visual_editor_is_only_available_for_tex_files": "",
+  "visual_editor_does_not_support_this_file_type": "",
   "want_change_to_apply_before_plan_end": "",
   "warnings": "",
   "we_are_unable_to_opt_you_into_this_experiment": "",

+ 1 - 1
services/web/frontend/js/features/source-editor/components/editor-switch.tsx

@@ -100,7 +100,7 @@ const RichTextToggle: FC<{
   if (disabled) {
     return (
       <OLTooltip
-        description={t('visual_editor_is_only_available_for_tex_files')}
+        description={t('visual_editor_does_not_support_this_file_type')}
         id="rich-text-toggle-tooltip"
         overlayProps={{ placement: 'bottom' }}
         tooltipProps={{ className: 'tooltip-wide' }}

+ 11 - 0
services/web/frontend/js/features/source-editor/extensions/visual/visual.ts

@@ -9,6 +9,7 @@ import {
 import { visualHighlightStyle, visualTheme } from './visual-theme'
 import { atomicDecorations } from './atomic-decorations'
 import { markDecorations } from './mark-decorations'
+import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
 import { EditorView, ViewPlugin } from '@codemirror/view'
 import { visualKeymap } from './visual-keymap'
 import { mousedown, mouseDownEffect } from './selection'
@@ -27,6 +28,15 @@ type Options = {
   previewByPath: (path: string) => PreviewPath | null
 }
 
+// Language-specific visual editor extensions provided by modules (e.g. the
+// markdown visual editor). They live in the visual bundle so they are only
+// active in visual mode and react to switching editor modes.
+const visualEditorExtensions: Array<(options: Options) => Extension> =
+  importOverleafModules('sourceEditorVisualExtensions').map(
+    (item: { import: { extension: (options: Options) => Extension } }) =>
+      item.import.extension
+  )
+
 const visualConf = new Compartment()
 
 export const toggleVisualEffect = StateEffect.define<boolean>()
@@ -171,6 +181,7 @@ const extension = (options: Options) => [
   mousedown,
   listItemMarker,
   atomicDecorations(options),
+  visualEditorExtensions.map(extension => extension(options)),
   markDecorations, // NOTE: must be after atomicDecorations, so that mark decorations wrap inline widgets
   visualKeymap,
   commandTooltip,

+ 3 - 2
services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts

@@ -63,7 +63,7 @@ import { useActiveOverallTheme } from '@/shared/hooks/use-active-overall-theme'
 import { useEditorSelectionContext } from '@/shared/context/editor-selection-context'
 import { useActiveEditorTheme } from '@/shared/hooks/use-active-editor-theme'
 import { useFeatureFlag } from '@/shared/context/split-test-context'
-import { isValidTeXFile } from '@/main/is-valid-tex-file'
+import { isCmVisualEditorAvailable } from '../utils/visual-editor'
 
 function useCodeMirrorScope(view: EditorView) {
   const { fileTreeData } = useFileTreeData()
@@ -277,7 +277,8 @@ function useCodeMirrorScope(view: EditorView) {
 
   const { previewByPath } = useFileTreePathContext()
 
-  const showVisual = visual && !!openDocName && isValidTeXFile(openDocName)
+  const showVisual =
+    visual && !!openDocName && isCmVisualEditorAvailable(openDocName)
 
   const visualRef = useRef({
     previewByPath,

+ 26 - 2
services/web/frontend/js/features/source-editor/utils/visual-editor.ts

@@ -2,13 +2,37 @@ import importOverleafModules from '../../../../macros/import-overleaf-module.mac
 import { isValidTeXFile } from '../../../main/is-valid-tex-file'
 
 const visualEditorProviders = importOverleafModules('visualEditorProviders')
+const cmVisualEditorProviders = importOverleafModules(
+  'sourceEditorVisualExtensions'
+)
 
-export function isVisualEditorAvailable(filename: string): boolean {
-  // Core LaTeX visual editor
+/**
+ * This currently covers LaTeX and Markdown. Other file
+ * types (e.g. .bib) use module-provided visual editors that render their own
+ * component instead, so they must NOT enable the CodeMirror visual extensions.
+ */
+export function isCmVisualEditorAvailable(filename: string): boolean {
   if (isValidTeXFile(filename)) {
     return true
   }
 
+  for (const provider of cmVisualEditorProviders) {
+    if (provider.import.isCmVisualEditorFile?.(filename)) {
+      return true
+    }
+  }
+  return false
+}
+
+/**
+ * Whether any visual editor exists for the file, including module-provided
+ * ones. Drives the editor toggle UI and the default editor mode for a file.
+ */
+export function isVisualEditorAvailable(filename: string): boolean {
+  if (isCmVisualEditorAvailable(filename)) {
+    return true
+  }
+
   // Visual editors provided by modules
   for (const provider of visualEditorProviders) {
     if (provider.import.isVisualEditorAvailable(filename)) {

+ 0 - 1
services/web/locales/da.json

@@ -2039,7 +2039,6 @@
   "viewer": "Læser",
   "viewing_x": "Ser <0>__endTime__</0>",
   "visual_editor": "Visuel editor",
-  "visual_editor_is_only_available_for_tex_files": "Den visuelle editor er kun tilgængelig for TeX filer",
   "want_access_to_overleaf_premium_features_through_your_university": "Vil du have adgang til __appName__ Premium-funktioner gennem dit universitet?",
   "want_change_to_apply_before_plan_end": "Hvis du ønsker at denne ændring skal tage effekt før slutningen på din nuværende faktureringsperiode, kontakt os venligst.",
   "we_are_unable_to_opt_you_into_this_experiment": "Vi kan ikke melde dig til dette eksperiment lige nu. Tjek venligst at din organisation tillader denne funktion, eller prøv igen senere.",

+ 1 - 1
services/web/locales/en.json

@@ -2999,7 +2999,7 @@
   "viewing": "Viewing",
   "viewing_x": "Viewing <0>__endTime__</0>",
   "visual": "Visual",
-  "visual_editor_is_only_available_for_tex_files": "Visual Editor is only available for TeX files",
+  "visual_editor_does_not_support_this_file_type": "Visual Editor doesn’t support this file type",
   "want_access_to_overleaf_premium_features_through_your_university": "Want access to __appName__ premium features through your university?",
   "want_change_to_apply_before_plan_end": "If you wish this change to apply before the end of your current billing period, please contact us.",
   "warnings": "Warnings",

+ 0 - 1
services/web/locales/zh-CN.json

@@ -2369,7 +2369,6 @@
   "viewing": "视图",
   "viewing_x": "正在查看<0>__endTime__</0>",
   "visual_editor": "可视化编辑器",
-  "visual_editor_is_only_available_for_tex_files": "可视化编辑器仅适用于 TeX 文件",
   "want_access_to_overleaf_premium_features_through_your_university": "想要通过您的大学访问__appName__高级功能吗?",
   "want_change_to_apply_before_plan_end": "如果您希望在当前计费周期结束前应用此更改,请与我们联系。",
   "we_are_unable_to_opt_you_into_this_experiment": "目前我们无法让您加入此实验,请确保您的组织已允许此功能,或稍后重试。",