@kgdiff/viewer 0.3.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/README.md +9 -8
- 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 +30 -173
- package/dist/controller.d.ts.map +1 -1
- package/dist/controller.js +94 -1099
- package/dist/controller.js.map +1 -1
- package/dist/element.d.ts +12 -6
- package/dist/element.d.ts.map +1 -1
- package/dist/element.js +105 -236
- package/dist/element.js.map +1 -1
- package/dist/hash-sync.d.ts +4 -2
- package/dist/hash-sync.d.ts.map +1 -1
- package/dist/hash-sync.js +21 -5
- package/dist/hash-sync.js.map +1 -1
- package/dist/i18n.d.ts +7 -7
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +14 -14
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +24 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keyboard.d.ts +6 -4
- package/dist/keyboard.d.ts.map +1 -1
- package/dist/keyboard.js +6 -5
- package/dist/keyboard.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/prefs.d.ts +7 -1
- package/dist/prefs.d.ts.map +1 -1
- package/dist/prefs.js +15 -3
- package/dist/prefs.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 +270 -295
- 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 +21 -5
- package/dist/ui/context.d.ts.map +1 -1
- package/dist/ui/context.js.map +1 -1
- package/dist/ui/dock.d.ts +17 -0
- package/dist/ui/dock.d.ts.map +1 -0
- package/dist/ui/dock.js +151 -0
- package/dist/ui/dock.js.map +1 -0
- 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.d.ts +7 -2
- package/dist/ui/header.d.ts.map +1 -1
- package/dist/ui/header.js +26 -135
- package/dist/ui/header.js.map +1 -1
- package/dist/ui/popovers.d.ts.map +1 -1
- package/dist/ui/popovers.js +3 -2
- package/dist/ui/popovers.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 -538
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/stage.d.ts +4 -0
- package/dist/ui/stage.d.ts.map +1 -1
- package/dist/ui/stage.js +42 -95
- package/dist/ui/stage.js.map +1 -1
- package/dist/ui/swatch.d.ts +7 -0
- package/dist/ui/swatch.d.ts.map +1 -0
- package/dist/ui/swatch.js +26 -0
- package/dist/ui/swatch.js.map +1 -0
- package/package.json +6 -6
- package/src/context.ts +106 -0
- package/src/controller.ts +120 -1196
- package/src/element.ts +114 -254
- package/src/hash-sync.ts +20 -6
- package/src/i18n.ts +15 -14
- package/src/index.ts +24 -10
- package/src/keyboard.ts +12 -6
- package/src/pipeline.ts +4 -1
- package/src/prefs.ts +19 -4
- package/src/root.ts +308 -0
- package/src/schedule.ts +43 -0
- package/src/session.ts +1386 -0
- package/src/styles.ts +277 -299
- package/src/theme.ts +167 -0
- package/src/ui/change-list.ts +401 -0
- package/src/ui/context.ts +23 -5
- package/src/ui/dock.ts +198 -0
- package/src/ui/filters.ts +79 -0
- package/src/ui/header.ts +40 -170
- package/src/ui/popovers.ts +3 -2
- package/src/ui/search.ts +220 -0
- package/src/ui/sidebar.ts +28 -667
- package/src/ui/stage.ts +50 -115
- package/src/ui/swatch.ts +31 -0
package/dist/prefs.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeLocale } from './i18n.js';
|
|
2
|
-
const MODES = ['overlay', 'swipe', 'replay'
|
|
2
|
+
const MODES = ['overlay', 'swipe', 'replay'];
|
|
3
|
+
const SCOPES = ['all', 'changes'];
|
|
3
4
|
const THEMES = ['auto', 'light', 'dark'];
|
|
4
5
|
const PALETTES = ['default', 'colorblind'];
|
|
5
6
|
const CHROMES = ['full', 'none'];
|
|
@@ -10,6 +11,14 @@ export const THEME_PREFERENCES = THEMES;
|
|
|
10
11
|
export function toMode(value) {
|
|
11
12
|
return MODES.includes(value) ? value : null;
|
|
12
13
|
}
|
|
14
|
+
export function toScope(value) {
|
|
15
|
+
return SCOPES.includes(value) ? value : null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Before scopes existed, “changes only” was a fourth mode. Attributes, properties, deep links
|
|
19
|
+
* and reports may still say `changes`: it means overlay + the `changes` scope.
|
|
20
|
+
*/
|
|
21
|
+
export const LEGACY_CHANGES_MODE = 'changes';
|
|
13
22
|
export function toTheme(value) {
|
|
14
23
|
return THEMES.includes(value) ? value : null;
|
|
15
24
|
}
|
|
@@ -35,16 +44,19 @@ export function sanitizeView(view) {
|
|
|
35
44
|
if (typeof view !== 'object' || view === null)
|
|
36
45
|
return undefined;
|
|
37
46
|
const v = view;
|
|
38
|
-
const
|
|
47
|
+
const legacy = v.mode === LEGACY_CHANGES_MODE;
|
|
48
|
+
const mode = legacy ? 'overlay' : toMode(v.mode);
|
|
49
|
+
const scope = toScope(v.scope) ?? (legacy && v.scope === undefined ? 'changes' : null);
|
|
39
50
|
const theme = toTheme(v.theme);
|
|
40
51
|
const palette = toPalette(v.palette);
|
|
41
52
|
const locale = toLocale(v.locale);
|
|
42
|
-
const dropped = ['mode', 'theme', 'palette', 'locale'].filter((k) => v[k] !== undefined && { mode, theme, palette, locale }[k] === null);
|
|
53
|
+
const dropped = ['mode', 'scope', 'theme', 'palette', 'locale'].filter((k) => v[k] !== undefined && { mode, scope, theme, palette, locale }[k] === null);
|
|
43
54
|
if (dropped.length > 0 && typeof console !== 'undefined') {
|
|
44
55
|
console.warn(`[kgdiff] ignoring invalid report view preferences: ${dropped.join(', ')}`);
|
|
45
56
|
}
|
|
46
57
|
return {
|
|
47
58
|
...(mode ? { mode } : {}),
|
|
59
|
+
...(scope ? { scope } : {}),
|
|
48
60
|
...(theme ? { theme } : {}),
|
|
49
61
|
...(palette ? { palette } : {}),
|
|
50
62
|
...(locale ? { locale } : {}),
|
package/dist/prefs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefs.js","sourceRoot":"","sources":["../src/prefs.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"prefs.js","sourceRoot":"","sources":["../src/prefs.ts"],"names":[],"mappings":"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"}
|
package/dist/root.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ViewerController } from './controller.js';
|
|
2
|
+
import type { Topic } from './session.js';
|
|
3
|
+
import type { FocusTarget, UiActions, UiContext } from './ui/context.js';
|
|
4
|
+
/** Something the root renders: a region, or the layout itself. */
|
|
5
|
+
export interface Region {
|
|
6
|
+
update(topics: ReadonlySet<Topic>): void;
|
|
7
|
+
}
|
|
8
|
+
/** What a root provides to the regions that bind to it. */
|
|
9
|
+
export interface ViewerContext {
|
|
10
|
+
readonly controller: ViewerController;
|
|
11
|
+
readonly actions: UiActions;
|
|
12
|
+
/** The element the root's events are dispatched on and its tokens are set on. */
|
|
13
|
+
readonly host: HTMLElement;
|
|
14
|
+
/** Render `region` on every notification (in binding order); returns the detach. */
|
|
15
|
+
attach(region: Region): () => void;
|
|
16
|
+
target(name: FocusTarget, focus: () => void): () => void;
|
|
17
|
+
focus(name: FocusTarget): boolean;
|
|
18
|
+
/** The keyboard map, for a key event that reached the root. */
|
|
19
|
+
handleKey(e: KeyboardEvent): void;
|
|
20
|
+
}
|
|
21
|
+
export declare const viewerContext: import("./context.js").Context<ViewerContext>;
|
|
22
|
+
export declare class ViewerRoot implements ViewerContext {
|
|
23
|
+
#private;
|
|
24
|
+
readonly controller: ViewerController;
|
|
25
|
+
/** The single polite live region announcing navigation ("Change 3 of 12: …"). */
|
|
26
|
+
readonly live: HTMLDivElement;
|
|
27
|
+
readonly host: HTMLElement;
|
|
28
|
+
readonly actions: UiActions;
|
|
29
|
+
/**
|
|
30
|
+
* `host` dispatches the events and computes the tokens set on `shadow` (its shadow root);
|
|
31
|
+
* `emitted` runs after each event was dispatched.
|
|
32
|
+
*/
|
|
33
|
+
constructor(host: HTMLElement, shadow: ShadowRoot, actions: UiActions, emitted?: (type: string) => void);
|
|
34
|
+
/**
|
|
35
|
+
* Provide the session to the regions and follow the system's color scheme and motion
|
|
36
|
+
* preference and other tabs' review progress; returns the function that stops it all.
|
|
37
|
+
*/
|
|
38
|
+
connect(): () => void;
|
|
39
|
+
attach(region: Region): () => void;
|
|
40
|
+
target(name: FocusTarget, focus: () => void): () => void;
|
|
41
|
+
focus(name: FocusTarget): boolean;
|
|
42
|
+
announce(text: string): void;
|
|
43
|
+
/** Render every region, never throwing: a failure shows the error state with safe defaults. */
|
|
44
|
+
render(topics: ReadonlySet<Topic>): void;
|
|
45
|
+
handleKey(e: KeyboardEvent): void;
|
|
46
|
+
}
|
|
47
|
+
/** The UI context of a region placed in `root` (its shadow tree), bound to `ctx`. */
|
|
48
|
+
export declare function uiContext(ctx: ViewerContext, root: ShadowRoot): UiContext;
|
|
49
|
+
/**
|
|
50
|
+
* Bind a region to the root nearest `anchor` (an element where the region is placed): `make`
|
|
51
|
+
* builds it once the root answers, and the root renders it from then on.
|
|
52
|
+
*/
|
|
53
|
+
export declare function bindRegion<R extends Region>(anchor: Element, make: (ui: UiContext) => R): R;
|
|
54
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../src/root.ts"],"names":[],"mappings":"AAYA,OAAO,EAAuB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOxE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEzE,kEAAkE;AAClE,MAAM,WAAW,MAAM;IACrB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,iFAAiF;IACjF,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,oFAAoF;IACpF,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IACzD,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;IAClC,+DAA+D;IAC/D,SAAS,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,aAAa,+CAAkD,CAAC;AAQ7E,qBAAa,UAAW,YAAW,aAAa;;IAC9C,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,iFAAiF;IACjF,QAAQ,CAAC,IAAI,iBAAgF;IAC7F,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAM5B;;;OAGG;IACH,YACE,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAiCjC;IAED;;;OAGG;IACH,OAAO,IAAI,MAAM,IAAI,CAsBpB;IAED,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAMjC;IAED,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAQvD;IAED,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAIhC;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAO3B;IAED,+FAA+F;IAC/F,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAcvC;IAWD,SAAS,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAuFhC;CACF;AAED,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,SAAS,CAQzE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC,CAU3F"}
|
package/dist/root.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { createContext, provideContext, requestContext } from './context.js';
|
|
2
|
+
import { ViewerController } from './controller.js';
|
|
3
|
+
import { h } from './dom.js';
|
|
4
|
+
import { isTypingTarget, keyAction } from './keyboard.js';
|
|
5
|
+
import { THEME_PREFERENCES } from './prefs.js';
|
|
6
|
+
import { defaultStorage } from './review-store.js';
|
|
7
|
+
import { cancelFrame, nextPaint, requestFrame } from './schedule.js';
|
|
8
|
+
import { stylesheet } from './styles.js';
|
|
9
|
+
import { themeFromStyle, tokenSheet } from './theme.js';
|
|
10
|
+
export const viewerContext = createContext('kgdiff.viewer/1');
|
|
11
|
+
function media(query) {
|
|
12
|
+
return typeof window !== 'undefined' && typeof window.matchMedia === 'function'
|
|
13
|
+
? window.matchMedia(query)
|
|
14
|
+
: null;
|
|
15
|
+
}
|
|
16
|
+
export class ViewerRoot {
|
|
17
|
+
controller;
|
|
18
|
+
/** The single polite live region announcing navigation ("Change 3 of 12: …"). */
|
|
19
|
+
live = h('div', { class: 'sr-only', 'aria-live': 'polite', 'aria-atomic': 'true' });
|
|
20
|
+
host;
|
|
21
|
+
actions;
|
|
22
|
+
#shadow;
|
|
23
|
+
#regions = [];
|
|
24
|
+
#targets = new Map();
|
|
25
|
+
#renderFailed = false;
|
|
26
|
+
/**
|
|
27
|
+
* `host` dispatches the events and computes the tokens set on `shadow` (its shadow root);
|
|
28
|
+
* `emitted` runs after each event was dispatched.
|
|
29
|
+
*/
|
|
30
|
+
constructor(host, shadow, actions, emitted) {
|
|
31
|
+
this.host = host;
|
|
32
|
+
this.#shadow = shadow;
|
|
33
|
+
this.actions = actions;
|
|
34
|
+
const emit = (type, detail) => {
|
|
35
|
+
host.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));
|
|
36
|
+
emitted?.(type);
|
|
37
|
+
};
|
|
38
|
+
const events = {
|
|
39
|
+
ready: (stats) => emit('kgdiff-ready', { stats }),
|
|
40
|
+
select: (hunk, node) => emit('kgdiff-select', { hunk, node }),
|
|
41
|
+
mode: (mode, scope) => emit('kgdiff-mode', { mode, scope }),
|
|
42
|
+
review: (hunk, reviewed, progress) => emit('kgdiff-review', { hunk, reviewed, progress }),
|
|
43
|
+
error: (error) => emit('kgdiff-error', { error }),
|
|
44
|
+
announce: (text) => this.announce(text),
|
|
45
|
+
replayEnd: (loop) => emit('kgdiff-replay-end', { loop }),
|
|
46
|
+
};
|
|
47
|
+
this.controller = new ViewerController(events, {
|
|
48
|
+
now: () => (typeof performance !== 'undefined' ? performance.now() : Date.now()),
|
|
49
|
+
requestFrame,
|
|
50
|
+
cancelFrame,
|
|
51
|
+
yieldToPaint: nextPaint,
|
|
52
|
+
storage: defaultStorage(),
|
|
53
|
+
// The one place the token set is applied: the canvas then draws with the tokens as
|
|
54
|
+
// computed on the host (page styles win).
|
|
55
|
+
theme: (base) => {
|
|
56
|
+
this.#tokens(base);
|
|
57
|
+
const view = host.ownerDocument.defaultView;
|
|
58
|
+
return view ? themeFromStyle(base, view.getComputedStyle(host)) : base;
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
this.controller.subscribe((topics) => this.render(topics));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Provide the session to the regions and follow the system's color scheme and motion
|
|
65
|
+
* preference and other tabs' review progress; returns the function that stops it all.
|
|
66
|
+
*/
|
|
67
|
+
connect() {
|
|
68
|
+
const c = this.controller;
|
|
69
|
+
const stop = [provideContext(this.host, viewerContext, () => this)];
|
|
70
|
+
const dark = media('(prefers-color-scheme: light)');
|
|
71
|
+
const motion = media('(prefers-reduced-motion: reduce)');
|
|
72
|
+
const apply = () => {
|
|
73
|
+
c.setSystemDark(!(dark?.matches ?? false));
|
|
74
|
+
c.setReducedMotion(motion?.matches ?? false);
|
|
75
|
+
};
|
|
76
|
+
for (const q of [dark, motion]) {
|
|
77
|
+
q?.addEventListener?.('change', apply);
|
|
78
|
+
stop.push(() => q?.removeEventListener?.('change', apply));
|
|
79
|
+
}
|
|
80
|
+
apply();
|
|
81
|
+
// Page styles may override tokens now that the host is in the document.
|
|
82
|
+
c.refreshTheme();
|
|
83
|
+
const onStorage = (e) => c.syncReview(e.key);
|
|
84
|
+
window.addEventListener('storage', onStorage);
|
|
85
|
+
stop.push(() => window.removeEventListener('storage', onStorage));
|
|
86
|
+
return () => {
|
|
87
|
+
for (const fn of stop)
|
|
88
|
+
fn();
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
attach(region) {
|
|
92
|
+
this.#regions.push(region);
|
|
93
|
+
return () => {
|
|
94
|
+
const i = this.#regions.indexOf(region);
|
|
95
|
+
if (i >= 0)
|
|
96
|
+
this.#regions.splice(i, 1);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
target(name, focus) {
|
|
100
|
+
const list = this.#targets.get(name) ?? [];
|
|
101
|
+
this.#targets.set(name, list);
|
|
102
|
+
list.push(focus);
|
|
103
|
+
return () => {
|
|
104
|
+
const i = list.indexOf(focus);
|
|
105
|
+
if (i >= 0)
|
|
106
|
+
list.splice(i, 1);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
focus(name) {
|
|
110
|
+
const focus = this.#targets.get(name)?.at(-1);
|
|
111
|
+
focus?.();
|
|
112
|
+
return focus !== undefined;
|
|
113
|
+
}
|
|
114
|
+
announce(text) {
|
|
115
|
+
const live = this.live;
|
|
116
|
+
live.textContent = '';
|
|
117
|
+
// A fresh text node in a later task makes screen readers announce repeats too.
|
|
118
|
+
setTimeout(() => {
|
|
119
|
+
live.textContent = text;
|
|
120
|
+
}, 30);
|
|
121
|
+
}
|
|
122
|
+
/** Render every region, never throwing: a failure shows the error state with safe defaults. */
|
|
123
|
+
render(topics) {
|
|
124
|
+
try {
|
|
125
|
+
for (const region of this.#regions)
|
|
126
|
+
region.update(topics);
|
|
127
|
+
this.#renderFailed = false;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error('[kgdiff] render failed:', error);
|
|
131
|
+
if (this.#renderFailed)
|
|
132
|
+
return;
|
|
133
|
+
this.#renderFailed = true;
|
|
134
|
+
const c = this.controller;
|
|
135
|
+
c.explicit.clear();
|
|
136
|
+
c.setThemePreference('auto');
|
|
137
|
+
c.setPalette('default');
|
|
138
|
+
c.fail(error instanceof Error ? error : new Error(String(error)));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Apply the token set of `base` (a built-in theme) on the host, in the host's document. */
|
|
142
|
+
#tokens(base) {
|
|
143
|
+
const doc = this.host.ownerDocument;
|
|
144
|
+
const tokens = tokenSheet(base, doc);
|
|
145
|
+
if (this.#shadow.adoptedStyleSheets[1] !== tokens) {
|
|
146
|
+
this.#shadow.adoptedStyleSheets = [stylesheet(doc), tokens];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
handleKey(e) {
|
|
150
|
+
const target = e.composedPath()[0] ?? null;
|
|
151
|
+
if (isTypingTarget(target))
|
|
152
|
+
return;
|
|
153
|
+
const c = this.controller;
|
|
154
|
+
const action = keyAction(e, c.mode, c.scope);
|
|
155
|
+
if (!action)
|
|
156
|
+
return;
|
|
157
|
+
// Enter / Space on a focused control activate that control.
|
|
158
|
+
const el = target;
|
|
159
|
+
if ((e.key === 'Enter' || e.key === ' ') &&
|
|
160
|
+
el?.closest?.('button, a, summary, [role="radio"], [role="menuitemradio"]')) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (c.status !== 'ready' && !['help', 'theme', 'sidebar', 'escape'].includes(action.type))
|
|
164
|
+
return;
|
|
165
|
+
e.preventDefault();
|
|
166
|
+
const a = this.actions;
|
|
167
|
+
switch (action.type) {
|
|
168
|
+
case 'mode':
|
|
169
|
+
c.setMode(action.mode);
|
|
170
|
+
break;
|
|
171
|
+
case 'scope':
|
|
172
|
+
c.toggleScope();
|
|
173
|
+
break;
|
|
174
|
+
case 'next':
|
|
175
|
+
c.next();
|
|
176
|
+
break;
|
|
177
|
+
case 'prev':
|
|
178
|
+
c.prev();
|
|
179
|
+
break;
|
|
180
|
+
case 'first':
|
|
181
|
+
c.first();
|
|
182
|
+
break;
|
|
183
|
+
case 'last':
|
|
184
|
+
c.last();
|
|
185
|
+
break;
|
|
186
|
+
case 'fly':
|
|
187
|
+
c.flyToSelection();
|
|
188
|
+
break;
|
|
189
|
+
case 'escape':
|
|
190
|
+
// An active search is cleared first (focus goes back to it).
|
|
191
|
+
if (c.query) {
|
|
192
|
+
c.setQuery('');
|
|
193
|
+
this.focus('search');
|
|
194
|
+
}
|
|
195
|
+
else
|
|
196
|
+
c.clearSelection();
|
|
197
|
+
break;
|
|
198
|
+
case 'play-pause':
|
|
199
|
+
c.togglePlay();
|
|
200
|
+
break;
|
|
201
|
+
case 'step':
|
|
202
|
+
c.stepReplay(action.direction);
|
|
203
|
+
break;
|
|
204
|
+
case 'divider':
|
|
205
|
+
c.setSplit(c.split + action.delta);
|
|
206
|
+
break;
|
|
207
|
+
case 'fit':
|
|
208
|
+
void c.fit();
|
|
209
|
+
break;
|
|
210
|
+
case 'zoom':
|
|
211
|
+
c.zoom(action.direction);
|
|
212
|
+
break;
|
|
213
|
+
case 'search':
|
|
214
|
+
a.focusSearch();
|
|
215
|
+
break;
|
|
216
|
+
case 'review':
|
|
217
|
+
c.toggleReviewed();
|
|
218
|
+
break;
|
|
219
|
+
case 'sidebar':
|
|
220
|
+
a.toggleSidebar();
|
|
221
|
+
break;
|
|
222
|
+
case 'theme': {
|
|
223
|
+
const i = THEME_PREFERENCES.indexOf(c.themePreference);
|
|
224
|
+
a.setThemePreference(THEME_PREFERENCES[(i + 1) % THEME_PREFERENCES.length]);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
case 'help':
|
|
228
|
+
a.openHelp();
|
|
229
|
+
break;
|
|
230
|
+
case 'expand':
|
|
231
|
+
c.expandNearest();
|
|
232
|
+
break;
|
|
233
|
+
default:
|
|
234
|
+
action;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/** The UI context of a region placed in `root` (its shadow tree), bound to `ctx`. */
|
|
239
|
+
export function uiContext(ctx, root) {
|
|
240
|
+
return {
|
|
241
|
+
...ctx.actions,
|
|
242
|
+
controller: ctx.controller,
|
|
243
|
+
root,
|
|
244
|
+
target: (name, focus) => ctx.target(name, focus),
|
|
245
|
+
focus: (name) => ctx.focus(name),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Bind a region to the root nearest `anchor` (an element where the region is placed): `make`
|
|
250
|
+
* builds it once the root answers, and the root renders it from then on.
|
|
251
|
+
*/
|
|
252
|
+
export function bindRegion(anchor, make) {
|
|
253
|
+
const bound = {};
|
|
254
|
+
requestContext(anchor, viewerContext, (ctx) => {
|
|
255
|
+
if (bound.region)
|
|
256
|
+
return;
|
|
257
|
+
bound.region = make(uiContext(ctx, anchor.getRootNode()));
|
|
258
|
+
ctx.attach(bound.region);
|
|
259
|
+
});
|
|
260
|
+
// Phase 1: regions are bound by the layout that owns the root, which answers at once.
|
|
261
|
+
if (!bound.region)
|
|
262
|
+
throw new Error('[kgdiff] a region found no root to bind to.');
|
|
263
|
+
return bound.region;
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=root.js.map
|
package/dist/root.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../src/root.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frames (RFC 0001 §1, Scheduling).
|
|
3
|
+
*
|
|
4
|
+
* The session's frame loop runs on animation frames only (`requestFrame`). It pauses where the
|
|
5
|
+
* browser pauses them, so a looping replay in a background tab costs nothing, and under load it
|
|
6
|
+
* never draws a frame that is not presented.
|
|
7
|
+
*
|
|
8
|
+
* One-off work that must not wait forever races a frame against a timer (`frameOrTimeout`):
|
|
9
|
+
* the loading steps and the change list's window. A hidden embedding container (an inactive
|
|
10
|
+
* tab panel, a collapsed notebook output, a background pane) can pause animation frames without
|
|
11
|
+
* the page reporting itself hidden; with frames alone, loading stalled there.
|
|
12
|
+
*/
|
|
13
|
+
/** One-off work waits at most this long for a frame (ms). */
|
|
14
|
+
export declare const FRAME_TIMEOUT = 32;
|
|
15
|
+
/** The next animation frame (0, and no call, where there are none). */
|
|
16
|
+
export declare function requestFrame(cb: (time: number) => void): number;
|
|
17
|
+
export declare function cancelFrame(id: number): void;
|
|
18
|
+
/** Call `cb` once: on the next animation frame, or after `FRAME_TIMEOUT` ms if none came. */
|
|
19
|
+
export declare function frameOrTimeout(cb: () => void): void;
|
|
20
|
+
/** Resolve once the browser had a chance to paint (between loading steps). */
|
|
21
|
+
export declare function nextPaint(): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../src/schedule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,6DAA6D;AAC7D,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,CAE/D;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAWnD;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzC"}
|
package/dist/schedule.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frames (RFC 0001 §1, Scheduling).
|
|
3
|
+
*
|
|
4
|
+
* The session's frame loop runs on animation frames only (`requestFrame`). It pauses where the
|
|
5
|
+
* browser pauses them, so a looping replay in a background tab costs nothing, and under load it
|
|
6
|
+
* never draws a frame that is not presented.
|
|
7
|
+
*
|
|
8
|
+
* One-off work that must not wait forever races a frame against a timer (`frameOrTimeout`):
|
|
9
|
+
* the loading steps and the change list's window. A hidden embedding container (an inactive
|
|
10
|
+
* tab panel, a collapsed notebook output, a background pane) can pause animation frames without
|
|
11
|
+
* the page reporting itself hidden; with frames alone, loading stalled there.
|
|
12
|
+
*/
|
|
13
|
+
/** One-off work waits at most this long for a frame (ms). */
|
|
14
|
+
export const FRAME_TIMEOUT = 32;
|
|
15
|
+
/** The next animation frame (0, and no call, where there are none). */
|
|
16
|
+
export function requestFrame(cb) {
|
|
17
|
+
return typeof requestAnimationFrame === 'function' ? requestAnimationFrame(cb) : 0;
|
|
18
|
+
}
|
|
19
|
+
export function cancelFrame(id) {
|
|
20
|
+
if (typeof cancelAnimationFrame === 'function')
|
|
21
|
+
cancelAnimationFrame(id);
|
|
22
|
+
}
|
|
23
|
+
/** Call `cb` once: on the next animation frame, or after `FRAME_TIMEOUT` ms if none came. */
|
|
24
|
+
export function frameOrTimeout(cb) {
|
|
25
|
+
let done = false;
|
|
26
|
+
const run = () => {
|
|
27
|
+
if (done)
|
|
28
|
+
return;
|
|
29
|
+
done = true;
|
|
30
|
+
cancelFrame(raf);
|
|
31
|
+
clearTimeout(timer);
|
|
32
|
+
cb();
|
|
33
|
+
};
|
|
34
|
+
const timer = setTimeout(run, FRAME_TIMEOUT);
|
|
35
|
+
const raf = requestFrame(run);
|
|
36
|
+
}
|
|
37
|
+
/** Resolve once the browser had a chance to paint (between loading steps). */
|
|
38
|
+
export function nextPaint() {
|
|
39
|
+
return new Promise((resolve) => frameOrTimeout(() => setTimeout(resolve, 0)));
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../src/schedule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,6DAA6D;AAC7D,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAEhC,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,EAA0B;IACrD,OAAO,OAAO,qBAAqB,KAAK,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,IAAI,OAAO,oBAAoB,KAAK,UAAU;QAAE,oBAAoB,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,EAAc;IAC3C,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,MAAM,GAAG,GAAG,GAAS,EAAE;QACrB,IAAI,IAAI;YAAE,OAAO;QACjB,IAAI,GAAG,IAAI,CAAC;QACZ,WAAW,CAAC,GAAG,CAAC,CAAC;QACjB,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,EAAE,EAAE,CAAC;IACP,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,SAAS;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC"}
|