Last active
January 14, 2017 17:23
-
-
Save AmauryCarrade/27a5266d49a3c1406e0e to your computer and use it in GitHub Desktop.
Affichage de raccourcis de modération et divers autres améliorations sur le forum de ZCraft
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
// ==UserScript== | |
// @name Affichage de raccourcis de modération sur ZCraft | |
// @namespace eu.carrade.amaury.zcraft | |
// @description Affichage de raccourcis de modération sur ZCraft | |
// @include https://forum.zcraft.fr/viewtopic.php* | |
// @include https://forum.zcraft.fr/post.php* | |
// @include https://forum.zcraft.fr/edit.php* | |
// @include http://forum.zcraft.fr/viewtopic.php* | |
// @include http://forum.zcraft.fr/post.php* | |
// @include http://forum.zcraft.fr/edit.php* | |
// @updateURL https://gist.githubusercontent.com/AmauryCarrade/27a5266d49a3c1406e0e/raw/mod-zcraft.user.js | |
// @version 4 | |
// @grant none | |
// ==/UserScript== | |
/** | |
* Adds a CSS rule. | |
* | |
* @param selector (string) The CSS selector. | |
* @param rules (string) The CSS rules, written in natural CSS. | |
*/ | |
function addCSSRule(selector, rules) | |
{ | |
var style = document.styleSheets[2]; | |
if(style.cssRules) | |
style.insertRule(selector + "{ " + rules + " }", 0); | |
else if(style.rules) | |
style.addRule(selector, rules); | |
} | |
/** | |
* Returns an XMLHttpRequest object. | |
*/ | |
function getXHR() | |
{ | |
if(window.XMLHttpRequest) | |
return new XMLHttpRequest(); | |
else | |
return new ActiveXObject("Microsoft.XMLHTTP"); | |
} | |
/** | |
* Returns the DOM of a distant page through a callback. | |
* | |
* @param url (string) The URL to be loaded. | |
* @param callback (runnable) A callback called with these arguments: | |
* - dom (Document) → the loaded DOM (null in case of fail) | |
* - success (bool) → true if the request was answered by a 200 status code | |
* - xhr (XMLHttpRequest) → The XMLHttpRequest object. | |
* @param method The HTTP method ("POST", "GET", ...). | |
* | |
* @return The XMLHttpRequest object. | |
*/ | |
function getDistantDOM(url, callback, method) | |
{ | |
var xhr = getXHR(); | |
xhr.responseType = 'document'; | |
xhr.onload = function() | |
{ | |
callback(xhr.response, xhr.status == 200, xhr); | |
} | |
xhr.open(method == undefined ? "GET" : method, url, true); | |
xhr.send(); | |
return xhr; | |
} | |
// Better smiley size | |
addCSSRule(".smiley", "max-width: 18px !important; max-height: 18px !important;"); | |
// Applications helpers injections | |
addCSSRule(".zus_fake_link", "color: #2365B0; cursor: pointer;"); | |
addCSSRule(".zus_textarea_bottom", "font-size: 0.8em;"); | |
addCSSRule(".zus_bottom_title", "font-weight: bold; padding-right: 15px;"); | |
addCSSRule(".zus_error", "color: #FE1616;"); | |
var text_separator = " • "; | |
var textareas_helpers = "<div class='zus_textarea_bottom'><span class='zus_bottom_title'>Candidatures</span> "; | |
textareas_helpers += "<span class='zus_fake_link' id='zus_accept'>Insérer le texte d'acceptation</span>" + text_separator; | |
textareas_helpers += "<span class='zus_fake_link' id='zus_tag'>Ajouter un tag</span>"; | |
textareas_helpers += "</div>" | |
var textareas = document.getElementsByTagName("textarea"); | |
for(var i = 0; i < textareas.length; i++) | |
{ | |
var textarea = textareas.item(i); | |
if(textarea.getAttribute("name") == "req_message") | |
{ | |
// We are here in a message textarea. | |
textarea.insertAdjacentHTML("afterend", textareas_helpers); | |
} | |
} | |
var texts = {}; | |
texts["accepted"] = "Tu es accepté parmi les Zcraftiens : félicitations ! :)\n\nPense bien à (re)lire le [url=http://www.zcraft.fr/zcraft-mode-demploi/guide-de-survie/]guide de survie pour les nouveaux Zcraftiens[/url] qui contient une mine d'informations pour bien démarrer."; | |
document.getElementById("zus_accept").onclick = function() | |
{ | |
insertTag(texts["accepted"], ""); | |
} | |
// Tags management | |
var tag_link = document.getElementById("zus_tag"); | |
var tag_adding = false; | |
tag_link.onclick = function() | |
{ | |
if(tag_adding) return false; | |
var tag = prompt("Quel tag ajouter ?\nSi présent, le tag sera retiré.\n\n", "Accepté"); | |
if(tag == null || tag == "") | |
return false; | |
tag_adding = true; | |
tag_link.innerHTML = "Ajout en cours..."; | |
var root = location.origin + "/"; | |
var formtype = ""; // "fast" (form under the topic), "post" (dedicated page for a new post) or "edit" (edit page). | |
switch(location.pathname) | |
{ | |
case "/viewtopic.php": | |
formtype = "fast"; | |
break; | |
case "/post.php": | |
formtype = "post"; | |
break; | |
case "/edit.php": | |
formtype = "edit"; | |
break; | |
} | |
/* | |
1/ Get the title, by loading the first page and parsing the page's title. | |
2/ Compute the new title (addition of the tag at the beginning). | |
3/ Update the title, in the database (AJAX request) and visually (page title, breadcumbs, main title). | |
*/ | |
/* 1 - What is the topic ID? */ | |
var topicID = undefined; | |
// Edit & new message pages | |
if(formtype == "edit" || formtype == "post") // The topic ID is in the breadcumbs, there's a link to the first page. | |
{ | |
var breadcrumbs = document.getElementById("brdmain").getElementsByClassName("crumbs").item(0).getElementsByTagName("li"); | |
for(var i = 0; i < breadcrumbs.length; i++) | |
{ | |
var linkHref = breadcrumbs.item(i).getElementsByTagName("a").item(0).getAttribute("href"); | |
if(linkHref != "" && linkHref.substr(0, 13) == "viewtopic.php") | |
{ | |
topicID = Number(linkHref.split("?")[1].split("=")[1]); | |
break; | |
} | |
} | |
} | |
else if(formtype == "fast") // The topic ID is in the RSS feed link: extern.php?action=feed&tid=<TopicID>&type=rss | |
{ | |
var links = document.getElementsByTagName("link"); | |
for(var i = 0; i < links.length; i++) | |
{ | |
var link = links.item(i); | |
var linkHref = link.getAttribute("href"); | |
if(link.getAttribute("rel") == "alternate" && link.getAttribute("type") == "application/rss+xml" && linkHref.substr(0, 27) == "extern.php?action=feed&tid=") | |
{ | |
topicID = Number(linkHref.split("?")[1].split("&")[1].split("=")[1]); | |
} | |
} | |
} | |
if(topicID == undefined || topicID <= 0) | |
{ | |
console.error("[Tag] ERROR: unable to add the tag. Cannot retrieve the topic ID (found: " + topicID + ") at " + location.href); | |
endTagAddition(false); | |
return; | |
} | |
/* 2 - What is the message ID? And the title? */ | |
var firstPageURL = root + "viewtopic.php?id=" + topicID; | |
getDistantDOM(firstPageURL, function(firstDOM, success) | |
{ | |
if(!success) | |
{ | |
console.error("[Tag] ERROR: unable to load the first topic page (topic ID: " + topicID + ") at " + location.href); | |
endTagAddition(false); | |
return; | |
} | |
var firstPostID = Number(firstDOM.getElementById("brdmain").getElementsByClassName("firstpost").item(0).getAttribute("id").substring(1)); | |
var postTitle = firstDOM.getElementsByTagName("title")[0].textContent.split("/")[0].trim(); | |
postTitle = postTitle.substr(0, postTitle.length - (" (Page 1)".length)); | |
/* 3 - Final title? */ | |
var fullTag = "[" + tag + "] "; | |
if(postTitle.indexOf(fullTag) == -1) | |
postTitle = fullTag + postTitle; | |
else | |
postTitle = postTitle.substring(fullTag.length); | |
/* 4 - Database-side update */ | |
var editFirstMessageFormURL = root + "edit.php?id=" + firstPostID + "&action=edit"; | |
getDistantDOM(editFirstMessageFormURL, function(editFirstDOM, success) | |
{ | |
if(!success) | |
{ | |
console.error("[Tag] ERROR: unable to load the first topic page (topic ID: " + topicID + ") at " + location.href + ". Are you allowed to do that?"); | |
endTagAddition(false); | |
return; | |
} | |
//var form_sent = "1"; | |
var req_subject = postTitle; | |
var req_message = ""; | |
//var silent = "1"; | |
//var submit = "Valider"; | |
var editForm = editFirstDOM.getElementById("edit"); | |
if(editForm == null) // Unauthorized. The HTTP response code is 200 even when the user is not allowed to edit a message >< . | |
{ | |
console.error("[Tag] ERROR: unable to load the first topic page (topic ID: " + topicID + ") at " + location.href + ". Access denied!"); | |
endTagAddition(false); | |
return; | |
} | |
var textareas = editForm.getElementsByTagName("textarea"); | |
for(var i = 0; i < textareas.length; i++) | |
{ | |
var firstPostTextarea = textareas.item(i); | |
if(firstPostTextarea.getAttribute("name") == "req_message") | |
{ | |
req_message = firstPostTextarea.innerHTML; | |
} | |
} | |
var xhr = getXHR(); | |
var postParams = ""; | |
postParams += "form_sent=1" | |
postParams += "&req_subject=" + encodeURIComponent(req_subject); | |
postParams += "&req_message=" + encodeURIComponent(req_message); | |
postParams += "&silent=1"; | |
postParams += "&submit=Valider" | |
xhr.open("POST", editFirstMessageFormURL, true); | |
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); | |
xhr.setRequestHeader("Content-length", postParams.length); | |
xhr.setRequestHeader("Referer", editFirstMessageFormURL); // needed: without the request is rejected. | |
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); | |
xhr.setRequestHeader('X-Alt-Referer', editFirstMessageFormURL); | |
xhr.setRequestHeader("Connection", "close"); | |
xhr.onreadystatechange = function() | |
{ | |
if(xhr.readyState == 4) | |
{ | |
if(xhr.status == 200) | |
{ | |
endTagAddition(true); | |
console.log(xhr.responseText); | |
} | |
else | |
{ | |
console.error("[Tag] ERROR: unable to save the new title at " + location.href + ". The server responded: " + xhr.status); | |
console.error(xhr); | |
endTagAddition(false); | |
return; | |
} | |
} | |
} | |
xhr.send(postParams); | |
}); | |
}); | |
} | |
/** | |
* Ends the tag addition display by setting the link text to a message (related to the success), and a few seconds later, putting back the original text. | |
* | |
* @param success (bool) Used to determine what will be displayed. | |
*/ | |
function endTagAddition(success) | |
{ | |
var message = success ? "Tag ajouté avec succès" : "Impossible d'ajouter le tag ! Consultez la console pour les détails." | |
tag_link.innerHTML = message; | |
if(!success) tag_link.classList.add("zus_error"); | |
setTimeout(function() { | |
tag_link.innerHTML = "Ajouter un tag"; | |
if(!success) tag_link.classList.remove("zus_error"); | |
tag_adding = false; | |
}, 4000); | |
} | |
// « New messages » link on every topic | |
// (TODO link detection to add it only if needed, and this on all pages?) | |
document.getElementById("searchlinks").insertAdjacentHTML("afterbegin", "<dd><span><a href='search.php?action=show_new'>Afficher les nouveaux messages</a></span></dd>"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment