expo-font 11.5.0 → 11.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/android/build.gradle +11 -8
- package/android/src/main/java/expo/modules/font/FontLoaderModule.kt +22 -49
- package/build/ExpoFontLoader.d.ts +1 -1
- package/build/ExpoFontLoader.d.ts.map +1 -1
- package/build/ExpoFontLoader.js +2 -2
- package/build/ExpoFontLoader.js.map +1 -1
- package/build/ExpoFontLoader.web.d.ts +4 -0
- package/build/ExpoFontLoader.web.d.ts.map +1 -1
- package/build/ExpoFontLoader.web.js +69 -10
- package/build/ExpoFontLoader.web.js.map +1 -1
- package/build/Font.d.ts.map +1 -1
- package/build/Font.js +24 -13
- package/build/Font.js.map +1 -1
- package/build/FontHooks.d.ts +1 -1
- package/build/FontHooks.d.ts.map +1 -1
- package/build/FontHooks.js +27 -11
- package/build/FontHooks.js.map +1 -1
- package/build/FontLoader.web.d.ts.map +1 -1
- package/build/FontLoader.web.js +4 -2
- package/build/FontLoader.web.js.map +1 -1
- package/build/memory.d.ts +7 -0
- package/build/memory.d.ts.map +1 -0
- package/build/memory.js +3 -0
- package/build/memory.js.map +1 -0
- package/build/server.d.ts +13 -0
- package/build/server.d.ts.map +1 -0
- package/build/server.js +26 -0
- package/build/server.js.map +1 -0
- package/expo-module.config.json +7 -0
- package/package.json +2 -2
- package/src/ExpoFontLoader.ts +2 -2
- package/src/ExpoFontLoader.web.ts +88 -10
- package/src/Font.ts +35 -18
- package/src/FontHooks.ts +33 -13
- package/src/FontLoader.web.ts +5 -5
- package/src/memory.ts +2 -0
- package/src/server.ts +34 -0
- package/tsconfig.json +1 -1
- package/android/src/main/java/expo/modules/font/FontLoaderPackage.kt +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,23 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 11.6.0 — 2023-09-04
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Added support for React Native 0.73. ([#24018](https://github.com/expo/expo/pull/24018) by [@kudo](https://github.com/kudo))
|
|
18
|
+
- Add static font extraction support with `expo-router`. ([#24027](https://github.com/expo/expo/pull/24027) by [@EvanBacon](https://github.com/EvanBacon))
|
|
19
|
+
|
|
20
|
+
### 💡 Others
|
|
21
|
+
|
|
22
|
+
- Migrated `FontLoaderModule` to use Expo Modules API. ([#24015](https://github.com/expo/expo/pull/24015) by [@lukmccall](https://github.com/lukmccall))
|
|
23
|
+
|
|
24
|
+
## 11.5.1 — 2023-08-02
|
|
25
|
+
|
|
26
|
+
### 💡 Others
|
|
27
|
+
|
|
28
|
+
- Change unloaded font error to a warning. ([#23788](https://github.com/expo/expo/pull/23788) by [@EvanBacon](https://github.com/EvanBacon))
|
|
29
|
+
|
|
13
30
|
## 11.5.0 — 2023-07-28
|
|
14
31
|
|
|
15
32
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '11.
|
|
6
|
+
version = '11.6.0'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -53,13 +53,16 @@ afterEvaluate {
|
|
|
53
53
|
android {
|
|
54
54
|
compileSdkVersion safeExtGet("compileSdkVersion", 33)
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
57
|
+
if (agpVersion.tokenize('.')[0].toInteger() < 8) {
|
|
58
|
+
compileOptions {
|
|
59
|
+
sourceCompatibility JavaVersion.VERSION_11
|
|
60
|
+
targetCompatibility JavaVersion.VERSION_11
|
|
61
|
+
}
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
kotlinOptions {
|
|
64
|
+
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
|
65
|
+
}
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
namespace "expo.modules.font"
|
|
@@ -67,7 +70,7 @@ android {
|
|
|
67
70
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
68
71
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
69
72
|
versionCode 29
|
|
70
|
-
versionName "11.
|
|
73
|
+
versionName "11.6.0"
|
|
71
74
|
}
|
|
72
75
|
lintOptions {
|
|
73
76
|
abortOnError false
|
|
@@ -2,48 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
package expo.modules.font
|
|
4
4
|
|
|
5
|
-
import android.content.Context
|
|
6
5
|
import android.graphics.Typeface
|
|
7
6
|
import android.net.Uri
|
|
8
|
-
|
|
9
|
-
import expo.modules.core.ExportedModule
|
|
10
|
-
import expo.modules.core.ModuleRegistry
|
|
11
|
-
import expo.modules.core.ModuleRegistryDelegate
|
|
12
|
-
import expo.modules.core.interfaces.ExpoMethod
|
|
13
|
-
import expo.modules.core.Promise
|
|
14
|
-
|
|
15
7
|
import expo.modules.interfaces.font.FontManagerInterface
|
|
16
|
-
import expo.modules.
|
|
17
|
-
|
|
8
|
+
import expo.modules.kotlin.exception.CodedException
|
|
9
|
+
import expo.modules.kotlin.exception.Exceptions
|
|
10
|
+
import expo.modules.kotlin.modules.Module
|
|
11
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
18
12
|
import java.io.File
|
|
19
|
-
import java.lang.Exception
|
|
20
13
|
|
|
21
14
|
private const val ASSET_SCHEME = "asset://"
|
|
22
|
-
private const val EXPORTED_NAME = "ExpoFontLoader"
|
|
23
15
|
|
|
24
|
-
class
|
|
25
|
-
|
|
16
|
+
private class FontManagerInterfaceNotFoundException :
|
|
17
|
+
CodedException("FontManagerInterface not found")
|
|
26
18
|
|
|
27
|
-
|
|
19
|
+
private class FileNotFoundException(uri: String) :
|
|
20
|
+
CodedException("File '$uri' doesn't exist")
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
open class FontLoaderModule : Module() {
|
|
23
|
+
@Suppress("MemberVisibilityCanBePrivate")
|
|
24
|
+
open val prefix = ""
|
|
32
25
|
|
|
33
|
-
override fun
|
|
34
|
-
|
|
35
|
-
}
|
|
26
|
+
override fun definition() = ModuleDefinition {
|
|
27
|
+
Name("ExpoFontLoader")
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
// TODO: remove Expo references
|
|
41
|
-
// https://github.com/expo/expo/pull/4652#discussion_r296630843
|
|
42
|
-
val prefix = if (isScoped) {
|
|
43
|
-
"ExpoFont-"
|
|
44
|
-
} else {
|
|
45
|
-
""
|
|
46
|
-
}
|
|
29
|
+
AsyncFunction("loadAsync") { fontFamilyName: String, localUri: String ->
|
|
30
|
+
val context = appContext.reactContext ?: throw Exceptions.ReactContextLost()
|
|
47
31
|
|
|
48
32
|
// TODO(nikki): make sure path is in experience's scope
|
|
49
33
|
val typeface: Typeface = if (localUri.startsWith(ASSET_SCHEME)) {
|
|
@@ -52,27 +36,16 @@ class FontLoaderModule(context: Context) : ExportedModule(context) {
|
|
|
52
36
|
localUri.substring(ASSET_SCHEME.length + 1)
|
|
53
37
|
)
|
|
54
38
|
} else {
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
val file = Uri.parse(localUri).path?.let { File(it) }
|
|
40
|
+
?: throw FileNotFoundException(localUri)
|
|
57
41
|
|
|
58
|
-
|
|
59
|
-
if (fontManager == null) {
|
|
60
|
-
promise.reject("E_NO_FONT_MANAGER", "There is no FontManager in module registry. Are you sure all the dependencies of expo-font are installed and linked?")
|
|
61
|
-
return
|
|
42
|
+
Typeface.createFromFile(file)
|
|
62
43
|
}
|
|
63
44
|
|
|
64
|
-
fontManager
|
|
65
|
-
|
|
66
|
-
} catch (e: Exception) {
|
|
67
|
-
promise.reject("E_UNEXPECTED", "Font.loadAsync unexpected exception: " + e.message, e)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
45
|
+
val fontManager = appContext.legacyModule<FontManagerInterface>()
|
|
46
|
+
?: throw FontManagerInterfaceNotFoundException()
|
|
70
47
|
|
|
71
|
-
|
|
72
|
-
private val isScoped: Boolean
|
|
73
|
-
get() {
|
|
74
|
-
val constantsModule: ConstantsInterface? by moduleRegistry()
|
|
75
|
-
// If there's no constants module, or app ownership isn't "expo", we're not in Expo Client.
|
|
76
|
-
return constantsModule != null && "expo" == constantsModule!!.appOwnership
|
|
48
|
+
fontManager.setTypeface(prefix + fontFamilyName, Typeface.NORMAL, typeface)
|
|
77
49
|
}
|
|
50
|
+
}
|
|
78
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoFontLoader.d.ts","sourceRoot":"","sources":["../src/ExpoFontLoader.ts"],"names":[],"mappings":";AACA,
|
|
1
|
+
{"version":3,"file":"ExpoFontLoader.d.ts","sourceRoot":"","sources":["../src/ExpoFontLoader.ts"],"names":[],"mappings":";AACA,wBAAqD"}
|
package/build/ExpoFontLoader.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default
|
|
1
|
+
import { requireNativeModule } from 'expo-modules-core';
|
|
2
|
+
export default requireNativeModule('ExpoFontLoader');
|
|
3
3
|
//# sourceMappingURL=ExpoFontLoader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoFontLoader.js","sourceRoot":"","sources":["../src/ExpoFontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ExpoFontLoader.js","sourceRoot":"","sources":["../src/ExpoFontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,eAAe,mBAAmB,CAAC,gBAAgB,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\nexport default requireNativeModule('ExpoFontLoader');\n"]}
|
|
@@ -4,7 +4,11 @@ declare const _default: {
|
|
|
4
4
|
readonly name: string;
|
|
5
5
|
unloadAllAsync(): Promise<void>;
|
|
6
6
|
unloadAsync(fontFamilyName: string, options?: UnloadFontOptions): Promise<void>;
|
|
7
|
+
getServerResources(): string[];
|
|
8
|
+
resetServerContext(): void;
|
|
9
|
+
isLoaded(fontFamilyName: string, resource?: UnloadFontOptions): boolean;
|
|
7
10
|
loadAsync(fontFamilyName: string, resource: FontResource): Promise<void>;
|
|
8
11
|
};
|
|
9
12
|
export default _default;
|
|
13
|
+
export declare function _createWebFontTemplate(fontFamily: string, resource: FontResource): string;
|
|
10
14
|
//# sourceMappingURL=ExpoFontLoader.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoFontLoader.web.d.ts","sourceRoot":"","sources":["../src/ExpoFontLoader.web.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAe,YAAY,EAAE,MAAM,cAAc,CAAC;;;
|
|
1
|
+
{"version":3,"file":"ExpoFontLoader.web.d.ts","sourceRoot":"","sources":["../src/ExpoFontLoader.web.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAe,YAAY,EAAE,MAAM,cAAc,CAAC;;;sBAqF/B,QAAQ,IAAI,CAAC;gCASH,MAAM,YAAY,iBAAiB,GAAG,QAAQ,IAAI,CAAC;0BAS/D,MAAM,EAAE;;6BAmBL,MAAM,aAAY,iBAAiB,GAAQ,OAAO;8BAUjD,MAAM,YAAY,YAAY,GAAG,QAAQ,IAAI,CAAC;;AApD1E,wBAqFE;AAeF,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CAIzF"}
|
|
@@ -31,6 +31,31 @@ function getFontFaceRulesMatchingResource(fontFamilyName, options) {
|
|
|
31
31
|
(options && options.display ? options.display === rule.style.fontDisplay : true));
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
+
const serverContext = new Set();
|
|
35
|
+
function getHeadElements() {
|
|
36
|
+
const entries = [...serverContext.entries()];
|
|
37
|
+
if (!entries.length) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const css = entries.map(([{ css }]) => css).join('\n');
|
|
41
|
+
const links = entries.map(([{ resourceId }]) => resourceId);
|
|
42
|
+
// TODO: Maybe return nothing if no fonts were loaded.
|
|
43
|
+
return [
|
|
44
|
+
{
|
|
45
|
+
$$type: 'style',
|
|
46
|
+
children: css,
|
|
47
|
+
id: ID,
|
|
48
|
+
type: 'text/css',
|
|
49
|
+
},
|
|
50
|
+
...links.map((resourceId) => ({
|
|
51
|
+
$$type: 'link',
|
|
52
|
+
rel: 'preload',
|
|
53
|
+
href: resourceId,
|
|
54
|
+
as: 'font',
|
|
55
|
+
crossorigin: '',
|
|
56
|
+
})),
|
|
57
|
+
];
|
|
58
|
+
}
|
|
34
59
|
export default {
|
|
35
60
|
get name() {
|
|
36
61
|
return 'ExpoFontLoader';
|
|
@@ -52,18 +77,53 @@ export default {
|
|
|
52
77
|
sheet.deleteRule(item.index);
|
|
53
78
|
}
|
|
54
79
|
},
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
80
|
+
getServerResources() {
|
|
81
|
+
const elements = getHeadElements();
|
|
82
|
+
return elements.map((element) => {
|
|
83
|
+
switch (element.$$type) {
|
|
84
|
+
case 'style':
|
|
85
|
+
return `<style id="${element.id}" type="${element.type}">${element.children}</style>`;
|
|
86
|
+
case 'link':
|
|
87
|
+
return `<link rel="${element.rel}" href="${element.href}" as="${element.as}" crossorigin="${element.crossorigin}" />`;
|
|
88
|
+
default:
|
|
89
|
+
return '';
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
resetServerContext() {
|
|
94
|
+
serverContext.clear();
|
|
95
|
+
},
|
|
96
|
+
isLoaded(fontFamilyName, resource = {}) {
|
|
97
|
+
if (typeof window === 'undefined') {
|
|
98
|
+
return !![...serverContext.values()].find((asset) => {
|
|
99
|
+
return asset.name === fontFamilyName;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return getFontFaceRulesMatchingResource(fontFamilyName, resource)?.length > 0;
|
|
103
|
+
},
|
|
104
|
+
// NOTE(EvanBacon): No async keyword! This cannot return a promise in Node environments.
|
|
105
|
+
loadAsync(fontFamilyName, resource) {
|
|
106
|
+
if (typeof window === 'undefined') {
|
|
107
|
+
serverContext.add({
|
|
108
|
+
name: fontFamilyName,
|
|
109
|
+
css: _createWebFontTemplate(fontFamilyName, resource),
|
|
110
|
+
// @ts-expect-error: typeof string
|
|
111
|
+
resourceId: resource.uri,
|
|
112
|
+
});
|
|
113
|
+
return Promise.resolve();
|
|
58
114
|
}
|
|
59
115
|
const canInjectStyle = document.head && typeof document.head.appendChild === 'function';
|
|
60
116
|
if (!canInjectStyle) {
|
|
61
117
|
throw new CodedError('ERR_WEB_ENVIRONMENT', `The browser's \`document.head\` element doesn't support injecting fonts.`);
|
|
62
118
|
}
|
|
63
|
-
const style =
|
|
119
|
+
const style = getStyleElement();
|
|
64
120
|
document.head.appendChild(style);
|
|
121
|
+
const res = getFontFaceRulesMatchingResource(fontFamilyName, resource);
|
|
122
|
+
if (!res.length) {
|
|
123
|
+
_createWebStyle(fontFamilyName, resource);
|
|
124
|
+
}
|
|
65
125
|
if (!isFontLoadingListenerSupported()) {
|
|
66
|
-
return;
|
|
126
|
+
return Promise.resolve();
|
|
67
127
|
}
|
|
68
128
|
return new FontObserver(fontFamilyName, { display: resource.display }).load(null, 6000);
|
|
69
129
|
},
|
|
@@ -79,12 +139,11 @@ function getStyleElement() {
|
|
|
79
139
|
styleElement.type = 'text/css';
|
|
80
140
|
return styleElement;
|
|
81
141
|
}
|
|
142
|
+
export function _createWebFontTemplate(fontFamily, resource) {
|
|
143
|
+
return `@font-face{font-family:${fontFamily};src:url(${resource.uri});font-display:${resource.display || FontDisplay.AUTO}}`;
|
|
144
|
+
}
|
|
82
145
|
function _createWebStyle(fontFamily, resource) {
|
|
83
|
-
const fontStyle =
|
|
84
|
-
font-family: ${fontFamily};
|
|
85
|
-
src: url(${resource.uri});
|
|
86
|
-
font-display: ${resource.display || FontDisplay.AUTO};
|
|
87
|
-
}`;
|
|
146
|
+
const fontStyle = _createWebFontTemplate(fontFamily, resource);
|
|
88
147
|
const styleElement = getStyleElement();
|
|
89
148
|
// @ts-ignore: TypeScript does not define HTMLStyleElement::styleSheet. This is just for IE and
|
|
90
149
|
// possibly can be removed if it's unnecessary on IE 11.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoFontLoader.web.js","sourceRoot":"","sources":["../src/ExpoFontLoader.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, Platform } from 'expo-modules-core';\nimport FontObserver from 'fontfaceobserver';\n\nimport { UnloadFontOptions } from './Font';\nimport { FontDisplay, FontResource } from './Font.types';\n\nfunction getFontFaceStyleSheet(): CSSStyleSheet | null {\n if (!Platform.isDOMAvailable) {\n return null;\n }\n const styleSheet = getStyleElement();\n return styleSheet.sheet ? (styleSheet.sheet as CSSStyleSheet) : null;\n}\n\ntype RuleItem = { rule: CSSFontFaceRule; index: number };\n\nfunction getFontFaceRules(): RuleItem[] {\n const sheet = getFontFaceStyleSheet();\n if (sheet) {\n // @ts-ignore: rule iterator\n const rules = [...sheet.cssRules];\n\n const items: RuleItem[] = [];\n\n for (let i = 0; i < rules.length; i++) {\n const rule = rules[i];\n if (rule instanceof CSSFontFaceRule) {\n items.push({ rule, index: i });\n }\n }\n return items;\n }\n return [];\n}\n\nfunction getFontFaceRulesMatchingResource(\n fontFamilyName: string,\n options?: UnloadFontOptions\n): RuleItem[] {\n const rules = getFontFaceRules();\n return rules.filter(({ rule }) => {\n return (\n rule.style.fontFamily === fontFamilyName &&\n (options && options.display ? options.display === (rule.style as any).fontDisplay : true)\n );\n });\n}\n\nexport default {\n get name(): string {\n return 'ExpoFontLoader';\n },\n\n async unloadAllAsync(): Promise<void> {\n if (!Platform.isDOMAvailable) return;\n\n const element = document.getElementById(ID);\n if (element && element instanceof HTMLStyleElement) {\n document.removeChild(element);\n }\n },\n\n async unloadAsync(fontFamilyName: string, options?: UnloadFontOptions): Promise<void> {\n const sheet = getFontFaceStyleSheet();\n if (!sheet) return;\n const items = getFontFaceRulesMatchingResource(fontFamilyName, options);\n for (const item of items) {\n sheet.deleteRule(item.index);\n }\n },\n\n async loadAsync(fontFamilyName: string, resource: FontResource): Promise<void> {\n if (!Platform.isDOMAvailable) {\n return;\n }\n\n const canInjectStyle = document.head && typeof document.head.appendChild === 'function';\n if (!canInjectStyle) {\n throw new CodedError(\n 'ERR_WEB_ENVIRONMENT',\n `The browser's \\`document.head\\` element doesn't support injecting fonts.`\n );\n }\n\n const style = _createWebStyle(fontFamilyName, resource);\n document.head!.appendChild(style);\n\n if (!isFontLoadingListenerSupported()) {\n return;\n }\n\n return new FontObserver(fontFamilyName, { display: resource.display }).load(null, 6000);\n },\n};\n\nconst ID = 'expo-generated-fonts';\n\nfunction getStyleElement(): HTMLStyleElement {\n const element = document.getElementById(ID);\n if (element && element instanceof HTMLStyleElement) {\n return element;\n }\n const styleElement = document.createElement('style');\n styleElement.id = ID;\n styleElement.type = 'text/css';\n return styleElement;\n}\n\nfunction _createWebStyle(fontFamily: string, resource: FontResource): HTMLStyleElement {\n const fontStyle = `@font-face {\n font-family: ${fontFamily};\n src: url(${resource.uri});\n font-display: ${resource.display || FontDisplay.AUTO};\n }`;\n\n const styleElement = getStyleElement();\n // @ts-ignore: TypeScript does not define HTMLStyleElement::styleSheet. This is just for IE and\n // possibly can be removed if it's unnecessary on IE 11.\n if (styleElement.styleSheet) {\n const styleElementIE = styleElement as any;\n styleElementIE.styleSheet.cssText = styleElementIE.styleSheet.cssText\n ? styleElementIE.styleSheet.cssText + fontStyle\n : fontStyle;\n } else {\n const textNode = document.createTextNode(fontStyle);\n styleElement.appendChild(textNode);\n }\n return styleElement;\n}\n\nfunction isFontLoadingListenerSupported(): boolean {\n const { userAgent } = window.navigator;\n // WebKit is broken https://github.com/bramstein/fontfaceobserver/issues/95\n const isIOS = !!userAgent.match(/iPad|iPhone/i);\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n // Edge is broken https://github.com/bramstein/fontfaceobserver/issues/109#issuecomment-333356795\n const isEdge = userAgent.includes('Edge');\n // Internet Explorer\n const isIE = userAgent.includes('Trident');\n // Firefox\n const isFirefox = userAgent.includes('Firefox');\n return !isSafari && !isIOS && !isEdge && !isIE && !isFirefox;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ExpoFontLoader.web.js","sourceRoot":"","sources":["../src/ExpoFontLoader.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, Platform } from 'expo-modules-core';\nimport FontObserver from 'fontfaceobserver';\n\nimport { UnloadFontOptions } from './Font';\nimport { FontDisplay, FontResource } from './Font.types';\n\nfunction getFontFaceStyleSheet(): CSSStyleSheet | null {\n if (!Platform.isDOMAvailable) {\n return null;\n }\n const styleSheet = getStyleElement();\n return styleSheet.sheet ? (styleSheet.sheet as CSSStyleSheet) : null;\n}\n\ntype RuleItem = { rule: CSSFontFaceRule; index: number };\n\nfunction getFontFaceRules(): RuleItem[] {\n const sheet = getFontFaceStyleSheet();\n if (sheet) {\n // @ts-ignore: rule iterator\n const rules = [...sheet.cssRules];\n\n const items: RuleItem[] = [];\n\n for (let i = 0; i < rules.length; i++) {\n const rule = rules[i];\n if (rule instanceof CSSFontFaceRule) {\n items.push({ rule, index: i });\n }\n }\n return items;\n }\n return [];\n}\n\nfunction getFontFaceRulesMatchingResource(\n fontFamilyName: string,\n options?: UnloadFontOptions\n): RuleItem[] {\n const rules = getFontFaceRules();\n return rules.filter(({ rule }) => {\n return (\n rule.style.fontFamily === fontFamilyName &&\n (options && options.display ? options.display === (rule.style as any).fontDisplay : true)\n );\n });\n}\n\nconst serverContext: Set<{ name: string; css: string; resourceId: string }> = new Set();\n\nfunction getHeadElements(): {\n $$type: string;\n rel?: string;\n href?: string;\n as?: string;\n crossorigin?: string;\n children?: string;\n id?: string;\n type?: string;\n}[] {\n const entries = [...serverContext.entries()];\n if (!entries.length) {\n return [];\n }\n const css = entries.map(([{ css }]) => css).join('\\n');\n const links = entries.map(([{ resourceId }]) => resourceId);\n // TODO: Maybe return nothing if no fonts were loaded.\n return [\n {\n $$type: 'style',\n children: css,\n id: ID,\n type: 'text/css',\n },\n ...links.map((resourceId) => ({\n $$type: 'link',\n rel: 'preload',\n href: resourceId,\n as: 'font',\n crossorigin: '',\n })),\n ];\n}\n\nexport default {\n get name(): string {\n return 'ExpoFontLoader';\n },\n\n async unloadAllAsync(): Promise<void> {\n if (!Platform.isDOMAvailable) return;\n\n const element = document.getElementById(ID);\n if (element && element instanceof HTMLStyleElement) {\n document.removeChild(element);\n }\n },\n\n async unloadAsync(fontFamilyName: string, options?: UnloadFontOptions): Promise<void> {\n const sheet = getFontFaceStyleSheet();\n if (!sheet) return;\n const items = getFontFaceRulesMatchingResource(fontFamilyName, options);\n for (const item of items) {\n sheet.deleteRule(item.index);\n }\n },\n\n getServerResources(): string[] {\n const elements = getHeadElements();\n\n return elements.map((element) => {\n switch (element.$$type) {\n case 'style':\n return `<style id=\"${element.id}\" type=\"${element.type}\">${element.children}</style>`;\n case 'link':\n return `<link rel=\"${element.rel}\" href=\"${element.href}\" as=\"${element.as}\" crossorigin=\"${element.crossorigin}\" />`;\n default:\n return '';\n }\n });\n },\n\n resetServerContext() {\n serverContext.clear();\n },\n\n isLoaded(fontFamilyName: string, resource: UnloadFontOptions = {}): boolean {\n if (typeof window === 'undefined') {\n return !![...serverContext.values()].find((asset) => {\n return asset.name === fontFamilyName;\n });\n }\n return getFontFaceRulesMatchingResource(fontFamilyName, resource)?.length > 0;\n },\n\n // NOTE(EvanBacon): No async keyword! This cannot return a promise in Node environments.\n loadAsync(fontFamilyName: string, resource: FontResource): Promise<void> {\n if (typeof window === 'undefined') {\n serverContext.add({\n name: fontFamilyName,\n css: _createWebFontTemplate(fontFamilyName, resource),\n // @ts-expect-error: typeof string\n resourceId: resource.uri!,\n });\n return Promise.resolve();\n }\n\n const canInjectStyle = document.head && typeof document.head.appendChild === 'function';\n if (!canInjectStyle) {\n throw new CodedError(\n 'ERR_WEB_ENVIRONMENT',\n `The browser's \\`document.head\\` element doesn't support injecting fonts.`\n );\n }\n\n const style = getStyleElement();\n document.head!.appendChild(style);\n\n const res = getFontFaceRulesMatchingResource(fontFamilyName, resource);\n if (!res.length) {\n _createWebStyle(fontFamilyName, resource);\n }\n\n if (!isFontLoadingListenerSupported()) {\n return Promise.resolve();\n }\n\n return new FontObserver(fontFamilyName, { display: resource.display }).load(null, 6000);\n },\n};\n\nconst ID = 'expo-generated-fonts';\n\nfunction getStyleElement(): HTMLStyleElement {\n const element = document.getElementById(ID);\n if (element && element instanceof HTMLStyleElement) {\n return element;\n }\n const styleElement = document.createElement('style');\n styleElement.id = ID;\n styleElement.type = 'text/css';\n return styleElement;\n}\n\nexport function _createWebFontTemplate(fontFamily: string, resource: FontResource): string {\n return `@font-face{font-family:${fontFamily};src:url(${resource.uri});font-display:${\n resource.display || FontDisplay.AUTO\n }}`;\n}\n\nfunction _createWebStyle(fontFamily: string, resource: FontResource): HTMLStyleElement {\n const fontStyle = _createWebFontTemplate(fontFamily, resource);\n\n const styleElement = getStyleElement();\n // @ts-ignore: TypeScript does not define HTMLStyleElement::styleSheet. This is just for IE and\n // possibly can be removed if it's unnecessary on IE 11.\n if (styleElement.styleSheet) {\n const styleElementIE = styleElement as any;\n styleElementIE.styleSheet.cssText = styleElementIE.styleSheet.cssText\n ? styleElementIE.styleSheet.cssText + fontStyle\n : fontStyle;\n } else {\n const textNode = document.createTextNode(fontStyle);\n styleElement.appendChild(textNode);\n }\n return styleElement;\n}\n\nfunction isFontLoadingListenerSupported(): boolean {\n const { userAgent } = window.navigator;\n // WebKit is broken https://github.com/bramstein/fontfaceobserver/issues/95\n const isIOS = !!userAgent.match(/iPad|iPhone/i);\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n // Edge is broken https://github.com/bramstein/fontfaceobserver/issues/109#issuecomment-333356795\n const isEdge = userAgent.includes('Edge');\n // Internet Explorer\n const isIE = userAgent.includes('Trident');\n // Firefox\n const isFirefox = userAgent.includes('Firefox');\n return !isSafari && !isIOS && !isEdge && !isIE && !isFirefox;\n}\n"]}
|
package/build/Font.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Font.d.ts","sourceRoot":"","sources":["../src/Font.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Font.d.ts","sourceRoot":"","sources":["../src/Font.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAYxF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAoB1E;AAGD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAKpD;AAGD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAErD;AAGD;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EACxD,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CAkCf;AAwCD;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBpD;AAGD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC/D,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAkBf;AA0BD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
|
package/build/Font.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { CodedError, UnavailabilityError } from 'expo-modules-core';
|
|
1
|
+
import { CodedError, Platform, UnavailabilityError } from 'expo-modules-core';
|
|
2
2
|
import ExpoFontLoader from './ExpoFontLoader';
|
|
3
3
|
import { FontDisplay } from './Font.types';
|
|
4
4
|
import { getAssetForSource, loadSingleFontAsync, fontFamilyNeedsScoping, getNativeFontName, } from './FontLoader';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { loaded, loadPromises } from './memory';
|
|
6
|
+
import { registerStaticFont } from './server';
|
|
7
7
|
// @needsAudit
|
|
8
8
|
// note(brentvatne): at some point we may want to warn if this is called outside of a managed app.
|
|
9
9
|
/**
|
|
@@ -21,15 +21,12 @@ export function processFontFamily(fontFamily) {
|
|
|
21
21
|
if (!isLoaded(fontFamily)) {
|
|
22
22
|
if (__DEV__) {
|
|
23
23
|
if (isLoading(fontFamily)) {
|
|
24
|
-
console.
|
|
24
|
+
console.warn(`You started loading the font "${fontFamily}", but used it before it finished loading. You need to wait for Font.loadAsync to complete before using the font.`);
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
|
-
console.
|
|
28
|
-
- If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.\n
|
|
29
|
-
- If this is a custom font, be sure to load it with Font.loadAsync.`);
|
|
27
|
+
console.warn(`fontFamily "${fontFamily}" is not a system font and has not been loaded through expo-font.`);
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
|
-
return 'System';
|
|
33
30
|
}
|
|
34
31
|
return `ExpoFont-${getNativeFontName(fontFamily)}`;
|
|
35
32
|
}
|
|
@@ -41,6 +38,9 @@ export function processFontFamily(fontFamily) {
|
|
|
41
38
|
* @return Returns `true` if the font has fully loaded.
|
|
42
39
|
*/
|
|
43
40
|
export function isLoaded(fontFamily) {
|
|
41
|
+
if (Platform.OS === 'web') {
|
|
42
|
+
return fontFamily in loaded || !!ExpoFontLoader.isLoaded(fontFamily);
|
|
43
|
+
}
|
|
44
44
|
return fontFamily in loaded;
|
|
45
45
|
}
|
|
46
46
|
// @needsAudit
|
|
@@ -66,17 +66,28 @@ export function isLoading(fontFamily) {
|
|
|
66
66
|
* @return Returns a promise that fulfils when the font has loaded. Often you may want to wrap the
|
|
67
67
|
* method in a `try/catch/finally` to ensure the app continues if the font fails to load.
|
|
68
68
|
*/
|
|
69
|
-
export
|
|
69
|
+
export function loadAsync(fontFamilyOrFontMap, source) {
|
|
70
|
+
// NOTE(EvanBacon): Static render pass on web must be synchronous to collect all fonts.
|
|
71
|
+
// Because of this, `loadAsync` doesn't use the `async` keyword and deviates from the
|
|
72
|
+
// standard Expo SDK style guide.
|
|
73
|
+
const isServer = Platform.OS === 'web' && typeof window === 'undefined';
|
|
70
74
|
if (typeof fontFamilyOrFontMap === 'object') {
|
|
71
75
|
if (source) {
|
|
72
|
-
|
|
76
|
+
return Promise.reject(new CodedError(`ERR_FONT_API`, `No fontFamily can be used for the provided source: ${source}. The second argument of \`loadAsync()\` can only be used with a \`string\` value as the first argument.`));
|
|
73
77
|
}
|
|
74
78
|
const fontMap = fontFamilyOrFontMap;
|
|
75
79
|
const names = Object.keys(fontMap);
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
if (isServer) {
|
|
81
|
+
names.map((name) => registerStaticFont(name, fontMap[name]));
|
|
82
|
+
return Promise.resolve();
|
|
83
|
+
}
|
|
84
|
+
return Promise.all(names.map((name) => loadFontInNamespaceAsync(name, fontMap[name]))).then(() => { });
|
|
85
|
+
}
|
|
86
|
+
if (isServer) {
|
|
87
|
+
registerStaticFont(fontFamilyOrFontMap, source);
|
|
88
|
+
return Promise.resolve();
|
|
78
89
|
}
|
|
79
|
-
return
|
|
90
|
+
return loadFontInNamespaceAsync(fontFamilyOrFontMap, source);
|
|
80
91
|
}
|
|
81
92
|
async function loadFontInNamespaceAsync(fontFamily, source) {
|
|
82
93
|
if (!source) {
|
package/build/Font.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Font.js","sourceRoot":"","sources":["../src/Font.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, UnavailabilityError } from 'expo-modules-core';\n\nimport ExpoFontLoader from './ExpoFontLoader';\nimport { FontDisplay, FontSource, FontResource, UnloadFontOptions } from './Font.types';\nimport {\n getAssetForSource,\n loadSingleFontAsync,\n fontFamilyNeedsScoping,\n getNativeFontName,\n} from './FontLoader';\n\nconst loaded: { [name: string]: boolean } = {};\nconst loadPromises: { [name: string]: Promise<void> } = {};\n\n// @needsAudit\n// note(brentvatne): at some point we may want to warn if this is called outside of a managed app.\n/**\n * Used to transform font family names to the scoped name. This does not need to\n * be called in standalone or bare apps but it will return unscoped font family\n * names if it is called in those contexts.\n *\n * @param fontFamily Name of font to process.\n * @returns Returns a name processed for use with the [current workflow](https://docs.expo.dev/archive/managed-vs-bare/).\n */\nexport function processFontFamily(fontFamily: string | null): string | null {\n if (!fontFamily || !fontFamilyNeedsScoping(fontFamily)) {\n return fontFamily;\n }\n\n if (!isLoaded(fontFamily)) {\n if (__DEV__) {\n if (isLoading(fontFamily)) {\n console.error(\n `You started loading the font \"${fontFamily}\", but used it before it finished loading. You need to wait for Font.loadAsync to complete before using the font.`\n );\n } else {\n console.error(\n `fontFamily \"${fontFamily}\" is not a system font and has not been loaded through Font.loadAsync.\\n\n- If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.\\n\n- If this is a custom font, be sure to load it with Font.loadAsync.`\n );\n }\n }\n\n return 'System';\n }\n\n return `ExpoFont-${getNativeFontName(fontFamily)}`;\n}\n\n// @needsAudit\n/**\n * Synchronously detect if the font for `fontFamily` has finished loading.\n *\n * @param fontFamily The name used to load the `FontResource`.\n * @return Returns `true` if the font has fully loaded.\n */\nexport function isLoaded(fontFamily: string): boolean {\n return fontFamily in loaded;\n}\n\n// @needsAudit\n/**\n * Synchronously detect if the font for `fontFamily` is still being loaded.\n *\n * @param fontFamily The name used to load the `FontResource`.\n * @returns Returns `true` if the font is still loading.\n */\nexport function isLoading(fontFamily: string): boolean {\n return fontFamily in loadPromises;\n}\n\n// @needsAudit\n/**\n * Highly efficient method for loading fonts from static or remote resources which can then be used\n * with the platform's native text elements. In the browser this generates a `@font-face` block in\n * a shared style sheet for fonts. No CSS is needed to use this method.\n *\n * @param fontFamilyOrFontMap string or map of values that can be used as the [`fontFamily`](https://reactnative.dev/docs/text#style)\n * style prop with React Native Text elements.\n * @param source the font asset that should be loaded into the `fontFamily` namespace.\n *\n * @return Returns a promise that fulfils when the font has loaded. Often you may want to wrap the\n * method in a `try/catch/finally` to ensure the app continues if the font fails to load.\n */\nexport async function loadAsync(\n fontFamilyOrFontMap: string | Record<string, FontSource>,\n source?: FontSource\n): Promise<void> {\n if (typeof fontFamilyOrFontMap === 'object') {\n if (source) {\n throw new CodedError(\n `ERR_FONT_API`,\n `No fontFamily can be used for the provided source: ${source}. The second argument of \\`loadAsync()\\` can only be used with a \\`string\\` value as the first argument.`\n );\n }\n const fontMap = fontFamilyOrFontMap;\n const names = Object.keys(fontMap);\n await Promise.all(names.map((name) => loadFontInNamespaceAsync(name, fontMap[name])));\n return;\n }\n\n return await loadFontInNamespaceAsync(fontFamilyOrFontMap, source);\n}\n\nasync function loadFontInNamespaceAsync(\n fontFamily: string,\n source?: FontSource | null\n): Promise<void> {\n if (!source) {\n throw new CodedError(\n `ERR_FONT_SOURCE`,\n `Cannot load null or undefined font source: { \"${fontFamily}\": ${source} }. Expected asset of type \\`FontSource\\` for fontFamily of name: \"${fontFamily}\"`\n );\n }\n\n if (loaded[fontFamily]) {\n return;\n }\n\n if (loadPromises.hasOwnProperty(fontFamily)) {\n return loadPromises[fontFamily];\n }\n\n // Important: we want all callers that concurrently try to load the same font to await the same\n // promise. If we're here, we haven't created the promise yet. To ensure we create only one\n // promise in the program, we need to create the promise synchronously without yielding the event\n // loop from this point.\n\n const asset = getAssetForSource(source);\n loadPromises[fontFamily] = (async () => {\n try {\n await loadSingleFontAsync(fontFamily, asset);\n loaded[fontFamily] = true;\n } finally {\n delete loadPromises[fontFamily];\n }\n })();\n\n await loadPromises[fontFamily];\n}\n\n// @needsAudit\n/**\n * Unloads all the custom fonts. This is used for testing.\n */\nexport async function unloadAllAsync(): Promise<void> {\n if (!ExpoFontLoader.unloadAllAsync) {\n throw new UnavailabilityError('expo-font', 'unloadAllAsync');\n }\n\n if (Object.keys(loadPromises).length) {\n throw new CodedError(\n `ERR_UNLOAD`,\n `Cannot unload fonts while they're still loading: ${Object.keys(loadPromises).join(', ')}`\n );\n }\n\n for (const fontFamily of Object.keys(loaded)) {\n delete loaded[fontFamily];\n }\n\n await ExpoFontLoader.unloadAllAsync();\n}\n\n// @needsAudit\n/**\n * Unload custom fonts matching the `fontFamily`s and display values provided.\n * Because fonts are automatically unloaded on every platform this is mostly used for testing.\n *\n * @param fontFamilyOrFontMap The name or names of the custom fonts that will be unloaded.\n * @param options When `fontFamilyOrFontMap` is a string, this should be the font source used to load\n * the custom font originally.\n */\nexport async function unloadAsync(\n fontFamilyOrFontMap: string | Record<string, UnloadFontOptions>,\n options?: UnloadFontOptions\n): Promise<void> {\n if (!ExpoFontLoader.unloadAsync) {\n throw new UnavailabilityError('expo-font', 'unloadAsync');\n }\n if (typeof fontFamilyOrFontMap === 'object') {\n if (options) {\n throw new CodedError(\n `ERR_FONT_API`,\n `No fontFamily can be used for the provided options: ${options}. The second argument of \\`unloadAsync()\\` can only be used with a \\`string\\` value as the first argument.`\n );\n }\n const fontMap = fontFamilyOrFontMap;\n const names = Object.keys(fontMap);\n await Promise.all(names.map((name) => unloadFontInNamespaceAsync(name, fontMap[name])));\n return;\n }\n\n return await unloadFontInNamespaceAsync(fontFamilyOrFontMap, options);\n}\n\nasync function unloadFontInNamespaceAsync(\n fontFamily: string,\n options?: UnloadFontOptions | null\n): Promise<void> {\n if (!loaded[fontFamily]) {\n return;\n } else {\n delete loaded[fontFamily];\n }\n\n // Important: we want all callers that concurrently try to load the same font to await the same\n // promise. If we're here, we haven't created the promise yet. To ensure we create only one\n // promise in the program, we need to create the promise synchronously without yielding the event\n // loop from this point.\n\n const nativeFontName = getNativeFontName(fontFamily);\n\n if (!nativeFontName) {\n throw new CodedError(`ERR_FONT_FAMILY`, `Cannot unload an empty name`);\n }\n\n await ExpoFontLoader.unloadAsync(nativeFontName, options);\n}\n\nexport { FontDisplay, FontSource, FontResource, UnloadFontOptions };\n"]}
|
|
1
|
+
{"version":3,"file":"Font.js","sourceRoot":"","sources":["../src/Font.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, Platform, UnavailabilityError } from 'expo-modules-core';\n\nimport ExpoFontLoader from './ExpoFontLoader';\nimport { FontDisplay, FontSource, FontResource, UnloadFontOptions } from './Font.types';\nimport {\n getAssetForSource,\n loadSingleFontAsync,\n fontFamilyNeedsScoping,\n getNativeFontName,\n} from './FontLoader';\nimport { loaded, loadPromises } from './memory';\nimport { registerStaticFont } from './server';\n\n// @needsAudit\n// note(brentvatne): at some point we may want to warn if this is called outside of a managed app.\n/**\n * Used to transform font family names to the scoped name. This does not need to\n * be called in standalone or bare apps but it will return unscoped font family\n * names if it is called in those contexts.\n *\n * @param fontFamily Name of font to process.\n * @returns Returns a name processed for use with the [current workflow](https://docs.expo.dev/archive/managed-vs-bare/).\n */\nexport function processFontFamily(fontFamily: string | null): string | null {\n if (!fontFamily || !fontFamilyNeedsScoping(fontFamily)) {\n return fontFamily;\n }\n\n if (!isLoaded(fontFamily)) {\n if (__DEV__) {\n if (isLoading(fontFamily)) {\n console.warn(\n `You started loading the font \"${fontFamily}\", but used it before it finished loading. You need to wait for Font.loadAsync to complete before using the font.`\n );\n } else {\n console.warn(\n `fontFamily \"${fontFamily}\" is not a system font and has not been loaded through expo-font.`\n );\n }\n }\n }\n\n return `ExpoFont-${getNativeFontName(fontFamily)}`;\n}\n\n// @needsAudit\n/**\n * Synchronously detect if the font for `fontFamily` has finished loading.\n *\n * @param fontFamily The name used to load the `FontResource`.\n * @return Returns `true` if the font has fully loaded.\n */\nexport function isLoaded(fontFamily: string): boolean {\n if (Platform.OS === 'web') {\n return fontFamily in loaded || !!ExpoFontLoader.isLoaded(fontFamily);\n }\n return fontFamily in loaded;\n}\n\n// @needsAudit\n/**\n * Synchronously detect if the font for `fontFamily` is still being loaded.\n *\n * @param fontFamily The name used to load the `FontResource`.\n * @returns Returns `true` if the font is still loading.\n */\nexport function isLoading(fontFamily: string): boolean {\n return fontFamily in loadPromises;\n}\n\n// @needsAudit\n/**\n * Highly efficient method for loading fonts from static or remote resources which can then be used\n * with the platform's native text elements. In the browser this generates a `@font-face` block in\n * a shared style sheet for fonts. No CSS is needed to use this method.\n *\n * @param fontFamilyOrFontMap string or map of values that can be used as the [`fontFamily`](https://reactnative.dev/docs/text#style)\n * style prop with React Native Text elements.\n * @param source the font asset that should be loaded into the `fontFamily` namespace.\n *\n * @return Returns a promise that fulfils when the font has loaded. Often you may want to wrap the\n * method in a `try/catch/finally` to ensure the app continues if the font fails to load.\n */\nexport function loadAsync(\n fontFamilyOrFontMap: string | Record<string, FontSource>,\n source?: FontSource\n): Promise<void> {\n // NOTE(EvanBacon): Static render pass on web must be synchronous to collect all fonts.\n // Because of this, `loadAsync` doesn't use the `async` keyword and deviates from the\n // standard Expo SDK style guide.\n const isServer = Platform.OS === 'web' && typeof window === 'undefined';\n\n if (typeof fontFamilyOrFontMap === 'object') {\n if (source) {\n return Promise.reject(\n new CodedError(\n `ERR_FONT_API`,\n `No fontFamily can be used for the provided source: ${source}. The second argument of \\`loadAsync()\\` can only be used with a \\`string\\` value as the first argument.`\n )\n );\n }\n const fontMap = fontFamilyOrFontMap;\n const names = Object.keys(fontMap);\n\n if (isServer) {\n names.map((name) => registerStaticFont(name, fontMap[name]));\n return Promise.resolve();\n }\n\n return Promise.all(names.map((name) => loadFontInNamespaceAsync(name, fontMap[name]))).then(\n () => {}\n );\n }\n\n if (isServer) {\n registerStaticFont(fontFamilyOrFontMap, source);\n return Promise.resolve();\n }\n\n return loadFontInNamespaceAsync(fontFamilyOrFontMap, source);\n}\n\nasync function loadFontInNamespaceAsync(\n fontFamily: string,\n source?: FontSource | null\n): Promise<void> {\n if (!source) {\n throw new CodedError(\n `ERR_FONT_SOURCE`,\n `Cannot load null or undefined font source: { \"${fontFamily}\": ${source} }. Expected asset of type \\`FontSource\\` for fontFamily of name: \"${fontFamily}\"`\n );\n }\n\n if (loaded[fontFamily]) {\n return;\n }\n\n if (loadPromises.hasOwnProperty(fontFamily)) {\n return loadPromises[fontFamily];\n }\n\n // Important: we want all callers that concurrently try to load the same font to await the same\n // promise. If we're here, we haven't created the promise yet. To ensure we create only one\n // promise in the program, we need to create the promise synchronously without yielding the event\n // loop from this point.\n\n const asset = getAssetForSource(source);\n loadPromises[fontFamily] = (async () => {\n try {\n await loadSingleFontAsync(fontFamily, asset);\n loaded[fontFamily] = true;\n } finally {\n delete loadPromises[fontFamily];\n }\n })();\n\n await loadPromises[fontFamily];\n}\n\n// @needsAudit\n/**\n * Unloads all the custom fonts. This is used for testing.\n */\nexport async function unloadAllAsync(): Promise<void> {\n if (!ExpoFontLoader.unloadAllAsync) {\n throw new UnavailabilityError('expo-font', 'unloadAllAsync');\n }\n\n if (Object.keys(loadPromises).length) {\n throw new CodedError(\n `ERR_UNLOAD`,\n `Cannot unload fonts while they're still loading: ${Object.keys(loadPromises).join(', ')}`\n );\n }\n\n for (const fontFamily of Object.keys(loaded)) {\n delete loaded[fontFamily];\n }\n\n await ExpoFontLoader.unloadAllAsync();\n}\n\n// @needsAudit\n/**\n * Unload custom fonts matching the `fontFamily`s and display values provided.\n * Because fonts are automatically unloaded on every platform this is mostly used for testing.\n *\n * @param fontFamilyOrFontMap The name or names of the custom fonts that will be unloaded.\n * @param options When `fontFamilyOrFontMap` is a string, this should be the font source used to load\n * the custom font originally.\n */\nexport async function unloadAsync(\n fontFamilyOrFontMap: string | Record<string, UnloadFontOptions>,\n options?: UnloadFontOptions\n): Promise<void> {\n if (!ExpoFontLoader.unloadAsync) {\n throw new UnavailabilityError('expo-font', 'unloadAsync');\n }\n if (typeof fontFamilyOrFontMap === 'object') {\n if (options) {\n throw new CodedError(\n `ERR_FONT_API`,\n `No fontFamily can be used for the provided options: ${options}. The second argument of \\`unloadAsync()\\` can only be used with a \\`string\\` value as the first argument.`\n );\n }\n const fontMap = fontFamilyOrFontMap;\n const names = Object.keys(fontMap);\n await Promise.all(names.map((name) => unloadFontInNamespaceAsync(name, fontMap[name])));\n return;\n }\n\n return await unloadFontInNamespaceAsync(fontFamilyOrFontMap, options);\n}\n\nasync function unloadFontInNamespaceAsync(\n fontFamily: string,\n options?: UnloadFontOptions | null\n): Promise<void> {\n if (!loaded[fontFamily]) {\n return;\n } else {\n delete loaded[fontFamily];\n }\n\n // Important: we want all callers that concurrently try to load the same font to await the same\n // promise. If we're here, we haven't created the promise yet. To ensure we create only one\n // promise in the program, we need to create the promise synchronously without yielding the event\n // loop from this point.\n\n const nativeFontName = getNativeFontName(fontFamily);\n\n if (!nativeFontName) {\n throw new CodedError(`ERR_FONT_FAMILY`, `Cannot unload an empty name`);\n }\n\n await ExpoFontLoader.unloadAsync(nativeFontName, options);\n}\n\nexport { FontDisplay, FontSource, FontResource, UnloadFontOptions };\n"]}
|
package/build/FontHooks.d.ts
CHANGED
|
@@ -16,5 +16,5 @@ import { FontSource } from './Font.types';
|
|
|
16
16
|
* loading.
|
|
17
17
|
* - __error__ (`Error | null`) - An error encountered when loading the fonts.
|
|
18
18
|
*/
|
|
19
|
-
export declare
|
|
19
|
+
export declare const useFonts: (map: string | Record<string, FontSource>) => [boolean, Error | null];
|
|
20
20
|
//# sourceMappingURL=FontHooks.d.ts.map
|
package/build/FontHooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontHooks.d.ts","sourceRoot":"","sources":["../src/FontHooks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"FontHooks.d.ts","sourceRoot":"","sources":["../src/FontHooks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAiC1C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI,CACzB,CAAC"}
|
package/build/FontHooks.js
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
import { loadAsync } from './Font';
|
|
2
|
+
import { loadAsync, isLoaded } from './Font';
|
|
3
|
+
function isMapLoaded(map) {
|
|
4
|
+
if (typeof map === 'string') {
|
|
5
|
+
return isLoaded(map);
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
return Object.keys(map).every((fontFamily) => isLoaded(fontFamily));
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function useRuntimeFonts(map) {
|
|
12
|
+
const [loaded, setLoaded] = useState(
|
|
13
|
+
// For web rehydration, we need to check if the fonts are already loaded during the static render.
|
|
14
|
+
// Native will also benefit from this optimization.
|
|
15
|
+
isMapLoaded(map));
|
|
16
|
+
const [error, setError] = useState(null);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
loadAsync(map)
|
|
19
|
+
.then(() => setLoaded(true))
|
|
20
|
+
.catch(setError);
|
|
21
|
+
}, []);
|
|
22
|
+
return [loaded, error];
|
|
23
|
+
}
|
|
24
|
+
function useStaticFonts(map) {
|
|
25
|
+
loadAsync(map);
|
|
26
|
+
return [true, null];
|
|
27
|
+
}
|
|
3
28
|
// @needsAudit
|
|
4
29
|
/**
|
|
5
30
|
* ```ts
|
|
@@ -18,14 +43,5 @@ import { loadAsync } from './Font';
|
|
|
18
43
|
* loading.
|
|
19
44
|
* - __error__ (`Error | null`) - An error encountered when loading the fonts.
|
|
20
45
|
*/
|
|
21
|
-
export
|
|
22
|
-
const [loaded, setLoaded] = useState(false);
|
|
23
|
-
const [error, setError] = useState(null);
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
loadAsync(map)
|
|
26
|
-
.then(() => setLoaded(true))
|
|
27
|
-
.catch(setError);
|
|
28
|
-
}, []);
|
|
29
|
-
return [loaded, error];
|
|
30
|
-
}
|
|
46
|
+
export const useFonts = typeof window === 'undefined' ? useStaticFonts : useRuntimeFonts;
|
|
31
47
|
//# sourceMappingURL=FontHooks.js.map
|
package/build/FontHooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontHooks.js","sourceRoot":"","sources":["../src/FontHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"FontHooks.js","sourceRoot":"","sources":["../src/FontHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAG7C,SAAS,WAAW,CAAC,GAAwC;IAC3D,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QAC3B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;KACtB;SAAM;QACL,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;KACrE;AACH,CAAC;AAED,SAAS,eAAe,CAAC,GAAwC;IAC/D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ;IAClC,kGAAkG;IAClG,mDAAmD;IACnD,WAAW,CAAC,GAAG,CAAC,CACjB,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,GAAG,CAAC;aACX,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;aAC3B,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,cAAc,CAAC,GAAwC;IAC9D,SAAS,CAAC,GAAG,CAAC,CAAC;IACf,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,cAAc;AACd;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,QAAQ,GACnB,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC","sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { loadAsync, isLoaded } from './Font';\nimport { FontSource } from './Font.types';\n\nfunction isMapLoaded(map: string | Record<string, FontSource>) {\n if (typeof map === 'string') {\n return isLoaded(map);\n } else {\n return Object.keys(map).every((fontFamily) => isLoaded(fontFamily));\n }\n}\n\nfunction useRuntimeFonts(map: string | Record<string, FontSource>): [boolean, Error | null] {\n const [loaded, setLoaded] = useState(\n // For web rehydration, we need to check if the fonts are already loaded during the static render.\n // Native will also benefit from this optimization.\n isMapLoaded(map)\n );\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n loadAsync(map)\n .then(() => setLoaded(true))\n .catch(setError);\n }, []);\n\n return [loaded, error];\n}\n\nfunction useStaticFonts(map: string | Record<string, FontSource>): [boolean, Error | null] {\n loadAsync(map);\n return [true, null];\n}\n\n// @needsAudit\n/**\n * ```ts\n * const [loaded, error] = useFonts({ ... });\n * ```\n * Load a map of fonts with [`loadAsync`](#loadasync). This returns a `boolean` if the fonts are\n * loaded and ready to use. It also returns an error if something went wrong, to use in development.\n *\n * > Note, the fonts are not \"reloaded\" when you dynamically change the font map.\n *\n * @param map A map of `fontFamily`s to [`FontSource`](#fontsource)s. After loading the font you can\n * use the key in the `fontFamily` style prop of a `Text` element.\n *\n * @return\n * - __loaded__ (`boolean`) - A boolean to detect if the font for `fontFamily` has finished\n * loading.\n * - __error__ (`Error | null`) - An error encountered when loading the fonts.\n */\nexport const useFonts: (map: string | Record<string, FontSource>) => [boolean, Error | null] =\n typeof window === 'undefined' ? useStaticFonts : useRuntimeFonts;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontLoader.web.d.ts","sourceRoot":"","sources":["../src/FontLoader.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAe,MAAM,cAAc,CAAC;AAiBrE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,YAAY,CAY1E;
|
|
1
|
+
{"version":3,"file":"FontLoader.web.d.ts","sourceRoot":"","sources":["../src/FontLoader.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAe,MAAM,cAAc,CAAC;AAiBrE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,YAAY,CAY1E;AAYD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAY5F;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
package/build/FontLoader.web.js
CHANGED
|
@@ -37,16 +37,18 @@ function throwInvalidSourceError(source) {
|
|
|
37
37
|
type = JSON.stringify(source, null, 2);
|
|
38
38
|
throw new CodedError(`ERR_FONT_SOURCE`, `Expected font asset of type \`string | FontResource | Asset\` instead got: ${type}`);
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
// NOTE(EvanBacon): No async keyword!
|
|
41
|
+
export function loadSingleFontAsync(name, input) {
|
|
41
42
|
if (typeof input !== 'object' || typeof input.uri !== 'string' || input.downloadAsync) {
|
|
42
43
|
throwInvalidSourceError(input);
|
|
43
44
|
}
|
|
44
45
|
try {
|
|
45
|
-
|
|
46
|
+
return ExpoFontLoader.loadAsync(name, input);
|
|
46
47
|
}
|
|
47
48
|
catch {
|
|
48
49
|
// No-op.
|
|
49
50
|
}
|
|
51
|
+
return Promise.resolve();
|
|
50
52
|
}
|
|
51
53
|
export function getNativeFontName(name) {
|
|
52
54
|
return name;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontLoader.web.js","sourceRoot":"","sources":["../src/FontLoader.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAA4B,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,SAAS,iBAAiB,CAAC,KAAU;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QAC7B,OAAO,KAAK,IAAI,IAAI,CAAC;KACtB;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACpC,OAAO,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC;KAC7D;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACpC,OAAO,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;KACnD;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAU;IACvC,OAAO,KAAK,CAAC,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE9C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QACnC,uBAAuB,CAAC,GAAG,CAAC,CAAC;KAC9B;IAED,OAAO;QACL,GAAG,EAAE,GAAI;QACT,OAAO;KACR,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAW;IAC1C,IAAI,IAAI,GAAW,OAAO,MAAM,CAAC;IACjC,IAAI,IAAI,KAAK,QAAQ;QAAE,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,8EAA8E,IAAI,EAAE,CACrF,CAAC;AACJ,CAAC;AAED,MAAM,
|
|
1
|
+
{"version":3,"file":"FontLoader.web.js","sourceRoot":"","sources":["../src/FontLoader.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAA4B,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,SAAS,iBAAiB,CAAC,KAAU;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QAC7B,OAAO,KAAK,IAAI,IAAI,CAAC;KACtB;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACpC,OAAO,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC;KAC7D;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACpC,OAAO,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;KACnD;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAU;IACvC,OAAO,KAAK,CAAC,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE9C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QACnC,uBAAuB,CAAC,GAAG,CAAC,CAAC;KAC9B;IAED,OAAO;QACL,GAAG,EAAE,GAAI;QACT,OAAO;KACR,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAW;IAC1C,IAAI,IAAI,GAAW,OAAO,MAAM,CAAC;IACjC,IAAI,IAAI,KAAK,QAAQ;QAAE,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,8EAA8E,IAAI,EAAE,CACrF,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,KAA2B;IAC3E,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAK,KAAa,CAAC,aAAa,EAAE;QAC9F,uBAAuB,CAAC,KAAK,CAAC,CAAC;KAChC;IAED,IAAI;QACF,OAAO,cAAc,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;KAC9C;IAAC,MAAM;QACN,SAAS;KACV;IAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { Asset } from 'expo-asset';\nimport { CodedError } from 'expo-modules-core';\n\nimport ExpoFontLoader from './ExpoFontLoader';\nimport { FontResource, FontSource, FontDisplay } from './Font.types';\n\nfunction uriFromFontSource(asset: any): string | null {\n if (typeof asset === 'string') {\n return asset || null;\n } else if (typeof asset === 'object') {\n return asset.uri || asset.localUri || asset.default || null;\n } else if (typeof asset === 'number') {\n return uriFromFontSource(Asset.fromModule(asset));\n }\n return null;\n}\n\nfunction displayFromFontSource(asset: any): FontDisplay | undefined {\n return asset.display || FontDisplay.AUTO;\n}\n\nexport function fontFamilyNeedsScoping(name: string): boolean {\n return false;\n}\n\nexport function getAssetForSource(source: FontSource): Asset | FontResource {\n const uri = uriFromFontSource(source);\n const display = displayFromFontSource(source);\n\n if (!uri || typeof uri !== 'string') {\n throwInvalidSourceError(uri);\n }\n\n return {\n uri: uri!,\n display,\n };\n}\n\nfunction throwInvalidSourceError(source: any): never {\n let type: string = typeof source;\n if (type === 'object') type = JSON.stringify(source, null, 2);\n throw new CodedError(\n `ERR_FONT_SOURCE`,\n `Expected font asset of type \\`string | FontResource | Asset\\` instead got: ${type}`\n );\n}\n\n// NOTE(EvanBacon): No async keyword!\nexport function loadSingleFontAsync(name: string, input: Asset | FontResource): Promise<void> {\n if (typeof input !== 'object' || typeof input.uri !== 'string' || (input as any).downloadAsync) {\n throwInvalidSourceError(input);\n }\n\n try {\n return ExpoFontLoader.loadAsync(name, input);\n } catch {\n // No-op.\n }\n\n return Promise.resolve();\n}\n\nexport function getNativeFontName(name: string): string {\n return name;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,EAAE;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CAAO,CAAC;AACtD,eAAO,MAAM,YAAY,EAAE;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAO,CAAC"}
|
package/build/memory.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAgC,EAAE,CAAC;AACtD,MAAM,CAAC,MAAM,YAAY,GAAsC,EAAE,CAAC","sourcesContent":["export const loaded: { [name: string]: boolean } = {};\nexport const loadPromises: { [name: string]: Promise<void> } = {};\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FontSource } from './Font.types';
|
|
2
|
+
/**
|
|
3
|
+
* @returns the server resources that should be statically extracted.
|
|
4
|
+
* @private
|
|
5
|
+
*/
|
|
6
|
+
export declare function getServerResources(): any;
|
|
7
|
+
/**
|
|
8
|
+
* @returns clear the server resources from the global scope.
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
export declare function resetServerContext(): any;
|
|
12
|
+
export declare function registerStaticFont(fontFamily: string, source?: FontSource | null): void;
|
|
13
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;;GAGG;AACH,wBAAgB,kBAAkB,QAEjC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,QAEjC;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,QAWhF"}
|
package/build/server.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CodedError } from 'expo-modules-core';
|
|
2
|
+
import ExpoFontLoader from './ExpoFontLoader';
|
|
3
|
+
import { getAssetForSource, loadSingleFontAsync } from './FontLoader';
|
|
4
|
+
/**
|
|
5
|
+
* @returns the server resources that should be statically extracted.
|
|
6
|
+
* @private
|
|
7
|
+
*/
|
|
8
|
+
export function getServerResources() {
|
|
9
|
+
return ExpoFontLoader.getServerResources();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* @returns clear the server resources from the global scope.
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
export function resetServerContext() {
|
|
16
|
+
return ExpoFontLoader.resetServerContext();
|
|
17
|
+
}
|
|
18
|
+
export function registerStaticFont(fontFamily, source) {
|
|
19
|
+
// MUST BE A SYNC FUNCTION!
|
|
20
|
+
if (!source) {
|
|
21
|
+
throw new CodedError(`ERR_FONT_SOURCE`, `Cannot load null or undefined font source: { "${fontFamily}": ${source} }. Expected asset of type \`FontSource\` for fontFamily of name: "${fontFamily}"`);
|
|
22
|
+
}
|
|
23
|
+
const asset = getAssetForSource(source);
|
|
24
|
+
loadSingleFontAsync(fontFamily, asset);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEtE;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,cAAc,CAAC,kBAAkB,EAAE,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,cAAc,CAAC,kBAAkB,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,MAA0B;IAC/E,2BAA2B;IAC3B,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,iDAAiD,UAAU,MAAM,MAAM,sEAAsE,UAAU,GAAG,CAC3J,CAAC;KACH;IACD,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAExC,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AACzC,CAAC","sourcesContent":["import { CodedError } from 'expo-modules-core';\n\nimport ExpoFontLoader from './ExpoFontLoader';\nimport { FontSource } from './Font.types';\nimport { getAssetForSource, loadSingleFontAsync } from './FontLoader';\n\n/**\n * @returns the server resources that should be statically extracted.\n * @private\n */\nexport function getServerResources() {\n return ExpoFontLoader.getServerResources();\n}\n\n/**\n * @returns clear the server resources from the global scope.\n * @private\n */\nexport function resetServerContext() {\n return ExpoFontLoader.resetServerContext();\n}\n\nexport function registerStaticFont(fontFamily: string, source?: FontSource | null) {\n // MUST BE A SYNC FUNCTION!\n if (!source) {\n throw new CodedError(\n `ERR_FONT_SOURCE`,\n `Cannot load null or undefined font source: { \"${fontFamily}\": ${source} }. Expected asset of type \\`FontSource\\` for fontFamily of name: \"${fontFamily}\"`\n );\n }\n const asset = getAssetForSource(source);\n\n loadSingleFontAsync(fontFamily, asset);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-font",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.6.0",
|
|
4
4
|
"description": "Load fonts at runtime and use them in React Native components.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"expo": "*"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "79607a7325f47aa17c36d266100d09a4ff2cc544"
|
|
46
46
|
}
|
package/src/ExpoFontLoader.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default
|
|
1
|
+
import { requireNativeModule } from 'expo-modules-core';
|
|
2
|
+
export default requireNativeModule('ExpoFontLoader');
|
|
@@ -46,6 +46,42 @@ function getFontFaceRulesMatchingResource(
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
const serverContext: Set<{ name: string; css: string; resourceId: string }> = new Set();
|
|
50
|
+
|
|
51
|
+
function getHeadElements(): {
|
|
52
|
+
$$type: string;
|
|
53
|
+
rel?: string;
|
|
54
|
+
href?: string;
|
|
55
|
+
as?: string;
|
|
56
|
+
crossorigin?: string;
|
|
57
|
+
children?: string;
|
|
58
|
+
id?: string;
|
|
59
|
+
type?: string;
|
|
60
|
+
}[] {
|
|
61
|
+
const entries = [...serverContext.entries()];
|
|
62
|
+
if (!entries.length) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
const css = entries.map(([{ css }]) => css).join('\n');
|
|
66
|
+
const links = entries.map(([{ resourceId }]) => resourceId);
|
|
67
|
+
// TODO: Maybe return nothing if no fonts were loaded.
|
|
68
|
+
return [
|
|
69
|
+
{
|
|
70
|
+
$$type: 'style',
|
|
71
|
+
children: css,
|
|
72
|
+
id: ID,
|
|
73
|
+
type: 'text/css',
|
|
74
|
+
},
|
|
75
|
+
...links.map((resourceId) => ({
|
|
76
|
+
$$type: 'link',
|
|
77
|
+
rel: 'preload',
|
|
78
|
+
href: resourceId,
|
|
79
|
+
as: 'font',
|
|
80
|
+
crossorigin: '',
|
|
81
|
+
})),
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
|
|
49
85
|
export default {
|
|
50
86
|
get name(): string {
|
|
51
87
|
return 'ExpoFontLoader';
|
|
@@ -69,9 +105,44 @@ export default {
|
|
|
69
105
|
}
|
|
70
106
|
},
|
|
71
107
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
108
|
+
getServerResources(): string[] {
|
|
109
|
+
const elements = getHeadElements();
|
|
110
|
+
|
|
111
|
+
return elements.map((element) => {
|
|
112
|
+
switch (element.$$type) {
|
|
113
|
+
case 'style':
|
|
114
|
+
return `<style id="${element.id}" type="${element.type}">${element.children}</style>`;
|
|
115
|
+
case 'link':
|
|
116
|
+
return `<link rel="${element.rel}" href="${element.href}" as="${element.as}" crossorigin="${element.crossorigin}" />`;
|
|
117
|
+
default:
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
resetServerContext() {
|
|
124
|
+
serverContext.clear();
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
isLoaded(fontFamilyName: string, resource: UnloadFontOptions = {}): boolean {
|
|
128
|
+
if (typeof window === 'undefined') {
|
|
129
|
+
return !![...serverContext.values()].find((asset) => {
|
|
130
|
+
return asset.name === fontFamilyName;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return getFontFaceRulesMatchingResource(fontFamilyName, resource)?.length > 0;
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
// NOTE(EvanBacon): No async keyword! This cannot return a promise in Node environments.
|
|
137
|
+
loadAsync(fontFamilyName: string, resource: FontResource): Promise<void> {
|
|
138
|
+
if (typeof window === 'undefined') {
|
|
139
|
+
serverContext.add({
|
|
140
|
+
name: fontFamilyName,
|
|
141
|
+
css: _createWebFontTemplate(fontFamilyName, resource),
|
|
142
|
+
// @ts-expect-error: typeof string
|
|
143
|
+
resourceId: resource.uri!,
|
|
144
|
+
});
|
|
145
|
+
return Promise.resolve();
|
|
75
146
|
}
|
|
76
147
|
|
|
77
148
|
const canInjectStyle = document.head && typeof document.head.appendChild === 'function';
|
|
@@ -82,11 +153,16 @@ export default {
|
|
|
82
153
|
);
|
|
83
154
|
}
|
|
84
155
|
|
|
85
|
-
const style =
|
|
156
|
+
const style = getStyleElement();
|
|
86
157
|
document.head!.appendChild(style);
|
|
87
158
|
|
|
159
|
+
const res = getFontFaceRulesMatchingResource(fontFamilyName, resource);
|
|
160
|
+
if (!res.length) {
|
|
161
|
+
_createWebStyle(fontFamilyName, resource);
|
|
162
|
+
}
|
|
163
|
+
|
|
88
164
|
if (!isFontLoadingListenerSupported()) {
|
|
89
|
-
return;
|
|
165
|
+
return Promise.resolve();
|
|
90
166
|
}
|
|
91
167
|
|
|
92
168
|
return new FontObserver(fontFamilyName, { display: resource.display }).load(null, 6000);
|
|
@@ -106,12 +182,14 @@ function getStyleElement(): HTMLStyleElement {
|
|
|
106
182
|
return styleElement;
|
|
107
183
|
}
|
|
108
184
|
|
|
185
|
+
export function _createWebFontTemplate(fontFamily: string, resource: FontResource): string {
|
|
186
|
+
return `@font-face{font-family:${fontFamily};src:url(${resource.uri});font-display:${
|
|
187
|
+
resource.display || FontDisplay.AUTO
|
|
188
|
+
}}`;
|
|
189
|
+
}
|
|
190
|
+
|
|
109
191
|
function _createWebStyle(fontFamily: string, resource: FontResource): HTMLStyleElement {
|
|
110
|
-
const fontStyle =
|
|
111
|
-
font-family: ${fontFamily};
|
|
112
|
-
src: url(${resource.uri});
|
|
113
|
-
font-display: ${resource.display || FontDisplay.AUTO};
|
|
114
|
-
}`;
|
|
192
|
+
const fontStyle = _createWebFontTemplate(fontFamily, resource);
|
|
115
193
|
|
|
116
194
|
const styleElement = getStyleElement();
|
|
117
195
|
// @ts-ignore: TypeScript does not define HTMLStyleElement::styleSheet. This is just for IE and
|
package/src/Font.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodedError, UnavailabilityError } from 'expo-modules-core';
|
|
1
|
+
import { CodedError, Platform, UnavailabilityError } from 'expo-modules-core';
|
|
2
2
|
|
|
3
3
|
import ExpoFontLoader from './ExpoFontLoader';
|
|
4
4
|
import { FontDisplay, FontSource, FontResource, UnloadFontOptions } from './Font.types';
|
|
@@ -8,9 +8,8 @@ import {
|
|
|
8
8
|
fontFamilyNeedsScoping,
|
|
9
9
|
getNativeFontName,
|
|
10
10
|
} from './FontLoader';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const loadPromises: { [name: string]: Promise<void> } = {};
|
|
11
|
+
import { loaded, loadPromises } from './memory';
|
|
12
|
+
import { registerStaticFont } from './server';
|
|
14
13
|
|
|
15
14
|
// @needsAudit
|
|
16
15
|
// note(brentvatne): at some point we may want to warn if this is called outside of a managed app.
|
|
@@ -30,19 +29,15 @@ export function processFontFamily(fontFamily: string | null): string | null {
|
|
|
30
29
|
if (!isLoaded(fontFamily)) {
|
|
31
30
|
if (__DEV__) {
|
|
32
31
|
if (isLoading(fontFamily)) {
|
|
33
|
-
console.
|
|
32
|
+
console.warn(
|
|
34
33
|
`You started loading the font "${fontFamily}", but used it before it finished loading. You need to wait for Font.loadAsync to complete before using the font.`
|
|
35
34
|
);
|
|
36
35
|
} else {
|
|
37
|
-
console.
|
|
38
|
-
`fontFamily "${fontFamily}" is not a system font and has not been loaded through
|
|
39
|
-
- If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.\n
|
|
40
|
-
- If this is a custom font, be sure to load it with Font.loadAsync.`
|
|
36
|
+
console.warn(
|
|
37
|
+
`fontFamily "${fontFamily}" is not a system font and has not been loaded through expo-font.`
|
|
41
38
|
);
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
|
-
|
|
45
|
-
return 'System';
|
|
46
41
|
}
|
|
47
42
|
|
|
48
43
|
return `ExpoFont-${getNativeFontName(fontFamily)}`;
|
|
@@ -56,6 +51,9 @@ export function processFontFamily(fontFamily: string | null): string | null {
|
|
|
56
51
|
* @return Returns `true` if the font has fully loaded.
|
|
57
52
|
*/
|
|
58
53
|
export function isLoaded(fontFamily: string): boolean {
|
|
54
|
+
if (Platform.OS === 'web') {
|
|
55
|
+
return fontFamily in loaded || !!ExpoFontLoader.isLoaded(fontFamily);
|
|
56
|
+
}
|
|
59
57
|
return fontFamily in loaded;
|
|
60
58
|
}
|
|
61
59
|
|
|
@@ -83,24 +81,43 @@ export function isLoading(fontFamily: string): boolean {
|
|
|
83
81
|
* @return Returns a promise that fulfils when the font has loaded. Often you may want to wrap the
|
|
84
82
|
* method in a `try/catch/finally` to ensure the app continues if the font fails to load.
|
|
85
83
|
*/
|
|
86
|
-
export
|
|
84
|
+
export function loadAsync(
|
|
87
85
|
fontFamilyOrFontMap: string | Record<string, FontSource>,
|
|
88
86
|
source?: FontSource
|
|
89
87
|
): Promise<void> {
|
|
88
|
+
// NOTE(EvanBacon): Static render pass on web must be synchronous to collect all fonts.
|
|
89
|
+
// Because of this, `loadAsync` doesn't use the `async` keyword and deviates from the
|
|
90
|
+
// standard Expo SDK style guide.
|
|
91
|
+
const isServer = Platform.OS === 'web' && typeof window === 'undefined';
|
|
92
|
+
|
|
90
93
|
if (typeof fontFamilyOrFontMap === 'object') {
|
|
91
94
|
if (source) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
return Promise.reject(
|
|
96
|
+
new CodedError(
|
|
97
|
+
`ERR_FONT_API`,
|
|
98
|
+
`No fontFamily can be used for the provided source: ${source}. The second argument of \`loadAsync()\` can only be used with a \`string\` value as the first argument.`
|
|
99
|
+
)
|
|
95
100
|
);
|
|
96
101
|
}
|
|
97
102
|
const fontMap = fontFamilyOrFontMap;
|
|
98
103
|
const names = Object.keys(fontMap);
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
|
|
105
|
+
if (isServer) {
|
|
106
|
+
names.map((name) => registerStaticFont(name, fontMap[name]));
|
|
107
|
+
return Promise.resolve();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return Promise.all(names.map((name) => loadFontInNamespaceAsync(name, fontMap[name]))).then(
|
|
111
|
+
() => {}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (isServer) {
|
|
116
|
+
registerStaticFont(fontFamilyOrFontMap, source);
|
|
117
|
+
return Promise.resolve();
|
|
101
118
|
}
|
|
102
119
|
|
|
103
|
-
return
|
|
120
|
+
return loadFontInNamespaceAsync(fontFamilyOrFontMap, source);
|
|
104
121
|
}
|
|
105
122
|
|
|
106
123
|
async function loadFontInNamespaceAsync(
|
package/src/FontHooks.ts
CHANGED
|
@@ -1,8 +1,38 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import { loadAsync } from './Font';
|
|
3
|
+
import { loadAsync, isLoaded } from './Font';
|
|
4
4
|
import { FontSource } from './Font.types';
|
|
5
5
|
|
|
6
|
+
function isMapLoaded(map: string | Record<string, FontSource>) {
|
|
7
|
+
if (typeof map === 'string') {
|
|
8
|
+
return isLoaded(map);
|
|
9
|
+
} else {
|
|
10
|
+
return Object.keys(map).every((fontFamily) => isLoaded(fontFamily));
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function useRuntimeFonts(map: string | Record<string, FontSource>): [boolean, Error | null] {
|
|
15
|
+
const [loaded, setLoaded] = useState(
|
|
16
|
+
// For web rehydration, we need to check if the fonts are already loaded during the static render.
|
|
17
|
+
// Native will also benefit from this optimization.
|
|
18
|
+
isMapLoaded(map)
|
|
19
|
+
);
|
|
20
|
+
const [error, setError] = useState<Error | null>(null);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
loadAsync(map)
|
|
24
|
+
.then(() => setLoaded(true))
|
|
25
|
+
.catch(setError);
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
return [loaded, error];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function useStaticFonts(map: string | Record<string, FontSource>): [boolean, Error | null] {
|
|
32
|
+
loadAsync(map);
|
|
33
|
+
return [true, null];
|
|
34
|
+
}
|
|
35
|
+
|
|
6
36
|
// @needsAudit
|
|
7
37
|
/**
|
|
8
38
|
* ```ts
|
|
@@ -21,15 +51,5 @@ import { FontSource } from './Font.types';
|
|
|
21
51
|
* loading.
|
|
22
52
|
* - __error__ (`Error | null`) - An error encountered when loading the fonts.
|
|
23
53
|
*/
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
const [error, setError] = useState<Error | null>(null);
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
loadAsync(map)
|
|
30
|
-
.then(() => setLoaded(true))
|
|
31
|
-
.catch(setError);
|
|
32
|
-
}, []);
|
|
33
|
-
|
|
34
|
-
return [loaded, error];
|
|
35
|
-
}
|
|
54
|
+
export const useFonts: (map: string | Record<string, FontSource>) => [boolean, Error | null] =
|
|
55
|
+
typeof window === 'undefined' ? useStaticFonts : useRuntimeFonts;
|
package/src/FontLoader.web.ts
CHANGED
|
@@ -46,19 +46,19 @@ function throwInvalidSourceError(source: any): never {
|
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
input: Asset | FontResource
|
|
52
|
-
): Promise<void> {
|
|
49
|
+
// NOTE(EvanBacon): No async keyword!
|
|
50
|
+
export function loadSingleFontAsync(name: string, input: Asset | FontResource): Promise<void> {
|
|
53
51
|
if (typeof input !== 'object' || typeof input.uri !== 'string' || (input as any).downloadAsync) {
|
|
54
52
|
throwInvalidSourceError(input);
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
try {
|
|
58
|
-
|
|
56
|
+
return ExpoFontLoader.loadAsync(name, input);
|
|
59
57
|
} catch {
|
|
60
58
|
// No-op.
|
|
61
59
|
}
|
|
60
|
+
|
|
61
|
+
return Promise.resolve();
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export function getNativeFontName(name: string): string {
|
package/src/memory.ts
ADDED
package/src/server.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CodedError } from 'expo-modules-core';
|
|
2
|
+
|
|
3
|
+
import ExpoFontLoader from './ExpoFontLoader';
|
|
4
|
+
import { FontSource } from './Font.types';
|
|
5
|
+
import { getAssetForSource, loadSingleFontAsync } from './FontLoader';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @returns the server resources that should be statically extracted.
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
export function getServerResources() {
|
|
12
|
+
return ExpoFontLoader.getServerResources();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @returns clear the server resources from the global scope.
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
export function resetServerContext() {
|
|
20
|
+
return ExpoFontLoader.resetServerContext();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function registerStaticFont(fontFamily: string, source?: FontSource | null) {
|
|
24
|
+
// MUST BE A SYNC FUNCTION!
|
|
25
|
+
if (!source) {
|
|
26
|
+
throw new CodedError(
|
|
27
|
+
`ERR_FONT_SOURCE`,
|
|
28
|
+
`Cannot load null or undefined font source: { "${fontFamily}": ${source} }. Expected asset of type \`FontSource\` for fontFamily of name: "${fontFamily}"`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const asset = getAssetForSource(source);
|
|
32
|
+
|
|
33
|
+
loadSingleFontAsync(fontFamily, asset);
|
|
34
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
package expo.modules.font
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import expo.modules.core.BasePackage
|
|
5
|
-
import expo.modules.core.ExportedModule
|
|
6
|
-
|
|
7
|
-
class FontLoaderPackage : BasePackage() {
|
|
8
|
-
override fun createExportedModules(context: Context): List<ExportedModule> {
|
|
9
|
-
return listOf<ExportedModule>(FontLoaderModule(context))
|
|
10
|
-
}
|
|
11
|
-
}
|