Skip to content

Instantly share code, notes, and snippets.

@johnmave126
Last active June 12, 2016 04:46
Show Gist options
  • Save johnmave126/3287b8d85a071b672344614432f97464 to your computer and use it in GitHub Desktop.
Save johnmave126/3287b8d85a071b672344614432f97464 to your computer and use it in GitHub Desktop.
Add floor and quote to MSSSUG comment system. To install this script, install Tampermonkey first and goto https://gist.github.com/raw/3287b8d85a071b672344614432f97464/better_msssug.user.js
// ==UserScript==
// @name MSSSUG better comments
// @namespace http://youmu.moe/
// @version 0.7
// @description Add floor and quote to MSSSUG comment system
// @author John Tan (johnmave126@gmail.com)
// @match *://ihome.ust.hk/~msssug/*
// @updateURL https://gist.github.com/raw/3287b8d85a071b672344614432f97464/better_msssug.meta.js
// @downloadURL https://gist.github.com/raw/3287b8d85a071b672344614432f97464/better_msssug.user.js
// @grant none
// ==/UserScript==
// ==UserScript==
// @name MSSSUG better comments
// @namespace http://youmu.moe/
// @version 0.7
// @description Add floor and quote to MSSSUG comment system
// @author John Tan (johnmave126@gmail.com)
// @match *://ihome.ust.hk/~msssug/*
// @updateURL https://gist.github.com/raw/3287b8d85a071b672344614432f97464/better_msssug.meta.js
// @downloadURL https://gist.github.com/raw/3287b8d85a071b672344614432f97464/better_msssug.user.js
// @grant none
// ==/UserScript==
/**
* Disclaimer: I didn't do any styling since MSSSUG website itself is ugly. But I did add proper class to each element, so customization
* via stylish (https://chrome.google.com/webstore/detail/stylish/fjnbnpbmkenffdnngjfgmeleoegfcffe?hl=en) is possible. Since I am graduating,
* I will not maintain this script on regular basis, which means if some day a smart/dumb IT secretary emerges and modifies/rewrites the
* website, this script may potentially break the website, and such bug may not be fixed in time. I will not take responsiblity of any
* consequences using this script. Hence, fork is very welcomed. To make life easier, I HEREBY DECLARE THAT THIS SCRIPT IS IN PUBLIC
* DOMAIN.
* John Tan (johnmave126@gmail.com) 2016
*/
/**
* Credits:
* Thank logchan (lg@logu.co) for testing!
*/
(function() {
'use strict';
var comments = [];
/**
* Detect whether user has login
*/
function isLogin() {
return document.body.querySelector('a.nav_item[href="/~msssug/login"]') === null;
}
/**
* Handle reply button click
*/
function genReplyHandler(elem, idx) {
elem.addEventListener('click', function() {
var replyContainer = document.body.querySelector('form[method="post"] iframe');
if(!replyContainer) {
return true;
}
/* Remove all previous reference */
var doc = replyContainer.contentDocument;
var boxList = doc.body.querySelectorAll('body > .x-replybox');
for(var i = 0; i < boxList.length; i++) {
doc.body.removeChild(boxList);
}
var replyBox = doc.createElement('span');
var replyHeading = doc.createElement('span');
replyHeading.appendChild(doc.createTextNode(comments[idx-1].author + '在'));
var jumpLink = doc.createElement('a');
jumpLink.href = '#L' + idx;
jumpLink.innerText = '#' + idx;
replyHeading.appendChild(jumpLink);
replyHeading.appendChild(doc.createTextNode('写道:'));
replyHeading.classList.add('x-replybox-heading');
replyHeading.style.display = 'block';
replyHeading.style.fontWeight = 'bold';
replyBox.appendChild(replyHeading);
var replyContent = doc.createElement('span');
replyContent.innerHTML = comments[idx-1].content.replace('\n', ' ');
replyContent.classList.add('x-replybox-content');
replyContent.style.padding = '2px 8px';
replyBox.appendChild(replyContent);
replyBox.classList.add('x-replybox');
replyBox.style.display = 'block';
replyBox.style.width = '50%';
replyBox.style.border = '1px solid #000';
replyBox.style.padding = '5px';
replyBox.style.marginBottom = '8px';
replyBox.setAttribute('contenteditable', 'false');
doc.body.insertBefore(replyBox, doc.body.firstChild);
if(replyBox.nextSibling === null) {
var emptyElem = document.createElement('p');
emptyElem.style.minWidth='1px';
emptyElem.style.minHeight='1px';
emptyElem.style.margin='0';
emptyElem.innerText = ' ';
doc.body.appendChild(emptyElem);
}
document.body.scrollTop = document.body.scrollHeight;
});
}
/**
* Generate a comment
*/
function genComment(authorLine, content, logined, floor) {
var comment = {};
var wrapper = document.createElement('div');
/* Generate heading */
var commentHeading = document.createElement('div');
/* Floor: Name @ Time */
var authorInfo = document.createElement('div');
var floorNumber = document.createTextNode(floor + '楼: ');
if(authorLine.data.match(/[a-zA-Z_]+|匿名/))
comment.author = authorLine.data.match(/[a-zA-Z_]+|匿名/)[0] || '';
else
comment.author = '';
authorInfo.appendChild(floorNumber);
authorInfo.appendChild(authorLine);
authorInfo.classList.add('x-comment-author');
authorInfo.style.display = 'inline-block';
commentHeading.appendChild(authorInfo);
var commentTool = document.createElement('div');
if(logined) {
/* Reply button */
var replyBtn = document.createElement('span');
replyBtn.innerText = '回复';
replyBtn.classList.add('x-comment-replybtn');
replyBtn.style.marginLeft = '5px';
replyBtn.style.cursor = 'pointer';
replyBtn.style.textDecoration = 'underline';
genReplyHandler(replyBtn, floor);
commentTool.appendChild(replyBtn);
}
commentTool.classList.add('x-comment-tools');
commentTool.style.display = 'inline-block';
commentHeading.appendChild(commentTool);
commentHeading.classList.add('x-comment-head');
wrapper.appendChild(commentHeading);
/* Move content */
var contentBox = document.createElement('div');
comment.content = '';
while(content.firstChild) {
var child = content.firstChild;
if(child.classList && child.classList.contains('x-dummy')) {
content.removeChild(child);
continue;
}
if(child.classList && child.classList.contains('x-replybox')) {
comment.content += '\u21b2';
}
else {
comment.content += child.innerText || child.data || '';
if(child.tagName == 'BR') {
comment.content += ' ';
}
}
contentBox.appendChild(child);
}
if(comment.content.length > 50) {
comment.content = comment.content.substr(0, 50) + ' ...';
}
content.parentNode.removeChild(content);
contentBox.classList.add('x-comment-body');
contentBox.style.padding = '14px 30px';
wrapper.appendChild(contentBox);
wrapper.id = 'L' + floor;
wrapper.classList.add('x-comment');
comments.push(comment);
return wrapper;
}
/**
* Do a synchronous refresh and get newest comment ID
*/
function newestID() {
var xhr = new XMLHttpRequest();
xhr.open('GET', window.location.href, false);
xhr.send();
return xhr.responseText.match(/<blockquote>/g).length + 1;
}
/**
* Check for editor loading and modify it when loaded
*/
function checkEditorLoad() {
if(WYSIWYF && WYSIWYF.editors && WYSIWYF.editors[0] && WYSIWYF.editors[0].ifmLoaded) {
var editor = WYSIWYF.editors[0];
var origCbk = editor.eHolder.parentNode.onsubmit;
editor.eHolder.parentNode.onsubmit = function(e) {
/* Delete our content to avoid "Spanize" */
if(editor.ifmDocument.body.firstChild.classList.contains('x-replybox')) {
editor.replyboxStore = editor.ifmDocument.body.firstChild;
editor.ifmDocument.body.removeChild(editor.replyboxStore);
}
return origCbk();
};
editor.eHolder.parentNode.addEventListener('submit', function(e) {
if(editor.replyboxStore) {
editor.ifmDocument.body.insertBefore(editor.replyboxStore, editor.ifmDocument.body.firstChild);
}
editor.replyboxStore = null;
var dummy = document.createElement('img');
dummy.id = 'L' + newestID();
dummy.style.width = '0';
dummy.style.height = '0';
dummy.style.position = 'relative';
dummy.style.top = '-3em';
dummy.classList.add('x-dummy');
editor.ifmDocument.body.insertBefore(dummy, editor.ifmDocument.body.firstChild);
editor.textarea.value = editor.ifmDocument.body.innerHTML;
return true;
});
}
else {
setTimeout(checkEditorLoad, 50);
}
}
/**
* Init the page
*/
function init() {
var logined = isLogin();
var h3Col = document.body.querySelectorAll('h3');
var commentHead = null;
for(var i = 0; i < h3Col.length; i++) {
if(h3Col[i].innerText === 'Comments') {
commentHead = h3Col[i];
break;
}
}
if(!commentHead) {
return;
}
if(logined) {
var newStyle = document.createElement('style');
var cssText = 'form[method="post"]>div, form[method="post"]>div>div { width: auto !important; height: auto !important; } form[method="post"]>div>iframe {width: 100% !important; min-height: 300px;}';
newStyle.type = 'text/css';
if(newStyle.styleSheet) {
newStyle.styleSheet.cssText = cssText;
}
else {
newStyle.appendChild(document.createTextNode(cssText));
}
(document.head || document.getElementsByTagName('head')[0]).appendChild(newStyle);
}
var cur = commentHead.nextSibling;
var floor = 1;
while(cur.nextSibling.tagName != 'H3') {
var authorLine = cur;
var brAnchor = cur.nextSibling;
var content = brAnchor.nextSibling;
cur = content.nextSibling;
var newComment = genComment(authorLine, content, logined, floor);
brAnchor.parentNode.insertBefore(newComment, brAnchor);
brAnchor.parentNode.removeChild(brAnchor);
floor++;
}
checkEditorLoad();
}
init();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment