diff options
author | grant-kun <[email protected]> | 2022-10-13 13:18:42 -0500 |
---|---|---|
committer | grant-kun <[email protected]> | 2022-10-13 13:18:42 -0500 |
commit | 26d50b8e63f79e48652840a54567b059d1f73766 (patch) | |
tree | 08d81de8bf558e80d0fde43e6c400650ae4786e8 /src/autolink.js | |
parent | afdd65e44c3a1a89d1aaa1c089508bd86477d727 (diff) |
adding stuff
Diffstat (limited to 'src/autolink.js')
-rw-r--r-- | src/autolink.js | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/src/autolink.js b/src/autolink.js new file mode 100644 index 0000000..c04a0d2 --- /dev/null +++ b/src/autolink.js @@ -0,0 +1,245 @@ +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, "<br />"); + } + 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 + + '<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=86 src="http://music.163.com/outchain/player?type=2&id=$1&auto=1&height=66"></iframe>' + ); + } + } + if (this.options.kickstarter || this.options.embed) { + if (re.kickstarter.test(match)) { + return match.replace( + re.kickstarter, + p1 + + '<iframe width="480" height="360" src="$1/widget/video.html" frameborder="0" scrolling="no"> </iframe>' + ); + } + } + if (this.options.vimeo || this.options.embed) { + if (re.vimeo.test(match)) { + return match.replace( + re.vimeo, + p1 + + '<iframe width="500" height="281" src="https://player.vimeo.com/video/$1" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>' + ); + } + } + if (this.options.youtube || this.options.embed) { + if (re.youtube.test(match)) { + return match.replace( + re.youtube, + p1 + + '<iframe width="560" height="315" src="https://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>' + ); + } + } + if (this.options.youku || this.options.embed) { + if (re.youku.test(match)) { + return match.replace( + re.youku, + p1 + + '<iframe height=498 width=510 src="http://player.youku.com/embed/$1" frameborder=0 allowfullscreen></iframe>' + ); + } + } + var text = this.options.removeHTTP ? removeHTTP(match) : match; + return ( + p1 + + '<a href="' + + match + + '"' + + this.attrs + + this.linkAttr + + ">" + + text + + "</a>" + ); + }, + /** + * @param {String} match + * @param {String} Offset 1 + */ + formatIMGMatch: function (match, p1) { + match = match.trim(); + var isIMG = re.image.test(match); + if (isIMG) { + return ( + p1 + + '<img src="' + + prepHTTP(match.trim()) + + '"' + + this.attrs + + this.imageAttr + + "/>" + ); + } + return this.formatURLMatch(match, p1); + }, + /** + * @param {String} text + */ + formatEmailMatch: function (text) { + return text.replace( + re.email, + '<a href="mailto:$&"' + this.attrs + this.linkAttr + ">$&</a>" + ); + }, +}; + +/** + * 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 |