Closed SeaHOH closed 1 year ago
I had looked into using XRegExp before, but scrapped that idea because I couldn't get a robust method to replace literal expressions.
const namedGroupsSub = [/([=(])\/((?:[^/]|\\\/)*?\(\?<(?:[^/]|\\\/)+)\/([dgimsuy]*)([,;)])/g, namedGroupsFill];
*/
If that expression works reliably, it could be used to rewrite all Regex to XRegExp, which would also give us support for Unicode categories (\p{FOO}
) and a few other things on top of your polyfill.
XRegExp looks powerful, but seems unsuitable for polyfill, it's a new style, not just a extended.
Not really, they also just extend the RegExp objects. All the other things are optional... but even minified, the simplest useful version compiles to ~200kB, that's a lot.
I'd much rather take yours then, but to be able to get rid of all handcrafted replacements I'm going to throw it at a whole bunch of test cases before integration.
But I saw below description in the doc, they have to do more work for ECMA compatibility, if provide polyfill support.
// Using named capture and flag x for free-spacing and line comments
const date = XRegExp(
`(?<year> [0-9]{4} ) -? # year
(?<month> [0-9]{2} ) -? # month
(?<day> [0-9]{2} ) # day`, 'x');
// XRegExps compile to RegExps and work with native methods
// However, named captures must be referenced using numbered backreferences
// if used with native methods
'2021-02-22'.replace(date, '$2/$3/$1');
// -> '02/22/2021'
Quick update: the last two weekends were spent on writing a parser-based polyfill (temporary repo, force-pushed quite often) based on the code here and a new expression scanner. The idea is to have it robust enough that we can just throw it at all JS and it figures out what needs replacement automatically. Luckily, regular expressions are regular (🤭), so a scanner even for complicated expressions is fairly straightforward (at least until a tc39 proposal lands that makes character classes a language of their own...).
This source compiles to two parts, a runtime segment that gets inserted as a polyfill and a host segment running in Palefill that replaces /foo/
literals with Regexp("foo")
calls. Terser's dead code elimination based conditional compiliation is pretty neat.
Preliminary performance impact is about 10ms/1MB source for NamedRegExpShim.replaceRegExpLiterals
and <=2ms per expression for the runtime transpiling part. With time-to-usable-interface for many "modern" sites upward of 10s, the added time is insignificant.
Downside: it is currently a bit over-eager and really only works with minified source due to context limiting issues. I have an idea how to solve that on the Palefill side, that'll be the next thing before final integration.
There are some bugs:
constructor
// temporary repo
RegExp("foo", "s"); // --> SyntaxError: invalid regular expression flag s
// my polyfill or firefox RegExp("foo", "s"); // --> /foo/s
// both OK RegExp("foo.", "s"); // --> /foo./s
- `Symbol.replace`
```javascript
// temporary repo
"foo bar".replace(RegExp("foo."), "($<foo>)"); // --> TypeError: groups is undefined
// temporary repo and my polyfill (early version)
"foo bar".replace(RegExp("foo.", "s"), "($<foo>)"); // --> "()bar"
"foo bar".replace(RegExp("(?<foo>foo).", "s"), ["($<foo>)", ""]); // --> "($<foo>),"
// my polyfill (current version) or firefox
"foo bar".replace(RegExp("foo."), "($<foo>)"); // --> "($<foo>)bar"
"foo bar".replace(RegExp("foo.", "s"), "($<foo>)"); // --> "($<foo>)bar"
"foo bar".replace(RegExp("(?<foo>foo).", "s"), ["($<foo>)", ""]); // --> "(foo),bar"
// both OK
"foo bar".replace(RegExp("(?<foo>foo).", "s"), "($<foo>)"); // --> "(foo)bar"
And now, I am aware of that use Object.defineProperty
in the constructor
is better instead of define get
function in class NamedRegExp
.
Resolved by implementing full support in PM 32.0 / UXP 6.0
They have started using this feature. e.g. https://github.com/orgs/opensearch-project/projects/30
Related scripts: https://github.githubassets.com/assets/vendors-node_modules_memex-frontend-latest_dist_client_app_bundle_js-e03fc02fea42.js https://github.githubassets.com/assets/chunk-app_assets_modules_github_insights_insights-query_ts-0b114b80f914.js
Only blank pages here. I think we need polyfill until Moonchild add this feature, and I finished it.
1. The polyfill (click)
```javascript /* ============================================================================= RegExp Named Capturing Groups polyfill ============================================================================= Only work with RegExp(...), polyfill with literal notation is impossible. working: // /Foo(?2. The babel polyfill (click)
```javascript function namedGroupsFill(match, splitS, pattern, flags, splitE) { return `${splitS}RegExp("${pattern.replace(/[\\"]/g, "\\$&")}","${flags}")${splitE}` } const namedGroupsSub = [/([=(])\/((?:[^/]|\\\/)*?\(\?<(?:[^/]|\\\/)+)\/([dgimsuy]*)([,;)])/g, namedGroupsFill]; /* /vendors-node_modules_memex-frontend-latest_dist_client_app_bundle_js-*.js /chunk-app_assets_modules_github_insights_insights-query_ts-*.js NAMED_CAPTURING_GROUPS_DONE = NAMED_CAPTURING_GROUPS.replace(...namedGroupsSub); */ ```