mediawiki-extensions-Visual.../modules/parser/ext.core.NoIncludeOnly.js
Gabriel Wicke 9ae572cca0 Fixes to template expansion / token transform managers, 296 tests passing.
* Convert isNoInclude logic to positive isInclude throughout and set it
  properly on attribute pipelines. Also don't cache non-include pipelines.
* Add a --pagename parameter to parse.js, which sets the page name in the
  environment. This is then returned by {{PAGENAME}}. Not the final solution,
  but useful for taxobox testing as taxons are selected based on PAGENAME.
* Add rudimentary pagenamebase parser function

Change-Id: If9c0be4c255200d0f2a30f02e5619437b4fd8f12
2012-04-11 16:34:27 +02:00

139 lines
3.7 KiB
JavaScript

/**
* Simple noinclude / onlyinclude implementation. Strips all tokens in
* noinclude sections.
*
* @author Gabriel Wicke <gwicke@wikimedia.org>
*/
var TokenCollector = require( './ext.util.TokenCollector.js' ).TokenCollector;
/**
* OnlyInclude sadly forces synchronous template processing, as it needs to
* hold onto all tokens in case an onlyinclude block is encountered later.
*/
function OnlyInclude( manager, isInclude ) {
this.manager = manager;
if ( isInclude ) {
this.accum = [];
this.inOnlyInclude = false;
this.foundOnlyInclude = false;
// register for 'any' token, collect those
this.manager.addTransform( this.onAnyInclude.bind( this ), this.rank, 'any' );
} else {
// just convert onlyinclude tokens into meta tags with rt info
this.manager.addTransform( this.onOnlyInclude.bind( this ), this.rank,
'tag', 'onlyinclude' );
}
}
OnlyInclude.prototype.rank = 0.001; // Before any further processing
OnlyInclude.prototype.onOnlyInclude = function ( token, manager ) {
var meta = new TagTk( 'meta' );
meta.dataAttribs = { strippedTokens: [token] };
return { token: meta };
};
OnlyInclude.prototype.onAnyInclude = function ( token, manager ) {
//this.manager.env.dp( 'onAnyInclude', token, this );
if ( token.constructor === EOFTk ) {
this.inOnlyInclude = false;
if ( this.accum.length && ! this.foundOnlyInclude ) {
var res = this.accum;
res.push( token );
this.accum = [];
this.manager.setTokensRank( res, this.rank + 0.001 );
return { tokens: res };
} else {
this.foundOnlyInclude = false;
this.accum = [];
return { token: token };
}
} else if ( ( token.constructor === TagTk ||
token.constructor === EndTagTk ||
token.constructor === SelfclosingTagTk ) &&
token.name === 'onlyinclude' ) {
var meta;
if ( ! this.inOnlyInclude ) {
this.foundOnlyInclude = true;
this.inOnlyInclude = true;
// wrap collected tokens into meta tag for round-tripping
meta = new TagTk( 'meta' );
this.accum.push( token );
meta.dataAttribs = { strippedTokens: this.accum };
this.accum = [];
return meta;
} else {
this.inOnlyInclude = false;
meta = new TagTk( 'meta' );
meta.dataAttribs = { strippedTokens: [token] };
}
meta.rank = this.rank;
return { token: meta };
} else {
if ( this.inOnlyInclude ) {
token.rank = this.rank;
return { token: token };
} else {
this.accum.push( token );
return { };
}
}
};
function NoInclude( manager, isInclude ) {
new TokenCollector(
manager,
function ( tokens ) {
if ( isInclude ) {
manager.env.tp( 'noinclude stripping' );
return {};
} else {
tokens.shift();
if ( tokens.length &&
tokens[tokens.length - 1].constructor !== EOFTk ) {
tokens.pop();
}
return { tokens: tokens };
}
}, // just strip it all..
true, // match the end-of-input if </noinclude> is missing
0.01, // very early in stage 1, to avoid any further processing.
'tag',
'noinclude'
);
}
// XXX: Preserve includeonly content in meta tag (data attribute) for
// round-tripping!
function IncludeOnly( manager, isInclude ) {
new TokenCollector(
manager,
function ( tokens ) {
if ( isInclude ) {
tokens.shift();
if ( tokens.length &&
tokens[tokens.length - 1].constructor !== EOFTk ) {
tokens.pop();
}
return { tokens: tokens };
} else {
manager.env.tp( 'includeonly stripping' );
return {};
}
},
true, // match the end-of-input if </noinclude> is missing
0.01, // very early in stage 1, to avoid any further processing.
'tag',
'includeonly'
);
}
if (typeof module == "object") {
module.exports.NoInclude = NoInclude;
module.exports.IncludeOnly = IncludeOnly;
module.exports.OnlyInclude = OnlyInclude;
}