2eb14fc0378432977d83366a3211c67f8913018d max Mon Sep 21 06:21:51 2026 -0700 hgc and hgTrackUi: open off-site links in a new tab, with rel="noopener noreferrer" offsiteLinksToNewTab() in utils.js runs over the rendered page alongside addHgsidToLinks() and gives every http(s) link whose host is not ours a target=_blank it does not already have, plus rel="noopener noreferrer". Without noopener the page that opens keeps a handle on the tab it came from and can navigate it; without noreferrer the Referer header carries our own URL, which has the session id in it. The href on a track description page is written by whoever wrote the track or the hub, so neither is theoretical. A mailto: or an ftp: link is left alone, and so is every link that stays on this server. jsAddHgsidToLinks() now emits both calls and is renamed jsFixUpPageLinks(). hgTracks.js runs the same pass over the track description popup: the replace it does before that already puts a target on every link in there, so what this adds is the rel on the ones that leave. refs #38380 diff --git src/hg/inc/jsHelper.h src/hg/inc/jsHelper.h index 1d81aae568b..03c95649850 100644 --- src/hg/inc/jsHelper.h +++ src/hg/inc/jsHelper.h @@ -153,35 +153,37 @@ void jsBeginCollapsibleSectionFontSize(struct cart *cart, char *track, char *section, char *sectionTitle, boolean isOpenDefault, char *fontSize); /* Make the hidden input, collapse/expand button and <TR id=...> needed for utils.js's * setTableRowVisibility(). Caller needs to have already created a <TABLE> and <FORM>. */ void jsBeginCollapsibleSectionOldStyle(struct cart *cart, char *track, char *section, char *sectionTitle, boolean isOpenDefault); /* Make the hidden input, collapse/expand button and <TR id=...> needed for utils.js's * setTableRowVisibility(). Caller needs to have already created a <TABLE> and <FORM>. * With support for varying font size */ void jsEndCollapsibleSection(); /* End the collapsible <TR id=...>. */ -void jsAddHgsidToLinks(); -/* Emit the javascript that gives every link on this page to one of our own CGIs the current - * session id. See addHgsidToLinks() in utils.js: a track description page comes from - * whoever wrote the track or the hub, so the session id cannot be substituted into it on - * the server without also handing it to an <img> that points somewhere else. */ +void jsFixUpPageLinks(); +/* Emit the javascript that tidies up this page's links once it is rendered: our own CGI + * links get the current session id, and links that leave this server open in a new tab with + * rel="noopener noreferrer". See addHgsidToLinks() and offsiteLinksToNewTab() in utils.js. + * A track description page comes from whoever wrote the track or the hub, so the session id + * cannot be substituted into it on the server without also handing it to an <img> that + * points somewhere else. */ void jsReloadOnBackButton(struct cart *cart); /* Add some javascript to detect that the back button (or reload) has been pressed, * and to resubmit in that case to redraw the page with the latest cart contents. */ // --- Genome browser specific json stuff - see also inc/json.h for more generic stuff void jsonDyStringPrint(struct dyString *dy, struct jsonElement *json, char *name, int indentLevel); // dyStringPrint out a jsonElement, indentLevel -1 means no indenting void jsonPrint(struct jsonElement *json, char *name, int indentLevel); // print out a jsonElement and children using hPrintf, and for indentLevel >=0 // bracketing with comments. See also jsonPrintToFile. void jsonErrPrintf(struct dyString *ds, char *format, ...)