Welcome to mirror list, hosted at ThFree Co, Russian Federation.

markdown_sourcemap_spec.js « services « content_editor « frontend « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4428fa682e76face4d453e5bdb024fea0c4faedd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import { Extension } from '@tiptap/core';
import BulletList from '~/content_editor/extensions/bullet_list';
import ListItem from '~/content_editor/extensions/list_item';
import TaskList from '~/content_editor/extensions/task_list';
import TaskItem from '~/content_editor/extensions/task_item';
import Paragraph from '~/content_editor/extensions/paragraph';
import markdownDeserializer from '~/content_editor/services/gl_api_markdown_deserializer';
import { getMarkdownSource, getFullSource } from '~/content_editor/services/markdown_sourcemap';
import { createTestEditor, createDocBuilder } from '../test_utils';

const BULLET_LIST_MARKDOWN = `+ list item 1
+ list item 2
  - embedded list item 3`;
const BULLET_LIST_HTML = `<ul data-sourcepos="1:1-3:24" dir="auto">
  <li data-sourcepos="1:1-1:13">list item 1</li>
  <li data-sourcepos="2:1-3:24">list item 2
    <ul data-sourcepos="3:3-3:24">
      <li data-sourcepos="3:3-3:24">embedded list item 3</li>
    </ul>
  </li>
</ul>`;

const BULLET_TASK_LIST_MARKDOWN = `- [ ] list item 1
+ [x] checked list item 2
  + [ ] embedded list item 1
  - [x] checked embedded list item 2`;
const BULLET_TASK_LIST_HTML = `<ul data-sourcepos="1:1-4:36" class="task-list" dir="auto">
  <li data-sourcepos="1:1-1:17" class="task-list-item"><input type="checkbox" class="task-list-item-checkbox"> list item 1</li>
  <li data-sourcepos="2:1-4:36" class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" checked> checked list item 2
    <ul data-sourcepos="3:3-4:36" class="task-list">
      <li data-sourcepos="3:3-3:28" class="task-list-item"><input type="checkbox" class="task-list-item-checkbox"> embedded list item 1</li>
      <li data-sourcepos="4:3-4:36" class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" checked> checked embedded list item 2</li>
    </ul>
  </li>
</ul>`;

const SourcemapExtension = Extension.create({
  // lets add `source` attribute to every element using `getMarkdownSource`
  addGlobalAttributes() {
    return [
      {
        types: [Paragraph.name, BulletList.name, ListItem.name],
        attributes: {
          source: {
            parseHTML: (element) => {
              const source = getMarkdownSource(element);
              return source;
            },
          },
        },
      },
    ];
  },
});

const tiptapEditor = createTestEditor({
  extensions: [BulletList, ListItem, TaskList, TaskItem, SourcemapExtension],
});

const {
  builders: { doc, bulletList, listItem, taskList, taskItem, paragraph },
} = createDocBuilder({
  tiptapEditor,
  names: {
    bulletList: { nodeType: BulletList.name },
    listItem: { nodeType: ListItem.name },
    taskList: { nodeType: TaskList.name },
    taskItem: { nodeType: TaskItem.name },
  },
});

const bulletListDoc = () =>
  doc(
    bulletList(
      { bullet: '+', source: '+ list item 1\n+ list item 2\n  - embedded list item 3' },
      listItem({ source: '+ list item 1' }, paragraph('list item 1')),
      listItem(
        { source: '+ list item 2\n  - embedded list item 3' },
        paragraph('list item 2'),
        bulletList(
          { bullet: '-', source: '- embedded list item 3' },
          listItem({ source: '- embedded list item 3' }, paragraph('embedded list item 3')),
        ),
      ),
    ),
  );

const bulletTaskListDoc = () =>
  doc(
    taskList(
      {
        bullet: '-',
        source:
          '- [ ] list item 1\n+ [x] checked list item 2\n  + [ ] embedded list item 1\n  - [x] checked embedded list item 2',
      },
      taskItem({ source: '- [ ] list item 1' }, paragraph('list item 1')),
      taskItem(
        {
          source:
            '+ [x] checked list item 2\n  + [ ] embedded list item 1\n  - [x] checked embedded list item 2',
          checked: true,
        },
        paragraph('checked list item 2'),
        taskList(
          {
            bullet: '+',
            source: '+ [ ] embedded list item 1\n  - [x] checked embedded list item 2',
          },
          taskItem({ source: '+ [ ] embedded list item 1' }, paragraph('embedded list item 1')),
          taskItem(
            { source: '- [x] checked embedded list item 2', checked: true },
            paragraph('checked embedded list item 2'),
          ),
        ),
      ),
    ),
  );

describe('content_editor/services/markdown_sourcemap', () => {
  describe('getFullSource', () => {
    it.each`
      lastChild                                                                | expected
      ${null}                                                                  | ${[]}
      ${{ nodeName: 'paragraph' }}                                             | ${[]}
      ${{ nodeName: '#comment', textContent: null }}                           | ${[]}
      ${{ nodeName: '#comment', textContent: '+ list item 1\n+ list item 2' }} | ${['+ list item 1', '+ list item 2']}
    `('with lastChild=$lastChild, returns $expected', ({ lastChild, expected }) => {
      const element = {
        ownerDocument: {
          body: {
            lastChild,
          },
        },
      };

      expect(getFullSource(element)).toEqual(expected);
    });
  });

  it.each`
    description           | sourceMarkdown               | sourceHTML               | expectedDoc
    ${'bullet list'}      | ${BULLET_LIST_MARKDOWN}      | ${BULLET_LIST_HTML}      | ${bulletListDoc}
    ${'bullet task list'} | ${BULLET_TASK_LIST_MARKDOWN} | ${BULLET_TASK_LIST_HTML} | ${bulletTaskListDoc}
  `(
    'gets markdown source for a rendered $description',
    async ({ sourceMarkdown, sourceHTML, expectedDoc }) => {
      const { document } = await markdownDeserializer({
        render: () => sourceHTML,
      }).deserialize({
        schema: tiptapEditor.schema,
        markdown: sourceMarkdown,
      });

      expect(document.toJSON()).toEqual(expectedDoc().toJSON());
    },
  );
});