-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for the 'y' flag to the RegExp constructor #492
Conversation
IIRC I had some problems with old FF when I played with something like this. Need to test it. |
What do you mean approximately with "old"? I can try to download it and check. |
I don't remember. Early implementations. It was in 2015. |
Most likely it was related this issue. |
77a7102
to
775b17f
Compare
I have tested this PR in firefox 11: it was affected by that bug which I fixed in 775b17f.
EDIT: Fixed |
RegExpWrapper | ||
); | ||
|
||
if (UNSUPPORTED_Y) defineProperty(result, 'sticky', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be placed on the prototype. I'm not sure that it's 100% safe, but before users issues, we can try it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we place it in the prototype, I'm not sure how we could check if the regexp is sticky.
Maybe I could add a __core-js_sticky__
own property and then make sticky
a prototype accessor for that property? I don't want to use a weakmap since it would always need to be polyfilled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests/tests/es.regexp.exec.js
Outdated
@@ -26,3 +26,33 @@ QUnit.test('RegExp#exec capturing groups', assert => { | |||
// #replace, but here also #replace is buggy :( | |||
// assert.deepEqual(/(a?)?/.exec('x'), ['', undefined], '/(a?)?/.exec("x") returns ["", undefined]'); | |||
}); | |||
|
|||
QUnit.test('RegExp#exec sticky', assert => { | |||
const re = new RegExp('a', 'y'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not polyfill RegExp
constructor in IE8- since we can't add accessors. At least, this test should be ignored in engines without descriptors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I'm also moving it to a separate file.
I have tested this PR in modern Chrome (full sticky support), Firefox 11 (broken sticky support) and IE11 (no sticky support). Note that in Firefox 11 it is not possible to polyfill the .sticky accessor, so I had to disable some tests there. |
edge: '13', | ||
firefox: '3', | ||
opera: '36', | ||
safari: '10.0', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got this data from MDN. Note that on Firefox 3 the y
flags doesn't correctly work with regexp methods, but this compat entry is only about the .sticky
accessor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need data for modern opera
- it's generated from chrome
.
@@ -20,6 +19,12 @@ var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () { | |||
return ''.replace(re, '$<a>') !== '7'; | |||
}); | |||
|
|||
// IE <= 11 replaces $0 with the whole match, as if it was $& | |||
// https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0 | |||
var REPLACE_KEEPS_$0 = (function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you prefer I can move this fix to a separate PR. I fixed it here just because I saw the tests failing on IE11 and it is related to RegExps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, it's fine 👍
tests/compat/tests.js
Outdated
return new RegExp('a', 'y').sticky === true; | ||
} catch (e) { | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need try / catch
here - we have it in tests runner.
@@ -710,6 +710,13 @@ GLOBAL.tests = { | |||
'es.regexp.flags': function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we should also update this and RegExp
constructor tests and results, maybe something else.
@@ -99,24 +95,22 @@ require('../internals/fix-regexp-well-known-symbol-logic')( | |||
var flags = (rx.ignoreCase ? 'i' : '') + | |||
(rx.multiline ? 'm' : '') + | |||
(rx.unicode ? 'u' : '') + | |||
(SUPPORTS_Y ? 'y' : 'g'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!
var arrayPush = [].push; | ||
var min = Math.min; | ||
var MAX_UINT32 = 0xffffffff; | ||
|
||
// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError | ||
var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); }); | ||
|
||
// @@split logic | ||
require('../internals/fix-regexp-well-known-symbol-logic')( | ||
'split', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In internalSplit
, we have possible RegExp
call with y
flag.
I realise this issue has been stale for a while, but I would just like to add my findings here. We've been using the fluent library in our project, which heavily relies on the sticky flag, and uses the lastIndex to move the cursor through the string while using multiple regexps with test and exec.
A quick fix for this is to patch Repro that fails in IE:
|
@ThaNarie since that PR is suspended, feel free to make an alternative version if it's interesting for you. |
@ThaNarie I don't have much time to pick this up again, buy if you want you could just take this PR and modify it if it's easier! |
My team has been running into the same issues w/ Fluent that @ThaNarie mentioned, so we are planning on taking a shot at getting an updated version of this PR up. We haven't contributed to core-js before, so we'll dig into the CONTRIBUTING doc and see what we can figure out! |
@HankMcCoy if you will have questions, ask me -) |
@HankMcCoy I will also dedicate some time in the coming weeks. It would be awesome if we could collaborate. |
zloirock#492 Co-authored-by: Nicolò Ribaudo <[email protected]>
zloirock#492 Co-authored-by: Nicolò Ribaudo <[email protected]>
We already partially had this logic in
RegExp#@@split
: I removed it from there and moved to theRegExp
exec internal polyfill.The changes to the exec constructor are mainly moving things to a single expression to different statements, so that I could place the two
SUPPORTS_Y
blocks in between.Fixes #372