r110406 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r110405‎ | r110406 | r110407 >
Date:16:50, 31 January 2012
Author:gwicke
Status:deferred
Tags:
Comment:
A few more debug helpers including a --trace mode for light debugging. Some
improvements to parser functions on the way to support the cite extensions.
Preparation for generic template and template arg in attribute support. 222
parser tests now passing.
Modified paths:
  • /trunk/extensions/VisualEditor/modules/parser/ext.core.NoIncludeOnly.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/ext.core.ParserFunctions.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/ext.core.TemplateHandler.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.environment.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/parse.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt (modified) (history)

Diff [purge]

Index: trunk/extensions/VisualEditor/modules/parser/ext.core.NoIncludeOnly.js
@@ -12,7 +12,7 @@
1313 manager,
1414 function ( tokens ) {
1515 if ( isInclude ) {
16 - manager.env.dp( 'noinclude stripping', tokens );
 16+ manager.env.tp( 'noinclude stripping' );
1717 return {};
1818 } else {
1919 tokens.shift();
@@ -42,6 +42,7 @@
4343 }
4444 return { tokens: tokens };
4545 } else {
 46+ manager.env.tp( 'includeonly stripping' );
4647 return {};
4748 }
4849 },
Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js
@@ -214,6 +214,11 @@
215215 }
216216 // Transform token with side effects
217217 res = transformer.transform( res.token, cb, this, this.prevToken );
 218+ // XXX: Sync transform:
 219+ // res = transformer.transform( res.token, this, this.prevToken );
 220+ // XXX: Async transform:
 221+ // res = transformer.transform( res.token, this, cb );
 222+
218223 // if multiple tokens or null token: process returned tokens (in parent)
219224 if ( !res.token || // async implies tokens instead of token, so no
220225 // need to check explicitly
@@ -725,7 +730,7 @@
726731
727732 // transform each argument (key and value), and handle asynchronous returns
728733 for ( var i = 0, l = attributes.length; i < l; i++ ) {
729 - kv = { key: [], value: [] };
 734+ var kv = { key: [], value: [] };
730735 this.kvs.push( kv );
731736
732737 // Assume that the return is async, will be decremented in callback
Index: trunk/extensions/VisualEditor/modules/parser/parse.js
@@ -23,6 +23,11 @@
2424 'boolean': true,
2525 'default': false
2626 },
 27+ 'trace': {
 28+ description: 'Trace mode (light debugging), implied by --debug',
 29+ 'boolean': true,
 30+ 'default': false
 31+ },
2732 'maxdepth': {
2833 description: 'Maximum expansion depth',
2934 'boolean': false,
@@ -52,6 +57,7 @@
5358 fetchTemplates: argv.fetchTemplates,
5459 // enable/disable debug output using this switch
5560 debug: argv.debug,
 61+ trace: argv.trace,
5662 maxDepth: argv.maxdepth
5763 } ),
5864 parser = new ParserPipeline( env );
Index: trunk/extensions/VisualEditor/modules/parser/ext.core.ParserFunctions.js
@@ -14,10 +14,10 @@
1515
1616 ParserFunctions.prototype['pf_#if'] = function ( target, argList, argDict ) {
1717 if ( target.trim() !== '' ) {
18 - this.manager.env.dp('#if, first branch', argDict[1] );
 18+ this.manager.env.dp('#if, first branch', target.trim(), argDict[1] );
1919 return argDict[1] || [];
2020 } else {
21 - this.manager.env.dp('#if, second branch', argDict[2] );
 21+ this.manager.env.dp('#if, second branch', target.trim(), argDict[2] );
2222 return argDict[2] || [];
2323 }
2424 };
@@ -25,10 +25,11 @@
2626 ParserFunctions.prototype['pf_#switch'] = function ( target, argList, argDict ) {
2727 this.manager.env.dp( 'switch enter: ' + target.trim() +
2828 ' looking in ', argDict );
29 - if ( target.trim() in argDict ) {
30 - this.manager.env.dp( 'switch found: ' + target.trim() +
31 - ' res=', argDict[target.trim()] );
32 - return argDict[target.trim()];
 29+ target = target.trim();
 30+ if ( target in argDict ) {
 31+ this.manager.env.dp( 'switch found: ' + target +
 32+ ' res=', argDict[target] );
 33+ return argDict[target];
3334 } else if ( '#default' in argDict ) {
3435 return argDict['#default'];
3536 } else {
@@ -149,9 +150,9 @@
150151 m: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); },
151152 M: function() { return Date.replaceChars.shortMonths[this.getMonth()]; },
152153 n: function() { return this.getMonth() + 1; },
153 - t: function() { var d = new Date(); return new Date(d.getFullYear(), d.getMonth(), 0).getDate() }, // Fixed now, gets #days of date
 154+ t: function() { var d = new Date(); return new Date(d.getFullYear(), d.getMonth(), 0).getDate(); }, // Fixed now, gets #days of date
154155 // Year
155 - L: function() { var year = this.getFullYear(); return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)); }, // Fixed now
 156+ L: function() { var year = this.getFullYear(); return (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)); }, // Fixed now
156157 o: function() { var d = new Date(this.valueOf()); d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); return d.getFullYear();}, //Fixed now
157158 Y: function() { return this.getFullYear(); },
158159 y: function() { return ('' + this.getFullYear()).substr(2); },
@@ -180,23 +181,46 @@
181182 U: function() { return this.getTime() / 1000; }
182183 };
183184
 185+ParserFunctions.prototype['pf_#ifexpr'] = function ( target, argList, argDict ) {
 186+ this.manager.env.dp( '#ifexp: ' + JSON.stringify( argList ) );
 187+ var res;
 188+ try {
 189+ var f = new Function ( 'return (' + target + ')' );
 190+ res = f();
 191+ } catch ( e ) {
 192+ return [{type: 'TEXT', value: 'class="error" in expression ' + target }];
 193+ }
 194+ if ( res ) {
 195+ return ( argList[0] && argList[0][1] ) || [];
 196+ } else {
 197+ return ( argList[1] && argList[1][1] ) || [];
 198+ }
 199+};
 200+ParserFunctions.prototype['pf_#iferror'] = function ( target, argList, argDict ) {
 201+ if ( target.indexOf( 'class="error"' ) >= 0 ) {
 202+ return ( argList[0] && argList[0][1] ) || [];
 203+ } else {
 204+ return ( argList[1] && argList[1][1] ) || [];
 205+ }
 206+};
 207+ParserFunctions.prototype['pf_#expr'] = function ( target, argList, argDict ) {
 208+ var res;
 209+ try {
 210+ var f = new Function ( 'return (' + target + ')' );
 211+ res = f();
 212+ } catch ( e ) {
 213+ return [{type: 'TEXT', value: 'class="error" in expression ' + target }];
 214+ }
 215+ return [{type: 'TEXT', value: res.toString()}];
 216+};
184217
185218
 219+
186220 /**
187221 * Stub section: Pick any of these and actually implement them!
188222 */
189223
190224 // FIXME
191 -ParserFunctions.prototype['pf_#ifexpr'] = function ( target, argList, argDict ) {
192 - this.manager.env.dp( '#ifexp: ' + JSON.stringify( argList ) );
193 - return ( argList[0] && argList[0][1] ) || [];
194 -};
195 -ParserFunctions.prototype['pf_#iferror'] = function ( target, argList, argDict ) {
196 - return ( argList[0] && argList[0][1] ) || [];
197 -};
198 -ParserFunctions.prototype['pf_#expr'] = function ( target, argList, argDict ) {
199 - return ( argList[0] && argList[0][1] ) || [];
200 -};
201225 ParserFunctions.prototype['pf_#ifexist'] = function ( target, argList, argDict ) {
202226 return ( argList[0] && argList[0][1] ) || [];
203227 };
@@ -225,12 +249,28 @@
226250 return [{type: 'TEXT', value: target}];
227251 };
228252 ParserFunctions.prototype['pf_urlencode'] = function ( target, argList, argDict ) {
 253+ this.manager.env.tp( 'urlencode: ' + target );
 254+ return [{type: 'TEXT', value: target.trim()}];
 255+};
 256+ParserFunctions.prototype['pf_anchorencode'] = function ( target, argList, argDict ) {
229257 return [{type: 'TEXT', value: target}];
230258 };
231259 ParserFunctions.prototype['pf_namespace'] = function ( target, argList, argDict ) {
232260 return [{type: 'TEXT', value: 'Main'}];
233261 };
 262+ParserFunctions.prototype['pf_protectionlevel'] = function ( target, argList, argDict ) {
 263+ return [{type: 'TEXT', value: ''}];
 264+};
 265+ParserFunctions.prototype['pf_ns'] = function ( target, argList, argDict ) {
 266+ return [{type: 'TEXT', value: target}];
 267+};
234268
 269+ParserFunctions.prototype['pf_subjectspace'] = function ( target, argList, argDict ) {
 270+ return [{type: 'TEXT', value: 'Main'}];
 271+};
 272+ParserFunctions.prototype['pf_talkspace'] = function ( target, argList, argDict ) {
 273+ return [{type: 'TEXT', value: 'Talk'}];
 274+};
235275
236276 if (typeof module == "object") {
237277 module.exports.ParserFunctions = ParserFunctions;
Index: trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt
@@ -629,7 +629,7 @@
630630 extlink
631631 = "["
632632 & { return setFlag('extlink'); }
633 - target:url
 633+ target:(url / tplarg / template)
634634 space*
635635 text:inlineline?
636636 "]" {
@@ -722,7 +722,7 @@
723723 var obj = {
724724 type: 'SELFCLOSINGTAG',
725725 name: 'template',
726 - attribs: [['data-target', JSON.stringify(target)]],
 726+ attribs: [], //[['data-target', JSON.stringify(target)]],
727727 orderedArgs: params,
728728 //args: {},
729729 target: target
@@ -748,6 +748,7 @@
749749 // parser only recognizes known self-closing tags for now, so use an
750750 // explicit end tag for now.
751751 //console.log(pp(obj));
 752+ //console.log( 'tokenizer template ' + JSON.stringify( target ));
752753 return obj;
753754 }
754755
@@ -770,12 +771,13 @@
771772 };
772773 if (params && params.length) {
773774 // HACK, not final.
774 - obj.attribs.push(['data-defaultvalue', params[0][1]]);
775 - obj.attribs.push(['data-json-args', JSON.stringify(params)]);
 775+ //obj.attribs.push(['data-defaultvalue', params[0][1]]);
 776+ //console.log(JSON.stringify(params, null, 2));
 777+ //obj.attribs.push(['data-json-args', JSON.stringify(params)]);
776778 obj.defaultvalue = params[0][1].length ? params[0][1] :
777779 [{type: 'TEXT', value: ''}];
778780 }
779 - //console.log( 'tokenizer tplarg ' + JSON.stringify( obj ));
 781+ //console.log( 'tokenizer tplarg ' + JSON.stringify( obj, null, 2 ));
780782 return obj;
781783 }
782784
Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js
@@ -88,6 +88,9 @@
8989 */
9090 this.treeBuilder = new FauxHTML5.TreeBuilder();
9191 this.treeBuilder.listenForTokensFrom( this.tokenPostProcessor );
 92+ //this.tokenPostProcessor.on('chunk', function( c ) {
 93+ // console.log( JSON.stringify( c, null, 2 ));
 94+ //} );
9295
9396 /**
9497 * Final processing on the HTML DOM.
@@ -233,7 +236,7 @@
234237
235238 ParserPipeline.prototype.cachePipeline = function ( inputType, pipelinePart, pipe ) {
236239 var cache = this.pipelineCache[inputType][pipelinePart];
237 - if ( cache && cache.length < 5 ) {
 240+ if ( cache && cache.length < 2 ) {
238241 cache.push( pipe );
239242 }
240243 };
Index: trunk/extensions/VisualEditor/modules/parser/ext.core.TemplateHandler.js
@@ -160,16 +160,17 @@
161161 // check for parser functions
162162
163163 // First, check the target for loops
164 - var target = this.manager.env.tokensToString( tplExpandData.target );
 164+ var target = this.manager.env.tokensToString( tplExpandData.target ).trim();
165165
166166 var args = this.manager.env.KVtoHash( tplExpandData.expandedArgs );
167167
168168 this.manager.env.dp( 'argHash: ', args );
169169
170 - var prefix = target.split(':', 1)[0].toLowerCase();
 170+ var prefix = target.split(':', 1)[0].toLowerCase().trim();
171171 if ( prefix && 'pf_' + prefix in this.parserFunctions ) {
172172 var funcArg = target.substr( prefix.length + 1 );
173 - this.manager.env.dp( 'entering prefix', funcArg, args );
 173+ this.manager.env.tp( 'func prefix: ' + prefix + ' arg=' + funcArg );
 174+ //this.manager.env.dp( 'entering prefix', funcArg, args );
174175 res = this.parserFunctions[ 'pf_' + prefix ]( funcArg,
175176 tplExpandData.expandedArgs, args );
176177
@@ -185,6 +186,7 @@
186187 //data.reset();
187188 }
188189 }
 190+ this.manager.env.tp( 'template target: ' + target );
189191
190192 // now normalize the target before template processing
191193 target = this.manager.env.normalizeTitle( target );
@@ -348,10 +350,11 @@
349351 // Start a new request if none is outstanding
350352 this.manager.env.dp( 'requestQueue: ', this.manager.env.requestQueue);
351353 if ( this.manager.env.requestQueue[title] === undefined ) {
 354+ this.manager.env.tp( 'Note: Starting new request for ' + title );
352355 this.manager.env.requestQueue[title] = new TemplateRequest( this.manager, title );
353356 }
354357 // Append a listener to the request
355 - this.manager.env.requestQueue[title].addListener( 'src', callback );
 358+ this.manager.env.requestQueue[title].once( 'src', callback );
356359
357360 }
358361 };
@@ -368,7 +371,7 @@
369372
370373 token.resultTokens = false;
371374
372 - new AttributeTransformManager(
 375+ new AttributeTransformManager (
373376 this.manager,
374377 this._returnArgAttributes.bind( this, token, cb, frame )
375378 ).process( attributes );
@@ -471,9 +474,8 @@
472475 src = '';
473476 }
474477 //console.log( 'Page ' + title + ': got ' + src );
475 - manager.env.dp( 'Success for ' + title + ' :' + body + ':' );
 478+ manager.env.tp( 'Retrieved ' + title );
476479 manager.env.pageCache[title] = src;
477 - manager.env.dp(data);
478480 self.emit( 'src', src, title );
479481 }
480482 // XXX: handle other status codes
Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.environment.js
@@ -4,6 +4,7 @@
55 parserFunctions: {},
66 pageCache: {}, // @fixme use something with managed space
77 debug: false,
 8+ trace: false,
89 wgScriptPath: "http://en.wikipedia.org/w",
910 wgScriptExtension: ".php",
1011 fetchTemplates: false,
@@ -129,7 +130,7 @@
130131 var tstring = JSON.stringify( token );
131132 this.dp ( 'MWParserEnvironment.tokensToString, non-text token: ' +
132133 tstring + JSON.stringify( tokens, null, 2 ) );
133 - out.push( tstring );
 134+ //out.push( tstring );
134135 }
135136 }
136137 //console.log( 'MWParserEnvironment.tokensToString result: ' + out.join('') );
@@ -150,6 +151,18 @@
151152 }
152153 };
153154
 155+/**
 156+ * Simple debug helper, trace-only
 157+ */
 158+MWParserEnvironment.prototype.tp = function ( ) {
 159+ if ( this.debug || this.trace ) {
 160+ if ( arguments.length > 1 ) {
 161+ console.log( JSON.stringify( arguments, null, 2 ) );
 162+ } else {
 163+ console.log( arguments[0] );
 164+ }
 165+ }
 166+};
154167
155168
156169 if (typeof module == "object") {

Status & tagging log