0) {=0A=
if (table.tHead && table.tHead.rows.length > 0) {=0A=
firstRow =3D table.tHead.rows[table.tHead.rows.length-1];=0A=
} else {=0A=
firstRow =3D table.rows[0];=0A=
}=0A=
}=0A=
if (!firstRow) return;=0A=
=0A=
// We have a first row: assume it's the header, and make its contents =
clickable links=0A=
for (var i =3D 0; i < firstRow.cells.length; i++) {=0A=
var cell =3D firstRow.cells[i];=0A=
if ((" "+cell.className+" ").indexOf(" unsortable ") =3D=3D -1) {=0A=
cell.innerHTML +=3D ' ';=0A=
}=0A=
}=0A=
if (ts_alternate_row_colors) {=0A=
ts_alternate(table);=0A=
}=0A=
}=0A=
=0A=
function ts_getInnerText(el) {=0A=
if (typeof el =3D=3D "string") return el;=0A=
if (typeof el =3D=3D "undefined") { return el };=0A=
if (el.textContent) return el.textContent; // not needed but it is =
faster=0A=
if (el.innerText) return el.innerText; // IE doesn't have =
textContent=0A=
var str =3D "";=0A=
=0A=
var cs =3D el.childNodes;=0A=
var l =3D cs.length;=0A=
for (var i =3D 0; i < l; i++) {=0A=
switch (cs[i].nodeType) {=0A=
case 1: //ELEMENT_NODE=0A=
str +=3D ts_getInnerText(cs[i]);=0A=
break;=0A=
case 3: //TEXT_NODE=0A=
str +=3D cs[i].nodeValue;=0A=
break;=0A=
}=0A=
}=0A=
return str;=0A=
}=0A=
=0A=
function ts_resortTable(lnk) {=0A=
// get the span=0A=
var span =3D lnk.getElementsByTagName('span')[0];=0A=
=0A=
var td =3D lnk.parentNode;=0A=
var tr =3D td.parentNode;=0A=
var column =3D td.cellIndex;=0A=
=0A=
var table =3D tr.parentNode;=0A=
while (table && !(table.tagName && table.tagName.toLowerCase() =3D=3D =
'table'))=0A=
table =3D table.parentNode;=0A=
if (!table) return;=0A=
=0A=
// Work out a type for the column=0A=
if (table.rows.length <=3D 1) return;=0A=
=0A=
// Skip the first row if that's where the headings are=0A=
var rowStart =3D (table.tHead && table.tHead.rows.length > 0 ? 0 : 1);=0A=
=0A=
var itm =3D "";=0A=
for (var i =3D rowStart; i < table.rows.length; i++) {=0A=
if (table.rows[i].cells.length > column) {=0A=
itm =3D ts_getInnerText(table.rows[i].cells[column]);=0A=
itm =3D itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, "");=0A=
if (itm !=3D "") break;=0A=
}=0A=
}=0A=
=0A=
sortfn =3D ts_sort_caseinsensitive;=0A=
if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/))=0A=
sortfn =3D ts_sort_date;=0A=
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/))=0A=
sortfn =3D ts_sort_date;=0A=
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/))=0A=
sortfn =3D ts_sort_date;=0A=
if (itm.match(/^[\u00a3$\u20ac]/)) // pound dollar euro=0A=
sortfn =3D ts_sort_currency;=0A=
if (itm.match(/^[\d.,]+\%?$/))=0A=
sortfn =3D ts_sort_numeric;=0A=
=0A=
var reverse =3D (span.getAttribute("sortdir") =3D=3D 'down');=0A=
=0A=
var newRows =3D new Array();=0A=
for (var j =3D rowStart; j < table.rows.length; j++) {=0A=
var row =3D table.rows[j];=0A=
var keyText =3D ts_getInnerText(row.cells[column]);=0A=
var oldIndex =3D (reverse ? -j : j);=0A=
=0A=
newRows[newRows.length] =3D new Array(row, keyText, oldIndex);=0A=
}=0A=
=0A=
newRows.sort(sortfn);=0A=
=0A=
var arrowHTML;=0A=
if (reverse) {=0A=
arrowHTML =3D '';=0A=
newRows.reverse();=0A=
span.setAttribute('sortdir','up');=0A=
} else {=0A=
arrowHTML =3D '';=0A=
span.setAttribute('sortdir','down');=0A=
}=0A=
=0A=
// We appendChild rows that already exist to the tbody, so it moves =
them rather than creating new ones=0A=
// don't do sortbottom rows=0A=
for (var i =3D 0; i < newRows.length; i++) {=0A=
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") =3D=3D =
-1)=0A=
table.tBodies[0].appendChild(newRows[i][0]);=0A=
}=0A=
// do sortbottom rows only=0A=
for (var i =3D 0; i < newRows.length; i++) {=0A=
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") !=3D -1)=0A=
table.tBodies[0].appendChild(newRows[i][0]);=0A=
}=0A=
=0A=
// Delete any other arrows there may be showing=0A=
var spans =3D getElementsByClassName(tr, "span", "sortarrow");=0A=
for (var i =3D 0; i < spans.length; i++) {=0A=
spans[i].innerHTML =3D '';=0A=
}=0A=
span.innerHTML =3D arrowHTML;=0A=
=0A=
ts_alternate(table); =0A=
}=0A=
=0A=
function ts_dateToSortKey(date) { =0A=
// y2k notes: two digit years less than 50 are treated as 20XX, greater =
than 50 are treated as 19XX=0A=
if (date.length =3D=3D 11) {=0A=
switch (date.substr(3,3).toLowerCase()) {=0A=
case "jan": var month =3D "01"; break;=0A=
case "feb": var month =3D "02"; break;=0A=
case "mar": var month =3D "03"; break;=0A=
case "apr": var month =3D "04"; break;=0A=
case "may": var month =3D "05"; break;=0A=
case "jun": var month =3D "06"; break;=0A=
case "jul": var month =3D "07"; break;=0A=
case "aug": var month =3D "08"; break;=0A=
case "sep": var month =3D "09"; break;=0A=
case "oct": var month =3D "10"; break;=0A=
case "nov": var month =3D "11"; break;=0A=
case "dec": var month =3D "12"; break;=0A=
// default: var month =3D "00";=0A=
}=0A=
return date.substr(7,4)+month+date.substr(0,2);=0A=
} else if (date.length =3D=3D 10) {=0A=
if (ts_europeandate =3D=3D false) {=0A=
return date.substr(6,4)+date.substr(0,2)+date.substr(3,2);=0A=
} else {=0A=
return date.substr(6,4)+date.substr(3,2)+date.substr(0,2);=0A=
}=0A=
} else if (date.length =3D=3D 8) {=0A=
yr =3D date.substr(6,2);=0A=
if (parseInt(yr) < 50) { =0A=
yr =3D '20'+yr; =0A=
} else { =0A=
yr =3D '19'+yr; =0A=
}=0A=
if (ts_europeandate =3D=3D true) {=0A=
return yr+date.substr(3,2)+date.substr(0,2);=0A=
} else {=0A=
return yr+date.substr(0,2)+date.substr(3,2);=0A=
}=0A=
}=0A=
return "00000000";=0A=
}=0A=
=0A=
function ts_parseFloat(num) {=0A=
if (!num) return 0;=0A=
num =3D parseFloat(num.replace(/,/g, ""));=0A=
return (isNaN(num) ? 0 : num);=0A=
}=0A=
=0A=
function ts_sort_date(a,b) {=0A=
var aa =3D ts_dateToSortKey(a[1]);=0A=
var bb =3D ts_dateToSortKey(b[1]);=0A=
return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);=0A=
}=0A=
=0A=
function ts_sort_currency(a,b) {=0A=
var aa =3D ts_parseFloat(a[1].replace(/[^0-9.]/g,''));=0A=
var bb =3D ts_parseFloat(b[1].replace(/[^0-9.]/g,''));=0A=
return (aa !=3D bb ? aa - bb : a[2] - b[2]);=0A=
}=0A=
=0A=
function ts_sort_numeric(a,b) {=0A=
var aa =3D ts_parseFloat(a[1]);=0A=
var bb =3D ts_parseFloat(b[1]);=0A=
return (aa !=3D bb ? aa - bb : a[2] - b[2]);=0A=
}=0A=
=0A=
function ts_sort_caseinsensitive(a,b) {=0A=
var aa =3D a[1].toLowerCase();=0A=
var bb =3D b[1].toLowerCase();=0A=
return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);=0A=
}=0A=
=0A=
function ts_sort_default(a,b) {=0A=
return (a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]);=0A=
}=0A=
=0A=
function ts_alternate(table) {=0A=
// Take object table and get all it's tbodies.=0A=
var tableBodies =3D table.getElementsByTagName("tbody");=0A=
// Loop through these tbodies=0A=
for (var i =3D 0; i < tableBodies.length; i++) {=0A=
// Take the tbody, and get all it's rows=0A=
var tableRows =3D tableBodies[i].getElementsByTagName("tr");=0A=
// Loop through these rows=0A=
// Start at 1 because we want to leave the heading row untouched=0A=
for (var j =3D 0; j < tableRows.length; j++) {=0A=
// Check if j is even, and apply classes for both possible results=0A=
var oldClasses =3D tableRows[j].className.split(" ");=0A=
var newClassName =3D "";=0A=
for (var k =3D 0; k < oldClasses.length; k++) {=0A=
if (oldClasses[k] !=3D "" && oldClasses[k] !=3D "even" && =
oldClasses[k] !=3D "odd")=0A=
newClassName +=3D oldClasses[k] + " ";=0A=
}=0A=
tableRows[j].className =3D newClassName + (j % 2 =3D=3D 0 ? "even" : =
"odd");=0A=
}=0A=
}=0A=
}=0A=
=0A=
/*=0A=
* End of table sorting code=0A=
*/=0A=
=0A=
=0A=
/**=0A=
* Add a cute little box at the top of the screen to inform the user of=0A=
* something, replacing any preexisting message.=0A=
*=0A=
* @param String -or- Dom Object message HTML to be put inside the right =
div=0A=
* @param String className Used in adding a class; should be different =
for each=0A=
* call to allow CSS/JS to hide different boxes. null =3D no class =
used.=0A=
* @return Boolean True on success, false on failure=0A=
*/=0A=
function jsMsg( message, className ) {=0A=
if ( !document.getElementById ) {=0A=
return false;=0A=
}=0A=
// We special-case skin structures provided by the software. Skins that=0A=
// choose to abandon or significantly modify our formatting can just =
define=0A=
// an mw-js-message div to start with.=0A=
var messageDiv =3D document.getElementById( 'mw-js-message' );=0A=
if ( !messageDiv ) {=0A=
messageDiv =3D document.createElement( 'div' );=0A=
if ( document.getElementById( 'column-content' )=0A=
&& document.getElementById( 'content' ) ) {=0A=
// MonoBook, presumably=0A=
document.getElementById( 'content' ).insertBefore(=0A=
messageDiv,=0A=
document.getElementById( 'content' ).firstChild=0A=
);=0A=
} else if ( document.getElementById('content')=0A=
&& document.getElementById( 'article' ) ) {=0A=
// Non-Monobook but still recognizable (old-style)=0A=
document.getElementById( 'article').insertBefore(=0A=
messageDiv,=0A=
document.getElementById( 'article' ).firstChild=0A=
);=0A=
} else {=0A=
return false;=0A=
}=0A=
}=0A=
=0A=
messageDiv.setAttribute( 'id', 'mw-js-message' );=0A=
if( className ) {=0A=
messageDiv.setAttribute( 'class', 'mw-js-message-'+className );=0A=
}=0A=
=0A=
if (typeof message =3D=3D=3D 'object') {=0A=
while (messageDiv.hasChildNodes()) // Remove old content=0A=
messageDiv.removeChild(messageDiv.firstChild);=0A=
messageDiv.appendChild (message); // Append new content=0A=
}=0A=
else {=0A=
messageDiv.innerHTML =3D message;=0A=
}=0A=
return true;=0A=
}=0A=
=0A=
/**=0A=
* Inject a cute little progress spinner after the specified element=0A=
*=0A=
* @param element Element to inject after=0A=
* @param id Identifier string (for use with removeSpinner(), below)=0A=
*/=0A=
function injectSpinner( element, id ) {=0A=
var spinner =3D document.createElement( "img" );=0A=
spinner.id =3D "mw-spinner-" + id;=0A=
spinner.src =3D stylepath + "/common/images/spinner.gif";=0A=
spinner.alt =3D spinner.title =3D "...";=0A=
if( element.nextSibling ) {=0A=
element.parentNode.insertBefore( spinner, element.nextSibling );=0A=
} else {=0A=
element.parentNode.appendChild( spinner );=0A=
}=0A=
}=0A=
=0A=
/**=0A=
* Remove a progress spinner added with injectSpinner()=0A=
*=0A=
* @param id Identifier string=0A=
*/=0A=
function removeSpinner( id ) {=0A=
var spinner =3D document.getElementById( "mw-spinner-" + id );=0A=
if( spinner ) {=0A=
spinner.parentNode.removeChild( spinner );=0A=
}=0A=
}=0A=
=0A=
function runOnloadHook() {=0A=
// don't run anything below this for non-dom browsers=0A=
if (doneOnloadHook || !(document.getElementById && =
document.getElementsByTagName)) {=0A=
return;=0A=
}=0A=
=0A=
// set this before running any hooks, since any errors below=0A=
// might cause the function to terminate prematurely=0A=
doneOnloadHook =3D true;=0A=
=0A=
updateTooltipAccessKeys( null );=0A=
akeytt( null );=0A=
setupCheckboxShiftClick();=0A=
sortables_init();=0A=
=0A=
// Run any added-on functions=0A=
for (var i =3D 0; i < onloadFuncts.length; i++) {=0A=
onloadFuncts[i]();=0A=
}=0A=
}=0A=
=0A=
/**=0A=
* Add an event handler to an element=0A=
*=0A=
* @param Element element Element to add handler to=0A=
* @param String attach Event to attach to=0A=
* @param callable handler Event handler callback=0A=
*/=0A=
function addHandler( element, attach, handler ) {=0A=
if( window.addEventListener ) {=0A=
element.addEventListener( attach, handler, false );=0A=
} else if( window.attachEvent ) {=0A=
element.attachEvent( 'on' + attach, handler );=0A=
}=0A=
}=0A=
=0A=
/**=0A=
* Add a click event handler to an element=0A=
*=0A=
* @param Element element Element to add handler to=0A=
* @param callable handler Event handler callback=0A=
*/=0A=
function addClickHandler( element, handler ) {=0A=
addHandler( element, 'click', handler );=0A=
}=0A=
//note: all skins should call runOnloadHook() at the end of html output,=0A=
// so the below should be redundant. It's there just in case.=0A=
hookEvent("load", runOnloadHook);=0A=
------=_NextPart_000_0000_01C8CFF7.55B9C990
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://ja.wikipedia.org/skins-1.5/common/ajax.js?156
// remote scripting library=0A=
// (c) copyright 2005 modernmethod, inc=0A=
var sajax_debug_mode =3D false;=0A=
var sajax_request_type =3D "GET";=0A=
=0A=
/**=0A=
* if sajax_debug_mode is true, this function outputs given the message =
into =0A=
* the element with id =3D sajax_debug; if no such element exists in the =
document, =0A=
* it is injected.=0A=
*/=0A=
function sajax_debug(text) {=0A=
if (!sajax_debug_mode) return false;=0A=
=0A=
var e=3D document.getElementById('sajax_debug');=0A=
=0A=
if (!e) {=0A=
e=3D document.createElement("p");=0A=
e.className=3D 'sajax_debug';=0A=
e.id=3D 'sajax_debug';=0A=
=0A=
var b=3D document.getElementsByTagName("body")[0];=0A=
=0A=
if (b.firstChild) b.insertBefore(e, b.firstChild);=0A=
else b.appendChild(e);=0A=
}=0A=
=0A=
var m=3D document.createElement("div");=0A=
m.appendChild( document.createTextNode( text ) );=0A=
=0A=
e.appendChild( m );=0A=
=0A=
return true;=0A=
}=0A=
=0A=
/**=0A=
* compatibility wrapper for creating a new XMLHttpRequest object.=0A=
*/=0A=
function sajax_init_object() {=0A=
sajax_debug("sajax_init_object() called..")=0A=
var A;=0A=
try {=0A=
// Try the new style before ActiveX so we don't=0A=
// unnecessarily trigger warnings in IE 7 when=0A=
// set to prompt about ActiveX usage=0A=
A =3D new XMLHttpRequest();=0A=
} catch (e) {=0A=
try {=0A=
A=3Dnew ActiveXObject("Msxml2.XMLHTTP");=0A=
} catch (e) {=0A=
try {=0A=
A=3Dnew ActiveXObject("Microsoft.XMLHTTP");=0A=
} catch (oc) {=0A=
A=3Dnull;=0A=
}=0A=
}=0A=
}=0A=
if (!A)=0A=
sajax_debug("Could not create connection object.");=0A=
=0A=
return A;=0A=
}=0A=
=0A=
/**=0A=
* Perform an ajax call to mediawiki. Calls are handeled by =
AjaxDispatcher.php=0A=
* func_name - the name of the function to call. Must be registered in =
$wgAjaxExportList=0A=
* args - an array of arguments to that function=0A=
* target - the target that will handle the result of the call. If this =
is a function,=0A=
* if will be called with the XMLHttpRequest as a parameter; =
if it's an input=0A=
* element, its value will be set to the resultText; if it's =
another type of=0A=
* element, its innerHTML will be set to the resultText.=0A=
*=0A=
* Example:=0A=
* sajax_do_call('doFoo', [1, 2, 3], =
document.getElementById("showFoo"));=0A=
*=0A=
* This will call the doFoo function via MediaWiki's AjaxDispatcher, with=0A=
* (1, 2, 3) as the parameter list, and will show the result in the =
element=0A=
* with id =3D showFoo=0A=
*/=0A=
function sajax_do_call(func_name, args, target) {=0A=
var i, x, n;=0A=
var uri;=0A=
var post_data;=0A=
uri =3D wgServer +=0A=
((wgScript =3D=3D null) ? (wgScriptPath + "/index.php") : wgScript) +=0A=
"?action=3Dajax";=0A=
if (sajax_request_type =3D=3D "GET") {=0A=
if (uri.indexOf("?") =3D=3D -1)=0A=
uri =3D uri + "?rs=3D" + encodeURIComponent(func_name);=0A=
else=0A=
uri =3D uri + "&rs=3D" + encodeURIComponent(func_name);=0A=
for (i =3D 0; i < args.length; i++)=0A=
uri =3D uri + "&rsargs[]=3D" + encodeURIComponent(args[i]);=0A=
//uri =3D uri + "&rsrnd=3D" + new Date().getTime();=0A=
post_data =3D null;=0A=
} else {=0A=
post_data =3D "rs=3D" + encodeURIComponent(func_name);=0A=
for (i =3D 0; i < args.length; i++)=0A=
post_data =3D post_data + "&rsargs[]=3D" + =
encodeURIComponent(args[i]);=0A=
}=0A=
x =3D sajax_init_object();=0A=
if (!x) {=0A=
alert("AJAX not supported");=0A=
return false;=0A=
}=0A=
=0A=
try {=0A=
x.open(sajax_request_type, uri, true);=0A=
} catch (e) {=0A=
if (window.location.hostname =3D=3D "localhost") {=0A=
alert("Your browser blocks XMLHttpRequest to 'localhost', try using a =
real hostname for development/testing.");=0A=
}=0A=
throw e;=0A=
}=0A=
if (sajax_request_type =3D=3D "POST") {=0A=
x.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");=0A=
x.setRequestHeader("Content-Type", =
"application/x-www-form-urlencoded");=0A=
}=0A=
x.setRequestHeader("Pragma", "cache=3Dyes");=0A=
x.setRequestHeader("Cache-Control", "no-transform");=0A=
x.onreadystatechange =3D function() {=0A=
if (x.readyState !=3D 4)=0A=
return;=0A=
=0A=
sajax_debug("received (" + x.status + " " + x.statusText + ") " + =
x.responseText);=0A=
=0A=
//if (x.status !=3D 200)=0A=
// alert("Error: " + x.status + " " + x.statusText + ": " + =
x.responseText);=0A=
//else=0A=
=0A=
if ( typeof( target ) =3D=3D 'function' ) {=0A=
target( x );=0A=
}=0A=
else if ( typeof( target ) =3D=3D 'object' ) {=0A=
if ( target.tagName =3D=3D 'INPUT' ) {=0A=
if (x.status =3D=3D 200) target.value=3D x.responseText;=0A=
//else alert("Error: " + x.status + " " + x.statusText + " (" + =
x.responseText + ")");=0A=
}=0A=
else {=0A=
if (x.status =3D=3D 200) target.innerHTML =3D x.responseText;=0A=
else target.innerHTML=3D "Error: " + x.status + =
" " + x.statusText + " (" + x.responseText + ")
";=0A=
}=0A=
}=0A=
else {=0A=
alert("bad target for sajax_do_call: not a function or object: " + =
target);=0A=
}=0A=
=0A=
return;=0A=
}=0A=
=0A=
sajax_debug(func_name + " uri =3D " + uri + " / post =3D " + post_data);=0A=
x.send(post_data);=0A=
sajax_debug(func_name + " waiting..");=0A=
delete x;=0A=
=0A=
return true;=0A=
}=0A=
------=_NextPart_000_0000_01C8CFF7.55B9C990
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://ja.wikipedia.org/skins-1.5/common/mwsuggest.js?156
/*=0A=
* OpenSearch ajax suggestion engine for MediaWiki=0A=
* =0A=
* uses core MediaWiki open search support to fetch suggestions=0A=
* and show them below search boxes and other inputs=0A=
*=0A=
* by Robert Stojnic (April 2008)=0A=
*/=0A=
=0A=
// search_box_id -> Results object =0A=
var os_map =3D {};=0A=
// cached data, url -> json_text=0A=
var os_cache =3D {};=0A=
// global variables for suggest_keypress=0A=
var os_cur_keypressed =3D 0;=0A=
var os_last_keypress =3D 0;=0A=
var os_keypressed_count =3D 0;=0A=
// type: Timer=0A=
var os_timer =3D null;=0A=
// tie mousedown/up events=0A=
var os_mouse_pressed =3D false;=0A=
var os_mouse_num =3D -1;=0A=
// if true, the last change was made by mouse (and not keyboard)=0A=
var os_mouse_moved =3D false;=0A=
// delay between keypress and suggestion (in ms)=0A=
var os_search_timeout =3D 250;=0A=
// these pairs of inputs/forms will be autoloaded at startup=0A=
var os_autoload_inputs =3D new Array('searchInput', 'searchInput2', =
'powerSearchText', 'searchText');=0A=
var os_autoload_forms =3D new Array('searchform', 'searchform2', =
'powersearch', 'search' );=0A=
// if we stopped the service=0A=
var os_is_stopped =3D false;=0A=
// max lines to show in suggest table=0A=
var os_max_lines_per_suggest =3D 7;=0A=
=0A=
/** Timeout timer class that will fetch the results */ =0A=
function os_Timer(id,r,query){=0A=
this.id =3D id;=0A=
this.r =3D r;=0A=
this.query =3D query; =0A=
}=0A=
=0A=
/** Property class for single search box */=0A=
function os_Results(name, formname){ =0A=
this.searchform =3D formname; // id of the searchform=0A=
this.searchbox =3D name; // id of the searchbox=0A=
this.container =3D name+"Suggest"; // div that holds results=0A=
this.resultTable =3D name+"Result"; // id base for the result table =
(+num =3D table row)=0A=
this.resultText =3D name+"ResultText"; // id base for the spans within =
result tables (+num)=0A=
this.toggle =3D name+"Toggle"; // div that has the toggle =
(enable/disable) link=0A=
this.query =3D null; // last processed query=0A=
this.results =3D null; // parsed titles=0A=
this.resultCount =3D 0; // number of results=0A=
this.original =3D null; // query that user entered =0A=
this.selected =3D -1; // which result is selected=0A=
this.containerCount =3D 0; // number of results visible in container =0A=
this.containerRow =3D 0; // height of result field in the container=0A=
this.containerTotal =3D 0; // total height of the container will all =
results=0A=
this.visible =3D false; // if container is visible=0A=
}=0A=
=0A=
/** Hide results div */=0A=
function os_hideResults(r){=0A=
var c =3D document.getElementById(r.container);=0A=
if(c !=3D null)=0A=
c.style.visibility =3D "hidden";=0A=
r.visible =3D false;=0A=
r.selected =3D -1;=0A=
}=0A=
=0A=
/** Show results div */=0A=
function os_showResults(r){=0A=
if(os_is_stopped)=0A=
return;=0A=
os_fitContainer(r);=0A=
var c =3D document.getElementById(r.container);=0A=
r.selected =3D -1;=0A=
if(c !=3D null){=0A=
c.scrollTop =3D 0;=0A=
c.style.visibility =3D "visible";=0A=
r.visible =3D true;=0A=
} =0A=
}=0A=
=0A=
function os_operaWidthFix(x){=0A=
// TODO: better css2 incompatibility detection here=0A=
if(is_opera || is_khtml || =
navigator.userAgent.toLowerCase().indexOf('firefox/1')!=3D-1){=0A=
return x - 30; // opera&konqueror & old firefox don't understand =
overflow-x, estimate scrollbar width=0A=
} =0A=
return x;=0A=
}=0A=
=0A=
function os_encodeQuery(value){=0A=
if (encodeURIComponent) {=0A=
return encodeURIComponent(value);=0A=
}=0A=
if(escape) {=0A=
return escape(value);=0A=
}=0A=
return null;=0A=
}=0A=
function os_decodeValue(value){=0A=
if (decodeURIComponent) {=0A=
return decodeURIComponent(value);=0A=
}=0A=
if(unescape){=0A=
return unescape(value);=0A=
}=0A=
return null;=0A=
}=0A=
=0A=
/** Brower-dependent functions to find window inner size, and scroll =
status */=0A=
function f_clientWidth() {=0A=
return f_filterResults (=0A=
window.innerWidth ? window.innerWidth : 0,=0A=
document.documentElement ? document.documentElement.clientWidth : 0,=0A=
document.body ? document.body.clientWidth : 0=0A=
);=0A=
}=0A=
function f_clientHeight() {=0A=
return f_filterResults (=0A=
window.innerHeight ? window.innerHeight : 0,=0A=
document.documentElement ? document.documentElement.clientHeight : 0,=0A=
document.body ? document.body.clientHeight : 0=0A=
);=0A=
}=0A=
function f_scrollLeft() {=0A=
return f_filterResults (=0A=
window.pageXOffset ? window.pageXOffset : 0,=0A=
document.documentElement ? document.documentElement.scrollLeft : 0,=0A=
document.body ? document.body.scrollLeft : 0=0A=
);=0A=
}=0A=
function f_scrollTop() {=0A=
return f_filterResults (=0A=
window.pageYOffset ? window.pageYOffset : 0,=0A=
document.documentElement ? document.documentElement.scrollTop : 0,=0A=
document.body ? document.body.scrollTop : 0=0A=
);=0A=
}=0A=
function f_filterResults(n_win, n_docel, n_body) {=0A=
var n_result =3D n_win ? n_win : 0;=0A=
if (n_docel && (!n_result || (n_result > n_docel)))=0A=
n_result =3D n_docel;=0A=
return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;=0A=
}=0A=
=0A=
/** Get the height available for the results container */=0A=
function os_availableHeight(r){=0A=
var absTop =3D document.getElementById(r.container).style.top;=0A=
var px =3D absTop.lastIndexOf("px");=0A=
if(px > 0)=0A=
absTop =3D absTop.substring(0,px);=0A=
return f_clientHeight() - (absTop - f_scrollTop());=0A=
}=0A=
=0A=
=0A=
/** Get element absolute position {left,top} */=0A=
function os_getElementPosition(elemID){=0A=
var offsetTrail =3D document.getElementById(elemID);=0A=
var offsetLeft =3D 0;=0A=
var offsetTop =3D 0;=0A=
while (offsetTrail){=0A=
offsetLeft +=3D offsetTrail.offsetLeft;=0A=
offsetTop +=3D offsetTrail.offsetTop;=0A=
offsetTrail =3D offsetTrail.offsetParent;=0A=
}=0A=
if (navigator.userAgent.indexOf('Mac') !=3D -1 && typeof =
document.body.leftMargin !=3D 'undefined'){=0A=
offsetLeft +=3D document.body.leftMargin;=0A=
offsetTop +=3D document.body.topMargin;=0A=
}=0A=
return {left:offsetLeft,top:offsetTop};=0A=
}=0A=
=0A=
/** Create the container div that will hold the suggested titles */=0A=
function os_createContainer(r){=0A=
var c =3D document.createElement("div");=0A=
var s =3D document.getElementById(r.searchbox);=0A=
var pos =3D os_getElementPosition(r.searchbox); =0A=
var left =3D pos.left;=0A=
var top =3D pos.top + s.offsetHeight;=0A=
c.className =3D "os-suggest";=0A=
c.setAttribute("id", r.container); =0A=
document.body.appendChild(c); =0A=
=0A=
// dynamically generated style params =0A=
// IE workaround, cannot explicitely set "style" attribute=0A=
c =3D document.getElementById(r.container);=0A=
c.style.top =3D top+"px";=0A=
c.style.left =3D left+"px";=0A=
c.style.width =3D s.offsetWidth+"px";=0A=
=0A=
// mouse event handlers=0A=
c.onmouseover =3D function(event) { os_eventMouseover(r.searchbox, =
event); };=0A=
c.onmousemove =3D function(event) { os_eventMousemove(r.searchbox, =
event); };=0A=
c.onmousedown =3D function(event) { return =
os_eventMousedown(r.searchbox, event); };=0A=
c.onmouseup =3D function(event) { os_eventMouseup(r.searchbox, event); =
};=0A=
return c;=0A=
}=0A=
=0A=
/** change container height to fit to screen */=0A=
function os_fitContainer(r){ =0A=
var c =3D document.getElementById(r.container);=0A=
var h =3D os_availableHeight(r) - 20;=0A=
var inc =3D r.containerRow;=0A=
h =3D parseInt(h/inc) * inc;=0A=
if(h < (2 * inc) && r.resultCount > 1) // min: two results=0A=
h =3D 2 * inc; =0A=
if((h/inc) > os_max_lines_per_suggest )=0A=
h =3D inc * os_max_lines_per_suggest;=0A=
if(h < r.containerTotal){=0A=
c.style.height =3D h +"px";=0A=
r.containerCount =3D parseInt(Math.round(h/inc));=0A=
} else{=0A=
c.style.height =3D r.containerTotal+"px";=0A=
r.containerCount =3D r.resultCount;=0A=
}=0A=
}=0A=
/** If some entries are longer than the box, replace text with "..." */=0A=
function os_trimResultText(r){=0A=
var w =3D document.getElementById(r.container).offsetWidth;=0A=
if(r.containerCount < r.resultCount){ =0A=
w -=3D 20; // give 20px for scrollbar =0A=
} else=0A=
w =3D os_operaWidthFix(w);=0A=
if(w < 10)=0A=
return;=0A=
for(var i=3D0;i w && (e.offsetWidth < lastW || iteration<2)){=0A=
changedText =3D true;=0A=
lastW =3D e.offsetWidth;=0A=
var l =3D e.innerHTML; =0A=
e.innerHTML =3D l.substring(0,l.length-replace)+"...";=0A=
iteration++;=0A=
replace =3D 4; // how many chars to replace=0A=
}=0A=
if(changedText){=0A=
// show hint for trimmed titles=0A=
=
document.getElementById(r.resultTable+i).setAttribute("title",r.results[i=
]);=0A=
}=0A=
}=0A=
}=0A=
=0A=
/** Handles data from XMLHttpRequest, and updates the suggest results */=0A=
function os_updateResults(r, query, text, cacheKey){ =0A=
os_cache[cacheKey] =3D text;=0A=
r.query =3D query;=0A=
r.original =3D query;=0A=
if(text =3D=3D ""){=0A=
r.results =3D null;=0A=
r.resultCount =3D 0;=0A=
os_hideResults(r);=0A=
} else{ =0A=
try {=0A=
var p =3D eval('('+text+')'); // simple json parse, could do a safer =
one=0A=
if(p.length<2 || p[1].length =3D=3D 0){=0A=
r.results =3D null;=0A=
r.resultCount =3D 0;=0A=
os_hideResults(r);=0A=
return;=0A=
} =0A=
var c =3D document.getElementById(r.container);=0A=
if(c =3D=3D null)=0A=
c =3D os_createContainer(r); =0A=
c.innerHTML =3D os_createResultTable(r,p[1]);=0A=
// init container table sizes=0A=
var t =3D document.getElementById(r.resultTable); =0A=
r.containerTotal =3D t.offsetHeight; =0A=
r.containerRow =3D t.offsetHeight / r.resultCount;=0A=
os_trimResultText(r); =0A=
os_showResults(r);=0A=
} catch(e){=0A=
// bad response from server or such=0A=
os_hideResults(r); =0A=
os_cache[cacheKey] =3D null;=0A=
}=0A=
} =0A=
}=0A=
=0A=
/** Create the result table to be placed in the container div */=0A=
function os_createResultTable(r, results){=0A=
var c =3D document.getElementById(r.container);=0A=
var width =3D os_operaWidthFix(c.offsetWidth); =0A=
var html =3D "";=0A=
r.results =3D new Array();=0A=
r.resultCount =3D results.length;=0A=
for(i=3D0;i"+title+" | ";=0A=
}=0A=
html+=3D"
"=0A=
return html;=0A=
}=0A=
=0A=
/** Fetch namespaces from checkboxes or hidden fields in the search form,=0A=
if none defined use wgSearchNamespaces global */=0A=
function os_getNamespaces(r){ =0A=
var namespaces =3D "";=0A=
var elements =3D document.forms[r.searchform].elements;=0A=
for(i=3D0; i < elements.length; i++){=0A=
var name =3D elements[i].name;=0A=
if(typeof name !=3D 'undefined' && name.length > 2 =0A=
&& name[0]=3D=3D'n' && name[1]=3D=3D's' =0A=
&& ((elements[i].type=3D=3D'checkbox' && elements[i].checked) =0A=
|| (elements[i].type=3D=3D'hidden' && elements[i].value=3D=3D"1")) ){=0A=
if(namespaces!=3D"")=0A=
namespaces+=3D"|";=0A=
namespaces+=3Dname.substring(2);=0A=
}=0A=
}=0A=
if(namespaces =3D=3D "")=0A=
namespaces =3D wgSearchNamespaces.join("|");=0A=
return namespaces;=0A=
}=0A=
=0A=
/** Update results if user hasn't already typed something else */=0A=
function os_updateIfRelevant(r, query, text, cacheKey){=0A=
var t =3D document.getElementById(r.searchbox);=0A=
if(t !=3D null && t.value =3D=3D query){ // check if response is still =
relevant =0A=
os_updateResults(r, query, text, cacheKey);=0A=
}=0A=
r.query =3D query;=0A=
}=0A=
=0A=
/** Fetch results after some timeout */=0A=
function os_delayedFetch(){=0A=
if(os_timer =3D=3D null)=0A=
return;=0A=
var r =3D os_timer.r;=0A=
var query =3D os_timer.query;=0A=
os_timer =3D null;=0A=
var path =3D =
wgMWSuggestTemplate.replace("{namespaces}",os_getNamespaces(r))=0A=
.replace("{dbname}",wgDBname)=0A=
.replace("{searchTerms}",os_encodeQuery(query));=0A=
=0A=
// try to get from cache, if not fetch using ajax=0A=
var cached =3D os_cache[path];=0A=
if(cached !=3D null){=0A=
os_updateIfRelevant(r, query, cached, path);=0A=
} else{ =0A=
var xmlhttp =3D sajax_init_object();=0A=
if(xmlhttp){=0A=
try { =0A=
xmlhttp.open("GET", path, true);=0A=
xmlhttp.onreadystatechange=3Dfunction(){=0A=
if (xmlhttp.readyState=3D=3D4 && typeof os_updateIfRelevant =
=3D=3D 'function') { =0A=
os_updateIfRelevant(r, query, xmlhttp.responseText, path);=0A=
}=0A=
};=0A=
xmlhttp.send(null); =0A=
} catch (e) {=0A=
if (window.location.hostname =3D=3D "localhost") {=0A=
alert("Your browser blocks XMLHttpRequest to 'localhost', try using =
a real hostname for development/testing.");=0A=
}=0A=
throw e;=0A=
}=0A=
}=0A=
}=0A=
}=0A=
=0A=
/** Init timed update via os_delayedUpdate() */=0A=
function os_fetchResults(r, query, timeout){=0A=
if(query =3D=3D ""){=0A=
os_hideResults(r);=0A=
return;=0A=
} else if(query =3D=3D r.query)=0A=
return; // no change=0A=
=0A=
os_is_stopped =3D false; // make sure we're running=0A=
=0A=
/* var cacheKey =3D wgDBname+":"+query; =0A=
var cached =3D os_cache[cacheKey];=0A=
if(cached !=3D null){=0A=
os_updateResults(r,wgDBname,query,cached);=0A=
return;=0A=
} */=0A=
=0A=
// cancel any pending fetches=0A=
if(os_timer !=3D null && os_timer.id !=3D null)=0A=
clearTimeout(os_timer.id);=0A=
// schedule delayed fetching of results =0A=
if(timeout !=3D 0){=0A=
os_timer =3D new =
os_Timer(setTimeout("os_delayedFetch()",timeout),r,query);=0A=
} else{ =0A=
os_timer =3D new os_Timer(null,r,query);=0A=
os_delayedFetch(); // do it now!=0A=
}=0A=
=0A=
}=0A=
/** Change the highlighted row (i.e. suggestion), from position cur to =
next */=0A=
function os_changeHighlight(r, cur, next, updateSearchBox){=0A=
if (next >=3D r.resultCount)=0A=
next =3D r.resultCount-1;=0A=
if (next < -1)=0A=
next =3D -1; =0A=
r.selected =3D next;=0A=
if (cur =3D=3D next)=0A=
return; // nothing to do.=0A=
=0A=
if(cur >=3D 0){=0A=
var curRow =3D document.getElementById(r.resultTable + cur);=0A=
if(curRow !=3D null)=0A=
curRow.className =3D "os-suggest-result";=0A=
}=0A=
var newText;=0A=
if(next >=3D 0){=0A=
var nextRow =3D document.getElementById(r.resultTable + next);=0A=
if(nextRow !=3D null)=0A=
nextRow.className =3D os_HighlightClass();=0A=
newText =3D r.results[next];=0A=
} else=0A=
newText =3D r.original;=0A=
=0A=
// adjust the scrollbar if any=0A=
if(r.containerCount < r.resultCount){=0A=
var c =3D document.getElementById(r.container);=0A=
var vStart =3D c.scrollTop / r.containerRow;=0A=
var vEnd =3D vStart + r.containerCount;=0A=
if(next < vStart)=0A=
c.scrollTop =3D next * r.containerRow;=0A=
else if(next >=3D vEnd)=0A=
c.scrollTop =3D (next - r.containerCount + 1) * r.containerRow;=0A=
}=0A=
=0A=
// update the contents of the search box=0A=
if(updateSearchBox){=0A=
os_updateSearchQuery(r,newText); =0A=
}=0A=
}=0A=
=0A=
function os_HighlightClass() {=0A=
var match =3D navigator.userAgent.match(/AppleWebKit\/(\d+)/);=0A=
if (match) {=0A=
var webKitVersion =3D parseInt(match[1]);=0A=
if (webKitVersion < 523) {=0A=
// CSS system highlight colors broken on old Safari=0A=
// https://bugs.webkit.org/show_bug.cgi?id=3D6129=0A=
// Safari 3.0.4, 3.1 known ok=0A=
return "os-suggest-result-hl-webkit";=0A=
}=0A=
}=0A=
return "os-suggest-result-hl";=0A=
}=0A=
=0A=
function os_updateSearchQuery(r,newText){=0A=
document.getElementById(r.searchbox).value =3D newText;=0A=
r.query =3D newText;=0A=
}=0A=
=0A=
/** Find event target */=0A=
function os_getTarget(e){=0A=
if (!e) e =3D window.event;=0A=
if (e.target) return e.target;=0A=
else if (e.srcElement) return e.srcElement;=0A=
else return null;=0A=
}=0A=
=0A=
=0A=
=0A=
/********************=0A=
* Keyboard events =0A=
********************/ =0A=
=0A=
/** Event handler that will fetch results on keyup */=0A=
function os_eventKeyup(e){=0A=
var targ =3D os_getTarget(e);=0A=
var r =3D os_map[targ.id];=0A=
if(r =3D=3D null)=0A=
return; // not our event=0A=
=0A=
// some browsers won't generate keypressed for arrow keys, catch it =0A=
if(os_keypressed_count =3D=3D 0){=0A=
os_processKey(r,os_cur_keypressed,targ);=0A=
}=0A=
var query =3D targ.value;=0A=
os_fetchResults(r,query,os_search_timeout);=0A=
}=0A=
=0A=
/** catch arrows up/down and escape to hide the suggestions */=0A=
function os_processKey(r,keypressed,targ){=0A=
if (keypressed =3D=3D 40){ // Arrow Down=0A=
if (r.visible) { =0A=
os_changeHighlight(r, r.selected, r.selected+1, true); =0A=
} else if(os_timer =3D=3D null){=0A=
// user wants to get suggestions now=0A=
r.query =3D "";=0A=
os_fetchResults(r,targ.value,0);=0A=
}=0A=
} else if (keypressed =3D=3D 38){ // Arrow Up=0A=
if (r.visible){=0A=
os_changeHighlight(r, r.selected, r.selected-1, true);=0A=
}=0A=
} else if(keypressed =3D=3D 27){ // Escape=0A=
document.getElementById(r.searchbox).value =3D r.original;=0A=
r.query =3D r.original;=0A=
os_hideResults(r);=0A=
} else if(r.query !=3D document.getElementById(r.searchbox).value){=0A=
// os_hideResults(r); // don't show old suggestions=0A=
}=0A=
}=0A=
=0A=
/** When keys is held down use a timer to output regular events */=0A=
function os_eventKeypress(e){ =0A=
var targ =3D os_getTarget(e);=0A=
var r =3D os_map[targ.id];=0A=
if(r =3D=3D null)=0A=
return; // not our event=0A=
=0A=
var keypressed =3D os_cur_keypressed;=0A=
if(keypressed =3D=3D 38 || keypressed =3D=3D 40){=0A=
var d =3D new Date()=0A=
var now =3D d.getTime();=0A=
if(now - os_last_keypress < 120){=0A=
os_last_keypress =3D now;=0A=
return;=0A=
}=0A=
}=0A=
=0A=
os_keypressed_count++;=0A=
os_processKey(r,keypressed,targ);=0A=
}=0A=
=0A=
/** Catch the key code (Firefox bug) */=0A=
function os_eventKeydown(e){=0A=
if (!e) e =3D window.event;=0A=
var targ =3D os_getTarget(e);=0A=
var r =3D os_map[targ.id];=0A=
if(r =3D=3D null)=0A=
return; // not our event=0A=
=0A=
os_mouse_moved =3D false;=0A=
=0A=
os_cur_keypressed =3D (window.Event) ? e.which : e.keyCode;=0A=
os_last_keypress =3D 0;=0A=
os_keypressed_count =3D 0;=0A=
}=0A=
=0A=
/** Event: loss of focus of input box */=0A=
function os_eventBlur(e){ =0A=
var targ =3D os_getTarget(e);=0A=
var r =3D os_map[targ.id];=0A=
if(r =3D=3D null)=0A=
return; // not our event=0A=
if(!os_mouse_pressed) =0A=
os_hideResults(r);=0A=
}=0A=
=0A=
/** Event: focus (catch only when stopped) */=0A=
function os_eventFocus(e){=0A=
// nothing happens here?=0A=
}=0A=
=0A=
=0A=
=0A=
/********************=0A=
* Mouse events =0A=
********************/ =0A=
=0A=
/** Mouse over the container */=0A=
function os_eventMouseover(srcId, e){=0A=
var targ =3D os_getTarget(e); =0A=
var r =3D os_map[srcId];=0A=
if(r =3D=3D null || !os_mouse_moved)=0A=
return; // not our event=0A=
var num =3D os_getNumberSuffix(targ.id);=0A=
if(num >=3D 0)=0A=
os_changeHighlight(r,r.selected,num,false);=0A=
=0A=
}=0A=
=0A=
/* Get row where the event occured (from its id) */=0A=
function os_getNumberSuffix(id){=0A=
var num =3D id.substring(id.length-2);=0A=
if( ! (num.charAt(0) >=3D '0' && num.charAt(0) <=3D '9') )=0A=
num =3D num.substring(1);=0A=
if(os_isNumber(num))=0A=
return parseInt(num);=0A=
else=0A=
return -1;=0A=
}=0A=
=0A=
/** Save mouse move as last action */=0A=
function os_eventMousemove(srcId, e){=0A=
os_mouse_moved =3D true;=0A=
}=0A=
=0A=
/** Mouse button held down, register possible click */=0A=
function os_eventMousedown(srcId, e){=0A=
var targ =3D os_getTarget(e);=0A=
var r =3D os_map[srcId];=0A=
if(r =3D=3D null)=0A=
return; // not our event=0A=
var num =3D os_getNumberSuffix(targ.id);=0A=
=0A=
os_mouse_pressed =3D true;=0A=
if(num >=3D 0){=0A=
os_mouse_num =3D num;=0A=
// os_updateSearchQuery(r,r.results[num]);=0A=
}=0A=
// keep the focus on the search field=0A=
document.getElementById(r.searchbox).focus();=0A=
=0A=
return false; // prevents selection=0A=
}=0A=
=0A=
/** Mouse button released, check for click on some row */=0A=
function os_eventMouseup(srcId, e){=0A=
var targ =3D os_getTarget(e);=0A=
var r =3D os_map[srcId];=0A=
if(r =3D=3D null)=0A=
return; // not our event=0A=
var num =3D os_getNumberSuffix(targ.id);=0A=
=0A=
if(num >=3D 0 && os_mouse_num =3D=3D num){=0A=
os_updateSearchQuery(r,r.results[num]);=0A=
os_hideResults(r);=0A=
document.getElementById(r.searchform).submit();=0A=
}=0A=
os_mouse_pressed =3D false;=0A=
// keep the focus on the search field=0A=
document.getElementById(r.searchbox).focus();=0A=
}=0A=
=0A=
/** Check if x is a valid integer */=0A=
function os_isNumber(x){=0A=
if(x =3D=3D "" || isNaN(x))=0A=
return false;=0A=
for(var i=3D0;i=3D '0' && c <=3D '9') )=0A=
return false;=0A=
}=0A=
return true;=0A=
}=0A=
=0A=
=0A=
/** When the form is submitted hide everything, cancel updates... */=0A=
function os_eventOnsubmit(e){=0A=
var targ =3D os_getTarget(e);=0A=
=0A=
os_is_stopped =3D true;=0A=
// kill timed requests=0A=
if(os_timer !=3D null && os_timer.id !=3D null){=0A=
clearTimeout(os_timer.id);=0A=
os_timer =3D null;=0A=
}=0A=
// Hide all suggestions=0A=
for(i=3D0;i