rikiki-deck 0.6.0 → 0.7.2
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/.claude/skills/rikiki-debug/SKILL.md +17 -7
- package/.claude/skills/rikiki-deck/SKILL.md +362 -77
- package/.claude/skills/rikiki-theme/SKILL.md +1 -1
- package/README.md +69 -50
- package/bin/lib/assemble.mjs +154 -0
- package/bin/lib/box-geometry.mjs +66 -0
- package/bin/lib/browser.mjs +302 -0
- package/bin/lib/check-api.d.ts +28 -0
- package/bin/lib/check-api.mjs +6 -0
- package/bin/lib/check-plugins.mjs +228 -0
- package/bin/lib/check.mjs +1347 -0
- package/bin/lib/cli-error.mjs +26 -0
- package/bin/lib/component-deps.mjs +69 -0
- package/bin/lib/diff.mjs +275 -0
- package/bin/lib/export-pdf.mjs +65 -0
- package/bin/lib/graph-hit.mjs +86 -0
- package/bin/lib/inline.mjs +137 -39
- package/bin/lib/narrative.mjs +77 -0
- package/bin/lib/prune-icons.mjs +104 -0
- package/bin/lib/render.mjs +195 -0
- package/bin/lib/scan-external.mjs +126 -0
- package/bin/lib/starter.mjs +27 -14
- package/bin/lib/visual.mjs +120 -0
- package/bin/rikiki.mjs +420 -35
- package/dist/annotation-marks.d.ts +60 -0
- package/dist/annotation-marks.js +1 -0
- package/dist/bar-segments.d.ts +28 -0
- package/dist/bar-segments.js +1 -0
- package/dist/browser-location.d.ts +3 -0
- package/dist/browser-location.js +1 -0
- package/dist/cards-syntax.d.ts +31 -0
- package/dist/cards-syntax.js +6 -0
- package/dist/{plugins/click-stages.d.ts → click-stages.d.ts} +1 -1
- package/dist/deck-agenda.d.ts +25 -0
- package/dist/deck-agenda.js +6 -0
- package/dist/deck-annotate.d.ts +108 -0
- package/dist/deck-annotate.js +18 -0
- package/dist/deck-bar.d.ts +32 -0
- package/dist/deck-bar.js +19 -0
- package/dist/deck-bento.d.ts +38 -0
- package/dist/deck-bento.js +4 -0
- package/dist/{molecules/deck-callout.d.ts → deck-callout.d.ts} +2 -0
- package/dist/deck-callout.js +1 -1
- package/dist/deck-cell.d.ts +19 -0
- package/dist/deck-cell.js +1 -0
- package/dist/deck-checklist.d.ts +20 -0
- package/dist/deck-checklist.js +1 -0
- package/dist/{layouts/deck-cover.d.ts → deck-cover.d.ts} +8 -0
- package/dist/deck-cover.js +9 -6
- package/dist/deck-csv.d.ts +38 -0
- package/dist/deck-csv.js +15 -0
- package/dist/deck-feature-cards.js +2 -2
- package/dist/deck-feature.d.ts +18 -0
- package/dist/deck-feature.js +2 -2
- package/dist/deck-figure.d.ts +26 -0
- package/dist/deck-figure.js +8 -0
- package/dist/deck-fit.d.ts +14 -0
- package/dist/deck-fit.js +1 -0
- package/dist/deck-flow.d.ts +41 -0
- package/dist/deck-flow.js +7 -0
- package/dist/deck-graph.d.ts +92 -0
- package/dist/deck-graph.js +25 -0
- package/dist/deck-grid.js +1 -1
- package/dist/deck-icon.d.ts +20 -0
- package/dist/deck-icon.js +1 -0
- package/dist/{atoms/deck-kicker.d.ts → deck-kicker.d.ts} +5 -0
- package/dist/deck-kicker.js +1 -1
- package/dist/deck-kpi-grid.d.ts +26 -0
- package/dist/deck-kpi-grid.js +4 -0
- package/dist/deck-link.d.ts +21 -0
- package/dist/deck-link.js +1 -0
- package/dist/{molecules/deck-md.d.ts → deck-md.d.ts} +3 -0
- package/dist/deck-md.js +8 -3
- package/dist/deck-mermaid.js +15 -3
- package/dist/deck-outline.d.ts +50 -0
- package/dist/deck-outline.js +1 -0
- package/dist/deck-overview.js +53 -39
- package/dist/deck-persona.d.ts +31 -0
- package/dist/deck-persona.js +6 -0
- package/dist/deck-photo.js +1 -1
- package/dist/deck-point.d.ts +22 -0
- package/dist/deck-point.js +1 -0
- package/dist/deck-presenter.js +120 -48
- package/dist/deck-pull.d.ts +13 -0
- package/dist/deck-pull.js +1 -0
- package/dist/{atoms/deck-punch.d.ts → deck-punch.d.ts} +6 -0
- package/dist/deck-punch.js +1 -1
- package/dist/deck-quote.d.ts +28 -0
- package/dist/deck-quote.js +6 -0
- package/dist/{runtime/deck-root.d.ts → deck-root.d.ts} +88 -8
- package/dist/deck-root.js +17 -13
- package/dist/deck-section.js +2 -2
- package/dist/deck-source.d.ts +12 -0
- package/dist/deck-source.js +2 -0
- package/dist/deck-split.d.ts +30 -0
- package/dist/deck-split.js +5 -3
- package/dist/{molecules/deck-stat.d.ts → deck-stat.d.ts} +2 -0
- package/dist/deck-stat.js +2 -2
- package/dist/{molecules/deck-step-list.d.ts → deck-step-list.d.ts} +8 -0
- package/dist/deck-step-list.js +4 -2
- package/dist/deck-table.d.ts +26 -0
- package/dist/deck-table.js +1 -0
- package/dist/deck-takeaway.d.ts +18 -0
- package/dist/deck-takeaway.js +2 -2
- package/dist/deck-timeline.d.ts +37 -0
- package/dist/deck-timeline.js +5 -0
- package/dist/deck-transition.js +3 -3
- package/dist/deck-versus.d.ts +18 -0
- package/dist/deck-versus.js +9 -0
- package/dist/deep-link.d.ts +29 -0
- package/dist/deep-link.js +1 -0
- package/dist/escape-html.d.ts +3 -0
- package/dist/escape-html.js +1 -0
- package/dist/fit-controller.d.ts +27 -0
- package/dist/fit-controller.js +1 -0
- package/dist/graph-layout.d.ts +35 -0
- package/dist/graph-layout.js +1 -0
- package/dist/grid-tracks.d.ts +17 -0
- package/dist/grid-tracks.js +1 -0
- package/dist/icon-set.d.ts +6 -0
- package/dist/icon-set.js +1 -0
- package/dist/index.d.ts +37 -31
- package/dist/index.js +95 -49
- package/dist/keymap.d.ts +40 -0
- package/dist/keymap.js +1 -0
- package/dist/mouse-nav.d.ts +12 -0
- package/dist/mouse-nav.js +1 -0
- package/dist/navigation.d.ts +25 -0
- package/dist/navigation.js +1 -0
- package/dist/parse-csv.d.ts +9 -0
- package/dist/parse-csv.js +3 -0
- package/dist/shared-styles.js +1 -1
- package/dist/shiki.d.ts +8 -0
- package/dist/signature.d.ts +2 -0
- package/dist/signature.js +1 -0
- package/dist/slide-fill.d.ts +8 -0
- package/dist/slide-fill.js +1 -0
- package/dist/standalone.js +301 -169
- package/dist/vendor/THIRD-PARTY-NOTICES.txt +4347 -0
- package/dist/vendor/inventory.json +3029 -0
- package/dist/vendor/lit.js +62 -2
- package/dist/vendor/mermaid.min.js +95 -95
- package/dist/vendor/shiki.js +1 -57
- package/dist/viewport.d.ts +42 -0
- package/dist/viewport.js +1 -0
- package/docs/llms/rikiki-reference.md +955 -64
- package/docs/llms/rikiki-workflow.md +536 -0
- package/llms.txt +39 -12
- package/package.json +33 -12
- package/themes/rikiki.css +173 -47
- package/themes/siliceum.css +171 -51
- package/dist/layouts/deck-feature.d.ts +0 -11
- package/dist/layouts/deck-split.d.ts +0 -18
- package/dist/layouts/deck-takeaway.d.ts +0 -11
- package/dist/plugins/shiki.d.ts +0 -8
- /package/dist/{runtime/color.d.ts → color.d.ts} +0 -0
- /package/dist/{atoms/deck-badge.d.ts → deck-badge.d.ts} +0 -0
- /package/dist/{molecules/deck-card.d.ts → deck-card.d.ts} +0 -0
- /package/dist/{atoms/deck-code-highlighter.d.ts → deck-code-highlighter.d.ts} +0 -0
- /package/dist/{atoms/deck-code.d.ts → deck-code.d.ts} +0 -0
- /package/dist/{layouts/deck-feature-cards.d.ts → deck-feature-cards.d.ts} +0 -0
- /package/dist/{molecules/deck-grid.d.ts → deck-grid.d.ts} +0 -0
- /package/dist/{runtime/deck-help.d.ts → deck-help.d.ts} +0 -0
- /package/dist/{molecules/deck-mermaid.d.ts → deck-mermaid.d.ts} +0 -0
- /package/dist/{molecules/deck-metric.d.ts → deck-metric.d.ts} +0 -0
- /package/dist/{runtime/deck-notes.d.ts → deck-notes.d.ts} +0 -0
- /package/dist/{runtime/deck-overview.d.ts → deck-overview.d.ts} +0 -0
- /package/dist/{layouts/deck-photo.d.ts → deck-photo.d.ts} +0 -0
- /package/dist/{runtime/deck-presenter.d.ts → deck-presenter.d.ts} +0 -0
- /package/dist/{layouts/deck-section.d.ts → deck-section.d.ts} +0 -0
- /package/dist/{molecules/deck-shortcut.d.ts → deck-shortcut.d.ts} +0 -0
- /package/dist/{molecules/deck-stack.d.ts → deck-stack.d.ts} +0 -0
- /package/dist/{molecules/deck-tier-list.d.ts → deck-tier-list.d.ts} +0 -0
- /package/dist/{runtime/deck-transition.d.ts → deck-transition.d.ts} +0 -0
package/dist/deck-presenter.js
CHANGED
|
@@ -1,23 +1,39 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),m=document.querySelector('script[type="module"][data-rikiki-bundle]')?.textContent??"";return{current:r+1,total:n.length,slideHtml:t?.outerHTML??"",nextHtml:d?.outerHTML??null,notes:b,themeHref:o,
|
|
1
|
+
var R={"&":"&","<":"<",">":">",'"':""","'":"'"};function S(e){return e==null?"":String(e).replace(/[&<>"']/g,n=>R[n])}var A="rik-presenter",D=new URL("./index.js",import.meta.url).href,a=null,p=null,u=null,f=null,h=!1;async function T(){if(f)return f;let e=window.getScreenDetails;if(!e)return null;try{return f=await e.call(window),f}catch{return null}}var g=1280,y=720;function C(e){return{left:Math.round(e.availLeft+(e.availWidth-g)/2),top:Math.round(e.availTop+(e.availHeight-y)/2)}}function M(e){let{left:n,top:r}=C(e);return`popup=yes,width=${g},height=${y},left=${n},top=${r}`}function $(e,n){let{left:r,top:t}=C(n);e.resizeTo(g,y),e.moveTo(r,t)}function E(e,n){e.requestFullscreen?.({screen:n}).then(()=>{if(!u?.has(e)){document.exitFullscreen?.().catch(()=>{});return}h=!0}).catch(()=>{})}function I(){document.fullscreenElement||(h=!1)}function B(){document.removeEventListener("fullscreenchange",I),h&&document.fullscreenElement&&document.exitFullscreen?.().catch(()=>{}),h=!1}function w(e){a?.close(),a=null,p?.close(),p=null,u?.delete(e),e.presenterActive=!1,B()}function P(e){let n=Array.from(e.children).filter(s=>s.tagName.toLowerCase().startsWith("deck-")),r=n.findIndex(s=>s.hasAttribute("active")),t=n[r]??null,d=n[r+1]??null,b=(t?.querySelector("deck-notes")?.textContent??"").trim(),o=document.querySelector('link[rel="stylesheet"][href*="rikiki"], link[rel="stylesheet"][href*="tokens"], link[rel="stylesheet"][href*="theme"]')?.href??"",l=Array.from(document.querySelectorAll("style")).map(s=>s.textContent??"").join(`
|
|
2
|
+
`),m=document.querySelector('script[type="module"][data-rikiki-bundle]')?.textContent??"";return{current:r+1,total:n.length,step:e.step,steps:Number(t?.getAttribute("steps")||t?.getAttribute("data-steps")||0),slideHtml:t?.outerHTML??"",nextHtml:d?.outerHTML??null,notes:b,themeHref:o,previewStyles:Array.from(document.querySelectorAll('link[rel="stylesheet"], style')).map(s=>s.outerHTML).join(`
|
|
3
|
+
`),moduleHrefs:Array.from(document.querySelectorAll('script[type="module"][src]')).map(s=>s.src),baseHref:document.baseURI,lang:document.documentElement.lang,canvasWidth:e.width,canvasHeight:e.height,inlineStyles:l,bundleHref:D,bundleInline:m}}function H(e){p&&p.postMessage({type:"state",state:P(e)})}var N=e=>`<!doctype html>
|
|
3
4
|
<html lang="en">
|
|
4
5
|
<head>
|
|
5
6
|
<meta charset="utf-8">
|
|
6
7
|
<title>Rikiki \xB7 presenter</title>
|
|
7
|
-
${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
|
|
8
|
+
${e.themeHref?`<link rel="stylesheet" href="${S(e.themeHref)}">`:""}
|
|
8
9
|
<style>
|
|
9
10
|
html, body { margin: 0; padding: 0; height: 100%; background: #0f1422; color: #fafafa; font-family: var(--rik-font-sans, system-ui); }
|
|
10
11
|
.grid {
|
|
11
12
|
display: grid;
|
|
12
13
|
grid-template-columns: 2fr 1fr;
|
|
13
|
-
|
|
14
|
+
/* Next is sized to its 16:9 content (top-right); notes fill the rest of the
|
|
15
|
+
right column; current spans the full left height. Avoids the dead bands a
|
|
16
|
+
full-height narrow Next pane left around a small 16:9 thumbnail. */
|
|
17
|
+
grid-template-rows: auto 1fr auto;
|
|
18
|
+
grid-template-areas:
|
|
19
|
+
"current next"
|
|
20
|
+
"current notes"
|
|
21
|
+
"footer footer";
|
|
14
22
|
gap: clamp(8px, 1.5vw, 16px);
|
|
15
23
|
padding: clamp(8px, 1.5vw, 16px);
|
|
16
24
|
height: 100vh;
|
|
17
25
|
box-sizing: border-box;
|
|
18
26
|
}
|
|
27
|
+
#current { grid-area: current; }
|
|
28
|
+
#next { grid-area: next; }
|
|
29
|
+
#notes-panel { grid-area: notes; }
|
|
30
|
+
#footer { grid-area: footer; }
|
|
19
31
|
@media (max-width: 1000px) {
|
|
20
|
-
.grid {
|
|
32
|
+
.grid {
|
|
33
|
+
grid-template-columns: 1fr;
|
|
34
|
+
grid-template-rows: auto auto 1fr auto;
|
|
35
|
+
grid-template-areas: "current" "next" "notes" "footer";
|
|
36
|
+
}
|
|
21
37
|
}
|
|
22
38
|
.panel {
|
|
23
39
|
background: #1e2840;
|
|
@@ -36,17 +52,31 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
|
|
|
36
52
|
background: #161c2e;
|
|
37
53
|
}
|
|
38
54
|
.panel .body { flex: 1; min-height: 0; padding: 16px; overflow: hidden; border-radius: 8px; }
|
|
39
|
-
/*
|
|
40
|
-
geometry regardless of
|
|
55
|
+
/* Current centers a 16:9 box in its (tall) pane so the thumbnail matches the
|
|
56
|
+
projection geometry regardless of pane shape (issue #5) \xB7 the size
|
|
41
57
|
container lets the iframe size against the pane in cq units. */
|
|
42
|
-
#current .body
|
|
58
|
+
#current .body { display: grid; place-items: center; container-type: size; }
|
|
43
59
|
.panel iframe { border: 0; background: #0f1422; display: block; }
|
|
44
|
-
#current-
|
|
60
|
+
#current-viewport {
|
|
45
61
|
aspect-ratio: 16 / 9;
|
|
46
62
|
width: min(100cqw, calc(100cqh * 16 / 9));
|
|
47
63
|
height: auto;
|
|
48
64
|
max-width: 100%;
|
|
49
65
|
}
|
|
66
|
+
/* Next sizes its 16:9 box from the column width (its pane row is auto), so
|
|
67
|
+
the panel hugs the thumbnail instead of stretching full-height. */
|
|
68
|
+
#next-viewport {
|
|
69
|
+
aspect-ratio: 16 / 9;
|
|
70
|
+
width: 100%;
|
|
71
|
+
height: auto;
|
|
72
|
+
display: block;
|
|
73
|
+
}
|
|
74
|
+
.preview-viewport { position: relative; overflow: hidden; }
|
|
75
|
+
.preview-viewport iframe {
|
|
76
|
+
position: absolute; top: 0; left: 0;
|
|
77
|
+
width: ${e.canvasWidth}px; height: ${e.canvasHeight}px;
|
|
78
|
+
transform-origin: top left;
|
|
79
|
+
}
|
|
50
80
|
#notes { font-size: 17px; line-height: 1.6; white-space: pre-wrap; padding: 20px; overflow: auto; color: #e8e4f0; }
|
|
51
81
|
#notes:empty::before { content: 'No notes for this slide.'; color: rgba(232,228,240,0.4); font-style: italic; }
|
|
52
82
|
#footer {
|
|
@@ -78,19 +108,19 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
|
|
|
78
108
|
<div class="grid">
|
|
79
109
|
<section class="panel" id="current">
|
|
80
110
|
<header>Current</header>
|
|
81
|
-
<div class="body"><iframe id="current-frame" srcdoc=""></iframe></div>
|
|
111
|
+
<div class="body"><div class="preview-viewport" id="current-viewport"><iframe id="current-frame" srcdoc=""></iframe></div></div>
|
|
82
112
|
</section>
|
|
83
113
|
<section class="panel" id="next">
|
|
84
114
|
<header>Next</header>
|
|
85
|
-
<div class="body"><iframe id="next-frame" srcdoc=""></iframe></div>
|
|
115
|
+
<div class="body"><div class="preview-viewport" id="next-viewport"><iframe id="next-frame" srcdoc=""></iframe></div></div>
|
|
86
116
|
</section>
|
|
87
|
-
<section class="panel" id="notes-panel"
|
|
117
|
+
<section class="panel" id="notes-panel">
|
|
88
118
|
<header>Speaker notes</header>
|
|
89
119
|
<div id="notes" class="body"></div>
|
|
90
120
|
</section>
|
|
91
121
|
<div id="footer">
|
|
92
122
|
<div><span id="timer">00:00</span> <button id="timer-toggle">Pause</button> <button id="timer-reset">Reset</button></div>
|
|
93
|
-
<div id="counter">${e.current} / ${e.total}</div>
|
|
123
|
+
<div><span id="counter">${e.current} / ${e.total}</span> <span id="stepper"></span></div>
|
|
94
124
|
<div>
|
|
95
125
|
<label class="opt"><input type="checkbox" id="opt-advance" checked> Advance on click</label>
|
|
96
126
|
<span class="ghost">\xB7 P to close</span>
|
|
@@ -98,9 +128,17 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
|
|
|
98
128
|
</div>
|
|
99
129
|
</div>
|
|
100
130
|
<script>
|
|
101
|
-
const channel = new BroadcastChannel('${
|
|
131
|
+
const channel = new BroadcastChannel('${A}');
|
|
102
132
|
const current = document.getElementById('current-frame');
|
|
103
133
|
const next = document.getElementById('next-frame');
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
const previewResize = new ResizeObserver(entries => {
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
entry.target.querySelector('iframe').style.transform = 'scale(' + (entry.contentRect.width / ${e.canvasWidth}) + ')';
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
document.querySelectorAll('.preview-viewport').forEach(el => previewResize.observe(el));
|
|
104
142
|
const notes = document.getElementById('notes');
|
|
105
143
|
const counter = document.getElementById('counter');
|
|
106
144
|
const timerEl = document.getElementById('timer');
|
|
@@ -128,25 +166,30 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
|
|
|
128
166
|
};
|
|
129
167
|
resetBtn.onclick = () => { startedAt = Date.now(); elapsed = 0; running = true; toggleBtn.textContent = 'Pause'; };
|
|
130
168
|
|
|
131
|
-
// Presentation options \xB7 push each change to the live deck over the channel.
|
|
132
169
|
document.getElementById('opt-advance').addEventListener('change', (e) => {
|
|
133
170
|
channel.postMessage({ type: 'config', advanceOnClick: e.target.checked });
|
|
134
171
|
});
|
|
135
172
|
|
|
136
173
|
function wrapFrame(slideHtml, forward) {
|
|
137
|
-
const
|
|
138
|
-
const
|
|
174
|
+
const previewStyles = ${JSON.stringify(e.previewStyles).replace(/</g,"\\u003c")};
|
|
175
|
+
const moduleHrefs = ${JSON.stringify(e.moduleHrefs).replace(/</g,"\\u003c")};
|
|
176
|
+
const baseHref = ${JSON.stringify(e.baseHref).replace(/</g,"\\u003c")};
|
|
177
|
+
const lang = ${JSON.stringify(e.lang).replace(/</g,"\\u003c")};
|
|
139
178
|
const bundleHref = ${JSON.stringify(e.bundleHref)};
|
|
140
179
|
const bundleInline = ${JSON.stringify(e.bundleInline)};
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
const escAttr = (s) => s.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
185
|
+
const escStyle = (s) => s.replace(/<\\/(style|script)/gi, '<\\\\/$1');
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
150
193
|
let bundleTag;
|
|
151
194
|
const esc = (c) => c.replace(/<\\/script/gi, '<\\\\/script');
|
|
152
195
|
if (bundleInline) {
|
|
@@ -160,12 +203,12 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
|
|
|
160
203
|
} else {
|
|
161
204
|
bundleTag = '<script type="module" src="' + bundleHref + '"><' + '/script>';
|
|
162
205
|
}
|
|
163
|
-
|
|
164
|
-
|
|
206
|
+
|
|
207
|
+
|
|
165
208
|
const activeSlide = slideHtml.replace(/^(\\s*<deck-[a-z-]+)/i, '$1 active');
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
169
212
|
const forwarder = forward
|
|
170
213
|
? '<scr' + 'ipt>(function(){' +
|
|
171
214
|
'var post=function(o){o.source="rikiki-presenter-input";parent.postMessage(o,"*");};' +
|
|
@@ -174,47 +217,76 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
|
|
|
174
217
|
'addEventListener("wheel",function(e){if(e.ctrlKey||e.metaKey)return;post({type:"wheel",x:e.clientX/innerWidth,y:e.clientY/innerHeight,dx:e.deltaX,dy:e.deltaY});},{passive:true});' +
|
|
175
218
|
'})();<' + '/scr' + 'ipt>'
|
|
176
219
|
: '';
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return '<!doctype html><html><head><meta charset="UTF-8"
|
|
181
|
-
bundleTag +
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
return '<!doctype html><html lang="' + escAttr(lang) + '"><head><meta charset="UTF-8"><base href="' + escAttr(baseHref) + '">' + previewStyles +
|
|
224
|
+
bundleTag + moduleHrefs.filter((href) => href !== bundleHref).map((href) => '<script type="module" src="' + escAttr(href) + '"><' + '/script>').join('') +
|
|
182
225
|
'<style>html,body{margin:0;padding:0;height:100%;overflow:hidden;background:#0f1422}' +
|
|
183
226
|
'deck-root{position:absolute;inset:0}</style>' +
|
|
184
|
-
'</head><body><deck-root no-hint no-arrows no-counter preview>' + activeSlide + '</deck-root>' + forwarder + '</body></html>';
|
|
227
|
+
'</head><body><deck-root width="${e.canvasWidth}" height="${e.canvasHeight}" no-hint no-arrows no-counter preview data-overview-snapshot>' + activeSlide + '</deck-root>' + forwarder + '</body></html>';
|
|
185
228
|
}
|
|
186
229
|
|
|
230
|
+
|
|
231
|
+
const frames = new Map();
|
|
232
|
+
function updateFrame(frame, html, step, forward) {
|
|
233
|
+
let state = frames.get(frame);
|
|
234
|
+
if (!state) {
|
|
235
|
+
state = { html, step, ready: false, painted: null };
|
|
236
|
+
frames.set(frame, state);
|
|
237
|
+
frame.addEventListener('load', () => {
|
|
238
|
+
state.ready = true;
|
|
239
|
+
paint();
|
|
240
|
+
});
|
|
241
|
+
frame.srcdoc = wrapFrame('', forward);
|
|
242
|
+
}
|
|
243
|
+
state.html = html;
|
|
244
|
+
state.step = step;
|
|
245
|
+
function paint() {
|
|
246
|
+
if (!state.ready) return;
|
|
247
|
+
const root = frame.contentDocument?.querySelector('deck-root');
|
|
248
|
+
if (!root) return;
|
|
249
|
+
if (state.painted !== state.html) {
|
|
250
|
+
root.innerHTML = state.html || '<div style="padding:3rem;color:white">End of deck</div>';
|
|
251
|
+
root.firstElementChild?.setAttribute('active', '');
|
|
252
|
+
state.painted = state.html;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
Promise.resolve().then(async () => {
|
|
256
|
+
const elements = [root.firstElementChild, ...root.querySelectorAll('*')].filter(Boolean);
|
|
257
|
+
await Promise.all(elements.map(el => el.updateComplete));
|
|
258
|
+
elements.forEach(el => el.applyStep?.(state.step));
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
paint();
|
|
262
|
+
}
|
|
187
263
|
channel.onmessage = (e) => {
|
|
188
264
|
if (e.data?.type !== 'state') return;
|
|
189
265
|
const s = e.data.state;
|
|
190
266
|
counter.textContent = s.current + ' / ' + s.total;
|
|
267
|
+
document.getElementById('stepper').textContent = s.steps ? ' \xB7 \xC9tape ' + s.step + ' / ' + s.steps : '';
|
|
191
268
|
notes.textContent = s.notes;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
else next.srcdoc = '<!doctype html><html><body style="background:#0f1422;color:rgba(232,228,240,0.4);display:flex;align-items:center;justify-content:center;font-family:system-ui">End of deck</body></html>';
|
|
269
|
+
updateFrame(current, s.slideHtml, s.step, true);
|
|
270
|
+
updateFrame(next, s.nextHtml, 0, false);
|
|
195
271
|
};
|
|
196
272
|
|
|
197
|
-
|
|
198
|
-
const seed = ${JSON.stringify(e)};
|
|
273
|
+
const seed = ${JSON.stringify(e).replace(/</g,"\\u003c")};
|
|
199
274
|
channel.postMessage({ type: 'state', state: seed });
|
|
200
275
|
|
|
201
|
-
// Forward keys back to the main window (so the speaker can drive nav from the laptop)
|
|
202
276
|
window.addEventListener('keydown', (e) => {
|
|
203
277
|
if (e.target.matches && e.target.matches('input,textarea,button')) return;
|
|
204
278
|
channel.postMessage({ type: 'key', key: e.key, shift: e.shiftKey });
|
|
205
279
|
});
|
|
206
280
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
// never reach this window directly \xB7 it postMessages them here instead.
|
|
281
|
+
|
|
282
|
+
|
|
210
283
|
window.addEventListener('message', (e) => {
|
|
211
284
|
const d = e.data;
|
|
212
285
|
if (!d || d.source !== 'rikiki-presenter-input') return;
|
|
213
286
|
channel.postMessage({ type: d.type, key: d.key, shift: d.shift, x: d.x, y: d.y, dx: d.dx, dy: d.dy });
|
|
214
287
|
});
|
|
215
288
|
|
|
216
|
-
// Tell main window we're alive
|
|
217
289
|
channel.postMessage({ type: 'hello' });
|
|
218
290
|
<\/script>
|
|
219
291
|
</body>
|
|
220
|
-
</html>`;function
|
|
292
|
+
</html>`;function W(e,n){let r=document.elementFromPoint(e,n);for(;r?.shadowRoot;){let t=r.shadowRoot.elementFromPoint(e,n);if(!t||t===r)break;r=t}return r}function q(e,n,r){for(let t=e;t;t=t.parentElement){let d=getComputedStyle(t);if(r!==0&&t.scrollHeight>t.clientHeight&&/auto|scroll/.test(d.overflowY)||n!==0&&t.scrollWidth>t.clientWidth&&/auto|scroll/.test(d.overflowX))return t}return null}function F(e,n,r){let t=e.getBoundingClientRect();return{x:t.left+n*t.width,y:t.top+r*t.height}}function L(e,n){let{x:r,y:t}=F(e,n.x??.5,n.y??.5);return{x:r,y:t,target:W(r,t)??e}}function O(e){let n=(e??"all").trim();return n==="none"?"none":n===""||n==="all"?"wheel arrows aux":n.split(/\s+/).filter(r=>r!=="click").join(" ")||"none"}function j(e){if(u=u??new WeakSet,u.has(e)){w(e);return}u.add(e);let n=e.mouseNav;p=new BroadcastChannel(A),e.addEventListener("step-change",()=>H(e)),p.addEventListener("message",i=>{let o=i.data;if(o?.type==="key"&&o.key)window.dispatchEvent(new KeyboardEvent("keydown",{key:o.key,shiftKey:!!o.shift,bubbles:!0}));else if(o?.type==="click"){let{x:l,y:m,target:s}=L(e,o),c={bubbles:!0,composed:!0,cancelable:!0,clientX:l,clientY:m,view:window,shiftKey:!!o.shift};s.dispatchEvent(new PointerEvent("pointerdown",{...c,pointerId:1,isPrimary:!0})),s.dispatchEvent(new PointerEvent("pointerup",{...c,pointerId:1,isPrimary:!0})),s.dispatchEvent(new MouseEvent("click",c))}else if(o?.type==="wheel"){let{x:l,y:m,target:s}=L(e,o),c=o.dx??0,v=o.dy??0,x=q(s,c,v);x?x.scrollBy({left:c,top:v}):s.dispatchEvent(new WheelEvent("wheel",{bubbles:!0,composed:!0,cancelable:!0,clientX:l,clientY:m,deltaX:c,deltaY:v,view:window}))}else o?.type==="config"&&typeof o.advanceOnClick=="boolean"?e.mouseNav=o.advanceOnClick?n:O(n):o?.type==="hello"&&H(e)});let r=f,t=r?.screens.find(i=>i!==r.currentScreen)??null;t?E(e,t):T().then(i=>{if(!i)return;let o=i.screens.find(l=>l!==i.currentScreen);o&&E(e,o),a&&i.currentScreen&&$(a,i.currentScreen)});let d=P(e),k=r?.currentScreen?M(r.currentScreen):`popup=yes,width=${g},height=${y}`;if(a=window.open("","rikiki-presenter",k),!a){console.warn("[rikiki/presenter] popup was blocked \xB7 allow popups for this site"),w(e);return}a.document.open(),a.document.write(N(d)),a.document.close(),e.presenterActive=!0,document.addEventListener("fullscreenchange",I);let b=setInterval(()=>{a?.closed&&(clearInterval(b),w(e))},1e3)}export{j as installPresenter};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export type DeckPullSide = 'left' | 'right' | 'full';
|
|
3
|
+
export declare class DeckPull extends LitElement {
|
|
4
|
+
static styles: import("lit").CSSResult;
|
|
5
|
+
/** `full` (default), or floated to one side so the text wraps around it. */
|
|
6
|
+
side: DeckPullSide;
|
|
7
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
8
|
+
}
|
|
9
|
+
declare global {
|
|
10
|
+
interface HTMLElementTagNameMap {
|
|
11
|
+
'deck-pull': DeckPull;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var s=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var p=(a,t,i,l)=>{for(var e=l>1?void 0:l?c(t,i):t,d=a.length-1,o;d>=0;d--)(o=a[d])&&(e=(l?o(t,i,e):o(e))||e);return l&&e&&s(t,i,e),e};import{LitElement as n,css as f,html as g}from"./vendor/lit.js";import{customElement as k,property as v}from"./vendor/lit.js";var r=class extends n{constructor(){super(...arguments);this.side="full"}render(){return g`<slot></slot>`}};r.styles=f`:host{display:block;font-family:var(--deck-pull-font,var(--rik-font-display,var(--rik-font-sans)));font-size:var(--deck-pull-size,var(--rik-font-size-big));line-height:1.15;letter-spacing:-0.02em;font-weight:800;color:var(--deck-pull-color,var(--rik-text-default));background:var(--deck-pull-bg,transparent);padding:var(--deck-pull-padding,var(--rik-space-2) 0);border-left:var(--deck-pull-rule-width,4px) solid var(--deck-pull-rule,var(--rik-accent));padding-left:var(--rik-space-4);text-wrap:balance}:host([side='left']),:host([side='right']){width:var(--deck-pull-width,38%);margin-block:var(--rik-space-2)}:host([side='left']){float:left;margin-right:var(--rik-space-4)}:host([side='right']){float:right;margin-left:var(--rik-space-4);border-left:0;border-right:var(--deck-pull-rule-width,4px) solid var(--deck-pull-rule,var(--rik-accent));padding-left:0;padding-right:var(--rik-space-4);text-align:right}@media print{:host{-webkit-print-color-adjust:exact;print-color-adjust:exact}}`,p([v({type:String,reflect:!0})],r.prototype,"side",2),r=p([k("deck-pull")],r);export{r as DeckPull};
|
|
@@ -7,6 +7,12 @@ export declare class DeckPunch extends LitElement {
|
|
|
7
7
|
size?: DeckPunchSize;
|
|
8
8
|
weight?: string;
|
|
9
9
|
align?: string;
|
|
10
|
+
/** Shrink to fit the box (overrides `size`/cqw fluid scaling). */
|
|
11
|
+
fit: boolean;
|
|
12
|
+
/** fit floor / ceiling in rem · default 1 / 12. */
|
|
13
|
+
fitMin?: number;
|
|
14
|
+
fitMax?: number;
|
|
15
|
+
private fitter;
|
|
10
16
|
updated(): void;
|
|
11
17
|
render(): import("lit-html").TemplateResult<1>;
|
|
12
18
|
}
|
package/dist/deck-punch.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var p=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
var p=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var n=(a,t,r,l)=>{for(var e=l>1?void 0:l?d(t,r):t,o=a.length-1,s;o>=0;o--)(s=a[o])&&(e=(l?s(t,r,e):s(e))||e);return l&&e&&p(t,r,e),e};import{LitElement as u,html as v,css as y}from"./vendor/lit.js";import{customElement as b,property as h}from"./vendor/lit.js";function g(a,t,r,l=.5){if(t<=a)return a;if(r(t))return t;let e=a,o=t;for(;o-e>l;){let s=(e+o)/2;r(s)?e=s:o=s}return e}var c=class{constructor(t,r={}){this.host=t;this.opts=r;t.addController(this)}hostConnected(){this.ro=new ResizeObserver(()=>this.refit()),this.ro.observe(this.host),this.refit(),document.fonts?.ready?.then(()=>{this.ro&&this.refit()})}hostDisconnected(){this.ro?.disconnect(),this.ro=void 0}refit(){let t=this.host;if(this.opts.enabled&&!this.opts.enabled()){t.style.removeProperty("font-size");return}if(t.clientWidth===0||t.clientHeight===0)return;let r=parseFloat(getComputedStyle(document.documentElement).fontSize)||16,l=(this.opts.minRem?.()??1)*r,e=(this.opts.maxRem?.()??12)*r,o=s=>(t.style.fontSize=`${s}px`,t.scrollWidth<=t.clientWidth&&t.scrollHeight<=t.clientHeight);t.style.fontSize=`${g(l,e,o)}px`}};var m={warn:"var(--rik-status-warn__text)",danger:"var(--rik-status-danger__text)",ok:"var(--rik-status-success__text)",info:"var(--rik-accent__text)",muted:"var(--rik-text-default--faint)",accent:"var(--rik-accent__text)"},f={lead:"var(--rik-font-size-lead)",big:"var(--rik-font-size-big)",mega:"var(--rik-font-size-mega)",stat:"var(--rik-font-size-stat)",display:"clamp(2.6rem, 6cqw, 5rem)"},i=class extends u{constructor(){super(...arguments);this.fit=!1;this.fitter=new c(this,{enabled:()=>this.fit,minRem:()=>this.fitMin??1,maxRem:()=>this.fitMax??12})}updated(){this.fitter.refit(),this.tone&&m[this.tone]?this.style.setProperty("--_color",m[this.tone]):this.style.removeProperty("--_color"),this.size&&f[this.size]?this.style.setProperty("--_size",f[this.size]):this.style.removeProperty("--_size")}render(){return v`<slot></slot>`}};i.styles=y`:host{display:block;margin:0;font-family:var(--rik-font-display,var(--rik-font-sans));font-weight:900;line-height:1.1;letter-spacing:-0.02em;font-size:var(--deck-punch-size,var(--_size,var(--rik-font-size-lead)));color:var(--deck-punch-color,var(--_color,inherit))}:host([weight="700"]){font-weight:700}:host([weight="800"]){font-weight:800}:host([align="center"]){text-align:center}:host([align="right"]){text-align:right}:host([fit]){display:block;width:100%;height:100%;overflow:hidden}`,n([h({type:String})],i.prototype,"tone",2),n([h({type:String})],i.prototype,"size",2),n([h({type:String,reflect:!0})],i.prototype,"weight",2),n([h({type:String,reflect:!0})],i.prototype,"align",2),n([h({type:Boolean})],i.prototype,"fit",2),n([h({type:Number,attribute:"fit-min"})],i.prototype,"fitMin",2),n([h({type:Number,attribute:"fit-max"})],i.prototype,"fitMax",2),i=n([b("deck-punch")],i);export{i as DeckPunch};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export type DeckQuoteSize = 'lead' | 'big' | 'mega';
|
|
3
|
+
export declare class DeckQuote extends LitElement {
|
|
4
|
+
static styles: import("lit").CSSResult;
|
|
5
|
+
/** Attributed name · omitted, the quote stands alone. */
|
|
6
|
+
author?: string;
|
|
7
|
+
/** Role or affiliation, under the name.
|
|
8
|
+
*
|
|
9
|
+
* NOT `role`: that attribute is ARIA's, and putting "CTO, Acme" in it would
|
|
10
|
+
* announce the figure as a landmark of that name. The property would also
|
|
11
|
+
* shadow HTMLElement.role. */
|
|
12
|
+
authorRole?: string;
|
|
13
|
+
/** Type size of the quoted line. */
|
|
14
|
+
size: DeckQuoteSize;
|
|
15
|
+
/** Drop the accent rule down the left edge. */
|
|
16
|
+
plain: boolean;
|
|
17
|
+
/** Use the inverse text tokens · for a quote on a dark slide. */
|
|
18
|
+
onDark: boolean;
|
|
19
|
+
/** Hide the decorative opening mark. */
|
|
20
|
+
noMark: boolean;
|
|
21
|
+
willUpdate(): void;
|
|
22
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
23
|
+
}
|
|
24
|
+
declare global {
|
|
25
|
+
interface HTMLElementTagNameMap {
|
|
26
|
+
'deck-quote': DeckQuote;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
var p=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var r=(s,o,n,i)=>{for(var t=i>1?void 0:i?k(o,n):o,c=s.length-1,d;c>=0;c--)(d=s[c])&&(t=(i?d(o,n,t):d(t))||t);return i&&t&&p(o,n,t),t};import{LitElement as h,css as f,html as l}from"./vendor/lit.js";import{customElement as v,property as a}from"./vendor/lit.js";var u={lead:"var(--rik-font-size-lead)",big:"var(--rik-font-size-big)",mega:"var(--rik-font-size-mega)"},e=class extends h{constructor(){super(...arguments);this.size="big";this.plain=!1;this.onDark=!1;this.noMark=!1}willUpdate(){this.style.setProperty("--_size",u[this.size]??u.big)}render(){return l`<figure> ${this.noMark?"":l`<span class="mark" aria-hidden="true">“</span>`}
|
|
2
|
+
<blockquote class="quote" part="quote"><slot></slot></blockquote>
|
|
3
|
+
${this.author?l`<figcaption class="who" part="attribution"> <span class="author">${this.author}</span> ${this.authorRole?l`<span class="role">${this.authorRole}</span>`:""}
|
|
4
|
+
</figcaption>`:""}
|
|
5
|
+
</figure>
|
|
6
|
+
`}};e.styles=f`:host{display:block;font-family:var(--rik-font-sans);padding-left:var(--rik-space-4);border-left:var(--deck-quote-rule-width,3px) solid var(--deck-quote-rule,var(--rik-accent))}figure{margin:0}:host([plain]){padding-left:0;border-left:none}.mark{display:block;font-family:var(--rik-font-display,var(--rik-font-sans));font-size:var(--deck-quote-mark-size,calc(var(--_size) * 1.8));line-height:0.8;color:var(--deck-quote-mark-color,var(--rik-accent));user-select:none}.quote{display:block;font-size:var(--deck-quote-size,var(--_size));line-height:1.25;color:var(--deck-quote-color,var(--rik-text-default));max-width:var(--deck-quote-max-width,26ch);margin:var(--deck-quote-gap,var(--rik-space-2)) 0;text-wrap:balance}.who{margin-top:var(--deck-quote-gap,var(--rik-space-2));line-height:1.35}.author{display:block;font-weight:700;color:var(--deck-quote-author-color,var(--rik-text-default))}.role{display:block;font-size:var(--rik-font-size-body);color:var(--deck-quote-role-color,var(--rik-text-default--muted))}:host([on-dark]) .quote,:host([on-dark]) .author{color:var(--rik-text-inverse)}:host([on-dark]) .role{color:var(--rik-text-inverse--muted)}`,r([a({type:String})],e.prototype,"author",2),r([a({type:String,attribute:"author-role"})],e.prototype,"authorRole",2),r([a({type:String,reflect:!0})],e.prototype,"size",2),r([a({type:Boolean,reflect:!0})],e.prototype,"plain",2),r([a({type:Boolean,reflect:!0,attribute:"on-dark"})],e.prototype,"onDark",2),r([a({type:Boolean,attribute:"no-mark"})],e.prototype,"noMark",2),e=r([v("deck-quote")],e);export{e as DeckQuote};
|
|
@@ -35,6 +35,9 @@ export interface DeckPlugin {
|
|
|
35
35
|
navigate?(to: number, ctx: DeckContext, proceed: () => void): boolean | void;
|
|
36
36
|
}
|
|
37
37
|
export declare class DeckRoot extends LitElement {
|
|
38
|
+
/** Internal overview surface: author selectors still see deck-root, but the
|
|
39
|
+
* outer thumbnail owns sizing and no presentation runtime is needed. */
|
|
40
|
+
private get _overviewSnapshot();
|
|
38
41
|
static styles: import("lit").CSSResult;
|
|
39
42
|
current: number;
|
|
40
43
|
step: number;
|
|
@@ -153,12 +156,29 @@ export declare class DeckRoot extends LitElement {
|
|
|
153
156
|
* the container for an embedded one). Driven by a ResizeObserver. */
|
|
154
157
|
private _applyScale;
|
|
155
158
|
private _resizeObserver;
|
|
159
|
+
/** A step the opening fragment asked for, held until the slide can hear it.
|
|
160
|
+
*
|
|
161
|
+
* The components that carry steps are opt-in modules, and a module can
|
|
162
|
+
* register AFTER the engine has read the fragment and applied the step. The
|
|
163
|
+
* step reached a slide whose children were still plain elements with no
|
|
164
|
+
* applyStep to call, so it landed on nothing and no second attempt was ever
|
|
165
|
+
* made · every link into the middle of a build opened its neutral state,
|
|
166
|
+
* which is the one thing such a link exists to avoid. */
|
|
167
|
+
private _pendingStep;
|
|
168
|
+
private _stepWatcher;
|
|
156
169
|
/** Zoom is live only in the fixed canvas and outside overlays. */
|
|
157
170
|
private _zoomEnabled;
|
|
158
171
|
/** Publish zoom + pan as custom props the #stage transform reads. */
|
|
159
172
|
private _applyZoom;
|
|
160
173
|
/** Keep the pan within bounds so the magnified stage always covers the
|
|
161
174
|
* viewport (no gaps); at fit (zoom 1) it forces re-centring. */
|
|
175
|
+
/** The three fields above, as the viewport model sees them. */
|
|
176
|
+
private get _view();
|
|
177
|
+
private set _view(value);
|
|
178
|
+
/** The logical canvas and the box it is shown in · the two measurements the
|
|
179
|
+
* arithmetic in src/domain/viewport.ts needs, and the only DOM it involves. */
|
|
180
|
+
private get _canvas();
|
|
181
|
+
private get _box();
|
|
162
182
|
private _clampPan;
|
|
163
183
|
/** Zoom by a factor, keeping the point at viewport (cx, cy) fixed. */
|
|
164
184
|
private _zoomAt;
|
|
@@ -176,6 +196,16 @@ export declare class DeckRoot extends LitElement {
|
|
|
176
196
|
* surface · removing the override lets the bands fall back to that same
|
|
177
197
|
* surface, which stays seamless too. */
|
|
178
198
|
private _applyLetterbox;
|
|
199
|
+
/** A slide can reach the engine before its own module does · an opt-in
|
|
200
|
+
* component loads from its own script tag, and nothing orders the two.
|
|
201
|
+
* Until it upgrades it has no shadow DOM and reports a TRANSPARENT
|
|
202
|
+
* background, so the read above finds nothing and the bands keep the page
|
|
203
|
+
* surface. This is the only measurement in the engine with no observer
|
|
204
|
+
* behind it, so without this it would never be taken again.
|
|
205
|
+
*
|
|
206
|
+
* Same shape as _stepWatcher below, which catches a step count that
|
|
207
|
+
* arrives late for the same reason. */
|
|
208
|
+
private _repaintLetterboxWhenDefined;
|
|
179
209
|
/** The scaling baseline is a framework concern, not a theme one: inject it
|
|
180
210
|
* globally so any theme (or none) gets it. The rem unit tracks the logical
|
|
181
211
|
* canvas height · the #stage transform does the responsive scaling · and the
|
|
@@ -195,6 +225,15 @@ export declare class DeckRoot extends LitElement {
|
|
|
195
225
|
* slide · it comes last so it wins the equal-specificity tie with the
|
|
196
226
|
* `:not([fluid])` rule. The `height:100%` pair backs the 100% `:host`
|
|
197
227
|
* sizing. */
|
|
228
|
+
/** Size the printed page from the deck's own canvas.
|
|
229
|
+
*
|
|
230
|
+
* `@page` cannot read a custom property, so the rule is written from JS every
|
|
231
|
+
* time the canvas changes. Without it the browser prints A4 and crops a 16:9
|
|
232
|
+
* slide down its right edge · the exact symptom the FAQ promised away. */
|
|
233
|
+
/** What a screen reader hears on a slide change · position first, because
|
|
234
|
+
* that is the part a listener cannot get any other way. */
|
|
235
|
+
private _liveLabel;
|
|
236
|
+
private _applyPageSize;
|
|
198
237
|
private static _injectGlobals;
|
|
199
238
|
connectedCallback(): void;
|
|
200
239
|
disconnectedCallback(): void;
|
|
@@ -221,6 +260,9 @@ export declare class DeckRoot extends LitElement {
|
|
|
221
260
|
private _onAuxUp;
|
|
222
261
|
private _onAuxClick;
|
|
223
262
|
/** Group slides into chapters bounded by <deck-section> markers. */
|
|
263
|
+
/** The deck's shape as the navigation model sees it · rebuilt with the DOM
|
|
264
|
+
* chapter list, and the only thing the decisions below read. */
|
|
265
|
+
private _outline;
|
|
224
266
|
private _buildChapters;
|
|
225
267
|
/** 2D navigation is opt-in via `nav="2d"` · it also needs the structure to
|
|
226
268
|
* make sense (2+ chapters, at least one with multiple slides). Without the
|
|
@@ -230,9 +272,34 @@ export declare class DeckRoot extends LitElement {
|
|
|
230
272
|
private _mouseEnabled;
|
|
231
273
|
/** Flat index → {chapter, intra-chapter index}. */
|
|
232
274
|
private _coords;
|
|
233
|
-
|
|
275
|
+
/** True when the deck IS the page rather than a widget inside one.
|
|
276
|
+
*
|
|
277
|
+
* A full-page deck owns the URL, the keyboard and the wheel · that is the
|
|
278
|
+
* whole point. An embedded deck owns none of them by default: the host put
|
|
279
|
+
* the anchor in the URL, the host's reader is using the arrow keys to read
|
|
280
|
+
* the host's page, and the wheel over a widget scrolls the page it sits in. */
|
|
281
|
+
private _isFullPage;
|
|
282
|
+
/** Does a key press belong to this deck right now? Always, when the deck is
|
|
283
|
+
* the page · only while focus is inside it, when it is embedded. */
|
|
284
|
+
private _ownsKeyboard;
|
|
234
285
|
private _onHash;
|
|
286
|
+
/** What the deep-link use case needs to know about this deck right now. */
|
|
287
|
+
private _linkContext;
|
|
235
288
|
private _readHash;
|
|
289
|
+
/** Watch for a stepping component arriving late, and replay the step at it.
|
|
290
|
+
*
|
|
291
|
+
* The trigger is the `data-steps` attribute a stepping component writes onto
|
|
292
|
+
* its slide when it connects: that mutation IS the moment a component
|
|
293
|
+
* capable of hearing a step appears. Watching it beats polling or waiting a
|
|
294
|
+
* fixed time, and beats asking every component to reach back into the deck.
|
|
295
|
+
*
|
|
296
|
+
* Armed only for a fragment that asks for a step, and disarmed at the first
|
|
297
|
+
* move the reader makes · their navigation outranks the link they opened. */
|
|
298
|
+
private _watchForLateSteps;
|
|
299
|
+
/** Replay the opening step now that something on the slide can receive it. */
|
|
300
|
+
private _replayPendingStep;
|
|
301
|
+
/** Stop waiting · the link was honoured, or the reader moved on themselves. */
|
|
302
|
+
private _forgetPendingStep;
|
|
236
303
|
private _writeHash;
|
|
237
304
|
private _onKey;
|
|
238
305
|
/** Lazy-import the help module the first time the user opens it. */
|
|
@@ -243,20 +310,33 @@ export declare class DeckRoot extends LitElement {
|
|
|
243
310
|
/** Lazy-import the overview module the first time the user opens it. */
|
|
244
311
|
private _renderOverviewIfActive;
|
|
245
312
|
private _maxSteps;
|
|
246
|
-
/**
|
|
247
|
-
*
|
|
248
|
-
*
|
|
313
|
+
/** Step count for ANY slide · the navigation model asks about the slide it is
|
|
314
|
+
* moving TO. Going back into the previous slide has to know that slide's
|
|
315
|
+
* last step BEFORE the move, which is why this is not limited to `current`.
|
|
316
|
+
* This is the `StepsOf` the domain takes. */
|
|
317
|
+
private _maxStepsFor;
|
|
318
|
+
/** The engine's own step count for a slide · `steps`/`data-steps` attribute,
|
|
319
|
+
* or a `deck-code[step-groups]` group count. Plugins extend it through their
|
|
320
|
+
* `steps` hook (see _maxStepsFor). */
|
|
249
321
|
private _baseMaxSteps;
|
|
322
|
+
/** Where the deck is, as the navigation model sees it. */
|
|
323
|
+
private get _position();
|
|
324
|
+
/** Apply a whole position decided by the domain.
|
|
325
|
+
*
|
|
326
|
+
* Slide AND step move together. The engine used to set them in two
|
|
327
|
+
* statements, so a plugin that DEFERS navigation (a View Transition) ran the
|
|
328
|
+
* second one against the old slide and the deferred move then reset the step
|
|
329
|
+
* to 0 · going back into a slide landed on step 0 instead of its last step.
|
|
330
|
+
* One value, applied once, cannot come apart that way. */
|
|
331
|
+
private _applyPosition;
|
|
332
|
+
private _moveTo;
|
|
250
333
|
private _advance;
|
|
251
334
|
private _back;
|
|
252
335
|
private _goTo;
|
|
253
|
-
private _goToNow;
|
|
254
336
|
private _goToCoords;
|
|
255
337
|
private _applyActive;
|
|
256
338
|
private _applyStep;
|
|
257
|
-
/**
|
|
258
|
-
* the overview grid, a black/white blanked screen, and the cover slide (the
|
|
259
|
-
* title slide has no business carrying a page number). */
|
|
339
|
+
/** Keep numbering on all slide layouts; hide it only in overlay modes. */
|
|
260
340
|
private _counterHidden;
|
|
261
341
|
private _updateUI;
|
|
262
342
|
updated(changed: PropertyValues<this>): void;
|