Skip to content

Commit

Permalink
fix(client): avoid updating existing head tags, close #1268
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Apr 20, 2023
1 parent 1fe9635 commit b109e39
Showing 1 changed file with 29 additions and 15 deletions.
44 changes: 29 additions & 15 deletions packages/client/src/setupUpdateHead.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { isPlainObject, isString } from '@vuepress/shared'
import {
isPlainObject,
isString,
resolveHeadIdentifier,
} from '@vuepress/shared'
import type { HeadConfig, VuepressSSRContext } from '@vuepress/shared'
import { onMounted, provide, ref, useSSRContext, watch } from 'vue'
import {
Expand All @@ -25,35 +29,45 @@ export const setupUpdateHead = (): void => {
return
}

const headTags = ref<HTMLElement[]>([])
const headTags = ref<{ el: HTMLElement; id: string }[]>([])

// load current head tags from DOM
const loadHead = (): void => {
head.value.forEach((item) => {
const tag = queryHeadTag(item)
if (tag) {
headTags.value.push(tag)
headTags.value.push({ el: tag, id: resolveHeadIdentifier(item) })
}
})
}

// update html lang attribute and head tags to DOM
const updateHead: UpdateHead = () => {
document.documentElement.lang = lang.value
const oldHeadTags = headTags.value
const newHeadTags = head.value
.map((item) => ({
id: resolveHeadIdentifier(item),
el: createHeadTag(item),
}))
.filter(({ el }) => el !== null)

headTags.value.forEach((item) => {
if (item.parentNode === document.head) {
document.head.removeChild(item)
}
// update lang
if (document.documentElement.lang !== lang.value)
document.documentElement.lang = lang.value

oldHeadTags.forEach(({ el, id: oldID }) => {
const existingHeaIndex = newHeadTags.findIndex(({ id }) => id === oldID)

// remove the tag in new tags to preserve it
if (existingHeaIndex !== -1) newHeadTags.splice(existingHeaIndex, 1)
// remove old head tags
else document.head.removeChild(el)
})
headTags.value.splice(0, headTags.value.length)

head.value.forEach((item) => {
const tag = createHeadTag(item)
if (tag !== null) {
document.head.appendChild(tag)
headTags.value.push(tag)
}
// append new head tags
newHeadTags.forEach((head) => {
document.head.appendChild(head.el)
headTags.value.push(head)
})
}
provide(updateHeadSymbol, updateHead)
Expand Down

0 comments on commit b109e39

Please sign in to comment.