) {
- super(fields, mods)
- this.id = id
- }
-
- render(path: Path, value: IObject, view: TreeView) {
- value = value ?? {}
- return `
- ${Object.keys(this.fields).map(f => {
- return this.fields[f].render(path.push(f), value[f], view)
- }).join('')}
-
`
- }
-}
diff --git a/src/nodes/custom/ResourceNode.ts b/src/nodes/custom/ResourceNode.ts
index 1d6d3d74..1fab1ab1 100644
--- a/src/nodes/custom/ResourceNode.ts
+++ b/src/nodes/custom/ResourceNode.ts
@@ -17,7 +17,7 @@ export class ResourceNode extends EnumNode {
const options = mods?.options ?? [] // TODO: Support registry using `github.com/Arcensoth/mcdata`
super(options, {
transform: (v) => {
- if (v === undefined) return undefined
+ if (v === undefined || v.length === 0) return undefined
return v.startsWith('minecraft:') ? v : 'minecraft:' + v
}, ...mods})
this.additional = mods?.additional ?? false
diff --git a/src/schemas/Sandbox.ts b/src/schemas/Sandbox.ts
index 457e1eb8..803ac839 100644
--- a/src/schemas/Sandbox.ts
+++ b/src/schemas/Sandbox.ts
@@ -1,9 +1,7 @@
import { ObjectNode } from '../nodes/ObjectNode';
import { EnumNode } from '../nodes/EnumNode';
-import { ResourceNode } from '../nodes/custom/ResourceNode';
import { NumberNode } from '../nodes/NumberNode';
import { BooleanNode } from '../nodes/BooleanNode';
-import { RootNode } from '../nodes/RootNode';
import { RangeNode } from '../nodes/custom/RangeNode';
import { MapNode } from '../nodes/MapNode';
import { StringNode } from '../nodes/StringNode';
@@ -11,10 +9,9 @@ import { ListNode } from '../nodes/ListNode';
const EntityCollection = ['sheep', 'pig']
-export const SandboxSchema = new RootNode('predicate', {
+export const SandboxSchema = new ObjectNode({
condition: new EnumNode(['foo', 'bar'], {
- default: () => 'bar',
- transform: (s: string) => (s === 'foo') ? {test: 'baz'} : s
+ default: () => 'bar'
}),
number: new NumberNode({integer: false, min: 0}),
range: new RangeNode({
@@ -22,14 +19,18 @@ export const SandboxSchema = new RootNode('predicate', {
}),
predicate: new ObjectNode({
type: new EnumNode(EntityCollection),
- nbt: new ResourceNode({
+ nbt: new StringNode({
default: (v) => 'hahaha'
}),
test: new BooleanNode({force: () => true}),
recipes: new MapNode(
new StringNode(),
new RangeNode({
- default: (v) => RangeNode.isExact(v) ? 2 : v
+ default: (v) => RangeNode.isExact(v) ? 2 : v,
+ transform: (v: any) => RangeNode.isRange(v) ? ({
+ min: v?.min ?? -2147483648,
+ max: v?.max ?? 2147483647
+ }) : v
})
)
}),
@@ -49,5 +50,6 @@ export const SandboxSchema = new RootNode('predicate', {
predicate: {
nbt: 'hi'
}
- })
+ }),
+ transform: (v) => v?.condition === 'foo' ? ({...v, test: 'hello'}) : v
});
diff --git a/src/view/SourceView.ts b/src/view/SourceView.ts
index 19bfaa4d..70970e14 100644
--- a/src/view/SourceView.ts
+++ b/src/view/SourceView.ts
@@ -13,7 +13,16 @@ export class SourceView implements ModelListener {
render() {
const transformed = this.model.schema.transform(new Path([], this.model), this.model.data)
- this.target.textContent = JSON.stringify(transformed)
+ const textarea = document.createElement('textarea')
+ textarea.style.width = 'calc(100% - 6px)'
+ textarea.rows = 10
+ textarea.textContent = JSON.stringify(transformed)
+ textarea.addEventListener('change', evt => {
+ const parsed = JSON.parse(textarea.value)
+ this.model.reset(parsed)
+ })
+ this.target.innerHTML = ''
+ this.target.appendChild(textarea)
}
invalidated() {
diff --git a/src/view/TreeView.ts b/src/view/TreeView.ts
index ac0aa372..915ed1cd 100644
--- a/src/view/TreeView.ts
+++ b/src/view/TreeView.ts
@@ -49,7 +49,8 @@ export class TreeView implements ModelListener {
}
render() {
- this.target.innerHTML = this.model.schema.render(new Path(), this.model.data, this)
+ this.target.innerHTML = this.model.schema.render(
+ new Path(), this.model.data, this, {hideLabel: true})
for (const id in this.registry) {
const element = this.target.querySelector(`[data-id="${id}"]`)
if (element !== null) this.registry[id](element)