da6a407445
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
/**
|
|
* useFileEditor — resolves which registered editor can handle a given MIME type.
|
|
*
|
|
* Other modules register editors at the `documents_file_editor` integration
|
|
* point by including an entry in their `integrations.ts`:
|
|
*
|
|
* ```ts
|
|
* documents_file_editor: [{
|
|
* id: 'my_editor',
|
|
* meta: { mimeTypes: ['text/plain'] },
|
|
* component: () => import('./components/MyEditor.vue'),
|
|
* }]
|
|
* ```
|
|
*
|
|
* Editor components receive the props:
|
|
* `entity: EntityObject`, `mime: string`,
|
|
* `readFile: (entityId: string) => Promise<string | null>`,
|
|
* `writeFile: (entityId: string, content: string) => Promise<number>`
|
|
*/
|
|
|
|
import { useIntegrationStore } from '@KTXC'
|
|
import type { EntityObject } from '@DocumentsManager/models/entity'
|
|
|
|
const INTEGRATION_POINT = 'documents_file_editor'
|
|
|
|
function mimeMatchesPattern(mime: string, pattern: string): boolean {
|
|
if (pattern.endsWith('/*')) {
|
|
return mime.startsWith(pattern.slice(0, -1))
|
|
}
|
|
return mime === pattern
|
|
}
|
|
|
|
function editorMatchesMime(
|
|
mime: string,
|
|
mimeTypes?: string[],
|
|
mimePatterns?: string[],
|
|
): boolean {
|
|
if (mimeTypes?.includes(mime)) return true
|
|
if (mimePatterns) {
|
|
for (const pattern of mimePatterns) {
|
|
if (mimeMatchesPattern(mime, pattern)) return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
export function useFileEditor() {
|
|
const integrationStore = useIntegrationStore()
|
|
|
|
/**
|
|
* Returns the highest-priority registered editor that can handle `mime`,
|
|
* or `null` if none is found.
|
|
*/
|
|
function findEditor(mime: string) {
|
|
const editors = integrationStore.getItems(INTEGRATION_POINT)
|
|
for (const editor of editors) {
|
|
if (
|
|
editorMatchesMime(
|
|
mime,
|
|
editor.meta?.mimeTypes as string[] | undefined,
|
|
editor.meta?.mimePatterns as string[] | undefined,
|
|
)
|
|
) {
|
|
return editor
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Convenience: returns true if any registered editor can handle this entity.
|
|
*/
|
|
function canEdit(entity: EntityObject): boolean {
|
|
const mime = entity.properties.mime
|
|
if (!mime) return false
|
|
return findEditor(mime) !== null
|
|
}
|
|
|
|
return { findEditor, canEdit }
|
|
}
|
|
|
|
export type UseFileEditorReturn = ReturnType<typeof useFileEditor>
|