1
+ /* global chrome */
2
+
1
3
// This script runs in the context of the web page
2
4
// console.log( 'Three.js DevTools: Content script loaded at document_readyState:', document.readyState ); // Comment out
3
5
4
- // Function to inject the bridge script
6
+ // Inject the bridge script into the main document or a target (e.g., iframe)
5
7
function injectBridge ( target = document ) {
6
8
7
9
const script = document . createElement ( 'script' ) ;
@@ -13,27 +15,20 @@ function injectBridge( target = document ) {
13
15
} ;
14
16
15
17
( target . head || target . documentElement ) . appendChild ( script ) ;
16
-
17
18
return script ;
18
19
19
20
}
20
21
21
- // Also inject into any existing iframes
22
+ // Inject bridge into all existing iframes
22
23
function injectIntoIframes ( ) {
23
24
24
- const iframes = document . querySelectorAll ( 'iframe' ) ;
25
- iframes . forEach ( iframe => {
25
+ document . querySelectorAll ( 'iframe' ) . forEach ( iframe => {
26
26
27
27
try {
28
28
29
- injectBridge ( iframe . contentDocument ) ;
30
-
31
- } catch ( e ) {
29
+ if ( iframe . contentDocument ) injectBridge ( iframe . contentDocument ) ;
32
30
33
- // Ignore cross-origin iframe errors
34
- // console.log( 'DevTools: Could not inject into iframe:', e ); // Comment out
35
-
36
- }
31
+ } catch ( e ) { /* Ignore cross-origin errors */ }
37
32
38
33
} ) ;
39
34
@@ -44,27 +39,21 @@ injectBridge();
44
39
injectIntoIframes ( ) ;
45
40
46
41
// Watch for new iframes being added
47
- const observer = new MutationObserver ( mutations => {
42
+ new MutationObserver ( mutations => {
48
43
49
44
mutations . forEach ( mutation => {
50
45
51
46
mutation . addedNodes . forEach ( node => {
52
47
53
48
if ( node . tagName === 'IFRAME' ) {
54
49
55
- // Wait for iframe to load
56
50
node . addEventListener ( 'load' , ( ) => {
57
51
58
52
try {
59
53
60
- injectBridge ( node . contentDocument ) ;
61
-
62
- } catch ( e ) {
63
-
64
- // Ignore cross-origin iframe errors
65
- // console.log( 'DevTools: Could not inject into iframe:', e ); // Comment out
54
+ if ( node . contentDocument ) injectBridge ( node . contentDocument ) ;
66
55
67
- }
56
+ } catch ( e ) { /* Ignore cross-origin errors */ }
68
57
69
58
} ) ;
70
59
@@ -74,19 +63,13 @@ const observer = new MutationObserver( mutations => {
74
63
75
64
} ) ;
76
65
77
- } ) ;
66
+ } ) . observe ( document . documentElement , { childList : true , subtree : true } ) ;
78
67
79
- observer . observe ( document . documentElement , {
80
- childList : true ,
81
- subtree : true
82
- } ) ;
83
-
84
- // Helper function to check if extension context is valid
68
+ // Helper to check if extension context is valid
85
69
function isExtensionContextValid ( ) {
86
70
87
71
try {
88
72
89
- // This will throw if context is invalidated
90
73
chrome . runtime . getURL ( '' ) ;
91
74
return true ;
92
75
@@ -98,120 +81,47 @@ function isExtensionContextValid() {
98
81
99
82
}
100
83
101
- // Handle messages from the main window
102
- function handleMainWindowMessage ( event ) {
103
-
104
- // Only accept messages from the same frame
105
- if ( event . source !== window ) {
106
-
107
- return ;
108
-
109
- }
110
-
111
- const message = event . data ;
112
- if ( ! message || message . id !== 'three-devtools' ) {
113
-
114
- return ;
115
-
116
- }
117
-
118
- // Check extension context before sending message
119
- if ( ! isExtensionContextValid ( ) ) {
120
-
121
- console . warn ( 'Extension context invalidated, cannot send message' ) ;
122
- return ;
123
-
124
- }
125
-
126
- // Add source information
127
- const messageWithSource = {
128
- ...event . data ,
129
- source : event . source === window ? 'main' : 'iframe'
130
- } ;
131
-
132
- // Forward to background page
133
- chrome . runtime . sendMessage ( messageWithSource ) ;
134
-
135
- }
136
-
137
- // Handle messages from iframes
138
- function handleIframeMessage ( event ) {
139
-
140
- // Skip messages from main window
141
- if ( event . source === window ) {
142
-
143
- return ;
144
-
145
- }
84
+ // Unified message handler for window messages
85
+ function handleWindowMessage ( event ) {
146
86
147
- const message = event . data ;
148
- if ( ! message || message . id !== 'three-devtools' ) {
87
+ // Only accept messages with the correct id
88
+ if ( ! event . data || event . data . id !== 'three-devtools' ) return ;
149
89
150
- return ;
151
-
152
- }
90
+ // Determine source: 'main' for window, 'iframe' otherwise
91
+ const source = event . source === window ? 'main' : 'iframe' ;
153
92
154
- // Check extension context before sending message
155
93
if ( ! isExtensionContextValid ( ) ) {
156
94
157
95
console . warn ( 'Extension context invalidated, cannot send message' ) ;
158
96
return ;
159
97
160
98
}
161
99
162
- // Add source information
163
- const messageWithSource = {
164
- ...event . data ,
165
- source : 'iframe'
166
- } ;
167
-
168
- // Forward to background page
100
+ const messageWithSource = { ...event . data , source } ;
169
101
chrome . runtime . sendMessage ( messageWithSource ) ;
170
102
171
103
}
172
104
173
- // Listener for messages forwarded from the background script (originating from panel)
174
- function handleBackgroundMessage ( message , sender , sendResponse ) {
105
+ // Listener for messages from the background script (originating from panel)
106
+ function handleBackgroundMessage ( message ) {
175
107
176
- // Check if the message is one we need to forward to the bridge
177
- // Only forward request-state now
178
108
if ( message . name === 'request-state' ) {
179
109
180
- // console.log( 'Content script: Forwarding message to bridge:', message.name );
181
- // Ensure the message has the correct ID before forwarding to the page
182
110
message . id = 'three-devtools' ;
183
- window . postMessage ( message , '*' ) ; // Forward the modified message to the page
184
-
185
- // Optional: Forward to iframes too, if needed (might cause duplicates if bridge is in iframe)
186
- /*
187
- const iframes = document.querySelectorAll('iframe');
188
- iframes.forEach(iframe => {
189
- try {
190
- iframe.contentWindow.postMessage(message, '*');
191
- } catch (e) {}
192
- });
193
- */
111
+ window . postMessage ( message , '*' ) ;
194
112
195
113
}
196
- // Keep channel open? No, this listener is synchronous for now.
197
- // return true;
198
114
199
115
}
200
116
201
117
// Add event listeners
202
- window . addEventListener ( 'message' , handleMainWindowMessage , false ) ;
203
- window . addEventListener ( 'message' , handleIframeMessage , false ) ;
204
- // chrome.runtime.onMessage.addListener( handleDevtoolsMessage ); // This seems redundant/incorrectly placed in original code
205
-
206
- // Use a single listener for messages from the background script
118
+ window . addEventListener ( 'message' , handleWindowMessage , false ) ;
207
119
chrome . runtime . onMessage . addListener ( handleBackgroundMessage ) ;
208
120
209
121
// Icon color scheme
210
122
const isLightTheme = window . matchMedia ( '(prefers-color-scheme: light)' ) . matches ;
211
-
212
123
chrome . runtime . sendMessage ( { scheme : isLightTheme ? 'light' : 'dark' } ) ;
213
-
214
- window . matchMedia ( '(prefers-color-scheme: light)' ) . onchange = ( event ) => {
124
+ window . matchMedia ( '(prefers-color-scheme: light)' ) . onchange = event => {
215
125
216
126
chrome . runtime . sendMessage ( { scheme : event . matches ? 'light' : 'dark' } ) ;
217
127
0 commit comments