@@ -2603,4 +2603,61 @@ describe('ReactDOMComponent', () => {
26032603 expect ( node . getAttribute ( 'onx' ) ) . toBe ( 'bar' ) ;
26042604 } ) ;
26052605 } ) ;
2606+
2607+ it ( 'receives events in specific order' , ( ) => {
2608+ let eventOrder = [ ] ;
2609+ let track = tag => ( ) => eventOrder . push ( tag ) ;
2610+ let outerRef = React . createRef ( ) ;
2611+ let innerRef = React . createRef ( ) ;
2612+
2613+ function OuterReactApp ( ) {
2614+ return (
2615+ < div
2616+ ref = { outerRef }
2617+ onClick = { track ( 'outer bubble' ) }
2618+ onClickCapture = { track ( 'outer capture' ) }
2619+ />
2620+ ) ;
2621+ }
2622+
2623+ function InnerReactApp ( ) {
2624+ return (
2625+ < div
2626+ ref = { innerRef }
2627+ onClick = { track ( 'inner bubble' ) }
2628+ onClickCapture = { track ( 'inner capture' ) }
2629+ />
2630+ ) ;
2631+ }
2632+
2633+ const container = document . createElement ( 'div' ) ;
2634+ document . body . appendChild ( container ) ;
2635+
2636+ try {
2637+
2638+ ReactDOM . render ( < OuterReactApp /> , container ) ;
2639+ ReactDOM . render ( < InnerReactApp /> , outerRef . current ) ;
2640+
2641+ document . addEventListener ( 'click' , track ( 'document bubble' ) ) ;
2642+ document . addEventListener ( 'click' , track ( 'document capture' ) , true ) ;
2643+
2644+ innerRef . current . click ( ) ;
2645+
2646+ // The order we receive here is not ideal since it is expected that the
2647+ // capture listener fire before all bubble listeners. Other React apps
2648+ // might depend on this.
2649+ //
2650+ // @see https://github.com/facebook/react/pull/12919#issuecomment-395224674
2651+ expect ( eventOrder ) . toEqual ( [
2652+ 'document capture' ,
2653+ 'inner capture' ,
2654+ 'inner bubble' ,
2655+ 'outer capture' ,
2656+ 'outer bubble' ,
2657+ 'document bubble' ,
2658+ ] ) ;
2659+ } finally {
2660+ document . body . removeChild ( container ) ;
2661+ }
2662+ } ) ;
26062663} ) ;
0 commit comments