User:TheDJ/Gadget-geonotice-core.js

/* _____________________________________________________________________________ * |                                                                             | * |                    === WARNING: GLOBAL GADGET FILE ===                      | * |                 Changes to this page affect many users. | * | Please discuss changes on the talk page or on WT:Gadget before editing. | * |_____________________________________________________________________________| * * Imported as of 8 august 2014 from testwiki:MediaWiki:Gadget-geonotice-core.js * Shows notices to registered users based on their location */

/* global jQuery, mediaWiki */

( function ( mw, $ ) { 'use strict';

mw.messages.set( {	'gn-hideButton': 'Hide' } );

/** * Namespace for all Geonotice methods and properties. * @class * @singleton */ var gn = {};

/** * @param {string} str Wiki-text of the link * @param {string} page The title of the target page of the link * @param {string} text The text to be used for the link */ /* jshint unused: true */

gn.geoWikiLinker = function (str, page, text) { text = text || page; return mw.html.element(		'a', {			href: mw.util.getUrl( page ),			title: page		}, text	); };

/** * Handle click events. * * @param {jQuery.Event} e Click event */ gn.hideGeonotice = function (e) { e.preventDefault;

var parentId = $(e.target).closest('li').attr('id').replace( /^geonotice/, ''); var hiddenNotices = gn.getHiddenNotices;

hiddenNotices.push(parentId); gn.saveHiddenNotices(hiddenNotices);

$( '#geonotice' + parentId ).hide; $( '#geonotice-hr' ).hide;

return false; };

/** * Boolean indicating whether this will be the first notice added to the page */ gn.firstnotice = true;

/** * Regular expression used to detect links in wiki-text */ gn.regexForInternalLinks = /\[\[([^{|}\[\]\n]+)(?:\|(.*?))?\]\]/g;

/** * A key used to store the array of hidden notices in Web Storage */ gn.storageKey = 'hidegeonotices';

/** * Get a list of the hidden notices */ gn.getHiddenNotices = function { var hiddenNotices = mw.storage.get( gn.storageKey ) || mw.storage.session.get( gn.storageKey );

try { return JSON.parse(hiddenNotices) || []; } catch (e) { return []; } };

/** * Save the list of the hidden notices */ gn.saveHiddenNotices = function ( notices ) { notices = JSON.stringify( notices ); mw.storage.set( gn.storageKey, notices ) || mw.storage.session.set( gn.storageKey, notices ); };

/** * Removes ids from localstorage that are no longer in use */ gn.expungeOldNotices = function( currentList ) { var savedList = gn.getHiddenNotices, originalLength = savedList.length; for (var i = savedList.length - 1; i >= 0; i--) { if( !( savedList[i] in currentList ) ) { savedList.splice( i, 0 ); }	}	if( originalLength !== savedList.length ) { gn.saveHiddenNotices( savedList ); } };

/** * Add a notice on top of the watchlist * * @param {Object} notice Object representing a notice */ gn.displayGeonotice = function (notice) { var geonoticeText = notice.text.replace( gn.regexForInternalLinks, gn.geoWikiLinker );

if (gn.firstnotice) { gn.firstnotice = false; $('#watchlist-message').prepend(			$( ' ' ).attr({ 'id' : 'geonotice-hr' })		); }

$('#watchlist-message').prepend(		$('')			.attr({ 'class' : 'geonotice plainlinks', 'id' : 'geonotice' + notice.id			})			.append( $( ' ' )					.html( geonoticeText ), $( ' ' )					.append(						$('')							.text( mw.msg( 'gn-hideButton' ) )							.click( gn.hideGeonotice )							.attr( { 'href' : '#' } )					) )	).show; };

/** * Determine which notices are still valid and are targeted to the location of the current user */ gn.runGeonotice = function { var now = new Date, hide, id, notice, minlat, maxlat, minlon, maxlon, startNotice, endNotice, hiddenNotices = gn.getHiddenNotices;

for (id in gn.notices) { hide = hiddenNotices.indexOf( id ) >= 0; if (!hide) { notice = gn.notices[id]; notice.id = id;

if (!notice || !notice.begin || !notice.end) { continue; }

startNotice = Date.parse(notice.begin); endNotice = Date.parse(notice.end);

if ( now.getTime > startNotice &&				now.getTime < endNotice ) { if (notice.country && Geo.country === notice.country) { gn.displayGeonotice(notice); } else { if (notice.corners) { minlat = Math.min(notice.corners[0][0], notice.corners[1][0]); maxlat = Math.max(notice.corners[0][0], notice.corners[1][0]); minlon = Math.min(notice.corners[0][1], notice.corners[1][1]); maxlon = Math.max(notice.corners[0][1], notice.corners[1][1]);

// Geo coordinates can be empty string if unknown. parseFloat makes // these NaN, so that you do not get to see a notice in that case. if ( minlat < parseFloat( Geo.lat ) && parseFloat( Geo.lat ) < maxlat &&							minlon < parseFloat( Geo.lon ) && parseFloat( Geo.lon ) < maxlon						) { gn.displayGeonotice(notice); }					}				}			}		}	}	gn.expungeOldNotices( gn.notices ); };

// Attach to window window.GeoNotice = $.extend( gn, window.GeoNotice ); gn.notices = require( './geonotice-list.json' );

if ( window.Geo !== undefined ) { $( gn.runGeonotice ); }

}( mediaWiki, jQuery ) );