@@ -49,6 +49,22 @@ const GOOGLE_STATICMAP_CENTER_RE = new RegExp(
4949 `center=(${ NUMBER_PART } )(?:%2c|%2C|,)(${ NUMBER_PART } )` ,
5050 "i" ,
5151) ;
52+ // JSON field patterns from HTML (e.g., "lat":52.28..."lng":-1.53)
53+ const GOOGLE_JSON_LAT_LNG_RE = new RegExp (
54+ `"lat"\\s*:\\s*(${ NUMBER_PART } )[^]{0,200}?"lng"\\s*:\\s*(${ NUMBER_PART } )` ,
55+ "i" ,
56+ ) ;
57+ const GOOGLE_JSON_LNG_LAT_RE = new RegExp (
58+ `"lng"\\s*:\\s*(${ NUMBER_PART } )[^]{0,200}?"lat"\\s*:\\s*(${ NUMBER_PART } )` ,
59+ "i" ,
60+ ) ;
61+ // Decimal pair pattern - requires 4+ decimals to avoid noise (e.g., 52.2814,-1.5345)
62+ const GOOGLE_DECIMAL_PAIR_RE = / (?< lat > - ? \d { 1 , 2 } \. \d { 4 , } ) \s * , \s * (?< lon > - ? \d { 1 , 3 } \. \d { 4 , } ) / g;
63+ // Center array pattern (e.g., "center":[52.28,-1.53])
64+ const GOOGLE_CENTER_ARRAY_RE = new RegExp (
65+ `"center"\\s*:\\s*\\[\\s*(${ NUMBER_PART } )\\s*,\\s*(${ NUMBER_PART } )\\s*\\]` ,
66+ "i" ,
67+ ) ;
5268
5369type ExpandedShortMapUrlResult = {
5470 expandedUrl : string ;
@@ -244,11 +260,91 @@ function parseGoogleStaticMapCenterFromText(input: string): { lat: number; lon:
244260 return sanitizeCoordinates ( { lat, lon } ) ;
245261}
246262
263+ function parseGoogleJsonLatLngFromText ( input : string ) : { lat : number ; lon : number } | null {
264+ if ( ! input ) return null ;
265+
266+ const match = input . match ( GOOGLE_JSON_LAT_LNG_RE ) ;
267+ if ( ! match ) return null ;
268+
269+ const [ , latRaw = "" , lngRaw = "" ] = match ;
270+ const lat = Number ( latRaw ) ;
271+ const lon = Number ( lngRaw ) ;
272+ if ( ! Number . isFinite ( lat ) || ! Number . isFinite ( lon ) ) return null ;
273+ if ( Math . abs ( lat ) > 90 || Math . abs ( lon ) > 180 ) return null ;
274+ // Reject super "round" tiny values that are common noise in arrays
275+ if ( Math . abs ( lat ) <= 2 && Math . abs ( lon ) <= 2 ) return null ;
276+
277+ return sanitizeCoordinates ( { lat, lon } ) ;
278+ }
279+
280+ function parseGoogleJsonLngLatFromText ( input : string ) : { lat : number ; lon : number } | null {
281+ if ( ! input ) return null ;
282+
283+ const match = input . match ( GOOGLE_JSON_LNG_LAT_RE ) ;
284+ if ( ! match ) return null ;
285+
286+ const [ , lngRaw = "" , latRaw = "" ] = match ;
287+ const lat = Number ( latRaw ) ;
288+ const lon = Number ( lngRaw ) ;
289+ if ( ! Number . isFinite ( lat ) || ! Number . isFinite ( lon ) ) return null ;
290+ if ( Math . abs ( lat ) > 90 || Math . abs ( lon ) > 180 ) return null ;
291+ if ( Math . abs ( lat ) <= 2 && Math . abs ( lon ) <= 2 ) return null ;
292+
293+ return sanitizeCoordinates ( { lat, lon } ) ;
294+ }
295+
296+ function parseGoogleCenterArrayFromText ( input : string ) : { lat : number ; lon : number } | null {
297+ if ( ! input ) return null ;
298+
299+ const match = input . match ( GOOGLE_CENTER_ARRAY_RE ) ;
300+ if ( ! match ) return null ;
301+
302+ const [ , latRaw = "" , lonRaw = "" ] = match ;
303+ const lat = Number ( latRaw ) ;
304+ const lon = Number ( lonRaw ) ;
305+ if ( ! Number . isFinite ( lat ) || ! Number . isFinite ( lon ) ) return null ;
306+ if ( Math . abs ( lat ) > 90 || Math . abs ( lon ) > 180 ) return null ;
307+ if ( Math . abs ( lat ) <= 2 && Math . abs ( lon ) <= 2 ) return null ;
308+
309+ return sanitizeCoordinates ( { lat, lon } ) ;
310+ }
311+
312+ function parseGoogleDecimalPairFromText ( input : string ) : { lat : number ; lon : number } | null {
313+ if ( ! input ) return null ;
314+
315+ // Scan for decimal pairs with 4+ decimal places
316+ const regex = new RegExp ( GOOGLE_DECIMAL_PAIR_RE ) ;
317+ let match = regex . exec ( input ) ;
318+ while ( match !== null ) {
319+ const groups = match . groups as { lat ?: string ; lon ?: string } | undefined ;
320+ if ( groups ?. lat && groups ?. lon ) {
321+ const lat = Number ( groups . lat ) ;
322+ const lon = Number ( groups . lon ) ;
323+ if (
324+ Number . isFinite ( lat ) &&
325+ Number . isFinite ( lon ) &&
326+ Math . abs ( lat ) <= 90 &&
327+ Math . abs ( lon ) <= 180 &&
328+ ! ( Math . abs ( lat ) <= 2 && Math . abs ( lon ) <= 2 )
329+ ) {
330+ return sanitizeCoordinates ( { lat, lon } ) ;
331+ }
332+ }
333+ match = regex . exec ( input ) ;
334+ }
335+
336+ return null ;
337+ }
338+
247339function parseGoogleCoordinatesFromText ( input : string ) : { lat : number ; lon : number } | null {
248340 return (
249341 parseGooglePreviewCoordinatesFromText ( input ) ??
250342 parseGoogleStateCoordinatesFromText ( input ) ??
251- parseGoogleStaticMapCenterFromText ( input )
343+ parseGoogleStaticMapCenterFromText ( input ) ??
344+ parseGoogleJsonLatLngFromText ( input ) ??
345+ parseGoogleJsonLngLatFromText ( input ) ??
346+ parseGoogleCenterArrayFromText ( input ) ??
347+ parseGoogleDecimalPairFromText ( input )
252348 ) ;
253349}
254350
@@ -385,10 +481,15 @@ async function fetchMapPageText(
385481 timeoutMs ,
386482 ) ;
387483 console . info ( "[share.debug] fetch_simplified_result_length" , simpleText ?. length ?? 0 ) ;
388- // Check if we still hit consent
389- const simpleUrl =
390- typeof simpleResponse . url === "string" ? parseUrl ( simpleResponse . url ) : null ;
391- if ( simpleUrl && ! isGoogleConsentHost ( simpleUrl . hostname ) ) {
484+ // Return the simplified HTML even if it still hit consent - let parsing try
485+ if ( simpleText ) {
486+ const simpleUrl =
487+ typeof simpleResponse . url === "string" ? parseUrl ( simpleResponse . url ) : null ;
488+ if ( simpleUrl && ! isGoogleConsentHost ( simpleUrl . hostname ) ) {
489+ console . info ( "[share.debug] fetch_simplified_success_no_consent" ) ;
490+ } else {
491+ console . info ( "[share.debug] fetch_simplified_still_consent_but_returning_html" ) ;
492+ }
392493 return simpleText ;
393494 }
394495 }
0 commit comments