Improve MisskeyPages
This commit is contained in:
		
							parent
							
								
									2fdec27ab0
								
							
						
					
					
						commit
						2d1f50303d
					
				
					 21 changed files with 248 additions and 176 deletions
				
			
		|  | @ -1915,6 +1915,12 @@ pages: | |||
|       text: "タイトル" | ||||
|       default: "デフォルト値" | ||||
| 
 | ||||
|     counter: "カウンター" | ||||
|     _counter: | ||||
|       name: "変数名" | ||||
|       text: "タイトル" | ||||
|       inc: "増加値" | ||||
| 
 | ||||
|     _button: | ||||
|       text: "タイトル" | ||||
|       action: "ボタンを押したときの動作" | ||||
|  |  | |||
|  | @ -26,6 +26,12 @@ export function collectPageVars(content) { | |||
| 					type: 'boolean', | ||||
| 					value: x.default || false | ||||
| 				}); | ||||
| 			} else if (x.type === 'counter') { | ||||
| 				pageVars.push({ | ||||
| 					name: x.name, | ||||
| 					type: 'number', | ||||
| 					value: 0 | ||||
| 				}); | ||||
| 			} else if (x.children) { | ||||
| 				collect(x.children); | ||||
| 			} | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.button') }}</template> | ||||
| 
 | ||||
| 	<section class="xfhsjczc"> | ||||
|  |  | |||
|  | @ -0,0 +1,42 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.counter') }}</template> | ||||
| 
 | ||||
| 	<section style="padding: 0 16px 0 16px;"> | ||||
| 		<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._counter.name') }}</span></ui-input> | ||||
| 		<ui-input v-model="value.text"><span>{{ $t('blocks._counter.text') }}</span></ui-input> | ||||
| 		<ui-input v-model="value.inc" type="number"><span>{{ $t('blocks._counter.increment') }}</span></ui-input> | ||||
| 	</section> | ||||
| </x-container> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons'; | ||||
| import i18n from '../../../../../i18n'; | ||||
| import XContainer from '../page-editor.container.vue'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	i18n: i18n('pages'), | ||||
| 
 | ||||
| 	components: { | ||||
| 		XContainer | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		value: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	data() { | ||||
| 		return { | ||||
| 			faBolt, faMagic | ||||
| 		}; | ||||
| 	}, | ||||
| 
 | ||||
| 	created() { | ||||
| 		if (this.value.name == null) Vue.set(this.value, 'name', ''); | ||||
| 	}, | ||||
| }); | ||||
| </script> | ||||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faQuestion"/> {{ $t('blocks.if') }}</template> | ||||
| 	<template #func> | ||||
| 		<button @click="add()"> | ||||
|  | @ -19,9 +19,7 @@ | |||
| 			</optgroup> | ||||
| 		</ui-select> | ||||
| 
 | ||||
| 		<div class="children"> | ||||
| 			<x-block v-for="child in value.children" :value="child" @input="v => updateItem(v)" @remove="() => remove(child)" :key="child.id" :ai-script="aiScript"/> | ||||
| 		</div> | ||||
| 		<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/> | ||||
| 	</section> | ||||
| </x-container> | ||||
| </template> | ||||
|  | @ -58,7 +56,7 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 
 | ||||
| 	beforeCreate() { | ||||
| 		this.$options.components.XBlock = require('../page-editor.block.vue').default | ||||
| 		this.$options.components.XBlocks = require('../page-editor.blocks.vue').default | ||||
| 	}, | ||||
| 
 | ||||
| 	created() { | ||||
|  | @ -81,27 +79,6 @@ export default Vue.extend({ | |||
| 			const id = uuid.v4(); | ||||
| 			this.value.children.push({ id, type }); | ||||
| 		}, | ||||
| 
 | ||||
| 		updateItem(v) { | ||||
| 			const i = this.value.children.findIndex(x => x.id === v.id); | ||||
| 			const newValue = [ | ||||
| 				...this.value.children.slice(0, i), | ||||
| 				v, | ||||
| 				...this.value.children.slice(i + 1) | ||||
| 			]; | ||||
| 			this.value.children = newValue; | ||||
| 			this.$emit('input', this.value); | ||||
| 		}, | ||||
| 
 | ||||
| 		remove(el) { | ||||
| 			const i = this.value.children.findIndex(x => x.id === el.id); | ||||
| 			const newValue = [ | ||||
| 				...this.value.children.slice(0, i), | ||||
| 				...this.value.children.slice(i + 1) | ||||
| 			]; | ||||
| 			this.value.children = newValue; | ||||
| 			this.$emit('input', this.value); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faImage"/> {{ $t('blocks.image') }}</template> | ||||
| 	<template #func> | ||||
| 		<button @click="choose()"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.numberInput') }}</template> | ||||
| 
 | ||||
| 	<section style="padding: 0 16px 0 16px;"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faPaperPlane"/> {{ $t('blocks.post') }}</template> | ||||
| 
 | ||||
| 	<section style="padding: 0 16px 16px 16px;"> | ||||
|  | @ -33,10 +33,6 @@ export default Vue.extend({ | |||
| 		}; | ||||
| 	}, | ||||
| 
 | ||||
| 	beforeCreate() { | ||||
| 		this.$options.components.XBlock = require('../page-editor.block.vue').default | ||||
| 	}, | ||||
| 
 | ||||
| 	created() { | ||||
| 		if (this.value.text == null) Vue.set(this.value, 'text', ''); | ||||
| 	}, | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faStickyNote"/> {{ value.title }}</template> | ||||
| 	<template #func> | ||||
| 		<button @click="rename()"> | ||||
|  | @ -11,9 +11,7 @@ | |||
| 	</template> | ||||
| 
 | ||||
| 	<section class="ilrvjyvi"> | ||||
| 		<div class="children"> | ||||
| 			<x-block v-for="child in value.children" :value="child" @input="v => updateItem(v)" @remove="() => remove(child)" :key="child.id" :ai-script="aiScript"/> | ||||
| 		</div> | ||||
| 		<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/> | ||||
| 	</section> | ||||
| </x-container> | ||||
| </template> | ||||
|  | @ -51,7 +49,7 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 
 | ||||
| 	beforeCreate() { | ||||
| 		this.$options.components.XBlock = require('../page-editor.block.vue').default | ||||
| 		this.$options.components.XBlocks = require('../page-editor.blocks.vue').default | ||||
| 	}, | ||||
| 
 | ||||
| 	created() { | ||||
|  | @ -93,27 +91,6 @@ export default Vue.extend({ | |||
| 			const id = uuid.v4(); | ||||
| 			this.value.children.push({ id, type }); | ||||
| 		}, | ||||
| 
 | ||||
| 		updateItem(v) { | ||||
| 			const i = this.value.children.findIndex(x => x.id === v.id); | ||||
| 			const newValue = [ | ||||
| 				...this.value.children.slice(0, i), | ||||
| 				v, | ||||
| 				...this.value.children.slice(i + 1) | ||||
| 			]; | ||||
| 			this.value.children = newValue; | ||||
| 			this.$emit('input', this.value); | ||||
| 		}, | ||||
| 
 | ||||
| 		remove(el) { | ||||
| 			const i = this.value.children.findIndex(x => x.id === el.id); | ||||
| 			const newValue = [ | ||||
| 				...this.value.children.slice(0, i), | ||||
| 				...this.value.children.slice(i + 1) | ||||
| 			]; | ||||
| 			this.value.children = newValue; | ||||
| 			this.$emit('input', this.value); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.switch') }}</template> | ||||
| 
 | ||||
| 	<section class="kjuadyyj"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.textInput') }}</template> | ||||
| 
 | ||||
| 	<section style="padding: 0 16px 0 16px;"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faAlignLeft"/> {{ $t('blocks.text') }}</template> | ||||
| 
 | ||||
| 	<section class="ihymsbbe"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.textareaInput') }}</template> | ||||
| 
 | ||||
| 	<section style="padding: 0 16px 16px 16px;"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <x-container @remove="() => $emit('remove')"> | ||||
| <x-container @remove="() => $emit('remove')" :draggable="true"> | ||||
| 	<template #header><fa :icon="faAlignLeft"/> {{ $t('blocks.textarea') }}</template> | ||||
| 
 | ||||
| 	<section class="ihymsbbe"> | ||||
|  |  | |||
|  | @ -1,33 +0,0 @@ | |||
| <template> | ||||
| <component :is="'x-' + value.type" :value="value" @input="v => updateItem(v)" @remove="() => $emit('remove', value)" :key="value.id" :ai-script="aiScript"/> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import XSection from './els/page-editor.el.section.vue'; | ||||
| import XText from './els/page-editor.el.text.vue'; | ||||
| import XTextarea from './els/page-editor.el.textarea.vue'; | ||||
| import XImage from './els/page-editor.el.image.vue'; | ||||
| import XButton from './els/page-editor.el.button.vue'; | ||||
| import XTextInput from './els/page-editor.el.text-input.vue'; | ||||
| import XTextareaInput from './els/page-editor.el.textarea-input.vue'; | ||||
| import XNumberInput from './els/page-editor.el.text-input.vue'; | ||||
| import XSwitch from './els/page-editor.el.switch.vue'; | ||||
| import XIf from './els/page-editor.el.if.vue'; | ||||
| import XPost from './els/page-editor.el.post.vue'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		value: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		aiScript: { | ||||
| 			required: true, | ||||
| 		}, | ||||
| 	}, | ||||
| }); | ||||
| </script> | ||||
|  | @ -0,0 +1,65 @@ | |||
| <template> | ||||
| <x-draggable tag="div" :list="blocks" handle=".drag-handle" :group="{ name: 'blocks' }" animation="150"> | ||||
| 	<component v-for="block in blocks" :is="'x-' + block.type" :value="block" @input="updateItem" @remove="removeItem" :key="block.id" :ai-script="aiScript"/> | ||||
| </x-draggable> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import * as XDraggable from 'vuedraggable'; | ||||
| import XSection from './els/page-editor.el.section.vue'; | ||||
| import XText from './els/page-editor.el.text.vue'; | ||||
| import XTextarea from './els/page-editor.el.textarea.vue'; | ||||
| import XImage from './els/page-editor.el.image.vue'; | ||||
| import XButton from './els/page-editor.el.button.vue'; | ||||
| import XTextInput from './els/page-editor.el.text-input.vue'; | ||||
| import XTextareaInput from './els/page-editor.el.textarea-input.vue'; | ||||
| import XNumberInput from './els/page-editor.el.text-input.vue'; | ||||
| import XSwitch from './els/page-editor.el.switch.vue'; | ||||
| import XIf from './els/page-editor.el.if.vue'; | ||||
| import XPost from './els/page-editor.el.post.vue'; | ||||
| import XCounter from './els/page-editor.el.counter.vue'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XDraggable, XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost, XCounter | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		value: { | ||||
| 			type: Array, | ||||
| 			required: true | ||||
| 		}, | ||||
| 		aiScript: { | ||||
| 			required: true, | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	computed: { | ||||
| 		blocks() { | ||||
| 			return this.value; | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		updateItem(v) { | ||||
| 			const i = this.blocks.findIndex(x => x.id === v.id); | ||||
| 			const newValue = [ | ||||
| 				...this.blocks.slice(0, i), | ||||
| 				v, | ||||
| 				...this.blocks.slice(i + 1) | ||||
| 			]; | ||||
| 			this.$emit('input', newValue); | ||||
| 		}, | ||||
| 
 | ||||
| 		removeItem(el) { | ||||
| 			const i = this.blocks.findIndex(x => x.id === el.id); | ||||
| 			const newValue = [ | ||||
| 				...this.blocks.slice(0, i), | ||||
| 				...this.blocks.slice(i + 1) | ||||
| 			]; | ||||
| 			this.$emit('input', newValue); | ||||
| 		}, | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
| <div class="cpjygsrt" :class="{ error: error != null, warn: warn != null }"> | ||||
| 	<header> | ||||
| <div class="cpjygsrt" :class="{ error: error != null, warn: warn != null, draggable }"> | ||||
| 	<header class="drag-handle"> | ||||
| 		<div class="title"><slot name="header"></slot></div> | ||||
| 		<div class="buttons"> | ||||
| 			<slot name="func"></slot> | ||||
|  | @ -38,6 +38,10 @@ export default Vue.extend({ | |||
| 			type: Boolean, | ||||
| 			default: true | ||||
| 		}, | ||||
| 		draggable: { | ||||
| 			type: Boolean, | ||||
| 			default: false | ||||
| 		}, | ||||
| 		error: { | ||||
| 			required: false, | ||||
| 			default: null | ||||
|  | @ -120,6 +124,10 @@ export default Vue.extend({ | |||
| 				&:active | ||||
| 					color var(--faceTextButtonActive) | ||||
| 
 | ||||
| 	&.draggable | ||||
| 		> header | ||||
| 			cursor move | ||||
| 
 | ||||
| 	> .warn | ||||
| 		color #b19e49 | ||||
| 		margin 0 | ||||
|  |  | |||
|  | @ -44,9 +44,7 @@ | |||
| 				</div> | ||||
| 			</template> | ||||
| 
 | ||||
| 			<div class="content" v-for="child in content"> | ||||
| 				<x-block :value="child" @input="v => updateItem(v)" @remove="() => remove(child)" :key="child.id" :ai-script="aiScript"/> | ||||
| 			</div> | ||||
| 			<x-blocks class="content" v-model="content" :ai-script="aiScript"/> | ||||
| 
 | ||||
| 			<ui-button @click="add()" v-if="!readonly"><fa :icon="faPlus"/></ui-button> | ||||
| 		</section> | ||||
|  | @ -98,7 +96,7 @@ import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt } fr | |||
| import { faSave, faStickyNote, faTrashAlt } from '@fortawesome/free-regular-svg-icons'; | ||||
| import i18n from '../../../../i18n'; | ||||
| import XVariable from './page-editor.script-block.vue'; | ||||
| import XBlock from './page-editor.block.vue'; | ||||
| import XBlocks from './page-editor.blocks.vue'; | ||||
| import * as uuid from 'uuid'; | ||||
| import { blockDefs } from '../../../../../../misc/aiscript/index'; | ||||
| import { ASTypeChecker } from '../../../../../../misc/aiscript/type-checker'; | ||||
|  | @ -109,7 +107,7 @@ export default Vue.extend({ | |||
| 	i18n: i18n('pages'), | ||||
| 
 | ||||
| 	components: { | ||||
| 		XVariable, XBlock | ||||
| 		XVariable, XBlocks | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
|  | @ -299,25 +297,6 @@ export default Vue.extend({ | |||
| 			this.variables.push({ id, name, type: null }); | ||||
| 		}, | ||||
| 
 | ||||
| 		updateItem(v) { | ||||
| 			const i = this.content.findIndex(x => x.id === v.id); | ||||
| 			const newValue = [ | ||||
| 				...this.content.slice(0, i), | ||||
| 				v, | ||||
| 				...this.content.slice(i + 1) | ||||
| 			]; | ||||
| 			this.content = newValue; | ||||
| 		}, | ||||
| 
 | ||||
| 		remove(el) { | ||||
| 			const i = this.content.findIndex(x => x.id === el.id); | ||||
| 			const newValue = [ | ||||
| 				...this.content.slice(0, i), | ||||
| 				...this.content.slice(i + 1) | ||||
| 			]; | ||||
| 			this.content = newValue; | ||||
| 		}, | ||||
| 
 | ||||
| 		removeVariable(v) { | ||||
| 			const i = this.variables.findIndex(x => x.name === v.name); | ||||
| 			const newValue = [ | ||||
|  | @ -343,7 +322,8 @@ export default Vue.extend({ | |||
| 					{ value: 'textInput', text: this.$t('blocks.textInput') }, | ||||
| 					{ value: 'textareaInput', text: this.$t('blocks.textareaInput') }, | ||||
| 					{ value: 'numberInput', text: this.$t('blocks.numberInput') }, | ||||
| 					{ value: 'switch', text: this.$t('blocks.switch') } | ||||
| 					{ value: 'switch', text: this.$t('blocks.switch') }, | ||||
| 					{ value: 'counter', text: this.$t('blocks.counter') } | ||||
| 				] | ||||
| 			}, { | ||||
| 				label: this.$t('special-blocks'), | ||||
|  |  | |||
|  | @ -15,10 +15,11 @@ import XSwitch from './page.switch.vue'; | |||
| import XIf from './page.if.vue'; | ||||
| import XTextarea from './page.textarea.vue'; | ||||
| import XPost from './page.post.vue'; | ||||
| import XCounter from './page.counter.vue'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf | ||||
| 		XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf, XCounter | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
|  |  | |||
							
								
								
									
										47
									
								
								src/client/app/common/views/pages/page/page.counter.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/client/app/common/views/pages/page/page.counter.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | |||
| <template> | ||||
| <div> | ||||
| 	<ui-button class="llumlmnx" @click="click()">{{ script.interpolate(value.text) }}</ui-button> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	props: { | ||||
| 		value: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		script: { | ||||
| 			required: true | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	data() { | ||||
| 		return { | ||||
| 			v: 0, | ||||
| 		}; | ||||
| 	}, | ||||
| 
 | ||||
| 	watch: { | ||||
| 		v() { | ||||
| 			this.script.aiScript.updatePageVar(this.value.name, this.v); | ||||
| 			this.script.eval(); | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		click() { | ||||
| 			this.v = this.v + (this.value.inc || 1); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="stylus" scoped> | ||||
| .llumlmnx | ||||
| 	display inline-block | ||||
| 	min-width 300px | ||||
| 	max-width 450px | ||||
| 	margin 8px 0 | ||||
| </style> | ||||
|  | @ -7,56 +7,6 @@ type Fn = { | |||
| 	exec: (args: Record<string, any>) => ReturnType<ASEvaluator['evaluate']>; | ||||
| }; | ||||
| 
 | ||||
| class AiScriptError extends Error { | ||||
| 	public info?: any; | ||||
| 
 | ||||
| 	constructor(message: string, info?: any) { | ||||
| 		super(message); | ||||
| 
 | ||||
| 		this.info = info; | ||||
| 
 | ||||
| 		// Maintains proper stack trace for where our error was thrown (only available on V8)
 | ||||
| 		if (Error.captureStackTrace) { | ||||
| 			Error.captureStackTrace(this, AiScriptError); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| class Scope { | ||||
| 	private layerdStates: Record<string, any>[]; | ||||
| 	public name: string; | ||||
| 
 | ||||
| 	constructor(layerdStates: Scope['layerdStates'], name?: Scope['name']) { | ||||
| 		this.layerdStates = layerdStates; | ||||
| 		this.name = name || 'anonymous'; | ||||
| 	} | ||||
| 
 | ||||
| 	@autobind | ||||
| 	public createChildScope(states: Record<string, any>, name?: Scope['name']): Scope { | ||||
| 		const layer = [states, ...this.layerdStates]; | ||||
| 		return new Scope(layer, name); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * 指定した名前の変数の値を取得します | ||||
| 	 * @param name 変数名 | ||||
| 	 */ | ||||
| 	@autobind | ||||
| 	public getState(name: string): any { | ||||
| 		for (const later of this.layerdStates) { | ||||
| 			const state = later[name]; | ||||
| 			if (state !== undefined) { | ||||
| 				return state; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		throw new AiScriptError( | ||||
| 			`No such variable '${name}' in scope '${this.name}'`, { | ||||
| 				scope: this.layerdStates | ||||
| 			}); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * AiScript evaluator | ||||
|  */ | ||||
|  | @ -238,3 +188,53 @@ export class ASEvaluator { | |||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| class AiScriptError extends Error { | ||||
| 	public info?: any; | ||||
| 
 | ||||
| 	constructor(message: string, info?: any) { | ||||
| 		super(message); | ||||
| 
 | ||||
| 		this.info = info; | ||||
| 
 | ||||
| 		// Maintains proper stack trace for where our error was thrown (only available on V8)
 | ||||
| 		if (Error.captureStackTrace) { | ||||
| 			Error.captureStackTrace(this, AiScriptError); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| class Scope { | ||||
| 	private layerdStates: Record<string, any>[]; | ||||
| 	public name: string; | ||||
| 
 | ||||
| 	constructor(layerdStates: Scope['layerdStates'], name?: Scope['name']) { | ||||
| 		this.layerdStates = layerdStates; | ||||
| 		this.name = name || 'anonymous'; | ||||
| 	} | ||||
| 
 | ||||
| 	@autobind | ||||
| 	public createChildScope(states: Record<string, any>, name?: Scope['name']): Scope { | ||||
| 		const layer = [states, ...this.layerdStates]; | ||||
| 		return new Scope(layer, name); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * 指定した名前の変数の値を取得します | ||||
| 	 * @param name 変数名 | ||||
| 	 */ | ||||
| 	@autobind | ||||
| 	public getState(name: string): any { | ||||
| 		for (const later of this.layerdStates) { | ||||
| 			const state = later[name]; | ||||
| 			if (state !== undefined) { | ||||
| 				return state; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		throw new AiScriptError( | ||||
| 			`No such variable '${name}' in scope '${this.name}'`, { | ||||
| 				scope: this.layerdStates | ||||
| 			}); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue