var externalLinkClick = function(e)
{
if (e.isDefaultPrevented())
{
return;
}
var $this = $(this),
href = $this.attr('href'),
lastEvent = $this.data('blank-handler-last');
if (!href)
{
return;
}
if (href.match(/^[a-z]:/i) && !href.match(/^https?:/i))
{
// ignore canonical but non http(s) links
return;
}
href = XenForo.canonicalizeUrl(href);
var regex = new RegExp('^[a-z]+://' + location.host + '(/|$|:)', 'i');
if (regex.test(href) && !$this.hasClass('ProxyLink'))
{
// if the link is local, then don't do the special processing... unless it's a proxy link
// so it's likely to be external after the redirect
return;
}
// we may have a direct click event and a bubbled event. Ensure they don't both fire.
if (lastEvent && lastEvent == e.timeStamp)
{
return;
}
$this.data('blank-handler-last', e.timeStamp);
var ua = navigator.userAgent,
isOldIE = ua.indexOf('MSIE') !== -1,
isSafari = ua.indexOf('Safari') !== -1 && ua.indexOf('Chrome') == -1,
isGecko = ua.indexOf('Gecko/') !== -1;
if (e.shiftKey && isGecko)
{
// Firefox doesn't trigger when holding shift. If the code below runs, it will force
// opening in a new tab instead of a new window, so stop. Note that Chrome still triggers here,
// but it does open in a new window anyway so we run the normal code.
return;
}
if (isSafari && (e.shiftKey || e.altKey))
{
// this adds to reading list or downloads instead of opening a new tab
return;
}
if (isOldIE)
{
// IE has mitigations for this and this blocks referrers
return;
}
// now run the opener clearing
if (isSafari)
{
// Safari doesn't work with the other approach
// Concept from: https://github.com/danielstjules/blankshield
var $iframe, iframeDoc, $script;
$iframe = $('<iframe style="display: none" />').appendTo(document.body);
iframeDoc = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
iframeDoc.__href = href; // set this so we don't need to do an eval-type thing
$script = $('<script />', iframeDoc);
$script[0].text = 'window.opener=null;' +
'window.parent=null;window.top=null;window.frameElement=null;' +
'window.open(document.__href).opener = null;';
iframeDoc.body.appendChild($script[0]);
$iframe.remove();
}
else
{
// use this approach for the rest to maintain referrers when possible
var w = window.open(href);
try
{
// this can potentially fail, don't want to break
w.opener = null;
}
catch (e) {}
}
e.preventDefault();
};
$(document)
.on('click', 'a[target=_blank]', externalLinkClick)
.on('focusin', 'a[target=_blank]', function(e)
{
// This approach is taken because middle click events do not bubble. This is a way of
// getting the equivalent of event bubbling on middle clicks in Chrome.
var $this = $(this);
if ($this.data('blank-handler'))
{
return;
}
$this.data('blank-handler', true)
.click(externalLinkClick);
});