forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathuseOpenResource.js
More file actions
75 lines (63 loc) · 2.62 KB
/
useOpenResource.js
File metadata and controls
75 lines (63 loc) · 2.62 KB
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
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {ReactFunctionLocation, ReactCallSite} from 'shared/ReactTypes';
import {useCallback, useContext, useSyncExternalStore} from 'react';
import ViewElementSourceContext from './Components/ViewElementSourceContext';
import {getAlwaysOpenInEditor} from '../../utils';
import useEditorURL from './useEditorURL';
import {LOCAL_STORAGE_ALWAYS_OPEN_IN_EDITOR} from '../../constants';
import {checkConditions} from './Editor/utils';
const useOpenResource = (
source: null | ReactFunctionLocation | ReactCallSite,
symbolicatedSource: null | ReactFunctionLocation | ReactCallSite,
): [
boolean, // isEnabled
() => void, // Open Resource
] => {
const {canViewElementSourceFunction, viewElementSourceFunction} = useContext(
ViewElementSourceContext,
);
const editorURL = useEditorURL();
const alwaysOpenInEditor = useSyncExternalStore(
useCallback(function subscribe(callback) {
window.addEventListener(LOCAL_STORAGE_ALWAYS_OPEN_IN_EDITOR, callback);
return function unsubscribe() {
window.removeEventListener(
LOCAL_STORAGE_ALWAYS_OPEN_IN_EDITOR,
callback,
);
};
}, []),
getAlwaysOpenInEditor,
);
// First check if this link is eligible for being open directly in the configured editor.
const openInEditor =
alwaysOpenInEditor && source !== null
? checkConditions(editorURL, symbolicatedSource || source)
: null;
// In some cases (e.g. FB internal usage) the standalone shell might not be able to view the source.
// To detect this case, we defer to an injected helper function (if present).
const linkIsEnabled =
(openInEditor !== null && !openInEditor.shouldDisableButton) ||
(viewElementSourceFunction != null &&
source != null &&
(canViewElementSourceFunction == null ||
canViewElementSourceFunction(source, symbolicatedSource)));
const viewSource = useCallback(() => {
if (openInEditor !== null && !openInEditor.shouldDisableButton) {
// If we have configured to always open in the code editor, we do so if we can.
// Otherwise, we fallback to open in the local editor if possible (e.g. non-file urls).
window.open(openInEditor.url);
} else if (viewElementSourceFunction != null && source != null) {
viewElementSourceFunction(source, symbolicatedSource);
}
}, [openInEditor, source, symbolicatedSource]);
return [linkIsEnabled, viewSource];
};
export default useOpenResource;