Files
shields/lib/logos.js
chris48s 504015c0ba migrate hapi/joi to joi (#5624)
* update joi + joi-extension-semver

* @hapi/joi --> joi

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2020-09-30 17:51:02 +00:00

143 lines
3.2 KiB
JavaScript

'use strict'
const Joi = require('joi')
const {
toSvgColor,
brightness,
normalizeColor,
} = require('../badge-maker/lib/color')
const coalesce = require('../core/base-service/coalesce')
const { svg2base64 } = require('./svg-helpers')
const logos = require('./load-logos')()
const simpleIcons = require('./load-simple-icons')()
// 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,
})
}
}
module.exports = {
prependPrefix,
isDataUrl,
decodeDataUrlFromQueryParam,
prepareNamedLogo,
getShieldsIcon,
getSimpleIcon,
makeLogo,
}