cf-elements 1.0.2 → 1.0.3

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.
Files changed (2) hide show
  1. package/cf-elements.js +114 -0
  2. package/package.json +1 -1
package/cf-elements.js CHANGED
@@ -99,6 +99,116 @@
99
99
  }
100
100
  })();
101
101
 
102
+ // ==========================================================================
103
+ // GOOGLE FONTS - Auto-load fonts from font attributes
104
+ // ==========================================================================
105
+
106
+ // System fonts that don't need to be loaded from Google
107
+ const SYSTEM_FONTS = new Set([
108
+ 'sans-serif', 'serif', 'monospace', 'cursive', 'fantasy', 'system-ui',
109
+ 'ui-sans-serif', 'ui-serif', 'ui-monospace', 'ui-rounded',
110
+ 'arial', 'helvetica', 'times new roman', 'times', 'courier new', 'courier',
111
+ 'verdana', 'georgia', 'palatino', 'garamond', 'bookman', 'tahoma',
112
+ 'trebuchet ms', 'arial black', 'impact', 'comic sans ms', 'inherit'
113
+ ]);
114
+
115
+ // Track which fonts have been loaded to avoid duplicates
116
+ const loadedFonts = new Set();
117
+
118
+ /**
119
+ * Extract Google Font names from the document
120
+ * Scans font attributes on cf-* elements and styleguide data
121
+ */
122
+ function extractFontsFromDocument() {
123
+ const fonts = new Set();
124
+
125
+ // 1. Extract from font attributes on elements
126
+ document.querySelectorAll('[font]').forEach(el => {
127
+ const font = el.getAttribute('font');
128
+ if (font) {
129
+ // Clean and add font name
130
+ const cleanFont = font.replace(/["']/g, '').split(',')[0].trim();
131
+ if (cleanFont && !SYSTEM_FONTS.has(cleanFont.toLowerCase())) {
132
+ fonts.add(cleanFont);
133
+ }
134
+ }
135
+ });
136
+
137
+ // 2. Extract from styleguide data if present
138
+ const styleguideEl = document.getElementById('cf-styleguide-data');
139
+ if (styleguideEl) {
140
+ try {
141
+ const data = JSON.parse(styleguideEl.textContent);
142
+ if (data.typography) {
143
+ const { headlineFont, subheadlineFont, contentFont } = data.typography;
144
+ [headlineFont, subheadlineFont, contentFont].forEach(font => {
145
+ if (font && !SYSTEM_FONTS.has(font.toLowerCase())) {
146
+ fonts.add(font);
147
+ }
148
+ });
149
+ }
150
+ } catch (e) {
151
+ // Ignore parse errors
152
+ }
153
+ }
154
+
155
+ // 3. Extract from inline font-family styles in cf-* elements
156
+ document.querySelectorAll('cf-headline, cf-subheadline, cf-paragraph, cf-button').forEach(el => {
157
+ const style = el.getAttribute('style') || '';
158
+ const match = style.match(/font-family:\s*["']?([^"';,]+)/i);
159
+ if (match) {
160
+ const font = match[1].trim();
161
+ if (font && !SYSTEM_FONTS.has(font.toLowerCase())) {
162
+ fonts.add(font);
163
+ }
164
+ }
165
+ });
166
+
167
+ return fonts;
168
+ }
169
+
170
+ /**
171
+ * Inject Google Fonts stylesheet into document head
172
+ */
173
+ function injectGoogleFonts(fonts) {
174
+ if (!fonts || fonts.size === 0) return;
175
+
176
+ // Filter out already loaded fonts
177
+ const newFonts = Array.from(fonts).filter(f => !loadedFonts.has(f));
178
+ if (newFonts.length === 0) return;
179
+
180
+ // Mark as loaded
181
+ newFonts.forEach(f => loadedFonts.add(f));
182
+
183
+ // Build Google Fonts URL
184
+ const fontParams = newFonts
185
+ .map(font => font.replace(/ /g, '+'))
186
+ .join('&family=');
187
+
188
+ const url = `https://fonts.googleapis.com/css2?family=${fontParams}:wght@300;400;500;600;700;800;900&display=swap`;
189
+
190
+ // Check if already loaded
191
+ if (document.querySelector(`link[href^="https://fonts.googleapis.com"][href*="${newFonts[0].replace(/ /g, '+')}"]`)) {
192
+ return;
193
+ }
194
+
195
+ // Inject link tag
196
+ const link = document.createElement('link');
197
+ link.id = 'cf-google-fonts';
198
+ link.rel = 'stylesheet';
199
+ link.href = url;
200
+ document.head.appendChild(link);
201
+ }
202
+
203
+ /**
204
+ * Auto-load Google Fonts from document
205
+ * Called before element rendering
206
+ */
207
+ function loadGoogleFonts() {
208
+ const fonts = extractFontsFromDocument();
209
+ injectGoogleFonts(fonts);
210
+ }
211
+
102
212
  // ==========================================================================
103
213
  // CONSTANTS & MAPPINGS
104
214
  // ==========================================================================
@@ -4588,6 +4698,7 @@
4588
4698
  // Auto-initialize when DOM is ready
4589
4699
  if (document.readyState === "loading") {
4590
4700
  document.addEventListener("DOMContentLoaded", () => {
4701
+ loadGoogleFonts(); // Load fonts before rendering
4591
4702
  styleguideManager.init();
4592
4703
  brandAssetsManager.init();
4593
4704
  initFunnelWind();
@@ -4600,6 +4711,7 @@
4600
4711
  } else {
4601
4712
  // DOM already ready, use requestAnimationFrame to ensure all elements are parsed
4602
4713
  requestAnimationFrame(() => {
4714
+ loadGoogleFonts(); // Load fonts before rendering
4603
4715
  styleguideManager.init();
4604
4716
  brandAssetsManager.init();
4605
4717
  initFunnelWind();
@@ -4616,12 +4728,14 @@
4616
4728
  init: initFunnelWind,
4617
4729
  initAnimations: initAnimations,
4618
4730
  loadAnimateCSS: loadAnimateCSS,
4731
+ loadGoogleFonts: loadGoogleFonts,
4619
4732
  initVideoBackgrounds: initVideoBackgrounds,
4620
4733
  elements: elements,
4621
4734
  StyleguideManager: styleguideManager,
4622
4735
  BrandAssetsManager: brandAssetsManager,
4623
4736
  initStyleguide: (data) => {
4624
4737
  styleguideManager.init(data);
4738
+ loadGoogleFonts(); // Load fonts from styleguide
4625
4739
  initFunnelWind();
4626
4740
  },
4627
4741
  initBrandAssets: (data) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cf-elements",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Zero-dependency markup library that generates ClickFunnels compatible HTML with inline styles",
5
5
  "main": "cf-elements.js",
6
6
  "browser": "cf-elements.js",