mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.29.0
* Added: Support for OpenDyslexic and Google Fonts. Font Family settings now provide a list of fonts to choose from, in addition to allowing a custom font to be entered. * Changed: When saving a settings backup, the current date will be included in the filename by default. (Closes #1084)
This commit is contained in:
parent
a529e7fd27
commit
04cfbe6ed9
23 changed files with 394 additions and 28 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.28.7",
|
||||
"version": "4.29.0",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
|
|
BIN
res/font/OpenDyslexic-Bold.otf
Normal file
BIN
res/font/OpenDyslexic-Bold.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexic-BoldItalic.otf
Normal file
BIN
res/font/OpenDyslexic-BoldItalic.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexic-Italic.otf
Normal file
BIN
res/font/OpenDyslexic-Italic.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexic-Regular.otf
Normal file
BIN
res/font/OpenDyslexic-Regular.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexicAlta-Bold.otf
Normal file
BIN
res/font/OpenDyslexicAlta-Bold.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexicAlta-BoldItalic.otf
Normal file
BIN
res/font/OpenDyslexicAlta-BoldItalic.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexicAlta-Italic.otf
Normal file
BIN
res/font/OpenDyslexicAlta-Italic.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexicAlta-Regular.otf
Normal file
BIN
res/font/OpenDyslexicAlta-Regular.otf
Normal file
Binary file not shown.
BIN
res/font/OpenDyslexicMono-Regular.otf
Normal file
BIN
res/font/OpenDyslexicMono-Regular.otf
Normal file
Binary file not shown.
|
@ -200,7 +200,7 @@ export default {
|
|||
attrs: {
|
||||
'data-title': this.t(
|
||||
'tooltip.link-unsafe',
|
||||
"Caution: This URL is on Google's Safe Browsing List for: {reasons}",
|
||||
'Caution: This URL is has been flagged as potentially harmful by: {reasons}',
|
||||
{
|
||||
reasons: reasons.toLowerCase()
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import * as TOKENIZERS from './tokenizers';
|
|||
import * as RICH_PROVIDERS from './rich_providers';
|
||||
|
||||
import Actions from './actions';
|
||||
import { getFontsList } from 'src/utilities/fonts';
|
||||
|
||||
export const SEPARATORS = '[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]';
|
||||
|
||||
|
@ -178,7 +179,8 @@ export default class Chat extends Module {
|
|||
path: 'Chat > Appearance >> General',
|
||||
title: 'Font Family',
|
||||
description: 'Set the font used for displaying chat messages.',
|
||||
component: 'setting-text-box'
|
||||
component: 'setting-combo-box',
|
||||
data: () => getFontsList()
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ export const Links = {
|
|||
url_notice = (<div class="ffz-i-attention">
|
||||
{this.i18n.tList(
|
||||
'tooltip.link-unsafe',
|
||||
"Caution: This URL is on Google's Safe Browsing List for: {reasons}",
|
||||
'Caution: This URL is has been flagged as potentially harmful by: {reasons}',
|
||||
{reasons: reasons.toLowerCase()}
|
||||
)}
|
||||
</div>);
|
||||
|
|
|
@ -15,14 +15,32 @@
|
|||
ref="control"
|
||||
class="tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-font-size-6 ffz-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05"
|
||||
@change="onChange"
|
||||
>
|
||||
<template v-for="i in nested_data">
|
||||
<optgroup
|
||||
v-if="i.entries"
|
||||
:key="i.key"
|
||||
:disabled="i.disabled"
|
||||
:label="i.i18n_key ? t(i.i18n_key, i.title, i) : i.title"
|
||||
>
|
||||
<option
|
||||
v-for="i in data"
|
||||
v-for="j in i.entries"
|
||||
:key="j.value"
|
||||
:selected="j.value === value"
|
||||
:value="j.v"
|
||||
>
|
||||
{{ j.i18n_key ? t(j.i18n_key, j.title, j) : j.title }}
|
||||
</option>
|
||||
</optgroup>
|
||||
<option
|
||||
v-else
|
||||
:key="i.value"
|
||||
:selected="i.value === value"
|
||||
:value="i.v"
|
||||
>
|
||||
{{ i.i18n_key ? t(i.i18n_key, i.title, i) : i.title }}
|
||||
</option>
|
||||
</template>
|
||||
<option :selected="isCustom">
|
||||
{{ t('setting.combo-box.custom', 'Custom') }}
|
||||
</option>
|
||||
|
@ -91,6 +109,36 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
nested_data() {
|
||||
const out = [];
|
||||
let current_group = null;
|
||||
let i = 0;
|
||||
|
||||
for(const entry of this.data) {
|
||||
if ( entry.separator ) {
|
||||
current_group = {
|
||||
key: entry.key ?? i,
|
||||
entries: [],
|
||||
i18n_key: entry.i18n_key,
|
||||
title: entry.title,
|
||||
disabled: entry.disabled
|
||||
};
|
||||
|
||||
out.push(current_group);
|
||||
|
||||
} else if ( current_group != null )
|
||||
current_group.entries.push(Object.assign({v: i}, entry));
|
||||
else
|
||||
out.push(Object.assign({v: i}, entry));
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(val) {
|
||||
for(const item of this.data)
|
||||
|
@ -108,7 +156,7 @@ export default {
|
|||
|
||||
methods: {
|
||||
onChange() {
|
||||
const idx = this.$refs.control.selectedIndex,
|
||||
const idx = this.$refs.control.value,
|
||||
raw_value = this.data[idx];
|
||||
|
||||
if ( raw_value ) {
|
||||
|
|
|
@ -388,13 +388,16 @@ export default class SettingsManager extends Module {
|
|||
// ========================================================================
|
||||
|
||||
async generateBackupFile() {
|
||||
const now = new Date(),
|
||||
timestamp = `${now.getFullYear()}-${now.getMonth()}-${now.getDate()}`;
|
||||
|
||||
if ( await this._needsZipBackup() ) {
|
||||
const blob = await this._getZipBackup();
|
||||
return new File([blob], 'ffz-settings.zip', {type: 'application/zip'});
|
||||
return new File([blob], `ffz-settings (${timestamp}).zip`, {type: 'application/zip'});
|
||||
}
|
||||
|
||||
const settings = await this.getSettingsDump();
|
||||
return new File([JSON.stringify(settings)], 'ffz-settings.json', {type: 'application/json;charset=utf-8'});
|
||||
return new File([JSON.stringify(settings)], `ffz-settings (${timestamp}).json`, {type: 'application/json;charset=utf-8'});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import {get} from 'utilities/object';
|
||||
import {ColorAdjuster} from 'utilities/color';
|
||||
import { useFont } from 'utilities/fonts';
|
||||
|
||||
import Module from 'utilities/module';
|
||||
|
||||
|
@ -88,6 +89,14 @@ export default class Chat extends Module {
|
|||
lh = Math.round((20/12) * size);
|
||||
|
||||
let font = this.chat.context.get('chat.font-family') || 'inherit';
|
||||
const [processed, unloader] = useFont(font);
|
||||
font = processed;
|
||||
|
||||
if ( this._font_unloader )
|
||||
this._font_unloader();
|
||||
|
||||
this._font_unloader = unloader;
|
||||
|
||||
if ( font.indexOf(' ') !== -1 && font.indexOf(',') === -1 && font.indexOf('"') === -1 && font.indexOf("'") === -1 )
|
||||
font = `"${font}"`;
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ import Module from 'utilities/module';
|
|||
|
||||
import {createElement, on, off} from 'utilities/dom';
|
||||
import {isValidShortcut, debounce, has} from 'utilities/object';
|
||||
import { IS_FIREFOX } from 'src/utilities/constants';
|
||||
import { IS_FIREFOX } from 'utilities/constants';
|
||||
import { getFontsList, useFont } from 'utilities/fonts';
|
||||
|
||||
const STYLE_VALIDATOR = createElement('span');
|
||||
|
||||
|
@ -417,7 +418,8 @@ export default class PlayerBase extends Module {
|
|||
path: 'Player > Closed Captioning >> Font',
|
||||
title: 'Font Family',
|
||||
description: 'Override the font used for displaying Closed Captions.',
|
||||
component: 'setting-text-box'
|
||||
component: 'setting-combo-box',
|
||||
data: () => getFontsList()
|
||||
},
|
||||
changed: () => this.updateCaptionsCSS()
|
||||
});
|
||||
|
@ -1031,20 +1033,33 @@ export default class PlayerBase extends Module {
|
|||
|
||||
updateCaptionsCSS() {
|
||||
// Font
|
||||
const font_out = [];
|
||||
|
||||
const font_size = this.settings.get('player.captions.font-size');
|
||||
let font_family = this.settings.get('player.captions.font-family');
|
||||
|
||||
if ( font_family && font_family.length ) {
|
||||
const [processed, unloader] = useFont(font_family);
|
||||
font_family = processed;
|
||||
|
||||
if ( this._font_unloader )
|
||||
this._font_unloader();
|
||||
|
||||
this._font_unloader = unloader;
|
||||
|
||||
if ( font_family.indexOf(' ') !== -1 && font_family.indexOf(',') === -1 && font_family.indexOf('"') === -1 && font_family.indexOf("'") === -1 )
|
||||
font_family = `"${font_family}"`;
|
||||
|
||||
STYLE_VALIDATOR.style.fontSize = '';
|
||||
STYLE_VALIDATOR.style.fontFamily = '';
|
||||
|
||||
STYLE_VALIDATOR.style.fontSize = font_size;
|
||||
STYLE_VALIDATOR.style.fontFamily = font_family;
|
||||
|
||||
const font_out = [];
|
||||
if ( STYLE_VALIDATOR.style.fontFamily )
|
||||
font_out.push(`font-family: ${STYLE_VALIDATOR.style.fontFamily} !important;`);
|
||||
}
|
||||
|
||||
STYLE_VALIDATOR.style.fontSize = '';
|
||||
STYLE_VALIDATOR.style.fontSize = font_size;
|
||||
|
||||
if ( STYLE_VALIDATOR.style.fontSize )
|
||||
font_out.push(`font-size: ${STYLE_VALIDATOR.style.fontSize} !important;`);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import {Color, ColorAdjuster} from 'utilities/color';
|
|||
import {get, has, make_enum, shallow_object_equals, set_equals, deep_equals} from 'utilities/object';
|
||||
import {WEBKIT_CSS as WEBKIT} from 'utilities/constants';
|
||||
import {FFZEvent} from 'utilities/events';
|
||||
import {useFont} from 'utilities/fonts';
|
||||
|
||||
import Module from 'utilities/module';
|
||||
|
||||
|
@ -717,6 +718,14 @@ export default class ChatHook extends Module {
|
|||
lh = Math.round((20/12) * size);
|
||||
|
||||
let font = this.chat.context.get('chat.font-family') || 'inherit';
|
||||
const [processed, unloader] = useFont(font);
|
||||
font = processed;
|
||||
|
||||
if ( this._font_unloader )
|
||||
this._font_unloader();
|
||||
|
||||
this._font_unloader = unloader;
|
||||
|
||||
if ( font.indexOf(' ') !== -1 && font.indexOf(',') === -1 && font.indexOf('"') === -1 && font.indexOf("'") === -1 )
|
||||
font = `"${font}"`;
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ export default class RichContent extends Module {
|
|||
|
||||
return (<div
|
||||
class="ffz--corner-flag ffz--corner-flag__warn ffz-tooltip ffz-tooltip--no-mouse"
|
||||
data-title={t.i18n.t('tooltip.link-unsafe', "Caution: This URL is on Google's Safe Browsing List for: {reasons}", {reasons})}
|
||||
data-title={t.i18n.t('tooltip.link-unsafe', 'Caution: This URL is has been flagged as potentially harmful by: {reasons}', {reasons})}
|
||||
>
|
||||
<figure class="ffz-i-attention" />
|
||||
</div>);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import Module from 'utilities/module';
|
||||
import {ManagedStyle} from 'utilities/dom';
|
||||
import {has} from 'utilities/object';
|
||||
import { getFontsList, useFont } from 'utilities/fonts';
|
||||
|
||||
const STYLE_VALIDATOR = document.createElement('span');
|
||||
|
||||
|
@ -378,8 +379,9 @@ export default class CSSTweaks extends Module {
|
|||
ui: {
|
||||
path: 'Appearance > Theme >> Fonts',
|
||||
title: 'Font Family',
|
||||
description: 'Override the font used for the entire Twitch website. The old default font was: `"Helvetica Neue",Helvetica,Arial,sans-serif`',
|
||||
component: 'setting-text-box'
|
||||
description: 'Override the font used for the entire Twitch website. The old default font was: `"Helvetica Neue",Helvetica,Arial,sans-serif`\n\nAny font available via [Google Fonts](https://fonts.google.com/) can be loaded by prefixing the font name with `google:`.',
|
||||
component: 'setting-combo-box',
|
||||
data: () => getFontsList()
|
||||
},
|
||||
changed: () => this.updateFont()
|
||||
});
|
||||
|
@ -481,6 +483,14 @@ export default class CSSTweaks extends Module {
|
|||
updateFont() {
|
||||
let font = this.settings.get('layout.theme.global-font');
|
||||
if ( font && font.length ) {
|
||||
const [processed, unloader] = useFont(font);
|
||||
font = processed;
|
||||
|
||||
if ( this._font_unloader )
|
||||
this._font_unloader();
|
||||
|
||||
this._font_unloader = unloader;
|
||||
|
||||
if ( font.indexOf(' ') !== -1 && font.indexOf(',') === -1 && font.indexOf('"') === -1 && font.indexOf("'") === -1 )
|
||||
font = `"${font}"`;
|
||||
|
||||
|
|
210
src/utilities/fonts.js
Normal file
210
src/utilities/fonts.js
Normal file
|
@ -0,0 +1,210 @@
|
|||
import { createElement } from "./dom";
|
||||
|
||||
const KNOWN_FONTS = [
|
||||
'Roobert', // Twitch Default
|
||||
'Arial',
|
||||
'Arial Black',
|
||||
'Verdana',
|
||||
'Helvetica',
|
||||
'Tahoma',
|
||||
'Trebuchet MS',
|
||||
'Impact',
|
||||
'Didot',
|
||||
'American Typewriter',
|
||||
'Lucida Console',
|
||||
'Monaco',
|
||||
'Bradley Hand',
|
||||
'Times New Roman',
|
||||
'Georgia',
|
||||
'Garamond',
|
||||
'Courier New',
|
||||
'Brush Script MT',
|
||||
'Comic Sans MS',
|
||||
];
|
||||
|
||||
export const VALID_FONTS = KNOWN_FONTS.filter(font => document.fonts.check(`16px ${font}`)).sort();
|
||||
|
||||
|
||||
/* Google Font Handling */
|
||||
|
||||
const GOOGLE_FONTS = [
|
||||
'Roboto',
|
||||
'Open Sans',
|
||||
'Noto Sans JP',
|
||||
'Lato',
|
||||
'Montserrat',
|
||||
'Roboto Condensed',
|
||||
'Source Sans Pro',
|
||||
'Oswald',
|
||||
'Poppins',
|
||||
'Noto Sans',
|
||||
'Roboto Mono',
|
||||
'Raleway',
|
||||
'Ubuntu',
|
||||
'Merriweather',
|
||||
'Nunito',
|
||||
'PT Sans',
|
||||
'Roboto Slab',
|
||||
'Playfair Display',
|
||||
'Lora',
|
||||
'Rubik',
|
||||
'Mukta',
|
||||
'Noto Sans KR',
|
||||
'Work Sans',
|
||||
'Nunito Sans',
|
||||
'Nanum Gothic',
|
||||
'Inter',
|
||||
'Quicksand',
|
||||
'PT Serif',
|
||||
'Hind Siliguri',
|
||||
'Titilium Web',
|
||||
'Fira Sans',
|
||||
'Noto Serif',
|
||||
'Noto Sans TC',
|
||||
'Karla'
|
||||
];
|
||||
|
||||
const LOADED_GOOGLE = new Map();
|
||||
const LOADED_GOOGLE_LINKS = new Map();
|
||||
|
||||
function loadGoogleFont(font) {
|
||||
if ( LOADED_GOOGLE_LINKS.has(font) )
|
||||
return;
|
||||
|
||||
const name = encodeURIComponent(font);
|
||||
|
||||
const link = createElement('link', {
|
||||
id: `ffz-font-${name}`,
|
||||
rel: 'stylesheet',
|
||||
href: `https://fonts.googleapis.com/css2?family=${name}`
|
||||
});
|
||||
|
||||
LOADED_GOOGLE_LINKS.set(font, link);
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
|
||||
function unloadGoogleFont(font) {
|
||||
const link = LOADED_GOOGLE_LINKS.get(font);
|
||||
if ( ! link )
|
||||
return;
|
||||
|
||||
LOADED_GOOGLE_LINKS.delete(font);
|
||||
link.remove();
|
||||
}
|
||||
|
||||
|
||||
/* OpenDyslexic Font */
|
||||
|
||||
const OD_FONTS = [
|
||||
'OpenDyslexic',
|
||||
'OpenDyslexicAlta',
|
||||
'OpenDyslexicMono'
|
||||
];
|
||||
|
||||
import OD_URL from 'styles/opendyslexic.scss';
|
||||
|
||||
let od_count = 0;
|
||||
let od_link = null;
|
||||
|
||||
function loadOpenDyslexic() {
|
||||
if ( od_link )
|
||||
return;
|
||||
|
||||
od_link = createElement('link', {
|
||||
id: `ffz-font-opendyslexic`,
|
||||
rel: 'stylesheet',
|
||||
type: 'text/css',
|
||||
href: OD_URL
|
||||
});
|
||||
|
||||
document.head.appendChild(od_link);
|
||||
}
|
||||
|
||||
|
||||
function unloadOpenDyslexic() {
|
||||
if ( ! od_link )
|
||||
return;
|
||||
|
||||
od_link.remove();
|
||||
od_link = null;
|
||||
}
|
||||
|
||||
|
||||
/* Using and Listing Fonts */
|
||||
|
||||
export function getFontsList() {
|
||||
const out = [
|
||||
{value: '', i18n_key: 'setting.font.default', title: 'Default'},
|
||||
{separator: true, i18n_key: 'setting.font.builtin', title: 'Built-in Fonts'},
|
||||
];
|
||||
|
||||
for(const font of VALID_FONTS)
|
||||
out.push({value: font, title: font});
|
||||
|
||||
out.push({
|
||||
separator: true, i18n_key: 'setting.font.dyslexic', title: 'Dyslexia Fonts'
|
||||
});
|
||||
|
||||
for(const font of OD_FONTS)
|
||||
out.push({value: font, title: font});
|
||||
|
||||
out.push({
|
||||
separator: true, i18n_key: 'setting.font.google', title: 'Google Fonts'
|
||||
});
|
||||
|
||||
for(const font of GOOGLE_FONTS)
|
||||
out.push({value: `google:${font}`, title: font});
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
export function useFont(font) {
|
||||
if ( ! font )
|
||||
return [font, null];
|
||||
|
||||
if ( OD_FONTS.includes(font) ) {
|
||||
od_count++;
|
||||
if ( od_count === 1 )
|
||||
loadOpenDyslexic();
|
||||
|
||||
let unloaded = false;
|
||||
const unloader = () => {
|
||||
if ( ! unloaded ) {
|
||||
unloaded = true;
|
||||
od_count--;
|
||||
if ( ! od_count )
|
||||
unloadOpenDyslexic();
|
||||
}
|
||||
}
|
||||
|
||||
return [font, unloader];
|
||||
}
|
||||
|
||||
if ( font.startsWith('google:') ) {
|
||||
const name = font.slice(7),
|
||||
count = (LOADED_GOOGLE.get(name) ?? 0) + 1;
|
||||
|
||||
LOADED_GOOGLE.set(name, count);
|
||||
if ( count === 1 )
|
||||
loadGoogleFont(name);
|
||||
|
||||
let unloaded = false;
|
||||
const unloader = () => {
|
||||
if ( ! unloaded ) {
|
||||
unloaded = true;
|
||||
const count = (LOADED_GOOGLE.get(name) ?? 0) - 1;
|
||||
if ( count > 0 ) {
|
||||
LOADED_GOOGLE.set(name, count);
|
||||
} else {
|
||||
LOADED_GOOGLE.delete(name);
|
||||
unloadGoogleFont(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [name, unloader];
|
||||
}
|
||||
|
||||
return [font, null];
|
||||
}
|
60
styles/opendyslexic.scss
Normal file
60
styles/opendyslexic.scss
Normal file
|
@ -0,0 +1,60 @@
|
|||
@font-face {
|
||||
font-family: 'opendyslexic';
|
||||
src: url('~res/font/OpenDyslexic-Regular.otf');
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexic';
|
||||
src: url('~res/font/OpenDyslexic-Italic.otf');
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexic';
|
||||
src: url('~res/font/OpenDyslexic-Bold.otf');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexic';
|
||||
src: url('~res/font/OpenDyslexic-BoldItalic.otf');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexicmono';
|
||||
src: url('~res/font/OpenDyslexicMono-Regular.otf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexicalta';
|
||||
src: url('~res/font/OpenDyslexicAlta-Regular.otf');
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexicalta';
|
||||
src: url('~res/font/OpenDyslexicAlta-Italic.otf');
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexicalta';
|
||||
src: url('~res/font/OpenDyslexicAlta-Bold.otf');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'opendyslexicalta';
|
||||
src: url('~res/font/OpenDyslexicAlta-BoldItalic.otf');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
|
@ -119,7 +119,7 @@ module.exports = {
|
|||
loader: 'graphql-tag/loader'
|
||||
},
|
||||
{
|
||||
test: /\.(?:eot|ttf|woff|woff2)$/,
|
||||
test: /\.(?:otf|eot|ttf|woff|woff2)$/,
|
||||
use: [{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue