User:Majr/inputCounter.js

$( function { 'use strict';

// Get rid of the jQuery.byteLength on the summary preventing extra characters being entered $( '#wpSummary' ).off( 'keypress' );

// Display the amount of chars left on inputs that have a maxlength parameter $( '#mw-content-text' ).on( 'focus keypress', 'input', function {	var $input = $( this ),		max = $input.data( 'maxlength' ) || $input.attr( 'maxLength' );	if ( !max ) {		return;	}	mw.loader.using( 'jquery.byteLength', function { if ( !$input.parent.find( '> .chars' ).length ) { $input .removeAttr( 'maxLength' ) .data( 'maxlength', max ) .css( {					width: $input.outerWidth,					'-moz-box-sizing': 'border-box',					boxSizing: 'border-box',					// Set soon to be lost native styling					paddingTop: $input.css( 'padding-top' ),					paddingBottom: $input.css( 'padding-bottom' ),					paddingLeft: $input.css( 'padding-left' ),					paddingRight: $input.css( 'padding-right' )				} ) .wrap( $( ' ' )					.addClass( 'input-counter' )					.css( 'position', 'relative' )				) .after( $( ' ' )					.addClass( 'chars' )					.css( { position: 'absolute', top: $input.css( 'border-top-width' ), right: $input.css( 'border-right-width' ), paddingTop: parseFloat( $input.css( 'padding-top' ) ) || 1, paddingRight: parseFloat( $input.css( 'padding-right' ) ) || 1, lineHeight: $input.css( 'line-height' ) } )				)				.parent.width( $input.outerWidth ); }		setTimeout( function {			var length = $.byteLength( $input.val ),				delta = max - length,				$number = $input.parent.find( '> .chars' );			// Take into account the predefined reason length			var $reasonList = $( '#wpDeleteReasonList, #wpProtectReasonSelection' );			if ( $reasonList.length && $reasonList.val !== 'other' ) {				delta -= $.byteLength( $reasonList.val ) + 2;			}			$number.text( delta );			if ( delta < 0 ) {				$number.addClass( 'extra-chars' ).css( 'color', '#F00' );			} else {				$number.removeClass( 'extra-chars' ).css( 'color', '#AAA' );			}			// Prevent entered text from overlapping the number			$input.css( 'padding-right', $number.innerWidth + 5 );			// Reset focus if it was lost			if ( !$input.is( ':focus' ) ) {				$input.focus;			}		}, 0 ); } ); } );

// Update char count when changing a pre-defined reason select box $( '#wpDeleteReasonList, #wpProtectReasonSelection' ).change( function {	$( '#wpReason, #mwProtect-reason' ).focus; } );

// Prevent forms from submitting that have inputs with too many characters $( '#mw-content-text' ).on( 'submit', 'form', function( e ) {	var $extraChars = $( this ).find( '.extra-chars' );	if ( !$extraChars.length ) {		return;	}	e.preventDefault;	// Scroll the first input field with too many chars into view if needed	if ( $extraChars.first.offset.top < $( window ).scrollTop + 40 ) {		$( window ).scrollTop( $extraChars.first.offset.top - 40 );	}	// Flash the numbers to draw attention to them	var flashes = 0, flash = setInterval( function { if ( $extraChars.data( 'flash' ) ) { $extraChars.data( 'flash', 0 ).css( {				backgroundColor: '',				color: '#F00'			} ); flashes++; } else { $extraChars.data( 'flash', 1 ).css( {				backgroundColor: '#F00',				color: '#FFF'			} ); }		if ( flashes === 4 ) { clearInterval( flash ); if ( !$extraChars.hasClass( 'extra-chars' ) ) { $extraChars.css( 'color', '#AAA' ); }		}	}, 500 ); } );

} );