Skip to content

Commit

Permalink
feat: update
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Apr 21, 2023
1 parent f1f9134 commit 9a6d689
Showing 1 changed file with 44 additions and 13 deletions.
57 changes: 44 additions & 13 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 @@ -8,6 +12,12 @@ import {
} from './composables/index.js'
import type { UpdateHead } from './composables/index.js'

interface HeadTagInfo {
el: HTMLElement
id: string
info: HeadConfig
}

/**
* Auto update head and provide as global util
*/
Expand All @@ -25,34 +35,55 @@ export const setupUpdateHead = (): void => {
return
}

const headTags = ref<HTMLElement[]>([])
const headInfos = ref<HeadTagInfo[]>([])

// load current head tags from DOM
const loadHead = (): void => {
head.value.forEach((item) => {
const tag = queryHeadTag(item)

if (tag) {
headTags.value.push(tag)
headInfos.value.push({
el: tag,
id: resolveHeadIdentifier(item)!,
info: item,
})
}
})
}

// update html lang attribute and head tags to DOM
const updateHead: UpdateHead = () => {
document.documentElement.lang = lang.value
const oldHeadInfos = headInfos.value
const newHeadTagsConfig = head.value

// update lang
if (document.documentElement.lang !== lang.value)
document.documentElement.lang = lang.value

headTags.value.forEach((item) => {
if (item.parentNode === document.head) {
document.head.removeChild(item)
oldHeadInfos.forEach(({ el, info, id: oldId }) => {
const existingHeadIndex = newHeadTagsConfig.findIndex(
(item) => resolveHeadIdentifier(item) === oldId
)

// remove the tag in new tags to preserve it
if (existingHeadIndex !== -1) {
newHeadTagsConfig.splice(existingHeadIndex, 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
newHeadTagsConfig.forEach((head) => {
const el = createHeadTag(head)
const id = resolveHeadIdentifier(head)!

if (el) {
document.head.appendChild(el)
headInfos.value.push({ el, id, info: head })
}
})
}
Expand Down

0 comments on commit 9a6d689

Please sign in to comment.