@kitlangton/knobs 0.4.0-next.6 → 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 +6 -4
- package/dist/dev/{chunk-ya44t7z5.js → chunk-a9pwf5c0.js} +28 -22
- package/dist/dev/{chunk-nhz9en4k.js → chunk-tttj4xpd.js} +1 -1
- package/dist/dev/index.js +3 -3
- package/dist/panel.js +28 -22
- package/dist/types/ui/compare-css.d.ts +1 -1
- package/dist/types/ui/compare.d.ts +1 -1
- package/dist/types/ui/player-css.d.ts +1 -1
- package/dist/types/ui/player.d.ts +0 -9
- package/dist/types/ui/timeline.d.ts +2 -4
- package/dist/types/ui/walkthrough-blocks.d.ts +19 -14
- package/dist/types/ui/walkthrough-media.d.ts +3 -1
- package/dist/types/ui/walkthrough-model.d.ts +21 -2
- package/dist/ui-react.js +450 -205
- package/dist/ui-solid.js +450 -205
- package/dist/ui.js +450 -372
- package/package.json +1 -1
package/dist/ui-solid.js
CHANGED
|
@@ -575,13 +575,14 @@ var compareCss = `
|
|
|
575
575
|
picked: the pill's bright copy is. */
|
|
576
576
|
.knobs-cmp-modes{position:relative;display:inline-flex;height:var(--_k-control-h);border-radius:var(--_k-radius);background:var(--_k-fill)}
|
|
577
577
|
.knobs-cmp-modes[hidden]{display:none}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
578
|
+
/* Hover is a quiet fill under the arrow cursor (no hand, no brightening), there at once. */
|
|
579
|
+
.knobs-ui .knobs-cmp-mode{display:inline-flex;align-items:center;height:100%;padding:0 8px;border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:default;white-space:nowrap;
|
|
580
|
+
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
581
|
+
.knobs-ui .knobs-cmp-mode:not([aria-checked="true"]):is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
581
582
|
/* Toggles: icon buttons, the accent's wash when on. */
|
|
582
|
-
.knobs-ui .knobs-cmp-toggle{display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:var(--_k-radius);color:var(--_k-fg-
|
|
583
|
-
transition:
|
|
584
|
-
.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){
|
|
583
|
+
.knobs-ui .knobs-cmp-toggle{display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:default;
|
|
584
|
+
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
585
|
+
.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
585
586
|
.knobs-ui .knobs-cmp-toggle[aria-pressed="true"]{color:var(--_k-accent-fg);background:var(--_k-accent-soft)}
|
|
586
587
|
.knobs-cmp-toggle svg{display:block}
|
|
587
588
|
.knobs-cmp-fill{flex:1}
|
|
@@ -595,11 +596,10 @@ var compareCss = `
|
|
|
595
596
|
.knobs-cmp-stage{position:relative;flex:1;min-height:96px;overflow:hidden;border-radius:var(--_k-radius-panel);background:var(--_ku-cmp-stage);touch-action:pan-y;outline:none}
|
|
596
597
|
.knobs-compare[data-frame="flat"] .knobs-cmp-stage{border-radius:0}
|
|
597
598
|
.knobs-compare[data-mode="wipe"] .knobs-cmp-stage{cursor:ew-resize}
|
|
598
|
-
/* Videos: a click on the stage plays and pauses. */
|
|
599
|
-
.knobs-compare[data-video]:not([data-mode="wipe"],[data-zoomed]) .knobs-cmp-stage{cursor:pointer}
|
|
600
599
|
/* Unzoomed, a finger still scrolls the page up and down; zoomed, the stage takes every gesture. */
|
|
601
|
-
.
|
|
602
|
-
.knobs-compare[data-
|
|
600
|
+
/* Zoomed, it pans: a move cursor, never a hand. */
|
|
601
|
+
.knobs-compare[data-zoomed] .knobs-cmp-stage{cursor:move;touch-action:none}
|
|
602
|
+
.knobs-compare[data-panning],.knobs-compare[data-panning] *{cursor:move!important}
|
|
603
603
|
/* Wiping, the grip stands in for the cursor. */
|
|
604
604
|
.knobs-compare[data-dragging],.knobs-compare[data-dragging] *{cursor:none!important}
|
|
605
605
|
.knobs-cmp-sizer{position:absolute;left:0;right:0;top:0;height:0;visibility:hidden;pointer-events:none}
|
|
@@ -646,8 +646,8 @@ var compareCss = `
|
|
|
646
646
|
opacity:0;scale:.96;pointer-events:none;transition:opacity .16s cubic-bezier(.4,0,1,1),scale .16s cubic-bezier(.4,0,1,1)}
|
|
647
647
|
.knobs-cmp-zoom[data-on]{opacity:1;scale:1;pointer-events:auto;transition:opacity .2s cubic-bezier(.2,.8,.2,1),scale .2s cubic-bezier(.2,.8,.2,1)}
|
|
648
648
|
:where(.knobs-ui) .knobs-cmp-zoom-reset{all:revert;box-sizing:border-box;font:inherit;letter-spacing:inherit;margin:0;border:0;outline:none;box-shadow:none;
|
|
649
|
-
display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border-radius:999px;background:transparent;color:var(--_k-fg-2);cursor:
|
|
650
|
-
:where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){
|
|
649
|
+
display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border-radius:999px;background:transparent;color:var(--_k-fg-2);cursor:default;transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
650
|
+
:where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
651
651
|
.knobs-cmp-note{position:absolute;left:50%;top:50%;translate:-50% -50%;color:var(--_k-fg-3);font-size:var(--_k-text-meta);pointer-events:none}
|
|
652
652
|
.knobs-cmp-note:empty{display:none}
|
|
653
653
|
.knobs-cmp-strip-host{flex:none;height:60px;min-height:0}
|
|
@@ -665,23 +665,29 @@ var playerCss = `
|
|
|
665
665
|
.knobs-ui.knobs-player{--_kp-stage:var(--_k-compare-stage);display:flex;flex-direction:column;gap:6px;width:100%;outline:none;
|
|
666
666
|
font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
|
|
667
667
|
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-ui.knobs-player,.knobs-ui.knobs-player[data-nested]{--_kp-stage:var(--k-compare-stage,transparent)}
|
|
668
|
-
.knobs-player-frame{position:relative;width:100%;aspect-ratio:var(--kp-aspect,16/9);overflow:hidden;border-radius:var(--_k-radius-panel);background:var(--_kp-stage)
|
|
668
|
+
.knobs-player-frame{position:relative;width:100%;aspect-ratio:var(--kp-aspect,16/9);overflow:hidden;border-radius:var(--_k-radius-panel);background:var(--_kp-stage)}
|
|
669
669
|
.knobs-player[data-frame="flat"] .knobs-player-frame{border-radius:0}
|
|
670
670
|
.knobs-player-media{position:absolute;inset:0;display:block;width:100%;height:100%;margin:0;padding:0;border:0;object-fit:contain;
|
|
671
671
|
opacity:0;filter:blur(4px);transition:opacity calc(var(--_k-motion-default-ms) * 1ms) var(--_k-motion-default),filter calc(var(--_k-motion-default-ms) * 1ms) var(--_k-motion-default)}
|
|
672
672
|
.knobs-player[data-ready] .knobs-player-media{opacity:1;filter:none}
|
|
673
|
-
.knobs-player-glyph{position:absolute;left:50%;top:50%;display:grid;place-items:center;width:44px;height:44px;margin:-22px 0 0 -22px;border-radius:50%;color:var(--_k-fg);pointer-events:none;
|
|
674
|
-
opacity:0;filter:blur(4px);scale:.96;
|
|
675
|
-
background:color-mix(in srgb,var(--_k-bg) 52%,transparent);-webkit-backdrop-filter:blur(14px) saturate(1.6);backdrop-filter:blur(14px) saturate(1.6);
|
|
676
|
-
box-shadow:inset 0 0 0 .5px var(--_k-border),inset 0 1px 0 var(--_k-rim);
|
|
677
|
-
transition:opacity calc(var(--_k-motion-snappy-ms) * 1ms) var(--_k-motion-snappy),filter calc(var(--_k-motion-snappy-ms) * 1ms) var(--_k-motion-snappy),scale calc(var(--_k-motion-snappy-ms) * 1ms) var(--_k-motion-snappy)}
|
|
678
|
-
.knobs-player-glyph svg{width:16px;height:16px}
|
|
679
|
-
.knobs-player-glyph[data-flash]{opacity:1;filter:none;scale:1}
|
|
680
673
|
.knobs-player-line{flex:none;min-height:0}
|
|
681
|
-
/*
|
|
682
|
-
|
|
674
|
+
/* The timeline's own stylesheet is look.ts's; what the player's row and every timeline share
|
|
675
|
+
about the hand is set here, after it. No hand cursor anywhere (the arrow, or a resize where it
|
|
676
|
+
resizes); hover is a quiet fill (fill-hover), in at once (hover-in, 0 ms), out easing. */
|
|
677
|
+
.knobs-ui .knobs-tl-play,.knobs-ui.knobs-timeline :is(.knobs-tl-pin,.knobs-tl-rlabel),
|
|
678
|
+
.knobs-ui.knobs-timeline[data-dragging] .knobs-tl-marker :is(.knobs-tl-pin,.knobs-tl-mlabel){cursor:default}
|
|
683
679
|
.knobs-ui .knobs-tl-play:hover,.knobs-tl-edge:hover::after,.knobs-tl-rlabel:hover,.knobs-tl-track:hover .knobs-tl-hover,
|
|
684
680
|
.knobs-timeline[data-variant="line"] .knobs-tl-track:hover .knobs-tl-segs{transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
681
|
+
/* The line's row: a minimal play/pause (the filled pair, a 28px target, no fill at rest), then
|
|
682
|
+
the line, centred on it. */
|
|
683
|
+
.knobs-ui.knobs-timeline[data-variant="line"]{gap:4px;align-items:center}
|
|
684
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-transport{display:flex}
|
|
685
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-play{width:28px;height:28px;min-width:28px;min-height:28px;border-radius:var(--_k-radius);background:transparent;color:var(--_k-fg-2);
|
|
686
|
+
transition:background calc(var(--_k-hover-out) * 1ms),transform .15s var(--_ku-ease)}
|
|
687
|
+
.knobs-ui.knobs-timeline[data-variant="line"][data-playing] .knobs-tl-play{background:transparent;color:var(--_k-fg-2)}
|
|
688
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-play:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
689
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-track{cursor:default;transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
690
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-track:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
685
691
|
`;
|
|
686
692
|
|
|
687
693
|
// src/ui/overlay-css.ts
|
|
@@ -3233,16 +3239,17 @@ var init_diff_css = __esm(() => {
|
|
|
3233
3239
|
.knobs-diff-nav>span{min-width:3.6em;text-align:center}
|
|
3234
3240
|
:where(.knobs-ui) :is(.knobs-diff-btn,.knobs-diff-choice,.knobs-diff-viewed,.knobs-diff-filter>input,.knobs-diff-filter>button){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;border-radius:0;
|
|
3235
3241
|
margin:0;padding:0;min-width:0;box-shadow:none;outline:none}
|
|
3236
|
-
.knobs-ui .knobs-diff-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:calc(var(--_k-radius) * 999);color:var(--_k-fg-
|
|
3237
|
-
transition:background
|
|
3238
|
-
|
|
3242
|
+
.knobs-ui .knobs-diff-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:calc(var(--_k-radius) * 999);color:var(--_k-fg-2);cursor:default;
|
|
3243
|
+
transition:background calc(var(--_k-hover-out) * 1ms),opacity .15s}
|
|
3244
|
+
/* Hover is a quiet fill under the arrow cursor (no hand, no brightening), there at once. */
|
|
3245
|
+
.knobs-ui .knobs-diff-btn:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
3239
3246
|
.knobs-ui .knobs-diff-btn[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
|
|
3240
3247
|
.knobs-ui .knobs-diff-btn:disabled{opacity:.35;cursor:default;background:transparent}
|
|
3241
3248
|
.knobs-diff-btn svg{width:16px;height:16px}
|
|
3242
3249
|
/* Viewed: a check with its word, as on GitHub; the path dims once it's ticked. */
|
|
3243
3250
|
.knobs-ui .knobs-diff-viewed{flex:none;display:inline-flex;align-items:center;gap:5px;height:var(--_k-control-h);padding:0 8px 0 6px;border-radius:var(--kd-ctl);color:var(--_k-fg-2);
|
|
3244
|
-
font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);white-space:nowrap;cursor:
|
|
3245
|
-
.knobs-ui .knobs-diff-viewed:is(:hover,:focus-visible){background:var(--
|
|
3251
|
+
font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);white-space:nowrap;cursor:default;transition:background calc(var(--_k-hover-out) * 1ms),color .15s}
|
|
3252
|
+
.knobs-ui .knobs-diff-viewed:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
3246
3253
|
.knobs-ui .knobs-diff-viewed[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
|
|
3247
3254
|
.knobs-diff-viewed svg{width:16px;height:16px}
|
|
3248
3255
|
.knobs-diff-viewed[aria-pressed="true"] svg{color:var(--kd-add)}
|
|
@@ -3261,8 +3268,8 @@ var init_diff_css = __esm(() => {
|
|
|
3261
3268
|
choice isn't brighter for being picked. Choices are styled by class, as the copy holds them too. */
|
|
3262
3269
|
.knobs-diff-seg{position:relative;flex:none;display:grid;grid-template-columns:1fr 1fr;height:var(--_k-control-h);padding:2px;border-radius:var(--kd-ctl);background:var(--_k-fill)}
|
|
3263
3270
|
.knobs-ui .knobs-diff-choice{padding:0 9px;border-radius:max(0px,calc(var(--kd-ctl) - 2px));color:var(--_k-fg-2);font-size:var(--_k-text-meta);
|
|
3264
|
-
font-weight:var(--_k-weight-label);white-space:nowrap;cursor:
|
|
3265
|
-
.knobs-ui .knobs-diff-choice:is(:hover,:focus-visible){
|
|
3271
|
+
font-weight:var(--_k-weight-label);white-space:nowrap;cursor:default;transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
3272
|
+
.knobs-ui .knobs-diff-choice:not([aria-checked="true"]):is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
3266
3273
|
/* The diff: one layer per file or layout on show, the old fading under the new. */
|
|
3267
3274
|
.knobs-diff-body{position:relative;flex:1;min-height:0}
|
|
3268
3275
|
.knobs-diff-probe{position:absolute;left:0;top:0;width:0;height:var(--kd-line);visibility:hidden;pointer-events:none}
|
|
@@ -3358,8 +3365,8 @@ var init_diff_css = __esm(() => {
|
|
|
3358
3365
|
.knobs-diff-filter svg{width:12px;height:12px;flex:none}
|
|
3359
3366
|
.knobs-ui .knobs-diff-filter>input{flex:1;min-width:0;height:100%;font:var(--_k-weight) var(--_k-font-size)/1 var(--_k-font);color:var(--_k-fg);caret-color:var(--_k-accent);background:transparent}
|
|
3360
3367
|
.knobs-ui .knobs-diff-filter>input::placeholder{color:var(--_k-fg-3)}
|
|
3361
|
-
.knobs-ui .knobs-diff-filter>button{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:var(--_k-fg-3);cursor:
|
|
3362
|
-
.knobs-ui .knobs-diff-filter>button:hover{background:var(--
|
|
3368
|
+
.knobs-ui .knobs-diff-filter>button{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:var(--_k-fg-3);cursor:default;transition:background calc(var(--_k-hover-out) * 1ms),opacity .12s}
|
|
3369
|
+
.knobs-ui .knobs-diff-filter>button:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
3363
3370
|
.knobs-diff-filter>button svg{width:12px;height:12px}
|
|
3364
3371
|
.knobs-diff-list{position:relative;flex:1;min-height:0}
|
|
3365
3372
|
.knobs-diff-files .knobs-diff-counts{font-size:var(--_k-text-meta);align-items:center}
|
|
@@ -11215,29 +11222,6 @@ var init_compare_strip = __esm(() => {
|
|
|
11215
11222
|
DIFF = { w: 32, h: 18 };
|
|
11216
11223
|
});
|
|
11217
11224
|
|
|
11218
|
-
// src/ui/player.ts
|
|
11219
|
-
function playGlyph(doc) {
|
|
11220
|
-
const element = doc.createElement("span");
|
|
11221
|
-
element.className = "knobs-player-glyph";
|
|
11222
|
-
element.setAttribute("aria-hidden", "true");
|
|
11223
|
-
let timer = 0;
|
|
11224
|
-
const win = doc.defaultView;
|
|
11225
|
-
return {
|
|
11226
|
-
element,
|
|
11227
|
-
flash(playing) {
|
|
11228
|
-
element.innerHTML = playing ? PLAY2 : PAUSE;
|
|
11229
|
-
element.setAttribute("data-flash", "");
|
|
11230
|
-
win.clearTimeout(timer);
|
|
11231
|
-
timer = win.setTimeout(() => element.removeAttribute("data-flash"), FLASH_MS);
|
|
11232
|
-
},
|
|
11233
|
-
dispose: () => win.clearTimeout(timer)
|
|
11234
|
-
};
|
|
11235
|
-
}
|
|
11236
|
-
var FLASH_MS = 450;
|
|
11237
|
-
var init_player = __esm(() => {
|
|
11238
|
-
init_timeline();
|
|
11239
|
-
});
|
|
11240
|
-
|
|
11241
11225
|
// src/ui/compare.ts
|
|
11242
11226
|
function compare(container, options) {
|
|
11243
11227
|
const doc = container.ownerDocument;
|
|
@@ -11356,8 +11340,7 @@ function compare(container, options) {
|
|
|
11356
11340
|
grip.setAttribute("aria-hidden", "true");
|
|
11357
11341
|
handle.append(grip);
|
|
11358
11342
|
const note = el("div", "knobs-cmp-note");
|
|
11359
|
-
|
|
11360
|
-
stage.append(canvas, split, seam, labels[0], labels[1], handle, zoomPill, note, glyph.element);
|
|
11343
|
+
stage.append(canvas, split, seam, labels[0], labels[1], handle, zoomPill, note);
|
|
11361
11344
|
root.append(bar, stage);
|
|
11362
11345
|
const wantsStrip = options.strip === true;
|
|
11363
11346
|
let tl = bound;
|
|
@@ -11399,7 +11382,6 @@ function compare(container, options) {
|
|
|
11399
11382
|
let drag = null;
|
|
11400
11383
|
const touches = new Map;
|
|
11401
11384
|
let pinch = null;
|
|
11402
|
-
let press = null;
|
|
11403
11385
|
const zu = new Spring(0, ZOOM.omega, ZOOM.zeta, 0.00001);
|
|
11404
11386
|
const zv = new Spring(0, ZOOM.omega, ZOOM.zeta, 0.00001);
|
|
11405
11387
|
const zw = new Spring(1, ZOOM.omega, ZOOM.zeta, 0.00001);
|
|
@@ -12228,10 +12210,8 @@ function compare(container, options) {
|
|
|
12228
12210
|
root.focus({ preventScroll: true });
|
|
12229
12211
|
touches.set(e.pointerId, p);
|
|
12230
12212
|
stage.setPointerCapture(e.pointerId);
|
|
12231
|
-
press = touches.size === 1 && mode !== "wipe" && master() ? p : null;
|
|
12232
12213
|
if (touches.size >= 2) {
|
|
12233
12214
|
e.preventDefault();
|
|
12234
|
-
press = null;
|
|
12235
12215
|
return startPinch();
|
|
12236
12216
|
}
|
|
12237
12217
|
if (mode === "wipe") {
|
|
@@ -12259,8 +12239,6 @@ function compare(container, options) {
|
|
|
12259
12239
|
const onMove = (e) => {
|
|
12260
12240
|
const p = local(e);
|
|
12261
12241
|
pointer = p;
|
|
12262
|
-
if (press && Math.hypot(p.x - press.x, p.y - press.y) > 4)
|
|
12263
|
-
press = null;
|
|
12264
12242
|
if (touches.has(e.pointerId))
|
|
12265
12243
|
touches.set(e.pointerId, p);
|
|
12266
12244
|
if (pinch && touches.size >= 2) {
|
|
@@ -12290,11 +12268,6 @@ function compare(container, options) {
|
|
|
12290
12268
|
drawNow();
|
|
12291
12269
|
};
|
|
12292
12270
|
const endDrag = (e) => {
|
|
12293
|
-
if (press && e.type === "pointerup") {
|
|
12294
|
-
api.toggle();
|
|
12295
|
-
glyph.flash(isPlaying());
|
|
12296
|
-
}
|
|
12297
|
-
press = null;
|
|
12298
12271
|
touches.delete(e.pointerId);
|
|
12299
12272
|
if (touches.size < 2)
|
|
12300
12273
|
pinch = null;
|
|
@@ -12456,7 +12429,6 @@ function compare(container, options) {
|
|
|
12456
12429
|
old.el.replaceWith(s.el);
|
|
12457
12430
|
old.preview.replaceWith(s.preview);
|
|
12458
12431
|
sides[index] = s;
|
|
12459
|
-
root.toggleAttribute("data-video", sides.some((x) => x.kind === "video"));
|
|
12460
12432
|
note.textContent = "";
|
|
12461
12433
|
setLabel(index, labelOf(index));
|
|
12462
12434
|
if (near)
|
|
@@ -12471,7 +12443,6 @@ function compare(container, options) {
|
|
|
12471
12443
|
stage.insertBefore(sides[0].preview, labels[0]);
|
|
12472
12444
|
setLabel(0, labelOf(0));
|
|
12473
12445
|
setLabel(1, labelOf(1));
|
|
12474
|
-
root.toggleAttribute("data-video", sides.some((s) => s.kind === "video"));
|
|
12475
12446
|
loupeBtn.setAttribute("aria-pressed", String(loupeOn));
|
|
12476
12447
|
loopBtn.setAttribute("aria-pressed", String(loopNow() !== null));
|
|
12477
12448
|
const modePill = modeList.length > 1 ? selectionPill(modes, {
|
|
@@ -12672,7 +12643,6 @@ function compare(container, options) {
|
|
|
12672
12643
|
disposed = true;
|
|
12673
12644
|
loop.stop();
|
|
12674
12645
|
modePill?.dispose();
|
|
12675
|
-
glyph.dispose();
|
|
12676
12646
|
win.clearTimeout(releaseTimer);
|
|
12677
12647
|
ro.disconnect();
|
|
12678
12648
|
nearIo?.disconnect();
|
|
@@ -12713,7 +12683,6 @@ var init_compare = __esm(() => {
|
|
|
12713
12683
|
init_icons();
|
|
12714
12684
|
init_look();
|
|
12715
12685
|
init_rgba();
|
|
12716
|
-
init_player();
|
|
12717
12686
|
init_selection_pill();
|
|
12718
12687
|
init_timeline();
|
|
12719
12688
|
init_timeline_model();
|
|
@@ -12732,6 +12701,171 @@ var init_compare = __esm(() => {
|
|
|
12732
12701
|
};
|
|
12733
12702
|
});
|
|
12734
12703
|
|
|
12704
|
+
// src/ui/player.ts
|
|
12705
|
+
function player(container, options) {
|
|
12706
|
+
const doc = container.ownerDocument;
|
|
12707
|
+
const el = (tag, cls) => {
|
|
12708
|
+
const n = doc.createElement(tag);
|
|
12709
|
+
n.className = cls;
|
|
12710
|
+
return n;
|
|
12711
|
+
};
|
|
12712
|
+
const look = {
|
|
12713
|
+
...options.preset ? { preset: options.preset } : {},
|
|
12714
|
+
...options.theme ? { theme: options.theme } : {},
|
|
12715
|
+
...options.appearance ? { appearance: options.appearance } : {}
|
|
12716
|
+
};
|
|
12717
|
+
const root = el("div", "knobs-player");
|
|
12718
|
+
root.setAttribute("role", "group");
|
|
12719
|
+
root.setAttribute("aria-label", options.label ?? "Video");
|
|
12720
|
+
applyLook2(root, options);
|
|
12721
|
+
const frame = el("div", "knobs-player-frame");
|
|
12722
|
+
frame.style.setProperty("--kp-aspect", String(options.aspect ?? 16 / 9));
|
|
12723
|
+
const v = el("video", "knobs-player-media");
|
|
12724
|
+
v.muted = options.muted ?? true;
|
|
12725
|
+
v.defaultMuted = v.muted;
|
|
12726
|
+
v.playsInline = true;
|
|
12727
|
+
v.preload = "metadata";
|
|
12728
|
+
v.setAttribute("playsinline", "");
|
|
12729
|
+
if (options.poster)
|
|
12730
|
+
v.poster = options.poster;
|
|
12731
|
+
if (options.captions) {
|
|
12732
|
+
const track = doc.createElement("track");
|
|
12733
|
+
track.kind = "captions";
|
|
12734
|
+
track.label = "Captions";
|
|
12735
|
+
track.srclang = doc.documentElement.lang || "en";
|
|
12736
|
+
track.default = true;
|
|
12737
|
+
track.src = options.captions;
|
|
12738
|
+
v.append(track);
|
|
12739
|
+
}
|
|
12740
|
+
frame.append(v);
|
|
12741
|
+
const host = el("div", "knobs-player-line");
|
|
12742
|
+
root.append(frame, host);
|
|
12743
|
+
container.append(root);
|
|
12744
|
+
const markers = (options.chapters ?? []).map((c, i) => ({
|
|
12745
|
+
id: c.id ?? `c${i}`,
|
|
12746
|
+
time: c.start,
|
|
12747
|
+
label: c.label
|
|
12748
|
+
}));
|
|
12749
|
+
const tl = timeline(host, {
|
|
12750
|
+
...look,
|
|
12751
|
+
variant: "line",
|
|
12752
|
+
duration: 1,
|
|
12753
|
+
fps: options.fps ?? 30,
|
|
12754
|
+
markers,
|
|
12755
|
+
repeat: options.loop ?? true,
|
|
12756
|
+
arrows: { step: 5, shift: 10 },
|
|
12757
|
+
label: options.label ? `${options.label} time` : "Video time",
|
|
12758
|
+
...options.hints === false ? { hints: false } : {}
|
|
12759
|
+
});
|
|
12760
|
+
const onFrame = () => root.setAttribute("data-ready", "");
|
|
12761
|
+
let pending = null;
|
|
12762
|
+
const seekVideo = (t) => {
|
|
12763
|
+
if (v.readyState < 1)
|
|
12764
|
+
return;
|
|
12765
|
+
if (v.seeking)
|
|
12766
|
+
pending = t;
|
|
12767
|
+
else
|
|
12768
|
+
v.currentTime = t;
|
|
12769
|
+
};
|
|
12770
|
+
let reported = 0;
|
|
12771
|
+
const onSeeked = () => {
|
|
12772
|
+
if (pending !== null) {
|
|
12773
|
+
const t = pending;
|
|
12774
|
+
pending = null;
|
|
12775
|
+
v.currentTime = t;
|
|
12776
|
+
return;
|
|
12777
|
+
}
|
|
12778
|
+
if (!v.paused || tl.playing || Math.abs(v.currentTime - reported) < 0.1)
|
|
12779
|
+
return;
|
|
12780
|
+
reported = v.currentTime;
|
|
12781
|
+
options.onSeek?.(reported);
|
|
12782
|
+
};
|
|
12783
|
+
const onMeta = () => {
|
|
12784
|
+
onFrame();
|
|
12785
|
+
if (v.videoWidth)
|
|
12786
|
+
frame.style.setProperty("--kp-aspect", String(v.videoWidth / v.videoHeight));
|
|
12787
|
+
if (Number.isFinite(v.duration))
|
|
12788
|
+
tl.update({ duration: v.duration });
|
|
12789
|
+
};
|
|
12790
|
+
v.addEventListener("loadedmetadata", onMeta);
|
|
12791
|
+
v.addEventListener("loadeddata", onFrame);
|
|
12792
|
+
v.addEventListener("seeked", onSeeked);
|
|
12793
|
+
const unlisten = tl.listen({
|
|
12794
|
+
onSeek(t, source) {
|
|
12795
|
+
if (source === "play") {
|
|
12796
|
+
if (Math.abs(v.currentTime - t) > 0.25)
|
|
12797
|
+
v.currentTime = t;
|
|
12798
|
+
return;
|
|
12799
|
+
}
|
|
12800
|
+
if (Math.abs(v.currentTime - t) < 1 / (options.fps ?? 30))
|
|
12801
|
+
return;
|
|
12802
|
+
seekVideo(t);
|
|
12803
|
+
},
|
|
12804
|
+
onPlay(on) {
|
|
12805
|
+
if (on)
|
|
12806
|
+
v.play().catch(() => tl.pause());
|
|
12807
|
+
else {
|
|
12808
|
+
v.pause();
|
|
12809
|
+
reported = tl.time;
|
|
12810
|
+
}
|
|
12811
|
+
root.toggleAttribute("data-playing", on);
|
|
12812
|
+
options.onPlay?.(on, tl.time);
|
|
12813
|
+
},
|
|
12814
|
+
onScrub(on) {
|
|
12815
|
+
if (on)
|
|
12816
|
+
v.pause();
|
|
12817
|
+
}
|
|
12818
|
+
});
|
|
12819
|
+
tl.drive(() => {
|
|
12820
|
+
if (v.readyState < 1)
|
|
12821
|
+
return Number.NaN;
|
|
12822
|
+
if (v.seeking)
|
|
12823
|
+
return tl.time;
|
|
12824
|
+
return v.ended ? Number.POSITIVE_INFINITY : v.currentTime;
|
|
12825
|
+
});
|
|
12826
|
+
const onClick = () => tl.focus();
|
|
12827
|
+
frame.addEventListener("click", onClick);
|
|
12828
|
+
v.src = options.src;
|
|
12829
|
+
const api = {
|
|
12830
|
+
element: root,
|
|
12831
|
+
video: v,
|
|
12832
|
+
timeline: tl,
|
|
12833
|
+
get time() {
|
|
12834
|
+
return tl.time;
|
|
12835
|
+
},
|
|
12836
|
+
get playing() {
|
|
12837
|
+
return tl.playing;
|
|
12838
|
+
},
|
|
12839
|
+
get duration() {
|
|
12840
|
+
return Number.isFinite(v.duration) ? v.duration : 0;
|
|
12841
|
+
},
|
|
12842
|
+
play: () => tl.play(),
|
|
12843
|
+
pause: () => tl.pause(),
|
|
12844
|
+
toggle: () => tl.toggle(),
|
|
12845
|
+
seek: (t, o) => tl.seek(t, o?.glide ? { glide: true } : undefined),
|
|
12846
|
+
seekBy: (d) => tl.seek(Math.min(tl.duration, Math.max(0, tl.time + d)), { glide: true }),
|
|
12847
|
+
focus: () => tl.focus(),
|
|
12848
|
+
dispose() {
|
|
12849
|
+
unlisten();
|
|
12850
|
+
tl.drive(null);
|
|
12851
|
+
tl.dispose();
|
|
12852
|
+
v.pause();
|
|
12853
|
+
frame.removeEventListener("click", onClick);
|
|
12854
|
+
v.removeEventListener("loadedmetadata", onMeta);
|
|
12855
|
+
v.removeEventListener("loadeddata", onFrame);
|
|
12856
|
+
v.removeEventListener("seeked", onSeeked);
|
|
12857
|
+
v.removeAttribute("src");
|
|
12858
|
+
v.load();
|
|
12859
|
+
root.remove();
|
|
12860
|
+
}
|
|
12861
|
+
};
|
|
12862
|
+
return api;
|
|
12863
|
+
}
|
|
12864
|
+
var init_player = __esm(() => {
|
|
12865
|
+
init_look();
|
|
12866
|
+
init_timeline();
|
|
12867
|
+
});
|
|
12868
|
+
|
|
12735
12869
|
// src/ui/solid.ts
|
|
12736
12870
|
import {
|
|
12737
12871
|
children,
|
|
@@ -18215,25 +18349,63 @@ function normalizeWalkthrough(doc) {
|
|
|
18215
18349
|
})),
|
|
18216
18350
|
sections: withKickers(sections, doc.sections, doc.kickers),
|
|
18217
18351
|
steps,
|
|
18218
|
-
prs: knownPRs(doc, sections),
|
|
18352
|
+
prs: knownPRs(doc, sections, steps),
|
|
18219
18353
|
...repoOf(doc) ? { repo: repoOf(doc) } : {}
|
|
18220
18354
|
};
|
|
18221
18355
|
}
|
|
18222
18356
|
var prNumber = (href) => /\/(?:pull|merge_requests)\/(\d+)(?:[/?#]|$)/.exec(href)?.[1] ?? null;
|
|
18223
18357
|
var repoOf = (doc) => doc.repo?.trim().replace(/^https?:\/\/github\.com\//, "").replace(/\/+$/, "") || undefined;
|
|
18224
|
-
|
|
18358
|
+
var PR_STATES = ["merged", "open", "draft", "closed"];
|
|
18359
|
+
function prStatus(status) {
|
|
18360
|
+
const words = (status ?? "").trim().toLowerCase();
|
|
18361
|
+
const first = /^[a-z]+/.exec(words)?.[0] ?? "";
|
|
18362
|
+
const state = PR_STATES.includes(first) ? first : first === "shipped" || first === "done" ? "merged" : null;
|
|
18363
|
+
return { state, checks: /\b(green|passing|passed|ci|checks? pass)/.test(words) };
|
|
18364
|
+
}
|
|
18365
|
+
function knownPRs(doc, sections, steps = []) {
|
|
18225
18366
|
const out = {};
|
|
18226
18367
|
const repo = repoOf(doc);
|
|
18227
|
-
|
|
18228
|
-
const
|
|
18229
|
-
|
|
18230
|
-
|
|
18231
|
-
|
|
18368
|
+
const add = (n, pr) => {
|
|
18369
|
+
const known = out[n] ?? {};
|
|
18370
|
+
const next = { ...known };
|
|
18371
|
+
for (const [k, v] of Object.entries(pr))
|
|
18372
|
+
if (v !== undefined && next[k] === undefined)
|
|
18373
|
+
next[k] = v;
|
|
18374
|
+
out[n] = next;
|
|
18375
|
+
};
|
|
18232
18376
|
for (const [k, pr] of Object.entries(doc.prs ?? {})) {
|
|
18233
18377
|
const n = k.replace(/^#/, "");
|
|
18234
18378
|
if (!/^\d+$/.test(n))
|
|
18235
18379
|
continue;
|
|
18236
|
-
|
|
18380
|
+
add(n, pr);
|
|
18381
|
+
}
|
|
18382
|
+
for (const step of steps)
|
|
18383
|
+
for (const m of step.media) {
|
|
18384
|
+
if (m.kind !== "stack")
|
|
18385
|
+
continue;
|
|
18386
|
+
for (const it of m.items) {
|
|
18387
|
+
const n = it.pr.replace(/^#/, "");
|
|
18388
|
+
if (!/^\d+$/.test(n))
|
|
18389
|
+
continue;
|
|
18390
|
+
const said = prStatus(it.status);
|
|
18391
|
+
add(n, {
|
|
18392
|
+
...said.state ? { state: said.state } : {},
|
|
18393
|
+
...said.state && said.checks ? { checks: true } : {},
|
|
18394
|
+
...it.title ? { title: plainMarkdown(it.title) } : {},
|
|
18395
|
+
...it.href ? { href: it.href } : {}
|
|
18396
|
+
});
|
|
18397
|
+
}
|
|
18398
|
+
}
|
|
18399
|
+
for (const s of sections) {
|
|
18400
|
+
const n = s.link && prNumber(s.link.href);
|
|
18401
|
+
if (!n)
|
|
18402
|
+
continue;
|
|
18403
|
+
const said = prStatus(s.status);
|
|
18404
|
+
add(n, {
|
|
18405
|
+
href: s.link.href.replace(/(\/pull\/\d+).*$/, "$1"),
|
|
18406
|
+
...said.state ? { state: said.state } : {},
|
|
18407
|
+
title: plainMarkdown(s.title)
|
|
18408
|
+
});
|
|
18237
18409
|
}
|
|
18238
18410
|
if (repo) {
|
|
18239
18411
|
for (const n of Object.keys(out))
|
|
@@ -18242,12 +18414,17 @@ function knownPRs(doc, sections) {
|
|
|
18242
18414
|
}
|
|
18243
18415
|
return out;
|
|
18244
18416
|
}
|
|
18245
|
-
function findPR(prs, n, repo) {
|
|
18246
|
-
const
|
|
18417
|
+
function findPR(prs, n, repo, kind = "pr") {
|
|
18418
|
+
const entry = prs[n];
|
|
18419
|
+
const known = entry && (entry.kind ?? "pr") === kind ? entry : undefined;
|
|
18420
|
+
const path = kind === "issue" ? "issues" : "pull";
|
|
18421
|
+
const href = repo ? `https://github.com/${repo}/${path}/${n}` : undefined;
|
|
18422
|
+
const base = kind === "issue" ? { kind } : {};
|
|
18247
18423
|
if (known)
|
|
18248
|
-
return known;
|
|
18249
|
-
return
|
|
18424
|
+
return known.href || !href ? { ...base, ...known } : { ...base, ...known, href };
|
|
18425
|
+
return href ? { ...base, href } : kind === "issue" ? { kind } : null;
|
|
18250
18426
|
}
|
|
18427
|
+
var issueNumber = (href) => /^https?:\/\/[^/]+\/.+\/issues\/(\d+)\/?(?:[?#].*)?$/.exec(href)?.[1] ?? null;
|
|
18251
18428
|
var isPullRequest = (href) => /\/(?:pull|merge_requests)\/\d+(?:[/?#]|$)/.test(href);
|
|
18252
18429
|
function withKickers(sections, source, kickers = "pr") {
|
|
18253
18430
|
if (kickers === false)
|
|
@@ -19211,7 +19388,7 @@ function mountHistory(host, m, steps) {
|
|
|
19211
19388
|
context: () => ({ kind: "history" })
|
|
19212
19389
|
};
|
|
19213
19390
|
}
|
|
19214
|
-
function mountStack(host, m, steps) {
|
|
19391
|
+
function mountStack(host, m, steps, findPR) {
|
|
19215
19392
|
const doc = host.ownerDocument;
|
|
19216
19393
|
const layout = stackLayout(m);
|
|
19217
19394
|
const root = el2(doc, "div", "knobs-wt-stack");
|
|
@@ -19253,7 +19430,10 @@ function mountStack(host, m, steps) {
|
|
|
19253
19430
|
const line = el2(doc, "div", "knobs-wt-sline");
|
|
19254
19431
|
if (it.order)
|
|
19255
19432
|
line.append(text2(doc, "span", "knobs-wt-sord", it.order));
|
|
19256
|
-
|
|
19433
|
+
const known = findPR?.(it.pr.replace(/^#/, "")) ?? null;
|
|
19434
|
+
const pr = link(doc, "knobs-wt-spr", it.pr, it.href ?? known?.href);
|
|
19435
|
+
pr.addEventListener("click", (e) => e.stopPropagation());
|
|
19436
|
+
line.append(pr);
|
|
19257
19437
|
const target = it.step ? steps?.find(it.step) : null;
|
|
19258
19438
|
if (target && steps) {
|
|
19259
19439
|
const title = text2(doc, "button", "knobs-wt-stitle", it.title);
|
|
@@ -19288,7 +19468,11 @@ function mountStack(host, m, steps) {
|
|
|
19288
19468
|
if (meta.childNodes.length)
|
|
19289
19469
|
main.append(meta);
|
|
19290
19470
|
row.append(main);
|
|
19291
|
-
|
|
19471
|
+
const said = prStatus(it.status);
|
|
19472
|
+
const state = known?.state ?? said.state;
|
|
19473
|
+
if (state)
|
|
19474
|
+
row.append(prStateLabel(doc, state, said.checks, it.status));
|
|
19475
|
+
else if (it.status) {
|
|
19292
19476
|
const chip = text2(doc, "span", "knobs-wt-chip knobs-wt-sstatus", it.status);
|
|
19293
19477
|
chip.dataset.tone = it.tone ?? "dim";
|
|
19294
19478
|
row.append(chip);
|
|
@@ -19595,8 +19779,29 @@ var PR_PATHS = {
|
|
|
19595
19779
|
pull: "M104,64A32,32,0,1,0,64,95v66a32,32,0,1,0,16,0V95A32.06,32.06,0,0,0,104,64ZM56,64A16,16,0,1,1,72,80,16,16,0,0,1,56,64ZM88,192a16,16,0,1,1-16-16A16,16,0,0,1,88,192Zm120-31V110.63a23.85,23.85,0,0,0-7-17L163.31,56H192a8,8,0,0,0,0-16H144a8,8,0,0,0-8,8V96a8,8,0,0,0,16,0V67.31L189.66,105a8,8,0,0,1,2.34,5.66V161a32,32,0,1,0,16,0Zm-8,47a16,16,0,1,1,16-16A16,16,0,0,1,200,208Z",
|
|
19596
19780
|
merge: "M208,112a32.05,32.05,0,0,0-30.69,23l-42.21-6a8,8,0,0,1-4.95-2.71L94.43,84.55A32,32,0,1,0,72,87v82a32,32,0,1,0,16,0V101.63l30,35a24,24,0,0,0,14.83,8.14l44,6.28A32,32,0,1,0,208,112ZM64,56A16,16,0,1,1,80,72,16,16,0,0,1,64,56ZM96,200a16,16,0,1,1-16-16A16,16,0,0,1,96,200Zm112-40a16,16,0,1,1,16-16A16,16,0,0,1,208,160Z"
|
|
19597
19781
|
};
|
|
19598
|
-
var
|
|
19782
|
+
var DRAFT = "M104,64A32,32,0,1,0,64,95v66a32,32,0,1,0,16,0V95A32.06,32.06,0,0,0,104,64ZM56,64A16,16,0,1,1,72,80,16,16,0,0,1,56,64ZM88,192a16,16,0,1,1-16-16A16,16,0,0,1,88,192ZM232,192a32,32,0,1,1-32-32A32,32,0,0,1,232,192ZM216,192a16,16,0,1,0-16,16A16,16,0,0,0,216,192ZM212,120a12,12,0,1,1-12-12A12,12,0,0,1,212,120ZM212,60a12,12,0,1,1-12-12A12,12,0,0,1,212,60Z";
|
|
19783
|
+
var X = "M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z";
|
|
19784
|
+
var CHECK3 = "M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z";
|
|
19785
|
+
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>`;
|
|
19786
|
+
var prGlyph = (state) => state === "merged" ? svg12(PR_PATHS.merge) : state === "draft" ? svg12(DRAFT, true) : state === "closed" ? svg12(X) : svg12(PR_PATHS.pull);
|
|
19599
19787
|
var PR_STATE = { merged: "Merged", open: "Open", draft: "Draft", closed: "Closed" };
|
|
19788
|
+
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";
|
|
19789
|
+
function prStateLabel(doc, state, checks, title) {
|
|
19790
|
+
const s = el2(doc, "span", "knobs-wt-prstate");
|
|
19791
|
+
s.dataset.state = state;
|
|
19792
|
+
s.innerHTML = prGlyph(state);
|
|
19793
|
+
s.append(text2(doc, "span", "", PR_STATE[state]));
|
|
19794
|
+
if (checks) {
|
|
19795
|
+
const c = el2(doc, "span", "knobs-wt-prchecks");
|
|
19796
|
+
c.innerHTML = svg12(CHECK3);
|
|
19797
|
+
c.title = "Checks pass";
|
|
19798
|
+
c.setAttribute("aria-label", "checks pass");
|
|
19799
|
+
s.append(c);
|
|
19800
|
+
}
|
|
19801
|
+
if (title)
|
|
19802
|
+
s.title = title;
|
|
19803
|
+
return s;
|
|
19804
|
+
}
|
|
19600
19805
|
function prChip(doc, n, pr) {
|
|
19601
19806
|
const chip = el2(doc, pr.href ? "a" : "span", "knobs-wt-pr");
|
|
19602
19807
|
if (pr.href) {
|
|
@@ -19604,27 +19809,55 @@ function prChip(doc, n, pr) {
|
|
|
19604
19809
|
chip.setAttribute("target", "_blank");
|
|
19605
19810
|
chip.setAttribute("rel", "noreferrer");
|
|
19606
19811
|
}
|
|
19812
|
+
const issue = pr.kind === "issue";
|
|
19813
|
+
if (issue)
|
|
19814
|
+
chip.dataset.kind = "issue";
|
|
19607
19815
|
if (pr.state)
|
|
19608
19816
|
chip.dataset.state = pr.state;
|
|
19609
|
-
chip.innerHTML = prGlyph(pr.state
|
|
19817
|
+
chip.innerHTML = issue ? svg12(ISSUE) : prGlyph(pr.state);
|
|
19610
19818
|
chip.append(text2(doc, "span", "", `#${n}`));
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19819
|
+
if (pr.checks) {
|
|
19820
|
+
const c = el2(doc, "span", "knobs-wt-prchecks");
|
|
19821
|
+
c.innerHTML = svg12(CHECK3);
|
|
19822
|
+
chip.append(c);
|
|
19823
|
+
}
|
|
19824
|
+
const words = [
|
|
19825
|
+
`${issue ? "Issue" : "Pull request"} #${n}`,
|
|
19826
|
+
pr.title,
|
|
19827
|
+
pr.state ? PR_STATE[pr.state] : "",
|
|
19828
|
+
pr.checks ? "checks pass" : ""
|
|
19829
|
+
].filter(Boolean);
|
|
19830
|
+
chip.title = words.slice(1).length ? `#${n} · ${words.slice(1).join(" · ")}` : `#${n}`;
|
|
19831
|
+
chip.setAttribute("aria-label", words.join(" · "));
|
|
19614
19832
|
return chip;
|
|
19615
19833
|
}
|
|
19616
19834
|
var PR_URL = /^https?:\/\/[^/]+\/.+\/(?:pull|merge_requests)\/(\d+)\/?(?:[?#].*)?$/;
|
|
19617
|
-
var
|
|
19835
|
+
var ISSUE_URL = /^https?:\/\/[^/]+\/.+\/issues\/(\d+)\/?(?:[?#].*)?$/;
|
|
19836
|
+
var REF = /(^|[^\w&/#:])(issue:)?#(\d{3,7})\b/gi;
|
|
19837
|
+
var WHOLE_REF = /^(issue:)?#(\d{1,7})$/i;
|
|
19838
|
+
var KEEP = 'a,pre,button,.knobs-wt-pr,.knobs-wt-slot:not([data-kind="table"]),.knobs-wt-stack';
|
|
19618
19839
|
function linkPRs(root, find) {
|
|
19619
19840
|
const doc = root.ownerDocument;
|
|
19841
|
+
const chip = (n, kind, href) => prChip(doc, n, { ...kind === "issue" ? { kind } : {}, ...find(n, kind), ...href ? { href } : {} });
|
|
19620
19842
|
for (const a of Array.from(root.querySelectorAll("a[href]"))) {
|
|
19621
|
-
if (a.classList.contains("knobs-wt-pr") || a.closest(
|
|
19843
|
+
if (a.classList.contains("knobs-wt-pr") || a.parentElement?.closest(KEEP))
|
|
19844
|
+
continue;
|
|
19845
|
+
const url = a.getAttribute("href") ?? "";
|
|
19846
|
+
const pr = PR_URL.exec(url)?.[1];
|
|
19847
|
+
const n = pr ?? ISSUE_URL.exec(url)?.[1];
|
|
19848
|
+
if (!n)
|
|
19622
19849
|
continue;
|
|
19623
|
-
const
|
|
19624
|
-
|
|
19625
|
-
if (!n || !(words === `#${n}` || words === n || words === a.getAttribute("href")))
|
|
19850
|
+
const words = (a.textContent ?? "").trim().replace(/^issue:/i, "");
|
|
19851
|
+
if (!(words === `#${n}` || words === n || words === url))
|
|
19626
19852
|
continue;
|
|
19627
|
-
a.replaceWith(
|
|
19853
|
+
a.replaceWith(chip(n, pr ? "pr" : "issue", a.href));
|
|
19854
|
+
}
|
|
19855
|
+
for (const c of Array.from(root.querySelectorAll("code"))) {
|
|
19856
|
+
if (c.closest("pre") || c.parentElement?.closest(KEEP))
|
|
19857
|
+
continue;
|
|
19858
|
+
const m = WHOLE_REF.exec((c.textContent ?? "").trim());
|
|
19859
|
+
if (m)
|
|
19860
|
+
c.replaceWith(chip(m[2], m[1] ? "issue" : "pr"));
|
|
19628
19861
|
}
|
|
19629
19862
|
const walker = doc.createTreeWalker(root, 5);
|
|
19630
19863
|
const hits = [];
|
|
@@ -19632,29 +19865,22 @@ function linkPRs(root, find) {
|
|
|
19632
19865
|
if (t.nodeType !== 3)
|
|
19633
19866
|
continue;
|
|
19634
19867
|
const p = t.parentElement;
|
|
19635
|
-
if (!p || p.closest(
|
|
19868
|
+
if (!p || p.closest(`${KEEP},code`))
|
|
19636
19869
|
continue;
|
|
19637
|
-
|
|
19638
|
-
if (
|
|
19870
|
+
REF.lastIndex = 0;
|
|
19871
|
+
if (REF.test(t.nodeValue ?? ""))
|
|
19639
19872
|
hits.push(t);
|
|
19640
19873
|
}
|
|
19641
19874
|
for (const t of hits) {
|
|
19642
19875
|
const value = t.nodeValue ?? "";
|
|
19643
19876
|
const frag = doc.createDocumentFragment();
|
|
19644
19877
|
let last = 0;
|
|
19645
|
-
|
|
19646
|
-
|
|
19647
|
-
for (let m = PR_REF.exec(value);m; m = PR_REF.exec(value)) {
|
|
19648
|
-
const pr = find(m[2]);
|
|
19649
|
-
if (!pr)
|
|
19650
|
-
continue;
|
|
19878
|
+
REF.lastIndex = 0;
|
|
19879
|
+
for (let m = REF.exec(value);m; m = REF.exec(value)) {
|
|
19651
19880
|
const at = m.index + m[1].length;
|
|
19652
|
-
frag.append(value.slice(last, at),
|
|
19653
|
-
last =
|
|
19654
|
-
changed = true;
|
|
19881
|
+
frag.append(value.slice(last, at), chip(m[3], m[2] ? "issue" : "pr"));
|
|
19882
|
+
last = m.index + m[0].length;
|
|
19655
19883
|
}
|
|
19656
|
-
if (!changed)
|
|
19657
|
-
continue;
|
|
19658
19884
|
frag.append(value.slice(last));
|
|
19659
19885
|
t.replaceWith(frag);
|
|
19660
19886
|
}
|
|
@@ -19673,7 +19899,7 @@ var snappy3 = springCss(SPRINGS.snappy);
|
|
|
19673
19899
|
var calm = springCss(SPRINGS.calm);
|
|
19674
19900
|
var state = springCss(SPRINGS.default);
|
|
19675
19901
|
var quick = springCss(FADE);
|
|
19676
|
-
var fade2 = "-webkit-mask-image:linear-gradient(to right,#000 calc(100% -
|
|
19902
|
+
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)";
|
|
19677
19903
|
var walkthroughCss = `
|
|
19678
19904
|
:where(.knobs-walkthrough,.knobs-walkthrough *,.knobs-wt-slot,.knobs-wt-slot *){box-sizing:border-box}
|
|
19679
19905
|
.knobs-ui:is(.knobs-walkthrough,.knobs-wt-slot){--k-glass:0;--k-glow:0;--kw-quick:${quick.easing};--kw-quick-ms:${quick.duration}ms}
|
|
@@ -19685,7 +19911,7 @@ var walkthroughCss = `
|
|
|
19685
19911
|
.knobs-walkthrough [hidden]{display:none!important}
|
|
19686
19912
|
/* (0,0,1): a host's element rules stop here, and every class rule below wins over it. */
|
|
19687
19913
|
:where(.knobs-walkthrough) :is(h1,h2,h3,p,ol,ul,dl,dd){margin:0;font:inherit;letter-spacing:inherit}
|
|
19688
|
-
.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
|
|
19914
|
+
.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)}
|
|
19689
19915
|
.knobs-walkthrough a:hover{text-decoration-color:currentColor}
|
|
19690
19916
|
.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)}
|
|
19691
19917
|
: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;
|
|
@@ -19713,14 +19939,17 @@ var walkthroughCss = `
|
|
|
19713
19939
|
.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)}
|
|
19714
19940
|
.knobs-walkthrough .knobs-wt-metaline a:not(.knobs-wt-pr):hover{color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
19715
19941
|
.knobs-wt-metaline svg{align-self:center;width:12px;height:12px;margin-left:2px}
|
|
19716
|
-
/* A pull request: a
|
|
19717
|
-
the success hue, merged the violet series, draft and closed
|
|
19718
|
-
|
|
19942
|
+
/* A pull request or issue: a capsule, its state's icon and number in a quiet tint of the state
|
|
19943
|
+
(open the success hue, merged the violet series, draft and closed faint, unknown neutral; a
|
|
19944
|
+
closed issue is done, so violet), a faint check where its checks pass, its title on hover. */
|
|
19945
|
+
.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;
|
|
19719
19946
|
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;
|
|
19720
19947
|
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
19721
19948
|
.knobs-ui .knobs-wt-pr[data-state="open"]{--kw-pr:color-mix(in oklch,var(--_k-ok) 60%,var(--_k-fg-2))}
|
|
19722
19949
|
.knobs-ui .knobs-wt-pr[data-state="merged"]{--kw-pr:color-mix(in oklch,var(--_k-series-5) 60%,var(--_k-fg-2))}
|
|
19723
19950
|
.knobs-ui .knobs-wt-pr:is([data-state="draft"],[data-state="closed"]){--kw-pr:var(--_k-fg-3)}
|
|
19951
|
+
.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))}
|
|
19952
|
+
.knobs-ui .knobs-wt-pr .knobs-wt-prchecks{margin-left:0}
|
|
19724
19953
|
.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)}
|
|
19725
19954
|
.knobs-wt-pr svg{flex:none}
|
|
19726
19955
|
.knobs-wt-metaline .knobs-wt-pr{align-self:center;margin:0}
|
|
@@ -19779,14 +20008,14 @@ var walkthroughCss = `
|
|
|
19779
20008
|
.knobs-wt-fi-ask{max-width:var(--kw-measure);color:var(--_k-fg);font-weight:var(--kw-strong);text-wrap:pretty}
|
|
19780
20009
|
.knobs-wt-fi-text{max-width:var(--kw-measure);color:var(--_k-fg);text-wrap:pretty}
|
|
19781
20010
|
.knobs-wt-fi-answer{max-width:var(--kw-measure);color:var(--_k-fg-2);text-wrap:pretty}
|
|
19782
|
-
: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:
|
|
20011
|
+
: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;
|
|
19783
20012
|
transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
19784
20013
|
.knobs-ui .knobs-wt-fi-step:is(:hover,:focus-visible){color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
19785
20014
|
|
|
19786
20015
|
/* ——— a disclosure: a small faint toggle with a caret, no fill. The body's height springs (in
|
|
19787
20016
|
script) and its content fades in place, top-anchored, under a soft bottom mask ——— */
|
|
19788
20017
|
.knobs-wt-disc{display:flex;flex-direction:column;min-width:0}
|
|
19789
|
-
.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:
|
|
20018
|
+
.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;
|
|
19790
20019
|
border-radius:calc(var(--_k-radius) / 2);transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
19791
20020
|
.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)}
|
|
19792
20021
|
.knobs-ui .knobs-wt-disc-toggle:focus-visible{box-shadow:0 0 0 2px var(--_k-focus)}
|
|
@@ -19813,7 +20042,7 @@ var walkthroughCss = `
|
|
|
19813
20042
|
.knobs-wt-n[data-leaving]{opacity:0;filter:blur(3px);padding-block:0}
|
|
19814
20043
|
.knobs-wt-n+.knobs-wt-n{box-shadow:inset 0 1px 0 var(--_k-border-subtle)}
|
|
19815
20044
|
.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)}
|
|
19816
|
-
.knobs-wt-n-meta[data-seek]{cursor:
|
|
20045
|
+
.knobs-wt-n-meta[data-seek]{cursor:default}
|
|
19817
20046
|
.knobs-wt-n-meta[data-seek]:hover{color:var(--_k-fg)}
|
|
19818
20047
|
.knobs-wt-n-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--_k-space-sibling)}
|
|
19819
20048
|
.knobs-wt-n-voice{height:30px;max-width:320px}
|
|
@@ -19830,7 +20059,7 @@ var walkthroughCss = `
|
|
|
19830
20059
|
/* Collapsed: the launcher and the bar swap in place, a quick fade with a little scale and blur
|
|
19831
20060
|
from the launcher's corner; the exit is the shorter. */
|
|
19832
20061
|
: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);
|
|
19833
|
-
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:
|
|
20062
|
+
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%;
|
|
19834
20063
|
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)}
|
|
19835
20064
|
.knobs-ui .knobs-wt-launch:is(:hover,:focus-visible){color:var(--_k-fg)}
|
|
19836
20065
|
.knobs-ui .knobs-wt-launch:focus-visible{box-shadow:var(--_k-focus-ring)}
|
|
@@ -19850,11 +20079,11 @@ var walkthroughCss = `
|
|
|
19850
20079
|
.knobs-wt-attach{display:flex;gap:4px;align-items:center;align-self:center}
|
|
19851
20080
|
.knobs-wt-attach:empty{display:none}
|
|
19852
20081
|
.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}
|
|
19853
|
-
.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:
|
|
20082
|
+
.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}
|
|
19854
20083
|
.knobs-ui .knobs-wt-x:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
19855
20084
|
.knobs-wt-x svg{width:12px;height:12px}
|
|
19856
20085
|
.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);
|
|
19857
|
-
color:var(--_k-fg-2);cursor:
|
|
20086
|
+
color:var(--_k-fg-2);cursor:default;transition:background .15s,color .15s}
|
|
19858
20087
|
.knobs-ui .knobs-wt-tool:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
19859
20088
|
.knobs-ui .knobs-wt-tool[aria-pressed="true"]{background:var(--_k-fill-selected);color:var(--_k-fg)}
|
|
19860
20089
|
.knobs-wt-tool svg{width:16px;height:16px}
|
|
@@ -19864,7 +20093,7 @@ var walkthroughCss = `
|
|
|
19864
20093
|
.knobs-ui .knobs-wt-tool[data-send][data-ready]{background:var(--_k-accent);color:var(--_k-bg)}
|
|
19865
20094
|
/* Back: in place over the bar for a few seconds after a note moves the page on. */
|
|
19866
20095
|
.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;
|
|
19867
|
-
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:
|
|
20096
|
+
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;
|
|
19868
20097
|
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)}
|
|
19869
20098
|
.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)}
|
|
19870
20099
|
.knobs-ui .knobs-wt-back:hover{background:var(--_k-fill-selected)}
|
|
@@ -19891,6 +20120,9 @@ var walkthroughCss = `
|
|
|
19891
20120
|
.knobs-wt-step[data-full] .knobs-wt-body{flex:1;min-height:0}
|
|
19892
20121
|
.knobs-wt-step[data-full] .knobs-wt-fit{height:100%;transition:none}
|
|
19893
20122
|
.knobs-wt-step[data-full] .knobs-wt-frame{height:100%;aspect-ratio:auto}
|
|
20123
|
+
.knobs-wt-step[data-full] .knobs-wt-slot[data-kind="video"]>.knobs-wt-body{display:flex;flex-direction:column}
|
|
20124
|
+
.knobs-wt-step[data-full] .knobs-wt-slot[data-kind="video"] .knobs-player{flex:1;min-height:0}
|
|
20125
|
+
.knobs-wt-step[data-full] .knobs-wt-slot[data-kind="video"] .knobs-player-frame{flex:1;min-height:0;aspect-ratio:auto}
|
|
19894
20126
|
|
|
19895
20127
|
/* ——— a taste test: the options side by side, Kit's pick checked and the rest stepping back. On
|
|
19896
20128
|
the step's card, so no fill of their own ——— */
|
|
@@ -19899,7 +20131,7 @@ var walkthroughCss = `
|
|
|
19899
20131
|
.knobs-wt-option{position:relative;display:flex;flex-direction:column;gap:var(--_k-space-sibling);min-width:0}
|
|
19900
20132
|
.knobs-wt-option>:not(.knobs-wt-pick){transition:opacity var(--kw-snappy-ms) var(--kw-snappy)}
|
|
19901
20133
|
.knobs-wt-options[data-has-pick] .knobs-wt-option:not([data-picked])>:not(.knobs-wt-pick){opacity:.55}
|
|
19902
|
-
.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:
|
|
20134
|
+
.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;
|
|
19903
20135
|
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
19904
20136
|
.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)}
|
|
19905
20137
|
.knobs-wt-letter{flex:none;font-weight:var(--kw-strong);color:var(--_k-fg)}
|
|
@@ -19922,17 +20154,18 @@ var walkthroughCss = `
|
|
|
19922
20154
|
.knobs-wt-bar{position:relative;height:4px;border-radius:2px;overflow:hidden;background:var(--_k-fill)}
|
|
19923
20155
|
.knobs-wt-fill{position:absolute;inset:0;border-radius:inherit;background:var(--_k-accent);transform-origin:0 50%;transform:scaleX(var(--kw-done,0))}
|
|
19924
20156
|
.knobs-walkthrough[data-settled] .knobs-wt-fill{transition:transform var(--kw-calm-ms) var(--kw-calm)}
|
|
19925
|
-
/* The contents: every row on one text edge and in one colour, title rows (
|
|
19926
|
-
radius) and the steps under them (20 high, half of it), bled out so their text sits on the
|
|
19927
|
-
rail's edge
|
|
19928
|
-
|
|
20157
|
+
/* The contents: every row on one text edge and in one colour, title rows (28 high, the control
|
|
20158
|
+
radius) and the steps under them (20 high, half of it), bled 6 px out so their text sits on the
|
|
20159
|
+
rail's edge and the first title's words on the column's top line; a narrow fade where a title
|
|
20160
|
+
runs out of room; the selection pill slides to the current step, and base rows never brighten. */
|
|
20161
|
+
.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}
|
|
19929
20162
|
.knobs-wt-toc::-webkit-scrollbar{display:none}
|
|
19930
20163
|
.knobs-wt-toc-group{display:flex;flex-direction:column;min-width:0}
|
|
19931
|
-
.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:
|
|
19932
|
-
padding:0
|
|
19933
|
-
transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
20164
|
+
.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;
|
|
20165
|
+
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;
|
|
20166
|
+
transition:color calc(var(--_k-hover-out) * 1ms),background calc(var(--_k-hover-out) * 1ms)}
|
|
19934
20167
|
.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)}
|
|
19935
|
-
.knobs-ui .knobs-wt-toc-row:is(:hover,:focus-visible){color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
20168
|
+
.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)}
|
|
19936
20169
|
.knobs-ui .knobs-wt-toc-row:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
19937
20170
|
.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)}
|
|
19938
20171
|
.knobs-wt-toc-label{min-width:0;overflow:hidden;${fade2}}
|
|
@@ -19944,7 +20177,7 @@ var walkthroughCss = `
|
|
|
19944
20177
|
.knobs-wt-toc-glyph[data-done]{background:var(--kw-tone)}
|
|
19945
20178
|
.knobs-wt-toc-glyph[data-tone="none"]{box-shadow:inset 0 0 0 1px var(--_k-border)}
|
|
19946
20179
|
.knobs-wt-actions{display:flex;flex-wrap:wrap;gap:4px}
|
|
19947
|
-
.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:
|
|
20180
|
+
.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;
|
|
19948
20181
|
transition:background .15s,color .15s}
|
|
19949
20182
|
.knobs-ui .knobs-wt-btn:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
19950
20183
|
.knobs-ui .knobs-wt-btn[data-primary]{background:var(--_k-fill-selected);color:var(--_k-fg)}
|
|
@@ -19978,11 +20211,10 @@ var walkthroughCss = `
|
|
|
19978
20211
|
/* One frame for every slot that has one (a picture, a video, a code block, a compare's stage, a
|
|
19979
20212
|
slot still loading): the panel radius and a quiet fill, no ring; concentric on a card. */
|
|
19980
20213
|
.knobs-wt-slot .knobs-cmp-stage{border-radius:var(--kw-frame-r)}
|
|
19981
|
-
/* A compare is
|
|
19982
|
-
|
|
20214
|
+
/* A compare is as tall as its two pictures side by side at this width, in every mode (Wipe fuses
|
|
20215
|
+
them at one side's size, so nothing grows or re-measures), plus its mode bar, the line and gaps
|
|
19983
20216
|
(92 px), and the frame strip with its gap (158 px). */
|
|
19984
20217
|
.knobs-wt-fit{width:100%;height:calc(100cqw / 2 / var(--kw-aspect,1.7778) + var(--kw-chrome,92px))}
|
|
19985
|
-
.knobs-wt-fit[data-overlay]{height:calc(100cqw / var(--kw-aspect,1.7778) + var(--kw-chrome,92px))}
|
|
19986
20218
|
.knobs-wt-fit[data-strip]{--kw-chrome:158px}
|
|
19987
20219
|
.knobs-wt-fit[data-settled]{transition:height var(--k-wt-calm-ms,${calm.duration}ms) ${calm.easing}}
|
|
19988
20220
|
.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)}
|
|
@@ -19991,8 +20223,12 @@ var walkthroughCss = `
|
|
|
19991
20223
|
.knobs-wt-frame[data-natural]>img{position:static;height:auto}
|
|
19992
20224
|
/* Diff, code and terminal: one plain container (no glass): a flat inset fill, a hairline ring, the
|
|
19993
20225
|
control radius and room inside, so a diff's buttons and the code under them can breathe. */
|
|
19994
|
-
.knobs-wt-slot[data-kind="diff"]>.knobs-wt-body{padding:var(--_k-
|
|
19995
|
-
|
|
20226
|
+
.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)}
|
|
20227
|
+
/* The diff inside it: its header row 28 high on the container's padding, a hairline under it, and
|
|
20228
|
+
no line of its own under the code (the container's ring closes it). */
|
|
20229
|
+
.knobs-wt-slot[data-kind="diff"] .knobs-ui.knobs-diff:not([data-on="pane"]){--kd-head:28px;--kd-x:0px}
|
|
20230
|
+
.knobs-wt-slot[data-kind="diff"] .knobs-ui.knobs-diff:not([data-on="pane"])::after{display:none}
|
|
20231
|
+
.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);
|
|
19996
20232
|
font:var(--_k-type-label)/var(--_k-leading-body) var(--_k-mono);white-space:pre;tab-size:2;scrollbar-width:thin}
|
|
19997
20233
|
.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)}
|
|
19998
20234
|
.knobs-wt-code[data-terminal]{white-space:pre-wrap;overflow-wrap:anywhere}
|
|
@@ -20038,7 +20274,7 @@ var walkthroughCss = `
|
|
|
20038
20274
|
.knobs-wt-mark:is([data-shape="dot"],[data-shape="arrow"]) .knobs-wt-mark-label{left:12px;bottom:auto;top:10px}
|
|
20039
20275
|
.knobs-wt-mark[data-shape="arrow"] .knobs-wt-mark-label{left:auto;right:30px;top:auto;bottom:30px}
|
|
20040
20276
|
.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;
|
|
20041
|
-
border-radius:var(--_k-radius);background:color-mix(in srgb,var(--_k-bg) 72%,transparent);color:var(--_k-fg-2);cursor:
|
|
20277
|
+
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;
|
|
20042
20278
|
transition:opacity calc(var(--_k-hover-out) * 1ms),color calc(var(--_k-hover-out) * 1ms)}
|
|
20043
20279
|
.knobs-ui .knobs-wt-anno-toggle:is(:hover,:focus-visible){opacity:1;color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
20044
20280
|
.knobs-ui .knobs-wt-anno-toggle:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
@@ -20059,7 +20295,7 @@ var walkthroughCss = `
|
|
|
20059
20295
|
.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);
|
|
20060
20296
|
border-radius:max(0px,calc(var(--_k-radius-panel) - 8px));transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
20061
20297
|
.knobs-wt-srow[data-trunk]{--kw-spb:0px;grid-template-columns:auto minmax(0,1fr)}
|
|
20062
|
-
.knobs-wt-srow[data-go]{cursor:
|
|
20298
|
+
.knobs-wt-srow[data-go]{cursor:default}
|
|
20063
20299
|
.knobs-wt-srow[data-go]:hover{background:var(--_ku-wash);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
20064
20300
|
.knobs-wt-lanes{display:flex;align-self:stretch;margin-block:calc(var(--kw-spt) * -1) calc(var(--kw-spb) * -1)}
|
|
20065
20301
|
.knobs-wt-lane{position:relative;flex:none;width:16px}
|
|
@@ -20075,7 +20311,7 @@ var walkthroughCss = `
|
|
|
20075
20311
|
.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}
|
|
20076
20312
|
.knobs-ui a.knobs-wt-spr:is(:hover,:focus-visible){color:var(--_k-fg);text-decoration:underline}
|
|
20077
20313
|
.knobs-ui .knobs-wt-stitle{font-weight:var(--_k-weight-label);line-height:var(--kw-line);color:var(--_k-fg);text-align:left}
|
|
20078
|
-
.knobs-ui button.knobs-wt-stitle{cursor:
|
|
20314
|
+
.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)}
|
|
20079
20315
|
.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)}
|
|
20080
20316
|
.knobs-ui .knobs-wt-ssummary{margin:0;max-width:var(--k-walkthrough-measure,68ch);color:var(--_k-fg-2)}
|
|
20081
20317
|
.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)}
|
|
@@ -20083,12 +20319,21 @@ var walkthroughCss = `
|
|
|
20083
20319
|
.knobs-wt-add{color:var(--_k-diff-add)}
|
|
20084
20320
|
.knobs-wt-del{color:var(--_k-diff-del)}
|
|
20085
20321
|
.knobs-wt-sstatus{margin-top:calc((var(--kw-line) - 20px) / 2)}
|
|
20322
|
+
/* A PR's state the GitHub way: its glyph and word, open and merged quietly tinted (as PR chips),
|
|
20323
|
+
draft and closed faint; no fill, no dot. A check after it where the checks pass, faint too. One
|
|
20324
|
+
width for every row, so the glyphs and words line up. */
|
|
20325
|
+
.knobs-ui .knobs-wt-prstate{--kw-pr:var(--_k-fg-3);display:inline-flex;align-items:center;gap:4px;min-width:calc(7ch + 32px);height:var(--kw-line);color:var(--kw-pr);
|
|
20326
|
+
font:var(--_k-weight) var(--_k-type-small)/var(--_k-leading-small) var(--_k-font);white-space:nowrap}
|
|
20327
|
+
.knobs-ui .knobs-wt-prstate[data-state="open"]{--kw-pr:color-mix(in oklch,var(--_k-ok) 60%,var(--_k-fg-2))}
|
|
20328
|
+
.knobs-ui .knobs-wt-prstate[data-state="merged"]{--kw-pr:color-mix(in oklch,var(--_k-series-5) 60%,var(--_k-fg-2))}
|
|
20329
|
+
.knobs-wt-prstate svg{flex:none}
|
|
20330
|
+
.knobs-ui .knobs-wt-prchecks{display:inline-flex;margin-left:2px;color:var(--_k-fg-3)}
|
|
20086
20331
|
.knobs-wt-stack[data-flat] .knobs-wt-srow{grid-template-columns:minmax(0,1fr) auto}
|
|
20087
20332
|
.knobs-wt-stack[data-flat] .knobs-wt-srow+.knobs-wt-srow{box-shadow:inset 0 1px 0 var(--_k-border)}
|
|
20088
20333
|
@container knobs-wt-slot (max-width:520px){
|
|
20089
20334
|
.knobs-wt-srow:not([data-trunk]){grid-template-columns:auto minmax(0,1fr)}
|
|
20090
20335
|
.knobs-wt-stack[data-flat] .knobs-wt-srow{grid-template-columns:minmax(0,1fr)}
|
|
20091
|
-
.knobs-wt-sstatus{grid-column:-2;justify-self:start;margin-top:4px}
|
|
20336
|
+
:is(.knobs-wt-sstatus,.knobs-wt-prstate){grid-column:-2;justify-self:start;margin-top:4px}
|
|
20092
20337
|
}
|
|
20093
20338
|
|
|
20094
20339
|
/* A table: a real one, its head stuck while it scrolls, both ways; edges fade where there's more
|
|
@@ -20098,7 +20343,7 @@ var walkthroughCss = `
|
|
|
20098
20343
|
.knobs-wt-tablebox{min-width:0}
|
|
20099
20344
|
/* A row with a step goes there: the whole row, a wash under the pointer, no arrow, so rows with and
|
|
20100
20345
|
without one line up. */
|
|
20101
|
-
.knobs-wt-tablebox [data-go]{cursor:
|
|
20346
|
+
.knobs-wt-tablebox [data-go]{cursor:default;outline:none}
|
|
20102
20347
|
.knobs-wt-tablebox tr[data-go]>td,.knobs-wt-trow[data-go]{transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
20103
20348
|
.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)}
|
|
20104
20349
|
.knobs-wt-tablebox [data-go]:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
@@ -20154,13 +20399,18 @@ var walkthroughCss = `
|
|
|
20154
20399
|
.knobs-wt-body:has(>.knobs-wt-chapters){display:flex;flex-direction:column;gap:var(--_k-space-title)}
|
|
20155
20400
|
.knobs-wt-chapters{position:relative;display:flex;flex-direction:column;margin:0 calc(var(--_k-space-sibling) * -1)}
|
|
20156
20401
|
.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);
|
|
20157
|
-
border-radius:var(--_k-radius);color:var(--_k-fg-2);text-align:left;white-space:nowrap;cursor:
|
|
20158
|
-
.knobs-ui .knobs-wt-chapter:is(:hover,:focus-visible){color:var(--_k-fg);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
20402
|
+
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)}
|
|
20403
|
+
.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)}
|
|
20159
20404
|
.knobs-ui .knobs-wt-chapter:focus-visible{box-shadow:inset 0 0 0 1px var(--_k-focus)}
|
|
20160
20405
|
.knobs-wt-chapter-n{font-size:var(--_k-type-small);color:var(--_k-fg-3)}
|
|
20161
20406
|
.knobs-wt-chapter-label{min-width:0;overflow:hidden;${fade2}}
|
|
20162
20407
|
.knobs-wt-chapter-time{font:var(--_k-weight) var(--_k-type-small)/1 var(--_k-mono);color:var(--_k-fg-3)}
|
|
20163
20408
|
.knobs-pick-copy :is(.knobs-wt-chapter-n,.knobs-wt-chapter-time){color:var(--_k-fg-2)}
|
|
20409
|
+
/* Every hover in the walkthrough lands at once (hover-in, 0 ms) and eases out (hover-out): links,
|
|
20410
|
+
buttons, chips, rail, chapter, table and stack rows (its own; the pieces inside keep theirs). */
|
|
20411
|
+
:is(.knobs-walkthrough,.knobs-wt-slot) :is(a,button,[data-go])[class*="knobs-wt-"]:is(:hover,:focus-visible),
|
|
20412
|
+
.knobs-walkthrough a:not([class]):hover,
|
|
20413
|
+
: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)}
|
|
20164
20414
|
@media(prefers-reduced-motion:reduce){:is(.knobs-walkthrough,.knobs-wt-slot) :where(*,::before,::after){transition-duration:.15s!important;transition-property:opacity,background,color!important}}
|
|
20165
20415
|
@media(prefers-reduced-motion:reduce){.knobs-wt-disc-content{transition:opacity .15s}}
|
|
20166
20416
|
`;
|
|
@@ -20261,7 +20511,6 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
20261
20511
|
fit.style.setProperty("--kw-aspect", String(known ?? DEFAULT_ASPECT));
|
|
20262
20512
|
const width = host.getBoundingClientRect().width;
|
|
20263
20513
|
const mode = m.mode ?? (width && width < 560 ? "wipe" : "side");
|
|
20264
|
-
fit.toggleAttribute("data-overlay", mode !== "side");
|
|
20265
20514
|
host.append(fit);
|
|
20266
20515
|
const [aspect, lib] = await Promise.all([
|
|
20267
20516
|
known ? Promise.resolve(known) : probeAspect(doc, after.src),
|
|
@@ -20285,7 +20534,6 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
20285
20534
|
...aspect ? { aspect } : {},
|
|
20286
20535
|
...m.strip ? { strip: true } : {},
|
|
20287
20536
|
onMode: (next) => {
|
|
20288
|
-
fit.toggleAttribute("data-overlay", next !== "side");
|
|
20289
20537
|
onEvent?.({ what: "mode", detail: next });
|
|
20290
20538
|
const layer = marks?.element;
|
|
20291
20539
|
if (layer) {
|
|
@@ -20309,6 +20557,12 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
20309
20557
|
}
|
|
20310
20558
|
});
|
|
20311
20559
|
const stage = fit.querySelector(".knobs-cmp-stage");
|
|
20560
|
+
if (stage)
|
|
20561
|
+
doc.defaultView?.requestAnimationFrame(() => {
|
|
20562
|
+
const chrome = fit.clientHeight - stage.clientHeight;
|
|
20563
|
+
if (alive() && stage.clientHeight > 0 && chrome > 0)
|
|
20564
|
+
fit.style.setProperty("--kw-chrome", `${Math.round(chrome)}px`);
|
|
20565
|
+
});
|
|
20312
20566
|
if (m.annotations?.length && stage) {
|
|
20313
20567
|
const shape = { w: aspect ?? DEFAULT_ASPECT, h: 1 };
|
|
20314
20568
|
marks = annotationLayer(stage, m.annotations, () => {
|
|
@@ -20384,45 +20638,38 @@ async function mountCompare(host, m, look, alive, onEvent) {
|
|
|
20384
20638
|
var round2 = (v) => Math.round(v * 100) / 100;
|
|
20385
20639
|
var MARK_GLIDE = 450;
|
|
20386
20640
|
var zoomedIn = (z) => z.w < 0.999 || z.h < 0.999;
|
|
20387
|
-
function mountVideo(host, m, onEvent) {
|
|
20641
|
+
async function mountVideo(host, m, look, alive, onEvent) {
|
|
20388
20642
|
const doc = host.ownerDocument;
|
|
20389
|
-
|
|
20643
|
+
await Promise.resolve().then(() => init_player());
|
|
20644
|
+
if (!alive())
|
|
20645
|
+
return { dispose() {} };
|
|
20390
20646
|
const aspect = parseAspect(m.aspect);
|
|
20391
|
-
|
|
20392
|
-
|
|
20393
|
-
const
|
|
20394
|
-
|
|
20395
|
-
|
|
20396
|
-
|
|
20397
|
-
|
|
20398
|
-
|
|
20399
|
-
|
|
20400
|
-
|
|
20401
|
-
|
|
20402
|
-
|
|
20403
|
-
|
|
20404
|
-
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20408
|
-
|
|
20409
|
-
|
|
20410
|
-
v.append(track);
|
|
20411
|
-
}
|
|
20412
|
-
v.src = m.src;
|
|
20413
|
-
v.addEventListener("play", () => onEvent?.({ what: "play", time: round2(v.currentTime) }));
|
|
20414
|
-
v.addEventListener("pause", () => onEvent?.({ what: "pause", time: round2(v.currentTime) }));
|
|
20415
|
-
v.addEventListener("seeked", () => {
|
|
20416
|
-
if (v.paused)
|
|
20417
|
-
onEvent?.({ what: "seek", time: round2(v.currentTime) });
|
|
20647
|
+
let pills = null;
|
|
20648
|
+
let marking = null;
|
|
20649
|
+
const p = player(host, {
|
|
20650
|
+
...look,
|
|
20651
|
+
src: m.src,
|
|
20652
|
+
...m.poster ? { poster: m.poster } : {},
|
|
20653
|
+
...m.captions ? { captions: m.captions } : {},
|
|
20654
|
+
...aspect ? { aspect } : {},
|
|
20655
|
+
...m.label ? { label: m.label } : {},
|
|
20656
|
+
...m.chapters?.length ? { chapters: m.chapters.map((c) => ({ label: c.label, start: c.start, ...c.id ? { id: c.id } : {} })) } : {},
|
|
20657
|
+
onPlay: (on, time) => {
|
|
20658
|
+
marking?.kick();
|
|
20659
|
+
onEvent?.({ what: on ? "play" : "pause", time: round2(time) });
|
|
20660
|
+
},
|
|
20661
|
+
onSeek: (time) => {
|
|
20662
|
+
pills?.sync();
|
|
20663
|
+
marking?.kick();
|
|
20664
|
+
onEvent?.({ what: "seek", time: round2(time) });
|
|
20665
|
+
}
|
|
20418
20666
|
});
|
|
20419
|
-
|
|
20420
|
-
host.
|
|
20421
|
-
|
|
20422
|
-
now: () => v.currentTime,
|
|
20667
|
+
const v = p.video;
|
|
20668
|
+
pills = m.chapters?.length ? chapterPills(host, m.chapters, {
|
|
20669
|
+
now: () => p.time,
|
|
20423
20670
|
seek: (t) => {
|
|
20424
|
-
|
|
20425
|
-
|
|
20671
|
+
p.seek(t, { glide: true });
|
|
20672
|
+
p.play();
|
|
20426
20673
|
},
|
|
20427
20674
|
onEvent
|
|
20428
20675
|
}) : null;
|
|
@@ -20430,36 +20677,33 @@ function mountVideo(host, m, onEvent) {
|
|
|
20430
20677
|
if (pills)
|
|
20431
20678
|
for (const type of ["timeupdate", "seeking", "seeked"])
|
|
20432
20679
|
v.addEventListener(type, sync);
|
|
20680
|
+
const frame = p.element.querySelector(".knobs-player-frame") ?? p.element;
|
|
20433
20681
|
const marks = m.annotations?.length ? annotationLayer(frame, m.annotations, () => ({
|
|
20434
20682
|
rects: [
|
|
20435
20683
|
contain({ w: frame.clientWidth, h: frame.clientHeight }, { w: v.videoWidth, h: v.videoHeight })
|
|
20436
20684
|
],
|
|
20437
|
-
time:
|
|
20685
|
+
time: p.time
|
|
20438
20686
|
})) : null;
|
|
20439
|
-
|
|
20440
|
-
|
|
20441
|
-
for (const type of ["
|
|
20442
|
-
v.addEventListener(type, () => marking
|
|
20687
|
+
if (marks) {
|
|
20688
|
+
marking = follow(doc.defaultView, () => p.playing, () => marks.update());
|
|
20689
|
+
for (const type of ["seeked", "loadedmetadata", "timeupdate"])
|
|
20690
|
+
v.addEventListener(type, () => marking?.kick());
|
|
20691
|
+
}
|
|
20443
20692
|
return {
|
|
20444
|
-
pause: () =>
|
|
20445
|
-
seekBy: (d) =>
|
|
20446
|
-
v.currentTime = Math.max(0, Math.min(v.duration || Infinity, v.currentTime + d));
|
|
20447
|
-
},
|
|
20693
|
+
pause: () => p.pause(),
|
|
20694
|
+
seekBy: (d) => p.seekBy(d),
|
|
20448
20695
|
context: () => ({
|
|
20449
20696
|
kind: "video",
|
|
20450
|
-
time: round2(
|
|
20451
|
-
...
|
|
20452
|
-
playing:
|
|
20697
|
+
time: round2(p.time),
|
|
20698
|
+
...p.duration ? { duration: round2(p.duration) } : {},
|
|
20699
|
+
playing: p.playing,
|
|
20453
20700
|
...pills?.current ? { chapter: pills.current.label } : {}
|
|
20454
20701
|
}),
|
|
20455
20702
|
dispose: () => {
|
|
20456
20703
|
marking?.stop();
|
|
20457
20704
|
marks?.dispose();
|
|
20458
20705
|
pills?.dispose();
|
|
20459
|
-
|
|
20460
|
-
v.removeAttribute("src");
|
|
20461
|
-
v.load();
|
|
20462
|
-
frame.remove();
|
|
20706
|
+
p.dispose();
|
|
20463
20707
|
}
|
|
20464
20708
|
};
|
|
20465
20709
|
}
|
|
@@ -20720,7 +20964,7 @@ function mediaSlot(container, options) {
|
|
|
20720
20964
|
case "diff":
|
|
20721
20965
|
return void mountDiff(host, m, look, alive, options.onEvent).then(done, fail("diff"));
|
|
20722
20966
|
case "video":
|
|
20723
|
-
return
|
|
20967
|
+
return void mountVideo(host, m, look, alive, options.onEvent).then(done, fail("video"));
|
|
20724
20968
|
case "image":
|
|
20725
20969
|
return done(mountImage(host, m));
|
|
20726
20970
|
case "code":
|
|
@@ -20734,7 +20978,7 @@ function mediaSlot(container, options) {
|
|
|
20734
20978
|
case "history":
|
|
20735
20979
|
return done(mountHistory(host, m, options.steps));
|
|
20736
20980
|
case "stack":
|
|
20737
|
-
return done(mountStack(host, m, options.steps));
|
|
20981
|
+
return done(mountStack(host, m, options.steps, options.findPR));
|
|
20738
20982
|
case "table":
|
|
20739
20983
|
return done(mountTable(host, m, options.steps));
|
|
20740
20984
|
case "mount": {
|
|
@@ -20788,7 +21032,7 @@ function mediaSlot(container, options) {
|
|
|
20788
21032
|
}
|
|
20789
21033
|
};
|
|
20790
21034
|
}
|
|
20791
|
-
var
|
|
21035
|
+
var CHECK4 = icon("check", { small: true });
|
|
20792
21036
|
|
|
20793
21037
|
// src/ui/walkthrough.ts
|
|
20794
21038
|
var el3 = (doc, tag, cls) => {
|
|
@@ -20875,7 +21119,7 @@ function tasteTest(container, options) {
|
|
|
20875
21119
|
pick.append(key);
|
|
20876
21120
|
}
|
|
20877
21121
|
const check = el3(doc, "span", "knobs-wt-check");
|
|
20878
|
-
check.innerHTML =
|
|
21122
|
+
check.innerHTML = CHECK4;
|
|
20879
21123
|
pick.append(check);
|
|
20880
21124
|
pick.addEventListener("click", () => {
|
|
20881
21125
|
const next = picked === o.id ? null : o.id;
|
|
@@ -21703,11 +21947,12 @@ function walkthrough(container, options) {
|
|
|
21703
21947
|
line.append(s);
|
|
21704
21948
|
return s;
|
|
21705
21949
|
};
|
|
21706
|
-
const findPRIn = (n) => findPR(page.prs, n, page.repo);
|
|
21950
|
+
const findPRIn = (n, kind = "pr") => findPR(page.prs, n, page.repo, kind);
|
|
21707
21951
|
const metaLink = (line, text, href) => {
|
|
21708
21952
|
const n = prNumber(href);
|
|
21709
|
-
|
|
21710
|
-
|
|
21953
|
+
const issue = n ? null : issueNumber(href);
|
|
21954
|
+
if (n || issue) {
|
|
21955
|
+
const chip = n ? prChip(doc, n, { ...findPRIn(n), href }) : prChip(doc, issue, { ...findPRIn(issue, "issue"), href });
|
|
21711
21956
|
line.append(chip);
|
|
21712
21957
|
return chip;
|
|
21713
21958
|
}
|
|
@@ -22036,7 +22281,7 @@ function walkthrough(container, options) {
|
|
|
22036
22281
|
media = el3(doc, "div", "knobs-wt-media");
|
|
22037
22282
|
media.style.setProperty("--kw-n", String(Math.min(step.media.length, step.columns)));
|
|
22038
22283
|
for (const m of step.media)
|
|
22039
|
-
slots.push(mediaSlot(media, { ...look, media: m, onEvent, steps: stepLinks }));
|
|
22284
|
+
slots.push(mediaSlot(media, { ...look, media: m, onEvent, steps: stepLinks, findPR: findPRIn }));
|
|
22040
22285
|
card.append(media);
|
|
22041
22286
|
}
|
|
22042
22287
|
let taste = null;
|