@livx.cc/appwrap 0.61.16 → 0.61.18

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": "@livx.cc/appwrap",
3
- "version": "0.61.16",
3
+ "version": "0.61.18",
4
4
  "description": "Wrap any PWA into a native app with native capabilities (appwrap runtime + @livx.cc/native-kit).",
5
5
  "license": "MIT",
6
6
  "author": "Elya Livshitz",
@@ -93,7 +93,14 @@ function registerIos(): void {
93
93
  ] as any);
94
94
 
95
95
  ObserverClass ??= (NSObject as any).extend(
96
- { observeValueForKeyPathOfObjectChangeContext() { emitState(); } },
96
+ {
97
+ observeValueForKeyPathOfObjectChangeContext() {
98
+ // Shell-coloured + non-opaque only to avoid a white flash before the first load; after it, WebKit
99
+ // must paint the page's own canvas, or a page with no background shows the (dark) shell through.
100
+ if (wv && !wv.opaque && !wv.loading && wv.URL) wv.opaque = true;
101
+ emitState();
102
+ },
103
+ },
97
104
  { name: 'AppwrapWebViewOverlayObserver' }
98
105
  );
99
106
  observer = ObserverClass.new();
@@ -205,22 +205,33 @@ function armIosKeyboardObservers(): void {
205
205
  armScrollClamp();
206
206
  }
207
207
 
208
+ /** The page's colour where the keyboard meets it: the first opaque background up from the element at the
209
+ * bottom-centre (then body/html). A transparent body (rgba(0,0,0,0)) must not read as black. */
210
+ const BOTTOM_BG_JS = `(() => {
211
+ const op = (c) => c && !/^rgba\\(.*,\\s*0\\)$/.test(c) && c !== 'transparent';
212
+ for (let e = document.elementFromPoint(innerWidth / 2, innerHeight - 2); e; e = e.parentElement) { const c = getComputedStyle(e).backgroundColor; if (op(c)) return c; }
213
+ for (const e of [document.body, document.documentElement]) { const c = e && getComputedStyle(e).backgroundColor; if (op(c)) return c; }
214
+ return '';
215
+ })()`;
216
+
208
217
  /**
209
- * Sample the page's background color once per keyboard-show and paint the webview + its window with
218
+ * Sample the page's bottom background color once per keyboard-show and paint the webview + its window with
210
219
  * it (Capacitor's autoBackdropColor) so there are no white flashes during the resize.
211
220
  */
212
221
  function syncBackdropColor(): void {
213
222
  try {
214
223
  const wk = bridge.getWebView()?.ios as WKWebView | undefined;
215
224
  if (!wk) return;
216
- wk.evaluateJavaScriptCompletionHandler('window.getComputedStyle(document.body).backgroundColor', (result: any) => {
225
+ wk.evaluateJavaScriptCompletionHandler(BOTTOM_BG_JS, (result: any) => {
217
226
  const m = /rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/.exec(String(result ?? ''));
218
227
  if (!m) return;
219
228
  Utils.dispatchToMainThread(() => {
220
229
  const w = bridge.getWebView()?.ios as WKWebView | undefined;
221
230
  if (!w) return;
222
231
  const color = UIColor.colorWithRedGreenBlueAlpha(+m[1] / 255, +m[2] / 255, +m[3] / 255, 1);
223
- w.backgroundColor = color;
232
+ // The keyboard's rounded corners (iOS 26) show whatever native view is behind the webview — paint
233
+ // the whole chain up to the window, not only the webview + window (a dark host view showed through).
234
+ for (let v: UIView | null = w; v; v = v.superview) v.backgroundColor = color;
224
235
  if (w.window) w.window.backgroundColor = color;
225
236
  if (SHELL_CONFIG.debug) appwrapNativeLog(`[native:keyboard] backdrop ← rgb(${m[1]},${m[2]},${m[3]})`);
226
237
  });