@@ -792,8 +792,22 @@ function handleHtmlResponse(response, frontendTarget, frontendSwap, trigger) {
792792 }
793793 // Priority 1: Server target (by index)
794794 let explicitTarget = serverTarget ;
795- // Priority 2: Frontend target as fallback (only if no server target and not excluded)
796- if ( ! explicitTarget && frontendTarget && ! excluded . has ( frontendTarget ) ) {
795+ let autoTargetSelector = null ;
796+ if ( ! explicitTarget ) {
797+ // Priority 2: auto-detect by beam-id / beam-item-id on root element
798+ const temp = document . createElement ( 'div' ) ;
799+ temp . innerHTML = htmlItem . trim ( ) ;
800+ const rootEl = temp . firstElementChild ;
801+ const beamId = rootEl ?. getAttribute ( 'beam-id' ) ;
802+ const beamItemId = rootEl ?. getAttribute ( 'beam-item-id' ) ;
803+ autoTargetSelector = beamId
804+ ? `[beam-id="${ escapeCss ( beamId ) } "]`
805+ : beamItemId
806+ ? `[beam-item-id="${ escapeCss ( beamItemId ) } "]`
807+ : null ;
808+ }
809+ // Priority 3: Frontend target as fallback (only if no server or auto target was found and not excluded)
810+ if ( ! explicitTarget && ! autoTargetSelector && frontendTarget && ! excluded . has ( frontendTarget ) ) {
797811 explicitTarget = frontendTarget ;
798812 }
799813 if ( explicitTarget ) {
@@ -806,33 +820,27 @@ function handleHtmlResponse(response, frontendTarget, frontendSwap, trigger) {
806820 console . warn ( `[beam] Target "${ explicitTarget } " not found on page, skipping` ) ;
807821 }
808822 }
823+ else if ( autoTargetSelector && ! excluded . has ( autoTargetSelector ) ) {
824+ const target = $ ( autoTargetSelector ) ;
825+ if ( target ) {
826+ applyHtml ( target , htmlItem . trim ( ) , { style : 'outerHTML' } ) ;
827+ }
828+ else {
829+ console . warn ( `[beam] Target "${ autoTargetSelector } " (from HTML) not found on page, skipping` ) ;
830+ }
831+ }
809832 else {
810- // Priority 3: auto-detect by id / beam-id / beam-item-id on root element
811- // Each identifier works on its own. If multiple are present, we use a deterministic
812- // priority order so only *one* target is selected.
813- const temp = document . createElement ( 'div' ) ;
814- temp . innerHTML = htmlItem . trim ( ) ;
815- const rootEl = temp . firstElementChild ;
816- const id = rootEl instanceof HTMLElement ? rootEl . id : '' ;
817- const beamId = rootEl ?. getAttribute ( 'beam-id' ) ;
818- const beamItemId = rootEl ?. getAttribute ( 'beam-item-id' ) ;
819- const selector = id
820- ? `#${ escapeCss ( id ) } `
821- : beamId
822- ? `[beam-id="${ escapeCss ( beamId ) } "]`
823- : beamItemId
824- ? `[beam-item-id="${ escapeCss ( beamItemId ) } "]`
825- : null ;
826- if ( selector && ! excluded . has ( selector ) ) {
827- const target = $ ( selector ) ;
833+ // If no beam-id/beam-item-id target is found, allow the triggering element's frontend target as the last fallback.
834+ if ( frontendTarget && ! excluded . has ( frontendTarget ) ) {
835+ const target = $ ( frontendTarget ) ;
828836 if ( target ) {
829- applyHtml ( target , htmlItem . trim ( ) , { style : 'outerHTML' } ) ;
837+ swap ( target , htmlItem , swapMode , trigger ) ;
830838 }
831839 else {
832- console . warn ( `[beam] Target "${ selector } " (from HTML) not found on page, skipping` ) ;
840+ console . warn ( `[beam] Target "${ frontendTarget } " not found on page, skipping` ) ;
833841 }
834842 }
835- // If no id/beam-id/beam-item-id found or excluded, skip silently
843+ // If no target found or all candidates are excluded, skip silently.
836844 }
837845 } ) ;
838846}
@@ -2160,38 +2168,19 @@ function setupInputWatcher(el) {
21602168 htmlEl . setAttribute ( 'beam-touched' , '' ) ;
21612169 try {
21622170 const stream = await api . call ( action , params ) ;
2163- const reader = stream . getReader ( ) ;
2164- try {
2165- while ( true ) {
2166- const { done, value } = await reader . read ( ) ;
2167- if ( done )
2168- break ;
2169- if ( value . html && targetSelector ) {
2170- const targets = $$ ( targetSelector ) ;
2171- const htmlArray = Array . isArray ( value . html ) ? value . html : [ value . html ] ;
2172- targets . forEach ( ( target , i ) => {
2173- const html = htmlArray [ i ] || htmlArray [ 0 ] ;
2174- if ( html )
2175- swap ( target , html , swapMode ) ;
2176- } ) ;
2177- }
2178- if ( value . html ) {
2179- const htmlStr = Array . isArray ( value . html ) ? value . html . join ( '' ) : value . html ;
2180- const { oob } = parseOobSwaps ( htmlStr ) ;
2181- for ( const { selector, content, swapMode : oobSwapMode } of oob ) {
2182- const oobTarget = $ ( selector ) ;
2183- if ( oobTarget )
2184- swap ( oobTarget , content , oobSwapMode || 'replace' ) ;
2185- }
2186- }
2187- if ( value . script )
2188- executeScript ( value . script ) ;
2189- }
2190- }
2191- finally {
2192- reader . releaseLock ( ) ;
2171+ const reader = stream . getReader ( ) ;
2172+ try {
2173+ while ( true ) {
2174+ const { done, value } = await reader . read ( ) ;
2175+ if ( done )
2176+ break ;
2177+ applyResponse ( value , targetSelector , swapMode , htmlEl ) ;
21932178 }
21942179 }
2180+ finally {
2181+ reader . releaseLock ( ) ;
2182+ }
2183+ }
21952184 catch ( err ) {
21962185 console . error ( 'Input watcher error:' , err ) ;
21972186 }
0 commit comments