@claspo/document-connector 16.7.5-scroll-fix1 → 16.7.6-ctx.2

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.
@@ -1 +1 @@
1
- class GlobalScrollBlocker{static block(){this.activeBlockersCount++;const l=document.documentElement;if(this.activeBlockersCount>1||l.scrollHeight<=l.clientHeight)return;const o=window.scrollY,t=window.scrollX,e=l.style;this.savedParams={scrollTopPosition:o,scrollLeftPosition:t,htmlElemTop:e.top||"",htmlElemLeft:e.left||"",htmlElemPosition:e.position||"",htmlElemWidth:e.width||"",htmlElemHeight:e.height||"",htmlElemOverflowY:e.overflowY||""},e.top=-o+"px",e.left=-t+"px",e.position="fixed",e.width="100%",e.height="auto",e.overflowY="scroll",l.classList.add(GlobalScrollBlocker.globalScrollBlockClass)}static restore(){if(0===this.activeBlockersCount)return;if(this.activeBlockersCount--,this.activeBlockersCount>0||!this.savedParams)return;const l=this.savedParams;this.savedParams=null;const o=document.documentElement,t=document.body,e=o.style,s=t.style,c=e.scrollBehavior||"",r=s.scrollBehavior||"";e.top=l.htmlElemTop,e.left=l.htmlElemLeft,e.position=l.htmlElemPosition,e.width=l.htmlElemWidth,e.height=l.htmlElemHeight,e.overflowY=l.htmlElemOverflowY,o.classList.remove(GlobalScrollBlocker.globalScrollBlockClass),e.scrollBehavior=s.scrollBehavior="auto",window.scroll(l.scrollLeftPosition,l.scrollTopPosition),e.scrollBehavior=c,s.scrollBehavior=r}}GlobalScrollBlocker.globalScrollBlockClass="cl-global-scroll-block",GlobalScrollBlocker.activeBlockersCount=0,GlobalScrollBlocker.savedParams=null;export default GlobalScrollBlocker;
1
+ class GlobalScrollBlocker{static block(){this.activeBlockersCount++;const l=document.documentElement;if(this.activeBlockersCount>1||l.scrollHeight<=l.clientHeight)return;const o=window.scrollY,t=window.scrollX,e=l.style;this.savedParams={scrollTopPosition:o,scrollLeftPosition:t,htmlElemTop:e.top||"",htmlElemLeft:e.left||"",htmlElemPosition:e.position||"",htmlElemWidth:e.width||"",htmlElemOverflowY:e.overflowY||""},e.top=-o+"px",e.left=-t+"px",e.position="fixed",e.width="100%",e.overflowY="scroll",l.classList.add(GlobalScrollBlocker.globalScrollBlockClass)}static restore(){if(0===this.activeBlockersCount)return;if(this.activeBlockersCount--,this.activeBlockersCount>0||!this.savedParams)return;const l=this.savedParams;this.savedParams=null;const o=document.documentElement,t=document.body,e=o.style,s=t.style,c=e.scrollBehavior||"",r=s.scrollBehavior||"";e.top=l.htmlElemTop,e.left=l.htmlElemLeft,e.position=l.htmlElemPosition,e.width=l.htmlElemWidth,e.overflowY=l.htmlElemOverflowY,o.classList.remove(GlobalScrollBlocker.globalScrollBlockClass),e.scrollBehavior=s.scrollBehavior="auto",window.scroll(l.scrollLeftPosition,l.scrollTopPosition),e.scrollBehavior=c,s.scrollBehavior=r}}GlobalScrollBlocker.globalScrollBlockClass="cl-global-scroll-block",GlobalScrollBlocker.activeBlockersCount=0,GlobalScrollBlocker.savedParams=null;export default GlobalScrollBlocker;
@@ -1,49 +1,11 @@
1
+ import { GoogleFontInput, GoogleFontsLoaderOptionsI, ResolvedGoogleFontRequestI } from './google-fonts/GoogleFonts.types';
1
2
  export default class GoogleFontsLoader {
2
- static getUsedGoogleFonts(documentModel: any): any;
3
- static _getEnabledStyleEntries(node: any): any[];
4
- static _normalizeFontWeight(fontWeight: any): number;
5
- static _normalizeFontFamilyName(fontFamily: any): string;
6
- loadedGoogleFonts: any[];
3
+ static getUsedGoogleFonts(documentModel: any): ResolvedGoogleFontRequestI[];
7
4
  widgetId?: number;
8
5
  siteId?: string;
9
- testStrings: {
10
- latin: string;
11
- cyrillic: string;
12
- };
13
- constructor(options: any);
14
- load(fonts: any, htmlDocumentObject: any): Promise<void>;
6
+ ownerId: string;
7
+ htmlDocumentObject?: Document;
8
+ constructor(options?: GoogleFontsLoaderOptionsI);
9
+ load(fonts: GoogleFontInput[], htmlDocumentObject?: Document): Promise<void>;
15
10
  cleanup(): void;
16
- _combineUrlDynamicPart(fonts: any): any[];
17
- _makeFontOptions(): any[];
18
- _loadResolvedFontVariations(fonts: any, htmlDocumentObject: any): Promise<any[]>;
19
- _fetchFontsMetadata(fontUrlParts: any): Promise<string>;
20
- _makeGoogleFontsUrl(fontUrlParts: any): string;
21
- _addFontsLinkToDocument(fontUrlParts: any, htmlDocumentObject: any): Promise<void> | Promise<PromiseSettledResult<unknown>[]>;
22
- _addFontsStyleToDocument(fontFaceCss: any, htmlDocumentObject: any): void;
23
- _parseFontFaces(cssText: any): any[];
24
- _getFontFaceProperty(css: any, property: any): any;
25
- _parseFontFaceWeight(fontWeight: any): {
26
- minWeight: number;
27
- maxWeight: number;
28
- };
29
- _resolveFontVariations(fonts: any, fontFaces: any): any[];
30
- _findNearestFontFaces(fontFaces: any, family: any, style: any, weight: any): any;
31
- _warnAboutUnresolvedReturnedFontFamilies(fonts: any, fontFaces: any, variations: any): void;
32
- _warnAboutItalicOnlyReturnedFontFamilies(fonts: any, fontFaces: any): void;
33
- _getFontFaceDistance(fontFace: any, weight: any): number;
34
- _resolveWeightForFontFace(fontFace: any, weight: any): any;
35
- _getFontFaceCss(variations: any): string;
36
- _dedupeFontVariations(variations: any): any[];
37
- _getVariationResourceKey(variation: any): any;
38
- _getFontFaceMergeKey(fontFace: any): string;
39
- _removeFontFaceWeight(css: any): string;
40
- _replaceFontFaceWeight(css: any, minWeight: any, maxWeight: any): string;
41
- _generateFontVariations(fonts: any): any[];
42
- _getFontFamily(font: any): any;
43
- _getRequestedWeights(font: any): number[];
44
- _encodeFontFamily(fontFamily: any): string;
45
- _createFontTester(variations: any, htmlDocumentObject: any): any;
46
- _waitForAllFontsToLoad(variations: any, htmlDocumentObject: any): Promise<void>;
47
- _waitForFontBatchLoad(batch: any, htmlDocumentObject: any): Promise<any[]>;
48
- _logError(message: any): void;
49
11
  }
@@ -1 +1 @@
1
- import DocumentUtils from"@claspo/common/document/DocumentUtils";import ErrorLogger from"@claspo/renderer/error/ErrorLogger";export default class GoogleFontsLoader{static getUsedGoogleFonts(t){const e=t.shared.googleFonts;if(!e||0===e.length)return[];const o=new Map,n=new Set,s=(t,e=400)=>{t&&(o.has(t)||o.set(t,new Set),o.get(t).add(GoogleFontsLoader._normalizeFontWeight(e)))};for(const e of t.views||[])DocumentUtils.iterateDepthFirst(e,t=>{const e=GoogleFontsLoader._getEnabledStyleEntries(t);for(const t of e)if(t.classes)for(const e of t.classes.split(" "))e&&e.startsWith("cl-")&&n.add(e);for(const t of e)t.styleAttributes&&t.styleAttributes.fontFamily&&s(t.styleAttributes.fontFamily,t.styleAttributes.fontWeight)});const a=t.shared;for(const t of n){const e=a.textClasses&&a.textClasses[t];e&&(e.styleAttributes&&e.styleAttributes.fontFamily?s(e.styleAttributes.fontFamily,e.styleAttributes.fontWeight):(e.isHeader&&a.headerFontFamily&&s(a.headerFontFamily,e.styleAttributes&&e.styleAttributes.fontWeight),!e.isHeader&&a.textFontFamily&&s(a.textFontFamily,e.styleAttributes&&e.styleAttributes.fontWeight)))}return a.textFontFamily&&s(a.textFontFamily),e.filter(t=>o.has(t)).map(t=>({fontFamily:t,weights:Array.from(o.get(t)).sort((t,e)=>t-e)}))}static _getEnabledStyleEntries(t){const e=[];t.props&&t.props.adaptiveStyles&&(e.push(...t.props.adaptiveStyles.desktop||[]),e.push(...t.props.adaptiveStyles.mobile||[])),t.props&&t.props.styles&&e.push(...t.props.styles||[]);const o=new Set(e.filter(t=>t.params&&!1===t.params.enabled).map(t=>t.element));return e.filter(t=>!o.has(t.element))}static _normalizeFontWeight(t){if("normal"===t)return 400;if("bold"===t)return 700;const e=parseInt(t,10);return Number.isFinite(e)&&e>0?e:400}static _normalizeFontFamilyName(t){return`${t||""}`.trim().replace(/\s+/g," ").toLowerCase()}constructor(t){this.loadedGoogleFonts=[],this.testStrings={latin:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",cyrillic:"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя"},t=t||{},this.widgetId=t.widgetId,this.siteId=t.siteId}async load(t,e){try{if(e=e||document,!(t||[]).length)return;const o=await this._loadResolvedFontVariations(t,e);if(!o.length)return;const n=this._createFontTester(o,e);e.body.appendChild(n);const s=this._waitForAllFontsToLoad(o,e),a=new Promise((t,e)=>setTimeout(()=>e(new Error("Timeout")),2e3));await Promise.race([s,a]),n.remove()}catch(t){this._logError(`Error while loading fonts ${t}`)}}cleanup(){this.loadedGoogleFonts.forEach(t=>t.remove()),this.loadedGoogleFonts=[]}_combineUrlDynamicPart(t){const e=[],o=this._makeFontOptions(),n=[{name:"normal",value:0},{name:"italic",value:1}];return t.forEach(t=>{const s=this._getFontFamily(t),a=this._getRequestedWeights(t);if(!s||!a.length)return;const r=[];n.forEach(t=>{o.forEach(e=>{r.push(`${t.value},${e}`)})});const i=r.join(";");e.push({fontFamily:s,weights:a,urlPart:`&family=${this._encodeFontFamily(s)}:ital,wght@${i}`})}),e}_makeFontOptions(){const t=[];for(let e=0;e<9;e++){const o=100*(e+1);t.push(o)}return t}async _loadResolvedFontVariations(t,e){const o=this._combineUrlDynamicPart(t);if(!o||0===o.length)return[];try{const n=await this._fetchFontsMetadata(o),s=this._parseFontFaces(n);if(!s.length)throw new Error("Google Fonts metadata did not contain font-face rules");const a=this._resolveFontVariations(t,s);this._warnAboutUnresolvedReturnedFontFamilies(t,s,a),this._warnAboutItalicOnlyReturnedFontFamilies(t,s);const r=this._getFontFaceCss(a);if(!r)throw new Error("Google Fonts metadata did not contain matching font faces");return this._addFontsStyleToDocument(r,e),this._dedupeFontVariations(a)}catch(n){return this._logError(`Failed to load optimized Google Fonts CSS. Falling back to stylesheet link. ${n}`),await this._addFontsLinkToDocument(o,e),this._generateFontVariations(t)}}async _fetchFontsMetadata(t){const e=this._makeGoogleFontsUrl(t),o=await fetch(e);if(!o.ok)throw new Error(`Google Fonts metadata request failed, url: ${e}, status: ${o.status}`);return o.text()}_makeGoogleFontsUrl(t){return"https://fonts.googleapis.com/css2?display=swap"+t.map(({urlPart:t})=>t).join("")}_addFontsLinkToDocument(t,e){if(!e.head)return Promise.resolve();const o=[{fontFamily:t.map(({fontFamily:t})=>t).join(", "),urlPart:t.map(({urlPart:t})=>t).join("")}].map(({fontFamily:t,urlPart:o})=>new Promise((n,s)=>{const a=e.createElement("link");a.rel="stylesheet",a.href="https://fonts.googleapis.com/css2?display=swap"+o,a.onload=()=>n({fontFamily:t,success:!0}),a.onerror=()=>{this._logError(`Failed to load font: ${t}`),s(new Error(`Failed to load font: ${t}`))},e.head.appendChild(a),this.loadedGoogleFonts.push(a)}));return Promise.allSettled(o)}_addFontsStyleToDocument(t,e){if(!e.head)return;const o=e.createElement("style");o.setAttribute("data-cl-google-fonts","true"),o.textContent=t,e.head.appendChild(o),this.loadedGoogleFonts.push(o)}_parseFontFaces(t){const e=[],o=/@font-face\s*{[^}]*}/gi;let n;for(;null!==(n=o.exec(t||""));){const t=n[0],o=this._getFontFaceProperty(t,"font-family"),s=this._getFontFaceProperty(t,"font-style")||"normal",a=this._parseFontFaceWeight(this._getFontFaceProperty(t,"font-weight"));o&&a?e.push({family:o,style:s,minWeight:a.minWeight,maxWeight:a.maxWeight,src:this._getFontFaceProperty(t,"src"),unicodeRange:this._getFontFaceProperty(t,"unicode-range"),css:t}):this._logError("Failed to parse font-face")}return e}_getFontFaceProperty(t,e){const o=new RegExp(`${e}\\s*:\\s*([^;]+);`,"i"),n=t.match(o);return n?n[1].trim().replace(/^['"]|['"]$/g,""):""}_parseFontFaceWeight(t){const e=`${t||""}`.match(/\d+(\.\d+)?/g);if(!e||!e.length)return null;const o=Number(e[0]),n=Number(e[e.length-1]);return{minWeight:Math.min(o,n),maxWeight:Math.max(o,n)}}_resolveFontVariations(t,e){const o=["normal","italic"],n=[],s=new Set;return t.forEach(t=>{const a=this._getFontFamily(t);this._getRequestedWeights(t).forEach(t=>{o.forEach(o=>{const r=this._findNearestFontFaces(e,a,o,t);if(!r.length)return;const i=this._resolveWeightForFontFace(r[0],t),l=`${a}|${o}|${i}`;s.has(l)||(s.add(l),n.push({family:a,weight:i,style:o,descriptor:`${o} ${i} 1em "${a}"`,cssBlocks:r.map(t=>t.css),fontFaces:r}))})})}),n}_findNearestFontFaces(t,e,o,n){const s=GoogleFontsLoader._normalizeFontFamilyName(e),a=t.filter(t=>GoogleFontsLoader._normalizeFontFamilyName(t.family)===s&&t.style===o);if(!a.length)return[];const r=a.reduce((t,e)=>{if(!t)return e;const o=this._getFontFaceDistance(e,n),s=this._getFontFaceDistance(t,n);if(o<s)return e;if(o>s)return t;const a=this._resolveWeightForFontFace(e,n),r=this._resolveWeightForFontFace(t,n);return n<=500?a<r?e:t:a>r?e:t},null),i=this._resolveWeightForFontFace(r,n);return a.filter(t=>this._resolveWeightForFontFace(t,n)===i)}_warnAboutUnresolvedReturnedFontFamilies(t,e,o){const n=new Set(e.map(t=>GoogleFontsLoader._normalizeFontFamilyName(t.family))),s=new Set(o.map(t=>GoogleFontsLoader._normalizeFontFamilyName(t.family))),a=[];t.forEach(t=>{const e=this._getFontFamily(t),o=GoogleFontsLoader._normalizeFontFamilyName(e);o&&n.has(o)&&!s.has(o)&&a.push(e)}),a.length&&this._logError(`Google Fonts metadata returned font faces that were not resolved: ${a.join(", ")}`)}_warnAboutItalicOnlyReturnedFontFamilies(t,e){const o=[];t.forEach(t=>{const n=this._getFontFamily(t),s=GoogleFontsLoader._normalizeFontFamilyName(n);if(!s)return;const a=e.filter(t=>GoogleFontsLoader._normalizeFontFamilyName(t.family)===s);if(!a.length)return;const r=a.some(t=>"normal"===t.style),i=a.some(t=>"italic"===t.style);!r&&i&&o.push(n)}),o.length&&this._logError(`Google Fonts metadata returned only italic font faces for: ${o.join(", ")}. Normal text may fall back to a different font.`)}_getFontFaceDistance(t,e){return e>=t.minWeight&&e<=t.maxWeight?0:Math.min(Math.abs(e-t.minWeight),Math.abs(e-t.maxWeight))}_resolveWeightForFontFace(t,e){return e<t.minWeight?t.minWeight:e>t.maxWeight?t.maxWeight:e}_getFontFaceCss(t){const e=[],o=new Map,n=new Set;return t.forEach(t=>{t.fontFaces&&t.fontFaces.length?t.fontFaces.forEach(t=>{const e=this._getFontFaceMergeKey(t),n=o.get(e);if(n)return n.minWeight=Math.min(n.minWeight,t.minWeight),void(n.maxWeight=Math.max(n.maxWeight,t.maxWeight));o.set(e,{fontFace:t,minWeight:t.minWeight,maxWeight:t.maxWeight})}):(t.cssBlocks||[]).forEach(t=>{t&&!n.has(t)&&(n.add(t),e.push(t))})}),o.forEach(({fontFace:t,minWeight:o,maxWeight:s})=>{const a=this._replaceFontFaceWeight(t.css,o,s);a&&!n.has(a)&&(n.add(a),e.push(a))}),e.join("\n")}_dedupeFontVariations(t){const e=new Set,o=[];return t.forEach(t=>{const n=this._getVariationResourceKey(t);e.has(n)||(e.add(n),o.push(t))}),o}_getVariationResourceKey(t){if(!t.fontFaces||!t.fontFaces.length)return t.descriptor;const e=Array.from(new Set(t.fontFaces.map(t=>this._getFontFaceMergeKey(t)))).sort();return[GoogleFontsLoader._normalizeFontFamilyName(t.family),t.style,e.join("|")].join("|")}_getFontFaceMergeKey(t){return[GoogleFontsLoader._normalizeFontFamilyName(t.family),t.style,t.src,t.unicodeRange,this._removeFontFaceWeight(t.css)].join("|")}_removeFontFaceWeight(t){return`${t||""}`.replace(/\s*font-weight\s*:\s*[^;]+;/i,"")}_replaceFontFaceWeight(t,e,o){const n=e===o?`${e}`:`${e} ${o}`;return`${t||""}`.replace(/font-weight\s*:\s*[^;]+;/i,`font-weight: ${n};`)}_generateFontVariations(t){const e=[];return t.forEach(t=>{const o=this._getFontFamily(t);this._getRequestedWeights(t).forEach(t=>{["normal","italic"].forEach(n=>{e.push({family:o,weight:t,style:n,descriptor:`${n} ${t} 1em "${o}"`})})})}),e}_getFontFamily(t){return"string"==typeof t?t:t&&t.fontFamily}_getRequestedWeights(t){if("string"==typeof t)return[400];const e=t&&t.weights;if(!e||!e.length)return[400];const o=e.map(t=>GoogleFontsLoader._normalizeFontWeight(t));return Array.from(new Set(o)).sort((t,e)=>t-e)}_encodeFontFamily(t){return encodeURIComponent(t).replace(/%20/g,"+")}_createFontTester(t,e){const o=e.createElement("div");return o.setAttribute("aria-hidden","true"),o.style.cssText="\n position: fixed;\n top: -9999px;\n left: -9999px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n visibility: hidden;\n pointer-events: none;\n user-select: none;\n z-index: -1;\n ",t.forEach(t=>{Object.entries(this.testStrings).forEach(([n,s])=>{const a=e.createElement("span");a.textContent=s,a.style.cssText=`\n font-family: "${t.family}", sans-serif;\n font-weight: ${t.weight};\n font-style: ${t.style};\n font-size: 20px;\n display: inline-block;\n white-space: nowrap;\n `,a.dataset.font=`${t.family}-${t.weight}-${t.style}`,a.dataset.subset=n,o.appendChild(a)})}),o}async _waitForAllFontsToLoad(t,e){const o=[];for(let e=0;e<t.length;e+=10)o.push(t.slice(e,e+10));for(const t of o)await this._waitForFontBatchLoad(t,e)}async _waitForFontBatchLoad(t,e){const o=t.map(async t=>{try{e.fonts.check(t.descriptor)||await e.fonts.load(t.descriptor)}catch(e){this._logError(`Failed to load: ${t.descriptor} ${e}`)}});return Promise.all(o)}_logError(t){const e=[];void 0!==this.widgetId&&null!==this.widgetId&&e.push(`widgetId: ${this.widgetId}`),this.siteId&&e.push(`siteId: ${this.siteId}`),ErrorLogger.log(e.length?`${t} (${e.join(", ")})`:t)}}
1
+ import GoogleFontsRegistry from"./google-fonts/GoogleFontsRegistry";import{getUsedGoogleFonts}from"./google-fonts/GoogleFontsUsageExtractor";let nextGoogleFontsLoaderOwnerId=1;export default class GoogleFontsLoader{static getUsedGoogleFonts(t){return getUsedGoogleFonts(t)}constructor(t){t=t||{},this.widgetId=t.widgetId,this.siteId=t.siteId,this.ownerId="google-fonts-loader-"+nextGoogleFontsLoaderOwnerId++}async load(t,o){this.htmlDocumentObject=o||document,await GoogleFontsRegistry.loadFonts({ownerId:this.ownerId,document:this.htmlDocumentObject,fonts:t,context:{widgetId:this.widgetId,siteId:this.siteId}})}cleanup(){GoogleFontsRegistry.releaseOwner({ownerId:this.ownerId,document:this.htmlDocumentObject}),this.htmlDocumentObject=void 0}}
@@ -0,0 +1,65 @@
1
+ export type GoogleFontStyleValue = 'normal' | 'italic';
2
+ export type GoogleFontWeightInput = number | string;
3
+ export interface GoogleFontVariationRequestI {
4
+ style: GoogleFontStyleValue;
5
+ weight: GoogleFontWeightInput;
6
+ }
7
+ export interface GoogleFontRequestI {
8
+ fontFamily: string;
9
+ weights?: GoogleFontWeightInput[];
10
+ variations?: GoogleFontVariationRequestI[];
11
+ }
12
+ export type GoogleFontInput = string | GoogleFontRequestI;
13
+ export interface ResolvedGoogleFontVariationI {
14
+ style: GoogleFontStyleValue;
15
+ weight: number;
16
+ }
17
+ export interface ResolvedGoogleFontRequestI {
18
+ fontFamily: string;
19
+ variations: ResolvedGoogleFontVariationI[];
20
+ }
21
+ export interface GoogleFontsLoaderOptionsI {
22
+ widgetId?: number;
23
+ siteId?: string;
24
+ }
25
+ export interface GoogleFontsLogContextI {
26
+ widgetId?: number;
27
+ siteId?: string;
28
+ }
29
+ export interface GoogleFontFaceI {
30
+ family: string;
31
+ style: GoogleFontStyleValue;
32
+ minWeight: number;
33
+ maxWeight: number;
34
+ src: string;
35
+ unicodeRange: string;
36
+ css: string;
37
+ }
38
+ export interface GoogleFontResourceI {
39
+ key: string;
40
+ family: string;
41
+ style: GoogleFontStyleValue;
42
+ minWeight: number;
43
+ maxWeight: number;
44
+ src: string;
45
+ unicodeRange: string;
46
+ css: string;
47
+ descriptor: string;
48
+ }
49
+ export interface GoogleFontsMetadataRequestI {
50
+ url: string;
51
+ cacheKeys: string[];
52
+ families: string[];
53
+ includesItalic: boolean;
54
+ }
55
+ export interface GoogleFontsFallbackRequestI {
56
+ url: string;
57
+ fontFamilyLabel: string;
58
+ }
59
+ export interface GoogleFontsResolveWarningI {
60
+ message: string;
61
+ }
62
+ export interface GoogleFontsResolveResultI {
63
+ resources: GoogleFontResourceI[];
64
+ warnings: GoogleFontsResolveWarningI[];
65
+ }
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,28 @@
1
+ import { GoogleFontFaceI, GoogleFontResourceI, GoogleFontsFallbackRequestI, GoogleFontsMetadataRequestI, GoogleFontsResolveResultI, GoogleFontsResolveWarningI, ResolvedGoogleFontRequestI } from './GoogleFonts.types';
2
+ export declare function buildMetadataRequest(fonts: ResolvedGoogleFontRequestI[]): GoogleFontsMetadataRequestI | null;
3
+ export declare function buildFallbackRequest(fonts: ResolvedGoogleFontRequestI[]): GoogleFontsFallbackRequestI | null;
4
+ export declare function fetchMetadata(request: GoogleFontsMetadataRequestI): Promise<string>;
5
+ export declare function parseFontFaces(cssText: string): GoogleFontFaceI[];
6
+ export declare function resolveResources(fonts: ResolvedGoogleFontRequestI[], fontFaces: GoogleFontFaceI[]): GoogleFontsResolveResultI;
7
+ export declare function mergeResourceCss(resource: GoogleFontResourceI, minWeight: number, maxWeight: number): string;
8
+ export declare function buildFontUrlParts(fonts: ResolvedGoogleFontRequestI[]): Array<{
9
+ fontFamily: string;
10
+ urlPart: string;
11
+ }>;
12
+ export declare function makeFontOptions(): number[];
13
+ export declare function makeGoogleFontsUrl(dynamicPart: string): string;
14
+ export declare function getMetadataCacheKey(font: ResolvedGoogleFontRequestI): string;
15
+ export declare function getFontFaceProperty(css: string, property: string): string;
16
+ export declare function parseFontFaceWeight(fontWeight: string): {
17
+ minWeight: number;
18
+ maxWeight: number;
19
+ } | null;
20
+ export declare function findNearestFontFaces(fontFaces: GoogleFontFaceI[], family: string, style: string, weight: number): GoogleFontFaceI[];
21
+ export declare function getFontFaceDistance(fontFace: GoogleFontFaceI, weight: number): number;
22
+ export declare function resolveWeightForFontFace(fontFace: GoogleFontFaceI, weight: number): number;
23
+ export declare function getFontFaceResourceKey(fontFace: GoogleFontFaceI): string;
24
+ export declare function removeFontFaceWeight(css: string): string;
25
+ export declare function replaceFontFaceWeight(css: string, minWeight: number, maxWeight: number): string;
26
+ export declare function makeFontDescriptor(family: string, style: string, weight: number): string;
27
+ export declare function getUnresolvedReturnedFontFamilyWarnings(fonts: ResolvedGoogleFontRequestI[], fontFaces: GoogleFontFaceI[], resolvedFamilies: Set<string>): GoogleFontsResolveWarningI[];
28
+ export declare function getItalicOnlyWarnings(fonts: ResolvedGoogleFontRequestI[], fontFaces: GoogleFontFaceI[]): GoogleFontsResolveWarningI[];
@@ -0,0 +1 @@
1
+ import{buildGoogleFontsLogMessage,encodeGoogleFontFamily,escapeFontFamilyForCss,normalizeFontFamilyName}from"./GoogleFontsUtils";export function buildMetadataRequest(e){const t=buildFontUrlParts(e);if(!t.length)return null;const n=e.some(e=>(e.variations||[]).some(e=>"italic"===e.style));return{url:makeGoogleFontsUrl(t.map(e=>e.urlPart).join("")),cacheKeys:e.map(e=>getMetadataCacheKey(e)),families:e.map(e=>e.fontFamily),includesItalic:n}}export function buildFallbackRequest(e){const t=buildFontUrlParts(e);return t.length?{url:makeGoogleFontsUrl(t.map(e=>e.urlPart).join("")),fontFamilyLabel:t.map(e=>e.fontFamily).join(", ")}:null}export async function fetchMetadata(e){let t;try{t=await fetch(e.url)}catch(t){throw new Error(buildGoogleFontsLogMessage("metadata request failed (network error)",{url:e.url,error:String(t)}))}if(!t.ok)throw new Error(buildGoogleFontsLogMessage("metadata request failed",{url:e.url,status:t.status}));return t.text()}export function parseFontFaces(e){const t=[],n=/@font-face\s*{[^}]*}/gi;let o;for(;null!==(o=n.exec(e||""));){const e=o[0],n=getFontFaceProperty(e,"font-family"),a=getFontFaceProperty(e,"font-style")||"normal",r=parseFontFaceWeight(getFontFaceProperty(e,"font-weight"));n&&r&&t.push({family:n,style:"italic"===a?"italic":"normal",minWeight:r.minWeight,maxWeight:r.maxWeight,src:getFontFaceProperty(e,"src"),unicodeRange:getFontFaceProperty(e,"unicode-range"),css:e})}return t}export function resolveResources(e,t){const n=new Map,o=[],a=new Set,r=getWeightRangeByResourceKey(t);return e.forEach(e=>{const o=normalizeFontFamilyName(e.fontFamily);(e.variations||[]).forEach(i=>{const s=findNearestFontFaces(t,e.fontFamily,i.style,i.weight);s.length&&(a.add(o),s.forEach(t=>{const o=getFontFaceResourceKey(t);if(n.has(o))return;const a=r.get(o)||{minWeight:t.minWeight,maxWeight:t.maxWeight};n.set(o,{key:o,family:e.fontFamily,style:t.style,minWeight:a.minWeight,maxWeight:a.maxWeight,src:t.src,unicodeRange:t.unicodeRange,css:replaceFontFaceWeight(t.css,a.minWeight,a.maxWeight),descriptor:makeFontDescriptor(e.fontFamily,t.style,a.minWeight)})}))})}),o.push(...getUnresolvedReturnedFontFamilyWarnings(e,t,a)),o.push(...getItalicOnlyWarnings(e,t)),{resources:Array.from(n.values()),warnings:o}}function getWeightRangeByResourceKey(e){const t=new Map;return(e||[]).forEach(e=>{const n=getFontFaceResourceKey(e),o=t.get(n);t.set(n,{minWeight:o?Math.min(o.minWeight,e.minWeight):e.minWeight,maxWeight:o?Math.max(o.maxWeight,e.maxWeight):e.maxWeight})}),t}export function mergeResourceCss(e,t,n){return replaceFontFaceWeight(e.css,t,n)}export function buildFontUrlParts(e){const t=makeFontOptions();return(e||[]).map(e=>{const n=(e.variations||[]).some(e=>"italic"===e.style),o=(e.variations||[]).some(e=>"normal"===e.style)||!n,a=[];return n?(o&&t.forEach(e=>a.push(`0,${e}`)),t.forEach(e=>a.push(`1,${e}`)),{fontFamily:e.fontFamily,urlPart:`&family=${encodeGoogleFontFamily(e.fontFamily)}:ital,wght@${a.join(";")}`}):{fontFamily:e.fontFamily,urlPart:`&family=${encodeGoogleFontFamily(e.fontFamily)}:wght@${t.join(";")}`}}).filter(e=>e.fontFamily)}export function makeFontOptions(){const e=[];for(let t=0;t<9;t++)e.push(100*(t+1));return e}export function makeGoogleFontsUrl(e){return`https://fonts.googleapis.com/css2?display=swap${e}`}export function getMetadataCacheKey(e){const t=Array.from(new Set((e.variations||[]).map(e=>e.style))).sort();return`${normalizeFontFamilyName(e.fontFamily)}|${t.join(",")||"normal"}`}export function getFontFaceProperty(e,t){const n=new RegExp(`${t}\\s*:\\s*([^;]+);`,"i"),o=`${e||""}`.match(n);return o?o[1].trim().replace(/^['"]|['"]$/g,""):""}export function parseFontFaceWeight(e){const t=`${e||""}`.match(/\d+(\.\d+)?/g);if(!t||!t.length)return null;const n=Number(t[0]),o=Number(t[t.length-1]);return{minWeight:Math.min(n,o),maxWeight:Math.max(n,o)}}export function findNearestFontFaces(e,t,n,o){const a=normalizeFontFamilyName(t),r=e.filter(e=>normalizeFontFamilyName(e.family)===a&&e.style===n);if(!r.length)return[];const i=r.reduce((e,t)=>{if(!e)return t;const n=getFontFaceDistance(t,o),a=getFontFaceDistance(e,o);if(n<a)return t;if(n>a)return e;const r=resolveWeightForFontFace(t,o),i=resolveWeightForFontFace(e,o);return o<=500?r<i?t:e:r>i?t:e},null),s=resolveWeightForFontFace(i,o);return r.filter(e=>resolveWeightForFontFace(e,o)===s)}export function getFontFaceDistance(e,t){return t>=e.minWeight&&t<=e.maxWeight?0:Math.min(Math.abs(t-e.minWeight),Math.abs(t-e.maxWeight))}export function resolveWeightForFontFace(e,t){return t<e.minWeight?e.minWeight:t>e.maxWeight?e.maxWeight:t}export function getFontFaceResourceKey(e){return[normalizeFontFamilyName(e.family),e.style,e.src,e.unicodeRange,removeFontFaceWeight(e.css)].join("|")}export function removeFontFaceWeight(e){return`${e||""}`.replace(/\s*font-weight\s*:\s*[^;]+;/i,"")}export function replaceFontFaceWeight(e,t,n){const o=t===n?`${t}`:`${t} ${n}`;return`${e||""}`.replace(/font-weight\s*:\s*[^;]+;/i,`font-weight: ${o};`)}export function makeFontDescriptor(e,t,n){return`${t} ${n} 1em "${escapeFontFamilyForCss(e)}"`}export function getUnresolvedReturnedFontFamilyWarnings(e,t,n){const o=new Set(t.map(e=>normalizeFontFamilyName(e.family))),a=[];return e.forEach(e=>{const t=normalizeFontFamilyName(e.fontFamily);t&&o.has(t)&&!n.has(t)&&a.push(e.fontFamily)}),a.length?[{message:buildGoogleFontsLogMessage("metadata returned unresolved font faces",{fontFamilies:a.join(", ")})}]:[]}export function getItalicOnlyWarnings(e,t){const n=[];return e.forEach(e=>{const o=normalizeFontFamilyName(e.fontFamily);if(!o)return;const a=t.filter(e=>normalizeFontFamilyName(e.family)===o);if(!a.length)return;const r=a.some(e=>"normal"===e.style),i=a.some(e=>"italic"===e.style);!r&&i&&n.push(e.fontFamily)}),n.length?[{message:buildGoogleFontsLogMessage("metadata returned only italic font faces, normal text may fall back to a different font",{fontFamilies:n.join(", ")})}]:[]}
@@ -0,0 +1,40 @@
1
+ import { GoogleFontInput, GoogleFontsLogContextI } from './GoogleFonts.types';
2
+ export interface GoogleFontsRegistryLoadParamsI {
3
+ ownerId: string;
4
+ document: Document;
5
+ fonts: GoogleFontInput[];
6
+ context?: GoogleFontsLogContextI;
7
+ }
8
+ export interface GoogleFontsRegistryReleaseParamsI {
9
+ ownerId: string;
10
+ document?: Document;
11
+ }
12
+ declare class GoogleFontsRegistry {
13
+ private statesByDocument;
14
+ loadFonts(params: GoogleFontsRegistryLoadParamsI): Promise<void>;
15
+ releaseOwner(params: GoogleFontsRegistryReleaseParamsI): void;
16
+ resetForTests(): void;
17
+ private normalizeFontsForLoading;
18
+ private mergeFontRequests;
19
+ private getState;
20
+ private getOwner;
21
+ private isCurrentOwner;
22
+ private getFontFaces;
23
+ private getCachedFontFaces;
24
+ private getPendingFontFaces;
25
+ private cacheFontFaces;
26
+ private isMatchingFontFace;
27
+ private getFontFaceCacheIdentity;
28
+ private hasFontStyleCoverage;
29
+ private addResource;
30
+ private addFallbackLink;
31
+ private generateFallbackResources;
32
+ private waitForFonts;
33
+ private prepareFontResourceLoads;
34
+ private waitForAllFontsToLoad;
35
+ private loadBrowserFont;
36
+ private createFontTester;
37
+ private logError;
38
+ }
39
+ declare const _default: GoogleFontsRegistry;
40
+ export default _default;
@@ -0,0 +1 @@
1
+ import ErrorLogger from"@claspo/renderer/error/ErrorLogger";import{buildFallbackRequest,buildMetadataRequest,fetchMetadata,getMetadataCacheKey,makeFontDescriptor,mergeResourceCss,parseFontFaces,resolveResources}from"./GoogleFontsMetadataService";import{buildGoogleFontsLogMessage,normalizeFontInput,parseGoogleFontsLogMessage,sortFontVariations}from"./GoogleFontsUtils";class GoogleFontsRegistry{constructor(){this.statesByDocument=new WeakMap}async loadFonts(e){const t=e.document||document,s=this.normalizeFontsForLoading(e.fonts);if(!s.length)return;const o=s.map(e=>e.fontFamily).join(", "),r=this.getState(t),n=this.getOwner(r,e.ownerId);try{const a=await this.getFontFaces(r,s);if(!this.isCurrentOwner(r,e.ownerId,n))return;if(!a.length)throw new Error(buildGoogleFontsLogMessage("metadata response contained no @font-face rules",{fontFamilies:o}));const i=resolveResources(s,a);if(!this.isCurrentOwner(r,e.ownerId,n))return;if(i.warnings.forEach(t=>this.logError(t.message,e.context)),!i.resources.length)throw new Error(buildGoogleFontsLogMessage("metadata response contained no matching font faces",{fontFamilies:o}));const l=i.resources.map(s=>this.addResource(r,n,t,e.ownerId,s));await this.waitForFonts(l.map(e=>e.resource),r,t,e.context)}catch(a){if(!this.isCurrentOwner(r,e.ownerId,n))return;const i=parseGoogleFontsLogMessage(a instanceof Error?a.message:String(a));if(this.logError(buildGoogleFontsLogMessage("optimized CSS load failed, falling back to stylesheet link",Object.assign({fontFamilies:o,cause:i.message},i.props)),e.context),await this.addFallbackLink(r,n,t,e.ownerId,s,e.context),!this.isCurrentOwner(r,e.ownerId,n))return;await this.waitForFonts(this.generateFallbackResources(s),r,t,e.context)}}releaseOwner(e){if(!e.document)return;const t=this.statesByDocument.get(e.document);if(!t)return;const s=t.ownersById.get(e.ownerId);s&&(s.resourceKeys.forEach(s=>{const o=t.resourcesByKey.get(s);o&&(o.owners.delete(e.ownerId),o.owners.size||(o.element.remove(),t.resourcesByKey.delete(s)))}),s.fallbackUrls.forEach(s=>{const o=t.fallbackLinksByUrl.get(s);o&&(o.owners.delete(e.ownerId),o.owners.size||(o.element.remove(),t.fallbackLinksByUrl.delete(s)))}),t.ownersById.delete(e.ownerId))}resetForTests(){this.statesByDocument=new WeakMap}normalizeFontsForLoading(e){const t=[];return(e||[]).forEach(e=>{const s=normalizeFontInput(e);if(!s)return;if("string"!=typeof e&&e.variations&&e.variations.length)return void t.push(s);const o=[];s.variations.forEach(e=>{o.push({style:"normal",weight:e.weight}),o.push({style:"italic",weight:e.weight})}),t.push({fontFamily:s.fontFamily,variations:sortFontVariations(o)})}),this.mergeFontRequests(t)}mergeFontRequests(e){const t=new Map;return e.forEach(e=>{const s=t.get(e.fontFamily);s?s.variations=sortFontVariations(s.variations.concat(e.variations)):t.set(e.fontFamily,{fontFamily:e.fontFamily,variations:sortFontVariations(e.variations)})}),Array.from(t.values())}getState(e){let t=this.statesByDocument.get(e);return t||(t={metadataByCacheKey:new Map,pendingMetadataByUrl:new Map,fallbackLinksByUrl:new Map,resourcesByKey:new Map,browserLoadsByResourceKey:new Map,ownersById:new Map},this.statesByDocument.set(e,t)),t}getOwner(e,t){let s=e.ownersById.get(t);return s||(s={resourceKeys:new Set,fallbackUrls:new Set},e.ownersById.set(t,s)),s}isCurrentOwner(e,t,s){return e.ownersById.get(t)===s}async getFontFaces(e,t){const s=this.getCachedFontFaces(e,t);if(!s.missingFonts.length)return s.cachedFontFaces;const o=this.getPendingFontFaces(e,s.missingFonts),r=o.pendingPromises.slice(),n=buildMetadataRequest(o.missingFonts);if(n){let t=e.pendingMetadataByUrl.get(n.url);if(!t){const s=fetchMetadata(n).then(t=>{const s=parseFontFaces(t);return this.cacheFontFaces(e,o.missingFonts,s),s}).finally(()=>e.pendingMetadataByUrl.delete(n.url));t={url:n.url,fonts:o.missingFonts,promise:s},e.pendingMetadataByUrl.set(n.url,t)}r.push(t.promise)}if(!r.length)return s.cachedFontFaces;const a=await Promise.all(r);return s.cachedFontFaces.concat(...a)}getCachedFontFaces(e,t){const s=[],o=new Set,r=[];for(const n of t){const t=getMetadataCacheKey(n).split("|")[0],a=[];Array.from(new Set((n.variations||[]).map(e=>e.style))).forEach(r=>{const i=Array.from(e.metadataByCacheKey.values()).find(e=>e.families.has(t)&&e.styles.has(r));i?i.fontFaces.filter(e=>this.isMatchingFontFace(e,t,r)).forEach(e=>{const t=this.getFontFaceCacheIdentity(e);o.has(t)||(o.add(t),s.push(e))}):a.push(...(n.variations||[]).filter(e=>e.style===r))}),a.length&&r.push({fontFamily:n.fontFamily,variations:sortFontVariations(a)})}return{cachedFontFaces:s,missingFonts:r}}getPendingFontFaces(e,t){const s=[],o=new Set,r=[];for(const n of t){const t=getMetadataCacheKey(n).split("|")[0],a=[];Array.from(new Set((n.variations||[]).map(e=>e.style))).forEach(r=>{const i=Array.from(e.pendingMetadataByUrl.values()).find(e=>this.hasFontStyleCoverage(e.fonts,t,r));i?o.has(i.url)||(o.add(i.url),s.push(i.promise)):a.push(...(n.variations||[]).filter(e=>e.style===r))}),a.length&&r.push({fontFamily:n.fontFamily,variations:sortFontVariations(a)})}return{pendingPromises:s,missingFonts:r}}cacheFontFaces(e,t,s){t.forEach(t=>{const o=getMetadataCacheKey(t).split("|")[0],r=new Set((t.variations||[]).map(e=>e.style)),n=s.filter(e=>this.isMatchingFontFace(e,o));e.metadataByCacheKey.set(`${o}|${Array.from(r).sort().join(",")||"normal"}`,{families:new Set([o]),styles:r,fontFaces:n})})}isMatchingFontFace(e,t,s){if(!e||!e.family)return!1;return!!getMetadataCacheKey({fontFamily:e.family,variations:[{style:e.style,weight:e.minWeight}]}).startsWith(t+"|")&&(!s||e.style===s)}getFontFaceCacheIdentity(e){return[e.family,e.style,e.minWeight,e.maxWeight,e.src,e.unicodeRange].join("|")}hasFontStyleCoverage(e,t,s){return(e||[]).some(e=>getMetadataCacheKey(e).split("|")[0]===t&&(e.variations||[]).some(e=>e.style===s))}addResource(e,t,s,o,r){const n=e.resourcesByKey.get(r.key);if(n){n.owners.add(o),t.resourceKeys.add(r.key);const e=Math.min(n.minWeight,r.minWeight),s=Math.max(n.maxWeight,r.maxWeight);return e===n.minWeight&&s===n.maxWeight||(n.minWeight=e,n.maxWeight=s,n.resource.minWeight=e,n.resource.maxWeight=s,n.resource.css=mergeResourceCss(n.resource,e,s),n.resource.descriptor=makeFontDescriptor(n.resource.family,n.resource.style,e),n.element.textContent=n.resource.css),n}const a=s.createElement("style");a.setAttribute("data-cl-google-fonts","true"),a.textContent=r.css,s.head&&s.head.appendChild(a);const i={resource:r,element:a,owners:new Set([o]),minWeight:r.minWeight,maxWeight:r.maxWeight};return e.resourcesByKey.set(r.key,i),t.resourceKeys.add(r.key),i}addFallbackLink(e,t,s,o,r,n){const a=buildFallbackRequest(r);if(!a||!s.head)return Promise.resolve();const i=e.fallbackLinksByUrl.get(a.url);if(i)return i.owners.add(o),t.fallbackUrls.add(a.url),i.promise;const l=s.createElement("link");l.rel="stylesheet",l.href=a.url;const c=new Promise((t,s)=>{l.onload=()=>t(),l.onerror=()=>{this.logError(buildGoogleFontsLogMessage("fallback stylesheet failed to load",{url:a.url,fontFamilies:a.fontFamilyLabel}),n),l.remove(),e.fallbackLinksByUrl.delete(a.url),s(new Error(buildGoogleFontsLogMessage("fallback stylesheet failed to load",{url:a.url})))}}),d={url:a.url,element:l,owners:new Set([o]),promise:c.catch(()=>{})};return e.fallbackLinksByUrl.set(a.url,d),t.fallbackUrls.add(a.url),s.head.appendChild(l),d.promise}generateFallbackResources(e){return e.reduce((e,t)=>((t.variations||[]).forEach(s=>{const o=makeFontDescriptor(t.fontFamily,s.style,s.weight);e.push({key:`${t.fontFamily}|${s.style}|${s.weight}|fallback`,family:t.fontFamily,style:s.style,minWeight:s.weight,maxWeight:s.weight,src:"",unicodeRange:"",css:"",descriptor:o})}),e),[])}async waitForFonts(e,t,s,o){if(!e.length||!s.fonts)return;const r=this.prepareFontResourceLoads(e,t,s,o);if(!r.length)return;const n=this.createFontTester(r.map(e=>e.resource),s);n&&s.body&&s.body.appendChild(n);const a=this.waitForAllFontsToLoad(r);let i=null;const l=new Promise(e=>{i=setTimeout(()=>{this.logError(buildGoogleFontsLogMessage("font loading timed out",{timeoutMs:2e3,pending:r.map(e=>e.resource.descriptor).join("; "),src:r.map(e=>e.resource.src).join("; ")}),o),e()},2e3)});try{await Promise.race([a,l])}finally{i&&clearTimeout(i),n&&n.remove()}}prepareFontResourceLoads(e,t,s,o){return e.reduce((e,r)=>{const n=t.browserLoadsByResourceKey.get(r.key);if(n&&n.loaded)return e;if(n&&n.promise)return e;const a={loaded:!1,promise:null},i=this.loadBrowserFont(r,s).then(()=>{a.loaded=!0,a.promise=null}).catch(e=>{t.browserLoadsByResourceKey.delete(r.key),this.logError(buildGoogleFontsLogMessage("font face failed to load",{descriptor:r.descriptor,src:r.src,error:String(e)}),o)});return a.promise=i,t.browserLoadsByResourceKey.set(r.key,a),e.push({resource:r,promise:i}),e},[])}async waitForAllFontsToLoad(e){for(let t=0;t<e.length;t+=10)await Promise.all(e.slice(t,t+10).map(e=>e.promise))}async loadBrowserFont(e,t){const s=t.fonts;if(!s)return;let o=!1;try{o=s.check(e.descriptor)}catch(e){}o||await s.load(e.descriptor)}createFontTester(e,t){if(!t.body)return null;const s=t.createElement("div");s.setAttribute("aria-hidden","true"),s.style.cssText="\n position: fixed;\n top: -9999px;\n left: -9999px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n visibility: hidden;\n pointer-events: none;\n user-select: none;\n z-index: -1;\n ";const o={latin:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",cyrillic:"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя"};return e.forEach(e=>{Object.entries(o).forEach(([o,r])=>{const n=t.createElement("span");n.textContent=r,n.style.cssText=`\n font-family: "${e.family}", sans-serif;\n font-weight: ${e.minWeight};\n font-style: ${e.style};\n font-size: 20px;\n display: inline-block;\n white-space: nowrap;\n `,n.dataset.font=`${e.family}-${e.minWeight}-${e.style}`,n.dataset.subset=o,s.appendChild(n)})}),s}logError(e,t){const{message:s,props:o}=parseGoogleFontsLogMessage(e);t&&void 0!==t.widgetId&&null!==t.widgetId&&(o.widgetId=t.widgetId),t&&t.siteId&&(o.siteId=t.siteId);const r=Object.keys(o).map(e=>`${e}: ${o[e]}`),n=r.length?` (${r.join(", ")})`:"";ErrorLogger.log(`GoogleFontsLoader error: ${s}${n}`)}}export default new GoogleFontsRegistry;
@@ -0,0 +1,11 @@
1
+ import { ResolvedGoogleFontRequestI } from './GoogleFonts.types';
2
+ interface ContentStyleUsageI {
3
+ hasItalic: boolean;
4
+ hasBold: boolean;
5
+ }
6
+ export declare function getUsedGoogleFonts(documentModel: any): ResolvedGoogleFontRequestI[];
7
+ export declare function getEnabledStyleEntries(node: any): any[];
8
+ export declare function splitClassNames(classNames: string): string[];
9
+ export declare function getContentStyleUsage(node: any): ContentStyleUsageI;
10
+ export declare function getNodeContentText(node: any): string;
11
+ export {};
@@ -0,0 +1 @@
1
+ import DocumentUtils from"@claspo/common/document/DocumentUtils";import{extractFirstCssFontFamily,normalizeFontFamilyName,normalizeFontWeight,sortFontVariations}from"./GoogleFontsUtils";export function getUsedGoogleFonts(t){const e=t&&t.shared&&t.shared.googleFonts;if(!e||0===e.length)return[];const s=new Map;e.forEach(t=>{const e=extractFirstCssFontFamily(t),o=normalizeFontFamilyName(e);o&&s.set(o,e)});const o=new Map,a=new Map,n=(t,e,a)=>{if(!s.has(t))return;const n=normalizeFontWeight(a);o.has(t)||o.set(t,new Map),o.get(t).set(`${e}|${n}`,{style:e,weight:n})},i=(t,e=400,s={hasItalic:!1,hasBold:!1})=>{const o=normalizeFontFamilyName(extractFirstCssFontFamily(t));o&&(n(o,"normal",e),s.hasItalic&&n(o,"italic",e),s.hasBold&&(n(o,"normal",700),s.hasItalic&&n(o,"italic",700)))},l=(t,e)=>{const s=a.get(t)||{hasItalic:!1,hasBold:!1};a.set(t,{hasItalic:s.hasItalic||e.hasItalic,hasBold:s.hasBold||e.hasBold})};for(const e of t.views||[])DocumentUtils.iterateDepthFirst(e,t=>{const e=getEnabledStyleEntries(t),s=getContentStyleUsage(t);for(const t of e)if(t.classes)for(const e of splitClassNames(t.classes))e&&e.startsWith("cl-")&&l(e,s);for(const t of e)t.styleAttributes&&t.styleAttributes.fontFamily&&i(t.styleAttributes.fontFamily,t.styleAttributes.fontWeight,s)});const r=t.shared||{};for(const[t,e]of a){const s=r.textClasses&&r.textClasses[t];s&&(s.styleAttributes&&s.styleAttributes.fontFamily?i(s.styleAttributes.fontFamily,s.styleAttributes.fontWeight,e):(s.isHeader&&r.headerFontFamily&&i(r.headerFontFamily,s.styleAttributes&&s.styleAttributes.fontWeight,e),!s.isHeader&&r.textFontFamily&&i(r.textFontFamily,s.styleAttributes&&s.styleAttributes.fontWeight,e)))}return r.textFontFamily&&i(r.textFontFamily),e.map(t=>normalizeFontFamilyName(extractFirstCssFontFamily(t))).filter(t=>o.has(t)).map(t=>({fontFamily:s.get(t),variations:sortFontVariations(Array.from(o.get(t).values()))}))}export function getEnabledStyleEntries(t){const e=[];t.props&&t.props.adaptiveStyles&&(e.push(...t.props.adaptiveStyles.desktop||[]),e.push(...t.props.adaptiveStyles.mobile||[])),t.props&&t.props.styles&&e.push(...t.props.styles||[]);const s=new Set(e.filter(t=>t.params&&!1===t.params.enabled).map(t=>t.element));return e.filter(t=>!s.has(t.element))}export function splitClassNames(t){return`${t||""}`.split(/\s+/).filter(Boolean)}export function getContentStyleUsage(t){const e=getNodeContentText(t);return{hasItalic:/<i(\s|>|\/)/i.test(e),hasBold:/<(b|strong)(\s|>|\/)/i.test(e)}}export function getNodeContentText(t){const e=t&&t.props&&t.props.content;return e?"string"==typeof e?e:"string"==typeof e.text?e.text:"string"==typeof e.html?e.html:"":""}
@@ -0,0 +1,17 @@
1
+ import { GoogleFontInput, GoogleFontStyleValue, GoogleFontWeightInput, ResolvedGoogleFontRequestI, ResolvedGoogleFontVariationI } from './GoogleFonts.types';
2
+ export declare function normalizeFontFamilyName(fontFamily: string | null | undefined): string;
3
+ export declare function extractFontFamilyName(fontFamily: string | null | undefined): string;
4
+ export declare function extractFirstCssFontFamily(fontFamily: string | null | undefined): string;
5
+ export declare function normalizeFontWeight(fontWeight: GoogleFontWeightInput | null | undefined): number;
6
+ export declare function sortFontVariations(variations: ResolvedGoogleFontVariationI[]): ResolvedGoogleFontVariationI[];
7
+ export declare function normalizeFontInput(font: GoogleFontInput): ResolvedGoogleFontRequestI | null;
8
+ export declare function normalizeFontInputs(fonts: GoogleFontInput[]): ResolvedGoogleFontRequestI[];
9
+ export declare function normalizeFontStyle(style: GoogleFontStyleValue | string): GoogleFontStyleValue;
10
+ export declare function escapeFontFamilyForCss(fontFamily: string): string;
11
+ export declare function encodeGoogleFontFamily(fontFamily: string): string;
12
+ export type GoogleFontsLogPropsI = Record<string, string | number>;
13
+ export declare function buildGoogleFontsLogMessage(message: string, props?: GoogleFontsLogPropsI): string;
14
+ export declare function parseGoogleFontsLogMessage(message: string): {
15
+ message: string;
16
+ props: GoogleFontsLogPropsI;
17
+ };
@@ -0,0 +1 @@
1
+ export function normalizeFontFamilyName(t){return`${t||""}`.trim().replace(/\s+/g," ").toLowerCase()}export function extractFontFamilyName(t){return stripWrappingQuotes(`${t||""}`.trim().replace(/\s+/g," "))}export function extractFirstCssFontFamily(t){const e=`${t||""}`.trim();if(!e)return"";let n="",o="";for(let t=0;t<e.length;t++){const r=e[t];if('"'!==r&&"'"!==r||"\\"===e[t-1]||(n?n===r&&(n=""):n=r),","===r&&!n)break;o+=r}return extractFontFamilyName(o)}export function normalizeFontWeight(t){if("normal"===t)return 400;if("bold"===t)return 700;const e=parseInt(`${t||""}`,10);return Number.isFinite(e)&&e>0?e:400}export function sortFontVariations(t){const e=new Map;return(t||[]).forEach(t=>{const n=normalizeFontStyle(t.style),o=normalizeFontWeight(t.weight);e.set(`${n}|${o}`,{style:n,weight:o})}),Array.from(e.values()).sort((t,e)=>t.weight!==e.weight?t.weight-e.weight:t.style===e.style?0:"normal"===t.style?-1:1)}export function normalizeFontInput(t){const e=extractFontFamilyName("string"==typeof t?t:t&&t.fontFamily);if(!e)return null;const n=[];return"string"==typeof t?n.push({style:"normal",weight:400}):((t.weights&&t.weights.length?t.weights:[]).forEach(t=>{n.push({style:"normal",weight:normalizeFontWeight(t)})}),(t.variations||[]).forEach(t=>{n.push({style:normalizeFontStyle(t.style),weight:normalizeFontWeight(t.weight)})}),n.length||n.push({style:"normal",weight:400})),{fontFamily:e,variations:sortFontVariations(n)}}export function normalizeFontInputs(t){return(t||[]).map(t=>normalizeFontInput(t)).filter(Boolean)}export function normalizeFontStyle(t){return"italic"===t?"italic":"normal"}export function escapeFontFamilyForCss(t){return`${t||""}`.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}export function encodeGoogleFontFamily(t){return encodeURIComponent(t).replace(/%20/g,"+")}export function buildGoogleFontsLogMessage(t,e){const n={message:t};return e&&Object.keys(e).forEach(t=>{const o=e[t];null!=o&&""!==o&&(n[t]=o)}),JSON.stringify(n)}export function parseGoogleFontsLogMessage(t){let e=null;try{e=JSON.parse(t)}catch(t){e=null}if(!e||"object"!=typeof e||"string"!=typeof e.message)return{message:t,props:{}};const n={};return Object.keys(e).forEach(t=>{"message"!==t&&void 0!==e[t]&&null!==e[t]&&(n[t]=e[t])}),{message:e.message,props:n}}function stripWrappingQuotes(t){const e=`${t||""}`.trim();return'"'===e[0]&&'"'===e[e.length-1]||"'"===e[0]&&"'"===e[e.length-1]?e.slice(1,-1).trim():e}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claspo/document-connector",
3
- "version": "16.7.5-scroll-fix1",
3
+ "version": "16.7.6-ctx.2",
4
4
  "scripts": {
5
5
  "test": "jest --no-cache --coverage",
6
6
  "build": "rm -rf out && tsc --project tsconfig.json && npm run minify",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@claspo/common": "7.2.0",
18
- "@claspo/renderer": "18.6.0"
18
+ "@claspo/renderer": "18.6.0-ctx.2"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@babel/core": "^7.28.5",