r113043 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r113042‎ | r113043 | r113044 >
Date:15:34, 5 March 2012
Author:gwicke
Status:deferred
Tags:
Comment:
A few improvements to external link and image handling. 264 tests passing.
Modified paths:
  • /trunk/extensions/VisualEditor/modules/parser/ext.Util.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js (modified) (history)
  • /trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt (modified) (history)

Diff [purge]

Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js
@@ -780,10 +780,10 @@
781781 // transform the key
782782 pipe = this.manager.getAttributePipeline( this.manager.inputType,
783783 this.manager.args );
784 - pipe.addListener( 'chunk',
 784+ pipe.on( 'chunk',
785785 this.onChunk.bind( this, this._returnAttributeKey.bind( this, i ) )
786786 );
787 - pipe.addListener( 'end',
 787+ pipe.on( 'end',
788788 this.onEnd.bind( this, this._returnAttributeKey.bind( this, i ) )
789789 );
790790 pipe.process( attributes[i].k.concat([{type:'END'}]) );
@@ -798,10 +798,10 @@
799799 // transform the value
800800 pipe = this.manager.getAttributePipeline( this.manager.inputType,
801801 this.manager.args );
802 - pipe.addListener( 'chunk',
 802+ pipe.on( 'chunk',
803803 this.onChunk.bind( this, this._returnAttributeValue.bind( this, i ) )
804804 );
805 - pipe.addListener( 'end',
 805+ pipe.on( 'end',
806806 this.onEnd.bind( this, this._returnAttributeValue.bind( this, i ) )
807807 );
808808 //console.warn('starting attribute transform of ' + JSON.stringify( attributes[i].v ) );
Index: trunk/extensions/VisualEditor/modules/parser/ext.Util.js
@@ -47,7 +47,7 @@
4848 case 'dl':
4949 case 'dt':
5050 case 'dd':
51 - case 'img': // hmm!
 51+ //case 'img': // hmm!
5252 case 'pre':
5353 case 'center':
5454 case 'blockquote':
Index: trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt
@@ -566,10 +566,7 @@
567567 urllink
568568 = ! { return syntaxFlags['extlink'] }
569569 target:url {
570 - return [ new TagTk( 'a', [new KV('href', target)] )
571 - , target
572 - , new EndTagTk( 'a' )
573 - ];
 570+ return [ new TagTk( 'urllink', [new KV('href', target)] ) ];
574571 }
575572
576573 extlink
@@ -588,15 +585,12 @@
589586 text = [ "[" + linkCount + "]" ];
590587 linkCount++;
591588 }
592 - var res = [
593 - new TagTk( 'a', [
594 - new KV('href', target),
595 - new KV('data-mw-type', 'external')
596 - ] ),
597 - ].concat( text
598 - , [ new EndTagTk( 'a' )]);
599 - //console.warn( JSON.stringify( res, null, 2 ) );
600 - return res;
 589+ return [
 590+ new SelfclosingTagTk( 'extlink', [
 591+ new KV('href', target),
 592+ new KV('content', text)
 593+ ] )
 594+ ];
601595 }
602596 / "[" & { clearFlag('extlink'); return false; }
603597 )
@@ -765,7 +759,7 @@
766760 target:wikilink_preprocessor_text
767761 lcontent:(
768762 & { return posStack.push('lcontent' , pos); }
769 - lcs:( "|" lt:link_text { return lt; } )+ {
 763+ lcs:( "|" lt:link_text { return new KV( '', lt ); } )+ {
770764 return { pos: posStack.pop('lcontent' , pos), content: lcs };
771765 }
772766
@@ -780,7 +774,7 @@
781775 tail:( ![A-Z \t(),.:-] tc:text_char { return tc } )* {
782776 var obj = new SelfclosingTagTk( 'wikilink' ),
783777 textTokens = [];
784 - obj.attribs.push( new KV('href', target) );
 778+ obj.attribs.push( new KV('', target) );
785779 obj.dataAttribs = {
786780 sourcePos: posStack.pop( 'wikilink', pos ),
787781 contentPos: lcontent.pos
@@ -790,10 +784,10 @@
791785
792786 //console.warn('lcontent: ' + JSON.stringify( lcontent, null, 2 ) );
793787 // Deal with content. XXX: Properly support pipe-trick etc
794 - lcontent.tail = tail && tail.join('') || '';
 788+ //lcontent.tail = tail && tail.join('') || '';
795789
796 - obj.attribs.push( new KV( 'content', lcontent.content ) );
797 - obj.attribs.push( new KV( 'tail', lcontent.tail ) );
 790+ obj.attribs = obj.attribs.concat( lcontent.content );
 791+ obj.attribs.push( new KV( 'tail', tail && tail.join('') || '' ) );
798792 //console.warn( "XXX:" + pp([obj].concat(textTokens, [new EndTagTk( 'a' )])) );
799793 return [obj];
800794 }
Index: trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js
@@ -25,7 +25,7 @@
2626
2727 WikiLinkHandler.prototype.onWikiLink = function ( token, manager, cb ) {
2828 var env = this.manager.env,
29 - href = env.lookupKV( token.attribs, 'href' ).v,
 29+ href = token.attribs[0].v,
3030 tail = env.lookupKV( token.attribs, 'tail' ).v;
3131 var title = this.manager.env.makeTitleFromPrefixedText(
3232 env.tokensToString( href )
@@ -41,13 +41,13 @@
4242 //
4343 //console.warn( 'title: ' + JSON.stringify( title ) );
4444 var obj = new TagTk( 'a', [ new KV( 'href', title.makeLink() ) ] ),
45 - content = this.manager.env.lookupKV( token.attribs, 'content' ).v;
 45+ content = token.attribs.slice(1, -1);
4646 //console.warn('content: ' + JSON.stringify( content, null, 2 ) );
4747 // XXX: handle trail
4848 if ( content.length ) {
4949 var out = []
5050 for ( var i = 0, l = content.length; i < l ; i++ ) {
51 - out = out.concat( content[i] );
 51+ out = out.concat( content[i].v );
5252 if ( i < l - 1 ) {
5353 out.push( '|' );
5454 }
@@ -103,7 +103,7 @@
104104 // distinguish media types
105105 // if image: parse options
106106
107 - var content = env.lookupKV( token.attribs, 'content' ).v;
 107+ var content = token.attribs.slice(1, -1);
108108
109109 // XXX: get /wiki from config!
110110 var a = new TagTk( 'a', [ new KV( 'href', '/wiki' + title.makeLink() ) ] );
@@ -188,6 +188,80 @@
189189 }
190190 };
191191
 192+
 193+function ExternalLinkHandler( manager, isInclude ) {
 194+ this.manager = manager;
 195+ this.manager.addTransform( this.onUrlLink.bind( this ), this.rank, 'tag', 'urllink' );
 196+ this.manager.addTransform( this.onExtLink.bind( this ),
 197+ this.rank, 'tag', 'extlink' );
 198+ // create a new peg parser for image options..
 199+ if ( !this.imageParser ) {
 200+ // Actually the regular tokenizer, but we'll call it with the
 201+ // img_options production only.
 202+ ExternalLinkHandler.prototype.imageParser = new PegTokenizer();
 203+ }
 204+}
 205+
 206+ExternalLinkHandler.prototype.rank = 1.15;
 207+ExternalLinkHandler.prototype._imageExtensions = {
 208+ 'jpg': true,
 209+ 'png': true,
 210+ 'gif': true
 211+};
 212+
 213+ExternalLinkHandler.prototype._isImageLink = function ( href ) {
 214+ var bits = href.split( '.' );
 215+ return bits.length > 1 &&
 216+ this._imageExtensions[ bits[bits.length - 1] ] &&
 217+ href.substr(0, 4) === 'http';
 218+};
 219+
 220+ExternalLinkHandler.prototype.onUrlLink = function ( token, manager, cb ) {
 221+ var href = this.manager.env.lookupKV( token.attribs, 'href' ).v;
 222+ if ( this._isImageLink( href ) ) {
 223+ return { token: new SelfclosingTagTk( 'img',
 224+ [
 225+ new KV( 'alt', href.split('/').last() ),
 226+ new KV( 'src', href ),
 227+ ]
 228+ )
 229+ };
 230+ } else {
 231+ return {
 232+ tokens: [
 233+ new TagTk( 'a', [ new KV( 'href', href ) ] ),
 234+ href,
 235+ new EndTagTk( 'a' )
 236+ ]
 237+ };
 238+ }
 239+};
 240+
 241+// Bracketed external link
 242+ExternalLinkHandler.prototype.onExtLink = function ( token, manager, cb ) {
 243+ var href = this.manager.env.lookupKV( token.attribs, 'href' ).v,
 244+ content= this.manager.env.lookupKV( token.attribs, 'content' ).v;
 245+ // validate the href
 246+ if ( this.imageParser.parseURL( href ) ) {
 247+ return {
 248+ tokens:
 249+ [
 250+
 251+ new TagTk( 'a', [
 252+ new KV('href', href),
 253+ new KV('data-mw-type', 'external')
 254+ ] ),
 255+ ].concat( content, [ new EndTagTk( 'a' )])
 256+ };
 257+ } else {
 258+ return {
 259+ tokens: ['[', href ].concat( content, [']'] )
 260+ };
 261+ }
 262+};
 263+
 264+
192265 if (typeof module == "object") {
193266 module.exports.WikiLinkHandler = WikiLinkHandler;
 267+ module.exports.ExternalLinkHandler = ExternalLinkHandler;
194268 }
Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js
@@ -71,6 +71,14 @@
7272 return this.parser.parse(text, 'img_options', null, this );
7373 };
7474
 75+PegTokenizer.prototype.parseURL = function( text ) {
 76+ try {
 77+ return this.parser.parse(text, 'url', null, this );
 78+ } catch ( e ) {
 79+ return false;
 80+ }
 81+};
 82+
7583 /*
7684 * Inline breaks, flag-enabled production which detects end positions for
7785 * active higher-level productions in inline and other nested productions.
Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js
@@ -26,7 +26,9 @@
2727 Sanitizer = require('./ext.core.Sanitizer.js').Sanitizer,
2828 TemplateHandler = require('./ext.core.TemplateHandler.js').TemplateHandler,
2929 AttributeExpander = require('./ext.core.AttributeExpander.js').AttributeExpander,
30 - WikiLinkHandler = require('./ext.core.LinkHandler.js').WikiLinkHandler,
 30+ LinkHandler = require('./ext.core.LinkHandler.js'),
 31+ WikiLinkHandler = LinkHandler.WikiLinkHandler,
 32+ ExternalLinkHandler = LinkHandler.ExternalLinkHandler,
3133 Cite = require('./ext.Cite.js').Cite,
3234 FauxHTML5 = require('./mediawiki.HTML5TreeBuilder.node.js').FauxHTML5,
3335 DOMPostProcessor = require('./mediawiki.DOMPostProcessor.js').DOMPostProcessor,
@@ -167,7 +169,8 @@
168170 // XXX: Should we support further processing after attribute
169171 // expansion?
170172 AttributeExpander,
171 - WikiLinkHandler
 173+ WikiLinkHandler,
 174+ ExternalLinkHandler
172175 /* ExtensionHandler1, */
173176 /* ExtensionHandler2, */
174177 ],

Status & tagging log