// ==UserScript== // @name [HFR] Apercu des posts dans la reponse/edition rapide // @version 0.2.4 // @namespace http://toyonos.info // @description Rajoute l'aperçu du message dans la réponse rapide et dans l'édition rapide du forum hardware.fr // @include http://forum.hardware.fr/* // @exclude http://forum.hardware.fr/message.php* // ==/UserScript== //Lib de generation de l'apercu (provenant de mdenhance) // uses code from Freekil (hfrenhance v1) var BBParser = { lieu : "http://forum-images.hardware.fr/icones/", //"../../../icones/"; lieuPerso : "http://forum-images.hardware.fr/images/perso/", //"../../../images/perso/"; parse: function(str) { str = str.replace(/,/gi,','); // Trouve les balises fixed var fixed = str.match(/(\[fixed\])((\n|.)+?)(\[\/fixed\])/gi); if (fixed) { fixed = fixed.toString(); } // Trouve les balises cpp var cpp = str.match(/(\[cpp\])((\n|.)+?)(\[\/cpp\])/gi); if (cpp) { cpp = cpp.toString(); } // Trouve les balises code var code = str.match(/(\[code(=[a-z0-9]+)?\])((\n|.)+?)(\[\/code\])/gi); if (code) { code = code.toString(); } str = str.replace(/,/gi,','); str = BBParser.htmlSpecialChars(str); str = BBParser.parseOwnSmilies(str); str = BBParser.parseBaseSmilies(str); str = BBParser.parseStyle(str); str = BBParser.parseExternal(str); str = BBParser.parseLists(str); str = BBParser.parseBlocks(str); // Special pour les balises fixed if (fixed) { fixed = fixed.split(','); for(i=0;i\n" ); thisfixed = thisfixed.replace(/ /gi,' '); str = str.replace( /(\[fixed\])((\n|.)+?)(\[\/fixed\])/,'
'+thisfixed+'
'); } } // Special pour les balises cpp if (cpp) { cpp = cpp.split(','); for(i=0;i
$2 
'); // each line is an ol list element thiscode = thiscode.replace(/\n/gi,''); // we're using a pre block, so we must remove line breaks str = str.replace( /(\[cpp\])((\n|.)+?)(\[\/cpp\])/,'
Code :
    '+thiscode+'
'); } } // Special pour les balises code if (code) { code = code.split(','); for(i=0;i
$2 
'); thiscode = thiscode.replace(/\n/gi,''); str = str.replace( /(\[code(=[a-z0-9]+)?\])((\n|.)+?)(\[\/code\])/,'
Code :
    '+thiscode+'
'); } } //str = htmlSpecialChars(str); return str; }, parseBaseSmilies: function(str) { var smilies = { gratgrat: ':gratgrat:', ange: ':ange:', benetton: ':benetton:', bic: ':bic:', bounce: ':bounce:', bug: ':bug:', crazy: ':crazy:', cry: ':cry:', dtc: ':dtc:', eek: ':eek:', eek2: ':eek2:', evil: ':evil:', fou: ':fou:', foudtag: ':foudtag:', fouyaya: ':fouyaya:', fuck: ':fuck:', gun: ':gun:', hebe: ':hebe:', heink: ':heink:', hello: ':hello:', hot: ':hot:', //int: ':int:', //can't use int, reserved word, see below jap: ':jap:', kaola: ':kaola:', lol: ':lol:', love: ':love:', mad: ':mad:', mmmfff: ':mmmfff:', na: ':na:', non: ':non:', ouch: ':ouch:', ouimaitre: ':ouimaitre:', pfff: ':pfff:', pouah: ':pouah:', pt1cable: ':pt1cable:', sarcastic: ':sarcastic:', sleep: ':sleep:', sol: ':sol:', spamafote: ':spamafote:', spookie: ':spookie:', sum: ':sum:', sweat: ':sweat:', vomi: ':vomi:', wahoo: ':wahoo:', whistle: ':whistle:' } var regexp; for (code in smilies) { regexp = new RegExp(smilies[code], 'gi'); // get regexp from object str = str.replace(regexp, '' + code + ''); } // fix for 'int' smiley str = str.replace(/:int:/gi, 'int'); var smilies2 = { confused: /([^\[]|^):\?\?:/gi, smile: /([^\[]|^):\)/gi, frown: /([^\[]|^):\(/gi, redface: /([^\[]|^):o/gi, biggrin: /([^\[]|^):D/gi, wink: /([^\[]|^);\)/gi, tongue: /([^\[]|^):p/gi, ohill: /([^\[]|^):\'\(/gi, ohwell: /([^\[]|^)(:\/)(?!\/)/gi // this one need a particular regex to avoid mixing up with urls } for (code in smilies2) { str = str.replace(smilies2[code], '$1' + code + ''); } return str; }, parseOwnSmilies: function(str) { str = str.replace( /\[:([^\]]+):(\d+)]/gi, '[:$1:$2]'); str = str.replace( /\[:([^\]:]+)]/gi, '[:$1]'); return str; }, parseStyle: function(str) { str = str.replace( /\[[su]\]((\n|.)+?)\[\/[su]\]/gi, '$1'); str = str.replace( /\[[bg]\]((\n|.)+?)\[\/[bg]\]/gi, '$1'); str = str.replace( /\[i\]((\n|.)+?)\[\/i\]/gi, '$1'); str = str.replace( /\[strike\]((\n|.)+?)\[\/strike\]/gi, '$1'); str = str.replace( /\[(#[a-f0-9]{6})\]((\n|.)+?)\[\/#([a-f0-9]{6})\]/gi, '$2' ); return str; }, parseExternal: function(str) { str = str.replace( /\[img\]([a-z]+:\/\/[^ \n\r]+?)\[\/img\]/gi, '$1'); str = str.replace( /\[url=([a-z]+:\/\/(www\.)?[^ \n\r\[\<]+)\](.+?)\[\/url\]/gi, '$3'); str = str.replace( /\[url\]([a-z]+:\/\/(www\.)?[^ \n\r\[\<]+)\[\/url\]/gi, '$1'); str = str.replace( /\[email\]([\w\.-]+@[\w\.-]+)\[\/email\]/gi, '$1'); str = str.replace( /(^|[\r\n \]\>])([a-z]+:\/\/(www\.)?[^ \n\r\<\[]+)/gi, '$1$2'); return str; }, parseLists: function(str) { str = str.replace( /((\[\*\](.*)(\r)?(\n))*(\[\*\][^\n]*))/gi, "
    $1
"); str = str.replace( /\[\*\]([^\n]*(\n|$))/gi, "
  • $1
  • " ); return str; }, parseBlocks: function(str) { var debutSpoiler, finSpoiler; var spoilers = str.match( /\[spoiler\]((\n|.)+?)\[\/spoiler\]/gi, debutSpoiler+"$1"+finSpoiler ); if (spoilers) { for(i=0; i Spoiler :

    '; str = str.replace( /\[spoiler\]((\n|.)+?)\[\/spoiler\]/i, debutSpoiler+"$1"+finSpoiler ); } } var debutCit = '
    '; var finCit = '
    '; str = str.replace( /\[citation\]\[nom\](.+?)\[\/nom]((\n|.)+?)\[\/citation\]/gi, debutCit+'$1

    $2

    '+finCit ); str = str.replace( /\[quotemsg=(.+?)\]((.|\n)+?)\[\/quotemsg\]/gi, debutCit+'Quelqu\'un a ecrit

    $2

    '+finCit ); var debutQuote = '
    Citation :

    '; var finQuote = '

    '; str = str.replace( /(\[quote\])((\n|.)+?)(\[\/quote\])/gi, debutQuote+"$2"+finQuote ); // Special quotes imbriques var quotes = str.match(/\[quote\]((\n|.)+?)\[\/quote\]/gi); if (quotes) { for(i=0;i/gi,'>'); str = str.replace(/,/gi,','); // fix code with a , in it str = str.replace(/ /gi, '  '); // fix for multiple spaces str = str.replace(/\n/g, "
    \n" ); return str; } } /***************************************************************/ var timer; var timerOpacity; var getElementByXpath = function (path, element) { var arr = Array(), xpr = document.evaluate(path, element, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); for (;item = xpr.iterateNext();) arr.push(item); return arr; } var clearPreview = function() { var container = document.getElementById('apercu_reponse'); container.style.display = 'none'; container.style.opacity = 1; } var fadeAway = function() { var opacity = 1; timerOpacity = setInterval(function() { var container = document.getElementById('apercu_reponse'); opacity -= 0.01; container.style.opacity = opacity; if (opacity < 0) clearPreview() } , 1); } var launchFading = function() { clearTimeout(timer); clearInterval(timerOpacity); document.getElementById('apercu_reponse').style.opacity = 1; timer = setTimeout(fadeAway, 5000); } var generatePreview = function (textAreaId) { var container; if (!document.getElementById('apercu_reponse')) { container = document.createElement('div'); container.id = 'apercu_reponse'; container.style.position = 'absolute'; container.style.textAlign = 'left'; container.style.backgroundColor = 'rgb(247, 247, 247)'; container.style.overflow = 'auto'; container.style.padding = '5px'; container.style.width = '80%'; container.style.maxHeight = '200px'; container.style.border = '1px solid black'; container.style.fontSize = '13px'; container.style.left = '10%'; container.addEventListener('scroll', launchFading, false); document.getElementById('mesdiscussions').appendChild(container); } else { container = document.getElementById('apercu_reponse'); } var content = document.getElementById(textAreaId); container.style.top = window.scrollY + 10 + 'px'; container.innerHTML = BBParser.parse(content.value); if (container.scrollTop == 0 || container.style.display == 'block') launchFading(); container.style.display = content.value == '' ? 'none' : 'block'; var pourcentage = content.value.slice(0, content.selectionStart).split('\n').length * 100 / content.value.split('\n').length; pourcentage = pourcentage < 1 ? 0 : pourcentage; var noScrollLimit = parseInt(container.style.maxHeight) * 100 / container.scrollHeight; container.scrollTop = pourcentage > noScrollLimit ? (container.scrollHeight * (pourcentage - noScrollLimit + 1) / 100) + (parseInt(container.style.maxHeight) / 2) : 0; } window.addEventListener('scroll', function() { var container = document.getElementById('apercu_reponse'); if (container && container.style.opacity == 1) { container.style.top = window.scrollY + 10 + 'px'; } } , false); /* Gestion de la reponse rapide */ if (document.getElementById('content_form')) { document.getElementById('content_form').addEventListener('keyup', function () { generatePreview('content_form'); } , false); } /* Gestion de l'edit rapide */ var root = document.getElementById('mesdiscussions'); getElementByXpath('.//table//tr[starts-with(@class, "message")]//div[@class="left"]//a[starts-with(@href, "/message.php")]//img[@alt="Edition rapide"]', root) .forEach(function(img) { var onclickCommand = img.parentNode.getAttribute('onclick'); var numreponse = onclickCommand.match(/edit_in\('.*','.*',[0-9]+,([0-9]+),''\)/).pop(); img.parentNode.addEventListener('click', function() { var timer = setInterval(function() { if (document.getElementById('rep_editin_' + numreponse)) { clearInterval(timer); document.getElementById('rep_editin_' + numreponse).addEventListener('keyup', function () { generatePreview('rep_editin_' + numreponse); } , false); var buttonValide = document.getElementById('rep_editin_' + numreponse).nextSibling.firstChild; buttonValide.addEventListener('click', clearPreview, false); buttonValide.nextSibling.addEventListener('click', clearPreview, false); } } , 500); } , false); }); // ============ Module d'auto update du script ============ ({ check4Update : function() { var autoUpdate = this; var mirrorUrl = GM_getValue('mirrorUrl', 'null'); if (mirrorUrl == 'null') autoUpdate.retrieveMirrorUrl(); var currentVersion = GM_getValue('currentVersion', '0.2.4'); // On met éventuellement la version stockée à jour avec la version courante, si la version courante est plus récente if (autoUpdate.isLater('0.2.4', currentVersion)) { GM_setValue('currentVersion', '0.2.4'); currentVersion = '0.2.4'; } // Par contre, si la version stockée est plus récente que la version courante -> création un menu d'update pour la dernière version else if (autoUpdate.isLater(currentVersion, '0.2.4')) { GM_registerMenuCommand("[HFR] Apercu des posts dans la reponse/edition rapide -> Installer la version " + currentVersion, function() { GM_openInTab(mirrorUrl + 'apercu_reponse_rapide.user.js'); } ); } // Si la version courante et la version stockée sont identiques, on ne fait rien if (GM_getValue('lastVersionCheck') == undefined || GM_getValue('lastVersionCheck') == '') GM_setValue('lastVersionCheck', new Date().getTime() + ''); // Pas eu de check depuis 24h, on vérifie... if ((new Date().getTime() - GM_getValue('lastVersionCheck')) > 86400000 && mirrorUrl != 'null') { var checkUrl = mirrorUrl + 'getLastVersion.php5?name=' + encodeURIComponent('[HFR] Apercu des posts dans la reponse/edition rapide'); if (isNaN(currentVersion.substring(currentVersion.length - 1))) checkUrl += '&sversion=' + currentVersion.substring(currentVersion.length - 1); GM_xmlhttpRequest({ method: "GET", url: checkUrl, onload: function(response) { var regExpVersion = new RegExp('^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}[a-zA-Z]?$'); var lastVersion = response.responseText; // Pas d'erreur et nouvelle version plus récente if (lastVersion != '-1' && regExpVersion.test(lastVersion) && autoUpdate.isLater(lastVersion, currentVersion)) { if (confirm('Une nouvelle version de [HFR] Apercu des posts dans la reponse/edition rapide est disponible : ' + lastVersion + '\nVoulez-vous l\'installer ?')) { GM_openInTab(mirrorUrl + 'apercu_reponse_rapide.user.js'); } else { // Mémorisation de la version refusée : elle servira de version de référence GM_setValue('currentVersion', lastVersion); } } GM_setValue('lastVersionCheck', new Date().getTime() + ''); } }); } }, max : function(v1, v2) { var tabV1 = v1.split('.'); var tabV2 = v2.split('.'); if (isNaN(tabV1[2].substring(tabV1[2].length - 1))) tabV1[2] = tabV1[2].substring(0, tabV1[2].length - 1); if (isNaN(tabV2[2].substring(tabV2[2].length - 1))) tabV2[2] = tabV2[2].substring(0, tabV2[2].length - 1); if ((tabV1[0] > tabV2[0]) || (tabV1[0] == tabV2[0] && tabV1[1] > tabV2[1]) || (tabV1[0] == tabV2[0] && tabV1[1] == tabV2[1] && tabV1[2] > tabV2[2])) { return v1; } else { return v2; } }, isLater : function(v1, v2) { return v1 != v2 && this.max(v1, v2) == v1; }, retrieveMirrorUrl : function() { var mirrors = 'http://hfr.toyonos.info/gm/;http://hfr-mirror.toyonos.info/gm/'.split(';'); var checkMirror = function (i) { var mirror = mirrors[i]; GM_xmlhttpRequest({ url: mirror + 'getLastVersion.php5', method: "HEAD", onload: function(response) { // Dès qu'un miroir répond, on le mémorise. if (response.status == 200) { GM_setValue('mirrorUrl', mirror); } else { // Sinon on test le prochain if ((i + 1) < mirrors.length) { checkMirror(i + 1); } else { GM_setValue('mirrorUrl', 'null'); } } } }); }; checkMirror(0); }, }).check4Update();