@@ -6,7 +6,67 @@ import { meta } from '../../hydration';
6
6
import type { HooksTree } from 'src/backend/types' ;
7
7
8
8
export function createRegExp ( string : string ) : RegExp {
9
- return new RegExp ( escapeStringRegExp ( string ) , 'i' ) ;
9
+ // Allow /regex/ syntax with optional last /
10
+ if ( string [ 0 ] === '/' ) {
11
+ // Cut off first slash
12
+ string = string . substring ( 1 ) ;
13
+ // Cut off last slash, but only if it's there
14
+ if ( string [ string . length - 1 ] === '/' ) {
15
+ string = string . substring ( 0 , string . length - 1 ) ;
16
+ }
17
+ try {
18
+ return new RegExp ( string , 'i' ) ;
19
+ } catch ( err ) {
20
+ // Bad regex. Make it not match anything.
21
+ // TODO: maybe warn in console?
22
+ return new RegExp ( '.^' ) ;
23
+ }
24
+ }
25
+
26
+ function isLetter ( char : string ) {
27
+ return char . toLowerCase ( ) !== char . toUpperCase ( ) ;
28
+ }
29
+
30
+ function matchAnyCase ( char : string ) {
31
+ if ( ! isLetter ( char ) ) {
32
+ // Don't mess with special characters like [.
33
+ return char ;
34
+ }
35
+ return '[' + char . toLowerCase ( ) + char . toUpperCase ( ) + ']' ;
36
+ }
37
+
38
+ // 'item' should match 'Item' and 'ListItem', but not 'InviteMom'.
39
+ // To do this, we'll slice off 'tem' and check first letter separately.
40
+ const escaped = escapeStringRegExp ( string ) ;
41
+ const firstChar = escaped [ 0 ] ;
42
+ let restRegex = '' ;
43
+ // For 'item' input, restRegex becomes '[tT][eE][mM]'
44
+ // We can't simply make it case-insensitive because first letter case matters.
45
+ for ( let i = 1 ; i < escaped . length ; i ++ ) {
46
+ restRegex += matchAnyCase ( escaped [ i ] ) ;
47
+ }
48
+
49
+ if ( ! isLetter ( firstChar ) ) {
50
+ // We can't put a non-character like [ in a group
51
+ // so we fall back to the simple case.
52
+ return new RegExp ( firstChar + restRegex ) ;
53
+ }
54
+
55
+ // Construct a smarter regex.
56
+ return new RegExp (
57
+ // For example:
58
+ // (^[iI]|I)[tT][eE][mM]
59
+ // Matches:
60
+ // 'Item'
61
+ // 'ListItem'
62
+ // but not 'InviteMom'
63
+ '(^' +
64
+ matchAnyCase ( firstChar ) +
65
+ '|' +
66
+ firstChar . toUpperCase ( ) +
67
+ ')' +
68
+ restRegex
69
+ ) ;
10
70
}
11
71
12
72
export function getMetaValueLabel ( data : Object ) : string | null {
0 commit comments