@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-react.js
CHANGED
|
@@ -576,13 +576,14 @@ var compareCss = `
|
|
|
576
576
|
picked: the pill's bright copy is. */
|
|
577
577
|
.knobs-cmp-modes{position:relative;display:inline-flex;height:var(--_k-control-h);border-radius:var(--_k-radius);background:var(--_k-fill)}
|
|
578
578
|
.knobs-cmp-modes[hidden]{display:none}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
579
|
+
/* Hover is a quiet fill under the arrow cursor (no hand, no brightening), there at once. */
|
|
580
|
+
.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;
|
|
581
|
+
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
582
|
+
.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)}
|
|
582
583
|
/* Toggles: icon buttons, the accent's wash when on. */
|
|
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-
|
|
584
|
-
transition:
|
|
585
|
-
.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){
|
|
584
|
+
.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;
|
|
585
|
+
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
586
|
+
.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
586
587
|
.knobs-ui .knobs-cmp-toggle[aria-pressed="true"]{color:var(--_k-accent-fg);background:var(--_k-accent-soft)}
|
|
587
588
|
.knobs-cmp-toggle svg{display:block}
|
|
588
589
|
.knobs-cmp-fill{flex:1}
|
|
@@ -596,11 +597,10 @@ var compareCss = `
|
|
|
596
597
|
.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}
|
|
597
598
|
.knobs-compare[data-frame="flat"] .knobs-cmp-stage{border-radius:0}
|
|
598
599
|
.knobs-compare[data-mode="wipe"] .knobs-cmp-stage{cursor:ew-resize}
|
|
599
|
-
/* Videos: a click on the stage plays and pauses. */
|
|
600
|
-
.knobs-compare[data-video]:not([data-mode="wipe"],[data-zoomed]) .knobs-cmp-stage{cursor:pointer}
|
|
601
600
|
/* Unzoomed, a finger still scrolls the page up and down; zoomed, the stage takes every gesture. */
|
|
602
|
-
.
|
|
603
|
-
.knobs-compare[data-
|
|
601
|
+
/* Zoomed, it pans: a move cursor, never a hand. */
|
|
602
|
+
.knobs-compare[data-zoomed] .knobs-cmp-stage{cursor:move;touch-action:none}
|
|
603
|
+
.knobs-compare[data-panning],.knobs-compare[data-panning] *{cursor:move!important}
|
|
604
604
|
/* Wiping, the grip stands in for the cursor. */
|
|
605
605
|
.knobs-compare[data-dragging],.knobs-compare[data-dragging] *{cursor:none!important}
|
|
606
606
|
.knobs-cmp-sizer{position:absolute;left:0;right:0;top:0;height:0;visibility:hidden;pointer-events:none}
|
|
@@ -647,8 +647,8 @@ var compareCss = `
|
|
|
647
647
|
opacity:0;scale:.96;pointer-events:none;transition:opacity .16s cubic-bezier(.4,0,1,1),scale .16s cubic-bezier(.4,0,1,1)}
|
|
648
648
|
.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)}
|
|
649
649
|
: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;
|
|
650
|
-
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:
|
|
651
|
-
:where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){
|
|
650
|
+
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)}
|
|
651
|
+
:where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
652
652
|
.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}
|
|
653
653
|
.knobs-cmp-note:empty{display:none}
|
|
654
654
|
.knobs-cmp-strip-host{flex:none;height:60px;min-height:0}
|
|
@@ -666,23 +666,29 @@ var playerCss = `
|
|
|
666
666
|
.knobs-ui.knobs-player{--_kp-stage:var(--_k-compare-stage);display:flex;flex-direction:column;gap:6px;width:100%;outline:none;
|
|
667
667
|
font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
|
|
668
668
|
: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)}
|
|
669
|
-
.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
|
+
.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)}
|
|
670
670
|
.knobs-player[data-frame="flat"] .knobs-player-frame{border-radius:0}
|
|
671
671
|
.knobs-player-media{position:absolute;inset:0;display:block;width:100%;height:100%;margin:0;padding:0;border:0;object-fit:contain;
|
|
672
672
|
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)}
|
|
673
673
|
.knobs-player[data-ready] .knobs-player-media{opacity:1;filter:none}
|
|
674
|
-
.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;
|
|
675
|
-
opacity:0;filter:blur(4px);scale:.96;
|
|
676
|
-
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);
|
|
677
|
-
box-shadow:inset 0 0 0 .5px var(--_k-border),inset 0 1px 0 var(--_k-rim);
|
|
678
|
-
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)}
|
|
679
|
-
.knobs-player-glyph svg{width:16px;height:16px}
|
|
680
|
-
.knobs-player-glyph[data-flash]{opacity:1;filter:none;scale:1}
|
|
681
674
|
.knobs-player-line{flex:none;min-height:0}
|
|
682
|
-
/*
|
|
683
|
-
|
|
675
|
+
/* The timeline's own stylesheet is look.ts's; what the player's row and every timeline share
|
|
676
|
+
about the hand is set here, after it. No hand cursor anywhere (the arrow, or a resize where it
|
|
677
|
+
resizes); hover is a quiet fill (fill-hover), in at once (hover-in, 0 ms), out easing. */
|
|
678
|
+
.knobs-ui .knobs-tl-play,.knobs-ui.knobs-timeline :is(.knobs-tl-pin,.knobs-tl-rlabel),
|
|
679
|
+
.knobs-ui.knobs-timeline[data-dragging] .knobs-tl-marker :is(.knobs-tl-pin,.knobs-tl-mlabel){cursor:default}
|
|
684
680
|
.knobs-ui .knobs-tl-play:hover,.knobs-tl-edge:hover::after,.knobs-tl-rlabel:hover,.knobs-tl-track:hover .knobs-tl-hover,
|
|
685
681
|
.knobs-timeline[data-variant="line"] .knobs-tl-track:hover .knobs-tl-segs{transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
682
|
+
/* The line's row: a minimal play/pause (the filled pair, a 28px target, no fill at rest), then
|
|
683
|
+
the line, centred on it. */
|
|
684
|
+
.knobs-ui.knobs-timeline[data-variant="line"]{gap:4px;align-items:center}
|
|
685
|
+
.knobs-timeline[data-variant="line"] .knobs-tl-transport{display:flex}
|
|
686
|
+
.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);
|
|
687
|
+
transition:background calc(var(--_k-hover-out) * 1ms),transform .15s var(--_ku-ease)}
|
|
688
|
+
.knobs-ui.knobs-timeline[data-variant="line"][data-playing] .knobs-tl-play{background:transparent;color:var(--_k-fg-2)}
|
|
689
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-play:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
690
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-track{cursor:default;transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
691
|
+
.knobs-ui.knobs-timeline[data-variant="line"] .knobs-tl-track:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
686
692
|
`;
|
|
687
693
|
|
|
688
694
|
// src/ui/overlay-css.ts
|
|
@@ -3234,16 +3240,17 @@ var init_diff_css = __esm(() => {
|
|
|
3234
3240
|
.knobs-diff-nav>span{min-width:3.6em;text-align:center}
|
|
3235
3241
|
: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;
|
|
3236
3242
|
margin:0;padding:0;min-width:0;box-shadow:none;outline:none}
|
|
3237
|
-
.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-
|
|
3238
|
-
transition:background
|
|
3239
|
-
|
|
3243
|
+
.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;
|
|
3244
|
+
transition:background calc(var(--_k-hover-out) * 1ms),opacity .15s}
|
|
3245
|
+
/* Hover is a quiet fill under the arrow cursor (no hand, no brightening), there at once. */
|
|
3246
|
+
.knobs-ui .knobs-diff-btn:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
3240
3247
|
.knobs-ui .knobs-diff-btn[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
|
|
3241
3248
|
.knobs-ui .knobs-diff-btn:disabled{opacity:.35;cursor:default;background:transparent}
|
|
3242
3249
|
.knobs-diff-btn svg{width:16px;height:16px}
|
|
3243
3250
|
/* Viewed: a check with its word, as on GitHub; the path dims once it's ticked. */
|
|
3244
3251
|
.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);
|
|
3245
|
-
font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);white-space:nowrap;cursor:
|
|
3246
|
-
.knobs-ui .knobs-diff-viewed:is(:hover,:focus-visible){background:var(--
|
|
3252
|
+
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}
|
|
3253
|
+
.knobs-ui .knobs-diff-viewed:is(:hover,:focus-visible){background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
3247
3254
|
.knobs-ui .knobs-diff-viewed[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
|
|
3248
3255
|
.knobs-diff-viewed svg{width:16px;height:16px}
|
|
3249
3256
|
.knobs-diff-viewed[aria-pressed="true"] svg{color:var(--kd-add)}
|
|
@@ -3262,8 +3269,8 @@ var init_diff_css = __esm(() => {
|
|
|
3262
3269
|
choice isn't brighter for being picked. Choices are styled by class, as the copy holds them too. */
|
|
3263
3270
|
.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)}
|
|
3264
3271
|
.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);
|
|
3265
|
-
font-weight:var(--_k-weight-label);white-space:nowrap;cursor:
|
|
3266
|
-
.knobs-ui .knobs-diff-choice:is(:hover,:focus-visible){
|
|
3272
|
+
font-weight:var(--_k-weight-label);white-space:nowrap;cursor:default;transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
3273
|
+
.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)}
|
|
3267
3274
|
/* The diff: one layer per file or layout on show, the old fading under the new. */
|
|
3268
3275
|
.knobs-diff-body{position:relative;flex:1;min-height:0}
|
|
3269
3276
|
.knobs-diff-probe{position:absolute;left:0;top:0;width:0;height:var(--kd-line);visibility:hidden;pointer-events:none}
|
|
@@ -3359,8 +3366,8 @@ var init_diff_css = __esm(() => {
|
|
|
3359
3366
|
.knobs-diff-filter svg{width:12px;height:12px;flex:none}
|
|
3360
3367
|
.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}
|
|
3361
3368
|
.knobs-ui .knobs-diff-filter>input::placeholder{color:var(--_k-fg-3)}
|
|
3362
|
-
.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:
|
|
3363
|
-
.knobs-ui .knobs-diff-filter>button:hover{background:var(--
|
|
3369
|
+
.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}
|
|
3370
|
+
.knobs-ui .knobs-diff-filter>button:hover{background:var(--_k-fill-hover);transition-duration:calc(var(--_k-hover-in) * 1ms)}
|
|
3364
3371
|
.knobs-diff-filter>button svg{width:12px;height:12px}
|
|
3365
3372
|
.knobs-diff-list{position:relative;flex:1;min-height:0}
|
|
3366
3373
|
.knobs-diff-files .knobs-diff-counts{font-size:var(--_k-text-meta);align-items:center}
|
|
@@ -11216,29 +11223,6 @@ var init_compare_strip = __esm(() => {
|
|
|
11216
11223
|
DIFF = { w: 32, h: 18 };
|
|
11217
11224
|
});
|
|
11218
11225
|
|
|
11219
|
-
// src/ui/player.ts
|
|
11220
|
-
function playGlyph(doc) {
|
|
11221
|
-
const element = doc.createElement("span");
|
|
11222
|
-
element.className = "knobs-player-glyph";
|
|
11223
|
-
element.setAttribute("aria-hidden", "true");
|
|
11224
|
-
let timer = 0;
|
|
11225
|
-
const win = doc.defaultView;
|
|
11226
|
-
return {
|
|
11227
|
-
element,
|
|
11228
|
-
flash(playing) {
|
|
11229
|
-
element.innerHTML = playing ? PLAY2 : PAUSE;
|
|
11230
|
-
element.setAttribute("data-flash", "");
|
|
11231
|
-
win.clearTimeout(timer);
|
|
11232
|
-
timer = win.setTimeout(() => element.removeAttribute("data-flash"), FLASH_MS);
|
|
11233
|
-
},
|
|
11234
|
-
dispose: () => win.clearTimeout(timer)
|
|
11235
|
-
};
|
|
11236
|
-
}
|
|
11237
|
-
var FLASH_MS = 450;
|
|
11238
|
-
var init_player = __esm(() => {
|
|
11239
|
-
init_timeline();
|
|
11240
|
-
});
|
|
11241
|
-
|
|
11242
11226
|
// src/ui/compare.ts
|
|
11243
11227
|
function compare(container, options) {
|
|
11244
11228
|
const doc = container.ownerDocument;
|
|
@@ -11357,8 +11341,7 @@ function compare(container, options) {
|
|
|
11357
11341
|
grip.setAttribute("aria-hidden", "true");
|
|
11358
11342
|
handle.append(grip);
|
|
11359
11343
|
const note = el("div", "knobs-cmp-note");
|
|
11360
|
-
|
|
11361
|
-
stage.append(canvas, split, seam, labels[0], labels[1], handle, zoomPill, note, glyph.element);
|
|
11344
|
+
stage.append(canvas, split, seam, labels[0], labels[1], handle, zoomPill, note);
|
|
11362
11345
|
root.append(bar, stage);
|
|
11363
11346
|
const wantsStrip = options.strip === true;
|
|
11364
11347
|
let tl = bound;
|
|
@@ -11400,7 +11383,6 @@ function compare(container, options) {
|
|
|
11400
11383
|
let drag = null;
|
|
11401
11384
|
const touches = new Map;
|
|
11402
11385
|
let pinch = null;
|
|
11403
|
-
let press = null;
|
|
11404
11386
|
const zu = new Spring(0, ZOOM.omega, ZOOM.zeta, 0.00001);
|
|
11405
11387
|
const zv = new Spring(0, ZOOM.omega, ZOOM.zeta, 0.00001);
|
|
11406
11388
|
const zw = new Spring(1, ZOOM.omega, ZOOM.zeta, 0.00001);
|
|
@@ -12229,10 +12211,8 @@ function compare(container, options) {
|
|
|
12229
12211
|
root.focus({ preventScroll: true });
|
|
12230
12212
|
touches.set(e.pointerId, p);
|
|
12231
12213
|
stage.setPointerCapture(e.pointerId);
|
|
12232
|
-
press = touches.size === 1 && mode !== "wipe" && master() ? p : null;
|
|
12233
12214
|
if (touches.size >= 2) {
|
|
12234
12215
|
e.preventDefault();
|
|
12235
|
-
press = null;
|
|
12236
12216
|
return startPinch();
|
|
12237
12217
|
}
|
|
12238
12218
|
if (mode === "wipe") {
|
|
@@ -12260,8 +12240,6 @@ function compare(container, options) {
|
|
|
12260
12240
|
const onMove = (e) => {
|
|
12261
12241
|
const p = local(e);
|
|
12262
12242
|
pointer = p;
|
|
12263
|
-
if (press && Math.hypot(p.x - press.x, p.y - press.y) > 4)
|
|
12264
|
-
press = null;
|
|
12265
12243
|
if (touches.has(e.pointerId))
|
|
12266
12244
|
touches.set(e.pointerId, p);
|
|
12267
12245
|
if (pinch && touches.size >= 2) {
|
|
@@ -12291,11 +12269,6 @@ function compare(container, options) {
|
|
|
12291
12269
|
drawNow();
|
|
12292
12270
|
};
|
|
12293
12271
|
const endDrag = (e) => {
|
|
12294
|
-
if (press && e.type === "pointerup") {
|
|
12295
|
-
api.toggle();
|
|
12296
|
-
glyph.flash(isPlaying());
|
|
12297
|
-
}
|
|
12298
|
-
press = null;
|
|
12299
12272
|
touches.delete(e.pointerId);
|
|
12300
12273
|
if (touches.size < 2)
|
|
12301
12274
|
pinch = null;
|
|
@@ -12457,7 +12430,6 @@ function compare(container, options) {
|
|
|
12457
12430
|
old.el.replaceWith(s.el);
|
|
12458
12431
|
old.preview.replaceWith(s.preview);
|
|
12459
12432
|
sides[index] = s;
|
|
12460
|
-
root.toggleAttribute("data-video", sides.some((x) => x.kind === "video"));
|
|
12461
12433
|
note.textContent = "";
|
|
12462
12434
|
setLabel(index, labelOf(index));
|
|
12463
12435
|
if (near)
|
|
@@ -12472,7 +12444,6 @@ function compare(container, options) {
|
|
|
12472
12444
|
stage.insertBefore(sides[0].preview, labels[0]);
|
|
12473
12445
|
setLabel(0, labelOf(0));
|
|
12474
12446
|
setLabel(1, labelOf(1));
|
|
12475
|
-
root.toggleAttribute("data-video", sides.some((s) => s.kind === "video"));
|
|
12476
12447
|
loupeBtn.setAttribute("aria-pressed", String(loupeOn));
|
|
12477
12448
|
loopBtn.setAttribute("aria-pressed", String(loopNow() !== null));
|
|
12478
12449
|
const modePill = modeList.length > 1 ? selectionPill(modes, {
|
|
@@ -12673,7 +12644,6 @@ function compare(container, options) {
|
|
|
12673
12644
|
disposed = true;
|
|
12674
12645
|
loop.stop();
|
|
12675
12646
|
modePill?.dispose();
|
|
12676
|
-
glyph.dispose();
|
|
12677
12647
|
win.clearTimeout(releaseTimer);
|
|
12678
12648
|
ro.disconnect();
|
|
12679
12649
|
nearIo?.disconnect();
|
|
@@ -12714,7 +12684,6 @@ var init_compare = __esm(() => {
|
|
|
12714
12684
|
init_icons();
|
|
12715
12685
|
init_look();
|
|
12716
12686
|
init_rgba();
|
|
12717
|
-
init_player();
|
|
12718
12687
|
init_selection_pill();
|
|
12719
12688
|
init_timeline();
|
|
12720
12689
|
init_timeline_model();
|
|
@@ -12733,6 +12702,171 @@ var init_compare = __esm(() => {
|
|
|
12733
12702
|
};
|
|
12734
12703
|
});
|
|
12735
12704
|
|
|
12705
|
+
// src/ui/player.ts
|
|
12706
|
+
function player(container, options) {
|
|
12707
|
+
const doc = container.ownerDocument;
|
|
12708
|
+
const el = (tag, cls) => {
|
|
12709
|
+
const n = doc.createElement(tag);
|
|
12710
|
+
n.className = cls;
|
|
12711
|
+
return n;
|
|
12712
|
+
};
|
|
12713
|
+
const look = {
|
|
12714
|
+
...options.preset ? { preset: options.preset } : {},
|
|
12715
|
+
...options.theme ? { theme: options.theme } : {},
|
|
12716
|
+
...options.appearance ? { appearance: options.appearance } : {}
|
|
12717
|
+
};
|
|
12718
|
+
const root = el("div", "knobs-player");
|
|
12719
|
+
root.setAttribute("role", "group");
|
|
12720
|
+
root.setAttribute("aria-label", options.label ?? "Video");
|
|
12721
|
+
applyLook2(root, options);
|
|
12722
|
+
const frame = el("div", "knobs-player-frame");
|
|
12723
|
+
frame.style.setProperty("--kp-aspect", String(options.aspect ?? 16 / 9));
|
|
12724
|
+
const v = el("video", "knobs-player-media");
|
|
12725
|
+
v.muted = options.muted ?? true;
|
|
12726
|
+
v.defaultMuted = v.muted;
|
|
12727
|
+
v.playsInline = true;
|
|
12728
|
+
v.preload = "metadata";
|
|
12729
|
+
v.setAttribute("playsinline", "");
|
|
12730
|
+
if (options.poster)
|
|
12731
|
+
v.poster = options.poster;
|
|
12732
|
+
if (options.captions) {
|
|
12733
|
+
const track = doc.createElement("track");
|
|
12734
|
+
track.kind = "captions";
|
|
12735
|
+
track.label = "Captions";
|
|
12736
|
+
track.srclang = doc.documentElement.lang || "en";
|
|
12737
|
+
track.default = true;
|
|
12738
|
+
track.src = options.captions;
|
|
12739
|
+
v.append(track);
|
|
12740
|
+
}
|
|
12741
|
+
frame.append(v);
|
|
12742
|
+
const host = el("div", "knobs-player-line");
|
|
12743
|
+
root.append(frame, host);
|
|
12744
|
+
container.append(root);
|
|
12745
|
+
const markers = (options.chapters ?? []).map((c, i) => ({
|
|
12746
|
+
id: c.id ?? `c${i}`,
|
|
12747
|
+
time: c.start,
|
|
12748
|
+
label: c.label
|
|
12749
|
+
}));
|
|
12750
|
+
const tl = timeline(host, {
|
|
12751
|
+
...look,
|
|
12752
|
+
variant: "line",
|
|
12753
|
+
duration: 1,
|
|
12754
|
+
fps: options.fps ?? 30,
|
|
12755
|
+
markers,
|
|
12756
|
+
repeat: options.loop ?? true,
|
|
12757
|
+
arrows: { step: 5, shift: 10 },
|
|
12758
|
+
label: options.label ? `${options.label} time` : "Video time",
|
|
12759
|
+
...options.hints === false ? { hints: false } : {}
|
|
12760
|
+
});
|
|
12761
|
+
const onFrame = () => root.setAttribute("data-ready", "");
|
|
12762
|
+
let pending = null;
|
|
12763
|
+
const seekVideo = (t) => {
|
|
12764
|
+
if (v.readyState < 1)
|
|
12765
|
+
return;
|
|
12766
|
+
if (v.seeking)
|
|
12767
|
+
pending = t;
|
|
12768
|
+
else
|
|
12769
|
+
v.currentTime = t;
|
|
12770
|
+
};
|
|
12771
|
+
let reported = 0;
|
|
12772
|
+
const onSeeked = () => {
|
|
12773
|
+
if (pending !== null) {
|
|
12774
|
+
const t = pending;
|
|
12775
|
+
pending = null;
|
|
12776
|
+
v.currentTime = t;
|
|
12777
|
+
return;
|
|
12778
|
+
}
|
|
12779
|
+
if (!v.paused || tl.playing || Math.abs(v.currentTime - reported) < 0.1)
|
|
12780
|
+
return;
|
|
12781
|
+
reported = v.currentTime;
|
|
12782
|
+
options.onSeek?.(reported);
|
|
12783
|
+
};
|
|
12784
|
+
const onMeta = () => {
|
|
12785
|
+
onFrame();
|
|
12786
|
+
if (v.videoWidth)
|
|
12787
|
+
frame.style.setProperty("--kp-aspect", String(v.videoWidth / v.videoHeight));
|
|
12788
|
+
if (Number.isFinite(v.duration))
|
|
12789
|
+
tl.update({ duration: v.duration });
|
|
12790
|
+
};
|
|
12791
|
+
v.addEventListener("loadedmetadata", onMeta);
|
|
12792
|
+
v.addEventListener("loadeddata", onFrame);
|
|
12793
|
+
v.addEventListener("seeked", onSeeked);
|
|
12794
|
+
const unlisten = tl.listen({
|
|
12795
|
+
onSeek(t, source) {
|
|
12796
|
+
if (source === "play") {
|
|
12797
|
+
if (Math.abs(v.currentTime - t) > 0.25)
|
|
12798
|
+
v.currentTime = t;
|
|
12799
|
+
return;
|
|
12800
|
+
}
|
|
12801
|
+
if (Math.abs(v.currentTime - t) < 1 / (options.fps ?? 30))
|
|
12802
|
+
return;
|
|
12803
|
+
seekVideo(t);
|
|
12804
|
+
},
|
|
12805
|
+
onPlay(on) {
|
|
12806
|
+
if (on)
|
|
12807
|
+
v.play().catch(() => tl.pause());
|
|
12808
|
+
else {
|
|
12809
|
+
v.pause();
|
|
12810
|
+
reported = tl.time;
|
|
12811
|
+
}
|
|
12812
|
+
root.toggleAttribute("data-playing", on);
|
|
12813
|
+
options.onPlay?.(on, tl.time);
|
|
12814
|
+
},
|
|
12815
|
+
onScrub(on) {
|
|
12816
|
+
if (on)
|
|
12817
|
+
v.pause();
|
|
12818
|
+
}
|
|
12819
|
+
});
|
|
12820
|
+
tl.drive(() => {
|
|
12821
|
+
if (v.readyState < 1)
|
|
12822
|
+
return Number.NaN;
|
|
12823
|
+
if (v.seeking)
|
|
12824
|
+
return tl.time;
|
|
12825
|
+
return v.ended ? Number.POSITIVE_INFINITY : v.currentTime;
|
|
12826
|
+
});
|
|
12827
|
+
const onClick = () => tl.focus();
|
|
12828
|
+
frame.addEventListener("click", onClick);
|
|
12829
|
+
v.src = options.src;
|
|
12830
|
+
const api = {
|
|
12831
|
+
element: root,
|
|
12832
|
+
video: v,
|
|
12833
|
+
timeline: tl,
|
|
12834
|
+
get time() {
|
|
12835
|
+
return tl.time;
|
|
12836
|
+
},
|
|
12837
|
+
get playing() {
|
|
12838
|
+
return tl.playing;
|
|
12839
|
+
},
|
|
12840
|
+
get duration() {
|
|
12841
|
+
return Number.isFinite(v.duration) ? v.duration : 0;
|
|
12842
|
+
},
|
|
12843
|
+
play: () => tl.play(),
|
|
12844
|
+
pause: () => tl.pause(),
|
|
12845
|
+
toggle: () => tl.toggle(),
|
|
12846
|
+
seek: (t, o) => tl.seek(t, o?.glide ? { glide: true } : undefined),
|
|
12847
|
+
seekBy: (d) => tl.seek(Math.min(tl.duration, Math.max(0, tl.time + d)), { glide: true }),
|
|
12848
|
+
focus: () => tl.focus(),
|
|
12849
|
+
dispose() {
|
|
12850
|
+
unlisten();
|
|
12851
|
+
tl.drive(null);
|
|
12852
|
+
tl.dispose();
|
|
12853
|
+
v.pause();
|
|
12854
|
+
frame.removeEventListener("click", onClick);
|
|
12855
|
+
v.removeEventListener("loadedmetadata", onMeta);
|
|
12856
|
+
v.removeEventListener("loadeddata", onFrame);
|
|
12857
|
+
v.removeEventListener("seeked", onSeeked);
|
|
12858
|
+
v.removeAttribute("src");
|
|
12859
|
+
v.load();
|
|
12860
|
+
root.remove();
|
|
12861
|
+
}
|
|
12862
|
+
};
|
|
12863
|
+
return api;
|
|
12864
|
+
}
|
|
12865
|
+
var init_player = __esm(() => {
|
|
12866
|
+
init_look();
|
|
12867
|
+
init_timeline();
|
|
12868
|
+
});
|
|
12869
|
+
|
|
12736
12870
|
// src/ui/react.tsx
|
|
12737
12871
|
import {
|
|
12738
12872
|
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;
|