User:Mrcool1122/monobook.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
The accompanying .css page for this skin can be added at User:Mrcool1122/monobook.css. |
// [[User:Lupin/popups.js]]
mw.loader.load(
'https://en.wikipedia.org/w/index.php?title=User:Lupin/popups.js'
+ '&action=raw&ctype=text/javascript&dontcountme=s');
popupMaxWidth=150;
/*<pre><nowiki> */
//
// comfortable javascript editor
// by: [[User:Cacycle]]
// from: [[User:Cacycle/Editor.js]]
// decription: [[User:Cacycle/Editor]]
//
// configuration variables
//
// levels of undo (each level holds the whole text)
var undoBufferMax = undoBufferMax || 20;
// button text and summary text of summary buttons
var summaryButtons = summaryButtons || [
['Copyedit', 'Copyedit'],
['Linkfix', 'Linkfix'],
['Vandal', 'Reverting vandalism'],
['Format', 'Formatting source text'],
['Cap lists', 'Capitalizing (link) lists as per [[Wikipedia:List]] and [[Wikipedia:Manual_of_Style]]']
];
// background color of preview box
var previewBackground = previewBackground || '#ffffdd';
//
// to be done:
// regexp internationalization
//
//document.getElementById('PreviewBox').innerHTML = '';
//document.getElementById('PreviewBox').innerHTML += ': "' + + '"<br>';
//
// find and replace functions
//
function Edit(what) {
// add focus to textbox
document.editform.wpTextbox1.focus();
// get the textarea object
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
// get the scroll position
var scrollTopPx = textarea.scrollTop;
var scrollHeightPx = textarea.scrollHeight;
// convert strange spaces, remove non-\n linebreak characters
convertStrangeSpaces();
// get the text from the textbox
var text = textarea.value;
var textNew;
// get the find text
var find = document.getElementById('findText');
if (find == null) { return; }
var findText = find.value;
// get the replace text
var replace = document.getElementById('replaceText');
if (replace == null) { return; }
var replaceText = replace.value;
// get checkboxes
var caseSensitive = document.getElementById('caseSensitive');
if (caseSensitive == null) { return; }
var regExp = document.getElementById('regExp');
if (regExp == null) { return; }
// changed flags
var textChanged = false;
var posChanged = false;
// get the text selection info
var startPos = textarea.selectionStart;
var endPos = textarea.selectionEnd;
var selected = text.substring(startPos, endPos);
var startPosNew;
var endPosNew;
// set cursor to position 0 if cursor has not already been set (better solution???)
if ( (startPos == endPos) && (startPos == text.length) ) {
textarea.selectionStart = 0;
textarea.selectionEnd = 0;
startPos = 0;
endPos = 0;
}
// manipulate selected text
if (selected != '') {
// lowercase selection
if ('lowercase'.indexOf(what) >= 0) {
var selectedNew = selected.toLowerCase();
textNew = text.substring(0, startPos) + selectedNew + text.substring(endPos);
startPosNew = startPos;
endPosNew = endPos;
textChanged = true;
}
// bold selection
if ('bold'.indexOf(what) >= 0) {
var selectedNew;
if ( /^\'\'\'.*\'\'\'$/.test(selected) ) {
selectedNew = selected.replace(/^\'\'\'(.*)\'\'\'$/, '$1');
startPosNew = startPos;
endPosNew = endPos - 6 ;
}
else {
selectedNew = "'''" + selected + "'''";
startPosNew = startPos;
endPosNew = endPos + 6;
}
textNew = text.substring(0, startPos) + selectedNew + text.substring(endPos);
textChanged = true;
}
// italic selection
if ('italic'.indexOf(what) >= 0) {
var selectedNew;
if ( /^\'\'.*\'\'$/.test(selected) ) {
selectedNew = selected.replace(/^\'\'(.*)\'\'$/, '$1');
startPosNew = startPos;
endPosNew = endPos - 4 ;
}
else {
selectedNew = "''" + selected + "''";
startPosNew = startPos;
endPosNew = endPos + 4;
}
textNew = text.substring(0, startPos) + selectedNew + text.substring(endPos);
textChanged = true;
}
}
// increase heading level
if ('headingmore'.indexOf(what) >= 0) {
var selectedNew = '';
// nothing selected, get current line
if (selected == '') {
var lineStart = text.lastIndexOf('\n', startPos - 1) + 1;
var lineEnd = text.indexOf('\n', startPos);
if (lineEnd < 0) {
lineEnd = text.length;
}
selectedNew = text.substring(lineStart, lineEnd);
// increase heading level
if ( /^\=\=.*\=\= *$/.test(selectedNew) ) {
selectedNew = selectedNew.replace(/^(\=\=+) *(.*?) *(\=\=+) *$/, '=$1 $2 $3=');
}
// make the line a heading
else {
selectedNew = selectedNew.replace(/(^ +| +$)/g, '');
if (selectedNew.length < 80) {
selectedNew = '== ' + selectedNew + ' ==';
}
else {
lineStart = startPos;
lineEnd = endPos;
selectedNew = selected;
}
}
startPosNew = lineStart;
endPosNew = lineStart;
textNew = text.substring(0, lineStart) + selectedNew + text.substring(lineEnd);
}
// increase all headings in selected text
else {
var lines = selected.split('\n');
// cycle trough the lines
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
// increase heading level in selected text
if ( /^==.*== *$/.test(line) ) {
line = line.replace(/^(==+) *(.*?) *(==+) *$/, '$1= $2 =$3');
}
selectedNew += line;
if (i < lines.length - 1) {
selectedNew += '\n';
}
}
startPosNew = startPos;
endPosNew = startPos + selectedNew.length;
textNew = text.substring(0, startPos) + selectedNew + text.substring(endPos);
}
textChanged = true;
}
// decrease heading level
if ('headingless'.indexOf(what) >= 0) {
var selectedNew = '';
// nothing selected, get current line
if (selected == '') {
var lineStart = text.lastIndexOf('\n', startPos - 1) + 1;
var lineEnd = text.indexOf('\n', startPos);
if (lineEnd < 0) {
lineEnd = text.length;
}
selectedNew = text.substring(lineStart, lineEnd);
// decrease heading level
if ( /^===.*=== *$/.test(selectedNew) ) {
selectedNew = selectedNew.replace(/^=(==.*==)= *$/, '$1');
}
else if ( /^==.*==$/.test(selectedNew) ) {
selectedNew = selectedNew.replace(/^== *(.*) *== *$/, '$1');
}
startPosNew = lineStart;
endPosNew = lineStart;
textNew = text.substring(0, lineStart) + selectedNew + text.substring(lineEnd);
}
// increase all headings in selected text
else {
var lines = selected.split('\n');
// cycle trough the lines
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
// decrease heading level in selected text
if ( /^===.*=== *$/.test(line) ) {
line = line.replace(/^=(==.*==)= *$/, '$1');
}
selectedNew += line;
if (i < lines.length - 1) {
selectedNew += '\n';
}
}
startPosNew = startPos;
endPosNew = startPos + selectedNew.length;
textNew = text.substring(0, startPos) + selectedNew + text.substring(endPos);
}
textChanged = true;
}
// replacements and text fixes
if ('spaces html punct caps dashes units math'.indexOf(what) >= 0) {
var startPosFix;
var endPosFix;
var selectedFix;
// apply to whole text if nothing is selected
if (startPos == endPos) {
startPosFix = 0;
endPosFix = text.length;
selectedFix = text;
}
else {
startPosFix = startPos;
endPosFix = endPos;
selectedFix = selected;
}
// apply fixes to selected text
if ('spaces'.indexOf (what) >= 0) { selectedFix = FixSpaces(selectedFix); }
else if ('html'.indexOf (what) >= 0) { selectedFix = FixHTML (selectedFix); }
else if ('punct'.indexOf (what) >= 0) { selectedFix = FixPunct (selectedFix); }
else if ('caps'.indexOf (what) >= 0) { selectedFix = FixCaps (selectedFix); }
else if ('dashes'.indexOf (what) >= 0) { selectedFix = FixDashes(selectedFix); }
else if ('units'.indexOf (what) >= 0) { selectedFix = FixUnits (selectedFix); }
else if ('math'.indexOf (what) >= 0) { selectedFix = FixMath (selectedFix); }
// remove newlines and spaces
selectedFix = selectedFix.replace(/\n{3,}/g, '\n\n');
selectedFix = selectedFix.replace(/^\n+/, '');
selectedFix = selectedFix.replace(/\n{2,}$/, '\n');
// set selection
if (startPos == endPos) {
startPosNew = startPos;
endPosNew = startPos;
}
else {
startPosNew = startPos;
endPosNew = startPos + selectedFix.length;
}
// insert selected into unchanged text
textNew = text.substring(0, startPosFix) + selectedFix + text.substring(endPosFix);
textChanged = true;
posChanged = true;
}
// prepare find regexp for find and replace
var regExpFlags = '';
if ('findprev findnext replaceprev replacenext replaceall'.indexOf(what) >= 0) {
// format the find text as regexp or plain text
if (regExp.checked) {
// replace \n with newline character, other characters have already been converted
replaceText = replaceText.replace(/((^|[^\\])(\\\\)*)\\n/g, '$1\n');
}
else {
findText = findText.replace(/([\\^\$\*\+\?\.\(\)\[\]\{\}\:\=\!\|\,\-])/g, '\\$1');
}
// set regexp flag i
if ( ! caseSensitive.checked ) {
regExpFlags = 'i';
}
}
// find / replace
if ('findnext replacenext findprev replaceprev'.indexOf(what) >= 0) {
if (find.value != '') {
// create regexp
var regExpFind = new RegExp(findText, regExpFlags + 'g');
// set start position for search to right
var indexStart;
var result;
if ('findnext replacenext'.indexOf(what) >= 0) {
indexStart = startPos;
if ( (selected.length > 0) && ('findnext'.indexOf(what) >= 0) ) {
indexStart = startPos + 1;
}
// execute the regexp search to the right
regExpFind.lastIndex = indexStart;
result = regExpFind.exec(text);
}
// prepare search to the left
else {
// set start position for search to left
indexStart = startPos - 1;
if ( (selected.length > 0) && ('replaceprev'.indexOf(what) >= 0) ) {
indexStart = startPos;
}
// cycle through the matches to the left
var resultNext;
do {
result = resultNext;
resultNext = regExpFind.exec(text);
if (resultNext == null) {
break;
}
} while (resultNext.index <= indexStart);
}
// get the matched string
var matched;
var matchedStart;
var matchedLength;
if (result != null) {
matched = result[0];
matchedStart = result.index;
matchedLength = matched.length;
// replace only if the next match was already selected
if ('replacenext replaceprev'.indexOf(what) >= 0) {
if (selected == matched) {
var replace = selected.replace(regExpFind, replaceText);
textNew = text.substr(0, matchedStart) + replace + text.substr(matchedStart + matched.length);
matchedLength = replace.length;
textChanged = true;
}
}
// select the found match in the textarea
startPosNew = matchedStart;
endPosNew = matchedStart + matchedLength;
}
else {
if ('findprev replaceprev'.indexOf(what) >= 0) {
indexStart = startPos;
}
startPosNew = indexStart;
endPosNew = indexStart;
}
posChanged = true;
}
}
// replace all
if ('replaceall'.indexOf(what) >= 0) {
if (find.value != '') {
// create regexp
var regExpFind = new RegExp(findText, regExpFlags + 'g');
// replace all in whole text
if (selected == '') {
// get the new cursorposition
textNew = text.replace(regExpFind, replaceText);
var textbefore = textNew.substr(0, startPos);
textbefore = textbefore.replace(regExpFind, replaceText);
startPosNew = textbefore.length;
endPosNew = startPosNew;
posChanged = true;
}
// replace all in selection
else {
var replace = selected.replace(regExpFind, replaceText);
startPosNew = startPos;
endPosNew = startPos + replace.length;
textNew = text.substr(0, startPos) + replace + text.substr(endPos);
}
textChanged = true;
}
}
// get the find field from the selection
if ('findnext findprev replacenext replaceprev getfind'.indexOf(what) >= 0) {
if ( ('getfind'.indexOf(what) >= 0) || ( (find.value == '') && (selected != '') ) ) {
if (regExp.checked) {
find.value = selected.replace(/\n/g, '\\n');
}
else {
find.value = selected.replace(/\n.*/, '');
startPosNew = startPos;
endPosNew = endPos;
}
}
}
// jump to top / bottom
if ('updown'.indexOf(what) >= 0) {
if (scrollTopPx > scrollHeightPx / 2) {
startPosNew = 0;
endPosNew = 0
}
else {
startPosNew = text.length;
endPosNew = text.length;
}
posChanged = true;
}
// change textarea, save undo info
if (textChanged) {
textarea.value = textNew;
SaveUndo(text, startPos, endPos);
SaveUndo(textNew, startPosNew, endPosNew);
}
// set the selection range
textarea.setSelectionRange(startPosNew, endPosNew);
// scroll the textarea to the selected text or cursor position
if (posChanged) {
ScrollToSelection();
}
else {
textarea.scrollTop = scrollTopPx;
}
return;
}
//
// scroll the textarea to the selected text or cursor position
//
function ScrollToSelection() {
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
var text = textarea.value;
var rows = textarea.rows;
var cols = textarea.cols;
// get total number of rows
var totalRows = GetRows(text, rows, cols);
// determine scroll position
if (totalRows >= rows) {
var startPos = textarea.selectionStart;
// breaking of the cursor row depends on trailing characters
var nextspace = text.indexOf(' ', startPos);
var nextreturn = text.indexOf('\n', startPos);
var tostart = text.substr(0, startPos);
var fromstart = text.substr(startPos);
fromstart = fromstart.replace(/\s.*/g, '');
// get the rows number of the cursor position
var currentRow = GetRows(tostart + fromstart, rows, cols);
currentRow = currentRow - rows / 2;
if (currentRow < 0) {
currentRow = 0;
}
// set scroll position
var scrollHeightRel = (currentRow - 1) / (totalRows);
var scrollHeightPx = textarea.scrollHeight;
var scrollTopPxNew = parseInt(scrollHeightRel * scrollHeightPx);
textarea.scrollTop = scrollTopPxNew;
}
return;
}
//
// get number of rows for a text in a textarea
//
function GetRows(text, rows, cols) {
var totalRows = 0;
var lines = text.split('\n');
// cycle trough the lines
for (var i = 0; i < lines.length; i++) {
totalRows ++;
var line = lines[i];
// simulate breaking of long lines
while (line.length > cols) {
// break line before border
var spaceBefore = line.lastIndexOf(' ', cols);
if (spaceBefore >= 0) {
line = line.substr(spaceBefore + 1);
}
else {
// break line after border
var spaceAfter = line.indexOf(' ', cols);
if (spaceAfter >= 0) {
line = line.substr(spaceAfter + 1);
line.replace(/^ */, '');
}
// no spaces, no break
else {
line = '';
}
}
if (line.length > 0) {
totalRows ++;
}
}
}
return(totalRows);
}
//
// fix characters, spaces, empty lines, certain headings
//
function FixSpaces(text) {
// remove trailing spaces from lines
text = text.replace(/ +\n/g, '\n');
// empty line before and after headings, spaces around word (lookahead)
text = text.replace(/(\n={2,}) *([^\n]*?) *(={2,})(?=\n)/g, '\n$1 $2 $3\n\n');
// uppercase important headings
text = text.replace(/\n== external links? ==\n/ig, '\n== External links ==\n');
text = text.replace(/\n== see also ==\n/ig, '\n== See also ==\n');
text = text.replace(/\n== references? ==\n/ig, '\n== References ==\n');
// add space after * # : ; (list) and after {| |- | (table)
text = text.replace(/(^|\n)([\*\#\:\;]+|\{\||\|\-|\|\}|\|) */g, '$1$2 ');
// empty line before and after tables
text = text.replace(/\n+(\{\|)/g, '\n\n$1');
text = text.replace(/(\n\|\}) *([^\n]*)[\n|$]+/g, '$1\n\n$2\n\n');
// empty line before and after lists
text = text.replace(/(^|\n)([^\*\#\:\;].*?)\n+([\*\#\:\;])/g, '$1$2\n\n$3');
text = text.replace(/(^|\n)([\*\#\:\;].*?)\n+([^\*\#\:\;])/g, '$1$2\n\n$3');
// split into lines and change single lines, used to handle tables
var lines = text.split('\n');
text = '';
var tableflag = false;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
// do not change lines starting with a blank
if ( ! line.match(/^ /) ) {
// detect table
if ( line.match(/^(\{\||\!|\|[^}])/) ) {
tableflag = true;
}
else if ( line.match(/^\|\}/) ) {
tableflag = false;
}
// changes only to be done in tables
if (tableflag) {
// add spaces around ||
line = line.replace(/ *\|\| */g, ' || ');
// to do: add spaces around | in tables without changing image markup!
}
// changes not to be done in tables
if ( ! tableflag) {
// empty line before and after images
line = line.replace(/^(\[\[image:.*?\]\])/ig, '\n$1');
line = line.replace(/(\[\[image:.*?(\[\[.*?\]\].*?)*\]\])$/ig, '$1\n');
// empty line before and after includes
line = line.replace(/^(\{\{.*?\}\})/g, '\n$1');
line = line.replace(/(\{\{.*?\}\})$/g, '$1\n');
// to be done: convert single newlines into spaces
// line = line.replace(/(\n[^\n \*\#\:\;\|\{].*?)\n([^\n \*\#\:\;\|\{])/g, '$1 $2');
}
}
// concatenate the lines
text += line;
if (i < lines.length - 1) {
text += '\n';
}
}
// remove spaces in wikilinks
text = text.replace(/\[\[ *([^\n]*?) *\]\]/g, '[[$1]]');
// remove spaces in external links
text = text.replace(/\[ *([^\n]*?) *\]/g, '[$1]');
// space around pipes in wikilinks but not in images
text = text.replace(/(\[\[(?!image:)[^\n]+?) *\| *(.*?\]\])/ig, '$1 | $2');
// space around pipes in templates
text = text.replace(/(\{\{)([^\n]+?)(\}\})/g,
function (p, p1, p2, p3) {
p2 = p2.replace(/ *(\|) */g,
function (p, p1) {
return(' | ');
}
);
return(p1 + p2 + p3);
}
);
// no space around pipes before brackets
text = text.replace(/ +\| +\]\]/g, '|]]');
// no space around pipes before curly brackets
text = text.replace(/ +\| +\}\}/g, '|}}');
// no empty line between headings and includes
text = text.replace(/\n(==+ [^\n]*? ==+\n)\n+(\{\{.*?\}\})/g, '$1$2');
// empty line before and after categories
text = text.replace(/(\[\[category:[^\n]*?\]\]) */gi, '\n\n$1\n\n');
// categories not separated by empty lines (lookahead)
text = text.replace(/(\[\[category:[^\n]*?\]\])\n*(?=\[\[category:[^\n]*?\]\])/gi, '$1\n');
return(text);
}
//
// fix html to wikicode
//
function FixHTML(text) {
// fix basic
text = FixSpaces(text);
// convert italic
text = text.replace(/<i>|<\/i>/g, '\'\'');
// convert bold
text = text.replace(/<b>|<\/b>/g, '\'\'\'');
// to do: tables
return(text);
}
//
// fix space before punctuation marks
//
function FixPunct(text) {
// fix basic
text = FixSpaces(text);
// remove space before .,: (; could be a definition)
text = text.replace(/([a-zA-Z\'\"\”\]\}\)]) +([\.\,\:])/g, '$1$2');
return(text);
}
//
// fix capitalizing of lists, linklists, images, headings
//
function FixCaps(text) {
// fix basic
text = FixSpaces(text);
// uppercase lists
text = text.replace(/(^|\n)([\*\#\:\;]+ \W*)(\w+)/g,
function (p, p1, p2, p3) {
if ( ! p3.match(/^(http|ftp)/) ) {
p3 = p3.substr(0, 1).toUpperCase() + p3.substr(1);
}
return(p1 + p2 + p3);
}
);
// uppercase link lists (link)
text = text.replace(/(^|\n)([\*\#\:\;]+ \[\[)([^\n]*?)(\]\])/g,
function (p, p1, p2, p3, p4) {
// uppercase link
p3 = p3.replace(/^(\W*)(\w+)/g,
function (p, p1, p2) {
if ( ! p2.match(/^(http|ftp)/) ) {
p2 = p2.substr(0, 1).toUpperCase() + p2.substr(1);
}
return(p1 + p2);
}
);
// uppercase comment
p3 = p3.replace(/(\| \W*)(\w+)/g,
function (p, p1, p2) {
if ( ! p2.match(/^(http|ftp)/) ) {
p2 = p2.substr(0, 1).toUpperCase() + p2.substr(1);
}
return(p1 + p2);
}
);
return(p1 + p2 + p3 + p4);
}
);
// uppercase headings
text = text.replace(/(^|\n)(==+ )(\W*\w)([^\n]* ==+(\n|$))/ig,
function (p, p1, p2, p3, p4) {
return(p1 + p2 + p3.toUpperCase() + p4);
}
);
// uppercase images
text = text.replace(/(\[\[)image:(\w)([^\n]*\]\])/ig,
function (p, p1, p2, p3) {
return(p1 + 'Image:' + p2.toUpperCase() + p3);
}
);
return(text);
}
//
// dash fixer - adds a tab that fixes several obvious en/em dash, minus sign, and such special characters.
// originally from User:Omegatron
//
function FixDashes(text) {
// fix basic
text = FixSpaces(text);
// convert html entities into actual dash characters
text = text.replace(/—/g, '—');
text = text.replace(/–/g, '–');
text = text.replace(/−/g, '\u2212');
// convert -- and em dashes with or without spaces to em dash surrounded by spaces
text = text.replace(/([a-zA-Z\'\"”\]\}\)]) *(--|—|—) *([a-zA-Z\'\"“\[\{\(])/g, '$1 — $3');
// convert - or en dashes with spaces to em dash character surrounded by spaces
text = text.replace(/([a-zA-Z\'\"”\]\}])( | )+(\u2212|–|–) +([a-zA-Z\'\"“\[\{])/g, '$1$2— $4');
// convert hyphen next to lone number into a minus sign character
text = text.replace(/([a-zA-Z\'\"”\]\>] )-(\d)/g, '$1\u2212$3');
// convert dashes to en dashes in dates
text = text.replace(/([ \(][12]\d\d\d) ?(--?|—|—) ?([12]\d\d\d|\d\d)([ \),.;])/g, '$1–$3$4');
return(text);
}
//
// unit formatter - new tab adds spaces between number and units, makes units consistent
// originally from User:Omegatron
//
function FixUnits(text) {
// fix basic
text = FixSpaces(text);
// convert all ° into actual ° symbol
text = text.replace(/°/g, '°');
// convert the word ohm(s) or the html entity into the actual O symbol (Omega, not the actual ohm symbol Ω) and make sure it's spaced
text = text.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|µ|µ|µ|n|p|f|a|z|y)? ?(Ω|ohm|Ohm)s?([ ,.])/g, '$1 $2O$4');
// convert various micro symbols into the actual micro symbol, make sure it's spaced
text = text.replace(/(\d) ?(μ|µ|µ)(g|s|m|A|K|mol|cd|rad|sr|Hz|N|J|W|Pa|lm|lx|C|V|O|F|Wb|T|H|S|Bq|Gy|Sv|kat|°C|M)([ ,.])/g, '$1 µ$3$4');
// convert capital K to lowercase k in units
text = text.replace(/(\d) ?K(g|s|m|A|K|mol|cd|rad|sr|Hz|N|J|W|Pa|lm|lx|C|V|O|F|Wb|T|H|S|Bq|Gy|Sv|kat|°C|M)([ ,.])/g, '$1 k$2$3');
// capitalize units correctly
text = text.replace(/(\d) ?(khz)([ ,.])/gi, '$1 kHz$3');
text = text.replace(/(\d) ?(mhz)([ ,.])/gi, '$1 MHz$3');
text = text.replace(/(\d) ?(ghz)([ ,.])/gi, '$1 GHz$3');
text = text.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|µ|µ|µ|n|p|f|a|z|y)?(hz|HZ)([ ,.])/g, '$1 $2Hz$4');
text = text.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|µ|µ|µ|n|p|f|a|z|y)?(pa|PA)([ ,.])/g, '$1 $2Pa$4');
// add a space before dB or B
text = text.replace(/(\d) ?(dB|B)\b/g, '$1 $2');
// add a space before any units that were missed before
text = text.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|µ|n|p|f|a|z|y)?(g|m|A|K|mol|cd|rad|sr|Hz|N|J|W|Pa|lm|lx|C|V|O|F|Wb|T|H|S|Bq|Gy|Sv|kat|°C|M)([ ,.])/g, '$1 $2$3$4');
// separate one for seconds since they give a lot of false positives like "1970s". Only difference is mandatory prefix.
text = text.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|µ|n|p|f|a|z|y)(s)([ ,.])/g, '$1 $2$3$4');
// bps or b/s or bits/s --> bit/s
text = text.replace(/([KkMmGgTtPpEeYyZz])(bps|bits?\/s|b\/s)/g, '$1bit/s');
// Bps or byte/s or bytes/s --> B/s
text = text.replace(/([KkMmGgTtPpEeYyZz])(Bps|bytes?\/s)/g, '$1B/s');
// after that, make capitalization correct
text = text.replace(/K(bit|B)\/s/g, 'k$1/s');
text = text.replace(/m(bit|B)\/s/g, 'M$1/s');
text = text.replace(/g(bit|B)\/s/g, 'G$1/s');
text = text.replace(/t(bit|B)\/s/g, 'T$1/s');
text = text.replace(/e(bit|B)\/s/g, 'E$1/s');
text = text.replace(/y(bit|B)\/s/g, 'Y$1/s');
text = text.replace(/z(bit|B)\/s/g, 'Z$1/s');
// fix a common error
text = text.replace(/mibi(bit|byte)/g, 'mebi$1');
return(text);
}
//
// math character fixer, originally from User:Omegatron
//
// DO NOT USE FOT <math> </math> WIKICODE!
//
function FixMath(text) {
// fix basic
text = FixSpaces(text);
// convert html entities into actual dash characters
text = text.replace(/−/g, '\u2212');
text = text.replace(/·/g, '·');
// Convert dash next to a number into a minus sign character
text = text.replace(/([^a-zA-Z0-9\,\_\{])-(\d)/g, '$1\u2212$2');
// changes 2x3 to 2×3
text = text.replace(/(\d ?)x( ?\d)/g, '$1×$2');
// changes 10^3 to 10<sup>3</sup>
text = text.replace(/(\d*\.?\d+)\^(\u2212?\d+\.?\d*)/g, '$1<sup>$2</sup>');
// change x^3 to x<sup>3</sup>
text = text.replace(/([0-9a-zA-Z])\^(\u2212?\d+\.?\d*) /g, '$1<sup>$2</sup>');
// change +/- to ±
text = text.replace(/( |\d)\+\/(-|\u2212)( |\d)/g, '$1±$3');
return(text);
}
//
// add a tag to the summary box
//
function AddSummary(summary) {
var text = document.editform.wpSummary;
if (text != null) {
if (text.value.match(/ \*\/ $/)) {
text += ' ';
}
else if (text.value != '') {
text.value += '; ';
}
text.value += summary;
}
}
// 20 level undo / redo
var undoBuffer = new Array(undoBufferMax);
var undoBufferSelStart = new Array(undoBufferMax);
var undoBufferSelEnd = new Array(undoBufferMax);
var undoBufferFirst = 0;
var undoBufferLast = 0;
var undoBufferCurr = 0;
//
// save undo information
//
function SaveUndo(text, startPos, endPos) {
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
if (undoBufferLast == 0) {
undoBuffer[1] = textarea.value;
undoBufferSelStart[1] = startPos;
undoBufferSelEnd[1] = endPos;
undoBufferCurr = 1;
undoBufferLast = 1;
}
undoBufferLast++;
undoBufferCurr = undoBufferLast;
var slot = undoBufferLast % undoBufferMax;
undoBuffer[slot] = text;
undoBufferSelStart[slot] = startPos;
undoBufferSelEnd[slot] = endPos;
}
//
//undo
//
function Undo() {
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
if (undoBufferCurr - 1 > undoBufferLast - undoBufferMax) {
if (undoBufferCurr - 1 >= 0) {
undoBufferCurr--;
var slot = undoBufferCurr % undoBufferMax;
textarea.value = undoBuffer[slot];
textarea.focus();
textarea.selectionStart = undoBufferSelStart[slot];
textarea.selectionEnd = undoBufferSelEnd[slot];
ScrollToSelection();
}
}
}
//
// redo
//
function Redo() {
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
if (undoBufferCurr + 1 <= undoBufferLast) {
undoBufferCurr++;
var slot = undoBufferCurr % undoBufferMax;
var slot = undoBufferCurr % undoBufferMax;
textarea.value = undoBuffer[slot];
textarea.focus();
textarea.selectionStart = undoBufferSelStart[slot];
textarea.selectionEnd = undoBufferSelEnd[slot];
ScrollToSelection();
}
}
//
// resize textarea to ~100% by adapting cols
//
function ResizeTextarea() {
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
textarea.style.width = '100%';
var widthMax = textarea.offsetWidth;
textarea.style.width = 'auto';
// provoke a scrollbar
var textLength = textarea.value.length;
var cols = textarea.cols;
var fillstring = '\n\n';
for (i = 0; i < cols; i++) {
fillstring += '\n';
}
// add the filling string
var startPos = textarea.selectionStart;
var endPos = textarea.selectionEnd;
var scrollTopPx = textarea.scrollTop;
textarea.value += fillstring;
// find optimal width
textarea.cols = 20;
for (var i = 64; i >= 1; i = i / 2) {
while (textarea.offsetWidth < widthMax) {
textarea.cols = textarea.cols + i;
}
textarea.cols = textarea.cols - i;
}
// remove filling string
textarea.value = textarea.value.substr(0, textLength);
textarea.selectionStart = startPos;
textarea.selectionEnd = endPos;
textarea.scrollTop = scrollTopPx;
return;
}
//
// convert strange spaces, remove non-\n linebreak characters
//
function convertStrangeSpaces() {
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
var startPos = textarea.selectionStart;
var endPos = textarea.selectionEnd;
var text = textarea.value;
text = text.replace(/[\t\v\u00A0\u2028\u2029]+/g, ' ');
text = text.replace(/[\r\f]/g, '');
textarea.value = text;
textarea.selectionStart = startPos;
textarea.selectionEnd = endPos;
return;
}
//
// setup routine for javascript editor
//
function SetupEditor() {
// at the moment this works only for mozilla browsers (Mozilla, Mozilla Firefox, Mozilla SeaMonkey)
var name = navigator.appName.match(/Netscape/i)[0];
if (name == null) { return; }
var version = navigator.appVersion.match(/\d+(\.\d+)/)[0];
if (version == null) { return; }
if (version < 5.0) { return; }
// get the textarea object
var textarea = document.editform.wpTextbox1;
if (textarea == null) { return; }
// setup the undo buffers and get the original text for instant change view
undoBuffer[0] = textarea.value;
editformOrig = textarea.value;
// set textarea size to maximal row number
window.onresize = ResizeTextarea;
ResizeTextarea();
// convert strange spaces, remove non-\n linebreak characters
convertStrangeSpaces();
// add custom edit area stylesheet definition to head
var insert = document.getElementsByTagName('head')[0];
if (insert != null) {
var html = '';
html +=
'<style type="text/css"> .customedit { font-size: smaller; padding-left: 0.1em; padding-right: 0.1em } </style>\n';
insert.innerHTML += html;
}
// add formatting buttons below the textarea
var insert = document.getElementById('editpage-copywarn');
if (insert != null) {
var editpagecopywarn = insert.cloneNode(true);
insert.setAttribute('id','customEditButtons');
var old = document.getElementById('editpage-specialchars');
old.parentNode.insertBefore(editpagecopywarn, old);
var html = '';
// find, replace
html += '<div style="margin-top: 0.2em; margin-left: 0;">\n';
html += '<input class="customedit" type="button" value="Get" onclick="javascript:Edit(\'getfind\');" title="Get the find text from the selection"/>\n';
html += '<input class="customedit" type="button" value="←Find" onclick="javascript:Edit(\'findprev\');" title="Find previous"/>\n';
html += '<input class="customedit" type="text" value="" onclick="javascript:();" id="findText" title=""/>\n';
html += '<input class="customedit" type="button" value="Find→" onclick="javascript:Edit(\'findnext\');" title="Find next"/>\n';
html += '<span style="margin-left: 0.5em;"></span>\n';
html += '<input class="customedit" type="button" value="↑↓" onclick="javascript:Edit(\'updown\');" title="Jump to the top / bottom"/>\n';
html += '<span style="margin-left: 1em;"></span>\n';
html += '<input class="customedit" type="button" value="←" onclick="javascript:Undo();" title="Undo buttons"/>\n';
html += '<input class="customedit" type="button" value="→" onclick="javascript:Redo();" title="Redo buttons"/>\n';
html += '<span style="margin-left: 1em;"></span>\n';
html += '<input class="customedit" type="button" style="font-weight: bold;" value="b" onclick="javascript:Edit(\'bold\');" title="Bold text"/>\n';
html += '<input class="customedit" type="button" style="font-style: italic;" value="i" onclick="javascript:Edit(\'italic\');" title="Italic text"/>\n';
html += '<input class="customedit" type="button" value="A→a" onclick="javascript:Edit(\'lowercase\');" title="Lowercase text"/>\n';
html += '<span style="margin-left: 0.5em;"></span>\n';
html += '<input class="customedit" type="button" value="=←" onclick="javascript:Edit(\'headingless\');" title="Decrease heading level"/>\n';
html += '<input class="customedit" type="button" value="→==" onclick="javascript:Edit(\'headingmore\');" title="Increase heading level"/>\n';
html += '</div>\n';
// fixing functions
html += '<div style="margin-top: 0.2em; margin-bottom: 0.5em; margin-left: 0;">\n';
html += '<input class="customedit" type="button" value="All" onclick="javascript:Edit(\'replaceall\');" title="Replace all in whole text or selection"/>\n';
html += '<input class="customedit" type="button" value="←Repl." onclick="javascript:Edit(\'replaceprev\');" title="Replace previous"/>\n';
html += '<input class="customedit" type="text" value="" onclick="javascript:();" id="replaceText" title=""/>\n';
html += '<input class="customedit" type="button" value="Repl.→" onclick="javascript:Edit(\'replacenext\');" title="Replace"/>\n';
html += '<span style="margin-left: 0.2em;"></span>\n';
html += '<span title="Search should be case sensitive"><input class="customedit" style="margin: 0;" type="checkbox" value="1" onclick="javascript:();" id="caseSensitive"/> Case</span>\n';
html += '<span style="margin-left: 0.2em;"></span>\n';
html += '<span title="Search should be a regular expression"><input class="customedit" style="margin: 0;" type="checkbox" value="1" onclick="javascript:();" id="regExp"/> Regexp</span>\n';
html += '<span style="margin-left: 1em;">Fix:</span>\n';
html += '<input class="customedit" type="button" value="Basic" onclick="javascript:Edit(\'spaces\');" title="Fix blanks and empty lines"/>\n';
html += '<input class="customedit" type="button" value="—" onclick="javascript:Edit(\'dashes\');" title="Fix dashes"/>\n';
html += '<input class="customedit" type="button" value="kΩ" onclick="javascript:Edit(\'units\');" title="Fix units"/>\n';
html += '<input class="customedit" type="button" value="√" onclick="javascript:Edit(\'math\');" title="Fix math, DO NOT USE ON <math></math> WIKICODE!!!"/>\n';
html += '<input class="customedit" type="button" value="html" onclick="javascript:Edit(\'html\');" title="Fix html to wikicode"/>\n';
html += '<input class="customedit" type="button" value=".,:" onclick="javascript:Edit(\'punct\');" title="Fix spaces before puntuation"/>\n';
html += '<input class="customedit" type="button" value="Aa" onclick="javascript:Edit(\'caps\');" title="Fix caps in headers and lists"/>\n';
html += '</div>\n';
insert.innerHTML = html;
}
// add summary buttons
var old = document.getElementById('wpSummary');
var insert = document.createElement('span');
insert.setAttribute('id','instantButtons');
old.parentNode.insertBefore(insert, old.nextSibling);
if (insert != null) {
var html = '';
html += '<span style="margin-left: 1em;">\n';
var summary;
for (var i = 0; i < summaryButtons.length; i++) {
html += '<input type="button" class="customedit" value="' + summaryButtons[i][0] + '" onclick="javascript:AddSummary(\'' + summaryButtons[i][1] + '\');" title="Add to summary: ' + summaryButtons[i][1] + '"/>\n';
}
html += '</span>\n';
insert.innerHTML = html;
}
// add preview and changes buttons
var old = document.getElementById('wpPreview');
var insert = document.createElement('span');
insert.setAttribute('id','customPreviewButtons');
old.parentNode.insertBefore(insert, old);
if (insert != null) {
var html = '';
html += '<span style="margin-left: 0.5em; margin-right: 0.5em">\n';
html += 'Instant:\n';
html += '<input type="button" class="customedit" title="Show a preview below" value="Preview" onclick="document.getElementById(\'PreviewBox\').innerHTML = wiki2html(editform.wpTextbox1.value);" />\n';
html += '<input type="button" class="customedit" title="Show changes since your last preview below" value="Changes" onclick="document.getElementById(\'PreviewBox\').innerHTML = diffString(editformOrig, editform.wpTextbox1.value);" />\n';
html += '<input type="button" class="customedit" title="Clear the preview box" value="Clear" onclick="document.getElementById(\'PreviewBox\').innerHTML = \'\';" />\n';
html += '</span>\n';
html += 'Server:\n';
insert.innerHTML = html;
}
// shorten button and tab texts
document.getElementById('wpPreview').value = 'Preview';
document.getElementById('wpDiff').value = 'Changes';
// add preview box
var old = document.getElementById('editpage-copywarn');
var insert = document.createElement('div');
insert.setAttribute('id','customPreviewBox');
old.parentNode.insertBefore(insert, old);
if (insert != null) {
var html = '';
html += '<div style="margin-top: 1em; margin-bottom: 0.5em; border-width: 1px; border-style: solid; border-color: #808080 #d0d0d0 #d0d0d0 #808080; id="PreviewBoxOutline">\n';
html += '<div style="padding: 5px; border-width: 1px; border-style: solid; border-color: #404040 #ffffff #ffffff #404040; background-color: ' + previewBackground + ';" id="PreviewBox">\n';
html += '</div>\n';
html += '</div>\n';
insert.innerHTML = html;
}
return;
}
/*
* Javascript Diff Algorithm
* By John Resig (http://ejohn.org/)
*
* More Info:
* http://ejohn.org/projects/javascript-diff-algorithm/
*/
function diffString( o, n ) {
// added by cacycle:
o = o.replace(/\</g, '<');
n = n.replace(/\</g, '<');
o = o.replace(/\>/g, '>');
n = n.replace(/\>/g, '>');
o = o.replace(/(sort|watch)/, ''); // its funny, it doesn't work if the text contains 'sort', 'watch'
n = n.replace(/sort/, 'sort');
var out = diff( o.split(/\s+/), n.split(/\s+/) );
var str = "";
for ( var i = 0; i < out.n.length - 1; i++ ) {
if ( out.n[i].text == null ) {
if ( out.n[i].indexOf('"') == -1 && out.n[i].indexOf('<') == -1 )
str += "<ins style='background:#E6FFE6;'> " + out.n[i] +"</ins>";
else
str += " " + out.n[i];
} else {
var pre = "";
if ( out.n[i].text.indexOf('"') == -1 && out.n[i].text.indexOf('<') == -1 ) {
var n = out.n[i].row + 1;
while ( n < out.o.length && out.o[n].text == null ) {
if ( out.o[n].indexOf('"') == -1 && out.o[n].indexOf('<') == -1 && out.o[n].indexOf(':') == -1 && out.o[n].indexOf(';') == -1 )
pre += " <del style='background:#FFE6E6;'>" + out.o[n] +" </del>";
n++;
}
}
str += " " + out.n[i].text + pre;
}
}
return str;
}
function diff( o, n ) {
var ns = new Array();
var os = new Array();
for ( var i = 0; i < n.length; i++ ) {
if ( ns[ n[i] ] == null )
ns[ n[i] ] = { rows: new Array(), o: null };
ns[ n[i] ].rows.push( i );
}
for ( var i = 0; i < o.length; i++ ) {
if ( os[ o[i] ] == null )
os[ o[i] ] = { rows: new Array(), n: null };
os[ o[i] ].rows.push( i );
}
for ( var i in ns ) {
if ( ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1 ) {
n[ ns[i].rows[0] ] = { text: n[ ns[i].rows[0] ], row: os[i].rows[0] };
o[ os[i].rows[0] ] = { text: o[ os[i].rows[0] ], row: ns[i].rows[0] };
}
}
for ( var i = 0; i < n.length - 1; i++ ) {
if ( n[i].text != null && n[i+1].text == null && o[ n[i].row + 1 ].text == null &&
n[i+1] == o[ n[i].row + 1 ] ) {
n[i+1] = { text: n[i+1], row: n[i].row + 1 };
o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1 };
}
}
for ( var i = n.length - 1; i > 0; i-- ) {
if ( n[i].text != null && n[i-1].text == null && o[ n[i].row - 1 ].text == null &&
n[i-1] == o[ n[i].row - 1 ] ) {
n[i-1] = { text: n[i-1], row: n[i].row - 1 };
o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1 };
}
}
return { o: o, n: n };
}
/* </nowiki></pre> */