@gitlab/ui
Version:
GitLab UI Components
68 lines (65 loc) • 1.5 kB
JavaScript
import Vue from 'vue';
const getBaseURL = () => {
const {
protocol,
host
} = window.location;
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 (e) {
return false;
}
};
const transform = function (el) {
let {
arg: {
skipSanitization = false
} = {}
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (skipSanitization) {
return;
}
const {
href,
target,
rel
} = el;
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 };