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