@@ -3281,3 +3281,220 @@ Deno.test({
32813281 } ) ;
32823282 } ,
32833283} ) ;
3284+
3285+ Deno . test ( {
3286+ name : "partials - submit form indicator on button" ,
3287+ fn : async ( ) => {
3288+ const app = testApp ( )
3289+ . get ( "/partial" , ( ctx ) => {
3290+ return ctx . render (
3291+ < Doc >
3292+ < Partial name = "foo" >
3293+ < p class = "done" > done</ p >
3294+ </ Partial >
3295+ </ Doc > ,
3296+ ) ;
3297+ } )
3298+ . get ( "/" , ( ctx ) => {
3299+ return ctx . render (
3300+ < Doc >
3301+ < div f-client-nav >
3302+ < form action = "/partial" >
3303+ < Partial name = "foo" >
3304+ < p class = "init" > init</ p >
3305+ </ Partial >
3306+ < button type = "submit" class = "update" >
3307+ update
3308+ </ button >
3309+ </ form >
3310+ </ div >
3311+ </ Doc > ,
3312+ ) ;
3313+ } ) ;
3314+
3315+ await withBrowserApp ( app , async ( page , address ) => {
3316+ await page . goto ( address , { waitUntil : "load" } ) ;
3317+ await page . locator ( ".init" ) . wait ( ) ;
3318+
3319+ // Attach a tracking indicator to the submit button
3320+ await page . evaluate ( ( ) => {
3321+ const btn = document . querySelector ( ".update" ) ! ;
3322+ const indicator = { _wasTrue : false , _value : false } ;
3323+ Object . defineProperty ( indicator , "value" , {
3324+ get ( ) {
3325+ return this . _value ;
3326+ } ,
3327+ set ( v : boolean ) {
3328+ this . _value = v ;
3329+ if ( v ) this . _wasTrue = true ;
3330+ } ,
3331+ } ) ;
3332+ // deno-lint-ignore no-explicit-any
3333+ ( btn as any ) . _freshIndicator = indicator ;
3334+ // deno-lint-ignore no-explicit-any
3335+ ( window as any ) . __indicator = indicator ;
3336+ } ) ;
3337+
3338+ await page . locator ( ".update" ) . click ( ) ;
3339+ await page . locator ( ".done" ) . wait ( ) ;
3340+
3341+ const result = await page . evaluate ( ( ) => {
3342+ // deno-lint-ignore no-explicit-any
3343+ const ind = ( window as any ) . __indicator ;
3344+ return { wasTrue : ind . _wasTrue , currentValue : ind . value } ;
3345+ } ) ;
3346+ expect ( result . wasTrue ) . toBe ( true ) ;
3347+ expect ( result . currentValue ) . toBe ( false ) ;
3348+ } ) ;
3349+ } ,
3350+ } ) ;
3351+
3352+ Deno . test ( {
3353+ name : "partials - submit form indicator on form element" ,
3354+ fn : async ( ) => {
3355+ const app = testApp ( )
3356+ . get ( "/partial" , ( ctx ) => {
3357+ return ctx . render (
3358+ < Doc >
3359+ < Partial name = "foo" >
3360+ < p class = "done" > done</ p >
3361+ </ Partial >
3362+ </ Doc > ,
3363+ ) ;
3364+ } )
3365+ . get ( "/" , ( ctx ) => {
3366+ return ctx . render (
3367+ < Doc >
3368+ < div f-client-nav >
3369+ < form action = "/partial" class = "myform" >
3370+ < Partial name = "foo" >
3371+ < p class = "init" > init</ p >
3372+ </ Partial >
3373+ < button type = "submit" class = "update" >
3374+ update
3375+ </ button >
3376+ </ form >
3377+ </ div >
3378+ </ Doc > ,
3379+ ) ;
3380+ } ) ;
3381+
3382+ await withBrowserApp ( app , async ( page , address ) => {
3383+ await page . goto ( address , { waitUntil : "load" } ) ;
3384+ await page . locator ( ".init" ) . wait ( ) ;
3385+
3386+ // Attach indicator to the form element (not the button)
3387+ await page . evaluate ( ( ) => {
3388+ const form = document . querySelector ( ".myform" ) ! ;
3389+ const indicator = { _wasTrue : false , _value : false } ;
3390+ Object . defineProperty ( indicator , "value" , {
3391+ get ( ) {
3392+ return this . _value ;
3393+ } ,
3394+ set ( v : boolean ) {
3395+ this . _value = v ;
3396+ if ( v ) this . _wasTrue = true ;
3397+ } ,
3398+ } ) ;
3399+ // deno-lint-ignore no-explicit-any
3400+ ( form as any ) . _freshIndicator = indicator ;
3401+ // deno-lint-ignore no-explicit-any
3402+ ( window as any ) . __indicator = indicator ;
3403+ } ) ;
3404+
3405+ await page . locator ( ".update" ) . click ( ) ;
3406+ await page . locator ( ".done" ) . wait ( ) ;
3407+
3408+ const result = await page . evaluate ( ( ) => {
3409+ // deno-lint-ignore no-explicit-any
3410+ const ind = ( window as any ) . __indicator ;
3411+ return { wasTrue : ind . _wasTrue , currentValue : ind . value } ;
3412+ } ) ;
3413+ expect ( result . wasTrue ) . toBe ( true ) ;
3414+ expect ( result . currentValue ) . toBe ( false ) ;
3415+ } ) ;
3416+ } ,
3417+ } ) ;
3418+
3419+ Deno . test ( {
3420+ name : "partials - submit form indicator prefers submitter over form" ,
3421+ fn : async ( ) => {
3422+ const app = testApp ( )
3423+ . get ( "/partial" , ( ctx ) => {
3424+ return ctx . render (
3425+ < Doc >
3426+ < Partial name = "foo" >
3427+ < p class = "done" > done</ p >
3428+ </ Partial >
3429+ </ Doc > ,
3430+ ) ;
3431+ } )
3432+ . get ( "/" , ( ctx ) => {
3433+ return ctx . render (
3434+ < Doc >
3435+ < div f-client-nav >
3436+ < form action = "/partial" class = "myform" >
3437+ < Partial name = "foo" >
3438+ < p class = "init" > init</ p >
3439+ </ Partial >
3440+ < button type = "submit" class = "update" >
3441+ update
3442+ </ button >
3443+ </ form >
3444+ </ div >
3445+ </ Doc > ,
3446+ ) ;
3447+ } ) ;
3448+
3449+ await withBrowserApp ( app , async ( page , address ) => {
3450+ await page . goto ( address , { waitUntil : "load" } ) ;
3451+ await page . locator ( ".init" ) . wait ( ) ;
3452+
3453+ // Attach indicators to both form and button
3454+ await page . evaluate ( ( ) => {
3455+ function makeIndicator ( name : string ) {
3456+ const indicator = { _wasTrue : false , _value : false } ;
3457+ Object . defineProperty ( indicator , "value" , {
3458+ get ( ) {
3459+ return this . _value ;
3460+ } ,
3461+ set ( v : boolean ) {
3462+ this . _value = v ;
3463+ if ( v ) this . _wasTrue = true ;
3464+ } ,
3465+ } ) ;
3466+ // deno-lint-ignore no-explicit-any
3467+ ( window as any ) [ name ] = indicator ;
3468+ return indicator ;
3469+ }
3470+
3471+ const btn = document . querySelector ( ".update" ) ! ;
3472+ const form = document . querySelector ( ".myform" ) ! ;
3473+ // deno-lint-ignore no-explicit-any
3474+ ( btn as any ) . _freshIndicator = makeIndicator ( "__btnIndicator" ) ;
3475+ // deno-lint-ignore no-explicit-any
3476+ ( form as any ) . _freshIndicator = makeIndicator ( "__formIndicator" ) ;
3477+ } ) ;
3478+
3479+ await page . locator ( ".update" ) . click ( ) ;
3480+ await page . locator ( ".done" ) . wait ( ) ;
3481+
3482+ const result = await page . evaluate ( ( ) => {
3483+ // deno-lint-ignore no-explicit-any
3484+ const w = window as any ;
3485+ return {
3486+ btnWasTrue : w . __btnIndicator . _wasTrue ,
3487+ btnCurrent : w . __btnIndicator . value ,
3488+ formWasTrue : w . __formIndicator . _wasTrue ,
3489+ formCurrent : w . __formIndicator . value ,
3490+ } ;
3491+ } ) ;
3492+ // Submitter indicator should have been toggled
3493+ expect ( result . btnWasTrue ) . toBe ( true ) ;
3494+ expect ( result . btnCurrent ) . toBe ( false ) ;
3495+ // Form indicator should NOT have been used
3496+ expect ( result . formWasTrue ) . toBe ( false ) ;
3497+ expect ( result . formCurrent ) . toBe ( false ) ;
3498+ } ) ;
3499+ } ,
3500+ } ) ;
0 commit comments