Merge branch 'develop'

This commit is contained in:
syuilo 2019-05-01 20:57:23 +09:00
commit 6d35872af5
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
29 changed files with 842 additions and 581 deletions

View file

@ -3,7 +3,7 @@
<template #header><fa :icon="faBolt"/> {{ $t('blocks.numberInput') }}</template>
<section style="padding: 0 16px 0 16px;">
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._numberInput.name') }}</span></ui-input>
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._numberInput.name') }}</span></ui-input>
<ui-input v-model="value.text"><span>{{ $t('blocks._numberInput.text') }}</span></ui-input>
<ui-input v-model="value.default" type="number"><span>{{ $t('blocks._numberInput.default') }}</span></ui-input>
</section>
@ -12,7 +12,7 @@
<script lang="ts">
import Vue from 'vue';
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../../../i18n';
import XContainer from '../page-editor.container.vue';
@ -31,7 +31,7 @@ export default Vue.extend({
data() {
return {
faBolt, faSquareRootAlt
faBolt, faMagic
};
},

View file

@ -3,7 +3,7 @@
<template #header><fa :icon="faBolt"/> {{ $t('blocks.switch') }}</template>
<section class="kjuadyyj">
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._switch.name') }}</span></ui-input>
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._switch.name') }}</span></ui-input>
<ui-input v-model="value.text"><span>{{ $t('blocks._switch.text') }}</span></ui-input>
<ui-switch v-model="value.default"><span>{{ $t('blocks._switch.default') }}</span></ui-switch>
</section>
@ -12,7 +12,7 @@
<script lang="ts">
import Vue from 'vue';
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../../../i18n';
import XContainer from '../page-editor.container.vue';
@ -31,7 +31,7 @@ export default Vue.extend({
data() {
return {
faBolt, faSquareRootAlt
faBolt, faMagic
};
},

View file

@ -3,7 +3,7 @@
<template #header><fa :icon="faBolt"/> {{ $t('blocks.textInput') }}</template>
<section style="padding: 0 16px 0 16px;">
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._textInput.name') }}</span></ui-input>
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._textInput.name') }}</span></ui-input>
<ui-input v-model="value.text"><span>{{ $t('blocks._textInput.text') }}</span></ui-input>
<ui-input v-model="value.default" type="text"><span>{{ $t('blocks._textInput.default') }}</span></ui-input>
</section>
@ -12,7 +12,7 @@
<script lang="ts">
import Vue from 'vue';
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../../../i18n';
import XContainer from '../page-editor.container.vue';
@ -31,7 +31,7 @@ export default Vue.extend({
data() {
return {
faBolt, faSquareRootAlt
faBolt, faMagic
};
},

View file

@ -3,7 +3,7 @@
<template #header><fa :icon="faBolt"/> {{ $t('blocks.textareaInput') }}</template>
<section style="padding: 0 16px 16px 16px;">
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._textareaInput.name') }}</span></ui-input>
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._textareaInput.name') }}</span></ui-input>
<ui-input v-model="value.text"><span>{{ $t('blocks._textareaInput.text') }}</span></ui-input>
<ui-textarea v-model="value.default"><span>{{ $t('blocks._textareaInput.default') }}</span></ui-textarea>
</section>
@ -12,7 +12,7 @@
<script lang="ts">
import Vue from 'vue';
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../../../i18n';
import XContainer from '../page-editor.container.vue';
@ -31,7 +31,7 @@ export default Vue.extend({
data() {
return {
faBolt, faSquareRootAlt
faBolt, faMagic
};
},

View file

@ -25,6 +25,9 @@
<section v-else-if="value.type === 'ref'" class="hpdwcrvs">
<select v-model="value.value">
<option v-for="v in aiScript.getVarsByType(getExpectedType ? getExpectedType() : null).filter(x => x.name !== name)" :value="v.name">{{ v.name }}</option>
<optgroup :label="$t('script.argVariables')">
<option v-for="v in fnSlots" :value="v.name">{{ v.name }}</option>
</optgroup>
<optgroup :label="$t('script.pageVariables')">
<option v-for="v in aiScript.getPageVarsByType(getExpectedType ? getExpectedType() : null)" :value="v">{{ v }}</option>
</optgroup>
@ -33,17 +36,15 @@
</optgroup>
</select>
</section>
<section v-else-if="value.type === 'in'" class="hpdwcrvs">
<select v-model="value.value">
<option v-for="v in fnSlots" :value="v">{{ v }}</option>
</select>
</section>
<section v-else-if="value.type === 'fn'" class="" style="padding:16px;">
<ui-textarea v-model="slots"></ui-textarea>
<section v-else-if="value.type === 'fn'" class="" style="padding:0 16px 16px 16px;">
<ui-textarea v-model="slots">
<span>{{ $t('script.blocks._fn.slots') }}</span>
<template #desc>{{ $t('script.blocks._fn.slots-info') }}</template>
</ui-textarea>
<x-v v-if="value.value.expression" v-model="value.value.expression" :title="$t(`script.blocks._fn.arg1`)" :get-expected-type="() => null" :ai-script="aiScript" :fn-slots="value.value.slots" :name="name"/>
</section>
<section v-else-if="value.type.startsWith('fn:')" class="" style="padding:16px;">
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="aiScript.getVarByName(value.type.split(':')[1]).value.slots[i]" :get-expected-type="() => null" :ai-script="aiScript" :name="name" :key="i"/>
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="aiScript.getVarByName(value.type.split(':')[1]).value.slots[i].name" :get-expected-type="() => null" :ai-script="aiScript" :name="name" :key="i"/>
</section>
<section v-else class="" style="padding:16px;">
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="$t(`script.blocks._${value.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :ai-script="aiScript" :name="name" :fn-slots="fnSlots" :key="i"/>
@ -55,8 +56,8 @@
import Vue from 'vue';
import i18n from '../../../../i18n';
import XContainer from './page-editor.container.vue';
import { faSuperscript, faPencilAlt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
import { AiScript } from '../../../scripts/aiscript';
import { faPencilAlt, faPlug } from '@fortawesome/free-solid-svg-icons';
import { isLiteralBlock, funcDefs, blockDefs } from '../../../../../../misc/aiscript/index';
import * as uuid from 'uuid';
export default Vue.extend({
@ -96,29 +97,32 @@ export default Vue.extend({
data() {
return {
AiScript,
error: null,
warn: null,
slots: '',
faSuperscript, faPencilAlt, faSquareRootAlt
faPencilAlt
};
},
computed: {
icon(): any {
if (this.value.type === null) return null;
if (this.value.type.startsWith('fn:')) return null;
return AiScript.blockDefs.find(x => x.type === this.value.type).icon;
if (this.value.type.startsWith('fn:')) return faPlug;
return blockDefs.find(x => x.type === this.value.type).icon;
},
typeText(): any {
if (this.value.type === null) return null;
if (this.value.type.startsWith('fn:')) return this.value.type.split(':')[1];
return this.$t(`script.blocks.${this.value.type}`);
},
},
watch: {
slots() {
this.value.value.slots = this.slots.split('\n');
this.value.value.slots = this.slots.split('\n').map(x => ({
name: x,
type: null
}));
}
},
@ -129,7 +133,7 @@ export default Vue.extend({
created() {
if (this.value.value == null) Vue.set(this.value, 'value', null);
if (this.value.value && this.value.value.slots) this.slots = this.value.value.slots.join('\n');
if (this.value.value && this.value.value.slots) this.slots = this.value.value.slots.map(x => x.name).join('\n');
this.$watch('value.type', (t) => {
this.warn = null;
@ -155,17 +159,17 @@ export default Vue.extend({
return;
}
if (AiScript.isLiteralBlock(this.value)) return;
if (isLiteralBlock(this.value)) return;
const empties = [];
for (let i = 0; i < AiScript.funcDefs[this.value.type].in.length; i++) {
for (let i = 0; i < funcDefs[this.value.type].in.length; i++) {
const id = uuid.v4();
empties.push({ id, type: null });
}
Vue.set(this.value, 'args', empties);
for (let i = 0; i < AiScript.funcDefs[this.value.type].in.length; i++) {
const inType = AiScript.funcDefs[this.value.type].in[i];
for (let i = 0; i < funcDefs[this.value.type].in.length; i++) {
const inType = funcDefs[this.value.type].in[i];
if (typeof inType !== 'number') {
if (inType === 'number') this.value.args[i].type = 'number';
if (inType === 'string') this.value.args[i].type = 'text';

View file

@ -36,10 +36,10 @@
</ui-select>
<div class="eyeCatch">
<ui-button v-if="eyeCatchingImageId == null" @click="setEyeCatchingImage()"><fa :icon="faPlus"/> {{ $t('set-eye-catchig-image') }}</ui-button>
<ui-button v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage()"><fa :icon="faPlus"/> {{ $t('set-eye-catchig-image') }}</ui-button>
<div v-else-if="eyeCatchingImage">
<img :src="eyeCatchingImage.url" :alt="eyeCatchingImage.name"/>
<ui-button @click="removeEyeCatchingImage()"><fa :icon="faTrashAlt"/> {{ $t('remove-eye-catchig-image') }}</ui-button>
<ui-button @click="removeEyeCatchingImage()" v-if="!readonly"><fa :icon="faTrashAlt"/> {{ $t('remove-eye-catchig-image') }}</ui-button>
</div>
</div>
</template>
@ -53,7 +53,7 @@
</div>
<ui-container :body-togglable="true">
<template #header><fa :icon="faSquareRootAlt"/> {{ $t('variables') }}</template>
<template #header><fa :icon="faMagic"/> {{ $t('variables') }}</template>
<div class="qmuvgica">
<div class="variables" v-show="variables.length > 0">
<template v-for="variable in variables">
@ -77,21 +77,31 @@
<template v-if="moreDetails">
<ui-info><span v-html="$t('variables-info2')"></span></ui-info>
<ui-info><span v-html="$t('variables-info3')"></span></ui-info>
<ui-info><span v-html="$t('variables-info4')"></span></ui-info>
</template>
</div>
</ui-container>
<ui-container :body-togglable="true" :expanded="false">
<template #header><fa :icon="faCode"/> {{ $t('inspector') }}</template>
<div style="padding:0 32px 32px 32px;">
<ui-textarea :value="JSON.stringify(content, null, 2)" readonly tall>{{ $t('content') }}</ui-textarea>
<ui-textarea :value="JSON.stringify(variables, null, 2)" readonly tall>{{ $t('variables') }}</ui-textarea>
</div>
</ui-container>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../../i18n';
import { faICursor, faPlus, faSquareRootAlt, faCog, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
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 * as uuid from 'uuid';
import { AiScript } from '../../../scripts/aiscript';
import { blockDefs } from '../../../../../../misc/aiscript/index';
import { ASTypeChecker } from '../../../../../../misc/aiscript/type-checker';
import { url } from '../../../../config';
import { collectPageVars } from '../../../scripts/collect-page-vars';
@ -104,7 +114,7 @@ export default Vue.extend({
props: {
page: {
type: String,
type: Object,
required: false
},
readonly: {
@ -132,7 +142,7 @@ export default Vue.extend({
showOptions: false,
moreDetails: false,
url,
faPlus, faICursor, faSave, faStickyNote, faSquareRootAlt, faCog, faTrashAlt, faExternalLinkSquareAlt
faPlus, faICursor, faSave, faStickyNote, faMagic, faCog, faTrashAlt, faExternalLinkSquareAlt, faCode
};
},
@ -149,32 +159,28 @@ export default Vue.extend({
},
created() {
this.aiScript = new AiScript();
this.aiScript = new ASTypeChecker();
this.$watch('variables', () => {
this.aiScript.injectVars(this.variables);
this.aiScript.variables = this.variables;
}, { deep: true });
this.$watch('content', () => {
this.aiScript.injectPageVars(collectPageVars(this.content));
this.aiScript.pageVars = collectPageVars(this.content);
}, { deep: true });
if (this.page) {
this.$root.api('pages/show', {
pageId: this.page,
}).then(page => {
this.author = page.user;
this.pageId = page.id;
this.title = page.title;
this.name = page.name;
this.currentName = page.name;
this.summary = page.summary;
this.font = page.font;
this.alignCenter = page.alignCenter;
this.content = page.content;
this.variables = page.variables;
this.eyeCatchingImageId = page.eyeCatchingImageId;
});
this.author = this.page.user;
this.pageId = this.page.id;
this.title = this.page.title;
this.name = this.page.name;
this.currentName = this.page.name;
this.summary = this.page.summary;
this.font = this.page.font;
this.alignCenter = this.page.alignCenter;
this.content = this.page.content;
this.variables = this.page.variables;
this.eyeCatchingImageId = this.page.eyeCatchingImageId;
} else {
const id = uuid.v4();
this.content = [{
@ -351,7 +357,7 @@ export default Vue.extend({
getScriptBlockList(type: string = null) {
const list = [];
const blocks = AiScript.blockDefs.filter(block => type === null || block.out === null || block.out === type);
const blocks = blockDefs.filter(block => type === null || block.out === null || block.out === type);
for (const block of blocks) {
const category = list.find(x => x.category === block.category);

View file

@ -20,13 +20,13 @@ export default Vue.extend({
methods: {
click() {
if (this.value.action === 'dialog') {
this.script.reEval();
this.script.eval();
this.$root.dialog({
text: this.script.interpolate(this.value.content)
});
} else if (this.value.action === 'resetRandom') {
this.script.aiScript.updateRandomSeed(Math.random());
this.script.reEval();
this.script.eval();
}
}
}

View file

@ -1,5 +1,5 @@
<template>
<div v-show="script.vars.find(x => x.name === value.var).value">
<div v-show="script.vars[value.var]">
<x-block v-for="child in value.children" :value="child" :page="page" :script="script" :key="child.id" :h="h"/>
</div>
</template>

View file

@ -26,7 +26,7 @@ export default Vue.extend({
watch: {
v() {
this.script.aiScript.updatePageVar(this.value.name, this.v);
this.script.reEval();
this.script.eval();
}
}
});

View file

@ -26,7 +26,7 @@ export default Vue.extend({
watch: {
v() {
this.script.aiScript.updatePageVar(this.value.name, this.v);
this.script.reEval();
this.script.eval();
}
}
});

View file

@ -26,7 +26,7 @@ export default Vue.extend({
watch: {
v() {
this.script.aiScript.updatePageVar(this.value.name, this.v);
this.script.reEval();
this.script.eval();
}
}
});

View file

@ -26,7 +26,7 @@ export default Vue.extend({
watch: {
v() {
this.script.aiScript.updatePageVar(this.value.name, this.v);
this.script.reEval();
this.script.eval();
}
}
});

View file

@ -11,6 +11,7 @@
<footer>
<small>@{{ page.user.username }}</small>
<router-link v-if="$store.getters.isSignedIn && $store.state.i.id === page.userId" :to="`/i/pages/edit/${page.id}`">{{ $t('edit-this-page') }}</router-link>
<router-link :to="`./${page.name}/view-source`">{{ $t('view-source') }}</router-link>
</footer>
</div>
</template>
@ -18,30 +19,36 @@
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../../i18n';
import { faICursor, faPlus, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
import { faICursor, faPlus } from '@fortawesome/free-solid-svg-icons';
import { faSave, faStickyNote } from '@fortawesome/free-regular-svg-icons';
import XBlock from './page.block.vue';
import { AiScript } from '../../../scripts/aiscript';
import { ASEvaluator } from '../../../../../../misc/aiscript/evaluator';
import { collectPageVars } from '../../../scripts/collect-page-vars';
import { url } from '../../../../config';
class Script {
public aiScript: AiScript;
public vars: any;
public aiScript: ASEvaluator;
private onError: any;
public vars: Record<string, any>;
constructor(aiScript) {
constructor(aiScript, onError) {
this.aiScript = aiScript;
this.vars = this.aiScript.evaluateVars();
this.onError = onError;
this.eval();
}
public reEval() {
this.vars = this.aiScript.evaluateVars();
public eval() {
try {
this.vars = this.aiScript.evaluateVars();
} catch (e) {
this.onError(e);
}
}
public interpolate(str: string) {
if (str == null) return null;
return str.replace(/\{(.+?)\}/g, match => {
const v = this.vars.find(x => x.name === match.slice(1, -1).trim()).value;
const v = this.vars[match.slice(1, -1).trim()];
return v == null ? 'NULL' : v.toString();
});
}
@ -69,7 +76,7 @@ export default Vue.extend({
return {
page: null,
script: null,
faPlus, faICursor, faSave, faStickyNote, faSquareRootAlt
faPlus, faICursor, faSave, faStickyNote
};
},
@ -80,13 +87,15 @@ export default Vue.extend({
}).then(page => {
this.page = page;
const pageVars = this.getPageVars();
this.script = new Script(new AiScript(this.page.variables, pageVars, {
this.script = new Script(new ASEvaluator(this.page.variables, pageVars, {
randomSeed: Math.random(),
user: page.user,
visitor: this.$store.state.i,
page: page,
url: url
}));
}), e => {
console.dir(e);
});
});
},
@ -146,4 +155,10 @@ export default Vue.extend({
display block
opacity 0.5
> a
font-size 14px
> a + a
margin-left 8px
</style>