WBB Quick Reply Plus

Adds More formatting buttons to Quick/Standard Reply

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name          WBB Quick Reply Plus
// @namespace     erosman
// @description   Adds More formatting buttons to Quick/Standard Reply
// @include       http://www.warez-bb.org/viewtopic.php*
// @include       http://www.warez-bb.org/posting.php*
// @include       http://www.warez-bb.org/privmsg.php*
// @exclude       http://www.warez-bb.org/privmsg.php?folder=*
// @include       https://www.warez-bb.org/viewtopic.php*
// @include       https://www.warez-bb.org/posting.php*
// @include       https://www.warez-bb.org/privmsg.php*
// @exclude       https://www.warez-bb.org/privmsg.php?folder=*
// @grant         none
// @author        erosman
// @version       1.8
// ==/UserScript==


/* --------- Note ---------
  This script adds more formatting options (B, i, u, List, List=) to the Quick Reply Box
  as well as Quote=, Font Size & Font Colour
  Also new functionality of 'RemoveTag', 'To Uppercase', 'To Lowercase' & 'TitleCase'
  Script now adds the functionality to Quick Reply, Normal Reply with/without Quote,
  PM reply and their Preview pages


  --------- History ---------

  1.8 Code rewrite + New DOM insertion method + Removed 'List=' since it is not supported on WBB
      + Added [*] + Added BB2 compatibility
  1.7 Code Improvement
  1.6 Code Improvement + Removed Capitalize (can be done with TitleCase)
  1.5 New RemoveTags function + Minor CSS change
  1.4 Code Improvement + Added Quote= (which is valid but is missing from phpBB inputs)
      + Added Font Size + Added Font Colour
  1.3 Code Improvement + Added PM pages
  1.2 Added TitleCase and new functions + Added script to reply page + Preview page
      + Error checking on phpBB post redirect page
  1.1 Added toLower, toUpper & Capitalize
  1.0 Initial release

*/


(function() { // anonymous function wrapper, used for error checking & limiting scope
'use strict'; // ECMAScript 5
if (frameElement) { return; } // end execution if in a frame, object or other embedding points

var BB3 = document.querySelector('link[href*="main.css"]') ? true : false; // BB2/BB3 check

var textarea = document.getElementById('message');
if (!textarea) { return; }  // end execution if not found

var bbcode = BB3 ? document.querySelector('div.bbcode') : textarea.parentNode;
if (!bbcode) { return; }  // end execution if not found


function makeChange() {

  var obj = textarea;
  obj.selectionEnd = obj.selectionEnd > obj.value.length ? obj.value.length : obj.selectionEnd;
  var startPos = obj.selectionStart;
  var endPos = obj.selectionEnd > obj.selectionStart ? obj.selectionEnd : obj.selectionStart;
  var openTaglength = 0;
  var tagLength = 0;
  var theSelection = obj.value.substring(startPos, endPos);
  var noSelection = 'Nothing was selected';
  var addTag = false;
  var tag, startTag, endTag;

  switch (this.value) {

    /* Actions */
    case 'toLower':
      theSelection.trim() ? theSelection = theSelection.toLowerCase() : alert(noSelection);
      break;
    case 'toUpper':
      theSelection.trim() ? theSelection = theSelection.toUpperCase() : alert(noSelection);
      break;
    case 'TitleCase':
      theSelection.trim() ? theSelection = toTitleCase(theSelection) : alert(noSelection);
      break;

    case 'RemoveTag':
      if (theSelection.trim()) {
        var ret = removeTag(theSelection);
        theSelection = ret[0];
        tagLength = ret[1];
      }
      else { alert(noSelection); }
      break;

    /* Tags */
    case 'B':
    case 'i':
    case 'u':
    case 'List':
      tag = this.value.toLowerCase();
      startTag = '[' + tag + ']';
      endTag = '[/' + tag + ']';
      addTag = true;
      break;

//    case 'List=':
    case 'Quote=':
      tag = this.value.toLowerCase();
      startTag = '[' + tag + '""]';
      endTag = '[/' + tag.slice(0, -1) + ']';
      addTag = true;
      break;

    case '[*]':
      startTag = this.value;
      endTag = '';
      addTag = true;
      break;

    default: // select options
      startTag = '[' + this.id + '=' + this.value + ']';
      endTag = '[/' + this.id + ']';
      addTag = true;
      this.selectedIndex = this.id === 'color' ? 0 : 2;
  }

  if (addTag) {
    theSelection = startTag + theSelection + endTag;
    openTaglength = startTag.length;
  }

  obj.value = obj.value.substring(0,startPos) + theSelection + obj.value.substring(endPos);
  obj.selectionStart = startPos + openTaglength;
  obj.selectionEnd = endPos + openTaglength - tagLength;
  obj.focus();
}

function toTitleCase(txt) {
  return txt.replace(/\w\S*/g,
    function (str) {
      return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
    });
}

function removeTag(txt) {
  var pat = /\[\/?(b|i|u|img|code|quote[^\]]*|\*|list[^\]]*|color[^\]]*|size[^\]]*)\]/gi;
  return [txt.replace(pat, ''), (txt.match(pat) || []).join('').length];
}

/* ----- Inputs ----- */
var buttons1 = [

  { value: 'Quote=', class: 'first-button' },
  { value: 'RemoveTag' },
  { value: 'toLower'},
  { value: 'toUpper' },
  { value: 'TitleCase', class: 'last-button' },
];

var buttons2 = [

  { accesskey: 'b', value: 'B', style: 'font-weight: bold;', class: 'first-button' },
  { accesskey: 'i', value: 'i', style: 'font-style: italic;' },
  { accesskey: 'u', value: 'u', style: 'text-decoration: underline;' },
  { accesskey: 'l', value: 'List' },
  { value: '[*]', class: 'last-button' },
//  { accesskey: 'o', value: 'List=', class: 'last-button' },

];

var options1 = [ // Font colour:

  { value: '#', textContent: 'Default' },
  { value: 'darkred', textContent: 'Dark Red', style: 'color: darkred;' },
  { value: 'red', textContent: 'Red', style: 'color: red;' },
  { value: 'orange', textContent: 'Orange', style: 'color: orange;' },
  { value: 'brown', textContent: 'Brown', style: 'color: brown;' },
  { value: 'yellow', textContent: 'Yellow', style: 'color: yellow;' },
  { value: 'green', textContent: 'Green', style: 'color: green;' },
  { value: 'olive', textContent: 'Olive', style: 'color: olive;' },
  { value: 'cyan', textContent: 'Cyan', style: 'color: cyan;' },
  { value: 'blue', textContent: 'Blue', style: 'color: blue;' },
  { value: 'darkblue', textContent: 'Dark Blue', style: 'color: darkblue;' },
  { value: 'indigo', textContent: 'Indigo', style: 'color: indigo;' },
  { value: 'violet', textContent: 'Violet', style: 'color: violet;' },
  { value: 'white', textContent: 'White', style: 'color: white;' },
  { value: 'black', textContent: 'Black', style: 'color: black;' },
];

var options2 = [ // Font size:

  { value: 7, textContent: 'Tiny' },
  { value: 9, textContent: 'Small' },
  { value: 12, textContent: 'Normal',  selected: 'selected'},
  { value: 18, textContent: 'Large' },
  { value: 24, textContent: 'Huge' },
];


function addNode(obj, templateNode, parentNode) {

  var node = templateNode.cloneNode(false);
  if (node.nodeName === 'INPUT') { node.addEventListener('click', makeChange, false); }

  for (var prop in obj) {
    prop === 'textContent' ? node.textContent = obj[prop] : node.setAttribute(prop, obj[prop]);
  }
  parentNode.appendChild(node);
}


// insert the extra elements in the page

/* ----- templates ----- */
var br = document.createElement('br');
br.setAttribute('style', 'clear: both;');
var input = document.createElement('input');
input.type = 'button';
// empty DocumentFragment object as a temporary container for the elements
var docfrag = document.createDocumentFragment();

if (!BB3) { docfrag.appendChild(br.cloneNode(false)); } // BB2 only

// All Pages (View Topic +  Post)
for (var i = 0, len = buttons1.length; i < len; i++) { addNode(buttons1[i], input, docfrag); }

// View Topic Pages
if (document.URL.indexOf('viewtopic.php') !== -1) {

  // template
  var select = document.createElement('select');
  select.setAttribute('style', 'padding: 0;');
  var option = document.createElement('option');

  docfrag.appendChild(br.cloneNode(false));
  for (var i = 0, len = buttons2.length; i < len; i++) { addNode(buttons2[i], input, docfrag); }

  docfrag.appendChild(document.createTextNode('\u00A0 Font colour: ')); // \u00A0 non-breaking space
  var select1 = select.cloneNode(false);
  select1.id = 'color';
  select1.addEventListener('change', makeChange, false);
  //select1.setAttribute('onchange', "this.selectedIndex=0;");
  for (var i = 0, len = options1.length; i < len; i++) { addNode(options1[i], option, select1); }
  docfrag.appendChild(select1);

  docfrag.appendChild(document.createTextNode('\u00A0  Font size: ')); // \u00A0 non-breaking space
  var select2 = select.cloneNode(false);
  select2.id = 'size';
  select2.addEventListener('change', makeChange, false);
  for (var i = 0, len = options2.length; i < len; i++) { addNode(options2[i], option, select2); }
  docfrag.appendChild(select2);
}

bbcode.appendChild(docfrag);


})(); // end of anonymous function