aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.js24
-rw-r--r--docs/frontend_api.md69
-rw-r--r--package.json1
-rw-r--r--pnpm-lock.yaml563
-rw-r--r--recipes/amazon-web-services/index.js3
-rw-r--r--recipes/amazon-work-mail/webview.js15
-rw-r--r--recipes/android-messages/webview.js20
-rw-r--r--recipes/anonaddy/index.js3
-rw-r--r--recipes/anydo/webview.js14
-rw-r--r--recipes/azure-devops/index.js3
-rw-r--r--recipes/basecamp/webview.js39
-rw-r--r--recipes/binance/index.js3
-rw-r--r--recipes/bip/index.js4
-rw-r--r--recipes/bip/webview.js4
-rw-r--r--recipes/bitbucket/index.js3
-rw-r--r--recipes/bitwarden/index.js3
-rw-r--r--recipes/campuswire/webview.js24
-rw-r--r--recipes/canvas/webview.js6
-rw-r--r--recipes/chatwork/webview.js21
-rw-r--r--recipes/cliq/webview.js8
-rw-r--r--recipes/clockify/webview.js2
-rw-r--r--recipes/devRant/webview.js27
-rw-r--r--recipes/devdocs/index.js3
-rw-r--r--recipes/dingtalk/webview.js27
-rw-r--r--recipes/disqus/webview.js7
-rw-r--r--recipes/epicgames/index.js3
-rw-r--r--recipes/erepublik/index.js3
-rw-r--r--recipes/erepublik/webview.js12
-rwxr-xr-xrecipes/facebook/webview.js16
-rw-r--r--recipes/fastmail/webview.js12
-rw-r--r--recipes/feedbin/webview.js2
-rw-r--r--recipes/feedly/webview.js8
-rw-r--r--recipes/figma/index.js3
-rw-r--r--recipes/fleep/index.js3
-rw-r--r--recipes/freshdesk/index.js3
-rw-r--r--recipes/gadugadu/webview.js4
-rw-r--r--recipes/github/index.js3
-rw-r--r--recipes/github/webview.js2
-rw-r--r--recipes/gitlab/index.js3
-rw-r--r--recipes/gitter/webview.js10
-rw-r--r--recipes/glowing-bear/webview.js7
-rw-r--r--recipes/gmail/index.js3
-rw-r--r--recipes/gmail/webview.js28
-rw-r--r--recipes/google-translate/index.js3
-rw-r--r--recipes/google-voice/webview.js7
-rw-r--r--recipes/googlecalendar/index.js3
-rw-r--r--recipes/googlecalendar/webview-unsafe.js8
-rw-r--r--recipes/googleclassroom/index.js3
-rw-r--r--recipes/googleclassroom/webview.js4
-rw-r--r--recipes/googledrive/index.js3
-rw-r--r--recipes/googlekeep/index.js3
-rw-r--r--recipes/googlemeet/index.js3
-rw-r--r--recipes/googlemeet/webview.js14
-rw-r--r--recipes/grape/index.js6
-rw-r--r--recipes/guilded/webview.js9
-rwxr-xr-xrecipes/habitica/webview.js4
-rw-r--r--recipes/hackmd/index.js3
-rw-r--r--recipes/hangouts/index.js3
-rw-r--r--recipes/hangoutschat/index.js3
-rw-r--r--recipes/hangoutschat/webview.js20
-rw-r--r--recipes/hey/webview.js28
-rw-r--r--recipes/hipchat/index.js6
-rw-r--r--recipes/icloud-reminders/index.js3
-rw-r--r--recipes/icq/webview.js12
-rw-r--r--recipes/idobata/webview.js4
-rw-r--r--recipes/infomaniak-mail/index.js3
-rw-r--r--recipes/infomaniak-mail/webview.js14
-rw-r--r--recipes/instagram/webview.js8
-rw-r--r--recipes/intercom/webview.js10
-rw-r--r--recipes/irccloud/webview.js4
-rw-r--r--recipes/jira/webview.js8
-rw-r--r--recipes/jitsi/webview.js5
-rw-r--r--recipes/jollor/webview.js12
-rw-r--r--recipes/keybase.io/index.js3
-rw-r--r--recipes/lark/webview.js14
-rw-r--r--recipes/lastpass/webview.js22
-rw-r--r--recipes/line-me/index.js3
-rw-r--r--recipes/linkedin/webview.js10
-rw-r--r--recipes/mattermost/index.js4
-rw-r--r--recipes/messenger/webview.js4
-rw-r--r--recipes/mewe/webview.js12
-rw-r--r--recipes/misskey/index.js4
-rwxr-xr-xrecipes/monday/webview.js4
-rw-r--r--recipes/msteams/webview.js14
-rw-r--r--recipes/mstodo/index.js3
-rw-r--r--recipes/mstodo/webview.js4
-rw-r--r--recipes/mysms/webview.js10
-rw-r--r--recipes/nextcloud-talk/webview.js7
-rw-r--r--recipes/nextdoor/webview.js6
-rw-r--r--recipes/notion/webview.js10
-rw-r--r--recipes/odoo/index.js3
-rw-r--r--recipes/office365-owa/webview.js26
-rw-r--r--recipes/onenote/index.js3
-rw-r--r--recipes/pinterest/index.js3
-rw-r--r--recipes/pivotal-tracker/webview.js6
-rw-r--r--recipes/plek/webview.js14
-rw-r--r--recipes/pleroma/index.js6
-rw-r--r--recipes/pleroma/webview.js8
-rw-r--r--recipes/plurk/webview.js8
-rw-r--r--recipes/podio/webview.js8
-rw-r--r--recipes/pomodoro-tracker/index.js3
-rw-r--r--recipes/producthunt/webview.js16
-rw-r--r--recipes/proton-mail/webview.js11
-rw-r--r--recipes/pulsesms/webview.js8
-rw-r--r--recipes/reddit/webview.js19
-rw-r--r--recipes/redditchat/webview.js3
-rw-r--r--recipes/riseup/index.js3
-rw-r--r--recipes/riseup/webview.js4
-rw-r--r--recipes/rocketchat/index.js4
-rw-r--r--recipes/rocketchat/webview.js6
-rw-r--r--recipes/roundcube/webview.js4
-rw-r--r--recipes/scribens/index.js3
-rw-r--r--recipes/scrumpy/webview.js12
-rw-r--r--recipes/simplenote/index.js3
-rw-r--r--recipes/simplenote/webview.js10
-rw-r--r--recipes/slack/webview.js2
-rw-r--r--recipes/slite/webview.js6
-rw-r--r--recipes/slowly/webview.js3
-rw-r--r--recipes/sococo/webview.js8
-rw-r--r--recipes/stackexchange/index.js3
-rw-r--r--recipes/stackoverflow-chat/index.js3
-rw-r--r--recipes/stackoverflow-chat/webview.js10
-rw-r--r--recipes/stackoverflow/webview.js4
-rw-r--r--recipes/steamchat/webview.js33
-rw-r--r--recipes/stride/webview.js4
-rw-r--r--recipes/sync/index.js3
-rw-r--r--recipes/teamleader/webview.js26
-rw-r--r--recipes/teamweek/index.js3
-rw-r--r--recipes/teamwork-projects/webview.js10
-rw-r--r--recipes/telegram-react/webview.js11
-rw-r--r--recipes/telegram/webview.js12
-rw-r--r--recipes/thelounge/webview.js8
-rw-r--r--recipes/threema/webview.js16
-rw-r--r--recipes/tinder/index.js3
-rw-r--r--recipes/todoist/webview.js6
-rw-r--r--recipes/trello/webview.js2
-rw-r--r--recipes/tutanota/index.js3
-rw-r--r--recipes/tweetdeck/webview.js2
-rw-r--r--recipes/twitter-dm/webview.js2
-rw-r--r--recipes/twitter/webview.js12
-rw-r--r--recipes/vk/webview.js4
-rw-r--r--recipes/wakatime/index.js3
-rw-r--r--recipes/webex-teams/webview.js12
-rw-r--r--recipes/wechat/webview.js17
-rw-r--r--recipes/weekplan/webview.js4
-rw-r--r--recipes/whatsapp/webview.js5
-rw-r--r--recipes/whereby/webview.js4
-rw-r--r--recipes/wire/webview.js19
-rw-r--r--recipes/workplace/webview.js21
-rw-r--r--recipes/wrike/webview.js10
-rw-r--r--recipes/xing/webview.js2
-rw-r--r--recipes/yammer/webview.js14
-rw-r--r--recipes/yandex-mail/webview.js4
-rw-r--r--recipes/youtrack/index.js3
-rw-r--r--recipes/zalo/webview.js2
-rw-r--r--recipes/zendesk/webview.js10
-rw-r--r--recipes/zulip/index.js4
-rw-r--r--recipes/zulip/webview.js8
-rw-r--r--scripts/package.js26
-rw-r--r--scripts/sample_recipe/index.js3
160 files changed, 1392 insertions, 543 deletions
diff --git a/.eslintrc.js b/.eslintrc.js
index d9be6f9..25e75f3 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -10,6 +10,26 @@ module.exports = {
10 node: true, 10 node: true,
11 jquery: true, 11 jquery: true,
12 }, 12 },
13 extends: ['eslint:recommended'], 13 extends: ['eslint:recommended', 'plugin:unicorn/recommended'],
14 rules: {}, 14 rules: {
15 // eslint-plugin-unicorn
16 'unicorn/no-null': 0,
17 'unicorn/no-useless-undefined': 0,
18 'unicorn/prefer-module': 0,
19 'unicorn/prevent-abbreviations': 0,
20 'unicorn/prefer-node-protocol': 0,
21 'unicorn/import-style': [
22 2,
23 {
24 styles: {
25 path: {
26 named: true,
27 },
28 },
29 },
30 ],
31 'unicorn/consistent-destructuring': 0,
32 'unicorn/no-array-reduce': 0,
33 'unicorn/no-nested-ternary': 0,
34 },
15}; 35};
diff --git a/docs/frontend_api.md b/docs/frontend_api.md
index cceda9c..aa1070b 100644
--- a/docs/frontend_api.md
+++ b/docs/frontend_api.md
@@ -3,20 +3,26 @@
3Provides a set of helper functions to integrate the service into [Ferdi](https://getferdi.com). 3Provides a set of helper functions to integrate the service into [Ferdi](https://getferdi.com).
4 4
5## Ferdi Class Methods 5## Ferdi Class Methods
6* [setBadge](#user-content-setbadge) 6
7* [injectCSS](#user-content-injectcss) 7- [setBadge](#user-content-setbadge)
8* [loop](#user-content-loop) 8- [injectCSS](#user-content-injectcss)
9* [onNotify](#user-content-onnotify) 9- [loop](#user-content-loop)
10* [handleDarkMode](#user-content-handleDarkMode) 10- [onNotify](#user-content-onnotify)
11- [handleDarkMode](#user-content-handleDarkMode)
11 12
12### setBadge(directMessages, [indirectMessages]) 13### setBadge(directMessages, [indirectMessages])
14
13Sets the unread message badge 15Sets the unread message badge
14 16
15#### Arguments 17#### Arguments
18
161. `int` directMessages 191. `int` directMessages
17 * sets the count of direct messages eg. Slack direct mentions, or a message to @channel 20
21- sets the count of direct messages eg. Slack direct mentions, or a message to @channel
22
182. `int` indirectMessages (optional) 232. `int` indirectMessages (optional)
19 * Set a badge that defines there are new messages but they do not involve me directly to me eg. in a channel 24
25- Set a badge that defines there are new messages but they do not involve me directly to me eg. in a channel
20 26
21#### Usage 27#### Usage
22 28
@@ -29,11 +35,14 @@ Ferdi.setBadge(3);
29``` 35```
30 36
31### injectCSS(pathToCssFile) 37### injectCSS(pathToCssFile)
38
32Injects the contents of one or more CSS files into the current webview 39Injects the contents of one or more CSS files into the current webview
33 40
34#### Arguments 41#### Arguments
42
351. `string` cssFile 431. `string` cssFile
36 * CSS files that should be injected. This must be an absolute path to the file 44
45- CSS files that should be injected. This must be an absolute path to the file
37 46
38#### Usage 47#### Usage
39 48
@@ -51,6 +60,7 @@ Ferdi.injectCSS(globalStyles, focusModeStyles);
51``` 60```
52 61
53### injectJSUnsafe(pathToJsFile) 62### injectJSUnsafe(pathToJsFile)
63
54Injects the contents of one or more JavaScript files into the current webview without context isolation 64Injects the contents of one or more JavaScript files into the current webview without context isolation
55 65
56Ferdi uses context isolation to prevent services from accessing Node.js APIs in the webview. 66Ferdi uses context isolation to prevent services from accessing Node.js APIs in the webview.
@@ -60,8 +70,10 @@ Trying to overwrite properties of the `window` object or other objects or trying
60The code is executed as if part of the body of a Javascript function, ie. you should modify the `window` object explicitly to expose objects in the global scope. 70The code is executed as if part of the body of a Javascript function, ie. you should modify the `window` object explicitly to expose objects in the global scope.
61 71
62#### Arguments 72#### Arguments
73
631. `string` jsFile 741. `string` jsFile
64 * JavaScript files that should be injected. This must be an absolute path to the file 75
76- JavaScript files that should be injected. This must be an absolute path to the file
65 77
66#### Usage 78#### Usage
67 79
@@ -79,9 +91,11 @@ Ferdi.injectCSS(globalScripts, focusModeScripts);
79``` 91```
80 92
81### loop(action) 93### loop(action)
94
82Runs an action every X milliseconds (Ferdi default is currently 1s) 95Runs an action every X milliseconds (Ferdi default is currently 1s)
83 96
84#### Arguments 97#### Arguments
98
851. `function` action 991. `function` action
86 100
87#### Usage 101#### Usage
@@ -90,36 +104,42 @@ Runs an action every X milliseconds (Ferdi default is currently 1s)
90// slack integration 104// slack integration
91const path = require('path'); 105const path = require('path');
92 106
93module.exports = (Ferdi) => { 107module.exports = Ferdi => {
94 const getMessages = () => { 108 const getMessages = () => {
95 const directMessages = $('.unread_highlights, .unread_highlight').not('.hidden').length; 109 const directMessages = $('.unread_highlights, .unread_highlight').not(
110 '.hidden',
111 ).length;
96 const indirectMessages = $('.unread').length - directMessages; 112 const indirectMessages = $('.unread').length - directMessages;
97 113
98 Ferdi.setBadge(directMessages, indirectMessages); 114 Ferdi.setBadge(directMessages, indirectMessages);
99 } 115 };
100 116
101 Ferdi.loop(getMessages); 117 Ferdi.loop(getMessages);
102 118
103 Ferdi.injectCSS(path.join(__dirname, 'style.css')); 119 Ferdi.injectCSS(path.join(__dirname, 'style.css'));
104} 120};
105``` 121```
106 122
107### onNotify(fn) 123### onNotify(fn)
124
108Runs `fn` on every notification created by the service before sending them to the host (Useful if you want to update information of the notification before showing it to the user) 125Runs `fn` on every notification created by the service before sending them to the host (Useful if you want to update information of the notification before showing it to the user)
109 126
110#### Arguments 127#### Arguments
128
1111. `function` fn 1291. `function` fn
112 130
113#### Usage 131#### Usage
114 132
115```js 133```js
116// messenger integration 134// messenger integration
117module.exports = (Ferdi) => { 135module.exports = Ferdi => {
118 const getMessages = () => { 136 const getMessages = () => {
119 let count = document.querySelectorAll('._5fx8:not(._569x),._1ht3:not(._569x)').length; 137 let count = document.querySelectorAll(
138 '._5fx8:not(._569x),._1ht3:not(._569x)',
139 ).length;
120 const messageRequestsElement = document.querySelector('._5nxf'); 140 const messageRequestsElement = document.querySelector('._5nxf');
121 if (messageRequestsElement) { 141 if (messageRequestsElement) {
122 count += parseInt(messageRequestsElement.innerHTML, 10); 142 count += parseInt(messageRequestsElement.textContent, 10);
123 } 143 }
124 144
125 Ferdi.setBadge(count); 145 Ferdi.setBadge(count);
@@ -129,7 +149,8 @@ module.exports = (Ferdi) => {
129 149
130 Ferdi.onNotify(notification => { 150 Ferdi.onNotify(notification => {
131 if (typeof notification.title !== 'string') { 151 if (typeof notification.title !== 'string') {
132 notification.title = ((notification.title.props || {}).content || [])[0] || 'Messenger'; 152 notification.title =
153 ((notification.title.props || {}).content || [])[0] || 'Messenger';
133 } 154 }
134 155
135 return notification; 156 return notification;
@@ -138,6 +159,7 @@ module.exports = (Ferdi) => {
138``` 159```
139 160
140### handleDarkMode(callback) 161### handleDarkMode(callback)
162
141You can use a `darkmode.css` to automatically get the service into a dark theme. If your service already supports its own dark mode (e.g. Reddit and YouTube have built-in dark modes), then you can use a custom dark mode handler instead. 163You can use a `darkmode.css` to automatically get the service into a dark theme. If your service already supports its own dark mode (e.g. Reddit and YouTube have built-in dark modes), then you can use a custom dark mode handler instead.
142 164
143This handler should take the necessary steps to (de-)activate dark mode on the page, e.g. by clicking a button or flipping a switch. 165This handler should take the necessary steps to (de-)activate dark mode on the page, e.g. by clicking a button or flipping a switch.
@@ -145,18 +167,21 @@ This handler should take the necessary steps to (de-)activate dark mode on the p
145Ferdi won't activate DarkReader or inject `darkmode.css` if the recipe has defined a custom handler. If you still need to do this, you can use the `injectDarkModeStyle` or `enableDarkMode` function provided as the second argument. 167Ferdi won't activate DarkReader or inject `darkmode.css` if the recipe has defined a custom handler. If you still need to do this, you can use the `injectDarkModeStyle` or `enableDarkMode` function provided as the second argument.
146 168
147#### Arguments 169#### Arguments
170
1481. `function` callback 1711. `function` callback
149 172
150#### Callback function arguments 173#### Callback function arguments
174
1511. `boolean` isEnabled: Is Dark Mode currently enabled? 1751. `boolean` isEnabled: Is Dark Mode currently enabled?
1522. `object` helpers: Helper functions that you can use in your function: 1762. `object` helpers: Helper functions that you can use in your function:
153 `enableDarkMode` - Enable DarkReader 177 `enableDarkMode` - Enable DarkReader
154 `disableDarkMode` - Disable DarkReader 178 `disableDarkMode` - Disable DarkReader
155 `injectDarkModeStyle` - Inject darkmode.css 179 `injectDarkModeStyle` - Inject darkmode.css
156 `removeDarkModeStyle` - Remove service's darkmode.css 180 `removeDarkModeStyle` - Remove service's darkmode.css
157 `isDarkModeStyleInjected` - Function that returns true if darkmode.css is injected into the page 181 `isDarkModeStyleInjected` - Function that returns true if darkmode.css is injected into the page
158 182
159#### Usage 183#### Usage
184
160```JavaScript 185```JavaScript
161// Handler that works for Reddit 186// Handler that works for Reddit
162Ferdi.handleDarkMode((isEnabled, helpers) => { 187Ferdi.handleDarkMode((isEnabled, helpers) => {
diff --git a/package.json b/package.json
index 60d8e2f..3c91661 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
28 "devDependencies": { 28 "devDependencies": {
29 "@types/targz": "1.0.1", 29 "@types/targz": "1.0.1",
30 "eslint": "7.32.0", 30 "eslint": "7.32.0",
31 "eslint-plugin-unicorn": "36.0.0",
31 "fs-extra": "10.0.0", 32 "fs-extra": "10.0.0",
32 "husky": "7.0.2", 33 "husky": "7.0.2",
33 "image-size": "1.0.0", 34 "image-size": "1.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8ceb3a8..d546822 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3,6 +3,7 @@ lockfileVersion: 5.3
3specifiers: 3specifiers:
4 '@types/targz': 1.0.1 4 '@types/targz': 1.0.1
5 eslint: 7.32.0 5 eslint: 7.32.0
6 eslint-plugin-unicorn: 36.0.0
6 fs-extra: 10.0.0 7 fs-extra: 10.0.0
7 husky: 7.0.2 8 husky: 7.0.2
8 image-size: 1.0.0 9 image-size: 1.0.0
@@ -14,6 +15,7 @@ specifiers:
14devDependencies: 15devDependencies:
15 '@types/targz': 1.0.1 16 '@types/targz': 1.0.1
16 eslint: 7.32.0 17 eslint: 7.32.0
18 eslint-plugin-unicorn: 36.0.0_eslint@7.32.0
17 fs-extra: 10.0.0 19 fs-extra: 10.0.0
18 husky: 7.0.2 20 husky: 7.0.2
19 image-size: 1.0.0 21 image-size: 1.0.0
@@ -30,11 +32,184 @@ packages:
30 '@babel/highlight': 7.14.5 32 '@babel/highlight': 7.14.5
31 dev: true 33 dev: true
32 34
35 /@babel/code-frame/7.14.5:
36 resolution: {integrity: sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==}
37 engines: {node: '>=6.9.0'}
38 dependencies:
39 '@babel/highlight': 7.14.5
40 dev: true
41
42 /@babel/compat-data/7.15.0:
43 resolution: {integrity: sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==}
44 engines: {node: '>=6.9.0'}
45 dev: true
46
47 /@babel/core/7.15.5:
48 resolution: {integrity: sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==}
49 engines: {node: '>=6.9.0'}
50 dependencies:
51 '@babel/code-frame': 7.14.5
52 '@babel/generator': 7.15.4
53 '@babel/helper-compilation-targets': 7.15.4_@babel+core@7.15.5
54 '@babel/helper-module-transforms': 7.15.7
55 '@babel/helpers': 7.15.4
56 '@babel/parser': 7.15.7
57 '@babel/template': 7.15.4
58 '@babel/traverse': 7.15.4
59 '@babel/types': 7.15.6
60 convert-source-map: 1.8.0
61 debug: 4.3.2
62 gensync: 1.0.0-beta.2
63 json5: 2.2.0
64 semver: 6.3.0
65 source-map: 0.5.7
66 transitivePeerDependencies:
67 - supports-color
68 dev: true
69
70 /@babel/eslint-parser/7.15.7_@babel+core@7.15.5+eslint@7.32.0:
71 resolution: {integrity: sha512-yJkHyomClm6A2Xzb8pdAo4HzYMSXFn1O5zrCYvbFP0yQFvHueLedV8WiEno8yJOKStjUXzBZzJFeWQ7b3YMsqQ==}
72 engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0}
73 peerDependencies:
74 '@babel/core': '>=7.11.0'
75 eslint: '>=7.5.0'
76 dependencies:
77 '@babel/core': 7.15.5
78 eslint: 7.32.0
79 eslint-scope: 5.1.1
80 eslint-visitor-keys: 2.1.0
81 semver: 6.3.0
82 dev: true
83
84 /@babel/generator/7.15.4:
85 resolution: {integrity: sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==}
86 engines: {node: '>=6.9.0'}
87 dependencies:
88 '@babel/types': 7.15.6
89 jsesc: 2.5.2
90 source-map: 0.5.7
91 dev: true
92
93 /@babel/helper-compilation-targets/7.15.4_@babel+core@7.15.5:
94 resolution: {integrity: sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==}
95 engines: {node: '>=6.9.0'}
96 peerDependencies:
97 '@babel/core': ^7.0.0
98 dependencies:
99 '@babel/compat-data': 7.15.0
100 '@babel/core': 7.15.5
101 '@babel/helper-validator-option': 7.14.5
102 browserslist: 4.17.3
103 semver: 6.3.0
104 dev: true
105
106 /@babel/helper-function-name/7.15.4:
107 resolution: {integrity: sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==}
108 engines: {node: '>=6.9.0'}
109 dependencies:
110 '@babel/helper-get-function-arity': 7.15.4
111 '@babel/template': 7.15.4
112 '@babel/types': 7.15.6
113 dev: true
114
115 /@babel/helper-get-function-arity/7.15.4:
116 resolution: {integrity: sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==}
117 engines: {node: '>=6.9.0'}
118 dependencies:
119 '@babel/types': 7.15.6
120 dev: true
121
122 /@babel/helper-hoist-variables/7.15.4:
123 resolution: {integrity: sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==}
124 engines: {node: '>=6.9.0'}
125 dependencies:
126 '@babel/types': 7.15.6
127 dev: true
128
129 /@babel/helper-member-expression-to-functions/7.15.4:
130 resolution: {integrity: sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==}
131 engines: {node: '>=6.9.0'}
132 dependencies:
133 '@babel/types': 7.15.6
134 dev: true
135
136 /@babel/helper-module-imports/7.15.4:
137 resolution: {integrity: sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==}
138 engines: {node: '>=6.9.0'}
139 dependencies:
140 '@babel/types': 7.15.6
141 dev: true
142
143 /@babel/helper-module-transforms/7.15.7:
144 resolution: {integrity: sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==}
145 engines: {node: '>=6.9.0'}
146 dependencies:
147 '@babel/helper-module-imports': 7.15.4
148 '@babel/helper-replace-supers': 7.15.4
149 '@babel/helper-simple-access': 7.15.4
150 '@babel/helper-split-export-declaration': 7.15.4
151 '@babel/helper-validator-identifier': 7.15.7
152 '@babel/template': 7.15.4
153 '@babel/traverse': 7.15.4
154 '@babel/types': 7.15.6
155 transitivePeerDependencies:
156 - supports-color
157 dev: true
158
159 /@babel/helper-optimise-call-expression/7.15.4:
160 resolution: {integrity: sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==}
161 engines: {node: '>=6.9.0'}
162 dependencies:
163 '@babel/types': 7.15.6
164 dev: true
165
166 /@babel/helper-replace-supers/7.15.4:
167 resolution: {integrity: sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==}
168 engines: {node: '>=6.9.0'}
169 dependencies:
170 '@babel/helper-member-expression-to-functions': 7.15.4
171 '@babel/helper-optimise-call-expression': 7.15.4
172 '@babel/traverse': 7.15.4
173 '@babel/types': 7.15.6
174 transitivePeerDependencies:
175 - supports-color
176 dev: true
177
178 /@babel/helper-simple-access/7.15.4:
179 resolution: {integrity: sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==}
180 engines: {node: '>=6.9.0'}
181 dependencies:
182 '@babel/types': 7.15.6
183 dev: true
184
185 /@babel/helper-split-export-declaration/7.15.4:
186 resolution: {integrity: sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==}
187 engines: {node: '>=6.9.0'}
188 dependencies:
189 '@babel/types': 7.15.6
190 dev: true
191
33 /@babel/helper-validator-identifier/7.15.7: 192 /@babel/helper-validator-identifier/7.15.7:
34 resolution: {integrity: sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==} 193 resolution: {integrity: sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==}
35 engines: {node: '>=6.9.0'} 194 engines: {node: '>=6.9.0'}
36 dev: true 195 dev: true
37 196
197 /@babel/helper-validator-option/7.14.5:
198 resolution: {integrity: sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==}
199 engines: {node: '>=6.9.0'}
200 dev: true
201
202 /@babel/helpers/7.15.4:
203 resolution: {integrity: sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==}
204 engines: {node: '>=6.9.0'}
205 dependencies:
206 '@babel/template': 7.15.4
207 '@babel/traverse': 7.15.4
208 '@babel/types': 7.15.6
209 transitivePeerDependencies:
210 - supports-color
211 dev: true
212
38 /@babel/highlight/7.14.5: 213 /@babel/highlight/7.14.5:
39 resolution: {integrity: sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==} 214 resolution: {integrity: sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==}
40 engines: {node: '>=6.9.0'} 215 engines: {node: '>=6.9.0'}
@@ -44,6 +219,46 @@ packages:
44 js-tokens: 4.0.0 219 js-tokens: 4.0.0
45 dev: true 220 dev: true
46 221
222 /@babel/parser/7.15.7:
223 resolution: {integrity: sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==}
224 engines: {node: '>=6.0.0'}
225 hasBin: true
226 dev: true
227
228 /@babel/template/7.15.4:
229 resolution: {integrity: sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==}
230 engines: {node: '>=6.9.0'}
231 dependencies:
232 '@babel/code-frame': 7.14.5
233 '@babel/parser': 7.15.7
234 '@babel/types': 7.15.6
235 dev: true
236
237 /@babel/traverse/7.15.4:
238 resolution: {integrity: sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==}
239 engines: {node: '>=6.9.0'}
240 dependencies:
241 '@babel/code-frame': 7.14.5
242 '@babel/generator': 7.15.4
243 '@babel/helper-function-name': 7.15.4
244 '@babel/helper-hoist-variables': 7.15.4
245 '@babel/helper-split-export-declaration': 7.15.4
246 '@babel/parser': 7.15.7
247 '@babel/types': 7.15.6
248 debug: 4.3.2
249 globals: 11.12.0
250 transitivePeerDependencies:
251 - supports-color
252 dev: true
253
254 /@babel/types/7.15.6:
255 resolution: {integrity: sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==}
256 engines: {node: '>=6.9.0'}
257 dependencies:
258 '@babel/helper-validator-identifier': 7.15.7
259 to-fast-properties: 2.0.0
260 dev: true
261
47 /@eslint/eslintrc/0.4.3: 262 /@eslint/eslintrc/0.4.3:
48 resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} 263 resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==}
49 engines: {node: ^10.12.0 || >=12.0.0} 264 engines: {node: ^10.12.0 || >=12.0.0}
@@ -92,6 +307,10 @@ packages:
92 resolution: {integrity: sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==} 307 resolution: {integrity: sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==}
93 dev: true 308 dev: true
94 309
310 /@types/normalize-package-data/2.4.1:
311 resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
312 dev: true
313
95 /@types/tar-fs/2.0.1: 314 /@types/tar-fs/2.0.1:
96 resolution: {integrity: sha512-qlsQyIY9sN7p221xHuXKNoMfUenOcvEBN4zI8dGsYbYCqHtTarXOEXSIgUnK+GcR0fZDse6pAIc5pIrCh9NefQ==} 315 resolution: {integrity: sha512-qlsQyIY9sN7p221xHuXKNoMfUenOcvEBN4zI8dGsYbYCqHtTarXOEXSIgUnK+GcR0fZDse6pAIc5pIrCh9NefQ==}
97 dependencies: 316 dependencies:
@@ -196,6 +415,18 @@ packages:
196 concat-map: 0.0.1 415 concat-map: 0.0.1
197 dev: true 416 dev: true
198 417
418 /browserslist/4.17.3:
419 resolution: {integrity: sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==}
420 engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
421 hasBin: true
422 dependencies:
423 caniuse-lite: 1.0.30001264
424 electron-to-chromium: 1.3.859
425 escalade: 3.1.1
426 node-releases: 1.1.77
427 picocolors: 0.2.1
428 dev: true
429
199 /buffer-alloc-unsafe/1.1.0: 430 /buffer-alloc-unsafe/1.1.0:
200 resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} 431 resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==}
201 dev: true 432 dev: true
@@ -211,11 +442,20 @@ packages:
211 resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=} 442 resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=}
212 dev: true 443 dev: true
213 444
445 /builtin-modules/3.2.0:
446 resolution: {integrity: sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==}
447 engines: {node: '>=6'}
448 dev: true
449
214 /callsites/3.1.0: 450 /callsites/3.1.0:
215 resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 451 resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
216 engines: {node: '>=6'} 452 engines: {node: '>=6'}
217 dev: true 453 dev: true
218 454
455 /caniuse-lite/1.0.30001264:
456 resolution: {integrity: sha512-Ftfqqfcs/ePiUmyaySsQ4PUsdcYyXG2rfoBVsk3iY1ahHaJEw65vfb7Suzqm+cEkwwPIv/XWkg27iCpRavH4zA==}
457 dev: true
458
219 /chalk/2.4.2: 459 /chalk/2.4.2:
220 resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 460 resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
221 engines: {node: '>=4'} 461 engines: {node: '>=4'}
@@ -237,6 +477,17 @@ packages:
237 resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} 477 resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
238 dev: true 478 dev: true
239 479
480 /ci-info/3.2.0:
481 resolution: {integrity: sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==}
482 dev: true
483
484 /clean-regexp/1.0.0:
485 resolution: {integrity: sha1-jffHquUf02h06PjQW5GAvBGj/tc=}
486 engines: {node: '>=4'}
487 dependencies:
488 escape-string-regexp: 1.0.5
489 dev: true
490
240 /color-convert/1.9.3: 491 /color-convert/1.9.3:
241 resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 492 resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
242 dependencies: 493 dependencies:
@@ -262,6 +513,12 @@ packages:
262 resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} 513 resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
263 dev: true 514 dev: true
264 515
516 /convert-source-map/1.8.0:
517 resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
518 dependencies:
519 safe-buffer: 5.1.2
520 dev: true
521
265 /core-util-is/1.0.2: 522 /core-util-is/1.0.2:
266 resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=} 523 resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=}
267 dev: true 524 dev: true
@@ -303,6 +560,10 @@ packages:
303 esutils: 2.0.3 560 esutils: 2.0.3
304 dev: true 561 dev: true
305 562
563 /electron-to-chromium/1.3.859:
564 resolution: {integrity: sha512-gXRXKNWedfdiKIzwr0Mg/VGCvxXzy+4SuK9hp1BDvfbCwx0O5Ot+2f4CoqQkqEJ3Zj/eAV/GoAFgBVFgkBLXuQ==}
565 dev: true
566
306 /emoji-regex/8.0.0: 567 /emoji-regex/8.0.0:
307 resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 568 resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
308 dev: true 569 dev: true
@@ -320,6 +581,17 @@ packages:
320 ansi-colors: 4.1.1 581 ansi-colors: 4.1.1
321 dev: true 582 dev: true
322 583
584 /error-ex/1.3.2:
585 resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
586 dependencies:
587 is-arrayish: 0.2.1
588 dev: true
589
590 /escalade/3.1.1:
591 resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
592 engines: {node: '>=6'}
593 dev: true
594
323 /escape-string-regexp/1.0.5: 595 /escape-string-regexp/1.0.5:
324 resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} 596 resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
325 engines: {node: '>=0.8.0'} 597 engines: {node: '>=0.8.0'}
@@ -330,6 +602,29 @@ packages:
330 engines: {node: '>=10'} 602 engines: {node: '>=10'}
331 dev: true 603 dev: true
332 604
605 /eslint-plugin-unicorn/36.0.0_eslint@7.32.0:
606 resolution: {integrity: sha512-xxN2vSctGWnDW6aLElm/LKIwcrmk6mdiEcW55Uv5krcrVcIFSWMmEgc/hwpemYfZacKZ5npFERGNz4aThsp1AA==}
607 engines: {node: '>=12'}
608 peerDependencies:
609 eslint: '>=7.32.0'
610 dependencies:
611 '@babel/helper-validator-identifier': 7.15.7
612 ci-info: 3.2.0
613 clean-regexp: 1.0.0
614 eslint: 7.32.0
615 eslint-template-visitor: 2.3.2_eslint@7.32.0
616 eslint-utils: 3.0.0_eslint@7.32.0
617 is-builtin-module: 3.1.0
618 lodash: 4.17.21
619 pluralize: 8.0.0
620 read-pkg-up: 7.0.1
621 regexp-tree: 0.1.24
622 safe-regex: 2.1.1
623 semver: 7.3.5
624 transitivePeerDependencies:
625 - supports-color
626 dev: true
627
333 /eslint-scope/5.1.1: 628 /eslint-scope/5.1.1:
334 resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} 629 resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
335 engines: {node: '>=8.0.0'} 630 engines: {node: '>=8.0.0'}
@@ -338,6 +633,21 @@ packages:
338 estraverse: 4.3.0 633 estraverse: 4.3.0
339 dev: true 634 dev: true
340 635
636 /eslint-template-visitor/2.3.2_eslint@7.32.0:
637 resolution: {integrity: sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==}
638 peerDependencies:
639 eslint: '>=7.0.0'
640 dependencies:
641 '@babel/core': 7.15.5
642 '@babel/eslint-parser': 7.15.7_@babel+core@7.15.5+eslint@7.32.0
643 eslint: 7.32.0
644 eslint-visitor-keys: 2.1.0
645 esquery: 1.4.0
646 multimap: 1.1.0
647 transitivePeerDependencies:
648 - supports-color
649 dev: true
650
341 /eslint-utils/2.1.0: 651 /eslint-utils/2.1.0:
342 resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} 652 resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
343 engines: {node: '>=6'} 653 engines: {node: '>=6'}
@@ -345,6 +655,16 @@ packages:
345 eslint-visitor-keys: 1.3.0 655 eslint-visitor-keys: 1.3.0
346 dev: true 656 dev: true
347 657
658 /eslint-utils/3.0.0_eslint@7.32.0:
659 resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
660 engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
661 peerDependencies:
662 eslint: '>=5'
663 dependencies:
664 eslint: 7.32.0
665 eslint-visitor-keys: 2.1.0
666 dev: true
667
348 /eslint-visitor-keys/1.3.0: 668 /eslint-visitor-keys/1.3.0:
349 resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} 669 resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==}
350 engines: {node: '>=4'} 670 engines: {node: '>=4'}
@@ -467,6 +787,14 @@ packages:
467 flat-cache: 3.0.4 787 flat-cache: 3.0.4
468 dev: true 788 dev: true
469 789
790 /find-up/4.1.0:
791 resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
792 engines: {node: '>=8'}
793 dependencies:
794 locate-path: 5.0.0
795 path-exists: 4.0.0
796 dev: true
797
470 /flat-cache/3.0.4: 798 /flat-cache/3.0.4:
471 resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} 799 resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
472 engines: {node: ^10.12.0 || >=12.0.0} 800 engines: {node: ^10.12.0 || >=12.0.0}
@@ -496,10 +824,19 @@ packages:
496 resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} 824 resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
497 dev: true 825 dev: true
498 826
827 /function-bind/1.1.1:
828 resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
829 dev: true
830
499 /functional-red-black-tree/1.0.1: 831 /functional-red-black-tree/1.0.1:
500 resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} 832 resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=}
501 dev: true 833 dev: true
502 834
835 /gensync/1.0.0-beta.2:
836 resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
837 engines: {node: '>=6.9.0'}
838 dev: true
839
503 /glob-parent/5.1.2: 840 /glob-parent/5.1.2:
504 resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 841 resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
505 engines: {node: '>= 6'} 842 engines: {node: '>= 6'}
@@ -518,6 +855,11 @@ packages:
518 path-is-absolute: 1.0.1 855 path-is-absolute: 1.0.1
519 dev: true 856 dev: true
520 857
858 /globals/11.12.0:
859 resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
860 engines: {node: '>=4'}
861 dev: true
862
521 /globals/13.11.0: 863 /globals/13.11.0:
522 resolution: {integrity: sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==} 864 resolution: {integrity: sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==}
523 engines: {node: '>=8'} 865 engines: {node: '>=8'}
@@ -539,6 +881,17 @@ packages:
539 engines: {node: '>=8'} 881 engines: {node: '>=8'}
540 dev: true 882 dev: true
541 883
884 /has/1.0.3:
885 resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
886 engines: {node: '>= 0.4.0'}
887 dependencies:
888 function-bind: 1.1.1
889 dev: true
890
891 /hosted-git-info/2.8.9:
892 resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
893 dev: true
894
542 /husky/7.0.2: 895 /husky/7.0.2:
543 resolution: {integrity: sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==} 896 resolution: {integrity: sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==}
544 engines: {node: '>=12'} 897 engines: {node: '>=12'}
@@ -582,6 +935,23 @@ packages:
582 resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 935 resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
583 dev: true 936 dev: true
584 937
938 /is-arrayish/0.2.1:
939 resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
940 dev: true
941
942 /is-builtin-module/3.1.0:
943 resolution: {integrity: sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==}
944 engines: {node: '>=6'}
945 dependencies:
946 builtin-modules: 3.2.0
947 dev: true
948
949 /is-core-module/2.7.0:
950 resolution: {integrity: sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==}
951 dependencies:
952 has: 1.0.3
953 dev: true
954
585 /is-docker/2.2.1: 955 /is-docker/2.2.1:
586 resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} 956 resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
587 engines: {node: '>=8'} 957 engines: {node: '>=8'}
@@ -632,6 +1002,16 @@ packages:
632 esprima: 4.0.1 1002 esprima: 4.0.1
633 dev: true 1003 dev: true
634 1004
1005 /jsesc/2.5.2:
1006 resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
1007 engines: {node: '>=4'}
1008 hasBin: true
1009 dev: true
1010
1011 /json-parse-even-better-errors/2.3.1:
1012 resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
1013 dev: true
1014
635 /json-schema-traverse/0.4.1: 1015 /json-schema-traverse/0.4.1:
636 resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 1016 resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
637 dev: true 1017 dev: true
@@ -644,6 +1024,14 @@ packages:
644 resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} 1024 resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=}
645 dev: true 1025 dev: true
646 1026
1027 /json5/2.2.0:
1028 resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==}
1029 engines: {node: '>=6'}
1030 hasBin: true
1031 dependencies:
1032 minimist: 1.2.5
1033 dev: true
1034
647 /jsonfile/6.1.0: 1035 /jsonfile/6.1.0:
648 resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} 1036 resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
649 dependencies: 1037 dependencies:
@@ -660,6 +1048,17 @@ packages:
660 type-check: 0.4.0 1048 type-check: 0.4.0
661 dev: true 1049 dev: true
662 1050
1051 /lines-and-columns/1.1.6:
1052 resolution: {integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=}
1053 dev: true
1054
1055 /locate-path/5.0.0:
1056 resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
1057 engines: {node: '>=8'}
1058 dependencies:
1059 p-locate: 4.1.0
1060 dev: true
1061
663 /lodash.clonedeep/4.5.0: 1062 /lodash.clonedeep/4.5.0:
664 resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=} 1063 resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=}
665 dev: true 1064 dev: true
@@ -672,6 +1071,10 @@ packages:
672 resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=} 1071 resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=}
673 dev: true 1072 dev: true
674 1073
1074 /lodash/4.17.21:
1075 resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
1076 dev: true
1077
675 /lru-cache/6.0.0: 1078 /lru-cache/6.0.0:
676 resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 1079 resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
677 engines: {node: '>=10'} 1080 engines: {node: '>=10'}
@@ -700,10 +1103,27 @@ packages:
700 resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1103 resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
701 dev: true 1104 dev: true
702 1105
1106 /multimap/1.1.0:
1107 resolution: {integrity: sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==}
1108 dev: true
1109
703 /natural-compare/1.4.0: 1110 /natural-compare/1.4.0:
704 resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} 1111 resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
705 dev: true 1112 dev: true
706 1113
1114 /node-releases/1.1.77:
1115 resolution: {integrity: sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==}
1116 dev: true
1117
1118 /normalize-package-data/2.5.0:
1119 resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
1120 dependencies:
1121 hosted-git-info: 2.8.9
1122 resolve: 1.20.0
1123 semver: 5.7.1
1124 validate-npm-package-license: 3.0.4
1125 dev: true
1126
707 /once/1.4.0: 1127 /once/1.4.0:
708 resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} 1128 resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
709 dependencies: 1129 dependencies:
@@ -731,6 +1151,25 @@ packages:
731 word-wrap: 1.2.3 1151 word-wrap: 1.2.3
732 dev: true 1152 dev: true
733 1153
1154 /p-limit/2.3.0:
1155 resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
1156 engines: {node: '>=6'}
1157 dependencies:
1158 p-try: 2.2.0
1159 dev: true
1160
1161 /p-locate/4.1.0:
1162 resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
1163 engines: {node: '>=8'}
1164 dependencies:
1165 p-limit: 2.3.0
1166 dev: true
1167
1168 /p-try/2.2.0:
1169 resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
1170 engines: {node: '>=6'}
1171 dev: true
1172
734 /parent-module/1.0.1: 1173 /parent-module/1.0.1:
735 resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 1174 resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
736 engines: {node: '>=6'} 1175 engines: {node: '>=6'}
@@ -738,6 +1177,21 @@ packages:
738 callsites: 3.1.0 1177 callsites: 3.1.0
739 dev: true 1178 dev: true
740 1179
1180 /parse-json/5.2.0:
1181 resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
1182 engines: {node: '>=8'}
1183 dependencies:
1184 '@babel/code-frame': 7.12.11
1185 error-ex: 1.3.2
1186 json-parse-even-better-errors: 2.3.1
1187 lines-and-columns: 1.1.6
1188 dev: true
1189
1190 /path-exists/4.0.0:
1191 resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1192 engines: {node: '>=8'}
1193 dev: true
1194
741 /path-is-absolute/1.0.1: 1195 /path-is-absolute/1.0.1:
742 resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} 1196 resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=}
743 engines: {node: '>=0.10.0'} 1197 engines: {node: '>=0.10.0'}
@@ -748,6 +1202,19 @@ packages:
748 engines: {node: '>=8'} 1202 engines: {node: '>=8'}
749 dev: true 1203 dev: true
750 1204
1205 /path-parse/1.0.7:
1206 resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1207 dev: true
1208
1209 /picocolors/0.2.1:
1210 resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==}
1211 dev: true
1212
1213 /pluralize/8.0.0:
1214 resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
1215 engines: {node: '>=4'}
1216 dev: true
1217
751 /prelude-ls/1.2.1: 1218 /prelude-ls/1.2.1:
752 resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 1219 resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
753 engines: {node: '>= 0.8.0'} 1220 engines: {node: '>= 0.8.0'}
@@ -786,6 +1253,25 @@ packages:
786 inherits: 2.0.4 1253 inherits: 2.0.4
787 dev: true 1254 dev: true
788 1255
1256 /read-pkg-up/7.0.1:
1257 resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
1258 engines: {node: '>=8'}
1259 dependencies:
1260 find-up: 4.1.0
1261 read-pkg: 5.2.0
1262 type-fest: 0.8.1
1263 dev: true
1264
1265 /read-pkg/5.2.0:
1266 resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
1267 engines: {node: '>=8'}
1268 dependencies:
1269 '@types/normalize-package-data': 2.4.1
1270 normalize-package-data: 2.5.0
1271 parse-json: 5.2.0
1272 type-fest: 0.6.0
1273 dev: true
1274
789 /readable-stream/2.3.7: 1275 /readable-stream/2.3.7:
790 resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} 1276 resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==}
791 dependencies: 1277 dependencies:
@@ -798,6 +1284,11 @@ packages:
798 util-deprecate: 1.0.2 1284 util-deprecate: 1.0.2
799 dev: true 1285 dev: true
800 1286
1287 /regexp-tree/0.1.24:
1288 resolution: {integrity: sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==}
1289 hasBin: true
1290 dev: true
1291
801 /regexpp/3.2.0: 1292 /regexpp/3.2.0:
802 resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} 1293 resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
803 engines: {node: '>=8'} 1294 engines: {node: '>=8'}
@@ -813,6 +1304,13 @@ packages:
813 engines: {node: '>=4'} 1304 engines: {node: '>=4'}
814 dev: true 1305 dev: true
815 1306
1307 /resolve/1.20.0:
1308 resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==}
1309 dependencies:
1310 is-core-module: 2.7.0
1311 path-parse: 1.0.7
1312 dev: true
1313
816 /rimraf/3.0.2: 1314 /rimraf/3.0.2:
817 resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 1315 resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
818 hasBin: true 1316 hasBin: true
@@ -828,6 +1326,22 @@ packages:
828 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 1326 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
829 dev: true 1327 dev: true
830 1328
1329 /safe-regex/2.1.1:
1330 resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==}
1331 dependencies:
1332 regexp-tree: 0.1.24
1333 dev: true
1334
1335 /semver/5.7.1:
1336 resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
1337 hasBin: true
1338 dev: true
1339
1340 /semver/6.3.0:
1341 resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
1342 hasBin: true
1343 dev: true
1344
831 /semver/7.3.5: 1345 /semver/7.3.5:
832 resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} 1346 resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==}
833 engines: {node: '>=10'} 1347 engines: {node: '>=10'}
@@ -867,6 +1381,33 @@ packages:
867 is-fullwidth-code-point: 3.0.0 1381 is-fullwidth-code-point: 3.0.0
868 dev: true 1382 dev: true
869 1383
1384 /source-map/0.5.7:
1385 resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=}
1386 engines: {node: '>=0.10.0'}
1387 dev: true
1388
1389 /spdx-correct/3.1.1:
1390 resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==}
1391 dependencies:
1392 spdx-expression-parse: 3.0.1
1393 spdx-license-ids: 3.0.10
1394 dev: true
1395
1396 /spdx-exceptions/2.3.0:
1397 resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==}
1398 dev: true
1399
1400 /spdx-expression-parse/3.0.1:
1401 resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
1402 dependencies:
1403 spdx-exceptions: 2.3.0
1404 spdx-license-ids: 3.0.10
1405 dev: true
1406
1407 /spdx-license-ids/3.0.10:
1408 resolution: {integrity: sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==}
1409 dev: true
1410
870 /sprintf-js/1.0.3: 1411 /sprintf-js/1.0.3:
871 resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} 1412 resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=}
872 dev: true 1413 dev: true
@@ -960,6 +1501,11 @@ packages:
960 resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==} 1501 resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==}
961 dev: true 1502 dev: true
962 1503
1504 /to-fast-properties/2.0.0:
1505 resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=}
1506 engines: {node: '>=4'}
1507 dev: true
1508
963 /type-check/0.4.0: 1509 /type-check/0.4.0:
964 resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 1510 resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
965 engines: {node: '>= 0.8.0'} 1511 engines: {node: '>= 0.8.0'}
@@ -972,6 +1518,16 @@ packages:
972 engines: {node: '>=10'} 1518 engines: {node: '>=10'}
973 dev: true 1519 dev: true
974 1520
1521 /type-fest/0.6.0:
1522 resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
1523 engines: {node: '>=8'}
1524 dev: true
1525
1526 /type-fest/0.8.1:
1527 resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
1528 engines: {node: '>=8'}
1529 dev: true
1530
975 /universalify/2.0.0: 1531 /universalify/2.0.0:
976 resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} 1532 resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
977 engines: {node: '>= 10.0.0'} 1533 engines: {node: '>= 10.0.0'}
@@ -991,6 +1547,13 @@ packages:
991 resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} 1547 resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
992 dev: true 1548 dev: true
993 1549
1550 /validate-npm-package-license/3.0.4:
1551 resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
1552 dependencies:
1553 spdx-correct: 3.1.1
1554 spdx-expression-parse: 3.0.1
1555 dev: true
1556
994 /which/2.0.2: 1557 /which/2.0.2:
995 resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1558 resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
996 engines: {node: '>= 8'} 1559 engines: {node: '>= 8'}
diff --git a/recipes/amazon-web-services/index.js b/recipes/amazon-web-services/index.js
index d0e2779..057cd19 100644
--- a/recipes/amazon-web-services/index.js
+++ b/recipes/amazon-web-services/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class AmazonWebServices extends Ferdi { module.exports = Ferdi => class AmazonWebServices extends Ferdi {};
2};
diff --git a/recipes/amazon-work-mail/webview.js b/recipes/amazon-work-mail/webview.js
index 944a15c..44f3058 100644
--- a/recipes/amazon-work-mail/webview.js
+++ b/recipes/amazon-work-mail/webview.js
@@ -1,6 +1,6 @@
1module.exports = (Ferdi) => { 1const reload = EventType =>
2 const reload = (EventType) => new Promise((resolve, reject) => { 2 new Promise((resolve, reject) => {
3 const btn = document.getElementsByClassName('giraffe-hierarchy-node-refresh')[0]; 3 const btn = document.querySelectorAll('.giraffe-hierarchy-node-refresh')[0];
4 const EventObject = document.createEvent('Events'); 4 const EventObject = document.createEvent('Events');
5 EventObject.initEvent(EventType, true, false); 5 EventObject.initEvent(EventType, true, false);
6 6
@@ -11,12 +11,13 @@ module.exports = (Ferdi) => {
11 } 11 }
12 }); 12 });
13 13
14module.exports = Ferdi => {
14 const getUnread = () => { 15 const getUnread = () => {
15 const nodes = document.getElementsByClassName('giraffe-hierarchy-node-counter'); 16 const nodes = document.querySelectorAll('.giraffe-hierarchy-node-counter');
16 let counter = 0; 17 let counter = 0;
17 18
18 for (let i = 0; i < nodes.length; i++) { 19 for (const node of nodes) {
19 counter += Ferdi.safeParseInt(nodes[i].innerText); 20 counter += Ferdi.safeParseInt(node.textContent);
20 } 21 }
21 22
22 Ferdi.setBadge(counter); 23 Ferdi.setBadge(counter);
@@ -27,6 +28,6 @@ module.exports = (Ferdi) => {
27 28
28 window.setInterval(() => { 29 window.setInterval(() => {
29 reload('click'); 30 reload('click');
30 }, 60000); 31 }, 60_000);
31 } 32 }
32}; 33};
diff --git a/recipes/android-messages/webview.js b/recipes/android-messages/webview.js
index 13def91..35d5de2 100644
--- a/recipes/android-messages/webview.js
+++ b/recipes/android-messages/webview.js
@@ -2,7 +2,13 @@ setTimeout(() => {
2 const elem = document.querySelector('#af-error-container'); 2 const elem = document.querySelector('#af-error-container');
3 3
4 // TODO: This will not work for non-english locales 4 // TODO: This will not work for non-english locales
5 if (elem && elem.innerText.toLowerCase().includes('the requested url was not found on this server')) { 5 if (
6 elem &&
7 elem.textContent &&
8 elem.textContent
9 .toLowerCase()
10 .includes('the requested url was not found on this server')
11 ) {
6 window.location.reload(); 12 window.location.reload();
7 } 13 }
8}, 1000); 14}, 1000);
@@ -11,10 +17,18 @@ module.exports = (Ferdi, settings) => {
11 const getMessages = () => { 17 const getMessages = () => {
12 const messages = document.querySelectorAll('.text-content.unread').length; 18 const messages = document.querySelectorAll('.text-content.unread').length;
13 Ferdi.setBadge(messages); 19 Ferdi.setBadge(messages);
14 } 20 };
15 21
16 window.addEventListener('beforeunload', async () => { 22 window.addEventListener('beforeunload', async () => {
17 Ferdi.clearStorageData(settings.id, { storages: ['appcache', 'serviceworkers', 'cachestorage', 'websql', 'indexdb'] }); 23 Ferdi.clearStorageData(settings.id, {
24 storages: [
25 'appcache',
26 'serviceworkers',
27 'cachestorage',
28 'websql',
29 'indexdb',
30 ],
31 });
18 Ferdi.releaseServiceWorkers(); 32 Ferdi.releaseServiceWorkers();
19 }); 33 });
20 34
diff --git a/recipes/anonaddy/index.js b/recipes/anonaddy/index.js
index d14a262..b8cdae2 100644
--- a/recipes/anonaddy/index.js
+++ b/recipes/anonaddy/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class anonaddy extends Ferdi { module.exports = Ferdi => class anonaddy extends Ferdi {};
2};
diff --git a/recipes/anydo/webview.js b/recipes/anydo/webview.js
index 4f4749b..e1ee479 100644
--- a/recipes/anydo/webview.js
+++ b/recipes/anydo/webview.js
@@ -1,13 +1,15 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 function getTasks() { 2 function getTasks() {
3 let incompleteCount = 0; 3 let incompleteCount = 0;
4 4
5 const countEls = document.querySelectorAll('.AppSidebarListsItems__itemContainer__sizeContainer:not([hidden]) > .AppSidebarListsItems__itemContainer__size'); 5 const countEls = document.querySelectorAll(
6 '.AppSidebarListsItems__itemContainer__sizeContainer:not([hidden]) > .AppSidebarListsItems__itemContainer__size',
7 );
6 8
7 if (countEls.length) { 9 if (countEls.length > 0) {
8 Array.from(countEls).forEach((el) => { 10 for (const el of countEls) {
9 incompleteCount += Ferdi.safeParseInt(el.innerHTML); 11 incompleteCount += Ferdi.safeParseInt(el.textContent);
10 }); 12 }
11 } 13 }
12 14
13 Ferdi.setBadge(incompleteCount); 15 Ferdi.setBadge(incompleteCount);
diff --git a/recipes/azure-devops/index.js b/recipes/azure-devops/index.js
index 2864cca..a6cb2af 100644
--- a/recipes/azure-devops/index.js
+++ b/recipes/azure-devops/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class azuredevops extends Ferdi { module.exports = Ferdi => class azuredevops extends Ferdi {};
2};
diff --git a/recipes/basecamp/webview.js b/recipes/basecamp/webview.js
index 16eced3..9d8e677 100644
--- a/recipes/basecamp/webview.js
+++ b/recipes/basecamp/webview.js
@@ -4,6 +4,14 @@ function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj }; 4 return obj && obj.__esModule ? obj : { default: obj };
5} 5}
6 6
7function show(element) {
8 element.style.display = 'inherit';
9}
10
11function hide(element) {
12 element.style.display = 'none';
13}
14
7module.exports = Ferdi => { 15module.exports = Ferdi => {
8 const modal = document.createElement('div'); 16 const modal = document.createElement('div');
9 17
@@ -16,12 +24,21 @@ module.exports = Ferdi => {
16 }; 24 };
17 function showModal(text) { 25 function showModal(text) {
18 show(modal); 26 show(modal);
19 modal.querySelector('p').innerHTML = text; 27
28 let p = modal.querySelector('p');
29
30 if (p) {
31 p.textContent = text;
32 }
20 } 33 }
21 34
22 function hideModal() { 35 function hideModal() {
23 hide(modal); 36 hide(modal);
24 modal.querySelector('p').innerHTML = ''; 37 let p = modal.querySelector('p');
38
39 if (p) {
40 p.textContent = '';
41 }
25 } 42 }
26 43
27 // Replace window.alert to hide alerts in Ferdi 44 // Replace window.alert to hide alerts in Ferdi
@@ -31,21 +48,17 @@ module.exports = Ferdi => {
31 showModal.apply(oldAlert, arguments); 48 showModal.apply(oldAlert, arguments);
32 }; 49 };
33 50
34 function show(element) {
35 element.style.display = 'inherit';
36 }
37
38 function hide(element) {
39 element.style.display = 'none';
40 }
41
42 modal.id = 'franz-modal'; 51 modal.id = 'franz-modal';
43 modal.innerHTML = 52 modal.textContent =
44 '<div class="modal-content"><span class="close">&times;</span><p></p></div>'; 53 '<div class="modal-content"><span class="close">&times;</span><p></p></div>';
45 modal.querySelector('.close').addEventListener('click', hideModal); 54
55 let close = modal.querySelector('.close');
56 if (close) {
57 close.addEventListener('click', hideModal);
58 }
46 waitFor( 59 waitFor(
47 () => document.body, 60 () => document.body,
48 () => document.body.appendChild(modal), 61 () => document.body.append(modal),
49 ); 62 );
50 63
51 document.addEventListener('keydown', e => { 64 document.addEventListener('keydown', e => {
diff --git a/recipes/binance/index.js b/recipes/binance/index.js
index a6681d5..b4d7495 100644
--- a/recipes/binance/index.js
+++ b/recipes/binance/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Binance extends Ferdi { module.exports = Ferdi => class Binance extends Ferdi {};
2};
diff --git a/recipes/bip/index.js b/recipes/bip/index.js
index 4507e72..8949ee0 100644
--- a/recipes/bip/index.js
+++ b/recipes/bip/index.js
@@ -1,3 +1 @@
1module.exports = Ferdi => class bip extends Ferdi { module.exports = Ferdi => class bip extends Ferdi {};
2
3};
diff --git a/recipes/bip/webview.js b/recipes/bip/webview.js
index ea8fa5f..f3166ce 100644
--- a/recipes/bip/webview.js
+++ b/recipes/bip/webview.js
@@ -6,8 +6,8 @@ module.exports = Ferdi => {
6 const getMessages = () => { 6 const getMessages = () => {
7 const elements = document.querySelectorAll('.contact-list__message__unread-badge-counter'); 7 const elements = document.querySelectorAll('.contact-list__message__unread-badge-counter');
8 let count = 0; 8 let count = 0;
9 for (let i = 0; i < elements.length; i++) { 9 for (const element of elements) {
10 count += Ferdi.safeParseInt(elements[i].textContent); 10 count += Ferdi.safeParseInt(element.textContent);
11 } 11 }
12 Ferdi.setBadge(count, 0); 12 Ferdi.setBadge(count, 0);
13 }; 13 };
diff --git a/recipes/bitbucket/index.js b/recipes/bitbucket/index.js
index 7983bf0..3709b27 100644
--- a/recipes/bitbucket/index.js
+++ b/recipes/bitbucket/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class bitbucket extends Ferdi { module.exports = Ferdi => class bitbucket extends Ferdi {};
2};
diff --git a/recipes/bitwarden/index.js b/recipes/bitwarden/index.js
index a59e581..ab7de5f 100644
--- a/recipes/bitwarden/index.js
+++ b/recipes/bitwarden/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Bitwarden extends Ferdi { module.exports = Ferdi => class Bitwarden extends Ferdi {};
2};
diff --git a/recipes/campuswire/webview.js b/recipes/campuswire/webview.js
index 9837030..418ac9d 100644
--- a/recipes/campuswire/webview.js
+++ b/recipes/campuswire/webview.js
@@ -1,10 +1,12 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let count = document.querySelectorAll('._5fx8:not(._569x),._1ht3:not(._569x)').length; 3 let count = document.querySelectorAll(
4 '._5fx8:not(._569x),._1ht3:not(._569x)',
5 ).length;
4 const messageRequestsElement = document.querySelector('._5nxf'); 6 const messageRequestsElement = document.querySelector('._5nxf');
5 7
6 if (messageRequestsElement) { 8 if (messageRequestsElement) {
7 count += Ferdi.safeParseInt(messageRequestsElement.innerHTML); 9 count += Ferdi.safeParseInt(messageRequestsElement.textContent);
8 } 10 }
9 11
10 Ferdi.setBadge(count); 12 Ferdi.setBadge(count);
@@ -12,19 +14,25 @@ module.exports = Ferdi => {
12 14
13 Ferdi.loop(getMessages); 15 Ferdi.loop(getMessages);
14 16
15 localStorage.setItem('_cs_desktopNotifsEnabled', JSON.stringify({ 17 localStorage.setItem(
16 __t: new Date().getTime(), 18 '_cs_desktopNotifsEnabled',
17 __v: true, 19 JSON.stringify({
18 })); 20 __t: Date.now(),
21 __v: true,
22 }),
23 );
19 24
20 if (typeof Ferdi.onNotify === 'function') { 25 if (typeof Ferdi.onNotify === 'function') {
21 Ferdi.onNotify(notification => { 26 Ferdi.onNotify(notification => {
22 if (typeof notification.title !== 'string') { 27 if (typeof notification.title !== 'string') {
23 notification.title = ((notification.title.props || {}).content || [])[0] || 'Campuswire'; 28 notification.title =
29 ((notification.title.props || {}).content || [])[0] || 'Campuswire';
24 } 30 }
25 31
26 if (typeof notification.options.body !== 'string') { 32 if (typeof notification.options.body !== 'string') {
27 notification.options.body = (((notification.options.body || {}).props || {}).content || [])[0] || ''; 33 notification.options.body =
34 (((notification.options.body || {}).props || {}).content || [])[0] ||
35 '';
28 } 36 }
29 37
30 return notification; 38 return notification;
diff --git a/recipes/canvas/webview.js b/recipes/canvas/webview.js
index a70f448..070a975 100644
--- a/recipes/canvas/webview.js
+++ b/recipes/canvas/webview.js
@@ -2,9 +2,11 @@ module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let direct = 0; 3 let direct = 0;
4 4
5 const MessageElement = document.querySelector('[id=global_nav_conversations_link]'); 5 const MessageElement = document.querySelector(
6 '[id=global_nav_conversations_link]',
7 );
6 if (MessageElement) { 8 if (MessageElement) {
7 direct += Ferdi.safeParseInt(MessageElement.innerHTML); 9 direct += Ferdi.safeParseInt(MessageElement.textContent);
8 } 10 }
9 11
10 Ferdi.setBadge(direct); 12 Ferdi.setBadge(direct);
diff --git a/recipes/chatwork/webview.js b/recipes/chatwork/webview.js
index 05e1912..ed09ef7 100644
--- a/recipes/chatwork/webview.js
+++ b/recipes/chatwork/webview.js
@@ -1,19 +1,26 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let directCount = 0; 3 let directCount = 0;
4 let indirectCount = 0; 4 let indirectCount = 0;
5 const roomInfoContainer = document.querySelectorAll('li.sc-dnqmqq'); 5 const roomInfoContainer = document.querySelectorAll('li.sc-dnqmqq');
6 Array.prototype.forEach.call(roomInfoContainer, (room) => { 6 Array.prototype.forEach.call(roomInfoContainer, room => {
7 let count = 0; 7 let count = 0;
8 const unreadBadge = room.querySelector('span.sc-kAzzGY'); 8 const unreadBadge = room.querySelector('span.sc-kAzzGY');
9 const unreadBadgeHasMention = room.querySelector('li._unreadBadge.sc-cSHVUG'); 9 const unreadBadgeHasMention = room.querySelector(
10 'li._unreadBadge.sc-cSHVUG',
11 );
10 12
11 if (unreadBadge && unreadBadge.innerText) { 13 if (unreadBadge && unreadBadge.textContent) {
12 count = Ferdi.safeParseInt(unreadBadge.innerText); 14 count = Ferdi.safeParseInt(unreadBadge.textContent);
13 } 15 }
14 16
15 if (count > 0) { 17 if (count > 0) {
16 if (room.querySelector('img.sc-gqjmRU').getAttribute('src').indexOf('avatar') < 0) { 18 if (
19 !room
20 .querySelector('img.sc-gqjmRU')
21 .getAttribute('src')
22 .includes('avatar')
23 ) {
17 if (unreadBadgeHasMention) { 24 if (unreadBadgeHasMention) {
18 directCount++; 25 directCount++;
19 } else { 26 } else {
@@ -25,7 +32,7 @@ module.exports = (Ferdi) => {
25 } 32 }
26 }); 33 });
27 Ferdi.setBadge(directCount, indirectCount); 34 Ferdi.setBadge(directCount, indirectCount);
28 } 35 };
29 36
30 Ferdi.loop(getMessages); 37 Ferdi.loop(getMessages);
31}; 38};
diff --git a/recipes/cliq/webview.js b/recipes/cliq/webview.js
index 0c6e550..23607bd 100644
--- a/recipes/cliq/webview.js
+++ b/recipes/cliq/webview.js
@@ -1,7 +1 @@
1module.exports = Ferdi => { module.exports = Ferdi => Ferdi;
2 const getMessages = () => {
3 // Ferdi.setBadge(ConversationsList.getUnreadBadgeCount());
4 };
5
6 Ferdi.loop(getMessages);
7};
diff --git a/recipes/clockify/webview.js b/recipes/clockify/webview.js
index 9fbb613..bf926e4 100644
--- a/recipes/clockify/webview.js
+++ b/recipes/clockify/webview.js
@@ -1,7 +1,7 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const notifications = document.querySelectorAll('.notification--number'); 3 const notifications = document.querySelectorAll('.notification--number');
4 Ferdi.setBadge(0, notifications.length >= 1 ? 1 : 0); 4 Ferdi.setBadge(0, notifications.length > 0 ? 1 : 0);
5 }; 5 };
6 6
7 Ferdi.loop(getMessages); 7 Ferdi.loop(getMessages);
diff --git a/recipes/devRant/webview.js b/recipes/devRant/webview.js
index 9e8b31c..7385db5 100644
--- a/recipes/devRant/webview.js
+++ b/recipes/devRant/webview.js
@@ -1,10 +1,16 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5setTimeout(() => { 7setTimeout(() => {
6 const elem = document.querySelector('.landing-title.version-title'); 8 const elem = document.querySelector('.landing-title.version-title');
7 if (elem && elem.innerText.toLowerCase().includes('google chrome')) { 9 if (
10 elem &&
11 elem.textContent &&
12 elem.textContent.toLowerCase().includes('google chrome')
13 ) {
8 window.location.reload(); 14 window.location.reload();
9 } 15 }
10}, 1000); 16}, 1000);
@@ -13,8 +19,11 @@ module.exports = (Ferdi, settings) => {
13 const getMessages = () => { 19 const getMessages = () => {
14 const elements = document.querySelectorAll('.CxUIE, .unread, ._0LqQ'); 20 const elements = document.querySelectorAll('.CxUIE, .unread, ._0LqQ');
15 let count = 0; 21 let count = 0;
16 for (let i = 0; i < elements.length; i += 1) { 22 for (const element of elements) {
17 if (elements[i].querySelectorAll('.P6z4j').length === 1 && elements[i].querySelectorAll('*[data-icon="muted"]').length === 0) { 23 if (
24 element.querySelectorAll('.P6z4j').length === 1 &&
25 element.querySelectorAll('*[data-icon="muted"]').length === 0
26 ) {
18 count += 1; 27 count += 1;
19 } 28 }
20 } 29 }
@@ -23,7 +32,15 @@ module.exports = (Ferdi, settings) => {
23 }; 32 };
24 33
25 window.addEventListener('beforeunload', async () => { 34 window.addEventListener('beforeunload', async () => {
26 Ferdi.clearStorageData(settings.id, { storages: ['appcache', 'serviceworkers', 'cachestorage', 'websql', 'indexdb'] }); 35 Ferdi.clearStorageData(settings.id, {
36 storages: [
37 'appcache',
38 'serviceworkers',
39 'cachestorage',
40 'websql',
41 'indexdb',
42 ],
43 });
27 Ferdi.releaseServiceWorkers(); 44 Ferdi.releaseServiceWorkers();
28 }); 45 });
29 46
diff --git a/recipes/devdocs/index.js b/recipes/devdocs/index.js
index 91113e0..119cbe1 100644
--- a/recipes/devdocs/index.js
+++ b/recipes/devdocs/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class devdocs extends Ferdi { module.exports = Ferdi => class devdocs extends Ferdi {};
2};
diff --git a/recipes/dingtalk/webview.js b/recipes/dingtalk/webview.js
index aa5f2a3..59881cf 100644
--- a/recipes/dingtalk/webview.js
+++ b/recipes/dingtalk/webview.js
@@ -1,21 +1,28 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 let checkIsRun = false; 8 let checkIsRun = false;
7 const checkHeightAction = () => { 9 const checkHeightAction = () => {
8 checkIsRun = true; 10 checkIsRun = true;
9 let checkHeight = setInterval(() => { 11 let checkHeight = setInterval(() => {
10 let menuPanel = document.getElementById('menu-pannel') 12 let menuPanel = document.querySelector('#menu-pannel');
11 if (!menuPanel) { 13 if (!menuPanel) {
12 return 14 return;
15 }
16 if (menuPanel.parentElement) {
17 menuPanel.parentElement.setAttribute(
18 'style',
19 'height:' + (window.outerHeight - 60) + 'px',
20 );
13 } 21 }
14 menuPanel.parentElement.setAttribute('style', 'height:' + (window.outerHeight - 60) + 'px');
15 clearInterval(checkHeight); 22 clearInterval(checkHeight);
16 checkIsRun = false 23 checkIsRun = false;
17 }, 1000) 24 }, 1000);
18 } 25 };
19 26
20 checkHeightAction(); 27 checkHeightAction();
21 28
@@ -26,8 +33,8 @@ module.exports = (Ferdi) => {
26 }); 33 });
27 34
28 const getMessages = () => { 35 const getMessages = () => {
29 const x = document.querySelectorAll('.unread-num em.ng-binding') 36 const x = document.querySelectorAll('.unread-num em.ng-binding');
30 Ferdi.setBadge(x.length > 0 ? x[0].innerHTML : 0); 37 Ferdi.setBadge(x.length > 0 ? x[0].textContent : 0);
31 }; 38 };
32 39
33 Ferdi.loop(getMessages); 40 Ferdi.loop(getMessages);
diff --git a/recipes/disqus/webview.js b/recipes/disqus/webview.js
index a79f5e7..fcdd386 100644
--- a/recipes/disqus/webview.js
+++ b/recipes/disqus/webview.js
@@ -1,15 +1,14 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getInnerInt = selector => { 2 const getInnerInt = selector => {
3 const element = document.querySelector(selector); 3 const element = document.querySelector(selector);
4 return element && Ferdi.safeParseInt(element.innerText); 4 return element && Ferdi.safeParseInt(element.textContent);
5 }; 5 };
6 6
7 const getMessages = () => { 7 const getMessages = () => {
8 const direct = ( 8 const direct =
9 getInnerInt("header div[data-role='unread-notification-count']") || 9 getInnerInt("header div[data-role='unread-notification-count']") ||
10 getInnerInt('a.has-notifs div.notif-count') || 10 getInnerInt('a.has-notifs div.notif-count') ||
11 0 11 0;
12 );
13 12
14 Ferdi.setBadge(direct); 13 Ferdi.setBadge(direct);
15 }; 14 };
diff --git a/recipes/epicgames/index.js b/recipes/epicgames/index.js
index 891040d..35bf240 100644
--- a/recipes/epicgames/index.js
+++ b/recipes/epicgames/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class epicgames extends Ferdi { module.exports = Ferdi => class epicgames extends Ferdi {};
2};
diff --git a/recipes/erepublik/index.js b/recipes/erepublik/index.js
index 146e5fb..12cdd73 100644
--- a/recipes/erepublik/index.js
+++ b/recipes/erepublik/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class erepublik extends Ferdi { module.exports = Ferdi => class erepublik extends Ferdi {};
2};
diff --git a/recipes/erepublik/webview.js b/recipes/erepublik/webview.js
index 6a105e1..a47c57d 100644
--- a/recipes/erepublik/webview.js
+++ b/recipes/erepublik/webview.js
@@ -4,19 +4,19 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
4 4
5module.exports = Ferdi => { 5module.exports = Ferdi => {
6 const getMessages = () => { 6 const getMessages = () => {
7 const elementNotify = document.getElementsByClassName('notify'); 7 const elementNotify = document.querySelectorAll('.notify');
8 const elementFeed = document.getElementsByClassName('unreadCounter ng-binding ng-scope'); 8 const elementFeed = document.querySelectorAll('.unreadCounter.ng-binding.ng-scope');
9 9
10 let countNotify = 0; 10 let countNotify = 0;
11 let countFeed = 0; 11 let countFeed = 0;
12 12
13 for (let i = 0; i < elementNotify.length; i++) { 13 for (const element of elementNotify) {
14 const splitText = elementNotify[i].title.split(':'); 14 const splitText = element.title.split(':');
15 countNotify += Ferdi.safeParseInt(splitText[1]); 15 countNotify += Ferdi.safeParseInt(splitText[1]);
16 } 16 }
17 17
18 for (let i = 0; i < elementFeed.length; i++) { 18 for (const element of elementFeed) {
19 countFeed += Ferdi.safeParseInt(elementFeed[i].textContent); 19 countFeed += Ferdi.safeParseInt(element.textContent);
20 } 20 }
21 21
22 Ferdi.setBadge(countNotify, countFeed); 22 Ferdi.setBadge(countNotify, countFeed);
diff --git a/recipes/facebook/webview.js b/recipes/facebook/webview.js
index 43de149..b38a2fb 100755
--- a/recipes/facebook/webview.js
+++ b/recipes/facebook/webview.js
@@ -1,19 +1,21 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getNotifications = function getNotifications() { 2 const getNotifications = function getNotifications() {
3 let count = 0; 3 let count = 0;
4 4
5 const elements = [ 5 const elements = [
6 document.getElementById('requestsCountValue'), 6 document.querySelector('#requestsCountValue'),
7 // document.getElementById('mercurymessagesCountValue'), 7 // document.getElementById('mercurymessagesCountValue'),
8 document.getElementById('notificationsCountValue'), 8 document.querySelector('#notificationsCountValue'),
9 document.querySelector('.k4urcfbm.qnrpqo6b.qt6c0cv9.jxrgncrl.jb3vyjys.taijpn5t.datstx6m.pq6dq46d.ljqsnud1.bp9cbjyn'), 9 document.querySelector(
10 '.k4urcfbm.qnrpqo6b.qt6c0cv9.jxrgncrl.jb3vyjys.taijpn5t.datstx6m.pq6dq46d.ljqsnud1.bp9cbjyn',
11 ),
10 ]; 12 ];
11 13
12 elements.forEach((element) => { 14 for (const element of elements) {
13 if (element !== null) { 15 if (element !== null) {
14 count += Ferdi.safeParseInt(element.innerHTML); 16 count += Ferdi.safeParseInt(element.textContent);
15 } 17 }
16 }); 18 }
17 19
18 Ferdi.setBadge(count); 20 Ferdi.setBadge(count);
19 }; 21 };
diff --git a/recipes/fastmail/webview.js b/recipes/fastmail/webview.js
index 42883e8..782963b 100644
--- a/recipes/fastmail/webview.js
+++ b/recipes/fastmail/webview.js
@@ -1,14 +1,18 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 const inbox = document.querySelector('.v-MailboxSource--inbox .v-MailboxSource-badge'); 9 const inbox = document.querySelector(
10 '.v-MailboxSource--inbox .v-MailboxSource-badge',
11 );
8 if (!inbox) { 12 if (!inbox) {
9 return; 13 return;
10 } 14 }
11 const messages = Ferdi.safeParseInt(inbox.innerText); 15 const messages = Ferdi.safeParseInt(inbox.textContent);
12 Ferdi.setBadge(messages); 16 Ferdi.setBadge(messages);
13 }; 17 };
14 18
diff --git a/recipes/feedbin/webview.js b/recipes/feedbin/webview.js
index 197814e..85df36f 100644
--- a/recipes/feedbin/webview.js
+++ b/recipes/feedbin/webview.js
@@ -1,7 +1,7 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 // eslint-disable-next-line no-undef 3 // eslint-disable-next-line no-undef
4 const count = feedbin.count_data.unread_entries.length || 0; 4 const count = feedbin.count_data.unread_entries.length > 0 || 0;
5 Ferdi.setBadge(count); 5 Ferdi.setBadge(count);
6 }; 6 };
7 7
diff --git a/recipes/feedly/webview.js b/recipes/feedly/webview.js
index 1c313e7..3e15fd5 100644
--- a/recipes/feedly/webview.js
+++ b/recipes/feedly/webview.js
@@ -1,10 +1,12 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const newsDOM = document.querySelectorAll("div[title='All'] > .LeftnavListRow__count")[0].innerHTML; 3 const newsDOM = document.querySelectorAll(
4 "div[title='All'] > .LeftnavListRow__count",
5 )[0].textContent;
4 let counter = Ferdi.safeParseInt(newsDOM); 6 let counter = Ferdi.safeParseInt(newsDOM);
5 7
6 if (newsDOM.indexOf('K') !== -1 || newsDOM.indexOf('+') !== -1) { 8 if (newsDOM && (newsDOM.includes('K') || newsDOM.includes('+'))) {
7 counter = `${newsDOM.substring(0, newsDOM.indexOf('K'))}000`; 9 counter = `${newsDOM.slice(0, Math.max(0, newsDOM.indexOf('K')))}000`;
8 } 10 }
9 11
10 Ferdi.setBadge(counter); 12 Ferdi.setBadge(counter);
diff --git a/recipes/figma/index.js b/recipes/figma/index.js
index 734a454..1542871 100644
--- a/recipes/figma/index.js
+++ b/recipes/figma/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class figma extends Ferdi { module.exports = Ferdi => class figma extends Ferdi {};
2};
diff --git a/recipes/fleep/index.js b/recipes/fleep/index.js
index 8f5370b..44283d7 100644
--- a/recipes/fleep/index.js
+++ b/recipes/fleep/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class fleep extends Ferdi { module.exports = Ferdi => class fleep extends Ferdi {};
2};
diff --git a/recipes/freshdesk/index.js b/recipes/freshdesk/index.js
index 4484d30..f2cc5c2 100644
--- a/recipes/freshdesk/index.js
+++ b/recipes/freshdesk/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Freshdesk extends Ferdi { module.exports = Ferdi => class Freshdesk extends Ferdi {};
2};
diff --git a/recipes/gadugadu/webview.js b/recipes/gadugadu/webview.js
index a3c1ee2..2f90db2 100644
--- a/recipes/gadugadu/webview.js
+++ b/recipes/gadugadu/webview.js
@@ -7,8 +7,8 @@ module.exports = Ferdi => {
7 const updates = Ferdi.safeParseInt(document.querySelector('i#sr-last-counter').textContent); 7 const updates = Ferdi.safeParseInt(document.querySelector('i#sr-last-counter').textContent);
8 let messages = 0; 8 let messages = 0;
9 const elements = document.querySelectorAll('.chat-counter:not(.d-none)'); 9 const elements = document.querySelectorAll('.chat-counter:not(.d-none)');
10 for (let i = 0; i < elements.length; i++) { 10 for (const element of elements) {
11 messages += Ferdi.safeParseInt(elements[i].textContent); 11 messages += Ferdi.safeParseInt(element.textContent);
12 } 12 }
13 13
14 Ferdi.setBadge(messages, updates); 14 Ferdi.setBadge(messages, updates);
diff --git a/recipes/github/index.js b/recipes/github/index.js
index a84e54a..84cb38d 100644
--- a/recipes/github/index.js
+++ b/recipes/github/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class GitHub extends Ferdi { module.exports = Ferdi => class GitHub extends Ferdi {};
2};
diff --git a/recipes/github/webview.js b/recipes/github/webview.js
index 47d4a13..d63a4c5 100644
--- a/recipes/github/webview.js
+++ b/recipes/github/webview.js
@@ -5,7 +5,7 @@ module.exports = Ferdi => {
5 ); 5 );
6 let directCount = 0; 6 let directCount = 0;
7 if (directCountElement) { 7 if (directCountElement) {
8 directCount = Ferdi.safeParseInt(directCountElement.innerHTML); 8 directCount = Ferdi.safeParseInt(directCountElement.textContent);
9 } 9 }
10 10
11 const indirectCountElement = document.querySelector( 11 const indirectCountElement = document.querySelector(
diff --git a/recipes/gitlab/index.js b/recipes/gitlab/index.js
index 500d8e8..7183771 100644
--- a/recipes/gitlab/index.js
+++ b/recipes/gitlab/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class gitlab extends Ferdi { module.exports = Ferdi => class gitlab extends Ferdi {};
2};
diff --git a/recipes/gitter/webview.js b/recipes/gitter/webview.js
index e78cadf..0026790 100644
--- a/recipes/gitter/webview.js
+++ b/recipes/gitter/webview.js
@@ -1,14 +1,16 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = Ferdi => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 // get unread messages 9 // get unread messages
8 let count = 0; 10 let count = 0;
9 document.querySelectorAll('div.unread-indicator').forEach((node) => { 11 for (const node of document.querySelectorAll('div.unread-indicator')) {
10 count += Ferdi.safeParseInt(node.innerText); 12 count += Ferdi.safeParseInt(node.textContent);
11 }); 13 }
12 14
13 // set Ferdi badge 15 // set Ferdi badge
14 Ferdi.setBadge(count); 16 Ferdi.setBadge(count);
diff --git a/recipes/glowing-bear/webview.js b/recipes/glowing-bear/webview.js
index 6abd69a..8bb9dfd 100644
--- a/recipes/glowing-bear/webview.js
+++ b/recipes/glowing-bear/webview.js
@@ -3,8 +3,11 @@ module.exports = Ferdi => {
3 const indirectElements = document.querySelectorAll('.badge:not(.danger)'); 3 const indirectElements = document.querySelectorAll('.badge:not(.danger)');
4 const direct = document.querySelectorAll('.badge.danger').length - 1; 4 const direct = document.querySelectorAll('.badge.danger').length - 1;
5 let indirect = -1; 5 let indirect = -1;
6 for (let i = 0; i < indirectElements.length; i += 1) { 6 for (const indirectElement of indirectElements) {
7 if (indirectElements[i].innerHTML.length > 0) { 7 if (
8 indirectElement.textContent &&
9 indirectElement.textContent.length > 0
10 ) {
8 indirect++; 11 indirect++;
9 } 12 }
10 } 13 }
diff --git a/recipes/gmail/index.js b/recipes/gmail/index.js
index 8aae88f..fe5d29b 100644
--- a/recipes/gmail/index.js
+++ b/recipes/gmail/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Gmail extends Ferdi { module.exports = Ferdi => class Gmail extends Ferdi {};
2};
diff --git a/recipes/gmail/webview.js b/recipes/gmail/webview.js
index 23b1382..9b94d33 100644
--- a/recipes/gmail/webview.js
+++ b/recipes/gmail/webview.js
@@ -1,21 +1,33 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 // if the user is on gmail's landing page, go to the login page. 8 // if the user is on gmail's landing page, go to the login page.
7 if (location.hostname == 'www.google.com' && location.href.includes('gmail/about/')) { 9 if (
8 location.href = 'https://accounts.google.com/AccountChooser?service=mail&continue=https://mail.google.com/mail/'; 10 location.hostname == 'www.google.com' &&
11 location.href.includes('gmail/about/')
12 ) {
13 location.href =
14 'https://accounts.google.com/AccountChooser?service=mail&continue=https://mail.google.com/mail/';
9 } 15 }
10 16
11 const getMessages = () => { 17 const getMessages = () => {
12 let count = 0; 18 let count = 0;
13 19
14 const inboxLinks = document.getElementsByClassName('J-Ke n0'); 20 const inboxLinks = document.querySelectorAll('.J-Ke.n0');
15 if (inboxLinks.length > 0) { 21 if (inboxLinks.length > 0) {
16 const unreadCounts = inboxLinks[0].parentNode.parentNode.getElementsByClassName('bsU'); 22 let parentNode = inboxLinks[0].parentNode;
17 if (unreadCounts.length > 0) { 23 if (parentNode) {
18 count = Ferdi.safeParseInt(unreadCounts[0].innerHTML); 24 let parentNodeOfParentNode = parentNode.parentNode;
25 if (parentNodeOfParentNode) {
26 const unreadCounts = parentNodeOfParentNode.querySelectorAll('.bsU');
27 if (unreadCounts.length > 0) {
28 count = Ferdi.safeParseInt(unreadCounts[0].textContent);
29 }
30 }
19 } 31 }
20 } 32 }
21 33
diff --git a/recipes/google-translate/index.js b/recipes/google-translate/index.js
index f714165..4ce580f 100644
--- a/recipes/google-translate/index.js
+++ b/recipes/google-translate/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class GoogleTranslate extends Ferdi { module.exports = Ferdi => class GoogleTranslate extends Ferdi {};
2};
diff --git a/recipes/google-voice/webview.js b/recipes/google-voice/webview.js
index eb3004d..8b2d2b3 100644
--- a/recipes/google-voice/webview.js
+++ b/recipes/google-voice/webview.js
@@ -1,16 +1,15 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 function parseQuery(query) { 2 function parseQuery(query) {
3 const el = document.querySelector(query); 3 const el = document.querySelector(query);
4 return el && Ferdi.safeParseInt(el.innerHTML); 4 return el && Ferdi.safeParseInt(el.textContent);
5 } 5 }
6 6
7 const getMessages = () => { 7 const getMessages = () => {
8 const el = document.querySelector('.msgCount'); 8 const el = document.querySelector('.msgCount');
9 let count; 9 let count;
10 10
11 if (el) { 11 if (el && el.textContent) {
12 // eslint-disable-next-line no-useless-escape 12 count = Ferdi.safeParseInt(el.textContent.replace(/[ ()]/gi, ''));
13 count = Ferdi.safeParseInt(el.innerHTML.replace(/[\(\) ]/gi, ''));
14 } else { 13 } else {
15 const count_messages = parseQuery( 14 const count_messages = parseQuery(
16 'gv-nav-tab[tooltip="Messages"] div[aria-label="Unread count"]', 15 'gv-nav-tab[tooltip="Messages"] div[aria-label="Unread count"]',
diff --git a/recipes/googlecalendar/index.js b/recipes/googlecalendar/index.js
index 553d5ef..e84eca2 100644
--- a/recipes/googlecalendar/index.js
+++ b/recipes/googlecalendar/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class GoogleCalendar extends Ferdi { module.exports = Ferdi => class GoogleCalendar extends Ferdi {};
2};
diff --git a/recipes/googlecalendar/webview-unsafe.js b/recipes/googlecalendar/webview-unsafe.js
index 54a7338..141d3bc 100644
--- a/recipes/googlecalendar/webview-unsafe.js
+++ b/recipes/googlecalendar/webview-unsafe.js
@@ -10,14 +10,14 @@ const waitFor = (condition, callback) => {
10}; 10};
11 11
12const showModal = text => { 12const showModal = text => {
13 modal.querySelector('p').innerHTML = text; 13 modal.querySelector('p').textContent = text;
14 updates += 1; 14 updates += 1;
15 window.ferdi.setBadge(updates); 15 window.ferdi.setBadge(updates);
16 modal.classList.add('open'); 16 modal.classList.add('open');
17}; 17};
18 18
19const hideModal = () => { 19const hideModal = () => {
20 modal.querySelector('p').innerHTML = ''; 20 modal.querySelector('p').textContent = '';
21 updates -= 1; 21 updates -= 1;
22 window.ferdi.setBadge(updates); 22 window.ferdi.setBadge(updates);
23 modal.classList.remove('open'); 23 modal.classList.remove('open');
@@ -26,7 +26,7 @@ const hideModal = () => {
26const createModal = () => { 26const createModal = () => {
27 const modalDialog = document.createElement('div'); 27 const modalDialog = document.createElement('div');
28 modalDialog.setAttribute('id', 'franz-modal'); 28 modalDialog.setAttribute('id', 'franz-modal');
29 modalDialog.innerHTML = 29 modalDialog.textContent =
30 '<div class="modal-content"><span class="close">&times;</span><p></p></div>'; 30 '<div class="modal-content"><span class="close">&times;</span><p></p></div>';
31 modalDialog.querySelector('.close').addEventListener('click', hideModal); 31 modalDialog.querySelector('.close').addEventListener('click', hideModal);
32 32
@@ -38,7 +38,7 @@ window.alert = showModal;
38modal = createModal(); 38modal = createModal();
39waitFor( 39waitFor(
40 () => document.body, 40 () => document.body,
41 () => document.body.appendChild(modal), 41 () => document.body.append(modal),
42); 42);
43document.addEventListener( 43document.addEventListener(
44 'keydown', 44 'keydown',
diff --git a/recipes/googleclassroom/index.js b/recipes/googleclassroom/index.js
index 9ccb30b..e46ccef 100644
--- a/recipes/googleclassroom/index.js
+++ b/recipes/googleclassroom/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class GoogleClassroom extends Ferdi { module.exports = Ferdi => class GoogleClassroom extends Ferdi {};
2};
diff --git a/recipes/googleclassroom/webview.js b/recipes/googleclassroom/webview.js
index 0f24597..f542b00 100644
--- a/recipes/googleclassroom/webview.js
+++ b/recipes/googleclassroom/webview.js
@@ -1,8 +1,8 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let homework = 0; 3 let homework = 0;
4 const upcomingAssignment = document.getElementsByClassName('hrUpcomingAssignmentGroup'); 4 const upcomingAssignment = document.querySelectorAll('.hrUpcomingAssignmentGroup');
5 if (upcomingAssignment.length != 0) { 5 if (upcomingAssignment.length > 0) {
6 let i; 6 let i;
7 for (i = 0; i < upcomingAssignment.length; i++) { 7 for (i = 0; i < upcomingAssignment.length; i++) {
8 homework += upcomingAssignment[i].childElementCount; 8 homework += upcomingAssignment[i].childElementCount;
diff --git a/recipes/googledrive/index.js b/recipes/googledrive/index.js
index c3580bd..7b71e60 100644
--- a/recipes/googledrive/index.js
+++ b/recipes/googledrive/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class googledrive extends Ferdi { module.exports = Ferdi => class googledrive extends Ferdi {};
2};
diff --git a/recipes/googlekeep/index.js b/recipes/googlekeep/index.js
index e311079..4e1c164 100644
--- a/recipes/googlekeep/index.js
+++ b/recipes/googlekeep/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class GoogleKeep extends Ferdi { module.exports = Ferdi => class GoogleKeep extends Ferdi {};
2};
diff --git a/recipes/googlemeet/index.js b/recipes/googlemeet/index.js
index 58aff86..e5d1742 100644
--- a/recipes/googlemeet/index.js
+++ b/recipes/googlemeet/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class GoogleMeet extends Ferdi { module.exports = Ferdi => class GoogleMeet extends Ferdi {};
2};
diff --git a/recipes/googlemeet/webview.js b/recipes/googlemeet/webview.js
index 7a97505..6ea36f3 100644
--- a/recipes/googlemeet/webview.js
+++ b/recipes/googlemeet/webview.js
@@ -1,22 +1,24 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5window.onload = () => { 7window.addEventListener('load', () => {
6 const title = document.querySelector('.window-title').innerHTML; 8 const title = document.querySelector('.window-title').textContent;
7 9
8 if (title && title.includes('Google Chrome 36+')) { 10 if (title && title.includes('Google Chrome 36+')) {
9 window.location.reload(); 11 window.location.reload();
10 } 12 }
11}; 13});
12 14
13module.exports = (Ferdi, settings) => { 15module.exports = (Ferdi, settings) => {
14 const getMessages = () => { 16 const getMessages = () => {
15 const elements = document.querySelectorAll('.CxUIE, .unread'); 17 const elements = document.querySelectorAll('.CxUIE, .unread');
16 let count = 0; 18 let count = 0;
17 19
18 for (let i = 0; i < elements.length; i += 1) { 20 for (const element of elements) {
19 if (elements[i].querySelectorAll('*[data-icon="muted"]').length === 0) { 21 if (element.querySelectorAll('*[data-icon="muted"]').length === 0) {
20 count += 1; 22 count += 1;
21 } 23 }
22 } 24 }
diff --git a/recipes/grape/index.js b/recipes/grape/index.js
index 356b57a..2039c8d 100644
--- a/recipes/grape/index.js
+++ b/recipes/grape/index.js
@@ -1,4 +1,4 @@
1function _asyncToGenerator(fn) { return function () { const gen = fn.apply(this, arguments); return new Promise((resolve, reject) => { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then((value) => { step('next', value); }, (err) => { step('throw', err); }); } } return step('next'); }); }; } 1function _asyncToGenerator(fn) { return function () { const gen = Reflect.apply(fn, this, arguments); return new Promise((resolve, reject) => { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then((value) => { step('next', value); }, (error) => { step('throw', error); }); } } return step('next'); }); }; }
2 2
3module.exports = Ferdi => class Grape extends Ferdi { 3module.exports = Ferdi => class Grape extends Ferdi {
4 validateUrl(url) { 4 validateUrl(url) {
@@ -8,8 +8,8 @@ module.exports = Ferdi => class Grape extends Ferdi {
8 method: 'GET', 8 method: 'GET',
9 }); 9 });
10 return resp.status === 200; 10 return resp.status === 200;
11 } catch (err) { 11 } catch (error) {
12 console.error(err); 12 console.error(error);
13 } 13 }
14 14
15 return false; 15 return false;
diff --git a/recipes/guilded/webview.js b/recipes/guilded/webview.js
index c8d33f2..69c3bcb 100644
--- a/recipes/guilded/webview.js
+++ b/recipes/guilded/webview.js
@@ -1,10 +1,13 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let unread = 0; 3 let unread = 0;
4 const notificationBadge = document.getElementsByClassName('NavSelectorItem-unread-badge')[0]; 4 const notificationBadge = document.querySelectorAll(
5 '.NavSelectorItem-unread-badge',
6 )[0];
5 if (notificationBadge != undefined) { 7 if (notificationBadge != undefined) {
6 const innerBadge = notificationBadge.getElementsByClassName('BadgeV2-count')[0]; 8 const innerBadge =
7 unread = Ferdi.safeParseInt(innerBadge.innerText); 9 notificationBadge.querySelectorAll('.BadgeV2-count')[0];
10 unread = Ferdi.safeParseInt(innerBadge.textContent);
8 } 11 }
9 Ferdi.setBadge(unread); 12 Ferdi.setBadge(unread);
10 }; 13 };
diff --git a/recipes/habitica/webview.js b/recipes/habitica/webview.js
index c856fca..aa678b5 100755
--- a/recipes/habitica/webview.js
+++ b/recipes/habitica/webview.js
@@ -1,9 +1,9 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let count = 0; 3 let count = 0;
4 const element = document.querySelector('.message-count'); 4 const element = document.querySelector('.message-count');
5 if (element) { 5 if (element) {
6 count = Ferdi.safeParseInt(element.innerText); 6 count = Ferdi.safeParseInt(element.textContent);
7 } 7 }
8 Ferdi.setBadge(count); 8 Ferdi.setBadge(count);
9 }; 9 };
diff --git a/recipes/hackmd/index.js b/recipes/hackmd/index.js
index c3d5c52..3a2908b 100644
--- a/recipes/hackmd/index.js
+++ b/recipes/hackmd/index.js
@@ -1,3 +1,2 @@
1// todo allow custom url 1// todo allow custom url
2module.exports = Ferdi => class HackMd extends Ferdi { 2module.exports = Ferdi => class HackMd extends Ferdi {};
3};
diff --git a/recipes/hangouts/index.js b/recipes/hangouts/index.js
index 0a1336f..e2a5585 100644
--- a/recipes/hangouts/index.js
+++ b/recipes/hangouts/index.js
@@ -1,2 +1 @@
1module.exports = (Ferdi) => class Hangouts extends Ferdi { module.exports = (Ferdi) => class Hangouts extends Ferdi {};
2};
diff --git a/recipes/hangoutschat/index.js b/recipes/hangoutschat/index.js
index 6bed9d7..bd7fbe7 100644
--- a/recipes/hangoutschat/index.js
+++ b/recipes/hangoutschat/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class HangoutsChat extends Ferdi { module.exports = Ferdi => class HangoutsChat extends Ferdi {};
2};
diff --git a/recipes/hangoutschat/webview.js b/recipes/hangoutschat/webview.js
index c8aa952..e2e5912 100644
--- a/recipes/hangoutschat/webview.js
+++ b/recipes/hangoutschat/webview.js
@@ -1,4 +1,4 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 // class corresponding to the red badge that is visible for direct messages 2 // class corresponding to the red badge that is visible for direct messages
3 const directMessageSelector = 'div.V6.CL.su.ahD.X9.Y2 span.akt span.XU'; 3 const directMessageSelector = 'div.V6.CL.su.ahD.X9.Y2 span.akt span.XU';
4 4
@@ -7,10 +7,21 @@ module.exports = (Ferdi) => {
7 7
8 const getMessages = () => { 8 const getMessages = () => {
9 // get unread direct messages 9 // get unread direct messages
10 const directCount = Number(document.querySelector(directMessageSelector).innerText); 10 let directCount;
11 let indirectCount;
12
13 const directCountSelector = document.querySelector(directMessageSelector);
14 if (directCountSelector) {
15 directCount = Number(directCountSelector.textContent);
16 }
11 17
12 // get unread indirect messages 18 // get unread indirect messages
13 const indirectCount = Number(document.querySelector(indirectMessageSelector).innerText); 19 const indirectCountSelector = document.querySelector(
20 indirectMessageSelector,
21 );
22 if (indirectCountSelector) {
23 indirectCount = Number(indirectCountSelector.textContent);
24 }
14 25
15 // set Ferdi badge 26 // set Ferdi badge
16 Ferdi.setBadge(directCount, indirectCount); 27 Ferdi.setBadge(directCount, indirectCount);
@@ -18,7 +29,8 @@ module.exports = (Ferdi) => {
18 29
19 Ferdi.loop(getMessages); 30 Ferdi.loop(getMessages);
20 31
21 document.addEventListener('click', (e) => { 32 document.addEventListener('click', e => {
33 // @ts-ignore
22 const { tagName, target, href } = e.target; 34 const { tagName, target, href } = e.target;
23 35
24 if (tagName === 'A' && target === '_blank') { 36 if (tagName === 'A' && target === '_blank') {
diff --git a/recipes/hey/webview.js b/recipes/hey/webview.js
index 686e811..67e87d4 100644
--- a/recipes/hey/webview.js
+++ b/recipes/hey/webview.js
@@ -1,23 +1,29 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 if (document.location.href == "https://app.hey.com/") { 3 if (document.location.href == 'https://app.hey.com/') {
4 let screener = 0; 4 let screener = 0;
5 let unread = 0; 5 let unread = 0;
6 6
7 if (document.getElementsByClassName('btn--icon-screener').length > 0) { 7 if (document.querySelectorAll('.btn--icon-screener').length > 0) {
8 let text = document.getElementsByClassName('btn--icon-screener')[0].innerText; 8 let text = document.querySelectorAll('.btn--icon-screener')[0]
9 9 .textContent;
10 screener = Ferdi.safeParseInt(/[0-9]+/.exec(text)[0]); 10 if (text) {
11 const parsedText = Ferdi.safeParseInt(/\d+/.exec(text));
12 screener = parsedText[0];
13 }
11 } 14 }
12 15
13 let postings = document.getElementsByClassName('posting'); 16 let postings = document.querySelectorAll('.posting');
14 17
15 if (postings.length > 0) { 18 if (postings.length > 0) {
16 Array.from(postings).forEach(p => { 19 for (const p of postings) {
17 if (p.nodeName == "ARTICLE" && p.getAttribute("data-seen") !== "true") { 20 if (
21 p.nodeName == 'ARTICLE' &&
22 p.getAttribute('data-seen') !== 'true'
23 ) {
18 unread++; 24 unread++;
19 } 25 }
20 }); 26 }
21 } 27 }
22 28
23 Ferdi.setBadge(unread, screener); 29 Ferdi.setBadge(unread, screener);
@@ -25,4 +31,4 @@ module.exports = (Ferdi) => {
25 }; 31 };
26 32
27 Ferdi.loop(getMessages); 33 Ferdi.loop(getMessages);
28} 34};
diff --git a/recipes/hipchat/index.js b/recipes/hipchat/index.js
index 5c550d8..0a461ab 100644
--- a/recipes/hipchat/index.js
+++ b/recipes/hipchat/index.js
@@ -1,4 +1,4 @@
1function _asyncToGenerator(fn) { return function () { const gen = fn.apply(this, arguments); return new Promise((resolve, reject) => { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then((value) => { step('next', value); }, (err) => { step('throw', err); }); } } return step('next'); }); }; } 1function _asyncToGenerator(fn) { return function () { const gen = Reflect.apply(fn, this, arguments); return new Promise((resolve, reject) => { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then((value) => { step('next', value); }, (error) => { step('throw', error); }); } } return step('next'); }); }; }
2 2
3module.exports = Ferdi => class HipChat extends Ferdi { 3module.exports = Ferdi => class HipChat extends Ferdi {
4 validateUrl(url) { 4 validateUrl(url) {
@@ -13,8 +13,8 @@ module.exports = Ferdi => class HipChat extends Ferdi {
13 const data = yield resp.json(); 13 const data = yield resp.json();
14 14
15 return Object.hasOwnProperty.call(data, 'features'); 15 return Object.hasOwnProperty.call(data, 'features');
16 } catch (err) { 16 } catch (error) {
17 console.error(err); 17 console.error(error);
18 } 18 }
19 19
20 return false; 20 return false;
diff --git a/recipes/icloud-reminders/index.js b/recipes/icloud-reminders/index.js
index f26900d..3fb9a8f 100644
--- a/recipes/icloud-reminders/index.js
+++ b/recipes/icloud-reminders/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class icloudreminders extends Ferdi { module.exports = Ferdi => class icloudreminders extends Ferdi {};
2};
diff --git a/recipes/icq/webview.js b/recipes/icq/webview.js
index 1bffd27..e782eb4 100644
--- a/recipes/icq/webview.js
+++ b/recipes/icq/webview.js
@@ -1,9 +1,15 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let directs = 0; 3 let directs = 0;
4 const elements = document.getElementsByClassName('nwa-msg-counter icq-recent_state-read'); 4 const elements = document.querySelectorAll(
5 for (let i = 0; i < elements.length; i++) { 5 '.nwa-msg-counter.icq-recent_state-read',
6 if (Ferdi.safeParseInt(elements[i].innerText.replace(/[^0-9.]/g, '')) > 0) { 6 );
7 for (const element of elements) {
8 if (
9 Ferdi.safeParseInt(
10 element.textContent && element.textContent.replace(/[^\d.]/g, ''),
11 ) > 0
12 ) {
7 directs += 1; // count 1 per channel with messages 13 directs += 1; // count 1 per channel with messages
8 } 14 }
9 } 15 }
diff --git a/recipes/idobata/webview.js b/recipes/idobata/webview.js
index 075316d..d30e2ad 100644
--- a/recipes/idobata/webview.js
+++ b/recipes/idobata/webview.js
@@ -1,10 +1,10 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const title = document.querySelector('title').innerHTML.match(/\d+/); 3 const title = document.querySelector('title').textContent.match(/\d+/);
4 const count = title !== null ? title[0] : 0; 4 const count = title !== null ? title[0] : 0;
5 5
6 Ferdi.setBadge(count); 6 Ferdi.setBadge(count);
7 } 7 };
8 8
9 Ferdi.loop(getMessages); 9 Ferdi.loop(getMessages);
10}; 10};
diff --git a/recipes/infomaniak-mail/index.js b/recipes/infomaniak-mail/index.js
index 93f2dcf..24184f8 100644
--- a/recipes/infomaniak-mail/index.js
+++ b/recipes/infomaniak-mail/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class infomaniakmail extends Ferdi { module.exports = Ferdi => class infomaniakmail extends Ferdi {};
2};
diff --git a/recipes/infomaniak-mail/webview.js b/recipes/infomaniak-mail/webview.js
index 04ac42d..f4e39dc 100644
--- a/recipes/infomaniak-mail/webview.js
+++ b/recipes/infomaniak-mail/webview.js
@@ -1,8 +1,16 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const count = document.querySelector('.ws-tree-node-badge').innerText; 3 const count = document.querySelector('.ws-tree-node-badge');
4 Ferdi.setBadge(count ? Number(count.substring(1, count.length - 1)) : 0); 4 if (count) {
5 } 5 const countText = count.textContent;
6 if (countText) {
7 Ferdi.setBadge(
8 // eslint-disable-next-line unicorn/prefer-string-slice
9 count ? Number(countText.substring(1, countText.length - 1)) : 0,
10 );
11 }
12 }
13 };
6 14
7 Ferdi.loop(getMessages); 15 Ferdi.loop(getMessages);
8}; 16};
diff --git a/recipes/instagram/webview.js b/recipes/instagram/webview.js
index b971021..797f544 100644
--- a/recipes/instagram/webview.js
+++ b/recipes/instagram/webview.js
@@ -1,11 +1,13 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 const element = document.querySelector('a[href^="/direct/inbox"]'); 9 const element = document.querySelector('a[href^="/direct/inbox"]');
8 Ferdi.setBadge(element ? Ferdi.safeParseInt(element.innerText) : 0); 10 Ferdi.setBadge(element ? Ferdi.safeParseInt(element.textContent) : 0);
9 }; 11 };
10 12
11 Ferdi.loop(getMessages); 13 Ferdi.loop(getMessages);
diff --git a/recipes/intercom/webview.js b/recipes/intercom/webview.js
index 1ccf8a0..ff3e9a0 100644
--- a/recipes/intercom/webview.js
+++ b/recipes/intercom/webview.js
@@ -1,8 +1,12 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const numMessages = Ferdi.safeParseInt(document.querySelector('.left-nav [data-content="Inbox"] .unread__container .unread').innerHTML); 3 const numMessages = Ferdi.safeParseInt(
4 document.querySelector(
5 '.left-nav [data-content="Inbox"] .unread__container .unread',
6 ).textContent,
7 );
4 Ferdi.setBadge(numMessages); 8 Ferdi.setBadge(numMessages);
5 } 9 };
6 10
7 Ferdi.loop(getMessages); 11 Ferdi.loop(getMessages);
8}; 12};
diff --git a/recipes/irccloud/webview.js b/recipes/irccloud/webview.js
index 0c46c46..ab26279 100644
--- a/recipes/irccloud/webview.js
+++ b/recipes/irccloud/webview.js
@@ -1,7 +1,7 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const directMessages = document.getElementsByClassName('buffer conversation active unread activeBadge').length; 3 const directMessages = document.querySelectorAll('.buffer.conversation.active.unread.activeBadge').length;
4 const indirectMessages = document.getElementsByClassName('buffer channel active unread').length; 4 const indirectMessages = document.querySelectorAll('.buffer.channel.active.unread').length;
5 5
6 Ferdi.setBadge(directMessages, indirectMessages); 6 Ferdi.setBadge(directMessages, indirectMessages);
7 }; 7 };
diff --git a/recipes/jira/webview.js b/recipes/jira/webview.js
index 246511e..9599b66 100644
--- a/recipes/jira/webview.js
+++ b/recipes/jira/webview.js
@@ -1,8 +1,10 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 // get unread messages 3 // get unread messages
4 const element = document.querySelector('#atlassian-navigation-notification-count span'); 4 const element = document.querySelector(
5 Ferdi.setBadge(element ? element.innerText : 0); 5 '#atlassian-navigation-notification-count span',
6 );
7 Ferdi.setBadge(element ? element.textContent : 0);
6 }; 8 };
7 9
8 Ferdi.loop(getMessages); 10 Ferdi.loop(getMessages);
diff --git a/recipes/jitsi/webview.js b/recipes/jitsi/webview.js
index 69c468e..f4121e9 100644
--- a/recipes/jitsi/webview.js
+++ b/recipes/jitsi/webview.js
@@ -3,7 +3,10 @@ const NOTIFICATION_BADGE_CLASS = '.badge-round';
3module.exports = Ferdi => { 3module.exports = Ferdi => {
4 const getMessages = () => { 4 const getMessages = () => {
5 const badges = [...document.querySelectorAll(NOTIFICATION_BADGE_CLASS)]; 5 const badges = [...document.querySelectorAll(NOTIFICATION_BADGE_CLASS)];
6 const messages = badges.reduce((currentValue, element) => currentValue + Number(element.innerText), 0); 6 const messages = badges.reduce(
7 (currentValue, element) => currentValue + Number(element.textContent),
8 0,
9 );
7 10
8 Ferdi.setBadge(messages); 11 Ferdi.setBadge(messages);
9 }; 12 };
diff --git a/recipes/jollor/webview.js b/recipes/jollor/webview.js
index 695a7fa..693e454 100644
--- a/recipes/jollor/webview.js
+++ b/recipes/jollor/webview.js
@@ -1,12 +1,16 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 const count = document.querySelector('.user-menu-message-item-count').innerHTML; 9 const count = document.querySelector(
10 '.user-menu-message-item-count',
11 ).textContent;
8 Ferdi.setBadge(count); 12 Ferdi.setBadge(count);
9 } 13 };
10 14
11 Ferdi.loop(getMessages); 15 Ferdi.loop(getMessages);
12 16
diff --git a/recipes/keybase.io/index.js b/recipes/keybase.io/index.js
index 3ffa657..ef5d5bc 100644
--- a/recipes/keybase.io/index.js
+++ b/recipes/keybase.io/index.js
@@ -1,2 +1 @@
1module.exports = (Ferdi) => class LineMe extends Ferdi { module.exports = (Ferdi) => class LineMe extends Ferdi {};
2};
diff --git a/recipes/lark/webview.js b/recipes/lark/webview.js
index 4e3a614..dfccccf 100644
--- a/recipes/lark/webview.js
+++ b/recipes/lark/webview.js
@@ -1,15 +1,19 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 const ele = document.querySelectorAll('.larkc-badge-count.navbarMenu-badge'); 9 const ele = document.querySelectorAll(
8 if (!ele.length) { 10 '.larkc-badge-count.navbarMenu-badge',
11 );
12 if (ele.length === 0) {
9 Ferdi.setBadge(0); 13 Ferdi.setBadge(0);
10 return; 14 return;
11 } 15 }
12 Ferdi.setBadge(ele[0].innerHTML); 16 Ferdi.setBadge(ele[0].textContent);
13 }; 17 };
14 18
15 Ferdi.loop(getMessages); 19 Ferdi.loop(getMessages);
diff --git a/recipes/lastpass/webview.js b/recipes/lastpass/webview.js
index 8bcf058..df3bd77 100644
--- a/recipes/lastpass/webview.js
+++ b/recipes/lastpass/webview.js
@@ -1,9 +1,13 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5setTimeout(() => { 7setTimeout(() => {
6 if (document.querySelector('body').innerHTML.includes('Google Chrome 36+')) { 8 if (
9 document.querySelector('body').textContent.includes('Google Chrome 36+')
10 ) {
7 window.location.reload(); 11 window.location.reload();
8 } 12 }
9}, 1000); 13}, 1000);
@@ -13,8 +17,8 @@ module.exports = (Ferdi, settings) => {
13 const elements = document.querySelectorAll('.CxUIE, .unread'); 17 const elements = document.querySelectorAll('.CxUIE, .unread');
14 let count = 0; 18 let count = 0;
15 19
16 for (let i = 0; i < elements.length; i += 1) { 20 for (const element of elements) {
17 if (elements[i].querySelectorAll('*[data-icon="muted"]').length === 0) { 21 if (element.querySelectorAll('*[data-icon="muted"]').length === 0) {
18 count += 1; 22 count += 1;
19 } 23 }
20 } 24 }
@@ -23,7 +27,15 @@ module.exports = (Ferdi, settings) => {
23 }; 27 };
24 28
25 window.addEventListener('beforeunload', async () => { 29 window.addEventListener('beforeunload', async () => {
26 Ferdi.clearStorageData(settings.id, { storages: ['appcache', 'serviceworkers', 'cachestorage', 'websql', 'indexdb'] }); 30 Ferdi.clearStorageData(settings.id, {
31 storages: [
32 'appcache',
33 'serviceworkers',
34 'cachestorage',
35 'websql',
36 'indexdb',
37 ],
38 });
27 Ferdi.releaseServiceWorkers(); 39 Ferdi.releaseServiceWorkers();
28 }); 40 });
29 41
diff --git a/recipes/line-me/index.js b/recipes/line-me/index.js
index 3ffa657..ef5d5bc 100644
--- a/recipes/line-me/index.js
+++ b/recipes/line-me/index.js
@@ -1,2 +1 @@
1module.exports = (Ferdi) => class LineMe extends Ferdi { module.exports = (Ferdi) => class LineMe extends Ferdi {};
2};
diff --git a/recipes/linkedin/webview.js b/recipes/linkedin/webview.js
index 8d1afc8..ae392f5 100644
--- a/recipes/linkedin/webview.js
+++ b/recipes/linkedin/webview.js
@@ -3,11 +3,15 @@ module.exports = Ferdi => {
3 let count = 0; 3 let count = 0;
4 4
5 if (window.location.pathname.includes('messaging')) { 5 if (window.location.pathname.includes('messaging')) {
6 count = document.querySelectorAll('.msg-conversation-card__unread-count').length; 6 count = document.querySelectorAll(
7 '.msg-conversation-card__unread-count',
8 ).length;
7 } else { 9 } else {
8 const element = document.querySelector('.nav-item--messaging .nav-item__badge-count'); 10 const element = document.querySelector(
11 '.nav-item--messaging .nav-item__badge-count',
12 );
9 if (element) { 13 if (element) {
10 count = Ferdi.safeParseInt(element.innerHTML); 14 count = Ferdi.safeParseInt(element.textContent);
11 } 15 }
12 } 16 }
13 17
diff --git a/recipes/mattermost/index.js b/recipes/mattermost/index.js
index 290cdbc..3a9a791 100644
--- a/recipes/mattermost/index.js
+++ b/recipes/mattermost/index.js
@@ -8,8 +8,8 @@ module.exports = Ferdi => class Mattermost extends Ferdi {
8 }, 8 },
9 }); 9 });
10 return resp.status.toString().startsWith('2'); 10 return resp.status.toString().startsWith('2');
11 } catch (err) { 11 } catch (error) {
12 console.error(err); 12 console.error(error);
13 } 13 }
14 14
15 return false; 15 return false;
diff --git a/recipes/messenger/webview.js b/recipes/messenger/webview.js
index 5b2f2ad..d2d85fe 100644
--- a/recipes/messenger/webview.js
+++ b/recipes/messenger/webview.js
@@ -33,7 +33,7 @@ module.exports = Ferdi => {
33 */ 33 */
34 const messageRequestsElement = document.querySelector('._5nxf'); 34 const messageRequestsElement = document.querySelector('._5nxf');
35 if (messageRequestsElement) { 35 if (messageRequestsElement) {
36 count += Ferdi.safeParseInt(messageRequestsElement.innerHTML); 36 count += Ferdi.safeParseInt(messageRequestsElement.textContent);
37 } 37 }
38 38
39 Ferdi.setBadge(count); 39 Ferdi.setBadge(count);
@@ -44,7 +44,7 @@ module.exports = Ferdi => {
44 localStorage.setItem( 44 localStorage.setItem(
45 '_cs_desktopNotifsEnabled', 45 '_cs_desktopNotifsEnabled',
46 JSON.stringify({ 46 JSON.stringify({
47 __t: new Date().getTime(), 47 __t: Date.now(),
48 __v: true, 48 __v: true,
49 }), 49 }),
50 ); 50 );
diff --git a/recipes/mewe/webview.js b/recipes/mewe/webview.js
index fcf5918..84438f2 100644
--- a/recipes/mewe/webview.js
+++ b/recipes/mewe/webview.js
@@ -1,11 +1,17 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = Ferdi => { 7module.exports = Ferdi => {
6 const calculateTotalDirectMessages = () => 8 const calculateTotalDirectMessages = () =>
7 Array.from(document.getElementsByClassName('chats-list-element')) 9 [...document.querySelectorAll('.chats-list-element')]
8 .map(el => Ferdi.safeParseInt(el.querySelector('.m-indicator .number').innerHTML)) 10 .map(el =>
11 Ferdi.safeParseInt(
12 el.querySelector('.m-indicator .number').textContent,
13 ),
14 )
9 .reduce((curr, prev) => curr + prev, 0); 15 .reduce((curr, prev) => curr + prev, 0);
10 16
11 Ferdi.loop(() => Ferdi.setBadge(calculateTotalDirectMessages())); 17 Ferdi.loop(() => Ferdi.setBadge(calculateTotalDirectMessages()));
diff --git a/recipes/misskey/index.js b/recipes/misskey/index.js
index 5805c37..51960a6 100644
--- a/recipes/misskey/index.js
+++ b/recipes/misskey/index.js
@@ -22,8 +22,8 @@ module.exports = Ferdi =>
22 'notesCount', 22 'notesCount',
23 'originalNotesCount', 23 'originalNotesCount',
24 ].reduce(r => r && Object.hasOwnProperty.call(data, 'uri'), true); 24 ].reduce(r => r && Object.hasOwnProperty.call(data, 'uri'), true);
25 } catch (err) { 25 } catch (error) {
26 console.error(err); 26 console.error(error);
27 } 27 }
28 return false; 28 return false;
29 } 29 }
diff --git a/recipes/monday/webview.js b/recipes/monday/webview.js
index 15f6335..aa0d9a8 100755
--- a/recipes/monday/webview.js
+++ b/recipes/monday/webview.js
@@ -8,8 +8,8 @@ module.exports = Ferdi => {
8 8
9 const counters = document.querySelectorAll('.surface-control-component .item-counter, .surface-control-component .view-item-counter'); 9 const counters = document.querySelectorAll('.surface-control-component .item-counter, .surface-control-component .view-item-counter');
10 10
11 for (let i = 0; i < counters.length; i++) { 11 for (const counter of counters) {
12 count += Ferdi.safeParseInt(counters[i].textContent); 12 count += Ferdi.safeParseInt(counter.textContent);
13 } 13 }
14 14
15 Ferdi.setBadge(count); 15 Ferdi.setBadge(count);
diff --git a/recipes/msteams/webview.js b/recipes/msteams/webview.js
index 0345105..1dc5aee 100644
--- a/recipes/msteams/webview.js
+++ b/recipes/msteams/webview.js
@@ -1,16 +1,22 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = Ferdi => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 let messages = 0; 9 let messages = 0;
8 const badge = document.querySelector('.activity-badge.dot-activity-badge .activity-badge'); 10 const badge = document.querySelector(
11 '.activity-badge.dot-activity-badge .activity-badge',
12 );
9 if (badge) { 13 if (badge) {
10 messages = Ferdi.safeParseInt(badge.innerHTML); 14 messages = Ferdi.safeParseInt(badge.textContent);
11 } 15 }
12 16
13 const indirectMessages = document.querySelectorAll('[class*=channel-anchor][class*=ts-unread-channel]').length; 17 const indirectMessages = document.querySelectorAll(
18 '[class*=channel-anchor][class*=ts-unread-channel]',
19 ).length;
14 20
15 Ferdi.setBadge(messages, indirectMessages); 21 Ferdi.setBadge(messages, indirectMessages);
16 }; 22 };
diff --git a/recipes/mstodo/index.js b/recipes/mstodo/index.js
index 73107f7..c0a684b 100644
--- a/recipes/mstodo/index.js
+++ b/recipes/mstodo/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class mstodo extends Ferdi { module.exports = Ferdi => class mstodo extends Ferdi {};
2};
diff --git a/recipes/mstodo/webview.js b/recipes/mstodo/webview.js
index 9f4efef..1692a4d 100644
--- a/recipes/mstodo/webview.js
+++ b/recipes/mstodo/webview.js
@@ -7,8 +7,8 @@ module.exports = Ferdi => {
7 const elements = document.querySelectorAll('.taskItem'); 7 const elements = document.querySelectorAll('.taskItem');
8 let count = 0; 8 let count = 0;
9 9
10 for (let i = 0; i < elements.length; i += 1) { 10 for (const element of elements) {
11 if (elements[i].querySelectorAll('.completed').length === 0) { 11 if (element.querySelectorAll('.completed').length === 0) {
12 count += 1; 12 count += 1;
13 } 13 }
14 } 14 }
diff --git a/recipes/mysms/webview.js b/recipes/mysms/webview.js
index 3f3415a..1878120 100644
--- a/recipes/mysms/webview.js
+++ b/recipes/mysms/webview.js
@@ -1,10 +1,14 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const elements = document.getElementsByClassName('unread'); 3 const elements = document.querySelectorAll('.unread');
4 4
5 let count = 0; 5 let count = 0;
6 for (let i = 0; i < elements.length; i++) { 6 for (const element of elements) {
7 if (Ferdi.safeParseInt(elements[i].innerText.replace(/[^0-9.]/g, '')) > 0) { 7 if (
8 Ferdi.safeParseInt(
9 element.textContent && element.textContent.replace(/[^\d.]/g, ''),
10 ) > 0
11 ) {
8 count++; // count 1 per channel with messages 12 count++; // count 1 per channel with messages
9 } 13 }
10 } 14 }
diff --git a/recipes/nextcloud-talk/webview.js b/recipes/nextcloud-talk/webview.js
index 1b55203..49a3e29 100644
--- a/recipes/nextcloud-talk/webview.js
+++ b/recipes/nextcloud-talk/webview.js
@@ -17,11 +17,10 @@ module.exports = Ferdi => {
17 17
18 let indirect = 0; 18 let indirect = 0;
19 19
20 document.querySelectorAll('.app-navigation-entry__counter').forEach( 20 for (const counter of document.querySelectorAll('.app-navigation-entry__counter')) {
21 (counter) => {
22 indirect += Number(counter.textContent); 21 indirect += Number(counter.textContent);
23 }, 22 }
24 ); 23
25 Ferdi.setBadge(direct, indirect); 24 Ferdi.setBadge(direct, indirect);
26 }; 25 };
27 26
diff --git a/recipes/nextdoor/webview.js b/recipes/nextdoor/webview.js
index 503d9a4..809e368 100644
--- a/recipes/nextdoor/webview.js
+++ b/recipes/nextdoor/webview.js
@@ -1,9 +1,11 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let unread = 0; 3 let unread = 0;
4 const notificationBadge = document.getElementsByClassName('notification-badge')[0]; 4 const notificationBadge = document.querySelectorAll(
5 '.notification-badge',
6 )[0];
5 if (notificationBadge != undefined) { 7 if (notificationBadge != undefined) {
6 unread = Ferdi.safeParseInt(notificationBadge.innerText); 8 unread = Ferdi.safeParseInt(notificationBadge.textContent);
7 } 9 }
8 Ferdi.setBadge(unread); 10 Ferdi.setBadge(unread);
9 }; 11 };
diff --git a/recipes/notion/webview.js b/recipes/notion/webview.js
index cd8f566..b209e75 100644
--- a/recipes/notion/webview.js
+++ b/recipes/notion/webview.js
@@ -1,13 +1,15 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let direct = 0; 3 let direct = 0;
4 const badgeDiv = document.querySelector('.notion-sidebar-container > div > div > div > :nth-child(4) > :nth-child(2) > div > :nth-child(3) > div > div'); 4 const badgeDiv = document.querySelector(
5 '.notion-sidebar-container > div > div > div > :nth-child(4) > :nth-child(2) > div > :nth-child(3) > div > div',
6 );
5 if (badgeDiv) { 7 if (badgeDiv) {
6 direct = Ferdi.safeParseInt(badgeDiv.innerText); 8 direct = Ferdi.safeParseInt(badgeDiv.textContent);
7 } 9 }
8 10
9 Ferdi.setBadge(direct); 11 Ferdi.setBadge(direct);
10 } 12 };
11 13
12 Ferdi.loop(getMessages); 14 Ferdi.loop(getMessages);
13}; 15};
diff --git a/recipes/odoo/index.js b/recipes/odoo/index.js
index 23328b9..ad78a76 100644
--- a/recipes/odoo/index.js
+++ b/recipes/odoo/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Odoo extends Ferdi { module.exports = Ferdi => class Odoo extends Ferdi {};
2};
diff --git a/recipes/office365-owa/webview.js b/recipes/office365-owa/webview.js
index b897c8d..17649fd 100644
--- a/recipes/office365-owa/webview.js
+++ b/recipes/office365-owa/webview.js
@@ -1,12 +1,14 @@
1module.exports = (Ferdi, settings) => { 1module.exports = (Ferdi, settings) => {
2 const collectCounts = (selector) => { 2 const collectCounts = selector => {
3 let unreadCount = 0; 3 let unreadCount = 0;
4 const foldersElement = document.querySelector(selector); 4 const foldersElement = document.querySelector(selector);
5 if (foldersElement) { 5 if (foldersElement) {
6 const allScreenReaders = foldersElement.querySelectorAll('span.screenReaderOnly'); 6 const allScreenReaders = foldersElement.querySelectorAll(
7 'span.screenReaderOnly',
8 );
7 for (const child of allScreenReaders) { 9 for (const child of allScreenReaders) {
8 if (child.previousSibling) { 10 if (child.previousSibling) {
9 unreadCount += Ferdi.safeParseInt(child.previousSibling.innerText); 11 unreadCount += Ferdi.safeParseInt(child.previousSibling.textContent);
10 } 12 }
11 } 13 }
12 } 14 }
@@ -17,22 +19,24 @@ module.exports = (Ferdi, settings) => {
17 let directUnreadCount = 0; 19 let directUnreadCount = 0;
18 let indirectUnreadCount = 0; 20 let indirectUnreadCount = 0;
19 21
20 if (location.pathname.match(/\/owa/)) { 22 if (/\/owa/.test(location.pathname)) {
21 // classic app 23 // classic app
22 directUnreadCount = Ferdi.safeParseInt(jQuery("span[title*='Inbox'] + div > span").first().text()); 24 directUnreadCount = Ferdi.safeParseInt(
25 document.querySelectorAll("span[title*='Inbox'] + div > span")[0]
26 .textContent,
27 );
23 } else { 28 } else {
24 // new app 29 // new app
25 if (settings.onlyShowFavoritesInUnreadCount === true) { 30 directUnreadCount =
26 directUnreadCount = collectCounts('div[role=tree]:nth-child(2)'); // favorites 31 settings.onlyShowFavoritesInUnreadCount === true
27 } else { 32 ? collectCounts('div[role=tree]:nth-child(2)')
28 directUnreadCount = collectCounts('div[role=tree]:nth-child(3)'); // folders 33 : collectCounts('div[role=tree]:nth-child(3)');
29 }
30 34
31 indirectUnreadCount = collectCounts('div[role=tree]:nth-child(4)'); // groups 35 indirectUnreadCount = collectCounts('div[role=tree]:nth-child(4)'); // groups
32 } 36 }
33 37
34 Ferdi.setBadge(directUnreadCount, indirectUnreadCount); 38 Ferdi.setBadge(directUnreadCount, indirectUnreadCount);
35 } 39 };
36 40
37 Ferdi.loop(getMessages); 41 Ferdi.loop(getMessages);
38}; 42};
diff --git a/recipes/onenote/index.js b/recipes/onenote/index.js
index b322187..b6a0630 100644
--- a/recipes/onenote/index.js
+++ b/recipes/onenote/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class onenote extends Ferdi { module.exports = Ferdi => class onenote extends Ferdi {};
2};
diff --git a/recipes/pinterest/index.js b/recipes/pinterest/index.js
index f48f249..2495a63 100644
--- a/recipes/pinterest/index.js
+++ b/recipes/pinterest/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class pinterest extends Ferdi { module.exports = Ferdi => class pinterest extends Ferdi {};
2};
diff --git a/recipes/pivotal-tracker/webview.js b/recipes/pivotal-tracker/webview.js
index e4899a5..1775292 100644
--- a/recipes/pivotal-tracker/webview.js
+++ b/recipes/pivotal-tracker/webview.js
@@ -1,10 +1,10 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const bell = document.querySelectorAll('#view65 > span')[0]; 3 const bell = document.querySelectorAll('#view65 > span')[0];
4 if (bell) { 4 if (bell) {
5 Ferdi.setBadge(bell.innerText); 5 Ferdi.setBadge(bell.textContent);
6 } 6 }
7 } 7 };
8 8
9 Ferdi.loop(getMessages); 9 Ferdi.loop(getMessages);
10}; 10};
diff --git a/recipes/plek/webview.js b/recipes/plek/webview.js
index bc6d5aa..0ac618b 100644
--- a/recipes/plek/webview.js
+++ b/recipes/plek/webview.js
@@ -1,20 +1,22 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 let directMessages = 0; 9 let directMessages = 0;
8 let indirectMessages = 0; 10 let indirectMessages = 0;
9 11
10 const elements = document.querySelectorAll('.counter'); 12 const elements = document.querySelectorAll('.counter');
11 for (let i = 0; i < elements.length; i += 1) { 13 for (const element of elements) {
12 directMessages += Ferdi.safeParseInt(elements[i].innerText); 14 directMessages += Ferdi.safeParseInt(element.textContent);
13 } 15 }
14 16
15 const elements2 = document.querySelectorAll('.badge'); 17 const elements2 = document.querySelectorAll('.badge');
16 for (let i = 0; i < elements2.length; i += 1) { 18 for (const element of elements2) {
17 indirectMessages += Ferdi.safeParseInt(elements2[i].innerText); 19 indirectMessages += Ferdi.safeParseInt(element.textContent);
18 } 20 }
19 21
20 Ferdi.setBadge(directMessages, indirectMessages); 22 Ferdi.setBadge(directMessages, indirectMessages);
diff --git a/recipes/pleroma/index.js b/recipes/pleroma/index.js
index c6cf368..06a6e2d 100644
--- a/recipes/pleroma/index.js
+++ b/recipes/pleroma/index.js
@@ -6,9 +6,9 @@ module.exports = Ferdi => class Pleroma extends Ferdi {
6 }); 6 });
7 const data = await resp.json(); 7 const data = await resp.json();
8 const version = data.version; 8 const version = data.version;
9 return typeof (version) === 'string' && version.indexOf('Pleroma') >= 0; 9 return typeof (version) === 'string' && version.includes('Pleroma');
10 } catch (err) { 10 } catch (error) {
11 console.log('Pleroma server validation error', err); 11 console.log('Pleroma server validation error', error);
12 } 12 }
13 return false; 13 return false;
14 } 14 }
diff --git a/recipes/pleroma/webview.js b/recipes/pleroma/webview.js
index 2ba184e..c7a6530 100644
--- a/recipes/pleroma/webview.js
+++ b/recipes/pleroma/webview.js
@@ -15,8 +15,8 @@ const getInstanceConfig = async () => {
15 ); 15 );
16 const pleromaFeConfig = frontendConfig.pleroma_fe || {}; 16 const pleromaFeConfig = frontendConfig.pleroma_fe || {};
17 return { ...staticConfig, ...pleromaFeConfig }; 17 return { ...staticConfig, ...pleromaFeConfig };
18 } catch (e) { 18 } catch (error) {
19 console.log('Failed to load dynamic frontend configuration', e); 19 console.log('Failed to load dynamic frontend configuration', error);
20 return staticConfig; 20 return staticConfig;
21 } 21 }
22}; 22};
@@ -161,8 +161,8 @@ module.exports = Ferdi => {
161 } 161 }
162 }); 162 });
163 }, 163 },
164 e => { 164 error => {
165 console.log('Failed to load instance logo', e); 165 console.log('Failed to load instance logo', error);
166 Ferdi.loop(getMessages); 166 Ferdi.loop(getMessages);
167 }, 167 },
168 ); 168 );
diff --git a/recipes/plurk/webview.js b/recipes/plurk/webview.js
index c79853d..09f15da 100644
--- a/recipes/plurk/webview.js
+++ b/recipes/plurk/webview.js
@@ -6,14 +6,14 @@ module.exports = Ferdi => {
6 const re = document.querySelector('#noti_re_count'); 6 const re = document.querySelector('#noti_re_count');
7 7
8 if (np) { 8 if (np) {
9 direct += Ferdi.safeParseInt(np.innerHTML); 9 direct += Ferdi.safeParseInt(np.textContent);
10 } 10 }
11 if (re) { 11 if (re) {
12 direct += Ferdi.safeParseInt(re.innerHTML); 12 direct += Ferdi.safeParseInt(re.textContent);
13 } 13 }
14 14
15 Ferdi.setBadge(direct); 15 Ferdi.setBadge(direct);
16 } 16 };
17 17
18 Ferdi.loop(getMessages, 10000); 18 Ferdi.loop(getMessages, 10_000);
19}; 19};
diff --git a/recipes/podio/webview.js b/recipes/podio/webview.js
index 1bfa60d..0a0c31e 100644
--- a/recipes/podio/webview.js
+++ b/recipes/podio/webview.js
@@ -1,10 +1,12 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 const updates = document.getElementsByClassName('counter')[0].innerHTML; 9 const updates = document.querySelectorAll('.counter')[0].textContent;
8 Ferdi.setBadge(updates, 0); 10 Ferdi.setBadge(updates, 0);
9 }; 11 };
10 12
diff --git a/recipes/pomodoro-tracker/index.js b/recipes/pomodoro-tracker/index.js
index 6bc8da9..52abf4d 100644
--- a/recipes/pomodoro-tracker/index.js
+++ b/recipes/pomodoro-tracker/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class pomodorotracker extends Ferdi { module.exports = Ferdi => class pomodorotracker extends Ferdi {};
2};
diff --git a/recipes/producthunt/webview.js b/recipes/producthunt/webview.js
index c03de9b..7f6c74b 100644
--- a/recipes/producthunt/webview.js
+++ b/recipes/producthunt/webview.js
@@ -1,7 +1,13 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const notificationsSelector = document.querySelector(
3 '[class*=header_] [class*=content_] [class*=actions_] [class*=notificationsButton_]',
4 );
5
2 const getMessages = () => { 6 const getMessages = () => {
3 Ferdi.setBadge(document.querySelector('[class*=header_] [class*=content_] [class*=actions_] [class*=notificationsButton_]').innerText) 7 if (notificationsSelector) {
4 } 8 Ferdi.setBadge(notificationsSelector.textContent);
9 }
10 };
5 11
6 Ferdi.loop(getMessages) 12 Ferdi.loop(getMessages);
7} 13};
diff --git a/recipes/proton-mail/webview.js b/recipes/proton-mail/webview.js
index ed66db5..395b779 100644
--- a/recipes/proton-mail/webview.js
+++ b/recipes/proton-mail/webview.js
@@ -4,10 +4,13 @@ module.exports = Ferdi => {
4 if (!element) { 4 if (!element) {
5 return; 5 return;
6 } 6 }
7 const text = element.innerText; 7 const text = element.textContent;
8 const count = Ferdi.safeParseInt(text.substring(1, text.length - 1)); 8 if (text) {
9 Ferdi.setBadge(count); 9 // eslint-disable-next-line unicorn/prefer-string-slice
10 } 10 const count = Ferdi.safeParseInt(text.substring(1, text.length - 1));
11 Ferdi.setBadge(count);
12 }
13 };
11 14
12 Ferdi.loop(getMessages); 15 Ferdi.loop(getMessages);
13}; 16};
diff --git a/recipes/pulsesms/webview.js b/recipes/pulsesms/webview.js
index 48bb2ad..d6d123c 100644
--- a/recipes/pulsesms/webview.js
+++ b/recipes/pulsesms/webview.js
@@ -1,7 +1,9 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 Ferdi.setBadge(document.querySelector('#unread_count').innerHTML.replace(/\s/g, '')); 3 Ferdi.setBadge(
4 } 4 document.querySelector('#unread_count').textContent.replace(/\s/g, ''),
5 );
6 };
5 7
6 Ferdi.loop(getMessages); 8 Ferdi.loop(getMessages);
7}; 9};
diff --git a/recipes/reddit/webview.js b/recipes/reddit/webview.js
index 5095ba1..8d165aa 100644
--- a/recipes/reddit/webview.js
+++ b/recipes/reddit/webview.js
@@ -12,16 +12,21 @@ module.exports = Ferdi => {
12 let count = 0; 12 let count = 0;
13 13
14 if (elements[0]) { 14 if (elements[0]) {
15 count = Ferdi.safeParseInt(elements[0].innerHTML); 15 count = Ferdi.safeParseInt(elements[0].textContent);
16 } 16 }
17 17
18 Ferdi.setBadge(count); 18 Ferdi.setBadge(count);
19 }; 19 };
20 20
21 if (document.querySelectorAll('.promotedlink').length > 0) { 21 if (document.querySelectorAll('.promotedlink').length > 0) {
22 document.querySelectorAll('.promotedlink').forEach(sponsoredLink => { 22 for (const sponsoredLink of document.querySelectorAll('.promotedlink')) {
23 sponsoredLink.parentElement.parentElement.style.display = 'none'; 23 if (
24 }); 24 sponsoredLink.parentElement &&
25 sponsoredLink.parentElement.parentElement
26 ) {
27 sponsoredLink.parentElement.parentElement.style.display = 'none';
28 }
29 }
25 } 30 }
26 31
27 Ferdi.loop(getMessages); 32 Ferdi.loop(getMessages);
@@ -41,8 +46,10 @@ module.exports = Ferdi => {
41 const btn = document.querySelector('[role=menu] button button'); 46 const btn = document.querySelector('[role=menu] button button');
42 const checked = btn && btn.getAttribute('aria-checked') === 'true'; 47 const checked = btn && btn.getAttribute('aria-checked') === 'true';
43 48
44 if ((checked && !isEnabled) || (!checked && isEnabled)) { 49 if (
45 // Click the button to switch between modes 50 ((checked && !isEnabled) || (!checked && isEnabled)) && // Click the button to switch between modes
51 btn
52 ) {
46 btn.click(); 53 btn.click();
47 } 54 }
48 }, 50); 55 }, 50);
diff --git a/recipes/redditchat/webview.js b/recipes/redditchat/webview.js
index 14f7f6c..19b306c 100644
--- a/recipes/redditchat/webview.js
+++ b/recipes/redditchat/webview.js
@@ -1,7 +1,6 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 // Regular expression for (*) or (1), will extract the asterisk or the number 2 // Regular expression for (*) or (1), will extract the asterisk or the number
3 // eslint-disable-next-line no-useless-escape 3 const titleRegEx = /^\(([\d*])\)/;
4 const titleRegEx = /^\(([\*\d])\)/;
5 const getMessages = function unreadCount() { 4 const getMessages = function unreadCount() {
6 let directCount = 0; 5 let directCount = 0;
7 let indirectCount = 0; 6 let indirectCount = 0;
diff --git a/recipes/riseup/index.js b/recipes/riseup/index.js
index b4e1380..d24be1d 100644
--- a/recipes/riseup/index.js
+++ b/recipes/riseup/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class riseupnet extends Ferdi { module.exports = Ferdi => class riseupnet extends Ferdi {};
2};
diff --git a/recipes/riseup/webview.js b/recipes/riseup/webview.js
index 0fb21f8..b3a78cf 100644
--- a/recipes/riseup/webview.js
+++ b/recipes/riseup/webview.js
@@ -1,9 +1,9 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let unread = 0; 3 let unread = 0;
4 const notificationBadge = document.getElementsByClassName('unreadcount')[0]; 4 const notificationBadge = document.querySelectorAll('.unreadcount')[0];
5 if (notificationBadge != undefined) { 5 if (notificationBadge != undefined) {
6 unread = Ferdi.safeParseInt(notificationBadge.innerText); 6 unread = Ferdi.safeParseInt(notificationBadge.textContent);
7 } 7 }
8 Ferdi.setBadge(unread); 8 Ferdi.setBadge(unread);
9 }; 9 };
diff --git a/recipes/rocketchat/index.js b/recipes/rocketchat/index.js
index 062b5ec..97de4fe 100644
--- a/recipes/rocketchat/index.js
+++ b/recipes/rocketchat/index.js
@@ -9,8 +9,8 @@ module.exports = Ferdi => class RocketChat extends Ferdi {
9 }); 9 });
10 const status = resp.status.toString(); 10 const status = resp.status.toString();
11 return status.startsWith('2') || status.startsWith('3'); 11 return status.startsWith('2') || status.startsWith('3');
12 } catch (err) { 12 } catch (error) {
13 console.error(err); 13 console.error(error);
14 } 14 }
15 15
16 return false; 16 return false;
diff --git a/recipes/rocketchat/webview.js b/recipes/rocketchat/webview.js
index 5ed7866..95ada6f 100644
--- a/recipes/rocketchat/webview.js
+++ b/recipes/rocketchat/webview.js
@@ -33,17 +33,17 @@ module.exports = Ferdi => {
33 33
34 const xmlhttp = new XMLHttpRequest(); 34 const xmlhttp = new XMLHttpRequest();
35 35
36 xmlhttp.onreadystatechange = function () { 36 xmlhttp.addEventListener('readystatechange', function () {
37 if (this.readyState != 4 || this.status != 200) { 37 if (this.readyState != 4 || this.status != 200) {
38 return; 38 return;
39 } 39 }
40 40
41 const response = JSON.parse(this.responseText); 41 const response = JSON.parse(this.responseText);
42 42
43 if (response.icons.length >= 1) { 43 if (response.icons.length > 0) {
44 Ferdi.setAvatarImage(`${window.location.protocol}//${window.location.host}${response.icons[0].src}`); 44 Ferdi.setAvatarImage(`${window.location.protocol}//${window.location.host}${response.icons[0].src}`);
45 } 45 }
46 }; 46 });
47 47
48 xmlhttp.open('GET', manifestUrl, true); 48 xmlhttp.open('GET', manifestUrl, true);
49 xmlhttp.send(); 49 xmlhttp.send();
diff --git a/recipes/roundcube/webview.js b/recipes/roundcube/webview.js
index c59da2f..08c6a95 100644
--- a/recipes/roundcube/webview.js
+++ b/recipes/roundcube/webview.js
@@ -2,8 +2,8 @@ module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const directElements = document.querySelectorAll('.unreadcount'); 3 const directElements = document.querySelectorAll('.unreadcount');
4 let direct = 0; 4 let direct = 0;
5 for (let i = 0; i < directElements.length; i += 1) { 5 for (const directElement of directElements) {
6 direct += Ferdi.safeParseInt(directElements[i].innerHTML); 6 direct += Ferdi.safeParseInt(directElement.textContent);
7 } 7 }
8 Ferdi.setBadge(direct); 8 Ferdi.setBadge(direct);
9 }; 9 };
diff --git a/recipes/scribens/index.js b/recipes/scribens/index.js
index 3851554..ae7e2d2 100644
--- a/recipes/scribens/index.js
+++ b/recipes/scribens/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Scribens extends Ferdi { module.exports = Ferdi => class Scribens extends Ferdi {};
2};
diff --git a/recipes/scrumpy/webview.js b/recipes/scrumpy/webview.js
index 5c762e4..46f6424 100644
--- a/recipes/scrumpy/webview.js
+++ b/recipes/scrumpy/webview.js
@@ -1,8 +1,12 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const notifications = document.querySelector('.c-notifications-dropdown__count') 3 const notifications = document.querySelector(
4 Ferdi.setBadge(notifications.innerText); 4 '.c-notifications-dropdown__count',
5 }; 5 );
6 if (notifications) {
7 Ferdi.setBadge(notifications.textContent);
8 }
9 };
6 10
7 Ferdi.loop(getMessages); 11 Ferdi.loop(getMessages);
8}; 12};
diff --git a/recipes/simplenote/index.js b/recipes/simplenote/index.js
index 18db071..15ecf81 100644
--- a/recipes/simplenote/index.js
+++ b/recipes/simplenote/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class simplenote extends Ferdi { module.exports = Ferdi => class simplenote extends Ferdi {};
2};
diff --git a/recipes/simplenote/webview.js b/recipes/simplenote/webview.js
index 8d1afc8..ae392f5 100644
--- a/recipes/simplenote/webview.js
+++ b/recipes/simplenote/webview.js
@@ -3,11 +3,15 @@ module.exports = Ferdi => {
3 let count = 0; 3 let count = 0;
4 4
5 if (window.location.pathname.includes('messaging')) { 5 if (window.location.pathname.includes('messaging')) {
6 count = document.querySelectorAll('.msg-conversation-card__unread-count').length; 6 count = document.querySelectorAll(
7 '.msg-conversation-card__unread-count',
8 ).length;
7 } else { 9 } else {
8 const element = document.querySelector('.nav-item--messaging .nav-item__badge-count'); 10 const element = document.querySelector(
11 '.nav-item--messaging .nav-item__badge-count',
12 );
9 if (element) { 13 if (element) {
10 count = Ferdi.safeParseInt(element.innerHTML); 14 count = Ferdi.safeParseInt(element.textContent);
11 } 15 }
12 } 16 }
13 17
diff --git a/recipes/slack/webview.js b/recipes/slack/webview.js
index 23cede8..f436ba9 100644
--- a/recipes/slack/webview.js
+++ b/recipes/slack/webview.js
@@ -24,7 +24,7 @@ module.exports = Ferdi => {
24 24
25 if (icon) { 25 if (icon) {
26 bgUrl = window.getComputedStyle(icon, null).getPropertyValue('background-image'); 26 bgUrl = window.getComputedStyle(icon, null).getPropertyValue('background-image');
27 bgUrl = /^url\((['"]?)(.*)\1\)$/.exec(bgUrl); 27 bgUrl = /^url\((["']?)(.*)\1\)$/.exec(bgUrl);
28 bgUrl = bgUrl ? bgUrl[2] : ''; 28 bgUrl = bgUrl ? bgUrl[2] : '';
29 } 29 }
30 30
diff --git a/recipes/slite/webview.js b/recipes/slite/webview.js
index d54b2d3..f1d9f32 100644
--- a/recipes/slite/webview.js
+++ b/recipes/slite/webview.js
@@ -1,7 +1,9 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const element = document.querySelector("#app button[data-test-id='notificationsCount']"); 3 const element = document.querySelector(
4 Ferdi.setBadge(element ? Ferdi.safeParseInt(element.innerText) : 0); 4 "#app button[data-test-id='notificationsCount']",
5 );
6 Ferdi.setBadge(element ? Ferdi.safeParseInt(element.textContent) : 0);
5 }; 7 };
6 8
7 Ferdi.loop(getMessages); 9 Ferdi.loop(getMessages);
diff --git a/recipes/slowly/webview.js b/recipes/slowly/webview.js
index e005ea1..cc40a46 100644
--- a/recipes/slowly/webview.js
+++ b/recipes/slowly/webview.js
@@ -1,2 +1 @@
1module.exports = () => { module.exports = () => {};
2};
diff --git a/recipes/sococo/webview.js b/recipes/sococo/webview.js
index 4f7e045..c0bb20f 100644
--- a/recipes/sococo/webview.js
+++ b/recipes/sococo/webview.js
@@ -1,10 +1,10 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let indirect = document.querySelectorAll('.new-messages'); 3 let indirect = document.querySelectorAll('.new-messages');
4 let direct = 0; 4 let direct = 0;
5 document.querySelectorAll('.people-pane .badge').forEach(function(badge){ 5 for (const badge of document.querySelectorAll('.people-pane .badge')) {
6 direct += Ferdi.safeParseInt(badge.innerText); 6 direct += Ferdi.safeParseInt(badge.textContent);
7 }); 7 }
8 Ferdi.setBadge(direct, indirect); 8 Ferdi.setBadge(direct, indirect);
9 }; 9 };
10 10
diff --git a/recipes/stackexchange/index.js b/recipes/stackexchange/index.js
index 907a90f..d9328a9 100644
--- a/recipes/stackexchange/index.js
+++ b/recipes/stackexchange/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class stackexchange extends Ferdi { module.exports = Ferdi => class stackexchange extends Ferdi {};
2};
diff --git a/recipes/stackoverflow-chat/index.js b/recipes/stackoverflow-chat/index.js
index c6cfcdf..ea29aa3 100644
--- a/recipes/stackoverflow-chat/index.js
+++ b/recipes/stackoverflow-chat/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class stackoverflowchat extends Ferdi { module.exports = Ferdi => class stackoverflowchat extends Ferdi {};
2};
diff --git a/recipes/stackoverflow-chat/webview.js b/recipes/stackoverflow-chat/webview.js
index cf487b5..4157600 100644
--- a/recipes/stackoverflow-chat/webview.js
+++ b/recipes/stackoverflow-chat/webview.js
@@ -1,13 +1,17 @@
1var _path = _interopRequireDefault(require('path')); 1var _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = Ferdi => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 const unreadSpan = document.querySelector('span.flag-count.message-count.unread-count'); 9 const unreadSpan = document.querySelector(
10 'span.flag-count.message-count.unread-count',
11 );
8 let directCount = 0; 12 let directCount = 0;
9 if (unreadSpan) { 13 if (unreadSpan) {
10 directCount = Ferdi.safeParseInt(unreadSpan.innerText); 14 directCount = Ferdi.safeParseInt(unreadSpan.textContent);
11 } 15 }
12 Ferdi.setBadge(directCount); 16 Ferdi.setBadge(directCount);
13 }; 17 };
diff --git a/recipes/stackoverflow/webview.js b/recipes/stackoverflow/webview.js
index 437fb49..83fd5dd 100644
--- a/recipes/stackoverflow/webview.js
+++ b/recipes/stackoverflow/webview.js
@@ -6,8 +6,8 @@ module.exports = (Ferdi) => {
6 const getMessages = () => { 6 const getMessages = () => {
7 const elements = document.querySelectorAll('.CxUIE, .unread'); 7 const elements = document.querySelectorAll('.CxUIE, .unread');
8 let count = 0; 8 let count = 0;
9 for (let i = 0; i < elements.length; i += 1) { 9 for (const element of elements) {
10 if (elements[i].querySelectorAll('*[data-icon="muted"]').length === 0) { 10 if (element.querySelectorAll('*[data-icon="muted"]').length === 0) {
11 count += 1; 11 count += 1;
12 } 12 }
13 } 13 }
diff --git a/recipes/steamchat/webview.js b/recipes/steamchat/webview.js
index 61d57ad..2990131 100644
--- a/recipes/steamchat/webview.js
+++ b/recipes/steamchat/webview.js
@@ -3,19 +3,24 @@ module.exports = Ferdi => {
3 // get new msg count 3 // get new msg count
4 let count = 0; 4 let count = 0;
5 const counters = document.querySelectorAll('[class*=FriendMessageCount]'); 5 const counters = document.querySelectorAll('[class*=FriendMessageCount]');
6 [].filter.call(counters, countValue => { 6 Array.prototype.filter.call(counters, countValue => {
7 if (countValue) { 7 if (countValue) {
8 count += Ferdi.safeParseInt(countValue.innerHTML); 8 count += Ferdi.safeParseInt(countValue.textContent);
9 } 9 }
10 }); 10 });
11 11
12 const indirectMessages = document.querySelectorAll('[class*=ChatUnreadMessageIndicator]').length; 12 const indirectMessages = document.querySelectorAll(
13 '[class*=ChatUnreadMessageIndicator]',
14 ).length;
13 Ferdi.setBadge(count, indirectMessages); 15 Ferdi.setBadge(count, indirectMessages);
14 16
15 // force scroll to bottom of chat window 17 // force scroll to bottom of chat window
16 const chatBoxes = document.querySelectorAll('.chat_dialog'); 18 const chatBoxes = document.querySelectorAll('.chat_dialog');
17 if (chatBoxes) { 19 if (chatBoxes) {
18 const chatBox = [].filter.call(chatBoxes, chat => chat.style.display !== 'none'); 20 const chatBox = Array.prototype.filter.call(
21 chatBoxes,
22 chat => chat.style.display !== 'none',
23 );
19 if (chatBox[0]) { 24 if (chatBox[0]) {
20 const chatWindow = chatBox[0].querySelector('.chat_dialog_scroll'); 25 const chatWindow = chatBox[0].querySelector('.chat_dialog_scroll');
21 chatWindow.scrollTop = chatWindow.scrollHeight; 26 chatWindow.scrollTop = chatWindow.scrollHeight;
@@ -25,13 +30,17 @@ module.exports = Ferdi => {
25 30
26 Ferdi.loop(getMessages); 31 Ferdi.loop(getMessages);
27 32
28 document.addEventListener('click', event => { 33 document.addEventListener(
29 const link = event.target.closest('a[href^="http"]'); 34 'click',
35 event => {
36 const link = event.target.closest('a[href^="http"]');
30 37
31 if (link && link.getAttribute('target') === '_top') { 38 if (link && link.getAttribute('target') === '_top') {
32 event.preventDefault(); 39 event.preventDefault();
33 event.stopPropagation(); 40 event.stopPropagation();
34 Ferdi.openNewWindow(link.getAttribute('href')); 41 Ferdi.openNewWindow(link.getAttribute('href'));
35 } 42 }
36 }, true); 43 },
44 true,
45 );
37}; 46};
diff --git a/recipes/stride/webview.js b/recipes/stride/webview.js
index 6b62e08..002fca5 100644
--- a/recipes/stride/webview.js
+++ b/recipes/stride/webview.js
@@ -10,7 +10,7 @@ module.exports = Ferdi => {
10 let indirectCount = 0; 10 let indirectCount = 0;
11 11
12 // get unread direct messages by tring to read the badge values 12 // get unread direct messages by tring to read the badge values
13 allBadges.forEach(item => { 13 for (const item of allBadges) {
14 if (item.hasAttribute('data-count')) { 14 if (item.hasAttribute('data-count')) {
15 // Count for DMs should be in the data-count attribute 15 // Count for DMs should be in the data-count attribute
16 directCount += Math.max(1, +item.getAttribute('data-count')); 16 directCount += Math.max(1, +item.getAttribute('data-count'));
@@ -18,7 +18,7 @@ module.exports = Ferdi => {
18 // this will be the case for indirect messages 18 // this will be the case for indirect messages
19 indirectCount++; 19 indirectCount++;
20 } 20 }
21 }); 21 }
22 22
23 // set Ferdi badge 23 // set Ferdi badge
24 Ferdi.setBadge(directCount, indirectCount); 24 Ferdi.setBadge(directCount, indirectCount);
diff --git a/recipes/sync/index.js b/recipes/sync/index.js
index a3e9be5..745078f 100644
--- a/recipes/sync/index.js
+++ b/recipes/sync/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class sync extends Ferdi { module.exports = Ferdi => class sync extends Ferdi {};
2};
diff --git a/recipes/teamleader/webview.js b/recipes/teamleader/webview.js
index 241d787..f846f55 100644
--- a/recipes/teamleader/webview.js
+++ b/recipes/teamleader/webview.js
@@ -1,26 +1,36 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 let notifications = 0; 9 let notifications = 0;
8 let indirectNotifications = 0; 10 let indirectNotifications = 0;
9 11
10 const notification_element = document.getElementById('notifications_amount'); 12 const notification_element = document.querySelector(
11 const ticket_element = document.querySelector("a[href='tickets.php'] > span"); 13 '#notifications_amount',
12 const call_element = document.getElementById('queue_amount'); 14 );
15 const ticket_element = document.querySelector(
16 "a[href='tickets.php'] > span",
17 );
18 const call_element = document.querySelector('#queue_amount');
13 19
14 if (notification_element) { 20 if (notification_element) {
15 notifications = Ferdi.safeParseInt(notification_element.getAttribute("datacount")); 21 notifications = Ferdi.safeParseInt(
22 notification_element.getAttribute('datacount'),
23 );
16 } 24 }
17 25
18 if (ticket_element != null) { 26 if (ticket_element != null) {
19 indirectNotifications = Ferdi.safeParseInt(ticket_element.innerHTML); 27 indirectNotifications = Ferdi.safeParseInt(ticket_element.textContent);
20 } 28 }
21 29
22 if (call_element) { 30 if (call_element) {
23 indirectNotifications += Ferdi.safeParseInt(call_element.getAttribute("datacount")); 31 indirectNotifications += Ferdi.safeParseInt(
32 call_element.getAttribute('datacount'),
33 );
24 } 34 }
25 35
26 Ferdi.setBadge(notifications, indirectNotifications); 36 Ferdi.setBadge(notifications, indirectNotifications);
diff --git a/recipes/teamweek/index.js b/recipes/teamweek/index.js
index 1b32271..b28967d 100644
--- a/recipes/teamweek/index.js
+++ b/recipes/teamweek/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Teamweek extends Ferdi { module.exports = Ferdi => class Teamweek extends Ferdi {};
2};
diff --git a/recipes/teamwork-projects/webview.js b/recipes/teamwork-projects/webview.js
index aa3e7be..7d3e845 100644
--- a/recipes/teamwork-projects/webview.js
+++ b/recipes/teamwork-projects/webview.js
@@ -1,14 +1,14 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let indirectCount = 0; 3 let indirectCount = 0;
4 const badge = document.getElementById('numNotifs2'); 4 const badge = document.querySelector('#numNotifs2');
5 5
6 if (badge && badge.innerText) { 6 if (badge && badge.textContent) {
7 indirectCount = Ferdi.safeParseInt(badge.innerText); 7 indirectCount = Ferdi.safeParseInt(badge.textContent);
8 } 8 }
9 9
10 Ferdi.setBadge(0, indirectCount); 10 Ferdi.setBadge(0, indirectCount);
11 } 11 };
12 12
13 Ferdi.loop(getMessages); 13 Ferdi.loop(getMessages);
14}; 14};
diff --git a/recipes/telegram-react/webview.js b/recipes/telegram-react/webview.js
index bf41404..c17b200 100644
--- a/recipes/telegram-react/webview.js
+++ b/recipes/telegram-react/webview.js
@@ -3,9 +3,14 @@ module.exports = Ferdi => {
3 let count = 0; 3 let count = 0;
4 const elements = document.querySelectorAll('.chatlist > li:not(.is-muted)'); 4 const elements = document.querySelectorAll('.chatlist > li:not(.is-muted)');
5 if (elements) { 5 if (elements) {
6 for (let i = 0; i < elements.length; i += 1) { 6 for (const element of elements) {
7 if (elements[i].querySelector('.unread') && elements[i].querySelector('.unread').innerHTML !== 0) { 7 if (
8 count += Ferdi.safeParseInt(elements[i].querySelector('.unread').innerHTML); 8 element.querySelector('.unread') &&
9 element.querySelector('.unread').textContent !== 0
10 ) {
11 count += Ferdi.safeParseInt(
12 element.querySelector('.unread').textContent,
13 );
9 } 14 }
10 } 15 }
11 } 16 }
diff --git a/recipes/telegram/webview.js b/recipes/telegram/webview.js
index 3b36483..358bdaa 100644
--- a/recipes/telegram/webview.js
+++ b/recipes/telegram/webview.js
@@ -2,18 +2,20 @@
2 2
3const _path = _interopRequireDefault(require('path')); 3const _path = _interopRequireDefault(require('path'));
4 4
5function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 5function _interopRequireDefault(obj) {
6 return obj && obj.__esModule ? obj : { default: obj };
7}
6 8
7module.exports = Ferdi => { 9module.exports = Ferdi => {
8 const getMessages = () => { 10 const getMessages = () => {
9 let count = 0; 11 let count = 0;
10 let count_sec = 0; 12 let count_sec = 0;
11 const elements = document.querySelectorAll('.rp'); 13 const elements = document.querySelectorAll('.rp');
12 for (let i = 0; i < elements.length; i += 1) { 14 for (const element of elements) {
13 const subtitleBadge = elements[i].querySelector('.dialog-subtitle-badge'); 15 const subtitleBadge = element.querySelector('.dialog-subtitle-badge');
14 if (subtitleBadge) { 16 if (subtitleBadge) {
15 const parsedValue = Ferdi.safeParseInt(subtitleBadge.innerText); 17 const parsedValue = Ferdi.safeParseInt(subtitleBadge.textContent);
16 if (elements[i].dataset.peerId > 0) { 18 if (element.dataset.peerId > 0) {
17 count += parsedValue; 19 count += parsedValue;
18 } else { 20 } else {
19 count_sec += parsedValue; 21 count_sec += parsedValue;
diff --git a/recipes/thelounge/webview.js b/recipes/thelounge/webview.js
index 28f647c..b950e8a 100644
--- a/recipes/thelounge/webview.js
+++ b/recipes/thelounge/webview.js
@@ -1,10 +1,12 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const indirectElements = document.querySelectorAll('.badge:not(.highlight)'); 3 const indirectElements = document.querySelectorAll(
4 '.badge:not(.highlight)',
5 );
4 const direct = document.querySelectorAll('.badge.highlight').length; 6 const direct = document.querySelectorAll('.badge.highlight').length;
5 let indirect = 0; 7 let indirect = 0;
6 for (let i = 0; i < indirectElements.length; i += 1) { 8 for (const indirectElement of indirectElements) {
7 if (indirectElements[i].innerHTML.length > 0) { 9 if (indirectElement.textContent.length > 0) {
8 indirect++; 10 indirect++;
9 } 11 }
10 } 12 }
diff --git a/recipes/threema/webview.js b/recipes/threema/webview.js
index 40f5203..cf7d1e1 100644
--- a/recipes/threema/webview.js
+++ b/recipes/threema/webview.js
@@ -1,17 +1,21 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = Ferdi => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 const elements = document.querySelectorAll('.badge.unread-count:not(.ng-hide)'); 9 const elements = document.querySelectorAll(
10 '.badge.unread-count:not(.ng-hide)',
11 );
8 let count = 0; 12 let count = 0;
9 13
10 for (let i = 0; i < elements.length; i += 1) { 14 for (const element of elements) {
11 try { 15 try {
12 count += Ferdi.safeParseInt(elements[i].innerHTML); 16 count += Ferdi.safeParseInt(element.textContent);
13 } catch (e) { 17 } catch (error) {
14 console.error(e); 18 console.error(error);
15 } 19 }
16 } 20 }
17 21
diff --git a/recipes/tinder/index.js b/recipes/tinder/index.js
index 38c3f5c..c0c5dd1 100644
--- a/recipes/tinder/index.js
+++ b/recipes/tinder/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Tinder extends Ferdi { module.exports = Ferdi => class Tinder extends Ferdi {};
2};
diff --git a/recipes/todoist/webview.js b/recipes/todoist/webview.js
index b548184..30030d5 100644
--- a/recipes/todoist/webview.js
+++ b/recipes/todoist/webview.js
@@ -1,4 +1,4 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 function getTasks() { 2 function getTasks() {
3 let todayCount = 0; 3 let todayCount = 0;
4 let inboxCount = 0; 4 let inboxCount = 0;
@@ -6,11 +6,11 @@ module.exports = (Ferdi) => {
6 const inboxElement = document.querySelector('#filter_inbox .item_counter'); 6 const inboxElement = document.querySelector('#filter_inbox .item_counter');
7 7
8 if (todayElement) { 8 if (todayElement) {
9 todayCount = Ferdi.safeParseInt(todayElement.innerHTML); 9 todayCount = Ferdi.safeParseInt(todayElement.textContent);
10 } 10 }
11 11
12 if (inboxElement) { 12 if (inboxElement) {
13 inboxCount = Ferdi.safeParseInt(inboxElement.innerHTML); 13 inboxCount = Ferdi.safeParseInt(inboxElement.textContent);
14 } 14 }
15 15
16 Ferdi.setBadge(inboxCount, todayCount); 16 Ferdi.setBadge(inboxCount, todayCount);
diff --git a/recipes/trello/webview.js b/recipes/trello/webview.js
index d9749b0..e359de9 100644
--- a/recipes/trello/webview.js
+++ b/recipes/trello/webview.js
@@ -1,7 +1,7 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const notifications = document.querySelectorAll('[class*=_3W-zkl4-bnVKzJ]'); 3 const notifications = document.querySelectorAll('[class*=_3W-zkl4-bnVKzJ]');
4 Ferdi.setBadge(0, notifications.length >= 1 ? 1 : 0); 4 Ferdi.setBadge(0, notifications.length > 0 ? 1 : 0);
5 }; 5 };
6 6
7 Ferdi.loop(getMessages); 7 Ferdi.loop(getMessages);
diff --git a/recipes/tutanota/index.js b/recipes/tutanota/index.js
index 3947605..5cb28eb 100644
--- a/recipes/tutanota/index.js
+++ b/recipes/tutanota/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class tutanota extends Ferdi { module.exports = Ferdi => class tutanota extends Ferdi {};
2};
diff --git a/recipes/tweetdeck/webview.js b/recipes/tweetdeck/webview.js
index 9bdc2be..7f99509 100644
--- a/recipes/tweetdeck/webview.js
+++ b/recipes/tweetdeck/webview.js
@@ -8,7 +8,7 @@ module.exports = Ferdi => {
8 const elements = document.querySelectorAll('.msg-unread-count'); 8 const elements = document.querySelectorAll('.msg-unread-count');
9 let count = 0; 9 let count = 0;
10 if (elements[0]) { 10 if (elements[0]) {
11 count = Ferdi.safeParseInt(elements[0].innerHTML); 11 count = Ferdi.safeParseInt(elements[0].textContent);
12 } 12 }
13 13
14 Ferdi.setBadge(count); 14 Ferdi.setBadge(count);
diff --git a/recipes/twitter-dm/webview.js b/recipes/twitter-dm/webview.js
index ac47134..dd6856a 100644
--- a/recipes/twitter-dm/webview.js
+++ b/recipes/twitter-dm/webview.js
@@ -3,7 +3,7 @@ module.exports = Ferdi => {
3 let count = 0; 3 let count = 0;
4 const elem = document.querySelector('a[href="/messages"] div div'); 4 const elem = document.querySelector('a[href="/messages"] div div');
5 if (elem) { 5 if (elem) {
6 count = Ferdi.safeParseInt(elem.innerText); 6 count = Ferdi.safeParseInt(elem.textContent);
7 } 7 }
8 8
9 Ferdi.setBadge(count); 9 Ferdi.setBadge(count);
diff --git a/recipes/twitter/webview.js b/recipes/twitter/webview.js
index dfd06d1..d88e3e4 100644
--- a/recipes/twitter/webview.js
+++ b/recipes/twitter/webview.js
@@ -4,13 +4,17 @@ module.exports = Ferdi => {
4 4
5 // "Notifications" and "Messages" - aria-label ending in 5 // "Notifications" and "Messages" - aria-label ending in
6 // "unread items". Sum the values for direct badge. 6 // "unread items". Sum the values for direct badge.
7 const notificationsElement = document.querySelector('[data-testid=AppTabBar_Notifications_Link] div div div'); 7 const notificationsElement = document.querySelector(
8 '[data-testid=AppTabBar_Notifications_Link] div div div',
9 );
8 if (notificationsElement) { 10 if (notificationsElement) {
9 direct += Ferdi.safeParseInt(notificationsElement.innerHTML); 11 direct += Ferdi.safeParseInt(notificationsElement.textContent);
10 } 12 }
11 const DMElement = document.querySelector('[data-testid=AppTabBar_DirectMessage_Link] div div div'); 13 const DMElement = document.querySelector(
14 '[data-testid=AppTabBar_DirectMessage_Link] div div div',
15 );
12 if (DMElement) { 16 if (DMElement) {
13 direct += Ferdi.safeParseInt(DMElement.innerHTML); 17 direct += Ferdi.safeParseInt(DMElement.textContent);
14 } 18 }
15 19
16 Ferdi.setBadge(direct); 20 Ferdi.setBadge(direct);
diff --git a/recipes/vk/webview.js b/recipes/vk/webview.js
index aeab0ec..decec13 100644
--- a/recipes/vk/webview.js
+++ b/recipes/vk/webview.js
@@ -1,9 +1,9 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let directs = 0; 3 let directs = 0;
4 const element = document.getElementsByClassName('left_count'); 4 const element = document.querySelectorAll('.left_count');
5 if (element.length > 0) { 5 if (element.length > 0) {
6 directs = Ferdi.safeParseInt(element[0].innerText); 6 directs = Ferdi.safeParseInt(element[0].textContent);
7 } 7 }
8 8
9 Ferdi.setBadge(directs); 9 Ferdi.setBadge(directs);
diff --git a/recipes/wakatime/index.js b/recipes/wakatime/index.js
index f16f627..4caa1ec 100644
--- a/recipes/wakatime/index.js
+++ b/recipes/wakatime/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class Wakatime extends Ferdi { module.exports = Ferdi => class Wakatime extends Ferdi {};
2};
diff --git a/recipes/webex-teams/webview.js b/recipes/webex-teams/webview.js
index d29bed9..8a748e8 100644
--- a/recipes/webex-teams/webview.js
+++ b/recipes/webex-teams/webview.js
@@ -1,15 +1,17 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let count = 0; 3 let count = 0;
4 4
5 let span = document.getElementsByClassName('navigation-list-item--badgeCount'); 5 let span = document.querySelectorAll('.navigation-list-item--badgeCount');
6 6
7 if (span.length == 0) { 7 if (span.length === 0) {
8 span = document.getElementsByClassName('navigation-list-item--badgeCount-minimized'); 8 span = document.querySelectorAll(
9 '.navigation-list-item--badgeCount-minimized',
10 );
9 } 11 }
10 12
11 if (span.length > 0) { 13 if (span.length > 0) {
12 count = Ferdi.safeParseInt(span[0].innerText); 14 count = Ferdi.safeParseInt(span[0].textContent);
13 } 15 }
14 16
15 Ferdi.setBadge(count); 17 Ferdi.setBadge(count);
diff --git a/recipes/wechat/webview.js b/recipes/wechat/webview.js
index d75bd72..e7de1f1 100644
--- a/recipes/wechat/webview.js
+++ b/recipes/wechat/webview.js
@@ -1,23 +1,28 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = (Ferdi) => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 let directCount = 0; 9 let directCount = 0;
8 let indirectCount = 0; 10 let indirectCount = 0;
9 const chat_item = document.querySelectorAll('div.chat_item'); 11 const chat_item = document.querySelectorAll('div.chat_item');
10 12
11 Array.prototype.forEach.call(chat_item, (item) => { 13 Array.prototype.forEach.call(chat_item, item => {
12 let count = 0; 14 let count = 0;
13 const reddot = item.querySelector('i.web_wechat_reddot_middle'); 15 const reddot = item.querySelector('i.web_wechat_reddot_middle');
14 const avatarImage = item.querySelector('img.img'); 16 const avatarImage = item.querySelector('img.img');
15 17
16 if (reddot) { 18 if (reddot) {
17 count = Ferdi.safeParseInt(reddot.innerText); 19 count = Ferdi.safeParseInt(reddot.textContent);
18 } 20 }
19 21
20 if (avatarImage && avatarImage.getAttribute('src').search('webwxgeticon') != -1) { 22 if (
23 avatarImage &&
24 avatarImage.getAttribute('src').search('webwxgeticon') != -1
25 ) {
21 directCount += count; 26 directCount += count;
22 } else { 27 } else {
23 indirectCount += count; 28 indirectCount += count;
@@ -25,7 +30,7 @@ module.exports = (Ferdi) => {
25 }); 30 });
26 31
27 Ferdi.setBadge(directCount, indirectCount); 32 Ferdi.setBadge(directCount, indirectCount);
28 } 33 };
29 34
30 Ferdi.loop(getMessages); 35 Ferdi.loop(getMessages);
31 36
diff --git a/recipes/weekplan/webview.js b/recipes/weekplan/webview.js
index f08859d..535ab9b 100644
--- a/recipes/weekplan/webview.js
+++ b/recipes/weekplan/webview.js
@@ -1,7 +1,7 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const events = document.querySelectorAll(".today")[0].getElementsByClassName('list')[0].getElementsByClassName('task-list')[0].getElementsByClassName('event-section')[0].getElementsByClassName('droppable')[0].children[0].childElementCount 3 const events = document.querySelectorAll(".today")[0].querySelectorAll('.list')[0].querySelectorAll('.task-list')[0].querySelectorAll('.event-section')[0].querySelectorAll('.droppable')[0].children[0].childElementCount
4 const tasks = document.querySelectorAll(".today")[0].getElementsByClassName('list')[0].getElementsByClassName('task-list')[0].getElementsByClassName('task-section')[0].getElementsByClassName('droppable')[0].children[0].childElementCount 4 const tasks = document.querySelectorAll(".today")[0].querySelectorAll('.list')[0].querySelectorAll('.task-list')[0].querySelectorAll('.task-section')[0].querySelectorAll('.droppable')[0].children[0].childElementCount
5 5
6 Ferdi.setBadge(events + tasks); 6 Ferdi.setBadge(events + tasks);
7 }; 7 };
diff --git a/recipes/whatsapp/webview.js b/recipes/whatsapp/webview.js
index dea7b6a..a908637 100644
--- a/recipes/whatsapp/webview.js
+++ b/recipes/whatsapp/webview.js
@@ -7,15 +7,14 @@ module.exports = (Ferdi, settings) => {
7 let count = 0; 7 let count = 0;
8 let indirectCount = 0; 8 let indirectCount = 0;
9 9
10 const parentChatElem = Array.from(document.querySelectorAll('div[aria-label]')) 10 const parentChatElem = [...document.querySelectorAll('div[aria-label]')]
11 .sort((a, b) => (a.offsetHeight < b.offsetHeight) ? 1 : -1)[0]; 11 .sort((a, b) => (a.offsetHeight < b.offsetHeight) ? 1 : -1)[0];
12 if (!parentChatElem) { 12 if (!parentChatElem) {
13 return; 13 return;
14 } 14 }
15 15
16 const unreadSpans = parentChatElem.querySelectorAll('span[aria-label]'); 16 const unreadSpans = parentChatElem.querySelectorAll('span[aria-label]');
17 for (let i = 0; i < unreadSpans.length; i++) { 17 for (const unreadElem of unreadSpans) {
18 const unreadElem = unreadSpans[i];
19 const countValue = Ferdi.safeParseInt(unreadElem.textContent); 18 const countValue = Ferdi.safeParseInt(unreadElem.textContent);
20 if (countValue > 0) { 19 if (countValue > 0) {
21 if (!unreadElem.parentNode.previousSibling || unreadElem.parentNode.previousSibling.querySelectorAll('[data-icon=muted]').length === 0) { 20 if (!unreadElem.parentNode.previousSibling || unreadElem.parentNode.previousSibling.querySelectorAll('[data-icon=muted]').length === 0) {
diff --git a/recipes/whereby/webview.js b/recipes/whereby/webview.js
index 52d6d7b..eb751a5 100644
--- a/recipes/whereby/webview.js
+++ b/recipes/whereby/webview.js
@@ -7,8 +7,8 @@ module.exports = Ferdi => {
7 const elements = document.querySelectorAll('.CxUIE, .unread'); 7 const elements = document.querySelectorAll('.CxUIE, .unread');
8 let count = 0; 8 let count = 0;
9 9
10 for (let i = 0; i < elements.length; i += 1) { 10 for (const element of elements) {
11 if (elements[i].querySelectorAll('*[data-icon="muted"]').length === 0) { 11 if (element.querySelectorAll('*[data-icon="muted"]').length === 0) {
12 count += 1; 12 count += 1;
13 } 13 }
14 } 14 }
diff --git a/recipes/wire/webview.js b/recipes/wire/webview.js
index 55720da..cdb5058 100644
--- a/recipes/wire/webview.js
+++ b/recipes/wire/webview.js
@@ -1,20 +1,25 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let direct = 0; 3 let direct = 0;
4 let indirect = 0; 4 let indirect = 0;
5 5
6 // Count how many people/groups have texted you 6 // Count how many people/groups have texted you
7 const conversationElems = document.querySelectorAll('[data-uie-name="conversation-folder-badge"]'); 7 const conversationElems = document.querySelectorAll(
8 '[data-uie-name="conversation-folder-badge"]',
9 );
8 if (conversationElems) { 10 if (conversationElems) {
9 for (const conversationElem of conversationElems) { 11 for (const conversationElem of conversationElems) {
10 direct += Ferdi.safeParseInt(conversationElem.innerText); 12 direct += Ferdi.safeParseInt(conversationElem.textContent);
11 } 13 }
12 } 14 }
13 15
14 // Count unread pending user requests 16 // Count unread pending user requests
15 const pendingElem = document.querySelector('[data-uie-name="item-pending-requests"]'); 17 const pendingElem = document.querySelector(
18 '[data-uie-name="item-pending-requests"]',
19 );
16 if (pendingElem) { 20 if (pendingElem) {
17 const matches = pendingElem.innerText.match(/^([1-9][0-9]*)/); 21 const matches =
22 pendingElem.textContent && pendingElem.textContent.match(/^([1-9]\d*)/);
18 if (matches && matches.length > 1) { 23 if (matches && matches.length > 1) {
19 indirect += Ferdi.safeParseInt(matches[1]); 24 indirect += Ferdi.safeParseInt(matches[1]);
20 } 25 }
@@ -22,13 +27,13 @@ module.exports = (Ferdi) => {
22 27
23 // Alternative would be to count all messages (unread conversation count + pending) from the header 28 // Alternative would be to count all messages (unread conversation count + pending) from the header
24 // const titleElem = document.querySelector('head title'); 29 // const titleElem = document.querySelector('head title');
25 // const matches = titleElem.innerText.match(/^\(([1-9][0-9]*)\)/); 30 // const matches = titleElem.textContent.match(/^\(([1-9][0-9]*)\)/);
26 // if (matches) { 31 // if (matches) {
27 // direct = matches[1]; 32 // direct = matches[1];
28 // } 33 // }
29 34
30 Ferdi.setBadge(direct, indirect); 35 Ferdi.setBadge(direct, indirect);
31 } 36 };
32 37
33 Ferdi.loop(getMessages); 38 Ferdi.loop(getMessages);
34}; 39};
diff --git a/recipes/workplace/webview.js b/recipes/workplace/webview.js
index efa5e2a..90c6c27 100644
--- a/recipes/workplace/webview.js
+++ b/recipes/workplace/webview.js
@@ -1,6 +1,8 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = Ferdi => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
@@ -10,7 +12,7 @@ module.exports = Ferdi => {
10 const notifications = document.querySelector('#notifications span span'); 12 const notifications = document.querySelector('#notifications span span');
11 13
12 if (notifications) { 14 if (notifications) {
13 indirect = Ferdi.safeParseInt(notifications.innerText); 15 indirect = Ferdi.safeParseInt(notifications.textContent);
14 } 16 }
15 17
16 if (chatsElement) { 18 if (chatsElement) {
@@ -18,10 +20,12 @@ module.exports = Ferdi => {
18 const chatMessages = chatsElement.querySelector('span'); 20 const chatMessages = chatsElement.querySelector('span');
19 21
20 if (chatMessages) { 22 if (chatMessages) {
21 direct = Ferdi.safeParseInt(chatMessages.innerText); 23 direct = Ferdi.safeParseInt(chatMessages.textContent);
22 } 24 }
23 } else { 25 } else {
24 direct = document.querySelectorAll('[data-pagelet="WorkGalahadChannel"] .uiList [role="gridcell"] [role="button"] .oxk9n0fw').length; 26 direct = document.querySelectorAll(
27 '[data-pagelet="WorkGalahadChannel"] .uiList [role="gridcell"] [role="button"] .oxk9n0fw',
28 ).length;
25 } 29 }
26 } 30 }
27 31
@@ -33,18 +37,21 @@ module.exports = Ferdi => {
33 Ferdi.injectCSS(_path.default.join(__dirname, 'workplace.css')); 37 Ferdi.injectCSS(_path.default.join(__dirname, 'workplace.css'));
34 38
35 localStorage._cs_desktopNotifsEnabled = JSON.stringify({ 39 localStorage._cs_desktopNotifsEnabled = JSON.stringify({
36 __t: new Date().getTime(), 40 __t: Date.now(),
37 __v: true, 41 __v: true,
38 }); 42 });
39 43
40 if (typeof Ferdi.onNotify === 'function') { 44 if (typeof Ferdi.onNotify === 'function') {
41 Ferdi.onNotify(notification => { 45 Ferdi.onNotify(notification => {
42 if (typeof notification.title !== 'string') { 46 if (typeof notification.title !== 'string') {
43 notification.title = ((notification.title.props || {}).content || [])[0] || 'Work Chat'; 47 notification.title =
48 ((notification.title.props || {}).content || [])[0] || 'Work Chat';
44 } 49 }
45 50
46 if (typeof notification.options.body !== 'string') { 51 if (typeof notification.options.body !== 'string') {
47 notification.options.body = (((notification.options.body || {}).props || {}).content || [])[0] || ''; 52 notification.options.body =
53 (((notification.options.body || {}).props || {}).content || [])[0] ||
54 '';
48 } 55 }
49 56
50 return notification; 57 return notification;
diff --git a/recipes/wrike/webview.js b/recipes/wrike/webview.js
index e09407d..93d5d53 100644
--- a/recipes/wrike/webview.js
+++ b/recipes/wrike/webview.js
@@ -1,13 +1,15 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let directCount = 0; 3 let directCount = 0;
4 const element = document.querySelector('.ws-navigation-button__indicator.ws-navigation-button-indicator'); 4 const element = document.querySelector(
5 '.ws-navigation-button__indicator.ws-navigation-button-indicator',
6 );
5 if (element) { 7 if (element) {
6 directCount = Ferdi.safeParseInt(element.innerText); 8 directCount = Ferdi.safeParseInt(element.textContent);
7 } 9 }
8 10
9 Ferdi.setBadge(directCount); 11 Ferdi.setBadge(directCount);
10 } 12 };
11 13
12 Ferdi.loop(getMessages); 14 Ferdi.loop(getMessages);
13}; 15};
diff --git a/recipes/xing/webview.js b/recipes/xing/webview.js
index 9effe95..75038bf 100644
--- a/recipes/xing/webview.js
+++ b/recipes/xing/webview.js
@@ -1,6 +1,6 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 function getUnreadConversations() { 2 function getUnreadConversations() {
3 Ferdi.setBadge(document.querySelector('#unread-conversations').innerHTML); 3 Ferdi.setBadge(document.querySelector('#unread-conversations').textContent);
4 } 4 }
5 5
6 Ferdi.loop(getUnreadConversations); 6 Ferdi.loop(getUnreadConversations);
diff --git a/recipes/yammer/webview.js b/recipes/yammer/webview.js
index d3a94da..6bfd971 100644
--- a/recipes/yammer/webview.js
+++ b/recipes/yammer/webview.js
@@ -2,15 +2,21 @@ module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let directMessages = 0; 3 let directMessages = 0;
4 let indirectMessages = 0; 4 let indirectMessages = 0;
5 const notificationElement = document.querySelector('.yj-notifications-indicator-count'); 5 const notificationElement = document.querySelector(
6 const newMessagesElement = document.querySelector('.yj-thread-list--new-messages-notice:not(.is-hidden) .yj-thread-list--new-message-text'); 6 '.yj-notifications-indicator-count',
7 );
8 const newMessagesElement = document.querySelector(
9 '.yj-thread-list--new-messages-notice:not(.is-hidden) .yj-thread-list--new-message-text',
10 );
7 11
8 if (notificationElement) { 12 if (notificationElement) {
9 directMessages = Ferdi.safeParseInt(notificationElement.innerHTML); 13 directMessages = Ferdi.safeParseInt(notificationElement.textContent);
10 } 14 }
11 15
12 if (newMessagesElement) { 16 if (newMessagesElement) {
13 indirectMessages = Ferdi.safeParseInt(newMessagesElement.innerHTML.match(/\d+/)[0]); 17 indirectMessages = Ferdi.safeParseInt(
18 newMessagesElement.textContent.match(/\d+/)[0],
19 );
14 } 20 }
15 21
16 Ferdi.setBadge(directMessages, indirectMessages); 22 Ferdi.setBadge(directMessages, indirectMessages);
diff --git a/recipes/yandex-mail/webview.js b/recipes/yandex-mail/webview.js
index 7a937a7..fff4602 100644
--- a/recipes/yandex-mail/webview.js
+++ b/recipes/yandex-mail/webview.js
@@ -2,8 +2,8 @@ module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 let count = 0; 3 let count = 0;
4 4
5 if (document.getElementsByClassName('mail-LabelList-Item_count').length > 1) { 5 if (document.querySelectorAll('.mail-LabelList-Item_count').length > 1) {
6 count = Ferdi.safeParseInt(document.getElementsByClassName('mail-LabelList-Item_count')[1].textContent); 6 count = Ferdi.safeParseInt(document.querySelectorAll('.mail-LabelList-Item_count')[1].textContent);
7 } 7 }
8 8
9 Ferdi.setBadge(count); 9 Ferdi.setBadge(count);
diff --git a/recipes/youtrack/index.js b/recipes/youtrack/index.js
index fbb0bb0..16a8178 100644
--- a/recipes/youtrack/index.js
+++ b/recipes/youtrack/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class youtrack extends Ferdi { module.exports = Ferdi => class youtrack extends Ferdi {};
2};
diff --git a/recipes/zalo/webview.js b/recipes/zalo/webview.js
index a79e29b..9ccc93b 100644
--- a/recipes/zalo/webview.js
+++ b/recipes/zalo/webview.js
@@ -1,6 +1,6 @@
1module.exports = Ferdi => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const notificationBadge = document.getElementsByClassName('tab-red-dot').length; 3 const notificationBadge = document.querySelectorAll('.tab-red-dot').length;
4 Ferdi.setBadge(notificationBadge); 4 Ferdi.setBadge(notificationBadge);
5 }; 5 };
6 6
diff --git a/recipes/zendesk/webview.js b/recipes/zendesk/webview.js
index b781121..0b448b7 100644
--- a/recipes/zendesk/webview.js
+++ b/recipes/zendesk/webview.js
@@ -1,13 +1,17 @@
1const _path = _interopRequireDefault(require('path')); 1const _path = _interopRequireDefault(require('path'));
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3function _interopRequireDefault(obj) {
4 return obj && obj.__esModule ? obj : { default: obj };
5}
4 6
5module.exports = Ferdi => { 7module.exports = Ferdi => {
6 const getMessages = () => { 8 const getMessages = () => {
7 let count = 0; 9 let count = 0;
8 const element = document.querySelector('.dashboard-top-panel .indicators .stats-group .cell-value'); 10 const element = document.querySelector(
11 '.dashboard-top-panel .indicators .stats-group .cell-value',
12 );
9 if (element) { 13 if (element) {
10 count = Ferdi.safeParseInt(element.innerHTML); 14 count = Ferdi.safeParseInt(element.textContent);
11 } 15 }
12 16
13 Ferdi.setBadge(count); 17 Ferdi.setBadge(count);
diff --git a/recipes/zulip/index.js b/recipes/zulip/index.js
index 5854600..8bad3cf 100644
--- a/recipes/zulip/index.js
+++ b/recipes/zulip/index.js
@@ -12,8 +12,8 @@ module.exports = Ferdi => class Zulip extends Ferdi {
12 const data = await resp.json(); 12 const data = await resp.json();
13 13
14 return Object.hasOwnProperty.call(data, 'realm_uri'); 14 return Object.hasOwnProperty.call(data, 'realm_uri');
15 } catch (err) { 15 } catch (error) {
16 console.error(err); 16 console.error(error);
17 } 17 }
18 18
19 return false; 19 return false;
diff --git a/recipes/zulip/webview.js b/recipes/zulip/webview.js
index 3de6c90..e9c13c0 100644
--- a/recipes/zulip/webview.js
+++ b/recipes/zulip/webview.js
@@ -1,6 +1,10 @@
1module.exports = (Ferdi) => { 1module.exports = Ferdi => {
2 const getMessages = () => { 2 const getMessages = () => {
3 const allMessages = Math.round(document.querySelectorAll('#global_filters .top_left_all_messages .count .value')[0].innerText); 3 const allMessages = Math.round(
4 document.querySelectorAll(
5 '#global_filters .top_left_all_messages .count .value',
6 )[0].textContent,
7 );
4 Ferdi.setBadge(allMessages); 8 Ferdi.setBadge(allMessages);
5 }; 9 };
6 10
diff --git a/scripts/package.js b/scripts/package.js
index 4fc02f1..ecf648d 100644
--- a/scripts/package.js
+++ b/scripts/package.js
@@ -125,7 +125,7 @@ const compress = (src, dest) =>
125 "The recipe's package.json contains no 'id' field. This field should contain a unique ID made of lowercase letters (a-z), numbers (0-9), hyphens (-), periods (.), and underscores (_)", 125 "The recipe's package.json contains no 'id' field. This field should contain a unique ID made of lowercase letters (a-z), numbers (0-9), hyphens (-), periods (.), and underscores (_)",
126 ); 126 );
127 // eslint-disable-next-line no-useless-escape 127 // eslint-disable-next-line no-useless-escape
128 } else if (!/^[a-zA-Z0-9._\-]+$/.test(config.id)) { 128 } else if (!/^[\w.\-]+$/.test(config.id)) {
129 configErrors.push( 129 configErrors.push(
130 "The recipe's package.json defines an invalid recipe ID. Please make sure the 'id' field only contains lowercase letters (a-z), numbers (0-9), hyphens (-), periods (.), and underscores (_)", 130 "The recipe's package.json defines an invalid recipe ID. Please make sure the 'id' field only contains lowercase letters (a-z), numbers (0-9), hyphens (-), periods (.), and underscores (_)",
131 ); 131 );
@@ -152,7 +152,7 @@ const compress = (src, dest) =>
152 } 152 }
153 153
154 const topLevelKeys = Object.keys(config); 154 const topLevelKeys = Object.keys(config);
155 topLevelKeys.forEach(key => { 155 for (const key of topLevelKeys) {
156 if (typeof config[key] === 'string') { 156 if (typeof config[key] === 'string') {
157 if (config[key] === '') { 157 if (config[key] === '') {
158 configErrors.push( 158 configErrors.push(
@@ -167,9 +167,9 @@ const compress = (src, dest) =>
167 `The recipe's package.json contains unexpected value for key: ${key}`, 167 `The recipe's package.json contains unexpected value for key: ${key}`,
168 ); 168 );
169 } 169 }
170 }); 170 }
171 171
172 const knownTopLevelKeys = [ 172 const knownTopLevelKeys = new Set([
173 'id', 173 'id',
174 'name', 174 'name',
175 'version', 175 'version',
@@ -177,9 +177,9 @@ const compress = (src, dest) =>
177 'repository', 177 'repository',
178 'aliases', 178 'aliases',
179 'config', 179 'config',
180 ]; 180 ]);
181 const unrecognizedKeys = topLevelKeys.filter( 181 const unrecognizedKeys = topLevelKeys.filter(
182 x => !knownTopLevelKeys.includes(x), 182 x => !knownTopLevelKeys.has(x),
183 ); 183 );
184 if (unrecognizedKeys.length > 0) { 184 if (unrecognizedKeys.length > 0) {
185 configErrors.push( 185 configErrors.push(
@@ -188,7 +188,7 @@ const compress = (src, dest) =>
188 } 188 }
189 if (config.config && typeof config.config === 'object') { 189 if (config.config && typeof config.config === 'object') {
190 const configKeys = Object.keys(config.config); 190 const configKeys = Object.keys(config.config);
191 const knownConfigKeys = [ 191 const knownConfigKeys = new Set([
192 'serviceURL', 192 'serviceURL',
193 'hasTeamId', 193 'hasTeamId',
194 'urlInputPrefix', 194 'urlInputPrefix',
@@ -201,9 +201,9 @@ const compress = (src, dest) =>
201 'allowFavoritesDelineationInUnreadCount', 201 'allowFavoritesDelineationInUnreadCount',
202 'message', 202 'message',
203 'disablewebsecurity', 203 'disablewebsecurity',
204 ]; 204 ]);
205 const unrecognizedConfigKeys = configKeys.filter( 205 const unrecognizedConfigKeys = configKeys.filter(
206 x => !knownConfigKeys.includes(x), 206 x => !knownConfigKeys.has(x),
207 ); 207 );
208 if (unrecognizedConfigKeys.length > 0) { 208 if (unrecognizedConfigKeys.length > 0) {
209 configErrors.push( 209 configErrors.push(
@@ -215,7 +215,7 @@ const compress = (src, dest) =>
215 // configErrors.push("The recipe's package.json contains both 'hasCustomUrl' and 'hasHostedOption'. Please remove 'hasCustomUrl' since it is overridden by 'hasHostedOption'"); 215 // configErrors.push("The recipe's package.json contains both 'hasCustomUrl' and 'hasHostedOption'. Please remove 'hasCustomUrl' since it is overridden by 'hasHostedOption'");
216 // } 216 // }
217 217
218 configKeys.forEach(key => { 218 for (const key of configKeys) {
219 if ( 219 if (
220 typeof config.config[key] === 'string' && 220 typeof config.config[key] === 'string' &&
221 config.config[key] === '' 221 config.config[key] === ''
@@ -224,7 +224,7 @@ const compress = (src, dest) =>
224 `The recipe's package.json contains empty value for key: ${key}`, 224 `The recipe's package.json contains empty value for key: ${key}`,
225 ); 225 );
226 } 226 }
227 }); 227 }
228 } 228 }
229 229
230 if (isGitRepo) { 230 if (isGitRepo) {
@@ -243,7 +243,7 @@ const compress = (src, dest) =>
243 result.deletions !== 0) 243 result.deletions !== 0)
244 ) { 244 ) {
245 const pkgJsonRelative = path.relative(repoRoot, packageJson); 245 const pkgJsonRelative = path.relative(repoRoot, packageJson);
246 if (!result.files.find(({ file }) => file === pkgJsonRelative)) { 246 if (!result.files.some(({ file }) => file === pkgJsonRelative)) {
247 configErrors.push( 247 configErrors.push(
248 `Found changes in '${relativeRepoSrc}' without the corresponding version bump in '${pkgJsonRelative}'`, 248 `Found changes in '${relativeRepoSrc}' without the corresponding version bump in '${pkgJsonRelative}'`,
249 ); 249 );
@@ -313,6 +313,6 @@ const compress = (src, dest) =>
313 ); 313 );
314 314
315 if (unsuccessful > 0) { 315 if (unsuccessful > 0) {
316 process.exit(1); 316 throw new Error(`One or more recipes couldn't be packaged.`);
317 } 317 }
318})(); 318})();
diff --git a/scripts/sample_recipe/index.js b/scripts/sample_recipe/index.js
index 0e52bf0..b947467 100644
--- a/scripts/sample_recipe/index.js
+++ b/scripts/sample_recipe/index.js
@@ -1,2 +1 @@
1module.exports = Ferdi => class SCLEAN extends Ferdi { module.exports = Ferdi => class SCLEAN extends Ferdi {};
2};