11import { requestUrl } from 'obsidian' ;
22import { Parser , ParsedLinkData } from './parser' ;
33import { ConcurrencyLimiter } from '../utils/concurrencyLimiter' ;
4+ import { getImageDimensions } from './utils/imageUtils' ;
45
56const electronPkg = require ( 'electron' ) ;
67
@@ -46,33 +47,88 @@ export class LocalParser extends Parser {
4647 }
4748
4849 meetsCriteria ( element : Element ) : boolean {
49- //If inline - display:none
50+ // If inline - display:none
5051 if ( / d i s p l a y : \s * n o n e / . test ( element . getAttribute ( 'style' ) ) ) {
5152 return false ;
5253 }
5354
54- //hide images in navigation bar/header
55+ // Check for logo images which should be allowed even in headers
56+ if ( element instanceof HTMLImageElement ) {
57+ const src = element . getAttribute ( 'src' ) || '' ;
58+ const alt = element . getAttribute ( 'alt' ) || '' ;
59+
60+ // Allow images that are likely logos based on src or alt text
61+ if (
62+ src . toLowerCase ( ) . includes ( 'logo' ) ||
63+ alt . toLowerCase ( ) . includes ( 'logo' ) ||
64+ src . endsWith ( '.svg' ) // SVGs are often used for logos
65+ ) {
66+ this . debugLog ( '[Link Embed] Image - Allowing logo image:' , src ) ;
67+ return true ;
68+ }
69+ }
70+
71+ // Hide images in navigation bar/header, unless they're potential logos
5572 let contains_header = false ;
5673 element . classList . forEach ( ( val ) => {
57- if ( val . toLowerCase ( ) . contains ( 'header' ) ) {
74+ if ( val . toLowerCase ( ) . includes ( 'header' ) ) {
5875 contains_header = true ;
5976 }
6077 } ) ;
61- if ( element . id . toLowerCase ( ) . contains ( 'header' ) || contains_header ) {
78+
79+ if (
80+ ( element . id . toLowerCase ( ) . includes ( 'header' ) || contains_header ) &&
81+ ! ( element instanceof HTMLImageElement )
82+ ) {
6283 return false ;
6384 }
6485
65- //recurse until <html>
86+ // Recurse until <html>
6687 if ( element . parentElement != null ) {
6788 return this . meetsCriteria ( element . parentElement ) ;
6889 }
6990
7091 return true ;
7192 }
7293
73- getImage ( doc : Document , url : URL ) : string {
94+ // Method to verify if an image URL can be loaded
95+ private async verifyImageUrl (
96+ imgUrl : string ,
97+ failedUrls : Set < string > ,
98+ ) : Promise < string | null > {
99+ if ( failedUrls . has ( imgUrl ) ) return null ;
100+
101+ try {
102+ // Try to get image dimensions - this will verify the image loads
103+ const dimensions = await getImageDimensions ( imgUrl ) ;
104+ if ( dimensions ) {
105+ this . debugLog (
106+ '[Link Embed] Image - Successfully verified image loads:' ,
107+ imgUrl ,
108+ ) ;
109+ return imgUrl ;
110+ } else {
111+ this . debugLog (
112+ '[Link Embed] Image - Image failed to load properly:' ,
113+ imgUrl ,
114+ ) ;
115+ failedUrls . add ( imgUrl ) ;
116+ }
117+ } catch ( error ) {
118+ this . debugError (
119+ '[Link Embed] Image - Failed to load image:' ,
120+ imgUrl ,
121+ error ,
122+ ) ;
123+ failedUrls . add ( imgUrl ) ;
124+ }
125+ return null ;
126+ }
127+
128+ async getImage ( doc : Document , url : URL ) : Promise < string > {
74129 const baseEl = doc . querySelector ( 'base[href]' ) as HTMLBaseElement ;
75130 const base = ( baseEl && baseEl . href ) || url . href ;
131+ const failedUrls = new Set < string > ( ) ; // Track failed URLs
76132
77133 this . debugLog ( '[Link Embed] Image - Looking for image for:' , url . href ) ;
78134 this . debugLog ( '[Link Embed] Image - Base URL:' , base ) ;
@@ -81,26 +137,30 @@ export class LocalParser extends Parser {
81137 const og = doc . querySelector < HTMLMetaElement > (
82138 'head meta[property="og:image"]' ,
83139 ) ;
84- if ( og ) {
140+ if ( og && og . content ) {
85141 this . debugLog (
86142 '[Link Embed] Image - Found Open Graph image:' ,
87143 og . content ,
88144 ) ;
89- if ( og . content ) {
90- try {
91- const resolvedUrl = new URL ( og . content , base ) . href ;
92- this . debugLog (
93- '[Link Embed] Image - Resolved OG image URL:' ,
94- resolvedUrl ,
95- ) ;
96- return resolvedUrl ;
97- } catch ( error ) {
98- this . debugError (
99- '[Link Embed] Image - Error resolving OG image URL:' ,
100- error ,
101- ) ;
102- return og . content ;
103- }
145+ try {
146+ const resolvedUrl = new URL ( og . content , base ) . href ;
147+ this . debugLog (
148+ '[Link Embed] Image - Resolved OG image URL:' ,
149+ resolvedUrl ,
150+ ) ;
151+
152+ // Verify OG image loads
153+ const verifiedUrl = await this . verifyImageUrl (
154+ resolvedUrl ,
155+ failedUrls ,
156+ ) ;
157+ if ( verifiedUrl ) return verifiedUrl ;
158+ } catch ( error ) {
159+ this . debugError (
160+ '[Link Embed] Image - Error resolving OG image URL:' ,
161+ error ,
162+ ) ;
163+ // No longer trying with original content if URL resolution fails
104164 }
105165 }
106166
@@ -124,10 +184,10 @@ export class LocalParser extends Parser {
124184 this . debugLog (
125185 `[Link Embed] Image - Found ${ imgs . length } images for selector "${ sel } "` ,
126186 ) ;
187+
127188 for ( const img of imgs ) {
128- if ( ! this . meetsCriteria ( img ) ) {
129- continue ;
130- }
189+ if ( ! this . meetsCriteria ( img ) ) continue ;
190+
131191 const src = img . getAttribute ( 'src' ) ;
132192 if ( src ) {
133193 this . debugLog (
@@ -140,19 +200,27 @@ export class LocalParser extends Parser {
140200 '[Link Embed] Image - Resolved image URL:' ,
141201 resolvedUrl ,
142202 ) ;
143- return resolvedUrl ;
203+
204+ // Verify image loads
205+ const verifiedUrl = await this . verifyImageUrl (
206+ resolvedUrl ,
207+ failedUrls ,
208+ ) ;
209+ if ( verifiedUrl ) return verifiedUrl ;
144210 } catch ( error ) {
145211 this . debugError (
146212 '[Link Embed] Image - Error resolving image URL:' ,
147213 error ,
148214 ) ;
149- return src ;
215+ // No longer trying with original src if URL resolution fails
150216 }
151217 }
152218 }
153219 }
154220
155- this . debugLog ( '[Link Embed] Image - No suitable image found' ) ;
221+ this . debugLog (
222+ '[Link Embed] Image - No suitable image found or all images failed to load' ,
223+ ) ;
156224 return '' ;
157225 }
158226
@@ -377,9 +445,10 @@ export class LocalParser extends Parser {
377445 let uRL = new URL ( url ) ;
378446 this . debugLog ( '[Link Embed] Doc:' , doc ) ;
379447 let title = this . getTitle ( doc , uRL ) ;
380- let image = this . getImage ( doc , uRL ) ;
381448 let description = this . getDescription ( doc ) ;
382449 let favicon = this . getFavicon ( doc , uRL ) ;
450+ // Get image - now this is an async call
451+ let image = await this . getImage ( doc , uRL ) ;
383452
384453 // 1. First, process the raw data to extract basic information
385454 let processedData = this . process ( {
0 commit comments