Commit 6456ad0f authored by rockyl's avatar rockyl

提交一下

parent 39f9e6a6
...@@ -62,7 +62,11 @@ function execute(document) { ...@@ -62,7 +62,11 @@ function execute(document) {
} }
return 1; return 1;
} else if (layer.name.match(excludeFlagReg)) { } else if (layer.name.match(excludeFlagReg)) {
try {
layer.remove(); layer.remove();
}catch (e) {
alert('移除图层' + layer.name + '失败,可能含有锁的层');
}
return 2; return 2;
} }
return 0; return 0;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"upload": "cp dist/index.html ../duiba-aurora-node/src/public/index.html&&ali-oss-publish -c oss.config.js -e dist", "upload": "node scripts/copy-index.js && ali-oss-publish -c oss.config.js -e dist",
"build:upload": "npm run build&&npm run upload", "build:upload": "npm run build&&npm run upload",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'" "i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
}, },
...@@ -13,10 +13,12 @@ ...@@ -13,10 +13,12 @@
"copy-to-clipboard": "^3.2.0", "copy-to-clipboard": "^3.2.0",
"core-js": "^2.6.5", "core-js": "^2.6.5",
"element-ui": "^2.4.5", "element-ui": "^2.4.5",
"indexdbwrapper": "^1.0.4",
"jszip": "^3.2.2", "jszip": "^3.2.2",
"moment": "^2.24.0", "moment": "^2.24.0",
"path": "^0.12.7", "path": "^0.12.7",
"querystringify": "^2.1.1", "querystringify": "^2.1.1",
"socket.io-client": "^2.3.0",
"splitpanes": "^1.14.5", "splitpanes": "^1.14.5",
"string-width": "^4.1.0", "string-width": "^4.1.0",
"uuid": "^3.3.3", "uuid": "^3.3.3",
...@@ -24,7 +26,8 @@ ...@@ -24,7 +26,8 @@
"vue-codemirror": "^4.0.6", "vue-codemirror": "^4.0.6",
"vue-i18n": "^8.0.0", "vue-i18n": "^8.0.0",
"vue-router": "^3.0.3", "vue-router": "^3.0.3",
"vuex": "^3.0.1" "vuex": "^3.0.1",
"zeroing-code-divider": "http://gitlab2.dui88.com/laoqifeng/zeroing-code-divider.git"
}, },
"devDependencies": { "devDependencies": {
"@kazupon/vue-i18n-loader": "^0.3.0", "@kazupon/vue-i18n-loader": "^0.3.0",
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>烽火台</title> <title>烽火台</title>
<script src="https://cdn.bootcss.com/jshint/2.10.2/jshint.min.js"></script>
<script src="https://cdn.bootcss.com/jsonlint/1.6.0/jsonlint.min.js"></script>
</head> </head>
<body> <body>
<noscript> <noscript>
......
/**
* Created by rockyl on 2019-12-26.
*/
const fs = require('fs');
fs.copyFileSync('dist/index.html', '../duiba-aurora-node/src/public/index.html');
const now = Date.now();
fs.copyFileSync('dist/index.html', `dist/index.${now}.html`);
console.log('node update-editor.js', now);
/**
* Created by rockyl on 2019-12-25.
*/
import io from 'socket.io-client';
import events from './global-events';
let socket;
export let codeSyncServeEnabled = false;
export function startCodeSyncServe(config) {
if (socket) {
socket.close();
}
socket = io(`http://${config.ip}:${config.port}`);
socket.on('connect', onConnect);
socket.on('disconnect', onDisconnect);
socket.on('edit-save', onEditSave);
events.$on('edit-open', editCode);
}
export function stop() {
}
export function editCode(code) {
socket.emit('edit-open', code);
}
function onConnect() {
codeSyncServeEnabled = true;
events.$emit('code-sync-start');
}
function onDisconnect() {
socket = null;
codeSyncServeEnabled = false;
events.$emit('code-sync-stop');
}
function onEditSave(data) {
events.$emit('edit-save', data)
}
<template>
<div style="width: 100%; height: 100%" ref="container"></div>
</template>
<script>
import * as monaco from 'monaco-editor';
export default {
name: "MonacoEditor",
data() {
return {
}
},
props: {
value: {
type: String,
default: '',
},
language: {
type: String,
default: 'javascript',
},
theme: {
type: String,
default: 'vs',
},
editorOptions: {
type: Object,
default: function(){
return {
selectOnLineNumbers: true,
roundedSelection: false,
readOnly: false, // 只读
cursorStyle: 'line', //光标样式
automaticLayout: false, //自动布局
glyphMargin: true, //字形边缘
useTabStops: false,
fontSize: 28, //字体大小
autoIndent:true,//自动布局
}
},
},
},
mounted() {
this.initEditor();
},
watch: {
value(value){
if(this.editor && value !== this.editor.getValue()){
this.editor.setValue(value);
}
}
},
methods: {
initEditor() {
this.editor = monaco.editor.create(this.$refs.container, {
value: this.value,
language: this.language,
theme: this.theme,
lineNumbers: 'on',
tabSize: 2,
insertSpaces: false,
editorOptions: this.editorOptions,
});
this.editor.onDidChangeModelContent(event => {
const value = this.editor.getValue();
this.$emit('input', value);
});
this.editor.updateOptions({
})
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
...@@ -30,7 +30,6 @@ export default { ...@@ -30,7 +30,6 @@ export default {
methods: { methods: {
drop(e) { drop(e) {
if (this.$store.state.project.dragUUID) { if (this.$store.state.project.dragUUID) {
// debugger;
console.log('native drop', this.$store.state); console.log('native drop', this.$store.state);
this.swvalue = `asset://${this.$store.state.project.dragUUID}` this.swvalue = `asset://${this.$store.state.project.dragUUID}`
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"Add": "Add", "Add": "Add",
"Delete": "Delete", "Delete": "Delete",
"Delete all": "Delete all", "Delete all": "Delete all",
"Not delete": "Not delete",
"Import": "Import", "Import": "Import",
"Export": "Export", "Export": "Export",
"Importing project": "Importing project", "Importing project": "Importing project",
...@@ -28,13 +29,20 @@ ...@@ -28,13 +29,20 @@
"EditEnv": "EditEnv", "EditEnv": "EditEnv",
"EditCustomModule": "EditCustomModule", "EditCustomModule": "EditCustomModule",
"Script": "Script", "Script": "Script",
"CodeSyncServe": "CodeSyncServe",
"ID": "ID", "ID": "ID",
"Mock Editor": "Mock Editor",
"Enable mock serve": "Enable mock serve",
"Name": "Name", "Name": "Name",
"Alias": "Alias", "Alias": "Alias",
"Output": "Output", "Output": "Output",
"Code": "Code", "Code": "Code",
"Desc": "Desc", "Desc": "Desc",
"Empty": "Empty", "Empty": "Empty",
"Path": "Path",
"Timeout": "Timeout",
"SuccessRatio": "SuccessRatio",
"Data": "Data",
"Key": "Key", "Key": "Key",
"Default": "Default", "Default": "Default",
"Event": "Event", "Event": "Event",
...@@ -147,9 +155,9 @@ ...@@ -147,9 +155,9 @@
"menu": { "menu": {
"save": "Save", "save": "Save",
"details": "Details", "details": "Details",
"preview": "Preview", "preview-fast": "Preview",
"preview2": "Fast-Preview",
"publish": "Publish", "publish": "Publish",
"mock": "Mock",
"exit": "Exit", "exit": "Exit",
"undo": "Undo", "undo": "Undo",
"redo": "Redo" "redo": "Redo"
...@@ -159,7 +167,8 @@ ...@@ -159,7 +167,8 @@
"image": "Image", "image": "Image",
"label": "Label", "label": "Label",
"rect": "Rect", "rect": "Rect",
"scrollView": "ScrollView" "scrollView": "ScrollView",
"svga": "SVGA"
}, },
"panes": { "panes": {
"Assets": "Assets", "Assets": "Assets",
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"Add": "添加", "Add": "添加",
"Delete": "删除", "Delete": "删除",
"Delete all": "删除全部", "Delete all": "删除全部",
"Not delete": "不删除",
"Import": "导入", "Import": "导入",
"Export": "导出", "Export": "导出",
"Importing project": "项目导入中", "Importing project": "项目导入中",
...@@ -28,13 +29,20 @@ ...@@ -28,13 +29,20 @@
"EditEnv": "编辑环境", "EditEnv": "编辑环境",
"EditCustomModule": "编辑自定义模块", "EditCustomModule": "编辑自定义模块",
"Script": "脚本", "Script": "脚本",
"CodeSyncServe": "代码同步服务",
"ID": "ID", "ID": "ID",
"Mock Editor": "Mock编辑器",
"Enable mock serve": "启用Mock服务",
"Name": "名字", "Name": "名字",
"Alias": "别名", "Alias": "别名",
"Output": "输出", "Output": "输出",
"Code": "代码", "Code": "代码",
"Desc": "描述", "Desc": "描述",
"Empty": "空", "Empty": "空",
"Path": "路径",
"Timeout": "超时(ms)",
"SuccessRatio": "成功率",
"Data": "数据",
"Key": "属性名", "Key": "属性名",
"Default": "默认值", "Default": "默认值",
"Event": "事件", "Event": "事件",
...@@ -151,9 +159,9 @@ ...@@ -151,9 +159,9 @@
"menu": { "menu": {
"save": "保存", "save": "保存",
"details": "详情", "details": "详情",
"preview": "预览", "preview-fast": "预览",
"preview2": "快速预览",
"publish": "发布", "publish": "发布",
"mock": "Mock",
"exit": "退出", "exit": "退出",
"undo": "撤销", "undo": "撤销",
"redo": "重做" "redo": "重做"
...@@ -165,7 +173,8 @@ ...@@ -165,7 +173,8 @@
"rect": "矩形", "rect": "矩形",
"circle": "圆形", "circle": "圆形",
"textinput": "输入框", "textinput": "输入框",
"scrollView": "滚动视图" "scrollView": "滚动视图",
"svga": "SVGA"
}, },
"panes": { "panes": {
"Assets": "素材", "Assets": "素材",
......
...@@ -39,15 +39,10 @@ export default new Vuex.Store({ ...@@ -39,15 +39,10 @@ export default new Vuex.Store({
'modifyAsset', 'modifyAsset',
'importView', 'importView',
'importAssets', 'importAssets',
'addDataMapping',
'deleteDataMapping',
'modifyDataMapping',
'addEnvMapping',
'deleteEnvMapping',
'modifyEnvMapping',
'modifyActiveView', 'modifyActiveView',
'behavior_save', 'behavior_save',
'modifyCustoms', 'modifyProjectDetails',
'modifyMocks',
] ]
}) })
] ]
......
...@@ -64,7 +64,6 @@ export const behaviorStore = { ...@@ -64,7 +64,6 @@ export const behaviorStore = {
state.processStack.push(process); state.processStack.push(process);
updatePropsEditable(state); updatePropsEditable(state);
state.currentProcess = process; state.currentProcess = process;
console.log(state.currentProcess);
}, },
popProcessStack(state, index) { popProcessStack(state, index) {
state.processStack.splice(index); state.processStack.splice(index);
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
import {envApi} from "../../api"; import {envApi} from "../../api";
import i18n from "../../i18n"; import i18n from "../../i18n";
const storeKey = 'code-sync-serve-config';
export const envStore = { export const envStore = {
state: { state: {
initialized: false, initialized: false,
...@@ -19,6 +21,10 @@ export const envStore = { ...@@ -19,6 +21,10 @@ export const envStore = {
processes: [], processes: [],
scripts: [], scripts: [],
customs: [], customs: [],
codeSyncServeConfig: {
ip: 'localhost',
port: 7788,
}
}, },
mutations: { mutations: {
updateEnv(state, env) { updateEnv(state, env) {
...@@ -28,6 +34,15 @@ export const envStore = { ...@@ -28,6 +34,15 @@ export const envStore = {
state.customs = parseItem(state.customs); state.customs = parseItem(state.customs);
state.initialized = true; state.initialized = true;
let configStr = localStorage.getItem(storeKey);
if (configStr) {
state.codeSyncServeConfig = JSON.parse(configStr);
}
},
saveCodeSyncServeConfig(state, config) {
state.codeSyncServeConfig = config;
localStorage.setItem(storeKey, JSON.stringify(state.codeSyncServeConfig));
}, },
}, },
getters: { getters: {
...@@ -77,7 +92,7 @@ export const envStore = { ...@@ -77,7 +92,7 @@ export const envStore = {
const env = await envApi.fetchEnv(); const env = await envApi.fetchEnv();
commit('updateEnv', env); commit('updateEnv', env);
} }
} },
} }
}; };
......
...@@ -3,17 +3,22 @@ ...@@ -3,17 +3,22 @@
*/ */
import Vue from "vue"; import Vue from "vue";
import JSZip from "jszip"; import JSZip from "jszip";
import { projectApi } from "../../api"; import {projectApi} from "../../api";
import path from "path"; import path from "path";
import generateUUID from "uuid/v4"; import generateUUID from "uuid/v4";
import { getCmpProps, flattenViews, getCmpByUUID } from '../../utils/common'; import {getCmpProps, flattenViews, getCmpByUUID} from '../../utils/common';
import { clonePureObj, saveAs } from "../../utils"; import {clonePureObj, getMockServeEnabled, saveAs} from "../../utils";
import { template } from "../../template"; import {template} from "../../template";
import { importView, uploadFile } from "../../api/project"; import {importView, uploadFile} from "../../api/project";
import events from "@/global-events"; import events from "@/global-events";
import {packImages} from "../../utils/sheet-pack"; import {packImages} from "../../utils/sheet-pack";
import {addBehavior, deleteProcessMeta, findProcess} from "./behavior"; import {addBehavior, deleteProcessMeta, findProcess} from "./behavior";
import db from "../../utils/db-storage";
import {preprocess} from "../../views/Preview/preview-preprocess";
const storeName = 'project';
const defaultOptions = { const defaultOptions = {
pageTitle: 'no title', pageTitle: 'no title',
entrySceneView: '', entrySceneView: '',
...@@ -25,8 +30,8 @@ const defaultOptions = { ...@@ -25,8 +30,8 @@ const defaultOptions = {
rendererType: 'webgl', rendererType: 'webgl',
tpl: template, tpl: template,
env: [ env: [
{ name: 'appID', value: '' }, {name: 'appID', value: ''},
{ name: 'projectID', value: '' }, {name: 'projectID', value: ''},
], ],
}; };
...@@ -36,33 +41,33 @@ function getDefaultOptions() { ...@@ -36,33 +41,33 @@ function getDefaultOptions() {
return clonePureObj(defaultOptions); return clonePureObj(defaultOptions);
} }
function setUUIDForAllChildren(node){ function setUUIDForAllChildren(node) {
if(node.children&&node.children.length>0){ if (node.children && node.children.length > 0) {
for(let i=0 ;i<node.children.length;i++){ for (let i = 0; i < node.children.length; i++) {
node.children[i]=copyBaseRoot(node.children[i]) node.children[i] = copyBaseRoot(node.children[i])
setUUIDForAllChildren(node.children[i]) setUUIDForAllChildren(node.children[i])
} }
} }
} }
let copyNodeCatch=null; let copyNodeCatch = null;
function copyBaseRoot(node){ function copyBaseRoot(node) {
let _node=JSON.parse(JSON.stringify(node)); let _node = JSON.parse(JSON.stringify(node));
let data let data;
if(_node.children&&_node.children.length>0){ if (_node.children && _node.children.length > 0) {
data={ data = {
name: _node.name, name: _node.name,
type: _node.type, type: _node.type,
properties: _node.properties, properties: _node.properties,
events: _node.events, events: _node.events,
uuid: generateUUID(), uuid: generateUUID(),
children:_node.children children: _node.children
}; };
}else{ } else {
data={ data = {
name: _node.name, name: _node.name,
type: _node.type, type: _node.type,
properties: _node.properties, properties: _node.properties,
...@@ -85,7 +90,9 @@ export const projectStore = { ...@@ -85,7 +90,9 @@ export const projectStore = {
dataMapping: [], dataMapping: [],
processes: [], processes: [],
customs: [], customs: [],
mock: [],
}, },
mockServeEnabled: false,
activeComponent: {}, activeComponent: {},
activeComponentCopy: {}, // 当前选中节点的镜像,用来处理拖拽时数据变化频繁的问题 activeComponentCopy: {}, // 当前选中节点的镜像,用来处理拖拽时数据变化频繁的问题
activeIdList: [], activeIdList: [],
...@@ -100,14 +107,14 @@ export const projectStore = { ...@@ -100,14 +107,14 @@ export const projectStore = {
state.dirty = dirty; state.dirty = dirty;
}, },
updateProject(state, project) { updateProject(state, project) {
const { id, name, creator, data } = project; const {id, name, creator, data} = project;
state.id = id; state.id = id;
state.name = name; state.name = name;
state.creator = creator; state.creator = creator;
const localData = state.data; const localData = state.data;
if (data) { if (data) {
const { views, assets, dataMapping, processes, options, customs, } = JSON.parse(data); const {views, assets, dataMapping, processes, options, customs, mock} = JSON.parse(data);
Vue.set(localData, 'options', options || getDefaultOptions()); Vue.set(localData, 'options', options || getDefaultOptions());
Vue.set(localData, 'views', views || []); Vue.set(localData, 'views', views || []);
...@@ -115,6 +122,7 @@ export const projectStore = { ...@@ -115,6 +122,7 @@ export const projectStore = {
Vue.set(localData, 'dataMapping', dataMapping || []); Vue.set(localData, 'dataMapping', dataMapping || []);
Vue.set(localData, 'processes', processes || []); Vue.set(localData, 'processes', processes || []);
Vue.set(localData, 'customs', customs || []); Vue.set(localData, 'customs', customs || []);
Vue.set(localData, 'mock', mock || []);
} else { } else {
Vue.set(localData, 'options', getDefaultOptions()); Vue.set(localData, 'options', getDefaultOptions());
Vue.set(localData, 'views', []); Vue.set(localData, 'views', []);
...@@ -122,7 +130,26 @@ export const projectStore = { ...@@ -122,7 +130,26 @@ export const projectStore = {
Vue.set(localData, 'dataMapping', []); Vue.set(localData, 'dataMapping', []);
Vue.set(localData, 'processes', []); Vue.set(localData, 'processes', []);
Vue.set(localData, 'customs', []); Vue.set(localData, 'customs', []);
Vue.set(localData, 'mock', []);
} }
state.mockServeEnabled = getMockServeEnabled(id);
updateMock(localData.mock);
},
modifyOptions(state, value){
state.data.options = value;
},
modifyEnv(state, value){
state.data.options.env = value;
},
modifyDataMapping(state, value){
state.data.dataMapping = value;
},
modifyCustoms(state, value) {
state.data.customs = value;
},
modifyProjectDetails(state) {
}, },
/** /**
* 激活组件 * 激活组件
...@@ -294,7 +321,7 @@ export const projectStore = { ...@@ -294,7 +321,7 @@ export const projectStore = {
modifyProject(state) { modifyProject(state) {
}, },
addNode(state, { node, name, type }) { addNode(state, {node, name, type}) {
const child = { const child = {
name, name,
type, type,
...@@ -314,16 +341,16 @@ export const projectStore = { ...@@ -314,16 +341,16 @@ export const projectStore = {
importView(state, view) { importView(state, view) {
state.data.views.push(view); state.data.views.push(view);
}, },
deleteNode(state, { node, parentNode }) { deleteNode(state, {node, parentNode}) {
const parentChildren = parentNode.children || parentNode; const parentChildren = parentNode.children || parentNode;
const index = parentChildren.indexOf(node); const index = parentChildren.indexOf(node);
parentChildren.splice(index, 1); parentChildren.splice(index, 1);
}, },
copyNode(state, { node, parentNode }) { copyNode(state, {node, parentNode}) {
let _node1=node let _node1 = node
copyNodeCatch=_node1; copyNodeCatch = _node1;
//localStorage.copyNodeCatch=_node1; //localStorage.copyNodeCatch=_node1;
// let _node=copyBaseRoot(_node1); // let _node=copyBaseRoot(_node1);
// setUUIDForAllChildren(_node) // setUUIDForAllChildren(_node)
...@@ -336,16 +363,16 @@ export const projectStore = { ...@@ -336,16 +363,16 @@ export const projectStore = {
// state.data.views.push(_node); // state.data.views.push(_node);
// } // }
}, },
pasteNode(state, { node, parentNode,pasteState}) { pasteNode(state, {node, parentNode, pasteState}) {
let _node1=copyNodeCatch; let _node1 = copyNodeCatch;
console.log(copyNodeCatch) console.log(copyNodeCatch)
if(_node1){ if (_node1) {
let _node=copyBaseRoot(_node1); let _node = copyBaseRoot(_node1);
setUUIDForAllChildren(_node) setUUIDForAllChildren(_node)
if(pasteState==1){ if (pasteState == 1) {
parentNode=parentNode; parentNode = parentNode;
}else{ } else {
parentNode=node; parentNode = node;
} }
if (parentNode) { if (parentNode) {
if (!parentNode.children) { if (!parentNode.children) {
...@@ -355,14 +382,14 @@ export const projectStore = { ...@@ -355,14 +382,14 @@ export const projectStore = {
} else { } else {
state.data.views.push(_node); state.data.views.push(_node);
} }
}else{ } else {
console.warn("请先选择一个节点进行复制") console.warn("请先选择一个节点进行复制")
} }
}, },
importAssets(state, assets) { importAssets(state, assets) {
state.data.assets.push(...assets); state.data.assets.push(...assets);
}, },
addAsset(state, { url, file }) { addAsset(state, {url, file}) {
const ext = path.extname(file.name); const ext = path.extname(file.name);
state.data.assets.push({ state.data.assets.push({
name: path.basename(file.name, ext), name: path.basename(file.name, ext),
...@@ -379,7 +406,7 @@ export const projectStore = { ...@@ -379,7 +406,7 @@ export const projectStore = {
} }
}, },
deleteAsset(state, uuid) { deleteAsset(state, uuid) {
const { assets } = state.data; const {assets} = state.data;
for (let i = 0, li = assets.length; i < li; i++) { for (let i = 0, li = assets.length; i < li; i++) {
const asset = state.data.assets[i]; const asset = state.data.assets[i];
if (asset.uuid === uuid) { if (asset.uuid === uuid) {
...@@ -389,61 +416,26 @@ export const projectStore = { ...@@ -389,61 +416,26 @@ export const projectStore = {
} }
}, },
deleteAllAssets(state) { deleteAllAssets(state) {
const { assets } = state.data; const {assets} = state.data;
assets.splice(0); assets.splice(0);
}, },
modifyAsset(state, asset) { modifyAsset(state, asset) {
}, },
addDataMapping(state, link) { modifyMocks(state, mocks) {
if (link) { state.data.mock = mocks;
state.data.dataMapping.push(link);
} else {
state.data.dataMapping.push({
name: '',
path: '',
});
}
},
deleteDataMapping(state, index) {
state.data.dataMapping.splice(index, 1);
},
modifyDataMapping(state) {
updateMock(mocks);
}, },
addEnvMapping(state, link) { setMockServeEnabled(state, enabled){
if (!state.data.options.env) { state.mockServeEnabled = enabled;
Vue.set(state.data.options, 'env', []);
} }
if (link) {
state.data.options.env.push(link);
} else {
state.data.options.env.push({
name: '',
value: '',
});
}
},
deleteEnvMapping(state, index) {
state.data.options.env.splice(index, 1);
},
modifyEnvMapping(state) {
},
modifyCustoms(state, customs) {
state.data.customs = customs;
},
}, },
getters: { getters: {
project(state) { project(state) {
const { id, name, creator, data } = state; const {id, name, creator, data} = state;
return { return {
id, name, creator, id, name, creator,
data: JSON.stringify(data), data: JSON.stringify(data),
...@@ -514,29 +506,33 @@ export const projectStore = { ...@@ -514,29 +506,33 @@ export const projectStore = {
}, },
}, },
actions: { actions: {
saveToLocal({ getters, commit }) { async saveToLocal({getters, commit}) {
const { project } = getters; const {project} = getters;
localStorage.setItem('project-' + project.id, JSON.stringify(project)); await db.set(storeName, {id: project.id, data: JSON.stringify(project)});
//localStorage.setItem('project-' + project.id, JSON.stringify(project));
commit('setDirty', true); commit('setDirty', true);
}, },
localVersionExist({ commit }, projectID) { async localVersionExist({commit}, projectID) {
let json = localStorage.getItem('project-' + projectID); let json = await db.get(storeName, projectID);
//let json = localStorage.getItem('project-' + projectID);
return !!json; return !!json;
}, },
loadFromLocal({ commit }, projectID) { async loadFromLocal({commit}, projectID) {
let json = localStorage.getItem('project-' + projectID); let json = await db.get(storeName, projectID);
//let json = localStorage.getItem('project-' + projectID);
if (json) { if (json) {
const project = JSON.parse(json); const project = JSON.parse(json.data);
commit('updateProject', project); commit('updateProject', project);
commit('setDirty', true); commit('setDirty', true);
} }
}, },
deleteLocalVersion({ state, commit }, projectID) { async deleteLocalVersion({state, commit}, projectID) {
localStorage.removeItem('project-' + projectID); await db.remove(storeName, projectID);
//localStorage.removeItem('project-' + projectID);
commit('setDirty', false); commit('setDirty', false);
}, },
async loadFromRemote({ commit, dispatch }, projectID) { async loadFromRemote({commit, dispatch}, projectID) {
const project = await projectApi.fetchOne(projectID); const project = await projectApi.fetchOne(projectID);
if (project) { if (project) {
dispatch('deleteLocalVersion', projectID); dispatch('deleteLocalVersion', projectID);
...@@ -545,11 +541,11 @@ export const projectStore = { ...@@ -545,11 +541,11 @@ export const projectStore = {
throw new Error('Project does not exist') throw new Error('Project does not exist')
} }
}, },
async saveToRemote({ state, dispatch, getters }) { async saveToRemote({state, dispatch, getters}) {
await projectApi.saveOne(getters.project); await projectApi.saveOne(getters.project);
dispatch('deleteLocalVersion', state.id); dispatch('deleteLocalVersion', state.id);
}, },
async updateProject({ commit }, projectID) { async updateProject({commit}, projectID) {
const project = await projectApi.getData(projectID); const project = await projectApi.getData(projectID);
commit('updateProject', project); commit('updateProject', project);
}, },
...@@ -581,7 +577,7 @@ export const projectStore = { ...@@ -581,7 +577,7 @@ export const projectStore = {
/** /**
* 修改属性 * 修改属性
*/ */
modifyProperties({ commit, state, getters }, props) { modifyProperties({commit, state, getters}, props) {
// debugger; // debugger;
// 如果当前修改的是“来源”属性,节点又没有高度宽度,则取图片的高度宽度 // 如果当前修改的是“来源”属性,节点又没有高度宽度,则取图片的高度宽度
let _props = _.cloneDeep(state.activeComponent.properties); let _props = _.cloneDeep(state.activeComponent.properties);
...@@ -609,6 +605,9 @@ export const projectStore = { ...@@ -609,6 +605,9 @@ export const projectStore = {
}); });
} }
} }
} else {
delete _props.imageWidth;
delete _props.imageHeight;
} }
commit('modifyActiveView', { commit('modifyActiveView', {
...@@ -620,13 +619,13 @@ export const projectStore = { ...@@ -620,13 +619,13 @@ export const projectStore = {
* @param {*} param0 * @param {*} param0
* @param {*} props * @param {*} props
*/ */
modifyCopyProperties({ commit }, props) { modifyCopyProperties({commit}, props) {
commit('modifyCopyProperties', props) commit('modifyCopyProperties', props)
}, },
/** /**
* 修改当前选中的节点 * 修改当前选中的节点
*/ */
modifyActiveView({ commit }, view) { modifyActiveView({commit}, view) {
commit('modifyActiveView', view) commit('modifyActiveView', view)
}, },
/** /**
...@@ -634,7 +633,7 @@ export const projectStore = { ...@@ -634,7 +633,7 @@ export const projectStore = {
* @param {*} param0 * @param {*} param0
* @param {*} script * @param {*} script
*/ */
addNodeScript({ commit, state }, script) { addNodeScript({commit, state}, script) {
let _scripts = _.cloneDeep(state.activeComponent.scripts || []); let _scripts = _.cloneDeep(state.activeComponent.scripts || []);
_scripts.push({ _scripts.push({
script: script, script: script,
...@@ -644,8 +643,8 @@ export const projectStore = { ...@@ -644,8 +643,8 @@ export const projectStore = {
scripts: _scripts scripts: _scripts
}) })
}, },
async importView({ commit }, { file, action }) { async importView({commit}, {file, action}) {
const { view, assets } = await importView(file); const {view, assets} = await importView(file);
switch (action) { switch (action) {
case 0: //单视图 case 0: //单视图
view.name = file.name.substring(0, file.name.lastIndexOf('.')); view.name = file.name.substring(0, file.name.lastIndexOf('.'));
...@@ -659,18 +658,18 @@ export const projectStore = { ...@@ -659,18 +658,18 @@ export const projectStore = {
} }
commit('importAssets', assets); commit('importAssets', assets);
}, },
exportView({ state }, view) { exportView({state}, view) {
let zip = new JSZip(); let zip = new JSZip();
zip.file('view.json', JSON.stringify(view)); zip.file('view.json', JSON.stringify(view));
zip.generateAsync({ type: "blob" }).then(function (content) { zip.generateAsync({type: "blob"}).then(function (content) {
saveAs(content, `view-${view.name}.zrv`); saveAs(content, `view-${view.name}.zrv`);
}); });
}, },
async uploadFiles({commit}, files) { async uploadFiles({commit}, files) {
const {failedList, result} = await uploadFiles(files); const {failedList, result} = await uploadFiles(files);
for (let item of result) { for (let item of result) {
const { url, __originFile } = item; const {url, __originFile} = item;
commit('addAsset', { url, file: __originFile }); commit('addAsset', {url, file: __originFile});
} }
return failedList; return failedList;
}, },
...@@ -692,12 +691,14 @@ export const projectStore = { ...@@ -692,12 +691,14 @@ export const projectStore = {
const {project} = getters; const {project} = getters;
const {processes, scripts, customs} = rootState.env; const {processes, scripts, customs} = rootState.env;
const data = { /*const data = {
processes, scripts, customs, processes, scripts, customs,
data: state.data, data: state.data,
}; };
localStorage.setItem('preview-project-' + project.id, JSON.stringify(data)); localStorage.setItem('preview-project-' + project.id, JSON.stringify(data));
localStorage.setItem('preview-ts', Date.now().toString()); localStorage.setItem('preview-ts', Date.now().toString());*/
preprocess(project, state.data, clonePureObj(processes), clonePureObj(scripts), clonePureObj(customs))
}, },
addBehaviorDirect({state}, {behaviors, alias}) { addBehaviorDirect({state}, {behaviors, alias}) {
...@@ -707,10 +708,15 @@ export const projectStore = { ...@@ -707,10 +708,15 @@ export const projectStore = {
deleteBehaviorDirect({state}, {behaviors, index, deleteMeta}) { deleteBehaviorDirect({state}, {behaviors, index, deleteMeta}) {
let behavior = behaviors.splice(index, 1)[0]; let behavior = behaviors.splice(index, 1)[0];
if(deleteMeta){ if (deleteMeta) {
deleteProcessMeta(behavior.meta, state.data.processes); deleteProcessMeta(behavior.meta, state.data.processes);
} }
}, },
setMockServeEnabled({state, commit}, enabled) {
localStorage.setItem('mock-enabled-' + state.id, JSON.stringify(enabled));
commit('setMockServeEnabled', enabled);
return enabled;
}
}, },
}; };
...@@ -766,3 +772,10 @@ async function packAssets(assets) { ...@@ -766,3 +772,10 @@ async function packAssets(assets) {
return newAssets; return newAssets;
} }
export async function updateMock(mocks) {
await db.clear('mock');
for (let mock of mocks) {
db.set('mock', mock);
}
}
...@@ -16,14 +16,16 @@ export const projectsStore = { ...@@ -16,14 +16,16 @@ export const projectsStore = {
state.projectCount = projectCount; state.projectCount = projectCount;
}, },
addProject(state, project) { addProject(state, project) {
state.unshift(project); state.projects.unshift(project);
}, },
deleteProject(state, projectID) { deleteProject(state, projectID) {
for (let i = 0, li = state.length; i < li; i++) { const {projects} = state;
const item = state[i];
for (let i = 0, li = projects.length; i < li; i++) {
const item = projects[i];
if (item.id === projectID) { if (item.id === projectID) {
state.splice(i, 1); projects.splice(i, 1);
break; break;
} }
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
*/ */
export const template = export const template =
`<!DOCTYPE html> `<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
...@@ -28,13 +28,13 @@ content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, u ...@@ -28,13 +28,13 @@ content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, u
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
background-color: white; background-color: white;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="$CONTAINER_ID$" style="line-height:0;font-size:0"></div> <div id="$CONTAINER_ID$" style="line-height:0;font-size:0"></div>
<script src="${process.env.NODE_ENV === 'development' ? 'http://10.10.94.134:4002/dist/index.js' : 'http://yun.duiba.com.cn/editor/zeroing/libs/engine.d20665eae76962ad21c153fe7a719130b08e292c.js'}"></script> <script src="${process.env.NODE_ENV === 'development' ? 'http://10.10.92.100:4002/debug/engine.js' : 'http://yun.duiba.com.cn/editor/zeroing/libs/engine.269ce0ee2f951a11e004eee2df2fa1d875fa0b62.js'}"></script>
$SCRIPTS$ $SCRIPTS$
<script> <script>
engine.launch('//yun.duiba.com.cn/aurora/$VERSION$-data.json'); engine.launch('//yun.duiba.com.cn/aurora/$VERSION$-data.json');
......
...@@ -2,16 +2,7 @@ ...@@ -2,16 +2,7 @@
$dock-pin-width: 9px; $dock-pin-width: 9px;
.behavior-editor-dialog { .behavior-editor-dialog {
display: flex;
flex-direction: column;
.el-dialog__body {
flex: 1;
height: 0;
padding: 5px;
}
.process-pane { .process-pane {
......
@import "var";
.code-sync-indicator {
padding: 5px;
cursor: pointer;
.indicator {
background-color: red;
width: 10px;
height: 10px;
border-radius: 50%;
}
.indicator.enabled {
background-color: limegreen;
}
}
.bottom-bar{
height: 20px;
display: flex;
align-items: center;
font-size: 12px;
color: $--color-text-secondary;
padding: 0 5px;
.editor-status{
}
.file-upload-indicator {
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
@import "views"; @import "views";
@import "assets"; @import "assets";
@import "behavior"; @import "behavior";
@import "bottom-bar";
.editor { .editor {
display: flex; display: flex;
...@@ -25,10 +26,6 @@ ...@@ -25,10 +26,6 @@
} }
} }
.file-upload-indicator{
color: $--color-text-secondary;
}
.right-part { .right-part {
color: $--color-text-regular; color: $--color-text-regular;
line-height: 15px; line-height: 15px;
...@@ -57,11 +54,11 @@ ...@@ -57,11 +54,11 @@
align-self: flex-start; align-self: flex-start;
} }
.bottom-bar{ .bottom-bar {
align-self: flex-end; align-self: flex-end;
} }
.list{ .list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
...@@ -101,28 +98,76 @@ ...@@ -101,28 +98,76 @@
} }
.details-dialog { .details-dialog {
.operate-bar{ .operate-bar {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
padding: 5px; padding: 5px;
} }
.tabs {
height: 100%;
display: flex;
flex-direction: column;
.el-tabs__content {
flex: 1;
& > div {
height: 100%;
}
}
}
.project-editor {
height: 100%;
display: flex;
flex-direction: column;
.project-scrollbar {
flex: 1;
}
}
.scrollbar { .scrollbar {
height: 40vh; height: 100%;
.view { .view {
padding-right: 10px; padding-right: 10px;
.custom-module-list{ .custom-module-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.item + .item { .item + .item {
margin-top: 5px; margin-top: 5px;
} }
} }
} }
} }
.full-scrollbar{ }
height: 68vh;
.mock-editor-dialog {
.mock-editor-view {
height: 100%;
display: flex;
flex-direction: column;
.enabled-switch {
align-self: flex-end;
}
.add-button {
align-self: flex-start;
}
.mock-table {
flex: 1;
}
}
.dialog-footer {
display: flex;
justify-content: space-between;
} }
} }
/** /**
* Created by rockyl on 2019-09-18. * Created by rockyl on 2019-09-18.
*/ */
@import "./var.scss"; @import "./var.scss";
@import "./base.scss"; @import "./base.scss";
@import "./home.scss"; @import "./home.scss";
@import "./editor.scss"; @import "./editor.scss";
@import "./playground.scss"; @import "./playground.scss";
@import "./inspector.scss"; @import "./inspector.scss";
@import "~element-ui/packages/theme-chalk/src/index.scss"; @import "~element-ui/packages/theme-chalk/src/index.scss";
.flex-dialog {
display: flex;
flex-direction: column;
.el-dialog__body {
flex: 1;
height: 0;
padding: 5px;
}
}
.el-tree { .el-tree {
background: transparent; background: transparent;
} }
...@@ -23,15 +32,18 @@ ...@@ -23,15 +32,18 @@
overflow-y: hidden; overflow-y: hidden;
} }
.el-tree-node__content > .el-tree-node__expand-icon{ .el-tree-node__content > .el-tree-node__expand-icon {
padding: 6px 0; padding: 6px 0;
} }
.el-input-number.is-without-controls .el-input__inner{
padding: 0 5px;
}
.el-input__inner { .el-input__inner {
padding: 0 5px; padding: 0 5px;
} }
.el-input--suffix .el-input__inner{ .el-input--suffix .el-input__inner {
padding-right: 5px; padding-right: 5px;
} }
...@@ -43,13 +55,13 @@ ...@@ -43,13 +55,13 @@
height: 100%; height: 100%;
} }
.el-tabs--border-card > .el-tabs__content{ .el-tabs--border-card > .el-tabs__content {
padding: 5px 0 5px 5px; padding: 5px 0 5px 5px;
} }
.el-input-number.is-controls-right .el-input__inner { .el-input-number.is-controls-right .el-input__inner {
padding-left: 5px; padding-left: 5px;
padding-right: 40px; padding-right: 25px;
} }
.el-input-number--mini .el-input-number__increase, .el-input-number--mini .el-input-number__decrease { .el-input-number--mini .el-input-number__increase, .el-input-number--mini .el-input-number__decrease {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
.el-collapse-item__header{ .el-collapse-item__header{
height: 25px; height: 25px;
line-height: 25px;
} }
.el-tabs__item { .el-tabs__item {
...@@ -67,7 +68,7 @@ ...@@ -67,7 +68,7 @@
} }
.el-button + .el-button { .el-button + .el-button {
margin-left: 2px; margin-left: 5px;
} }
.trigger-list{ .trigger-list{
......
...@@ -30,6 +30,10 @@ export const componentsMap = [ ...@@ -30,6 +30,10 @@ export const componentsMap = [
label: '滚动视图', label: '滚动视图',
value: 'scrollView' value: 'scrollView'
}, },
{
label: 'SVGA',
value: 'svga'
},
]; ];
// 属性的计算方法 // 属性的计算方法
......
/**
* Created by rockyl on 2019-12-18.
*/
const version = 3;
const storeConfigs = [
{name: 'project', key: 'id'},
{name: 'mock', key: 'path'},
{name: 'preview', key: 'id'},
];
export default {
open(databaseName = 'store') {
return new Promise((resolve, reject) => {
let request = window.indexedDB.open(databaseName, version);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = (event) => {
this.db = event.target.result;
resolve(request.result);
};
request.onupgradeneeded = (event) => {
this.db = event.target.result;
this.createStore(storeConfigs);
}
})
},
createStore(stores) {
for (let {name, key} of stores) {
if (!this.db.objectStoreNames.contains(name)) {
this.db.createObjectStore(name, {keyPath: key || 'id'});
}
}
},
get(storeName, id) {
return new Promise((resolve, reject) => {
let request = this.db.transaction([storeName])
.objectStore(storeName)
.get(id);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
resolve(request.result);
};
})
},
getAll(storeName) {
return new Promise((resolve, reject) => {
let request = this.db.transaction([storeName])
.objectStore(storeName)
.getAll();
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
resolve(request.result);
};
})
},
add(storeName, data) {
return new Promise((resolve, reject) => {
let request = this.db.transaction([storeName], 'readwrite')
.objectStore(storeName)
.add(data);
request.onsuccess = function (event) {
resolve();
};
request.onerror = function (event) {
reject(event.target.error);
}
});
},
put(storeName, data) {
return new Promise((resolve, reject) => {
let request = this.db.transaction([storeName], 'readwrite')
.objectStore(storeName)
.put(data);
request.onsuccess = function (event) {
resolve();
};
request.onerror = function (event) {
reject(event.target.error);
}
});
},
async set(storeName, data) {
try {
await this.add(storeName, data);
} catch (e) {
await this.put(storeName, data);
}
},
remove(storeName, id) {
return new Promise((resolve, reject) => {
let request = this.db.transaction([storeName], 'readwrite')
.objectStore(storeName)
.delete(id);
request.onsuccess = function (event) {
resolve();
};
request.onerror = function (event) {
reject(event.target.error);
}
});
},
clear(storeName){
return new Promise((resolve, reject) => {
let request = this.db.transaction([storeName], 'readwrite')
.objectStore(storeName)
.clear();
request.onsuccess = function (event) {
resolve();
};
request.onerror = function (event) {
reject(event.target.error);
}
});
},
}
\ No newline at end of file
...@@ -24,7 +24,7 @@ export function playWaiting(promise, text, closeLoading = true) { ...@@ -24,7 +24,7 @@ export function playWaiting(promise, text, closeLoading = true) {
messageError(e); messageError(e);
throw e; throw e;
}).finally(() => { }).finally(() => {
if(closeLoading){ if (closeLoading) {
loading.close(); loading.close();
} }
}) })
...@@ -59,7 +59,7 @@ export function updateProcesses(processes, targetMetaID, replaceMetaID) { ...@@ -59,7 +59,7 @@ export function updateProcesses(processes, targetMetaID, replaceMetaID) {
subProcess.meta = replaceMetaID; subProcess.meta = replaceMetaID;
} }
} }
if(process.metas){ if (process.metas) {
updateProcesses(process.metas, targetMetaID, replaceMetaID) updateProcesses(process.metas, targetMetaID, replaceMetaID)
} }
} }
...@@ -116,12 +116,39 @@ export function readTextFile(file) { ...@@ -116,12 +116,39 @@ export function readTextFile(file) {
}) })
} }
export function selectFile(callback, {accept, multiple} = {}) { function scanEntries(item){
return new Promise(resolve => {
if (item.isDirectory) {
let directoryReader = item.createReader();
directoryReader.readEntries(function(es){
resolve(es);
});
}else{
resolve();
}
})
}
export async function scanFiles(item, container) {
const entries = await scanEntries(item);
if(entries){
for(let entry of entries){
container.push(entry);
await scanFiles(entry, container);
}
}
}
export function selectFile(callback, {accept, multiple, acceptDirectory} = {}) {
let input = document.createElement('input'); let input = document.createElement('input');
input.type = 'file'; input.type = 'file';
input.onchange = function (e) { input.onchange = function (e) {
callback(input.files); callback(input.files);
}; };
if(acceptDirectory){
input.webkitdirectory = true;
}
if (accept) { if (accept) {
input.accept = accept; input.accept = accept;
} }
...@@ -131,14 +158,26 @@ export function selectFile(callback, {accept, multiple} = {}) { ...@@ -131,14 +158,26 @@ export function selectFile(callback, {accept, multiple} = {}) {
input.click(); input.click();
} }
export function openPreview(packResult){ export function openPreview(packResult) {
setTimeout(() => { setTimeout(() => {
let url; let url;
if(location.host.startsWith('localhost')){ if (location.host.startsWith('localhost')) {
url = packResult.tplUrl; url = packResult.tplUrl;
}else{ } else {
url = '/preview?url=http:' + packResult.tplUrl; url = '/preview?url=http:' + packResult.tplUrl;
} }
window.open(url, 'blank'); window.open(url, 'blank');
}, 500); }, 500);
} }
export function newScriptEl(url) {
return `<script src="${url}"></script>`
}
export function getMockServeEnabled(projectID) {
let enabled = localStorage.getItem('mock-enabled-' + projectID);
if (enabled) {
enabled = JSON.parse(enabled);
}
return !!enabled;
}
...@@ -203,6 +203,20 @@ export default { ...@@ -203,6 +203,20 @@ export default {
type: 'textArea', type: 'textArea',
value: '' value: ''
}, },
type: {
title: '输入类型',
type: 'select',
options: [
{ label: '文本', value: 'text' },
{ label: '密码', value: 'password' },
],
value: 'text'
},
pattern: {
title: '输入模式',
type: 'input',
value: ''
},
fillColor: { fillColor: {
title: '颜色', title: '颜色',
type: 'colorPicker', type: 'colorPicker',
...@@ -234,7 +248,7 @@ export default { ...@@ -234,7 +248,7 @@ export default {
}, },
}, },
image: { image: {
groupName: '来源', groupName: '图片',
source: { source: {
title: '来源', title: '来源',
type: 'source', type: 'source',
...@@ -259,6 +273,30 @@ export default { ...@@ -259,6 +273,30 @@ export default {
} }
} }
}, },
svga: {
groupName: 'SVGA',
source: {
title: '来源',
type: 'source',
value: ''
},
lockStep: {
title: '锁步',
type: 'switch',
props: {
width: 40
},
value: false
},
autoPlay: {
title: '自动播放',
type: 'switch',
props: {
width: 40
},
value: false
},
},
rect: { rect: {
groupName: '矩形', groupName: '矩形',
fillColor: { fillColor: {
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
*/ */
import MaxRectsBinPack from "./MaxRectsBinPack"; import MaxRectsBinPack from "./MaxRectsBinPack";
import {clonePureObj} from "./index";
const packExts = ['.png']; //, '.jpg', '.jpeg', '.bmp' const packExts = ['.png']; //, '.jpg', '.jpeg', '.bmp'
...@@ -83,7 +84,7 @@ export async function packImages(asssts, options = {}) { ...@@ -83,7 +84,7 @@ export async function packImages(asssts, options = {}) {
}; };
for (let asset of rect.assets) { for (let asset of rect.assets) {
frames[asset.uuid] = sprite; frames[asset.uuid] = Object.assign({}, sprite, {name: asset.name});
i++; i++;
} }
} }
......
...@@ -11,13 +11,16 @@ ...@@ -11,13 +11,16 @@
</split-panes> </split-panes>
<inspector splitpanes-min="20" :splitpanes-size="getSize(0, 1)"></inspector> <inspector splitpanes-min="20" :splitpanes-size="getSize(0, 1)"></inspector>
</split-panes> </split-panes>
<bottom-bar/>
<details-dialog ref="dialogsDialog"/> <details-dialog ref="dialogsDialog"/>
<pack-result-dialog ref="packResultDialog"/> <pack-result-dialog ref="packResultDialog"/>
<mock-editor-dialog ref="mockEditorDialog"/>
<code-sync-serve-dialog ref="codeSyncServeDialog"/>
</div> </div>
</template> </template>
<script> <script>
import {mapGetters, mapActions} from 'vuex' import {mapState, mapActions} from 'vuex'
import SplitPanes from 'splitpanes' import SplitPanes from 'splitpanes'
import ToolBar from "./Editor/ToolBar"; import ToolBar from "./Editor/ToolBar";
import Inspector from "./Editor/Inspector"; import Inspector from "./Editor/Inspector";
...@@ -29,10 +32,19 @@ ...@@ -29,10 +32,19 @@
import i18n from "../i18n"; import i18n from "../i18n";
import PackResultDialog from "./Editor/dialogs/PackResultDialog"; import PackResultDialog from "./Editor/dialogs/PackResultDialog";
import events from "@/global-events.js" import events from "@/global-events.js"
import db from "../utils/db-storage";
import MockEditorDialog from "./Editor/dialogs/MockEditorDialog";
import {startCodeSyncServe} from "../code-sync-serve";
import BottomBar from "./Editor/BottomBar";
import CodeSyncServeDialog from "./Editor/dialogs/CodeSyncServeDialog";
export default { export default {
name: 'Editor', name: 'Editor',
components: { components: {
CodeSyncServeDialog,
BottomBar,
MockEditorDialog,
PackResultDialog, PackResultDialog,
DetailsDialog, DetailsDialog,
Assets, Assets,
...@@ -59,29 +71,39 @@ ...@@ -59,29 +71,39 @@
} }
}, },
computed: { computed: {
...mapGetters([]), ...mapState({
codeSyncServeConfig(state) {
return state.env.codeSyncServeConfig;
},
}),
}, },
async mounted() { async mounted() {
document.addEventListener('keydown', this.onKeyPress); document.addEventListener('keydown', this.onKeyPress);
events.$on('save-and-preview', () => {
this.clickMenu("preview");
});
events.$on('show-code-sync-serve-dialog', () => {
this.$refs.codeSyncServeDialog.show();
});
await playWaiting(this.prepare(), this.$t('Preparing')).catch(e => { await playWaiting(this.prepare(), this.$t('Preparing')).catch(e => {
}); });
setTimeout(() => {
startCodeSyncServe(this.codeSyncServeConfig);
}, 100);
this.loadProject(); this.loadProject();
}, },
destroyed() { destroyed() {
document.removeEventListener('keydown', this.onKeyPress) document.removeEventListener('keydown', this.onKeyPress)
}, },
created() {
events.$on('saveAndPreview', () => {
this.clickMenu("preview");
});
},
methods: { methods: {
prepare() { prepare() {
return Promise.all([ return Promise.all([
this.updateEnv(), this.updateEnv(),
db.open('store'),
]) ])
}, },
onKeyPress(e) { onKeyPress(e) {
...@@ -166,14 +188,18 @@ ...@@ -166,14 +188,18 @@
this.$refs.dialogsDialog.show(); this.$refs.dialogsDialog.show();
break; break;
case 'preview': case 'preview':
this.preview();
await this.pack(true); await this.pack(true);
break; break;
case 'preview2': case 'preview-fast':
this.preview(); this.preview();
break; break;
case 'publish': case 'publish':
await this.publish(); await this.publish();
break; break;
case 'mock':
this.$refs.mockEditorDialog.show();
break;
case 'undo': case 'undo':
this.$store.commit('undoRedo', 1); this.$store.commit('undoRedo', 1);
break; break;
...@@ -202,7 +228,7 @@ ...@@ -202,7 +228,7 @@
break; break;
} }
}, },
async publish(){ async publish() {
this.pack(); this.pack();
}, },
async pack(debug = false) { async pack(debug = false) {
...@@ -211,7 +237,7 @@ ...@@ -211,7 +237,7 @@
text: this.$t('Packing'), text: this.$t('Packing'),
}); });
try { try {
if(!debug){ if (!debug) {
await this.saveProject(false); await this.saveProject(false);
} }
const packResult = await this.packProject(debug); const packResult = await this.packProject(debug);
...@@ -257,7 +283,7 @@ ...@@ -257,7 +283,7 @@
let previewUrl = new URL(location.href); let previewUrl = new URL(location.href);
previewUrl.hash = '#/preview/' + projectID; previewUrl.hash = '#/preview/' + projectID;
setTimeout(()=>{ setTimeout(() => {
window.open(previewUrl.href, 'blank'); window.open(previewUrl.href, 'blank');
}, 300); }, 300);
}, },
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<el-scrollbar class="assets-scrollbar" wrap-class="wrap-x-hidden" <el-scrollbar class="assets-scrollbar" wrap-class="wrap-x-hidden"
view-class="scrollbar-view"> view-class="scrollbar-view">
<div class="file-list"> <div class="file-list">
<div class="file-uploader" @click="toUploadFile"> <div class="file-uploader" @click="toUploadFile" @dragover.prevent @drop="onDropFile">
<i class="el-icon-plus file-uploader-icon"></i> <i class="el-icon-plus file-uploader-icon"></i>
</div> </div>
<file-item v-for="(asset, index) in assets" :data="asset" :key="index" @show-file-details="showFileDetails" <file-item v-for="(asset, index) in assets" :data="asset" :key="index" @show-file-details="showFileDetails"
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
import FileItem from "./Assets/FileItem"; import FileItem from "./Assets/FileItem";
import AssetsShow from "./Assets/AssetsShow"; import AssetsShow from "./Assets/AssetsShow";
import SplitPanes from 'splitpanes' import SplitPanes from 'splitpanes'
import {selectFile} from "../../utils"; import {scanFiles, selectFile} from "../../utils";
export default { export default {
name: "Assets", name: "Assets",
...@@ -68,6 +68,23 @@ ...@@ -68,6 +68,23 @@
this.uploadFiles(files); this.uploadFiles(files);
}, {multiple: true}) }, {multiple: true})
}, },
async onDropFile(e) {
const items = e.dataTransfer.items;
let allFiles = [];
let allEntries = [];
for (let item of items) {
await scanFiles(item.webkitGetAsEntry(), allEntries);
}
for (let entry of allEntries) {
await new Promise(resolve => {
entry.file(function (file) {
allFiles.push(file);
resolve();
});
})
}
this.uploadFiles(allFiles);
},
showFileDetails(file) { showFileDetails(file) {
this.$refs.assetsShow.show(file); this.$refs.assetsShow.show(file);
}, },
......
<template> <template>
<div class="file-item" @click="$emit('click', $event)"> <div class="file-item" @click="$emit('click', $event)">
<div class="icon"> <div class="icon">
<i v-if="!showThumbnail" draggable="true" class="file-icon" :class="fileIcon"></i> <i @dragstart="assetDragStart(data)" v-if="!showThumbnail" draggable="true" class="file-icon" :class="fileIcon"></i>
<img @dragstart="assetDragStart(data)" v-if="showThumbnail" draggable="true" class="thumbnail" :src="thumbnailUrl" <img @dragstart="assetDragStart(data)" v-if="showThumbnail" draggable="true" class="thumbnail" :src="thumbnailUrl"
alt="thumb" @dblclick="onDbclick()"> alt="thumb" @dblclick="onDbclick()">
<div class="operate-bar"> <div class="operate-bar">
......
<template>
<div class="bottom-bar">
<div class="editor-status">Ready</div>
<code-sync-indicator/>
<upload-indicator/>
</div>
</template>
<script>
import UploadIndicator from "./BottomBar/UploadIndicator";
import CodeSyncIndicator from "./BottomBar/CodeSyncIndicator";
export default {
name: "BottomBar",
components: {CodeSyncIndicator, UploadIndicator},
}
</script>
<style scoped>
</style>
<template>
<div class="code-sync-indicator">
<div class="indicator" :class="{enabled: enabled}" @click="onClick"></div>
</div>
</template>
<script>
import events from "../../../global-events";
import {codeSyncServeEnabled} from "../../../code-sync-serve";
export default {
name: "CodeSyncIndicator",
data() {
return {
enabled: codeSyncServeEnabled,
}
},
mounted() {
events.$on('code-sync-start', this.onCodeSyncStart);
events.$on('code-sync-stop', this.onCodeSyncStop);
},
destroyed() {
events.$off('code-sync-start', this.onCodeSyncStart);
events.$off('code-sync-stop', this.onCodeSyncStop);
},
methods: {
onCodeSyncStart() {
this.enabled = true;
},
onCodeSyncStop() {
this.enabled = false;
},
onClick() {
events.$emit('show-code-sync-serve-dialog');
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
<el-tab-pane :label="$t('Props')" name="properties"> <el-tab-pane :label="$t('Props')" name="properties">
<props-tab/> <props-tab/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('Script')" name="script">
<scripts-tab/>
</el-tab-pane>
<el-tab-pane :label="$t('Behavior')" name="behavior"> <el-tab-pane :label="$t('Behavior')" name="behavior">
<behavior-tab/> <behavior-tab/>
</el-tab-pane> </el-tab-pane>
...@@ -15,10 +18,11 @@ ...@@ -15,10 +18,11 @@
import Pane from '../../components/Pane'; import Pane from '../../components/Pane';
import BehaviorTab from "./Inspector/BehaviorTab"; import BehaviorTab from "./Inspector/BehaviorTab";
import PropsTab from "./Inspector/PropsTab"; import PropsTab from "./Inspector/PropsTab";
import ScriptsTab from "./Inspector/ScriptsTab";
export default { export default {
name: 'Inspector', name: 'Inspector',
components: {BehaviorTab, PropsTab, Pane}, components: {ScriptsTab, BehaviorTab, PropsTab, Pane},
data() { data() {
return { return {
tab: 'properties' tab: 'properties'
......
...@@ -147,28 +147,32 @@ ...@@ -147,28 +147,32 @@
}, },
handleBehaviorsChange(isPreview) { handleBehaviorsChange(isPreview) {
if (isPreview) { if (isPreview) {
events.$emit('saveAndPreview') events.$emit('save-and-preview')
} }
}, },
async deleteBehavior(index, behaviors) { async deleteBehavior(index, behaviors) {
let deleteMeta = false; let deleteMeta = false;
let close;
await this.$confirm(this.$t('Are you sure to delete it\'s process'), this.$t('Alert'), { await this.$confirm(this.$t('Are you sure to delete it\'s process'), this.$t('Alert'), {
showClose: false, confirmButtonText: this.$t('Delete'),
closeOnClickModal: false, cancelButtonText: this.$t('Not delete'),
closeOnPressEscape: false, distinguishCancelAndClose: true,
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
deleteMeta = true; deleteMeta = true;
}).catch((e) => { }).catch(action => {
if(action === 'close'){
close = true;
}
}); });
if(!close){
this.deleteBehaviorDirect({ this.deleteBehaviorDirect({
behaviors, behaviors,
index, index,
deleteMeta, deleteMeta,
}) })
}
}, },
...mapActions([ ...mapActions([
'modifyActiveView', 'modifyActiveView',
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
<div class="zero-inspector-props-form" v-if="activeComponent.uuid"> <div class="zero-inspector-props-form" v-if="activeComponent.uuid">
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden"> <el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden">
<el-form ref="form" size="mini" :model="form" label-width="80px" @submit.native.prevent> <el-form ref="form" size="mini" :model="form" label-width="80px" @submit.native.prevent>
<el-collapse v-model="configColl">
<el-collapse-item :title="$t('Props')" name="properties">
<el-form-item label="名称"> <el-form-item label="名称">
<el-input v-model="form.name" @input="v => handleChange('name', v)"></el-input> <el-input v-model="form.name" @input="v => handleChange('name', v)"></el-input>
</el-form-item> </el-form-item>
...@@ -23,32 +21,6 @@ ...@@ -23,32 +21,6 @@
</el-tooltip> </el-tooltip>
</el-form-item> </el-form-item>
</template> </template>
</el-collapse-item>
<el-collapse-item :title="$t('Script')" name="scripts">
<el-collapse accordion v-if="activeComponent.scripts && activeComponent.scripts.length">
<template v-for="(script, index) in activeComponent.scripts">
<el-collapse-item :title="getScriptName(script.script)" :key="script + index">
<template v-for="(p, key) in getScriptOptions(script.script)">
<el-form-item :key="activeComponent.uuid + index + key" :label="p.alias|| key">
<dynamic-component :component-value="getScriptValue(p, key, index)" :component-props="getScriptProps(p, index)" :component-type="getScriptType(p, index)" @onChange="v => handleScriptChange(index, key, v)"></dynamic-component>
</el-form-item>
</template>
<el-form-item label="">
<el-button @click="deleteNodeScript(index)">删除</el-button>
</el-form-item>
</el-collapse-item>
</template>
</el-collapse>
<div style="padding-top: 15px;text-align: center;">
<el-dropdown trigger="click" @command="handleAddScript" placement="top" size="small">
<el-button size="mini">{{$t('Add')}}</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(script, key) of scripts" :command="script.id" :key="key">{{script.name}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-collapse-item>
</el-collapse>
</el-form> </el-form>
</el-scrollbar> </el-scrollbar>
</div> </div>
...@@ -110,36 +82,6 @@ const componentMapper = { ...@@ -110,36 +82,6 @@ const componentMapper = {
} }
}; };
const scriptTypeMap = {
number: {
component: 'el-input-number',
props: {
size: 'mini'
}
},
string: {
component: 'el-input'
},
boolean: {
component: 'el-switch',
props: {
width: 40
}
},
color: {
component: 'el-color-picker',
props: {
'show-alpha': true
}
},
select: {
component: 'el-select',
props: {
slotComponent: 'el-option'
}
}
};
export default { export default {
name: 'PropsTab', name: 'PropsTab',
components: { 'dynamic-component': dynamicComponent }, components: { 'dynamic-component': dynamicComponent },
...@@ -150,18 +92,11 @@ export default { ...@@ -150,18 +92,11 @@ export default {
name: '', name: '',
type: '', type: '',
properties: {}, properties: {},
scripts: []
}, },
configColl: ['properties']
}; };
}, },
computed: { computed: {
...mapGetters(['activeComponent', 'activeComponentCopy', 'componentList']), ...mapGetters(['activeComponent', 'activeComponentCopy', 'componentList']),
...mapState({
scripts(state){
return state.env.scripts;
}
}),
cmpProps: function() { cmpProps: function() {
// 获取properties.js中的默认配置 // 获取properties.js中的默认配置
return getCmpProps(this.activeComponent.type); return getCmpProps(this.activeComponent.type);
...@@ -183,13 +118,6 @@ export default { ...@@ -183,13 +118,6 @@ export default {
_view[label] = v; _view[label] = v;
this.$store.dispatch('modifyActiveView', _view); this.$store.dispatch('modifyActiveView', _view);
}, },
/**
* 脚本预设对象选中
*/
handleAddScript(command) {
console.log('handleAddScript', command);
this.$store.dispatch('addNodeScript', command);
},
/** /**
* 基础属性发生改变 * 基础属性发生改变
*/ */
...@@ -200,20 +128,6 @@ export default { ...@@ -200,20 +128,6 @@ export default {
_prop[key] = v; _prop[key] = v;
this.$store.dispatch('modifyProperties', _prop); this.$store.dispatch('modifyProperties', _prop);
}, },
/**
* 事件属性发生改变
*/
handleScriptChange(index, key, v) {
let _props = {};
_props[key] = v;
let _scripts = _.cloneDeep(this.activeComponent.scripts);
let _script = _scripts[index];
_script.props = _.assign(_script.props, _props);
_scripts[index] = _script;
this.$store.dispatch('modifyActiveView', {
scripts: _scripts
});
},
/** /**
* 获取动态组件的类型 * 获取动态组件的类型
*/ */
...@@ -239,61 +153,6 @@ export default { ...@@ -239,61 +153,6 @@ export default {
let _properties = this.activeComponentCopy.properties; let _properties = this.activeComponentCopy.properties;
return _properties[key] === undefined || _properties[key] === null ? item.value : _properties[key]; return _properties[key] === undefined || _properties[key] === null ? item.value : _properties[key];
}, },
getScriptValue(item, key, index) {
let _script = this.activeComponent.scripts[index];
// let result =
return _script.props[key] || item.default;
},
getScriptProps(item, index) {
let _type = item.type;
let _options = [];
if (_type === 'enum') {
// 如果脚本选项对应的类型是数组,说明是枚举类型
_options = item.enum.map(i => {
return {
label: i,
value: i
};
});
_type = 'select';
}
let _cmp = scriptTypeMap[_type];
return {
size: 'mini',
...(_cmp.props || {}),
options: _options
};
},
getScriptType(item, index) {
// 如果脚本选项对应的类型是数组,说明是枚举类型
let _type = item.type;
if (_type === 'enum') {
_type = 'select';
}
return scriptTypeMap[_type].component;
},
getScriptName(id) {
let _script = this.scripts.find(script => script.id === id);
return _script ? _script.name : '';
},
getScriptOptions(id) {
let _script = this.scripts.find(script => script.id === id);
return _script ? _script.props : {};
},
/**
* 删除节点脚本
*/
deleteNodeScript(index) {
let _scripts = _.cloneDeep(this.activeComponent.scripts);
_.remove(_scripts, (s, sindex) => {
return sindex === index;
});
this.$store.dispatch('modifyActiveView', {
scripts: _scripts
});
}
} }
}; };
</script> </script>
......
<template> <template>
<div class="zero-inspector-script-form" v-if="activeComponent.uuid"> <div class="zero-inspector-props-form" v-if="activeComponent.uuid">
<el-collapse v-model="configColl"> <el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden">
<el-collapse-item title="配置" name="properties">
<el-form ref="form" size="mini" :model="form" label-width="80px" @submit.native.prevent> <el-form ref="form" size="mini" :model="form" label-width="80px" @submit.native.prevent>
<el-form-item label="名称"> <el-collapse accordion v-if="activeComponent.scripts && activeComponent.scripts.length">
<el-input v-model="form.name" @input="v => handleChange('name', v)"></el-input> <template v-for="(script, index) in activeComponent.scripts">
</el-form-item> <el-collapse-item :title="getScriptName(script.script)" :key="script + index">
<el-form-item label="类型"> <template v-for="(p, key) in getScriptOptions(script.script)">
<el-select v-model="form.type" @change="v => handleChange('type', v)" placeholder="请选择类型"> <el-form-item :key="activeComponent.uuid + index + key" :label="p.alias|| key">
<el-option v-for="cmp in componentsMap" :key="cmp.value" :label="cmp.label" :value="cmp.value"></el-option> <dynamic-component :component-value="getScriptValue(p, key, index)" :component-props="getScriptProps(p, index)" :component-type="getScriptType(p, index)" @onChange="v => handleScriptChange(index, key, v)"></dynamic-component>
</el-select>
</el-form-item>
<template v-for="(p, key) in cmpProps">
<el-form-item v-if="key !== 'groupName'" :id="activeComponent.uuid + '-' + key" :key="activeComponent.uuid + key" :label="p.title">
<!-- {{key}} -->
<dynamic-component :label="key" :item="p" :properties="activeComponent.properties"></dynamic-component>
</el-form-item> </el-form-item>
</template> </template>
</el-form> <el-form-item label="">
</el-collapse-item> <el-button @click="deleteNodeScript(index)">删除</el-button>
<el-collapse-item title="脚本" name="scripts"> </el-form-item>
</el-collapse-item> </el-collapse-item>
</template>
</el-collapse> </el-collapse>
<div style="padding-top: 15px;text-align: center;">
<el-dropdown trigger="click" @command="handleAddScript" placement="top" size="small">
<el-button size="mini">{{$t('Add')}}</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(script, key) of scripts" :command="script.id" :key="key">{{script.name}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-form>
</el-scrollbar>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters, mapState } from 'vuex';
import _ from 'lodash';
import { componentsMap, getCmpProps } from '../../../utils/common'; import { componentsMap, getCmpProps } from '../../../utils/common';
import dynamicComponent from '../components/dynamicComponent'; import dynamicComponent from '../components/dynamicComponent';
const scriptTypeMap = {
number: {
component: 'el-input-number',
props: {
size: 'mini'
}
},
string: {
component: 'el-input'
},
boolean: {
component: 'el-switch',
props: {
width: 40
}
},
color: {
component: 'el-color-picker',
props: {
'show-alpha': true
}
},
select: {
component: 'el-select',
props: {
slotComponent: 'el-option'
}
}
};
export default { export default {
name: 'PropsTab', name: 'ScriptsTab',
components: { 'dynamic-component': dynamicComponent }, components: { 'dynamic-component': dynamicComponent },
data() { data() {
return { return {
componentsMap, componentsMap,
form: { form: {
name: '', scripts: []
type: '',
properties: {}
}, },
configColl: ['properties'] configColl: ['properties']
}; };
}, },
computed: { computed: {
...mapGetters(['activeComponent', 'componentList']), ...mapGetters(['activeComponent', 'activeComponentCopy', 'componentList']),
cmpProps: function() { ...mapState({
return getCmpProps(this.activeComponent.type); scripts(state){
return state.env.scripts;
} }
}),
}, },
watch: { methods: {
activeComponent: { /**
deep: true, * 脚本预设对象选中
handler: function(val) { */
this.form.name = val.name || ''; handleAddScript(command) {
this.form.type = val.type || ''; console.log('handleAddScript', command);
this.form.properties = val.properties || {}; this.$store.dispatch('addNodeScript', command);
},
/**
* 事件属性发生改变
*/
handleScriptChange(index, key, v) {
let _props = {};
_props[key] = v;
let _scripts = _.cloneDeep(this.activeComponent.scripts);
let _script = _scripts[index];
_script.props = _.assign(_script.props, _props);
_scripts[index] = _script;
this.$store.dispatch('modifyActiveView', {
scripts: _scripts
});
},
getScriptValue(item, key, index) {
let _script = this.activeComponent.scripts[index];
let v = _script.props[key];
return v === undefined ? item.default : v;
},
getScriptProps(item, index) {
let _type = item.type;
let _options = [];
if (_type === 'enum') {
// 如果脚本选项对应的类型是数组,说明是枚举类型
_options = item.enum.map(i => {
return {
label: i,
value: i
};
});
_type = 'select';
} }
let _cmp = scriptTypeMap[_type];
return {
size: 'mini',
...(_cmp.props || {}),
options: _options
};
},
getScriptType(item, index) {
// 如果脚本选项对应的类型是数组,说明是枚举类型
let _type = item.type;
if (_type === 'enum') {
_type = 'select';
} }
return scriptTypeMap[_type].component;
}, },
methods: { getScriptName(id) {
handleChange(label, v) { let _script = this.scripts.find(script => script.id === id);
this.$store.dispatch('modifyComponent', { return _script ? _script.name : '';
label: label, },
value: v getScriptOptions(id) {
let _script = this.scripts.find(script => script.id === id);
return _script ? _script.props : {};
},
/**
* 删除节点脚本
*/
deleteNodeScript(index) {
let _scripts = _.cloneDeep(this.activeComponent.scripts);
_.remove(_scripts, (s, sindex) => {
return sindex === index;
});
this.$store.dispatch('modifyActiveView', {
scripts: _scripts
}); });
} }
} }
...@@ -72,14 +167,17 @@ export default { ...@@ -72,14 +167,17 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
.zero-inspector-script-form { .zero-inspector-props-form {
width: 100%; width: 100%;
padding-right: 10px; padding-right: 10px;
.el-form-item--mini.el-form-item {
margin-bottom: 10px;
}
.el-divider__text { .el-divider__text {
background-color: #e9e9e9; background-color: #e9e9e9;
} }
.zero-inspector-props-group {
max-height: 500px;
}
}
.script-config-dialog {
height: 350px;
} }
</style> </style>
\ No newline at end of file
<template> <template>
<div class="tool-bar"> <div class="tool-bar">
<sample-menu :data="menu" @click-menu="clickMenu"/> <sample-menu :data="menu" @click-menu="clickMenu"/>
<upload-indicator/>
<div style="flex: 1"></div> <div style="flex: 1"></div>
<div class="right-part"> <div class="right-part">
<span> <span>
...@@ -15,11 +14,10 @@ ...@@ -15,11 +14,10 @@
<script> <script>
import {mapState, mapActions, mapMutations} from 'vuex' import {mapState, mapActions, mapMutations} from 'vuex'
import SampleMenu from "../../components/SampleMenu"; import SampleMenu from "../../components/SampleMenu";
import UploadIndicator from "./ToolBar/UploadIndicator";
export default { export default {
name: "ToolBar", name: "ToolBar",
components: {UploadIndicator, SampleMenu}, components: {SampleMenu},
data() { data() {
return {} return {}
}, },
...@@ -45,7 +43,7 @@ ...@@ -45,7 +43,7 @@
async mounted() { async mounted() {
//监听键盘事件 //监听键盘事件
document.addEventListener('keydown', this.onKeyPress); //document.addEventListener('keydown', this.onKeyPress);
}, },
methods: { methods: {
clickMenu(menuItem) { clickMenu(menuItem) {
......
...@@ -5,10 +5,11 @@ ...@@ -5,10 +5,11 @@
:show-close="false" :show-close="false"
fullscreen fullscreen
:append-to-body="true" :append-to-body="true"
custom-class="behavior-editor-dialog" custom-class="flex-dialog behavior-editor-dialog"
> >
<div class="meta-editor-wrapper"> <div class="meta-editor-wrapper">
<el-form ref="form" v-if="meta" :model="meta" :rules="rules" :show-message="false" class="info-editor" size="mini" label-position="right" label-width="70px" @submit.native.prevent> <el-form ref="form" v-if="meta" :model="meta" :rules="rules" :show-message="false" class="info-editor" size="mini"
label-position="right" label-width="70px" @submit.native.prevent>
<template> <template>
<el-form-item prop="id" :label="$t('ID')"> <el-form-item prop="id" :label="$t('ID')">
<el-input v-model="meta.id" :placeholder="$t('ID')" :readonly="!editable"/> <el-input v-model="meta.id" :placeholder="$t('ID')" :readonly="!editable"/>
...@@ -42,6 +43,7 @@ ...@@ -42,6 +43,7 @@
</template> </template>
</el-form> </el-form>
<div style="margin-top: 5px;"> <div style="margin-top: 5px;">
<code-sync-indicator/>
<el-tag v-for="(item, key) in exposeVariables" :key="key" size="mini">{{item}}</el-tag> <el-tag v-for="(item, key) in exposeVariables" :key="key" size="mini">{{item}}</el-tag>
</div> </div>
<!--<el-input v-if="meta" class="script-editor" :readonly=" !editable" type="textarea" :placeholder="$t('Code')" <!--<el-input v-if="meta" class="script-editor" :readonly=" !editable" type="textarea" :placeholder="$t('Code')"
...@@ -49,10 +51,7 @@ ...@@ -49,10 +51,7 @@
<codemirror ref="codeEditor" v-if="meta" <codemirror ref="codeEditor" v-if="meta"
v-model="meta.script" v-model="meta.script"
:options="cmOptions" :options="cmOptions"
@cursorActivity="onCodeChange" @cursorActivity="onCodeChange"/>
>
</codemirror>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<div class="button-bar"> <div class="button-bar">
...@@ -64,7 +63,7 @@ ...@@ -64,7 +63,7 @@
</el-popover> </el-popover>
</el-button-group> </el-button-group>
<el-button size="mini" plain @click="cancel">{{$t('Cancel')}}</el-button> <el-button size="mini" plain @click="cancel">{{$t('Cancel')}}</el-button>
<el-button size="mini" plain @click="save(true)">{{$t('Save And Preview')}}</el-button> <!--<el-button size="mini" plain @click="save(true)">{{$t('Save And Preview')}}</el-button>-->
<el-button size="mini" type="primary" plain @click="save(false)">{{$t('Save')}}</el-button> <el-button size="mini" type="primary" plain @click="save(false)">{{$t('Save')}}</el-button>
</div> </div>
</div> </div>
...@@ -85,14 +84,17 @@ ...@@ -85,14 +84,17 @@
import 'codemirror/addon/hint/show-hint.js' import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/show-hint.css' import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/javascript-hint.js' import 'codemirror/addon/hint/javascript-hint.js'
import events from "@/global-events.js" import 'codemirror/addon/lint/lint.js'
import 'codemirror/addon/lint/lint.css'
import 'codemirror/addon/lint/javascript-lint.js'
import events from '../../../global-events';
import CodeSyncIndicator from "../BottomBar/CodeSyncIndicator";
const exposeVariables = ['args', 'props', 'target', 'global', 'vm', 'engine']; const exposeVariables = ['args', 'props', 'target', 'global', 'vm', 'engine'];
export default { export default {
name: "MetaEditorDialog", name: "MetaEditorDialog",
components: {PropsEditorDialog, ElFormItem, codemirror}, components: {CodeSyncIndicator, PropsEditorDialog, ElFormItem, codemirror},
data() { data() {
return { return {
visible: false, visible: false,
...@@ -102,26 +104,35 @@ ...@@ -102,26 +104,35 @@
rules: { rules: {
id: [ id: [
{ required: true, trigger: 'blur' }, {required: true, trigger: 'blur'},
], ],
name: [ name: [
{ required: true, trigger: 'blur' } {required: true, trigger: 'blur'}
], ],
}, },
cmOptions: { cmOptions: {
tabSize: 2, tabSize: 2,
mode: 'text/javascript',
styleActiveLine: true, styleActiveLine: true,
theme: 'default', theme: 'default',
lineNumbers: true,
line: true, line: true,
matchBrackets: true, matchBrackets: true,
autoCloseBrackets: true, autoCloseBrackets: true,
extraKeys: {
"Alt-Space": "autocomplete",
},
lineNumbers: true,
mode: {name: 'javascript', globalVars: true},
gutters: ["CodeMirror-lint-markers"],
lint: true
} }
} }
}, },
mounted(){ mounted() {
events.$on('edit-save', this.onEditSave);
},
destroyed(){
events.$off('edit-save', this.onEditSave);
}, },
computed: { computed: {
editable() { editable() {
...@@ -136,6 +147,11 @@ ...@@ -136,6 +147,11 @@
this.visible = true; this.visible = true;
this.meta = clonePureObj(meta); this.meta = clonePureObj(meta);
this.oldMetaID = this.meta.id; this.oldMetaID = this.meta.id;
events.$emit('edit-open', this.meta.script);
},
onEditSave(code){
this.$set(this.meta, 'script', code);
}, },
onClickEditProps() { onClickEditProps() {
this.$refs.propsEditorDialog.edit(this.meta.props); this.$refs.propsEditorDialog.edit(this.meta.props);
...@@ -148,8 +164,8 @@ ...@@ -148,8 +164,8 @@
.catch((e) => { .catch((e) => {
}); });
} else { } else {
this.$emit('input',this.meta,isPreview); this.$emit('input', this.meta, isPreview);
this.visible=false; this.visible = false;
} }
} else { } else {
return false; return false;
...@@ -167,19 +183,19 @@ ...@@ -167,19 +183,19 @@
}, },
onPaste(e) { onPaste(e) {
let metaStr = e.clipboardData.getData("Text"); let metaStr = e.clipboardData.getData("Text");
if(metaStr){ if (metaStr) {
try { try {
let meta = JSON.parse(metaStr); let meta = JSON.parse(metaStr);
this.meta = meta; this.meta = meta;
}catch (e) { } catch (e) {
} }
} }
}, },
focusPasteBoard(){ focusPasteBoard() {
this.$refs.pasteBoard.focus(); this.$refs.pasteBoard.focus();
}, },
onCodeChange(codemirror){ onCodeChange(codemirror) {
//codemirror.showHint(); //codemirror.showHint();
//console.log(code); //console.log(code);
} }
......
<template> <template>
<el-dialog :title="$t('Behavior Editor')" :visible.sync="visible" :before-close="beforeClose" @opened="onOpened" <el-dialog :title="$t('Behavior Editor')" :visible.sync="visible" :before-close="beforeClose" @opened="onOpened"
:fullscreen="true" :close-on-click-modal="false" :close-on-press-escape="false" :fullscreen="true" :close-on-click-modal="false" :close-on-press-escape="false"
:append-to-body="true" custom-class="behavior-editor-dialog"> :append-to-body="true" custom-class="flex-dialog behavior-editor-dialog">
<behavior-editor v-if="editorReady" ref="behaviorEditor" class="full-size"></behavior-editor> <behavior-editor v-if="editorReady" ref="behaviorEditor" class="full-size"></behavior-editor>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button size="mini" @click="onSave(true)">{{$t('Save And Preview')}}</el-button> <el-button size="mini" @click="onSave(true)">{{$t('Save And Preview')}}</el-button>
......
<template>
<el-dialog :title="$t('CodeSyncServe')" width="70%" :visible.sync="visible"
:append-to-body="true"
custom-class=""
>
<div>
<el-form label-position="right" label-width="50px" size="mini">
<el-form-item label="IP">
<el-input v-model="config.ip"/>
</el-form-item>
<el-form-item label="Port">
<el-input-number v-model="config.port" controls-position="right" :max="65535"/>
</el-form-item>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<div>
</div>
<div>
<el-button size="mini" @click="onClose">{{$t('Close')}}</el-button>
<el-button size="mini" @click="onSave" type="primary">{{$t('Save')}}</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import {mapMutations, mapState} from 'vuex'
import EnabledSetter from "../components/EnabledSetter";
import ElFormItem from "../behavior-editor/inputs/form-item";
import {clonePureObj} from "../../../utils";
import {startCodeSyncServe} from "../../../code-sync-serve";
export default {
name: "CodeSyncServeDialog",
components: {ElFormItem, EnabledSetter,},
data() {
return {
visible: false,
config: {},
}
},
mounted() {
},
computed: {
...mapState({
codeSyncServeConfig(state) {
return state.env.codeSyncServeConfig;
}
})
},
methods: {
show() {
this.config = clonePureObj(this.codeSyncServeConfig);
this.visible = true;
},
onSave() {
this.saveCodeSyncServeConfig(this.config);
startCodeSyncServe(this.config);
this.visible = false;
},
onClose() {
this.visible = false;
},
...mapMutations([
'saveCodeSyncServeConfig',
]),
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template> <template>
<el-dialog :title="$t('Project details')" width="70%" :visible.sync="visible" @open="onOpen" <el-dialog :title="$t('Project details')" width="70%" :visible.sync="visible" @opened="onOpen"
:close-on-click-modal="false" :close-on-click-modal="false"
:append-to-body="true" :append-to-body="true"
:show-close="false" :show-close="false"
fullscreen fullscreen
custom-class="details-dialog" custom-class="flex-dialog details-dialog"
> >
<el-tabs v-model="activeName"> <el-tabs v-model="activeName" class="tabs">
<el-tab-pane :label="$t('Project')" name="project"> <el-tab-pane :label="$t('Project')" name="project">
<project-editor/> <project-editor ref="projectEditor"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('Env constant')" name="env"> <el-tab-pane :label="$t('Env constant')" name="env">
<env-editor/> <env-editor ref="envEditor"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('Data mapping')" name="data-mapping"> <el-tab-pane :label="$t('Data mapping')" name="data-mapping">
<data-mapping-editor/> <data-mapping-editor ref="dataMappingEditor"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('Custom module')" name="custom"> <el-tab-pane :label="$t('Custom module')" name="custom">
<custom-editor/> <custom-editor ref="customEditor"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button size="mini" @click="onClose">{{$t('Close')}}</el-button> <el-button size="mini" @click="onClose">{{$t('Close')}}</el-button>
<el-button size="mini" @click="onSave" type="primary">{{$t('Save')}}</el-button>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
import {mapMutations} from 'vuex';
import ProjectEditor from "./editors/ProjectEditor"; import ProjectEditor from "./editors/ProjectEditor";
import EnvEditor from "./editors/EnvEditor"; import EnvEditor from "./editors/EnvEditor";
import CustomEditor from "./editors/CustomEditor"; import CustomEditor from "./editors/CustomEditor";
import DataMappingEditor from "./editors/DataMappingEditor"; import DataMappingEditor from "./editors/DataMappingEditor";
const refs = [
'projectEditor',
'envEditor',
'dataMappingEditor',
'customEditor',
];
export default { export default {
name: "DetailsDialog", name: "DetailsDialog",
components: {DataMappingEditor, CustomEditor, EnvEditor, ProjectEditor}, components: {DataMappingEditor, CustomEditor, EnvEditor, ProjectEditor},
...@@ -45,12 +54,24 @@ ...@@ -45,12 +54,24 @@
show() { show() {
this.visible = true; this.visible = true;
}, },
onSave() {
for (let ref of refs) {
this.$refs[ref].save();
}
this.visible = false;
this.modifyProjectDetails();
},
onClose() { onClose() {
this.visible = false; this.visible = false;
}, },
onOpen() { onOpen() {
for (let ref of refs) {
this.$refs[ref].edit();
}
}, },
...mapMutations([
'modifyProjectDetails',
]),
} }
} }
</script> </script>
......
<template>
<el-dialog :title="$t('Mock Editor')" width="70%" :visible.sync="visible"
:close-on-click-modal="false"
:append-to-body="true"
:show-close="false"
fullscreen
custom-class="flex-dialog mock-editor-dialog"
>
<div class="mock-editor-view">
<label class="enabled-switch">
<el-switch :value="mockServeEnabled" @input="onMockServeEnabledChange"/>
{{$t('Enable mock serve')}}
</label>
<el-table class="mock-table" :data="mocks" height="100%" stripe size="mini">
<el-table-column type="expand">
<template slot-scope="props">
<codemirror ref="codeEditor"
v-model="props.row.data"
:options="cmOptions"/>
</template>
</el-table-column>
<el-table-column
prop="disabled"
width="40">
<template slot-scope="scope">
<enabled-setter :target="scope.row"/>
</template>
</el-table-column>
<el-table-column
prop="path"
:label="$t('Path')"
width="200">
<template slot-scope="scope">
<el-input v-model="scope.row.path" size="mini"/>
</template>
</el-table-column>
<el-table-column
prop="timeout"
:label="$t('Timeout')"
width="100">
<template slot-scope="scope">
<el-input-number style="width:100%;" v-model="scope.row.timeout" size="mini" controls-position="right"/>
</template>
</el-table-column>
<el-table-column
prop="successRatio"
:label="$t('SuccessRatio')"
width="150">
<template slot-scope="scope">
<el-slider v-model="scope.row.successRatio" size="mini" :max="1" :min="0" :step="0.1"/>
</template>
</el-table-column>
<el-table-column
prop="data"
:label="$t('Data')">
<template slot-scope="scope">
<span style="white-space: nowrap;overflow: hidden;">{{scope.row.data}}</span>
</template>
</el-table-column>
<el-table-column
width="50">
<template slot-scope="scope">
<el-button circle size="mini" type="danger" icon="el-icon-delete" plain
@click="toDeleteItem(scope.$index)"/>
</template>
</el-table-column>
</el-table>
</div>
<div slot="footer" class="dialog-footer">
<div>
<el-button size="mini" @click="onAdd">{{$t('Add')}}</el-button>
</div>
<div>
<el-button size="mini" @click="onClose">{{$t('Close')}}</el-button>
<el-button size="mini" @click="onSave" type="primary">{{$t('Save')}}</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import {mapState, mapMutations, mapActions} from 'vuex'
import EnabledSetter from "../components/EnabledSetter";
import {clonePureObj} from "../../../utils";
import {codemirror} from "vue-codemirror";
import 'codemirror/addon/lint/lint.js'
import 'codemirror/addon/lint/lint.css'
import 'codemirror/addon/lint/json-lint.js'
export default {
name: "MockEditorDialog",
components: {EnabledSetter, codemirror},
data() {
return {
visible: false,
mocks: [],
cmOptions: {
tabSize: 2,
styleActiveLine: true,
theme: 'default',
line: true,
matchBrackets: true,
autoCloseBrackets: true,
lineNumbers: true,
mode: "application/json",
gutters: ["CodeMirror-lint-markers"],
lint: true
}
}
},
mounted() {
},
computed: {
...mapState({
mocksOrigin: state => state.project.data.mock,
mockServeEnabled: state => state.project.mockServeEnabled,
}),
},
watch: {
mockServeEnabled(v) {
}
},
methods: {
show() {
this.mocks = clonePureObj(this.mocksOrigin);
this.visible = true;
},
onSave() {
this.modifyMocks(this.mocks);
this.visible = false;
},
onClose() {
this.visible = false;
},
onAdd() {
this.mocks.push({
path: '',
data: '',
timeout: 0,
successRatio: 1,
});
},
onDelete(index) {
this.mocks.splice(index, 1);
},
toDeleteItem(index) {
this.$confirm(this.$t('Are you sure to delete this item'), this.$t('Alert'), {
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
type: 'warning'
}).then(() => {
this.onDelete(index);
}).catch((e) => {
});
},
onMockServeEnabledChange(v){
this.setMockServeEnabled(v);
},
...mapMutations([
'modifyMocks',
]),
...mapActions([
'setMockServeEnabled',
]),
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template> <template>
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden" view-class="view"> <el-table v-if="editData" :data="customMetas" stripe height="100%">
<el-checkbox-group :value="customs" class="custom-module-list" @input="onChange"> <el-table-column
<el-checkbox class="item" v-for="customMeta in customMetas" :key="customMeta.id" :label="customMeta.id"> width="40"
{{customMeta.alias || customMeta.name}} >
</el-checkbox> <template slot-scope="scope">
</el-checkbox-group> <el-checkbox v-model="scope.row.selected"/>
</el-scrollbar> </template>
</el-table-column>
<el-table-column
prop="id"
label="ID"
width="200">
</el-table-column>
<el-table-column
prop="name"
:label="$t('Name')"
width="200">
</el-table-column>
<!--<el-table-column
label="Version"
width="100"
>
<template slot-scope="scope">
<el-select size="mini"/>
</template>
</el-table-column>-->
<el-table-column>
</el-table-column>
</el-table>
</template> </template>
<script> <script>
import {mapState, mapMutations} from 'vuex' import {mapState, mapMutations} from 'vuex'
import {clonePureObj} from "../../../../utils";
export default { export default {
name: "CustomEditor", name: "CustomEditor",
data() { data() {
return { return {
visible: false, visible: false,
customMetas: [],
editData: null,
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
customMetas: state => state.env.customs,
customs: state => state.project.data.customs, customs: state => state.project.data.customs,
}), }),
}, },
methods: { methods: {
edit() {
this.editData = clonePureObj(this.customs);
this.customMetas.splice(0);
for (let meta of this.$store.state.env.customs) {
this.customMetas.push({
id: meta.id,
name: meta.name,
selected: this.editData.includes(meta.id),
})
}
},
save() {
const editData = this.editData;
editData.splice(0);
for (let meta of this.customMetas) {
if(meta.selected){
editData.push(meta.id);
}
}
this.modifyCustoms(editData);
},
...mapMutations([ ...mapMutations([
'modifyCustoms', 'modifyCustoms',
]), ]),
onChange(v){
this.modifyCustoms(v);
}
} }
} }
</script> </script>
......
<template> <template>
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden" view-class="view"> <el-scrollbar v-if="editData" class="scrollbar" wrap-class="wrap-x-hidden" view-class="view">
<div class="mapping-list"> <div class="mapping-list">
<el-button class="add-button" icon="el-icon-plus" size="mini" circle @click="onAdd"/> <el-button class="add-button" icon="el-icon-plus" size="mini" circle @click="onAdd"/>
<div class="list"> <div class="list">
<div class="item" v-for="(link, index) in mapping"> <div class="item" v-for="(link, index) in editData">
<el-input size="mini" style="width: 30%" v-model="link.name" @change="onChange"/> <el-input size="mini" style="width: 30%" v-model="link.name"/>
<el-icon class="el-icon-connection"/> <el-icon class="el-icon-connection"/>
<el-input size="mini" v-model="link.path" @change="onChange"/> <el-input size="mini" v-model="link.path"/>
<el-button class="delete-button" icon="el-icon-minus" circle size="mini" plain type="danger" @click="toDeleteItem(link, index)"/> <el-button class="delete-button" icon="el-icon-minus" circle size="mini" plain type="danger" @click="toDeleteItem(link, index)"/>
</div> </div>
</div> </div>
...@@ -16,12 +16,14 @@ ...@@ -16,12 +16,14 @@
<script> <script>
import {mapState, mapMutations} from 'vuex' import {mapState, mapMutations} from 'vuex'
import {clonePureObj} from "../../../../utils";
export default { export default {
name: "DataMappingEditor", name: "DataMappingEditor",
data() { data() {
return { return {
visible: false, visible: false,
editData: null,
} }
}, },
computed: { computed: {
...@@ -30,11 +32,17 @@ ...@@ -30,11 +32,17 @@
}), }),
}, },
methods: { methods: {
onAdd() { edit() {
this.addDataMapping(); this.editData = clonePureObj(this.mapping);
},
save() {
this.modifyDataMapping(this.editData);
}, },
onChange() { onAdd() {
this.modifyDataMapping(); this.editData.push({
name: '',
path: '',
});
}, },
toDeleteItem(link, index) { toDeleteItem(link, index) {
this.$confirm(this.$t('Are you sure to delete this item'), this.$t('Alert'), { this.$confirm(this.$t('Are you sure to delete this item'), this.$t('Alert'), {
...@@ -42,13 +50,11 @@ ...@@ -42,13 +50,11 @@
cancelButtonText: this.$t('Cancel'), cancelButtonText: this.$t('Cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.deleteDataMapping(index); this.editData.splice(index, 1);
}).catch((e) => { }).catch((e) => {
}); });
}, },
...mapMutations([ ...mapMutations([
'addDataMapping',
'deleteDataMapping',
'modifyDataMapping', 'modifyDataMapping',
]), ]),
} }
......
<template> <template>
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden" view-class="view"> <el-scrollbar v-if="editData" class="scrollbar" wrap-class="wrap-x-hidden" view-class="view">
<div class="mapping-list"> <div class="mapping-list">
<el-button class="add-button" icon="el-icon-plus" size="mini" circle @click="onAdd"/> <el-button class="add-button" icon="el-icon-plus" size="mini" circle @click="onAdd"/>
<div class="list"> <div class="list">
<div class="item" v-for="(link, index) in env"> <div class="item" v-for="(link, index) in editData">
<el-input size="mini" style="width: 30%" v-model="link.name" @change="onChange"/> <el-input size="mini" style="width: 30%" v-model="link.name"/>
<el-icon class="el-icon-connection"/> <el-icon class="el-icon-connection"/>
<el-input size="mini" v-model="link.value" @change="onChange"/> <el-input size="mini" v-model="link.value"/>
<el-button class="delete-button" icon="el-icon-minus" circle size="mini" plain type="danger" @click="toDeleteItem(link, index)"/> <el-button class="delete-button" icon="el-icon-minus" circle size="mini" plain type="danger"
@click="toDeleteItem(link, index)"/>
</div> </div>
</div> </div>
</div> </div>
...@@ -16,12 +17,14 @@ ...@@ -16,12 +17,14 @@
<script> <script>
import {mapState, mapMutations} from 'vuex' import {mapState, mapMutations} from 'vuex'
import {clonePureObj} from "../../../../utils";
export default { export default {
name: "EnvEditor", name: "EnvEditor",
data() { data() {
return { return {
visible: false, visible: false,
editData: null,
} }
}, },
computed: { computed: {
...@@ -30,11 +33,17 @@ ...@@ -30,11 +33,17 @@
}), }),
}, },
methods: { methods: {
onAdd() { edit() {
this.addEnvMapping(); this.editData = clonePureObj(this.env);
},
save() {
this.modifyEnv(this.editData);
}, },
onChange() { onAdd() {
this.modifyEnvMapping(); this.editData.push({
name: '',
value: '',
});
}, },
toDeleteItem(link, index) { toDeleteItem(link, index) {
this.$confirm(this.$t('Are you sure to delete this item'), this.$t('Alert'), { this.$confirm(this.$t('Are you sure to delete this item'), this.$t('Alert'), {
...@@ -42,14 +51,12 @@ ...@@ -42,14 +51,12 @@
cancelButtonText: this.$t('Cancel'), cancelButtonText: this.$t('Cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.deleteEnvMapping(index); this.editData.splice(index, 1);
}).catch((e) => { }).catch((e) => {
}); });
}, },
...mapMutations([ ...mapMutations([
'addEnvMapping', 'modifyEnv',
'deleteEnvMapping',
'modifyEnvMapping',
]), ]),
} }
} }
......
<template> <template>
<div> <div class="project-editor">
<el-scrollbar class="scrollbar full-scrollbar" wrap-class="wrap-x-hidden" view-class="view"> <el-scrollbar v-if="editData" class="project-scrollbar" wrap-class="wrap-x-hidden" view-class="view">
<el-form @submit.native.prevent ref="form" :model="options" size="mini" label-position="right" <el-form @submit.native.prevent ref="form" :model="editData" size="mini" label-position="right"
label-width="150px"> label-width="150px">
<el-form-item prop="pageTitle" :label="$t('Page title')"> <el-form-item prop="pageTitle" :label="$t('Page title')">
<el-input v-model="options.pageTitle"/> <el-input v-model="editData.pageTitle"/>
</el-form-item> </el-form-item>
<el-form-item prop="entrySceneView" :label="$t('Entry scene view')"> <el-form-item prop="entrySceneView" :label="$t('Entry scene view')">
<el-select v-model="options.entrySceneView"> <el-select v-model="editData.entrySceneView">
<el-option v-for="(view, index) in project.data.views" <el-option v-for="(view, index) in project.data.views"
:key="index" :key="index"
:value="view.name" :value="view.name"
...@@ -16,19 +16,19 @@ ...@@ -16,19 +16,19 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="containerId" :label="$t('Container ID')"> <el-form-item prop="containerId" :label="$t('Container ID')">
<el-input v-model="options.containerId"/> <el-input v-model="editData.containerId"/>
</el-form-item> </el-form-item>
<el-form-item prop="designWidth" :label="$t('Design width')"> <el-form-item prop="designWidth" :label="$t('Design width')">
<el-input-number v-model="options.designWidth" controls-position="right"/> <el-input-number v-model="editData.designWidth" controls-position="right"/>
</el-form-item> </el-form-item>
<el-form-item prop="designHeight" :label="$t('Design height')"> <el-form-item prop="designHeight" :label="$t('Design height')">
<el-input-number v-model="options.designHeight" controls-position="right"/> <el-input-number v-model="editData.designHeight" controls-position="right"/>
</el-form-item> </el-form-item>
<el-form-item prop="frameRate" :label="$t('Frame Rate')"> <el-form-item prop="frameRate" :label="$t('Frame Rate')">
<el-input-number v-model="options.frameRate" :max="60" :min="0" controls-position="right"/> <el-input-number v-model="editData.frameRate" :max="60" :min="0" controls-position="right"/>
</el-form-item> </el-form-item>
<el-form-item prop="scaleMode" :label="$t('Scale Mode')"> <el-form-item prop="scaleMode" :label="$t('Scale Mode')">
<el-select v-model="options.scaleMode"> <el-select v-model="editData.scaleMode">
<el-option v-for="(label, key) in scaleMode" <el-option v-for="(label, key) in scaleMode"
:key="key" :key="key"
:value="key" :value="key"
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="rendererType" :label="$t('Renderer Type')"> <el-form-item prop="rendererType" :label="$t('Renderer Type')">
<el-select v-model="options.rendererType"> <el-select v-model="editData.rendererType">
<el-option v-for="(label, key) in rendererType" <el-option v-for="(label, key) in rendererType"
:key="key" :key="key"
:value="key" :value="key"
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
<el-form-item prop="tpl" :label="$t('Template')"> <el-form-item prop="tpl" :label="$t('Template')">
<!-- <el-input type="textarea" v-model="options.tpl" :rows="10"/> --> <!-- <el-input type="textarea" v-model="options.tpl" :rows="10"/> -->
<codemirror ref="codeEditor" <codemirror ref="codeEditor"
v-model="options.tpl" v-model="editData.tpl"
:options="cmOptions" :options="cmOptions"
@cursorActivity="onCodeChange" @cursorActivity="onCodeChange"
> >
...@@ -56,10 +56,10 @@ ...@@ -56,10 +56,10 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-scrollbar> </el-scrollbar>
<div class="operate-bar"> <!--<div class="operate-bar">
<el-button size="mini" @click="onReset">{{$t('Reset')}}</el-button> <el-button size="mini" @click="onReset">{{$t('Reset')}}</el-button>
<el-button size="mini" type="primary" @click="onSave">{{$t('Save')}}</el-button> <el-button size="mini" type="primary" @click="onSave">{{$t('Save')}}</el-button>
</div> </div>-->
</div> </div>
</template> </template>
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
import 'codemirror/addon/hint/show-hint.js' import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/show-hint.css' import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/javascript-hint.js' import 'codemirror/addon/hint/javascript-hint.js'
import {clonePureObj} from "../../../../utils";
export default { export default {
name: "ProjectEditor", name: "ProjectEditor",
...@@ -82,6 +83,7 @@ ...@@ -82,6 +83,7 @@
const rendererType = this.$t('rendererType'); const rendererType = this.$t('rendererType');
return { return {
visible: false, visible: false,
editData: null,
scaleMode, scaleMode,
rendererType, rendererType,
cmOptions: { cmOptions: {
...@@ -106,15 +108,21 @@ ...@@ -106,15 +108,21 @@
}, },
methods: { methods: {
...mapMutations([ ...mapMutations([
'modifyProject', 'modifyOptions',
]), ]),
onReset() { edit() {
this.editData = clonePureObj(this.options);
},
save() {
this.modifyOptions(this.editData);
},
/*onReset() {
this.$refs.form.resetFields(); this.$refs.form.resetFields();
}, },
onSave() { onSave() {
this.modifyProject(); this.modifyProject();
}, },*/
onCodeChange(codemirror){ onCodeChange(codemirror) {
//codemirror.showHint(); //codemirror.showHint();
//console.log(code); //console.log(code);
} }
......
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
<template slot="header" slot-scope="scope"> <template slot="header" slot-scope="scope">
<el-checkbox <el-checkbox
v-model="onlyMine" v-model="onlyMine"
size="mini">{{$t('Only mine')}}</el-checkbox> size="mini">{{$t('Only mine')}}
</el-checkbox>
</template> </template>
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
...@@ -44,11 +45,12 @@ ...@@ -44,11 +45,12 @@
type="warning" icon="icon-download" type="warning" icon="icon-download"
size="small" circle plain> size="small" circle plain>
</el-button> </el-button>
<!--<el-button <el-button
v-if="showDeleteButton"
@click.native.prevent="onDeleteProject(scope.row)" @click.native.prevent="onDeleteProject(scope.row)"
type="danger" icon="el-icon-delete" type="danger" icon="el-icon-delete"
size="small" circle plain> size="small" circle plain>
</el-button>--> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
...@@ -96,13 +98,16 @@ ...@@ -96,13 +98,16 @@
}); });
}, },
computed: { computed: {
showDeleteButton() {
return location.host.startsWith('localhost');
},
...mapState([ ...mapState([
'projects', 'projects',
'env', 'env',
]), ]),
}, },
watch: { watch: {
onlyMine(){ onlyMine() {
this.handleCurrentChange(1); this.handleCurrentChange(1);
} }
}, },
......
<template> <template>
<iframe ref="iframe" class="player-wrapper"> <div class="wrapper">
<iframe v-if="flag" ref="iframe" class="player-wrapper"></iframe>
</iframe> </div>
</template> </template>
<script> <script>
import {applyMock} from "./Preview/mock-serve";
import db from "../utils/db-storage";
import {newScriptEl} from "../utils";
export default { export default {
name: "Preview", name: "Preview",
components: {},
data() { data() {
return { return {
ts: '', ts: '',
flag: false,
} }
}, },
mounted() { async mounted() {
if(!this.ts){ this.codes = {};
this.urls = {};
if (!this.ts) {
this.ts = localStorage.getItem('preview-ts'); this.ts = localStorage.getItem('preview-ts');
} }
document.addEventListener("visibilitychange", this.onVisibilityChange); document.addEventListener("visibilitychange", this.onVisibilityChange);
setTimeout(()=>{
this.buildPage(); await db.open();
}, 100);
this.reload();
}, },
destroyed(){ destroyed() {
document.removeEventListener("visibilitychange", this.onVisibilityChange); document.removeEventListener("visibilitychange", this.onVisibilityChange);
}, },
methods: { methods: {
onVisibilityChange(e){ reload() {
if(!document.hidden){ this.flag = false;
setTimeout(() => {
this.flag = true;
this.buildPage();
}, 300);
},
onVisibilityChange(e) {
if (!document.hidden) {
let ts = localStorage.getItem('preview-ts'); let ts = localStorage.getItem('preview-ts');
if(this.ts !== ts){ if (this.ts !== ts) {
this.$refs.iframe.contentDocument.location.reload(); //this.$refs.iframe.contentDocument.location.reload();
document.location.reload(); //document.location.reload();
this.ts = ts; this.ts = ts;
this.reload();
} }
} }
}, },
buildPage() { async buildPage() {
const {projectID} = this.$route.params; const {projectID} = this.$route.params;
const storeKey = 'preview-project-' + projectID; const {data, codes} = await db.get('preview', projectID);
let data = localStorage.getItem(storeKey);
let dataObj = JSON.parse(data); let {options: {tpl, pageTitle, containerId}} = data;
//const dataName = projectID + "_data";
//const launchCode = `engine.launchWithWindowVariable("${dataName}");`;
let {options: {tpl, pageTitle, containerId}} = dataObj.data; const scripts = [];
for (let key in codes) {
let oldCode = this.codes[key];
let code = codes[key];
let url;
if (oldCode !== code) {
url = this.urls[key] = URL.createObjectURL(new Blob([code]));
} else {
url = this.urls[key];
}
scripts.push(newScriptEl(url));
}
this.codes = codes;
const dataUrl = URL.createObjectURL(new Blob([JSON.stringify(data)]));
const launchCode = `engine.launchWithLocalStorage("${projectID}");`; document.title = pageTitle;
tpl = tpl tpl = tpl
.replace('$PAGE_TITLE$', pageTitle) .replace('$PAGE_TITLE$', pageTitle)
.replace('$CONTAINER_ID$', containerId) .replace('$CONTAINER_ID$', containerId)
.replace('$SCRIPTS$', '') .replace('$SCRIPTS$', scripts.join('\n'))
.replace('engine.launch(\'//yun.duiba.com.cn/aurora/$VERSION$-data.json\');', launchCode); .replace('//yun.duiba.com.cn/aurora/$VERSION$-data.json', dataUrl);
const doc = this.$refs.iframe.contentDocument; const doc = this.$refs.iframe.contentDocument;
const win = this.$refs.iframe.contentWindow;
doc.write(tpl); doc.write(tpl);
applyMock(projectID, win);
}, },
} }
} }
</script> </script>
<style scoped> <style scoped>
.player-wrapper{ .wrapper {
width: 100%;
height: 100%;
}
.player-wrapper {
border: 0; border: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.mock-button {
position: absolute;
right: 10px;
bottom: 10px;
}
</style> </style>
\ No newline at end of file
/**
* Created by rockyl on 2019-12-18.
*/
import db from "../../utils/db-storage";
import {getMockServeEnabled} from "../../utils";
db.open();
const logStyle = "color: rgb(63, 172, 203)";
export function applyMock(projectID, win) {
win.mock = function ({url, method, params = {}, type}, callback, resolve, reject) {
const mockServeEnabled = getMockServeEnabled(projectID);
if (!mockServeEnabled) {
callback();
return;
}
if(url.includes('projectx')){
url = url.replace(/projectx\/\w+\//, '');
}
db.get('mock', url)
.then(
rule => {
if (rule && !rule.disabled) {
const {timeout = 0, successRatio = 1, data} = rule;
setTimeout(function () {
if (Math.random() < successRatio) {
try {
console.log(`%c[mock] ${url} ${method} ${JSON.stringify(params)}`, logStyle, JSON.parse(data));
resolve(JSON.parse(data));
} catch (e) {
reject(e);
}
} else {
reject(url + ' 404 (Not Found)')
}
}, timeout);
callback(rule);
} else {
callback();
}
},
e => {
callback();
}
);
};
}
\ No newline at end of file
/**
* Created by rockyl on 2019-12-20.
*/
import {clonePureObj} from "../../utils";
import {divideCode} from "zeroing-code-divider";
import db from "../../utils/db-storage";
const storeName = 'preview';
function getPack(packs) {
return function (ids) {
return packs.filter(pack => ids.includes(pack.id))
}
}
export async function preprocess(project, data, processes, scripts, customs) {
let newData = clonePureObj(data);
const codes = await divideCode(newData, {
debug: true,
getProcesses: getPack(processes),
getScripts: getPack(scripts),
getCustoms: getPack(customs),
});
db.set(storeName, {
id: project.id,
data: newData,
codes,
});
localStorage.setItem('preview-ts', Date.now().toString());
}
const serverHost = 'http://10.10.95.74:7777'; const serverHost = 'http://10.10.95.74:7777';
//const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = { module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '//yun.duiba.com.cn/editor/zeroing/v1/' : '', publicPath: process.env.NODE_ENV === 'production' ? '//yun.duiba.com.cn/editor/zeroing/v1/' : '',
pluginOptions: { pluginOptions: {
...@@ -23,6 +25,10 @@ module.exports = { ...@@ -23,6 +25,10 @@ module.exports = {
} }
},*/ },*/
configureWebpack: { configureWebpack: {
plugins: [
/*new MonacoWebpackPlugin({
languages: ['html', 'javascript', 'json']
})*/
]
} }
}; };
...@@ -1292,6 +1292,11 @@ address@>=0.0.1, address@^1.0.0, address@^1.0.3: ...@@ -1292,6 +1292,11 @@ address@>=0.0.1, address@^1.0.0, address@^1.0.3:
resolved "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz?cache=0&sync_timestamp=1566806470420&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faddress%2Fdownload%2Faddress-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" resolved "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz?cache=0&sync_timestamp=1566806470420&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faddress%2Fdownload%2Faddress-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
integrity sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY= integrity sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY=
after@0.8.2:
version "0.8.2"
resolved "https://registry.npm.taobao.org/after/download/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.npm.taobao.org/agent-base/download/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" resolved "https://registry.npm.taobao.org/agent-base/download/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
...@@ -1535,6 +1540,11 @@ array-unique@^0.3.2: ...@@ -1535,6 +1540,11 @@ array-unique@^0.3.2:
resolved "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" resolved "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.npm.taobao.org/arraybuffer.slice/download/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
integrity sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=
asap@~2.0.3: asap@~2.0.3:
version "2.0.6" version "2.0.6"
resolved "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" resolved "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
...@@ -1689,11 +1699,21 @@ babel-runtime@6.x: ...@@ -1689,11 +1699,21 @@ babel-runtime@6.x:
core-js "^2.4.0" core-js "^2.4.0"
regenerator-runtime "^0.11.0" regenerator-runtime "^0.11.0"
backo2@1.0.2:
version "1.0.2"
resolved "https://registry.npm.taobao.org/backo2/download/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
balanced-match@^1.0.0: balanced-match@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-arraybuffer@0.1.5:
version "0.1.5"
resolved "https://registry.npm.taobao.org/base64-arraybuffer/download/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
base64-js@^1.0.2: base64-js@^1.0.2:
version "1.3.1" version "1.3.1"
resolved "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" resolved "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
...@@ -1724,6 +1744,13 @@ bcrypt-pbkdf@^1.0.0: ...@@ -1724,6 +1744,13 @@ bcrypt-pbkdf@^1.0.0:
dependencies: dependencies:
tweetnacl "^0.14.3" tweetnacl "^0.14.3"
better-assert@~1.0.0:
version "1.0.2"
resolved "https://registry.npm.taobao.org/better-assert/download/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522"
integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=
dependencies:
callsite "1.0.0"
bfj@^6.1.1: bfj@^6.1.1:
version "6.1.2" version "6.1.2"
resolved "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" resolved "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f"
...@@ -1761,6 +1788,11 @@ bl@^3.0.0: ...@@ -1761,6 +1788,11 @@ bl@^3.0.0:
dependencies: dependencies:
readable-stream "^3.0.1" readable-stream "^3.0.1"
blob@0.0.5:
version "0.0.5"
resolved "https://registry.npm.taobao.org/blob/download/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
integrity sha1-1oDu7yX4zZGtUz9bAe7UjmTK9oM=
block-stream@*: block-stream@*:
version "0.0.9" version "0.0.9"
resolved "https://registry.npm.taobao.org/block-stream/download/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" resolved "https://registry.npm.taobao.org/block-stream/download/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
...@@ -2057,6 +2089,11 @@ caller-path@^2.0.0: ...@@ -2057,6 +2089,11 @@ caller-path@^2.0.0:
dependencies: dependencies:
caller-callsite "^2.0.0" caller-callsite "^2.0.0"
callsite@1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/callsite/download/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
callsites@^2.0.0: callsites@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.npm.taobao.org/callsites/download/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" resolved "https://registry.npm.taobao.org/callsites/download/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
...@@ -2366,9 +2403,9 @@ code-point-at@^1.0.0: ...@@ -2366,9 +2403,9 @@ code-point-at@^1.0.0:
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.41.0: codemirror@^5.41.0:
version "5.49.2" version "5.50.0"
resolved "https://registry.npm.taobao.org/codemirror/download/codemirror-5.49.2.tgz#c84fdaf11b19803f828b0c67060c7bc6d154ccad" resolved "https://registry.npm.taobao.org/codemirror/download/codemirror-5.50.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcodemirror%2Fdownload%2Fcodemirror-5.50.0.tgz#aeacd18f225735b17cbab98908edace87fedcdab"
integrity sha1-yE/a8RsZgD+CiwxnBgx7xtFUzK0= integrity sha1-rqzRjyJXNbF8urmJCO2s6H/tzas=
collection-visit@^1.0.0: collection-visit@^1.0.0:
version "1.0.0" version "1.0.0"
...@@ -2448,11 +2485,26 @@ commondir@^1.0.1: ...@@ -2448,11 +2485,26 @@ commondir@^1.0.1:
resolved "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" resolved "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
component-bind@1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/component-bind/download/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=
component-emitter@1.2.1:
version "1.2.1"
resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=
component-emitter@^1.2.1: component-emitter@^1.2.1:
version "1.3.0" version "1.3.0"
resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A= integrity sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A=
component-inherit@0.0.3:
version "0.0.3"
resolved "https://registry.npm.taobao.org/component-inherit/download/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=
compressible@~2.0.16: compressible@~2.0.16:
version "2.0.17" version "2.0.17"
resolved "https://registry.npm.taobao.org/compressible/download/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" resolved "https://registry.npm.taobao.org/compressible/download/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1"
...@@ -2941,14 +2993,14 @@ debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: ...@@ -2941,14 +2993,14 @@ debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@3.1.0: debug@3.1.0, debug@~3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" resolved "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE= integrity sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@4, debug@^4.1.0, debug@^4.1.1: debug@4, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0:
version "4.1.1" version "4.1.1"
resolved "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" resolved "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E= integrity sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=
...@@ -3393,6 +3445,34 @@ end-or-error@^1.0.1: ...@@ -3393,6 +3445,34 @@ end-or-error@^1.0.1:
resolved "https://registry.npm.taobao.org/end-or-error/download/end-or-error-1.0.1.tgz#dc7a6210fe78d372fee24a8b4899dbd155414dcb" resolved "https://registry.npm.taobao.org/end-or-error/download/end-or-error-1.0.1.tgz#dc7a6210fe78d372fee24a8b4899dbd155414dcb"
integrity sha1-3HpiEP5403L+4kqLSJnb0VVBTcs= integrity sha1-3HpiEP5403L+4kqLSJnb0VVBTcs=
engine.io-client@~3.4.0:
version "3.4.0"
resolved "https://registry.npm.taobao.org/engine.io-client/download/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700"
integrity sha1-gqZCtChiqbP3oYj0F3ay3qtkNwA=
dependencies:
component-emitter "1.2.1"
component-inherit "0.0.3"
debug "~4.1.0"
engine.io-parser "~2.2.0"
has-cors "1.1.0"
indexof "0.0.1"
parseqs "0.0.5"
parseuri "0.0.5"
ws "~6.1.0"
xmlhttprequest-ssl "~1.5.4"
yeast "0.1.2"
engine.io-parser@~2.2.0:
version "2.2.0"
resolved "https://registry.npm.taobao.org/engine.io-parser/download/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed"
integrity sha1-MSxIlPV9UqArQgho2ntcHISvgO0=
dependencies:
after "0.8.2"
arraybuffer.slice "~0.0.7"
base64-arraybuffer "0.1.5"
blob "0.0.5"
has-binary2 "~1.0.2"
enhanced-resolve@^4.1.0: enhanced-resolve@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.npm.taobao.org/enhanced-resolve/download/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" resolved "https://registry.npm.taobao.org/enhanced-resolve/download/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f"
...@@ -4270,6 +4350,18 @@ has-ansi@^2.0.0: ...@@ -4270,6 +4350,18 @@ has-ansi@^2.0.0:
dependencies: dependencies:
ansi-regex "^2.0.0" ansi-regex "^2.0.0"
has-binary2@~1.0.2:
version "1.0.3"
resolved "https://registry.npm.taobao.org/has-binary2/download/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d"
integrity sha1-d3asYn8+p3JQz8My2rfd9eT10R0=
dependencies:
isarray "2.0.1"
has-cors@1.1.0:
version "1.1.0"
resolved "https://registry.npm.taobao.org/has-cors/download/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39"
integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=
has-flag@^3.0.0: has-flag@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
...@@ -4657,11 +4749,21 @@ indent-string@^2.1.0: ...@@ -4657,11 +4749,21 @@ indent-string@^2.1.0:
dependencies: dependencies:
repeating "^2.0.0" repeating "^2.0.0"
indexdbwrapper@^1.0.4:
version "1.0.4"
resolved "https://registry.npm.taobao.org/indexdbwrapper/download/indexdbwrapper-1.0.4.tgz#a2dce8f7e67d89331e87726636fa67fb472f0b3e"
integrity sha1-otzo9+Z9iTMeh3JmNvpn+0cvCz4=
indexes-of@^1.0.1: indexes-of@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" resolved "https://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
indexof@0.0.1:
version "0.0.1"
resolved "https://registry.npm.taobao.org/indexof/download/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
infer-owner@^1.0.3: infer-owner@^1.0.3:
version "1.0.4" version "1.0.4"
resolved "https://registry.npm.taobao.org/infer-owner/download/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" resolved "https://registry.npm.taobao.org/infer-owner/download/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
...@@ -5118,6 +5220,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: ...@@ -5118,6 +5220,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
isarray@2.0.1:
version "2.0.1"
resolved "https://registry.npm.taobao.org/isarray/download/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=
isexe@^2.0.0: isexe@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" resolved "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
...@@ -6227,6 +6334,11 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: ...@@ -6227,6 +6334,11 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
object-component@0.0.3:
version "0.0.3"
resolved "https://registry.npm.taobao.org/object-component/download/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=
object-copy@^0.1.0: object-copy@^0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.npm.taobao.org/object-copy/download/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" resolved "https://registry.npm.taobao.org/object-copy/download/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
...@@ -6629,6 +6741,20 @@ parse5@^4.0.0: ...@@ -6629,6 +6741,20 @@ parse5@^4.0.0:
resolved "https://registry.npm.taobao.org/parse5/download/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" resolved "https://registry.npm.taobao.org/parse5/download/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
integrity sha1-bXhlbj2o14tOwLkG98CO8d/j9gg= integrity sha1-bXhlbj2o14tOwLkG98CO8d/j9gg=
parseqs@0.0.5:
version "0.0.5"
resolved "https://registry.npm.taobao.org/parseqs/download/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"
integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=
dependencies:
better-assert "~1.0.0"
parseuri@0.0.5:
version "0.0.5"
resolved "https://registry.npm.taobao.org/parseuri/download/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a"
integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=
dependencies:
better-assert "~1.0.0"
parseurl@~1.3.2, parseurl@~1.3.3: parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" resolved "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
...@@ -8332,6 +8458,35 @@ snyk@^1.231.0: ...@@ -8332,6 +8458,35 @@ snyk@^1.231.0:
uuid "^3.3.2" uuid "^3.3.2"
wrap-ansi "^5.1.0" wrap-ansi "^5.1.0"
socket.io-client@^2.3.0:
version "2.3.0"
resolved "https://registry.npm.taobao.org/socket.io-client/download/socket.io-client-2.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsocket.io-client%2Fdownload%2Fsocket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4"
integrity sha1-FNW6LgC5vNFFrkQ6uWs/hsvMG7Q=
dependencies:
backo2 "1.0.2"
base64-arraybuffer "0.1.5"
component-bind "1.0.0"
component-emitter "1.2.1"
debug "~4.1.0"
engine.io-client "~3.4.0"
has-binary2 "~1.0.2"
has-cors "1.1.0"
indexof "0.0.1"
object-component "0.0.3"
parseqs "0.0.5"
parseuri "0.0.5"
socket.io-parser "~3.3.0"
to-array "0.1.4"
socket.io-parser@~3.3.0:
version "3.3.0"
resolved "https://registry.npm.taobao.org/socket.io-parser/download/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f"
integrity sha1-K1KpalCf3zFEC6QP7WCUx9TxJi8=
dependencies:
component-emitter "1.2.1"
debug "~3.1.0"
isarray "2.0.1"
sockjs-client@1.3.0: sockjs-client@1.3.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.npm.taobao.org/sockjs-client/download/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" resolved "https://registry.npm.taobao.org/sockjs-client/download/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177"
...@@ -8957,6 +9112,11 @@ tmp@^0.1.0: ...@@ -8957,6 +9112,11 @@ tmp@^0.1.0:
dependencies: dependencies:
rimraf "^2.6.3" rimraf "^2.6.3"
to-array@0.1.4:
version "0.1.4"
resolved "https://registry.npm.taobao.org/to-array/download/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA=
to-arraybuffer@^1.0.0: to-arraybuffer@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.npm.taobao.org/to-arraybuffer/download/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" resolved "https://registry.npm.taobao.org/to-arraybuffer/download/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
...@@ -9787,6 +9947,13 @@ ws@^6.0.0, ws@^6.2.1: ...@@ -9787,6 +9947,13 @@ ws@^6.0.0, ws@^6.2.1:
dependencies: dependencies:
async-limiter "~1.0.0" async-limiter "~1.0.0"
ws@~6.1.0:
version "6.1.4"
resolved "https://registry.npm.taobao.org/ws/download/ws-6.1.4.tgz?cache=0&sync_timestamp=1576314828024&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fws%2Fdownload%2Fws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9"
integrity sha1-W1yIAK+rkl6UzLKdFTyNAsF3bvk=
dependencies:
async-limiter "~1.0.0"
xdg-basedir@^3.0.0: xdg-basedir@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npm.taobao.org/xdg-basedir/download/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" resolved "https://registry.npm.taobao.org/xdg-basedir/download/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
...@@ -9819,6 +9986,11 @@ xmlbuilder@~9.0.1: ...@@ -9819,6 +9986,11 @@ xmlbuilder@~9.0.1:
resolved "https://registry.npm.taobao.org/xmlbuilder/download/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" resolved "https://registry.npm.taobao.org/xmlbuilder/download/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
xmlhttprequest-ssl@~1.5.4:
version "1.5.5"
resolved "https://registry.npm.taobao.org/xmlhttprequest-ssl/download/xmlhttprequest-ssl-1.5.5.tgz?cache=0&sync_timestamp=1564594466893&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxmlhttprequest-ssl%2Fdownload%2Fxmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
xregexp@2.0.0: xregexp@2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.npm.taobao.org/xregexp/download/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" resolved "https://registry.npm.taobao.org/xregexp/download/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
...@@ -9937,3 +10109,12 @@ yargs@^7.0.0: ...@@ -9937,3 +10109,12 @@ yargs@^7.0.0:
which-module "^1.0.0" which-module "^1.0.0"
y18n "^3.2.1" y18n "^3.2.1"
yargs-parser "^5.0.0" yargs-parser "^5.0.0"
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.npm.taobao.org/yeast/download/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=
"zeroing-code-divider@http://gitlab2.dui88.com/laoqifeng/zeroing-code-divider.git":
version "1.0.0"
resolved "http://gitlab2.dui88.com/laoqifeng/zeroing-code-divider.git#0b495d6ecae34322ad1f553a624cd31b9b4e5931"
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
<module version="4"> <module version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/dist" />
</content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment