Commit 6456ad0f authored by rockyl's avatar rockyl

提交一下

parent 39f9e6a6
......@@ -62,7 +62,11 @@ function execute(document) {
}
return 1;
} else if (layer.name.match(excludeFlagReg)) {
try {
layer.remove();
}catch (e) {
alert('移除图层' + layer.name + '失败,可能含有锁的层');
}
return 2;
}
return 0;
......
......@@ -4,7 +4,7 @@
"scripts": {
"serve": "vue-cli-service serve",
"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",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
},
......@@ -13,10 +13,12 @@
"copy-to-clipboard": "^3.2.0",
"core-js": "^2.6.5",
"element-ui": "^2.4.5",
"indexdbwrapper": "^1.0.4",
"jszip": "^3.2.2",
"moment": "^2.24.0",
"path": "^0.12.7",
"querystringify": "^2.1.1",
"socket.io-client": "^2.3.0",
"splitpanes": "^1.14.5",
"string-width": "^4.1.0",
"uuid": "^3.3.3",
......@@ -24,7 +26,8 @@
"vue-codemirror": "^4.0.6",
"vue-i18n": "^8.0.0",
"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": {
"@kazupon/vue-i18n-loader": "^0.3.0",
......
......@@ -6,6 +6,9 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<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>
<body>
<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 {
methods: {
drop(e) {
if (this.$store.state.project.dragUUID) {
// debugger;
console.log('native drop', this.$store.state);
this.swvalue = `asset://${this.$store.state.project.dragUUID}`
}
......
......@@ -18,6 +18,7 @@
"Add": "Add",
"Delete": "Delete",
"Delete all": "Delete all",
"Not delete": "Not delete",
"Import": "Import",
"Export": "Export",
"Importing project": "Importing project",
......@@ -28,13 +29,20 @@
"EditEnv": "EditEnv",
"EditCustomModule": "EditCustomModule",
"Script": "Script",
"CodeSyncServe": "CodeSyncServe",
"ID": "ID",
"Mock Editor": "Mock Editor",
"Enable mock serve": "Enable mock serve",
"Name": "Name",
"Alias": "Alias",
"Output": "Output",
"Code": "Code",
"Desc": "Desc",
"Empty": "Empty",
"Path": "Path",
"Timeout": "Timeout",
"SuccessRatio": "SuccessRatio",
"Data": "Data",
"Key": "Key",
"Default": "Default",
"Event": "Event",
......@@ -147,9 +155,9 @@
"menu": {
"save": "Save",
"details": "Details",
"preview": "Preview",
"preview2": "Fast-Preview",
"preview-fast": "Preview",
"publish": "Publish",
"mock": "Mock",
"exit": "Exit",
"undo": "Undo",
"redo": "Redo"
......@@ -159,7 +167,8 @@
"image": "Image",
"label": "Label",
"rect": "Rect",
"scrollView": "ScrollView"
"scrollView": "ScrollView",
"svga": "SVGA"
},
"panes": {
"Assets": "Assets",
......
......@@ -18,6 +18,7 @@
"Add": "添加",
"Delete": "删除",
"Delete all": "删除全部",
"Not delete": "不删除",
"Import": "导入",
"Export": "导出",
"Importing project": "项目导入中",
......@@ -28,13 +29,20 @@
"EditEnv": "编辑环境",
"EditCustomModule": "编辑自定义模块",
"Script": "脚本",
"CodeSyncServe": "代码同步服务",
"ID": "ID",
"Mock Editor": "Mock编辑器",
"Enable mock serve": "启用Mock服务",
"Name": "名字",
"Alias": "别名",
"Output": "输出",
"Code": "代码",
"Desc": "描述",
"Empty": "空",
"Path": "路径",
"Timeout": "超时(ms)",
"SuccessRatio": "成功率",
"Data": "数据",
"Key": "属性名",
"Default": "默认值",
"Event": "事件",
......@@ -151,9 +159,9 @@
"menu": {
"save": "保存",
"details": "详情",
"preview": "预览",
"preview2": "快速预览",
"preview-fast": "预览",
"publish": "发布",
"mock": "Mock",
"exit": "退出",
"undo": "撤销",
"redo": "重做"
......@@ -165,7 +173,8 @@
"rect": "矩形",
"circle": "圆形",
"textinput": "输入框",
"scrollView": "滚动视图"
"scrollView": "滚动视图",
"svga": "SVGA"
},
"panes": {
"Assets": "素材",
......
......@@ -39,15 +39,10 @@ export default new Vuex.Store({
'modifyAsset',
'importView',
'importAssets',
'addDataMapping',
'deleteDataMapping',
'modifyDataMapping',
'addEnvMapping',
'deleteEnvMapping',
'modifyEnvMapping',
'modifyActiveView',
'behavior_save',
'modifyCustoms',
'modifyProjectDetails',
'modifyMocks',
]
})
]
......
......@@ -64,7 +64,6 @@ export const behaviorStore = {
state.processStack.push(process);
updatePropsEditable(state);
state.currentProcess = process;
console.log(state.currentProcess);
},
popProcessStack(state, index) {
state.processStack.splice(index);
......
......@@ -7,6 +7,8 @@
import {envApi} from "../../api";
import i18n from "../../i18n";
const storeKey = 'code-sync-serve-config';
export const envStore = {
state: {
initialized: false,
......@@ -19,6 +21,10 @@ export const envStore = {
processes: [],
scripts: [],
customs: [],
codeSyncServeConfig: {
ip: 'localhost',
port: 7788,
}
},
mutations: {
updateEnv(state, env) {
......@@ -28,6 +34,15 @@ export const envStore = {
state.customs = parseItem(state.customs);
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: {
......@@ -77,7 +92,7 @@ export const envStore = {
const env = await envApi.fetchEnv();
commit('updateEnv', env);
}
}
},
}
};
......
......@@ -3,17 +3,22 @@
*/
import Vue from "vue";
import JSZip from "jszip";
import { projectApi } from "../../api";
import {projectApi} from "../../api";
import path from "path";
import generateUUID from "uuid/v4";
import { getCmpProps, flattenViews, getCmpByUUID } from '../../utils/common';
import { clonePureObj, saveAs } from "../../utils";
import { template } from "../../template";
import { importView, uploadFile } from "../../api/project";
import {getCmpProps, flattenViews, getCmpByUUID} from '../../utils/common';
import {clonePureObj, getMockServeEnabled, saveAs} from "../../utils";
import {template} from "../../template";
import {importView, uploadFile} from "../../api/project";
import events from "@/global-events";
import {packImages} from "../../utils/sheet-pack";
import {addBehavior, deleteProcessMeta, findProcess} from "./behavior";
import db from "../../utils/db-storage";
import {preprocess} from "../../views/Preview/preview-preprocess";
const storeName = 'project';
const defaultOptions = {
pageTitle: 'no title',
entrySceneView: '',
......@@ -25,8 +30,8 @@ const defaultOptions = {
rendererType: 'webgl',
tpl: template,
env: [
{ name: 'appID', value: '' },
{ name: 'projectID', value: '' },
{name: 'appID', value: ''},
{name: 'projectID', value: ''},
],
};
......@@ -36,33 +41,33 @@ function getDefaultOptions() {
return clonePureObj(defaultOptions);
}
function setUUIDForAllChildren(node){
if(node.children&&node.children.length>0){
for(let i=0 ;i<node.children.length;i++){
node.children[i]=copyBaseRoot(node.children[i])
function setUUIDForAllChildren(node) {
if (node.children && node.children.length > 0) {
for (let i = 0; i < node.children.length; i++) {
node.children[i] = copyBaseRoot(node.children[i])
setUUIDForAllChildren(node.children[i])
}
}
}
let copyNodeCatch=null;
let copyNodeCatch = null;
function copyBaseRoot(node){
let _node=JSON.parse(JSON.stringify(node));
function copyBaseRoot(node) {
let _node = JSON.parse(JSON.stringify(node));
let data
let data;
if(_node.children&&_node.children.length>0){
data={
if (_node.children && _node.children.length > 0) {
data = {
name: _node.name,
type: _node.type,
properties: _node.properties,
events: _node.events,
uuid: generateUUID(),
children:_node.children
children: _node.children
};
}else{
data={
} else {
data = {
name: _node.name,
type: _node.type,
properties: _node.properties,
......@@ -85,7 +90,9 @@ export const projectStore = {
dataMapping: [],
processes: [],
customs: [],
mock: [],
},
mockServeEnabled: false,
activeComponent: {},
activeComponentCopy: {}, // 当前选中节点的镜像,用来处理拖拽时数据变化频繁的问题
activeIdList: [],
......@@ -100,14 +107,14 @@ export const projectStore = {
state.dirty = dirty;
},
updateProject(state, project) {
const { id, name, creator, data } = project;
const {id, name, creator, data} = project;
state.id = id;
state.name = name;
state.creator = creator;
const localData = state.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, 'views', views || []);
......@@ -115,6 +122,7 @@ export const projectStore = {
Vue.set(localData, 'dataMapping', dataMapping || []);
Vue.set(localData, 'processes', processes || []);
Vue.set(localData, 'customs', customs || []);
Vue.set(localData, 'mock', mock || []);
} else {
Vue.set(localData, 'options', getDefaultOptions());
Vue.set(localData, 'views', []);
......@@ -122,7 +130,26 @@ export const projectStore = {
Vue.set(localData, 'dataMapping', []);
Vue.set(localData, 'processes', []);
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 = {
modifyProject(state) {
},
addNode(state, { node, name, type }) {
addNode(state, {node, name, type}) {
const child = {
name,
type,
......@@ -314,16 +341,16 @@ export const projectStore = {
importView(state, view) {
state.data.views.push(view);
},
deleteNode(state, { node, parentNode }) {
deleteNode(state, {node, parentNode}) {
const parentChildren = parentNode.children || parentNode;
const index = parentChildren.indexOf(node);
parentChildren.splice(index, 1);
},
copyNode(state, { node, parentNode }) {
let _node1=node
copyNodeCatch=_node1;
copyNode(state, {node, parentNode}) {
let _node1 = node
copyNodeCatch = _node1;
//localStorage.copyNodeCatch=_node1;
// let _node=copyBaseRoot(_node1);
// setUUIDForAllChildren(_node)
......@@ -336,16 +363,16 @@ export const projectStore = {
// state.data.views.push(_node);
// }
},
pasteNode(state, { node, parentNode,pasteState}) {
let _node1=copyNodeCatch;
pasteNode(state, {node, parentNode, pasteState}) {
let _node1 = copyNodeCatch;
console.log(copyNodeCatch)
if(_node1){
let _node=copyBaseRoot(_node1);
if (_node1) {
let _node = copyBaseRoot(_node1);
setUUIDForAllChildren(_node)
if(pasteState==1){
parentNode=parentNode;
}else{
parentNode=node;
if (pasteState == 1) {
parentNode = parentNode;
} else {
parentNode = node;
}
if (parentNode) {
if (!parentNode.children) {
......@@ -355,14 +382,14 @@ export const projectStore = {
} else {
state.data.views.push(_node);
}
}else{
} else {
console.warn("请先选择一个节点进行复制")
}
},
importAssets(state, assets) {
state.data.assets.push(...assets);
},
addAsset(state, { url, file }) {
addAsset(state, {url, file}) {
const ext = path.extname(file.name);
state.data.assets.push({
name: path.basename(file.name, ext),
......@@ -379,7 +406,7 @@ export const projectStore = {
}
},
deleteAsset(state, uuid) {
const { assets } = state.data;
const {assets} = state.data;
for (let i = 0, li = assets.length; i < li; i++) {
const asset = state.data.assets[i];
if (asset.uuid === uuid) {
......@@ -389,61 +416,26 @@ export const projectStore = {
}
},
deleteAllAssets(state) {
const { assets } = state.data;
const {assets} = state.data;
assets.splice(0);
},
modifyAsset(state, asset) {
},
addDataMapping(state, link) {
if (link) {
state.data.dataMapping.push(link);
} else {
state.data.dataMapping.push({
name: '',
path: '',
});
}
},
deleteDataMapping(state, index) {
state.data.dataMapping.splice(index, 1);
},
modifyDataMapping(state) {
modifyMocks(state, mocks) {
state.data.mock = mocks;
updateMock(mocks);
},
addEnvMapping(state, link) {
if (!state.data.options.env) {
Vue.set(state.data.options, 'env', []);
setMockServeEnabled(state, enabled){
state.mockServeEnabled = enabled;
}
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: {
project(state) {
const { id, name, creator, data } = state;
const {id, name, creator, data} = state;
return {
id, name, creator,
data: JSON.stringify(data),
......@@ -514,29 +506,33 @@ export const projectStore = {
},
},
actions: {
saveToLocal({ getters, commit }) {
const { project } = getters;
async saveToLocal({getters, commit}) {
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);
},
localVersionExist({ commit }, projectID) {
let json = localStorage.getItem('project-' + projectID);
async localVersionExist({commit}, projectID) {
let json = await db.get(storeName, projectID);
//let json = localStorage.getItem('project-' + projectID);
return !!json;
},
loadFromLocal({ commit }, projectID) {
let json = localStorage.getItem('project-' + projectID);
async loadFromLocal({commit}, projectID) {
let json = await db.get(storeName, projectID);
//let json = localStorage.getItem('project-' + projectID);
if (json) {
const project = JSON.parse(json);
const project = JSON.parse(json.data);
commit('updateProject', project);
commit('setDirty', true);
}
},
deleteLocalVersion({ state, commit }, projectID) {
localStorage.removeItem('project-' + projectID);
async deleteLocalVersion({state, commit}, projectID) {
await db.remove(storeName, projectID);
//localStorage.removeItem('project-' + projectID);
commit('setDirty', false);
},
async loadFromRemote({ commit, dispatch }, projectID) {
async loadFromRemote({commit, dispatch}, projectID) {
const project = await projectApi.fetchOne(projectID);
if (project) {
dispatch('deleteLocalVersion', projectID);
......@@ -545,11 +541,11 @@ export const projectStore = {
throw new Error('Project does not exist')
}
},
async saveToRemote({ state, dispatch, getters }) {
async saveToRemote({state, dispatch, getters}) {
await projectApi.saveOne(getters.project);
dispatch('deleteLocalVersion', state.id);
},
async updateProject({ commit }, projectID) {
async updateProject({commit}, projectID) {
const project = await projectApi.getData(projectID);
commit('updateProject', project);
},
......@@ -581,7 +577,7 @@ export const projectStore = {
/**
* 修改属性
*/
modifyProperties({ commit, state, getters }, props) {
modifyProperties({commit, state, getters}, props) {
// debugger;
// 如果当前修改的是“来源”属性,节点又没有高度宽度,则取图片的高度宽度
let _props = _.cloneDeep(state.activeComponent.properties);
......@@ -609,6 +605,9 @@ export const projectStore = {
});
}
}
} else {
delete _props.imageWidth;
delete _props.imageHeight;
}
commit('modifyActiveView', {
......@@ -620,13 +619,13 @@ export const projectStore = {
* @param {*} param0
* @param {*} props
*/
modifyCopyProperties({ commit }, props) {
modifyCopyProperties({commit}, props) {
commit('modifyCopyProperties', props)
},
/**
* 修改当前选中的节点
*/
modifyActiveView({ commit }, view) {
modifyActiveView({commit}, view) {
commit('modifyActiveView', view)
},
/**
......@@ -634,7 +633,7 @@ export const projectStore = {
* @param {*} param0
* @param {*} script
*/
addNodeScript({ commit, state }, script) {
addNodeScript({commit, state}, script) {
let _scripts = _.cloneDeep(state.activeComponent.scripts || []);
_scripts.push({
script: script,
......@@ -644,8 +643,8 @@ export const projectStore = {
scripts: _scripts
})
},
async importView({ commit }, { file, action }) {
const { view, assets } = await importView(file);
async importView({commit}, {file, action}) {
const {view, assets} = await importView(file);
switch (action) {
case 0: //单视图
view.name = file.name.substring(0, file.name.lastIndexOf('.'));
......@@ -659,18 +658,18 @@ export const projectStore = {
}
commit('importAssets', assets);
},
exportView({ state }, view) {
exportView({state}, view) {
let zip = new JSZip();
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`);
});
},
async uploadFiles({commit}, files) {
const {failedList, result} = await uploadFiles(files);
for (let item of result) {
const { url, __originFile } = item;
commit('addAsset', { url, file: __originFile });
const {url, __originFile} = item;
commit('addAsset', {url, file: __originFile});
}
return failedList;
},
......@@ -692,12 +691,14 @@ export const projectStore = {
const {project} = getters;
const {processes, scripts, customs} = rootState.env;
const data = {
/*const data = {
processes, scripts, customs,
data: state.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}) {
......@@ -707,10 +708,15 @@ export const projectStore = {
deleteBehaviorDirect({state}, {behaviors, index, deleteMeta}) {
let behavior = behaviors.splice(index, 1)[0];
if(deleteMeta){
if (deleteMeta) {
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) {
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 = {
state.projectCount = projectCount;
},
addProject(state, project) {
state.unshift(project);
state.projects.unshift(project);
},
deleteProject(state, projectID) {
for (let i = 0, li = state.length; i < li; i++) {
const item = state[i];
const {projects} = state;
for (let i = 0, li = projects.length; i < li; i++) {
const item = projects[i];
if (item.id === projectID) {
state.splice(i, 1);
projects.splice(i, 1);
break;
}
}
......
......@@ -3,7 +3,7 @@
*/
export const template =
`<!DOCTYPE html>
`<!DOCTYPE html>
<html lang="en">
<head>
......@@ -28,13 +28,13 @@ content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, u
overflow: hidden;
position: absolute;
background-color: white;
}
</style>
}
</style>
</head>
<body>
<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$
<script>
engine.launch('//yun.duiba.com.cn/aurora/$VERSION$-data.json');
......
......@@ -2,16 +2,7 @@
$dock-pin-width: 9px;
.behavior-editor-dialog {
display: flex;
flex-direction: column;
.el-dialog__body {
flex: 1;
height: 0;
padding: 5px;
}
.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 @@
@import "views";
@import "assets";
@import "behavior";
@import "bottom-bar";
.editor {
display: flex;
......@@ -25,10 +26,6 @@
}
}
.file-upload-indicator{
color: $--color-text-secondary;
}
.right-part {
color: $--color-text-regular;
line-height: 15px;
......@@ -57,11 +54,11 @@
align-self: flex-start;
}
.bottom-bar{
.bottom-bar {
align-self: flex-end;
}
.list{
.list {
display: flex;
flex-direction: column;
flex: 1;
......@@ -101,28 +98,76 @@
}
.details-dialog {
.operate-bar{
.operate-bar {
display: flex;
justify-content: flex-end;
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 {
height: 40vh;
height: 100%;
.view {
padding-right: 10px;
.custom-module-list{
.custom-module-list {
display: flex;
flex-direction: column;
.item + .item {
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.
*/
@import "./var.scss";
@import "./base.scss";
@import "./home.scss";
@import "./editor.scss";
@import "./playground.scss";
@import "./inspector.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 {
background: transparent;
}
......@@ -23,15 +32,18 @@
overflow-y: hidden;
}
.el-tree-node__content > .el-tree-node__expand-icon{
.el-tree-node__content > .el-tree-node__expand-icon {
padding: 6px 0;
}
.el-input-number.is-without-controls .el-input__inner{
padding: 0 5px;
}
.el-input__inner {
padding: 0 5px;
}
.el-input--suffix .el-input__inner{
.el-input--suffix .el-input__inner {
padding-right: 5px;
}
......@@ -43,13 +55,13 @@
height: 100%;
}
.el-tabs--border-card > .el-tabs__content{
.el-tabs--border-card > .el-tabs__content {
padding: 5px 0 5px 5px;
}
.el-input-number.is-controls-right .el-input__inner {
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 {
......
......@@ -13,6 +13,7 @@
.el-collapse-item__header{
height: 25px;
line-height: 25px;
}
.el-tabs__item {
......@@ -67,7 +68,7 @@
}
.el-button + .el-button {
margin-left: 2px;
margin-left: 5px;
}
.trigger-list{
......
......@@ -30,6 +30,10 @@ export const componentsMap = [
label: '滚动视图',
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) {
messageError(e);
throw e;
}).finally(() => {
if(closeLoading){
if (closeLoading) {
loading.close();
}
})
......@@ -59,7 +59,7 @@ export function updateProcesses(processes, targetMetaID, replaceMetaID) {
subProcess.meta = replaceMetaID;
}
}
if(process.metas){
if (process.metas) {
updateProcesses(process.metas, targetMetaID, replaceMetaID)
}
}
......@@ -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');
input.type = 'file';
input.onchange = function (e) {
callback(input.files);
};
if(acceptDirectory){
input.webkitdirectory = true;
}
if (accept) {
input.accept = accept;
}
......@@ -131,14 +158,26 @@ export function selectFile(callback, {accept, multiple} = {}) {
input.click();
}
export function openPreview(packResult){
export function openPreview(packResult) {
setTimeout(() => {
let url;
if(location.host.startsWith('localhost')){
if (location.host.startsWith('localhost')) {
url = packResult.tplUrl;
}else{
} else {
url = '/preview?url=http:' + packResult.tplUrl;
}
window.open(url, 'blank');
}, 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 {
type: 'textArea',
value: ''
},
type: {
title: '输入类型',
type: 'select',
options: [
{ label: '文本', value: 'text' },
{ label: '密码', value: 'password' },
],
value: 'text'
},
pattern: {
title: '输入模式',
type: 'input',
value: ''
},
fillColor: {
title: '颜色',
type: 'colorPicker',
......@@ -234,7 +248,7 @@ export default {
},
},
image: {
groupName: '来源',
groupName: '图片',
source: {
title: '来源',
type: 'source',
......@@ -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: {
groupName: '矩形',
fillColor: {
......
......@@ -3,6 +3,7 @@
*/
import MaxRectsBinPack from "./MaxRectsBinPack";
import {clonePureObj} from "./index";
const packExts = ['.png']; //, '.jpg', '.jpeg', '.bmp'
......@@ -83,7 +84,7 @@ export async function packImages(asssts, options = {}) {
};
for (let asset of rect.assets) {
frames[asset.uuid] = sprite;
frames[asset.uuid] = Object.assign({}, sprite, {name: asset.name});
i++;
}
}
......
......@@ -11,13 +11,16 @@
</split-panes>
<inspector splitpanes-min="20" :splitpanes-size="getSize(0, 1)"></inspector>
</split-panes>
<bottom-bar/>
<details-dialog ref="dialogsDialog"/>
<pack-result-dialog ref="packResultDialog"/>
<mock-editor-dialog ref="mockEditorDialog"/>
<code-sync-serve-dialog ref="codeSyncServeDialog"/>
</div>
</template>
<script>
import {mapGetters, mapActions} from 'vuex'
import {mapState, mapActions} from 'vuex'
import SplitPanes from 'splitpanes'
import ToolBar from "./Editor/ToolBar";
import Inspector from "./Editor/Inspector";
......@@ -29,10 +32,19 @@
import i18n from "../i18n";
import PackResultDialog from "./Editor/dialogs/PackResultDialog";
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 {
name: 'Editor',
components: {
CodeSyncServeDialog,
BottomBar,
MockEditorDialog,
PackResultDialog,
DetailsDialog,
Assets,
......@@ -59,29 +71,39 @@
}
},
computed: {
...mapGetters([]),
...mapState({
codeSyncServeConfig(state) {
return state.env.codeSyncServeConfig;
},
}),
},
async mounted() {
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 => {
});
setTimeout(() => {
startCodeSyncServe(this.codeSyncServeConfig);
}, 100);
this.loadProject();
},
destroyed() {
document.removeEventListener('keydown', this.onKeyPress)
},
created() {
events.$on('saveAndPreview', () => {
this.clickMenu("preview");
});
},
methods: {
prepare() {
return Promise.all([
this.updateEnv(),
db.open('store'),
])
},
onKeyPress(e) {
......@@ -166,14 +188,18 @@
this.$refs.dialogsDialog.show();
break;
case 'preview':
this.preview();
await this.pack(true);
break;
case 'preview2':
case 'preview-fast':
this.preview();
break;
case 'publish':
await this.publish();
break;
case 'mock':
this.$refs.mockEditorDialog.show();
break;
case 'undo':
this.$store.commit('undoRedo', 1);
break;
......@@ -202,7 +228,7 @@
break;
}
},
async publish(){
async publish() {
this.pack();
},
async pack(debug = false) {
......@@ -211,7 +237,7 @@
text: this.$t('Packing'),
});
try {
if(!debug){
if (!debug) {
await this.saveProject(false);
}
const packResult = await this.packProject(debug);
......@@ -257,7 +283,7 @@
let previewUrl = new URL(location.href);
previewUrl.hash = '#/preview/' + projectID;
setTimeout(()=>{
setTimeout(() => {
window.open(previewUrl.href, 'blank');
}, 300);
},
......
......@@ -23,7 +23,7 @@
<el-scrollbar class="assets-scrollbar" wrap-class="wrap-x-hidden"
view-class="scrollbar-view">
<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>
</div>
<file-item v-for="(asset, index) in assets" :data="asset" :key="index" @show-file-details="showFileDetails"
......@@ -42,7 +42,7 @@
import FileItem from "./Assets/FileItem";
import AssetsShow from "./Assets/AssetsShow";
import SplitPanes from 'splitpanes'
import {selectFile} from "../../utils";
import {scanFiles, selectFile} from "../../utils";
export default {
name: "Assets",
......@@ -68,6 +68,23 @@
this.uploadFiles(files);
}, {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) {
this.$refs.assetsShow.show(file);
},
......
<template>
<div class="file-item" @click="$emit('click', $event)">
<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"
alt="thumb" @dblclick="onDbclick()">
<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 @@
<el-tab-pane :label="$t('Props')" name="properties">
<props-tab/>
</el-tab-pane>
<el-tab-pane :label="$t('Script')" name="script">
<scripts-tab/>
</el-tab-pane>
<el-tab-pane :label="$t('Behavior')" name="behavior">
<behavior-tab/>
</el-tab-pane>
......@@ -15,10 +18,11 @@
import Pane from '../../components/Pane';
import BehaviorTab from "./Inspector/BehaviorTab";
import PropsTab from "./Inspector/PropsTab";
import ScriptsTab from "./Inspector/ScriptsTab";
export default {
name: 'Inspector',
components: {BehaviorTab, PropsTab, Pane},
components: {ScriptsTab, BehaviorTab, PropsTab, Pane},
data() {
return {
tab: 'properties'
......
......@@ -147,28 +147,32 @@
},
handleBehaviorsChange(isPreview) {
if (isPreview) {
events.$emit('saveAndPreview')
events.$emit('save-and-preview')
}
},
async deleteBehavior(index, behaviors) {
let deleteMeta = false;
let close;
await this.$confirm(this.$t('Are you sure to delete it\'s process'), this.$t('Alert'), {
showClose: false,
closeOnClickModal: false,
closeOnPressEscape: false,
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
confirmButtonText: this.$t('Delete'),
cancelButtonText: this.$t('Not delete'),
distinguishCancelAndClose: true,
type: 'warning'
}).then(() => {
deleteMeta = true;
}).catch((e) => {
}).catch(action => {
if(action === 'close'){
close = true;
}
});
if(!close){
this.deleteBehaviorDirect({
behaviors,
index,
deleteMeta,
})
}
},
...mapActions([
'modifyActiveView',
......
......@@ -2,8 +2,6 @@
<div class="zero-inspector-props-form" v-if="activeComponent.uuid">
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden">
<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-input v-model="form.name" @input="v => handleChange('name', v)"></el-input>
</el-form-item>
......@@ -23,32 +21,6 @@
</el-tooltip>
</el-form-item>
</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-scrollbar>
</div>
......@@ -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 {
name: 'PropsTab',
components: { 'dynamic-component': dynamicComponent },
......@@ -150,18 +92,11 @@ export default {
name: '',
type: '',
properties: {},
scripts: []
},
configColl: ['properties']
};
},
computed: {
...mapGetters(['activeComponent', 'activeComponentCopy', 'componentList']),
...mapState({
scripts(state){
return state.env.scripts;
}
}),
cmpProps: function() {
// 获取properties.js中的默认配置
return getCmpProps(this.activeComponent.type);
......@@ -183,13 +118,6 @@ export default {
_view[label] = v;
this.$store.dispatch('modifyActiveView', _view);
},
/**
* 脚本预设对象选中
*/
handleAddScript(command) {
console.log('handleAddScript', command);
this.$store.dispatch('addNodeScript', command);
},
/**
* 基础属性发生改变
*/
......@@ -200,20 +128,6 @@ export default {
_prop[key] = v;
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 {
let _properties = this.activeComponentCopy.properties;
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>
......
<template>
<div class="zero-inspector-script-form" v-if="activeComponent.uuid">
<el-collapse v-model="configColl">
<el-collapse-item title="配置" name="properties">
<div class="zero-inspector-props-form" v-if="activeComponent.uuid">
<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-item label="名称">
<el-input v-model="form.name" @input="v => handleChange('name', v)"></el-input>
</el-form-item>
<el-form-item label="类型">
<el-select v-model="form.type" @change="v => handleChange('type', v)" placeholder="请选择类型">
<el-option v-for="cmp in componentsMap" :key="cmp.value" :label="cmp.label" :value="cmp.value"></el-option>
</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-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>
</el-collapse-item>
<el-collapse-item title="脚本" name="scripts">
<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-form>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { mapGetters, mapState } from 'vuex';
import _ from 'lodash';
import { componentsMap, getCmpProps } from '../../../utils/common';
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 {
name: 'PropsTab',
name: 'ScriptsTab',
components: { 'dynamic-component': dynamicComponent },
data() {
return {
componentsMap,
form: {
name: '',
type: '',
properties: {}
scripts: []
},
configColl: ['properties']
};
},
computed: {
...mapGetters(['activeComponent', 'componentList']),
cmpProps: function() {
return getCmpProps(this.activeComponent.type);
...mapGetters(['activeComponent', 'activeComponentCopy', 'componentList']),
...mapState({
scripts(state){
return state.env.scripts;
}
}),
},
watch: {
activeComponent: {
deep: true,
handler: function(val) {
this.form.name = val.name || '';
this.form.type = val.type || '';
this.form.properties = val.properties || {};
methods: {
/**
* 脚本预设对象选中
*/
handleAddScript(command) {
console.log('handleAddScript', command);
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: {
handleChange(label, v) {
this.$store.dispatch('modifyComponent', {
label: label,
value: v
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
});
}
}
......@@ -72,14 +167,17 @@ export default {
</script>
<style lang="scss">
.zero-inspector-script-form {
.zero-inspector-props-form {
width: 100%;
padding-right: 10px;
.el-form-item--mini.el-form-item {
margin-bottom: 10px;
}
.el-divider__text {
background-color: #e9e9e9;
}
.zero-inspector-props-group {
max-height: 500px;
}
}
.script-config-dialog {
height: 350px;
}
</style>
\ No newline at end of file
<template>
<div class="tool-bar">
<sample-menu :data="menu" @click-menu="clickMenu"/>
<upload-indicator/>
<div style="flex: 1"></div>
<div class="right-part">
<span>
......@@ -15,11 +14,10 @@
<script>
import {mapState, mapActions, mapMutations} from 'vuex'
import SampleMenu from "../../components/SampleMenu";
import UploadIndicator from "./ToolBar/UploadIndicator";
export default {
name: "ToolBar",
components: {UploadIndicator, SampleMenu},
components: {SampleMenu},
data() {
return {}
},
......@@ -45,7 +43,7 @@
async mounted() {
//监听键盘事件
document.addEventListener('keydown', this.onKeyPress);
//document.addEventListener('keydown', this.onKeyPress);
},
methods: {
clickMenu(menuItem) {
......
......@@ -5,10 +5,11 @@
:show-close="false"
fullscreen
:append-to-body="true"
custom-class="behavior-editor-dialog"
custom-class="flex-dialog behavior-editor-dialog"
>
<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>
<el-form-item prop="id" :label="$t('ID')">
<el-input v-model="meta.id" :placeholder="$t('ID')" :readonly="!editable"/>
......@@ -42,6 +43,7 @@
</template>
</el-form>
<div style="margin-top: 5px;">
<code-sync-indicator/>
<el-tag v-for="(item, key) in exposeVariables" :key="key" size="mini">{{item}}</el-tag>
</div>
<!--<el-input v-if="meta" class="script-editor" :readonly=" !editable" type="textarea" :placeholder="$t('Code')"
......@@ -49,10 +51,7 @@
<codemirror ref="codeEditor" v-if="meta"
v-model="meta.script"
:options="cmOptions"
@cursorActivity="onCodeChange"
>
</codemirror>
@cursorActivity="onCodeChange"/>
</div>
<div slot="footer" class="dialog-footer">
<div class="button-bar">
......@@ -64,7 +63,7 @@
</el-popover>
</el-button-group>
<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>
</div>
</div>
......@@ -85,14 +84,17 @@
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/show-hint.css'
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'];
export default {
name: "MetaEditorDialog",
components: {PropsEditorDialog, ElFormItem, codemirror},
components: {CodeSyncIndicator, PropsEditorDialog, ElFormItem, codemirror},
data() {
return {
visible: false,
......@@ -102,26 +104,35 @@
rules: {
id: [
{ required: true, trigger: 'blur' },
{required: true, trigger: 'blur'},
],
name: [
{ required: true, trigger: 'blur' }
{required: true, trigger: 'blur'}
],
},
cmOptions: {
tabSize: 2,
mode: 'text/javascript',
styleActiveLine: true,
theme: 'default',
lineNumbers: true,
line: true,
matchBrackets: 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: {
editable() {
......@@ -136,6 +147,11 @@
this.visible = true;
this.meta = clonePureObj(meta);
this.oldMetaID = this.meta.id;
events.$emit('edit-open', this.meta.script);
},
onEditSave(code){
this.$set(this.meta, 'script', code);
},
onClickEditProps() {
this.$refs.propsEditorDialog.edit(this.meta.props);
......@@ -148,8 +164,8 @@
.catch((e) => {
});
} else {
this.$emit('input',this.meta,isPreview);
this.visible=false;
this.$emit('input', this.meta, isPreview);
this.visible = false;
}
} else {
return false;
......@@ -167,19 +183,19 @@
},
onPaste(e) {
let metaStr = e.clipboardData.getData("Text");
if(metaStr){
if (metaStr) {
try {
let meta = JSON.parse(metaStr);
this.meta = meta;
}catch (e) {
} catch (e) {
}
}
},
focusPasteBoard(){
focusPasteBoard() {
this.$refs.pasteBoard.focus();
},
onCodeChange(codemirror){
onCodeChange(codemirror) {
//codemirror.showHint();
//console.log(code);
}
......
<template>
<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"
: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>
<div slot="footer" class="dialog-footer">
<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>
<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"
:append-to-body="true"
:show-close="false"
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">
<project-editor/>
<project-editor ref="projectEditor"/>
</el-tab-pane>
<el-tab-pane :label="$t('Env constant')" name="env">
<env-editor/>
<env-editor ref="envEditor"/>
</el-tab-pane>
<el-tab-pane :label="$t('Data mapping')" name="data-mapping">
<data-mapping-editor/>
<data-mapping-editor ref="dataMappingEditor"/>
</el-tab-pane>
<el-tab-pane :label="$t('Custom module')" name="custom">
<custom-editor/>
<custom-editor ref="customEditor"/>
</el-tab-pane>
</el-tabs>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="onClose">{{$t('Close')}}</el-button>
<el-button size="mini" @click="onSave" type="primary">{{$t('Save')}}</el-button>
</div>
</el-dialog>
</template>
<script>
import {mapMutations} from 'vuex';
import ProjectEditor from "./editors/ProjectEditor";
import EnvEditor from "./editors/EnvEditor";
import CustomEditor from "./editors/CustomEditor";
import DataMappingEditor from "./editors/DataMappingEditor";
const refs = [
'projectEditor',
'envEditor',
'dataMappingEditor',
'customEditor',
];
export default {
name: "DetailsDialog",
components: {DataMappingEditor, CustomEditor, EnvEditor, ProjectEditor},
......@@ -45,12 +54,24 @@
show() {
this.visible = true;
},
onSave() {
for (let ref of refs) {
this.$refs[ref].save();
}
this.visible = false;
this.modifyProjectDetails();
},
onClose() {
this.visible = false;
},
onOpen() {
for (let ref of refs) {
this.$refs[ref].edit();
}
},
...mapMutations([
'modifyProjectDetails',
]),
}
}
</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>
<el-scrollbar class="scrollbar" wrap-class="wrap-x-hidden" view-class="view">
<el-checkbox-group :value="customs" class="custom-module-list" @input="onChange">
<el-checkbox class="item" v-for="customMeta in customMetas" :key="customMeta.id" :label="customMeta.id">
{{customMeta.alias || customMeta.name}}
</el-checkbox>
</el-checkbox-group>
</el-scrollbar>
<el-table v-if="editData" :data="customMetas" stripe height="100%">
<el-table-column
width="40"
>
<template slot-scope="scope">
<el-checkbox v-model="scope.row.selected"/>
</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>
<script>
import {mapState, mapMutations} from 'vuex'
import {clonePureObj} from "../../../../utils";
export default {
name: "CustomEditor",
data() {
return {
visible: false,
customMetas: [],
editData: null,
}
},
computed: {
...mapState({
customMetas: state => state.env.customs,
customs: state => state.project.data.customs,
}),
},
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([
'modifyCustoms',
]),
onChange(v){
this.modifyCustoms(v);
}
}
}
</script>
......
<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">
<el-button class="add-button" icon="el-icon-plus" size="mini" circle @click="onAdd"/>
<div class="list">
<div class="item" v-for="(link, index) in mapping">
<el-input size="mini" style="width: 30%" v-model="link.name" @change="onChange"/>
<div class="item" v-for="(link, index) in editData">
<el-input size="mini" style="width: 30%" v-model="link.name"/>
<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)"/>
</div>
</div>
......@@ -16,12 +16,14 @@
<script>
import {mapState, mapMutations} from 'vuex'
import {clonePureObj} from "../../../../utils";
export default {
name: "DataMappingEditor",
data() {
return {
visible: false,
editData: null,
}
},
computed: {
......@@ -30,11 +32,17 @@
}),
},
methods: {
onAdd() {
this.addDataMapping();
edit() {
this.editData = clonePureObj(this.mapping);
},
save() {
this.modifyDataMapping(this.editData);
},
onChange() {
this.modifyDataMapping();
onAdd() {
this.editData.push({
name: '',
path: '',
});
},
toDeleteItem(link, index) {
this.$confirm(this.$t('Are you sure to delete this item'), this.$t('Alert'), {
......@@ -42,13 +50,11 @@
cancelButtonText: this.$t('Cancel'),
type: 'warning'
}).then(() => {
this.deleteDataMapping(index);
this.editData.splice(index, 1);
}).catch((e) => {
});
},
...mapMutations([
'addDataMapping',
'deleteDataMapping',
'modifyDataMapping',
]),
}
......
<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">
<el-button class="add-button" icon="el-icon-plus" size="mini" circle @click="onAdd"/>
<div class="list">
<div class="item" v-for="(link, index) in env">
<el-input size="mini" style="width: 30%" v-model="link.name" @change="onChange"/>
<div class="item" v-for="(link, index) in editData">
<el-input size="mini" style="width: 30%" v-model="link.name"/>
<el-icon class="el-icon-connection"/>
<el-input size="mini" v-model="link.value" @change="onChange"/>
<el-button class="delete-button" icon="el-icon-minus" circle size="mini" plain type="danger" @click="toDeleteItem(link, index)"/>
<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)"/>
</div>
</div>
</div>
......@@ -16,12 +17,14 @@
<script>
import {mapState, mapMutations} from 'vuex'
import {clonePureObj} from "../../../../utils";
export default {
name: "EnvEditor",
data() {
return {
visible: false,
editData: null,
}
},
computed: {
......@@ -30,11 +33,17 @@
}),
},
methods: {
onAdd() {
this.addEnvMapping();
edit() {
this.editData = clonePureObj(this.env);
},
save() {
this.modifyEnv(this.editData);
},
onChange() {
this.modifyEnvMapping();
onAdd() {
this.editData.push({
name: '',
value: '',
});
},
toDeleteItem(link, index) {
this.$confirm(this.$t('Are you sure to delete this item'), this.$t('Alert'), {
......@@ -42,14 +51,12 @@
cancelButtonText: this.$t('Cancel'),
type: 'warning'
}).then(() => {
this.deleteEnvMapping(index);
this.editData.splice(index, 1);
}).catch((e) => {
});
},
...mapMutations([
'addEnvMapping',
'deleteEnvMapping',
'modifyEnvMapping',
'modifyEnv',
]),
}
}
......
<template>
<div>
<el-scrollbar class="scrollbar full-scrollbar" wrap-class="wrap-x-hidden" view-class="view">
<el-form @submit.native.prevent ref="form" :model="options" size="mini" label-position="right"
<div class="project-editor">
<el-scrollbar v-if="editData" class="project-scrollbar" wrap-class="wrap-x-hidden" view-class="view">
<el-form @submit.native.prevent ref="form" :model="editData" size="mini" label-position="right"
label-width="150px">
<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 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"
:key="index"
:value="view.name"
......@@ -16,19 +16,19 @@
</el-select>
</el-form-item>
<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 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 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 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 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"
:key="key"
:value="key"
......@@ -37,7 +37,7 @@
</el-select>
</el-form-item>
<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"
:key="key"
:value="key"
......@@ -48,7 +48,7 @@
<el-form-item prop="tpl" :label="$t('Template')">
<!-- <el-input type="textarea" v-model="options.tpl" :rows="10"/> -->
<codemirror ref="codeEditor"
v-model="options.tpl"
v-model="editData.tpl"
:options="cmOptions"
@cursorActivity="onCodeChange"
>
......@@ -56,10 +56,10 @@
</el-form-item>
</el-form>
</el-scrollbar>
<div class="operate-bar">
<!--<div class="operate-bar">
<el-button size="mini" @click="onReset">{{$t('Reset')}}</el-button>
<el-button size="mini" type="primary" @click="onSave">{{$t('Save')}}</el-button>
</div>
</div>-->
</div>
</template>
......@@ -73,6 +73,7 @@
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/javascript-hint.js'
import {clonePureObj} from "../../../../utils";
export default {
name: "ProjectEditor",
......@@ -82,6 +83,7 @@
const rendererType = this.$t('rendererType');
return {
visible: false,
editData: null,
scaleMode,
rendererType,
cmOptions: {
......@@ -106,15 +108,21 @@
},
methods: {
...mapMutations([
'modifyProject',
'modifyOptions',
]),
onReset() {
edit() {
this.editData = clonePureObj(this.options);
},
save() {
this.modifyOptions(this.editData);
},
/*onReset() {
this.$refs.form.resetFields();
},
onSave() {
this.modifyProject();
},
onCodeChange(codemirror){
},*/
onCodeChange(codemirror) {
//codemirror.showHint();
//console.log(code);
}
......
......@@ -26,7 +26,8 @@
<template slot="header" slot-scope="scope">
<el-checkbox
v-model="onlyMine"
size="mini">{{$t('Only mine')}}</el-checkbox>
size="mini">{{$t('Only mine')}}
</el-checkbox>
</template>
<template slot-scope="scope">
<el-button
......@@ -44,11 +45,12 @@
type="warning" icon="icon-download"
size="small" circle plain>
</el-button>
<!--<el-button
<el-button
v-if="showDeleteButton"
@click.native.prevent="onDeleteProject(scope.row)"
type="danger" icon="el-icon-delete"
size="small" circle plain>
</el-button>-->
</el-button>
</template>
</el-table-column>
</el-table>
......@@ -96,13 +98,16 @@
});
},
computed: {
showDeleteButton() {
return location.host.startsWith('localhost');
},
...mapState([
'projects',
'env',
]),
},
watch: {
onlyMine(){
onlyMine() {
this.handleCurrentChange(1);
}
},
......
<template>
<iframe ref="iframe" class="player-wrapper">
</iframe>
<div class="wrapper">
<iframe v-if="flag" ref="iframe" class="player-wrapper"></iframe>
</div>
</template>
<script>
import {applyMock} from "./Preview/mock-serve";
import db from "../utils/db-storage";
import {newScriptEl} from "../utils";
export default {
name: "Preview",
components: {},
data() {
return {
ts: '',
flag: false,
}
},
mounted() {
if(!this.ts){
async mounted() {
this.codes = {};
this.urls = {};
if (!this.ts) {
this.ts = localStorage.getItem('preview-ts');
}
document.addEventListener("visibilitychange", this.onVisibilityChange);
setTimeout(()=>{
this.buildPage();
}, 100);
await db.open();
this.reload();
},
destroyed(){
destroyed() {
document.removeEventListener("visibilitychange", this.onVisibilityChange);
},
methods: {
onVisibilityChange(e){
if(!document.hidden){
reload() {
this.flag = false;
setTimeout(() => {
this.flag = true;
this.buildPage();
}, 300);
},
onVisibilityChange(e) {
if (!document.hidden) {
let ts = localStorage.getItem('preview-ts');
if(this.ts !== ts){
this.$refs.iframe.contentDocument.location.reload();
document.location.reload();
if (this.ts !== ts) {
//this.$refs.iframe.contentDocument.location.reload();
//document.location.reload();
this.ts = ts;
this.reload();
}
}
},
buildPage() {
async buildPage() {
const {projectID} = this.$route.params;
const storeKey = 'preview-project-' + projectID;
let data = localStorage.getItem(storeKey);
let dataObj = JSON.parse(data);
const {data, codes} = await db.get('preview', projectID);
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
.replace('$PAGE_TITLE$', pageTitle)
.replace('$CONTAINER_ID$', containerId)
.replace('$SCRIPTS$', '')
.replace('engine.launch(\'//yun.duiba.com.cn/aurora/$VERSION$-data.json\');', launchCode);
.replace('$SCRIPTS$', scripts.join('\n'))
.replace('//yun.duiba.com.cn/aurora/$VERSION$-data.json', dataUrl);
const doc = this.$refs.iframe.contentDocument;
const win = this.$refs.iframe.contentWindow;
doc.write(tpl);
applyMock(projectID, win);
},
}
}
</script>
<style scoped>
.player-wrapper{
.wrapper {
width: 100%;
height: 100%;
}
.player-wrapper {
border: 0;
width: 100%;
height: 100%;
}
}
.mock-button {
position: absolute;
right: 10px;
bottom: 10px;
}
</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 MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '//yun.duiba.com.cn/editor/zeroing/v1/' : '',
pluginOptions: {
......@@ -23,6 +25,10 @@ module.exports = {
}
},*/
configureWebpack: {
plugins: [
/*new MonacoWebpackPlugin({
languages: ['html', 'javascript', 'json']
})*/
]
}
};
......@@ -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"
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:
version "4.3.0"
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:
resolved "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
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:
version "2.0.6"
resolved "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
......@@ -1689,11 +1699,21 @@ babel-runtime@6.x:
core-js "^2.4.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:
version "1.0.0"
resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
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:
version "1.3.1"
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:
dependencies:
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:
version "6.1.2"
resolved "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f"
......@@ -1761,6 +1788,11 @@ bl@^3.0.0:
dependencies:
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@*:
version "0.0.9"
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:
dependencies:
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:
version "2.0.0"
resolved "https://registry.npm.taobao.org/callsites/download/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
......@@ -2366,9 +2403,9 @@ code-point-at@^1.0.0:
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.41.0:
version "5.49.2"
resolved "https://registry.npm.taobao.org/codemirror/download/codemirror-5.49.2.tgz#c84fdaf11b19803f828b0c67060c7bc6d154ccad"
integrity sha1-yE/a8RsZgD+CiwxnBgx7xtFUzK0=
version "5.50.0"
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-rqzRjyJXNbF8urmJCO2s6H/tzas=
collection-visit@^1.0.0:
version "1.0.0"
......@@ -2448,11 +2485,26 @@ commondir@^1.0.1:
resolved "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
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:
version "1.3.0"
resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
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:
version "2.0.17"
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:
dependencies:
ms "2.0.0"
debug@3.1.0:
debug@3.1.0, debug@~3.1.0:
version "3.1.0"
resolved "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=
dependencies:
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"
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=
......@@ -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"
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:
version "4.1.0"
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:
dependencies:
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:
version "3.0.0"
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:
dependencies:
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:
version "1.0.1"
resolved "https://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
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:
version "1.0.4"
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:
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=
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:
version "2.0.0"
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:
resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
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:
version "0.1.0"
resolved "https://registry.npm.taobao.org/object-copy/download/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
......@@ -6629,6 +6741,20 @@ parse5@^4.0.0:
resolved "https://registry.npm.taobao.org/parse5/download/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
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:
version "1.3.3"
resolved "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
......@@ -8332,6 +8458,35 @@ snyk@^1.231.0:
uuid "^3.3.2"
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:
version "1.3.0"
resolved "https://registry.npm.taobao.org/sockjs-client/download/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177"
......@@ -8957,6 +9112,11 @@ tmp@^0.1.0:
dependencies:
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:
version "1.0.1"
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:
dependencies:
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:
version "3.0.0"
resolved "https://registry.npm.taobao.org/xdg-basedir/download/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
......@@ -9819,6 +9986,11 @@ xmlbuilder@~9.0.1:
resolved "https://registry.npm.taobao.org/xmlbuilder/download/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
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:
version "2.0.0"
resolved "https://registry.npm.taobao.org/xregexp/download/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
......@@ -9937,3 +10109,12 @@ yargs@^7.0.0:
which-module "^1.0.0"
y18n "^3.2.1"
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 @@
<module version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/dist" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</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