@webview-native-ui/engine 0.0.7 → 1.0.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/dist/native/session.js
CHANGED
|
@@ -83,6 +83,18 @@ export const startNativeSession = async (config, nativeBridge, plugin = {
|
|
|
83
83
|
const placementOwner = {};
|
|
84
84
|
let coveredToken;
|
|
85
85
|
let placementEpoch = 0;
|
|
86
|
+
const releases = new Set();
|
|
87
|
+
let cancelReleaseWait = () => { };
|
|
88
|
+
let releaseCancellation = new Promise((resolve) => {
|
|
89
|
+
cancelReleaseWait = resolve;
|
|
90
|
+
});
|
|
91
|
+
const cancelReleases = () => {
|
|
92
|
+
releases.clear();
|
|
93
|
+
cancelReleaseWait();
|
|
94
|
+
releaseCancellation = new Promise((resolve) => {
|
|
95
|
+
cancelReleaseWait = resolve;
|
|
96
|
+
});
|
|
97
|
+
};
|
|
86
98
|
const clearPlacement = () => {
|
|
87
99
|
placementEpoch++;
|
|
88
100
|
coveredToken = undefined;
|
|
@@ -105,6 +117,28 @@ export const startNativeSession = async (config, nativeBridge, plugin = {
|
|
|
105
117
|
send: (request) => {
|
|
106
118
|
if (!config.placementHandoff)
|
|
107
119
|
return nativeBridge.send(request);
|
|
120
|
+
if (request.action === 'visibility' && !request.visible)
|
|
121
|
+
cancelReleases();
|
|
122
|
+
if (request.action === 'visibility' && request.visible && releases.size) {
|
|
123
|
+
const version = generation;
|
|
124
|
+
const epoch = placementEpoch;
|
|
125
|
+
const host = target;
|
|
126
|
+
const cancellation = releaseCancellation;
|
|
127
|
+
// All reveal paths (including scroll fallback) wait for idle release's placement/draw ACK.
|
|
128
|
+
// Re-enter to include releases added while waiting. Hide/teardown cancels the wait.
|
|
129
|
+
return Promise.race([Promise.allSettled([...releases]), cancellation]).then(() => {
|
|
130
|
+
if (stopped ||
|
|
131
|
+
cancellation !== releaseCancellation ||
|
|
132
|
+
version !== generation ||
|
|
133
|
+
epoch !== placementEpoch ||
|
|
134
|
+
host !== target ||
|
|
135
|
+
!host?.isConnected ||
|
|
136
|
+
findTarget() !== target ||
|
|
137
|
+
effectiveDestination() !== 'native')
|
|
138
|
+
return {};
|
|
139
|
+
return bridge.send(request);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
108
142
|
const binding = projectionPlacement(target);
|
|
109
143
|
if (request.action === 'cover') {
|
|
110
144
|
const alreadyCovered = coveredToken === request.token && binding?.owner === placementOwner && binding.projected;
|
|
@@ -146,7 +180,7 @@ export const startNativeSession = async (config, nativeBridge, plugin = {
|
|
|
146
180
|
const payload = revealing && binding?.owner === placementOwner
|
|
147
181
|
? { ...request, token: ('token' in request ? request.token : coveredToken), placement: binding.measure() }
|
|
148
182
|
: request;
|
|
149
|
-
|
|
183
|
+
const pending = nativeBridge
|
|
150
184
|
.send(payload)
|
|
151
185
|
.then(async (result) => {
|
|
152
186
|
// A native drag can race retirement before its notification reaches JS.
|
|
@@ -169,6 +203,10 @@ export const startNativeSession = async (config, nativeBridge, plugin = {
|
|
|
169
203
|
failed();
|
|
170
204
|
throw error;
|
|
171
205
|
});
|
|
206
|
+
if (request.action !== 'release' || !config.nativeDragHandoff)
|
|
207
|
+
return pending;
|
|
208
|
+
releases.add(pending);
|
|
209
|
+
return pending.finally(() => releases.delete(pending));
|
|
172
210
|
}
|
|
173
211
|
catch (error) {
|
|
174
212
|
failed();
|
|
@@ -361,7 +399,7 @@ export const startNativeSession = async (config, nativeBridge, plugin = {
|
|
|
361
399
|
if (destination === 'native') {
|
|
362
400
|
const version = generation;
|
|
363
401
|
await bridge.send({ action: 'visibility', visible: true });
|
|
364
|
-
if (stopped || version !== generation || destination !== 'native')
|
|
402
|
+
if (stopped || version !== generation || destination !== 'native' || automaticMotion)
|
|
365
403
|
return;
|
|
366
404
|
setVisibility();
|
|
367
405
|
scrollOwner = [...projectionAncestors(target)].find((element) => {
|
|
@@ -582,6 +620,7 @@ export const startNativeSession = async (config, nativeBridge, plugin = {
|
|
|
582
620
|
if (stopped)
|
|
583
621
|
return;
|
|
584
622
|
stopped = true;
|
|
623
|
+
cancelReleases();
|
|
585
624
|
retireValueRead();
|
|
586
625
|
clearPlacement();
|
|
587
626
|
generation++;
|
|
@@ -643,6 +682,7 @@ export const startNativeSession = async (config, nativeBridge, plugin = {
|
|
|
643
682
|
hide: () => {
|
|
644
683
|
requestedDestination = destination = 'none';
|
|
645
684
|
generation++;
|
|
685
|
+
cancelReleases();
|
|
646
686
|
automaticMotion = false;
|
|
647
687
|
nativeDragging = false;
|
|
648
688
|
clearTimeout(scrollTimer);
|
|
Binary file
|
|
Binary file
|
package/docs/maintenance.md
CHANGED
|
@@ -13,7 +13,7 @@ The public entry points are `src/index.ts` and `src/ionic.ts`, with shared contr
|
|
|
13
13
|
- `src/projection/`: image handoff, projection ownership, events and styles.
|
|
14
14
|
- `src/dom/`: geometry, scrolling, visibility and overlay coordination.
|
|
15
15
|
|
|
16
|
-
`npm run build` bundles `src/native/bootstrap.ts` into `runtime/native-ui-engine.js`, the shared WebView runtime. Android packages this file directly as an asset. The build also copies it into `ios/Sources/WebViewNativeUIEngine/Resources` because SwiftPM requires resources inside the target directory. Both generated files are
|
|
16
|
+
`npm run build` bundles `src/native/bootstrap.ts` into `runtime/native-ui-engine.js`, the shared WebView runtime. Android packages this file directly as an asset. The build also copies it into `ios/Sources/WebViewNativeUIEngine/Resources` because SwiftPM requires resources inside the target directory. Both generated files are ignored during development and included in release tags so SwiftPM consumers do not need Node.js. Run `npm run build` before building a source checkout with Xcode. Edit the TypeScript source, not either generated file; CI checks regeneration and verifies the runtime included in npm and Maven archives.
|
|
17
17
|
|
|
18
18
|
Browser tests mirror these groups under `tests/`. `tests/cordova/` contains the real native consumer fixture.
|
|
19
19
|
|
|
@@ -40,7 +40,7 @@ CI-only setup, packaging commands and GitHub outputs are defined in `.github/wor
|
|
|
40
40
|
|
|
41
41
|
## Maven publication
|
|
42
42
|
|
|
43
|
-
The `Native UI Engine Maven Release` workflow is manually dispatched on
|
|
43
|
+
The `Native UI Engine Maven Release` workflow is manually dispatched on the release tag with the exact engine package version. The tagged commit must first pass `Native UI Engine` CI. It signs an AAR, source archive, generated Kotlin API documentation and Maven metadata, uploads once, and completes when Central reports `PUBLISHING` or `PUBLISHED`. The deployment ID and state changes are recorded in the run summary. `PUBLISHING` means validation passed and Central accepted publication; it does not guarantee that artifacts can already be downloaded. This workflow does not wait for distribution. The npm release checks that this workflow succeeded for the exact release commit; it does not wait for Maven Central distribution. Existing coordinates are never overwritten; if an upload times out, inspect the recorded deployment in Central before taking further action.
|
|
44
44
|
|
|
45
45
|
Configure the repository's Actions secrets with `CENTRAL_USERNAME`, `CENTRAL_PASSWORD` (a Central user token), `MAVEN_SIGNING_KEY` (ASCII-armored private key) and `MAVEN_SIGNING_PASSWORD`. The signing public key must be available to Central. GitHub secrets are scoped to this repository.
|
|
46
46
|
|
|
@@ -53,12 +53,30 @@ versions across these distributions.
|
|
|
53
53
|
|
|
54
54
|
The npm organization `webview-native-ui` and Maven Central namespace `io.github.webview-native-ui` are registered. Maintain npm trusted publishing for `webview-native-ui/engine`, workflow `release.yml`, and provision the Maven secrets above in this repository. Credentials are not copied by moving source files.
|
|
55
55
|
|
|
56
|
-
1. Prepare
|
|
57
|
-
2.
|
|
58
|
-
3.
|
|
56
|
+
1. Run **Prepare release** (`prepare-release.yml`) on `main` and select `major`, `minor`, `patch` or `revision`. No local build, commit or tag is needed.
|
|
57
|
+
2. The workflow increments the version using npm, builds and verifies the package, and pushes a version-only main commit plus a separate release commit/tag containing the generated resources. It explicitly starts `Native UI Engine` validation on that tag and creates a GitHub Release draft with generated release notes.
|
|
58
|
+
3. Review and edit the release notes. After tag validation passes, dispatch `native-ui-engine-release.yml` on that tag with the exact package version.
|
|
59
|
+
4. Once Maven publication succeeds, publish the GitHub Release draft. Central `PUBLISHING` means upload acceptance, not download readiness; mention any pending Android distribution in the notes. `release.yml` verifies the tag, package version, tag CI and Maven acceptance before publishing to npm (`next` for revisions, `latest` for stable releases).
|
|
60
|
+
|
|
61
|
+
Version increments follow npm SemVer rules; `revision` maps to `prerelease`:
|
|
62
|
+
|
|
63
|
+
| Current | Selection | Next |
|
|
64
|
+
| --------- | --------- | --------- |
|
|
65
|
+
| `1.2.3` | major | `2.0.0` |
|
|
66
|
+
| `1.2.3` | minor | `1.3.0` |
|
|
67
|
+
| `1.2.3` | patch | `1.2.4` |
|
|
68
|
+
| `1.2.3` | revision | `1.2.4-0` |
|
|
69
|
+
| `1.2.4-0` | revision | `1.2.4-1` |
|
|
70
|
+
| `1.2.4-2` | patch | `1.2.4` |
|
|
71
|
+
| `1.3.0-2` | minor | `1.3.0` |
|
|
72
|
+
| `2.0.0-2` | major | `2.0.0` |
|
|
73
|
+
|
|
74
|
+
Generated runtime commits never enter main's history. The CI preparation pushes main and the release tag atomically, without force. Publication accepts only a tagged child of main that adds the two generated resources and changes no other files. npm rebuilds and checks the runtime before publication; Maven packages the runtime from the same tested tag.
|
|
75
|
+
|
|
76
|
+
If preparation fails before pushing, rerun it. If main and the tag were already pushed, do not rerun preparation (that requests another version) or move the tag. Manually run `Native UI Engine` on the existing tag if validation was not started, and create the release draft for that tag if it is missing. This also recovers a failure between the push, validation dispatch and draft creation. Existing tags and published artifacts are never overwritten.
|
|
59
77
|
|
|
60
78
|
No build or test command publishes a package. Existing npm/Maven versions are never overwritten.
|
|
61
79
|
|
|
62
|
-
To rerun release verification for an existing tag,
|
|
80
|
+
To rerun release verification for an existing tag, select that tag as both the workflow ref and the `tag` input: `gh workflow run release.yml --ref vX.Y.Z -f tag=vX.Y.Z`. This uses the workflow saved in that release, including for older tags that predate the release-only commit layout. It checks the original tagged commit and skips npm publication only when the existing package contents match. Keep the tag unchanged. Release tooling uses the Node.js 24 bundled npm, matching CI.
|
|
63
81
|
|
|
64
82
|
[Documentation overview](README.md)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var WebViewNativeUIEngineRuntime=(()=>{var
|
|
1
|
+
"use strict";var WebViewNativeUIEngineRuntime=(()=>{var Ge=Object.defineProperty;var ut=Object.getOwnPropertyDescriptor;var ft=Object.getOwnPropertyNames;var pt=Object.prototype.hasOwnProperty;var mt=(t,r)=>{for(var o in r)Ge(t,o,{get:r[o],enumerable:!0})},vt=(t,r,o,v)=>{if(r&&typeof r=="object"||typeof r=="function")for(let y of ft(r))!pt.call(t,y)&&y!==o&&Ge(t,y,{get:()=>r[y],enumerable:!(v=ut(r,y))||v.enumerable});return t};var ht=t=>vt(Ge({},"__esModule",{value:!0}),t);var Ot={};mt(Ot,{hide:()=>kt,notify:()=>Mt,receive:()=>xt,show:()=>Ht,start:()=>Ct,stop:()=>Rt});var tt=(t,r,o)=>{for(let[v,y]of Object.entries(r)){if(!/^[a-z][a-z0-9-]*$/.test(v))throw new TypeError("Native value keys must be lowercase attribute names");let f=(Object.hasOwn(o,v)?o[v]:void 0)?.property;if(f&&(!/^[a-zA-Z][\w]*$/.test(f)||/^on/i.test(f)||["innerHTML","outerHTML","textContent","innerText","style","constructor","prototype"].includes(f)))throw new TypeError("Native value binding requires a data property");let P=JSON.stringify(y);if(P===void 0)throw new TypeError("Native values must be JSON values");if(f){let p=t;JSON.stringify(p[f])!==P&&(p[f]=y)}else{let p=`data-native-ui-value-${v}`,M=typeof y=="string"?y:P;t.getAttribute(p)!==M&&t.setAttribute(p,M)}}};var yt=Symbol.for("webview-native-ui-engine.projection-placement");var Ue=t=>t?.[yt];var gt=(t,r)=>{if(t.matches("ion-toast, ion-menu"))return!1;let o=t;if(o.showBackdrop===!1)return!1;if(!t.matches("ion-modal"))return!0;let v=r??o.initialBreakpoint;return v===void 0||v>(o.backdropBreakpoint??0)},wt=Symbol.for("@webview-native-ui/engine/overlays/v1"),bt=t=>{let r=new Set,o=new Set,v=new Set,y=new WeakMap,m=new WeakSet,f=new Map,P=[],p={},M=new Map,x,j=g=>{for(let d of[...v])try{d(g)}catch(w){console.error("Native UI overlay listener failed",w)}},B=(g,d,w)=>{d==="willPresent"||d==="didPresent"?(m.delete(g),r.add(g)):d==="didDismiss"&&(m.add(g),r.delete(g),o.delete(g),y.delete(g));let c=w?.detail?.breakpoint;typeof c=="number"&&c>0&&y.set(g,c),j({element:g,phase:d,event:w})},k=(g=!1)=>{let d=!1;for(let w of r)(!w.isConnected||w.ownerDocument!==t||!P.some(({selector:c})=>w.matches(c)))&&(r.delete(w),o.delete(w),d=!0);for(let w of t.querySelectorAll(P.map(({selector:c})=>c).join(",")))!r.has(w)&&!m.has(w)&&(g||!w.matches("ion-popover"))&&(w.presented||w.classList.contains("show-menu"))&&(r.add(w),d=!0);d&&j({phase:"change"})};return{get active(){return r},subscribe(g){return v.add(g),()=>{v.delete(g)}},setNative(g,d){o.has(g)!==d&&(d?o.add(g):o.delete(g),j({element:g,phase:"change"}))},isExcluded(g){return!!p.exclude&&g.matches(p.exclude)},isNative(g){return o.has(g)},get stack(){let g=[...r].filter(w=>w.isConnected&&w.ownerDocument===t),d=w=>{let c=Number.parseFloat(t.defaultView.getComputedStyle(w).zIndex);return Number.isFinite(c)?c:w.overlayIndex??0};return g.sort((w,c)=>d(w)-d(c)),g},isCovered(g){let d=this.stack,w=d.reduce((c,W,R)=>W.contains(g)?R:c,-1);return d.some((c,W)=>{if(o.has(c)||p.exclude&&c.matches(p.exclude))return!1;let R=p.covers?.(c,g);return R!==void 0?R:W>w&&!c.contains(g)&&(c.matches("ion-menu")||gt(c,y.get(c)))})},enable(g,d){let w={...p,...d},c=[...g,...w.additional??[]];w.exclude&&t.querySelector(w.exclude);let W=new Map;for(let l of c){t.querySelector(l.selector);for(let[V,$]of Object.entries(l.events)){let G=W.get($);if(G&&G.phase!==V)throw new TypeError(`Overlay event "${$}" has conflicting phases`);W.set($,{phase:V,selector:G?`${G.selector}, ${l.selector}`:l.selector})}}p=w,P=c,M=W;for(let l of M.keys()){if(f.has(l))continue;let V=$=>{let G=M.get(l),ye=$.composedPath().find(J=>J instanceof t.defaultView.HTMLElement&&J.matches(G.selector));ye&&B(ye,G.phase,$)};t.addEventListener(l,V,!0),f.set(l,()=>t.removeEventListener(l,V,!0))}for(let[l,V]of f)M.has(l)||(V(),f.delete(l));let R=!x;x||(x=new MutationObserver(()=>k()),x.observe(t.documentElement,{childList:!0,subtree:!0}),t.addEventListener("nativeUIOverlayAdopted",l=>{let V=l.detail;V?.ownerDocument===t&&B(V,"willPresent",l)})),k(R),(R||d)&&j({phase:"change"})}}},nt=t=>{let r=t;return r[wt]??=bt(t)};function*Ne(t){let r=t;for(;r;){let o=r.getRootNode();r=r.assignedSlot??r.parentElement??(o instanceof ShadowRoot?o.host:null),r&&(yield r)}}var Et=({x:t,y:r,width:o,height:v})=>({x:t,y:r,width:o,height:v}),ot=t=>{let r=t.getBoundingClientRect(),o=getComputedStyle(t),v=parseFloat(o.borderLeftWidth)||0,y=parseFloat(o.borderTopWidth)||0;return{x:r.left+v,y:r.top+y,width:r.width-v-(parseFloat(o.borderRightWidth)||0),height:r.height-y-(parseFloat(o.borderBottomWidth)||0)}},Ke=(t,r,o)=>{let v=[t,...Ne(t)],y=v.indexOf(r);if(y<=0||r===t.ownerDocument.scrollingElement)return;let m=t.ownerDocument.defaultView;if(m.visualViewport&&(m.visualViewport.scale!==1||m.visualViewport.offsetLeft||m.visualViewport.offsetTop))return;let f=0,P=0,p=m.innerWidth,M=m.innerHeight;for(let[k,g]of v.entries()){let d=getComputedStyle(g);if(d.transform!=="none"&&!new DOMMatrixReadOnly(d.transform).isIdentity||d.zoom&&d.zoom!=="normal"&&Number(d.zoom)!==1||[d.translate,d.rotate,d.scale,d.perspective].some(R=>R&&R!=="none")||d.writingMode&&d.writingMode!=="horizontal-tb"||k<y&&/^(fixed|sticky)$/.test(d.position))return;if(k===0)continue;if(d.scrollbarGutter&&d.scrollbarGutter!=="auto")return;let w=/^(auto|scroll|hidden|clip)$/.test(d.overflowX),c=/^(auto|scroll|hidden|clip)$/.test(d.overflowY);if(k<y&&(w||c))return;let W=g===t.ownerDocument.scrollingElement;if(k>y&&((w||W)&&g.scrollWidth>g.clientWidth||(c||W)&&g.scrollHeight>g.clientHeight)||(w||c)&&[d.borderTopLeftRadius,d.borderTopRightRadius,d.borderBottomLeftRadius,d.borderBottomRightRadius].some(R=>parseFloat(R)>0)||d.clipPath&&d.clipPath!=="none"||d.maskImage&&d.maskImage!=="none")return;if(k>=y){let R=ot(g);w&&(f=Math.max(f,R.x),p=Math.min(p,R.x+R.width)),c&&(P=Math.max(P,R.y),M=Math.min(M,R.y+R.height))}}let x=getComputedStyle(r);if(!/^(auto|scroll)$/.test(x.overflowX)&&!/^(auto|scroll)$/.test(x.overflowY))return;let j=ot(r);if(p<=f||M<=P||!j.width||!j.height)return;let B=Et(t.getBoundingClientRect());return{id:o(r),offsetX:r.scrollLeft,offsetY:r.scrollTop,viewport:j,clip:{x:f,y:P,width:p-f,height:M-P},contentWidth:r.scrollWidth,contentHeight:r.scrollHeight,frame:{...B,x:B.x-j.x+r.scrollLeft,y:B.y-j.y+r.scrollTop}}};var it=t=>{let r=globalThis;if(r.Capacitor?.convertFileSrc)return r.Capacitor.convertFileSrc(t);if(!t.startsWith("file:"))return t;if(r.WkWebView?.convertFilePath)return r.WkWebView.convertFilePath(t);throw new Error("Native UI file URL requires a host resource handler")};var he=t=>new Promise((r,o)=>{let v=setTimeout(()=>o(new Error("Native UI bridge timed out")),5e3);t.then(r,o).finally(()=>clearTimeout(v))}),Xe=async t=>{try{return await he(t)}catch(r){throw t.then(o=>o.remove()).catch(()=>{}),r}};var Ye=async(t,r)=>{let o=new Map;for(let P of t.update??[])o.set(P,{updated:!0});for(let P of["native","web","none"])for(let p of t.projection?.[P]??[]){let M=o.get(p)??{updated:!1};if(M.destination&&M.destination!==P)throw new TypeError(`Projection event "${p}" has conflicting destinations`);o.set(p,{...M,destination:P})}let v=!1,y=[],m=async()=>{v=!0;let p=(await Promise.allSettled(y.splice(0).map(M=>Promise.resolve().then(()=>M.remove())))).find(M=>M.status==="rejected");if(p?.status==="rejected")throw p.reason},f=[...o].map(async([P,p])=>{let M=await Xe(Promise.resolve().then(()=>t.addListener(P,x=>{!v&&(!t.accepts||t.accepts(x))&&r(p.destination,p.updated)})));v?await M.remove():y.push(M)});try{return await Promise.all(f),{remove:m}}catch(P){throw await m().catch(()=>{}),P}};var xe=":is([data-native-ui-snapshot-source], [data-native-ui-snapshot-prepared], [data-native-ui-snapshot-content])",rt=`
|
|
2
2
|
@layer native-ui-projection {
|
|
3
|
-
${
|
|
4
|
-
${
|
|
5
|
-
${
|
|
3
|
+
${xe}, ${xe} *, ${xe}::part(native) { visibility: hidden !important; }
|
|
4
|
+
${xe}::before, ${xe}::after,
|
|
5
|
+
${xe} *::before, ${xe} *::after {
|
|
6
6
|
visibility: hidden !important;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
@@ -19,4 +19,4 @@ ${je} *::before, ${je} *::after {
|
|
|
19
19
|
visibility: hidden !important;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
`;var Pt=(t,r=!1)=>JSON.stringify(t.map(({control:o})=>[o.id,o.kind,o.placement,r?0:o.x,r?0:o.y,o.width,o.height,o.dark,o.rtl])),Tt=async(t,r,o)=>{let v=o.captureDelayMs??50;if(!Number.isFinite(v)||v<0||v>2147483647)throw new RangeError("captureDelayMs must be a finite, nonnegative timer interval");let h="native",m=t.element.ownerDocument,f=m.defaultView,P=Array.from(f.crypto.getRandomValues(new Uint32Array(4)),e=>e.toString(16)).join("-"),p=e=>e.isConnected&&e.ownerDocument===m,L=e=>!!e?.isConnected&&e.ownerDocument===m,x=new Map,M=new Set,B=e=>{M.delete(e),e.style.setProperty("display","none","important"),e.removeAttribute("data-native-ui-projection-image"),e.removeAttribute("src"),Pe()},H=r.send.bind(r),g="data-native-ui-snapshot",l=`${t.namespace}:sources-change`,w=new Set,c=new Set,N=new Set,k=new WeakMap,d=0,V=e=>JSON.stringify(e.map(i=>{k.has(i.scope)||k.set(i.scope,++d);let n=o.transient&&!o.opaqueUnderlay?i.scope.element.getBoundingClientRect():void 0,s=n?{...i,control:{...i.control,x:i.control.x-n.x,y:i.control.y-n.y}}:i;return[k.get(i.scope),Pt([s],!!o.opaqueUnderlay)]})),F=new Map,G=e=>{let i=e.getRootNode();return i.nodeType===11&&"host"in i?i:m},pe=e=>{if(F.has(e))return;let i=m.createElement("style");i.setAttribute("data-native-ui-snapshot-base",""),i.textContent=rt+(e.nodeType===11?st:""),(e.nodeType===11?e:e.head).append(i),F.set(e,i)},Y=e=>{let i=[...e.getAnimations({subtree:!0}),...[...K.get(e)??[]].flatMap(n=>n.shadowRoot?.getAnimations()??[])];for(let n of i)"transitionProperty"in n&&n.transitionProperty==="visibility"&&n.cancel()},K=new Map,ne=e=>{let i=K.get(e)??new Set;K.set(e,i);let n=e.hasAttribute("data-native-ui-snapshot-source")||e.hasAttribute("data-native-ui-snapshot-prepared"),s=T=>{if(!T.hasAttribute("data-native-ui-projection-node")){if(T.shadowRoot){i.add(T),pe(T.shadowRoot);for(let S of T.shadowRoot.children)s(S)}for(let S of T.children)s(S)}};s(e);for(let T of i)T.toggleAttribute("data-native-ui-snapshot-content",n);Y(e)},le=()=>`${f.innerWidth}:${f.innerHeight}:${f.devicePixelRatio}`,A=!1,se=!1,Q=0,O=0,j,de,b,me=!1,z=!1,X=0,ve=0,$=0,he=0,ae=0,Se=-1,q=!1,We=!1,W,Pe=()=>{let e=new Set(W?.candidates.map(n=>n.scope.element));for(let[n,s]of x){let T=!q&&n.isConnected&&e.has(n);if(T&&(b||z||A))continue;let S=T?2*Math.max(1,j?.scopes.filter(C=>C.element===n).length??0):0,R=Math.max(0,S-s.filter(C=>M.has(C)).length),U=s.filter(C=>M.has(C)||R-- >0?!0:(C.remove(),!1));U.length?x.set(n,U):x.delete(n)}let i=new Set([...W?.candidates.map(n=>n.scope.element.getRootNode())??[],...b?.scopes.map(n=>n.element.getRootNode())??[],...j?.scopes.map(n=>n.element.getRootNode())??[],...[...M].map(n=>n.getRootNode()),...[...K.values()].flatMap(n=>[...n].map(s=>s.shadowRoot))]);for(let[n,s]of F)n.nodeType===11&&!i.has(n)&&(s.remove(),F.delete(n))},ye=new Set,oe=(e,i,n)=>{let s=()=>{ye.delete(s)&&(H({action:e,token:i}).catch(()=>{}),e==="restored"&&Pe())};ye.add(s),n&&!q?f.requestAnimationFrame(()=>f.requestAnimationFrame(s)):s()},ge=new Set,we=()=>{ge.forEach(e=>N.delete(e)),ge.clear()},Te=(e,i=!1)=>{!e||e===j||e===b||(e.images.forEach(n=>{B(n)}),oe("release",e.data.token,i))},Ue=e=>e.filter(i=>{if(!L(i.scope.element)||![i.element,...i.sources??[]].every(p))return!1;if(i.control.scroll){let n=i.element.getBoundingClientRect(),s=i.control.scroll.clip;if(n.right<=s.x||n.bottom<=s.y||n.left>=s.x+s.width||n.top>=s.y+s.height)return!1}return o.eligible?.(i)??!0}),xe=async()=>{if(he=0,q||h!=="native"||We||me||b||o.blocked()||!W||j?.revision===W.revision&&Se===ae)return;let{revision:e,candidates:i}=W,n=$,s=ae,T=le(),S=Ue(i);if(!S.length)return;We=!0;let R,U=!1,C=[];try{let ie=!1,re=H({action:"prepare",revision:o.captureRevision?.()??e,viewportWidth:f.innerWidth,ids:S.map(E=>E.control.id)});re.then(E=>{ie&&E.token&&H({action:"release",token:E.token}).catch(()=>{})}).catch(()=>{});try{R=await fe(re)}finally{ie=!0}if(!R.token||!R.parts?.length)return;let Ce=new Set(S.map(E=>E.control.id));if(R.parts.some(E=>!E.url.startsWith("file:")&&!/^\/__native_ui_engine__\/nativeUI[a-fA-F0-9]+\/[a-fA-F0-9-]+-[0-9]+\.png$/.test(E.url)||!E.ids.length||E.ids.some(_=>!Ce.has(_))||![E.x,E.y,E.width,E.height].every(Number.isFinite)||E.width<=0||E.height<=0)||new Set(R.parts.flatMap(E=>E.ids)).size!==Ce.size||R.parts.some(E=>new Set(E.ids.map(_=>S.find(Me=>Me.control.id===_).scope)).size!==1)||(await fe(Promise.all(R.parts.map(async E=>{let _=S.find(Ye=>E.ids.includes(Ye.control.id)).scope.element,Me=x.get(_);Me||(Me=[],x.set(_,Me));let ue=Me.find(Ye=>!M.has(Ye));return ue||(ue=m.createElement("img"),ue.setAttribute("data-native-ui-projection-node",""),Me.push(ue)),M.add(ue),C.push(ue),ue.src=it(E.url),await ue.decode(),ue}))),q||h!=="native"||me||b||o.blocked()||$!==n||le()!==T||W?.revision!==e||S.some(E=>!L(E.scope.element)||![E.element,...E.sources??[]].every(p))))return;let Oe=j,et={data:R,images:C,sources:Array.from(new Set(S.flatMap(E=>[E.element,...E.sources??[]]))),targets:R.parts.map(E=>S.find(_=>E.ids.includes(_.control.id)).element),scopes:R.parts.map(E=>S.find(_=>E.ids.includes(_.control.id)).scope),parents:R.parts.map(E=>S.find(_=>E.ids.includes(_.control.id)).scope.element.parentNode),frames:[],viewport:T,revision:e,layout:V(S)};try{if(!Ve(et))throw new Error("Projection destination is unavailable")}catch(E){u();try{Ve(),j?.sources.forEach(_=>{N.add(_),ge.add(_)})}catch{y()}throw E}j=et,we(),j.sources.forEach(E=>{N.add(E),ge.add(E)}),o.opaqueUnderlay&&H({action:"prepared",token:R.token}).catch(()=>{}),f.dispatchEvent(new Event(l)),Se=s,U=!0,Te(Oe)}catch{}finally{U||C.forEach(ie=>{B(ie)}),R?.token&&!U&&H({action:"release",token:R.token}).catch(()=>{}),We=!1,W&&(W.revision!==e||ae!==s)&&ce()}},ce=()=>{f.clearTimeout(he),!q&&h==="native"&&!b&&!me&&!o.blocked()&&(he=f.setTimeout(()=>{xe()},v))},De,He=(e,i)=>{if(i.some(s=>s.scope.element.ownerDocument!==m||[s.element,...s.sources??[]].some(T=>T.ownerDocument!==m)))throw new TypeError("All projection sources and fallback scopes must share one Document");if(o.blocked())return;!b&&j&&j.layout!==V(Ue(i))&&Le();let n=V(i);De!==n&&(De=n,ae++,$++),W?.revision!==e&&$++,W={revision:e,candidates:i},Pe(),(j?.revision!==e||Se!==ae)&&ce()},Be=e=>{!b&&j&&e&&W?.candidates.some(i=>i.scrollElement===e&&j.sources.includes(i.element))&&Le(),b&&Re(),ae++,$++,ce()},Ne=await ze(r.listen(({active:e})=>{me=e,$++,f.clearTimeout(he),e||ce()})),ke=new Set,a=e=>{K.get(e)?.forEach(i=>i.removeAttribute("data-native-ui-snapshot-content")),ke.delete(e)&&e.removeAttribute("data-native-ui-snapshot-prepared"),e.removeAttribute("data-native-ui-snapshot-visible"),e.removeAttribute(g),e.removeAttribute("data-native-ui-snapshot-positioned"),e.removeAttribute("data-native-ui-snapshot-source"),Y(e),K.delete(e)},u=()=>{O++,f.cancelAnimationFrame(Q);for(let e of Fe.keys())e.style.setProperty("opacity","0","important");Fe.clear(),Q=0,A=!1,se=!1,we(),b?.sources.forEach(e=>{w.delete(e),c.delete(e)}),D.forEach(a),D.clear(),F.forEach((e,i)=>{(q||i.nodeType===11&&!i.host.isConnected)&&(e.remove(),F.delete(i))})},y=(e=b,i=z)=>{if(b!==e)return;let n=new Set([b,j]);u(),b=void 0,j=void 0,z=!1,f.clearTimeout(X),n.forEach(s=>Te(s,i)),o.wake()},I=()=>{if(!b)return;if(j!==b){y();return}let e=b;O++,f.cancelAnimationFrame(Q),Q=0,A=se=!1,e.sources.forEach(i=>{w.delete(i),c.delete(i)}),D.forEach(i=>i.removeAttribute("data-native-ui-snapshot-source")),ee(e,!!o.opaqueUnderlay),b=void 0,z=!1,f.clearTimeout(X),oe("restored",e.data.token,!0),e.sources.forEach(i=>{N.add(i),ge.add(i)}),o.wake()},J=()=>{z&&I(),ye.forEach(e=>e())},Z=e=>e.scopes.map(i=>L(i.element)?i.element:void 0),D=new Set,ee=(e,i)=>{for(let n of D)n.toggleAttribute("data-native-ui-snapshot-visible",i),ne(n);e.images.forEach(n=>n.style.setProperty("opacity",i?"1":"0","important"))},te=new Map,Fe=new Map,Re=()=>{let e=[];for(let[i,n]of Fe){let{target:s,frame:T}=n;if(!s.isConnected){i.remove();continue}let S=s.shadowRoot??s;i.parentNode!==S&&S.insertBefore(i,null);let R=s.getBoundingClientRect(),U=i.getBoundingClientRect(),C=parseFloat(i.style.width)||T.width,ie=parseFloat(i.style.height)||T.height,re=U.width/C||1,Ce=U.height/ie||1,Oe=n.scale??(n.scale={x:re,y:Ce});e.push({element:i,left:(parseFloat(i.style.left)||0)+(R.x+T.x*re/Oe.x-U.x)/re,top:(parseFloat(i.style.top)||0)+(R.y+T.y*Ce/Oe.y-U.y)/Ce,width:T.width/Oe.x,height:T.height/Oe.y})}for(let{element:i,...n}of e)for(let[s,T]of Object.entries(n)){let S=`${T}px`;i.style.getPropertyValue(s)!==S&&i.style.setProperty(s,S,"important")}},Ve=(e=b??j)=>{if(!e||z)return!1;if(!e.sources.every(p)||Z(e).some(n=>!n))return Le(),!1;let i=Z(e);if(b){if(i.some(s=>!s?.isConnected||!F.has(G(s))))return y(b,!1),!1;let n=new Set;for(let[s,T]of e.targets.entries()){let S=te.get(T),R=i[s];!S||!R?.isConnected||(R.setAttribute(g,S),R.setAttribute("data-native-ui-snapshot-source",""),n.add(R))}for(let s of D)n.has(s)||a(s);return D.clear(),n.forEach(s=>D.add(s)),ee(e,se),!0}x.forEach(n=>n.forEach(s=>{e.images.includes(s)||(s.style.setProperty("display","none","important"),s.removeAttribute("data-native-ui-projection-image"))})),te.clear(),Fe.clear(),D.forEach(a),D.clear();for(let n of new Set(i)){if(!n)continue;D.add(n),pe(G(n));let s=i.flatMap((U,C)=>U===n?[C]:[]),T=`${P}-${s[0]}`;n.setAttribute(g,T),n!==e.targets[s[0]]&&(n.setAttribute("data-native-ui-snapshot-prepared",""),ke.add(n)),n.toggleAttribute("data-native-ui-snapshot-visible",!!o.opaqueUnderlay),ne(n);let S=n.getBoundingClientRect();n.toggleAttribute("data-native-ui-snapshot-positioned",f.getComputedStyle(n).position==="static");let R=n.shadowRoot??n;for(let U of[...s].reverse()){let C=e.images[U],ie=e.data.parts[U],re=e.frames[U]??{x:o.opaqueUnderlay?0:ie.x-S.x,y:o.opaqueUnderlay?0:ie.y-S.y,width:ie.width,height:ie.height};e.frames[U]=re,te.set(e.targets[U],T),C.inert=!0,C.setAttribute("aria-hidden","true"),C.setAttribute("data-native-ui-projection-image",T),C.style.cssText="all:initial!important;position:absolute!important;display:block!important;visibility:visible!important;pointer-events:none!important;image-rendering:pixelated!important;will-change:opacity!important;opacity:0!important;",C.style.setProperty("width",`${re.width}px`,"important"),C.style.setProperty("height",`${re.height}px`,"important"),C.style.setProperty("left","0px","important"),C.style.setProperty("top","0px","important"),C.style.setProperty("opacity",o.opaqueUnderlay?"1":"0","important"),C.parentNode!==R&&R.insertBefore(C,null),Fe.set(C,{target:n,frame:re})}}return e.parents=e.scopes.map(n=>n.element.parentNode),Re(),!0},Ge=e=>e.images.map((i,n)=>{let s=i.getBoundingClientRect();return{...e.data.parts[n],x:s.x,y:s.y,width:s.width,height:s.height}}),Ke=()=>{if(J(),q||h==="none"||b)return;let e=j;if(!e||e.viewport!==le()||!e.sources.every(p)||o.current&&!o.current(e.targets)||e.targets.some(s=>!te.has(s))||Z(e).some(s=>!s?.isConnected)||[...D].some(s=>!s.isConnected))return;e.scopes.some((s,T)=>s.element.parentNode!==e.parents[T])&&Ve(),Re();let i=++O,n=()=>O===i;A=!0,se=!!o.opaqueUnderlay,b=e,$++,f.clearTimeout(he),e.sources.forEach(s=>{w.add(s)}),D.forEach(s=>s.setAttribute("data-native-ui-snapshot-source","")),ee(e,se),Q=f.requestAnimationFrame(()=>{Q=0,n()&&(A=!1,o.wake())}),fe(H({action:"cover",token:e.data.token,...o.transient?{transient:!0,viewportWidth:f.innerWidth,parts:Ge(e)}:{}})).then(s=>{if(n()){if(A=!1,s?.shown!==!0){y(e,!1);return}z||(se=!0,e.sources.forEach(T=>c.add(T)),Ve(),Re()),f.cancelAnimationFrame(Q),Q=f.requestAnimationFrame(()=>{Q=0,n()&&H({action:"painted",token:e.data.token}).catch(()=>{n()&&y(e,!1)})}),o.wake()}}).catch(()=>{n()&&y(e,!1)})},Ze=()=>{if(!(!b||q||z)){if(!b.sources.every(p)||Z(b).some(e=>!e)||o.current&&!o.current(b.targets)){y(b,!1);return}if(!o.blocked()){if(Re(),o.transient){let e=b;if(Z(e).some(s=>!s?.isConnected)){y(e,!1);return}let n=Ge(e);o.opaqueUnderlay||n.every((s,T)=>s.width===e.data.parts[T].width&&s.height===e.data.parts[T].height)?e.data={...e.data,parts:n}:j=void 0,H({action:"restore",token:e.data.token,viewportWidth:f.innerWidth,parts:n}).catch(()=>{})}ve=o.revision?.()??W?.revision??0,z=!0,b.sources.forEach(e=>w.delete(e)),X=f.setTimeout(()=>{z&&y(b,!1)},250),o.wake()}}},dt=(e,i,n)=>{!z||!b||n===void 0||n<=ve||!o.transient&&e||b.data.parts.every(s=>s.ids.every(T=>i?.includes(T)))&&(I(),ce())},Le=(e=!1)=>{ye.forEach(n=>n()),$++,f.clearTimeout(he);let i=j;if(j=void 0,(e||q)&&(de=void 0),o.retainPreparedUntilRelease&&!b&&!e&&!q){if(i){let n={};de=n,fe(H({action:"release",token:i.data.token})).catch(()=>{}).finally(()=>{if(i.images.forEach(s=>{B(s)}),de===n&&(de=void 0,!(j||b))){for(let s of D)s.getAttribute(g)!==te.get(s)&&(D.delete(s),ke.delete(s));u(),te.clear(),f.dispatchEvent(new Event(l))}})}if(de)return}Te(i),b?y(b,!1):(u(),te.clear(),f.dispatchEvent(new Event(l)))},Qe;try{o.events&&(Qe=await qe(o.events,(e,i)=>{if(!q){if(e&&(h=e),h==="none"){Le();return}e==="web"&&Ke(),e==="native"&&(Ze(),ce()),i&&Be()}}))}catch(e){throw q=!0,Le(),await fe(Promise.resolve(Ne.remove())).catch(()=>{}),e}return{get owners(){return[...w]},get visibleOwners(){return[...c]},get preparedOwners(){return[...N]},consider:He,changed:Be,moved:Re,get token(){return z?void 0:b?.data.token},begin:Ke,get restoring(){return z},get handoffPending(){return A},retireRestoration:J,end:Ze,updated:dt,invalidate:Le,async destroy(){q=!0,Le(),x.forEach(e=>e.forEach(i=>i.remove())),x.clear(),await Promise.allSettled([fe(Promise.resolve().then(()=>Ne?.remove())),fe(Promise.resolve().then(()=>Qe?.remove()))])}}},at=async(t,r,o)=>{let v=await Tt(t,r,o),h=v.consider;return Object.assign(v,{consider:(m,f)=>h(m,f.map(P=>({...P,scope:t})))})};var ct=(t,r)=>{if(t.nodeType!==1||t.namespaceURI!=="http://www.w3.org/1999/xhtml"||!t.ownerDocument||!("style"in t))throw new TypeError("A Web projection scope requires an HTMLElement fallback");if(t.matches("img, input, textarea, select, video, audio, canvas, iframe, embed, object, br, hr, area, base, link, meta, source, track, wbr"))throw new TypeError("A Web projection fallback must be a container element; use the existing fallback container");return Object.freeze({element:t,namespace:r})};var lt=async(t,r,o={addListener:async(v,h)=>globalThis.Capacitor.addListener(t.plugin,v,h)})=>{let v="view",h=t.receiveListeners,m=!1,f=!1,P="native",p="native",L=nt(document),x=()=>P==="native"&&d&&L.isCovered(d)?"web":P,M=!1,B=!1,H=!1,g=!1,l,w,c,N=!1,k=()=>{let a=N;N=!0;try{c?.begin()}finally{N=a}},d,V=0,F,G=()=>{V++,F?.(),F=void 0},pe=async()=>{if(!t.values||!d||m)return;let a=d;G();let u=V,y=()=>!m&&u===V&&d===a&&ve()===a&&a.isConnected;if(a.localName.includes("-")&&!a.matches(":defined")&&Object.values(t.values).some(J=>J.property)){if(await Promise.race([a.ownerDocument.defaultView.customElements.whenDefined(a.localName),new Promise(J=>{F=J})]),!y())return;F=void 0}let I=await r.send({action:"values"}).catch(()=>{});if(y()&&I?.values&&typeof I.values=="object"&&!Array.isArray(I.values))try{tt(a,I.values,t.values)}catch(J){console.warn("[Native UI Engine] Cannot reflect values",J)}},Y={},K,ne=0,le=()=>{ne++,K=void 0;let a=$e(d);a?.owner===Y&&(a.projected=!1,a.owner=void 0)},A={listen:a=>r.listen(u=>{a(u),!u.active&&B&&(B=!1,Te()),u.precovered&&Ue(u.precovered)}),send:a=>{if(!t.placementHandoff)return r.send(a);let u=$e(d);if(a.action==="cover"){let D=K===a.token&&u?.owner===Y&&u.projected,ee=++ne;return K=a.token,u&&(u.owner=Y,u.projected=!!D),r.send(a).then(te=>(ee===ne&&u===$e(d)&&u?.owner===Y&&(u.projected=te?.shown===!0),te)).catch(te=>{throw ee===ne&&u?.owner===Y&&(le(),u.invalidate()),te})}let y=a.action==="release"&&a.token===K,I=K&&(a.action==="restore"||y||a.action==="reset"||a.action==="visibility"&&a.visible);I&&ne++;let J=ne,Z=()=>{J!==ne||u?.owner!==Y||(le(),u.invalidate())};try{let D=I&&u?.owner===Y?{...a,token:"token"in a?a.token:K,placement:u.measure()}:a;return r.send(D).then(async ee=>(a.action==="release"&&ee?.requiresPlacement&&(u&&(!u.owner||u.owner===Y)?ee=await r.send({...a,placement:u.measure()}):(await r.send({action:"visibility",visible:!1}),ee=await r.send(a))),J===ne&&(a.action==="resume"||y||a.action==="reset"||a.action==="visibility")&&le(),ee)).catch(ee=>{throw Z(),ee})}catch(D){return Z(),Promise.reject(D)}}},se=0,Q=0,O=0,j,de=!1,b=!1,me=!1,z=document.createElement("style"),X=`data-native-ui-session-${t.id.replace(/[^a-zA-Z0-9-]/g,"")}`;z.textContent=`[${X}="native"], [${X}="native"] *, [${X}="none"], [${X}="none"] * {visibility:hidden!important}`,document.documentElement.append(z);let ve=()=>{let a=document.querySelectorAll(t.projectionSelector);return a.length===1&&a[0]instanceof HTMLElement?a[0]:void 0},$=()=>{let a=x();d&&d.getAttribute("data-native-ui-destination")!==a&&d.setAttribute("data-native-ui-destination",a),d&&(p==="web"||p==="native"&&H?d.removeAttribute(X):d.setAttribute(X,p))},he=()=>{if(!d?.isConnected)return[];let a=d.getBoundingClientRect(),u={x:a.x,y:a.y,width:a.width,height:a.height},y=l&&_e(d,l,()=>t.id);return[{element:d,scrollElement:l,control:{id:v,...u,...y?{scroll:y}:{}}}]},ae=async()=>{if(m)return;let a=O,u=t.failedFallback==="native"&&x()==="native"&&!!d?.isConnected;await A.send({action:"visibility",visible:u}).catch(()=>{}),!(m||a!==O)&&(u||p==="none"?$():d?.removeAttribute(X))},Se=()=>{if(!M||p!=="native"||!d?.isConnected||c?.token||c?.restoring)return;let a=t.failedFallback==="native";A.send({action:"visibility",visible:a}).catch(()=>{}),a?$():d.removeAttribute(X)},q=()=>{if(m||N)return;if(Se(),p==="web"&&c&&!c.token&&!c.restoring){A.send({action:"visibility",visible:!1}).catch(()=>{}),d?.removeAttribute(X);return}if(!c?.restoring||j===c||p!=="native")return;j=c;let a=O,u=c;A.send({action:"resume"}).then(()=>{m||a!==O||u!==c||ve()!==d||(H=!1,u.updated(void 0,[v],++se),$(),W())}).catch(()=>{a!==O||m||(u.invalidate(),ae())}).finally(()=>{j===u&&(j=void 0),q()})},We=async()=>{if(m||de)return;if(ve()!==d){O++,M=!1,B=!1,clearTimeout(w),le(),d?.removeAttribute(X),d?.removeAttribute("data-native-ui-destination"),G();let u=c,y=d;c=void 0,d=void 0,ye.disconnect(),xe();try{y&&await A.send({action:"visibility",visible:!1})}finally{await u?.destroy()}if(m)return;d=ve(),H=!1,d&&(ye.observe(d),pe())}if(xe(),!M){if(c?.restoring){q();return}if(p=x(),!d){await A.send({action:"visibility",visible:!1});return}if(!c){de=!0;let u=O;try{let y=await at(ct(d,t.id),A,{wake:q,captureDelayMs:t.captureDelayMs,retainPreparedUntilRelease:t.nativeDragHandoff,blocked:()=>p!=="native"||M||H&&!c?.token,revision:()=>se,captureRevision:t.captureMode==="view"?()=>Q:void 0,transient:!0,opaqueUnderlay:t.captureMode==="view"});if(m||u!==O){await y.destroy();return}c=y}finally{de=!1}}if(!m){if(p==="native"&&H){await A.send({action:"visibility",visible:!1}),$();return}if(p==="native"){let u=O;if(await A.send({action:"visibility",visible:!0}),m||u!==O||p!=="native")return;$(),l=[...Ae(d)].find(Z=>{let D=getComputedStyle(Z);return/auto|scroll/.test(D.overflowX+D.overflowY)&&(Z.scrollHeight>Z.clientHeight||Z.scrollWidth>Z.clientWidth)});let y=l&&_e(d,l,()=>t.id),I=t.nativeDragHandoff&&t.captureMode==="view"&&l?{viewport:l.getBoundingClientRect(),offsetX:l.scrollLeft,offsetY:l.scrollTop,rangeX:Math.max(0,l.scrollWidth-l.clientWidth),rangeY:Math.max(0,l.scrollHeight-l.clientHeight)}:void 0,J=await A.send({action:"track",viewportWidth:innerWidth,...y?{scroll:y}:{},...I?{gesture:I}:{}});if(m||u!==O)return;g=J?.tracked===!0,c.consider(t.captureMode==="view"?Q:++se,he())}else await A.send({action:"visibility",visible:!1}),$()}}},W=()=>{m||(b=!0,!(!f||me)&&(me=!0,Promise.resolve().then(async()=>{try{for(;b&&!m;)b=!1,await We()}catch{await ae()}finally{me=!1,b&&W()}})))},Pe=()=>{c?.invalidate(),W()},ye=new ResizeObserver(Pe);window.addEventListener("resize",Pe);let oe=new Set,ge=new WeakSet,we=a=>{let u=a.composedPath()[0]??a.target;if(!(m||p!=="native"||!d||ge.has(a)||u!==document&&![...Ae(d)].includes(u))){if(ge.add(a),g&&u===l){c?.changed(u);return}M?t.captureMode==="view"?c?.moved():c?.changed():((j||c?.restoring)&&O++,M=!0,k(),H=t.failedFallback!=="native",c?.token?d.removeAttribute(X):Se()),Te()}};function Te(){clearTimeout(w),w=setTimeout(()=>{B||(M=!1,!(m||p!=="native")&&(c?.end(),c?.restoring||W()))},100)}function Ue(a){if(m||p!=="native"||!d?.isConnected||!c||(B=!0,c.token))return;(j||c.restoring)&&O++,K=a;let u=$e(d);if(u&&(u.owner=Y,u.projected=!0),M=!0,k(),!c.token){M=!1,ae();return}Te()}let xe=()=>{let a=new Set(d?Ae(d):[]),u=a.size!==oe.size||[...a].some(y=>!oe.has(y));for(let y of oe)a.has(y)||(y.removeEventListener("scroll",we),y.removeEventListener("slotchange",ce),oe.delete(y));for(let y of a)oe.has(y)||(y.addEventListener("scroll",we,{passive:!0}),y.addEventListener("slotchange",ce),oe.add(y));u&&(g=!1,l=void 0,c?.invalidate(),W())},ce=()=>{xe(),W()};document.addEventListener("scroll",we,!0);let De=new MutationObserver(a=>{xe(),ve()!==d?W():d&&a.some(u=>u.type==="childList")&&He(x())});De.observe(document.documentElement,{childList:!0,attributes:!0,subtree:!0});let He=(a,u=!1)=>{if(m||!u&&a===p)return;M=!1,B=!1,clearTimeout(w),p=a,O++;let y=O;p==="none"?A.send({action:"visibility",visible:!1}).then(()=>{p!=="none"||y!==O||m||(c?.invalidate(!0),$())}).catch(()=>{p!=="none"||y!==O||m||(c?.invalidate(!0),$())}):p==="web"?(k(),c?.token||A.send({action:"visibility",visible:!1}).catch(()=>{}),$()):p==="native"&&(c?.end(),c?.restoring||W())},Be=L.subscribe(()=>queueMicrotask(()=>He(x()))),Ne,ke=async()=>{if(!m){m=!0,G(),le(),O++,Be(),De.disconnect(),ye.disconnect(),window.removeEventListener("resize",Pe),document.removeEventListener("scroll",we,!0);for(let a of oe)a.removeEventListener("scroll",we),a.removeEventListener("slotchange",ce);oe.clear(),clearTimeout(w),d?.removeAttribute(X),d?.removeAttribute("data-native-ui-destination"),z.remove(),await Promise.allSettled([Promise.resolve(Ne?.remove()),c?.destroy()])}};try{let a=O;Ne=await qe({addListener:(y,I)=>o.addListener(y,I),update:h?.update,projection:h?.projection,accepts:y=>!h?.match||Object.entries(h?.match).every(([I,J])=>typeof y=="object"&&y!==null&&y[I]===J)},(y,I)=>{m||(y&&(y==="native"&&(H=!1),P=y,A.send({action:"destination",destination:y}).catch(()=>{}),He(x(),!0)),I&&(pe(),Q++,c?.changed(),p==="native"&&W()))});let u=await A.send({action:"connect"});return O===a&&["native","web","none"].includes(u?.destination)&&(P=u.destination),p=x(),f=!0,W(),{destroy:ke,show:()=>{H=!1,P="native",He(x(),!0)},hide:()=>{P=p="none",O++,M=!1,B=!1,clearTimeout(w),c?.invalidate(!0),$()}}}catch(a){throw await ke(),a}};var be=new Map,Ee=new Map,Ie=new Map,Lt=Array.from(crypto.getRandomValues(new Uint32Array(4)),t=>t.toString(16)).join("-"),Xe=new Map,Mt=(t,r,o)=>Xe.get(t)?.get(r)?.(o),jt=0,St=(t,r)=>new Promise((o,v)=>{let h=`${t}:${Lt}:${++jt}`,m=setTimeout(()=>{Ee.delete(h),v(new Error("Native UI session timed out"))},5e3);Ee.set(h,{resolve:o,reject:v,timer:m});let f=JSON.stringify({key:h,request:r}),P=globalThis,p=P.webkit?.messageHandlers?.[t]??P[t]??P.nativeUIEngine;if(!p){clearTimeout(m),Ee.delete(h),v(new Error("Native UI session unavailable"));return}try{p.postMessage(f)}catch(L){clearTimeout(m),Ee.delete(h),v(L)}}),xt=(t,r,o,v)=>{if(r===null){Ie.get(t)?.(o);return}let h=Ee.get(r);!h||!r.startsWith(`${t}:`)||(Ee.delete(r),clearTimeout(h.timer),v?h.reject(new Error(v)):h.resolve(o))},Ht=t=>{be.get(t)?.show()},kt=t=>(be.get(t)?.hide(),!0),Rt=async t=>{let r=be.get(t);be.delete(t),Xe.delete(t),Ie.delete(t);for(let[o,v]of Ee)o.startsWith(`${t}:`)&&(Ee.delete(o),clearTimeout(v.timer),v.reject(new Error("Native UI session closed")));await r?.destroy()},Ct=async t=>{if(be.has(t.id))return;let r,o=!1,v,h={show:()=>{v="native",r?.show()},hide:()=>{v="none",r?.hide()},destroy:async()=>{o=!0,await r?.destroy()}};be.set(t.id,h);try{if(document.readyState==="loading"&&await new Promise(f=>document.addEventListener("DOMContentLoaded",()=>f(),{once:!0})),o)return;let m=new Map;t.runtime==="cordova"&&Xe.set(t.id,m),r=await lt(t,{send:f=>St(t.id,f),listen:async f=>(Ie.set(t.id,f),{remove:()=>{Ie.get(t.id)===f&&Ie.delete(t.id)}})},t.runtime==="cordova"?{addListener:async(f,P)=>(m.set(f,P),{remove:()=>{m.delete(f)}})}:void 0),v==="none"?r.hide():v==="native"&&r.show(),o&&await r.destroy()}catch(m){throw be.get(t.id)===h&&(be.delete(t.id),Xe.delete(t.id)),m}};return ht(Ot);})();
|
|
22
|
+
`;var Pt=(t,r=!1)=>JSON.stringify(t.map(({control:o})=>[o.id,o.kind,o.placement,r?0:o.x,r?0:o.y,o.width,o.height,o.dark,o.rtl])),Tt=async(t,r,o)=>{let v=o.captureDelayMs??50;if(!Number.isFinite(v)||v<0||v>2147483647)throw new RangeError("captureDelayMs must be a finite, nonnegative timer interval");let y="native",m=t.element.ownerDocument,f=m.defaultView,P=Array.from(f.crypto.getRandomValues(new Uint32Array(4)),e=>e.toString(16)).join("-"),p=e=>e.isConnected&&e.ownerDocument===m,M=e=>!!e?.isConnected&&e.ownerDocument===m,x=new Map,j=new Set,B=e=>{j.delete(e),e.style.setProperty("display","none","important"),e.removeAttribute("data-native-ui-projection-image"),e.removeAttribute("src"),He()},k=r.send.bind(r),g="data-native-ui-snapshot",d=`${t.namespace}:sources-change`,w=new Set,c=new Set,W=new Set,R=new WeakMap,l=0,V=e=>JSON.stringify(e.map(i=>{R.has(i.scope)||R.set(i.scope,++l);let n=o.transient&&!o.opaqueUnderlay?i.scope.element.getBoundingClientRect():void 0,a=n?{...i,control:{...i.control,x:i.control.x-n.x,y:i.control.y-n.y}}:i;return[R.get(i.scope),Pt([a],!!o.opaqueUnderlay)]})),$=new Map,G=e=>{let i=e.getRootNode();return i.nodeType===11&&"host"in i?i:m},ye=e=>{if($.has(e))return;let i=m.createElement("style");i.setAttribute("data-native-ui-snapshot-base",""),i.textContent=rt+(e.nodeType===11?st:""),(e.nodeType===11?e:e.head).append(i),$.set(e,i)},J=e=>{let i=[...e.getAnimations({subtree:!0}),...[...K.get(e)??[]].flatMap(n=>n.shadowRoot?.getAnimations()??[])];for(let n of i)"transitionProperty"in n&&n.transitionProperty==="visibility"&&n.cancel()},K=new Map,ee=e=>{let i=K.get(e)??new Set;K.set(e,i);let n=e.hasAttribute("data-native-ui-snapshot-source")||e.hasAttribute("data-native-ui-snapshot-prepared"),a=T=>{if(!T.hasAttribute("data-native-ui-projection-node")){if(T.shadowRoot){i.add(T),ye(T.shadowRoot);for(let S of T.shadowRoot.children)a(S)}for(let S of T.children)a(S)}};a(e);for(let T of i)T.toggleAttribute("data-native-ui-snapshot-content",n);J(e)},pe=()=>`${f.innerWidth}:${f.innerHeight}:${f.devicePixelRatio}`,re=!1,le=!1,te=0,de=0,L,me,b,H=!1,D=!1,Pe=0,Te=0,oe=0,ue=0,I=0,fe=-1,A=!1,Fe=!1,Y,He=()=>{let e=new Set(Y?.candidates.map(n=>n.scope.element));for(let[n,a]of x){let T=!A&&n.isConnected&&e.has(n);if(T&&(b||D||re))continue;let S=T?2*Math.max(1,L?.scopes.filter(O=>O.element===n).length??0):0,C=Math.max(0,S-a.filter(O=>j.has(O)).length),U=a.filter(O=>j.has(O)||C-- >0?!0:(O.remove(),!1));U.length?x.set(n,U):x.delete(n)}let i=new Set([...Y?.candidates.map(n=>n.scope.element.getRootNode())??[],...b?.scopes.map(n=>n.element.getRootNode())??[],...L?.scopes.map(n=>n.element.getRootNode())??[],...[...j].map(n=>n.getRootNode()),...[...K.values()].flatMap(n=>[...n].map(a=>a.shadowRoot))]);for(let[n,a]of $)n.nodeType===11&&!i.has(n)&&(a.remove(),$.delete(n))},ge=new Set,Ve=(e,i,n)=>{let a=()=>{ge.delete(a)&&(k({action:e,token:i}).catch(()=>{}),e==="restored"&&He())};ge.add(a),n&&!A?f.requestAnimationFrame(()=>f.requestAnimationFrame(a)):a()},q=new Set,ke=()=>{q.forEach(e=>W.delete(e)),q.clear()},Le=(e,i=!1)=>{!e||e===L||e===b||(e.images.forEach(n=>{B(n)}),Ve("release",e.data.token,i))},se=e=>e.filter(i=>{if(!M(i.scope.element)||![i.element,...i.sources??[]].every(p))return!1;if(i.control.scroll){let n=i.element.getBoundingClientRect(),a=i.control.scroll.clip;if(n.right<=a.x||n.bottom<=a.y||n.left>=a.x+a.width||n.top>=a.y+a.height)return!1}return o.eligible?.(i)??!0}),ze=async()=>{if(ue=0,A||y!=="native"||Fe||H||b||o.blocked()||!Y||L?.revision===Y.revision&&fe===I)return;let{revision:e,candidates:i}=Y,n=oe,a=I,T=pe(),S=se(i);if(!S.length)return;Fe=!0;let C,U=!1,O=[];try{let ae=!1,ce=k({action:"prepare",revision:o.captureRevision?.()??e,viewportWidth:f.innerWidth,ids:S.map(E=>E.control.id)});ce.then(E=>{ae&&E.token&&k({action:"release",token:E.token}).catch(()=>{})}).catch(()=>{});try{C=await he(ce)}finally{ae=!0}if(!C.token||!C.parts?.length)return;let We=new Set(S.map(E=>E.control.id));if(C.parts.some(E=>!E.url.startsWith("file:")&&!/^\/__native_ui_engine__\/nativeUI[a-fA-F0-9]+\/[a-fA-F0-9-]+-[0-9]+\.png$/.test(E.url)||!E.ids.length||E.ids.some(_=>!We.has(_))||![E.x,E.y,E.width,E.height].every(Number.isFinite)||E.width<=0||E.height<=0)||new Set(C.parts.flatMap(E=>E.ids)).size!==We.size||C.parts.some(E=>new Set(E.ids.map(_=>S.find(Se=>Se.control.id===_).scope)).size!==1)||(await he(Promise.all(C.parts.map(async E=>{let _=S.find(_e=>E.ids.includes(_e.control.id)).scope.element,Se=x.get(_);Se||(Se=[],x.set(_,Se));let ve=Se.find(_e=>!j.has(_e));return ve||(ve=m.createElement("img"),ve.setAttribute("data-native-ui-projection-node",""),Se.push(ve)),j.add(ve),O.push(ve),ve.src=it(E.url),await ve.decode(),ve}))),A||y!=="native"||H||b||o.blocked()||oe!==n||pe()!==T||Y?.revision!==e||S.some(E=>!M(E.scope.element)||![E.element,...E.sources??[]].every(p))))return;let De=L,et={data:C,images:O,sources:Array.from(new Set(S.flatMap(E=>[E.element,...E.sources??[]]))),targets:C.parts.map(E=>S.find(_=>E.ids.includes(_.control.id)).element),scopes:C.parts.map(E=>S.find(_=>E.ids.includes(_.control.id)).scope),parents:C.parts.map(E=>S.find(_=>E.ids.includes(_.control.id)).scope.element.parentNode),frames:[],viewport:T,revision:e,layout:V(S)};try{if(!Q(et))throw new Error("Projection destination is unavailable")}catch(E){Ae();try{Q(),L?.sources.forEach(_=>{W.add(_),q.add(_)})}catch{ne()}throw E}L=et,ke(),L.sources.forEach(E=>{W.add(E),q.add(E)}),o.opaqueUnderlay&&k({action:"prepared",token:C.token}).catch(()=>{}),f.dispatchEvent(new Event(d)),fe=a,U=!0,Le(De)}catch{}finally{U||O.forEach(ae=>{B(ae)}),C?.token&&!U&&k({action:"release",token:C.token}).catch(()=>{}),Fe=!1,Y&&(Y.revision!==e||I!==a)&&ie()}},ie=()=>{f.clearTimeout(ue),!A&&y==="native"&&!b&&!H&&!o.blocked()&&(ue=f.setTimeout(()=>{ze()},v))},Re,Je=(e,i)=>{if(i.some(a=>a.scope.element.ownerDocument!==m||[a.element,...a.sources??[]].some(T=>T.ownerDocument!==m)))throw new TypeError("All projection sources and fallback scopes must share one Document");if(o.blocked())return;!b&&L&&L.layout!==V(se(i))&&je();let n=V(i);Re!==n&&(Re=n,I++,oe++),Y?.revision!==e&&oe++,Y={revision:e,candidates:i},He(),(L?.revision!==e||fe!==I)&&ie()},Me=e=>{!b&&L&&e&&Y?.candidates.some(i=>i.scrollElement===e&&L.sources.includes(i.element))&&je(),b&&z(),I++,oe++,ie()},Ce=await Xe(r.listen(({active:e})=>{H=e,oe++,f.clearTimeout(ue),e||ie()})),Oe=new Set,we=e=>{K.get(e)?.forEach(i=>i.removeAttribute("data-native-ui-snapshot-content")),Oe.delete(e)&&e.removeAttribute("data-native-ui-snapshot-prepared"),e.removeAttribute("data-native-ui-snapshot-visible"),e.removeAttribute(g),e.removeAttribute("data-native-ui-snapshot-positioned"),e.removeAttribute("data-native-ui-snapshot-source"),J(e),K.delete(e)},Ae=()=>{de++,f.cancelAnimationFrame(te);for(let e of Z.keys())e.style.setProperty("opacity","0","important");Z.clear(),te=0,re=!1,le=!1,ke(),b?.sources.forEach(e=>{w.delete(e),c.delete(e)}),h.forEach(we),h.clear(),$.forEach((e,i)=>{(A||i.nodeType===11&&!i.host.isConnected)&&(e.remove(),$.delete(i))})},ne=(e=b,i=D)=>{if(b!==e)return;let n=new Set([b,L]);Ae(),b=void 0,L=void 0,D=!1,f.clearTimeout(Pe),n.forEach(a=>Le(a,i)),o.wake()},$e=()=>{if(!b)return;if(L!==b){ne();return}let e=b;de++,f.cancelAnimationFrame(te),te=0,re=le=!1,e.sources.forEach(i=>{w.delete(i),c.delete(i)}),h.forEach(i=>i.removeAttribute("data-native-ui-snapshot-source")),N(e,!!o.opaqueUnderlay),b=void 0,D=!1,f.clearTimeout(Pe),Ve("restored",e.data.token,!0),e.sources.forEach(i=>{W.add(i),q.add(i)}),o.wake()},s=()=>{D&&$e(),ge.forEach(e=>e())},u=e=>e.scopes.map(i=>M(i.element)?i.element:void 0),h=new Set,N=(e,i)=>{for(let n of h)n.toggleAttribute("data-native-ui-snapshot-visible",i),ee(n);e.images.forEach(n=>n.style.setProperty("opacity",i?"1":"0","important"))},F=new Map,Z=new Map,z=()=>{let e=[];for(let[i,n]of Z){let{target:a,frame:T}=n;if(!a.isConnected){i.remove();continue}let S=a.shadowRoot??a;i.parentNode!==S&&S.insertBefore(i,null);let C=a.getBoundingClientRect(),U=i.getBoundingClientRect(),O=parseFloat(i.style.width)||T.width,ae=parseFloat(i.style.height)||T.height,ce=U.width/O||1,We=U.height/ae||1,De=n.scale??(n.scale={x:ce,y:We});e.push({element:i,left:(parseFloat(i.style.left)||0)+(C.x+T.x*ce/De.x-U.x)/ce,top:(parseFloat(i.style.top)||0)+(C.y+T.y*We/De.y-U.y)/We,width:T.width/De.x,height:T.height/De.y})}for(let{element:i,...n}of e)for(let[a,T]of Object.entries(n)){let S=`${T}px`;i.style.getPropertyValue(a)!==S&&i.style.setProperty(a,S,"important")}},Q=(e=b??L)=>{if(!e||D)return!1;if(!e.sources.every(p)||u(e).some(n=>!n))return je(),!1;let i=u(e);if(b){if(i.some(a=>!a?.isConnected||!$.has(G(a))))return ne(b,!1),!1;let n=new Set;for(let[a,T]of e.targets.entries()){let S=F.get(T),C=i[a];!S||!C?.isConnected||(C.setAttribute(g,S),C.setAttribute("data-native-ui-snapshot-source",""),n.add(C))}for(let a of h)n.has(a)||we(a);return h.clear(),n.forEach(a=>h.add(a)),N(e,le),!0}x.forEach(n=>n.forEach(a=>{e.images.includes(a)||(a.style.setProperty("display","none","important"),a.removeAttribute("data-native-ui-projection-image"))})),F.clear(),Z.clear(),h.forEach(we),h.clear();for(let n of new Set(i)){if(!n)continue;h.add(n),ye(G(n));let a=i.flatMap((U,O)=>U===n?[O]:[]),T=`${P}-${a[0]}`;n.setAttribute(g,T),n!==e.targets[a[0]]&&(n.setAttribute("data-native-ui-snapshot-prepared",""),Oe.add(n)),n.toggleAttribute("data-native-ui-snapshot-visible",!!o.opaqueUnderlay),ee(n);let S=n.getBoundingClientRect();n.toggleAttribute("data-native-ui-snapshot-positioned",f.getComputedStyle(n).position==="static");let C=n.shadowRoot??n;for(let U of[...a].reverse()){let O=e.images[U],ae=e.data.parts[U],ce=e.frames[U]??{x:o.opaqueUnderlay?0:ae.x-S.x,y:o.opaqueUnderlay?0:ae.y-S.y,width:ae.width,height:ae.height};e.frames[U]=ce,F.set(e.targets[U],T),O.inert=!0,O.setAttribute("aria-hidden","true"),O.setAttribute("data-native-ui-projection-image",T),O.style.cssText="all:initial!important;position:absolute!important;display:block!important;visibility:visible!important;pointer-events:none!important;image-rendering:pixelated!important;will-change:opacity!important;opacity:0!important;",O.style.setProperty("width",`${ce.width}px`,"important"),O.style.setProperty("height",`${ce.height}px`,"important"),O.style.setProperty("left","0px","important"),O.style.setProperty("top","0px","important"),O.style.setProperty("opacity",o.opaqueUnderlay?"1":"0","important"),O.parentNode!==C&&C.insertBefore(O,null),Z.set(O,{target:n,frame:ce})}}return e.parents=e.scopes.map(n=>n.element.parentNode),z(),!0},X=e=>e.images.map((i,n)=>{let a=i.getBoundingClientRect();return{...e.data.parts[n],x:a.x,y:a.y,width:a.width,height:a.height}}),Ie=()=>{if(s(),A||y==="none"||b)return;let e=L;if(!e||e.viewport!==pe()||!e.sources.every(p)||o.current&&!o.current(e.targets)||e.targets.some(a=>!F.has(a))||u(e).some(a=>!a?.isConnected)||[...h].some(a=>!a.isConnected))return;e.scopes.some((a,T)=>a.element.parentNode!==e.parents[T])&&Q(),z();let i=++de,n=()=>de===i;re=!0,le=!!o.opaqueUnderlay,b=e,oe++,f.clearTimeout(ue),e.sources.forEach(a=>{w.add(a)}),h.forEach(a=>a.setAttribute("data-native-ui-snapshot-source","")),N(e,le),te=f.requestAnimationFrame(()=>{te=0,n()&&(re=!1,o.wake())}),he(k({action:"cover",token:e.data.token,...o.transient?{transient:!0,viewportWidth:f.innerWidth,parts:X(e)}:{}})).then(a=>{if(n()){if(re=!1,a?.shown!==!0){ne(e,!1);return}D||(le=!0,e.sources.forEach(T=>c.add(T)),Q(),z()),f.cancelAnimationFrame(te),te=f.requestAnimationFrame(()=>{te=0,n()&&k({action:"painted",token:e.data.token}).catch(()=>{n()&&ne(e,!1)})}),o.wake()}}).catch(()=>{n()&&ne(e,!1)})},Ze=()=>{if(!(!b||A||D)){if(!b.sources.every(p)||u(b).some(e=>!e)||o.current&&!o.current(b.targets)){ne(b,!1);return}if(!o.blocked()){if(z(),o.transient){let e=b;if(u(e).some(a=>!a?.isConnected)){ne(e,!1);return}let n=X(e);o.opaqueUnderlay||n.every((a,T)=>a.width===e.data.parts[T].width&&a.height===e.data.parts[T].height)?e.data={...e.data,parts:n}:L=void 0,k({action:"restore",token:e.data.token,viewportWidth:f.innerWidth,parts:n}).catch(()=>{})}Te=o.revision?.()??Y?.revision??0,D=!0,b.sources.forEach(e=>w.delete(e)),Pe=f.setTimeout(()=>{D&&ne(b,!1)},250),o.wake()}}},dt=(e,i,n)=>{!D||!b||n===void 0||n<=Te||!o.transient&&e||b.data.parts.every(a=>a.ids.every(T=>i?.includes(T)))&&($e(),ie())},je=(e=!1)=>{ge.forEach(n=>n()),oe++,f.clearTimeout(ue);let i=L;if(L=void 0,(e||A)&&(me=void 0),o.retainPreparedUntilRelease&&!b&&!e&&!A){if(i){let n={};me=n,he(k({action:"release",token:i.data.token})).catch(()=>{}).finally(()=>{if(i.images.forEach(a=>{B(a)}),me===n&&(me=void 0,!(L||b))){for(let a of h)a.getAttribute(g)!==F.get(a)&&(h.delete(a),Oe.delete(a));Ae(),F.clear(),f.dispatchEvent(new Event(d))}})}if(me)return}Le(i),b?ne(b,!1):(Ae(),F.clear(),f.dispatchEvent(new Event(d)))},Qe;try{o.events&&(Qe=await Ye(o.events,(e,i)=>{if(!A){if(e&&(y=e),y==="none"){je();return}e==="web"&&Ie(),e==="native"&&(Ze(),ie()),i&&Me()}}))}catch(e){throw A=!0,je(),await he(Promise.resolve(Ce.remove())).catch(()=>{}),e}return{get owners(){return[...w]},get visibleOwners(){return[...c]},get preparedOwners(){return[...W]},consider:Je,changed:Me,moved:z,get token(){return D?void 0:b?.data.token},begin:Ie,get restoring(){return D},get handoffPending(){return re},retireRestoration:s,end:Ze,updated:dt,invalidate:je,async destroy(){A=!0,je(),x.forEach(e=>e.forEach(i=>i.remove())),x.clear(),await Promise.allSettled([he(Promise.resolve().then(()=>Ce?.remove())),he(Promise.resolve().then(()=>Qe?.remove()))])}}},at=async(t,r,o)=>{let v=await Tt(t,r,o),y=v.consider;return Object.assign(v,{consider:(m,f)=>y(m,f.map(P=>({...P,scope:t})))})};var ct=(t,r)=>{if(t.nodeType!==1||t.namespaceURI!=="http://www.w3.org/1999/xhtml"||!t.ownerDocument||!("style"in t))throw new TypeError("A Web projection scope requires an HTMLElement fallback");if(t.matches("img, input, textarea, select, video, audio, canvas, iframe, embed, object, br, hr, area, base, link, meta, source, track, wbr"))throw new TypeError("A Web projection fallback must be a container element; use the existing fallback container");return Object.freeze({element:t,namespace:r})};var lt=async(t,r,o={addListener:async(v,y)=>globalThis.Capacitor.addListener(t.plugin,v,y)})=>{let v="view",y=t.receiveListeners,m=!1,f=!1,P="native",p="native",M=nt(document),x=()=>P==="native"&&l&&M.isCovered(l)?"web":P,j=!1,B=!1,k=!1,g=!1,d,w,c,W=!1,R=()=>{let s=W;W=!0;try{c?.begin()}finally{W=s}},l,V=0,$,G=()=>{V++,$?.(),$=void 0},ye=async()=>{if(!t.values||!l||m)return;let s=l;G();let u=V,h=()=>!m&&u===V&&l===s&&fe()===s&&s.isConnected;if(s.localName.includes("-")&&!s.matches(":defined")&&Object.values(t.values).some(F=>F.property)){if(await Promise.race([s.ownerDocument.defaultView.customElements.whenDefined(s.localName),new Promise(F=>{$=F})]),!h())return;$=void 0}let N=await r.send({action:"values"}).catch(()=>{});if(h()&&N?.values&&typeof N.values=="object"&&!Array.isArray(N.values))try{tt(s,N.values,t.values)}catch(F){console.warn("[Native UI Engine] Cannot reflect values",F)}},J={},K,ee=0,pe=new Set,re=()=>{},le=new Promise(s=>{re=s}),te=()=>{pe.clear(),re(),le=new Promise(s=>{re=s})},de=()=>{ee++,K=void 0;let s=Ue(l);s?.owner===J&&(s.projected=!1,s.owner=void 0)},L={listen:s=>r.listen(u=>{s(u),!u.active&&B&&(B=!1,Re()),u.precovered&&Je(u.precovered)}),send:s=>{if(!t.placementHandoff)return r.send(s);if(s.action==="visibility"&&!s.visible&&te(),s.action==="visibility"&&s.visible&&pe.size){let z=H,Q=ee,X=l,Ie=le;return Promise.race([Promise.allSettled([...pe]),Ie]).then(()=>m||Ie!==le||z!==H||Q!==ee||X!==l||!X?.isConnected||fe()!==l||x()!=="native"?{}:L.send(s))}let u=Ue(l);if(s.action==="cover"){let z=K===s.token&&u?.owner===J&&u.projected,Q=++ee;return K=s.token,u&&(u.owner=J,u.projected=!!z),r.send(s).then(X=>(Q===ee&&u===Ue(l)&&u?.owner===J&&(u.projected=X?.shown===!0),X)).catch(X=>{throw Q===ee&&u?.owner===J&&(de(),u.invalidate()),X})}let h=s.action==="release"&&s.token===K,N=K&&(s.action==="restore"||h||s.action==="reset"||s.action==="visibility"&&s.visible);N&&ee++;let F=ee,Z=()=>{F!==ee||u?.owner!==J||(de(),u.invalidate())};try{let z=N&&u?.owner===J?{...s,token:"token"in s?s.token:K,placement:u.measure()}:s,Q=r.send(z).then(async X=>(s.action==="release"&&X?.requiresPlacement&&(u&&(!u.owner||u.owner===J)?X=await r.send({...s,placement:u.measure()}):(await r.send({action:"visibility",visible:!1}),X=await r.send(s))),F===ee&&(s.action==="resume"||h||s.action==="reset"||s.action==="visibility")&&de(),X)).catch(X=>{throw Z(),X});return s.action!=="release"||!t.nativeDragHandoff?Q:(pe.add(Q),Q.finally(()=>pe.delete(Q)))}catch(z){return Z(),Promise.reject(z)}}},me=0,b=0,H=0,D,Pe=!1,Te=!1,oe=!1,ue=document.createElement("style"),I=`data-native-ui-session-${t.id.replace(/[^a-zA-Z0-9-]/g,"")}`;ue.textContent=`[${I}="native"], [${I}="native"] *, [${I}="none"], [${I}="none"] * {visibility:hidden!important}`,document.documentElement.append(ue);let fe=()=>{let s=document.querySelectorAll(t.projectionSelector);return s.length===1&&s[0]instanceof HTMLElement?s[0]:void 0},A=()=>{let s=x();l&&l.getAttribute("data-native-ui-destination")!==s&&l.setAttribute("data-native-ui-destination",s),l&&(p==="web"||p==="native"&&k?l.removeAttribute(I):l.setAttribute(I,p))},Fe=()=>{if(!l?.isConnected)return[];let s=l.getBoundingClientRect(),u={x:s.x,y:s.y,width:s.width,height:s.height},h=d&&Ke(l,d,()=>t.id);return[{element:l,scrollElement:d,control:{id:v,...u,...h?{scroll:h}:{}}}]},Y=async()=>{if(m)return;let s=H,u=t.failedFallback==="native"&&x()==="native"&&!!l?.isConnected;await L.send({action:"visibility",visible:u}).catch(()=>{}),!(m||s!==H)&&(u||p==="none"?A():l?.removeAttribute(I))},He=()=>{if(!j||p!=="native"||!l?.isConnected||c?.token||c?.restoring)return;let s=t.failedFallback==="native";L.send({action:"visibility",visible:s}).catch(()=>{}),s?A():l.removeAttribute(I)},ge=()=>{if(m||W)return;if(He(),p==="web"&&c&&!c.token&&!c.restoring){L.send({action:"visibility",visible:!1}).catch(()=>{}),l?.removeAttribute(I);return}if(!c?.restoring||D===c||p!=="native")return;D=c;let s=H,u=c;L.send({action:"resume"}).then(()=>{m||s!==H||u!==c||fe()!==l||(k=!1,u.updated(void 0,[v],++me),A(),q())}).catch(()=>{s!==H||m||(u.invalidate(),Y())}).finally(()=>{D===u&&(D=void 0),ge()})},Ve=async()=>{if(m||Pe)return;if(fe()!==l){H++,j=!1,B=!1,clearTimeout(w),de(),l?.removeAttribute(I),l?.removeAttribute("data-native-ui-destination"),G();let u=c,h=l;c=void 0,l=void 0,Le.disconnect(),Me();try{h&&await L.send({action:"visibility",visible:!1})}finally{await u?.destroy()}if(m)return;l=fe(),k=!1,l&&(Le.observe(l),ye())}if(Me(),!j){if(c?.restoring){ge();return}if(p=x(),!l){await L.send({action:"visibility",visible:!1});return}if(!c){Pe=!0;let u=H;try{let h=await at(ct(l,t.id),L,{wake:ge,captureDelayMs:t.captureDelayMs,retainPreparedUntilRelease:t.nativeDragHandoff,blocked:()=>p!=="native"||j||k&&!c?.token,revision:()=>me,captureRevision:t.captureMode==="view"?()=>b:void 0,transient:!0,opaqueUnderlay:t.captureMode==="view"});if(m||u!==H){await h.destroy();return}c=h}finally{Pe=!1}}if(!m){if(p==="native"&&k){await L.send({action:"visibility",visible:!1}),A();return}if(p==="native"){let u=H;if(await L.send({action:"visibility",visible:!0}),m||u!==H||p!=="native"||j)return;A(),d=[...Ne(l)].find(Z=>{let z=getComputedStyle(Z);return/auto|scroll/.test(z.overflowX+z.overflowY)&&(Z.scrollHeight>Z.clientHeight||Z.scrollWidth>Z.clientWidth)});let h=d&&Ke(l,d,()=>t.id),N=t.nativeDragHandoff&&t.captureMode==="view"&&d?{viewport:d.getBoundingClientRect(),offsetX:d.scrollLeft,offsetY:d.scrollTop,rangeX:Math.max(0,d.scrollWidth-d.clientWidth),rangeY:Math.max(0,d.scrollHeight-d.clientHeight)}:void 0,F=await L.send({action:"track",viewportWidth:innerWidth,...h?{scroll:h}:{},...N?{gesture:N}:{}});if(m||u!==H)return;g=F?.tracked===!0,c.consider(t.captureMode==="view"?b:++me,Fe())}else await L.send({action:"visibility",visible:!1}),A()}}},q=()=>{m||(Te=!0,!(!f||oe)&&(oe=!0,Promise.resolve().then(async()=>{try{for(;Te&&!m;)Te=!1,await Ve()}catch{await Y()}finally{oe=!1,Te&&q()}})))},ke=()=>{c?.invalidate(),q()},Le=new ResizeObserver(ke);window.addEventListener("resize",ke);let se=new Set,ze=new WeakSet,ie=s=>{let u=s.composedPath()[0]??s.target;if(!(m||p!=="native"||!l||ze.has(s)||u!==document&&![...Ne(l)].includes(u))){if(ze.add(s),g&&u===d){c?.changed(u);return}j?t.captureMode==="view"?c?.moved():c?.changed():((D||c?.restoring)&&H++,j=!0,R(),k=t.failedFallback!=="native",c?.token?l.removeAttribute(I):He()),Re()}};function Re(){clearTimeout(w),w=setTimeout(()=>{B||(j=!1,!(m||p!=="native")&&(c?.end(),c?.restoring||q()))},100)}function Je(s){if(m||p!=="native"||!l?.isConnected||!c||(B=!0,c.token))return;(D||c.restoring)&&H++,K=s;let u=Ue(l);if(u&&(u.owner=J,u.projected=!0),j=!0,R(),!c.token){j=!1,Y();return}Re()}let Me=()=>{let s=new Set(l?Ne(l):[]),u=s.size!==se.size||[...s].some(h=>!se.has(h));for(let h of se)s.has(h)||(h.removeEventListener("scroll",ie),h.removeEventListener("slotchange",Ce),se.delete(h));for(let h of s)se.has(h)||(h.addEventListener("scroll",ie,{passive:!0}),h.addEventListener("slotchange",Ce),se.add(h));u&&(g=!1,d=void 0,c?.invalidate(),q())},Ce=()=>{Me(),q()};document.addEventListener("scroll",ie,!0);let Oe=new MutationObserver(s=>{Me(),fe()!==l?q():l&&s.some(u=>u.type==="childList")&&we(x())});Oe.observe(document.documentElement,{childList:!0,attributes:!0,subtree:!0});let we=(s,u=!1)=>{if(m||!u&&s===p)return;j=!1,B=!1,clearTimeout(w),p=s,H++;let h=H;p==="none"?L.send({action:"visibility",visible:!1}).then(()=>{p!=="none"||h!==H||m||(c?.invalidate(!0),A())}).catch(()=>{p!=="none"||h!==H||m||(c?.invalidate(!0),A())}):p==="web"?(R(),c?.token||L.send({action:"visibility",visible:!1}).catch(()=>{}),A()):p==="native"&&(c?.end(),c?.restoring||q())},Ae=M.subscribe(()=>queueMicrotask(()=>we(x()))),ne,$e=async()=>{if(!m){m=!0,te(),G(),de(),H++,Ae(),Oe.disconnect(),Le.disconnect(),window.removeEventListener("resize",ke),document.removeEventListener("scroll",ie,!0);for(let s of se)s.removeEventListener("scroll",ie),s.removeEventListener("slotchange",Ce);se.clear(),clearTimeout(w),l?.removeAttribute(I),l?.removeAttribute("data-native-ui-destination"),ue.remove(),await Promise.allSettled([Promise.resolve(ne?.remove()),c?.destroy()])}};try{let s=H;ne=await Ye({addListener:(h,N)=>o.addListener(h,N),update:y?.update,projection:y?.projection,accepts:h=>!y?.match||Object.entries(y?.match).every(([N,F])=>typeof h=="object"&&h!==null&&h[N]===F)},(h,N)=>{m||(h&&(h==="native"&&(k=!1),P=h,L.send({action:"destination",destination:h}).catch(()=>{}),we(x(),!0)),N&&(ye(),b++,c?.changed(),p==="native"&&q()))});let u=await L.send({action:"connect"});return H===s&&["native","web","none"].includes(u?.destination)&&(P=u.destination),p=x(),f=!0,q(),{destroy:$e,show:()=>{k=!1,P="native",we(x(),!0)},hide:()=>{P=p="none",H++,te(),j=!1,B=!1,clearTimeout(w),c?.invalidate(!0),A()}}}catch(s){throw await $e(),s}};var be=new Map,Ee=new Map,Be=new Map,Lt=Array.from(crypto.getRandomValues(new Uint32Array(4)),t=>t.toString(16)).join("-"),qe=new Map,Mt=(t,r,o)=>qe.get(t)?.get(r)?.(o),jt=0,St=(t,r)=>new Promise((o,v)=>{let y=`${t}:${Lt}:${++jt}`,m=setTimeout(()=>{Ee.delete(y),v(new Error("Native UI session timed out"))},5e3);Ee.set(y,{resolve:o,reject:v,timer:m});let f=JSON.stringify({key:y,request:r}),P=globalThis,p=P.webkit?.messageHandlers?.[t]??P[t]??P.nativeUIEngine;if(!p){clearTimeout(m),Ee.delete(y),v(new Error("Native UI session unavailable"));return}try{p.postMessage(f)}catch(M){clearTimeout(m),Ee.delete(y),v(M)}}),xt=(t,r,o,v)=>{if(r===null){Be.get(t)?.(o);return}let y=Ee.get(r);!y||!r.startsWith(`${t}:`)||(Ee.delete(r),clearTimeout(y.timer),v?y.reject(new Error(v)):y.resolve(o))},Ht=t=>{be.get(t)?.show()},kt=t=>(be.get(t)?.hide(),!0),Rt=async t=>{let r=be.get(t);be.delete(t),qe.delete(t),Be.delete(t);for(let[o,v]of Ee)o.startsWith(`${t}:`)&&(Ee.delete(o),clearTimeout(v.timer),v.reject(new Error("Native UI session closed")));await r?.destroy()},Ct=async t=>{if(be.has(t.id))return;let r,o=!1,v,y={show:()=>{v="native",r?.show()},hide:()=>{v="none",r?.hide()},destroy:async()=>{o=!0,await r?.destroy()}};be.set(t.id,y);try{if(document.readyState==="loading"&&await new Promise(f=>document.addEventListener("DOMContentLoaded",()=>f(),{once:!0})),o)return;let m=new Map;t.runtime==="cordova"&&qe.set(t.id,m),r=await lt(t,{send:f=>St(t.id,f),listen:async f=>(Be.set(t.id,f),{remove:()=>{Be.get(t.id)===f&&Be.delete(t.id)}})},t.runtime==="cordova"?{addListener:async(f,P)=>(m.set(f,P),{remove:()=>{m.delete(f)}})}:void 0),v==="none"?r.hide():v==="native"&&r.show(),o&&await r.destroy()}catch(m){throw be.get(t.id)===y&&(be.delete(t.id),qe.delete(t.id)),m}};return ht(Ot);})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webview-native-ui/engine",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Native UI placement, scroll tracking, and Web projection for Capacitor and Cordova plugin maintainers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
"prepublishOnly": "npm run build",
|
|
36
36
|
"test:release": "node --test scripts/native-ui-engine-release/*.test.mjs",
|
|
37
37
|
"test:package": "node scripts/verify-package.mjs",
|
|
38
|
-
"release": "np --no-publish --no-tests --branch main",
|
|
39
38
|
"test:cordova": "node scripts/verify-cordova.mjs",
|
|
40
39
|
"format:check": "prettier --check \"**/*.{ts,js,mjs,cjs,json,md,yml,yaml,html}\"",
|
|
41
40
|
"swiftlint": "node-swiftlint",
|
|
@@ -51,7 +50,6 @@
|
|
|
51
50
|
"esbuild": "^0.27.0",
|
|
52
51
|
"eslint": "^10.13.0",
|
|
53
52
|
"globals": "^17.13.0",
|
|
54
|
-
"np": "^10.2.0",
|
|
55
53
|
"prettier": "^3.6.2",
|
|
56
54
|
"swiftlint": "^2.0.0",
|
|
57
55
|
"typescript": "^5.9.3",
|