Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ module.exports = {
mixin$Animatable: 'readonly',
MouseEventHandler: 'readonly',
NavigateEvent: 'readonly',
Partial: 'readonly',
PerformanceMeasureOptions: 'readonly',
PropagationPhases: 'readonly',
PropertyDescriptor: 'readonly',
Expand Down
16 changes: 8 additions & 8 deletions flow-typed/environments/bom.js
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ declare class WebSocket extends EventTarget {
bufferedAmount: number;
extensions: string;
onopen: (ev: any) => mixed;
onmessage: (ev: MessageEvent) => mixed;
onmessage: (ev: MessageEvent<>) => mixed;
onclose: (ev: CloseEvent) => mixed;
onerror: (ev: any) => mixed;
binaryType: 'blob' | 'arraybuffer';
Expand Down Expand Up @@ -855,8 +855,8 @@ declare class Worker extends EventTarget {
workerOptions?: WorkerOptions
): void;
onerror: null | ((ev: any) => mixed);
onmessage: null | ((ev: MessageEvent) => mixed);
onmessageerror: null | ((ev: MessageEvent) => mixed);
onmessage: null | ((ev: MessageEvent<>) => mixed);
onmessageerror: null | ((ev: MessageEvent<>) => mixed);
postMessage(message: any, ports?: any): void;
terminate(): void;
}
Expand Down Expand Up @@ -888,14 +888,14 @@ declare class WorkerGlobalScope extends EventTarget {
}

declare class DedicatedWorkerGlobalScope extends WorkerGlobalScope {
onmessage: (ev: MessageEvent) => mixed;
onmessageerror: (ev: MessageEvent) => mixed;
onmessage: (ev: MessageEvent<>) => mixed;
onmessageerror: (ev: MessageEvent<>) => mixed;
postMessage(message: any, transfer?: Iterable<any>): void;
}

declare class SharedWorkerGlobalScope extends WorkerGlobalScope {
name: string;
onconnect: (ev: MessageEvent) => mixed;
onconnect: (ev: MessageEvent<>) => mixed;
}

declare class WorkerLocation {
Expand Down Expand Up @@ -2056,8 +2056,8 @@ declare class MessagePort extends EventTarget {
start(): void;
close(): void;

onmessage: null | ((ev: MessageEvent) => mixed);
onmessageerror: null | ((ev: MessageEvent) => mixed);
onmessage: null | ((ev: MessageEvent<>) => mixed);
onmessageerror: null | ((ev: MessageEvent<>) => mixed);
}

declare class MessageChannel {
Expand Down
6 changes: 3 additions & 3 deletions flow-typed/environments/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ type TransitionEventHandler = (event: TransitionEvent) => mixed;
type TransitionEventListener =
| {handleEvent: TransitionEventHandler, ...}
| TransitionEventHandler;
type MessageEventHandler = (event: MessageEvent) => mixed;
type MessageEventHandler = (event: MessageEvent<>) => mixed;
type MessageEventListener =
| {handleEvent: MessageEventHandler, ...}
| MessageEventHandler;
Expand Down Expand Up @@ -845,8 +845,8 @@ declare class PageTransitionEvent extends Event {
// https://www.w3.org/TR/2008/WD-html5-20080610/comms.html
// and
// https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interfaces
declare class MessageEvent extends Event {
data: mixed;
declare class MessageEvent<Data = mixed> extends Event {
data: Data;
origin: string;
lastEventId: string;
source: WindowProxy;
Expand Down
4 changes: 2 additions & 2 deletions flow-typed/environments/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ declare class ErrorEvent extends Event {
// https://html.spec.whatwg.org/multipage/web-messaging.html#broadcasting-to-other-browsing-contexts
declare class BroadcastChannel extends EventTarget {
name: string;
onmessage: ?(event: MessageEvent) => void;
onmessageerror: ?(event: MessageEvent) => void;
onmessage: ?(event: MessageEvent<>) => void;
onmessageerror: ?(event: MessageEvent<>) => void;

constructor(name: string): void;
postMessage(msg: mixed): void;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-devtools-core/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
scheduleRetry();
}

function handleMessage(event: MessageEvent) {
function handleMessage(event: MessageEvent<>) {
let data;
try {
if (typeof event.data === 'string') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,50 @@
/* global chrome */
/** @flow */

// We can't use chrome.storage domain from scripts which are injected in ExecutionWorld.MAIN
// This is the only purpose of this script - to send persisted settings to installHook.js content script

async function messageListener(event: MessageEvent) {
import type {UnknownMessageEvent} from './messages';
import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';
import {postMessage} from './messages';

async function messageListener(event: UnknownMessageEvent) {
if (event.source !== window) {
return;
}

if (event.data.source === 'react-devtools-hook-installer') {
if (event.data.payload.handshake) {
const settings = await chrome.storage.local.get();
const settings: Partial<DevToolsHookSettings> =
await chrome.storage.local.get();
// If storage was empty (first installation), define default settings
if (typeof settings.appendComponentStack !== 'boolean') {
settings.appendComponentStack = true;
}
if (typeof settings.breakOnConsoleErrors !== 'boolean') {
settings.breakOnConsoleErrors = false;
}
if (typeof settings.showInlineWarningsAndErrors !== 'boolean') {
settings.showInlineWarningsAndErrors = true;
}
if (typeof settings.hideConsoleLogsInStrictMode !== 'boolean') {
settings.hideConsoleLogsInStrictMode = false;
}
if (
typeof settings.disableSecondConsoleLogDimmingInStrictMode !== 'boolean'
) {
settings.disableSecondConsoleLogDimmingInStrictMode = false;
}
const hookSettings: DevToolsHookSettings = {
appendComponentStack:
typeof settings.appendComponentStack === 'boolean'
? settings.appendComponentStack
: true,
breakOnConsoleErrors:
typeof settings.breakOnConsoleErrors === 'boolean'
? settings.breakOnConsoleErrors
: false,
showInlineWarningsAndErrors:
typeof settings.showInlineWarningsAndErrors === 'boolean'
? settings.showInlineWarningsAndErrors
: true,
hideConsoleLogsInStrictMode:
typeof settings.hideConsoleLogsInStrictMode === 'boolean'
? settings.hideConsoleLogsInStrictMode
: false,
disableSecondConsoleLogDimmingInStrictMode:
typeof settings.disableSecondConsoleLogDimmingInStrictMode ===
'boolean'
? settings.disableSecondConsoleLogDimmingInStrictMode
: false,
};

window.postMessage({
postMessage({
source: 'react-devtools-hook-settings-injector',
payload: {settings},
payload: {settings: hookSettings},
});

window.removeEventListener('message', messageListener);
Expand All @@ -41,7 +53,7 @@ async function messageListener(event: MessageEvent) {
}

window.addEventListener('message', messageListener);
window.postMessage({
postMessage({
source: 'react-devtools-hook-settings-injector',
payload: {handshake: true},
});
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
/** @flow */

import type {UnknownMessageEvent} from './messages';
import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';

import {installHook} from 'react-devtools-shared/src/hook';
import {
getIfReloadedAndProfiling,
getProfilingSettings,
} from 'react-devtools-shared/src/utils';
import {postMessage} from './messages';

let resolveHookSettingsInjection;
let resolveHookSettingsInjection: (settings: DevToolsHookSettings) => void;

function messageListener(event: MessageEvent) {
function messageListener(event: UnknownMessageEvent) {
if (event.source !== window) {
return;
}

if (event.data.source === 'react-devtools-hook-settings-injector') {
const payload = event.data.payload;
// In case handshake message was sent prior to hookSettingsInjector execution
// We can't guarantee order
if (event.data.payload.handshake) {
window.postMessage({
if (payload.handshake) {
postMessage({
source: 'react-devtools-hook-installer',
payload: {handshake: true},
});
} else if (event.data.payload.settings) {
} else if (payload.settings) {
window.removeEventListener('message', messageListener);
resolveHookSettingsInjection(event.data.payload.settings);
resolveHookSettingsInjection(payload.settings);
}
}
}

// Avoid double execution
if (!window.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) {
const hookSettingsPromise = new Promise(resolve => {
const hookSettingsPromise = new Promise<DevToolsHookSettings>(resolve => {
resolveHookSettingsInjection = resolve;
});

window.addEventListener('message', messageListener);
window.postMessage({
postMessage({
source: 'react-devtools-hook-installer',
payload: {handshake: true},
});
Expand Down
42 changes: 42 additions & 0 deletions packages/react-devtools-extensions/src/contentScripts/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/** @flow */

import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';

export function postMessage(event: UnknownMessageEventData): void {
window.postMessage(event);
}

export interface UnknownMessageEvent
extends MessageEvent<UnknownMessageEventData> {}

export type UnknownMessageEventData =
| HookSettingsInjectorEventData
| HookInstallerEventData;

export type HookInstallerEventData = {
source: 'react-devtools-hook-installer',
payload: HookInstallerEventPayload,
};

export type HookInstallerEventPayload = HookInstallerEventPayloadHandshake;

export type HookInstallerEventPayloadHandshake = {
handshake: true,
};

export type HookSettingsInjectorEventData = {
source: 'react-devtools-hook-settings-injector',
payload: HookSettingsInjectorEventPayload,
};

export type HookSettingsInjectorEventPayload =
| HookSettingsInjectorEventPayloadHandshake
| HookSettingsInjectorEventPayloadSettings;

export type HookSettingsInjectorEventPayloadHandshake = {
handshake: true,
};

export type HookSettingsInjectorEventPayloadSettings = {
settings: DevToolsHookSettings,
};
35 changes: 17 additions & 18 deletions packages/react-reconciler/src/ReactFiberTreeReflection.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,24 @@ import {NoFlags, Placement, Hydrating} from './ReactFiberFlags';
export function getNearestMountedFiber(fiber: Fiber): null | Fiber {
let node = fiber;
let nearestMounted: null | Fiber = fiber;
if (!fiber.alternate) {
// If there is no alternate, this might be a new tree that isn't inserted
// yet. If it is, then it will have a pending insertion effect on it.
let nextNode: Fiber = node;
do {
node = nextNode;
if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
// This is an insertion or in-progress hydration. The nearest possible
// mounted fiber is the parent but we need to continue to figure out
// if that one is still mounted.
nearestMounted = node.return;
}
// $FlowFixMe[incompatible-type] we bail out when we get a null
nextNode = node.return;
} while (nextNode);
} else {
while (node.return) {
node = node.return;
// If there is no alternate, this might be a new tree that isn't inserted
// yet. If it is, then it will have a pending insertion effect on it.
let nextNode: Fiber = node;
while (nextNode && !nextNode.alternate) {
node = nextNode;
if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
// This is an insertion or in-progress hydration. The nearest possible
// mounted fiber is the parent but we need to continue to figure out
// if that one is still mounted.
nearestMounted = node.return;
}
// $FlowFixMe[incompatible-type] we bail out when we get a null
nextNode = node.return;
}
// After we've reached an alternate, go the rest of the way to see if the
// tree is still mounted. If it's not, its return pointer will be disconnected.
while (node.return) {
node = node.return;
}
if (node.tag === HostRoot) {
// TODO: Check if this was a nested HostRoot when used with
Expand Down
Loading