diff options
Diffstat (limited to 'app/assets/javascripts/diffs/store/utils.js')
-rw-r--r-- | app/assets/javascripts/diffs/store/utils.js | 97 |
1 files changed, 65 insertions, 32 deletions
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index 1839df12c96..c52da558be2 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -15,13 +15,23 @@ import { INLINE_DIFF_LINES_KEY, SHOW_WHITESPACE, NO_SHOW_WHITESPACE, + CONFLICT_OUR, + CONFLICT_THEIR, + CONFLICT_MARKER, + CONFLICT_MARKER_OUR, + CONFLICT_MARKER_THEIR, } from '../constants'; import { prepareRawDiffFile } from '../utils/diff_file'; -export const isAdded = line => ['new', 'new-nonewline'].includes(line.type); -export const isRemoved = line => ['old', 'old-nonewline'].includes(line.type); -export const isUnchanged = line => !line.type; -export const isMeta = line => ['match', 'new-nonewline', 'old-nonewline'].includes(line.type); +export const isAdded = (line) => ['new', 'new-nonewline'].includes(line.type); +export const isRemoved = (line) => ['old', 'old-nonewline'].includes(line.type); +export const isUnchanged = (line) => !line.type; +export const isMeta = (line) => ['match', 'new-nonewline', 'old-nonewline'].includes(line.type); +export const isConflictMarker = (line) => + [CONFLICT_MARKER_OUR, CONFLICT_MARKER_THEIR].includes(line.type); +export const isConflictSeperator = (line) => line.type === CONFLICT_MARKER; +export const isConflictOur = (line) => line.type === CONFLICT_OUR; +export const isConflictTheir = (line) => line.type === CONFLICT_THEIR; /** * Pass in the inline diff lines array which gets converted @@ -42,12 +52,22 @@ export const isMeta = line => ['match', 'new-nonewline', 'old-nonewline'].includ export const parallelizeDiffLines = (diffLines, inline) => { let freeRightIndex = null; + let conflictStartIndex = -1; const lines = []; + // `chunk` is used for dragging to select diff lines + // we are restricting commenting to only lines that appear between + // "expansion rows". Here equal chunks are lines grouped together + // inbetween expansion rows. + let chunk = 0; + for (let i = 0, diffLinesLength = diffLines.length, index = 0; i < diffLinesLength; i += 1) { const line = diffLines[i]; + line.chunk = chunk; + + if (isMeta(line)) chunk += 1; - if (isRemoved(line) || inline) { + if (isRemoved(line) || isConflictOur(line) || inline) { lines.push({ [LINE_POSITION_LEFT]: line, [LINE_POSITION_RIGHT]: null, @@ -58,7 +78,7 @@ export const parallelizeDiffLines = (diffLines, inline) => { freeRightIndex = index; } index += 1; - } else if (isAdded(line)) { + } else if (isAdded(line) || isConflictTheir(line)) { if (freeRightIndex !== null) { // If an old line came before this without a line on the right, this // line can be put to the right of it. @@ -77,15 +97,28 @@ export const parallelizeDiffLines = (diffLines, inline) => { freeRightIndex = null; index += 1; } - } else if (isMeta(line) || isUnchanged(line)) { - // line in the right panel is the same as in the left one - lines.push({ - [LINE_POSITION_LEFT]: line, - [LINE_POSITION_RIGHT]: line, - }); + } else if ( + isMeta(line) || + isUnchanged(line) || + isConflictMarker(line) || + (isConflictSeperator(line) && inline) + ) { + if (conflictStartIndex <= 0) { + // line in the right panel is the same as in the left one + lines.push({ + [LINE_POSITION_LEFT]: line, + [LINE_POSITION_RIGHT]: !inline && line, + }); - freeRightIndex = null; - index += 1; + if (!inline && isConflictMarker(line)) { + conflictStartIndex = index; + } + freeRightIndex = null; + index += 1; + } else { + lines[conflictStartIndex][LINE_POSITION_RIGHT] = line; + conflictStartIndex = -1; + } } } @@ -93,10 +126,10 @@ export const parallelizeDiffLines = (diffLines, inline) => { }; export function findDiffFile(files, match, matchKey = 'file_hash') { - return files.find(file => file[matchKey] === match); + return files.find((file) => file[matchKey] === match); } -export const getReversePosition = linePosition => { +export const getReversePosition = (linePosition) => { if (linePosition === LINE_POSITION_RIGHT) { return LINE_POSITION_LEFT; } @@ -173,7 +206,7 @@ export const findIndexInInlineLines = (lines, lineNumbers) => { const { oldLineNumber, newLineNumber } = lineNumbers; return lines.findIndex( - line => line.old_line === oldLineNumber && line.new_line === newLineNumber, + (line) => line.old_line === oldLineNumber && line.new_line === newLineNumber, ); }; @@ -346,7 +379,7 @@ export function prepareLineForRenamedFile({ line, diffFile, index = 0 }) { function prepareDiffFileLines(file) { const inlineLines = file[INLINE_DIFF_LINES_KEY]; - inlineLines.forEach(line => prepareLine(line, file)); // WARNING: In-Place Mutations! + inlineLines.forEach((line) => prepareLine(line, file)); // WARNING: In-Place Mutations! Object.assign(file, { inlineLinesCount: inlineLines.length, @@ -400,7 +433,7 @@ export function getDiffPositionByLineCode(diffFiles) { let lines = []; lines = diffFiles.reduce((acc, diffFile) => { - diffFile[INLINE_DIFF_LINES_KEY].forEach(line => { + diffFile[INLINE_DIFF_LINES_KEY].forEach((line) => { acc.push({ file: diffFile, line }); }); @@ -447,21 +480,21 @@ export function isDiscussionApplicableToLine({ discussion, diffPosition, latestD ...(discussion.positions || []), ]; - const removeLineRange = position => { + const removeLineRange = (position) => { const { line_range: pNotUsed, ...positionNoLineRange } = position; return positionNoLineRange; }; return discussionPositions .map(removeLineRange) - .some(position => isEqual(position, diffPositionCopy)); + .some((position) => isEqual(position, diffPositionCopy)); } // eslint-disable-next-line return latestDiff && discussion.active && line_code === discussion.line_code; } -export const getLowestSingleFolder = folder => { +export const getLowestSingleFolder = (folder) => { const getFolder = (blob, start = []) => blob.tree.reduce( (acc, file) => { @@ -493,8 +526,8 @@ export const getLowestSingleFolder = folder => { }; }; -export const flattenTree = tree => { - const flatten = blobTree => +export const flattenTree = (tree) => { + const flatten = (blobTree) => blobTree.reduce((acc, file) => { const blob = file; let treeToFlatten = blob.tree; @@ -516,7 +549,7 @@ export const flattenTree = tree => { return flatten(tree); }; -export const generateTreeList = files => { +export const generateTreeList = (files) => { const { treeEntries, tree } = files.reduce( (acc, file) => { const split = file.new_path.split('/'); @@ -566,8 +599,8 @@ export const generateTreeList = files => { return { treeEntries, tree: flattenTree(tree) }; }; -export const getDiffMode = diffFile => { - const diffModeKey = Object.keys(diffModes).find(key => diffFile[`${key}_file`]); +export const getDiffMode = (diffFile) => { + const diffModeKey = Object.keys(diffModes).find((key) => diffFile[`${key}_file`]); return ( diffModes[diffModeKey] || (diffFile.viewer && @@ -615,11 +648,11 @@ export const convertExpandLines = ({ return lines; }; -export const idleCallback = cb => requestIdleCallback(cb); +export const idleCallback = (cb) => requestIdleCallback(cb); function getLinesFromFileByLineCode(file, lineCode) { const inlineLines = file[INLINE_DIFF_LINES_KEY]; - const matchesCode = line => line.line_code === lineCode; + const matchesCode = (line) => line.line_code === lineCode; return inlineLines.filter(matchesCode); } @@ -628,15 +661,15 @@ export const updateLineInFile = (selectedFile, lineCode, updateFn) => { getLinesFromFileByLineCode(selectedFile, lineCode).forEach(updateFn); }; -export const allDiscussionWrappersExpanded = diff => { +export const allDiscussionWrappersExpanded = (diff) => { let discussionsExpanded = true; - const changeExpandedResult = line => { + const changeExpandedResult = (line) => { if (line && line.discussions.length) { discussionsExpanded = discussionsExpanded && line.discussionsExpanded; } }; - diff[INLINE_DIFF_LINES_KEY].forEach(line => { + diff[INLINE_DIFF_LINES_KEY].forEach((line) => { changeExpandedResult(line); }); |