Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Prevent double article submission on v1 editor (#1791)
  • Loading branch information
aspittel authored and maestromac committed Feb 13, 2019
1 parent 81c889b commit 09c82fe
Showing 1 changed file with 68 additions and 70 deletions.
138 changes: 68 additions & 70 deletions app/views/articles/_markdown_form.html.erb
Expand Up @@ -2,37 +2,36 @@
<% if @article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>

<ul>
<% @article.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
<% @article.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<span id="error_explanation_anchor"></span>
<% if hiring_form?(@tag, @article) %>
<div class="job-listing-header">
<h5>< beta ❤️ ></h5>
<h1>The #Hiring Tag</h1>
<h3>Fill out this form to share your company's job opportunity.</h3>
</div>
<% end %>
<div class="container article markdown-editor" id="markdown-editor">
<% unless hiring_form?(@tag, @article) %>
<div class="top-buttons">
<button id="help-butt" class="editor-button help-butt">HELP</button>
<button id="markdownbutt" class="editor-button markdown-butt active">MARKDOWN</button>
<button id="previewbutt" class="editor-button">PREVIEW</button>
<button id="article-submit" class="editor-button submit">SAVE POST</button>
<h1>The #Hiring Tag</h1>
<h3>Fill out this form to share your company's job opportunity.</h3>
</div>
<% end %>
<div id="markdown-editor-main" class="editor-view">
<% if hiring_form?(@tag, @article) %>
<%= render 'articles/hiring_form', f:f %>
<% else %>
<% if current_user.organization %>
<div class="org-publish-check-wrapper" style="color:<%=current_user.organization.text_color_hex%>;background:<%=current_user.organization.bg_color_hex%>">
<div class="container article markdown-editor" id="markdown-editor">
<% unless hiring_form?(@tag, @article) %>
<div class="top-buttons">
<button id="help-butt" class="editor-button help-butt">HELP</button>
<button id="markdownbutt" class="editor-button markdown-butt active">MARKDOWN</button>
<button id="previewbutt" class="editor-button">PREVIEW</button>
<button id="article-submit" class="editor-button submit">SAVE POST</button>
</div>
<% end %>
<div id="markdown-editor-main" class="editor-view">
<% if hiring_form?(@tag, @article) %>
<%= render 'articles/hiring_form', f:f %>
<% else %>
<% if current_user.organization %>
<div class="org-publish-check-wrapper" style="color:<%=current_user.organization.text_color_hex%>;background:<%=current_user.organization.bg_color_hex%>">
Publish under the <%= current_user.organization.name %> organization?
<%= f.check_box :publish_under_org, {checked: @article.organization_id.present?} %>
</div>
Expand Down Expand Up @@ -109,54 +108,50 @@
<h3>
<a href="/<%= @user.username %>">
<img class="profile-pic" src="<%= cloudinary(@user.profile_image_url,50)%>" alt="<%= @user.username %> profile" />
By <%= @user.name %>
</a>
<% if @user.twitter_username.present? %>
<a href="https://twitter.com/<%= @user.twitter_username %>"><%= icon("twitter","20") %></a>
<% end %>
<% if @user.github_username.present? %>
<a href="https://github.com/<%= @user.github_username %>"><%= icon("github","20") %></a>
<% end %>
<span class="published-at"><%= "on "+@article.published_at.strftime("%B %d, %Y") if @article.published_at %></span>
</h3>
<div class="tags">
</div>
</div>
<div class="body" id="article_body" name="article[body]">
By <%= @user.name %>
</a>
<% if @user.twitter_username.present? %>
<a href="https://twitter.com/<%= @user.twitter_username %>"><%= icon("twitter","20") %></a>
<% end %>
<% if @user.github_username.present? %>
<a href="https://github.com/<%= @user.github_username %>"><%= icon("github","20") %></a>
<% end %>
<span class="published-at"><%= "on "+@article.published_at.strftime("%B %d, %Y") if @article.published_at %></span>
</h3>
<div class="tags">
</div>
<%= render "articles/about_author" %>
<% if current_user.organization %>
<%= render "articles/org_branding", organization: current_user.organization %>
<% end %>
</div>
<div class="body" id="article_body" name="article[body]">
</div>
<%= render "articles/about_author" %>
<% if current_user.organization %>
<%= render "articles/org_branding", organization: current_user.organization %>
<% end %>
</div>
</div>

<div id="editor-help" class="editor-view editor-article-view hidden">
<%= render "pages/editor_guide_text", version: "1" %>
</div>


<%= javascript_include_tag 'lib/js-yaml', async: true %>
<%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/postscribe/2.0.8/postscribe.min.js', async: true %>
<%= javascript_include_tag 'https://embed.runkit.com', async: true %>

<script>
var html,parsed;

function removeExistingErrorExplanation() {
var existingErrors = document.getElementById('error_explanation');
if (existingErrors) {
existingErrors.parentNode.removeChild(existingErrors);
}
}

function markdown() {
var articleContent = document.getElementById("article_body_markdown").value;
var cleanedArticleContent = cleanFrontMatterVariableNames(articleContent);
document.getElementById("article_body_markdown").value = cleanedArticleContent;
loadYamlFront(cleanedArticleContent);
}

function cleanFrontMatterVariableNames(rawText) {
var cleanedText = rawText;
var frontMatterVariableNames = [
Expand All @@ -177,7 +172,7 @@
})
return cleanedText;
}

function loadYamlFront(text) {
try {
parsed = jsyaml.loadFront(text);
Expand All @@ -191,24 +186,24 @@
}
// html = converter.makeHtml(parsed.__content);
}

function htmlEntities(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

function addQuotesToTitle(text) {
var correctedText = text;
correctedText = correctedText.replace(/title\:\s(.*)\n/m, function (match, p1) {
return "title: \"" + p1 + "\"\n"
})
return correctedText;
}

document.getElementById("previewbutt").onclick = function(e) {
e.preventDefault();
e.target.classList.add("loading");
markdown();

function successCb(response) {
removeExistingErrorExplanation();
document.getElementById("article_title").innerHTML = htmlEntities(filterXSS(response.title));
Expand All @@ -217,7 +212,7 @@
toggleOrgElements(document.getElementById('article_publish_under_org').checked);
<% end %>
activateButton(e.target,"article-preview");

if(!parsed.cover_image || parsed.cover_image.length < 0) {
document.getElementById("image_preview").className = ' hidden';
document.getElementById("blank_space").className = "blank-space";
Expand All @@ -234,7 +229,7 @@
<%= RunkitTag.special_script.html_safe %>
},150)
}

function errorCb(response) {
removeExistingErrorExplanation();
document.getElementById("previewbutt").className = "";
Expand All @@ -254,12 +249,12 @@
var referenceNode = document.getElementById("error_explanation_anchor");
referenceNode.parentNode.insertBefore(div, referenceNode.nextSibling);
}

var body = JSON.stringify({
utf8: "✓",
article_body: document.getElementById("article_body_markdown").value,
})

getCsrfToken()
.then(sendFetch("article-preview", body))
.then(function (response) {
Expand All @@ -273,7 +268,7 @@
errorCb(["It seems like something went wrong with your browser. Please copy your work and refresh the page."]);
});
}

function activateButton(button, viewID) {
var butts = document.getElementsByClassName("editor-button");
for(var i = 0; i < butts.length; i++) {
Expand All @@ -287,17 +282,17 @@
button.classList.add("active");
document.getElementById(viewID).classList.remove("hidden");
}

document.getElementById("help-butt").onclick = function(e){
e.preventDefault();
activateButton(e.target,"editor-help");
}

document.getElementById("markdownbutt").onclick = function(e){
e.preventDefault();
activateButton(e.target,"markdown-editor-main");
}

document.getElementById("article_body_markdown").onkeydown = function(e){
var ctl = document.getElementById('article_body_markdown');
var ctlvalue = ctl.value;
Expand All @@ -308,12 +303,12 @@
ctl.setSelectionRange(position+4, position+4);
}
}

document.getElementById('image-upload-button').onclick = function (e) {
e.preventDefault();
document.getElementById('image-upload').click();
}

document.getElementById('image-upload').onchange = function (e) {
var image = document.getElementById('image-upload').files;
if (image.length > 0) {
Expand All @@ -327,7 +322,7 @@
},50)
}
}

function uploadImageCb(response) {
var address = document.getElementById('uploaded-image');
address.value = response.link;
Expand All @@ -338,15 +333,15 @@
document.getElementById('image-upload-file-label').style.color = '#00c673';
document.getElementById('image-upload-submit').style.display = 'none';
}

function generateUploadFormdata(image) {
var token = document.querySelector("meta[name='csrf-token']").content;
var formData = new FormData();
formData.append('authenticity_token', token);
formData.append('image', image[0]);
return formData;
}

document.getElementById('image-upload-submit').onclick = function (e) {
e.preventDefault();
var image = document.getElementById('image-upload').files;
Expand All @@ -367,8 +362,11 @@
})
}
}


let alreadySubmitted = false;
document.getElementsByClassName("submit")[0].onclick = function (e) {
if (alreadySubmitted) return;
alreadySubmitted = true;
var butts = document.getElementsByClassName("editor-button");
for(var i = 0; i < butts.length; i++) {
butts[i].classList.add("disabled");
Expand All @@ -379,12 +377,12 @@
subButt.classList.add("loading");
markdown();
}

<% if current_user.organization %>
<% if current_user.organization %>
document.getElementById('article_publish_under_org').onclick = function(event){
toggleOrgElements(event.target.checked);
}

function toggleOrgElements(checkedState) {
var orgBrandAbout = document.getElementById('org-branding');
var orgBrandTitle = document.getElementById('org-branded-title');
Expand All @@ -396,7 +394,7 @@
orgBrandTitle.style.display = 'none';
}
}

<% end %>
<% end %>
// add event listener for clicking out of page
</script>

0 comments on commit 09c82fe

Please sign in to comment.