@lark-apaas/coding-registry-buildless 0.1.19 → 0.1.20-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/coding-registry-buildless",
3
- "version": "0.1.19",
3
+ "version": "0.1.20-beta.0",
4
4
  "description": "Miaoda registry (buildless runtime) — shadcn-style copy-in SDKs (globals + CDN-pinned, browser Babel) for buildless static HTML stacks",
5
5
  "type": "module",
6
6
  "files": [
@@ -152,6 +152,47 @@
152
152
  const KEEP_LIVE_PREFIXES = ['cd-'];
153
153
  const keepsCloneLive = (el) => KEEP_LIVE_PREFIXES.some((p) => el.localName.startsWith(p));
154
154
 
155
+ /* Why a clone needs a substrate rule of its own: _collectAuthorCss samples
156
+ * document.styleSheets, which never lists a shadow root's styles, so a clone
157
+ * gets 100% of the author's CSS and 0% of deck-stage's. That split is deliberate
158
+ * (no .rail / .thumb / .stage chrome inside a clone) but it halves a neutralising
159
+ * pair — author `html { background }` travels and _applyAuthorCss's :host alias
160
+ * lands it right under the clone, while the substrate that covers it on the
161
+ * stage cannot travel at all.
162
+ * Read off the live stage, never restated here: a second declaration stops
163
+ * matching the moment a mode selector or a theme moves the real one (the reason
164
+ * _syncThumbHostAttrs mirrors computed values rather than stylesheet text).
165
+ * !important costs the author every override of this one property, their own
166
+ * !important included. Intended: the substrate belongs to whoever renders the
167
+ * slide. Specificity can't carry it alone — the alias is zeroed to :where(:host)
168
+ * so a plain rule wins, but importance outranks specificity. Own sheet rather
169
+ * than appended to the author snapshot, so their CSS stays verbatim. */
170
+ const cloneBaseCss = (substrate) => ':host { background: ' + substrate + ' !important; }';
171
+
172
+ /* Alpha is pulled out of the serialisation, never pattern-matched at the end of
173
+ * the string: a trailing-", 0)" test also fires on every opaque colour whose
174
+ * blue channel is zero (rgb(255, 0, 0), rgb(0, 0, 0)), skipping a layer that
175
+ * does paint.
176
+ * Two serialisations to read, because computed background-color drops the
177
+ * authored notation only for sRGB: hex, named colours, hsl(), transparent and
178
+ * light-dark() all come back as rgb()/rgba() with comma-separated alpha, while
179
+ * anything wider keeps its own function and puts alpha after a slash —
180
+ * oklch(L C H / 0), color(srgb 1 0 0 / 0), oklab(…) from color-mix(). Only the
181
+ * host end of _slideSubstrate's chain is author-styleable, but that is enough
182
+ * for a transparent wide-gamut colour to reach here. Unknown shapes count as
183
+ * opaque: they at least give the clone a substrate. */
184
+ const alphaOf = (bg) => {
185
+ const slashed = /\/\s*([0-9.eE+-]+)(%?)\s*\)\s*$/.exec(bg);
186
+ if (slashed) return parseFloat(slashed[1]) / (slashed[2] ? 100 : 1);
187
+ const legacy = /^rgba?\(([^)]*)\)$/.exec(bg);
188
+ if (legacy) {
189
+ const parts = legacy[1].split(',');
190
+ if (parts.length === 4) return parseFloat(parts[3]);
191
+ }
192
+ return 1;
193
+ };
194
+ const paintsNothing = (bg) => !bg || bg === 'transparent' || alphaOf(bg) === 0;
195
+
155
196
  // Mirrors the host platform's isMobile() (UA regex + iPad maxTouchPoints);
156
197
  // the product iframe is cross-origin, so the shared helper can't be
157
198
  // imported. Deliberately NOT viewport-based: the desktop workbench renders
@@ -220,6 +261,7 @@
220
261
  position: relative;
221
262
  transform-origin: center center;
222
263
  flex-shrink: 0;
264
+ /* Sole declaration of the slide substrate; _slideSubstrate reads it back. */
223
265
  background: #fff;
224
266
  will-change: transform;
225
267
  }
@@ -1044,9 +1086,10 @@
1044
1086
  * <deck-stage> ancestor, so a rule like `deck-stage section { background }`
1045
1087
  * (the common per-slide default-background idiom) would never match and
1046
1088
  * the clone renders with a transparent background — through which the
1047
- * page-level html/body background (rewritten to :host above) leaks. The
1048
- * thumb's own host IS the deck-stage from the clone's perspective, so
1049
- * alias deck-stage → :host to restore the match. */
1089
+ * thumb host shows. The thumb's own host IS the deck-stage from the clone's
1090
+ * perspective, so alias deck-stage → :host to restore the match. The alias
1091
+ * also lands a page-level html/:root background right under the clone, a spot
1092
+ * it never occupies on the stage — _mountCloneStyles covers that. */
1050
1093
  _applyAuthorCss(rawCss) {
1051
1094
  const authorCss = rawCss
1052
1095
  // The shadow host is featureless outside the functional :host(...)
@@ -1090,6 +1133,42 @@
1090
1133
  }
1091
1134
  }
1092
1135
 
1136
+ /** Not just .canvas: mobile browse and print clear it on purpose to expose the
1137
+ * layer behind, so walk the same layers the stage composites — and stop at the
1138
+ * host, because the next one up is the author's page background, the thing
1139
+ * that must never become a substrate. '' when nothing paints; only happens in
1140
+ * modes that render no clone, and the caller then adds no rule. */
1141
+ _slideSubstrate() {
1142
+ for (const el of [this._canvas, this._stage, this]) {
1143
+ if (!el) continue;
1144
+ const bg = getComputedStyle(el).backgroundColor;
1145
+ if (!paintsNothing(bg)) return bg;
1146
+ }
1147
+ return '';
1148
+ }
1149
+
1150
+ /** One base sheet shared by reference across every clone, so re-reading it on
1151
+ * each mount also re-levels clones built earlier — that is what carries a
1152
+ * mid-session theme change to thumbs already on screen. */
1153
+ _mountCloneStyles(sr) {
1154
+ const substrate = this._slideSubstrate();
1155
+ const baseCss = substrate ? cloneBaseCss(substrate) : '';
1156
+ if (this._adoptedSheet) {
1157
+ if (!this._cloneBaseSheet) this._cloneBaseSheet = new CSSStyleSheet();
1158
+ this._cloneBaseSheet.replaceSync(baseCss);
1159
+ sr.adoptedStyleSheets = [this._adoptedSheet, this._cloneBaseSheet];
1160
+ return;
1161
+ }
1162
+ // replaceSync threw — fall back to inline <style>, one per sheet so the
1163
+ // author's text stays a verbatim block.
1164
+ const author = document.createElement('style');
1165
+ author.textContent = this._authorCss || '';
1166
+ sr.appendChild(author);
1167
+ const base = document.createElement('style');
1168
+ base.textContent = baseCss;
1169
+ sr.appendChild(base);
1170
+ }
1171
+
1093
1172
  _syncThumbHostAttrs(host, cs) {
1094
1173
  const de = document.documentElement;
1095
1174
  // setAttribute overwrites but can't delete — an attr removed from
@@ -2368,12 +2447,7 @@
2368
2447
  host.style.cssText = 'position:absolute;inset:0;';
2369
2448
  this._syncThumbHostAttrs(host);
2370
2449
  const sr = host.attachShadow({ mode: 'open' });
2371
- if (this._adoptedSheet) sr.adoptedStyleSheets = [this._adoptedSheet];
2372
- else {
2373
- const st = document.createElement('style');
2374
- st.textContent = this._authorCss || '';
2375
- sr.appendChild(st);
2376
- }
2450
+ this._mountCloneStyles(sr);
2377
2451
  if (entry.clone) sr.appendChild(entry.clone.cloneNode(true));
2378
2452
  card.appendChild(host);
2379
2453
  wrap.appendChild(card);
@@ -2480,12 +2554,7 @@
2480
2554
  host.style.cssText = 'position:absolute;inset:0;';
2481
2555
  this._syncThumbHostAttrs(host);
2482
2556
  const sr = host.attachShadow({ mode: 'open' });
2483
- if (this._adoptedSheet) sr.adoptedStyleSheets = [this._adoptedSheet];
2484
- else {
2485
- const st = document.createElement('style');
2486
- st.textContent = this._authorCss || '';
2487
- sr.appendChild(st);
2488
- }
2557
+ this._mountCloneStyles(sr);
2489
2558
  sr.appendChild(clone);
2490
2559
  entry.frame.appendChild(host);
2491
2560
  entry.host = host;