@@ -18,8 +18,13 @@ interface ImageLightboxProps
1818 width ?: number ;
1919}
2020
21- const getImageUrl = ( src : string , imgPath : string ) : string =>
22- isExternalImage ( src ) ? src : imgPath ;
21+ const getImageUrl = ( src : string , imgPath : string ) : string => {
22+ if ( isExternalImage ( src ) ) {
23+ // Normalize protocol-relative URLs to use https:
24+ return src . startsWith ( '//' ) ? `https:${ src } ` : src ;
25+ }
26+ return imgPath ;
27+ } ;
2328
2429type ValidDimensions = {
2530 height : number ;
@@ -57,25 +62,32 @@ export function ImageLightbox({
5762 ! ! dimensions && ( ! isExternalImage ( src ) || isAllowedRemoteImage ( src ) ) ;
5863
5964 const openInNewTab = ( ) => {
60- window . open ( getImageUrl ( src , imgPath ) , '_blank' ) ;
65+ window . open ( getImageUrl ( src , imgPath ) , '_blank' , 'noopener,noreferrer' ) ;
6166 } ;
6267
6368 const handleClick = ( e : React . MouseEvent ) => {
6469 // Middle-click or Ctrl/Cmd+click opens in new tab
6570 if ( e . button === 1 || e . ctrlKey || e . metaKey ) {
6671 e . preventDefault ( ) ;
72+ e . stopPropagation ( ) ;
6773 openInNewTab ( ) ;
6874 return ;
6975 }
70- // Regular click falls through to Dialog.Trigger
76+ // Regular click opens lightbox - let it bubble to Dialog.Trigger
7177 } ;
7278
7379 const handleKeyDown = ( e : React . KeyboardEvent ) => {
74- if ( ( e . key === 'Enter' || e . key === ' ' ) && ( e . ctrlKey || e . metaKey ) ) {
80+ if ( e . key === 'Enter' || e . key === ' ' ) {
81+ if ( e . ctrlKey || e . metaKey ) {
82+ e . preventDefault ( ) ;
83+ e . stopPropagation ( ) ;
84+ openInNewTab ( ) ;
85+ return ;
86+ }
87+ // Regular Enter/Space should open lightbox
7588 e . preventDefault ( ) ;
76- openInNewTab ( ) ;
89+ setOpen ( true ) ;
7790 }
78- // Regular Enter/Space falls through to Dialog.Trigger
7991 } ;
8092
8193 // Filter out props that are incompatible with Next.js Image component
0 commit comments