Aller au contenu

Utilisateur:Dfeldmann/MenuPopup.js

Une page de Wikipédia, l'encyclopédie libre.
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;

Firefox (sur GNU/Linux) / Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.
/**
* MenuPopUp (MPU)
*
* Display a menu in a popup.  This menu can be customized and contains any link or javascript code the user needs.
* Affiche un menu dans un popup. Ce menu peut être configuré pour contenir tous les liens ou code javascript que l'utilisateur souhaite.
*
* Add the following line in the monobook to activate the popups : 
* Ajouter la ligne suivante au monobook pour activer les popups : 
* importScript( "Utilisateur:Deep silence/MenuPopup.js" );
* 
* The following parameters can be cutomized : 
* Les paramètres qui suivent peuvent être modifiés par l'utilistateur : 
* var MPU_key = 'a';			// name of the keybord key used to open the menu (Obligatoire/Mandatory)
* var MPU_modifier = 'Alt';		// name of the 'modifier' used to open the menu conjointly with the MPU_key (Optionnel/Optional, or 'Alt', 'Ctrl', 'Shift')
* var PMU_menu_definition = 'xxxxx'	// content of the menu : see documentation bellow (Optionnel/Optional, uses default definition file is not defined)
* var PMU_menu_style = 'xxxxx'		// style of the menu (Optionnel/Optional, uses default CSS file is not defined)
* var PMU_menu_refresh = true		// set this parameter to true forces the cache refresh of the menu definition. It is usefull when updating a menu definition, but should be discarded once its definition is fixed. (Optionnel/Optional, uses 'false' by default)
*
* Auteurs : [[:fr:User:Deep silence]]
* License: GFDL
* Date de dernière révision : 27/04/2009
*  
*  MENU DEFINITION
*  xxx:(title)				//title in xxx menu (if 'xxxx' is not given, it is assumed for the main menu)
*  xxx:------				//separator in xxx menu
*  xxx:linklabel=linklabel		// link 
*  xxx:menulabel->submenu	// submenu
*  
*  submenu:(title)			// title of submenu 'submenu'
*  etc...
*  
*  KEYWORDS : 
*  %%USERNAME%%				Name of the user
*  %%_USERNAME_%%				Name of the user with '_' as space
*  %%PAGENAME%%				Name of the current page
*  %%_USERNAME_%%				Name of the current page with '_' as space
*  %%JJMMAAAA%%				Date 
*  %%INSERT%%param1%%param2%%param3%%	Insertion code : will insert 'param1' before the selected text, 'param2' after the selected text, will insert 'param3' at the caret place
* 					These three parameters are optional
*
*/
 
/*
*
*  Fonctions et variables communes
*
*/
// DATES DU JOUR A DIFFERENTS FORMATS
var MPU_Mois = new Array('janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre'); 
var MPU_today = new Date();
var MPU_jjmmaa = MPU_today.getDate() + '_' + MPU_Mois[MPU_today.getMonth()] + '_' + (MPU_today.getYear() + 1900);
 
// NOM DE LA PAGE ACTUELLE (sans namespace)
if (typeof mw.config.get('wgPageName') == "undefined"){
MPU_pageName = "unknown";			// pour debugage en dehors de wikipedia
} else {
MPU_pageName = mw.config.get('wgPageName').replace(/_/g, ' '); 
MPU_pageName_ = mw.config.get('wgPageName');
}
 
// NOM DU USER
if (typeof mw.config.get('wgUserName') == "undefined"){
MPU_userName = "user unknown";				// pour debugage en dehors de wikipedia
} else {
MPU_userName = mw.config.get('wgUserName');
MPU_userName_ = mw.config.get('wgUserName').replace(/ /,'_') ;
}
 
 
 
/*
*  FONCTION DE GESTION DES TOUCHES ENFONCEES
*  retourne "Shift", "Ctrl", "Alt", séparés par "+", 
* selon les touches enfoncées lors d'un clic de souris.
* (doit être appelée avec l'evenement du clic souris)
*/
function MPU_getAdditionalKey(event) {
event = (event ? event: window.event );
 
var ctrlPressed=event.ctrlKey;
var altPressed=event.altKey;
var shiftPressed=event.shiftKey;
 
var listResult = new Array;
if (shiftPressed) {
listResult.push("Shift");
}
if (altPressed) {
listResult.push("Alt");
}
if (ctrlPressed) {
listResult.push("Ctrl");
}
 
var result = "";
for (var i=0;i<listResult.length;i++){
if (i != 0){
	 result +="+";
}
result += listResult[i];
}
 
return result;
}
 
 
/*
* 	GESTION DE LA SOURIS
*/
document.onmousemove = MPU_getMouseXY;
var MPU_mousePositionX = 0
var MPU_mousePositionY = 0
 
// Main function to retrieve mouse x-y pos.s
function MPU_getMouseXY(event) {
event = (event ? event : window.event );
// rattrapage du scroll quand position des divs = 'fixed'
MPU_mousePositionX  = (event.x ? event.x : event.clientX) + document.body.scrollLeft;
MPU_mousePositionY  = (event.y ? event.y : event.clientY) + document.body.scrollTop;
return true
}
 
 
 
 
// for DOM parent
function MPU_addDOMElt(parentElt, tag, params){
var att;
var mn;
 
// TEXTNODE
if (typeof params == "undefined"){
mn = document.createTextNode(tag);
 
// DOM NODE
} else {
mn = document.createElement( tag );
for (var e=0; e<params.length; e++){
att = document.createAttribute(params[e][0]);
att.nodeValue = params[e][1];
mn.setAttributeNode(att);
}   
}
 
parentElt.appendChild(mn);
 
return mn;
}
 
// for MPU object parent
function MPU_addContent(menuParent, tag, params){
var par = null;
if (menuParent == null || typeof menuParent == "undefined"){	// main menu
	par = document.getElementsByTagName('body')[0];
} else {							//sub menu
	par = document.getElementById(menuParent.nom);
}
 
return MPU_addDOMElt(par, tag, params);
}
 
 
 
/*
*
* MENU POPUP PROTOTYPES
*
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ELEMENT : définit un élément de menu (parent racine)
function MPU_menuElement() {
this.menuParent = null;	// default value, overiden for sub menus
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MENU : contient une liste d options, 
// qui peuvent être des liens, des fonctions 
// javascript, ou des sous-menus
MPU_menuPopUp.prototype = new MPU_menuElement() ;
function MPU_menuPopUp(){
this.parent = MPU_menuElement;
this.parent();
this.contenu = new Array;
// nom du menu principal par defaut
this.nom = "menu_maincontext";
this.subMenuList = new Array; // liste des sous menus
}
// fonction d'ajout d'un élément au menu
MPU_menuPopUp.prototype.addElement = function( element ) {
// save any sub menu
if (element.sousMenu != null){
this.subMenuList.push( element.sousMenu );
element.sousMenu.menuParent = this;
}
 
// save the new element and link it back
this.contenu.push(element);
element.menuParent = this;
}
// fonction d'initialisation du menu
MPU_menuPopUp.prototype.initialiser = function( ) {
MPU_addContent(this.menuParent, 'div', [["id", this.nom], ["class", 'MPU_menu']]);
 
// initialise les lignes du menu
for(var a=0;a<this.contenu.length;a++){
this.contenu[a].initialiser();
}
 
// crée un lien de la balise vers l'objet menu
document.getElementById( this.nom ).menuObject = this;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// LIEN: définit un élément de menu de type lien
MPU_menuLien.prototype = new MPU_menuElement() ;
function MPU_menuLien(lib, addr){
this.parent = MPU_menuElement;
this.parent();
this.libelle = lib;
this.address = addr;
}
MPU_menuLien.prototype.initialiser = function() {
var elt = MPU_addContent(this.menuParent, 'div', [["class", 'MPU_lien'], ["onMouseOver", "MPU_closeSubMenus(null, '"+ this.menuParent.nom + "');"]]);
elt = MPU_addDOMElt(elt, 'a', [["href", this.address]]);
elt = MPU_addDOMElt(elt, this.libelle);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// LIGNE TITRE: définit un élément de menu de type titre
MPU_menuTitre.prototype = new MPU_menuElement() ;
function MPU_menuTitre(lib){
this.parent = MPU_menuElement;
this.parent();
this.libelle = lib;
}
MPU_menuTitre.prototype.initialiser = function() {
var elt = MPU_addContent(this.menuParent, 'div', [["class", 'MPU_title']]);
elt = MPU_addDOMElt(elt, 'b', []);
elt = MPU_addDOMElt(elt, this.libelle);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SEPARATEUR: définit un élément de menu de ligne de séparation
MPU_menuSeparateur.prototype = new MPU_menuElement() ;
function MPU_menuSeparateur(){
this.parent = MPU_menuElement;
this.parent();
}
MPU_menuSeparateur.prototype.initialiser = function() {
MPU_addContent(this.menuParent, 'hr', []);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SOUS MENU: définit un élément de menu de type lien vers un sous menu
MPU_sousMenuLien.prototype = new MPU_menuLien() ;
function MPU_sousMenuLien(lib, sousMenu){
this.parent = MPU_menuLien;
this.parent( lib , "#" );
this.sousMenu = sousMenu;
// renomage puisque devient sous-menu
this.sousMenu.nom = "menu_" + lib.replace(/ /,"");
}
MPU_sousMenuLien.prototype.initialiser = function() {
this.sousMenu.initialiser();
var elt = MPU_addContent(this.menuParent, 'div', [["class", 'MPU_menuLien'], ["onMouseOver", "MPU_closeSubMenus(null, '"+ this.menuParent.nom + "');MPU_openSubMenu( '"+this.sousMenu.nom+"')"]]);
MPU_addDOMElt(elt, this.libelle);
elt = MPU_addDOMElt(elt, 'div',  [["class", 'MPU_menuLienFleche']] );
elt = MPU_addDOMElt(elt, 'b',  [] );
MPU_addDOMElt(elt, '\u0020\u00BB' );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 
/*
*
* MENU POPUP ESSENTIAL FUNCTIONS
*
*/
// fonction appelée pour ouvrir un menu 
function MPU_openMainMenu( event ){
var key = (event ? event.which: window.event.keyCode );
 
if ( (String.fromCharCode(key)==MPU_key && (MPU_modifier=='' || MPU_getAdditionalKey((event ? event: window.event ))==MPU_modifier) && document.getElementById) ){
var menu = document.getElementById( "menu_maincontext" );
 
// vérifie si le menu dépasse de l'écran
var okDroite =  (parseInt(MPU_mousePositionX) + parseInt(menu.offsetWidth) + 3) < window.innerWidth;
var okBas = (parseInt(MPU_mousePositionY) + parseInt(menu.offsetHeight) + 3) < window.innerHeight;
 
if (okBas){
	  menu.style.top = MPU_mousePositionY  + 'px';
} else {
	  menu.style.top = (parseInt(MPU_mousePositionY) - 5 - parseInt(menu.offsetHeight)) + 'px';
}
if (okDroite){
	  menu.style.left = MPU_mousePositionX + 'px';
} else {
	  menu.style.left = (parseInt(MPU_mousePositionX) - 5 - parseInt(menu.offsetWidth)) + 'px';
}
 
	menu.style.visibility = "visible"; 
}
}
 
 
// fonction appelée pour ouvrir un sous menu
// le nom indique quel sousmenu afficher
function MPU_openSubMenu( nom ){
if ( nom!=null && document.getElementById ){
var menu = document.getElementById( nom );
var menuParent = document.getElementById( menu.menuObject.menuParent.nom );
 
// vérifie si le menu dépasse de l'écran
var okDroite =  (parseInt( menuParent.offsetLeft ) + parseInt( menuParent.offsetWidth ) + parseInt(menu.offsetWidth) ) < window.innerWidth;
var okBas = (parseInt( menuParent.offsetTop) + parseInt( menuParent.offsetHeight ) + parseInt(menu.offsetHeight) ) < window.innerHeight;
 
if (okDroite){
	 menu.style.left = parseInt( menuParent.offsetLeft ) + parseInt( menuParent.offsetWidth ) + 2 + 'px';
} else {
	 menu.style.left = parseInt( menuParent.offsetLeft ) - parseInt( menu.offsetWidth ) - 3 + 'px';
}
 
menu.style.visibility = "visible"; 
}
}
 
 
 
// fonction appelée pour fermer un menu ou un sous menu
// le nom en paramètre est null pour le menu ppal
function MPU_closeMenu(e, nom){
if (document.getElementById){
MPU_closeSubMenus(e, nom);	// closes its submenus
 
if (nom == null){
	  nom = "menu_maincontext";
}
var menu = document.getElementById( nom );
menu.style.visibility = "hidden";
}
}
 
 
// fonction appelée pour fermer les sous menus d'un menu
// le nom en paramètre est null pour le menu ppal
function MPU_closeSubMenus(e, nom){
if (document.getElementById){
if (nom == null){
	  nom = "menu_maincontext";
}
var menu = document.getElementById( nom );
 
// ferme tous les sous menus
for (var i=0;i<menu.menuObject.subMenuList.length;i++){
	  MPU_closeMenu(e, menu.menuObject.subMenuList[i].nom);
}
}
}
 
 
 
// internal function used to get the user's menu definition file
function MPU_loadMenu_GetDefinitionFile()
{
var xmlhttp = false;
/* IE */
/*@cc_on
@if (@_jscript_version >= 5)
try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (E)
{
xmlhttp = false;
}
}
@else
xmlhttp = false;
@end @*/
 
//try again with normal browsers
if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
{
try
{
xmlhttp = new XMLHttpRequest();
}
catch (e)
{
xmlhttp = false;
}
}
 
if (xmlhttp)
{
/* on définit ce qui doit se passer quand la page répondra */
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState == 4) // 4 : état "complete" 
{
if (xmlhttp.status == 200) // 200 : code HTTP pour OK 
{
		MPU_loadMenu_ParseDefinition(xmlhttp.responseText);
}
}
}
}
return xmlhttp;
}
 
// internal function used to get the parts of the user's menu
function MPU_loadMenu_GetMenu(name, create){
	if (create == null){	// by default, creates the submenu if it does not exist
	   create = true;
	}
 
	var currentMenu;
	if (name == ""){	// adds title to the main menu
		currentMenu = MPU_menuPrincipal;
	} else {
		currentMenu = menusMap.Get(name);
		if (create && typeof currentMenu == "undefined"){
			currentMenu = new MPU_menuPopUp( );
			menusMap.Set(name, currentMenu);
		}
	}
 
	return currentMenu;
}
 
 
// function used to replace keywords (see MPU_PARSER_MENU_KEYWORDS) 
// by their corresponding values
function MPU_loadMenu_ReplaceKeywords(str){
	str = str.replace (/%%USERNAME%%/, MPU_userName);
	str = str.replace (/%%_USERNAME_%%/, MPU_userName_);
	str = str.replace (/%%PAGENAME%%/, MPU_pageName);
	str = str.replace (/%%_PAGENAME_%%/, MPU_pageName_);
	str = str.replace (/%%JJMMAAAA%%/, MPU_jjmmaa);
	if (/%%INSERT%%([^%]*)%%([^%]*)%%([^%]*)%%/.exec(str)){
		var p1 = RegExp.$1.replace(/'/g, "\\'");
		var p2 = RegExp.$2.replace(/'/g, "\\'");
		var p3 = RegExp.$3.replace(/'/g, "\\'");
		str = str.replace (/%%INSERT%%([^%]*)%%([^%]*)%%([^%]*)%%/, "javascript:insertTags('"+p1+"','"+p2+"','"+p3+"');");
	}
 
	return str;	
}
 
 
// function used to parse and create the user's menu definition file
function MPU_loadMenu_ParseDefinition(def) {
	var MPU_PARSER_MENU_NOWIKI = /^\s*(<\s*pre\s*>)?\s*<\s*\/?\s*nowiki\s*>\s*(<\s*\/\s*pre\s*>)?\s*$/;
	var MPU_PARSER_MENU_TITLE = /^\s*([^:]*)\s*:\s*\((.+)\)\s*$/;
	var MPU_PARSER_MENU_SEPARATOR = /^\s*([^:]*)\s*:\s*-{2,}\s*$/;
	var MPU_PARSER_MENU_LINK = /^\s*([^:]*)\s*:\s*([^=]+)\s*=\s*(.+)\s*$/;
	var MPU_PARSER_MENU_SUB = /^\s*([^:]*)\s*:\s*([^()]+)\s*->\s*([^\s]+)\s*$/;
 
	var defs = def.split("\n");
	var l=defs.length;
	var line;
	var currentMenu;
	var errorFound = false;
 
	MPU_menuPrincipal = new MPU_menuPopUp(); 	
	menusMap = {
		Set : function(key, menu) {this[key] = menu;},
		Get : function(key) {return this[key];}
	}
 
	for (var i=0; i<l; i++){
		line = defs[i];
		if (! /^ *$/.test(line)){
			if (MPU_PARSER_MENU_NOWIKI.exec( line )){
				// skipped
			} else if (MPU_PARSER_MENU_TITLE.exec( line )){
				currentMenu = MPU_loadMenu_GetMenu(RegExp.$1);
				currentMenu.addElement( new MPU_menuTitre( MPU_loadMenu_ReplaceKeywords(RegExp.$2) ) );
 
			} else if (MPU_PARSER_MENU_SEPARATOR.exec( line )){
				currentMenu = MPU_loadMenu_GetMenu(RegExp.$1);
				currentMenu.addElement( new MPU_menuSeparateur( ) );
 
			} else if (MPU_PARSER_MENU_LINK.exec( line )){
				currentMenu = MPU_loadMenu_GetMenu(RegExp.$1);
				currentMenu.addElement( new MPU_menuLien( MPU_loadMenu_ReplaceKeywords(RegExp.$2), MPU_loadMenu_ReplaceKeywords(RegExp.$3) ));
 
			} else if (MPU_PARSER_MENU_SUB.exec( line )){
				currentMenu = MPU_loadMenu_GetMenu(RegExp.$1);
				currentMenu.addElement( new MPU_sousMenuLien( RegExp.$2, MPU_loadMenu_GetMenu(RegExp.$3) ) );
 
			} else {// shows unparsed lines at the bottom of the menu
				errorFound = true;
				currentMenu = MPU_loadMenu_GetMenu("unknown");
				currentMenu.addElement( new MPU_menuTitre( line) );
			}
		}
	}
 
	if (errorFound) { // shows unparsed lines at the bottom of the menu
		MPU_menuPrincipal.addElement( new MPU_sousMenuLien( "ERRORS" , MPU_loadMenu_GetMenu("unknown") ) );
	}
 
	// toujours à faire en dernier
	MPU_menuPrincipal.initialiser();
}
 
 
/////////////////////////////////////////////////////////////////////////////////////////////
// INITIALISATIONS
// 		1. evenements
//		2. Loads CSS
//		3. menu
/////////////////////////////////////////////////////////////////////////////////////////////
function MPU_INIT($){
	var url;
 
	// 1. Loads CSS
	if (typeof PMU_menu_style  == "undefined"){
		url = "Utilisateur:Deep_silence/MenuPopup.css";
	} else {
		url = "Utilisateur:" + MPU_userName_ +"/"+ PMU_menu_style;
	}
	var MPU_fileref=document.createElement("link");
	MPU_fileref.setAttribute("rel", "stylesheet");
	MPU_fileref.setAttribute("type", "text/css");
	MPU_fileref.setAttribute("href", "/w/index.php?title="+ url +"&action=raw&ctype=text/css");  
	document.getElementsByTagName("head")[0].appendChild( MPU_fileref );
 
	// 2. Loads menu
	if (typeof PMU_menu_definition  == "undefined"){
		url = "Utilisateur:Deep silence/MenuDefinitionDéfaut";
	} else {
		url = "Utilisateur:" + MPU_userName_ +"/"+ PMU_menu_definition;
	}
	var xmlhttp = MPU_loadMenu_GetDefinitionFile(); 
	if (typeof PMU_menu_refresh != "undefined" && PMU_menu_refresh){
		url += "&maxage=0&smaxage=0";
	} else {
		url += "&maxage=1800&smaxage=1800";
	}
	xmlhttp.open("GET", "/w/index.php?title="+ url +"&action=raw&ctype=text/css" ,true); 
	xmlhttp.send(null); 
 
	// 3. initialise les évenements
	document.onkeypress = MPU_openMainMenu;
	document.onclick = MPU_closeMenu;
}
 
 
$(MPU_INIT);