MediaWiki:Gadget-geonotice-core.js
Appearance
This page is loaded as a part of the geonotice-core gadget, a hidden gadget. |
/* _____________________________________________________________________________
* | |
* | === 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(
$( '<hr>' ).attr({ 'id' : 'geonotice-hr' })
);
}
$('#watchlist-message').prepend(
$('<li>')
.attr({
'class' : 'geonotice plainlinks',
'id' : 'geonotice' + notice.id
})
.append(
$( '<span>' )
.html( geonoticeText ),
$( '<small>' )
.append(
$('<a>')
.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 );
if ( window.Geo !== undefined ) {
$( gn.runGeonotice );
}
}( mediaWiki, jQuery ) );