Différences entre les versions de « Utilisateur:Jluc/monobook.js »

De Entre Amis
Aller à : navigation, rechercher
(Résumé automatique : blanchiment)
Ligne 1 : Ligne 1 :
−
/* <pre><nowiki> */
 
  
−
 
−
/*
 
−
 
−
Name:    diff.js
 
−
Version: 0.5.0 (June 18, 2006)
 
−
Info:    http://en.wikipedia.org/wiki/User:Cacycle/editor
 
−
Code:    http://en.wikipedia.org/wiki/User:Cacycle/editor.js
 
−
 
−
Comfortable JavaScript editor extension for Wikipedia edit pages by [[User:Cacycle]]
 
−
See [[User:Cacycle/Editor]] for a description and [[User:Cacycle/Editor.js]] for this code.
 
−
Features include:
 
−
* Regular expression search and replace
 
−
* Server-independent ''Show preview'' and ''Show changes''
 
−
* One-click fixing of common mistakes
 
−
* Convert html tables and other markup to wikicode
 
−
* Undo/redo
 
−
* Input boxes with history
 
−
* Fullscreen view
 
−
* Find ahead as you type
 
−
* Horizontal cursor memory
 
−
See [[User:Cacycle/Editor]] for an installation guide.
 
−
The program works only for the mozilla browsers Mozilla, Mozilla Firefox, and Mozilla SeaMonkey.
 
−
The code is currently under active development and might change rapidly.
 
−
This code has been released into the public domain.
 
−
 
−
*/
 
−
 
−
 
−
//
 
−
// configuration variables
 
−
//
 
−
 
−
// levels of undo (each level holds the whole text)
 
−
var undoBufferMax = undoBufferMax || 20;
 
−
 
−
// style for preview box
 
−
var stylePreviewBox = stylePreviewBox || 'background-color: #f9f9f9;';
 
−
 
−
// style for custom edit buttons
 
−
var styleButtons = styleButtons || 'font-size: smaller; padding-left: 0.1em; padding-right: 0.1em; margin-left: 0.1em; margin-right: 0.1em; height: 1.6em; vertical-align: bottom;';
 
−
 
−
// history length for summary, find and replace fields
 
−
var findHistoryLength = findHistoryLength || 10;
 
−
 
−
// presets for input field dropdown options
 
−
var presetOptions = presetOptions || [];
 
−
presetOptions['summary'] = presetOptions['summary'] || [
 
−
'Copyedit',
 
−
'Linkfix',
 
−
'Reverting vandalism',
 
−
'Formatting source text'
 
−
];
 
−
 
−
// expiration time span for history cookies in seconds
 
−
var cookieExpireSec = cookieExpireSec || (365 * 24 * 60 * 60);
 
−
 
−
// enable cursor horizontal position memory
 
−
var cursorMemory = cursorMemory || true;
 
−
 
−
// show at least this number of lines ahead of cursor movement
 
−
var scrollMargin = scrollMargin || 1;
 
−
 
−
// show at least this number of lines ahead of cursor movement for
 
−
var findMargin = findMargin || 2;
 
−
 
−
// find ahead checkbox selected by default
 
−
var findAheadSelected = findAheadSelected || true;
 
−
 
−
 
−
// global variables
 
−
 
−
 
−
// history
 
−
var fieldHist = [];
 
−
var cookieName = [];
 
−
var inputElement = [];
 
−
var selectElement = [];
 
−
 
−
var checkMarker = [];
 
−
checkMarker[true] = '\u2022';
 
−
checkMarker[false] = '\u22c5';
 
−
 
−
// undo
 
−
var undoBuffer = new Array(undoBufferMax);
 
−
var undoBufferSelStart = new Array(undoBufferMax);
 
−
var undoBufferSelEnd = new Array(undoBufferMax);
 
−
var undoBufferFirst = 0;
 
−
var undoBufferLast = 0;
 
−
var undoBufferCurr = 0;
 
−
 
−
// fullscreen
 
−
var normalTextareaWidth;
 
−
var normalTextareaHeight;
 
−
var normalTextareaMargin;
 
−
var normalTextareaRows;
 
−
var normalPageXOffset;
 
−
var normalPageYOffset;
 
−
var normalTreePos = {};
 
−
var fullScreenMode = false;
 
−
var fullButtonValue = 'Full screen';
 
−
var fullButtonTitle = 'Full screen editing mode';
 
−
var normalButtonValue = 'Normal view';
 
−
var normalButtonTitle = 'Back no normal page view';
 
−
var normalFloatButtonValue = 'Back';
 
−
 
−
// textarea text info object
 
−
var textRows = new Object();
 
−
textRows.lineStart = [];
 
−
textRows.lineLength = [];
 
−
textRows.rowStart = [];
 
−
textRows.rowLength = [];
 
−
 
−
var textareaElement = {};
 
−
var lastChangePos;
 
−
 
−
// counter
 
−
var i;
 
−
var j;
 
−
 
−
 
−
// load the editor after page loading
 
−
if (window.addOnloadHook != null) {
 
−
addOnloadHook(SetupEditor);
 
−
}
 
−
 
−
//
 
−
// find and replace functions
 
−
//
 
−
 
−
function Edit(what) {
 
−
 
−
// add focus to textbox
 
−
textareaElement.focus();
 
−
 
−
// get the scroll position
 
−
var scrollTopPx = textareaElement.scrollTop;
 
−
var scrollHeightPx = textareaElement.scrollHeight;
 
−
 
−
// convert strange spaces, remove non-\n linebreak characters
 
−
convertStrangeSpaces();
 
−
 
−
var textNew;
 
−
  var textLength = textareaElement.value.length;
 
−
 
−
// get the find text
 
−
var find = document.getElementById('findText');
 
−
var findText = find.value;
 
−
 
−
// get the replace text
 
−
var replace = document.getElementById('replaceText');
 
−
var replaceText = replace.value;
 
−
 
−
// get checkboxes
 
−
var caseSensitive = document.getElementById('caseSensitive');
 
−
var regExp = document.getElementById('regExp');
 
−
 
−
// changed flags
 
−
var textChanged = false;
 
−
var posChanged = false;
 
−
 
−
// get the text selection info
 
−
var startPos = textareaElement.selectionStart;
 
−
var endPos = textareaElement.selectionEnd;
 
−
var selected = textareaElement.value.substring(startPos, endPos);
 
−
var startPosNew;
 
−
var endPosNew;
 
−
 
−
// manipulate selected text
 
−
if (selected != '') {
 
−
 
−
// lowercase selection
 
−
if ('lowercase'.indexOf(what) >= 0) {
 
−
var selectedNew = selected.toLowerCase();
 
−
textNew = textareaElement.value.substring(0, startPos) + selectedNew + textareaElement.value.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 = textareaElement.value.substring(0, startPos) + selectedNew + textareaElement.value.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 = textareaElement.value.substring(0, startPos) + selectedNew + textareaElement.value.substring(endPos);
 
−
textChanged = true;
 
−
}
 
−
}
 
−
 
−
// increase heading level
 
−
if ('headingmore'.indexOf(what) >= 0) {
 
−
var selectedNew = '';
 
−
 
−
// nothing selected, get current line
 
−
if (selected == '') {
 
−
var lineStart = textareaElement.value.lastIndexOf('\n', startPos - 1) + 1;
 
−
var lineEnd = textareaElement.value.indexOf('\n', startPos);
 
−
if (lineEnd < 0) {
 
−
lineEnd = textLength;
 
−
}
 
−
selectedNew = textareaElement.value.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 = textareaElement.value.substring(0, lineStart) + selectedNew + textareaElement.value.substring(lineEnd);
 
−
}
 
−
 
−
// increase all headings in selected text
 
−
else {
 
−
var lines = selected.split('\n');
 
−
 
−
// cycle trough the lines
 
−
for (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 = textareaElement.value.substring(0, startPos) + selectedNew + textareaElement.value.substring(endPos);
 
−
}
 
−
textChanged = true;
 
−
}
 
−
 
−
// decrease heading level
 
−
if ('headingless'.indexOf(what) >= 0) {
 
−
var selectedNew = '';
 
−
 
−
// nothing selected, get current line
 
−
if (selected == '') {
 
−
var lineStart = textareaElement.value.lastIndexOf('\n', startPos - 1) + 1;
 
−
var lineEnd = textareaElement.value.indexOf('\n', startPos);
 
−
if (lineEnd < 0) {
 
−
lineEnd = textLength;
 
−
}
 
−
selectedNew = textareaElement.value.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 = textareaElement.value.substring(0, lineStart) + selectedNew + textareaElement.value.substring(lineEnd);
 
−
}
 
−
 
−
// increase all headings in selected text
 
−
else {
 
−
var lines = selected.split('\n');
 
−
 
−
// cycle trough the lines
 
−
for (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 = textareaElement.value.substring(0, startPos) + selectedNew + textareaElement.value.substring(endPos);
 
−
}
 
−
textChanged = true;
 
−
}
 
−
 
−
// replacements and text fixes
 
−
if ('spaces pipes 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 = textLength;
 
−
selectedFix = textareaElement.value;
 
−
}
 
−
else {
 
−
startPosFix = startPos;
 
−
endPosFix = endPos;
 
−
selectedFix = selected;
 
−
}
 
−
 
−
// apply fixes to selected text
 
−
if      ('spaces'.indexOf(what) >= 0) { selectedFix = FixSpaces(selectedFix); }
 
−
else if ('pipes'.indexOf (what) >= 0) { selectedFix = FixPipes (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 = textareaElement.value.substring(0, startPosFix) + selectedFix + textareaElement.value.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(textareaElement.value);
 
−
}
 
−
 
−
// 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(textareaElement.value);
 
−
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 = textareaElement.value.substr(0, matchedStart) + replace + textareaElement.value.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 (findText != '') {
 
−
 
−
// create regexp
 
−
var regExpFind = new RegExp(findText, regExpFlags + 'g');
 
−
 
−
 
−
// replace all in whole text
 
−
if (selected == '') {
 
−
 
−
// get the new cursorposition
 
−
textNew = textareaElement.value.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 = textareaElement.value.substr(0, startPos) + replace + textareaElement.value.substr(endPos);
 
−
}
 
−
textChanged = true;
 
−
}
 
−
}
 
−
 
−
// save search history to cookie
 
−
if ('findnext findprev'.indexOf(what) >= 0) {
 
−
AddToHistory('find');
 
−
}
 
−
if ('replacenext replaceprev replaceall'.indexOf(what) >= 0) {
 
−
AddToHistory('find');
 
−
AddToHistory('replace');
 
−
}
 
−
 
−
// get the find field from the selection or the current word
 
−
if ('findnext findprev replacenext replaceprev getfind'.indexOf(what) >= 0) {
 
−
if ( ('getfind'.indexOf(what) >= 0) || (find.value == '') ) {
 
−
 
−
// get from the selection
 
−
var newFind = '';
 
−
if (selected != '') {
 
−
  newFind = selected;
 
−
startPosNew = startPos;
 
−
endPosNew = endPos;
 
−
}
 
−
 
−
// get from the current word
 
−
else {
 
−
 
−
// get until next nonword char to the right
 
−
endPosNew = endPos;
 
−
  var pos = startPos;
 
−
  while (pos < textLength) {
 
−
    var character = textareaElement.value.substr(pos ++, 1);
 
−
    if ( character.match(/\W/) ) {
 
−
  endPosNew = pos - 1;
 
−
      break;
 
−
    }
 
−
newFind += character;
 
−
  }
 
−
 
−
// get until next nonword char to the left
 
−
startPosNew = startPos;
 
−
  pos = startPos - 1;
 
−
  while (pos >= 0) {
 
−
    var character = textareaElement.value.substr(pos --, 1);
 
−
    if ( character.match(/\W/) ) {
 
−
    startPosNew = pos + 2;
 
−
      break;
 
−
    }
 
−
    newFind = character + newFind;
 
−
  }
 
−
}
 
−
 
−
// replace newlines in find field
 
−
if (regExp.checked) {
 
−
find.value = newFind.replace(/\n/g, '\\n');
 
−
}
 
−
else {
 
−
find.value = newFind.replace(/\n.*/, '');
 
−
}
 
−
}
 
−
}
 
−
 
−
// undo all
 
−
if ('undoall'.indexOf(what) >= 0) {
 
−
startPosNew = startPos;
 
−
endPosNew = startPos;
 
−
textNew = editformOrig;
 
−
textChanged = true;
 
−
}
 
−
 
−
// jump to top / bottom
 
−
if ('updown'.indexOf(what) >= 0) {
 
−
if (scrollTopPx > scrollHeightPx / 2) {
 
−
startPosNew = 0;
 
−
endPosNew = 0
 
−
}
 
−
else {
 
−
startPosNew = textLength;
 
−
endPosNew = textLength;
 
−
}
 
−
posChanged = true;
 
−
}
 
−
 
−
// jump to the last changed position, event handler for button
 
−
if ('lastchangepos'.indexOf(what) >= 0) {
 
−
startPosNew = lastChangePos;
 
−
endPosNew = lastChangePos;
 
−
posChanged = true;
 
−
  }
 
−
 
−
// changed textarea, save undo info
 
−
if (textChanged) {
 
−
textareaElement.value = textNew;
 
−
SaveUndo(textareaElement.value, startPos, endPos);
 
−
SaveUndo(textNew, startPosNew, endPosNew);
 
−
textRows.changed = true;
 
−
posChanged = true;
 
−
}
 
−
 
−
// set the selection range
 
−
textareaElement.setSelectionRange(startPosNew, endPosNew);
 
−
 
−
// scroll the textarea to the selected text or cursor position
 
−
if (posChanged || textChanged) {
 
−
ParseRows();
 
−
}
 
−
if (posChanged) {
 
−
  ScrollTextarea(textRows.selStartRow, textRows.selEndRow, 0, findMargin, scrollTopPx);
 
−
}
 
−
else {
 
−
textareaElement.scrollTop = scrollTopPx;
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// scroll the textarea if the selected text is outside the viewport
 
−
//
 
−
 
−
function ScrollTextarea(rowStart, rowEnd, lines, margin, scrollTopPx) {
 
−
 
−
// get top row
 
−
  var scrollHeightPx = textareaElement.scrollHeight;
 
−
  var scrollTopRow = scrollTopPx / scrollHeightPx * textRows.rowTotal;
 
−
 
−
// cusor direction: up
 
−
if (lines <= 0) {
 
−
  if (scrollTopRow > (rowStart + lines) - margin) {
 
−
scrollTopRow = (rowStart + lines) - margin;
 
−
if (scrollTopRow < 0) {
 
−
  scrollTopRow = 0;
 
−
}
 
−
}
 
−
}
 
−
 
−
// cusor direction: down
 
−
if (lines >= 0) {
 
−
  if (scrollTopRow < (rowEnd + 1 + lines) + margin - textRows.rows) {
 
−
scrollTopRow = (rowEnd + 1 + lines) + margin - textRows.rows;
 
−
if (scrollTopRow > textRows.rowTotal + 1 - textRows.rows) {
 
−
  scrollTopRow = textRows.rowTotal + 1 - textRows.rows;
 
−
}
 
−
}
 
−
}
 
−
 
−
// set scroll position
 
−
textareaElement.scrollTop = scrollTopRow / textRows.rowTotal * scrollHeightPx;
 
−
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// ParseRows: get row structure of textarea
 
−
//
 
−
 
−
function ParseRows() {
 
−
 
−
textRows.selStart = textareaElement.selectionStart;
 
−
textRows.selEnd = textareaElement.selectionEnd;
 
−
 
−
// if the text has not changed we don't need to parse lines and rows
 
−
if (textRows.changed != true) {
 
−
if (textRows.textarea == null) {
 
−
textRows.changed = true;
 
−
}
 
−
else if (textRows.textarea.length != textareaElement.value.length) {
 
−
textRows.changed = true;
 
−
}
 
−
else if (textRows.textarea != textareaElement.value) {
 
−
textRows.changed = true;
 
−
}
 
−
}
 
−
  if (textRows.changed) {
 
−
textRows.changed = false
 
−
textRows.textarea = textareaElement.value;
 
−
textRows.cols = textareaElement.cols;
 
−
textRows.rows = textareaElement.rows;
 
−
 
−
// parse lines
 
−
textRows.lineStart = [];
 
−
textRows.lineLength = [];
 
−
var pos;
 
−
var posNext = 0;
 
−
var line = 0;
 
−
do {
 
−
pos = posNext;
 
−
textRows.lineStart[line] = pos;
 
−
posNext = textRows.textarea.indexOf('\n', pos) + 1;
 
−
textRows.lineLength[line] = posNext - pos - 1;
 
−
line ++;
 
−
} while (posNext > 0);
 
−
textRows.lineLength[line - 1] = textRows.textarea.length - pos;
 
−
  textRows.lineTotal = line;
 
−
 
−
// parse rows
 
−
textRows.rowStart = [];
 
−
textRows.rowLength = [];
 
−
var lineTotal = textRows.lineTotal;
 
−
var row = 0;
 
−
for (line = 0; line < lineTotal; line ++) {
 
−
var rowStart;
 
−
var rowStartNext = textRows.lineStart[line];
 
−
var lineEnd = rowStartNext + textRows.lineLength[line];
 
−
 
−
// cycle row by row to the end of the line
 
−
do {
 
−
rowStart = rowStartNext;
 
−
pos = 0;
 
−
posNext = rowStart;
 
−
if (rowStart + textRows.cols >= lineEnd) {
 
−
rowStartNext = lineEnd;
 
−
}
 
−
 
−
// find last space before or first after right border
 
−
else {
 
−
do {
 
−
pos = posNext;
 
−
posNext = textRows.textarea.indexOf(' ', pos + 1);
 
−
} while ( (posNext >= 0) && (posNext <= rowStart + textRows.cols) && (posNext < lineEnd) );
 
−
if (pos > rowStart) {
 
−
rowStartNext = pos + 1;
 
−
}
 
−
else if ( (posNext >= 0) && (posNext < lineEnd) ) {
 
−
rowStartNext = posNext + 1;
 
−
}
 
−
else {
 
−
rowStartNext = lineEnd;
 
−
}
 
−
}
 
−
 
−
// jump over trailing spaces
 
−
while (textRows.textarea.charAt(rowStartNext) == ' ') {
 
−
rowStartNext ++;
 
−
}
 
−
 
−
// set row start and length
 
−
textRows.rowStart[row] = rowStart;
 
−
textRows.rowLength[row] = rowStartNext - rowStart;
 
−
row ++;
 
−
} while (rowStartNext < lineEnd);
 
−
}
 
−
  textRows.rowTotal = row;
 
−
}
 
−
 
−
// get text selection rows by stepwise approximation
 
−
var rowTotal = textRows.rowTotal;
 
−
var selStart = textRows.selStart;
 
−
var selEnd = textRows.selEnd;
 
−
 
−
// find the largest 2^n < rows
 
−
var add = 1;
 
−
while (add < rowTotal) {
 
−
  add = add * 2;
 
−
}
 
−
  add = add / 2;
 
−
 
−
// approximate with decreasing add
 
−
var selStartRow = add;
 
−
var selEndRow = add;
 
−
while (add >= 1) {
 
−
 
−
// approximate selection start
 
−
if (selStartRow >= rowTotal) {
 
−
selStartRow -= add;
 
−
}
 
−
else if (textRows.rowStart[selStartRow] > selStart) {
 
−
selStartRow -= add;
 
−
}
 
−
else {
 
−
selStartRow += add;
 
−
}
 
−
 
−
// approximate selection end
 
−
if (selEndRow >= rowTotal) {
 
−
selEndRow -= add;
 
−
}
 
−
else if (textRows.rowStart[selEndRow] > selEnd) {
 
−
selEndRow -= add;
 
−
}
 
−
else {
 
−
selEndRow += add;
 
−
}
 
−
  add = add / 2;
 
−
}
 
−
if (textRows.rowStart[selStartRow] > selStart) {
 
−
selStartRow --;
 
−
}
 
−
if (textRows.rowStart[selEndRow] > selEnd) {
 
−
selEndRow --;
 
−
}
 
−
textRows.selStartRow = selStartRow;
 
−
textRows.selEndRow = selEndRow;
 
−
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// 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 ');
 
−
text = text.replace(/ +\n/g, '\n');
 
−
 
−
// 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, ' || ');
 
−
}
 
−
 
−
// 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]');
 
−
 
−
// 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');
 
−
 
−
// spaces in comments
 
−
text = text.replace(/(<!--) *(.*?) *(-->)/g, '$1 $2 $3');
 
−
 
−
// empty lines around html comments, spaces in comments
 
−
text = text.replace(/\n+(<!--.*?-->)\n+/g, '\n$1\n\n');
 
−
text = text.replace(/^(<!--.*?-->)\n+/g, '$1\n');
 
−
text = text.replace(/\n+(<!--.*?-->)$/g, '\n$1');
 
−
 
−
// 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 space around vertical bars
 
−
//
 
−
 
−
function FixPipes(text) {
 
−
 
−
// fix basic
 
−
text = FixSpaces(text);
 
−
 
−
// 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, ' | ');
 
−
return(p1 + p2 + p3);
 
−
}
 
−
);
 
−
 
−
return(text);
 
−
}
 
−
 
−
 
−
//
 
−
// fix html to wikicode
 
−
//
 
−
 
−
function FixHTML(text) {
 
−
 
−
// fix basic
 
−
text = FixSpaces(text);
 
−
 
−
// convert italic
 
−
text = text.replace(/<i(\s.*?)?>|<\/i(\s.*?)?>/gi, '\'\'');
 
−
 
−
// convert bold
 
−
text = text.replace(/<b(\s.*?)?>|<\/b(\s.*?)?>/gi, '\'\'\'');
 
−
 
−
// convert tables
 
−
text = text.replace(/\s*<\/td(\s.*?)?>\s*/gi, '');
 
−
text = text.replace(/\s*<\/th(\s.*?)?>\s*/gi, '');
 
−
text = text.replace(/\s*<\/tr(\s.*?)?>\s*/gi, '');
 
−
 
−
text = text.replace(/\s*<td\s*>\s*/gi, '\n| ');
 
−
text = text.replace(/\s*<td\s+(.*?)? *>\s*/gi,
 
−
function (p, p1) {
 
−
return('\n| ' + p1.replace(/\s+/g, ' ') + ' | ');
 
−
}
 
−
);
 
−
text = text.replace(/\s*<th\s*>\s*/gi, '\n! ');
 
−
text = text.replace(/\s*<th\s+(.*?)? *>\s*/gi,
 
−
function (p, p1) {
 
−
return('\n! ' + p1.replace(/\s+/g, ' ') + ' | ');
 
−
}
 
−
);
 
−
 
−
text = text.replace(/\s*<tr\s*>\s*/g, '\n|-\n');
 
−
text = text.replace(/\s*<tr\s+(.*?)? *>\s*/gi,
 
−
function (p, p1) {
 
−
return('\n|- ' + p1.replace(/\s+/g, ' ') + '\n');
 
−
}
 
−
);
 
−
 
−
text = text.replace(/\s*<table\s*>\s*(\|-\n)?/gi, '\n{|\n');
 
−
text = text.replace(/\s*<table\s+(.*?)? *>\s*(\|-\n)?/gi,
 
−
function (p, p1) {
 
−
return('\n{| ' + p1.replace(/\s+/g, ' ') + '\n');
 
−
}
 
−
);
 
−
text = text.replace(/\s*<\/table\s+(.*?)?>\s*/gi, '\n|}\n');
 
−
 
−
// convert links
 
−
text = text.replace(/<a\s+(.*?)href\s*=\s*(\"|\')\s*(\S*?)\s*(\"|\')(.*?)>\s*(.*?)\s*<\/a>/gi,
 
−
function (p, p1, p2, p3, p4, p5, p6) {
 
−
if (p6 == '') {
 
−
return('[' + p3 + ']');
 
−
}
 
−
return('[' + p3 + ' ' + p6.replace(/\s+/g, ' ') + ']');
 
−
}
 
−
);
 
−
text = text.replace(/<a\s+(.*?)href\s*=\s*(\S*?)\s+(.*?)>\s*(.*?)\s*<\/a>/gi,
 
−
function (p, p1, p2, p3, p4) {
 
−
if (p4 == '') {
 
−
return('[' + p2 + ']');
 
−
}
 
−
return('[' + p2 + ' ' + p4.replace(/\s+/g, ' ') + ']');
 
−
}
 
−
);
 
−
 
−
// convert images
 
−
text = text.replace(/<img\s+(.*?)src\s*=\s*(\"|\')\s*(\S*?)\s*(\"|\')(.*?)>/gi,
 
−
function (p, p1, p2, p3, p4, p5) {
 
−
return('[[Image:' + p3.replace(/^.*\/([^\/]+)$/, '$1') + ']]');
 
−
}
 
−
);
 
−
text = text.replace(/<img\s+(.*?)src\s*=\s*(\S*?)\s+(.*?)>/gi,
 
−
function (p, p1, p2, p3) {
 
−
return('[[Image:' + p2.replace(/^.*\/([^\/]+)$/, '$1') + ']]');
 
−
}
 
−
);
 
−
 
−
// to do: lists, h1 - hx
 
−
 
−
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(/^([\*\#\:\;]+ (\&\w+\;|\{\{.*$|[\W\d])*)([^\W\d].*)$/gm,
 
−
function (p, p1, p2, p3) {
 
−
if ( ! p3.match(/^(http|ftp|alpha|beta|gamma|delta|epsilon|kappa|lambda)/) ) {
 
−
p3 = p3.substr(0, 1).toUpperCase() + p3.substr(1);
 
−
}
 
−
return(p1 + p3);
 
−
}
 
−
);
 
−
 
−
 
−
// uppercase link lists (link)
 
−
text = text.replace(/^([\*\#\:\;]+ \[\[)([^\n]*?)(\]\])/gm,
 
−
function (p, p1, p2, p3) {
 
−
 
−
// uppercase link
 
−
p2 = p2.replace(/^((\&\w+\;|[\W\d])*)([^\W\d].*)$/,
 
−
function (p, p1, p2, p3) {
 
−
if ( ! p3.match(/^(http|ftp|alpha|beta|gamma|delta|epsilon|kappa|lambda)/) ) {
 
−
p3 = p3.substr(0, 1).toUpperCase() + p3.substr(1);
 
−
}
 
−
return(p1 + p3);
 
−
}
 
−
);
 
−
 
−
// uppercase comment
 
−
p2 = p2.replace(/(\| *(\&\w+\;|[\W\d])*)([^\W\d].*)$/,
 
−
function (p, p1, p2, p3) {
 
−
if ( ! p3.match(/^(http|ftp|alpha|beta|gamma|delta|epsilon|kappa|lambda)/) ) {
 
−
p3 = p3.substr(0, 1).toUpperCase() + p3.substr(1);
 
−
}
 
−
return(p1 + p3);
 
−
}
 
−
);
 
−
return(p1 + p2 + p3);
 
−
}
 
−
);
 
−
 
−
// uppercase headings
 
−
text = text.replace(/^(==+ (\&\w+\;|[\W\d])*)([^\W\d].* ==+)$/gm,
 
−
function (p, p1, p2, p3) {
 
−
if ( ! p3.match(/^(http|ftp|alpha|beta|gamma|delta|epsilon|kappa|lambda)/) ) {
 
−
p3 = p3.substr(0, 1).toUpperCase() + p3.substr(1);
 
−
}
 
−
return(p1 + p3);
 
−
}
 
−
);
 
−
 
−
// uppercase images
 
−
text = text.replace(/(\[\[)image:(\w)([^\n]*\]\])/igm,
 
−
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(/&mdash;/g, '—');
 
−
text = text.replace(/&ndash;/g, '–');
 
−
text = text.replace(/&minus;/g, '\u2212');
 
−
 
−
// convert -- and em dashes with or without spaces to em dash surrounded by spaces
 
−
text = text.replace(/([a-zA-Z\'\"”\]\}\)]) *(--|—|&mdash;) *([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\'\"”\]\}])( |&nbsp;)+(\u2212|–|&ndash;) +([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$2');
 
−
 
−
// convert dashes to en dashes in dates
 
−
text = text.replace(/([ \(][12]\d\d\d) ?(--?|—|&mdash;) ?([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 &deg; into actual ° symbol
 
−
text = text.replace(/&deg;/g, '°');
 
−
 
−
// convert the word ohm(s) or the html entity into the actual O symbol (Omega, not the actual ohm symbol &#8486;) 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)? ?(&Omega;|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) ?(&mu;|µ|&micro;)(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 ON WHOLE DOCUMENT OR <math> </math> WIKICODE!
 
−
//
 
−
 
−
function FixMath(text) {
 
−
 
−
// fix basic
 
−
text = FixSpaces(text);
 
−
 
−
// convert html entities into actual dash characters
 
−
text = text.replace(/&minus;/g, '\u2212');
 
−
text = text.replace(/&middot;/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.getElementById('wpSummary');
 
−
if (text.value.match(/ \*\/ $/)) {
 
−
text += ' ';
 
−
}
 
−
else if (text.value != '') {
 
−
text.value += '; ';
 
−
}
 
−
text.value += summary;
 
−
}
 
−
 
−
 
−
//
 
−
// save undo information
 
−
//
 
−
 
−
function SaveUndo(text, startPos, endPos) {
 
−
 
−
if (undoBufferLast == 0) {
 
−
undoBuffer[1] = textareaElement.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() {
 
−
 
−
if (undoBufferCurr - 1 > undoBufferLast - undoBufferMax) {
 
−
if (undoBufferCurr - 1 >= 0) {
 
−
undoBufferCurr--;
 
−
var slot = undoBufferCurr % undoBufferMax;
 
−
textareaElement.value = undoBuffer[slot];
 
−
textareaElement.focus();
 
−
textareaElement.selectionStart = undoBufferSelStart[slot];
 
−
textareaElement.selectionEnd = undoBufferSelEnd[slot];
 
−
textRows.changed = true;
 
−
ParseRows();
 
−
ScrollTextarea(textRows.selStartRow, textRows.selEndRow, 0, findMargin, textareaElement.scrollTop);
 
−
}
 
−
}
 
−
}
 
−
 
−
 
−
//
 
−
// redo
 
−
//
 
−
 
−
function Redo() {
 
−
 
−
if (undoBufferCurr + 1 <= undoBufferLast) {
 
−
undoBufferCurr++;
 
−
var slot = undoBufferCurr % undoBufferMax;
 
−
var slot = undoBufferCurr % undoBufferMax;
 
−
textareaElement.value = undoBuffer[slot];
 
−
textareaElement.focus();
 
−
textareaElement.selectionStart = undoBufferSelStart[slot];
 
−
textareaElement.selectionEnd = undoBufferSelEnd[slot];
 
−
textRows.changed = true;
 
−
  ParseRows();
 
−
  ScrollTextarea(textRows.selStartRow, textRows.selEndRow, 0, findMargin, textareaElement.scrollTop);
 
−
}
 
−
}
 
−
 
−
//
 
−
// resize textarea to ~100% by adapting cols
 
−
//
 
−
 
−
function ResizeTextarea() {
 
−
 
−
var textareaClone = document.getElementById('textareaClone');
 
−
var scrollTopPx = textareaElement.scrollTop;
 
−
textareaClone.style.width = '100%';
 
−
textareaClone.style.display = 'block';
 
−
var widthMax = textareaClone.offsetWidth;
 
−
textareaClone.style.width = 'auto';
 
−
 
−
// find optimal width
 
−
textareaClone.cols = 20;
 
−
for (var i = 64; i >= 1; i = i / 2) {
 
−
while (textareaClone.offsetWidth < widthMax) {
 
−
textareaClone.cols = textareaClone.cols + i;
 
−
}
 
−
textareaClone.cols = textareaClone.cols - i;
 
−
}
 
−
textareaClone.style.display = 'none';
 
−
textareaElement.cols = textareaClone.cols;
 
−
textareaElement.style.width = 'auto';
 
−
textareaElement.scrollTop = scrollTopPx;
 
−
 
−
// parse rows
 
−
textRows.changed = true;
 
−
  ParseRows();
 
−
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// convert strange spaces, remove non-\n linebreak characters
 
−
//
 
−
 
−
function convertStrangeSpaces() {
 
−
 
−
var startPos = textareaElement.selectionStart;
 
−
var endPos = textareaElement.selectionEnd;
 
−
 
−
var text = textareaElement.value;
 
−
text = text.replace(/[\t\v\u00a0\u2028\u2029]+/g, ' '); // \u00a0 = &nbsp;
 
−
text = text.replace(/[\r\f]/g, '');
 
−
textareaElement.value = text;
 
−
 
−
textareaElement.selectionStart = startPos;
 
−
textareaElement.selectionEnd = endPos;
 
−
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// setup routine for javascript editor
 
−
//
 
−
 
−
function SetupEditor() {
 
−
 
−
var html = '';
 
−
 
−
// check if the editor is already installed
 
−
if (document.getElementById('findText') != null) { return; }
 
−
 
−
// at the moment this works only for mozilla browsers (Mozilla, Mozilla Firefox, Mozilla SeaMonkey)
 
−
var browser = navigator.appName;
 
−
if (browser == null) { return; }
 
−
if (! /Netscape/i.test(browser)) { return; }
 
−
var version = navigator.appVersion.match(/\d+(\.\d+)/)[0];
 
−
if (version == null) { return; }
 
−
if (version < 5.0) { return; }
 
−
 
−
// get the textarea object
 
−
textareaElement = document.getElementById('wpTextbox1');
 
−
if (textareaElement == null) { return; }
 
−
 
−
// setup the undo buffers and get the original text for instant change view
 
−
undoBuffer[0] = textareaElement.value;
 
−
editformOrig = textareaElement.value;
 
−
 
−
// set textarea size to maximal row number, always show vertical scrollbar
 
−
  textareaElement.style.overflow = '-moz-scrollbars-vertical';
 
−
  textareaElement.style.overflowX = 'auto';
 
−
 
−
// convert strange spaces, remove non-\n linebreak characters
 
−
convertStrangeSpaces();
 
−
 
−
// add custom edit area stylesheet definition to head
 
−
var insert = document.getElementsByTagName('head')[0];
 
−
html = '';
 
−
html += '<style type="text/css">';
 
−
html += '.customEdit { ' + styleButtons + '}';
 
−
html += '.previewBox { ' + stylePreviewBox + ' }';
 
−
html += '</style>';
 
−
insert.innerHTML += html;
 
−
 
−
// create inputWrapper for textarea and buttons (fullscreen elements)
 
−
var inputWrapper = document.createElement('div');
 
−
inputWrapper.id = 'inputWrapper';
 
−
textareaElement.parentNode.insertBefore(inputWrapper, textareaElement);
 
−
 
−
// move textareaElement to textareaWrapper
 
−
var textareaWrapper = document.createElement('div');
 
−
textareaWrapper.id = 'textareaWrapper';
 
−
inputWrapper.appendChild(textareaWrapper);
 
−
textareaWrapper.appendChild(textareaElement);
 
−
 
−
// add all other buttons and inputs to buttonsWrapper
 
−
var buttonsWrapper = document.createElement('div');
 
−
buttonsWrapper.id = 'buttonsWrapper';
 
−
inputWrapper.appendChild(buttonsWrapper);
 
−
 
−
// add custom formatting buttons
 
−
var customEditButtons = document.createElement('div');
 
−
customEditButtons.id ='customEditButtons';
 
−
html = '';
 
−
 
−
// find, replace
 
−
html += '<div style="margin-top: 0.1em; margin-left: 0;" id="customEditRow1">';
 
−
html += '<input class="customEdit" type="button" value="Get" onclick="javascript:Edit(\'getfind\');" title="Get the find text from the selection">';
 
−
html += '<input class="customEdit" type="button" value="&larr;Find" onclick="javascript:Edit(\'findprev\');" title="Find previous">';
 
−
html += '<span style="position: relative; padding: 0; margin: 0 0.2em;" id="findComboInput">';
 
−
html += '<input class="customEdit" type="text" value="" style="height: 1.4em; font-family: monospace; height: 1.2em; padding: 0; margin: 0; position: absolute; left: 0; top: 0; z-index: 2;" onfocus="javascript:this.setSelectionRange(0, this.textLength);" id="findText" title="">';
 
−
html += '<select class="customEdit" id="findSelect" style="height: 1.5em; font-family: monospace; border: none; padding: 0; margin: 0; position: relative; vertical-align: baseline; z-index: 1;" onfocus="javascript:SetComboOptions(\'find\')" onChange="javascript:ChangeComboInput(\'find\');">';
 
−
html += '</select>';
 
−
html += '</span>';
 
−
html += '<input class="customEdit" type="button" value="Find&rarr;" onclick="javascript:Edit(\'findnext\');" title="Find next">';
 
−
html += '<span style="margin-left: 0.5em;"></span/>';
 
−
html += '<input class="customEdit" type="button" value="&uarr;&darr;" onclick="javascript:Edit(\'updown\');" title="Jump to the top / bottom">';
 
−
html += '<input class="customEdit" type="button" value="&crarr;" id="lastChangePos" onclick="javascript:Edit(\'lastchangepos\');" title="Jump to the last changed position">';
 
−
  html += '<span style="margin-left: 1em;"></span/>';
 
−
html += '<input class="customEdit" type="button" value="&larr;" onclick="javascript:Undo();" title="Undo button clicks">';
 
−
html += '<input class="customEdit" type="button" value="&rarr;" onclick="javascript:Redo();" title="Redo button clicks">';
 
−
html += '<span style="margin-left: 0.5em;"></span/>';
 
−
html += '<input class="customEdit" type="button" value="Undo all" onclick="javascript:Edit(\'undoall\');" title="Restore original text, can be undone">';
 
−
html += '<span style="margin-left: 1em;"></span/>';
 
−
html += '<input class="customEdit" type="button" style="font-weight: bold;" value="b" onclick="javascript:Edit(\'bold\');" title="Bold text">';
 
−
html += '<input class="customEdit" type="button" style="font-style: italic;" value="i" onclick="javascript:Edit(\'italic\');" title="Italic text">';
 
−
html += '<input class="customEdit" type="button" value="A&rarr;a" onclick="javascript:Edit(\'lowercase\');" title="Lowercase text">';
 
−
html += '<span style="margin-left: 0.5em;"></span/>';
 
−
html += '<input class="customEdit" type="button" value="=&larr;" onclick="javascript:Edit(\'headingless\');" title="Decrease heading level of current lines">';
 
−
html += '<input class="customEdit" type="button" value="&rarr;==" onclick="javascript:Edit(\'headingmore\');" title="Increase heading level of current lines">';
 
−
html += '<span style="margin-left: 0.5em;"></span/>';
 
−
html += '<input class="customEdit" type="button" value="&prod;" id="scrollToTop" title="Scroll text area to window top">';
 
−
html += '<input class="customEdit" type="button" id="fullScreenButtonFloat" style="display: none; position: absolute; z-index: 5;">';
 
−
html += '<input class="customEdit" type="button" id="fullScreenButton">';
 
−
html += '</div>';
 
−
 
−
// fixing functions
 
−
html += '<div style="margin-top: 0.2em; margin-bottom: 0.5em; margin-left: 0;" id="customEditRow2">';
 
−
html += '<input class="customEdit" type="button" value="All" onclick="javascript:Edit(\'replaceall\');" title="Replace all occurrences in whole text or selection">';
 
−
html += '<input class="customEdit" type="button" value="&larr;Repl." onclick="javascript:Edit(\'replaceprev\');" title="Replace previous">';
 
−
html += '<span style="position: relative; padding: 0; margin: 0 0.2em;" id="replaceComboInput">';
 
−
html += '<input class="customEdit" type="text" value="" style="height: 1.4em; font-family: monospace; height: 1.2em; padding: 0; margin: 0; position: absolute; left: 0; top: 0; z-index: 2;" onfocus="this.setSelectionRange(0, this.textLength);" id="replaceText" title="">';
 
−
html += '<select class="customEdit" id="replaceSelect" style="height: 1.5em; font-family: monospace; border: none; padding: 0; margin: 0; position: relative; vertical-align: baseline; z-index: 1;" onfocus="SetComboOptions(\'replace\')" onChange="javascript:ChangeComboInput(\'replace\');">';
 
−
html += '</select>';
 
−
html += '</span>';
 
−
html += '<input class="customEdit" type="button" value="Repl.&rarr;" onclick="javascript:Edit(\'replacenext\');" title="Replace">';
 
−
html += '<span title="Find ahead as you type (non-regexp only)"><input class="customEdit" style="margin: 0 0.2em 0 0.5em;" type="checkbox" value="1" id="findAhead">Find ahead</span>';
 
−
html += '<span title="Search should be case sensitive"><input class="customEdit" style="margin: 0 0.2em 0 0.3em;" type="checkbox" value="1" id="caseSensitive">Case</span>';
 
−
html += '<span title="Search should be a regular expression"><input class="customEdit" style="margin: 0 0.2em 0 0.3em;" type="checkbox" value="1" id="regExp">Regexp</span>';
 
−
html += '<span style="margin-left: 1em;">Fix:</span/>';
 
−
html += '<input class="customEdit" type="button" value="Basic" onclick="javascript:Edit(\'spaces\');" title="Fix blanks and empty lines">';
 
−
html += '<input class="customEdit" type="button" value="&nbsp;|&nbsp;" onclick="javascript:Edit(\'pipes\');" title="Fix blanks around vertical bars">';
 
−
html += '<input class="customEdit" type="button" value="k&Omega;" onclick="javascript:Edit(\'units\');" title="Fix units">';
 
−
html += '<input class="customEdit" type="button" value="&radic;" onclick="javascript:Edit(\'math\');" title="Fix math, DO NOT USE ON WHOLE TEXT OR <math></math> WIKICODE!!!">';
 
−
  html += '<span style="margin-left: 0.5em;"></span/>';
 
−
html += '<input class="customEdit" type="button" value="&mdash;" onclick="javascript:Edit(\'dashes\');" title="Fix dashes">';
 
−
html += '<input class="customEdit" type="button" value="html" onclick="javascript:Edit(\'html\');" title="Fix html to wikicode">';
 
−
html += '<input class="customEdit" type="button" value=".,:" onclick="javascript:Edit(\'punct\');" title="Fix spaces before puntuation">';
 
−
html += '<input class="customEdit" type="button" value="Aa" onclick="javascript:Edit(\'caps\');" title="Fix caps in headers and lists">';
 
−
html += '</div>';
 
−
customEditButtons.innerHTML = html;
 
−
buttonsWrapper.appendChild(customEditButtons);
 
−
 
−
// add elements to buttonsWrapper
 
−
var element = document.getElementById('editpage-copywarn');
 
−
while (element != null) {
 
−
if (element.id == 'editpage-specialchars') {
 
−
break;
 
−
}
 
−
next_element = element.nextSibling;
 
−
buttonsWrapper.appendChild(element);
 
−
element = next_element;
 
−
}
 
−
 
−
// add preview and changes buttons
 
−
var customPreview = document.createElement('span');
 
−
customPreview.id = 'customPreviewButtons';
 
−
html = '';
 
−
html += '<span style="margin-left: 0.5em; margin-right: 0.5em">';
 
−
html += 'Instant:\n';
 
−
  html += '<input type="button" class="customEdit" title="Show a preview below" value="Preview" id="instantPreview" onclick="NormalScreen(); document.getElementById(\'PreviewBox\').innerHTML = wiki2html(editform.wpTextbox1.value);">';
 
−
html += '<input type="button" class="customEdit" title="Show changes since your last preview below" value="Changes" id="instantDiff" onclick="NormalScreen(); document.getElementById(\'PreviewBox\').innerHTML = StringDiff(editformOrig, editform.wpTextbox1.value);">';
 
−
html += '<input type="button" class="customEdit" title="Clear the preview box" value="Clear" id="instantClear" onclick="NormalScreen(); document.getElementById(\'PreviewBox\').innerHTML = \'\';">';
 
−
html += '</span>';
 
−
html += 'Server:\n';
 
−
customPreview.innerHTML = html;
 
−
var preview = document.getElementById('wpPreview');
 
−
preview.parentNode.insertBefore(customPreview, preview);
 
−
 
−
// add preview box
 
−
var previewBox = document.createElement('div');
 
−
previewBox.id = 'customPreviewBox';
 
−
html = '';
 
−
html += '<div style="margin-top: 0.5em; margin-bottom: 0.5em; border-width: 1px; border-style: solid; border-color: #808080 #d0d0d0 #d0d0d0 #808080;" id="PreviewBoxOutline">';
 
−
html += '<div class="previewBox" style="padding: 5px; border-width: 1px; border-style: solid; border-color: #404040 #ffffff #ffffff #404040;" id="PreviewBox">';
 
−
html += '</div>';
 
−
html += '</div>';
 
−
html += '<input class="customEdit" type="button" value="Scroll up" id="scrollToTopBottom" title="Scroll text area to window top">';
 
−
previewBox.innerHTML = html;
 
−
inputWrapper.parentNode.insertBefore(previewBox, inputWrapper.nextSibling);
 
−
 
−
// move linebreak before checkboxes down
 
−
var summary = document.getElementById('wpSummary');
 
−
var checkboxSep = document.createTextNode('');
 
−
summary.parentNode.replaceChild(checkboxSep, summary.nextSibling);
 
−
 
−
// move 'Summary:' into submit button div
 
−
var summary = document.getElementById('wpSummary');
 
−
var summaryLabel = document.getElementById('wpSummaryLabel');
 
−
summary.parentNode.insertBefore(summaryLabel, summary.parentNode.firstChild);
 
−
 
−
// make the summary a combo box
 
−
var summary = document.getElementById('wpSummary');
 
−
var htmlPre = '';
 
−
var htmlPost = '';
 
−
html = '';
 
−
htmlPre  += ' <span style="position: relative;" id="summaryComboInput">';
 
−
html    += ' style="padding: 0; margin: 0; position: absolute; left: 0; top: 0; z-index: 2;" onfocus="this.setSelectionRange(0, this.textLength);"';
 
−
htmlPost += '<select style="border: none; padding: 0; margin: 0; position: relative; vertical-align: middle; z-index: 1;" id="wpSummarySelect" onfocus="javascript:SetComboOptions(\'summary\')" onchange="javascript:ChangeComboInput(\'summary\');">';
 
−
htmlPost += '</select>';
 
−
htmlPost += '</span>';
 
−
summary.parentNode.innerHTML = summary.parentNode.innerHTML.replace(/\s*(<input.*?id\=\"wpSummary\")(.*?>)/, htmlPre + '$1' + html + '$2' + htmlPost);
 
−
 
−
// add margin around submit buttons
 
−
var saveButton = document.getElementById('wpSave');
 
−
saveButton.parentNode.style.marginTop = '0.7em';
 
−
saveButton.parentNode.style.marginBottom = '0.5em';
 
−
 
−
// move copywarn down
 
−
var copywarn = document.getElementById('editpage-copywarn');
 
−
inputWrapper.parentNode.insertBefore(copywarn, previewBox.nextSibling);
 
−
 
−
// shorten submit button texts and add onclick handler
 
−
document.getElementById('wpPreview').value = 'Preview';
 
−
document.getElementById('wpDiff').value = 'Changes';
 
−
window.onsubmit = function() {
 
−
AddToHistory('summary');
 
−
};
 
−
 
−
// set up combo input boxes with history
 
−
fieldHist ['find'] = [];
 
−
cookieName['find'] = 'findHistory';
 
−
inputElement['find'] = new Object(document.getElementById('findText'));
 
−
selectElement['find'] = new Object(document.getElementById('findSelect'));
 
−
selectElement['find'].style.height = (inputElement['find'].clientHeight + 1) +'px';
 
−
 
−
fieldHist ['replace'] = [];
 
−
cookieName['replace'] = 'replaceHistory';
 
−
inputElement['replace'] = new Object(document.getElementById('replaceText'));
 
−
selectElement['replace'] = new Object(document.getElementById('replaceSelect'));
 
−
selectElement['replace'].style.height = (inputElement['replace'].clientHeight + 1) +'px';
 
−
 
−
fieldHist ['summary'] = [];
 
−
cookieName['summary'] = 'summaryHistory';
 
−
inputElement['summary'] = new Object(document.getElementById('wpSummary'));
 
−
selectElement['summary'] = new Object(document.getElementById('wpSummarySelect'));
 
−
selectElement['summary'].style.height = (inputElement['summary'].clientHeight + 1) +'px';
 
−
 
−
ResizeComboInput('find');
 
−
ResizeComboInput('replace');
 
−
ResizeComboInput('summary');
 
−
 
−
// setup fullscreen mode
 
−
 
−
// save textbox properties
 
−
normalTextareaWidth = getStyle(textareaElement, 'width');
 
−
normalTextareaHeight = getStyle(textareaElement, 'height');
 
−
normalTextareaMargin = getStyle(textareaElement, 'margin');
 
−
normalTextareaRows = textareaElement.rows;
 
−
 
−
// set fullscreen style fixes
 
−
var inputWrapper = document.getElementById('inputWrapper');
 
−
var content = document.getElementById('content');
 
−
var content = document.getElementById('content');
 
−
inputWrapper.style.lineHeight = getStyle(content, 'line-height');
 
−
 
−
// move globalWrapper elements to new subGlobalWrapper
 
−
var globalWrapper = document.getElementById('globalWrapper');
 
−
var subGlobalWrapper = document.createElement('div');
 
−
subGlobalWrapper.id = 'subGlobalWrapper';
 
−
globalWrapper.appendChild(subGlobalWrapper);
 
−
var element = globalWrapper.firstChild;
 
−
while (element != null) {
 
−
if (element.id == 'subGlobalWrapper') {
 
−
break;
 
−
}
 
−
next_element = element.nextSibling;
 
−
subGlobalWrapper.appendChild(element);
 
−
element = next_element;
 
−
}
 
−
 
−
// set original tree position of input area
 
−
normalTreePos = inputWrapper.nextSibling;
 
−
 
−
// set fullscreen button texts
 
−
var fullScreenButton = document.getElementById('fullScreenButton');
 
−
var floatButton = document.getElementById('fullScreenButtonFloat');
 
−
fullScreenButton.value = fullButtonValue;
 
−
fullScreenButton.title = fullButtonTitle;
 
−
floatButton.value = normalFloatButtonValue;
 
−
floatButton.title = normalButtonTitle;
 
−
 
−
// set button event handlers
 
−
document.captureEvents(Event.click);
 
−
document.captureEvents(Event.mouseover);
 
−
document.captureEvents(Event.keyup);
 
−
document.captureEvents(Event.keypress);
 
−
 
−
// fullscreen
 
−
fullScreenButton.onclick = FullScreen;
 
−
floatButton.onclick = NormalScreen;
 
−
floatButton.onblur = function() {
 
−
floatButton.style.right = '0.5em';
 
−
floatButton.style.bottom = '0.5em';
 
−
floatButton.style.top = '';
 
−
floatButton.style.left = '';
 
−
};
 
−
 
−
// scroll to text area top
 
−
var scrollToTop = document.getElementById('scrollToTop');
 
−
var scrollToTopBottom = document.getElementById('scrollToTopBottom');
 
−
scrollToTop.onmouseover = ScrollToTop;
 
−
scrollToTop.onclick = ScrollToTop;
 
−
scrollToTopBottom.onmouseover = ScrollToTop;
 
−
scrollToTopBottom.onclick = ScrollToTop;
 
−
 
−
// find ahead
 
−
var findText = document.getElementById('findText');
 
−
findText.onkeyup = FindAhead;
 
−
 
−
// cursor memory, jump to last changed position
 
−
textareaElement.onkeypress = KeyTextArea;
 
−
textareaElement.onkeyup = KeyTextArea;
 
−
textareaElement.onclick = ClickTextArea;
 
−
 
−
// submit buttons
 
−
var saveButton = document.getElementById('wpSave');
 
−
var previewButton = document.getElementById('wpPreview');
 
−
var diffButton = document.getElementById('wpDiff');
 
−
saveButton.onclick = function() { NormalScreen(); saveButton.onclick = null; saveButton.click(); };
 
−
previewButton.onclick = function() { NormalScreen(); previewButton.onclick = null; previewButton.click(); };
 
−
diffButton.onclick = function() { NormalScreen(); diffButton.onclick = null; diffButton.click(); };
 
−
 
−
// insert an invisible clone of the textarea for resizing
 
−
  var textareaClone = textareaElement.cloneNode(false);
 
−
  textareaClone.id = 'textareaClone';
 
−
  textareaClone.name = null;
 
−
  textareaClone.accesskey = null
 
−
  textareaClone.tabindex = null;
 
−
textareaClone.style.position = 'relative';
 
−
  textareaClone.style.display = 'none';
 
−
textareaClone.style.zIndex = '-5';
 
−
textareaClone.style.height = '';
 
−
textareaClone.rows = 1;
 
−
  textareaClone.style.overflow = 'scroll';
 
−
  textareaElement.parentNode.insertBefore(textareaClone, textareaElement.nextSibling);
 
−
 
−
// resize textarea and parse rows
 
−
window.onresize = ResizeTextarea;
 
−
ResizeTextarea();
 
−
 
−
// set textarea cursor to start
 
−
textareaElement.setSelectionRange(0, 0);
 
−
 
−
// default checkboxes
 
−
  if (findAheadSelected) {
 
−
    document.getElementById('findAhead').checked = true;
 
−
  }
 
−
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// FindAhead: find non-regexp text as you type, event handler for find field
 
−
//
 
−
 
−
function FindAhead() {
 
−
 
−
  if (document.getElementById('findAhead').checked) {
 
−
    if (!document.getElementById('regExp').checked) {
 
−
 
−
// get the find text
 
−
var find = document.getElementById('findText');
 
−
var findText = find.value;
 
−
 
−
// get checkboxes
 
−
var caseSensitive = document.getElementById('caseSensitive');
 
−
var regExp = document.getElementById('regExp');
 
−
 
−
// replace special characters for regexp search
 
−
var startPos = textareaElement.selectionStart;
 
−
findText = findText.replace(/([\\^\$\*\+\?\.\(\)\[\]\{\}\:\=\!\|\,\-])/g, '\\$1');
 
−
if ( ! caseSensitive.checked ) {
 
−
regExpFlags = 'i';
 
−
}
 
−
if (findText != '') {
 
−
 
−
// create regexp
 
−
var regExpFind = new RegExp(findText, regExpFlags);
 
−
 
−
// set start position for search to right
 
−
var indexStart;
 
−
var result;
 
−
indexStart = startPos;
 
−
 
−
// execute the regexp search to the right
 
−
regExpFind.lastIndex = indexStart;
 
−
result = regExpFind.exec(textareaElement.value);
 
−
 
−
// set the selection
 
−
if (result != null) {
 
−
 
−
// set the selection range
 
−
textareaElement.setSelectionRange(result.index, result.index + result[0].length);
 
−
 
−
// scroll the textarea to the selected text or cursor position
 
−
ParseRows();
 
−
if (textRows.selStartRow >= textRows.rows) {
 
−
  ScrollTextarea(textRows.selStartRow, textRows.selEndRow, 0, 0, 0);
 
−
}
 
−
else {
 
−
  ScrollTextarea(textRows.selStartRow, textRows.selEndRow, 0, 0, textareaElement.scrollHeight);
 
−
}
 
−
}
 
−
}
 
−
}
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// ClickTextArea: event handler for textarea clicks
 
−
//
 
−
 
−
function ClickTextArea(event) {
 
−
 
−
// reset cursor memory
 
−
  textRows.cursorMemory = null;
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// KeyTextArea: event handler for textarea keypresses
 
−
//
 
−
 
−
function KeyTextArea(event) {
 
−
 
−
// 'jump to last change' function
 
−
if (event.type == 'keyup') {
 
−
 
−
// left, right, up, down, page up, page down;
 
−
switch (event.keyCode) {
 
−
case 37: ; case 39: ; case 38: ; case 33: ; case 40: ; case 34: break;
 
−
default:
 
−
if (event.charCode != null) {
 
−
lastChangePos = textareaElement.selectionStart;
 
−
}
 
−
  }
 
−
  }
 
−
 
−
// cursor memory function
 
−
else if (event.type == 'keypress') {
 
−
 
−
// check if cursor memory has been enabled
 
−
if (cursorMemory != true) {
 
−
return;
 
−
}
 
−
 
−
// left, right
 
−
if ( (event.keyCode == 37) || (event.keyCode == 39) ) {
 
−
textRows.cursorMemory = null;
 
−
}
 
−
 
−
// up, down, page up, page down; contains a workaround for a bug that misplaces cusor in empty lines
 
−
else if ( (event.keyCode == 38) || (event.keyCode == 40) || (event.keyCode == 33) || (event.keyCode == 34) ) {
 
−
ParseRows();
 
−
var row = textRows.selStartRow;
 
−
var col;
 
−
if (textRows.cursorMemory != null) {
 
−
col = textRows.cursorMemory;
 
−
}
 
−
else {
 
−
col = textRows.selEnd - textRows.rowStart[row];
 
−
textRows.cursorMemory = col;
 
−
}
 
−
var lines;
 
−
 
−
// up, down, page up, page down
 
−
switch (event.keyCode) {
 
−
case 38: lines = -1; break;
 
−
case 33: lines = scrollMargin - textRows.rows; break;
 
−
case 40: lines = 1; break;
 
−
case 34: lines = textRows.rows - scrollMargin;
 
−
}
 
−
if ( ( (lines < 0) && (row > 0) ) || ( (lines > 0) && (row < textRows.rowTotal) ) ) {
 
−
row = row + lines;
 
−
if (row < 0) {
 
−
row = 0;
 
−
}
 
−
else if (row > textRows.rowTotal) {
 
−
row = textRows.rowTotal;
 
−
}
 
−
var pos;
 
−
if (textRows.rowLength[row] >= col) {
 
−
pos = textRows.rowStart[row] + col;
 
−
if (!event.metaKey && !event.shiftKey && !event.ctrlKey) {
 
−
textareaElement.setSelectionRange(pos, pos);
 
−
event.preventDefault();
 
−
}
 
−
}
 
−
else {
 
−
pos = textRows.rowStart[row] + textRows.rowLength[row];
 
−
}
 
−
ScrollTextarea(textRows.selStartRow, textRows.selEndRow, lines, scrollMargin, textareaElement.scrollTop);
 
−
}
 
−
}
 
−
else {
 
−
textRows.changed = true;
 
−
}
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// ScrollToTop: event handler for scroll to textarea top button
 
−
//
 
−
 
−
function ScrollToTop(event) {
 
−
 
−
var scrollToTop = document.getElementById('scrollToTop');
 
−
var scrollToTopBottom = document.getElementById('scrollToTopBottom');
 
−
var textarea = document.getElementById('textareaWrapper');
 
−
var buttons = document.getElementById('buttonsWrapper');
 
−
var textareaTop = getOffsetTop(textarea);
 
−
var buttonsTop = getOffsetTop(buttons);
 
−
var offset = window.pageYOffset;
 
−
 
−
// click
 
−
if (event.type == 'click') {
 
−
if (offset == textareaTop) {
 
−
  window.scroll(0, buttonsTop);
 
−
scrollToTop.title = "Scroll text area to window top";
 
−
scrollToTopBottom.title = "Scroll text area to window top";
 
−
}
 
−
else {
 
−
window.scroll(0, textareaTop);
 
−
scrollToTop.title = "Scroll button area to window top";
 
−
scrollToTopBottom.title = "Scroll button area to window top";
 
−
}
 
−
}
 
−
 
−
// mouseover
 
−
else {
 
−
if (offset == textareaTop) {
 
−
scrollToTop.title = "Scroll button area to window top";
 
−
scrollToTopBottom.title = "Scroll button area to window top";
 
−
}
 
−
else {
 
−
scrollToTop.title = "Scroll text area to window top";
 
−
scrollToTopBottom.title = "Scroll text area to window top";
 
−
}
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
 
−
//
 
−
// FullScreen: change to fullscreen input area; event handler for fullscreen buttons
 
−
//
 
−
 
−
function FullScreen(event) {
 
−
 
−
fullScreenMode = true;
 
−
 
−
// save window scroll position
 
−
normalPageYOffset = window.pageYOffset;
 
−
normalPageXOffset = window.pageXOffset;
 
−
 
−
// get fullscreen button coordinates
 
−
var buttonOffsetLeft = event.pageX - window.pageXOffset;
 
−
var buttonOffsetTop = event.pageY - window.pageYOffset;
 
−
 
−
// move the input area up in the tree
 
−
var inputWrapper = document.getElementById('inputWrapper');
 
−
var globalWrapper = document.getElementById('globalWrapper');
 
−
var subGlobalWrapper = document.getElementById('subGlobalWrapper');
 
−
globalWrapper.insertBefore(inputWrapper, subGlobalWrapper);
 
−
 
−
// set input area to fullscreen
 
−
inputWrapper.style.position = 'fixed';
 
−
inputWrapper.style.top = '0';
 
−
inputWrapper.style.left = '0';
 
−
inputWrapper.style.right = '0';
 
−
inputWrapper.style.bottom = '0';
 
−
var content = document.getElementById('content');
 
−
inputWrapper.style.backgroundColor = getStyle(content, 'background-color');
 
−
var buttonsWrapper = document.getElementById('buttonsWrapper');
 
−
buttonsWrapper.style.paddingLeft = '0.5em'
 
−
buttonsWrapper.style.paddingBottom = '0.5em'
 
−
 
−
// set textarea size
 
−
textareaElement.style.margin = '0';
 
−
 
−
// set the textarea to maximal height
 
−
var textareaWrapper = document.getElementById('textareaWrapper');
 
−
textareaElement.style.height = (window.innerHeight - buttonsWrapper.offsetHeight - 4) + 'px';
 
−
 
−
// hide the rest of the page
 
−
subGlobalWrapper.style.display = 'none';
 
−
 
−
// set floating 'back to normal' button
 
−
var floatButton = document.getElementById('fullScreenButtonFloat');
 
−
floatButton.style.right = '';
 
−
floatButton.style.bottomt = '';
 
−
floatButton.style.display = 'inline';
 
−
floatButton.style.left = (buttonOffsetLeft - floatButton.offsetWidth / 2) + 'px';
 
−
floatButton.style.top = (buttonOffsetTop - floatButton.offsetHeight / 2) + 'px';
 
−
floatButton.focus();
 
−
 
−
// change fullscreen button text and handler
 
−
var fullScreenButton = document.getElementById('fullScreenButton');
 
−
fullScreenButton.value = normalButtonValue;
 
−
fullScreenButton.title = normalButtonTitle;
 
−
fullScreenButton.onclick = NormalScreen;
 
−
 
−
// set rows
 
−
var textareaClone = document.getElementById('textareaClone');
 
−
textareaClone.style.display = 'block';
 
−
  var rows = textareaElement.clientHeight / textareaClone.clientHeight * textareaClone.rows;
 
−
textareaClone.style.display = 'none';
 
−
textareaElement.rows = rows;
 
−
 
−
// resize textarea to defined cols number and parse rows
 
−
ResizeTextarea();
 
−
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// NormalScreen: change back to normal page view; event handler for fulscreen buttons
 
−
//
 
−
 
−
function NormalScreen() {
 
−
 
−
// check if we are in fullscreen mode
 
−
if (fullScreenMode != true) {
 
−
return;
 
−
}
 
−
fullScreenMode = false;
 
−
 
−
// hide floating 'back to normal' button
 
−
var floatButton = document.getElementById('fullScreenButtonFloat').style.display = 'none';
 
−
 
−
// show the rest of the page
 
−
document.getElementById('subGlobalWrapper').style.display = 'block';
 
−
 
−
// set input area back to the original position
 
−
var inputWrapper = document.getElementById('inputWrapper');
 
−
normalTreePos.parentNode.insertBefore(inputWrapper, normalTreePos);
 
−
inputWrapper.style.position = 'static';
 
−
inputWrapper.style.height = '';
 
−
inputWrapper.style.backgroundColor = '';
 
−
 
−
// reset textarea settings
 
−
textareaElement.style.width = normalTextareaWidth;
 
−
textareaElement.style.height = normalTextareaHeight;
 
−
textareaElement.style.margin = normalTextareaMargin;
 
−
textareaElement.rows = normalTextareaRows;
 
−
document.getElementById('buttonsWrapper').style.padding = '';
 
−
 
−
// change fullscreen button text and handler
 
−
var fullScreenButton = document.getElementById('fullScreenButton');
 
−
fullScreenButton.value = fullButtonValue;
 
−
fullScreenButton.title = fullButtonTitle;
 
−
fullScreenButton.onclick = FullScreen;
 
−
 
−
// reset window scroll position
 
−
window.scrollTo(normalPageXOffset, normalPageYOffset);
 
−
 
−
// resize textarea to defined cols number
 
−
ResizeTextarea();
 
−
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// ResizeComboInput: set the size of the background select boxes so that the button is visible
 
−
//
 
−
 
−
function ResizeComboInput(field) {
 
−
 
−
// add a dummy option
 
−
var dummy;
 
−
if (selectElement[field].options.length == 0) {
 
−
selectElement[field].options[0] = new Option('');
 
−
dummy = true;
 
−
}
 
−
 
−
// set option widths to 0
 
−
for (i = 0; i < selectElement[field].options.length; i ++) {
 
−
selectElement[field].options[i].style.width = '0';
 
−
}
 
−
 
−
// calculate select width
 
−
var inputWidth = inputElement[field].clientWidth;
 
−
var selectWidth = selectElement[field].clientWidth;
 
−
var optionWidth = selectElement[field].options[0].offsetWidth;
 
−
var border = inputElement[field].offsetWidth - inputElement[field].clientWidth;
 
−
selectElement[field].style.width = (selectWidth - optionWidth + inputWidth - border) + 'px';
 
−
 
−
// delete dummy option
 
−
if (dummy) {
 
−
selectElement[field].options[0] = null;
 
−
}
 
−
 
−
// set option widths to auto
 
−
for (i = 0; i < selectElement[field].options.length; i ++) {
 
−
selectElement[field].options[i].style.width = 'auto';
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// ChangeComboInput: set the input value to selected option; onchange event handler for select boxes
 
−
//
 
−
 
−
function ChangeComboInput(field) {
 
−
 
−
// get selection index (-1 for unselected)
 
−
var selected = selectElement[field].selectedIndex;
 
−
if (selected >= 0) {
 
−
 
−
// get selected option
 
−
var option = selectElement[field].options[selected];
 
−
if (option.text != '') {
 
−
 
−
// add case and regexp checkboxes to find / replace fields
 
−
if (option.value == 'setcheck') {
 
−
document.getElementById('caseSensitive').checked
 
−
= ( option.text.charAt(0) == checkMarker[true] );
 
−
document.getElementById('regExp').checked
 
−
= ( option.text.charAt(1) == checkMarker[true] );
 
−
inputElement[field].value = option.text.substr(3);
 
−
}
 
−
else {
 
−
inputElement[field].value = option.text;
 
−
}
 
−
}
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// AddToHistory: add an input value to the cookie history
 
−
//
 
−
 
−
function AddToHistory(field) {
 
−
 
−
if (inputElement[field].value != '') {
 
−
 
−
// load history from cookie
 
−
LoadHistoryFromCookie(field);
 
−
 
−
// add current value to history
 
−
fieldHist[field].unshift(inputElement[field].value);
 
−
 
−
// add case and regexp checkboxes to find / replace value
 
−
if ( (field == 'find') || (field == 'replace') ) {
 
−
fieldHist[field][0] =
 
−
checkMarker[ document.getElementById('caseSensitive').checked ] +
 
−
checkMarker[ document.getElementById('regExp').checked ] +
 
−
' ' + fieldHist[field][0];
 
−
}
 
−
 
−
// remove multiple old copies from history
 
−
i = 1;
 
−
while (i < fieldHist[field].length) {
 
−
if (fieldHist[field][i] == fieldHist[field][0]) {
 
−
fieldHist[field].splice(i, 1);
 
−
}
 
−
else {
 
−
i ++;
 
−
}
 
−
}
 
−
 
−
// remove new value if it is a preset value
 
−
i = 0;
 
−
if (presetOptions[field] != null) {
 
−
while (i < presetOptions[field].length) {
 
−
if (presetOptions[field][i] == fieldHist[field][0]) {
 
−
fieldHist[field].shift;
 
−
break;
 
−
}
 
−
else {
 
−
i ++;
 
−
}
 
−
}
 
−
}
 
−
 
−
// cut history to maximal history length
 
−
fieldHist[field] = fieldHist[field].slice(0, findHistoryLength);
 
−
 
−
// saved history to cookie
 
−
SaveHistoryToCookie(field);
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// SetComboOptions: generate the select options from cookie history; onfocus handler for select box
 
−
//
 
−
 
−
function SetComboOptions(field) {
 
−
 
−
// load history from cookie
 
−
LoadHistoryFromCookie(field);
 
−
 
−
var option = {};
 
−
var selected = null;
 
−
j = 0;
 
−
 
−
// delete options
 
−
var options = selectElement[field].options;
 
−
for (i = 0; i > options.length; i ++) {
 
−
selectElement[field].remove(i);
 
−
}
 
−
 
−
// delete optgroup
 
−
option = document.getElementById(field + 'Optgroup');
 
−
if (option != null) {
 
−
selectElement[field].removeChild(option);
 
−
}
 
−
 
−
// workaround for onchange not firing when selecting first option from unselected dropdown
 
−
option = document.createElement('option');
 
−
option.style.display = 'none';
 
−
selectElement[field].options[j++] = option;
 
−
 
−
// add history entries
 
−
for (i = 0; i < fieldHist[field].length; i ++) {
 
−
if (fieldHist[field][i] != null) {
 
−
if (fieldHist[field][i] == inputElement[field].value) {
 
−
selected = j;
 
−
}
 
−
option = document.createElement('option');
 
−
option.text = fieldHist[field][i];
 
−
if ( (field == 'find') || (field == 'replace') ) {
 
−
option.value = 'setcheck';
 
−
}
 
−
selectElement[field].options[j++] = option;
 
−
}
 
−
}
 
−
 
−
// add preset entries
 
−
if (presetOptions[field] != null) {
 
−
var startPreset = j;
 
−
for (i = 0; i < presetOptions[field].length; i ++) {
 
−
if (presetOptions[field][i] != null) {
 
−
if (presetOptions[field][i] == inputElement[field].value) {
 
−
selected = j;
 
−
}
 
−
option = document.createElement('option');
 
−
option.text = presetOptions[field][i];
 
−
selectElement[field].options[j++] = option;
 
−
}
 
−
}
 
−
 
−
// add a blank separator
 
−
if (startPreset > 1) {
 
−
option = document.createElement('optgroup');
 
−
option.label = '\u00a0';
 
−
option.id = field + 'Optgroup';
 
−
selectElement[field].insertBefore(option, selectElement[field].options[startPreset]);
 
−
}
 
−
}
 
−
 
−
// set the selection
 
−
selectElement[field].selectedIndex = selected;
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// LoadHistoryFromCookie: get the input box history from the respective cookie
 
−
//
 
−
 
−
function LoadHistoryFromCookie(field) {
 
−
var cookie = GetCookie(cookieName[field]);
 
−
if (cookie != null) {
 
−
cookie = decodeURIComponent(cookie);
 
−
fieldHist[field] = cookie.split('\n');
 
−
}
 
−
return;
 
−
}
 
−
 
−
 
−
//
 
−
// SaveHistoryToCookie: save the input box history to the respective cookie
 
−
//
 
−
 
−
function SaveHistoryToCookie(field) {
 
−
var cookieExpire = new Date();
 
−
cookieExpire.setTime( cookieExpire.getTime() + cookieExpireSec * 1000 );
 
−
var cookie = '';
 
−
cookie = fieldHist[field].join('\n')
 
−
cookie = encodeURIComponent(cookie);
 
−
SetCookie(cookieName[field], cookie, cookieExpire.toGMTString());
 
−
return;
 
−
}
 
−
 
−
 
−
// getStyle: get style properties for non-inline css definitions
 
−
function getStyle(element, styleProperty) {
 
−
var style;
 
−
if (element != null) {
 
−
style = document.defaultView.getComputedStyle(element, null).getPropertyValue(styleProperty);
 
−
}
 
−
return(style);
 
−
}
 
−
 
−
 
−
//
 
−
// GetCookie
 
−
//
 
−
 
−
function GetCookie(name) {
 
−
var cookie = ' ' + document.cookie;
 
−
var search = ' ' + name + '=';
 
−
var setStr = null;
 
−
var offset = 0;
 
−
var end = 0;
 
−
if (cookie.length > 0) {
 
−
offset = cookie.indexOf(search);
 
−
if (offset != -1) {
 
−
offset += search.length;
 
−
end = cookie.indexOf(';', offset)
 
−
if (end == -1) {
 
−
end = cookie.length;
 
−
}
 
−
setStr = cookie.substring(offset, end);
 
−
setStr = setStr.replace(/\\+/g, ' ');
 
−
setStr = decodeURIComponent(setStr);
 
−
}
 
−
}
 
−
return(setStr);
 
−
}
 
−
 
−
 
−
//
 
−
// SetCookie
 
−
//
 
−
 
−
function SetCookie(name, value, expires, path, domain, secure) {
 
−
document.cookie = name + '=' + encodeURIComponent(value) +
 
−
((expires) ? '; expires=' + expires : '') +
 
−
((path)    ? '; path=' + path : '') +
 
−
((domain)  ? '; domain=' + domain : '') +
 
−
((secure)  ? '; secure' : '');
 
−
}
 
−
 
−
//
 
−
// getOffsetTop: get element offset relative to left window border
 
−
//
 
−
 
−
function getOffsetTop(element) {
 
−
var offset = 0;
 
−
do {
 
−
offset += element.offsetTop;
 
−
} while ( (element = element.offsetParent) != null );
 
−
return(offset);
 
−
}
 
−
 
−
 
−
/* </nowiki></pre> */
 
−
 
−
 
−
 
−
 
−
 
−
var alwaysEval = false; //mettez cette valeur à true si vous voulez que l'evaluation soit lancée automatiquement (à éviter en temps normal)
 
−
function initEvalProjectNames()
 
−
{
 
−
        evalProjectNames=new Array(); //liste de vos projets
 
−
        evalProjectNames.push("Architecture")
 
−
        evalProjectNames.push("Littérature") //mettre ici autant de ligne comme celle ci que de projet que vous voulez évaluer
 
−
}
 

Version du 23 mai 2008 à 13:36