Просмотр исходного кода

Merge pull request #22940 from overleaf/mj-font-script

[web] Add script for updating unfilled font

GitOrigin-RevId: c25a470e5263f62a9d445b10e66fa222b9fa8fa5
Mathias Jakobsen 1 год назад
Родитель
Сommit
5b7ca476a7

+ 48 - 0
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)

+ 1 - 3
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');
 }

+ 11 - 0
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',
+])

+ 2 - 8
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