-
Notifications
You must be signed in to change notification settings - Fork 10.7k
/
font-families-loader.tsx
97 lines (86 loc) · 2.4 KB
/
font-families-loader.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* External dependencies
*/
import { useEffect } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
// @ts-expect-error No types for this exist yet.
// eslint-disable-next-line @woocommerce/dependency-group
import { store as coreStore } from '@wordpress/core-data';
/**
* Internal dependencies
*/
import { FontFamily } from '~/customize-store/types/font';
type Props = {
fontFamilies: Array< FontFamily >;
iframeInstance: HTMLObjectElement | null;
onLoad?: () => void;
preload?: boolean;
};
const isUrlEncoded = ( url: string ) => {
if ( typeof url !== 'string' ) {
return false;
}
return url !== decodeURIComponent( url );
};
const getDisplaySrcFromFontFace = ( input: string, urlPrefix: string ) => {
if ( ! input ) {
return;
}
// If it is a theme font, we need to make the url absolute
if ( input.startsWith( 'file:.' ) && urlPrefix ) {
const absoluteUrl = input.replace( 'file:.', urlPrefix );
return ! isUrlEncoded( absoluteUrl )
? encodeURI( absoluteUrl )
: absoluteUrl;
}
return ! isUrlEncoded( input ) ? encodeURI( input ) : input;
};
export const FontFamiliesLoader = ( {
fontFamilies,
iframeInstance,
onLoad,
}: Props ) => {
const { site, currentTheme } = useSelect( ( select ) => {
return {
// @ts-expect-error No types for this exist yet.
site: select( coreStore ).getSite(),
// @ts-expect-error No types for this exist yet.
currentTheme: select( coreStore ).getCurrentTheme(),
};
} );
useEffect( () => {
if ( ! Array.isArray( fontFamilies ) || ! site ) {
return;
}
const themeUrl =
site?.url + '/wp-content/themes/' + currentTheme?.stylesheet;
fontFamilies.forEach( async ( fontFamily ) => {
fontFamily.fontFace?.forEach( async ( fontFace ) => {
const src = Array.isArray( fontFace.src )
? fontFace.src[ 0 ]
: fontFace.src;
const srcFont = getDisplaySrcFromFontFace( src, themeUrl );
const dataSource = `url(${ srcFont })`;
const newFont = new FontFace( fontFace.fontFamily, dataSource, {
style: fontFace.fontStyle,
weight: fontFace.fontWeight,
} );
const loadedFace = await newFont.load();
document.fonts.add( loadedFace );
if ( iframeInstance ) {
iframeInstance.contentDocument?.fonts.add( loadedFace );
}
if ( onLoad ) {
onLoad();
}
} );
} );
}, [
currentTheme?.stylesheet,
fontFamilies,
iframeInstance,
onLoad,
site,
] );
return <></>;
};