User:Krinkle/Extension review/InlineCategorizer

From mediawiki.org

Prequel[edit]

  • Originally written by mdale in the JS2 branch at /branches/js2-work
  • Also authored by werdna, who added it to mediawiki core in r56032. Which was then removed by tstartling in r59446 to be further worked on in the js2-work branch
  • In r92110 diebuche brought ajaxcategories.js back from trunk from before tstartling removed it. (log)
    • Hm.. perhaps it should've been copied from /branches/js2-work/phase3/js/ajaxcategories.js (r60225) instead /trunk/phase3/js2/ajaxcategories.js:r58959, the branch seems to have a more recent version!
  • After several larger and smaller reviews by catrope and krinkle
  • .. it was removed again from trunk into an extension by krinkle, because there is simply too much work to be done and the code base is not near acceptable for core, yet.

This page serves as a planning page for this module.

  • What are the requirements
  • Proposals for implementations.
  • Do we start from scratch ? Or from /branches/js2-work/phase3/js/ ? Or from the rewrite that diebuche and krinkle did in early 2011 ?
    • Currently the latter is taken as starting point in the extensions directory.

Problems[edit]

Object oriented model[edit]

There seems to be little to no separation between general logic and the user interface events. The only way to property perform actions is by triggering native events. Also the code extracts information about the current active state on the contents of the DOM (instead of having a local object with the properties and keeping that in sync with the frontend).

The proposed solution would be to split the module up into two parts. An API object with methods and a UI object with methods. The API object methods are called from the event handlers in the UI methods, but can also be called directly (ie. by other gadgets or by unit tests). And, of course, not a single call should be made from an API method to a UI method. Connection between the two works through callbacks.

A short sample / proposal (could be moved to a subpage for wiki-programming)

/**
 * InlineCategorizer.api.js
 */

var ic = mw.InlineCategorizer, api = ic.api = {

  init: function() {
    ...
    categorylinksCache[mw.config.get( 'wgPageName' )] = mw.config.get( 'wgCategories' );
  },

  getWikitext: function( pageName, success, error ) {
    // Ajax request to get the wikitext of a page.
    // Calls success( .. ) or error( .. ) from the ajax callback
  },

  fetchCategorylinks: function( pageName, callback ) {
    /*
      Something like:
      if ( pageName in categorylinksCache ) {
        callback( categorylinksCache[pageName] );
        return;
      }
      // XXX: Ajax request to get categorylinks for pagename
        categorylinksCache[pageName] = data;
        callback( data );
    */
  }

  hasCategory: function( pageName, categoryName, callback ) {
      api.fetchCategorylinks( pageName, function( cats ) {
        callback( $.inArray( categoryName, cats ) );
    }
  }
}

/**
 * InlineCategorizer.ui.js
 */
var ic = mw.InlineCategorizer, ui = ic.ui = {
  ...
  x.find( 'mw-inlinecategorizer-add' ).click( function( e ) {
    ic.api.hasCategory( pageName, new mw.Title( $input.val() ).getPrefixedText(), function( hasCat ) {
     if ( hasCat ) {
        // Don't add duplicate, show error
      } else {
        // Create link and add to #mw-catlinks
      }
    }

}

Parser[edit]

Right now it understands and avoids <nowiki>-tags and <!-- comments --> to some degree, but it doesn't handle <pre>-tags yet.