d5580b384522b44b2d374446d33304a1adf2e13a chmalee Mon Apr 20 14:05:06 2026 -0700 hgTracks: wrap setInHistory calls in try/catch, refs #37367 diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 37669810613..4731835736a 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -4460,31 +4460,39 @@ imageV2.markAsDirtyPage(); // vis of cfg change imageV2.drawHighlights(); if (typeof showMouseovers !== 'undefined' && showMouseovers) { convertTitleTagsToMouseovers(); } return; } } imageV2.loadRemoteTracks(); makeItemsByDrag.load(); imageV2.loadSuggestBox(); imageV2.drawHighlights(); if (imageV2.backSupport) { + // try/catch: browser extensions that proxy history.pushState can throw + // "Permission denied to access property apply" under Firefox cross-origin + // security. Swallow it so zoom/drag still complete; only the URL-bar + // position update is lost. + try { imageV2.setInHistory(false); // Set this new position into History stack + } catch (e) { + console.warn("setInHistory failed, continuing:", e); + } } else { imageV2.markAsDirtyPage(); } if (typeof showMouseovers !== 'undefined' && showMouseovers) { convertTitleTagsToMouseovers(); } if(typeof window.igvBrowser !== "undefined") { window.igvBrowser.search(genomePos.get()); } }, updateImgForId: function (html, id, fullImageReload, newJsonRec) { // update row in imgTbl for given id. // return true if we successfully pull slice for id and update it in imgTrack. var newTr = $(html).find("tr[id='tr_" + id + "']"); @@ -5187,31 +5195,36 @@ // Have vis box changes update cart through ajax. This helps keep page/cart in sync. vis.initForAjax(); // We reach here from these possible paths: // A) Forward: Full page retrieval: hgTracks is first navigated to (or chrom change) // B) Back-button past a full retrieval (B in: ->A,->b,->c(full page),->d,<-c,<-B(again)) // B1) Dirty page: at least one non-position change (e.g. 1 track vis changed in b) // B2) Clean page: only position changes from A->b->| var curPos = encodeURIComponent(genomePos.get().replace(/,/g,'')); var curDbPos = hgTracks.lastDbPos; var cachedPos = imageV2.history.getState().data.position; var cachedDbPos = imageV2.history.getState().data.lastDbPos; // A) Forward: Full page retrieval: hgTracks is first navigated to (or chrom change) if (!cachedDbPos) { // Not a back-button operation // set the current position into history outright (will replace). No img update needed + // try/catch: see comment on the other setInHistory call site. + try { imageV2.setInHistory(true); + } catch (e) { + console.warn("setInHistory failed, continuing:", e); + } } else { // B) Back-button past a full retrieval genomePos.set(decodeURIComponent(cachedPos)); // B1) Dirty page: at least one non-position change if (imageV2.isDirtyPage()) { imageV2.markAsCleanPage(); // Only forcing a full page refresh if chrom changes var cachedChrom = decodeURIComponent(cachedPos).split(':')[0]; var curChrom = decodeURIComponent( curPos).split(':')[0]; if (cachedChrom === curChrom) { imageV2.navigateInPlace("db="+getDb()+"&"+cachedDbPos, null, false); } else { imageV2.fullReload(); } } else { // B2) Clean page: only position changes from a->b