main
js 171 lines 4.49 KB
Raw
1 /* global chrome */
2
3 import {__DEBUG__} from 'react-devtools-shared/src/constants';
4 import setExtensionIconAndPopup from './setExtensionIconAndPopup';
5 import {executeScriptInMainWorld} from './executeScript';
6
7 import {EXTENSION_CONTAINED_VERSIONS} from '../utils';
8
9 export function handleReactDevToolsHookMessage(message, sender) {
10 const {payload} = message;
11
12 switch (payload?.type) {
13 case 'react-renderer-attached': {
14 setExtensionIconAndPopup(payload.reactBuildType, sender.tab.id);
15
16 break;
17 }
18 }
19 }
20
21 export function handleBackendManagerMessage(message, sender) {
22 const {payload} = message;
23
24 switch (payload?.type) {
25 case 'require-backends': {
26 payload.versions.forEach(version => {
27 if (EXTENSION_CONTAINED_VERSIONS.includes(version)) {
28 executeScriptInMainWorld({
29 injectImmediately: true,
30 target: {tabId: sender.tab.id},
31 files: [`/build/react_devtools_backend_${version}.js`],
32 });
33 }
34 });
35
36 break;
37 }
38 }
39 }
40
41 export function handleDevToolsPageMessage(message) {
42 const {payload} = message;
43
44 switch (payload?.type) {
45 // Proxy this message from DevTools page to content script via chrome.tabs.sendMessage
46 case 'fetch-file-with-cache': {
47 const {
48 payload: {tabId, url},
49 } = message;
50
51 if (!tabId || !url) {
52 // Send a response straight away to get the Promise fulfilled.
53 chrome.runtime.sendMessage({
54 source: 'react-devtools-background',
55 payload: {
56 type: 'fetch-file-with-cache-error',
57 url,
58 value: null,
59 },
60 });
61 } else {
62 chrome.tabs.sendMessage(tabId, {
63 source: 'devtools-page',
64 payload: {
65 type: 'fetch-file-with-cache',
66 url,
67 },
68 });
69 }
70
71 break;
72 }
73
74 case 'inject-backend-manager': {
75 const {
76 payload: {tabId},
77 } = message;
78
79 if (!tabId) {
80 throw new Error("Couldn't inject backend manager: tabId not specified");
81 }
82
83 executeScriptInMainWorld({
84 injectImmediately: true,
85 target: {tabId},
86 files: ['/build/backendManager.js'],
87 }).then(
88 () => {
89 if (__DEBUG__) {
90 console.log('Successfully injected backend manager');
91 }
92 },
93 reason => {
94 console.error('Failed to inject backend manager:', reason);
95 },
96 );
97
98 break;
99 }
100
101 case 'eval-in-inspected-window': {
102 const {
103 payload: {tabId, requestId, scriptId, args},
104 } = message;
105
106 chrome.tabs
107 .sendMessage(tabId, {
108 source: 'devtools-page-eval',
109 payload: {
110 scriptId,
111 args,
112 },
113 })
114 .then(response => {
115 if (!response) {
116 chrome.runtime.sendMessage({
117 source: 'react-devtools-background',
118 payload: {
119 type: 'eval-in-inspected-window-response',
120 requestId,
121 result: null,
122 error: 'No response from content script',
123 },
124 });
125 return;
126 }
127 const {result, error} = response;
128 chrome.runtime.sendMessage({
129 source: 'react-devtools-background',
130 payload: {
131 type: 'eval-in-inspected-window-response',
132 requestId,
133 result,
134 error,
135 },
136 });
137 })
138 .catch(error => {
139 chrome.runtime.sendMessage({
140 source: 'react-devtools-background',
141 payload: {
142 type: 'eval-in-inspected-window-response',
143 requestId,
144 result: null,
145 error: error?.message || String(error),
146 },
147 });
148 });
149
150 break;
151 }
152 }
153 }
154
155 export function handleFetchResourceContentScriptMessage(message) {
156 const {payload} = message;
157
158 switch (payload?.type) {
159 case 'fetch-file-with-cache-complete':
160 case 'fetch-file-with-cache-error':
161 // Forward the result of fetch-in-page requests back to the DevTools page.
162 // We switch the source here because of inconsistency between Firefox and Chrome
163 // In Chromium this message will be propagated from content script to DevTools page
164 // For Firefox, only background script will get this message, so we need to forward it to DevTools page
165 chrome.runtime.sendMessage({
166 source: 'react-devtools-background',
167 payload,
168 });
169 break;
170 }
171 }