@@ -7,45 +7,43 @@ if (elem) {
77
88( ( win , doc ) => {
99 let iframe ;
10- let bodyOverflow ;
10+ let shadowHost ;
11+ let shadowRoot ;
1112
1213 const onMessage = ( event ) => {
14+ if ( ! iframe ) return ;
1315 if ( event . data === 'collapse' ) {
1416 iframe . height = 40 ;
1517 iframe . width = 40 ;
16- doc . body . style . overflow = bodyOverflow ;
1718 return ;
1819 }
1920 if ( event . data === 'toolbar' ) {
2021 iframe . height = 40 ;
2122 iframe . width = '100%' ;
22- doc . body . style . overflow = bodyOverflow ;
2323 return ;
2424 }
2525 if ( event . data === 'expand' ) {
2626 iframe . width = '100%' ;
2727 iframe . height = '100%' ;
28- doc . body . style . overflow = 'hidden' ;
2928 }
3029 if ( event . data === 'error' ) {
3130 iframe . width = '40%' ;
3231 iframe . height = '40%' ;
33- doc . body . style . overflow = bodyOverflow ;
3432 }
3533 } ;
3634
37- let observer ;
38-
3935 function injectDebugKitIframe ( ) {
4036 if ( ! win . debugKitId ) {
4137 return ;
4238 }
43-
44- const { body } = doc ;
45-
46- // Remove the old iframe if it exists (in case of ajax swaps).
47- if ( iframe && iframe . parentNode ) {
48- iframe . parentNode . removeChild ( iframe ) ;
39+ if ( ! shadowHost ) {
40+ shadowHost = doc . getElementById ( 'debugkit-shadow-host' ) ;
41+ if ( ! shadowHost ) {
42+ shadowHost = doc . createElement ( 'div' ) ;
43+ shadowHost . id = 'debugkit-shadow-host' ;
44+ doc . documentElement . appendChild ( shadowHost ) ;
45+ }
46+ shadowRoot = shadowHost . shadowRoot || shadowHost . attachShadow ( { mode : 'open' } ) ;
4947 }
5048
5149 iframe = doc . createElement ( 'iframe' ) ;
@@ -59,33 +57,17 @@ if (elem) {
5957 iframe . height = 40 ;
6058 iframe . width = 40 ;
6159 iframe . src = `${ window . debugKitBaseUrl } debug-kit/toolbar/${ window . debugKitId } ` ;
62-
63- body . appendChild ( iframe ) ;
64- bodyOverflow = body . style . overflow ;
65-
60+ shadowRoot . appendChild ( iframe ) ;
6661 if ( ! win . debugKitMessageListenerApplied ) {
6762 window . addEventListener ( 'message' , onMessage , false ) ;
6863 win . debugKitMessageListenerApplied = true ;
6964 }
7065 }
7166
72- const onReady = ( ) => {
73- injectDebugKitIframe ( ) ;
74- if ( ! observer ) {
75- observer = new MutationObserver ( ( ) => {
76- if ( ! doc . body . querySelector ( 'iframe[src*="debug-kit/toolbar/"]' ) ) {
77- injectDebugKitIframe ( ) ;
78- }
79- } ) ;
80- if ( doc . body ) {
81- observer . observe ( doc . body , { childList : true } ) ;
82- }
83- }
84- } ;
85-
8667 const logAjaxRequest = ( original ) => function ajaxRequest ( ) {
8768 if ( this . readyState === 4 && this . getResponseHeader ( 'X-DEBUGKIT-ID' ) ) {
8869 const newId = this . getResponseHeader ( 'X-DEBUGKIT-ID' ) ;
70+
8971 window . debugKitId = newId ;
9072 const params = {
9173 requestId : newId ,
@@ -98,8 +80,9 @@ if (elem) {
9880
9981 if ( iframe && iframe . contentWindow ) {
10082 iframe . contentWindow . postMessage ( `ajax-completed$$${ JSON . stringify ( params ) } ` , window . location . origin ) ;
101- } else {
102- console . warn ( 'DebugKit: Unable to send ajax completion message - iframe not available' ) ;
83+ }
84+ else {
85+ console . warn ( 'DebugKit iframe not found.' ) ;
10386 }
10487 }
10588 if ( original ) {
@@ -109,51 +92,41 @@ if (elem) {
10992 } ;
11093
11194 const proxyAjaxOpen = ( ) => {
112- if ( window . XMLHttpRequest . prototype . _debugKitOpenProxied ) {
113- return ;
114- }
11595 const proxied = window . XMLHttpRequest . prototype . open ;
11696 window . XMLHttpRequest . prototype . open = function ajaxCall ( ...args ) {
11797 this . _arguments = args ;
11898 return proxied . apply ( this , [ ] . slice . call ( args ) ) ;
11999 } ;
120- window . XMLHttpRequest . prototype . _debugKitOpenProxied = true ;
121100 } ;
122101
123102 const proxyAjaxSend = ( ) => {
124- if ( window . XMLHttpRequest . prototype . _debugKitSendProxied ) {
125- return ;
126- }
127103 const proxied = window . XMLHttpRequest . prototype . send ;
128104 window . XMLHttpRequest . prototype . send = function ajaxCall ( ...args ) {
129105 this . onreadystatechange = logAjaxRequest ( this . onreadystatechange ) ;
130106 return proxied . apply ( this , [ ] . slice . call ( args ) ) ;
131107 } ;
132- window . XMLHttpRequest . prototype . _debugKitSendProxied = true ;
133108 } ;
134109
135- // Bind on ready callbacks to DOMContentLoaded (native js)
136- // Since the body is already loaded (DOMContentLoaded), the event is not triggered.
137- if ( doc . addEventListener ) {
138- // This ensures that all event listeners get applied only once.
139- if ( ! win . debugKitListenersApplied ) {
140- if ( ! win . debugKitAjaxProxied ) {
141- doc . addEventListener ( 'DOMContentLoaded' , proxyAjaxOpen , false ) ;
142- doc . addEventListener ( 'DOMContentLoaded' , proxyAjaxSend , false ) ;
143- if ( doc . readyState === 'interactive' || doc . readyState === 'complete' ) {
144- proxyAjaxOpen ( ) ;
145- proxyAjaxSend ( ) ;
146- }
147- win . debugKitAjaxProxied = true ;
148- }
149- doc . addEventListener ( 'DOMContentLoaded' , onReady , false ) ;
150- if ( doc . readyState === 'interactive' || doc . readyState === 'complete' ) {
151- onReady ( ) ;
152- }
153- win . debugKitListenersApplied = true ;
110+ // Improved: Setup listeners and proxies only once, using closure variables
111+ let listenersSetup = false ;
112+ function setupDebugKitListeners ( ) {
113+ if ( listenersSetup ) return ;
114+ // Set up AJAX proxying
115+ proxyAjaxOpen ( ) ;
116+ proxyAjaxSend ( ) ;
117+ // Set up ready handler
118+ if ( doc . readyState === 'loading' ) {
119+ doc . addEventListener ( 'DOMContentLoaded' , injectDebugKitIframe , false ) ;
120+ } else {
121+ injectDebugKitIframe ( ) ;
154122 }
123+ listenersSetup = true ;
124+ }
125+
126+ if ( doc . addEventListener ) {
127+ setupDebugKitListeners ( ) ;
155128 } else {
156129 throw new Error ( 'Unable to add event listener for DebugKit. Please use a browser'
157- + ' that supports addEventListener().' ) ;
130+ + ' that supports addEventListener().' ) ;
158131 }
159132} ) ( window , document ) ;
0 commit comments