UNPKG

@gitlab/ui

Version:
65 lines (62 loc) 1.74 kB
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 };