Completed
Push — master ( 8967bc...e88c19 )
by Rain
02:47
created

dev/Common/Booter.js   F

Complexity

Total Complexity 76
Complexity/F 2.92

Size

Lines of Code 337
Function Count 26

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
c 1
b 0
f 0
nc 8
dl 0
loc 337
rs 3.8494
wmc 76
mnd 4
bc 47
fnc 26
bpm 1.8076
cpm 2.923
noi 3

14 Functions

Rating   Name   Duplication   Size   Complexity  
B useJsNextBundle.constructor 0 39 3
A Booter.js ➔ runMainBoot 0 13 3
A Booter.js ➔ ??? 0 1 1
B window.__runBoot 0 23 6
B window.__initAppData 0 23 4
B Booter.js ➔ includeAppScr 0 11 6
C Booter.js ➔ runApp 0 62 10
A Booter.js ➔ getRainloopBootData 0 12 3
B Booter.js ➔ showError 0 28 6
A Booter.js ➔ includeScr 0 4 1
A Booter.js ➔ getComputedStyle 0 6 3
A Booter.js ➔ includeLayout 0 17 4
A Booter.js ➔ includeStyle 0 4 1
B Booter.js ➔ showDescriptionAndLoading 0 19 5

How to fix   Complexity   

Complexity

Complex classes like dev/Common/Booter.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
2
import window from 'window';
3
import progressJs from 'progressJs';
4
import Promise from 'Promise';
5
6
import STYLES_CSS from 'Styles/@Boot.css';
7
import LAYOUT_HTML from 'Html/Layout.html';
8
9
import {getHash, setHash, clearHash} from 'Storage/RainLoop';
10
11
let RL_APP_DATA_STORAGE = null;
12
13
/* eslint-disable  */
14
window.__rlah = () => getHash();
15
window.__rlah_set = () => setHash();
16
window.__rlah_clear = () => clearHash();
17
window.__rlah_data = () => RL_APP_DATA_STORAGE;
18
/* eslint-enable */
19
20
const useJsNextBundle = (function() {
21
22
	if (!RL_ES6)
0 ignored issues
show
Best Practice introduced by
If you intend to check if the variable RL_ES6 is declared in the current environment, consider using typeof RL_ES6 === "undefined" instead. This is safe if the variable is not actually declared.
Loading history...
23
	{
24
		return false;
25
	}
26
27
	/* eslint-disable  */
28
	try {
29
30
		eval(`
1 ignored issue
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
31
 // let + const
32
const x = 5; let y = 4; var z = 4;
33
34
 // Arrow Function
35
const f = () => 'rainloop';
36
37
 // Default + Rest + Spread
38
const d = (test = 1, ...t) => 'rainloop';
39
d(...[1, 2, 3]);
40
41
// Destructuring
42
let [a, b] = [1, 2];
43
({a, b} = {a: 1, b: 2});
44
45
// Class
46
class Q1 { constructor() {} }
47
48
// Class extends + super
49
class Q2 extends Q1 { constructor() { super() } }
50
51
`);
52
		return true;
53
	}
54
	catch (e) {}
55
56
    return false;
57
	/* eslint-enable */
58
}());
59
60
/**
61
 * @param {string} id
62
 * @param {string} name
63
 * @returns {string}
64
 */
65
function getComputedStyle(id, name)
66
{
67
	var element = window.document.getElementById(id);
68
	return element.currentStyle ? element.currentStyle[name] :
69
		(window.getComputedStyle ? window.getComputedStyle(element, null).getPropertyValue(name) : null);
70
}
71
72
/**
73
 * @param {string} styles
74
 * @returns {void}
75
 */
76
function includeStyle(styles)
77
{
78
	window.document.write(unescape('%3Csty' + 'le%3E' + styles + '"%3E%3C/' + 'sty' + 'le%3E')); // eslint-disable-line no-useless-concat
79
}
80
81
/**
82
 * @param {string} src
83
 * @returns {void}
84
 */
85
function includeScr(src)
86
{
87
	window.document.write(unescape('%3Csc' + 'ript type="text/jav' + 'ascr' + 'ipt" data-cfasync="false" sr' + 'c="' + src + '"%3E%3C/' + 'scr' + 'ipt%3E')); // eslint-disable-line no-useless-concat
88
}
89
90
/**
91
 * @returns {boolean}
92
 */
93
function includeLayout()
94
{
95
	const app = window.document.getElementById('rl-app');
96
97
	if (STYLES_CSS)
98
	{
99
		includeStyle(STYLES_CSS);
100
	}
101
102
	if (app && LAYOUT_HTML)
103
	{
104
		app.innerHTML = LAYOUT_HTML.replace(/[\r\n\t]+/g, '');
105
		return true;
106
	}
107
108
	return false;
109
}
110
111
/**
112
 * @param {mixed} data
0 ignored issues
show
Documentation introduced by
The parameter data does not exist. Did you maybe forget to remove this comment?
Loading history...
113
 * @returns {void}
114
 */
115
function includeAppScr({admin = false, mobile = false, mobileDevice = false})
116
{
117
	let src = './?/';
118
	src += admin ? 'Admin' : '';
119
	src += 'AppData@';
120
	src += mobile ? 'mobile' : 'no-mobile';
121
	src += mobileDevice ? '-1' : '-0';
122
	src += '/';
123
124
	includeScr(src + (window.__rlah ? window.__rlah() || '0' : '0') + '/' + window.Math.random().toString().substr(2) + '/');
125
}
126
127
/**
128
 * @returns {object}
129
 */
130
function getRainloopBootData()
131
{
132
	let result = {};
133
	const meta = window.document.getElementById('app-boot-data');
134
135
	if (meta && meta.getAttribute)
136
	{
137
		result = JSON.parse(meta.getAttribute('content')) || {};
138
	}
139
140
	return result;
141
}
142
143
/**
144
 * @param {string} additionalError
145
 * @returns {void}
146
 */
147
function showError(additionalError)
148
{
149
	const
150
		oR = window.document.getElementById('rl-loading'),
151
		oL = window.document.getElementById('rl-loading-error'),
152
		oLA = window.document.getElementById('rl-loading-error-additional');
153
154
	if (oR)
155
	{
156
		oR.style.display = 'none';
157
	}
158
159
	if (oL)
160
	{
161
		oL.style.display = 'block';
162
	}
163
164
	if (oLA && additionalError)
165
	{
166
		oLA.style.display = 'block';
167
		oLA.innerHTML = additionalError;
168
	}
169
170
	if (progressJs)
171
	{
172
		progressJs.set(100).end();
173
	}
174
}
175
176
/**
177
 * @param {string} description
178
 * @returns {void}
179
 */
180
function showDescriptionAndLoading(description)
181
{
182
	const
183
		oE = window.document.getElementById('rl-loading'),
184
		oElDesc = window.document.getElementById('rl-loading-desc');
185
186
	if (oElDesc && description)
187
	{
188
		oElDesc.innerHTML = description;
189
	}
190
191
	if (oE && oE.style)
192
	{
193
		oE.style.opacity = 0;
194
		window.setTimeout(() => {
195
			oE.style.opacity = 1;
196
		}, 300);
197
	}
198
}
199
200
/**
201
 * @param {boolean} withError
202
 * @param {string} additionalError
203
 * @returns {void}
204
 */
205
function runMainBoot(withError, additionalError)
206
{
207
	if (window.__APP_BOOT && !withError)
208
	{
209
		window.__APP_BOOT(() => {
210
			showError(additionalError);
211
		});
212
	}
213
	else
214
	{
215
		showError(additionalError);
216
	}
217
}
218
219
/**
220
 * @returns {void}
221
 */
222
function runApp()
223
{
224
	const appData = window.__rlah_data();
225
226
	if (window.jassl && progressJs && appData && appData.TemplatesLink && appData.LangLink &&
227
		appData.StaticLibJsLink && appData.StaticAppJsLink && appData.StaticAppJsNextLink && appData.StaticEditorJsLink)
228
	{
229
		const p = progressJs;
230
231
		p.setOptions({theme: 'rainloop'});
232
		p.start().set(5);
233
234
		const
235
			libs = window.jassl(appData.StaticLibJsLink).then(() => {
236
				if (window.$)
237
				{
238
					window.$('#rl-check').remove();
239
240
					if (appData.IncludeBackground)
241
					{
242
						window.$('#rl-bg').attr('style', 'background-image: none !important;')
243
							.backstretch(appData.IncludeBackground.replace('{{USER}}',
244
								(window.__rlah ? (window.__rlah() || '0') : '0')), {fade: 100, centeredX: true, centeredY: true})
245
							.removeAttr('style');
246
					}
247
				}
248
			}),
249
			common = Promise.all([
250
				window.jassl(appData.TemplatesLink),
251
				window.jassl(appData.LangLink)
252
			]);
253
254
		Promise.all([libs, common])
255
			.then(() => {
256
				p.set(30);
257
				return window.jassl(useJsNextBundle ? appData.StaticAppJsNextLink : appData.StaticAppJsLink);
258
			})
259
			.then(() => {
260
				p.set(50);
261
				return appData.PluginsLink ? window.jassl(appData.PluginsLink) : window.Promise.resolve();
262
			})
263
			.then(() => {
264
				p.set(70);
265
				runMainBoot(false);
266
			})
267
			.catch((e) => {
268
				runMainBoot(true);
269
				throw e;
270
			})
271
			.then(() => window.jassl(appData.StaticEditorJsLink))
272
			.then(() => {
273
				if (window.CKEDITOR && window.__initEditor) {
274
					window.__initEditor();
275
					window.__initEditor = null;
276
				}
277
			});
278
	}
279
	else
280
	{
281
		runMainBoot(true);
282
	}
283
}
284
285
/**
286
 * @param {mixed} data
287
 * @returns {void}
288
 */
289
window.__initAppData = function(data) {
290
291
	RL_APP_DATA_STORAGE = data;
292
293
	window.__rlah_set();
294
295
	if (RL_APP_DATA_STORAGE)
296
	{
297
		if (RL_APP_DATA_STORAGE.NewThemeLink)
298
		{
299
			(window.document.getElementById('app-theme-link') || {}).href = RL_APP_DATA_STORAGE.NewThemeLink;
300
		}
301
302
		if (RL_APP_DATA_STORAGE.IncludeCss)
303
		{
304
			includeStyle(RL_APP_DATA_STORAGE.IncludeCss);
305
		}
306
307
		showDescriptionAndLoading(RL_APP_DATA_STORAGE.LoadingDescriptionEsc || '');
308
	}
309
310
	runApp();
311
};
312
313
/**
314
 * @returns {void}
315
 */
316
window.__runBoot = function() {
317
318
	if (!window.navigator || !window.navigator.cookieEnabled)
319
	{
320
		window.document.location.replace('./?/NoCookie');
321
	}
322
323
	const root = document.documentElement;
324
	if ('none' !== getComputedStyle('rl-check', 'display'))
325
	{
326
		root.className += ' no-css';
327
	}
328
329
	if (useJsNextBundle)
330
	{
331
		root.className += ' js-next';
332
	}
333
334
	if (includeLayout())
335
	{
336
		includeAppScr(getRainloopBootData());
337
	}
338
};
339
340