@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEditorContext } from "../../vue/context.js";
|
|
2
|
-
import { createDocumentChat } from "./document-chat-model.js";
|
|
3
2
|
import { modelProfiles } from "./model-profiles.js";
|
|
3
|
+
import { createDocumentChat } from "./document-chat-model.js";
|
|
4
4
|
import { useNotifier } from "../../vue/use-notifier.js";
|
|
5
5
|
import { useStoreRef } from "../../vue/store-ref.js";
|
|
6
6
|
import { computed, getCurrentScope, onScopeDispose } from "vue";
|
|
@@ -13,7 +13,7 @@ import { computed, getCurrentScope, onScopeDispose } from "vue";
|
|
|
13
13
|
function useDocumentChat(editor) {
|
|
14
14
|
const context = useEditorContext();
|
|
15
15
|
const chat = createDocumentChat({
|
|
16
|
-
|
|
16
|
+
ai: context.backend.ai,
|
|
17
17
|
modelRef: modelProfiles(context).modelRef,
|
|
18
18
|
notify: useNotifier(editor),
|
|
19
19
|
t: context.t
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-document-chat.js","names":[],"sources":["../../../src/features/ai/use-document-chat.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { computed, getCurrentScope, type MaybeRefOrGetter, onScopeDispose } from 'vue'\nimport { useEditorContext } from '../../vue/context'\nimport { useStoreRef } from '../../vue/store-ref'\nimport { useNotifier } from '../../vue/use-notifier'\nimport { createDocumentChat } from './document-chat-model'\nimport { modelProfiles } from './model-profiles'\n\nexport type { AgentOpState } from './agent-op-review'\nexport type { DocumentChatGeneration, DocumentChatTurn } from './document-chat-model'\n\n/**\n * The document chat (see `createDocumentChat`) as Vue refs: a thin hook. Call it during component setup (it injects\n * the editor context); the request stops with the component's scope. The 429 notice goes to `editor`'s surface (else\n * the app's notifier).\n */\nexport function useDocumentChat(editor?: MaybeRefOrGetter<Editor | undefined>) {\n const context = useEditorContext()\n const chat = createDocumentChat({
|
|
1
|
+
{"version":3,"file":"use-document-chat.js","names":[],"sources":["../../../src/features/ai/use-document-chat.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { computed, getCurrentScope, type MaybeRefOrGetter, onScopeDispose } from 'vue'\nimport { useEditorContext } from '../../vue/context'\nimport { useStoreRef } from '../../vue/store-ref'\nimport { useNotifier } from '../../vue/use-notifier'\nimport { createDocumentChat } from './document-chat-model'\nimport { modelProfiles } from './model-profiles'\n\nexport type { AgentOpState } from './agent-op-review'\nexport type { DocumentChatGeneration, DocumentChatTurn } from './document-chat-model'\n\n/**\n * The document chat (see `createDocumentChat`) as Vue refs: a thin hook. Call it during component setup (it injects\n * the editor context); the request stops with the component's scope. The 429 notice goes to `editor`'s surface (else\n * the app's notifier).\n */\nexport function useDocumentChat(editor?: MaybeRefOrGetter<Editor | undefined>) {\n const context = useEditorContext()\n const chat = createDocumentChat({ ai: context.backend.ai, modelRef: modelProfiles(context).modelRef, notify: useNotifier(editor), t: context.t })\n const snapshot = useStoreRef(chat.state)\n if (getCurrentScope()) onScopeDispose(chat.abort)\n const { ask, abort, reset, decide, reveal, addGeneration, updateGeneration, removeGeneration, clearError } = chat\n return {\n /** The underlying model, for flows that act on it (`createAiSidebarFlow`). */\n model: chat,\n messages: computed(() => snapshot.value.messages),\n ops: computed(() => snapshot.value.ops),\n streaming: computed(() => snapshot.value.streaming),\n error: computed(() => snapshot.value.error),\n ask,\n abort,\n reset,\n decide,\n reveal,\n addGeneration,\n updateGeneration,\n removeGeneration,\n clearError,\n }\n}\n"],"mappings":";;;;;;;;;;;;AAgBA,SAAgB,gBAAgB,QAA+C;CAC7E,MAAM,UAAU,iBAAiB;CACjC,MAAM,OAAO,mBAAmB;EAAE,IAAI,QAAQ,QAAQ;EAAI,UAAU,cAAc,OAAO,CAAC,CAAC;EAAU,QAAQ,YAAY,MAAM;EAAG,GAAG,QAAQ;CAAE,CAAC;CAChJ,MAAM,WAAW,YAAY,KAAK,KAAK;CACvC,IAAI,gBAAgB,GAAG,eAAe,KAAK,KAAK;CAChD,MAAM,EAAE,KAAK,OAAO,OAAO,QAAQ,QAAQ,eAAe,kBAAkB,kBAAkB,eAAe;CAC7G,OAAO;;EAEL,OAAO;EACP,UAAU,eAAe,SAAS,MAAM,QAAQ;EAChD,KAAK,eAAe,SAAS,MAAM,GAAG;EACtC,WAAW,eAAe,SAAS,MAAM,SAAS;EAClD,OAAO,eAAe,SAAS,MAAM,KAAK;EAC1C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ModelSlot } from "../../settings/values.js";
|
|
2
2
|
import "../../settings/index.js";
|
|
3
|
-
import { ModelProfile, ModelRef
|
|
3
|
+
import { ModelProfile, ModelRef } from "../../core/backend-types.js";
|
|
4
|
+
import { UserModelProfile } from "./protocol/models.js";
|
|
4
5
|
import "./protocol/index.js";
|
|
5
6
|
import { ComputedRef, Ref } from "vue";
|
|
6
7
|
//#region src/features/ai/use-model-profiles.d.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { ReadonlyStore } from "../../core/store.js";
|
|
1
2
|
import { AuthorColorStyle } from "../../settings/values.js";
|
|
2
3
|
import "../../settings/index.js";
|
|
3
|
-
import { ReadonlyStore } from "../../core/store.js";
|
|
4
4
|
import { AuthorIdentity } from "../../core/feature.js";
|
|
5
5
|
import "../../core/index.js";
|
|
6
6
|
import { Editor, Extension } from "@tiptap/core";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { derived } from "../../core/store.js";
|
|
2
|
-
import { AuthorMark } from "./schema.js";
|
|
2
|
+
import { AuthorMark, authorsSchemaExtensions } from "./schema.js";
|
|
3
3
|
import { AuthorAttribution } from "./attribution.js";
|
|
4
4
|
//#region src/features/authors/feature.ts
|
|
5
5
|
/**
|
|
@@ -14,6 +14,8 @@ import { AuthorAttribution } from "./attribution.js";
|
|
|
14
14
|
function authorsFeatureCore(ui) {
|
|
15
15
|
return {
|
|
16
16
|
id: "authors",
|
|
17
|
+
dimension: "content",
|
|
18
|
+
schemaExtensions: authorsSchemaExtensions,
|
|
17
19
|
extensions: (ctx) => [AuthorMark, AuthorAttribution.configure({
|
|
18
20
|
user: () => ctx.collaboration?.user ?? null,
|
|
19
21
|
isYSync: (tr) => ctx.anchorResolver?.isYSync(tr) ?? false,
|
|
@@ -22,16 +24,15 @@ function authorsFeatureCore(ui) {
|
|
|
22
24
|
style: editing.authorColorStyle
|
|
23
25
|
}), (a, b) => a.enabled === b.enabled && a.style === b.style)
|
|
24
26
|
})],
|
|
25
|
-
|
|
26
|
-
id: "
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}]
|
|
27
|
+
commands: (ctx) => [{
|
|
28
|
+
id: "authorColors",
|
|
29
|
+
toolbar: {
|
|
30
|
+
group: "collaboration",
|
|
31
|
+
order: 20
|
|
32
|
+
},
|
|
33
|
+
icon: "i-lucide-palette",
|
|
34
|
+
label: ctx.t("authors.title"),
|
|
35
|
+
component: ui.toolbarButton
|
|
35
36
|
}],
|
|
36
37
|
settingsTabs: (ctx) => [{
|
|
37
38
|
id: "authors",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/authors/feature.ts"],"sourcesContent":["import type { EditorFeature } from '../../core'\nimport { derived } from '../../core/store'\nimport { AuthorAttribution } from './attribution'\nimport { AuthorMark } from './schema'\n\n/** What a framework binding supplies to the authors feature. */\nexport interface AuthorsUi<C> {\n /** The „Autorenfarben“ toolbar button (its popover is the `AuthorColorsPanel`). */\n toolbarButton: C\n /** The „Autorenfarben“ settings tab component of the framework. */\n settingsTab: C\n}\n\n/**\n * Who wrote what: every text run the session's user inserts carries an `author` mark (id, name, colour; one author per\n * run, remote changes and Yjs undo/redo keep the original author's mark), the colouring mode (settings\n * `editing.authorColors` and `editing.authorColorStyle`) tints or colours the runs by author, the „Autorenfarben“\n * toolbar button shows the switch, the style and a legend of the document's authors, and the `authors` settings tab\n * holds the same switches. Attribution is inert without a user (`collaboration.user` of the surface), so standalone\n * editors write unmarked text. Remote changes are told apart through the preset's anchor resolver (collab feature),\n * which this feature does not import. The mark has no Markdown form (Markdown export and AI context stay clean).\n */\nexport function authorsFeatureCore<C>(ui: AuthorsUi<C>): EditorFeature<C> {\n return {\n id: 'authors',\n extensions: ctx => [\n AuthorMark,\n AuthorAttribution.configure({\n user: () => ctx.collaboration?.user ?? null,\n isYSync: tr => ctx.anchorResolver?.isYSync(tr) ?? false,\n coloring: derived(\n ctx.settings,\n ({ editing }) => ({ enabled: editing.authorColors, style: editing.authorColorStyle }),\n (a, b) => a.enabled === b.enabled && a.style === b.style,\n ),\n }),\n ],\n
|
|
1
|
+
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/authors/feature.ts"],"sourcesContent":["import type { EditorFeature } from '../../core'\nimport { derived } from '../../core/store'\nimport { AuthorAttribution } from './attribution'\nimport { AuthorMark, authorsSchemaExtensions } from './schema'\n\n/** What a framework binding supplies to the authors feature. */\nexport interface AuthorsUi<C> {\n /** The „Autorenfarben“ toolbar button (its popover is the `AuthorColorsPanel`). */\n toolbarButton: C\n /** The „Autorenfarben“ settings tab component of the framework. */\n settingsTab: C\n}\n\n/**\n * Who wrote what: every text run the session's user inserts carries an `author` mark (id, name, colour; one author per\n * run, remote changes and Yjs undo/redo keep the original author's mark), the colouring mode (settings\n * `editing.authorColors` and `editing.authorColorStyle`) tints or colours the runs by author, the „Autorenfarben“\n * toolbar button shows the switch, the style and a legend of the document's authors, and the `authors` settings tab\n * holds the same switches. Attribution is inert without a user (`collaboration.user` of the surface), so standalone\n * editors write unmarked text. Remote changes are told apart through the preset's anchor resolver (collab feature),\n * which this feature does not import. The mark has no Markdown form (Markdown export and AI context stay clean).\n */\nexport function authorsFeatureCore<C>(ui: AuthorsUi<C>): EditorFeature<C> {\n return {\n id: 'authors',\n dimension: 'content',\n schemaExtensions: authorsSchemaExtensions,\n extensions: ctx => [\n AuthorMark,\n AuthorAttribution.configure({\n user: () => ctx.collaboration?.user ?? null,\n isYSync: tr => ctx.anchorResolver?.isYSync(tr) ?? false,\n coloring: derived(\n ctx.settings,\n ({ editing }) => ({ enabled: editing.authorColors, style: editing.authorColorStyle }),\n (a, b) => a.enabled === b.enabled && a.style === b.style,\n ),\n }),\n ],\n commands: ctx => [\n { id: 'authorColors', toolbar: { group: 'collaboration', order: 20 }, icon: 'i-lucide-palette', label: ctx.t('authors.title'), component: ui.toolbarButton },\n ],\n settingsTabs: ctx => [{ id: 'authors', label: ctx.t('authors.tab'), icon: 'i-lucide-palette', component: ui.settingsTab }],\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAsBA,SAAgB,mBAAsB,IAAoC;CACxE,OAAO;EACL,IAAI;EACJ,WAAW;EACX,kBAAkB;EAClB,aAAY,QAAO,CACjB,YACA,kBAAkB,UAAU;GAC1B,YAAY,IAAI,eAAe,QAAQ;GACvC,UAAS,OAAM,IAAI,gBAAgB,QAAQ,EAAE,KAAK;GAClD,UAAU,QACR,IAAI,WACH,EAAE,eAAe;IAAE,SAAS,QAAQ;IAAc,OAAO,QAAQ;GAAiB,KAClF,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,KACrD;EACF,CAAC,CACH;EACA,WAAU,QAAO,CACf;GAAE,IAAI;GAAgB,SAAS;IAAE,OAAO;IAAiB,OAAO;GAAG;GAAG,MAAM;GAAoB,OAAO,IAAI,EAAE,eAAe;GAAG,WAAW,GAAG;EAAc,CAC7J;EACA,eAAc,QAAO,CAAC;GAAE,IAAI;GAAW,OAAO,IAAI,EAAE,aAAa;GAAG,MAAM;GAAoB,WAAW,GAAG;EAAY,CAAC;CAC3H;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MenuItem } from "../../core/
|
|
1
|
+
import { MenuItem } from "../../core/command-types.js";
|
|
2
2
|
import { BlockAction, BlockActionContext, BlockTarget } from "../../core/extension-points.js";
|
|
3
3
|
import "../../core/index.js";
|
|
4
4
|
import { Editor } from "@tiptap/core";
|
|
@@ -13,5 +13,26 @@ export interface BlockActionEntry {
|
|
|
13
13
|
export declare function effectiveTarget(editor: Editor, target: BlockTarget): BlockTarget;
|
|
14
14
|
/** The actions `target` offers; a `menu` action only when its menu has items. */
|
|
15
15
|
export declare function blockActionsFor(editor: Editor, target: BlockTarget, actions: readonly BlockAction[]): BlockActionEntry[];
|
|
16
|
+
/**
|
|
17
|
+
* Attribute a block's own chrome sets on the elements it shows in its top-right corner (status badges, kind or menu
|
|
18
|
+
* buttons, ...). The hover bar docks immediately left of them, vertically centred on them, so both read as one row
|
|
19
|
+
* instead of the bar covering the block's icons. A block without such elements gets the bar at the editor's right edge.
|
|
20
|
+
*/
|
|
21
|
+
export declare const BLOCK_CORNER_ATTR = "data-block-corner";
|
|
22
|
+
/** Where a block's corner elements sit, in viewport coordinates. */
|
|
23
|
+
export interface BlockCorner {
|
|
24
|
+
/** Left edge of the leftmost corner element. */
|
|
25
|
+
left: number;
|
|
26
|
+
/** Vertical centre of the first corner element. */
|
|
27
|
+
centerY: number;
|
|
28
|
+
/** The marked elements, for a host that wants to watch them for size changes. */
|
|
29
|
+
elements: HTMLElement[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The corner elements `dom` (a block's node view root) marks with `BLOCK_CORNER_ATTR`, or null when none is shown.
|
|
33
|
+
* Elements inside a nested block's own node view belong to that block and do not count; neither do hidden ones (no
|
|
34
|
+
* layout box).
|
|
35
|
+
*/
|
|
36
|
+
export declare function blockCornerOf(dom: HTMLElement): BlockCorner | null;
|
|
16
37
|
//#endregion
|
|
17
38
|
//# sourceMappingURL=block-actions.d.ts.map
|
|
@@ -18,7 +18,7 @@ function blockActionsFor(editor, target, actions) {
|
|
|
18
18
|
abilities: abilitiesAt(editor, target.pos, target.node)
|
|
19
19
|
};
|
|
20
20
|
return actions.flatMap((action) => {
|
|
21
|
-
if (!ctx.abilities.has(action.ability) || action.isVisible?.(ctx) === false) return [];
|
|
21
|
+
if (action.ability && !ctx.abilities.has(action.ability) || action.isVisible?.(ctx) === false) return [];
|
|
22
22
|
if (!action.menu) return [{
|
|
23
23
|
action,
|
|
24
24
|
ctx
|
|
@@ -31,7 +31,31 @@ function blockActionsFor(editor, target, actions) {
|
|
|
31
31
|
}] : [];
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Attribute a block's own chrome sets on the elements it shows in its top-right corner (status badges, kind or menu
|
|
36
|
+
* buttons, ...). The hover bar docks immediately left of them, vertically centred on them, so both read as one row
|
|
37
|
+
* instead of the bar covering the block's icons. A block without such elements gets the bar at the editor's right edge.
|
|
38
|
+
*/
|
|
39
|
+
const BLOCK_CORNER_ATTR = "data-block-corner";
|
|
40
|
+
/**
|
|
41
|
+
* The corner elements `dom` (a block's node view root) marks with `BLOCK_CORNER_ATTR`, or null when none is shown.
|
|
42
|
+
* Elements inside a nested block's own node view belong to that block and do not count; neither do hidden ones (no
|
|
43
|
+
* layout box).
|
|
44
|
+
*/
|
|
45
|
+
function blockCornerOf(dom) {
|
|
46
|
+
const elements = [...dom.querySelectorAll(`[${BLOCK_CORNER_ATTR}]`)].filter((element) => {
|
|
47
|
+
const owner = element.closest("[data-node-view-wrapper]");
|
|
48
|
+
return !(owner && owner !== dom && dom.contains(owner));
|
|
49
|
+
});
|
|
50
|
+
const rects = elements.map((element) => element.getBoundingClientRect()).filter((rect) => rect.width > 0 && rect.height > 0);
|
|
51
|
+
if (!rects.length) return null;
|
|
52
|
+
return {
|
|
53
|
+
left: Math.min(...rects.map((rect) => rect.left)),
|
|
54
|
+
centerY: rects[0].top + rects[0].height / 2,
|
|
55
|
+
elements
|
|
56
|
+
};
|
|
57
|
+
}
|
|
34
58
|
//#endregion
|
|
35
|
-
export { blockActionsFor, effectiveTarget };
|
|
59
|
+
export { BLOCK_CORNER_ATTR, blockActionsFor, blockCornerOf, effectiveTarget };
|
|
36
60
|
|
|
37
61
|
//# sourceMappingURL=block-actions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-actions.js","names":[],"sources":["../../../src/features/block-ui/block-actions.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { abilitiesAt, type BlockAction, type BlockActionContext, type BlockTarget, type MenuItem } from '../../core'\nimport { isChromeNode } from '../../core/schema'\n\n/** An action `target` offers, with the context it runs with and, for a `menu` action, its items. */\nexport interface BlockActionEntry {\n action: BlockAction\n ctx: BlockActionContext\n menu?: MenuItem[]\n}\n\n/** Hovering a composite's title/description/tags row addresses the composite itself. */\nexport function effectiveTarget(editor: Editor, target: BlockTarget): BlockTarget {\n if (!isChromeNode(target.node)) return target\n const $pos = editor.state.doc.resolve(target.pos)\n return { node: $pos.parent, pos: $pos.before() }\n}\n\n/** The actions `target` offers; a `menu` action only when its menu has items. */\nexport function blockActionsFor(editor: Editor, target: BlockTarget, actions: readonly BlockAction[]): BlockActionEntry[] {\n const ctx: BlockActionContext = { ...target, editor, abilities: abilitiesAt(editor, target.pos, target.node) }\n return actions.flatMap((action): BlockActionEntry[] => {\n if (!ctx.abilities.has(action.ability) || action.isVisible?.(ctx) === false) return []\n if (!action.menu) return [{ action, ctx }]\n const menu = action.menu(ctx)\n return menu.length ? [{ action, ctx, menu }] : []\n })\n}\n"],"mappings":";;;;AAYA,SAAgB,gBAAgB,QAAgB,QAAkC;CAChF,IAAI,CAAC,aAAa,OAAO,IAAI,GAAG,OAAO;CACvC,MAAM,OAAO,OAAO,MAAM,IAAI,QAAQ,OAAO,GAAG;CAChD,OAAO;EAAE,MAAM,KAAK;EAAQ,KAAK,KAAK,OAAO;CAAE;AACjD;;AAGA,SAAgB,gBAAgB,QAAgB,QAAqB,SAAqD;CACxH,MAAM,MAA0B;EAAE,GAAG;EAAQ;EAAQ,WAAW,YAAY,QAAQ,OAAO,KAAK,OAAO,IAAI;CAAE;CAC7G,OAAO,QAAQ,SAAS,WAA+B;EACrD,
|
|
1
|
+
{"version":3,"file":"block-actions.js","names":[],"sources":["../../../src/features/block-ui/block-actions.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { abilitiesAt, type BlockAction, type BlockActionContext, type BlockTarget, type MenuItem } from '../../core'\nimport { isChromeNode } from '../../core/schema'\n\n/** An action `target` offers, with the context it runs with and, for a `menu` action, its items. */\nexport interface BlockActionEntry {\n action: BlockAction\n ctx: BlockActionContext\n menu?: MenuItem[]\n}\n\n/** Hovering a composite's title/description/tags row addresses the composite itself. */\nexport function effectiveTarget(editor: Editor, target: BlockTarget): BlockTarget {\n if (!isChromeNode(target.node)) return target\n const $pos = editor.state.doc.resolve(target.pos)\n return { node: $pos.parent, pos: $pos.before() }\n}\n\n/** The actions `target` offers; a `menu` action only when its menu has items. */\nexport function blockActionsFor(editor: Editor, target: BlockTarget, actions: readonly BlockAction[]): BlockActionEntry[] {\n const ctx: BlockActionContext = { ...target, editor, abilities: abilitiesAt(editor, target.pos, target.node) }\n return actions.flatMap((action): BlockActionEntry[] => {\n if ((action.ability && !ctx.abilities.has(action.ability)) || action.isVisible?.(ctx) === false) return []\n if (!action.menu) return [{ action, ctx }]\n const menu = action.menu(ctx)\n return menu.length ? [{ action, ctx, menu }] : []\n })\n}\n\n/**\n * Attribute a block's own chrome sets on the elements it shows in its top-right corner (status badges, kind or menu\n * buttons, ...). The hover bar docks immediately left of them, vertically centred on them, so both read as one row\n * instead of the bar covering the block's icons. A block without such elements gets the bar at the editor's right edge.\n */\nexport const BLOCK_CORNER_ATTR = 'data-block-corner'\n\n/** Where a block's corner elements sit, in viewport coordinates. */\nexport interface BlockCorner {\n /** Left edge of the leftmost corner element. */\n left: number\n /** Vertical centre of the first corner element. */\n centerY: number\n /** The marked elements, for a host that wants to watch them for size changes. */\n elements: HTMLElement[]\n}\n\n/**\n * The corner elements `dom` (a block's node view root) marks with `BLOCK_CORNER_ATTR`, or null when none is shown.\n * Elements inside a nested block's own node view belong to that block and do not count; neither do hidden ones (no\n * layout box).\n */\nexport function blockCornerOf(dom: HTMLElement): BlockCorner | null {\n const elements = [...dom.querySelectorAll<HTMLElement>(`[${BLOCK_CORNER_ATTR}]`)].filter((element) => {\n const owner = element.closest('[data-node-view-wrapper]')\n return !(owner && owner !== dom && dom.contains(owner))\n })\n const rects = elements.map(element => element.getBoundingClientRect()).filter(rect => rect.width > 0 && rect.height > 0)\n if (!rects.length) return null\n return {\n left: Math.min(...rects.map(rect => rect.left)),\n centerY: rects[0]!.top + rects[0]!.height / 2,\n elements,\n }\n}\n"],"mappings":";;;;AAYA,SAAgB,gBAAgB,QAAgB,QAAkC;CAChF,IAAI,CAAC,aAAa,OAAO,IAAI,GAAG,OAAO;CACvC,MAAM,OAAO,OAAO,MAAM,IAAI,QAAQ,OAAO,GAAG;CAChD,OAAO;EAAE,MAAM,KAAK;EAAQ,KAAK,KAAK,OAAO;CAAE;AACjD;;AAGA,SAAgB,gBAAgB,QAAgB,QAAqB,SAAqD;CACxH,MAAM,MAA0B;EAAE,GAAG;EAAQ;EAAQ,WAAW,YAAY,QAAQ,OAAO,KAAK,OAAO,IAAI;CAAE;CAC7G,OAAO,QAAQ,SAAS,WAA+B;EACrD,IAAK,OAAO,WAAW,CAAC,IAAI,UAAU,IAAI,OAAO,OAAO,KAAM,OAAO,YAAY,GAAG,MAAM,OAAO,OAAO,CAAC;EACzG,IAAI,CAAC,OAAO,MAAM,OAAO,CAAC;GAAE;GAAQ;EAAI,CAAC;EACzC,MAAM,OAAO,OAAO,KAAK,GAAG;EAC5B,OAAO,KAAK,SAAS,CAAC;GAAE;GAAQ;GAAK;EAAK,CAAC,IAAI,CAAC;CAClD,CAAC;AACH;;;;;;AAOA,MAAa,oBAAoB;;;;;;AAiBjC,SAAgB,cAAc,KAAsC;CAClE,MAAM,WAAW,CAAC,GAAG,IAAI,iBAA8B,IAAI,kBAAkB,EAAE,CAAC,CAAC,CAAC,QAAQ,YAAY;EACpG,MAAM,QAAQ,QAAQ,QAAQ,0BAA0B;EACxD,OAAO,EAAE,SAAS,UAAU,OAAO,IAAI,SAAS,KAAK;CACvD,CAAC;CACD,MAAM,QAAQ,SAAS,KAAI,YAAW,QAAQ,sBAAsB,CAAC,CAAC,CAAC,QAAO,SAAQ,KAAK,QAAQ,KAAK,KAAK,SAAS,CAAC;CACvH,IAAI,CAAC,MAAM,QAAQ,OAAO;CAC1B,OAAO;EACL,MAAM,KAAK,IAAI,GAAG,MAAM,KAAI,SAAQ,KAAK,IAAI,CAAC;EAC9C,SAAS,MAAM,EAAE,CAAE,MAAM,MAAM,EAAE,CAAE,SAAS;EAC5C;CACF;AACF"}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { useUiKit } from "../../../vue/kit/use-ui-kit.js";
|
|
2
|
-
import { blockActionsFor, effectiveTarget } from "../block-actions.js";
|
|
2
|
+
import { blockActionsFor, blockCornerOf, effectiveTarget } from "../block-actions.js";
|
|
3
3
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createVNode, defineComponent, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, unref, useTemplateRef, watch, withCtx, withModifiers } from "vue";
|
|
4
4
|
//#region src/features/block-ui/components/BlockActionsOverlay.vue
|
|
5
5
|
/** Gap between the bar and the editor's right edge. */
|
|
6
6
|
const EDGE_GUTTER = 8;
|
|
7
|
+
/** Gap between the bar and the block's own corner elements it docks next to. */
|
|
8
|
+
const CORNER_GAP = 4;
|
|
7
9
|
/**
|
|
8
10
|
* The hover actions of a block, right-aligned at the editor's text column (the drag handle sits on the block's left and
|
|
9
11
|
* targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite
|
|
10
12
|
* chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is
|
|
11
13
|
* read-only. `menu` actions open a dropdown of their items instead of running on click.
|
|
14
|
+
*
|
|
15
|
+
* A block that shows icons of its own in its top-right corner marks them with `data-block-corner` (`BLOCK_CORNER_ATTR`):
|
|
16
|
+
* the bar then docks immediately left of them, centred on their row, instead of covering them. Without such elements
|
|
17
|
+
* it sits at the editor's right edge, aligned to the block's top.
|
|
12
18
|
*/
|
|
13
19
|
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
14
20
|
__name: "BlockActionsOverlay",
|
|
@@ -43,13 +49,33 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
43
49
|
const items = computed(() => block.value ? blockActionsFor(props.editor, block.value, props.actions) : []);
|
|
44
50
|
const top = ref(0);
|
|
45
51
|
const right = ref(0);
|
|
52
|
+
/** Whether the bar is docked next to the block's corner elements: `top` is then their vertical centre. */
|
|
53
|
+
const docked = ref(false);
|
|
46
54
|
const measured = ref(false);
|
|
55
|
+
let watched = [];
|
|
56
|
+
function watchCorner(elements) {
|
|
57
|
+
if (elements.length === watched.length && elements.every((element, index) => element === watched[index])) return;
|
|
58
|
+
for (const element of watched) resizeObserver?.unobserve(element);
|
|
59
|
+
watched = elements;
|
|
60
|
+
for (const element of watched) resizeObserver?.observe(element);
|
|
61
|
+
}
|
|
47
62
|
function measure() {
|
|
48
63
|
const { editor, host } = props;
|
|
49
64
|
const dom = block.value && host && !editor.isDestroyed ? editor.view.nodeDOM(block.value.pos) : null;
|
|
50
65
|
measured.value = dom instanceof HTMLElement;
|
|
51
|
-
if (!(dom instanceof HTMLElement) || !host)
|
|
66
|
+
if (!(dom instanceof HTMLElement) || !host) {
|
|
67
|
+
watchCorner([]);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
52
70
|
const hostRect = host.getBoundingClientRect();
|
|
71
|
+
const corner = blockCornerOf(dom);
|
|
72
|
+
watchCorner(corner?.elements ?? []);
|
|
73
|
+
docked.value = corner !== null;
|
|
74
|
+
if (corner) {
|
|
75
|
+
top.value = corner.centerY - hostRect.top;
|
|
76
|
+
right.value = hostRect.right - corner.left + CORNER_GAP;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
53
79
|
const rect = dom.getBoundingClientRect();
|
|
54
80
|
top.value = rect.top - hostRect.top + 2;
|
|
55
81
|
right.value = hostRect.right - editor.view.dom.getBoundingClientRect().right + EDGE_GUTTER;
|
|
@@ -76,21 +102,24 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
76
102
|
window.addEventListener("scroll", measure, true);
|
|
77
103
|
resizeObserver = new ResizeObserver(measure);
|
|
78
104
|
resizeObserver.observe(props.editor.view.dom);
|
|
105
|
+
for (const element of watched) resizeObserver.observe(element);
|
|
79
106
|
});
|
|
80
107
|
onBeforeUnmount(() => {
|
|
81
108
|
window.removeEventListener("resize", measure);
|
|
82
109
|
window.removeEventListener("scroll", measure, true);
|
|
83
110
|
resizeObserver?.disconnect();
|
|
111
|
+
watched = [];
|
|
84
112
|
});
|
|
85
113
|
return (_ctx, _cache) => {
|
|
86
114
|
return visible.value ? (openBlock(), createElementBlock("div", {
|
|
87
115
|
key: 0,
|
|
88
116
|
ref_key: "root",
|
|
89
117
|
ref: root,
|
|
90
|
-
class: "block-actions absolute z-10 flex gap-0.5 rounded-md
|
|
118
|
+
class: "block-actions absolute z-10 flex gap-0.5 rounded-md bg-[var(--sk-bg)] p-0.5",
|
|
91
119
|
style: normalizeStyle({
|
|
92
120
|
top: `${top.value}px`,
|
|
93
|
-
right: `${right.value}px
|
|
121
|
+
right: `${right.value}px`,
|
|
122
|
+
transform: docked.value ? "translateY(-50%)" : void 0
|
|
94
123
|
}),
|
|
95
124
|
onMouseenter: _cache[2] || (_cache[2] = ($event) => emit("hover", true)),
|
|
96
125
|
onMouseleave: onMouseLeave
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockActionsOverlay.js","names":["_openBlock","_createElementBlock","_normalizeStyle","_Fragment","_renderList","_createBlock","_unref","_withCtx","_createVNode","_withModifiers","_createCommentVNode"],"sources":["../../../../src/features/block-ui/components/BlockActionsOverlay.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useUiKit } from '../../../vue/kit/use-ui-kit'\nimport type { Editor } from '@tiptap/vue-3'\nimport { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue'\nimport type { BlockAction, BlockTarget } from '../../../core'\nimport { blockActionsFor, effectiveTarget } from '../block-actions'\n\n/** Gap between the bar and the editor's right edge. */\nconst EDGE_GUTTER = 8\n\n/**\n * The hover actions of a block, right-aligned at the editor's text column (the drag handle sits on the block's left and\n * targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite\n * chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is\n * read-only. `menu` actions open a dropdown of their items instead of running on click.\n */\nconst props = defineProps<{\n editor: Editor\n target: BlockTarget | null\n actions: readonly BlockAction[]\n host: HTMLElement | null\n}>()\n\nconst { Button: UButton, DropdownMenu: UDropdownMenu, Tooltip: UTooltip } = useUiKit()\n\nconst emit = defineEmits<{ hover: [hovered: boolean] }>()\n\n/** The target in the current document; null once its position holds something else (deleted, replaced). */\nconst block = computed<BlockTarget | null>(() => {\n const { editor, target } = props\n if (!target || editor.isDestroyed) return null\n const { doc } = editor.state\n if (target.pos < 0 || target.pos >= doc.content.size) return null\n const node = doc.nodeAt(target.pos)\n if (!node || node.type !== target.node.type) return null\n return effectiveTarget(editor, { node, pos: target.pos })\n})\n\n// Reading `state` makes the flag follow `setEditable` (which dispatches a transaction).\nconst editable = computed(() => {\n void props.editor.state\n return props.editor.isEditable\n})\n\nconst items = computed(() => (block.value ? blockActionsFor(props.editor, block.value, props.actions) : []))\n\nconst top = ref(0)\nconst right = ref(0)\nconst measured = ref(false)\n\nfunction measure() {\n const { editor, host } = props\n const dom = block.value && host && !editor.isDestroyed ? editor.view.nodeDOM(block.value.pos) : null\n measured.value = dom instanceof HTMLElement\n if (!(dom instanceof HTMLElement) || !host) return\n const hostRect = host.getBoundingClientRect()\n const rect = dom.getBoundingClientRect()\n top.value = rect.top - hostRect.top + 2\n right.value = hostRect.right - editor.view.dom.getBoundingClientRect().right + EDGE_GUTTER\n}\n\nwatch([block, () => props.editor.state], measure, { flush: 'post' })\n\nconst visible = computed(() => editable.value && items.value.length > 0 && measured.value)\n\n// An open action menu is rendered outside the overlay (portal): the overlay counts as hovered until the menu closes.\nconst root = useTemplateRef<HTMLElement>('root')\nconst menuOpen = ref(false)\nfunction onMenuOpen(open: boolean) {\n menuOpen.value = open\n emit('hover', open || !!root.value?.matches(':hover'))\n}\nfunction onMouseLeave() {\n if (!menuOpen.value) emit('hover', false)\n}\n\n// A vanishing overlay sends no mouseleave: report it, so the host does not keep waiting for one.\nwatch(visible, (value) => {\n if (value) return\n menuOpen.value = false\n emit('hover', false)\n})\n\n// The bar follows the editor's right edge when the column resizes without the window doing so.\nlet resizeObserver: ResizeObserver | undefined\nonMounted(() => {\n window.addEventListener('resize', measure)\n window.addEventListener('scroll', measure, true)\n resizeObserver = new ResizeObserver(measure)\n resizeObserver.observe(props.editor.view.dom)\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('resize', measure)\n window.removeEventListener('scroll', measure, true)\n resizeObserver?.disconnect()\n})\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n ref=\"root\"\n class=\"block-actions absolute z-10 flex gap-0.5 rounded-md border border-[var(--sk-border)] bg-[var(--sk-bg)] p-0.5 shadow-sm\"\n :style=\"{ top: `${top}px`, right: `${right}px` }\"\n @mouseenter=\"emit('hover', true)\"\n @mouseleave=\"onMouseLeave\"\n >\n <template v-for=\"entry in items\" :key=\"entry.action.id\">\n <UDropdownMenu v-if=\"entry.menu\" :items=\"entry.menu\" :content=\"{ align: 'end' }\" @update:open=\"onMenuOpen\">\n <UTooltip :text=\"entry.action.label\">\n <UButton\n size=\"xs\"\n color=\"neutral\"\n variant=\"ghost\"\n :icon=\"entry.action.icon\"\n :aria-label=\"entry.action.label\"\n @mousedown.prevent\n />\n </UTooltip>\n </UDropdownMenu>\n <UTooltip v-else :text=\"entry.action.label\">\n <UButton\n size=\"xs\"\n color=\"neutral\"\n variant=\"ghost\"\n :icon=\"entry.action.icon\"\n :aria-label=\"entry.action.label\"\n @mousedown.prevent\n @click=\"entry.action.run?.(entry.ctx)\"\n />\n </UTooltip>\n </template>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BlockActionsOverlay.js","names":["_openBlock","_createElementBlock","_normalizeStyle","_Fragment","_renderList","_createBlock","_unref","_withCtx","_createVNode","_withModifiers","_createCommentVNode"],"sources":["../../../../src/features/block-ui/components/BlockActionsOverlay.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useUiKit } from '../../../vue/kit/use-ui-kit'\nimport type { Editor } from '@tiptap/vue-3'\nimport { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue'\nimport type { BlockAction, BlockTarget } from '../../../core'\nimport { blockActionsFor, blockCornerOf, effectiveTarget } from '../block-actions'\n\n/** Gap between the bar and the editor's right edge. */\nconst EDGE_GUTTER = 8\n/** Gap between the bar and the block's own corner elements it docks next to. */\nconst CORNER_GAP = 4\n\n/**\n * The hover actions of a block, right-aligned at the editor's text column (the drag handle sits on the block's left and\n * targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite\n * chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is\n * read-only. `menu` actions open a dropdown of their items instead of running on click.\n *\n * A block that shows icons of its own in its top-right corner marks them with `data-block-corner` (`BLOCK_CORNER_ATTR`):\n * the bar then docks immediately left of them, centred on their row, instead of covering them. Without such elements\n * it sits at the editor's right edge, aligned to the block's top.\n */\nconst props = defineProps<{\n editor: Editor\n target: BlockTarget | null\n actions: readonly BlockAction[]\n host: HTMLElement | null\n}>()\n\nconst { Button: UButton, DropdownMenu: UDropdownMenu, Tooltip: UTooltip } = useUiKit()\n\nconst emit = defineEmits<{ hover: [hovered: boolean] }>()\n\n/** The target in the current document; null once its position holds something else (deleted, replaced). */\nconst block = computed<BlockTarget | null>(() => {\n const { editor, target } = props\n if (!target || editor.isDestroyed) return null\n const { doc } = editor.state\n if (target.pos < 0 || target.pos >= doc.content.size) return null\n const node = doc.nodeAt(target.pos)\n if (!node || node.type !== target.node.type) return null\n return effectiveTarget(editor, { node, pos: target.pos })\n})\n\n// Reading `state` makes the flag follow `setEditable` (which dispatches a transaction).\nconst editable = computed(() => {\n void props.editor.state\n return props.editor.isEditable\n})\n\nconst items = computed(() => (block.value ? blockActionsFor(props.editor, block.value, props.actions) : []))\n\nconst top = ref(0)\nconst right = ref(0)\n/** Whether the bar is docked next to the block's corner elements: `top` is then their vertical centre. */\nconst docked = ref(false)\nconst measured = ref(false)\n\nlet watched: HTMLElement[] = []\n// The corner elements can change size (a badge appears) without the document changing: watch the current ones.\nfunction watchCorner(elements: HTMLElement[]) {\n if (elements.length === watched.length && elements.every((element, index) => element === watched[index])) return\n for (const element of watched) resizeObserver?.unobserve(element)\n watched = elements\n for (const element of watched) resizeObserver?.observe(element)\n}\n\nfunction measure() {\n const { editor, host } = props\n const dom = block.value && host && !editor.isDestroyed ? editor.view.nodeDOM(block.value.pos) : null\n measured.value = dom instanceof HTMLElement\n if (!(dom instanceof HTMLElement) || !host) {\n watchCorner([])\n return\n }\n const hostRect = host.getBoundingClientRect()\n const corner = blockCornerOf(dom)\n watchCorner(corner?.elements ?? [])\n docked.value = corner !== null\n if (corner) {\n top.value = corner.centerY - hostRect.top\n right.value = hostRect.right - corner.left + CORNER_GAP\n return\n }\n const rect = dom.getBoundingClientRect()\n top.value = rect.top - hostRect.top + 2\n right.value = hostRect.right - editor.view.dom.getBoundingClientRect().right + EDGE_GUTTER\n}\n\nwatch([block, () => props.editor.state], measure, { flush: 'post' })\n\nconst visible = computed(() => editable.value && items.value.length > 0 && measured.value)\n\n// An open action menu is rendered outside the overlay (portal): the overlay counts as hovered until the menu closes.\nconst root = useTemplateRef<HTMLElement>('root')\nconst menuOpen = ref(false)\nfunction onMenuOpen(open: boolean) {\n menuOpen.value = open\n emit('hover', open || !!root.value?.matches(':hover'))\n}\nfunction onMouseLeave() {\n if (!menuOpen.value) emit('hover', false)\n}\n\n// A vanishing overlay sends no mouseleave: report it, so the host does not keep waiting for one.\nwatch(visible, (value) => {\n if (value) return\n menuOpen.value = false\n emit('hover', false)\n})\n\n// The bar follows the editor's right edge when the column resizes without the window doing so.\nlet resizeObserver: ResizeObserver | undefined\nonMounted(() => {\n window.addEventListener('resize', measure)\n window.addEventListener('scroll', measure, true)\n resizeObserver = new ResizeObserver(measure)\n resizeObserver.observe(props.editor.view.dom)\n for (const element of watched) resizeObserver.observe(element)\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('resize', measure)\n window.removeEventListener('scroll', measure, true)\n resizeObserver?.disconnect()\n watched = []\n})\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n ref=\"root\"\n class=\"block-actions absolute z-10 flex gap-0.5 rounded-md bg-[var(--sk-bg)] p-0.5\"\n :style=\"{ top: `${top}px`, right: `${right}px`, transform: docked ? 'translateY(-50%)' : undefined }\"\n @mouseenter=\"emit('hover', true)\"\n @mouseleave=\"onMouseLeave\"\n >\n <template v-for=\"entry in items\" :key=\"entry.action.id\">\n <UDropdownMenu v-if=\"entry.menu\" :items=\"entry.menu\" :content=\"{ align: 'end' }\" @update:open=\"onMenuOpen\">\n <UTooltip :text=\"entry.action.label\">\n <UButton\n size=\"xs\"\n color=\"neutral\"\n variant=\"ghost\"\n :icon=\"entry.action.icon\"\n :aria-label=\"entry.action.label\"\n @mousedown.prevent\n />\n </UTooltip>\n </UDropdownMenu>\n <UTooltip v-else :text=\"entry.action.label\">\n <UButton\n size=\"xs\"\n color=\"neutral\"\n variant=\"ghost\"\n :icon=\"entry.action.icon\"\n :aria-label=\"entry.action.label\"\n @mousedown.prevent\n @click=\"entry.action.run?.(entry.ctx)\"\n />\n </UTooltip>\n </template>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -7,6 +7,10 @@ import { Editor } from "@tiptap/vue-3";
|
|
|
7
7
|
* targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite
|
|
8
8
|
* chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is
|
|
9
9
|
* read-only. `menu` actions open a dropdown of their items instead of running on click.
|
|
10
|
+
*
|
|
11
|
+
* A block that shows icons of its own in its top-right corner marks them with `data-block-corner` (`BLOCK_CORNER_ATTR`):
|
|
12
|
+
* the bar then docks immediately left of them, centred on their row, instead of covering them. Without such elements
|
|
13
|
+
* it sits at the editor's right edge, aligned to the block's top.
|
|
10
14
|
*/
|
|
11
15
|
type __VLS_Props = {
|
|
12
16
|
editor: Editor;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isChromeNode } from "../../../core/schema/node-flags.js";
|
|
2
1
|
import { editorEntryOf } from "../../../core/editor-ui.js";
|
|
2
|
+
import { isChromeNode } from "../../../core/schema/node-flags.js";
|
|
3
3
|
import { useUiKit } from "../../../vue/kit/use-ui-kit.js";
|
|
4
4
|
import { useEditorSettings } from "../../../vue/settings.js";
|
|
5
5
|
import { firstLineCenterShift, gutterShiftOf, handleLeftOf, hasKindIcon } from "../handle-geometry.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/block-ui/feature.ts"],"sourcesContent":["import { NodeRange } from '@tiptap/extension-node-range'\nimport type { EditorFeature } from '../../core'\n\n/** What a framework binding supplies to the block-ui feature. */\nexport interface BlockUiUi<C> {\n /** The block UI of an editor (drag handle, permanent handles, hover actions); mounted beside the editor content. */\n overlay: C\n}\n\n/**\n * Block-level UI beside the editor content: the drag handle (upstream `@tiptap/extension-drag-handle`) with hover\n * targeting, and the hover actions of the targeted block (features' and host block actions, `BlockActionsOverlay`).\n * Also adds block-range selection (`NodeRange`: Mod+drag, Shift+↑/↓). Composite chrome (`editorChrome` nodes) targets its\n * parent block.\n *\n * Opt-in: the simple editor has none of it. Installing a binding also bundles the drag handle's transitive collaboration\n * support code (its upstream package imports `@tiptap/extension-collaboration` and `y-tiptap`), even without a live\n * collaboration session.\n */\nexport function blockUiFeatureCore<C>(ui: BlockUiUi<C>): EditorFeature<C> {\n return {\n id: 'block-ui',\n extensions: () => [NodeRange],\n overlays: [ui.overlay],\n }\n}\n"],"mappings":";;;;;;;;;;;;AAmBA,SAAgB,mBAAsB,IAAoC;CACxE,OAAO;EACL,IAAI;EACJ,kBAAkB,CAAC,SAAS;EAC5B,UAAU,CAAC,GAAG,OAAO;CACvB;AACF"}
|
|
1
|
+
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/block-ui/feature.ts"],"sourcesContent":["import { NodeRange } from '@tiptap/extension-node-range'\nimport type { EditorFeature } from '../../core'\n\n/** What a framework binding supplies to the block-ui feature. */\nexport interface BlockUiUi<C> {\n /** The block UI of an editor (drag handle, permanent handles, hover actions); mounted beside the editor content. */\n overlay: C\n}\n\n/**\n * Block-level UI beside the editor content: the drag handle (upstream `@tiptap/extension-drag-handle`) with hover\n * targeting, and the hover actions of the targeted block (features' and host block actions, `BlockActionsOverlay`).\n * Also adds block-range selection (`NodeRange`: Mod+drag, Shift+↑/↓). Composite chrome (`editorChrome` nodes) targets its\n * parent block.\n *\n * Opt-in: the simple editor has none of it. Installing a binding also bundles the drag handle's transitive collaboration\n * support code (its upstream package imports `@tiptap/extension-collaboration` and `y-tiptap`), even without a live\n * collaboration session.\n */\nexport function blockUiFeatureCore<C>(ui: BlockUiUi<C>): EditorFeature<C> {\n return {\n id: 'block-ui',\n dimension: 'interaction',\n extensions: () => [NodeRange],\n overlays: [ui.overlay],\n }\n}\n"],"mappings":";;;;;;;;;;;;AAmBA,SAAgB,mBAAsB,IAAoC;CACxE,OAAO;EACL,IAAI;EACJ,WAAW;EACX,kBAAkB,CAAC,SAAS;EAC5B,UAAU,CAAC,GAAG,OAAO;CACvB;AACF"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { BlockActionEntry, blockActionsFor, effectiveTarget } from "./block-actions.js";
|
|
1
|
+
import { BLOCK_CORNER_ATTR, BlockActionEntry, BlockCorner, blockActionsFor, blockCornerOf, effectiveTarget } from "./block-actions.js";
|
|
2
2
|
import { BlockUiUi, blockUiFeatureCore } from "./feature.js";
|
|
3
|
-
export { type BlockActionEntry, type BlockUiUi, blockActionsFor, blockUiFeatureCore, effectiveTarget };
|
|
3
|
+
export { BLOCK_CORNER_ATTR, type BlockActionEntry, type BlockCorner, type BlockUiUi, blockActionsFor, blockCornerOf, blockUiFeatureCore, effectiveTarget };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { blockUiFeatureCore } from "./feature.js";
|
|
2
|
-
import { blockActionsFor, effectiveTarget } from "./block-actions.js";
|
|
3
|
-
export { blockActionsFor, blockUiFeatureCore, effectiveTarget };
|
|
2
|
+
import { BLOCK_CORNER_ATTR, blockActionsFor, blockCornerOf, effectiveTarget } from "./block-actions.js";
|
|
3
|
+
export { BLOCK_CORNER_ATTR, blockActionsFor, blockCornerOf, blockUiFeatureCore, effectiveTarget };
|
|
@@ -7,6 +7,10 @@ import { Editor } from "@tiptap/core";
|
|
|
7
7
|
* targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite
|
|
8
8
|
* chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is
|
|
9
9
|
* read-only. `menu` actions open a dropdown of their items instead of running on click.
|
|
10
|
+
*
|
|
11
|
+
* A block that shows icons of its own in its top-right corner marks them with `data-block-corner` (`BLOCK_CORNER_ATTR`):
|
|
12
|
+
* the bar then docks immediately left of them, centred on their row, instead of covering them. Without such elements
|
|
13
|
+
* it sits at the editor's right edge, aligned to the block's top.
|
|
10
14
|
*/
|
|
11
15
|
export declare function BlockActionsOverlay({ editor, target, actions, host, onHover }: {
|
|
12
16
|
editor: Editor;
|
|
@@ -2,17 +2,23 @@ import { Icon } from "../../../react/Icon.js";
|
|
|
2
2
|
import { Button } from "../../../react/ui/button.js";
|
|
3
3
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../../../react/ui/tooltip.js";
|
|
4
4
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "../../../react/ui/dropdown-menu.js";
|
|
5
|
-
import { blockActionsFor, effectiveTarget } from "../block-actions.js";
|
|
5
|
+
import { blockActionsFor, blockCornerOf, effectiveTarget } from "../block-actions.js";
|
|
6
6
|
import { useEffect, useLayoutEffect, useReducer, useRef, useState } from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/features/block-ui/react/BlockActionsOverlay.tsx
|
|
9
9
|
/** Gap between the bar and the editor's right edge. */
|
|
10
10
|
const EDGE_GUTTER = 8;
|
|
11
|
+
/** Gap between the bar and the block's own corner elements it docks next to. */
|
|
12
|
+
const CORNER_GAP = 4;
|
|
11
13
|
/**
|
|
12
14
|
* The hover actions of a block, right-aligned at the editor's text column (the drag handle sits on the block's left and
|
|
13
15
|
* targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite
|
|
14
16
|
* chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is
|
|
15
17
|
* read-only. `menu` actions open a dropdown of their items instead of running on click.
|
|
18
|
+
*
|
|
19
|
+
* A block that shows icons of its own in its top-right corner marks them with `data-block-corner` (`BLOCK_CORNER_ATTR`):
|
|
20
|
+
* the bar then docks immediately left of them, centred on their row, instead of covering them. Without such elements
|
|
21
|
+
* it sits at the editor's right edge, aligned to the block's top.
|
|
16
22
|
*/
|
|
17
23
|
function BlockActionsOverlay({ editor, target, actions, host, onHover }) {
|
|
18
24
|
const [, rerender] = useReducer((count) => count + 1, 0);
|
|
@@ -35,19 +41,35 @@ function BlockActionsOverlay({ editor, target, actions, host, onHover }) {
|
|
|
35
41
|
})();
|
|
36
42
|
const items = block && editor.isEditable ? blockActionsFor(editor, block, actions) : [];
|
|
37
43
|
const [place, setPlace] = useState(null);
|
|
44
|
+
const resizeObserver = useRef(null);
|
|
45
|
+
const watched = useRef([]);
|
|
46
|
+
const watchCorner = (elements) => {
|
|
47
|
+
const current = watched.current;
|
|
48
|
+
if (elements.length === current.length && elements.every((element, index) => element === current[index])) return;
|
|
49
|
+
for (const element of current) resizeObserver.current?.unobserve(element);
|
|
50
|
+
watched.current = elements;
|
|
51
|
+
for (const element of elements) resizeObserver.current?.observe(element);
|
|
52
|
+
};
|
|
38
53
|
const measure = () => {
|
|
39
54
|
const dom = block && host && !editor.isDestroyed ? editor.view.nodeDOM(block.pos) : null;
|
|
40
55
|
if (!(dom instanceof HTMLElement) || !host) {
|
|
56
|
+
watchCorner([]);
|
|
41
57
|
setPlace(null);
|
|
42
58
|
return;
|
|
43
59
|
}
|
|
44
60
|
const hostRect = host.getBoundingClientRect();
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
top,
|
|
49
|
-
right
|
|
50
|
-
|
|
61
|
+
const corner = blockCornerOf(dom);
|
|
62
|
+
watchCorner(corner?.elements ?? []);
|
|
63
|
+
const next = corner ? {
|
|
64
|
+
top: corner.centerY - hostRect.top,
|
|
65
|
+
right: hostRect.right - corner.left + CORNER_GAP,
|
|
66
|
+
docked: true
|
|
67
|
+
} : {
|
|
68
|
+
top: dom.getBoundingClientRect().top - hostRect.top + 2,
|
|
69
|
+
right: hostRect.right - editor.view.dom.getBoundingClientRect().right + EDGE_GUTTER,
|
|
70
|
+
docked: false
|
|
71
|
+
};
|
|
72
|
+
setPlace((previous) => previous && previous.top === next.top && previous.right === next.right && previous.docked === next.docked ? previous : next);
|
|
51
73
|
};
|
|
52
74
|
useLayoutEffect(measure);
|
|
53
75
|
const visible = editor.isEditable && items.length > 0 && place !== null;
|
|
@@ -57,12 +79,15 @@ function BlockActionsOverlay({ editor, target, actions, host, onHover }) {
|
|
|
57
79
|
const run = () => latestMeasure.current();
|
|
58
80
|
window.addEventListener("resize", run);
|
|
59
81
|
window.addEventListener("scroll", run, true);
|
|
60
|
-
const
|
|
61
|
-
resizeObserver.
|
|
82
|
+
const observer = new ResizeObserver(run);
|
|
83
|
+
resizeObserver.current = observer;
|
|
84
|
+
observer.observe(editor.view.dom);
|
|
85
|
+
for (const element of watched.current) observer.observe(element);
|
|
62
86
|
return () => {
|
|
63
87
|
window.removeEventListener("resize", run);
|
|
64
88
|
window.removeEventListener("scroll", run, true);
|
|
65
|
-
|
|
89
|
+
observer.disconnect();
|
|
90
|
+
resizeObserver.current = null;
|
|
66
91
|
};
|
|
67
92
|
}, [editor]);
|
|
68
93
|
const root = useRef(null);
|
|
@@ -82,10 +107,11 @@ function BlockActionsOverlay({ editor, target, actions, host, onHover }) {
|
|
|
82
107
|
if (!visible || !place) return null;
|
|
83
108
|
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx("div", {
|
|
84
109
|
ref: root,
|
|
85
|
-
className: "block-actions absolute z-10 flex gap-0.5 rounded-md
|
|
110
|
+
className: "block-actions absolute z-10 flex gap-0.5 rounded-md bg-background p-0.5",
|
|
86
111
|
style: {
|
|
87
112
|
top: `${place.top}px`,
|
|
88
|
-
right: `${place.right}px
|
|
113
|
+
right: `${place.right}px`,
|
|
114
|
+
transform: place.docked ? "translateY(-50%)" : void 0
|
|
89
115
|
},
|
|
90
116
|
onMouseEnter: () => onHover(true),
|
|
91
117
|
onMouseLeave: () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockActionsOverlay.js","names":[],"sources":["../../../../src/features/block-ui/react/BlockActionsOverlay.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useEffect, useLayoutEffect, useReducer, useRef, useState } from 'react'\nimport type { BlockAction, BlockTarget, MenuItem } from '../../../core'\nimport { Icon } from '../../../react/Icon'\nimport { Button } from '../../../react/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '../../../react/ui/dropdown-menu'\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../../react/ui/tooltip'\nimport { blockActionsFor, effectiveTarget } from '../block-actions'\n\n/** Gap between the bar and the editor's right edge. */\nconst EDGE_GUTTER = 8\n\n/**\n * The hover actions of a block, right-aligned at the editor's text column (the drag handle sits on the block's left and\n * targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite\n * chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is\n * read-only. `menu` actions open a dropdown of their items instead of running on click.\n */\nexport function BlockActionsOverlay({ editor, target, actions, host, onHover }: {\n editor: Editor\n target: BlockTarget | null\n actions: readonly BlockAction[]\n host: HTMLElement | null\n onHover: (hovered: boolean) => void\n}) {\n // The document and `isEditable` change with transactions (`setEditable` dispatches one too): render on each.\n const [, rerender] = useReducer((count: number) => count + 1, 0)\n useEffect(() => {\n editor.on('transaction', rerender)\n return () => { editor.off('transaction', rerender) }\n }, [editor])\n\n // The target in the current document; null once its position holds something else (deleted, replaced).\n const block = ((): BlockTarget | null => {\n if (!target || editor.isDestroyed) return null\n const { doc } = editor.state\n if (target.pos < 0 || target.pos >= doc.content.size) return null\n const node = doc.nodeAt(target.pos)\n if (!node || node.type !== target.node.type) return null\n return effectiveTarget(editor, { node, pos: target.pos })\n })()\n const items = block && editor.isEditable ? blockActionsFor(editor, block, actions) : []\n\n const [place, setPlace] = useState<{ top: number, right: number } | null>(null)\n const measure = () => {\n const dom = block && host && !editor.isDestroyed ? editor.view.nodeDOM(block.pos) : null\n if (!(dom instanceof HTMLElement) || !host) {\n setPlace(null)\n return\n }\n const hostRect = host.getBoundingClientRect()\n const rect = dom.getBoundingClientRect()\n const top = rect.top - hostRect.top + 2\n const right = hostRect.right - editor.view.dom.getBoundingClientRect().right + EDGE_GUTTER\n setPlace(previous => (previous && previous.top === top && previous.right === right ? previous : { top, right }))\n }\n // After every render: the block, the document or the layout may have moved it. Equal positions bail out of the state update.\n useLayoutEffect(measure)\n\n const visible = editor.isEditable && items.length > 0 && place !== null\n\n // The bar follows the editor's right edge when the column resizes without the window doing so.\n const latestMeasure = useRef(measure)\n latestMeasure.current = measure\n useEffect(() => {\n const run = () => latestMeasure.current()\n window.addEventListener('resize', run)\n window.addEventListener('scroll', run, true)\n const resizeObserver = new ResizeObserver(run)\n resizeObserver.observe(editor.view.dom)\n return () => {\n window.removeEventListener('resize', run)\n window.removeEventListener('scroll', run, true)\n resizeObserver.disconnect()\n }\n }, [editor])\n\n // An open action menu is rendered outside the overlay (portal): the overlay counts as hovered until the menu closes.\n const root = useRef<HTMLDivElement>(null)\n const menuOpen = useRef(false)\n const onMenuOpenChange = (open: boolean) => {\n menuOpen.current = open\n onHover(open || !!root.current?.matches(':hover'))\n }\n\n // A vanishing overlay sends no mouseleave: report it, so the host does not keep waiting for one.\n const wasVisible = useRef(false)\n useEffect(() => {\n if (wasVisible.current && !visible) {\n menuOpen.current = false\n onHover(false)\n }\n wasVisible.current = visible\n }, [visible, onHover])\n\n if (!visible || !place) return null\n return (\n <TooltipProvider>\n <div\n ref={root}\n className=\"block-actions absolute z-10 flex gap-0.5 rounded-md border border-border bg-background p-0.5 shadow-sm\"\n style={{ top: `${place.top}px`, right: `${place.right}px` }}\n onMouseEnter={() => onHover(true)}\n onMouseLeave={() => { if (!menuOpen.current) onHover(false) }}\n >\n {items.map((entry) => {\n const button = (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={entry.action.label}\n onMouseDown={event => event.preventDefault()}\n onClick={entry.menu ? undefined : () => entry.action.run?.(entry.ctx)}\n >\n <Icon name={entry.action.icon} />\n </Button>\n )\n if (!entry.menu) {\n return (\n <Tooltip key={entry.action.id}>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent>{entry.action.label}</TooltipContent>\n </Tooltip>\n )\n }\n return (\n <DropdownMenu key={entry.action.id} onOpenChange={onMenuOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>{button}</DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent>{entry.action.label}</TooltipContent>\n </Tooltip>\n <DropdownMenuContent align=\"end\">\n {entry.menu.map((item, index) => <MenuRow key={index} item={item} />)}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n })}\n </div>\n </TooltipProvider>\n )\n}\n\nfunction MenuRow({ item }: { item: MenuItem }) {\n if (item.type === 'label') return <DropdownMenuLabel>{item.label}</DropdownMenuLabel>\n if (item.type === 'separator') return <DropdownMenuSeparator />\n return (\n <DropdownMenuItem disabled={item.disabled} onSelect={() => item.onSelect?.()}>\n {item.icon && <Icon name={item.icon} />}\n <span>{item.label}</span>\n {item.description && <span className=\"ml-auto text-xs text-muted-foreground\">{item.description}</span>}\n </DropdownMenuItem>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BlockActionsOverlay.js","names":[],"sources":["../../../../src/features/block-ui/react/BlockActionsOverlay.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useEffect, useLayoutEffect, useReducer, useRef, useState } from 'react'\nimport type { BlockAction, BlockTarget, MenuItem } from '../../../core'\nimport { Icon } from '../../../react/Icon'\nimport { Button } from '../../../react/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '../../../react/ui/dropdown-menu'\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../../react/ui/tooltip'\nimport { blockActionsFor, blockCornerOf, effectiveTarget } from '../block-actions'\n\n/** Gap between the bar and the editor's right edge. */\nconst EDGE_GUTTER = 8\n/** Gap between the bar and the block's own corner elements it docks next to. */\nconst CORNER_GAP = 4\n\n/**\n * The hover actions of a block, right-aligned at the editor's text column (the drag handle sits on the block's left and\n * targets the same block). Positioned absolutely inside `host`, a `relative` element around the editor; the composite\n * chrome (title, description, tags) addresses the composite (`effectiveTarget`). The bar is hidden while the editor is\n * read-only. `menu` actions open a dropdown of their items instead of running on click.\n *\n * A block that shows icons of its own in its top-right corner marks them with `data-block-corner` (`BLOCK_CORNER_ATTR`):\n * the bar then docks immediately left of them, centred on their row, instead of covering them. Without such elements\n * it sits at the editor's right edge, aligned to the block's top.\n */\nexport function BlockActionsOverlay({ editor, target, actions, host, onHover }: {\n editor: Editor\n target: BlockTarget | null\n actions: readonly BlockAction[]\n host: HTMLElement | null\n onHover: (hovered: boolean) => void\n}) {\n // The document and `isEditable` change with transactions (`setEditable` dispatches one too): render on each.\n const [, rerender] = useReducer((count: number) => count + 1, 0)\n useEffect(() => {\n editor.on('transaction', rerender)\n return () => { editor.off('transaction', rerender) }\n }, [editor])\n\n // The target in the current document; null once its position holds something else (deleted, replaced).\n const block = ((): BlockTarget | null => {\n if (!target || editor.isDestroyed) return null\n const { doc } = editor.state\n if (target.pos < 0 || target.pos >= doc.content.size) return null\n const node = doc.nodeAt(target.pos)\n if (!node || node.type !== target.node.type) return null\n return effectiveTarget(editor, { node, pos: target.pos })\n })()\n const items = block && editor.isEditable ? blockActionsFor(editor, block, actions) : []\n\n // `docked`: the bar sits next to the block's corner elements, and `top` is then their vertical centre.\n const [place, setPlace] = useState<{ top: number, right: number, docked: boolean } | null>(null)\n const resizeObserver = useRef<ResizeObserver | null>(null)\n const watched = useRef<HTMLElement[]>([])\n // The corner elements can change size (a badge appears) without the document changing: watch the current ones.\n const watchCorner = (elements: HTMLElement[]) => {\n const current = watched.current\n if (elements.length === current.length && elements.every((element, index) => element === current[index])) return\n for (const element of current) resizeObserver.current?.unobserve(element)\n watched.current = elements\n for (const element of elements) resizeObserver.current?.observe(element)\n }\n const measure = () => {\n const dom = block && host && !editor.isDestroyed ? editor.view.nodeDOM(block.pos) : null\n if (!(dom instanceof HTMLElement) || !host) {\n watchCorner([])\n setPlace(null)\n return\n }\n const hostRect = host.getBoundingClientRect()\n const corner = blockCornerOf(dom)\n watchCorner(corner?.elements ?? [])\n const next = corner\n ? { top: corner.centerY - hostRect.top, right: hostRect.right - corner.left + CORNER_GAP, docked: true }\n : {\n top: dom.getBoundingClientRect().top - hostRect.top + 2,\n right: hostRect.right - editor.view.dom.getBoundingClientRect().right + EDGE_GUTTER,\n docked: false,\n }\n setPlace(previous => (previous && previous.top === next.top && previous.right === next.right && previous.docked === next.docked ? previous : next))\n }\n // After every render: the block, the document or the layout may have moved it. Equal positions bail out of the state update.\n useLayoutEffect(measure)\n\n const visible = editor.isEditable && items.length > 0 && place !== null\n\n // The bar follows the editor's right edge when the column resizes without the window doing so.\n const latestMeasure = useRef(measure)\n latestMeasure.current = measure\n useEffect(() => {\n const run = () => latestMeasure.current()\n window.addEventListener('resize', run)\n window.addEventListener('scroll', run, true)\n const observer = new ResizeObserver(run)\n resizeObserver.current = observer\n observer.observe(editor.view.dom)\n for (const element of watched.current) observer.observe(element)\n return () => {\n window.removeEventListener('resize', run)\n window.removeEventListener('scroll', run, true)\n observer.disconnect()\n resizeObserver.current = null\n }\n }, [editor])\n\n // An open action menu is rendered outside the overlay (portal): the overlay counts as hovered until the menu closes.\n const root = useRef<HTMLDivElement>(null)\n const menuOpen = useRef(false)\n const onMenuOpenChange = (open: boolean) => {\n menuOpen.current = open\n onHover(open || !!root.current?.matches(':hover'))\n }\n\n // A vanishing overlay sends no mouseleave: report it, so the host does not keep waiting for one.\n const wasVisible = useRef(false)\n useEffect(() => {\n if (wasVisible.current && !visible) {\n menuOpen.current = false\n onHover(false)\n }\n wasVisible.current = visible\n }, [visible, onHover])\n\n if (!visible || !place) return null\n return (\n <TooltipProvider>\n <div\n ref={root}\n className=\"block-actions absolute z-10 flex gap-0.5 rounded-md bg-background p-0.5\"\n style={{ top: `${place.top}px`, right: `${place.right}px`, transform: place.docked ? 'translateY(-50%)' : undefined }}\n onMouseEnter={() => onHover(true)}\n onMouseLeave={() => { if (!menuOpen.current) onHover(false) }}\n >\n {items.map((entry) => {\n const button = (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={entry.action.label}\n onMouseDown={event => event.preventDefault()}\n onClick={entry.menu ? undefined : () => entry.action.run?.(entry.ctx)}\n >\n <Icon name={entry.action.icon} />\n </Button>\n )\n if (!entry.menu) {\n return (\n <Tooltip key={entry.action.id}>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent>{entry.action.label}</TooltipContent>\n </Tooltip>\n )\n }\n return (\n <DropdownMenu key={entry.action.id} onOpenChange={onMenuOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>{button}</DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent>{entry.action.label}</TooltipContent>\n </Tooltip>\n <DropdownMenuContent align=\"end\">\n {entry.menu.map((item, index) => <MenuRow key={index} item={item} />)}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n })}\n </div>\n </TooltipProvider>\n )\n}\n\nfunction MenuRow({ item }: { item: MenuItem }) {\n if (item.type === 'label') return <DropdownMenuLabel>{item.label}</DropdownMenuLabel>\n if (item.type === 'separator') return <DropdownMenuSeparator />\n return (\n <DropdownMenuItem disabled={item.disabled} onSelect={() => item.onSelect?.()}>\n {item.icon && <Icon name={item.icon} />}\n <span>{item.label}</span>\n {item.description && <span className=\"ml-auto text-xs text-muted-foreground\">{item.description}</span>}\n </DropdownMenuItem>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isChromeNode } from "../../../core/schema/node-flags.js";
|
|
2
1
|
import { editorEntryOf } from "../../../core/editor-ui.js";
|
|
2
|
+
import { isChromeNode } from "../../../core/schema/node-flags.js";
|
|
3
3
|
import { cn } from "../../../react/ui/utils.js";
|
|
4
4
|
import { Icon } from "../../../react/Icon.js";
|
|
5
5
|
import { useEditorSettings } from "../../../react/settings.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, ySyncPluginKey, yUndoPluginKey } from "@tiptap/y-tiptap";
|
|
2
1
|
import * as Y from "yjs";
|
|
2
|
+
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, ySyncPluginKey, yUndoPluginKey } from "@tiptap/y-tiptap";
|
|
3
3
|
//#region src/features/collab/anchor-resolver.ts
|
|
4
4
|
const positionMappings = /* @__PURE__ */ new WeakMap();
|
|
5
5
|
/**
|
|
@@ -15,6 +15,8 @@ import { CollaborationCaret } from "@tiptap/extension-collaboration-caret";
|
|
|
15
15
|
function collabFeatureCore(ui = {}) {
|
|
16
16
|
return {
|
|
17
17
|
id: "collab",
|
|
18
|
+
dimension: "interaction",
|
|
19
|
+
backend: ["collaboration"],
|
|
18
20
|
anchorResolver: () => yjsAnchorResolver,
|
|
19
21
|
extensions: ({ collaboration }) => {
|
|
20
22
|
if (!collaboration) return [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/collab/feature.ts"],"sourcesContent":["import type { AnyExtension } from '@tiptap/core'\nimport { Collaboration } from '@tiptap/extension-collaboration'\nimport { CollaborationCaret } from '@tiptap/extension-collaboration-caret'\nimport type { EditorFeature } from '../../core'\nimport { yjsAnchorResolver } from './anchor-resolver'\n\n/** What a framework binding supplies to the collab feature. */\nexport interface CollabUi {\n /** Extensions added before `Collaboration` while a session exists (framework state-sync plugins). */\n extensions?: AnyExtension[]\n}\n\n/**\n * Real-time collaboration through Yjs. Active only with a session on the surface (`collaboration` prop): the Y.Doc\n * is then the document (`Collaboration`, which brings the per-user undo/redo; core turns its own history off), and a\n * provider adds remote carets (`CollaborationCaret`, labelled with the session's `user`). Without a session the\n * feature contributes no extensions, so the editor behaves like a standalone one. It also supplies `DocAnchors` with\n * the Yjs-backed `AnchorResolver`, so anchored ranges (AI reviews, ghost text, chat ops) survive concurrent edits.\n *\n * Pairs with the server of `@ecsplico/editor/nuxt` (or any Hocuspocus server on the matching advanced schema).\n * A surface given a `collaboration` session requires this feature and throws otherwise.\n */\nexport function collabFeatureCore(ui: CollabUi = {}): EditorFeature<never> {\n return {\n id: 'collab',\n anchorResolver: () => yjsAnchorResolver,\n extensions: ({ collaboration }) => {\n if (!collaboration) return []\n if (collaboration.token !== undefined && collaboration.provider) collaboration.provider.configuration.token = collaboration.token\n return [\n ...(ui.extensions ?? []),\n Collaboration.configure({ document: collaboration.ydoc }),\n ...(collaboration.provider\n ? [CollaborationCaret.configure({ provider: collaboration.provider, ...(collaboration.user && { user: collaboration.user }) })]\n : []),\n ]\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,SAAgB,kBAAkB,KAAe,CAAC,GAAyB;CACzE,OAAO;EACL,IAAI;EACJ,sBAAsB;EACtB,aAAa,EAAE,oBAAoB;GACjC,IAAI,CAAC,eAAe,OAAO,CAAC;GAC5B,IAAI,cAAc,UAAU,KAAA,KAAa,cAAc,UAAU,cAAc,SAAS,cAAc,QAAQ,cAAc;GAC5H,OAAO;IACL,GAAI,GAAG,cAAc,CAAC;IACtB,cAAc,UAAU,EAAE,UAAU,cAAc,KAAK,CAAC;IACxD,GAAI,cAAc,WACd,CAAC,mBAAmB,UAAU;KAAE,UAAU,cAAc;KAAU,GAAI,cAAc,QAAQ,EAAE,MAAM,cAAc,KAAK;IAAG,CAAC,CAAC,IAC5H,CAAC;GACP;EACF;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"feature.js","names":[],"sources":["../../../src/features/collab/feature.ts"],"sourcesContent":["import type { AnyExtension } from '@tiptap/core'\nimport { Collaboration } from '@tiptap/extension-collaboration'\nimport { CollaborationCaret } from '@tiptap/extension-collaboration-caret'\nimport type { EditorFeature } from '../../core'\nimport { yjsAnchorResolver } from './anchor-resolver'\n\n/** What a framework binding supplies to the collab feature. */\nexport interface CollabUi {\n /** Extensions added before `Collaboration` while a session exists (framework state-sync plugins). */\n extensions?: AnyExtension[]\n}\n\n/**\n * Real-time collaboration through Yjs. Active only with a session on the surface (`collaboration` prop): the Y.Doc\n * is then the document (`Collaboration`, which brings the per-user undo/redo; core turns its own history off), and a\n * provider adds remote carets (`CollaborationCaret`, labelled with the session's `user`). Without a session the\n * feature contributes no extensions, so the editor behaves like a standalone one. It also supplies `DocAnchors` with\n * the Yjs-backed `AnchorResolver`, so anchored ranges (AI reviews, ghost text, chat ops) survive concurrent edits.\n *\n * Pairs with the server of `@ecsplico/editor/nuxt` (or any Hocuspocus server on the matching advanced schema).\n * A surface given a `collaboration` session requires this feature and throws otherwise.\n */\nexport function collabFeatureCore(ui: CollabUi = {}): EditorFeature<never> {\n return {\n id: 'collab',\n dimension: 'interaction',\n backend: ['collaboration'],\n anchorResolver: () => yjsAnchorResolver,\n extensions: ({ collaboration }) => {\n if (!collaboration) return []\n if (collaboration.token !== undefined && collaboration.provider) collaboration.provider.configuration.token = collaboration.token\n return [\n ...(ui.extensions ?? []),\n Collaboration.configure({ document: collaboration.ydoc }),\n ...(collaboration.provider\n ? [CollaborationCaret.configure({ provider: collaboration.provider, ...(collaboration.user && { user: collaboration.user }) })]\n : []),\n ]\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,SAAgB,kBAAkB,KAAe,CAAC,GAAyB;CACzE,OAAO;EACL,IAAI;EACJ,WAAW;EACX,SAAS,CAAC,eAAe;EACzB,sBAAsB;EACtB,aAAa,EAAE,oBAAoB;GACjC,IAAI,CAAC,eAAe,OAAO,CAAC;GAC5B,IAAI,cAAc,UAAU,KAAA,KAAa,cAAc,UAAU,cAAc,SAAS,cAAc,QAAQ,cAAc;GAC5H,OAAO;IACL,GAAI,GAAG,cAAc,CAAC;IACtB,cAAc,UAAU,EAAE,UAAU,cAAc,KAAK,CAAC;IACxD,GAAI,cAAc,WACd,CAAC,mBAAmB,UAAU;KAAE,UAAU,cAAc;KAAU,GAAI,cAAc,QAAQ,EAAE,MAAM,cAAc,KAAK;IAAG,CAAC,CAAC,IAC5H,CAAC;GACP;EACF;CACF;AACF"}
|