const re = { http: /.*?:\/\//g, url: /(\s|^)((https?|ftp):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\w-\/\?\=\#\.])*/gi, image: /\.(jpe?g|png|gif)$/, email: /(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/gi, cloudmusic: /http:\/\/music\.163\.com\/#\/song\?id=(\d+)/i, kickstarter: /(https?:\/\/www\.kickstarter\.com\/projects\/\d+\/[a-zA-Z0-9_-]+)(\?\w+\=\w+)?/i, youtube: /https?:\/\/www\.youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)(\?\w+\=\w+)?/i, vimeo: /https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/[^\/]*\/videos\/|album\/\d+\/video\/|video\/|)(\d+)(?:$|\/|\?)/i, youku: /https?:\/\/v\.youku\.com\/v_show\/id_([a-zA-Z0-9_\=-]+).html(\?\w+\=\w+)?(\#\w+)?/i, }; /** * AutoLink constructor function * * @param {String} text * @param {Object} options * @constructor */ function AutoLink(string, options = {}) { this.string = options.safe ? safe_tags_replace(string) : string; this.options = options; this.attrs = ""; this.linkAttr = ""; this.imageAttr = ""; if (this.options.sharedAttr) { this.attrs = getAttr(this.options.sharedAttr); } if (this.options.linkAttr) { this.linkAttr = getAttr(this.options.linkAttr); } if (this.options.imageAttr) { this.imageAttr = getAttr(this.options.imageAttr); } } AutoLink.prototype = { constructor: AutoLink, /** * call relative functions to parse url/email/image * * @returns {String} */ parse: function () { var shouldReplaceImage = defaultTrue(this.options.image); var shouldRelaceEmail = defaultTrue(this.options.email); var shouldRelaceBr = defaultTrue(this.options.br); var result = ""; if (!shouldReplaceImage) { result = this.string.replace(re.url, this.formatURLMatch.bind(this)); } else { result = this.string.replace(re.url, this.formatIMGMatch.bind(this)); } if (shouldRelaceEmail) { result = this.formatEmailMatch.call(this, result); } if (shouldRelaceBr) { result = result.replace(/\r?\n/g, "
"); } return result; }, /** * @param {String} match * @returns {String} Offset 1 */ formatURLMatch: function (match, p1) { match = prepHTTP(match.trim()); if (this.options.cloudmusic || this.options.embed) { if (match.indexOf("music.163.com/#/song?id=") > -1) { return match.replace( re.cloudmusic, p1 + '' ); } } if (this.options.kickstarter || this.options.embed) { if (re.kickstarter.test(match)) { return match.replace( re.kickstarter, p1 + '' ); } } if (this.options.vimeo || this.options.embed) { if (re.vimeo.test(match)) { return match.replace( re.vimeo, p1 + '' ); } } if (this.options.youtube || this.options.embed) { if (re.youtube.test(match)) { return match.replace( re.youtube, p1 + '' ); } } if (this.options.youku || this.options.embed) { if (re.youku.test(match)) { return match.replace( re.youku, p1 + '' ); } } var text = this.options.removeHTTP ? removeHTTP(match) : match; return ( p1 + '" + text + "" ); }, /** * @param {String} match * @param {String} Offset 1 */ formatIMGMatch: function (match, p1) { match = match.trim(); var isIMG = re.image.test(match); if (isIMG) { return ( p1 + '" ); } return this.formatURLMatch(match, p1); }, /** * @param {String} text */ formatEmailMatch: function (text) { return text.replace( re.email, '$&" ); }, }; /** * return true if undefined * else return itself * * @param {Boolean} val * @returns {Boolean} */ function defaultTrue(val) { return typeof val === "undefined" ? true : val; } /** * parse attrs from object * * @param {Object} obj * @returns {Stirng} */ function getAttr(obj) { var attr = ""; for (var key in obj) { if (key) { attr += " " + key + '="' + obj[key] + '"'; } } return attr; } /** * @param {String} url * @returns {String} */ function prepHTTP(url) { if (url.substring(0, 4) !== "http" && url.substring(0, 2) !== "//") { return "http://" + url; } return url; } /** * @param {String} url * @returns {String} */ function removeHTTP(url) { return url.replace(re.http, ""); } var tagsToReplace = { "&": "&", "<": "<", ">": ">", }; /** * Replace tag if should be replace * * @param {String} tag * @returns {String} */ function replaceTag(tag) { return tagsToReplace[tag] || tag; } /** * Make string safe by replacing html tag * * @param {String} str * @returns {String} */ function safe_tags_replace(str) { return str.replace(/[&<>]/g, replaceTag); } /** * return an instance of AutoLink * * @param {String} string * @param {Object} options * @returns {Object} */ function autoLink(string, options) { return new AutoLink(string, options).parse(); } //export default autoLink