// ==UserScript== // @name JVChat Premium // @description Outil de discussion instantanée pour les forums de Jeuxvideo.com // @author Blaff // @namespace JVChatPremium // @version 0.1.42 // @match http://*.jeuxvideo.com/forums/42-* // @match https://*.jeuxvideo.com/forums/42-* // @match http://*.jeuxvideo.com/forums/1-* // @match https://*.jeuxvideo.com/forums/1-* // @grant none // @downloadURL none // ==/UserScript== /* TODO: - Smooth transition on append messages (slide-in plutôt que jump) - Détection captcha - Bouton actualiser les messages (+ afficher le delai courrant d'actualisation) - Bouton désactiver JVChat - Bouton retour liste des sujets - Notification avec @pseudo - Blacklist - Pouvoir voir les anciens messages - La leftbar ne se rétrécie pas si le titre du topic n'a pas d'espaces */ let CSS = ``; let PANEL = `

Profil

Topic

Forum

Sondage

Configuration

Les paramètres sont automatiquement sauvegardés et mis à jour lorsque vous les modifiez.

Jouer un son de notification lorsqu'un nouveau message est posté et que vous êtes sur un onglet différent.

? ms

Ajuste le délai d'actualisation des messages en mode turbo (celui-ci permet de mettre à jour les messages plus rapidement, mais est déconseillé si vous avez une connexion instable).

? %

Configure l'espace utilisé horizontalement par les messages (une valeur réduite facilite la lecture sur les écrans larges).

`; function getForm(doc) { return doc.getElementsByClassName('form-post-message')[0]; } function getHash(doc) { let hash = doc.querySelector("#ajax_hash_liste_messages") if (!hash) { return undefined; } return hash.getAttribute("value"); } let freshHash = getHash(document); let freshForm = getForm(document); let firstMessageId = undefined; let firstMessageDate = undefined; let allMessagesId = {}; let userConnected = undefined; let updateIntervals = [2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 30, 30, 30, 30, 30, 30, 30, 30, 60]; let transisitions = [0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 19, 19, 19, 19, 19, 19, 19, 19, 31]; let updateIntervalIdx = 0; let updateIntervalMax = updateIntervals.length - 1; let isLocked = false; let isError = false; let isReduced = true; let nbNewMessage = 0; let favicon = makeFavicon(); let currentUser = {notif: undefined, mp: undefined, author: undefined, avatar: undefined}; let currentTopicTitle = undefined; let turboActivated = false; let sondageChoices = undefined; let urlToFetch = undefined; let urlToCheckEdit = undefined; let currentFetchedPage = 1; let currentTimeoutId = -1; let shouldCheckEdited = false; let checkEditInterval = 30000; let postingMessage = false; let fetchingMessages = false; let leavingTopic = false; let storageKey = "jvchat-premium-configuration"; let ringBell = undefined; let configuration = { default_reduced: false, turbo_delay: 500, max_width: 100, play_sound: false, sound: "data:audio/mp3;base64, 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KZ+4/J4hhPMbxk9uZlkvh6/jLtS6T9noZlleNzM1apGt+7CwkdfONPpLpNT0rivtF6d5JRejlihnmuTMIf3OWsl7KKKapZHQ3IBmnFlUchyHaOIzN+Syuo2SUVYPlNqCn+n4xG78SrR1lD/QTSyWlcKHJychjdSVSWMwDAM3EY7Rf/////4vzXlEEQJGHKsO7LsZ6U2J2PwPQf/////wNDUARKBH5g6tXeyKSKCcnRpY3DcYAAEAAAMEoLwyQhqjAOAaMLkNqt00SR7TGnEwMCcLkwGAN/0YLQF4kEeYBQBxgMgDf5zDxADC4wy5TXmbBm6JJimNECMEY0V/+ZUKbI8RFS75hwiwRgQhhQ3//mSGBgiSmIDAYQ8RaowYaYQy///4FAgIFCFcICDBAACE//uSxO0AK+Iu+xnsAAT7PuBXPaAAsrSBICGWxf///q8USLIIaMqLIIUF1n1hhHpwYQrd////69i6hehbyJiOCcatiVjSXVaU3Fpsebiy2x/////+jW3RSxAe2JliKcPPIim67osRh10V2u7ALDWcx1hv///////DiG7T48oOzeXsjTHhtmap3fdFMdYWZaysLddlhtaIrlpqFlMSp//////////3Hh1Qdf8HMPUvasytPttG5svXpBLO1LJlr//////7WYlRuzEotEYCfqZiTvX4k5UPRJynekxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv/7ksQ5A8AAAaQcAAAgAAA0gAAABKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=" }; function saveConfig() { let config = JSON.stringify(configuration); localStorage.setItem(storageKey, config); } function loadConfig() { let config = JSON.parse(localStorage.getItem(storageKey) || "{}"); for (let key in config) { if (config.hasOwnProperty(key) && configuration.hasOwnProperty(key)) { configuration[key] = config[key]; } } } function getTopicLocked(elem) { let lock = elem.getElementsByClassName("message-lock-topic")[0]; if (lock === undefined) { return lock; } let reason = lock.getElementsByTagName("span")[0].textContent.trim(); return `Le topic a été vérouillé pour la raison suivante : "${reason}"`; } function getTopicError(elem) { let error = elem.getElementsByClassName("img-erreur")[0]; if (error === undefined) { return error; } return `Le topic présente une erreur: ${error.getAttribute("alt")}`; } function parseSondage(elem) { let blocSondage = elem.getElementsByClassName("bloc-sondage")[0]; if (!blocSondage) { return null; } let intitule = blocSondage.getElementsByClassName("intitule-sondage")[0].innerHTML; let answered = !!(blocSondage.getElementsByClassName("result-pourcent")[0]); let choix = blocSondage.getElementsByClassName("tab-choix")[0].getElementsByTagName("tr"); let results = []; if (answered) { for (let ch of choix) { let pourcent = parseInt(ch.getElementsByClassName("pourcent")[0].innerHTML.trim().split(" ")[0]); let response = ch.getElementsByClassName("reponse")[0].innerHTML.trim(); results.push({response: response, pourcent: pourcent}); } } else { for (let ch of choix) { let btnResponse = ch.getElementsByClassName("btn-sondage-reponse")[0]; let response = btnResponse.innerHTML.trim(); let sondageId = btnResponse.getAttribute("data-id-sondage"); let responseId = btnResponse.getAttribute("data-id-reponse"); results.push({response: response, sondageId: sondageId, responseId:responseId}); } } let votes = parseInt(blocSondage.getElementsByClassName("pied-result")[0].innerHTML.trim().split(" ")[0]); return {answered:answered, intitule: intitule, results:results, votes:votes}; } function tryCatch(func) { function wrapped(optArg) { try { func(optArg); } catch(err) { let message = `Une erreur est survenue dans JVChat Premium: '${err.message}' (line ${err.lineNumber})`; console.error(message); try { addAlertbox("danger", message); } catch(e) { alert(message); } } } return wrapped; } function toggleTextarea() { isReduced = !isReduced; configuration["default_reduced"] = isReduced; saveConfig(); let isDown = isScrollDown(); document.getElementById("bloc-formulaire-forum").getElementsByClassName("jv-editor-toolbar")[0].classList.toggle("jvchat-hide"); document.getElementById("jvchat-enlarge").classList.toggle("jvchat-hide"); document.getElementById("jvchat-reduce").classList.toggle("jvchat-hide"); document.getElementById("jvchat-post").classList.toggle("jvchat-hide"); document.getElementById("bloc-formulaire-forum").classList.toggle("jvchat-reduced"); setTextareaHeight(); if (isDown) { setScrollDown(); } } function parseURL(url) { let regex = /^(.*?)(\/\d+-\d+-\d+-)(\d+)(-\d+-\d+-\d+-)(.*?)(\.htm)(.*)$/i; let [_, domain, ids, page, nums, title, htm, anchor] = url.match(regex); return {domain: domain, ids: ids, page: page, nums: nums, title: title, htm: htm, anchor: anchor}; } function buildURL(dict) { return `${dict.domain}${dict.ids}${dict.page}${dict.nums}${dict.title}${dict.htm}${dict.anchor}`; } function getForum(document) { let ariane = document.getElementsByClassName("bloc-fil-ariane-crumb-forum")[0]; let links = ariane.getElementsByTagName("a"); let title = ""; let forumLink = ""; for (let i = links.length - 1; i >= 0; i--) { forumLink = links[i]; title = forumLink.innerHTML.trim(); if (title.startsWith("Forum ")) { break; } } return {href: forumLink.getAttribute("href"), title: title.replace("Forum ", "")}; } function getLastPage(document) { let blocPages = document.getElementsByClassName("bloc-liste-num-page")[0]; let spans = blocPages.getElementsByTagName("span"); let lastPage = 1; for (let span of spans) { let page = parseInt(span.textContent.trim()); if (!isNaN(page) && page > lastPage) { lastPage = page; } } return lastPage; } function parseMessage(elem) { let conteneurs = elem.getElementsByClassName("conteneur-message"); let conteneur = conteneurs[conteneurs.length - 1]; let blacklisted = conteneurs[0].classList.contains("conteneur-message-blacklist"); let author = conteneur.getElementsByClassName("bloc-pseudo-msg")[0].textContent.trim(); let avatar = conteneur.getElementsByClassName("user-avatar-msg")[0]; if (avatar !== undefined) { avatar = avatar.getAttribute("data-srcset"); } let date = conteneur.getElementsByClassName("bloc-date-msg")[0].textContent.trim(); let content = conteneur.getElementsByClassName("text-enrichi-forum")[0]; let id = parseInt(elem.getAttribute("data-id")); let edited = elem.getElementsByClassName("info-edition-msg")[0]; if (edited !== undefined) { let msgEdited = edited.textContent.trim(); edited = msgEdited.match(/Message édité le .*? à (.*?) par/i)[1]; } return {author: author, date: date, avatar: avatar, edited: edited, id: id, content: content, blacklisted: blacklisted}; } function parseUserInfo(elem) { let accountMp = elem.getElementsByClassName("jv-nav-account-mp")[0]; if (accountMp === undefined) { return {author: undefined, avatar: undefined, mp: undefined, notif: undefined}; } let numberMp = accountMp.getElementsByClassName("jv-account-number-mp")[0]; let accountNotif = elem.getElementsByClassName("jv-nav-account-notif")[0]; let numberNotif = accountNotif.getElementsByClassName("jv-account-number-notif")[0]; let accountUser = elem.getElementsByClassName("jv-nav-account-user")[0]; let avatarBox = accountUser.getElementsByClassName("account-avatar-box")[0]; let authorBox = accountUser.getElementsByClassName("account-pseudo")[0]; let mp = parseInt(numberMp.getAttribute("data-val")); let notif = parseInt(numberNotif.getAttribute("data-val")); let avatar = avatarBox.style["background-image"].slice(5, -2).replace("/avatar-md/", "/avatar/"); let author = authorBox.textContent.trim(); return {author: author, avatar: avatar, mp: mp, notif: notif}; } function parseTopicInfo(elem) { let title = elem.querySelector("#bloc-title-forum").textContent.trim(); let connected = parseInt(elem.getElementsByClassName("nb-connect-fofo")[0].textContent.trim()); let lastPage = getLastPage(elem); let pageActive = elem.getElementsByClassName("page-active")[0]; let page = 1; if (pageActive !== undefined) { page = parseInt(pageActive.textContent.trim()); } return {title: title, connected: connected, lastPage: lastPage, page: page}; } function fixMessage(elem) { let jvcares = Array.from(elem.getElementsByClassName("JvCare")); for (let jvcare of jvcares) { let a = document.createElement("a"); a.setAttribute("target", "_blank"); a.setAttribute("href", jvCake(jvcare.getAttribute("class"))); a.innerHTML = jvcare.innerHTML; jvcare.outerHTML = a.outerHTML; } } function jvCake(cls) { let base16 = '0A12B34C56D78E9F', lien = '', s = cls.split(' ')[1]; for (let i = 0; i < s.length; i += 2) { lien += String.fromCharCode(base16.indexOf(s.charAt(i)) * 16 + base16.indexOf(s.charAt(i + 1))); } return lien; } function improveImages(elem) { let imagesShack = elem.getElementsByClassName("img-shack"); for (let image of imagesShack) { let src = image.src; let parent = image.parentNode; let extension = parent.href.split(".").pop(); let direct = src.replace(/(.*?)\/minis\/(.*)\.\w+/i, "$1/fichiers/$2." + extension); parent.href = direct; if (extension.toUpperCase() === "GIF") { image.src = direct; } src = image.src; image.setAttribute("onerror", `this.onerror=null;this.src='${direct}'`); } } function clearPage(document) { let buttons = `
`; document.head.insertAdjacentHTML("beforeend", CSS); let previsu = document.getElementById("bloc-formulaire-forum").getElementsByClassName("previsu-editor")[0]; if (previsu) { previsu.parentElement.removeChild(previsu); } let messageTopic = document.getElementById("message_topic"); if (messageTopic) { messageTopic.classList.add("jvchat-textarea"); messageTopic.setAttribute("placeholder", "Hop hop hop, le message ne va pas s'écrire tout seul !"); messageTopic.insertAdjacentHTML("afterend", buttons); messageTopic.addEventListener("keydown", tryCatch(postMessageIfEnter)); document.getElementById("jvchat-post").addEventListener("click", tryCatch(postMessage)); document.getElementById("jvchat-enlarge").addEventListener("click", tryCatch(toggleTextarea)); document.getElementById("jvchat-reduce").addEventListener("click", tryCatch(toggleTextarea)); } document.getElementsByClassName("conteneur-messages-pagi")[0].insertAdjacentHTML("afterbegin", "

"); document.getElementById("page-messages-forum").insertAdjacentHTML("afterbegin", "
"); document.getElementById("content-context").insertAdjacentHTML("afterbegin", PANEL); document.getElementById("content-context").insertAdjacentHTML("beforeend", "
"); document.getElementById("bloc-formulaire-forum").classList.add("jvchat-reduced"); document.getElementById("bloc-formulaire-forum").classList.add("jvchat-hide"); let toolbar = document.getElementById("bloc-formulaire-forum").getElementsByClassName("jv-editor-toolbar")[0]; if (toolbar) { toolbar.classList.add("jvchat-hide"); } document.getElementById("jvchat-main").addEventListener("click", tryCatch(dontScrollOnExpand)); document.getElementById("jvchat-alerts").addEventListener("click", tryCatch(closeAlert)); document.getElementById("jvchat-leftbar-reduce").addEventListener("click", tryCatch(toggleSidebar)); document.getElementById("jvchat-leftbar-extend").addEventListener("click", tryCatch(toggleSidebar)); document.getElementById("jvchat-leftbar-config-open").addEventListener("click", tryCatch(toggleConfig)); document.getElementById("jvchat-leftbar-config-close").addEventListener("click", tryCatch(toggleConfig)); document.getElementById("jvchat-turbo-checkbox").addEventListener("change", tryCatch(toggleTurbo)); document.getElementById("jvchat-play-sound-checkbox").checked = configuration["play_sound"]; document.getElementById("jvchat-play-sound-checkbox").addEventListener("change", tryCatch(togglePlaySoundOption)); document.getElementById("jvchat-turbo-delay-range").value = configuration["turbo_delay"]; document.getElementById("jvchat-turbo-delay-span").innerHTML = `${configuration["turbo_delay"]} ms`; document.getElementById("jvchat-turbo-delay-range").addEventListener("input", tryCatch(changeTurboDelayOption)); document.getElementById("jvchat-max-width-range").value = configuration["max_width"]; document.getElementById("jvchat-max-width-span").innerHTML = `${configuration["max_width"]} %`; document.getElementById("jvchat-max-width-range").addEventListener("input", tryCatch(changeMaxWidthOption)); adjustMaxWidth(configuration["max_width"]); let favs = Array.from(document.querySelectorAll("link[rel='icon'], link[rel='shortcut icon']")); for (let fav of favs) { fav.parentElement.removeChild(fav); } setFavicon(""); document.addEventListener("visibilitychange", function() { let hidden = document.hidden; if (hidden) { let newHr = document.getElementById("jvchat-ruler-new"); if (newHr) { newHr.removeAttribute("id"); } nbNewMessage = 0; } else if (!isError && !isLocked) { setFavicon(""); } }); } function toggleSidebar(event) { let isDown = isScrollDown(); document.getElementById("jvchat-leftbar-extend").classList.toggle("jvchat-hide"); document.getElementById("jvchat-leftbar-reduce").classList.toggle("jvchat-hide"); document.getElementById("jvchat-leftbar-config").classList.toggle("jvchat-hide"); document.getElementById("jvchat-leftbar").classList.toggle("jvchat-leftbar-reduced"); if (isDown) { setScrollDown(); } } function toggleConfig(event) { document.getElementById("jvchat-leftbar-config-open").classList.toggle("jvchat-hide"); document.getElementById("jvchat-leftbar-config-close").classList.toggle("jvchat-hide"); document.getElementById("jvchat-info").classList.toggle("jvchat-hide"); document.getElementById("jvchat-config").classList.toggle("jvchat-hide"); } function toggleTurbo(event) { let checked = document.getElementById("jvchat-turbo-checkbox").checked; updateIntervalIdx = 0; if (!checked) { turboActivated = false; } else { turboActivated = true; // If waiting for next update, restart it immedtialty, otherwise just wait for the HTTP request to end if (!fetchingMessages) { clearTimeout(currentTimeoutId); updateMessages(currentFetchedPage, true); } } } function togglePlaySoundOption(event) { let checked = document.getElementById("jvchat-play-sound-checkbox").checked; configuration["play_sound"] = checked; saveConfig(); } function changeTurboDelayOption(event) { let ms = document.getElementById("jvchat-turbo-delay-range").value; document.getElementById("jvchat-turbo-delay-span").innerHTML = `${ms} ms`; configuration["turbo_delay"] = parseInt(ms); saveConfig(); } function changeMaxWidthOption(event) { let maxWidth = parseInt(document.getElementById("jvchat-max-width-range").value); document.getElementById("jvchat-max-width-span").innerHTML = `${maxWidth} %`; configuration["max_width"] = maxWidth; saveConfig(); adjustMaxWidth(maxWidth); } function adjustMaxWidth(maxWidth) { document.getElementById("page-messages-forum").style["flex-grow"] = maxWidth; document.getElementById("jvchat-right-padding").style["flex-grow"] = 100 - maxWidth; } function closeAlert(event) { let target = event.target; if (!target) { return; } if (target.classList.contains("jvchat-alert-close")) { let parent = target.parentElement; parent.parentElement.removeChild(parent); } } function postMessage() { if (freshForm === undefined) { addAlertbox("danger", "Impossible de poster le message, aucun formulaire trouvé"); return; } let textarea = document.getElementById("message_topic"); let formData = serializeForm(freshForm); formData["message_topic"] = textarea.value; let formulaire = document.getElementById("bloc-formulaire-forum"); formulaire.classList.add("jvchat-disabled-form"); textarea.setAttribute("disabled", "true"); function onSuccess(res) { formulaire.classList.remove("jvchat-disabled-form"); textarea.removeAttribute("disabled"); let alert = parsePage(res).alert; if (!alert) { textarea.value = ""; } setTextareaHeight(); setScrollDown(); postingMessage = false; } function onError(err) { addAlertbox("danger", err); formulaire.classList.remove("jvchat-disabled-form"); textarea.removeAttribute("disabled"); postingMessage = false; } function onTimeout(err) { addAlertbox("warning", err); formulaire.classList.remove("jvchat-disabled-form"); textarea.removeAttribute("disabled"); postingMessage = false; } let timeout = 20000; if (turboActivated) { timeout = 5000; } postingMessage = true; request("POST", document.URL, onSuccess, onError, onTimeout, makeFormData(formData), false, timeout); } function editMessage(bloc) { let textarea = bloc.getElementsByClassName("jvchat-edition-textarea")[0]; let blocEdition = bloc.getElementsByClassName("jvchat-edition")[0]; let formData = JSON.parse(blocEdition.getAttribute("data-form")); formData["message_topic"] = textarea.value; formData["id_message"] = bloc.getAttribute("jvchat-id"); formData["ajax_hash"] = freshHash; formData["action"] = "post"; let edition = bloc.getElementsByClassName("jvchat-edition")[0]; edition.classList.add("jvchat-disabled-form"); textarea.setAttribute("disabled", "true"); function onSuccess(res) { edition.classList.remove("jvchat-disabled-form"); if (res['reset_form']) { let reset = document.createElement("html"); reset.innerHTML = res["hidden_reset"]; let resetData = serializeForm(reset); for (let key in resetData) { formData[key] = resetData[key]; } blocEdition.setAttribute("data-form", JSON.stringify(formData)); } textarea.removeAttribute("disabled"); if (res.erreur.length > 0) { for (let err of res.erreur) { addAlertbox("danger", err); } return; } let dom = document.createElement("html"); dom.innerHTML = res["html"]; let message = getMessages(dom)[0]; addMessages([message], true); } function onError(err) { addAlertbox("danger", err); edition.classList.remove("jvchat-disabled-form"); textarea.removeAttribute("disabled"); } function onTimeout(err) { addAlertbox("warning", err); edition.classList.remove("jvchat-disabled-form"); textarea.removeAttribute("disabled"); } let url = "http://www.jeuxvideo.com/forums/ajax_edit_message.php"; request("POST", url, onSuccess, onError, onTimeout, makeFormData(formData), true, 20000); } function requestEdit(bloc) { if (!bloc.getElementsByClassName("jvchat-edition")[0].classList.contains("jvchat-hide")) { return; } let contentClasses = bloc.getElementsByClassName("jvchat-content")[0].classList; contentClasses.add("disabled-content"); function onSuccess(res) { contentClasses.remove("disabled-content"); if (res.erreur.length > 0) { for (let err of res.erreur) { addAlertbox("danger", err); } return; } let dom = document.createElement("html"); dom.innerHTML = res["html"]; let textarea = dom.getElementsByTagName("textarea")[0] let txt = textarea.value; textarea.parentElement.removeChild(textarea); let form = dom.getElementsByTagName("form")[0]; let formData = serializeForm(form); let editionBloc = bloc.getElementsByClassName("jvchat-edition")[0]; editionBloc.setAttribute("data-form", JSON.stringify(formData)); let height = computeHeight(countLines(txt)); let isDown = isScrollDown(); bloc.getElementsByClassName("jvchat-edition-textarea")[0].value = txt; bloc.getElementsByClassName("jvchat-edition-textarea")[0].style["height"] = `${height}rem`; bloc.getElementsByClassName("jvchat-content")[0].classList.add("jvchat-hide"); editionBloc.classList.remove("jvchat-hide"); if (isDown) { setScrollDown(); } } function onError(err) { addAlertbox("danger", err); contentClasses.remove("disabled-content"); } function onTimeout(err) { addAlertbox("warning", err); contentClasses.remove("disabled-content"); } let id = bloc.getAttribute("jvchat-id"); let url = `http://www.jeuxvideo.com/forums/ajax_edit_message.php?id_message=${id}&ajax_hash=${freshHash}&action=get`; request("GET", url, onSuccess, onError, onTimeout, undefined, true, 5000); } function countLines(text) { return text.split(/\r|\r\n|\n/).length; } function computeHeight(lines) { return 1 * lines + 0.6; } function setTextareaHeight(plusOne) { let textarea = document.getElementById("message_topic"); if (!isReduced) { textarea.style["height"] = ""; return; } plusOne = !!plusOne; let lines = countLines(textarea.value); if (!plusOne && lines === 1) { textarea.style["height"] = ""; return; } if (plusOne) { lines += 1; } let height = computeHeight(lines); textarea.style["height"] = `${height}rem`; } function postMessageIfEnter(event) { if (isReduced && (event.which == 13 || event.keyCode == 13)) { if (event.shiftKey) { let isDown = isScrollDown(); setTextareaHeight(true); if (isDown) { setScrollDown(); } } else { event.preventDefault(); postMessage(); } } } function serializeForm(form) { // Useless actually, just use new FormData(form) let dict = {}; for (let select of form.getElementsByTagName("select")) { dict[select.name] = select.querySelector("option[selected]").value; } for (let input of form.getElementsByTagName("input")) { dict[input.name] = input.value; } for (let textarea of form.getElementsByTagName("textarea")) { dict[textarea.name] = textarea.value; } return dict; } function makeFormData(dict) { var formData = new FormData(); for (let key in dict) { formData.append(key, dict[key]); } return formData; } function getMessages(document) { let blocMessages = document.getElementsByClassName("bloc-message-forum"); let messages = []; for (let bloc of blocMessages) { messages.push(parseMessage(bloc)); } return messages; } function makeMessage(message) { let content = message.content; fixMessage(content); improveImages(content); let id = message.id; let avatar = message.avatar; let date = message.date; let toQuoteDate = date; let titleDate = date; let textDate = date.slice(-8); if (message.edited !== undefined) { textDate += "*"; titleDate += ` (édité à ${message.edited})`; } let exists = avatar !== undefined; let author = exists ? message.author : `${message.author}`; let authorHref = exists ? `href="http://www.jeuxvideo.com/profil/${author.toLowerCase()}?mode=infos"` : ""; let authorTitle = exists ? `title="Ouvrir le profil de ${author}"` : ""; let authorAvatarHidden = exists ? "": "class='jvchat-hide-visibility'"; let editionSpan = ''; let edition = (currentUser.author === undefined) || (message.author.toLowerCase() !== currentUser.author.toLowerCase()) ? "" : editionSpan; let html = `
${author}
${edition} ${textDate}
${content.outerHTML}

`; return html; } function parseDate(string) { let [date, time] = string.toLowerCase().split("à"); let [day, month, year] = date.trim().split(" "); let [hour, minute, second] = time.trim().split(":"); let monthIndex = ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"].indexOf(month.trim().toLowerCase()); return new Date(parseInt(year), monthIndex, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second)); } function addMessages(messages, editing) { editing = !!editing; let main = document.getElementById("jvchat-main"); let hasNewMessages = false; let init = true; let toInsert = ""; for (let message of messages) { let date = parseDate(message.date); let id = message.id; if (init === true && !editing) { init = false; let now = new Date(); let delta = now - date; if (delta > 5 * 60 * 1000 + checkEditInterval) { shouldCheckEdited = false; } else { shouldCheckEdited = true; } } if (message.blacklisted) { continue; } if (firstMessageId === undefined) { firstMessageId = id; firstMessageDate = date; } let referenced = allMessagesId.hasOwnProperty(id); let edited = message.edited; // Attention à 2 choses: le changement d'heure et le fait qu'un message suivant un autre peut avoir un id inférieur au précédent if ((id < firstMessageId && date < firstMessageDate) || (referenced && allMessagesId[id] === edited)) { continue; } let newBloc = makeMessage(message); allMessagesId[id] = edited; if (referenced) { let selector = `.jvchat-message[jvchat-id="${id}"]`; let oldBloc = main.querySelector(selector).closest(".jvchat-bloc-message"); let isDown = isScrollDown(); oldBloc.outerHTML = newBloc; if (isDown) { setScrollDown(); } continue; } hasNewMessages = true; if (nbNewMessage === 0 && document.hidden) { let hrs = document.getElementsByClassName("jvchat-ruler"); let lastHr = hrs[hrs.length - 1]; lastHr.setAttribute("id", "jvchat-ruler-new"); } toInsert += newBloc; nbNewMessage++; } if (toInsert !== "") { let isDown = isScrollDown(); main.insertAdjacentHTML("beforeend", toInsert); if (isDown) { setScrollDown(); } } if (editing) { return; } if (isScrollDown()) { let blocMessages = main.getElementsByClassName("jvchat-bloc-message"); let nb = blocMessages.length; if (nb > 100) { for (let i = 0; i < nb - 100; i++) { main.removeChild(blocMessages[0]); } setScrollDown(); } } if (hasNewMessages) { if (!turboActivated) { decreaseUpdateInterval(); } if (document.hidden) { setFavicon(nbNewMessage > 99 ? 99 : nbNewMessage); if (configuration["play_sound"]) { ringBell.pause(); ringBell.currentTime = 0; ringBell.play(); } } } else { if (!turboActivated) { increaseUpdateInterval(); } } } function submitSondageAnswer(event) { let target = event.target; if (!target) { return; } if (target.classList.contains("click-sondage")) { let reponseNum = parseInt(target.getAttribute("sondage-reponse-num")); let sondageId = sondageChoices[reponseNum]["sondageId"]; let reponseId = sondageChoices[reponseNum]["responseId"]; let topicId = urlToFetch["ids"].split("-")[2]; let url = `http://www.jeuxvideo.com/forums/ajax_topic_sondage_vote.php?id_topic=${topicId}&id_sondage_reponse=${reponseId}&id_sondage=${sondageId}&ajax_hash=${freshHash}`; function onSuccess(res) { if (res.erreur.length > 0) { for (let err of res.erreur) { addAlertbox("danger", err); } return; } let dom = document.createElement("html"); dom.innerHTML = res["html"]; let sondage = parseSondage(dom); if (!sondage) { addAlertbox("warning", "Erreur lors de la récupération du sondage"); return; } setSondage(sondage); } function onError(err) { addAlertbox("danger", err); } function onTimeout(err) { addAlertbox("warning", err); } request("POST", url, onSuccess, onError, onTimeout, undefined, true, 5000); } } function setSondage(sondage) { let choix = document.getElementById("jvchat-sondage-choix"); if (sondage["answered"]) { choix.removeEventListener("click", submitSondageAnswer); choix.classList.remove("notanswered"); } else { if (!sondageChoices) { sondageChoices = sondage["results"]; } choix.addEventListener("click", submitSondageAnswer); choix.classList.add("notanswered"); } if (!choix.firstChild) { document.getElementById("jvchat-sondage-intitule").innerHTML = sondage["intitule"]; let results = sondage["results"]; for (let i = 0; i < results.length; i++) { let res = results[i]; let tr = `
${res["pourcent"]} %
${res["response"]}
`; choix.insertAdjacentHTML("beforeend", tr); } } else { let trs = choix.getElementsByClassName("result-pourcent"); for (let i = 0; i < trs.length; i++) { let res = sondage["results"][i]; let tr = trs[i]; tr.getElementsByClassName("pourcent")[0].innerHTML = `${res["pourcent"]} %`; tr.getElementsByTagName("span")[0].style["width"] = `${res["pourcent"]}%`; } } document.getElementById("jvchat-sondage-votes").innerHTML = `(${sondage["votes"]} votes)`; } function setUser(document, user) { let isConnected = (user.author !== undefined); if (isConnected) { if (user.author !== currentUser.author) { let pseudo = document.getElementById("jvchat-user-pseudo"); pseudo.innerHTML = user.author; let avatarLink = document.getElementById("jvchat-user-avatar-link"); let notifLink = document.getElementById("jvchat-user-notif-link"); avatarLink.setAttribute("href", `http://www.jeuxvideo.com/profil/${user.author.toLowerCase()}?mode=infos`); notifLink.setAttribute("href", `http://www.jeuxvideo.com/profil/${user.author.toLowerCase()}?mode=abonnements`); } if (user.avatar !== currentUser.avatar) { let avatar = document.getElementById("jvchat-user-avatar"); avatar.style["background-image"] = `url("${user.avatar}")`; } if (user.mp !== currentUser.mp) { let mp = document.getElementById("jvchat-user-mp"); mp.setAttribute("data-val", user.mp); if (user.mp > 0) { mp.classList.add("has-notif"); } else { mp.classList.remove("has-notif"); } } if (user.notif !== currentUser.notif) { let notif = document.getElementById("jvchat-user-notif"); notif.setAttribute("data-val", user.notif); if (user.notif > 0) { notif.classList.add("has-notif"); } else { notif.classList.remove("has-notif"); } } } if ((userConnected === undefined && isConnected) || (userConnected !== undefined && isConnected !== userConnected)) { document.getElementById("jvchat-profil").classList.toggle("jvchat-hide"); let isDown = isScrollDown(); document.getElementById("bloc-formulaire-forum").classList.toggle("jvchat-hide"); if (isDown) { setScrollDown(); } } if (userConnected !== undefined) { if (isConnected && !userConnected) { addAlertbox("success", "Vous êtes désormais connecté"); } else if (!isConnected && userConnected) { addAlertbox("warning", "Vous avez été déconnecté"); } } userConnected = isConnected; currentUser = user; } function setTopicTitle(document, topicTitle) { if (topicTitle !== currentTopicTitle) { currentTopicTitle = topicTitle; document.getElementById("jvchat-topic-title").innerHTML = topicTitle; } } function setTopicNbConnected(document, nbConnected) { let txt = `${nbConnected} connectés`; if (!(nbConnected > 1)) { if (nbConnected === undefined) { txt = "? connectés"; } else { txt = txt.slice(0, -1); } } document.getElementById("jvchat-topic-nb-connected").innerHTML = txt; } function setTopicNbMessages(document, nbMessages) { let txt = `${nbMessages} messages`; if (!(nbMessages > 1)) { if (nbMessages === undefined) { txt = "? messages"; } else { txt = txt.slice(0, -1); } } document.getElementById("jvchat-topic-nb-messages").innerHTML = txt; } function triggerJVChat() { // TamperMonkey / Chrome bug: https://github.com/Tampermonkey/tampermonkey/issues/705#issuecomment-493895776 if (window) { if (window.clearTimeout) { window.clearTimeout = window.clearTimeout.bind(window); } if (window.clearInterval) { window.clearInterval = window.clearInterval.bind(window); } if (window.setTimeout) { window.setTimeout = window.setTimeout.bind(window); } if (window.setInterval) { window.setInterval = window.setInterval.bind(window); } window.onbeforeunload = function(event) { leavingTopic = true; } } let topicUrl = document.URL; let topic = parseTopicInfo(document); let user = parseUserInfo(document); let sondage = parseSondage(document); urlToFetch = parseURL(topicUrl); urlToFetch.page = 1; urlToFetch.anchor = ""; urlToCheckEdit = parseURL(topicUrl); urlToCheckEdit.page = 1; urlToCheckEdit.anchor = ""; loadConfig(); ringBell = new Audio(configuration["sound"]); clearPage(document); setUser(document, user); setTopicTitle(document, topic.title); setTopicNbMessages(document, undefined); setTopicNbConnected(document, topic.connected); if (sondage) { document.getElementById("jvchat-sondage").classList.remove("jvchat-hide") setSondage(sondage); } document.getElementById("jvchat-topic-title").setAttribute("href", buildURL(urlToFetch)); let forum = getForum(document); let forumSide = document.getElementById("jvchat-forum-title"); forumSide.setAttribute("href", forum.href); forumSide.innerHTML = forum.title; let defaultReduced = configuration["default_reduced"]; let messageTopic = document.getElementById("message_topic"); if (defaultReduced === false || (messageTopic && messageTopic.value !== "")) { toggleTextarea(); } let page = topic.lastPage > 1 ? topic.lastPage - 1 : topic.lastPage; updateMessages(page, true); setInterval(checkEdited, checkEditInterval); } function updateMessages(page, goToLast) { if (postingMessage && turboActivated) { // Postpone message fetching, posting the message is priorized fetchingMessages = false; currentTimeoutId = setTimeout(tryCatch(function() { updateMessages(page, goToLast); }), 100); return; } function scheduleNextUpdate(interval, p, goLast) { fetchingMessages = false; currentTimeoutId = setTimeout(tryCatch(function() { updateMessages(p, goLast); }), interval); }; function onSuccess(res) { let parsed = parsePage(res); let lastPage = parsed.lastPage; let currPage = parsed.page; let int = turboActivated ? configuration["turbo_delay"] : updateIntervals[updateIntervalIdx] * 1000; if (page < lastPage && goToLast) { updateMessages(page + 1, true); } else if (currPage < page || parsed.nbMessagesPage === 0) { // Bug des messages supprimés scheduleNextUpdate(int, page - 1, false); } else if (page > lastPage) { updateMessages(lastPage, true); } else { scheduleNextUpdate(int, page, true); } } function onError(err) { if (!isError) { isError = true; setFixedAlert("danger", err); } scheduleNextUpdate(turboActivated ? configuration["turbo_delay"] : 60000, page, true); } function onTimeout(err) { addAlertbox("warning", err); scheduleNextUpdate(turboActivated ? configuration["turbo_delay"] : 10000, page, true); } let timeout = 10000; if (turboActivated) { timeout = 5000; } fetchingMessages = true; currentFetchedPage = page; urlToFetch.page = page; let urlLastPage = buildURL(urlToFetch); request("GET", urlLastPage, onSuccess, onError, onTimeout, undefined, false, timeout); } function checkEdited() { if (!shouldCheckEdited || currentFetchedPage === 1 || isError) { return; } urlToCheckEdit.page = currentFetchedPage - 1; let urlPrevLastPage = buildURL(urlToCheckEdit); function onSuccess(res) { let newMessages = []; let edited = res.getElementsByClassName("info-edition-msg"); for (let msg of edited) { let bloc = msg.closest(".bloc-message-forum"); newMessages.push(parseMessage(bloc)); } addMessages(newMessages, true); } function onError() {} function onTimeout() {} request("GET", urlPrevLastPage, onSuccess, onError, onTimeout, undefined, false, 20000); } function parseAlerts(res) { let alerts = []; let alertsDiv = res.getElementsByClassName("alert"); for (let a of alertsDiv) { let type = "danger"; if (a.classList.contains("alert-warning")) { type = "warning"; } else if (a.classList.contains("alert-success")) { type = "success"; } let message = a.getElementsByClassName("alert-row")[0].textContent.trim(); alerts.push({type: type, message: message}); } return alerts; } function increaseUpdateInterval() { if (updateIntervalIdx < updateIntervalMax) { updateIntervalIdx++; } } function decreaseUpdateInterval() { updateIntervalIdx = transisitions[updateIntervalIdx]; } function parsePage(res) { let error = getTopicError(res); if (error !== undefined) { if (!isError) { updateIntervalIdx = updateIntervalMax; isError = true; setFixedAlert("danger", error); } return {lastPage: undefined, page: undefined, alert: true, nbMessagesPage: 0} } if (isError) { isError = false; updateIntervalIdx = 0; removeFixedAlert("Le topic ne retourne plus d'erreur"); } let form = getForm(res); if (form !== undefined) { freshForm = form; } let hash = getHash(res); if (hash !== undefined) { freshHash = hash; } let messages = getMessages(res); addMessages(messages); let user = parseUserInfo(res); setUser(document, user); let topic = parseTopicInfo(res); let nbMessages = (topic.lastPage - 1) * 20; if (topic.page == topic.lastPage) { nbMessages += messages.length; } setTopicNbMessages(document, nbMessages); setTopicNbConnected(document, topic.connected); let alerts = parseAlerts(res); for (let alert of alerts) { addAlertbox(alert.type, alert.message); } let locked = getTopicLocked(res); let isLocked_ = (locked !== undefined); if (isLocked_ && !isLocked) { updateInterval = updateIntervalMax; setFixedAlert("warning", locked); } else if (!isLocked_ && isLocked) { updateInterval = 0; removeFixedAlert("Le topic a été dévérouillé"); } isLocked = isLocked_; let sondage = parseSondage(res); if (sondage) { setSondage(sondage); } return {page: topic.page, lastPage: topic.lastPage, nbMessagesPage: messages.length, alert: isLocked_ || (alerts.length > 0)}; } function addAlertbox(type, message) { // type: success / warning / danger let alert = `
${message}
`; document.getElementById("jvchat-fixed-alert").insertAdjacentHTML("afterend", alert); } function setFixedAlert(type, message) { setFavicon("⨯"); document.getElementById("jvchat-fixed-alert").getElementsByClassName("alert-row")[0].innerHTML = message; document.getElementById("jvchat-fixed-alert").setAttribute("class", `alert alert-${type}`); } function removeFixedAlert(message) { document.getElementById("jvchat-fixed-alert").classList.add("jvchat-hide"); if (message !== undefined) { addAlertbox("success", message); } if (document.hidden && nbNewMessage > 0) { setFavicon(nbNewMessage > 99 ? 99 : nbNewMessage); } else { setFavicon(""); } } function makeJVChatButton() { let cls = 'btn-jvchat'; let text = 'JVChat'; let btn = ``; return btn; } function addJVChatButton(document) { let css = `` document.head.insertAdjacentHTML("beforeend", css); let blocPreRight = document.getElementsByClassName("bloc-pre-right"); let jvchatButton = makeJVChatButton(); for (let bloc of blocPreRight) { bloc.insertAdjacentHTML('afterbegin', jvchatButton); } } function bindJVChatButton(document) { let buttons = document.getElementsByClassName('btn-jvchat'); for (let btn of buttons) { btn.addEventListener('click', tryCatch(triggerJVChat)); } } function request(mode, url, callbackSuccess, callbackError, callbackTimeout, data, json, timeout) { json = !!json; let xhr = new XMLHttpRequest(); xhr.timeout = timeout; xhr.ontimeout = tryCatch(function() { callbackTimeout(`La délai d'attente de la requête a expiré`); }); xhr.onerror = tryCatch(function() { callbackError(`La requête a échoué (${xhr.status}): ${xhr.statusText}`); }); xhr.onabort = tryCatch(function() { if (!leavingTopic) { callbackTimeout(`La requête a été interrompue pour une raison inconnue`); } }); xhr.onload = tryCatch(function() { if (xhr.status !== 200) { callbackError(`La requête a retourné une erreur (${xhr.status}): ${xhr.statusText}`); return; } callbackSuccess(xhr.response); }); if (data === undefined) { data = null; } if (json) { xhr.responseType = "json"; } else { xhr.responseType = "document"; } xhr.open(mode, url, true); xhr.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate"); xhr.send(data); }; // On copie/colle le code de TopicLive et on se sent développeur :) function makeFavicon() { let canvas = document.createElement("canvas"); canvas.width = 16; canvas.height = 16; let context = canvas.getContext('2d'); let image = new Image(); image.src = 'data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABMLAAATCwAAAAAAAAAAAABkRgT/ZEYE/2RGBP9kRgT/ZEYE/2RGBf9lRgD/YEcV/zJW7v8tV///Llf+/y5X//8uV///Llf//y5X//8uV///ZEYE/2RGBP9kRgT/ZEYE/2RGBP9kRgX/ZUYA/2BHFf8yVu7/LVf//y5X/v8uV///Llf//y5X//8uV///Llf//2RGBP9kRgT/ZEYE/2VHBf9lRwX/ZEYF/2VGAP9gRxX/Mlbu/y1X//8uV/7/Llf//y5X//8uV///Llf//y5X//9kRgT/ZEcF/2ZIB/9iQwH/YkMB/2ZJCP9lRgD/YEcV/zJW7v8tV///L1f+/y1W//8tVv//L1j//y5X//8uV///ZUcE/2NFBP9ZOQD/bE8R/2xPEf9ZOQD/ZEQA/2FIFv8xVu7/Llj//yxV/v8uV///Llf//ytV//8vWP//Llf//2NFA/9kRgj/xLif/+7r5P/u6+T/w7if/2VGBP9fRhT/M1fv/yxW//8uV/7/1d3//9Xd//8uV///LVb//y9Y//9ZOQD/wLOZ/9/Yy/91WiD/dVog/97Yy//CtZj/VzsF/zFW8f8tV///L1f+/9Lb///S2///L1f//y5X//8rVf//bFAR/+nk2v91Wib/WzsA/1s7AP90Wif/7OfZ/2dQIv8wU+v/1d7//9Pb/v8tVv//LVb//9Pc///S2///Llf//2xQEf/p5Nr/dVom/1s7AP9bOwD/dFon/+zn2f9nUCL/MFPr/9Xe///T2/7/LVb//y1W///T3P//0tv//y5X//9ZOQD/wLOZ/9/Yy/91WiD/dVog/97Yy//CtZj/VzsF/zFW8f8tV///L1f+/9Lb///S2///L1f//y5X//8rVf//Y0UD/2RGCP/EuJ//7uvk/+7r5P/DuJ//ZUYE/19GFP8zV+//LFb//y5X/v/V3f//1d3//y5X//8tVv//L1j//2VHBP9jRQT/WTkA/2xPEf9sTxH/WTkA/2REAP9hSBb/MVbu/y5Y//8sVf7/Llf//y5X//8rVf//L1j//y5X//9kRgT/ZEcF/2ZIB/9iQwH/YkMB/2ZJCP9lRgD/YEcV/zJW7v8tV///L1f+/y1W//8tVv//L1j//y5X//8uV///ZEYE/2RGBP9kRgT/ZUcF/2VHBf9kRgX/ZUYA/2BHFf8yVu7/LVf//y5X/v8uV///Llf//y5X//8uV///Llf//2RGBP9kRgT/ZEYE/2RGBP9kRgT/ZEYF/2VGAP9gRxX/Mlbu/y1X//8uV/7/Llf//y5X//8uV///Llf//y5X//9kRgT/ZEYE/2RGBP9kRgT/ZEYE/2RGBf9lRgD/YEcV/zJW7v8tV///Llf+/y5X//8uV///Llf//y5X//8uV///AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='; return {canvas: canvas, context: context, image: image}; }; function clearFavicon() { favicon.context.clearRect(0, 0, favicon.canvas.width, favicon.canvas.height); favicon.context.drawImage(favicon.image, 0, 0); }; function fillFavicon(txt) { clearFavicon(); if (txt !== '') { let context = favicon.context; context.fillStyle = 'DodgerBlue'; context.fillRect(0, 0, context.measureText(txt).width + 3, 11); context.fillStyle = 'white'; context.font = 'bold 10px Verdana'; context.textBaseline = 'bottom'; context.fillText(txt, 1, 11); } }; function setFavicon(txt) { let fav = document.getElementById("jvchat-favicon"); if (fav) { fav.parentElement.removeChild(fav); } fillFavicon(txt); let url = favicon.canvas.toDataURL('image/png'); let icon = ``; document.head.insertAdjacentHTML("beforeend", icon); } function reverseMessage(blocMessage) { let node = blocMessage.getElementsByClassName("txt-msg")[0].cloneNode(true); for (let child of Array.from(node.childNodes)) { if (!child.insertAdjacentHTML) { child.outerHTML = ""; continue; } child.outerHTML = `${child.outerHTML}\n\n`; } for (let br of Array.from(node.getElementsByTagName("br"))) { br.outerHTML = ""; } for (let link of Array.from(node.getElementsByTagName("a"))) { link.outerHTML = link.getAttribute("href"); } for (let sticker of Array.from(node.getElementsByClassName("img-stickers"))) { sticker.outerHTML = sticker.getAttribute("alt"); } for (let img of Array.from(node.getElementsByTagName("img"))) { img.outerHTML = img.getAttribute("alt"); } for (let strong of Array.from(node.getElementsByTagName("strong"))) { strong.outerHTML = `'''${strong.innerHTML}'''`; } for (let em of Array.from(node.getElementsByTagName("em"))) { em.outerHTML = `''${em.innerHTML}''`; } for (let u of Array.from(node.getElementsByTagName("u"))) { u.outerHTML = `${u.innerHTML}`; } for (let pre of Array.from(node.getElementsByTagName("pre"))) { pre.outerHTML = pre.innerHTML; } for (let code of Array.from(node.getElementsByClassName("code-jv"))) { code.outerHTML = `${code.innerHTML}`; } let spoils = Array.from(node.getElementsByClassName("bloc-spoil-jv")); spoils.reverse(); for (let spoil of spoils) { spoil.outerHTML = `${spoil.getElementsByClassName("contenu-spoil")[0].innerHTML}` } let uls = Array.from(node.getElementsByTagName("ul")); uls.reverse(); for (let ul of uls) { for (let li of Array.from(ul.getElementsByTagName("li"))) { let end = li.textContent.endsWith("\n") ? "" : "\n"; li.outerHTML = `* ${li.innerHTML}${end}`; } ul.outerHTML = ul.innerHTML } let ols = Array.from(node.getElementsByTagName("ol")); ols.reverse(); for (let ol of ols) { for (let li of Array.from(ol.getElementsByTagName("li"))) { let end = li.textContent.endsWith("\n") ? "" : "\n"; li.outerHTML = `# ${li.innerHTML}${end}`; } ol.outerHTML = ol.innerHTML; } let quotes = Array.from(node.getElementsByClassName("blockquote-jv")); quotes.reverse(); for (let quote of quotes) { let content = ""; for (let child of Array.from(quote.childNodes)) { let childText = child.innerHTML !== undefined ? child.innerHTML : child.textContent; content += childText + '\n\n'; } let quoted = '> ' + content.split(/\n/).join('\n> '); quote.outerHTML = `

${quoted}

`; } let ps = Array.from(node.getElementsByTagName("p")); ps.reverse(); for (let p of ps) { p.outerHTML = p.innerHTML; } let txt = node.innerHTML.replace(/>/g, '>').replace(/</g, '<').replace(/&/g, '&').trim(); return txt; } function reverseQuote(blocMessage) { let author = blocMessage.getElementsByClassName("jvchat-author")[0].textContent.trim(); let date = blocMessage.getElementsByClassName("jvchat-date")[0].getAttribute("to-quote"); let header = `> Le ${date} ${author} a écrit :\n`; let txt = reverseMessage(blocMessage); let quoted = '> ' + txt.split(/\n/).join('\n> '); return header + quoted + '\n\n'; } function insertAtCursor(input, textToInsert) { const value = input.value; const start = input.selectionStart; const end = input.selectionEnd; input.value = value.slice(0, start) + textToInsert + value.slice(end); input.selectionStart = input.selectionEnd = start + textToInsert.length; } function dontScrollOnExpand(event) { let target = event.target; if (!target) { return; } let classes = target.classList; if (classes.contains("blockquote-jv")) { let isDown = isScrollDown(); target.setAttribute('data-visible', '1'); if (isDown) { setScrollDown(); } } else if (classes.contains("txt-spoil") || classes.contains("aff-spoil") || classes.contains("masq-spoil")) { event.preventDefault(); let check = target.closest(".bloc-spoil-jv").getElementsByClassName("open-spoil")[0]; let isDown = isScrollDown(); check.checked = !check.checked; if (isDown) { setScrollDown(); } } else if (classes.contains("jvchat-quote")) { let bloc = target.closest(".jvchat-message"); let quote = reverseQuote(bloc); let textarea = document.getElementById("message_topic"); if (isReduced) { toggleTextarea(); } insertAtCursor(textarea, quote); textarea.focus(); } else if (classes.contains("jvchat-edit")) { let bloc = target.closest(".jvchat-message"); requestEdit(bloc); } else if (classes.contains("jvchat-edition-check")) { let bloc = target.closest(".jvchat-message"); editMessage(bloc); } else if (classes.contains("jvchat-edition-cancel")) { let bloc = target.closest(".jvchat-message"); let isDown = isScrollDown(); bloc.getElementsByClassName("jvchat-content")[0].classList.remove("jvchat-hide"); bloc.getElementsByClassName("jvchat-edition")[0].classList.add("jvchat-hide"); if (isDown) { setScrollDown(); } } } function isScrollDown() { let element = document.getElementById("jvchat-main"); return element.clientHeight + Math.floor(element.scrollTop) >= element.scrollHeight - 1; } function setScrollDown() { let element = document.getElementById("jvchat-main"); element.scrollTop = element.scrollHeight + 10000; } function main() { addJVChatButton(document); bindJVChatButton(document); } main();