@formicoidea/labre-core 0.41.0 → 0.42.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/LICENSE +384 -0
- package/dist/_pkgs/affine-block-bookmark/bookmark-block.js +2 -2
- package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.js +7 -1
- package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-block.js +2 -1
- package/dist/_pkgs/affine-block-embed/embed-github-block/embed-github-block.js +2 -1
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.d.ts +2 -0
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.js +5 -0
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.d.ts +1 -0
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.js +30 -8
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/utils.d.ts +8 -0
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/utils.js +19 -0
- package/dist/_pkgs/affine-block-embed/embed-loom-block/embed-loom-block.js +2 -1
- package/dist/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-block.js +2 -1
- package/dist/_pkgs/affine-block-frame/frame-manager.js +1 -1
- package/dist/_pkgs/affine-block-frame/frame-tool.js +1 -1
- package/dist/_pkgs/affine-block-frame/frame-toolbar.js +6 -1
- package/dist/_pkgs/affine-block-list/list-keymap.js +7 -0
- package/dist/_pkgs/affine-block-note/note-keymap.js +7 -1
- package/dist/_pkgs/affine-block-paragraph/paragraph-keymap.js +7 -1
- package/dist/_pkgs/affine-block-root/commands/pivot-commands.js +1 -8
- package/dist/_pkgs/affine-block-root/commands/tag-commands.js +1 -8
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.d.ts +9 -0
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.js +51 -0
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.d.ts +22 -0
- package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.js +46 -0
- package/dist/_pkgs/affine-block-root/edgeless/utils/pinch-zoom.d.ts +21 -0
- package/dist/_pkgs/affine-block-root/edgeless/utils/pinch-zoom.js +24 -0
- package/dist/_pkgs/affine-block-root/edgeless/utils/query.js +8 -0
- package/dist/_pkgs/affine-block-root/keyboard/keymap.js +1 -16
- package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +21 -3
- package/dist/_pkgs/affine-block-surface/element-model/index.js +14 -2
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.d.ts +23 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.js +89 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.d.ts +7 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.js +5 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.d.ts +41 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.js +70 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.d.ts +49 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.js +257 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/tagged-path.d.ts +16 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/tagged-path.js +24 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.d.ts +24 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.js +66 -0
- package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +4 -0
- package/dist/_pkgs/affine-block-surface/extensions/index.js +4 -0
- package/dist/_pkgs/affine-block-surface/extensions/interchange-import.d.ts +66 -4
- package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +241 -11
- package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +18 -0
- package/dist/_pkgs/affine-block-surface/extensions/legend-toolbar.d.ts +81 -0
- package/dist/_pkgs/affine-block-surface/extensions/legend-toolbar.js +81 -0
- package/dist/_pkgs/affine-block-surface/extensions/legend.d.ts +136 -0
- package/dist/_pkgs/affine-block-surface/extensions/legend.js +439 -0
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.d.ts +17 -3
- package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +35 -13
- package/dist/_pkgs/affine-block-surface/extensions/reading.d.ts +61 -1
- package/dist/_pkgs/affine-block-surface/extensions/reading.js +85 -39
- package/dist/_pkgs/affine-block-surface/extensions/record-action.d.ts +66 -0
- package/dist/_pkgs/affine-block-surface/extensions/record-action.js +145 -0
- package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +253 -28
- package/dist/_pkgs/affine-block-surface/extensions/validation.js +489 -41
- package/dist/_pkgs/affine-block-surface/framework-background/background-view.d.ts +115 -0
- package/dist/_pkgs/affine-block-surface/framework-background/background-view.js +185 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/framework-background/labels.d.ts +16 -1
- package/dist/_pkgs/affine-block-surface/framework-background/labels.js +31 -21
- package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +29 -5
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.d.ts +6 -4
- package/dist/_pkgs/affine-block-surface/framework-background/stacking.js +56 -8
- package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.d.ts +12 -0
- package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.js +15 -0
- package/dist/_pkgs/affine-block-surface/view.js +8 -1
- package/dist/_pkgs/affine-block-surface-ref/configs/slash-menu.js +1 -1
- package/dist/_pkgs/affine-components/color-picker/button.d.ts +56 -1
- package/dist/_pkgs/affine-components/color-picker/button.js +168 -23
- package/dist/_pkgs/affine-components/color-picker/framework-palette.d.ts +106 -0
- package/dist/_pkgs/affine-components/color-picker/framework-palette.js +177 -0
- package/dist/_pkgs/affine-components/color-picker/index.d.ts +2 -0
- package/dist/_pkgs/affine-components/color-picker/index.js +2 -0
- package/dist/_pkgs/affine-components/color-picker/palette-carousel.d.ts +85 -0
- package/dist/_pkgs/affine-components/color-picker/palette-carousel.js +440 -0
- package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.d.ts +31 -1
- package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.js +189 -63
- package/dist/_pkgs/affine-components/resource/resource.js +29 -16
- package/dist/_pkgs/affine-components/translations.d.ts +8 -0
- package/dist/_pkgs/affine-components/translations.js +17 -0
- package/dist/_pkgs/affine-foundation/view.js +2 -1
- package/dist/_pkgs/affine-gfx-brush/element-renderer.js +2 -2
- package/dist/_pkgs/affine-gfx-brush/toolbar/configs/brush.js +6 -1
- package/dist/_pkgs/affine-gfx-brush/toolbar/configs/highlighter.js +6 -1
- package/dist/_pkgs/affine-gfx-connector/connector-manager.d.ts +9 -1
- package/dist/_pkgs/affine-gfx-connector/connector-manager.js +61 -0
- package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.d.ts +7 -1
- package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.js +87 -17
- package/dist/_pkgs/affine-gfx-connector/element-renderer/index.js +78 -17
- package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.d.ts +24 -2
- package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.js +31 -8
- package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.d.ts +124 -3
- package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.js +216 -54
- package/dist/_pkgs/affine-gfx-connector/text/text.d.ts +13 -4
- package/dist/_pkgs/affine-gfx-connector/text/text.js +13 -44
- package/dist/_pkgs/affine-gfx-connector/toolbar/config.d.ts +56 -0
- package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +72 -4
- package/dist/_pkgs/affine-gfx-connector/toolbar/hollow-endpoint-icons.d.ts +8 -0
- package/dist/_pkgs/affine-gfx-connector/toolbar/hollow-endpoint-icons.js +118 -0
- package/dist/_pkgs/affine-gfx-connector/view/view.d.ts +37 -1
- package/dist/_pkgs/affine-gfx-connector/view/view.js +97 -8
- package/dist/_pkgs/affine-gfx-group/command/group-api.js +1 -1
- package/dist/_pkgs/affine-gfx-group/store.js +0 -2
- package/dist/_pkgs/affine-gfx-group/translations.d.ts +9 -10
- package/dist/_pkgs/affine-gfx-group/translations.js +9 -13
- package/dist/_pkgs/affine-gfx-mindmap/templates/index.js +1 -1
- package/dist/_pkgs/affine-gfx-mindmap/toolbar/basket-elements.js +1 -1
- package/dist/_pkgs/affine-gfx-mindmap/toolbar/utils/import-mindmap.js +2 -2
- package/dist/_pkgs/affine-gfx-mindmap/translations.d.ts +1 -1
- package/dist/_pkgs/affine-gfx-mindmap/translations.js +1 -1
- package/dist/_pkgs/affine-gfx-shape/element-renderer/highlighter.js +2 -2
- package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.d.ts +6 -0
- package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.js +30 -1
- package/dist/_pkgs/affine-gfx-shape/polygon-tool.d.ts +20 -1
- package/dist/_pkgs/affine-gfx-shape/polygon-tool.js +9 -1
- package/dist/_pkgs/affine-gfx-shape/toolbar/config.js +6 -1
- package/dist/_pkgs/affine-gfx-shape/toolbar/palette-color-action.js +11 -1
- package/dist/_pkgs/affine-gfx-template/builtin/other.js +1 -1
- package/dist/_pkgs/affine-gfx-template/snapshot-from-action.js +32 -119
- package/dist/_pkgs/affine-gfx-template/toolbar/template-type.d.ts +1 -1
- package/dist/_pkgs/affine-gfx-text/dblclick-add-edgeless-text.d.ts +13 -1
- package/dist/_pkgs/affine-gfx-text/dblclick-add-edgeless-text.js +19 -4
- package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.d.ts +41 -0
- package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +57 -2
- package/dist/_pkgs/affine-gfx-text/toolbar/actions.d.ts +8 -1
- package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +12 -2
- package/dist/_pkgs/affine-gfx-text/translations.d.ts +1 -0
- package/dist/_pkgs/affine-gfx-text/translations.js +2 -1
- package/dist/_pkgs/affine-inline-preset/markdown.js +5 -1
- package/dist/_pkgs/affine-model/consts/connector.d.ts +28 -2
- package/dist/_pkgs/affine-model/consts/connector.js +26 -0
- package/dist/_pkgs/affine-model/elements/bpmn/pool.js +1 -1
- package/dist/_pkgs/affine-model/elements/brush/brush.js +1 -1
- package/dist/_pkgs/affine-model/elements/c4/board.js +1 -1
- package/dist/_pkgs/affine-model/elements/c4/boundary.js +1 -1
- package/dist/_pkgs/affine-model/elements/connector/connector.d.ts +135 -0
- package/dist/_pkgs/affine-model/elements/connector/connector.js +246 -5
- package/dist/_pkgs/affine-model/elements/connector/end-label.d.ts +83 -0
- package/dist/_pkgs/affine-model/elements/connector/end-label.js +119 -0
- package/dist/_pkgs/affine-model/elements/connector/index.d.ts +1 -0
- package/dist/_pkgs/affine-model/elements/connector/index.js +1 -0
- package/dist/_pkgs/affine-model/elements/context-map/context-map.js +1 -1
- package/dist/_pkgs/affine-model/elements/core-domain/core-domain.d.ts +28 -0
- package/dist/_pkgs/affine-model/elements/core-domain/core-domain.js +129 -2
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.d.ts +8 -0
- package/dist/_pkgs/affine-model/elements/cynefin/cynefin.js +45 -2
- package/dist/_pkgs/affine-model/elements/edgy/board.js +1 -1
- package/dist/_pkgs/affine-model/elements/edgy/facets.js +1 -1
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.d.ts +6 -0
- package/dist/_pkgs/affine-model/elements/estuarine/estuarine.js +36 -2
- package/dist/_pkgs/affine-model/elements/event-storming/event-storming.d.ts +18 -7
- package/dist/_pkgs/affine-model/elements/event-storming/event-storming.js +23 -8
- package/dist/_pkgs/affine-model/elements/framework-background/background.d.ts +16 -0
- package/dist/_pkgs/affine-model/elements/framework-background/background.js +18 -0
- package/dist/_pkgs/affine-model/elements/highlighter/highlighter.js +1 -1
- package/dist/_pkgs/affine-model/elements/index.d.ts +8 -0
- package/dist/_pkgs/affine-model/elements/index.js +1 -0
- package/dist/_pkgs/affine-model/elements/shape/shape.js +1 -1
- package/dist/_pkgs/affine-model/elements/text/text.js +1 -1
- package/dist/_pkgs/affine-model/elements/uml/band.d.ts +39 -0
- package/dist/_pkgs/affine-model/elements/uml/band.js +31 -0
- package/dist/_pkgs/affine-model/elements/uml/diagram.d.ts +158 -0
- package/dist/_pkgs/affine-model/elements/uml/diagram.js +229 -0
- package/dist/_pkgs/affine-model/elements/uml/fragment.d.ts +161 -0
- package/dist/_pkgs/affine-model/elements/uml/fragment.js +205 -0
- package/dist/_pkgs/affine-model/elements/uml/index.d.ts +8 -0
- package/dist/_pkgs/affine-model/elements/uml/index.js +8 -0
- package/dist/_pkgs/affine-model/elements/uml/lifeline.d.ts +77 -0
- package/dist/_pkgs/affine-model/elements/uml/lifeline.js +89 -0
- package/dist/_pkgs/affine-model/elements/uml/node.d.ts +142 -0
- package/dist/_pkgs/affine-model/elements/uml/node.js +190 -0
- package/dist/_pkgs/affine-model/elements/uml/partition.d.ts +106 -0
- package/dist/_pkgs/affine-model/elements/uml/partition.js +172 -0
- package/dist/_pkgs/affine-model/elements/uml/region.d.ts +75 -0
- package/dist/_pkgs/affine-model/elements/uml/region.js +150 -0
- package/dist/_pkgs/affine-model/elements/uml/subject.d.ts +37 -0
- package/dist/_pkgs/affine-model/elements/uml/subject.js +108 -0
- package/dist/_pkgs/affine-model/elements/wardley/wardley.js +1 -1
- package/dist/_pkgs/affine-shared/services/embed-iframe/embed-iframe-config.d.ts +1 -0
- package/dist/_pkgs/affine-shared/services/font-loader/config.d.ts +7 -0
- package/dist/_pkgs/affine-shared/services/font-loader/config.js +43 -0
- package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.js +1 -9
- package/dist/_pkgs/affine-shared/services/telemetry-service/document-damage-watcher.d.ts +53 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/document-damage-watcher.js +95 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/index.js +1 -0
- package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +26 -1
- package/dist/_pkgs/affine-shared/services/telemetry-service/telemetry-service.d.ts +2 -2
- package/dist/_pkgs/affine-shared/services/toolbar-service/command-action.d.ts +34 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/command-action.js +63 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/services/toolbar-service/index.js +1 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +77 -7
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +97 -7
- package/dist/_pkgs/affine-shared/styles/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/styles/index.js +1 -0
- package/dist/_pkgs/affine-shared/styles/motion.d.ts +14 -0
- package/dist/_pkgs/affine-shared/styles/motion.js +38 -0
- package/dist/_pkgs/affine-shared/utils/event.d.ts +10 -0
- package/dist/_pkgs/affine-shared/utils/event.js +20 -0
- package/dist/_pkgs/affine-shared/utils/file/filesys.d.ts +16 -0
- package/dist/_pkgs/affine-shared/utils/file/filesys.js +25 -0
- package/dist/_pkgs/affine-shared/utils/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/utils/index.js +1 -0
- package/dist/_pkgs/affine-shared/utils/link-preview-refresh.d.ts +12 -0
- package/dist/_pkgs/affine-shared/utils/link-preview-refresh.js +13 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.d.ts +12 -4
- package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.js +27 -4
- package/dist/_pkgs/affine-widget-edgeless-toolbar/create-popper.js +13 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +2 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +2 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.d.ts +80 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.js +270 -81
- package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/senior-menu-selection.d.ts +15 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/senior-menu-selection.js +15 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/panel/font-weight-and-style-panel.js +8 -1
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-ghost-overlay.d.ts +42 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-ghost-overlay.js +100 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-placement-tool.d.ts +100 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-placement-tool.js +274 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/index.d.ts +3 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/index.js +3 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/translate-created.d.ts +25 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/translate-created.js +67 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/view.js +5 -0
- package/dist/_pkgs/global/gfx/xywh.js +7 -0
- package/dist/_pkgs/std/extension/command-registry.d.ts +158 -1
- package/dist/_pkgs/std/extension/command-registry.js +22 -0
- package/dist/_pkgs/std/gfx/index.d.ts +1 -1
- package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.d.ts +12 -0
- package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.js +20 -1
- package/dist/_pkgs/std/gfx/interactivity/manager.d.ts +10 -0
- package/dist/_pkgs/std/gfx/interactivity/manager.js +12 -0
- package/dist/_pkgs/std/gfx/model/surface/element-model.js +12 -7
- package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +56 -0
- package/dist/_pkgs/std/gfx/model/surface/surface-model.js +84 -3
- package/dist/_pkgs/std/gfx/view/view.d.ts +11 -2
- package/dist/_pkgs/std/gfx/view/view.js +16 -2
- package/dist/commands.d.ts +6 -0
- package/dist/commands.js +8 -1
- package/dist/frameworks.d.ts +9 -0
- package/dist/frameworks.js +19 -0
- package/dist/translations.js +16 -0
- package/package.json +9 -4
- package/dist/_pkgs/affine-gfx-group/group-watcher.d.ts +0 -1
- package/dist/_pkgs/affine-gfx-group/group-watcher.js +0 -20
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { DomRenderer } from '../../../affine-block-surface/index.js';
|
|
2
|
-
import { type ConnectorElementModel } from '../../../affine-model/index.js';
|
|
2
|
+
import { type ConnectorElementModel, type PointStyle } from '../../../affine-model/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Exported for `src/__tests__/endpoint-style.unit.spec.ts`: the hollow heads are
|
|
5
|
+
* defined by the fact that `fill` and `stroke` differ, which is only observable
|
|
6
|
+
* on the marker node this builds.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createArrowMarker(id: string, style: PointStyle, color: string, strokeWidth: number, isStart?: boolean): SVGMarkerElement;
|
|
3
9
|
/**
|
|
4
10
|
* Renders a ConnectorElementModel to a given HTMLElement using DOM/SVG.
|
|
5
11
|
* This function is intended to be registered via the DomElementRendererExtension.
|
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import { ConnectorMode, DefaultTheme, } from '../../../affine-model/index.js';
|
|
2
2
|
import { PointLocation, SVGPathBuilder } from '../../../global/gfx/index.js';
|
|
3
3
|
import { isConnectorWithLabel } from '../../connector-manager.js';
|
|
4
|
-
import { DEFAULT_ARROW_SIZE } from '../utils.js';
|
|
4
|
+
import { DEFAULT_ARROW_SIZE, HOLLOW_HEAD_FILL } from '../utils.js';
|
|
5
5
|
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
6
|
+
/**
|
|
7
|
+
* The outline width of a hollow head, in the marker's own `viewBox` units.
|
|
8
|
+
*
|
|
9
|
+
* Pinned rather than inherited. A marker declares `markerUnits="strokeWidth"`
|
|
10
|
+
* and a `0 0 20 20` viewBox mapped onto `markerWidth`, so one viewBox unit is
|
|
11
|
+
* already a fixed fraction of the connector's `strokeWidth` — the outline
|
|
12
|
+
* scales with the line without this attribute existing, and `1` is exactly the
|
|
13
|
+
* SVG default the solid heads get implicitly today. Nothing changes visually.
|
|
14
|
+
*
|
|
15
|
+
* It is set only on the hollow heads because they are the only ones where the
|
|
16
|
+
* value is observable: a solid head paints `fill` and `stroke` in the same
|
|
17
|
+
* colour, so its outline is invisible either way. On a hollow head the outline
|
|
18
|
+
* IS the head. Leaving it to a default that a future `stroke-width` on the
|
|
19
|
+
* `<svg>`, the `<defs>`, or the marker itself would override means the UML
|
|
20
|
+
* heads could silently thicken or vanish; the solid twins would not notice.
|
|
21
|
+
*/
|
|
22
|
+
const HOLLOW_HEAD_STROKE_WIDTH = 1;
|
|
23
|
+
const LABEL_SLOTS = ['center', 'source', 'target'];
|
|
6
24
|
/**
|
|
7
25
|
* The nodes a connector host already owns, kept across renders. Rebuilding the
|
|
8
26
|
* whole `<svg>` subtree on every frame allocated one element per connector per
|
|
@@ -46,7 +64,12 @@ function createConnectorPath(points, mode) {
|
|
|
46
64
|
}
|
|
47
65
|
return pathBuilder.build();
|
|
48
66
|
}
|
|
49
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Exported for `src/__tests__/endpoint-style.unit.spec.ts`: the hollow heads are
|
|
69
|
+
* defined by the fact that `fill` and `stroke` differ, which is only observable
|
|
70
|
+
* on the marker node this builds.
|
|
71
|
+
*/
|
|
72
|
+
export function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
|
|
50
73
|
const marker = document.createElementNS(SVG_NS, 'marker');
|
|
51
74
|
const size = DEFAULT_ARROW_SIZE * (strokeWidth / 2);
|
|
52
75
|
marker.id = id;
|
|
@@ -57,6 +80,8 @@ function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
|
|
|
57
80
|
marker.setAttribute('markerHeight', String(size));
|
|
58
81
|
marker.setAttribute('orient', 'auto');
|
|
59
82
|
marker.setAttribute('markerUnits', 'strokeWidth');
|
|
83
|
+
// No `default`, as on the canvas side: an unknown persisted `PointStyle`
|
|
84
|
+
// yields an empty marker rather than a wrong head.
|
|
60
85
|
switch (style) {
|
|
61
86
|
case 'Arrow': {
|
|
62
87
|
const path = document.createElementNS(SVG_NS, 'path');
|
|
@@ -74,6 +99,15 @@ function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
|
|
|
74
99
|
marker.append(path);
|
|
75
100
|
break;
|
|
76
101
|
}
|
|
102
|
+
case 'TriangleHollow': {
|
|
103
|
+
const path = document.createElementNS(SVG_NS, 'path');
|
|
104
|
+
path.setAttribute('d', isStart ? 'M 20 7 L 12 10 L 20 13 Z' : 'M 0 7 L 8 10 L 0 13 Z');
|
|
105
|
+
path.setAttribute('fill', HOLLOW_HEAD_FILL);
|
|
106
|
+
path.setAttribute('stroke', color);
|
|
107
|
+
path.setAttribute('stroke-width', String(HOLLOW_HEAD_STROKE_WIDTH));
|
|
108
|
+
marker.append(path);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
77
111
|
case 'Circle': {
|
|
78
112
|
const circle = document.createElementNS(SVG_NS, 'circle');
|
|
79
113
|
circle.setAttribute('cx', '10');
|
|
@@ -92,6 +126,15 @@ function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
|
|
|
92
126
|
marker.append(path);
|
|
93
127
|
break;
|
|
94
128
|
}
|
|
129
|
+
case 'DiamondHollow': {
|
|
130
|
+
const path = document.createElementNS(SVG_NS, 'path');
|
|
131
|
+
path.setAttribute('d', 'M 10 6 L 14 10 L 10 14 L 6 10 Z');
|
|
132
|
+
path.setAttribute('fill', HOLLOW_HEAD_FILL);
|
|
133
|
+
path.setAttribute('stroke', color);
|
|
134
|
+
path.setAttribute('stroke-width', String(HOLLOW_HEAD_STROKE_WIDTH));
|
|
135
|
+
marker.append(path);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
95
138
|
}
|
|
96
139
|
return marker;
|
|
97
140
|
}
|
|
@@ -119,29 +162,53 @@ function getRetainedConnectorDom(element) {
|
|
|
119
162
|
svg,
|
|
120
163
|
defs,
|
|
121
164
|
path,
|
|
122
|
-
|
|
165
|
+
labels: {},
|
|
123
166
|
};
|
|
124
167
|
retainedConnectorDom.set(element, retained);
|
|
125
168
|
return retained;
|
|
126
169
|
}
|
|
127
|
-
function getOrCreateLabelElement(retained) {
|
|
128
|
-
|
|
129
|
-
|
|
170
|
+
function getOrCreateLabelElement(retained, slot) {
|
|
171
|
+
const existing = retained.labels[slot];
|
|
172
|
+
if (existing) {
|
|
173
|
+
return existing;
|
|
130
174
|
}
|
|
131
175
|
const label = document.createElement('div');
|
|
132
|
-
|
|
133
|
-
|
|
176
|
+
// Appended after the `<svg>` rather than inserted directly behind it, so the
|
|
177
|
+
// three captions land in slot order instead of in reverse creation order.
|
|
178
|
+
// Every one of them is absolutely positioned, so document order is a
|
|
179
|
+
// debugging convenience, not a layout decision.
|
|
180
|
+
(retained.svg.parentElement ?? retained.svg).append(label);
|
|
181
|
+
retained.labels[slot] = label;
|
|
134
182
|
return label;
|
|
135
183
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
184
|
+
/**
|
|
185
|
+
* The text and box one slot paints, or `null` when that caption is absent.
|
|
186
|
+
*
|
|
187
|
+
* The DOM twin of `paintedLabels` on the canvas side: same three slots, same
|
|
188
|
+
* `labelStyle` shared by all three, so the two renderers cannot disagree about
|
|
189
|
+
* what a connector is showing.
|
|
190
|
+
*/
|
|
191
|
+
function labelContent(model, slot) {
|
|
192
|
+
if (slot === 'center') {
|
|
193
|
+
return isConnectorWithLabel(model) && model.labelXYWH
|
|
194
|
+
? { text: model.text?.toString() ?? '', xywh: model.labelXYWH }
|
|
195
|
+
: null;
|
|
196
|
+
}
|
|
197
|
+
const xywh = model.endLabelXYWH(slot);
|
|
198
|
+
return model.hasEndLabel(slot) && xywh
|
|
199
|
+
? { text: model.endLabelText(slot)?.toString() ?? '', xywh }
|
|
200
|
+
: null;
|
|
201
|
+
}
|
|
202
|
+
function renderConnectorLabel(model, retained, renderer, zoom, slot) {
|
|
203
|
+
const content = labelContent(model, slot);
|
|
204
|
+
if (!content) {
|
|
205
|
+
retained.labels[slot]?.remove();
|
|
206
|
+
delete retained.labels[slot];
|
|
140
207
|
return;
|
|
141
208
|
}
|
|
142
|
-
const [lx, ly, lw, lh] =
|
|
209
|
+
const [lx, ly, lw, lh] = content.xywh;
|
|
143
210
|
const { labelStyle: { color, fontSize, fontWeight, fontStyle, fontFamily, textAlign, }, } = model;
|
|
144
|
-
const labelElement = getOrCreateLabelElement(retained);
|
|
211
|
+
const labelElement = getOrCreateLabelElement(retained, slot);
|
|
145
212
|
labelElement.style.position = 'absolute';
|
|
146
213
|
labelElement.style.left = `${lx * zoom}px`;
|
|
147
214
|
labelElement.style.top = `${ly * zoom}px`;
|
|
@@ -168,7 +235,7 @@ function renderConnectorLabel(model, retained, renderer, zoom) {
|
|
|
168
235
|
labelElement.style.whiteSpace = 'pre-wrap';
|
|
169
236
|
labelElement.style.wordWrap = 'break-word';
|
|
170
237
|
// Add text content
|
|
171
|
-
labelElement.textContent =
|
|
238
|
+
labelElement.textContent = content.text;
|
|
172
239
|
}
|
|
173
240
|
/**
|
|
174
241
|
* Renders a ConnectorElementModel to a given HTMLElement using DOM/SVG.
|
|
@@ -264,6 +331,9 @@ export const connectorDomRenderer = (model, element, renderer) => {
|
|
|
264
331
|
element.style.height = `${model.h * zoom}px`;
|
|
265
332
|
element.style.overflow = 'visible';
|
|
266
333
|
element.style.pointerEvents = 'none';
|
|
267
|
-
// Render
|
|
268
|
-
|
|
334
|
+
// Render each caption that is present — the centre name and the two end
|
|
335
|
+
// labels — and drop the node of any that is not.
|
|
336
|
+
for (const slot of LABEL_SLOTS) {
|
|
337
|
+
renderConnectorLabel(model, retained, renderer, zoom, slot);
|
|
338
|
+
}
|
|
269
339
|
};
|
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
import { ElementRendererExtension, } from '../../affine-block-surface/index.js';
|
|
2
2
|
import { getFontString, getLineHeight, getTextWidth, isRTL, wrapTextDeltas, } from '../../affine-gfx-text/index.js';
|
|
3
3
|
import { ConnectorMode, DefaultTheme, } from '../../affine-model/index.js';
|
|
4
|
-
import { getBezierParameters } from '../../global/gfx/index.js';
|
|
4
|
+
import { getBezierParameters, } from '../../global/gfx/index.js';
|
|
5
5
|
import { deltaInsertsToChunks } from '../../std/inline/index.js';
|
|
6
|
-
import { isConnectorWithLabel } from '../connector-manager.js';
|
|
7
|
-
import { DEFAULT_ARROW_SIZE, getArrowOptions, renderArrow, renderCircle, renderDiamond, renderTriangle, } from './utils.js';
|
|
6
|
+
import { isConnectorWithEndLabel, isConnectorWithLabel, } from '../connector-manager.js';
|
|
7
|
+
import { DEFAULT_ARROW_SIZE, getArrowOptions, HOLLOW_HEAD_FILL, renderArrow, renderCircle, renderDiamond, renderTriangle, } from './utils.js';
|
|
8
|
+
/** The captions this connector paints, in the order they are drawn. */
|
|
9
|
+
function paintedLabels(model) {
|
|
10
|
+
const labels = [];
|
|
11
|
+
if (isConnectorWithLabel(model)) {
|
|
12
|
+
const { text, labelXYWH, labelStyle, labelConstraints } = model;
|
|
13
|
+
labels.push({
|
|
14
|
+
text: text,
|
|
15
|
+
xywh: labelXYWH,
|
|
16
|
+
style: labelStyle,
|
|
17
|
+
constraints: labelConstraints,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
for (const end of ['source', 'target']) {
|
|
21
|
+
if (!isConnectorWithEndLabel(model, end))
|
|
22
|
+
continue;
|
|
23
|
+
const connectorModel = model;
|
|
24
|
+
labels.push({
|
|
25
|
+
text: connectorModel.endLabelText(end),
|
|
26
|
+
xywh: connectorModel.endLabelXYWH(end),
|
|
27
|
+
style: connectorModel.labelStyle,
|
|
28
|
+
constraints: connectorModel.labelConstraints,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return labels;
|
|
32
|
+
}
|
|
8
33
|
export const connector = (model, ctx, matrix, renderer, rc) => {
|
|
9
34
|
const { mode, path: points, strokeStyle, frontEndpointStyle, rearEndpointStyle, strokeWidth, } = model;
|
|
10
35
|
// points might not be build yet in some senarios
|
|
@@ -13,29 +38,39 @@ export const connector = (model, ctx, matrix, renderer, rc) => {
|
|
|
13
38
|
return;
|
|
14
39
|
}
|
|
15
40
|
ctx.setTransform(matrix);
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
41
|
+
const labels = paintedLabels(model);
|
|
42
|
+
// Each label's box, expressed relative to the element's own origin — the
|
|
43
|
+
// frame both the clip rects and the per-label transforms are written in.
|
|
44
|
+
let offsets = [];
|
|
45
|
+
if (labels.length) {
|
|
20
46
|
ctx.save();
|
|
21
|
-
const { deserializedXYWH
|
|
47
|
+
const { deserializedXYWH } = model;
|
|
22
48
|
const [x, y, w, h] = deserializedXYWH;
|
|
23
|
-
const [lx, ly, lw, lh] = labelXYWH;
|
|
24
49
|
const offset = DEFAULT_ARROW_SIZE * strokeWidth;
|
|
25
|
-
|
|
26
|
-
|
|
50
|
+
offsets = labels.map(label => [label.xywh[0] - x, label.xywh[1] - y]);
|
|
51
|
+
// One subtracted rect PER label: `evenodd` over the element rect and the
|
|
52
|
+
// caption rects leaves the stroke everywhere except under a caption, so a
|
|
53
|
+
// multiplicity beside an end punches the line exactly as the centre name
|
|
54
|
+
// always has.
|
|
27
55
|
const path = new Path2D();
|
|
28
56
|
path.rect(-offset / 2, -offset / 2, w + offset, h + offset);
|
|
29
|
-
|
|
57
|
+
labels.forEach((label, index) => {
|
|
58
|
+
const [dx, dy] = offsets[index];
|
|
59
|
+
const [, , lw, lh] = label.xywh;
|
|
60
|
+
path.rect(dx - 3 - 0.5, dy - 3 - 0.5, lw + 6 + 1, lh + 6 + 1);
|
|
61
|
+
});
|
|
30
62
|
ctx.clip(path, 'evenodd');
|
|
31
63
|
}
|
|
32
64
|
const strokeColor = renderer.getColorValue(model.stroke, DefaultTheme.connectorColor, true);
|
|
33
65
|
renderPoints(model, ctx, rc, points, strokeStyle === 'dash', mode === ConnectorMode.Curve, strokeColor);
|
|
34
66
|
renderEndpoint(model, points, ctx, rc, 'Front', frontEndpointStyle, strokeColor);
|
|
35
67
|
renderEndpoint(model, points, ctx, rc, 'Rear', rearEndpointStyle, strokeColor);
|
|
36
|
-
if (
|
|
68
|
+
if (labels.length) {
|
|
37
69
|
ctx.restore();
|
|
38
|
-
|
|
70
|
+
labels.forEach((label, index) => {
|
|
71
|
+
const [dx, dy] = offsets[index];
|
|
72
|
+
renderLabel(label, ctx, matrix.translate(dx, dy), renderer);
|
|
73
|
+
});
|
|
39
74
|
}
|
|
40
75
|
};
|
|
41
76
|
export const ConnectorElementRendererExtension = ElementRendererExtension('connector', connector);
|
|
@@ -93,6 +128,13 @@ function renderPoints(model, ctx, rc, points, dash, curve, stroke) {
|
|
|
93
128
|
}
|
|
94
129
|
function renderEndpoint(model, location, ctx, rc, end, style, stroke) {
|
|
95
130
|
const arrowOptions = getArrowOptions(end, model, stroke);
|
|
131
|
+
// No `default` on purpose: `PointStyle` is a persisted, append-only enum, so
|
|
132
|
+
// a build older than a member paints no head rather than throwing or drawing
|
|
133
|
+
// a wrong one. See the enum's docblock in `@labre/affine-model`.
|
|
134
|
+
//
|
|
135
|
+
// The hollow spread lives inside its own case: this runs once per endpoint
|
|
136
|
+
// per frame, and a solid head — or `None`, the default on the front of every
|
|
137
|
+
// connector — should not allocate an options object it never reads.
|
|
96
138
|
switch (style) {
|
|
97
139
|
case 'Arrow':
|
|
98
140
|
renderArrow(location, ctx, rc, arrowOptions);
|
|
@@ -100,23 +142,42 @@ function renderEndpoint(model, location, ctx, rc, end, style, stroke) {
|
|
|
100
142
|
case 'Triangle':
|
|
101
143
|
renderTriangle(location, ctx, rc, arrowOptions);
|
|
102
144
|
break;
|
|
145
|
+
case 'TriangleHollow':
|
|
146
|
+
renderTriangle(location, ctx, rc, {
|
|
147
|
+
...arrowOptions,
|
|
148
|
+
fillColor: HOLLOW_HEAD_FILL,
|
|
149
|
+
});
|
|
150
|
+
break;
|
|
103
151
|
case 'Circle':
|
|
104
152
|
renderCircle(location, ctx, rc, arrowOptions);
|
|
105
153
|
break;
|
|
106
154
|
case 'Diamond':
|
|
107
155
|
renderDiamond(location, ctx, rc, arrowOptions);
|
|
108
156
|
break;
|
|
157
|
+
case 'DiamondHollow':
|
|
158
|
+
renderDiamond(location, ctx, rc, {
|
|
159
|
+
...arrowOptions,
|
|
160
|
+
fillColor: HOLLOW_HEAD_FILL,
|
|
161
|
+
});
|
|
162
|
+
break;
|
|
109
163
|
}
|
|
110
164
|
}
|
|
111
|
-
|
|
112
|
-
|
|
165
|
+
/**
|
|
166
|
+
* Paints ONE caption at the origin of `matrix`.
|
|
167
|
+
*
|
|
168
|
+
* Takes a label rather than the connector: the centre name and the two end
|
|
169
|
+
* labels are the same drawing, and the only thing that told them apart was
|
|
170
|
+
* which pair of fields the function reached into.
|
|
171
|
+
*/
|
|
172
|
+
function renderLabel(label, ctx, matrix, renderer) {
|
|
173
|
+
const { text, xywh, style: { color, fontSize, fontWeight, fontStyle, fontFamily, textAlign }, constraints: { hasMaxWidth, maxWidth }, } = label;
|
|
113
174
|
const font = getFontString({
|
|
114
175
|
fontStyle,
|
|
115
176
|
fontWeight,
|
|
116
177
|
fontSize,
|
|
117
178
|
fontFamily,
|
|
118
179
|
});
|
|
119
|
-
const [, , w, h] =
|
|
180
|
+
const [, , w, h] = xywh;
|
|
120
181
|
const cx = w / 2;
|
|
121
182
|
const cy = h / 2;
|
|
122
183
|
ctx.setTransform(matrix);
|
|
@@ -3,6 +3,17 @@ import { type ConnectorElementModel, ConnectorMode, type LocalConnectorElementMo
|
|
|
3
3
|
import type { BezierCurveParameters, IVec, PointLocation } from '../../global/gfx/index.js';
|
|
4
4
|
type ConnectorEnd = 'Front' | 'Rear';
|
|
5
5
|
export declare const DEFAULT_ARROW_SIZE = 15;
|
|
6
|
+
/**
|
|
7
|
+
* The interior of a hollow endpoint head (`TriangleHollow`, `DiamondHollow`).
|
|
8
|
+
*
|
|
9
|
+
* The notation card fill (R33), NOT a theme-resolved token and NOT
|
|
10
|
+
* `transparent`: a UML hollow head reads as a white shape sitting on top of the
|
|
11
|
+
* line it terminates, exactly like the class box it points at — which is itself
|
|
12
|
+
* painted `NOTATION_NEUTRALS.cardFill` in every theme. `transparent` would let
|
|
13
|
+
* the connector's own line show through the head; a theme token would turn the
|
|
14
|
+
* head black-on-black next to a card-white box in a dark host.
|
|
15
|
+
*/
|
|
16
|
+
export declare const HOLLOW_HEAD_FILL: string;
|
|
6
17
|
export declare function getArrowPoints(points: PointLocation[], size: number | undefined, mode: ConnectorMode, bezierParameters: BezierCurveParameters, endPoint?: ConnectorEnd, radians?: number): {
|
|
7
18
|
points: (IVec | PointLocation)[];
|
|
8
19
|
};
|
|
@@ -12,7 +23,12 @@ export declare function getDiamondPoints(point: PointLocation, size?: number, en
|
|
|
12
23
|
points: (IVec | PointLocation)[];
|
|
13
24
|
};
|
|
14
25
|
export type ArrowOptions = ReturnType<typeof getArrowOptions>;
|
|
15
|
-
|
|
26
|
+
/**
|
|
27
|
+
* @param fillColor the interior of a closed head. Defaults to `strokeColor`, so
|
|
28
|
+
* a `Triangle` or a `Diamond` stays the solid head it has always been; the
|
|
29
|
+
* hollow UML heads pass `HOLLOW_HEAD_FILL` instead.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getArrowOptions(end: ConnectorEnd, model: ConnectorElementModel | LocalConnectorElementModel, strokeColor: string, fillColor?: string): {
|
|
16
32
|
end: ConnectorEnd;
|
|
17
33
|
seed: number;
|
|
18
34
|
mode: ConnectorMode;
|
|
@@ -32,7 +48,13 @@ export declare function getRcOptions(options: ArrowOptions): {
|
|
|
32
48
|
fill: string;
|
|
33
49
|
fillStyle: string;
|
|
34
50
|
};
|
|
35
|
-
|
|
51
|
+
/**
|
|
52
|
+
* @param color the outline colour.
|
|
53
|
+
* @param fillColor the interior colour. Defaults to `color` — the solid head.
|
|
54
|
+
* A hollow head passes the notation card fill, so the outline stays the
|
|
55
|
+
* connector's colour while the inside reads as empty.
|
|
56
|
+
*/
|
|
57
|
+
export declare function renderRoundedPolygon(ctx: CanvasRenderingContext2D, points: IVec[], color: string, strokeWidth: number, fill?: boolean, fillColor?: string): void;
|
|
36
58
|
export declare function renderArrow(points: PointLocation[], ctx: CanvasRenderingContext2D, rc: RoughCanvas, options: ArrowOptions): void;
|
|
37
59
|
export declare function renderTriangle(points: PointLocation[], ctx: CanvasRenderingContext2D, rc: RoughCanvas, options: ArrowOptions): void;
|
|
38
60
|
export declare function renderDiamond(points: PointLocation[], ctx: CanvasRenderingContext2D, rc: RoughCanvas, options: ArrowOptions): void;
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { ConnectorMode, } from '../../affine-model/index.js';
|
|
2
|
+
import { NOTATION_NEUTRALS } from '../../affine-shared/consts/index.js';
|
|
2
3
|
import { getBezierParameters, getBezierTangent, Vec } from '../../global/gfx/index.js';
|
|
3
4
|
export const DEFAULT_ARROW_SIZE = 15;
|
|
5
|
+
/**
|
|
6
|
+
* The interior of a hollow endpoint head (`TriangleHollow`, `DiamondHollow`).
|
|
7
|
+
*
|
|
8
|
+
* The notation card fill (R33), NOT a theme-resolved token and NOT
|
|
9
|
+
* `transparent`: a UML hollow head reads as a white shape sitting on top of the
|
|
10
|
+
* line it terminates, exactly like the class box it points at — which is itself
|
|
11
|
+
* painted `NOTATION_NEUTRALS.cardFill` in every theme. `transparent` would let
|
|
12
|
+
* the connector's own line show through the head; a theme token would turn the
|
|
13
|
+
* head black-on-black next to a card-white box in a dark host.
|
|
14
|
+
*/
|
|
15
|
+
export const HOLLOW_HEAD_FILL = NOTATION_NEUTRALS.cardFill;
|
|
4
16
|
export function getArrowPoints(points, size = 10, mode, bezierParameters, endPoint = 'Rear', radians = Math.PI / 4) {
|
|
5
17
|
const anchorPoint = getPointWithTangent(points, mode, endPoint, bezierParameters);
|
|
6
18
|
const unit = Vec.mul(anchorPoint.tangent, -1);
|
|
@@ -70,7 +82,12 @@ export function getDiamondPoints(point, size = 10, endPoint = 'Rear') {
|
|
|
70
82
|
points: diamondPoints,
|
|
71
83
|
};
|
|
72
84
|
}
|
|
73
|
-
|
|
85
|
+
/**
|
|
86
|
+
* @param fillColor the interior of a closed head. Defaults to `strokeColor`, so
|
|
87
|
+
* a `Triangle` or a `Diamond` stays the solid head it has always been; the
|
|
88
|
+
* hollow UML heads pass `HOLLOW_HEAD_FILL` instead.
|
|
89
|
+
*/
|
|
90
|
+
export function getArrowOptions(end, model, strokeColor, fillColor = strokeColor) {
|
|
74
91
|
const { seed, mode, rough, roughness, strokeWidth, path } = model;
|
|
75
92
|
return {
|
|
76
93
|
end,
|
|
@@ -80,7 +97,7 @@ export function getArrowOptions(end, model, strokeColor) {
|
|
|
80
97
|
roughness,
|
|
81
98
|
strokeWidth,
|
|
82
99
|
strokeColor,
|
|
83
|
-
fillColor
|
|
100
|
+
fillColor,
|
|
84
101
|
fillStyle: 'solid',
|
|
85
102
|
bezierParameters: getBezierParameters(path),
|
|
86
103
|
};
|
|
@@ -96,8 +113,14 @@ export function getRcOptions(options) {
|
|
|
96
113
|
fillStyle: 'solid',
|
|
97
114
|
};
|
|
98
115
|
}
|
|
99
|
-
|
|
100
|
-
|
|
116
|
+
/**
|
|
117
|
+
* @param color the outline colour.
|
|
118
|
+
* @param fillColor the interior colour. Defaults to `color` — the solid head.
|
|
119
|
+
* A hollow head passes the notation card fill, so the outline stays the
|
|
120
|
+
* connector's colour while the inside reads as empty.
|
|
121
|
+
*/
|
|
122
|
+
export function renderRoundedPolygon(ctx, points, color, strokeWidth, fill = true, fillColor = color) {
|
|
123
|
+
ctx.fillStyle = fillColor;
|
|
101
124
|
ctx.strokeStyle = color;
|
|
102
125
|
ctx.lineWidth = strokeWidth;
|
|
103
126
|
ctx.lineJoin = 'round';
|
|
@@ -132,7 +155,7 @@ export function renderArrow(points, ctx, rc, options) {
|
|
|
132
155
|
}
|
|
133
156
|
}
|
|
134
157
|
export function renderTriangle(points, ctx, rc, options) {
|
|
135
|
-
const { mode, end, bezierParameters, rough, strokeColor, strokeWidth } = options;
|
|
158
|
+
const { mode, end, bezierParameters, rough, fillColor, strokeColor, strokeWidth, } = options;
|
|
136
159
|
const radians = Math.PI / 6;
|
|
137
160
|
const size = DEFAULT_ARROW_SIZE * (strokeWidth / 2);
|
|
138
161
|
const { points: trianglePoints } = getArrowPoints(points, size, mode, bezierParameters, end, radians);
|
|
@@ -144,11 +167,11 @@ export function renderTriangle(points, ctx, rc, options) {
|
|
|
144
167
|
], getRcOptions(options));
|
|
145
168
|
}
|
|
146
169
|
else {
|
|
147
|
-
renderRoundedPolygon(ctx, trianglePoints, strokeColor, strokeWidth);
|
|
170
|
+
renderRoundedPolygon(ctx, trianglePoints, strokeColor, strokeWidth, true, fillColor);
|
|
148
171
|
}
|
|
149
172
|
}
|
|
150
173
|
export function renderDiamond(points, ctx, rc, options) {
|
|
151
|
-
const { mode, end, rough, bezierParameters, strokeColor, strokeWidth } = options;
|
|
174
|
+
const { mode, end, rough, bezierParameters, fillColor, strokeColor, strokeWidth, } = options;
|
|
152
175
|
const anchorPoint = getPointWithTangent(points, mode, end, bezierParameters);
|
|
153
176
|
const size = 10 * (strokeWidth / 2);
|
|
154
177
|
const { points: diamondPoints } = getDiamondPoints(anchorPoint, size, end);
|
|
@@ -161,7 +184,7 @@ export function renderDiamond(points, ctx, rc, options) {
|
|
|
161
184
|
], getRcOptions(options));
|
|
162
185
|
}
|
|
163
186
|
else {
|
|
164
|
-
renderRoundedPolygon(ctx, diamondPoints, strokeColor, strokeWidth);
|
|
187
|
+
renderRoundedPolygon(ctx, diamondPoints, strokeColor, strokeWidth, true, fillColor);
|
|
165
188
|
}
|
|
166
189
|
}
|
|
167
190
|
export function renderCircle(points, ctx, rc, options) {
|
|
@@ -1,17 +1,136 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ConnectorElementModel, type ConnectorLabelEnd } from '../../affine-model/index.js';
|
|
2
2
|
import type { RichText } from '../../affine-rich-text/index.js';
|
|
3
|
-
import { type IVec } from '../../global/gfx/index.js';
|
|
3
|
+
import { type IVec, type XYWH } from '../../global/gfx/index.js';
|
|
4
4
|
import { type BlockComponent, type BlockStdScope, ShadowlessElement } from '../../std/index.js';
|
|
5
|
-
|
|
5
|
+
import * as Y from 'yjs';
|
|
6
|
+
/**
|
|
7
|
+
* Which of a connector's three labels a gesture is about — its centre caption,
|
|
8
|
+
* or one of the two end labels UML writes multiplicities and role names in
|
|
9
|
+
* (`docs/adr/0018` phase 2).
|
|
10
|
+
*
|
|
11
|
+
* Built on the model's own `ConnectorLabelEnd` rather than restating its two
|
|
12
|
+
* members: the ends are the model's vocabulary — they are the names of its two
|
|
13
|
+
* `Connection`s — and only the EDITOR has a third case, because only the editor
|
|
14
|
+
* has to be pointed at one label out of three.
|
|
15
|
+
*/
|
|
16
|
+
export type ConnectorLabelWhich = 'center' | ConnectorLabelEnd;
|
|
17
|
+
/**
|
|
18
|
+
* The model fields each label lives in.
|
|
19
|
+
*
|
|
20
|
+
* Declared once, as data, because THREE places need the same answer — the
|
|
21
|
+
* editor's read, its resize write and its empty-commit delete — and three
|
|
22
|
+
* `which === 'center' ? … : …` chains is how one of them ends up writing the
|
|
23
|
+
* centre label's box under an end label's text.
|
|
24
|
+
*/
|
|
25
|
+
export declare const CONNECTOR_LABEL_FIELDS: {
|
|
26
|
+
readonly center: {
|
|
27
|
+
readonly text: "text";
|
|
28
|
+
readonly xywh: "labelXYWH";
|
|
29
|
+
};
|
|
30
|
+
readonly source: {
|
|
31
|
+
readonly text: "sourceLabel";
|
|
32
|
+
readonly xywh: "sourceLabelXYWH";
|
|
33
|
+
};
|
|
34
|
+
readonly target: {
|
|
35
|
+
readonly text: "targetLabel";
|
|
36
|
+
readonly xywh: "targetLabelXYWH";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
/** {@link CONNECTOR_LABEL_FIELDS}, defaulting to the centre label. */
|
|
40
|
+
export declare function connectorLabelFields(which?: ConnectorLabelWhich): {
|
|
41
|
+
readonly text: "text";
|
|
42
|
+
readonly xywh: "labelXYWH";
|
|
43
|
+
} | {
|
|
44
|
+
readonly text: "sourceLabel";
|
|
45
|
+
readonly xywh: "sourceLabelXYWH";
|
|
46
|
+
} | {
|
|
47
|
+
readonly text: "targetLabel";
|
|
48
|
+
readonly xywh: "targetLabelXYWH";
|
|
49
|
+
};
|
|
50
|
+
/** The `Y.Text` of `which`, or `undefined` when that label does not exist. */
|
|
51
|
+
export declare function connectorLabelText(connector: ConnectorElementModel, which?: ConnectorLabelWhich): Y.Text | undefined;
|
|
52
|
+
/** The box of `which`, or `undefined` when that label does not exist. */
|
|
53
|
+
export declare function connectorLabelXYWH(connector: ConnectorElementModel, which?: ConnectorLabelWhich): XYWH | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* The box an end label of `size` takes on the current path — the one geometry
|
|
56
|
+
* helper the model owns, so the renderer, the editor and the hit test all place
|
|
57
|
+
* an end label in the same spot.
|
|
58
|
+
*/
|
|
59
|
+
export declare function connectorEndLabelBoxFor(connector: ConnectorElementModel, which: ConnectorLabelEnd, size?: {
|
|
60
|
+
w: number;
|
|
61
|
+
h: number;
|
|
62
|
+
}): XYWH;
|
|
63
|
+
/**
|
|
64
|
+
* What to write so that `which` EXISTS, or `null` when it already does.
|
|
65
|
+
*
|
|
66
|
+
* The centre label is seeded where the pointer is, riding the path by an offset
|
|
67
|
+
* distance — it has always been a caption the author places. An end label is
|
|
68
|
+
* seeded at its ENDPOINT and ignores the pointer: the whole value of one is
|
|
69
|
+
* that it follows the end when the node moves (`docs/adr/0018`, "Alternatives
|
|
70
|
+
* rejected"), so where the double-click landed says nothing about where it
|
|
71
|
+
* belongs.
|
|
72
|
+
*/
|
|
73
|
+
export declare function connectorLabelSeedProps(connector: ConnectorElementModel, which?: ConnectorLabelWhich, point?: IVec): Record<string, unknown> | null;
|
|
74
|
+
/**
|
|
75
|
+
* What to write when an editing session ENDS, or `null` when the text is
|
|
76
|
+
* already exactly what the model holds.
|
|
77
|
+
*
|
|
78
|
+
* A label committed empty clears both of its fields, so the connector reads
|
|
79
|
+
* as one that has none (`hasEndLabel` false, nothing painted, nothing
|
|
80
|
+
* exported). The KEYS stay in the Y.Map as `undefined` — the field setter
|
|
81
|
+
* writes what it is given — so only a connector that never carried an end
|
|
82
|
+
* label is byte-identical to a pre-0020 one; `docs/adr/0020`'s "no migration"
|
|
83
|
+
* promise is about that connector, not about this reset.
|
|
84
|
+
*
|
|
85
|
+
* Pure and exported: it is the one rule with three outcomes (delete, trim,
|
|
86
|
+
* nothing) times three labels, and a spec should be able to ask it directly.
|
|
87
|
+
*/
|
|
88
|
+
export declare function connectorLabelCommitProps(raw: string, which?: ConnectorLabelWhich): Record<string, unknown> | null;
|
|
89
|
+
export type MountConnectorLabelEditorOptions = {
|
|
90
|
+
/** Which label to edit. Defaults to the centre one. */
|
|
91
|
+
which?: ConnectorLabelWhich;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Opens the label editor on ONE of a connector's three labels.
|
|
95
|
+
*
|
|
96
|
+
* This function used to exist twice — here and byte-alike in `text.ts`, which
|
|
97
|
+
* was the copy the package barrel re-exported — so the toolbar and the keyboard
|
|
98
|
+
* reached one body and the view's double-click the other. `docs/adr/0018`
|
|
99
|
+
* phase 2 makes the difference visible (a selector only one copy would have
|
|
100
|
+
* carried), so the duplicate is gone and `text.ts` re-exports this one.
|
|
101
|
+
*/
|
|
102
|
+
export declare function mountConnectorLabelEditor(connector: ConnectorElementModel, edgeless: BlockComponent, point?: IVec, options?: MountConnectorLabelEditorOptions): void;
|
|
6
103
|
declare const EdgelessConnectorLabelEditor_base: typeof ShadowlessElement & import("../../global/utils/types.js").Constructor<import("../../global/lit/with-disposable.js").DisposableClass>;
|
|
7
104
|
export declare class EdgelessConnectorLabelEditor extends EdgelessConnectorLabelEditor_base {
|
|
8
105
|
static styles: import("lit").CSSResult;
|
|
9
106
|
get crud(): import("../../affine-block-surface/index.js").EdgelessCRUDExtension;
|
|
10
107
|
get gfx(): import("../../std/gfx/controller.js").GfxController;
|
|
11
108
|
get selection(): import("../../std/gfx/selection.js").GfxSelectionManager;
|
|
109
|
+
/** The two model fields this editor reads and writes. */
|
|
110
|
+
get fields(): {
|
|
111
|
+
readonly text: "text";
|
|
112
|
+
readonly xywh: "labelXYWH";
|
|
113
|
+
} | {
|
|
114
|
+
readonly text: "sourceLabel";
|
|
115
|
+
readonly xywh: "sourceLabelXYWH";
|
|
116
|
+
} | {
|
|
117
|
+
readonly text: "targetLabel";
|
|
118
|
+
readonly xywh: "targetLabelXYWH";
|
|
119
|
+
};
|
|
120
|
+
/** The `Y.Text` this editor is bound to. */
|
|
121
|
+
get yText(): Y.Text | undefined;
|
|
12
122
|
private _isComposition;
|
|
13
123
|
private _keeping;
|
|
124
|
+
private _removing;
|
|
14
125
|
private _resizeObserver;
|
|
126
|
+
/**
|
|
127
|
+
* Where the editor sits, in MODEL coordinates.
|
|
128
|
+
*
|
|
129
|
+
* The centre label rides the path by its offset distance, so its anchor is
|
|
130
|
+
* recomputed from the connector; an end label's box is the anchor, and it is
|
|
131
|
+
* the box that follows the endpoint (see `connectorEndLabelBox`).
|
|
132
|
+
*/
|
|
133
|
+
private get _labelCenter();
|
|
15
134
|
private readonly _updateLabelRect;
|
|
16
135
|
get inlineEditor(): import("../../affine-shared/types/index.js").AffineInlineEditor | null;
|
|
17
136
|
get inlineEditorContainer(): import("../../std/inline/inline-editor.js").InlineRootElement<import("../../affine-shared/types/index.js").AffineTextAttributes> | null | undefined;
|
|
@@ -22,6 +141,8 @@ export declare class EdgelessConnectorLabelEditor extends EdgelessConnectorLabel
|
|
|
22
141
|
render(): import("lit-html").TemplateResult<1>;
|
|
23
142
|
setKeeping(keeping: boolean): void;
|
|
24
143
|
accessor connector: ConnectorElementModel;
|
|
144
|
+
/** Which of the connector's three labels is being edited. */
|
|
145
|
+
accessor which: ConnectorLabelWhich;
|
|
25
146
|
accessor std: BlockStdScope;
|
|
26
147
|
accessor richText: RichText;
|
|
27
148
|
}
|