@gitlab/ui
Version:
GitLab UI Components
65 lines (62 loc) • 1.74 kB
JavaScript
import Vue from 'vue';
const getBaseURL = () => {
const _window$location = window.location,
protocol = _window$location.protocol,
host = _window$location.host;
return `${protocol}//${host}`;
};
const isTargetBlank = target => {
return target === '_blank';
};
const isExternalURL = (target, hostname) => {
return isTargetBlank(target) && hostname !== window.location.hostname;
};
const secureRel = rel => {
const rels = rel ? rel.trim().split(' ') : [];
if (!rels.includes('noopener')) {
rels.push('noopener');
}
if (!rels.includes('noreferrer')) {
rels.push('noreferrer');
}
return rels.join(' ');
};
const isSafeURL = url => {
try {
const parsedURL = new URL(url, getBaseURL());
return ['http:', 'https:', 'mailto:', 'ftp:'].includes(parsedURL.protocol);
} catch {
return false;
}
};
const transform = function (el) {
let _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$arg = _ref.arg,
_ref$arg2 = _ref$arg === void 0 ? {} : _ref$arg,
_ref$arg2$skipSanitiz = _ref$arg2.skipSanitization,
skipSanitization = _ref$arg2$skipSanitiz === void 0 ? false : _ref$arg2$skipSanitiz;
if (skipSanitization) {
return;
}
const href = el.href,
target = el.target,
rel = el.rel;
if (!isSafeURL(href)) {
el.href = 'about:blank';
}
if (isTargetBlank(target)) {
el.rel = secureRel(rel);
}
};
const SafeLinkDirective = {
inserted: transform,
update: function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
Vue.nextTick(() => {
transform(...args);
});
}
};
export { SafeLinkDirective, isExternalURL };