https://www.mediawiki.org/wiki/Special:Code/MediaWiki/113043

Revision: 113043
Author:   gwicke
Date:     2012-03-05 15:34:27 +0000 (Mon, 05 Mar 2012)
Log Message:
-----------
A few improvements to external link and image handling. 264 tests passing.

Modified Paths:
--------------
    trunk/extensions/VisualEditor/modules/parser/ext.Util.js
    trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js
    
trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js
    trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js
    trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js
    trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt

Modified: trunk/extensions/VisualEditor/modules/parser/ext.Util.js
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/ext.Util.js    2012-03-05 
15:23:04 UTC (rev 113042)
+++ trunk/extensions/VisualEditor/modules/parser/ext.Util.js    2012-03-05 
15:34:27 UTC (rev 113043)
@@ -47,7 +47,7 @@
                case 'dl':
                case 'dt':
                case 'dd':
-               case 'img': // hmm!
+               //case 'img': // hmm!
                case 'pre':
                case 'center':
                case 'blockquote':

Modified: trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js        
2012-03-05 15:23:04 UTC (rev 113042)
+++ trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js        
2012-03-05 15:34:27 UTC (rev 113043)
@@ -25,7 +25,7 @@
 
 WikiLinkHandler.prototype.onWikiLink = function ( token, manager, cb ) {
        var env = this.manager.env,
-               href = env.lookupKV( token.attribs, 'href' ).v,
+               href = token.attribs[0].v,
                tail = env.lookupKV( token.attribs, 'tail' ).v;
        var title = this.manager.env.makeTitleFromPrefixedText( 
                                        env.tokensToString( href )
@@ -41,13 +41,13 @@
                // 
                //console.warn( 'title: ' + JSON.stringify( title ) );
                var obj = new TagTk( 'a', [ new KV( 'href', title.makeLink() ) 
] ),
-                       content = this.manager.env.lookupKV( token.attribs, 
'content' ).v;
+                       content = token.attribs.slice(1, -1);
                //console.warn('content: ' + JSON.stringify( content, null, 2 ) 
);
                // XXX: handle trail
                if ( content.length ) {
                        var out = []
                        for ( var i = 0, l = content.length; i < l ; i++ ) {
-                               out = out.concat( content[i] );
+                               out = out.concat( content[i].v );
                                if ( i < l - 1 ) {
                                        out.push( '|' );
                                }
@@ -103,7 +103,7 @@
        // distinguish media types
        // if image: parse options
        
-       var content = env.lookupKV( token.attribs, 'content' ).v;
+       var content = token.attribs.slice(1, -1);
 
        // XXX: get /wiki from config!
        var a = new TagTk( 'a', [ new KV( 'href', '/wiki' + title.makeLink() ) 
] );
@@ -188,6 +188,80 @@
        }
 };
 
+
+function ExternalLinkHandler( manager, isInclude ) {
+       this.manager = manager;
+       this.manager.addTransform( this.onUrlLink.bind( this ), this.rank, 
'tag', 'urllink' );
+       this.manager.addTransform( this.onExtLink.bind( this ), 
+                       this.rank, 'tag', 'extlink' );
+       // create a new peg parser for image options..
+       if ( !this.imageParser ) {
+               // Actually the regular tokenizer, but we'll call it with the
+               // img_options production only.
+               ExternalLinkHandler.prototype.imageParser = new PegTokenizer();
+       }
+}
+
+ExternalLinkHandler.prototype.rank = 1.15;
+ExternalLinkHandler.prototype._imageExtensions = {
+       'jpg': true,
+       'png': true,
+       'gif': true
+};
+
+ExternalLinkHandler.prototype._isImageLink = function ( href ) {
+       var bits = href.split( '.' );
+       return bits.length > 1 && 
+               this._imageExtensions[ bits[bits.length - 1] ] &&
+               href.substr(0, 4) === 'http';
+};
+
+ExternalLinkHandler.prototype.onUrlLink = function ( token, manager, cb ) {
+       var href = this.manager.env.lookupKV( token.attribs, 'href' ).v;
+       if ( this._isImageLink( href ) ) {
+               return { token: new SelfclosingTagTk( 'img', 
+                               [ 
+                                       new KV( 'alt', href.split('/').last() ),
+                                       new KV( 'src', href ),
+                               ] 
+                       ) 
+               };
+       } else {
+               return { 
+                       tokens: [
+                               new TagTk( 'a', [ new KV( 'href', href ) ] ),
+                               href,
+                               new EndTagTk( 'a' )
+                       ] 
+               };
+       }
+};
+
+// Bracketed external link
+ExternalLinkHandler.prototype.onExtLink = function ( token, manager, cb ) {
+       var href = this.manager.env.lookupKV( token.attribs, 'href' ).v,
+          content=  this.manager.env.lookupKV( token.attribs, 'content' ).v;
+       // validate the href
+       if ( this.imageParser.parseURL( href ) ) {
+               return { 
+                       tokens:
+                               [
+                                       
+                                       new TagTk( 'a', [
+                                                               new KV('href', 
href),
+                                                               new 
KV('data-mw-type', 'external')
+                                                       ] ),
+                               ].concat( content, [ new EndTagTk( 'a' )])
+               };
+       } else {
+               return {
+                       tokens: ['[', href ].concat( content, [']'] )
+               };
+       }
+};
+
+
 if (typeof module == "object") {
        module.exports.WikiLinkHandler = WikiLinkHandler;
+       module.exports.ExternalLinkHandler = ExternalLinkHandler;
 }

Modified: 
trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js
===================================================================
--- 
trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js 
    2012-03-05 15:23:04 UTC (rev 113042)
+++ 
trunk/extensions/VisualEditor/modules/parser/mediawiki.TokenTransformManager.js 
    2012-03-05 15:34:27 UTC (rev 113043)
@@ -780,10 +780,10 @@
                        // transform the key
                        pipe = this.manager.getAttributePipeline( 
this.manager.inputType,
                                                                                
                                                this.manager.args );
-                       pipe.addListener( 'chunk',
+                       pipe.on( 'chunk',
                                        this.onChunk.bind( this, 
this._returnAttributeKey.bind( this, i ) ) 
                                );
-                       pipe.addListener( 'end', 
+                       pipe.on( 'end', 
                                        this.onEnd.bind( this, 
this._returnAttributeKey.bind( this, i ) ) 
                                );
                        pipe.process( attributes[i].k.concat([{type:'END'}]) );
@@ -798,10 +798,10 @@
                        // transform the value
                        pipe = this.manager.getAttributePipeline( 
this.manager.inputType,
                                                                                
                                                this.manager.args );
-                       pipe.addListener( 'chunk', 
+                       pipe.on( 'chunk', 
                                        this.onChunk.bind( this, 
this._returnAttributeValue.bind( this, i ) ) 
                                        );
-                       pipe.addListener( 'end', 
+                       pipe.on( 'end', 
                                        this.onEnd.bind( this, 
this._returnAttributeValue.bind( this, i ) ) 
                                        );
                        //console.warn('starting attribute transform of ' + 
JSON.stringify( attributes[i].v ) );

Modified: trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js    
2012-03-05 15:23:04 UTC (rev 113042)
+++ trunk/extensions/VisualEditor/modules/parser/mediawiki.parser.js    
2012-03-05 15:34:27 UTC (rev 113043)
@@ -26,7 +26,9 @@
        Sanitizer                   = 
require('./ext.core.Sanitizer.js').Sanitizer,
        TemplateHandler             = 
require('./ext.core.TemplateHandler.js').TemplateHandler,
        AttributeExpander            = 
require('./ext.core.AttributeExpander.js').AttributeExpander,
-       WikiLinkHandler             = 
require('./ext.core.LinkHandler.js').WikiLinkHandler,
+       LinkHandler                 = require('./ext.core.LinkHandler.js'),
+       WikiLinkHandler                         = LinkHandler.WikiLinkHandler,
+       ExternalLinkHandler                     = 
LinkHandler.ExternalLinkHandler,
        Cite                        = require('./ext.Cite.js').Cite,
        FauxHTML5                   = 
require('./mediawiki.HTML5TreeBuilder.node.js').FauxHTML5,
        DOMPostProcessor            = 
require('./mediawiki.DOMPostProcessor.js').DOMPostProcessor,
@@ -167,7 +169,8 @@
                                // XXX: Should we support further processing 
after attribute
                                // expansion?
                                AttributeExpander,
-                               WikiLinkHandler
+                               WikiLinkHandler,
+                               ExternalLinkHandler
                                /* ExtensionHandler1, */
                                /* ExtensionHandler2, */
                        ],

Modified: 
trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js     
2012-03-05 15:23:04 UTC (rev 113042)
+++ trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js     
2012-03-05 15:34:27 UTC (rev 113043)
@@ -71,6 +71,14 @@
                return this.parser.parse(text, 'img_options', null, this );
 };
 
+PegTokenizer.prototype.parseURL = function( text ) {
+       try {
+               return this.parser.parse(text, 'url', null, this );
+       } catch ( e ) {
+               return false;
+       }
+};
+
 /*
  * Inline breaks, flag-enabled production which detects end positions for
  * active higher-level productions in inline and other nested productions.

Modified: trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt 
2012-03-05 15:23:04 UTC (rev 113042)
+++ trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt 
2012-03-05 15:34:27 UTC (rev 113043)
@@ -566,10 +566,7 @@
 urllink
   = ! { return syntaxFlags['extlink'] }
     target:url {
-      return [ new TagTk( 'a', [new KV('href', target)] )
-             , target
-             , new EndTagTk( 'a' )
-             ];
+      return [ new TagTk( 'urllink', [new KV('href', target)] ) ];
   }
 
 extlink
@@ -588,15 +585,12 @@
                 text = [ "[" + linkCount + "]" ];
                 linkCount++;
             }
-            var res = [ 
-                new TagTk( 'a', [
-                            new KV('href', target),
-                            new KV('data-mw-type', 'external')
-                        ] ),
-            ].concat( text 
-                    , [ new EndTagTk( 'a' )]);
-            //console.warn( JSON.stringify( res, null, 2 ) );
-            return res;
+            return [
+                new SelfclosingTagTk( 'extlink', [
+                    new KV('href', target),
+                    new KV('content', text)
+                ] )
+            ];
         }
       / "[" & { clearFlag('extlink'); return false; }
     )
@@ -765,7 +759,7 @@
     target:wikilink_preprocessor_text
     lcontent:( 
                & { return posStack.push('lcontent' , pos); }
-               lcs:( "|" lt:link_text { return lt; } )+ { 
+               lcs:( "|" lt:link_text { return new KV( '', lt ); } )+ { 
                    return { pos: posStack.pop('lcontent' , pos), content: lcs 
};
                }
             
@@ -780,7 +774,7 @@
     tail:( ![A-Z \t(),.:-] tc:text_char { return tc } )* {
       var obj = new SelfclosingTagTk( 'wikilink' ),
           textTokens = [];
-      obj.attribs.push( new KV('href', target) );
+      obj.attribs.push( new KV('', target) );
       obj.dataAttribs = { 
           sourcePos: posStack.pop( 'wikilink', pos ),
           contentPos: lcontent.pos
@@ -790,10 +784,10 @@
 
       //console.warn('lcontent: ' + JSON.stringify( lcontent, null, 2 ) );
       // Deal with content. XXX: Properly support pipe-trick etc
-      lcontent.tail = tail && tail.join('') || '';
+      //lcontent.tail = tail && tail.join('') || '';
 
-      obj.attribs.push( new KV( 'content', lcontent.content ) );
-      obj.attribs.push( new KV( 'tail', lcontent.tail ) );
+      obj.attribs = obj.attribs.concat( lcontent.content );
+      obj.attribs.push( new KV( 'tail', tail && tail.join('') || '' ) );
       //console.warn( "XXX:" + pp([obj].concat(textTokens, [new EndTagTk( 'a' 
)])) );
       return [obj];
   }


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to