expo-font 11.10.3 → 12.0.1
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 +21 -3
- package/android/build.gradle +7 -95
- package/build/ExpoFontLoader.web.d.ts +0 -1
- package/build/ExpoFontLoader.web.d.ts.map +1 -1
- package/build/ExpoFontLoader.web.js +0 -3
- package/build/ExpoFontLoader.web.js.map +1 -1
- package/build/Font.types.d.ts +2 -2
- package/build/Font.types.js.map +1 -1
- package/build/FontHooks.d.ts +1 -1
- package/build/FontHooks.js +1 -1
- package/build/FontHooks.js.map +1 -1
- package/build/FontLoader.d.ts.map +1 -1
- package/build/FontLoader.js +4 -5
- package/build/FontLoader.js.map +1 -1
- package/expo-module.config.json +3 -0
- package/ios/{EXFont.podspec → ExpoFont.podspec} +8 -7
- package/ios/FontExceptions.swift +19 -0
- package/ios/FontFamilyAliasManager.swift +59 -0
- package/ios/FontLoaderModule.swift +31 -0
- package/ios/FontUtils.swift +85 -0
- package/ios/UIFont+FontFamilyAlias.swift +18 -0
- package/package.json +2 -2
- package/src/ExpoFontLoader.web.ts +0 -4
- package/src/Font.types.ts +2 -2
- package/src/FontHooks.ts +1 -1
- package/src/FontLoader.ts +4 -5
- package/ios/EXFont/EXFont.h +0 -13
- package/ios/EXFont/EXFont.m +0 -43
- package/ios/EXFont/EXFontLoader.h +0 -10
- package/ios/EXFont/EXFontLoader.m +0 -148
- package/ios/EXFont/EXFontLoaderProcessor.h +0 -14
- package/ios/EXFont/EXFontLoaderProcessor.m +0 -69
- package/ios/EXFont/EXFontManager.h +0 -12
- package/ios/EXFont/EXFontManager.m +0 -31
- package/ios/EXFont/EXFontScaler.h +0 -8
- package/ios/EXFont/EXFontScaler.m +0 -16
- package/ios/EXFont/Singletons/EXFontScalersManager.h +0 -8
- package/ios/EXFont/Singletons/EXFontScalersManager.m +0 -61
package/CHANGELOG.md
CHANGED
|
@@ -10,17 +10,35 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## 12.0.1 — 2024-04-22
|
|
14
|
+
|
|
15
|
+
### 💡 Others
|
|
16
|
+
|
|
17
|
+
- Stopped scoping font family names in Expo Go on iOS. ([#28344](https://github.com/expo/expo/pull/28344) by [@tsapeta](https://github.com/tsapeta))
|
|
18
|
+
|
|
19
|
+
## 12.0.0 — 2024-04-18
|
|
20
|
+
|
|
21
|
+
### 🎉 New features
|
|
22
|
+
|
|
23
|
+
- [iOS] The native module has been simplified and rewritten to Swift. ([#26380](https://github.com/expo/expo/pull/26380) by [@tsapeta](https://github.com/tsapeta))
|
|
24
|
+
|
|
25
|
+
### 💡 Others
|
|
26
|
+
|
|
27
|
+
- drop unused web `name` property. ([#27437](https://github.com/expo/expo/pull/27437) by [@EvanBacon](https://github.com/EvanBacon))
|
|
28
|
+
- Remove most of Constants.appOwnership. ([#26313](https://github.com/expo/expo/pull/26313) by [@wschurman](https://github.com/wschurman))
|
|
29
|
+
- Removed deprecated backward compatible Gradle settings. ([#28083](https://github.com/expo/expo/pull/28083) by [@kudo](https://github.com/kudo))
|
|
30
|
+
|
|
31
|
+
## 11.10.3 - 2024-02-16
|
|
14
32
|
|
|
15
33
|
### 🐛 Bug fixes
|
|
16
34
|
|
|
17
35
|
- Only include supported font files when using the plugin. ([#27002](https://github.com/expo/expo/pull/27002) by [@alanjhughes](https://github.com/alanjhughes))
|
|
18
36
|
|
|
19
|
-
## 11.10.2
|
|
37
|
+
## 11.10.2 - 2024-01-18
|
|
20
38
|
|
|
21
39
|
_This version does not introduce any user-facing changes._
|
|
22
40
|
|
|
23
|
-
## 11.10.1
|
|
41
|
+
## 11.10.1 - 2024-01-10
|
|
24
42
|
|
|
25
43
|
### 🎉 New features
|
|
26
44
|
|
package/android/build.gradle
CHANGED
|
@@ -1,107 +1,19 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
|
-
apply plugin: 'kotlin-android'
|
|
3
|
-
apply plugin: 'maven-publish'
|
|
4
2
|
|
|
5
3
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '
|
|
4
|
+
version = '12.0.1'
|
|
7
5
|
|
|
8
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
useExpoPublishing()
|
|
15
|
-
useCoreDependencies()
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
buildscript {
|
|
20
|
-
// Simple helper that allows the root project to override versions declared by this library.
|
|
21
|
-
ext.safeExtGet = { prop, fallback ->
|
|
22
|
-
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Ensures backward compatibility
|
|
26
|
-
ext.getKotlinVersion = {
|
|
27
|
-
if (ext.has("kotlinVersion")) {
|
|
28
|
-
ext.kotlinVersion()
|
|
29
|
-
} else {
|
|
30
|
-
ext.safeExtGet("kotlinVersion", "1.8.10")
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
repositories {
|
|
35
|
-
mavenCentral()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
dependencies {
|
|
39
|
-
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
44
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
45
|
-
afterEvaluate {
|
|
46
|
-
publishing {
|
|
47
|
-
publications {
|
|
48
|
-
release(MavenPublication) {
|
|
49
|
-
from components.release
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
repositories {
|
|
53
|
-
maven {
|
|
54
|
-
url = mavenLocal().url
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
7
|
+
apply from: expoModulesCorePlugin
|
|
8
|
+
applyKotlinExpoModulesCorePlugin()
|
|
9
|
+
useCoreDependencies()
|
|
10
|
+
useDefaultAndroidSdkVersions()
|
|
11
|
+
useExpoPublishing()
|
|
60
12
|
|
|
61
13
|
android {
|
|
62
|
-
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
63
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
64
|
-
compileSdkVersion safeExtGet("compileSdkVersion", 34)
|
|
65
|
-
|
|
66
|
-
defaultConfig {
|
|
67
|
-
minSdkVersion safeExtGet("minSdkVersion", 23)
|
|
68
|
-
targetSdkVersion safeExtGet("targetSdkVersion", 34)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
publishing {
|
|
72
|
-
singleVariant("release") {
|
|
73
|
-
withSourcesJar()
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
lintOptions {
|
|
78
|
-
abortOnError false
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
83
|
-
if (agpVersion.tokenize('.')[0].toInteger() < 8) {
|
|
84
|
-
compileOptions {
|
|
85
|
-
sourceCompatibility JavaVersion.VERSION_11
|
|
86
|
-
targetCompatibility JavaVersion.VERSION_11
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
kotlinOptions {
|
|
90
|
-
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
14
|
namespace "expo.modules.font"
|
|
95
15
|
defaultConfig {
|
|
96
16
|
versionCode 29
|
|
97
|
-
versionName "
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
dependencies {
|
|
102
|
-
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
103
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
104
|
-
implementation project(':expo-modules-core')
|
|
105
|
-
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
17
|
+
versionName "12.0.1"
|
|
106
18
|
}
|
|
107
19
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { UnloadFontOptions } from './Font';
|
|
2
2
|
import { FontResource } from './Font.types';
|
|
3
3
|
declare const _default: {
|
|
4
|
-
readonly name: string;
|
|
5
4
|
unloadAllAsync(): Promise<void>;
|
|
6
5
|
unloadAsync(fontFamilyName: string, options?: UnloadFontOptions): Promise<void>;
|
|
7
6
|
getServerResources(): string[];
|
|
@@ -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;;sBAiF/B,QAAQ,IAAI,CAAC;gCASH,MAAM,YAAY,iBAAiB,GAAG,QAAQ,IAAI,CAAC;0BAS/D,MAAM,EAAE;;6BAqBL,MAAM,aAAY,iBAAiB,GAAQ,OAAO;8BAUjD,MAAM,YAAY,YAAY,GAAG,QAAQ,IAAI,CAAC;;AAlD1E,wBAmFE;AAeF,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CAIzF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoFontLoader.web.js","sourceRoot":"","sources":["../src/ExpoFontLoader.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAgB,MAAM,cAAc,CAAC;AAEzD,SAAS,qBAAqB;IAC5B,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IACD,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;IACrC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAE,UAAU,CAAC,KAAuB,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAID,SAAS,gBAAgB;IACvB,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAC;IACtC,IAAI,KAAK,EAAE;QACT,4BAA4B;QAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElC,MAAM,KAAK,GAAe,EAAE,CAAC;QAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,YAAY,eAAe,EAAE;gBACnC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;aAChC;SACF;QACD,OAAO,KAAK,CAAC;KACd;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,gCAAgC,CACvC,cAAsB,EACtB,OAA2B;IAE3B,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QAC/B,OAAO,CACL,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,cAAc;YACxC,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,KAAM,IAAI,CAAC,KAAa,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAC1F,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,aAAa,GAA2D,IAAI,GAAG,EAAE,CAAC;AAExF,SAAS,eAAe;IAUtB,MAAM,OAAO,GAAG,CAAC,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QACnB,OAAO,EAAE,CAAC;KACX;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;IAC5D,sDAAsD;IACtD,OAAO;QACL;YACE,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,GAAG;YACb,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,UAAU;SACjB;QACD,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAC5B,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,MAAM;YACV,WAAW,EAAE,EAAE;SAChB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,eAAe;IACb,IAAI,IAAI;QACN,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,QAAQ,CAAC,cAAc;YAAE,OAAO;QAErC,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,OAAO,IAAI,OAAO,YAAY,gBAAgB,EAAE;YAClD,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;SAC/B;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,cAAsB,EAAE,OAA2B;QACnE,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,KAAK,GAAG,gCAAgC,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACxE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC9B;IACH,CAAC;IAED,kBAAkB;QAChB,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;QAEnC,OAAO,QAAQ;aACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACf,QAAQ,OAAO,CAAC,MAAM,EAAE;gBACtB,KAAK,OAAO;oBACV,OAAO,cAAc,OAAO,CAAC,EAAE,WAAW,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,UAAU,CAAC;gBACxF,KAAK,MAAM;oBACT,OAAO,cAAc,OAAO,CAAC,GAAG,WAAW,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,EAAE,kBAAkB,OAAO,CAAC,WAAW,MAAM,CAAC;gBACxH;oBACE,OAAO,EAAE,CAAC;aACb;QACH,CAAC,CAAC;aACD,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,kBAAkB;QAChB,aAAa,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,cAAsB,EAAE,WAA8B,EAAE;QAC/D,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBAClD,OAAO,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC;YACvC,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,gCAAgC,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;IAChF,CAAC;IAED,wFAAwF;IACxF,SAAS,CAAC,cAAsB,EAAE,QAAsB;QACtD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,aAAa,CAAC,GAAG,CAAC;gBAChB,IAAI,EAAE,cAAc;gBACpB,GAAG,EAAE,sBAAsB,CAAC,cAAc,EAAE,QAAQ,CAAC;gBACrD,kCAAkC;gBAClC,UAAU,EAAE,QAAQ,CAAC,GAAI;aAC1B,CAAC,CAAC;YACH,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,KAAK,UAAU,CAAC;QACxF,IAAI,CAAC,cAAc,EAAE;YACnB,MAAM,IAAI,UAAU,CAClB,qBAAqB,EACrB,0EAA0E,CAC3E,CAAC;SACH;QAED,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAElC,MAAM,GAAG,GAAG,gCAAgC,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;YACf,eAAe,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;SAC3C;QAED,IAAI,CAAC,8BAA8B,EAAE,EAAE;YACrC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QAED,OAAO,IAAI,YAAY,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1F,CAAC;CACF,CAAC;AAEF,MAAM,EAAE,GAAG,sBAAsB,CAAC;AAElC,SAAS,eAAe;IACtB,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAC5C,IAAI,OAAO,IAAI,OAAO,YAAY,gBAAgB,EAAE;QAClD,OAAO,OAAO,CAAC;KAChB;IACD,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IACrB,YAAY,CAAC,IAAI,GAAG,UAAU,CAAC;IAC/B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,QAAsB;IAC/E,OAAO,0BAA0B,UAAU,YAAY,QAAQ,CAAC,GAAG,kBACjE,QAAQ,CAAC,OAAO,IAAI,WAAW,CAAC,IAClC,GAAG,CAAC;AACN,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB,EAAE,QAAsB;IACjE,MAAM,SAAS,GAAG,sBAAsB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE/D,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,+FAA+F;IAC/F,wDAAwD;IACxD,IAAI,YAAY,CAAC,UAAU,EAAE;QAC3B,MAAM,cAAc,GAAG,YAAmB,CAAC;QAC3C,cAAc,CAAC,UAAU,CAAC,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,OAAO;YACnE,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,GAAG,SAAS;YAC/C,CAAC,CAAC,SAAS,CAAC;KACf;SAAM;QACL,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACpD,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;KACpC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAS,8BAA8B;IACrC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,2EAA2E;IAC3E,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,gCAAgC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5E,iGAAiG;IACjG,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1C,oBAAoB;IACpB,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3C,UAAU;IACV,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC;AAC/D,CAAC","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\n .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 .filter(Boolean);\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"]}
|
|
1
|
+
{"version":3,"file":"ExpoFontLoader.web.js","sourceRoot":"","sources":["../src/ExpoFontLoader.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,YAAY,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAgB,MAAM,cAAc,CAAC;AAEzD,SAAS,qBAAqB;IAC5B,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IACD,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;IACrC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAE,UAAU,CAAC,KAAuB,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAID,SAAS,gBAAgB;IACvB,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAC;IACtC,IAAI,KAAK,EAAE;QACT,4BAA4B;QAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElC,MAAM,KAAK,GAAe,EAAE,CAAC;QAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,YAAY,eAAe,EAAE;gBACnC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;aAChC;SACF;QACD,OAAO,KAAK,CAAC;KACd;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,gCAAgC,CACvC,cAAsB,EACtB,OAA2B;IAE3B,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QAC/B,OAAO,CACL,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,cAAc;YACxC,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,KAAM,IAAI,CAAC,KAAa,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAC1F,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,aAAa,GAA2D,IAAI,GAAG,EAAE,CAAC;AAExF,SAAS,eAAe;IAUtB,MAAM,OAAO,GAAG,CAAC,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QACnB,OAAO,EAAE,CAAC;KACX;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;IAC5D,sDAAsD;IACtD,OAAO;QACL;YACE,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,GAAG;YACb,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,UAAU;SACjB;QACD,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAC5B,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,MAAM;YACV,WAAW,EAAE,EAAE;SAChB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,eAAe;IACb,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,QAAQ,CAAC,cAAc;YAAE,OAAO;QAErC,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,OAAO,IAAI,OAAO,YAAY,gBAAgB,EAAE;YAClD,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;SAC/B;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,cAAsB,EAAE,OAA2B;QACnE,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,KAAK,GAAG,gCAAgC,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACxE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC9B;IACH,CAAC;IAED,kBAAkB;QAChB,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;QAEnC,OAAO,QAAQ;aACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACf,QAAQ,OAAO,CAAC,MAAM,EAAE;gBACtB,KAAK,OAAO;oBACV,OAAO,cAAc,OAAO,CAAC,EAAE,WAAW,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,UAAU,CAAC;gBACxF,KAAK,MAAM;oBACT,OAAO,cAAc,OAAO,CAAC,GAAG,WAAW,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,EAAE,kBAAkB,OAAO,CAAC,WAAW,MAAM,CAAC;gBACxH;oBACE,OAAO,EAAE,CAAC;aACb;QACH,CAAC,CAAC;aACD,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,kBAAkB;QAChB,aAAa,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,cAAsB,EAAE,WAA8B,EAAE;QAC/D,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBAClD,OAAO,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC;YACvC,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,gCAAgC,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;IAChF,CAAC;IAED,wFAAwF;IACxF,SAAS,CAAC,cAAsB,EAAE,QAAsB;QACtD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,aAAa,CAAC,GAAG,CAAC;gBAChB,IAAI,EAAE,cAAc;gBACpB,GAAG,EAAE,sBAAsB,CAAC,cAAc,EAAE,QAAQ,CAAC;gBACrD,kCAAkC;gBAClC,UAAU,EAAE,QAAQ,CAAC,GAAI;aAC1B,CAAC,CAAC;YACH,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,KAAK,UAAU,CAAC;QACxF,IAAI,CAAC,cAAc,EAAE;YACnB,MAAM,IAAI,UAAU,CAClB,qBAAqB,EACrB,0EAA0E,CAC3E,CAAC;SACH;QAED,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAElC,MAAM,GAAG,GAAG,gCAAgC,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;YACf,eAAe,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;SAC3C;QAED,IAAI,CAAC,8BAA8B,EAAE,EAAE;YACrC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QAED,OAAO,IAAI,YAAY,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1F,CAAC;CACF,CAAC;AAEF,MAAM,EAAE,GAAG,sBAAsB,CAAC;AAElC,SAAS,eAAe;IACtB,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAC5C,IAAI,OAAO,IAAI,OAAO,YAAY,gBAAgB,EAAE;QAClD,OAAO,OAAO,CAAC;KAChB;IACD,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IACrB,YAAY,CAAC,IAAI,GAAG,UAAU,CAAC;IAC/B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,QAAsB;IAC/E,OAAO,0BAA0B,UAAU,YAAY,QAAQ,CAAC,GAAG,kBACjE,QAAQ,CAAC,OAAO,IAAI,WAAW,CAAC,IAClC,GAAG,CAAC;AACN,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB,EAAE,QAAsB;IACjE,MAAM,SAAS,GAAG,sBAAsB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE/D,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,+FAA+F;IAC/F,wDAAwD;IACxD,IAAI,YAAY,CAAC,UAAU,EAAE;QAC3B,MAAM,cAAc,GAAG,YAAmB,CAAC;QAC3C,cAAc,CAAC,UAAU,CAAC,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,OAAO;YACnE,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,GAAG,SAAS;YAC/C,CAAC,CAAC,SAAS,CAAC;KACf;SAAM;QACL,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACpD,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;KACpC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAS,8BAA8B;IACrC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,2EAA2E;IAC3E,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,gCAAgC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5E,iGAAiG;IACjG,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1C,oBAAoB;IACpB,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3C,UAAU;IACV,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC;AAC/D,CAAC","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 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\n .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 .filter(Boolean);\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.types.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Asset } from 'expo-asset';
|
|
2
2
|
/**
|
|
3
|
-
* The different types of assets you can provide to the [`loadAsync()`](#
|
|
3
|
+
* The different types of assets you can provide to the [`loadAsync()`](#loadasyncfontfamilyorfontmap-source) function.
|
|
4
4
|
* A font source can be a URI, a module ID, or an Expo Asset.
|
|
5
5
|
*/
|
|
6
6
|
export type FontSource = string | number | Asset | FontResource;
|
|
7
7
|
/**
|
|
8
8
|
* An object used to dictate the resource that is loaded into the provided font namespace when used
|
|
9
|
-
* with [`loadAsync`](#
|
|
9
|
+
* with [`loadAsync`](#loadasyncfontfamilyorfontmap-source).
|
|
10
10
|
*/
|
|
11
11
|
export type FontResource = {
|
|
12
12
|
uri?: string | number;
|
package/build/Font.types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Font.types.js","sourceRoot":"","sources":["../src/Font.types.ts"],"names":[],"mappings":"AAwBA,cAAc;AACd;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,WA8BX;AA9BD,WAAY,WAAW;IACrB;;;;OAIG;IACH,4BAAa,CAAA;IACb;;;OAGG;IACH,4BAAa,CAAA;IACb;;;OAGG;IACH,8BAAe,CAAA;IACf;;;;;;OAMG;IACH,oCAAqB,CAAA;IACrB;;;OAGG;IACH,oCAAqB,CAAA;AACvB,CAAC,EA9BW,WAAW,KAAX,WAAW,QA8BtB","sourcesContent":["import { Asset } from 'expo-asset';\n\n// @needsAudit\n/**\n * The different types of assets you can provide to the [`loadAsync()`](#
|
|
1
|
+
{"version":3,"file":"Font.types.js","sourceRoot":"","sources":["../src/Font.types.ts"],"names":[],"mappings":"AAwBA,cAAc;AACd;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,WA8BX;AA9BD,WAAY,WAAW;IACrB;;;;OAIG;IACH,4BAAa,CAAA;IACb;;;OAGG;IACH,4BAAa,CAAA;IACb;;;OAGG;IACH,8BAAe,CAAA;IACf;;;;;;OAMG;IACH,oCAAqB,CAAA;IACrB;;;OAGG;IACH,oCAAqB,CAAA;AACvB,CAAC,EA9BW,WAAW,KAAX,WAAW,QA8BtB","sourcesContent":["import { Asset } from 'expo-asset';\n\n// @needsAudit\n/**\n * The different types of assets you can provide to the [`loadAsync()`](#loadasyncfontfamilyorfontmap-source) function.\n * A font source can be a URI, a module ID, or an Expo Asset.\n */\nexport type FontSource = string | number | Asset | FontResource;\n\n// @needsAudit\n/**\n * An object used to dictate the resource that is loaded into the provided font namespace when used\n * with [`loadAsync`](#loadasyncfontfamilyorfontmap-source).\n */\nexport type FontResource = {\n uri?: string | number;\n /**\n * Sets the [`font-display`](#fontdisplay) property for a given typeface in the browser.\n * @platform web\n */\n display?: FontDisplay;\n default?: string;\n};\n\n// @needsAudit\n/**\n * Sets the [font-display](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display)\n * for a given typeface. The default font value on web is `FontDisplay.AUTO`.\n * Even though setting the `fontDisplay` does nothing on native platforms, the default behavior\n * emulates `FontDisplay.SWAP` on flagship devices like iOS, Samsung, Pixel, etc. Default\n * functionality varies on One Plus devices. In the browser this value is set in the generated\n * `@font-face` CSS block and not as a style property meaning you cannot dynamically change this\n * value based on the element it's used in.\n * @platform web\n */\nexport enum FontDisplay {\n /**\n * __(Default)__ The font display strategy is defined by the user agent or platform.\n * This generally defaults to the text being invisible until the font is loaded.\n * Good for buttons or banners that require a specific treatment.\n */\n AUTO = 'auto',\n /**\n * Fallback text is rendered immediately with a default font while the desired font is loaded.\n * This is good for making the content appear to load instantly and is usually preferred.\n */\n SWAP = 'swap',\n /**\n * The text will be invisible until the font has loaded. If the font fails to load then nothing\n * will appear - it's best to turn this off when debugging missing text.\n */\n BLOCK = 'block',\n /**\n * Splits the behavior between `SWAP` and `BLOCK`.\n * There will be a [100ms timeout](https://developers.google.com/web/updates/2016/02/font-display?hl=en)\n * where the text with a custom font is invisible, after that the text will either swap to the\n * styled text or it'll show the unstyled text and continue to load the custom font. This is good\n * for buttons that need a custom font but should also be quickly available to screen-readers.\n */\n FALLBACK = 'fallback',\n /**\n * This works almost identically to `FALLBACK`, the only difference is that the browser will\n * decide to load the font based on slow connection speed or critical resource demand.\n */\n OPTIONAL = 'optional',\n}\n\n// @needsAudit\n/**\n * Object used to query fonts for unloading.\n */\nexport type UnloadFontOptions = Pick<FontResource, 'display'>;\n"]}
|
package/build/FontHooks.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { FontSource } from './Font.types';
|
|
|
3
3
|
* ```ts
|
|
4
4
|
* const [loaded, error] = useFonts({ ... });
|
|
5
5
|
* ```
|
|
6
|
-
* Load a map of fonts with [`loadAsync`](#
|
|
6
|
+
* Load a map of fonts with [`loadAsync`](#loadasyncfontfamilyorfontmap-source). This returns a `boolean` if the fonts are
|
|
7
7
|
* loaded and ready to use. It also returns an error if something went wrong, to use in development.
|
|
8
8
|
*
|
|
9
9
|
* > Note, the fonts are not "reloaded" when you dynamically change the font map.
|
package/build/FontHooks.js
CHANGED
|
@@ -30,7 +30,7 @@ function useStaticFonts(map) {
|
|
|
30
30
|
* ```ts
|
|
31
31
|
* const [loaded, error] = useFonts({ ... });
|
|
32
32
|
* ```
|
|
33
|
-
* Load a map of fonts with [`loadAsync`](#
|
|
33
|
+
* Load a map of fonts with [`loadAsync`](#loadasyncfontfamilyorfontmap-source). This returns a `boolean` if the fonts are
|
|
34
34
|
* loaded and ready to use. It also returns an error if something went wrong, to use in development.
|
|
35
35
|
*
|
|
36
36
|
* > Note, the fonts are not "reloaded" when you dynamically change the font 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,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`](#
|
|
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`](#loadasyncfontfamilyorfontmap-source). 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.d.ts","sourceRoot":"","sources":["../src/FontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"FontLoader.d.ts","sourceRoot":"","sources":["../src/FontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKnC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAIxD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ5D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,YAAY,CAiB1E;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,GAAG,YAAY,GAC1B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD"}
|
package/build/FontLoader.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { Asset } from 'expo-asset';
|
|
2
2
|
import Constants from 'expo-constants';
|
|
3
|
-
import { CodedError } from 'expo-modules-core';
|
|
4
|
-
import { Platform } from 'react-native';
|
|
3
|
+
import { CodedError, Platform } from 'expo-modules-core';
|
|
5
4
|
import ExpoFontLoader from './ExpoFontLoader';
|
|
6
|
-
const
|
|
7
|
-
const isInIOSStandalone = Constants.appOwnership === 'standalone' && Platform.OS === 'ios';
|
|
5
|
+
const isInExpoGo = Constants.appOwnership === 'expo';
|
|
8
6
|
export function fontFamilyNeedsScoping(name) {
|
|
9
|
-
return (
|
|
7
|
+
return (isInExpoGo &&
|
|
8
|
+
Platform.OS !== 'ios' &&
|
|
10
9
|
!Constants.systemFonts.includes(name) &&
|
|
11
10
|
name !== 'System' &&
|
|
12
11
|
!name.includes(Constants.sessionId));
|
package/build/FontLoader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontLoader.js","sourceRoot":"","sources":["../src/FontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"FontLoader.js","sourceRoot":"","sources":["../src/FontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAG9C,MAAM,UAAU,GAAG,SAAS,CAAC,YAAY,KAAK,MAAM,CAAC;AAErD,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,CACL,UAAU;QACV,QAAQ,CAAC,EAAE,KAAK,KAAK;QACrB,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;QACrC,IAAI,KAAK,QAAQ;QACjB,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,CACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,IAAI,MAAM,YAAY,KAAK,EAAE;QAC3B,OAAO,MAAM,CAAC;KACf;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QAC9B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;KAC9B;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACrC,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;KACjC;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,WAAW,EAAE;QAC1E,OAAO,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;KACtC;IAED,oEAAoE;IACpE,uEAAuE;IACvE,yCAAyC;IACzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,KAA2B;IAE3B,MAAM,KAAK,GAAG,KAAc,CAAC;IAC7B,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE;QACxB,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,mFAAmF,CACpF,CAAC;KACH;IAED,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;QACrB,MAAM,IAAI,UAAU,CAAC,cAAc,EAAE,sCAAsC,IAAI,GAAG,CAAC,CAAC;KACrF;IACD,MAAM,cAAc,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE;QAChC,OAAO,GAAG,SAAS,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC;KACzC;SAAM;QACL,OAAO,IAAI,CAAC;KACb;AACH,CAAC","sourcesContent":["import { Asset } from 'expo-asset';\nimport Constants from 'expo-constants';\nimport { CodedError, Platform } from 'expo-modules-core';\n\nimport ExpoFontLoader from './ExpoFontLoader';\nimport { FontResource, FontSource } from './Font.types';\n\nconst isInExpoGo = Constants.appOwnership === 'expo';\n\nexport function fontFamilyNeedsScoping(name: string): boolean {\n return (\n isInExpoGo &&\n Platform.OS !== 'ios' &&\n !Constants.systemFonts.includes(name) &&\n name !== 'System' &&\n !name.includes(Constants.sessionId)\n );\n}\n\nexport function getAssetForSource(source: FontSource): Asset | FontResource {\n if (source instanceof Asset) {\n return source;\n }\n\n if (typeof source === 'string') {\n return Asset.fromURI(source);\n } else if (typeof source === 'number') {\n return Asset.fromModule(source);\n } else if (typeof source === 'object' && typeof source.uri !== 'undefined') {\n return getAssetForSource(source.uri);\n }\n\n // @ts-ignore Error: Type 'string' is not assignable to type 'Asset'\n // We can't have a string here, we would have thrown an error if !isWeb\n // or returned Asset.fromModule if isWeb.\n return source;\n}\n\nexport async function loadSingleFontAsync(\n name: string,\n input: Asset | FontResource\n): Promise<void> {\n const asset = input as Asset;\n if (!asset.downloadAsync) {\n throw new CodedError(\n `ERR_FONT_SOURCE`,\n '`loadSingleFontAsync` expected resource of type `Asset` from expo-asset on native'\n );\n }\n\n await asset.downloadAsync();\n if (!asset.downloaded) {\n throw new CodedError(`ERR_DOWNLOAD`, `Failed to download asset for font \"${name}\"`);\n }\n await ExpoFontLoader.loadAsync(getNativeFontName(name), asset.localUri);\n}\n\nexport function getNativeFontName(name: string): string {\n if (fontFamilyNeedsScoping(name)) {\n return `${Constants.sessionId}-${name}`;\n } else {\n return name;\n }\n}\n"]}
|
package/expo-module.config.json
CHANGED
|
@@ -3,7 +3,7 @@ require 'json'
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
|
4
4
|
|
|
5
5
|
Pod::Spec.new do |s|
|
|
6
|
-
s.name = '
|
|
6
|
+
s.name = 'ExpoFont'
|
|
7
7
|
s.version = package['version']
|
|
8
8
|
s.summary = package['description']
|
|
9
9
|
s.description = package['description']
|
|
@@ -15,15 +15,16 @@ Pod::Spec.new do |s|
|
|
|
15
15
|
:osx => '10.15',
|
|
16
16
|
:tvos => '13.4'
|
|
17
17
|
}
|
|
18
|
+
s.swift_version = '5.4'
|
|
18
19
|
s.source = { git: 'https://github.com/expo/expo.git' }
|
|
19
20
|
s.static_framework = true
|
|
20
21
|
|
|
21
22
|
s.dependency 'ExpoModulesCore'
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
# Swift/Objective-C compatibility
|
|
25
|
+
s.pod_target_xcconfig = {
|
|
26
|
+
'DEFINES_MODULE' => 'YES'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
s.source_files = "**/*.{h,m,swift}"
|
|
29
30
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
|
|
3
|
+
internal final class FontFileNotFoundException: GenericException<String> {
|
|
4
|
+
override var reason: String {
|
|
5
|
+
"Font file '\(param)' doesn't exist"
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
internal final class FontCreationFailedException: GenericException<String> {
|
|
10
|
+
override var reason: String {
|
|
11
|
+
"Could not create font from loaded data for '\(param)'"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
internal final class FontRegistrationFailedException: GenericException<CFError> {
|
|
16
|
+
override var reason: String {
|
|
17
|
+
"Registering '\(param)' font failed with message: '\(param.localizedDescription)'"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
A registry of font family aliases mapped to their real font family names.
|
|
5
|
+
*/
|
|
6
|
+
private var fontFamilyAliases = [String: String]()
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
A flag that is set to `true` when the ``UIFont.fontNames(forFamilyName:)`` is already swizzled.
|
|
10
|
+
*/
|
|
11
|
+
private var hasSwizzled = false
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
Manages the font family aliases and swizzles the `UIFont` class.
|
|
15
|
+
*/
|
|
16
|
+
internal struct FontFamilyAliasManager {
|
|
17
|
+
/**
|
|
18
|
+
Whether the given alias has already been set.
|
|
19
|
+
*/
|
|
20
|
+
internal static func hasAlias(_ familyNameAlias: String) -> Bool {
|
|
21
|
+
return fontFamilyAliases[familyNameAlias] != nil
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
Sets the alias for the given family name.
|
|
26
|
+
If the alias has already been set, its family name will be overriden.
|
|
27
|
+
*/
|
|
28
|
+
internal static func setAlias(_ familyNameAlias: String, forFamilyName familyName: String) {
|
|
29
|
+
maybeSwizzleUIFont()
|
|
30
|
+
fontFamilyAliases[familyNameAlias] = familyName
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
Returns the family name for the given alias or `nil` when it's not set yet.
|
|
35
|
+
*/
|
|
36
|
+
internal static func familyName(forAlias familyNameAlias: String) -> String? {
|
|
37
|
+
return fontFamilyAliases[familyNameAlias]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
Swizzles ``UIFont.fontNames(forFamilyName:)`` to support font family aliases.
|
|
43
|
+
This is necessary because the user provides a custom family name that is then used in stylesheets,
|
|
44
|
+
however the font usually has a different name encoded in the binary, thus the system may use a different name.
|
|
45
|
+
*/
|
|
46
|
+
private func maybeSwizzleUIFont() {
|
|
47
|
+
if hasSwizzled {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
let originalMethod = class_getClassMethod(UIFont.self, #selector(UIFont.fontNames(forFamilyName:)))
|
|
51
|
+
let newMethod = class_getClassMethod(UIFont.self, #selector(UIFont._expo_fontNames(forFamilyName:)))
|
|
52
|
+
|
|
53
|
+
if let originalMethod, let newMethod {
|
|
54
|
+
method_exchangeImplementations(originalMethod, newMethod)
|
|
55
|
+
} else {
|
|
56
|
+
log.error("expo-font is unable to swizzle `UIFont.fontNames(forFamilyName:)`")
|
|
57
|
+
}
|
|
58
|
+
hasSwizzled = true
|
|
59
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
|
|
3
|
+
public final class FontLoaderModule: Module {
|
|
4
|
+
public func definition() -> ModuleDefinition {
|
|
5
|
+
Name("ExpoFontLoader")
|
|
6
|
+
|
|
7
|
+
Property("customNativeFonts") {
|
|
8
|
+
return queryCustomNativeFonts()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
AsyncFunction("loadAsync") { (fontFamilyAlias: String, localUri: URL) in
|
|
12
|
+
// If the font was already registered, unregister it first. Otherwise CTFontManagerRegisterGraphicsFont
|
|
13
|
+
// would fail because of a duplicated font name when the app reloads or someone wants to override a font.
|
|
14
|
+
if let familyName = FontFamilyAliasManager.familyName(forAlias: fontFamilyAlias) {
|
|
15
|
+
try unregisterFont(named: familyName)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Create a font object from the given file
|
|
19
|
+
let font = try loadFont(fromPath: localUri.path, alias: fontFamilyAlias)
|
|
20
|
+
|
|
21
|
+
// Register the font
|
|
22
|
+
try registerFont(font)
|
|
23
|
+
|
|
24
|
+
// The real font name might be different than it's been requested by the user,
|
|
25
|
+
// so we save the provided name as an alias.
|
|
26
|
+
if let fullName = font.fullName as? String {
|
|
27
|
+
FontFamilyAliasManager.setAlias(fontFamilyAlias, forFamilyName: fullName)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import CoreGraphics
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Queries custom native font names from the Info.plist `UIAppFonts`.
|
|
5
|
+
*/
|
|
6
|
+
internal func queryCustomNativeFonts() -> [String] {
|
|
7
|
+
// [0] Read from main bundle's Info.plist
|
|
8
|
+
guard let fontFilePaths = Bundle.main.object(forInfoDictionaryKey: "UIAppFonts") as? [String] else {
|
|
9
|
+
return []
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// [1] Get font family names for each font file
|
|
13
|
+
let fontFamilies: [[String]] = fontFilePaths.compactMap { fontFilePath in
|
|
14
|
+
guard let fontUrl = Bundle.main.url(forResource: fontFilePath, withExtension: nil) as? URL else {
|
|
15
|
+
return []
|
|
16
|
+
}
|
|
17
|
+
guard let fontDescriptors = CTFontManagerCreateFontDescriptorsFromURL(fontUrl as CFURL) as? [CTFontDescriptor] else {
|
|
18
|
+
return []
|
|
19
|
+
}
|
|
20
|
+
return fontDescriptors.compactMap { descriptor in
|
|
21
|
+
return CTFontDescriptorCopyAttribute(descriptor, kCTFontFamilyNameAttribute) as? String
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// [2] Retrieve font names by family names
|
|
26
|
+
return fontFamilies.flatMap { fontFamilyNames in
|
|
27
|
+
return fontFamilyNames.flatMap { fontFamilyName in
|
|
28
|
+
return UIFont.fontNames(forFamilyName: fontFamilyName)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
Loads the font from the given path and returns it as ``CGFont``.
|
|
35
|
+
*/
|
|
36
|
+
internal func loadFont(fromPath path: String, alias: String) throws -> CGFont {
|
|
37
|
+
guard let data = FileManager.default.contents(atPath: path) else {
|
|
38
|
+
throw FontFileNotFoundException(path)
|
|
39
|
+
}
|
|
40
|
+
guard let provider = CGDataProvider(data: data as CFData), let font = CGFont(provider) else {
|
|
41
|
+
throw FontCreationFailedException(alias)
|
|
42
|
+
}
|
|
43
|
+
return font
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
Registers the given font to make it discoverable through font descriptor matching.
|
|
48
|
+
*/
|
|
49
|
+
internal func registerFont(_ font: CGFont) throws {
|
|
50
|
+
var error: Unmanaged<CFError>?
|
|
51
|
+
|
|
52
|
+
if !CTFontManagerRegisterGraphicsFont(font, &error), let error = error?.takeRetainedValue() {
|
|
53
|
+
let fontError = CTFontManagerError(rawValue: CFErrorGetCode(error))
|
|
54
|
+
|
|
55
|
+
switch fontError {
|
|
56
|
+
case .alreadyRegistered, .duplicatedName:
|
|
57
|
+
// Ignore the error if:
|
|
58
|
+
// - this exact font instance was already registered or
|
|
59
|
+
// - another instance already registered with the same name (assuming it's most likely the same font anyway)
|
|
60
|
+
return
|
|
61
|
+
default:
|
|
62
|
+
throw FontRegistrationFailedException(error)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
Unregisters the given font, so the app will no longer be able to render it.
|
|
69
|
+
*/
|
|
70
|
+
internal func unregisterFont(_ font: CGFont) throws {
|
|
71
|
+
var error: Unmanaged<CFError>?
|
|
72
|
+
|
|
73
|
+
if !CTFontManagerUnregisterGraphicsFont(font, &error), let error = error?.takeRetainedValue() {
|
|
74
|
+
throw FontRegistrationFailedException(error)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
Unregisters a font with the given name, so the app will no longer be able to render it.
|
|
80
|
+
*/
|
|
81
|
+
internal func unregisterFont(named fontName: String) throws {
|
|
82
|
+
if let font = CGFont(fontName as CFString) {
|
|
83
|
+
try unregisterFont(font)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
An extension to ``UIFont`` that adds a custom implementation of `fontNames(forFamilyName:)` that supports aliasing font families.
|
|
3
|
+
*/
|
|
4
|
+
public extension UIFont {
|
|
5
|
+
/**
|
|
6
|
+
Returns an array of font names for the specified family name or its alias.
|
|
7
|
+
*/
|
|
8
|
+
@objc
|
|
9
|
+
static dynamic func _expo_fontNames(forFamilyName familyName: String) -> [String] {
|
|
10
|
+
let fontNames = UIFont._expo_fontNames(forFamilyName: familyName)
|
|
11
|
+
|
|
12
|
+
if fontNames.isEmpty, let aliasedFamilyName = FontFamilyAliasManager.familyName(forAlias: familyName) {
|
|
13
|
+
// Note that this actually calls the original method implementation (if swizzled).
|
|
14
|
+
return UIFont._expo_fontNames(forFamilyName: aliasedFamilyName)
|
|
15
|
+
}
|
|
16
|
+
return fontNames
|
|
17
|
+
}
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-font",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.1",
|
|
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": "0897aeadb926491a457bcd67d83360956994ee82"
|
|
46
46
|
}
|
package/src/Font.types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Asset } from 'expo-asset';
|
|
|
2
2
|
|
|
3
3
|
// @needsAudit
|
|
4
4
|
/**
|
|
5
|
-
* The different types of assets you can provide to the [`loadAsync()`](#
|
|
5
|
+
* The different types of assets you can provide to the [`loadAsync()`](#loadasyncfontfamilyorfontmap-source) function.
|
|
6
6
|
* A font source can be a URI, a module ID, or an Expo Asset.
|
|
7
7
|
*/
|
|
8
8
|
export type FontSource = string | number | Asset | FontResource;
|
|
@@ -10,7 +10,7 @@ export type FontSource = string | number | Asset | FontResource;
|
|
|
10
10
|
// @needsAudit
|
|
11
11
|
/**
|
|
12
12
|
* An object used to dictate the resource that is loaded into the provided font namespace when used
|
|
13
|
-
* with [`loadAsync`](#
|
|
13
|
+
* with [`loadAsync`](#loadasyncfontfamilyorfontmap-source).
|
|
14
14
|
*/
|
|
15
15
|
export type FontResource = {
|
|
16
16
|
uri?: string | number;
|
package/src/FontHooks.ts
CHANGED
|
@@ -38,7 +38,7 @@ function useStaticFonts(map: string | Record<string, FontSource>): [boolean, Err
|
|
|
38
38
|
* ```ts
|
|
39
39
|
* const [loaded, error] = useFonts({ ... });
|
|
40
40
|
* ```
|
|
41
|
-
* Load a map of fonts with [`loadAsync`](#
|
|
41
|
+
* Load a map of fonts with [`loadAsync`](#loadasyncfontfamilyorfontmap-source). This returns a `boolean` if the fonts are
|
|
42
42
|
* loaded and ready to use. It also returns an error if something went wrong, to use in development.
|
|
43
43
|
*
|
|
44
44
|
* > Note, the fonts are not "reloaded" when you dynamically change the font map.
|
package/src/FontLoader.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { Asset } from 'expo-asset';
|
|
2
2
|
import Constants from 'expo-constants';
|
|
3
|
-
import { CodedError } from 'expo-modules-core';
|
|
4
|
-
import { Platform } from 'react-native';
|
|
3
|
+
import { CodedError, Platform } from 'expo-modules-core';
|
|
5
4
|
|
|
6
5
|
import ExpoFontLoader from './ExpoFontLoader';
|
|
7
6
|
import { FontResource, FontSource } from './Font.types';
|
|
8
7
|
|
|
9
|
-
const
|
|
10
|
-
const isInIOSStandalone = Constants.appOwnership === 'standalone' && Platform.OS === 'ios';
|
|
8
|
+
const isInExpoGo = Constants.appOwnership === 'expo';
|
|
11
9
|
|
|
12
10
|
export function fontFamilyNeedsScoping(name: string): boolean {
|
|
13
11
|
return (
|
|
14
|
-
|
|
12
|
+
isInExpoGo &&
|
|
13
|
+
Platform.OS !== 'ios' &&
|
|
15
14
|
!Constants.systemFonts.includes(name) &&
|
|
16
15
|
name !== 'System' &&
|
|
17
16
|
!name.includes(Constants.sessionId)
|
package/ios/EXFont/EXFont.h
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <Foundation/Foundation.h>
|
|
4
|
-
#import <ExpoModulesCore/Platform.h>
|
|
5
|
-
|
|
6
|
-
static const char *EXFontAssocKey = "EXFont";
|
|
7
|
-
|
|
8
|
-
@interface EXFont : NSObject
|
|
9
|
-
|
|
10
|
-
- (instancetype)initWithCGFont:(CGFontRef)cgFont;
|
|
11
|
-
- (UIFont *)UIFontWithSize:(CGFloat)fsize;
|
|
12
|
-
|
|
13
|
-
@end
|
package/ios/EXFont/EXFont.m
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <EXFont/EXFont.h>
|
|
4
|
-
#import <objc/runtime.h>
|
|
5
|
-
#import <CoreText/CoreText.h>
|
|
6
|
-
|
|
7
|
-
@interface EXFont ()
|
|
8
|
-
|
|
9
|
-
@property (nonatomic, assign) CGFontRef cgFont;
|
|
10
|
-
@property (nonatomic, strong) NSMutableDictionary *sizes;
|
|
11
|
-
|
|
12
|
-
@end
|
|
13
|
-
|
|
14
|
-
@implementation EXFont
|
|
15
|
-
|
|
16
|
-
- (instancetype)initWithCGFont:(CGFontRef)cgFont
|
|
17
|
-
{
|
|
18
|
-
if (self = [super init]) {
|
|
19
|
-
_cgFont = cgFont;
|
|
20
|
-
_sizes = [NSMutableDictionary dictionary];
|
|
21
|
-
}
|
|
22
|
-
return self;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
- (UIFont *)UIFontWithSize:(CGFloat)fsize
|
|
26
|
-
{
|
|
27
|
-
NSNumber *size = @(fsize);
|
|
28
|
-
UIFont *uiFont = _sizes[size];
|
|
29
|
-
if (uiFont) {
|
|
30
|
-
return uiFont;
|
|
31
|
-
}
|
|
32
|
-
uiFont = (__bridge_transfer UIFont *)CTFontCreateWithGraphicsFont(_cgFont, fsize, NULL, NULL);
|
|
33
|
-
_sizes[size] = uiFont;
|
|
34
|
-
objc_setAssociatedObject(uiFont, EXFontAssocKey, self, OBJC_ASSOCIATION_ASSIGN);
|
|
35
|
-
return uiFont;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
- (void)dealloc
|
|
39
|
-
{
|
|
40
|
-
CGFontRelease(_cgFont);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@end
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <ExpoModulesCore/EXExportedModule.h>
|
|
4
|
-
#import <ExpoModulesCore/EXModuleRegistryConsumer.h>
|
|
5
|
-
|
|
6
|
-
@interface EXFontLoader : EXExportedModule <EXModuleRegistryConsumer>
|
|
7
|
-
|
|
8
|
-
- (instancetype)initWithFontFamilyPrefix:(NSString *)prefix;
|
|
9
|
-
|
|
10
|
-
@end
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <CoreText/CoreText.h>
|
|
4
|
-
#import <EXFont/EXFontLoader.h>
|
|
5
|
-
#import <EXFont/EXFontLoaderProcessor.h>
|
|
6
|
-
#import <ExpoModulesCore/EXFontManagerInterface.h>
|
|
7
|
-
#import <ExpoModulesCore/EXFontScalersManagerInterface.h>
|
|
8
|
-
#import <EXFont/EXFontScaler.h>
|
|
9
|
-
#import <EXFont/EXFont.h>
|
|
10
|
-
#import <objc/runtime.h>
|
|
11
|
-
#import <EXFont/EXFontManager.h>
|
|
12
|
-
#import <EXFont/EXFontScalersManager.h>
|
|
13
|
-
|
|
14
|
-
@interface EXFontLoader ()
|
|
15
|
-
|
|
16
|
-
@property (nonatomic, strong) EXFontScaler *scaler;
|
|
17
|
-
@property (nonatomic, strong) EXFontLoaderProcessor *processor;
|
|
18
|
-
@property (nonatomic, strong) EXFontManager *manager;
|
|
19
|
-
|
|
20
|
-
@end
|
|
21
|
-
|
|
22
|
-
@implementation EXFontLoader
|
|
23
|
-
|
|
24
|
-
EX_EXPORT_MODULE(ExpoFontLoader);
|
|
25
|
-
|
|
26
|
-
- (instancetype)init
|
|
27
|
-
{
|
|
28
|
-
if (self = [super init]) {
|
|
29
|
-
_scaler = [[EXFontScaler alloc] init];
|
|
30
|
-
_manager = [[EXFontManager alloc] init];
|
|
31
|
-
_processor = [[EXFontLoaderProcessor alloc] initWithManager:_manager];
|
|
32
|
-
}
|
|
33
|
-
return self;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
- (instancetype)initWithFontFamilyPrefix:(NSString *)prefix
|
|
37
|
-
{
|
|
38
|
-
if (self = [super init]) {
|
|
39
|
-
_scaler = [[EXFontScaler alloc] init];
|
|
40
|
-
_manager = [[EXFontManager alloc] init];
|
|
41
|
-
_processor = [[EXFontLoaderProcessor alloc] initWithFontFamilyPrefix:prefix manager:_manager];
|
|
42
|
-
}
|
|
43
|
-
return self;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry
|
|
48
|
-
{
|
|
49
|
-
if (moduleRegistry) {
|
|
50
|
-
id<EXFontManagerInterface> manager = [moduleRegistry getModuleImplementingProtocol:@protocol(EXFontManagerInterface)];
|
|
51
|
-
[manager addFontProcessor:_processor];
|
|
52
|
-
|
|
53
|
-
id<EXFontScalersManagerInterface> scalersManager = [moduleRegistry getSingletonModuleForName:@"FontScalersManager"];
|
|
54
|
-
[scalersManager registerFontScaler:_scaler];
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
- (NSDictionary *)constantsToExport
|
|
59
|
-
{
|
|
60
|
-
return @{
|
|
61
|
-
@"customNativeFonts": [self queryCustomNativeFonts],
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
EX_EXPORT_METHOD_AS(loadAsync,
|
|
66
|
-
loadAsyncWithFontFamilyName:(NSString *)fontFamilyName
|
|
67
|
-
withLocalUri:(NSString *)path
|
|
68
|
-
resolver:(EXPromiseResolveBlock)resolve
|
|
69
|
-
rejecter:(EXPromiseRejectBlock)reject)
|
|
70
|
-
{
|
|
71
|
-
if ([_manager fontForName:fontFamilyName]) {
|
|
72
|
-
reject(@"E_FONT_ALREADY_EXISTS",
|
|
73
|
-
[NSString stringWithFormat:@"Font with family name '%@' already loaded", fontFamilyName],
|
|
74
|
-
nil);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// TODO(nikki): make sure path is in experience's scope
|
|
79
|
-
NSURL *uriString = [[NSURL alloc] initWithString:path];
|
|
80
|
-
NSData *data = [[NSFileManager defaultManager] contentsAtPath:[uriString path]];
|
|
81
|
-
if (!data) {
|
|
82
|
-
reject(@"E_FONT_FILE_NOT_FOUND",
|
|
83
|
-
[NSString stringWithFormat:@"File '%@' for font '%@' doesn't exist", path, fontFamilyName],
|
|
84
|
-
nil);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
|
|
89
|
-
CGFontRef font = CGFontCreateWithDataProvider(provider);
|
|
90
|
-
CGDataProviderRelease(provider);
|
|
91
|
-
if (!font) {
|
|
92
|
-
reject(@"E_FONT_CREATION_FAILED",
|
|
93
|
-
[NSString stringWithFormat:@"Could not create font from loaded data for '%@'", fontFamilyName],
|
|
94
|
-
nil);
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
[_manager setFont:[[EXFont alloc] initWithCGFont:font] forName:fontFamilyName];
|
|
99
|
-
resolve(nil);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
#pragma mark - Internals
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Queries custom native font names from the Info.plist `UIAppFonts`.
|
|
106
|
-
*/
|
|
107
|
-
- (NSArray<NSString *> *)queryCustomNativeFonts {
|
|
108
|
-
#if TARGET_OS_IOS || TARGET_OS_TV
|
|
109
|
-
// [0] Read from main bundle's Info.plist
|
|
110
|
-
NSArray *fontFilePaths = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIAppFonts"];
|
|
111
|
-
NSMutableSet<NSString *> *fontFamilies = [[NSMutableSet alloc] init];
|
|
112
|
-
|
|
113
|
-
// [1] Get font family names for each font file
|
|
114
|
-
for (NSString *fontFilePath in fontFilePaths) {
|
|
115
|
-
NSURL *fontURL = [[NSBundle mainBundle] URLForResource:fontFilePath withExtension:nil];
|
|
116
|
-
if (fontURL) {
|
|
117
|
-
CFArrayRef fontDescriptors = CTFontManagerCreateFontDescriptorsFromURL((__bridge CFURLRef)fontURL);
|
|
118
|
-
if (fontDescriptors) {
|
|
119
|
-
CFIndex count = CFArrayGetCount(fontDescriptors);
|
|
120
|
-
for (CFIndex i = 0; i < count; ++i) {
|
|
121
|
-
CTFontDescriptorRef descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fontDescriptors, i);
|
|
122
|
-
CFStringRef familyNameRef = (CFStringRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontFamilyNameAttribute);
|
|
123
|
-
if (familyNameRef) {
|
|
124
|
-
[fontFamilies addObject:(__bridge_transfer NSString *)familyNameRef];
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
CFRelease(fontDescriptors);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// [2] Retrieve font names by family names
|
|
133
|
-
NSMutableSet<NSString *> *fontNames = [[NSMutableSet alloc] init];
|
|
134
|
-
for (NSString *familyName in fontFamilies) {
|
|
135
|
-
for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
|
|
136
|
-
[fontNames addObject:fontName];
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// [3] Return as array
|
|
141
|
-
return [fontNames allObjects];
|
|
142
|
-
#elif TARGET_OS_OSX
|
|
143
|
-
// TODO: Add support for `ATSApplicationFontsPath` key in Info.plist
|
|
144
|
-
return @[];
|
|
145
|
-
#endif
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
@end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <Foundation/Foundation.h>
|
|
4
|
-
#import <ExpoModulesCore/EXFontProcessorInterface.h>
|
|
5
|
-
#import <EXFont/EXFontManager.h>
|
|
6
|
-
|
|
7
|
-
@interface EXFontLoaderProcessor : NSObject <EXFontProcessorInterface>
|
|
8
|
-
|
|
9
|
-
- (instancetype)initWithFontFamilyPrefix:(NSString *)prefix
|
|
10
|
-
manager:(EXFontManager *)manager;
|
|
11
|
-
|
|
12
|
-
- (instancetype)initWithManager:(EXFontManager *)manager;
|
|
13
|
-
|
|
14
|
-
@end
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <EXFont/EXFontLoaderProcessor.h>
|
|
4
|
-
#import <EXFont/EXFontLoader.h>
|
|
5
|
-
#import <EXFont/EXFont.h>
|
|
6
|
-
#import <EXFont/EXFontManager.h>
|
|
7
|
-
#import <objc/runtime.h>
|
|
8
|
-
|
|
9
|
-
@interface EXFontLoaderProcessor ()
|
|
10
|
-
|
|
11
|
-
@property (nonatomic, copy) NSString *fontFamilyPrefix;
|
|
12
|
-
@property (nonatomic, strong) EXFontManager *manager;
|
|
13
|
-
|
|
14
|
-
@end
|
|
15
|
-
|
|
16
|
-
@implementation EXFontLoaderProcessor
|
|
17
|
-
|
|
18
|
-
- (instancetype)initWithFontFamilyPrefix:(NSString *)prefix
|
|
19
|
-
manager:(EXFontManager *)manager
|
|
20
|
-
{
|
|
21
|
-
if (self = [super init]) {
|
|
22
|
-
_fontFamilyPrefix = prefix;
|
|
23
|
-
_manager = manager;
|
|
24
|
-
}
|
|
25
|
-
return self;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
- (instancetype)initWithManager:(EXFontManager *)manager
|
|
29
|
-
{
|
|
30
|
-
return [self initWithFontFamilyPrefix:nil manager:manager];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
- (UIFont *)updateFont:(UIFont *)uiFont
|
|
34
|
-
withFamily:(NSString *)family
|
|
35
|
-
size:(NSNumber *)size
|
|
36
|
-
weight:(NSString *)weight
|
|
37
|
-
style:(NSString *)style
|
|
38
|
-
variant:(NSArray<NSDictionary *> *)variant
|
|
39
|
-
scaleMultiplier:(CGFloat)scaleMultiplier
|
|
40
|
-
{
|
|
41
|
-
const CGFloat defaultFontSize = 14;
|
|
42
|
-
EXFont *exFont = nil;
|
|
43
|
-
|
|
44
|
-
// Did we get a new family, and if so, is it associated with an EXFont?
|
|
45
|
-
if (_fontFamilyPrefix && [family hasPrefix:_fontFamilyPrefix]) {
|
|
46
|
-
NSString *suffix = [family substringFromIndex:_fontFamilyPrefix.length];
|
|
47
|
-
exFont = [_manager fontForName:suffix];
|
|
48
|
-
} else if (!_fontFamilyPrefix) {
|
|
49
|
-
exFont = [_manager fontForName:family];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Did the passed-in UIFont come from an EXFont?
|
|
53
|
-
if (!exFont && uiFont) {
|
|
54
|
-
exFont = objc_getAssociatedObject(uiFont, EXFontAssocKey);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// If it's an EXFont, generate the corresponding UIFont, else fallback to React Native's built-in method
|
|
58
|
-
if (exFont) {
|
|
59
|
-
CGFloat computedSize = [size doubleValue] ?: uiFont.pointSize ?: defaultFontSize;
|
|
60
|
-
if (scaleMultiplier > 0.0 && scaleMultiplier != 1.0) {
|
|
61
|
-
computedSize = round(computedSize * scaleMultiplier);
|
|
62
|
-
}
|
|
63
|
-
return [exFont UIFontWithSize:computedSize];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return nil;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
@end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <Foundation/Foundation.h>
|
|
4
|
-
#import <EXFont/EXFont.h>
|
|
5
|
-
|
|
6
|
-
@interface EXFontManager : NSObject
|
|
7
|
-
|
|
8
|
-
- (instancetype)init;
|
|
9
|
-
- (EXFont *)fontForName:(NSString *)name;
|
|
10
|
-
- (void)setFont:(EXFont *)font forName:(NSString *)name;
|
|
11
|
-
|
|
12
|
-
@end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <EXFont/EXFontManager.h>
|
|
4
|
-
|
|
5
|
-
@interface EXFontManager ()
|
|
6
|
-
|
|
7
|
-
@property (nonatomic, strong, readonly) NSMutableDictionary *registry;
|
|
8
|
-
|
|
9
|
-
@end
|
|
10
|
-
|
|
11
|
-
@implementation EXFontManager
|
|
12
|
-
|
|
13
|
-
- (instancetype)init
|
|
14
|
-
{
|
|
15
|
-
if (self = [super init]) {
|
|
16
|
-
_registry = [NSMutableDictionary dictionary];
|
|
17
|
-
}
|
|
18
|
-
return self;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
- (EXFont *)fontForName:(NSString *)name
|
|
22
|
-
{
|
|
23
|
-
return _registry[name];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
- (void)setFont:(EXFont *)font forName:(NSString *)name
|
|
27
|
-
{
|
|
28
|
-
_registry[name] = font;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <EXFont/EXFontScaler.h>
|
|
4
|
-
|
|
5
|
-
#import <EXFont/EXFont.h>
|
|
6
|
-
#import <objc/runtime.h>
|
|
7
|
-
|
|
8
|
-
@implementation EXFontScaler
|
|
9
|
-
|
|
10
|
-
- (UIFont *)scaledFont:(UIFont *)font toSize:(CGFloat)fontSize
|
|
11
|
-
{
|
|
12
|
-
EXFont *exFont = objc_getAssociatedObject(font, EXFontAssocKey);
|
|
13
|
-
return [exFont UIFontWithSize:fontSize];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@end
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <ExpoModulesCore/EXSingletonModule.h>
|
|
4
|
-
#import <ExpoModulesCore/EXFontScalersManagerInterface.h>
|
|
5
|
-
|
|
6
|
-
@interface EXFontScalersManager : EXSingletonModule <EXFontScalersManagerInterface>
|
|
7
|
-
|
|
8
|
-
@end
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <EXFont/EXFontScalersManager.h>
|
|
4
|
-
|
|
5
|
-
#import <ExpoModulesCore/EXDefines.h>
|
|
6
|
-
#import <EXFont/EXFont.h>
|
|
7
|
-
|
|
8
|
-
#import <objc/runtime.h>
|
|
9
|
-
|
|
10
|
-
static NSPointerArray *currentFontScalers;
|
|
11
|
-
|
|
12
|
-
@implementation UIFont (EXFontLoader)
|
|
13
|
-
|
|
14
|
-
- (UIFont *)EXFontWithSize:(CGFloat)fontSize
|
|
15
|
-
{
|
|
16
|
-
for (id<EXFontScalerInterface> fontScaler in currentFontScalers) {
|
|
17
|
-
UIFont *scaledFont = [fontScaler scaledFont:self toSize:fontSize];
|
|
18
|
-
if (scaledFont) {
|
|
19
|
-
return scaledFont;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return [self EXFontWithSize:fontSize];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@end
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* A singleton module responsible for overriding UIFont's
|
|
30
|
-
* fontWithSize: method which is used for scaling fonts.
|
|
31
|
-
* We need this one, central place to store the scalers
|
|
32
|
-
* as for now to get rid of timing problems when backgrounding/
|
|
33
|
-
* foregrounding apps.
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
@implementation EXFontScalersManager
|
|
37
|
-
|
|
38
|
-
EX_REGISTER_SINGLETON_MODULE(FontScalersManager);
|
|
39
|
-
|
|
40
|
-
+ (void)initialize
|
|
41
|
-
{
|
|
42
|
-
static dispatch_once_t initializeCurrentFontScalersOnce;
|
|
43
|
-
dispatch_once(&initializeCurrentFontScalersOnce, ^{
|
|
44
|
-
currentFontScalers = [NSPointerArray weakObjectsPointerArray];
|
|
45
|
-
|
|
46
|
-
Class uiFont = [UIFont class];
|
|
47
|
-
SEL uiUpdate = @selector(fontWithSize:);
|
|
48
|
-
SEL exUpdate = @selector(EXFontWithSize:);
|
|
49
|
-
|
|
50
|
-
method_exchangeImplementations(class_getInstanceMethod(uiFont, uiUpdate),
|
|
51
|
-
class_getInstanceMethod(uiFont, exUpdate));
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
- (void)registerFontScaler:(id<EXFontScalerInterface>)fontScaler
|
|
56
|
-
{
|
|
57
|
-
[currentFontScalers compact];
|
|
58
|
-
[currentFontScalers addPointer:(__bridge void * _Nullable)(fontScaler)];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
@end
|