|
|
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(/—/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$2');
| |
− |
| |
− | // 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 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(/−/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.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 =
| |
− | 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="←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→" onclick="javascript:Edit(\'findnext\');" title="Find next">';
| |
− | html += '<span style="margin-left: 0.5em;"></span/>';
| |
− | html += '<input class="customEdit" type="button" value="↑↓" onclick="javascript:Edit(\'updown\');" title="Jump to the top / bottom">';
| |
− | html += '<input class="customEdit" type="button" value="↵" 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="←" onclick="javascript:Undo();" title="Undo button clicks">';
| |
− | html += '<input class="customEdit" type="button" value="→" 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→a" onclick="javascript:Edit(\'lowercase\');" title="Lowercase text">';
| |
− | html += '<span style="margin-left: 0.5em;"></span/>';
| |
− | html += '<input class="customEdit" type="button" value="=←" onclick="javascript:Edit(\'headingless\');" title="Decrease heading level of current lines">';
| |
− | html += '<input class="customEdit" type="button" value="→==" 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="∏" 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="←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.→" 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=" | " onclick="javascript:Edit(\'pipes\');" title="Fix blanks around vertical bars">';
| |
− | html += '<input class="customEdit" type="button" value="kΩ" onclick="javascript:Edit(\'units\');" title="Fix units">';
| |
− | html += '<input class="customEdit" type="button" value="√" 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="—" 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
| |
− | }
| |