@@ -63,6 +63,7 @@ import { createWorkerFacades } from './runtime/workers/facades.mjs';
6363 const documentCharset = String ( boot . documentCharset || '' ) ;
6464 const dynamicCompileAllowed = boot . dynamicCompileAllowed === true ;
6565 const urlMeta = new WeakMap ( ) ;
66+ const navShareVersions = new WeakMap ( ) ;
6667 const messageListenerWrappers = new WeakMap ( ) ;
6768 const frameWindowOrigins = new WeakMap ( ) ;
6869 const frameSandboxMeta = new WeakMap ( ) ;
@@ -318,6 +319,10 @@ import { createWorkerFacades } from './runtime/workers/facades.mjs';
318319 }
319320 function shareFragmentForKey ( key ) { return ZP . makeShareFragment ( String ( key ) , activeServers ) ; }
320321 function isHTTPURL ( raw ) { try { const u = new URL ( String ( raw ) , baseURL ) ; return u . protocol === 'http:' || u . protocol === 'https:' ; } catch { return false ; } }
322+ function isControlURL ( raw ) {
323+ const value = String ( raw || '' ) . trim ( ) ;
324+ return value . startsWith ( ZP . CONTROL_PREFIX ) || value . startsWith ( proxyOrigin + ZP . CONTROL_PREFIX ) ;
325+ }
321326 function hasExecutableURLScheme ( raw ) { return / ^ (?: j a v a s c r i p t | d a t a | v b s c r i p t ) : / i. test ( String ( raw ) . trim ( ) ) ; }
322327 function hasDangerousURLScheme ( raw ) { return / ^ (?: j a v a s c r i p t | v b s c r i p t ) : / i. test ( String ( raw ) . trim ( ) ) ; }
323328 function shouldBlockURLAttribute ( el , key , raw ) {
@@ -1749,6 +1754,29 @@ import { createWorkerFacades } from './runtime/workers/facades.mjs';
17491754 function visibleNavigationURL ( el , attrName ) {
17501755 return Native . getAttribute . call ( el , 'data-zp-target-url' ) || urlMeta . get ( el ) || Native . getAttribute . call ( el , attrName ) || '' ;
17511756 }
1757+ function isShareNavigationAttribute ( el , attrName ) {
1758+ const tag = el && el . localName ;
1759+ return attrLocalName ( attrName ) === 'href' && ( tag === 'a' || tag === 'area' ) ;
1760+ }
1761+ function bumpNavigationShareVersion ( el ) {
1762+ const version = ( navShareVersions . get ( el ) || 0 ) + 1 ;
1763+ navShareVersions . set ( el , version ) ;
1764+ return version ;
1765+ }
1766+ function scheduleNavigationShareURL ( el , attrName , target ) {
1767+ if ( ! isShareNavigationAttribute ( el , attrName ) ) return ;
1768+ const version = bumpNavigationShareVersion ( el ) ;
1769+ ZP . encryptShareURL ( target ) . then ( share => {
1770+ if ( navShareVersions . get ( el ) !== version ) return ;
1771+ if ( ( Native . getAttribute . call ( el , 'data-zp-target-url' ) || urlMeta . get ( el ) || '' ) !== target ) return ;
1772+ const href = `${ ZP . makeSharePath ( share . encrypted ) } ${ shareFragmentForKey ( share . key ) } ` ;
1773+ if ( Native . getAttribute . call ( el , attrName ) !== href ) Native . setAttribute . call ( el , attrName , href ) ;
1774+ } ) . catch ( ( ) => { } ) ;
1775+ }
1776+ function rememberNavigationTarget ( el , target ) {
1777+ urlMeta . set ( el , target ) ;
1778+ if ( Native . getAttribute . call ( el , 'data-zp-target-url' ) !== target ) Native . setAttribute . call ( el , 'data-zp-target-url' , target ) ;
1779+ }
17521780 function visibleSrcset ( el ) {
17531781 const stored = Native . getAttribute . call ( el , 'data-zp-target-srcset' ) ;
17541782 if ( stored ) return stored ;
@@ -2392,10 +2420,11 @@ import { createWorkerFacades } from './runtime/workers/facades.mjs';
23922420 if ( isResourceURLAttribute ( this , key ) ) return setResourceURLAttribute ( this , k , v ) ;
23932421 if ( isURLBearing ( this , key ) ) {
23942422 if ( shouldBlockURLAttribute ( this , localKey , v ) ) return blockExecutableURL ( this , localKey , v ) ;
2423+ if ( isControlURL ( v ) ) return Native . setAttribute . call ( this , k , v ) ;
23952424 if ( isHTTPURL ( v ) ) {
23962425 const t = targetURL ( v ) ;
2397- urlMeta . set ( this , t ) ;
2398- if ( ! usesRawURLAttribute ( this , key ) ) Native . setAttribute . call ( this , 'data-zp-target-url' , t ) ;
2426+ rememberNavigationTarget ( this , t ) ;
2427+ scheduleNavigationShareURL ( this , k , t ) ;
23992428 if ( ( this . localName === 'iframe' || this . localName === 'frame' ) && localKey === 'src' ) {
24002429 setFrameSourceAttribute ( this , k , t ) ;
24012430 return ;
@@ -2425,10 +2454,11 @@ import { createWorkerFacades } from './runtime/workers/facades.mjs';
24252454 if ( isResourceURLAttribute ( this , key ) ) return setResourceURLAttribute ( this , k , v , ns ) ;
24262455 if ( isURLBearing ( this , key ) ) {
24272456 if ( shouldBlockURLAttribute ( this , localKey , v ) ) return blockExecutableURL ( this , localKey , v ) ;
2457+ if ( isControlURL ( v ) ) return Native . setAttributeNS . call ( this , ns , k , v ) ;
24282458 if ( isHTTPURL ( v ) ) {
24292459 const t = targetURL ( v ) ;
2430- urlMeta . set ( this , t ) ;
2431- if ( ! usesRawURLAttribute ( this , key ) ) Native . setAttribute . call ( this , 'data-zp-target-url' , t ) ;
2460+ rememberNavigationTarget ( this , t ) ;
2461+ scheduleNavigationShareURL ( this , k , t ) ;
24322462 if ( ( this . localName === 'iframe' || this . localName === 'frame' ) && localKey === 'src' ) {
24332463 setFrameSourceAttribute ( this , k , t , ns ) ;
24342464 return ;
@@ -2532,6 +2562,11 @@ import { createWorkerFacades } from './runtime/workers/facades.mjs';
25322562 urlMeta . delete ( this ) ;
25332563 Native . removeAttribute . call ( this , 'data-zp-target-url' ) ;
25342564 }
2565+ if ( isURLBearing ( this , key ) && usesRawURLAttribute ( this , key ) ) {
2566+ bumpNavigationShareVersion ( this ) ;
2567+ urlMeta . delete ( this ) ;
2568+ Native . removeAttribute . call ( this , 'data-zp-target-url' ) ;
2569+ }
25352570 if ( isSrcsetAttribute ( this , key ) ) Native . removeAttribute . call ( this , 'data-zp-target-srcset' ) ;
25362571 return Native . removeAttribute . call ( this , k ) ;
25372572 }
@@ -3081,16 +3116,16 @@ import { createWorkerFacades } from './runtime/workers/facades.mjs';
30813116 if ( ! isURLBearing ( el , key ) ) return ;
30823117 const raw = Native . getAttribute . call ( el , key ) ;
30833118 if ( shouldBlockURLAttribute ( el , localKey , raw ) ) { blockExecutableURL ( el , localKey , raw ) ; return ; }
3084- if ( ! raw || ! isHTTPURL ( raw ) || String ( raw ) . startsWith ( proxyOrigin ) ) return ;
3119+ if ( ! raw || ! isHTTPURL ( raw ) || isControlURL ( raw ) || String ( raw ) . startsWith ( proxyOrigin ) ) return ;
30853120 if ( isResourceURLAttribute ( el , key ) ) {
30863121 if ( ! Native . getAttribute . call ( el , 'data-zp-target-url' ) ) setResourceURLAttribute ( el , key , raw ) ;
30873122 return ;
30883123 }
30893124 let target ;
30903125 try { target = targetURL ( raw ) ; } catch { return ; }
3091- const alreadyMapped = urlMeta . get ( el ) === target && ( ! usesRawURLAttribute ( el , key ) ? Native . getAttribute . call ( el , 'data-zp-target-url' ) === target : true ) ;
3092- urlMeta . set ( el , target ) ;
3093- if ( ! usesRawURLAttribute ( el , key ) ) Native . setAttribute . call ( el , 'data-zp-target-url' , target ) ;
3126+ const alreadyMapped = urlMeta . get ( el ) === target && Native . getAttribute . call ( el , 'data-zp-target-url' ) === target ;
3127+ rememberNavigationTarget ( el , target ) ;
3128+ scheduleNavigationShareURL ( el , key , target ) ;
30943129 if ( ( tag === 'iframe' || tag === 'frame' ) && localKey === 'src' ) {
30953130 sanitizeFrameSandbox ( el ) ;
30963131 setFrameSourceAttribute ( el , key , target ) ;
0 commit comments