@ecsplico/editor 2.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -1
- package/README.md +39 -156
- package/dist/adapters/comments/drizzle.d.ts +1 -1
- package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
- package/dist/adapters/comments/rest-model.js.map +1 -0
- package/dist/adapters/comments/types.d.ts +2 -2
- package/dist/adapters/document-state.d.ts +23 -0
- package/dist/adapters/document-state.js +66 -0
- package/dist/adapters/document-state.js.map +1 -0
- package/dist/adapters/documents.js +14 -11
- package/dist/adapters/documents.js.map +1 -1
- package/dist/adapters/drizzle.d.ts +2 -2
- package/dist/adapters/drizzle.js +97 -88
- package/dist/adapters/drizzle.js.map +1 -1
- package/dist/adapters/forge.d.ts +12 -7
- package/dist/adapters/forge.js +38 -45
- package/dist/adapters/forge.js.map +1 -1
- package/dist/adapters/http.d.ts +20 -0
- package/dist/adapters/http.js +68 -0
- package/dist/adapters/http.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/json.d.ts +3 -3
- package/dist/adapters/json.js +58 -49
- package/dist/adapters/json.js.map +1 -1
- package/dist/adapters/memory.d.ts +21 -0
- package/dist/adapters/memory.js +53 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/nitro.d.ts +23 -20
- package/dist/adapters/nitro.js +58 -163
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/react.d.ts +55 -0
- package/dist/adapters/react.js +209 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/shared.d.ts +15 -21
- package/dist/adapters/shared.js +10 -8
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/vue.d.ts +15 -30
- package/dist/adapters/vue.js +36 -87
- package/dist/adapters/vue.js.map +1 -1
- package/dist/code/CodeSurface.vue.d.ts +3 -3
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.js +95 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/abilities.js +1 -0
- package/dist/core/abilities.js.map +1 -1
- package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
- package/dist/core/api-routes.js.map +1 -0
- package/dist/core/backend-capability.d.ts +7 -0
- package/dist/core/backend-capability.js +17 -0
- package/dist/core/backend-capability.js.map +1 -0
- package/dist/core/backend-types.d.ts +245 -0
- package/dist/core/backend-types.js +17 -0
- package/dist/core/backend-types.js.map +1 -0
- package/dist/core/backend.d.ts +108 -0
- package/dist/core/backend.js +14 -0
- package/dist/core/backend.js.map +1 -0
- package/dist/core/block-convert.d.ts +7 -5
- package/dist/core/block-convert.js +28 -5
- package/dist/core/block-convert.js.map +1 -1
- package/dist/core/command-types.d.ts +89 -0
- package/dist/core/commands.d.ts +40 -0
- package/dist/core/commands.js +151 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/context.d.ts +17 -20
- package/dist/core/context.js +24 -21
- package/dist/core/context.js.map +1 -1
- package/dist/core/core-feature.d.ts +22 -7
- package/dist/core/core-feature.js +51 -18
- package/dist/core/core-feature.js.map +1 -1
- package/dist/core/define-editor.d.ts +4 -3
- package/dist/core/define-editor.js +14 -7
- package/dist/core/define-editor.js.map +1 -1
- package/dist/core/document-markdown.js +12 -3
- package/dist/core/document-markdown.js.map +1 -1
- package/dist/core/editor-ui.d.ts +8 -1
- package/dist/core/editor-ui.js +9 -8
- package/dist/core/editor-ui.js.map +1 -1
- package/dist/core/extension-points.d.ts +3 -15
- package/dist/core/feature-context.d.ts +8 -7
- package/dist/core/feature-context.js +12 -11
- package/dist/core/feature-context.js.map +1 -1
- package/dist/core/feature.d.ts +35 -19
- package/dist/core/feature.js.map +1 -1
- package/dist/core/fences.d.ts +2 -1
- package/dist/core/fences.js +3 -2
- package/dist/core/fences.js.map +1 -1
- package/dist/core/fetch-error.d.ts +1 -1
- package/dist/core/fetch-error.js +3 -1
- package/dist/core/fetch-error.js.map +1 -1
- package/dist/core/hash.d.ts +5 -0
- package/dist/core/hash.js +11 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/http-backend.d.ts +11 -0
- package/dist/core/http-backend.js +195 -0
- package/dist/core/http-backend.js.map +1 -0
- package/dist/core/index.d.ts +14 -9
- package/dist/core/index.js +12 -9
- package/dist/core/palette.d.ts +48 -0
- package/dist/core/palette.js +95 -0
- package/dist/core/palette.js.map +1 -0
- package/dist/core/schema/abilities.d.ts +2 -1
- package/dist/core/schema/abilities.js +5 -1
- package/dist/core/schema/abilities.js.map +1 -1
- package/dist/core/schema/index.d.ts +11 -5
- package/dist/core/schema/index.js +13 -8
- package/dist/core/schema/index.js.map +1 -1
- package/dist/core/schema/mark-flags.d.ts +8 -1
- package/dist/core/schema/of-features.d.ts +13 -0
- package/dist/core/schema/of-features.js +14 -0
- package/dist/core/schema/of-features.js.map +1 -0
- package/dist/core/slash.d.ts +8 -6
- package/dist/core/slash.js +24 -16
- package/dist/core/slash.js.map +1 -1
- package/dist/core/surface-session.js +13 -5
- package/dist/core/surface-session.js.map +1 -1
- package/dist/core/toolbar-items.d.ts +10 -4
- package/dist/core/toolbar-items.js +269 -195
- package/dist/core/toolbar-items.js.map +1 -1
- package/dist/core/util.js +11 -0
- package/dist/core/util.js.map +1 -0
- package/dist/document/DocumentSurface.d.ts +1 -1
- package/dist/document/DocumentSurface.vue.d.ts +3 -3
- package/dist/features/ai/agent-op-review.d.ts +1 -1
- package/dist/features/ai/agent-op-review.js +1 -1
- package/dist/features/ai/agent-ops.js +1 -1
- package/dist/features/ai/ai-apply.d.ts +2 -2
- package/dist/features/ai/ai-apply.js +1 -1
- package/dist/features/ai/ai-review.js +1 -1
- package/dist/features/ai/ai-sse.d.ts +6 -6
- package/dist/features/ai/ai-sse.js +20 -63
- package/dist/features/ai/ai-sse.js.map +1 -1
- package/dist/features/ai/assistant.d.ts +8 -7
- package/dist/features/ai/assistant.js +3 -3
- package/dist/features/ai/assistant.js.map +1 -1
- package/dist/features/ai/block-actions.d.ts +3 -2
- package/dist/features/ai/block-actions.js +3 -2
- package/dist/features/ai/block-actions.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js +1 -1
- package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
- package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/document-chat-model.d.ts +8 -7
- package/dist/features/ai/document-chat-model.js +5 -5
- package/dist/features/ai/document-chat-model.js.map +1 -1
- package/dist/features/ai/document-chat.js +1 -1
- package/dist/features/ai/feature.js +27 -14
- package/dist/features/ai/feature.js.map +1 -1
- package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
- package/dist/features/ai/ghost-autocomplete.js +6 -9
- package/dist/features/ai/ghost-autocomplete.js.map +1 -1
- package/dist/features/ai/index.d.ts +4 -3
- package/dist/features/ai/index.js +10 -10
- package/dist/features/ai/model-profiles.d.ts +5 -4
- package/dist/features/ai/model-profiles.js +2 -2
- package/dist/features/ai/model-profiles.js.map +1 -1
- package/dist/features/ai/protocol/block-lines.js +1 -1
- package/dist/features/ai/protocol/block-lines.js.map +1 -1
- package/dist/features/ai/protocol/chat.js +4 -1
- package/dist/features/ai/protocol/chat.js.map +1 -1
- package/dist/features/ai/protocol/index.d.ts +3 -2
- package/dist/features/ai/protocol/models.d.ts +2 -16
- package/dist/features/ai/protocol/models.js.map +1 -1
- package/dist/features/ai/rate-limit.d.ts +1 -1
- package/dist/features/ai/rate-limit.js +3 -1
- package/dist/features/ai/rate-limit.js.map +1 -1
- package/dist/features/ai/react/AiSelectionMenu.js +2 -2
- package/dist/features/ai/react/AiSidebar.js +4 -4
- package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
- package/dist/features/ai/react/DocumentChatOps.js +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
- package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/react/use-ai-assistant.js +3 -3
- package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/react/use-document-chat.js +2 -2
- package/dist/features/ai/react/use-document-chat.js.map +1 -1
- package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
- package/dist/features/ai/selection-flow.d.ts +1 -1
- package/dist/features/ai/selection-flow.js +1 -1
- package/dist/features/ai/sidebar-flow.d.ts +1 -1
- package/dist/features/ai/sidebar-flow.js +1 -1
- package/dist/features/ai/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/use-ai-assistant.js +3 -3
- package/dist/features/ai/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/use-document-chat.js +2 -2
- package/dist/features/ai/use-document-chat.js.map +1 -1
- package/dist/features/ai/use-model-profiles.d.ts +2 -1
- package/dist/features/authors/attribution.d.ts +1 -1
- package/dist/features/authors/feature.js +12 -11
- package/dist/features/authors/feature.js.map +1 -1
- package/dist/features/block-ui/block-actions.d.ts +22 -1
- package/dist/features/block-ui/block-actions.js +26 -2
- package/dist/features/block-ui/block-actions.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.js +33 -4
- package/dist/features/block-ui/components/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.vue.d.ts +4 -0
- package/dist/features/block-ui/components/BlockUi.js +1 -1
- package/dist/features/block-ui/feature.js +1 -0
- package/dist/features/block-ui/feature.js.map +1 -1
- package/dist/features/block-ui/index.d.ts +2 -2
- package/dist/features/block-ui/index.js +2 -2
- package/dist/features/block-ui/react/BlockActionsOverlay.d.ts +4 -0
- package/dist/features/block-ui/react/BlockActionsOverlay.js +38 -12
- package/dist/features/block-ui/react/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/react/BlockUi.js +1 -1
- package/dist/features/collab/anchor-resolver.js +1 -1
- package/dist/features/collab/feature.js +2 -0
- package/dist/features/collab/feature.js.map +1 -1
- package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
- package/dist/features/comments/feature.js +12 -11
- package/dist/features/comments/feature.js.map +1 -1
- package/dist/features/comments/index.d.ts +3 -2
- package/dist/features/comments/index.js +1 -1
- package/dist/features/comments/margin-layout.d.ts +3 -2
- package/dist/features/comments/model.d.ts +3 -67
- package/dist/features/comments/model.js +2 -2
- package/dist/features/comments/model.js.map +1 -1
- package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
- package/dist/features/comments/react/use-comments.d.ts +2 -1
- package/dist/features/comments/react.d.ts +1 -1
- package/dist/features/comments/schema.d.ts +2 -52
- package/dist/features/comments/schema.js.map +1 -1
- package/dist/features/comments/snapshot-equality.js.map +1 -1
- package/dist/features/comments/use-comments.d.ts +3 -2
- package/dist/features/comments/vue.d.ts +1 -1
- package/dist/features/composites/accepted-children.d.ts +1 -0
- package/dist/features/composites/accepted-children.js +16 -1
- package/dist/features/composites/accepted-children.js.map +1 -1
- package/dist/features/composites/ai-brief.js +31 -0
- package/dist/features/composites/ai-brief.js.map +1 -1
- package/dist/features/composites/bibliography-command.d.ts +11 -0
- package/dist/features/composites/bibliography-form.js +90 -0
- package/dist/features/composites/bibliography-form.js.map +1 -0
- package/dist/features/composites/bibliography.d.ts +33 -0
- package/dist/features/composites/bibliography.js +120 -0
- package/dist/features/composites/bibliography.js.map +1 -0
- package/dist/features/composites/components/BibliographyEditor.js +261 -0
- package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/components/CompositeChrome.js +75 -26
- package/dist/features/composites/components/CompositeChrome.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.js +46 -11
- package/dist/features/composites/components/CompositeDetails.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
- package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
- package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeInspector.js +17 -5
- package/dist/features/composites/components/CompositeInspector.js.map +1 -1
- package/dist/features/composites/components/CompositeTable.js +13 -4
- package/dist/features/composites/components/CompositeTable.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/components/CompositeView.js +11 -1
- package/dist/features/composites/components/CompositeView.js.map +1 -1
- package/dist/features/composites/components/DerivationBadge.js +103 -0
- package/dist/features/composites/components/DerivationBadge.js.map +1 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.js +122 -0
- package/dist/features/composites/components/ReferenceView.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
- package/dist/features/composites/components/SettingsEditingTab.js +1 -1
- package/dist/features/composites/convert.js +2 -2
- package/dist/features/composites/convert.js.map +1 -1
- package/dist/features/composites/derivation.d.ts +61 -0
- package/dist/features/composites/derivation.js +98 -0
- package/dist/features/composites/derivation.js.map +1 -0
- package/dist/features/composites/derived-chrome.js +69 -0
- package/dist/features/composites/derived-chrome.js.map +1 -0
- package/dist/features/composites/feature.js +159 -109
- package/dist/features/composites/feature.js.map +1 -1
- package/dist/features/composites/fences.d.ts +4 -3
- package/dist/features/composites/fences.js +51 -7
- package/dist/features/composites/fences.js.map +1 -1
- package/dist/features/composites/index.d.ts +12 -3
- package/dist/features/composites/index.js +15 -6
- package/dist/features/composites/inspector-model.d.ts +4 -1
- package/dist/features/composites/inspector-model.js +8 -4
- package/dist/features/composites/inspector-model.js.map +1 -1
- package/dist/features/composites/kinds.d.ts +8 -1
- package/dist/features/composites/kinds.js +145 -6
- package/dist/features/composites/kinds.js.map +1 -1
- package/dist/features/composites/legacy.d.ts +4 -1
- package/dist/features/composites/legacy.js +56 -1
- package/dist/features/composites/legacy.js.map +1 -1
- package/dist/features/composites/meta-display.js +40 -1
- package/dist/features/composites/meta-display.js.map +1 -1
- package/dist/features/composites/meta-keys.d.ts +7 -0
- package/dist/features/composites/meta-keys.js +21 -0
- package/dist/features/composites/meta-keys.js.map +1 -0
- package/dist/features/composites/node-views.d.ts +6 -3
- package/dist/features/composites/node-views.js +7 -3
- package/dist/features/composites/node-views.js.map +1 -1
- package/dist/features/composites/nodes.d.ts +6 -1
- package/dist/features/composites/nodes.js +33 -7
- package/dist/features/composites/nodes.js.map +1 -1
- package/dist/features/composites/react/BibliographyEditor.js +229 -0
- package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/react/CompositeChrome.js +65 -17
- package/dist/features/composites/react/CompositeChrome.js.map +1 -1
- package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
- package/dist/features/composites/react/CompositeDetails.js +45 -6
- package/dist/features/composites/react/CompositeDetails.js.map +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
- package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeInspector.js +11 -5
- package/dist/features/composites/react/CompositeInspector.js.map +1 -1
- package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/react/CompositeTable.js +16 -2
- package/dist/features/composites/react/CompositeTable.js.map +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
- package/dist/features/composites/react/CompositeView.js +6 -1
- package/dist/features/composites/react/CompositeView.js.map +1 -1
- package/dist/features/composites/react/DerivationBadge.js +116 -0
- package/dist/features/composites/react/DerivationBadge.js.map +1 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/react/ReferenceView.d.ts +11 -0
- package/dist/features/composites/react/ReferenceView.js +115 -0
- package/dist/features/composites/react/ReferenceView.js.map +1 -0
- package/dist/features/composites/react/SettingsEditingTab.js +2 -2
- package/dist/features/composites/react.d.ts +2 -1
- package/dist/features/composites/react.js +7 -3
- package/dist/features/composites/react.js.map +1 -1
- package/dist/features/composites/reference-ai.js +16 -0
- package/dist/features/composites/reference-ai.js.map +1 -0
- package/dist/features/composites/reference-label.d.ts +19 -0
- package/dist/features/composites/reference-label.js +58 -0
- package/dist/features/composites/reference-label.js.map +1 -0
- package/dist/features/composites/reference-suggestion.d.ts +10 -0
- package/dist/features/composites/reference-suggestion.js +41 -0
- package/dist/features/composites/reference-suggestion.js.map +1 -0
- package/dist/features/composites/reference-text.d.ts +18 -0
- package/dist/features/composites/reference-text.js +89 -0
- package/dist/features/composites/reference-text.js.map +1 -0
- package/dist/features/composites/reference.d.ts +44 -0
- package/dist/features/composites/reference.js +148 -0
- package/dist/features/composites/reference.js.map +1 -0
- package/dist/features/composites/reveal-source.d.ts +32 -0
- package/dist/features/composites/reveal-source.js +89 -0
- package/dist/features/composites/reveal-source.js.map +1 -0
- package/dist/features/composites/rows.d.ts +21 -2
- package/dist/features/composites/rows.js +63 -9
- package/dist/features/composites/rows.js.map +1 -1
- package/dist/features/composites/schema.d.ts +9 -3
- package/dist/features/composites/schema.js +11 -4
- package/dist/features/composites/schema.js.map +1 -1
- package/dist/features/composites/table-model.js +12 -21
- package/dist/features/composites/table-model.js.map +1 -1
- package/dist/features/composites/vue.d.ts +3 -2
- package/dist/features/composites/vue.js +8 -4
- package/dist/features/composites/vue.js.map +1 -1
- package/dist/features/media/assets.d.ts +2 -0
- package/dist/features/media/assets.js +3 -2
- package/dist/features/media/assets.js.map +1 -1
- package/dist/features/media/components/FileView.js +13 -4
- package/dist/features/media/components/FileView.js.map +1 -1
- package/dist/features/media/feature.d.ts +3 -3
- package/dist/features/media/feature.js +21 -28
- package/dist/features/media/feature.js.map +1 -1
- package/dist/features/media/file-import.js +2 -2
- package/dist/features/media/file-import.js.map +1 -1
- package/dist/features/media/index.d.ts +2 -2
- package/dist/features/media/index.js +2 -2
- package/dist/features/media/react/FileView.js +19 -2
- package/dist/features/media/react/FileView.js.map +1 -1
- package/dist/features/media/schema.d.ts +8 -0
- package/dist/features/media/schema.js +126 -11
- package/dist/features/media/schema.js.map +1 -1
- package/dist/features/media/upload.d.ts +16 -14
- package/dist/features/media/upload.js +13 -19
- package/dist/features/media/upload.js.map +1 -1
- package/dist/features/mentions/index.d.ts +4 -3
- package/dist/features/mentions/index.js +4 -1
- package/dist/features/mentions/index.js.map +1 -1
- package/dist/features/mentions/mention-text.d.ts +1 -1
- package/dist/features/mentions/mention-text.js.map +1 -1
- package/dist/features/mentions/mention.d.ts +0 -6
- package/dist/features/mentions/mention.js.map +1 -1
- package/dist/features/mentions/metadata-defaults.d.ts +2 -2
- package/dist/features/mentions/metadata-defaults.js +3 -9
- package/dist/features/mentions/metadata-defaults.js.map +1 -1
- package/dist/features/mentions/schema.d.ts +2 -1
- package/dist/features/mentions/schema.js.map +1 -1
- package/dist/features/tables/feature.d.ts +2 -1
- package/dist/features/tables/feature.js +90 -70
- package/dist/features/tables/feature.js.map +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
- package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/feature.js +2 -0
- package/dist/features/themes/feature.js.map +1 -1
- package/dist/features/themes/index.d.ts +2 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
- package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/schema.d.ts +2 -6
- package/dist/features/themes/schema.js.map +1 -1
- package/dist/features/themes/theme-runtime.d.ts +1 -1
- package/dist/features/themes/theme-runtime.js +4 -2
- package/dist/features/themes/theme-runtime.js.map +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js +48 -28
- package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/feature.js +21 -19
- package/dist/features/transcript/feature.js.map +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
- package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/segment-node.d.ts +2 -0
- package/dist/features/transcript/segment-node.js +35 -7
- package/dist/features/transcript/segment-node.js.map +1 -1
- package/dist/i18n/de/composites.js +91 -1
- package/dist/i18n/de/composites.js.map +1 -1
- package/dist/i18n/de/integrations.js +49 -8
- package/dist/i18n/de/integrations.js.map +1 -1
- package/dist/i18n/de/media.js +0 -1
- package/dist/i18n/de/media.js.map +1 -1
- package/dist/i18n/de/palette.js +22 -0
- package/dist/i18n/de/palette.js.map +1 -0
- package/dist/i18n/de/tables.js +0 -1
- package/dist/i18n/de/tables.js.map +1 -1
- package/dist/i18n/de/transcript.js +2 -1
- package/dist/i18n/de/transcript.js.map +1 -1
- package/dist/i18n/de/tree.js +3 -0
- package/dist/i18n/de/tree.js.map +1 -1
- package/dist/i18n/de.d.ts +157 -11
- package/dist/i18n/de.js +3 -1
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en/composites.js +89 -1
- package/dist/i18n/en/composites.js.map +1 -1
- package/dist/i18n/en/integrations.js +49 -8
- package/dist/i18n/en/integrations.js.map +1 -1
- package/dist/i18n/en/media.js +0 -1
- package/dist/i18n/en/media.js.map +1 -1
- package/dist/i18n/en/palette.js +22 -0
- package/dist/i18n/en/palette.js.map +1 -0
- package/dist/i18n/en/tables.js +0 -1
- package/dist/i18n/en/tables.js.map +1 -1
- package/dist/i18n/en/transcript.js +2 -1
- package/dist/i18n/en/transcript.js.map +1 -1
- package/dist/i18n/en/tree.js +3 -0
- package/dist/i18n/en/tree.js.map +1 -1
- package/dist/i18n/en.js +3 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
- package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
- package/dist/integrations/composite-ai/composite-fill.js +97 -56
- package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
- package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
- package/dist/integrations/composite-ai/composite-summary.js +7 -26
- package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
- package/dist/integrations/composite-ai/derive.d.ts +29 -0
- package/dist/integrations/composite-ai/derive.js +173 -0
- package/dist/integrations/composite-ai/derive.js.map +1 -0
- package/dist/integrations/composite-ai/index.d.ts +11 -7
- package/dist/integrations/composite-ai/index.js +72 -14
- package/dist/integrations/composite-ai/index.js.map +1 -1
- package/dist/integrations/composite-ai/rendition.d.ts +45 -0
- package/dist/integrations/composite-ai/rendition.js +314 -0
- package/dist/integrations/composite-ai/rendition.js.map +1 -0
- package/dist/integrations/composite-media/index.d.ts +7 -5
- package/dist/integrations/composite-media/index.js +86 -13
- package/dist/integrations/composite-media/index.js.map +1 -1
- package/dist/integrations/transcript-ai/index.d.ts +1 -1
- package/dist/integrations/transcript-ai/index.js +5 -2
- package/dist/integrations/transcript-ai/index.js.map +1 -1
- package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
- package/dist/integrations/transcript-ai/protocol.js +0 -2
- package/dist/integrations/transcript-ai/protocol.js.map +1 -1
- package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
- package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
- package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
- package/dist/markdown/MarkdownSurface.vue.d.ts +10 -9
- package/dist/markdown/MarkdownSurface2.js +3 -6
- package/dist/markdown/MarkdownSurface2.js.map +1 -1
- package/dist/markdown/document.js +1 -1
- package/dist/markdown/source-mode.d.ts +1 -1
- package/dist/nuxt/module.d.ts +1402 -54
- package/dist/nuxt/module.js +6 -49
- package/dist/nuxt/module.js.map +1 -1
- package/dist/nuxt/runtime/install-context.d.ts +7 -3
- package/dist/nuxt/runtime/install-context.js +14 -8
- package/dist/nuxt/runtime/install-context.js.map +1 -1
- package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
- package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
- package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
- package/dist/presets/compose.d.ts +94 -0
- package/dist/presets/compose.js +164 -0
- package/dist/presets/compose.js.map +1 -0
- package/dist/react/AdvancedEditor.d.ts +15 -15
- package/dist/react/AdvancedEditor.js +15 -13
- package/dist/react/AdvancedEditor.js.map +1 -1
- package/dist/react/EditorCommandPalette.d.ts +13 -0
- package/dist/react/EditorCommandPalette.js +118 -0
- package/dist/react/EditorCommandPalette.js.map +1 -0
- package/dist/react/EditorSettingsModal.d.ts +5 -5
- package/dist/react/EditorSettingsModal.js +7 -4
- package/dist/react/EditorSettingsModal.js.map +1 -1
- package/dist/react/EditorSettingsPanel.d.ts +7 -7
- package/dist/react/EditorSettingsPanel.js +8 -5
- package/dist/react/EditorSettingsPanel.js.map +1 -1
- package/dist/react/EditorSurface.d.ts +7 -7
- package/dist/react/EditorSurface.js +10 -6
- package/dist/react/EditorSurface.js.map +1 -1
- package/dist/react/EditorToolbar.d.ts +4 -6
- package/dist/react/EditorToolbar.js +29 -37
- package/dist/react/EditorToolbar.js.map +1 -1
- package/dist/react/SimpleEditor.d.ts +22 -23
- package/dist/react/SimpleEditor.js +21 -7
- package/dist/react/SimpleEditor.js.map +1 -1
- package/dist/react/advanced.d.ts +4 -3
- package/dist/react/advanced.js +2 -2
- package/dist/react/compose.d.ts +20 -0
- package/dist/react/compose.js +49 -0
- package/dist/react/compose.js.map +1 -0
- package/dist/react/composed-surface.d.ts +39 -0
- package/dist/react/composed-surface.js +71 -0
- package/dist/react/composed-surface.js.map +1 -0
- package/dist/react/context.js +6 -2
- package/dist/react/context.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +2 -1
- package/dist/react/key-labels.js +15 -0
- package/dist/react/key-labels.js.map +1 -0
- package/dist/react/settings.d.ts +1 -1
- package/dist/react/simple.d.ts +2 -2
- package/dist/react/ui/command.js +36 -1
- package/dist/react/ui/command.js.map +1 -1
- package/dist/schema/advanced.d.ts +6 -6
- package/dist/schema/advanced.js +26 -29
- package/dist/schema/advanced.js.map +1 -1
- package/dist/server/ai.d.ts +5 -16
- package/dist/server/ai.js.map +1 -1
- package/dist/server/auth.d.ts +9 -0
- package/dist/server/collab-state.d.ts +1 -1
- package/dist/server/collab-state.js.map +1 -1
- package/dist/server/collab.d.ts +13 -13
- package/dist/server/collab.js +34 -18
- package/dist/server/collab.js.map +1 -1
- package/dist/server/crossref.js +78 -0
- package/dist/server/crossref.js.map +1 -0
- package/dist/server/errors.d.ts +1 -1
- package/dist/server/errors.js +1 -1
- package/dist/server/errors.js.map +1 -1
- package/dist/server/extract.js +308 -0
- package/dist/server/extract.js.map +1 -0
- package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
- package/dist/server/h3.js.map +1 -0
- package/dist/server/handlers/ai.d.ts +30 -9
- package/dist/server/handlers/ai.js +170 -36
- package/dist/server/handlers/ai.js.map +1 -1
- package/dist/server/handlers/context.d.ts +12 -5
- package/dist/server/handlers/context.js +10 -4
- package/dist/server/handlers/context.js.map +1 -1
- package/dist/server/handlers/editor.d.ts +19 -13
- package/dist/server/handlers/editor.js +49 -38
- package/dist/server/handlers/editor.js.map +1 -1
- package/dist/server/handlers/index.d.ts +4 -4
- package/dist/server/handlers/index.js +4 -4
- package/dist/server/host.d.ts +16 -25
- package/dist/server/host.js +58 -41
- package/dist/server/host.js.map +1 -1
- package/dist/server/index.d.ts +6 -4
- package/dist/server/index.js +3 -2
- package/dist/server/pdf.js +97 -0
- package/dist/server/pdf.js.map +1 -0
- package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
- package/dist/server/ports.js +29 -0
- package/dist/server/ports.js.map +1 -0
- package/dist/server/routes.js +144 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.js.map +1 -1
- package/dist/styles/composites.css +25 -0
- package/dist/tree/DocumentTree.js +56 -29
- package/dist/tree/DocumentTree.js.map +1 -1
- package/dist/tree/react/DocumentTree.js +23 -0
- package/dist/tree/react/DocumentTree.js.map +1 -1
- package/dist/tree/tree-host.js +1 -1
- package/dist/vue/AdvancedEditor.js +30 -9
- package/dist/vue/AdvancedEditor.js.map +1 -1
- package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
- package/dist/vue/SimpleEditor.js +62 -16
- package/dist/vue/SimpleEditor.js.map +1 -1
- package/dist/vue/SimpleEditor.vue.d.ts +37 -7
- package/dist/vue/advanced.d.ts +3 -2
- package/dist/vue/advanced.js +2 -2
- package/dist/vue/components/EditorCommandPalette.js +91 -0
- package/dist/vue/components/EditorCommandPalette.js.map +1 -0
- package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
- package/dist/vue/components/EditorSettingsModal.js +10 -6
- package/dist/vue/components/EditorSettingsModal.js.map +1 -1
- package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
- package/dist/vue/components/EditorSettingsPanel.js +10 -6
- package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
- package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
- package/dist/vue/components/EditorSurface.js +11 -6
- package/dist/vue/components/EditorSurface.js.map +1 -1
- package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
- package/dist/vue/components/EditorToolbar.js +41 -49
- package/dist/vue/components/EditorToolbar.js.map +1 -1
- package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
- package/dist/vue/compose.d.ts +17 -0
- package/dist/vue/compose.js +51 -0
- package/dist/vue/compose.js.map +1 -0
- package/dist/vue/context-key.d.ts +6 -0
- package/dist/vue/context-key.js +6 -0
- package/dist/vue/context-key.js.map +1 -0
- package/dist/vue/context.d.ts +8 -6
- package/dist/vue/context.js +6 -5
- package/dist/vue/context.js.map +1 -1
- package/dist/vue/index.d.ts +10 -8
- package/dist/vue/index.js +10 -8
- package/dist/vue/kit/index.d.ts +2 -2
- package/dist/vue/kit/nuxt-ui.js +23 -0
- package/dist/vue/kit/nuxt-ui.js.map +1 -1
- package/dist/vue/kit/types.d.ts +40 -1
- package/package.json +30 -16
- package/dist/adapters/comments/client.d.ts +0 -64
- package/dist/adapters/comments/client.js.map +0 -1
- package/dist/adapters/routes.js.map +0 -1
- package/dist/core/toolbar.d.ts +0 -74
- package/dist/core/toolbar.js +0 -45
- package/dist/core/toolbar.js.map +0 -1
- package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
- package/dist/integrations/composite-ai/document-transcribe.js +0 -89
- package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
- package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
- package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
- package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
- package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
- package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
- package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
- package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
- package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
- package/dist/presets/advanced.d.ts +0 -33
- package/dist/presets/advanced.js +0 -50
- package/dist/presets/advanced.js.map +0 -1
- package/dist/presets/simple.d.ts +0 -9
- package/dist/presets/simple.js +0 -12
- package/dist/presets/simple.js.map +0 -1
- package/dist/react/advanced-preset.d.ts +0 -11
- package/dist/react/advanced-preset.js +0 -31
- package/dist/react/advanced-preset.js.map +0 -1
- package/dist/vue/advanced-preset.d.ts +0 -13
- package/dist/vue/advanced-preset.js +0 -33
- package/dist/vue/advanced-preset.js.map +0 -1
- package/docs/extending.md +0 -538
- package/docs/integration.md +0 -630
- package/docs/llms.md +0 -383
- package/docs/usage.md +0 -1076
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/features/composites/reference-ai.ts
|
|
2
|
+
/**
|
|
3
|
+
* How the chat and rewrite models learn the `reference` chip: written as Markdown text `[@<Block-ID>]`, which the
|
|
4
|
+
* composites feature's `normalize` stage turns back into a chip. Not a convert target (no conversion provider owns it).
|
|
5
|
+
*/
|
|
6
|
+
const REFERENCE_AI_BLOCK = {
|
|
7
|
+
id: "reference",
|
|
8
|
+
label: "Verweis",
|
|
9
|
+
description: "Inline-Verweis auf einen Baustein dieses Dokuments (Zitat, Quelle), optional mit Fundstelle (Seite oder Zeit).",
|
|
10
|
+
syntax: "[@<Block-ID>] oder [@<Block-ID>, S. 12]",
|
|
11
|
+
example: "Das zeigt die Studie [@0f3c9a52-7d1e-4b8a-9c2f-5e6d7a8b9c0d, S. 12]."
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { REFERENCE_AI_BLOCK };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=reference-ai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-ai.js","names":[],"sources":["../../../src/features/composites/reference-ai.ts"],"sourcesContent":["// i18n-ignore-file: model-facing block description (German prompt text, not UI)\nimport type { AiBlock } from '../../core/feature'\n\n/**\n * How the chat and rewrite models learn the `reference` chip: written as Markdown text `[@<Block-ID>]`, which the\n * composites feature's `normalize` stage turns back into a chip. Not a convert target (no conversion provider owns it).\n */\nexport const REFERENCE_AI_BLOCK: AiBlock = {\n id: 'reference',\n label: 'Verweis',\n description: 'Inline-Verweis auf einen Baustein dieses Dokuments (Zitat, Quelle), optional mit Fundstelle (Seite oder Zeit).',\n syntax: '[@<Block-ID>] oder [@<Block-ID>, S. 12]',\n example: 'Das zeigt die Studie [@0f3c9a52-7d1e-4b8a-9c2f-5e6d7a8b9c0d, S. 12].',\n}\n"],"mappings":";;;;;AAOA,MAAa,qBAA8B;CACzC,IAAI;CACJ,OAAO;CACP,aAAa;CACb,QAAQ;CACR,SAAS;AACX"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CompositeKind } from "./kinds.js";
|
|
2
|
+
import "./reference.js";
|
|
3
|
+
import { Editor } from "@tiptap/core";
|
|
4
|
+
import { Node as Node$1 } from "@tiptap/pm/model";
|
|
5
|
+
//#region src/features/composites/reference-label.d.ts
|
|
6
|
+
/** What a reference chip shows of its target: the parts of a `CompositeRow`, or of a composite node (`referenceTarget`). */
|
|
7
|
+
export interface ReferenceTarget {
|
|
8
|
+
meta: Record<string, unknown>;
|
|
9
|
+
title: string;
|
|
10
|
+
kindLabel: string;
|
|
11
|
+
}
|
|
12
|
+
/** The Baustein `node` as a reference target. */
|
|
13
|
+
export declare function referenceTarget(node: Node$1, kinds: readonly CompositeKind[]): ReferenceTarget;
|
|
14
|
+
/** The chip text: the short citation ("Doe et al. 2024") when the target has bibliographic data, else its title, else its kind's label. */
|
|
15
|
+
export declare function referenceLabel(target: ReferenceTarget): string;
|
|
16
|
+
/** The chip's tooltip: the full citation, else the title. */
|
|
17
|
+
export declare function referenceTitle(target: ReferenceTarget): string;
|
|
18
|
+
//#endregion
|
|
19
|
+
//# sourceMappingURL=reference-label.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { findBlockById } from "../../core/schema/block-ids.js";
|
|
2
|
+
import { compositeKind } from "./kinds.js";
|
|
3
|
+
import "./meta-keys.js";
|
|
4
|
+
import { compositeKindsOf } from "./nodes.js";
|
|
5
|
+
import { citeFull, citeShort } from "./bibliography.js";
|
|
6
|
+
//#region src/features/composites/reference-label.ts
|
|
7
|
+
/** The Baustein `node` as a reference target. */
|
|
8
|
+
function referenceTarget(node, kinds) {
|
|
9
|
+
return {
|
|
10
|
+
meta: node.attrs.meta ?? {},
|
|
11
|
+
title: node.childCount > 0 ? node.child(0).textContent.trim() : "",
|
|
12
|
+
kindLabel: compositeKind(kinds, String(node.attrs.kind)).label
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const bibOfTarget = (target) => {
|
|
16
|
+
const bib = target.meta["bib"];
|
|
17
|
+
if (!bib || typeof bib !== "object" || Array.isArray(bib)) return null;
|
|
18
|
+
return "type" in bib && typeof bib.type === "string" ? bib : null;
|
|
19
|
+
};
|
|
20
|
+
/** The chip text: the short citation ("Doe et al. 2024") when the target has bibliographic data, else its title, else its kind's label. */
|
|
21
|
+
function referenceLabel(target) {
|
|
22
|
+
const bib = bibOfTarget(target);
|
|
23
|
+
return bib ? citeShort(bib, target.title) : target.title || target.kindLabel;
|
|
24
|
+
}
|
|
25
|
+
/** The chip's tooltip: the full citation, else the title. */
|
|
26
|
+
function referenceTitle(target) {
|
|
27
|
+
const bib = bibOfTarget(target);
|
|
28
|
+
return bib ? citeFull({
|
|
29
|
+
...bib,
|
|
30
|
+
title: target.title
|
|
31
|
+
}) : target.title || target.kindLabel;
|
|
32
|
+
}
|
|
33
|
+
/** The attrs of a `reference` node that the label needs, typed (a node's `attrs` is a loose record). */
|
|
34
|
+
function referenceAttrsOf(node) {
|
|
35
|
+
return {
|
|
36
|
+
target: String(node.attrs.target ?? ""),
|
|
37
|
+
label: String(node.attrs.label ?? "")
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** What a chip shows now: the live label and tooltip of its target, or (`gone`) the attrs' cached label when the target no longer exists. */
|
|
41
|
+
function resolveReference(editor, attrs) {
|
|
42
|
+
const found = findBlockById(editor.state.doc, attrs.target);
|
|
43
|
+
if (found?.node.type.name !== "composite") return {
|
|
44
|
+
label: attrs.label,
|
|
45
|
+
title: attrs.label,
|
|
46
|
+
gone: true
|
|
47
|
+
};
|
|
48
|
+
const target = referenceTarget(found.node, compositeKindsOf(editor));
|
|
49
|
+
return {
|
|
50
|
+
label: referenceLabel(target),
|
|
51
|
+
title: referenceTitle(target),
|
|
52
|
+
gone: false
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
export { referenceAttrsOf, referenceLabel, referenceTarget, referenceTitle, resolveReference };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=reference-label.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-label.js","names":[],"sources":["../../../src/features/composites/reference-label.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport { findBlockById } from '../../core/schema'\nimport { type CslItem, BIB_KEY, citeFull, citeShort } from './bibliography'\nimport { compositeKind, type CompositeKind } from './kinds'\nimport { compositeKindsOf } from './nodes'\nimport type { ReferenceAttrs } from './reference'\n\n/** What a reference chip shows of its target: the parts of a `CompositeRow`, or of a composite node (`referenceTarget`). */\nexport interface ReferenceTarget {\n meta: Record<string, unknown>\n title: string\n kindLabel: string\n}\n\n/** The Baustein `node` as a reference target. */\nexport function referenceTarget(node: PMNode, kinds: readonly CompositeKind[]): ReferenceTarget {\n return {\n meta: (node.attrs.meta ?? {}) as Record<string, unknown>,\n title: node.childCount > 0 ? node.child(0).textContent.trim() : '',\n kindLabel: compositeKind(kinds, String(node.attrs.kind)).label,\n }\n}\n\nconst bibOfTarget = (target: ReferenceTarget): CslItem | null => {\n const bib = target.meta[BIB_KEY]\n if (!bib || typeof bib !== 'object' || Array.isArray(bib)) return null\n return 'type' in bib && typeof bib.type === 'string' ? bib as CslItem : null\n}\n\n/** The chip text: the short citation (\"Doe et al. 2024\") when the target has bibliographic data, else its title, else its kind's label. */\nexport function referenceLabel(target: ReferenceTarget): string {\n const bib = bibOfTarget(target)\n return bib ? citeShort(bib, target.title) : target.title || target.kindLabel\n}\n\n/** The chip's tooltip: the full citation, else the title. */\nexport function referenceTitle(target: ReferenceTarget): string {\n const bib = bibOfTarget(target)\n return bib ? citeFull({ ...bib, title: target.title }) : target.title || target.kindLabel\n}\n\n/** The attrs of a `reference` node that the label needs, typed (a node's `attrs` is a loose record). */\nexport function referenceAttrsOf(node: PMNode): Pick<ReferenceAttrs, 'target' | 'label'> {\n return { target: String(node.attrs.target ?? ''), label: String(node.attrs.label ?? '') }\n}\n\n/** What a chip shows now: the live label and tooltip of its target, or (`gone`) the attrs' cached label when the target no longer exists. */\nexport function resolveReference(editor: Editor, attrs: Pick<ReferenceAttrs, 'target' | 'label'>): { label: string, title: string, gone: boolean } {\n const found = findBlockById(editor.state.doc, attrs.target)\n if (found?.node.type.name !== 'composite') return { label: attrs.label, title: attrs.label, gone: true }\n const target = referenceTarget(found.node, compositeKindsOf(editor))\n return { label: referenceLabel(target), title: referenceTitle(target), gone: false }\n}\n"],"mappings":";;;;;;;AAgBA,SAAgB,gBAAgB,MAAc,OAAkD;CAC9F,OAAO;EACL,MAAO,KAAK,MAAM,QAAQ,CAAC;EAC3B,OAAO,KAAK,aAAa,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI;EAChE,WAAW,cAAc,OAAO,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC;CAC3D;AACF;AAEA,MAAM,eAAe,WAA4C;CAC/D,MAAM,MAAM,OAAO,KAAA;CACnB,IAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG,OAAO;CAClE,OAAO,UAAU,OAAO,OAAO,IAAI,SAAS,WAAW,MAAiB;AAC1E;;AAGA,SAAgB,eAAe,QAAiC;CAC9D,MAAM,MAAM,YAAY,MAAM;CAC9B,OAAO,MAAM,UAAU,KAAK,OAAO,KAAK,IAAI,OAAO,SAAS,OAAO;AACrE;;AAGA,SAAgB,eAAe,QAAiC;CAC9D,MAAM,MAAM,YAAY,MAAM;CAC9B,OAAO,MAAM,SAAS;EAAE,GAAG;EAAK,OAAO,OAAO;CAAM,CAAC,IAAI,OAAO,SAAS,OAAO;AAClF;;AAGA,SAAgB,iBAAiB,MAAwD;CACvF,OAAO;EAAE,QAAQ,OAAO,KAAK,MAAM,UAAU,EAAE;EAAG,OAAO,OAAO,KAAK,MAAM,SAAS,EAAE;CAAE;AAC1F;;AAGA,SAAgB,iBAAiB,QAAgB,OAAkG;CACjJ,MAAM,QAAQ,cAAc,OAAO,MAAM,KAAK,MAAM,MAAM;CAC1D,IAAI,OAAO,KAAK,KAAK,SAAS,aAAa,OAAO;EAAE,OAAO,MAAM;EAAO,OAAO,MAAM;EAAO,MAAM;CAAK;CACvG,MAAM,SAAS,gBAAgB,MAAM,MAAM,iBAAiB,MAAM,CAAC;CACnE,OAAO;EAAE,OAAO,eAAe,MAAM;EAAG,OAAO,eAAe,MAAM;EAAG,MAAM;CAAM;AACrF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Translate } from "../../i18n/index.js";
|
|
2
|
+
import { ReferenceOptions } from "./reference.js";
|
|
3
|
+
//#region src/features/composites/reference-suggestion.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* `[@` trigger for ReferenceNode: the Bausteine of the document (with a block ID) whose title, kind or chip label (the
|
|
6
|
+
* short citation) contains the typed query, inserted as a chip that shows the short citation or the title. `t` renders the popup texts in the app's language.
|
|
7
|
+
*/
|
|
8
|
+
export declare const referenceSuggestion: (t: Translate) => NonNullable<ReferenceOptions["suggestion"]>;
|
|
9
|
+
//#endregion
|
|
10
|
+
//# sourceMappingURL=reference-suggestion.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ABILITY } from "../../core/schema/abilities.js";
|
|
2
|
+
import { hasAbility } from "../../core/abilities.js";
|
|
3
|
+
import { createSuggestionRender } from "../../core/suggestion-popup.js";
|
|
4
|
+
import { compositeKindsOf } from "./nodes.js";
|
|
5
|
+
import { referenceLabel } from "./reference-label.js";
|
|
6
|
+
import { compositeRows } from "./rows.js";
|
|
7
|
+
//#region src/features/composites/reference-suggestion.ts
|
|
8
|
+
/** Rows of the popup; more would need scrolling past what a citation picker is for, and the query narrows them anyway. */
|
|
9
|
+
const MAX_ITEMS = 20;
|
|
10
|
+
/**
|
|
11
|
+
* `[@` trigger for ReferenceNode: the Bausteine of the document (with a block ID) whose title, kind or chip label (the
|
|
12
|
+
* short citation) contains the typed query, inserted as a chip that shows the short citation or the title. `t` renders the popup texts in the app's language.
|
|
13
|
+
*/
|
|
14
|
+
const referenceSuggestion = (t) => ({
|
|
15
|
+
allow: ({ editor }) => hasAbility(editor, ABILITY.reference),
|
|
16
|
+
items: ({ query, editor }) => {
|
|
17
|
+
const needle = query.trim().toLowerCase();
|
|
18
|
+
return compositeRows(editor.state.doc, compositeKindsOf(editor)).rows.filter((row) => row.id !== null).map((row) => ({
|
|
19
|
+
row,
|
|
20
|
+
label: referenceLabel(row)
|
|
21
|
+
})).filter(({ row, label }) => !needle || [
|
|
22
|
+
label,
|
|
23
|
+
row.title,
|
|
24
|
+
row.kindLabel
|
|
25
|
+
].some((part) => part.toLowerCase().includes(needle))).slice(0, MAX_ITEMS).map(({ row, label }) => ({
|
|
26
|
+
target: row.id,
|
|
27
|
+
documentId: null,
|
|
28
|
+
locator: null,
|
|
29
|
+
label
|
|
30
|
+
}));
|
|
31
|
+
},
|
|
32
|
+
render: createSuggestionRender({
|
|
33
|
+
display: (item) => ({ label: item.label }),
|
|
34
|
+
emptyText: t("composites.reference.empty"),
|
|
35
|
+
loadingText: t("common.loading")
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
//#endregion
|
|
39
|
+
export { referenceSuggestion };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=reference-suggestion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-suggestion.js","names":[],"sources":["../../../src/features/composites/reference-suggestion.ts"],"sourcesContent":["import { createSuggestionRender, hasAbility } from '../../core'\nimport { ABILITY } from '../../core/schema'\nimport type { Translate } from '../../i18n'\nimport { compositeKindsOf } from './nodes'\nimport type { ReferenceAttrs, ReferenceOptions } from './reference'\nimport { referenceLabel } from './reference-label'\nimport { compositeRows } from './rows'\n\n/** Rows of the popup; more would need scrolling past what a citation picker is for, and the query narrows them anyway. */\nconst MAX_ITEMS = 20\n\n/**\n * `[@` trigger for ReferenceNode: the Bausteine of the document (with a block ID) whose title, kind or chip label (the\n * short citation) contains the typed query, inserted as a chip that shows the short citation or the title. `t` renders the popup texts in the app's language.\n */\nexport const referenceSuggestion = (t: Translate): NonNullable<ReferenceOptions['suggestion']> => ({\n allow: ({ editor }) => hasAbility(editor, ABILITY.reference),\n items: ({ query, editor }): ReferenceAttrs[] => {\n const needle = query.trim().toLowerCase()\n return compositeRows(editor.state.doc, compositeKindsOf(editor)).rows\n .filter(row => row.id !== null)\n .map(row => ({ row, label: referenceLabel(row) }))\n .filter(({ row, label }) => !needle || [label, row.title, row.kindLabel].some(part => part.toLowerCase().includes(needle)))\n .slice(0, MAX_ITEMS)\n .map(({ row, label }): ReferenceAttrs => ({ target: row.id!, documentId: null, locator: null, label }))\n },\n render: createSuggestionRender<ReferenceAttrs>({\n display: item => ({ label: item.label }),\n emptyText: t('composites.reference.empty'),\n loadingText: t('common.loading'),\n }),\n})\n"],"mappings":";;;;;;;;AASA,MAAM,YAAY;;;;;AAMlB,MAAa,uBAAuB,OAA+D;CACjG,QAAQ,EAAE,aAAa,WAAW,QAAQ,QAAQ,SAAS;CAC3D,QAAQ,EAAE,OAAO,aAA+B;EAC9C,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,YAAY;EACxC,OAAO,cAAc,OAAO,MAAM,KAAK,iBAAiB,MAAM,CAAC,CAAC,CAAC,KAC9D,QAAO,QAAO,IAAI,OAAO,IAAI,CAAC,CAC9B,KAAI,SAAQ;GAAE;GAAK,OAAO,eAAe,GAAG;EAAE,EAAE,CAAC,CACjD,QAAQ,EAAE,KAAK,YAAY,CAAC,UAAU;GAAC;GAAO,IAAI;GAAO,IAAI;EAAS,CAAC,CAAC,MAAK,SAAQ,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,CAC1H,MAAM,GAAG,SAAS,CAAC,CACnB,KAAK,EAAE,KAAK,aAA6B;GAAE,QAAQ,IAAI;GAAK,YAAY;GAAM,SAAS;GAAM;EAAM,EAAE;CAC1G;CACA,QAAQ,uBAAuC;EAC7C,UAAS,UAAS,EAAE,OAAO,KAAK,MAAM;EACtC,WAAW,EAAE,4BAA4B;EACzC,aAAa,EAAE,gBAAgB;CACjC,CAAC;AACH"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { JSONContent } from "@tiptap/core";
|
|
2
|
+
import { Node as Node$1 } from "@tiptap/pm/model";
|
|
3
|
+
//#region src/features/composites/reference-text.d.ts
|
|
4
|
+
/** Block IDs of every composite in a TipTap JSON tree, added to `into`. */
|
|
5
|
+
export declare function collectCompositeIds(content: JSONContent | null | undefined, into: Set<string>): Set<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Turns `[@<id>]` / `[@<id>, <locator>]` tokens in text nodes into `reference` nodes (attrs target, locator, empty
|
|
8
|
+
* `label`: the node view resolves the live label) — for imported and AI-generated Markdown, whose parser keeps the
|
|
9
|
+
* token as text. Only ids in `ids` (the Bausteine of the document) match; unknown ids and text in code blocks, inline
|
|
10
|
+
* code or links stay plain. Returns the input unchanged when nothing matched.
|
|
11
|
+
*/
|
|
12
|
+
export declare function referencesFromText(json: JSONContent, ids: ReadonlySet<string>): JSONContent;
|
|
13
|
+
/** Block IDs of the composites of `doc`: the Bausteine a `[@id]` text may point at. */
|
|
14
|
+
export declare function compositeIdsOf(doc: Node$1): Set<string>;
|
|
15
|
+
/** The `normalize` stage: the composites of the document (`current`) and of `blocks` themselves may be referenced by text. */
|
|
16
|
+
export declare function normalizeReferences(blocks: JSONContent[], current: ReadonlySet<string>): JSONContent[];
|
|
17
|
+
//#endregion
|
|
18
|
+
//# sourceMappingURL=reference-text.d.ts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { blockIdOf } from "../../core/schema/block-ids.js";
|
|
2
|
+
import { REFERENCE_TOKEN_SOURCE } from "./reference.js";
|
|
3
|
+
//#region src/features/composites/reference-text.ts
|
|
4
|
+
/** `[@<block id>]` or `[@<block id>, <locator>]`; a `]` inside the locator is written `\]`. */
|
|
5
|
+
const TOKEN = new RegExp(REFERENCE_TOKEN_SOURCE, "g");
|
|
6
|
+
/** Block IDs of every composite in a TipTap JSON tree, added to `into`. */
|
|
7
|
+
function collectCompositeIds(content, into) {
|
|
8
|
+
if (!content) return into;
|
|
9
|
+
if (content.type === "composite" && typeof content.attrs?.id === "string" && content.attrs.id) into.add(content.attrs.id);
|
|
10
|
+
for (const child of content.content ?? []) collectCompositeIds(child, into);
|
|
11
|
+
return into;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Turns `[@<id>]` / `[@<id>, <locator>]` tokens in text nodes into `reference` nodes (attrs target, locator, empty
|
|
15
|
+
* `label`: the node view resolves the live label) — for imported and AI-generated Markdown, whose parser keeps the
|
|
16
|
+
* token as text. Only ids in `ids` (the Bausteine of the document) match; unknown ids and text in code blocks, inline
|
|
17
|
+
* code or links stay plain. Returns the input unchanged when nothing matched.
|
|
18
|
+
*/
|
|
19
|
+
function referencesFromText(json, ids) {
|
|
20
|
+
if (!ids.size) return json;
|
|
21
|
+
const splitText = (node) => {
|
|
22
|
+
const text = node.text ?? "";
|
|
23
|
+
if (!text.includes("[@") || node.marks?.some((m) => m.type === "code" || m.type === "link")) return [node];
|
|
24
|
+
const out = [];
|
|
25
|
+
let last = 0;
|
|
26
|
+
for (const match of text.matchAll(TOKEN)) {
|
|
27
|
+
const target = match[1];
|
|
28
|
+
if (!ids.has(target)) continue;
|
|
29
|
+
const at = match.index ?? 0;
|
|
30
|
+
if (at > last) out.push({
|
|
31
|
+
...node,
|
|
32
|
+
text: text.slice(last, at)
|
|
33
|
+
});
|
|
34
|
+
out.push({
|
|
35
|
+
type: "reference",
|
|
36
|
+
attrs: {
|
|
37
|
+
target,
|
|
38
|
+
documentId: null,
|
|
39
|
+
locator: match[2]?.replace(/\\\]/g, "]").trim() || null,
|
|
40
|
+
label: ""
|
|
41
|
+
},
|
|
42
|
+
...node.marks?.length ? { marks: node.marks } : {}
|
|
43
|
+
});
|
|
44
|
+
last = at + match[0].length;
|
|
45
|
+
}
|
|
46
|
+
if (!out.length) return [node];
|
|
47
|
+
if (last < text.length) out.push({
|
|
48
|
+
...node,
|
|
49
|
+
text: text.slice(last)
|
|
50
|
+
});
|
|
51
|
+
return out;
|
|
52
|
+
};
|
|
53
|
+
const walk = (node) => {
|
|
54
|
+
if (!node.content || node.type === "codeBlock") return node;
|
|
55
|
+
let changed = false;
|
|
56
|
+
const content = node.content.flatMap((child) => {
|
|
57
|
+
const next = child.type === "text" ? splitText(child) : [walk(child)];
|
|
58
|
+
if (next.length !== 1 || next[0] !== child) changed = true;
|
|
59
|
+
return next;
|
|
60
|
+
});
|
|
61
|
+
return changed ? {
|
|
62
|
+
...node,
|
|
63
|
+
content
|
|
64
|
+
} : node;
|
|
65
|
+
};
|
|
66
|
+
return walk(json);
|
|
67
|
+
}
|
|
68
|
+
/** Block IDs of the composites of `doc`: the Bausteine a `[@id]` text may point at. */
|
|
69
|
+
function compositeIdsOf(doc) {
|
|
70
|
+
const ids = /* @__PURE__ */ new Set();
|
|
71
|
+
doc.descendants((node) => {
|
|
72
|
+
if (node.type.name !== "composite") return;
|
|
73
|
+
const id = blockIdOf(node);
|
|
74
|
+
if (id) ids.add(id);
|
|
75
|
+
});
|
|
76
|
+
return ids;
|
|
77
|
+
}
|
|
78
|
+
/** The `normalize` stage: the composites of the document (`current`) and of `blocks` themselves may be referenced by text. */
|
|
79
|
+
function normalizeReferences(blocks, current) {
|
|
80
|
+
const doc = {
|
|
81
|
+
type: "doc",
|
|
82
|
+
content: blocks
|
|
83
|
+
};
|
|
84
|
+
return referencesFromText(doc, collectCompositeIds(doc, new Set(current))).content ?? [];
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { collectCompositeIds, compositeIdsOf, normalizeReferences, referencesFromText };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=reference-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-text.js","names":[],"sources":["../../../src/features/composites/reference-text.ts"],"sourcesContent":["import type { JSONContent } from '@tiptap/core'\nimport type { Node as PMNode } from '@tiptap/pm/model'\nimport { blockIdOf } from '../../core/schema'\nimport { REFERENCE_TOKEN_SOURCE } from './reference'\n\n/** `[@<block id>]` or `[@<block id>, <locator>]`; a `]` inside the locator is written `\\]`. */\nconst TOKEN = new RegExp(REFERENCE_TOKEN_SOURCE, 'g')\n\n/** Block IDs of every composite in a TipTap JSON tree, added to `into`. */\nexport function collectCompositeIds(content: JSONContent | null | undefined, into: Set<string>): Set<string> {\n if (!content) return into\n if (content.type === 'composite' && typeof content.attrs?.id === 'string' && content.attrs.id) into.add(content.attrs.id)\n for (const child of content.content ?? []) collectCompositeIds(child, into)\n return into\n}\n\n/**\n * Turns `[@<id>]` / `[@<id>, <locator>]` tokens in text nodes into `reference` nodes (attrs target, locator, empty\n * `label`: the node view resolves the live label) — for imported and AI-generated Markdown, whose parser keeps the\n * token as text. Only ids in `ids` (the Bausteine of the document) match; unknown ids and text in code blocks, inline\n * code or links stay plain. Returns the input unchanged when nothing matched.\n */\nexport function referencesFromText(json: JSONContent, ids: ReadonlySet<string>): JSONContent {\n if (!ids.size) return json\n\n const splitText = (node: JSONContent): JSONContent[] => {\n const text = node.text ?? ''\n if (!text.includes('[@') || node.marks?.some(m => m.type === 'code' || m.type === 'link')) return [node]\n const out: JSONContent[] = []\n let last = 0\n for (const match of text.matchAll(TOKEN)) {\n const target = match[1]!\n if (!ids.has(target)) continue\n const at = match.index ?? 0\n if (at > last) out.push({ ...node, text: text.slice(last, at) })\n out.push({\n type: 'reference',\n attrs: { target, documentId: null, locator: match[2]?.replace(/\\\\\\]/g, ']').trim() || null, label: '' },\n ...(node.marks?.length ? { marks: node.marks } : {}),\n })\n last = at + match[0].length\n }\n if (!out.length) return [node]\n if (last < text.length) out.push({ ...node, text: text.slice(last) })\n return out\n }\n\n const walk = (node: JSONContent): JSONContent => {\n if (!node.content || node.type === 'codeBlock') return node\n let changed = false\n const content = node.content.flatMap((child) => {\n const next = child.type === 'text' ? splitText(child) : [walk(child)]\n if (next.length !== 1 || next[0] !== child) changed = true\n return next\n })\n return changed ? { ...node, content } : node\n }\n return walk(json)\n}\n\n/** Block IDs of the composites of `doc`: the Bausteine a `[@id]` text may point at. */\nexport function compositeIdsOf(doc: PMNode): Set<string> {\n const ids = new Set<string>()\n doc.descendants((node) => {\n if (node.type.name !== 'composite') return\n const id = blockIdOf(node)\n if (id) ids.add(id)\n })\n return ids\n}\n\n/** The `normalize` stage: the composites of the document (`current`) and of `blocks` themselves may be referenced by text. */\nexport function normalizeReferences(blocks: JSONContent[], current: ReadonlySet<string>): JSONContent[] {\n const doc: JSONContent = { type: 'doc', content: blocks }\n return referencesFromText(doc, collectCompositeIds(doc, new Set(current))).content ?? []\n}\n"],"mappings":";;;;AAMA,MAAM,QAAQ,IAAI,OAAO,wBAAwB,GAAG;;AAGpD,SAAgB,oBAAoB,SAAyC,MAAgC;CAC3G,IAAI,CAAC,SAAS,OAAO;CACrB,IAAI,QAAQ,SAAS,eAAe,OAAO,QAAQ,OAAO,OAAO,YAAY,QAAQ,MAAM,IAAI,KAAK,IAAI,QAAQ,MAAM,EAAE;CACxH,KAAK,MAAM,SAAS,QAAQ,WAAW,CAAC,GAAG,oBAAoB,OAAO,IAAI;CAC1E,OAAO;AACT;;;;;;;AAQA,SAAgB,mBAAmB,MAAmB,KAAuC;CAC3F,IAAI,CAAC,IAAI,MAAM,OAAO;CAEtB,MAAM,aAAa,SAAqC;EACtD,MAAM,OAAO,KAAK,QAAQ;EAC1B,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO,MAAK,MAAK,EAAE,SAAS,UAAU,EAAE,SAAS,MAAM,GAAG,OAAO,CAAC,IAAI;EACvG,MAAM,MAAqB,CAAC;EAC5B,IAAI,OAAO;EACX,KAAK,MAAM,SAAS,KAAK,SAAS,KAAK,GAAG;GACxC,MAAM,SAAS,MAAM;GACrB,IAAI,CAAC,IAAI,IAAI,MAAM,GAAG;GACtB,MAAM,KAAK,MAAM,SAAS;GAC1B,IAAI,KAAK,MAAM,IAAI,KAAK;IAAE,GAAG;IAAM,MAAM,KAAK,MAAM,MAAM,EAAE;GAAE,CAAC;GAC/D,IAAI,KAAK;IACP,MAAM;IACN,OAAO;KAAE;KAAQ,YAAY;KAAM,SAAS,MAAM,EAAE,EAAE,QAAQ,SAAS,GAAG,CAAC,CAAC,KAAK,KAAK;KAAM,OAAO;IAAG;IACtG,GAAI,KAAK,OAAO,SAAS,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;GACpD,CAAC;GACD,OAAO,KAAK,MAAM,EAAE,CAAC;EACvB;EACA,IAAI,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI;EAC7B,IAAI,OAAO,KAAK,QAAQ,IAAI,KAAK;GAAE,GAAG;GAAM,MAAM,KAAK,MAAM,IAAI;EAAE,CAAC;EACpE,OAAO;CACT;CAEA,MAAM,QAAQ,SAAmC;EAC/C,IAAI,CAAC,KAAK,WAAW,KAAK,SAAS,aAAa,OAAO;EACvD,IAAI,UAAU;EACd,MAAM,UAAU,KAAK,QAAQ,SAAS,UAAU;GAC9C,MAAM,OAAO,MAAM,SAAS,SAAS,UAAU,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC;GACpE,IAAI,KAAK,WAAW,KAAK,KAAK,OAAO,OAAO,UAAU;GACtD,OAAO;EACT,CAAC;EACD,OAAO,UAAU;GAAE,GAAG;GAAM;EAAQ,IAAI;CAC1C;CACA,OAAO,KAAK,IAAI;AAClB;;AAGA,SAAgB,eAAe,KAA0B;CACvD,MAAM,sBAAM,IAAI,IAAY;CAC5B,IAAI,aAAa,SAAS;EACxB,IAAI,KAAK,KAAK,SAAS,aAAa;EACpC,MAAM,KAAK,UAAU,IAAI;EACzB,IAAI,IAAI,IAAI,IAAI,EAAE;CACpB,CAAC;CACD,OAAO;AACT;;AAGA,SAAgB,oBAAoB,QAAuB,SAA6C;CACtG,MAAM,MAAmB;EAAE,MAAM;EAAO,SAAS;CAAO;CACxD,OAAO,mBAAmB,KAAK,oBAAoB,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;AACzF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Extension, Node } from "@tiptap/core";
|
|
2
|
+
import { PluginKey } from "@tiptap/pm/state";
|
|
3
|
+
import { SuggestionOptions } from "@tiptap/suggestion";
|
|
4
|
+
//#region src/features/composites/reference.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Attributes of a reference chip. `target` is the block ID of the referenced Baustein; `label` caches its display text
|
|
7
|
+
* for the cases the target cannot be resolved (the node view shows the live label and only falls back to this one).
|
|
8
|
+
*/
|
|
9
|
+
export interface ReferenceAttrs {
|
|
10
|
+
target: string;
|
|
11
|
+
/** Document of the target; `null` = this document (cross-document references are not resolved yet). */
|
|
12
|
+
documentId: string | null;
|
|
13
|
+
/** Position inside the target's source: `S. 12` (PDF page), `03:14` (recording time); `null` = the whole Baustein. */
|
|
14
|
+
locator: string | null;
|
|
15
|
+
label: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const REFERENCE_NODE = "reference";
|
|
18
|
+
/** `[@<target>]` / `[@<target>, <locator>]`, the chip's Markdown form; `]` in a locator is escaped as `\]`. */
|
|
19
|
+
export declare function referenceMarkdown(attrs: Pick<ReferenceAttrs, 'target' | 'locator'>): string;
|
|
20
|
+
declare module '@tiptap/core' {
|
|
21
|
+
interface Commands<ReturnType> {
|
|
22
|
+
reference: {
|
|
23
|
+
/** Inserts a reference chip (followed by a space) at the selection. */
|
|
24
|
+
insertReference: (attrs: Partial<ReferenceAttrs> & Pick<ReferenceAttrs, 'target'>) => ReturnType;
|
|
25
|
+
/** Sets the locator of the reference chip at `pos`; an empty text clears it. */
|
|
26
|
+
setReferenceLocator: (pos: number, locator: string) => ReturnType;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export interface ReferenceOptions {
|
|
31
|
+
HTMLAttributes: Record<string, unknown>;
|
|
32
|
+
/** `[@` popup (client only, see reference-suggestion.ts); `null` = schema only (server, Markdown). */
|
|
33
|
+
suggestion: Omit<SuggestionOptions<ReferenceAttrs, ReferenceAttrs>, 'editor'> | null;
|
|
34
|
+
}
|
|
35
|
+
/** Own key, so the `[@` popup runs next to the `@` mention and `#` tag popups. */
|
|
36
|
+
export declare const ReferenceSuggestionPluginKey: PluginKey<any>;
|
|
37
|
+
/**
|
|
38
|
+
* Inline chip pointing at a Baustein of the document (a paper, a recording, a note): shared by the client editor and
|
|
39
|
+
* the server (collab schema, Markdown). Markdown form `[@<block id>, <locator>]`; text of that form becomes chips again
|
|
40
|
+
* through `referencesFromText` (the composites feature's `normalize` stage). The client adds the node view and the popup.
|
|
41
|
+
*/
|
|
42
|
+
export declare const ReferenceNode: Node<ReferenceOptions, any>;
|
|
43
|
+
//#endregion
|
|
44
|
+
//# sourceMappingURL=reference.d.ts.map
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Extension, Node, mergeAttributes } from "@tiptap/core";
|
|
2
|
+
import { PluginKey } from "@tiptap/pm/state";
|
|
3
|
+
import { Suggestion } from "@tiptap/suggestion";
|
|
4
|
+
//#region src/features/composites/reference.ts
|
|
5
|
+
const REFERENCE_NODE = "reference";
|
|
6
|
+
/** `[@<target>]` / `[@<target>, <locator>]`, the chip's Markdown form; `]` in a locator is escaped as `\]`. */
|
|
7
|
+
function referenceMarkdown(attrs) {
|
|
8
|
+
const locator = attrs.locator?.trim();
|
|
9
|
+
return locator ? `[@${attrs.target}, ${locator.replace(/\]/g, "\\]")}]` : `[@${attrs.target}]`;
|
|
10
|
+
}
|
|
11
|
+
/** Pattern of the chip's Markdown form (capture 1: block id, capture 2: locator with `\]` still escaped); compile with `new RegExp(..., 'g')`. */
|
|
12
|
+
const REFERENCE_TOKEN_SOURCE = String.raw`\[@([0-9a-f-]{36})(?:,\s*((?:\\\]|[^\]])+))?\]`;
|
|
13
|
+
/** Own key, so the `[@` popup runs next to the `@` mention and `#` tag popups. */
|
|
14
|
+
const ReferenceSuggestionPluginKey = new PluginKey("referenceSuggestion");
|
|
15
|
+
/**
|
|
16
|
+
* Inline chip pointing at a Baustein of the document (a paper, a recording, a note): shared by the client editor and
|
|
17
|
+
* the server (collab schema, Markdown). Markdown form `[@<block id>, <locator>]`; text of that form becomes chips again
|
|
18
|
+
* through `referencesFromText` (the composites feature's `normalize` stage). The client adds the node view and the popup.
|
|
19
|
+
*/
|
|
20
|
+
const ReferenceNode = Node.create({
|
|
21
|
+
name: REFERENCE_NODE,
|
|
22
|
+
group: "inline",
|
|
23
|
+
inline: true,
|
|
24
|
+
atom: true,
|
|
25
|
+
selectable: true,
|
|
26
|
+
priority: 99,
|
|
27
|
+
markdownTokenizer: {
|
|
28
|
+
name: "referenceToken",
|
|
29
|
+
level: "inline",
|
|
30
|
+
start: (src) => src.search(/\[@[0-9a-f-]{36}/),
|
|
31
|
+
tokenize: (src) => {
|
|
32
|
+
const match = new RegExp(`^${REFERENCE_TOKEN_SOURCE}`).exec(src);
|
|
33
|
+
return match ? {
|
|
34
|
+
type: "text",
|
|
35
|
+
raw: match[0],
|
|
36
|
+
text: match[0]
|
|
37
|
+
} : void 0;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
addOptions() {
|
|
41
|
+
return {
|
|
42
|
+
HTMLAttributes: { class: "reference" },
|
|
43
|
+
suggestion: null
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
addAttributes() {
|
|
47
|
+
return {
|
|
48
|
+
target: {
|
|
49
|
+
default: "",
|
|
50
|
+
parseHTML: (el) => el.getAttribute("data-target") ?? "",
|
|
51
|
+
renderHTML: (attrs) => ({ "data-target": attrs.target })
|
|
52
|
+
},
|
|
53
|
+
documentId: {
|
|
54
|
+
default: null,
|
|
55
|
+
parseHTML: (el) => el.getAttribute("data-document"),
|
|
56
|
+
renderHTML: (attrs) => attrs.documentId ? { "data-document": attrs.documentId } : {}
|
|
57
|
+
},
|
|
58
|
+
locator: {
|
|
59
|
+
default: null,
|
|
60
|
+
parseHTML: (el) => el.getAttribute("data-locator"),
|
|
61
|
+
renderHTML: (attrs) => attrs.locator ? { "data-locator": attrs.locator } : {}
|
|
62
|
+
},
|
|
63
|
+
label: {
|
|
64
|
+
default: "",
|
|
65
|
+
parseHTML: (el) => el.getAttribute("data-label") ?? el.textContent ?? "",
|
|
66
|
+
renderHTML: (attrs) => ({ "data-label": attrs.label })
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
parseHTML() {
|
|
71
|
+
return [{ tag: `span[data-type="${this.name}"]` }];
|
|
72
|
+
},
|
|
73
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
74
|
+
return [
|
|
75
|
+
"span",
|
|
76
|
+
mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
77
|
+
String(node.attrs.label ?? "")
|
|
78
|
+
];
|
|
79
|
+
},
|
|
80
|
+
renderText: ({ node }) => referenceMarkdown(node.attrs),
|
|
81
|
+
renderMarkdown: (node) => referenceMarkdown({
|
|
82
|
+
target: String(node.attrs?.target ?? ""),
|
|
83
|
+
locator: typeof node.attrs?.locator === "string" ? node.attrs.locator : null
|
|
84
|
+
}),
|
|
85
|
+
addCommands() {
|
|
86
|
+
return {
|
|
87
|
+
insertReference: (attrs) => ({ commands }) => commands.insertContent([{
|
|
88
|
+
type: this.name,
|
|
89
|
+
attrs
|
|
90
|
+
}, {
|
|
91
|
+
type: "text",
|
|
92
|
+
text: " "
|
|
93
|
+
}]),
|
|
94
|
+
setReferenceLocator: (pos, locator) => ({ tr, dispatch }) => {
|
|
95
|
+
const node = tr.doc.nodeAt(pos);
|
|
96
|
+
if (node?.type.name !== this.name) return false;
|
|
97
|
+
if (dispatch) tr.setNodeMarkup(pos, void 0, {
|
|
98
|
+
...node.attrs,
|
|
99
|
+
locator: locator.trim() || null
|
|
100
|
+
});
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
addExtensions() {
|
|
106
|
+
const { suggestion } = this.options;
|
|
107
|
+
return suggestion ? [ReferenceSuggestion.configure({ suggestion })] : [];
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
/**
|
|
111
|
+
* The `[@` popup of ReferenceNode. Priority 101 (like TagNode), above core's Keymap (100): extension priority orders
|
|
112
|
+
* the ProseMirror plugins' `handleKeyDown`, and with a lower one Enter would split the paragraph instead of picking.
|
|
113
|
+
*/
|
|
114
|
+
const ReferenceSuggestion = Extension.create({
|
|
115
|
+
name: "referenceSuggestion",
|
|
116
|
+
priority: 101,
|
|
117
|
+
addOptions() {
|
|
118
|
+
return { suggestion: null };
|
|
119
|
+
},
|
|
120
|
+
addProseMirrorPlugins() {
|
|
121
|
+
const { suggestion } = this.options;
|
|
122
|
+
if (!suggestion) return [];
|
|
123
|
+
const { allow, ...rest } = suggestion;
|
|
124
|
+
return [Suggestion({
|
|
125
|
+
pluginKey: ReferenceSuggestionPluginKey,
|
|
126
|
+
char: "[@",
|
|
127
|
+
allowSpaces: true,
|
|
128
|
+
allow: (p) => allow?.(p) ?? true,
|
|
129
|
+
command: ({ editor, range, props }) => {
|
|
130
|
+
if (editor.view.state.selection.$to.nodeAfter?.text?.startsWith(" ")) range.to += 1;
|
|
131
|
+
editor.chain().focus().insertContentAt(range, [{
|
|
132
|
+
type: REFERENCE_NODE,
|
|
133
|
+
attrs: props
|
|
134
|
+
}, {
|
|
135
|
+
type: "text",
|
|
136
|
+
text: " "
|
|
137
|
+
}]).run();
|
|
138
|
+
editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd();
|
|
139
|
+
},
|
|
140
|
+
...rest,
|
|
141
|
+
editor: this.editor
|
|
142
|
+
})];
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
//#endregion
|
|
146
|
+
export { REFERENCE_NODE, REFERENCE_TOKEN_SOURCE, ReferenceNode, ReferenceSuggestion, ReferenceSuggestionPluginKey, referenceMarkdown };
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference.js","names":[],"sources":["../../../src/features/composites/reference.ts"],"sourcesContent":["import { Extension, mergeAttributes, Node } from '@tiptap/core'\nimport { PluginKey } from '@tiptap/pm/state'\nimport { Suggestion, type SuggestionOptions } from '@tiptap/suggestion'\n\n/**\n * Attributes of a reference chip. `target` is the block ID of the referenced Baustein; `label` caches its display text\n * for the cases the target cannot be resolved (the node view shows the live label and only falls back to this one).\n */\nexport interface ReferenceAttrs {\n target: string\n /** Document of the target; `null` = this document (cross-document references are not resolved yet). */\n documentId: string | null\n /** Position inside the target's source: `S. 12` (PDF page), `03:14` (recording time); `null` = the whole Baustein. */\n locator: string | null\n label: string\n}\n\nexport const REFERENCE_NODE = 'reference'\n\n/** Trigger of the popup. Two characters: `[@` is the Markdown form, so typing it by hand and picking from the list agree. */\nexport const REFERENCE_TRIGGER = '[@'\n\n/** `[@<target>]` / `[@<target>, <locator>]`, the chip's Markdown form; `]` in a locator is escaped as `\\]`. */\nexport function referenceMarkdown(attrs: Pick<ReferenceAttrs, 'target' | 'locator'>): string {\n const locator = attrs.locator?.trim()\n return locator ? `[@${attrs.target}, ${locator.replace(/\\]/g, '\\\\]')}]` : `[@${attrs.target}]`\n}\n\n/** Pattern of the chip's Markdown form (capture 1: block id, capture 2: locator with `\\]` still escaped); compile with `new RegExp(..., 'g')`. */\nexport const REFERENCE_TOKEN_SOURCE = String.raw`\\[@([0-9a-f-]{36})(?:,\\s*((?:\\\\\\]|[^\\]])+))?\\]`\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n reference: {\n /** Inserts a reference chip (followed by a space) at the selection. */\n insertReference: (attrs: Partial<ReferenceAttrs> & Pick<ReferenceAttrs, 'target'>) => ReturnType\n /** Sets the locator of the reference chip at `pos`; an empty text clears it. */\n setReferenceLocator: (pos: number, locator: string) => ReturnType\n }\n }\n}\n\nexport interface ReferenceOptions {\n HTMLAttributes: Record<string, unknown>\n /** `[@` popup (client only, see reference-suggestion.ts); `null` = schema only (server, Markdown). */\n suggestion: Omit<SuggestionOptions<ReferenceAttrs, ReferenceAttrs>, 'editor'> | null\n}\n\n/** Own key, so the `[@` popup runs next to the `@` mention and `#` tag popups. */\nexport const ReferenceSuggestionPluginKey = new PluginKey('referenceSuggestion')\n\n/**\n * Inline chip pointing at a Baustein of the document (a paper, a recording, a note): shared by the client editor and\n * the server (collab schema, Markdown). Markdown form `[@<block id>, <locator>]`; text of that form becomes chips again\n * through `referencesFromText` (the composites feature's `normalize` stage). The client adds the node view and the popup.\n */\nexport const ReferenceNode = Node.create<ReferenceOptions>({\n name: REFERENCE_NODE,\n group: 'inline',\n inline: true,\n atom: true,\n selectable: true,\n // Just below Mention (100): TipTap's Markdown manager registers the tokenizers in priority order and marked tries the\n // last registered first, so `markdownTokenizer` below sees `[@<id>]` before Mention's `[@ ...]` shortcode does.\n priority: 99,\n\n // Claims `[@<block id>, <locator>]` as plain text, so Mention's tokenizer (which takes every `[@...]`) leaves it alone;\n // the composites feature's `normalize` stage turns it into a chip when the id belongs to a Baustein of the document.\n markdownTokenizer: {\n name: 'referenceToken',\n level: 'inline',\n start: src => src.search(/\\[@[0-9a-f-]{36}/),\n tokenize: (src) => {\n const match = new RegExp(`^${REFERENCE_TOKEN_SOURCE}`).exec(src)\n return match ? { type: 'text', raw: match[0], text: match[0] } : undefined\n },\n },\n\n addOptions() {\n return { HTMLAttributes: { class: 'reference' }, suggestion: null }\n },\n\n addAttributes() {\n return {\n target: {\n default: '',\n parseHTML: el => el.getAttribute('data-target') ?? '',\n renderHTML: attrs => ({ 'data-target': attrs.target }),\n },\n documentId: {\n default: null,\n parseHTML: el => el.getAttribute('data-document'),\n renderHTML: attrs => attrs.documentId ? { 'data-document': attrs.documentId } : {},\n },\n locator: {\n default: null,\n parseHTML: el => el.getAttribute('data-locator'),\n renderHTML: attrs => attrs.locator ? { 'data-locator': attrs.locator } : {},\n },\n label: {\n default: '',\n parseHTML: el => el.getAttribute('data-label') ?? el.textContent ?? '',\n renderHTML: attrs => ({ 'data-label': attrs.label }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: `span[data-type=\"${this.name}\"]` }]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return ['span', mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), String(node.attrs.label ?? '')]\n },\n\n renderText: ({ node }) => referenceMarkdown(node.attrs as ReferenceAttrs),\n\n // Markdown export (editor.getMarkdown(), AI context/selection) writes the chip as `[@<id>, <locator>]`.\n renderMarkdown: node => referenceMarkdown({ target: String(node.attrs?.target ?? ''), locator: typeof node.attrs?.locator === 'string' ? node.attrs.locator : null }),\n\n addCommands() {\n return {\n insertReference: attrs => ({ commands }) =>\n commands.insertContent([{ type: this.name, attrs }, { type: 'text', text: ' ' }]),\n setReferenceLocator: (pos, locator) => ({ tr, dispatch }) => {\n const node = tr.doc.nodeAt(pos)\n if (node?.type.name !== this.name) return false\n if (dispatch) tr.setNodeMarkup(pos, undefined, { ...node.attrs, locator: locator.trim() || null })\n return true\n },\n }\n },\n\n // The popup lives in a companion extension (see `ReferenceSuggestion`): it must rank above TipTap's core keymap\n // (100) to see Enter first, which this node cannot (its priority orders the Markdown tokenizer).\n addExtensions() {\n const { suggestion } = this.options\n return suggestion ? [ReferenceSuggestion.configure({ suggestion })] : []\n },\n})\n\n/**\n * The `[@` popup of ReferenceNode. Priority 101 (like TagNode), above core's Keymap (100): extension priority orders\n * the ProseMirror plugins' `handleKeyDown`, and with a lower one Enter would split the paragraph instead of picking.\n */\nexport const ReferenceSuggestion = Extension.create<{ suggestion: NonNullable<ReferenceOptions['suggestion']> | null }>({\n name: 'referenceSuggestion',\n priority: 101,\n\n addOptions() {\n return { suggestion: null }\n },\n\n addProseMirrorPlugins() {\n const { suggestion } = this.options\n if (!suggestion) return []\n const { allow, ...rest } = suggestion\n return [Suggestion<ReferenceAttrs, ReferenceAttrs>({\n pluginKey: ReferenceSuggestionPluginKey,\n char: REFERENCE_TRIGGER,\n allowSpaces: true,\n allow: p => allow?.(p) ?? true,\n command: ({ editor, range, props }) => {\n // Reuse a following space instead of doubling it (as Mention does).\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n if (nodeAfter?.text?.startsWith(' ')) range.to += 1\n editor.chain().focus()\n .insertContentAt(range, [{ type: REFERENCE_NODE, attrs: props }, { type: 'text', text: ' ' }])\n .run()\n editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd()\n },\n ...rest,\n editor: this.editor,\n })]\n },\n})\n"],"mappings":";;;;AAiBA,MAAa,iBAAiB;;AAM9B,SAAgB,kBAAkB,OAA2D;CAC3F,MAAM,UAAU,MAAM,SAAS,KAAK;CACpC,OAAO,UAAU,KAAK,MAAM,OAAO,IAAI,QAAQ,QAAQ,OAAO,KAAK,EAAE,KAAK,KAAK,MAAM,OAAO;AAC9F;;AAGA,MAAa,yBAAyB,OAAO,GAAG;;AAoBhD,MAAa,+BAA+B,IAAI,UAAU,qBAAqB;;;;;;AAO/E,MAAa,gBAAgB,KAAK,OAAyB;CACzD,MAAM;CACN,OAAO;CACP,QAAQ;CACR,MAAM;CACN,YAAY;CAGZ,UAAU;CAIV,mBAAmB;EACjB,MAAM;EACN,OAAO;EACP,QAAO,QAAO,IAAI,OAAO,kBAAkB;EAC3C,WAAW,QAAQ;GACjB,MAAM,QAAQ,IAAI,OAAO,IAAI,wBAAwB,CAAC,CAAC,KAAK,GAAG;GAC/D,OAAO,QAAQ;IAAE,MAAM;IAAQ,KAAK,MAAM;IAAI,MAAM,MAAM;GAAG,IAAI,KAAA;EACnE;CACF;CAEA,aAAa;EACX,OAAO;GAAE,gBAAgB,EAAE,OAAO,YAAY;GAAG,YAAY;EAAK;CACpE;CAEA,gBAAgB;EACd,OAAO;GACL,QAAQ;IACN,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,aAAa,KAAK;IACnD,aAAY,WAAU,EAAE,eAAe,MAAM,OAAO;GACtD;GACA,YAAY;IACV,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,eAAe;IAChD,aAAY,UAAS,MAAM,aAAa,EAAE,iBAAiB,MAAM,WAAW,IAAI,CAAC;GACnF;GACA,SAAS;IACP,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,cAAc;IAC/C,aAAY,UAAS,MAAM,UAAU,EAAE,gBAAgB,MAAM,QAAQ,IAAI,CAAC;GAC5E;GACA,OAAO;IACL,SAAS;IACT,YAAW,OAAM,GAAG,aAAa,YAAY,KAAK,GAAG,eAAe;IACpE,aAAY,WAAU,EAAE,cAAc,MAAM,MAAM;GACpD;EACF;CACF;CAEA,YAAY;EACV,OAAO,CAAC,EAAE,KAAK,mBAAmB,KAAK,KAAK,IAAI,CAAC;CACnD;CAEA,WAAW,EAAE,MAAM,kBAAkB;EACnC,OAAO;GAAC;GAAQ,gBAAgB,EAAE,aAAa,KAAK,KAAK,GAAG,KAAK,QAAQ,gBAAgB,cAAc;GAAG,OAAO,KAAK,MAAM,SAAS,EAAE;EAAC;CAC1I;CAEA,aAAa,EAAE,WAAW,kBAAkB,KAAK,KAAuB;CAGxE,iBAAgB,SAAQ,kBAAkB;EAAE,QAAQ,OAAO,KAAK,OAAO,UAAU,EAAE;EAAG,SAAS,OAAO,KAAK,OAAO,YAAY,WAAW,KAAK,MAAM,UAAU;CAAK,CAAC;CAEpK,cAAc;EACZ,OAAO;GACL,kBAAiB,WAAU,EAAE,eAC3B,SAAS,cAAc,CAAC;IAAE,MAAM,KAAK;IAAM;GAAM,GAAG;IAAE,MAAM;IAAQ,MAAM;GAAI,CAAC,CAAC;GAClF,sBAAsB,KAAK,aAAa,EAAE,IAAI,eAAe;IAC3D,MAAM,OAAO,GAAG,IAAI,OAAO,GAAG;IAC9B,IAAI,MAAM,KAAK,SAAS,KAAK,MAAM,OAAO;IAC1C,IAAI,UAAU,GAAG,cAAc,KAAK,KAAA,GAAW;KAAE,GAAG,KAAK;KAAO,SAAS,QAAQ,KAAK,KAAK;IAAK,CAAC;IACjG,OAAO;GACT;EACF;CACF;CAIA,gBAAgB;EACd,MAAM,EAAE,eAAe,KAAK;EAC5B,OAAO,aAAa,CAAC,oBAAoB,UAAU,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC;CACzE;AACF,CAAC;;;;;AAMD,MAAa,sBAAsB,UAAU,OAA2E;CACtH,MAAM;CACN,UAAU;CAEV,aAAa;EACX,OAAO,EAAE,YAAY,KAAK;CAC5B;CAEA,wBAAwB;EACtB,MAAM,EAAE,eAAe,KAAK;EAC5B,IAAI,CAAC,YAAY,OAAO,CAAC;EACzB,MAAM,EAAE,OAAO,GAAG,SAAS;EAC3B,OAAO,CAAC,WAA2C;GACjD,WAAW;GACX,MAAA;GACA,aAAa;GACb,QAAO,MAAK,QAAQ,CAAC,KAAK;GAC1B,UAAU,EAAE,QAAQ,OAAO,YAAY;IAGrC,IADkB,OAAO,KAAK,MAAM,UAAU,IAAI,WACnC,MAAM,WAAW,GAAG,GAAG,MAAM,MAAM;IAClD,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CACnB,gBAAgB,OAAO,CAAC;KAAE,MAAM;KAAgB,OAAO;IAAM,GAAG;KAAE,MAAM;KAAQ,MAAM;IAAI,CAAC,CAAC,CAAC,CAC7F,IAAI;IACP,OAAO,KAAK,IAAI,cAAc,aAAa,aAAa,CAAC,EAAE,cAAc;GAC3E;GACA,GAAG;GACH,QAAQ,KAAK;EACf,CAAC,CAAC;CACJ;AACF,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Editor, Extension } from "@tiptap/core";
|
|
2
|
+
//#region src/features/composites/reveal-source.d.ts
|
|
3
|
+
declare module '@tiptap/core' {
|
|
4
|
+
interface Commands<ReturnType> {
|
|
5
|
+
sourceReveal: {
|
|
6
|
+
/** Seek and play the media of the source-holding Baustein enclosing `pos` to `seconds`; silent when there is none. */
|
|
7
|
+
seekSource: (pos: number, seconds: number) => ReturnType;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Where in the source a locator points: a time in seconds (`3:07`) or a PDF page (`S. 12`, `p. 12`, `12`). */
|
|
12
|
+
export type SourceLocator = {
|
|
13
|
+
seconds: number;
|
|
14
|
+
} | {
|
|
15
|
+
page: number;
|
|
16
|
+
};
|
|
17
|
+
/** Parses a reference locator; null for anything that is not a time or a page number. */
|
|
18
|
+
export declare function parseLocator(locator: string | null | undefined): SourceLocator | null;
|
|
19
|
+
/**
|
|
20
|
+
* Seeks and plays the audio/video of the nearest source-holding Baustein around `pos` (a transcript segment inside a
|
|
21
|
+
* rendition reaches the recording that way). Silent when there is no source or no media element.
|
|
22
|
+
*/
|
|
23
|
+
export declare function seekSource(editor: Editor, pos: number, seconds: number): void;
|
|
24
|
+
/**
|
|
25
|
+
* Shows the source of Baustein `targetId` at `locator`: a `mm:ss` time seeks the media, a page number opens a PDF source
|
|
26
|
+
* at that page; then the source block flashes. Silent when the target or its source is gone.
|
|
27
|
+
*/
|
|
28
|
+
export declare function revealSource(editor: Editor, targetId: string, locator: string | null): void;
|
|
29
|
+
/** Registers `seekSource` as an editor command, so features that must not import composites (transcript) can call it. */
|
|
30
|
+
export declare const SourceReveal: Extension<any, any>;
|
|
31
|
+
//#endregion
|
|
32
|
+
//# sourceMappingURL=reveal-source.d.ts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { blockIdOf, findBlockById } from "../../core/schema/block-ids.js";
|
|
2
|
+
import { sourceOf } from "./derivation.js";
|
|
3
|
+
import { compositeKindsOf } from "./nodes.js";
|
|
4
|
+
import { Extension } from "@tiptap/core";
|
|
5
|
+
//#region src/features/composites/reveal-source.ts
|
|
6
|
+
/** DOM event the PDF file view listens for; `detail` is the 1-based page to open the viewer at. */
|
|
7
|
+
const REVEAL_PAGE_EVENT = "sk-reveal-page";
|
|
8
|
+
const TIME_LOCATOR = /^(\d+):(\d{2})$/;
|
|
9
|
+
const PAGE_LOCATOR = /^(?:S\.|p\.)?\s*(\d+)$/i;
|
|
10
|
+
/** Parses a reference locator; null for anything that is not a time or a page number. */
|
|
11
|
+
function parseLocator(locator) {
|
|
12
|
+
const text = locator?.trim();
|
|
13
|
+
if (!text) return null;
|
|
14
|
+
const time = TIME_LOCATOR.exec(text);
|
|
15
|
+
if (time) return { seconds: Number(time[1]) * 60 + Number(time[2]) };
|
|
16
|
+
const page = PAGE_LOCATOR.exec(text);
|
|
17
|
+
if (page && Number(page[1]) > 0) return { page: Number(page[1]) };
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/** The source block of the composite `composite` at `pos` with its document position, or null. */
|
|
21
|
+
function sourceAt(editor, composite, pos) {
|
|
22
|
+
const source = sourceOf(composite, compositeKindsOf(editor));
|
|
23
|
+
if (!source) return null;
|
|
24
|
+
let sourcePos = pos + 1;
|
|
25
|
+
for (let i = 0; i < source.index; i++) sourcePos += composite.child(i).nodeSize;
|
|
26
|
+
return {
|
|
27
|
+
node: source.node,
|
|
28
|
+
pos: sourcePos
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** The element of the node view at `pos` that carries the view's own listeners (the framework's wrapper), or null. */
|
|
32
|
+
function viewElement(editor, pos) {
|
|
33
|
+
const dom = editor.view.nodeDOM(pos);
|
|
34
|
+
if (!(dom instanceof HTMLElement)) return null;
|
|
35
|
+
return dom.matches("[data-node-view-wrapper]") ? dom : dom.querySelector("[data-node-view-wrapper]") ?? dom;
|
|
36
|
+
}
|
|
37
|
+
function playAt(editor, sourcePos, seconds) {
|
|
38
|
+
const dom = editor.view.nodeDOM(sourcePos);
|
|
39
|
+
if (!(dom instanceof HTMLElement)) return false;
|
|
40
|
+
const media = dom.matches("audio,video") ? dom : dom.querySelector("audio,video");
|
|
41
|
+
if (!media) return false;
|
|
42
|
+
media.currentTime = seconds;
|
|
43
|
+
media.play().catch(() => {});
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Seeks and plays the audio/video of the nearest source-holding Baustein around `pos` (a transcript segment inside a
|
|
48
|
+
* rendition reaches the recording that way). Silent when there is no source or no media element.
|
|
49
|
+
*/
|
|
50
|
+
function seekSource(editor, pos, seconds) {
|
|
51
|
+
if (!Number.isFinite(seconds) || seconds < 0) return;
|
|
52
|
+
const $pos = editor.state.doc.resolve(pos);
|
|
53
|
+
for (let depth = $pos.depth; depth >= 0; depth--) {
|
|
54
|
+
const composite = $pos.node(depth);
|
|
55
|
+
if (composite.type.name !== "composite") continue;
|
|
56
|
+
const source = sourceAt(editor, composite, $pos.before(depth));
|
|
57
|
+
if (!source) continue;
|
|
58
|
+
playAt(editor, source.pos, seconds);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Shows the source of Baustein `targetId` at `locator`: a `mm:ss` time seeks the media, a page number opens a PDF source
|
|
64
|
+
* at that page; then the source block flashes. Silent when the target or its source is gone.
|
|
65
|
+
*/
|
|
66
|
+
function revealSource(editor, targetId, locator) {
|
|
67
|
+
const target = findBlockById(editor.state.doc, targetId);
|
|
68
|
+
if (!target) return;
|
|
69
|
+
const source = sourceAt(editor, target.node, target.pos);
|
|
70
|
+
if (!source) return;
|
|
71
|
+
const parsed = parseLocator(locator);
|
|
72
|
+
if (parsed && "seconds" in parsed) playAt(editor, source.pos, parsed.seconds);
|
|
73
|
+
else if (parsed && source.node.type.name === "file" && source.node.attrs.mimeType === "application/pdf") viewElement(editor, source.pos)?.dispatchEvent(new CustomEvent(REVEAL_PAGE_EVENT, { detail: parsed.page }));
|
|
74
|
+
editor.commands.revealBlock(blockIdOf(source.node) ?? targetId);
|
|
75
|
+
}
|
|
76
|
+
/** Registers `seekSource` as an editor command, so features that must not import composites (transcript) can call it. */
|
|
77
|
+
const SourceReveal = Extension.create({
|
|
78
|
+
name: "sourceReveal",
|
|
79
|
+
addCommands() {
|
|
80
|
+
return { seekSource: (pos, seconds) => ({ editor }) => {
|
|
81
|
+
seekSource(editor, pos, seconds);
|
|
82
|
+
return true;
|
|
83
|
+
} };
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
//#endregion
|
|
87
|
+
export { REVEAL_PAGE_EVENT, SourceReveal, parseLocator, revealSource, seekSource };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=reveal-source.js.map
|