MediaWiki:Gadget-sftJSmsg.js

/* ------------------------------------------------------------------------ *\
    Klasa wielokrotnego użytku do "łagodnych" komunikatów Javascriptowych
	
    Copyright:  ©2008-2010 Maciej Jaros (pl:User:Nux, en:User:Nux)
     Licencja:  GNU General Public License v2
                http://opensource.org/licenses/gpl-license.php

	Note:
		For best results in IE add this to your CSS:
		html {height:100%}
\* ------------------------------------------------------------------------ */

//
// Object
//
function sftJSmsg()
{
	//
	// VERSION
	this.ver = this.version = '0.2.0';
	
	this.msgEls = new Array();

	// settings
	this.showCancel = false;	// show cancel button
	this.noButtons = false;		// no buttons - NOTE: you'll have to close message for yourself if you use it
	this.createRegularForm = false;	// instead of a simple popup use popup to submit a form created in it
	this.RegularForm = {	// settings for a form (if createRegularForm==ture)
		'method' : 'POST',			// default method
		'action' : location.href	// default actions
	};
	this.autoOKClose = true;	// add close action for OK button
	
	this.styleZbase = 50000;	// base z-index for msg (note that there can be more z-indexes used)
	this.styleTop = 100;
	this.styleWidth = 330;
	this.pozFromTop = 40;
	
	// lang
	this.lang = {
		'OK' : 'OK',
		'Cancel' : 'Anuluj'
	};
	
	//
	// .init()
	//
	this.init = function()
	{
		var glob = document.body;
		
		var nel;
		
		//
		// document shade
		nel = document.createElement('div');
		nel.style.cssText = 'background:white;filter:alpha(opacity=75);opacity:0.75;position:absolute;left:0px;top:0px;';
		nel.style.width = document.documentElement.scrollWidth+'px';
		nel.style.height= document.documentElement.scrollHeight+'px';
		nel.style.display = 'none';
		glob.appendChild(nel);
		this.msgEls[this.msgEls.length] = nel;

		//
		// main message element
		nel = document.createElement('div');
		nel.style.cssText = 'text-align:center;background:white;padding:5px 10px;border:1px solid black;position:absolute;';
		// przy ustawionym min-height
		// if (nel.style.maxHeight==undefined)	nel.style.height='300px'; // IE blah...
		nel.style.display = 'none';
		glob.appendChild(nel);
		var elAppender = this.elMain = this.msgEls[this.msgEls.length] = nel;

		//
		// form element
		if (this.createRegularForm)
		{
			nel = document.createElement('form');
			/*
			nel.setAttribute('action', this.RegularForm.action);
			nel.setAttribute('method', this.RegularForm.method);
			*/
			for (var key in this.RegularForm)
			{
				nel.setAttribute(key, this.RegularForm[key]);
			}
			elAppender.appendChild(nel);
			elAppender = nel;	// podmiana, żeby zawartość i przyciski były w elemencie FORM
		}

		//
		// message content
		nel = document.createElement('div');
		nel.style.margin = '1em .5em';
		elAppender.appendChild(nel);
		this.elContent = nel;

		if (!this.noButtons)
		{
			//
			// message buttons elements
			nel = document.createElement('div');
			nel.style.marginBottom = '1em';
			elAppender.appendChild(nel);
			this.msgBtns = new Object();
			this.msgBtns.parent = nel;
			this.msgBtns.parent.sftJSmsg = this;
			
			// OK (always)
			nel = document.createElement('input');
			nel.setAttribute('type', (!this.createRegularForm) ? 'button' : 'submit');
			nel.setAttribute('name', 'submit');
			nel.setAttribute('value', this.lang['OK']);
			nel.style.padding = '0 1em';
			this.msgBtns.parent.appendChild(nel);
			this.msgBtns.ok = nel;
			// Cancel (if asked for by the user)
			if (this.showCancel)
			{
				nel = document.createElement('input');
				nel.setAttribute('type', 'button');
				nel.setAttribute('value', this.lang['Cancel']);
				nel.onclick = this.close;
				nel.style.marginLeft = '1em';
				this.msgBtns.parent.appendChild(nel);
				this.msgBtns.cancel = nel;
			}
		}
		
		// setup user changable styles
		this.reInit();
		
		// enable resize
		/*
		smpAddEvent(window, 'resize', function() {
			this.reInit()
		});
		*/
		window.sftJSmsgs[window.sftJSmsgs.length] = this;
	}

	//
	// .reInit()
	//
	// reInit so that changed styles will work
	this.reInit = function()
	{
		//
		// ew. korekta wielkości cienia z tyłu
		var shade_el = this.msgEls[0];
		shade_el.style.width = document.documentElement.scrollWidth+'px';
		shade_el.style.height= document.documentElement.scrollHeight+'px';

		//
		// z-index
		for (var i=0; i<this.msgEls.length; i++)
		{
			this.msgEls[i].style.zIndex = this.styleZbase+i;
		}
		
		//
		// top
		if (this.styleTop==undefined)	// auto-top
		{
			var cur_scroll = qmGetPageScroll();
			this.styleTop = cur_scroll[1]+this.pozFromTop;
		}
		this.elMain.style.top = this.styleTop+'px';

		//
		// width + left
		var left=undefined;
		if (this.styleWidth==undefined)	// auto-width
		{
			this.elMain.style.width = '';
			if (this.styleLeft==undefined)
			{
				left = 100;	// if both undefined then left cannot be computed
			}
		}
		else
		{
			this.elMain.style.width = this.styleWidth+'px';
		}
		// final left setup
		var glob = document.body;
		if (left==undefined && this.styleLeft==undefined)	// if not yet set
		{
			left = Math.floor(glob.clientWidth/2 - this.styleWidth/2);
		}
		else
		{
			left = this.styleLeft;
		}
		this.elMain.style.left	= ((left<10) ? 10 : left)+'px';	// including padding
	}

	//
	// .show(html, strOKclick)
	//
	this.show = function(html, strOKclick)
	{
		// init / reInit
		if (this.msgEls.length==0)
		{
			this.init();
		}
		else
		{
			this.reInit();
		}
		
		//
		// wiadomosc
		if (!this.prevHTML || html!=this.prevHTML)
		{
			this.prevHTML = html;
			this.elContent.innerHTML = html;
		}
		
		if (!this.noButtons)
		{
			//
			// akcja
			if (typeof strOKclick =='string' && strOKclick.length>0)
			{
				if (this.autoOKClose)
				{
					this.msgBtns.ok.akcja = this.close;
					this.msgBtns.ok.onclick = new Function(strOKclick +'; this.akcja()');
				}
				else
				{
					this.msgBtns.ok.onclick = new Function(strOKclick);
				}
			}
			else //if (!this.createRegularForm)
			{
				this.msgBtns.ok.onclick = this.close;
			}
		}
		
		//
		// pokaż
		for (var i=0; i<this.msgEls.length; i++)
		{
			this.msgEls[i].style.display = 'block';
		}
		
		// scroll
		var cur_scroll = qmGetPageScroll();
		window.scroll(cur_scroll[0], this.styleTop-this.pozFromTop);
	}

	//
	// .close()
	//
	var _this = this;	// to avoid this problems when hooked to a button
	this.close = function()
	{
		for (var i=0; i<_this.msgEls.length; i++)
		{
			_this.msgEls[i].style.display = 'none';
		}
	}

	//
	// .setOKdisabled(disable)
	//
	this.setOKdisabled = function(disable)
	{
		this.msgBtns.ok.disabled = disable;
	}
}

window.sftJSmsg = sftJSmsg;

/* ------------------------------------------------------------------------ *\
	Simple messages
	
	TODO
	* add a way to stop quee messages (in the second message comming from quee)
\* ------------------------------------------------------------------------ */

//
// Object init
//
var oJsAlert = {
	oMsg : null,
	arrQuee : [],
	isVisible : false
}

window.oJsAlert = oJsAlert;

//
// init msg for alerts
//
oJsAlert.init = function ()
{
	var msg = new sftJSmsg();
	msg.styleTop = undefined;	// = auto-top = don't scroll
	var win_size = qmGetWindowSize();
	poz_top = Math.floor(win_size[1]/2)-100;	// ~middle
	if (poz_top<0)
	{
		poz_top = 20;
	}
	msg.pozFromTop = poz_top;
	msg.styleWidth = 400;
	msg.showCancel = false;
	msg.autoOKClose = false;
	msg.createRegularForm = false;
	
	oJsAlert.oMsg = msg;
}
jQuery (oJsAlert.init);

//
// Unqueed show
//
oJsAlert.show = function (txt)
{
	// set visibility for quee
	oJsAlert.isVisible = true;
	
	// add quee runner
	var strOKclick = "oJsAlert.close();";

	// show alert
	var msg = oJsAlert.oMsg;
	msg.styleTop = undefined;	// = auto-top = don't scroll
	var win_size = qmGetWindowSize();
	poz_top = Math.floor(win_size[1]/2)-200;	// ~middle
	if (poz_top<0)
	{
		poz_top = 20;
	}
	msg.pozFromTop = poz_top;
	msg.styleWidth = 400;
	msg.show(''
		+'<div class="jsAlert">'
			+txt
		+'</div>'
		,strOKclick
	);	
}

//
// hide and check for next
//
oJsAlert.close = function ()
{
	// set visibility
	oJsAlert.isVisible = false;
	
	// close (hide) message box
	oJsAlert.oMsg.close();
	
	// quee
	oJsAlert.quee();
}
// quee (FIFO)
oJsAlert.quee = function ()
{
	if (oJsAlert.arrQuee.length>0)
	{
		var txt = oJsAlert.arrQuee.shift();
		jsAlert(txt);
	}
}

//
// alert() replacement
//
function jsAlert(txt)
{
	// not loaded? add to quee...
	if (oJsAlert.oMsg == null)
	{
		oJsAlert.arrQuee.push(txt);
		if (oJsAlert.arrQuee.length==1)
		{
			jQuery (function(){oJsAlert.quee()});
		}
	}
	// already visible? add to quee
	else if (oJsAlert.isVisible)
	{
		oJsAlert.arrQuee.push(txt);
	}
	// otherwise just show
	else
	{
		oJsAlert.show (txt);
	}
}
window.jsAlert = jsAlert;

/* ------------------------------------------------------------------------ *\
	Various functions based on info and scripts from
	www.quirksmode.org
	
    Copyright:  ©2008 Maciej Jaros (pl:User:Nux, en:User:Nux), Peter-Paul Koch
     Licencja:  Public domain
\* ------------------------------------------------------------------------ */
// element [left, top]
function qmFindPos(obj)
{
	if (typeof obj != 'object' || obj==null)
	{
		return [0,0];
	}
	
	var curleft = curtop = 0;
	if (obj.offsetParent)
	{
		do
		{
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
		while (obj = obj.offsetParent);
	}
	return [curleft, curtop];
}
// page X, Y scroll [width, height]
function qmGetPageScroll()
{
	var retArray;

	if (self.pageYOffset)	// FF, Opera (probably all except IE)
	{
		retArray = [self.pageXOffset, self.pageYOffset];
	}
	else if (document.documentElement && document.documentElement.scrollTop) // IE 6 Strict
	{
		retArray = [document.documentElement.scrollLeft, document.documentElement.scrollTop];
	}
	else if (document.body)	// IE
	{
		retArray = [document.body.scrollLeft, document.body.scrollTop];
	}

	return retArray;
}
// window [width, height]
function qmGetWindowSize()
{
	var retArray;
	
	if (typeof(window.innerWidth) == 'number')	// FF, Opera (probably all except IE)
	{
		retArray = [window.innerWidth, window.innerHeight]
	}
	else if (document.documentElement && document.documentElement.clientWidth) //IE 6 strict
	{
		retArray = [document.documentElement.clientWidth, document.documentElement.clientHeight];
	}
	else if (document.body && document.body.clientWidth) //IE 4 compatible
	{
		retArray = [document.body.clientWidth, document.body.clientHeight];
	}

	return retArray;
}

if (typeof smpAddEvent != 'function')
{
	function smpAddEvent(obj, onwhat, fun)
	{
		if (obj.addEventListener)
		{
			obj.addEventListener(onwhat, fun, false);
		}
		else if (obj.attachEvent)
		{
			obj.attachEvent('on'+onwhat, fun);
		}
		else
		{
			// error
		}
	}
}

//
// Correct size of the shade element(s) on window resize
//
window.sftJSmsgs = new Array();
smpAddEvent(window, 'resize', function()
{
	if (window.sftJSmsgs.length<1)
	{
		return;
	}
	
	for (var i=window.sftJSmsgs.length-1; i>=0; i--)
	{
		var msg = window.sftJSmsgs[i];
		if (msg.msgEls[0].style.display == 'block')
		{
			msg.reInit();
		}
	}
});

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.
Kembali kehalaman sebelumnya