From 225719993a7b355dbfde5f0a49e6f161d6f75e41 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bartosz=20Dziewo=C5=84ski?= Date: Tue, 25 Aug 2015 09:43:38 +0200 Subject: [PATCH] mediawiki.Uri: Use extended RegExps through templates JavaScript does not support the 'x' RegExp option for 'extended' RegExps, or named capturing groups, which makes it impossible to write large RegExps in a readable way. OR DOES IT?!? Cons: * Small runtime performance loss to convert to regular RegExp * Worse minification due to unminifiable whitespace (Both of these problems could probably me resolved if we moved the processing server-side somehow, but there's no support for it in ResourceLoader now) Pros: * You can actually somewhat understand the bloody things if you care to, unlike before. YMMV: * The actual regexps are in different files Change-Id: I41630bf20cdb5c2936d85d9f831f2aa7bb8cfef1 --- resources/Resources.php | 8 +++++++ resources/src/mediawiki/mediawiki.Uri.js | 8 +++++-- .../src/mediawiki/mediawiki.Uri.loose.regexp | 22 +++++++++++++++++++ .../src/mediawiki/mediawiki.Uri.strict.regexp | 13 +++++++++++ .../mediawiki/mediawiki.template.regexp.js | 15 +++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 resources/src/mediawiki/mediawiki.Uri.loose.regexp create mode 100644 resources/src/mediawiki/mediawiki.Uri.strict.regexp create mode 100644 resources/src/mediawiki/mediawiki.template.regexp.js diff --git a/resources/Resources.php b/resources/Resources.php index 2293984377..cac87b9203 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -849,6 +849,10 @@ return array( ), 'targets' => array( 'desktop', 'mobile' ), ), + 'mediawiki.template.regexp' => array( + 'scripts' => 'resources/src/mediawiki/mediawiki.template.regexp.js', + 'targets' => array( 'desktop', 'mobile' ), + ), 'mediawiki.apipretty' => array( 'styles' => 'resources/src/mediawiki/mediawiki.apipretty.css', 'targets' => array( 'desktop', 'mobile' ), @@ -1155,6 +1159,10 @@ return array( ), 'mediawiki.Uri' => array( 'scripts' => 'resources/src/mediawiki/mediawiki.Uri.js', + 'templates' => array( + 'strict.regexp' => 'resources/src/mediawiki/mediawiki.Uri.strict.regexp', + 'loose.regexp' => 'resources/src/mediawiki/mediawiki.Uri.loose.regexp', + ), 'dependencies' => 'mediawiki.util', 'targets' => array( 'desktop', 'mobile' ), ), diff --git a/resources/src/mediawiki/mediawiki.Uri.js b/resources/src/mediawiki/mediawiki.Uri.js index 07d89006b2..ac6c583dc6 100644 --- a/resources/src/mediawiki/mediawiki.Uri.js +++ b/resources/src/mediawiki/mediawiki.Uri.js @@ -74,13 +74,17 @@ /** * Regular expressions to parse many common URIs. * + * As they are gnarly, they have been moved to separate files to allow us to format them in the + * 'extended' regular expression format (which JavaScript normally doesn't support). The subset of + * features handled is minimal, but just the free whitespace gives us a lot. + * * @private * @static * @property {Object} parser */ var parser = { - strict: /^(?:([^:\/?#]+):)?(?:\/\/(?:(?:([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?([^:\/?#]*)(?::(\d*))?)?((?:[^?#\/]*\/)*[^?#]*)(?:\?([^#]*))?(?:#(.*))?/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?(?:(?:([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?([^:\/?#]*)(?::(\d*))?((?:\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?[^?#\/]*)(?:\?([^#]*))?(?:#(.*))?/ + strict: mw.template.get( 'mediawiki.Uri', 'strict.regexp' ).render(), + loose: mw.template.get( 'mediawiki.Uri', 'loose.regexp' ).render() }, /** diff --git a/resources/src/mediawiki/mediawiki.Uri.loose.regexp b/resources/src/mediawiki/mediawiki.Uri.loose.regexp new file mode 100644 index 0000000000..300ab3bacf --- /dev/null +++ b/resources/src/mediawiki/mediawiki.Uri.loose.regexp @@ -0,0 +1,22 @@ +^ +(?: + (?![^:@]+:[^:@/]*@) + (?[^:/?#.]+): +)? +(?://)? +(?:(?: + (?[^:@/?#]*) + (?::(?[^:@/?#]*))? +)?@)? +(?[^:/?#]*) +(?::(?\d*))? +( + (?:/ + (?:[^?#] + (?![^?#/]*\.[^?#/.]+(?:[?#]|$)) + )*/? + )? + [^?#/]* +) +(?:\?(?[^#]*))? +(?:\#(?.*))? diff --git a/resources/src/mediawiki/mediawiki.Uri.strict.regexp b/resources/src/mediawiki/mediawiki.Uri.strict.regexp new file mode 100644 index 0000000000..2ac7d2fce9 --- /dev/null +++ b/resources/src/mediawiki/mediawiki.Uri.strict.regexp @@ -0,0 +1,13 @@ +^ +(?:(?[^:/?#]+):)? +(?://(?: + (?: + (?[^:@/?#]*) + (?::(?[^:@/?#]*))? + )?@)? + (?[^:/?#]*) + (?::(?\d*))? +)? +(?(?:[^?#/]*/)*[^?#]*) +(?:\?(?[^#]*))? +(?:\#(?.*))? diff --git a/resources/src/mediawiki/mediawiki.template.regexp.js b/resources/src/mediawiki/mediawiki.template.regexp.js new file mode 100644 index 0000000000..3ec0a1f5c9 --- /dev/null +++ b/resources/src/mediawiki/mediawiki.template.regexp.js @@ -0,0 +1,15 @@ +mediaWiki.template.registerCompiler( 'regexp', { + compile: function ( src ) { + return { + render: function () { + return new RegExp( + src + // Remove whitespace + .replace( /\s+/g, '' ) + // Remove named capturing groups + .replace( /\?<\w+?>/g, '' ) + ); + } + }; + } +} ); -- 2.20.1