From 53c2973c341e38e944faad2154f6c26380cd06f2 Mon Sep 17 00:00:00 2001 From: Misode Date: Sat, 5 Dec 2020 16:30:14 +0100 Subject: [PATCH] Add suffixInjector hook --- src/app/Mounter.ts | 12 ------ src/app/components/panels/PreviewPanel.ts | 10 +---- src/app/components/panels/TreePanel.ts | 28 +------------ src/app/hooks/renderHtml.ts | 11 +++-- src/app/hooks/suffixInjector.ts | 50 +++++++++++++++++++++++ src/app/preview/BiomeNoisePreview.ts | 1 + src/app/preview/Preview.ts | 1 + 7 files changed, 60 insertions(+), 53 deletions(-) create mode 100644 src/app/hooks/suffixInjector.ts 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())