UNPKG

8.54 kBJavaScriptView Raw
1import Vue from 'vue/dist/vue.esm';
2import Vuex from 'vuex';
3import userConfig from 'manifest';
4import demoList from '.demoList.json';
5import router from '@/js/router.js';
6import bus from '@/js/eventbus.js';
7
8let config = userConfig;
9if (typeof config === 'function') {
10 config = config(process.env.NODE_ENV);
11}
12
13config = Object.assign(
14 {
15 name: 'DEMOSIFY',
16 version: 'v1',
17 homePage: 'https://github.com/betseyliu/demo-ground',
18 logo: '',
19 // 可选主题: active4d, allHallowsEve, amy, blackboard, brillianceBlack,
20 // brillianceDull, chromeDevtools, cloudsMidnight, clouds, cobalt,
21 // dawn, dreamweaver, eiffel, espressoLibre, github, idle, katzenmilch,
22 // kuroirTheme, lazy, magicwbAmiga, merbivoreSoft, merbivore, monokai,
23 // pastelsOnDark, slushAndPoppies, solarizedDark, solarizedLight,
24 // spacecadet, sunburst, textmateMacClassic, tomorrowNightBlue,
25 // tomorrowNightBright, tomorrowNightEighties, tomorrowNight, tomorrow,
26 // twilight, vibrantInk, zenburnesque, iplastic, idlefingers, krtheme,
27 // monoindustrial,
28 boxTheme: 'monokai',
29 globalPackages: {
30 js: [],
31 css: []
32 },
33 // tab waterfall
34 editorViewMode: 'tab'
35 },
36 config
37);
38
39import progress from 'nprogress';
40progress.configure({
41 showSpinner: false
42});
43
44Vue.use(Vuex);
45
46const demoBoxes = {};
47
48function 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}
56importAllDemo(require.context('demos', true, /config.js$/));
57
58const 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
69const 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
87if (state.inIframe) {
88 state.isSidebarShown = false;
89}
90
91const 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
165const 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
324const store = new Vuex.Store({
325 state,
326 mutations,
327 actions
328});
329
330bus.$on('setBoxes', demo => {
331 store.dispatch('setBoxes', demo);
332});
333
334export default store;