@@ -12,6 +12,17 @@ import { now, yieldToPage } from './GleapCaptureTasks';
1212export const MAX_CAPTURE_EDGE = 2560 ;
1313const JPEG_QUALITY = 0.85 ;
1414const TRANSPARENT_GIF = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' ;
15+ // An <img> the render can't download (cross-origin without CORS headers, so the canvas may not read
16+ // it) gets a neutral tint instead of an empty hole, so the screenshot doesn't look like the app lost
17+ // the image. Stretches to any box. The tab capture and the classic server render keep such images.
18+ const IMAGE_PLACEHOLDER =
19+ 'data:image/svg+xml;charset=utf-8,' +
20+ encodeURIComponent (
21+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1" preserveAspectRatio="none">' +
22+ '<rect width="1" height="1" fill="rgb(128,128,128)" fill-opacity="0.16"/></svg>'
23+ ) ;
24+ // CSS background images stay transparent (usually decoration).
25+ const imagePlaceholder = ( imageDom ) => ( imageDom ? IMAGE_PLACEHOLDER : TRANSPARENT_GIF ) ;
1526
1627// Gleap's own UI never appears in a capture: the widget, launcher, notifications, banners, modals,
1728// tooltips, tours, the admin helper and the capture UI itself.
@@ -1313,6 +1324,26 @@ const createImageFetcher = () => {
13131324 }
13141325} ;
13151326
1327+ // The render downloads every image and font again (fetch). The logger is paused meanwhile, but the
1328+ // browser still lists those downloads in Resource Timing: mark them so they never show up as the
1329+ // app's requests (or failures) in the logs.
1330+ const ignoreInNetworkLogs = ( url , since ) => {
1331+ try {
1332+ if ( typeof url === 'string' && url . indexOf ( 'data:' ) !== 0 && url . indexOf ( 'blob:' ) !== 0 ) {
1333+ GleapNetworkIntercepter . getInstance ( ) . ignoreInternalRequest ( url , null , since ) ;
1334+ }
1335+ } catch ( exp ) { }
1336+ } ;
1337+
1338+ // Wraps createImageFetcher's result: every image the render asks for is marked before the download.
1339+ const createTrackedImageFetcher = ( since ) => {
1340+ const fetchAway = createImageFetcher ( ) ;
1341+ return ( url ) => {
1342+ ignoreInNetworkLogs ( url , since ) ;
1343+ return fetchAway ? fetchAway ( url ) : Promise . resolve ( false ) ;
1344+ } ;
1345+ } ;
1346+
13161347// Network logging is paused while renders download assets; overlapping renders share one pause.
13171348let networkLogPauses = 0 ;
13181349let networkLogsWereStopped = false ;
@@ -1374,6 +1405,7 @@ export const renderDom = ({ privacyOptions, maskSelectors, isActive }) =>
13741405
13751406 // Its asset downloads (fonts, images) are not the app's traffic: keep them out of the network logs.
13761407 const resumeNetworkLogs = pauseNetworkLogs ( ) ;
1408+ const renderStart = now ( ) ;
13771409 let context = null ;
13781410 let sandbox = null ;
13791411 let settled = false ;
@@ -1383,6 +1415,12 @@ export const renderDom = ({ privacyOptions, maskSelectors, isActive }) =>
13831415 clearTimeout ( deadline ) ;
13841416 clearInterval ( watch ) ;
13851417 if ( context ) {
1418+ try {
1419+ // Fonts and CSS assets don't pass the image fetcher.
1420+ if ( context . requests && typeof context . requests . forEach === 'function' ) {
1421+ context . requests . forEach ( ( request , url ) => ignoreInNetworkLogs ( url , renderStart ) ) ;
1422+ }
1423+ } catch ( exp ) { }
13861424 try {
13871425 // Removes the sandbox as well.
13881426 destroyContext ( context ) ;
@@ -1460,7 +1498,13 @@ export const renderDom = ({ privacyOptions, maskSelectors, isActive }) =>
14601498 overflow : 'visible' ,
14611499 } ,
14621500 features : { restoreScrollPosition : false } ,
1463- fetchFn : createImageFetcher ( ) ,
1501+ fetchFn : createTrackedImageFetcher ( renderStart ) ,
1502+ // Passing `fetch` replaces modern-screenshot's defaults: keep its cache setting.
1503+ fetch : {
1504+ requestInit : { cache : 'force-cache' } ,
1505+ bypassingCache : false ,
1506+ placeholderImage : imagePlaceholder ,
1507+ } ,
14641508 // How long to wait for images that are still loading; the render itself gets longer below.
14651509 timeout : imagesLoadingInViewport ( ) ? 3000 : 50 ,
14661510 } ) ;
0 commit comments