BigW Consortium Gitlab

preview_markdown.js 5.93 KB
Newer Older
1
/* eslint-disable func-names, no-var, object-shorthand, comma-dangle, prefer-arrow-callback */
2

3 4
// MarkdownPreview
//
5
// Handles toggling the "Write" and "Preview" tab clicks, rendering the preview
6
// (including the explanation of quick actions), and showing a warning when
7
// more than `x` users are referenced.
8
//
Mike Greiling committed
9
(function () {
10
  var lastTextareaPreviewed;
11
  var lastTextareaHeight = null;
12 13 14
  var markdownPreview;
  var previewButtonSelector;
  var writeButtonSelector;
Fatih Acet committed
15

Mike Greiling committed
16
  window.MarkdownPreview = (function () {
Fatih Acet committed
17 18
    function MarkdownPreview() {}

19
    // Minimum number of users referenced before triggering a warning
Fatih Acet committed
20
    MarkdownPreview.prototype.referenceThreshold = 10;
21
    MarkdownPreview.prototype.emptyMessage = 'Nothing to preview.';
Fatih Acet committed
22 23 24

    MarkdownPreview.prototype.ajaxCache = {};

Mike Greiling committed
25
    MarkdownPreview.prototype.showPreview = function ($form) {
26
      var mdText;
27
      var preview = $form.find('.js-md-preview');
28
      var url = preview.data('url');
29 30 31 32 33
      if (preview.hasClass('md-preview-loading')) {
        return;
      }
      mdText = $form.find('textarea.markdown-area').val();

Fatih Acet committed
34
      if (mdText.trim().length === 0) {
35
        preview.text(this.emptyMessage);
36
        this.hideReferencedUsers($form);
37
      } else {
38
        preview.addClass('md-preview-loading').text('Loading...');
39 40 41 42 43 44 45 46 47
        this.fetchMarkdownPreview(mdText, url, (function (response) {
          var body;
          if (response.body.length > 0) {
            body = response.body;
          } else {
            body = this.emptyMessage;
          }

          preview.removeClass('md-preview-loading').html(body);
48
          preview.renderGFM();
49
          this.renderReferencedUsers(response.references.users, $form);
50 51 52 53

          if (response.references.commands) {
            this.renderReferencedCommands(response.references.commands, $form);
          }
54
        }).bind(this));
Fatih Acet committed
55 56 57
      }
    };

58 59
    MarkdownPreview.prototype.fetchMarkdownPreview = function (text, url, success) {
      if (!url) {
Fatih Acet committed
60 61 62
        return;
      }
      if (text === this.ajaxCache.text) {
63 64
        success(this.ajaxCache.response);
        return;
Fatih Acet committed
65
      }
66
      $.ajax({
Fatih Acet committed
67
        type: 'POST',
68
        url: url,
Fatih Acet committed
69 70 71 72
        data: {
          text: text
        },
        dataType: 'json',
Mike Greiling committed
73
        success: (function (response) {
74 75 76
          this.ajaxCache = {
            text: text,
            response: response
Fatih Acet committed
77
          };
78 79
          success(response);
        }).bind(this)
Fatih Acet committed
80 81 82
      });
    };

Mike Greiling committed
83
    MarkdownPreview.prototype.hideReferencedUsers = function ($form) {
84
      $form.find('.referenced-users').hide();
Fatih Acet committed
85 86
    };

Mike Greiling committed
87
    MarkdownPreview.prototype.renderReferencedUsers = function (users, $form) {
Fatih Acet committed
88
      var referencedUsers;
89
      referencedUsers = $form.find('.referenced-users');
Fatih Acet committed
90 91 92
      if (referencedUsers.length) {
        if (users.length >= this.referenceThreshold) {
          referencedUsers.show();
93
          referencedUsers.find('.js-referenced-users-count').text(users.length);
Fatih Acet committed
94
        } else {
95
          referencedUsers.hide();
Fatih Acet committed
96 97 98 99
        }
      }
    };

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
    MarkdownPreview.prototype.hideReferencedCommands = function ($form) {
      $form.find('.referenced-commands').hide();
    };

    MarkdownPreview.prototype.renderReferencedCommands = function (commands, $form) {
      var referencedCommands;
      referencedCommands = $form.find('.referenced-commands');
      if (commands.length > 0) {
        referencedCommands.html(commands);
        referencedCommands.show();
      } else {
        referencedCommands.html('');
        referencedCommands.hide();
      }
    };

Fatih Acet committed
116
    return MarkdownPreview;
Mike Greiling committed
117
  }());
Fatih Acet committed
118

119
  markdownPreview = new window.MarkdownPreview();
Fatih Acet committed
120 121 122 123 124 125 126

  previewButtonSelector = '.js-md-preview-button';

  writeButtonSelector = '.js-md-write-button';

  lastTextareaPreviewed = null;

Mike Greiling committed
127
  $.fn.setupMarkdownPreview = function () {
128
    var $form = $(this);
129 130 131
    $form.find('textarea.markdown-area').on('input', function () {
      markdownPreview.hideReferencedUsers($form);
    });
Fatih Acet committed
132 133
  };

Mike Greiling committed
134
  $(document).on('markdown-preview:show', function (e, $form) {
Fatih Acet committed
135 136 137
    if (!$form) {
      return;
    }
138

Fatih Acet committed
139
    lastTextareaPreviewed = $form.find('textarea.markdown-area');
140 141
    lastTextareaHeight = lastTextareaPreviewed.height();

142
    // toggle tabs
Fatih Acet committed
143 144
    $form.find(writeButtonSelector).parent().removeClass('active');
    $form.find(previewButtonSelector).parent().addClass('active');
145

146
    // toggle content
Fatih Acet committed
147 148
    $form.find('.md-write-holder').hide();
    $form.find('.md-preview-holder').show();
149
    markdownPreview.showPreview($form);
Fatih Acet committed
150 151
  });

Mike Greiling committed
152
  $(document).on('markdown-preview:hide', function (e, $form) {
Fatih Acet committed
153 154 155 156
    if (!$form) {
      return;
    }
    lastTextareaPreviewed = null;
157 158 159 160 161

    if (lastTextareaHeight) {
      $form.find('textarea.markdown-area').height(lastTextareaHeight);
    }

162
    // toggle tabs
Fatih Acet committed
163 164
    $form.find(writeButtonSelector).parent().addClass('active');
    $form.find(previewButtonSelector).parent().removeClass('active');
165

166
    // toggle content
Fatih Acet committed
167 168
    $form.find('.md-write-holder').show();
    $form.find('textarea.markdown-area').focus();
169
    $form.find('.md-preview-holder').hide();
170 171

    markdownPreview.hideReferencedCommands($form);
Fatih Acet committed
172 173
  });

Mike Greiling committed
174
  $(document).on('markdown-preview:toggle', function (e, keyboardEvent) {
Fatih Acet committed
175 176 177 178
    var $target;
    $target = $(keyboardEvent.target);
    if ($target.is('textarea.markdown-area')) {
      $(document).triggerHandler('markdown-preview:show', [$target.closest('form')]);
179
      keyboardEvent.preventDefault();
Fatih Acet committed
180 181 182
    } else if (lastTextareaPreviewed) {
      $target = lastTextareaPreviewed;
      $(document).triggerHandler('markdown-preview:hide', [$target.closest('form')]);
183
      keyboardEvent.preventDefault();
Fatih Acet committed
184 185 186
    }
  });

Mike Greiling committed
187
  $(document).on('click', previewButtonSelector, function (e) {
Fatih Acet committed
188 189 190
    var $form;
    e.preventDefault();
    $form = $(this).closest('form');
191
    $(document).triggerHandler('markdown-preview:show', [$form]);
Fatih Acet committed
192 193
  });

Mike Greiling committed
194
  $(document).on('click', writeButtonSelector, function (e) {
Fatih Acet committed
195 196 197
    var $form;
    e.preventDefault();
    $form = $(this).closest('form');
198
    $(document).triggerHandler('markdown-preview:hide', [$form]);
Fatih Acet committed
199
  });
200
}());