diff --git a/src/app/hooks/getFilterKey.ts b/src/app/hooks/getFilterKey.ts new file mode 100644 index 00000000..aaaa4c4a --- /dev/null +++ b/src/app/hooks/getFilterKey.ts @@ -0,0 +1,24 @@ +import { Hook, ModelPath, relativePath } from '@mcschema/core' + +export const getFilterKey: Hook<[ModelPath, number?], string | null> = { + base: () => null, + boolean: () => null, + choice: () => null, + list: () => null, + map: () => null, + number: () => null, + string: () => null, + object({ filter, getActiveFields }, path, origin, depth = 0) { + if (depth > 2) return null + if (filter) { + const filtered = relativePath(path, filter) + if (filtered && filtered.pop().equals(origin)) return filtered.last() as string + } + const activeFields = getActiveFields(path) + for (const k of Object.keys(activeFields)) { + const filtered = activeFields[k].hook(this, path.push(k), origin, depth += 1) + if (filtered) return filtered + } + return null + } +} diff --git a/src/app/hooks/renderHtml.ts b/src/app/hooks/renderHtml.ts index 596320e5..178c48ad 100644 --- a/src/app/hooks/renderHtml.ts +++ b/src/app/hooks/renderHtml.ts @@ -5,6 +5,7 @@ import { hexId, htmlEncode } from '../Utils' import { suffixInjector } from './suffixInjector' import { Octicon } from '../components/Octicon' import { App, BlockStateRegistry } from '../App' +import { getFilterKey } from './getFilterKey' /** * Secondary model used to remember the keys of a map @@ -163,7 +164,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = { return ['', ``, ''] }, - object({ node, getActiveFields, getChildModelPath }, path, value, mounter) { + object({ node, getActiveFields, getChildModelPath, filter }, path, value, mounter) { let prefix = '' if (node.optional()) { if (value === undefined) { @@ -172,13 +173,19 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = { prefix = `` } } - let suffix = node.hook(suffixInjector, path, mounter) || '' + let suffix = '' let body = '' if (typeof value === 'object' && value !== undefined && (!(node.optional() && value === undefined))) { const activeFields = getActiveFields(path) + const activeKeys = Object.keys(activeFields) + const filterKey = path.modelArr.length === 0 ? null : node.hook(getFilterKey, path, path) + if (filterKey) { + suffix += activeFields[filterKey].hook(this, path.push(filterKey), value[filterKey], mounter)[1] + } body = (App.treeMinimized.get() - ? Object.keys(activeFields).filter(k => value[k] !== undefined) - : Object.keys(activeFields)) + ? activeKeys.filter(k => value[k] !== undefined) + : activeKeys) + .filter(k => filterKey !== k) .filter(k => activeFields[k].enabled(path)) .map(k => { const field = activeFields[k] @@ -204,6 +211,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = { }) .join('') } + suffix += node.hook(suffixInjector, path, mounter) || '' return ['', prefix + suffix, body] }, diff --git a/src/styles/nodes.css b/src/styles/nodes.css index 7bf3cdf9..ae048ed4 100644 --- a/src/styles/nodes.css +++ b/src/styles/nodes.css @@ -306,6 +306,7 @@ span.menu-item { border-left: none; } +.node-entry > .object-node > .node-body > .node > .node-header > .node-icon + *, .node-entry > .object-node > .node-body > .node > .node-header > *:first-child { border-top-left-radius: 0; border-bottom-left-radius: 0; @@ -337,6 +338,12 @@ span.menu-item { margin-top: 4px; } +.node-entry > .object-node[data-category] > .node-header > .node-icon + *, +.node-entry > .object-node[data-category] > .node-header > *:first-child { + border-top-left-radius: 0; + border-left: none; +} + .node-entry > .object-node[data-category] > .node-body, .node-entry > .list-node[data-category] > .node-body, .node-entry > .map-node[data-category] > .node-body {