@formicoidea/labre-core 0.53.0 → 0.55.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/dist/_pkgs/affine-block-data-view/data-view-block.js +1 -1
- package/dist/_pkgs/affine-block-database/components/title/index.js +7 -2
- package/dist/_pkgs/affine-block-database/database-block-styles.js +9 -1
- package/dist/_pkgs/affine-block-embed-doc/page-drop/page-drop.d.ts +70 -0
- package/dist/_pkgs/affine-block-embed-doc/page-drop/page-drop.js +196 -0
- package/dist/_pkgs/affine-block-embed-doc/view.js +3 -0
- package/dist/_pkgs/affine-block-frame/frame-template.d.ts +11 -0
- package/dist/_pkgs/affine-block-frame/frame-template.js +24 -4
- package/dist/_pkgs/affine-block-frame/translations.d.ts +3 -0
- package/dist/_pkgs/affine-block-frame/translations.js +7 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.js +9 -3
- package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +9 -5
- package/dist/_pkgs/affine-block-surface/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.d.ts +55 -3
- package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.js +139 -6
- package/dist/_pkgs/affine-block-surface/renderer/notation-tint.d.ts +92 -0
- package/dist/_pkgs/affine-block-surface/renderer/notation-tint.js +113 -0
- package/dist/_pkgs/affine-block-surface/surface-block.js +2 -2
- package/dist/_pkgs/affine-components/color-picker/styles.js +1 -1
- package/dist/_pkgs/affine-components/context-menu/input.js +2 -1
- package/dist/_pkgs/affine-components/context-menu/menu-renderer.d.ts +7 -0
- package/dist/_pkgs/affine-components/context-menu/menu-renderer.js +53 -13
- package/dist/_pkgs/affine-components/drop-indicator/file-drop-manager.js +15 -0
- package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/index.js +4 -2
- package/dist/_pkgs/affine-inline-link/link-node/link-popup/styles.js +1 -1
- package/dist/_pkgs/affine-inline-reference/reference-node/reference-popup/reference-popup.js +9 -9
- package/dist/_pkgs/affine-shared/consts/notation.d.ts +1 -0
- package/dist/_pkgs/affine-shared/consts/notation.js +29 -0
- package/dist/_pkgs/affine-shared/services/frame-template-service.d.ts +5 -0
- package/dist/_pkgs/affine-shared/services/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/services/index.js +1 -0
- package/dist/_pkgs/affine-shared/services/page-drop-service.d.ts +61 -0
- package/dist/_pkgs/affine-shared/services/page-drop-service.js +30 -0
- package/dist/_pkgs/affine-shared/styles/scrollbar-style.js +1 -1
- package/dist/_pkgs/affine-widget-edgeless-auto-connect/index.js +5 -5
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-auto-complete.js +2 -2
- package/dist/_pkgs/affine-widget-keyboard-toolbar/config.js +6 -6
- package/dist/_pkgs/affine-widget-keyboard-toolbar/styles.js +1 -1
- package/dist/_pkgs/affine-widget-linked-doc/config.d.ts +8 -0
- package/dist/_pkgs/affine-widget-linked-doc/config.js +8 -1
- package/dist/_pkgs/affine-widget-linked-doc/linked-doc-popover.js +40 -32
- package/dist/_pkgs/affine-widget-linked-doc/styles.js +1 -1
- package/dist/_pkgs/affine-widget-linked-doc/translations.d.ts +2 -0
- package/dist/_pkgs/affine-widget-linked-doc/translations.js +6 -0
- package/dist/_pkgs/affine-widget-thread-marks/widget.d.ts +3 -1
- package/dist/_pkgs/affine-widget-thread-marks/widget.js +6 -1
- package/dist/_pkgs/affine-widget-toolbar/utils.d.ts +2 -1
- package/dist/_pkgs/affine-widget-toolbar/utils.js +5 -2
- package/dist/_pkgs/data-view/core/common/properties.js +2 -2
- package/dist/_pkgs/data-view/core/common/property-menu.d.ts +3 -3
- package/dist/_pkgs/data-view/core/common/property-menu.js +7 -7
- package/dist/_pkgs/data-view/core/component/overflow/overflow.js +4 -1
- package/dist/_pkgs/data-view/core/group-by/renderer/base.d.ts +4 -1
- package/dist/_pkgs/data-view/core/group-by/renderer/base.js +17 -2
- package/dist/_pkgs/data-view/core/group-by/renderer/number-group.js +1 -1
- package/dist/_pkgs/data-view/core/group-by/renderer/select-group.d.ts +0 -3
- package/dist/_pkgs/data-view/core/group-by/renderer/select-group.js +63 -118
- package/dist/_pkgs/data-view/core/group-by/renderer/string-group.js +1 -1
- package/dist/_pkgs/data-view/core/group-by/setting.js +2 -2
- package/dist/_pkgs/data-view/core/utils/wording.d.ts +6 -2
- package/dist/_pkgs/data-view/core/utils/wording.js +5 -3
- package/dist/_pkgs/data-view/core/view/default-name.d.ts +6 -0
- package/dist/_pkgs/data-view/core/view/default-name.js +8 -0
- package/dist/_pkgs/data-view/translations.d.ts +45 -0
- package/dist/_pkgs/data-view/translations.js +118 -0
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.d.ts +3 -1
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.js +5 -1
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.d.ts +6 -0
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.js +11 -0
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +9 -10
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.js +3 -0
- package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +7 -4
- package/dist/_pkgs/data-view/view-presets/table/mobile/column-header.d.ts +3 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/column-header.js +102 -124
- package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +12 -7
- package/dist/_pkgs/data-view/view-presets/table/mobile/header.d.ts +8 -2
- package/dist/_pkgs/data-view/view-presets/table/mobile/header.js +64 -24
- package/dist/_pkgs/data-view/view-presets/table/mobile/menu.d.ts +3 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/menu.js +7 -3
- package/dist/_pkgs/data-view/view-presets/table/mobile/row.d.ts +23 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/row.js +138 -55
- package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-style.d.ts +17 -0
- package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-style.js +31 -6
- package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.d.ts +5 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.js +11 -4
- package/dist/_pkgs/data-view/view-presets/table/pc/group.js +4 -2
- package/dist/_pkgs/data-view/view-presets/table/pc/row/row.js +5 -1
- package/dist/_pkgs/data-view/widget-presets/quick-setting-bar/filter/index.js +1 -2
- package/dist/_pkgs/data-view/widget-presets/quick-setting-bar/filter/list-view.d.ts +3 -1
- package/dist/_pkgs/data-view/widget-presets/quick-setting-bar/filter/list-view.js +23 -3
- package/dist/_pkgs/data-view/widget-presets/quick-setting-bar/index.js +8 -8
- package/dist/_pkgs/data-view/widget-presets/tools/presets/filter/filter.d.ts +3 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/filter/filter.js +125 -60
- package/dist/_pkgs/data-view/widget-presets/tools/presets/search/search.d.ts +3 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/search/search.js +37 -5
- package/dist/_pkgs/data-view/widget-presets/tools/presets/sort/sort.d.ts +3 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/sort/sort.js +131 -66
- package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.d.ts +3 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.js +143 -40
- package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +30 -22
- package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.js +8 -6
- package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.js +15 -0
- package/package.json +1 -1
|
@@ -85,7 +85,7 @@ export class DataViewBlockComponent extends CaptionedBlockComponent {
|
|
|
85
85
|
style="display:flex;align-items:center;justify-content: space-between;gap: 12px"
|
|
86
86
|
class="database-header-bar"
|
|
87
87
|
>
|
|
88
|
-
<div style="flex:1">
|
|
88
|
+
<div style="flex:1;min-width:0">
|
|
89
89
|
${renderUniLit(widgetPresets.viewBar, props)}
|
|
90
90
|
</div>
|
|
91
91
|
${renderUniLit(this.toolsWidget, props)}
|
|
@@ -32,6 +32,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
+
import { DOC_UNTITLED, translateKey } from '../../../affine-shared/services/index.js';
|
|
35
36
|
import { unsafeCSSVarV2 } from '../../../affine-shared/theme/index.js';
|
|
36
37
|
import { stopPropagation } from '../../../affine-shared/utils/index.js';
|
|
37
38
|
import { SignalWatcher, WithDisposable } from '../../../global/lit/index.js';
|
|
@@ -112,7 +113,7 @@ let DatabaseTitle = (() => {
|
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
.affine-database-title [data-title-empty='true']::before {
|
|
115
|
-
content:
|
|
116
|
+
content: attr(data-untitled);
|
|
116
117
|
position: absolute;
|
|
117
118
|
pointer-events: none;
|
|
118
119
|
color: var(--affine-text-primary-color);
|
|
@@ -152,12 +153,16 @@ let DatabaseTitle = (() => {
|
|
|
152
153
|
height: isEmpty ? 'auto' : 0,
|
|
153
154
|
opacity: isEmpty && !this.isFocus$.value ? 1 : 0,
|
|
154
155
|
});
|
|
156
|
+
const std = this.database?.std;
|
|
157
|
+
// A base is a page: its empty title is the page's "Untitled" (P7).
|
|
158
|
+
const untitled = std ? translateKey(std, ...DOC_UNTITLED) : DOC_UNTITLED[1];
|
|
155
159
|
return html ` <div
|
|
156
160
|
class="${classList}"
|
|
157
161
|
data-title-empty="${isEmpty}"
|
|
158
162
|
data-title-focus="${this.isFocus$.value}"
|
|
163
|
+
data-untitled="${untitled}"
|
|
159
164
|
>
|
|
160
|
-
<div class="text" style="${untitledStyle}"
|
|
165
|
+
<div class="text" style="${untitledStyle}">${untitled}</div>
|
|
161
166
|
<div class="text">${this.text$.value}</div>
|
|
162
167
|
<textarea
|
|
163
168
|
.disabled="${this.readonly$.value}"
|
|
@@ -46,14 +46,22 @@ export const databaseTitleRowStyles = css({
|
|
|
46
46
|
marginBottom: '8px',
|
|
47
47
|
alignItems: 'center',
|
|
48
48
|
});
|
|
49
|
+
// Too narrow for the tabs and the tools side by side (a phone, P7), the tools
|
|
50
|
+
// drop to a line of their own, on the right, instead of squeezing the
|
|
51
|
+
// current view's tab to its icon.
|
|
49
52
|
export const databaseToolbarRowStyles = css({
|
|
50
53
|
display: 'flex',
|
|
54
|
+
flexWrap: 'wrap',
|
|
51
55
|
alignItems: 'center',
|
|
52
56
|
justifyContent: 'space-between',
|
|
53
57
|
gap: '12px',
|
|
58
|
+
'& data-view-header-tools': {
|
|
59
|
+
marginLeft: 'auto',
|
|
60
|
+
},
|
|
54
61
|
});
|
|
55
62
|
export const databaseViewBarContainerStyles = css({
|
|
56
|
-
flex: 1,
|
|
63
|
+
flex: '1 1 200px',
|
|
64
|
+
minWidth: 0,
|
|
57
65
|
});
|
|
58
66
|
export const databaseContentStyles = css({
|
|
59
67
|
position: 'relative',
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type PageDrop } from '../../affine-shared/services/index.js';
|
|
2
|
+
import { type IVec } from '../../global/gfx/index.js';
|
|
3
|
+
import { type BlockStdScope, LifeCycleWatcher } from '../../std/index.js';
|
|
4
|
+
import type { BlockModel, Store } from '../../store/index.js';
|
|
5
|
+
/** The drop line in a note: a block and which side of it. */
|
|
6
|
+
export interface PageDropLine {
|
|
7
|
+
model: BlockModel;
|
|
8
|
+
placement: 'before' | 'after';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Where a dropped page's card goes (labre P7, ADR-0045 §7 amended
|
|
12
|
+
* 2026-10-16), mirroring "Show here" (`fragments/doc-title`, `show-here.ts`):
|
|
13
|
+
*
|
|
14
|
+
* - on a drop line in a note (page view, or a note on the canvas): a block
|
|
15
|
+
* beside the line's block, climbing out of whatever cannot hold a card (a
|
|
16
|
+
* list item, a callout) to the first parent that can;
|
|
17
|
+
* - on the canvas, off any note: a canvas card centred on the drop point,
|
|
18
|
+
* through the CRUD `addBlock`, which stamps the viewer's active layer
|
|
19
|
+
* (ADR 0031 §6), then selected;
|
|
20
|
+
* - in the page view with no line (dropped under the content): the end of
|
|
21
|
+
* the last note.
|
|
22
|
+
*
|
|
23
|
+
* The caller owns the undo step (`captureSync` around it). Returns the new
|
|
24
|
+
* card's id, or `null` when nothing was written (read-only, no root).
|
|
25
|
+
*/
|
|
26
|
+
export declare function placePageCard(std: BlockStdScope, pageId: string, at: {
|
|
27
|
+
canvas: boolean;
|
|
28
|
+
line: PageDropLine | null;
|
|
29
|
+
point: IVec;
|
|
30
|
+
}): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* The drop line under a client point, as the editor's own file drop draws it
|
|
33
|
+
* (`FileDropExtension.dropTarget$`): none on the canvas itself or on a block
|
|
34
|
+
* that sits on it, only inside a note.
|
|
35
|
+
*/
|
|
36
|
+
export declare function dropLineAt(std: BlockStdScope, clientX: number, clientY: number): PageDropLine | null;
|
|
37
|
+
/**
|
|
38
|
+
* Hangs the host's `undo` / `redo` on the undo step that holds the card (the
|
|
39
|
+
* last one, the caller having opened it with `captureSync`), so one Mod+Z
|
|
40
|
+
* removes the card AND puts back what the host did. Yjs gives a popped step's
|
|
41
|
+
* twin (the redo step an undo creates, and back) a fresh `meta`: the hooks are
|
|
42
|
+
* carried over at each pop. A step whose card was already gone (removed by
|
|
43
|
+
* another peer) changes nothing, so Yjs skips it and the host's hooks are not
|
|
44
|
+
* called: the page stays where the drop put it, nothing is lost.
|
|
45
|
+
*/
|
|
46
|
+
export declare function rideUndoStep(store: Store, drop: PageDrop): void;
|
|
47
|
+
/** The `stack-item-popped` half of {@link rideUndoStep}. */
|
|
48
|
+
export declare function runUndoHooks(store: Store, event: {
|
|
49
|
+
stackItem: {
|
|
50
|
+
meta: Map<unknown, unknown>;
|
|
51
|
+
};
|
|
52
|
+
type: 'undo' | 'redo';
|
|
53
|
+
}): void;
|
|
54
|
+
/**
|
|
55
|
+
* The whole drop: ask the host, place the card in one undo step, hang the
|
|
56
|
+
* host's hooks on it. A drop the host turns down, or a card that cannot be
|
|
57
|
+
* placed, writes nothing (the host's own change is undone at once).
|
|
58
|
+
*/
|
|
59
|
+
export declare function dropPage(std: BlockStdScope, event: Pick<DragEvent, 'dataTransfer' | 'clientX' | 'clientY'>, canvas: boolean): string | null;
|
|
60
|
+
/**
|
|
61
|
+
* Mounts the page drop on the editor: a native drop the host accepts places
|
|
62
|
+
* the page's card, and the history runs the host's hooks with the card's
|
|
63
|
+
* undo step. Without a `PageDropProvider` nothing changes: `dropPage` returns
|
|
64
|
+
* at the verdict.
|
|
65
|
+
*/
|
|
66
|
+
export declare class PageDropWatcher extends LifeCycleWatcher {
|
|
67
|
+
static readonly key = "labre-page-drop-watcher";
|
|
68
|
+
private readonly _onPopped;
|
|
69
|
+
mounted(): void;
|
|
70
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { EdgelessCRUDIdentifier } from '../../affine-block-surface/index.js';
|
|
2
|
+
import { EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../../affine-shared/consts/index.js';
|
|
3
|
+
import { PageDropProvider, pageDropVerdict, TelemetryProvider, } from '../../affine-shared/services/index.js';
|
|
4
|
+
import { calcDropTarget, getClosestBlockComponentByPoint, getLastNoteBlock, isInsideEdgelessEditor, matchModels, } from '../../affine-shared/utils/index.js';
|
|
5
|
+
import { Bound, Point } from '../../global/gfx/index.js';
|
|
6
|
+
import { LifeCycleWatcher } from '../../std/index.js';
|
|
7
|
+
import { GfxControllerIdentifier, SurfaceBlockModel } from '../../std/gfx/index.js';
|
|
8
|
+
const LINKED_DOC = 'affine:embed-linked-doc';
|
|
9
|
+
/** The canvas card's style, the one "Show here" and "Linked doc" insert. */
|
|
10
|
+
const CANVAS_STYLE = 'vertical';
|
|
11
|
+
/** Where the host's `undo` / `redo` ride on the card's undo step. */
|
|
12
|
+
const UNDO_HOOKS = 'labre:page-drop';
|
|
13
|
+
/**
|
|
14
|
+
* Where a dropped page's card goes (labre P7, ADR-0045 §7 amended
|
|
15
|
+
* 2026-10-16), mirroring "Show here" (`fragments/doc-title`, `show-here.ts`):
|
|
16
|
+
*
|
|
17
|
+
* - on a drop line in a note (page view, or a note on the canvas): a block
|
|
18
|
+
* beside the line's block, climbing out of whatever cannot hold a card (a
|
|
19
|
+
* list item, a callout) to the first parent that can;
|
|
20
|
+
* - on the canvas, off any note: a canvas card centred on the drop point,
|
|
21
|
+
* through the CRUD `addBlock`, which stamps the viewer's active layer
|
|
22
|
+
* (ADR 0031 §6), then selected;
|
|
23
|
+
* - in the page view with no line (dropped under the content): the end of
|
|
24
|
+
* the last note.
|
|
25
|
+
*
|
|
26
|
+
* The caller owns the undo step (`captureSync` around it). Returns the new
|
|
27
|
+
* card's id, or `null` when nothing was written (read-only, no root).
|
|
28
|
+
*/
|
|
29
|
+
export function placePageCard(std, pageId, at) {
|
|
30
|
+
const { store } = std;
|
|
31
|
+
if (store.readonly || !store.root || !pageId)
|
|
32
|
+
return null;
|
|
33
|
+
let id = null;
|
|
34
|
+
if (at.line)
|
|
35
|
+
id = insertBeside(store, pageId, at.line);
|
|
36
|
+
else if (at.canvas)
|
|
37
|
+
id = insertOnCanvas(std, pageId, at.point);
|
|
38
|
+
else
|
|
39
|
+
id = insertAtEnd(store, pageId);
|
|
40
|
+
if (id) {
|
|
41
|
+
std.getOptional(TelemetryProvider)?.track('BlockCreated', {
|
|
42
|
+
blockType: LINKED_DOC,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
47
|
+
function insertBeside(store, pageId, line) {
|
|
48
|
+
let model = line.model;
|
|
49
|
+
let placement = line.placement;
|
|
50
|
+
while (model) {
|
|
51
|
+
const parent = store.getParent(model);
|
|
52
|
+
if (!parent)
|
|
53
|
+
return null;
|
|
54
|
+
if (store.schema.safeValidate(LINKED_DOC, parent.flavour)) {
|
|
55
|
+
return (store.addSiblingBlocks(model, [{ flavour: LINKED_DOC, pageId }], placement)[0] ?? null);
|
|
56
|
+
}
|
|
57
|
+
// Out of a list item or a callout: the card goes after the container.
|
|
58
|
+
model = parent;
|
|
59
|
+
placement = 'after';
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function insertAtEnd(store, pageId) {
|
|
64
|
+
const root = store.root;
|
|
65
|
+
if (!root)
|
|
66
|
+
return null;
|
|
67
|
+
const noteId = getLastNoteBlock(store)?.id ?? store.addBlock('affine:note', {}, root.id);
|
|
68
|
+
return store.addBlock(LINKED_DOC, { pageId }, noteId);
|
|
69
|
+
}
|
|
70
|
+
function insertOnCanvas(std, pageId, point) {
|
|
71
|
+
const gfx = std.get(GfxControllerIdentifier);
|
|
72
|
+
const surface = gfx.surface;
|
|
73
|
+
if (!surface)
|
|
74
|
+
return null;
|
|
75
|
+
const xywh = Bound.fromCenter(gfx.viewport.toModelCoordFromClientCoord(point), EMBED_CARD_WIDTH[CANVAS_STYLE], EMBED_CARD_HEIGHT[CANVAS_STYLE]).serialize();
|
|
76
|
+
const id = std
|
|
77
|
+
.get(EdgelessCRUDIdentifier)
|
|
78
|
+
.addBlock(LINKED_DOC, { pageId, xywh, style: CANVAS_STYLE }, surface);
|
|
79
|
+
gfx.selection.set({ elements: [id], editing: false });
|
|
80
|
+
return id;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The drop line under a client point, as the editor's own file drop draws it
|
|
84
|
+
* (`FileDropExtension.dropTarget$`): none on the canvas itself or on a block
|
|
85
|
+
* that sits on it, only inside a note.
|
|
86
|
+
*/
|
|
87
|
+
export function dropLineAt(std, clientX, clientY) {
|
|
88
|
+
const point = new Point(clientX, clientY);
|
|
89
|
+
const element = getClosestBlockComponentByPoint(point);
|
|
90
|
+
if (!element)
|
|
91
|
+
return null;
|
|
92
|
+
const model = element.model;
|
|
93
|
+
if (matchModels(std.store.getParent(model), [SurfaceBlockModel]))
|
|
94
|
+
return null;
|
|
95
|
+
const target = calcDropTarget(point, model, element);
|
|
96
|
+
if (!target)
|
|
97
|
+
return null;
|
|
98
|
+
const placement = target.placement === 'before' ? 'before' : 'after';
|
|
99
|
+
return { model: target.modelState.model, placement };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Hangs the host's `undo` / `redo` on the undo step that holds the card (the
|
|
103
|
+
* last one, the caller having opened it with `captureSync`), so one Mod+Z
|
|
104
|
+
* removes the card AND puts back what the host did. Yjs gives a popped step's
|
|
105
|
+
* twin (the redo step an undo creates, and back) a fresh `meta`: the hooks are
|
|
106
|
+
* carried over at each pop. A step whose card was already gone (removed by
|
|
107
|
+
* another peer) changes nothing, so Yjs skips it and the host's hooks are not
|
|
108
|
+
* called: the page stays where the drop put it, nothing is lost.
|
|
109
|
+
*/
|
|
110
|
+
export function rideUndoStep(store, drop) {
|
|
111
|
+
if (!drop.undo && !drop.redo)
|
|
112
|
+
return;
|
|
113
|
+
store.history.undoManager.undoStack.at(-1)?.meta.set(UNDO_HOOKS, drop);
|
|
114
|
+
}
|
|
115
|
+
/** The `stack-item-popped` half of {@link rideUndoStep}. */
|
|
116
|
+
export function runUndoHooks(store, event) {
|
|
117
|
+
const drop = event.stackItem.meta.get(UNDO_HOOKS);
|
|
118
|
+
if (!drop)
|
|
119
|
+
return;
|
|
120
|
+
const manager = store.history.undoManager;
|
|
121
|
+
const twin = event.type === 'undo' ? manager.redoStack.at(-1) : manager.undoStack.at(-1);
|
|
122
|
+
twin?.meta.set(UNDO_HOOKS, drop);
|
|
123
|
+
if (event.type === 'undo')
|
|
124
|
+
drop.undo?.();
|
|
125
|
+
else
|
|
126
|
+
drop.redo?.();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Drops already placed: an editor nested in another (a synced page's
|
|
130
|
+
* content) sees the same bubbling event as its host, and one drop is one card.
|
|
131
|
+
*/
|
|
132
|
+
const handled = new WeakSet();
|
|
133
|
+
/**
|
|
134
|
+
* The whole drop: ask the host, place the card in one undo step, hang the
|
|
135
|
+
* host's hooks on it. A drop the host turns down, or a card that cannot be
|
|
136
|
+
* placed, writes nothing (the host's own change is undone at once).
|
|
137
|
+
*/
|
|
138
|
+
export function dropPage(std, event, canvas) {
|
|
139
|
+
const { dataTransfer } = event;
|
|
140
|
+
if (!dataTransfer || dataTransfer.files.length > 0)
|
|
141
|
+
return null;
|
|
142
|
+
if (handled.has(event))
|
|
143
|
+
return null;
|
|
144
|
+
if (pageDropVerdict(std, dataTransfer) !== 'accept')
|
|
145
|
+
return null;
|
|
146
|
+
const service = std.getOptional(PageDropProvider);
|
|
147
|
+
if (!service)
|
|
148
|
+
return null;
|
|
149
|
+
const { store } = std;
|
|
150
|
+
const line = dropLineAt(std, event.clientX, event.clientY);
|
|
151
|
+
handled.add(event);
|
|
152
|
+
const drop = service.drop({ dataTransfer, docId: store.id });
|
|
153
|
+
if (!drop)
|
|
154
|
+
return null;
|
|
155
|
+
store.captureSync();
|
|
156
|
+
const id = placePageCard(std, drop.pageId, {
|
|
157
|
+
canvas,
|
|
158
|
+
line,
|
|
159
|
+
point: [event.clientX, event.clientY],
|
|
160
|
+
});
|
|
161
|
+
if (!id) {
|
|
162
|
+
drop.undo?.();
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
rideUndoStep(store, drop);
|
|
166
|
+
store.captureSync();
|
|
167
|
+
return id;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Mounts the page drop on the editor: a native drop the host accepts places
|
|
171
|
+
* the page's card, and the history runs the host's hooks with the card's
|
|
172
|
+
* undo step. Without a `PageDropProvider` nothing changes: `dropPage` returns
|
|
173
|
+
* at the verdict.
|
|
174
|
+
*/
|
|
175
|
+
export class PageDropWatcher extends LifeCycleWatcher {
|
|
176
|
+
constructor() {
|
|
177
|
+
super(...arguments);
|
|
178
|
+
this._onPopped = (event) => runUndoHooks(this.std.store, event);
|
|
179
|
+
}
|
|
180
|
+
static { this.key = 'labre-page-drop-watcher'; }
|
|
181
|
+
mounted() {
|
|
182
|
+
super.mounted();
|
|
183
|
+
const { std } = this;
|
|
184
|
+
std.event.disposables.add(std.event.add('nativeDrop', context => {
|
|
185
|
+
const event = context.get('dndState').raw;
|
|
186
|
+
// Never `return true`: that would stop the dispatch before the file
|
|
187
|
+
// drop's own handler, which clears the drop line it drew.
|
|
188
|
+
if (dropPage(std, event, isInsideEdgelessEditor(std.host))) {
|
|
189
|
+
event.preventDefault();
|
|
190
|
+
}
|
|
191
|
+
}));
|
|
192
|
+
const manager = std.store.history.undoManager;
|
|
193
|
+
manager.on('stack-item-popped', this._onPopped);
|
|
194
|
+
std.event.disposables.add(() => manager.off('stack-item-popped', this._onPopped));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -3,6 +3,7 @@ import { effects } from './effects.js';
|
|
|
3
3
|
import { EdgelessClipboardEmbedLinkedDocConfig, EmbedLinkedDocInteraction, EmbedLinkedDocViewExtensions, } from './embed-linked-doc-block/index.js';
|
|
4
4
|
import { EdgelessClipboardEmbedSyncedDocConfig, EmbedSyncedDocViewExtensions, } from './embed-synced-doc-block/index.js';
|
|
5
5
|
import { EmbedSyncedDocInteraction } from './embed-synced-doc-block/configs/edgeless-interaction.js';
|
|
6
|
+
import { PageDropWatcher } from './page-drop/page-drop.js';
|
|
6
7
|
export class EmbedDocViewExtension extends ViewExtensionProvider {
|
|
7
8
|
constructor() {
|
|
8
9
|
super(...arguments);
|
|
@@ -16,6 +17,8 @@ export class EmbedDocViewExtension extends ViewExtensionProvider {
|
|
|
16
17
|
super.setup(context);
|
|
17
18
|
context.register(EmbedLinkedDocViewExtensions);
|
|
18
19
|
context.register(EmbedSyncedDocViewExtensions);
|
|
20
|
+
// Pages dragged in from the host (PageDropProvider), both views.
|
|
21
|
+
context.register(PageDropWatcher);
|
|
19
22
|
const isEdgeless = this.isEdgeless(context.scope);
|
|
20
23
|
if (isEdgeless) {
|
|
21
24
|
context.register([
|
|
@@ -48,6 +48,17 @@ export declare class FrameTemplateWatcher extends LifeCycleWatcher {
|
|
|
48
48
|
mounted(): void;
|
|
49
49
|
unmounted(): void;
|
|
50
50
|
}
|
|
51
|
+
interface NoticeAction {
|
|
52
|
+
key: string;
|
|
53
|
+
label: string;
|
|
54
|
+
onClick: () => void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The success notification's « View », when the host can show its templates
|
|
58
|
+
* (labre P7): it calls `showTemplates` and nothing else. Absent, the
|
|
59
|
+
* notification has no action, as before 0.54.
|
|
60
|
+
*/
|
|
61
|
+
export declare function templateViewAction(std: BlockStdScope, service: FrameTemplateService): NoticeAction | undefined;
|
|
51
62
|
/**
|
|
52
63
|
* "Save as template": serialize the frame and hand it to the host. Reads the
|
|
53
64
|
* document and writes nothing to it, so a read-only viewer may save too: the
|
|
@@ -4,7 +4,7 @@ import { ConnectorElementModel, } from '../affine-model/index.js';
|
|
|
4
4
|
import { FrameTemplateProvider, NotificationProvider, translateKey, } from '../affine-shared/services/index.js';
|
|
5
5
|
import { LifeCycleWatcher } from '../std/index.js';
|
|
6
6
|
import { GfxBlockElementModel } from '../std/gfx/index.js';
|
|
7
|
-
import { FRAME_TOAST_TEMPLATE_SAVE_FAILED, FRAME_TOAST_TEMPLATE_SAVED, } from './translations.js';
|
|
7
|
+
import { FRAME_TOAST_TEMPLATE_SAVE_FAILED, FRAME_TOAST_TEMPLATE_SAVED, FRAME_TOAST_TEMPLATE_VIEW, } from './translations.js';
|
|
8
8
|
/**
|
|
9
9
|
* Narrow a transformer to one frame's members: the surface keeps only the
|
|
10
10
|
* elements and child blocks in `ids` — the surface transformer's own
|
|
@@ -160,15 +160,35 @@ export class FrameTemplateWatcher extends LifeCycleWatcher {
|
|
|
160
160
|
}
|
|
161
161
|
/** Frames whose save is in flight, per document: a double click saves once. */
|
|
162
162
|
const saving = new Set();
|
|
163
|
-
function tell(std, wording, success) {
|
|
163
|
+
function tell(std, wording, success, action) {
|
|
164
164
|
const text = translateKey(std, ...wording);
|
|
165
165
|
const notification = std.getOptional(NotificationProvider);
|
|
166
166
|
if (notification) {
|
|
167
|
-
notification.notify({
|
|
167
|
+
notification.notify({
|
|
168
|
+
title: text,
|
|
169
|
+
accent: success ? 'success' : 'error',
|
|
170
|
+
...(action ? { actions: [action] } : {}),
|
|
171
|
+
});
|
|
168
172
|
return;
|
|
169
173
|
}
|
|
174
|
+
// The plain toast has no button: without a notification service the
|
|
175
|
+
// action is dropped, and the template is still where the host keeps it.
|
|
170
176
|
toast(std.host, text);
|
|
171
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* The success notification's « View », when the host can show its templates
|
|
180
|
+
* (labre P7): it calls `showTemplates` and nothing else. Absent, the
|
|
181
|
+
* notification has no action, as before 0.54.
|
|
182
|
+
*/
|
|
183
|
+
export function templateViewAction(std, service) {
|
|
184
|
+
if (!service.showTemplates)
|
|
185
|
+
return undefined;
|
|
186
|
+
return {
|
|
187
|
+
key: 'frame-template-view',
|
|
188
|
+
label: translateKey(std, ...FRAME_TOAST_TEMPLATE_VIEW),
|
|
189
|
+
onClick: () => service.showTemplates?.(),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
172
192
|
/**
|
|
173
193
|
* "Save as template": serialize the frame and hand it to the host. Reads the
|
|
174
194
|
* document and writes nothing to it, so a read-only viewer may save too: the
|
|
@@ -195,7 +215,7 @@ export async function saveFrameAsTemplate(std, frame) {
|
|
|
195
215
|
title: snapshot.meta.title,
|
|
196
216
|
snapshot,
|
|
197
217
|
});
|
|
198
|
-
tell(std, FRAME_TOAST_TEMPLATE_SAVED, true);
|
|
218
|
+
tell(std, FRAME_TOAST_TEMPLATE_SAVED, true, templateViewAction(std, service));
|
|
199
219
|
}
|
|
200
220
|
catch (error) {
|
|
201
221
|
console.error(error);
|
|
@@ -41,6 +41,9 @@ export declare const FRAME_TOOLBAR_UNGROUP: ChromeWording;
|
|
|
41
41
|
export declare const FRAME_TOOLBAR_SAVE_AS_TEMPLATE: ChromeWording;
|
|
42
42
|
export declare const FRAME_TOAST_TEMPLATE_SAVED: ChromeWording;
|
|
43
43
|
export declare const FRAME_TOAST_TEMPLATE_SAVE_FAILED: ChromeWording;
|
|
44
|
+
/** The success notification's action, when the host can show its templates
|
|
45
|
+
* (`FrameTemplateService.showTemplates`). */
|
|
46
|
+
export declare const FRAME_TOAST_TEMPLATE_VIEW: ChromeWording;
|
|
44
47
|
export declare const FRAME_TOOLBAR_BACKGROUND: ChromeWording;
|
|
45
48
|
export declare const FRAME_PRESENT_TOOL_TOOLTIP: ChromeWording;
|
|
46
49
|
export declare const FRAME_PRESENT_PREVIOUS: ChromeWording;
|
|
@@ -61,6 +61,12 @@ export const FRAME_TOAST_TEMPLATE_SAVE_FAILED = [
|
|
|
61
61
|
'com.labre.frame.toast.template-save-failed',
|
|
62
62
|
'The frame could not be saved as a template',
|
|
63
63
|
];
|
|
64
|
+
/** The success notification's action, when the host can show its templates
|
|
65
|
+
* (`FrameTemplateService.showTemplates`). */
|
|
66
|
+
export const FRAME_TOAST_TEMPLATE_VIEW = [
|
|
67
|
+
'com.labre.frame.toast.template-view',
|
|
68
|
+
'View',
|
|
69
|
+
];
|
|
64
70
|
export const FRAME_TOOLBAR_BACKGROUND = [
|
|
65
71
|
'com.labre.frame.toolbar.background',
|
|
66
72
|
'Background',
|
|
@@ -132,6 +138,7 @@ export const FRAME_CHROME_WORDINGS = [
|
|
|
132
138
|
FRAME_TOOLBAR_BACKGROUND,
|
|
133
139
|
FRAME_TOAST_TEMPLATE_SAVED,
|
|
134
140
|
FRAME_TOAST_TEMPLATE_SAVE_FAILED,
|
|
141
|
+
FRAME_TOAST_TEMPLATE_VIEW,
|
|
135
142
|
FRAME_PRESENT_TOOL_TOOLTIP,
|
|
136
143
|
FRAME_PRESENT_PREVIOUS,
|
|
137
144
|
FRAME_PRESENT_NEXT,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FrameworkBackgroundElementModel } from '../../../affine-model/index.js';
|
|
1
|
+
import { ColorScheme, FrameworkBackgroundElementModel, } from '../../../affine-model/index.js';
|
|
2
2
|
import { createIdentifier } from '../../../global/di/index.js';
|
|
3
3
|
import { Bound } from '../../../global/gfx/index.js';
|
|
4
4
|
import { GfxBlockElementModel, GfxControllerIdentifier, GfxPrimitiveElementModel, } from '../../../std/gfx/index.js';
|
|
@@ -149,10 +149,16 @@ export function renderCanvasSvg(std) {
|
|
|
149
149
|
* `bound`, one model per pass, each inside a group carrying its markers (ADR
|
|
150
150
|
* 0032 §6), in the canvas' own z-order: a text block is painted at its layer
|
|
151
151
|
* index, between the elements it sits between on screen.
|
|
152
|
+
*
|
|
153
|
+
* Always in the LIGHT scheme, whatever the canvas shows (ADR 0039): the file
|
|
154
|
+
* is printed on white, read back by the SVG importer by its stored colours
|
|
155
|
+
* (rule R33), and a `{ light, dark }` pair painted on its dark side would turn
|
|
156
|
+
* a black stroke white on a white page. The PNG export, a picture of the
|
|
157
|
+
* screen, keeps the scheme in force.
|
|
152
158
|
*/
|
|
153
159
|
function paintSvg(std, renderer, elements, texts, bound) {
|
|
154
160
|
const gfx = std.get(GfxControllerIdentifier);
|
|
155
|
-
return runWithRecordingPath2D(() => {
|
|
161
|
+
return renderer.withColorScheme(ColorScheme.Light, () => runWithRecordingPath2D(() => {
|
|
156
162
|
const { ctx, canvas, serialize, markRoot, markedGroup } = createSvgContext(bound.w, bound.h);
|
|
157
163
|
const rc = new RoughCanvas(canvas);
|
|
158
164
|
markRoot();
|
|
@@ -174,7 +180,7 @@ function paintSvg(std, renderer, elements, texts, bound) {
|
|
|
174
180
|
});
|
|
175
181
|
}
|
|
176
182
|
return { svg: serialize(), bound };
|
|
177
|
-
});
|
|
183
|
+
}));
|
|
178
184
|
}
|
|
179
185
|
/**
|
|
180
186
|
* What an element's group says about it in the file (ADR 0032 §6): its id, its
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TranslationProvider } from '../../affine-shared/services/index.js';
|
|
2
|
+
import { notationColor, } from '../renderer/notation-tint.js';
|
|
2
3
|
import { backgroundColor, backgroundInstanceZoneBand, backgroundInstanceZones, backgroundPlot, backgroundPoint, BROKEN_BACKGROUND_COLOR, DEFAULT_BACKGROUND_SURFACE, warnBrokenBackgroundColor, } from './def.js';
|
|
3
4
|
import { backgroundInVariant, backgroundLabelText, backgroundTexts, backgroundVisible, } from './labels.js';
|
|
4
5
|
/**
|
|
@@ -106,12 +107,15 @@ export function createFrameworkBackgroundRenderer(def) {
|
|
|
106
107
|
const palette = def.chrome?.palette;
|
|
107
108
|
const family = def.chrome?.fontFamily ?? DEFAULT_FONT_FAMILY;
|
|
108
109
|
const surface = def.chrome?.surface ?? DEFAULT_BACKGROUND_SURFACE;
|
|
109
|
-
const
|
|
110
|
+
const declared = (c) => backgroundColor(c, palette);
|
|
110
111
|
const texts = backgroundTexts(def);
|
|
111
112
|
// The DECLARATION of the instance partition — how it stacks, how it is drawn.
|
|
112
113
|
// What it contains is the model's business and is read on every paint.
|
|
113
114
|
const instanceZonesDef = def.instanceZones;
|
|
114
115
|
return (model, ctx, matrix, renderer) => {
|
|
116
|
+
// A board is chrome painted at render time, so on a dark canvas every
|
|
117
|
+
// declared colour goes through the dark notation table (ADR 0039).
|
|
118
|
+
const color = (c, use = 'ink') => notationColor(renderer, declared(c), use);
|
|
115
119
|
const props = model;
|
|
116
120
|
const visible = (prop) => backgroundVisible(prop, props);
|
|
117
121
|
// Which READING of the frame this instance is showing. Washes, zones and
|
|
@@ -175,7 +179,7 @@ export function createFrameworkBackgroundRenderer(def) {
|
|
|
175
179
|
// neither its fill nor its frame is painted.
|
|
176
180
|
const carded = cardPath();
|
|
177
181
|
if (carded && surface.fill) {
|
|
178
|
-
ctx.fillStyle = color(surface.fill);
|
|
182
|
+
ctx.fillStyle = color(surface.fill, 'fill');
|
|
179
183
|
ctx.fill();
|
|
180
184
|
}
|
|
181
185
|
// The side bands sit BETWEEN the fill and the border: a band is part of the
|
|
@@ -194,7 +198,7 @@ export function createFrameworkBackgroundRenderer(def) {
|
|
|
194
198
|
if (thickness <= 0)
|
|
195
199
|
continue;
|
|
196
200
|
if (band.fill) {
|
|
197
|
-
ctx.fillStyle = color(band.fill);
|
|
201
|
+
ctx.fillStyle = color(band.fill, 'fill');
|
|
198
202
|
if (top)
|
|
199
203
|
ctx.fillRect(0, 0, w, thickness);
|
|
200
204
|
else
|
|
@@ -236,7 +240,7 @@ export function createFrameworkBackgroundRenderer(def) {
|
|
|
236
240
|
if (!visible(wash.visibleProp))
|
|
237
241
|
continue;
|
|
238
242
|
const gradient = ctx.createLinearGradient(x0, 0, x1, 0);
|
|
239
|
-
const hex = color(wash.color);
|
|
243
|
+
const hex = color(wash.color, 'fill');
|
|
240
244
|
for (const [offset, alpha] of wash.stops) {
|
|
241
245
|
gradient.addColorStop(offset, rgba(hex, alpha));
|
|
242
246
|
}
|
|
@@ -252,7 +256,7 @@ export function createFrameworkBackgroundRenderer(def) {
|
|
|
252
256
|
continue;
|
|
253
257
|
if (!visible(zone.fillVisibleProp))
|
|
254
258
|
continue;
|
|
255
|
-
ctx.fillStyle = color(zone.fill);
|
|
259
|
+
ctx.fillStyle = color(zone.fill, 'fill');
|
|
256
260
|
ctx.fillRect(x0 + zone.rect.x * pw, y0 + zone.rect.y * ph, zone.rect.w * pw, zone.rect.h * ph);
|
|
257
261
|
}
|
|
258
262
|
// The partition THIS element carries, resolved once per paint: alone on
|
|
@@ -4,6 +4,7 @@ export { SurfaceElementModel, SurfaceGroupLikeModel, } from './element-model/bas
|
|
|
4
4
|
export { CanvasElementType } from './element-model/index.js';
|
|
5
5
|
export { CanvasRenderer } from './renderer/canvas-renderer.js';
|
|
6
6
|
export { DomRenderer } from './renderer/dom-renderer.js';
|
|
7
|
+
export * from './renderer/notation-tint.js';
|
|
7
8
|
export { isPainted } from './renderer/paint-predicate.js';
|
|
8
9
|
export { ElementHighlightOverlay } from './renderer/element-highlight-overlay.js';
|
|
9
10
|
export type { ElementRenderer } from './renderer/elements/index.js';
|
|
@@ -6,6 +6,7 @@ export { SurfaceElementModel, SurfaceGroupLikeModel, } from './element-model/bas
|
|
|
6
6
|
export { CanvasElementType } from './element-model/index.js';
|
|
7
7
|
export { CanvasRenderer } from './renderer/canvas-renderer.js';
|
|
8
8
|
export { DomRenderer } from './renderer/dom-renderer.js';
|
|
9
|
+
export * from './renderer/notation-tint.js';
|
|
9
10
|
export { isPainted } from './renderer/paint-predicate.js';
|
|
10
11
|
export { ElementHighlightOverlay } from './renderer/element-highlight-overlay.js';
|
|
11
12
|
export * from './renderer/elements/type.js';
|
|
@@ -5,12 +5,14 @@ import type { GfxLocalElementModel, GridManager, LayerManager, SurfaceBlockModel
|
|
|
5
5
|
import { Subject } from 'rxjs';
|
|
6
6
|
import type { SurfaceElementModel } from '../element-model/base.js';
|
|
7
7
|
import { RoughCanvas } from '../utils/rough/canvas.js';
|
|
8
|
+
import { type NotationColorUse, NotationTint } from './notation-tint.js';
|
|
8
9
|
import type { Overlay } from './overlay.js';
|
|
9
10
|
type EnvProvider = {
|
|
10
11
|
generateColorProperty: (color: Color, fallback?: Color) => string;
|
|
11
12
|
getColorScheme: () => ColorScheme;
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
/** `theme` absent: the scheme in force. */
|
|
14
|
+
getColorValue: (color: Color, fallback?: Color, real?: boolean, theme?: ColorScheme) => string;
|
|
15
|
+
getPropertyValue: (property: string, theme?: ColorScheme) => string;
|
|
14
16
|
selectedElements?: () => string[];
|
|
15
17
|
};
|
|
16
18
|
type RendererOptions = {
|
|
@@ -96,6 +98,19 @@ export declare class CanvasRenderer {
|
|
|
96
98
|
}>;
|
|
97
99
|
usePlaceholder: boolean;
|
|
98
100
|
viewport: Viewport;
|
|
101
|
+
private readonly _surface;
|
|
102
|
+
/** Set by {@link withColorScheme} for the length of one paint. */
|
|
103
|
+
private _schemeOverride;
|
|
104
|
+
/** Built on the first dark paint, from the registered framework entries. */
|
|
105
|
+
private _darkTint;
|
|
106
|
+
private _notationTint;
|
|
107
|
+
/**
|
|
108
|
+
* The dark notation table while a NOTATION element is being painted on a
|
|
109
|
+
* dark canvas, `null` otherwise (light scheme, a neutral element, outside a
|
|
110
|
+
* paint). Painters read it through `notationColor` and
|
|
111
|
+
* {@link getColorValue}; see `notation-tint.ts` and ADR 0039.
|
|
112
|
+
*/
|
|
113
|
+
get notationTint(): NotationTint | null;
|
|
99
114
|
get stackingCanvas(): HTMLCanvasElement[];
|
|
100
115
|
constructor(options: RendererOptions);
|
|
101
116
|
/**
|
|
@@ -144,8 +159,45 @@ export declare class CanvasRenderer {
|
|
|
144
159
|
*/
|
|
145
160
|
renderBoundTo(ctx: CanvasRenderingContext2D, rc: RoughCanvas, bound: IBound, surfaceElements?: SurfaceElementModel[]): void;
|
|
146
161
|
getColorScheme(): ColorScheme;
|
|
147
|
-
|
|
162
|
+
/**
|
|
163
|
+
* A stored colour, resolved for the scheme in force.
|
|
164
|
+
*
|
|
165
|
+
* While a notation element is painted on a dark canvas, a PLAIN stored value
|
|
166
|
+
* (a string: what every framework writes) goes through the dark notation
|
|
167
|
+
* table as `use`; a `{ light, dark }` pair already knows its dark side and
|
|
168
|
+
* is never tinted, nor is a fallback (ADR 0039).
|
|
169
|
+
*/
|
|
170
|
+
getColorValue(color: Color, fallback?: Color, real?: boolean, use?: NotationColorUse): string;
|
|
171
|
+
/**
|
|
172
|
+
* The colour of words drawn on a fill of the same element: tinted like any
|
|
173
|
+
* ink, unless the fill is painted as stored, in which case the words keep
|
|
174
|
+
* the colour they were chosen for on it ("ink follows its paper", ADR 0039).
|
|
175
|
+
* `fill` is `null` when the element draws no fill.
|
|
176
|
+
*/
|
|
177
|
+
getInkColorValue(color: Color, fallback: Color, fill: Color | null): string;
|
|
148
178
|
getPropertyValue(property: string): string;
|
|
179
|
+
/**
|
|
180
|
+
* Paint with `scheme` whatever the canvas shows. The SVG export paints
|
|
181
|
+
* light: a file is printed on white and read back by colour (ADR 0039).
|
|
182
|
+
*/
|
|
183
|
+
withColorScheme<T>(scheme: ColorScheme, paint: () => T): T;
|
|
184
|
+
/**
|
|
185
|
+
* "Ink follows its paper" for words that are elements of their own (a C4
|
|
186
|
+
* title, an Event Storming label): text with no fill of its own, drawn on
|
|
187
|
+
* the topmost filled element under it that keeps its stored fill, keeps its
|
|
188
|
+
* stored colour too (ADR 0039). `papers` are the filled elements painted
|
|
189
|
+
* before it in this pass, in z-order.
|
|
190
|
+
*/
|
|
191
|
+
private _sitsOnKeptPaper;
|
|
192
|
+
/** The dark table when this pass paints dark, else `null`. */
|
|
193
|
+
private _tintForPass;
|
|
194
|
+
/**
|
|
195
|
+
* Whether an element is part of a notation, read off the document as the
|
|
196
|
+
* colour carousel reads it (ADR 0027): its own role or its being a board,
|
|
197
|
+
* else (a connector) a role at either end, else a framework board it sits
|
|
198
|
+
* inside. A neutral element anywhere else is painted exactly as stored.
|
|
199
|
+
*/
|
|
200
|
+
private _isNotation;
|
|
149
201
|
getDebugMetrics(): CanvasRendererDebugMetrics;
|
|
150
202
|
resetDebugMetrics(): void;
|
|
151
203
|
refresh(target?: RefreshTarget): void;
|