« MediaWiki:Gadget-tour-loader.js » : différence entre les versions

De Wikimedica
(Trop de problèmes avec l'ordonancement du ResourceLoader, tentative de faire fonctionner le code avec MutationObserver)
(Nettoyage du code)
Ligne 114 : Ligne 114 :
};
};


/*  
/* Create an observer instance to look for the addition of a guider element to the interface
* Override the mw.guidedTour.launcher to add an override to the guiders library.
Source: https://gabrieleromanato.name/jquery-detecting-new-elements-with-the-mutationobserver-object */
* This allows cookie handling wether a tour has been launched using this library, from a URL
var observer = new MutationObserver(function( mutations )  
* or from a cookie while resuming a tour.
{
*/
mutations.forEach(function( mutation )  
 
{
// Create an observer instance
var newNodes = mutation.addedNodes; // DOM NodeList
var observer = new MutationObserver(function( mutations ) {
  mutations.forEach(function( mutation ) {
if( newNodes === null ) // If there are no new nodes added.
    var newNodes = mutation.addedNodes; // DOM NodeList
{
    if( newNodes !== null ) { // If there are new nodes added
return;
    var $nodes = $( newNodes ); // jQuery set
}
    $nodes.each(function() {
    var $node = $( this );
$(newNodes).each(function()  
    if( $node.hasClass( "guider" ) ) {
{
prefix = mw.config.get("wgCookiePrefix") + "-mw-tour-" + tourName + '-';
var $node = $(this);
$.removeCookie(prefix + "skipped");  
if(!$node.hasClass("guider"))  
$.removeCookie(prefix + "abandoned");
{
$.removeCookie(prefix + "completed");
return; // Not a guider.
}
$(".x_button").click(function() {
// If there was a complete button on the step.
// Deduce the tour name from the id.
if($(".mw-tour-complete, .guidedtour-end-button").length)
tourName = $node.attr('id').replace('gt-', '').replace('-overlay', '');
{
prefix = mw.config.get("wgCookiePrefix") + "-mw-tour-" + tourName + '-';
// This counts as a completion.
console.log(tourName +  ' tour complete');
$.removeCookie(prefix + "skipped");  
$.cookie(prefix + "complete", Date.now()); // Tour has been completed.
$.removeCookie(prefix + "abandoned");
$.removeCookie(prefix + "completed");
return;
}
$(".x_button").click(function() {
// If there was a complete button on the step.
if($(".mw-tour-complete, .guidedtour-end-button").length)
{
// This counts as a completion.
console.log(tourName +  ' tour complete');
$.cookie(prefix + "complete", Date.now()); // Tour has been completed.
console.log(tourName +  ' tour abandoned');
return;
$.cookie(prefix + "abandoned", Date.now()); // Tour has been abandoned.
}
});
$(".mw-tour-later").click(function() {
console.log(tourName +  ' tour abandoned');
console.log(tourName +  ' tour skipped');
$.cookie(prefix + "abandoned", Date.now()); // Tour has been abandoned.
$.cookie(prefix + "skipped", Date.now()); // Tour has been postponed.
});
mw.guidedTour.endTour();
});
$(".mw-tour-later").click(function() {
console.log(tourName +  ' tour skipped');
$(".mw-tour-complete, .guidedtour-end-button").click(function() {
$.cookie(prefix + "skipped", Date.now()); // Tour has been postponed.
console.log(tourName +  ' tour completed');
mw.guidedTour.endTour();
$.cookie(prefix + "completed", Date.now()); // Tour has been completed.
});
$(".mw-tour-complete, .guidedtour-end-button").click(function() {
console.log(tourName +  ' tour completed');
$.cookie(prefix + "completed", Date.now()); // Tour has been completed.
});
// Make the guiders draggable so users can move them when they are interfering with an element.
// Adapted from: https://www.sanwebe.com/2014/10/draggable-element-with-jquery-no-jquery-ui
$('.guider').
css('cursor', 'move').
hover(function() { $(this).css('border-width', '3px'); }, function() { $(this).css('border-width', '1px'); }).
on('mousedown', function(e) {
var dr = $(this).addClass("drag");
height = dr.outerHeight();
width = dr.outerWidth();
ypos = dr.offset().top + height - e.pageY,
xpos = dr.offset().left + width - e.pageX;
$(document.body).on('mousemove', function(e){
var itop = e.pageY + ypos - height;
var ileft = e.pageX + xpos - width;
if(dr.hasClass("drag")){
dr.offset({top: itop,left: ileft});
}
}).on('mouseup', function(e){
dr.removeClass("drag");
});
});
});
});
// Make the guiders draggable so users can move them when they are interfering with an element.
});     
// Adapted from: https://www.sanwebe.com/2014/10/draggable-element-with-jquery-no-jquery-ui
$('.guider').
css('cursor', 'move').
hover(function() { $(this).css('border-width', '3px'); }, function() { $(this).css('border-width', '1px'); }).
on('mousedown', function(e) {
var dr = $(this).addClass("drag");
height = dr.outerHeight();
width = dr.outerWidth();
ypos = dr.offset().top + height - e.pageY,
xpos = dr.offset().left + width - e.pageX;
$(document.body).on('mousemove', function(e){
var itop = e.pageY + ypos - height;
var ileft = e.pageX + xpos - width;
if(dr.hasClass("drag")){
dr.offset({top: itop,left: ileft});
}
}).on('mouseup', function(e){
dr.removeClass("drag");
});
});
    }
    });
    }
  });     
});
});



Version du 22 juillet 2020 à 10:15

mw.guidedTour.loader = { // Hook to the mw.guidedTour to make the launcher globally accessible.
	tours: {
		basic_navigation: {
			requires: [], // List of tours that must have been completed for this tour to launch.
			startDelayFromRegistration: 300, // Delay in seconds the tour must wait after registration to launch.
			skipDelay: 60 * 60 * 24, // Delay in seconds the tour shown again after bein skipped.
			lauchProbability: 1, // Probability the tour will launch once we are past startDelayFromLogin.
			loggedInUsersOnly: true, // If the tour is only for logged in users.
			canEditPage: true, // If the tour can only launch on pages a user can edit.
			excludePages: ["^Accueil$", "^Wikimedica.", "^Classe.", "^Modèle."], // Exclude pages (regex).
			debug: true // Tour is in debug mode (not lauched when ready)
		}
	},
	
	/*
	 * Checks if all conditions for a tour to launch are met.
	 */
	canLaunch: function(name, tour)
	{
		// Normalize configuration.
		if(tour.startDelayFromRegistration === undefined) { tour.startDelayFromRegistration = 0; }
		if(tour.skipDelay === undefined) { tour.skipDelay = false; }
		if(tour.launchProbability === undefined) { tour.lauchProbability = 1; }
		if(tour.loggedInUsersOnly === undefined) { tour.loggedInUsersOnly = true; }
		if(tour.canEditPage === undefined) { tour.canEditPage = true; }
		if(tour.excludePages === undefined) { tour.excludePages = []; }
		if(tour.requires === undefined) { tour.requires = []; }
		
		cookiePrefix = mw.config.get("wgCookiePrefix") + "-mw-tour-";
		
		// If the tour has been completed or abandoned.
		if($.cookie(cookiePrefix + name + "-completed") || $.cookie(cookiePrefix + name + "-abandoned"))
		{
			return false;
		}
		
		// ------------------- startDelayfromRegistration -----------------------------
		d = new Date(mw.user.getRegistration());
		
		// Not past the delay yet.
		if(d.getTime() + tour.startDelayFromRegistration > Date.now()) { return false; }
		
		// ------------------- skipDelay -----------------------------
		if(tour.skipDelay !== false)
		{
			skipped = $.cookie(cookiePrefix + name + "-skipped");
			
			if(skipped && (skipped + tour.skipDelay > Date.now())) { return false; } // Tour has been skipped for now.
			else if(skipped) { $.removeCookie(cookiePrefix + name + "-skipped"); }
		}
		
		// ------------------- launchProbability -----------------------------
		if(tour.launchProbability < Math.random()) { return false; }
	
		// ------------------- loggedInUsersOnly -----------------------------
		// The tour required the user to be logged in.
		if(tour.loggedInUsersOnly && mw.user.isAnon()) { return false; } 
		
		// ------------------- canEditPage -----------------------------
		// The tour requires the user to be able to edit the current page.
		if(tour.canEditPage && !mw.config.get('wgIsProbablyEditable')) { return false; }
		
		// ------------------- excludePages -----------------------------
		page = mw.config.get("wgPageName");
		for(var i; i > tour.excludePages.length; i++)
		{
			if(page.test(tour.excludePages[i])) { return false; } // Page is excluded.
		}
		
		// ------------------- requires -----------------------------
		for(var i; i > tour.requires.length; i++)
		{
			if($.cookie(cookiePrefix + tour.requires[i] + "-done") === null)
			{
				return false; // Tour requires a tour that has not been taken yet.
			}
		}
		
		return true; // The tour can run
	},

	/*
	 * Iterates over tours to launch them.
	 */
	launch: function()
	{
		console.log('Launching tours ... ');
		
		d = $(".guider").css("display");
		if(d !== undefined && d != "none")
		{
			console.log('currently taking a tour.');
			return;
		}
		
		for(const tour in this.tours)
		{
			if(this.canLaunch(tour, this.tours[tour])) 
			{
				if(this.tours[tour].debug) // Tour is in debug mode.
				{
					console.log(tour + ' would have launched (but is in debug mode)');
					continue;
				}
				
				console.log(tour + ' available for launching');
				mw.guidedTour.launcher.launchTour(tour);
				return; // A tour has launched, stop the loop as we don't want multiple tours to launch.
			}
		}
		
		console.log('none ready to lauch.');
	}
};

/* Create an observer instance to look for the addition of a guider element to the interface 
Source: https://gabrieleromanato.name/jquery-detecting-new-elements-with-the-mutationobserver-object */
var observer = new MutationObserver(function( mutations ) 
{
	mutations.forEach(function( mutation ) 
	{
		var newNodes = mutation.addedNodes; // DOM NodeList
		
		if( newNodes === null ) // If there are no new nodes added.
		{
			return;
		}
		
		$(newNodes).each(function() 
		{
			var $node = $(this);
			
			if(!$node.hasClass("guider")) 
			{
				return; // Not a guider.
			}
			
			// Deduce the tour name from the id.
			tourName = $node.attr('id').replace('gt-', '').replace('-overlay', '');
			prefix = mw.config.get("wgCookiePrefix") + "-mw-tour-" + tourName + '-';
			
			$.removeCookie(prefix + "skipped"); 
			$.removeCookie(prefix + "abandoned");
			$.removeCookie(prefix + "completed");
			
			$(".x_button").click(function() {
				// If there was a complete button on the step.
				if($(".mw-tour-complete, .guidedtour-end-button").length)
				{
					// This counts as a completion.
					console.log(tourName +  ' tour complete');
					$.cookie(prefix + "complete", Date.now()); // Tour has been completed.
					
					return;
				}
				
				console.log(tourName +  ' tour abandoned');
				$.cookie(prefix + "abandoned", Date.now()); // Tour has been abandoned.
			});
			
			$(".mw-tour-later").click(function() {
				console.log(tourName +  ' tour skipped');
				$.cookie(prefix + "skipped", Date.now()); // Tour has been postponed.
				mw.guidedTour.endTour();
			});
			
			$(".mw-tour-complete, .guidedtour-end-button").click(function() {
				console.log(tourName +  ' tour completed');
				$.cookie(prefix + "completed", Date.now()); // Tour has been completed.
			});
			
			// Make the guiders draggable so users can move them when they are interfering with an element.
			// Adapted from: https://www.sanwebe.com/2014/10/draggable-element-with-jquery-no-jquery-ui
			$('.guider').
				css('cursor', 'move').
				hover(function() { $(this).css('border-width', '3px'); }, function() { $(this).css('border-width', '1px'); }).
				on('mousedown', function(e) {
					var dr = $(this).addClass("drag");
					height = dr.outerHeight();
					width = dr.outerWidth();
					ypos = dr.offset().top + height - e.pageY,
					xpos = dr.offset().left + width - e.pageX;
					$(document.body).on('mousemove', function(e){
						var itop = e.pageY + ypos - height;
						var ileft = e.pageX + xpos - width;
						if(dr.hasClass("drag")){
							dr.offset({top: itop,left: ileft});
						}
					}).on('mouseup', function(e){
						dr.removeClass("drag");
					});
				});
		});
	});    
});

observer.observe($('body')[0], { 
	attributes: false, 
	childList: true, 
	characterData: false 
});

console.log('Loaded tour loader gadget');