Backend notifies the frontend of Storage API support. Frontend disables e.g. reload-and-profile based on this.

This commit is contained in:
Brian Vaughn
2019-06-07 13:08:49 -07:00
parent 3e3c83aecd
commit 78721bde4c
3 changed files with 49 additions and 3 deletions
+9
View File
@@ -127,6 +127,15 @@ export default class Agent extends EventEmitter {
if (this._isProfiling) {
bridge.send('profilingStatus', true);
}
// Notify the frontend if the backend supports the Storage API (e.g. localStorage).
// If not, features like reload-and-profile will not work correctly and must be disabled.
let isBackendStorageAPISupported = false;
try {
localStorage.getItem('test');
isBackendStorageAPISupported = true;
} catch (error) {}
bridge.send('isBackendStorageAPISupported', isBackendStorageAPISupported);
}
captureScreenshot = ({
+22 -1
View File
@@ -73,6 +73,10 @@ export default class Store extends EventEmitter {
// The InspectedElementContext also relies on this mutability for its WeakMap usage.
_idToElement: Map<number, Element> = new Map();
// Can the backend use the Storage API (e.g. localStorage)?
// If not, features like reload-and-profile will not work correctly and must be disabled.
_isBackendStorageAPISupported: boolean = false;
// Map of element (id) to the set of elements (ids) it owns.
// This map enables getOwnersListForElement() to avoid traversing the entire tree.
_ownersMap: Map<number, Set<number>> = new Map();
@@ -141,6 +145,10 @@ export default class Store extends EventEmitter {
this._bridge = bridge;
bridge.addListener('operations', this.onBridgeOperations);
bridge.addListener('shutdown', this.onBridgeShutdown);
bridge.addListener(
'isBackendStorageAPISupported',
this.onBridgeStorageSupported
);
this._profilerStore = new ProfilerStore(bridge, this, isProfiling);
}
@@ -261,7 +269,10 @@ export default class Store extends EventEmitter {
}
get supportsReloadAndProfile(): boolean {
return this._supportsReloadAndProfile;
// Does the DevTools shell support reloading and eagerly injecting the renderer interface?
// And if so, can the backend use the localStorage API?
// Both of these are required for the reload-and-profile feature to work.
return this._supportsReloadAndProfile && this._isBackendStorageAPISupported;
}
containsElement(id: number): boolean {
@@ -904,5 +915,15 @@ export default class Store extends EventEmitter {
this._bridge.removeListener('operations', this.onBridgeOperations);
this._bridge.removeListener('shutdown', this.onBridgeShutdown);
this._bridge.removeListener(
'isBackendStorageAPISupported',
this.onBridgeStorageSupported
);
};
onBridgeStorageSupported = (isBackendStorageAPISupported: boolean) => {
this._isBackendStorageAPISupported = isBackendStorageAPISupported;
this.emit('supportsReloadAndProfile');
};
}
@@ -1,19 +1,35 @@
// @flow
import React, { useCallback, useContext } from 'react';
import React, { useCallback, useContext, useMemo } from 'react';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import { BridgeContext, StoreContext } from '../context';
import { useSubscription } from '../hooks';
import Store from 'src/devtools/store';
export default function ReloadAndProfileButton() {
const bridge = useContext(BridgeContext);
const store = useContext(StoreContext);
const supportsReloadAndProfileSubscription = useMemo(
() => ({
getCurrentValue: () => store.supportsReloadAndProfile,
subscribe: (callback: Function) => {
store.addListener('supportsReloadAndProfile', callback);
return () => store.removeListener('supportsReloadAndProfile', callback);
},
}),
[store]
);
const supportsReloadAndProfile = useSubscription<boolean, Store>(
supportsReloadAndProfileSubscription
);
const reloadAndProfile = useCallback(() => bridge.send('reloadAndProfile'), [
bridge,
]);
if (!store.supportsReloadAndProfile) {
if (!supportsReloadAndProfile) {
return null;
}