1 | import Vue from 'vue/dist/vue.esm';
|
2 | import Vuex from 'vuex';
|
3 | import userConfig from 'manifest';
|
4 | import demoList from '.demoList.json';
|
5 | import router from '@/js/router.js';
|
6 | import bus from '@/js/eventbus.js';
|
7 |
|
8 | let config = userConfig;
|
9 | if (typeof config === 'function') {
|
10 | config = config(process.env.NODE_ENV);
|
11 | }
|
12 |
|
13 | config = Object.assign(
|
14 | {
|
15 | name: 'DEMOSIFY',
|
16 | version: 'v1',
|
17 | homePage: 'https://github.com/betseyliu/demo-ground',
|
18 | logo: '',
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | boxTheme: 'monokai',
|
29 | globalPackages: {
|
30 | js: [],
|
31 | css: []
|
32 | },
|
33 |
|
34 | editorViewMode: 'tab'
|
35 | },
|
36 | config
|
37 | );
|
38 |
|
39 | import progress from 'nprogress';
|
40 | progress.configure({
|
41 | showSpinner: false
|
42 | });
|
43 |
|
44 | Vue.use(Vuex);
|
45 |
|
46 | const demoBoxes = {};
|
47 |
|
48 | function importAllDemo(r) {
|
49 | r.keys().forEach(key => {
|
50 | const matched = /^\.\/((?:.+\/)*.+)\//.exec(key);
|
51 | if (matched) {
|
52 | demoBoxes[matched[1]] = r(key).default;
|
53 | }
|
54 | });
|
55 | }
|
56 | importAllDemo(require.context('demos', true, /config.js$/));
|
57 |
|
58 | const links = demoList.map(link => {
|
59 | if (typeof link === 'string') {
|
60 | link = { label: link, src: link };
|
61 | }
|
62 |
|
63 | if ('demos' in link) {
|
64 | link.demos.map(l => ({ lable: l, src: l }));
|
65 | }
|
66 | return link;
|
67 | });
|
68 |
|
69 | const state = {
|
70 | config,
|
71 | boxes: {},
|
72 | foldBoxes: [],
|
73 | links,
|
74 | iframeStatus: null,
|
75 | isSidebarShown: true,
|
76 | transforming: false,
|
77 | inIframe: window !== top,
|
78 | autoRun: true,
|
79 | logs: [],
|
80 | currentBox: undefined,
|
81 | dependencies: {
|
82 | js: [],
|
83 | css: []
|
84 | }
|
85 | };
|
86 |
|
87 | if (state.inIframe) {
|
88 | state.isSidebarShown = false;
|
89 | }
|
90 |
|
91 | const mutations = {
|
92 | CLEAR_BOXES(state) {
|
93 | state.boxes = {};
|
94 | },
|
95 | UPDATE_TAB(state, { type, tabName }) {
|
96 | if (!state.boxes[type]) state.boxes[type] = {};
|
97 | state.boxes[type].tabName = tabName;
|
98 | },
|
99 | UPDATE_KEY(state, { type, key }) {
|
100 | if (!state.boxes[type]) state.boxes[type] = {};
|
101 | state.boxes[type].key = key;
|
102 | },
|
103 | UPDATE_CODE(state, { type, code }) {
|
104 | if (!state.boxes[type]) state.boxes[type] = {};
|
105 | state.boxes[type].code = code;
|
106 | if (state.autoRun) bus.$emit('run');
|
107 | },
|
108 | UPDATE_TRANSFORM(state, { type, transform }) {
|
109 | if (!state.boxes[type]) state.boxes[type] = {};
|
110 | state.boxes[type].transform = transform;
|
111 | },
|
112 | UPDATE_TRANSFORMER(state, { type, transformer }) {
|
113 | if (!state.boxes[type]) state.boxes[type] = {};
|
114 | state.boxes[type].transformer = transformer;
|
115 | },
|
116 | UPDATE_EDITOR_HOOK(state, { type, editorHook }) {
|
117 | if (!state.boxes[type]) state.boxes[type] = {};
|
118 | state.boxes[type].editorHook = editorHook;
|
119 | },
|
120 | UPDATE_INPUT_HOOK(state, { type, inputHook }) {
|
121 | if (!state.boxes[type]) state.boxes[type] = {};
|
122 | state.boxes[type].inputHook = inputHook;
|
123 | },
|
124 | UPDATE_FOLD_BOXES(state, foldBoxes) {
|
125 | state.foldBoxes = foldBoxes;
|
126 | },
|
127 | UPDATE_VISIBLE(state, { type, visible }) {
|
128 | if (!state.boxes[type]) state.boxes[type] = {};
|
129 | state.boxes[type].visible = visible;
|
130 | },
|
131 | TOGGLE_BOX_FOLD(state, boxName) {
|
132 | const boxIndex = state.foldBoxes.indexOf(boxName);
|
133 | if (boxIndex > -1) {
|
134 | state.foldBoxes.splice(boxIndex, 1);
|
135 | } else {
|
136 | state.foldBoxes.push(boxName);
|
137 | }
|
138 | },
|
139 | SET_IFRAME_STATUS(state, status) {
|
140 | state.iframeStatus = status;
|
141 | },
|
142 | SET_TRANSFORM(state, status) {
|
143 | state.transforming = status;
|
144 | },
|
145 | TOGGLE_AUTO_RUN(state) {
|
146 | state.autoRun = !state.autoRun;
|
147 | },
|
148 | CLEAR_LOGS(state) {
|
149 | state.logs = [];
|
150 | },
|
151 | ADD_LOG(state, log) {
|
152 | state.logs.push(log);
|
153 | },
|
154 | UPDATE_DEPENDENCIES(state, dependencies = { js: [], css: [] }) {
|
155 | state.dependencies = dependencies;
|
156 | },
|
157 | TOGGLE_SIDEBAR(state) {
|
158 | state.isSidebarShown = !state.isSidebarShown;
|
159 | },
|
160 | UPDATE_CURRENT_BOX(state, box) {
|
161 | state.currentBox = box;
|
162 | }
|
163 | };
|
164 |
|
165 | const actions = {
|
166 | clearBoxes({ commit }) {
|
167 | commit('CLEAR_BOXES');
|
168 | },
|
169 | updateTab({ commit }, pl) {
|
170 | commit('UPDATE_TAB', pl);
|
171 | },
|
172 | updateKey({ commit }, pl) {
|
173 | commit('UPDATE_KEY', pl);
|
174 | },
|
175 | updateCode({ commit }, pl) {
|
176 | commit('UPDATE_CODE', pl);
|
177 | },
|
178 | updateTransformer({ commit }, pl) {
|
179 | commit('UPDATE_TRANSFORMER', pl);
|
180 | },
|
181 | updateTransform({ commit }, pl) {
|
182 | commit('UPDATE_TRANSFORM', pl);
|
183 | },
|
184 | updateEditorHook({ commit }, pl) {
|
185 | commit('UPDATE_EDITOR_HOOK', pl);
|
186 | },
|
187 | updateInputHook({ commit }, pl) {
|
188 | commit('UPDATE_INPUT_HOOK', pl);
|
189 | },
|
190 | updateFoldBoxes({ commit }, pl) {
|
191 | commit('UPDATE_FOLD_BOXES', pl);
|
192 | },
|
193 | updateVisible({ commit }, pl) {
|
194 | commit('UPDATE_VISIBLE', pl);
|
195 | },
|
196 | toggleBoxFold({ commit }, pl) {
|
197 | commit('TOGGLE_BOX_FOLD', pl);
|
198 | },
|
199 | toogleAutoRun({ commit }) {
|
200 | commit('TOGGLE_AUTO_RUN');
|
201 | },
|
202 | updateDependencies({ commit }, pl) {
|
203 | commit('UPDATE_DEPENDENCIES', pl);
|
204 | },
|
205 | updateCurrentBox({ commit }, pl) {
|
206 | commit('UPDATE_CURRENT_BOX', pl);
|
207 | },
|
208 | async setBoxes({ dispatch }, demo) {
|
209 | progress.start();
|
210 |
|
211 | let demoID;
|
212 | if (!demoBoxes[demo]) {
|
213 | router.push({ path: '/404' });
|
214 | progress.done();
|
215 | return;
|
216 | }
|
217 | if (typeof demo === 'string') {
|
218 | demoID = demo;
|
219 | if (typeof demoBoxes[demo] === 'function') {
|
220 | demo = await demoBoxes[demo]();
|
221 | } else {
|
222 | demo = await demoBoxes[demo];
|
223 | }
|
224 | } else {
|
225 | demoID =
|
226 | 'demo-' +
|
227 | Math.random()
|
228 | .toString(16)
|
229 | .slice(2, 14);
|
230 | }
|
231 |
|
232 | let { foldBoxes, packages, ...boxes } = demo;
|
233 |
|
234 | const ac = [];
|
235 |
|
236 | dispatch('clearBoxes');
|
237 |
|
238 | packages = packages || { js: [], css: [] };
|
239 |
|
240 | ['html', 'css', 'javascript', 'rawdata'].forEach(type => {
|
241 | if (!boxes[type] || typeof boxes[type] === 'string') {
|
242 | boxes[type] = {
|
243 | code: boxes[type] || '',
|
244 | visible: boxes[type] != null
|
245 | };
|
246 | } else if (
|
247 | boxes[type].default &&
|
248 | typeof boxes[type].default === 'string'
|
249 | ) {
|
250 | boxes[type] = {
|
251 | code: boxes[type].default,
|
252 | visible: true
|
253 | };
|
254 | } else if (typeof boxes[type].code !== 'string') {
|
255 | boxes[type].code =
|
256 | boxes[type].code != null ? boxes[type].code.default || '' : '';
|
257 | }
|
258 | boxes[type].transformer = boxes[type].transformer || type;
|
259 | boxes[type].visible = !!boxes[type].visible;
|
260 | });
|
261 |
|
262 | Object.entries(boxes).forEach(
|
263 | ([
|
264 | type,
|
265 | {
|
266 | tabName,
|
267 | code,
|
268 | transformer,
|
269 | visible,
|
270 | transform,
|
271 | editorHook,
|
272 | inputHook
|
273 | }
|
274 | ]) => {
|
275 | transform =
|
276 | transform ||
|
277 | function(code) {
|
278 | return code;
|
279 | };
|
280 | ac.push(
|
281 | dispatch('updateTab', { type, tabName }),
|
282 | dispatch('updateKey', { type, key: demoID }),
|
283 | dispatch('updateCode', { type, code }),
|
284 | dispatch('updateTransformer', { type, transformer }),
|
285 | dispatch('updateTransform', { type, transform }),
|
286 | dispatch('updateVisible', { type, visible: Boolean(visible) }),
|
287 | dispatch('updateEditorHook', { type, editorHook }),
|
288 | dispatch('updateInputHook', { type, inputHook })
|
289 | );
|
290 | }
|
291 | );
|
292 |
|
293 | const dependencies = {
|
294 | js: [...(config.globalPackages.js || []), ...(packages.js || [])],
|
295 | css: [...(config.globalPackages.css || []), ...(packages.css || [])]
|
296 | };
|
297 |
|
298 | ac.push(dispatch('updateFoldBoxes', foldBoxes || []));
|
299 | ac.push(dispatch('updateDependencies', dependencies));
|
300 | ac.push(
|
301 | dispatch(
|
302 | 'updateCurrentBox',
|
303 | Object.entries(boxes).find(([key, value]) => value.visible)[0] ||
|
304 | undefined
|
305 | )
|
306 | );
|
307 | await Promise.all(ac);
|
308 | progress.done();
|
309 | },
|
310 | setIframeStatus({ commit }, status) {
|
311 | commit('SET_IFRAME_STATUS', status);
|
312 | },
|
313 | transform({ commit }, status) {
|
314 | commit('SET_TRANSFORM', status);
|
315 | },
|
316 | clearLogs({ commit }) {
|
317 | commit('CLEAR_LOGS');
|
318 | },
|
319 | addLog({ commit }, pl) {
|
320 | commit('ADD_LOG', pl);
|
321 | }
|
322 | };
|
323 |
|
324 | const store = new Vuex.Store({
|
325 | state,
|
326 | mutations,
|
327 | actions
|
328 | });
|
329 |
|
330 | bus.$on('setBoxes', demo => {
|
331 | store.dispatch('setBoxes', demo);
|
332 | });
|
333 |
|
334 | export default store;
|