PageSourceSearch

https://www.telia.no/static/js/mobile-safari-video-fix.js?h=0624200-448052dd3712e66f15ac1bb35c8db3a3

js telia.no collected 2026-10-01 10:34:05 UTC 5,405 bytes, 139 lines download raw bytes

1// Mobile Safari Video Poster Fix - Sets poster attribute to video src value
2(function() {
3    'use strict';
4    
5    function isMobileSafari() {
6        const userAgent = navigator.userAgent;
7        const isIOS = /iPad|iPhone|iPod/.test(userAgent);
8        
9        const isSafari = userAgent.includes('Safari') && !userAgent.includes('Chrome') && !userAgent.includes('CriOS') && !userAgent.includes('FxiOS');
10        const isMobile = userAgent.includes('Mobile');
11        
12        const result = (isIOS && isSafari) || (isMobile && isSafari);
13        
14        return result;
15    }
16
17    if (!isMobileSafari()) {
18        return;
19    }
20    
21    function extractFirstFrame(video) {
22        return new Promise((resolve, reject) => {
23            const canvas = document.createElement('canvas');
24            const context = canvas.getContext('2d');
25
26            function captureFrame() {
27                try {
28                    canvas.width = video.videoWidth || 640;
29                    canvas.height = video.videoHeight || 360;
30
31                    context.drawImage(video, 0, 0, canvas.width, canvas.height);
32                    
33                    const dataURL = canvas.toDataURL('image/jpeg', 0.8);
34                    resolve(dataURL);
35                } catch (error) {
36                    console.error('Error extracting frame:', error);
37                    reject(error);
38                }
39            }
40            
41            function seekAndCapture() {                
42                video.setAttribute('preload', 'metadata');
43                video.currentTime = 0;
44                
45                const onSeeked = () => {
46                    video.removeEventListener('seeked', onSeeked);
47                    setTimeout(captureFrame, 100);
48                };
49                
50                const onCanPlay = () => {
51                    video.removeEventListener('canplay', onCanPlay);
52                    video.addEventListener('seeked', onSeeked, { once: true });
53                    video.currentTime = 0;
54                };
55                
56                const onLoadedMetadata = () => {
57                    video.removeEventListener('loadedmetadata', onLoadedMetadata);
58                    
59                    if (video.readyState >= 1) {
60                        onCanPlay();
61                    } else {
62                        video.addEventListener('canplay', onCanPlay, { once: true });
63                    }
64                };
65                
66                if (video.readyState >= 1) {
67                    onCanPlay();
68                } else {
69                    video.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
70                    video.load();
71                }
72                
73                setTimeout(() => {
74                    video.removeEventListener('seeked', onSeeked);
75                    video.removeEventListener('canplay', onCanPlay);
76                    video.removeEventListener('loadedmetadata', onLoadedMetadata);
77                    console.error('Timeout waiting for video to be ready for frame extraction');
78                    reject(new Error('Timeout waiting for video frame extraction'));
79                }, 8000);
80            }
81            
82            if (video.readyState >= 2 && video.videoWidth > 0) {
83                captureFrame();
84            } else {
85                seekAndCapture();
86            }
87        });
88    }
89    
90    function fixVideoPosters() {
91        const videos = document.querySelectorAll('video[data-mobile-safari-video="true"]');
92        
93        videos.forEach(async (video) => {
94            const src = video.getAttribute('src') || video.currentSrc;
95            
96            video.removeAttribute('autoplay');
97            video.removeAttribute('muted');
98            video.removeAttribute('playsinline');
99            
100            const posterValue = video.getAttribute('poster');
101            const needsPoster = !posterValue || posterValue.trim() === '';
102            
103            if (needsPoster) {
104                try {
105                    // Extract first frame as poster
106                    const posterDataURL = await extractFirstFrame(video);
107                    video.setAttribute('poster', posterDataURL);
108                } catch (error) {
109                    console.warn('Failed to extract frame, fallback to src as poster:', error);
110                    // Fallback to using video src as poster
111                    if (src) {
112                        video.setAttribute('poster', src);
113                    } else {
114                        // Check for source elements within the video
115                        const sourceElement = video.querySelector('source');
116                        if (sourceElement) {
117                            const sourceSrc = sourceElement.getAttribute('src');
118                            if (sourceSrc) {
119                                video.setAttribute('poster', sourceSrc);
120                            }
121                        }
122                    }
123                }
124                
125                video.removeAttribute('data-mobile-safari-video');
126            }
127            
128            if (!video.paused) {
129                video.pause();
130            }
131        });
132    }
133    
134    if (document.readyState === 'loading') {
135        document.addEventListener('DOMContentLoaded', fixVideoPosters);
136    } else {
137        fixVideoPosters();
138    }
139})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.