User:Zocky/wikEdDev.js

/* */

/*

Zocky's hacks of User:Cacycle/wikEd. Hacks released under GPL.



var programHomepage = 'http://en.wikipedia.org/wiki/User:Cacycle/wikEd'; var programVersion = 'alpha'; var programDate    = 'September 12, 2006';

// // configuration variables //

// CSS rules edit frame var frameCSS = frameCSS || [];

frameCSS['body']             = frameCSS['body']             || 'background: #fff; margin: 0px; padding: 0.2em; overflow: -moz-scrollbars-vertical; overflow-x: auto;font-size:13px;padding:8px';

frameCSS['.wikEdLine']      = frameCSS['.wikEdLine']      || 'color: #333;'; frameCSS['.wikEdBlock']     = frameCSS['.wikEdBlock']     || ''; frameCSS['.wikEdInline']     = frameCSS['.wikEdInline']    || 'background: #ddd; color: #484; font-family: monospace; font-weight:bold'; frameCSS['.wikEdUnknown']    = frameCSS['.wikEdUnknown']   || 'background: red; color: white; font-weight: bold;'; frameCSS['.wikEdSub']        = frameCSS['.wikEdSub']       || 'position: relative; top: 0.3em; font-size:90%'; frameCSS['.wikEdSup']        = frameCSS['.wikEdSup']       || 'position: relative; top: -0.3em;font-size:90%'; frameCSS['.wikEdBold']       = frameCSS['.wikEdBold']      || 'color:#000; font-weight: bold;'; frameCSS['.wikEdComment']    = frameCSS['.wikEdComment']   || 'background-color: #ffff80;'; frameCSS['.wikEdDel']        = frameCSS['.wikEdDel']       || 'text-decoration: line-through;'; frameCSS['.wikEdIns']        = frameCSS['.wikEdIns']       || 'text-decoration: underline;'; frameCSS['.wikEdItalic']     = frameCSS['.wikEdItalic']    || 'font-style: italic;'; frameCSS['.wikEdRGB']        = frameCSS['.wikEdRGB']       || '';

// horizontal rule frameCSS['.wikEdHR']         = frameCSS['.wikEdHR']        || 'background-color: #d0d0d0;'; frameCSS['.wikEdHRInline']   = frameCSS['.wikEdHRInline']  || 'color: #999; font-family: monospace;';

// wiki code frameCSS['.wikEdWiki']       = frameCSS['.wikEdWiki']      || 'color: #999; font-family: monospace;'; frameCSS['.wikEdWikiRedir']  = frameCSS['.wikEdWikiRedir'] || 'color: #999; font-family: monospace;';

// headings frameCSS['.wikEdHeading']    = frameCSS['.wikEdHeading']   || 'font-weight:bold;font-size:120%;padding:8px 0;'; frameCSS['.wikEdHeadingWp']  = frameCSS['.wikEdHeadingWp'] || 'font-weight:bold;font-size:120%;padding:8px 0;';

// tables frameCSS['.wikEdTableBlock'] = frameCSS['.wikEdTableBlock'] || 'background-color: #f0f0f0;'; frameCSS['.wikEdTableLine']  = frameCSS['.wikEdTableLine'] || 'background-color: #f0f0f0;'; frameCSS['.wikEdTableTag']   = frameCSS['.wikEdTableTag']  || 'background-color: #f0f0f0; color: #0000e0; font-weight: bold;';

// list frameCSS['.wikEdListBlock']  = frameCSS['.wikEdListBlock'] || 'padding:4px 0;'; frameCSS['.wikEdListLine']   = frameCSS['.wikEdListLine']  || ''; frameCSS['.wikEdListTag']    = frameCSS['.wikEdListTag']   || 'color: teal; font-family: monospace;font-weight:bold;';

// space-pre frameCSS['.wikEdSpaceBlock'] = frameCSS['.wikEdSpaceBlock'] || 'background-color: #f0f0f0;'; frameCSS['.wikEdSpaceLine']  = frameCSS['.wikEdSpaceLine'] || 'background-color: #f0f0f0;'; frameCSS['.wikEdSpaceTag']   = frameCSS['.wikEdSpaceTag']  || 'color: #0000e0; font-weight: bold;';

// wiki links, images, categories, templates frameCSS['.wikEdLinkTag']    = frameCSS['.wikEdLinkTag']   || 'color: #999; font-family: monospace;';

frameCSS['.wikEdLink']       = frameCSS['.wikEdLink']      || ''; frameCSS['.wikEdImage']      = frameCSS['.wikEdImage']     || 'background:#ff8;'; frameCSS['.wikEdCat']        = frameCSS['.wikEdCat']       || 'background:#ff8'; frameCSS['.wikEdTempl']      = frameCSS['.wikEdTempl']     || 'background:#ff8;';

// interlanguage frameCSS['.wikEdInter']      = frameCSS['.wikEdInter']     || 'color: #999; font-family: monospace;'; frameCSS['.wikEdLinkInter']  = frameCSS['.wikEdLinkInter'] || ''; frameCSS['.wikEdImageInter'] = frameCSS['.wikEdImageInter'] || 'background:#ff8'; frameCSS['.wikEdCatInter']   = frameCSS['.wikEdCatInter']  || 'background:#ff8'; frameCSS['.wikEdTemplInter'] = frameCSS['.wikEdTemplInter'] || '';

// name frameCSS['.wikEdLinkName']   = frameCSS['.wikEdLinkName']  || 'color: #999; font-family: monospace;'; frameCSS['.wikEdImageName']  = frameCSS['.wikEdImageName'] || 'color: #999; font-family: monospace;'; frameCSS['.wikEdCatName']    = frameCSS['.wikEdCatName']   || 'color: #999; font-family: monospace;'; frameCSS['.wikEdTemplName']  = frameCSS['.wikEdTemplName'] || 'color: #999; font-family: monospace;'; frameCSS['.wikEdURLLink']    = frameCSS['.wikEdURLLink']   || 'color: #f00000; font-weight: bold;';

// text and parameters frameCSS['.wikEdLinkText']   = frameCSS['.wikEdLinkText']  || 'color:#00d;text-decoration:underline'; frameCSS['.wikEdLinkLiteral']   = frameCSS['.wikEdLinkLiteral']|| 'color:#00d;text-decoration:underline'; frameCSS['.wikEdImageText']  = frameCSS['.wikEdImageText'] || 'color: #999; font-family: monospace;'; frameCSS['.wikEdCatText']    = frameCSS['.wikEdCatText']   || 'color: #999; font-family: monospace;'; frameCSS['.wikEdTemplText']  = frameCSS['.wikEdTemplText'] || 'color: #999; font-family: monospace;'; frameCSS['.wikEdURLText']    = frameCSS['.wikEdURLText']   || 'font-weight: bold;';

// insert wikicode here frameCSS['.wikEdInsertHere'] = frameCSS['.wikEdInsertHere'] || 'background-color: orange; font-style: italic;';

// invisibles frameCSS['.wikEdTab']        = frameCSS['.wikEdTab']       || 'outline: silver dotted thin; display: inline;'; frameCSS['.wikEdBlank']      = frameCSS['.wikEdBlank']     || 'background-color: #ff0000; outline: black dotted thin; display: inline;';

// CSS rules main window var mainCSS = mainCSS || []; mainCSS['.wikEdCombo']          = mainCSS['.wikEdCombo']         || '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;'; mainCSS['.wikEdPreviewBox']     = mainCSS['.wikEdPreviewBox']    || 'background-color: #f9f9f9;';

mainCSS['.wikEdButtonsFormat']  = mainCSS['.wikEdButtonsFormat'] || 'background: #d4d0cc; border: 1px black solid; padding: 0.1em; margin: 0.2em 0.6em 0 0    ; float: left;'; mainCSS['.wikEdButtonsFind']    = mainCSS['.wikEdButtonsFind']   || 'background: #d4d0cc; border: 1px black solid; padding: 0.1em; margin: 0.2em 0.6em 0 0    ; float: left;'; mainCSS['.wikEdButtonsFix']     = mainCSS['.wikEdButtonsFix']    || 'background: #d4d0cc; border: 1px black solid; padding: 0.1em; margin: 0.2em 0.6em 0 0    ; float: left'; mainCSS['.wikEdButtonsWindow']  = mainCSS['.wikEdButtonsWindow'] || 'background: #d4d0cc; border: 1px black solid; padding: 0.1em; margin: 0.2em 0     0 0    ; float: right;'; mainCSS['.wikEdButtonsPreview'] = mainCSS['.wikEdButtonsPreview'] || 'background: #d4d0cc; border: 1px black solid; padding: 0.1em; margin: 0.2em 0    0 0.6em; float: right;';

mainCSS['.wikEdButton']         = mainCSS['.wikEdButton']        || 'vertical-align: text-top; font-size: small; text-decoration: underline; margin: 1px 2px; padding: 0; background: #d4d0cc; border: 1px #d4d0cc solid; cursor: pointer;'; mainCSS['.wikEdButton:hover']   = mainCSS['.wikEdButton:hover']  || 'background: #e4e0dd; border: 1px outset; cursor: pointer;'; mainCSS['.wikEdButton:active']  = mainCSS['.wikEdButton:active'] || 'background: #e4e0dc; border: 1px inset;  cursor: pointer;'; mainCSS['.wikEdButtonFloat']    = mainCSS['.wikEdButtonFloat']   || 'background: #d4d0cc; border: 1px outset; cursor: pointer; display: none; position: absolute; z-index: 5;'; mainCSS['.wikEdButtonChecked']  = mainCSS['.wikEdButtonChecked'] || 'vertical-align: text-top; font-size: small; text-decoration: underline; margin: 1px 2px; padding: 0; background: #f8f8f8; border: 1px inset;  cursor: pointer;'; mainCSS['.wikEdButtonUnchecked'] = mainCSS['.wikEdButtonUnchecked']|| 'vertical-align: text-top; font-size: small; text-decoration: underline; margin: 1px 2px; padding: 0; background: #e4e0dd; border: 1px outset; cursor: pointer;';

// levels of undo (each level holds the whole text) var undoBufferMax = undoBufferMax || 20;

// history length for summary, find and replace fields var findHistoryLength = findHistoryLength || 10;

// presets for input field dropdown options, {using} appends a link to this script var presetOptions = presetOptions || []; presetOptions['summary'] = presetOptions['summary'] || [ 'article created', 'intro rewrite', 'copyedit', 'linkfix', 'fixing typos', 'reverting test', 'reverting vandalism', 'formatting source text', '({using})' ];

// text for summary link to this script var summaryUsing = summaryUsing || 'using wikEd';

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

// highlight syntax var highlightSyntax = highlightSyntax || true;

// enable wikEd var useWikEd = useWikEd || true;

// image source (button images) var imagesPath = imagesPath || 'http://upload.wikimedia.org/wikipedia/commons/'; var image = image || []; image['align_buttons']     = image['align_buttons']      || imagesPath + '0/01/WikEd_align_buttons.png'; image['align_top']         = image['align_top']          || imagesPath + '1/13/WikEd_align_top.png'; image['bold']              = image['bold']               || imagesPath + '5/59/WikEd_bold.png'; image['bullet_list']       = image['bullet_list']        || imagesPath + '6/62/WikEd_bullet_list.png'; image['case']              = image['case']               || imagesPath + 'a/aa/WikEd_case.png'; image['case_sensitive']    = image['case_sensitive']     || imagesPath + '0/0d/WikEd_case_sensitive.png'; image['classic']           = image['classic']            || imagesPath + '9/9e/WikEd_classic.png'; image['clear_find']        = image['clear_find']         || imagesPath + 'f/f0/WikEd_clear_find.png'; image['clear_history']     = image['clear_history']      || imagesPath + 'c/c8/WikEd_clear_history.png'; image['close']             = image['close']              || imagesPath + '9/97/WikEd_close.png'; image['decrease_heading']  = image['decrease_heading']   || imagesPath + '7/72/WikEd_decrease_heading.png'; image['definition_list']   = image['definition_list']    || imagesPath + 'f/f5/WikEd_definition_list.png'; image['diff']              = image['diff']               || imagesPath + 'd/db/WikEd_diff.png'; image['error']             = image['error']              || imagesPath + '3/3e/WikEd_error.png'; image['find_ahead']        = image['find_ahead']         || imagesPath + '3/34/WikEd_find_ahead.png'; image['find_all']          = image['find_all']           || imagesPath + '7/75/WikEd_find_all.png'; image['find_next']         = image['find_next']          || imagesPath + 'a/ad/WikEd_find_next.png'; image['find_prev']         = image['find_prev']          || imagesPath + 'f/f5/WikEd_find_prev.png'; image['fix_all']           = image['fix_all']            || imagesPath + '8/86/WikEd_fix_all.png'; image['fix_basic']         = image['fix_basic']          || imagesPath + '3/30/WikEd_fix_basic.png'; image['fix_caps']          = image['fix_caps']           || imagesPath + '0/00/WikEd_fix_caps.png'; image['fix_chem']          = image['fix_chem']           || imagesPath + 'e/e7/WikEd_fix_chem.png'; image['fix_dash']          = image['fix_dash']           || imagesPath + 'e/e5/WikEd_fix_dash.png'; image['fix_html']          = image['fix_html']           || imagesPath + '0/05/WikEd_fix_html.png'; image['fix_math']          = image['fix_math']           || imagesPath + '3/3f/WikEd_fix_math.png'; image['fix_pipes']         = image['fix_pipes']          || imagesPath + '9/92/WikEd_fix_pipes.png'; image['fix_punct']         = image['fix_punct']          || imagesPath + 'd/db/WikEd_fix_punct.png'; image['fix_units']         = image['fix_units']          || imagesPath + '6/69/WikEd_fix_units.png'; image['fullscreen']        = image['fullscreen']         || imagesPath + 'd/d3/WikEd_fullscreen.png'; image['get_selection']     = image['get_selection']      || imagesPath + '9/96/WikEd_get_selection.png'; // image['get_selection_both'] = image['get_selection_both'] || imagesPath + '9/95/WikEd_get_selection_both.png'; image['image']             = image['image']              || imagesPath + '3/37/WikEd_image.png'; image['increase_heading']  = image['increase_heading']   || imagesPath + '5/50/WikEd_increase_heading.png'; image['indent_list']       = image['indent_list']        || imagesPath + '7/7a/WikEd_indent_list.png'; image['italic']            = image['italic']             || imagesPath + 'd/d4/WikEd_italic.png'; image['jump_next']         = image['jump_next']          || imagesPath + '5/54/WikEd_jump_next.png'; image['jump_prev']         = image['jump_prev']          || imagesPath + 'c/c7/WikEd_jump_prev.png'; image['jump_top_bottom']   = image['jump_top_bottom']    || imagesPath + '5/5d/WikEd_jump_top_bottom.png'; image['logo']              = image['logo']               || imagesPath + '6/67/WikEd_logo.png'; image['number_list']       = image['number_list']        || imagesPath + '3/3b/WikEd_number_list.png'; image['preview']           = image['preview']            || imagesPath + '3/31/WikEd_preview.png'; image['redirect']          = image['redirect']           || imagesPath + 'f/fa/WikEd_redirect.png'; image['redo']              = image['redo']               || imagesPath + 'd/d7/WikEd_redo.png'; image['redo_all']          = image['redo_all']           || imagesPath + '2/2d/WikEd_redo_all.png'; image['regexp']            = image['regexp']             || imagesPath + '6/6a/WikEd_regexp.png'; image['replace_all']       = image['replace_all']        || imagesPath + '2/2a/WikEd_replace_all.png'; image['replace_next']      = image['replace_next']       || imagesPath + 'b/b0/WikEd_replace_next.png'; image['replace_prev']      = image['replace_prev']       || imagesPath + 'a/a1/WikEd_replace_prev.png'; image['source']            = image['source']             || imagesPath + '0/02/WikEd_source.png'; image['subscript']         = image['subscript']          || imagesPath + '9/9e/WikEd_subscript.png'; image['superscript']       = image['superscript']        || imagesPath + 'b/bf/WikEd_superscript.png'; image['syntax']            = image['syntax']             || imagesPath + '6/67/WikEd_syntax.png'; image['table']             = image['table']              || imagesPath + 'b/bd/WikEd_table.png'; image['textify']           = image['textify']            || imagesPath + 'c/cd/WikEd_textify.png'; image['underline']         = image['underline']          || imagesPath + '2/21/WikEd_underline.png'; image['undo']              = image['undo']               || imagesPath + 'e/e6/WikEd_undo.png'; image['undo_all']          = image['undo_all']           || imagesPath + '0/08/WikEd_undo_all.png'; image['weblink']           = image['weblink']            || imagesPath + '1/16/WikEd_weblink.png'; image['wikify']            = image['wikify']             || imagesPath + '9/9f/WikEd_wikify.png'; image['wikilink']          = image['wikilink']           || imagesPath + '2/21/WikEd_wikilink.png'; // 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;

var editformOrig = ''; var editformLast = null;

// 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 textareaObj = {}; var frameBody = {}; var frameDocument = {}; var frameWindow = {};

var lastPosObj = null;

// counters var i; var j;

// add setup routine to addOnloadHook if (window.addOnloadHook != null) { addOnloadHook(WikEdSetup); }

// // WikEdSetup: setup routine, called //

function WikEdSetup {

var html = '';

// check if setup was already run if (document.getElementById('wikEdLogo') != null) { return; }

// insert logo into personal toolbar var logo = {}; logo.img = document.createElement('img'); logo.lnk = document.createElement('a'); logo.lnk.href = programHomepage; logo.lnk.alt = 'WikEd Logo'; logo.lnk.appendChild(logo.img); var listObj = document.createElement('li'); listObj.id = 'wikEdLogo'; listObj.appendChild(logo.lnk); var personalTools = document.getElementById('p-personal').getElementsByTagName('ul')[0]; personalTools.appendChild(listObj);

// set error logo SetLogo(logo, false);

// at the moment this works only for mozilla browsers (Mozilla, Mozilla Firefox, Mozilla SeaMonkey) if (navigator.appName == null) { return; }	var nameMatch = navigator.appName.match(/Netscape/i); if (nameMatch == null) { return; }	var name = nameMatch[0]; if ( (name == null) || (name == '') ) { return; }	var version = navigator.appVersion.match(/\d+(\.\d+)/)[0]; if ( (version == null) || (version < 5.0) ) { return; }

// check if this is an edit page textareaObj = document.getElementById('wpTextbox1'); if (textareaObj == null) {

// reset error indicator SetLogo(logo); return; }

// get initial textarea height var textareaHeight = textareaObj.offsetHeight;

// setup the undo buffers and get the original text for local changes view editformOrig = textareaObj.value;

// set textarea size to maximal row number, always show vertical scrollbar textareaObj.style.overflow = '-moz-scrollbars-vertical'; textareaObj.style.overflowX = 'auto';

// add stylesheet definitions var mainStyle = new StyleSheet; for (var rule in mainCSS) { mainStyle.addRule(rule, mainCSS[rule]); }

// create inputWrapper for textarea and buttons (fullscreen elements) var inputWrapper = document.createElement('div'); inputWrapper.id = 'inputWrapper'; textareaObj.parentNode.insertBefore(inputWrapper, textareaObj);

// move textareaObj to textareaWrapper var textareaWrapper = document.createElement('div'); textareaWrapper.id = 'textareaWrapper'; inputWrapper.appendChild(textareaWrapper); textareaWrapper.appendChild(textareaObj);

// add all other buttons and inputs to buttonsWrapper var buttonsWrapper = document.createElement('div'); buttonsWrapper.id = 'buttonsWrapper'; inputWrapper.appendChild(buttonsWrapper);

// add custom formatting buttons var wikEditButtons = document.createElement('div'); wikEditButtons.id = 'wikEditButtons'; html = '';

// format buttons html += ' ';

html += ''; html += '';

html += ''; html += ''; html += ''; html += ''; html += ''; html += '';

html += ''; html += '';

html += ''; html += '';

html += ' ';

html += ''; html += '';

html += ''; html += '';

html += '<img class="wikEdButton" src="' + image['bullet_list']     + '" width="16" height="16" alt="Bullet list"      title="Bulleted list"                        onClick="javascript:Edit(\'bulletlist\');">'; html += '<img class="wikEdButton" src="' + image['number_list']     + '" width="16" height="16" alt="Number list"      title="Numbered list"                        onClick="javascript:Edit(\'numberlist\');">'; html += '<img class="wikEdButton" src="' + image['indent_list']     + '" width="16" height="16" alt="Indent list"      title="Indented list"                        onClick="javascript:Edit(\'indentlist\');">'; html += '<img class="wikEdButton" src="' + image['definition_list'] + '" width="16" height="16" alt="Def list"         title="Definition list"                      onClick="javascript:Edit(\'deflist\');">';

html += '<img class="wikEdButton" src="' + image['image']           + '" width="16" height="16" alt="Image"            title="Image"                                onClick="javascript:Edit(\'image\');">'; html += '<img class="wikEdButton" src="' + image['table']           + '" width="16" height="16" alt="Table"            title="Table"                                onClick="javascript:Edit(\'table\');">';

html += '<img class="wikEdButton" src="' + image['wikify']          + '" width="16" height="16" alt="Wikify"           title="Wikify pasted content"                onClick="javascript:Edit(\'wikify\');">'; html += '<img class="wikEdButton" src="' + image['textify']         + '" width="16" height="16" alt="Textify"          title="Convert pasted content to plain text" onClick="javascript:Edit(\'textify\');">';

html += ' ';

// window functions: syntax highlighting, classic textarea, align, fullscreen html += ' ';

html += '<img class="wikEdButtonUnchecked" src="' + image['source']       + '" width="16" height="16" alt="Source"             title="Show the source code for testing purposes"    id="source"                onClick="javascript:Button(\'source\', true);" onLoad="javascript:Button(\'source\', null, false);" >'; html += '<img class="wikEdButtonUnchecked" src="' + image['syntax']       + '" width="16" height="16" alt="Syntax"             title="Highlight syntax"                             id="syntax"                onClick="javascript:Button(\'syntax\', true);" onLoad="javascript:Button(\'syntax\', null, highlightSyntax);" >'; html += '<img class="wikEdButton"         src="' + image['align_buttons'] + '" width="16" height="16" alt="Scroll to buttons"  title="Scroll to edit buttons"                       id="scrolltobuttons"       onClick="javascript:Button(\'scrolltobuttons\');">'; html += '<img class="wikEdButton"         src="' + image['align_top']     + '" width="16" height="16" alt="Scroll to textarea" title="Scroll to textarea"                           id="scrolltotop"           onClick="javascript:Button(\'scrolltotop\');">'; html += ' '; html += '<img class="wikEdButtonUnchecked" src="' + image['classic']      + '" width="16" height="16" alt="wikEd"              title="Use wikEd"                                    id="wikEd"                 onClick="javascript:Button(\'wikEd\', true);"           onLoad="javascript:Button(\'wikEd\', null, useWikEd);" >'; html += '<img class="wikEdButtonFloat"    src="' + image['fullscreen']    + '" width="16" height="16" alt="Fullscreen"         title="Switch to fullscreen mode"                    id="fullScreenButtonFloat" onClick="javascript:Button(\'fullScreenButtonFloat\');" onLoad="javascript:Button(\'fullScreenButtonFloat\', null, false);" >'; html += '<img class="wikEdButton"         src="' + image['fullscreen']    + '" width="16" height="16" alt="Fullscreen"         title="Switch to fullscreen mode"                    id="fullScreenButton"      onClick="javascript:Button(\'fullScreenButton\');"      onLoad="javascript:Button(\'fullScreenButton\', null, false);" >'; html += '<img class="wikEdButton"         src="' + image['clear_history'] + '" width="16" height="16" alt="Clear history"      title="Clear the find, replace, and summary history" id="clearhistory"          onClick="javascript:Button(\'clearhistory\');">'; html += ' ';

// find / replace buttons

html += ' ';

html += '<img class="wikEdButton" src="' + image['get_selection']     + '" width="16" height="16" alt="Get find"         title="Copy selection to find field (double click: copy selection to find and to replace field)" onClick="javascript:Edit(\'getfind\');" ondblclick="javascript:Edit(\'getfindreplace\');">'; html += '<img class="wikEdButton" src="' + image['find_all']          + '" width="16" height="16" alt="Find all"         title="Find all matches in whole text or selection"    onClick="javascript:Edit(\'findall\');">'; html += '<img class="wikEdButton" src="' + image['find_prev']         + '" width="16" height="16" alt="Find prev"        title="Find previous match"                            onClick="javascript:Edit(\'findprev\');">';

html += ' '; html += '<input class="wikEdCombo" 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="wikEdCombo" 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 += ' '; html += ' ';

html += '<img class="wikEdButton" src="' + image['find_next']         + '" width="16" height="16" alt="Find next"        title="Find next match"                                 onClick="javascript:Edit(\'findnext\');">'; html += '<img class="wikEdButton" src="' + image['jump_top_bottom']   + '" width="16" height="16" alt="Jump up/down"     title="Jump to the top / bottom"                        onClick="javascript:Edit(\'updown\');">'; html += '<img class="wikEdButton" src="' + image['jump_prev']         + '" width="16" height="16" alt="Jump prev"        title="Jump to previously changed position"             onClick="javascript:Edit(\'prevpos\');">'; html += '<img class="wikEdButton" src="' + image['jump_next']         + '" width="16" height="16" alt="Jump next"        title="Jump back to last position"                      onClick="javascript:Edit(\'lastpos\');">';

html += ' ';

//	html += '<img class="wikEdButton" src="' + image['get_selection_both'] + '" width="16" height="16" alt="Get both"        title="Copy selection to find and replace fields" onClick="javascript:Edit(\'getboth\');" ondblclick="javascript:Edit(\'getfindreplace\');">'; html += '<img class="wikEdButton" src="' + image['clear_find']        + '" width="16" height="16" alt="Clear find"       title="Clear the find field (to search for selected text)" onClick="javascript:Button(\'clearfind\');">'; html += '<img class="wikEdButton" src="' + image['replace_all']       + '" width="16" height="16" alt="Replace all"      title="Replace all matches in whole text or selection"             onClick="javascript:Edit(\'replaceall\');">'; html += '<img class="wikEdButton" src="' + image['replace_prev']      + '" width="16" height="16" alt="Replace prev"     title="Replace previous match"                                     onClick="javascript:Edit(\'replaceprev\');">';

html += ' '; html += '<input class="wikEdCombo" 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="wikEdCombo" 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 += ' '; html += ' ';

html += '<img class="wikEdButton" src="'         + image['replace_next']     + '" width="16" height="16" alt="Replace next"    title="Replace next match"              onClick="javascript:Edit(\'replacenext\');">';

html += '<img class="wikEdButtonUnchecked" src="' + image['case_sensitive']  + '" width="16" height="16" alt="Case sensitive"  title="Search is case sensitive"                               id="caseSensitive" onClick="javascript:Button(\'caseSensitive\', true);" onLoad="javascript:Button(\'caseSensitive\', null, false);" >'; html += '<img class="wikEdButtonUnchecked" src="' + image['regexp']          + '" width="16" height="16" alt="RegExp"          title="Search field is a regular expression"                   id="regExp"        onClick="javascript:Button(\'regExp\', true);"        onLoad="javascript:Button(\'regExp\', null, false);" >'; html += '<img class="wikEdButtonUnchecked" src="' + image['find_ahead']      + '" width="16" height="16" alt="Find ahead"      title="Find ahead as you type (only for non-regexp searches)"  id="findAhead"     onClick="javascript:Button(\'findAhead\', true);"     onLoad="javascript:Button(\'findAhead\', null, findAheadSelected);" >';

html += ' ';

// fixing buttons html += ' ';

html += '<img class="wikEdButton" src="' + image['fix_basic']       + '" width="16" height="16" alt="Fix basic"        title="Fix blanks and empty lines, always done by other fixing functions" onClick="javascript:Edit(\'fixbasic\');">';

html += '<img class="wikEdButton" src="' + image['fix_pipes']       + '" width="16" height="16" alt="Pipe spaces"      title="Add blanks around vertical bars in wikilinks"                      onClick="javascript:Edit(\'fixpipes\');">'; html += '<img class="wikEdButton" src="' + image['fix_punct']       + '" width="16" height="16" alt="Fix puntuation"   title="Fix spaces before puntuation"                                      onClick="javascript:Edit(\'fixpunct\');">'; html += '<img class="wikEdButton" src="' + image['fix_math']        + '" width="16" height="16" alt="Fix math"         title="Fix math"                                                          onClick="javascript:Edit(\'fixmath\');">'; html += '<img class="wikEdButton" src="' + image['fix_chem']        + '" width="16" height="16" alt="Fix chem"         title="Fix chemical formulas"                                             onClick="javascript:Edit(\'fixchem\');">';

html += ' ';

html += '<img class="wikEdButton" src="' + image['fix_units']       + '" width="16" height="16" alt="Fix units"        title="Fix units"                                                         onClick="javascript:Edit(\'fixunits\');">'; html += '<img class="wikEdButton" src="' + image['fix_dash']        + '" width="16" height="16" alt="Fix dashes"       title="Fix dashes"                                                        onClick="javascript:Edit(\'fixdashes\');">'; html += '<img class="wikEdButton" src="' + image['fix_html']        + '" width="16" height="16" alt="Fix html"         title="Fix html to wikicode"                                              onClick="javascript:Edit(\'fixhtml\');">'; html += '<img class="wikEdButton" src="' + image['fix_caps']        + '" width="16" height="16" alt="Fix caps"         title="Fix caps in headers and lists"                                     onClick="javascript:Edit(\'fixcaps\');">'; html += '<img class="wikEdButton" src="' + image['fix_all']         + '" width="16" height="16" alt="Fix all"          title="Fix units, dashes, html, and caps"                                 onClick="javascript:Edit(\'fixall\');">';

html += ' ';

html += '<br style="clear: both">';

wikEditButtons.innerHTML = html; buttonsWrapper.appendChild(wikEditButtons);

// 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 box upper buttons var previewBoxButtons = document.createElement('div'); previewBoxButtons.id = 'previewBoxButtons'; previewBoxButtons.className = 'wikEdButtonsPreview';

html = ''; html += '<img class="wikEdButton" src="' + image['preview']      + '" width="16" height="16" alt="Preview"        title="Show preview below"        id="preview"          onClick="javascript:Button(\'preview\');"          onLoad="javascript:Button(\'preview\', null, false, \'wikEdButton\');" >'; html += '<img class="wikEdButton" src="' + image['diff']         + '" width="16" height="16" alt="Changes"        title="Show changes below"        id="diff"             onClick="javascript:Button(\'diff\');"             onLoad="javascript:Button(\'diff\', null, false, \'wikEdButton\');" >'; html += '<img class="wikEdButton" src="' + image['close']        + '" width="16" height="16" alt="Close"          title="Close preview box"         id="close"            onClick="javascript:Button(\'close\');"            onLoad="javascript:Button(\'close\', null, false, \'wikEdButton\');" >'; html += '<img class="wikEdButton" src="' + image['align_buttons'] + '" width="16" height="16" alt="Scroll buttons" title="Scroll to edit buttons"   id="scrolltobuttons2" onClick="javascript:Button(\'scrolltobuttons2\');">'; html += '<img class="wikEdButton" src="' + image['align_top']    + '" width="16" height="16" alt="Scroll top"     title="Scroll to textarea"        id="scrolltotop2"     onClick="javascript:Button(\'scrolltotop2\');">';

previewBoxButtons.innerHTML = html; document.getElementById('wpSave').parentNode.insertBefore(previewBoxButtons, document.getElementById('wpSave').parentNode.firstChild);

// add preview box var previewBox = document.createElement('div'); previewBox.id = 'customPreviewBox'; previewBox.style.display = 'none';

html = ''; html += '<div style="clear: both; margin-top: 0.5em; margin-bottom: 0; border-width: 1px; border-style: solid; border-color: #808080 #d0d0d0 #d0d0d0 #808080;" id="PreviewBoxOutline">'; html += '<div class="wikEdPreviewBox" style="padding: 5px; border-width: 1px; border-style: solid; border-color: #404040 #ffffff #ffffff #404040;" id="PreviewBox">'; html += ' '; html += ' ';

html += ' '; html += '<img class="wikEdButton" src="' + image['preview']      + '" width="16" height="16" alt="Preview"        title="Show preview above"     id="preview2"         onClick="javascript:Button(\'preview2\');"         onLoad="javascript:Button(\'preview2\', null, false, \'wikEdButton\');" >'; html += '<img class="wikEdButton" src="' + image['diff']         + '" width="16" height="16" alt="Changes"        title="Show changes above"     id="diff2"            onClick="javascript:Button(\'diff2\');"            onLoad="javascript:Button(\'diff2\', null, false, \'wikEdButton\');" >'; html += '<img class="wikEdButton" src="' + image['close']        + '" width="16" height="16" alt="Close"          title="Close preview box"      id="close2"           onClick="javascript:Button(\'close2\');"           onLoad="javascript:Button(\'close2\', null, false, \'wikEdButton\');" >'; html += '<img class="wikEdButton" src="' + image['align_buttons'] + '" width="16" height="16" alt="Scroll buttons" title="Scroll to edit buttons" id="scrolltobuttons3" onClick="javascript:Button(\'scrolltobuttons3\');">'; html += '<img class="wikEdButton" src="' + image['align_top']    + '" width="16" height="16" alt="Scroll top"     title="Scroll to textarea"     id="scrolltotop3"     onClick="javascript:Button(\'scrolltotop3\');">'; html += ' ';

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); summary.parentNode.style.marginTop = '0.25em';

// make the summary a combo box var summary = document.getElementById('wpSummary'); var htmlPre = ''; var htmlPost = ''; html = ''; htmlPre += ' '; 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 += ' '; htmlPost += ' '; summary.parentNode.innerHTML = summary.parentNode.innerHTML.replace(/\s*(<input\b[^>]*?id\=\"wpSummary\")([^>]*>)/, htmlPre + '$1' + html + '$2' + htmlPost);

// add margin around submit buttons var saveButton = document.getElementById('wpSave'); saveButton.parentNode.style.marginTop = '0.5em'; saveButton.parentNode.style.marginBottom = '0.5em';

// move copywarn down var copywarn = document.getElementById('editpage-copywarn'); inputWrapper.parentNode.insertBefore(copywarn, previewBox.nextSibling);

// showikEdn submit button texts and add onclick handler document.getElementById('wpPreview').value = 'Preview'; document.getElementById('wpDiff').value = 'Changes';

// 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(textareaObj, 'width'); normalTextareaHeight = GetStyle(textareaObj, 'height'); normalTextareaMargin = GetStyle(textareaObj, 'margin'); normalTextareaRows = textareaObj.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; }

// create iframe

// moving an iframe in design mode may crash seamonkey var frameWrapper = document.createElement('div'); frameWrapper.id = 'frameWrapper'; html = ''; html += '<div id="frameBorderOuter" style="width: 100%; margin-top: 0.5em; margin-bottom: 0.1em; border-width: 1px; border-style: solid; border-color: #808080 #d0d0d0 #d0d0d0 #808080;">'; html += '<div id="frameBorderInner" style="padding: 0; border-width: 1px; border-style: solid; border-color: #404040 #ffffff #ffffff #404040;">'; html += ' '; html += '<iframe id="wikEdFrame" name="wikEdFrame" style="width: 100%; height: ' + textareaHeight + 'px; padding: 0; margin: 0; border: none;"> '; html += ' '; html += ' ';

frameWrapper.innerHTML = html; inputWrapper.insertBefore(frameWrapper, textareaWrapper);

frameWindow = document.getElementById('wikEdFrame').contentWindow; frameDocument = frameWindow.document;

// fill the frame with content html = ''; html += '  '; html += '<body id="frameBody" onload="window.document.designMode = \'on\'; window.document.execCommand(\'styleWithCSS\', false, false);">'; html += ' '; frameDocument.open; frameDocument.write(html); frameDocument.close; frameBody = frameDocument.body;

// add frame stylesheet definition var frameStyle = new StyleSheet(frameDocument); for (var rule in frameCSS) { frameStyle.addRule(rule, frameCSS[rule]); }

// 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 frame events frameDocument.addEventListener('keypress', KeyFrame, true); frameDocument.addEventListener('mousedown', KeyFrame, true);

// set fullscreen events fullScreenButton.addEventListener('click', FullScreen, true); floatButton.addEventListener('click', NormalScreen, true);

floatButton.onblur = function { floatButton.style.right = '0.5em'; floatButton.style.bottom = '0.5em'; floatButton.style.top = ''; floatButton.style.left = ''; };

// find ahead events var findText = document.getElementById('findText'); findText.addEventListener('keyup', FindAhead, true);

// submit button events var saveButton = document.getElementById('wpSave'); var previewButton = document.getElementById('wpPreview'); var diffButton = document.getElementById('wpDiff'); saveButton.onclick = function { if (useWikEd == true) { UpdateTextarea; }		AddToHistory('summary'); saveButton.onclick = null; saveButton.click; };	previewButton.onclick = function { if (useWikEd == true) { UpdateTextarea; }		previewButton.onclick = null; previewButton.click; };	diffButton.onclick = function { if (useWikEd == true) { UpdateTextarea; }		diffButton.onclick = null; diffButton.click; };

// set textarea cursor to start //	textareaObj.setSelectionRange(0, 0);

if (useWikEd != true) { document.getElementById('wikEdButtonsFormat').style.display = 'none'; document.getElementById('wikEdButtonsFind').style.display = 'none'; document.getElementById('wikEdButtonsFix').style.display = 'none'; document.getElementById('wikEdButtonsWindow').style.display = 'block'; }	else { UpdateFrame; document.getElementById('textareaWrapper').style.display = 'none'; document.getElementById('frameWrapper').style.display = 'block'; }

// disable scrolling to edit window on next preview page document.getElementById('editform').action += '&noscroll';

// scroll to edit window if it is not a preview page if (window.location.search.match('noscroll') == null) { window.scroll(0, GetOffsetTop(inputWrapper)); }

// reset error indicator SetLogo(logo);

return; }

// // Button: toggle or set button checked state //

function SetLogo(logo, error) {

if (error == false) { logo.img.src = image['error']; logo.img.alt = 'WikEd error'; logo.lnk.title = 'WikEd ' + programVersion + ' (' + programDate + '): Loading error'; }	else { logo.img.src = image['logo']; logo.img.alt = 'WikEd'; logo.lnk.title = 'WikEd ' + programVersion + ' (' + programDate + ')'; }	return; }

// // Button: toggle or set button checked state //

function Button(whichButton, toggleButton, setButton, classButton, doButton) {

var buttonObj = document.getElementById(whichButton);

// init the button //////////// onLoad doesn't work!??! if (setButton != null) { if (setButton == false) { buttonObj.checked = false; if (classButton == null) { buttonObj.className = 'wikEdButtonUnchecked'; }		}		else { buttonObj.checked = true; if (classButton == null) { buttonObj.className = 'wikEdButtonChecked'; }		}	}	else if (classButton != null) { buttonObj.className = classButton; }

// toggle the button if (toggleButton != null) { if (toggleButton == true) { if (buttonObj.checked == true) { buttonObj.checked = false; buttonObj.className = 'wikEdButtonUnchecked'; }			else { buttonObj.checked = true; buttonObj.className = 'wikEdButtonChecked'; }		}	}

// perform specific actions if ( ( (setButton == null) && (classButton == null) ) || (doButton == true) ) {

// remove active content removeElements(['script', 'object', 'applet', 'embed']);

var toggle = false; switch (whichButton) { case 'syntax': var obj = {}; obj.html = frameBody.innerHTML; if (buttonObj.checked == true) { highlightSyntax = true; HighlightSyntax(obj); }				else { highlightSyntax = false; RemoveHighlighting(obj); }				frameBody.innerHTML = obj.html; break; case 'source': var obj = {}; if (buttonObj.checked == true) { Edit('sourceon'); }				else { Edit('sourceoff'); }				break; case 'scrolltotop': case 'scrolltotop2': case 'scrolltotop3': var wrapperObj = document.getElementById('inputWrapper'); var wrapperTop = GetOffsetTop(wrapperObj); window.scroll(0, wrapperTop); break; case 'scrolltobuttons': case 'scrolltobuttons2': case 'scrolltobuttons3': var wrapperObj = document.getElementById('buttonsWrapper'); var wrapperTop = GetOffsetTop(wrapperObj); window.scroll(0, wrapperTop); break; case 'preview': case 'preview2': NormalScreen; UpdateTextarea; document.getElementById('PreviewBox').innerHTML = wiki2html(textareaObj.value); document.getElementById('customPreviewBox').style.display = 'block'; break; case 'diff': case 'diff2': NormalScreen; UpdateTextarea; document.getElementById('PreviewBox').innerHTML = StringDiff(editformOrig, textareaObj.value); document.getElementById('customPreviewBox').style.display = 'block'; break; case 'close': case 'close2': document.getElementById('customPreviewBox').style.display = 'none'; break; case 'wikEd': if (buttonObj.checked == false) { UpdateTextarea; document.getElementById('frameWrapper').style.display = 'none'; document.getElementById('textareaWrapper').style.display = 'block'; document.getElementById('wikEdButtonsFormat').style.display = 'none'; //document.getElementById('wikEdButtonsWindow').style.display = 'none'; document.getElementById('wikEdButtonsFind').style.display = 'none'; document.getElementById('wikEdButtonsFix').style.display = 'none'; useWikEd = false; }				else { UpdateFrame; document.getElementById('textareaWrapper').style.display = 'none'; document.getElementById('frameWrapper').style.display = 'block'; document.getElementById('wikEdButtonsFormat').style.display = 'block'; document.getElementById('wikEdButtonsWindow').style.display = 'block'; document.getElementById('wikEdButtonsFind').style.display = 'block'; document.getElementById('wikEdButtonsFix').style.display = 'block'; useWikEd = true; }				break; case 'caseSensitive': toggle = true; break; case 'regExp': toggle = true; break; case 'findAhead': toggle = true; break; case 'fullScreenButton': case 'fullScreenFloat': //				FullScreen; //				fullScreenButton //				fullScreenButtonFloat break; case 'clearhistory': ClearHistory('find'); ClearHistory('replace'); ClearHistory('summary'); break; case 'clearfind': inputElement['find'].value = ''; break; case 'placeholder'://testing break; }	}	return; }

// // editing functions //

function Edit(whichButton) {

// add focus to textbox //	textareaObj.focus;

// remove active content removeElements(['script', 'object', 'applet', 'embed', 'textarea']);

// get the scroll position var scrollTopPx = textareaObj.scrollTop; var scrollHeightPx = textareaObj.scrollHeight;

// convert strange spaces, remove non-\n linebreak characters //	ConvertStrangeSpaces;

// generate several different text ranges to apply the changes to later var obj = {};

// setup whole object for the whole text obj.whole = {}; obj.whole.plainArray = []; obj.whole.plainNode = []; obj.whole.plainStart = []; obj.whole.from = 'whole';

// get whole range obj.whole.range = document.createRange; obj.whole.range.setStartBefore(frameBody.firstChild); obj.whole.range.setEndAfter(frameBody.lastChild);

// get whole plain text GetInnerHTML(obj.whole, frameBody);

RemoveHighlightingWikify(obj.whole); obj.whole.plain = obj.whole.html; obj.whole.plain = obj.whole.plain.replace(/ /g, '\n');

obj.whole.range.setStartBefore(frameBody.firstChild); obj.whole.range.setEndAfter(frameBody.lastChild);

// setup selection object for the selected text obj.selection = {}; obj.selection.from = 'selection';

// set selection range obj.sel = frameWindow.getSelection; obj.selection.range = obj.sel.getRangeAt(obj.sel.rangeCount - 1);

// copy range to document fragment var documentFragment = obj.selection.range.cloneContents;

// get selected text GetInnerHTML(obj.selection, documentFragment);

RemoveHighlightingWikify(obj.selection); obj.selection.plain = obj.selection.html; obj.selection.plain = obj.selection.plain.replace(/ /g, '\n');

// setup cursor object for the cursor position obj.cursor = {}; obj.cursor.from = 'cursor'; obj.cursor.range = document.createRange; obj.cursor.range.setStart(obj.sel.focusNode, obj.sel.focusOffset); obj.cursor.range.setEnd(obj.sel.focusNode, obj.sel.focusOffset); obj.cursor.plain = '';

// setup focusWord object for the word under the cursor obj.focusWord = {}; obj.focusWord.from = 'focusWord'; obj.focusWord.range = document.createRange;

// setup focusLine object for the line under the cursor obj.focusLine = {}; obj.focusLine.from = 'focusLine'; obj.focusLine.range = document.createRange;

// setup selectionWord object for the words under the selection obj.selectionWord = {}; obj.selectionWord.from = 'selectionWord'; obj.selectionWord.range = document.createRange;

// setup selectionLine object for the lines under the selection obj.selectionLine = {}; obj.selectionLine.from = 'selectionLine'; obj.selectionLine.range = document.createRange;

// find the respective word and line boundaries FindBoundaries(obj.focusWord, obj.focusLine, obj.whole, obj.cursor); FindBoundaries(obj.selectionWord, obj.selectionLine, obj.whole, obj.selection);

// get the wikified plain text for the word under the cursor var documentFragment = obj.focusWord.range.cloneContents; GetInnerHTML(obj.focusWord, documentFragment); RemoveHighlightingWikify(obj.focusWord); obj.focusWord.plain = obj.focusWord.html; obj.focusWord.plain = obj.focusWord.plain.replace(/ /g, '\n');

// get the wikified plain text for the line under the cursor var documentFragment = obj.focusLine.range.cloneContents; GetInnerHTML(obj.focusLine, documentFragment); RemoveHighlightingWikify(obj.focusLine); obj.focusLine.plain = obj.focusLine.html; obj.focusLine.plain = obj.focusLine.plain.replace(/ /g, '\n');

// get the wikified plain text for the words under the selection var documentFragment = obj.selectionWord.range.cloneContents; GetInnerHTML(obj.selectionWord, documentFragment); RemoveHighlightingWikify(obj.selectionWord); obj.selectionWord.plain = obj.selectionWord.html; obj.selectionWord.plain = obj.selectionWord.plain.replace(/ /g, '\n');

// get the wikified plain text for the lines under the selection var documentFragment = obj.selectionLine.range.cloneContents; GetInnerHTML(obj.selectionLine, documentFragment); RemoveHighlightingWikify(obj.selectionLine); obj.selectionLine.plain = obj.selectionLine.html; // obj.selectionLine.plain = obj.selectionLine.plain.replace(/\n/g, ''); obj.selectionLine.plain = obj.selectionLine.plain.replace(/ /g, '\n');

// select the appropriate object to change (whole, selection, cursor, focusWord, focusLine, selectionWord, or selectionLine) obj.changed = {}; switch (whichButton) {

// no text: cursor case 'undo': case 'redo': obj.changed = obj.cursor; break;

// basic wiki character formatting: selection / focusWord / cursor case 'bold': case 'italic': case 'underline': case 'sup': case 'sub': case 'wikilink': case 'weblink': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else if (obj.focusWord.plain != '') { obj.changed = obj.focusWord; }			else { obj.changed = obj.cursor; }			break;

// character formatting: selection / focusWord case 'case': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else { obj.changed = obj.focusWord; }			break;

// whole text changes: whole case 'undoall': case 'redoall': obj.changed = obj.whole; break;

// update syntax highlighting: selection / whole case 'update_syntax': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else { obj.changed = obj.whole; }			break;

// multiple line changes: selectionLine case 'headingless': case 'headingmore': case 'bulletlist': case 'numberlist': case 'indentlist': case 'deflist': if (obj.selection.plain != '') { obj.changed = obj.selectionLine; }			else { obj.changed = obj.focusLine; }			break;

// image: selectionWord (if text is selected) / cursor //whole, selection, cursor, focusWord, focusLine, selectionWord, or selectionLine case 'image': if (obj.selection.plain != '') { obj.changed = obj.selectionWord; }			else { obj.changed = obj.cursor; }			break;

// table: selectionLine / cursor case 'table': if (obj.selection.plain != '') { obj.changed = obj.selectionLine; }			else { obj.changed = obj.cursor; }			break;

// wikify, textify: selection / whole case 'wikify': case 'textify': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else { obj.changed = obj.whole; }			break;

// redirect: whole case 'redirect': obj.changed = obj.whole; break;

// character formatting: selection / focusWord case 'getfind': case 'getfindreplace': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else { obj.changed = obj.focusWord; }			break;

// find and replace: find value / selection / focusWord case 'findprev': case 'findnext': case 'replaceprev': case 'replacenext': if (inputElement['find'].value != '') { obj.changed = obj.cursor; obj.changed.plain = inputElement['find'].value; }			else if (obj.selection.plain != '') { obj.changed = obj.selection; }			else if (obj.focusWord.plain != '') { obj.changed = obj.focusWord; }			else { obj.changed = null; }			break;

// replaceall: selection / whole case 'findall': case 'replaceall': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else { obj.changed = obj.whole; }			break;

//////////////////////////////////		case 'updown': obj.changed = obj.cursor; //dummy break; // jump to position: dummy case 'prevpos': case 'lastpos': obj.changed = obj.cursor; //dummy break;

// fixing buttons: selection / whole case 'fixbasic': case 'fixpunct': case 'fixmath': case 'fixchem': case 'fixunits': case 'fixdashes': case 'fixhtml': case 'fixcaps': case 'fixall': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else { obj.changed = obj.whole; }			break;

// fixing buttons: selection, focusLine case 'fixpipes': if (obj.selection.plain != '') { obj.changed = obj.selection; }			else { obj.changed = obj.focusLine; }			break;

// source on / off: selection / whole case 'sourceon': case 'sourceoff': //			if (obj.selection.plain != '') { //				obj.changed = obj.selection; //			} //			else { obj.changed = obj.whole; //			}			break;

// unknown edit function default: alert('Unknown edit function \ + whichButton + '\); }

if (obj.changed != null) {

// convert strange spaces //		obj.changed.plain = obj.changed.plain.replace(/[\t\v\u2028\u2029]+/g, ' '); //		obj.changed.plain = obj.changed.plain.replace(/[\r\f]/g, ''); } // exit if (obj.changed == null) { frameWindow.focus; return; }

// set local syntax highlighting flag var highlightSyntaxEdit = highlightSyntax;

// manipulate the text var selectChange = true; switch (whichButton) {

// undo case 'undo': FrameExecCommand('undo'); obj.changed = null; break;

// redo case 'redo': inputElement['find'].value = FrameExecCommand('redo'); obj.changed = null; break;

// bold case 'bold': if ( /\'\'\'([^\'].*?)\'\'\'/.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/\'\'\'([^\'].*?)\'\'\'/g, '$1'); }			else { obj.changed.plain = '\'\'\ + obj.changed.plain + '\'\'\; obj.changed.plain = obj.changed.plain.replace(/(\'\'\')( *)(.*?)( *)(\'\'\')/, '$2$1$3$5$4'); }			break;

// italic case 'italic': if ( /\'\'([^\'].*?)\'\'/.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/\'\'([^\'].*?)\'\'/g, '$1'); }			else { obj.changed.plain = '\'\ + obj.changed.plain + '\'\; obj.changed.plain = obj.changed.plain.replace(/(\'\')( *)(.*?)( *)(\'\')/, '$2$1$3$5$4'); }			break;

// underline case 'underline': if ( /&lt;u&gt;(.*?)&lt;\/u&gt;/i.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/&lt;u&gt;(.*?)&lt;\/u&gt;/g, '$1'); }			else { obj.changed.plain = '&lt;u&gt;' + obj.changed.plain + '&lt;\/u&gt;'; obj.changed.plain = obj.changed.plain.replace(/(&lt;u&gt;)( *)(.*?)( *)(&lt;\/u&gt;)/, '$2$1$3$5$4'); }			break;

// superscript case 'sup': if ( /&lt;sup&gt;(.*?)&lt;\/sup&gt;/i.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/&lt;sup&gt;(.*?)&lt;\/sup&gt;/g, '$1'); }			else { obj.changed.plain = '&lt;sup&gt;' + obj.changed.plain + '&lt;/sup&gt;'; obj.changed.plain = obj.changed.plain.replace(/(&lt;sup&gt;)( *)(.*?)( *)(&lt;\/sup&gt;)/, '$2$1$3$5$4'); }			break;

// subscript case 'sub': if ( /&lt;sub&gt;(.*?)&lt;\/sub&gt;/i.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/&lt;sub&gt;(.*?)&lt;\/sub&gt;/g, '$1'); }			else { obj.changed.plain = '&lt;sub&gt;' + obj.changed.plain + '&lt;/sub&gt;'; obj.changed.plain = obj.changed.plain.replace(/(&lt;sub&gt;)( *)(.*?)( *)(&lt;\/sub&gt;)/, '$2$1$3$5$4'); }			break;

// toggle lowercase / uppercase case 'case':

// lowercase all uppercased text if (obj.changed.plain.toUpperCase == obj.changed.plain) { obj.changed.plain = obj.changed.plain.toLowerCase; }

// first-letter-uppercase all lowercased text else if (obj.changed.plain.toLowerCase == obj.changed.plain) { obj.changed.plain = obj.changed.plain.replace(/\b(\w)(\w*)/g,					function (p, p1, p2) {						return(p1.toUpperCase + p2.toLowerCase);					}				); }

// uppercase mixed upper and lowercased text else { obj.changed.plain = obj.changed.plain.toUpperCase; }			break;

case 'undoall': obj.changed.plain = editformOrig; break; case 'redoall': if (editformLast != null) { obj.changed.plain = editformLast; }			break;

// update syntax highlighting case 'update_syntax': highlightSyntaxEdit = true; break;

// various editing buttons case 'wikilink': if ( /\[\[(.*?)\]\]/.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/\[\[(.*?)\]\]/g, '$1'); }			else { obj.changed.plain = '\[\[' + obj.changed.plain + '\]\]'; obj.changed.plain = obj.changed.plain.replace(/(\[\[)( *)(.*?)( *)(\]\])/, '$2$1$3$5$4'); }			break; case 'weblink': if ( /\[(.*?)\]/.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/\[(.*?)\]/g, '$1'); }			else { obj.changed.plain = '\[' + obj.changed.plain + '\]'; obj.changed.plain = obj.changed.plain.replace(/(\[)( *)(.*?)( *)(\])/, '$2$1$3$5$4'); }			break; case 'headingless': obj.changed.plain = obj.changed.plain.replace(/(^|\n)=(=+) *([^\n]*?) *=+(?=\n|$)/g, '$1$2 $3 $2'); // decrease heading obj.changed.plain = obj.changed.plain.replace(/(^|\n)=(?!=) *([^\n]*?) *=+(?=\n|$)/g, '$1$2'); // remove heading obj.changed.plain = obj.changed.plain.replace(/(^|\n)(=+) *([^\n]*?) *=+(?=\n|$)/g, '$1$2 $3 $2'); // adjust closing tags break; case 'headingmore': obj.changed.plain = obj.changed.plain.replace(/(^|\n)(=+) *([^\n]*?) *=+(?=\n|$)/g, '$1=$2 $3 $2='); // increase heading obj.changed.plain = obj.changed.plain.replace(/(^|\n)([^=\n\s][^\n]*?)(?=\n|$)/g, '$1== $2 =='); // create new heading obj.changed.plain = obj.changed.plain.replace(/(^|\n)(=+) *([^\n]*?) *=+(?=\n|$)/g, '$1$2 $3 $2'); // adjust closing tags break; case 'bulletlist': obj.changed.plain = obj.changed.plain.replace(/(^|\n) +(?=\n)/g, '$1'); obj.changed.plain = obj.changed.plain.replace(/(^|\n)([\*\#\:\;]*) */g, '$1*$2 '); obj.changed.plain = obj.changed.plain.replace(/(^|\n)(\*{4,})([\*\#\:\;]*) */g, '$1$3 '); break; case 'numberlist': obj.changed.plain = obj.changed.plain.replace(/(^|\n) +(?=\n)/g, '$1'); obj.changed.plain = obj.changed.plain.replace(/(^|\n)([\*\#\:\;]*) */g, '$1#$2 '); obj.changed.plain = obj.changed.plain.replace(/(^|\n)(\#{4,})([\*\#\:\;]*) */g, '$1$3 '); break; case 'indentlist': obj.changed.plain = obj.changed.plain.replace(/(^|\n) +(?=\n)/g, '$1'); obj.changed.plain = obj.changed.plain.replace(/(^|\n)([\*\#\:\;]*) */g, '$1:$2 '); obj.changed.plain = obj.changed.plain.replace(/(^|\n)(\:{4,})([\*\#\:\;]*) */g, '$1$3 '); break; case 'deflist': obj.changed.plain = obj.changed.plain.replace(/(^|\n) +(?=\n)/g, '$1'); obj.changed.plain = obj.changed.plain.replace(/(^|\n) *([^\n\s\;]+) *([^\n]+?)/g, '$1; $2 : $3'); break; case 'image': if (obj.changed.plain != '') { obj.changed.plain = ''; }			else { obj.changed.plain = ''; if (obj.focusWord.plain != '') { obj.changed.plain = ' ' + obj.changed.plain + ' '; }			}			break; case 'table': if (obj.changed.plain != '') { obj.changed.plain = obj.changed.plain.replace(/(^|\n) */g, '\n|-\n| '); obj.changed.plain = obj.changed.plain.replace(/^\n\|\-\n/, '\n{| \n'); obj.changed.plain = obj.changed.plain.replace(/$/g, '\n|}\n'); }			else { obj.changed.plain = '\n{| \n|+ caption \n! heading !! heading \n|-\n| cell || cell \n|-\n| cell || cell \n|}\n'; if (obj.focusLine.plain != '') { obj.changed.plain = '\n' + obj.changed.plain + '\n'; }			}			break;

// wikify: always done above case 'wikify': break;

// textify: strip html from pasted content case 'textify': var objTextify = {};

// get inner html without wikifying if (obj.changed.from == 'whole') { GetInnerHTML(objTextify, frameBody); }			else { obj.selection.range = obj.sel.getRangeAt(obj.sel.rangeCount - 1); var documentFragment = obj.selection.range.cloneContents; GetInnerHTML(objTextify, documentFragment); }

// convert html to plain obj.changed.plain = objTextify.html; obj.changed.plain = obj.changed.plain.replace(/\n/g, '');

// delete tags obj.changed.plain = obj.changed.plain.replace(/<(style)\b[^>]*>.*?<\/\1>/g, '');

// newlines obj.changed.plain = obj.changed.plain.replace(/<(br)\b.*?>/g, '\n');

// blocks obj.changed.plain = obj.changed.plain.replace(/<\/?(address|blockquote|center|div|h1|h2|h3|h4|h5|h6|hr|isindex|p|pre)\b.*?>/g, '\n\n');

// lists obj.changed.plain = obj.changed.plain.replace(/<\/?(dir|dl|menu|ol|ul)\b.*?>/g, '\n'); obj.changed.plain = obj.changed.plain.replace(/<\/(dd|dt|li)>/g, '\n');

// forms obj.changed.plain = obj.changed.plain.replace(/<\/?(select|textarea)\b.*?>/g, '\n'); obj.changed.plain = obj.changed.plain.replace(/<\/(option|legend|optgroup)>/g, '\n');

// table obj.changed.plain = obj.changed.plain.replace(/<\/?(table|caption)\b.*?>/g, '\n'); obj.changed.plain = obj.changed.plain.replace(/<\/(tr|th|td)>/g, '\n');

// finish html to plain conversion obj.changed.plain = obj.changed.plain.replace(/<.*?>/g, ''); obj.changed.plain = obj.changed.plain.replace(/\t|\u00a0| /g, ' '); obj.changed.plain = obj.changed.plain.replace(/\n +/g, '\n'); obj.changed.plain = obj.changed.plain.replace(/\n{3,}/g, '\n\n'); obj.changed.plain = obj.changed.plain.replace(/^\n{2,}|\n{2,}$/g, '\n'); obj.changed.plain = obj.changed.plain.replace(/\n/g, ' '); break;

// redirect case 'redirect': var linkTarget; if (obj.selectionWord.plain != '') { linkTarget = obj.selectionWord.plain; }			else { linkTarget = ' article link '; }

// remove leading and trailing spaces linkTarget = linkTarget.replace(/^\s+|\s+$/g, '');

// remove link text linkTarget = linkTarget.replace(/\|.*?(\]|$)/g, '$1');

// remove square brackets linkTarget = linkTarget.replace(/\[|\]/g, ''); // remove link leftovers linkTarget = linkTarget.replace(/ +\| +/g, ' '); obj.changed.plain = '#redirect ' + linkTarget + '';

if (inputElement['summary'].value == '') { inputElement['summary'].value = '#redirect ' + linkTarget + ''; }			selectChange = false; break;

// copy selection to find field case 'getfind': inputElement['find'].value = obj.changed.plain; obj.changed = null; break;

// copy selection to find and to replace field case 'getfindreplace': inputElement['find'].value = obj.changed.plain; inputElement['replace'].value = obj.changed.plain; obj.changed = null; break;

// find and replace case 'findprev': case 'findnext': case 'replaceprev': case 'replacenext': case 'findall': case 'replaceall':

// get the find text var findText = obj.changed.plain; if (findText == '') { obj.changed = null; break; }

// get the replace text var replaceText = inputElement['replace'].value;

// get the find and replace checkbutton states var caseSensitive = document.getElementById('caseSensitive'); var regExp = document.getElementById('regExp'); var findAhead = document.getElementById('findAhead');

// use the fast built-in find function for non-regexp searches if ( (regExp.checked == false) && ( (whichButton == 'findnext') || (whichButton == 'findprev') ) ) {

// get direction var backwards = false; if (whichButton == 'findprev') { backwards = true; }

// function: window.find(string, caseSensitive, backwards, wrapAround, wholeWord, searchInFrames, showDialog) var found = frameWindow.find(findText, caseSensitive, backwards, false, false, false, false); if (found == false) { obj.changed.range.collapse(backwards); obj.changed.plain = null; }				else { obj.changed = null; }			} // slow javascript regexp find and replace else {

// format the find and replace texts as regexp or plain text if (regExp.checked == false) { findText = findText.replace(/([\\^\$\*\+\?\.\(\)\[\]\{\}\:\=\!\|\,\-])/g, '\\$1'); }

// replace \n with newline character else { replaceText = replaceText.replace(/((^|[^\\])(\\\\)*)\\n/g, '$1\n'); }

// set regexp flags var regExpFlags = 'g'; if ( ! caseSensitive.checked ) { regExpFlags += 'i'; }

// create regexp var regExpFind = new RegExp(findText, regExpFlags);

// replace all var replacedFlag = false; if (whichButton == 'replaceall') { if (regExpFind.test(obj.changed.plain)) { obj.changed.plain = obj.changed.plain.replace(regExpFind, replaceText); replacedFlag = true; }					else { obj.changed.plain = null; }				}

// find all if (whichButton == 'findall') { ////////////////////////// set selection with multiple ranges obj.changed = null; break; }

// replace an existing selection else if ( (whichButton == 'replaceprev') || (whichButton == 'replacenext') ) { if (regExpFind.test(obj.selection.plain)) { obj.changed.plain = obj.selection.plain.replace(regExpFind, replaceText); replacedFlag = true; }					else { obj.changed.plain = null; }				}				else if ( (whichButton == 'findnext') || (whichButton == 'findprev') ) { obj.changed.plain = null; } // perform find if (replacedFlag == false) { ParseDOM(obj, frameBody); var result = []; // find next, search to the right if ( (whichButton == 'findnext') || (whichButton == 'replacenext') ) { // set start position for search to right regExpFind.lastIndex = obj.plainFocus; // execute the regexp search to the right result = regExpFind.exec(obj.plain); // collapse the selection to its end for no find if (result == null) { var range = obj.sel.getRangeAt(obj.sel.rangeCount - 1); obj.changed.range.setEnd(range.endContainer, range.endOffset); obj.changed.range.collapse(false); }					} // find previous, search to the left else if ( (whichButton == 'findprev') || (whichButton == 'replaceprev') ) { // cycle through the matches to the left var resultNext; do { result = resultNext; resultNext = regExpFind.exec(obj.plain); if (resultNext == null) { break; }						} while (resultNext.index < obj.plainAnchor); // collapse the selection to its start for no find if (result == null) { var range = obj.sel.getRangeAt(obj.sel.rangeCount - 1); obj.changed.range.setStart(range.startContainer, range.startOffset); obj.changed.range.collapse(true); }					} // select the find if (result != null) { // make changed range text the next selection i = 0; while ( (obj.plainStart[i + 1] <= result.index) && (obj.plainStart[i + 1] != null) ) { i ++; }						j = i;						while ( (obj.plainStart[j + 1] <= result.index + result[0].length) && (obj.plainStart[j + 1] != null) ) { j ++; }						obj.changed.range.setStart(obj.plainNode[i], result.index - obj.plainStart[i]); obj.changed.range.setEnd (obj.plainNode[j], result.index + result[0].length - obj.plainStart[j]); }				}			} // save search history to cookie if ( (whichButton == 'findprev') || (whichButton == 'findnext') ) { AddToHistory('find'); }			if ( (whichButton == 'replaceprev') || (whichButton == 'replacenext') || (whichButton == 'replaceall') ) { AddToHistory('find'); AddToHistory('replace'); }			break;

// jump to top or bottom case 'updown':

// jump to bottom /////////////////////// also check which is closer!!!!! if ( (obj.cursor.range.startContainer == frameBody) && (obj.cursor.range.startOffset == 0) ) { obj.changed.range.setEndAfter(frameBody.lastChild); obj.changed.range.collapse(false); frameBody.scrollTop = frameBody.scrollHeight; }

// jump to top else { obj.changed.range.setStartBefore(frameBody.firstChild); obj.changed.range.collapse(true); frameBody.scrollTop = 0; }			obj.changed.plain = null; break;

// jump to previously changed position case 'prevpos': if ( frameDocument.queryCommandEnabled('undo') ) { FrameExecCommand('undo'); FrameExecCommand('redo'); lastPosObj = obj.cursor; }			obj.changed = null break;

// jump back to last position case 'lastpos': if (lastPosObj != null) { obj.changed = lastPosObj; lastPosObj = null; obj.changed.plain = null; }			else { obj.changed = null; }			break;

// fixbasic: fix characters, spaces, empty lines, certain headings, needed for all fixing functions // to do: only certain changes in multiline tags: comments, tables, subst case 'fixbasic': FixBasic(obj.changed); break;

// fixpipes: add spaces around pipes in wikilinks and templates (good for link lists) case 'fixpipes': FixPipes(obj.changed); break; case 'fixpunct': FixPunct(obj.changed); break; case 'fixmath': FixMath(obj.changed); break; case 'fixchem': FixChem(obj.changed); break; case 'fixunits': FixUnits(obj.changed); break; case 'fixdashes': FixDashes(obj.changed); break; case 'fixhtml': FixHTML(obj.changed); break; case 'fixcaps': FixCaps(obj.changed); break; case 'fixall': FixAll(obj.changed); break;

// source on		case 'sourceon': obj.changed.plain = obj.changed.plain.replace(/&lt;br&gt;/g, ''); obj.changed.plain = obj.changed.plain.replace(/&/g, '&amp;'); obj.changed.plain = obj.changed.plain.replace(/\n/g, '&lt;br&gt;\n'); highlightSyntaxEdit = false; break;

// source off case 'sourceoff': obj.changed.plain = obj.changed.plain.replace(/&lt;br&gt;\n/gi, '\n'); obj.changed.plain = obj.changed.plain.replace(/&amp;/g, '&'); break;

default: alert('Unknown edit function \ + whichButton + '\); }

// exit if (obj.changed == null) { frameWindow.focus; return; }

// update the selection only if (obj.changed.plain == null) { obj.sel.removeAllRanges; obj.sel.addRange(obj.changed.range); }

// apply text changes else {

// save last version for redo all switch (whichButton) { case 'undo': case 'redo': case 'undoall': case 'redoall': if (editformLast == null) { editformLast = obj.changed.plain; }				break; default: editformLast = null; ///////////////// also after every key click

// highlight syntax obj.changed.plain = obj.changed.plain.replace(/\n/g, ' '); obj.html = obj.changed.plain; if (highlightSyntaxEdit == true) { HighlightSyntax(obj, true); }

// make changed range text the current selection obj.sel.removeAllRanges; obj.sel.addRange(obj.changed.range);

// replace the selection with changed text if (obj.html != '') { FrameExecCommand('inserthtml', obj.html); }			else { FrameExecCommand('delete'); }

// get the text content of the changed text var div = document.createElement('div'); div.innerHTML = obj.changed.plain; var plainText = div.textContent;

// select the changed text by using a backwards find if (selectChange != false) { if (plainText.length > 0) {

// function: window.find(string, caseSensitive, backwards, wrapAround, wholeWord, searchInFrames, showDialog) frameWindow.find(plainText, true, true, false, false, false, false); }			}		}	}

// focus the frame frameWindow.focus;

return; }

// // FixBasic: fix characters, spaces, empty lines, certain headings, needed for all fixing functions //

function FixBasic(obj) {

// non-breaking space character to normal space obj.plain = obj.plain.replace(/(\u00a0)/g, ' ');

// remove trailing spaces obj.plain = obj.plain.replace(/( | )+\n/g, '\n');

// empty line before and after headings, spaces around word (lookahead) obj.plain = obj.plain.replace(/\n+(={2,}) *([^\n]*?) *(={2,})(?=\n)\n*/g, '\n\n$1 $2 $3\n\n');

// uppercase well known headings obj.plain = obj.plain.replace(/\n== external links? ==\n/ig, '\n== External links ==\n'); obj.plain = obj.plain.replace(/\n== see also ==\n/ig, '\n== See also ==\n'); obj.plain = obj.plain.replace(/\n== references? ==\n/ig, '\n== References ==\n');

// add space after * # : ; (list) and after {| |- | (table) obj.plain = obj.plain.replace(/(^|\n)([\*\#\:\;]+|\{\||\|\-|\|\}|\|) */g, '$1$2 '); obj.plain = obj.plain.replace(/ +\n/g, '\n');

// empty line before and after tables obj.plain = obj.plain.replace(/\n+(\{\|)/g, '\n\n$1'); obj.plain = obj.plain.replace(/(\n\|\}) *([^\n]*)[\n|$]+/g, '$1\n\n$2\n\n');

// empty line before and after lists obj.plain = obj.plain.replace(/(^|\n)([^\*\#\:\;].*?)\n+([\*\#\:\;])/g, '$1$2\n\n$3'); obj.plain = obj.plain.replace(/(^|\n)([\*\#\:\;].*?)\n+([^\*\#\:\;])/g, '$1$2\n\n$3');

// split into lines and change single lines, used to handle tables var lines = obj.plain.split('\n'); obj.plain = ''; 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(/^(\)/ig, '\n$1'); line = line.replace(/(\)$/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 obj.plain += line; if (i < lines.length - 1) { obj.plain += '\n'; }	}

// remove spaces in wikilinks obj.plain = obj.plain.replace(/\[\[ *([^\n]*?) *\]\]/g, '$1');

// remove spaces in external links obj.plain = obj.plain.replace(/\[ *([^\n]*?) *\]/g, '[$1]');

// no space around pipes before brackets obj.plain = obj.plain.replace(/ +\| +\]\]/g, '|]]');

// no space around pipes before curly brackets obj.plain = obj.plain.replace(/ +\| +\}\}/g, '|}}');

// no empty line between headings and includes obj.plain = obj.plain.replace(/\n(==+ [^\n]*? ==+\n)\n+(\{\{.*?\}\})/g, '\n$1$2');

// spaces in comments obj.plain = obj.plain.replace(//g, '$1 $2 $3');

// empty lines around html comments obj.plain = obj.plain.replace(/\n+\n+/g, '\n$1\n\n'); obj.plain = obj.plain.replace(/^\n+/g, '$1\n'); obj.plain = obj.plain.replace(/\n+$/g, '\n$1');

// empty line before and after categories obj.plain = obj.plain.replace(/( |\n)*(\[\[category:[^\n]*?\]\])( |\n)*/gi, '\n\n$2\n\n');

// categories not separated by empty lines (lookahead) obj.plain = obj.plain.replace(/(\[\[category:[^\n]*?\]\])\n*(?=\[\[category:[^\n]*?\]\])/gi, '$1\n');

// single empty lines only obj.plain = obj.plain.replace(/\n{3,}/g, '\n\n');

// remove leading and trailing newlines obj.plain = obj.plain.replace(/^\n+/, ''); obj.plain = obj.plain.replace(/\n{2,}$/, '\n');

return; }

// // FixPipes: add spaces around pipes in wikilinks and templates (good for link lists) //

function FixPipes(obj) { FixBasic(obj); obj.plain = obj.plain.replace(/(\)/ig, '$1 | $2'); obj.plain = obj.plain.replace(/(\{\{)([^\n]+?)(\}\})/g,		function (p, p1, p2, p3) {			p2 = p2.replace(/ *(\|) */g, ' | ');			return(p1 + p2 + p3);		}	); return; }

// // FixPunct: remove space before .,: //

function FixPunct(obj) { FixBasic(obj);

// ; could be a definition obj.plain = obj.plain.replace(/([a-zA-Z\'\"\”\]\}\)]) +([\.\,\:])/g, '$1$2');

return; }

// // FixMath: math character fixer, originally from User:Omegatron //

function FixMath(obj) {

FixBasic(obj);

// change only outside $$ $$ wikicode obj.plain = obj.plain.replace(/(.*?)<math(\b[^>]*)?>.*?<\/math>/gi,		function (p, p1) {

// convert html entities into actual dash characters p1 = p1.replace(/&minus;/g, '\u2212'); p1 = p1.replace(/&middot;/g, '·');

// convert dash next to a number into a minus sign character p1 = p1.replace(/([^a-zA-Z0-9\,\_\{])-(\d)/g, '$1\u2212$2');

// changes 2x3 to 2×3 p1 = p1.replace(/(\d ?)x( ?\d)/g, '$1×$2');

// changes 10^3 to 103 p1 = p1.replace(/(\d*\.?\d+)\^(\u2212?\d+\.?\d*)/g, '$1$2');

// change x^3 to x3			p1 = p1.replace(/([0-9a-zA-Z])\^(\u2212?\d+\.?\d*) /g, '$1$2');

// change +/- to ± p1 = p1.replace(/( |\d)\+\/(-|\u2212)( |\d)/g, '$1±$3'); return(p1); }	);	return; }

// // FixChem: fix chemical formulas //

function FixChem(obj) {

FixBasic(obj); /*

var realElements = 'H|He|Li|Be|B|C|N|O|F|Ne|Na|Mg|Al|Si|P|S|Cl|Ar|K|Ca|Sc|Ti|V|Cr|Mn|Fe|Co|Ni|Cu|Zn|Ga|Ge|As|Se|Br|Kr|Rb|Sr|Y|Zr|Nb|Mo|Tc|Ru|Rh|Pd|Ag|Cd|In|Sn|Sb|Te|I|Xe|Cs|Ba|Hf|Ta|W|Re|Os|Ir|Pt|Au|Hg|Tl|Pb|Bi|Po|At|Rn|Fr|Ra|Rf|Db|Sg|Bh|Hs|Mt|Ds|Rg|La|Ce|Pr|Nd|Pm|Sm|Eu|Gd|Tb|Dy|Ho|Er|Tm|Yb|Lu|Ac|Th|Pa|U|Np|Pu|Am|Cm|Bk|Cf|Es|Fm|Md|No|Lr'; var pseudoElements = '|D|T|Me|Et|Pr|Bu'; // fix formulas obj.plain = obj.plain.replace('/(\d*)(\s*)(((' + elements + pseudoElements')(&lt;sub&gt;)?(\d*)(&lt;\/sub&gt;)?)+)|[\(\)\[\]\-\=])\b/g', function (p, p1, p2, p3, p4, p5, p6) { var whole = p1 + p2 + p3; var prefixNumber = p1 + 0; var formula = p3; //			     if (not one real element) { return(whole); }

// clean prefix prefix = prefix.replace(/0*(\d+)/g, '$1');

// subscript and clean indices formula = formula.replace(/(&lt;sub&gt;)?0*(\d+)(&lt;\/sub&gt;)?/g, '&lt;sub&gt;$2&lt;\/sub&gt;');

return(prefix + ' ' + formula); }	);	return; }

// // FixUnits: unit formatter - new tab adds spaces between number and units, makes units consistent // originally from User:Omegatron //

function FixUnits(obj) { FixBasic(obj);

// convert all &deg; into actual ° symbol obj.plain = obj.plain.replace(/&deg;/g, '°');

// convert the word ohm(s) or the html entity into the actual Omega symbol (not the actual ohm symbol &#8486;) and make sure it's spaced obj.plain = obj.plain.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|&mu;|µ|&micro;|n|p|f|a|z|y)? ?(&Omega;|&#8486;|(ohm|Ohm)s?)([\s.,:;\'\"\/\)])/g, '$1 $2\u03a9$5');

// convert various micro symbols into the actual micro symbol, make sure it's spaced obj.plain = obj.plain.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)([\s.,:;\'\"\/\)])/g, '$1 µ$3$4');

// convert capital K to lowercase k in units obj.plain = obj.plain.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)([\s.,:;\'\"\/\)])/g, '$1 k$2$3');

// capitalize units correctly obj.plain = obj.plain.replace(/(\d) ?(khz)([ ,.])/gi, '$1 kHz$3'); obj.plain = obj.plain.replace(/(\d) ?(mhz)([ ,.])/gi, '$1 MHz$3'); obj.plain = obj.plain.replace(/(\d) ?(ghz)([ ,.])/gi, '$1 GHz$3'); obj.plain = obj.plain.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|&mu;|µ|&micro;|n|p|f|a|z|y)?(hz|HZ)([\s.,:;\'\"\/\)])/g, '$1 $2Hz$4');	obj.plain = obj.plain.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|&mu;|µ|&micro;|n|p|f|a|z|y)?(pa|PA)([\s.,:;\'\"\/\)])/g, '$1 $2Pa$4');

// add a space before dB	obj.plain = obj.plain.replace(/(\d) ?(dB)([\s.,:;\'\"\/\)])/g, '$1 $2$3');

// add a space before any units that were missed before obj.plain = obj.plain.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|&mu;|µ|&micro;|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)([\s.,:;\'\"\/\)])/g, '$1 $2$3$4');

// separate one for seconds since they give a lot of false positives like "1970s". Only difference is mandatory prefix. obj.plain = obj.plain.replace(/(\d) ?(Y|Z|E|P|T|G|M|k|K|h|da|d|c|m|&mu;|µ|&micro;|n|p|f|a|z|y)(s)([\s.,:;\'\"\/\)])/g, '$1 $2$3$4');

// bps or b/s or bits/s --> bit/s obj.plain = obj.plain.replace(/([KkMmGgTtPpEeYyZz])(bps|bits?\/s|b\/s)/g, '$1bit/s');

// Bps or byte/s or bytes/s --> B/s obj.plain = obj.plain.replace(/([KkMmGgTtPpEeYyZz])(Bps|bytes?\/s)/g, '$1B/s');

// after that, make capitalization correct obj.plain = obj.plain.replace(/K(bit|B)\/s/g, 'k$1/s'); obj.plain = obj.plain.replace(/m(bit|B)\/s/g, 'M$1/s'); obj.plain = obj.plain.replace(/g(bit|B)\/s/g, 'G$1/s'); obj.plain = obj.plain.replace(/t(bit|B)\/s/g, 'T$1/s'); obj.plain = obj.plain.replace(/e(bit|B)\/s/g, 'E$1/s'); obj.plain = obj.plain.replace(/y(bit|B)\/s/g, 'Y$1/s'); obj.plain = obj.plain.replace(/z(bit|B)\/s/g, 'Z$1/s');

// fix a common error obj.plain = obj.plain.replace(/mibi(bit|byte)/g, 'mebi$1');

return; }

// // FixDashes: dash fixer - adds a tab that fixes several obvious en/em dash, minus sign, and such special characters. // originally from User:Omegatron //

function FixDashes(obj) { FixBasic(obj);

// convert html entities into actual dash characters obj.plain = obj.plain.replace(/&mdash;/g, '—'); obj.plain = obj.plain.replace(/–/g, '–'); obj.plain = obj.plain.replace(/&minus;/g, '\u2212');

// convert -- and em dashes with or without spaces to em dash surrounded by spaces obj.plain = obj.plain.replace(/([a-zA-Z\'\"”\]\}\)]) *(--|—|&mdash;) *([a-zA-Z\'\"“\[\{\(])/g, '$1 — $3');

// convert - or en dashes with spaces to em dash character surrounded by spaces obj.plain = obj.plain.replace(/([a-zA-Z\'\"”\]\}])( | )+(\u2212|–|–) +([a-zA-Z\'\"“\[\{])/g, '$1$2— $4');

// convert hyphen next to lone number into a minus sign character obj.plain = obj.plain.replace(/([a-zA-Z\'\"”\]\>] )-(\d)/g, '$1\u2212$2');

// convert dashes to en dashes in dates obj.plain = obj.plain.replace(/([ \(][12]\d\d\d) ?(--?|—|&mdash;) ?([12]\d\d\d|\d\d)([ \),.;])/g, '$1–$3$4');

return; }

// // FixHTML: fix html to wikicode ///////////////// obsolete, use function below //

function FixHTML(obj) { FixBasic(obj);

// remove syntax highlighting obj.html = obj.plain; RemoveHighlighting(obj);

// turn visible html code into real html obj.html = obj.html.replace(/&lt;/g, '<'); obj.html = obj.html.replace(/&gt;/g, '>');

// wikify WikifyHTML(obj);

// turn real html into visible html code obj.html = obj.html.replace(/ /g, '\n'); obj.html = obj.html.replace(/</g, '&lt;'); obj.html = obj.html.replace(/>/g, '&gt;'); obj.plain = obj.html;

return; }

// // FixCaps: fix capitalizing of lists, linklists, images, headings //

function FixCaps(obj) { FixBasic(obj);

// uppercase lists // start (listcode (char-ent|tag|category..|digit|non-word,non-ret))(word,non-digit..) end obj.plain = obj.plain.replace(/^([\*\#\:\;]+ (\&\w+\;|\<[^\n]*?\>|\{\{.*?\}\}[^\n]*|\d|[^\w\n])*)([^\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) obj.plain = obj.plain.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 obj.plain = obj.plain.replace(/^(==+ (\&\w+\;|<.*?>|\d|[^\w\n])*)([^\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 obj.plain = obj.plain.replace(/(\)/igm,		function (p, p1, p2, p3) {			return(p1 + 'Image:' + p2.toUpperCase + p3);		}	);

return; }

// // FixAll: //

function FixAll(obj) { FixBasic(obj); FixUnits(obj); FixDashes(obj); FixHTML(obj); FixCaps(obj); return; }

// // removeElements: remove elements by tag name //

function removeElements(tagNameArray) {

// cycle through the element names for each (var tagNameStr in tagNameArray) { var elementArray = frameDocument.getElementsByTagName(tagNameStr); for (i = 0; i < elementArray.length; i ++) { elementArray[i].parentNode.removeChild(elementArray[i]); }	}	return; }

// // FindBoundaries: find word boundaries and line boundaries starting from selection.range //

function FindBoundaries(word, line, whole, selection) {

/* textareaObj.value = '';

// get the start node and offset var startNode = selection.range.startContainer; var startNodeOffset = selection.range.startOffset;

// get the end node and offset var endNode = selection.range.endContainer; var endNodeOffset = selection.range.endOffset;

if (startNode.nodeType == 1) { startNode = startNode.childNodes[startNodeOffset]; startNodeOffset = 0; }	if (endNode.nodeType == 1) { endNode = endNode.childNodes[endNodeOffset]; endNodeOffset = 0; }

// find the start and end nodes in the whole plain text arrays var startNodeIndex; var endNodeIndex; for (i = 0; i < whole.plainArray.length; i ++) { if (startNode == whole.plainNode[i]) { startNodeIndex = i;		} if (endNode == whole.plainNode[i]) { endNodeIndex = i;			break; }	}

// find last previous word and line boundary var foundWord = false; var foundLine = false; var regExp = new RegExp('.*[^\\w\\-]', 'g');

// check text nodes left-wise for a boundary for (i = startNodeIndex; i >= 0; i --) { var plain = whole.plainArray[i];

// boundary is a newline if (plain == '\n') {

// current newline is the start node if (i == startNodeIndex) { if (! foundWord) { word.range.setStartBefore(whole.plainNode[i]); foundWord = true; }				line.range.setStartBefore(whole.plainNode[i]); }			else { if (! foundWord) { word.range.setStartAfter(whole.plainNode[i]); foundWord = true; }				line.range.setStartAfter(whole.plainNode[i]); }			foundLine = true; break; }

// check text node for a word boundary else if (! foundWord) { if (i == startNodeIndex) { plain = plain.substr(0, startNodeOffset); }			regExp.lastIndex = 0; if (regExp.exec(plain) != null) { word.range.setStart(whole.plainNode[i], regExp.lastIndex); foundWord = true; }		}	}

// boundary is start of text if (! foundLine) { line.range.setStartBefore(whole.plainNode[0]); if (! foundWord) { word.range.setStartBefore(whole.plainNode[0]); }	}

// find next word and line boundary regExp = new RegExp('[^\\w\\-]', 'g'); foundWord = false; foundLine = false;

// check text nodes right-wise for a boundary for (i = endNodeIndex; i < whole.plainArray.length; i ++) { var plain = whole.plainArray[i];

// boundary is a newline if (plain == '\n') { if (! foundWord) { word.range.setEndBefore(whole.plainNode[i]); foundWord = true; }			line.range.setEndBefore(whole.plainNode[i]); foundLine = true; break; }

// check text node for a word boundary else if (! foundWord) { if (i == endNodeIndex) { regExp.lastIndex = endNodeOffset; }			else { regExp.lastIndex = 0; }			var regExpArray = regExp.exec(plain); if (regExpArray != null) { /* textareaObj.value = ''; textareaObj.value += 'i: ' + i + '\n'; textareaObj.value += 'whole.plainNode[i]: ' + whole.plainNode[i] + '\n'; textareaObj.value += 'whole.plainNode[i].type: ' + whole.plainNode[i].type + '\n'; textareaObj.value += 'whole.plainNode[i].name: ' + whole.plainNode[i].name + '\n'; textareaObj.value += 'whole.plainNode[i].value: ' + whole.plainNode[i].value + '\n'; textareaObj.value += 'regExpArray.index: ' + regExpArray.index + '\n'; word.range.setEnd(whole.plainNode[i], regExpArray.index);///////////////////////// error on sourceoff ///////////////////////////////////////

// Error: uncaught exception:

foundWord = true; }		}	}

// boundary is end of text if (! foundLine) { line.range.setEndAfter(whole.plainNode[whole.plainArray.length - 1]); if (! foundWord) { word.range.setEndAfter(whole.plainNode[whole.plainArray.length - 1]); }	}	return; }

// // remove syntax highlighting and wikify //

function RemoveHighlightingWikify(obj) {

if (obj.html != '') {

// remove syntax highlighting RemoveHighlighting(obj);

// wikify if (obj.htmlCode == true) { WikifyHTML(obj); }	}	return; }

// // scroll the textarea if the selected text is outside the viewport //

function ScrollTextarea(rowStart, rowEnd, lines, margin, scrollTopPx) {

// get top row var scrollHeightPx = textareaObj.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 textareaObj.scrollTop = scrollTopRow / textRows.rowTotal * scrollHeightPx;

return; }

// // ParseRows: get row structure of textarea //

function ParseRows {

textRows.selStart = textareaObj.selectionStart; textRows.selEnd = textareaObj.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 != textareaObj.value.length) { textRows.changed = true; }		else if (textRows.textarea != textareaObj.value) { textRows.changed = true; }	}	if (textRows.changed) { textRows.changed = false textRows.textarea = textareaObj.value; textRows.cols = textareaObj.cols; textRows.rows = textareaObj.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; }

// // convert strange spaces, remove non-\n linebreak characters //

function ConvertStrangeSpaces {

//	var text = textareaObj.value; //	text = text.replace(/[\t\v\u00a0\u2028\u2029]+/g, ' '); // \u00a0 = //	text = text.replace(/[\t\v\u2028\u2029]+/g, ' '); //	text = text.replace(/[\r\f]/g, ''); //	textareaObj.value = text;

return; }

// // wikifyHTML, obj.html contains the text to be wikified //

/*	allowed and converted tags: br|p h1|h2|h3|h4|h5|h6 hr i|dfn|cite|em|var b|strong table|caption|col|thead|tfoot|tbody|tr|td|th dl|dt|dd|li|ol|ul a not allowed yet, converted to span: bdo|q|kbd|samp|abbr|acronym|label other allowed tags: big|blockquote|colgroup|center|code|del|div|font|ins|pre|s|small|span|strike|sub|sup|tt|u|rb|rp|rt|ruby mediawiki tags: nowiki|math|gallery|noinclude|includeonly|ref|references

function WikifyHTML(obj) {

// delete tags obj.html = obj.html.replace(/<(style)\b[^>]*>.*?<\/\1>/g, '');

// standardize newline, remove multiple spaces obj.html = obj.html.replace(/<br(\b[^>]*)?>/gi, '\n'); obj.html = obj.html.replace(/\n?\r/g, '\n'); obj.html = obj.html.replace(/ +/g, ' ');

// escape character entities obj.html = obj.html.replace(/&(?!(amp;|lt;|gt;))/g, '&amp;');

// remove comments obj.html = obj.html.replace(//g, '');

// horizontal rule obj.html = obj.html.replace(/\s*<hr(\b[^>]*)>\s*/gi, '\n\n');

// <i> italic obj.html = obj.html.replace(/<(i|em|dfn|var|cite)\b.*?>/gi, '\'\''); obj.html = obj.html.replace(/<\/(i|em|dfn|var|cite)\b.*?>/gi, '\'\'');

// <b> bold obj.html = obj.html.replace(/<(b|strong)\b.*?>/gi, '\'\'\''); obj.html = obj.html.replace(/<\/(b|strong)\b.*?>/gi, '\'\'\'');

// .. headings obj.html = obj.html.replace(/\s*<h1\b[^>]*>(.*?)<\/h1\b[^>]*>\s*/gi, '\n\n= $1 =\n\n'); obj.html = obj.html.replace(/\s*<h2\b[^>]*>(.*?)<\/h2\b[^>]*>\s*/gi, '\n\n== $1 ==\n\n'); obj.html = obj.html.replace(/\s*<h3\b[^>]*>(.*?)<\/h3\b[^>]*>\s*/gi, '\n\n=== $1 ===\n\n'); obj.html = obj.html.replace(/\s*<h4\b[^>]*>(.*?)<\/h4\b[^>]*>\s*/gi, '\n\n==== $1 ====\n\n'); obj.html = obj.html.replace(/\s*<h5\b[^>]*>(.*?)<\/h5\b[^>]*>\s*/gi, '\n\n===== $1 =====\n\n'); obj.html = obj.html.replace(/\s*<h6\b[^>]*>(.*?)<\/h6\b[^>]*>\s*/gi, '\n\n====== $1 ======\n\n');

// 	obj.html = obj.html.replace(/<(span|div)\s+([^>]*)>/gi,		function (p, p1, p2) {			return('<' + p1 + SanitizeAttributes(p1, p2) +  '>');		}	);

// table cell, remove first paragraph obj.html = obj.html.replace(/(<td\b[^>]*>)\s*<p\b.*?>/gi, '$1');

//  	obj.html = obj.html.replace(/<\/?(thead|tbody|tfoot)\b.*?>/gi, '');

// table cells obj.html = obj.html.replace(/\s*<td\s*>\s*/gi, '\n| '); obj.html = obj.html.replace(/\s*<(td)\s+([^>]*)>\s*/gi,		function (p, p1, p2) {			return('\n|' + SanitizeAttributes(p1, p2) + ' | ');		}	);

// table cells obj.html = obj.html.replace(/\s*<th\s*>\s*/gi, '\n| '); obj.html = obj.html.replace(/\s*<(th)\s+([^>]*)>\s*/gi,		function (p, p1, p2) {			return('\n!' + SanitizeAttributes(p1, p2) + ' | ');		}	);

// table rows obj.html = obj.html.replace(/\s*<tr\s*>\s*/gi, '\n|-\n'); obj.html = obj.html.replace(/\s*<(tr)\s+([^>]*)>\s*/gi,		function (p, p1, p2) {			return('\n|-' + SanitizeAttributes(p1, p2) + '\n');		}	);

// captionCaption obj.html = obj.html.replace(/\s*<caption\s*>\s*/gi, '\n|+ '); obj.html = obj.html.replace(/\s*<(caption)\s+([^>]*)>\s*/gi,		function (p, p1, p2) {			return('\n|+' + SanitizeAttributes(p1, p2) + ' | ');		}	);

// tables obj.html = obj.html.replace(/\s*<table\s*>\s*(\|-\n)?/gi, '\n\n{|\n'); obj.html = obj.html.replace(/\s*<(table)\s+([^>]*)>\s*(\|-\n)?/gi,		function (p, p1, p2) {			return('\n{|' + SanitizeAttributes(p1, p2) + '\n');		}	); obj.html = obj.html.replace(/\s*<\/table>\s*/gi, '\n|}\n\n');

// convert images obj.html = obj.html.replace(/<img\b([^>]*)>/gi,		function (p, p1) {

// get and format parameters var address = ''; var regExpMatch = /\bsrc\s*=\s*(\'|\")([^\'\"]*)(\'|\")/i.exec(p1);			if (regExpMatch != null) {				address = regExpMatch[2].replace(/^ +| +$/g, '');			}

var alt = ''; regExpMatch = /\balt\s*=\s*(\'|\")([^\'\"]*)(\'|\")/i.exec(p1);			if (regExpMatch != null) {				alt = regExpMatch[2].replace(/^ +| +$/g, );				alt = alt.replace(/&amp;nbsp;|\n/g, ' ');				alt = alt.replace(/ {2,}/g, ' ');				alt = alt.replace(/^ | $/g, );				if (alt != '') {					alt = '|' + alt;				}			}

var imgWidth = ''; regExpMatch = /\bwidth\s*=\s*(\'|\")([^\'\"]*)(\'|\")/i.exec(p1);			if (regExpMatch != null) {				imgWidth = '|' + regExpMatch[2].replace(/^ +| +$/g, '') + 'px';			}

var longDesc = '';; regExpMatch = /\blongdesc\s*=\s*(\'|\")([^\'\"]*)(\'|\")/i.exec(p1);			if (regExpMatch != null) {				longDesc = regExpMatch[2].replace(/^ +| +$/g, '');			}

// wiki image var image = ''; regExpMatch = /^\/wiki\/Image:(.*)$/.exec(longDesc); if (regExpMatch != null) { image = regExpMatch[1]; }

// external image else { regExpMatch = /([^\/]+)$/.exec(address); if (regExpMatch != null) { image = regExpMatch[1]; }			}

if (image != '') { return(''); }			return(''); }	);

// convert links obj.html = obj.html.replace(/<a\b([^>]*)>(.*?)<\/a>/gi,		function (p, p1, p2) {

// get and format parameters var address = ''; var regExpMatch = /\bhref\s*=\s*(\'|\")([^\'\"]*)(\'|\")/i.exec(p1);			if (regExpMatch != null) {				address = regExpMatch[2].replace(/^ +| +$/g, );			}			if (address == ) {				return('');			}

var linkText = p2; linkText = linkText.replace(/&amp;nbsp;|\n/g, ' '); linkText = linkText.replace(/ {2,}/g, ' '); linkText = linkText.replace(/^ | $/g, ''); if ( /\/i.exec(linkText) ) { return(linkText); }

// wikilink var regExpString = '^'; var urlProtocol = window.location.protocol; urlProtocol = urlProtocol.replace(/\./g, '\\.'); regExpString += '(' + urlProtocol + '//|)(';			var urlHostname = window.location.hostname;			if (urlHostname != '') {				urlHostname = urlHostname.replace(/\./g, '\\.');				regExpString += urlHostname + '/';			}			regExpString += '|)[\\w\\./]*/wiki/(.*)$'; /*

Debug; Debug('regExpString', regExpString); Debug('linkText', linkText); var regExp = new RegExp(regExpString); var regExpMatch = regExp.exec(address); if (regExpMatch != null) { var article = regExpMatch[3].replace(/_/g, ' '); article = decodeURIComponent(article); article = article.replace(/&/g, '&amp;'); if (linkText == '') { return( + article + ); }				if ( ( (article.substr(0, 1).toLowerCase + article.substr(1)) == linkText )					|| ( (article.substr(0, 1).toUpperCase + article.substr(1)) == linkText ) ) { return( + linkText + ); }				if ( ( (article.substr(0, 1).toLowerCase + article.substr(1)) == linkText.substr(0, linkText.length - 1) )					|| ( (article.substr(0, 1).toUpperCase + article.substr(1)) == linkText.substr(0, linkText.length - 1) ) ) { return(  + linkText.substr(0, linkText.length - 1) +  + linkText.substr(linkText.length - 1) ); }				return( + linkText + ); }

// normal link if ( (linkText == '') || ( (address.substr(0, 1).toLowerCase + address.substr(1)) == linkText ) || ( (address.substr(0, 1).toUpperCase + address.substr(1)) == linkText ) ) { return('[' + address + ']'); }			return('[' + address + ' ' + linkText + ']'); }	);

// convert lists //definition lists to be done///////////////////// var listObj = {}; listObj.prefix = ''; obj.html = obj.html.replace(/\s*<(\/?(ol|ul|li))\b[^>]*>\s*/gi,		function (p, p1, p2, p3, p4) {			switch (p1.toLowerCase) {				case 'ol':					listObj.prefix += '#';					return('\n\n');				case 'ul':					listObj.prefix += '*';					return('\n\n');				case '/ol':				case '/ul':					listObj.prefix = listObj.prefix.substr(0, listObj.prefix.length - 1);					return('\n\n');				case 'li':					return('\n' + listObj.prefix + ' ');				case '/li':					return('');			}		}	);

// paragraph obj.html = obj.html.replace(/(.)<p\b.*?>/gi, '$1\n\n'); obj.html = obj.html.replace(/<\/p\b.*?>/gi, '');

// <> remove not allowed tags obj.html = obj.html.replace(/(<\/?)(\/?)(\w+)(.*?>)/g,		function (p, p1, p2, p3, p4) {			if ( /^(big|blockquote|colgroup|center|code|del|div|font|ins|pre|s|small|span|strike|sub|sup|tt|u|rb|rp|rt|ruby|nowiki|math|gallery|noinclude|includeonly|ref|references)$/i.test(p3) ) {				return(p1 + p2 + p3 + p4);			}			else {				return('');			}		}	);

// opening html tags obj.html = obj.html.replace(/<(\w+)(.*?)>/gi,		function (p, p1, p2) {			return('&lt;' + p1 + SanitizeAttributes(p1, p2) + '&gt;');		}	);

// closing html tags obj.html = obj.html.replace(/</g, '&lt;'); obj.html = obj.html.replace(/>/g, '&gt;');

// newlines to 	obj.html = obj.html.replace(/\n{3,}/g, '\n\n'); obj.html = obj.html.replace(/\n/g, ' ');

return; }

// // SanitizeAttributes: see Sanitizer.php //

function SanitizeAttributes(tag, attributes) {

var common = 'lang|dir|style|class'; // not needed: id|title var tablealign = '|align|char|charoff|valign'; var tablecell = '|abbr|axis|headers|scope|rowspan|colspan|nowrap|width|height|bgcolor'; tag = tag.toLowerCase; var sanitized = ''; var regExp = /(\w+)\s*=\s*(\'|\")([^\'\"]*)(\'|\")/g;	var regExpMatch;	while (regExpMatch = regExp.exec(attributes)) {		var attrib = regExpMatch[1];		var attribValue = regExpMatch[3];		if (attribValue == '') {			continue;		}		var valid = false;		if ('center|em|strong|cite|code|var|sub|supdl|dd|dt|tt|b|i|big|small|strike|s|u|rb|rp|ruby'.indexOf(tag) >= 0) {			if (common.indexOf(attrib) >= 0) { valid = true; }		}		else if ('div|span|h1|h2|h3|h4|h5|h6|p'.indexOf(tag) >= 0) {			if ((common + '|align').indexOf(attrib) >= 0) { valid = true; }		}		else if ('blockquote'.indexOf(tag) >= 0) {			if ((common + '|cite').indexOf(attrib) >= 0) { valid = true; }		}		else if ('br'.indexOf(tag) >= 0) {			if ('style|clear'.indexOf(attrib) >= 0) { valid = true; }		}		else if ('pre'.indexOf(tag) >= 0) {			if ((common + '|width').indexOf(attrib) >= 0) { valid = true; }		}		else if ('ins|del'.indexOf(tag) >= 0) { if ((common + '|cite|datetime').indexOf(attrib) >= 0) { valid = true; } }		else if ('ul'.indexOf(tag) >= 0) { if ((common + '|type').indexOf(attrib) >= 0) { valid = true; } }		else if ('ol'.indexOf(tag) >= 0) { if ((common + '|type|start').indexOf(attrib) >= 0) { valid = true; } }		else if ('li'.indexOf(tag) >= 0) { if ((common + '|type|value').indexOf(attrib) >= 0) { valid = true; } }		else if ('table'.indexOf(tag) >= 0) { if ((common + '|summary|width|border|frame|rules|cellspacing|cellpadding|align|bgcolor|frame|rules|border').indexOf(attrib) >= 0) { valid = true; } }		else if ('caption'.indexOf(tag) >= 0) { if ((common + '|align').indexOf(attrib) >= 0) { valid = true; } }		else if ('thead|tfoot|tbody'.indexOf(tag) >= 0) { if ((common + tablealign).indexOf(attrib) >= 0) { valid = true; } }		else if ('colgroup|col'.indexOf(tag) >= 0) { if ((common + '|span|width' + tablealign).indexOf(attrib) >= 0) { valid = true; } }		else if ('tr'.indexOf(tag) >= 0) { if ((common + '|bgcolor' + tablealign).indexOf(attrib) >= 0) { valid = true; } }		else if ('td|th'.indexOf(tag) >= 0) { if ((common + tablecell + tablealign).indexOf(attrib) >= 0) { valid = true; } }		else if ('font'.indexOf(tag) >= 0) { if ((common + '|size|color|face').indexOf(attrib) >= 0) { valid = true; } }		else if ('hr'.indexOf(tag) >= 0) { if ((common + '|noshade|size|width').indexOf(attrib) >= 0) { valid = true; } }		else if ('rt'.indexOf(tag) >= 0) { if ((common + '|rbspan').indexOf(attrib) >= 0) { valid = true; } }		if (valid == true) {

// remove non-standard styles and clean up			if (attrib == 'style') { attribValue = attribValue.replace(/ *(\-moz[\w\-]+|windowtext) */g, ''); attribValue = attribValue.replace(/\b0(%|in|cm|mm|em|ex|pt|pc|px)\b/g, '0'); attribValue = attribValue.replace(/[\w\-]+ *\: *\; */g, ''); attribValue = attribValue.replace(/ *(|:) */g, '$1 '); attribValue = attribValue.replace(/( |;)+$/g, ';'); }			sanitized += ' ' + attrib + '="' + attribValue + '"'; }	}	return(sanitized); }

// // // RemoveHighlighting: remove syntax highlighting in obj.plain; sets obj.htmlCode if text contains html code //

function RemoveHighlighting(obj) {

// remove highlighting-only div, span, and xmp var isRemove = []; obj.html = obj.html.replace(/(<(\/?)(div|span|xmp)(.*?)>)/g,		function (p, p1, p2, p3, p4) {			if (p2 == ) {				if ( p4.match(/\bclass=\"wikEd\w+\"/) ) {					isRemove.push(true);					return();				}				else if (p4 == ) {					isRemove.push(true);					return();				}				isRemove.push(false);				return(p1);			}			if (isRemove.pop == true) {				return('');			}			return(p1);		}	);

obj.html = obj.html.replace(//g, ''); obj.html = obj.html.replace(/\n|\r/g, ''); if (obj.html.match(/<(?!br)/)) { obj.htmlCode = true; }	else { obj.htmlCode = false; }

return; }

// // // HighlightSyntax: highlight syntax in obj.html; if singleLine is set, no block syntax will be highlighted; call RemoveHighlighting first //

function HighlightSyntax(obj, singleLine) {

// convert newlines obj.html = obj.html.replace(/\n|\r/g, ''); obj.html = obj.html.replace(/<br(\b[^>]*)?>/g, '\n');

// escape character entities obj.html = obj.html.replace(/&(?!(amp;|lt;|gt;|nbsp;))/g, '&amp;');

////blocks start // various blocks if (singleLine != true) { obj.html = obj.html.replace(/(&lt;(blockquote|center|div|pre)\b.*?&gt;)/gi, ' $1'); obj.html = obj.html.replace(/(&lt;\/(blockquote|center|div|pre)\b.*?&gt;)/gi, '$1 '); }

// lists * # : ; obj.html = obj.html.replace(/^([\*\#\:\;]+)(.*?)$/gm, ' $1 $2 '); if (singleLine != true) { obj.html = obj.html.replace(/((<span class=\"wikEdListLine\">[^\n]*\n)+)/g, ' $1'); obj.html = obj.html.replace(/(<span class=\"wikEdListLine\">[^\n]*)(\n)(?!<span class=\"wikEdListLine\">)/g, '$1 $2'); }

// #redirect (finish) obj.html = obj.html.replace(/(<span class=\"wikEdWikiRedir\">)(.*?<\/span>)/g, '$1#$2');

// space-pre if (singleLine != true) { obj.html = obj.html.replace(/^( +)(.*?)$/gm, ' $1 $2 '); obj.html = obj.html.replace(/((<span class=\"wikEdSpaceLine\">[^\n]*\n)+)/g, ' $1'); obj.html = obj.html.replace(/(<span class=\"wikEdSpaceLine\">[^\n]*)(\n)(?! )/g, '$1 $2'); }

// horizontal rule obj.html = obj.html.replace(/(^|\n|<[^>]*>)(\n|<[^>]*>|$)/g, '$1 $2 $3'); obj.html = obj.html.replace(/(&lt;hr&gt;)/g, ' $1 ');

// == headings obj.html = obj.html.replace(/(^|\n|<[^>]*>)(=+ *)([^\n]*?)( *=+ *)(\n|<[^>]*>|$)/g,		function (p, p1, p2, p3, p4, p5) {			p2 = p2.replace(/(=+)/g, ' $1 ');			p4 = p4.replace(/(=+)/g, ' $1 ');			if ( /^(external links?|see also|references?)$/i.test(p3) ) {				p1 = p1 + ' ';				p5 = ' ' + p5;			}			else {				p1 = p1 + ' ';				p5 = ' ' + p5;			}			return(p1 + p2 + p3 + p4 + p5);		}	);

// tables                      (    |    |    |  |    |  ) obj.html = obj.html.replace(/^(\{\||\|\+|\|\-|\!|\|\}|\|)(.*?)$/gm, ' $1 $2 '); if (singleLine != true) { obj.html = obj.html.replace(/(^|\n)((<[^>]*>)*\{\|)/g, '$1 $2'); obj.html = obj.html.replace(/(^|\n)((<[^>]*>)*\|\}(<[^>]*>)*)/g, '$1$2 '); obj.html = obj.html.replace(/(&lt;table\b.*?&gt;)/gi, ' $1'); obj.html = obj.html.replace(/(&lt;\/table\b.*?&gt;)/gi, '$1 '); }

// wiki markup if (singleLine != true) { obj.html = obj.html.replace(/(&lt;(gallery)\b.*?&gt;)/gi, '$1 $1'); obj.html = obj.html.replace(/(&lt;\/(gallery)\b.*?&gt;)/gi, '$1 '); } ////blocks end

//  	obj.html = obj.html.replace(/((&lt;)sup\b.*?(&gt;)(.*?)(&lt;)\/sup\b.*?(&gt;))/gi, ' $1 '); obj.html = obj.html.replace(/((&lt;)sub\b.*?(&gt;)(.*?)(&lt;)\/sub\b.*?(&gt;))/gi, ' $1 '); obj.html = obj.html.replace(/((&lt;)(ins|u)\b.*?(&gt;)(.*?)(&lt;)\/(ins|u)\b.*?(&gt;))/gi, ' $1 '); obj.html = obj.html.replace(/((&lt;)(del|s|strike)\b.*?(&gt;)(.*?)(&lt;)\/(del|s|strike)\b.*?(&gt;))/gi, ' $1 ');

// various inlines obj.html = obj.html.replace(/(&lt;\/?(sub|sup|ins|u|del|s|strike|big|br|colgroup|code|font|small|span|tt|rb|rp|rt|ruby)\b.*?&gt;)/gi, ' $1 ');

// unsupported or not needed <> tags obj.html = obj.html.replace(/(&lt;\/?)(\w+)(.*?\/?&gt;)/g,		function (p, p1, p2, p3) {			if ( ! /^(col|thead|tfoot|tbody|big|br|blockquote|colgroup|center|code|del|div|font|ins|pre|s|small|span|strike|sub|sup|tt|u|rb|rp|rt|ruby|nowiki|math|gallery|noinclude|includeonly|ref|references)$/i.test(p2) ) {				p1 = ' ' + p1;				p3 = p3 + ' ';			}			return(p1 + p2 + p3);		}	);

// comments obj.html = obj.html.replace(/(&lt;!--.*?--&gt;)/g, ' $1 ');

//    wiki markup obj.html = obj.html.replace(/((&lt;)(nowiki|math|gallery|noinclude|includeonly|ref|references)\b.*?(&gt;)(.*?)(&lt;)\/(nowiki|math|gallery|noinclude|includeonly|ref|references)\b.*?(&gt;))/gi, ' $1 '); /* disabled, eats text // [] URL links obj.html = obj.html.replace(/(\[?)((http:\/\/|https:\/\/|ftp:\/\/|irc:\/\/|gopher:\/\/|news:|mailto:)\S*[\w\/])([^\]*?)([^\n\]]*)(.)/gi,		function (p, p1, p2, p3, p4, p5) {

// link URL, text p2 = p2.replace(/(.*)/, ' $1 '); p4 = p4.replace(/^(\s*)(.*?)(\s*)$/, '$1 $2 $3');

// link tags if ( (/\[/.test(p1)) && (/\]/.test(p5)) ) { p1 = p1.replace(/(\[)/, ' $1 '); p5 = p5.replace(/(\])/, ' $1 '); }			return(p1 + p2 + p4 + p5); }	); //  links, images, categories	obj.html = obj.html.replace(/(\[\[)([^\]]*)(\]\])/g, function (p, p1, p2, p3) {

// image if ( /^\s*image:/i.test(p2) ) { if (p2.match(/^(\s*)(.*:)+/)) { p1 = ' ' + p1; p3 = p3 + ' '; }				else { p1 = ' ' + p1; p3 = p3 + ' '; }				p2 = p2.replace(/^(\s*)(.*:)+/, '$1 $2 '); p2 = p2.replace(/(\s*)([^>:\|]+)(\s*\|\s*|$)/, '$1 $2 $3'); p2 = p2.replace(/(\|\s*)(.*)/,					function (p, p1, p2) {						p2 = p2.replace(/(.*?)(\s*(\||$))/g, ' $1 $2');						return(p1 + p2);					}				); }

// category else if ( /^\s*category:/i.test(p2) ) { if (p2.match(/^(\s*)(.*:)+/)) { p1 = ' ' + p1; p3 = p3 + ' '; }				else { p1 = ' ' + p1; p3 = p3 + ' '; }				p2 = p2.replace(/^(\s*)(.*:)+/, '$1 $2 '); p2 = p2.replace(/(\s*)([^>:\|]+)(\s*\|\s*|$)/, '$1 $2 $3'); p2 = p2.replace(/(\|\s*)(.*)/,					function (p, p1, p2) {						p2 = p2.replace(/(.*?)(\s*(\||$))/g, ' $1 $2');						return(p1 + p2);					}				); }

// wikilink else { if (p2.match(/^(\s*)(.*:)+/)) { p1 = ' ' + p1; p3 = p3 + ' '; }				else { p1 = ' ' + p1; p3 = p3 + ' '; }				p2 = p2.replace(/^(\s*)(.*:)+/, '$1 $2 '); p2 = p2.replace(/(\s*)([^>:\|]+)((\s*\|\s*)(.*))?$/,					function (p, p1, p2, p3, p4, p5) {                                         if (!p5)                                          {                                            return   p1                                                    + ' ' + p2 + ' '                                                   + p3;                                          }                                          else                                          {                                            return   p1                                                    + ' ' + p2 + ' '                                                   + p4                                                   + ' ' + p5 + ' ';                                          }                                        }				); }

// link tags p1 = p1.replace(/(\[+)/, ' $1 '); p2 = p2.replace(/(\|)/gi, ' $1 '); p3 = p3.replace(/(\]+)/, ' $1 '); return(p1 + p2 + p3); }	);

//, templates obj.html = obj.html.replace(/(\{\{+)([^\}]*)(\}\}+)/g,		function (p, p1, p2, p3) {			if (p2.match(/^(\s*)(.*:)+/)) {				p1 = ' ' + p1;				p3 = p3 + ' ';			}			else {				p1 = ' ' + p1;				p3 = p3 + ' ';			}			p2 = p2.replace(/^(\s*)(.*:)+/, '$1 $2 ');			p2 = p2.replace(/(\s*)([^>:\|]+)(\s*\|\s*|$)/, '$1 $2 $3');			p2 = p2.replace(/(\|\s*)(.*)/, function (p, p1, p2) { p2 = p2.replace(/(.*?)(\s*(\||$))/g, ' $1 $2'); return(p1 + p2); }			);

// template tags p1 = p1.replace(/(\{+)/, ' $1 '); p2 = p2.replace(/(\|)/g, ' $1 '); p3 = p3.replace(/(\}+)/, ' $1 '); return(p1 + p2 + p3); }	);

// #redirect obj.html = obj.html.replace(/(^|\n)(#)(redirect\b)/g, '$1 $3 ');

/////////// blocks original place

// <b> <i> obj.html = obj.html.replace(/(\'\'\')(\'*)(.*?)(\'*)(\'\'\')/g, ' $2$3$4 '); obj.html = obj.html.replace(/(\'\')(.*?)(\'\')/g, ' $1$2$3 '); obj.html = obj.html.replace(/(<span class=\"wikEdBold\">)/g, '$1\'\'\''); obj.html = obj.html.replace(/(<\/span>)/g, '\'\'\'$1'); obj.html = obj.html.replace(/(\'{2,})/g, ' $1 ');

// named colors obj.html = obj.html.replace(/(\b(red|orange|yellow|fuchsia|white|lime|aqua|silver)\b)/g, '<span style="background-color: $1;" class="wikEdColors">$1 '); obj.html = obj.html.replace(/(\b(maroon|olive|purple|green|navy|teal|blue|black|gray)\b)/g, '<span style="color: white; background-color: $1;" class="wikEdColors">$1 ');

// RGB colors obj.html = obj.html.replace(/(#[0-9a-fA-F]{6})([\s\'\";])/g, '<span style="background-color: $1;" class="wikEdColors">$1 $2');	obj.html = obj.html.replace(/(rgb\(\s*\d+,\s*\d+,\s*\d+\s*\))/gi, '<span style="background-color: $1;" class="wikEdColors">$1 ');

// newlines to        obj.html = ' ' + obj.html.replace(/\n/g, ' ') + ' ';

// remove comments /////// obj.html = obj.html.replace(//g, ''); ///////

// remove ... 	var isRemove = []; obj.html = obj.html.replace(/(&lt;(\/?)span(.*?)&gt;)/g,		function (p, p1, p2, p3) {			if (p2 == ) {				if (p3 == ) {					isRemove.push(true);					return();				}				isRemove.push(false);				return(p1);			}			if (isRemove.pop == true) {				return();			}			return(p1);		}	);

// display tabs and strange blanks obj.html = obj.html.replace(/(\t)(?!<\/xmp>)/g, '<xmp class="wikEdTab">$1 '); obj.html = obj.html.replace(/([\v\u2028\u2029])(?!<\/xmp>)/g, '<xmp class="wikEdBlank">$1 ');

return; }

// // HighlightSyntaxFrame: highlight syntax in frame //

function HighlightSyntaxFrame {

if (highlightSyntax != true) { return; }

// get the selection var obj = {}; obj.sel = frameWindow.getSelection;

// highlight the whole frame if (obj.sel.isCollapsed) { obj.html = frameBody.innerHTML;

// remove syntax highlighting RemoveHighlighting(obj);

// wikify, highlight, and replace if (obj.htmlCode == true) { WikifyHTML(obj); }		HighlightSyntax(obj); FrameExecCommand('selectall'); if (obj.html != '') { FrameExecCommand('inserthtml', obj.html); }		else { FrameExecCommand('delete'); }	}

// highlight a selection else { obj.selRange = obj.sel.getRangeAt(obj.sel.rangeCount - 1); var documentFragment = obj.selRange.cloneContents;

// get the inner HTML of the document fragment GetInnerHTML(obj, documentFragment); if (obj.html != '') {

// remove syntax highlighting RemoveHighlighting(obj);

// wikify, highlight, and replace selection if (obj.htmlCode == true) { WikifyHTML(obj); }			HighlightSyntax(obj); if (obj.html != '') { FrameExecCommand('inserthtml', obj.html); }			else { FrameExecCommand('delete'); }		}	}

// get new cursor container and offset obj.startPos = obj.startContainerPos + obj.selRange.startOffset; obj.endPos = obj.endContainerPos + obj.selRange.endOffset; obj.selRange = null; GetTextPosContainer(obj, frameBody); /* // set the new cursor position var range = document.createRange; range.setStart(obj.startContainer, obj.startOffset); range.setEnd(obj.endContainer, obj.endOffset); obj.sel.removeAllRanges; obj.sel.addRange(range); // focus the frame frameWindow.focus;

return; }

// // UpdateTextarea: copy frame content to textarea //

function UpdateTextarea {

// get frame content var obj = {}; obj.html = frameBody.innerHTML;

// wikify the text RemoveHighlightingWikify(obj);

// textify obj.plain = obj.html; obj.plain = obj.plain.replace(/ /g, '\n'); obj.plain = obj.plain.replace(/<.*?>/g, ''); obj.plain = obj.plain.replace(/&lt;/g, '<'); obj.plain = obj.plain.replace(/&gt;/g, '>'); obj.plain = obj.plain.replace(/\u00a0| /g, ' '); obj.plain = obj.plain.replace(/&amp;/g, '&'); ///?

// copy to textarea textareaObj.value = obj.plain;

return; }

// // UpdateFrame: copy textarea content to frame //

function UpdateFrame {

// get frame content var obj = {}; obj.html = textareaObj.value; obj.html = obj.html.replace(/</g, '&lt;'); obj.html = obj.html.replace(/>/g, '&gt;'); obj.html = obj.html.replace(/(\n?\r|\n)/g, ' ');

// display multiple blanks obj.html = obj.html.replace(/ /g, '  '); obj.html = obj.html.replace(/(\u00a0| ) /g, ' ');

// highlight the syntax if (highlightSyntax == true) { HighlightSyntax(obj); }

// set frame content frameBody.innerHTML = obj.html; return; }

// // KeyFrame: event handler for keypress in frame //

function KeyFrame(event) {

return; }

// // SetFrameSelection: wrapper for execCommand method //

function FrameExecCommand(command, option) { /* Debug(null); Debug('command', command); Debug('option', option);

frameDocument.execCommand(command, false, option); return; }

// // FindAhead: non-regexp and case-insensitive find-as-you-type, event handler for find field //

function FindAhead {

if (document.getElementById('findAhead').checked == true) {

// get the find text var findText = document.getElementById('findText').value; if (findText == '') { return; } // function: window.find(string, caseSensitive, backwards, wrapAround, wholeWord, searchInFrames, showDialog) var found = frameWindow.find(findText, false, false, true, false, false, false); if (found == false) { var sel = frameWindow.getSelection; sel.collapse(sel.anchorNode, sel.anchorOffset); }	}	return; }

// // FullScreen: change to fullscreen input area; event handler for fullscreen buttons //

function FullScreen(event) {

fullScreenMode = true;

// get heights var windowHeight = window.innerHeight; var buttonsWrapper = document.getElementById('buttonsWrapper'); var buttonsWrapperHeight = buttonsWrapper.offsetHeight; /*// set buttons margin buttonsWrapper.style.paddingLeft = '0.2em' buttonsWrapper.style.paddingBottom = '0.2em'

// textareaObj.value = windowHeight + ' - ' + buttonsWrapperHeight + ' = ' + (windowHeight - buttonsWrapperHeight);

// 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 // moving iframe in design 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'; // set color var content = document.getElementById('content'); inputWrapper.style.backgroundColor = GetStyle(content, 'background-color');

// set the textarea to maximal height frameBody.style.height = (windowHeight - buttonsWrapperHeight - 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.bottom = ''; 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; // scroll to frame top var wrapperObj = document.getElementById('frameWrapper'); var wrapperTop = GetOffsetTop(wrapperObj); window.scroll(0, wrapperTop);

return; }

// // NormalScreen: change back to normal page view; event handler for fullscreen 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 textareaObj.style.width = normalTextareaWidth; textareaObj.style.height = normalTextareaHeight; textareaObj.style.margin = normalTextareaMargin; textareaObj.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);

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 a tag to the summary box if (field == 'summary') { var text = inputElement[field].value; if ( (text != '') && (!text.match(/ \*\/ $/) ) ) { if (option.text.match(/^\w/)) { text += ', '; }					else { text += ' '; }				}				text += option.text; inputElement[field].value = text; }

// add case and regexp checkboxes to find / replace fields else if (option.value == 'setcheck') { Button('caseSensitive', null, (option.text.charAt(0) == checkMarker[true]) ); Button('regExp',       null, (option.text.charAt(1) == checkMarker[true]) ); inputElement[field].value = option.text.substr(3); }

// add option text 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 if (presetOptions[field] != null) { i = 0; 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]; if (field == 'summary') { option.text = option.text.replace(/\{using\}/g, summaryUsing); }				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; }

// // ClearHistory: clear the history of combo input fields //

function ClearHistory(field) { var cookieExpire = new Date; cookieExpire.setTime( cookieExpire.getTime + cookieExpireSec * 1000 ); SetCookie(cookieName[field], '', cookieExpire.toGMTString); SetComboOptions(field); return; }

// // LoadHistoryFromCookie: get the input box history from the respective cookie //

function LoadHistoryFromCookie(field) { var cookie = GetCookie(cookieName[field]); if (cookie != '') { cookie = decodeURIComponent(cookie); fieldHist[field] = cookie.split('\n'); }	else { fieldHist[field] = []; }	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 = cookie.replace(/\n$/, ''); cookie = encodeURIComponent(cookie); SetCookie(cookieName[field], cookie, cookieExpire.toGMTString); return; }

// GetStyle: get computed 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 = ''; var offset = 0; var end = 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) { var cookie = name + '=' + encodeURIComponent(value); if (expires != null) { cookie += '; expires=' + expires }	if (path != null) { cookie += '; path=' + path; }	if (domain != null) { cookie += '; domain=' + domain; }	if (secure != null) { cookie += '; secure'; }	document.cookie = cookie; }

// // 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); }

// // GetOffsetLeft: get element offset relative to left window border //

function GetOffsetLeft (element) { var offset = 0; do { offset += element.offsetLeft; } while ( (element = element.offsetParent) != null ); return(offset); }

// // GetCursorTextPos //

function GetCursorTextPos(obj, currentNode) {

for (var i = 0; i < currentNode.childNodes.length; i ++) { var childNode = currentNode.childNodes.item(i);

// get the position for a given container if (childNode == obj.selRange.startContainer) { obj.startContainerPos = obj.plain.length; }		if (childNode == obj.selRange.endContainer) { obj.endContainerPos = obj.plain.length; return; }

switch (childNode.nodeType) { case 1: if ( (childNode.childNodes.length == 0) && leafElements[childNode.nodeName] ) { if (childNode.nodeName == 'BR') { obj.plain += '\n'; }				}				else { GetCursorTextPos(obj, childNode); }				break; case 3: var value = childNode.nodeValue; value = value.replace(/</g, '&lt;'); value = value.replace(/>/g, '&gt;'); obj.plain += value; break; case 5: var value = '&' + childNode.nodeName + ';'; obj.plain += value; break; }	}	return; }

// // GetTextPosContainer // sets obj.startContainerm, obj.startOffset, obj.endContainer, obj.endOffset for obj.startPos, obj.endPos

function GetTextPosContainer(obj, currentNode) {

for (var i = 0; i < currentNode.childNodes.length; i ++) { var childNode = currentNode.childNodes.item(i); var textLength = obj.plain.length; switch (childNode.nodeType) { case 1: if ( (childNode.childNodes.length == 0) && leafElements[childNode.nodeName] ) { if (childNode.nodeName == 'BR') { obj.plain += '\n'; }				}				else { GetTextPosContainer(obj, childNode); if (obj.endOffset != null) { return; }				}				break; case 3: var value = childNode.nodeValue; value = value.replace(/</g, '&lt;'); value = value.replace(/>/g, '&gt;'); obj.plain += value; break; case 5: var value = '&' + childNode.nodeName + ';'; obj.plain += value; break; }

// get the container for a given position if (obj.startOffset == null) { if (obj.plain.length >= obj.startPos) { obj.startContainer = childNode; obj.startOffset = obj.startPos - textLength; }		}		if (obj.plain.length >= obj.endPos) { obj.endContainer = childNode; obj.endOffset = obj.endPos - textLength; return; }	}	return; }

// define leaf elements for GetInnerHTML var leafElements = []; leafElements['IMG'] = true; leafElements['HR'] = true; leafElements['BR'] = true; leafElements['INPUT'] = true;

// // ParseDOM: //

function ParseDOM(obj, topNode) {

obj.plainLength = 0; obj.plainArray = []; obj.plainNode = []; obj.plainStart = []; obj.plainPos = []; ParseDOMRecursive(obj, topNode); obj.plain = obj.plainArray.join('');

return; }

// // ParseDOMRecursive: //

function ParseDOMRecursive(obj, currentNode) {

// cycle through the child nodes of currentNode for each (var childNode in currentNode.childNodes) {

// check for selection if (childNode == obj.sel.focusNode) { obj.plainFocus = obj.plainLength + obj.sel.focusOffset; }		if (childNode == obj.sel.anchorNode) { obj.plainAnchor = obj.plainLength + obj.sel.anchorOffset; }		var value = null;

// get text of child node switch (childNode.nodeType) { case 1: if ( (childNode.childNodes.length == 0) && (leafElements[childNode.nodeName] == true) ) { if (childNode.nodeName == 'BR') { value = '\n'; }				}				else { ParseDOMRecursive(obj, childNode); }				break; case 3: value = childNode.nodeValue; break; case 5: value = '&' + childNode.nodeName + ';'; break; }

// add text to text object if (value != null) {

// array of text fragments obj.plainArray.push(value);

// array of text fragment node references obj.plainNode.push(childNode);

// array of text fragment text positions obj.plainStart.push(obj.plainLength);

// node references containing text positions obj.plainPos[childNode] = obj.plainLength;

// current text length obj.plainLength += value.length; }	}	return; }

// // GetInnerHTML: get innerHTML from document fragment //

function GetInnerHTML(obj, currentNode) {

// initialize string if (obj.html == null) { obj.html = ''; }	if (obj.plain == null) { obj.plain = ''; }	if (obj.plainArray == null) { obj.plainArray = []; obj.plainNode = []; obj.plainStart = []; }

for (var i = 0; i < currentNode.childNodes.length; i ++) { var childNode = currentNode.childNodes.item(i); switch (childNode.nodeType) { case 1: obj.html += '<' + childNode.nodeName.toLowerCase; for (var j = 0; j < childNode.attributes.length; j ++) { if (childNode.attributes.item(j).nodeValue != null) { obj.html += ' ' + childNode.attributes.item(j).nodeName + '="' + childNode.attributes.item(j).nodeValue.replace(/</g, '&lt;').replace(/>/g, '&gt;') + '"'; }				}				if ( (childNode.childNodes.length == 0) && leafElements[childNode.nodeName] ) { obj.html += '>'; if (childNode.nodeName == 'BR') { obj.plainArray.push('\n'); obj.plainNode.push(childNode); obj.plainStart.push(obj.plain.length); obj.plain += '\n'; }				}				else { obj.html += '>'; GetInnerHTML(obj, childNode); obj.html += '</' + childNode.nodeName.toLowerCase + '>' }				break; case 3: var value = childNode.nodeValue; value = value.replace(/</g, '&lt;'); value = value.replace(/>/g, '&gt;'); obj.html += value; obj.plainArray.push(value); obj.plainNode.push(childNode); obj.plainStart.push(obj.plain.length); obj.plain += value; break; case 4: obj.html += '<![CDATA[' + childNode.nodeValue + ']]>'; break; case 5: var value = '&' + childNode.nodeName + ';'; obj.html += value; obj.plainArray.push(value); obj.plainNode.push(childNode); obj.plainStart.push(obj.plain.length); obj.plain += value; break; case 8: obj.html += ''; break; }	}	return; }

// StyleSheet: create a new style sheet object function StyleSheet(documentObject) {

this.styleElement = null; if (documentObject == null) { documentObject = document; }

// IE	if (documentObject.createStyleSheet) { this.styleElement = documentObject.createStyleSheet; }

// standards compliant browsers else { this.styleElement = documentObject.createElement('style'); this.styleElement.from = 'text/css'; var insert = documentObject.getElementsByTagName('head')[0]; if (insert != null) { insert.appendChild(this.styleElement); }	}

// add-a-rule method

// IE	this.addRule = function(selector, declaration) { if (this.styleElement.addRule) { this.styleElement.addRule(selector, declaration); }

// standards compliant browsers else { if (this.styleElement.sheet != null) { if (this.styleElement.sheet.insertRule != null) { this.styleElement.sheet.insertRule(selector + ' { ' + declaration + ' } ', 0); }			}		}	};	return; }

// Debug: print variable content function Debug(objectName, object) {

document.getElementById('textareaWrapper').style.display = 'block'; if (objectName == null) { textareaObj.value = ''; textareaObj.style.height = '10em'; }	else { textareaObj.value += objectName + ': ' + object + '\n'; }	return; }

/* */