@webview-native-ui/engine 0.0.4 → 0.0.6
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/README.md +1 -0
- package/dist/dom/visibility.js +1 -0
- package/dist/projection/scope.js +1 -1
- package/dist/projection/styles.d.ts +2 -2
- package/dist/projection/styles.js +20 -9
- package/dist/projection/web.js +259 -185
- package/dist/types.d.ts +4 -0
- package/docs/capacitor-plugin.md +4 -0
- package/docs/cordova-plugin.md +4 -0
- package/docs/projection-containers.md +195 -0
- package/docs/projection.md +30 -16
- package/ios/Sources/WebViewNativeUIEngine/CoveredSnapshots.swift +2 -2
- package/ios/Sources/WebViewNativeUIEngine/NativeUIProjection.swift +35 -22
- package/ios/Sources/WebViewNativeUIEngine/Resources/native-ui-engine.js +20 -12
- package/ios/Sources/WebViewNativeUIEngine/ScrollBindings.swift +1 -0
- package/ios/Sources/WebViewNativeUIEngine/ScrollTracker.swift +1 -1
- package/package.json +2 -2
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
"use strict";var WebViewNativeUIEngineRuntime=(()=>{var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
visibility:visible!important;opacity:0!important;will-change:opacity!important;
|
|
9
|
-
pointer-events:none!important;image-rendering:pixelated!important;
|
|
1
|
+
"use strict";var WebViewNativeUIEngineRuntime=(()=>{var _e=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var ft=Object.prototype.hasOwnProperty;var pt=(t,i)=>{for(var r in i)_e(t,r,{get:i[r],enumerable:!0})},mt=(t,i,r,v)=>{if(i&&typeof i=="object"||typeof i=="function")for(let h of ut(i))!ft.call(t,h)&&h!==r&&_e(t,h,{get:()=>i[h],enumerable:!(v=dt(i,h))||v.enumerable});return t};var vt=t=>mt(_e({},"__esModule",{value:!0}),t);var Rt={};pt(Rt,{hide:()=>Ht,notify:()=>Lt,receive:()=>St,show:()=>xt,start:()=>Ct,stop:()=>kt});var ht=Symbol.for("webview-native-ui-engine.projection-placement");var Ne=t=>t?.[ht];var yt=(t,i)=>{if(t.matches("ion-toast, ion-menu"))return!1;let r=t;if(r.showBackdrop===!1)return!1;if(!t.matches("ion-modal"))return!0;let v=i??r.initialBreakpoint;return v===void 0||v>(r.backdropBreakpoint??0)},gt=Symbol.for("@webview-native-ui/engine/overlays/v1"),wt=t=>{let i=new Set,r=new Set,v=new Set,h=new WeakMap,d=new WeakSet,p=new Map,T=[],f={},L=new Map,C,j=y=>{for(let l of[...v])try{l(y)}catch(g){console.error("Native UI overlay listener failed",g)}},B=(y,l,g)=>{l==="willPresent"||l==="didPresent"?(d.delete(y),i.add(y)):l==="didDismiss"&&(d.add(y),i.delete(y),r.delete(y),h.delete(y));let c=g?.detail?.breakpoint;typeof c=="number"&&c>0&&h.set(y,c),j({element:y,phase:l,event:g})},S=(y=!1)=>{let l=!1;for(let g of i)(!g.isConnected||g.ownerDocument!==t||!T.some(({selector:c})=>g.matches(c)))&&(i.delete(g),r.delete(g),l=!0);for(let g of t.querySelectorAll(T.map(({selector:c})=>c).join(",")))!i.has(g)&&!d.has(g)&&(y||!g.matches("ion-popover"))&&(g.presented||g.classList.contains("show-menu"))&&(i.add(g),l=!0);l&&j({phase:"change"})};return{get active(){return i},subscribe(y){return v.add(y),()=>{v.delete(y)}},setNative(y,l){r.has(y)!==l&&(l?r.add(y):r.delete(y),j({element:y,phase:"change"}))},isExcluded(y){return!!f.exclude&&y.matches(f.exclude)},isNative(y){return r.has(y)},get stack(){let y=[...i].filter(g=>g.isConnected&&g.ownerDocument===t),l=g=>{let c=Number.parseFloat(t.defaultView.getComputedStyle(g).zIndex);return Number.isFinite(c)?c:g.overlayIndex??0};return y.sort((g,c)=>l(g)-l(c)),y},isCovered(y){let l=this.stack,g=l.reduce((c,D,x)=>D.contains(y)?x:c,-1);return l.some((c,D)=>{if(r.has(c)||f.exclude&&c.matches(f.exclude))return!1;let x=f.covers?.(c,y);return x!==void 0?x:D>g&&!c.contains(y)&&(c.matches("ion-menu")||yt(c,h.get(c)))})},enable(y,l){let g={...f,...l},c=[...y,...g.additional??[]];g.exclude&&t.querySelector(g.exclude);let D=new Map;for(let m of c){t.querySelector(m.selector);for(let[O,A]of Object.entries(m.events)){let N=D.get(A);if(N&&N.phase!==O)throw new TypeError(`Overlay event "${A}" has conflicting phases`);D.set(A,{phase:O,selector:N?`${N.selector}, ${m.selector}`:m.selector})}}f=g,T=c,L=D;for(let m of L.keys()){if(p.has(m))continue;let O=A=>{let N=L.get(m),oe=A.composedPath().find(F=>F instanceof t.defaultView.HTMLElement&&F.matches(N.selector));oe&&B(oe,N.phase,A)};t.addEventListener(m,O,!0),p.set(m,()=>t.removeEventListener(m,O,!0))}for(let[m,O]of p)L.has(m)||(O(),p.delete(m));let x=!C;C||(C=new MutationObserver(()=>S()),C.observe(t.documentElement,{childList:!0,subtree:!0}),t.addEventListener("nativeUIOverlayAdopted",m=>{let O=m.detail;O?.ownerDocument===t&&B(O,"willPresent",m)})),S(x),(x||l)&&j({phase:"change"})}}},tt=t=>{let i=t;return i[gt]??=wt(t)};function*We(t){let i=t;for(;i;){let r=i.getRootNode();i=i.assignedSlot??i.parentElement??(r instanceof ShadowRoot?r.host:null),i&&(yield i)}}var bt=({x:t,y:i,width:r,height:v})=>({x:t,y:i,width:r,height:v}),nt=t=>{let i=t.getBoundingClientRect(),r=getComputedStyle(t),v=parseFloat(r.borderLeftWidth)||0,h=parseFloat(r.borderTopWidth)||0;return{x:i.left+v,y:i.top+h,width:i.width-v-(parseFloat(r.borderRightWidth)||0),height:i.height-h-(parseFloat(r.borderBottomWidth)||0)}},Ge=(t,i,r)=>{let v=[t,...We(t)],h=v.indexOf(i);if(h<=0||i===t.ownerDocument.scrollingElement)return;let d=t.ownerDocument.defaultView;if(d.visualViewport&&(d.visualViewport.scale!==1||d.visualViewport.offsetLeft||d.visualViewport.offsetTop))return;let p=0,T=0,f=d.innerWidth,L=d.innerHeight;for(let[S,y]of v.entries()){let l=getComputedStyle(y);if(l.transform!=="none"&&!new DOMMatrixReadOnly(l.transform).isIdentity||l.zoom&&l.zoom!=="normal"&&Number(l.zoom)!==1||[l.translate,l.rotate,l.scale,l.perspective].some(x=>x&&x!=="none")||l.writingMode&&l.writingMode!=="horizontal-tb"||S<h&&/^(fixed|sticky)$/.test(l.position))return;if(S===0)continue;if(l.scrollbarGutter&&l.scrollbarGutter!=="auto")return;let g=/^(auto|scroll|hidden|clip)$/.test(l.overflowX),c=/^(auto|scroll|hidden|clip)$/.test(l.overflowY);if(S<h&&(g||c))return;let D=y===t.ownerDocument.scrollingElement;if(S>h&&((g||D)&&y.scrollWidth>y.clientWidth||(c||D)&&y.scrollHeight>y.clientHeight)||(g||c)&&[l.borderTopLeftRadius,l.borderTopRightRadius,l.borderBottomLeftRadius,l.borderBottomRightRadius].some(x=>parseFloat(x)>0)||l.clipPath&&l.clipPath!=="none"||l.maskImage&&l.maskImage!=="none")return;if(S>=h){let x=nt(y);g&&(p=Math.max(p,x.x),f=Math.min(f,x.x+x.width)),c&&(T=Math.max(T,x.y),L=Math.min(L,x.y+x.height))}}let C=getComputedStyle(i);if(!/^(auto|scroll)$/.test(C.overflowX)&&!/^(auto|scroll)$/.test(C.overflowY))return;let j=nt(i);if(f<=p||L<=T||!j.width||!j.height)return;let B=bt(t.getBoundingClientRect());return{id:r(i),offsetX:i.scrollLeft,offsetY:i.scrollTop,viewport:j,clip:{x:p,y:T,width:f-p,height:L-T},contentWidth:i.scrollWidth,contentHeight:i.scrollHeight,frame:{...B,x:B.x-j.x+i.scrollLeft,y:B.y-j.y+i.scrollTop}}};var ot=t=>{let i=globalThis;if(i.Capacitor?.convertFileSrc)return i.Capacitor.convertFileSrc(t);if(!t.startsWith("file:"))return t;if(i.WkWebView?.convertFilePath)return i.WkWebView.convertFilePath(t);throw new Error("Native UI file URL requires a host resource handler")};var pe=t=>new Promise((i,r)=>{let v=setTimeout(()=>r(new Error("Native UI bridge timed out")),5e3);t.then(i,r).finally(()=>clearTimeout(v))}),Be=async t=>{try{return await pe(t)}catch(i){throw t.then(r=>r.remove()).catch(()=>{}),i}};var ze=async(t,i)=>{let r=new Map;for(let T of t.update??[])r.set(T,{updated:!0});for(let T of["native","web","none"])for(let f of t.projection?.[T]??[]){let L=r.get(f)??{updated:!1};if(L.destination&&L.destination!==T)throw new TypeError(`Projection event "${f}" has conflicting destinations`);r.set(f,{...L,destination:T})}let v=!1,h=[],d=async()=>{v=!0;let f=(await Promise.allSettled(h.splice(0).map(L=>Promise.resolve().then(()=>L.remove())))).find(L=>L.status==="rejected");if(f?.status==="rejected")throw f.reason},p=[...r].map(async([T,f])=>{let L=await Be(Promise.resolve().then(()=>t.addListener(T,C=>{!v&&(!t.accepts||t.accepts(C))&&i(f.destination,f.updated)})));v?await L.remove():h.push(L)});try{return await Promise.all(p),{remove:d}}catch(T){throw await d().catch(()=>{}),T}};var je=":is([data-native-ui-snapshot-source], [data-native-ui-snapshot-prepared], [data-native-ui-snapshot-content])",rt=`
|
|
2
|
+
@layer native-ui-projection {
|
|
3
|
+
${je}, ${je} *, ${je}::part(native) { visibility: hidden !important; }
|
|
4
|
+
${je}::before, ${je}::after,
|
|
5
|
+
${je} *::before, ${je} *::after {
|
|
6
|
+
visibility: hidden !important;
|
|
7
|
+
}
|
|
10
8
|
}
|
|
11
9
|
[data-native-ui-snapshot-visible] { opacity:1!important;overflow:visible!important; }
|
|
12
|
-
[data-native-ui-snapshot-visible][data-native-ui-snapshot
|
|
13
|
-
|
|
14
|
-
`),x.forEach(({target:C,x:Q,y:ne},oe)=>G.set(C,{x:Q,y:ne,style:r.sheet.cssRules[oe*2+1].style}))},Ye=()=>{if(f(),X||v==="none"||w)return;let t=R;if(!t||t.viewport!==I()||!t.sources.every(u)||n.current&&!n.current(t.targets)||t.targets.some(r=>!K.has(r))||b(t).some(r=>!r?.isConnected)||[...D].some(r=>!r.isConnected))return;t.scopes.some((r,L)=>r.element.parentNode!==t.parents[L])&&Fe(),Y();let s=++ve,g=()=>ve===s;F=!0,q=!!n.opaqueUnderlay,w=t,$++,d.clearTimeout(se),t.sources.forEach(r=>{O.add(r)}),D.forEach(r=>{r.setAttribute("data-native-ui-snapshot-source",""),r.toggleAttribute("data-native-ui-snapshot-visible",q)}),W=d.requestAnimationFrame(()=>{W=0,g()&&(F=!1,n.wake())}),ce(M({action:"cover",token:t.data.token,...n.transient?{transient:!0}:{}})).then(r=>{if(g()){if(F=!1,r?.shown!==!0){te(t,!1);return}z||(q=!0,t.sources.forEach(L=>h.add(L)),Fe(),Y(),ae()),d.cancelAnimationFrame(W),W=d.requestAnimationFrame(()=>{W=0,g()&&M({action:"painted",token:t.data.token}).catch(()=>{g()&&te(t,!1)})}),n.wake()}}).catch(()=>{g()&&te(t,!1)})},qe=()=>{if(!(!w||X||z)){if(!w.sources.every(u)||b(w).some(t=>!t)||n.current&&!n.current(w.targets)){te(w,!1);return}if(!n.blocked()){if(n.transient){let t=w,s=b(t);if(s.some(r=>!r?.isConnected)){te(t,!1);return}let g=s.map((r,L)=>{let x=Qe(r,d),C=t.frames[L];return{...t.data.parts[L],x:x.x+C.x*x.scaleX,y:x.y+C.y*x.scaleY,width:C.width*x.scaleX,height:C.height*x.scaleY}});g.some((r,L)=>["x","y","width","height"].some(x=>r[x]!==t.data.parts[L][x]))&&(n.opaqueUnderlay?t.data={...t.data,parts:g}:R=void 0),M({action:"restore",token:t.data.token,viewportWidth:d.innerWidth,parts:g}).catch(()=>{})}Pe=n.revision?.()??_?.revision??0,z=!0,w.sources.forEach(t=>O.delete(t)),he=d.setTimeout(()=>{z&&te(w,!1)},250),n.wake()}}},ot=(t,s,g)=>{!z||!w||g===void 0||g<=Pe||!n.transient&&t||w.data.parts.every(r=>r.ids.every(L=>s?.includes(L)))&&(i(),re())},we=(t=!1)=>{Le.forEach(g=>g()),$++,d.clearTimeout(se);let s=R;if(R=void 0,(t||X)&&(k=void 0),n.retainPreparedUntilRelease&&!w&&!t&&!X){if(s){let g={};k=g,ce(M({action:"release",token:s.data.token})).catch(()=>{}).finally(()=>{if(s.images.forEach(r=>{r.src=""}),k===g&&(k=void 0,!(R||w))){for(let r of D)r.getAttribute(T)!==K.get(r)&&(D.delete(r),ue.delete(r));ye(),K.clear(),d.dispatchEvent(new Event(N))}})}if(k)return}ee(s),w?te(w,!1):(ye(),K.clear(),d.dispatchEvent(new Event(N)))},_e;try{n.events&&(_e=await Ie(n.events,(t,s)=>{if(!X){if(t&&(v=t),v==="none"){we();return}t==="web"&&Ye(),t==="native"&&(qe(),re()),s&&Se()}}))}catch(t){throw X=!0,we(),await ce(Promise.resolve(Ce.remove())).catch(()=>{}),t}return{get owners(){return[...O]},get visibleOwners(){return[...h]},get preparedOwners(){return[...c]},consider:ke,changed:Se,moved:()=>{Y(),ae()},get token(){return z?void 0:w?.data.token},begin:Ye,get restoring(){return z},get handoffPending(){return F},retireRestoration:f,end:qe,updated:ot,invalidate:we,async destroy(){X=!0,we(),await Promise.allSettled([ce(Promise.resolve().then(()=>Ce?.remove())),ce(Promise.resolve().then(()=>_e?.remove()))])}}},et=async(e,o,n)=>{let p=await yt(e,o,n),v=p.consider;return Object.assign(p,{consider:(l,d)=>v(l,d.map(E=>({...E,scope:e})))})};var tt=(e,o)=>{if(e.nodeType!==1||e.namespaceURI!=="http://www.w3.org/1999/xhtml"||!e.ownerDocument||!("style"in e))throw new TypeError("A Web projection scope requires an HTMLElement fallback");if(e.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 support ::before; use its existing container element");return Object.freeze({element:e,namespace:o})};var nt=async(e,o,n={addListener:async(p,v)=>globalThis.Capacitor.addListener(e.plugin,p,v)})=>{let p="view",v=e.receiveListeners,l=!1,d=!1,E="native",u="native",S=Ke(document),M=()=>E==="native"&&m&&S.isCovered(m)?"web":E,T=!1,N=!1,O=!1,h=!1,c,y,a,U=!1,j=()=>{let i=U;U=!0;try{a?.begin()}finally{U=i}},m,A={},I,F=0,q=()=>{F++,I=void 0;let i=De(m);i?.owner===A&&(i.projected=!1,i.owner=void 0)},W={listen:i=>o.listen(f=>{i(f),!f.active&&N&&(N=!1,re()),f.precovered&&Ae(f.precovered)}),send:i=>{if(!e.placementHandoff)return o.send(i);let f=De(m);if(i.action==="cover"){let J=I===i.token&&f?.owner===A&&f.projected,Y=++F;return I=i.token,f&&(f.owner=A,f.projected=!!J),o.send(i).then(ae=>(Y===F&&f===De(m)&&f?.owner===A&&(f.projected=ae?.shown===!0),ae)).catch(ae=>{throw Y===F&&f?.owner===A&&(q(),f.invalidate()),ae})}let b=i.action==="release"&&i.token===I,D=I&&(i.action==="restore"||b||i.action==="reset"||i.action==="visibility"&&i.visible);D&&F++;let K=F,G=()=>{K!==F||f?.owner!==A||(q(),f.invalidate())};try{let J=D&&f?.owner===A?{...i,token:"token"in i?i.token:I,placement:f.measure()}:i;return o.send(J).then(async Y=>(i.action==="release"&&Y?.requiresPlacement&&(f&&(!f.owner||f.owner===A)?Y=await o.send({...i,placement:f.measure()}):(await o.send({action:"visibility",visible:!1}),Y=await o.send(i))),K===F&&(i.action==="resume"||b||i.action==="reset"||i.action==="visibility")&&q(),Y)).catch(Y=>{throw G(),Y})}catch(J){return G(),Promise.reject(J)}}},ve=0,R=0,k=0,w=!1,le=!1,z=!1,he=!1,Pe=document.createElement("style"),$=`data-native-ui-session-${e.id.replace(/[^a-zA-Z0-9-]/g,"")}`;Pe.textContent=`[${$}="native"], [${$}="native"] *, [${$}="none"], [${$}="none"] * {visibility:hidden!important}`,document.documentElement.append(Pe);let se=()=>{let i=document.querySelectorAll(e.projectionSelector);return i.length===1&&i[0]instanceof HTMLElement?i[0]:void 0},B=()=>{m&&(u==="web"||u==="native"&&O?m.removeAttribute($):m.setAttribute($,u))},xe=()=>{if(!m?.isConnected)return[];let i=m.getBoundingClientRect(),f={x:i.x,y:i.y,width:i.width,height:i.height},b=c&&Xe(m,c,()=>e.id);return[{element:m,scrollElement:c,control:{id:p,...f,...b?{scroll:b}:{}}}]},X=async()=>{if(l)return;let i=k,f=e.failedFallback==="native"&&M()==="native"&&!!m?.isConnected;await W.send({action:"visibility",visible:f}).catch(()=>{}),!(l||i!==k)&&(f||u==="none"?B():m?.removeAttribute($))},Te=()=>{if(!T||u!=="native"||!m?.isConnected||a?.token||a?.restoring)return;let i=e.failedFallback==="native";W.send({action:"visibility",visible:i}).catch(()=>{}),i?B():m.removeAttribute($)},_=()=>{if(l||U)return;if(Te(),u==="web"&&a&&!a.token&&!a.restoring){W.send({action:"visibility",visible:!1}).catch(()=>{}),m?.removeAttribute($);return}if(w||!a?.restoring||u!=="native")return;w=!0;let i=k,f=a;W.send({action:"resume"}).then(()=>{l||i!==k||f!==a||(O=!1,f.updated(void 0,[p],++ve),B(),Z())}).catch(()=>{i!==k||l||(f.invalidate(),X())}).finally(()=>{w=!1,_()})},Le=async()=>{if(l||le||T)return;if(a?.restoring){_();return}let i=se();if(i!==m){if(k++,q(),m?.removeAttribute($),await a?.destroy(),a=void 0,l)return;m=i,O=!1,Me.disconnect(),m&&Me.observe(m)}if(ke(),u=M(),!m){await W.send({action:"visibility",visible:!1});return}if(!a){le=!0;let f=k;try{let b=await et(tt(m,e.id),W,{wake:_,captureDelayMs:e.captureDelayMs,retainPreparedUntilRelease:e.nativeDragHandoff,blocked:()=>u!=="native"||T||O&&!a?.token,revision:()=>ve,captureRevision:e.captureMode==="view"?()=>R:void 0,transient:!0,opaqueUnderlay:e.captureMode==="view"});if(l||f!==k){await b.destroy();return}a=b}finally{le=!1}}if(!l){if(u==="native"&&O){await W.send({action:"visibility",visible:!1}),B();return}if(u==="native"){let f=k;if(await W.send({action:"visibility",visible:!0}),l||f!==k||u!=="native")return;B(),c=[...fe(m)].find(G=>{let J=getComputedStyle(G);return/auto|scroll/.test(J.overflowX+J.overflowY)&&(G.scrollHeight>G.clientHeight||G.scrollWidth>G.clientWidth)});let b=c&&Xe(m,c,()=>e.id),D=e.nativeDragHandoff&&e.captureMode==="view"&&c?{viewport:c.getBoundingClientRect(),offsetX:c.scrollLeft,offsetY:c.scrollTop,rangeX:Math.max(0,c.scrollWidth-c.clientWidth),rangeY:Math.max(0,c.scrollHeight-c.clientHeight)}:void 0,K=await W.send({action:"track",viewportWidth:innerWidth,...b?{scroll:b}:{},...D?{gesture:D}:{}});if(l||f!==k)return;h=K?.tracked===!0,a.consider(e.captureMode==="view"?R:++ve,xe())}else await W.send({action:"visibility",visible:!1}),B()}},Z=()=>{l||(z=!0,!(!d||he)&&(he=!0,Promise.resolve().then(async()=>{try{for(;z&&!l;)z=!1,await Le()}catch{await X()}finally{he=!1,z&&Z()}})))},de=()=>{a?.invalidate(),Z()},Me=new ResizeObserver(de);window.addEventListener("resize",de);let ee=new Set,He=new WeakSet,ge=i=>{let f=i.composedPath()[0]??i.target;if(!(l||u!=="native"||!m||He.has(i)||f!==document&&![...fe(m)].includes(f))){if(He.add(i),h&&f===c){a?.changed(f);return}T?e.captureMode==="view"?a?.moved():a?.changed():((w||a?.restoring)&&k++,T=!0,j(),O=e.failedFallback!=="native",a?.token?m.removeAttribute($):Te()),re()}};function re(){clearTimeout(y),y=setTimeout(()=>{N||(T=!1,!(l||u!=="native")&&(a?.end(),a?.restoring||Z()))},100)}function Ae(i){if(l||u!=="native"||!m?.isConnected||!a||(N=!0,a.token))return;(w||a.restoring)&&k++,I=i;let f=De(m);if(f&&(f.owner=A,f.projected=!0),T=!0,j(),!a.token){T=!1,X();return}re()}let ke=()=>{let i=new Set(m?fe(m):[]),f=i.size!==ee.size||[...i].some(b=>!ee.has(b));for(let b of ee)i.has(b)||(b.removeEventListener("scroll",ge),b.removeEventListener("slotchange",Se),ee.delete(b));for(let b of i)ee.has(b)||(b.addEventListener("scroll",ge,{passive:!0}),b.addEventListener("slotchange",Se),ee.add(b));f&&(h=!1,c=void 0,a?.invalidate(),Z())},Se=()=>{ke(),Z()};document.addEventListener("scroll",ge,!0);let Ce=new MutationObserver(i=>{ke(),se()!==m?Z():m&&i.some(f=>f.type==="childList")&&ue(M())});Ce.observe(document.documentElement,{childList:!0,attributes:!0,subtree:!0});let ue=(i,f=!1)=>{if(l||!f&&i===u)return;T=!1,N=!1,clearTimeout(y),u=i,k++;let b=k;u==="none"?W.send({action:"visibility",visible:!1}).then(()=>{u!=="none"||b!==k||l||(a?.invalidate(!0),B())}).catch(()=>{u!=="none"||b!==k||l||(a?.invalidate(!0),B())}):u==="web"?(j(),a?.token||W.send({action:"visibility",visible:!1}).catch(()=>{}),B()):u==="native"&&(a?.end(),a?.restoring||Z())},We=S.subscribe(()=>queueMicrotask(()=>ue(M()))),ye,te=async()=>{if(!l){l=!0,q(),k++,We(),Ce.disconnect(),Me.disconnect(),window.removeEventListener("resize",de),document.removeEventListener("scroll",ge,!0);for(let i of ee)i.removeEventListener("scroll",ge),i.removeEventListener("slotchange",Se);ee.clear(),clearTimeout(y),m?.removeAttribute($),Pe.remove(),await Promise.allSettled([Promise.resolve(ye?.remove()),a?.destroy()])}};try{let i=k;ye=await Ie({addListener:(b,D)=>n.addListener(b,D),update:v?.update,projection:v?.projection,accepts:b=>!v?.match||Object.entries(v?.match).every(([D,K])=>typeof b=="object"&&b!==null&&b[D]===K)},(b,D)=>{l||(b&&(b==="native"&&(O=!1),E=b,W.send({action:"destination",destination:b}).catch(()=>{}),ue(M(),!0)),D&&(R++,a?.changed(),u==="native"&&Z()))});let f=await W.send({action:"connect"});return k===i&&["native","web","none"].includes(f?.destination)&&(E=f.destination),u=M(),d=!0,Z(),{destroy:te,show:()=>{O=!1,E="native",ue(M(),!0)},hide:()=>{E=u="none",k++,T=!1,N=!1,clearTimeout(y),a?.invalidate(!0),B()}}}catch(i){throw await te(),i}};var pe=new Map,me=new Map,Re=new Map,wt=Array.from(crypto.getRandomValues(new Uint32Array(4)),e=>e.toString(16)).join("-"),ze=new Map,bt=(e,o,n)=>ze.get(e)?.get(o)?.(n),Et=0,Pt=(e,o)=>new Promise((n,p)=>{let v=`${e}:${wt}:${++Et}`,l=setTimeout(()=>{me.delete(v),p(new Error("Native UI session timed out"))},5e3);me.set(v,{resolve:n,reject:p,timer:l});let d=JSON.stringify({key:v,request:o}),E=globalThis,u=E.webkit?.messageHandlers?.[e]??E[e]??E.nativeUIEngine;if(!u){clearTimeout(l),me.delete(v),p(new Error("Native UI session unavailable"));return}try{u.postMessage(d)}catch(S){clearTimeout(l),me.delete(v),p(S)}}),Tt=(e,o,n,p)=>{if(o===null){Re.get(e)?.(n);return}let v=me.get(o);!v||!o.startsWith(`${e}:`)||(me.delete(o),clearTimeout(v.timer),p?v.reject(new Error(p)):v.resolve(n))},Lt=e=>{pe.get(e)?.show()},Mt=e=>(pe.get(e)?.hide(),!0),St=async e=>{let o=pe.get(e);pe.delete(e),ze.delete(e),Re.delete(e);for(let[n,p]of me)n.startsWith(`${e}:`)&&(me.delete(n),clearTimeout(p.timer),p.reject(new Error("Native UI session closed")));await o?.destroy()},jt=async e=>{if(pe.has(e.id))return;let o,n=!1,p,v={show:()=>{p="native",o?.show()},hide:()=>{p="none",o?.hide()},destroy:async()=>{n=!0,await o?.destroy()}};pe.set(e.id,v);try{if(document.readyState==="loading"&&await new Promise(d=>document.addEventListener("DOMContentLoaded",()=>d(),{once:!0})),n)return;let l=new Map;e.runtime==="cordova"&&ze.set(e.id,l),o=await nt(e,{send:d=>Pt(e.id,d),listen:async d=>(Re.set(e.id,d),{remove:()=>{Re.get(e.id)===d&&Re.delete(e.id)}})},e.runtime==="cordova"?{addListener:async(d,E)=>(l.set(d,E),{remove:()=>{l.delete(d)}})}:void 0),p==="none"?o.hide():p==="native"&&o.show(),n&&await o.destroy()}catch(l){throw pe.get(e.id)===v&&(pe.delete(e.id),ze.delete(e.id)),l}};return ut(xt);})();
|
|
10
|
+
[data-native-ui-snapshot-visible][data-native-ui-snapshot-positioned] { position:relative!important; }
|
|
11
|
+
`,it=`
|
|
12
|
+
@layer native-ui-projection {
|
|
13
|
+
:host([data-native-ui-snapshot-content]),
|
|
14
|
+
:host([data-native-ui-snapshot-content])::before,
|
|
15
|
+
:host([data-native-ui-snapshot-content])::after,
|
|
16
|
+
:host([data-native-ui-snapshot-content]) *,
|
|
17
|
+
:host([data-native-ui-snapshot-content]) *::before,
|
|
18
|
+
:host([data-native-ui-snapshot-content]) *::after {
|
|
19
|
+
visibility: hidden !important;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
`;var Et=(t,i=!1)=>JSON.stringify(t.map(({control:r})=>[r.id,r.kind,r.placement,i?0:r.x,i?0:r.y,r.width,r.height,r.dark,r.rtl])),Pt=async(t,i,r)=>{let v=r.captureDelayMs??50;if(!Number.isFinite(v)||v<0||v>2147483647)throw new RangeError("captureDelayMs must be a finite, nonnegative timer interval");let h="native",d=t.element.ownerDocument,p=d.defaultView,T=Array.from(p.crypto.getRandomValues(new Uint32Array(4)),e=>e.toString(16)).join("-"),f=e=>e.isConnected&&e.ownerDocument===d,L=e=>!!e?.isConnected&&e.ownerDocument===d,C=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"),le()},S=i.send.bind(i),y="data-native-ui-snapshot",l=`${t.namespace}:sources-change`,g=new Set,c=new Set,D=new Set,x=new WeakMap,m=0,O=e=>JSON.stringify(e.map(o=>{x.has(o.scope)||x.set(o.scope,++m);let n=r.transient&&!r.opaqueUnderlay?o.scope.element.getBoundingClientRect():void 0,s=n?{...o,control:{...o.control,x:o.control.x-n.x,y:o.control.y-n.y}}:o;return[x.get(o.scope),Et([s],!!r.opaqueUnderlay)]})),A=new Map,N=e=>{let o=e.getRootNode();return o.nodeType===11&&"host"in o?o:d},oe=e=>{if(A.has(e))return;let o=d.createElement("style");o.setAttribute("data-native-ui-snapshot-base",""),o.textContent=rt+(e.nodeType===11?it:""),(e.nodeType===11?e:e.head).append(o),A.set(e,o)},F=e=>{let o=[...e.getAnimations({subtree:!0}),...[...se.get(e)??[]].flatMap(n=>n.shadowRoot?.getAnimations()??[])];for(let n of o)"transitionProperty"in n&&n.transitionProperty==="visibility"&&n.cancel()},se=new Map,Se=e=>{let o=se.get(e)??new Set;se.set(e,o);let n=e.hasAttribute("data-native-ui-snapshot-source")||e.hasAttribute("data-native-ui-snapshot-prepared"),s=P=>{if(!P.hasAttribute("data-native-ui-projection-node")){if(P.shadowRoot){o.add(P),oe(P.shadowRoot);for(let M of P.shadowRoot.children)s(M)}for(let M of P.children)s(M)}};s(e);for(let P of o)P.toggleAttribute("data-native-ui-snapshot-content",n);F(e)},W=()=>`${p.innerWidth}:${p.innerHeight}:${p.devicePixelRatio}`,Z=!1,ae=!1,J=0,me=0,R,U,b,q=!1,X=!1,we=0,Oe=0,ee=0,ve=0,z=0,be=-1,V=!1,te=!1,Y,le=()=>{let e=new Set(Y?.candidates.map(n=>n.scope.element));for(let[n,s]of C){let P=!V&&n.isConnected&&e.has(n);if(P&&(b||X||Z))continue;let M=P?2*Math.max(1,R?.scopes.filter(k=>k.element===n).length??0):0,H=Math.max(0,M-s.filter(k=>j.has(k)).length),I=s.filter(k=>j.has(k)||H-- >0?!0:(k.remove(),!1));I.length?C.set(n,I):C.delete(n)}let o=new Set([...Y?.candidates.map(n=>n.scope.element.getRootNode())??[],...b?.scopes.map(n=>n.element.getRootNode())??[],...R?.scopes.map(n=>n.element.getRootNode())??[],...[...j].map(n=>n.getRootNode()),...[...se.values()].flatMap(n=>[...n].map(s=>s.shadowRoot))]);for(let[n,s]of A)n.nodeType===11&&!o.has(n)&&(s.remove(),A.delete(n))},he=new Set,Ie=(e,o,n)=>{let s=()=>{he.delete(s)&&(S({action:e,token:o}).catch(()=>{}),e==="restored"&&le())};he.add(s),n&&!V?p.requestAnimationFrame(()=>p.requestAnimationFrame(s)):s()},de=new Set,xe=()=>{de.forEach(e=>D.delete(e)),de.clear()},He=(e,o=!1)=>{!e||e===R||e===b||(e.images.forEach(n=>{B(n)}),Ie("release",e.data.token,o))},Ee=e=>e.filter(o=>{if(!L(o.scope.element)||![o.element,...o.sources??[]].every(f))return!1;if(o.control.scroll){let n=o.element.getBoundingClientRect(),s=o.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 r.eligible?.(o)??!0}),qe=async()=>{if(ve=0,V||h!=="native"||te||q||b||r.blocked()||!Y||R?.revision===Y.revision&&be===z)return;let{revision:e,candidates:o}=Y,n=ee,s=z,P=W(),M=Ee(o);if(!M.length)return;te=!0;let H,I=!1,k=[];try{let re=!1,ie=S({action:"prepare",revision:r.captureRevision?.()??e,viewportWidth:p.innerWidth,ids:M.map(w=>w.control.id)});ie.then(w=>{re&&w.token&&S({action:"release",token:w.token}).catch(()=>{})}).catch(()=>{});try{H=await pe(ie)}finally{re=!0}if(!H.token||!H.parts?.length)return;let Ce=new Set(M.map(w=>w.control.id));if(H.parts.some(w=>!w.url.startsWith("file:")&&!/^\/__native_ui_engine__\/nativeUI[a-fA-F0-9]+\/[a-fA-F0-9-]+-[0-9]+\.png$/.test(w.url)||!w.ids.length||w.ids.some(G=>!Ce.has(G))||![w.x,w.y,w.width,w.height].every(Number.isFinite)||w.width<=0||w.height<=0)||new Set(H.parts.flatMap(w=>w.ids)).size!==Ce.size||H.parts.some(w=>new Set(w.ids.map(G=>M.find(Me=>Me.control.id===G).scope)).size!==1)||(await pe(Promise.all(H.parts.map(async w=>{let G=M.find(Ye=>w.ids.includes(Ye.control.id)).scope.element,Me=C.get(G);Me||(Me=[],C.set(G,Me));let fe=Me.find(Ye=>!j.has(Ye));return fe||(fe=d.createElement("img"),fe.setAttribute("data-native-ui-projection-node",""),Me.push(fe)),j.add(fe),k.push(fe),fe.src=ot(w.url),await fe.decode(),fe}))),V||h!=="native"||q||b||r.blocked()||ee!==n||W()!==P||Y?.revision!==e||M.some(w=>!L(w.scope.element)||![w.element,...w.sources??[]].every(f))))return;let Re=R,et={data:H,images:k,sources:Array.from(new Set(M.flatMap(w=>[w.element,...w.sources??[]]))),targets:H.parts.map(w=>M.find(G=>w.ids.includes(G.control.id)).element),scopes:H.parts.map(w=>M.find(G=>w.ids.includes(G.control.id)).scope),parents:H.parts.map(w=>M.find(G=>w.ids.includes(G.control.id)).scope.element.parentNode),frames:[],viewport:P,revision:e,layout:O(M)};try{if(!Ue(et))throw new Error("Projection destination is unavailable")}catch(w){Q();try{Ue(),R?.sources.forEach(G=>{D.add(G),de.add(G)})}catch{$()}throw w}R=et,xe(),R.sources.forEach(w=>{D.add(w),de.add(w)}),r.opaqueUnderlay&&S({action:"prepared",token:H.token}).catch(()=>{}),p.dispatchEvent(new Event(l)),be=s,I=!0,He(Re)}catch{}finally{I||k.forEach(re=>{B(re)}),H?.token&&!I&&S({action:"release",token:H.token}).catch(()=>{}),te=!1,Y&&(Y.revision!==e||z!==s)&&ue()}},ue=()=>{p.clearTimeout(ve),!V&&h==="native"&&!b&&!q&&!r.blocked()&&(ve=p.setTimeout(()=>{qe()},v))},Ae,a=(e,o)=>{if(o.some(s=>s.scope.element.ownerDocument!==d||[s.element,...s.sources??[]].some(P=>P.ownerDocument!==d)))throw new TypeError("All projection sources and fallback scopes must share one Document");if(r.blocked())return;!b&&R&&R.layout!==O(Ee(o))&&Le();let n=O(o);Ae!==n&&(Ae=n,z++,ee++),Y?.revision!==e&&ee++,Y={revision:e,candidates:o},le(),(R?.revision!==e||be!==z)&&ue()},u=e=>{!b&&R&&e&&Y?.candidates.some(o=>o.scrollElement===e&&R.sources.includes(o.element))&&Le(),b&&ke(),z++,ee++,ue()},E=await Be(i.listen(({active:e})=>{q=e,ee++,p.clearTimeout(ve),e||ue()})),_=new Set,ce=e=>{se.get(e)?.forEach(o=>o.removeAttribute("data-native-ui-snapshot-content")),_.delete(e)&&e.removeAttribute("data-native-ui-snapshot-prepared"),e.removeAttribute("data-native-ui-snapshot-visible"),e.removeAttribute(y),e.removeAttribute("data-native-ui-snapshot-positioned"),e.removeAttribute("data-native-ui-snapshot-source"),F(e),se.delete(e)},Q=()=>{me++,p.cancelAnimationFrame(J);for(let e of Fe.keys())e.style.setProperty("opacity","0","important");Fe.clear(),J=0,Z=!1,ae=!1,xe(),b?.sources.forEach(e=>{g.delete(e),c.delete(e)}),K.forEach(ce),K.clear(),A.forEach((e,o)=>{(V||o.nodeType===11&&!o.host.isConnected)&&(e.remove(),A.delete(o))})},$=(e=b,o=X)=>{if(b!==e)return;let n=new Set([b,R]);Q(),b=void 0,R=void 0,X=!1,p.clearTimeout(we),n.forEach(s=>He(s,o)),r.wake()},ne=()=>{if(!b)return;if(R!==b){$();return}let e=b;me++,p.cancelAnimationFrame(J),J=0,Z=ae=!1,e.sources.forEach(o=>{g.delete(o),c.delete(o)}),K.forEach(o=>o.removeAttribute("data-native-ui-snapshot-source")),Xe(e,!!r.opaqueUnderlay),b=void 0,X=!1,p.clearTimeout(we),Ie("restored",e.data.token,!0),e.sources.forEach(o=>{D.add(o),de.add(o)}),r.wake()},Pe=()=>{X&&ne(),he.forEach(e=>e())},De=e=>e.scopes.map(o=>L(o.element)?o.element:void 0),K=new Set,Xe=(e,o)=>{for(let n of K)n.toggleAttribute("data-native-ui-snapshot-visible",o),Se(n);e.images.forEach(n=>n.style.setProperty("opacity",o?"1":"0","important"))},Te=new Map,Fe=new Map,ke=()=>{let e=[];for(let[o,n]of Fe){let{target:s,frame:P}=n;if(!s.isConnected){o.remove();continue}let M=s.shadowRoot??s;o.parentNode!==M&&M.insertBefore(o,null);let H=s.getBoundingClientRect(),I=o.getBoundingClientRect(),k=parseFloat(o.style.width)||P.width,re=parseFloat(o.style.height)||P.height,ie=I.width/k||1,Ce=I.height/re||1,Re=n.scale??(n.scale={x:ie,y:Ce});e.push({element:o,left:(parseFloat(o.style.left)||0)+(H.x+P.x*ie/Re.x-I.x)/ie,top:(parseFloat(o.style.top)||0)+(H.y+P.y*Ce/Re.y-I.y)/Ce,width:P.width/Re.x,height:P.height/Re.y})}for(let{element:o,...n}of e)for(let[s,P]of Object.entries(n)){let M=`${P}px`;o.style.getPropertyValue(s)!==M&&o.style.setProperty(s,M,"important")}},Ue=(e=b??R)=>{if(!e||X)return!1;if(!e.sources.every(f)||De(e).some(n=>!n))return Le(),!1;let o=De(e);if(b){if(o.some(s=>!s?.isConnected||!A.has(N(s))))return $(b,!1),!1;let n=new Set;for(let[s,P]of e.targets.entries()){let M=Te.get(P),H=o[s];!M||!H?.isConnected||(H.setAttribute(y,M),H.setAttribute("data-native-ui-snapshot-source",""),n.add(H))}for(let s of K)n.has(s)||ce(s);return K.clear(),n.forEach(s=>K.add(s)),Xe(e,ae),!0}C.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(),K.forEach(ce),K.clear();for(let n of new Set(o)){if(!n)continue;K.add(n),oe(N(n));let s=o.flatMap((I,k)=>I===n?[k]:[]),P=`${T}-${s[0]}`;n.setAttribute(y,P),n!==e.targets[s[0]]&&(n.setAttribute("data-native-ui-snapshot-prepared",""),_.add(n)),n.toggleAttribute("data-native-ui-snapshot-visible",!!r.opaqueUnderlay),Se(n);let M=n.getBoundingClientRect();n.toggleAttribute("data-native-ui-snapshot-positioned",p.getComputedStyle(n).position==="static");let H=n.shadowRoot??n;for(let I of[...s].reverse()){let k=e.images[I],re=e.data.parts[I],ie=e.frames[I]??{x:r.opaqueUnderlay?0:re.x-M.x,y:r.opaqueUnderlay?0:re.y-M.y,width:re.width,height:re.height};e.frames[I]=ie,Te.set(e.targets[I],P),k.inert=!0,k.setAttribute("aria-hidden","true"),k.setAttribute("data-native-ui-projection-image",P),k.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;",k.style.setProperty("width",`${ie.width}px`,"important"),k.style.setProperty("height",`${ie.height}px`,"important"),k.style.setProperty("left","0px","important"),k.style.setProperty("top","0px","important"),k.style.setProperty("opacity",r.opaqueUnderlay?"1":"0","important"),k.parentNode!==H&&H.insertBefore(k,null),Fe.set(k,{target:n,frame:ie})}}return e.parents=e.scopes.map(n=>n.element.parentNode),ke(),!0},Je=e=>e.images.map((o,n)=>{let s=o.getBoundingClientRect();return{...e.data.parts[n],x:s.x,y:s.y,width:s.width,height:s.height}}),Ke=()=>{if(Pe(),V||h==="none"||b)return;let e=R;if(!e||e.viewport!==W()||!e.sources.every(f)||r.current&&!r.current(e.targets)||e.targets.some(s=>!Te.has(s))||De(e).some(s=>!s?.isConnected)||[...K].some(s=>!s.isConnected))return;e.scopes.some((s,P)=>s.element.parentNode!==e.parents[P])&&Ue(),ke();let o=++me,n=()=>me===o;Z=!0,ae=!!r.opaqueUnderlay,b=e,ee++,p.clearTimeout(ve),e.sources.forEach(s=>{g.add(s)}),K.forEach(s=>s.setAttribute("data-native-ui-snapshot-source","")),Xe(e,ae),J=p.requestAnimationFrame(()=>{J=0,n()&&(Z=!1,r.wake())}),pe(S({action:"cover",token:e.data.token,...r.transient?{transient:!0,viewportWidth:p.innerWidth,parts:Je(e)}:{}})).then(s=>{if(n()){if(Z=!1,s?.shown!==!0){$(e,!1);return}X||(ae=!0,e.sources.forEach(P=>c.add(P)),Ue(),ke()),p.cancelAnimationFrame(J),J=p.requestAnimationFrame(()=>{J=0,n()&&S({action:"painted",token:e.data.token}).catch(()=>{n()&&$(e,!1)})}),r.wake()}}).catch(()=>{n()&&$(e,!1)})},Ze=()=>{if(!(!b||V||X)){if(!b.sources.every(f)||De(b).some(e=>!e)||r.current&&!r.current(b.targets)){$(b,!1);return}if(!r.blocked()){if(ke(),r.transient){let e=b;if(De(e).some(s=>!s?.isConnected)){$(e,!1);return}let n=Je(e);r.opaqueUnderlay||n.every((s,P)=>s.width===e.data.parts[P].width&&s.height===e.data.parts[P].height)?e.data={...e.data,parts:n}:R=void 0,S({action:"restore",token:e.data.token,viewportWidth:p.innerWidth,parts:n}).catch(()=>{})}Oe=r.revision?.()??Y?.revision??0,X=!0,b.sources.forEach(e=>g.delete(e)),we=p.setTimeout(()=>{X&&$(b,!1)},250),r.wake()}}},lt=(e,o,n)=>{!X||!b||n===void 0||n<=Oe||!r.transient&&e||b.data.parts.every(s=>s.ids.every(P=>o?.includes(P)))&&(ne(),ue())},Le=(e=!1)=>{he.forEach(n=>n()),ee++,p.clearTimeout(ve);let o=R;if(R=void 0,(e||V)&&(U=void 0),r.retainPreparedUntilRelease&&!b&&!e&&!V){if(o){let n={};U=n,pe(S({action:"release",token:o.data.token})).catch(()=>{}).finally(()=>{if(o.images.forEach(s=>{B(s)}),U===n&&(U=void 0,!(R||b))){for(let s of K)s.getAttribute(y)!==Te.get(s)&&(K.delete(s),_.delete(s));Q(),Te.clear(),p.dispatchEvent(new Event(l))}})}if(U)return}He(o),b?$(b,!1):(Q(),Te.clear(),p.dispatchEvent(new Event(l)))},Qe;try{r.events&&(Qe=await ze(r.events,(e,o)=>{if(!V){if(e&&(h=e),h==="none"){Le();return}e==="web"&&Ke(),e==="native"&&(Ze(),ue()),o&&u()}}))}catch(e){throw V=!0,Le(),await pe(Promise.resolve(E.remove())).catch(()=>{}),e}return{get owners(){return[...g]},get visibleOwners(){return[...c]},get preparedOwners(){return[...D]},consider:a,changed:u,moved:ke,get token(){return X?void 0:b?.data.token},begin:Ke,get restoring(){return X},get handoffPending(){return Z},retireRestoration:Pe,end:Ze,updated:lt,invalidate:Le,async destroy(){V=!0,Le(),C.forEach(e=>e.forEach(o=>o.remove())),C.clear(),await Promise.allSettled([pe(Promise.resolve().then(()=>E?.remove())),pe(Promise.resolve().then(()=>Qe?.remove()))])}}},st=async(t,i,r)=>{let v=await Pt(t,i,r),h=v.consider;return Object.assign(v,{consider:(d,p)=>h(d,p.map(T=>({...T,scope:t})))})};var at=(t,i)=>{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:i})};var ct=async(t,i,r={addListener:async(v,h)=>globalThis.Capacitor.addListener(t.plugin,v,h)})=>{let v="view",h=t.receiveListeners,d=!1,p=!1,T="native",f="native",L=tt(document),C=()=>T==="native"&&m&&L.isCovered(m)?"web":T,j=!1,B=!1,S=!1,y=!1,l,g,c,D=!1,x=()=>{let a=D;D=!0;try{c?.begin()}finally{D=a}},m,O={},A,N=0,oe=()=>{N++,A=void 0;let a=Ne(m);a?.owner===O&&(a.projected=!1,a.owner=void 0)},F={listen:a=>i.listen(u=>{a(u),!u.active&&B&&(B=!1,he()),u.precovered&&Ie(u.precovered)}),send:a=>{if(!t.placementHandoff)return i.send(a);let u=Ne(m);if(a.action==="cover"){let $=A===a.token&&u?.owner===O&&u.projected,ne=++N;return A=a.token,u&&(u.owner=O,u.projected=!!$),i.send(a).then(Pe=>(ne===N&&u===Ne(m)&&u?.owner===O&&(u.projected=Pe?.shown===!0),Pe)).catch(Pe=>{throw ne===N&&u?.owner===O&&(oe(),u.invalidate()),Pe})}let E=a.action==="release"&&a.token===A,_=A&&(a.action==="restore"||E||a.action==="reset"||a.action==="visibility"&&a.visible);_&&N++;let ce=N,Q=()=>{ce!==N||u?.owner!==O||(oe(),u.invalidate())};try{let $=_&&u?.owner===O?{...a,token:"token"in a?a.token:A,placement:u.measure()}:a;return i.send($).then(async ne=>(a.action==="release"&&ne?.requiresPlacement&&(u&&(!u.owner||u.owner===O)?ne=await i.send({...a,placement:u.measure()}):(await i.send({action:"visibility",visible:!1}),ne=await i.send(a))),ce===N&&(a.action==="resume"||E||a.action==="reset"||a.action==="visibility")&&oe(),ne)).catch(ne=>{throw Q(),ne})}catch($){return Q(),Promise.reject($)}}},se=0,Se=0,W=0,Z=!1,ae=!1,J=!1,me=!1,R=document.createElement("style"),U=`data-native-ui-session-${t.id.replace(/[^a-zA-Z0-9-]/g,"")}`;R.textContent=`[${U}="native"], [${U}="native"] *, [${U}="none"], [${U}="none"] * {visibility:hidden!important}`,document.documentElement.append(R);let b=()=>{let a=document.querySelectorAll(t.projectionSelector);return a.length===1&&a[0]instanceof HTMLElement?a[0]:void 0},q=()=>{m&&(f==="web"||f==="native"&&S?m.removeAttribute(U):m.setAttribute(U,f))},X=()=>{if(!m?.isConnected)return[];let a=m.getBoundingClientRect(),u={x:a.x,y:a.y,width:a.width,height:a.height},E=l&&Ge(m,l,()=>t.id);return[{element:m,scrollElement:l,control:{id:v,...u,...E?{scroll:E}:{}}}]},we=async()=>{if(d)return;let a=W,u=t.failedFallback==="native"&&C()==="native"&&!!m?.isConnected;await F.send({action:"visibility",visible:u}).catch(()=>{}),!(d||a!==W)&&(u||f==="none"?q():m?.removeAttribute(U))},Oe=()=>{if(!j||f!=="native"||!m?.isConnected||c?.token||c?.restoring)return;let a=t.failedFallback==="native";F.send({action:"visibility",visible:a}).catch(()=>{}),a?q():m.removeAttribute(U)},ee=()=>{if(d||D)return;if(Oe(),f==="web"&&c&&!c.token&&!c.restoring){F.send({action:"visibility",visible:!1}).catch(()=>{}),m?.removeAttribute(U);return}if(Z||!c?.restoring||f!=="native")return;Z=!0;let a=W,u=c;F.send({action:"resume"}).then(()=>{d||a!==W||u!==c||(S=!1,u.updated(void 0,[v],++se),q(),z())}).catch(()=>{a!==W||d||(u.invalidate(),we())}).finally(()=>{Z=!1,ee()})},ve=async()=>{if(d||ae||j)return;if(c?.restoring){ee();return}let a=b();if(a!==m){if(W++,oe(),m?.removeAttribute(U),await c?.destroy(),c=void 0,d)return;m=a,S=!1,V.disconnect(),m&&V.observe(m)}if(de(),f=C(),!m){await F.send({action:"visibility",visible:!1});return}if(!c){ae=!0;let u=W;try{let E=await st(at(m,t.id),F,{wake:ee,captureDelayMs:t.captureDelayMs,retainPreparedUntilRelease:t.nativeDragHandoff,blocked:()=>f!=="native"||j||S&&!c?.token,revision:()=>se,captureRevision:t.captureMode==="view"?()=>Se:void 0,transient:!0,opaqueUnderlay:t.captureMode==="view"});if(d||u!==W){await E.destroy();return}c=E}finally{ae=!1}}if(!d){if(f==="native"&&S){await F.send({action:"visibility",visible:!1}),q();return}if(f==="native"){let u=W;if(await F.send({action:"visibility",visible:!0}),d||u!==W||f!=="native")return;q(),l=[...We(m)].find(Q=>{let $=getComputedStyle(Q);return/auto|scroll/.test($.overflowX+$.overflowY)&&(Q.scrollHeight>Q.clientHeight||Q.scrollWidth>Q.clientWidth)});let E=l&&Ge(m,l,()=>t.id),_=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,ce=await F.send({action:"track",viewportWidth:innerWidth,...E?{scroll:E}:{},..._?{gesture:_}:{}});if(d||u!==W)return;y=ce?.tracked===!0,c.consider(t.captureMode==="view"?Se:++se,X())}else await F.send({action:"visibility",visible:!1}),q()}},z=()=>{d||(J=!0,!(!p||me)&&(me=!0,Promise.resolve().then(async()=>{try{for(;J&&!d;)J=!1,await ve()}catch{await we()}finally{me=!1,J&&z()}})))},be=()=>{c?.invalidate(),z()},V=new ResizeObserver(be);window.addEventListener("resize",be);let te=new Set,Y=new WeakSet,le=a=>{let u=a.composedPath()[0]??a.target;if(!(d||f!=="native"||!m||Y.has(a)||u!==document&&![...We(m)].includes(u))){if(Y.add(a),y&&u===l){c?.changed(u);return}j?t.captureMode==="view"?c?.moved():c?.changed():((Z||c?.restoring)&&W++,j=!0,x(),S=t.failedFallback!=="native",c?.token?m.removeAttribute(U):Oe()),he()}};function he(){clearTimeout(g),g=setTimeout(()=>{B||(j=!1,!(d||f!=="native")&&(c?.end(),c?.restoring||z()))},100)}function Ie(a){if(d||f!=="native"||!m?.isConnected||!c||(B=!0,c.token))return;(Z||c.restoring)&&W++,A=a;let u=Ne(m);if(u&&(u.owner=O,u.projected=!0),j=!0,x(),!c.token){j=!1,we();return}he()}let de=()=>{let a=new Set(m?We(m):[]),u=a.size!==te.size||[...a].some(E=>!te.has(E));for(let E of te)a.has(E)||(E.removeEventListener("scroll",le),E.removeEventListener("slotchange",xe),te.delete(E));for(let E of a)te.has(E)||(E.addEventListener("scroll",le,{passive:!0}),E.addEventListener("slotchange",xe),te.add(E));u&&(y=!1,l=void 0,c?.invalidate(),z())},xe=()=>{de(),z()};document.addEventListener("scroll",le,!0);let He=new MutationObserver(a=>{de(),b()!==m?z():m&&a.some(u=>u.type==="childList")&&Ee(C())});He.observe(document.documentElement,{childList:!0,attributes:!0,subtree:!0});let Ee=(a,u=!1)=>{if(d||!u&&a===f)return;j=!1,B=!1,clearTimeout(g),f=a,W++;let E=W;f==="none"?F.send({action:"visibility",visible:!1}).then(()=>{f!=="none"||E!==W||d||(c?.invalidate(!0),q())}).catch(()=>{f!=="none"||E!==W||d||(c?.invalidate(!0),q())}):f==="web"?(x(),c?.token||F.send({action:"visibility",visible:!1}).catch(()=>{}),q()):f==="native"&&(c?.end(),c?.restoring||z())},qe=L.subscribe(()=>queueMicrotask(()=>Ee(C()))),ue,Ae=async()=>{if(!d){d=!0,oe(),W++,qe(),He.disconnect(),V.disconnect(),window.removeEventListener("resize",be),document.removeEventListener("scroll",le,!0);for(let a of te)a.removeEventListener("scroll",le),a.removeEventListener("slotchange",xe);te.clear(),clearTimeout(g),m?.removeAttribute(U),R.remove(),await Promise.allSettled([Promise.resolve(ue?.remove()),c?.destroy()])}};try{let a=W;ue=await ze({addListener:(E,_)=>r.addListener(E,_),update:h?.update,projection:h?.projection,accepts:E=>!h?.match||Object.entries(h?.match).every(([_,ce])=>typeof E=="object"&&E!==null&&E[_]===ce)},(E,_)=>{d||(E&&(E==="native"&&(S=!1),T=E,F.send({action:"destination",destination:E}).catch(()=>{}),Ee(C(),!0)),_&&(Se++,c?.changed(),f==="native"&&z()))});let u=await F.send({action:"connect"});return W===a&&["native","web","none"].includes(u?.destination)&&(T=u.destination),f=C(),p=!0,z(),{destroy:Ae,show:()=>{S=!1,T="native",Ee(C(),!0)},hide:()=>{T=f="none",W++,j=!1,B=!1,clearTimeout(g),c?.invalidate(!0),q()}}}catch(a){throw await Ae(),a}};var ye=new Map,ge=new Map,$e=new Map,Tt=Array.from(crypto.getRandomValues(new Uint32Array(4)),t=>t.toString(16)).join("-"),Ve=new Map,Lt=(t,i,r)=>Ve.get(t)?.get(i)?.(r),Mt=0,jt=(t,i)=>new Promise((r,v)=>{let h=`${t}:${Tt}:${++Mt}`,d=setTimeout(()=>{ge.delete(h),v(new Error("Native UI session timed out"))},5e3);ge.set(h,{resolve:r,reject:v,timer:d});let p=JSON.stringify({key:h,request:i}),T=globalThis,f=T.webkit?.messageHandlers?.[t]??T[t]??T.nativeUIEngine;if(!f){clearTimeout(d),ge.delete(h),v(new Error("Native UI session unavailable"));return}try{f.postMessage(p)}catch(L){clearTimeout(d),ge.delete(h),v(L)}}),St=(t,i,r,v)=>{if(i===null){$e.get(t)?.(r);return}let h=ge.get(i);!h||!i.startsWith(`${t}:`)||(ge.delete(i),clearTimeout(h.timer),v?h.reject(new Error(v)):h.resolve(r))},xt=t=>{ye.get(t)?.show()},Ht=t=>(ye.get(t)?.hide(),!0),kt=async t=>{let i=ye.get(t);ye.delete(t),Ve.delete(t),$e.delete(t);for(let[r,v]of ge)r.startsWith(`${t}:`)&&(ge.delete(r),clearTimeout(v.timer),v.reject(new Error("Native UI session closed")));await i?.destroy()},Ct=async t=>{if(ye.has(t.id))return;let i,r=!1,v,h={show:()=>{v="native",i?.show()},hide:()=>{v="none",i?.hide()},destroy:async()=>{r=!0,await i?.destroy()}};ye.set(t.id,h);try{if(document.readyState==="loading"&&await new Promise(p=>document.addEventListener("DOMContentLoaded",()=>p(),{once:!0})),r)return;let d=new Map;t.runtime==="cordova"&&Ve.set(t.id,d),i=await ct(t,{send:p=>jt(t.id,p),listen:async p=>($e.set(t.id,p),{remove:()=>{$e.get(t.id)===p&&$e.delete(t.id)}})},t.runtime==="cordova"?{addListener:async(p,T)=>(d.set(p,T),{remove:()=>{d.delete(p)}})}:void 0),v==="none"?i.hide():v==="native"&&i.show(),r&&await i.destroy()}catch(d){throw ye.get(t.id)===h&&(ye.delete(t.id),Ve.delete(t.id)),d}};return vt(Rt);})();
|
|
@@ -14,6 +14,7 @@ public final class NativeUIScrollBindings {
|
|
|
14
14
|
for (id, group) in Dictionary(grouping: nodes.filter { $0.scroll != nil }, by: { $0.scroll!.id }) {
|
|
15
15
|
if group.contains(where: { $0.scroll?.reuse == true }) {
|
|
16
16
|
if let tracker = previous[id], tracker.replace(group, webView: webView, scale: scale) {
|
|
17
|
+
tracker.render = render
|
|
17
18
|
trackers[id] = tracker
|
|
18
19
|
} else { rejected.append(contentsOf: group.map(\.id)) }
|
|
19
20
|
} else if let tracker = NativeUIScrollTracker(webView: webView, nodes: group, scale: scale, render: render) {
|
|
@@ -34,7 +34,7 @@ public final class NativeUIScrollTracker {
|
|
|
34
34
|
private let contentOrigin: CGPoint
|
|
35
35
|
private let viewportCorrection: CGPoint
|
|
36
36
|
private var frames: [String: CGRect] = [:]
|
|
37
|
-
|
|
37
|
+
var render: (String, CGRect, CGRect) -> Void
|
|
38
38
|
private var observation: NSKeyValueObservation?
|
|
39
39
|
|
|
40
40
|
public init?(webView: WKWebView, nodes: [NativeUIScrollNode], scale: CGFloat,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webview-native-ui/engine",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
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",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"lint": "npm run typecheck && eslint . --max-warnings 0 && npm run format:check",
|
|
34
34
|
"format": "prettier --write \"**/*.{ts,js,mjs,cjs,json,md,yml,yaml,html}\"",
|
|
35
35
|
"prepublishOnly": "npm run build",
|
|
36
|
-
"test:release": "node --test scripts/native-ui-engine-release
|
|
36
|
+
"test:release": "node --test scripts/native-ui-engine-release/*.test.mjs",
|
|
37
37
|
"test:package": "node scripts/verify-package.mjs",
|
|
38
38
|
"release": "np --no-publish --no-tests --branch main",
|
|
39
39
|
"test:cordova": "node scripts/verify-cordova.mjs",
|