add highlighting the magic word that does not begin with '#' (v 1.9.0)

* fix brackets color

Change-Id: I1cd057287d5ae142ed240e4ea9012790716f888c
This commit is contained in:
Pavel Astakhov 2014-08-29 10:05:50 +06:00
parent 77c8f73fec
commit 65ffeacf9e
4 changed files with 70 additions and 49 deletions

View file

@ -3,9 +3,28 @@
class CodeMirrorHooks { class CodeMirrorHooks {
static $globalVariableScript = array();
/**
*
* @global Parser $wgParser
* @param EditPage $editPage
* @param OutputPage $output
* @return boolean
*/
public static function onEditPageShowEditFormInitial( EditPage $editPage, OutputPage $output ) { public static function onEditPageShowEditFormInitial( EditPage $editPage, OutputPage $output ) {
global $wgParser;
if ( false === isset( $wgParser->mFunctionSynonyms ) ) {
$wgParser->firstCallInit();
}
self::$globalVariableScript['FunctionSynonyms'] = $wgParser->mFunctionSynonyms;
$output->addModules( 'ext.CodeMirror' ); $output->addModules( 'ext.CodeMirror' );
return true; return true;
} }
public static function onMakeGlobalVariablesScript( array &$vars, OutputPage $out ) {
foreach ( self::$globalVariableScript as $key=> $value ) {
$vars["extCodeMirror$key"] = $value;
}
}
} }

View file

@ -15,7 +15,7 @@ if ( !defined( 'MEDIAWIKI' ) ) {
die( 'This file is an extension to MediaWiki and thus not a valid entry point.' ); die( 'This file is an extension to MediaWiki and thus not a valid entry point.' );
} }
const EXT_CODEMIRROR_VERSION = '1.8.0'; const EXT_CODEMIRROR_VERSION = '1.9.0';
// Register this extension on Special:Version // Register this extension on Special:Version
$wgExtensionCredits['parserhook'][] = array( $wgExtensionCredits['parserhook'][] = array(
@ -35,6 +35,7 @@ $wgAutoloadClasses['CodeMirrorHooks'] = __DIR__ . '/CodeMirror.hooks.php';
$wgHooks['EditPage::showEditForm:initial'][] = 'CodeMirrorHooks::onEditPageShowEditFormInitial'; $wgHooks['EditPage::showEditForm:initial'][] = 'CodeMirrorHooks::onEditPageShowEditFormInitial';
$wgHooks['EditPage::showReadOnlyForm:initial'][] = 'CodeMirrorHooks::onEditPageShowEditFormInitial'; $wgHooks['EditPage::showReadOnlyForm:initial'][] = 'CodeMirrorHooks::onEditPageShowEditFormInitial';
$wgHooks['MakeGlobalVariablesScript'][] = 'CodeMirrorHooks::onMakeGlobalVariablesScript';
$tpl = array( $tpl = array(
'localBasePath' => __DIR__ . '/resources', 'localBasePath' => __DIR__ . '/resources',

View file

@ -1,7 +1,8 @@
/*global CodeMirror*/ /*global CodeMirror, mw*/
jQuery( document ).ready( function ( $ ) { jQuery( document ).ready( function ( $ ) {
var textbox1 = $( '#wpTextbox1' ); var textbox1 = $( '#wpTextbox1' );
var codeMirror = CodeMirror.fromTextArea( textbox1[0], { var codeMirror = CodeMirror.fromTextArea( textbox1[0], {
mwextFunctionSynonyms: mw.config.get( 'extCodeMirrorFunctionSynonyms' ),
styleActiveLine: true, styleActiveLine: true,
//lineNumbers: true, //lineNumbers: true,
lineWrapping: true, lineWrapping: true,

View file

@ -10,7 +10,7 @@
})(function( CodeMirror ) { })(function( CodeMirror ) {
'use strict'; 'use strict';
CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) { CodeMirror.defineMode('mediawiki', function( config/*, parserConfig */ ) {
var tagName = false; var tagName = false;
var mustEat = true; var mustEat = true;
@ -35,9 +35,9 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
state.ImInBlock.pop(); //FIXME: it is wrong Link state.ImInBlock.pop(); //FIXME: it is wrong Link
return null; return null;
} else if ( stream.eatWhile( /[^#\s\u00a0\|\]\&]/ ) ) { //FIXME '{{' brokes Link, sample [[z{{page]] } else if ( stream.eatWhile( /[^#\s\u00a0\|\]\&]/ ) ) { //FIXME '{{' brokes Link, sample [[z{{page]]
return 'attribute mw-underline strong'; return 'attribute mw-underline';
} else if ( stream.peek() === '&' ) { // check for character entity references } else if ( stream.peek() === '&' ) { // check for character entity references
style = ['attribute', 'mw-underline', 'strong']; style = ['attribute', 'mw-underline'];
mnemonicStyle = ['mw-underline']; mnemonicStyle = ['mw-underline'];
} else if ( stream.eat( '#' ) ) { } else if ( stream.eat( '#' ) ) {
state.ImInBlock.push( 'LinkToSection' ); state.ImInBlock.push( 'LinkToSection' );
@ -46,20 +46,18 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
stream.eatSpace(); stream.eatSpace();
state.ImInBlock.pop(); state.ImInBlock.pop();
state.ImInBlock.push( 'LinkText' ); state.ImInBlock.push( 'LinkText' );
return 'tag strong'; return 'attribute strong';
} else if ( stream.eatSpace() ) { } else if ( stream.eatSpace() ) {
if ( /[^#\|\]]/.test( stream.peek() ) ) { if ( /[^#\|\]]/.test( stream.peek() ) ) {
return 'attribute mw-underline strong'; return 'attribute mw-underline strong';
} }
return null; return null;
} else if ( stream.eat( ']' ) ) { } else if ( stream.match( ']]' ) ) {
if ( stream.eat( ']' ) ) { state.ImInBlock.pop();
state.ImInBlock.pop(); // if ( !stream.eatSpace() ) {
// if ( !stream.eatSpace() ) { // state.ImInBlock.push( 'LinkTrail' );
// state.ImInBlock.push( 'LinkTrail' ); // }
// } return 'attribute';
return 'tag bracket';
}
} }
break; break;
case 'LinkToSection': case 'LinkToSection':
@ -80,12 +78,12 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
break; break;
case 'LinkText': case 'LinkText':
stream.eatSpace(); stream.eatSpace();
if ( stream.match( /[\s\u00a0]*\]\]/ ) ) { if ( stream.match( ']]' ) ) {
state.ImInBlock.pop(); state.ImInBlock.pop();
// if ( !stream.eatSpace() ) { // if ( !stream.eatSpace() ) {
// state.ImInBlock.push( 'LinkTrail' ); // state.ImInBlock.push( 'LinkTrail' );
// } // }
return 'tag bracket'; return 'attribute';
} }
if ( stream.eatWhile( /[^\]\s\u00a0\&]/ ) ) { if ( stream.eatWhile( /[^\]\s\u00a0\&]/ ) ) {
@ -104,31 +102,19 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
// } // }
// break; // break;
case 'TemplatePageName': case 'TemplatePageName':
state.ImInBlock.pop();
if ( stream.eat( '#' ) ) {
state.ImInBlock.push( 'ParserFunctionName' );
return 'keyword strong';
}
if ( stream.eatWhile( /[^\s\u00a0\}\|<\{\&]/ ) ) {
state.ImInBlock.push( 'TemplatePageNameContinue' );
return 'attribute mw-underline';
}
break;
case 'TemplatePageNameContinue':
stream.eatSpace();
if ( stream.match( /[\s\u00a0]*[^\s\u00a0\}\|<\{\&]/ ) ) { if ( stream.match( /[\s\u00a0]*[^\s\u00a0\}\|<\{\&]/ ) ) {
return 'attribute mw-underline'; return 'attribute strong mw-underline';
} }
if ( stream.eat( '|' ) ) { if ( stream.eat( '|' ) ) {
state.ImInBlock.pop(); state.ImInBlock.pop();
state.ImInBlock.push( 'TemplateArgument' ); state.ImInBlock.push( 'TemplateArgument' );
state.bTempArgName = true; state.bTempArgName = true;
stream.eatSpace(); stream.eatSpace();
return 'tag strong'; return 'attribute strong';
} }
if ( stream.match( /\}\}/ ) ) { if ( stream.match( '}}' ) ) {
state.ImInBlock.pop(); state.ImInBlock.pop();
return 'tag bracket'; return 'attribute';
} }
if ( stream.peek() === '&' ) { if ( stream.peek() === '&' ) {
style = ['attribute', 'mw-underline']; style = ['attribute', 'mw-underline'];
@ -146,12 +132,10 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
return 'string'; return 'string';
} else if ( stream.eat( '|' ) ) { } else if ( stream.eat( '|' ) ) {
state.bTempArgName = true; state.bTempArgName = true;
return 'tag strong'; return 'attribute strong';
} else if ( stream.eat( '}' ) ) { } else if ( stream.match( '}}' ) ) {
if ( stream.eat( '}' ) ) { state.ImInBlock.pop();
state.ImInBlock.pop(); return 'attribute';
return 'tag bracket';
}
} }
style.push( 'string' ); style.push( 'string' );
break; break;
@ -171,7 +155,7 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
} }
break; break;
case 'ParserFunctionName': case 'ParserFunctionName':
if ( stream.eatWhile( /\w/ ) ) { if ( stream.match( /#?\w+/ ) ) { // FIXME: {{#name}} and and {{uc}} are wrong, must have ':'
return 'keyword strong'; return 'keyword strong';
} }
if ( stream.eat( ':' ) ) { if ( stream.eat( ':' ) ) {
@ -179,17 +163,20 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
state.ImInBlock.push( 'ParserFunctionArgument' ); state.ImInBlock.push( 'ParserFunctionArgument' );
return 'keyword strong'; return 'keyword strong';
} }
if ( stream.match( /[\s\u00a0]*\}\}/ ) ) {
state.ImInBlock.pop();
return 'keyword';
}
style = ['keyword'];
break; break;
case 'ParserFunctionArgument': case 'ParserFunctionArgument':
if ( stream.eatWhile( /[^\}\|<\{\&]/ ) ) { if ( stream.eatWhile( /[^\}\|<\{\&]/ ) ) {
return 'string-2'; return 'string-2';
} else if ( stream.eat( '|' ) ) { } else if ( stream.eat( '|' ) ) {
return 'tag strong'; return 'keyword strong';
} else if ( stream.eat( '}' ) ) { } else if ( stream.match( '}}' ) ) {
if ( stream.eat( '}' ) ) { state.ImInBlock.pop();
state.ImInBlock.pop(); return 'keyword';
return 'tag bracket';
}
} }
style.push( 'string-2' ); style.push( 'string-2' );
break; break;
@ -286,10 +273,23 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
stream.eatSpace(); stream.eatSpace();
state.ImInBlock.push( 'TemplateVariable' ); state.ImInBlock.push( 'TemplateVariable' );
return 'variable-2'; return 'variable-2';
} else if ( stream.eat( '{' ) ) { // Templates } else if ( stream.match( /\{[\s\u00a0]*/ ) ) {
stream.eatSpace(); if ( stream.peek() === '#' ) { // Parser function
state.ImInBlock.push( 'ParserFunctionName' );
return 'keyword';
}
// Check for parser function without '#'
var name = stream.match( /(\w+)(\:|[\s\u00a0]*)(\}\}?)?(.)?/ );
if ( name ) {
stream.backUp( name[0].length );
if ( (name[2] === ':' || name[4] === undefined || name[3] === '}}') && (config.mwextFunctionSynonyms[0][name[1].toLowerCase()] || config.mwextFunctionSynonyms[1][name[1]]) ) {
state.ImInBlock.push( 'ParserFunctionName' );
return 'keyword';
}
}
// Template
state.ImInBlock.push( 'TemplatePageName' ); state.ImInBlock.push( 'TemplatePageName' );
return 'tag bracket'; return 'attribute';
} }
break; break;
case '[': case '[':
@ -297,7 +297,7 @@ CodeMirror.defineMode('mediawiki', function( /*config, parserConfig*/ ) {
stream.eatSpace(); stream.eatSpace();
if ( /[^\]\|\[\{]/.test( stream.peek() ) ) { if ( /[^\]\|\[\{]/.test( stream.peek() ) ) {
state.ImInBlock.push( 'Link' ); state.ImInBlock.push( 'Link' );
return 'tag bracket'; return 'attribute';
} }
} }
break; break;