-
Notifications
You must be signed in to change notification settings - Fork 3
/
matcher.mjs
102 lines (88 loc) · 3.12 KB
/
matcher.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"use strict";
function areArraysEqual(array1, array2) {
return array1.length === array2.length && array1.every((value, index) => value === array2[index]);
}
function checkTab(tab) {
if (!tab)
throw new Error("Tab can't be null");
if (!tab.url)
throw new Error("Tab should have URL");
}
const defaultConfiguration = [
'https://app.slack.com/client/([\dA-Z]+)/.*',
'https://mail\\.google\\.com/mail/u/(\d+).*',
'https://(?:www\\.spotify\\.com|www\\.open\\.spotify\\.com)/.*',
'https://www\\.google\\.com/maps.*',
'https://([^/]+)/.*',
'http://([^/]+)/.*'
];
class RegexMatcher {
constructor(regexps, debug) {
if (!Array.isArray(regexps))
throw new Error("An array is expected");
for (const regex of regexps) {
if (!regex instanceof RegExp) {
throw new Error("An array of regular expressions is expected");
}
}
this.matchers = regexps;
this.debug = debug;
debug(`Constructed RegexMatcher with ${regexps.length} patterns \n` + regexps);
}
static defaultPatterns() {
RegexMatcher.convertLinesToRegExp(defaultConfiguration, (line, error, pattern) => {
throw new Error(`Pattern ${pattern} is invalid: ${error.message}`)
});
return defaultConfiguration;
}
// Returns an error message if any
static validatePattern(line) {
let error = "";
RegexMatcher.convertLinesToRegExp([line], (lineNumber, e) => error = e.message);
return error;
}
static parsePatterns(regexPatternsAsText, handleErrors) {
if (typeof regexPatternsAsText !== "string")
throw new Error("Regex matcher only accepts a list of patterns separated by a newline symbol");
let lines = regexPatternsAsText.split("\n");
return RegexMatcher.convertLinesToRegExp(lines, handleErrors);
}
static convertLinesToRegExp(lines, handleErrors) {
if (!handleErrors)
throw new Error("Error handler is missing");
let result = [];
lines.forEach((line, i) => {
try {
if (!line)
return;
result.push(new RegExp(line));
} catch (e) {
handleErrors(i, e, line);
}
});
return result;
}
match(targetTab, sourceTab) {
checkTab(targetTab);
checkTab(sourceTab);
const input1 = "" + targetTab.url;
const input2 = "" + sourceTab.url;
for (const matcher of this.matchers) {
this.debug("Matching", input1, input2, "with matcher", matcher);
const match1 = matcher.exec(input1);
const match2 = matcher.exec(input2);
if (match1 || match2) {
this.debug("Match!", match1, match2);
if (!match1)
return false;
if (!match2)
return false;
match1.shift();
match2.shift();
return areArraysEqual(match1, match2);
}
}
return false;
}
}
export {RegexMatcher};