User:Yair rand/MobileJS.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// this replaces MobileFrontend/javascripts/opensearch.js and MobileFrontend/javascripts/application.js.
// Assumes that this is in the head, and that pageLoaded is called from the bottom of that body, and
// that #logo has onclick="logoClick()" in the html, and that #results is available.

// handle clicking on headers to expand sections and clicking on links that lead to hidden sections
document.onclick = function(e) { 
	e = e || event;
	for( e = e.target || e.srcElement; e && e.nodeName != "A" && e.className != "section_heading"; ) {
		e = e.parentNode;
	}
	if( e && e.className == "section_heading") { // headers
		wm_toggle_section( parseInt( e.id.replace( /section_(\d+)/, '$1' ) ) );
	} else if( e && e.hash && e.hash.indexOf( '#' ) == 0 ) { // links
		wm_reveal_for_hash( e.hash );
	}
}

var languageSelection;

// called from the bottom of the body
function pageLoaded() { 

	if ( document.location.hash.indexOf( '#' ) == 0 ) {
		wm_reveal_for_hash( document.location.hash );
	}

	var search = document.getElementById('search'), 
		clearSearch = document.getElementById('clearsearch'),
		results = document.getElementById('results'),
		sq = document.getElementById( 'sq' );
	languageSelection = document.getElementById( 'languageselection' );
	clearSearch.setAttribute('title', 'Clear'); // should start with correct title attribute
	
	
	results.style.width = ( sq.offsetWidth - 2 ) + pixels;
	results.style.left = sq.offsetLeft + pixels;
	results.style.top = ( sq.offsetTop + sq.offsetHeight )	+ pixels;

	function clearSearchBox() {
		search.value = '';
		clearSearch.style.display = results.style.display = 'none';
		return false;
	}
	clearSearch.onmousedown = clearSearchBox;

	search.onkeyup = function() {
		if ( clearSearch ) {
			clearSearch.style.display = search.value.length > 0 ? 'block' : results.style.display = 'none';
		}
		// from bottom
		clearTimeout( timer );
		var term = this.value;
		if ( term.length < 1 ) {
			results.innerHTML = '';
		} else {
			timer = setTimeout( function () { searchApi( term ); }, typingDelay );
		}
	}

	// Try to scroll and hide URL bar
	window.scrollTo( 0, 1 );
};

// Activated by "onclick='logoClick()'" in #logo html
function logoClick() {
	var n = document.getElementById( 'nav' ).style;
	n.display = n.display == 'block' ? 'none' : 'block';
	if (n.display == 'block' && languageSelection && languageSelection.offsetWidth > 175 ) {
		n.width = (languageSelection.offsetWidth + 30) + 'px';
	}
};

// Activated by "onchange='javascript:navigateToLanguageSelection();'" in #languageSelection html
function navigateToLanguageSelection() {
	if ( languageSelection ) {
		var url = languageSelection.options[languageSelection.selectedIndex].value;
		if ( url ) {
			location.href = url;
		}
	}
}

updateOrientation();

/**
 * updateOrientation checks the current orientation, sets the body's class
 * attribute to portrait, landscapeLeft, or landscapeRight,
 * and displays a descriptive message on "Handling iPhone or iPod touch Orientation Events".
 */

function updateOrientation() {
	switch (window.orientation) {
	case 0:
		document.body.setAttribute('class', 'portrait');
		break;
	case 90:
	case -90:
		document.body.setAttribute('class', 'landscape');
	}
}

// Point to the updateOrientation function when iPhone switches between portrait and landscape modes.
window.onorientationchange = updateOrientation;

function wm_reveal_for_hash(hash) {
	var targetel = document.getElementById(hash.substr(1));
	if (targetel) {
		for (var p = targetel.parentNode; p && p.className != 'content_block' && p.className != 'section_heading';) {
			p = p.parentNode;
		}
		if (p && p.style.display != 'block') {
			var section_idx = parseInt(p.id.split('_')[1]);
			wm_toggle_section(section_idx);
		}
	}
}

function wm_toggle_section(section_id) {
	var b = document.getElementById('section_' + section_id),
		bb = b.getElementsByTagName('button');
	for (var i = 0; i <= 1; i++) {
		var s = bb[i].style;
		s.display = s.display == 'none' || (i && !s.display) ? 'inline-block' : 'none';
	}
	for (var i = 0, d = ['content_', 'anchor_']; i <= 1; i++) {
		var s = document.getElementById(d[i] + section_id).style;
		s.display = s.display == 'block' ? 'none' : 'block';
	}
}

var apiUrl = (window.scriptPath?scriptPath:'/w')+'/api.php'; // this actually needs to get the real script path, atm unavailable

var timer = -1;
var typingDelay = 500;
var numResults = 10;
var pixels = 'px';

function searchApi( term ) {
	var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject( 'Microsoft.XMLHTTP' );

	xmlHttp.onreadystatechange = function() {
		if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) {
			var response = (window.JSON && JSON.parse ? JSON.parse : eval)( xmlHttp.responseText )[1];
			results.style.display = 'block';
			for(;results.firstChild;){results.removeChild(results.firstChild)}
			if(response.length === 0){
				results.appendChild( document.createTextNode( "No results" ) );
			} else { 
				results.appendChild( document.createElement('div') ).className = "suggestions-results";
				for( var i = 0; i < response.length; i++ ){
					var newdiv = results.lastChild.appendChild( document.createElement('div') );
					newdiv.className = "suggestions-result"; // seriously, why does this need a class? can't any css be done as #results>div?
					newdiv.title = response[i];
					newdiv.appendChild( document.createElement('a') ).href = '/wiki/' + response[i];
					newdiv.firstChild.appendChild( document.createTextNode( response[i] ) );
				}
			}
		}
	}
	var url = apiUrl + '?action=opensearch&limit=' + numResults + '&namespace=0&format=json&search=' + term;
	xmlHttp.open( 'GET', url, true );
	xmlHttp.send();
}