// ==UserScript==
// @name MefiReply
// @namespace https://github.com/emanuelfeld
// @version 0.2
// @description Adds anchor to quote-reply and link back to original comments. Select the text you want quoted or just click 'reply' to include everything.
// @author Emanuel Feld
// @include http://*.metafilter.com/*
// @include https://*.metafilter.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
let loggedInModern = document.getElementsByClassName('profile').length > 0;
let loggedInClassic = document.getElementById('navoften') !== null;
let replyArea = document.getElementById('comment');
// run only if logged in and thread not archived
if ((loggedInModern || loggedInClassic) && replyArea) {
run();
}
function run () {
let pageLocation = location.protocol + '//' + location.host + location.pathname;
let host = location.host;
if (host.indexOf('www.') === 0) {
host = host.slice(4);
}
let site = host.split('.')[0];
appendReplyLinks(site, pageLocation);
// monitor for new comments
let observer = new MutationObserver(function(mutations) {
mutations.forEach(function (mutationRecord) {
let newDiv = document.getElementById('newcommentsmsg');
if (newDiv.style.display === 'none') {
appendReplyLinks(site, pageLocation);
}
});
});
let target = document.getElementById('newcommentsmsg');
observer.observe(target, { attributes : true, attributeFilter : ['style'] });
}
// check if element actually is a post comment
function isComment (element, site) {
return (['metafilter', 'projects', 'music', 'irl', 'metatalk'].indexOf(site) > -1 &&
element.id === '' &&
element.querySelector('.whitesmallcopy') === null) ||
(['ask', 'fanfare'].indexOf(site) > -1 && element.id.indexOf('c') === 0);
}
// add a reply link to each comment
function appendReplyLinks (site, pageLocation) {
let comments = document.querySelectorAll('div.comments');
for (let i = 0; i < comments.length; i++) {
if (isComment(comments[i], site)) {
let commentMetaLinks = comments[i].querySelectorAll('.smallcopy > a');
let commentUsername = commentMetaLinks[0].textContent;
let commentAnchor = commentMetaLinks[1].href;
// skip a link if replying to mod
if (commentMetaLinks[1].href.indexOf('faq.metafilter.com') > -1) {
commentAnchor = commentMetaLinks[2].href;
}
let commentId = commentAnchor.split('#')[1];
if (document.getElementById('mefiReply' + commentId) === null) {
let replySpan = document.createElement('span');
replySpan.id = 'reply' + commentAnchor.split('#')[1];
replySpan.innerHTML = '[]';
replySpan.querySelector('a').addEventListener ('click', function () {
addReply(commentUsername, commentId, commentAnchor);
}, false);
comments[i].querySelector('.smallcopy').appendChild(replySpan);
}
}
}
}
// return the selected text if any, otherwise null
function getSelectedText () {
let selection = window.getSelection();
let selectedText = selection.toString().trim();
if (selectedText.length && selection.isCollapsed === false) {
return selectedText;
} else {
return null;
}
}
// add text to comment box
function addReply (username, id, anchor) {
let quoteText;
try {
quoteText = document.getElementById('c' + id).textContent;
} catch (e) {
quoteText = document.querySelector('[name="' + id + '"]')
.nextElementSibling.textContent;
}
quoteText = quoteText.split('posted by').slice(0, -1).join().trim();
let selectedText = getSelectedText();
// quote selected text instead if it's in full comment
if (selectedText && quoteText.indexOf(selectedText) > -1) {
quoteText = selectedText;
}
let replyText = '> ' + username + ':\r\n"' + quoteText + '"\r\n\r\n';
let replyArea = document.getElementById('comment');
replyArea.value = replyArea.value.trim();
if (replyArea.value.length !== 0) {
replyArea.value += '\r\n\r\n' + replyText;
} else {
replyArea.value = replyText;
}
}
})();