From 73eca2a95ef401a8e3061a14949ee1dbf34f99b9 Mon Sep 17 00:00:00 2001
From: Robert Speicher <rspeicher@gmail.com>
Date: Wed, 25 Nov 2015 16:26:15 -0500
Subject: [PATCH] Decouple Markdown previews from DropzoneInput

---
 .../javascripts/dropzone_input.js.coffee      | 80 +----------------
 .../javascripts/markdown_preview.js.coffee    | 87 +++++++++++++++++++
 app/views/projects/_md_preview.html.haml      |  2 +-
 3 files changed, 92 insertions(+), 77 deletions(-)
 create mode 100644 app/assets/javascripts/markdown_preview.js.coffee

diff --git a/app/assets/javascripts/dropzone_input.js.coffee b/app/assets/javascripts/dropzone_input.js.coffee
index 6f789e668af..30a35a04339 100644
--- a/app/assets/javascripts/dropzone_input.js.coffee
+++ b/app/assets/javascripts/dropzone_input.js.coffee
@@ -1,3 +1,5 @@
+#= require markdown_preview
+
 class @DropzoneInput
   constructor: (form) ->
     Dropzone.autoDiscover = false
@@ -11,17 +13,14 @@ class @DropzoneInput
     uploadProgress = $("<div class=\"div-dropzone-progress\"></div>")
     btnAlert = "<button type=\"button\"" + alertAttr + ">&times;</button>"
     project_uploads_path = window.project_uploads_path or null
-    markdown_preview_path = window.markdown_preview_path or null
     max_file_size = gon.max_file_size or 10
 
     form_textarea = $(form).find("textarea.markdown-area")
     form_textarea.wrap "<div class=\"div-dropzone\"></div>"
     form_textarea.on 'paste', (event) =>
       handlePaste(event)
-    form_textarea.on "input", ->
-      hideReferencedUsers()
-    form_textarea.on "blur", ->
-      renderMarkdown()
+
+    $(form).setupMarkdownPreview()
 
     form_dropzone = $(form).find('.div-dropzone')
     form_dropzone.parent().addClass "div-dropzone-wrapper"
@@ -34,42 +33,6 @@ class @DropzoneInput
       "opacity": 0
       "display": "none"
 
-    # Preview button
-    $(document).off "click", ".js-md-preview-button"
-    $(document).on "click", ".js-md-preview-button", (e) ->
-      ###
-      Shows the Markdown preview.
-
-      Lets the server render GFM into Html and displays it.
-      ###
-      e.preventDefault()
-      form = $(this).closest("form")
-      # toggle tabs
-      form.find(".js-md-write-button").parent().removeClass "active"
-      form.find(".js-md-preview-button").parent().addClass "active"
-
-      # toggle content
-      form.find(".md-write-holder").hide()
-      form.find(".md-preview-holder").show()
-
-      renderMarkdown()
-
-    # Write button
-    $(document).off "click", ".js-md-write-button"
-    $(document).on "click", ".js-md-write-button", (e) ->
-      ###
-      Shows the Markdown textarea.
-      ###
-      e.preventDefault()
-      form = $(this).closest("form")
-      # toggle tabs
-      form.find(".js-md-write-button").parent().addClass "active"
-      form.find(".js-md-preview-button").parent().removeClass "active"
-
-      # toggle content
-      form.find(".md-write-holder").show()
-      form.find(".md-preview-holder").hide()
-
     dropzone = form_dropzone.dropzone(
       url: project_uploads_path
       dictDefaultMessage: ""
@@ -136,41 +99,6 @@ class @DropzoneInput
 
     child = $(dropzone[0]).children("textarea")
 
-    hideReferencedUsers = ->
-      referencedUsers = form.find(".referenced-users")
-      referencedUsers.hide()
-
-    renderReferencedUsers = (users) ->
-      referencedUsers = form.find(".referenced-users")
-
-      if referencedUsers.length
-        if users.length >= 10
-          referencedUsers.show()
-          referencedUsers.find(".js-referenced-users-count").text users.length
-        else
-          referencedUsers.hide()
-
-    renderMarkdown = ->
-      preview = form.find(".js-md-preview")
-      mdText = form.find(".markdown-area").val()
-      if mdText.trim().length is 0
-        preview.text "Nothing to preview."
-        hideReferencedUsers()
-      else
-        preview.text "Loading..."
-        $.ajax(
-          type: "POST",
-          url: markdown_preview_path,
-          data: {
-            text: mdText
-          },
-          dataType: "json"
-        ).success (data) ->
-          preview.html data.body
-          preview.syntaxHighlight()
-
-          renderReferencedUsers data.references.users
-
     formatLink = (link) ->
       text = "[#{link.alt}](#{link.url})"
       text = "!#{text}" if link.is_image
diff --git a/app/assets/javascripts/markdown_preview.js.coffee b/app/assets/javascripts/markdown_preview.js.coffee
new file mode 100644
index 00000000000..98fc8f17340
--- /dev/null
+++ b/app/assets/javascripts/markdown_preview.js.coffee
@@ -0,0 +1,87 @@
+# MarkdownPreview
+#
+# Handles toggling the "Write" and "Preview" tab clicks, rendering the preview,
+# and showing a warning when more than `x` users are referenced.
+#
+class @MarkdownPreview
+  # Minimum number of users referenced before triggering a warning
+  referenceThreshold: 10
+
+  showPreview: (form) ->
+    preview = form.find('.js-md-preview')
+    mdText  = form.find('textarea.markdown-area').val()
+
+    if mdText.trim().length == 0
+      preview.text('Nothing to preview.')
+      @hideReferencedUsers(form)
+    else
+      preview.text('Loading...')
+      @renderMarkdown mdText, (response) =>
+        preview.html(response.body)
+        preview.syntaxHighlight()
+        @renderReferencedUsers(response.references.users, form)
+
+  renderMarkdown: (text, success) ->
+    return unless window.markdown_preview_path
+
+    $.ajax
+      type: 'POST'
+      url: window.markdown_preview_path
+      data: { text: text }
+      dataType: 'json'
+      success: success
+
+  hideReferencedUsers: (form) ->
+    referencedUsers = form.find('.referenced-users')
+    referencedUsers.hide()
+
+  renderReferencedUsers: (users, form) ->
+    referencedUsers = form.find('.referenced-users')
+
+    if referencedUsers.length
+      if users.length >= @referenceThreshold
+        referencedUsers.show()
+        referencedUsers.find('.js-referenced-users-count').text(users.length)
+      else
+        referencedUsers.hide()
+
+markdownPreview = new MarkdownPreview()
+
+previewButtonSelector = '.js-md-preview-button'
+writeButtonSelector   = '.js-md-write-button'
+
+$.fn.setupMarkdownPreview = ->
+  $form = $(this)
+
+  form_textarea = $form.find('textarea.markdown-area')
+
+  form_textarea.on 'input', -> markdownPreview.hideReferencedUsers($form)
+  form_textarea.on 'blur',  -> markdownPreview.showPreview($form)
+
+$(document).on 'click', previewButtonSelector, (e) ->
+  e.preventDefault()
+
+  $form = $(this).closest('form')
+
+  # toggle tabs
+  $form.find(writeButtonSelector).parent().removeClass('active')
+  $form.find(previewButtonSelector).parent().addClass('active')
+
+  # toggle content
+  $form.find('.md-write-holder').hide()
+  $form.find('.md-preview-holder').show()
+
+  markdownPreview.showPreview($form)
+
+$(document).on 'click', writeButtonSelector, (e) ->
+  e.preventDefault()
+
+  $form = $(this).closest('form')
+
+  # toggle tabs
+  $form.find(writeButtonSelector).parent().addClass('active')
+  $form.find(previewButtonSelector).parent().removeClass('active')
+
+  # toggle content
+  $form.find('.md-write-holder').show()
+  $form.find('.md-preview-holder').hide()
diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml
index 7b21095ea3e..8218cf11201 100644
--- a/app/views/projects/_md_preview.html.haml
+++ b/app/views/projects/_md_preview.html.haml
@@ -5,7 +5,7 @@
         %a.js-md-write-button(href="#md-write-holder" tabindex="-1")
           Write
       %li
-        %a.js-md-preview-button(href="md-preview-holder" tabindex="-1")
+        %a.js-md-preview-button(href="#md-preview-holder" tabindex="-1")
           Preview
 
     - if defined?(referenced_users) && referenced_users
-- 
GitLab