@lark-apaas/coding-registry-buildless 0.1.21 → 0.1.23
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/components/design-canvas.jsx +5 -5
- package/components/tweaks-panel.jsx +8 -5
- package/package.json +1 -1
- package/scripts/android-frame.js +253 -0
- package/scripts/browser-window.js +246 -0
- package/scripts/deck-stage.js +63 -23
- package/scripts/design-canvas.js +2189 -0
- package/scripts/ios-frame.js +338 -0
- package/scripts/macos-window.js +260 -0
package/scripts/deck-stage.js
CHANGED
|
@@ -35,9 +35,10 @@
|
|
|
35
35
|
* a `deckchange`
|
|
36
36
|
* CustomEvent on the element: detail = {action, from, to, slide}.
|
|
37
37
|
* (g) mobile — on mobile devices the same deck automatically renders as
|
|
38
|
-
* a scrollable vertical card list (browse) and a
|
|
39
|
-
*
|
|
40
|
-
* mobile/responsive slide layouts.
|
|
38
|
+
* a scrollable vertical card list (browse) and a fullscreen presenting
|
|
39
|
+
* mode, pseudo-landscape or upright as the host asks. This needs NO
|
|
40
|
+
* authoring changes: never hand-roll mobile/responsive slide layouts.
|
|
41
|
+
* Desktop behaviour is unchanged.
|
|
41
42
|
* Browse mode renders each slide's static base state and never fires
|
|
42
43
|
* entrance animations — exactly like the thumbnail rail and print
|
|
43
44
|
* (presenting keeps animations). One more surface that requires the
|
|
@@ -224,7 +225,15 @@
|
|
|
224
225
|
* reuses. It costs one thing — render() also resets that img's `sizes`,
|
|
225
226
|
* discarding the rail-width hint _materialize sets; the URL still matches the
|
|
226
227
|
* slide's, so the thumb reuses the slide's decoded bitmap. */
|
|
227
|
-
|
|
228
|
+
/* The device frames (ios-/android-/macos-/browser-) get in on the *other* half
|
|
229
|
+
* of the rule. Their content lives in a shadow root, so cloneNode captures none
|
|
230
|
+
* of it — for them re-mounting is not "adds nothing", it is the only way to get
|
|
231
|
+
* the content at all. They do satisfy clause 2: purely presentational, read
|
|
232
|
+
* attributes and paint the shadow, no storage and no messages.
|
|
233
|
+
* design-canvas is deliberately NOT on this list — it reads localStorage,
|
|
234
|
+
* fetches its sidecar and posts to the host on mount, so running it once per
|
|
235
|
+
* thumbnail would corrupt the real state. */
|
|
236
|
+
const KEEP_LIVE_PREFIXES = ['cd-', 'ios-', 'android-', 'macos-', 'browser-'];
|
|
228
237
|
const keepsCloneLive = (el) => KEEP_LIVE_PREFIXES.some((p) => el.localName.startsWith(p));
|
|
229
238
|
|
|
230
239
|
/* Why a clone needs a substrate rule of its own: _collectAuthorCss samples
|
|
@@ -607,11 +616,13 @@
|
|
|
607
616
|
Rotate only while the device is physically portrait. Once the user
|
|
608
617
|
turns the phone (system auto-rotate) the viewport itself is landscape,
|
|
609
618
|
and stacking another 90° would render slides sideways — so landscape
|
|
610
|
-
falls back to a plain full-bleed fit.
|
|
611
|
-
|
|
619
|
+
falls back to a plain full-bleed fit. data-present-portrait is the
|
|
620
|
+
host asking for an upright presentation, which suppresses the rotation
|
|
621
|
+
on a portrait device too. This selector is the third copy of the
|
|
622
|
+
predicate in _presentRotated — keep all three in phase. */
|
|
612
623
|
:host([data-mobile-present]) .stage { background: #000; }
|
|
613
624
|
@media (orientation: portrait) {
|
|
614
|
-
:host([data-mobile-present]) .stage {
|
|
625
|
+
:host([data-mobile-present]:not([data-present-portrait])) .stage {
|
|
615
626
|
inset: auto;
|
|
616
627
|
left: 50%;
|
|
617
628
|
top: 50%;
|
|
@@ -882,6 +893,10 @@
|
|
|
882
893
|
this._snthumb = /[?&](_snthumb|thumbnail)=/.test(location.search);
|
|
883
894
|
this._preflight = /[?&]preflight=/.test(location.search);
|
|
884
895
|
this._mobile = isMobileUA();
|
|
896
|
+
// Orientation the host asked presenting to enter in. Sticky: only a
|
|
897
|
+
// message that actually carries `orientation` moves it, so replays and
|
|
898
|
+
// any other bare {on} message leave the current orientation alone.
|
|
899
|
+
this._presentPortrait = false;
|
|
885
900
|
// Layout-driven size signal. window.resize is unreliable inside
|
|
886
901
|
// prerendered/reframed iOS WebViews and host-managed iframes — the
|
|
887
902
|
// frame can change size without any resize event, leaving a layout
|
|
@@ -1896,7 +1911,17 @@
|
|
|
1896
1911
|
_syncMobileMode() {
|
|
1897
1912
|
const eligible = (this._mobile || this._preflight) && !this.hasAttribute('noscale') && !this._snthumb;
|
|
1898
1913
|
this.toggleAttribute('data-mobile-list', eligible && !this._presenting);
|
|
1899
|
-
|
|
1914
|
+
const present = eligible && !!this._presenting && !this._preflight;
|
|
1915
|
+
this.toggleAttribute('data-mobile-present', present);
|
|
1916
|
+
this.toggleAttribute('data-present-portrait', present && this._presentPortrait);
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
// Single source of truth for "is the presenting stage CSS-rotated?".
|
|
1920
|
+
// Read by the fit and the tap zones; the @media (orientation: portrait)
|
|
1921
|
+
// rule above is the same predicate spelled in CSS, reached through the
|
|
1922
|
+
// data-present-portrait attribute _syncMobileMode derives from this state.
|
|
1923
|
+
_presentRotated() {
|
|
1924
|
+
return !this._presentPortrait && window.innerHeight >= window.innerWidth;
|
|
1900
1925
|
}
|
|
1901
1926
|
|
|
1902
1927
|
_fitMobileList() {
|
|
@@ -2037,12 +2062,12 @@
|
|
|
2037
2062
|
this.removeAttribute('data-windowed');
|
|
2038
2063
|
this._canvas.style.width = this.designWidth + 'px';
|
|
2039
2064
|
this._canvas.style.height = this.designHeight + 'px';
|
|
2040
|
-
//
|
|
2041
|
-
//
|
|
2042
|
-
//
|
|
2043
|
-
const
|
|
2044
|
-
const lw =
|
|
2045
|
-
const lh =
|
|
2065
|
+
// Rotated: the stage is CSS-rotated, so its logical size is the swapped
|
|
2066
|
+
// viewport. Otherwise (device already landscape, or the host asked for
|
|
2067
|
+
// an upright presentation) it is a plain fit into the viewport.
|
|
2068
|
+
const rotated = this._presentRotated();
|
|
2069
|
+
const lw = rotated ? window.innerHeight : window.innerWidth;
|
|
2070
|
+
const lh = rotated ? window.innerWidth : window.innerHeight;
|
|
2046
2071
|
const s = Math.min(lw / this.designWidth, lh / this.designHeight);
|
|
2047
2072
|
this._canvas.style.transform = 'scale(' + s + ')';
|
|
2048
2073
|
}
|
|
@@ -2121,13 +2146,25 @@
|
|
|
2121
2146
|
_onMessage(e) {
|
|
2122
2147
|
const d = e.data;
|
|
2123
2148
|
if (d && d.type === 'miaoda:deck:presenting' && typeof d.on === 'boolean') {
|
|
2149
|
+
// orientation is optional and sticky — the host owns it end to end, and
|
|
2150
|
+
// a message that omits it (a mirror replay, or a host that predates the
|
|
2151
|
+
// field) means "unchanged", never "back to landscape". Absent field on
|
|
2152
|
+
// a fresh deck therefore keeps the historical rotate-on-portrait
|
|
2153
|
+
// behaviour, which is what the default has to be.
|
|
2154
|
+
const portrait = d.orientation === 'portrait';
|
|
2155
|
+
const flipped = d.orientation != null && portrait !== this._presentPortrait;
|
|
2156
|
+
if (d.orientation != null) this._presentPortrait = portrait;
|
|
2124
2157
|
// Same-value messages (incl. mirror replays routed back through here)
|
|
2125
2158
|
// must not re-run the layout work or re-emit. _presenting starts
|
|
2126
|
-
// undefined, so the first message always lands.
|
|
2127
|
-
|
|
2159
|
+
// undefined, so the first message always lands. The one same-value
|
|
2160
|
+
// case that still has to land is an orientation flip while presenting:
|
|
2161
|
+
// it carries the same `on` but needs the relayout.
|
|
2162
|
+
if (d.on === this._presenting && !(flipped && d.on)) return;
|
|
2128
2163
|
this._presenting = d.on;
|
|
2129
2164
|
this._syncMobileMode();
|
|
2130
|
-
|
|
2165
|
+
// Leaving presenting, or flipping to upright (which has no control
|
|
2166
|
+
// layer at all), both have to take an open one down with them.
|
|
2167
|
+
if (!d.on || this._presentPortrait) this._toggleMobUi(false);
|
|
2131
2168
|
this._syncRailHidden();
|
|
2132
2169
|
this._syncNotesHidden();
|
|
2133
2170
|
this._closeMenu();
|
|
@@ -2221,8 +2258,12 @@
|
|
|
2221
2258
|
e.preventDefault();
|
|
2222
2259
|
if (this.hasAttribute('data-mobile-present')) {
|
|
2223
2260
|
const zone = this._mobPresentZone(e);
|
|
2224
|
-
if (zone === 'menu')
|
|
2225
|
-
|
|
2261
|
+
if (zone === 'menu') {
|
|
2262
|
+
// Upright presenting ships no control layer: the host owns the exit
|
|
2263
|
+
// chrome and the page navigation there, so the middle third stays
|
|
2264
|
+
// inert rather than offering a second, conflicting way in.
|
|
2265
|
+
if (!this._presentPortrait) this._toggleMobUi();
|
|
2266
|
+
} else {
|
|
2226
2267
|
this._advance(zone === 'prev' ? -1 : 1, 'tap');
|
|
2227
2268
|
if (this.hasAttribute('data-mob-ui')) this._toggleMobUi(true);
|
|
2228
2269
|
}
|
|
@@ -2238,10 +2279,9 @@
|
|
|
2238
2279
|
// these comparisons — single point of change).
|
|
2239
2280
|
_mobPresentZone(e) {
|
|
2240
2281
|
const rect = this._stage.getBoundingClientRect();
|
|
2241
|
-
//
|
|
2242
|
-
//
|
|
2243
|
-
const
|
|
2244
|
-
const x = portrait
|
|
2282
|
+
// Rotated stage = the visual x axis comes from viewport y; unrotated =
|
|
2283
|
+
// viewport x directly. Same predicate as the fit.
|
|
2284
|
+
const x = this._presentRotated()
|
|
2245
2285
|
? (e.clientY - rect.top) / Math.max(1, rect.height)
|
|
2246
2286
|
: (e.clientX - rect.left) / Math.max(1, rect.width);
|
|
2247
2287
|
return x < 1 / 3 ? 'prev' : x > 2 / 3 ? 'next' : 'menu';
|