import { wait } from '@proton/shared/lib/helpers/promise' ; import { MessageImage , MessageRemoteImage } from '../../logic/messages/messagesTypes' ; export const ATTRIBUTES = [ 'url' , 'xlink:href' , 'src' , 'srcset' , 'svg' , 'background' , 'poster' ] ; export const urlCreator = ( ) => window . URL || window . webkitURL ; export const removeProtonPrefix = ( match ) => { ATTRIBUTES . forEach ( ( attr ) => { const protonAttr = `proton-${ attr }` ; if ( match . hasAttribute ( protonAttr ) ) { match . setAttribute ( attr , match . getAttribute ( protonAttr ) as string ) ; match . removeAttribute ( protonAttr ) ; } } ) ; } ; interface LoadBackgroundImagesProps { images ? : MessageRemoteImage [ ] ; document ? : Element ; } export const loadBackgroundImages = ( { images , document } ) => { if ( ! document || ! images ) { return ; } const elementWithStyleTag = document ?. querySelectorAll ( '[style]' ) ; elementWithStyleTag ?. forEach ( ( element ) => { const styleAttribute = element . getAttribute ( 'style' ) ; if ( styleAttribute && styleAttribute . includes ( 'proton-url' ) ) { const rawUrlMatch = styleAttribute . match ( /proton-url\((.*?)\)/ ) ?. [ 1 ] ; const cleanUrlMatch = rawUrlMatch ?. replace ( /('|")/g , '' ) ; const preLoadedImage = images . find ( ( img ) => cleanUrlMatch === img . originalURL ) ; if ( preLoadedImage && preLoadedImage . url && rawUrlMatch ) { element . setAttribute ( 'style' , styleAttribute . replace ( rawUrlMatch , preLoadedImage . url ) . replace ( 'proton-url' , 'url' ) ) ; } } } ) ; } ; export const loadElementOtherThanImages = ( images , messageDocument ? ) => { const elementOtherThanImages = images . filter ( ( image ) => image . original ?. tagName !== 'IMG' ) ; const selector = ATTRIBUTES . map ( ( name ) => { if ( name === 'xlink:href' ) { return '[*|href]:not([href])' ; } return `[proton-${ name }]` ; } ) . join ( ',' ) ; const foundElements = messageDocument ? messageDocument . querySelectorAll ( selector ) : [ ] ; foundElements . forEach ( ( element ) => { ATTRIBUTES . forEach ( ( attr ) => { const protonAttr = `proton-${ attr }` ; if ( element . hasAttribute ( protonAttr ) ) { const elementValue = element . getAttribute ( protonAttr ) as string ; const elementWithOriginalURL = elementOtherThanImages . find ( ( el ) => { return elementValue === el . url ; } ) ; if ( elementWithOriginalURL && elementWithOriginalURL . url ) { element . setAttribute ( attr , elementWithOriginalURL . url ) ; } element . removeAttribute ( protonAttr ) ; } } ) ; } ) ; } ; const imageFailedWithProxy = ( image ) => ( image . error as any ) ?. data ?. Code === 2902 && ! image . tracker ; export const hasToSkipProxy = ( images = [ ] ) => { const remoteImages = images . filter ( ( image ) => image . type === 'remote' ) as MessageRemoteImage [ ] ; return remoteImages . every ( ( image ) => image . status === 'loaded' ) && remoteImages . some ( imageFailedWithProxy ) ; } ; export const loadRemoteImages = async ( useProxy , images , onLoadRemoteImagesProxy , onLoadRemoteImagesDirect ) => { await wait ( 0 ) ; const imagesToLoad = images . filter ( ( image ) => image . status === 'not-loaded' ) ; if ( useProxy ) { return onLoadRemoteImagesProxy ( imagesToLoad ) ; } return onLoadRemoteImagesDirect ( imagesToLoad ) ; } ; export const loadFakeImages = async ( images , onLoadFakeImagesProxy ) => { await wait ( 0 ) ; return onLoadFakeImagesProxy ( images ) ; } ; export const loadSkipProxyImages = async ( images , onLoadRemoteImagesDirect ) => { await wait ( 0 ) ; const imagesToLoad = images . filter ( imageFailedWithProxy ) ; return onLoadRemoteImagesDirect ( imagesToLoad ) ; } ;