MediaWiki: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 );

    if ( window.Geo !== undefined ) {

    $( gn.runGeonotice );

    }

    }( mediaWiki, jQuery ) );