Clean up existing code and pass jshint

Coding style:
* Avoid meaningless '_' in variable names, especially when used
  inconsistently.
* Avoid trailing line comments.
* Consistent if/else curly brace position.
* Consistently use single quotes (there are no magic quotes in js).
* Consistently use $ in variable names of jQuery-wrapped elements
  (as opposed to plain node references).
* Avoid using variable names like '_this' or 'that', instead name
  them after the object.
* Too many var statements.
* Hoist var statement.
* Fix alignment of closing parentheses in initEditPage.

Code quality:
* Remove commented out code.
* Add missing radix parameter for parseInt.
* Remove unused private function "printWithRunin".
* Remove unused parameters.
* Don't call "console.log" in production client-side code because
  the console doesn't always exist in normal browser modes (and
  would result in an Uncaught ReferenceError, aborting the script
  unexpectedly and leaving the user interface in a likely
  unresponsive state).
* Use the Promise.done and Promise.fail handlers of mw.Api,
  instead of the deprecated 'ok' and 'err' parameters.
* Use jQuery#on instead of the deprecated jQuery#bind.
* Use a local shared reference to the singleton instead of relying
  on 'this' context, this way the methods can be called
  regardless of context. Such as in the $(document).ready(), or
  when passing around setErrors callback.
* Avoid using invalid html shortcuts like <div/>, use <tag>
  for creation, and <tag>..</tag> for parsing (per style guide).
* Document inputKeydown parameter being jQuery.Event (as oppposed
  to native Event).

Misc:
* Renamed '_in' to 'in', and renamed again to 'input' ('in' is an
  illegal variable name and would've crashed).

Change-Id: I283fda1409b1e76db56a939183bdaefc95e60961
This commit is contained in:
Timo Tijhof 2013-12-11 00:05:26 +01:00
parent 60cee45f4e
commit 4b31b71cfc
2 changed files with 145 additions and 137 deletions

View file

@ -12,12 +12,12 @@
*/ */
var var
histList = [""], histList = [''],
histPos = 0, histPos = 0,
question, question,
_in, input,
_out, output,
_$spinner, $spinner,
lastError = null, lastError = null,
sessionContent = null, sessionContent = null,
sessionKey = null, sessionKey = null,
@ -25,45 +25,55 @@
clearNextRequest = false; clearNextRequest = false;
function refocus() { function refocus() {
_in.blur(); // Needed for Mozilla to scroll correctly. // Needed for Mozilla to scroll correctly
_in.focus(); input.blur();
input.focus();
} }
function initConsole() { function initConsole() {
_in = document.getElementById( "mw-scribunto-input" ); input = document.getElementById( 'mw-scribunto-input' );
_out = document.getElementById( "mw-scribunto-output" ); output = document.getElementById( 'mw-scribunto-output' );
_$spinner = $.createSpinner( { size: 'small', type: 'block' } ); $spinner = $.createSpinner( { size: 'small', type: 'block' } );
recalculateInputHeight(); recalculateInputHeight();
println( mw.msg( 'scribunto-console-intro' ), 'mw-scribunto-message' ); println( mw.msg( 'scribunto-console-intro' ), 'mw-scribunto-message' );
} }
/**
* Use onkeydown because IE doesn't support onkeypress for arrow keys
* @param {jQuery.Event} e
*/
function inputKeydown( e ) { function inputKeydown( e ) {
// Use onkeydown because IE doesn't support onkeypress for arrow keys /*jshint noempty:false */
if ( e.shiftKey && e.keyCode === 13 ) { // shift-enter if ( e.shiftKey && e.keyCode === 13 ) {
// shift-enter
// don't do anything; allow the shift-enter to insert a line break as normal // don't do anything; allow the shift-enter to insert a line break as normal
} else if ( e.keyCode === 13 ) { // enter } else if ( e.keyCode === 13 ) {
// enter
// execute the input on enter // execute the input on enter
go(); go();
} else if ( e.keyCode === 38 ) { // up } else if ( e.keyCode === 38 ) {
// up
// go up in history if at top or ctrl-up // go up in history if at top or ctrl-up
if ( e.ctrlKey || caretInFirstLine( _in ) ) { if ( e.ctrlKey || caretInFirstLine( input ) ) {
hist( 'up' ); hist( 'up' );
} }
} else if ( e.keyCode === 40 ) { // down } else if ( e.keyCode === 40 ) {
// down
// go down in history if at end or ctrl-down // go down in history if at end or ctrl-down
if ( e.ctrlKey || caretInLastLine( _in ) ) { if ( e.ctrlKey || caretInLastLine( input ) ) {
hist( 'down' ); hist( 'down' );
} }
} }
setTimeout( recalculateInputHeight, 0 ); setTimeout( recalculateInputHeight, 0 );
//return true;
} }
function inputFocus( e ) { /**
* @param {jQuery.Event} e
*/
function inputFocus() {
if ( sessionContent === null ) { if ( sessionContent === null ) {
// No previous state to clear // No previous state to clear
return; return;
@ -86,7 +96,7 @@
return true; return true;
} }
var firstLineBreak = textbox.value.indexOf( "\n" ); var firstLineBreak = textbox.value.indexOf( '\n' );
return ((firstLineBreak === -1) || (textbox.selectionStart <= firstLineBreak)); return ((firstLineBreak === -1) || (textbox.selectionStart <= firstLineBreak));
} }
@ -97,44 +107,39 @@
return true; return true;
} }
var lastLineBreak = textbox.value.lastIndexOf( "\n" ); var lastLineBreak = textbox.value.lastIndexOf( '\n' );
return ( textbox.selectionEnd > lastLineBreak ); return ( textbox.selectionEnd > lastLineBreak );
} }
function recalculateInputHeight() { function recalculateInputHeight() {
var rows = _in.value.split( /\n/ ).length var rows = input.value.split( /\n/ ).length +
+ 1 // prevent scrollbar flickering in Mozilla // prevent scrollbar flickering in Mozilla
+ ( window.opera ? 1 : 0 ); // leave room for scrollbar in Opera 1 +
// leave room for scrollbar in Opera
( window.opera ? 1 : 0 );
// without this check, it is impossible to select text in Opera 7.60 or Opera 8.0. // without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.
if ( _in.rows !== rows ) { if ( input.rows !== rows ) {
_in.rows = rows; input.rows = rows;
} }
} }
function println( s, type ) { function println( s, type ) {
if ( ( s = String( s ) ) ) { if ( ( s = String( s ) ) ) {
var newdiv = document.createElement( "div" ); var newdiv = document.createElement( 'div' );
newdiv.appendChild( document.createTextNode( s ) ); newdiv.appendChild( document.createTextNode( s ) );
newdiv.className = type; newdiv.className = type;
_out.appendChild( newdiv ); output.appendChild( newdiv );
return newdiv; return newdiv;
} }
} }
function printWithRunin( h, s, type ) {
var div = println( s, type );
var head = document.createElement( "strong" );
head.appendChild( document.createTextNode( h + ": " ) );
div.insertBefore( head, div.firstChild );
}
function printClearBar( msg ) { function printClearBar( msg ) {
$( '<div/>' ) $( '<div>' )
.attr( 'class', 'mw-scribunto-clear' ) .attr( 'class', 'mw-scribunto-clear' )
.text( mw.msg( msg ) ) .text( mw.msg( msg ) )
.appendTo( _out ); .appendTo( output );
} }
function hist( direction ) { function hist( direction ) {
@ -152,7 +157,7 @@
if ( direction === 'up' ) { if ( direction === 'up' ) {
if ( histPos === L - 1 ) { if ( histPos === L - 1 ) {
// Save this entry in case the user hits the down key. // Save this entry in case the user hits the down key.
histList[histPos] = _in.value; histList[histPos] = input.value;
} }
if ( histPos > 0 ) { if ( histPos > 0 ) {
@ -161,65 +166,68 @@
// Set to nothing first for the same reason // Set to nothing first for the same reason
setTimeout( setTimeout(
function () { function () {
_in.value = ''; input.value = '';
_in.value = histList[histPos]; input.value = histList[histPos];
var caretPos = _in.value.length; var caretPos = input.value.length;
if ( _in.setSelectionRange ) { if ( input.setSelectionRange ) {
_in.setSelectionRange( caretPos, caretPos ); input.setSelectionRange( caretPos, caretPos );
} }
}, },
0 0
); );
} }
} } else {
else // down // direction down
{
if ( histPos < L - 1 ) { if ( histPos < L - 1 ) {
histPos++; histPos++;
_in.value = histList[histPos]; input.value = histList[histPos];
} }
else if ( histPos === L - 1 ) { else if ( histPos === L - 1 ) {
// Already on the current entry: clear but save // Already on the current entry: clear but save
if ( _in.value ) { if ( input.value ) {
histList[histPos] = _in.value; histList[histPos] = input.value;
++histPos; ++histPos;
_in.value = ""; input.value = '';
} }
} }
} }
} }
function printQuestion( q ) { function printQuestion( q ) {
println( q, "mw-scribunto-input" ); println( q, 'mw-scribunto-input' );
} }
function printError( er ) { function printError( er ) {
var lineNumberString; var lineNumberString;
lastError = er; // for debugging the shell // for debugging the shell
lastError = er;
if ( er.name ) { if ( er.name ) {
// lineNumberString should not be "", to avoid a very wacky bug in IE 6. // lineNumberString should not be '', to avoid a very wacky bug in IE 6.
lineNumberString = (er.lineNumber !== undefined) ? (" on line " + er.lineNumber + ": ") : ": "; lineNumberString = (er.lineNumber !== undefined) ? (' on line ' + er.lineNumber + ': ') : ': ';
// Because IE doesn't have error.toString. // Because IE doesn't have error.toString.
println( er.name + lineNumberString + er.message, "mw-scribunto-error" ); println( er.name + lineNumberString + er.message, 'mw-scribunto-error' );
} else { } else {
println( er, "mw-scribunto-error" ); // Because security errors in Moz /only/ have toString. // Because security errors in Moz /only/ have toString.
println( er, 'mw-scribunto-error' );
} }
} }
function setPending() { function setPending() {
pending = true; pending = true;
_in.readOnly = true; input.readOnly = true;
_$spinner.insertBefore( _in ); $spinner.insertBefore( input );
} }
function clearPending() { function clearPending() {
_$spinner.remove(); $spinner.remove();
pending = false; pending = false;
_in.readOnly = false; input.readOnly = false;
} }
function go() { function go() {
var params, api, content, sentContent;
if ( pending ) { if ( pending ) {
// If there is an XHR request pending, don't send another one // If there is an XHR request pending, don't send another one
// We set readOnly on the textarea to give a UI indication, this is // We set readOnly on the textarea to give a UI indication, this is
@ -227,35 +235,36 @@
return; return;
} }
question = _in.value; question = input.value;
if ( question === "" ) { if ( question === '' ) {
return; return;
} }
histList[histList.length - 1] = question; histList[histList.length - 1] = question;
histList[histList.length] = ""; histList[histList.length] = '';
histPos = histList.length - 1; histPos = histList.length - 1;
// Unfortunately, this has to happen *before* the script is run, so that // Unfortunately, this has to happen *before* the script is run, so that
// print() output will go in the right place. // print() output will go in the right place.
_in.value = ''; input.value = '';
// can't preventDefault on input, so also clear it later // can't preventDefault on input, so also clear it later
setTimeout( function () { setTimeout( function () {
_in.value = ""; input.value = '';
}, 0 ); }, 0 );
recalculateInputHeight(); recalculateInputHeight();
printQuestion( question ); printQuestion( question );
var params = { params = {
action: 'scribunto-console', action: 'scribunto-console',
title: mw.config.get( 'wgPageName' ), title: mw.config.get( 'wgPageName' ),
question: question question: question
}; };
var content = getContent(); content = getContent();
var sentContent = false; sentContent = false;
if ( !sessionKey || sessionContent !== content ) { if ( !sessionKey || sessionContent !== content ) {
params.clear = true; params.clear = true;
params.content = content; params.content = content;
@ -269,17 +278,17 @@
clearNextRequest = false; clearNextRequest = false;
} }
var api = new mw.Api(); api = new mw.Api();
setPending(); setPending();
api.post( params, { api.post( params )
ok: function ( result ) { .done( function ( result ) {
if ( result.sessionIsNew === '' && !sentContent ) { if ( result.sessionIsNew === '' && !sentContent ) {
// Session was lost. Resend query, with content // Session was lost. Resend query, with content
printClearBar( 'scribunto-console-cleared-session-lost' ); printClearBar( 'scribunto-console-cleared-session-lost' );
sessionContent = null; sessionContent = null;
clearPending(); clearPending();
_in.value = params.question; input.value = params.question;
go(); go();
return; return;
} }
@ -292,25 +301,23 @@
println( result.print, 'mw-scribunto-print' ); println( result.print, 'mw-scribunto-print' );
} }
if ( result['return'] !== '' ) { if ( result['return'] !== '' ) {
println( result['return'], "mw-scribunto-normalOutput" ); println( result['return'], 'mw-scribunto-normalOutput' );
} }
} }
clearPending(); clearPending();
setTimeout( refocus, 0 ); setTimeout( refocus, 0 );
}, } )
.fail( function ( code, result ) {
err: function ( code, result ) { if ( result.error && result.error.info ) {
if ( 'error' in result && 'info' in result.error ) {
printError( result.error.info ); printError( result.error.info );
} else if ( 'exception' in result ) { } else if ( result.exception ) {
printError( 'Error sending API request: ' + result.exception ); printError( 'Error sending API request: ' + result.exception );
} else { } else {
console.log( result ); mw.log( result );
printError( 'error' ); printError( 'error' );
} }
clearPending(); clearPending();
setTimeout( refocus, 0 ); setTimeout( refocus, 0 );
}
} ); } );
} }
@ -325,33 +332,36 @@
} }
} }
function onClearClick( e ) { /**
* @param {jQuery.Event} e
*/
function onClearClick() {
$( '#mw-scribunto-output' ).empty(); $( '#mw-scribunto-output' ).empty();
clearNextRequest = true; clearNextRequest = true;
refocus(); refocus();
} }
mw.scribunto.edit = { mw.scribunto.edit = {
'init': function () { init: function () {
var action = mw.config.get( 'wgAction' ); var action = mw.config.get( 'wgAction' );
if ( action === 'edit' || action === 'submit' || action === 'editredlink' ) { if ( action === 'edit' || action === 'submit' || action === 'editredlink' ) {
this.initEditPage(); this.initEditPage();
} }
}, },
'initEditPage': function () { initEditPage: function () {
var console = document.getElementById( 'mw-scribunto-console' ); var console = document.getElementById( 'mw-scribunto-console' );
if ( !console ) { if ( !console ) {
return; return;
} }
$( '<fieldset/>' ) $( '<fieldset>' )
.attr( 'class', 'mw-scribunto-console-fieldset' ) .attr( 'class', 'mw-scribunto-console-fieldset' )
.append( $( '<legend/>' ).text( mw.msg( 'scribunto-console-title' ) ) ) .append( $( '<legend>' ).text( mw.msg( 'scribunto-console-title' ) ) )
.append( $( '<div id="mw-scribunto-output"></div>' ) ) .append( $( '<div id="mw-scribunto-output"></div>' ) )
.append( .append(
$( '<div/>' ).append( $( '<div>' ).append(
$( '<textarea/>' ) $( '<textarea>' )
.attr( { .attr( {
id: 'mw-scribunto-input', id: 'mw-scribunto-input',
'class': 'mw-scribunto-input', 'class': 'mw-scribunto-input',
@ -365,8 +375,8 @@
) )
) )
.append( .append(
$( '<div/>' ).append( $( '<div>' ).append(
$( '<input/>' ) $( '<input>' )
.attr( { .attr( {
type: 'button', type: 'button',
value: mw.msg( 'scribunto-console-clear' ) value: mw.msg( 'scribunto-console-clear' )
@ -374,13 +384,14 @@
.bind( 'click', onClearClick ) .bind( 'click', onClearClick )
) )
) )
.wrap( '<form/>' ) .wrap( '<form>' )
.appendTo( console ); .appendTo( console );
initConsole(); initConsole();
} }
}; };
$( document ).ready( function () { $( function () {
mw.scribunto.edit.init(); mw.scribunto.edit.init();
} ); } );

View file

@ -1,50 +1,47 @@
( function ( $, mw ) { ( function ( $, mw ) {
mw.scribunto = { var scribunto = mw.scribunto = {
errors: null, errors: null,
'setErrors': function ( errors ) { setErrors: function ( errors ) {
this.errors = errors; scribunto.errors = errors;
}, },
'init': function () { init: function () {
var regex = /^mw-scribunto-error-(\d+)/, var regex = /^mw-scribunto-error-(\d+)/,
that = this, $dialog = $( '<div>' );
dialog = $( '<div>' );
dialog.dialog( { $dialog.dialog( {
title: mw.msg( 'scribunto-parser-dialog-title' ), title: mw.msg( 'scribunto-parser-dialog-title' ),
autoOpen: false autoOpen: false
} ); } );
$( '.scribunto-error' ).each( function ( index, span ) { $( '.scribunto-error' ).each( function ( index, span ) {
var matches = regex.exec( span.id ); var errorId,
matches = regex.exec( span.id );
if ( matches === null ) { if ( matches === null ) {
console.log( "mw.scribunto.init: regex mismatch!" ); mw.log( 'mw.scribunto.init: regex mismatch!' );
return; return;
} }
var errorId = parseInt( matches[1] ); errorId = parseInt( matches[1], 10 );
$( span ) $( span ).on( 'click', function ( e ) {
.bind( 'click', function ( evt ) { if ( typeof scribunto.errors[ errorId ] !== 'string' ) {
if ( typeof that.errors[ errorId ] !== 'string' ) { mw.log( 'mw.scribunto.init: error ' + matches[1] + ' not found, ' +
console.log( "mw.scribunto.init: error " + matches[1] + " not found, " + 'mw.loader.using() callback may not have been called yet.' );
"mw.loader.using() callback may not have been called yet." );
return; return;
} }
var error = that.errors[ errorId ]; var error = scribunto.errors[ errorId ];
dialog $dialog
.dialog( 'close' ) .dialog( 'close' )
.html( error ) .html( error )
.dialog( 'option', 'position', [ evt.clientX + 5, evt.clientY + 5 ] ) .dialog( 'option', 'position', [ e.clientX + 5, e.clientY + 5 ] )
.dialog( 'open' ); .dialog( 'open' );
} ); } );
} ); } );
} }
}; };
$( document ).ready( function () { $( mw.scribunto.init );
mw.scribunto.init();
} );
} ) ( jQuery, mediaWiki ); } ) ( jQuery, mediaWiki );