diff --git a/src/app/hooks/canFlatten.ts b/src/app/hooks/canFlatten.ts new file mode 100644 index 00000000..deb4dabe --- /dev/null +++ b/src/app/hooks/canFlatten.ts @@ -0,0 +1,23 @@ +import { Hook } from '@mcschema/core' +import { getFilterKey } from './getFilterKey' + +export const canFlatten: Hook<[], boolean> = { + base: () => false, + boolean: () => false, + choice: () => false, + list: () => false, + map: () => false, + number: () => false, + string: () => false, + object({ node, getActiveFields }, path) { + const filterKey = path.modelArr.length === 0 ? null : node.hook(getFilterKey, path, path) + const visibleEntries = Object.entries(getActiveFields(path)) + .filter(([k, v]) => filterKey !== k && v.enabled(path)) + if (visibleEntries.length !== 1) return false + + const nestedPath = path.push(visibleEntries[0][0]) + if (visibleEntries[0][1].type(nestedPath) !== 'object') return false + + return visibleEntries[0][1].hook(getFilterKey, nestedPath, nestedPath) === null + } +} diff --git a/src/app/hooks/customValidation.ts b/src/app/hooks/customValidation.ts index b55a7243..84a0e761 100644 --- a/src/app/hooks/customValidation.ts +++ b/src/app/hooks/customValidation.ts @@ -1,5 +1,5 @@ import { Errors, Hook, relativePath } from '@mcschema/core' -import { App, BlockStateRegistry } from '../App' +import { App } from '../App' import { getFilterKey } from './getFilterKey' import { walk } from './walk' diff --git a/src/app/hooks/renderHtml.ts b/src/app/hooks/renderHtml.ts index 1a3ebb09..6d8128ab 100644 --- a/src/app/hooks/renderHtml.ts +++ b/src/app/hooks/renderHtml.ts @@ -4,8 +4,9 @@ import { Mounter } from '../views/View' import { hexId, htmlEncode } from '../Utils' import { suffixInjector } from './suffixInjector' import { Octicon } from '../components/Octicon' -import { App, BlockStateRegistry } from '../App' +import { App } from '../App' import { getFilterKey } from './getFilterKey' +import { canFlatten } from './canFlatten' /** * Secondary model used to remember the keys of a map @@ -189,7 +190,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = { : activeKeys) .filter(k => filterKey !== k) .filter(k => activeFields[k].enabled(path)) - if (visibleKeys.length === 1 && activeFields[visibleKeys[0]].type(path.push(visibleKeys[0])) === 'object') { + if (node.hook(canFlatten, path)) { const newValue = value[visibleKeys[0]] ?? {} body = activeFields[visibleKeys[0]].hook(this, path.push(visibleKeys[0]), newValue, mounter)[2] } else { diff --git a/tsconfig.json b/tsconfig.json index 7ff59641..500959ca 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "target": "es6", "lib": [ "dom", + "es2017.object", "es2019" ], "module": "esnext",