@kgdiff/viewer 0.4.0 → 0.5.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/context.d.ts +42 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +87 -0
- package/dist/context.js.map +1 -0
- package/dist/controller.d.ts +26 -185
- package/dist/controller.d.ts.map +1 -1
- package/dist/controller.js +45 -1155
- package/dist/controller.js.map +1 -1
- package/dist/element.d.ts +6 -3
- package/dist/element.d.ts.map +1 -1
- package/dist/element.js +49 -229
- package/dist/element.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +3 -2
- package/dist/pipeline.js.map +1 -1
- package/dist/root.d.ts +54 -0
- package/dist/root.d.ts.map +1 -0
- package/dist/root.js +265 -0
- package/dist/root.js.map +1 -0
- package/dist/schedule.d.ts +22 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/schedule.js +41 -0
- package/dist/schedule.js.map +1 -0
- package/dist/session.d.ts +253 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +1239 -0
- package/dist/session.js.map +1 -0
- package/dist/standalone/kgdiff-viewer-compute.js +1 -1
- package/dist/standalone/kgdiff-viewer.js +4 -4
- package/dist/styles.d.ts +13 -6
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +217 -248
- package/dist/styles.js.map +1 -1
- package/dist/theme.d.ts +25 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +149 -0
- package/dist/theme.js.map +1 -0
- package/dist/ui/change-list.d.ts +18 -0
- package/dist/ui/change-list.d.ts.map +1 -0
- package/dist/ui/change-list.js +331 -0
- package/dist/ui/change-list.js.map +1 -0
- package/dist/ui/context.d.ts +19 -5
- package/dist/ui/context.d.ts.map +1 -1
- package/dist/ui/context.js.map +1 -1
- package/dist/ui/filters.d.ts +9 -0
- package/dist/ui/filters.d.ts.map +1 -0
- package/dist/ui/filters.js +68 -0
- package/dist/ui/filters.js.map +1 -0
- package/dist/ui/header.js +2 -2
- package/dist/ui/header.js.map +1 -1
- package/dist/ui/search.d.ts +13 -0
- package/dist/ui/search.d.ts.map +1 -0
- package/dist/ui/search.js +191 -0
- package/dist/ui/search.js.map +1 -0
- package/dist/ui/sidebar.d.ts +8 -16
- package/dist/ui/sidebar.d.ts.map +1 -1
- package/dist/ui/sidebar.js +15 -539
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/stage.js +1 -1
- package/dist/ui/stage.js.map +1 -1
- package/dist/ui/swatch.js +1 -1
- package/dist/ui/swatch.js.map +1 -1
- package/package.json +6 -6
- package/src/context.ts +106 -0
- package/src/controller.ts +70 -1257
- package/src/element.ts +52 -243
- package/src/index.ts +3 -1
- package/src/pipeline.ts +4 -1
- package/src/root.ts +308 -0
- package/src/schedule.ts +43 -0
- package/src/session.ts +1386 -0
- package/src/styles.ts +225 -253
- package/src/theme.ts +167 -0
- package/src/ui/change-list.ts +401 -0
- package/src/ui/context.ts +21 -5
- package/src/ui/filters.ts +79 -0
- package/src/ui/header.ts +2 -2
- package/src/ui/search.ts +220 -0
- package/src/ui/sidebar.ts +28 -668
- package/src/ui/stage.ts +1 -1
- package/src/ui/swatch.ts +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Web Components community context protocol
|
|
3
|
+
* (https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md),
|
|
4
|
+
* without dependencies: how the viewer's regions find the root whose session they show
|
|
5
|
+
* (RFC 0001 §2).
|
|
6
|
+
*
|
|
7
|
+
* A consumer dispatches a `context-request` event (bubbling, composed: it crosses shadow roots
|
|
8
|
+
* on its way up); the nearest provider of that context answers through the callback and stops
|
|
9
|
+
* the event. Requests nobody answered reach `document`, where they wait; a provider that
|
|
10
|
+
* connects later announces itself with `context-provider` and the waiting requests are sent
|
|
11
|
+
* again, so definition and connection order do not matter. A consumer outside the provider's
|
|
12
|
+
* subtree sends its request through an element inside it (`via`: the root named by `for`).
|
|
13
|
+
*/
|
|
14
|
+
export interface Context<T> {
|
|
15
|
+
/**
|
|
16
|
+
* `Symbol.for(name)`: equal across copies of the library on one page (an IIFE report bundle
|
|
17
|
+
* next to an ESM build), so a component of one copy finds the root of another. The name is
|
|
18
|
+
* versioned when the provided value changes incompatibly.
|
|
19
|
+
*/
|
|
20
|
+
readonly key: symbol;
|
|
21
|
+
/** Carries the value type only. */
|
|
22
|
+
readonly __value?: T;
|
|
23
|
+
}
|
|
24
|
+
export declare const createContext: <T>(name: string) => Context<T>;
|
|
25
|
+
export declare class ContextRequestEvent<T> extends Event {
|
|
26
|
+
readonly context: Context<T>;
|
|
27
|
+
/** The consumer, which may differ from the element the event is dispatched on (`via`). */
|
|
28
|
+
readonly consumer: Element;
|
|
29
|
+
readonly callback: (value: T) => void;
|
|
30
|
+
constructor(context: Context<T>,
|
|
31
|
+
/** The consumer, which may differ from the element the event is dispatched on (`via`). */
|
|
32
|
+
consumer: Element, callback: (value: T) => void);
|
|
33
|
+
}
|
|
34
|
+
export declare class ContextProviderEvent<T> extends Event {
|
|
35
|
+
readonly context: Context<T>;
|
|
36
|
+
constructor(context: Context<T>);
|
|
37
|
+
}
|
|
38
|
+
/** Ask for `context` for `consumer`, through `via` (an element of the provider's subtree). */
|
|
39
|
+
export declare function requestContext<T>(consumer: Element, context: Context<T>, callback: (value: T) => void, via?: Element | null): void;
|
|
40
|
+
/** Answer requests for `context` reaching `host`; returns the function that stops answering. */
|
|
41
|
+
export declare function provideContext<T>(host: Element, context: Context<T>, value: () => T): () => void;
|
|
42
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,GAAI,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,CAAC,CAAgC,CAAC;AAE1F,qBAAa,mBAAmB,CAAC,CAAC,CAAE,SAAQ,KAAK;IAE7C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5B,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,OAAO;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI;IAJvC,YACW,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5B,0FAA0F;IACjF,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAGtC;CACF;AAED,qBAAa,oBAAoB,CAAC,CAAC,CAAE,SAAQ,KAAK;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAAxC,YAAqB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAEvC;CACF;AAwCD,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,CAAC,EAC9B,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAC5B,GAAG,GAAE,OAAO,GAAG,IAAW,GACzB,IAAI,CAGN;AAED,gGAAgG;AAChG,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,IAAI,CAWhG"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Web Components community context protocol
|
|
3
|
+
* (https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md),
|
|
4
|
+
* without dependencies: how the viewer's regions find the root whose session they show
|
|
5
|
+
* (RFC 0001 §2).
|
|
6
|
+
*
|
|
7
|
+
* A consumer dispatches a `context-request` event (bubbling, composed: it crosses shadow roots
|
|
8
|
+
* on its way up); the nearest provider of that context answers through the callback and stops
|
|
9
|
+
* the event. Requests nobody answered reach `document`, where they wait; a provider that
|
|
10
|
+
* connects later announces itself with `context-provider` and the waiting requests are sent
|
|
11
|
+
* again, so definition and connection order do not matter. A consumer outside the provider's
|
|
12
|
+
* subtree sends its request through an element inside it (`via`: the root named by `for`).
|
|
13
|
+
*/
|
|
14
|
+
export const createContext = (name) => ({ key: Symbol.for(name) });
|
|
15
|
+
export class ContextRequestEvent extends Event {
|
|
16
|
+
context;
|
|
17
|
+
consumer;
|
|
18
|
+
callback;
|
|
19
|
+
constructor(context,
|
|
20
|
+
/** The consumer, which may differ from the element the event is dispatched on (`via`). */
|
|
21
|
+
consumer, callback) {
|
|
22
|
+
super('context-request', { bubbles: true, composed: true });
|
|
23
|
+
this.context = context;
|
|
24
|
+
this.consumer = consumer;
|
|
25
|
+
this.callback = callback;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class ContextProviderEvent extends Event {
|
|
29
|
+
context;
|
|
30
|
+
constructor(context) {
|
|
31
|
+
super('context-provider', { bubbles: true, composed: true });
|
|
32
|
+
this.context = context;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const waiting = new Set();
|
|
36
|
+
let collecting = false;
|
|
37
|
+
/** Keep the requests nobody answered, and send them again when a provider connects. */
|
|
38
|
+
function collect() {
|
|
39
|
+
if (collecting || typeof document === 'undefined')
|
|
40
|
+
return;
|
|
41
|
+
collecting = true;
|
|
42
|
+
document.addEventListener('context-request', (e) => {
|
|
43
|
+
// Consumers that left the document since they asked are forgotten, closures and all.
|
|
44
|
+
for (const w of waiting)
|
|
45
|
+
if (!w.consumer.isConnected)
|
|
46
|
+
waiting.delete(w);
|
|
47
|
+
const r = e;
|
|
48
|
+
waiting.add({
|
|
49
|
+
context: r.context,
|
|
50
|
+
consumer: r.consumer,
|
|
51
|
+
via: e.composedPath()[0] ?? r.consumer,
|
|
52
|
+
callback: r.callback,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
document.addEventListener('context-provider', (e) => {
|
|
56
|
+
const key = e.context.key;
|
|
57
|
+
for (const w of [...waiting]) {
|
|
58
|
+
if (w.context.key !== key)
|
|
59
|
+
continue;
|
|
60
|
+
waiting.delete(w);
|
|
61
|
+
// Unanswered again: it waits again on its way through `document`.
|
|
62
|
+
if (w.consumer.isConnected) {
|
|
63
|
+
w.via.dispatchEvent(new ContextRequestEvent(w.context, w.consumer, w.callback));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Ask for `context` for `consumer`, through `via` (an element of the provider's subtree). */
|
|
69
|
+
export function requestContext(consumer, context, callback, via = null) {
|
|
70
|
+
collect();
|
|
71
|
+
(via ?? consumer).dispatchEvent(new ContextRequestEvent(context, consumer, callback));
|
|
72
|
+
}
|
|
73
|
+
/** Answer requests for `context` reaching `host`; returns the function that stops answering. */
|
|
74
|
+
export function provideContext(host, context, value) {
|
|
75
|
+
collect();
|
|
76
|
+
const answer = (e) => {
|
|
77
|
+
const r = e;
|
|
78
|
+
if (r.context?.key !== context.key)
|
|
79
|
+
return;
|
|
80
|
+
e.stopPropagation();
|
|
81
|
+
r.callback(value());
|
|
82
|
+
};
|
|
83
|
+
host.addEventListener('context-request', answer);
|
|
84
|
+
host.dispatchEvent(new ContextProviderEvent(context));
|
|
85
|
+
return () => host.removeEventListener('context-request', answer);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/controller.d.ts
CHANGED
|
@@ -1,54 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The canvas side of the viewer: a `DiffSession` (state, commands, events; `session.ts`) plus
|
|
3
|
+
* the one view that draws it (RFC 0001 §1: renderer, camera, framing, minimap), behind the
|
|
4
|
+
* `SessionView` boundary. Phase 3 of the RFC moves this view out into a `StageView` of its own,
|
|
5
|
+
* so one session can drive several canvases.
|
|
3
6
|
*
|
|
4
|
-
* -
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
*
|
|
12
|
-
* The UI subscribes to topic notifications (batched per microtask) and reads public fields.
|
|
7
|
+
* - draws the session's view state into the renderer (and the minimap, throttled while
|
|
8
|
+
* replaying);
|
|
9
|
+
* - frames what the session asks for in the free part of the canvas, clear of the chrome over
|
|
10
|
+
* it (`framing.ts`); the replay camera follows the playing hunk / chapter unless the user
|
|
11
|
+
* moved it in the last 2 s;
|
|
12
|
+
* - fits a new diff once the canvas is laid out, and again on resize with `autoFit`;
|
|
13
|
+
* - turns canvas hovers and clicks into session commands.
|
|
13
14
|
*/
|
|
14
|
-
import type {
|
|
15
|
-
import type { LayoutResult } from '@kgdiff/layout';
|
|
15
|
+
import type { Rect } from '@kgdiff/core';
|
|
16
16
|
import { type Camera } from '@kgdiff/renderer';
|
|
17
|
-
import { type ChangeFamily, type FocusState, type PaletteName, type Scene, type Theme, type ThemeName, type VisualResolver } from '@kgdiff/scene';
|
|
18
17
|
import { type ChromeLayout } from './framing.js';
|
|
19
|
-
import
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
import { ReplayClock } from './replay.js';
|
|
24
|
-
import { type StorageLike } from './review-store.js';
|
|
25
|
-
import { type SearchHit } from './search.js';
|
|
26
|
-
export type Status = 'idle' | 'loading' | 'ready' | 'error';
|
|
27
|
-
export type Topic = 'status' | 'data' | 'mode' | 'selection' | 'filters' | 'review' | 'replay' | 'hover' | 'theme' | 'locale' | 'focus' | 'swipe' | 'overview';
|
|
28
|
-
export interface ControllerHost {
|
|
29
|
-
ready(stats: DiffStats): void;
|
|
30
|
-
select(hunk: string | null, node: string | null): void;
|
|
31
|
-
mode(mode: ViewerMode, scope: ViewerScope): void;
|
|
32
|
-
review(hunk: string, reviewed: boolean, progress: ReviewState): void;
|
|
33
|
-
error(error: Error): void;
|
|
34
|
-
announce(text: string): void;
|
|
35
|
-
/** Playback reached the end of the replay; `loop`: it starts again after the loop delay. */
|
|
36
|
-
replayEnd(loop: boolean): void;
|
|
37
|
-
}
|
|
18
|
+
import { DiffSession, type SessionDeps, type SessionHost, type SessionView } from './session.js';
|
|
19
|
+
export type { Preference, Status, Topic } from './session.js';
|
|
20
|
+
export type ControllerHost = SessionHost;
|
|
21
|
+
export type ControllerDeps = SessionDeps;
|
|
38
22
|
export interface FitOptions {
|
|
39
23
|
readonly animate?: boolean;
|
|
40
24
|
/** Room around the content, px (default `FRAME_PADDING`); kept for later automatic fits. */
|
|
41
25
|
readonly padding?: number;
|
|
42
26
|
}
|
|
43
|
-
export interface ControllerDeps {
|
|
44
|
-
readonly now: () => number;
|
|
45
|
-
readonly requestFrame: (cb: (time: number) => void) => number;
|
|
46
|
-
readonly cancelFrame: (id: number) => void;
|
|
47
|
-
/** Resolves once the browser had a chance to paint (between loading steps). */
|
|
48
|
-
readonly yieldToPaint: () => Promise<void>;
|
|
49
|
-
readonly storage: StorageLike | null;
|
|
50
|
-
}
|
|
51
|
-
export type Preference = 'mode' | 'scope' | 'theme' | 'palette' | 'locale';
|
|
52
27
|
/** Camera follow is suppressed this long after the user moved the camera (ms). */
|
|
53
28
|
export declare const USER_CAMERA_GRACE = 2000;
|
|
54
29
|
/** The camera follows when less than this share of the target bounds is in view. */
|
|
@@ -61,41 +36,8 @@ export declare const FIT_MAX_ZOOM = 2.5;
|
|
|
61
36
|
export declare const OVERVIEW_COVERAGE = 0.98;
|
|
62
37
|
/** Share of `bounds` inside `view`, in [0, 1]. */
|
|
63
38
|
export declare function coverage(bounds: Rect, view: Rect): number;
|
|
64
|
-
export declare class ViewerController {
|
|
39
|
+
export declare class ViewerController extends DiffSession implements SessionView {
|
|
65
40
|
#private;
|
|
66
|
-
status: Status;
|
|
67
|
-
/** Steps of the current load, in order; `step` is the running one. */
|
|
68
|
-
steps: LoadStep[];
|
|
69
|
-
step: LoadStep | null;
|
|
70
|
-
error: Error | null;
|
|
71
|
-
data: LoadedDiff | null;
|
|
72
|
-
layout: LayoutResult | null;
|
|
73
|
-
scene: Scene | null;
|
|
74
|
-
resolver: VisualResolver | null;
|
|
75
|
-
list: ListModel;
|
|
76
|
-
mode: ViewerMode;
|
|
77
|
-
scope: ViewerScope;
|
|
78
|
-
themePreference: ThemePreference;
|
|
79
|
-
palette: PaletteName;
|
|
80
|
-
locale: Locale;
|
|
81
|
-
systemDark: boolean;
|
|
82
|
-
reducedMotion: boolean;
|
|
83
|
-
/** Preferences set explicitly by the embedder (a report's `view` does not override them). */
|
|
84
|
-
readonly explicit: Set<Preference>;
|
|
85
|
-
selectedHunk: number;
|
|
86
|
-
selectedNode: number;
|
|
87
|
-
/** An edge emphasized from the detail panel (drawn as hovered). */
|
|
88
|
-
pinnedEdge: number;
|
|
89
|
-
hoverNode: number;
|
|
90
|
-
hoverEdge: number;
|
|
91
|
-
hoverGroup: number;
|
|
92
|
-
readonly families: Set<ChangeFamily>;
|
|
93
|
-
hops: number;
|
|
94
|
-
readonly expanded: Set<string>;
|
|
95
|
-
focus: FocusState | null;
|
|
96
|
-
clock: ReplayClock | null;
|
|
97
|
-
split: number;
|
|
98
|
-
emphasis: number;
|
|
99
41
|
/**
|
|
100
42
|
* Keep the view fitted (embeds without controls): fit again when the canvas is resized unless
|
|
101
43
|
* the user moved the camera since, and at the start of every loop.
|
|
@@ -105,21 +47,7 @@ export declare class ViewerController {
|
|
|
105
47
|
selectOnClick: boolean;
|
|
106
48
|
/** The whole content is in view (the minimap has nothing to add). */
|
|
107
49
|
overview: boolean;
|
|
108
|
-
constructor(host:
|
|
109
|
-
subscribe(listener: (topics: ReadonlySet<Topic>) => void): () => void;
|
|
110
|
-
/** Deliver pending notifications now (also used by tests). */
|
|
111
|
-
flush(): void;
|
|
112
|
-
get themeName(): ThemeName;
|
|
113
|
-
get theme(): Theme;
|
|
114
|
-
get diff(): DiffResult | null;
|
|
115
|
-
get hunkCount(): number;
|
|
116
|
-
isReviewed(hunkId: string): boolean;
|
|
117
|
-
reviewState(): ReviewState;
|
|
118
|
-
search(query: string, limit?: number): SearchHit[];
|
|
119
|
-
load(options: LoadOptions): Promise<void>;
|
|
120
|
-
loadPayload(payload: ReportPayload): Promise<void>;
|
|
121
|
-
/** Show an error state (bad payload, failed load). */
|
|
122
|
-
fail(error: Error): void;
|
|
50
|
+
constructor(host: SessionHost, deps: SessionDeps);
|
|
123
51
|
attach(stage: HTMLElement, minimapHost: HTMLElement | null): void;
|
|
124
52
|
detach(): void;
|
|
125
53
|
destroy(): void;
|
|
@@ -141,108 +69,21 @@ export declare class ViewerController {
|
|
|
141
69
|
layoutChanged(): void;
|
|
142
70
|
/** The user panned / zoomed: suspend replay camera follow for `USER_CAMERA_GRACE`. */
|
|
143
71
|
noteUserCamera(): void;
|
|
144
|
-
/** Redraw on the next animation frame. */
|
|
145
|
-
invalidate(): void;
|
|
146
72
|
/** Resolve the current view and hand it to the renderer (and the minimap). */
|
|
147
73
|
draw(now?: number): void;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
/** Set mode and scope together (one notification, one `kgdiff-mode` event). */
|
|
157
|
-
setView(mode: ViewerMode, scope: ViewerScope): void;
|
|
158
|
-
selectHunkById(id: string | null, options?: {
|
|
159
|
-
fly?: boolean;
|
|
160
|
-
}): void;
|
|
161
|
-
/**
|
|
162
|
-
* Select hunk `h` (scene index; -1 clears). `node` focuses one of its nodes in the detail
|
|
163
|
-
* panel. `fly` (default true) brings it into view. In replay, seeks to the end of its window.
|
|
164
|
-
*/
|
|
165
|
-
selectHunk(h: number, options?: {
|
|
166
|
-
fly?: boolean;
|
|
167
|
-
node?: number;
|
|
168
|
-
}): void;
|
|
169
|
-
/** Select a node: its hunk when it has one, else the node itself. */
|
|
170
|
-
selectNode(i: number, options?: {
|
|
171
|
-
fly?: boolean;
|
|
172
|
-
}): void;
|
|
173
|
-
clearSelection(): void;
|
|
174
|
-
next(): void;
|
|
175
|
-
prev(): void;
|
|
176
|
-
first(): void;
|
|
177
|
-
last(): void;
|
|
178
|
-
/** Emphasize an edge (from the detail panel) and fly to it. */
|
|
179
|
-
pinEdge(j: number): void;
|
|
180
|
-
flyToHunk(h: number): void;
|
|
181
|
-
flyToNode(i: number): void;
|
|
182
|
-
flyToSelection(): void;
|
|
74
|
+
sceneChanged(): void;
|
|
75
|
+
installed(): void;
|
|
76
|
+
drawnChanged(): void;
|
|
77
|
+
show(bounds: Rect): void;
|
|
78
|
+
/** Follow `bounds` (replay): fly unless the user steered recently or it is mostly visible. */
|
|
79
|
+
follow(bounds: Rect): void;
|
|
80
|
+
looped(): void;
|
|
81
|
+
viewport(): Rect | null;
|
|
183
82
|
/**
|
|
184
83
|
* Fit everything visible (the focus in changes-only mode), labels included, into the free part
|
|
185
84
|
* of the canvas. Before the canvas is laid out it falls back to the renderer's own fit.
|
|
186
85
|
*/
|
|
187
86
|
fit(options?: FitOptions): Promise<void>;
|
|
188
87
|
zoom(direction: 1 | -1): void;
|
|
189
|
-
/** Clear hover state (pointer left the canvas). */
|
|
190
|
-
clearHover(): void;
|
|
191
|
-
toggleFamily(family: ChangeFamily): void;
|
|
192
|
-
/** Replace the family filter (empty = all). Setting the current set again clears it. */
|
|
193
|
-
setFamilies(families: readonly ChangeFamily[]): void;
|
|
194
|
-
setHops(hops: number): void;
|
|
195
|
-
/**
|
|
196
|
-
* Expand collapsed group `index` of the current focus: its in-scene members become visible
|
|
197
|
-
* and, for a `changes`-scoped layout, the neighbours left out of the layout are placed with
|
|
198
|
-
* `extendLayout` (nothing already placed moves) and the scene is rebuilt.
|
|
199
|
-
*/
|
|
200
|
-
expandGroup(index: number): void;
|
|
201
|
-
/**
|
|
202
|
-
* The collapsed group nearest the selection (else the view center), or -1. Groups that can
|
|
203
|
-
* be expanded at least partly come first.
|
|
204
|
-
*/
|
|
205
|
-
nearestGroup(): number;
|
|
206
|
-
/** Expand the group nearest the selection (keyboard `e`); announces what happened. */
|
|
207
|
-
expandNearest(): void;
|
|
208
|
-
/**
|
|
209
|
-
* Whether collapsed group `index` can be expanded completely: always, unless some members lie
|
|
210
|
-
* outside a `changes`-scoped layout and the layout engine is known to be unavailable
|
|
211
|
-
* (standalone report without the compute add-on).
|
|
212
|
-
*/
|
|
213
|
-
canExpand(index: number): boolean;
|
|
214
|
-
/** Bring a union node into the scene and the focus (search results), then select it. */
|
|
215
|
-
revealNode(id: UnionId): Promise<void>;
|
|
216
|
-
play(): void;
|
|
217
|
-
/** Pause; a looping replay stays paused (until `play`, a new diff or loop turned on again). */
|
|
218
|
-
pause(): void;
|
|
219
|
-
togglePlay(): void;
|
|
220
|
-
/**
|
|
221
|
-
* Play the replay over and over: `delay` ms after it ends it starts again; null plays it
|
|
222
|
-
* once. Turning the loop on starts a replay that is shown but not playing.
|
|
223
|
-
*/
|
|
224
|
-
setLoop(delay: number | null): void;
|
|
225
|
-
get loopDelay(): number | null;
|
|
226
|
-
/**
|
|
227
|
-
* Hold playback while the pointer rests on the graph (`pause-on-hover`): a playing replay
|
|
228
|
-
* pauses and continues on release; a pending loop restart waits for the release, then the
|
|
229
|
-
* full loop delay.
|
|
230
|
-
*/
|
|
231
|
-
hold(held: boolean): void;
|
|
232
|
-
seek(t: number): void;
|
|
233
|
-
stepReplay(direction: 1 | -1): void;
|
|
234
|
-
restart(): void;
|
|
235
|
-
cycleSpeed(): void;
|
|
236
|
-
setSpeed(speed: number): void;
|
|
237
|
-
setSplit(split: number): void;
|
|
238
|
-
setReviewed(hunkId: string, reviewed: boolean): void;
|
|
239
|
-
/** Another tab changed review progress (`storage` event): re-read it. */
|
|
240
|
-
syncReview(key: string | null): void;
|
|
241
|
-
toggleReviewed(hunkId?: string): void;
|
|
242
|
-
setThemePreference(pref: ThemePreference): void;
|
|
243
|
-
setPalette(palette: PaletteName): void;
|
|
244
|
-
setLocale(locale: Locale): void;
|
|
245
|
-
setSystemDark(dark: boolean): void;
|
|
246
|
-
setReducedMotion(reduced: boolean): void;
|
|
247
88
|
}
|
|
248
89
|
//# sourceMappingURL=controller.d.ts.map
|
package/dist/controller.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACL,KAAK,MAAM,EAMZ,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EACL,KAAK,YAAY,EAOlB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EAEX,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC9D,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC;AACzC,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC;AAEzC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,oFAAoF;AACpF,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,sFAAsF;AACtF,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,0EAA0E;AAC1E,eAAO,MAAM,YAAY,MAAM,CAAC;AAGhC,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAQtC,kDAAkD;AAClD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAazD;AAED,qBAAa,gBAAiB,SAAQ,WAAY,YAAW,WAAW;;IACtE;;;OAGG;IACH,OAAO,UAAS;IAChB,qFAAqF;IACrF,aAAa,UAAQ;IACrB,qEAAqE;IACrE,QAAQ,UAAQ;IAyBhB,YAAY,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAI/C;IAID,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAsBhE;IAED,MAAM,IAAI,IAAI,CASb;IAEQ,OAAO,IAAI,IAAI,CAGvB;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,YAAY,CAAC,GAAG,IAAI,GAAG,IAAI,CAErD;IAED;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAGrC;IAED;;;OAGG;IACH,aAAa,IAAI,IAAI,CAmBpB;IAED,sFAAsF;IACtF,cAAc,IAAI,IAAI,CAGrB;IAID,8EAA8E;IAC9E,IAAI,CAAC,GAAG,SAAc,GAAG,IAAI,CA0B5B;IAED,YAAY,IAAI,IAAI,CAKnB;IAED,SAAS,IAAI,IAAI,CAMhB;IAED,YAAY,IAAI,IAAI,CAGnB;IAED,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CAEvB;IAED,8FAA8F;IAC9F,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CAKzB;IAED,MAAM,IAAI,IAAI,CAEb;IAED,QAAQ,IAAI,IAAI,GAAG,IAAI,CAEtB;IA8BD;;;OAGG;IACH,GAAG,CAAC,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3C;IAqED,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAG5B;CA4CF"}
|