mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Module for loading per language visual editor extensions
GitOrigin-RevId: 5244e754337a1e48b8de63e881648b2397500b25
This commit is contained in:
committed by
Copybot
parent
9743c7006e
commit
7b3692ce6f
@@ -1027,7 +1027,7 @@ module.exports = {
|
||||
tprFileViewNotOriginalImporter: [],
|
||||
contactUsModal: [],
|
||||
sourceEditorExtensions: [],
|
||||
sourceEditorMarkdownExtensions: [],
|
||||
sourceEditorVisualExtensions: [],
|
||||
sourceEditorComponents: [],
|
||||
pdfLogEntryHeaderActionComponents: [],
|
||||
pdfLogEntryComponents: [],
|
||||
|
||||
@@ -157,7 +157,7 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
|
||||
? historyOT(options.currentDoc.currentDocument)
|
||||
: ranges(),
|
||||
trackDetachedComments(options.currentDoc),
|
||||
visual(options.visual),
|
||||
visual(options.docName, options.visual),
|
||||
mathPreview(options.settings.mathPreview),
|
||||
reviewTooltip(options.editorContextMenuEnabled),
|
||||
contextMenu(options.editorContextMenuEnabled),
|
||||
|
||||
@@ -22,20 +22,20 @@ import { commandTooltip } from '../command-tooltip'
|
||||
import { tableGeneratorTheme } from './table-generator'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
import { PreviewPath } from '../../../../../../types/preview-path'
|
||||
import { getFileExtension } from '../../utils/file'
|
||||
|
||||
type Options = {
|
||||
visual: boolean
|
||||
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('sourceEditorMarkdownExtensions').map(
|
||||
(item: { import: { extension: (options: Options) => Extension } }) =>
|
||||
item.import.extension
|
||||
)
|
||||
// Module-provided visual editors registered via the
|
||||
// `sourceEditorVisualExtensions` hook. Module exposes `getExtensions(ext)`,
|
||||
// returning the visual-mode extensions for that file extension. A module match takes precedence
|
||||
// over the LaTeX fallback
|
||||
const moduleVisualExtensionProviders: Array<{
|
||||
import: { getExtensions: (ext: string) => Extension }
|
||||
}> = importOverleafModules('sourceEditorVisualExtensions')
|
||||
|
||||
const visualConf = new Compartment()
|
||||
|
||||
@@ -56,12 +56,16 @@ const visualState = StateField.define<boolean>({
|
||||
})
|
||||
|
||||
const configureVisualExtensions = (options: Options) =>
|
||||
options.visual ? extension(options) : []
|
||||
options.visual ? sharedVisualExtensions() : []
|
||||
|
||||
export const visual = (docName: string, options: Options): Extension => {
|
||||
const extensions =
|
||||
visualModuleExtensions(docName) ?? latexVisualExtensions(options)
|
||||
|
||||
export const visual = (options: Options): Extension => {
|
||||
return [
|
||||
visualState.init(() => options.visual),
|
||||
visualConf.of(configureVisualExtensions(options)),
|
||||
visualOnly(options.visual, extensions),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -78,9 +82,17 @@ export const setVisual = (options: Options): TransactionSpec => {
|
||||
}
|
||||
}
|
||||
|
||||
export const sourceOnly = (visual: boolean, extension: Extension) => {
|
||||
// Loads `extension` only while the editor is in a particular mode, reacting to
|
||||
// mode switches via `toggleVisualEffect`. `activeWhenVisual` selects which mode:
|
||||
// `true` for visual-only, `false` for source-only.
|
||||
const modeOnly = (
|
||||
activeWhenVisual: boolean,
|
||||
visual: boolean,
|
||||
extension: Extension
|
||||
) => {
|
||||
const conf = new Compartment()
|
||||
const configure = (visual: boolean) => (visual ? [] : extension)
|
||||
const configure = (visual: boolean) =>
|
||||
visual === activeWhenVisual ? extension : []
|
||||
return [
|
||||
conf.of(configure(visual)),
|
||||
|
||||
@@ -98,6 +110,12 @@ export const sourceOnly = (visual: boolean, extension: Extension) => {
|
||||
]
|
||||
}
|
||||
|
||||
export const visualOnly = (visual: boolean, extension: Extension) =>
|
||||
modeOnly(true, visual, extension)
|
||||
|
||||
export const sourceOnly = (visual: boolean, extension: Extension) =>
|
||||
modeOnly(false, visual, extension)
|
||||
|
||||
const parsedAttributesConf = new Compartment()
|
||||
|
||||
/**
|
||||
@@ -175,19 +193,39 @@ const scrollJumpAdjuster = EditorState.transactionExtender.of(tr => {
|
||||
return {}
|
||||
})
|
||||
|
||||
const extension = (options: Options) => [
|
||||
const sharedVisualExtensions = () => [
|
||||
visualTheme,
|
||||
visualHighlightStyle,
|
||||
mousedown,
|
||||
scrollJumpAdjuster,
|
||||
showContentWhenParsed,
|
||||
EditorView.contentAttributes.of({ 'aria-label': 'Visual Editor editing' }),
|
||||
]
|
||||
|
||||
const latexVisualExtensions = (options: Options): Extension => [
|
||||
listItemMarker,
|
||||
atomicDecorations(options),
|
||||
visualEditorExtensions.map(extension => extension(options)),
|
||||
markDecorations, // NOTE: must be after atomicDecorations, so that mark decorations wrap inline widgets
|
||||
visualKeymap,
|
||||
commandTooltip,
|
||||
scrollJumpAdjuster,
|
||||
showContentWhenParsed,
|
||||
pasteHtml,
|
||||
tableGeneratorTheme,
|
||||
EditorView.contentAttributes.of({ 'aria-label': 'Visual Editor editing' }),
|
||||
]
|
||||
|
||||
// Returns the visual-mode extensions provided by a module for the active document
|
||||
const visualModuleExtensions = (docName: string): Extension | null => {
|
||||
const fileExt = getFileExtension(docName)
|
||||
if (!fileExt) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (const provider of moduleVisualExtensionProviders) {
|
||||
const extensions = provider.import.getExtensions(fileExt)
|
||||
if (Array.isArray(extensions) && extensions.length === 0) {
|
||||
continue
|
||||
}
|
||||
return extensions
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||
import { isValidTeXFile } from '../../../main/is-valid-tex-file'
|
||||
import { getFileExtension } from './file'
|
||||
|
||||
const visualEditorProviders = importOverleafModules('visualEditorProviders')
|
||||
const cmVisualEditorProviders = importOverleafModules(
|
||||
'sourceEditorMarkdownExtensions'
|
||||
)
|
||||
const cmVisualEditorProviders: Array<{
|
||||
import: { getExtensions: (ext: string) => unknown }
|
||||
}> = importOverleafModules('sourceEditorVisualExtensions')
|
||||
|
||||
/**
|
||||
* This currently covers LaTeX and Markdown. Other file
|
||||
@@ -16,8 +17,16 @@ export function isCmVisualEditorAvailable(filename: string): boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
const extension = getFileExtension(filename)
|
||||
if (extension === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
for (const provider of cmVisualEditorProviders) {
|
||||
if (provider.import.isCmVisualEditorFile?.(filename)) {
|
||||
const extensions = provider.import.getExtensions(extension)
|
||||
if (
|
||||
Array.isArray(extensions) ? extensions.length > 0 : extensions != null
|
||||
) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user