diff --git a/src/app/Mounter.ts b/src/app/Mounter.ts
index 09cf502d..8e6c273d 100644
--- a/src/app/Mounter.ts
+++ b/src/app/Mounter.ts
@@ -5,28 +5,16 @@ type Registry = {
[id: string]: (el: Element) => void
}
-type NodeInjector = (path: ModelPath, mounter: Mounter) => string
-
-type TreeViewOptions = {
- nodeInjector?: NodeInjector
-}
-
export interface Mounter {
register(callback: (el: Element) => void): string
registerEvent(type: string, callback: (el: Element) => void): string
registerChange(callback: (el: Element) => void): string
registerClick(callback: (el: Element) => void): string
- nodeInjector(path: ModelPath, mounter: Mounter): string
mount(el: Element): void
}
export class Mounter implements Mounter {
registry: Registry = {}
- nodeInjector: NodeInjector
-
- constructor(options?: TreeViewOptions) {
- this.nodeInjector = options?.nodeInjector ?? (() => '')
- }
/**
* Registers a callback and gives an ID
diff --git a/src/app/components/panels/PreviewPanel.ts b/src/app/components/panels/PreviewPanel.ts
index 62f78a1e..e47c0072 100644
--- a/src/app/components/panels/PreviewPanel.ts
+++ b/src/app/components/panels/PreviewPanel.ts
@@ -1,6 +1,5 @@
import { DataModel } from '@mcschema/core';
-import { App, Previews } from '../../App';
-import { BiomeNoisePreview } from '../../preview/BiomeNoisePreview';
+import { App } from '../../App';
import { Tracker } from '../../Tracker';
import { View } from '../../views/View';
import { Octicon } from '../Octicon';
@@ -36,12 +35,7 @@ export const PreviewPanel = (view: View, model: DataModel) => {
})
App.preview.watchRun((value) => {
if (value) {
- redraw()
- }
- }, 'preview-panel')
-
- ;(Previews.biome_noise as BiomeNoisePreview).biomeColors.watch(() => {
- if (App.preview.get()?.getName() === 'biome-noise') {
+ value.redraw = redraw
redraw()
}
}, 'preview-panel')
diff --git a/src/app/components/panels/TreePanel.ts b/src/app/components/panels/TreePanel.ts
index 485460f8..12e95f30 100644
--- a/src/app/components/panels/TreePanel.ts
+++ b/src/app/components/panels/TreePanel.ts
@@ -6,7 +6,6 @@ import { Octicon } from '../Octicon';
import { Mounter } from '../../Mounter';
import { renderHtml } from '../../hooks/renderHtml';
import config from '../../../config.json'
-import { locale } from '../../Locales';
import { BiomeNoisePreview } from '../../preview/BiomeNoisePreview';
const createPopupIcon = (type: string, icon: keyof typeof Octicon, popup: string) => {
@@ -39,33 +38,8 @@ const treeViewObserver = (el: Element) => {
})
}
-const treeViewNodeInjector = (path: ModelPath, mounter: Mounter) => {
-
- let res = Object.keys(Previews).map(k => Previews[k])
- .filter(v => v.active(path))
- .map(v => {
- const id = mounter.registerClick(() => {
- Tracker.setPreview(v.getName())
- v.path = path
- App.preview.set(v)
- })
- return ``
- }).join('')
-
- if (path.pop().endsWith(new Path(['generator', 'biome_source', 'biomes']))) {
- const biomePreview = Previews.biome_noise as BiomeNoisePreview
- const biome = path.push('biome').get()
- const id = mounter.registerChange(el => {
- biomePreview.setBiomeColor(biome, (el as HTMLInputElement).value)
- biomePreview.state = {}
- })
- res += ``
- }
- return res
-}
-
export const TreePanel = (view: View, model: DataModel) => {
- const mounter = new Mounter({ nodeInjector: treeViewNodeInjector })
+ const mounter = new Mounter()
const getContent = () => {
if (App.loaded.get()) {
const path = new ModelPath(model)
diff --git a/src/app/hooks/renderHtml.ts b/src/app/hooks/renderHtml.ts
index e37bfc58..33cc61b1 100644
--- a/src/app/hooks/renderHtml.ts
+++ b/src/app/hooks/renderHtml.ts
@@ -2,6 +2,7 @@ import { Hook, ModelPath, Path, StringHookParams, ValidationOption, EnumOption,
import { locale, segmentedLocale } from '../Locales'
import { Mounter } from '../Mounter'
import { hexId, htmlEncode } from '../Utils'
+import { suffixInjector } from './suffixInjector'
/**
* Secondary model used to remember the keys of a map
@@ -69,7 +70,6 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
path.model.set(path, [...value, children.default()])
})
const suffix = ``
- + mounter.nodeInjector(path, mounter)
let body = ''
if (Array.isArray(value)) {
@@ -106,9 +106,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
path.model.set(path.push(key), children.default())
})
const keyRendered = keys.hook(this, keyPath, keyPath.get() ?? '', mounter)
- const suffix = keyRendered[1]
- + ``
- + mounter.nodeInjector(path, mounter)
+ const suffix = keyRendered[1] + ``
let body = ''
if (typeof value === 'object' && value !== undefined) {
body = Object.keys(value)
@@ -156,7 +154,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
prefix = ``
}
}
- let suffix = mounter.nodeInjector(path, mounter)
+ let suffix = node.hook(suffixInjector, path, mounter) || ''
let body = ''
if (typeof value === 'object' && value !== undefined && (!(node.optional() && value === undefined))) {
const activeFields = getActiveFields(path)
@@ -191,7 +189,8 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
evt.stopPropagation()
})
})
- return ['', rawString(params, path, inputId), '']
+ const suffix = params.node.hook(suffixInjector, path, mounter) || ''
+ return ['', rawString(params, path, inputId) + suffix, '']
}
}
diff --git a/src/app/hooks/suffixInjector.ts b/src/app/hooks/suffixInjector.ts
new file mode 100644
index 00000000..c85cfb49
--- /dev/null
+++ b/src/app/hooks/suffixInjector.ts
@@ -0,0 +1,50 @@
+import { Hook, ModelPath, Path } from '@mcschema/core'
+import { App, Previews } from '../App'
+import { Octicon } from '../components/Octicon'
+import { locale } from '../Locales'
+import { Mounter } from '../Mounter'
+import { BiomeNoisePreview } from '../preview/BiomeNoisePreview'
+import { Preview } from '../preview/Preview'
+import { Tracker } from '../Tracker'
+
+export const suffixInjector: Hook<[Mounter], string | void> = {
+ base() {},
+ boolean() {},
+ list() {},
+ map() {},
+ number() {},
+
+ choice({ switchNode }, path, mounter) {
+ return switchNode.hook(this, path, mounter)
+ },
+
+ object({}, path, mounter) {
+ if (Previews.biome_noise.active(path)) {
+ return setPreview(Previews.biome_noise, path, mounter)
+ }
+ if (Previews.noise_settings.active(path)) {
+ return setPreview(Previews.noise_settings, path, mounter)
+ }
+ },
+
+ string({}, path, mounter) {
+ if (path.endsWith(new Path(['biome']))
+ && path.pop().pop().endsWith(new Path(['generator', 'biome_source', 'biomes']))) {
+ const biomePreview = Previews.biome_noise as BiomeNoisePreview
+ const biome = path.get()
+ const id = mounter.registerChange(el => {
+ biomePreview.setBiomeColor(biome, (el as HTMLInputElement).value)
+ })
+ return ``
+ }
+ }
+}
+
+function setPreview(preview: Preview, path: ModelPath, mounter: Mounter) {
+ const id = mounter.registerClick(() => {
+ Tracker.setPreview(preview.getName())
+ preview.path = path
+ App.preview.set(preview)
+ })
+ return ``
+}
diff --git a/src/app/preview/BiomeNoisePreview.ts b/src/app/preview/BiomeNoisePreview.ts
index db14a728..efc4f115 100644
--- a/src/app/preview/BiomeNoisePreview.ts
+++ b/src/app/preview/BiomeNoisePreview.ts
@@ -23,6 +23,7 @@ export class BiomeNoisePreview extends Preview {
this.biomeColors = new Property({})
this.biomeColors.set(JSON.parse(localStorage.getItem(LOCAL_STORAGE_BIOME_COLORS) ?? '{}'))
this.noise = []
+ this.biomeColors.watch(() => this.redraw())
}
getName() {
diff --git a/src/app/preview/Preview.ts b/src/app/preview/Preview.ts
index 35b97926..3bc173d7 100644
--- a/src/app/preview/Preview.ts
+++ b/src/app/preview/Preview.ts
@@ -4,6 +4,7 @@ import { View } from "../views/View"
export abstract class Preview {
state: any
path?: ModelPath
+ redraw: () => void = () => {}
dirty(path: ModelPath): boolean {
return JSON.stringify(this.state) !== JSON.stringify(path.get())