From 5b7ca476a704e5d55a78605a52f97c261b8c2689 Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen Date: Mon, 20 Jan 2025 11:50:27 +0000 Subject: [PATCH] Merge pull request #22940 from overleaf/mj-font-script [web] Add script for updating unfilled font GitOrigin-RevId: c25a470e5263f62a9d445b10e66fa222b9fa8fa5 --- .../fonts/material-symbols/build-unfilled.mjs | 48 +++++++++++++++++++ .../material-symbols/material-symbols.css | 4 +- .../material-symbols/unfilled-symbols.mjs | 11 +++++ .../js/shared/components/material-icon.tsx | 10 +--- 4 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 services/web/frontend/fonts/material-symbols/build-unfilled.mjs create mode 100644 services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs diff --git a/services/web/frontend/fonts/material-symbols/build-unfilled.mjs b/services/web/frontend/fonts/material-symbols/build-unfilled.mjs new file mode 100644 index 0000000000..1c37bc9ae4 --- /dev/null +++ b/services/web/frontend/fonts/material-symbols/build-unfilled.mjs @@ -0,0 +1,48 @@ +import path from 'node:path' +import fs from 'node:fs/promises' +import icons from './unfilled-symbols.mjs' + +const iconList = [...new Set(icons)].sort().map(encodeURIComponent).join(',') + +const url = `https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20,400,0,0&icon_names=${iconList}&display=block` +console.log(`Fetching font configuration from ${url}`) + +const cssFile = await ( + await fetch(url, { + headers: { + // Specify a user agent to get a woff2 file + 'User-Agent': + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36', + }, + }) +).text() + +const woff2UrlText = cssFile.match(/url\(([^)]+)\) format\('woff2'\)/)?.[1] + +if (!woff2UrlText) { + throw new Error( + 'Could not find woff2 URL in CSS file, try accessing the font configuration URL to check whether an error is reported' + ) +} + +const woff2Url = new URL(woff2UrlText) +if (woff2Url.protocol !== 'https:') { + throw new Error(`Expected HTTPS URL, got ${woff2Url.protocol}`) +} +if (woff2Url.hostname !== 'fonts.gstatic.com') { + throw new Error( + `Expected to download font from fonts.gstatic.com, got ${woff2Url.hostname}` + ) +} + +console.log(`Fetching woff2 file: ${woff2Url}`) + +const outputPath = path.join( + import.meta.dirname, + 'MaterialSymbolsRoundedUnfilledPartialSlice.woff2' +) + +const res = await fetch(woff2Url) + +console.log(`Saving font file to ${outputPath}`) +await fs.writeFile(outputPath, res.body) diff --git a/services/web/frontend/fonts/material-symbols/material-symbols.css b/services/web/frontend/fonts/material-symbols/material-symbols.css index 7fda97b6ef..6ffcdd4288 100644 --- a/services/web/frontend/fonts/material-symbols/material-symbols.css +++ b/services/web/frontend/fonts/material-symbols/material-symbols.css @@ -16,9 +16,7 @@ font-weight: 400; font-display: block; /* - Generated by accessing - https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20,400,0,0&icon_names=SORTED_SYMBOL_LIST&display=block - with a sorted list of symbols, and downloading the linked woff2 file. + Generated by frontend/fonts/material-symbols/build-unfilled.mjs */ src: url('MaterialSymbolsRoundedUnfilledPartialSlice.woff2') format('woff2'); } diff --git a/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs b/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs new file mode 100644 index 0000000000..7463addc64 --- /dev/null +++ b/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs @@ -0,0 +1,11 @@ +// @ts-check +// Make sure to run the build-unfilled.mjs script after updating this list +// to update the font file with the latest icons. + +export default /** @type {const} */ ([ + 'description', + 'forum', + 'integration_instructions', + 'rate_review', + 'report', +]) diff --git a/services/web/frontend/js/shared/components/material-icon.tsx b/services/web/frontend/js/shared/components/material-icon.tsx index 19305b7e60..3f5a499853 100644 --- a/services/web/frontend/js/shared/components/material-icon.tsx +++ b/services/web/frontend/js/shared/components/material-icon.tsx @@ -1,15 +1,9 @@ import classNames from 'classnames' import React from 'react' import { bsVersion } from '@/features/utils/bootstrap-5' +import unfilledIconTypes from '../../../fonts/material-symbols/unfilled-symbols.mjs' -// NOTE: When updating this list, make sure to update the bundled .woff2 -// file as well. See details in material-symbols.css -export type AvailableUnfilledIcon = - | 'description' - | 'forum' - | 'integration_instructions' - | 'rate_review' - | 'report' +export type AvailableUnfilledIcon = (typeof unfilledIconTypes)[number] type BaseIconProps = React.ComponentProps<'i'> & { accessibilityLabel?: string