From: James D. Forrester Date: Thu, 5 Sep 2019 22:20:46 +0000 (-0700) Subject: Deprecate mediawiki.RegExp; move only function to mw.util X-Git-Tag: 1.34.0-rc.0~346 X-Git-Url: http://git.cyclocoop.org/?a=commitdiff_plain;h=8697ba835463c9413699a01293cf8f4e88ef8e35;p=lhc%2Fweb%2Fwiklou.git Deprecate mediawiki.RegExp; move only function to mw.util Bug: T218339 Change-Id: I1079e99fc22ed7f3159e7fe45581db799ae7259d --- diff --git a/RELEASE-NOTES-1.34 b/RELEASE-NOTES-1.34 index 229fda407c..aaf4d78fea 100644 --- a/RELEASE-NOTES-1.34 +++ b/RELEASE-NOTES-1.34 @@ -491,6 +491,7 @@ because of Phabricator reports. class. If you extend this class please be sure to override all its methods or extend RevisionSearchResult. * Skin::getSkinNameMessages() is deprecated and no longer used. +* The mediawiki.RegExp module is deprecated; use mw.util.escapeRegExp() instead. === Other changes in 1.34 === * … diff --git a/maintenance/jsduck/categories.json b/maintenance/jsduck/categories.json index 54c1d38805..b19420f14f 100644 --- a/maintenance/jsduck/categories.json +++ b/maintenance/jsduck/categories.json @@ -21,7 +21,6 @@ "classes": [ "mw.Title", "mw.Uri", - "mw.RegExp", "mw.String", "mw.messagePoster.*", "mw.notification", diff --git a/resources/Resources.php b/resources/Resources.php index cfcfc19eb3..b3aee844e6 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -212,7 +212,7 @@ return [ 'jquery.highlightText' => [ 'scripts' => 'resources/src/jquery/jquery.highlightText.js', 'dependencies' => [ - 'mediawiki.RegExp', + 'mediawiki.util', ], 'targets' => [ 'desktop', 'mobile' ], ], @@ -288,7 +288,7 @@ return [ 'messages' => [ 'sort-descending', 'sort-ascending' ], 'dependencies' => [ 'jquery.tablesorter.styles', - 'mediawiki.RegExp', + 'mediawiki.util', 'mediawiki.language.months', ], ], @@ -755,7 +755,7 @@ return [ ], 'dependencies' => [ 'mediawiki.language', - 'mediawiki.RegExp', + 'mediawiki.util', ], 'targets' => [ 'desktop', 'mobile' ], ], @@ -926,7 +926,7 @@ return [ 'resources/src/mediawiki.htmlform/selectorother.js', ], 'dependencies' => [ - 'mediawiki.RegExp', + 'mediawiki.util', 'jquery.lengthLimit', ], 'messages' => [ @@ -967,7 +967,7 @@ return [ 'scripts' => 'resources/src/mediawiki.inspect.js', 'dependencies' => [ 'mediawiki.String', - 'mediawiki.RegExp', + 'mediawiki.util', ], 'targets' => [ 'desktop', 'mobile' ], ], @@ -1027,8 +1027,12 @@ return [ 'targets' => [ 'desktop', 'mobile' ], ], 'mediawiki.RegExp' => [ + 'deprecated' => 'Please use mw.util.escapeRegExp() instead.', 'scripts' => 'resources/src/mediawiki.RegExp.js', 'targets' => [ 'desktop', 'mobile' ], + 'dependencies' => [ + 'mediawiki.util', + ], ], 'mediawiki.String' => [ 'scripts' => 'resources/src/mediawiki.String.js', @@ -1261,7 +1265,6 @@ return [ ], 'dependencies' => [ 'jquery.client', - 'mediawiki.RegExp', ], 'messages' => [ 'brackets', 'word-separator' ], 'targets' => [ 'desktop', 'mobile' ], @@ -1699,7 +1702,7 @@ return [ 'mediawiki.util', 'mediawiki.Title', 'mediawiki.jqueryMsg', - 'mediawiki.RegExp', + 'mediawiki.util', ], 'messages' => [ 'watch', @@ -2638,7 +2641,7 @@ return [ 'period-pm', ], 'dependencies' => [ - 'mediawiki.RegExp', + 'mediawiki.util', 'oojs-ui-core', 'oojs-ui.styles.icons-moderation', 'oojs-ui.styles.icons-movement', diff --git a/resources/src/jquery.tablesorter/jquery.tablesorter.js b/resources/src/jquery.tablesorter/jquery.tablesorter.js index 7a131da48e..a6c8cd7bab 100644 --- a/resources/src/jquery.tablesorter/jquery.tablesorter.js +++ b/resources/src/jquery.tablesorter/jquery.tablesorter.js @@ -543,7 +543,7 @@ // Construct regexes for number identification for ( i = 0; i < ascii.length; i++ ) { ts.transformTable[ localised[ i ] ] = ascii[ i ]; - digits.push( mw.RegExp.escape( localised[ i ] ) ); + digits.push( mw.util.escapeRegExp( localised[ i ] ) ); } } digitClass = '[' + digits.join( '', digits ) + ']'; @@ -569,13 +569,13 @@ for ( i = 0; i < 12; i++ ) { name = mw.language.months.names[ i ].toLowerCase(); ts.monthNames[ name ] = i + 1; - regex.push( mw.RegExp.escape( name ) ); + regex.push( mw.util.escapeRegExp( name ) ); name = mw.language.months.genitive[ i ].toLowerCase(); ts.monthNames[ name ] = i + 1; - regex.push( mw.RegExp.escape( name ) ); + regex.push( mw.util.escapeRegExp( name ) ); name = mw.language.months.abbrev[ i ].toLowerCase().replace( '.', '' ); ts.monthNames[ name ] = i + 1; - regex.push( mw.RegExp.escape( name ) ); + regex.push( mw.util.escapeRegExp( name ) ); } // Build piped string @@ -750,7 +750,7 @@ if ( ts.collationTable ) { // Build array of key names for ( key in ts.collationTable ) { - keys.push( mw.RegExp.escape( key ) ); + keys.push( mw.util.escapeRegExp( key ) ); } if ( keys.length ) { ts.collationRegex = new RegExp( keys.join( '|' ), 'ig' ); diff --git a/resources/src/jquery/jquery.highlightText.js b/resources/src/jquery/jquery.highlightText.js index de0860724c..1fabb431fd 100644 --- a/resources/src/jquery/jquery.highlightText.js +++ b/resources/src/jquery/jquery.highlightText.js @@ -17,7 +17,7 @@ } $.highlightText.innerHighlight( node, - new RegExp( '(^|\\s)' + mw.RegExp.escape( words[ i ] ), 'i' ) + new RegExp( '(^|\\s)' + mw.util.escapeRegExp( words[ i ] ), 'i' ) ); } return node; @@ -26,7 +26,7 @@ prefixHighlight: function ( node, prefix ) { $.highlightText.innerHighlight( node, - new RegExp( '(^)' + mw.RegExp.escape( prefix ), 'i' ) + new RegExp( '(^)' + mw.util.escapeRegExp( prefix ), 'i' ) ); }, @@ -38,7 +38,7 @@ $.highlightText.innerHighlight( node, - new RegExp( '(^)' + mw.RegExp.escape( prefix ) + comboMarks + '*', 'i' ) + new RegExp( '(^)' + mw.util.escapeRegExp( prefix ) + comboMarks + '*', 'i' ) ); }, diff --git a/resources/src/mediawiki.RegExp.js b/resources/src/mediawiki.RegExp.js index 5323d4fd87..258bc2c3b7 100644 --- a/resources/src/mediawiki.RegExp.js +++ b/resources/src/mediawiki.RegExp.js @@ -1,22 +1,5 @@ ( function () { - /** - * @class mw.RegExp - */ - mw.RegExp = { - /** - * Escape string for safe inclusion in regular expression - * - * The following characters are escaped: - * - * \ { } ( ) | . ? * + - ^ $ [ ] - * - * @since 1.26 - * @static - * @param {string} str String to escape - * @return {string} Escaped string - */ - escape: function ( str ) { - return str.replace( /([\\{}()|.?*+\-^$\[\]])/g, '\\$1' ); // eslint-disable-line no-useless-escape - } - }; + mw.RegExp = {}; + // Backwards-compatible alias; @deprecated since 1.34 + mw.log.deprecate( mw.RegExp, 'escape', mw.util.escapeRegExp, 'Use mw.util.escapeRegExp() instead.', 'mw.RegExp.escape' ); }() ); diff --git a/resources/src/mediawiki.htmlform/cloner.js b/resources/src/mediawiki.htmlform/cloner.js index 99eebae30b..9cafcd43e3 100644 --- a/resources/src/mediawiki.htmlform/cloner.js +++ b/resources/src/mediawiki.htmlform/cloner.js @@ -16,7 +16,7 @@ var $li, $ul = $createButton.prev( 'ul.mw-htmlform-cloner-ul' ), html = $ul.data( 'template' ).replace( - new RegExp( mw.RegExp.escape( $ul.data( 'uniqueId' ) ), 'g' ), + new RegExp( mw.util.escapeRegExp( $ul.data( 'uniqueId' ) ), 'g' ), 'clone' + ( ++cloneCounter ) ); diff --git a/resources/src/mediawiki.inspect.js b/resources/src/mediawiki.inspect.js index 7f4af5bd81..c7b99b21e9 100644 --- a/resources/src/mediawiki.inspect.js +++ b/resources/src/mediawiki.inspect.js @@ -242,7 +242,7 @@ */ inspect.grep = function ( pattern ) { if ( typeof pattern.test !== 'function' ) { - pattern = new RegExp( mw.RegExp.escape( pattern ), 'g' ); + pattern = new RegExp( mw.util.escapeRegExp( pattern ), 'g' ); } return inspect.getLoadedModules().filter( function ( moduleName ) { diff --git a/resources/src/mediawiki.page.watch.ajax.js b/resources/src/mediawiki.page.watch.ajax.js index f550a91516..6b04b3c5a9 100644 --- a/resources/src/mediawiki.page.watch.ajax.js +++ b/resources/src/mediawiki.page.watch.ajax.js @@ -91,7 +91,7 @@ actionPaths = mw.config.get( 'wgActionPaths' ); for ( key in actionPaths ) { parts = actionPaths[ key ].split( '$1' ); - parts = parts.map( mw.RegExp.escape ); + parts = parts.map( mw.util.escapeRegExp ); m = new RegExp( parts.join( '(.+)' ) ).exec( url ); if ( m && m[ 1 ] ) { return key; diff --git a/resources/src/mediawiki.util/jquery.accessKeyLabel.js b/resources/src/mediawiki.util/jquery.accessKeyLabel.js index cdc5808ca7..a2f92517d1 100644 --- a/resources/src/mediawiki.util/jquery.accessKeyLabel.js +++ b/resources/src/mediawiki.util/jquery.accessKeyLabel.js @@ -138,7 +138,7 @@ } parts = ( separatorMsg + mw.message( 'brackets' ).plain() ).split( '$1' ); - regexp = new RegExp( parts.map( mw.RegExp.escape ).join( '.*?' ) + '$' ); + regexp = new RegExp( parts.map( mw.util.escapeRegExp ).join( '.*?' ) + '$' ); newTitle = oldTitle.replace( regexp, '' ); accessKeyLabel = getAccessKeyLabel( element ); diff --git a/resources/src/mediawiki.util/util.js b/resources/src/mediawiki.util/util.js index 7e0722f442..0d9a88017a 100644 --- a/resources/src/mediawiki.util/util.js +++ b/resources/src/mediawiki.util/util.js @@ -209,7 +209,7 @@ */ getParamValue: function ( param, url ) { // Get last match, stop at hash - var re = new RegExp( '^[^#]*[&?]' + mw.RegExp.escape( param ) + '=([^&#]*)' ), + var re = new RegExp( '^[^#]*[&?]' + util.escapeRegExp( param ) + '=([^&#]*)' ), m = re.exec( url !== undefined ? url : location.href ); if ( m ) { @@ -515,6 +515,22 @@ isIPAddress: function ( address, allowBlock ) { return util.isIPv4Address( address, allowBlock ) || util.isIPv6Address( address, allowBlock ); + }, + + /** + * Escape string for safe inclusion in regular expression + * + * The following characters are escaped: + * + * \ { } ( ) | . ? * + - ^ $ [ ] + * + * @since 1.26; moved to mw.util in 1.34 + * @param {string} str String to escape + * @return {string} Escaped string + */ + escapeRegExp: function ( str ) { + // eslint-disable-next-line no-useless-escape + return str.replace( /([\\{}()|.?*+\-^$\[\]])/g, '\\$1' ); } }; diff --git a/resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js b/resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js index 81cf433f38..7102b6710f 100644 --- a/resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js +++ b/resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js @@ -415,7 +415,7 @@ // eslint-disable-next-line no-restricted-properties v = v.normalize(); } - re = new RegExp( '^\\s*' + mw.RegExp.escape( v ), 'i' ); + re = new RegExp( '^\\s*' + mw.util.escapeRegExp( v ), 'i' ); for ( k in this.values ) { k = +k; if ( !isNaN( k ) && re.test( this.values[ k ] ) ) { diff --git a/resources/src/moment/moment-locale-overrides.js b/resources/src/moment/moment-locale-overrides.js index 04658b92ae..d00ed82eab 100644 --- a/resources/src/moment/moment-locale-overrides.js +++ b/resources/src/moment/moment-locale-overrides.js @@ -10,7 +10,7 @@ if ( mw.config.get( 'wgTranslateNumerals' ) ) { for ( i = 0; i < 10; i++ ) { if ( table[ i ] !== undefined ) { - s = s.replace( new RegExp( mw.RegExp.escape( table[ i ] ), 'g' ), i ); + s = s.replace( new RegExp( mw.util.escapeRegExp( table[ i ] ), 'g' ), i ); } } } diff --git a/tests/qunit/QUnitTestResources.php b/tests/qunit/QUnitTestResources.php index 76f4f82c89..cab6c3bf99 100644 --- a/tests/qunit/QUnitTestResources.php +++ b/tests/qunit/QUnitTestResources.php @@ -60,7 +60,6 @@ return [ 'tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.messagePoster.factory.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.RegExp.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.String.byteLength.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.String.trimByteLength.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.storage.test.js', @@ -115,7 +114,6 @@ return [ 'mediawiki.ForeignApi.core', 'mediawiki.jqueryMsg', 'mediawiki.messagePoster', - 'mediawiki.RegExp', 'mediawiki.String', 'mediawiki.storage', 'mediawiki.Title', diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.RegExp.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.RegExp.test.js deleted file mode 100644 index cde77e72a4..0000000000 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.RegExp.test.js +++ /dev/null @@ -1,38 +0,0 @@ -( function () { - QUnit.module( 'mediawiki.RegExp' ); - - QUnit.test( 'escape', function ( assert ) { - var specials, normal; - - specials = [ - '\\', - '{', - '}', - '(', - ')', - '[', - ']', - '|', - '.', - '?', - '*', - '+', - '-', - '^', - '$' - ]; - - normal = [ - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', - 'abcdefghijklmnopqrstuvwxyz', - '0123456789' - ].join( '' ); - - specials.forEach( function ( str ) { - assert.propEqual( str.match( new RegExp( mw.RegExp.escape( str ) ) ), [ str ], 'Match ' + str ); - } ); - - assert.strictEqual( mw.RegExp.escape( normal ), normal, 'Alphanumerals are left alone' ); - } ); - -}() ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js index 17672db80e..4f61abd186 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js @@ -440,4 +440,38 @@ assert.strictEqual( util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] ); } ); } ); + + QUnit.test( 'escapeRegExp', function ( assert ) { + var specials, normal; + + specials = [ + '\\', + '{', + '}', + '(', + ')', + '[', + ']', + '|', + '.', + '?', + '*', + '+', + '-', + '^', + '$' + ]; + + normal = [ + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + 'abcdefghijklmnopqrstuvwxyz', + '0123456789' + ].join( '' ); + + specials.forEach( function ( str ) { + assert.propEqual( str.match( new RegExp( mw.util.escapeRegExp( str ) ) ), [ str ], 'Match ' + str ); + } ); + + assert.strictEqual( mw.util.escapeRegExp( normal ), normal, 'Alphanumerals are left alone' ); + } ); }() );