|
@@ -17,7 +17,7 @@
|
|
|
<magic-tab v-model:value="selectTab" :tabs="openedScripts" className="magic-script-tab" ref="tab"
|
|
|
:allow-close="true" @close="onClose" @change="tab => bus.$emit('open', tab)" @item-contextmenu="onContextMenu">
|
|
|
<template v-slot="{ tab }">
|
|
|
- <magic-text-icon :icon="tab.getIcon(tab.item)"/>{{ tab.item.name }}<span v-if="tab.item.script !== tab.tmpScript">*</span>
|
|
|
+ <magic-text-icon :icon="tab.getIcon(tab.item)"/>{{ tab.item.name }}<span v-if="isUpdated(tab)">*</span>
|
|
|
<magic-icon v-if="tab.item.lock === $LOCKED" icon="lock"/>
|
|
|
<magic-avatar-group :users="activateUserFiles[tab.item.id] || []" :max="3" :size="20"/>
|
|
|
</template>
|
|
@@ -71,6 +71,7 @@ RequestParameter.setEnvironment(() => {
|
|
|
}
|
|
|
return env
|
|
|
})
|
|
|
+// 关闭tab
|
|
|
const onClose = tab => {
|
|
|
let index = openedScripts.findIndex(it => it === tab)
|
|
|
openedScripts.splice(index, 1)
|
|
@@ -93,39 +94,99 @@ const onClose = tab => {
|
|
|
watch(openedScripts, (newVal) => {
|
|
|
store.set(constants.RECENT_OPENED_TAB, newVal.filter(it => it.item?.id).map(it => it.item.id))
|
|
|
})
|
|
|
-bus.$event(Socket.EXCEPTION, ([ [scriptId, message, line] ]) => {
|
|
|
- if(selectTab.value?.item?.id === scriptId){
|
|
|
- const range = new Range(line[0], line[2], line[1], line[3] + 1)
|
|
|
- const instance = editor.value.getInstance()
|
|
|
- const decorations = instance.deltaDecorations([], [{
|
|
|
- range,
|
|
|
- options: {
|
|
|
- hoverMessage: {
|
|
|
- value: message
|
|
|
- },
|
|
|
- inlineClassName: 'squiggly-error'
|
|
|
+// 执行保存
|
|
|
+const doSave = (flag) => {
|
|
|
+ const opened = selectTab.value
|
|
|
+ if(opened && opened.item){
|
|
|
+ const item = selectTab.value.processSave(opened.item)
|
|
|
+ Object.keys(item).forEach(key => opened.item[key] = item[key])
|
|
|
+ return request.sendJson(`/resource/file/${selectTab.value.type}/save?auto=${flag ? 0 : 1}`, item).success((id) => {
|
|
|
+ if(id) {
|
|
|
+ bus.status(`保存${opened.title}「${opened.path()}」成功`)
|
|
|
+ opened.tmpObject = JSON.parse(JSON.stringify(item))
|
|
|
+ if(opened.item.id !== id){
|
|
|
+ bus.report(`script-add`)
|
|
|
+ } else {
|
|
|
+ bus.report(`script-save`)
|
|
|
+ }
|
|
|
+ opened.item.id = id
|
|
|
+ }else{
|
|
|
+ bus.status(`保存${opened.title}「${opened.path()}」失败`, false)
|
|
|
+ proxy.$alert(`保存${opened.title}「${opened.path()}」失败`)
|
|
|
}
|
|
|
- }])
|
|
|
- instance.revealRangeInCenter(range)
|
|
|
- instance.focus()
|
|
|
- if(constants.DECORATION_TIMEOUT >= 0){
|
|
|
- setTimeout(() => instance.deltaDecorations(decorations, []), constants.DECORATION_TIMEOUT)
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+// 执行测试
|
|
|
+const doTest = () => selectTab.value.doTest(selectTab.value)
|
|
|
+const doContinue = step => {
|
|
|
+ if(selectTab.value.debuging){
|
|
|
+ editor.value.removedDecorations(selectTab.value.debugDecorations)
|
|
|
+ selectTab.value.debuging = false
|
|
|
+ selectTab.value.variables = null
|
|
|
+ const breakpoints = (selectTab.value.decorations || []).filter(it => it.options.linesDecorationsClassName === 'breakpoints').map(it => it.range.startLineNumber).join('|')
|
|
|
+ bus.send(Socket.RESUME_BREAKPOINT, [selectTab.value.item.id, (step === true ? '1' : '0'), breakpoints].join(','))
|
|
|
+ }
|
|
|
+}
|
|
|
+// tab 右键菜单事件
|
|
|
+const onContextMenu = (event, item, index) => {
|
|
|
+ const menus = [{
|
|
|
+ label: '关闭',
|
|
|
+ divided: true,
|
|
|
+ onClick(){
|
|
|
+ onClose(item)
|
|
|
+ }
|
|
|
+ },{
|
|
|
+ label: '关闭其他',
|
|
|
+ divided: true,
|
|
|
+ onClick(){
|
|
|
+ [...openedScripts].forEach((it, i) => i != index && onClose(it))
|
|
|
+ }
|
|
|
+ },{
|
|
|
+ label: '关闭左侧',
|
|
|
+ onClick(){
|
|
|
+ [...openedScripts].forEach((it, i) => i < index && onClose(it))
|
|
|
+ }
|
|
|
+ },{
|
|
|
+ label: '关闭右侧',
|
|
|
+ divided: true,
|
|
|
+ onClick(){
|
|
|
+ [...openedScripts].forEach((it, i) => i > index && onClose(it))
|
|
|
}
|
|
|
+ },{
|
|
|
+ label: '全部关闭',
|
|
|
+ onClick(){
|
|
|
+ [...openedScripts].forEach(it => onClose(it))
|
|
|
+ }
|
|
|
+ }]
|
|
|
+ proxy.$contextmenu({ menus, event})
|
|
|
+}
|
|
|
+// 判断是否有变动
|
|
|
+const isUpdated = (tab) => Object.keys(tab.tmpObject || {}).some(k => {
|
|
|
+ const v1 = tab.tmpObject[k]
|
|
|
+ const v2 = tab.item[k]
|
|
|
+ if(v1 === v2 || k === 'properties'){
|
|
|
+ return false
|
|
|
}
|
|
|
+ return (typeof v1 === 'object' || typeof v2 === 'object') ? JSON.stringify(v1) !== JSON.stringify(v2) : v1 !== v2
|
|
|
})
|
|
|
+// 退出登录
|
|
|
bus.$on(Message.LOGOUT, () => [...openedScripts].forEach(tab => onClose(tab)))
|
|
|
+// 执行删除时
|
|
|
bus.$on(Message.DELETE_FILE, item => {
|
|
|
const index = openedScripts.findIndex(it => it.item === item)
|
|
|
if(index > -1){
|
|
|
onClose(openedScripts[index])
|
|
|
}
|
|
|
})
|
|
|
+// 重新加载资源完毕时
|
|
|
bus.$on(Message.RELOAD_RESOURCES_FINISH, ()=> {
|
|
|
openedScripts.filter(opened => opened.item && opened.item.id).forEach(opened => request.sendGet(`/resource/file/${opened.item.id}`).success(data => {
|
|
|
bus.status(`获取${opened.title}「${opened.path()}」详情成功`)
|
|
|
Object.keys(data).forEach(key => opened.item[key] = data[key])
|
|
|
}))
|
|
|
})
|
|
|
+// 登录响应
|
|
|
bus.$event(Socket.LOGIN_RESPONSE, () => {
|
|
|
if(selectTab.value){
|
|
|
bus.send(Socket.SET_FILE_ID, selectTab.value.item?.id || '0')
|
|
@@ -146,10 +207,11 @@ bus.$on(Message.OPEN, opened => {
|
|
|
request.sendGet(`/resource/file/${opened.item.id}`).success(data => {
|
|
|
bus.status(`获取${opened.title}「${opened.path()}」详情成功`)
|
|
|
Object.keys(data).forEach(key => opened.item[key] = data[key])
|
|
|
- opened.tmpScript = data.script
|
|
|
+ opened.tmpObject = JSON.parse(JSON.stringify(opened.processSave(data)))
|
|
|
loading.value = false
|
|
|
})
|
|
|
} else {
|
|
|
+ opened.tmpObject = JSON.parse(JSON.stringify(opened.processSave(opened.item)))
|
|
|
loading.value = false
|
|
|
}
|
|
|
}
|
|
@@ -163,31 +225,6 @@ bus.$on(Message.OPEN, opened => {
|
|
|
}
|
|
|
nextTick(() => tab.value && tab.value.scrollIntoView(opened))
|
|
|
})
|
|
|
-// 执行保存
|
|
|
-const doSave = (flag) => {
|
|
|
- const opened = selectTab.value
|
|
|
- if(opened && opened.item){
|
|
|
- const item = selectTab.value.processSave(opened.item)
|
|
|
- Object.keys(item).forEach(key => opened.item[key] = item[key])
|
|
|
- return request.sendJson(`/resource/file/${selectTab.value.type}/save?auto=${flag ? 0 : 1}`, item).success((id) => {
|
|
|
- if(id) {
|
|
|
- bus.status(`保存${opened.title}「${opened.path()}」成功`)
|
|
|
- opened.tmpScript = item.script
|
|
|
- if(opened.item.id !== id){
|
|
|
- bus.report(`script-add`)
|
|
|
- } else {
|
|
|
- bus.report(`script-save`)
|
|
|
- }
|
|
|
- opened.item.id = id
|
|
|
- }else{
|
|
|
- bus.status(`保存${opened.title}「${opened.path()}」失败`, false)
|
|
|
- proxy.$alert(`保存${opened.title}「${opened.path()}」失败`)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-}
|
|
|
-// 执行测试
|
|
|
-const doTest = () => selectTab.value.doTest(selectTab.value)
|
|
|
// 保存事件
|
|
|
bus.$on(Message.DO_SAVE, doSave)
|
|
|
// 测试事件
|
|
@@ -229,49 +266,31 @@ bus.$event(Socket.BREAKPOINT, ([ scriptId, { range, variables } ]) => {
|
|
|
})
|
|
|
bus.report(`debug-in`)
|
|
|
})
|
|
|
-const doContinue = step => {
|
|
|
- if(selectTab.value.debuging){
|
|
|
- editor.value.removedDecorations(selectTab.value.debugDecorations)
|
|
|
- selectTab.value.debuging = false
|
|
|
- selectTab.value.variables = null
|
|
|
- const breakpoints = (selectTab.value.decorations || []).filter(it => it.options.linesDecorationsClassName === 'breakpoints').map(it => it.range.startLineNumber).join('|')
|
|
|
- bus.send(Socket.RESUME_BREAKPOINT, [selectTab.value.item.id, (step === true ? '1' : '0'), breakpoints].join(','))
|
|
|
- }
|
|
|
-}
|
|
|
+// 恢复断点
|
|
|
bus.$on(Message.DEBUG_CONTINUE, doContinue)
|
|
|
+// 断点单步运行
|
|
|
bus.$on(Message.DEBUG_SETPINTO, () => doContinue(true))
|
|
|
-const onContextMenu = (event, item, index) => {
|
|
|
- const menus = [{
|
|
|
- label: '关闭',
|
|
|
- divided: true,
|
|
|
- onClick(){
|
|
|
- onClose(item)
|
|
|
- }
|
|
|
- },{
|
|
|
- label: '关闭其他',
|
|
|
- divided: true,
|
|
|
- onClick(){
|
|
|
- [...openedScripts].forEach((it, i) => i != index && onClose(it))
|
|
|
- }
|
|
|
- },{
|
|
|
- label: '关闭左侧',
|
|
|
- onClick(){
|
|
|
- [...openedScripts].forEach((it, i) => i < index && onClose(it))
|
|
|
- }
|
|
|
- },{
|
|
|
- label: '关闭右侧',
|
|
|
- divided: true,
|
|
|
- onClick(){
|
|
|
- [...openedScripts].forEach((it, i) => i > index && onClose(it))
|
|
|
- }
|
|
|
- },{
|
|
|
- label: '全部关闭',
|
|
|
- onClick(){
|
|
|
- [...openedScripts].forEach(it => onClose(it))
|
|
|
+// 执行出现异常
|
|
|
+bus.$event(Socket.EXCEPTION, ([ [scriptId, message, line] ]) => {
|
|
|
+ if(selectTab.value?.item?.id === scriptId){
|
|
|
+ const range = new Range(line[0], line[2], line[1], line[3] + 1)
|
|
|
+ const instance = editor.value.getInstance()
|
|
|
+ const decorations = instance.deltaDecorations([], [{
|
|
|
+ range,
|
|
|
+ options: {
|
|
|
+ hoverMessage: {
|
|
|
+ value: message
|
|
|
+ },
|
|
|
+ inlineClassName: 'squiggly-error'
|
|
|
+ }
|
|
|
+ }])
|
|
|
+ instance.revealRangeInCenter(range)
|
|
|
+ instance.focus()
|
|
|
+ if(constants.DECORATION_TIMEOUT >= 0){
|
|
|
+ setTimeout(() => instance.deltaDecorations(decorations, []), constants.DECORATION_TIMEOUT)
|
|
|
}
|
|
|
- }]
|
|
|
- proxy.$contextmenu({ menus, event})
|
|
|
-}
|
|
|
+ }
|
|
|
+})
|
|
|
const emit = defineEmits(['onLoad'])
|
|
|
onMounted(() => emit('onLoad'))
|
|
|
</script>
|