-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathGlobalHook.js
77 lines (68 loc) · 2.74 KB
/
GlobalHook.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/
'use strict';
/* globals chrome */
// Inject a `__REACT_DEVTOOLS_GLOBAL_HOOK__` global so that React can detect that the
// devtools are installed (and skip its suggestion to install the devtools).
var installGlobalHook = require('./backend/installGlobalHook.js');
var installRelayHook = require('./plugins/Relay/installRelayHook.js');
var lastDetectionResult;
// We want to detect when a renderer attaches, and notify the "background
// page" (which is shared between tabs and can highlight the React icon).
// Currently we are in "content script" context, so we can't listen
// to the hook directly (it will be injected directly into the page).
// So instead, the hook will use postMessage() to pass message to us here.
// And when this happens, we'll send a message to the "background page".
window.addEventListener('message', function(evt) {
if (evt.source === window && evt.data && evt.data.source === 'react-devtools-detector') {
lastDetectionResult = {
hasDetectedReact: true,
reactBuildType: evt.data.reactBuildType,
};
chrome.runtime.sendMessage(lastDetectionResult);
}
});
// NOTE: Firefox WebExtensions content scripts are still alive and not re-injected
// while navigating the history to a document that has not been destroyed yet,
// replay the last detection result if the content script is active and the
// document has been hidden and shown again.
window.addEventListener('pageshow', function(evt) {
if (!lastDetectionResult || evt.target !== window.document) {
return;
}
chrome.runtime.sendMessage(lastDetectionResult);
});
var detectReact = `
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.on('renderer', function(evt) {
window.postMessage({
source: 'react-devtools-detector',
reactBuildType: evt.reactBuildType,
}, '*');
});
`;
var saveNativeValues = `
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeObjectCreate = Object.create;
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeMap = Map;
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeWeakMap = WeakMap;
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.nativeSet = Set;
`;
var js = (
';(' + installGlobalHook.toString() + '(window))' +
';(' + installRelayHook.toString() + '(window))' +
saveNativeValues +
detectReact
);
// This script runs before the <head> element is created, so we add the script
// to <html> instead.
var script = document.createElement('script');
script.textContent = js;
document.documentElement.appendChild(script);
script.parentNode.removeChild(script);