@@ -814,85 +814,79 @@ describe('FragmentRefs', () => {
814814 expect ( logs ) . toEqual ( [ ] ) ;
815815 } ) ;
816816
817- // @gate enableFragmentRefs
818- it (
819- 'removes a capture listener registered with boolean when removed with options object' ,
820- async ( ) => {
821- const fragmentRef = React . createRef ( null ) ;
822- function Test ( ) {
823- return (
824- < Fragment ref = { fragmentRef } >
825- < div id = "child-a" />
826- </ Fragment >
827- ) ;
828- }
829- const root = ReactDOMClient . createRoot ( container ) ;
830- await act ( ( ) => {
831- root . render ( < Test /> ) ;
832- } ) ;
817+ // @gate enableFragmentRefs
818+ it ( 'removes a capture listener registered with boolean when removed with options object' , async ( ) => {
819+ const fragmentRef = React . createRef ( null ) ;
820+ function Test ( ) {
821+ return (
822+ < Fragment ref = { fragmentRef } >
823+ < div id = "child-a" />
824+ </ Fragment >
825+ ) ;
826+ }
827+ const root = ReactDOMClient . createRoot ( container ) ;
828+ await act ( ( ) => {
829+ root . render ( < Test /> ) ;
830+ } ) ;
833831
834- const logs = [ ] ;
835- function logCapture ( ) {
836- logs . push ( 'capture' ) ;
837- }
832+ const logs = [ ] ;
833+ function logCapture ( ) {
834+ logs . push ( 'capture' ) ;
835+ }
838836
839- // Register with boolean `true` (capture phase)
840- fragmentRef . current . addEventListener ( 'click' , logCapture , true ) ;
841- document . querySelector ( '#child-a' ) . click ( ) ;
842- expect ( logs ) . toEqual ( [ 'capture' ] ) ;
837+ // Register with boolean `true` (capture phase)
838+ fragmentRef . current . addEventListener ( 'click' , logCapture , true ) ;
839+ document . querySelector ( '#child-a' ) . click ( ) ;
840+ expect ( logs ) . toEqual ( [ 'capture' ] ) ;
843841
844- logs . length = 0 ;
842+ logs . length = 0 ;
845843
846- // Remove with equivalent options object {capture: true}
847- // Per DOM spec, these are identical - the listener MUST be removed
848- fragmentRef . current . removeEventListener ( 'click' , logCapture , {
849- capture : true ,
850- } ) ;
851- document . querySelector ( '#child-a' ) . click ( ) ;
852- // Listener should have been removed - logs must remain empty
853- expect ( logs ) . toEqual ( [ ] ) ;
854- } ,
855- ) ;
844+ // Remove with equivalent options object {capture: true}
845+ // Per DOM spec, these are identical - the listener MUST be removed
846+ fragmentRef . current . removeEventListener ( 'click' , logCapture , {
847+ capture : true ,
848+ } ) ;
849+ document . querySelector ( '#child-a' ) . click ( ) ;
850+ // Listener should have been removed - logs must remain empty
851+ expect ( logs ) . toEqual ( [ ] ) ;
852+ } ) ;
856853
857- // @gate enableFragmentRefs
858- it (
859- 'removes a capture listener registered with options object when removed with boolean' ,
860- async ( ) => {
861- const fragmentRef = React . createRef ( null ) ;
862- function Test ( ) {
863- return (
864- < Fragment ref = { fragmentRef } >
865- < div id = "child-b" />
866- </ Fragment >
867- ) ;
868- }
869- const root = ReactDOMClient . createRoot ( container ) ;
870- await act ( ( ) => {
871- root . render ( < Test /> ) ;
872- } ) ;
854+ // @gate enableFragmentRefs
855+ it ( 'removes a capture listener registered with options object when removed with boolean' , async ( ) => {
856+ const fragmentRef = React . createRef ( null ) ;
857+ function Test ( ) {
858+ return (
859+ < Fragment ref = { fragmentRef } >
860+ < div id = "child-b" />
861+ </ Fragment >
862+ ) ;
863+ }
864+ const root = ReactDOMClient . createRoot ( container ) ;
865+ await act ( ( ) => {
866+ root . render ( < Test /> ) ;
867+ } ) ;
873868
874- const logs = [ ] ;
875- function logCapture ( ) {
876- logs . push ( 'capture' ) ;
877- }
869+ const logs = [ ] ;
870+ function logCapture ( ) {
871+ logs . push ( 'capture' ) ;
872+ }
878873
879- // Register with options object {capture: true}
880- fragmentRef . current . addEventListener ( 'click' , logCapture , {
881- capture : true ,
882- } ) ;
883- document . querySelector ( '#child-b' ) . click ( ) ;
884- expect ( logs ) . toEqual ( [ 'capture' ] ) ;
874+ // Register with options object {capture: true}
875+ fragmentRef . current . addEventListener ( 'click' , logCapture , {
876+ capture : true ,
877+ } ) ;
878+ document . querySelector ( '#child-b' ) . click ( ) ;
879+ expect ( logs ) . toEqual ( [ 'capture' ] ) ;
885880
886- logs . length = 0 ;
881+ logs . length = 0 ;
887882
888- // Remove with boolean `true`
889- // Per DOM spec, these are identical - the listener MUST be removed
890- fragmentRef . current . removeEventListener ( 'click' , logCapture , true ) ;
891- document . querySelector ( '#child-b' ) . click ( ) ;
892- // Listener should have been removed - logs must remain empty
893- expect ( logs ) . toEqual ( [ ] ) ;
894- } ,
895- ) ;
883+ // Remove with boolean `true`
884+ // Per DOM spec, these are identical - the listener MUST be removed
885+ fragmentRef . current . removeEventListener ( 'click' , logCapture , true ) ;
886+ document . querySelector ( '#child-b' ) . click ( ) ;
887+ // Listener should have been removed - logs must remain empty
888+ expect ( logs ) . toEqual ( [ ] ) ;
889+ } ) ;
896890
897891 // @gate enableFragmentRefs
898892 it ( 'applies event listeners to portaled children' , async ( ) => {
@@ -2762,87 +2756,81 @@ describe('FragmentRefs', () => {
27622756 } ) ;
27632757
27642758 // @gate enableFragmentRefs
2765- it (
2766- 'treats passive:true and passive:false as same listener per DOM spec' ,
2767- async ( ) => {
2768- const fragmentRef = React . createRef ( ) ;
2769- const root = ReactDOMClient . createRoot ( container ) ;
2770-
2771- await act ( ( ) => {
2772- root . render (
2773- < Fragment ref = { fragmentRef } >
2774- < div id = "child" />
2775- </ Fragment > ,
2776- ) ;
2777- } ) ;
2778-
2779- const logs = [ ] ;
2780- const handler = ( ) => logs . push ( 'fired' ) ;
2781-
2782- const child = document . querySelector ( '#child' ) ;
2783- const spy = jest . spyOn ( child , 'addEventListener' ) ;
2784- // Per DOM spec, listener identity is (type, callback, capture).
2785- // passive is NOT part of the key, so these are the SAME listener.
2786- fragmentRef . current . addEventListener ( 'click' , handler , { passive : false } ) ;
2787- // Second add is a no-op: same (type, callback, capture) identity.
2788- fragmentRef . current . addEventListener ( 'click' , handler , { passive : true } ) ;
2789- expect ( spy ) . toHaveBeenCalledTimes ( 1 ) ;
2790- expect ( spy ) . toHaveBeenCalledWith ( 'click' , handler , { passive : false } ) ;
2759+ it ( 'treats passive:true and passive:false as same listener per DOM spec' , async ( ) => {
2760+ const fragmentRef = React . createRef ( ) ;
2761+ const root = ReactDOMClient . createRoot ( container ) ;
27912762
2792- document . querySelector ( '#child' ) . click ( ) ;
2793- // First handler fires once (second add was a no-op).
2794- expect ( logs ) . toEqual ( [ 'fired' ] ) ;
2763+ await act ( ( ) => {
2764+ root . render (
2765+ < Fragment ref = { fragmentRef } >
2766+ < div id = "child" />
2767+ </ Fragment > ,
2768+ ) ;
2769+ } ) ;
27952770
2796- // removeEventListener also ignores passive when matching
2797- fragmentRef . current . removeEventListener ( 'click' , handler , {
2798- passive : true ,
2799- } ) ;
2771+ const logs = [ ] ;
2772+ const handler = ( ) => logs . push ( 'fired' ) ;
2773+
2774+ const child = document . querySelector ( '#child' ) ;
2775+ const spy = jest . spyOn ( child , 'addEventListener' ) ;
2776+ // Per DOM spec, listener identity is (type, callback, capture).
2777+ // passive is NOT part of the key, so these are the SAME listener.
2778+ fragmentRef . current . addEventListener ( 'click' , handler , { passive : false } ) ;
2779+ // Second add is a no-op: same (type, callback, capture) identity.
2780+ fragmentRef . current . addEventListener ( 'click' , handler , { passive : true } ) ;
2781+ expect ( spy ) . toHaveBeenCalledTimes ( 1 ) ;
2782+ expect ( spy ) . toHaveBeenCalledWith ( 'click' , handler , { passive : false } ) ;
2783+
2784+ document . querySelector ( '#child' ) . click ( ) ;
2785+ // First handler fires once (second add was a no-op).
2786+ expect ( logs ) . toEqual ( [ 'fired' ] ) ;
2787+
2788+ // removeEventListener also ignores passive when matching
2789+ fragmentRef . current . removeEventListener ( 'click' , handler , {
2790+ passive : true ,
2791+ } ) ;
28002792
2801- logs . length = 0 ;
2802- document . querySelector ( '#child' ) . click ( ) ;
2803- expect ( logs ) . toEqual ( [ ] ) ;
2804- } ,
2805- ) ;
2793+ logs . length = 0 ;
2794+ document . querySelector ( '#child' ) . click ( ) ;
2795+ expect ( logs ) . toEqual ( [ ] ) ;
2796+ } ) ;
28062797 // @gate enableFragmentRefs
2807- it (
2808- 'removes a listener registered with passive:false when removed with passive:true' ,
2809- async ( ) => {
2810- const fragmentRef = React . createRef ( null ) ;
2811- function Test ( ) {
2812- return (
2813- < >
2814- < div id = "child-x" />
2815- </ >
2816- ) ;
2817- }
2818- const root = ReactDOMClient . createRoot ( container ) ;
2819- await act ( ( ) => {
2820- root . render (
2821- < Fragment ref = { fragmentRef } >
2822- < Test />
2823- </ Fragment > ,
2824- ) ;
2825- } ) ;
2826- const logs = [ ] ;
2827- function handler ( ) {
2828- logs . push ( 'fired' ) ;
2829- }
2830- // Register with passive: false
2831- fragmentRef . current . addEventListener ( 'click' , handler , {
2832- passive : false ,
2833- } ) ;
2834- document . querySelector ( '#child-x' ) . click ( ) ;
2835- expect ( logs ) . toEqual ( [ 'fired' ] ) ;
2836- logs . length = 0 ;
2837- // Remove with passive: true - per DOM spec, passive is NOT part of identity
2838- // so this MUST remove the listener regardless of passive mismatch.
2839- fragmentRef . current . removeEventListener ( 'click' , handler , {
2840- passive : true ,
2841- } ) ;
2842- document . querySelector ( '#child-x' ) . click ( ) ;
2843- // Listener removed - no more invocations
2844- expect ( logs ) . toEqual ( [ ] ) ;
2845- } ,
2846- ) ;
2798+ it ( 'removes a listener registered with passive:false when removed with passive:true' , async ( ) => {
2799+ const fragmentRef = React . createRef ( null ) ;
2800+ function Test ( ) {
2801+ return (
2802+ < >
2803+ < div id = "child-x" />
2804+ </ >
2805+ ) ;
2806+ }
2807+ const root = ReactDOMClient . createRoot ( container ) ;
2808+ await act ( ( ) => {
2809+ root . render (
2810+ < Fragment ref = { fragmentRef } >
2811+ < Test />
2812+ </ Fragment > ,
2813+ ) ;
2814+ } ) ;
2815+ const logs = [ ] ;
2816+ function handler ( ) {
2817+ logs . push ( 'fired' ) ;
2818+ }
2819+ // Register with passive: false
2820+ fragmentRef . current . addEventListener ( 'click' , handler , {
2821+ passive : false ,
2822+ } ) ;
2823+ document . querySelector ( '#child-x' ) . click ( ) ;
2824+ expect ( logs ) . toEqual ( [ 'fired' ] ) ;
2825+ logs . length = 0 ;
2826+ // Remove with passive: true - per DOM spec, passive is NOT part of identity
2827+ // so this MUST remove the listener regardless of passive mismatch.
2828+ fragmentRef . current . removeEventListener ( 'click' , handler , {
2829+ passive : true ,
2830+ } ) ;
2831+ document . querySelector ( '#child-x' ) . click ( ) ;
2832+ // Listener removed - no more invocations
2833+ expect ( logs ) . toEqual ( [ ] ) ;
2834+ } ) ;
28472835 } ) ;
28482836} ) ;
0 commit comments