links.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import { testDataProcessor as test } from '../../tests/_utils/utils';
  6. describe( 'GFMDataProcessor', () => {
  7. describe( 'links', () => {
  8. it( 'should autolink', () => {
  9. test(
  10. 'Link: <http://example.com/>.',
  11. '<p>Link: <a href="http://example.com/">http://example.com/</a>.</p>',
  12. // When converting back it will be represented as standard markdown link.
  13. 'Link: [http://example.com/](http://example.com/).'
  14. );
  15. } );
  16. it( 'should autolink #2', () => {
  17. test(
  18. 'Link: http://example.com/.',
  19. '<p>Link: <a href="http://example.com/">http://example.com/</a>.</p>',
  20. // When converting back it will be represented as standard markdown link.
  21. 'Link: [http://example.com/](http://example.com/).'
  22. );
  23. } );
  24. it( 'should autolink with params', () => {
  25. test(
  26. 'Link: <http://example.com/?foo=1&bar=2>.',
  27. '<p>Link: <a href="http://example.com/?foo=1&bar=2">http://example.com/?foo=1&bar=2</a>.</p>',
  28. // When converting back it will be represented as standard markdown link.
  29. 'Link: [http://example.com/?foo=1&bar=2](http://example.com/?foo=1&bar=2).'
  30. );
  31. } );
  32. it( 'should autolink inside list', () => {
  33. test(
  34. '* <http://example.com/>',
  35. '<ul><li><a href="http://example.com/">http://example.com/</a></li></ul>',
  36. // When converting back it will be represented as standard markdown link.
  37. '* [http://example.com/](http://example.com/)'
  38. );
  39. } );
  40. it( 'should autolink inside blockquote', () => {
  41. test(
  42. '> Blockquoted: <http://example.com/>',
  43. '<blockquote>' +
  44. '<p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>' +
  45. '</blockquote>',
  46. // When converting back it will be represented as standard markdown link.
  47. '> Blockquoted: [http://example.com/](http://example.com/)'
  48. );
  49. } );
  50. it( 'should not autolink inside inline code', () => {
  51. test(
  52. '`<http://example.com/>`',
  53. '<p><code><http://example.com/></code></p>'
  54. );
  55. } );
  56. it( 'should not autolink inside code block', () => {
  57. test(
  58. ' <http://example.com/>',
  59. '<pre><code><http://example.com/></code></pre>',
  60. // When converting back, code block will be normalized to ```.
  61. '```\n' +
  62. '<http://example.com/>\n' +
  63. '```'
  64. );
  65. } );
  66. it( 'should not process already linked #1', () => {
  67. test(
  68. 'Already linked: [http://example.com/](http://example.com/)',
  69. '<p>Already linked: <a href="http://example.com/">http://example.com/</a></p>'
  70. );
  71. } );
  72. it( 'should not process already linked #2', () => {
  73. test(
  74. 'Already linked: [**http://example.com/**](http://example.com/)',
  75. '<p>Already linked: <a href="http://example.com/"><strong>http://example.com/</strong></a></p>'
  76. );
  77. } );
  78. it( 'should process inline links', () => {
  79. test(
  80. '[URL](/url/)',
  81. '<p><a href="/url/">URL</a></p>'
  82. );
  83. } );
  84. it( 'should process inline links with title', () => {
  85. test(
  86. '[URL and title](/url/ "title")',
  87. '<p><a href="/url/" title="title">URL and title</a></p>'
  88. );
  89. } );
  90. it( 'should process inline links with title preceded by two spaces', () => {
  91. test(
  92. '[URL and title](/url/ "title preceded by two spaces")',
  93. '<p><a href="/url/" title="title preceded by two spaces">URL and title</a></p>',
  94. // When converting back spaces will be normalized to one space.
  95. '[URL and title](/url/ "title preceded by two spaces")'
  96. );
  97. } );
  98. it( 'should process inline links with title preceded by tab', () => {
  99. test(
  100. '[URL and title](/url/ "title preceded by tab")',
  101. '<p><a href="/url/" title="title preceded by tab">URL and title</a></p>',
  102. // When converting back tab will be normalized to one space.
  103. '[URL and title](/url/ "title preceded by tab")'
  104. );
  105. } );
  106. it( 'should process inline links with title that has spaces afterwards', () => {
  107. test(
  108. '[URL and title](/url/ "title has spaces afterward" )',
  109. '<p><a href="/url/" title="title has spaces afterward">URL and title</a></p>',
  110. // When converting back spaces will be removed.
  111. '[URL and title](/url/ "title has spaces afterward")'
  112. );
  113. } );
  114. it( 'should process inline links with spaces in URL', () => {
  115. test(
  116. '[URL and title]( /url/has space )',
  117. '<p><a href="/url/has space">URL and title</a></p>',
  118. // When converting back unneeded spaces will be removed.
  119. '[URL and title](/url/has space)'
  120. );
  121. } );
  122. it( 'should process inline links with titles and spaces in URL', () => {
  123. test(
  124. '[URL and title]( /url/has space/ "url has space and title")',
  125. '<p><a href="/url/has space/" title="url has space and title">URL and title</a></p>',
  126. // When converting back unneeded spaces will be removed.
  127. '[URL and title](/url/has space/ "url has space and title")'
  128. );
  129. } );
  130. it( 'should process empty link', () => {
  131. test(
  132. '[Empty]()',
  133. '<p><a href="">Empty</a></p>'
  134. );
  135. } );
  136. it( 'should process reference links', () => {
  137. test(
  138. 'Foo [bar] [1].\n' +
  139. '[1]: /url/ "Title"',
  140. '<p>Foo <a href="/url/" title="Title">bar</a>.</p>',
  141. // After converting back reference links will be converted to normal links.
  142. // This might be a problem when switching between source and editor.
  143. 'Foo [bar](/url/ "Title").'
  144. );
  145. } );
  146. it( 'should process reference links - without space', () => {
  147. test(
  148. 'Foo [bar][1].\n' +
  149. '[1]: /url/ "Title"',
  150. '<p>Foo <a href="/url/" title="Title">bar</a>.</p>',
  151. 'Foo [bar](/url/ "Title").'
  152. );
  153. } );
  154. it( 'should process reference links - with newline', () => {
  155. test(
  156. 'Foo [bar]\n' +
  157. '[1].\n' +
  158. '[1]: /url/ "Title"',
  159. '<p>Foo <a href="/url/" title="Title">bar</a>.</p>',
  160. 'Foo [bar](/url/ "Title").'
  161. );
  162. } );
  163. it( 'should process reference links - with embedded brackets', () => {
  164. test(
  165. 'With [embedded [brackets]] [b].\n' +
  166. '[b]: /url/',
  167. '<p>With <a href="/url/">embedded [brackets]</a>.</p>',
  168. 'With [embedded [brackets]](/url/).'
  169. );
  170. } );
  171. it( 'should process reference links - with reference indented once', () => {
  172. test(
  173. 'Indented [once][].\n' +
  174. ' [once]: /url',
  175. '<p>Indented <a href="/url">once</a>.</p>',
  176. 'Indented [once](/url).'
  177. );
  178. } );
  179. it( 'should process reference links - with reference indented twice', () => {
  180. test(
  181. 'Indented [twice][].\n' +
  182. ' [twice]: /url',
  183. '<p>Indented <a href="/url">twice</a>.</p>',
  184. 'Indented [twice](/url).'
  185. );
  186. } );
  187. it( 'should process reference links - with reference indented three times', () => {
  188. test(
  189. 'Indented [trice][].\n' +
  190. ' [trice]: /url',
  191. '<p>Indented <a href="/url">trice</a>.</p>',
  192. 'Indented [trice](/url).'
  193. );
  194. } );
  195. it( 'should NOT process reference links - with reference indented four times', () => {
  196. test(
  197. 'Indented [four][].\n' +
  198. ' [four]: /url',
  199. // GitHub renders it as:
  200. // <p>Indented [four][].<br>
  201. // [four]: /url</p>
  202. // Marked converts it to the code block.
  203. '<p>Indented [four][].</p><pre><code>[four]: /url</code></pre>',
  204. 'Indented [four][].\n' +
  205. '\n' +
  206. '```\n' +
  207. '[four]: /url\n' +
  208. '```'
  209. );
  210. } );
  211. it( 'should process reference links when title and reference are same #1', () => {
  212. test(
  213. '[this] [this]\n' +
  214. '[this]: foo',
  215. '<p><a href="foo">this</a></p>',
  216. '[this](foo)'
  217. );
  218. } );
  219. it( 'should process reference links when title and reference are same #2', () => {
  220. test(
  221. '[this][this]\n' +
  222. '[this]: foo',
  223. '<p><a href="foo">this</a></p>',
  224. '[this](foo)'
  225. );
  226. } );
  227. it( 'should process reference links when only title is provided and is same as reference #1', () => {
  228. test(
  229. '[this] []\n' +
  230. '[this]: foo',
  231. '<p><a href="foo">this</a></p>',
  232. '[this](foo)'
  233. );
  234. } );
  235. it( 'should process reference links when only title is provided and is same as reference #2', () => {
  236. test(
  237. '[this][]\n' +
  238. '[this]: foo',
  239. '<p><a href="foo">this</a></p>',
  240. '[this](foo)'
  241. );
  242. } );
  243. it( 'should process reference links when only title is provided and is same as reference #3', () => {
  244. test(
  245. '[this]\n' +
  246. '[this]: foo',
  247. '<p><a href="foo">this</a></p>',
  248. '[this](foo)'
  249. );
  250. } );
  251. it( 'should not process reference links when reference is not found #1', () => {
  252. test(
  253. '[this] []',
  254. '<p>[this] []</p>'
  255. );
  256. } );
  257. it( 'should not process reference links when reference is not found #2', () => {
  258. test(
  259. '[this][]',
  260. '<p>[this][]</p>'
  261. );
  262. } );
  263. it( 'should not process reference links when reference is not found #2', () => {
  264. test(
  265. '[this]',
  266. '<p>[this]</p>'
  267. );
  268. } );
  269. it( 'should process reference links nested in brackets #1', () => {
  270. test(
  271. '[a reference inside [this][]]\n' +
  272. '[this]: foo',
  273. '<p>[a reference inside <a href="foo">this</a>]</p>',
  274. '[a reference inside [this](foo)]'
  275. );
  276. } );
  277. it( 'should process reference links nested in brackets #2', () => {
  278. test(
  279. '[a reference inside [this]]\n' +
  280. '[this]: foo',
  281. '<p>[a reference inside <a href="foo">this</a>]</p>',
  282. '[a reference inside [this](foo)]'
  283. );
  284. } );
  285. it( 'should not process reference links when title is same as reference but reference is different', () => {
  286. test(
  287. '[this](/something/else/)\n' +
  288. '[this]: foo',
  289. '<p><a href="/something/else/">this</a></p>',
  290. '[this](/something/else/)'
  291. );
  292. } );
  293. it( 'should not process reference links suppressed by backslashes', () => {
  294. test(
  295. 'Suppress \\[this] and [this\\].\n' +
  296. '[this]: foo',
  297. '<p>Suppress [this] and [this].</p>',
  298. 'Suppress [this] and [this].'
  299. );
  300. } );
  301. it( 'should process reference links when used across multiple lines #1', () => {
  302. test(
  303. 'This is [multiline\n' +
  304. 'reference]\n' +
  305. '[multiline reference]: foo',
  306. '<p>This is <a href="foo">multiline<br></br>reference</a></p>',
  307. 'This is [multiline\n' +
  308. 'reference](foo)'
  309. );
  310. } );
  311. it( 'should process reference links when used across multiple lines #2', () => {
  312. test(
  313. 'This is [multiline \n' +
  314. 'reference]\n' +
  315. '[multiline reference]: foo',
  316. '<p>This is <a href="foo">multiline<br></br>reference</a></p>',
  317. 'This is [multiline\n' +
  318. 'reference](foo)'
  319. );
  320. } );
  321. it( 'should process reference links case-insensitive', () => {
  322. test(
  323. '[hi]\n' +
  324. '[HI]: /url',
  325. '<p><a href="/url">hi</a></p>',
  326. '[hi](/url)'
  327. );
  328. } );
  329. } );
  330. } );