GitLab 自定义 HTML 头部标签

文档

配置

vim /etc/gitlab/gitlab.rb

文件已经增加了防盗链

gitlab_rails['custom_html_header_tags'] = '|
      <script src="https://gitlab-xuxiaowei.oss-cn-qingdao.aliyuncs.com/custom_html_header_tags/index.js"></script>
      <link rel="stylesheet" href="https://gitlab-xuxiaowei.oss-cn-qingdao.aliyuncs.com/custom_html_header_tags/index.css">
'

gitlab_rails['content_security_policy'] = {
  'directives' => {
    'script_src' => "'self' 'unsafe-eval' https://gitlab-xuxiaowei.oss-cn-qingdao.aliyuncs.com",
    'style_src' => "'self' 'unsafe-inline' https://gitlab-xuxiaowei.oss-cn-qingdao.aliyuncs.com",
  }
}

index.js

文件已经增加了防盗链

let forumUrl = "https://xuxiaowei.io"
let forumName = "徐晓伟论坛"
let forumLogo = "https://gitlab-xuxiaowei.oss-cn-qingdao.aliyuncs.com/custom_html_header_tags/png/1492x512.png"
let wechatWorkUrl = "https://work.weixin.qq.com/gm/75cfc47d6a341047e4b6aca7389bdfa8"
let wechatWorkLogo = 'https://gitlab-xuxiaowei.oss-cn-qingdao.aliyuncs.com/custom_html_header_tags/png/wechat-work.jpg'

function forum() {
    let header = document.querySelector('header')
    let logos = header?.querySelectorAll('.brand-logo')
    let secondLogoLink = logos?.[1]
    if (secondLogoLink) {
        secondLogoLink.href = forumUrl
        secondLogoLink.title = forumName
        secondLogoLink.innerHTML = `<img src="${forumLogo}" alt="${forumName}" style="height: 26px">`
    }
}

function wechatWork() {
    // Select all img elements whose src attribute contains '/assets/illustrations/wechat-com-'
    let imgs = document.querySelectorAll('img[src*="/assets/illustrations/wechat-com-"]')
    let newSrc = wechatWorkLogo
    imgs.forEach(img => {
        img.src = newSrc
        let grandParent = img.parentNode.parentNode;
        if (grandParent) {
            grandParent.style.cursor = 'pointer';
            grandParent.addEventListener('click', function (e) {
                window.open(wechatWorkUrl, '_blank');
            });
        }
    })
    let blankStateBody = document.querySelectorAll('.blank-state-body')
    blankStateBody?.forEach((body) => {
        body?.querySelectorAll('p').forEach((p) => {
            p.style.display = 'none'
        })
    })
}

window.onload = function () {
    console.log('onload!')
}

window.addEventListener('DOMContentLoaded', function () {
    console.log('DOMContentLoaded!')
    forum()
    wechatWork()
})

window.addEventListener('popstate', function () {
    console.log('popstate!')
    forum();
    wechatWork();
})

window.addEventListener('load', function () {
    // Get the navigation performance entry for the current page
    let navEntry = performance.getEntriesByType('navigation')[0]

    if (navEntry && navEntry.responseStatus) {
        let status = navEntry.responseStatus
        console.log('Page status code:', status)

        if (status === 200) {
            console.log('✅ Page loaded successfully (200)')
        } else if (status === 500) {
            console.log('❌ Internal server error (500)')
        } else {
            console.log('⚠️ Other status code:', status)
        }
    } else {
        // Fallback: some older browsers don't support this
        console.log('Browser does not support responseStatus')
    }
})