Greasy Fork 支持简体中文。

WBB Quick Reply Plus

Adds More formatting buttons to Quick/Standard Reply

// ==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