mediawiki-extensions-Visual.../modules/parser/ext.core.AttributeExpander.js
Gabriel Wicke 8368e17d6a Biggish token transform system refactoring
* All parser pipelines including tokenizer and DOM stuff are now constructed
  from a 'recipe' data structure in a ParserPipelineFactory.

* All sub-pipelines of these can now be cached

* Event registrations to a pipeline are directly forwarded to the last
  pipeline member to save relatively expensive event forwarding.

* Some APIs for on-demand expansion / format conversion of parameters from
  parser functions are added:

  param.to('tokens/expanded', cb)
  param.to('text/wiki', cb) (this does not work yet)

  All parameters are additionally wrapped into a Param object that provides
  method for positional parameter naming (.named() or conversion to a dict
  (.dict()).

* The async token transform manager is now separated from a frame object, with
  the frame holding arguments, an on-demand expansion method and loop checks.

* Only keys of template parameters are now expanded. Parser functions or
  template arguments trigger an expansion on-demand. This (unsurprisingly)
  makes a big performance difference with typical switch-heavy template
  systems.

* Return values from async transforms are no longer used in favor of plain
  callbacks. This saves the complication of having to maintain two code paths.
  A trick in transformTokens still avoids the construction of unneeded
  TokenAccumulators.

* The results of template expansions are no longer buffered.

* 301 parser tests are passing

Known issues:

* Cosmetic cleanup remains to do
* Some parser functions do not support async expansions yet, and need to be
  modified.

Change-Id: I1a7690baffbe8141cadf67270904a1b2e1df879a
2012-04-25 16:51:36 +02:00

67 lines
1.8 KiB
JavaScript

/**
* Generic attribute expansion handler.
*
* @author Gabriel Wicke <gwicke@wikimedia.org>
*/
var $ = require('jquery'),
request = require('request'),
events = require('events'),
qs = require('querystring'),
ParserFunctions = require('./ext.core.ParserFunctions.js').ParserFunctions,
AttributeTransformManager = require('./mediawiki.TokenTransformManager.js')
.AttributeTransformManager,
defines = require('./mediawiki.parser.defines.js');
function AttributeExpander ( manager ) {
this.manager = manager;
// XXX: only register for tag tokens?
manager.addTransform( this.onToken.bind(this),
this.rank, 'any' );
}
// constants
AttributeExpander.prototype.rank = 1.11;
/**
* Token handler
*
* Expands target and arguments (both keys and values) and either directly
* calls or sets up the callback to _expandTemplate, which then fetches and
* processes the template.
*/
AttributeExpander.prototype.onToken = function ( token, frame, cb ) {
//console.warn( 'AttributeExpander.onToken', JSON.stringify( token ) );
if ( (token.constructor === TagTk ||
token.constructor === SelfclosingTagTk) &&
token.attribs &&
token.attribs.length ) {
token = $.extend( {}, token );
token.attribs = token.attribs.slice();
var atm = new AttributeTransformManager(
this.manager,
this._returnAttributes.bind( this, token, cb )
);
cb( { async: true } );
atm.process( token.attribs );
} else {
cb ( { token: token } );
}
};
/**
* Callback for attribute expansion in AttributeTransformManager
*/
AttributeExpander.prototype._returnAttributes = function ( token, cb,
attributes )
{
this.manager.env.dp( 'AttributeExpander._returnAttributes: ',attributes );
token.attribs = attributes;
cb( { token: token } );
};
if (typeof module == "object") {
module.exports.AttributeExpander = AttributeExpander;
}