NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name SA:MP Forum Enhancer // @namespace https://y-less.com/ // @version 0.2 // @copyright 2018, Alex "Y_Less" Cole // @license MPL-2.0 // @description Enhance the SA:MP forums. // @author Y_Less // @match http://forum.sa-mp.com/* // @grant GM_xmlhttpRequest // ==/UserScript== // ==OpenUserJS== // @author y-less // @collaborator y-less // ==/OpenUserJS== (function() { 'use strict'; var STYLE = ''; function replaceTextAndSubmit(form, textbox) { try { // Submit it to AWS 'forumfmt' to convert to BB code. GM_xmlhttpRequest({ method: 'POST', url: 'https://ns3prdlla4.execute-api.eu-west-1.amazonaws.com/prod/markdown-post', contentType: 'application/json', headers: { 'User-Agent': 'ForumEnhancer', 'Accept': 'application/json', }, onload: function (details) { // Paste the new text in to the textbox. var text = JSON.parse(details.response).BB; if (text) { textbox.value = text; form.submit(); } else { alert('Could not retrieve BB code:'); console.error('Could not retrieve BB code:'); console.error(details); } }, onerror: function (details) { alert('Could not retrieve BB code:'); console.error(details); }, // Get the text. data: JSON.stringify({ MD: textbox.value, Style: STYLE, }).replace('\t', '\\t'), }); } catch (e) { alert('Could not retrieve BB code:'); console.error(e); } } function doTab(textbox, shift) { var start = textbox.selectionStart; // Mark the bounds of the selection. var end = textbox.selectionEnd; // Mark the bounds of the selection. var text = textbox.value; var next = text.indexOf('\n', start); var prev = text.lastIndexOf('\n', start) + 1; if (next >= end || next === -1) { if (shift) { // Unindent, or go to the start of the line. if (text[prev] === '\t') { textbox.value = text.substring(0, prev) + text.substring(prev + 1); textbox.selectionStart = textbox.selectionEnd = Math.max(prev, start - 1); } } else { // Point or single line: Just add a tab here. textbox.value = text.substring(0, start) + '\t' + text.substring(end); textbox.selectionStart = textbox.selectionEnd = start + 1; } } else { // Multi-line: Indent. // First, collect the lines to indent. var begin = prev; var finish; // Mark the bounds of the affected lines. var lines = []; // Put the affected lines in an array. for ( ; ; ) { next = text.indexOf('\n', prev); if (next === -1) { lines.push(text.substring(prev)); finish = text.length; break; } else { lines.push(text.substring(prev, next)); if (next >= end) { finish = next; break; } else { prev = next + 1; } } } // Debug print the lines. if (shift) { var reduced = 0; // Backwards - harder! textbox.value = text.substring(0, begin) + lines.map(function (x) { if (x[0] === '\t') { ++reduced; return x.substring(1); } else { return x; } }).join('\n') + text.substring(finish); // Reselect from `start - 1` to `end - number of lines` (depending on how many lines were // actually changed). textbox.selectionStart = (lines[0][0] === '\t') ? Math.max(begin, start - 1) : start; textbox.selectionEnd = end - reduced + ((text[end - 1] === '\n' && text[end] === '\t') ? 1 : 0); } else { // Forwards - easy! textbox.value = text.substring(0, begin) + lines.map(function (x) { return '\t' + x; }).join('\n') + text.substring(finish); // Reselect from `start + 1` to `end + number of lines`. textbox.selectionStart = start + 1; textbox.selectionEnd = end + lines.length; } } } window.addEventListener('load', function(e) { var textbox = document.getElementById('vB_Editor_001_textarea') || document.getElementById('vB_Editor_QR_textarea'); if (textbox) { var form = textbox.form; textbox.addEventListener('keydown', function (event) { if (event.keyCode === 9 && !event.ctrlKey && !event.altKey && !event.metaKey) { // Pressed "tab", but not something like "ctrl+tab". doTab(textbox, event.shiftKey); event.stopPropagation(); event.preventDefault(); } else if (event.keyCode === 13 && !event.shiftKey && event.ctrlKey && !event.altKey && !event.metaKey) { // ctrl-enter. if (form.onsubmit.call(form, {})) { // Must use ".call", ignore Tampermonkey! // The default submission handler didn't prevent us submitting. replaceTextAndSubmit(form, textbox); } // Don't submit it here, we'll do that shortly when the data is returned. event.stopPropagation(); event.preventDefault(); } }); form.addEventListener('submit', function (event) { if (!event.defaultPrevented) { // `prepare_submit` didn't stop us. replaceTextAndSubmit(form, textbox) } event.stopPropagation(); event.preventDefault(); // Don't submit it here, we'll do that shortly when the data is returned. }); } }, false); })();