lists.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. import { testDataProcessor } from '../_utils/utils';
  6. import MarkdownDataProcessor from '../../src/gfmdataprocessor';
  7. import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';
  8. describe( 'GFMDataProcessor', () => {
  9. describe( 'lists', () => {
  10. it( 'should process tight asterisks', () => {
  11. testDataProcessor(
  12. '* item 1\n' +
  13. '* item 2\n' +
  14. '* item 3',
  15. // GitHub renders it as (notice spaces before list items)
  16. // <ul>
  17. // <li> item 1</li>
  18. // <li> item 2</li>
  19. // <li> item 3</li>
  20. // </ul>
  21. '<ul><li>item 1</li><li>item 2</li><li>item 3</li></ul>',
  22. // List will be normalized to 3-space representation.
  23. '* item 1\n' +
  24. '* item 2\n' +
  25. '* item 3'
  26. );
  27. } );
  28. it( 'should process loose asterisks', () => {
  29. testDataProcessor(
  30. '* item 1\n' +
  31. '\n' +
  32. '* item 2\n' +
  33. '\n' +
  34. '* item 3',
  35. // Loose lists are rendered with with paragraph inside.
  36. '<ul>' +
  37. '<li>' +
  38. '<p>item 1</p>' +
  39. '</li>' +
  40. '<li>' +
  41. '<p>item 2</p>' +
  42. '</li>' +
  43. '<li>' +
  44. '<p>item 3</p>' +
  45. '</li>' +
  46. '</ul>',
  47. // List will be normalized to 3-space representation.
  48. '* item 1\n' +
  49. '\n' +
  50. '* item 2\n' +
  51. '\n' +
  52. '* item 3'
  53. );
  54. } );
  55. it( 'should process tight pluses', () => {
  56. testDataProcessor(
  57. '+ item 1\n' +
  58. '+ item 2\n' +
  59. '+ item 3',
  60. '<ul>' +
  61. '<li>item 1</li>' +
  62. '<li>item 2</li>' +
  63. '<li>item 3</li>' +
  64. '</ul>',
  65. // List will be normalized to asterisks, 3-space representation.
  66. '* item 1\n' +
  67. '* item 2\n' +
  68. '* item 3'
  69. );
  70. } );
  71. it( 'should process loose pluses', () => {
  72. testDataProcessor(
  73. '+ item 1\n' +
  74. '\n' +
  75. '+ item 2\n' +
  76. '\n' +
  77. '+ item 3',
  78. '<ul>' +
  79. '<li>' +
  80. '<p>item 1</p>' +
  81. '</li>' +
  82. '<li>' +
  83. '<p>item 2</p>' +
  84. '</li>' +
  85. '<li>' +
  86. '<p>item 3</p>' +
  87. '</li>' +
  88. '</ul>',
  89. // List will be normalized to asterisks, 3-space representation.
  90. '* item 1\n' +
  91. '\n' +
  92. '* item 2\n' +
  93. '\n' +
  94. '* item 3'
  95. );
  96. } );
  97. it( 'should process tight minuses', () => {
  98. testDataProcessor(
  99. '- item 1\n' +
  100. '- item 2\n' +
  101. '- item 3',
  102. '<ul>' +
  103. '<li>item 1</li>' +
  104. '<li>item 2</li>' +
  105. '<li>item 3</li>' +
  106. '</ul>',
  107. // List will be normalized to asterisks, 3-space representation.
  108. '* item 1\n' +
  109. '* item 2\n' +
  110. '* item 3'
  111. );
  112. } );
  113. it( 'should process loose minuses', () => {
  114. testDataProcessor(
  115. '- item 1\n' +
  116. '\n' +
  117. '- item 2\n' +
  118. '\n' +
  119. '- item 3',
  120. '<ul>' +
  121. '<li>' +
  122. '<p>item 1</p>' +
  123. '</li>' +
  124. '<li>' +
  125. '<p>item 2</p>' +
  126. '</li>' +
  127. '<li>' +
  128. '<p>item 3</p>' +
  129. '</li>' +
  130. '</ul>',
  131. // List will be normalized to asterisks, 3-space representation.
  132. '* item 1\n' +
  133. '\n' +
  134. '* item 2\n' +
  135. '\n' +
  136. '* item 3'
  137. );
  138. } );
  139. it( 'should process ordered list with tabs', () => {
  140. testDataProcessor(
  141. '1. item 1\n' +
  142. '2. item 2\n' +
  143. '3. item 3',
  144. '<ol>' +
  145. '<li>item 1</li>' +
  146. '<li>item 2</li>' +
  147. '<li>item 3</li>' +
  148. '</ol>',
  149. // List will be normalized to 2-space representation.
  150. '1. item 1\n' +
  151. '2. item 2\n' +
  152. '3. item 3'
  153. );
  154. } );
  155. it( 'should process ordered list with spaces', () => {
  156. testDataProcessor(
  157. '1. item 1\n' +
  158. '2. item 2\n' +
  159. '3. item 3',
  160. '<ol>' +
  161. '<li>item 1</li>' +
  162. '<li>item 2</li>' +
  163. '<li>item 3</li>' +
  164. '</ol>',
  165. // List will be normalized to 2-space representation.
  166. '1. item 1\n' +
  167. '2. item 2\n' +
  168. '3. item 3'
  169. );
  170. } );
  171. it( 'should process loose ordered list with tabs', () => {
  172. testDataProcessor(
  173. '1. item 1\n' +
  174. '\n' +
  175. '2. item 2\n' +
  176. '\n' +
  177. '3. item 3',
  178. '<ol>' +
  179. '<li>' +
  180. '<p>item 1</p>' +
  181. '</li>' +
  182. '<li>' +
  183. '<p>item 2</p>' +
  184. '</li>' +
  185. '<li>' +
  186. '<p>item 3</p>' +
  187. '</li>' +
  188. '</ol>',
  189. // List will be normalized to 2-space representation.
  190. '1. item 1\n' +
  191. '\n' +
  192. '2. item 2\n' +
  193. '\n' +
  194. '3. item 3'
  195. );
  196. } );
  197. it( 'should process loose ordered list with spaces', () => {
  198. testDataProcessor(
  199. '1. item 1\n' +
  200. '\n' +
  201. '2. item 2\n' +
  202. '\n' +
  203. '3. item 3',
  204. '<ol>' +
  205. '<li>' +
  206. '<p>item 1</p>' +
  207. '</li>' +
  208. '<li>' +
  209. '<p>item 2</p>' +
  210. '</li>' +
  211. '<li>' +
  212. '<p>item 3</p>' +
  213. '</li>' +
  214. '</ol>',
  215. // List will be normalized to 2-space representation.
  216. '1. item 1\n' +
  217. '\n' +
  218. '2. item 2\n' +
  219. '\n' +
  220. '3. item 3'
  221. );
  222. } );
  223. it( 'should process nested and mixed lists', () => {
  224. testDataProcessor(
  225. '1. First\n' +
  226. '2. Second:\n' +
  227. ' * Fee\n' +
  228. ' * Fie\n' +
  229. ' * Foe\n' +
  230. '3. Third',
  231. '<ol>' +
  232. '<li>First</li>' +
  233. '<li>Second:' +
  234. '<ul>' +
  235. '<li>Fee</li>' +
  236. '<li>Fie</li>' +
  237. '<li>Foe</li>' +
  238. '</ul>' +
  239. '</li>' +
  240. '<li>Third</li>' +
  241. '</ol>',
  242. // All lists will be normalized after converting back.
  243. '1. First\n' +
  244. '2. Second:\n' +
  245. ' * Fee\n' +
  246. ' * Fie\n' +
  247. ' * Foe\n' +
  248. '3. Third'
  249. );
  250. } );
  251. it( 'should process nested and mixed loose lists', () => {
  252. testDataProcessor(
  253. '1. First\n' +
  254. '\n' +
  255. '2. Second:\n' +
  256. ' * Fee\n' +
  257. ' * Fie\n' +
  258. ' * Foe\n' +
  259. '\n' +
  260. '3. Third',
  261. '<ol>' +
  262. '<li>' +
  263. '<p>First</p>' +
  264. '</li>' +
  265. '<li>' +
  266. '<p>Second:</p>' +
  267. '<ul>' +
  268. '<li>Fee</li>' +
  269. '<li>Fie</li>' +
  270. '<li>Foe</li>' +
  271. '</ul>' +
  272. '</li>' +
  273. '<li>' +
  274. '<p>Third</p>' +
  275. '</li>' +
  276. '</ol>',
  277. // All lists will be normalized after converting back.
  278. '1. First\n' +
  279. '\n' +
  280. '2. Second:\n' +
  281. '\n' +
  282. ' * Fee\n' +
  283. ' * Fie\n' +
  284. ' * Foe\n' +
  285. '3. Third'
  286. );
  287. } );
  288. it( 'should create same bullet from different list indicators', () => {
  289. testDataProcessor(
  290. '* test\n' +
  291. '+ test\n' +
  292. '- test',
  293. '<ul>' +
  294. '<li>test</li>' +
  295. '<li>test</li>' +
  296. '<li>test</li>' +
  297. '</ul>',
  298. // After converting back list items will be unified.
  299. '* test\n' +
  300. '* test\n' +
  301. '* test'
  302. );
  303. } );
  304. } );
  305. describe( 'todo lists', () => {
  306. it( 'should process todo lists', () => {
  307. testDataProcessor(
  308. '* [ ] Item 1\n' +
  309. '* [x] Item 2',
  310. '<ul>' +
  311. '<li><input disabled="" type="checkbox"></input>Item 1</li>' +
  312. '<li><input checked="" disabled="" type="checkbox"></input>Item 2</li>' +
  313. '</ul>' );
  314. } );
  315. it( 'should process the HTML produced by the todo list feature', () => {
  316. const htmlDataProcessor = new HtmlDataProcessor();
  317. const mdDataProcessor = new MarkdownDataProcessor();
  318. const viewFragment = htmlDataProcessor.toView(
  319. '<ul class="todo-list">' +
  320. '<li><label class="todo-list__label">' +
  321. '<input type="checkbox" disabled="disabled">' +
  322. '<span class="todo-list__label__description">Item 1</span>' +
  323. '</label></li>' +
  324. '<li><label class="todo-list__label">' +
  325. '<input type="checkbox" disabled="disabled" checked="checked">' +
  326. '<span class="todo-list__label__description">Item 2</span>' +
  327. '</label></li>' +
  328. '</ul>'
  329. );
  330. expect( mdDataProcessor.toData( viewFragment ) ).to.equal(
  331. '* [ ] Item 1\n' +
  332. '* [x] Item 2'
  333. );
  334. } );
  335. } );
  336. } );