Skip to content
Snippets Groups Projects
Select Git revision
  • 2960f3a30b3f3f30ff3765ca32e8229f454d2cda
  • master default protected
  • gh-pages
  • dependabot/npm_and_yarn/nock-14.0.8
  • dependabot/npm_and_yarn/react-dom-19.1.1
  • dependabot/npm_and_yarn/react-19.1.1
  • server-2025-08-01-57ada99c
  • server-2025-02-01-6100669a
  • server-2024-11-01-87cba042
  • server-2024-10-01-6875b7c8
  • dependabot/npm_and_yarn/path-to-regexp-8.2.0
  • server-2024-09-01-3d52575c
  • daily-tests-gha2
  • daily-tests-gha
  • server-2023-12-01-92d8fb8e
  • server-2023-11-01-a80c93fd
  • server-2023-10-01-31096085
  • coc-v2
  • server-2023-09-01-8edc3810
  • server-2023-08-01-75858a03
  • server-2023-07-01-02183d8d
  • server-2025-08-03
  • server-2025-07-01
  • 5.0.2
  • 5.0.1
  • 5.0.0
  • server-2025-06-01
  • server-2025-05-01
  • server-2025-04-03
  • server-2025-03-02
  • server-2025-03-01
  • server-2025-02-02
  • server-2025-01-01
  • server-2024-12-01
  • server-2024-11-02
  • 4.1.0
  • server-2024-09-25
  • server-2024-09-02
  • server-2024-08-01
  • server-2024-07-01
  • 4.0.0
41 results

logos.js

Blame
  • logos.js 3.20 KiB
    import Joi from 'joi'
    import {
      toSvgColor,
      brightness,
      normalizeColor,
    } from '../badge-maker/lib/color.js'
    import coalesce from '../core/base-service/coalesce.js'
    import { svg2base64 } from './svg-helpers.js'
    import loadLogos from './load-logos.js'
    import loadSimpleIcons from './load-simple-icons.js'
    const logos = loadLogos()
    const simpleIcons = loadSimpleIcons()
    
    // for backwards-compatibility with deleted logos
    const logoAliases = {
      azuredevops: 'azure-devops',
      eclipse: 'eclipse-ide',
      'gitter-white': 'gitter',
      scrutinizer: 'scrutinizer-ci',
      stackoverflow: 'stack-overflow',
      tfs: 'azure-devops',
    }
    const lightThreshold = 0.4
    const darkThreshold = 0.6
    
    function prependPrefix(s, prefix) {
      if (s === undefined) {
        return undefined
      }
    
      s = `${s}`
    
      if (s.startsWith(prefix)) {
        return s
      } else {
        return prefix + s
      }
    }
    
    function isDataUrl(s) {
      try {
        Joi.assert(s, Joi.string().dataUri())
        return true
      } catch (e) {
        return false
      }
    }
    
    // +'s are replaced with spaces when used in query params, this returns them
    // to +'s, then removes remaining whitespace.
    // https://github.com/badges/shields/pull/1546
    function decodeDataUrlFromQueryParam(value) {
      if (typeof value !== 'string') {
        return undefined
      }
      const maybeDataUrl = prependPrefix(value, 'data:')
        .replace(/ /g, '+')
        .replace(/\s/g, '')
      return isDataUrl(maybeDataUrl) ? maybeDataUrl : undefined
    }
    
    function getShieldsIcon({ name, color }) {
      if (!(name in logos)) {
        return undefined
      }
    
      const { svg, base64, isMonochrome } = logos[name]
      const svgColor = toSvgColor(color)
      if (svgColor && isMonochrome) {
        return svg2base64(svg.replace(/fill="(.+?)"/g, `fill="${svgColor}"`))
      } else {
        return base64
      }
    }
    
    function getSimpleIconStyle({ icon, style }) {
      const { hex } = icon
      if (style !== 'social' && brightness(normalizeColor(hex)) <= lightThreshold) {
        return 'light'
      }
      if (style === 'social' && brightness(normalizeColor(hex)) >= darkThreshold) {
        return 'dark'
      }
      return 'default'
    }
    
    function getSimpleIcon({ name, color, style }) {
      const key = name.replace(/ /g, '-')
    
      if (!(key in simpleIcons)) {
        return undefined
      }
    
      const svgColor = toSvgColor(color)
      if (svgColor) {
        return svg2base64(
          simpleIcons[key].svg.replace('<svg', `<svg fill="${svgColor}"`)
        )
      } else {
        const iconStyle = getSimpleIconStyle({ icon: simpleIcons[key], style })
        return simpleIcons[key].base64[iconStyle]
      }
    }
    
    function prepareNamedLogo({ name, color, style }) {
      if (typeof name !== 'string') {
        return undefined
      }
    
      name = name.toLowerCase()
    
      if (name in logoAliases) {
        name = logoAliases[name]
      }
    
      return (
        getShieldsIcon({ name, color }) || getSimpleIcon({ name, color, style })
      )
    }
    
    function makeLogo(defaultNamedLogo, overrides) {
      const maybeDataUrl = decodeDataUrlFromQueryParam(overrides.logo)
      if (maybeDataUrl) {
        return maybeDataUrl
      } else {
        return prepareNamedLogo({
          name: coalesce(overrides.logo, defaultNamedLogo),
          color: overrides.logoColor,
          style: overrides.style,
        })
      }
    }
    
    export {
      prependPrefix,
      isDataUrl,
      decodeDataUrlFromQueryParam,
      prepareNamedLogo,
      getShieldsIcon,
      getSimpleIcon,
      makeLogo,
    }