I rewrote the frontend in React using a module bundler. It's matched feature-for-feature with the current frontend, with only slight changes in the styling. I did not fuss about making the styling identical; the badge popup looks particularly different. This makes the front end much easier to develop. I'm really looking forward to implementing #701, to which this paves the way. This makes light use of Next.js, which provides webpack config and dev/build tooling. We’ll probably replace it with create-react-app or our own webpack setup because unfortunately it comes with a lot of runtime overhead (the build is 400k). Let’s open new issues for bugs and features, and track other follow-ups here: https://github.com/badges/shields/projects/1
75 lines
1.9 KiB
JavaScript
75 lines
1.9 KiB
JavaScript
export function markdown(badgeUri, link, title) {
|
|
const withoutLink = ``;
|
|
if (link) {
|
|
return `[${withoutLink}](${link})`;
|
|
} else {
|
|
return withoutLink;
|
|
}
|
|
}
|
|
|
|
export function reStructuredText(badgeUri, link, title) {
|
|
let result = `.. image:: ${badgeUri}`;
|
|
if (title) {
|
|
result += ` :alt: ${title}`;
|
|
}
|
|
if (link) {
|
|
result += ` :target: ${link}`;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function quoteAsciiDocAttribute(attr) {
|
|
if (typeof attr === 'string') {
|
|
const withQuotesEscaped = attr.replace('"', '\\"');
|
|
return `"${withQuotesEscaped}"`;
|
|
} else if (attr == null) {
|
|
return 'None';
|
|
} else {
|
|
return attr;
|
|
}
|
|
}
|
|
|
|
// lodash.mapvalues is huge!
|
|
function mapValues(obj, iteratee) {
|
|
const result = {};
|
|
for (const k in obj) {
|
|
result[k] = iteratee(obj[k]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function renderAsciiDocAttributes(positional, named) {
|
|
// http://asciidoc.org/userguide.html#X21
|
|
const needsQuoting = positional.some(attr => attr.includes(',')) ||
|
|
Object.keys(named).length > 0;
|
|
|
|
if (needsQuoting) {
|
|
positional = positional.map(attr => quoteAsciiDocAttribute(attr));
|
|
named = mapValues(named, attr => quoteAsciiDocAttribute(attr));
|
|
}
|
|
|
|
const items = positional
|
|
.concat(Object.entries(named).map(([k, v]) => `${k}=${v}`));
|
|
|
|
if (items.length) {
|
|
return `[${items.join(',')}]`;
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
export function asciiDoc(badgeUri, link, title) {
|
|
const positional = title ? [title] : [];
|
|
const named = link ? { link } : {};
|
|
const attrs = renderAsciiDocAttributes(positional, named);
|
|
return `image:${badgeUri}${attrs}`;
|
|
}
|
|
|
|
export default function generateAllMarkup(badgeUri, link, title) {
|
|
// This is a wee bit "clever". It runs each of the three functions on the
|
|
// parameters provided, and returns the result in an object.
|
|
return mapValues(
|
|
{ markdown, reStructuredText, asciiDoc },
|
|
fn => fn(badgeUri, link, title));
|
|
}
|