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

Merge pull request #21680 from overleaf/rd-dyslexic-font

Add OpenDyslexic Mono typeface font to the source editor

GitOrigin-RevId: 8826e51cfa50f1d5ffc2217fb86fb4d1dec21b92
Rebeka Dekany 1 год назад
Родитель
Сommit
4563273396

+ 2 - 0
services/web/frontend/extracted-translations.json

@@ -215,6 +215,7 @@
   "clear_cached_files": "",
   "clear_search": "",
   "click_here_to_view_sl_in_lng": "",
+  "click_to_give_feedback": "",
   "clicking_delete_will_remove_sso_config_and_clear_saml_data": "",
   "clone_with_git": "",
   "close": "",
@@ -934,6 +935,7 @@
   "new_compile_domain_notice": "",
   "new_file": "",
   "new_folder": "",
+  "new_font_open_dyslexic": "",
   "new_name": "",
   "new_password": "",
   "new_project": "",

+ 1 - 0
services/web/frontend/fonts/README.md

@@ -7,6 +7,7 @@ This directory contains fonts used by the Overleaf web application.
 * [Merriweather](https://github.com/SorkinType/Merriweather)
 * [Noto Sans](https://notofonts.github.io/#latin-greek-cyrillic)
 * [Noto Serif](https://notofonts.github.io/#latin-greek-cyrillic)
+* [OpenDyslexic Mono](https://github.com/antijingoist/opendyslexic/tree/master)
 * [Open Sans](https://github.com/googlefonts/opensans)
 * [Source Code Pro](https://github.com/adobe-fonts/source-code-pro)
 * [STIX Two Math](https://github.com/stipub/stixfonts/)

+ 8 - 0
services/web/frontend/fonts/build-fonts.mjs

@@ -71,6 +71,14 @@ const families = [
     license:
       'https://raw.githubusercontent.com/notofonts/latin-greek-cyrillic/refs/heads/main/OFL.txt',
   },
+  {
+    folder: 'open-dyslexic-mono',
+    url: 'https://github.com/antijingoist/opendyslexic',
+    fonts: [
+      'https://github.com/antijingoist/open-dyslexic/blob/master/otf/OpenDyslexicMono-Regular.otf',
+    ],
+    license: 'https://github.com/antijingoist/opendyslexic/blob/master/OFL.txt',
+  },
   {
     folder: 'open-sans',
     url: 'https://github.com/googlefonts/opensans',

+ 94 - 0
services/web/frontend/fonts/open-dyslexic-mono/OFL.txt

@@ -0,0 +1,94 @@
+Copyright (c) 2019-07-29, Abbie Gonzalez (https://abbiecod.es|support@abbiecod.es),
+with Reserved Font Name OpenDyslexic.
+Copyright (c) 12/2012 - 2019
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

BIN
services/web/frontend/fonts/open-dyslexic-mono/OpenDyslexicMono-Regular.woff2


+ 6 - 0
services/web/frontend/fonts/open-dyslexic-mono/open-dyslexic-mono.css

@@ -0,0 +1,6 @@
+@font-face {
+  font-family: 'OpenDyslexic Mono';
+  src: url('./OpenDyslexicMono-Regular.woff2') format('woff2');
+  font-style: normal;
+  font-weight: normal;
+}

+ 42 - 16
services/web/frontend/js/features/editor-left-menu/components/settings/settings-font-family.tsx

@@ -2,27 +2,53 @@ import { useTranslation } from 'react-i18next'
 import { FontFamily } from '../../../source-editor/extensions/theme'
 import { useProjectSettingsContext } from '../../context/project-settings-context'
 import SettingsMenuSelect from './settings-menu-select'
+import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
+import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
+import MaterialIcon from '@/shared/components/material-icon'
 
 export default function SettingsFontFamily() {
   const { t } = useTranslation()
   const { fontFamily, setFontFamily } = useProjectSettingsContext()
 
   return (
-    <SettingsMenuSelect<FontFamily>
-      onChange={setFontFamily}
-      value={fontFamily}
-      options={[
-        {
-          value: 'monaco',
-          label: 'Monaco / Menlo / Consolas',
-        },
-        {
-          value: 'lucida',
-          label: 'Lucida / Source Code Pro',
-        },
-      ]}
-      label={t('font_family')}
-      name="fontFamily"
-    />
+    <div className="left-menu-setting-position">
+      <SettingsMenuSelect<FontFamily>
+        onChange={setFontFamily}
+        value={fontFamily}
+        options={[
+          {
+            value: 'monaco',
+            label: 'Monaco / Menlo / Consolas',
+          },
+          {
+            value: 'lucida',
+            label: 'Lucida / Source Code Pro',
+          },
+          {
+            value: 'opendyslexicmono',
+            label: 'OpenDyslexic Mono',
+          },
+        ]}
+        label={t('font_family')}
+        name="fontFamily"
+      />
+      <OLTooltip
+        id="font-family-tooltip"
+        description={`${t('new_font_open_dyslexic')} ${t('click_to_give_feedback')}`}
+        overlayProps={{ placement: 'right' }}
+      >
+        <a
+          href="https://docs.google.com/forms/d/e/1FAIpQLScOt_IHTrcaM_uitP9dgCo_r4dl4cy9Ry6LhYYcwTN4qDTDUg/viewform"
+          className="left-menu-setting-icon"
+          target="_blank"
+          rel="noreferrer noopener"
+        >
+          <BootstrapVersionSwitcher
+            bs3={<span className="info-badge" />}
+            bs5={<MaterialIcon type="info" className="info-badge" />}
+          />
+        </a>
+      </OLTooltip>
+    </div>
   )
 }

+ 2 - 1
services/web/frontend/js/features/history/extensions/theme.ts

@@ -1,7 +1,7 @@
 import { EditorView } from '@codemirror/view'
 import { Compartment, TransactionSpec } from '@codemirror/state'
 
-export type FontFamily = 'monaco' | 'lucida'
+export type FontFamily = 'monaco' | 'lucida' | 'opendyslexicmono'
 export type LineHeight = 'compact' | 'normal' | 'wide'
 
 export type Options = {
@@ -26,6 +26,7 @@ export const lineHeights: Record<LineHeight, number> = {
 const fontFamilies: Record<FontFamily, string[]> = {
   monaco: ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'monospace'],
   lucida: ['Lucida Console', 'Source Code Pro', 'monospace'],
+  opendyslexicmono: ['OpenDyslexic Mono', 'monospace'],
 }
 
 const createThemeFromOptions = ({

+ 2 - 1
services/web/frontend/js/features/source-editor/extensions/theme.ts

@@ -8,7 +8,7 @@ const optionsThemeConf = new Compartment()
 const selectedThemeConf = new Compartment()
 export const themeOptionsChange = Annotation.define<boolean>()
 
-export type FontFamily = 'monaco' | 'lucida'
+export type FontFamily = 'monaco' | 'lucida' | 'opendyslexicmono'
 export type LineHeight = 'compact' | 'normal' | 'wide'
 export type OverallTheme = '' | 'light-'
 
@@ -62,6 +62,7 @@ export const lineHeights: Record<LineHeight, number> = {
 const fontFamilies: Record<FontFamily, string[]> = {
   monaco: ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'monospace'],
   lucida: ['Lucida Console', 'Source Code Pro', 'monospace'],
+  opendyslexicmono: ['OpenDyslexic Mono', 'monospace'],
 }
 
 const createThemeFromOptions = ({

+ 14 - 0
services/web/frontend/stylesheets/app/editor/left-menu.less

@@ -146,6 +146,20 @@
     }
   }
 
+  .left-menu-setting-position {
+    position: relative;
+
+    .left-menu-setting {
+      margin-top: 0 !important;
+    }
+
+    .left-menu-setting-icon {
+      position: absolute;
+      right: 65%;
+      top: 25%;
+    }
+  }
+
   .left-menu-setting {
     padding: 0 9px;
     display: flex;

+ 1 - 0
services/web/frontend/stylesheets/bootstrap-5/main-style.scss

@@ -5,6 +5,7 @@
 @import '../../fonts/source-code-pro/source-code-pro.css';
 @import '../../fonts/STIXTwoMath/stix-two-math.css';
 @import '../../fonts/noto-serif/noto-serif.css';
+@import '../../fonts/open-dyslexic-mono/open-dyslexic-mono.css';
 @import '../../fonts/material-symbols/material-symbols.css';
 @import '../../fonts/font-awesome/font-awesome.css';
 

+ 14 - 0
services/web/frontend/stylesheets/bootstrap-5/pages/editor/left-menu.scss

@@ -129,6 +129,20 @@
     }
   }
 
+  .left-menu-setting-position {
+    position: relative;
+
+    .left-menu-setting {
+      margin-top: 0 !important;
+    }
+
+    .left-menu-setting-icon {
+      position: absolute;
+      right: 65%;
+      top: 30%;
+    }
+  }
+
   .left-menu-setting {
     padding: 0 var(--spacing-02);
     display: flex;

+ 1 - 0
services/web/frontend/stylesheets/main-style.less

@@ -5,6 +5,7 @@
 @import (less) '../fonts/source-code-pro/source-code-pro.css';
 @import (less) '../fonts/STIXTwoMath/stix-two-math.css';
 @import (less) '../fonts/noto-serif/noto-serif.css';
+@import (less) '../fonts/open-dyslexic-mono/open-dyslexic-mono.css';
 @import (less) '../fonts/material-symbols/material-symbols.css';
 
 @is-overleaf-light: false;

+ 2 - 0
services/web/locales/en.json

@@ -289,6 +289,7 @@
   "clearing": "Clearing",
   "click_here_to_view_sl_in_lng": "Click here to use __appName__ in <0>__lngName__</0>",
   "click_link_to_proceed": "Click <b>__clickText__</b> below to proceed.",
+  "click_to_give_feedback": "Click to give feedback.",
   "clicking_delete_will_remove_sso_config_and_clear_saml_data": "Clicking <0>Delete</0> will remove your SSO configuration and unlink all users. You can only do this when SSO is disabled in your Group settings.",
   "clone_with_git": "Clone with Git",
   "close": "Close",
@@ -1328,6 +1329,7 @@
   "new_compile_domain_notice": "We’ve recently migrated PDF downloads to a new domain. Something might be blocking your browser from accessing that new domain, <0>__compilesUserContentDomain__</0>. This could be caused by network blocking or a strict browser plugin rule. Please follow our <1>troubleshooting guide</1>.",
   "new_file": "New file",
   "new_folder": "New folder",
+  "new_font_open_dyslexic": "New font: OpenDyslexic Mono is designed to improve readability for those with dyslexia.",
   "new_name": "New Name",
   "new_password": "New Password",
   "new_project": "New Project",

+ 2 - 1
services/web/test/frontend/components/editor-left-menu/editor-left-menu.spec.tsx

@@ -729,12 +729,13 @@ describe('<EditorLeftMenu />', function () {
         cy.get<HTMLOptionElement>('#settings-menu-fontFamily option').then(
           options => {
             const values = [...options].map(o => o.value)
-            expect(values).to.deep.eq(['monaco', 'lucida'])
+            expect(values).to.deep.eq(['monaco', 'lucida', 'opendyslexicmono'])
 
             const texts = [...options].map(o => o.text)
             expect(texts).to.deep.eq([
               'Monaco / Menlo / Consolas',
               'Lucida / Source Code Pro',
+              'OpenDyslexic Mono',
             ])
           }
         )

+ 5 - 0
services/web/test/frontend/features/editor-left-menu/components/settings/settings-font-family.test.tsx

@@ -19,5 +19,10 @@ describe('<SettingsFontFamily />', function () {
 
     const optionLucida = within(select).getByText('Lucida / Source Code Pro')
     expect(optionLucida.getAttribute('value')).to.equal('lucida')
+
+    const optionOpenDyslexicMono = within(select).getByText('OpenDyslexic Mono')
+    expect(optionOpenDyslexicMono.getAttribute('value')).to.equal(
+      'opendyslexicmono'
+    )
   })
 })