Jump to content

User:PleaseStand/highlight-comments-dev.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by PleaseStand (talk | contribs) at 05:03, 18 February 2011 (allow for custom settings, cleaned up a bit). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/**
 * Highlights specific users' posts to discussion pages using a CSS class.
 *
 * Originally written by PleaseStand in 2010, updated for MediaWiki 1.17 in 2011
 * Released to the public domain; see http://en.wikipedia.org/wiki/Template:PD-self
 */
 
( function( $, mw ) {
	
	// Some ugly bits to work out after ResourceLoader is first improved
	var Map = mw.Map || mw.config.constructor,
		options = ( mw.userJSOptions && mw.userJSOptions.highlightComments ) || new Map();
	
	// Initialize other enclosed variables.
	var linkMap = new Map(), classNumber = 0;

    /**
	 * Give comments linking to any given page a specific CSS class.
	 * Essentially, we need to find the comment's container and wrap (except where unnecessary)
	 * everything inside except replies to that comment. We can filter the replies out in that
	 * they are inside other element types that have the effect of indenting the text.
	 */
	function wrapComments() {
		// Elements containing comments or indented text (replies to those comments)
		var commentTags = 'dd, li, p',
			indentTags = 'dl, ol, ul';
		
		$( 'a' ).each( function() {
			// linkMap is a Map from linked page names to CSS class names.
			if ( linkMap.exists( this.title ) ) {
				var className = linkMap.get( this.title );
				$(this).closest( commentTags ).contents().not( indentTags ).each( function() {
						if ( this.nodeType == 1 ) {
							$( this ).addClass( className );
						} else {
							$( this ).wrap( $( '<span/>', { 'class': className } ) );
						}
				} );
			}
		} );
	}
	
	/**
	 * Add a group of users whose comments should be given the same CSS class.
	 * @param className The CSS class name to use
	 * @param users An array of usernames
	 */
	function addClassForUsers( className, users ) {
		var ns = mw.config.get( 'wgFormattedNamespaces' );
		for ( var i = 0; i < users.length; ++i ) {
			var userName = users[i],
				userPage = ns[2] + ':' + userName,
				userTalkPage = ns[3] + ':' + userName;
			linkMap.set( userPage, className );
			linkMap.set( userTalkPage, className );
		}
	}
	
	/**
	 * Add a group of users whose comments should be highlighted in the same color.
	 * @param color The CSS background-color to use
	 * @param users An array of usernames
	 * @return The resulting CSSStyleSheet object
	 */
	function addColorForUsers( color, users ) {
		var className = 'highlighted-comment-' + classNumber++;
		addClassForUsers( className, users );
		return mw.util.addCSS( '.' + className + ' { background-color: ' + color + '; }' );
	}
	
	// Members exposed to custom highlighter functions
	var hc = {
		addClassForUsers: addClassForUsers,
		addColorForUsers: addColorForUsers
	};
	
	$( function() {
			options.get( 'customHighlighter', function() {
				// Default highlighter function - use mw.user.name() in the future?
				addColorForUsers( '#ff7', [ mw.config.get( 'wgUserName' ) ] );
				wrapComments();
			} )( hc );
	} );
	
} )( jQuery, mediaWiki );