Skip to content

Commit

Permalink
Ensure sync-xhr is allowed before reload and profile (#20879)
Browse files Browse the repository at this point in the history
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
  • Loading branch information
ChrisDobby and bvaughn committed Mar 11, 2021
1 parent b7e6310 commit bd245c1
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 9 deletions.
2 changes: 2 additions & 0 deletions packages/react-devtools-shared/src/backend/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import type {
RendererInterface,
} from './types';
import type {ComponentFilter} from '../types';
import {isSynchronousXHRSupported} from './utils';

const debug = (methodName, ...args) => {
if (__DEBUG__) {
Expand Down Expand Up @@ -221,6 +222,7 @@ export default class Agent extends EventEmitter<{|
isBackendStorageAPISupported = true;
} catch (error) {}
bridge.send('isBackendStorageAPISupported', isBackendStorageAPISupported);
bridge.send('isSynchronousXHRSupported', isSynchronousXHRSupported());

setupHighlighter(bridge, this);
setupTraceUpdates(this);
Expand Down
8 changes: 8 additions & 0 deletions packages/react-devtools-shared/src/backend/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,11 @@ export function format(

return '' + formatted;
}

export function isSynchronousXHRSupported(): boolean {
return !!(
window.document &&
window.document.featurePolicy &&
window.document.featurePolicy.allowsFeature('sync-xhr')
);
}
1 change: 1 addition & 0 deletions packages/react-devtools-shared/src/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export type BackendEvents = {|
extensionBackendInitialized: [],
inspectedElement: [InspectedElementPayload],
isBackendStorageAPISupported: [boolean],
isSynchronousXHRSupported: [boolean],
operations: [Array<number>],
ownersList: [OwnersList],
overrideComponentFilters: [Array<ComponentFilter>],
Expand Down
56 changes: 47 additions & 9 deletions packages/react-devtools-shared/src/devtools/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ export default class Store extends EventEmitter<{|
// If not, features like reload-and-profile will not work correctly and must be disabled.
_isBackendStorageAPISupported: boolean = false;

// Can DevTools use sync XHR requests?
// If not, features like reload-and-profile will not work correctly and must be disabled.
// This current limitation applies only to web extension builds
// and will need to be reconsidered in the future if we add support for reload to React Native.
_isSynchronousXHRSupported: boolean = false;

_nativeStyleEditorValidAttributes: $ReadOnlyArray<string> | null = null;

// Map of element (id) to the set of elements (ids) it owns.
Expand Down Expand Up @@ -195,12 +201,16 @@ export default class Store extends EventEmitter<{|
bridge.addListener('shutdown', this.onBridgeShutdown);
bridge.addListener(
'isBackendStorageAPISupported',
this.onBridgeStorageSupported,
this.onBackendStorageAPISupported,
);
bridge.addListener(
'isNativeStyleEditorSupported',
this.onBridgeNativeStyleEditorSupported,
);
bridge.addListener(
'isSynchronousXHRSupported',
this.onBridgeSynchronousXHRSupported,
);
bridge.addListener(
'unsupportedRendererVersion',
this.onBridgeUnsupportedRendererVersion,
Expand Down Expand Up @@ -359,11 +369,16 @@ export default class Store extends EventEmitter<{|
get supportsProfiling(): boolean {
return this._supportsProfiling;
}

get supportsReloadAndProfile(): boolean {
// 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;
// And if so, can the backend use the localStorage API and sync XHR?
// All of these are currently required for the reload-and-profile feature to work.
return (
this._supportsReloadAndProfile &&
this._isBackendStorageAPISupported &&
this._isSynchronousXHRSupported
);
}

get supportsTraceUpdates(): boolean {
Expand Down Expand Up @@ -1130,20 +1145,43 @@ export default class Store extends EventEmitter<{|
debug('onBridgeShutdown', 'unsubscribing from Bridge');
}

this._bridge.removeListener('operations', this.onBridgeOperations);
this._bridge.removeListener('shutdown', this.onBridgeShutdown);
this._bridge.removeListener(
const bridge = this._bridge;
bridge.removeListener('operations', this.onBridgeOperations);
bridge.removeListener(
'overrideComponentFilters',
this.onBridgeOverrideComponentFilters,
);
bridge.removeListener('shutdown', this.onBridgeShutdown);
bridge.removeListener(
'isBackendStorageAPISupported',
this.onBridgeStorageSupported,
this.onBackendStorageAPISupported,
);
bridge.removeListener(
'isNativeStyleEditorSupported',
this.onBridgeNativeStyleEditorSupported,
);
bridge.removeListener(
'isSynchronousXHRSupported',
this.onBridgeSynchronousXHRSupported,
);
bridge.removeListener(
'unsupportedRendererVersion',
this.onBridgeUnsupportedRendererVersion,
);
};

onBridgeStorageSupported = (isBackendStorageAPISupported: boolean) => {
onBackendStorageAPISupported = (isBackendStorageAPISupported: boolean) => {
this._isBackendStorageAPISupported = isBackendStorageAPISupported;

this.emit('supportsReloadAndProfile');
};

onBridgeSynchronousXHRSupported = (isSynchronousXHRSupported: boolean) => {
this._isSynchronousXHRSupported = isSynchronousXHRSupported;

this.emit('supportsReloadAndProfile');
};

onBridgeUnsupportedRendererVersion = () => {
this._unsupportedRendererVersionDetected = true;

Expand Down

0 comments on commit bd245c1

Please sign in to comment.