@startinblox/core 0.17.21-beta.9 → 0.17.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/package.json +2 -2
  2. package/dist/_snowpack/env.js +0 -3
  3. package/dist/_snowpack/pkg/autolinker.js +0 -4281
  4. package/dist/_snowpack/pkg/autolinker.js.map +0 -1
  5. package/dist/_snowpack/pkg/autolinker.js.map.proxy.js +0 -1
  6. package/dist/_snowpack/pkg/common/_baseUnary-217dffb2.js +0 -377
  7. package/dist/_snowpack/pkg/common/_baseUnary-217dffb2.js.map +0 -1
  8. package/dist/_snowpack/pkg/common/_baseUnary-217dffb2.js.map.proxy.js +0 -1
  9. package/dist/_snowpack/pkg/common/_commonjsHelpers-8c19dec8.js +0 -22
  10. package/dist/_snowpack/pkg/common/_commonjsHelpers-8c19dec8.js.map +0 -1
  11. package/dist/_snowpack/pkg/common/_commonjsHelpers-8c19dec8.js.map.proxy.js +0 -1
  12. package/dist/_snowpack/pkg/common/decode-a4c334cf.js +0 -216
  13. package/dist/_snowpack/pkg/common/decode-a4c334cf.js.map +0 -1
  14. package/dist/_snowpack/pkg/common/decode-a4c334cf.js.map.proxy.js +0 -1
  15. package/dist/_snowpack/pkg/common/lit-html-babd44cd.js +0 -1119
  16. package/dist/_snowpack/pkg/common/lit-html-babd44cd.js.map +0 -1
  17. package/dist/_snowpack/pkg/common/lit-html-babd44cd.js.map.proxy.js +0 -1
  18. package/dist/_snowpack/pkg/delta-markdown-for-quill.js +0 -25677
  19. package/dist/_snowpack/pkg/delta-markdown-for-quill.js.map +0 -1
  20. package/dist/_snowpack/pkg/delta-markdown-for-quill.js.map.proxy.js +0 -1
  21. package/dist/_snowpack/pkg/dialog-polyfill.js +0 -859
  22. package/dist/_snowpack/pkg/dialog-polyfill.js.map +0 -1
  23. package/dist/_snowpack/pkg/dialog-polyfill.js.map.proxy.js +0 -1
  24. package/dist/_snowpack/pkg/fusejs.js +0 -1783
  25. package/dist/_snowpack/pkg/fusejs.js.map +0 -1
  26. package/dist/_snowpack/pkg/fusejs.js.map.proxy.js +0 -1
  27. package/dist/_snowpack/pkg/import-map.json +0 -23
  28. package/dist/_snowpack/pkg/jsonld-context-parser.js +0 -804
  29. package/dist/_snowpack/pkg/jsonld-context-parser.js.map +0 -1
  30. package/dist/_snowpack/pkg/jsonld-context-parser.js.map.proxy.js +0 -1
  31. package/dist/_snowpack/pkg/leaflet/dist/leaflet.css +0 -640
  32. package/dist/_snowpack/pkg/leaflet/dist/leaflet.css.proxy.js +0 -10
  33. package/dist/_snowpack/pkg/leaflet.markercluster/dist/MarkerCluster.Default.css +0 -60
  34. package/dist/_snowpack/pkg/leaflet.markercluster/dist/MarkerCluster.Default.css.proxy.js +0 -10
  35. package/dist/_snowpack/pkg/leaflet.markercluster/dist/MarkerCluster.css +0 -14
  36. package/dist/_snowpack/pkg/leaflet.markercluster/dist/MarkerCluster.css.proxy.js +0 -10
  37. package/dist/_snowpack/pkg/lit-html/directives/if-defined.js +0 -40
  38. package/dist/_snowpack/pkg/lit-html/directives/if-defined.js.map +0 -1
  39. package/dist/_snowpack/pkg/lit-html/directives/if-defined.js.map.proxy.js +0 -1
  40. package/dist/_snowpack/pkg/lit-html/directives/unsafe-html.js +0 -46
  41. package/dist/_snowpack/pkg/lit-html/directives/unsafe-html.js.map +0 -1
  42. package/dist/_snowpack/pkg/lit-html/directives/unsafe-html.js.map.proxy.js +0 -1
  43. package/dist/_snowpack/pkg/lit-html/directives/until.js +0 -88
  44. package/dist/_snowpack/pkg/lit-html/directives/until.js.map +0 -1
  45. package/dist/_snowpack/pkg/lit-html/directives/until.js.map.proxy.js +0 -1
  46. package/dist/_snowpack/pkg/lit-html.js +0 -92
  47. package/dist/_snowpack/pkg/lit-html.js.map +0 -1
  48. package/dist/_snowpack/pkg/lit-html.js.map.proxy.js +0 -1
  49. package/dist/_snowpack/pkg/markdown-it.js +0 -11860
  50. package/dist/_snowpack/pkg/markdown-it.js.map +0 -1
  51. package/dist/_snowpack/pkg/markdown-it.js.map.proxy.js +0 -1
  52. package/dist/_snowpack/pkg/quill/dist/quill.snow.css +0 -945
  53. package/dist/_snowpack/pkg/quill/dist/quill.snow.css.proxy.js +0 -10
  54. package/dist/_snowpack/pkg/quill-delta-to-markdown.js +0 -1029
  55. package/dist/_snowpack/pkg/quill-delta-to-markdown.js.map +0 -1
  56. package/dist/_snowpack/pkg/quill-delta-to-markdown.js.map.proxy.js +0 -1
  57. package/dist/_snowpack/pkg/quill.js +0 -13382
  58. package/dist/_snowpack/pkg/quill.js.map +0 -1
  59. package/dist/_snowpack/pkg/quill.js.map.proxy.js +0 -1
  60. package/dist/_snowpack/pkg/slim-select.js +0 -4
  61. package/dist/_snowpack/pkg/slim-select.js.map +0 -1
  62. package/dist/_snowpack/pkg/slim-select.js.map.proxy.js +0 -1
  63. package/dist/_snowpack/pkg/tui-calendar/dist/tui-calendar.css +0 -1164
  64. package/dist/_snowpack/pkg/tui-calendar/dist/tui-calendar.css.proxy.js +0 -10
  65. package/dist/_snowpack/pkg/tui-calendar.js +0 -42285
  66. package/dist/_snowpack/pkg/tui-calendar.js.map +0 -1
  67. package/dist/_snowpack/pkg/tui-calendar.js.map.proxy.js +0 -1
  68. package/dist/components/solid-ac-checker.js +0 -51
  69. package/dist/components/solid-ac-checker.js.map +0 -1
  70. package/dist/components/solid-calendar.js +0 -87
  71. package/dist/components/solid-calendar.js.map +0 -1
  72. package/dist/components/solid-delete.js +0 -111
  73. package/dist/components/solid-delete.js.map +0 -1
  74. package/dist/components/solid-display.js +0 -194
  75. package/dist/components/solid-display.js.map +0 -1
  76. package/dist/components/solid-form-search.js +0 -226
  77. package/dist/components/solid-form-search.js.map +0 -1
  78. package/dist/components/solid-form.js +0 -354
  79. package/dist/components/solid-form.js.map +0 -1
  80. package/dist/components/solid-lang.js +0 -46
  81. package/dist/components/solid-lang.js.map +0 -1
  82. package/dist/components/solid-map.js +0 -242
  83. package/dist/components/solid-map.js.map +0 -1
  84. package/dist/components/solid-table.js +0 -263
  85. package/dist/components/solid-table.js.map +0 -1
  86. package/dist/components/solid-widget.js +0 -94
  87. package/dist/components/solid-widget.js.map +0 -1
  88. package/dist/import.css +0 -4
  89. package/dist/index.js +0 -43
  90. package/dist/index.js.map +0 -1
  91. package/dist/libs/Component.js +0 -19
  92. package/dist/libs/Component.js.map +0 -1
  93. package/dist/libs/ComponentFactory.js +0 -196
  94. package/dist/libs/ComponentFactory.js.map +0 -1
  95. package/dist/libs/Compositor.js +0 -103
  96. package/dist/libs/Compositor.js.map +0 -1
  97. package/dist/libs/Sib.js +0 -58
  98. package/dist/libs/Sib.js.map +0 -1
  99. package/dist/libs/filter.js +0 -214
  100. package/dist/libs/filter.js.map +0 -1
  101. package/dist/libs/helpers.js +0 -219
  102. package/dist/libs/helpers.js.map +0 -1
  103. package/dist/libs/interfaces.js +0 -6
  104. package/dist/libs/interfaces.js.map +0 -1
  105. package/dist/libs/lit-helpers.js +0 -169
  106. package/dist/libs/lit-helpers.js.map +0 -1
  107. package/dist/libs/polyfills.js +0 -40
  108. package/dist/libs/polyfills.js.map +0 -1
  109. package/dist/libs/store/store.js +0 -863
  110. package/dist/libs/store/store.js.map +0 -1
  111. package/dist/locales/en.json +0 -10
  112. package/dist/locales/en.json.proxy.js +0 -2
  113. package/dist/locales/fr.json +0 -10
  114. package/dist/locales/fr.json.proxy.js +0 -2
  115. package/dist/mixins/attributeBinderMixin.js +0 -124
  116. package/dist/mixins/attributeBinderMixin.js.map +0 -1
  117. package/dist/mixins/contextMixin.js +0 -28
  118. package/dist/mixins/contextMixin.js.map +0 -1
  119. package/dist/mixins/counterMixin.js +0 -75
  120. package/dist/mixins/counterMixin.js.map +0 -1
  121. package/dist/mixins/federationMixin.js +0 -63
  122. package/dist/mixins/federationMixin.js.map +0 -1
  123. package/dist/mixins/filterMixin.js +0 -136
  124. package/dist/mixins/filterMixin.js.map +0 -1
  125. package/dist/mixins/grouperMixin.js +0 -80
  126. package/dist/mixins/grouperMixin.js.map +0 -1
  127. package/dist/mixins/highlighterMixin.js +0 -42
  128. package/dist/mixins/highlighterMixin.js.map +0 -1
  129. package/dist/mixins/interfaces.js +0 -8
  130. package/dist/mixins/interfaces.js.map +0 -1
  131. package/dist/mixins/listMixin.js +0 -136
  132. package/dist/mixins/listMixin.js.map +0 -1
  133. package/dist/mixins/nextMixin.js +0 -26
  134. package/dist/mixins/nextMixin.js.map +0 -1
  135. package/dist/mixins/paginateMixin.js +0 -110
  136. package/dist/mixins/paginateMixin.js.map +0 -1
  137. package/dist/mixins/requiredMixin.js +0 -34
  138. package/dist/mixins/requiredMixin.js.map +0 -1
  139. package/dist/mixins/sorterMixin.js +0 -149
  140. package/dist/mixins/sorterMixin.js.map +0 -1
  141. package/dist/mixins/storeMixin.js +0 -102
  142. package/dist/mixins/storeMixin.js.map +0 -1
  143. package/dist/mixins/translationMixin.js +0 -68
  144. package/dist/mixins/translationMixin.js.map +0 -1
  145. package/dist/mixins/validationMixin.js +0 -113
  146. package/dist/mixins/validationMixin.js.map +0 -1
  147. package/dist/mixins/widgetMixin.js +0 -447
  148. package/dist/mixins/widgetMixin.js.map +0 -1
  149. package/dist/new-widgets/attributeMixins/actionMixin.js +0 -14
  150. package/dist/new-widgets/attributeMixins/actionMixin.js.map +0 -1
  151. package/dist/new-widgets/attributeMixins/blankMixin.js +0 -10
  152. package/dist/new-widgets/attributeMixins/blankMixin.js.map +0 -1
  153. package/dist/new-widgets/attributeMixins/booleanMixin.js +0 -10
  154. package/dist/new-widgets/attributeMixins/booleanMixin.js.map +0 -1
  155. package/dist/new-widgets/attributeMixins/index.js +0 -20
  156. package/dist/new-widgets/attributeMixins/index.js.map +0 -1
  157. package/dist/new-widgets/attributeMixins/mailtoMixin.js +0 -10
  158. package/dist/new-widgets/attributeMixins/mailtoMixin.js.map +0 -1
  159. package/dist/new-widgets/attributeMixins/multipleMixin.js +0 -28
  160. package/dist/new-widgets/attributeMixins/multipleMixin.js.map +0 -1
  161. package/dist/new-widgets/attributeMixins/numberMixin.js +0 -10
  162. package/dist/new-widgets/attributeMixins/numberMixin.js.map +0 -1
  163. package/dist/new-widgets/attributeMixins/placeholderMixin.js +0 -19
  164. package/dist/new-widgets/attributeMixins/placeholderMixin.js.map +0 -1
  165. package/dist/new-widgets/attributeMixins/telMixin.js +0 -10
  166. package/dist/new-widgets/attributeMixins/telMixin.js.map +0 -1
  167. package/dist/new-widgets/baseWidgetMixin.js +0 -122
  168. package/dist/new-widgets/baseWidgetMixin.js.map +0 -1
  169. package/dist/new-widgets/callbackMixins/autocompletionMixin.js +0 -104
  170. package/dist/new-widgets/callbackMixins/autocompletionMixin.js.map +0 -1
  171. package/dist/new-widgets/callbackMixins/index.js +0 -8
  172. package/dist/new-widgets/callbackMixins/index.js.map +0 -1
  173. package/dist/new-widgets/callbackMixins/richtextMixin.js +0 -42
  174. package/dist/new-widgets/callbackMixins/richtextMixin.js.map +0 -1
  175. package/dist/new-widgets/callbackMixins/slimselect.css +0 -2
  176. package/dist/new-widgets/callbackMixins/slimselect.css.proxy.js +0 -10
  177. package/dist/new-widgets/new-widget-factory.js +0 -96
  178. package/dist/new-widgets/new-widget-factory.js.map +0 -1
  179. package/dist/new-widgets/templateAdditionMixins/addableMixin.js +0 -41
  180. package/dist/new-widgets/templateAdditionMixins/addableMixin.js.map +0 -1
  181. package/dist/new-widgets/templateAdditionMixins/index.js +0 -14
  182. package/dist/new-widgets/templateAdditionMixins/index.js.map +0 -1
  183. package/dist/new-widgets/templateAdditionMixins/labelLastMixin.js +0 -29
  184. package/dist/new-widgets/templateAdditionMixins/labelLastMixin.js.map +0 -1
  185. package/dist/new-widgets/templateAdditionMixins/labelMixin.js +0 -31
  186. package/dist/new-widgets/templateAdditionMixins/labelMixin.js.map +0 -1
  187. package/dist/new-widgets/templates/defaultTemplatesDirectory.js +0 -36
  188. package/dist/new-widgets/templates/defaultTemplatesDirectory.js.map +0 -1
  189. package/dist/new-widgets/templates/displayTemplatesDirectory.js +0 -90
  190. package/dist/new-widgets/templates/displayTemplatesDirectory.js.map +0 -1
  191. package/dist/new-widgets/templates/formTemplatesDirectory.js +0 -397
  192. package/dist/new-widgets/templates/formTemplatesDirectory.js.map +0 -1
  193. package/dist/new-widgets/templates/groupTemplatesDirectory.js +0 -21
  194. package/dist/new-widgets/templates/groupTemplatesDirectory.js.map +0 -1
  195. package/dist/new-widgets/templates/index.js +0 -7
  196. package/dist/new-widgets/templates/index.js.map +0 -1
  197. package/dist/new-widgets/templates/setTemplatesDirectory.js +0 -49
  198. package/dist/new-widgets/templates/setTemplatesDirectory.js.map +0 -1
  199. package/dist/new-widgets/templatesDependencies/altMixin.js +0 -13
  200. package/dist/new-widgets/templatesDependencies/altMixin.js.map +0 -1
  201. package/dist/new-widgets/templatesDependencies/editableMixin.js +0 -77
  202. package/dist/new-widgets/templatesDependencies/editableMixin.js.map +0 -1
  203. package/dist/new-widgets/templatesDependencies/filterRangeFormMixin.js +0 -38
  204. package/dist/new-widgets/templatesDependencies/filterRangeFormMixin.js.map +0 -1
  205. package/dist/new-widgets/templatesDependencies/formCheckboxMixin.js +0 -14
  206. package/dist/new-widgets/templatesDependencies/formCheckboxMixin.js.map +0 -1
  207. package/dist/new-widgets/templatesDependencies/formCheckboxesMixin.js +0 -51
  208. package/dist/new-widgets/templatesDependencies/formCheckboxesMixin.js.map +0 -1
  209. package/dist/new-widgets/templatesDependencies/formDropdownMixin.js +0 -66
  210. package/dist/new-widgets/templatesDependencies/formDropdownMixin.js.map +0 -1
  211. package/dist/new-widgets/templatesDependencies/formFileMixin.js +0 -81
  212. package/dist/new-widgets/templatesDependencies/formFileMixin.js.map +0 -1
  213. package/dist/new-widgets/templatesDependencies/formLengthMixin.js +0 -19
  214. package/dist/new-widgets/templatesDependencies/formLengthMixin.js.map +0 -1
  215. package/dist/new-widgets/templatesDependencies/formMinMaxMixin.js +0 -19
  216. package/dist/new-widgets/templatesDependencies/formMinMaxMixin.js.map +0 -1
  217. package/dist/new-widgets/templatesDependencies/formMixin.js +0 -66
  218. package/dist/new-widgets/templatesDependencies/formMixin.js.map +0 -1
  219. package/dist/new-widgets/templatesDependencies/formNumberMixin.js +0 -14
  220. package/dist/new-widgets/templatesDependencies/formNumberMixin.js.map +0 -1
  221. package/dist/new-widgets/templatesDependencies/formRadioMixin.js +0 -16
  222. package/dist/new-widgets/templatesDependencies/formRadioMixin.js.map +0 -1
  223. package/dist/new-widgets/templatesDependencies/formStepMixin.js +0 -13
  224. package/dist/new-widgets/templatesDependencies/formStepMixin.js.map +0 -1
  225. package/dist/new-widgets/templatesDependencies/linkTextMixin.js +0 -14
  226. package/dist/new-widgets/templatesDependencies/linkTextMixin.js.map +0 -1
  227. package/dist/new-widgets/templatesDependencies/multipleFormMixin.js +0 -125
  228. package/dist/new-widgets/templatesDependencies/multipleFormMixin.js.map +0 -1
  229. package/dist/new-widgets/templatesDependencies/multipleselectFormMixin.js +0 -74
  230. package/dist/new-widgets/templatesDependencies/multipleselectFormMixin.js.map +0 -1
  231. package/dist/new-widgets/templatesDependencies/patternMixin.js +0 -19
  232. package/dist/new-widgets/templatesDependencies/patternMixin.js.map +0 -1
  233. package/dist/new-widgets/templatesDependencies/rangeMixin.js +0 -110
  234. package/dist/new-widgets/templatesDependencies/rangeMixin.js.map +0 -1
  235. package/dist/new-widgets/templatesDependencies/setMixin.js +0 -12
  236. package/dist/new-widgets/templatesDependencies/setMixin.js.map +0 -1
  237. package/dist/new-widgets/templatesDependencies/valueRichtextMixin.js +0 -12
  238. package/dist/new-widgets/templatesDependencies/valueRichtextMixin.js.map +0 -1
  239. package/dist/new-widgets/valueTransformationMixins/autolinkMixin.js +0 -18
  240. package/dist/new-widgets/valueTransformationMixins/autolinkMixin.js.map +0 -1
  241. package/dist/new-widgets/valueTransformationMixins/dateMixin.js +0 -35
  242. package/dist/new-widgets/valueTransformationMixins/dateMixin.js.map +0 -1
  243. package/dist/new-widgets/valueTransformationMixins/dateTimeMixin.js +0 -16
  244. package/dist/new-widgets/valueTransformationMixins/dateTimeMixin.js.map +0 -1
  245. package/dist/new-widgets/valueTransformationMixins/index.js +0 -16
  246. package/dist/new-widgets/valueTransformationMixins/index.js.map +0 -1
  247. package/dist/new-widgets/valueTransformationMixins/markdownMixin.js +0 -25
  248. package/dist/new-widgets/valueTransformationMixins/markdownMixin.js.map +0 -1
  249. package/dist/new-widgets/valueTransformationMixins/multilineMixin.js +0 -17
  250. package/dist/new-widgets/valueTransformationMixins/multilineMixin.js.map +0 -1
  251. package/dist/new-widgets/valueTransformationMixins/oembedMixin.js +0 -27
  252. package/dist/new-widgets/valueTransformationMixins/oembedMixin.js.map +0 -1
  253. package/dist/solid-template-element.js +0 -164
  254. package/dist/solid-template-element.js.map +0 -1
  255. package/dist/style/default-theme.css +0 -24
  256. package/dist/style/default-theme.css.proxy.js +0 -10
  257. package/dist/widgets/baseWidget.js +0 -332
  258. package/dist/widgets/baseWidget.js.map +0 -1
  259. package/dist/widgets/widget-factory.js +0 -24
  260. package/dist/widgets/widget-factory.js.map +0 -1
@@ -1,4281 +0,0 @@
1
- /**
2
- * Assigns (shallow copies) the properties of `src` onto `dest`, if the
3
- * corresponding property on `dest` === `undefined`.
4
- *
5
- * @param {Object} dest The destination object.
6
- * @param {Object} src The source object.
7
- * @return {Object} The destination object (`dest`)
8
- */
9
- function defaults(dest, src) {
10
- for (var prop in src) {
11
- if (src.hasOwnProperty(prop) && dest[prop] === undefined) {
12
- dest[prop] = src[prop];
13
- }
14
- }
15
- return dest;
16
- }
17
- /**
18
- * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the
19
- * end of the string (by default, two periods: '..'). If the `str` length does not exceed
20
- * `len`, the string will be returned unchanged.
21
- *
22
- * @param {String} str The string to truncate and add an ellipsis to.
23
- * @param {Number} truncateLen The length to truncate the string at.
24
- * @param {String} [ellipsisChars=...] The ellipsis character(s) to add to the end of `str`
25
- * when truncated. Defaults to '...'
26
- */
27
- function ellipsis(str, truncateLen, ellipsisChars) {
28
- var ellipsisLength;
29
- if (str.length > truncateLen) {
30
- if (ellipsisChars == null) {
31
- ellipsisChars = '…';
32
- ellipsisLength = 3;
33
- }
34
- else {
35
- ellipsisLength = ellipsisChars.length;
36
- }
37
- str = str.substring(0, truncateLen - ellipsisLength) + ellipsisChars;
38
- }
39
- return str;
40
- }
41
- /**
42
- * Supports `Array.prototype.indexOf()` functionality for old IE (IE8 and below).
43
- *
44
- * @param {Array} arr The array to find an element of.
45
- * @param {*} element The element to find in the array, and return the index of.
46
- * @return {Number} The index of the `element`, or -1 if it was not found.
47
- */
48
- function indexOf(arr, element) {
49
- if (Array.prototype.indexOf) {
50
- return arr.indexOf(element);
51
- }
52
- else {
53
- for (var i = 0, len = arr.length; i < len; i++) {
54
- if (arr[i] === element)
55
- return i;
56
- }
57
- return -1;
58
- }
59
- }
60
- /**
61
- * Removes array elements based on a filtering function. Mutates the input
62
- * array.
63
- *
64
- * Using this instead of the ES5 Array.prototype.filter() function, to allow
65
- * Autolinker compatibility with IE8, and also to prevent creating many new
66
- * arrays in memory for filtering.
67
- *
68
- * @param {Array} arr The array to remove elements from. This array is
69
- * mutated.
70
- * @param {Function} fn A function which should return `true` to
71
- * remove an element.
72
- * @return {Array} The mutated input `arr`.
73
- */
74
- function remove(arr, fn) {
75
- for (var i = arr.length - 1; i >= 0; i--) {
76
- if (fn(arr[i]) === true) {
77
- arr.splice(i, 1);
78
- }
79
- }
80
- }
81
- /**
82
- * Performs the functionality of what modern browsers do when `String.prototype.split()` is called
83
- * with a regular expression that contains capturing parenthesis.
84
- *
85
- * For example:
86
- *
87
- * // Modern browsers:
88
- * "a,b,c".split( /(,)/ ); // --> [ 'a', ',', 'b', ',', 'c' ]
89
- *
90
- * // Old IE (including IE8):
91
- * "a,b,c".split( /(,)/ ); // --> [ 'a', 'b', 'c' ]
92
- *
93
- * This method emulates the functionality of modern browsers for the old IE case.
94
- *
95
- * @param {String} str The string to split.
96
- * @param {RegExp} splitRegex The regular expression to split the input `str` on. The splitting
97
- * character(s) will be spliced into the array, as in the "modern browsers" example in the
98
- * description of this method.
99
- * Note #1: the supplied regular expression **must** have the 'g' flag specified.
100
- * Note #2: for simplicity's sake, the regular expression does not need
101
- * to contain capturing parenthesis - it will be assumed that any match has them.
102
- * @return {String[]} The split array of strings, with the splitting character(s) included.
103
- */
104
- function splitAndCapture(str, splitRegex) {
105
- if (!splitRegex.global)
106
- throw new Error("`splitRegex` must have the 'g' flag set");
107
- var result = [], lastIdx = 0, match;
108
- while (match = splitRegex.exec(str)) {
109
- result.push(str.substring(lastIdx, match.index));
110
- result.push(match[0]); // push the splitting char(s)
111
- lastIdx = match.index + match[0].length;
112
- }
113
- result.push(str.substring(lastIdx));
114
- return result;
115
- }
116
- /**
117
- * Function that should never be called but is used to check that every
118
- * enum value is handled using TypeScript's 'never' type.
119
- */
120
- function throwUnhandledCaseError(theValue) {
121
- throw new Error("Unhandled case for value: '" + theValue + "'");
122
- }
123
-
124
- /**
125
- * @class Autolinker.HtmlTag
126
- * @extends Object
127
- *
128
- * Represents an HTML tag, which can be used to easily build/modify HTML tags programmatically.
129
- *
130
- * Autolinker uses this abstraction to create HTML tags, and then write them out as strings. You may also use
131
- * this class in your code, especially within a {@link Autolinker#replaceFn replaceFn}.
132
- *
133
- * ## Examples
134
- *
135
- * Example instantiation:
136
- *
137
- * var tag = new Autolinker.HtmlTag( {
138
- * tagName : 'a',
139
- * attrs : { 'href': 'http://google.com', 'class': 'external-link' },
140
- * innerHtml : 'Google'
141
- * } );
142
- *
143
- * tag.toAnchorString(); // <a href="http://google.com" class="external-link">Google</a>
144
- *
145
- * // Individual accessor methods
146
- * tag.getTagName(); // 'a'
147
- * tag.getAttr( 'href' ); // 'http://google.com'
148
- * tag.hasClass( 'external-link' ); // true
149
- *
150
- *
151
- * Using mutator methods (which may be used in combination with instantiation config properties):
152
- *
153
- * var tag = new Autolinker.HtmlTag();
154
- * tag.setTagName( 'a' );
155
- * tag.setAttr( 'href', 'http://google.com' );
156
- * tag.addClass( 'external-link' );
157
- * tag.setInnerHtml( 'Google' );
158
- *
159
- * tag.getTagName(); // 'a'
160
- * tag.getAttr( 'href' ); // 'http://google.com'
161
- * tag.hasClass( 'external-link' ); // true
162
- *
163
- * tag.toAnchorString(); // <a href="http://google.com" class="external-link">Google</a>
164
- *
165
- *
166
- * ## Example use within a {@link Autolinker#replaceFn replaceFn}
167
- *
168
- * var html = Autolinker.link( "Test google.com", {
169
- * replaceFn : function( match ) {
170
- * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance, configured with the Match's href and anchor text
171
- * tag.setAttr( 'rel', 'nofollow' );
172
- *
173
- * return tag;
174
- * }
175
- * } );
176
- *
177
- * // generated html:
178
- * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a>
179
- *
180
- *
181
- * ## Example use with a new tag for the replacement
182
- *
183
- * var html = Autolinker.link( "Test google.com", {
184
- * replaceFn : function( match ) {
185
- * var tag = new Autolinker.HtmlTag( {
186
- * tagName : 'button',
187
- * attrs : { 'title': 'Load URL: ' + match.getAnchorHref() },
188
- * innerHtml : 'Load URL: ' + match.getAnchorText()
189
- * } );
190
- *
191
- * return tag;
192
- * }
193
- * } );
194
- *
195
- * // generated html:
196
- * // Test <button title="Load URL: http://google.com">Load URL: google.com</button>
197
- */
198
- var HtmlTag = /** @class */ (function () {
199
- /**
200
- * @method constructor
201
- * @param {Object} [cfg] The configuration properties for this class, in an Object (map)
202
- */
203
- function HtmlTag(cfg) {
204
- if (cfg === void 0) { cfg = {}; }
205
- /**
206
- * @cfg {String} tagName
207
- *
208
- * The tag name. Ex: 'a', 'button', etc.
209
- *
210
- * Not required at instantiation time, but should be set using {@link #setTagName} before {@link #toAnchorString}
211
- * is executed.
212
- */
213
- this.tagName = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
214
- /**
215
- * @cfg {Object.<String, String>} attrs
216
- *
217
- * An key/value Object (map) of attributes to create the tag with. The keys are the attribute names, and the
218
- * values are the attribute values.
219
- */
220
- this.attrs = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
221
- /**
222
- * @cfg {String} innerHTML
223
- *
224
- * The inner HTML for the tag.
225
- */
226
- this.innerHTML = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
227
- /**
228
- * @protected
229
- * @property {RegExp} whitespaceRegex
230
- *
231
- * Regular expression used to match whitespace in a string of CSS classes.
232
- */
233
- this.whitespaceRegex = /\s+/; // default value just to get the above doc comment in the ES5 output and documentation generator
234
- this.tagName = cfg.tagName || '';
235
- this.attrs = cfg.attrs || {};
236
- this.innerHTML = cfg.innerHtml || cfg.innerHTML || ''; // accept either the camelCased form or the fully capitalized acronym as in the DOM
237
- }
238
- /**
239
- * Sets the tag name that will be used to generate the tag with.
240
- *
241
- * @param {String} tagName
242
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
243
- */
244
- HtmlTag.prototype.setTagName = function (tagName) {
245
- this.tagName = tagName;
246
- return this;
247
- };
248
- /**
249
- * Retrieves the tag name.
250
- *
251
- * @return {String}
252
- */
253
- HtmlTag.prototype.getTagName = function () {
254
- return this.tagName || '';
255
- };
256
- /**
257
- * Sets an attribute on the HtmlTag.
258
- *
259
- * @param {String} attrName The attribute name to set.
260
- * @param {String} attrValue The attribute value to set.
261
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
262
- */
263
- HtmlTag.prototype.setAttr = function (attrName, attrValue) {
264
- var tagAttrs = this.getAttrs();
265
- tagAttrs[attrName] = attrValue;
266
- return this;
267
- };
268
- /**
269
- * Retrieves an attribute from the HtmlTag. If the attribute does not exist, returns `undefined`.
270
- *
271
- * @param {String} attrName The attribute name to retrieve.
272
- * @return {String} The attribute's value, or `undefined` if it does not exist on the HtmlTag.
273
- */
274
- HtmlTag.prototype.getAttr = function (attrName) {
275
- return this.getAttrs()[attrName];
276
- };
277
- /**
278
- * Sets one or more attributes on the HtmlTag.
279
- *
280
- * @param {Object.<String, String>} attrs A key/value Object (map) of the attributes to set.
281
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
282
- */
283
- HtmlTag.prototype.setAttrs = function (attrs) {
284
- Object.assign(this.getAttrs(), attrs);
285
- return this;
286
- };
287
- /**
288
- * Retrieves the attributes Object (map) for the HtmlTag.
289
- *
290
- * @return {Object.<String, String>} A key/value object of the attributes for the HtmlTag.
291
- */
292
- HtmlTag.prototype.getAttrs = function () {
293
- return this.attrs || (this.attrs = {});
294
- };
295
- /**
296
- * Sets the provided `cssClass`, overwriting any current CSS classes on the HtmlTag.
297
- *
298
- * @param {String} cssClass One or more space-separated CSS classes to set (overwrite).
299
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
300
- */
301
- HtmlTag.prototype.setClass = function (cssClass) {
302
- return this.setAttr('class', cssClass);
303
- };
304
- /**
305
- * Convenience method to add one or more CSS classes to the HtmlTag. Will not add duplicate CSS classes.
306
- *
307
- * @param {String} cssClass One or more space-separated CSS classes to add.
308
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
309
- */
310
- HtmlTag.prototype.addClass = function (cssClass) {
311
- var classAttr = this.getClass(), whitespaceRegex = this.whitespaceRegex, classes = (!classAttr) ? [] : classAttr.split(whitespaceRegex), newClasses = cssClass.split(whitespaceRegex), newClass;
312
- while (newClass = newClasses.shift()) {
313
- if (indexOf(classes, newClass) === -1) {
314
- classes.push(newClass);
315
- }
316
- }
317
- this.getAttrs()['class'] = classes.join(" ");
318
- return this;
319
- };
320
- /**
321
- * Convenience method to remove one or more CSS classes from the HtmlTag.
322
- *
323
- * @param {String} cssClass One or more space-separated CSS classes to remove.
324
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
325
- */
326
- HtmlTag.prototype.removeClass = function (cssClass) {
327
- var classAttr = this.getClass(), whitespaceRegex = this.whitespaceRegex, classes = (!classAttr) ? [] : classAttr.split(whitespaceRegex), removeClasses = cssClass.split(whitespaceRegex), removeClass;
328
- while (classes.length && (removeClass = removeClasses.shift())) {
329
- var idx = indexOf(classes, removeClass);
330
- if (idx !== -1) {
331
- classes.splice(idx, 1);
332
- }
333
- }
334
- this.getAttrs()['class'] = classes.join(" ");
335
- return this;
336
- };
337
- /**
338
- * Convenience method to retrieve the CSS class(es) for the HtmlTag, which will each be separated by spaces when
339
- * there are multiple.
340
- *
341
- * @return {String}
342
- */
343
- HtmlTag.prototype.getClass = function () {
344
- return this.getAttrs()['class'] || "";
345
- };
346
- /**
347
- * Convenience method to check if the tag has a CSS class or not.
348
- *
349
- * @param {String} cssClass The CSS class to check for.
350
- * @return {Boolean} `true` if the HtmlTag has the CSS class, `false` otherwise.
351
- */
352
- HtmlTag.prototype.hasClass = function (cssClass) {
353
- return (' ' + this.getClass() + ' ').indexOf(' ' + cssClass + ' ') !== -1;
354
- };
355
- /**
356
- * Sets the inner HTML for the tag.
357
- *
358
- * @param {String} html The inner HTML to set.
359
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
360
- */
361
- HtmlTag.prototype.setInnerHTML = function (html) {
362
- this.innerHTML = html;
363
- return this;
364
- };
365
- /**
366
- * Backwards compatibility method name.
367
- *
368
- * @param {String} html The inner HTML to set.
369
- * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
370
- */
371
- HtmlTag.prototype.setInnerHtml = function (html) {
372
- return this.setInnerHTML(html);
373
- };
374
- /**
375
- * Retrieves the inner HTML for the tag.
376
- *
377
- * @return {String}
378
- */
379
- HtmlTag.prototype.getInnerHTML = function () {
380
- return this.innerHTML || "";
381
- };
382
- /**
383
- * Backward compatibility method name.
384
- *
385
- * @return {String}
386
- */
387
- HtmlTag.prototype.getInnerHtml = function () {
388
- return this.getInnerHTML();
389
- };
390
- /**
391
- * Override of superclass method used to generate the HTML string for the tag.
392
- *
393
- * @return {String}
394
- */
395
- HtmlTag.prototype.toAnchorString = function () {
396
- var tagName = this.getTagName(), attrsStr = this.buildAttrsStr();
397
- attrsStr = (attrsStr) ? ' ' + attrsStr : ''; // prepend a space if there are actually attributes
398
- return ['<', tagName, attrsStr, '>', this.getInnerHtml(), '</', tagName, '>'].join("");
399
- };
400
- /**
401
- * Support method for {@link #toAnchorString}, returns the string space-separated key="value" pairs, used to populate
402
- * the stringified HtmlTag.
403
- *
404
- * @protected
405
- * @return {String} Example return: `attr1="value1" attr2="value2"`
406
- */
407
- HtmlTag.prototype.buildAttrsStr = function () {
408
- if (!this.attrs)
409
- return ""; // no `attrs` Object (map) has been set, return empty string
410
- var attrs = this.getAttrs(), attrsArr = [];
411
- for (var prop in attrs) {
412
- if (attrs.hasOwnProperty(prop)) {
413
- attrsArr.push(prop + '="' + attrs[prop] + '"');
414
- }
415
- }
416
- return attrsArr.join(" ");
417
- };
418
- return HtmlTag;
419
- }());
420
-
421
- /**
422
- * Date: 2015-10-05
423
- * Author: Kasper Søfren <soefritz@gmail.com> (https://github.com/kafoso)
424
- *
425
- * A truncation feature, where the ellipsis will be placed at a section within
426
- * the URL making it still somewhat human readable.
427
- *
428
- * @param {String} url A URL.
429
- * @param {Number} truncateLen The maximum length of the truncated output URL string.
430
- * @param {String} ellipsisChars The characters to place within the url, e.g. "...".
431
- * @return {String} The truncated URL.
432
- */
433
- function truncateSmart(url, truncateLen, ellipsisChars) {
434
- var ellipsisLengthBeforeParsing;
435
- var ellipsisLength;
436
- if (ellipsisChars == null) {
437
- ellipsisChars = '&hellip;';
438
- ellipsisLength = 3;
439
- ellipsisLengthBeforeParsing = 8;
440
- }
441
- else {
442
- ellipsisLength = ellipsisChars.length;
443
- ellipsisLengthBeforeParsing = ellipsisChars.length;
444
- }
445
- var parse_url = function (url) {
446
- var urlObj = {};
447
- var urlSub = url;
448
- var match = urlSub.match(/^([a-z]+):\/\//i);
449
- if (match) {
450
- urlObj.scheme = match[1];
451
- urlSub = urlSub.substr(match[0].length);
452
- }
453
- match = urlSub.match(/^(.*?)(?=(\?|#|\/|$))/i);
454
- if (match) {
455
- urlObj.host = match[1];
456
- urlSub = urlSub.substr(match[0].length);
457
- }
458
- match = urlSub.match(/^\/(.*?)(?=(\?|#|$))/i);
459
- if (match) {
460
- urlObj.path = match[1];
461
- urlSub = urlSub.substr(match[0].length);
462
- }
463
- match = urlSub.match(/^\?(.*?)(?=(#|$))/i);
464
- if (match) {
465
- urlObj.query = match[1];
466
- urlSub = urlSub.substr(match[0].length);
467
- }
468
- match = urlSub.match(/^#(.*?)$/i);
469
- if (match) {
470
- urlObj.fragment = match[1];
471
- //urlSub = urlSub.substr(match[0].length); -- not used. Uncomment if adding another block.
472
- }
473
- return urlObj;
474
- };
475
- var buildUrl = function (urlObj) {
476
- var url = "";
477
- if (urlObj.scheme && urlObj.host) {
478
- url += urlObj.scheme + "://";
479
- }
480
- if (urlObj.host) {
481
- url += urlObj.host;
482
- }
483
- if (urlObj.path) {
484
- url += "/" + urlObj.path;
485
- }
486
- if (urlObj.query) {
487
- url += "?" + urlObj.query;
488
- }
489
- if (urlObj.fragment) {
490
- url += "#" + urlObj.fragment;
491
- }
492
- return url;
493
- };
494
- var buildSegment = function (segment, remainingAvailableLength) {
495
- var remainingAvailableLengthHalf = remainingAvailableLength / 2, startOffset = Math.ceil(remainingAvailableLengthHalf), endOffset = (-1) * Math.floor(remainingAvailableLengthHalf), end = "";
496
- if (endOffset < 0) {
497
- end = segment.substr(endOffset);
498
- }
499
- return segment.substr(0, startOffset) + ellipsisChars + end;
500
- };
501
- if (url.length <= truncateLen) {
502
- return url;
503
- }
504
- var availableLength = truncateLen - ellipsisLength;
505
- var urlObj = parse_url(url);
506
- // Clean up the URL
507
- if (urlObj.query) {
508
- var matchQuery = urlObj.query.match(/^(.*?)(?=(\?|\#))(.*?)$/i);
509
- if (matchQuery) {
510
- // Malformed URL; two or more "?". Removed any content behind the 2nd.
511
- urlObj.query = urlObj.query.substr(0, matchQuery[1].length);
512
- url = buildUrl(urlObj);
513
- }
514
- }
515
- if (url.length <= truncateLen) {
516
- return url;
517
- }
518
- if (urlObj.host) {
519
- urlObj.host = urlObj.host.replace(/^www\./, "");
520
- url = buildUrl(urlObj);
521
- }
522
- if (url.length <= truncateLen) {
523
- return url;
524
- }
525
- // Process and build the URL
526
- var str = "";
527
- if (urlObj.host) {
528
- str += urlObj.host;
529
- }
530
- if (str.length >= availableLength) {
531
- if (urlObj.host.length == truncateLen) {
532
- return (urlObj.host.substr(0, (truncateLen - ellipsisLength)) + ellipsisChars).substr(0, availableLength + ellipsisLengthBeforeParsing);
533
- }
534
- return buildSegment(str, availableLength).substr(0, availableLength + ellipsisLengthBeforeParsing);
535
- }
536
- var pathAndQuery = "";
537
- if (urlObj.path) {
538
- pathAndQuery += "/" + urlObj.path;
539
- }
540
- if (urlObj.query) {
541
- pathAndQuery += "?" + urlObj.query;
542
- }
543
- if (pathAndQuery) {
544
- if ((str + pathAndQuery).length >= availableLength) {
545
- if ((str + pathAndQuery).length == truncateLen) {
546
- return (str + pathAndQuery).substr(0, truncateLen);
547
- }
548
- var remainingAvailableLength = availableLength - str.length;
549
- return (str + buildSegment(pathAndQuery, remainingAvailableLength)).substr(0, availableLength + ellipsisLengthBeforeParsing);
550
- }
551
- else {
552
- str += pathAndQuery;
553
- }
554
- }
555
- if (urlObj.fragment) {
556
- var fragment = "#" + urlObj.fragment;
557
- if ((str + fragment).length >= availableLength) {
558
- if ((str + fragment).length == truncateLen) {
559
- return (str + fragment).substr(0, truncateLen);
560
- }
561
- var remainingAvailableLength2 = availableLength - str.length;
562
- return (str + buildSegment(fragment, remainingAvailableLength2)).substr(0, availableLength + ellipsisLengthBeforeParsing);
563
- }
564
- else {
565
- str += fragment;
566
- }
567
- }
568
- if (urlObj.scheme && urlObj.host) {
569
- var scheme = urlObj.scheme + "://";
570
- if ((str + scheme).length < availableLength) {
571
- return (scheme + str).substr(0, truncateLen);
572
- }
573
- }
574
- if (str.length <= truncateLen) {
575
- return str;
576
- }
577
- var end = "";
578
- if (availableLength > 0) {
579
- end = str.substr((-1) * Math.floor(availableLength / 2));
580
- }
581
- return (str.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);
582
- }
583
-
584
- /**
585
- * Date: 2015-10-05
586
- * Author: Kasper Søfren <soefritz@gmail.com> (https://github.com/kafoso)
587
- *
588
- * A truncation feature, where the ellipsis will be placed in the dead-center of the URL.
589
- *
590
- * @param {String} url A URL.
591
- * @param {Number} truncateLen The maximum length of the truncated output URL string.
592
- * @param {String} ellipsisChars The characters to place within the url, e.g. "..".
593
- * @return {String} The truncated URL.
594
- */
595
- function truncateMiddle(url, truncateLen, ellipsisChars) {
596
- if (url.length <= truncateLen) {
597
- return url;
598
- }
599
- var ellipsisLengthBeforeParsing;
600
- var ellipsisLength;
601
- if (ellipsisChars == null) {
602
- ellipsisChars = '&hellip;';
603
- ellipsisLengthBeforeParsing = 8;
604
- ellipsisLength = 3;
605
- }
606
- else {
607
- ellipsisLengthBeforeParsing = ellipsisChars.length;
608
- ellipsisLength = ellipsisChars.length;
609
- }
610
- var availableLength = truncateLen - ellipsisLength;
611
- var end = "";
612
- if (availableLength > 0) {
613
- end = url.substr((-1) * Math.floor(availableLength / 2));
614
- }
615
- return (url.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);
616
- }
617
-
618
- /**
619
- * A truncation feature where the ellipsis will be placed at the end of the URL.
620
- *
621
- * @param {String} anchorText
622
- * @param {Number} truncateLen The maximum length of the truncated output URL string.
623
- * @param {String} ellipsisChars The characters to place within the url, e.g. "..".
624
- * @return {String} The truncated URL.
625
- */
626
- function truncateEnd(anchorText, truncateLen, ellipsisChars) {
627
- return ellipsis(anchorText, truncateLen, ellipsisChars);
628
- }
629
-
630
- /**
631
- * @protected
632
- * @class Autolinker.AnchorTagBuilder
633
- * @extends Object
634
- *
635
- * Builds anchor (&lt;a&gt;) tags for the Autolinker utility when a match is
636
- * found.
637
- *
638
- * Normally this class is instantiated, configured, and used internally by an
639
- * {@link Autolinker} instance, but may actually be used indirectly in a
640
- * {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag}
641
- * instances which may be modified before returning from the
642
- * {@link Autolinker#replaceFn replaceFn}. For example:
643
- *
644
- * var html = Autolinker.link( "Test google.com", {
645
- * replaceFn : function( match ) {
646
- * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance
647
- * tag.setAttr( 'rel', 'nofollow' );
648
- *
649
- * return tag;
650
- * }
651
- * } );
652
- *
653
- * // generated html:
654
- * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a>
655
- */
656
- var AnchorTagBuilder = /** @class */ (function () {
657
- /**
658
- * @method constructor
659
- * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map).
660
- */
661
- function AnchorTagBuilder(cfg) {
662
- if (cfg === void 0) { cfg = {}; }
663
- /**
664
- * @cfg {Boolean} newWindow
665
- * @inheritdoc Autolinker#newWindow
666
- */
667
- this.newWindow = false; // default value just to get the above doc comment in the ES5 output and documentation generator
668
- /**
669
- * @cfg {Object} truncate
670
- * @inheritdoc Autolinker#truncate
671
- */
672
- this.truncate = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
673
- /**
674
- * @cfg {String} className
675
- * @inheritdoc Autolinker#className
676
- */
677
- this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
678
- this.newWindow = cfg.newWindow || false;
679
- this.truncate = cfg.truncate || {};
680
- this.className = cfg.className || '';
681
- }
682
- /**
683
- * Generates the actual anchor (&lt;a&gt;) tag to use in place of the
684
- * matched text, via its `match` object.
685
- *
686
- * @param {Autolinker.match.Match} match The Match instance to generate an
687
- * anchor tag from.
688
- * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag.
689
- */
690
- AnchorTagBuilder.prototype.build = function (match) {
691
- return new HtmlTag({
692
- tagName: 'a',
693
- attrs: this.createAttrs(match),
694
- innerHtml: this.processAnchorText(match.getAnchorText())
695
- });
696
- };
697
- /**
698
- * Creates the Object (map) of the HTML attributes for the anchor (&lt;a&gt;)
699
- * tag being generated.
700
- *
701
- * @protected
702
- * @param {Autolinker.match.Match} match The Match instance to generate an
703
- * anchor tag from.
704
- * @return {Object} A key/value Object (map) of the anchor tag's attributes.
705
- */
706
- AnchorTagBuilder.prototype.createAttrs = function (match) {
707
- var attrs = {
708
- 'href': match.getAnchorHref() // we'll always have the `href` attribute
709
- };
710
- var cssClass = this.createCssClass(match);
711
- if (cssClass) {
712
- attrs['class'] = cssClass;
713
- }
714
- if (this.newWindow) {
715
- attrs['target'] = "_blank";
716
- attrs['rel'] = "noopener noreferrer"; // Issue #149. See https://mathiasbynens.github.io/rel-noopener/
717
- }
718
- if (this.truncate) {
719
- if (this.truncate.length && this.truncate.length < match.getAnchorText().length) {
720
- attrs['title'] = match.getAnchorHref();
721
- }
722
- }
723
- return attrs;
724
- };
725
- /**
726
- * Creates the CSS class that will be used for a given anchor tag, based on
727
- * the `matchType` and the {@link #className} config.
728
- *
729
- * Example returns:
730
- *
731
- * - "" // no {@link #className}
732
- * - "myLink myLink-url" // url match
733
- * - "myLink myLink-email" // email match
734
- * - "myLink myLink-phone" // phone match
735
- * - "myLink myLink-hashtag" // hashtag match
736
- * - "myLink myLink-mention myLink-twitter" // mention match with Twitter service
737
- *
738
- * @protected
739
- * @param {Autolinker.match.Match} match The Match instance to generate an
740
- * anchor tag from.
741
- * @return {String} The CSS class string for the link. Example return:
742
- * "myLink myLink-url". If no {@link #className} was configured, returns
743
- * an empty string.
744
- */
745
- AnchorTagBuilder.prototype.createCssClass = function (match) {
746
- var className = this.className;
747
- if (!className) {
748
- return "";
749
- }
750
- else {
751
- var returnClasses = [className], cssClassSuffixes = match.getCssClassSuffixes();
752
- for (var i = 0, len = cssClassSuffixes.length; i < len; i++) {
753
- returnClasses.push(className + '-' + cssClassSuffixes[i]);
754
- }
755
- return returnClasses.join(' ');
756
- }
757
- };
758
- /**
759
- * Processes the `anchorText` by truncating the text according to the
760
- * {@link #truncate} config.
761
- *
762
- * @private
763
- * @param {String} anchorText The anchor tag's text (i.e. what will be
764
- * displayed).
765
- * @return {String} The processed `anchorText`.
766
- */
767
- AnchorTagBuilder.prototype.processAnchorText = function (anchorText) {
768
- anchorText = this.doTruncate(anchorText);
769
- return anchorText;
770
- };
771
- /**
772
- * Performs the truncation of the `anchorText` based on the {@link #truncate}
773
- * option. If the `anchorText` is longer than the length specified by the
774
- * {@link #truncate} option, the truncation is performed based on the
775
- * `location` property. See {@link #truncate} for details.
776
- *
777
- * @private
778
- * @param {String} anchorText The anchor tag's text (i.e. what will be
779
- * displayed).
780
- * @return {String} The truncated anchor text.
781
- */
782
- AnchorTagBuilder.prototype.doTruncate = function (anchorText) {
783
- var truncate = this.truncate;
784
- if (!truncate || !truncate.length)
785
- return anchorText;
786
- var truncateLength = truncate.length, truncateLocation = truncate.location;
787
- if (truncateLocation === 'smart') {
788
- return truncateSmart(anchorText, truncateLength);
789
- }
790
- else if (truncateLocation === 'middle') {
791
- return truncateMiddle(anchorText, truncateLength);
792
- }
793
- else {
794
- return truncateEnd(anchorText, truncateLength);
795
- }
796
- };
797
- return AnchorTagBuilder;
798
- }());
799
-
800
- /**
801
- * @abstract
802
- * @class Autolinker.match.Match
803
- *
804
- * Represents a match found in an input string which should be Autolinked. A Match object is what is provided in a
805
- * {@link Autolinker#replaceFn replaceFn}, and may be used to query for details about the match.
806
- *
807
- * For example:
808
- *
809
- * var input = "..."; // string with URLs, Email Addresses, and Mentions (Twitter, Instagram, Soundcloud)
810
- *
811
- * var linkedText = Autolinker.link( input, {
812
- * replaceFn : function( match ) {
813
- * console.log( "href = ", match.getAnchorHref() );
814
- * console.log( "text = ", match.getAnchorText() );
815
- *
816
- * switch( match.getType() ) {
817
- * case 'url' :
818
- * console.log( "url: ", match.getUrl() );
819
- *
820
- * case 'email' :
821
- * console.log( "email: ", match.getEmail() );
822
- *
823
- * case 'mention' :
824
- * console.log( "mention: ", match.getMention() );
825
- * }
826
- * }
827
- * } );
828
- *
829
- * See the {@link Autolinker} class for more details on using the {@link Autolinker#replaceFn replaceFn}.
830
- */
831
- var Match = /** @class */ (function () {
832
- /**
833
- * @member Autolinker.match.Match
834
- * @method constructor
835
- * @param {Object} cfg The configuration properties for the Match
836
- * instance, specified in an Object (map).
837
- */
838
- function Match(cfg) {
839
- /**
840
- * @cfg {Autolinker.AnchorTagBuilder} tagBuilder (required)
841
- *
842
- * Reference to the AnchorTagBuilder instance to use to generate an anchor
843
- * tag for the Match.
844
- */
845
- this.__jsduckDummyDocProp = null; // property used just to get the above doc comment into the ES5 output and documentation generator
846
- /**
847
- * @cfg {String} matchedText (required)
848
- *
849
- * The original text that was matched by the {@link Autolinker.matcher.Matcher}.
850
- */
851
- this.matchedText = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
852
- /**
853
- * @cfg {Number} offset (required)
854
- *
855
- * The offset of where the match was made in the input string.
856
- */
857
- this.offset = 0; // default value just to get the above doc comment in the ES5 output and documentation generator
858
- this.tagBuilder = cfg.tagBuilder;
859
- this.matchedText = cfg.matchedText;
860
- this.offset = cfg.offset;
861
- }
862
- /**
863
- * Returns the original text that was matched.
864
- *
865
- * @return {String}
866
- */
867
- Match.prototype.getMatchedText = function () {
868
- return this.matchedText;
869
- };
870
- /**
871
- * Sets the {@link #offset} of where the match was made in the input string.
872
- *
873
- * A {@link Autolinker.matcher.Matcher} will be fed only HTML text nodes,
874
- * and will therefore set an original offset that is relative to the HTML
875
- * text node itself. However, we want this offset to be relative to the full
876
- * HTML input string, and thus if using {@link Autolinker#parse} (rather
877
- * than calling a {@link Autolinker.matcher.Matcher} directly), then this
878
- * offset is corrected after the Matcher itself has done its job.
879
- *
880
- * @param {Number} offset
881
- */
882
- Match.prototype.setOffset = function (offset) {
883
- this.offset = offset;
884
- };
885
- /**
886
- * Returns the offset of where the match was made in the input string. This
887
- * is the 0-based index of the match.
888
- *
889
- * @return {Number}
890
- */
891
- Match.prototype.getOffset = function () {
892
- return this.offset;
893
- };
894
- /**
895
- * Returns the CSS class suffix(es) for this match.
896
- *
897
- * A CSS class suffix is appended to the {@link Autolinker#className} in
898
- * the {@link Autolinker.AnchorTagBuilder} when a match is translated into
899
- * an anchor tag.
900
- *
901
- * For example, if {@link Autolinker#className} was configured as 'myLink',
902
- * and this method returns `[ 'url' ]`, the final class name of the element
903
- * will become: 'myLink myLink-url'.
904
- *
905
- * The match may provide multiple CSS class suffixes to be appended to the
906
- * {@link Autolinker#className} in order to facilitate better styling
907
- * options for different match criteria. See {@link Autolinker.match.Mention}
908
- * for an example.
909
- *
910
- * By default, this method returns a single array with the match's
911
- * {@link #getType type} name, but may be overridden by subclasses.
912
- *
913
- * @return {String[]}
914
- */
915
- Match.prototype.getCssClassSuffixes = function () {
916
- return [this.getType()];
917
- };
918
- /**
919
- * Builds and returns an {@link Autolinker.HtmlTag} instance based on the
920
- * Match.
921
- *
922
- * This can be used to easily generate anchor tags from matches, and either
923
- * return their HTML string, or modify them before doing so.
924
- *
925
- * Example Usage:
926
- *
927
- * var tag = match.buildTag();
928
- * tag.addClass( 'cordova-link' );
929
- * tag.setAttr( 'target', '_system' );
930
- *
931
- * tag.toAnchorString(); // <a href="http://google.com" class="cordova-link" target="_system">Google</a>
932
- *
933
- * Example Usage in {@link Autolinker#replaceFn}:
934
- *
935
- * var html = Autolinker.link( "Test google.com", {
936
- * replaceFn : function( match ) {
937
- * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance
938
- * tag.setAttr( 'rel', 'nofollow' );
939
- *
940
- * return tag;
941
- * }
942
- * } );
943
- *
944
- * // generated html:
945
- * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a>
946
- */
947
- Match.prototype.buildTag = function () {
948
- return this.tagBuilder.build(this);
949
- };
950
- return Match;
951
- }());
952
-
953
- /*! *****************************************************************************
954
- Copyright (c) Microsoft Corporation. All rights reserved.
955
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
956
- this file except in compliance with the License. You may obtain a copy of the
957
- License at http://www.apache.org/licenses/LICENSE-2.0
958
-
959
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
960
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
961
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
962
- MERCHANTABLITY OR NON-INFRINGEMENT.
963
-
964
- See the Apache Version 2.0 License for specific language governing permissions
965
- and limitations under the License.
966
- ***************************************************************************** */
967
- /* global Reflect, Promise */
968
-
969
- var extendStatics = function(d, b) {
970
- extendStatics = Object.setPrototypeOf ||
971
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
972
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
973
- return extendStatics(d, b);
974
- };
975
-
976
- function __extends(d, b) {
977
- extendStatics(d, b);
978
- function __() { this.constructor = d; }
979
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
980
- }
981
-
982
- var __assign = function() {
983
- __assign = Object.assign || function __assign(t) {
984
- for (var s, i = 1, n = arguments.length; i < n; i++) {
985
- s = arguments[i];
986
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
987
- }
988
- return t;
989
- };
990
- return __assign.apply(this, arguments);
991
- };
992
-
993
- /**
994
- * @class Autolinker.match.Email
995
- * @extends Autolinker.match.Match
996
- *
997
- * Represents a Email match found in an input string which should be Autolinked.
998
- *
999
- * See this class's superclass ({@link Autolinker.match.Match}) for more details.
1000
- */
1001
- var EmailMatch = /** @class */ (function (_super) {
1002
- __extends(EmailMatch, _super);
1003
- /**
1004
- * @method constructor
1005
- * @param {Object} cfg The configuration properties for the Match
1006
- * instance, specified in an Object (map).
1007
- */
1008
- function EmailMatch(cfg) {
1009
- var _this = _super.call(this, cfg) || this;
1010
- /**
1011
- * @cfg {String} email (required)
1012
- *
1013
- * The email address that was matched.
1014
- */
1015
- _this.email = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1016
- _this.email = cfg.email;
1017
- return _this;
1018
- }
1019
- /**
1020
- * Returns a string name for the type of match that this class represents.
1021
- * For the case of EmailMatch, returns 'email'.
1022
- *
1023
- * @return {String}
1024
- */
1025
- EmailMatch.prototype.getType = function () {
1026
- return 'email';
1027
- };
1028
- /**
1029
- * Returns the email address that was matched.
1030
- *
1031
- * @return {String}
1032
- */
1033
- EmailMatch.prototype.getEmail = function () {
1034
- return this.email;
1035
- };
1036
- /**
1037
- * Returns the anchor href that should be generated for the match.
1038
- *
1039
- * @return {String}
1040
- */
1041
- EmailMatch.prototype.getAnchorHref = function () {
1042
- return 'mailto:' + this.email;
1043
- };
1044
- /**
1045
- * Returns the anchor text that should be generated for the match.
1046
- *
1047
- * @return {String}
1048
- */
1049
- EmailMatch.prototype.getAnchorText = function () {
1050
- return this.email;
1051
- };
1052
- return EmailMatch;
1053
- }(Match));
1054
-
1055
- /**
1056
- * @class Autolinker.match.Hashtag
1057
- * @extends Autolinker.match.Match
1058
- *
1059
- * Represents a Hashtag match found in an input string which should be
1060
- * Autolinked.
1061
- *
1062
- * See this class's superclass ({@link Autolinker.match.Match}) for more
1063
- * details.
1064
- */
1065
- var HashtagMatch = /** @class */ (function (_super) {
1066
- __extends(HashtagMatch, _super);
1067
- /**
1068
- * @method constructor
1069
- * @param {Object} cfg The configuration properties for the Match
1070
- * instance, specified in an Object (map).
1071
- */
1072
- function HashtagMatch(cfg) {
1073
- var _this = _super.call(this, cfg) || this;
1074
- /**
1075
- * @cfg {String} serviceName
1076
- *
1077
- * The service to point hashtag matches to. See {@link Autolinker#hashtag}
1078
- * for available values.
1079
- */
1080
- _this.serviceName = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1081
- /**
1082
- * @cfg {String} hashtag (required)
1083
- *
1084
- * The HashtagMatch that was matched, without the '#'.
1085
- */
1086
- _this.hashtag = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1087
- _this.serviceName = cfg.serviceName;
1088
- _this.hashtag = cfg.hashtag;
1089
- return _this;
1090
- }
1091
- /**
1092
- * Returns a string name for the type of match that this class represents.
1093
- * For the case of HashtagMatch, returns 'hashtag'.
1094
- *
1095
- * @return {String}
1096
- */
1097
- HashtagMatch.prototype.getType = function () {
1098
- return 'hashtag';
1099
- };
1100
- /**
1101
- * Returns the configured {@link #serviceName} to point the HashtagMatch to.
1102
- * Ex: 'facebook', 'twitter'.
1103
- *
1104
- * @return {String}
1105
- */
1106
- HashtagMatch.prototype.getServiceName = function () {
1107
- return this.serviceName;
1108
- };
1109
- /**
1110
- * Returns the matched hashtag, without the '#' character.
1111
- *
1112
- * @return {String}
1113
- */
1114
- HashtagMatch.prototype.getHashtag = function () {
1115
- return this.hashtag;
1116
- };
1117
- /**
1118
- * Returns the anchor href that should be generated for the match.
1119
- *
1120
- * @return {String}
1121
- */
1122
- HashtagMatch.prototype.getAnchorHref = function () {
1123
- var serviceName = this.serviceName, hashtag = this.hashtag;
1124
- switch (serviceName) {
1125
- case 'twitter':
1126
- return 'https://twitter.com/hashtag/' + hashtag;
1127
- case 'facebook':
1128
- return 'https://www.facebook.com/hashtag/' + hashtag;
1129
- case 'instagram':
1130
- return 'https://instagram.com/explore/tags/' + hashtag;
1131
- default: // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case.
1132
- throw new Error('Unknown service name to point hashtag to: ' + serviceName);
1133
- }
1134
- };
1135
- /**
1136
- * Returns the anchor text that should be generated for the match.
1137
- *
1138
- * @return {String}
1139
- */
1140
- HashtagMatch.prototype.getAnchorText = function () {
1141
- return '#' + this.hashtag;
1142
- };
1143
- return HashtagMatch;
1144
- }(Match));
1145
-
1146
- /**
1147
- * @class Autolinker.match.Mention
1148
- * @extends Autolinker.match.Match
1149
- *
1150
- * Represents a Mention match found in an input string which should be Autolinked.
1151
- *
1152
- * See this class's superclass ({@link Autolinker.match.Match}) for more details.
1153
- */
1154
- var MentionMatch = /** @class */ (function (_super) {
1155
- __extends(MentionMatch, _super);
1156
- /**
1157
- * @method constructor
1158
- * @param {Object} cfg The configuration properties for the Match
1159
- * instance, specified in an Object (map).
1160
- */
1161
- function MentionMatch(cfg) {
1162
- var _this = _super.call(this, cfg) || this;
1163
- /**
1164
- * @cfg {String} serviceName
1165
- *
1166
- * The service to point mention matches to. See {@link Autolinker#mention}
1167
- * for available values.
1168
- */
1169
- _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator
1170
- /**
1171
- * @cfg {String} mention (required)
1172
- *
1173
- * The Mention that was matched, without the '@' character.
1174
- */
1175
- _this.mention = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1176
- _this.mention = cfg.mention;
1177
- _this.serviceName = cfg.serviceName;
1178
- return _this;
1179
- }
1180
- /**
1181
- * Returns a string name for the type of match that this class represents.
1182
- * For the case of MentionMatch, returns 'mention'.
1183
- *
1184
- * @return {String}
1185
- */
1186
- MentionMatch.prototype.getType = function () {
1187
- return 'mention';
1188
- };
1189
- /**
1190
- * Returns the mention, without the '@' character.
1191
- *
1192
- * @return {String}
1193
- */
1194
- MentionMatch.prototype.getMention = function () {
1195
- return this.mention;
1196
- };
1197
- /**
1198
- * Returns the configured {@link #serviceName} to point the mention to.
1199
- * Ex: 'instagram', 'twitter', 'soundcloud'.
1200
- *
1201
- * @return {String}
1202
- */
1203
- MentionMatch.prototype.getServiceName = function () {
1204
- return this.serviceName;
1205
- };
1206
- /**
1207
- * Returns the anchor href that should be generated for the match.
1208
- *
1209
- * @return {String}
1210
- */
1211
- MentionMatch.prototype.getAnchorHref = function () {
1212
- switch (this.serviceName) {
1213
- case 'twitter':
1214
- return 'https://twitter.com/' + this.mention;
1215
- case 'instagram':
1216
- return 'https://instagram.com/' + this.mention;
1217
- case 'soundcloud':
1218
- return 'https://soundcloud.com/' + this.mention;
1219
- default: // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case.
1220
- throw new Error('Unknown service name to point mention to: ' + this.serviceName);
1221
- }
1222
- };
1223
- /**
1224
- * Returns the anchor text that should be generated for the match.
1225
- *
1226
- * @return {String}
1227
- */
1228
- MentionMatch.prototype.getAnchorText = function () {
1229
- return '@' + this.mention;
1230
- };
1231
- /**
1232
- * Returns the CSS class suffixes that should be used on a tag built with
1233
- * the match. See {@link Autolinker.match.Match#getCssClassSuffixes} for
1234
- * details.
1235
- *
1236
- * @return {String[]}
1237
- */
1238
- MentionMatch.prototype.getCssClassSuffixes = function () {
1239
- var cssClassSuffixes = _super.prototype.getCssClassSuffixes.call(this), serviceName = this.getServiceName();
1240
- if (serviceName) {
1241
- cssClassSuffixes.push(serviceName);
1242
- }
1243
- return cssClassSuffixes;
1244
- };
1245
- return MentionMatch;
1246
- }(Match));
1247
-
1248
- /**
1249
- * @class Autolinker.match.Phone
1250
- * @extends Autolinker.match.Match
1251
- *
1252
- * Represents a Phone number match found in an input string which should be
1253
- * Autolinked.
1254
- *
1255
- * See this class's superclass ({@link Autolinker.match.Match}) for more
1256
- * details.
1257
- */
1258
- var PhoneMatch = /** @class */ (function (_super) {
1259
- __extends(PhoneMatch, _super);
1260
- /**
1261
- * @method constructor
1262
- * @param {Object} cfg The configuration properties for the Match
1263
- * instance, specified in an Object (map).
1264
- */
1265
- function PhoneMatch(cfg) {
1266
- var _this = _super.call(this, cfg) || this;
1267
- /**
1268
- * @protected
1269
- * @property {String} number (required)
1270
- *
1271
- * The phone number that was matched, without any delimiter characters.
1272
- *
1273
- * Note: This is a string to allow for prefixed 0's.
1274
- */
1275
- _this.number = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1276
- /**
1277
- * @protected
1278
- * @property {Boolean} plusSign (required)
1279
- *
1280
- * `true` if the matched phone number started with a '+' sign. We'll include
1281
- * it in the `tel:` URL if so, as this is needed for international numbers.
1282
- *
1283
- * Ex: '+1 (123) 456 7879'
1284
- */
1285
- _this.plusSign = false; // default value just to get the above doc comment in the ES5 output and documentation generator
1286
- _this.number = cfg.number;
1287
- _this.plusSign = cfg.plusSign;
1288
- return _this;
1289
- }
1290
- /**
1291
- * Returns a string name for the type of match that this class represents.
1292
- * For the case of PhoneMatch, returns 'phone'.
1293
- *
1294
- * @return {String}
1295
- */
1296
- PhoneMatch.prototype.getType = function () {
1297
- return 'phone';
1298
- };
1299
- /**
1300
- * Returns the phone number that was matched as a string, without any
1301
- * delimiter characters.
1302
- *
1303
- * Note: This is a string to allow for prefixed 0's.
1304
- *
1305
- * @return {String}
1306
- */
1307
- PhoneMatch.prototype.getPhoneNumber = function () {
1308
- return this.number;
1309
- };
1310
- /**
1311
- * Alias of {@link #getPhoneNumber}, returns the phone number that was
1312
- * matched as a string, without any delimiter characters.
1313
- *
1314
- * Note: This is a string to allow for prefixed 0's.
1315
- *
1316
- * @return {String}
1317
- */
1318
- PhoneMatch.prototype.getNumber = function () {
1319
- return this.getPhoneNumber();
1320
- };
1321
- /**
1322
- * Returns the anchor href that should be generated for the match.
1323
- *
1324
- * @return {String}
1325
- */
1326
- PhoneMatch.prototype.getAnchorHref = function () {
1327
- return 'tel:' + (this.plusSign ? '+' : '') + this.number;
1328
- };
1329
- /**
1330
- * Returns the anchor text that should be generated for the match.
1331
- *
1332
- * @return {String}
1333
- */
1334
- PhoneMatch.prototype.getAnchorText = function () {
1335
- return this.matchedText;
1336
- };
1337
- return PhoneMatch;
1338
- }(Match));
1339
-
1340
- /**
1341
- * @class Autolinker.match.Url
1342
- * @extends Autolinker.match.Match
1343
- *
1344
- * Represents a Url match found in an input string which should be Autolinked.
1345
- *
1346
- * See this class's superclass ({@link Autolinker.match.Match}) for more details.
1347
- */
1348
- var UrlMatch = /** @class */ (function (_super) {
1349
- __extends(UrlMatch, _super);
1350
- /**
1351
- * @method constructor
1352
- * @param {Object} cfg The configuration properties for the Match
1353
- * instance, specified in an Object (map).
1354
- */
1355
- function UrlMatch(cfg) {
1356
- var _this = _super.call(this, cfg) || this;
1357
- /**
1358
- * @cfg {String} url (required)
1359
- *
1360
- * The url that was matched.
1361
- */
1362
- _this.url = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1363
- /**
1364
- * @cfg {"scheme"/"www"/"tld"} urlMatchType (required)
1365
- *
1366
- * The type of URL match that this class represents. This helps to determine
1367
- * if the match was made in the original text with a prefixed scheme (ex:
1368
- * 'http://www.google.com'), a prefixed 'www' (ex: 'www.google.com'), or
1369
- * was matched by a known top-level domain (ex: 'google.com').
1370
- */
1371
- _this.urlMatchType = 'scheme'; // default value just to get the above doc comment in the ES5 output and documentation generator
1372
- /**
1373
- * @cfg {Boolean} protocolUrlMatch (required)
1374
- *
1375
- * `true` if the URL is a match which already has a protocol (i.e.
1376
- * 'http://'), `false` if the match was from a 'www' or known TLD match.
1377
- */
1378
- _this.protocolUrlMatch = false; // default value just to get the above doc comment in the ES5 output and documentation generator
1379
- /**
1380
- * @cfg {Boolean} protocolRelativeMatch (required)
1381
- *
1382
- * `true` if the URL is a protocol-relative match. A protocol-relative match
1383
- * is a URL that starts with '//', and will be either http:// or https://
1384
- * based on the protocol that the site is loaded under.
1385
- */
1386
- _this.protocolRelativeMatch = false; // default value just to get the above doc comment in the ES5 output and documentation generator
1387
- /**
1388
- * @cfg {Object} stripPrefix (required)
1389
- *
1390
- * The Object form of {@link Autolinker#cfg-stripPrefix}.
1391
- */
1392
- _this.stripPrefix = { scheme: true, www: true }; // default value just to get the above doc comment in the ES5 output and documentation generator
1393
- /**
1394
- * @cfg {Boolean} stripTrailingSlash (required)
1395
- * @inheritdoc Autolinker#cfg-stripTrailingSlash
1396
- */
1397
- _this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator
1398
- /**
1399
- * @cfg {Boolean} decodePercentEncoding (required)
1400
- * @inheritdoc Autolinker#cfg-decodePercentEncoding
1401
- */
1402
- _this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator
1403
- /**
1404
- * @private
1405
- * @property {RegExp} schemePrefixRegex
1406
- *
1407
- * A regular expression used to remove the 'http://' or 'https://' from
1408
- * URLs.
1409
- */
1410
- _this.schemePrefixRegex = /^(https?:\/\/)?/i;
1411
- /**
1412
- * @private
1413
- * @property {RegExp} wwwPrefixRegex
1414
- *
1415
- * A regular expression used to remove the 'www.' from URLs.
1416
- */
1417
- _this.wwwPrefixRegex = /^(https?:\/\/)?(www\.)?/i;
1418
- /**
1419
- * @private
1420
- * @property {RegExp} protocolRelativeRegex
1421
- *
1422
- * The regular expression used to remove the protocol-relative '//' from the {@link #url} string, for purposes
1423
- * of {@link #getAnchorText}. A protocol-relative URL is, for example, "//yahoo.com"
1424
- */
1425
- _this.protocolRelativeRegex = /^\/\//;
1426
- /**
1427
- * @private
1428
- * @property {Boolean} protocolPrepended
1429
- *
1430
- * Will be set to `true` if the 'http://' protocol has been prepended to the {@link #url} (because the
1431
- * {@link #url} did not have a protocol)
1432
- */
1433
- _this.protocolPrepended = false;
1434
- _this.urlMatchType = cfg.urlMatchType;
1435
- _this.url = cfg.url;
1436
- _this.protocolUrlMatch = cfg.protocolUrlMatch;
1437
- _this.protocolRelativeMatch = cfg.protocolRelativeMatch;
1438
- _this.stripPrefix = cfg.stripPrefix;
1439
- _this.stripTrailingSlash = cfg.stripTrailingSlash;
1440
- _this.decodePercentEncoding = cfg.decodePercentEncoding;
1441
- return _this;
1442
- }
1443
- /**
1444
- * Returns a string name for the type of match that this class represents.
1445
- * For the case of UrlMatch, returns 'url'.
1446
- *
1447
- * @return {String}
1448
- */
1449
- UrlMatch.prototype.getType = function () {
1450
- return 'url';
1451
- };
1452
- /**
1453
- * Returns a string name for the type of URL match that this class
1454
- * represents.
1455
- *
1456
- * This helps to determine if the match was made in the original text with a
1457
- * prefixed scheme (ex: 'http://www.google.com'), a prefixed 'www' (ex:
1458
- * 'www.google.com'), or was matched by a known top-level domain (ex:
1459
- * 'google.com').
1460
- *
1461
- * @return {"scheme"/"www"/"tld"}
1462
- */
1463
- UrlMatch.prototype.getUrlMatchType = function () {
1464
- return this.urlMatchType;
1465
- };
1466
- /**
1467
- * Returns the url that was matched, assuming the protocol to be 'http://' if the original
1468
- * match was missing a protocol.
1469
- *
1470
- * @return {String}
1471
- */
1472
- UrlMatch.prototype.getUrl = function () {
1473
- var url = this.url;
1474
- // if the url string doesn't begin with a protocol, assume 'http://'
1475
- if (!this.protocolRelativeMatch && !this.protocolUrlMatch && !this.protocolPrepended) {
1476
- url = this.url = 'http://' + url;
1477
- this.protocolPrepended = true;
1478
- }
1479
- return url;
1480
- };
1481
- /**
1482
- * Returns the anchor href that should be generated for the match.
1483
- *
1484
- * @return {String}
1485
- */
1486
- UrlMatch.prototype.getAnchorHref = function () {
1487
- var url = this.getUrl();
1488
- return url.replace(/&amp;/g, '&'); // any &amp;'s in the URL should be converted back to '&' if they were displayed as &amp; in the source html
1489
- };
1490
- /**
1491
- * Returns the anchor text that should be generated for the match.
1492
- *
1493
- * @return {String}
1494
- */
1495
- UrlMatch.prototype.getAnchorText = function () {
1496
- var anchorText = this.getMatchedText();
1497
- if (this.protocolRelativeMatch) {
1498
- // Strip off any protocol-relative '//' from the anchor text
1499
- anchorText = this.stripProtocolRelativePrefix(anchorText);
1500
- }
1501
- if (this.stripPrefix.scheme) {
1502
- anchorText = this.stripSchemePrefix(anchorText);
1503
- }
1504
- if (this.stripPrefix.www) {
1505
- anchorText = this.stripWwwPrefix(anchorText);
1506
- }
1507
- if (this.stripTrailingSlash) {
1508
- anchorText = this.removeTrailingSlash(anchorText); // remove trailing slash, if there is one
1509
- }
1510
- if (this.decodePercentEncoding) {
1511
- anchorText = this.removePercentEncoding(anchorText);
1512
- }
1513
- return anchorText;
1514
- };
1515
- // ---------------------------------------
1516
- // Utility Functionality
1517
- /**
1518
- * Strips the scheme prefix (such as "http://" or "https://") from the given
1519
- * `url`.
1520
- *
1521
- * @private
1522
- * @param {String} url The text of the anchor that is being generated, for
1523
- * which to strip off the url scheme.
1524
- * @return {String} The `url`, with the scheme stripped.
1525
- */
1526
- UrlMatch.prototype.stripSchemePrefix = function (url) {
1527
- return url.replace(this.schemePrefixRegex, '');
1528
- };
1529
- /**
1530
- * Strips the 'www' prefix from the given `url`.
1531
- *
1532
- * @private
1533
- * @param {String} url The text of the anchor that is being generated, for
1534
- * which to strip off the 'www' if it exists.
1535
- * @return {String} The `url`, with the 'www' stripped.
1536
- */
1537
- UrlMatch.prototype.stripWwwPrefix = function (url) {
1538
- return url.replace(this.wwwPrefixRegex, '$1'); // leave any scheme ($1), it one exists
1539
- };
1540
- /**
1541
- * Strips any protocol-relative '//' from the anchor text.
1542
- *
1543
- * @private
1544
- * @param {String} text The text of the anchor that is being generated, for which to strip off the
1545
- * protocol-relative prefix (such as stripping off "//")
1546
- * @return {String} The `anchorText`, with the protocol-relative prefix stripped.
1547
- */
1548
- UrlMatch.prototype.stripProtocolRelativePrefix = function (text) {
1549
- return text.replace(this.protocolRelativeRegex, '');
1550
- };
1551
- /**
1552
- * Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed.
1553
- *
1554
- * @private
1555
- * @param {String} anchorText The text of the anchor that is being generated, for which to remove any trailing
1556
- * slash ('/') that may exist.
1557
- * @return {String} The `anchorText`, with the trailing slash removed.
1558
- */
1559
- UrlMatch.prototype.removeTrailingSlash = function (anchorText) {
1560
- if (anchorText.charAt(anchorText.length - 1) === '/') {
1561
- anchorText = anchorText.slice(0, -1);
1562
- }
1563
- return anchorText;
1564
- };
1565
- /**
1566
- * Decodes percent-encoded characters from the given `anchorText`, in
1567
- * preparation for the text to be displayed.
1568
- *
1569
- * @private
1570
- * @param {String} anchorText The text of the anchor that is being
1571
- * generated, for which to decode any percent-encoded characters.
1572
- * @return {String} The `anchorText`, with the percent-encoded characters
1573
- * decoded.
1574
- */
1575
- UrlMatch.prototype.removePercentEncoding = function (anchorText) {
1576
- // First, convert a few of the known % encodings to the corresponding
1577
- // HTML entities that could accidentally be interpretted as special
1578
- // HTML characters
1579
- var preProcessedEntityAnchorText = anchorText
1580
- .replace(/%22/gi, '&quot;') // " char
1581
- .replace(/%26/gi, '&amp;') // & char
1582
- .replace(/%27/gi, '&#39;') // ' char
1583
- .replace(/%3C/gi, '&lt;') // < char
1584
- .replace(/%3E/gi, '&gt;'); // > char
1585
- try {
1586
- // Now attempt to decode the rest of the anchor text
1587
- return decodeURIComponent(preProcessedEntityAnchorText);
1588
- }
1589
- catch (e) { // Invalid % escape sequence in the anchor text
1590
- return preProcessedEntityAnchorText;
1591
- }
1592
- };
1593
- return UrlMatch;
1594
- }(Match));
1595
-
1596
- /**
1597
- * @abstract
1598
- * @class Autolinker.matcher.Matcher
1599
- *
1600
- * An abstract class and interface for individual matchers to find matches in
1601
- * an input string with linkified versions of them.
1602
- *
1603
- * Note that Matchers do not take HTML into account - they must be fed the text
1604
- * nodes of any HTML string, which is handled by {@link Autolinker#parse}.
1605
- */
1606
- var Matcher = /** @class */ (function () {
1607
- /**
1608
- * @method constructor
1609
- * @param {Object} cfg The configuration properties for the Matcher
1610
- * instance, specified in an Object (map).
1611
- */
1612
- function Matcher(cfg) {
1613
- /**
1614
- * @cfg {Autolinker.AnchorTagBuilder} tagBuilder (required)
1615
- *
1616
- * Reference to the AnchorTagBuilder instance to use to generate HTML tags
1617
- * for {@link Autolinker.match.Match Matches}.
1618
- */
1619
- this.__jsduckDummyDocProp = null; // property used just to get the above doc comment into the ES5 output and documentation generator
1620
- this.tagBuilder = cfg.tagBuilder;
1621
- }
1622
- return Matcher;
1623
- }());
1624
-
1625
- /*
1626
- * This file builds and stores a library of the common regular expressions used
1627
- * by the Autolinker utility.
1628
- *
1629
- * Other regular expressions may exist ad-hoc, but these are generally the
1630
- * regular expressions that are shared between source files.
1631
- */
1632
- /**
1633
- * Regular expression to match upper and lowercase ASCII letters
1634
- */
1635
- var letterRe = /[A-Za-z]/;
1636
- /**
1637
- * Regular expression to match ASCII digits
1638
- */
1639
- var digitRe = /[\d]/;
1640
- /**
1641
- * Regular expression to match everything *except* ASCII digits
1642
- */
1643
- var nonDigitRe = /[\D]/;
1644
- /**
1645
- * Regular expression to match whitespace
1646
- */
1647
- var whitespaceRe = /\s/;
1648
- /**
1649
- * Regular expression to match quote characters
1650
- */
1651
- var quoteRe = /['"]/;
1652
- /**
1653
- * Regular expression to match the range of ASCII control characters (0-31), and
1654
- * the backspace char (127)
1655
- */
1656
- var controlCharsRe = /[\x00-\x1F\x7F]/;
1657
- /**
1658
- * The string form of a regular expression that would match all of the
1659
- * alphabetic ("letter") chars in the unicode character set when placed in a
1660
- * RegExp character class (`[]`). This includes all international alphabetic
1661
- * characters.
1662
- *
1663
- * These would be the characters matched by unicode regex engines `\p{L}`
1664
- * escape ("all letters").
1665
- *
1666
- * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)
1667
- * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Letter'
1668
- * regex's bmp
1669
- *
1670
- * VERY IMPORTANT: This set of characters is defined inside of a Regular
1671
- * Expression literal rather than a string literal to prevent UglifyJS from
1672
- * compressing the unicode escape sequences into their actual unicode
1673
- * characters. If Uglify compresses these into the unicode characters
1674
- * themselves, this results in the error "Range out of order in character
1675
- * class" when these characters are used inside of a Regular Expression
1676
- * character class (`[]`). See usages of this const. Alternatively, we can set
1677
- * the UglifyJS option `ascii_only` to true for the build, but that doesn't
1678
- * help others who are pulling in Autolinker into their own build and running
1679
- * UglifyJS themselves.
1680
- */
1681
- var alphaCharsStr = /A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC/
1682
- .source; // see note in above variable description
1683
- /**
1684
- * The string form of a regular expression that would match all emoji characters
1685
- * Based on the emoji regex defined in this article: https://thekevinscott.com/emojis-in-javascript/
1686
- */
1687
- var emojiStr = /\u2700-\u27bf\udde6-\uddff\ud800-\udbff\udc00-\udfff\ufe0e\ufe0f\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0\ud83c\udffb-\udfff\u200d\u3299\u3297\u303d\u3030\u24c2\ud83c\udd70-\udd71\udd7e-\udd7f\udd8e\udd91-\udd9a\udde6-\uddff\ude01-\ude02\ude1a\ude2f\ude32-\ude3a\ude50-\ude51\u203c\u2049\u25aa-\u25ab\u25b6\u25c0\u25fb-\u25fe\u00a9\u00ae\u2122\u2139\udc04\u2600-\u26FF\u2b05\u2b06\u2b07\u2b1b\u2b1c\u2b50\u2b55\u231a\u231b\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa\udccf\u2935\u2934\u2190-\u21ff/
1688
- .source;
1689
- /**
1690
- * The string form of a regular expression that would match all of the
1691
- * combining mark characters in the unicode character set when placed in a
1692
- * RegExp character class (`[]`).
1693
- *
1694
- * These would be the characters matched by unicode regex engines `\p{M}`
1695
- * escape ("all marks").
1696
- *
1697
- * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)
1698
- * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Mark'
1699
- * regex's bmp
1700
- *
1701
- * VERY IMPORTANT: This set of characters is defined inside of a Regular
1702
- * Expression literal rather than a string literal to prevent UglifyJS from
1703
- * compressing the unicode escape sequences into their actual unicode
1704
- * characters. If Uglify compresses these into the unicode characters
1705
- * themselves, this results in the error "Range out of order in character
1706
- * class" when these characters are used inside of a Regular Expression
1707
- * character class (`[]`). See usages of this const. Alternatively, we can set
1708
- * the UglifyJS option `ascii_only` to true for the build, but that doesn't
1709
- * help others who are pulling in Autolinker into their own build and running
1710
- * UglifyJS themselves.
1711
- */
1712
- var marksStr = /\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D4-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F/
1713
- .source; // see note in above variable description
1714
- /**
1715
- * The string form of a regular expression that would match all of the
1716
- * alphabetic ("letter") chars, emoji, and combining marks in the unicode character set
1717
- * when placed in a RegExp character class (`[]`). This includes all
1718
- * international alphabetic characters.
1719
- *
1720
- * These would be the characters matched by unicode regex engines `\p{L}\p{M}`
1721
- * escapes and emoji characters.
1722
- */
1723
- var alphaCharsAndMarksStr = alphaCharsStr + emojiStr + marksStr;
1724
- /**
1725
- * The string form of a regular expression that would match all of the
1726
- * decimal number chars in the unicode character set when placed in a RegExp
1727
- * character class (`[]`).
1728
- *
1729
- * These would be the characters matched by unicode regex engines `\p{Nd}`
1730
- * escape ("all decimal numbers")
1731
- *
1732
- * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)
1733
- * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Decimal_Number'
1734
- * regex's bmp
1735
- *
1736
- * VERY IMPORTANT: This set of characters is defined inside of a Regular
1737
- * Expression literal rather than a string literal to prevent UglifyJS from
1738
- * compressing the unicode escape sequences into their actual unicode
1739
- * characters. If Uglify compresses these into the unicode characters
1740
- * themselves, this results in the error "Range out of order in character
1741
- * class" when these characters are used inside of a Regular Expression
1742
- * character class (`[]`). See usages of this const. Alternatively, we can set
1743
- * the UglifyJS option `ascii_only` to true for the build, but that doesn't
1744
- * help others who are pulling in Autolinker into their own build and running
1745
- * UglifyJS themselves.
1746
- */
1747
- var decimalNumbersStr = /0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19/
1748
- .source; // see note in above variable description
1749
- /**
1750
- * The string form of a regular expression that would match all of the
1751
- * letters and decimal number chars in the unicode character set when placed in
1752
- * a RegExp character class (`[]`).
1753
- *
1754
- * These would be the characters matched by unicode regex engines
1755
- * `[\p{L}\p{Nd}]` escape ("all letters and decimal numbers")
1756
- */
1757
- var alphaNumericCharsStr = alphaCharsAndMarksStr + decimalNumbersStr;
1758
- /**
1759
- * The string form of a regular expression that would match all of the
1760
- * letters, combining marks, and decimal number chars in the unicode character
1761
- * set when placed in a RegExp character class (`[]`).
1762
- *
1763
- * These would be the characters matched by unicode regex engines
1764
- * `[\p{L}\p{M}\p{Nd}]` escape ("all letters, combining marks, and decimal
1765
- * numbers")
1766
- */
1767
- var alphaNumericAndMarksCharsStr = alphaCharsAndMarksStr + decimalNumbersStr;
1768
- // Simplified IP regular expression
1769
- var ipStr = '(?:[' + decimalNumbersStr + ']{1,3}\\.){3}[' + decimalNumbersStr + ']{1,3}';
1770
- // Protected domain label which do not allow "-" character on the beginning and the end of a single label
1771
- var domainLabelStr = '[' + alphaNumericAndMarksCharsStr + '](?:[' + alphaNumericAndMarksCharsStr + '\\-]{0,61}[' + alphaNumericAndMarksCharsStr + '])?';
1772
- var getDomainLabelStr = function (group) {
1773
- return '(?=(' + domainLabelStr + '))\\' + group;
1774
- };
1775
- /**
1776
- * A function to match domain names of a URL or email address.
1777
- * Ex: 'google', 'yahoo', 'some-other-company', etc.
1778
- */
1779
- var getDomainNameStr = function (group) {
1780
- return '(?:' + getDomainLabelStr(group) + '(?:\\.' + getDomainLabelStr(group + 1) + '){0,126}|' + ipStr + ')';
1781
- };
1782
- /**
1783
- * A regular expression that is simply the character class of the characters
1784
- * that may be used in a domain name, minus the '-' or '.'
1785
- */
1786
- var domainNameCharRegex = new RegExp("[" + alphaNumericAndMarksCharsStr + "]");
1787
-
1788
- // NOTE: THIS IS A GENERATED FILE
1789
- // To update with the latest TLD list, run `npm run update-tld-regex` or `yarn update-tld-regex` (depending on which you have installed)
1790
- var tldRegex = /(?:xn--vermgensberatung-pwb|xn--vermgensberater-ctb|xn--clchc0ea0b2g2a9gcd|xn--w4r85el8fhu5dnra|northwesternmutual|travelersinsurance|vermögensberatung|xn--3oq18vl8pn36a|xn--5su34j936bgsg|xn--bck1b9a5dre4c|xn--mgbai9azgqp6j|xn--mgberp4a5d4ar|xn--xkc2dl3a5ee0h|vermögensberater|xn--fzys8d69uvgm|xn--mgba7c0bbn0a|xn--xkc2al3hye2a|americanexpress|kerryproperties|sandvikcoromant|xn--i1b6b1a6a2e|xn--kcrx77d1x4a|xn--lgbbat1ad8j|xn--mgba3a4f16a|xn--mgbaakc7dvf|xn--mgbc0a9azcg|xn--nqv7fs00ema|afamilycompany|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|xn--54b7fta0cc|xn--6qq986b3xl|xn--80aqecdr1a|xn--b4w605ferd|xn--fiq228c5hs|xn--h2breg3eve|xn--jlq61u9w7b|xn--mgba3a3ejt|xn--mgbaam7a8h|xn--mgbayh7gpa|xn--mgbb9fbpob|xn--mgbbh1a71e|xn--mgbca7dzdo|xn--mgbi4ecexp|xn--mgbx4cd0ab|xn--rvc1e0am3e|international|lifeinsurance|spreadbetting|travelchannel|wolterskluwer|xn--eckvdtc9d|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--h2brj9c8c|xn--tiq49xqyj|xn--yfro4i67o|xn--ygbi2ammx|construction|lplfinancial|scholarships|versicherung|xn--3e0b707e|xn--45br5cyl|xn--80adxhks|xn--80asehdb|xn--8y0a063a|xn--gckr3f0f|xn--mgb9awbf|xn--mgbab2bd|xn--mgbgu82a|xn--mgbpl2fh|xn--mgbt3dhd|xn--mk1bu44c|xn--ngbc5azd|xn--ngbe9e0a|xn--ogbpf8fl|xn--qcka1pmc|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|rightathome|williamhill|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--3bst00m|xn--3ds443g|xn--3hcrj9c|xn--42c2d9a|xn--45brj9c|xn--55qw42g|xn--6frz82g|xn--80ao21a|xn--9krt00a|xn--cck2b3b|xn--czr694b|xn--d1acj3b|xn--efvy88h|xn--estv75g|xn--fct429k|xn--fjq720a|xn--flw351e|xn--g2xx48c|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|xn--imr513n|xn--j6w193g|xn--jvr189m|xn--kprw13d|xn--kpry57d|xn--kpu716f|xn--mgbbh1a|xn--mgbtx2b|xn--mix891f|xn--nyqy26a|xn--otu796d|xn--pbt977c|xn--pgbs0dh|xn--q9jyb4c|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--vuq861b|xn--w4rs40l|xn--xhq521b|xn--zfr164b|சிங்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nationwide|newholland|nextdirect|onyourside|properties|protection|prudential|realestate|republican|restaurant|schaeffler|swiftcover|tatamotors|technology|telefonica|university|vistaprint|vlaanderen|volkswagen|xn--30rr7y|xn--3pxu8k|xn--45q11c|xn--4gbrim|xn--55qx5d|xn--5tzm5g|xn--80aswg|xn--90a3ac|xn--9dbq2a|xn--9et52u|xn--c2br7g|xn--cg4bki|xn--czrs0t|xn--czru2d|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--io0a7i|xn--kput3i|xn--mxtq1m|xn--o3cw4h|xn--pssy2u|xn--unup4y|xn--wgbh1c|xn--wgbl6a|xn--y9a3aq|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|fujixerox|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|honeywell|institute|insurance|kuokgroup|ladbrokes|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|scjohnson|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|xn--90ais|xn--c1avg|xn--d1alf|xn--e1a4c|xn--fhbei|xn--j1aef|xn--j1amh|xn--l1acc|xn--ngbrx|xn--nqv7f|xn--p1acf|xn--tckwe|xn--vhquv|yodobashi|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|budapest|builders|business|capetown|catering|catholic|chrysler|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|esurance|etisalat|everbank|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|movistar|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|symantec|training|uconnect|vanguard|ventures|verisign|woodside|xn--90ae|xn--node|xn--p1ai|xn--qxam|yokohama|السعودية|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|cartier|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|iselect|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lancome|lanxess|lasalle|latrobe|leclerc|liaison|limited|lincoln|markets|metlife|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|shriram|singles|staples|starhub|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|yamaxun|youtube|zuerich|католик|اتصالات|الجزائر|العليان|پاکستان|كاثوليك|موبايلي|இந்தியா|abarth|abbott|abbvie|active|africa|agency|airbus|airtel|alipay|alsace|alstom|anquan|aramco|author|bayern|beauty|berlin|bharti|blanco|bostik|boston|broker|camera|career|caseih|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|mobily|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|piaget|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|warman|webcam|xihuan|yachts|yandex|zappos|москва|онлайн|ابوظبي|ارامكو|الاردن|المغرب|امارات|فلسطين|مليسيا|भारतम्|இலங்கை|ファッション|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|dodge|drive|dubai|earth|edeka|email|epost|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glade|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|intel|irish|iveco|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|lixil|loans|locus|lotte|lotto|lupin|macys|mango|media|miami|money|mopar|movie|nadex|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|yahoo|zippo|ایران|بازار|بھارت|سودان|سورية|همراه|भारोत|संगठन|বাংলা|భారత్|ഭാരതം|嘉里大酒店|aarp|able|adac|aero|aigo|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|doha|duck|duns|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|raid|read|reit|rent|rest|rich|rmit|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scor|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|yoga|zara|zero|zone|дети|сайт|بارت|بيتك|ڀارت|تونس|شبكة|عراق|عمان|موقع|भारत|ভারত|ভাৰত|ਭਾਰਤ|ભારત|ଭାରତ|ಭಾರತ|ලංකා|グーグル|クラウド|ポイント|大众汽车|组织机构|電訊盈科|香格里拉|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bnl|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceb|ceo|cfa|cfd|com|crs|csc|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jcp|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|off|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|qvc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|srl|srt|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|xxx|xyz|you|yun|zip|бел|ком|қаз|мкд|мон|орг|рус|срб|укр|հայ|קום|عرب|قطر|كوم|مصر|कॉम|नेट|คอม|ไทย|ストア|セール|みんな|中文网|天主教|我爱你|新加坡|淡马锡|诺基亚|飞利浦|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|бг|ею|рф|გე|닷넷|닷컴|삼성|한국|コム|世界|中信|中国|中國|企业|佛山|信息|健康|八卦|公司|公益|台湾|台灣|商城|商店|商标|嘉里|在线|大拿|娱乐|家電|工行|广东|微博|慈善|手机|手表|招聘|政务|政府|新闻|时尚|書籍|机构|游戏|澳門|点看|珠宝|移动|网址|网店|网站|网络|联通|谷歌|购物|通販|集团|食品|餐厅|香港)/;
1791
-
1792
- // For debugging: search for other "For debugging" lines
1793
- // import CliTable from 'cli-table';
1794
- // RegExp objects which are shared by all instances of EmailMatcher. These are
1795
- // here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is
1796
- // called multiple times, thus instantiating EmailMatcher and its RegExp
1797
- // objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314).
1798
- // See descriptions of the properties where they are used for details about them
1799
- var localPartCharRegex = new RegExp("[" + alphaNumericAndMarksCharsStr + "!#$%&'*+/=?^_`{|}~-]");
1800
- var strictTldRegex = new RegExp("^" + tldRegex.source + "$");
1801
- /**
1802
- * @class Autolinker.matcher.Email
1803
- * @extends Autolinker.matcher.Matcher
1804
- *
1805
- * Matcher to find email matches in an input string.
1806
- *
1807
- * See this class's superclass ({@link Autolinker.matcher.Matcher}) for more details.
1808
- */
1809
- var EmailMatcher = /** @class */ (function (_super) {
1810
- __extends(EmailMatcher, _super);
1811
- function EmailMatcher() {
1812
- var _this = _super !== null && _super.apply(this, arguments) || this;
1813
- /**
1814
- * Valid characters that can be used in the "local" part of an email address,
1815
- * i.e. the "name" part of "name@site.com"
1816
- */
1817
- _this.localPartCharRegex = localPartCharRegex;
1818
- /**
1819
- * Stricter TLD regex which adds a beginning and end check to ensure
1820
- * the string is a valid TLD
1821
- */
1822
- _this.strictTldRegex = strictTldRegex;
1823
- return _this;
1824
- }
1825
- /**
1826
- * @inheritdoc
1827
- */
1828
- EmailMatcher.prototype.parseMatches = function (text) {
1829
- var tagBuilder = this.tagBuilder, localPartCharRegex = this.localPartCharRegex, strictTldRegex = this.strictTldRegex, matches = [], len = text.length, noCurrentEmailMatch = new CurrentEmailMatch();
1830
- // for matching a 'mailto:' prefix
1831
- var mailtoTransitions = {
1832
- 'm': 'a',
1833
- 'a': 'i',
1834
- 'i': 'l',
1835
- 'l': 't',
1836
- 't': 'o',
1837
- 'o': ':',
1838
- };
1839
- var charIdx = 0, state = 0 /* NonEmailMatch */, currentEmailMatch = noCurrentEmailMatch;
1840
- // For debugging: search for other "For debugging" lines
1841
- // const table = new CliTable( {
1842
- // head: [ 'charIdx', 'char', 'state', 'charIdx', 'currentEmailAddress.idx', 'hasDomainDot' ]
1843
- // } );
1844
- while (charIdx < len) {
1845
- var char = text.charAt(charIdx);
1846
- // For debugging: search for other "For debugging" lines
1847
- // table.push(
1848
- // [ charIdx, char, State[ state ], charIdx, currentEmailAddress.idx, currentEmailAddress.hasDomainDot ]
1849
- // );
1850
- switch (state) {
1851
- case 0 /* NonEmailMatch */:
1852
- stateNonEmailAddress(char);
1853
- break;
1854
- case 1 /* Mailto */:
1855
- stateMailTo(text.charAt(charIdx - 1), char);
1856
- break;
1857
- case 2 /* LocalPart */:
1858
- stateLocalPart(char);
1859
- break;
1860
- case 3 /* LocalPartDot */:
1861
- stateLocalPartDot(char);
1862
- break;
1863
- case 4 /* AtSign */:
1864
- stateAtSign(char);
1865
- break;
1866
- case 5 /* DomainChar */:
1867
- stateDomainChar(char);
1868
- break;
1869
- case 6 /* DomainHyphen */:
1870
- stateDomainHyphen(char);
1871
- break;
1872
- case 7 /* DomainDot */:
1873
- stateDomainDot(char);
1874
- break;
1875
- default:
1876
- throwUnhandledCaseError(state);
1877
- }
1878
- // For debugging: search for other "For debugging" lines
1879
- // table.push(
1880
- // [ charIdx, char, State[ state ], charIdx, currentEmailAddress.idx, currentEmailAddress.hasDomainDot ]
1881
- // );
1882
- charIdx++;
1883
- }
1884
- // Capture any valid match at the end of the string
1885
- captureMatchIfValidAndReset();
1886
- // For debugging: search for other "For debugging" lines
1887
- //console.log( '\n' + table.toString() );
1888
- return matches;
1889
- // Handles the state when we're not in an email address
1890
- function stateNonEmailAddress(char) {
1891
- if (char === 'm') {
1892
- beginEmailMatch(1 /* Mailto */);
1893
- }
1894
- else if (localPartCharRegex.test(char)) {
1895
- beginEmailMatch();
1896
- }
1897
- else ;
1898
- }
1899
- // Handles if we're reading a 'mailto:' prefix on the string
1900
- function stateMailTo(prevChar, char) {
1901
- if (prevChar === ':') {
1902
- // We've reached the end of the 'mailto:' prefix
1903
- if (localPartCharRegex.test(char)) {
1904
- state = 2 /* LocalPart */;
1905
- currentEmailMatch = new CurrentEmailMatch(__assign({}, currentEmailMatch, { hasMailtoPrefix: true }));
1906
- }
1907
- else {
1908
- // we've matched 'mailto:' but didn't get anything meaningful
1909
- // immediately afterwards (for example, we encountered a
1910
- // space character, or an '@' character which formed 'mailto:@'
1911
- resetToNonEmailMatchState();
1912
- }
1913
- }
1914
- else if (mailtoTransitions[prevChar] === char) ;
1915
- else if (localPartCharRegex.test(char)) {
1916
- // We we're reading a prefix of 'mailto:', but encountered a
1917
- // different character that didn't continue the prefix
1918
- state = 2 /* LocalPart */;
1919
- }
1920
- else if (char === '.') {
1921
- // We we're reading a prefix of 'mailto:', but encountered a
1922
- // dot character
1923
- state = 3 /* LocalPartDot */;
1924
- }
1925
- else if (char === '@') {
1926
- // We we're reading a prefix of 'mailto:', but encountered a
1927
- // an @ character
1928
- state = 4 /* AtSign */;
1929
- }
1930
- else {
1931
- // not an email address character, return to "NonEmailAddress" state
1932
- resetToNonEmailMatchState();
1933
- }
1934
- }
1935
- // Handles the state when we're currently in the "local part" of an
1936
- // email address (as opposed to the "domain part")
1937
- function stateLocalPart(char) {
1938
- if (char === '.') {
1939
- state = 3 /* LocalPartDot */;
1940
- }
1941
- else if (char === '@') {
1942
- state = 4 /* AtSign */;
1943
- }
1944
- else if (localPartCharRegex.test(char)) ;
1945
- else {
1946
- // not an email address character, return to "NonEmailAddress" state
1947
- resetToNonEmailMatchState();
1948
- }
1949
- }
1950
- // Handles the state where we've read
1951
- function stateLocalPartDot(char) {
1952
- if (char === '.') {
1953
- // We read a second '.' in a row, not a valid email address
1954
- // local part
1955
- resetToNonEmailMatchState();
1956
- }
1957
- else if (char === '@') {
1958
- // We read the '@' character immediately after a dot ('.'), not
1959
- // an email address
1960
- resetToNonEmailMatchState();
1961
- }
1962
- else if (localPartCharRegex.test(char)) {
1963
- state = 2 /* LocalPart */;
1964
- }
1965
- else {
1966
- // Anything else, not an email address
1967
- resetToNonEmailMatchState();
1968
- }
1969
- }
1970
- function stateAtSign(char) {
1971
- if (domainNameCharRegex.test(char)) {
1972
- state = 5 /* DomainChar */;
1973
- }
1974
- else {
1975
- // Anything else, not an email address
1976
- resetToNonEmailMatchState();
1977
- }
1978
- }
1979
- function stateDomainChar(char) {
1980
- if (char === '.') {
1981
- state = 7 /* DomainDot */;
1982
- }
1983
- else if (char === '-') {
1984
- state = 6 /* DomainHyphen */;
1985
- }
1986
- else if (domainNameCharRegex.test(char)) ;
1987
- else {
1988
- // Anything else, we potentially matched if the criteria has
1989
- // been met
1990
- captureMatchIfValidAndReset();
1991
- }
1992
- }
1993
- function stateDomainHyphen(char) {
1994
- if (char === '-' || char === '.') {
1995
- // Not valid to have two hyphens ("--") or hypen+dot ("-.")
1996
- captureMatchIfValidAndReset();
1997
- }
1998
- else if (domainNameCharRegex.test(char)) {
1999
- state = 5 /* DomainChar */;
2000
- }
2001
- else {
2002
- // Anything else
2003
- captureMatchIfValidAndReset();
2004
- }
2005
- }
2006
- function stateDomainDot(char) {
2007
- if (char === '.' || char === '-') {
2008
- // not valid to have two dots ("..") or dot+hypen (".-")
2009
- captureMatchIfValidAndReset();
2010
- }
2011
- else if (domainNameCharRegex.test(char)) {
2012
- state = 5 /* DomainChar */;
2013
- // After having read a '.' and then a valid domain character,
2014
- // we now know that the domain part of the email is valid, and
2015
- // we have found at least a partial EmailMatch (however, the
2016
- // email address may have additional characters from this point)
2017
- currentEmailMatch = new CurrentEmailMatch(__assign({}, currentEmailMatch, { hasDomainDot: true }));
2018
- }
2019
- else {
2020
- // Anything else
2021
- captureMatchIfValidAndReset();
2022
- }
2023
- }
2024
- function beginEmailMatch(newState) {
2025
- if (newState === void 0) { newState = 2 /* LocalPart */; }
2026
- state = newState;
2027
- currentEmailMatch = new CurrentEmailMatch({ idx: charIdx });
2028
- }
2029
- function resetToNonEmailMatchState() {
2030
- state = 0 /* NonEmailMatch */;
2031
- currentEmailMatch = noCurrentEmailMatch;
2032
- }
2033
- /*
2034
- * Captures the current email address as an EmailMatch if it's valid,
2035
- * and resets the state to read another email address.
2036
- */
2037
- function captureMatchIfValidAndReset() {
2038
- if (currentEmailMatch.hasDomainDot) { // we need at least one dot in the domain to be considered a valid email address
2039
- var matchedText = text.slice(currentEmailMatch.idx, charIdx);
2040
- // If we read a '.' or '-' char that ended the email address
2041
- // (valid domain name characters, but only valid email address
2042
- // characters if they are followed by something else), strip
2043
- // it off now
2044
- if (/[-.]$/.test(matchedText)) {
2045
- matchedText = matchedText.slice(0, -1);
2046
- }
2047
- var emailAddress = currentEmailMatch.hasMailtoPrefix
2048
- ? matchedText.slice('mailto:'.length)
2049
- : matchedText;
2050
- // if the email address has a valid TLD, add it to the list of matches
2051
- if (doesEmailHaveValidTld(emailAddress)) {
2052
- matches.push(new EmailMatch({
2053
- tagBuilder: tagBuilder,
2054
- matchedText: matchedText,
2055
- offset: currentEmailMatch.idx,
2056
- email: emailAddress
2057
- }));
2058
- }
2059
- }
2060
- resetToNonEmailMatchState();
2061
- /**
2062
- * Determines if the given email address has a valid TLD or not
2063
- * @param {string} emailAddress - email address
2064
- * @return {Boolean} - true is email have valid TLD, false otherwise
2065
- */
2066
- function doesEmailHaveValidTld(emailAddress) {
2067
- var emailAddressTld = emailAddress.split('.').pop() || '';
2068
- var emailAddressNormalized = emailAddressTld.toLowerCase();
2069
- var isValidTld = strictTldRegex.test(emailAddressNormalized);
2070
- return isValidTld;
2071
- }
2072
- }
2073
- };
2074
- return EmailMatcher;
2075
- }(Matcher));
2076
- var CurrentEmailMatch = /** @class */ (function () {
2077
- function CurrentEmailMatch(cfg) {
2078
- if (cfg === void 0) { cfg = {}; }
2079
- this.idx = cfg.idx !== undefined ? cfg.idx : -1;
2080
- this.hasMailtoPrefix = !!cfg.hasMailtoPrefix;
2081
- this.hasDomainDot = !!cfg.hasDomainDot;
2082
- }
2083
- return CurrentEmailMatch;
2084
- }());
2085
-
2086
- /**
2087
- * @private
2088
- * @class Autolinker.matcher.UrlMatchValidator
2089
- * @singleton
2090
- *
2091
- * Used by Autolinker to filter out false URL positives from the
2092
- * {@link Autolinker.matcher.Url UrlMatcher}.
2093
- *
2094
- * Due to the limitations of regular expressions (including the missing feature
2095
- * of look-behinds in JS regular expressions), we cannot always determine the
2096
- * validity of a given match. This class applies a bit of additional logic to
2097
- * filter out any false positives that have been matched by the
2098
- * {@link Autolinker.matcher.Url UrlMatcher}.
2099
- */
2100
- var UrlMatchValidator = /** @class */ (function () {
2101
- function UrlMatchValidator() {
2102
- }
2103
- /**
2104
- * Determines if a given URL match found by the {@link Autolinker.matcher.Url UrlMatcher}
2105
- * is valid. Will return `false` for:
2106
- *
2107
- * 1) URL matches which do not have at least have one period ('.') in the
2108
- * domain name (effectively skipping over matches like "abc:def").
2109
- * However, URL matches with a protocol will be allowed (ex: 'http://localhost')
2110
- * 2) URL matches which do not have at least one word character in the
2111
- * domain name (effectively skipping over matches like "git:1.0").
2112
- * However, URL matches with a protocol will be allowed (ex: 'intra-net://271219.76')
2113
- * 3) A protocol-relative url match (a URL beginning with '//') whose
2114
- * previous character is a word character (effectively skipping over
2115
- * strings like "abc//google.com")
2116
- *
2117
- * Otherwise, returns `true`.
2118
- *
2119
- * @param {String} urlMatch The matched URL, if there was one. Will be an
2120
- * empty string if the match is not a URL match.
2121
- * @param {String} protocolUrlMatch The match URL string for a protocol
2122
- * match. Ex: 'http://yahoo.com'. This is used to match something like
2123
- * 'http://localhost', where we won't double check that the domain name
2124
- * has at least one '.' in it.
2125
- * @return {Boolean} `true` if the match given is valid and should be
2126
- * processed, or `false` if the match is invalid and/or should just not be
2127
- * processed.
2128
- */
2129
- UrlMatchValidator.isValid = function (urlMatch, protocolUrlMatch) {
2130
- if ((protocolUrlMatch && !this.isValidUriScheme(protocolUrlMatch)) ||
2131
- this.urlMatchDoesNotHaveProtocolOrDot(urlMatch, protocolUrlMatch) || // At least one period ('.') must exist in the URL match for us to consider it an actual URL, *unless* it was a full protocol match (like 'http://localhost')
2132
- (this.urlMatchDoesNotHaveAtLeastOneWordChar(urlMatch, protocolUrlMatch) && // At least one letter character must exist in the domain name after a protocol match. Ex: skip over something like "git:1.0"
2133
- !this.isValidIpAddress(urlMatch)) || // Except if it's an IP address
2134
- this.containsMultipleDots(urlMatch)) {
2135
- return false;
2136
- }
2137
- return true;
2138
- };
2139
- UrlMatchValidator.isValidIpAddress = function (uriSchemeMatch) {
2140
- var newRegex = new RegExp(this.hasFullProtocolRegex.source + this.ipRegex.source);
2141
- var uriScheme = uriSchemeMatch.match(newRegex);
2142
- return uriScheme !== null;
2143
- };
2144
- UrlMatchValidator.containsMultipleDots = function (urlMatch) {
2145
- var stringBeforeSlash = urlMatch;
2146
- if (this.hasFullProtocolRegex.test(urlMatch)) {
2147
- stringBeforeSlash = urlMatch.split('://')[1];
2148
- }
2149
- return stringBeforeSlash.split('/')[0].indexOf("..") > -1;
2150
- };
2151
- /**
2152
- * Determines if the URI scheme is a valid scheme to be autolinked. Returns
2153
- * `false` if the scheme is 'javascript:' or 'vbscript:'
2154
- *
2155
- * @private
2156
- * @param {String} uriSchemeMatch The match URL string for a full URI scheme
2157
- * match. Ex: 'http://yahoo.com' or 'mailto:a@a.com'.
2158
- * @return {Boolean} `true` if the scheme is a valid one, `false` otherwise.
2159
- */
2160
- UrlMatchValidator.isValidUriScheme = function (uriSchemeMatch) {
2161
- var uriSchemeMatchArr = uriSchemeMatch.match(this.uriSchemeRegex), uriScheme = uriSchemeMatchArr && uriSchemeMatchArr[0].toLowerCase();
2162
- return (uriScheme !== 'javascript:' && uriScheme !== 'vbscript:');
2163
- };
2164
- /**
2165
- * Determines if a URL match does not have either:
2166
- *
2167
- * a) a full protocol (i.e. 'http://'), or
2168
- * b) at least one dot ('.') in the domain name (for a non-full-protocol
2169
- * match).
2170
- *
2171
- * Either situation is considered an invalid URL (ex: 'git:d' does not have
2172
- * either the '://' part, or at least one dot in the domain name. If the
2173
- * match was 'git:abc.com', we would consider this valid.)
2174
- *
2175
- * @private
2176
- * @param {String} urlMatch The matched URL, if there was one. Will be an
2177
- * empty string if the match is not a URL match.
2178
- * @param {String} protocolUrlMatch The match URL string for a protocol
2179
- * match. Ex: 'http://yahoo.com'. This is used to match something like
2180
- * 'http://localhost', where we won't double check that the domain name
2181
- * has at least one '.' in it.
2182
- * @return {Boolean} `true` if the URL match does not have a full protocol,
2183
- * or at least one dot ('.') in a non-full-protocol match.
2184
- */
2185
- UrlMatchValidator.urlMatchDoesNotHaveProtocolOrDot = function (urlMatch, protocolUrlMatch) {
2186
- return (!!urlMatch && (!protocolUrlMatch || !this.hasFullProtocolRegex.test(protocolUrlMatch)) && urlMatch.indexOf('.') === -1);
2187
- };
2188
- /**
2189
- * Determines if a URL match does not have either:
2190
- *
2191
- * a) a full protocol (i.e. 'http://'), or
2192
- * b) at least one word character after the protocol (i.e. in the domain name)
2193
- *
2194
- * At least one letter character must exist in the domain name after a
2195
- * protocol match. Ex: skip over something like "git:1.0"
2196
- *
2197
- * @private
2198
- * @param {String} urlMatch The matched URL, if there was one. Will be an
2199
- * empty string if the match is not a URL match.
2200
- * @param {String} protocolUrlMatch The match URL string for a protocol
2201
- * match. Ex: 'http://yahoo.com'. This is used to know whether or not we
2202
- * have a protocol in the URL string, in order to check for a word
2203
- * character after the protocol separator (':').
2204
- * @return {Boolean} `true` if the URL match does not have a full protocol, or
2205
- * at least one word character in it, `false` otherwise.
2206
- */
2207
- UrlMatchValidator.urlMatchDoesNotHaveAtLeastOneWordChar = function (urlMatch, protocolUrlMatch) {
2208
- if (urlMatch && protocolUrlMatch) {
2209
- return !this.hasFullProtocolRegex.test(protocolUrlMatch) && !this.hasWordCharAfterProtocolRegex.test(urlMatch);
2210
- }
2211
- else {
2212
- return false;
2213
- }
2214
- };
2215
- /**
2216
- * Regex to test for a full protocol, with the two trailing slashes. Ex: 'http://'
2217
- *
2218
- * @private
2219
- * @property {RegExp} hasFullProtocolRegex
2220
- */
2221
- UrlMatchValidator.hasFullProtocolRegex = /^[A-Za-z][-.+A-Za-z0-9]*:\/\//;
2222
- /**
2223
- * Regex to find the URI scheme, such as 'mailto:'.
2224
- *
2225
- * This is used to filter out 'javascript:' and 'vbscript:' schemes.
2226
- *
2227
- * @private
2228
- * @property {RegExp} uriSchemeRegex
2229
- */
2230
- UrlMatchValidator.uriSchemeRegex = /^[A-Za-z][-.+A-Za-z0-9]*:/;
2231
- /**
2232
- * Regex to determine if at least one word char exists after the protocol (i.e. after the ':')
2233
- *
2234
- * @private
2235
- * @property {RegExp} hasWordCharAfterProtocolRegex
2236
- */
2237
- UrlMatchValidator.hasWordCharAfterProtocolRegex = new RegExp(":[^\\s]*?[" + alphaCharsStr + "]");
2238
- /**
2239
- * Regex to determine if the string is a valid IP address
2240
- *
2241
- * @private
2242
- * @property {RegExp} ipRegex
2243
- */
2244
- UrlMatchValidator.ipRegex = /[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?(:[0-9]*)?\/?$/;
2245
- return UrlMatchValidator;
2246
- }());
2247
-
2248
- // RegExp objects which are shared by all instances of UrlMatcher. These are
2249
- // here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is
2250
- // called multiple times, thus instantiating UrlMatcher and its RegExp
2251
- // objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314).
2252
- // See descriptions of the properties where they are used for details about them
2253
- var matcherRegex = (function () {
2254
- var schemeRegex = /(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\/\/)(?!\d+\/?)(?:\/\/)?)/, // match protocol, allow in format "http://" or "mailto:". However, do not match the first part of something like 'link:http://www.google.com' (i.e. don't match "link:"). Also, make sure we don't interpret 'google.com:8000' as if 'google.com' was a protocol here (i.e. ignore a trailing port number in this regex)
2255
- wwwRegex = /(?:www\.)/, // starting with 'www.'
2256
- // Allow optional path, query string, and hash anchor, not ending in the following characters: "?!:,.;"
2257
- // http://blog.codinghorror.com/the-problem-with-urls/
2258
- urlSuffixRegex = new RegExp('[/?#](?:[' + alphaNumericAndMarksCharsStr + '\\-+&@#/%=~_()|\'$*\\[\\]{}?!:,.;^\u2713]*[' + alphaNumericAndMarksCharsStr + '\\-+&@#/%=~_()|\'$*\\[\\]{}\u2713])?');
2259
- return new RegExp([
2260
- '(?:',
2261
- '(',
2262
- schemeRegex.source,
2263
- getDomainNameStr(2),
2264
- ')',
2265
- '|',
2266
- '(',
2267
- '(//)?',
2268
- wwwRegex.source,
2269
- getDomainNameStr(6),
2270
- ')',
2271
- '|',
2272
- '(',
2273
- '(//)?',
2274
- getDomainNameStr(10) + '\\.',
2275
- tldRegex.source,
2276
- '(?![-' + alphaNumericCharsStr + '])',
2277
- ')',
2278
- ')',
2279
- '(?::[0-9]+)?',
2280
- '(?:' + urlSuffixRegex.source + ')?' // match for path, query string, and/or hash anchor - optional
2281
- ].join(""), 'gi');
2282
- })();
2283
- var wordCharRegExp = new RegExp('[' + alphaNumericAndMarksCharsStr + ']');
2284
- /**
2285
- * @class Autolinker.matcher.Url
2286
- * @extends Autolinker.matcher.Matcher
2287
- *
2288
- * Matcher to find URL matches in an input string.
2289
- *
2290
- * See this class's superclass ({@link Autolinker.matcher.Matcher}) for more details.
2291
- */
2292
- var UrlMatcher = /** @class */ (function (_super) {
2293
- __extends(UrlMatcher, _super);
2294
- /**
2295
- * @method constructor
2296
- * @param {Object} cfg The configuration properties for the Match instance,
2297
- * specified in an Object (map).
2298
- */
2299
- function UrlMatcher(cfg) {
2300
- var _this = _super.call(this, cfg) || this;
2301
- /**
2302
- * @cfg {Object} stripPrefix (required)
2303
- *
2304
- * The Object form of {@link Autolinker#cfg-stripPrefix}.
2305
- */
2306
- _this.stripPrefix = { scheme: true, www: true }; // default value just to get the above doc comment in the ES5 output and documentation generator
2307
- /**
2308
- * @cfg {Boolean} stripTrailingSlash (required)
2309
- * @inheritdoc Autolinker#stripTrailingSlash
2310
- */
2311
- _this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator
2312
- /**
2313
- * @cfg {Boolean} decodePercentEncoding (required)
2314
- * @inheritdoc Autolinker#decodePercentEncoding
2315
- */
2316
- _this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator
2317
- /**
2318
- * @protected
2319
- * @property {RegExp} matcherRegex
2320
- *
2321
- * The regular expression to match URLs with an optional scheme, port
2322
- * number, path, query string, and hash anchor.
2323
- *
2324
- * Example matches:
2325
- *
2326
- * http://google.com
2327
- * www.google.com
2328
- * google.com/path/to/file?q1=1&q2=2#myAnchor
2329
- *
2330
- *
2331
- * This regular expression will have the following capturing groups:
2332
- *
2333
- * 1. Group that matches a scheme-prefixed URL (i.e. 'http://google.com').
2334
- * This is used to match scheme URLs with just a single word, such as
2335
- * 'http://localhost', where we won't double check that the domain name
2336
- * has at least one dot ('.') in it.
2337
- * 2. Group that matches a 'www.' prefixed URL. This is only matched if the
2338
- * 'www.' text was not prefixed by a scheme (i.e.: not prefixed by
2339
- * 'http://', 'ftp:', etc.)
2340
- * 3. A protocol-relative ('//') match for the case of a 'www.' prefixed
2341
- * URL. Will be an empty string if it is not a protocol-relative match.
2342
- * We need to know the character before the '//' in order to determine
2343
- * if it is a valid match or the // was in a string we don't want to
2344
- * auto-link.
2345
- * 4. Group that matches a known TLD (top level domain), when a scheme
2346
- * or 'www.'-prefixed domain is not matched.
2347
- * 5. A protocol-relative ('//') match for the case of a known TLD prefixed
2348
- * URL. Will be an empty string if it is not a protocol-relative match.
2349
- * See #3 for more info.
2350
- */
2351
- _this.matcherRegex = matcherRegex;
2352
- /**
2353
- * A regular expression to use to check the character before a protocol-relative
2354
- * URL match. We don't want to match a protocol-relative URL if it is part
2355
- * of another word.
2356
- *
2357
- * For example, we want to match something like "Go to: //google.com",
2358
- * but we don't want to match something like "abc//google.com"
2359
- *
2360
- * This regular expression is used to test the character before the '//'.
2361
- *
2362
- * @protected
2363
- * @type {RegExp} wordCharRegExp
2364
- */
2365
- _this.wordCharRegExp = wordCharRegExp;
2366
- _this.stripPrefix = cfg.stripPrefix;
2367
- _this.stripTrailingSlash = cfg.stripTrailingSlash;
2368
- _this.decodePercentEncoding = cfg.decodePercentEncoding;
2369
- return _this;
2370
- }
2371
- /**
2372
- * @inheritdoc
2373
- */
2374
- UrlMatcher.prototype.parseMatches = function (text) {
2375
- var matcherRegex = this.matcherRegex, stripPrefix = this.stripPrefix, stripTrailingSlash = this.stripTrailingSlash, decodePercentEncoding = this.decodePercentEncoding, tagBuilder = this.tagBuilder, matches = [], match;
2376
- var _loop_1 = function () {
2377
- var matchStr = match[0], schemeUrlMatch = match[1], wwwUrlMatch = match[4], wwwProtocolRelativeMatch = match[5],
2378
- //tldUrlMatch = match[ 8 ], -- not needed at the moment
2379
- tldProtocolRelativeMatch = match[9], offset = match.index, protocolRelativeMatch = wwwProtocolRelativeMatch || tldProtocolRelativeMatch, prevChar = text.charAt(offset - 1);
2380
- if (!UrlMatchValidator.isValid(matchStr, schemeUrlMatch)) {
2381
- return "continue";
2382
- }
2383
- // If the match is preceded by an '@' character, then it is either
2384
- // an email address or a username. Skip these types of matches.
2385
- if (offset > 0 && prevChar === '@') {
2386
- return "continue";
2387
- }
2388
- // If it's a protocol-relative '//' match, but the character before the '//'
2389
- // was a word character (i.e. a letter/number), then we found the '//' in the
2390
- // middle of another word (such as "asdf//asdf.com"). In this case, skip the
2391
- // match.
2392
- if (offset > 0 && protocolRelativeMatch && this_1.wordCharRegExp.test(prevChar)) {
2393
- return "continue";
2394
- }
2395
- // If the URL ends with a question mark, don't include the question
2396
- // mark as part of the URL. We'll assume the question mark was the
2397
- // end of a sentence, such as: "Going to google.com?"
2398
- if (/\?$/.test(matchStr)) {
2399
- matchStr = matchStr.substr(0, matchStr.length - 1);
2400
- }
2401
- // Handle a closing parenthesis or square bracket at the end of the
2402
- // match, and exclude it if there is not a matching open parenthesis
2403
- // or square bracket in the match itself.
2404
- if (this_1.matchHasUnbalancedClosingParen(matchStr)) {
2405
- matchStr = matchStr.substr(0, matchStr.length - 1); // remove the trailing ")"
2406
- }
2407
- else {
2408
- // Handle an invalid character after the TLD
2409
- var pos = this_1.matchHasInvalidCharAfterTld(matchStr, schemeUrlMatch);
2410
- if (pos > -1) {
2411
- matchStr = matchStr.substr(0, pos); // remove the trailing invalid chars
2412
- }
2413
- }
2414
- // The autolinker accepts many characters in a url's scheme (like `fake://test.com`).
2415
- // However, in cases where a URL is missing whitespace before an obvious link,
2416
- // (for example: `nowhitespacehttp://www.test.com`), we only want the match to start
2417
- // at the http:// part. We will check if the match contains a common scheme and then
2418
- // shift the match to start from there.
2419
- var foundCommonScheme = ['http://', 'https://'].find(function (commonScheme) { return !!schemeUrlMatch && schemeUrlMatch.indexOf(commonScheme) !== -1; });
2420
- if (foundCommonScheme) {
2421
- // If we found an overmatched URL, we want to find the index
2422
- // of where the match should start and shift the match to
2423
- // start from the beginning of the common scheme
2424
- var indexOfSchemeStart = matchStr.indexOf(foundCommonScheme);
2425
- matchStr = matchStr.substr(indexOfSchemeStart);
2426
- schemeUrlMatch = schemeUrlMatch.substr(indexOfSchemeStart);
2427
- offset = offset + indexOfSchemeStart;
2428
- }
2429
- var urlMatchType = schemeUrlMatch ? 'scheme' : (wwwUrlMatch ? 'www' : 'tld'), protocolUrlMatch = !!schemeUrlMatch;
2430
- matches.push(new UrlMatch({
2431
- tagBuilder: tagBuilder,
2432
- matchedText: matchStr,
2433
- offset: offset,
2434
- urlMatchType: urlMatchType,
2435
- url: matchStr,
2436
- protocolUrlMatch: protocolUrlMatch,
2437
- protocolRelativeMatch: !!protocolRelativeMatch,
2438
- stripPrefix: stripPrefix,
2439
- stripTrailingSlash: stripTrailingSlash,
2440
- decodePercentEncoding: decodePercentEncoding,
2441
- }));
2442
- };
2443
- var this_1 = this;
2444
- while ((match = matcherRegex.exec(text)) !== null) {
2445
- _loop_1();
2446
- }
2447
- return matches;
2448
- };
2449
- /**
2450
- * Determines if a match found has an unmatched closing parenthesis,
2451
- * square bracket or curly bracket. If so, the symbol will be removed
2452
- * from the match itself, and appended after the generated anchor tag.
2453
- *
2454
- * A match may have an extra closing parenthesis at the end of the match
2455
- * because the regular expression must include parenthesis for URLs such as
2456
- * "wikipedia.com/something_(disambiguation)", which should be auto-linked.
2457
- *
2458
- * However, an extra parenthesis *will* be included when the URL itself is
2459
- * wrapped in parenthesis, such as in the case of:
2460
- * "(wikipedia.com/something_(disambiguation))"
2461
- * In this case, the last closing parenthesis should *not* be part of the
2462
- * URL itself, and this method will return `true`.
2463
- *
2464
- * For square brackets in URLs such as in PHP arrays, the same behavior as
2465
- * parenthesis discussed above should happen:
2466
- * "[http://www.example.com/foo.php?bar[]=1&bar[]=2&bar[]=3]"
2467
- * The closing square bracket should not be part of the URL itself, and this
2468
- * method will return `true`.
2469
- *
2470
- * @protected
2471
- * @param {String} matchStr The full match string from the {@link #matcherRegex}.
2472
- * @return {Boolean} `true` if there is an unbalanced closing parenthesis or
2473
- * square bracket at the end of the `matchStr`, `false` otherwise.
2474
- */
2475
- UrlMatcher.prototype.matchHasUnbalancedClosingParen = function (matchStr) {
2476
- var endChar = matchStr.charAt(matchStr.length - 1);
2477
- var startChar;
2478
- if (endChar === ')') {
2479
- startChar = '(';
2480
- }
2481
- else if (endChar === ']') {
2482
- startChar = '[';
2483
- }
2484
- else if (endChar === '}') {
2485
- startChar = '{';
2486
- }
2487
- else {
2488
- return false; // not a close parenthesis or square bracket
2489
- }
2490
- // Find if there are the same number of open braces as close braces in
2491
- // the URL string, minus the last character (which we have already
2492
- // determined to be either ')', ']' or '}'
2493
- var numOpenBraces = 0;
2494
- for (var i = 0, len = matchStr.length - 1; i < len; i++) {
2495
- var char = matchStr.charAt(i);
2496
- if (char === startChar) {
2497
- numOpenBraces++;
2498
- }
2499
- else if (char === endChar) {
2500
- numOpenBraces = Math.max(numOpenBraces - 1, 0);
2501
- }
2502
- }
2503
- // If the number of open braces matches the number of close braces in
2504
- // the URL minus the last character, then the match has *unbalanced*
2505
- // braces because of the last character. Example of unbalanced braces
2506
- // from the regex match:
2507
- // "http://example.com?a[]=1]"
2508
- if (numOpenBraces === 0) {
2509
- return true;
2510
- }
2511
- return false;
2512
- };
2513
- /**
2514
- * Determine if there's an invalid character after the TLD in a URL. Valid
2515
- * characters after TLD are ':/?#'. Exclude scheme matched URLs from this
2516
- * check.
2517
- *
2518
- * @protected
2519
- * @param {String} urlMatch The matched URL, if there was one. Will be an
2520
- * empty string if the match is not a URL match.
2521
- * @param {String} schemeUrlMatch The match URL string for a scheme
2522
- * match. Ex: 'http://yahoo.com'. This is used to match something like
2523
- * 'http://localhost', where we won't double check that the domain name
2524
- * has at least one '.' in it.
2525
- * @return {Number} the position where the invalid character was found. If
2526
- * no such character was found, returns -1
2527
- */
2528
- UrlMatcher.prototype.matchHasInvalidCharAfterTld = function (urlMatch, schemeUrlMatch) {
2529
- if (!urlMatch) {
2530
- return -1;
2531
- }
2532
- var offset = 0;
2533
- if (schemeUrlMatch) {
2534
- offset = urlMatch.indexOf(':');
2535
- urlMatch = urlMatch.slice(offset);
2536
- }
2537
- var re = new RegExp("^((.?\/\/)?[-." + alphaNumericAndMarksCharsStr + "]*[-" + alphaNumericAndMarksCharsStr + "]\\.[-" + alphaNumericAndMarksCharsStr + "]+)");
2538
- var res = re.exec(urlMatch);
2539
- if (res === null) {
2540
- return -1;
2541
- }
2542
- offset += res[1].length;
2543
- urlMatch = urlMatch.slice(res[1].length);
2544
- if (/^[^-.A-Za-z0-9:\/?#]/.test(urlMatch)) {
2545
- return offset;
2546
- }
2547
- return -1;
2548
- };
2549
- return UrlMatcher;
2550
- }(Matcher));
2551
-
2552
- // RegExp objects which are shared by all instances of HashtagMatcher. These are
2553
- // here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is
2554
- // called multiple times, thus instantiating HashtagMatcher and its RegExp
2555
- // objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314).
2556
- // See descriptions of the properties where they are used for details about them
2557
- var matcherRegex$1 = new RegExp("#[_" + alphaNumericAndMarksCharsStr + "]{1,139}(?![_" + alphaNumericAndMarksCharsStr + "])", 'g'); // lookahead used to make sure we don't match something above 139 characters
2558
- var nonWordCharRegex = new RegExp('[^' + alphaNumericAndMarksCharsStr + ']');
2559
- /**
2560
- * @class Autolinker.matcher.Hashtag
2561
- * @extends Autolinker.matcher.Matcher
2562
- *
2563
- * Matcher to find HashtagMatch matches in an input string.
2564
- */
2565
- var HashtagMatcher = /** @class */ (function (_super) {
2566
- __extends(HashtagMatcher, _super);
2567
- /**
2568
- * @method constructor
2569
- * @param {Object} cfg The configuration properties for the Match instance,
2570
- * specified in an Object (map).
2571
- */
2572
- function HashtagMatcher(cfg) {
2573
- var _this = _super.call(this, cfg) || this;
2574
- /**
2575
- * @cfg {String} serviceName
2576
- *
2577
- * The service to point hashtag matches to. See {@link Autolinker#hashtag}
2578
- * for available values.
2579
- */
2580
- _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator
2581
- /**
2582
- * The regular expression to match Hashtags. Example match:
2583
- *
2584
- * #asdf
2585
- *
2586
- * @protected
2587
- * @property {RegExp} matcherRegex
2588
- */
2589
- _this.matcherRegex = matcherRegex$1;
2590
- /**
2591
- * The regular expression to use to check the character before a username match to
2592
- * make sure we didn't accidentally match an email address.
2593
- *
2594
- * For example, the string "asdf@asdf.com" should not match "@asdf" as a username.
2595
- *
2596
- * @protected
2597
- * @property {RegExp} nonWordCharRegex
2598
- */
2599
- _this.nonWordCharRegex = nonWordCharRegex;
2600
- _this.serviceName = cfg.serviceName;
2601
- return _this;
2602
- }
2603
- /**
2604
- * @inheritdoc
2605
- */
2606
- HashtagMatcher.prototype.parseMatches = function (text) {
2607
- var matcherRegex = this.matcherRegex, nonWordCharRegex = this.nonWordCharRegex, serviceName = this.serviceName, tagBuilder = this.tagBuilder, matches = [], match;
2608
- while ((match = matcherRegex.exec(text)) !== null) {
2609
- var offset = match.index, prevChar = text.charAt(offset - 1);
2610
- // If we found the match at the beginning of the string, or we found the match
2611
- // and there is a whitespace char in front of it (meaning it is not a '#' char
2612
- // in the middle of a word), then it is a hashtag match.
2613
- if (offset === 0 || nonWordCharRegex.test(prevChar)) {
2614
- var matchedText = match[0], hashtag = match[0].slice(1); // strip off the '#' character at the beginning
2615
- matches.push(new HashtagMatch({
2616
- tagBuilder: tagBuilder,
2617
- matchedText: matchedText,
2618
- offset: offset,
2619
- serviceName: serviceName,
2620
- hashtag: hashtag
2621
- }));
2622
- }
2623
- }
2624
- return matches;
2625
- };
2626
- return HashtagMatcher;
2627
- }(Matcher));
2628
-
2629
- // RegExp objects which are shared by all instances of PhoneMatcher. These are
2630
- // here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is
2631
- // called multiple times, thus instantiating PhoneMatcher and its RegExp
2632
- // objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314).
2633
- // See descriptions of the properties where they are used for details about them
2634
- // Over the years, many people have added to this regex, but it should have been
2635
- // split up by country. Maybe one day we can break this down.
2636
- var mostPhoneNumbers = /(?:(?:(?:(\+)?\d{1,3}[-\040.]?)?\(?\d{3}\)?[-\040.]?\d{3}[-\040.]?\d{4})|(?:(\+)(?:9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-\040.]?(?:\d[-\040.]?){6,12}\d+))([,;]+[0-9]+#?)*/;
2637
- // Regex for Japanese phone numbers
2638
- var japanesePhoneRe = /(0([1-9]{1}-?[1-9]\d{3}|[1-9]{2}-?\d{3}|[1-9]{2}\d{1}-?\d{2}|[1-9]{2}\d{2}-?\d{1})-?\d{4}|0[789]0-?\d{4}-?\d{4}|050-?\d{4}-?\d{4})/;
2639
- // Combined regex
2640
- var phoneMatcherRegex = new RegExp(mostPhoneNumbers.source + "|" + japanesePhoneRe.source, 'g');
2641
- /**
2642
- * @class Autolinker.matcher.Phone
2643
- * @extends Autolinker.matcher.Matcher
2644
- *
2645
- * Matcher to find Phone number matches in an input string.
2646
- *
2647
- * See this class's superclass ({@link Autolinker.matcher.Matcher}) for more
2648
- * details.
2649
- */
2650
- var PhoneMatcher = /** @class */ (function (_super) {
2651
- __extends(PhoneMatcher, _super);
2652
- function PhoneMatcher() {
2653
- var _this = _super !== null && _super.apply(this, arguments) || this;
2654
- /**
2655
- * The regular expression to match Phone numbers. Example matches:
2656
- *
2657
- * (123) 456-7890
2658
- * 123 456 7890
2659
- * 123-456-7890
2660
- * +18004441234,,;,10226420346#
2661
- * +1 (800) 444 1234
2662
- * 10226420346#
2663
- * 1-800-444-1234,1022,64,20346#
2664
- *
2665
- * This regular expression has the following capturing groups:
2666
- *
2667
- * 1 or 2. The prefixed '+' sign, if there is one.
2668
- *
2669
- * @protected
2670
- * @property {RegExp} matcherRegex
2671
- */
2672
- _this.matcherRegex = phoneMatcherRegex;
2673
- return _this;
2674
- }
2675
- /**
2676
- * @inheritdoc
2677
- */
2678
- PhoneMatcher.prototype.parseMatches = function (text) {
2679
- var matcherRegex = this.matcherRegex, tagBuilder = this.tagBuilder, matches = [], match;
2680
- while ((match = matcherRegex.exec(text)) !== null) {
2681
- // Remove non-numeric values from phone number string
2682
- var matchedText = match[0], cleanNumber = matchedText.replace(/[^0-9,;#]/g, ''), // strip out non-digit characters exclude comma semicolon and #
2683
- plusSign = !!(match[1] || match[2]), // match[ 1 ] or match[ 2 ] is the prefixed plus sign, if there is one
2684
- before = match.index == 0 ? '' : text.substr(match.index - 1, 1), after = text.substr(match.index + matchedText.length, 1), contextClear = !before.match(/\d/) && !after.match(/\d/);
2685
- if (this.testMatch(match[3]) && this.testMatch(matchedText) && contextClear) {
2686
- matches.push(new PhoneMatch({
2687
- tagBuilder: tagBuilder,
2688
- matchedText: matchedText,
2689
- offset: match.index,
2690
- number: cleanNumber,
2691
- plusSign: plusSign
2692
- }));
2693
- }
2694
- }
2695
- return matches;
2696
- };
2697
- PhoneMatcher.prototype.testMatch = function (text) {
2698
- return nonDigitRe.test(text);
2699
- };
2700
- return PhoneMatcher;
2701
- }(Matcher));
2702
-
2703
- // RegExp objects which are shared by all instances of MentionMatcher. These are
2704
- // here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is
2705
- // called multiple times, thus instantiating MentionMatcher and its RegExp
2706
- // objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314).
2707
- // See descriptions of the properties where they are used for details about them
2708
- var twitterRegex = new RegExp("@[_" + alphaNumericAndMarksCharsStr + "]{1,50}(?![_" + alphaNumericAndMarksCharsStr + "])", 'g'); // lookahead used to make sure we don't match something above 50 characters
2709
- var instagramRegex = new RegExp("@[_." + alphaNumericAndMarksCharsStr + "]{1,30}(?![_" + alphaNumericAndMarksCharsStr + "])", 'g'); // lookahead used to make sure we don't match something above 30 characters
2710
- var soundcloudRegex = new RegExp("@[-_." + alphaNumericAndMarksCharsStr + "]{1,50}(?![-_" + alphaNumericAndMarksCharsStr + "])", 'g'); // lookahead used to make sure we don't match something above 50 characters
2711
- var nonWordCharRegex$1 = new RegExp('[^' + alphaNumericAndMarksCharsStr + ']');
2712
- /**
2713
- * @class Autolinker.matcher.Mention
2714
- * @extends Autolinker.matcher.Matcher
2715
- *
2716
- * Matcher to find/replace username matches in an input string.
2717
- */
2718
- var MentionMatcher = /** @class */ (function (_super) {
2719
- __extends(MentionMatcher, _super);
2720
- /**
2721
- * @method constructor
2722
- * @param {Object} cfg The configuration properties for the Match instance,
2723
- * specified in an Object (map).
2724
- */
2725
- function MentionMatcher(cfg) {
2726
- var _this = _super.call(this, cfg) || this;
2727
- /**
2728
- * @cfg {'twitter'/'instagram'/'soundcloud'} protected
2729
- *
2730
- * The name of service to link @mentions to.
2731
- *
2732
- * Valid values are: 'twitter', 'instagram', or 'soundcloud'
2733
- */
2734
- _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator
2735
- /**
2736
- * Hash of regular expression to match username handles. Example match:
2737
- *
2738
- * @asdf
2739
- *
2740
- * @private
2741
- * @property {Object} matcherRegexes
2742
- */
2743
- _this.matcherRegexes = {
2744
- 'twitter': twitterRegex,
2745
- 'instagram': instagramRegex,
2746
- 'soundcloud': soundcloudRegex
2747
- };
2748
- /**
2749
- * The regular expression to use to check the character before a username match to
2750
- * make sure we didn't accidentally match an email address.
2751
- *
2752
- * For example, the string "asdf@asdf.com" should not match "@asdf" as a username.
2753
- *
2754
- * @private
2755
- * @property {RegExp} nonWordCharRegex
2756
- */
2757
- _this.nonWordCharRegex = nonWordCharRegex$1;
2758
- _this.serviceName = cfg.serviceName;
2759
- return _this;
2760
- }
2761
- /**
2762
- * @inheritdoc
2763
- */
2764
- MentionMatcher.prototype.parseMatches = function (text) {
2765
- var serviceName = this.serviceName, matcherRegex = this.matcherRegexes[this.serviceName], nonWordCharRegex = this.nonWordCharRegex, tagBuilder = this.tagBuilder, matches = [], match;
2766
- if (!matcherRegex) {
2767
- return matches;
2768
- }
2769
- while ((match = matcherRegex.exec(text)) !== null) {
2770
- var offset = match.index, prevChar = text.charAt(offset - 1);
2771
- // If we found the match at the beginning of the string, or we found the match
2772
- // and there is a whitespace char in front of it (meaning it is not an email
2773
- // address), then it is a username match.
2774
- if (offset === 0 || nonWordCharRegex.test(prevChar)) {
2775
- var matchedText = match[0].replace(/\.+$/g, ''), // strip off trailing .
2776
- mention = matchedText.slice(1); // strip off the '@' character at the beginning
2777
- matches.push(new MentionMatch({
2778
- tagBuilder: tagBuilder,
2779
- matchedText: matchedText,
2780
- offset: offset,
2781
- serviceName: serviceName,
2782
- mention: mention
2783
- }));
2784
- }
2785
- }
2786
- return matches;
2787
- };
2788
- return MentionMatcher;
2789
- }(Matcher));
2790
-
2791
- // For debugging: search for other "For debugging" lines
2792
- // import CliTable from 'cli-table';
2793
- /**
2794
- * Parses an HTML string, calling the callbacks to notify of tags and text.
2795
- *
2796
- * ## History
2797
- *
2798
- * This file previously used a regular expression to find html tags in the input
2799
- * text. Unfortunately, we ran into a bunch of catastrophic backtracking issues
2800
- * with certain input text, causing Autolinker to either hang or just take a
2801
- * really long time to parse the string.
2802
- *
2803
- * The current code is intended to be a O(n) algorithm that walks through
2804
- * the string in one pass, and tries to be as cheap as possible. We don't need
2805
- * to implement the full HTML spec, but rather simply determine where the string
2806
- * looks like an HTML tag, and where it looks like text (so that we can autolink
2807
- * that).
2808
- *
2809
- * This state machine parser is intended just to be a simple but performant
2810
- * parser of HTML for the subset of requirements we have. We simply need to:
2811
- *
2812
- * 1. Determine where HTML tags are
2813
- * 2. Determine the tag name (Autolinker specifically only cares about <a>,
2814
- * <script>, and <style> tags, so as not to link any text within them)
2815
- *
2816
- * We don't need to:
2817
- *
2818
- * 1. Create a parse tree
2819
- * 2. Auto-close tags with invalid markup
2820
- * 3. etc.
2821
- *
2822
- * The other intention behind this is that we didn't want to add external
2823
- * dependencies on the Autolinker utility which would increase its size. For
2824
- * instance, adding htmlparser2 adds 125kb to the minified output file,
2825
- * increasing its final size from 47kb to 172kb (at the time of writing). It
2826
- * also doesn't work exactly correctly, treating the string "<3 blah blah blah"
2827
- * as an HTML tag.
2828
- *
2829
- * Reference for HTML spec:
2830
- *
2831
- * https://www.w3.org/TR/html51/syntax.html#sec-tokenization
2832
- *
2833
- * @param {String} html The HTML to parse
2834
- * @param {Object} callbacks
2835
- * @param {Function} callbacks.onOpenTag Callback function to call when an open
2836
- * tag is parsed. Called with the tagName as its argument.
2837
- * @param {Function} callbacks.onCloseTag Callback function to call when a close
2838
- * tag is parsed. Called with the tagName as its argument. If a self-closing
2839
- * tag is found, `onCloseTag` is called immediately after `onOpenTag`.
2840
- * @param {Function} callbacks.onText Callback function to call when text (i.e
2841
- * not an HTML tag) is parsed. Called with the text (string) as its first
2842
- * argument, and offset (number) into the string as its second.
2843
- */
2844
- function parseHtml(html, _a) {
2845
- var onOpenTag = _a.onOpenTag, onCloseTag = _a.onCloseTag, onText = _a.onText, onComment = _a.onComment, onDoctype = _a.onDoctype;
2846
- var noCurrentTag = new CurrentTag();
2847
- var charIdx = 0, len = html.length, state = 0 /* Data */, currentDataIdx = 0, // where the current data start index is
2848
- currentTag = noCurrentTag; // describes the current tag that is being read
2849
- // For debugging: search for other "For debugging" lines
2850
- // const table = new CliTable( {
2851
- // head: [ 'charIdx', 'char', 'state', 'currentDataIdx', 'currentOpenTagIdx', 'tag.type' ]
2852
- // } );
2853
- while (charIdx < len) {
2854
- var char = html.charAt(charIdx);
2855
- // For debugging: search for other "For debugging" lines
2856
- // ALSO: Temporarily remove the 'const' keyword on the State enum
2857
- // table.push(
2858
- // [ charIdx, char, State[ state ], currentDataIdx, currentTag.idx, currentTag.idx === -1 ? '' : currentTag.type ]
2859
- // );
2860
- switch (state) {
2861
- case 0 /* Data */:
2862
- stateData(char);
2863
- break;
2864
- case 1 /* TagOpen */:
2865
- stateTagOpen(char);
2866
- break;
2867
- case 2 /* EndTagOpen */:
2868
- stateEndTagOpen(char);
2869
- break;
2870
- case 3 /* TagName */:
2871
- stateTagName(char);
2872
- break;
2873
- case 4 /* BeforeAttributeName */:
2874
- stateBeforeAttributeName(char);
2875
- break;
2876
- case 5 /* AttributeName */:
2877
- stateAttributeName(char);
2878
- break;
2879
- case 6 /* AfterAttributeName */:
2880
- stateAfterAttributeName(char);
2881
- break;
2882
- case 7 /* BeforeAttributeValue */:
2883
- stateBeforeAttributeValue(char);
2884
- break;
2885
- case 8 /* AttributeValueDoubleQuoted */:
2886
- stateAttributeValueDoubleQuoted(char);
2887
- break;
2888
- case 9 /* AttributeValueSingleQuoted */:
2889
- stateAttributeValueSingleQuoted(char);
2890
- break;
2891
- case 10 /* AttributeValueUnquoted */:
2892
- stateAttributeValueUnquoted(char);
2893
- break;
2894
- case 11 /* AfterAttributeValueQuoted */:
2895
- stateAfterAttributeValueQuoted(char);
2896
- break;
2897
- case 12 /* SelfClosingStartTag */:
2898
- stateSelfClosingStartTag(char);
2899
- break;
2900
- case 13 /* MarkupDeclarationOpenState */:
2901
- stateMarkupDeclarationOpen();
2902
- break;
2903
- case 14 /* CommentStart */:
2904
- stateCommentStart(char);
2905
- break;
2906
- case 15 /* CommentStartDash */:
2907
- stateCommentStartDash(char);
2908
- break;
2909
- case 16 /* Comment */:
2910
- stateComment(char);
2911
- break;
2912
- case 17 /* CommentEndDash */:
2913
- stateCommentEndDash(char);
2914
- break;
2915
- case 18 /* CommentEnd */:
2916
- stateCommentEnd(char);
2917
- break;
2918
- case 19 /* CommentEndBang */:
2919
- stateCommentEndBang(char);
2920
- break;
2921
- case 20 /* Doctype */:
2922
- stateDoctype(char);
2923
- break;
2924
- default:
2925
- throwUnhandledCaseError(state);
2926
- }
2927
- // For debugging: search for other "For debugging" lines
2928
- // ALSO: Temporarily remove the 'const' keyword on the State enum
2929
- // table.push(
2930
- // [ charIdx, char, State[ state ], currentDataIdx, currentTag.idx, currentTag.idx === -1 ? '' : currentTag.type ]
2931
- // );
2932
- charIdx++;
2933
- }
2934
- if (currentDataIdx < charIdx) {
2935
- emitText();
2936
- }
2937
- // For debugging: search for other "For debugging" lines
2938
- // console.log( '\n' + table.toString() );
2939
- // Called when non-tags are being read (i.e. the text around HTML †ags)
2940
- // https://www.w3.org/TR/html51/syntax.html#data-state
2941
- function stateData(char) {
2942
- if (char === '<') {
2943
- startNewTag();
2944
- }
2945
- }
2946
- // Called after a '<' is read from the Data state
2947
- // https://www.w3.org/TR/html51/syntax.html#tag-open-state
2948
- function stateTagOpen(char) {
2949
- if (char === '!') {
2950
- state = 13 /* MarkupDeclarationOpenState */;
2951
- }
2952
- else if (char === '/') {
2953
- state = 2 /* EndTagOpen */;
2954
- currentTag = new CurrentTag(__assign({}, currentTag, { isClosing: true }));
2955
- }
2956
- else if (char === '<') {
2957
- // start of another tag (ignore the previous, incomplete one)
2958
- startNewTag();
2959
- }
2960
- else if (letterRe.test(char)) {
2961
- // tag name start (and no '/' read)
2962
- state = 3 /* TagName */;
2963
- currentTag = new CurrentTag(__assign({}, currentTag, { isOpening: true }));
2964
- }
2965
- else {
2966
- // Any other
2967
- state = 0 /* Data */;
2968
- currentTag = noCurrentTag;
2969
- }
2970
- }
2971
- // After a '<x', '</x' sequence is read (where 'x' is a letter character),
2972
- // this is to continue reading the tag name
2973
- // https://www.w3.org/TR/html51/syntax.html#tag-name-state
2974
- function stateTagName(char) {
2975
- if (whitespaceRe.test(char)) {
2976
- currentTag = new CurrentTag(__assign({}, currentTag, { name: captureTagName() }));
2977
- state = 4 /* BeforeAttributeName */;
2978
- }
2979
- else if (char === '<') {
2980
- // start of another tag (ignore the previous, incomplete one)
2981
- startNewTag();
2982
- }
2983
- else if (char === '/') {
2984
- currentTag = new CurrentTag(__assign({}, currentTag, { name: captureTagName() }));
2985
- state = 12 /* SelfClosingStartTag */;
2986
- }
2987
- else if (char === '>') {
2988
- currentTag = new CurrentTag(__assign({}, currentTag, { name: captureTagName() }));
2989
- emitTagAndPreviousTextNode(); // resets to Data state as well
2990
- }
2991
- else if (!letterRe.test(char) && !digitRe.test(char) && char !== ':') {
2992
- // Anything else that does not form an html tag. Note: the colon
2993
- // character is accepted for XML namespaced tags
2994
- resetToDataState();
2995
- }
2996
- else ;
2997
- }
2998
- // Called after the '/' is read from a '</' sequence
2999
- // https://www.w3.org/TR/html51/syntax.html#end-tag-open-state
3000
- function stateEndTagOpen(char) {
3001
- if (char === '>') { // parse error. Encountered "</>". Skip it without treating as a tag
3002
- resetToDataState();
3003
- }
3004
- else if (letterRe.test(char)) {
3005
- state = 3 /* TagName */;
3006
- }
3007
- else {
3008
- // some other non-tag-like character, don't treat this as a tag
3009
- resetToDataState();
3010
- }
3011
- }
3012
- // https://www.w3.org/TR/html51/syntax.html#before-attribute-name-state
3013
- function stateBeforeAttributeName(char) {
3014
- if (whitespaceRe.test(char)) ;
3015
- else if (char === '/') {
3016
- state = 12 /* SelfClosingStartTag */;
3017
- }
3018
- else if (char === '>') {
3019
- emitTagAndPreviousTextNode(); // resets to Data state as well
3020
- }
3021
- else if (char === '<') {
3022
- // start of another tag (ignore the previous, incomplete one)
3023
- startNewTag();
3024
- }
3025
- else if (char === "=" || quoteRe.test(char) || controlCharsRe.test(char)) {
3026
- // "Parse error" characters that, according to the spec, should be
3027
- // appended to the attribute name, but we'll treat these characters
3028
- // as not forming a real HTML tag
3029
- resetToDataState();
3030
- }
3031
- else {
3032
- // Any other char, start of a new attribute name
3033
- state = 5 /* AttributeName */;
3034
- }
3035
- }
3036
- // https://www.w3.org/TR/html51/syntax.html#attribute-name-state
3037
- function stateAttributeName(char) {
3038
- if (whitespaceRe.test(char)) {
3039
- state = 6 /* AfterAttributeName */;
3040
- }
3041
- else if (char === '/') {
3042
- state = 12 /* SelfClosingStartTag */;
3043
- }
3044
- else if (char === '=') {
3045
- state = 7 /* BeforeAttributeValue */;
3046
- }
3047
- else if (char === '>') {
3048
- emitTagAndPreviousTextNode(); // resets to Data state as well
3049
- }
3050
- else if (char === '<') {
3051
- // start of another tag (ignore the previous, incomplete one)
3052
- startNewTag();
3053
- }
3054
- else if (quoteRe.test(char)) {
3055
- // "Parse error" characters that, according to the spec, should be
3056
- // appended to the attribute name, but we'll treat these characters
3057
- // as not forming a real HTML tag
3058
- resetToDataState();
3059
- }
3060
- else ;
3061
- }
3062
- // https://www.w3.org/TR/html51/syntax.html#after-attribute-name-state
3063
- function stateAfterAttributeName(char) {
3064
- if (whitespaceRe.test(char)) ;
3065
- else if (char === '/') {
3066
- state = 12 /* SelfClosingStartTag */;
3067
- }
3068
- else if (char === '=') {
3069
- state = 7 /* BeforeAttributeValue */;
3070
- }
3071
- else if (char === '>') {
3072
- emitTagAndPreviousTextNode();
3073
- }
3074
- else if (char === '<') {
3075
- // start of another tag (ignore the previous, incomplete one)
3076
- startNewTag();
3077
- }
3078
- else if (quoteRe.test(char)) {
3079
- // "Parse error" characters that, according to the spec, should be
3080
- // appended to the attribute name, but we'll treat these characters
3081
- // as not forming a real HTML tag
3082
- resetToDataState();
3083
- }
3084
- else {
3085
- // Any other character, start a new attribute in the current tag
3086
- state = 5 /* AttributeName */;
3087
- }
3088
- }
3089
- // https://www.w3.org/TR/html51/syntax.html#before-attribute-value-state
3090
- function stateBeforeAttributeValue(char) {
3091
- if (whitespaceRe.test(char)) ;
3092
- else if (char === "\"") {
3093
- state = 8 /* AttributeValueDoubleQuoted */;
3094
- }
3095
- else if (char === "'") {
3096
- state = 9 /* AttributeValueSingleQuoted */;
3097
- }
3098
- else if (/[>=`]/.test(char)) {
3099
- // Invalid chars after an '=' for an attribute value, don't count
3100
- // the current tag as an HTML tag
3101
- resetToDataState();
3102
- }
3103
- else if (char === '<') {
3104
- // start of another tag (ignore the previous, incomplete one)
3105
- startNewTag();
3106
- }
3107
- else {
3108
- // Any other character, consider it an unquoted attribute value
3109
- state = 10 /* AttributeValueUnquoted */;
3110
- }
3111
- }
3112
- // https://www.w3.org/TR/html51/syntax.html#attribute-value-double-quoted-state
3113
- function stateAttributeValueDoubleQuoted(char) {
3114
- if (char === "\"") { // end the current double-quoted attribute
3115
- state = 11 /* AfterAttributeValueQuoted */;
3116
- }
3117
- }
3118
- // https://www.w3.org/TR/html51/syntax.html#attribute-value-single-quoted-state
3119
- function stateAttributeValueSingleQuoted(char) {
3120
- if (char === "'") { // end the current single-quoted attribute
3121
- state = 11 /* AfterAttributeValueQuoted */;
3122
- }
3123
- }
3124
- // https://www.w3.org/TR/html51/syntax.html#attribute-value-unquoted-state
3125
- function stateAttributeValueUnquoted(char) {
3126
- if (whitespaceRe.test(char)) {
3127
- state = 4 /* BeforeAttributeName */;
3128
- }
3129
- else if (char === '>') {
3130
- emitTagAndPreviousTextNode();
3131
- }
3132
- else if (char === '<') {
3133
- // start of another tag (ignore the previous, incomplete one)
3134
- startNewTag();
3135
- }
3136
- else ;
3137
- }
3138
- // https://www.w3.org/TR/html51/syntax.html#after-attribute-value-quoted-state
3139
- function stateAfterAttributeValueQuoted(char) {
3140
- if (whitespaceRe.test(char)) {
3141
- state = 4 /* BeforeAttributeName */;
3142
- }
3143
- else if (char === '/') {
3144
- state = 12 /* SelfClosingStartTag */;
3145
- }
3146
- else if (char === '>') {
3147
- emitTagAndPreviousTextNode();
3148
- }
3149
- else if (char === '<') {
3150
- // start of another tag (ignore the previous, incomplete one)
3151
- startNewTag();
3152
- }
3153
- else {
3154
- // Any other character, "parse error". Spec says to switch to the
3155
- // BeforeAttributeState and re-consume the character, as it may be
3156
- // the start of a new attribute name
3157
- state = 4 /* BeforeAttributeName */;
3158
- reconsumeCurrentCharacter();
3159
- }
3160
- }
3161
- // A '/' has just been read in the current tag (presumably for '/>'), and
3162
- // this handles the next character
3163
- // https://www.w3.org/TR/html51/syntax.html#self-closing-start-tag-state
3164
- function stateSelfClosingStartTag(char) {
3165
- if (char === '>') {
3166
- currentTag = new CurrentTag(__assign({}, currentTag, { isClosing: true }));
3167
- emitTagAndPreviousTextNode(); // resets to Data state as well
3168
- }
3169
- else {
3170
- state = 4 /* BeforeAttributeName */;
3171
- }
3172
- }
3173
- // https://www.w3.org/TR/html51/syntax.html#markup-declaration-open-state
3174
- // (HTML Comments or !DOCTYPE)
3175
- function stateMarkupDeclarationOpen(char) {
3176
- if (html.substr(charIdx, 2) === '--') { // html comment
3177
- charIdx += 2; // "consume" characters
3178
- currentTag = new CurrentTag(__assign({}, currentTag, { type: 'comment' }));
3179
- state = 14 /* CommentStart */;
3180
- }
3181
- else if (html.substr(charIdx, 7).toUpperCase() === 'DOCTYPE') {
3182
- charIdx += 7; // "consume" characters
3183
- currentTag = new CurrentTag(__assign({}, currentTag, { type: 'doctype' }));
3184
- state = 20 /* Doctype */;
3185
- }
3186
- else {
3187
- // At this point, the spec specifies that the state machine should
3188
- // enter the "bogus comment" state, in which case any character(s)
3189
- // after the '<!' that were read should become an HTML comment up
3190
- // until the first '>' that is read (or EOF). Instead, we'll assume
3191
- // that a user just typed '<!' as part of text data
3192
- resetToDataState();
3193
- }
3194
- }
3195
- // Handles after the sequence '<!--' has been read
3196
- // https://www.w3.org/TR/html51/syntax.html#comment-start-state
3197
- function stateCommentStart(char) {
3198
- if (char === '-') {
3199
- // We've read the sequence '<!---' at this point (3 dashes)
3200
- state = 15 /* CommentStartDash */;
3201
- }
3202
- else if (char === '>') {
3203
- // At this point, we'll assume the comment wasn't a real comment
3204
- // so we'll just emit it as data. We basically read the sequence
3205
- // '<!-->'
3206
- resetToDataState();
3207
- }
3208
- else {
3209
- // Any other char, take it as part of the comment
3210
- state = 16 /* Comment */;
3211
- }
3212
- }
3213
- // We've read the sequence '<!---' at this point (3 dashes)
3214
- // https://www.w3.org/TR/html51/syntax.html#comment-start-dash-state
3215
- function stateCommentStartDash(char) {
3216
- if (char === '-') {
3217
- // We've read '<!----' (4 dashes) at this point
3218
- state = 18 /* CommentEnd */;
3219
- }
3220
- else if (char === '>') {
3221
- // At this point, we'll assume the comment wasn't a real comment
3222
- // so we'll just emit it as data. We basically read the sequence
3223
- // '<!--->'
3224
- resetToDataState();
3225
- }
3226
- else {
3227
- // Anything else, take it as a valid comment
3228
- state = 16 /* Comment */;
3229
- }
3230
- }
3231
- // Currently reading the comment's text (data)
3232
- // https://www.w3.org/TR/html51/syntax.html#comment-state
3233
- function stateComment(char) {
3234
- if (char === '-') {
3235
- state = 17 /* CommentEndDash */;
3236
- }
3237
- }
3238
- // When we we've read the first dash inside a comment, it may signal the
3239
- // end of the comment if we read another dash
3240
- // https://www.w3.org/TR/html51/syntax.html#comment-end-dash-state
3241
- function stateCommentEndDash(char) {
3242
- if (char === '-') {
3243
- state = 18 /* CommentEnd */;
3244
- }
3245
- else {
3246
- // Wasn't a dash, must still be part of the comment
3247
- state = 16 /* Comment */;
3248
- }
3249
- }
3250
- // After we've read two dashes inside a comment, it may signal the end of
3251
- // the comment if we then read a '>' char
3252
- // https://www.w3.org/TR/html51/syntax.html#comment-end-state
3253
- function stateCommentEnd(char) {
3254
- if (char === '>') {
3255
- emitTagAndPreviousTextNode();
3256
- }
3257
- else if (char === '!') {
3258
- state = 19 /* CommentEndBang */;
3259
- }
3260
- else if (char === '-') ;
3261
- else {
3262
- // Anything else, switch back to the comment state since we didn't
3263
- // read the full "end comment" sequence (i.e. '-->')
3264
- state = 16 /* Comment */;
3265
- }
3266
- }
3267
- // We've read the sequence '--!' inside of a comment
3268
- // https://www.w3.org/TR/html51/syntax.html#comment-end-bang-state
3269
- function stateCommentEndBang(char) {
3270
- if (char === '-') {
3271
- // We read the sequence '--!-' inside of a comment. The last dash
3272
- // could signify that the comment is going to close
3273
- state = 17 /* CommentEndDash */;
3274
- }
3275
- else if (char === '>') {
3276
- // End of comment with the sequence '--!>'
3277
- emitTagAndPreviousTextNode();
3278
- }
3279
- else {
3280
- // The '--!' was not followed by a '>', continue reading the
3281
- // comment's text
3282
- state = 16 /* Comment */;
3283
- }
3284
- }
3285
- /**
3286
- * For DOCTYPES in particular, we don't care about the attributes. Just
3287
- * advance to the '>' character and emit the tag, unless we find a '<'
3288
- * character in which case we'll start a new tag.
3289
- *
3290
- * Example doctype tag:
3291
- * <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
3292
- *
3293
- * Actual spec: https://www.w3.org/TR/html51/syntax.html#doctype-state
3294
- */
3295
- function stateDoctype(char) {
3296
- if (char === '>') {
3297
- emitTagAndPreviousTextNode();
3298
- }
3299
- else if (char === '<') {
3300
- startNewTag();
3301
- }
3302
- else ;
3303
- }
3304
- /**
3305
- * Resets the state back to the Data state, and removes the current tag.
3306
- *
3307
- * We'll generally run this function whenever a "parse error" is
3308
- * encountered, where the current tag that is being read no longer looks
3309
- * like a real HTML tag.
3310
- */
3311
- function resetToDataState() {
3312
- state = 0 /* Data */;
3313
- currentTag = noCurrentTag;
3314
- }
3315
- /**
3316
- * Starts a new HTML tag at the current index, ignoring any previous HTML
3317
- * tag that was being read.
3318
- *
3319
- * We'll generally run this function whenever we read a new '<' character,
3320
- * including when we read a '<' character inside of an HTML tag that we were
3321
- * previously reading.
3322
- */
3323
- function startNewTag() {
3324
- state = 1 /* TagOpen */;
3325
- currentTag = new CurrentTag({ idx: charIdx });
3326
- }
3327
- /**
3328
- * Once we've decided to emit an open tag, that means we can also emit the
3329
- * text node before it.
3330
- */
3331
- function emitTagAndPreviousTextNode() {
3332
- var textBeforeTag = html.slice(currentDataIdx, currentTag.idx);
3333
- if (textBeforeTag) {
3334
- // the html tag was the first element in the html string, or two
3335
- // tags next to each other, in which case we should not emit a text
3336
- // node
3337
- onText(textBeforeTag, currentDataIdx);
3338
- }
3339
- if (currentTag.type === 'comment') {
3340
- onComment(currentTag.idx);
3341
- }
3342
- else if (currentTag.type === 'doctype') {
3343
- onDoctype(currentTag.idx);
3344
- }
3345
- else {
3346
- if (currentTag.isOpening) {
3347
- onOpenTag(currentTag.name, currentTag.idx);
3348
- }
3349
- if (currentTag.isClosing) { // note: self-closing tags will emit both opening and closing
3350
- onCloseTag(currentTag.name, currentTag.idx);
3351
- }
3352
- }
3353
- // Since we just emitted a tag, reset to the data state for the next char
3354
- resetToDataState();
3355
- currentDataIdx = charIdx + 1;
3356
- }
3357
- function emitText() {
3358
- var text = html.slice(currentDataIdx, charIdx);
3359
- onText(text, currentDataIdx);
3360
- currentDataIdx = charIdx + 1;
3361
- }
3362
- /**
3363
- * Captures the tag name from the start of the tag to the current character
3364
- * index, and converts it to lower case
3365
- */
3366
- function captureTagName() {
3367
- var startIdx = currentTag.idx + (currentTag.isClosing ? 2 : 1);
3368
- return html.slice(startIdx, charIdx).toLowerCase();
3369
- }
3370
- /**
3371
- * Causes the main loop to re-consume the current character, such as after
3372
- * encountering a "parse error" that changed state and needs to reconsume
3373
- * the same character in that new state.
3374
- */
3375
- function reconsumeCurrentCharacter() {
3376
- charIdx--;
3377
- }
3378
- }
3379
- var CurrentTag = /** @class */ (function () {
3380
- function CurrentTag(cfg) {
3381
- if (cfg === void 0) { cfg = {}; }
3382
- this.idx = cfg.idx !== undefined ? cfg.idx : -1;
3383
- this.type = cfg.type || 'tag';
3384
- this.name = cfg.name || '';
3385
- this.isOpening = !!cfg.isOpening;
3386
- this.isClosing = !!cfg.isClosing;
3387
- }
3388
- return CurrentTag;
3389
- }());
3390
-
3391
- /**
3392
- * @class Autolinker
3393
- * @extends Object
3394
- *
3395
- * Utility class used to process a given string of text, and wrap the matches in
3396
- * the appropriate anchor (&lt;a&gt;) tags to turn them into links.
3397
- *
3398
- * Any of the configuration options may be provided in an Object provided
3399
- * to the Autolinker constructor, which will configure how the {@link #link link()}
3400
- * method will process the links.
3401
- *
3402
- * For example:
3403
- *
3404
- * var autolinker = new Autolinker( {
3405
- * newWindow : false,
3406
- * truncate : 30
3407
- * } );
3408
- *
3409
- * var html = autolinker.link( "Joe went to www.yahoo.com" );
3410
- * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>'
3411
- *
3412
- *
3413
- * The {@link #static-link static link()} method may also be used to inline
3414
- * options into a single call, which may be more convenient for one-off uses.
3415
- * For example:
3416
- *
3417
- * var html = Autolinker.link( "Joe went to www.yahoo.com", {
3418
- * newWindow : false,
3419
- * truncate : 30
3420
- * } );
3421
- * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>'
3422
- *
3423
- *
3424
- * ## Custom Replacements of Links
3425
- *
3426
- * If the configuration options do not provide enough flexibility, a {@link #replaceFn}
3427
- * may be provided to fully customize the output of Autolinker. This function is
3428
- * called once for each URL/Email/Phone#/Hashtag/Mention (Twitter, Instagram, Soundcloud)
3429
- * match that is encountered.
3430
- *
3431
- * For example:
3432
- *
3433
- * var input = "..."; // string with URLs, Email Addresses, Phone #s, Hashtags, and Mentions (Twitter, Instagram, Soundcloud)
3434
- *
3435
- * var linkedText = Autolinker.link( input, {
3436
- * replaceFn : function( match ) {
3437
- * console.log( "href = ", match.getAnchorHref() );
3438
- * console.log( "text = ", match.getAnchorText() );
3439
- *
3440
- * switch( match.getType() ) {
3441
- * case 'url' :
3442
- * console.log( "url: ", match.getUrl() );
3443
- *
3444
- * if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) {
3445
- * var tag = match.buildTag(); // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes
3446
- * tag.setAttr( 'rel', 'nofollow' );
3447
- * tag.addClass( 'external-link' );
3448
- *
3449
- * return tag;
3450
- *
3451
- * } else {
3452
- * return true; // let Autolinker perform its normal anchor tag replacement
3453
- * }
3454
- *
3455
- * case 'email' :
3456
- * var email = match.getEmail();
3457
- * console.log( "email: ", email );
3458
- *
3459
- * if( email === "my@own.address" ) {
3460
- * return false; // don't auto-link this particular email address; leave as-is
3461
- * } else {
3462
- * return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`)
3463
- * }
3464
- *
3465
- * case 'phone' :
3466
- * var phoneNumber = match.getPhoneNumber();
3467
- * console.log( phoneNumber );
3468
- *
3469
- * return '<a href="http://newplace.to.link.phone.numbers.to/">' + phoneNumber + '</a>';
3470
- *
3471
- * case 'hashtag' :
3472
- * var hashtag = match.getHashtag();
3473
- * console.log( hashtag );
3474
- *
3475
- * return '<a href="http://newplace.to.link.hashtag.handles.to/">' + hashtag + '</a>';
3476
- *
3477
- * case 'mention' :
3478
- * var mention = match.getMention();
3479
- * console.log( mention );
3480
- *
3481
- * return '<a href="http://newplace.to.link.mention.to/">' + mention + '</a>';
3482
- * }
3483
- * }
3484
- * } );
3485
- *
3486
- *
3487
- * The function may return the following values:
3488
- *
3489
- * - `true` (Boolean): Allow Autolinker to replace the match as it normally
3490
- * would.
3491
- * - `false` (Boolean): Do not replace the current match at all - leave as-is.
3492
- * - Any String: If a string is returned from the function, the string will be
3493
- * used directly as the replacement HTML for the match.
3494
- * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify
3495
- * an HTML tag before writing out its HTML text.
3496
- */
3497
- var Autolinker = /** @class */ (function () {
3498
- /**
3499
- * @method constructor
3500
- * @param {Object} [cfg] The configuration options for the Autolinker instance,
3501
- * specified in an Object (map).
3502
- */
3503
- function Autolinker(cfg) {
3504
- if (cfg === void 0) { cfg = {}; }
3505
- /**
3506
- * The Autolinker version number exposed on the instance itself.
3507
- *
3508
- * Ex: 0.25.1
3509
- */
3510
- this.version = Autolinker.version;
3511
- /**
3512
- * @cfg {Boolean/Object} [urls]
3513
- *
3514
- * `true` if URLs should be automatically linked, `false` if they should not
3515
- * be. Defaults to `true`.
3516
- *
3517
- * Examples:
3518
- *
3519
- * urls: true
3520
- *
3521
- * // or
3522
- *
3523
- * urls: {
3524
- * schemeMatches : true,
3525
- * wwwMatches : true,
3526
- * tldMatches : true
3527
- * }
3528
- *
3529
- * As shown above, this option also accepts an Object form with 3 properties
3530
- * to allow for more customization of what exactly gets linked. All default
3531
- * to `true`:
3532
- *
3533
- * @cfg {Boolean} [urls.schemeMatches] `true` to match URLs found prefixed
3534
- * with a scheme, i.e. `http://google.com`, or `other+scheme://google.com`,
3535
- * `false` to prevent these types of matches.
3536
- * @cfg {Boolean} [urls.wwwMatches] `true` to match urls found prefixed with
3537
- * `'www.'`, i.e. `www.google.com`. `false` to prevent these types of
3538
- * matches. Note that if the URL had a prefixed scheme, and
3539
- * `schemeMatches` is true, it will still be linked.
3540
- * @cfg {Boolean} [urls.tldMatches] `true` to match URLs with known top
3541
- * level domains (.com, .net, etc.) that are not prefixed with a scheme or
3542
- * `'www.'`. This option attempts to match anything that looks like a URL
3543
- * in the given text. Ex: `google.com`, `asdf.org/?page=1`, etc. `false`
3544
- * to prevent these types of matches.
3545
- */
3546
- this.urls = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
3547
- /**
3548
- * @cfg {Boolean} [email=true]
3549
- *
3550
- * `true` if email addresses should be automatically linked, `false` if they
3551
- * should not be.
3552
- */
3553
- this.email = true; // default value just to get the above doc comment in the ES5 output and documentation generator
3554
- /**
3555
- * @cfg {Boolean} [phone=true]
3556
- *
3557
- * `true` if Phone numbers ("(555)555-5555") should be automatically linked,
3558
- * `false` if they should not be.
3559
- */
3560
- this.phone = true; // default value just to get the above doc comment in the ES5 output and documentation generator
3561
- /**
3562
- * @cfg {Boolean/String} [hashtag=false]
3563
- *
3564
- * A string for the service name to have hashtags (ex: "#myHashtag")
3565
- * auto-linked to. The currently-supported values are:
3566
- *
3567
- * - 'twitter'
3568
- * - 'facebook'
3569
- * - 'instagram'
3570
- *
3571
- * Pass `false` to skip auto-linking of hashtags.
3572
- */
3573
- this.hashtag = false; // default value just to get the above doc comment in the ES5 output and documentation generator
3574
- /**
3575
- * @cfg {String/Boolean} [mention=false]
3576
- *
3577
- * A string for the service name to have mentions (ex: "@myuser")
3578
- * auto-linked to. The currently supported values are:
3579
- *
3580
- * - 'twitter'
3581
- * - 'instagram'
3582
- * - 'soundcloud'
3583
- *
3584
- * Defaults to `false` to skip auto-linking of mentions.
3585
- */
3586
- this.mention = false; // default value just to get the above doc comment in the ES5 output and documentation generator
3587
- /**
3588
- * @cfg {Boolean} [newWindow=true]
3589
- *
3590
- * `true` if the links should open in a new window, `false` otherwise.
3591
- */
3592
- this.newWindow = true; // default value just to get the above doc comment in the ES5 output and documentation generator
3593
- /**
3594
- * @cfg {Boolean/Object} [stripPrefix=true]
3595
- *
3596
- * `true` if 'http://' (or 'https://') and/or the 'www.' should be stripped
3597
- * from the beginning of URL links' text, `false` otherwise. Defaults to
3598
- * `true`.
3599
- *
3600
- * Examples:
3601
- *
3602
- * stripPrefix: true
3603
- *
3604
- * // or
3605
- *
3606
- * stripPrefix: {
3607
- * scheme : true,
3608
- * www : true
3609
- * }
3610
- *
3611
- * As shown above, this option also accepts an Object form with 2 properties
3612
- * to allow for more customization of what exactly is prevented from being
3613
- * displayed. Both default to `true`:
3614
- *
3615
- * @cfg {Boolean} [stripPrefix.scheme] `true` to prevent the scheme part of
3616
- * a URL match from being displayed to the user. Example:
3617
- * `'http://google.com'` will be displayed as `'google.com'`. `false` to
3618
- * not strip the scheme. NOTE: Only an `'http://'` or `'https://'` scheme
3619
- * will be removed, so as not to remove a potentially dangerous scheme
3620
- * (such as `'file://'` or `'javascript:'`)
3621
- * @cfg {Boolean} [stripPrefix.www] www (Boolean): `true` to prevent the
3622
- * `'www.'` part of a URL match from being displayed to the user. Ex:
3623
- * `'www.google.com'` will be displayed as `'google.com'`. `false` to not
3624
- * strip the `'www'`.
3625
- */
3626
- this.stripPrefix = { scheme: true, www: true }; // default value just to get the above doc comment in the ES5 output and documentation generator
3627
- /**
3628
- * @cfg {Boolean} [stripTrailingSlash=true]
3629
- *
3630
- * `true` to remove the trailing slash from URL matches, `false` to keep
3631
- * the trailing slash.
3632
- *
3633
- * Example when `true`: `http://google.com/` will be displayed as
3634
- * `http://google.com`.
3635
- */
3636
- this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator
3637
- /**
3638
- * @cfg {Boolean} [decodePercentEncoding=true]
3639
- *
3640
- * `true` to decode percent-encoded characters in URL matches, `false` to keep
3641
- * the percent-encoded characters.
3642
- *
3643
- * Example when `true`: `https://en.wikipedia.org/wiki/San_Jos%C3%A9` will
3644
- * be displayed as `https://en.wikipedia.org/wiki/San_José`.
3645
- */
3646
- this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator
3647
- /**
3648
- * @cfg {Number/Object} [truncate=0]
3649
- *
3650
- * ## Number Form
3651
- *
3652
- * A number for how many characters matched text should be truncated to
3653
- * inside the text of a link. If the matched text is over this number of
3654
- * characters, it will be truncated to this length by adding a two period
3655
- * ellipsis ('..') to the end of the string.
3656
- *
3657
- * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file'
3658
- * truncated to 25 characters might look something like this:
3659
- * 'yahoo.com/some/long/pat..'
3660
- *
3661
- * Example Usage:
3662
- *
3663
- * truncate: 25
3664
- *
3665
- *
3666
- * Defaults to `0` for "no truncation."
3667
- *
3668
- *
3669
- * ## Object Form
3670
- *
3671
- * An Object may also be provided with two properties: `length` (Number) and
3672
- * `location` (String). `location` may be one of the following: 'end'
3673
- * (default), 'middle', or 'smart'.
3674
- *
3675
- * Example Usage:
3676
- *
3677
- * truncate: { length: 25, location: 'middle' }
3678
- *
3679
- * @cfg {Number} [truncate.length=0] How many characters to allow before
3680
- * truncation will occur. Defaults to `0` for "no truncation."
3681
- * @cfg {"end"/"middle"/"smart"} [truncate.location="end"]
3682
- *
3683
- * - 'end' (default): will truncate up to the number of characters, and then
3684
- * add an ellipsis at the end. Ex: 'yahoo.com/some/long/pat..'
3685
- * - 'middle': will truncate and add the ellipsis in the middle. Ex:
3686
- * 'yahoo.com/s..th/to/a/file'
3687
- * - 'smart': for URLs where the algorithm attempts to strip out unnecessary
3688
- * parts first (such as the 'www.', then URL scheme, hash, etc.),
3689
- * attempting to make the URL human-readable before looking for a good
3690
- * point to insert the ellipsis if it is still too long. Ex:
3691
- * 'yahoo.com/some..to/a/file'. For more details, see
3692
- * {@link Autolinker.truncate.TruncateSmart}.
3693
- */
3694
- this.truncate = { length: 0, location: 'end' }; // default value just to get the above doc comment in the ES5 output and documentation generator
3695
- /**
3696
- * @cfg {String} className
3697
- *
3698
- * A CSS class name to add to the generated links. This class will be added
3699
- * to all links, as well as this class plus match suffixes for styling
3700
- * url/email/phone/hashtag/mention links differently.
3701
- *
3702
- * For example, if this config is provided as "myLink", then:
3703
- *
3704
- * - URL links will have the CSS classes: "myLink myLink-url"
3705
- * - Email links will have the CSS classes: "myLink myLink-email", and
3706
- * - Phone links will have the CSS classes: "myLink myLink-phone"
3707
- * - Hashtag links will have the CSS classes: "myLink myLink-hashtag"
3708
- * - Mention links will have the CSS classes: "myLink myLink-mention myLink-[type]"
3709
- * where [type] is either "instagram", "twitter" or "soundcloud"
3710
- */
3711
- this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
3712
- /**
3713
- * @cfg {Function} replaceFn
3714
- *
3715
- * A function to individually process each match found in the input string.
3716
- *
3717
- * See the class's description for usage.
3718
- *
3719
- * The `replaceFn` can be called with a different context object (`this`
3720
- * reference) using the {@link #context} cfg.
3721
- *
3722
- * This function is called with the following parameter:
3723
- *
3724
- * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which
3725
- * can be used to retrieve information about the match that the `replaceFn`
3726
- * is currently processing. See {@link Autolinker.match.Match} subclasses
3727
- * for details.
3728
- */
3729
- this.replaceFn = null; // default value just to get the above doc comment in the ES5 output and documentation generator
3730
- /**
3731
- * @cfg {Object} context
3732
- *
3733
- * The context object (`this` reference) to call the `replaceFn` with.
3734
- *
3735
- * Defaults to this Autolinker instance.
3736
- */
3737
- this.context = undefined; // default value just to get the above doc comment in the ES5 output and documentation generator
3738
- /**
3739
- * @cfg {Boolean} [sanitizeHtml=false]
3740
- *
3741
- * `true` to HTML-encode the start and end brackets of existing HTML tags found
3742
- * in the input string. This will escape `<` and `>` characters to `&lt;` and
3743
- * `&gt;`, respectively.
3744
- *
3745
- * Setting this to `true` will prevent XSS (Cross-site Scripting) attacks,
3746
- * but will remove the significance of existing HTML tags in the input string. If
3747
- * you would like to maintain the significance of existing HTML tags while also
3748
- * making the output HTML string safe, leave this option as `false` and use a
3749
- * tool like https://github.com/cure53/DOMPurify (or others) on the input string
3750
- * before running Autolinker.
3751
- */
3752
- this.sanitizeHtml = false; // default value just to get the above doc comment in the ES5 output and documentation generator
3753
- /**
3754
- * @private
3755
- * @property {Autolinker.matcher.Matcher[]} matchers
3756
- *
3757
- * The {@link Autolinker.matcher.Matcher} instances for this Autolinker
3758
- * instance.
3759
- *
3760
- * This is lazily created in {@link #getMatchers}.
3761
- */
3762
- this.matchers = null;
3763
- /**
3764
- * @private
3765
- * @property {Autolinker.AnchorTagBuilder} tagBuilder
3766
- *
3767
- * The AnchorTagBuilder instance used to build match replacement anchor tags.
3768
- * Note: this is lazily instantiated in the {@link #getTagBuilder} method.
3769
- */
3770
- this.tagBuilder = null;
3771
- // Note: when `this.something` is used in the rhs of these assignments,
3772
- // it refers to the default values set above the constructor
3773
- this.urls = this.normalizeUrlsCfg(cfg.urls);
3774
- this.email = typeof cfg.email === 'boolean' ? cfg.email : this.email;
3775
- this.phone = typeof cfg.phone === 'boolean' ? cfg.phone : this.phone;
3776
- this.hashtag = cfg.hashtag || this.hashtag;
3777
- this.mention = cfg.mention || this.mention;
3778
- this.newWindow = typeof cfg.newWindow === 'boolean' ? cfg.newWindow : this.newWindow;
3779
- this.stripPrefix = this.normalizeStripPrefixCfg(cfg.stripPrefix);
3780
- this.stripTrailingSlash = typeof cfg.stripTrailingSlash === 'boolean' ? cfg.stripTrailingSlash : this.stripTrailingSlash;
3781
- this.decodePercentEncoding = typeof cfg.decodePercentEncoding === 'boolean' ? cfg.decodePercentEncoding : this.decodePercentEncoding;
3782
- this.sanitizeHtml = cfg.sanitizeHtml || false;
3783
- // Validate the value of the `mention` cfg
3784
- var mention = this.mention;
3785
- if (mention !== false && mention !== 'twitter' && mention !== 'instagram' && mention !== 'soundcloud') {
3786
- throw new Error("invalid `mention` cfg - see docs");
3787
- }
3788
- // Validate the value of the `hashtag` cfg
3789
- var hashtag = this.hashtag;
3790
- if (hashtag !== false && hashtag !== 'twitter' && hashtag !== 'facebook' && hashtag !== 'instagram') {
3791
- throw new Error("invalid `hashtag` cfg - see docs");
3792
- }
3793
- this.truncate = this.normalizeTruncateCfg(cfg.truncate);
3794
- this.className = cfg.className || this.className;
3795
- this.replaceFn = cfg.replaceFn || this.replaceFn;
3796
- this.context = cfg.context || this;
3797
- }
3798
- /**
3799
- * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles,
3800
- * Hashtags, and Mentions found in the given chunk of HTML. Does not link URLs
3801
- * found within HTML tags.
3802
- *
3803
- * For instance, if given the text: `You should go to http://www.yahoo.com`,
3804
- * then the result will be `You should go to &lt;a href="http://www.yahoo.com"&gt;http://www.yahoo.com&lt;/a&gt;`
3805
- *
3806
- * Example:
3807
- *
3808
- * var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } );
3809
- * // Produces: "Go to <a href="http://google.com">google.com</a>"
3810
- *
3811
- * @static
3812
- * @param {String} textOrHtml The HTML or text to find matches within (depending
3813
- * on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #mention},
3814
- * {@link #hashtag}, and {@link #mention} options are enabled).
3815
- * @param {Object} [options] Any of the configuration options for the Autolinker
3816
- * class, specified in an Object (map). See the class description for an
3817
- * example call.
3818
- * @return {String} The HTML text, with matches automatically linked.
3819
- */
3820
- Autolinker.link = function (textOrHtml, options) {
3821
- var autolinker = new Autolinker(options);
3822
- return autolinker.link(textOrHtml);
3823
- };
3824
- /**
3825
- * Parses the input `textOrHtml` looking for URLs, email addresses, phone
3826
- * numbers, username handles, and hashtags (depending on the configuration
3827
- * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
3828
- * objects describing those matches (without making any replacements).
3829
- *
3830
- * Note that if parsing multiple pieces of text, it is slightly more efficient
3831
- * to create an Autolinker instance, and use the instance-level {@link #parse}
3832
- * method.
3833
- *
3834
- * Example:
3835
- *
3836
- * var matches = Autolinker.parse( "Hello google.com, I am asdf@asdf.com", {
3837
- * urls: true,
3838
- * email: true
3839
- * } );
3840
- *
3841
- * console.log( matches.length ); // 2
3842
- * console.log( matches[ 0 ].getType() ); // 'url'
3843
- * console.log( matches[ 0 ].getUrl() ); // 'google.com'
3844
- * console.log( matches[ 1 ].getType() ); // 'email'
3845
- * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
3846
- *
3847
- * @static
3848
- * @param {String} textOrHtml The HTML or text to find matches within
3849
- * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
3850
- * {@link #hashtag}, and {@link #mention} options are enabled).
3851
- * @param {Object} [options] Any of the configuration options for the Autolinker
3852
- * class, specified in an Object (map). See the class description for an
3853
- * example call.
3854
- * @return {Autolinker.match.Match[]} The array of Matches found in the
3855
- * given input `textOrHtml`.
3856
- */
3857
- Autolinker.parse = function (textOrHtml, options) {
3858
- var autolinker = new Autolinker(options);
3859
- return autolinker.parse(textOrHtml);
3860
- };
3861
- /**
3862
- * Normalizes the {@link #urls} config into an Object with 3 properties:
3863
- * `schemeMatches`, `wwwMatches`, and `tldMatches`, all Booleans.
3864
- *
3865
- * See {@link #urls} config for details.
3866
- *
3867
- * @private
3868
- * @param {Boolean/Object} urls
3869
- * @return {Object}
3870
- */
3871
- Autolinker.prototype.normalizeUrlsCfg = function (urls) {
3872
- if (urls == null)
3873
- urls = true; // default to `true`
3874
- if (typeof urls === 'boolean') {
3875
- return { schemeMatches: urls, wwwMatches: urls, tldMatches: urls };
3876
- }
3877
- else { // object form
3878
- return {
3879
- schemeMatches: typeof urls.schemeMatches === 'boolean' ? urls.schemeMatches : true,
3880
- wwwMatches: typeof urls.wwwMatches === 'boolean' ? urls.wwwMatches : true,
3881
- tldMatches: typeof urls.tldMatches === 'boolean' ? urls.tldMatches : true
3882
- };
3883
- }
3884
- };
3885
- /**
3886
- * Normalizes the {@link #stripPrefix} config into an Object with 2
3887
- * properties: `scheme`, and `www` - both Booleans.
3888
- *
3889
- * See {@link #stripPrefix} config for details.
3890
- *
3891
- * @private
3892
- * @param {Boolean/Object} stripPrefix
3893
- * @return {Object}
3894
- */
3895
- Autolinker.prototype.normalizeStripPrefixCfg = function (stripPrefix) {
3896
- if (stripPrefix == null)
3897
- stripPrefix = true; // default to `true`
3898
- if (typeof stripPrefix === 'boolean') {
3899
- return { scheme: stripPrefix, www: stripPrefix };
3900
- }
3901
- else { // object form
3902
- return {
3903
- scheme: typeof stripPrefix.scheme === 'boolean' ? stripPrefix.scheme : true,
3904
- www: typeof stripPrefix.www === 'boolean' ? stripPrefix.www : true
3905
- };
3906
- }
3907
- };
3908
- /**
3909
- * Normalizes the {@link #truncate} config into an Object with 2 properties:
3910
- * `length` (Number), and `location` (String).
3911
- *
3912
- * See {@link #truncate} config for details.
3913
- *
3914
- * @private
3915
- * @param {Number/Object} truncate
3916
- * @return {Object}
3917
- */
3918
- Autolinker.prototype.normalizeTruncateCfg = function (truncate) {
3919
- if (typeof truncate === 'number') {
3920
- return { length: truncate, location: 'end' };
3921
- }
3922
- else { // object, or undefined/null
3923
- return defaults(truncate || {}, {
3924
- length: Number.POSITIVE_INFINITY,
3925
- location: 'end'
3926
- });
3927
- }
3928
- };
3929
- /**
3930
- * Parses the input `textOrHtml` looking for URLs, email addresses, phone
3931
- * numbers, username handles, and hashtags (depending on the configuration
3932
- * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
3933
- * objects describing those matches (without making any replacements).
3934
- *
3935
- * This method is used by the {@link #link} method, but can also be used to
3936
- * simply do parsing of the input in order to discover what kinds of links
3937
- * there are and how many.
3938
- *
3939
- * Example usage:
3940
- *
3941
- * var autolinker = new Autolinker( {
3942
- * urls: true,
3943
- * email: true
3944
- * } );
3945
- *
3946
- * var matches = autolinker.parse( "Hello google.com, I am asdf@asdf.com" );
3947
- *
3948
- * console.log( matches.length ); // 2
3949
- * console.log( matches[ 0 ].getType() ); // 'url'
3950
- * console.log( matches[ 0 ].getUrl() ); // 'google.com'
3951
- * console.log( matches[ 1 ].getType() ); // 'email'
3952
- * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
3953
- *
3954
- * @param {String} textOrHtml The HTML or text to find matches within
3955
- * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
3956
- * {@link #hashtag}, and {@link #mention} options are enabled).
3957
- * @return {Autolinker.match.Match[]} The array of Matches found in the
3958
- * given input `textOrHtml`.
3959
- */
3960
- Autolinker.prototype.parse = function (textOrHtml) {
3961
- var _this = this;
3962
- var skipTagNames = ['a', 'style', 'script'], skipTagsStackCount = 0, // used to only Autolink text outside of anchor/script/style tags. We don't want to autolink something that is already linked inside of an <a> tag, for instance
3963
- matches = [];
3964
- // Find all matches within the `textOrHtml` (but not matches that are
3965
- // already nested within <a>, <style> and <script> tags)
3966
- parseHtml(textOrHtml, {
3967
- onOpenTag: function (tagName) {
3968
- if (skipTagNames.indexOf(tagName) >= 0) {
3969
- skipTagsStackCount++;
3970
- }
3971
- },
3972
- onText: function (text, offset) {
3973
- // Only process text nodes that are not within an <a>, <style> or <script> tag
3974
- if (skipTagsStackCount === 0) {
3975
- // "Walk around" common HTML entities. An '&nbsp;' (for example)
3976
- // could be at the end of a URL, but we don't want to
3977
- // include the trailing '&' in the URL. See issue #76
3978
- // TODO: Handle HTML entities separately in parseHtml() and
3979
- // don't emit them as "text" except for &amp; entities
3980
- var htmlCharacterEntitiesRegex = /(&nbsp;|&#160;|&lt;|&#60;|&gt;|&#62;|&quot;|&#34;|&#39;)/gi;
3981
- var textSplit = splitAndCapture(text, htmlCharacterEntitiesRegex);
3982
- var currentOffset_1 = offset;
3983
- textSplit.forEach(function (splitText, i) {
3984
- // even number matches are text, odd numbers are html entities
3985
- if (i % 2 === 0) {
3986
- var textNodeMatches = _this.parseText(splitText, currentOffset_1);
3987
- matches.push.apply(matches, textNodeMatches);
3988
- }
3989
- currentOffset_1 += splitText.length;
3990
- });
3991
- }
3992
- },
3993
- onCloseTag: function (tagName) {
3994
- if (skipTagNames.indexOf(tagName) >= 0) {
3995
- skipTagsStackCount = Math.max(skipTagsStackCount - 1, 0); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0
3996
- }
3997
- },
3998
- onComment: function (offset) { },
3999
- onDoctype: function (offset) { },
4000
- });
4001
- // After we have found all matches, remove subsequent matches that
4002
- // overlap with a previous match. This can happen for instance with URLs,
4003
- // where the url 'google.com/#link' would match '#link' as a hashtag.
4004
- matches = this.compactMatches(matches);
4005
- // And finally, remove matches for match types that have been turned
4006
- // off. We needed to have all match types turned on initially so that
4007
- // things like hashtags could be filtered out if they were really just
4008
- // part of a URL match (for instance, as a named anchor).
4009
- matches = this.removeUnwantedMatches(matches);
4010
- return matches;
4011
- };
4012
- /**
4013
- * After we have found all matches, we need to remove matches that overlap
4014
- * with a previous match. This can happen for instance with URLs, where the
4015
- * url 'google.com/#link' would match '#link' as a hashtag. Because the
4016
- * '#link' part is contained in a larger match that comes before the HashTag
4017
- * match, we'll remove the HashTag match.
4018
- *
4019
- * @private
4020
- * @param {Autolinker.match.Match[]} matches
4021
- * @return {Autolinker.match.Match[]}
4022
- */
4023
- Autolinker.prototype.compactMatches = function (matches) {
4024
- // First, the matches need to be sorted in order of offset
4025
- matches.sort(function (a, b) { return a.getOffset() - b.getOffset(); });
4026
- for (var i = 0; i < matches.length - 1; i++) {
4027
- var match = matches[i], offset = match.getOffset(), matchedTextLength = match.getMatchedText().length, endIdx = offset + matchedTextLength;
4028
- if (i + 1 < matches.length) {
4029
- // Remove subsequent matches that equal offset with current match
4030
- if (matches[i + 1].getOffset() === offset) {
4031
- var removeIdx = matches[i + 1].getMatchedText().length > matchedTextLength ? i : i + 1;
4032
- matches.splice(removeIdx, 1);
4033
- continue;
4034
- }
4035
- // Remove subsequent matches that overlap with the current match
4036
- if (matches[i + 1].getOffset() < endIdx) {
4037
- matches.splice(i + 1, 1);
4038
- }
4039
- }
4040
- }
4041
- return matches;
4042
- };
4043
- /**
4044
- * Removes matches for matchers that were turned off in the options. For
4045
- * example, if {@link #hashtag hashtags} were not to be matched, we'll
4046
- * remove them from the `matches` array here.
4047
- *
4048
- * Note: we *must* use all Matchers on the input string, and then filter
4049
- * them out later. For example, if the options were `{ url: false, hashtag: true }`,
4050
- * we wouldn't want to match the text '#link' as a HashTag inside of the text
4051
- * 'google.com/#link'. The way the algorithm works is that we match the full
4052
- * URL first (which prevents the accidental HashTag match), and then we'll
4053
- * simply throw away the URL match.
4054
- *
4055
- * @private
4056
- * @param {Autolinker.match.Match[]} matches The array of matches to remove
4057
- * the unwanted matches from. Note: this array is mutated for the
4058
- * removals.
4059
- * @return {Autolinker.match.Match[]} The mutated input `matches` array.
4060
- */
4061
- Autolinker.prototype.removeUnwantedMatches = function (matches) {
4062
- if (!this.hashtag)
4063
- remove(matches, function (match) { return match.getType() === 'hashtag'; });
4064
- if (!this.email)
4065
- remove(matches, function (match) { return match.getType() === 'email'; });
4066
- if (!this.phone)
4067
- remove(matches, function (match) { return match.getType() === 'phone'; });
4068
- if (!this.mention)
4069
- remove(matches, function (match) { return match.getType() === 'mention'; });
4070
- if (!this.urls.schemeMatches) {
4071
- remove(matches, function (m) { return m.getType() === 'url' && m.getUrlMatchType() === 'scheme'; });
4072
- }
4073
- if (!this.urls.wwwMatches) {
4074
- remove(matches, function (m) { return m.getType() === 'url' && m.getUrlMatchType() === 'www'; });
4075
- }
4076
- if (!this.urls.tldMatches) {
4077
- remove(matches, function (m) { return m.getType() === 'url' && m.getUrlMatchType() === 'tld'; });
4078
- }
4079
- return matches;
4080
- };
4081
- /**
4082
- * Parses the input `text` looking for URLs, email addresses, phone
4083
- * numbers, username handles, and hashtags (depending on the configuration
4084
- * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
4085
- * objects describing those matches.
4086
- *
4087
- * This method processes a **non-HTML string**, and is used to parse and
4088
- * match within the text nodes of an HTML string. This method is used
4089
- * internally by {@link #parse}.
4090
- *
4091
- * @private
4092
- * @param {String} text The text to find matches within (depending on if the
4093
- * {@link #urls}, {@link #email}, {@link #phone},
4094
- * {@link #hashtag}, and {@link #mention} options are enabled). This must be a non-HTML string.
4095
- * @param {Number} [offset=0] The offset of the text node within the
4096
- * original string. This is used when parsing with the {@link #parse}
4097
- * method to generate correct offsets within the {@link Autolinker.match.Match}
4098
- * instances, but may be omitted if calling this method publicly.
4099
- * @return {Autolinker.match.Match[]} The array of Matches found in the
4100
- * given input `text`.
4101
- */
4102
- Autolinker.prototype.parseText = function (text, offset) {
4103
- if (offset === void 0) { offset = 0; }
4104
- offset = offset || 0;
4105
- var matchers = this.getMatchers(), matches = [];
4106
- for (var i = 0, numMatchers = matchers.length; i < numMatchers; i++) {
4107
- var textMatches = matchers[i].parseMatches(text);
4108
- // Correct the offset of each of the matches. They are originally
4109
- // the offset of the match within the provided text node, but we
4110
- // need to correct them to be relative to the original HTML input
4111
- // string (i.e. the one provided to #parse).
4112
- for (var j = 0, numTextMatches = textMatches.length; j < numTextMatches; j++) {
4113
- textMatches[j].setOffset(offset + textMatches[j].getOffset());
4114
- }
4115
- matches.push.apply(matches, textMatches);
4116
- }
4117
- return matches;
4118
- };
4119
- /**
4120
- * Automatically links URLs, Email addresses, Phone numbers, Hashtags,
4121
- * and Mentions (Twitter, Instagram, Soundcloud) found in the given chunk of HTML. Does not link
4122
- * URLs found within HTML tags.
4123
- *
4124
- * For instance, if given the text: `You should go to http://www.yahoo.com`,
4125
- * then the result will be `You should go to
4126
- * &lt;a href="http://www.yahoo.com"&gt;http://www.yahoo.com&lt;/a&gt;`
4127
- *
4128
- * This method finds the text around any HTML elements in the input
4129
- * `textOrHtml`, which will be the text that is processed. Any original HTML
4130
- * elements will be left as-is, as well as the text that is already wrapped
4131
- * in anchor (&lt;a&gt;) tags.
4132
- *
4133
- * @param {String} textOrHtml The HTML or text to autolink matches within
4134
- * (depending on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #hashtag}, and {@link #mention} options are enabled).
4135
- * @return {String} The HTML, with matches automatically linked.
4136
- */
4137
- Autolinker.prototype.link = function (textOrHtml) {
4138
- if (!textOrHtml) {
4139
- return "";
4140
- } // handle `null` and `undefined` (for JavaScript users that don't have TypeScript support)
4141
- /* We would want to sanitize the start and end characters of a tag
4142
- * before processing the string in order to avoid an XSS scenario.
4143
- * This behaviour can be changed by toggling the sanitizeHtml option.
4144
- */
4145
- if (this.sanitizeHtml) {
4146
- textOrHtml = textOrHtml
4147
- .replace(/</g, '&lt;')
4148
- .replace(/>/g, '&gt;');
4149
- }
4150
- var matches = this.parse(textOrHtml), newHtml = [], lastIndex = 0;
4151
- for (var i = 0, len = matches.length; i < len; i++) {
4152
- var match = matches[i];
4153
- newHtml.push(textOrHtml.substring(lastIndex, match.getOffset()));
4154
- newHtml.push(this.createMatchReturnVal(match));
4155
- lastIndex = match.getOffset() + match.getMatchedText().length;
4156
- }
4157
- newHtml.push(textOrHtml.substring(lastIndex)); // handle the text after the last match
4158
- return newHtml.join('');
4159
- };
4160
- /**
4161
- * Creates the return string value for a given match in the input string.
4162
- *
4163
- * This method handles the {@link #replaceFn}, if one was provided.
4164
- *
4165
- * @private
4166
- * @param {Autolinker.match.Match} match The Match object that represents
4167
- * the match.
4168
- * @return {String} The string that the `match` should be replaced with.
4169
- * This is usually the anchor tag string, but may be the `matchStr` itself
4170
- * if the match is not to be replaced.
4171
- */
4172
- Autolinker.prototype.createMatchReturnVal = function (match) {
4173
- // Handle a custom `replaceFn` being provided
4174
- var replaceFnResult;
4175
- if (this.replaceFn) {
4176
- replaceFnResult = this.replaceFn.call(this.context, match); // Autolinker instance is the context
4177
- }
4178
- if (typeof replaceFnResult === 'string') {
4179
- return replaceFnResult; // `replaceFn` returned a string, use that
4180
- }
4181
- else if (replaceFnResult === false) {
4182
- return match.getMatchedText(); // no replacement for the match
4183
- }
4184
- else if (replaceFnResult instanceof HtmlTag) {
4185
- return replaceFnResult.toAnchorString();
4186
- }
4187
- else { // replaceFnResult === true, or no/unknown return value from function
4188
- // Perform Autolinker's default anchor tag generation
4189
- var anchorTag = match.buildTag(); // returns an Autolinker.HtmlTag instance
4190
- return anchorTag.toAnchorString();
4191
- }
4192
- };
4193
- /**
4194
- * Lazily instantiates and returns the {@link Autolinker.matcher.Matcher}
4195
- * instances for this Autolinker instance.
4196
- *
4197
- * @private
4198
- * @return {Autolinker.matcher.Matcher[]}
4199
- */
4200
- Autolinker.prototype.getMatchers = function () {
4201
- if (!this.matchers) {
4202
- var tagBuilder = this.getTagBuilder();
4203
- var matchers = [
4204
- new HashtagMatcher({ tagBuilder: tagBuilder, serviceName: this.hashtag }),
4205
- new EmailMatcher({ tagBuilder: tagBuilder }),
4206
- new PhoneMatcher({ tagBuilder: tagBuilder }),
4207
- new MentionMatcher({ tagBuilder: tagBuilder, serviceName: this.mention }),
4208
- new UrlMatcher({ tagBuilder: tagBuilder, stripPrefix: this.stripPrefix, stripTrailingSlash: this.stripTrailingSlash, decodePercentEncoding: this.decodePercentEncoding })
4209
- ];
4210
- return (this.matchers = matchers);
4211
- }
4212
- else {
4213
- return this.matchers;
4214
- }
4215
- };
4216
- /**
4217
- * Returns the {@link #tagBuilder} instance for this Autolinker instance,
4218
- * lazily instantiating it if it does not yet exist.
4219
- *
4220
- * @private
4221
- * @return {Autolinker.AnchorTagBuilder}
4222
- */
4223
- Autolinker.prototype.getTagBuilder = function () {
4224
- var tagBuilder = this.tagBuilder;
4225
- if (!tagBuilder) {
4226
- tagBuilder = this.tagBuilder = new AnchorTagBuilder({
4227
- newWindow: this.newWindow,
4228
- truncate: this.truncate,
4229
- className: this.className
4230
- });
4231
- }
4232
- return tagBuilder;
4233
- };
4234
- /**
4235
- * @static
4236
- * @property {String} version
4237
- *
4238
- * The Autolinker version number in the form major.minor.patch
4239
- *
4240
- * Ex: 0.25.1
4241
- */
4242
- Autolinker.version = '3.14.2';
4243
- /**
4244
- * For backwards compatibility with Autolinker 1.x, the AnchorTagBuilder
4245
- * class is provided as a static on the Autolinker class.
4246
- */
4247
- Autolinker.AnchorTagBuilder = AnchorTagBuilder;
4248
- /**
4249
- * For backwards compatibility with Autolinker 1.x, the HtmlTag class is
4250
- * provided as a static on the Autolinker class.
4251
- */
4252
- Autolinker.HtmlTag = HtmlTag;
4253
- /**
4254
- * For backwards compatibility with Autolinker 1.x, the Matcher classes are
4255
- * provided as statics on the Autolinker class.
4256
- */
4257
- Autolinker.matcher = {
4258
- Email: EmailMatcher,
4259
- Hashtag: HashtagMatcher,
4260
- Matcher: Matcher,
4261
- Mention: MentionMatcher,
4262
- Phone: PhoneMatcher,
4263
- Url: UrlMatcher
4264
- };
4265
- /**
4266
- * For backwards compatibility with Autolinker 1.x, the Match classes are
4267
- * provided as statics on the Autolinker class.
4268
- */
4269
- Autolinker.match = {
4270
- Email: EmailMatch,
4271
- Hashtag: HashtagMatch,
4272
- Match: Match,
4273
- Mention: MentionMatch,
4274
- Phone: PhoneMatch,
4275
- Url: UrlMatch
4276
- };
4277
- return Autolinker;
4278
- }());
4279
-
4280
- export { Autolinker };
4281
- //# sourceMappingURL=autolinker.js.map