From e8a4517d6bbb70f5d3ebcf98277e71ee89169cf1 Mon Sep 17 00:00:00 2001 From: Daimona Eaytoy Date: Wed, 27 Jun 2018 20:05:52 +0200 Subject: [PATCH] Improve Ace syntax highlight Several improvements, this is the list: *Added highlighting for disabled and deprecated variables *Simplified a bit Ace's keyword mapper *Added highlighting for ternary operator *Added logic to retrieve operators from AF tokenizer *Removed $ symbol since it's not usable in declaring stuff *Customized highlighting via CSS Depends-On: I5c370b54e6516889624088e27928ad3a1f48a821 Change-Id: If95e34fc7260413c4fb39c18a1ef44f5a93e1a68 --- includes/AbuseFilter.php | 13 +++++++++++-- modules/ext.abuseFilter.css | 11 +++++++++++ modules/mode-abusefilter.js | 30 +++++++++++++++--------------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/includes/AbuseFilter.php b/includes/AbuseFilter.php index 584fdfc56..c5df77d93 100644 --- a/includes/AbuseFilter.php +++ b/includes/AbuseFilter.php @@ -2094,17 +2094,26 @@ class AbuseFilter { public static function getAceConfig( $canEdit ) { $values = self::getBuilderValues(); $deprecatedVars = self::getDeprecatedVariables(); - $builderVariables = implode( '|', - array_keys( array_merge( $values['vars'], $deprecatedVars ) ) ); + + $builderVariables = implode( '|', array_keys( $values['vars'] ) ); $builderFunctions = implode( '|', array_keys( AbuseFilterParser::$mFunctions ) ); // AbuseFilterTokenizer::$keywords also includes constants (true, false and null), // but Ace redefines these constants afterwards so this will not be an issue $builderKeywords = implode( '|', AbuseFilterTokenizer::$keywords ); + // Extract operators from tokenizer like we do in AbuseFilterParserTest + $operators = implode( '|', array_map( function ( $op ) { + return preg_quote( $op, '/' ); + }, AbuseFilterTokenizer::$operators ) ); + $deprecatedVariables = implode( '|', array_keys( $deprecatedVars ) ); + $disabledVariables = implode( '|', array_keys( self::$disabledVars ) ); return [ 'variables' => $builderVariables, 'functions' => $builderFunctions, 'keywords' => $builderKeywords, + 'operators' => $operators, + 'deprecated' => $deprecatedVariables, + 'disabled' => $disabledVariables, 'aceReadOnly' => !$canEdit ]; } diff --git a/modules/ext.abuseFilter.css b/modules/ext.abuseFilter.css index 40e2e23e4..a7818ce4d 100644 --- a/modules/ext.abuseFilter.css +++ b/modules/ext.abuseFilter.css @@ -152,3 +152,14 @@ ul li.mw-abusefilter-changeslist-match { .mw-abusefilter-history-buttons { text-align: center; } + +/* Ace highlight customisation */ + +span.ace_invalid.ace_deprecated { + color: #fe6767; + background-color: initial; +} + +span.ace_support.ace_function { + color: #495dd0; +} diff --git a/modules/mode-abusefilter.js b/modules/mode-abusefilter.js index c82b831de..518e8bd47 100644 --- a/modules/mode-abusefilter.js +++ b/modules/mode-abusefilter.js @@ -6,18 +6,16 @@ ace.define( 'ace/mode/abusefilter_highlight_rules', [ 'require', 'exports', 'mod TextHighlightRules = require( './text_highlight_rules' ).TextHighlightRules, AFHighlightRules = function () { - var keywords = ( mw.config.get( 'aceConfig' ).keywords ), + var cfg = mw.config.get( 'aceConfig' ), constants = ( 'true|false|null' ), - functions = ( mw.config.get( 'aceConfig' ).functions ), - variables = ( mw.config.get( 'aceConfig' ).variables ), - deprecated = ( '' ), // Template for deprecated vars, already registered within ace settings. keywordMapper = this.createKeywordMapper( { - keyword: keywords, - 'support.function': functions, + keyword: cfg.keywords, + 'support.function': cfg.functions, 'constant.language': constants, - 'variable.language': variables, - 'keyword.deprecated': deprecated + 'variable.language': cfg.variables, + 'invalid.deprecated': cfg.deprecated, + 'invalid.illegal': cfg.disabled }, 'identifier' ), @@ -27,7 +25,9 @@ ace.define( 'ace/mode/abusefilter_highlight_rules', [ 'require', 'exports', 'mod fraction = '(?:\\.\\d+)', intPart = '(?:\\d+)', pointFloat = '(?:(?:' + intPart + '?' + fraction + ')|(?:' + intPart + '\\.))', - floatNumber = '(?:' + pointFloat + ')'; + floatNumber = '(?:' + pointFloat + ')', + singleQuoteString = '\'(?:[^\\\\]|\\\\.)*?\'', + doubleQuoteString = '"(?:[^\\\\]|\\\\.)*?"'; this.$rules = { start: [ { @@ -35,11 +35,11 @@ ace.define( 'ace/mode/abusefilter_highlight_rules', [ 'require', 'exports', 'mod regex: '\\/\\*', next: 'comment' }, { - token: 'string', // " string - regex: '"(?:[^\\\\]|\\\\.)*?"' + token: 'string', + regex: doubleQuoteString }, { - token: 'string', // ' string - regex: '\'(?:[^\\\\]|\\\\.)*?\'' + token: 'string', + regex: singleQuoteString }, { token: 'constant.numeric', // float regex: floatNumber @@ -48,10 +48,10 @@ ace.define( 'ace/mode/abusefilter_highlight_rules', [ 'require', 'exports', 'mod regex: integer + '\\b' }, { token: keywordMapper, - regex: '[a-zA-Z_$][a-zA-Z0-9_$]*\\b' + regex: '[a-zA-Z_][a-zA-Z0-9_]*\\b' }, { token: 'keyword.operator', - regex: '\\+|\\-|\\*\\*|\\*|\\/|%|\\^|&|\\||<|>|<=|=>|==|!=|===|!==|:=|=|!' + regex: cfg.operators }, { token: 'paren.lparen', regex: '[\\[\\(]'