This repository has been archived by the owner on Apr 5, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vanilla Staticman JS & HTML reorganization (#245)
* vanilla staticman.js & <article> 4 cmt * try fixing JSON structure * fixed threadID in data attrib * xhrObj.options.reCaptcha initiated only once
- Loading branch information
1 parent
9bd8ab8
commit d8c65c2
Showing
3 changed files
with
154 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,122 @@ | ||
// Static comments | ||
// from: /~https://github.com/eduardoboucas/popcorn/blob/gh-pages/js/main.js | ||
$(document).ready(function() { | ||
$('.new-comment').submit(function () { | ||
var form = this; | ||
(function() { | ||
let form = document.querySelector('.new-comment'); | ||
if (form) { | ||
form.addEventListener('submit', function () { | ||
form.classList.add('loading'); | ||
form.querySelector('input[type="submit"]:enabled').classList.add('hidden'); // hide "submit" | ||
form.querySelector('input[type="submit"]:disabled').classList.remove('hidden'); // show "submitted" | ||
|
||
$(form).addClass('loading'); | ||
$('input[type="submit"]:enabled').addClass('hidden'); // hide "submit" | ||
$('input[type="submit"]:disabled').removeClass('hidden'); // show "submitted" | ||
// Construct form action URL form JS to avoid spam | ||
let api = '{{ .api }}'; | ||
let gitProvider = '{{ .gitprovider }}'; | ||
let username = '{{ .username }}'; | ||
let repo = '{{ .repo }}'; | ||
let branch = '{{ .branch }}'; | ||
let url = ['https:/', api, 'v3/entry', gitProvider, username, repo, branch, 'comments'].join('/'); | ||
|
||
// Construct form action URL form JS to avoid spam | ||
var api = '{{ .api }}'; | ||
var gitProvider = '{{ .gitprovider }}'; | ||
var username = '{{ .username }}'; | ||
var repo = '{{ .repo }}'; | ||
var branch = '{{ .branch }}'; | ||
// Convert form fields to a JSON-friendly string | ||
let formObj = Object.fromEntries(new FormData(form)); | ||
let xhrObj = {fields: {}, options: {}}; | ||
Object.entries(formObj).forEach(([key, value]) => { | ||
let a = key.indexOf('['), b = key.indexOf('reCaptcha'); | ||
if (a == -1) { // key = "g-recaptcha-response" | ||
xhrObj[key] = value; | ||
} else if (a == 6 || (a == 7 && b == -1)) { // key = "fields[*]", "options[*]" | ||
xhrObj[key.slice(0, a)][key.slice(a + 1, -1)] = value; | ||
} else { // key = "options[reCaptcha][*]" | ||
// define xhrObj.options.reCaptcha if it doesn't exist | ||
xhrObj.options.reCaptcha = xhrObj.options.reCaptcha || {}; | ||
xhrObj.options.reCaptcha[key.slice(b + 11, -1)] = value; | ||
} | ||
}); | ||
let formData = JSON.stringify(xhrObj); // some API don't accept FormData objects | ||
|
||
$.ajax({ | ||
type: $(this).attr('method'), | ||
url: ['https:/', api, 'v3/entry', gitProvider, username, repo, branch, 'comments'].join('/'), | ||
data: $(this).serialize(), | ||
contentType: 'application/x-www-form-urlencoded', | ||
success: function (data) { | ||
showAlert('success'); | ||
setTimeout(function(){ clearForm() }, 3000); // display success message for 3s | ||
$(form).removeClass('loading'); | ||
}, | ||
error: function (err) { | ||
console.log(err); | ||
showAlert('failed'); | ||
$(form).removeClass('loading'); | ||
} | ||
|
||
let xhr = new XMLHttpRequest(); | ||
xhr.open('POST', url); | ||
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); | ||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); | ||
xhr.onreadystatechange = function () { | ||
if (xhr.readyState === XMLHttpRequest.DONE) { | ||
let status = xhr.status; | ||
if (status >= 200 && status < 400) { | ||
formSubmitted(); | ||
} else { | ||
formError(err); | ||
} | ||
} | ||
}; | ||
xhr.send(formData); | ||
|
||
return false; | ||
}); | ||
|
||
return false; | ||
}); | ||
function formSubmitted() { | ||
showAlert('success'); | ||
setTimeout(function(){ clearForm() }, 3000); // display success message for 3s | ||
form.classList.remove('loading'); | ||
} | ||
|
||
function showAlert(msg) { | ||
if (msg == 'success') { | ||
$('.submit-notice').addClass('submit-success') | ||
$('.new-comment .submit-success').removeClass('hidden'); // show submit success message | ||
$('.new-comment .submit-failed').addClass('hidden'); // hide submit failed message | ||
} else { | ||
$('.submit-notice').addClass('submit-failed') | ||
$('.new-comment .submit-success').addClass('hidden'); // hide submit success message | ||
$('.new-comment .submit-failed').removeClass('hidden'); // show submit failed message | ||
function formError(err) { | ||
console.log(err); | ||
showAlert('failed'); | ||
form.classList.remove('loading'); | ||
} | ||
$('input[type="submit"]:enabled').removeClass('hidden'); // show "submit" | ||
$('input[type="submit"]:disabled').addClass('hidden'); // hide "submitted" | ||
} | ||
|
||
function clearForm() { | ||
resetReplyTarget(); | ||
$('.new-comment input') | ||
.filter(function() { | ||
return this.name.match(/^fields\[.*\]$/); | ||
}) | ||
.val(''); // empty all text & hidden fields but not options | ||
$('.new-comment textarea').val(''); // empty text area | ||
$('.submit-notice').removeClass('.submit-success').removeClass('.submit-failed'); | ||
$('.new-comment .submit-success').addClass('hidden'); // hide submission status | ||
$('.new-comment .submit-failed').addClass('hidden'); // hide submission status | ||
} | ||
function showAlert(msg) { | ||
if (msg == 'success') { | ||
form.querySelector('.submit-notice').classList.add('submit-success') | ||
form.querySelector('.submit-success').classList.remove('hidden'); // show submit success message | ||
form.querySelector('.submit-failed').classList.add('hidden'); // hide submit failed message | ||
} else { | ||
form.querySelector('.submit-notice').classList.add('submit-failed') | ||
form.querySelector('.submit-success').classList.add('hidden'); // hide submit success message | ||
form.querySelector('.submit-failed').classList.remove('hidden'); // show submit failed message | ||
} | ||
form.querySelector('input[type="submit"]:enabled').classList.remove('hidden'); // show "submit" | ||
form.querySelector('input[type="submit"]:disabled').classList.add('hidden'); // hide "submitted" | ||
} | ||
|
||
function resetReplyTarget() { | ||
$('.new-comment .reply-notice .reply-name').text(''); | ||
$('.new-comment .reply-notice .comment-avatar').remove(); | ||
$('.new-comment .reply-notice .reply-close-btn').remove(); | ||
$('.new-comment .reply-notice').addClass('hidden'); // hide reply target display | ||
$('.new-comment input[type="hidden"]') | ||
.filter(function() { | ||
return this.name.match(/^fields\[reply[a-zA-Z]*\]$/); | ||
}) | ||
.val(''); // empty all hidden fields whose name starts from "reply" | ||
} | ||
// empty all text & hidden fields but not options | ||
function clearForm() { | ||
resetReplyTarget(); | ||
form.querySelector('.submit-notice').classList.remove('.submit-success'); // IE10 compatibility | ||
form.querySelector('.submit-notice').classList.remove('.submit-failed'); | ||
form.querySelector('.submit-success').classList.add('hidden'); // hide submission status | ||
form.querySelector('.submit-failed').classList.add('hidden'); // hide submission status | ||
} | ||
|
||
// record reply target when "reply to this comment" is pressed | ||
$('.comment').on('click', '.comment-reply-btn', function (evt){ | ||
resetReplyTarget(); | ||
var cmt = $(evt.delegateTarget); | ||
var replyThread = cmt.find('.comment-threadID').text(); | ||
$('.new-comment input[name="fields[replyThread]"]').val(replyThread); | ||
$('.new-comment input[name="fields[replyID]"]').val(cmt.attr("id")); | ||
authorTag = cmt.find('.comment-author'); | ||
replyName = authorTag.text(); | ||
$('.new-comment input[name="fields[replyName]"]').val(replyName); | ||
function resetReplyTarget() { | ||
form.querySelector('.reply-notice .reply-name').innerText = ''; | ||
form.querySelector('.reply-notice').classList.add('hidden'); // hide reply target display | ||
// empty all hidden fields whose name starts from "reply" | ||
Array.from(form.elements).filter(e => e.name.indexOf('fields[reply') === 0).forEach(e => e.value = ''); | ||
} | ||
|
||
// display reply target avatar and name | ||
$('.new-comment .reply-notice').removeClass('hidden'); | ||
$('.new-comment .reply-name').text(replyName); | ||
avatarTag = cmt.find('.comment-avatar'); | ||
// use clone to avoid removal of avatar in comments by resetReplyTarget() | ||
$('.new-comment .reply-arrow').after(avatarTag.clone()); | ||
// add button for removing reply target (static method would give error msg) | ||
closeBtn = $("<a class='reply-close-btn button'><i class='fas fa-times'></i></a>"); | ||
$('.new-comment .reply-notice').append(closeBtn); | ||
}); | ||
// record reply target when one of the "reply" buttons is pressed | ||
document.querySelector('.comments-container').addEventListener('click', function (evt) { | ||
let target = evt.target; | ||
if (target.matches('.comment-reply-btn')){ | ||
resetReplyTarget(); | ||
let cmt = target; | ||
while (!cmt.matches('.comment')) { // find the comment containing the clicked "reply" button | ||
cmt = cmt.parentNode; | ||
} | ||
form.querySelector('input[name="fields[replyThread]"]').value = cmt.dataset.replyThread; | ||
form.querySelector('input[name="fields[replyID]"]').value = cmt.getAttribute('id'); | ||
let replyName = cmt.querySelector('.comment-author').innerText | ||
form.querySelector('input[name="fields[replyName]"]').value = replyName; | ||
|
||
// handle removal of reply target when '×' is pressed | ||
$('.new-comment .reply-notice').on('click', '.reply-close-btn', function(){ | ||
resetReplyTarget(); | ||
}); | ||
// display reply name | ||
form.querySelector('.reply-notice').classList.remove('hidden'); | ||
form.querySelector('.reply-name').innerText = replyName; | ||
} | ||
}); | ||
|
||
// handle removal of reply target when '×' is pressed | ||
form.querySelector('.reply-close-btn').addEventListener('click', resetReplyTarget); | ||
|
||
// clear form when reset button is clicked | ||
$('.new-comment input[type="reset"]').click(function (){ | ||
clearForm(); | ||
}); | ||
}); | ||
// clear form when reset button is clicked | ||
form.querySelector('input[type="reset"]').addEventListener('click', clearForm); | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters