@atlaskit/adf-schema
Version:
Shared package that contains the ADF-schema (json) and ProseMirror node/mark specs
128 lines (118 loc) • 5.86 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.LINK_REGEXP = void 0;
exports.getLinkMatch = getLinkMatch;
exports.isRootRelative = isRootRelative;
exports.linkifyMatch = exports.linkify = exports.isSafeUrl = void 0;
exports.normalizeUrl = normalizeUrl;
var _linkifyIt = _interopRequireDefault(require("linkify-it"));
// @ts-nocheck
/**
* This file has been partially duplicated in packages/linking-platform/linking-common/src/url.ts
* Any changes made here should be mirrored there.
* Ticket for dedeplication: https://product-fabric.atlassian.net/browse/EDM-7138
* Ticket for fixing linkification of filename-like urls: https://product-fabric.atlassian.net/browse/EDM-7190
*/
var whitelistedURLPatterns = [/^http[s\u017F]?:\/\//im, /^ftp[s\u017F]?:\/\//im, /^gopher:\/\//im, /^integrity:\/\//im, /^file:\/\//im, /^[s\u017F]mb:\/\//im, /^dynamic[s\u017F]nav:\/\//im, /^jamf[s\u017F]elf[s\u017F]ervice:\/\//im, /^\//im, /^mailto:/im, /^[s\u017F][k\u212A]ype:/im, /^callto:/im, /^facetime:/im, /^git:/im, /^irc6?:/im, /^new[s\u017F]:/im, /^nntp:/im, /^feed:/im, /^cv[s\u017F]:/im, /^[s\u017F]vn:/im, /^mvn:/im, /^[s\u017F][s\u017F]h:/im, /^[s\u017F]cp:\/\//im, /^[s\u017F]ftp:\/\//im, /^itm[s\u017F]:/im,
// This is not a valid notes link, but we support this pattern for backwards compatibility
/^note[s\u017F]:/im, /^note[s\u017F]:\/\//im, /^hipchat:\/\//im,
// This is not a valid sourcetree link, but we support this pattern for backwards compatibility
/^[s\u017F]ourcetree:/im, /^[s\u017F]ourcetree:\/\//im, /^urn:/im, /^tel:/im, /^xmpp:/im, /^telnet:/im, /^vnc:/im, /^rdp:/im, /^what[s\u017F]app:/im, /^[s\u017F]lac[k\u212A]:/im, /^[s\u017F]ip[s\u017F]?:/im, /^magnet:/im, /^#/im];
/**
* Please notify the Editor Mobile team (Slack: #help-mobilekit) if the logic for this changes.
*/
var isSafeUrl = exports.isSafeUrl = function isSafeUrl(url) {
var urlTrimmed = url.trim();
if (urlTrimmed.length === 0) {
return true;
}
return whitelistedURLPatterns.some(function (p) {
return p.test(urlTrimmed);
});
};
var linkify = exports.linkify = (0, _linkifyIt.default)();
linkify.add('sourcetree:', 'http:');
linkify.add('jamfselfservice:', 'http:');
var urlWithoutSpacesValidator = {
validate: /(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+/
};
// `tel:` URI spec is https://datatracker.ietf.org/doc/html/rfc3966
// We're not validating the phone number or separators - but if there's a space it definitely isn't a valid `tel:` URI
linkify.add('tel:', urlWithoutSpacesValidator);
// https://datatracker.ietf.org/doc/html/rfc8089
linkify.add('file:', urlWithoutSpacesValidator);
linkify.add('notes:', 'http:');
var tlds = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
var tlds2Char = 'a[cdefgilmnoqrtuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrtuvwxyz]|n[acefgilopruz]|om|p[aefghkmnrtw]|qa|r[eosuw]|s[abcdegijklmnrtuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]';
tlds.push(tlds2Char);
linkify.tlds(tlds, false);
// linkify-it mishandles closing braces on long urls, so we preference using our own regex first:
// https://product-fabric.atlassian.net/browse/ED-13669
var LINK_REGEXP = exports.LINK_REGEXP = /(https?|ftp|jamfselfservice|gopher|dynamicsnav|integrity|file|smb):\/\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+/;
/** Attempt to find a link match using a regex string defining a URL */
var linkifyMatch = exports.linkifyMatch = function linkifyMatch(text) {
if (!LINK_REGEXP.test(text)) {
return [];
}
var matches = [];
var startpos = 0;
var substr;
substr = text.substr(startpos);
while (substr) {
var link = (substr.match(LINK_REGEXP) || [''])[0];
if (link) {
var index = substr.search(LINK_REGEXP);
var start = index >= 0 ? index + startpos : index;
var end = start + link.length;
matches.push({
index: start,
lastIndex: end,
raw: link,
url: link,
text: link,
schema: ''
});
startpos += end;
substr = text.substr(startpos);
} else {
break;
}
}
return matches;
};
/**
* Attempt to find a link match. Tries to use our regex search first.
* If this doesn't match (e.g. no protocol), try using linkify-it library.
* Returns null if url string empty or no string given, or if no match found.
*/
function getLinkMatch(str) {
if (!str) {
return null;
}
// linkify-it mishandles closing braces on long urls, so we preference using our own regex first:
// https://product-fabric.atlassian.net/browse/ED-13669
var match = linkifyMatch(str);
if (!match.length) {
match = linkify.match(str);
}
return match && match[0];
}
/**
* Adds protocol to url if needed.
* Returns empty string if no url given or if no link match found.
*/
function normalizeUrl(url) {
var match = getLinkMatch(url);
return match && match.url || '';
}
/**
* checks if root relative link
*/
function isRootRelative(url) {
// Support `#top` and `#` special references as per:
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#linking_to_an_element_on_the_same_page
return url.startsWith('/') || url === '#top' || url === '#';
}