@@ -65,6 +65,14 @@ export function applyCaptchaFrameVisibility(candidates, frameContexts, navigatio
6565 }
6666
6767 const uniqueMatch = ( items ) => items . length === 1 ? items [ 0 ] : null ;
68+ const httpOrigin = ( value ) => {
69+ try {
70+ const parsed = new URL ( String ( value || '' ) ) ;
71+ return / ^ h t t p s ? : $ / . test ( parsed . protocol ) ? parsed . origin : '' ;
72+ } catch ( _ ) {
73+ return '' ;
74+ }
75+ } ;
6876 const findEmbeddingFrame = ( frameId , parentFrameId ) => {
6977 const parentContext = contextsByFrameId . get ( parentFrameId ) ;
7078 if ( ! parentContext ) return null ;
@@ -91,6 +99,13 @@ export function applyCaptchaFrameVisibility(candidates, frameContexts, navigatio
9199 const byName = uniqueMatch ( childFrames . filter ( child => String ( child ?. name || '' ) === frameName ) ) ;
92100 if ( byName ) return byName ;
93101 }
102+ const frameOrigins = new Set ( [ ...frameUrls ] . map ( httpOrigin ) . filter ( Boolean ) ) ;
103+ if ( frameOrigins . size ) {
104+ const byOrigin = uniqueMatch ( childFrames . filter ( child =>
105+ [ child ?. loadedUrl , child ?. url ] . some ( url => frameOrigins . has ( httpOrigin ( url ) ) )
106+ ) ) ;
107+ if ( byOrigin ) return byOrigin ;
108+ }
94109 return childFrames . length === 1 ? childFrames [ 0 ] : null ;
95110 } ;
96111
@@ -112,12 +127,13 @@ export function applyCaptchaFrameVisibility(candidates, frameContexts, navigatio
112127 const parentVisible = frameIsVisible ( parentFrameId , visiting ) ;
113128 visiting . delete ( frameId ) ;
114129 const embeddingFrame = parentVisible ? findEmbeddingFrame ( frameId , parentFrameId ) : null ;
115- // A cross-origin child can redirect while its embedding iframe keeps the
116- // original src. In that case parent code cannot read loadedUrl, so a
117- // missing match means visibility is unknown rather than hidden. Only
118- // demote when a matched embedding frame is conclusively hidden.
130+ // A unique origin match covers common cross-origin redirects whose iframe
131+ // keeps its original src. When multiple embedding elements are still
132+ // indistinguishable, visibility is unknown; fail closed so an internally
133+ // visible widget inside a hidden iframe is not promoted into the paid-task
134+ // ranking tier.
119135 const visible = parentVisible
120- && ( embeddingFrame ? embeddingFrame . visible === true : true ) ;
136+ && embeddingFrame ? .visible === true ;
121137 visibilityByFrameId . set ( frameId , visible ) ;
122138 return visible ;
123139 } ;
0 commit comments