@kitlangton/knobs 0.4.0-next.7 → 0.4.0-next.8
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 +3 -1
- package/dist/types/ui/walkthrough-blocks.d.ts +15 -22
- package/dist/types/ui/walkthrough-model.d.ts +21 -2
- package/dist/ui-react.js +366 -133
- package/dist/ui-solid.js +366 -133
- package/dist/ui.js +367 -295
- package/package.json +1 -1
package/dist/ui.js
CHANGED
|
@@ -9662,6 +9662,171 @@ var init_compare = __esm(() => {
|
|
|
9662
9662
|
};
|
|
9663
9663
|
});
|
|
9664
9664
|
|
|
9665
|
+
// src/ui/player.ts
|
|
9666
|
+
function player(container, options) {
|
|
9667
|
+
const doc = container.ownerDocument;
|
|
9668
|
+
const el = (tag, cls) => {
|
|
9669
|
+
const n = doc.createElement(tag);
|
|
9670
|
+
n.className = cls;
|
|
9671
|
+
return n;
|
|
9672
|
+
};
|
|
9673
|
+
const look = {
|
|
9674
|
+
...options.preset ? { preset: options.preset } : {},
|
|
9675
|
+
...options.theme ? { theme: options.theme } : {},
|
|
9676
|
+
...options.appearance ? { appearance: options.appearance } : {}
|
|
9677
|
+
};
|
|
9678
|
+
const root = el("div", "knobs-player");
|
|
9679
|
+
root.setAttribute("role", "group");
|
|
9680
|
+
root.setAttribute("aria-label", options.label ?? "Video");
|
|
9681
|
+
applyLook2(root, options);
|
|
9682
|
+
const frame = el("div", "knobs-player-frame");
|
|
9683
|
+
frame.style.setProperty("--kp-aspect", String(options.aspect ?? 16 / 9));
|
|
9684
|
+
const v = el("video", "knobs-player-media");
|
|
9685
|
+
v.muted = options.muted ?? true;
|
|
9686
|
+
v.defaultMuted = v.muted;
|
|
9687
|
+
v.playsInline = true;
|
|
9688
|
+
v.preload = "metadata";
|
|
9689
|
+
v.setAttribute("playsinline", "");
|
|
9690
|
+
if (options.poster)
|
|
9691
|
+
v.poster = options.poster;
|
|
9692
|
+
if (options.captions) {
|
|
9693
|
+
const track = doc.createElement("track");
|
|
9694
|
+
track.kind = "captions";
|
|
9695
|
+
track.label = "Captions";
|
|
9696
|
+
track.srclang = doc.documentElement.lang || "en";
|
|
9697
|
+
track.default = true;
|
|
9698
|
+
track.src = options.captions;
|
|
9699
|
+
v.append(track);
|
|
9700
|
+
}
|
|
9701
|
+
frame.append(v);
|
|
9702
|
+
const host = el("div", "knobs-player-line");
|
|
9703
|
+
root.append(frame, host);
|
|
9704
|
+
container.append(root);
|
|
9705
|
+
const markers = (options.chapters ?? []).map((c, i) => ({
|
|
9706
|
+
id: c.id ?? `c${i}`,
|
|
9707
|
+
time: c.start,
|
|
9708
|
+
label: c.label
|
|
9709
|
+
}));
|
|
9710
|
+
const tl = timeline(host, {
|
|
9711
|
+
...look,
|
|
9712
|
+
variant: "line",
|
|
9713
|
+
duration: 1,
|
|
9714
|
+
fps: options.fps ?? 30,
|
|
9715
|
+
markers,
|
|
9716
|
+
repeat: options.loop ?? true,
|
|
9717
|
+
arrows: { step: 5, shift: 10 },
|
|
9718
|
+
label: options.label ? `${options.label} time` : "Video time",
|
|
9719
|
+
...options.hints === false ? { hints: false } : {}
|
|
9720
|
+
});
|
|
9721
|
+
const onFrame = () => root.setAttribute("data-ready", "");
|
|
9722
|
+
let pending = null;
|
|
9723
|
+
const seekVideo = (t) => {
|
|
9724
|
+
if (v.readyState < 1)
|
|
9725
|
+
return;
|
|
9726
|
+
if (v.seeking)
|
|
9727
|
+
pending = t;
|
|
9728
|
+
else
|
|
9729
|
+
v.currentTime = t;
|
|
9730
|
+
};
|
|
9731
|
+
let reported = 0;
|
|
9732
|
+
const onSeeked = () => {
|
|
9733
|
+
if (pending !== null) {
|
|
9734
|
+
const t = pending;
|
|
9735
|
+
pending = null;
|
|
9736
|
+
v.currentTime = t;
|
|
9737
|
+
return;
|
|
9738
|
+
}
|
|
9739
|
+
if (!v.paused || tl.playing || Math.abs(v.currentTime - reported) < 0.1)
|
|
9740
|
+
return;
|
|
9741
|
+
reported = v.currentTime;
|
|
9742
|
+
options.onSeek?.(reported);
|
|
9743
|
+
};
|
|
9744
|
+
const onMeta = () => {
|
|
9745
|
+
onFrame();
|
|
9746
|
+
if (v.videoWidth)
|
|
9747
|
+
frame.style.setProperty("--kp-aspect", String(v.videoWidth / v.videoHeight));
|
|
9748
|
+
if (Number.isFinite(v.duration))
|
|
9749
|
+
tl.update({ duration: v.duration });
|
|
9750
|
+
};
|
|
9751
|
+
v.addEventListener("loadedmetadata", onMeta);
|
|
9752
|
+
v.addEventListener("loadeddata", onFrame);
|
|
9753
|
+
v.addEventListener("seeked", onSeeked);
|
|
9754
|
+
const unlisten = tl.listen({
|
|
9755
|
+
onSeek(t, source) {
|
|
9756
|
+
if (source === "play") {
|
|
9757
|
+
if (Math.abs(v.currentTime - t) > 0.25)
|
|
9758
|
+
v.currentTime = t;
|
|
9759
|
+
return;
|
|
9760
|
+
}
|
|
9761
|
+
if (Math.abs(v.currentTime - t) < 1 / (options.fps ?? 30))
|
|
9762
|
+
return;
|
|
9763
|
+
seekVideo(t);
|
|
9764
|
+
},
|
|
9765
|
+
onPlay(on) {
|
|
9766
|
+
if (on)
|
|
9767
|
+
v.play().catch(() => tl.pause());
|
|
9768
|
+
else {
|
|
9769
|
+
v.pause();
|
|
9770
|
+
reported = tl.time;
|
|
9771
|
+
}
|
|
9772
|
+
root.toggleAttribute("data-playing", on);
|
|
9773
|
+
options.onPlay?.(on, tl.time);
|
|
9774
|
+
},
|
|
9775
|
+
onScrub(on) {
|
|
9776
|
+
if (on)
|
|
9777
|
+
v.pause();
|
|
9778
|
+
}
|
|
9779
|
+
});
|
|
9780
|
+
tl.drive(() => {
|
|
9781
|
+
if (v.readyState < 1)
|
|
9782
|
+
return Number.NaN;
|
|
9783
|
+
if (v.seeking)
|
|
9784
|
+
return tl.time;
|
|
9785
|
+
return v.ended ? Number.POSITIVE_INFINITY : v.currentTime;
|
|
9786
|
+
});
|
|
9787
|
+
const onClick = () => tl.focus();
|
|
9788
|
+
frame.addEventListener("click", onClick);
|
|
9789
|
+
v.src = options.src;
|
|
9790
|
+
const api = {
|
|
9791
|
+
element: root,
|
|
9792
|
+
video: v,
|
|
9793
|
+
timeline: tl,
|
|
9794
|
+
get time() {
|
|
9795
|
+
return tl.time;
|
|
9796
|
+
},
|
|
9797
|
+
get playing() {
|
|
9798
|
+
return tl.playing;
|
|
9799
|
+
},
|
|
9800
|
+
get duration() {
|
|
9801
|
+
return Number.isFinite(v.duration) ? v.duration : 0;
|
|
9802
|
+
},
|
|
9803
|
+
play: () => tl.play(),
|
|
9804
|
+
pause: () => tl.pause(),
|
|
9805
|
+
toggle: () => tl.toggle(),
|
|
9806
|
+
seek: (t, o) => tl.seek(t, o?.glide ? { glide: true } : undefined),
|
|
9807
|
+
seekBy: (d) => tl.seek(Math.min(tl.duration, Math.max(0, tl.time + d)), { glide: true }),
|
|
9808
|
+
focus: () => tl.focus(),
|
|
9809
|
+
dispose() {
|
|
9810
|
+
unlisten();
|
|
9811
|
+
tl.drive(null);
|
|
9812
|
+
tl.dispose();
|
|
9813
|
+
v.pause();
|
|
9814
|
+
frame.removeEventListener("click", onClick);
|
|
9815
|
+
v.removeEventListener("loadedmetadata", onMeta);
|
|
9816
|
+
v.removeEventListener("loadeddata", onFrame);
|
|
9817
|
+
v.removeEventListener("seeked", onSeeked);
|
|
9818
|
+
v.removeAttribute("src");
|
|
9819
|
+
v.load();
|
|
9820
|
+
root.remove();
|
|
9821
|
+
}
|
|
9822
|
+
};
|
|
9823
|
+
return api;
|
|
9824
|
+
}
|
|
9825
|
+
var init_player = __esm(() => {
|
|
9826
|
+
init_look();
|
|
9827
|
+
init_timeline();
|
|
9828
|
+
});
|
|
9829
|
+
|
|
9665
9830
|
// src/ui/scrollbar.ts
|
|
9666
9831
|
function overlayScrollbar(scroller, content) {
|
|
9667
9832
|
const doc = scroller.ownerDocument;
|
|
@@ -16379,169 +16544,8 @@ init_timeline();
|
|
|
16379
16544
|
init_timeline_model();
|
|
16380
16545
|
init_compare();
|
|
16381
16546
|
init_compare_strip();
|
|
16547
|
+
init_player();
|
|
16382
16548
|
|
|
16383
|
-
// src/ui/player.ts
|
|
16384
|
-
init_look();
|
|
16385
|
-
init_timeline();
|
|
16386
|
-
function player(container, options) {
|
|
16387
|
-
const doc = container.ownerDocument;
|
|
16388
|
-
const el = (tag, cls) => {
|
|
16389
|
-
const n = doc.createElement(tag);
|
|
16390
|
-
n.className = cls;
|
|
16391
|
-
return n;
|
|
16392
|
-
};
|
|
16393
|
-
const look = {
|
|
16394
|
-
...options.preset ? { preset: options.preset } : {},
|
|
16395
|
-
...options.theme ? { theme: options.theme } : {},
|
|
16396
|
-
...options.appearance ? { appearance: options.appearance } : {}
|
|
16397
|
-
};
|
|
16398
|
-
const root = el("div", "knobs-player");
|
|
16399
|
-
root.setAttribute("role", "group");
|
|
16400
|
-
root.setAttribute("aria-label", options.label ?? "Video");
|
|
16401
|
-
applyLook2(root, options);
|
|
16402
|
-
const frame = el("div", "knobs-player-frame");
|
|
16403
|
-
frame.style.setProperty("--kp-aspect", String(options.aspect ?? 16 / 9));
|
|
16404
|
-
const v = el("video", "knobs-player-media");
|
|
16405
|
-
v.muted = options.muted ?? true;
|
|
16406
|
-
v.defaultMuted = v.muted;
|
|
16407
|
-
v.playsInline = true;
|
|
16408
|
-
v.preload = "metadata";
|
|
16409
|
-
v.setAttribute("playsinline", "");
|
|
16410
|
-
if (options.poster)
|
|
16411
|
-
v.poster = options.poster;
|
|
16412
|
-
if (options.captions) {
|
|
16413
|
-
const track = doc.createElement("track");
|
|
16414
|
-
track.kind = "captions";
|
|
16415
|
-
track.label = "Captions";
|
|
16416
|
-
track.srclang = doc.documentElement.lang || "en";
|
|
16417
|
-
track.default = true;
|
|
16418
|
-
track.src = options.captions;
|
|
16419
|
-
v.append(track);
|
|
16420
|
-
}
|
|
16421
|
-
frame.append(v);
|
|
16422
|
-
const host = el("div", "knobs-player-line");
|
|
16423
|
-
root.append(frame, host);
|
|
16424
|
-
container.append(root);
|
|
16425
|
-
const markers = (options.chapters ?? []).map((c, i) => ({
|
|
16426
|
-
id: c.id ?? `c${i}`,
|
|
16427
|
-
time: c.start,
|
|
16428
|
-
label: c.label
|
|
16429
|
-
}));
|
|
16430
|
-
const tl = timeline(host, {
|
|
16431
|
-
...look,
|
|
16432
|
-
variant: "line",
|
|
16433
|
-
duration: 1,
|
|
16434
|
-
fps: options.fps ?? 30,
|
|
16435
|
-
markers,
|
|
16436
|
-
repeat: options.loop ?? true,
|
|
16437
|
-
arrows: { step: 5, shift: 10 },
|
|
16438
|
-
label: options.label ? `${options.label} time` : "Video time",
|
|
16439
|
-
...options.hints === false ? { hints: false } : {}
|
|
16440
|
-
});
|
|
16441
|
-
const onFrame = () => root.setAttribute("data-ready", "");
|
|
16442
|
-
let pending = null;
|
|
16443
|
-
const seekVideo = (t) => {
|
|
16444
|
-
if (v.readyState < 1)
|
|
16445
|
-
return;
|
|
16446
|
-
if (v.seeking)
|
|
16447
|
-
pending = t;
|
|
16448
|
-
else
|
|
16449
|
-
v.currentTime = t;
|
|
16450
|
-
};
|
|
16451
|
-
let reported = 0;
|
|
16452
|
-
const onSeeked = () => {
|
|
16453
|
-
if (pending !== null) {
|
|
16454
|
-
const t = pending;
|
|
16455
|
-
pending = null;
|
|
16456
|
-
v.currentTime = t;
|
|
16457
|
-
return;
|
|
16458
|
-
}
|
|
16459
|
-
if (!v.paused || tl.playing || Math.abs(v.currentTime - reported) < 0.1)
|
|
16460
|
-
return;
|
|
16461
|
-
reported = v.currentTime;
|
|
16462
|
-
options.onSeek?.(reported);
|
|
16463
|
-
};
|
|
16464
|
-
const onMeta = () => {
|
|
16465
|
-
onFrame();
|
|
16466
|
-
if (v.videoWidth)
|
|
16467
|
-
frame.style.setProperty("--kp-aspect", String(v.videoWidth / v.videoHeight));
|
|
16468
|
-
if (Number.isFinite(v.duration))
|
|
16469
|
-
tl.update({ duration: v.duration });
|
|
16470
|
-
};
|
|
16471
|
-
v.addEventListener("loadedmetadata", onMeta);
|
|
16472
|
-
v.addEventListener("loadeddata", onFrame);
|
|
16473
|
-
v.addEventListener("seeked", onSeeked);
|
|
16474
|
-
const unlisten = tl.listen({
|
|
16475
|
-
onSeek(t, source) {
|
|
16476
|
-
if (source === "play") {
|
|
16477
|
-
if (Math.abs(v.currentTime - t) > 0.25)
|
|
16478
|
-
v.currentTime = t;
|
|
16479
|
-
return;
|
|
16480
|
-
}
|
|
16481
|
-
if (Math.abs(v.currentTime - t) < 1 / (options.fps ?? 30))
|
|
16482
|
-
return;
|
|
16483
|
-
seekVideo(t);
|
|
16484
|
-
},
|
|
16485
|
-
onPlay(on) {
|
|
16486
|
-
if (on)
|
|
16487
|
-
v.play().catch(() => tl.pause());
|
|
16488
|
-
else {
|
|
16489
|
-
v.pause();
|
|
16490
|
-
reported = tl.time;
|
|
16491
|
-
}
|
|
16492
|
-
root.toggleAttribute("data-playing", on);
|
|
16493
|
-
options.onPlay?.(on, tl.time);
|
|
16494
|
-
},
|
|
16495
|
-
onScrub(on) {
|
|
16496
|
-
if (on)
|
|
16497
|
-
v.pause();
|
|
16498
|
-
}
|
|
16499
|
-
});
|
|
16500
|
-
tl.drive(() => {
|
|
16501
|
-
if (v.readyState < 1)
|
|
16502
|
-
return Number.NaN;
|
|
16503
|
-
if (v.seeking)
|
|
16504
|
-
return tl.time;
|
|
16505
|
-
return v.ended ? Number.POSITIVE_INFINITY : v.currentTime;
|
|
16506
|
-
});
|
|
16507
|
-
const onClick = () => tl.focus();
|
|
16508
|
-
frame.addEventListener("click", onClick);
|
|
16509
|
-
v.src = options.src;
|
|
16510
|
-
const api = {
|
|
16511
|
-
element: root,
|
|
16512
|
-
video: v,
|
|
16513
|
-
timeline: tl,
|
|
16514
|
-
get time() {
|
|
16515
|
-
return tl.time;
|
|
16516
|
-
},
|
|
16517
|
-
get playing() {
|
|
16518
|
-
return tl.playing;
|
|
16519
|
-
},
|
|
16520
|
-
get duration() {
|
|
16521
|
-
return Number.isFinite(v.duration) ? v.duration : 0;
|
|
16522
|
-
},
|
|
16523
|
-
play: () => tl.play(),
|
|
16524
|
-
pause: () => tl.pause(),
|
|
16525
|
-
toggle: () => tl.toggle(),
|
|
16526
|
-
seek: (t, o) => tl.seek(t, o?.glide ? { glide: true } : undefined),
|
|
16527
|
-
seekBy: (d) => tl.seek(Math.min(tl.duration, Math.max(0, tl.time + d)), { glide: true }),
|
|
16528
|
-
focus: () => tl.focus(),
|
|
16529
|
-
dispose() {
|
|
16530
|
-
unlisten();
|
|
16531
|
-
tl.drive(null);
|
|
16532
|
-
tl.dispose();
|
|
16533
|
-
v.pause();
|
|
16534
|
-
frame.removeEventListener("click", onClick);
|
|
16535
|
-
v.removeEventListener("loadedmetadata", onMeta);
|
|
16536
|
-
v.removeEventListener("loadeddata", onFrame);
|
|
16537
|
-
v.removeEventListener("seeked", onSeeked);
|
|
16538
|
-
v.removeAttribute("src");
|
|
16539
|
-
v.load();
|
|
16540
|
-
root.remove();
|
|
16541
|
-
}
|
|
16542
|
-
};
|
|
16543
|
-
return api;
|
|
16544
|
-
}
|
|
16545
16549
|
// src/ui/history.ts
|
|
16546
16550
|
init_motion();
|
|
16547
16551
|
init_glide();
|
|
@@ -17414,25 +17418,63 @@ function normalizeWalkthrough(doc) {
|
|
|
17414
17418
|
})),
|
|
17415
17419
|
sections: withKickers(sections, doc.sections, doc.kickers),
|
|
17416
17420
|
steps,
|
|
17417
|
-
prs: knownPRs(doc, sections),
|
|
17421
|
+
prs: knownPRs(doc, sections, steps),
|
|
17418
17422
|
...repoOf(doc) ? { repo: repoOf(doc) } : {}
|
|
17419
17423
|
};
|
|
17420
17424
|
}
|
|
17421
17425
|
var prNumber = (href) => /\/(?:pull|merge_requests)\/(\d+)(?:[/?#]|$)/.exec(href)?.[1] ?? null;
|
|
17422
17426
|
var repoOf = (doc) => doc.repo?.trim().replace(/^https?:\/\/github\.com\//, "").replace(/\/+$/, "") || undefined;
|
|
17423
|
-
|
|
17427
|
+
var PR_STATES = ["merged", "open", "draft", "closed"];
|
|
17428
|
+
function prStatus(status) {
|
|
17429
|
+
const words = (status ?? "").trim().toLowerCase();
|
|
17430
|
+
const first = /^[a-z]+/.exec(words)?.[0] ?? "";
|
|
17431
|
+
const state = PR_STATES.includes(first) ? first : first === "shipped" || first === "done" ? "merged" : null;
|
|
17432
|
+
return { state, checks: /\b(green|passing|passed|ci|checks? pass)/.test(words) };
|
|
17433
|
+
}
|
|
17434
|
+
function knownPRs(doc, sections, steps = []) {
|
|
17424
17435
|
const out = {};
|
|
17425
17436
|
const repo = repoOf(doc);
|
|
17426
|
-
|
|
17427
|
-
const
|
|
17428
|
-
|
|
17429
|
-
|
|
17430
|
-
|
|
17437
|
+
const add = (n, pr) => {
|
|
17438
|
+
const known = out[n] ?? {};
|
|
17439
|
+
const next = { ...known };
|
|
17440
|
+
for (const [k, v] of Object.entries(pr))
|
|
17441
|
+
if (v !== undefined && next[k] === undefined)
|
|
17442
|
+
next[k] = v;
|
|
17443
|
+
out[n] = next;
|
|
17444
|
+
};
|
|
17431
17445
|
for (const [k, pr] of Object.entries(doc.prs ?? {})) {
|
|
17432
17446
|
const n = k.replace(/^#/, "");
|
|
17433
17447
|
if (!/^\d+$/.test(n))
|
|
17434
17448
|
continue;
|
|
17435
|
-
|
|
17449
|
+
add(n, pr);
|
|
17450
|
+
}
|
|
17451
|
+
for (const step of steps)
|
|
17452
|
+
for (const m of step.media) {
|
|
17453
|
+
if (m.kind !== "stack")
|
|
17454
|
+
continue;
|
|
17455
|
+
for (const it of m.items) {
|
|
17456
|
+
const n = it.pr.replace(/^#/, "");
|
|
17457
|
+
if (!/^\d+$/.test(n))
|
|
17458
|
+
continue;
|
|
17459
|
+
const said = prStatus(it.status);
|
|
17460
|
+
add(n, {
|
|
17461
|
+
...said.state ? { state: said.state } : {},
|
|
17462
|
+
...said.state && said.checks ? { checks: true } : {},
|
|
17463
|
+
...it.title ? { title: plainMarkdown(it.title) } : {},
|
|
17464
|
+
...it.href ? { href: it.href } : {}
|
|
17465
|
+
});
|
|
17466
|
+
}
|
|
17467
|
+
}
|
|
17468
|
+
for (const s of sections) {
|
|
17469
|
+
const n = s.link && prNumber(s.link.href);
|
|
17470
|
+
if (!n)
|
|
17471
|
+
continue;
|
|
17472
|
+
const said = prStatus(s.status);
|
|
17473
|
+
add(n, {
|
|
17474
|
+
href: s.link.href.replace(/(\/pull\/\d+).*$/, "$1"),
|
|
17475
|
+
...said.state ? { state: said.state } : {},
|
|
17476
|
+
title: plainMarkdown(s.title)
|
|
17477
|
+
});
|
|
17436
17478
|
}
|
|
17437
17479
|
if (repo) {
|
|
17438
17480
|
for (const n of Object.keys(out))
|
|
@@ -17441,13 +17483,17 @@ function knownPRs(doc, sections) {
|
|
|
17441
17483
|
}
|
|
17442
17484
|
return out;
|
|
17443
17485
|
}
|
|
17444
|
-
function findPR(prs, n, repo) {
|
|
17445
|
-
const
|
|
17446
|
-
const
|
|
17486
|
+
function findPR(prs, n, repo, kind = "pr") {
|
|
17487
|
+
const entry = prs[n];
|
|
17488
|
+
const known = entry && (entry.kind ?? "pr") === kind ? entry : undefined;
|
|
17489
|
+
const path = kind === "issue" ? "issues" : "pull";
|
|
17490
|
+
const href = repo ? `https://github.com/${repo}/${path}/${n}` : undefined;
|
|
17491
|
+
const base = kind === "issue" ? { kind } : {};
|
|
17447
17492
|
if (known)
|
|
17448
|
-
return known.href || !href ? known : { ...known, href };
|
|
17449
|
-
return href ? { href } : null;
|
|
17493
|
+
return known.href || !href ? { ...base, ...known } : { ...base, ...known, href };
|
|
17494
|
+
return href ? { ...base, href } : kind === "issue" ? { kind } : null;
|
|
17450
17495
|
}
|
|
17496
|
+
var issueNumber = (href) => /^https?:\/\/[^/]+\/.+\/issues\/(\d+)\/?(?:[?#].*)?$/.exec(href)?.[1] ?? null;
|
|
17451
17497
|
var isPullRequest = (href) => /\/(?:pull|merge_requests)\/\d+(?:[/?#]|$)/.test(href);
|
|
17452
17498
|
function withKickers(sections, source, kickers = "pr") {
|
|
17453
17499
|
if (kickers === false)
|
|
@@ -22340,12 +22386,7 @@ var CHECK3 = "M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11
|
|
|
22340
22386
|
var svg12 = (d, evenodd = false) => `<svg class="knobs-icon" viewBox="0 0 256 256" width="12" height="12" fill="currentColor"${evenodd ? ' fill-rule="evenodd"' : ""} aria-hidden="true" focusable="false"><path d="${d}"/></svg>`;
|
|
22341
22387
|
var prGlyph = (state) => state === "merged" ? svg12(PR_PATHS.merge) : state === "draft" ? svg12(DRAFT, true) : state === "closed" ? svg12(X) : svg12(PR_PATHS.pull);
|
|
22342
22388
|
var PR_STATE = { merged: "Merged", open: "Open", draft: "Draft", closed: "Closed" };
|
|
22343
|
-
|
|
22344
|
-
const words = (status ?? "").trim().toLowerCase();
|
|
22345
|
-
const first = /^[a-z]+/.exec(words)?.[0] ?? "";
|
|
22346
|
-
const state = first in PR_STATE ? first : null;
|
|
22347
|
-
return { state, checks: /\b(green|passing|passed|ci|checks? pass)/.test(words) };
|
|
22348
|
-
}
|
|
22389
|
+
var ISSUE = "M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-88a16,16,0,1,1-16-16A16,16,0,0,1,144,128Z";
|
|
22349
22390
|
function prStateLabel(doc, state, checks, title) {
|
|
22350
22391
|
const s = el2(doc, "span", "knobs-wt-prstate");
|
|
22351
22392
|
s.dataset.state = state;
|
|
@@ -22369,27 +22410,55 @@ function prChip(doc, n, pr) {
|
|
|
22369
22410
|
chip.setAttribute("target", "_blank");
|
|
22370
22411
|
chip.setAttribute("rel", "noreferrer");
|
|
22371
22412
|
}
|
|
22413
|
+
const issue = pr.kind === "issue";
|
|
22414
|
+
if (issue)
|
|
22415
|
+
chip.dataset.kind = "issue";
|
|
22372
22416
|
if (pr.state)
|
|
22373
22417
|
chip.dataset.state = pr.state;
|
|
22374
|
-
chip.innerHTML = prGlyph(pr.state);
|
|
22418
|
+
chip.innerHTML = issue ? svg12(ISSUE) : prGlyph(pr.state);
|
|
22375
22419
|
chip.append(text2(doc, "span", "", `#${n}`));
|
|
22376
|
-
|
|
22377
|
-
|
|
22378
|
-
|
|
22420
|
+
if (pr.checks) {
|
|
22421
|
+
const c = el2(doc, "span", "knobs-wt-prchecks");
|
|
22422
|
+
c.innerHTML = svg12(CHECK3);
|
|
22423
|
+
chip.append(c);
|
|
22424
|
+
}
|
|
22425
|
+
const words = [
|
|
22426
|
+
`${issue ? "Issue" : "Pull request"} #${n}`,
|
|
22427
|
+
pr.title,
|
|
22428
|
+
pr.state ? PR_STATE[pr.state] : "",
|
|
22429
|
+
pr.checks ? "checks pass" : ""
|
|
22430
|
+
].filter(Boolean);
|
|
22431
|
+
chip.title = words.slice(1).length ? `#${n} · ${words.slice(1).join(" · ")}` : `#${n}`;
|
|
22432
|
+
chip.setAttribute("aria-label", words.join(" · "));
|
|
22379
22433
|
return chip;
|
|
22380
22434
|
}
|
|
22381
22435
|
var PR_URL = /^https?:\/\/[^/]+\/.+\/(?:pull|merge_requests)\/(\d+)\/?(?:[?#].*)?$/;
|
|
22382
|
-
var
|
|
22436
|
+
var ISSUE_URL = /^https?:\/\/[^/]+\/.+\/issues\/(\d+)\/?(?:[?#].*)?$/;
|
|
22437
|
+
var REF = /(^|[^\w&/#:])(issue:)?#(\d{3,7})\b/gi;
|
|
22438
|
+
var WHOLE_REF = /^(issue:)?#(\d{1,7})$/i;
|
|
22439
|
+
var KEEP = 'a,pre,button,.knobs-wt-pr,.knobs-wt-slot:not([data-kind="table"]),.knobs-wt-stack';
|
|
22383
22440
|
function linkPRs(root, find) {
|
|
22384
22441
|
const doc = root.ownerDocument;
|
|
22442
|
+
const chip = (n, kind, href) => prChip(doc, n, { ...kind === "issue" ? { kind } : {}, ...find(n, kind), ...href ? { href } : {} });
|
|
22385
22443
|
for (const a of Array.from(root.querySelectorAll("a[href]"))) {
|
|
22386
|
-
if (a.classList.contains("knobs-wt-pr") || a.closest(
|
|
22444
|
+
if (a.classList.contains("knobs-wt-pr") || a.parentElement?.closest(KEEP))
|
|
22445
|
+
continue;
|
|
22446
|
+
const url = a.getAttribute("href") ?? "";
|
|
22447
|
+
const pr = PR_URL.exec(url)?.[1];
|
|
22448
|
+
const n = pr ?? ISSUE_URL.exec(url)?.[1];
|
|
22449
|
+
if (!n)
|
|
22387
22450
|
continue;
|
|
22388
|
-
const
|
|
22389
|
-
|
|
22390
|
-
if (!n || !(words === `#${n}` || words === n || words === a.getAttribute("href")))
|
|
22451
|
+
const words = (a.textContent ?? "").trim().replace(/^issue:/i, "");
|
|
22452
|
+
if (!(words === `#${n}` || words === n || words === url))
|
|
22391
22453
|
continue;
|
|
22392
|
-
a.replaceWith(
|
|
22454
|
+
a.replaceWith(chip(n, pr ? "pr" : "issue", a.href));
|
|
22455
|
+
}
|
|
22456
|
+
for (const c of Array.from(root.querySelectorAll("code"))) {
|
|
22457
|
+
if (c.closest("pre") || c.parentElement?.closest(KEEP))
|
|
22458
|
+
continue;
|
|
22459
|
+
const m = WHOLE_REF.exec((c.textContent ?? "").trim());
|
|
22460
|
+
if (m)
|
|
22461
|
+
c.replaceWith(chip(m[2], m[1] ? "issue" : "pr"));
|
|
22393
22462
|
}
|
|
22394
22463
|
const walker = doc.createTreeWalker(root, 5);
|
|
22395
22464
|
const hits = [];
|
|
@@ -22397,29 +22466,22 @@ function linkPRs(root, find) {
|
|
|
22397
22466
|
if (t.nodeType !== 3)
|
|
22398
22467
|
continue;
|
|
22399
22468
|
const p = t.parentElement;
|
|
22400
|
-
if (!p || p.closest(
|
|
22469
|
+
if (!p || p.closest(`${KEEP},code`))
|
|
22401
22470
|
continue;
|
|
22402
|
-
|
|
22403
|
-
if (
|
|
22471
|
+
REF.lastIndex = 0;
|
|
22472
|
+
if (REF.test(t.nodeValue ?? ""))
|
|
22404
22473
|
hits.push(t);
|
|
22405
22474
|
}
|
|
22406
22475
|
for (const t of hits) {
|
|
22407
22476
|
const value = t.nodeValue ?? "";
|
|
22408
22477
|
const frag = doc.createDocumentFragment();
|
|
22409
22478
|
let last = 0;
|
|
22410
|
-
|
|
22411
|
-
|
|
22412
|
-
for (let m = PR_REF.exec(value);m; m = PR_REF.exec(value)) {
|
|
22413
|
-
const pr = find(m[2]);
|
|
22414
|
-
if (!pr)
|
|
22415
|
-
continue;
|
|
22479
|
+
REF.lastIndex = 0;
|
|
22480
|
+
for (let m = REF.exec(value);m; m = REF.exec(value)) {
|
|
22416
22481
|
const at = m.index + m[1].length;
|
|
22417
|
-
frag.append(value.slice(last, at),
|
|
22418
|
-
last =
|
|
22419
|
-
changed = true;
|
|
22482
|
+
frag.append(value.slice(last, at), chip(m[3], m[2] ? "issue" : "pr"));
|
|
22483
|
+
last = m.index + m[0].length;
|
|
22420
22484
|
}
|
|
22421
|
-
if (!changed)
|
|
22422
|
-
continue;
|
|
22423
22485
|
frag.append(value.slice(last));
|
|
22424
22486
|
t.replaceWith(frag);
|
|
22425
22487
|
}
|
|
@@ -22438,7 +22500,7 @@ var snappy3 = springCss(SPRINGS.snappy);
|
|
|
22438
22500
|
var calm = springCss(SPRINGS.calm);
|
|
22439
22501
|
var state = springCss(SPRINGS.default);
|
|
22440
22502
|
var quick = springCss(FADE);
|
|
22441
|
-
var fade2 = "-webkit-mask-image:linear-gradient(to right,#000 calc(100% -
|
|
22503
|
+
var fade2 = "-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 16px),transparent);mask-image:linear-gradient(to right,#000 calc(100% - 16px),transparent)";
|
|
22442
22504
|
var walkthroughCss = `
|
|
22443
22505
|
:where(.knobs-walkthrough,.knobs-walkthrough *,.knobs-wt-slot,.knobs-wt-slot *){box-sizing:border-box}
|
|
22444
22506
|
.knobs-ui:is(.knobs-walkthrough,.knobs-wt-slot){--k-glass:0;--k-glow:0;--kw-quick:${quick.easing};--kw-quick-ms:${quick.duration}ms}
|
|
@@ -22450,7 +22512,7 @@ var walkthroughCss = `
|
|
|
22450
22512
|
.knobs-walkthrough [hidden]{display:none!important}
|
|
22451
22513
|
/* (0,0,1): a host's element rules stop here, and every class rule below wins over it. */
|
|
22452
22514
|
:where(.knobs-walkthrough) :is(h1,h2,h3,p,ol,ul,dl,dd){margin:0;font:inherit;letter-spacing:inherit}
|
|
22453
|
-
.knobs-walkthrough a{color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 35%,transparent);text-underline-offset:2px;transition:text-decoration-color
|
|
22515
|
+
.knobs-walkthrough a{cursor:default;color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 35%,transparent);text-underline-offset:2px;transition:text-decoration-color calc(var(--_k-hover-out) * 1ms)}
|
|
22454
22516
|
.knobs-walkthrough a:hover{text-decoration-color:currentColor}
|
|
22455
22517
|
.knobs-walkthrough code,.knobs-wt-slot code{font:var(--_k-type-label) var(--_k-mono);padding:1px 5px;border-radius:calc(var(--_k-radius) / 2);background:var(--_k-fill)}
|
|
22456
22518
|
:where(.knobs-ui) :is(.knobs-wt-btn,.knobs-wt-pick,.knobs-wt-toc-row,button.knobs-wt-stitle,.knobs-wt-chapter,.knobs-wt-disc-toggle){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;
|
|
@@ -22478,14 +22540,17 @@ var walkthroughCss = `
|
|
|
22478
22540
|
.knobs-walkthrough .knobs-wt-metaline a:not(.knobs-wt-pr){display:inline-flex;align-items:baseline;color:inherit;text-decoration:none;transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
22479
22541
|
.knobs-walkthrough .knobs-wt-metaline a:not(.knobs-wt-pr):hover{color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22480
22542
|
.knobs-wt-metaline svg{align-self:center;width:12px;height:12px;margin-left:2px}
|
|
22481
|
-
/* A pull request: a
|
|
22482
|
-
the success hue, merged the violet series, draft and closed
|
|
22483
|
-
|
|
22543
|
+
/* A pull request or issue: a capsule, its state's icon and number in a quiet tint of the state
|
|
22544
|
+
(open the success hue, merged the violet series, draft and closed faint, unknown neutral; a
|
|
22545
|
+
closed issue is done, so violet), a faint check where its checks pass, its title on hover. */
|
|
22546
|
+
.knobs-ui .knobs-wt-pr{--kw-pr:var(--_k-fg-2);display:inline-flex;align-items:center;gap:3px;height:18px;padding:0 6px 0 5px;margin:0 1px;border-radius:9px;vertical-align:1px;
|
|
22484
22547
|
background:color-mix(in oklch,var(--kw-pr) 12%,transparent);color:var(--kw-pr);font:var(--_k-weight-label) var(--_k-type-small)/1 var(--_k-font);font-variant-numeric:tabular-nums;white-space:nowrap;text-decoration:none;
|
|
22485
22548
|
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
22486
22549
|
.knobs-ui .knobs-wt-pr[data-state="open"]{--kw-pr:color-mix(in oklch,var(--_k-ok) 60%,var(--_k-fg-2))}
|
|
22487
22550
|
.knobs-ui .knobs-wt-pr[data-state="merged"]{--kw-pr:color-mix(in oklch,var(--_k-series-5) 60%,var(--_k-fg-2))}
|
|
22488
22551
|
.knobs-ui .knobs-wt-pr:is([data-state="draft"],[data-state="closed"]){--kw-pr:var(--_k-fg-3)}
|
|
22552
|
+
.knobs-ui .knobs-wt-pr[data-kind="issue"][data-state="closed"]{--kw-pr:color-mix(in oklch,var(--_k-series-5) 60%,var(--_k-fg-2))}
|
|
22553
|
+
.knobs-ui .knobs-wt-pr .knobs-wt-prchecks{margin-left:0}
|
|
22489
22554
|
.knobs-ui a.knobs-wt-pr:is(:hover,:focus-visible){background:color-mix(in oklch,var(--kw-pr) 22%,transparent);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22490
22555
|
.knobs-wt-pr svg{flex:none}
|
|
22491
22556
|
.knobs-wt-metaline .knobs-wt-pr{align-self:center;margin:0}
|
|
@@ -22544,14 +22609,14 @@ var walkthroughCss = `
|
|
|
22544
22609
|
.knobs-wt-fi-ask{max-width:var(--kw-measure);color:var(--_k-fg);font-weight:var(--kw-strong);text-wrap:pretty}
|
|
22545
22610
|
.knobs-wt-fi-text{max-width:var(--kw-measure);color:var(--_k-fg);text-wrap:pretty}
|
|
22546
22611
|
.knobs-wt-fi-answer{max-width:var(--kw-measure);color:var(--_k-fg-2);text-wrap:pretty}
|
|
22547
|
-
:where(.knobs-ui) .knobs-wt-fi-step{all:revert;box-sizing:border-box;font:inherit;color:inherit;background:transparent;border:0;margin:0;padding:0;cursor:
|
|
22612
|
+
:where(.knobs-ui) .knobs-wt-fi-step{all:revert;box-sizing:border-box;font:inherit;color:inherit;background:transparent;border:0;margin:0;padding:0;cursor:default;outline:none;
|
|
22548
22613
|
transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
22549
22614
|
.knobs-ui .knobs-wt-fi-step:is(:hover,:focus-visible){color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22550
22615
|
|
|
22551
22616
|
/* ——— a disclosure: a small faint toggle with a caret, no fill. The body's height springs (in
|
|
22552
22617
|
script) and its content fades in place, top-anchored, under a soft bottom mask ——— */
|
|
22553
22618
|
.knobs-wt-disc{display:flex;flex-direction:column;min-width:0}
|
|
22554
|
-
.knobs-ui .knobs-wt-disc-toggle{display:inline-flex;align-items:center;gap:var(--_k-space-inside);width:max-content;height:20px;color:var(--_k-fg-3);font-size:var(--_k-type-small);line-height:var(--_k-leading-small);cursor:
|
|
22619
|
+
.knobs-ui .knobs-wt-disc-toggle{display:inline-flex;align-items:center;gap:var(--_k-space-inside);width:max-content;height:20px;color:var(--_k-fg-3);font-size:var(--_k-type-small);line-height:var(--_k-leading-small);cursor:default;
|
|
22555
22620
|
border-radius:calc(var(--_k-radius) / 2);transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
22556
22621
|
.knobs-ui .knobs-wt-disc-toggle:is(:hover,:focus-visible),.knobs-wt-disc[data-open]>.knobs-wt-disc-toggle{color:var(--_k-fg-2);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22557
22622
|
.knobs-ui .knobs-wt-disc-toggle:focus-visible{box-shadow:0 0 0 2px var(--_k-focus)}
|
|
@@ -22578,7 +22643,7 @@ var walkthroughCss = `
|
|
|
22578
22643
|
.knobs-wt-n[data-leaving]{opacity:0;filter:blur(3px);padding-block:0}
|
|
22579
22644
|
.knobs-wt-n+.knobs-wt-n{box-shadow:inset 0 1px 0 var(--_k-border-subtle)}
|
|
22580
22645
|
.knobs-wt-n-meta{flex:none;min-width:44px;color:var(--_k-fg-3);font:var(--_k-weight) var(--_k-type-small)/var(--_k-leading-body) var(--_k-mono)}
|
|
22581
|
-
.knobs-wt-n-meta[data-seek]{cursor:
|
|
22646
|
+
.knobs-wt-n-meta[data-seek]{cursor:default}
|
|
22582
22647
|
.knobs-wt-n-meta[data-seek]:hover{color:var(--_k-fg)}
|
|
22583
22648
|
.knobs-wt-n-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--_k-space-sibling)}
|
|
22584
22649
|
.knobs-wt-n-voice{height:30px;max-width:320px}
|
|
@@ -22595,7 +22660,7 @@ var walkthroughCss = `
|
|
|
22595
22660
|
/* Collapsed: the launcher and the bar swap in place, a quick fade with a little scale and blur
|
|
22596
22661
|
from the launcher's corner; the exit is the shorter. */
|
|
22597
22662
|
:where(.knobs-ui) .knobs-wt-launch{all:revert;box-sizing:border-box;justify-self:end;align-self:end;display:inline-flex;align-items:center;gap:6px;height:32px;margin:0;padding:0 10px 0 9px;border:0;border-radius:var(--_k-round);
|
|
22598
|
-
background:var(--_k-bg);color:var(--_k-fg-2);box-shadow:var(--_ku-pane-ring),var(--_k-shadow-overlay);font:var(--kw-strong) var(--_k-type-small)/1 var(--_k-font);cursor:
|
|
22663
|
+
background:var(--_k-bg);color:var(--_k-fg-2);box-shadow:var(--_ku-pane-ring),var(--_k-shadow-overlay);font:var(--kw-strong) var(--_k-type-small)/1 var(--_k-font);cursor:default;outline:none;transform-origin:100% 100%;
|
|
22599
22664
|
transition:color calc(var(--_k-hover-out) * 1ms),opacity var(--kw-quick-ms) var(--kw-quick),scale var(--kw-quick-ms) var(--kw-quick),filter var(--kw-quick-ms) var(--kw-quick)}
|
|
22600
22665
|
.knobs-ui .knobs-wt-launch:is(:hover,:focus-visible){color:var(--_k-fg)}
|
|
22601
22666
|
.knobs-ui .knobs-wt-launch:focus-visible{box-shadow:var(--_k-focus-ring)}
|
|
@@ -22615,11 +22680,11 @@ var walkthroughCss = `
|
|
|
22615
22680
|
.knobs-wt-attach{display:flex;gap:4px;align-items:center;align-self:center}
|
|
22616
22681
|
.knobs-wt-attach:empty{display:none}
|
|
22617
22682
|
.knobs-wt-chip-a{display:inline-flex;align-items:center;gap:2px;height:24px;padding:0 2px 0 9px;border-radius:var(--_k-round);background:var(--_k-fill-selected);font-size:var(--_k-type-small);white-space:nowrap}
|
|
22618
|
-
.knobs-ui .knobs-wt-x{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;color:var(--_k-fg-3);cursor:
|
|
22683
|
+
.knobs-ui .knobs-wt-x{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;color:var(--_k-fg-3);cursor:default;transition:background .15s,color .15s}
|
|
22619
22684
|
.knobs-ui .knobs-wt-x:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
22620
22685
|
.knobs-wt-x svg{width:12px;height:12px}
|
|
22621
22686
|
.knobs-ui .knobs-wt-tool{flex:none;display:inline-flex;align-items:center;justify-content:center;gap:5px;min-width:32px;height:32px;padding:0 8px;border-radius:calc(var(--_k-radius) + 2px);
|
|
22622
|
-
color:var(--_k-fg-2);cursor:
|
|
22687
|
+
color:var(--_k-fg-2);cursor:default;transition:background .15s,color .15s}
|
|
22623
22688
|
.knobs-ui .knobs-wt-tool:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
22624
22689
|
.knobs-ui .knobs-wt-tool[aria-pressed="true"]{background:var(--_k-fill-selected);color:var(--_k-fg)}
|
|
22625
22690
|
.knobs-wt-tool svg{width:16px;height:16px}
|
|
@@ -22629,7 +22694,7 @@ var walkthroughCss = `
|
|
|
22629
22694
|
.knobs-ui .knobs-wt-tool[data-send][data-ready]{background:var(--_k-accent);color:var(--_k-bg)}
|
|
22630
22695
|
/* Back: in place over the bar for a few seconds after a note moves the page on. */
|
|
22631
22696
|
.knobs-ui .knobs-wt-back{position:absolute;left:8px;bottom:calc(100% + 8px);display:inline-flex;align-items:center;gap:var(--_k-space-inside);max-width:min(360px,calc(100% - 16px));height:28px;padding:0 12px 0 9px;
|
|
22632
|
-
border-radius:var(--_k-round);background:var(--_k-bg);color:var(--_k-fg);box-shadow:var(--_ku-pane-ring),var(--_k-shadow-overlay);font-size:var(--_k-type-small);font-weight:var(--kw-strong);cursor:
|
|
22697
|
+
border-radius:var(--_k-round);background:var(--_k-bg);color:var(--_k-fg);box-shadow:var(--_ku-pane-ring),var(--_k-shadow-overlay);font-size:var(--_k-type-small);font-weight:var(--kw-strong);cursor:default;
|
|
22633
22698
|
opacity:0;scale:.96;filter:blur(3px);pointer-events:none;transition:opacity .11s cubic-bezier(.4,0,1,1),scale .11s cubic-bezier(.4,0,1,1),filter .11s cubic-bezier(.4,0,1,1)}
|
|
22634
22699
|
.knobs-ui .knobs-wt-back[data-on]{opacity:1;scale:1;filter:none;pointer-events:auto;transition:opacity .15s cubic-bezier(.2,.8,.2,1),scale .15s cubic-bezier(.2,.8,.2,1),filter .15s cubic-bezier(.2,.8,.2,1)}
|
|
22635
22700
|
.knobs-ui .knobs-wt-back:hover{background:var(--_k-fill-selected)}
|
|
@@ -22656,6 +22721,9 @@ var walkthroughCss = `
|
|
|
22656
22721
|
.knobs-wt-step[data-full] .knobs-wt-body{flex:1;min-height:0}
|
|
22657
22722
|
.knobs-wt-step[data-full] .knobs-wt-fit{height:100%;transition:none}
|
|
22658
22723
|
.knobs-wt-step[data-full] .knobs-wt-frame{height:100%;aspect-ratio:auto}
|
|
22724
|
+
.knobs-wt-step[data-full] .knobs-wt-slot[data-kind="video"]>.knobs-wt-body{display:flex;flex-direction:column}
|
|
22725
|
+
.knobs-wt-step[data-full] .knobs-wt-slot[data-kind="video"] .knobs-player{flex:1;min-height:0}
|
|
22726
|
+
.knobs-wt-step[data-full] .knobs-wt-slot[data-kind="video"] .knobs-player-frame{flex:1;min-height:0;aspect-ratio:auto}
|
|
22659
22727
|
|
|
22660
22728
|
/* ——— a taste test: the options side by side, Kit's pick checked and the rest stepping back. On
|
|
22661
22729
|
the step's card, so no fill of their own ——— */
|
|
@@ -22664,7 +22732,7 @@ var walkthroughCss = `
|
|
|
22664
22732
|
.knobs-wt-option{position:relative;display:flex;flex-direction:column;gap:var(--_k-space-sibling);min-width:0}
|
|
22665
22733
|
.knobs-wt-option>:not(.knobs-wt-pick){transition:opacity var(--kw-snappy-ms) var(--kw-snappy)}
|
|
22666
22734
|
.knobs-wt-options[data-has-pick] .knobs-wt-option:not([data-picked])>:not(.knobs-wt-pick){opacity:.55}
|
|
22667
|
-
.knobs-ui .knobs-wt-pick{display:flex;align-items:center;gap:8px;width:100%;min-height:28px;margin:0 -6px;width:calc(100% + 12px);padding:0 6px;border-radius:var(--_k-radius);cursor:
|
|
22735
|
+
.knobs-ui .knobs-wt-pick{display:flex;align-items:center;gap:8px;width:100%;min-height:28px;margin:0 -6px;width:calc(100% + 12px);padding:0 6px;border-radius:var(--_k-radius);cursor:default;color:var(--_k-fg-2);text-align:left;
|
|
22668
22736
|
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
22669
22737
|
.knobs-ui .knobs-wt-pick:is(:hover,:focus-visible){color:var(--_k-fg);background:var(--_k-fill);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22670
22738
|
.knobs-wt-letter{flex:none;font-weight:var(--kw-strong);color:var(--_k-fg)}
|
|
@@ -22687,17 +22755,18 @@ var walkthroughCss = `
|
|
|
22687
22755
|
.knobs-wt-bar{position:relative;height:4px;border-radius:2px;overflow:hidden;background:var(--_k-fill)}
|
|
22688
22756
|
.knobs-wt-fill{position:absolute;inset:0;border-radius:inherit;background:var(--_k-accent);transform-origin:0 50%;transform:scaleX(var(--kw-done,0))}
|
|
22689
22757
|
.knobs-walkthrough[data-settled] .knobs-wt-fill{transition:transform var(--kw-calm-ms) var(--kw-calm)}
|
|
22690
|
-
/* The contents: every row on one text edge and in one colour, title rows (
|
|
22691
|
-
radius) and the steps under them (20 high, half of it), bled out so their text sits on the
|
|
22692
|
-
rail's edge
|
|
22693
|
-
|
|
22758
|
+
/* The contents: every row on one text edge and in one colour, title rows (28 high, the control
|
|
22759
|
+
radius) and the steps under them (20 high, half of it), bled 6 px out so their text sits on the
|
|
22760
|
+
rail's edge and the first title's words on the column's top line; a narrow fade where a title
|
|
22761
|
+
runs out of room; the selection pill slides to the current step, and base rows never brighten. */
|
|
22762
|
+
.knobs-wt-toc{position:relative;flex:1 1 auto;min-height:0;overflow:auto;scrollbar-width:none;display:flex;flex-direction:column;gap:var(--_k-space-sibling);margin:-4px -6px 0;padding:0 0 8px}
|
|
22694
22763
|
.knobs-wt-toc::-webkit-scrollbar{display:none}
|
|
22695
22764
|
.knobs-wt-toc-group{display:flex;flex-direction:column;min-width:0}
|
|
22696
|
-
.knobs-ui .knobs-wt-toc-row{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--_k-space-sibling);align-items:center;flex:none;width:100%;height:
|
|
22697
|
-
padding:0
|
|
22698
|
-
transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
22765
|
+
.knobs-ui .knobs-wt-toc-row{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--_k-space-sibling);align-items:center;flex:none;width:100%;height:28px;
|
|
22766
|
+
padding:0 6px;border-radius:var(--_k-radius);color:var(--_k-fg-2);font-size:var(--_k-type-body);line-height:var(--_k-leading-body);font-weight:var(--_k-weight);text-align:left;white-space:nowrap;cursor:default;
|
|
22767
|
+
transition:color calc(var(--_k-hover-out) * 1ms),background calc(var(--_k-hover-out) * 1ms)}
|
|
22699
22768
|
.knobs-ui .knobs-wt-toc-sub{height:20px;border-radius:calc(var(--_k-radius) / 2);font-size:var(--_k-type-small);line-height:var(--_k-leading-small);font-weight:var(--_k-weight)}
|
|
22700
|
-
.knobs-ui .knobs-wt-toc-row:is(:hover,:focus-visible){color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22769
|
+
.knobs-ui .knobs-wt-toc-row:is(:hover,:focus-visible){color:var(--_k-fg);background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22701
22770
|
.knobs-ui .knobs-wt-toc-row:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
22702
22771
|
.knobs-wt-toc-end{display:flex;align-items:center;font-size:var(--_k-type-small);line-height:var(--_k-leading-small);font-weight:var(--_k-weight);color:var(--_k-fg-3)}
|
|
22703
22772
|
.knobs-wt-toc-label{min-width:0;overflow:hidden;${fade2}}
|
|
@@ -22709,7 +22778,7 @@ var walkthroughCss = `
|
|
|
22709
22778
|
.knobs-wt-toc-glyph[data-done]{background:var(--kw-tone)}
|
|
22710
22779
|
.knobs-wt-toc-glyph[data-tone="none"]{box-shadow:inset 0 0 0 1px var(--_k-border)}
|
|
22711
22780
|
.knobs-wt-actions{display:flex;flex-wrap:wrap;gap:4px}
|
|
22712
|
-
.knobs-ui .knobs-wt-btn{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 9px;border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:
|
|
22781
|
+
.knobs-ui .knobs-wt-btn{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 9px;border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:default;white-space:nowrap;
|
|
22713
22782
|
transition:background .15s,color .15s}
|
|
22714
22783
|
.knobs-ui .knobs-wt-btn:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
22715
22784
|
.knobs-ui .knobs-wt-btn[data-primary]{background:var(--_k-fill-selected);color:var(--_k-fg)}
|
|
@@ -22743,11 +22812,10 @@ var walkthroughCss = `
|
|
|
22743
22812
|
/* One frame for every slot that has one (a picture, a video, a code block, a compare's stage, a
|
|
22744
22813
|
slot still loading): the panel radius and a quiet fill, no ring; concentric on a card. */
|
|
22745
22814
|
.knobs-wt-slot .knobs-cmp-stage{border-radius:var(--kw-frame-r)}
|
|
22746
|
-
/* A compare is
|
|
22747
|
-
|
|
22815
|
+
/* A compare is as tall as its two pictures side by side at this width, in every mode (Wipe fuses
|
|
22816
|
+
them at one side's size, so nothing grows or re-measures), plus its mode bar, the line and gaps
|
|
22748
22817
|
(92 px), and the frame strip with its gap (158 px). */
|
|
22749
22818
|
.knobs-wt-fit{width:100%;height:calc(100cqw / 2 / var(--kw-aspect,1.7778) + var(--kw-chrome,92px))}
|
|
22750
|
-
.knobs-wt-fit[data-overlay]{height:calc(100cqw / var(--kw-aspect,1.7778) + var(--kw-chrome,92px))}
|
|
22751
22819
|
.knobs-wt-fit[data-strip]{--kw-chrome:158px}
|
|
22752
22820
|
.knobs-wt-fit[data-settled]{transition:height var(--k-wt-calm-ms,${calm.duration}ms) ${calm.easing}}
|
|
22753
22821
|
.knobs-wt-frame{position:relative;width:100%;overflow:hidden;border-radius:var(--kw-frame-r);background:var(--_k-fill);aspect-ratio:var(--kw-aspect,16/9)}
|
|
@@ -22756,8 +22824,12 @@ var walkthroughCss = `
|
|
|
22756
22824
|
.knobs-wt-frame[data-natural]>img{position:static;height:auto}
|
|
22757
22825
|
/* Diff, code and terminal: one plain container (no glass): a flat inset fill, a hairline ring, the
|
|
22758
22826
|
control radius and room inside, so a diff's buttons and the code under them can breathe. */
|
|
22759
|
-
.knobs-wt-slot[data-kind="diff"]>.knobs-wt-body{padding:var(--_k-
|
|
22760
|
-
|
|
22827
|
+
.knobs-wt-slot[data-kind="diff"]>.knobs-wt-body{padding:var(--_k-pad-card);border-radius:var(--_k-radius-panel);background:var(--_k-bg-inset);box-shadow:inset 0 0 0 1px var(--_k-border-subtle)}
|
|
22828
|
+
/* The diff inside it: its header row 28 high on the container's padding, a hairline under it, and
|
|
22829
|
+
no line of its own under the code (the container's ring closes it). */
|
|
22830
|
+
.knobs-wt-slot[data-kind="diff"] .knobs-ui.knobs-diff:not([data-on="pane"]){--kd-head:28px;--kd-x:0px}
|
|
22831
|
+
.knobs-wt-slot[data-kind="diff"] .knobs-ui.knobs-diff:not([data-on="pane"])::after{display:none}
|
|
22832
|
+
.knobs-wt-code{margin:0;padding:var(--_k-pad-card);max-height:420px;overflow:auto;border-radius:var(--_k-radius-panel);background:var(--_k-bg-inset);box-shadow:inset 0 0 0 1px var(--_k-border-subtle);color:var(--_k-fg);
|
|
22761
22833
|
font:var(--_k-type-label)/var(--_k-leading-body) var(--_k-mono);white-space:pre;tab-size:2;scrollbar-width:thin}
|
|
22762
22834
|
.knobs-surface :is(.knobs-wt-code,.knobs-wt-slot[data-kind="diff"]>.knobs-wt-body){padding-inline:0;border-radius:0;background:transparent;box-shadow:inset 0 1px 0 var(--_k-border-subtle),inset 0 -1px 0 var(--_k-border-subtle)}
|
|
22763
22835
|
.knobs-wt-code[data-terminal]{white-space:pre-wrap;overflow-wrap:anywhere}
|
|
@@ -22803,7 +22875,7 @@ var walkthroughCss = `
|
|
|
22803
22875
|
.knobs-wt-mark:is([data-shape="dot"],[data-shape="arrow"]) .knobs-wt-mark-label{left:12px;bottom:auto;top:10px}
|
|
22804
22876
|
.knobs-wt-mark[data-shape="arrow"] .knobs-wt-mark-label{left:auto;right:30px;top:auto;bottom:30px}
|
|
22805
22877
|
.knobs-ui .knobs-wt-anno-toggle{all:revert;box-sizing:border-box;position:absolute;top:8px;right:8px;display:grid;place-items:center;width:28px;height:28px;padding:0;border:0;margin:0;
|
|
22806
|
-
border-radius:var(--_k-radius);background:color-mix(in srgb,var(--_k-bg) 72%,transparent);color:var(--_k-fg-2);cursor:
|
|
22878
|
+
border-radius:var(--_k-radius);background:color-mix(in srgb,var(--_k-bg) 72%,transparent);color:var(--_k-fg-2);cursor:default;opacity:.6;outline:none;
|
|
22807
22879
|
transition:opacity calc(var(--_k-hover-out) * 1ms),color calc(var(--_k-hover-out) * 1ms)}
|
|
22808
22880
|
.knobs-ui .knobs-wt-anno-toggle:is(:hover,:focus-visible){opacity:1;color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22809
22881
|
.knobs-ui .knobs-wt-anno-toggle:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
@@ -22824,7 +22896,7 @@ var walkthroughCss = `
|
|
|
22824
22896
|
.knobs-wt-srow{display:grid;grid-template-columns:auto minmax(0,1fr) auto;column-gap:10px;align-items:start;margin:0 -8px;padding:var(--kw-spt) 8px var(--kw-spb);
|
|
22825
22897
|
border-radius:max(0px,calc(var(--_k-radius-panel) - 8px));transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
22826
22898
|
.knobs-wt-srow[data-trunk]{--kw-spb:0px;grid-template-columns:auto minmax(0,1fr)}
|
|
22827
|
-
.knobs-wt-srow[data-go]{cursor:
|
|
22899
|
+
.knobs-wt-srow[data-go]{cursor:default}
|
|
22828
22900
|
.knobs-wt-srow[data-go]:hover{background:var(--_ku-wash);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22829
22901
|
.knobs-wt-lanes{display:flex;align-self:stretch;margin-block:calc(var(--kw-spt) * -1) calc(var(--kw-spb) * -1)}
|
|
22830
22902
|
.knobs-wt-lane{position:relative;flex:none;width:16px}
|
|
@@ -22840,7 +22912,7 @@ var walkthroughCss = `
|
|
|
22840
22912
|
.knobs-ui .knobs-wt-spr{font:var(--_k-weight-label) var(--_k-type-label)/var(--kw-line) var(--_k-mono);color:var(--_k-fg-2);text-decoration:none;white-space:nowrap}
|
|
22841
22913
|
.knobs-ui a.knobs-wt-spr:is(:hover,:focus-visible){color:var(--_k-fg);text-decoration:underline}
|
|
22842
22914
|
.knobs-ui .knobs-wt-stitle{font-weight:var(--_k-weight-label);line-height:var(--kw-line);color:var(--_k-fg);text-align:left}
|
|
22843
|
-
.knobs-ui button.knobs-wt-stitle{cursor:
|
|
22915
|
+
.knobs-ui button.knobs-wt-stitle{cursor:default;text-decoration:underline;text-decoration-color:transparent;text-underline-offset:3px;transition:text-decoration-color calc(var(--_k-hover-out) * 1ms)}
|
|
22844
22916
|
.knobs-ui :is(.knobs-wt-srow[data-go]:hover button.knobs-wt-stitle,button.knobs-wt-stitle:focus-visible){text-decoration-color:color-mix(in oklch,currentColor 45%,transparent);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22845
22917
|
.knobs-ui .knobs-wt-ssummary{margin:0;max-width:var(--k-walkthrough-measure,68ch);color:var(--_k-fg-2)}
|
|
22846
22918
|
.knobs-wt-smeta{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 12px;font:var(--_k-weight) var(--_k-type-small)/var(--kw-line) var(--_k-mono);font-variant-numeric:tabular-nums;color:var(--_k-fg-3)}
|
|
@@ -22872,7 +22944,7 @@ var walkthroughCss = `
|
|
|
22872
22944
|
.knobs-wt-tablebox{min-width:0}
|
|
22873
22945
|
/* A row with a step goes there: the whole row, a wash under the pointer, no arrow, so rows with and
|
|
22874
22946
|
without one line up. */
|
|
22875
|
-
.knobs-wt-tablebox [data-go]{cursor:
|
|
22947
|
+
.knobs-wt-tablebox [data-go]{cursor:default;outline:none}
|
|
22876
22948
|
.knobs-wt-tablebox tr[data-go]>td,.knobs-wt-trow[data-go]{transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
22877
22949
|
.knobs-wt-tablebox tr[data-go]:is(:hover,:focus-visible)>td,.knobs-wt-trow[data-go]:is(:hover,:focus-visible){background:var(--_ku-wash);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22878
22950
|
.knobs-wt-tablebox [data-go]:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
@@ -22928,13 +23000,18 @@ var walkthroughCss = `
|
|
|
22928
23000
|
.knobs-wt-body:has(>.knobs-wt-chapters){display:flex;flex-direction:column;gap:var(--_k-space-title)}
|
|
22929
23001
|
.knobs-wt-chapters{position:relative;display:flex;flex-direction:column;margin:0 calc(var(--_k-space-sibling) * -1)}
|
|
22930
23002
|
.knobs-ui .knobs-wt-chapter{position:relative;display:grid;grid-template-columns:2ch minmax(0,1fr) auto;column-gap:var(--_k-space-sibling);align-items:center;height:32px;padding:0 var(--_k-space-sibling);
|
|
22931
|
-
border-radius:var(--_k-radius);color:var(--_k-fg-2);text-align:left;white-space:nowrap;cursor:
|
|
22932
|
-
.knobs-ui .knobs-wt-chapter:is(:hover,:focus-visible){color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
23003
|
+
border-radius:var(--_k-radius);color:var(--_k-fg-2);text-align:left;white-space:nowrap;cursor:default;transition:color calc(var(--_k-hover-out) * 1ms),background calc(var(--_k-hover-out) * 1ms)}
|
|
23004
|
+
.knobs-ui .knobs-wt-chapter:is(:hover,:focus-visible){color:var(--_k-fg);background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22933
23005
|
.knobs-ui .knobs-wt-chapter:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
22934
23006
|
.knobs-wt-chapter-n{font-size:var(--_k-type-small);color:var(--_k-fg-3)}
|
|
22935
23007
|
.knobs-wt-chapter-label{min-width:0;overflow:hidden;${fade2}}
|
|
22936
23008
|
.knobs-wt-chapter-time{font:var(--_k-weight) var(--_k-type-small)/1 var(--_k-mono);color:var(--_k-fg-3)}
|
|
22937
23009
|
.knobs-pick-copy :is(.knobs-wt-chapter-n,.knobs-wt-chapter-time){color:var(--_k-fg-2)}
|
|
23010
|
+
/* Every hover in the walkthrough lands at once (hover-in, 0 ms) and eases out (hover-out): links,
|
|
23011
|
+
buttons, chips, rail, chapter, table and stack rows (its own; the pieces inside keep theirs). */
|
|
23012
|
+
:is(.knobs-walkthrough,.knobs-wt-slot) :is(a,button,[data-go])[class*="knobs-wt-"]:is(:hover,:focus-visible),
|
|
23013
|
+
.knobs-walkthrough a:not([class]):hover,
|
|
23014
|
+
:is(.knobs-walkthrough,.knobs-wt-slot) :is(.knobs-wt-srow,tr)[data-go]:is(:hover,:focus-visible) :is(td,.knobs-wt-stitle){transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
22938
23015
|
@media(prefers-reduced-motion:reduce){:is(.knobs-walkthrough,.knobs-wt-slot) :where(*,::before,::after){transition-duration:.15s!important;transition-property:opacity,background,color!important}}
|
|
22939
23016
|
@media(prefers-reduced-motion:reduce){.knobs-wt-disc-content{transition:opacity .15s}}
|
|
22940
23017
|
`;
|
|
@@ -23035,7 +23112,6 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
23035
23112
|
fit.style.setProperty("--kw-aspect", String(known ?? DEFAULT_ASPECT));
|
|
23036
23113
|
const width = host.getBoundingClientRect().width;
|
|
23037
23114
|
const mode = m.mode ?? (width && width < 560 ? "wipe" : "side");
|
|
23038
|
-
fit.toggleAttribute("data-overlay", mode !== "side");
|
|
23039
23115
|
host.append(fit);
|
|
23040
23116
|
const [aspect, lib] = await Promise.all([
|
|
23041
23117
|
known ? Promise.resolve(known) : probeAspect(doc, after.src),
|
|
@@ -23059,7 +23135,6 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
23059
23135
|
...aspect ? { aspect } : {},
|
|
23060
23136
|
...m.strip ? { strip: true } : {},
|
|
23061
23137
|
onMode: (next) => {
|
|
23062
|
-
fit.toggleAttribute("data-overlay", next !== "side");
|
|
23063
23138
|
onEvent?.({ what: "mode", detail: next });
|
|
23064
23139
|
const layer = marks?.element;
|
|
23065
23140
|
if (layer) {
|
|
@@ -23083,6 +23158,12 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
23083
23158
|
}
|
|
23084
23159
|
});
|
|
23085
23160
|
const stage = fit.querySelector(".knobs-cmp-stage");
|
|
23161
|
+
if (stage)
|
|
23162
|
+
doc.defaultView?.requestAnimationFrame(() => {
|
|
23163
|
+
const chrome = fit.clientHeight - stage.clientHeight;
|
|
23164
|
+
if (alive() && stage.clientHeight > 0 && chrome > 0)
|
|
23165
|
+
fit.style.setProperty("--kw-chrome", `${Math.round(chrome)}px`);
|
|
23166
|
+
});
|
|
23086
23167
|
if (m.annotations?.length && stage) {
|
|
23087
23168
|
const shape = { w: aspect ?? DEFAULT_ASPECT, h: 1 };
|
|
23088
23169
|
marks = annotationLayer(stage, m.annotations, () => {
|
|
@@ -23158,45 +23239,38 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
23158
23239
|
var round2 = (v) => Math.round(v * 100) / 100;
|
|
23159
23240
|
var MARK_GLIDE = 450;
|
|
23160
23241
|
var zoomedIn = (z) => z.w < 0.999 || z.h < 0.999;
|
|
23161
|
-
function mountVideo(host, m, onEvent) {
|
|
23242
|
+
async function mountVideo(host, m, look, alive, onEvent) {
|
|
23162
23243
|
const doc = host.ownerDocument;
|
|
23163
|
-
|
|
23244
|
+
await Promise.resolve().then(() => init_player());
|
|
23245
|
+
if (!alive())
|
|
23246
|
+
return { dispose() {} };
|
|
23164
23247
|
const aspect = parseAspect(m.aspect);
|
|
23165
|
-
|
|
23166
|
-
|
|
23167
|
-
const
|
|
23168
|
-
|
|
23169
|
-
|
|
23170
|
-
|
|
23171
|
-
|
|
23172
|
-
|
|
23173
|
-
|
|
23174
|
-
|
|
23175
|
-
|
|
23176
|
-
|
|
23177
|
-
|
|
23178
|
-
|
|
23179
|
-
|
|
23180
|
-
|
|
23181
|
-
|
|
23182
|
-
|
|
23183
|
-
|
|
23184
|
-
v.append(track);
|
|
23185
|
-
}
|
|
23186
|
-
v.src = m.src;
|
|
23187
|
-
v.addEventListener("play", () => onEvent?.({ what: "play", time: round2(v.currentTime) }));
|
|
23188
|
-
v.addEventListener("pause", () => onEvent?.({ what: "pause", time: round2(v.currentTime) }));
|
|
23189
|
-
v.addEventListener("seeked", () => {
|
|
23190
|
-
if (v.paused)
|
|
23191
|
-
onEvent?.({ what: "seek", time: round2(v.currentTime) });
|
|
23248
|
+
let pills = null;
|
|
23249
|
+
let marking = null;
|
|
23250
|
+
const p = player(host, {
|
|
23251
|
+
...look,
|
|
23252
|
+
src: m.src,
|
|
23253
|
+
...m.poster ? { poster: m.poster } : {},
|
|
23254
|
+
...m.captions ? { captions: m.captions } : {},
|
|
23255
|
+
...aspect ? { aspect } : {},
|
|
23256
|
+
...m.label ? { label: m.label } : {},
|
|
23257
|
+
...m.chapters?.length ? { chapters: m.chapters.map((c) => ({ label: c.label, start: c.start, ...c.id ? { id: c.id } : {} })) } : {},
|
|
23258
|
+
onPlay: (on, time) => {
|
|
23259
|
+
marking?.kick();
|
|
23260
|
+
onEvent?.({ what: on ? "play" : "pause", time: round2(time) });
|
|
23261
|
+
},
|
|
23262
|
+
onSeek: (time) => {
|
|
23263
|
+
pills?.sync();
|
|
23264
|
+
marking?.kick();
|
|
23265
|
+
onEvent?.({ what: "seek", time: round2(time) });
|
|
23266
|
+
}
|
|
23192
23267
|
});
|
|
23193
|
-
|
|
23194
|
-
host.
|
|
23195
|
-
|
|
23196
|
-
now: () => v.currentTime,
|
|
23268
|
+
const v = p.video;
|
|
23269
|
+
pills = m.chapters?.length ? chapterPills(host, m.chapters, {
|
|
23270
|
+
now: () => p.time,
|
|
23197
23271
|
seek: (t) => {
|
|
23198
|
-
|
|
23199
|
-
|
|
23272
|
+
p.seek(t, { glide: true });
|
|
23273
|
+
p.play();
|
|
23200
23274
|
},
|
|
23201
23275
|
onEvent
|
|
23202
23276
|
}) : null;
|
|
@@ -23204,36 +23278,33 @@ function mountVideo(host, m, onEvent) {
|
|
|
23204
23278
|
if (pills)
|
|
23205
23279
|
for (const type of ["timeupdate", "seeking", "seeked"])
|
|
23206
23280
|
v.addEventListener(type, sync);
|
|
23281
|
+
const frame = p.element.querySelector(".knobs-player-frame") ?? p.element;
|
|
23207
23282
|
const marks = m.annotations?.length ? annotationLayer(frame, m.annotations, () => ({
|
|
23208
23283
|
rects: [
|
|
23209
23284
|
contain({ w: frame.clientWidth, h: frame.clientHeight }, { w: v.videoWidth, h: v.videoHeight })
|
|
23210
23285
|
],
|
|
23211
|
-
time:
|
|
23286
|
+
time: p.time
|
|
23212
23287
|
})) : null;
|
|
23213
|
-
|
|
23214
|
-
|
|
23215
|
-
for (const type of ["
|
|
23216
|
-
v.addEventListener(type, () => marking
|
|
23288
|
+
if (marks) {
|
|
23289
|
+
marking = follow(doc.defaultView, () => p.playing, () => marks.update());
|
|
23290
|
+
for (const type of ["seeked", "loadedmetadata", "timeupdate"])
|
|
23291
|
+
v.addEventListener(type, () => marking?.kick());
|
|
23292
|
+
}
|
|
23217
23293
|
return {
|
|
23218
|
-
pause: () =>
|
|
23219
|
-
seekBy: (d) =>
|
|
23220
|
-
v.currentTime = Math.max(0, Math.min(v.duration || Infinity, v.currentTime + d));
|
|
23221
|
-
},
|
|
23294
|
+
pause: () => p.pause(),
|
|
23295
|
+
seekBy: (d) => p.seekBy(d),
|
|
23222
23296
|
context: () => ({
|
|
23223
23297
|
kind: "video",
|
|
23224
|
-
time: round2(
|
|
23225
|
-
...
|
|
23226
|
-
playing:
|
|
23298
|
+
time: round2(p.time),
|
|
23299
|
+
...p.duration ? { duration: round2(p.duration) } : {},
|
|
23300
|
+
playing: p.playing,
|
|
23227
23301
|
...pills?.current ? { chapter: pills.current.label } : {}
|
|
23228
23302
|
}),
|
|
23229
23303
|
dispose: () => {
|
|
23230
23304
|
marking?.stop();
|
|
23231
23305
|
marks?.dispose();
|
|
23232
23306
|
pills?.dispose();
|
|
23233
|
-
|
|
23234
|
-
v.removeAttribute("src");
|
|
23235
|
-
v.load();
|
|
23236
|
-
frame.remove();
|
|
23307
|
+
p.dispose();
|
|
23237
23308
|
}
|
|
23238
23309
|
};
|
|
23239
23310
|
}
|
|
@@ -23494,7 +23565,7 @@ function mediaSlot(container, options) {
|
|
|
23494
23565
|
case "diff":
|
|
23495
23566
|
return void mountDiff(host, m, look, alive, options.onEvent).then(done, fail("diff"));
|
|
23496
23567
|
case "video":
|
|
23497
|
-
return
|
|
23568
|
+
return void mountVideo(host, m, look, alive, options.onEvent).then(done, fail("video"));
|
|
23498
23569
|
case "image":
|
|
23499
23570
|
return done(mountImage(host, m));
|
|
23500
23571
|
case "code":
|
|
@@ -24477,11 +24548,12 @@ function walkthrough(container, options) {
|
|
|
24477
24548
|
line.append(s);
|
|
24478
24549
|
return s;
|
|
24479
24550
|
};
|
|
24480
|
-
const findPRIn = (n) => findPR(page.prs, n, page.repo);
|
|
24551
|
+
const findPRIn = (n, kind = "pr") => findPR(page.prs, n, page.repo, kind);
|
|
24481
24552
|
const metaLink = (line, text, href) => {
|
|
24482
24553
|
const n = prNumber(href);
|
|
24483
|
-
|
|
24484
|
-
|
|
24554
|
+
const issue = n ? null : issueNumber(href);
|
|
24555
|
+
if (n || issue) {
|
|
24556
|
+
const chip = n ? prChip(doc, n, { ...findPRIn(n), href }) : prChip(doc, issue, { ...findPRIn(issue, "issue"), href });
|
|
24485
24557
|
line.append(chip);
|
|
24486
24558
|
return chip;
|
|
24487
24559
|
}
|