PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/ajax/libs/jQuery-linkify/1.0.1/jquery.linkify.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 270 lines | 147 code | 45 blank | 78 comment | 20 complexity | 503602abc1883e847ea21a71935f3b12 MD5 | raw file
  1. /*
  2. * Linkify - v1.0.1
  3. * Find URLs in plain text and return HTML for discovered links.
  4. * https://github.com/HitSend/jQuery-linkify/
  5. *
  6. * Made by SoapBox Innovations, Inc.
  7. * Under MIT License
  8. */
  9. ;(function ($, window, document, undefined) {
  10. // Create the defaults once
  11. var pluginName = 'linkify',
  12. defaults = {
  13. tagName: 'a',
  14. newLine: '\n',
  15. target: '_blank',
  16. linkClass: null,
  17. linkClasses: ['linkified'],
  18. linkAttributes: null
  19. };
  20. /**
  21. A Linkified object contains a DOM node (or just plain text) whose
  22. inner text is replaced by HTML containing `<a>` links to URLs
  23. discovered in that text. Call with
  24. new Linkified(element, options)
  25. Here are some the available options and their defaults
  26. {
  27. tagName: 'a',
  28. newLine: '\n',
  29. target: '_blank',
  30. linkClass: null,
  31. linkClasses: ['linkified'],
  32. linkAttributes: null
  33. }
  34. @class Linkified
  35. */
  36. function Linkified(element, options) {
  37. this.element = element;
  38. // Setup settings
  39. this.settings = $.extend({}, defaults, options);
  40. this._defaults = defaults;
  41. this._name = pluginName;
  42. this.init();
  43. }
  44. Linkified.prototype = {
  45. constructor: Linkified,
  46. /**
  47. Initialized
  48. @method init
  49. */
  50. init: function () {
  51. this.settings.linkClasses = this.settings.linkClasses || [];
  52. this.linkify();
  53. },
  54. /**
  55. Linkify the contained element
  56. @method linkify
  57. @return {String} html
  58. */
  59. linkify: function (options) {
  60. if (options) {
  61. $.extend(this.settings, options);
  62. }
  63. var attr,
  64. linkClass = this.settings.linkClass,
  65. linkClasses = this.settings.linkClasses || [],
  66. linkReplace = [],
  67. text = typeof this.element === 'object' && this.element.textContent ?
  68. this.element.textContent :
  69. this.element.toString() || '';
  70. // Normalize class names
  71. if (linkClass && $.inArray(linkClass, linkClasses) < 0) {
  72. linkClasses.push(linkClass);
  73. this.settings.linkClass = undefined;
  74. }
  75. // Get rid of tags and HTML-structure,
  76. // Duplicate whitespace in preparation for linking
  77. text = text
  78. .replace(/</g, '&lt;')
  79. .replace(/(\s)/g, '$1$1');
  80. // Build up the replacement string
  81. linkReplace.push(
  82. '$1<' + this.settings.tagName,
  83. 'href="http://$2$4$5$6"'
  84. );
  85. // Add classes
  86. if (linkClasses.length > 0) {
  87. linkReplace.push('class="' + linkClasses.join(' ') + '"');
  88. }
  89. // Add target
  90. if (this.settings.target) {
  91. linkReplace.push('target="' + this.settings.target + '"');
  92. }
  93. // Add other (normalized) attributes
  94. for (attr in this.settings.linkAttributes) {
  95. linkReplace.push([
  96. attr,
  97. '="',
  98. this.settings.linkAttributes[attr]
  99. .replace(/\"/g, '&quot;')
  100. .replace(/\$/g, '&#36;'),
  101. '"'
  102. ].join(''));
  103. }
  104. // Finish off
  105. linkReplace.push('>$2$3$4$5$6</' + this.settings.tagName + '>$7');
  106. // Create the link
  107. text = text.replace(this.constructor.linkMatch, linkReplace.join(' '));
  108. // The previous line added `http://` to emails. Replace that with `mailto:`
  109. text = text.replace(this.constructor.emailLinkMatch, '$1mailto:$3');
  110. // Revert whitespace characters back to a single character
  111. text = text.replace(/(\s){2}/g, '$1');
  112. // Trim and account for new lines
  113. text = text
  114. .replace(/^\s+|\s+$/g, '')
  115. .replace(/\n/g, this.settings.newLine);
  116. if (typeof this.element === 'object') {
  117. // Set the HTML on the element to the newly linkified text
  118. this.element.innerHTML = text;
  119. }
  120. this.html = text;
  121. return text;
  122. },
  123. /**
  124. Returns the HTML of the linkified element.
  125. @method toString
  126. @return {String} html
  127. */
  128. toString: function () {
  129. // Returned the linkified HTML
  130. return this.html || '';
  131. }
  132. };
  133. /**
  134. The url-matching regular expression for double-spaced text
  135. @property linkMatch
  136. @static
  137. @type RegExp
  138. */
  139. Linkified.linkMatch = new RegExp([
  140. // The groups
  141. '(', // 1. Character before the link
  142. '\\s|[^a-zA-Z0-9.\\+_\\/"\\>\\-]|^',
  143. ')(?:', //Main group
  144. '(', // 2. Email address (optional)
  145. '[a-zA-Z0-9\\+_\\-]+',
  146. '(?:',
  147. '\\.[a-zA-Z0-9\\+_\\-]+',
  148. ')*@',
  149. ')?(', // 3. Protocol (optional)
  150. 'http:\\/\\/|https:\\/\\/|ftp:\\/\\/',
  151. ')?(', // 4. Domain & Subdomains
  152. '(?:(?:[a-z0-9][a-z0-9_%\\-_+]*\\.)+)',
  153. ')(', // 5. Top-level domain - http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
  154. '(?:com|ca|co|edu|gov|net|org|dev|biz|cat|int|pro|tel|mil|aero|asia|coop|info|jobs|mobi|museum|name|post|travel|local|[a-z]{2})',
  155. ')(', // 6. Query string (optional)
  156. '(?:',
  157. '[\\/|\\?]',
  158. '(?:',
  159. '[\\-a-zA-Z0-9_%#*&+=~!?,;:.\\/]*',
  160. ')*',
  161. ')',
  162. '[\\-\\/a-zA-Z0-9_%#*&+=~]',
  163. '|',
  164. '\\/?',
  165. ')?',
  166. ')(', // 7. Character after the link
  167. '[^a-zA-Z0-9\\+_\\/"\\<\\-]|$',
  168. ')'
  169. ].join(''), 'g');
  170. /**
  171. The regular expression of matching email links after the
  172. application of the initial link matcher.
  173. @property emailLinkMatch
  174. @static
  175. @type RegExp
  176. */
  177. Linkified.emailLinkMatch = /(<[a-z]+ href=\")(http:\/\/)([a-zA-Z0-9\+_\-]+(?:\.[a-zA-Z0-9\+_\-]+)*@)/g;
  178. // Plugin definition
  179. $.fn[pluginName] = function (options) {
  180. return this.each(function () {
  181. if (!$.data(this, 'plugin-' + pluginName)) {
  182. $.data(this, 'plugin-' + pluginName, new Linkified(this, options));
  183. } else {
  184. $.data(this, 'plugin-' + pluginName).linkify(options);
  185. }
  186. });
  187. };
  188. // Maintain access to the constructor from the plugin
  189. $.fn[pluginName].Constructor = Linkified;
  190. // DOM data- API setup
  191. $(window).on('load', function () {
  192. $('[data-linkify]').each(function () {
  193. var $this = $(this),
  194. $target,
  195. target = $this.attr('data-linkify'),
  196. options = {
  197. tagName: $this.attr('data-linkify-tagname') || undefined,
  198. newLine: $this.attr('data-linkify-newline') || undefined,
  199. target: $this.attr('data-linkify-target') || undefined,
  200. linkClass: $this.attr('data-linkify-linkclass') || undefined
  201. };
  202. $target = target === 'this' ? $this : $this.find(target);
  203. $target.linkify(options);
  204. });
  205. });
  206. // Setup click events for linkified elements
  207. $('body').on('click', '.linkified', function () {
  208. var $link = $(this),
  209. url = $link.attr('href'),
  210. isEmail = url.substr(0, 7) === 'mailto:',
  211. target = $link.attr('target');
  212. if (isEmail) {
  213. // mailto links ignore the target
  214. window.location.href = url;
  215. } else {
  216. window.open(url, target);
  217. }
  218. return false;
  219. });
  220. })(jQuery, window, document);