User:Zocky/wikEdDev.js
From Wikipedia, the free encyclopedia
If a message on your talk page led you here, please be wary of who left it. Code that you insert on this page could contain malicious content capable of compromising your account. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. If this is a .js page, the code will be executed when previewing the page.
Note: After saving, you have to bypass your browser's cache to see the changes. In Internet Explorer and Firefox, hold down the Ctrl key and click the Refresh or Reload button. Opera users have to clear their caches through Tools→Preferences, see the instructions for Opera. Konqueror and Safari users can just click the Reload button.
/* <pre><nowiki> */ /* [[User:Zocky|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 [[User:Cacycle/wikEd|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 += '<div class="wikEdButtonsFormat" id="wikEdButtonsFormat">'; html += '<img class="wikEdButton" src="' + image['undo'] + '" width="16" height="16" alt="Undo" title="Undo" onClick="javascript:Edit(\'undo\');">'; html += '<img class="wikEdButton" src="' + image['redo'] + '" width="16" height="16" alt="Redo" title="Redo" onClick="javascript:Edit(\'redo\');">'; html += '<img class="wikEdButton" src="' + image['bold'] + '" width="16" height="16" alt="Bold" title="Bold text" onClick="javascript:Edit(\'bold\');">'; html += '<img class="wikEdButton" src="' + image['italic'] + '" width="16" height="16" alt="Italic" title="Italic text" onClick="javascript:Edit(\'italic\');">'; html += '<img class="wikEdButton" src="' + image['underline'] + '" width="16" height="16" alt="Underline" title="Underline text" onClick="javascript:Edit(\'underline\');">'; html += '<img class="wikEdButton" src="' + image['superscript'] + '" width="16" height="16" alt="Superscript" title="Superscript text" onClick="javascript:Edit(\'sup\');">'; html += '<img class="wikEdButton" src="' + image['subscript'] + '" width="16" height="16" alt="Subscript" title="Subscript text" onClick="javascript:Edit(\'sub\');">'; html += '<img class="wikEdButton" src="' + image['case'] + '" width="16" height="16" alt="Casing" title="Toggle between lowercase, uppercase first letters, and uppercase" onClick="javascript:Edit(\'case\');">'; html += '<img class="wikEdButton" src="' + image['undo_all'] + '" width="16" height="16" alt="Undo all" title="Undo all changes" onClick="javascript:Edit(\'undoall\');">'; html += '<img class="wikEdButton" src="' + image['redo_all'] + '" width="16" height="16" alt="Redo all" title="Redo all changes" onClick="javascript:Edit(\'redoall\');">'; html += '<img class="wikEdButton" src="' + image['redirect'] + '" width="16" height="16" alt="Redirect" title="Redirect" onClick="javascript:Edit(\'redirect\');">'; html += '<img class="wikEdButton" src="' + image['syntax'] + '" width="16" height="16" alt="Syntax" title="Update syntax highlighting" onClick="javascript:Edit(\'update_syntax\');">'; html += '<br>'; html += '<img class="wikEdButton" src="' + image['wikilink'] + '" width="16" height="16" alt="Link" title="Wiki link" onClick="javascript:Edit(\'wikilink\');">'; html += '<img class="wikEdButton" src="' + image['weblink'] + '" width="16" height="16" alt="Weblink" title="External Weblink" onClick="javascript:Edit(\'weblink\');">'; html += '<img class="wikEdButton" src="' + image['decrease_heading'] + '" width="16" height="16" alt="Heading-" title="Decrease heading levels" onClick="javascript:Edit(\'headingless\');">'; html += '<img class="wikEdButton" src="' + image['increase_heading'] + '" width="16" height="16" alt="Heading+" title="Increase heading levels" onClick="javascript:Edit(\'headingmore\');">'; 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 += '</div>'; // window functions: syntax highlighting, classic textarea, align, fullscreen html += '<div class="wikEdButtonsWindow" id="wikEdButtonsWindow">'; 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 += '<br>'; 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 += '</div>'; // find / replace buttons html += '<div class="wikEdButtonsFind" id="wikEdButtonsFind">'; 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 += '<span style="position: relative; padding: 0; margin: 0 0.2em;" id="findComboInput">'; 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 += '</select>'; html += '</span>'; 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 += '<br>'; // 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 += '<span style="position: relative; padding: 0; margin: 0 0.2em;" id="replaceComboInput">'; 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 += '</select>'; html += '</span>'; 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 += '</div>'; // fixing buttons html += '<div class="wikEdButtonsFix" id="wikEdButtonsFix">'; 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 += '<br>'; 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 += '</div>'; 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 += '</div>'; html += '</div>'; html += '<div class="wikEdButtonsWindow">'; 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 += '</div>'; 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 += ' <span style="position: relative;" id="summaryComboInput">'; html += ' style="padding: 0; margin: 0; position: absolute; left: 0; top: 0; z-index: 2;" onfocus="this.setSelectionRange(0, this.textLength);"'; htmlPost += '<select style="border: none; padding: 0; margin: 0; position: relative; vertical-align: middle; z-index: 1;" id="wpSummarySelect" onfocus="javascript:SetComboOptions(\'summary\')" onchange="javascript:ChangeComboInput(\'summary\');">'; htmlPost += '</select>'; htmlPost += '</span>'; summary.parentNode.innerHTML = summary.parentNode.innerHTML.replace(/\s*(<input\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 += '</div>'; html += '<iframe id="wikEdFrame" name="wikEdFrame" style="width: 100%; height: ' + textareaHeight + 'px; padding: 0; margin: 0; border: none;"></iframe>'; html += '</div>'; html += '</div>'; frameWrapper.innerHTML = html; inputWrapper.insertBefore(frameWrapper, textareaWrapper); frameWindow = document.getElementById('wikEdFrame').contentWindow; frameDocument = frameWindow.document; // fill the frame with content html = ''; html += '<html><head></head>'; html += '<body id="frameBody" onload="window.document.designMode = \'on\'; window.document.execCommand(\'styleWithCSS\', false, false);">'; html += '</body></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(/<br>/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(/<br>/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(/<br>/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(/<br>/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(/<br>/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(/<br>/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 ( /<u>(.*?)<\/u>/i.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/<u>(.*?)<\/u>/g, '$1'); } else { obj.changed.plain = '<u>' + obj.changed.plain + '<\/u>'; obj.changed.plain = obj.changed.plain.replace(/(<u>)( *)(.*?)( *)(<\/u>)/, '$2$1$3$5$4'); } break; // superscript case 'sup': if ( /<sup>(.*?)<\/sup>/i.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/<sup>(.*?)<\/sup>/g, '$1'); } else { obj.changed.plain = '<sup>' + obj.changed.plain + '</sup>'; obj.changed.plain = obj.changed.plain.replace(/(<sup>)( *)(.*?)( *)(<\/sup>)/, '$2$1$3$5$4'); } break; // subscript case 'sub': if ( /<sub>(.*?)<\/sub>/i.test(obj.changed.plain) ) { obj.changed.plain = obj.changed.plain.replace(/<sub>(.*?)<\/sub>/g, '$1'); } else { obj.changed.plain = '<sub>' + obj.changed.plain + '</sub>'; obj.changed.plain = obj.changed.plain.replace(/(<sub>)( *)(.*?)( *)(<\/sub>)/, '$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 = '[[Image:<span class="wikEdInsertHere">filename</span>|thumb|<span class="wikEdInsertHere">width</span>px|' + obj.changed.plain + ']]'; } else { obj.changed.plain = '[[Image:<span class="wikEdInsertHere">filename</span>|thumb|<span class="wikEdInsertHere">width</span>px|<span class="wikEdInsertHere"> </span>]]'; 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{| {{Prettytable}}\n'); obj.changed.plain = obj.changed.plain.replace(/$/g, '\n|}\n'); } else { obj.changed.plain = '\n{| {{Prettytable}}\n|+ <span class="wikEdInsertHere">caption</span>\n! <span class="wikEdinserthere">heading</span> !! <span class="wikEdInsertHere">heading</span>\n|-\n| <span class="wikEdInsertHere">cell</span> || <span class="wikEdInsertHere">cell</span>\n|-\n| <span class="wikEdInsertHere">cell</span> || <span class="wikEdInsertHere">cell</span>\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, '<br>'); break; // redirect case 'redirect': var linkTarget; if (obj.selectionWord.plain != '') { linkTarget = obj.selectionWord.plain; } else { linkTarget = '<span class="wikEdInsertHere">article link</span>'; } // 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(/<br>/g, ''); obj.changed.plain = obj.changed.plain.replace(/&/g, '&'); obj.changed.plain = obj.changed.plain.replace(/\n/g, '<br>\n'); highlightSyntaxEdit = false; break; // source off case 'sourceoff': obj.changed.plain = obj.changed.plain.replace(/<br>\n/gi, '\n'); obj.changed.plain = obj.changed.plain.replace(/&/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, '<br>'); 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(/^(\[\[image:.*?\]\])/ig, '\n$1'); line = line.replace(/(\[\[image:.*?(\[\[.*?\]\].*?)*\]\])$/ig, '$1\n'); // empty line before and after includes line = line.replace(/^(\{\{.*?\}\})/g, '\n$1'); line = line.replace(/(\{\{.*?\}\})$/g, '$1\n'); // to be done: convert single newlines into spaces // line = line.replace(/(\n[^\n \*\#\:\;\|\{].*?)\n([^\n \*\#\:\;\|\{])/g, '$1 $2'); } } // concatenate the lines 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(/(<!--) *([^\n]*?) *(-->)/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(/(\[\[(?!image:)[^\n]+?) *\| *(.*?\]\])/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 <math> </math> wikicode obj.plain = obj.plain.replace(/(.*?)<math(\b[^>]*)?>.*?<\/math>/gi, function (p, p1) { // convert html entities into actual dash characters p1 = p1.replace(/−/g, '\u2212'); p1 = p1.replace(/·/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 10<sup>3</sup> p1 = p1.replace(/(\d*\.?\d+)\^(\u2212?\d+\.?\d*)/g, '$1<sup>$2</sup>'); // change x^3 to x<sup>3</sup> p1 = p1.replace(/([0-9a-zA-Z])\^(\u2212?\d+\.?\d*) /g, '$1<sup>$2</sup>'); // 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')(<sub>)?(\d*)(<\/sub>)?)+)|[\(\)\[\]\-\=])\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(/(<sub>)?0*(\d+)(<\/sub>)?/g, '<sub>$2<\/sub>'); 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 ° into actual ° symbol obj.plain = obj.plain.replace(/°/g, '°'); // convert the word ohm(s) or the html entity into the actual Omega symbol (not the actual ohm symbol Ω) 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|μ|µ|µ|n|p|f|a|z|y)? ?(Ω|Ω|(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) ?(μ|µ)(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|μ|µ|µ|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|μ|µ|µ|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|μ|µ|µ|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|μ|µ|µ|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(/—/g, '—'); obj.plain = obj.plain.replace(/–/g, '–'); obj.plain = obj.plain.replace(/−/g, '\u2212'); // convert -- and em dashes with or without spaces to em dash surrounded by spaces obj.plain = obj.plain.replace(/([a-zA-Z\'\"”\]\}\)]) *(--|—|—) *([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) ?(--?|—|—) ?([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(/</g, '<'); obj.html = obj.html.replace(/>/g, '>'); // wikify WikifyHTML(obj); // turn real html into visible html code obj.html = obj.html.replace(/<br>/g, '\n'); obj.html = obj.html.replace(/</g, '<'); obj.html = obj.html.replace(/>/g, '>'); 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(/(\[\[)image:(\w)([^\n]*\]\])/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: [Exception... "Index or size is negative or greater than the allowed amount" // code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "file:///C:/editor.js Line: 1713"] 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, '&'); // remove comments obj.html = obj.html.replace(/<!--.*?-->/g, ''); // <hr> horizontal rule obj.html = obj.html.replace(/\s*<hr(\b[^>]*)>\s*/gi, '\n----\n'); // <i> <em> <dfn> <var> <cite> 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> <strong> bold obj.html = obj.html.replace(/<(b|strong)\b.*?>/gi, '\'\'\''); obj.html = obj.html.replace(/<\/(b|strong)\b.*?>/gi, '\'\'\''); // <h1> .. <h6> 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'); // <span> <div> obj.html = obj.html.replace(/<(span|div)\s+([^>]*)>/gi, function (p, p1, p2) { return('<' + p1 + SanitizeAttributes(p1, p2) + '>'); } ); // <td> <p> table cell, remove first paragraph obj.html = obj.html.replace(/(<td\b[^>]*>)\s*<p\b.*?>/gi, '$1'); // <thead> <tbody> <tfoot> obj.html = obj.html.replace(/<\/?(thead|tbody|tfoot)\b.*?>/gi, ''); // <td> 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) + ' | '); } ); // <th> 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) + ' | '); } ); // <tr> 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'); } ); // <caption> 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) + ' | '); } ); // <table> 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(/&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('[[Image:' + image + imgWidth + alt + ']]'); } 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(/&nbsp;|\n/g, ' '); linkText = linkText.replace(/ {2,}/g, ' '); linkText = linkText.replace(/^ | $/g, ''); if ( /\[image:(.*?)\]/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, '&'); 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('[[' + article + '|' + 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(''); } } ); // <p> 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('<' + p1 + SanitizeAttributes(p1, p2) + '>'); } ); // closing html tags obj.html = obj.html.replace(/</g, '<'); obj.html = obj.html.replace(/>/g, '>'); // newlines to <br> obj.html = obj.html.replace(/\n{3,}/g, '\n\n'); obj.html = obj.html.replace(/\n/g, '<br>'); 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(/<!--wikEd\w+-->/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, '&'); ////blocks start // various blocks if (singleLine != true) { obj.html = obj.html.replace(/(<(blockquote|center|div|pre)\b.*?>)/gi, '<span class="wikEdBlock">$1'); obj.html = obj.html.replace(/(<\/(blockquote|center|div|pre)\b.*?>)/gi, '$1</span><!--wikEdBlock-->'); } // lists * # : ; obj.html = obj.html.replace(/^([\*\#\:\;]+)(.*?)$/gm, '<span class="wikEdListLine"><span class="wikEdListTag">$1</span><!--wikEdListTag-->$2</span><!--wikEdListLine-->'); if (singleLine != true) { obj.html = obj.html.replace(/((<span class=\"wikEdListLine\">[^\n]*\n)+)/g, '<span class="wikEdListBlock">$1'); obj.html = obj.html.replace(/(<span class=\"wikEdListLine\">[^\n]*)(\n)(?!<span class=\"wikEdListLine\">)/g, '$1</span><!--wikEdListBlock-->$2'); } // #redirect (finish) obj.html = obj.html.replace(/(<span class=\"wikEdWikiRedir\">)(.*?<\/span><!--wikEdWikiRedir-->)/g, '$1#$2'); // space-pre if (singleLine != true) { obj.html = obj.html.replace(/^( +)(.*?)$/gm, '<span class="wikEdSpaceLine"><span class="wikEdSpaceTag">$1</span><!--wikEdSpaceTag-->$2</span><!--wikEdSpaceLine-->'); obj.html = obj.html.replace(/((<span class=\"wikEdSpaceLine\">[^\n]*\n)+)/g, '<span class="wikEdSpaceBlock">$1'); obj.html = obj.html.replace(/(<span class=\"wikEdSpaceLine\">[^\n]*)(\n)(?!<span class="wikEdSpaceLine">)/g, '$1</span><!--wikEdSpaceBlock-->$2'); } // ---- <hr> horizontal rule obj.html = obj.html.replace(/(^|\n|<[^>]*>)(----)(\n|<[^>]*>|$)/g, '$1<span class="wikEdHR">$2</span><!--wikEdHR-->$3'); obj.html = obj.html.replace(/(<hr>)/g, '<span class="wikEdHRInline">$1</span><!--wikEdHRInline-->'); // == headings obj.html = obj.html.replace(/(^|\n|<[^>]*>)(=+ *)([^\n]*?)( *=+ *)(\n|<[^>]*>|$)/g, function (p, p1, p2, p3, p4, p5) { p2 = p2.replace(/(=+)/g, '<span class="wikEdWiki">$1</span><!--wikEdWiki-->'); p4 = p4.replace(/(=+)/g, '<span class="wikEdWiki">$1</span><!--wikEdWiki-->'); if ( /^(external links?|see also|references?)$/i.test(p3) ) { p1 = p1 + '<span class="wikEdHeadingWp">'; p5 = '</span><!--wikEdHeadingWp-->' + p5; } else { p1 = p1 + '<span class="wikEdHeading">'; p5 = '</span><!--wikEdHeading-->' + p5; } return(p1 + p2 + p3 + p4 + p5); } ); // tables ( | | | | | ) obj.html = obj.html.replace(/^(\{\||\|\+|\|\-|\!|\|\}|\|)(.*?)$/gm, '<span class="wikEdTableLine"><span class="wikEdTableTag">$1</span><!--wikEdTableTag-->$2</span><!--wikEdTableLine-->'); if (singleLine != true) { obj.html = obj.html.replace(/(^|\n)((<[^>]*>)*\{\|)/g, '$1<span class="wikEdTableBlock">$2'); obj.html = obj.html.replace(/(^|\n)((<[^>]*>)*\|\}(<[^>]*>)*)/g, '$1$2</span><!--wikEdTableBlock-->'); obj.html = obj.html.replace(/(<table\b.*?>)/gi, '<span class="wikEdTableBlock">$1'); obj.html = obj.html.replace(/(<\/table\b.*?>)/gi, '$1</span><!--wikEdTableBlock-->'); } // <gallery> wiki markup if (singleLine != true) { obj.html = obj.html.replace(/(<(gallery)\b.*?>)/gi, '$1<span class="wikEdWiki">$1'); obj.html = obj.html.replace(/(<\/(gallery)\b.*?>)/gi, '$1</span><!--wikEdWiki-->'); } ////blocks end // <sup> </sub> <ins> <del> obj.html = obj.html.replace(/((<)sup\b.*?(>)(.*?)(<)\/sup\b.*?(>))/gi, '<span class="wikEdSup">$1</span><!--wikEdSup-->'); obj.html = obj.html.replace(/((<)sub\b.*?(>)(.*?)(<)\/sub\b.*?(>))/gi, '<span class="wikEdSub">$1</span><!--wikEdSub-->'); obj.html = obj.html.replace(/((<)(ins|u)\b.*?(>)(.*?)(<)\/(ins|u)\b.*?(>))/gi, '<span class="wikEdIns">$1</span><!--wikEdIns-->'); obj.html = obj.html.replace(/((<)(del|s|strike)\b.*?(>)(.*?)(<)\/(del|s|strike)\b.*?(>))/gi, '<span class="wikEdDel">$1</span><!--wikEdDel-->'); // various inlines obj.html = obj.html.replace(/(<\/?(sub|sup|ins|u|del|s|strike|big|br|colgroup|code|font|small|span|tt|rb|rp|rt|ruby)\b.*?>)/gi, '<span class="wikEdInline">$1</span><!--wikEdInline-->'); // unsupported or not needed <> tags obj.html = obj.html.replace(/(<\/?)(\w+)(.*?\/?>)/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 = '<span class="wikEdUnknown">' + p1; p3 = p3 + '</span><!--wikEdUnknown-->'; } return(p1 + p2 + p3); } ); // comments obj.html = obj.html.replace(/(<!--.*?-->)/g, '<span class="wikEdComment">$1</span><!--wikEdComment-->'); // <nowiki> <math> <noinclude> <includeonly> <ref> <references> wiki markup obj.html = obj.html.replace(/((<)(nowiki|math|gallery|noinclude|includeonly|ref|references)\b.*?(>)(.*?)(<)\/(nowiki|math|gallery|noinclude|includeonly|ref|references)\b.*?(>))/gi, '<span class="wikEdWiki">$1</span><!--wikEdWiki-->'); /* 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(/(.*)/, '<span class="wikEdURLLink">$1</span><!--wikEdURLLink-->'); p4 = p4.replace(/^(\s*)(.*?)(\s*)$/, '$1<span class="wikEdURLText">$2</span><!--wikEdURLText-->$3'); // link tags if ( (/\[/.test(p1)) && (/\]/.test(p5)) ) { p1 = p1.replace(/(\[)/, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); p5 = p5.replace(/(\])/, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); } 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 = '<span class="wikEdImageInter">' + p1; p3 = p3 + '</span><!--wikEdImageInter-->'; } else { p1 = '<span class="wikEdImage">' + p1; p3 = p3 + '</span><!--wikEdImage-->'; } p2 = p2.replace(/^(\s*)(.*:)+/, '$1<span class="wikEdInter">$2</span><!--wikEdInter-->'); p2 = p2.replace(/(\s*)([^>:\|]+)(\s*\|\s*|$)/, '$1<span class="wikEdImageName">$2</span><!--wikEdImageName-->$3'); p2 = p2.replace(/(\|\s*)(.*)/, function (p, p1, p2) { p2 = p2.replace(/(.*?)(\s*(\||$))/g, '<span class="wikEdImageText">$1</span><!--wikEdImageText-->$2'); return(p1 + p2); } ); } // category else if ( /^\s*category:/i.test(p2) ) { if (p2.match(/^(\s*)(.*:)+/)) { p1 = '<span class="wikEdCatInter">' + p1; p3 = p3 + '</span><!--wikEdCatInter-->'; } else { p1 = '<span class="wikEdCat">' + p1; p3 = p3 + '</span><!--wikEdCat-->'; } p2 = p2.replace(/^(\s*)(.*:)+/, '$1<span class="wikEdInter">$2</span><!--wikEdInter-->'); p2 = p2.replace(/(\s*)([^>:\|]+)(\s*\|\s*|$)/, '$1<span class="wikEdCatName">$2</span><!--wikEdCatName-->$3'); p2 = p2.replace(/(\|\s*)(.*)/, function (p, p1, p2) { p2 = p2.replace(/(.*?)(\s*(\||$))/g, '<span class="wikEdCatText">$1</span><!--wikEdCatText-->$2'); return(p1 + p2); } ); } // wikilink else { if (p2.match(/^(\s*)(.*:)+/)) { p1 = '<span class="wikEdLinkInter">' + p1; p3 = p3 + '</span><!--wikEdLinkInter-->'; } else { p1 = '<span class="wikEdLink">' + p1; p3 = p3 + '</span><!--wikEdLink-->'; } p2 = p2.replace(/^(\s*)(.*:)+/, '$1<span class="wikEdInter">$2</span><!--wikEdInter-->'); p2 = p2.replace(/(\s*)([^>:\|]+)((\s*\|\s*)(.*))?$/, function (p, p1, p2, p3, p4, p5) { if (!p5) { return p1 + '<span class="wikEdLinkLiteral">' + p2 + '</span><!--wikEdLinkLiteral-->' + p3; } else { return p1 + '<span class="wikEdLinkName">' + p2 + '</span><!--wikEdLinkName-->' + p4 + '<span class="wikEdLinkText">' + p5 + '</span><!--wikEdLinkText-->'; } } ); } // link tags p1 = p1.replace(/(\[+)/, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); p2 = p2.replace(/(\|)/gi, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); p3 = p3.replace(/(\]+)/, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); return(p1 + p2 + p3); } ); // {{ }}, {{{ }}} templates obj.html = obj.html.replace(/(\{\{+)([^\}]*)(\}\}+)/g, function (p, p1, p2, p3) { if (p2.match(/^(\s*)(.*:)+/)) { p1 = '<span class="wikEdTemplInter">' + p1; p3 = p3 + '</span><!--wikEdTemplInter-->'; } else { p1 = '<span class="wikEdTempl">' + p1; p3 = p3 + '</span><!--wikEdTempl-->'; } p2 = p2.replace(/^(\s*)(.*:)+/, '$1<span class="wikEdInter">$2</span><!--wikEdInter-->'); p2 = p2.replace(/(\s*)([^>:\|]+)(\s*\|\s*|$)/, '$1<span class="wikEdTemplName">$2</span><!--wikEdTemplName-->$3'); p2 = p2.replace(/(\|\s*)(.*)/, function (p, p1, p2) { p2 = p2.replace(/(.*?)(\s*(\||$))/g, '<span class="wikEdTemplText">$1</span><!--wikEdTemplText-->$2'); return(p1 + p2); } ); // template tags p1 = p1.replace(/(\{+)/, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); p2 = p2.replace(/(\|)/g, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); p3 = p3.replace(/(\}+)/, '<span class="wikEdLinkTag">$1</span><!--wikEdLinkTag-->'); return(p1 + p2 + p3); } ); // #redirect obj.html = obj.html.replace(/(^|\n)(#)(redirect\b)/g, '$1<span class="wikEdWikiRedir">$3</span><!--wikEdWikiRedir-->'); /////////// blocks original place // <b> <i> obj.html = obj.html.replace(/(\'\'\')(\'*)(.*?)(\'*)(\'\'\')/g, '<span class="wikEdBold">$2$3$4</span><!--wikEdBold-->'); obj.html = obj.html.replace(/(\'\')(.*?)(\'\')/g, '<span class="wikEdItalic">$1$2$3</span><!--wikEdItalic-->'); obj.html = obj.html.replace(/(<span class=\"wikEdBold\">)/g, '$1\'\'\''); obj.html = obj.html.replace(/(<\/span><!--wikEdBold-->)/g, '\'\'\'$1'); obj.html = obj.html.replace(/(\'{2,})/g, '<span class="wikEdWiki">$1</span><!--wikEdWiki-->'); // 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</span><!--wikEdColors-->'); 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</span><!--wikEdColors-->'); // RGB colors obj.html = obj.html.replace(/(#[0-9a-fA-F]{6})([\s\'\";])/g, '<span style="background-color: $1;" class="wikEdColors">$1</span><!--wikEdColors-->$2'); obj.html = obj.html.replace(/(rgb\(\s*\d+,\s*\d+,\s*\d+\s*\))/gi, '<span style="background-color: $1;" class="wikEdColors">$1</span><!--wikEdColors-->'); // newlines to <br> obj.html = '<span class="wikEdLine">' + obj.html.replace(/\n/g, '</span><!--wikEdLine--><br><span class="wikEdLine">') + '</span><!--wikEdLine-->'; // remove comments /////// obj.html = obj.html.replace(/<!--wikEd\w+-->/g, ''); /////// // remove <span> ... </span> var isRemove = []; obj.html = obj.html.replace(/(<(\/?)span(.*?)>)/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><!--wikEdTab-->)/g, '<xmp class="wikEdTab">$1</xmp><!--wikEdTab-->'); obj.html = obj.html.replace(/([\v\u2028\u2029])(?!<\/xmp><!--wikEdBlank-->)/g, '<xmp class="wikEdBlank">$1</xmp><!--wikEdBlank-->'); 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(/<br>/g, '\n'); obj.plain = obj.plain.replace(/<.*?>/g, ''); obj.plain = obj.plain.replace(/</g, '<'); obj.plain = obj.plain.replace(/>/g, '>'); obj.plain = obj.plain.replace(/\u00a0| /g, ' '); obj.plain = obj.plain.replace(/&/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, '<'); obj.html = obj.html.replace(/>/g, '>'); obj.html = obj.html.replace(/(\n?\r|\n)/g, '<br>'); // 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, '<'); value = value.replace(/>/g, '>'); 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, '<'); value = value.replace(/>/g, '>'); 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, '<').replace(/>/g, '>') + '"'; } } 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, '<'); value = value.replace(/>/g, '>'); 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 += '<!--' + childNode.nodeValue + '-->'; 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; } /* </nowiki></pre> */

