@formicoidea/labre-core 0.39.1 → 0.40.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-callout/emoji-margin.js +19 -11
- package/dist/_pkgs/affine-block-list/list-block.d.ts +8 -1
- package/dist/_pkgs/affine-block-list/list-block.js +27 -17
- package/dist/_pkgs/affine-block-note/configs/tooltips.d.ts +16 -0
- package/dist/_pkgs/affine-block-note/configs/tooltips.js +99 -66
- package/dist/_pkgs/affine-block-paragraph/paragraph-block.d.ts +8 -1
- package/dist/_pkgs/affine-block-paragraph/paragraph-block.js +30 -15
- package/dist/_pkgs/affine-block-paragraph/styles.js +30 -83
- package/dist/_pkgs/affine-block-paragraph/turbo/paragraph-layout-handler.js +1 -0
- package/dist/_pkgs/affine-block-paragraph/turbo/paragraph-painter.worker.d.ts +2 -0
- package/dist/_pkgs/affine-block-paragraph/turbo/paragraph-painter.worker.js +6 -1
- package/dist/_pkgs/affine-block-root/edgeless/clipboard/clipboard.js +3 -3
- package/dist/_pkgs/affine-block-root/keyboard/keymap.js +20 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.d.ts +6 -4
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +15 -10
- package/dist/_pkgs/affine-block-surface/framework-background/def.d.ts +4 -1
- package/dist/_pkgs/affine-block-surface/framework-background/def.js +6 -2
- package/dist/_pkgs/affine-block-surface/utils/priority-queue.js +2 -2
- package/dist/_pkgs/affine-components/toggle-button/toggle-button.d.ts +5 -0
- package/dist/_pkgs/affine-components/toggle-button/toggle-button.js +31 -18
- package/dist/_pkgs/affine-gfx-template/builtin/other.js +31 -14
- package/dist/_pkgs/affine-inline-preset/markdown.d.ts +3 -0
- package/dist/_pkgs/affine-inline-preset/markdown.js +19 -0
- package/dist/_pkgs/affine-shared/adapters/middlewares/proxy.d.ts +10 -0
- package/dist/_pkgs/affine-shared/adapters/middlewares/proxy.js +19 -12
- package/dist/_pkgs/affine-shared/adapters/utils/fetch.js +4 -0
- package/dist/_pkgs/affine-shared/consts/heading.d.ts +29 -0
- package/dist/_pkgs/affine-shared/consts/heading.js +70 -0
- package/dist/_pkgs/affine-shared/consts/index.d.ts +2 -0
- package/dist/_pkgs/affine-shared/consts/index.js +2 -0
- package/dist/_pkgs/affine-shared/consts/notation.d.ts +67 -0
- package/dist/_pkgs/affine-shared/consts/notation.js +65 -0
- package/dist/_pkgs/std/gfx/model/surface/element-model.d.ts +2 -2
- package/dist/_pkgs/std/gfx/model/surface/element-model.js +2 -2
- package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +1 -1
- package/dist/_pkgs/std/gfx/model/surface/surface-model.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,32 @@
|
|
|
1
|
+
import { HEADING_LEVELS, HEADING_SCALE } from '../affine-shared/consts/index.js';
|
|
1
2
|
import { unsafeCSSVarV2 } from '../affine-shared/theme/index.js';
|
|
2
|
-
import { css } from 'lit';
|
|
3
|
+
import { css, unsafeCSS } from 'lit';
|
|
4
|
+
/** Inline code is set this much smaller than the text around it. */
|
|
5
|
+
const INLINE_CODE_SHRINK_PX = 3;
|
|
6
|
+
/**
|
|
7
|
+
* H1…H6, generated from `HEADING_SCALE` so every size, line box and margin has
|
|
8
|
+
* one source. Inline code in a heading stays `INLINE_CODE_SHRINK_PX` below the
|
|
9
|
+
* heading's size; H6, the level closest to body text, keeps the body's code
|
|
10
|
+
* padding (with its 2px bottom).
|
|
11
|
+
*/
|
|
12
|
+
const headingStyles = unsafeCSS(HEADING_LEVELS.map(level => {
|
|
13
|
+
const { fontSize, fontWeight, letterSpacing, lineHeightExtra, marginTop } = HEADING_SCALE[level];
|
|
14
|
+
return `
|
|
15
|
+
.${level} {
|
|
16
|
+
font-size: ${fontSize}px;
|
|
17
|
+
font-weight: ${fontWeight};
|
|
18
|
+
letter-spacing: ${letterSpacing}em;
|
|
19
|
+
line-height: calc(1em + ${lineHeightExtra}px);
|
|
20
|
+
margin-top: ${marginTop}px;
|
|
21
|
+
margin-bottom: 10px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.${level} code {
|
|
25
|
+
font-size: ${fontSize - INLINE_CODE_SHRINK_PX}px;
|
|
26
|
+
padding: ${level === 'h6' ? '0px 4px 2px' : '0px 4px'};
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
}).join(''));
|
|
3
30
|
export const paragraphBlockStyles = css `
|
|
4
31
|
affine-paragraph {
|
|
5
32
|
box-sizing: border-box;
|
|
@@ -21,91 +48,11 @@ export const paragraphBlockStyles = css `
|
|
|
21
48
|
}
|
|
22
49
|
|
|
23
50
|
affine-paragraph code {
|
|
24
|
-
font-size: calc(var(--affine-font-base) -
|
|
51
|
+
font-size: calc(var(--affine-font-base) - ${INLINE_CODE_SHRINK_PX}px);
|
|
25
52
|
padding: 0px 4px 2px;
|
|
26
53
|
}
|
|
27
54
|
|
|
28
|
-
|
|
29
|
-
font-size: var(--affine-font-h-1);
|
|
30
|
-
font-weight: 700;
|
|
31
|
-
letter-spacing: -0.02em;
|
|
32
|
-
line-height: calc(1em + 8px);
|
|
33
|
-
margin-top: 18px;
|
|
34
|
-
margin-bottom: 10px;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.h1 code {
|
|
38
|
-
font-size: calc(var(--affine-font-base) + 10px);
|
|
39
|
-
padding: 0px 4px;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.h2 {
|
|
43
|
-
font-size: var(--affine-font-h-2);
|
|
44
|
-
font-weight: 600;
|
|
45
|
-
letter-spacing: -0.02em;
|
|
46
|
-
line-height: calc(1em + 10px);
|
|
47
|
-
margin-top: 14px;
|
|
48
|
-
margin-bottom: 10px;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.h2 code {
|
|
52
|
-
font-size: calc(var(--affine-font-base) + 8px);
|
|
53
|
-
padding: 0px 4px;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.h3 {
|
|
57
|
-
font-size: var(--affine-font-h-3);
|
|
58
|
-
font-weight: 600;
|
|
59
|
-
letter-spacing: -0.02em;
|
|
60
|
-
line-height: calc(1em + 8px);
|
|
61
|
-
margin-top: 12px;
|
|
62
|
-
margin-bottom: 10px;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.h3 code {
|
|
66
|
-
font-size: calc(var(--affine-font-base) + 6px);
|
|
67
|
-
padding: 0px 4px;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.h4 {
|
|
71
|
-
font-size: var(--affine-font-h-4);
|
|
72
|
-
font-weight: 600;
|
|
73
|
-
letter-spacing: -0.015em;
|
|
74
|
-
line-height: calc(1em + 8px);
|
|
75
|
-
margin-top: 12px;
|
|
76
|
-
margin-bottom: 10px;
|
|
77
|
-
}
|
|
78
|
-
.h4 code {
|
|
79
|
-
font-size: calc(var(--affine-font-base) + 4px);
|
|
80
|
-
padding: 0px 4px;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.h5 {
|
|
84
|
-
font-size: var(--affine-font-h-5);
|
|
85
|
-
font-weight: 600;
|
|
86
|
-
letter-spacing: -0.015em;
|
|
87
|
-
line-height: calc(1em + 8px);
|
|
88
|
-
margin-top: 12px;
|
|
89
|
-
margin-bottom: 10px;
|
|
90
|
-
}
|
|
91
|
-
.h5 code {
|
|
92
|
-
font-size: calc(var(--affine-font-base) + 2px);
|
|
93
|
-
padding: 0px 4px;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.h6 {
|
|
97
|
-
font-size: var(--affine-font-h-6);
|
|
98
|
-
font-weight: 600;
|
|
99
|
-
letter-spacing: -0.015em;
|
|
100
|
-
line-height: calc(1em + 8px);
|
|
101
|
-
margin-top: 12px;
|
|
102
|
-
margin-bottom: 10px;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.h6 code {
|
|
106
|
-
font-size: var(--affine-font-base);
|
|
107
|
-
padding: 0px 4px 2px;
|
|
108
|
-
}
|
|
55
|
+
${headingStyles}
|
|
109
56
|
|
|
110
57
|
.quote {
|
|
111
58
|
line-height: 26px;
|
|
@@ -19,6 +19,7 @@ export class ParagraphLayoutHandlerExtension extends BlockLayoutHandlerExtension
|
|
|
19
19
|
const { zoom, viewScale } = viewportRecord;
|
|
20
20
|
const paragraph = {
|
|
21
21
|
type: 'affine:paragraph',
|
|
22
|
+
paragraphType: model.props.type,
|
|
22
23
|
sentences: [],
|
|
23
24
|
blockId: model.id,
|
|
24
25
|
rect: { x: 0, y: 0, w: 0, h: 0 },
|
|
@@ -6,6 +6,8 @@ interface SentenceLayout {
|
|
|
6
6
|
}
|
|
7
7
|
export interface ParagraphLayout extends BlockLayout {
|
|
8
8
|
type: 'affine:paragraph';
|
|
9
|
+
/** The paragraph block's own `props.type`: `text`, `quote`, `h1`…`h6`. */
|
|
10
|
+
paragraphType: string;
|
|
9
11
|
sentences: SentenceLayout[];
|
|
10
12
|
}
|
|
11
13
|
export declare const ParagraphLayoutPainterExtension: import("../../store/index.js").ExtensionType;
|
|
@@ -39,12 +39,17 @@ class ParagraphLayoutPainter {
|
|
|
39
39
|
console.warn('Expected paragraph layout but received different format:', layout);
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
+
// Headings are not painted (TODO: fine-tune the baseline for heading
|
|
43
|
+
// sizes). Skipped on the block TYPE, not on the font size: H6 is set at
|
|
44
|
+
// the body's 15px (`HEADING_SCALE`), so a size test would paint it as text.
|
|
45
|
+
if (layout.paragraphType.startsWith('h'))
|
|
46
|
+
return;
|
|
42
47
|
const renderedPositions = new Set();
|
|
43
48
|
layout.sentences.forEach(sentence => {
|
|
44
49
|
const fontSize = sentence.fontSize;
|
|
45
50
|
const baselineY = getBaseline(fontSize);
|
|
46
51
|
if (fontSize !== 15)
|
|
47
|
-
return; //
|
|
52
|
+
return; // the baseline is tuned for body text only
|
|
48
53
|
ctx.font = `${fontSize}px Inter`;
|
|
49
54
|
ctx.strokeStyle = 'yellow';
|
|
50
55
|
sentence.rects.forEach(textRect => {
|
|
@@ -4,7 +4,7 @@ import { addImages } from '../../../affine-block-image/index.js';
|
|
|
4
4
|
import { CanvasRenderer, DefaultTool, EdgelessCRUDIdentifier, ExportManager, getSurfaceComponent, } from '../../../affine-block-surface/index.js';
|
|
5
5
|
import { splitIntoLines } from '../../../affine-gfx-text/index.js';
|
|
6
6
|
import { BookmarkStyles, DEFAULT_NOTE_HEIGHT, DEFAULT_NOTE_WIDTH, FrameBlockModel, MAX_IMAGE_WIDTH, } from '../../../affine-model/index.js';
|
|
7
|
-
import { ClipboardAdapter, decodeClipboardBlobs, } from '../../../affine-shared/adapters/index.js';
|
|
7
|
+
import { ClipboardAdapter, decodeClipboardBlobs, ImageProxyService, } from '../../../affine-shared/adapters/index.js';
|
|
8
8
|
import { CANVAS_EXPORT_IGNORE_TAGS, EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../../../affine-shared/consts/index.js';
|
|
9
9
|
import { EmbedOptionProvider, ParseDocUrlProvider, TelemetryProvider, } from '../../../affine-shared/services/index.js';
|
|
10
10
|
import { convertToPng, isInsidePageEditor, isTopLevelBlock, isUrlInClipboard, matchModels, referenceToNode, } from '../../../affine-shared/utils/index.js';
|
|
@@ -324,7 +324,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
|
|
324
324
|
}
|
|
325
325
|
ctx.scale(dpr, dpr);
|
|
326
326
|
const replaceImgSrcWithSvg = this._exportManager?.replaceImgSrcWithSvg;
|
|
327
|
-
const imageProxy = host.std.
|
|
327
|
+
const imageProxy = host.std.get(ImageProxyService).imageProxyURL;
|
|
328
328
|
const html2canvasOption = {
|
|
329
329
|
ignoreElements: function (element) {
|
|
330
330
|
if (CANVAS_EXPORT_IGNORE_TAGS.includes(element.tagName) ||
|
|
@@ -351,7 +351,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
|
|
351
351
|
await replaceImgSrcWithSvg?.(element);
|
|
352
352
|
},
|
|
353
353
|
backgroundColor: 'transparent',
|
|
354
|
-
useCORS: imageProxy
|
|
354
|
+
useCORS: !imageProxy,
|
|
355
355
|
proxy: imageProxy,
|
|
356
356
|
};
|
|
357
357
|
const _drawTopLevelBlock = async (block, isInFrame = false) => {
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
import { KeymapExtension } from '../../std/index.js';
|
|
2
|
+
const NATIVE_FOCUSABLE_SELECTOR = 'button, a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
3
|
+
/**
|
|
4
|
+
* The editor host swallows Tab and Shift-Tab so that indentation stays under
|
|
5
|
+
* the control of the block-scoped handlers. That would however trap the focus
|
|
6
|
+
* on the native controls the editor renders (the collapse button of headings
|
|
7
|
+
* and lists, for instance), which then could neither be reached nor left with
|
|
8
|
+
* the keyboard. When the event originates from such a control — and not from
|
|
9
|
+
* editable text — the native tabbing behaviour is let through.
|
|
10
|
+
*/
|
|
11
|
+
const isNativeFocusableTarget = (target) => {
|
|
12
|
+
if (!(target instanceof Element))
|
|
13
|
+
return false;
|
|
14
|
+
if (target instanceof HTMLElement && target.isContentEditable)
|
|
15
|
+
return false;
|
|
16
|
+
return !!target.closest(NATIVE_FOCUSABLE_SELECTOR);
|
|
17
|
+
};
|
|
2
18
|
export const fallbackKeymap = KeymapExtension(() => {
|
|
3
19
|
return {
|
|
4
20
|
Tab: ctx => {
|
|
5
21
|
const event = ctx.get('defaultState').event;
|
|
22
|
+
if (isNativeFocusableTarget(event.target))
|
|
23
|
+
return;
|
|
6
24
|
event.stopPropagation();
|
|
7
25
|
event.preventDefault();
|
|
8
26
|
},
|
|
9
27
|
'Shift-Tab': ctx => {
|
|
10
28
|
const event = ctx.get('defaultState').event;
|
|
29
|
+
if (isNativeFocusableTarget(event.target))
|
|
30
|
+
return;
|
|
11
31
|
event.stopPropagation();
|
|
12
32
|
event.preventDefault();
|
|
13
33
|
},
|
|
@@ -3,12 +3,14 @@ import { type BlockStdScope, type EditorHost } from '../../../std/index.js';
|
|
|
3
3
|
import { GfxBlockElementModel, type GfxController, GfxPrimitiveElementModel } from '../../../std/gfx/index.js';
|
|
4
4
|
import type { ExtensionType, Store } from '../../../store/index.js';
|
|
5
5
|
import { CanvasRenderer } from '../../renderer/canvas-renderer.js';
|
|
6
|
-
export type ExportOptions = {
|
|
7
|
-
imageProxyEndpoint: string;
|
|
8
|
-
};
|
|
9
6
|
export declare class ExportManager {
|
|
10
7
|
readonly std: BlockStdScope;
|
|
11
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The image proxy every remote-image fetch of the export goes through —
|
|
10
|
+
* resolved from {@link ImageProxyService}, the one host seam for it, never
|
|
11
|
+
* from a local constant. Empty means « fetch direct » (issue #258).
|
|
12
|
+
*/
|
|
13
|
+
private get _imageProxyURL();
|
|
12
14
|
replaceImgSrcWithSvg: (element: HTMLElement) => Promise<void>;
|
|
13
15
|
get doc(): Store;
|
|
14
16
|
get editorHost(): EditorHost;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ImageBlockModel } from '../../../affine-model/index.js';
|
|
2
|
-
import { FetchUtils } from '../../../affine-shared/adapters/index.js';
|
|
3
|
-
import { CANVAS_EXPORT_IGNORE_TAGS
|
|
2
|
+
import { FetchUtils, ImageProxyService } from '../../../affine-shared/adapters/index.js';
|
|
3
|
+
import { CANVAS_EXPORT_IGNORE_TAGS } from '../../../affine-shared/consts/index.js';
|
|
4
4
|
import { isInsidePageEditor, matchModels } from '../../../affine-shared/utils/index.js';
|
|
5
5
|
import { BlockSuiteError, ErrorCode } from '../../../global/exceptions/index.js';
|
|
6
6
|
import { deserializeXYWH } from '../../../global/gfx/index.js';
|
|
@@ -10,6 +10,14 @@ import { CanvasRenderer } from '../../renderer/canvas-renderer.js';
|
|
|
10
10
|
import { getBgGridGap } from '../../utils/get-bg-grip-gap.js';
|
|
11
11
|
import { FileExporter } from './file-exporter.js';
|
|
12
12
|
export class ExportManager {
|
|
13
|
+
/**
|
|
14
|
+
* The image proxy every remote-image fetch of the export goes through —
|
|
15
|
+
* resolved from {@link ImageProxyService}, the one host seam for it, never
|
|
16
|
+
* from a local constant. Empty means « fetch direct » (issue #258).
|
|
17
|
+
*/
|
|
18
|
+
get _imageProxyURL() {
|
|
19
|
+
return this.std.get(ImageProxyService).imageProxyURL;
|
|
20
|
+
}
|
|
13
21
|
get doc() {
|
|
14
22
|
return this.std.store;
|
|
15
23
|
}
|
|
@@ -18,14 +26,11 @@ export class ExportManager {
|
|
|
18
26
|
}
|
|
19
27
|
constructor(std) {
|
|
20
28
|
this.std = std;
|
|
21
|
-
this._exportOptions = {
|
|
22
|
-
imageProxyEndpoint: DEFAULT_IMAGE_PROXY_ENDPOINT,
|
|
23
|
-
};
|
|
24
29
|
this.replaceImgSrcWithSvg = async (element) => {
|
|
25
30
|
const imgList = Array.from(element.querySelectorAll('img'));
|
|
26
31
|
// Create an array of promises
|
|
27
32
|
const promises = imgList.map(img => {
|
|
28
|
-
return FetchUtils.fetchImage(img.src, undefined, this.
|
|
33
|
+
return FetchUtils.fetchImage(img.src, undefined, this._imageProxyURL)
|
|
29
34
|
.then(response => response && response.blob())
|
|
30
35
|
.then(async (blob) => {
|
|
31
36
|
if (!blob)
|
|
@@ -159,8 +164,8 @@ export class ExportManager {
|
|
|
159
164
|
x: pageLeft - viewport.left,
|
|
160
165
|
width: pageWidth,
|
|
161
166
|
height: viewportHeight,
|
|
162
|
-
useCORS: this.
|
|
163
|
-
proxy: this.
|
|
167
|
+
useCORS: !this._imageProxyURL,
|
|
168
|
+
proxy: this._imageProxyURL,
|
|
164
169
|
};
|
|
165
170
|
let data;
|
|
166
171
|
try {
|
|
@@ -228,8 +233,8 @@ export class ExportManager {
|
|
|
228
233
|
});
|
|
229
234
|
await this.replaceImgSrcWithSvg(element);
|
|
230
235
|
},
|
|
231
|
-
useCORS: this.
|
|
232
|
-
proxy: this.
|
|
236
|
+
useCORS: !this._imageProxyURL,
|
|
237
|
+
proxy: this._imageProxyURL,
|
|
233
238
|
};
|
|
234
239
|
let data;
|
|
235
240
|
try {
|
|
@@ -494,7 +494,10 @@ export interface FrameworkBackgroundDef {
|
|
|
494
494
|
transitionBandWidth?: Ratio;
|
|
495
495
|
chrome?: BackgroundChromeDef;
|
|
496
496
|
}
|
|
497
|
-
/**
|
|
497
|
+
/**
|
|
498
|
+
* The default card: a plain rectangle in the shared notation scale's card
|
|
499
|
+
* fill, no border, no radius.
|
|
500
|
+
*/
|
|
498
501
|
export declare const DEFAULT_BACKGROUND_SURFACE: BackgroundSurfaceDef;
|
|
499
502
|
/** The plot rectangle of a background of size `w × h`, in element-local units. */
|
|
500
503
|
export declare function backgroundPlot(def: FrameworkBackgroundDef, w: number, h: number): {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { NOTATION_NEUTRALS } from '../../affine-shared/consts/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The default card: a plain rectangle in the shared notation scale's card
|
|
4
|
+
* fill, no border, no radius.
|
|
5
|
+
*/
|
|
2
6
|
export const DEFAULT_BACKGROUND_SURFACE = {
|
|
3
|
-
fill:
|
|
7
|
+
fill: NOTATION_NEUTRALS.cardFill,
|
|
4
8
|
};
|
|
5
9
|
/** The plot rectangle of a background of size `w × h`, in element-local units. */
|
|
6
10
|
export function backgroundPlot(def, w, h) {
|
|
@@ -21,9 +21,9 @@ export class PriorityQueue {
|
|
|
21
21
|
if (rightChildIndex < length) {
|
|
22
22
|
leftChild = this.heap[leftChildIndex];
|
|
23
23
|
rightChild = this.heap[rightChildIndex];
|
|
24
|
-
if ((swap ===
|
|
24
|
+
if ((swap === -1 &&
|
|
25
25
|
this._compare(rightChild.priority, element.priority) < 0) ||
|
|
26
|
-
(swap !==
|
|
26
|
+
(swap !== -1 &&
|
|
27
27
|
this._compare(rightChild.priority, leftChild.priority) < 0)) {
|
|
28
28
|
swap = rightChildIndex;
|
|
29
29
|
}
|
|
@@ -6,6 +6,11 @@ export declare class ToggleButton extends ToggleButton_base {
|
|
|
6
6
|
render(): import("lit-html").TemplateResult<1>;
|
|
7
7
|
accessor collapsed: boolean;
|
|
8
8
|
accessor updateCollapsed: (collapsed: boolean) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Id of the children container this button expands and collapses,
|
|
11
|
+
* exposed to assistive technologies through `aria-controls`.
|
|
12
|
+
*/
|
|
13
|
+
accessor controls: string;
|
|
9
14
|
}
|
|
10
15
|
declare global {
|
|
11
16
|
interface HTMLElementTagNameMap {
|
|
@@ -48,13 +48,18 @@ let ToggleButton = (() => {
|
|
|
48
48
|
let _updateCollapsed_decorators;
|
|
49
49
|
let _updateCollapsed_initializers = [];
|
|
50
50
|
let _updateCollapsed_extraInitializers = [];
|
|
51
|
+
let _controls_decorators;
|
|
52
|
+
let _controls_initializers = [];
|
|
53
|
+
let _controls_extraInitializers = [];
|
|
51
54
|
return class ToggleButton extends _classSuper {
|
|
52
55
|
static {
|
|
53
56
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
54
57
|
_collapsed_decorators = [property({ attribute: false })];
|
|
55
58
|
_updateCollapsed_decorators = [property({ attribute: false })];
|
|
59
|
+
_controls_decorators = [property({ attribute: false })];
|
|
56
60
|
__esDecorate(this, null, _collapsed_decorators, { kind: "accessor", name: "collapsed", static: false, private: false, access: { has: obj => "collapsed" in obj, get: obj => obj.collapsed, set: (obj, value) => { obj.collapsed = value; } }, metadata: _metadata }, _collapsed_initializers, _collapsed_extraInitializers);
|
|
57
61
|
__esDecorate(this, null, _updateCollapsed_decorators, { kind: "accessor", name: "updateCollapsed", static: false, private: false, access: { has: obj => "updateCollapsed" in obj, get: obj => obj.updateCollapsed, set: (obj, value) => { obj.updateCollapsed = value; } }, metadata: _metadata }, _updateCollapsed_initializers, _updateCollapsed_extraInitializers);
|
|
62
|
+
__esDecorate(this, null, _controls_decorators, { kind: "accessor", name: "controls", static: false, private: false, access: { has: obj => "controls" in obj, get: obj => obj.controls, set: (obj, value) => { obj.controls = value; } }, metadata: _metadata }, _controls_initializers, _controls_extraInitializers);
|
|
58
63
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
59
64
|
}
|
|
60
65
|
static { this.styles = css `
|
|
@@ -63,6 +68,11 @@ let ToggleButton = (() => {
|
|
|
63
68
|
align-items: start;
|
|
64
69
|
justify-content: start;
|
|
65
70
|
position: absolute;
|
|
71
|
+
padding: 0;
|
|
72
|
+
border: 0;
|
|
73
|
+
color: inherit;
|
|
74
|
+
background: transparent;
|
|
75
|
+
font: inherit;
|
|
66
76
|
width: 16px;
|
|
67
77
|
height: 16px;
|
|
68
78
|
top: calc((1em - 16px) / 2 + 5px);
|
|
@@ -78,6 +88,11 @@ let ToggleButton = (() => {
|
|
|
78
88
|
background: var(--affine-hover-color);
|
|
79
89
|
}
|
|
80
90
|
|
|
91
|
+
.toggle-icon:focus-visible {
|
|
92
|
+
opacity: 1;
|
|
93
|
+
outline: 1px solid var(--affine-primary-color);
|
|
94
|
+
}
|
|
95
|
+
|
|
81
96
|
.toggle-icon[data-collapsed='true'] {
|
|
82
97
|
opacity: 1;
|
|
83
98
|
}
|
|
@@ -100,32 +115,23 @@ let ToggleButton = (() => {
|
|
|
100
115
|
}
|
|
101
116
|
`; }
|
|
102
117
|
render() {
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
class="toggle-icon"
|
|
107
|
-
@click=${() => this.updateCollapsed(!this.collapsed)}
|
|
108
|
-
>
|
|
109
|
-
${ToggleDownIcon({
|
|
110
|
-
width: '16px',
|
|
111
|
-
height: '16px',
|
|
112
|
-
})}
|
|
113
|
-
</div>
|
|
114
|
-
`;
|
|
115
|
-
const toggleRightTemplate = html `
|
|
116
|
-
<div
|
|
118
|
+
return html `
|
|
119
|
+
<button
|
|
120
|
+
type="button"
|
|
117
121
|
contenteditable="false"
|
|
118
122
|
class="toggle-icon"
|
|
119
123
|
data-collapsed=${this.collapsed}
|
|
124
|
+
aria-label=${this.collapsed ? 'Expand content' : 'Collapse content'}
|
|
125
|
+
aria-expanded=${!this.collapsed}
|
|
126
|
+
aria-controls=${this.controls}
|
|
120
127
|
@click=${() => this.updateCollapsed(!this.collapsed)}
|
|
121
128
|
>
|
|
122
|
-
${ToggleRightIcon({
|
|
129
|
+
${(this.collapsed ? ToggleRightIcon : ToggleDownIcon)({
|
|
123
130
|
width: '16px',
|
|
124
131
|
height: '16px',
|
|
125
132
|
})}
|
|
126
|
-
</
|
|
133
|
+
</button>
|
|
127
134
|
`;
|
|
128
|
-
return this.collapsed ? toggleRightTemplate : toggleDownTemplate;
|
|
129
135
|
}
|
|
130
136
|
#collapsed_accessor_storage = __runInitializers(this, _collapsed_initializers, void 0);
|
|
131
137
|
get collapsed() { return this.#collapsed_accessor_storage; }
|
|
@@ -133,9 +139,16 @@ let ToggleButton = (() => {
|
|
|
133
139
|
#updateCollapsed_accessor_storage = (__runInitializers(this, _collapsed_extraInitializers), __runInitializers(this, _updateCollapsed_initializers, void 0));
|
|
134
140
|
get updateCollapsed() { return this.#updateCollapsed_accessor_storage; }
|
|
135
141
|
set updateCollapsed(value) { this.#updateCollapsed_accessor_storage = value; }
|
|
142
|
+
#controls_accessor_storage = (__runInitializers(this, _updateCollapsed_extraInitializers), __runInitializers(this, _controls_initializers, void 0));
|
|
143
|
+
/**
|
|
144
|
+
* Id of the children container this button expands and collapses,
|
|
145
|
+
* exposed to assistive technologies through `aria-controls`.
|
|
146
|
+
*/
|
|
147
|
+
get controls() { return this.#controls_accessor_storage; }
|
|
148
|
+
set controls(value) { this.#controls_accessor_storage = value; }
|
|
136
149
|
constructor() {
|
|
137
150
|
super(...arguments);
|
|
138
|
-
__runInitializers(this,
|
|
151
|
+
__runInitializers(this, _controls_extraInitializers);
|
|
139
152
|
}
|
|
140
153
|
};
|
|
141
154
|
})();
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { ConnectorMode, FontFamily, FontWeight, PointStyle, ShapeStyle, StrokeStyle, TextAlign, } from '../../affine-model/index.js';
|
|
2
|
+
import { NOTATION_NEUTRALS } from '../../affine-shared/consts/index.js';
|
|
2
3
|
import { makeTemplateSnapshot, surfaceText, } from '../make-snapshot.js';
|
|
3
4
|
/**
|
|
4
5
|
* The generic ("Other") diagrams: built ONLY from general BlockSuite shapes
|
|
5
6
|
* (`shape` rect/polygon, `text`, `connector`) per the composition principle —
|
|
6
7
|
* they belong to no framework, so they ship from the template package itself.
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Their neutrals are the shared notation scale's, like every framework's:
|
|
11
|
+
* the ink, the divider grey, the label grey and the card white. Only
|
|
12
|
+
* the hues (kanban cards, gantt bars) are the diagrams' own.
|
|
13
|
+
*/
|
|
14
|
+
const DARK = NOTATION_NEUTRALS.ink;
|
|
15
|
+
const MUTED = NOTATION_NEUTRALS.divider;
|
|
10
16
|
function rect(x, y, w, h, opts = {}) {
|
|
11
17
|
const el = {
|
|
12
18
|
type: 'shape',
|
|
13
19
|
shapeType: opts.shapeType ?? 'rect',
|
|
14
20
|
filled: true,
|
|
15
|
-
fillColor: opts.fill ??
|
|
21
|
+
fillColor: opts.fill ?? NOTATION_NEUTRALS.cardFill,
|
|
16
22
|
strokeColor: opts.stroke ?? DARK,
|
|
17
23
|
strokeWidth: opts.sw ?? 2,
|
|
18
24
|
strokeStyle: opts.dash ? StrokeStyle.Dash : StrokeStyle.Solid,
|
|
@@ -36,7 +42,7 @@ function label(x, y, w, h, str, opts = {}) {
|
|
|
36
42
|
return {
|
|
37
43
|
type: 'text',
|
|
38
44
|
text: surfaceText(str),
|
|
39
|
-
color: opts.color ??
|
|
45
|
+
color: opts.color ?? DARK,
|
|
40
46
|
fontFamily: FontFamily.Inter,
|
|
41
47
|
fontSize: opts.fontSize ?? 16,
|
|
42
48
|
fontWeight: opts.weight ?? FontWeight.Regular,
|
|
@@ -72,7 +78,12 @@ function swot() {
|
|
|
72
78
|
}
|
|
73
79
|
// ── Kanban (To do / Doing / Done) ─────────────────────────────────────
|
|
74
80
|
function kanban() {
|
|
75
|
-
const colOpts = {
|
|
81
|
+
const colOpts = {
|
|
82
|
+
fill: NOTATION_NEUTRALS.cardFill,
|
|
83
|
+
stroke: MUTED,
|
|
84
|
+
sw: 1.5,
|
|
85
|
+
radius: 10,
|
|
86
|
+
};
|
|
76
87
|
const head = {
|
|
77
88
|
fontSize: 18,
|
|
78
89
|
weight: FontWeight.Medium,
|
|
@@ -109,7 +120,10 @@ function bmc() {
|
|
|
109
120
|
});
|
|
110
121
|
const hdr = (x, s) => ({
|
|
111
122
|
box: rect(x, 8, 128, 34, { stroke: MUTED, sw: 1 }),
|
|
112
|
-
txt: label(x + 8, 16, 120, 18, s, {
|
|
123
|
+
txt: label(x + 8, 16, 120, 18, s, {
|
|
124
|
+
fontSize: 11,
|
|
125
|
+
color: NOTATION_NEUTRALS.label,
|
|
126
|
+
}),
|
|
113
127
|
});
|
|
114
128
|
const h1 = hdr(470, 'Designed for');
|
|
115
129
|
const h2 = hdr(602, 'Designed by');
|
|
@@ -156,7 +170,7 @@ function fishbone() {
|
|
|
156
170
|
sw: 1.4,
|
|
157
171
|
dash: true,
|
|
158
172
|
text: n,
|
|
159
|
-
textColor:
|
|
173
|
+
textColor: NOTATION_NEUTRALS.label,
|
|
160
174
|
fontSize: 13,
|
|
161
175
|
});
|
|
162
176
|
const out = {
|
|
@@ -190,10 +204,13 @@ function gantt() {
|
|
|
190
204
|
// week gridlines + labels
|
|
191
205
|
for (let i = 0; i < 6; i++) {
|
|
192
206
|
const x = 220 + i * 130;
|
|
193
|
-
out[`g${i}`] = line(x, 40, x, 268, {
|
|
207
|
+
out[`g${i}`] = line(x, 40, x, 268, {
|
|
208
|
+
stroke: NOTATION_NEUTRALS.cardBorder,
|
|
209
|
+
sw: 1,
|
|
210
|
+
});
|
|
194
211
|
out[`w${i}`] = label(x - 16, 12, 40, 20, `W${i + 1}`, {
|
|
195
212
|
fontSize: 12,
|
|
196
|
-
color:
|
|
213
|
+
color: NOTATION_NEUTRALS.label,
|
|
197
214
|
align: TextAlign.Center,
|
|
198
215
|
});
|
|
199
216
|
}
|
|
@@ -212,11 +229,11 @@ function gantt() {
|
|
|
212
229
|
}
|
|
213
230
|
const ATTRS = 'width="100%" height="100%" viewBox="0 0 135 80" xmlns="http://www.w3.org/2000/svg"';
|
|
214
231
|
const previews = {
|
|
215
|
-
swot: `<svg ${ATTRS} fill="none"><rect x="20" y="12" width="95" height="56" stroke="
|
|
216
|
-
kanban: `<svg ${ATTRS} fill="none"><rect x="10" y="12" width="35" height="56" rx="4" stroke="
|
|
217
|
-
bmc: `<svg ${ATTRS} fill="none"><g stroke="
|
|
218
|
-
fishbone: `<svg ${ATTRS} fill="none"><path d="M14 40 H112" stroke="
|
|
219
|
-
gantt: `<svg ${ATTRS} fill="none"><path d="M40 14 V70 M62 14 V70 M84 14 V70 M106 14 V70" stroke="
|
|
232
|
+
swot: `<svg ${ATTRS} fill="none"><rect x="20" y="12" width="95" height="56" stroke="${DARK}" stroke-width="2"/><path d="M67.5 12 V68 M20 40 H115" stroke="${DARK}" stroke-width="1.6"/></svg>`,
|
|
233
|
+
kanban: `<svg ${ATTRS} fill="none"><rect x="10" y="12" width="35" height="56" rx="4" stroke="${MUTED}"/><rect x="50" y="12" width="35" height="56" rx="4" stroke="${MUTED}"/><rect x="90" y="12" width="35" height="56" rx="4" stroke="${MUTED}"/><rect x="15" y="22" width="25" height="11" rx="2" fill="#fde6c8"/><rect x="55" y="22" width="25" height="11" rx="2" fill="#d6e4fb"/><rect x="95" y="22" width="25" height="11" rx="2" fill="#d5efd9"/></svg>`,
|
|
234
|
+
bmc: `<svg ${ATTRS} fill="none"><g stroke="${DARK}" stroke-width="1.2"><rect x="8" y="14" width="22" height="40"/><rect x="32" y="14" width="22" height="20"/><rect x="32" y="35" width="22" height="19"/><rect x="56" y="14" width="22" height="40"/><rect x="80" y="14" width="22" height="20"/><rect x="80" y="35" width="22" height="19"/><rect x="104" y="14" width="22" height="40"/><rect x="8" y="56" width="57" height="14"/><rect x="68" y="56" width="58" height="14"/></g></svg>`,
|
|
235
|
+
fishbone: `<svg ${ATTRS} fill="none"><path d="M14 40 H112" stroke="${DARK}" stroke-width="3"/><rect x="112" y="33" width="20" height="14" stroke="${DARK}" stroke-width="1.4"/><path d="M40 18 L52 40 M40 62 L52 40 M84 18 L96 40 M84 62 L96 40" stroke="${DARK}" stroke-width="1.4"/></svg>`,
|
|
236
|
+
gantt: `<svg ${ATTRS} fill="none"><path d="M40 14 V70 M62 14 V70 M84 14 V70 M106 14 V70" stroke="${NOTATION_NEUTRALS.cardBorder}"/><rect x="40" y="22" width="34" height="8" rx="2" fill="#4574c4"/><rect x="52" y="36" width="44" height="8" rx="2" fill="#2f9e95"/><rect x="62" y="50" width="50" height="8" rx="2" fill="#d99a2b"/><rect x="84" y="64" width="28" height="8" rx="2" fill="#43a06b"/></svg>`,
|
|
220
237
|
};
|
|
221
238
|
function t(name, preview, elements) {
|
|
222
239
|
return {
|
|
@@ -18,4 +18,7 @@ export declare const UnderthroughExtension: ExtensionType & {
|
|
|
18
18
|
export declare const CodeExtension: ExtensionType & {
|
|
19
19
|
identifier: import("../global/di/types.js").ServiceIdentifier<import("../std/inline/index.js").InlineMarkdownMatch<AffineTextAttributes>>;
|
|
20
20
|
};
|
|
21
|
+
export declare const EmDashExtension: ExtensionType & {
|
|
22
|
+
identifier: import("../global/di/types.js").ServiceIdentifier<import("../std/inline/index.js").InlineMarkdownMatch<AffineTextAttributes>>;
|
|
23
|
+
};
|
|
21
24
|
export declare const MarkdownExtensions: ExtensionType[];
|
|
@@ -193,6 +193,24 @@ export const CodeExtension = InlineMarkdownExtension({
|
|
|
193
193
|
});
|
|
194
194
|
},
|
|
195
195
|
});
|
|
196
|
+
// typographic replacement: word -- + space => word — + space
|
|
197
|
+
// not convert: --- + space (divider shortcut), --flag + space, inside inline code
|
|
198
|
+
export const EmDashExtension = InlineMarkdownExtension({
|
|
199
|
+
name: 'em-dash',
|
|
200
|
+
pattern: /(?:^|[^-])--\s$/,
|
|
201
|
+
action: ({ inlineEditor, inlineRange, undoManager }) => {
|
|
202
|
+
const dashes = { index: inlineRange.index - 3, length: 2 };
|
|
203
|
+
const format = inlineEditor.getFormat(dashes);
|
|
204
|
+
if (format.code)
|
|
205
|
+
return;
|
|
206
|
+
undoManager.stopCapturing();
|
|
207
|
+
inlineEditor.insertText(dashes, '—', format);
|
|
208
|
+
inlineEditor.setInlineRange({
|
|
209
|
+
index: inlineRange.index - 1,
|
|
210
|
+
length: 0,
|
|
211
|
+
});
|
|
212
|
+
},
|
|
213
|
+
});
|
|
196
214
|
export const MarkdownExtensions = [
|
|
197
215
|
BoldItalicMarkdown,
|
|
198
216
|
BoldMarkdown,
|
|
@@ -201,4 +219,5 @@ export const MarkdownExtensions = [
|
|
|
201
219
|
UnderthroughExtension,
|
|
202
220
|
CodeExtension,
|
|
203
221
|
LatexExtension,
|
|
222
|
+
EmDashExtension,
|
|
204
223
|
];
|
|
@@ -2,7 +2,17 @@ import type { TransformerMiddleware } from '../../../store/index.js';
|
|
|
2
2
|
import { StoreExtension } from '../../../store/index.js';
|
|
3
3
|
export declare const customImageProxyMiddleware: (imageProxyURL: string) => TransformerMiddleware;
|
|
4
4
|
export declare const setImageProxyMiddlewareURL: (url: string) => void;
|
|
5
|
+
/**
|
|
6
|
+
* Reads the URL at run time: a `setImageProxyURL` made after module load
|
|
7
|
+
* reaches every job using this middleware.
|
|
8
|
+
*/
|
|
5
9
|
export declare const defaultImageProxyMiddleware: TransformerMiddleware;
|
|
10
|
+
/**
|
|
11
|
+
* The ONE seam governing every remote-image fetch the library performs on the
|
|
12
|
+
* host's behalf: link-card favicons and og:images, image import, canvas
|
|
13
|
+
* PNG/PDF export, copy-as-image. An empty URL means « fetch direct ».
|
|
14
|
+
* See `docs/integrate/04-host-seams.md`.
|
|
15
|
+
*/
|
|
6
16
|
export declare class ImageProxyService extends StoreExtension {
|
|
7
17
|
static key: string;
|
|
8
18
|
private _imageProxyURL;
|