File size: 4,720 Bytes
8fd7a1d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
 * Google Fonts integration utility
 */

const GOOGLE_FONTS_API_KEY = process.env.GOOGLE_FONTS_API_KEY || 'demo'; // Can be set via environment
const GOOGLE_FONTS_API_URL = 'https://www.googleapis.com/webfonts/v1/webfonts';

// Popular Google Fonts list for quick selection
const POPULAR_GOOGLE_FONTS = [
    'Open Sans',
    'Roboto',
    'Lato',
    'Montserrat',
    'Source Sans Pro',
    'Roboto Condensed',
    'Oswald',
    'Raleway',
    'Nunito',
    'Ubuntu',
    'Playfair Display',
    'Merriweather',
    'PT Sans',
    'Poppins',
    'Fira Sans',
    'Work Sans',
    'Roboto Slab',
    'Crimson Text',
    'Droid Sans',
    'Libre Baskerville'
];

let fontsCache = null;
let loadingPromise = null;

/**
 * Load a Google Font by adding a link tag to the document head
 * @param {string} fontFamily - The font family name
 * @param {string[]} weights - Array of font weights (e.g., ['400', '700'])
 * @returns {Promise<void>}
 */
const loadGoogleFont = (fontFamily, weights = ['400']) => {
    return new Promise((resolve, reject) => {
        const fontName = fontFamily.replace(/\s+/g, '+');
        const weightStr = weights.join(',');
        const url = `https://fonts.googleapis.com/css2?family=${fontName}:wght@${weightStr}&display=swap`;
        
        // Check if already loaded
        const existingLink = document.querySelector(`link[href*="${fontName}"]`);
        if (existingLink) {
            resolve();
            return;
        }

        const link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = url;
        
        link.onload = () => resolve();
        link.onerror = () => reject(new Error(`Failed to load font: ${fontFamily}`));
        
        document.head.appendChild(link);
    });
};

/**
 * Get list of available Google Fonts
 * @returns {Promise<Array>} Array of font objects with family, category, variants
 */
const getGoogleFontsList = async () => {
    if (fontsCache) {
        return fontsCache;
    }

    if (loadingPromise) {
        return loadingPromise;
    }

    loadingPromise = (async () => {
        try {
            // For demo purposes, return popular fonts if no API key
            if (GOOGLE_FONTS_API_KEY === 'demo') {
                fontsCache = POPULAR_GOOGLE_FONTS.map(family => ({
                    family,
                    category: 'sans-serif',
                    variants: ['regular', '700']
                }));
                return fontsCache;
            }

            const response = await fetch(`${GOOGLE_FONTS_API_URL}?key=${GOOGLE_FONTS_API_KEY}&sort=popularity`);
            
            if (!response.ok) {
                throw new Error(`Google Fonts API error: ${response.status}`);
            }

            const data = await response.json();
            fontsCache = data.items || [];
            return fontsCache;
        } catch (error) {
            console.warn('Failed to load Google Fonts list, using popular fonts:', error);
            // Fallback to popular fonts
            fontsCache = POPULAR_GOOGLE_FONTS.map(family => ({
                family,
                category: 'sans-serif',
                variants: ['regular', '700']
            }));
            return fontsCache;
        }
    })();

    return loadingPromise;
};

/**
 * Search Google Fonts by name
 * @param {string} query - Search query
 * @returns {Promise<Array>} Filtered array of font objects
 */
const searchGoogleFonts = async (query) => {
    const fonts = await getGoogleFontsList();
    const lowercaseQuery = query.toLowerCase();
    
    return fonts.filter(font => 
        font.family.toLowerCase().includes(lowercaseQuery)
    ).slice(0, 10); // Limit results
};

/**
 * Check if a font is a Google Font
 * @param {string} fontFamily - Font family name
 * @returns {Promise<boolean>}
 */
const isGoogleFont = async (fontFamily) => {
    const fonts = await getGoogleFontsList();
    return fonts.some(font => font.family.toLowerCase() === fontFamily.toLowerCase());
};

/**
 * Get popular Google Fonts for quick selection
 * @returns {Array<string>} Array of popular font family names
 */
const getPopularGoogleFonts = () => {
    return [...POPULAR_GOOGLE_FONTS];
};

/**
 * Remove a Google Font from the document
 * @param {string} fontFamily - The font family name to remove
 */
const removeGoogleFont = (fontFamily) => {
    const fontName = fontFamily.replace(/\s+/g, '+');
    const existingLink = document.querySelector(`link[href*="${fontName}"]`);
    if (existingLink) {
        existingLink.remove();
    }
};

export {
    loadGoogleFont,
    getGoogleFontsList,
    searchGoogleFonts,
    isGoogleFont,
    getPopularGoogleFonts,
    removeGoogleFont
};