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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
'use strict';
const IGNORE_NOTHING = 'ignoreNothing';
const IGNORE_NORMAL = 'ignoreNormal';
const IGNORE_FULL = 'ignoreFull';
const schemeSegment = '(\\*|http|https|ws|wss|file|ftp)';
const hostSegment = '(\\*|(?:\\*\\.)?(?:[^/*]+))?';
const pathSegment = '(.*)';
const isFirefox = function() {
return navigator.userAgent.indexOf('Firefox') !== -1 || navigator.userAgent.indexOf('Gecko/') !== -1;
};
const isEdge = function() {
return navigator.userAgent.indexOf('Edg') !== -1;
};
const showNotification = function(message) {
browser.notifications.create({
'type': 'basic',
'iconUrl': browser.extension.getURL('icons/keepassxc_64x64.png'),
'title': 'KeePassXC-Browser',
'message': message
});
};
const AssociatedAction = {
NOT_ASSOCIATED: 0,
ASSOCIATED: 1,
NEW_ASSOCIATION: 2,
CANCELED: 3
};
const ManualFill = {
NONE: 0,
PASSWORD: 1,
BOTH: 2
};
/**
* Transforms a valid match pattern into a regular expression
* which matches all URLs included by that pattern.
*
* @param {string} pattern The pattern to transform.
* @return {RegExp} The pattern's equivalent as a RegExp.
* @throws {TypeError} If the pattern is not a valid MatchPattern
*
* https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Match_patterns
*/
const matchPatternToRegExp = function(pattern) {
if (pattern === '') {
return (/^(?:http|https|file|ftp|app):\/\//);
}
const matchPatternRegExp = new RegExp(
`^${schemeSegment}://${hostSegment}/${pathSegment}$`
);
const match = matchPatternRegExp.exec(pattern);
if (!match) {
throw new TypeError(`"${pattern}" is not a valid MatchPattern`);
}
let [ , scheme, host, path ] = match;
if (!host) {
throw new TypeError(`"${pattern}" does not have a valid host`);
}
let regex = '^';
if (scheme === '*') {
regex += '(http|https)';
} else {
regex += scheme;
}
regex += '://';
if (host && host === '*') {
regex += '[^/]+?';
} else if (host) {
if (host.match(/^\*\./)) {
regex += '[^/]*?';
host = host.substring(2);
}
regex += host.replace(/\./g, '\\.');
}
if (path) {
path = trimURL(path);
if (path === '*') {
regex += '(/.*)?';
} else if (path.charAt(0) !== '/') {
regex += '/';
regex += path.replace(/\./g, '\\.').replace(/\*/g, '.*?');
regex += '/?';
}
}
regex += '$';
return new RegExp(regex);
};
const siteMatch = function(site, url) {
const rx = matchPatternToRegExp(site);
return url.match(rx);
};
const slashNeededForUrl = function(pattern) {
const matchPattern = new RegExp(`^${schemeSegment}://${hostSegment}$`);
return matchPattern.exec(pattern);
};
function tr(key, params) {
return browser.i18n.getMessage(key, params);
}
// Removes everything after '?' from URL
const trimURL = function(url) {
return url.indexOf('?') !== -1 ? url.split('?')[0] : url;
};
|