r86558 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r86557‎ | r86558 | r86559 >
Date:22:32, 20 April 2011
Author:happy-melon
Status:resolved (Comments)
Tags:
Comment:
Auto suggest tags.
Modified paths:
  • /trunk/extensions/CodeReview/CodeReview.php (modified) (history)
  • /trunk/extensions/CodeReview/modules/ext.codereview.js (modified) (history)

Diff [purge]

Index: trunk/extensions/CodeReview/modules/ext.codereview.js
@@ -0,0 +1,82 @@
 2+jQuery( function( $ ) {
 3+ // Animate the add-tags input to suggest existing tabs
 4+ $('#wpTag').suggestions( {
 5+ fetch: function( query ) {
 6+ var $this = $(this);
 7+ var doUpdate = function(){
 8+ var currentText = $this.val();
 9+ var currentTags = currentText.split( /, */ );
 10+ var lastTag, doneTags;
 11+ if( currentTags.length == 0 ){
 12+ lastTag = doneTags = '';
 13+ } else {
 14+ lastTag = currentTags.pop();
 15+ doneTags = currentTags.length > 0
 16+ ? currentTags.join( ', ' ) + ', '
 17+ : '';
 18+ }
 19+ var tags = $this.data( 'suggestions' );
 20+
 21+ var suggestions = [];
 22+ for( var i in tags ){
 23+ // Don't suggest a tag that's already been added
 24+ var good = true;
 25+ for( var j in currentTags ){
 26+ if( currentTags[j] === tags[i] ){
 27+ good = false;
 28+ }
 29+ }
 30+ if( good && tags[i].indexOf( lastTag ) != -1 ){
 31+ suggestions.push( doneTags + tags[i] );
 32+ }
 33+ }
 34+
 35+ $this.suggestions( 'suggestions', suggestions );
 36+ };
 37+ if( $(this).data( 'suggestions' ) ){
 38+ doUpdate();
 39+ } else {
 40+ // Need to get the tags from the API
 41+ var request = $.getJSON(
 42+ mw.config.get( 'wgScriptPath' ) + '/api.php',
 43+ {
 44+ action: 'query',
 45+ list: 'codetags',
 46+ ctrepo: mw.config.get( 'wgCodeReviewRepository' ),
 47+ format: 'json'
 48+ },
 49+ function( data ) {
 50+ if ( data && 'query' in data && 'codetags' in data.query ) {
 51+ var d = data.query.codetags;
 52+ var tags = [];
 53+ for ( var i in d ){
 54+ tags.push( d[i].name );
 55+ }
 56+ $this.data( 'suggestions', tags );
 57+ // Go again
 58+ doUpdate();
 59+ }
 60+ }
 61+ );
 62+ }
 63+ $(this).data( 'request', request );
 64+ },
 65+ cancel: function () {
 66+ var request = $(this).data( 'request' );
 67+ // If the delay setting has caused the fetch to have not even happend yet, the request object will
 68+ // have never been set
 69+ if ( request && $.isFunction( request.abort ) ) {
 70+ request.abort();
 71+ $(this).removeData( 'request' );
 72+ }
 73+ },
 74+ delay: 0,
 75+ positionFromLeft: $( 'body' ).hasClass( 'rtl' ),
 76+ highlightInput: true
 77+ } )
 78+ .bind( 'paste cut drop', function( e ) {
 79+ // make sure paste and cut events from the mouse and drag&drop events
 80+ // trigger the keypress handler and cause the suggestions to update
 81+ $( this ).trigger( 'keypress' );
 82+ } );
 83+});
\ No newline at end of file
Index: trunk/extensions/CodeReview/CodeReview.php
@@ -145,6 +145,7 @@
146146 $wgResourceModules['ext.codereview'] = array(
147147 'styles' => 'ext.codereview.css',
148148 'scripts' => 'ext.codereview.js',
 149+ 'dependencies' => 'jquery.suggestions',
149150 ) + $commonModuleInfo;
150151
151152 // On-demand diff loader for CodeRevisionView:
@@ -289,3 +290,18 @@
290291 $files[] = dirname( __FILE__ ) . '/tests/CodeReviewTest.php';
291292 return true;
292293 }
 294+
 295+# Add global JS vars
 296+$wgHooks['MakeGlobalVariablesScript'][] = 'efCodeReviewResourceLoaderGlobals';
 297+
 298+function efCodeReviewResourceLoaderGlobals( &$values ){
 299+ # Bleugh, this is horrible
 300+ global $wgTitle;
 301+ if( $wgTitle->isSpecial( 'Code' ) ){
 302+ $bits = explode( '/', $wgTitle->getText() );
 303+ if( isset( $bits[1] ) ){
 304+ $values['wgCodeReviewRepository'] = $bits[1];
 305+ }
 306+ }
 307+ return true;
 308+}
\ No newline at end of file

Sign-offs

UserFlagDate
Catropeinspected08:28, 21 April 2011
Catropetested08:48, 21 April 2011

Follow-up revisions

RevisionCommit summaryAuthorDate
r86659Follow-up r41810: avoid multiple API calls.happy-melon19:36, 21 April 2011

Comments

#Comment by Catrope (talk | contribs)   08:44, 21 April 2011

Cool feature, thanks for implementing this!

A few remarks:

  • Before calling $.getJSON(), you should check whether there's already a request running by checking against $(this).data( 'request' ) . Right now multiple API requests will be made if you send a rapid succession of key presses into the textbox the first time (this is the fixme)
  • It would be cool if you could use the advanced features that $.suggestions offers (I don't remember how they work, it's been almost two years) to only display baz instead of foo, bar, baz when entering a third tag into the text box
  • It would be nice if the autocompletion takes tags already added to the revision (but not present in the text box) into account and doesn't suggest them again
  • Once you're using that tags-already-present data, you should already be halfway writing a similar suggestion feature for the remove tags text box, which would be awesome :)
#Comment by Happy-melon (talk | contribs)   19:41, 21 April 2011

The multiple-requests thing is fixed in r86659. Me writing javascript is kind of like extracting teeth, so I don't intend to spend too much time extending this; it's more a reaction to the proliferation of near-identical tags. Since the list of current tags are visible the line above the input boxes, I'm not convinced that suggestions for the remove box are really necessary; if anything, we want to have some sort of click-me-to-delete-this-tag functionality on the tags themselves, and hide the input field entirely for JS-enabled browsers.

#Comment by Catrope (talk | contribs)   21:59, 21 April 2011

The multiple-requests thing is fixed in r86659.

Thanks.

Me writing javascript is kind of like extracting teeth, so I don't intend to spend too much time extending this; it's more a reaction to the proliferation of near-identical tags.

No worries. You did a good job on this one though.

Since the list of current tags are visible the line above the input boxes, I'm not convinced that suggestions for the remove box are really necessary; if anything, we want to have some sort of click-me-to-delete-this-tag functionality on the tags themselves, and hide the input field entirely for JS-enabled browsers.

Very good idea.

Status & tagging log