// MediaWiki JavaScript support functions var clientPC = navigator.userAgent.toLowerCase(); // Get client info var is_gecko = /gecko/.test( clientPC ) && !/khtml|spoofer|netscape\/7\.0/.test(clientPC); var webkit_match = clientPC.match(/applewebkit\/(\d+)/); if (webkit_match) { var is_safari = clientPC.indexOf('applewebkit') != -1 && clientPC.indexOf('spoofer') == -1; var is_safari_win = is_safari && clientPC.indexOf('windows') != -1; var webkit_version = parseInt(webkit_match[1]); } var is_khtml = navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ); // For accesskeys; note that FF3+ is included here! var is_ff2 = /firefox\/[2-9]|minefield\/3/.test( clientPC ); var is_ff2_ = /firefox\/2/.test( clientPC ); // These aren't used here, but some custom scripts rely on them var is_ff2_win = is_ff2 && clientPC.indexOf('windows') != -1; var is_ff2_x11 = is_ff2 && clientPC.indexOf('x11') != -1; if (clientPC.indexOf('opera') != -1) { var is_opera = true; var is_opera_preseven = window.opera && !document.childNodes; var is_opera_seven = window.opera && document.childNodes; var is_opera_95 = /opera\/(9.[5-9]|[1-9][0-9])/.test( clientPC ); } // Global external objects used by this script. /*extern ta, stylepath, skin */ // add any onload functions in this hook (please don't hard-code any events in the xhtml source) var doneOnloadHook; if (!window.onloadFuncts) { var onloadFuncts = []; } function addOnloadHook(hookFunct) { // Allows add-on scripts to add onload functions if(!doneOnloadHook) { onloadFuncts[onloadFuncts.length] = hookFunct; } else { hookFunct(); // bug in MSIE script loading } } function hookEvent(hookName, hookFunct) { addHandler(window, hookName, hookFunct); } function importScript(page) { var uri = wgScript + '?title=' + encodeURIComponent(page.replace(/ /g,'_')).replace('%2F','/').replace('%3A',':') + '&action=raw&ctype=text/javascript'; return importScriptURI(uri); } var loadedScripts = {}; // included-scripts tracker function importScriptURI(url) { if (loadedScripts[url]) { return null; } loadedScripts[url] = true; var s = document.createElement('script'); s.setAttribute('src',url); s.setAttribute('type','text/javascript'); document.getElementsByTagName('head')[0].appendChild(s); return s; } function importStylesheet(page) { return importStylesheetURI(wgScript + '?action=raw&ctype=text/css&title=' + encodeURIComponent(page.replace(/ /g,'_'))); } function importStylesheetURI(url) { return document.createStyleSheet ? document.createStyleSheet(url) : appendCSS('@import "' + url + '";'); } function appendCSS(text) { var s = document.createElement('style'); s.type = 'text/css'; s.rel = 'stylesheet'; if (s.styleSheet) s.styleSheet.cssText = text //IE else s.appendChild(document.createTextNode(text + '')) //Safari sometimes borks on null document.getElementsByTagName('head')[0].appendChild(s); return s; } // special stylesheet links if (typeof stylepath != 'undefined' && typeof skin != 'undefined') { if (is_opera_preseven) { importStylesheetURI(stylepath+'/'+skin+'/Opera6Fixes.css'); } else if (is_opera_seven && !is_opera_95) { importStylesheetURI(stylepath+'/'+skin+'/Opera7Fixes.css'); } else if (is_opera_95) { importStylesheetURI(stylepath+'/'+skin+'/Opera9Fixes.css'); } else if (is_khtml) { importStylesheetURI(stylepath+'/'+skin+'/KHTMLFixes.css'); } else if (is_ff2_) { importStylesheetURI(stylepath+'/'+skin+'/FF2Fixes.css'); } } if (wgBreakFrames) { // Un-trap us from framesets if (window.top != window) { window.top.location = window.location; } } function showTocToggle() { if (document.createTextNode) { // Uses DOM calls to avoid document.write + XHTML issues var linkHolder = document.getElementById('toctitle'); if (!linkHolder) { return; } var outerSpan = document.createElement('span'); outerSpan.className = 'toctoggle'; var toggleLink = document.createElement('a'); toggleLink.id = 'togglelink'; toggleLink.className = 'internal'; toggleLink.href = 'javascript:toggleToc()'; toggleLink.appendChild(document.createTextNode(tocHideText)); outerSpan.appendChild(document.createTextNode('[')); outerSpan.appendChild(toggleLink); outerSpan.appendChild(document.createTextNode(']')); linkHolder.appendChild(document.createTextNode(' ')); linkHolder.appendChild(outerSpan); var cookiePos = document.cookie.indexOf("hidetoc="); if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) { toggleToc(); } } } function changeText(el, newText) { // Safari work around if (el.innerText) { el.innerText = newText; } else if (el.firstChild && el.firstChild.nodeValue) { el.firstChild.nodeValue = newText; } } function toggleToc() { var toc = document.getElementById('toc').getElementsByTagName('ul')[0]; var toggleLink = document.getElementById('togglelink'); if (toc && toggleLink && toc.style.display == 'none') { changeText(toggleLink, tocHideText); toc.style.display = 'block'; document.cookie = "hidetoc=0"; } else { changeText(toggleLink, tocShowText); toc.style.display = 'none'; document.cookie = "hidetoc=1"; } } var mwEditButtons = []; var mwCustomEditButtons = []; // eg to add in MediaWiki:Common.js function escapeQuotes(text) { var re = new RegExp("'","g"); text = text.replace(re,"\\'"); re = new RegExp("\\n","g"); text = text.replace(re,"\\n"); return escapeQuotesHTML(text); } function escapeQuotesHTML(text) { var re = new RegExp('&',"g"); text = text.replace(re,"&"); re = new RegExp('"',"g"); text = text.replace(re,"""); re = new RegExp('<',"g"); text = text.replace(re,"<"); re = new RegExp('>',"g"); text = text.replace(re,">"); return text; } /** * Set the accesskey prefix based on browser detection. */ var tooltipAccessKeyPrefix = 'alt-'; if (is_opera) { tooltipAccessKeyPrefix = 'shift-esc-'; } else if (!is_safari_win && is_safari && webkit_version > 526) { tooltipAccessKeyPrefix = 'ctrl-alt-'; } else if (!is_safari_win && (is_safari || clientPC.indexOf('mac') != -1 || clientPC.indexOf('konqueror') != -1 )) { tooltipAccessKeyPrefix = 'ctrl-'; } else if (is_ff2) { tooltipAccessKeyPrefix = 'alt-shift-'; } var tooltipAccessKeyRegexp = /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/; /** * Add the appropriate prefix to the accesskey shown in the tooltip. * If the nodeList parameter is given, only those nodes are updated; * otherwise, all the nodes that will probably have accesskeys by * default are updated. * * @param Array nodeList -- list of elements to update */ function updateTooltipAccessKeys( nodeList ) { if ( !nodeList ) { // skins without a "column-one" element don't seem to have links with accesskeys either var columnOne = document.getElementById("column-one"); if ( columnOne ) updateTooltipAccessKeys( columnOne.getElementsByTagName("a") ); // these are rare enough that no such optimization is needed updateTooltipAccessKeys( document.getElementsByTagName("input") ); updateTooltipAccessKeys( document.getElementsByTagName("label") ); return; } for ( var i = 0; i < nodeList.length; i++ ) { var element = nodeList[i]; var tip = element.getAttribute("title"); if ( tip && tooltipAccessKeyRegexp.exec(tip) ) { tip = tip.replace(tooltipAccessKeyRegexp, "["+tooltipAccessKeyPrefix+"$5]"); element.setAttribute("title", tip ); } } } /** * Add a link to one of the portlet menus on the page, including: * * p-cactions: Content actions (shown as tabs above the main content in Monobook) * p-personal: Personal tools (shown at the top right of the page in Monobook) * p-navigation: Navigation * p-tb: Toolbox * * This function exists for the convenience of custom JS authors. All * but the first three parameters are optional, though providing at * least an id and a tooltip is recommended. * * By default the new link will be added to the end of the list. To * add the link before a given existing item, pass the DOM node of * that item (easily obtained with document.getElementById()) as the * nextnode parameter; to add the link _after_ an existing item, pass * the node's nextSibling instead. * * @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb") * @param String href -- link URL * @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook) * @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-") * @param String tooltip -- text to show when hovering over the link, without accesskey suffix * @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts) * @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list * * @return Node -- the DOM node of the new item (an LI element) or null */ function addPortletLink(portlet, href, text, id, tooltip, accesskey, nextnode) { var node = document.getElementById(portlet); if ( !node ) return null; node = node.getElementsByTagName( "ul" )[0]; if ( !node ) return null; var link = document.createElement( "a" ); link.appendChild( document.createTextNode( text ) ); link.href = href; var item = document.createElement( "li" ); item.appendChild( link ); if ( id ) item.id = id; if ( accesskey ) { link.setAttribute( "accesskey", accesskey ); tooltip += " ["+accesskey+"]"; } if ( tooltip ) { link.setAttribute( "title", tooltip ); } if ( accesskey && tooltip ) { updateTooltipAccessKeys( new Array( link ) ); } if ( nextnode && nextnode.parentNode == node ) node.insertBefore( item, nextnode ); else node.appendChild( item ); // IE compatibility (?) return item; } function getInnerText(el) { if (typeof el == "string") return el; if (typeof el == "undefined") { return el }; if (el.textContent) return el.textContent; // not needed but it is faster if (el.innerText) return el.innerText; // IE doesn't have textContent var str = ""; var cs = el.childNodes; var l = cs.length; for (var i = 0; i < l; i++) { switch (cs[i].nodeType) { case 1: //ELEMENT_NODE str += ts_getInnerText(cs[i]); break; case 3: //TEXT_NODE str += cs[i].nodeValue; break; } } return str; } /** * Set up accesskeys/tooltips from the deprecated ta array. If doId * is specified, only set up for that id. Note that this function is * deprecated and will not be supported indefinitely -- use * updateTooltipAccessKey() instead. * * @param mixed doId string or null */ function akeytt( doId ) { // A lot of user scripts (and some of the code below) break if // ta isn't defined, so we make sure it is. Explictly using // window.ta avoids a "ta is not defined" error. if (!window.ta) window.ta = new Array; // Make a local, possibly restricted, copy to avoid clobbering // the original. var ta; if ( doId ) { ta = [doId]; } else { ta = window.ta; } // Now deal with evil deprecated ta var watchCheckboxExists = document.getElementById( 'wpWatchthis' ) ? true : false; for (var id in ta) { var n = document.getElementById(id); if (n) { var a = null; var ak = ''; // Are we putting accesskey in it if (ta[id][0].length > 0) { // Is this object a object? If not assume it's the next child. if (n.nodeName.toLowerCase() == "a") { a = n; } else { a = n.childNodes[0]; } // Don't add an accesskey for the watch tab if the watch // checkbox is also available. if (a && ((id != 'ca-watch' && id != 'ca-unwatch') || !watchCheckboxExists)) { a.accessKey = ta[id][0]; ak = ' ['+tooltipAccessKeyPrefix+ta[id][0]+']'; } } else { // We don't care what type the object is when assigning tooltip a = n; ak = ''; } if (a) { a.title = ta[id][1]+ak; } } } } var checkboxes; var lastCheckbox; function setupCheckboxShiftClick() { checkboxes = []; lastCheckbox = null; var inputs = document.getElementsByTagName('input'); addCheckboxClickHandlers(inputs); } function addCheckboxClickHandlers(inputs, start) { if ( !start) start = 0; var finish = start + 250; if ( finish > inputs.length ) finish = inputs.length; for ( var i = start; i < finish; i++ ) { var cb = inputs[i]; if ( !cb.type || cb.type.toLowerCase() != 'checkbox' ) continue; var end = checkboxes.length; checkboxes[end] = cb; cb.index = end; cb.onclick = checkboxClickHandler; } if ( finish < inputs.length ) { setTimeout( function () { addCheckboxClickHandlers(inputs, finish); }, 200 ); } } function checkboxClickHandler(e) { if (typeof e == 'undefined') { e = window.event; } if ( !e.shiftKey || lastCheckbox === null ) { lastCheckbox = this.index; return true; } var endState = this.checked; var start, finish; if ( this.index < lastCheckbox ) { start = this.index + 1; finish = lastCheckbox; } else { start = lastCheckbox; finish = this.index - 1; } for (var i = start; i <= finish; ++i ) { checkboxes[i].checked = endState; } lastCheckbox = this.index; return true; } function toggle_element_activation(ida,idb) { if (!document.getElementById) { return; } document.getElementById(ida).disabled=true; document.getElementById(idb).disabled=false; } function toggle_element_check(ida,idb) { if (!document.getElementById) { return; } document.getElementById(ida).checked=true; document.getElementById(idb).checked=false; } /* Written by Jonathan Snook, http://www.snook.ca/jonathan Add-ons by Robert Nyman, http://www.robertnyman.com Author says "The credit comment is all it takes, no license. Go crazy with it!:-)" From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ */ function getElementsByClassName(oElm, strTagName, oClassNames){ var arrReturnElements = new Array(); if ( typeof( oElm.getElementsByClassName ) == "function" ) { /* Use a native implementation where possible FF3, Saf3.2, Opera 9.5 */ var arrNativeReturn = oElm.getElementsByClassName( oClassNames ); if ( strTagName == "*" ) return arrNativeReturn; for ( var h=0; h < arrNativeReturn.length; h++ ) { if( arrNativeReturn[h].tagName.toLowerCase() == strTagName.toLowerCase() ) arrReturnElements[arrReturnElements.length] = arrNativeReturn[h]; } return arrReturnElements; } var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName); var arrRegExpClassNames = new Array(); if(typeof oClassNames == "object"){ for(var i=0; i 0) { if (table.tHead && table.tHead.rows.length > 0) { firstRow = table.tHead.rows[table.tHead.rows.length-1]; } else { firstRow = table.rows[0]; } } if (!firstRow) return; // We have a first row: assume it's the header, and make its contents clickable links for (var i = 0; i < firstRow.cells.length; i++) { var cell = firstRow.cells[i]; if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) { cell.innerHTML += '  ' + '' + '' + '↓'; } } if (ts_alternate_row_colors) { ts_alternate(table); } } function ts_getInnerText(el) { return getInnerText( el ); } function ts_resortTable(lnk) { // get the span var span = lnk.getElementsByTagName('span')[0]; var td = lnk.parentNode; var tr = td.parentNode; var column = td.cellIndex; var table = tr.parentNode; while (table && !(table.tagName && table.tagName.toLowerCase() == 'table')) table = table.parentNode; if (!table) return; if (table.rows.length <= 1) return; // Generate the number transform table if it's not done already if (ts_number_transform_table == null) { ts_initTransformTable(); } // Work out a type for the column // Skip the first row if that's where the headings are var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1); var itm = ""; for (var i = rowStart; i < table.rows.length; i++) { if (table.rows[i].cells.length > column) { itm = ts_getInnerText(table.rows[i].cells[column]); itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, ""); if (itm != "") break; } } // TODO: bug 8226, localised date formats var sortfn = ts_sort_generic; var preprocessor = ts_toLowerCase; if (/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/.test(itm)) { preprocessor = ts_dateToSortKey; } else if (/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/.test(itm)) { preprocessor = ts_dateToSortKey; } else if (/^\d\d[\/.-]\d\d[\/.-]\d\d$/.test(itm)) { preprocessor = ts_dateToSortKey; // pound dollar euro yen currency cents } else if (/(^[\u00a3$\u20ac\u00a4\u00a5]|\u00a2$)/.test(itm)) { preprocessor = ts_currencyToSortKey; } else if (ts_number_regex.test(itm)) { preprocessor = ts_parseFloat; } var reverse = (span.getAttribute("sortdir") == 'down'); var newRows = new Array(); var staticRows = new Array(); for (var j = rowStart; j < table.rows.length; j++) { var row = table.rows[j]; if((" "+row.className+" ").indexOf(" unsortable ") < 0) { var keyText = ts_getInnerText(row.cells[column]); var oldIndex = (reverse ? -j : j); var preprocessed = preprocessor( keyText ); newRows[newRows.length] = new Array(row, preprocessed, oldIndex); } else staticRows[staticRows.length] = new Array(row, false, j-rowStart); } newRows.sort(sortfn); var arrowHTML; if (reverse) { arrowHTML = '↓'; newRows.reverse(); span.setAttribute('sortdir','up'); } else { arrowHTML = '↑'; span.setAttribute('sortdir','down'); } for (var i = 0; i < staticRows.length; i++) { var row = staticRows[i]; newRows.splice(row[2], 0, row); } // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones // don't do sortbottom rows for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1) table.tBodies[0].appendChild(newRows[i][0]); } // do sortbottom rows only for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1) table.tBodies[0].appendChild(newRows[i][0]); } // Delete any other arrows there may be showing var spans = getElementsByClassName(tr, "span", "sortarrow"); for (var i = 0; i < spans.length; i++) { spans[i].innerHTML = '↓'; } span.innerHTML = arrowHTML; if (ts_alternate_row_colors) { ts_alternate(table); } } function ts_initTransformTable() { if ( typeof wgSeparatorTransformTable == "undefined" || ( wgSeparatorTransformTable[0] == '' && wgDigitTransformTable[2] == '' ) ) { digitClass = "[0-9,.]"; ts_number_transform_table = false; } else { ts_number_transform_table = {}; // Unpack the transform table // Separators ascii = wgSeparatorTransformTable[0].split("\t"); localised = wgSeparatorTransformTable[1].split("\t"); for ( var i = 0; i < ascii.length; i++ ) { ts_number_transform_table[localised[i]] = ascii[i]; } // Digits ascii = wgDigitTransformTable[0].split("\t"); localised = wgDigitTransformTable[1].split("\t"); for ( var i = 0; i < ascii.length; i++ ) { ts_number_transform_table[localised[i]] = ascii[i]; } // Construct regex for number identification digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '\\.']; maxDigitLength = 1; for ( var digit in ts_number_transform_table ) { // Escape regex metacharacters digits.push( digit.replace( /[\\\\$\*\+\?\.\(\)\|\{\}\[\]\-]/, function( s ) { return '\\' + s; } ) ); if (digit.length > maxDigitLength) { maxDigitLength = digit.length; } } if ( maxDigitLength > 1 ) { digitClass = '[' + digits.join( '', digits ) + ']'; } else { digitClass = '(' + digits.join( '|', digits ) + ')'; } } // We allow a trailing percent sign, which we just strip. This works fine // if percents and regular numbers aren't being mixed. ts_number_regex = new RegExp( "^(" + "[+-]?[0-9][0-9,]*(\\.[0-9,]*)?(E[+-]?[0-9][0-9,]*)?" + // Fortran-style scientific "|" + "[+-]?" + digitClass + "+%?" + // Generic localised ")$", "i" ); } function ts_toLowerCase( s ) { return s.toLowerCase(); } function ts_dateToSortKey(date) { // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX if (date.length == 11) { switch (date.substr(3,3).toLowerCase()) { case "jan": var month = "01"; break; case "feb": var month = "02"; break; case "mar": var month = "03"; break; case "apr": var month = "04"; break; case "may": var month = "05"; break; case "jun": var month = "06"; break; case "jul": var month = "07"; break; case "aug": var month = "08"; break; case "sep": var month = "09"; break; case "oct": var month = "10"; break; case "nov": var month = "11"; break; case "dec": var month = "12"; break; // default: var month = "00"; } return date.substr(7,4)+month+date.substr(0,2); } else if (date.length == 10) { if (ts_europeandate == false) { return date.substr(6,4)+date.substr(0,2)+date.substr(3,2); } else { return date.substr(6,4)+date.substr(3,2)+date.substr(0,2); } } else if (date.length == 8) { yr = date.substr(6,2); if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; } if (ts_europeandate == true) { return yr+date.substr(3,2)+date.substr(0,2); } else { return yr+date.substr(0,2)+date.substr(3,2); } } return "00000000"; } function ts_parseFloat( s ) { if ( !s ) { return 0; } if (ts_number_transform_table != false) { var newNum = '', c; for ( var p = 0; p < s.length; p++ ) { c = s.charAt( p ); if (c in ts_number_transform_table) { newNum += ts_number_transform_table[c]; } else { newNum += c; } } s = newNum; } num = parseFloat(s.replace(/,/g, "")); return (isNaN(num) ? 0 : num); } function ts_currencyToSortKey( s ) { return ts_parseFloat(s.replace(/[^0-9.,]/g,'')); } function ts_sort_generic(a, b) { return a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]; } function ts_alternate(table) { // Take object table and get all it's tbodies. var tableBodies = table.getElementsByTagName("tbody"); // Loop through these tbodies for (var i = 0; i < tableBodies.length; i++) { // Take the tbody, and get all it's rows var tableRows = tableBodies[i].getElementsByTagName("tr"); // Loop through these rows // Start at 1 because we want to leave the heading row untouched for (var j = 0; j < tableRows.length; j++) { // Check if j is even, and apply classes for both possible results var oldClasses = tableRows[j].className.split(" "); var newClassName = ""; for (var k = 0; k < oldClasses.length; k++) { if (oldClasses[k] != "" && oldClasses[k] != "even" && oldClasses[k] != "odd") newClassName += oldClasses[k] + " "; } tableRows[j].className = newClassName + (j % 2 == 0 ? "even" : "odd"); } } } /* * End of table sorting code */ /** * Add a cute little box at the top of the screen to inform the user of * something, replacing any preexisting message. * * @param String -or- Dom Object message HTML to be put inside the right div * @param String className Used in adding a class; should be different for each * call to allow CSS/JS to hide different boxes. null = no class used. * @return Boolean True on success, false on failure */ function jsMsg( message, className ) { if ( !document.getElementById ) { return false; } // We special-case skin structures provided by the software. Skins that // choose to abandon or significantly modify our formatting can just define // an mw-js-message div to start with. var messageDiv = document.getElementById( 'mw-js-message' ); if ( !messageDiv ) { messageDiv = document.createElement( 'div' ); if ( document.getElementById( 'column-content' ) && document.getElementById( 'content' ) ) { // MonoBook, presumably document.getElementById( 'content' ).insertBefore( messageDiv, document.getElementById( 'content' ).firstChild ); } else if ( document.getElementById('content') && document.getElementById( 'article' ) ) { // Non-Monobook but still recognizable (old-style) document.getElementById( 'article').insertBefore( messageDiv, document.getElementById( 'article' ).firstChild ); } else { return false; } } messageDiv.setAttribute( 'id', 'mw-js-message' ); messageDiv.style.display = 'block'; if( className ) { messageDiv.setAttribute( 'class', 'mw-js-message-'+className ); } if (typeof message === 'object') { while (messageDiv.hasChildNodes()) // Remove old content messageDiv.removeChild(messageDiv.firstChild); messageDiv.appendChild (message); // Append new content } else { messageDiv.innerHTML = message; } return true; } /** * Inject a cute little progress spinner after the specified element * * @param element Element to inject after * @param id Identifier string (for use with removeSpinner(), below) */ function injectSpinner( element, id ) { var spinner = document.createElement( "img" ); spinner.id = "mw-spinner-" + id; spinner.src = stylepath + "/common/images/spinner.gif"; spinner.alt = spinner.title = "..."; if( element.nextSibling ) { element.parentNode.insertBefore( spinner, element.nextSibling ); } else { element.parentNode.appendChild( spinner ); } } /** * Remove a progress spinner added with injectSpinner() * * @param id Identifier string */ function removeSpinner( id ) { var spinner = document.getElementById( "mw-spinner-" + id ); if( spinner ) { spinner.parentNode.removeChild( spinner ); } } function runOnloadHook() { // don't run anything below this for non-dom browsers //alert('runOnloadHook has run!'); if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) { return; } // set this before running any hooks, since any errors below // might cause the function to terminate prematurely doneOnloadHook = true; updateTooltipAccessKeys( null ); akeytt( null ); setupCheckboxShiftClick(); sortables_init(); // Run any added-on functions for (var i = 0; i < onloadFuncts.length; i++) { onloadFuncts[i](); } } /** * Add an event handler to an element * * @param Element element Element to add handler to * @param String attach Event to attach to * @param callable handler Event handler callback */ function addHandler( element, attach, handler ) { if( window.addEventListener ) { element.addEventListener( attach, handler, false ); } else if( window.attachEvent ) { element.attachEvent( 'on' + attach, handler ); } } /** * Add a click event handler to an element * * @param Element element Element to add handler to * @param callable handler Event handler callback */ function addClickHandler( element, handler ) { addHandler( element, 'click', handler ); } /** * Removes an event handler from an element * * @param Element element Element to remove handler from * @param String remove Event to remove * @param callable handler Event handler callback to remove */ function removeHandler( element, remove, handler ) { if( window.removeEventListener ) { element.removeEventListener( remove, handler, false ); } else if( window.detachEvent ) { element.detachEvent( 'on' + remove, handler ); } } //note: all skins should call runOnloadHook() at the end of html output, // so the below should be redundant. It's there just in case. hookEvent("load", runOnloadHook); /**************find the tabs for tabbed unit under the characterfetcher on the Universe Front Page and apply toggling***********/ function fetch_uni_tab(evt) { filearray = new Object(); tabarray = new Object(); tabarray['heroes'] = "tab_heroes"; tabarray['villains'] = "tab_villains"; tabarray['teams'] = "tab_teams"; tabarray['places'] = "tab_places"; tabarray['events'] = "tab_events"; contentarray = new Object(); contentarray['heroes'] = "tab_heroes-content"; contentarray['villains'] = "tab_villains-content"; contentarray['teams'] = "tab_teams-content"; contentarray['places'] = "tab_places-content"; contentarray['events'] = "tab_events-content"; /*document.getElementById('main_issue_tab_content').innerHTML = '



'+'\n'; url = filearray[tabname]; makeRequest(url,'main_issue_tab_content');*/ var evt = (evt) ? evt : ((window.event) ? event : null); var objectID = (evt.target) ? evt.target.id : ((evt.srcElement) ? evt.srcElement.id : null); /*alert("you clicked on the " + objectID + " div");*/ /* this sets the ID of the content box to be "objectID-content", so if the div that is clicked has a div id of "char-powers", the div to toggle will be "char-powers-content" */ var linkID = objectID + "-content"; for (i in tabarray) { document.getElementById(tabarray[i]).className = 'tab'; } document.getElementById(objectID).className = 'tab_on'; for (i in contentarray) { document.getElementById(contentarray[i]).style.display = 'none'; } document.getElementById(linkID).style.display = 'block'; } function tabLinks(classID) { document.getElementsByClassName = function(cl) { var retnode = []; var myclass = new RegExp('\\b'+cl+'\\b'); var elem = this.getElementsByTagName('*'); for (var i = 0; i < elem.length; i++) { var classes = elem[i].className; if (myclass.test(classes)) retnode.push(elem[i]); } return retnode; } linkClass = document.getElementsByClassName(classID); for( var i = 0; i < linkClass.length; i++ ) { if( linkClass[i].className == classID ) /*alert("there are divs with the class name " + classID + " on this page!");*/ linkClass[i].onclick = fetch_uni_tab; } } var currentGrp = 0; function tabScroll(evt) { var evt = (evt) ? evt : ((window.event) ? event : null); var objectID = (evt.target) ? evt.target.id : ((evt.srcElement) ? evt.srcElement.id : null); var parnt = document.getElementById(objectID).parentNode.id; var arwName = document.getElementById(this.id).className; /**this function has been modified to accomodate only 2 groups (8 images/links) per tab**/ /**when increasing the number of groups, the stuff that has been commented-out will need to be reinstated**/ grpArray = new Object(); grpArray[0] = parnt + "-grp1"; grpArray[1] = parnt + "-grp2"; /*grpArray[2] = parnt + "-grp3";*/ hide(grpArray[currentGrp]); if (arwName == 'tab_arw_left') { currentGrp = (currentGrp == 0) ? 1 : currentGrp-1; /*currentGrp = (currentGrp == 0) ? 2 : currentGrp-1;*/ } if (arwName == 'tab_arw_right') { currentGrp = (currentGrp == 1) ? 0 : currentGrp+1; /*currentGrp = (currentGrp == 2) ? 0 : currentGrp+1;*/ } unhide(grpArray[currentGrp]); } function arwBtns(classID) { document.getElementsByClassName = function(cl) { var retnode = []; var myclass = new RegExp('\\b'+cl+'\\b'); var elem = this.getElementsByTagName('*'); for (var i = 0; i < elem.length; i++) { var classes = elem[i].className; if (myclass.test(classes)) retnode.push(elem[i]); } return retnode; } linkClass = document.getElementsByClassName(classID); for( var i = 0; i < linkClass.length; i++ ) { if( linkClass[i].className == classID ) /*alert("there are divs with the class name " + classID + " on this page!");*/ linkClass[i].onclick = tabScroll; } } /****************end tabs stuff*******************************/ function hide_panel() { document.getElementById('editpanel').style.display = 'none'; } function show_panel() { document.getElementById('editpanel').style.display = 'block'; } function showEditTools() { //alert('yeap'); str = document.editform.wpTextbox1.value; var outputstuff = 'Creating a new article:
Please click on the appropriate template below to get started:'; if (str.length == 0) { document.getElementById('templatetools').innerHTML = outputstuff; } } function fetchTemplate(type) { switch(type) { case 'person': var output = "{{Powerbox|\nuniverse =\n| blurb =\n| real_name = \n| aliases = \n| identity = \n| occupation = \n| citizenship = \n| place_of_birth = \n| relatives = \n| groups = \n| education = \n| height = \n| weight = \n| eyes = \n| hair =\n| powers = \n| abilities = \n| weapons = \n| paraphernalia = \n| debut =\n| origin = \n| significant_issues = \n}}{{Headshot|\nmain_image= image_not_available.gif\n}}{{bio|\nbio_text= \n}}\n{{person}}"; break; case 'team': var output = "{{teambox|\nuniverse = Marvel Universe\n| blurb =\n| base_of_operations = \n| debut =\n| significant_issues = \n| current_members = \n| former_members = \n| other_members =\n}}\n{{headshot|\nmain_image=image_not_available.gif\n}}\n{{teamhistory|\nbio_text = \n}}\n{{team}}"; break; case 'place': var output = "{{Placebox|\nuniverse =\n| location = \n| builder = \n| owner = \n| points_of_interest = \n| features = \n| debut =\n| significant_issues = \n}}{{Headshot|\nmain_image=image_not_available.gif\n}}{{placehistory|\nplace_text=\n}}\n{{place}}"; break; case 'object': var output = "{{Objectbox|\nuniverse =\n| location =\n| creator =\n| owner =\n| features = \n| powers =\n| debut =\n| significant_issues = \n}}{{Headshot|\nmain_image = image_not_available.gif\n}}{{objecthistory|\nobject_text=\n}}\n{{object}}"; break; case 'species': var output = "{{speciesbox|\nuniverse =\n| home_world = \n| appearance =\n| distinguishing_features =\n| technology = \n| government = \n| debut =\n| significant_issues = \n| significant_citizens = \n}}{{headshot|\nmain_image=image_not_available.gif\n}}\n{{sp_history|\nspecieshistory = \n}}\n{{species}}"; break; case 'event': var output = "{{eventshot|main_image=}}\n{{eventsbox|\nuniverse =\n| key_characters =\n| key_issues =\n| tie-ins =\n}}\n{{eventhistory|event_text=\n}}\n{{event}}"; break; case 'disambig': var output = "{{ disambig }}\n\n Place your text here"; break; case 'topic': var output = "Place your text here.\n\n\n {{ topic }}"; break; } document.getElementById('wpTextbox1').value = output; } function mrvl_randis() { var mrvl_randNum = Math.floor(Math.random()*9); document.getElementById(mrvl_dispArray[mrvl_randNum]).style.display = ''; } function mrvl_dis(ele) { for (var abc=0; abc < mrvl_dispArray.length; abc++) { document.getElementById(mrvl_dispArray[abc]).style.display = 'none'; } document.getElementById(ele).style.display = ''; } /* Unobtrusive Flash Objects (UFO) v3.12 Copyright 2005, 2006 Bobby van der Sluis This software is licensed under the CC-GNU LGPL */ var UFO = { requiredAttrParams: ["movie", "width", "height", "majorversion", "build"], optionalAttrEmb: ["name", "swliveconnect", "align"], optionalAttrObj: ["id", "align"], optionalAttrParams: ["play", "loop", "menu", "quality", "scale", "salign", "wmode", "bgcolor", "base", "flashvars", "devicefont", "allowscriptaccess", "seamlesstabbing"], ximovie: "ufo.swf", xiwidth: "215", xiheight: "138", is_w3cdom: (typeof document.getElementById != "undefined" && typeof document.getElementsByTagName != "undefined" && (typeof document.createElement != "undefined" || typeof document.createElementNS != "undefined")), is_ie: (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1), is_safari: (navigator.userAgent.toLowerCase().indexOf("safari") != -1), is_win: (navigator.userAgent.toLowerCase().indexOf("win") != -1), is_mac: (navigator.userAgent.toLowerCase().indexOf("mac") != -1), is_XML: (typeof document.contentType != "undefined" && document.contentType.indexOf("xml") > -1), foList: [], create: function(FO, id) { if (!UFO.is_w3cdom) return; UFO.foList[id] = UFO.updateFO(FO); UFO.createStyleRule("#" + id, "visibility:hidden;"); UFO.domLoad(id); }, updateFO: function(FO) { if (typeof FO.xi != "undefined" && FO.xi == "true") { if (typeof FO.ximovie == "undefined") FO.ximovie = UFO.ximovie; if (typeof FO.xiwidth == "undefined") FO.xiwidth = UFO.xiwidth; if (typeof FO.xiheight == "undefined") FO.xiheight = UFO.xiheight; } else { FO.xi = false; } FO.domLoaded = false; return FO; }, domLoad: function(id) { var timer = setInterval(function() { // doesn't work in IE/Mac if((document.getElementsByTagName("body")[0] != null || document.body != null) && document.getElementById(id) != null) { UFO.main(id); clearInterval(timer); } }, 250); if (typeof document.addEventListener != "undefined") { document.addEventListener("DOMContentLoaded", function() { UFO.main(id); clearInterval(timer); } , null); // Mozilla only } }, main: function(id) { var FO = UFO.foList[id]; if (FO.domLoaded) return; // for Mozilla, only execute once UFO.foList[id].domLoaded = true; document.getElementById(id).style.visibility = "hidden"; if (UFO.hasRequiredAttrParams(id)) { if (UFO.hasFlashVersion(FO.majorversion, FO.build)) { if (typeof FO.setcontainercss != "undefined" && FO.setcontainercss == "true") { UFO.setContainerCSS(id); } UFO.writeFlashObject(id); } else if (FO.xi && UFO.hasFlashVersion("6", "65")) { UFO.createModalDialog(id); } } document.getElementById(id).style.visibility = "visible"; }, createStyleRule: function(selector, declaration) { if (UFO.is_ie && UFO.is_mac) return; // bugs in IE/Mac var head = document.getElementsByTagName("head")[0]; var style = UFO.createElement("style"); if (!(UFO.is_ie && UFO.is_win)) { var styleRule = document.createTextNode(selector + " {" + declaration + "}"); style.appendChild(styleRule); // bugs in IE/Win } style.setAttribute("type", "text/css"); style.setAttribute("media", "screen"); head.appendChild(style); if (UFO.is_safari && UFO.is_XML) { head.innerHTML += ""; } // force Safari repaint for MIME type application/xhtml+xml if (UFO.is_ie && UFO.is_win && document.styleSheets && document.styleSheets.length > 0) { var lastStyle = document.styleSheets[document.styleSheets.length - 1]; if (typeof lastStyle.addRule == "object") { lastStyle.addRule(selector, declaration); } } }, setContainerCSS: function(id) { var FO = UFO.foList[id]; var wUnit = (FO.width.indexOf("%") == -1) ? "px" : ""; var hUnit = (FO.height.indexOf("%") == -1) ? "px" : ""; UFO.createStyleRule("#" + id, "width:" + FO.width + wUnit +"; height:" + FO.height + hUnit +";"); if (FO.width == "100%") { UFO.createStyleRule("body", "margin-left:0; margin-right:0; padding-left:0; padding-right:0;"); } if (FO.height == "100%") { UFO.createStyleRule("html", "height:100%; overflow:hidden;"); UFO.createStyleRule("body", "margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0; height:100%;"); } }, createElement: function(el) { return (typeof document.createElementNS != "undefined") ? document.createElementNS("http://www.w3.org/1999/xhtml", el) : document.createElement(el); }, hasRequiredAttrParams: function(id) { var FO = UFO.foList[id]; for (var i = 0; i < UFO.requiredAttrParams.length; i++) { if (typeof FO[UFO.requiredAttrParams[i]] == "undefined") return false; } return true; }, hasFlashVersion: function(majorVersion, buildVersion) { var reqVersion = parseFloat(majorVersion + "." + buildVersion); if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") { var desc = navigator.plugins["Shockwave Flash"].description; if (desc) { var versionStr = desc.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); var major = parseInt(versionStr.replace(/^(.*)\..*$/, "$1")); var build = (versionStr.indexOf("r") == -1) ? 0 : parseInt(versionStr.replace(/^.*r(.*)$/, "$1")); var flashVersion = parseFloat(major + "." + build); } } else if (window.ActiveXObject) { try { var flashObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); var desc = flashObj.GetVariable("$version"); if (desc) { var versionArr = desc.replace(/^\S+\s+(.*)$/, "$1").split(","); var major = parseInt(versionArr[0]); var build = parseInt(versionArr[2]); var flashVersion = parseFloat(major + "." + build); } } catch(e) {} } if (typeof flashVersion != "undefined"){ return (flashVersion >= reqVersion ? true : false); } return false; }, writeFlashObject: function(id) { var el = document.getElementById(id); if (typeof el.innerHTML == "undefined") return; var FO = UFO.foList[id]; if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") { try { // older versions of Gecko only support innerHTML get and not set el.innerHTML = "ufo-test"; } catch (e) {} if (el.innerHTML != "ufo-test") { while(el.hasChildNodes()) { el.removeChild(el.firstChild); } var embed = UFO.createElement("embed"); embed.setAttribute("type", "application/x-shockwave-flash"); embed.setAttribute("pluginspage", "http://www.macromedia.com/go/getflashplayer"); embed.setAttribute("src", FO.movie); embed.setAttribute("width", FO.width); embed.setAttribute("height", FO.height); for (var i = 0; i < UFO.optionalAttrEmb.length; i++) { if (typeof FO[UFO.optionalAttrEmb[i]] != "undefined") { embed.setAttribute(UFO.optionalAttrEmb[i], FO[UFO.optionalAttrEmb[i]]); } } for (var i = 0; i < UFO.optionalAttrParams.length; i++) { if (typeof FO[UFO.optionalAttrParams[i]] != "undefined") { embed.setAttribute(UFO.optionalAttrParams[i], FO[UFO.optionalAttrParams[i]]); } } el.appendChild(embed); } else { var embHTML = ""; for (var i = 0; i < UFO.optionalAttrEmb.length; i++) { if (typeof FO[UFO.optionalAttrEmb[i]] != "undefined") { embHTML += ' ' + UFO.optionalAttrEmb[i] + '="' + FO[UFO.optionalAttrEmb[i]] + '"'; } } for (var i = 0; i < UFO.optionalAttrParams.length; i++) { if (typeof FO[UFO.optionalAttrParams[i]] != "undefined") { embHTML += ' ' + UFO.optionalAttrParams[i] + '="' + FO[UFO.optionalAttrParams[i]] + '"'; } } el.innerHTML = ''; } } else { var objAttrHTML = ""; for (var i = 0; i < UFO.optionalAttrObj.length; i++) { if (typeof FO[UFO.optionalAttrObj[i]] != "undefined") { objAttrHTML += ' ' + UFO.optionalAttrObj[i] + '="' + FO[UFO.optionalAttrObj[i]] + '"'; } } var objParamHTML = ""; for (var i = 0; i < UFO.optionalAttrParams.length; i++) { if (typeof FO[UFO.optionalAttrParams[i]] != "undefined") { objParamHTML += ''; } } var protocol = (window.location.protocol == "https:" ? "https:" : "http:"); el.innerHTML = '' + objParamHTML + ''; } }, cleanupIELeaks: function() { var objects = document.getElementsByTagName("OBJECT"); for (var i = 0; i < objects.length; i++) { for (var x in objects[i]) { if (typeof objects[i][x] == "function") { objects[i][x] = null; } } } }, createModalDialog: function(id) { var FO = UFO.foList[id]; UFO.createStyleRule("html", "height:100%; overflow:hidden;"); UFO.createStyleRule("body", "height:100%; overflow:hidden;"); UFO.createStyleRule("#xi-con", "position:absolute; left:0; top:0; z-index:1000; width:100%; height:100%; background-color:#333; filter:alpha(opacity:50); -khtml-opacity:0.5; -moz-opacity:0.5; opacity:0.5;"); UFO.createStyleRule("#xi-mod", "position:absolute; left:50%; top:50%; margin-left: -" + (parseInt(FO.xiwidth)/2) + "px; margin-top: -" + (parseInt(FO.xiheight)/2) + "px; width:" + FO.xiwidth + "px; height:" + FO.xiheight + "px;"); var body = document.getElementsByTagName("body")[0]; var container = UFO.createElement("div"); container.setAttribute("id", "xi-con"); var dialog = UFO.createElement("div"); dialog.setAttribute("id", "xi-mod"); container.appendChild(dialog); body.appendChild(container); var MMredirectURL = window.location; document.title = document.title.slice(0, 47) + " - Flash Player Installation"; var MMdoctitle = document.title; var MMplayerType = (UFO.is_ie && UFO.is_win) ? "ActiveX" : "PlugIn"; var xiUrlCancel = (typeof FO.xiurlcancel != "undefined") ? "&xiUrlCancel=" + FO.xiurlcancel : ""; var xiUrlFailed = (typeof FO.xiurlfailed != "undefined") ? "&xiUrlFailed=" + FO.xiurlfailed : ""; UFO.foList["xi-mod"] = { movie:FO.ximovie, width:FO.xiwidth, height:FO.xiheight, majorversion:"6", build:"65", flashvars:"MMredirectURL=" + MMredirectURL + "&MMplayerType=" + MMplayerType + "&MMdoctitle=" + MMdoctitle + xiUrlCancel + xiUrlFailed }; UFO.writeFlashObject("xi-mod"); }, expressInstallCallback: function() { var body = document.getElementsByTagName("body")[0]; var dialog = document.getElementById("xi-con"); body.removeChild(dialog); UFO.createStyleRule("body", "height:auto; overflow:auto;"); UFO.createStyleRule("html", "height:auto; overflow:auto;"); } }; if (typeof window.attachEvent != "undefined" && UFO.is_ie && UFO.is_win) { window.attachEvent("onunload", UFO.cleanupIELeaks); } function mu_addsearch(){ var xml_url = 'http://marvel.michele.crossbow/universe3zx/opensearch_desc.php'; var img_url = 'http://marvel.com/search/ie_marveluniverse.gif'; var name = 'OpenSearch'; if (typeof window.sidebar.addSearchEngine != 'undefined') window.sidebar.addSearchEngine(xml_url, img_url, name, 'General'); else if (typeof window.external.AddSearchProvider != 'undefined') window.external.AddSearchProvider(xml_url); } /* this function finds the ID of the individual div and toggles the associated content div when it is clicked */ function pBoxLink(evt) { /*this gets the ID of the div that is clicked*/ var evt = (evt) ? evt : ((window.event) ? event : null); var objectID = (evt.target) ? evt.target.id : ((evt.srcElement) ? evt.srcElement.id : null); /* this sets the ID of the content box to be "objectID-content", so if the div that is clicked has a div id of "char-powers", the div to toggle will be "char-powers-content" */ var linkID = objectID + "-content"; /* this determines the current display style of the content div and toogles it on or off */ var object = document.getElementById(linkID); dispState = object.style.display; /*alert('objectID = ' + objectID + ' and linkID = ' + linkID + 'the display stat of the ' + linkID + ' div is ' + dispState);*/ if (dispState != 'none') object.style.display = 'none'; else object.style.display = 'block'; } /* this is going to be the function called onload in the body tag which should find all the divs with the class 'myLink' and apply the toggleLink function to each of those divs */ function findLinks(classID) { document.getElementsByClassName = function(cl) { var retnode = []; var myclass = new RegExp('\\b'+cl+'\\b'); var elem = this.getElementsByTagName('*'); for (var i = 0; i < elem.length; i++) { var classes = elem[i].className; if (myclass.test(classes)) retnode.push(elem[i]); } return retnode; } linkClass = document.getElementsByClassName(classID); for( var i = 0; i < linkClass.length; i++ ) { if( linkClass[i].className == classID ) /*alert("there are divs with the class name " + classID + " on this page!");*/ linkClass[i].onclick = pBoxLink; } }