BigW Consortium Gitlab

diff.js 4.37 KB
Newer Older
1
import { getLocationHash } from './lib/utils/url_utility';
2
import FilesCommentButton from './files_comment_button';
3
import SingleFileDiff from './single_file_diff';
4
import imageDiffHelper from './image_diff/helpers/index';
5

6 7
const UNFOLD_COUNT = 20;
let isBound = false;
Fatih Acet committed
8

9
export default class Diff {
10 11
  constructor() {
    const $diffFile = $('.files .diff-file');
12

13 14 15 16 17
    $diffFile.each((index, file) => {
      if (!$.data(file, 'singleFileDiff')) {
        $.data(file, 'singleFileDiff', new SingleFileDiff(file));
      }
    });
18

19
    const tab = document.getElementById('diffs');
20
    if (!tab || (tab && tab.dataset && tab.dataset.isLocked !== '')) FilesCommentButton.init($diffFile);
21

22 23 24
    const firstFile = $('.files').first().get(0);
    const canCreateNote = firstFile && firstFile.hasAttribute('data-can-create-note');
    $diffFile.each((index, file) => imageDiffHelper.initImageDiff(file, canCreateNote));
25

26 27 28
    if (!isBound) {
      $(document)
        .on('click', '.js-unfold', this.handleClickUnfold.bind(this))
29 30
        .on('click', '.diff-line-num a', this.handleClickLineNum.bind(this))
        .on('mousedown', 'td.line_content.parallel', this.handleParallelLineDown.bind(this));
31 32
      isBound = true;
    }
33

34
    if (getLocationHash()) {
35
      this.highlightSelectedLine();
Fatih Acet committed
36 37
    }

38 39 40 41 42
    this.openAnchoredDiff();
  }

  handleClickUnfold(e) {
    const $target = $(e.target);
43
    const [oldLineNumber, newLineNumber] = this.lineNumbers($target.parent());
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    const offset = newLineNumber - oldLineNumber;
    const bottom = $target.hasClass('js-unfold-bottom');
    let since;
    let to;
    let unfold = true;

    if (bottom) {
      const lineNumber = newLineNumber + 1;
      since = lineNumber;
      to = lineNumber + UNFOLD_COUNT;
    } else {
      const lineNumber = newLineNumber - 1;
      since = lineNumber - UNFOLD_COUNT;
      to = lineNumber;

      // make sure we aren't loading more than we need
      const prevNewLine = this.lineNumbers($target.parent().prev())[1];
      if (since <= prevNewLine + 1) {
        since = prevNewLine + 1;
        unfold = false;
64
      }
65
    }
66

67 68 69
    const file = $target.parents('.diff-file');
    const link = file.data('blob-diff-path');
    const view = file.data('view');
70

71 72 73
    const params = { since, to, bottom, offset, unfold, view };
    $.get(link, params, response => $target.parent().replaceWith(response));
  }
74

75
  openAnchoredDiff(cb) {
76
    const locationHash = getLocationHash();
77
    const anchoredDiff = locationHash && locationHash.split('_')[0];
78

79 80 81 82 83 84 85 86 87 88 89 90 91
    if (!anchoredDiff) return;

    const diffTitle = $(`#${anchoredDiff}`);
    const diffFile = diffTitle.closest('.diff-file');
    const nothingHereBlock = $('.nothing-here-block:visible', diffFile);
    if (nothingHereBlock.length) {
      const clickTarget = $('.js-file-title, .click-to-expand', diffFile);
      diffFile.data('singleFileDiff').toggleDiff(clickTarget, () => {
        this.highlightSelectedLine();
        if (cb) cb();
      });
    } else if (cb) {
      cb();
92
    }
93
  }
94

95 96 97 98 99 100 101
  handleClickLineNum(e) {
    const hash = $(e.currentTarget).attr('href');
    e.preventDefault();
    if (window.history.pushState) {
      window.history.pushState(null, null, hash);
    } else {
      window.location.hash = hash;
102
    }
103 104
    this.highlightSelectedLine();
  }
105
  // eslint-disable-next-line class-methods-use-this
106 107 108 109 110 111 112 113 114 115 116
  handleParallelLineDown(e) {
    const line = $(e.currentTarget);
    const table = line.closest('table');

    table.removeClass('left-side-selected right-side-selected');

    const lineClass = ['left-side', 'right-side'].filter(name => line.hasClass(name))[0];
    if (lineClass) {
      table.addClass(`${lineClass}-selected`);
    }
  }
117
  // eslint-disable-next-line class-methods-use-this
118 119 120
  diffViewType() {
    return $('.inline-parallel-buttons a.active').data('view-type');
  }
121
  // eslint-disable-next-line class-methods-use-this
122
  lineNumbers(line) {
123 124
    const children = line.find('.diff-line-num').toArray();
    if (children.length !== 2) {
125
      return [0, 0];
126
    }
127
    return children.map(elm => parseInt($(elm).data('linenumber'), 10) || 0);
128
  }
129
  // eslint-disable-next-line class-methods-use-this
130
  highlightSelectedLine() {
131
    const hash = getLocationHash();
132 133
    const $diffFiles = $('.diff-file');
    $diffFiles.find('.hll').removeClass('hll');
134

135 136 137 138
    if (hash) {
      $diffFiles
        .find(`tr#${hash}:not(.match) td, td#${hash}, td[data-line-code="${hash}"]`)
        .addClass('hll');
139 140
    }
  }
141
}