@formicoidea/labre-core 0.46.2 → 0.47.1
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-attachment/configs/slash-menu.js +2 -2
- package/dist/_pkgs/affine-block-attachment/translations.js +2 -2
- package/dist/_pkgs/affine-block-data-view/columns/index.d.ts +1 -1
- package/dist/_pkgs/affine-block-database/data-source.d.ts +1 -1
- package/dist/_pkgs/affine-block-database/properties/converts.d.ts +4 -4
- package/dist/_pkgs/affine-block-database/properties/index.d.ts +1 -1
- package/dist/_pkgs/affine-block-embed/embed-html-block/configs/toolbar.js +1 -1
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.d.ts +1 -1
- package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.js +1 -1
- package/dist/_pkgs/affine-block-embed/translations.d.ts +1 -1
- package/dist/_pkgs/affine-block-embed/translations.js +2 -2
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/slash-menu.js +6 -6
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/toolbar.js +1 -1
- package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.js +3 -3
- package/dist/_pkgs/affine-block-embed-doc/translations.d.ts +1 -1
- package/dist/_pkgs/affine-block-embed-doc/translations.js +8 -8
- package/dist/_pkgs/affine-block-frame/commands.js +41 -1
- package/dist/_pkgs/affine-block-frame/frame-manager.d.ts +1 -1
- package/dist/_pkgs/affine-block-frame/frame-toolbar.js +2 -2
- package/dist/_pkgs/affine-block-frame/translations.js +1 -1
- package/dist/_pkgs/affine-block-frame/view.js +7 -2
- package/dist/_pkgs/affine-block-note/components/edgeless-page-block-title.d.ts +7 -0
- package/dist/_pkgs/affine-block-note/components/edgeless-page-block-title.js +15 -1
- package/dist/_pkgs/affine-block-note/translations.js +8 -8
- package/dist/_pkgs/affine-block-root/commands/copy-link-commands.js +2 -2
- package/dist/_pkgs/affine-block-root/configs/toolbar.d.ts +1 -1
- package/dist/_pkgs/affine-block-root/configs/toolbar.js +1 -1
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/misc.d.ts +1 -1
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.d.ts +1 -1
- package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.js +1 -1
- package/dist/_pkgs/affine-block-root/translations.d.ts +1 -1
- package/dist/_pkgs/affine-block-root/translations.js +2 -2
- package/dist/_pkgs/affine-block-surface/extensions/canvas-grid/commands.js +21 -7
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/commands.d.ts +2 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/commands.js +79 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.d.ts +18 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +53 -30
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/index.d.ts +1 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/index.js +1 -0
- package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +1 -1
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/commands.js +1 -1
- package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.d.ts +8 -2
- package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.js +11 -13
- package/dist/_pkgs/affine-block-surface/view.js +11 -2
- package/dist/_pkgs/affine-block-surface-ref/translations.js +8 -8
- package/dist/_pkgs/affine-components/translations.js +6 -6
- package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +8 -0
- package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +65 -4
- package/dist/_pkgs/affine-fragment-doc-title/effects.d.ts +2 -0
- package/dist/_pkgs/affine-fragment-doc-title/effects.js +2 -0
- package/dist/_pkgs/affine-fragment-doc-title/index.d.ts +2 -0
- package/dist/_pkgs/affine-fragment-doc-title/index.js +2 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/format.d.ts +69 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/format.js +182 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +62 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +649 -0
- package/dist/_pkgs/affine-fragment-doc-title/translations.d.ts +21 -0
- package/dist/_pkgs/affine-fragment-doc-title/translations.js +58 -0
- package/dist/_pkgs/affine-gfx-group/toolbar/config.d.ts +2 -2
- package/dist/_pkgs/affine-gfx-group/toolbar/config.js +2 -2
- package/dist/_pkgs/affine-gfx-group/translations.js +1 -1
- package/dist/_pkgs/affine-gfx-note/translations.js +2 -2
- package/dist/_pkgs/affine-shared/services/index.d.ts +2 -0
- package/dist/_pkgs/affine-shared/services/index.js +2 -0
- package/dist/_pkgs/affine-shared/services/linked-doc-creation-service.d.ts +1 -1
- package/dist/_pkgs/affine-shared/services/properties-panel-service.d.ts +50 -0
- package/dist/_pkgs/affine-shared/services/properties-panel-service.js +17 -0
- package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +124 -0
- package/dist/_pkgs/affine-shared/services/title-band-service.js +17 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +3 -3
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +17 -17
- package/dist/_pkgs/affine-widget-edgeless-auto-connect/translations.js +2 -2
- package/dist/_pkgs/affine-widget-edgeless-selected-rect/translations.js +1 -1
- package/dist/_pkgs/affine-widget-linked-doc/translations.js +3 -3
- package/dist/_pkgs/affine-widget-slash-menu/translations.js +1 -1
- package/dist/_pkgs/data-view/property-presets/converts.d.ts +2 -2
- package/dist/_pkgs/data-view/property-presets/index.d.ts +1 -1
- package/dist/_pkgs/data-view/property-presets/number/cell-renderer.d.ts +1 -1
- package/dist/_pkgs/data-view/property-presets/number/define.d.ts +1 -1
- package/dist/_pkgs/data-view/property-presets/number/types.d.ts +2 -2
- package/dist/_pkgs/data-view/property-presets/pure-index.d.ts +2 -1
- package/dist/_pkgs/data-view/property-presets/pure-index.js +4 -0
- package/dist/_pkgs/std/extension/command-registry.d.ts +50 -1
- package/dist/_pkgs/std/extension/command-registry.js +26 -7
- package/dist/commands.js +2 -1
- package/dist/host-panels.d.ts +83 -2
- package/dist/host-panels.js +82 -1
- package/dist/translations.js +1 -1
- package/package.json +1 -1
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/file-exporter.d.ts +0 -26
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/file-exporter.js +0 -73
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { CanvasGrid, TelemetryProvider } from '../../../affine-shared/services/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* The canvas grid's two commands (ADR 0031 §11, §12), `owner: 'core'`, on the
|
|
4
|
-
* palette
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* palette, the agent and the host's view menu (`'view-menu'`, ADR 0034
|
|
5
|
+
* amendment of 2026-10-13). The library has no page "more" menu — that
|
|
6
|
+
* belongs to the host — so these are the grid's whole UI here; a host lists
|
|
7
|
+
* them with `getViewActions` and runs them through `runCommand`.
|
|
7
8
|
*
|
|
8
9
|
* Both self-emit `CanvasGridToggled` (see the telemetry README): `scope` is
|
|
9
10
|
* which gesture ran, and a save that changes nothing reports nothing.
|
|
@@ -27,11 +28,17 @@ const toggleGrid = {
|
|
|
27
28
|
labelFallback: 'Show or hide the grid',
|
|
28
29
|
descriptionKey: 'com.labre.command.canvas.grid.toggle.description',
|
|
29
30
|
descriptionFallback: 'Show or hide the canvas grid on your screen only. Nothing changes for anyone else.',
|
|
31
|
+
category: 'display',
|
|
32
|
+
iconKey: 'canvas.grid',
|
|
30
33
|
keywords: ['grid', 'dots', 'background'],
|
|
31
|
-
surfaces: ['palette', 'agent'],
|
|
34
|
+
surfaces: ['palette', 'agent', 'view-menu'],
|
|
35
|
+
order: 0,
|
|
32
36
|
scope: 'edgeless',
|
|
33
37
|
defaultKeys: { mac: [], other: [] },
|
|
34
38
|
when: std => !!std.getOptional(CanvasGrid),
|
|
39
|
+
// What this viewer sees now. A signal read, so a menu that reads it inside
|
|
40
|
+
// an effect ticks and unticks with the grid, whoever flips it.
|
|
41
|
+
checked: std => std.getOptional(CanvasGrid)?.visible$.value ?? false,
|
|
35
42
|
run: std => {
|
|
36
43
|
const grid = std.getOptional(CanvasGrid);
|
|
37
44
|
if (!grid)
|
|
@@ -51,13 +58,20 @@ const saveGridForEveryone = {
|
|
|
51
58
|
labelKey: 'com.labre.command.canvas.grid.save-for-everyone',
|
|
52
59
|
labelFallback: 'Save the grid for everyone',
|
|
53
60
|
descriptionKey: 'com.labre.command.canvas.grid.save-for-everyone.description',
|
|
54
|
-
descriptionFallback: 'Make the grid as you see it now the setting of this
|
|
61
|
+
descriptionFallback: 'Make the grid as you see it now the setting of this page, for everyone who opens it.',
|
|
62
|
+
category: 'display',
|
|
55
63
|
keywords: ['grid', 'dots', 'background', 'document'],
|
|
56
|
-
surfaces: ['palette', 'agent'],
|
|
64
|
+
surfaces: ['palette', 'agent', 'view-menu'],
|
|
65
|
+
order: 1,
|
|
57
66
|
scope: 'edgeless',
|
|
58
67
|
defaultKeys: { mac: [], other: [] },
|
|
59
68
|
availability: 'editable',
|
|
60
|
-
|
|
69
|
+
// Offered once this viewer has a grid of their own (`source$` is
|
|
70
|
+
// `'local'`, i.e. after a toggle): that is what the gesture saves, and the
|
|
71
|
+
// follow-up the hosts' menus already showed after the toggle. A signal
|
|
72
|
+
// read, so a view menu read inside an effect shows the entry right after a
|
|
73
|
+
// toggle and drops it after the save.
|
|
74
|
+
when: std => std.getOptional(CanvasGrid)?.source$.value === 'local',
|
|
61
75
|
run: std => {
|
|
62
76
|
const saved = std.getOptional(CanvasGrid)?.saveForEveryone() ?? null;
|
|
63
77
|
if (saved === null)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { downloadBlob } from '../../../affine-shared/utils/index.js';
|
|
2
|
+
import { ExportManager } from './export-manager.js';
|
|
3
|
+
/**
|
|
4
|
+
* "Export as PNG" and "Export as PDF" of the canvas, in the command registry
|
|
5
|
+
* (ADR 0034, amendment of 2026-10-13). `owner: 'core'`: the picture is the
|
|
6
|
+
* canvas's, whatever drew on it.
|
|
7
|
+
*
|
|
8
|
+
* On the `'view-menu'` surface because the export is proper to the canvas
|
|
9
|
+
* VIEW (the host's "This view" section reads them through `getViewActions`),
|
|
10
|
+
* and on the palette. Not `'agent'`: an agent turn would drop a file on the
|
|
11
|
+
* user's disk they did not ask for.
|
|
12
|
+
*
|
|
13
|
+
* The library renders and the host decides where the bytes go: given
|
|
14
|
+
* `params.deliver` (`CommandFileParams`), the command hands the file over and
|
|
15
|
+
* downloads nothing — `runViewAction` passes one and returns the file. Without
|
|
16
|
+
* it (the palette, a bound chord) the command downloads the file itself, which
|
|
17
|
+
* is what a standalone editor needs. Nothing to draw, no file, no error.
|
|
18
|
+
*
|
|
19
|
+
* It READS, so there is no read-only guard: a reader exports what they see.
|
|
20
|
+
* No `telemetry` field, for `export.svg`'s reason — it names no framework —
|
|
21
|
+
* and usage is still measured by `runCommand`.
|
|
22
|
+
*/
|
|
23
|
+
function deliverOf(params) {
|
|
24
|
+
const deliver = params?.deliver;
|
|
25
|
+
return typeof deliver === 'function' ? deliver : undefined;
|
|
26
|
+
}
|
|
27
|
+
async function exportCanvas(std, render, params) {
|
|
28
|
+
const exporter = std.getOptional(ExportManager);
|
|
29
|
+
if (!exporter)
|
|
30
|
+
return;
|
|
31
|
+
const file = await render(exporter);
|
|
32
|
+
if (!file)
|
|
33
|
+
return;
|
|
34
|
+
const deliver = deliverOf(params);
|
|
35
|
+
if (deliver)
|
|
36
|
+
deliver(file);
|
|
37
|
+
else
|
|
38
|
+
downloadBlob(file.blob, file.filename);
|
|
39
|
+
}
|
|
40
|
+
const exportPng = {
|
|
41
|
+
id: 'canvas.export.png',
|
|
42
|
+
owner: 'core',
|
|
43
|
+
kind: 'action',
|
|
44
|
+
labelKey: 'com.labre.command.canvas.export.png',
|
|
45
|
+
labelFallback: 'Export as PNG',
|
|
46
|
+
descriptionKey: 'com.labre.command.canvas.export.png.description',
|
|
47
|
+
descriptionFallback: 'Download the whole canvas as an image, as you see it on your screen.',
|
|
48
|
+
category: 'export',
|
|
49
|
+
iconKey: 'canvas.export.png',
|
|
50
|
+
keywords: ['png', 'image', 'export', 'download', 'picture'],
|
|
51
|
+
surfaces: ['view-menu', 'palette'],
|
|
52
|
+
order: 10,
|
|
53
|
+
scope: 'edgeless',
|
|
54
|
+
defaultKeys: { mac: [], other: [] },
|
|
55
|
+
when: std => !!std.getOptional(ExportManager),
|
|
56
|
+
run: (std, _invocation, params) => exportCanvas(std, exporter => exporter.pngFile(), params),
|
|
57
|
+
};
|
|
58
|
+
const exportPdf = {
|
|
59
|
+
id: 'canvas.export.pdf',
|
|
60
|
+
owner: 'core',
|
|
61
|
+
kind: 'action',
|
|
62
|
+
labelKey: 'com.labre.command.canvas.export.pdf',
|
|
63
|
+
labelFallback: 'Export as PDF',
|
|
64
|
+
descriptionKey: 'com.labre.command.canvas.export.pdf.description',
|
|
65
|
+
descriptionFallback: 'Download the whole canvas as a one-page PDF holding its image.',
|
|
66
|
+
category: 'export',
|
|
67
|
+
iconKey: 'canvas.export.pdf',
|
|
68
|
+
keywords: ['pdf', 'export', 'download', 'print'],
|
|
69
|
+
surfaces: ['view-menu', 'palette'],
|
|
70
|
+
order: 11,
|
|
71
|
+
scope: 'edgeless',
|
|
72
|
+
defaultKeys: { mac: [], other: [] },
|
|
73
|
+
when: std => !!std.getOptional(ExportManager),
|
|
74
|
+
run: (std, _invocation, params) => exportCanvas(std, exporter => exporter.pdfFile(), params),
|
|
75
|
+
};
|
|
76
|
+
export const canvasExportCommands = [
|
|
77
|
+
exportPng,
|
|
78
|
+
exportPdf,
|
|
79
|
+
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IBound } from '../../../global/gfx/index.js';
|
|
2
|
-
import { type BlockStdScope, type EditorHost } from '../../../std/index.js';
|
|
2
|
+
import { type BlockStdScope, type CommandFile, 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';
|
|
@@ -39,7 +39,24 @@ export declare class ExportManager {
|
|
|
39
39
|
edgelessToCanvas(surfaceRenderer: CanvasRenderer, bound: IBound, gfx: GfxController, blocks?: GfxBlockElementModel[], elements?: GfxPrimitiveElementModel[], edgelessBackground?: {
|
|
40
40
|
zoom: number;
|
|
41
41
|
}): Promise<HTMLCanvasElement | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* The canvas (or, in page mode, the document) as a PNG file, or `null` when
|
|
44
|
+
* there is nothing to draw. Renders, never downloads: the caller decides
|
|
45
|
+
* where the bytes go (`canvas.export.png` hands them to a host, or to the
|
|
46
|
+
* browser).
|
|
47
|
+
*/
|
|
48
|
+
pngFile(): Promise<CommandFile | null>;
|
|
49
|
+
/**
|
|
50
|
+
* The same picture in a one-page PDF (`pdf-lib`, loaded on demand), or
|
|
51
|
+
* `null` when there is nothing to draw. The PDF is an image: its text is
|
|
52
|
+
* not selectable.
|
|
53
|
+
*/
|
|
54
|
+
pdfFile(): Promise<CommandFile | null>;
|
|
55
|
+
/** Render, then hand the file to the browser. Nothing to draw, no file. */
|
|
42
56
|
exportPdf(): Promise<void>;
|
|
57
|
+
/** Render, then hand the file to the browser. Nothing to draw, no file. */
|
|
43
58
|
exportPng(): Promise<void>;
|
|
59
|
+
/** The document title, sanitised; the translated "Untitled" without one. */
|
|
60
|
+
private _fileStem;
|
|
44
61
|
}
|
|
45
62
|
export declare const ExportManagerExtension: ExtensionType;
|
|
@@ -2,14 +2,13 @@ import { ImageBlockModel } from '../../../affine-model/index.js';
|
|
|
2
2
|
import { FetchUtils, ImageProxyService } from '../../../affine-shared/adapters/index.js';
|
|
3
3
|
import { CANVAS_EXPORT_IGNORE_TAGS } from '../../../affine-shared/consts/index.js';
|
|
4
4
|
import { CanvasGrid, CHROME_UNTITLED, translateKey, } from '../../../affine-shared/services/index.js';
|
|
5
|
-
import { isInsidePageEditor, matchModels, normalizeCanvasExportColors, toLegacyColors, } from '../../../affine-shared/utils/index.js';
|
|
5
|
+
import { downloadBlob, isInsidePageEditor, matchModels, normalizeCanvasExportColors, safeFilename, toLegacyColors, } from '../../../affine-shared/utils/index.js';
|
|
6
6
|
import { BlockSuiteError, ErrorCode } from '../../../global/exceptions/index.js';
|
|
7
7
|
import { deserializeXYWH } from '../../../global/gfx/index.js';
|
|
8
8
|
import { StdIdentifier, } from '../../../std/index.js';
|
|
9
9
|
import { GfxBlockElementModel, GfxControllerIdentifier, GfxPrimitiveElementModel, isGfxGroupCompatibleModel, } from '../../../std/gfx/index.js';
|
|
10
10
|
import { CanvasRenderer } from '../../renderer/canvas-renderer.js';
|
|
11
11
|
import { getBgGridGap } from '../../utils/get-bg-grip-gap.js';
|
|
12
|
-
import { FileExporter } from './file-exporter.js';
|
|
13
12
|
/**
|
|
14
13
|
* The SVG the PNG export paints the canvas background from: the background
|
|
15
14
|
* colour, plus the dotted grid unless `gridColor` is `null` — what this
|
|
@@ -379,38 +378,62 @@ export class ExportManager {
|
|
|
379
378
|
ctx.drawImage(surfaceCanvas, 50, 50, bound.w, bound.h);
|
|
380
379
|
return canvas;
|
|
381
380
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
381
|
+
/**
|
|
382
|
+
* The canvas (or, in page mode, the document) as a PNG file, or `null` when
|
|
383
|
+
* there is nothing to draw. Renders, never downloads: the caller decides
|
|
384
|
+
* where the bytes go (`canvas.export.png` hands them to a host, or to the
|
|
385
|
+
* browser).
|
|
386
|
+
*/
|
|
387
|
+
async pngFile() {
|
|
388
|
+
if (!this.doc.root)
|
|
389
|
+
return null;
|
|
390
|
+
const canvas = await this._toCanvas();
|
|
391
|
+
if (!canvas)
|
|
392
|
+
return null;
|
|
393
|
+
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
|
|
394
|
+
if (!blob)
|
|
395
|
+
return null;
|
|
396
|
+
return { blob, filename: `${this._fileStem()}.png` };
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* The same picture in a one-page PDF (`pdf-lib`, loaded on demand), or
|
|
400
|
+
* `null` when there is nothing to draw. The PDF is an image: its text is
|
|
401
|
+
* not selectable.
|
|
402
|
+
*/
|
|
403
|
+
async pdfFile() {
|
|
404
|
+
if (!this.doc.root)
|
|
405
|
+
return null;
|
|
406
|
+
const canvas = await this._toCanvas();
|
|
407
|
+
if (!canvas)
|
|
408
|
+
return null;
|
|
390
409
|
const PDFLib = await import('pdf-lib');
|
|
391
410
|
const pdfDoc = await PDFLib.PDFDocument.create();
|
|
392
|
-
const page = pdfDoc.addPage([
|
|
393
|
-
const
|
|
394
|
-
const { width, height } =
|
|
395
|
-
page.drawImage(
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
401
|
-
const pdfBase64 = await pdfDoc.saveAsBase64({ dataUri: true });
|
|
402
|
-
FileExporter.exportFile(rootModel.props.title.toString() + '.pdf', pdfBase64);
|
|
411
|
+
const page = pdfDoc.addPage([canvas.width, canvas.height]);
|
|
412
|
+
const image = await pdfDoc.embedPng(canvas.toDataURL('image/png'));
|
|
413
|
+
const { width, height } = image.scale(1);
|
|
414
|
+
page.drawImage(image, { x: 0, y: 0, width, height });
|
|
415
|
+
const bytes = await pdfDoc.save();
|
|
416
|
+
return {
|
|
417
|
+
blob: new Blob([bytes], { type: 'application/pdf' }),
|
|
418
|
+
filename: `${this._fileStem()}.pdf`,
|
|
419
|
+
};
|
|
403
420
|
}
|
|
421
|
+
/** Render, then hand the file to the browser. Nothing to draw, no file. */
|
|
422
|
+
async exportPdf() {
|
|
423
|
+
const file = await this.pdfFile();
|
|
424
|
+
if (file)
|
|
425
|
+
downloadBlob(file.blob, file.filename);
|
|
426
|
+
}
|
|
427
|
+
/** Render, then hand the file to the browser. Nothing to draw, no file. */
|
|
404
428
|
async exportPng() {
|
|
405
|
-
const
|
|
406
|
-
if (
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
FileExporter.exportPng(title.trim() || translateKey(this.std, ...CHROME_UNTITLED), canvasImage.toDataURL('image/png'));
|
|
429
|
+
const file = await this.pngFile();
|
|
430
|
+
if (file)
|
|
431
|
+
downloadBlob(file.blob, file.filename);
|
|
432
|
+
}
|
|
433
|
+
/** The document title, sanitised; the translated "Untitled" without one. */
|
|
434
|
+
_fileStem() {
|
|
435
|
+
const root = this.doc.root;
|
|
436
|
+
return safeFilename(root?.props.title.toString(), translateKey(this.std, ...CHROME_UNTITLED));
|
|
414
437
|
}
|
|
415
438
|
}
|
|
416
439
|
export const ExportManagerExtension = {
|
|
@@ -292,7 +292,7 @@ const IMPORT_DEFAULT_NAME_FALLBACK = 'Imported diagram';
|
|
|
292
292
|
* because nothing is wrong with the FILE.
|
|
293
293
|
*/
|
|
294
294
|
const IMPORT_READONLY_KEY = 'com.labre.interchange.import.readonly';
|
|
295
|
-
const IMPORT_READONLY_FALLBACK = 'This
|
|
295
|
+
const IMPORT_READONLY_FALLBACK = 'This page became read-only while the file was being read, so nothing was imported.';
|
|
296
296
|
const IMPORT_REMARKS_KEY = 'com.labre.interchange.import.remarks';
|
|
297
297
|
const IMPORT_REMARKS_FALLBACK = 'What the import could not keep as it was';
|
|
298
298
|
const IMPORT_CONSOLE_KEY = 'com.labre.interchange.import.console';
|
|
@@ -293,7 +293,7 @@ const hideForEveryone = {
|
|
|
293
293
|
labelKey: 'com.labre.command.canvas.visibility.hide-for-everyone',
|
|
294
294
|
labelFallback: 'Hide for everyone',
|
|
295
295
|
descriptionKey: 'com.labre.command.canvas.visibility.hide-for-everyone.description',
|
|
296
|
-
descriptionFallback: 'Hide the selected elements for everyone who opens this
|
|
296
|
+
descriptionFallback: 'Hide the selected elements for everyone who opens this page. They stay in the page and in the selection pane.',
|
|
297
297
|
surfaces: ['palette', 'agent'],
|
|
298
298
|
scope: 'edgeless',
|
|
299
299
|
defaultKeys: { mac: [], other: [] },
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import type { GfxController } from '../../std/gfx/index.js';
|
|
2
2
|
import { Overlay } from './overlay.js';
|
|
3
3
|
/**
|
|
4
|
-
* Draws the transient emphasis
|
|
5
|
-
*
|
|
4
|
+
* Draws the transient emphasis around the elements held by `gfx.highlight`
|
|
5
|
+
* (`ElementHighlightManager`).
|
|
6
|
+
*
|
|
7
|
+
* The emphasis is the canvas's existing vocabulary, a square border on the
|
|
8
|
+
* element's bounds like the selection frame (`edgeless-selected-rect`), not a
|
|
9
|
+
* second, detached ring: the product owner asked for the border alone after
|
|
10
|
+
* the P1 recette, so a selection-pane hover reads as « this one » and not as a
|
|
11
|
+
* new kind of mark.
|
|
6
12
|
*
|
|
7
13
|
* The overlay is a pure renderer: it owns no state, reads nothing from the
|
|
8
14
|
* store and mutates nothing, which makes it safe on a read-only editor.
|
|
@@ -2,15 +2,17 @@ import { getChromeAccentColor } from '../../affine-shared/services/index.js';
|
|
|
2
2
|
import { DisposableGroup } from '../../global/disposable/index.js';
|
|
3
3
|
import { effect } from '@preact/signals-core';
|
|
4
4
|
import { Overlay } from './overlay.js';
|
|
5
|
-
/**
|
|
5
|
+
/** Border thickness, in screen pixels: the selection frame's. */
|
|
6
6
|
const HIGHLIGHT_STROKE_WIDTH = 2;
|
|
7
|
-
/** Gap between the element bounds and the ring, in screen pixels. */
|
|
8
|
-
const HIGHLIGHT_GAP = 4;
|
|
9
|
-
/** Ring corner radius, in screen pixels. */
|
|
10
|
-
const HIGHLIGHT_RADIUS = 4;
|
|
11
7
|
/**
|
|
12
|
-
* Draws the transient emphasis
|
|
13
|
-
*
|
|
8
|
+
* Draws the transient emphasis around the elements held by `gfx.highlight`
|
|
9
|
+
* (`ElementHighlightManager`).
|
|
10
|
+
*
|
|
11
|
+
* The emphasis is the canvas's existing vocabulary, a square border on the
|
|
12
|
+
* element's bounds like the selection frame (`edgeless-selected-rect`), not a
|
|
13
|
+
* second, detached ring: the product owner asked for the border alone after
|
|
14
|
+
* the P1 recette, so a selection-pane hover reads as « this one » and not as a
|
|
15
|
+
* new kind of mark.
|
|
14
16
|
*
|
|
15
17
|
* The overlay is a pure renderer: it owns no state, reads nothing from the
|
|
16
18
|
* store and mutates nothing, which makes it safe on a read-only editor.
|
|
@@ -37,8 +39,6 @@ export class ElementHighlightOverlay extends Overlay {
|
|
|
37
39
|
if (elements.length === 0)
|
|
38
40
|
return;
|
|
39
41
|
const { zoom } = this.gfx.viewport;
|
|
40
|
-
const gap = HIGHLIGHT_GAP / zoom;
|
|
41
|
-
const radius = HIGHLIGHT_RADIUS / zoom;
|
|
42
42
|
ctx.save();
|
|
43
43
|
ctx.strokeStyle = this._strokeColor;
|
|
44
44
|
ctx.lineWidth = HIGHLIGHT_STROKE_WIDTH / zoom;
|
|
@@ -46,14 +46,12 @@ export class ElementHighlightOverlay extends Overlay {
|
|
|
46
46
|
const [x, y, w, h] = element.deserializedXYWH;
|
|
47
47
|
ctx.save();
|
|
48
48
|
// Rotate around the element center so rotated elements keep a tight
|
|
49
|
-
//
|
|
49
|
+
// border; connectors and other non-rotatable elements use their bound box.
|
|
50
50
|
ctx.translate(x + w / 2, y + h / 2);
|
|
51
51
|
if (element.rotate) {
|
|
52
52
|
ctx.rotate((element.rotate * Math.PI) / 180);
|
|
53
53
|
}
|
|
54
|
-
ctx.
|
|
55
|
-
ctx.roundRect(-w / 2 - gap, -h / 2 - gap, w + gap * 2, h + gap * 2, radius);
|
|
56
|
-
ctx.stroke();
|
|
54
|
+
ctx.strokeRect(-w / 2, -h / 2, w, h);
|
|
57
55
|
ctx.restore();
|
|
58
56
|
}
|
|
59
57
|
ctx.restore();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { ExportToPdfIcon, ExportToPngIcon, GridIcon, } from '@blocksuite/icons/lit';
|
|
1
2
|
import { ViewExtensionProvider, } from '../affine-ext-loader/index.js';
|
|
2
3
|
import { CanvasGrid, CanvasLocalVisibility, } from '../affine-shared/services/index.js';
|
|
3
4
|
import { BlockViewExtension, CommandExtension, FlavourExtension, } from '../std/index.js';
|
|
4
5
|
import { literal } from 'lit/static-html.js';
|
|
5
6
|
import { effects } from './effects.js';
|
|
6
|
-
import { auditCommands, CanvasActiveLayer, canvasGridCommands, EdgelessCRUDExtension, EdgelessLegacySlotExtension, EditPropsMiddlewareBuilder, exportSvgCommands, exportSvgToolbarExtension, mapQualityCommands, mapQualityWidget, ReadingManager, readingProposalWidget, readingToolbarExtension, selectionPaneCommands, SelectionPaneModel, SpotlightManager, UserLayerMiddlewareBuilder, userLayerCommands, ValidationManager, validationExceptionToolbarExtension, ValidationOverlay, violationDetailWidget, } from './extensions/index.js';
|
|
7
|
+
import { auditCommands, CanvasActiveLayer, canvasExportCommands, canvasGridCommands, EdgelessCRUDExtension, EdgelessLegacySlotExtension, EditPropsMiddlewareBuilder, exportSvgCommands, exportSvgToolbarExtension, mapQualityCommands, mapQualityWidget, ReadingManager, readingProposalWidget, readingToolbarExtension, selectionPaneCommands, SelectionPaneModel, SpotlightManager, UserLayerMiddlewareBuilder, userLayerCommands, ValidationManager, validationExceptionToolbarExtension, ValidationOverlay, violationDetailWidget, } from './extensions/index.js';
|
|
7
8
|
import { ExportManagerExtension } from './extensions/export-manager/export-manager.js';
|
|
8
9
|
import { BackgroundStackingExtension } from './framework-background/stacking.js';
|
|
9
10
|
import { ElementHighlightOverlay } from './renderer/element-highlight-overlay.js';
|
|
@@ -87,7 +88,15 @@ export class SurfaceViewExtension extends ViewExtensionProvider {
|
|
|
87
88
|
// the edgeless root's background, the surface container and the PNG
|
|
88
89
|
// export; previews follow the document setting alone.
|
|
89
90
|
context.register(CanvasGrid);
|
|
90
|
-
context.register(CommandExtension(canvasGridCommands));
|
|
91
|
+
context.register(CommandExtension(canvasGridCommands, { 'canvas.grid': GridIcon() }));
|
|
92
|
+
// The canvas's PNG and PDF export (ADR 0034, amendment of 2026-10-13):
|
|
93
|
+
// the "This view" entries a host lists with `getViewActions`. Edgeless
|
|
94
|
+
// only — the page-mode export was never offered — and never gated: a
|
|
95
|
+
// picture of what is on the canvas is not a framework's tooling.
|
|
96
|
+
context.register(CommandExtension(canvasExportCommands, {
|
|
97
|
+
'canvas.export.png': ExportToPngIcon(),
|
|
98
|
+
'canvas.export.pdf': ExportToPdfIcon(),
|
|
99
|
+
}));
|
|
91
100
|
// User layers (ADR 0031 §2-§6): the viewer's active layer (session
|
|
92
101
|
// only), the `beforeAdd` middleware that stamps it on what is created,
|
|
93
102
|
// and the commands the pane's layer rows run. Content, never gated.
|
|
@@ -94,35 +94,35 @@ export const SURFACE_REF_PLACEHOLDER_NOT_AVAILABLE = [
|
|
|
94
94
|
*/
|
|
95
95
|
export const SURFACE_REF_PLACEHOLDER_DELETED_FRAME = [
|
|
96
96
|
'com.labre.surface-ref.placeholder.deleted.frame',
|
|
97
|
-
'The frame is deleted or not in this
|
|
97
|
+
'The frame is deleted or not in this page.',
|
|
98
98
|
];
|
|
99
99
|
export const SURFACE_REF_PLACEHOLDER_DELETED_GROUP = [
|
|
100
100
|
'com.labre.surface-ref.placeholder.deleted.group',
|
|
101
|
-
'The group is deleted or not in this
|
|
101
|
+
'The group is deleted or not in this page.',
|
|
102
102
|
];
|
|
103
103
|
export const SURFACE_REF_PLACEHOLDER_DELETED_MINDMAP = [
|
|
104
104
|
'com.labre.surface-ref.placeholder.deleted.mindmap',
|
|
105
|
-
'The mind map is deleted or not in this
|
|
105
|
+
'The mind map is deleted or not in this page.',
|
|
106
106
|
];
|
|
107
107
|
export const SURFACE_REF_PLACEHOLDER_DELETED_EDGELESS = [
|
|
108
108
|
'com.labre.surface-ref.placeholder.deleted.edgeless',
|
|
109
|
-
'The canvas content is deleted or not in this
|
|
109
|
+
'The canvas content is deleted or not in this page.',
|
|
110
110
|
];
|
|
111
111
|
export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_FRAME = [
|
|
112
112
|
'com.labre.surface-ref.placeholder.cannot-display.frame',
|
|
113
|
-
'The frame is inserted but cannot display in canvas mode. Switch to
|
|
113
|
+
'The frame is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
|
|
114
114
|
];
|
|
115
115
|
export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_GROUP = [
|
|
116
116
|
'com.labre.surface-ref.placeholder.cannot-display.group',
|
|
117
|
-
'The group is inserted but cannot display in canvas mode. Switch to
|
|
117
|
+
'The group is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
|
|
118
118
|
];
|
|
119
119
|
export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_MINDMAP = [
|
|
120
120
|
'com.labre.surface-ref.placeholder.cannot-display.mindmap',
|
|
121
|
-
'The mind map is inserted but cannot display in canvas mode. Switch to
|
|
121
|
+
'The mind map is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
|
|
122
122
|
];
|
|
123
123
|
export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_EDGELESS = [
|
|
124
124
|
'com.labre.surface-ref.placeholder.cannot-display.edgeless',
|
|
125
|
-
'The canvas content is inserted but cannot display in canvas mode. Switch to
|
|
125
|
+
'The canvas content is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
|
|
126
126
|
];
|
|
127
127
|
/**
|
|
128
128
|
* Per-kind table joining the two placeholder sentences above to the
|
|
@@ -117,7 +117,7 @@ export const EMBED_CARD_TITLE_ALIAS_PLACEHOLDER = [
|
|
|
117
117
|
];
|
|
118
118
|
export const EMBED_CARD_DESCRIPTION_ALIAS_PLACEHOLDER = [
|
|
119
119
|
'com.labre.embed.card.description-alias-placeholder',
|
|
120
|
-
'Add description alias (empty to inherit
|
|
120
|
+
'Add description alias (empty to inherit page content)',
|
|
121
121
|
];
|
|
122
122
|
export const EMBED_CARD_TITLE_PLACEHOLDER = [
|
|
123
123
|
'com.labre.embed.card.title-placeholder',
|
|
@@ -292,7 +292,7 @@ export const EMOJI_GROUP_WORDINGS = {
|
|
|
292
292
|
/* ── Linked doc title chip ───────────────────────────────────────────── */
|
|
293
293
|
export const DOC_TITLE_ARIA = [
|
|
294
294
|
'com.labre.linked-doc.title-aria',
|
|
295
|
-
'
|
|
295
|
+
'Page title',
|
|
296
296
|
];
|
|
297
297
|
/* ── Linked-doc notifications ─────────────────────────────────────────── */
|
|
298
298
|
export const NOTIFY_SWITCHED_TO_CARD_TITLE = [
|
|
@@ -309,7 +309,7 @@ export const NOTIFY_SWITCHED_TO_EMBED_TITLE = [
|
|
|
309
309
|
];
|
|
310
310
|
export const NOTIFY_SWITCHED_TO_EMBED_MESSAGE = [
|
|
311
311
|
'com.labre.notify.linked-doc.switched-to-embed.message',
|
|
312
|
-
'Custom alias removed. The linked
|
|
312
|
+
'Custom alias removed. The linked page now displays the original title and description.',
|
|
313
313
|
];
|
|
314
314
|
export const NOTIFY_CLEARED_ALIASES_TITLE = [
|
|
315
315
|
'com.labre.notify.linked-doc.cleared-aliases.title',
|
|
@@ -317,17 +317,17 @@ export const NOTIFY_CLEARED_ALIASES_TITLE = [
|
|
|
317
317
|
];
|
|
318
318
|
export const NOTIFY_CLEARED_ALIASES_MESSAGE = [
|
|
319
319
|
'com.labre.notify.linked-doc.cleared-aliases.message',
|
|
320
|
-
'Card view has been restored to original
|
|
320
|
+
'Card view has been restored to original page title and description. All custom aliases have been removed.',
|
|
321
321
|
];
|
|
322
322
|
/* ── Open-doc dropdown ────────────────────────────────────────────────── */
|
|
323
323
|
export const OPEN_LABEL = ['com.labre.open-doc.open', 'Open'];
|
|
324
324
|
export const OPEN_DOC_MENU_ARIA = [
|
|
325
325
|
'com.labre.open-doc.menu-aria',
|
|
326
|
-
'Open
|
|
326
|
+
'Open page menu',
|
|
327
327
|
];
|
|
328
328
|
export const OPEN_DOC_WITH_ARIA = [
|
|
329
329
|
'com.labre.open-doc.with-aria',
|
|
330
|
-
'Open
|
|
330
|
+
'Open page with',
|
|
331
331
|
];
|
|
332
332
|
/* ── Resource popover (attachment / image not-found or retrieve error) ─ */
|
|
333
333
|
/**
|
|
@@ -13,6 +13,14 @@ export declare class DocTitle extends DocTitle_base {
|
|
|
13
13
|
get inlineEditor(): import("../affine-shared/types/index.js").AffineInlineEditor | null;
|
|
14
14
|
get inlineEditorContainer(): HTMLDivElement;
|
|
15
15
|
connectedCallback(): void;
|
|
16
|
+
/**
|
|
17
|
+
* The `std` the title band reads its seams from, when the band belongs
|
|
18
|
+
* here: in the page view, never inside a note on the canvas, where
|
|
19
|
+
* `edgeless-page-block-title` draws the band itself (ADR 0035 §11), so a
|
|
20
|
+
* host that renders this title in the note header does not get two.
|
|
21
|
+
*/
|
|
22
|
+
private get _bandStd();
|
|
23
|
+
firstUpdated(): void;
|
|
16
24
|
render(): import("lit-html").TemplateResult<1>;
|
|
17
25
|
private accessor _isComposing;
|
|
18
26
|
private accessor _isReadonly;
|
|
@@ -34,12 +34,12 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
34
34
|
};
|
|
35
35
|
import { CodeBlockModel, ListBlockModel, NoteBlockModel, NoteDisplayMode, ParagraphBlockModel, } from '../affine-model/index.js';
|
|
36
36
|
import { focusTextModel } from '../affine-rich-text/index.js';
|
|
37
|
-
import { translateKey } from '../affine-shared/services/index.js';
|
|
37
|
+
import { TitleBandProvider, translateKey } from '../affine-shared/services/index.js';
|
|
38
38
|
import { matchModels } from '../affine-shared/utils/index.js';
|
|
39
39
|
import { WithDisposable } from '../global/lit/index.js';
|
|
40
40
|
import { ShadowlessElement } from '../std/index.js';
|
|
41
41
|
import { effect } from '@preact/signals-core';
|
|
42
|
-
import { css, html } from 'lit';
|
|
42
|
+
import { css, html, nothing } from 'lit';
|
|
43
43
|
import { property, query, state } from 'lit/decorators.js';
|
|
44
44
|
import { DOC_TITLE_PLACEHOLDER } from './translations.js';
|
|
45
45
|
const DOC_BLOCK_CHILD_PADDING = 24;
|
|
@@ -76,9 +76,18 @@ let DocTitle = (() => {
|
|
|
76
76
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
77
77
|
}
|
|
78
78
|
static { this.styles = css `
|
|
79
|
+
/*
|
|
80
|
+
* The page title's family is a host's to choose (labre ADR-0049 §5: the
|
|
81
|
+
* Labre app sets Cabinet Grotesk); headings H1 to H6 stay in the body
|
|
82
|
+
* family. Unset, the title keeps the body family, DESIGN.md's One Family
|
|
83
|
+
* Rule.
|
|
84
|
+
*/
|
|
79
85
|
.doc-title-container {
|
|
80
86
|
box-sizing: border-box;
|
|
81
|
-
font-family: var(
|
|
87
|
+
font-family: var(
|
|
88
|
+
--labre-doc-title-font-family,
|
|
89
|
+
var(--affine-font-family)
|
|
90
|
+
);
|
|
82
91
|
font-size: var(--affine-font-base);
|
|
83
92
|
line-height: var(--affine-line-height);
|
|
84
93
|
color: var(--affine-text-primary-color);
|
|
@@ -112,6 +121,27 @@ let DocTitle = (() => {
|
|
|
112
121
|
}
|
|
113
122
|
}
|
|
114
123
|
|
|
124
|
+
.doc-title-container.doc-title-container-with-band {
|
|
125
|
+
padding-bottom: 8px;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.doc-title-band {
|
|
129
|
+
box-sizing: border-box;
|
|
130
|
+
width: 100%;
|
|
131
|
+
max-width: var(--affine-editor-width);
|
|
132
|
+
margin-left: auto;
|
|
133
|
+
margin-right: auto;
|
|
134
|
+
padding: 0 var(--affine-editor-side-padding, ${DOC_BLOCK_CHILD_PADDING}px)
|
|
135
|
+
24px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@container viewport (width <= 640px) {
|
|
139
|
+
.doc-title-band {
|
|
140
|
+
padding-left: ${DOC_BLOCK_CHILD_PADDING}px;
|
|
141
|
+
padding-right: ${DOC_BLOCK_CHILD_PADDING}px;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
115
145
|
.doc-title-container-empty::before {
|
|
116
146
|
content: attr(data-placeholder);
|
|
117
147
|
color: var(--affine-placeholder-color);
|
|
@@ -178,13 +208,35 @@ let DocTitle = (() => {
|
|
|
178
208
|
});
|
|
179
209
|
}
|
|
180
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* The `std` the title band reads its seams from, when the band belongs
|
|
213
|
+
* here: in the page view, never inside a note on the canvas, where
|
|
214
|
+
* `edgeless-page-block-title` draws the band itself (ADR 0035 §11), so a
|
|
215
|
+
* host that renders this title in the note header does not get two.
|
|
216
|
+
*/
|
|
217
|
+
get _bandStd() {
|
|
218
|
+
if (this.closest('edgeless-page-block-title'))
|
|
219
|
+
return null;
|
|
220
|
+
const std = this._std;
|
|
221
|
+
return std?.getOptional(TitleBandProvider) ? std : null;
|
|
222
|
+
}
|
|
223
|
+
firstUpdated() {
|
|
224
|
+
// `<doc-title>` sits beside the editor host, not inside it: on the first
|
|
225
|
+
// frame the host may not carry its `std` yet, and without one the band
|
|
226
|
+
// cannot read its seam. One more render once it has mounted.
|
|
227
|
+
if (this._std)
|
|
228
|
+
return;
|
|
229
|
+
const frame = requestAnimationFrame(() => this.requestUpdate());
|
|
230
|
+
this._disposables.add(() => cancelAnimationFrame(frame));
|
|
231
|
+
}
|
|
181
232
|
render() {
|
|
182
233
|
const isEmpty = !this._rootModel?.props.title.length && !this._isComposing;
|
|
234
|
+
const bandStd = this._bandStd;
|
|
183
235
|
return html `
|
|
184
236
|
<div
|
|
185
237
|
class="doc-title-container ${isEmpty
|
|
186
238
|
? 'doc-title-container-empty'
|
|
187
|
-
: ''}"
|
|
239
|
+
: ''} ${bandStd ? 'doc-title-container-with-band' : ''}"
|
|
188
240
|
data-block-is-title="true"
|
|
189
241
|
data-placeholder=${this._placeholder}
|
|
190
242
|
>
|
|
@@ -197,6 +249,15 @@ let DocTitle = (() => {
|
|
|
197
249
|
.wrapText=${this.wrapText}
|
|
198
250
|
></rich-text>
|
|
199
251
|
</div>
|
|
252
|
+
${bandStd
|
|
253
|
+
? html `<div class="doc-title-band">
|
|
254
|
+
<labre-title-band
|
|
255
|
+
.std=${bandStd}
|
|
256
|
+
.docId=${this.doc.id}
|
|
257
|
+
.surface=${'page'}
|
|
258
|
+
></labre-title-band>
|
|
259
|
+
</div>`
|
|
260
|
+
: nothing}
|
|
200
261
|
`;
|
|
201
262
|
}
|
|
202
263
|
#_isComposing_accessor_storage;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { DocTitle } from './doc-title.js';
|
|
2
|
+
import { LABRE_TITLE_BAND, TitleBand } from './title-band/title-band.js';
|
|
2
3
|
export declare function effects(): void;
|
|
3
4
|
declare global {
|
|
4
5
|
interface HTMLElementTagNameMap {
|
|
5
6
|
'doc-title': DocTitle;
|
|
7
|
+
[LABRE_TITLE_BAND]: TitleBand;
|
|
6
8
|
}
|
|
7
9
|
}
|