-
Notifications
You must be signed in to change notification settings - Fork 35
/
index.js
140 lines (118 loc) · 3.24 KB
/
index.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* loader module
* @module src/loader
*
* the module aims to setup monaco-editor
* into your browser by using its `loader` script
*/
import state from 'state-local';
import defaultConfig from '../config';
import validators from '../validators';
import compose from '../utils/compose';
import deepMerge from '../utils/deepMerge';
import makeCancelable from '../utils/makeCancelable';
/** the local state of the module */
const [getState, setState] = state.create({
config: defaultConfig,
isInitialized: false,
resolve: null,
reject: null,
monaco: null,
});
/**
* set the loader configuration
* @param {Object} config - the configuration object
*/
function config(config) {
setState(state => ({
config: deepMerge(
state.config,
validators.config(config),
),
}));
}
/**
* handles the initialization of the monaco-editor
* @return {Promise} - returns an instance of monaco (with a cancelable promise)
*/
function init() {
const state = getState(({ isInitialized }) => ({ isInitialized }));
if (!state.isInitialized) {
if (window.monaco && window.monaco.editor) {
storeMonacoInstance(window.monaco);
return makeCancelable(Promise.resolve(window.monaco));
}
compose(
injectScripts,
getMonacoLoaderScript,
)(configureLoader);
setState({ isInitialized: true });
}
return makeCancelable(wrapperPromise);
}
/**
* injects provided scripts into the document.body
* @param {Object} script - an HTML script element
* @return {Object} - the injected HTML script element
*/
function injectScripts(script) {
return document.body.appendChild(script);
}
/**
* creates an HTML script element with/without provided src
* @param {string} [src] - the source path of the script
* @return {Object} - the created HTML script element
*/
function createScript(src) {
const script = document.createElement('script');
return (src && (script.src = src), script);
}
/**
* creates an HTML script element with the monaco loader src
* @return {Object} - the created HTML script element
*/
function getMonacoLoaderScript(configureLoader) {
const state = getState(({ config, reject }) => ({ config, reject }));
const loaderScript = createScript(`${state.config.paths.vs}/loader.js`);
loaderScript.onload = () => configureLoader();
loaderScript.onerror = state.reject;
return loaderScript;
}
/**
* configures the monaco loader
*/
function configureLoader() {
const state = getState(
({ config, resolve, reject }) => ({ config, resolve, reject })
);
const require = window.require;
require.config(state.config);
require(
['vs/editor/editor.main'],
function(monaco) {
storeMonacoInstance(monaco);
state.resolve(monaco);
},
function(error) {
state.reject(error);
},
);
}
/**
* store monaco instance in local state
*/
function storeMonacoInstance(monaco) {
if (!getState().monaco) {
setState({ monaco });
}
}
/**
* internal helper function
* extracts stored monaco instance
* @return {Object|null} - the monaco instance
*/
function __getMonacoInstance() {
return getState(({ monaco }) => monaco);
}
const wrapperPromise = new Promise((resolve, reject) => setState({ resolve, reject }));
export default { config, init, __getMonacoInstance };