summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/diff.js.es6
blob: 343285cebd1278b92f65cfc77c6e87ad09c9e0bf (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
/* eslint-disable */

((global) => {
  const UNFOLD_COUNT = 20;

  class Diff {
    constructor() {
      $('.files .diff-file').singleFileDiff();
      $('.files .diff-file').filesCommentButton();

      if (this.diffViewType() === 'parallel') {
        $('.content-wrapper .container-fluid').removeClass('container-limited');
      }

      $(document)
        .off('click', '.js-unfold, .diff-line-num a')
        .on('click', '.js-unfold', this.handleClickUnfold.bind(this))
        .on('click', '.diff-line-num a', this.handleClickLineNum.bind(this));

      this.highlighSelectedLine();
    }

    handleClickUnfold(event) {
      const $target = $(event.target);
      const [oldLineNumber, newLineNumber] = this.lineNumbers($target.parent());
      const offset = newLineNumber - oldLineNumber;
      const bottom = $target.hasClass('js-unfold-bottom');
      let since, 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 [prevOldLine, prevNewLine] = this.lineNumbers($target.parent().prev());
        if (since <= prevNewLine + 1) {
          since = prevNewLine + 1;
          unfold = false;
        }
      }

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

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

    handleClickLineNum(event) {
      const hash = $(event.currentTarget).attr('href');
      event.preventDefault();
      if (history.pushState) {
        history.pushState(null, null, hash);
      } else {
        window.location.hash = hash;
      }
      this.highlighSelectedLine();
    };

    diffViewType() {
      return $('.inline-parallel-buttons a.active').data('view-type');
    }

    lineNumbers(line) {
      if (!line.children().length) {
        return [0, 0];
      }

      return line.find('.diff-line-num').map(function() {
        return parseInt($(this).data('linenumber'));
      });
    }

    highlighSelectedLine() {
      const $diffFiles = $('.diff-file');
      $diffFiles.find('.hll').removeClass('hll');

      if (window.location.hash !== '') {
        const hash = window.location.hash.replace('#', '');
        $diffFiles
          .find(`tr#${hash}:not(.match) td, td#${hash}, td[data-line-code="${hash}"]`)
          .addClass('hll');
      }
    }
  }

  global.Diff = Diff;

})(window.gl || (window.gl = {}));