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

utils.js « show « issues « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 60e66f59f92e0f1ec5ba98357c54f327701f3ca6 (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
import { COLON, HYPHEN, NEWLINE } from '~/lib/utils/text_utility';

/**
 * Get the index from sourcepos that represents the line of
 * the description when the description is split by newline.
 *
 * @param {String} sourcepos Source position in format `23:3-23:14`
 * @returns {Number} Index of description split by newline
 */
const getDescriptionIndex = (sourcepos) => {
  const [startRange] = sourcepos.split(HYPHEN);
  const [startRow] = startRange.split(COLON);
  return startRow - 1;
};

/**
 * Given a `ul` or `ol` element containing a new sort order, this function performs
 * a depth-first search to get the new sort order in the form of sourcepos indices.
 *
 * @param {HTMLElement} list A `ul` or `ol` element containing a new sort order
 * @returns {Array<Number>} An array representing the new order of the list
 */
const getNewSourcePositions = (list) => {
  const newSourcePositions = [];

  function pushPositionOfChildListItems(el) {
    if (!el) {
      return;
    }
    if (el.tagName === 'LI') {
      newSourcePositions.push(getDescriptionIndex(el.dataset.sourcepos));
    }
    Array.from(el.children).forEach(pushPositionOfChildListItems);
  }

  pushPositionOfChildListItems(list);

  return newSourcePositions;
};

/**
 * Converts a description to one with a new list sort order.
 *
 * Given a description like:
 *
 * <pre>
 * 1. I am text
 * 2.
 * 3. - Item 1
 * 4. - Item 2
 * 5.   - Item 3
 * 6.   - Item 4
 * 7. - Item 5
 * </pre>
 *
 * And a reordered list (due to dragging Item 2 into Item 1's position) like:
 *
 * <pre>
 * <ul data-sourcepos="3:1-8:0">
 *   <li data-sourcepos="4:1-4:8">
 *     Item 2
 *     <ul data-sourcepos="5:1-6:10">
 *       <li data-sourcepos="5:1-5:10">Item 3</li>
 *       <li data-sourcepos="6:1-6:10">Item 4</li>
 *     </ul>
 *   </li>
 *   <li data-sourcepos="3:1-3:8">Item 1</li>
 *   <li data-sourcepos="7:1-8:0">Item 5</li>
 * <ul>
 * </pre>
 *
 * This function returns:
 *
 * <pre>
 * 1. I am text
 * 2.
 * 3. - Item 2
 * 4.   - Item 3
 * 5.   - Item 4
 * 6. - Item 1
 * 7. - Item 5
 * </pre>
 *
 * @param {String} description Description in markdown format
 * @param {HTMLElement} list A `ul` or `ol` element containing a new sort order
 * @returns {String} Markdown with a new list sort order
 */
export const convertDescriptionWithNewSort = (description, list) => {
  const descriptionLines = description.split(NEWLINE);
  const startIndexOfList = getDescriptionIndex(list.dataset.sourcepos);

  getNewSourcePositions(list)
    .map((lineIndex) => descriptionLines[lineIndex])
    .forEach((line, index) => {
      descriptionLines[startIndexOfList + index] = line;
    });

  return descriptionLines.join(NEWLINE);
};