From 6c7340977e310b7b6a691969a076d213ae952635 Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Thu, 10 Jun 2021 12:49:44 +0430 Subject: [PATCH] fix: list HMR --- src/core/runtime/utils.ts | 69 ++++++++++++++++++++-- src/defaultTheme/components/atoms/List.vue | 14 ++++- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/core/runtime/utils.ts b/src/core/runtime/utils.ts index 192384c4f..d8b5636a8 100644 --- a/src/core/runtime/utils.ts +++ b/src/core/runtime/utils.ts @@ -13,6 +13,11 @@ export const TAGS_MAP = { export const expandTags = (_tags: string[]) => _tags.flatMap(t => TAGS_MAP[t]) +/** + * List of text nodes + */ +export const TEXT_TAGS = expandTags(['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li']) + // @vue/component export const Markdown = { functional: true, @@ -33,16 +38,72 @@ export const Markdown = { } } +/** + * Check virtual node's tag + * @param vnode Virtuel node from Vue virtual DOM + * @param tag tag name + * @returns `true` it the virtual node match the tag + */ export function isTag(vnode: any, tag: string): boolean { return vnode?.tag === tag || vnode?.componentOptions?.tag === tag || vnode?.asyncMeta?.tag === tag } +/** + * Find children of a virtual node + * @param vnode Virtuel node from Vue virtual DOM + * @returns Children of given node + */ +export function nodeChildren(vnode) { + return vnode.children || vnode?.componentOptions?.children || vnode?.asyncMeta?.children +} + +/** + * Calculate text content of a virtual node + * @param vnode Virtuel node from Vue virtual DOM + * @returns text content of given node + */ +export function nodeTextContent(vnode: any) { + if (Array.isArray(vnode)) { + return vnode.map(nodeTextContent).join('') + } + + // Check for text node + if (vnode.text) { + return vnode.text + } + + // Walk through node children + const children = nodeChildren(vnode) + if (Array.isArray(children)) { + return children.map(nodeTextContent).join('') + } + + // Return empty string for non-text nodes without any children + return '' +} + +/** + * Unwrap tags within a virtual node + * @param vnode Virtuel node from Vue virtual DOM + * @param tags list of tags to unwrap + * @returns + */ export function unwrap(vnode: any, tags = ['p']) { + if (Array.isArray(vnode)) { + return vnode.flatMap(node => unwrap(node, tags)) + } tags = expandTags(tags) - const needUnwrap = tags.some(tag => isTag(vnode, tag)) - return needUnwrap - ? vnode.children || vnode?.componentOptions?.children || vnode?.asyncMeta?.children || [vnode] - : [vnode] + let result = vnode + + // unwrapp children + if (tags.some(tag => isTag(vnode, tag))) { + result = nodeChildren(vnode) || vnode + if (TEXT_TAGS.some(tag => isTag(vnode, tag))) { + result = [result] + } + } + + return result } export function flatUnwrap(vnodes: any[], tags = ['p']) { diff --git a/src/defaultTheme/components/atoms/List.vue b/src/defaultTheme/components/atoms/List.vue index 6ec1027e0..be21f0d8f 100644 --- a/src/defaultTheme/components/atoms/List.vue +++ b/src/defaultTheme/components/atoms/List.vue @@ -12,9 +12,8 @@